ACMI: Corrected conservation issue

Patch contributed by Mattijs Janssens
Resolves bug-report http://bugs.openfoam.org/view.php?id=2057
This commit is contained in:
Henry Weller 2016-05-30 08:29:11 +01:00
parent 3f608e95e6
commit d438da1eb7
21 changed files with 233 additions and 596 deletions

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013-2015 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2013-2016 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2015 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2012-2016 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2015 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2012-2016 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License

View File

@ -997,7 +997,7 @@ bool Foam::polyMesh::upToDatePoints(const regIOobject& io) const
void Foam::polyMesh::setUpToDatePoints(regIOobject& io) const
{
io.eventNo() = points_.eventNo();
io.eventNo() = points_.eventNo()+1;
}

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License

View File

@ -137,22 +137,15 @@ Foam::tmp<Foam::Field<Type>>
Foam::cyclicACMIFvPatchField<Type>::patchNeighbourField() const
{
const Field<Type>& iField = this->primitiveField();
const labelUList& nbrFaceCellsCoupled =
cyclicACMIPatch_.cyclicACMIPatch().neighbPatch().faceCells();
const labelUList& faceCellsNonOverlap =
cyclicACMIPatch_.cyclicACMIPatch().nonOverlapPatch().faceCells();
Field<Type> pnfCoupled(iField, nbrFaceCellsCoupled);
Field<Type> pfNonOverlap(iField, faceCellsNonOverlap);
const cyclicACMIPolyPatch& cpp = cyclicACMIPatch_.cyclicACMIPatch();
tmp<Field<Type>> tpnf
(
new Field<Type>
cyclicACMIPatch_.interpolate
(
cyclicACMIPatch_.interpolate
Field<Type>
(
pnfCoupled,
pfNonOverlap
iField,
cpp.neighbPatch().faceCells()
)
)
);
@ -207,10 +200,12 @@ void Foam::cyclicACMIFvPatchField<Type>::updateInterfaceMatrix
const Pstream::commsTypes
) const
{
const cyclicACMIPolyPatch& cpp = cyclicACMIPatch_.cyclicACMIPatch();
// note: only applying coupled contribution
const labelUList& nbrFaceCellsCoupled =
cyclicACMIPatch_.cyclicACMIPatch().neighbPatch().faceCells();
cpp.neighbPatch().faceCells();
scalarField pnf(psiInternal, nbrFaceCellsCoupled);
@ -237,10 +232,11 @@ void Foam::cyclicACMIFvPatchField<Type>::updateInterfaceMatrix
const Pstream::commsTypes
) const
{
const cyclicACMIPolyPatch& cpp = cyclicACMIPatch_.cyclicACMIPatch();
// note: only applying coupled contribution
const labelUList& nbrFaceCellsCoupled =
cyclicACMIPatch_.cyclicACMIPatch().neighbPatch().faceCells();
const labelUList& nbrFaceCellsCoupled = cpp.neighbPatch().faceCells();
Field<Type> pnf(psiInternal, nbrFaceCellsCoupled);
@ -258,149 +254,6 @@ void Foam::cyclicACMIFvPatchField<Type>::updateInterfaceMatrix
}
template<class Type>
Foam::tmp<Foam::Field<Type>> Foam::cyclicACMIFvPatchField<Type>::snGrad
(
const scalarField& deltaCoeffs
) const
{
// note: only applying coupled contribution
return coupledFvPatchField<Type>::snGrad(deltaCoeffs);
}
template<class Type>
void Foam::cyclicACMIFvPatchField<Type>::updateCoeffs()
{
// update non-overlap patch - some will implement updateCoeffs, and
// others will implement evaluate
// scale neighbour field by (1 - mask)
const scalarField& mask = cyclicACMIPatch_.cyclicACMIPatch().mask();
const fvPatchField<Type>& npf = nonOverlapPatchField();
const_cast<fvPatchField<Type>&>(npf).updateCoeffs(1.0 - mask);
}
template<class Type>
void Foam::cyclicACMIFvPatchField<Type>::initEvaluate
(
const Pstream::commsTypes comms
)
{
// update non-overlap patch (if not already updated by updateCoeffs)
// scale neighbour field by (1 - mask)
fvPatchField<Type>& npf =
const_cast<fvPatchField<Type>&>(nonOverlapPatchField());
if (!npf.updated())
{
const scalarField& mask = cyclicACMIPatch_.cyclicACMIPatch().mask();
npf.evaluate(comms);
npf *= 1.0 - mask;
}
}
template<class Type>
void Foam::cyclicACMIFvPatchField<Type>::evaluate
(
const Pstream::commsTypes comms
)
{
// blend contributions from the coupled and non-overlap patches
// neighbour patch field is updated via updateCoeffs or initEvaluate
// and is already scaled by (1 - mask)
const fvPatchField<Type>& npf = nonOverlapPatchField();
coupledFvPatchField<Type>::evaluate(comms);
const Field<Type>& cpf = *this;
const scalarField& mask = cyclicACMIPatch_.cyclicACMIPatch().mask();
Field<Type>::operator=(mask*cpf + npf);
fvPatchField<Type>::evaluate();
}
template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::cyclicACMIFvPatchField<Type>::valueInternalCoeffs
(
const tmp<scalarField>& w
) const
{
// note: do not blend based on mask field
// - when applied this is scaled by the areas which are already scaled
return coupledFvPatchField<Type>::valueInternalCoeffs(w);
}
template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::cyclicACMIFvPatchField<Type>::valueBoundaryCoeffs
(
const tmp<scalarField>& w
) const
{
// note: do not blend based on mask field
// - when applied this is scaled by the areas which are already scaled
return coupledFvPatchField<Type>::valueBoundaryCoeffs(w);
}
template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::cyclicACMIFvPatchField<Type>::gradientInternalCoeffs
(
const scalarField& deltaCoeffs
) const
{
// note: do not blend based on mask field
// - when applied this is scaled by the areas which are already scaled
return coupledFvPatchField<Type>::gradientInternalCoeffs(deltaCoeffs);
}
template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::cyclicACMIFvPatchField<Type>::gradientInternalCoeffs() const
{
// note: do not blend based on mask field
// - when applied this is scaled by the areas which are already scaled
return coupledFvPatchField<Type>::gradientInternalCoeffs();
}
template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::cyclicACMIFvPatchField<Type>::gradientBoundaryCoeffs
(
const scalarField& deltaCoeffs
) const
{
// note: do not blend based on mask field
// - when applied this is scaled by the areas which are already scaled
return coupledFvPatchField<Type>::gradientBoundaryCoeffs(deltaCoeffs);
}
template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::cyclicACMIFvPatchField<Type>::gradientBoundaryCoeffs() const
{
// note: do not blend based on mask field
// - when applied this is scaled by the areas which are already scaled
return coupledFvPatchField<Type>::gradientBoundaryCoeffs();
}
template<class Type>
void Foam::cyclicACMIFvPatchField<Type>::manipulateMatrix
(

View File

@ -218,63 +218,6 @@ public:
const Pstream::commsTypes commsType
) const;
//- Return patch-normal gradient
virtual tmp<Field<Type>> snGrad
(
const scalarField& deltaCoeffs
) const;
//- Update the coefficients associated with the patch field
void updateCoeffs();
//- Initialise the evaluation of the patch field
virtual void initEvaluate
(
const Pstream::commsTypes commsType
);
//- Evaluate the patch field
virtual void evaluate
(
const Pstream::commsTypes commsType
);
//- Return the matrix diagonal coefficients corresponding to the
// evaluation of the value of this patchField with given weights
virtual tmp<Field<Type>> valueInternalCoeffs
(
const tmp<scalarField>&
) const;
//- Return the matrix source coefficients corresponding to the
// evaluation of the value of this patchField with given weights
virtual tmp<Field<Type>> valueBoundaryCoeffs
(
const tmp<scalarField>&
) const;
//- Return the matrix diagonal coefficients corresponding to the
// evaluation of the gradient of this patchField
virtual tmp<Field<Type>> gradientInternalCoeffs
(
const scalarField& deltaCoeffs
) const;
//- Return the matrix diagonal coefficients corresponding to the
// evaluation of the gradient of this patchField
virtual tmp<Field<Type>> gradientInternalCoeffs() const;
//- Return the matrix source coefficients corresponding to the
// evaluation of the gradient of this patchField
virtual tmp<Field<Type>> gradientBoundaryCoeffs
(
const scalarField& deltaCoeffs
) const;
//- Return the matrix source coefficients corresponding to the
// evaluation of the gradient of this patchField
virtual tmp<Field<Type>> gradientBoundaryCoeffs() const;
//- Manipulate matrix
virtual void manipulateMatrix(fvMatrix<Type>& matrix);

