diff --git a/src/finiteVolume/fields/fvPatchFields/constraint/cyclicACMI/cyclicACMIFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/constraint/cyclicACMI/cyclicACMIFvPatchField.C index ebd326cdb3..51e975cfdd 100644 --- a/src/finiteVolume/fields/fvPatchFields/constraint/cyclicACMI/cyclicACMIFvPatchField.C +++ b/src/finiteVolume/fields/fvPatchFields/constraint/cyclicACMI/cyclicACMIFvPatchField.C @@ -227,9 +227,15 @@ bool Foam::cyclicACMIFvPatchField::all_ready() const recvRequests_.start(), recvRequests_.size() ) + && UPstream::finishedRequests + ( + recvRequests1_.start(), + recvRequests1_.size() + ) ) { recvRequests_.clear(); + recvRequests1_.clear(); ++done; } @@ -240,9 +246,15 @@ bool Foam::cyclicACMIFvPatchField::all_ready() const sendRequests_.start(), sendRequests_.size() ) + && UPstream::finishedRequests + ( + sendRequests1_.start(), + sendRequests1_.size() + ) ) { sendRequests_.clear(); + sendRequests1_.clear(); ++done; } @@ -260,9 +272,15 @@ bool Foam::cyclicACMIFvPatchField::ready() const recvRequests_.start(), recvRequests_.size() ) + && UPstream::finishedRequests + ( + recvRequests1_.start(), + recvRequests1_.size() + ) ) { recvRequests_.clear(); + recvRequests1_.clear(); if ( @@ -271,9 +289,15 @@ bool Foam::cyclicACMIFvPatchField::ready() const sendRequests_.start(), sendRequests_.size() ) + && UPstream::finishedRequests + ( + sendRequests1_.start(), + sendRequests1_.size() + ) ) { sendRequests_.clear(); + sendRequests1_.clear(); } return true; @@ -483,7 +507,7 @@ void Foam::cyclicACMIFvPatchField::initEvaluate const Field pnf(this->primitiveField(), nbrFaceCells); // Assert that all receives are known to have finished - if (!recvRequests_.empty()) + if (!recvRequests_.empty() || !recvRequests1_.empty()) { FatalErrorInFunction << "Outstanding recv request(s) on patch " @@ -494,14 +518,20 @@ void Foam::cyclicACMIFvPatchField::initEvaluate // Assume that sends are also OK sendRequests_.clear(); + sendRequests1_.clear(); cyclicACMIPatch_.initInterpolate ( pnf, sendRequests_, - sendBufs_, recvRequests_, - recvBufs_ + sendBufs_, + recvBufs_, + + sendRequests1_, + recvRequests1_, + sendBufs1_, + recvBufs1_ ); } } @@ -547,12 +577,15 @@ void Foam::cyclicACMIFvPatchField::evaluate ( Field::null(), // Not used for distributed recvRequests_, - recvBufs_ + recvBufs_, + recvRequests1_, + recvBufs1_ ).ptr() ); // Receive requests all handled by last function call recvRequests_.clear(); + recvRequests1_.clear(); if (doTransform()) { @@ -608,7 +641,7 @@ void Foam::cyclicACMIFvPatchField::initInterfaceMatrixUpdate transformCoupleField(pnf, cmpt); // Assert that all receives are known to have finished - if (!recvRequests_.empty()) + if (!recvRequests_.empty() || !recvRequests1_.empty()) { FatalErrorInFunction << "Outstanding recv request(s) on patch " @@ -619,14 +652,20 @@ void Foam::cyclicACMIFvPatchField::initInterfaceMatrixUpdate // Assume that sends are also OK sendRequests_.clear(); + sendRequests1_.clear(); cyclicACMIPatch_.initInterpolate ( pnf, sendRequests_, - scalarSendBufs_, recvRequests_, - scalarRecvBufs_ + scalarSendBufs_, + scalarRecvBufs_, + + sendRequests1_, + recvRequests1_, + scalarSendBufs1_, + scalarRecvBufs1_ ); } @@ -681,11 +720,14 @@ void Foam::cyclicACMIFvPatchField::updateInterfaceMatrix ( solveScalarField::null(), // Not used for distributed recvRequests_, - scalarRecvBufs_ + scalarRecvBufs_, + recvRequests1_, + scalarRecvBufs1_ ); // Receive requests all handled by last function call recvRequests_.clear(); + recvRequests1_.clear(); } else { @@ -738,7 +780,7 @@ void Foam::cyclicACMIFvPatchField::initInterfaceMatrixUpdate transformCoupleField(pnf); // Assert that all receives are known to have finished - if (!recvRequests_.empty()) + if (!recvRequests_.empty() || !recvRequests1_.empty()) { FatalErrorInFunction << "Outstanding recv request(s) on patch " @@ -749,14 +791,20 @@ void Foam::cyclicACMIFvPatchField::initInterfaceMatrixUpdate // Assume that sends are also OK sendRequests_.clear(); + sendRequests1_.clear(); cyclicACMIPatch_.initInterpolate ( pnf, sendRequests_, - sendBufs_, recvRequests_, - recvBufs_ + sendBufs_, + recvBufs_, + + sendRequests1_, + recvRequests1_, + sendBufs1_, + recvBufs1_ ); } @@ -798,11 +846,14 @@ void Foam::cyclicACMIFvPatchField::updateInterfaceMatrix ( Field::null(), // Not used for distributed recvRequests_, - recvBufs_ + recvBufs_, + recvRequests1_, + recvBufs1_ ); // Receive requests all handled by last function call recvRequests_.clear(); + recvRequests1_.clear(); } else { diff --git a/src/finiteVolume/fields/fvPatchFields/constraint/cyclicACMI/cyclicACMIFvPatchField.H b/src/finiteVolume/fields/fvPatchFields/constraint/cyclicACMI/cyclicACMIFvPatchField.H index 3647bdd38e..4baa003659 100644 --- a/src/finiteVolume/fields/fvPatchFields/constraint/cyclicACMI/cyclicACMIFvPatchField.H +++ b/src/finiteVolume/fields/fvPatchFields/constraint/cyclicACMI/cyclicACMIFvPatchField.H @@ -102,6 +102,28 @@ class cyclicACMIFvPatchField //- Scalar receive buffers mutable PtrList> scalarRecvBufs_; + + // Only used for AMI caching + + //- Current range of send requests (non-blocking) + mutable labelRange sendRequests1_; + + //- Current range of recv requests (non-blocking) + mutable labelRange recvRequests1_; + + //- Send buffers + mutable PtrList> sendBufs1_; + + //- Receive buffers_ + mutable PtrList> recvBufs1_; + + //- Scalar send buffers + mutable PtrList> scalarSendBufs1_; + + //- Scalar receive buffers + mutable PtrList> scalarRecvBufs1_; + + //- Neighbour coupled internal cell data mutable autoPtr> patchNeighbourFieldPtr_; diff --git a/src/finiteVolume/fields/fvPatchFields/constraint/cyclicAMI/cyclicAMIFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/constraint/cyclicAMI/cyclicAMIFvPatchField.C index 314bbc5c21..9c67211448 100644 --- a/src/finiteVolume/fields/fvPatchFields/constraint/cyclicAMI/cyclicAMIFvPatchField.C +++ b/src/finiteVolume/fields/fvPatchFields/constraint/cyclicAMI/cyclicAMIFvPatchField.C @@ -207,9 +207,15 @@ bool Foam::cyclicAMIFvPatchField::all_ready() const recvRequests_.start(), recvRequests_.size() ) + && UPstream::finishedRequests + ( + recvRequests1_.start(), + recvRequests1_.size() + ) ) { recvRequests_.clear(); + recvRequests1_.clear(); ++done; } @@ -220,9 +226,15 @@ bool Foam::cyclicAMIFvPatchField::all_ready() const sendRequests_.start(), sendRequests_.size() ) + && UPstream::finishedRequests + ( + sendRequests1_.start(), + sendRequests1_.size() + ) ) { sendRequests_.clear(); + sendRequests1_.clear(); ++done; } @@ -240,9 +252,15 @@ bool Foam::cyclicAMIFvPatchField::ready() const recvRequests_.start(), recvRequests_.size() ) + && UPstream::finishedRequests + ( + recvRequests1_.start(), + recvRequests1_.size() + ) ) { recvRequests_.clear(); + recvRequests1_.clear(); if ( @@ -251,9 +269,15 @@ bool Foam::cyclicAMIFvPatchField::ready() const sendRequests_.start(), sendRequests_.size() ) + && UPstream::finishedRequests + ( + sendRequests1_.start(), + sendRequests1_.size() + ) ) { sendRequests_.clear(); + sendRequests1_.clear(); } return true; @@ -319,8 +343,9 @@ Foam::cyclicAMIFvPatchField::getNeighbourField template -bool Foam::cyclicAMIFvPatchField::cacheNeighbourField() +bool Foam::cyclicAMIFvPatchField::cacheNeighbourField() const { + return false; return (FieldBase::localBoundaryConsistency() != 0); } @@ -491,7 +516,7 @@ void Foam::cyclicAMIFvPatchField::initEvaluate const cyclicAMIPolyPatch& cpp = cyclicAMIPatch_.cyclicAMIPatch(); // Assert that all receives are known to have finished - if (!recvRequests_.empty()) + if (!recvRequests_.empty() || !recvRequests1_.empty()) { FatalErrorInFunction << "Outstanding recv request(s) on patch " @@ -502,14 +527,20 @@ void Foam::cyclicAMIFvPatchField::initEvaluate // Assume that sends are also OK sendRequests_.clear(); + sendRequests1_.clear(); cpp.initInterpolate ( pnf, sendRequests_, - sendBufs_, recvRequests_, - recvBufs_ + sendBufs_, + recvBufs_, + + sendRequests1_, + recvRequests1_, + sendBufs1_, + recvBufs1_ ); } } @@ -562,12 +593,15 @@ void Foam::cyclicAMIFvPatchField::evaluate Field::null(), // Not used for distributed recvRequests_, recvBufs_, + recvRequests1_, + recvBufs1_, defaultValues ).ptr() ); // Receive requests all handled by last function call recvRequests_.clear(); + recvRequests1_.clear(); if (doTransform()) { @@ -618,7 +652,7 @@ void Foam::cyclicAMIFvPatchField::initInterfaceMatrixUpdate const cyclicAMIPolyPatch& cpp = cyclicAMIPatch_.cyclicAMIPatch(); // Assert that all receives are known to have finished - if (!recvRequests_.empty()) + if (!recvRequests_.empty() || !recvRequests1_.empty()) { FatalErrorInFunction << "Outstanding recv request(s) on patch " @@ -629,14 +663,20 @@ void Foam::cyclicAMIFvPatchField::initInterfaceMatrixUpdate // Assume that sends are also OK sendRequests_.clear(); + sendRequests1_.clear(); cpp.initInterpolate ( pnf, sendRequests_, - scalarSendBufs_, recvRequests_, - scalarRecvBufs_ + scalarSendBufs_, + scalarRecvBufs_, + + sendRequests1_, + recvRequests1_, + scalarSendBufs1_, + scalarRecvBufs1_ ); } @@ -691,11 +731,14 @@ void Foam::cyclicAMIFvPatchField::updateInterfaceMatrix solveScalarField::null(), // Not used for distributed recvRequests_, scalarRecvBufs_, + recvRequests1_, + scalarRecvBufs1_, defaultValues ); // Receive requests all handled by last function call recvRequests_.clear(); + recvRequests1_.clear(); } else { @@ -757,7 +800,7 @@ void Foam::cyclicAMIFvPatchField::initInterfaceMatrixUpdate const cyclicAMIPolyPatch& cpp = cyclicAMIPatch_.cyclicAMIPatch(); // Assert that all receives are known to have finished - if (!recvRequests_.empty()) + if (!recvRequests_.empty() || !recvRequests1_.empty()) { FatalErrorInFunction << "Outstanding recv request(s) on patch " @@ -768,14 +811,20 @@ void Foam::cyclicAMIFvPatchField::initInterfaceMatrixUpdate // Assume that sends are also OK sendRequests_.clear(); + sendRequests1_.clear(); cpp.initInterpolate ( pnf, sendRequests_, - sendBufs_, recvRequests_, - recvBufs_ + sendBufs_, + recvBufs_, + + sendRequests1_, + recvRequests1_, + sendBufs1_, + recvBufs1_ ); } @@ -829,11 +878,14 @@ void Foam::cyclicAMIFvPatchField::updateInterfaceMatrix Field::null(), // Not used for distributed recvRequests_, recvBufs_, + recvRequests1_, + recvBufs1_, defaultValues ); // Receive requests all handled by last function call recvRequests_.clear(); + recvRequests1_.clear(); } else { @@ -918,7 +970,7 @@ void Foam::cyclicAMIFvPatchField::manipulateMatrix } // Set internalCoeffs and boundaryCoeffs in the assembly matrix - // on clyclicAMI patches to be used in the individual matrix by + // on cyclicAMI patches to be used in the individual matrix by // matrix.flux() if (matrix.psi(mat).mesh().fluxRequired(this->internalField().name())) { diff --git a/src/finiteVolume/fields/fvPatchFields/constraint/cyclicAMI/cyclicAMIFvPatchField.H b/src/finiteVolume/fields/fvPatchFields/constraint/cyclicAMI/cyclicAMIFvPatchField.H index a0ed730956..6e5c9943ac 100644 --- a/src/finiteVolume/fields/fvPatchFields/constraint/cyclicAMI/cyclicAMIFvPatchField.H +++ b/src/finiteVolume/fields/fvPatchFields/constraint/cyclicAMI/cyclicAMIFvPatchField.H @@ -113,6 +113,28 @@ class cyclicAMIFvPatchField //- Scalar receive buffers mutable PtrList> scalarRecvBufs_; + + // Only used for AMI caching + + //- Current range of send requests (non-blocking) + mutable labelRange sendRequests1_; + + //- Current range of recv requests (non-blocking) + mutable labelRange recvRequests1_; + + //- Send buffers + mutable PtrList> sendBufs1_; + + //- Receive buffers_ + mutable PtrList> recvBufs1_; + + //- Scalar send buffers + mutable PtrList> scalarSendBufs1_; + + //- Scalar receive buffers + mutable PtrList> scalarRecvBufs1_; + + //- Neighbour coupled internal cell data mutable autoPtr> patchNeighbourFieldPtr_; @@ -134,7 +156,7 @@ class cyclicAMIFvPatchField virtual bool all_ready() const; //- Use neighbour field caching - static bool cacheNeighbourField(); + bool cacheNeighbourField() const; //- Return neighbour coupled internal cell data tmp> getNeighbourField(const UList&) const; diff --git a/src/finiteVolume/fvMesh/fvPatches/constraint/cyclicACMI/cyclicACMIFvPatch.H b/src/finiteVolume/fvMesh/fvPatches/constraint/cyclicACMI/cyclicACMIFvPatch.H index 9525a4db0a..68c98c8d01 100644 --- a/src/finiteVolume/fvMesh/fvPatches/constraint/cyclicACMI/cyclicACMIFvPatch.H +++ b/src/finiteVolume/fvMesh/fvPatches/constraint/cyclicACMI/cyclicACMIFvPatch.H @@ -220,9 +220,14 @@ public: ( const Field& fld, labelRange& sendRequests, - PtrList>& sendBuffers, labelRange& recvRequests, - PtrList>& recvBuffers + PtrList>& sendBuffers, + PtrList>& recvBuffers, + + labelRange& sendRequests1, + labelRange& recvRequests1, + PtrList>& sendBuffers1, + PtrList>& recvBuffers1 ) const { // Make sure areas are up-to-date @@ -232,9 +237,14 @@ public: ( fld, sendRequests, - sendBuffers, recvRequests, - recvBuffers + sendBuffers, + recvBuffers, + + sendRequests1, + recvRequests1, + sendBuffers1, + recvBuffers1 ); } @@ -243,7 +253,9 @@ public: ( const Field& localFld, const labelRange& requests, // The receive requests - const PtrList>& recvBuffers + const PtrList>& recvBuffers, + const labelRange& requests1, // The receive requests + const PtrList>& recvBuffers1 ) const { return cyclicACMIPolyPatch_.interpolate @@ -251,6 +263,8 @@ public: localFld, requests, recvBuffers, + requests1, + recvBuffers1, UList() ); } diff --git a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolationTemplates.C b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolationTemplates.C index 090b203855..6e4d6e8b6a 100644 --- a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolationTemplates.C +++ b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolationTemplates.C @@ -89,37 +89,18 @@ void Foam::AMIInterpolation::weightedSum const UList& defaultValues ) const { - cache_.setDirection(toSource); - - const auto wsum = [&](List& res, const label i){ - weightedSum - ( - lowWeightCorrection_, - cache_.cSrcAddress(i), - cache_.cSrcWeights(i), - cache_.cSrcWeightsSum(i), - fld, - multiplyWeightedOp>(plusEqOp()), - res, - defaultValues - ); - }; - - if (!cache_.apply(result, wsum)) - { - // Both -1 => equates to non-caching - weightedSum - ( - lowWeightCorrection_, - (toSource ? srcAddress_ : tgtAddress_), - (toSource ? srcWeights_ : tgtWeights_), - (toSource ? srcWeightsSum_ : tgtWeightsSum_), - fld, - multiplyWeightedOp>(plusEqOp()), - result, - defaultValues - ); - } + // Note: using non-caching AMI + weightedSum + ( + lowWeightCorrection_, + (toSource ? srcAddress_ : tgtAddress_), + (toSource ? srcWeights_ : tgtWeights_), + (toSource ? srcWeightsSum_ : tgtWeightsSum_), + fld, + multiplyWeightedOp>(plusEqOp()), + result, + defaultValues + ); } @@ -208,7 +189,11 @@ void Foam::AMIInterpolation::interpolate map.distribute(work); } - result0.resize_nocopy(srcAddress.size()); + if constexpr (is_contiguous_scalar::value) + { + result0 = Zero; + } + weightedSum ( lowWeightCorrection_, @@ -248,7 +233,11 @@ void Foam::AMIInterpolation::interpolate map.distribute(work); } - result1.resize_nocopy(srcAddress.size()); + if constexpr (is_contiguous_scalar::value) + { + result1 = Zero; + } + weightedSum ( lowWeightCorrection_, @@ -309,6 +298,12 @@ void Foam::AMIInterpolation::interpolate } result.resize_nocopy(srcAddress.size()); + + if constexpr (is_contiguous_scalar::value) + { + result = Zero; + } + weightedSum ( lowWeightCorrection_, diff --git a/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicACMIGAMGInterfaceField/cyclicACMIGAMGInterfaceField.C b/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicACMIGAMGInterfaceField/cyclicACMIGAMGInterfaceField.C index 0d1cc1f1d7..4f0a50270a 100644 --- a/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicACMIGAMGInterfaceField/cyclicACMIGAMGInterfaceField.C +++ b/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicACMIGAMGInterfaceField/cyclicACMIGAMGInterfaceField.C @@ -67,9 +67,7 @@ Foam::cyclicACMIGAMGInterfaceField::cyclicACMIGAMGInterfaceField GAMGInterfaceField(GAMGCp, fineInterface), cyclicACMIInterface_(refCast(GAMGCp)), doTransform_(false), - rank_(0), - sendRequests_(), - recvRequests_() + rank_(0) { const cyclicAMILduInterfaceField& p = refCast(fineInterface); @@ -89,9 +87,7 @@ Foam::cyclicACMIGAMGInterfaceField::cyclicACMIGAMGInterfaceField GAMGInterfaceField(GAMGCp, doTransform, rank), cyclicACMIInterface_(refCast(GAMGCp)), doTransform_(doTransform), - rank_(rank), - sendRequests_(), - recvRequests_() + rank_(rank) {} @@ -104,9 +100,7 @@ Foam::cyclicACMIGAMGInterfaceField::cyclicACMIGAMGInterfaceField GAMGInterfaceField(GAMGCp, is), cyclicACMIInterface_(refCast(GAMGCp)), doTransform_(readBool(is)), - rank_(readLabel(is)), - sendRequests_(), - recvRequests_() + rank_(readLabel(is)) {} @@ -120,9 +114,7 @@ Foam::cyclicACMIGAMGInterfaceField::cyclicACMIGAMGInterfaceField GAMGInterfaceField(GAMGCp, local), cyclicACMIInterface_(refCast(GAMGCp)), doTransform_(false), - rank_(0), - sendRequests_(), - recvRequests_() + rank_(0) { const auto& p = refCast(local); @@ -142,9 +134,15 @@ bool Foam::cyclicACMIGAMGInterfaceField::ready() const recvRequests_.start(), recvRequests_.size() ) + && UPstream::finishedRequests + ( + recvRequests1_.start(), + recvRequests1_.size() + ) ) { recvRequests_.clear(); + recvRequests1_.clear(); if ( @@ -153,9 +151,15 @@ bool Foam::cyclicACMIGAMGInterfaceField::ready() const sendRequests_.start(), sendRequests_.size() ) + && UPstream::finishedRequests + ( + sendRequests1_.start(), + sendRequests1_.size() + ) ) { sendRequests_.clear(); + sendRequests1_.clear(); } return true; @@ -210,15 +214,9 @@ void Foam::cyclicACMIGAMGInterfaceField::initInterfaceMatrixUpdate // Transform according to the transformation tensors transformCoupleField(pnf, cmpt); - const auto& map = - ( - cyclicACMIInterface_.owner() - ? AMI.tgtMap() - : AMI.srcMap() - ); // Assert that all receives are known to have finished - if (!recvRequests_.empty()) + if (!recvRequests_.empty() || !recvRequests1_.empty()) { FatalErrorInFunction << "Outstanding recv request(s) on patch " @@ -226,22 +224,63 @@ void Foam::cyclicACMIGAMGInterfaceField::initInterfaceMatrixUpdate << abort(FatalError); } - // Assume that sends are also OK - sendRequests_.clear(); + const auto& cache = AMI.cache(); - // Insert send/receive requests (non-blocking). See e.g. - // cyclicAMIPolyPatchTemplates.C - const label oldWarnComm = UPstream::commWarn(AMI.comm()); - map.send - ( - pnf, - sendRequests_, - scalarSendBufs_, - recvRequests_, - scalarRecvBufs_, - 19462+cyclicACMIInterface_.index() // unique offset + patch index - ); - UPstream::commWarn(oldWarnComm); + if (cache.index0() == -1 && cache.index1() == -1) + { + const auto& map = + ( + cyclicACMIInterface_.owner() + ? AMI.tgtMap() + : AMI.srcMap() + ); + + // Insert send/receive requests (non-blocking). See e.g. + // cyclicAMIPolyPatchTemplates.C + const label oldWarnComm = UPstream::commWarn(AMI.comm()); + map.send + ( + pnf, + sendRequests_, + scalarSendBufs_, + recvRequests_, + scalarRecvBufs_, + 19462+cyclicACMIInterface_.index() // unique offset + patch index + ); + UPstream::commWarn(oldWarnComm); + } + else + { + cache.setDirection(cyclicACMIInterface_.owner()); + + if (cache.index0() != -1) + { + const auto& map0 = cache.cTgtMapPtr0()(); + map0.send + ( + pnf, + sendRequests_, + scalarSendBufs_, + recvRequests_, + scalarRecvBufs_, + 19462+cyclicACMIInterface_.index() // unique offset + patch index + ); + } + + if (cache.index1() != -1) + { + const auto& map1 = cache.cTgtMapPtr1()(); + map1.send + ( + pnf, + sendRequests1_, + scalarSendBufs1_, + recvRequests1_, + scalarRecvBufs1_, + 19463+cyclicACMIInterface_.index() // unique offset + patch index + ); + } + } } this->updatedMatrix(false); @@ -260,6 +299,8 @@ void Foam::cyclicACMIGAMGInterfaceField::updateInterfaceMatrix const Pstream::commsTypes ) const { + typedef multiplyWeightedOp> opType; + const labelUList& faceCells = lduAddr.patchAddr(patchId); const auto& AMI = @@ -269,48 +310,122 @@ void Foam::cyclicACMIGAMGInterfaceField::updateInterfaceMatrix : cyclicACMIInterface_.neighbPatch().AMI() ); - DebugPout<< "cyclicACMIGAMGInterfaceField::updateInterfaceMatrix() :" - << " interface:" << cyclicACMIInterface_.index() - << " size:" << cyclicACMIInterface_.size() - << " owner:" << cyclicACMIInterface_.owner() - << " AMI distributed:" << AMI.distributed() - << endl; - + const auto& cache = AMI.cache(); if (AMI.distributed() && AMI.comm() != -1) { - const auto& map = - ( - cyclicACMIInterface_.owner() - ? AMI.tgtMap() - : AMI.srcMap() - ); + if (cache.index0() == -1 && cache.index1() == -1) + { + const auto& map = + ( + cyclicACMIInterface_.owner() + ? AMI.tgtMap() + : AMI.srcMap() + ); - // Receive (= copy) data from buffers into work. TBD: receive directly - // into slices of work. - solveScalarField work; - map.receive - ( - recvRequests_, - scalarRecvBufs_, - work, - 19462+cyclicACMIInterface_.index() // unique offset + patch index - ); + // Receive (= copy) data from buffers into work. TBD: receive directly + // into slices of work. + solveScalarField work; + map.receive + ( + recvRequests_, + scalarRecvBufs_, + work, + 19462+cyclicACMIInterface_.index() // unique offset + patch index + ); - // Receive requests all handled by last function call - recvRequests_.clear(); + // Receive requests all handled by last function call + recvRequests_.clear(); - solveScalarField pnf(faceCells.size(), Zero); - AMI.weightedSum - ( - cyclicACMIInterface_.owner(), - work, - pnf, // result - solveScalarField::null() - ); + solveScalarField pnf(faceCells.size(), Zero); + AMI.weightedSum + ( + cyclicACMIInterface_.owner(), + work, + pnf, // result + solveScalarField::null() + ); - // Add result using coefficients - this->addToInternalField(result, !add, faceCells, coeffs, pnf); + // Add result using coefficients + this->addToInternalField(result, !add, faceCells, coeffs, pnf); + } + else + { + cache.setDirection(cyclicACMIInterface_.owner()); + + solveScalarField pnf(faceCells.size()); + solveScalarField work(faceCells.size()); + + if (cache.index0() != -1) + { + // Receive (= copy) data from buffers into work. TBD: receive directly + // into slices of work. + work = Zero; + cache.cTgtMapPtr0()().receive + ( + recvRequests_, + scalarRecvBufs_, + work, + 19462+cyclicACMIInterface_.index() // unique offset + patch index + ); + + // Receive requests all handled by last function call + recvRequests_.clear(); + + pnf = Zero; + AMIInterpolation::weightedSum + ( + AMI.lowWeightCorrection(), + cache.cSrcAddress0(), + cache.cSrcWeights0(), + cache.cSrcWeightsSum0(), + work, + opType(plusEqOp()), + pnf, + solveScalarField::null() + ); + + pnf *= (1-cache.weight()); + + // Add result using coefficients + this->addToInternalField(result, !add, faceCells, coeffs, pnf); + } + + if (cache.index1() != -1) + { + // Receive (= copy) data from buffers into work. TBD: receive directly + // into slices of work. + work = Zero; + cache.cTgtMapPtr1()().receive + ( + recvRequests1_, + scalarRecvBufs1_, + work, + 19463+cyclicACMIInterface_.index() // unique offset + patch index + ); + + // Receive requests all handled by last function call + recvRequests1_.clear(); + + pnf = Zero; + AMIInterpolation::weightedSum + ( + AMI.lowWeightCorrection(), + cache.cSrcAddress1(), + cache.cSrcWeights1(), + cache.cSrcWeightsSum1(), + work, + opType(plusEqOp()), + pnf, + solveScalarField::null() + ); + + pnf *= cache.weight(); + + // Add result using coefficients + this->addToInternalField(result, !add, faceCells, coeffs, pnf); + } + } } else { @@ -318,23 +433,72 @@ void Foam::cyclicACMIGAMGInterfaceField::updateInterfaceMatrix const labelUList& nbrFaceCells = lduAddr.patchAddr(cyclicACMIInterface_.neighbPatchID()); - solveScalarField pnf(psiInternal, nbrFaceCells); + solveScalarField work(psiInternal, nbrFaceCells); // Transform according to the transformation tensors - transformCoupleField(pnf, cmpt); + transformCoupleField(work, cmpt); - if (cyclicACMIInterface_.owner()) + if (cache.index0() == -1 && cache.index1() == -1) { - pnf = AMI.interpolateToSource(pnf); + if (cyclicACMIInterface_.owner()) + { + work = AMI.interpolateToSource(work); + } + else + { + work = AMI.interpolateToTarget(work); + } + + const labelUList& faceCells = lduAddr.patchAddr(patchId); + + this->addToInternalField(result, !add, faceCells, coeffs, work); } else { - pnf = AMI.interpolateToTarget(pnf); + cache.setDirection(cyclicACMIInterface_.owner()); + + solveScalarField pnf(faceCells.size()); + + if (cache.index0() != -1) + { + pnf = Zero; + AMIInterpolation::weightedSum + ( + AMI.lowWeightCorrection(), + cache.cSrcAddress0(), + cache.cSrcWeights0(), + cache.cSrcWeightsSum0(), + work, + opType(plusEqOp()), + pnf, + solveScalarField::null() + ); + + pnf *= (1 - cache.weight()); + + this->addToInternalField(result, !add, faceCells, coeffs, pnf); + } + + if (cache.index1() != -1) + { + pnf = Zero; + AMIInterpolation::weightedSum + ( + AMI.lowWeightCorrection(), + cache.cSrcAddress1(), + cache.cSrcWeights1(), + cache.cSrcWeightsSum1(), + work, + opType(plusEqOp()), + pnf, + solveScalarField::null() + ); + + pnf *= cache.weight(); + + this->addToInternalField(result, !add, faceCells, coeffs, pnf); + } } - - const labelUList& faceCells = lduAddr.patchAddr(patchId); - - this->addToInternalField(result, !add, faceCells, coeffs, pnf); } this->updatedMatrix(true); diff --git a/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicACMIGAMGInterfaceField/cyclicACMIGAMGInterfaceField.H b/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicACMIGAMGInterfaceField/cyclicACMIGAMGInterfaceField.H index e40687e593..7909dcf777 100644 --- a/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicACMIGAMGInterfaceField/cyclicACMIGAMGInterfaceField.H +++ b/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicACMIGAMGInterfaceField/cyclicACMIGAMGInterfaceField.H @@ -83,6 +83,20 @@ class cyclicACMIGAMGInterfaceField //- Scalar receive buffers mutable PtrList> scalarRecvBufs_; + // Only used for AMI caching + + //- Current range of send requests (non-blocking) + mutable labelRange sendRequests1_; + + //- Current range of recv requests (non-blocking) + mutable labelRange recvRequests1_; + + //- Scalar send buffers + mutable PtrList> scalarSendBufs1_; + + //- Scalar receive buffers + mutable PtrList> scalarRecvBufs1_; + // Private Member Functions diff --git a/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicAMIGAMGInterfaceField/cyclicAMIGAMGInterfaceField.C b/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicAMIGAMGInterfaceField/cyclicAMIGAMGInterfaceField.C index ee07f27441..83c7e92246 100644 --- a/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicAMIGAMGInterfaceField/cyclicAMIGAMGInterfaceField.C +++ b/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicAMIGAMGInterfaceField/cyclicAMIGAMGInterfaceField.C @@ -67,9 +67,7 @@ Foam::cyclicAMIGAMGInterfaceField::cyclicAMIGAMGInterfaceField GAMGInterfaceField(GAMGCp, fineInterface), cyclicAMIInterface_(refCast(GAMGCp)), doTransform_(false), - rank_(0), - sendRequests_(), - recvRequests_() + rank_(0) { const cyclicAMILduInterfaceField& p = refCast(fineInterface); @@ -89,9 +87,7 @@ Foam::cyclicAMIGAMGInterfaceField::cyclicAMIGAMGInterfaceField GAMGInterfaceField(GAMGCp, doTransform, rank), cyclicAMIInterface_(refCast(GAMGCp)), doTransform_(doTransform), - rank_(rank), - sendRequests_(), - recvRequests_() + rank_(rank) {} @@ -104,9 +100,7 @@ Foam::cyclicAMIGAMGInterfaceField::cyclicAMIGAMGInterfaceField GAMGInterfaceField(GAMGCp, is), cyclicAMIInterface_(refCast(GAMGCp)), doTransform_(readBool(is)), - rank_(readLabel(is)), - sendRequests_(), - recvRequests_() + rank_(readLabel(is)) {} @@ -120,9 +114,7 @@ Foam::cyclicAMIGAMGInterfaceField::cyclicAMIGAMGInterfaceField GAMGInterfaceField(GAMGCp, local), cyclicAMIInterface_(refCast(GAMGCp)), doTransform_(false), - rank_(0), - sendRequests_(), // assume no requests in flight for input field - recvRequests_() + rank_(0) { const auto& p = refCast(local); @@ -142,9 +134,15 @@ bool Foam::cyclicAMIGAMGInterfaceField::ready() const recvRequests_.start(), recvRequests_.size() ) + && UPstream::finishedRequests + ( + recvRequests1_.start(), + recvRequests1_.size() + ) ) { recvRequests_.clear(); + recvRequests1_.clear(); if ( @@ -153,9 +151,15 @@ bool Foam::cyclicAMIGAMGInterfaceField::ready() const sendRequests_.start(), sendRequests_.size() ) + && UPstream::finishedRequests + ( + sendRequests1_.start(), + sendRequests1_.size() + ) ) { sendRequests_.clear(); + sendRequests1_.clear(); } return true; @@ -183,7 +187,6 @@ void Foam::cyclicAMIGAMGInterfaceField::initInterfaceMatrixUpdate ? cyclicAMIInterface_.AMI() : cyclicAMIInterface_.neighbPatch().AMI() ); - if (AMI.distributed() && AMI.comm() != -1) { //DebugPout<< "cyclicAMIFvPatchField::initInterfaceMatrixUpdate() :" @@ -211,15 +214,8 @@ void Foam::cyclicAMIGAMGInterfaceField::initInterfaceMatrixUpdate // Transform according to the transformation tensors transformCoupleField(pnf, cmpt); - const auto& map = - ( - cyclicAMIInterface_.owner() - ? AMI.tgtMap() - : AMI.srcMap() - ); - // Assert that all receives are known to have finished - if (!recvRequests_.empty()) + if (!recvRequests_.empty() || !recvRequests1_.empty()) { FatalErrorInFunction << "Outstanding recv request(s) on patch " @@ -227,22 +223,63 @@ void Foam::cyclicAMIGAMGInterfaceField::initInterfaceMatrixUpdate << abort(FatalError); } - // Assume that sends are also OK - sendRequests_.clear(); + const auto& cache = AMI.cache(); - // Insert send/receive requests (non-blocking). See e.g. - // cyclicAMIPolyPatchTemplates.C - const label oldWarnComm = UPstream::commWarn(AMI.comm()); - map.send - ( - pnf, - sendRequests_, - scalarSendBufs_, - recvRequests_, - scalarRecvBufs_, - 19462+cyclicAMIInterface_.index() // unique offset + patch index - ); - UPstream::commWarn(oldWarnComm); + if (cache.index0() == -1 && cache.index1() == -1) + { + const auto& map = + ( + cyclicAMIInterface_.owner() + ? AMI.tgtMap() + : AMI.srcMap() + ); + + // Insert send/receive requests (non-blocking). See e.g. + // cyclicAMIPolyPatchTemplates.C + const label oldWarnComm = UPstream::commWarn(AMI.comm()); + map.send + ( + pnf, + sendRequests_, + scalarSendBufs_, + recvRequests_, + scalarRecvBufs_, + 19462+cyclicAMIInterface_.index() // unique offset + patch index + ); + UPstream::commWarn(oldWarnComm); + } + else + { + cache.setDirection(cyclicAMIInterface_.owner()); + + if (cache.index0() != -1) + { + const auto& map0 = cache.cTgtMapPtr0()(); + map0.send + ( + pnf, + sendRequests_, + scalarSendBufs_, + recvRequests_, + scalarRecvBufs_, + 19462+cyclicAMIInterface_.index() // unique offset + patch index + ); + } + + if (cache.index1() != -1) + { + const auto& map1 = cache.cTgtMapPtr1()(); + map1.send + ( + pnf, + sendRequests1_, + scalarSendBufs1_, + recvRequests1_, + scalarRecvBufs1_, + 19463+cyclicAMIInterface_.index() // unique offset + patch index + ); + } + } } this->updatedMatrix(false); @@ -261,6 +298,8 @@ void Foam::cyclicAMIGAMGInterfaceField::updateInterfaceMatrix const Pstream::commsTypes commsType ) const { + typedef multiplyWeightedOp> opType; + const labelUList& faceCells = lduAddr.patchAddr(patchId); const auto& AMI = @@ -284,6 +323,8 @@ void Foam::cyclicAMIGAMGInterfaceField::updateInterfaceMatrix // << " AMI low-weight:" << AMI.applyLowWeightCorrection() // << endl; + const auto& cache = AMI.cache(); + if (AMI.distributed() && AMI.comm() != -1) { if (commsType != UPstream::commsTypes::nonBlocking) @@ -293,38 +334,118 @@ void Foam::cyclicAMIGAMGInterfaceField::updateInterfaceMatrix << exit(FatalError); } - const auto& map = - ( - cyclicAMIInterface_.owner() - ? AMI.tgtMap() - : AMI.srcMap() - ); + if (cache.index0() == -1 && cache.index1() == -1) + { + const auto& map = + ( + cyclicAMIInterface_.owner() + ? AMI.tgtMap() + : AMI.srcMap() + ); - // Receive (= copy) data from buffers into work. TBD: receive directly - // into slices of work. - solveScalarField work; - map.receive - ( - recvRequests_, - scalarRecvBufs_, - work, - 19462+cyclicAMIInterface_.index() // unique offset + patch index - ); + // Receive (= copy) data from buffers into work. TBD: receive directly + // into slices of work. + solveScalarField work; + map.receive + ( + recvRequests_, + scalarRecvBufs_, + work, + 19462+cyclicAMIInterface_.index() // unique offset + patch index + ); - // Receive requests all handled by last function call - recvRequests_.clear(); + // Receive requests all handled by last function call + recvRequests_.clear(); - solveScalarField pnf(faceCells.size(), Zero); - AMI.weightedSum - ( - cyclicAMIInterface_.owner(), - work, - pnf, // result - defaultValues - ); + solveScalarField pnf(faceCells.size(), Zero); + AMI.weightedSum + ( + cyclicAMIInterface_.owner(), + work, + pnf, // result + defaultValues + ); - // Add result using coefficients - this->addToInternalField(result, !add, faceCells, coeffs, pnf); + // Add result using coefficients + this->addToInternalField(result, !add, faceCells, coeffs, pnf); + } + else + { + cache.setDirection(cyclicAMIInterface_.owner()); + + solveScalarField pnf(faceCells.size()); + solveScalarField work(faceCells.size()); + + if (cache.index0() != -1) + { + // Receive (= copy) data from buffers into work. TBD: receive directly + // into slices of work. + work = Zero; + cache.cTgtMapPtr0()().receive + ( + recvRequests_, + scalarRecvBufs_, + work, + 19462+cyclicAMIInterface_.index() // unique offset + patch index + ); + + // Receive requests all handled by last function call + recvRequests_.clear(); + + pnf = Zero; + AMIInterpolation::weightedSum + ( + AMI.lowWeightCorrection(), + cache.cSrcAddress0(), + cache.cSrcWeights0(), + cache.cSrcWeightsSum0(), + work, + opType(plusEqOp()), + pnf, + defaultValues + ); + + pnf *= (1-cache.weight()); + + // Add result using coefficients + this->addToInternalField(result, !add, faceCells, coeffs, pnf); + } + + if (cache.index1() != -1) + { + // Receive (= copy) data from buffers into work. TBD: receive directly + // into slices of work. + work = Zero; + cache.cTgtMapPtr1()().receive + ( + recvRequests1_, + scalarRecvBufs1_, + work, + 19463+cyclicAMIInterface_.index() // unique offset + patch index + ); + + // Receive requests all handled by last function call + recvRequests1_.clear(); + + pnf = Zero; + AMIInterpolation::weightedSum + ( + AMI.lowWeightCorrection(), + cache.cSrcAddress1(), + cache.cSrcWeights1(), + cache.cSrcWeightsSum1(), + work, + opType(plusEqOp()), + pnf, + defaultValues + ); + + pnf *= cache.weight(); + + // Add result using coefficients + this->addToInternalField(result, !add, faceCells, coeffs, pnf); + } + } } else { @@ -337,17 +458,68 @@ void Foam::cyclicAMIGAMGInterfaceField::updateInterfaceMatrix // Transform according to the transformation tensors transformCoupleField(work, cmpt); - solveScalarField pnf(faceCells.size(), Zero); - AMI.weightedSum - ( - cyclicAMIInterface_.owner(), - work, - pnf, // result - defaultValues - ); + solveScalarField pnf(faceCells.size()); - // Add result using coefficients - this->addToInternalField(result, !add, faceCells, coeffs, pnf); + if (cache.index0() == -1 && cache.index1() == -1) + { + pnf = Zero; + AMI.weightedSum + ( + cyclicAMIInterface_.owner(), + work, + pnf, // result + defaultValues + ); + + // Add result using coefficients + this->addToInternalField(result, !add, faceCells, coeffs, pnf); + } + else + { + cache.setDirection(cyclicAMIInterface_.owner()); + + if (cache.index0() != -1) + { + pnf = Zero; + AMIInterpolation::weightedSum + ( + AMI.lowWeightCorrection(), + cache.cSrcAddress0(), + cache.cSrcWeights0(), + cache.cSrcWeightsSum0(), + work, + opType(plusEqOp()), + pnf, + defaultValues + ); + + pnf *= (1 - cache.weight()); + + // Add result using coefficients + this->addToInternalField(result, !add, faceCells, coeffs, pnf); + } + + if (cache.index1() != -1) + { + pnf = Zero; + AMIInterpolation::weightedSum + ( + AMI.lowWeightCorrection(), + cache.cSrcAddress1(), + cache.cSrcWeights1(), + cache.cSrcWeightsSum1(), + work, + opType(plusEqOp()), + pnf, + defaultValues + ); + + pnf *= cache.weight(); + + // Add result using coefficients + this->addToInternalField(result, !add, faceCells, coeffs, pnf); + } + } } this->updatedMatrix(true); diff --git a/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicAMIGAMGInterfaceField/cyclicAMIGAMGInterfaceField.H b/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicAMIGAMGInterfaceField/cyclicAMIGAMGInterfaceField.H index 5de13c74ae..a7e841e9cb 100644 --- a/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicAMIGAMGInterfaceField/cyclicAMIGAMGInterfaceField.H +++ b/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicAMIGAMGInterfaceField/cyclicAMIGAMGInterfaceField.H @@ -83,6 +83,21 @@ class cyclicAMIGAMGInterfaceField mutable PtrList> scalarRecvBufs_; + // Only used for AMI caching + + //- Current range of send requests (non-blocking) + mutable labelRange sendRequests1_; + + //- Current range of recv requests (non-blocking) + mutable labelRange recvRequests1_; + + //- Scalar send buffers + mutable PtrList> scalarSendBufs1_; + + //- Scalar receive buffers + mutable PtrList> scalarRecvBufs1_; + + // Private Member Functions //- No copy construct diff --git a/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPolyPatch/cyclicAMIPolyPatch.C b/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPolyPatch/cyclicAMIPolyPatch.C index 53a3af8642..7d41d4e21e 100644 --- a/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPolyPatch/cyclicAMIPolyPatch.C +++ b/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPolyPatch/cyclicAMIPolyPatch.C @@ -415,6 +415,8 @@ void Foam::cyclicAMIPolyPatch::resetAMI(const UList& points) const if (returnReduceOr(restoredFromCache, comm)) { // Restored AMI weight and addressing from cache - all done + Info<< "AMI: weights and addresses restored from cache" << endl; + return; } } diff --git a/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPolyPatch/cyclicAMIPolyPatch.H b/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPolyPatch/cyclicAMIPolyPatch.H index 7e4156fdd9..51f660f68e 100644 --- a/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPolyPatch/cyclicAMIPolyPatch.H +++ b/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPolyPatch/cyclicAMIPolyPatch.H @@ -523,9 +523,14 @@ public: ( const Field& fld, labelRange& sendRequests, - PtrList>& sendBuffers, labelRange& recvRequests, - PtrList>& recvBuffers + PtrList>& sendBuffers, + PtrList>& recvBuffers, + + labelRange& sendRequests1, + labelRange& recvRequests1, + PtrList>& sendBuffers1, + PtrList>& recvBuffers1 ) const; template @@ -533,9 +538,14 @@ public: ( const Field& fld, labelRange& sendRequests, - PtrList>& sendBuffers, labelRange& recvRequests, - PtrList>& recvBuffers + PtrList>& sendBuffers, + PtrList>& recvBuffers, + + labelRange& sendRequests1, + labelRange& recvRequests1, + PtrList>& sendBuffers1, + PtrList>& recvBuffers1 ) const; template @@ -544,6 +554,8 @@ public: const Field& localFld, const labelRange& requests, // The receive requests const PtrList>& recvBuffers, + const labelRange& requests1, // The receive requests + const PtrList>& recvBuffers1, const UList& defaultValues ) const; diff --git a/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPolyPatch/cyclicAMIPolyPatchTemplates.C b/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPolyPatch/cyclicAMIPolyPatchTemplates.C index 07ef0fa0bc..74d8a5594b 100644 --- a/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPolyPatch/cyclicAMIPolyPatchTemplates.C +++ b/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPolyPatch/cyclicAMIPolyPatchTemplates.C @@ -63,6 +63,7 @@ Foam::tmp> Foam::cyclicAMIPolyPatch::interpolate if constexpr (transform_supported) { + // Only creates the co-ord system if using periodic AMI cs.reset(cylindricalCS()); } @@ -176,27 +177,73 @@ void Foam::cyclicAMIPolyPatch::initInterpolateUntransformed ( const Field& fld, labelRange& sendRequests, - PtrList>& sendBuffers, labelRange& recvRequests, - PtrList>& recvBuffers + PtrList>& sendBuffers, + PtrList>& recvBuffers, + + labelRange& sendRequests1, + labelRange& recvRequests1, + PtrList>& sendBuffers1, + PtrList>& recvBuffers1 ) const { const auto& AMI = (owner() ? this->AMI() : neighbPatch().AMI()); if (AMI.distributed() && AMI.comm() != -1) { - const auto& map = (owner() ? AMI.tgtMap() : AMI.srcMap()); + const auto& cache = AMI.cache(); - // Insert send/receive requests (non-blocking) - map.send - ( - fld, - sendRequests, - sendBuffers, - recvRequests, - recvBuffers, - 3894+this->index() // unique offset + patch index - ); + if (cache.index0() == -1 && cache.index1() == -1) + { + const auto& map = (owner() ? AMI.tgtMap() : AMI.srcMap()); + + // Insert send/receive requests (non-blocking) + map.send + ( + fld, + sendRequests, + sendBuffers, + recvRequests, + recvBuffers, + 3894+this->index() // unique offset + patch index + ); + } + else + { + cache.setDirection(owner()); + + if (cache.index0() != -1) + { + const auto& map0 = cache.cTgtMapPtr0()(); + + // Insert send/receive requests (non-blocking) + map0.send + ( + fld, + sendRequests, + sendBuffers, + recvRequests, + recvBuffers, + 3894+this->index() // unique offset + patch index + ); + } + + if (cache.index1() != -1) + { + const auto& map1 = cache.cTgtMapPtr1()(); + + // Insert send/receive requests (non-blocking) + map1.send + ( + fld, + sendRequests1, + sendBuffers1, + recvRequests1, + recvBuffers1, + 3895+this->index() // unique offset + patch index + ); + } + } } } @@ -206,9 +253,14 @@ void Foam::cyclicAMIPolyPatch::initInterpolate ( const Field& fld, labelRange& sendRequests, - PtrList>& sendBuffers, labelRange& recvRequests, - PtrList>& recvBuffers + PtrList>& sendBuffers, + PtrList>& recvBuffers, + + labelRange& sendRequests1, + labelRange& recvRequests1, + PtrList>& sendBuffers1, + PtrList>& recvBuffers1 ) const { const auto& AMI = (owner() ? this->AMI() : neighbPatch().AMI()); @@ -221,32 +273,17 @@ void Foam::cyclicAMIPolyPatch::initInterpolate // Can rotate fields (vector and non-spherical tensors) constexpr bool transform_supported = is_rotational_vectorspace_v; - [[maybe_unused]] - autoPtr cs; - if constexpr (transform_supported) - { - cs.reset(cylindricalCS()); - } - - if (!cs) - { - initInterpolateUntransformed - ( - fld, - sendRequests, - sendBuffers, - recvRequests, - recvBuffers - ); - } - else if constexpr (transform_supported) { const cyclicAMIPolyPatch& nbrPp = this->neighbPatch(); Field localFld(fld.size()); - // Transform to cylindrical coords + // Only creates the co-ord system if using periodic AMI + // - convert to cylindrical coordinate system + auto cs = cylindricalCS(); + + if (cs) { const tensorField nbrT(cs().R(nbrPp.faceCentres())); Foam::invTransform(localFld, nbrT, fld); @@ -256,9 +293,30 @@ void Foam::cyclicAMIPolyPatch::initInterpolate ( localFld, sendRequests, - sendBuffers, recvRequests, - recvBuffers + sendBuffers, + recvBuffers, + + sendRequests1, + recvRequests1, + sendBuffers1, + recvBuffers1 + ); + } + else + { + initInterpolateUntransformed + ( + fld, + sendRequests, + recvRequests, + sendBuffers, + recvBuffers, + + sendRequests1, + recvRequests1, + sendBuffers1, + recvBuffers1 ); } } @@ -270,14 +328,19 @@ Foam::tmp> Foam::cyclicAMIPolyPatch::interpolate const Field& localFld, const labelRange& requests, const PtrList>& recvBuffers, + const labelRange& requests1, + const PtrList>& recvBuffers1, const UList& defaultValues ) const { auto tresult = tmp>::New(this->size(), Zero); const auto& AMI = (owner() ? this->AMI() : neighbPatch().AMI()); + const auto& cache = AMI.cache(); + cache.setDirection(owner()); Field work; + Field work1; if (AMI.distributed()) { if (AMI.comm() == -1) @@ -285,71 +348,157 @@ Foam::tmp> Foam::cyclicAMIPolyPatch::interpolate return tresult; } - const auto& map = (owner() ? AMI.tgtMap() : AMI.srcMap()); + if (cache.index0() == -1 && cache.index1() == -1) + { + // No caching + const auto& map = (owner() ? AMI.tgtMap() : AMI.srcMap()); - // Receive (= copy) data from buffers into work. TBD: receive directly - // into slices of work. - map.receive - ( - requests, - recvBuffers, - work, - 3894+this->index() // unique offset + patch index - ); + // Receive (= copy) data from buffers into work. TBD: receive + // directly into slices of work. + map.receive + ( + requests, + recvBuffers, + work, + 3894+this->index() // unique offset + patch index + ); + } + else + { + // Using AMI cache + + if (cache.index0() != -1) + { + cache.cTgtMapPtr0()().receive + ( + requests, + recvBuffers, + work, + 3894+this->index() // unique offset + patch index + ); + } + + if (cache.index1() != -1) + { + cache.cTgtMapPtr1()().receive + ( + requests1, + recvBuffers1, + work1, + 3895+this->index() // unique offset + patch index + ); + } + } } + const Field& fld = (AMI.distributed() ? work : localFld); + const Field& fld1 = (AMI.distributed() ? work1 : localFld); // Rotate fields (vector and non-spherical tensors) constexpr bool transform_supported = is_rotational_vectorspace_v; - [[maybe_unused]] - autoPtr cs; + // Rotate fields (vector and non-spherical tensors) for periodic AMI + tensorField ownTransform; + Field localDeflt; - // Rotate fields (vector and non-spherical tensors) if constexpr (transform_supported) { - cs.reset(cylindricalCS()); - } + // Only creates the co-ord system if using periodic AMI + // - convert to cylindrical coordinate system + auto cs = cylindricalCS(); - if (!cs) - { - AMI.weightedSum - ( - owner(), - fld, - tresult.ref(), - defaultValues - ); - } - else if constexpr (transform_supported) - { - const tensorField ownT(cs().R(this->faceCentres())); - - Field localDeflt(defaultValues.size()); - if (defaultValues.size() == size()) + if (cs) { - // Transform default values into cylindrical coords (using - // *this faceCentres) - // We get in UList (why? Copied from cyclicAMI). Convert to - // Field so we can use transformField routines. - const SubField defaultSubFld(defaultValues); - const Field& defaultFld(defaultSubFld); - Foam::invTransform(localDeflt, ownT, defaultFld); - } + ownTransform = cs().R(this->faceCentres()); + localDeflt = defaultValues; + if (defaultValues.size() == size()) + { + // Transform default values into cylindrical coords (using + // *this faceCentres) + // We get in UList (why? Copied from cyclicAMI). Convert to + // Field so we can use transformField routines. + const SubField defaultSubFld(defaultValues); + const Field& defaultFld(defaultSubFld); + Foam::invTransform(localDeflt, ownTransform, defaultFld); + } + } + } + + const auto& localDefaultValues = + transform_supported ? localDeflt : defaultValues; + + if (cache.index0() == -1 && cache.index1() == -1) + { + // No caching AMI.weightedSum ( owner(), fld, tresult.ref(), - localDeflt + localDefaultValues ); // Transform back - Foam::transform(tresult.ref(), ownT, tresult()); - } + if (ownTransform.size()) + { + Foam::transform(tresult.ref(), ownTransform, tresult()); + } - return tresult; + return tresult; + } + else + { + if (cache.index0() != -1) + { + AMIInterpolation::weightedSum + ( + AMI.lowWeightCorrection(), + cache.cSrcAddress0(), + cache.cSrcWeights0(), + cache.cSrcWeightsSum0(), + fld, + multiplyWeightedOp>(plusEqOp()), + tresult.ref(), + localDefaultValues + ); + + if (ownTransform.size()) + { + Foam::transform(tresult.ref(), ownTransform, tresult()); + } + + // Assuming cache weight is zero when index1 is inactive (==-1) + tresult.ref() *= (1 - cache.weight()); + } + + if (cache.index1() != -1) + { + auto tresult1 = tmp>::New(this->size(), Zero); + + AMIInterpolation::weightedSum + ( + AMI.lowWeightCorrection(), + cache.cSrcAddress1(), + cache.cSrcWeights1(), + cache.cSrcWeightsSum1(), + fld1, + multiplyWeightedOp>(plusEqOp()), + tresult1.ref(), + localDefaultValues + ); + + if (ownTransform.size()) + { + Foam::transform(tresult1.ref(), ownTransform, tresult1()); + } + + tresult1.ref() *= cache.weight(); + tresult.ref() += tresult1(); + } + + return tresult; + } }