diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaceFields/processorGAMGInterfaceField/processorGAMGInterfaceField.C b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaceFields/processorGAMGInterfaceField/processorGAMGInterfaceField.C index e46b8c2d1e9e88d75d43c50c12ed4913398c4269..ef92cb5ac30d4935a3578854cdfb2ede1d4fe85c 100644 --- a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaceFields/processorGAMGInterfaceField/processorGAMGInterfaceField.C +++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaceFields/processorGAMGInterfaceField/processorGAMGInterfaceField.C @@ -109,6 +109,18 @@ Foam::processorGAMGInterfaceField::processorGAMGInterfaceField // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // +bool Foam::processorGAMGInterfaceField::ready() const +{ + const bool ok = UPstream::finishedRequest(recvRequest_); + if (ok) + { + recvRequest_ = -1; + if (UPstream::finishedRequest(sendRequest_)) sendRequest_ = -1; + } + return ok; +} + + void Foam::processorGAMGInterfaceField::initInterfaceMatrixUpdate ( solveScalarField&, diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaceFields/processorGAMGInterfaceField/processorGAMGInterfaceField.H b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaceFields/processorGAMGInterfaceField/processorGAMGInterfaceField.H index c6ae154aef32dc745ef9e152ba70bc50978c0d42..39a52d0e57e9f6123dc4b8c488522594468248f5 100644 --- a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaceFields/processorGAMGInterfaceField/processorGAMGInterfaceField.H +++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaceFields/processorGAMGInterfaceField/processorGAMGInterfaceField.H @@ -162,6 +162,9 @@ public: // Interface matrix update + //- Are all (receive) data available? + virtual bool ready() const; + //- Initialise neighbour matrix update virtual void initInterfaceMatrixUpdate ( diff --git a/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicACMIGAMGInterfaceField/cyclicACMIGAMGInterfaceField.C b/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicACMIGAMGInterfaceField/cyclicACMIGAMGInterfaceField.C index d2a7f16d2576330658948e0f1a66132fa603caf2..02afdbdae6ad35d4392880f4e1741fd858e0d854 100644 --- a/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicACMIGAMGInterfaceField/cyclicACMIGAMGInterfaceField.C +++ b/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicACMIGAMGInterfaceField/cyclicACMIGAMGInterfaceField.C @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2013 OpenFOAM Foundation - Copyright (C) 2019 OpenCFD Ltd. + Copyright (C) 2019,2023 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -67,7 +67,9 @@ Foam::cyclicACMIGAMGInterfaceField::cyclicACMIGAMGInterfaceField GAMGInterfaceField(GAMGCp, fineInterface), cyclicACMIInterface_(refCast<const cyclicACMIGAMGInterface>(GAMGCp)), doTransform_(false), - rank_(0) + rank_(0), + sendRequests_(0), + recvRequests_(0) { const cyclicAMILduInterfaceField& p = refCast<const cyclicAMILduInterfaceField>(fineInterface); @@ -87,7 +89,9 @@ Foam::cyclicACMIGAMGInterfaceField::cyclicACMIGAMGInterfaceField GAMGInterfaceField(GAMGCp, doTransform, rank), cyclicACMIInterface_(refCast<const cyclicACMIGAMGInterface>(GAMGCp)), doTransform_(doTransform), - rank_(rank) + rank_(rank), + sendRequests_(0), + recvRequests_(0) {} @@ -100,7 +104,9 @@ Foam::cyclicACMIGAMGInterfaceField::cyclicACMIGAMGInterfaceField GAMGInterfaceField(GAMGCp, is), cyclicACMIInterface_(refCast<const cyclicACMIGAMGInterface>(GAMGCp)), doTransform_(readBool(is)), - rank_(readLabel(is)) + rank_(readLabel(is)), + sendRequests_(0), + recvRequests_(0) {} @@ -114,7 +120,9 @@ Foam::cyclicACMIGAMGInterfaceField::cyclicACMIGAMGInterfaceField GAMGInterfaceField(GAMGCp, local), cyclicACMIInterface_(refCast<const cyclicACMIGAMGInterface>(GAMGCp)), doTransform_(false), - rank_(0) + rank_(0), + sendRequests_(0), + recvRequests_(0) { const auto& p = refCast<const cyclicACMILduInterfaceField>(local); @@ -123,13 +131,108 @@ Foam::cyclicACMIGAMGInterfaceField::cyclicACMIGAMGInterfaceField } -// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // -Foam::cyclicACMIGAMGInterfaceField::~cyclicACMIGAMGInterfaceField() -{} +bool Foam::cyclicACMIGAMGInterfaceField::ready() const +{ + if + ( + UPstream::finishedRequests + ( + recvRequests_.start(), + recvRequests_.size() + ) + ) + { + recvRequests_.clear(); + if + ( + UPstream::finishedRequests + ( + sendRequests_.start(), + sendRequests_.size() + ) + ) + { + sendRequests_.clear(); + } + + return true; + } + + return false; +} + + +void Foam::cyclicACMIGAMGInterfaceField::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 +{ + const auto& AMI = + ( + cyclicACMIInterface_.owner() + ? cyclicACMIInterface_.AMI() + : cyclicACMIInterface_.neighbPatch().AMI() + ); + + if (AMI.distributed()) + { + DebugPout<< "cyclicACMIFvPatchField::initInterfaceMatrixUpdate() :" + << " interface:" << cyclicACMIInterface_.index() + << " size:" << cyclicACMIInterface_.size() + << " owner:" << cyclicACMIInterface_.owner() + << " AMI distributed:" << AMI.distributed() + << endl; + + // Start sending + if (commsType != UPstream::commsTypes::nonBlocking) + { + FatalErrorInFunction + << "Can only evaluate distributed AMI with nonBlocking" + << exit(FatalError); + } + + // Get neighbouring field + const labelList& nbrFaceCells = + lduAddr.patchAddr(cyclicACMIInterface_.neighbPatchID()); + + solveScalarField pnf(psiInternal, nbrFaceCells); + + // Transform according to the transformation tensors + transformCoupleField(pnf, cmpt); + + const auto& map = + ( + cyclicACMIInterface_.owner() + ? AMI.tgtMap() + : AMI.srcMap() + ); + + // Insert send/receive requests (non-blocking). See e.g. + // cyclicAMIPolyPatchTemplates.C + const label oldWarnComm = UPstream::warnComm; + UPstream::warnComm = AMI.comm(); + map.send + ( + pnf, + sendRequests_, + scalarSendBufs_, + recvRequests_, + scalarRecvBufs_ + ); + UPstream::warnComm = oldWarnComm; + } +} -// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // void Foam::cyclicACMIGAMGInterfaceField::updateInterfaceMatrix ( @@ -143,30 +246,73 @@ void Foam::cyclicACMIGAMGInterfaceField::updateInterfaceMatrix const Pstream::commsTypes ) const { - // Get neighbouring field - const labelList& nbrFaceCells = - lduAddr.patchAddr + const labelUList& faceCells = lduAddr.patchAddr(patchId); + + const auto& AMI = + ( + cyclicACMIInterface_.owner() + ? cyclicACMIInterface_.AMI() + : cyclicACMIInterface_.neighbPatch().AMI() + ); + + DebugPout<< "cyclicACMIGAMGInterfaceField::updateInterfaceMatrix() :" + << " interface:" << cyclicACMIInterface_.index() + << " size:" << cyclicACMIInterface_.size() + << " owner:" << cyclicACMIInterface_.owner() + << " AMI distributed:" << AMI.distributed() + << endl; + + + if (AMI.distributed()) + { + const auto& map = ( - cyclicACMIInterface_.neighbPatchID() + cyclicACMIInterface_.owner() + ? AMI.tgtMap() + : AMI.srcMap() ); - solveScalarField pnf(psiInternal, nbrFaceCells); + // Receive (= copy) data from buffers into work. TBD: receive directly + // into slices of work. + solveScalarField work; + map.receive(recvRequests_, scalarRecvBufs_, work); - // Transform according to the transformation tensors - transformCoupleField(pnf, cmpt); + solveScalarField pnf(faceCells.size(), Zero); + AMI.weightedSum + ( + cyclicACMIInterface_.owner(), + work, + pnf, // result + solveScalarField::null() + ); - if (cyclicACMIInterface_.owner()) - { - pnf = cyclicACMIInterface_.AMI().interpolateToSource(pnf); + // Add result using coefficients + this->addToInternalField(result, !add, faceCells, coeffs, pnf); } else { - pnf = cyclicACMIInterface_.neighbPatch().AMI().interpolateToTarget(pnf); - } + // Get neighbouring field + const labelList& nbrFaceCells = + lduAddr.patchAddr(cyclicACMIInterface_.neighbPatchID()); - const labelUList& faceCells = lduAddr.patchAddr(patchId); + solveScalarField pnf(psiInternal, nbrFaceCells); + + // Transform according to the transformation tensors + transformCoupleField(pnf, cmpt); - this->addToInternalField(result, !add, faceCells, coeffs, pnf); + if (cyclicACMIInterface_.owner()) + { + pnf = AMI.interpolateToSource(pnf); + } + else + { + pnf = AMI.interpolateToTarget(pnf); + } + + const labelUList& faceCells = lduAddr.patchAddr(patchId); + + this->addToInternalField(result, !add, faceCells, coeffs, pnf); + } } diff --git a/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicACMIGAMGInterfaceField/cyclicACMIGAMGInterfaceField.H b/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicACMIGAMGInterfaceField/cyclicACMIGAMGInterfaceField.H index ed3f8b6be860a24c3bc17c75c03070948d80c816..e40687e593e9bcd0e2a4e33a87b6bf1251113b4b 100644 --- a/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicACMIGAMGInterfaceField/cyclicACMIGAMGInterfaceField.H +++ b/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicACMIGAMGInterfaceField/cyclicACMIGAMGInterfaceField.H @@ -69,6 +69,21 @@ class cyclicACMIGAMGInterfaceField int rank_; + // 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_; + + //- Scalar send buffers + mutable PtrList<List<solveScalar>> scalarSendBufs_; + + //- Scalar receive buffers + mutable PtrList<List<solveScalar>> scalarRecvBufs_; + + // Private Member Functions //- No copy construct @@ -139,7 +154,7 @@ public: //- Destructor - virtual ~cyclicACMIGAMGInterfaceField(); + virtual ~cyclicACMIGAMGInterfaceField() = default; // Member Functions @@ -155,6 +170,22 @@ public: // Interface matrix update + //- Are all (receive) data available? + virtual bool ready() const; + + //- 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 ( diff --git a/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicAMIGAMGInterfaceField/cyclicAMIGAMGInterfaceField.C b/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicAMIGAMGInterfaceField/cyclicAMIGAMGInterfaceField.C index 2255bbdac89dd69605f3e300b88a8ad45d778c53..21a7a0ce655190585bd7511f51c6d41bc944d339 100644 --- a/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicAMIGAMGInterfaceField/cyclicAMIGAMGInterfaceField.C +++ b/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicAMIGAMGInterfaceField/cyclicAMIGAMGInterfaceField.C @@ -67,7 +67,9 @@ Foam::cyclicAMIGAMGInterfaceField::cyclicAMIGAMGInterfaceField GAMGInterfaceField(GAMGCp, fineInterface), cyclicAMIInterface_(refCast<const cyclicAMIGAMGInterface>(GAMGCp)), doTransform_(false), - rank_(0) + rank_(0), + sendRequests_(0), + recvRequests_(0) { const cyclicAMILduInterfaceField& p = refCast<const cyclicAMILduInterfaceField>(fineInterface); @@ -87,7 +89,9 @@ Foam::cyclicAMIGAMGInterfaceField::cyclicAMIGAMGInterfaceField GAMGInterfaceField(GAMGCp, doTransform, rank), cyclicAMIInterface_(refCast<const cyclicAMIGAMGInterface>(GAMGCp)), doTransform_(doTransform), - rank_(rank) + rank_(rank), + sendRequests_(0), + recvRequests_(0) {} @@ -100,7 +104,9 @@ Foam::cyclicAMIGAMGInterfaceField::cyclicAMIGAMGInterfaceField GAMGInterfaceField(GAMGCp, is), cyclicAMIInterface_(refCast<const cyclicAMIGAMGInterface>(GAMGCp)), doTransform_(readBool(is)), - rank_(readLabel(is)) + rank_(readLabel(is)), + sendRequests_(0), + recvRequests_(0) {} @@ -114,7 +120,9 @@ Foam::cyclicAMIGAMGInterfaceField::cyclicAMIGAMGInterfaceField GAMGInterfaceField(GAMGCp, local), cyclicAMIInterface_(refCast<const cyclicAMIGAMGInterface>(GAMGCp)), doTransform_(false), - rank_(0) + rank_(0), + sendRequests_(0), // assume no requests in flight for input field + recvRequests_(0) { const auto& p = refCast<const cyclicAMILduInterfaceField>(local); @@ -123,15 +131,41 @@ Foam::cyclicAMIGAMGInterfaceField::cyclicAMIGAMGInterfaceField } -// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // -Foam::cyclicAMIGAMGInterfaceField::~cyclicAMIGAMGInterfaceField() -{} +bool Foam::cyclicAMIGAMGInterfaceField::ready() const +{ + if + ( + UPstream::finishedRequests + ( + recvRequests_.start(), + recvRequests_.size() + ) + ) + { + recvRequests_.clear(); + + if + ( + UPstream::finishedRequests + ( + sendRequests_.start(), + sendRequests_.size() + ) + ) + { + sendRequests_.clear(); + } + + return true; + } + return false; +} -// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // -void Foam::cyclicAMIGAMGInterfaceField::updateInterfaceMatrix +void Foam::cyclicAMIGAMGInterfaceField::initInterfaceMatrixUpdate ( solveScalarField& result, const bool add, @@ -140,50 +174,162 @@ void Foam::cyclicAMIGAMGInterfaceField::updateInterfaceMatrix const solveScalarField& psiInternal, const scalarField& coeffs, const direction cmpt, - const Pstream::commsTypes + const Pstream::commsTypes commsType ) const { - // Get neighbouring field + const auto& AMI = + ( + cyclicAMIInterface_.owner() + ? cyclicAMIInterface_.AMI() + : cyclicAMIInterface_.neighbPatch().AMI() + ); - const label oldWarnComm = UPstream::warnComm; + if (AMI.distributed()) + { + //DebugPout<< "cyclicAMIFvPatchField::initInterfaceMatrixUpdate() :" + // << " interface:" << cyclicAMIInterface_.index() + // << " size:" << cyclicAMIInterface_.size() + // << " owner:" << cyclicAMIInterface_.owner() + // << " AMI distributed:" << AMI.distributed() + // << " AMI low-weight:" << AMI.applyLowWeightCorrection() + // << endl; + + // Start sending + if (commsType != UPstream::commsTypes::nonBlocking) + { + FatalErrorInFunction + << "Can only evaluate distributed AMI with nonBlocking" + << exit(FatalError); + } + + // Get neighbouring field + const labelList& nbrFaceCells = + lduAddr.patchAddr(cyclicAMIInterface_.neighbPatchID()); + + solveScalarField pnf(psiInternal, nbrFaceCells); + + // Transform according to the transformation tensors + transformCoupleField(pnf, cmpt); + + const auto& map = + ( + cyclicAMIInterface_.owner() + ? AMI.tgtMap() + : AMI.srcMap() + ); - const labelList& nbrFaceCells = - lduAddr.patchAddr + // Insert send/receive requests (non-blocking). See e.g. + // cyclicAMIPolyPatchTemplates.C + const label oldWarnComm = UPstream::warnComm; + UPstream::warnComm = AMI.comm(); + map.send ( - cyclicAMIInterface_.neighbPatchID() + pnf, + sendRequests_, + scalarSendBufs_, + recvRequests_, + scalarRecvBufs_ ); + UPstream::warnComm = oldWarnComm; + } +} + + +void Foam::cyclicAMIGAMGInterfaceField::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 +{ + const labelUList& faceCells = lduAddr.patchAddr(patchId); + + const auto& AMI = + ( + cyclicAMIInterface_.owner() + ? cyclicAMIInterface_.AMI() + : cyclicAMIInterface_.neighbPatch().AMI() + ); - solveScalarField pnf(psiInternal, nbrFaceCells); + solveScalarField defaultValues; + if (AMI.applyLowWeightCorrection()) + { + defaultValues = solveScalarField(psiInternal, faceCells); + } - // Transform according to the transformation tensors - transformCoupleField(pnf, cmpt); + //DebugPout<< "cyclicAMIFvPatchField::updateInterfaceMatrix() :" + // << " interface:" << cyclicAMIInterface_.index() + // << " size:" << cyclicAMIInterface_.size() + // << " owner:" << cyclicAMIInterface_.owner() + // << " AMI distributed:" << AMI.distributed() + // << " AMI low-weight:" << AMI.applyLowWeightCorrection() + // << endl; - if (cyclicAMIInterface_.owner()) + if (AMI.distributed()) { - const auto& AMI = cyclicAMIInterface_.AMI(); + if (commsType != UPstream::commsTypes::nonBlocking) + { + FatalErrorInFunction + << "Can only evaluate distributed AMI with nonBlocking" + << exit(FatalError); + } + + const auto& map = + ( + cyclicAMIInterface_.owner() + ? AMI.tgtMap() + : AMI.srcMap() + ); - // Switch on warning if using wrong communicator. Can be removed if - // sure all is correct - UPstream::warnComm = AMI.comm(); + // Receive (= copy) data from buffers into work. TBD: receive directly + // into slices of work. + solveScalarField work; + map.receive(recvRequests_, scalarRecvBufs_, work); - pnf = AMI.interpolateToSource(pnf); + solveScalarField pnf(faceCells.size(), Zero); + AMI.weightedSum + ( + cyclicAMIInterface_.owner(), + work, + pnf, // result + defaultValues + ); + + // Add result using coefficients + this->addToInternalField(result, !add, faceCells, coeffs, pnf); } else { - const auto& AMI = cyclicAMIInterface_.neighbPatch().AMI(); + // Get neighbouring field + const labelList& nbrFaceCells = + lduAddr.patchAddr(cyclicAMIInterface_.neighbPatchID()); + + solveScalarField work(psiInternal, nbrFaceCells); + + // Transform according to the transformation tensors + transformCoupleField(work, cmpt); // Switch on warning if using wrong communicator. Can be removed if // sure all is correct UPstream::warnComm = AMI.comm(); - pnf = AMI.interpolateToTarget(pnf); - } - - const labelUList& faceCells = lduAddr.patchAddr(patchId); - - this->addToInternalField(result, !add, faceCells, coeffs, pnf); + solveScalarField pnf(faceCells.size(), Zero); + AMI.weightedSum + ( + cyclicAMIInterface_.owner(), + work, + pnf, // result + defaultValues + ); - UPstream::warnComm = oldWarnComm; + // Add result using coefficients + this->addToInternalField(result, !add, faceCells, coeffs, pnf); + } } diff --git a/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicAMIGAMGInterfaceField/cyclicAMIGAMGInterfaceField.H b/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicAMIGAMGInterfaceField/cyclicAMIGAMGInterfaceField.H index 52ede77b5a3bda94c18ca0854d1180ee773341ee..5de13c74aef7039c98342eabad910820b514f262 100644 --- a/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicAMIGAMGInterfaceField/cyclicAMIGAMGInterfaceField.H +++ b/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicAMIGAMGInterfaceField/cyclicAMIGAMGInterfaceField.H @@ -68,6 +68,21 @@ class cyclicAMIGAMGInterfaceField int rank_; + // 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_; + + //- Scalar send buffers + mutable PtrList<List<solveScalar>> scalarSendBufs_; + + //- Scalar receive buffers + mutable PtrList<List<solveScalar>> scalarRecvBufs_; + + // Private Member Functions //- No copy construct @@ -138,7 +153,7 @@ public: //- Destructor - virtual ~cyclicAMIGAMGInterfaceField(); + virtual ~cyclicAMIGAMGInterfaceField() = default; // Member Functions @@ -154,6 +169,22 @@ public: // Interface matrix update + //- Are all (receive) data available? + virtual bool ready() const; + + //- 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 ( diff --git a/tutorials/basic/laplacianFoam/implicitAMI-nonblocking/README.txt b/tutorials/basic/laplacianFoam/twoBlocks-processorAgglom/README.txt similarity index 100% rename from tutorials/basic/laplacianFoam/implicitAMI-nonblocking/README.txt rename to tutorials/basic/laplacianFoam/twoBlocks-processorAgglom/README.txt