View File

@ -43,7 +43,12 @@ void Foam::cyclicACMIFvPatch::updateAreas() const
{
if (cyclicACMIPolyPatch_.updated())
{
// Set Sf and magSf for both sides' coupled and non-overlapping patches
if (debug)
{
Pout<< "cyclicACMIFvPatch::updateAreas() : updating fv areas for "
<< name() << " and " << this->nonOverlapPatch().name()
<< endl;
}
// owner couple
const_cast<vectorField&>(Sf()) = patch().faceAreas();
@ -81,25 +86,37 @@ void Foam::cyclicACMIFvPatch::makeWeights(scalarField& w) const
if (coupled())
{
const cyclicACMIFvPatch& nbrPatch = neighbFvPatch();
const fvPatch& nbrPatchNonOverlap = nonOverlapPatch();
const scalarField deltas(nf() & coupledFvPatch::delta());
const scalarField nbrDeltas
// These deltas are of the cyclic part alone - they are
// not affected by the amount of overlap with the nonOverlapPatch
scalarField nbrDeltas
(
interpolate
(
nbrPatch.nf() & nbrPatch.coupledFvPatch::delta(),
nbrPatchNonOverlap.nf() & nbrPatchNonOverlap.delta()
nbrPatch.nf() & nbrPatch.coupledFvPatch::delta()
)
);
scalar tol = cyclicACMIPolyPatch::tolerance();
forAll(deltas, facei)
{
scalar di = deltas[facei];
scalar dni = nbrDeltas[facei];
w[facei] = dni/(di + dni);
if (dni < tol)
{
// Avoid zero weights on disconnected faces. This value
// will be weighted with the (zero) face area so will not
// influence calculations.
w[facei] = 1.0;
}
else
{
w[facei] = dni/(di + dni);
}
}
}
else
@ -122,30 +139,12 @@ Foam::tmp<Foam::vectorField> Foam::cyclicACMIFvPatch::delta() const
{
if (coupled())
{
const cyclicACMIFvPatch& nbrPatchCoupled = neighbFvPatch();
const fvPatch& nbrPatchNonOverlap = nonOverlapPatch();
const cyclicACMIFvPatch& nbrPatch = neighbFvPatch();
const vectorField patchD(coupledFvPatch::delta());
vectorField nbrPatchD
(
interpolate
(
nbrPatchCoupled.coupledFvPatch::delta(),
nbrPatchNonOverlap.delta()
)
);
vectorField nbrPatchD(interpolate(nbrPatch.coupledFvPatch::delta()));
const vectorField nbrPatchD0
(
interpolate
(
vectorField(nbrPatchCoupled.size(), Zero),
nbrPatchNonOverlap.delta()()
)
);
nbrPatchD -= nbrPatchD0;
tmp<vectorField> tpdv(new vectorField(patchD.size()));
vectorField& pdv = tpdv.ref();

View File

@ -174,10 +174,11 @@ public:
//- Return delta (P to N) vectors across coupled patch
virtual tmp<vectorField> delta() const;
//- Interpolate (make sure to have uptodate areas)
template<class Type>
tmp<Field<Type>> interpolate
(
const Field<Type>& fldCoupled
const Field<Type>& fld
) const
{
updateAreas();
@ -185,57 +186,18 @@ public:
return
cyclicACMIPolyPatch_.cyclicAMIPolyPatch::interpolate
(
fldCoupled
fld
);
}
//- Interpolate (make sure to have uptodate areas)
template<class Type>
tmp<Field<Type>> interpolate
(
const tmp<Field<Type>>& tfldCoupled
const tmp<Field<Type>>& tfld
) const
{
updateAreas();
return
cyclicACMIPolyPatch_.cyclicAMIPolyPatch::interpolate
(
tfldCoupled
);
}
template<class Type>
tmp<Field<Type>> interpolate
(
const Field<Type>& fldCoupled,
const Field<Type>& fldNonOverlap
) const
{
updateAreas();
return
cyclicACMIPolyPatch_.interpolate
(
fldCoupled,
fldNonOverlap
);
}
template<class Type>
tmp<Field<Type>> interpolate
(
const tmp<Field<Type>>& tFldCoupled,
const tmp<Field<Type>>& tFldNonOverlap
) const
{
updateAreas();
return
cyclicACMIPolyPatch_.interpolate
(
tFldCoupled,
tFldNonOverlap
);
return interpolate(tfld());
}

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License

View File

@ -378,10 +378,17 @@ public:
//- Return const access to source patch weights
inline const scalarListList& srcWeights() const;
//- Return access to source patch weights
inline scalarListList& srcWeights();
//- Return const access to normalisation factor of source
// patch weights (i.e. the sum before normalisation)
inline const scalarField& srcWeightsSum() const;
//- Return access to normalisation factor of source
// patch weights (i.e. the sum before normalisation)
inline scalarField& srcWeightsSum();
//- Source map pointer - valid only if singlePatchProc = -1
// This gets source data into a form to be consumed by
// tgtAddress, tgtWeights
@ -399,10 +406,17 @@ public:
//- Return const access to target patch weights
inline const scalarListList& tgtWeights() const;
//- Return access to target patch weights
inline scalarListList& tgtWeights();
//- Return const access to normalisation factor of target
// patch weights (i.e. the sum before normalisation)
inline const scalarField& tgtWeightsSum() const;
//- Return access to normalisation factor of target
// patch weights (i.e. the sum before normalisation)
inline scalarField& tgtWeightsSum();
//- Target map pointer - valid only if singlePatchProc=-1.
// This gets target data into a form to be consumed by
// srcAddress, srcWeights

View File

@ -72,6 +72,14 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::srcWeights() const
}
template<class SourcePatch, class TargetPatch>
inline Foam::scalarListList&
Foam::AMIInterpolation<SourcePatch, TargetPatch>::srcWeights()
{
return srcWeights_;
}
template<class SourcePatch, class TargetPatch>
inline const Foam::scalarField&
Foam::AMIInterpolation<SourcePatch, TargetPatch>::srcWeightsSum() const
@ -80,6 +88,14 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::srcWeightsSum() const
}
template<class SourcePatch, class TargetPatch>
inline Foam::scalarField&
Foam::AMIInterpolation<SourcePatch, TargetPatch>::srcWeightsSum()
{
return srcWeightsSum_;
}
template<class SourcePatch, class TargetPatch>
inline const Foam::mapDistribute&
Foam::AMIInterpolation<SourcePatch, TargetPatch>::srcMap() const
@ -112,6 +128,14 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::tgtWeights() const
}
template<class SourcePatch, class TargetPatch>
inline Foam::scalarListList&
Foam::AMIInterpolation<SourcePatch, TargetPatch>::tgtWeights()
{
return tgtWeights_;
}
template<class SourcePatch, class TargetPatch>
inline const Foam::scalarField&
Foam::AMIInterpolation<SourcePatch, TargetPatch>::tgtWeightsSum() const
@ -120,6 +144,14 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::tgtWeightsSum() const
}
template<class SourcePatch, class TargetPatch>
inline Foam::scalarField&
Foam::AMIInterpolation<SourcePatch, TargetPatch>::tgtWeightsSum()
{
return tgtWeightsSum_;
}
template<class SourcePatch, class TargetPatch>
inline const Foam::mapDistribute&
Foam::AMIInterpolation<SourcePatch, TargetPatch>::tgtMap() const

