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" 118 GeometricField<Type, fvPatchField, volMesh>::
119 Boundary::localConsistency;
121 const int oldConsistency = consistency;
126 consistency = oldConsistency;
134 const cyclicACMIFvPatchField<Type>& ptf,
136 const DimensionedField<Type, volMesh>& iF,
137 const fvPatchFieldMapper& mapper
140 cyclicACMILduInterfaceField(),
141 coupledFvPatchField<Type>(ptf,
p, iF, mapper),
142 cyclicACMIPatch_(
refCast<const cyclicACMIFvPatch>(
p)),
143 patchNeighbourFieldPtr_(nullptr)
153 if (!isA<cyclicACMIFvPatch>(this->
patch()))
156 <<
"\n patch type '" << p.type()
157 <<
"' not constraint type '" <<
typeName <<
"'" 158 <<
"\n for patch " <<
p.name()
163 if (
debug && !ptf.all_ready())
166 <<
"Outstanding request(s) on patch " << cyclicACMIPatch_.
name()
175 const cyclicACMIFvPatchField<Type>& ptf
178 cyclicACMILduInterfaceField(),
179 coupledFvPatchField<Type>(ptf),
180 cyclicACMIPatch_(ptf.cyclicACMIPatch_),
181 patchNeighbourFieldPtr_(nullptr)
183 if (
debug && !ptf.all_ready())
186 <<
"Outstanding request(s) on patch " << cyclicACMIPatch_.
name()
195 const cyclicACMIFvPatchField<Type>& ptf,
196 const DimensionedField<Type, volMesh>& iF
199 cyclicACMILduInterfaceField(),
200 coupledFvPatchField<Type>(ptf, iF),
201 cyclicACMIPatch_(ptf.cyclicACMIPatch_),
202 patchNeighbourFieldPtr_(nullptr)
204 if (
debug && !ptf.all_ready())
207 <<
"Outstanding request(s) on patch " << cyclicACMIPatch_.
name()
218 return cyclicACMIPatch_.coupled();
231 recvRequests_.start(),
236 recvRequests_.
clear();
244 sendRequests_.start(),
249 sendRequests_.clear();
264 recvRequests_.start(),
269 recvRequests_.clear();
275 sendRequests_.start(),
280 sendRequests_.clear();
294 const Field<Type>& iField
298 <<
"cyclicACMIFvPatchField::patchNeighbourField(const Field<Type>&) :" 299 <<
" field:" << this->internalField().name()
300 <<
" patch:" << this->
patch().name()
305 const cyclicACMIFvPatch& neighbPatch = cyclicACMIPatch_.
neighbPatch();
306 const labelUList& nbrFaceCells = neighbPatch.faceCells();
308 tmp<Field<Type>> tpnf
310 cyclicACMIPatch_.interpolate
323 transform(tpnf.ref(), forwardT(), tpnf());
348 if (this->ownerAMI().distributed() && cacheNeighbourField())
353 <<
"Outstanding recv request(s) on patch " 354 << cyclicACMIPatch_.name()
355 <<
" field " << this->internalField().name()
360 if (!patchNeighbourFieldPtr_)
363 <<
"cyclicACMIFvPatchField::patchNeighbourField() :" 364 <<
" field:" << this->internalField().name()
365 <<
" patch:" << this->
patch().name()
366 <<
" calculating&caching patchNeighbourField" 370 patchNeighbourFieldPtr_.reset
372 patchNeighbourField(this->primitiveField()).ptr()
378 <<
"cyclicACMIFvPatchField::patchNeighbourField() :" 379 <<
" field:" << this->internalField().name()
380 <<
" patch:" << this->
patch().name()
381 <<
" returning cached patchNeighbourField" 384 return patchNeighbourFieldPtr_();
390 <<
"cyclicACMIFvPatchField::evaluate() :" 391 <<
" field:" << this->internalField().name()
392 <<
" patch:" << this->
patch().name()
393 <<
" calculating up-to-date patchNeighbourField" 396 return patchNeighbourField(this->primitiveField());
405 const GeometricField<Type, fvPatchField, volMesh>&
fld =
406 static_cast<const GeometricField<Type, fvPatchField, volMesh>&
> 408 this->primitiveField()
411 return refCast<const cyclicACMIFvPatchField<Type>>
413 fld.boundaryField()[cyclicACMIPatch_.neighbPatchID()]
425 this->primitiveField()
429 return fld.boundaryField()[cyclicACMIPatch_.nonOverlapPatchID()];
439 if (!this->updated())
441 this->updateCoeffs();
444 if (this->ownerAMI().distributed() && cacheNeighbourField())
449 patchNeighbourFieldPtr_.reset(
nullptr);
455 <<
"cyclicACMIFvPatchField::initEvaluate() :" 456 <<
" field:" << this->internalField().name()
457 <<
" patch:" << this->
patch().name()
458 <<
" starting send&receive" 463 const cyclicACMIFvPatch& neighbPatch = cyclicACMIPatch_.neighbPatch();
464 const labelUList& nbrFaceCells = neighbPatch.faceCells();
465 const Field<Type> pnf(this->primitiveField(), nbrFaceCells);
468 if (!recvRequests_.empty())
471 <<
"Outstanding recv request(s) on patch " 472 << cyclicACMIPatch_.name()
473 <<
" field " << this->internalField().name()
478 sendRequests_.clear();
480 cyclicACMIPatch_.initInterpolate
498 if (!this->updated())
500 this->updateCoeffs();
503 const auto& AMI = this->ownerAMI();
505 if (AMI.distributed() && cacheNeighbourField())
511 <<
"Can only evaluate distributed AMI with nonBlocking" 515 patchNeighbourFieldPtr_.reset(
nullptr);
520 <<
"Outstanding recv request(s) on patch " 521 << cyclicACMIPatch_.name()
522 <<
" field " << this->internalField().name()
526 patchNeighbourFieldPtr_.reset
528 cyclicACMIPatch_.interpolate
537 recvRequests_.clear();
540 auto& patchNeighbourField = patchNeighbourFieldPtr_.ref();
545 transform(patchNeighbourField, forwardT(), patchNeighbourField);
567 if (this->ownerAMI().distributed())
573 <<
"Can only evaluate distributed AMI with nonBlocking" 578 <<
"cyclicACMIFvPatchField::initInterfaceMatrixUpdate() :" 579 <<
" field:" << this->internalField().name()
580 <<
" patch:" << this->
patch().name()
581 <<
" starting send&receive" 585 lduAddr.
patchAddr(cyclicACMIPatch_.neighbPatchID());
590 transformCoupleField(pnf, cmpt);
593 if (!recvRequests_.empty())
596 <<
"Outstanding recv request(s) on patch " 597 << cyclicACMIPatch_.name()
598 <<
" field " << this->internalField().name()
603 sendRequests_.clear();
605 cyclicACMIPatch_.initInterpolate
622 const lduAddressing& lduAddr,
630 DebugPout<<
"cyclicACMIFvPatchField::updateInterfaceMatrix() :" 631 <<
" field:" << this->internalField().name()
632 <<
" patch:" << this->
patch().name()
641 if (this->ownerAMI().distributed())
646 <<
"Can only evaluate distributed AMI with nonBlocking" 651 <<
"cyclicACMIFvPatchField::evaluate() :" 652 <<
" field:" << this->internalField().name()
653 <<
" patch:" << this->
patch().name()
654 <<
" consuming received coupled neighbourfield" 658 cyclicACMIPatch_.interpolate
666 recvRequests_.clear();
671 lduAddr.patchAddr(cyclicACMIPatch_.neighbPatchID());
676 transformCoupleField(pnf, cmpt);
678 pnf = cyclicACMIPatch_.interpolate(pnf);
681 this->addToInternalField(result, !
add,
faceCells, coeffs, pnf);
697 const auto& AMI = this->ownerAMI();
699 if (AMI.distributed())
704 <<
"Can only evaluate distributed AMI with nonBlocking" 709 lduAddr.
patchAddr(cyclicACMIPatch_.neighbPatchID());
711 Field<Type> pnf(psiInternal, nbrFaceCells);
714 transformCoupleField(pnf);
717 if (!recvRequests_.empty())
720 <<
"Outstanding recv request(s) on patch " 721 << cyclicACMIPatch_.name()
722 <<
" field " << this->internalField().name()
727 sendRequests_.clear();
729 cyclicACMIPatch_.initInterpolate
746 const lduAddressing& lduAddr,
748 const Field<Type>& psiInternal,
757 const auto& AMI = this->ownerAMI();
761 if (AMI.distributed())
766 <<
"Can only evaluate distributed AMI with nonBlocking" 771 cyclicACMIPatch_.interpolate
779 recvRequests_.clear();
784 lduAddr.patchAddr(cyclicACMIPatch_.neighbPatchID());
786 pnf = Field<Type>(psiInternal, nbrFaceCells);
789 transformCoupleField(pnf);
791 pnf = cyclicACMIPatch_.interpolate(pnf);
794 this->addToInternalField(result, !
add,
faceCells, coeffs, pnf);
804 const scalarField& mask = cyclicACMIPatch_.cyclicACMIPatch().mask();
822 if (this->cyclicACMIPatch().owner())
824 label index = this->
patch().index();
826 const label globalPatchID =
854 label globalFaceI =
faceMap[j];
856 const scalar boundCorr = -bndCoeffs[subFaceI];
857 const scalar intCorr = -intCoeffs[subFaceI];
859 matrix.
upper()[globalFaceI] += boundCorr;
860 matrix.
diag()[u[globalFaceI]] -= intCorr;
861 matrix.
diag()[l[globalFaceI]] -= boundCorr;
865 matrix.
lower()[globalFaceI] += intCorr;
873 if (matrix.
psi(mat).mesh().fluxRequired(this->internalField().
name()))
877 globalPatchID, intCoeffs*pTraits<Type>::one
881 globalPatchID, bndCoeffs*pTraits<Type>::one
884 const label nbrPathID =
885 cyclicACMIPatch_.cyclicACMIPatch().neighbPatchID();
887 const label nbrGlobalPatchID =
893 nbrGlobalPatchID, intCoeffs*pTraits<Type>::one
897 nbrGlobalPatchID, bndCoeffs*pTraits<Type>::one
908 fvMatrix<Type>& matrix,
909 const Field<scalar>& coeffs,
913 const label index(this->
patch().index());
915 const label nSubFaces
917 matrix.lduMeshAssembly().cellBoundMap()[mat][index].size()
920 auto tmapCoeffs = tmp<Field<scalar>>
::New(nSubFaces,
Zero);
921 auto& mapCoeffs = tmapCoeffs.ref();
924 cyclicACMIPatch_.cyclicACMIPatch().AMI().srcWeights();
926 const scalarField& mask = cyclicACMIPatch_.cyclicACMIPatch().mask();
933 for(label i=0; i<w.size(); i++)
935 if (mask[faceI] > tol)
937 const label localFaceId =
938 matrix.lduMeshAssembly().facePatchFaceMap()
939 [mat][index][subFaceI];
940 mapCoeffs[subFaceI] = w[i]*coeffs[localFaceId];
959 const scalarField& mask = cyclicACMIPatch_.cyclicACMIPatch().mask();
971 if (patchNeighbourFieldPtr_)
973 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.
const scalarField & diag() const
virtual void evaluate(const Pstream::commsTypes commsType)
Evaluate the patch field.
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) to Type reference.
virtual label nonOverlapPatchID() const
Return neighbour.
static const Field< Type > & null() noexcept
Return a null Field (reference to a nullObject). Behaves like an empty Field.
Ostream & endl(Ostream &os)
Add newline and flush stream.
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...
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.
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.
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
Matrix is asymmetric (ie, full)
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 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 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" (immediate) : (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.
"buffered" : (MPI_Bsend, MPI_Recv)
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)