diff --git a/src/finiteVolume/fields/fvPatchFields/constraint/cyclicACMI/cyclicACMIFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/constraint/cyclicACMI/cyclicACMIFvPatchField.C index 388a74f540..99a12cbc27 100644 --- a/src/finiteVolume/fields/fvPatchFields/constraint/cyclicACMI/cyclicACMIFvPatchField.C +++ b/src/finiteVolume/fields/fvPatchFields/constraint/cyclicACMI/cyclicACMIFvPatchField.C @@ -41,7 +41,10 @@ Foam::cyclicACMIFvPatchField::cyclicACMIFvPatchField : cyclicACMILduInterfaceField(), coupledFvPatchField(p, iF), - cyclicACMIPatch_(refCast(p)) + cyclicACMIPatch_(refCast(p)), + sendRequests_(0), + recvRequests_(0), + patchNeighbourFieldPtr_(nullptr) {} @@ -55,7 +58,10 @@ Foam::cyclicACMIFvPatchField::cyclicACMIFvPatchField : cyclicACMILduInterfaceField(), coupledFvPatchField(p, iF, dict, IOobjectOption::NO_READ), - cyclicACMIPatch_(refCast(p, dict)) + cyclicACMIPatch_(refCast(p, dict)), + sendRequests_(0), + recvRequests_(0), + patchNeighbourFieldPtr_(nullptr) { if (!isA(p)) { @@ -68,6 +74,21 @@ Foam::cyclicACMIFvPatchField::cyclicACMIFvPatchField << exit(FatalIOError); } + if (cacheNeighbourField()) + { + // Handle neighbour value first, before any evaluate() + const auto* hasNeighbValue = + dict.findEntry("neighbourValue", keyType::LITERAL); + + if (hasNeighbValue) + { + patchNeighbourFieldPtr_.reset + ( + new Field(*hasNeighbValue, p.size()) + ); + } + } + // Use 'value' supplied, or set to coupled field if (!this->readValueEntry(dict) && this->coupled()) { @@ -108,8 +129,19 @@ Foam::cyclicACMIFvPatchField::cyclicACMIFvPatchField : cyclicACMILduInterfaceField(), coupledFvPatchField(ptf, p, iF, mapper), - cyclicACMIPatch_(refCast(p)) + cyclicACMIPatch_(refCast(p)), + sendRequests_(0), + recvRequests_(0), + patchNeighbourFieldPtr_(nullptr) { + if (ptf.patchNeighbourFieldPtr_ && cacheNeighbourField()) + { + patchNeighbourFieldPtr_.reset + ( + new Field(ptf.patchNeighbourFieldPtr_(), mapper) + ); + } + if (!isA(this->patch())) { FatalErrorInFunction @@ -120,10 +152,15 @@ Foam::cyclicACMIFvPatchField::cyclicACMIFvPatchField << " in file " << this->internalField().objectPath() << exit(FatalError); } + if (debug && !ptf.all_ready()) + { + FatalErrorInFunction + << "Outstanding request(s) on patch " << cyclicACMIPatch_.name() + << abort(FatalError); + } } - template Foam::cyclicACMIFvPatchField::cyclicACMIFvPatchField ( @@ -132,8 +169,18 @@ Foam::cyclicACMIFvPatchField::cyclicACMIFvPatchField : cyclicACMILduInterfaceField(), coupledFvPatchField(ptf), - cyclicACMIPatch_(ptf.cyclicACMIPatch_) -{} + cyclicACMIPatch_(ptf.cyclicACMIPatch_), + sendRequests_(0), + recvRequests_(0), + patchNeighbourFieldPtr_(ptf.patchNeighbourFieldPtr_) +{ + if (debug && !ptf.all_ready()) + { + FatalErrorInFunction + << "Outstanding request(s) on patch " << cyclicACMIPatch_.name() + << abort(FatalError); + } +} template @@ -145,8 +192,18 @@ Foam::cyclicACMIFvPatchField::cyclicACMIFvPatchField : cyclicACMILduInterfaceField(), coupledFvPatchField(ptf, iF), - cyclicACMIPatch_(ptf.cyclicACMIPatch_) -{} + cyclicACMIPatch_(ptf.cyclicACMIPatch_), + sendRequests_(0), + recvRequests_(0), + patchNeighbourFieldPtr_(nullptr) +{ + if (debug && !ptf.all_ready()) + { + FatalErrorInFunction + << "Outstanding request(s) on patch " << cyclicACMIPatch_.name() + << abort(FatalError); + } +} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // @@ -159,13 +216,87 @@ bool Foam::cyclicACMIFvPatchField::coupled() const template -Foam::tmp> -Foam::cyclicACMIFvPatchField::patchNeighbourField() const +bool Foam::cyclicACMIFvPatchField::all_ready() const { - const Field& iField = this->primitiveField(); - //const cyclicACMIPolyPatch& cpp = cyclicACMIPatch_.cyclicACMIPatch(); + int done = 0; - // By pass polyPatch to get nbrId. Instead use cyclicAMIFvPatch virtual + if + ( + UPstream::finishedRequests + ( + recvRequests_.start(), + recvRequests_.size() + ) + ) + { + recvRequests_.clear(); + ++done; + } + + if + ( + UPstream::finishedRequests + ( + sendRequests_.start(), + sendRequests_.size() + ) + ) + { + sendRequests_.clear(); + ++done; + } + + return (done == 2); +} + + +template +bool Foam::cyclicACMIFvPatchField::ready() const +{ + if + ( + UPstream::finishedRequests + ( + recvRequests_.start(), + recvRequests_.size() + ) + ) + { + recvRequests_.clear(); + + if + ( + UPstream::finishedRequests + ( + sendRequests_.start(), + sendRequests_.size() + ) + ) + { + sendRequests_.clear(); + } + + return true; + } + + return false; +} + + +template +Foam::tmp> +Foam::cyclicACMIFvPatchField::patchNeighbourField +( + const Field& iField +) const +{ + DebugPout + << "cyclicACMIFvPatchField::patchNeighbourField(const Field&) :" + << " field:" << this->internalField().name() + << " patch:" << this->patch().name() + << endl; + + // By pass polyPatch to get nbrId. Instead use cyclicACMIFvPatch virtual // neighbPatch() const cyclicACMIFvPatch& neighbPatch = cyclicACMIPatch_.neighbPatch(); const labelUList& nbrFaceCells = neighbPatch.faceCells(); @@ -192,6 +323,77 @@ Foam::cyclicACMIFvPatchField::patchNeighbourField() const } +template +bool Foam::cyclicACMIFvPatchField::cacheNeighbourField() +{ + /* + return + ( + GeometricField::Boundary::localConsistency + != 0 + ); + */ + return false; +} + + +template +Foam::tmp> +Foam::cyclicACMIFvPatchField::patchNeighbourField() const +{ + if (this->ownerAMI().distributed() && cacheNeighbourField()) + { + if (!this->ready()) + { + FatalErrorInFunction + << "Outstanding recv request(s) on patch " + << cyclicACMIPatch_.name() + << " field " << this->internalField().name() + << abort(FatalError); + } + + // Initialise if not done in construct-from-dictionary + if (!patchNeighbourFieldPtr_) + { + DebugPout + << "cyclicACMIFvPatchField::patchNeighbourField() :" + << " field:" << this->internalField().name() + << " patch:" << this->patch().name() + << " calculating&caching patchNeighbourField" + << endl; + + // Do interpolation and store result + patchNeighbourFieldPtr_.reset + ( + patchNeighbourField(this->primitiveField()).ptr() + ); + } + else + { + DebugPout + << "cyclicACMIFvPatchField::patchNeighbourField() :" + << " field:" << this->internalField().name() + << " patch:" << this->patch().name() + << " returning cached patchNeighbourField" + << endl; + } + return patchNeighbourFieldPtr_(); + } + else + { + // Do interpolation + DebugPout + << "cyclicACMIFvPatchField::evaluate() :" + << " field:" << this->internalField().name() + << " patch:" << this->patch().name() + << " calculating up-to-date patchNeighbourField" + << endl; + + return patchNeighbourField(this->primitiveField()); + } +} + + template const Foam::cyclicACMIFvPatchField& Foam::cyclicACMIFvPatchField::neighbourPatchField() const @@ -224,6 +426,178 @@ Foam::cyclicACMIFvPatchField::nonOverlapPatchField() const } +template +void Foam::cyclicACMIFvPatchField::initEvaluate +( + const Pstream::commsTypes commsType +) +{ + if (!this->updated()) + { + this->updateCoeffs(); + } + + if (this->ownerAMI().distributed() && cacheNeighbourField()) + { + if (commsType != UPstream::commsTypes::nonBlocking) + { + // Invalidate old field - or flag as fatal? + patchNeighbourFieldPtr_.reset(nullptr); + return; + } + + // Start sending + DebugPout + << "cyclicACMIFvPatchField::initEvaluate() :" + << " field:" << this->internalField().name() + << " patch:" << this->patch().name() + << " starting send&receive" + << endl; + + if (!this->ready()) + { + FatalErrorInFunction + << "Outstanding recv request(s) on patch " + << cyclicACMIPatch_.name() + << " field " << this->internalField().name() + << abort(FatalError); + } + + // By-pass polyPatch to get nbrId. Instead use cyclicACMIFvPatch virtual + // neighbPatch() + const cyclicACMIFvPatch& neighbPatch = cyclicACMIPatch_.neighbPatch(); + const labelUList& nbrFaceCells = neighbPatch.faceCells(); + const Field pnf(this->primitiveField(), nbrFaceCells); + + cyclicACMIPatch_.initInterpolate + ( + pnf, + sendRequests_, + sendBufs_, + recvRequests_, + recvBufs_ + ); + } +} + + +template +void Foam::cyclicACMIFvPatchField::evaluate +( + const Pstream::commsTypes commsType +) +{ + if (!this->updated()) + { + this->updateCoeffs(); + } + + const auto& AMI = this->ownerAMI(); + + if (AMI.distributed() && cacheNeighbourField()) + { + // Calculate patchNeighbourField + if (commsType != UPstream::commsTypes::nonBlocking) + { + FatalErrorInFunction + << "Can only evaluate distributed AMI with nonBlocking" + << exit(FatalError); + } + + patchNeighbourFieldPtr_.reset(nullptr); + + if (!this->ready()) + { + FatalErrorInFunction + << "Outstanding recv request(s) on patch " + << cyclicACMIPatch_.name() + << " field " << this->internalField().name() + << abort(FatalError); + } + + patchNeighbourFieldPtr_.reset + ( + cyclicACMIPatch_.interpolate + ( + Field::null(), // Not used for distributed + recvRequests_, + recvBufs_ + ).ptr() + ); + + auto& patchNeighbourField = patchNeighbourFieldPtr_.ref(); + + if (doTransform()) + { + // In-place transform + transform(patchNeighbourField, forwardT(), patchNeighbourField); + } + } + + // Use patchNeighbourField() and patchInternalField() to obtain face value + coupledFvPatchField::evaluate(commsType); +} + + +template +void Foam::cyclicACMIFvPatchField::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 +{ + if (this->ownerAMI().distributed()) + { + // Start sending + if (commsType != UPstream::commsTypes::nonBlocking) + { + FatalErrorInFunction + << "Can only evaluate distributed AMI with nonBlocking" + << exit(FatalError); + } + + DebugPout + << "cyclicACMIFvPatchField::initInterfaceMatrixUpdate() :" + << " field:" << this->internalField().name() + << " patch:" << this->patch().name() + << " starting send&receive" + << endl; + + if (!this->ready()) + { + FatalErrorInFunction + << "Outstanding recv request(s) on patch " + << cyclicACMIPatch_.name() + << " field " << this->internalField().name() + << abort(FatalError); + } + + const labelUList& nbrFaceCells = + lduAddr.patchAddr(cyclicACMIPatch_.neighbPatchID()); + + solveScalarField pnf(psiInternal, nbrFaceCells); + + // Transform according to the transformation tensors + transformCoupleField(pnf, cmpt); + + cyclicACMIPatch_.initInterpolate + ( + pnf, + sendRequests_, + scalarSendBufs_, + recvRequests_, + scalarRecvBufs_ + ); + } +} + + template void Foam::cyclicACMIFvPatchField::updateInterfaceMatrix ( @@ -234,33 +608,113 @@ void Foam::cyclicACMIFvPatchField::updateInterfaceMatrix const solveScalarField& psiInternal, const scalarField& coeffs, const direction cmpt, - const Pstream::commsTypes + const Pstream::commsTypes commsType ) const { + DebugPout<< "cyclicACMIFvPatchField::updateInterfaceMatrix() :" + << " field:" << this->internalField().name() + << " patch:" << this->patch().name() + << endl; + // note: only applying coupled contribution -// const labelUList& nbrFaceCellsCoupled = -// lduAddr.patchAddr -// ( -// cyclicACMIPatch_.cyclicACMIPatch().neighbPatchID() -// ); - - const labelUList& nbrFaceCellsCoupled = - lduAddr.patchAddr(cyclicACMIPatch_.neighbPatchID()); - - solveScalarField pnf(psiInternal, nbrFaceCellsCoupled); - - // Transform according to the transformation tensors - transformCoupleField(pnf, cmpt); - - pnf = cyclicACMIPatch_.interpolate(pnf); - const labelUList& faceCells = lduAddr.patchAddr(patchId); + solveScalarField pnf; + + if (this->ownerAMI().distributed()) + { + if (commsType != UPstream::commsTypes::nonBlocking) + { + FatalErrorInFunction + << "Can only evaluate distributed AMI with nonBlocking" + << exit(FatalError); + } + + DebugPout + << "cyclicACMIFvPatchField::evaluate() :" + << " field:" << this->internalField().name() + << " patch:" << this->patch().name() + << " consuming received coupled neighbourfield" + << endl; + + pnf = + cyclicACMIPatch_.interpolate + ( + solveScalarField::null(), // Not used for distributed + recvRequests_, + scalarRecvBufs_ + ); + } + else + { + const labelUList& nbrFaceCells = + lduAddr.patchAddr(cyclicACMIPatch_.neighbPatchID()); + + pnf = solveScalarField(psiInternal, nbrFaceCells); + + // Transform according to the transformation tensors + transformCoupleField(pnf, cmpt); + + pnf = cyclicACMIPatch_.interpolate(pnf); + } + this->addToInternalField(result, !add, faceCells, coeffs, pnf); } +template +void Foam::cyclicACMIFvPatchField::initInterfaceMatrixUpdate +( + Field& result, + const bool add, + const lduAddressing& lduAddr, + const label patchId, + const Field& psiInternal, + const scalarField& coeffs, + const Pstream::commsTypes commsType +) const +{ + const auto& AMI = this->ownerAMI(); + + if (AMI.distributed()) + { + if (commsType != UPstream::commsTypes::nonBlocking) + { + FatalErrorInFunction + << "Can only evaluate distributed AMI with nonBlocking" + << exit(FatalError); + } + + if (!this->ready()) + { + FatalErrorInFunction + << "Outstanding recv request(s) on patch " + << cyclicACMIPatch_.name() + << " field " << this->internalField().name() + << abort(FatalError); + } + + const labelUList& nbrFaceCells = + lduAddr.patchAddr(cyclicACMIPatch_.neighbPatchID()); + + Field pnf(psiInternal, nbrFaceCells); + + // Transform according to the transformation tensors + transformCoupleField(pnf); + + cyclicACMIPatch_.initInterpolate + ( + pnf, + sendRequests_, + sendBufs_, + recvRequests_, + recvBufs_ + ); + } +} + + template void Foam::cyclicACMIFvPatchField::updateInterfaceMatrix ( @@ -270,23 +724,47 @@ void Foam::cyclicACMIFvPatchField::updateInterfaceMatrix const label patchId, const Field& psiInternal, const scalarField& coeffs, - const Pstream::commsTypes + const Pstream::commsTypes commsType ) const { // note: only applying coupled contribution - const labelUList& nbrFaceCellsCoupled = - lduAddr.patchAddr(cyclicACMIPatch_.neighbPatchID()); - - Field pnf(psiInternal, nbrFaceCellsCoupled); - - // Transform according to the transformation tensors - transformCoupleField(pnf); - - pnf = cyclicACMIPatch_.interpolate(pnf); - const labelUList& faceCells = lduAddr.patchAddr(patchId); + const auto& AMI = this->ownerAMI(); + + Field pnf; + + if (AMI.distributed()) + { + if (commsType != UPstream::commsTypes::nonBlocking) + { + FatalErrorInFunction + << "Can only evaluate distributed AMI with nonBlocking" + << exit(FatalError); + } + + pnf = + cyclicACMIPatch_.interpolate + ( + Field::null(), // Not used for distributed + recvRequests_, + recvBufs_ + ); + } + else + { + const labelUList& nbrFaceCells = + lduAddr.patchAddr(cyclicACMIPatch_.neighbPatchID()); + + pnf = Field(psiInternal, nbrFaceCells); + + // Transform according to the transformation tensors + transformCoupleField(pnf); + + pnf = cyclicACMIPatch_.interpolate(pnf); + } + this->addToInternalField(result, !add, faceCells, coeffs, pnf); } @@ -364,7 +842,7 @@ void Foam::cyclicACMIFvPatchField::manipulateMatrix } // Set internalCoeffs and boundaryCoeffs in the assembly matrix - // on clyclicAMI patches to be used in the individual matrix by + // on cyclicACMI patches to be used in the individual matrix by // matrix.flux() if (matrix.psi(mat).mesh().fluxRequired(this->internalField().name())) { @@ -462,6 +940,11 @@ void Foam::cyclicACMIFvPatchField::write(Ostream& os) const { fvPatchField::write(os); fvPatchField::writeValueEntry(os); + + if (patchNeighbourFieldPtr_) + { + patchNeighbourFieldPtr_->writeEntry("neighbourValue", os); + } } diff --git a/src/finiteVolume/fields/fvPatchFields/constraint/cyclicACMI/cyclicACMIFvPatchField.H b/src/finiteVolume/fields/fvPatchFields/constraint/cyclicACMI/cyclicACMIFvPatchField.H index a3664e5937..1b2a9083ad 100644 --- a/src/finiteVolume/fields/fvPatchFields/constraint/cyclicACMI/cyclicACMIFvPatchField.H +++ b/src/finiteVolume/fields/fvPatchFields/constraint/cyclicACMI/cyclicACMIFvPatchField.H @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2013-2016 OpenFOAM Foundation - Copyright (C) 2019 OpenCFD Ltd. + Copyright (C) 2019,2023 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -41,6 +41,8 @@ Usage { type cyclicACMI; + value ; + neighbourValue ; } \endverbatim @@ -80,8 +82,52 @@ class cyclicACMIFvPatchField const cyclicACMIFvPatch& cyclicACMIPatch_; + // Sending and receiving (distributed AMI) + + //- Current range of send requests (non-blocking) + mutable labelRange sendRequests_; + + //- Current range of recv requests (non-blocking) + mutable labelRange recvRequests_; + + //- Send buffers + mutable PtrList> sendBufs_; + + //- Receive buffers_ + mutable PtrList> recvBufs_; + + //- Scalar send buffers + mutable PtrList> scalarSendBufs_; + + //- Scalar receive buffers + mutable PtrList> scalarRecvBufs_; + + //- Neighbour coupled internal cell data + mutable autoPtr> patchNeighbourFieldPtr_; + + // Private Member Functions + //- Return the AMI corresponding to the owner side + const AMIPatchToPatchInterpolation& ownerAMI() const + { + return + ( + cyclicACMIPatch_.owner() + ? cyclicACMIPatch_.AMI() + : cyclicACMIPatch_.neighbPatch().AMI() + ); + } + + //- All receive/send requests have completed + virtual bool all_ready() const; + + //- Use neighbour field caching + static bool cacheNeighbourField(); + + //- Return neighbour coupled internal cell data + tmp> patchNeighbourField(const Field&) const; + //- Return neighbour side field given internal fields template tmp> neighbourSideField @@ -174,12 +220,15 @@ public: } - // Evaluation functions + // Coupling //- Return true if coupled. Note that the underlying patch // is not coupled() - the points don't align virtual bool coupled() const; + //- Are all (receive) data available? + virtual bool ready() const; + //- Return true if this patch field fixes a value // Needed to check if a level has to be specified while solving // Poisson equations @@ -200,7 +249,6 @@ public: } } - //- Return neighbour coupled internal cell data virtual tmp> patchNeighbourField() const; @@ -210,7 +258,32 @@ public: //- Return reference to non-overlapping patchField const fvPatchField& nonOverlapPatchField() const; - //- Update result field based on interface functionality + + // Evaluation + + //- Initialise the evaluation of the patch field + virtual void initEvaluate(const Pstream::commsTypes commsType); + + //- Evaluate the patch field + virtual void evaluate(const Pstream::commsTypes commsType); + + + // Coupled interface functionality + + //- Initialise neighbour matrix update + 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; + + //- Update result field based on interface functionality virtual void updateInterfaceMatrix ( solveScalarField& result, @@ -223,6 +296,18 @@ public: const Pstream::commsTypes commsType ) const; + //- Initialise neighbour matrix update + virtual void initInterfaceMatrixUpdate + ( + Field& result, + const bool add, + const lduAddressing& lduAddr, + const label patchId, + const Field& psiInternal, + const scalarField& coeffs, + const Pstream::commsTypes commsType + ) const; + //- Update result field based on interface functionality virtual void updateInterfaceMatrix ( diff --git a/src/finiteVolume/fields/fvPatchFields/constraint/cyclicAMI/cyclicAMIFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/constraint/cyclicAMI/cyclicAMIFvPatchField.C index c0af222ce5..9f3d146b1c 100644 --- a/src/finiteVolume/fields/fvPatchFields/constraint/cyclicAMI/cyclicAMIFvPatchField.C +++ b/src/finiteVolume/fields/fvPatchFields/constraint/cyclicAMI/cyclicAMIFvPatchField.C @@ -76,16 +76,19 @@ Foam::cyclicAMIFvPatchField::cyclicAMIFvPatchField << exit(FatalIOError); } - // Handle neighbour value first, before any evaluate() - const auto* hasNeighbValue = - dict.findEntry("neighbourValue", keyType::LITERAL); - - if (hasNeighbValue) + if (cacheNeighbourField()) { - patchNeighbourFieldPtr_.reset - ( - new Field(*hasNeighbValue, p.size()) - ); + // Handle neighbour value first, before any evaluate() + const auto* hasNeighbValue = + dict.findEntry("neighbourValue", keyType::LITERAL); + + if (hasNeighbValue) + { + patchNeighbourFieldPtr_.reset + ( + new Field(*hasNeighbValue, p.size()) + ); + } } // Use 'value' supplied, or evaluate (if coupled) or set to internal field @@ -119,7 +122,7 @@ Foam::cyclicAMIFvPatchField::cyclicAMIFvPatchField recvRequests_(0), patchNeighbourFieldPtr_(nullptr) { - if (ptf.patchNeighbourFieldPtr_) + if (ptf.patchNeighbourFieldPtr_ && cacheNeighbourField()) { patchNeighbourFieldPtr_.reset ( @@ -298,11 +301,22 @@ Foam::cyclicAMIFvPatchField::patchNeighbourField } +template +bool Foam::cyclicAMIFvPatchField::cacheNeighbourField() +{ + return + ( + GeometricField::Boundary::localConsistency + != 0 + ); +} + + template Foam::tmp> Foam::cyclicAMIFvPatchField::patchNeighbourField() const { - if (this->ownerAMI().distributed()) + if (this->ownerAMI().distributed() && cacheNeighbourField()) { if (!this->ready()) { @@ -360,7 +374,7 @@ void Foam::cyclicAMIFvPatchField::initEvaluate this->updateCoeffs(); } - if (this->ownerAMI().distributed()) + if (this->ownerAMI().distributed() && cacheNeighbourField()) { if (commsType != UPstream::commsTypes::nonBlocking) { @@ -404,7 +418,7 @@ void Foam::cyclicAMIFvPatchField::evaluate const auto& AMI = this->ownerAMI(); - if (AMI.distributed()) + if (AMI.distributed() && cacheNeighbourField()) { // Calculate patchNeighbourField if (commsType != UPstream::commsTypes::nonBlocking) @@ -513,16 +527,11 @@ void Foam::cyclicAMIFvPatchField::updateInterfaceMatrix const labelUList& faceCells = lduAddr.patchAddr(patchId); - const auto& AMI = - ( - cyclicAMIPatch_.owner() - ? cyclicAMIPatch_.AMI() - : cyclicAMIPatch_.neighbPatch().AMI() - ); + const auto& AMI = this->ownerAMI(); solveScalarField pnf; - if (this->ownerAMI().distributed()) + if (AMI.distributed()) { if (commsType != UPstream::commsTypes::nonBlocking) { diff --git a/src/finiteVolume/fields/fvPatchFields/constraint/cyclicAMI/cyclicAMIFvPatchField.H b/src/finiteVolume/fields/fvPatchFields/constraint/cyclicAMI/cyclicAMIFvPatchField.H index a843f3c175..59d07dfb9b 100644 --- a/src/finiteVolume/fields/fvPatchFields/constraint/cyclicAMI/cyclicAMIFvPatchField.H +++ b/src/finiteVolume/fields/fvPatchFields/constraint/cyclicAMI/cyclicAMIFvPatchField.H @@ -133,6 +133,9 @@ class cyclicAMIFvPatchField //- All receive/send requests have completed virtual bool all_ready() const; + //- Use neighbour field caching + static bool cacheNeighbourField(); + //- Return neighbour coupled internal cell data tmp> patchNeighbourField(const Field&) const; diff --git a/src/finiteVolume/fvMesh/fvPatches/constraint/cyclicACMI/cyclicACMIFvPatch.H b/src/finiteVolume/fvMesh/fvPatches/constraint/cyclicACMI/cyclicACMIFvPatch.H index 16ca0b4586..9525a4db0a 100644 --- a/src/finiteVolume/fvMesh/fvPatches/constraint/cyclicACMI/cyclicACMIFvPatch.H +++ b/src/finiteVolume/fvMesh/fvPatches/constraint/cyclicACMI/cyclicACMIFvPatch.H @@ -213,6 +213,48 @@ public: return interpolate(tfld()); } + // Interpolations (non-blocking). Subject to change + + template + void initInterpolate + ( + const Field& fld, + labelRange& sendRequests, + PtrList>& sendBuffers, + labelRange& recvRequests, + PtrList>& recvBuffers + ) const + { + // Make sure areas are up-to-date + updateAreas(); + + cyclicACMIPolyPatch_.initInterpolate + ( + fld, + sendRequests, + sendBuffers, + recvRequests, + recvBuffers + ); + } + + template + tmp> interpolate + ( + const Field& localFld, + const labelRange& requests, // The receive requests + const PtrList>& recvBuffers + ) const + { + return cyclicACMIPolyPatch_.interpolate + ( + localFld, + requests, + recvBuffers, + UList() + ); + } + // Interface transfer functions