View File

@ -38,35 +38,10 @@ namespace Foam
addToRunTimeSelectionTable(polyPatch, cyclicACMIPolyPatch, dictionary);
}
const Foam::scalar Foam::cyclicACMIPolyPatch::tolerance_ = 1e-6;
const Foam::scalar Foam::cyclicACMIPolyPatch::tolerance_ = 1e-10;
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
void Foam::cyclicACMIPolyPatch::initPatchFaceAreas() const
{
if
(
!empty()
&& (faceAreas0_.empty() || boundaryMesh().mesh().moving())
)
{
faceAreas0_ = faceAreas();
}
const cyclicACMIPolyPatch& nbrACMI =
refCast<const cyclicACMIPolyPatch>(this->neighbPatch());
if
(
!nbrACMI.empty()
&& (nbrACMI.faceAreas0().empty() || boundaryMesh().mesh().moving())
)
{
nbrACMI.faceAreas0_ = nbrACMI.faceAreas();
}
}
void Foam::cyclicACMIPolyPatch::resetAMI
(
const AMIPatchToPatchInterpolation::interpolationMethod&
@ -76,37 +51,117 @@ void Foam::cyclicACMIPolyPatch::resetAMI
{
const polyPatch& nonOverlapPatch = this->nonOverlapPatch();
initPatchFaceAreas();
// Reset patch face areas based on original patch for AMI calculation
vectorField::subField Sf = faceAreas();
vectorField::subField noSf = nonOverlapPatch.faceAreas();
forAll(Sf, facei)
if (debug)
{
Sf[facei] = faceAreas0_[facei];
noSf[facei] = faceAreas0_[facei];
Pout<< "cyclicACMIPolyPatch::resetAMI : recalculating weights"
<< " for " << name() << " and " << nonOverlapPatch.name()
<< endl;
}
// Calculate the AMI using partial face-area-weighted
if (boundaryMesh().mesh().hasCellCentres())
{
WarningInFunction
<< "The mesh already has cellCentres calculated when"
<< " resetting ACMI " << name() << "." << endl
<< "This is a problem since ACMI adapts the face areas"
<< " (to close cells) so this has" << endl
<< "to be done before cell centre calculation." << endl
<< "This can happen if e.g. the cyclicACMI is after"
<< " any processor patches in the boundary." << endl
<< "Continuing with potential for incorrect geometry"
<< " calculation and mass loss" << endl;
}
// Trigger re-building of faceAreas
(void)boundaryMesh().mesh().faceAreas();
// Calculate the AMI using partial face-area-weighted. This leaves
// the weights as fractions of local areas (sum(weights) = 1 means
// face is fully covered)
cyclicAMIPolyPatch::resetAMI
(
AMIPatchToPatchInterpolation::imPartialFaceAreaWeight
);
AMIPatchToPatchInterpolation& AMI =
const_cast<AMIPatchToPatchInterpolation&>(this->AMI());
srcMask_ =
min(scalar(1) - tolerance_, max(tolerance_, AMI().srcWeightsSum()));
min(scalar(1) - tolerance_, max(tolerance_, AMI.srcWeightsSum()));
tgtMask_ =
min(scalar(1) - tolerance_, max(tolerance_, AMI().tgtWeightsSum()));
min(scalar(1) - tolerance_, max(tolerance_, AMI.tgtWeightsSum()));
forAll(Sf, facei)
// Adapt owner side areas. Note that in uncoupled situations (e.g.
// decomposePar) srcMask, tgtMask can be zero size.
if (srcMask_.size())
{
Sf[facei] *= srcMask_[facei];
noSf[facei] *= 1.0 - srcMask_[facei];
vectorField::subField Sf = faceAreas();
vectorField::subField noSf = nonOverlapPatch.faceAreas();
forAll(Sf, facei)
{
Sf[facei] *= srcMask_[facei];
noSf[facei] *= 1.0 - srcMask_[facei];
}
}
// Adapt slave side areas
if (tgtMask_.size())
{
const cyclicACMIPolyPatch& cp =
refCast<const cyclicACMIPolyPatch>(this->neighbPatch());
const polyPatch& pp = cp.nonOverlapPatch();
vectorField::subField Sf = cp.faceAreas();
vectorField::subField noSf = pp.faceAreas();
forAll(Sf, facei)
{
Sf[facei] *= tgtMask_[facei];
noSf[facei] *= 1.0 - tgtMask_[facei];
}
}
setNeighbourFaceAreas();
// Re-normalise the weights since the effect of overlap is already
// accounted for in the area.
{
scalarListList& srcWeights = AMI.srcWeights();
scalarField& srcWeightsSum = AMI.srcWeightsSum();
forAll(srcWeights, i)
{
scalarList& wghts = srcWeights[i];
if (wghts.size())
{
scalar& sum = srcWeightsSum[i];
forAll(wghts, j)
{
wghts[j] /= sum;
}
sum = 1.0;
}
}
}
{
scalarListList& tgtWeights = AMI.tgtWeights();
scalarField& tgtWeightsSum = AMI.tgtWeightsSum();
forAll(tgtWeights, i)
{
scalarList& wghts = tgtWeights[i];
if (wghts.size())
{
scalar& sum = tgtWeightsSum[i];
forAll(wghts, j)
{
wghts[j] /= sum;
}
sum = 1.0;
}
}
}
// Set the updated flag
updated_ = true;
@ -114,36 +169,13 @@ void Foam::cyclicACMIPolyPatch::resetAMI
}
void Foam::cyclicACMIPolyPatch::setNeighbourFaceAreas() const
{
const cyclicACMIPolyPatch& cp =
refCast<const cyclicACMIPolyPatch>(this->neighbPatch());
const polyPatch& pp = cp.nonOverlapPatch();
const vectorField& faceAreas0 = cp.faceAreas0();
if (tgtMask_.size() == cp.size())
{
vectorField::subField Sf = cp.faceAreas();
vectorField::subField noSf = pp.faceAreas();
forAll(Sf, facei)
{
Sf[facei] = tgtMask_[facei]*faceAreas0[facei];
noSf[facei] = (1.0 - tgtMask_[facei])*faceAreas0[facei];
}
}
else
{
WarningInFunction
<< "Target mask size differs to that of the neighbour patch\n"
<< " May occur when decomposing." << endl;
}
}
void Foam::cyclicACMIPolyPatch::initGeometry(PstreamBuffers& pBufs)
{
if (debug)
{
Pout<< "cyclicACMIPolyPatch::initGeometry : " << name() << endl;
}
cyclicAMIPolyPatch::initGeometry(pBufs);
// Initialise the AMI
@ -153,6 +185,10 @@ void Foam::cyclicACMIPolyPatch::initGeometry(PstreamBuffers& pBufs)
void Foam::cyclicACMIPolyPatch::calcGeometry(PstreamBuffers& pBufs)
{
if (debug)
{
Pout<< "cyclicACMIPolyPatch::calcGeometry : " << name() << endl;
}
cyclicAMIPolyPatch::calcGeometry(pBufs);
}
@ -163,6 +199,10 @@ void Foam::cyclicACMIPolyPatch::initMovePoints
const pointField& p
)
{
if (debug)
{
Pout<< "cyclicACMIPolyPatch::initMovePoints : " << name() << endl;
}
cyclicAMIPolyPatch::initMovePoints(pBufs, p);
// Initialise the AMI
@ -176,24 +216,40 @@ void Foam::cyclicACMIPolyPatch::movePoints
const pointField& p
)
{
if (debug)
{
Pout<< "cyclicACMIPolyPatch::movePoints : " << name() << endl;
}
cyclicAMIPolyPatch::movePoints(pBufs, p);
}
void Foam::cyclicACMIPolyPatch::initUpdateMesh(PstreamBuffers& pBufs)
{
if (debug)
{
Pout<< "cyclicACMIPolyPatch::initUpdateMesh : " << name() << endl;
}
cyclicAMIPolyPatch::initUpdateMesh(pBufs);
}
void Foam::cyclicACMIPolyPatch::updateMesh(PstreamBuffers& pBufs)
{
if (debug)
{
Pout<< "cyclicACMIPolyPatch::updateMesh : " << name() << endl;
}
cyclicAMIPolyPatch::updateMesh(pBufs);
}
void Foam::cyclicACMIPolyPatch::clearGeom()
{
if (debug)
{
Pout<< "cyclicACMIPolyPatch::clearGeom : " << name() << endl;
}
cyclicAMIPolyPatch::clearGeom();
}
@ -224,7 +280,6 @@ Foam::cyclicACMIPolyPatch::cyclicACMIPolyPatch
)
:
cyclicAMIPolyPatch(name, size, start, index, bm, patchType, transform),
faceAreas0_(),
nonOverlapPatchName_(word::null),
nonOverlapPatchID_(-1),
srcMask_(),
@ -248,7 +303,6 @@ Foam::cyclicACMIPolyPatch::cyclicACMIPolyPatch
)
:
cyclicAMIPolyPatch(name, dict, index, bm, patchType),
faceAreas0_(),
nonOverlapPatchName_(dict.lookup("nonOverlapPatch")),
nonOverlapPatchID_(-1),
srcMask_(),
@ -279,7 +333,6 @@ Foam::cyclicACMIPolyPatch::cyclicACMIPolyPatch
)
:
cyclicAMIPolyPatch(pp, bm),
faceAreas0_(),
nonOverlapPatchName_(pp.nonOverlapPatchName_),
nonOverlapPatchID_(-1),
srcMask_(),
@ -305,7 +358,6 @@ Foam::cyclicACMIPolyPatch::cyclicACMIPolyPatch
)
:
cyclicAMIPolyPatch(pp, bm, index, newSize, newStart, nbrPatchName),
faceAreas0_(),
nonOverlapPatchName_(nonOverlapPatchName),
nonOverlapPatchID_(-1),
srcMask_(),
@ -337,7 +389,6 @@ Foam::cyclicACMIPolyPatch::cyclicACMIPolyPatch
)
:
cyclicAMIPolyPatch(pp, bm, index, mapAddressing, newStart),
faceAreas0_(),
nonOverlapPatchName_(pp.nonOverlapPatchName_),
nonOverlapPatchID_(-1),
srcMask_(),

