47 patchNeighbourFieldPtr_(nullptr)
62 patchNeighbourFieldPtr_(nullptr)
67 <<
"\n patch type '" <<
p.type()
68 <<
"' not constraint type '" <<
typeName <<
"'"
69 <<
"\n for patch " <<
p.name()
75 if (cacheNeighbourField())
78 const auto* hasNeighbValue =
83 patchNeighbourFieldPtr_.reset
126 patchNeighbourFieldPtr_(nullptr)
139 <<
"\n patch type '" <<
p.type()
140 <<
"' not constraint type '" <<
typeName <<
"'"
141 <<
"\n for patch " <<
p.name()
146 if (debug && !ptf.all_ready())
149 <<
"Outstanding request(s) on patch " << cyclicAMIPatch_.name()
150 << abort(FatalError);
163 cyclicAMIPatch_(ptf.cyclicAMIPatch_),
164 patchNeighbourFieldPtr_(nullptr)
166 if (
debug && !ptf.all_ready())
169 <<
"Outstanding request(s) on patch " << cyclicAMIPatch_.name()
170 << abort(FatalError);
184 cyclicAMIPatch_(ptf.cyclicAMIPatch_),
185 patchNeighbourFieldPtr_(nullptr)
187 if (
debug && !ptf.all_ready())
190 <<
"Outstanding request(s) on patch " << cyclicAMIPatch_.name()
191 << abort(FatalError);
199bool Foam::cyclicAMIFvPatchField<Type>::all_ready()
const
207 recvRequests_.start(),
212 recvRequests1_.start(),
213 recvRequests1_.size()
217 recvRequests_.clear();
218 recvRequests1_.clear();
226 sendRequests_.start(),
231 sendRequests1_.start(),
232 sendRequests1_.size()
236 sendRequests_.clear();
237 sendRequests1_.clear();
252 recvRequests_.start(),
257 recvRequests1_.start(),
258 recvRequests1_.size()
262 recvRequests_.clear();
263 recvRequests1_.clear();
269 sendRequests_.start(),
274 sendRequests1_.start(),
275 sendRequests1_.size()
279 sendRequests_.clear();
280 sendRequests1_.clear();
298 patchNeighbourFieldPtr_.reset(
nullptr);
310 patchNeighbourFieldPtr_.reset(
nullptr);
316Foam::cyclicAMIFvPatchField<Type>::getNeighbourField
323 const auto& neighbPatch = cyclicAMIPatch_.neighbPatch();
324 const labelUList& nbrFaceCells = neighbPatch.faceCells();
329 if (cyclicAMIPatch_.applyLowWeightCorrection())
331 defaultValues =
Field<Type>(internalData, cyclicAMIPatch_.faceCells());
334 tmp<Field<Type>> tpnf = cyclicAMIPatch_.interpolate(pnf, defaultValues);
346bool Foam::cyclicAMIFvPatchField<Type>::cacheNeighbourField()
const
363Foam::cyclicAMIFvPatchField<Type>::getPatchNeighbourField
365 bool checkCommunicator
368 const auto& AMI = this->ownerAMI();
372 AMI.distributed() && cacheNeighbourField()
373 && (!checkCommunicator || AMI.comm() != -1)
379 <<
"Outstanding recv request(s) on patch "
380 << cyclicAMIPatch_.name()
385 const auto& fvp = this->
patch();
386 const auto&
mesh = fvp.boundaryMesh().mesh();
390 patchNeighbourFieldPtr_
391 && !
mesh.upToDatePoints(this->internalField())
400 patchNeighbourFieldPtr_.reset(
nullptr);
404 if (!patchNeighbourFieldPtr_)
414 patchNeighbourFieldPtr_.reset
416 getNeighbourField(this->primitiveField()).ptr()
441 return patchNeighbourFieldPtr_();
456 return this->getPatchNeighbourField(
true);
467 auto tpnf = this->getPatchNeighbourField(
false);
479 this->primitiveField()
484 fld.boundaryField()[cyclicAMIPatch_.neighbPatchID()]
500 const auto& AMI = this->ownerAMI();
502 if (AMI.distributed() && cacheNeighbourField() && AMI.comm() != -1)
514 patchNeighbourFieldPtr_.reset(
nullptr);
529 if (!recvRequests_.empty() || !recvRequests1_.empty())
532 <<
"Outstanding recv request(s) on patch "
533 << cyclicAMIPatch_.name()
539 sendRequests_.clear();
540 sendRequests1_.clear();
565 if (!this->updated())
567 this->updateCoeffs();
570 const auto& AMI = this->ownerAMI();
572 if (AMI.distributed() && cacheNeighbourField() && AMI.comm() != -1)
578 <<
"Can only evaluate distributed AMI with nonBlocking"
582 patchNeighbourFieldPtr_.reset(
nullptr);
587 if (AMI.applyLowWeightCorrection())
589 defaultValues = this->patchInternalField();
599 patchNeighbourFieldPtr_.reset
613 recvRequests_.
clear();
614 recvRequests1_.clear();
619 auto& pnf = *patchNeighbourFieldPtr_;
642 const auto& AMI = this->ownerAMI();
644 if (AMI.distributed() && AMI.comm() != -1)
650 <<
"Can only evaluate distributed AMI with nonBlocking"
655 lduAddr.
patchAddr(cyclicAMIPatch_.neighbPatchID());
660 transformCoupleField(pnf, cmpt);
662 const cyclicAMIPolyPatch& cpp = cyclicAMIPatch_.cyclicAMIPatch();
665 if (!recvRequests_.empty() || !recvRequests1_.empty())
668 <<
"Outstanding recv request(s) on patch "
669 << cyclicAMIPatch_.name()
670 <<
" field " << this->internalField().name()
675 sendRequests_.clear();
676 sendRequests1_.clear();
693 this->updatedMatrix(
false);
702 const lduAddressing& lduAddr,
717 const auto& AMI = this->ownerAMI();
721 if (AMI.distributed() && AMI.comm() != -1)
726 <<
"Can only evaluate distributed AMI with nonBlocking"
731 if (AMI.applyLowWeightCorrection())
750 recvRequests_.clear();
751 recvRequests1_.clear();
756 if (cyclicAMIPatch_.applyLowWeightCorrection())
762 lduAddr.patchAddr(cyclicAMIPatch_.neighbPatchID());
767 transformCoupleField(pnf, cmpt);
769 pnf = cyclicAMIPatch_.interpolate(pnf, defaultValues);
791 const auto& AMI = this->ownerAMI();
793 if (AMI.distributed() && AMI.comm() != -1)
798 <<
"Can only evaluate distributed AMI with nonBlocking"
803 lduAddr.
patchAddr(cyclicAMIPatch_.neighbPatchID());
805 Field<Type> pnf(psiInternal, nbrFaceCells);
808 transformCoupleField(pnf);
810 const cyclicAMIPolyPatch& cpp = cyclicAMIPatch_.cyclicAMIPatch();
813 if (!recvRequests_.empty() || !recvRequests1_.empty())
816 <<
"Outstanding recv request(s) on patch "
817 << cyclicAMIPatch_.name()
818 <<
" field " << this->internalField().name()
823 sendRequests_.clear();
824 sendRequests1_.clear();
841 this->updatedMatrix(
false);
850 const lduAddressing& lduAddr,
852 const Field<Type>& psiInternal,
864 const auto& AMI = this->ownerAMI();
868 if (AMI.distributed() && AMI.comm() != -1)
873 <<
"Can only evaluate distributed AMI with nonBlocking"
880 if (AMI.applyLowWeightCorrection())
897 recvRequests_.
clear();
898 recvRequests1_.clear();
903 lduAddr.patchAddr(cyclicAMIPatch_.neighbPatchID());
908 transformCoupleField(pnf);
911 if (cyclicAMIPatch_.applyLowWeightCorrection())
916 pnf = cyclicAMIPatch_.interpolate(pnf, defaultValues);
934 if (this->cyclicAMIPatch().owner())
936 const label index = this->patch().index();
938 const label globalPatchID =
966 label globalFaceI =
faceMap[j];
968 const scalar boundCorr = -bndCoeffs[subFaceI];
969 const scalar intCorr = -intCoeffs[subFaceI];
971 matrix.
upper()[globalFaceI] += boundCorr;
972 matrix.
diag()[u[globalFaceI]] -= intCorr;
973 matrix.
diag()[l[globalFaceI]] -= boundCorr;
977 matrix.
lower()[globalFaceI] += intCorr;
996 const label nbrPathID =
997 cyclicAMIPatch_.cyclicAMIPatch().neighbPatchID();
999 const label nbrGlobalPatchID =
1017Foam::tmp<Foam::Field<Foam::scalar>>
1018Foam::cyclicAMIFvPatchField<Type>::coeffs
1025 const label index(this->
patch().index());
1027 const label nSubFaces
1029 matrix.lduMeshAssembly().cellBoundMap()[mat][index].size()
1033 auto& mapCoeffs = tmapCoeffs.ref();
1036 cyclicAMIPatch_.cyclicAMIPatch().AMI().srcWeights();
1042 for(label i=0; i<w.size(); i++)
1044 const label localFaceId =
1045 matrix.lduMeshAssembly().facePatchFaceMap()[mat][index][subFaceI];
1046 mapCoeffs[subFaceI] = w[i]*coeffs[localFaceId];
1056template<
class Type2>
1057void Foam::cyclicAMIFvPatchField<Type>::collectStencilData
1069 mapPtr().distribute(work);
1073 const auto& slots = stencil[facei];
1074 expandedData[facei].push_back
1084 const auto& slots = stencil[facei];
1085 expandedData[facei].push_back
1100 if (patchNeighbourFieldPtr_)
1102 patchNeighbourFieldPtr_->writeEntry(
"neighbourValue",
os);
1112 const fvPatchField<Type>& ptf
1128 && cycPtr->patchNeighbourFieldPtr_
1129 && cycPtr->patchNeighbourFieldPtr_->size() == this->size()
1132 if (!patchNeighbourFieldPtr_)
1134 patchNeighbourFieldPtr_ = autoPtr<Field<Type>>
::New();
1138 *patchNeighbourFieldPtr_ = *(cycPtr->patchNeighbourFieldPtr_);
1142 patchNeighbourFieldPtr_.reset(
nullptr);
1150 const fvPatchField<Type>& ptf
1166 && cycPtr->patchNeighbourFieldPtr_
1167 && cycPtr->patchNeighbourFieldPtr_->size() == this->size()
1170 if (!patchNeighbourFieldPtr_)
1172 patchNeighbourFieldPtr_ = autoPtr<Field<Type>>
::New();
1176 *patchNeighbourFieldPtr_ = *(cycPtr->patchNeighbourFieldPtr_);
1180 patchNeighbourFieldPtr_.reset(
nullptr);
Info<< nl;Info<< "Write faMesh in vtk format:"<< nl;{ vtk::uindirectPatchWriter writer(aMesh.patch(), fileName(aMesh.time().globalPath()/vtkBaseFileName));writer.writeGeometry();globalIndex procAddr(aMesh.nFaces());labelList cellIDs;if(UPstream::master()) { cellIDs.resize(procAddr.totalSize());for(const labelRange &range :procAddr.ranges()) { auto slice=cellIDs.slice(range);slice=identity(range);} } writer.beginCellData(4);writer.writeProcIDs();writer.write("cellID", cellIDs);writer.write("area", aMesh.S().field());writer.write("normal", aMesh.faceAreaNormals());writer.beginPointData(1);writer.write("normal", aMesh.pointAreaNormals());Info<< " "<< writer.output().name()<< nl;}{ vtk::lineWriter writer(aMesh.points(), aMesh.edges(), fileName(aMesh.time().globalPath()/(vtkBaseFileName+"-edges")));writer.writeGeometry();writer.beginCellData(4);writer.writeProcIDs();{ Field< scalar > fld(faMeshTools::flattenEdgeField(aMesh.magLe(), true))
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
const Mesh & mesh() const noexcept
Return const reference to mesh.
static int localBoundaryConsistency() noexcept
Get flag for local boundary consistency checks.
static const char *const typeName
Typename for Field.
Generic templated field type that is much like a Foam::List except that it is expected to hold numeri...
static const Field< Type > & null() noexcept
Return a null Field (reference to a nullObject). Behaves like an empty Field.
constexpr Field() noexcept
Default construct.
Generic GeometricField class.
A simple container of IOobject preferences. Can also be used for general handling of read/no-read/rea...
const word & name() const noexcept
Return the object name.
fileName objectPath() const
The complete path + object name.
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
void resize_nocopy(const label len)
Adjust allocated size of list without necessarily.
void clear()
Clear the list, i.e. set size to zero.
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
A List with indirect addressing. Like IndirectList but does not store addressing.
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
void deepCopy(const UList< T > &list)
Copy elements of the given UList. Sizes must match!
void size(const label n)
Older name for setAddressableSize.
static bool finishedRequests(label pos, label len=-1)
Non-blocking comms: have all requests (from position onwards) finished? Corresponds to MPI_Testall().
commsTypes
Communications types.
@ nonBlocking
"nonBlocking" (immediate) : (MPI_Isend, MPI_Irecv)
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Abstract base class for coupled patches.
coupledFvPatchField(const fvPatch &, const DimensionedField< Type, volMesh > &)
Construct from patch and internal field.
virtual void evaluate(const Pstream::commsTypes commsType)
Evaluate the patch field.
virtual const labelUList & faceCells() const
Return faceCell addressing.
This boundary condition enforces a cyclic condition between a pair of boundaries, whereby communicati...
virtual void autoMap(const fvPatchFieldMapper &)
Map (and resize as needed) from self given a mapping object.
virtual bool doTransform() const
Does the patch field perform the transformation.
virtual void initInterfaceMatrixUpdate(solveScalarField &result, const bool add, const lduAddressing &lduAddr, const label patchId, const solveScalarField &psiInternal, const scalarField &coeffs, const direction cmpt, const Pstream::commsTypes commsType) const
Initialise neighbour matrix update.
cyclicAMIFvPatchField(const fvPatch &, const DimensionedField< Type, volMesh > &)
Construct from patch and internal field.
const cyclicAMIFvPatchField< Type > & neighbourPatchField() const
Return reference to neighbour patchField.
virtual void manipulateMatrix(fvMatrix< Type > &m, const label iMatrix, const direction cmpt)
Manipulate matrix.
virtual bool coupled() const
Return true if coupled. Note that the underlying patch.
virtual void updateInterfaceMatrix(solveScalarField &result, const bool add, const lduAddressing &lduAddr, const label patchId, const solveScalarField &psiInternal, const scalarField &coeffs, const direction cmpt, const Pstream::commsTypes commsType) const
Update result field based on interface functionality.
virtual void initEvaluate(const Pstream::commsTypes commsType)
Initialise the evaluation of the patch field.
virtual void write(Ostream &os) const
Write.
virtual void evaluate(const Pstream::commsTypes commsType)
Evaluate the patch field.
virtual void rmap(const fvPatchField< Type > &, const labelList &)
Reverse map the given fvPatchField onto this fvPatchField.
const cyclicAMIFvPatch & cyclicAMIPatch() const noexcept
Return local reference cast into the cyclic AMI patch.
virtual bool ready() const
Are all (receive) data available?
virtual tmp< Field< Type > > patchNeighbourField() const
Return neighbour coupled internal cell data.
virtual const tensorField & forwardT() const
Return face transformation tensor.
Cyclic patch for Arbitrary Mesh Interface (AMI).
virtual const cyclicAMIFvPatch & neighbPatch() const
Return a reference to the neighbour patch.
Abstract base class for cyclic AMI coupled interfaces.
cyclicAMILduInterfaceField()
Construct null.
void transformCoupleField(Field< Type > &f) const
Transform given patch field.
Cyclic patch for Arbitrary Mesh Interface (AMI).
tmp< Field< Type > > interpolate(const Field< Type > &fld, const UList< Type > &defaultValues=UList< Type >()) const
Interpolate field.
void initInterpolate(const Field< Type > &fld, labelRange &sendRequests, labelRange &recvRequests, PtrList< List< Type > > &sendBuffers, PtrList< List< Type > > &recvBuffers, labelRange &sendRequests1, labelRange &recvRequests1, PtrList< List< Type > > &sendBuffers1, PtrList< List< Type > > &recvBuffers1) const
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Smooth ATC in cells next to a set of patches supplied by type.
A special matrix type and solver, designed for finite volume solutions of scalar equations....
const FieldField< Field, Type > & internalCoeffs() const noexcept
fvBoundary scalar field containing pseudo-matrix coeffs for internal cells
const FieldField< Field, Type > & boundaryCoeffs() const noexcept
fvBoundary scalar field containing pseudo-matrix coeffs for boundary cells
const lduPrimitiveMeshAssembly & lduMeshAssembly()
Return optional lduAdressing.
const GeometricField< Type, fvPatchField, volMesh > & psi(const label i=0) const
Return psi.
const fvPatch & patch() const noexcept
Return the patch.
bool updated() const noexcept
True if the boundary condition has already been updated.
A FieldMapper for finite-volume patch fields.
Abstract base class with a fat-interface to all derived classes covering all possible ways in which t...
virtual void autoMap(const fvPatchFieldMapper &)
Map (and resize as needed) from self given a mapping object.
virtual void write(Ostream &) const
Write.
virtual void operator==(const fvPatchField< Type > &)
virtual tmp< Field< Type > > patchInternalField() const
Return internal field next to patch.
void writeValueEntry(Ostream &os) const
Write *this field as a "value" entry.
const Field< Type > & primitiveField() const noexcept
Return const-reference to the internal field values.
const DimensionedField< Type, volMesh > & internalField() const noexcept
Return const-reference to the dimensioned internal field.
virtual void operator=(const UList< Type > &)
virtual void updateCoeffs()
virtual void rmap(const fvPatchField< Type > &, const labelList &)
Reverse map the given fvPatchField onto this fvPatchField.
bool readValueEntry(const dictionary &dict, IOobjectOption::readOption readOpt=IOobjectOption::LAZY_READ)
Read the "value" entry into *this.
void extrapolateInternal()
Assign the patch field from the internal field.
A finiteVolume patch using a polyPatch and a fvBoundaryMesh.
The class contains the addressing required by the lduMatrix: upper, lower and losort.
virtual const labelUList & upperAddr() const =0
Return upper addressing.
virtual const labelUList & lowerAddr() const =0
Return lower addressing.
virtual const labelUList & patchAddr(const label patchNo) const =0
Return patch to internal addressing given patch number.
bool updatedMatrix() const noexcept
Whether matrix has been updated.
void addToInternalField(Field< Type > &result, const bool add, const labelUList &faceCells, const scalarField &coeffs, const Field< Type > &vals) const
Add/subtract weighted contributions to internal field.
const lduAddressing & lduAddr() const
Return the LDU addressing.
bool asymmetric() const noexcept
Matrix is asymmetric (ie, full).
const scalarField & diag() const
const scalarField & upper() const
const scalarField & lower() const
const labelListListList & cellBoundMap() const
Return patch local sub-face to nbrCellId map.
const labelListListList & faceBoundMap() const
Return boundary face map.
const labelListListList & facePatchFaceMap() const
Return patch local sub-face to local patch face map.
const labelListList & patchLocalToGlobalMap() const
Return patchLocalToGlobalMap.
A traits class, which is primarily used for primitives and vector-space.
A class for managing references or pointers (no reference counting).
bool fluxRequired(const word &name) const
Get flux-required for given name, or default.
A class for managing temporary objects.
T & ref() const
Return non-const reference to the contents of a non-null managed pointer.
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
OBJstream os(runTime.globalPath()/outputName)
Namespace for handling debugging switches.
const std::string patch
OpenFOAM patch number as a std::string.
List< scalarList > scalarListList
List of scalarList.
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
Type & refCast(U &obj)
A dynamic_cast (for references) to Type reference.
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh > > &tf1, const word &name, const dimensionSet &dimensions, const bool initCopy=false)
Global function forwards to reuseTmpDimensionedField::New.
List< labelList > labelListList
List of labelList.
List< label > labelList
A List of labels.
refinementData transform(const tensor &, const refinementData val)
No-op rotational transform for base types.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
const word GlobalIOList< Tuple2< scalar, vector > >::typeName("scalarVectorTable")
void add(DimensionedField< scalar, GeoMesh > &result, const dimensioned< scalar > &dt1, const DimensionedField< scalar, GeoMesh > &f2)
const Type * isA(const U &obj)
Attempt dynamic_cast to Type.
errorManip< error > abort(error &err)
Field< solveScalar > solveScalarField
IOerror FatalIOError
Error stream (stdout output on all processes), with additional 'FOAM FATAL IO ERROR' header text and ...
static constexpr const zero Zero
Global zero (0).
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
errorManipArg< error, int > exit(error &err, const int errNo=1)
UList< label > labelUList
A UList of labels.
List< scalar > scalarList
List of scalar.
dict add("bounds", meshBb)
#define forAll(list, i)
Loop across all elements in list.