Go to the documentation of this file.
58 if (!
mesh.upToDatePoints(AMITime_))
64 <<
" mesh points are up to time " <<
mesh.pointsInstance()
65 <<
" patch:" << this->
name()
73 && (updated || prevTimeIndex_ !=
mesh.time().timeIndex())
78 Pout<<
"cyclicACMIPolyPatch::updateAreas() :"
79 <<
" patch:" << this->
name()
81 <<
" AMITime_:" << AMITime_.
eventNo()
82 <<
" uptodate:" <<
mesh.upToDatePoints(AMITime_)
83 <<
" mesh.time().timeIndex():" <<
mesh.time().timeIndex()
84 <<
" prevTimeIndex_:" << prevTimeIndex_
91 <<
"Topology changes and scaling currently not supported."
92 <<
" Patch " << this->
name() <<
endl;
95 const scalar t =
mesh.time().timeOutputValue();
106 if (!tgtScalePtr_.valid())
120 Pout<<
"cyclicACMIPolyPatch::updateAreas : scaling masks"
121 <<
" for " <<
name() <<
" mask " <<
gAverage(srcScaledMask_)
130 cpp.scalePatchFaceAreas(*
this, srcScaledMask_, thisSf_, thisNoSf_);
131 cpp.scalePatchFaceAreas(nbrCpp, tgtScaledMask_, nbrSf_, nbrNoSf_);
133 prevTimeIndex_ =
mesh.time().timeIndex();
147 return io.upToDate(AMITime_);
163 label nUncovered = 0;
165 for (
const scalar
sum : weightSum)
167 if (
sum < tolerance_)
171 else if (
sum > scalar(1) - tolerance_)
176 reduce(nUncovered, sumOp<label>());
177 reduce(nCovered, sumOp<label>());
178 label nTotal =
returnReduce(weightSum.size(), sumOp<label>());
180 Info<<
"ACMI: Patch " <<
name <<
" uncovered/blended/covered = "
181 << nUncovered <<
", " << nTotal-nUncovered-nCovered
182 <<
", " << nCovered <<
endl;
197 const scalar maxTol = scalar(1) - tolerance_;
203 <<
"rescaling non-overlap patch areas for: "
206 if (mask.size() != noSf.size())
209 <<
"Inconsistent sizes for patch: " << acmipp.
name()
210 <<
" - not manipulating patches" <<
nl
211 <<
" - size: " << size() <<
nl
212 <<
" - non-overlap patch size: " << noSf.size() <<
nl
213 <<
" - mask size: " << mask.size() <<
nl
214 <<
"This is OK for decomposition but"
215 <<
" should be considered fatal at run-time" <<
endl;
222 const scalar w =
min(maxTol,
max(tolerance_, mask[facei]));
223 noSf[facei] = noFaceArea[facei]*(scalar(1) - w);
226 if (!createAMIFaces_)
233 <<
"scaling coupled patch areas for: " << acmipp.
name() <<
endl;
240 Sf[facei] = faceArea[facei]*
max(tolerance_, mask[facei]);
252 scalar&
sum = weightsSum[i];
278 const polyPatch& nonOverlapPatch = this->nonOverlapPatch();
281 <<
"cyclicACMIPolyPatch::resetAMI : recalculating weights"
282 <<
" for " <<
name() <<
" and " << nonOverlapPatch.name()
285 const polyMesh&
mesh = boundaryMesh().mesh();
290 <<
"cyclicACMIPolyPatch::resetAMI : clearing cellCentres"
291 <<
" for " <<
name() <<
" and " << nonOverlapPatch.name() <<
nl
292 <<
"The mesh already has cellCentres calculated when"
293 <<
" resetting ACMI " <<
name() <<
"." <<
nl
294 <<
"This is a problem since ACMI adapts the face areas"
295 <<
" (to close cells) so this has" <<
nl
296 <<
"to be done before cell centre calculation." <<
nl
297 <<
"This can happen if e.g. the cyclicACMI is after"
298 <<
" any processor patches in the boundary." <<
endl;
309 <<
"primitiveMesh must already have face geometry"
321 reportCoverage(
"source", AMI.srcWeightsSum());
322 reportCoverage(
"target", AMI.tgtWeightsSum());
328 srcMask_ =
min(scalar(1),
max(scalar(0), AMI.srcWeightsSum()));
329 tgtMask_ =
min(scalar(1),
max(scalar(0), AMI.tgtWeightsSum()));
335 const cyclicACMIPolyPatch&
patch = *
this;
337 <<
" non-overlap patch: " <<
patch.nonOverlapPatch().name()
338 <<
" size:" <<
patch.nonOverlapPatch().size()
339 <<
" mask size:" <<
patch.srcMask().size() <<
endl;
342 const cyclicACMIPolyPatch&
patch = this->neighbPatch();
344 <<
" non-overlap patch: " <<
patch.nonOverlapPatch().name()
345 <<
" size:" <<
patch.nonOverlapPatch().size()
346 <<
" mask size:" <<
patch.neighbPatch().tgtMask().size()
355 if (!owner() || !canResetAMI())
360 const polyPatch& nonOverlapPatch = this->nonOverlapPatch();
361 const cyclicACMIPolyPatch& nbrPatch = this->neighbPatch();
362 const polyPatch& nbrNonOverlapPatch = nbrPatch.nonOverlapPatch();
364 if (srcScalePtr_.valid())
367 thisSf_ = this->faceAreas();
368 thisNoSf_ = nonOverlapPatch.faceAreas();
369 nbrSf_ = nbrPatch.faceAreas();
370 nbrNoSf_ = nbrNonOverlapPatch.faceAreas();
379 nonOverlapPatch.faceAreas()
385 nbrPatch.faceAreas(),
386 nbrNonOverlapPatch.faceAreas()
403 if (!createAMIFaces_ && canResetAMI())
408 scalePatchFaceAreas();
431 if (!createAMIFaces_ && canResetAMI())
436 scalePatchFaceAreas();
442 PstreamBuffers& pBufs,
479 if (srcScalePtr_.valid())
484 return srcScaledMask_;
495 if (tgtScalePtr_.valid())
500 return tgtScaledMask_;
517 const polyBoundaryMesh& bm,
518 const word& patchType,
520 const word& defaultAMIMethod
534 nonOverlapPatchName_(word::null),
535 nonOverlapPatchID_(-1),
543 boundaryMesh().
mesh().pointsInstance(),
544 boundaryMesh().
mesh(),
553 AMIPtr_->setRequireMatch(
false);
566 const word& patchType,
567 const word& defaultAMIMethod
571 nonOverlapPatchName_(
dict.
get<
word>(
"nonOverlapPatch")),
572 nonOverlapPatchID_(-1),
596 AMIPtr_->setRequireMatch(
false);
598 if (nonOverlapPatchName_ ==
name)
601 <<
"Non-overlapping patch name " << nonOverlapPatchName_
602 <<
" cannot be the same as this patch " <<
name
618 nonOverlapPatchName_(pp.nonOverlapPatchName_),
619 nonOverlapPatchID_(-1),
624 pp.srcScalePtr_.valid()
625 ? pp.srcScalePtr_.clone(*this)
643 AMIPtr_->setRequireMatch(
false);
656 const label newStart,
657 const word& nbrPatchName,
658 const word& nonOverlapPatchName
662 nonOverlapPatchName_(nonOverlapPatchName),
663 nonOverlapPatchID_(-1),
668 pp.srcScalePtr_.valid()
669 ? pp.srcScalePtr_.clone(*this)
687 AMIPtr_->setRequireMatch(
false);
689 if (nonOverlapPatchName_ ==
name())
692 <<
"Non-overlapping patch name " << nonOverlapPatchName_
693 <<
" cannot be the same as this patch " <<
name()
712 nonOverlapPatchName_(pp.nonOverlapPatchName_),
713 nonOverlapPatchID_(-1),
718 pp.srcScalePtr_.valid()
719 ? pp.srcScalePtr_.clone(*this)
753 forAll (addSourceFaces, faceI)
755 if (fMask[faceI] > tolerance_)
757 const labelList& nbrFaceIs = addSourceFaces[faceI];
761 label nbrFaceI = nbrFaceIs[j];
763 if (nbrFaceI < neighbPatch().size())
785 dOverFaces.
setSize(srcFaces.size());
786 forAll (dOverFaces, faceI)
788 if (fMask[faceI] > tolerance_)
790 dOverFaces[faceI].setSize(srcFaces[faceI].size());
792 forAll (dOverFaces[faceI], subFaceI)
794 dOverFaces[faceI][subFaceI] = srcFaces[faceI][subFaceI];
804 const polyPatch& pp = this->boundaryMesh()[neighbPatchID()];
807 if (!owner() && srcScalePtr_.valid())
810 <<
"Ignoring \"scale\" setting in slave patch " <<
name()
812 srcScalePtr_.clear();
813 tgtScalePtr_.clear();
816 return refCast<const cyclicACMIPolyPatch>(pp);
822 if (nonOverlapPatchID_ == -1)
825 this->boundaryMesh().findPatchID(nonOverlapPatchName_);
827 if (nonOverlapPatchID_ == -1)
830 <<
"Illegal non-overlapping patch name " << nonOverlapPatchName_
831 <<
nl <<
"Valid patch names are "
832 << this->boundaryMesh().names()
836 if (nonOverlapPatchID_ < index())
839 <<
"Boundary ordering error: " <<
type()
840 <<
" patch must be defined prior to its non-overlapping patch"
842 <<
type() <<
" patch: " <<
name() <<
", ID:" << index() <<
nl
843 <<
"Non-overlap patch: " << nonOverlapPatchName_
844 <<
", ID:" << nonOverlapPatchID_ <<
nl
848 const polyPatch& noPp = this->boundaryMesh()[nonOverlapPatchID_];
852 if (size() == noPp.size())
859 scalar ratio =
mag(magSf[facei]/(noMagSf[facei] + ROOTVSMALL));
861 if (ratio - 1 > tolerance_)
876 <<
"Inconsistent ACMI patches " <<
name() <<
" and "
877 << noPp.name() <<
". Patches should have identical topology"
882 return nonOverlapPatchID_;
888 PstreamBuffers& pBufs,
914 if (owner() && srcScalePtr_.valid())
916 srcScalePtr_->writeData(
os);
addToRunTimeSelectionTable(decompositionMethod, kahipDecomp, dictionary)
virtual bool order(PstreamBuffers &, const primitivePatch &, labelList &faceMap, labelList &rotation) const
vectorField pointField
pointField is a vectorField.
List< scalarList > scalarListList
A List of scalarList.
const bMesh & mesh() const
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
Defines the attributes of an object for which implicit objectRegistry management is supported,...
List< scalar > scalarList
A List of scalars.
virtual void calcGeometry(PstreamBuffers &)
virtual void movePoints(PstreamBuffers &pBufs, const pointField &)
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
virtual void resetAMI() const
virtual bool owner() const
A class for handling words, derived from Foam::string.
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
A polyBoundaryMesh is a polyPatch list with additional search methods and registered IO.
bool upToDate(const regIOobject &) const
virtual void initOrder(PstreamBuffers &, const primitivePatch &) const
bool found(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Type gAverage(const FieldField< Field, Type > &f)
bool upToDate(const regIOobject &) const
virtual void initGeometry(PstreamBuffers &)
Buffers for inter-processor communications streams (UOPstream, UIPstream).
const scalarListList & weights() const
void setUpToDate(regIOobject &) const
static const scalar tolerance_
Ostream & endl(Ostream &os)
T get(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
virtual void resetAMI() const
dimensionSet transform(const dimensionSet &ds)
virtual void newInternalProcFaces(label &, label &) const
label min(const labelHashSet &set, label minValue=labelMax)
Mesh consisting of general polyhedral cells.
virtual void initMovePoints(PstreamBuffers &pBufs, const pointField &)
virtual void updateMesh(PstreamBuffers &)
SubField is a Field obtained as a section of another Field, without its own allocation....
const polyPatch & nonOverlapPatch() const
const dimensionSet dimTime(0, 0, 1, 0, 0, 0, 0)
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
virtual void updateMesh(PstreamBuffers &)
virtual void write(Ostream &) const
const polyMesh & mesh() const noexcept
const scalarField & weightsSum() const
virtual void calcGeometry(PstreamBuffers &)
Generic templated field type.
virtual void write(Ostream &) const
const polyBoundaryMesh & boundaryMesh() const
autoPtr< AMIPatchToPatchInterpolation > AMIPtr_
A patch is a list of labels that address the faces in the global face list.
virtual const scalarField & srcMask() const
void setSize(const label n)
virtual void movePoints(PstreamBuffers &pBufs, const pointField &)
const scalarField & srcWeightsSum() const
bool hasCellCentres() const noexcept
bool hasFaceAreas() const noexcept
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
cyclicACMIPolyPatch(const word &name, const label size, const label start, const label index, const polyBoundaryMesh &bm, const word &patchType, const transformType transform=UNKNOWN, const word &defaultAMIMethod=faceAreaWeightAMI::typeName)
virtual bool order(PstreamBuffers &, const primitivePatch &, labelList &faceMap, labelList &rotation) const
label max(const labelHashSet &set, label maxValue=labelMin)
virtual void initOrder(PstreamBuffers &, const primitivePatch &) const
virtual label nonOverlapPatchID() const
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
OBJstream os(runTime.globalPath()/outputName)
Macros for easy insertion into run-time selection tables.
Top level data entry class for use in dictionaries. Provides a mechanism to specify a variable as a c...
Generic dimensioned Type class.
errorManip< error > abort(error &err)
errorManipArg< error, int > exit(error &err, const int errNo=1)
virtual void initMovePoints(PstreamBuffers &pBufs, const pointField &)
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh >> &tdf1, const word &name, const dimensionSet &dimensions)
virtual void scalePatchFaceAreas()
List< labelList > labelListList
A List of labelList.
regIOobject is an abstract class derived from IOobject to handle automatic object registration with t...
#define FatalErrorInFunction
virtual const cyclicACMIPolyPatch & neighbPatch() const
virtual refPtr< labelListList > mapCollocatedFaces() const
virtual void initUpdateMesh(PstreamBuffers &)
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
const vectorField::subField faceAreas() const
virtual bool updateAreas() const
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
fileName::Type type(const fileName &name, const bool followLink=true)
Interpolation class dealing with transfer of data between two primitive patches with an arbitrary mes...
AMIInterpolation AMIPatchToPatchInterpolation
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &df)
Ostream & writeEntry(const keyType &key, const T &value)
List< ReturnType > get(const UPtrList< T > &list, const AccessOp &aop)
word name(const expressions::valueTypeCode typeCode)
Addressing for all faces on surface of mesh. Can either be read from polyMesh or from triSurface....
PrimitivePatch< SubList< face >, const pointField & > primitivePatch
A PrimitivePatch with a SubList addressing for the faces, const reference for the point field.
SubField< Type > subField
#define FatalIOErrorInFunction(ios)
const word & name() const noexcept
virtual const scalarField & tgtMask() const
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Cyclic patch for Arbitrarily Coupled Mesh Interface (ACMI).
defineTypeNameAndDebug(combustionModel, 0)
#define WarningInFunction
const scalarField & tgtWeightsSum() const
A class for managing references or pointers (no reference counting)
A list of faces which address into the list of points.
virtual void initGeometry(PstreamBuffers &)
void reportCoverage(const word &name, const scalarField &weightSum) const
virtual void initUpdateMesh(PstreamBuffers &)
Cyclic patch for Arbitrary Mesh Interface (AMI)