View File

@ -57,8 +57,8 @@ private:
// Private data
//- Copy of the original patch face areas
mutable vectorField faceAreas0_;
//- Fraction of face area below which face is considered disconnected
static const scalar tolerance_;
//- Name of non-overlapping patch
const word nonOverlapPatchName_;
@ -78,14 +78,8 @@ private:
protected:
static const scalar tolerance_;
// Protected Member Functions
//- Initialise patch face areas
virtual void initPatchFaceAreas() const;
//- Reset the AMI interpolator
virtual void resetAMI
(
@ -93,9 +87,6 @@ protected:
AMIPatchToPatchInterpolation::imFaceAreaWeight
) const;
//- Set neighbour ACMI patch areas
virtual void setNeighbourFaceAreas() const;
//- Initialise the calculation of the patch geometry
virtual void initGeometry(PstreamBuffers&);
@ -254,9 +245,6 @@ public:
//- Return access to the updated flag
inline bool updated() const;
//- Return access to the original patch face areas
inline const vectorField& faceAreas0() const;
//- Return a reference to the neighbour patch
virtual const cyclicACMIPolyPatch& neighbPatch() const;
@ -275,34 +263,8 @@ public:
//- Mask field where 1 = overlap, 0 = no-overlap
inline const scalarField& mask() const;
// Interpolations
//- Interpolate field
template<class Type>
tmp<Field<Type>> interpolate
(
const Field<Type>& fldCouple,
const Field<Type>& fldNonOverlap
) const;
//- Interpolate tmp field
template<class Type>
tmp<Field<Type>> interpolate
(
const tmp<Field<Type>>& tFldCouple,
const tmp<Field<Type>>& tFldNonOverlap
) const;
//- Low-level interpolate List
template<class Type, class CombineOp>
void interpolate
(
const UList<Type>& fldCouple,
const UList<Type>& fldNonOverlap,
const CombineOp& cop,
List<Type>& result
) const;
//- Overlap tolerance
inline static scalar tolerance();
//- Calculate the patch geometry
@ -353,12 +315,6 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "cyclicACMIPolyPatchTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2013-2016 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -37,12 +37,6 @@ inline bool Foam::cyclicACMIPolyPatch::updated() const
}
inline const Foam::vectorField& Foam::cyclicACMIPolyPatch::faceAreas0() const
{
return faceAreas0_;
}
inline const Foam::word& Foam::cyclicACMIPolyPatch::nonOverlapPatchName() const
{
return nonOverlapPatchName_;
@ -80,4 +74,10 @@ inline const Foam::scalarField& Foam::cyclicACMIPolyPatch::mask() const
}
inline Foam::scalar Foam::cyclicACMIPolyPatch::tolerance()
{
return tolerance_;
}
// ************************************************************************* //

