Bug fix: out-of range access in implicit least squares
Conflicts: src/finiteVolume/finiteVolume/gradSchemes/leastSquaresGrad/leastSquaresVectors.C
This commit is contained in:
parent
8622f1fd19
commit
d5b124d72f
1 changed files with 53 additions and 82 deletions
|
@ -101,19 +101,15 @@ void Foam::leastSquaresVectors::makeLeastSquaresVectors() const
|
||||||
// Set local references to mesh data
|
// Set local references to mesh data
|
||||||
const unallocLabelList& owner = mesh().owner();
|
const unallocLabelList& owner = mesh().owner();
|
||||||
const unallocLabelList& neighbour = mesh().neighbour();
|
const unallocLabelList& neighbour = mesh().neighbour();
|
||||||
|
|
||||||
const volVectorField& C = mesh().C();
|
const volVectorField& C = mesh().C();
|
||||||
const surfaceScalarField& w = mesh().weights();
|
|
||||||
// const surfaceScalarField& magSf = mesh().magSf();
|
|
||||||
|
|
||||||
|
|
||||||
// Set up temporary storage for the dd tensor (before inversion)
|
// Set up temporary storage for the dd tensor (before inversion)
|
||||||
symmTensorField dd(mesh().nCells(), symmTensor::zero);
|
symmTensorField dd(mesh().nCells(), symmTensor::zero);
|
||||||
|
|
||||||
forAll(owner, facei)
|
forAll(owner, faceI)
|
||||||
{
|
{
|
||||||
label own = owner[facei];
|
label own = owner[faceI];
|
||||||
label nei = neighbour[facei];
|
label nei = neighbour[faceI];
|
||||||
|
|
||||||
vector d = C[nei] - C[own];
|
vector d = C[nei] - C[own];
|
||||||
symmTensor wdd = (1.0/magSqr(d))*sqr(d);
|
symmTensor wdd = (1.0/magSqr(d))*sqr(d);
|
||||||
|
@ -122,113 +118,88 @@ void Foam::leastSquaresVectors::makeLeastSquaresVectors() const
|
||||||
dd[nei] += wdd;
|
dd[nei] += wdd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
forAll(lsP.boundaryField(), patchI)
|
||||||
forAll(lsP.boundaryField(), patchi)
|
|
||||||
{
|
{
|
||||||
const fvsPatchScalarField& pw = w.boundaryField()[patchi];
|
const fvPatch& p = mesh().boundary()[patchI];
|
||||||
// Note: least squares in 1.4.1 and other OpenCFD versions
|
|
||||||
// are wrong because of incorrect weighting. HJ, 23/Oct/2008
|
|
||||||
// const fvsPatchScalarField& pMagSf = magSf.boundaryField()[patchi];
|
|
||||||
|
|
||||||
const fvPatch& p = pw.patch();
|
|
||||||
const unallocLabelList& faceCells = p.patch().faceCells();
|
const unallocLabelList& faceCells = p.patch().faceCells();
|
||||||
|
|
||||||
// Build the d-vectors
|
|
||||||
|
|
||||||
// Original version: closest distance to boundary
|
|
||||||
vectorField pd =
|
|
||||||
mesh().Sf().boundaryField()[patchi]
|
|
||||||
/(
|
|
||||||
mesh().magSf().boundaryField()[patchi]
|
|
||||||
*mesh().deltaCoeffs().boundaryField()[patchi]
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!mesh().orthogonal())
|
|
||||||
{
|
|
||||||
pd -= mesh().correctionVectors().boundaryField()[patchi]
|
|
||||||
/mesh().deltaCoeffs().boundaryField()[patchi];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Better version of d-vectors: Zeljko Tukovic, 25/Apr/2010
|
// Better version of d-vectors: Zeljko Tukovic, 25/Apr/2010
|
||||||
// Experimental: review fixed gradient condition. HJ, 30/Sep/2010
|
const vectorField pd = p.delta();
|
||||||
// vectorField pd = p.delta();
|
|
||||||
|
|
||||||
if (p.coupled())
|
forAll(pd, patchFaceI)
|
||||||
{
|
{
|
||||||
forAll(pd, patchFacei)
|
const vector& d = pd[patchFaceI];
|
||||||
{
|
dd[faceCells[patchFaceI]] += (1.0/magSqr(d))*sqr(d);
|
||||||
const vector& d = pd[patchFacei];
|
|
||||||
|
|
||||||
dd[faceCells[patchFacei]] += (1.0/magSqr(d))*sqr(d);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
forAll(pd, patchFacei)
|
|
||||||
{
|
|
||||||
const vector& d = pd[patchFacei];
|
|
||||||
|
|
||||||
dd[faceCells[patchFacei]] += (1.0/magSqr(d))*sqr(d);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For easy access of neighbour coupled patch field needed for
|
||||||
// Invert the dd tensor
|
// lsN vectors on implicitly coupled boundaries. VV, 18/June/2014
|
||||||
// symmTensorField invDd = inv(dd);
|
volSymmTensorField volInvDd
|
||||||
// Fix: householder inverse. HJ, 3/Nov/2009
|
(
|
||||||
symmTensorField invDd = hinv(dd);
|
IOobject
|
||||||
|
(
|
||||||
|
"volInvDd",
|
||||||
|
mesh().pointsInstance(),
|
||||||
|
mesh(),
|
||||||
|
IOobject::NO_READ,
|
||||||
|
IOobject::NO_WRITE
|
||||||
|
),
|
||||||
|
mesh(),
|
||||||
|
dimensionedSymmTensor("zero", dimless, symmTensor::zero),
|
||||||
|
"zeroGradient"
|
||||||
|
);
|
||||||
|
symmTensorField& invDd = volInvDd.internalField();
|
||||||
|
// invDd = inv(dd);
|
||||||
|
invDd = hinv(dd);
|
||||||
|
|
||||||
// Revisit all faces and calculate the lsP and lsN vectors
|
// Revisit all faces and calculate the lsP and lsN vectors
|
||||||
forAll(owner, facei)
|
forAll(owner, faceI)
|
||||||
{
|
{
|
||||||
label own = owner[facei];
|
label own = owner[faceI];
|
||||||
label nei = neighbour[facei];
|
label nei = neighbour[faceI];
|
||||||
|
|
||||||
vector d = C[nei] - C[own];
|
vector d = C[nei] - C[own];
|
||||||
scalar magSfByMagSqrd = 1.0/magSqr(d);
|
scalar magSfByMagSqrd = 1.0/magSqr(d);
|
||||||
|
|
||||||
lsP[facei] = magSfByMagSqrd*(invDd[own] & d);
|
lsP[faceI] = magSfByMagSqrd*(invDd[own] & d);
|
||||||
lsN[facei] = -magSfByMagSqrd*(invDd[nei] & d);
|
lsN[faceI] = -magSfByMagSqrd*(invDd[nei] & d);
|
||||||
}
|
}
|
||||||
|
|
||||||
forAll(lsP.boundaryField(), patchi)
|
forAll(lsP.boundaryField(), patchI)
|
||||||
{
|
{
|
||||||
fvsPatchVectorField& patchLsP = lsP.boundaryField()[patchi];
|
fvsPatchVectorField& patchLsP = lsP.boundaryField()[patchI];
|
||||||
|
fvsPatchVectorField& patchLsN = lsN.boundaryField()[patchI];
|
||||||
const fvsPatchScalarField& pw = w.boundaryField()[patchi];
|
const fvPatch& p = mesh().boundary()[patchI];
|
||||||
// Note: least squares in 1.4.1 and other OpenCFD versions
|
|
||||||
// are wrong because of incorrect weighting. HJ, 23/Oct/2008
|
|
||||||
// const fvsPatchScalarField& pMagSf = magSf.boundaryField()[patchi];
|
|
||||||
|
|
||||||
const fvPatch& p = pw.patch();
|
|
||||||
const unallocLabelList& faceCells = p.faceCells();
|
const unallocLabelList& faceCells = p.faceCells();
|
||||||
|
|
||||||
// Build the d-vectors
|
|
||||||
// Better version of d-vectors: Zeljko Tukovic, 25/Apr/2010
|
// Better version of d-vectors: Zeljko Tukovic, 25/Apr/2010
|
||||||
vectorField pd = p.delta();
|
const vectorField pd = p.delta();
|
||||||
|
|
||||||
if (p.coupled())
|
if (p.coupled())
|
||||||
{
|
{
|
||||||
forAll(pd, patchFacei)
|
const symmTensorField invDdNei =
|
||||||
{
|
volInvDd.boundaryField()[patchI].patchNeighbourField();
|
||||||
const vector& d = pd[patchFacei];
|
|
||||||
|
|
||||||
patchLsP[patchFacei] =
|
forAll(pd, patchFaceI)
|
||||||
(1.0/magSqr(d))
|
{
|
||||||
*(invDd[faceCells[patchFacei]] & d);
|
const vector& d = pd[patchFaceI];
|
||||||
|
|
||||||
|
patchLsP[patchFaceI] = (1.0/magSqr(d))
|
||||||
|
*(invDd[faceCells[patchFaceI]] & d);
|
||||||
|
|
||||||
|
patchLsN[patchFaceI] = - (1.0/magSqr(d))
|
||||||
|
*(invDdNei[patchFaceI] & d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
forAll(pd, patchFacei)
|
forAll(pd, patchFaceI)
|
||||||
{
|
{
|
||||||
const vector& d = pd[patchFacei];
|
const vector& d = pd[patchFaceI];
|
||||||
|
|
||||||
patchLsP[patchFacei] =
|
patchLsP[patchFaceI] = (1.0/magSqr(d))
|
||||||
(1.0/magSqr(d))
|
*(invDd[faceCells[patchFaceI]] & d);
|
||||||
*(invDd[faceCells[patchFacei]] & d);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue