45 patchNeighbourFieldPtr_(nullptr)
60 patchNeighbourFieldPtr_(nullptr)
62 if (!isA<cyclicACMIFvPatch>(
p))
65 <<
" patch type '" <<
p.type()
66 <<
"' not constraint type '" <<
typeName <<
"'" 67 <<
"\n for patch " <<
p.name()
73 if (cacheNeighbourField())
76 const auto* hasNeighbValue =
81 patchNeighbourFieldPtr_.reset
83 new Field<Type>(*hasNeighbValue,
p.size())
94 const GeometricField<Type, fvPatchField, volMesh>&
fld =
95 static_cast<const GeometricField<Type, fvPatchField, volMesh>&
> 102 <<
" patch " <<
p.name()
104 <<
" refers to non-overlap patch " 106 <<
" which is not constructed yet." <<
nl 107 <<
" Either supply an initial value or change the ordering" 120 const cyclicACMIFvPatchField<Type>& ptf,
122 const DimensionedField<Type, volMesh>& iF,
123 const fvPatchFieldMapper& mapper
126 cyclicACMILduInterfaceField(),
127 coupledFvPatchField<Type>(ptf,
p, iF, mapper),
128 cyclicACMIPatch_(
refCast<const cyclicACMIFvPatch>(
p)),
129 patchNeighbourFieldPtr_(nullptr)
139 if (!isA<cyclicACMIFvPatch>(this->
patch()))
142 <<
"\n patch type '" << p.type()
143 <<
"' not constraint type '" <<
typeName <<
"'" 144 <<
"\n for patch " <<
p.name()
149 if (
debug && !ptf.all_ready())
152 <<
"Outstanding request(s) on patch " << cyclicACMIPatch_.
name()
161 const cyclicACMIFvPatchField<Type>& ptf
164 cyclicACMILduInterfaceField(),
165 coupledFvPatchField<Type>(ptf),
166 cyclicACMIPatch_(ptf.cyclicACMIPatch_),
167 patchNeighbourFieldPtr_(nullptr)
169 if (
debug && !ptf.all_ready())
172 <<
"Outstanding request(s) on patch " << cyclicACMIPatch_.
name()
181 const cyclicACMIFvPatchField<Type>& ptf,
182 const DimensionedField<Type, volMesh>& iF
185 cyclicACMILduInterfaceField(),
186 coupledFvPatchField<Type>(ptf, iF),
187 cyclicACMIPatch_(ptf.cyclicACMIPatch_),
188 patchNeighbourFieldPtr_(nullptr)
190 if (
debug && !ptf.all_ready())
193 <<
"Outstanding request(s) on patch " << cyclicACMIPatch_.
name()
204 return cyclicACMIPatch_.coupled();
217 recvRequests_.start(),
222 recvRequests_.
clear();
230 sendRequests_.start(),
235 sendRequests_.clear();
250 recvRequests_.start(),
255 recvRequests_.clear();
261 sendRequests_.start(),
266 sendRequests_.clear();
280 const Field<Type>& iField
284 <<
"cyclicACMIFvPatchField::patchNeighbourField(const Field<Type>&) :" 285 <<
" field:" << this->internalField().name()
286 <<
" patch:" << this->
patch().name()
291 const cyclicACMIFvPatch& neighbPatch = cyclicACMIPatch_.
neighbPatch();
292 const labelUList& nbrFaceCells = neighbPatch.faceCells();
294 tmp<Field<Type>> tpnf
296 cyclicACMIPatch_.interpolate
309 transform(tpnf.ref(), forwardT(), tpnf());
334 if (this->ownerAMI().distributed() && cacheNeighbourField())
339 <<
"Outstanding recv request(s) on patch " 340 << cyclicACMIPatch_.name()
341 <<
" field " << this->internalField().name()
346 if (!patchNeighbourFieldPtr_)
349 <<
"cyclicACMIFvPatchField::patchNeighbourField() :" 350 <<
" field:" << this->internalField().name()
351 <<
" patch:" << this->
patch().name()
352 <<
" calculating&caching patchNeighbourField" 356 patchNeighbourFieldPtr_.reset
358 patchNeighbourField(this->primitiveField()).ptr()
364 <<
"cyclicACMIFvPatchField::patchNeighbourField() :" 365 <<
" field:" << this->internalField().name()
366 <<
" patch:" << this->
patch().name()
367 <<
" returning cached patchNeighbourField" 370 return patchNeighbourFieldPtr_();
376 <<
"cyclicACMIFvPatchField::evaluate() :" 377 <<
" field:" << this->internalField().name()
378 <<
" patch:" << this->
patch().name()
379 <<
" calculating up-to-date patchNeighbourField" 382 return patchNeighbourField(this->primitiveField());
391 const GeometricField<Type, fvPatchField, volMesh>&
fld =
392 static_cast<const GeometricField<Type, fvPatchField, volMesh>&
> 394 this->primitiveField()
397 return refCast<const cyclicACMIFvPatchField<Type>>
399 fld.boundaryField()[cyclicACMIPatch_.neighbPatchID()]
411 this->primitiveField()
415 return fld.boundaryField()[cyclicACMIPatch_.nonOverlapPatchID()];
425 if (!this->updated())
427 this->updateCoeffs();
430 if (this->ownerAMI().distributed() && cacheNeighbourField())
435 patchNeighbourFieldPtr_.reset(
nullptr);
441 <<
"cyclicACMIFvPatchField::initEvaluate() :" 442 <<
" field:" << this->internalField().name()
443 <<
" patch:" << this->
patch().name()
444 <<
" starting send&receive" 450 <<
"Outstanding recv request(s) on patch " 451 << cyclicACMIPatch_.name()
452 <<
" field " << this->internalField().name()
458 const cyclicACMIFvPatch& neighbPatch = cyclicACMIPatch_.neighbPatch();
459 const labelUList& nbrFaceCells = neighbPatch.faceCells();
460 const Field<Type> pnf(this->primitiveField(), nbrFaceCells);
462 cyclicACMIPatch_.initInterpolate
480 if (!this->updated())
482 this->updateCoeffs();
485 const auto& AMI = this->ownerAMI();
487 if (AMI.distributed() && cacheNeighbourField())
493 <<
"Can only evaluate distributed AMI with nonBlocking" 497 patchNeighbourFieldPtr_.reset(
nullptr);
502 <<
"Outstanding recv request(s) on patch " 503 << cyclicACMIPatch_.name()
504 <<
" field " << this->internalField().name()
508 patchNeighbourFieldPtr_.reset
510 cyclicACMIPatch_.interpolate
518 auto& patchNeighbourField = patchNeighbourFieldPtr_.ref();
523 transform(patchNeighbourField, forwardT(), patchNeighbourField);
545 if (this->ownerAMI().distributed())
551 <<
"Can only evaluate distributed AMI with nonBlocking" 556 <<
"cyclicACMIFvPatchField::initInterfaceMatrixUpdate() :" 557 <<
" field:" << this->internalField().name()
558 <<
" patch:" << this->
patch().name()
559 <<
" starting send&receive" 565 <<
"Outstanding recv request(s) on patch " 566 << cyclicACMIPatch_.name()
567 <<
" field " << this->internalField().name()
572 lduAddr.
patchAddr(cyclicACMIPatch_.neighbPatchID());
577 transformCoupleField(pnf, cmpt);
579 cyclicACMIPatch_.initInterpolate
596 const lduAddressing& lduAddr,
604 DebugPout<<
"cyclicACMIFvPatchField::updateInterfaceMatrix() :" 605 <<
" field:" << this->internalField().name()
606 <<
" patch:" << this->
patch().name()
615 if (this->ownerAMI().distributed())
620 <<
"Can only evaluate distributed AMI with nonBlocking" 625 <<
"cyclicACMIFvPatchField::evaluate() :" 626 <<
" field:" << this->internalField().name()
627 <<
" patch:" << this->
patch().name()
628 <<
" consuming received coupled neighbourfield" 632 cyclicACMIPatch_.interpolate
642 lduAddr.patchAddr(cyclicACMIPatch_.neighbPatchID());
647 transformCoupleField(pnf, cmpt);
649 pnf = cyclicACMIPatch_.interpolate(pnf);
652 this->addToInternalField(result, !
add,
faceCells, coeffs, pnf);
668 const auto& AMI = this->ownerAMI();
670 if (AMI.distributed())
675 <<
"Can only evaluate distributed AMI with nonBlocking" 682 <<
"Outstanding recv request(s) on patch " 683 << cyclicACMIPatch_.name()
684 <<
" field " << this->internalField().name()
689 lduAddr.
patchAddr(cyclicACMIPatch_.neighbPatchID());
691 Field<Type> pnf(psiInternal, nbrFaceCells);
694 transformCoupleField(pnf);
696 cyclicACMIPatch_.initInterpolate
713 const lduAddressing& lduAddr,
715 const Field<Type>& psiInternal,
724 const auto& AMI = this->ownerAMI();
728 if (AMI.distributed())
733 <<
"Can only evaluate distributed AMI with nonBlocking" 738 cyclicACMIPatch_.interpolate
748 lduAddr.patchAddr(cyclicACMIPatch_.neighbPatchID());
750 pnf = Field<Type>(psiInternal, nbrFaceCells);
753 transformCoupleField(pnf);
755 pnf = cyclicACMIPatch_.interpolate(pnf);
758 this->addToInternalField(result, !
add,
faceCells, coeffs, pnf);
768 const scalarField& mask = cyclicACMIPatch_.cyclicACMIPatch().mask();
786 if (this->cyclicACMIPatch().owner())
788 label index = this->
patch().index();
790 const label globalPatchID =
818 label globalFaceI =
faceMap[j];
820 const scalar boundCorr = -bndCoeffs[subFaceI];
821 const scalar intCorr = -intCoeffs[subFaceI];
823 matrix.
upper()[globalFaceI] += boundCorr;
824 matrix.
diag()[u[globalFaceI]] -= intCorr;
825 matrix.
diag()[l[globalFaceI]] -= boundCorr;
829 matrix.
lower()[globalFaceI] += intCorr;
837 if (matrix.
psi(mat).mesh().fluxRequired(this->internalField().
name()))
841 globalPatchID, intCoeffs*pTraits<Type>::one
845 globalPatchID, bndCoeffs*pTraits<Type>::one
848 const label nbrPathID =
849 cyclicACMIPatch_.cyclicACMIPatch().neighbPatchID();
851 const label nbrGlobalPatchID =
857 nbrGlobalPatchID, intCoeffs*pTraits<Type>::one
861 nbrGlobalPatchID, bndCoeffs*pTraits<Type>::one
872 fvMatrix<Type>& matrix,
873 const Field<scalar>& coeffs,
877 const label index(this->
patch().index());
879 const label nSubFaces
881 matrix.lduMeshAssembly().cellBoundMap()[mat][index].size()
884 Field<scalar> mapCoeffs(nSubFaces,
Zero);
887 cyclicACMIPatch_.cyclicACMIPatch().AMI().srcWeights();
889 const scalarField& mask = cyclicACMIPatch_.cyclicACMIPatch().mask();
896 for(label i=0; i<w.size(); i++)
898 if (mask[faceI] > tol)
900 const label localFaceId =
901 matrix.lduMeshAssembly().facePatchFaceMap()
902 [mat][index][subFaceI];
903 mapCoeffs[subFaceI] = w[i]*coeffs[localFaceId];
922 const scalarField& mask = cyclicACMIPatch_.cyclicACMIPatch().mask();
934 if (patchNeighbourFieldPtr_)
936 patchNeighbourFieldPtr_->writeEntry(
"neighbourValue",
os);
bool readValueEntry(const dictionary &dict, IOobjectOption::readOption readOpt=IOobjectOption::LAZY_READ)
Read the "value" entry into *this.
List< scalar > scalarList
List of scalar.
virtual void evaluate(const Pstream::commsTypes commsType)
Evaluate the patch field.
"blocking" : (MPI_Bsend, MPI_Recv)
const labelListList & patchLocalToGlobalMap() const
Return patchLocalToGlobalMap.
errorManipArg< error, int > exit(error &err, const int errNo=1)
const fvPatchField< Type > & nonOverlapPatchField() const
Return reference to non-overlapping patchField.
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...
const fvPatch & patch() const noexcept
Return the patch.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
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 tmp< Field< Type > > patchNeighbourField() const
Return neighbour coupled internal cell data.
const lduPrimitiveMeshAssembly & lduMeshAssembly()
Return optional lduAdressing.
constexpr char nl
The newline '\n' character (0x0a)
Type & refCast(U &obj)
A dynamic_cast (for references). Generates a FatalError on failed casts and uses the virtual type() m...
virtual label nonOverlapPatchID() const
Return neighbour.
Ostream & endl(Ostream &os)
Add newline and flush stream.
A finiteVolume patch using a polyPatch and a fvBoundaryMesh.
Abstract base class with a fat-interface to all derived classes covering all possible ways in which t...
Generic GeometricField class.
This boundary condition enforces a cyclic condition between a pair of boundaries, whereby communicati...
void writeValueEntry(Ostream &os) const
Write *this field as a "value" entry.
Smooth ATC in cells next to a set of patches supplied by type.
virtual void write(Ostream &) const
Write.
virtual const labelUList & lowerAddr() const =0
Return lower addressing.
virtual bool coupled() const
Return true if coupled. Note that the underlying patch.
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.
static const char *const typeName
Typename for Field.
Cyclic patch for Arbitrarily Coupled Mesh Interface (ACMI)
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.
virtual bool ready() const
Are all (receive) data available?
virtual void write(Ostream &os) const
Write.
void clear()
Clear the list, i.e. set size to zero.
List< scalarList > scalarListList
List of scalarList.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
virtual const labelUList & upperAddr() const =0
Return upper addressing.
virtual const cyclicACMIFvPatch & neighbPatch() const
Return neighbour fvPatch.
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.
const Field< Type > & primitiveField() const noexcept
Return const-reference to the internal field values.
const cyclicACMIFvPatchField< Type > & neighbourPatchField() const
Return reference to neighbour patchField.
virtual void evaluate(const Pstream::commsTypes commsType)
Evaluate the patch field.
cyclicACMIFvPatchField(const fvPatch &, const DimensionedField< Type, volMesh > &)
Construct from patch and internal field.
errorManip< error > abort(error &err)
Abstract base class for coupled patches.
Abstract base class for cyclic ACMI coupled interfaces.
const word & nonOverlapPatchName() const
Non-overlapping patch name.
bool asymmetric() const noexcept
An Ostream is an abstract base class for all output systems (streams, files, token lists...
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.
virtual void updateCoeffs()
Update the coefficients associated with the patch field.
OBJstream os(runTime.globalPath()/outputName)
const labelListListList & faceBoundMap() const
Return boundary face map.
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.
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))
virtual void initEvaluate(const Pstream::commsTypes commsType)
Initialise the evaluation of the patch field.
const cyclicACMIPolyPatch & cyclicACMIPatch() const
Return local reference cast into the cyclic patch.
const lduAddressing & lduAddr() const
Return the LDU addressing.
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
static const Field< Type > & null()
Return nullObject reference Field.
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 DimensionedField< Type, volMesh > & internalField() const noexcept
Return const-reference to the dimensioned internal field.
const std::string patch
OpenFOAM patch number as a std::string.
virtual void manipulateMatrix(fvMatrix< Type > &matrix)
Manipulate matrix.
#define DebugPout
Report an information message using Foam::Pout.
"nonBlocking" : (MPI_Isend, MPI_Irecv)
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
virtual const word & name() const
Return name.
A class for managing temporary objects.
dimensionSet transform(const dimensionSet &ds)
Return the argument; transformations do not change the dimensions.
static scalar tolerance()
Overlap tolerance.
static bool finishedRequests(const label pos, label len=-1)
Non-blocking comms: have all requests (from position onwards) finished? Corresponds to MPI_Testall() ...
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)