View File

@ -1,87 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013-2016 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
template<class Type>
Foam::tmp<Foam::Field<Type>> Foam::cyclicACMIPolyPatch::interpolate
(
const Field<Type>& fldCouple,
const Field<Type>& fldNonOverlap
) const
{
// Note: do not scale AMI field as face areas have already been taken into
// account
if (owner())
{
return
AMI().interpolateToSource(fldCouple)
+ (1.0 - AMI().srcWeightsSum())*fldNonOverlap;
}
else
{
return
neighbPatch().AMI().interpolateToTarget(fldCouple)
+ (1.0 - neighbPatch().AMI().tgtWeightsSum())*fldNonOverlap;
}
}
template<class Type>
Foam::tmp<Foam::Field<Type>> Foam::cyclicACMIPolyPatch::interpolate
(
const tmp<Field<Type>>& tFldCouple,
const tmp<Field<Type>>& tFldNonOverlap
) const
{
return interpolate(tFldCouple(), tFldNonOverlap());
}
template<class Type, class CombineOp>
void Foam::cyclicACMIPolyPatch::interpolate
(
const UList<Type>& fldCouple,
const UList<Type>& fldNonOverlap,
const CombineOp& cop,
List<Type>& result
) const
{
// Note: do not scale AMI field as face areas have already been taken into
// account
if (owner())
{
AMI().interpolateToSource(fldCouple, cop, result);
result += (1.0 - AMI().srcWeightsSum())*fldNonOverlap;
}
else
{
neighbPatch().AMI().interpolateToTarget(fldCouple, cop, result);
result += (1.0 - neighbPatch().AMI().tgtWeightsSum())*fldNonOverlap;
}
}
// ************************************************************************* //

