47 patchNeighbourFieldPtr_(nullptr)
62 patchNeighbourFieldPtr_(nullptr)
64 if (!isA<cyclicAMIFvPatch>(
p))
67 <<
"\n patch type '" <<
p.type()
68 <<
"' not constraint type '" << typeName <<
"'" 69 <<
"\n for patch " <<
p.name()
70 <<
" of field " << this->internalField().name()
71 <<
" in file " << this->internalField().objectPath()
75 if (cacheNeighbourField())
78 const auto* hasNeighbValue =
79 dict.findEntry(
"neighbourValue", keyType::LITERAL);
83 patchNeighbourFieldPtr_.reset
85 new Field<Type>(*hasNeighbValue,
p.size())
91 if (!this->readValueEntry(
dict))
100 const auto oldConsistency = FieldBase::localBoundaryConsistency(0);
102 this->
evaluate(UPstream::commsTypes::nonBlocking);
104 FieldBase::localBoundaryConsistency(oldConsistency);
108 this->extrapolateInternal();
117 const cyclicAMIFvPatchField<Type>& ptf,
119 const DimensionedField<Type, volMesh>& iF,
120 const fvPatchFieldMapper& mapper
123 cyclicAMILduInterfaceField(),
124 coupledFvPatchField<Type>(ptf,
p, iF, mapper),
125 cyclicAMIPatch_(
refCast<const cyclicAMIFvPatch>(
p)),
126 patchNeighbourFieldPtr_(nullptr)
136 if (!isA<cyclicAMIFvPatch>(this->
patch()))
139 <<
"\n patch type '" << p.type()
140 <<
"' not constraint type '" << typeName <<
"'" 141 <<
"\n for patch " <<
p.name()
142 <<
" of field " << this->internalField().name()
143 <<
" in file " << this->internalField().objectPath()
146 if (
debug && !ptf.all_ready())
149 <<
"Outstanding request(s) on patch " << cyclicAMIPatch_.name()
158 const cyclicAMIFvPatchField<Type>& ptf
161 cyclicAMILduInterfaceField(),
162 coupledFvPatchField<Type>(ptf),
163 cyclicAMIPatch_(ptf.cyclicAMIPatch_),
164 patchNeighbourFieldPtr_(nullptr)
166 if (
debug && !ptf.all_ready())
169 <<
"Outstanding request(s) on patch " << cyclicAMIPatch_.name()
178 const cyclicAMIFvPatchField<Type>& ptf,
179 const DimensionedField<Type, volMesh>& iF
182 cyclicAMILduInterfaceField(),
183 coupledFvPatchField<Type>(ptf, iF),
184 cyclicAMIPatch_(ptf.cyclicAMIPatch_),
185 patchNeighbourFieldPtr_(nullptr)
187 if (
debug && !ptf.all_ready())
190 <<
"Outstanding request(s) on patch " << cyclicAMIPatch_.name()
205 UPstream::finishedRequests
207 recvRequests_.start(),
212 recvRequests_.
clear();
218 UPstream::finishedRequests
220 sendRequests_.start(),
225 sendRequests_.clear();
238 UPstream::finishedRequests
240 recvRequests_.start(),
245 recvRequests_.clear();
249 UPstream::finishedRequests
251 sendRequests_.start(),
256 sendRequests_.clear();
274 patchNeighbourFieldPtr_.reset(
nullptr);
286 patchNeighbourFieldPtr_.reset(
nullptr);
294 const UList<Type>& internalData
299 const auto& neighbPatch = cyclicAMIPatch_.neighbPatch();
300 const labelUList& nbrFaceCells = neighbPatch.faceCells();
302 Field<Type> pnf(internalData, nbrFaceCells);
303 Field<Type> defaultValues;
305 if (cyclicAMIPatch_.applyLowWeightCorrection())
307 defaultValues = Field<Type>(internalData, cyclicAMIPatch_.faceCells());
310 tmp<Field<Type>> tpnf = cyclicAMIPatch_.interpolate(pnf, defaultValues);
314 transform(tpnf.ref(), forwardT(), tpnf());
324 return (FieldBase::localBoundaryConsistency() != 0);
335 const auto& AMI = this->ownerAMI();
339 AMI.distributed() && cacheNeighbourField()
346 <<
"Outstanding recv request(s) on patch " 347 << cyclicAMIPatch_.name()
348 <<
" field " << this->internalField().name()
352 const auto& fvp = this->
patch();
356 patchNeighbourFieldPtr_
357 && !fvp.boundaryMesh().mesh().upToDatePoints(this->internalField())
366 patchNeighbourFieldPtr_.reset(
nullptr);
370 if (!patchNeighbourFieldPtr_)
380 patchNeighbourFieldPtr_.reset
382 getNeighbourField(this->primitiveField()).ptr()
407 return patchNeighbourFieldPtr_();
412 return getNeighbourField(this->primitiveField());
421 return this->getPatchNeighbourField(
true);
432 auto tpnf = this->getPatchNeighbourField(
false);
444 this->primitiveField()
447 return refCast<const cyclicAMIFvPatchField<Type>>
449 fld.boundaryField()[cyclicAMIPatch_.neighbPatchID()]
460 if (!this->updated())
462 this->updateCoeffs();
465 const auto& AMI = this->ownerAMI();
467 if (AMI.distributed() && cacheNeighbourField() && AMI.comm() != -1)
476 if (commsType != UPstream::commsTypes::nonBlocking)
479 patchNeighbourFieldPtr_.reset(
nullptr);
487 const cyclicAMIFvPatch& neighbPatch = cyclicAMIPatch_.neighbPatch();
488 const labelUList& nbrFaceCells = neighbPatch.faceCells();
489 const Field<Type> pnf(this->primitiveField(), nbrFaceCells);
491 const cyclicAMIPolyPatch& cpp = cyclicAMIPatch_.cyclicAMIPatch();
494 if (!recvRequests_.empty())
497 <<
"Outstanding recv request(s) on patch " 498 << cyclicAMIPatch_.name()
499 <<
" field " << this->internalField().name()
504 sendRequests_.clear();
521 const Pstream::commsTypes commsType
524 if (!this->updated())
526 this->updateCoeffs();
529 const auto& AMI = this->ownerAMI();
531 if (AMI.distributed() && cacheNeighbourField() && AMI.comm() != -1)
534 if (commsType != UPstream::commsTypes::nonBlocking)
537 <<
"Can only evaluate distributed AMI with nonBlocking" 541 patchNeighbourFieldPtr_.reset(
nullptr);
543 const cyclicAMIPolyPatch& cpp = cyclicAMIPatch_.cyclicAMIPatch();
545 Field<Type> defaultValues;
546 if (AMI.applyLowWeightCorrection())
548 defaultValues = this->patchInternalField();
558 patchNeighbourFieldPtr_.reset
570 recvRequests_.clear();
575 auto& pnf = *patchNeighbourFieldPtr_;
598 const auto& AMI = this->ownerAMI();
600 if (AMI.distributed() && AMI.comm() != -1)
603 if (commsType != UPstream::commsTypes::nonBlocking)
606 <<
"Can only evaluate distributed AMI with nonBlocking" 611 lduAddr.
patchAddr(cyclicAMIPatch_.neighbPatchID());
616 transformCoupleField(pnf, cmpt);
618 const cyclicAMIPolyPatch& cpp = cyclicAMIPatch_.cyclicAMIPatch();
621 if (!recvRequests_.empty())
624 <<
"Outstanding recv request(s) on patch " 625 << cyclicAMIPatch_.name()
626 <<
" field " << this->internalField().name()
631 sendRequests_.clear();
643 this->updatedMatrix(
false);
667 const auto& AMI = this->ownerAMI();
671 if (AMI.distributed() && AMI.comm() != -1)
673 if (commsType != UPstream::commsTypes::nonBlocking)
676 <<
"Can only evaluate distributed AMI with nonBlocking" 681 if (AMI.applyLowWeightCorrection())
686 const cyclicAMIPolyPatch& cpp = cyclicAMIPatch_.cyclicAMIPatch();
691 solveScalarField::null(),
698 recvRequests_.
clear();
703 if (cyclicAMIPatch_.applyLowWeightCorrection())
709 lduAddr.
patchAddr(cyclicAMIPatch_.neighbPatchID());
714 transformCoupleField(pnf, cmpt);
716 pnf = cyclicAMIPatch_.interpolate(pnf, defaultValues);
720 this->addToInternalField(result, !
add, faceCells, coeffs, pnf);
722 this->updatedMatrix(
true);
738 const auto& AMI = this->ownerAMI();
740 if (AMI.distributed() && AMI.comm() != -1)
742 if (commsType != UPstream::commsTypes::nonBlocking)
745 <<
"Can only evaluate distributed AMI with nonBlocking" 750 lduAddr.
patchAddr(cyclicAMIPatch_.neighbPatchID());
752 Field<Type> pnf(psiInternal, nbrFaceCells);
755 transformCoupleField(pnf);
757 const cyclicAMIPolyPatch& cpp = cyclicAMIPatch_.cyclicAMIPatch();
760 if (!recvRequests_.empty())
763 <<
"Outstanding recv request(s) on patch " 764 << cyclicAMIPatch_.name()
765 <<
" field " << this->internalField().name()
770 sendRequests_.clear();
782 this->updatedMatrix(
false);
805 const auto& AMI = this->ownerAMI();
809 if (AMI.distributed() && AMI.comm() != -1)
811 if (commsType != UPstream::commsTypes::nonBlocking)
814 <<
"Can only evaluate distributed AMI with nonBlocking" 818 const cyclicAMIPolyPatch& cpp = cyclicAMIPatch_.cyclicAMIPatch();
820 Field<Type> defaultValues;
821 if (AMI.applyLowWeightCorrection())
823 defaultValues = Field<Type>(psiInternal, faceCells);
836 recvRequests_.
clear();
841 lduAddr.
patchAddr(cyclicAMIPatch_.neighbPatchID());
843 pnf = Field<Type>(psiInternal, nbrFaceCells);
846 transformCoupleField(pnf);
848 Field<Type> defaultValues;
849 if (cyclicAMIPatch_.applyLowWeightCorrection())
851 defaultValues = Field<Type>(psiInternal, faceCells);
854 pnf = cyclicAMIPatch_.interpolate(pnf, defaultValues);
858 this->addToInternalField(result, !
add, faceCells, coeffs, pnf);
860 this->updatedMatrix(
true);
872 if (this->cyclicAMIPatch().owner())
874 const label index = this->
patch().index();
876 const label globalPatchID =
904 label globalFaceI =
faceMap[j];
906 const scalar boundCorr = -bndCoeffs[subFaceI];
907 const scalar intCorr = -intCoeffs[subFaceI];
909 matrix.
upper()[globalFaceI] += boundCorr;
910 matrix.
diag()[u[globalFaceI]] -= intCorr;
911 matrix.
diag()[l[globalFaceI]] -= boundCorr;
915 matrix.
lower()[globalFaceI] += intCorr;
923 if (matrix.
psi(mat).mesh().fluxRequired(this->internalField().
name()))
927 globalPatchID, intCoeffs*pTraits<Type>::one
931 globalPatchID, bndCoeffs*pTraits<Type>::one
934 const label nbrPathID =
935 cyclicAMIPatch_.cyclicAMIPatch().neighbPatchID();
937 const label nbrGlobalPatchID =
943 nbrGlobalPatchID, intCoeffs*pTraits<Type>::one
947 nbrGlobalPatchID, bndCoeffs*pTraits<Type>::one
958 fvMatrix<Type>& matrix,
959 const Field<scalar>& coeffs,
963 const label index(this->
patch().index());
965 const label nSubFaces
967 matrix.lduMeshAssembly().cellBoundMap()[mat][index].size()
970 auto tmapCoeffs = tmp<Field<scalar>>
::New(nSubFaces,
Zero);
971 auto& mapCoeffs = tmapCoeffs.ref();
974 cyclicAMIPatch_.cyclicAMIPatch().AMI().srcWeights();
980 for(label i=0; i<w.size(); i++)
982 const label localFaceId =
983 matrix.lduMeshAssembly().facePatchFaceMap()[mat][index][subFaceI];
984 mapCoeffs[subFaceI] = w[i]*coeffs[localFaceId];
994 template<
class Type2>
997 const refPtr<mapDistribute>& mapPtr,
1000 List<Type2>& expandedData
1007 mapPtr().distribute(work);
1011 const auto& slots = stencil[facei];
1012 expandedData[facei].push_back
1014 UIndirectList<typename Type2::value_type>(work, slots)
1022 const auto& slots = stencil[facei];
1023 expandedData[facei].push_back
1025 UIndirectList<typename Type2::value_type>(data, slots)
1032 template<
class Type>
1036 fvPatchField<Type>::writeValueEntry(
os);
1038 if (patchNeighbourFieldPtr_)
1040 patchNeighbourFieldPtr_->writeEntry(
"neighbourValue",
os);
1047 template<
class Type>
1061 const auto* cycPtr = isA<cyclicAMIFvPatchField<Type>>(ptf);
1066 && cycPtr->patchNeighbourFieldPtr_
1067 && cycPtr->patchNeighbourFieldPtr_->size() == this->size()
1070 if (!patchNeighbourFieldPtr_)
1076 *patchNeighbourFieldPtr_ = *(cycPtr->patchNeighbourFieldPtr_);
1080 patchNeighbourFieldPtr_.reset(
nullptr);
1085 template<
class Type>
1088 const fvPatchField<Type>& ptf
1099 const auto* cycPtr = isA<cyclicAMIFvPatchField<Type>>(ptf);
1104 && cycPtr->patchNeighbourFieldPtr_
1105 && cycPtr->patchNeighbourFieldPtr_->size() == this->size()
1108 if (!patchNeighbourFieldPtr_)
1110 patchNeighbourFieldPtr_ = autoPtr<Field<Type>>
::New();
1114 *patchNeighbourFieldPtr_ = *(cycPtr->patchNeighbourFieldPtr_);
1118 patchNeighbourFieldPtr_.reset(
nullptr);
List< scalar > scalarList
List of scalar.
const scalarField & diag() const
virtual bool ready() const
Are all (receive) data available?
errorManipArg< error, int > exit(error &err, const int errNo=1)
Field< solveScalar > solveScalarField
commsTypes
Communications types.
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...
void checkCommunicator(int comm, int rank)
Fatal if communicator is outside the allocated range.
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.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
virtual void manipulateMatrix(fvMatrix< Type > &m, const label iMatrix, const direction cmpt)
Manipulate matrix.
const lduPrimitiveMeshAssembly & lduMeshAssembly()
Return optional lduAdressing.
Cyclic patch for Arbitrary Mesh Interface (AMI)
Type & refCast(U &obj)
A dynamic_cast (for references) to Type reference.
A finiteVolume patch using a polyPatch and a fvBoundaryMesh.
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.
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.
void resize_nocopy(const label len)
Adjust allocated size of list without necessarily.
Generic GeometricField class.
Smooth ATC in cells next to a set of patches supplied by type.
List< labelList > labelListList
List of labelList.
virtual void initEvaluate(const Pstream::commsTypes commsType)
Initialise the evaluation of the patch field.
UList< label > labelUList
A UList of labels.
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
#define forAll(list, i)
Loop across all elements in list.
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.
void write(vtk::formatter &fmt, const Type &val, const label n=1)
Component-wise write of a value (N times)
Abstract base class for cyclic AMI coupled interfaces.
const GeometricField< Type, fvPatchField, volMesh > & psi(const label i=0) const
Return psi.
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
void clear()
Clear the list, i.e. set size to zero.
List< scalarList > scalarListList
List of scalarList.
virtual void write(Ostream &os) const
Write.
virtual void evaluate(const Pstream::commsTypes commsType)
Evaluate the patch field.
A FieldMapper for finite-volume patch fields.
virtual const labelUList & patchAddr(const label patchNo) const =0
Return patch to internal addressing given patch number.
const scalarField & lower() const
A special matrix type and solver, designed for finite volume solutions of scalar equations. Face addressing is used to make all matrix assembly and solution loops vectorise.
errorManip< error > abort(error &err)
Abstract base class for coupled patches.
virtual tmp< Field< Type > > patchNeighbourField() const
Return neighbour coupled internal cell data.
bool asymmetric() const noexcept
Matrix is asymmetric (ie, full)
void add(FieldField< Field1, typename typeOfSum< Type1, Type2 >::type > &f, const FieldField< Field1, Type1 > &f1, const FieldField< Field2, Type2 > &f2)
refinementData transform(const tensor &, const refinementData val)
No-op rotational transform for base types.
int debug
Static debugging option.
OBJstream os(runTime.globalPath()/outputName)
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< ' ';}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< ' ';}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< ' ';}gmvFile<< nl;for(const word &name :lagrangianScalarNames){ IOField< scalar > fld(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
string evaluate(label fieldWidth, const std::string &s, size_t pos=0, size_t len=std::string::npos)
String evaluation with specified (positive, non-zero) field width.
const scalarField & upper() const
const lduAddressing & lduAddr() const
Return the LDU addressing.
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
A simple container of IOobject preferences. Can also be used for general handling of read/no-read/rea...
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
const std::string patch
OpenFOAM patch number as a std::string.
const cyclicAMIFvPatchField< Type > & neighbourPatchField() const
Return reference to neighbour patchField.
const FieldField< Field, Type > & internalCoeffs() const noexcept
fvBoundary scalar field containing pseudo-matrix coeffs for internal cells
Pointer management similar to std::unique_ptr, with some additional methods and type checking...
The class contains the addressing required by the lduMatrix: upper, lower and losort.
const FieldField< Field, Type > & boundaryCoeffs() const noexcept
fvBoundary scalar field containing pseudo-matrix coeffs for boundary cells
cyclicAMIFvPatchField(const fvPatch &, const DimensionedField< Type, volMesh > &)
Construct from patch and internal field.
void deepCopy(const UList< T > &list)
Copy elements of the given UList. Sizes must match!
virtual void rmap(const fvPatchField< Type > &, const labelList &)
Reverse map the given fvPatchField onto this fvPatchField.
A class for managing temporary objects.
tmp< faMatrix< Type > > operator==(const faMatrix< Type > &, const faMatrix< Type > &)
This boundary condition enforces a cyclic condition between a pair of boundaries, whereby communicati...
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)