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))
101 GeometricField<Type, fvPatchField, volMesh>::
102 Boundary::localConsistency;
104 const int oldConsistency = consistency;
107 this->
evaluate(UPstream::commsTypes::nonBlocking);
109 consistency = oldConsistency;
113 this->extrapolateInternal();
122 const cyclicAMIFvPatchField<Type>& ptf,
124 const DimensionedField<Type, volMesh>& iF,
125 const fvPatchFieldMapper& mapper
128 cyclicAMILduInterfaceField(),
129 coupledFvPatchField<Type>(ptf,
p, iF, mapper),
130 cyclicAMIPatch_(
refCast<const cyclicAMIFvPatch>(
p)),
131 patchNeighbourFieldPtr_(nullptr)
141 if (!isA<cyclicAMIFvPatch>(this->
patch()))
144 <<
"\n patch type '" << p.type()
145 <<
"' not constraint type '" << typeName <<
"'" 146 <<
"\n for patch " <<
p.name()
147 <<
" of field " << this->internalField().name()
148 <<
" in file " << this->internalField().objectPath()
151 if (
debug && !ptf.all_ready())
154 <<
"Outstanding request(s) on patch " << cyclicAMIPatch_.name()
163 const cyclicAMIFvPatchField<Type>& ptf
166 cyclicAMILduInterfaceField(),
167 coupledFvPatchField<Type>(ptf),
168 cyclicAMIPatch_(ptf.cyclicAMIPatch_),
169 patchNeighbourFieldPtr_(nullptr)
171 if (
debug && !ptf.all_ready())
174 <<
"Outstanding request(s) on patch " << cyclicAMIPatch_.name()
183 const cyclicAMIFvPatchField<Type>& ptf,
184 const DimensionedField<Type, volMesh>& iF
187 cyclicAMILduInterfaceField(),
188 coupledFvPatchField<Type>(ptf, iF),
189 cyclicAMIPatch_(ptf.cyclicAMIPatch_),
190 patchNeighbourFieldPtr_(nullptr)
192 if (
debug && !ptf.all_ready())
195 <<
"Outstanding request(s) on patch " << cyclicAMIPatch_.name()
210 UPstream::finishedRequests
212 recvRequests_.start(),
217 recvRequests_.
clear();
223 UPstream::finishedRequests
225 sendRequests_.start(),
230 sendRequests_.clear();
243 UPstream::finishedRequests
245 recvRequests_.start(),
250 recvRequests_.clear();
254 UPstream::finishedRequests
256 sendRequests_.start(),
261 sendRequests_.clear();
279 patchNeighbourFieldPtr_.reset(
nullptr);
291 patchNeighbourFieldPtr_.reset(
nullptr);
299 const Field<Type>& iField
304 const cyclicAMIFvPatch& neighbPatch = cyclicAMIPatch_.
neighbPatch();
305 const labelUList& nbrFaceCells = neighbPatch.faceCells();
307 Field<Type> pnf(iField, nbrFaceCells);
308 Field<Type> defaultValues;
310 if (cyclicAMIPatch_.applyLowWeightCorrection())
312 defaultValues = Field<Type>(iField, cyclicAMIPatch_.faceCells());
315 tmp<Field<Type>> tpnf = cyclicAMIPatch_.interpolate(pnf, defaultValues);
319 transform(tpnf.ref(), forwardT(), tpnf());
331 GeometricField<Type, fvPatchField, volMesh>::Boundary::localConsistency
341 if (this->ownerAMI().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 patchNeighbourField(this->primitiveField()).ptr()
407 return patchNeighbourFieldPtr_();
412 return patchNeighbourField(this->primitiveField());
421 const GeometricField<Type, fvPatchField, volMesh>&
fld =
422 static_cast<const GeometricField<Type, fvPatchField, volMesh>&
> 424 this->primitiveField()
427 return refCast<const cyclicAMIFvPatchField<Type>>
429 fld.boundaryField()[cyclicAMIPatch_.neighbPatchID()]
440 if (!this->updated())
442 this->updateCoeffs();
445 if (this->ownerAMI().distributed() && cacheNeighbourField())
454 if (commsType != UPstream::commsTypes::nonBlocking)
457 patchNeighbourFieldPtr_.reset(
nullptr);
465 const cyclicAMIFvPatch& neighbPatch = cyclicAMIPatch_.neighbPatch();
466 const labelUList& nbrFaceCells = neighbPatch.faceCells();
467 const Field<Type> pnf(this->primitiveField(), nbrFaceCells);
469 const cyclicAMIPolyPatch& cpp = cyclicAMIPatch_.cyclicAMIPatch();
472 if (!recvRequests_.empty())
475 <<
"Outstanding recv request(s) on patch " 476 << cyclicAMIPatch_.name()
477 <<
" field " << this->internalField().name()
482 sendRequests_.clear();
499 const Pstream::commsTypes commsType
502 if (!this->updated())
504 this->updateCoeffs();
507 const auto& AMI = this->ownerAMI();
509 if (AMI.distributed() && cacheNeighbourField())
512 if (commsType != UPstream::commsTypes::nonBlocking)
515 <<
"Can only evaluate distributed AMI with nonBlocking" 519 patchNeighbourFieldPtr_.reset(
nullptr);
521 const cyclicAMIPolyPatch& cpp = cyclicAMIPatch_.cyclicAMIPatch();
523 Field<Type> defaultValues;
524 if (AMI.applyLowWeightCorrection())
526 defaultValues = this->patchInternalField();
536 patchNeighbourFieldPtr_.reset
548 recvRequests_.clear();
550 auto& patchNeighbourField = patchNeighbourFieldPtr_.ref();
555 transform(patchNeighbourField, forwardT(), patchNeighbourField);
577 if (this->ownerAMI().distributed())
580 if (commsType != UPstream::commsTypes::nonBlocking)
583 <<
"Can only evaluate distributed AMI with nonBlocking" 588 lduAddr.
patchAddr(cyclicAMIPatch_.neighbPatchID());
593 transformCoupleField(pnf, cmpt);
595 const cyclicAMIPolyPatch& cpp = cyclicAMIPatch_.cyclicAMIPatch();
598 if (!recvRequests_.empty())
601 <<
"Outstanding recv request(s) on patch " 602 << cyclicAMIPatch_.name()
603 <<
" field " << this->internalField().name()
608 sendRequests_.clear();
627 const lduAddressing& lduAddr,
632 const Pstream::commsTypes commsType
642 const auto& AMI = this->ownerAMI();
646 if (AMI.distributed())
648 if (commsType != UPstream::commsTypes::nonBlocking)
651 <<
"Can only evaluate distributed AMI with nonBlocking" 656 if (AMI.applyLowWeightCorrection())
661 const cyclicAMIPolyPatch& cpp = cyclicAMIPatch_.cyclicAMIPatch();
666 solveScalarField::null(),
673 recvRequests_.clear();
678 if (cyclicAMIPatch_.applyLowWeightCorrection())
684 lduAddr.patchAddr(cyclicAMIPatch_.neighbPatchID());
689 transformCoupleField(pnf, cmpt);
691 pnf = cyclicAMIPatch_.interpolate(pnf, defaultValues);
695 this->addToInternalField(result, !
add,
faceCells, coeffs, pnf);
711 const auto& AMI = this->ownerAMI();
713 if (AMI.distributed())
715 if (commsType != UPstream::commsTypes::nonBlocking)
718 <<
"Can only evaluate distributed AMI with nonBlocking" 723 lduAddr.
patchAddr(cyclicAMIPatch_.neighbPatchID());
725 Field<Type> pnf(psiInternal, nbrFaceCells);
728 transformCoupleField(pnf);
730 const cyclicAMIPolyPatch& cpp = cyclicAMIPatch_.cyclicAMIPatch();
733 if (!recvRequests_.empty())
736 <<
"Outstanding recv request(s) on patch " 737 << cyclicAMIPatch_.name()
738 <<
" field " << this->internalField().name()
743 sendRequests_.clear();
762 const lduAddressing& lduAddr,
764 const Field<Type>& psiInternal,
766 const Pstream::commsTypes commsType
776 const auto& AMI = this->ownerAMI();
780 if (AMI.distributed())
782 if (commsType != UPstream::commsTypes::nonBlocking)
785 <<
"Can only evaluate distributed AMI with nonBlocking" 789 const cyclicAMIPolyPatch& cpp = cyclicAMIPatch_.cyclicAMIPatch();
791 Field<Type> defaultValues;
792 if (AMI.applyLowWeightCorrection())
794 defaultValues = Field<Type>(psiInternal, faceCells);
807 recvRequests_.clear();
812 lduAddr.patchAddr(cyclicAMIPatch_.neighbPatchID());
814 pnf = Field<Type>(psiInternal, nbrFaceCells);
817 transformCoupleField(pnf);
819 Field<Type> defaultValues;
820 if (cyclicAMIPatch_.applyLowWeightCorrection())
822 defaultValues = Field<Type>(psiInternal, faceCells);
825 pnf = cyclicAMIPatch_.interpolate(pnf, defaultValues);
829 this->addToInternalField(result, !
add,
faceCells, coeffs, pnf);
841 if (this->cyclicAMIPatch().owner())
843 const label index = this->
patch().index();
845 const label globalPatchID =
873 label globalFaceI =
faceMap[j];
875 const scalar boundCorr = -bndCoeffs[subFaceI];
876 const scalar intCorr = -intCoeffs[subFaceI];
878 matrix.
upper()[globalFaceI] += boundCorr;
879 matrix.
diag()[u[globalFaceI]] -= intCorr;
880 matrix.
diag()[l[globalFaceI]] -= boundCorr;
884 matrix.
lower()[globalFaceI] += intCorr;
892 if (matrix.
psi(mat).mesh().fluxRequired(this->internalField().
name()))
896 globalPatchID, intCoeffs*pTraits<Type>::one
900 globalPatchID, bndCoeffs*pTraits<Type>::one
903 const label nbrPathID =
904 cyclicAMIPatch_.cyclicAMIPatch().neighbPatchID();
906 const label nbrGlobalPatchID =
912 nbrGlobalPatchID, intCoeffs*pTraits<Type>::one
916 nbrGlobalPatchID, bndCoeffs*pTraits<Type>::one
927 fvMatrix<Type>& matrix,
928 const Field<scalar>& coeffs,
932 const label index(this->
patch().index());
934 const label nSubFaces
936 matrix.lduMeshAssembly().cellBoundMap()[mat][index].size()
939 auto tmapCoeffs = tmp<Field<scalar>>
::New(nSubFaces,
Zero);
940 auto& mapCoeffs = tmapCoeffs.ref();
943 cyclicAMIPatch_.cyclicAMIPatch().AMI().srcWeights();
949 for(label i=0; i<w.size(); i++)
951 const label localFaceId =
952 matrix.lduMeshAssembly().facePatchFaceMap()[mat][index][subFaceI];
953 mapCoeffs[subFaceI] = w[i]*coeffs[localFaceId];
963 template<
class Type2>
966 const refPtr<mapDistribute>& mapPtr,
969 List<Type2>& expandedData
976 mapPtr().distribute(work);
983 UIndirectList<typename Type2::value_type>(work, slots)
994 UIndirectList<typename Type2::value_type>(data, slots)
1001 template<
class Type>
1005 fvPatchField<Type>::writeValueEntry(
os);
1007 if (patchNeighbourFieldPtr_)
1009 patchNeighbourFieldPtr_->writeEntry(
"neighbourValue",
os);
1016 template<
class Type>
1030 const auto* cycPtr = isA<cyclicAMIFvPatchField<Type>>(ptf);
1033 const auto& cyc = *cycPtr;
1036 cyc.patchNeighbourFieldPtr_
1037 && cyc.patchNeighbourFieldPtr_->size() == this->size()
1040 const auto& cycPnf = cyc.patchNeighbourFieldPtr_();
1041 if (patchNeighbourFieldPtr_)
1044 patchNeighbourFieldPtr_() = cycPnf;
1049 patchNeighbourFieldPtr_.reset(
new Field<Type>(cycPnf));
1054 patchNeighbourFieldPtr_.reset(
nullptr);
1059 patchNeighbourFieldPtr_.reset(
nullptr);
1064 template<
class Type>
1067 const fvPatchField<Type>& ptf
1078 const auto* cycPtr = isA<cyclicAMIFvPatchField<Type>>(ptf);
1081 const auto& cyc = *cycPtr;
1084 cyc.patchNeighbourFieldPtr_
1085 && cyc.patchNeighbourFieldPtr_->size() == this->size()
1088 const auto& cycPnf = cyc.patchNeighbourFieldPtr_();
1089 if (patchNeighbourFieldPtr_)
1092 patchNeighbourFieldPtr_() = cycPnf;
1097 patchNeighbourFieldPtr_.reset(
new Field<Type>(cycPnf));
1102 patchNeighbourFieldPtr_.reset(
nullptr);
1107 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...
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.
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.
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)
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 scalarField & upper() const
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)