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))
95 this->
evaluate(UPstream::commsTypes::nonBlocking);
99 this->extrapolateInternal();
108 const cyclicAMIFvPatchField<Type>& ptf,
110 const DimensionedField<Type, volMesh>& iF,
111 const fvPatchFieldMapper& mapper
114 cyclicAMILduInterfaceField(),
115 coupledFvPatchField<Type>(ptf,
p, iF, mapper),
116 cyclicAMIPatch_(
refCast<const cyclicAMIFvPatch>(
p)),
117 patchNeighbourFieldPtr_(nullptr)
127 if (!isA<cyclicAMIFvPatch>(this->
patch()))
130 <<
"\n patch type '" << p.type()
131 <<
"' not constraint type '" << typeName <<
"'" 132 <<
"\n for patch " <<
p.name()
133 <<
" of field " << this->internalField().name()
134 <<
" in file " << this->internalField().objectPath()
137 if (
debug && !ptf.all_ready())
140 <<
"Outstanding request(s) on patch " << cyclicAMIPatch_.name()
149 const cyclicAMIFvPatchField<Type>& ptf
152 cyclicAMILduInterfaceField(),
153 coupledFvPatchField<Type>(ptf),
154 cyclicAMIPatch_(ptf.cyclicAMIPatch_),
155 patchNeighbourFieldPtr_(nullptr)
157 if (
debug && !ptf.all_ready())
160 <<
"Outstanding request(s) on patch " << cyclicAMIPatch_.name()
169 const cyclicAMIFvPatchField<Type>& ptf,
170 const DimensionedField<Type, volMesh>& iF
173 cyclicAMILduInterfaceField(),
174 coupledFvPatchField<Type>(ptf, iF),
175 cyclicAMIPatch_(ptf.cyclicAMIPatch_),
176 patchNeighbourFieldPtr_(nullptr)
178 if (
debug && !ptf.all_ready())
181 <<
"Outstanding request(s) on patch " << cyclicAMIPatch_.name()
196 UPstream::finishedRequests
198 recvRequests_.start(),
203 recvRequests_.
clear();
209 UPstream::finishedRequests
211 sendRequests_.start(),
216 sendRequests_.clear();
229 UPstream::finishedRequests
231 recvRequests_.start(),
236 recvRequests_.clear();
240 UPstream::finishedRequests
242 sendRequests_.start(),
247 sendRequests_.clear();
265 patchNeighbourFieldPtr_.reset(
nullptr);
277 patchNeighbourFieldPtr_.reset(
nullptr);
285 const Field<Type>& iField
290 const cyclicAMIFvPatch& neighbPatch = cyclicAMIPatch_.
neighbPatch();
291 const labelUList& nbrFaceCells = neighbPatch.faceCells();
293 Field<Type> pnf(iField, nbrFaceCells);
294 Field<Type> defaultValues;
296 if (cyclicAMIPatch_.applyLowWeightCorrection())
298 defaultValues = Field<Type>(iField, cyclicAMIPatch_.faceCells());
301 tmp<Field<Type>> tpnf = cyclicAMIPatch_.interpolate(pnf, defaultValues);
305 transform(tpnf.ref(), forwardT(), tpnf());
317 GeometricField<Type, fvPatchField, volMesh>::Boundary::localConsistency
327 if (this->ownerAMI().distributed() && cacheNeighbourField())
332 <<
"Outstanding recv request(s) on patch " 333 << cyclicAMIPatch_.name()
334 <<
" field " << this->internalField().name()
338 const auto& fvp = this->
patch();
342 patchNeighbourFieldPtr_
343 && !fvp.boundaryMesh().mesh().upToDatePoints(this->internalField())
352 patchNeighbourFieldPtr_.reset(
nullptr);
356 if (!patchNeighbourFieldPtr_)
366 patchNeighbourFieldPtr_.reset
368 patchNeighbourField(this->primitiveField()).ptr()
393 return patchNeighbourFieldPtr_();
398 return patchNeighbourField(this->primitiveField());
407 const GeometricField<Type, fvPatchField, volMesh>&
fld =
408 static_cast<const GeometricField<Type, fvPatchField, volMesh>&
> 410 this->primitiveField()
413 return refCast<const cyclicAMIFvPatchField<Type>>
415 fld.boundaryField()[cyclicAMIPatch_.neighbPatchID()]
426 if (!this->updated())
428 this->updateCoeffs();
431 if (this->ownerAMI().distributed() && cacheNeighbourField())
440 if (commsType != UPstream::commsTypes::nonBlocking)
443 patchNeighbourFieldPtr_.reset(
nullptr);
451 const cyclicAMIFvPatch& neighbPatch = cyclicAMIPatch_.neighbPatch();
452 const labelUList& nbrFaceCells = neighbPatch.faceCells();
453 const Field<Type> pnf(this->primitiveField(), nbrFaceCells);
455 const cyclicAMIPolyPatch& cpp = cyclicAMIPatch_.cyclicAMIPatch();
472 const Pstream::commsTypes commsType
475 if (!this->updated())
477 this->updateCoeffs();
480 const auto& AMI = this->ownerAMI();
482 if (AMI.distributed() && cacheNeighbourField())
485 if (commsType != UPstream::commsTypes::nonBlocking)
488 <<
"Can only evaluate distributed AMI with nonBlocking" 492 patchNeighbourFieldPtr_.reset(
nullptr);
494 const cyclicAMIPolyPatch& cpp = cyclicAMIPatch_.cyclicAMIPatch();
496 Field<Type> defaultValues;
497 if (AMI.applyLowWeightCorrection())
499 defaultValues = this->patchInternalField();
509 patchNeighbourFieldPtr_.reset
519 auto& patchNeighbourField = patchNeighbourFieldPtr_.ref();
524 transform(patchNeighbourField, forwardT(), patchNeighbourField);
546 if (this->ownerAMI().distributed())
549 if (commsType != UPstream::commsTypes::nonBlocking)
552 <<
"Can only evaluate distributed AMI with nonBlocking" 557 lduAddr.
patchAddr(cyclicAMIPatch_.neighbPatchID());
562 transformCoupleField(pnf, cmpt);
564 const cyclicAMIPolyPatch& cpp = cyclicAMIPatch_.cyclicAMIPatch();
583 const lduAddressing& lduAddr,
588 const Pstream::commsTypes commsType
598 const auto& AMI = this->ownerAMI();
602 if (AMI.distributed())
604 if (commsType != UPstream::commsTypes::nonBlocking)
607 <<
"Can only evaluate distributed AMI with nonBlocking" 612 if (AMI.applyLowWeightCorrection())
617 const cyclicAMIPolyPatch& cpp = cyclicAMIPatch_.cyclicAMIPatch();
622 solveScalarField::null(),
631 if (cyclicAMIPatch_.applyLowWeightCorrection())
637 lduAddr.patchAddr(cyclicAMIPatch_.neighbPatchID());
642 transformCoupleField(pnf, cmpt);
644 pnf = cyclicAMIPatch_.interpolate(pnf, defaultValues);
648 this->addToInternalField(result, !
add,
faceCells, coeffs, pnf);
664 const auto& AMI = this->ownerAMI();
666 if (AMI.distributed())
668 if (commsType != UPstream::commsTypes::nonBlocking)
671 <<
"Can only evaluate distributed AMI with nonBlocking" 676 lduAddr.
patchAddr(cyclicAMIPatch_.neighbPatchID());
678 Field<Type> pnf(psiInternal, nbrFaceCells);
681 transformCoupleField(pnf);
683 const cyclicAMIPolyPatch& cpp = cyclicAMIPatch_.cyclicAMIPatch();
702 const lduAddressing& lduAddr,
704 const Field<Type>& psiInternal,
706 const Pstream::commsTypes commsType
716 const auto& AMI = this->ownerAMI();
720 if (AMI.distributed())
722 if (commsType != UPstream::commsTypes::nonBlocking)
725 <<
"Can only evaluate distributed AMI with nonBlocking" 729 const cyclicAMIPolyPatch& cpp = cyclicAMIPatch_.cyclicAMIPatch();
731 Field<Type> defaultValues;
732 if (AMI.applyLowWeightCorrection())
734 defaultValues = Field<Type>(psiInternal, faceCells);
749 lduAddr.patchAddr(cyclicAMIPatch_.neighbPatchID());
751 pnf = Field<Type>(psiInternal, nbrFaceCells);
754 transformCoupleField(pnf);
756 Field<Type> defaultValues;
757 if (cyclicAMIPatch_.applyLowWeightCorrection())
759 defaultValues = Field<Type>(psiInternal, faceCells);
762 pnf = cyclicAMIPatch_.interpolate(pnf, defaultValues);
766 this->addToInternalField(result, !
add,
faceCells, coeffs, pnf);
778 if (this->cyclicAMIPatch().owner())
780 const label index = this->
patch().index();
782 const label globalPatchID =
810 label globalFaceI =
faceMap[j];
812 const scalar boundCorr = -bndCoeffs[subFaceI];
813 const scalar intCorr = -intCoeffs[subFaceI];
815 matrix.
upper()[globalFaceI] += boundCorr;
816 matrix.
diag()[u[globalFaceI]] -= intCorr;
817 matrix.
diag()[l[globalFaceI]] -= boundCorr;
821 matrix.
lower()[globalFaceI] += intCorr;
829 if (matrix.
psi(mat).mesh().fluxRequired(this->internalField().
name()))
833 globalPatchID, intCoeffs*pTraits<Type>::one
837 globalPatchID, bndCoeffs*pTraits<Type>::one
840 const label nbrPathID =
841 cyclicAMIPatch_.cyclicAMIPatch().neighbPatchID();
843 const label nbrGlobalPatchID =
849 nbrGlobalPatchID, intCoeffs*pTraits<Type>::one
853 nbrGlobalPatchID, bndCoeffs*pTraits<Type>::one
864 fvMatrix<Type>& matrix,
865 const Field<scalar>& coeffs,
869 const label index(this->
patch().index());
871 const label nSubFaces
873 matrix.lduMeshAssembly().cellBoundMap()[mat][index].size()
876 auto tmapCoeffs = tmp<Field<scalar>>
::New(nSubFaces,
Zero);
877 auto& mapCoeffs = tmapCoeffs.ref();
880 cyclicAMIPatch_.cyclicAMIPatch().AMI().srcWeights();
886 for(label i=0; i<w.size(); i++)
888 const label localFaceId =
889 matrix.lduMeshAssembly().facePatchFaceMap()[mat][index][subFaceI];
890 mapCoeffs[subFaceI] = w[i]*coeffs[localFaceId];
900 template<
class Type2>
903 const refPtr<mapDistribute>& mapPtr,
906 List<Type2>& expandedData
913 mapPtr().distribute(work);
920 UIndirectList<typename Type2::value_type>(work, slots)
931 UIndirectList<typename Type2::value_type>(data, slots)
942 fvPatchField<Type>::writeValueEntry(
os);
944 if (patchNeighbourFieldPtr_)
946 patchNeighbourFieldPtr_->writeEntry(
"neighbourValue",
os);
967 const auto* cycPtr = isA<cyclicAMIFvPatchField<Type>>(ptf);
970 const auto& cyc = *cycPtr;
973 cyc.patchNeighbourFieldPtr_
974 && cyc.patchNeighbourFieldPtr_->size() == this->size()
977 const auto& cycPnf = cyc.patchNeighbourFieldPtr_();
978 if (patchNeighbourFieldPtr_)
981 patchNeighbourFieldPtr_() = cycPnf;
986 patchNeighbourFieldPtr_.reset(
new Field<Type>(cycPnf));
991 patchNeighbourFieldPtr_.reset(
nullptr);
996 patchNeighbourFieldPtr_.reset(
nullptr);
1001 template<
class Type>
1004 const fvPatchField<Type>& ptf
1015 const auto* cycPtr = isA<cyclicAMIFvPatchField<Type>>(ptf);
1018 const auto& cyc = *cycPtr;
1021 cyc.patchNeighbourFieldPtr_
1022 && cyc.patchNeighbourFieldPtr_->size() == this->size()
1025 const auto& cycPnf = cyc.patchNeighbourFieldPtr_();
1026 if (patchNeighbourFieldPtr_)
1029 patchNeighbourFieldPtr_() = cycPnf;
1034 patchNeighbourFieldPtr_.reset(
new Field<Type>(cycPnf));
1039 patchNeighbourFieldPtr_.reset(
nullptr);
1044 patchNeighbourFieldPtr_.reset(
nullptr);
List< scalar > scalarList
List of scalar.
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...
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). Generates a FatalError on failed casts and uses the virtual type() m...
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.
Smooth ATC in cells next to a set of patches supplied by type.
void push_back(const T &val)
Append an element at the end of the list.
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.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
virtual void evaluate(const Pstream::commsTypes commsType)
Evaluate the patch field.
A FieldMapper for finite-volume patch fields.
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.
virtual const labelUList & patchAddr(const label patchNo) const =0
Return patch to internal addressing given patch number.
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
void add(FieldField< Field1, typename typeOfSum< Type1, Type2 >::type > &f, const FieldField< Field1, Type1 > &f1, const FieldField< Field2, Type2 > &f2)
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))
const lduAddressing & lduAddr() const
Return the LDU addressing.
virtual const cyclicAMIFvPatch & neighbPatch() const
Return a reference to the neighbour patch.
#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
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.
virtual void rmap(const fvPatchField< Type > &, const labelList &)
Reverse map the given fvPatchField onto this fvPatchField.
List< label > labelList
A List of labels.
A class for managing temporary objects.
tmp< faMatrix< Type > > operator==(const faMatrix< Type > &, const faMatrix< Type > &)
dimensionSet transform(const dimensionSet &ds)
Return the argument; transformations do not change the dimensions.
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)