View File

@ -13,7 +13,6 @@ if [ -d 0 ] ; then
rm -rf 0
fi
runApplication createPatch -overwrite
runApplication createBaffles -overwrite
runApplication mergeOrSplitBaffles -split -overwrite

View File

@ -1,28 +0,0 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object createPatchDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Do a synchronisation of coupled points after creation of any patches.
// Note: this does not work with points that are on multiple coupled patches
// with transformations (i.e. cyclics).
pointSync false;
// Patches to create. An empty patch list just removes patches with zero
// faces from $FOAM_CASE/constant/polyMesh/boundary.
patches
(
);
// ************************************************************************* //

View File

@ -11,7 +11,4 @@ runApplication topoSet -constant
# split the mesh to generate the ACMI coupled patches
runApplication createBaffles -overwrite
# remove zero-sized patches
runApplication createPatch -overwrite
cp -rf 0.orig 0

View File

@ -1,54 +0,0 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object createPatchDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// This application/dictionary controls:
// - optional: create new patches from boundary faces (either given as
// a set of patches or as a faceSet)
// - always: order faces on coupled patches such that they are opposite. This
// is done for all coupled faces, not just for any patches created.
// - optional: synchronise points on coupled patches.
// 1. Create cyclic:
// - specify where the faces should come from
// - specify the type of cyclic. If a rotational specify the rotationAxis
// and centre to make matching easier
// - always create both halves in one invocation with correct 'neighbourPatch'
// setting.
// - optionally pointSync true to guarantee points to line up.
// 2. Correct incorrect cyclic:
// This will usually fail upon loading:
// "face 0 area does not match neighbour 2 by 0.0100005%"
// " -- possible face ordering problem."
// - in polyMesh/boundary file:
// - loosen matchTolerance of all cyclics to get case to load
// - or change patch type from 'cyclic' to 'patch'
// and regenerate cyclic as above
// Do a synchronisation of coupled points after creation of any patches.
// Note: this does not work with points that are on multiple coupled patches
// with transformations (i.e. cyclics).
pointSync false;
// Patches to create.
patches
(
// none
);
// ************************************************************************* //