59 if (!
mesh.upToDatePoints(AMITime_))
65 <<
" mesh points are up to time " <<
mesh.pointsInstance()
66 <<
" patch:" << this->
name()
74 && (updated || prevTimeIndex_ !=
mesh.time().timeIndex())
79 Pout<<
"cyclicACMIPolyPatch::updateAreas() :" 80 <<
" patch:" << this->
name()
82 <<
" AMITime_:" << AMITime_.
eventNo()
83 <<
" uptodate:" <<
mesh.upToDatePoints(AMITime_)
84 <<
" mesh.time().timeIndex():" <<
mesh.time().timeIndex()
85 <<
" prevTimeIndex_:" << prevTimeIndex_
92 <<
"Topology changes and scaling currently not supported." 93 <<
" Patch " << this->
name() <<
endl;
96 const scalar t =
mesh.time().timeOutputValue();
121 Pout<<
"cyclicACMIPolyPatch::updateAreas : scaling masks" 122 <<
" for " <<
name() <<
" mask " <<
gAverage(srcScaledMask_)
131 cpp.scalePatchFaceAreas(*
this, srcScaledMask_, thisSf_, thisNoSf_);
132 cpp.scalePatchFaceAreas(nbrCpp, tgtScaledMask_, nbrSf_, nbrNoSf_);
134 prevTimeIndex_ =
mesh.time().timeIndex();
148 return io.upToDate(AMITime_);
164 label nUncovered = 0;
166 for (
const scalar
sum : weightSum)
168 if (
sum < tolerance_)
172 else if (
sum > scalar(1) - tolerance_)
177 reduce(nUncovered, sumOp<label>());
178 reduce(nCovered, sumOp<label>());
179 label nTotal =
returnReduce(weightSum.size(), sumOp<label>());
181 Info<<
"ACMI: Patch " <<
name <<
" uncovered/blended/covered = " 182 << nUncovered <<
", " << nTotal-nUncovered-nCovered
183 <<
", " << nCovered <<
endl;
197 const scalar maxTol = scalar(1) - tolerance_;
203 <<
"rescaling non-overlap patch areas for: " 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];
254 for (scalar& w : wghts)
263 const polyMesh&
mesh = boundaryMesh().mesh();
295 const polyPatch& nonOverlapPatch = this->nonOverlapPatch();
298 <<
"cyclicACMIPolyPatch::resetAMI : recalculating weights" 299 <<
" for " <<
name() <<
" and " << nonOverlapPatch.name()
302 const polyMesh&
mesh = boundaryMesh().mesh();
310 <<
"primitiveMesh must already have face geometry" 322 reportCoverage(
"source", AMI.srcWeightsSum());
323 reportCoverage(
"target", AMI.tgtWeightsSum());
329 srcMask_ =
clamp(AMI.srcWeightsSum(), zero_one{});
330 tgtMask_ =
clamp(AMI.tgtWeightsSum(), zero_one{});
336 const cyclicACMIPolyPatch&
patch = *
this;
338 <<
" non-overlap patch: " <<
patch.nonOverlapPatch().name()
339 <<
" size:" <<
patch.nonOverlapPatch().size()
343 const cyclicACMIPolyPatch&
patch = this->neighbPatch();
345 <<
" non-overlap patch: " <<
patch.nonOverlapPatch().name()
346 <<
" size:" <<
patch.nonOverlapPatch().size()
355 if (!owner() || !canResetAMI())
360 const polyPatch& nonOverlapPatch = this->nonOverlapPatch();
361 const cyclicACMIPolyPatch& nbrPatch = this->neighbPatch();
362 const polyPatch& nbrNonOverlapPatch = nbrPatch.nonOverlapPatch();
369 thisSf_ = this->faceAreas();
370 thisNoSf_ = nonOverlapPatch.faceAreas();
371 nbrSf_ = nbrPatch.faceAreas();
372 nbrNoSf_ = nbrNonOverlapPatch.faceAreas();
385 nonOverlapPatch.primitivePatch::faceAreas()
391 nbrPatch.primitivePatch::faceAreas(),
392 nbrNonOverlapPatch.primitivePatch::faceAreas()
396 boundaryMesh().mesh().setUpToDatePoints(AMITime_);
400 const auto& acmipp = *
this;
401 const auto&
mesh = boundaryMesh().mesh();
404 Info<<
"cyclicACMI PP: " << acmipp.
name()
407 <<
"cyclicACMI N-O PP: " << nonOverlapPatch.name()
410 <<
"cyclicACMI NBR PP: " << nbrPatch.name()
413 <<
"cyclicACMI NBR N-O PP: " << nbrNonOverlapPatch.name()
414 <<
" V:" <<
sum(
scalarField(vols, nbrNonOverlapPatch.faceCells()))
416 <<
"cyclicACMI PP+N-O AREA: " 417 <<
sum(faceAreas() + nonOverlapPatch.faceAreas()) <<
nl 418 <<
"cyclicACMI NBR PP+N-O AREA: " 419 <<
sum(nbrPatch.faceAreas() + nbrNonOverlapPatch.faceAreas())
434 if (!createAMIFaces_ && canResetAMI())
439 scalePatchFaceAreas();
462 if (!createAMIFaces_ && canResetAMI())
467 scalePatchFaceAreas();
473 PstreamBuffers& pBufs,
515 return srcScaledMask_;
531 return tgtScaledMask_;
548 const polyBoundaryMesh& bm,
549 const word& patchType,
551 const word& defaultAMIMethod
565 nonOverlapPatchName_(),
566 nonOverlapPatchID_(-1),
574 boundaryMesh().
mesh().pointsInstance(),
575 boundaryMesh().
mesh(),
578 IOobject::NO_REGISTER
584 AMIPtr_->setRequireMatch(
false);
597 const word& patchType,
598 const word& defaultAMIMethod
602 nonOverlapPatchName_(
dict.
get<
word>(
"nonOverlapPatch")),
603 nonOverlapPatchID_(-1),
622 AMIPtr_->setRequireMatch(
false);
624 if (nonOverlapPatchName_ ==
name)
627 <<
"Non-overlapping patch name " << nonOverlapPatchName_
628 <<
" cannot be the same as this patch " <<
name 644 nonOverlapPatchName_(
pp.nonOverlapPatchName_),
645 nonOverlapPatchID_(-1),
648 srcScalePtr_(
pp.srcScalePtr_.clone(*this)),
664 AMIPtr_->setRequireMatch(
false);
677 const label newStart,
678 const word& nbrPatchName,
679 const word& nonOverlapPatchName
683 nonOverlapPatchName_(nonOverlapPatchName),
684 nonOverlapPatchID_(-1),
687 srcScalePtr_(
pp.srcScalePtr_.clone(*this)),
703 AMIPtr_->setRequireMatch(
false);
705 if (nonOverlapPatchName_ ==
name())
708 <<
"Non-overlapping patch name " << nonOverlapPatchName_
709 <<
" cannot be the same as this patch " <<
name()
728 nonOverlapPatchName_(
pp.nonOverlapPatchName_),
729 nonOverlapPatchID_(-1),
732 srcScalePtr_(
pp.srcScalePtr_.clone(*this)),
764 forAll(addSourceFaces, faceI)
766 if (fMask[faceI] > tolerance_)
768 const labelList& nbrFaceIs = addSourceFaces[faceI];
772 label nbrFaceI = nbrFaceIs[j];
774 if (nbrFaceI < neighbPatch().size())
797 dOverFaces.
setSize(srcFaces.size());
800 if (fMask[faceI] > tolerance_)
802 dOverFaces[faceI].setSize(srcFaces[faceI].size());
804 forAll(dOverFaces[faceI], subFaceI)
806 dOverFaces[faceI][subFaceI] = srcFaces[faceI][subFaceI];
816 const polyPatch&
pp = this->boundaryMesh()[neighbPatchID()];
819 if (!owner() && srcScalePtr_)
822 <<
"Ignoring \"scale\" setting in slave patch " <<
name()
824 srcScalePtr_.clear();
825 tgtScalePtr_.clear();
828 return refCast<const cyclicACMIPolyPatch>(
pp);
834 if (nonOverlapPatchID_ == -1)
837 this->boundaryMesh().findPatchID(nonOverlapPatchName_);
839 if (nonOverlapPatchID_ == -1)
842 <<
"Illegal non-overlapping patch name " << nonOverlapPatchName_
843 <<
nl <<
"Valid patch names are " 844 << this->boundaryMesh().names()
848 if (nonOverlapPatchID_ < index())
851 <<
"Boundary ordering error: " <<
type()
852 <<
" patch must be defined prior to its non-overlapping patch" 854 <<
type() <<
" patch: " <<
name() <<
", ID:" << index() <<
nl 855 <<
"Non-overlap patch: " << nonOverlapPatchName_
856 <<
", ID:" << nonOverlapPatchID_ <<
nl 860 const polyPatch& noPp = this->boundaryMesh()[nonOverlapPatchID_];
864 if (size() == noPp.size())
871 scalar ratio =
mag(magSf[facei]/(noMagSf[facei] + ROOTVSMALL));
873 if (ratio - 1 > tolerance_)
888 <<
"Inconsistent ACMI patches " <<
name() <<
" and " 889 << noPp.name() <<
". Patches should have identical topology" 894 return nonOverlapPatchID_;
900 PstreamBuffers& pBufs,
926 if (owner() && srcScalePtr_)
928 srcScalePtr_->writeData(
os);
List< ReturnType > get(const UPtrList< T > &list, const AccessOp &aop)
List of values generated by applying the access operation to each list item.
List< T > uniqueSort(const UList< T > &input)
Return sorted list with removal of duplicates.
virtual void clearGeom()
Clear geometry.
List< scalar > scalarList
List of scalar.
virtual void resetAMI() const
Reset the AMI interpolator, use current patch points.
const Field< point_type > & faceAreas() const
Return face area vectors for patch.
Cyclic patch for Arbitrarily Coupled Mesh Interface (ACMI).
void size(const label n)
Older name for setAddressableSize.
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &f1)
virtual bool order(PstreamBuffers &, const primitivePatch &, labelList &faceMap, labelList &rotation) const
Return new ordering for primitivePatch.
virtual const cyclicACMIPolyPatch & neighbPatch() const
Return a reference to the neighbour patch.
virtual void initUpdateMesh(PstreamBuffers &)
Initialise the update of the patch topology.
errorManipArg< error, int > exit(error &err, const int errNo=1)
virtual void initUpdateMesh(PstreamBuffers &)
Initialise the update of the patch topology.
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
virtual void initGeometry(PstreamBuffers &)
Initialise the calculation of the patch geometry.
virtual bool updateAreas() const
Update the AMI and patch areas. Return true if anything.
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
A list of keyword definitions, which are a keyword followed by a number of values (eg...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
AMIInterpolation AMIPatchToPatchInterpolation
Patch-to-patch interpolation == Foam::AMIInterpolation.
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
void setUpToDate()
Set as up-to-date.
virtual void write(Ostream &) const
Write the polyPatch data as a dictionary.
constexpr char nl
The newline '\n' character (0x0a)
label eventNo() const noexcept
Event number at last update.
virtual void updateMesh(PstreamBuffers &)
Update of the patch topology.
static const scalar tolerance_
Tolerance used e.g. for area calculations/limits.
Addressing for all faces on surface of mesh. Can either be read from polyMesh or from triSurface...
Ostream & endl(Ostream &os)
Add newline and flush stream.
void setUpToDate(regIOobject &) const
Set object up to date with *this.
Ostream & writeEntry(const keyType &key, const T &value)
Write a keyword/value entry.
const cellList & cells() const
virtual const scalarField & tgtMask() const
Return the mask/weighting for the target patch.
virtual void calcGeometry(PstreamBuffers &)
Calculate the patch geometry.
SubField is a Field obtained as a section of another Field, without its own allocation. SubField is derived from a SubList rather than a List.
T returnReduce(const T &value, const BinaryOp &bop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Perform reduction on a copy, using specified binary operation.
List< labelList > labelListList
List of labelList.
virtual void write(Ostream &) const
Write the polyPatch data as a dictionary.
A class for managing references or pointers (no reference counting)
void reportCoverage(const word &name, const scalarField &weightSum) const
Report coverage statics, e.g. number of uncovered/blended/covered faces.
Macros for easy insertion into run-time selection tables.
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
bool createAMIFaces_
Flag to indicate that new AMI faces will created.
#define forAll(list, i)
Loop across all elements in list.
virtual void calcGeometry(PstreamBuffers &)
Calculate the patch geometry.
const polyPatch & nonOverlapPatch() const
Return a const reference to the non-overlapping patch.
virtual void newInternalProcFaces(label &, label &) const
Return number of new internal sub-faces and new proc faces.
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
A list of faces which address into the list of points.
virtual void movePoints(PstreamBuffers &pBufs, const pointField &)
Correct patches after moving points.
vectorField pointField
pointField is a vectorField.
void setSize(const label n)
Alias for resize()
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
virtual const scalarField & srcMask() const
Return the mask/weighting for the source patch.
const polyBoundaryMesh & boundaryMesh() const noexcept
Return boundaryMesh reference.
virtual void scalePatchFaceAreas()
Scale patch face areas to maintain physical area.
const labelUList & faceCells() const
Return face-cell addressing.
const polyMesh & mesh() const noexcept
Return the mesh reference.
List< scalarList > scalarListList
List of scalarList.
A class for handling words, derived from Foam::string.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
autoPtr< AMIPatchToPatchInterpolation > AMIPtr_
AMI interpolation class.
virtual void updateMesh(PstreamBuffers &)
Update of the patch topology.
virtual void initMovePoints(PstreamBuffers &pBufs, const pointField &)
Initialise the patches for moving points.
Cyclic patch for Arbitrary Mesh Interface (AMI)
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
const vectorField & cellCentres() const
errorManip< error > abort(error &err)
const scalarField & weightsSum() const
Helper function to return the weights sum.
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
A polyBoundaryMesh is a polyPatch list with additional search methods and registered IO...
virtual void clearGeom()
Clear geometry.
const word & name() const noexcept
The patch name.
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Top level data entry class for use in dictionaries. Provides a mechanism to specify a variable as a c...
const vectorField::subField faceAreas() const
Return face normals.
int debug
Static debugging option.
virtual bool order(PstreamBuffers &, const primitivePatch &, labelList &faceMap, labelList &rotation) const
Return new ordering for primitivePatch.
OBJstream os(runTime.globalPath()/outputName)
virtual void initGeometry(PstreamBuffers &)
Initialise the calculation of the patch geometry.
defineTypeNameAndDebug(combustionModel, 0)
bool hasFaceAreas() const noexcept
Buffers for inter-processor communications streams (UOPstream, UIPstream).
PrimitivePatch< SubList< face >, const pointField & > primitivePatch
A PrimitivePatch with a SubList addressing for the faces, const reference for the point field...
bool upToDate(const regIOobject &) const
Return true if given object is up to date with *this.
const vectorField & faceCentres() const
virtual void initOrder(PstreamBuffers &, const primitivePatch &) const
Initialize ordering for primitivePatch. Does not refer to *this (except for name() and type() etc...
virtual void resetAMI() const
Reset the AMI interpolator, use current patch points.
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)
Construct from (base coupled patch) components.
#define WarningInFunction
Report a warning using Foam::Warning.
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
Type gAverage(const FieldField< Field, Type > &f)
virtual bool owner() const
Does this side own the patch?
const vectorField & faceAreas() const
const std::string patch
OpenFOAM patch number as a std::string.
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)
Reduce inplace (cf. MPI Allreduce) using specified communication schedule.
#define DebugPout
Report an information message using Foam::Pout.
regIOobject is an abstract class derived from IOobject to handle automatic object registration with t...
messageStream Info
Information stream (stdout output on master, null elsewhere)
SubField< vector > subField
Declare type of subField.
virtual refPtr< labelListList > mapCollocatedFaces() const
Return collocated faces.
Mesh consisting of general polyhedral cells.
IOobject io("surfaceFilmProperties", mesh.time().constant(), mesh, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE, IOobject::NO_REGISTER)
A patch is a list of labels that address the faces in the global face list.
dimensionSet transform(const dimensionSet &ds)
Return the argument; transformations do not change the dimensions.
virtual void initOrder(PstreamBuffers &, const primitivePatch &) const
Initialize ordering for primitivePatch. Does not.
Defines the attributes of an object for which implicit objectRegistry management is supported...
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
const scalarListList & weights() const
Helper function to return the weights.
virtual label nonOverlapPatchID() const
Non-overlapping patch ID.
uindirectPrimitivePatch pp(UIndirectList< face >(mesh.faces(), faceLabels), mesh.points())
dimensionSet clamp(const dimensionSet &a, const dimensionSet &range)
addToRunTimeSelectionTable(functionObject, pointHistory, dictionary)
const scalarField & cellVolumes() const
virtual void movePoints(PstreamBuffers &pBufs, const pointField &)
Correct patches after moving points.
virtual void initMovePoints(PstreamBuffers &pBufs, const pointField &)
Initialise the patches for moving points.
IOerror FatalIOError
Error stream (stdout output on all processes), with additional 'FOAM FATAL IO ERROR' header text and ...