WIP: AMI caching - updates for parallel operation

This commit is contained in:
Andrew Heather
2025-06-23 11:51:32 +01:00
parent 6392c88f5f
commit f17f2f1123
13 changed files with 982 additions and 298 deletions

View File

@ -227,9 +227,15 @@ bool Foam::cyclicACMIFvPatchField<Type>::all_ready() const
recvRequests_.start(), recvRequests_.start(),
recvRequests_.size() recvRequests_.size()
) )
&& UPstream::finishedRequests
(
recvRequests1_.start(),
recvRequests1_.size()
)
) )
{ {
recvRequests_.clear(); recvRequests_.clear();
recvRequests1_.clear();
++done; ++done;
} }
@ -240,9 +246,15 @@ bool Foam::cyclicACMIFvPatchField<Type>::all_ready() const
sendRequests_.start(), sendRequests_.start(),
sendRequests_.size() sendRequests_.size()
) )
&& UPstream::finishedRequests
(
sendRequests1_.start(),
sendRequests1_.size()
)
) )
{ {
sendRequests_.clear(); sendRequests_.clear();
sendRequests1_.clear();
++done; ++done;
} }
@ -260,9 +272,15 @@ bool Foam::cyclicACMIFvPatchField<Type>::ready() const
recvRequests_.start(), recvRequests_.start(),
recvRequests_.size() recvRequests_.size()
) )
&& UPstream::finishedRequests
(
recvRequests1_.start(),
recvRequests1_.size()
)
) )
{ {
recvRequests_.clear(); recvRequests_.clear();
recvRequests1_.clear();
if if
( (
@ -271,9 +289,15 @@ bool Foam::cyclicACMIFvPatchField<Type>::ready() const
sendRequests_.start(), sendRequests_.start(),
sendRequests_.size() sendRequests_.size()
) )
&& UPstream::finishedRequests
(
sendRequests1_.start(),
sendRequests1_.size()
)
) )
{ {
sendRequests_.clear(); sendRequests_.clear();
sendRequests1_.clear();
} }
return true; return true;
@ -483,7 +507,7 @@ void Foam::cyclicACMIFvPatchField<Type>::initEvaluate
const Field<Type> pnf(this->primitiveField(), nbrFaceCells); const Field<Type> pnf(this->primitiveField(), nbrFaceCells);
// Assert that all receives are known to have finished // Assert that all receives are known to have finished
if (!recvRequests_.empty()) if (!recvRequests_.empty() || !recvRequests1_.empty())
{ {
FatalErrorInFunction FatalErrorInFunction
<< "Outstanding recv request(s) on patch " << "Outstanding recv request(s) on patch "
@ -494,14 +518,20 @@ void Foam::cyclicACMIFvPatchField<Type>::initEvaluate
// Assume that sends are also OK // Assume that sends are also OK
sendRequests_.clear(); sendRequests_.clear();
sendRequests1_.clear();
cyclicACMIPatch_.initInterpolate cyclicACMIPatch_.initInterpolate
( (
pnf, pnf,
sendRequests_, sendRequests_,
sendBufs_,
recvRequests_, recvRequests_,
recvBufs_ sendBufs_,
recvBufs_,
sendRequests1_,
recvRequests1_,
sendBufs1_,
recvBufs1_
); );
} }
} }
@ -547,12 +577,15 @@ void Foam::cyclicACMIFvPatchField<Type>::evaluate
( (
Field<Type>::null(), // Not used for distributed Field<Type>::null(), // Not used for distributed
recvRequests_, recvRequests_,
recvBufs_ recvBufs_,
recvRequests1_,
recvBufs1_
).ptr() ).ptr()
); );
// Receive requests all handled by last function call // Receive requests all handled by last function call
recvRequests_.clear(); recvRequests_.clear();
recvRequests1_.clear();
if (doTransform()) if (doTransform())
{ {
@ -608,7 +641,7 @@ void Foam::cyclicACMIFvPatchField<Type>::initInterfaceMatrixUpdate
transformCoupleField(pnf, cmpt); transformCoupleField(pnf, cmpt);
// Assert that all receives are known to have finished // Assert that all receives are known to have finished
if (!recvRequests_.empty()) if (!recvRequests_.empty() || !recvRequests1_.empty())
{ {
FatalErrorInFunction FatalErrorInFunction
<< "Outstanding recv request(s) on patch " << "Outstanding recv request(s) on patch "
@ -619,14 +652,20 @@ void Foam::cyclicACMIFvPatchField<Type>::initInterfaceMatrixUpdate
// Assume that sends are also OK // Assume that sends are also OK
sendRequests_.clear(); sendRequests_.clear();
sendRequests1_.clear();
cyclicACMIPatch_.initInterpolate cyclicACMIPatch_.initInterpolate
( (
pnf, pnf,
sendRequests_, sendRequests_,
scalarSendBufs_,
recvRequests_, recvRequests_,
scalarRecvBufs_ scalarSendBufs_,
scalarRecvBufs_,
sendRequests1_,
recvRequests1_,
scalarSendBufs1_,
scalarRecvBufs1_
); );
} }
@ -681,11 +720,14 @@ void Foam::cyclicACMIFvPatchField<Type>::updateInterfaceMatrix
( (
solveScalarField::null(), // Not used for distributed solveScalarField::null(), // Not used for distributed
recvRequests_, recvRequests_,
scalarRecvBufs_ scalarRecvBufs_,
recvRequests1_,
scalarRecvBufs1_
); );
// Receive requests all handled by last function call // Receive requests all handled by last function call
recvRequests_.clear(); recvRequests_.clear();
recvRequests1_.clear();
} }
else else
{ {
@ -738,7 +780,7 @@ void Foam::cyclicACMIFvPatchField<Type>::initInterfaceMatrixUpdate
transformCoupleField(pnf); transformCoupleField(pnf);
// Assert that all receives are known to have finished // Assert that all receives are known to have finished
if (!recvRequests_.empty()) if (!recvRequests_.empty() || !recvRequests1_.empty())
{ {
FatalErrorInFunction FatalErrorInFunction
<< "Outstanding recv request(s) on patch " << "Outstanding recv request(s) on patch "
@ -749,14 +791,20 @@ void Foam::cyclicACMIFvPatchField<Type>::initInterfaceMatrixUpdate
// Assume that sends are also OK // Assume that sends are also OK
sendRequests_.clear(); sendRequests_.clear();
sendRequests1_.clear();
cyclicACMIPatch_.initInterpolate cyclicACMIPatch_.initInterpolate
( (
pnf, pnf,
sendRequests_, sendRequests_,
sendBufs_,
recvRequests_, recvRequests_,
recvBufs_ sendBufs_,
recvBufs_,
sendRequests1_,
recvRequests1_,
sendBufs1_,
recvBufs1_
); );
} }
@ -798,11 +846,14 @@ void Foam::cyclicACMIFvPatchField<Type>::updateInterfaceMatrix
( (
Field<Type>::null(), // Not used for distributed Field<Type>::null(), // Not used for distributed
recvRequests_, recvRequests_,
recvBufs_ recvBufs_,
recvRequests1_,
recvBufs1_
); );
// Receive requests all handled by last function call // Receive requests all handled by last function call
recvRequests_.clear(); recvRequests_.clear();
recvRequests1_.clear();
} }
else else
{ {

View File

@ -102,6 +102,28 @@ class cyclicACMIFvPatchField
//- Scalar receive buffers //- Scalar receive buffers
mutable PtrList<List<solveScalar>> scalarRecvBufs_; mutable PtrList<List<solveScalar>> 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<List<Type>> sendBufs1_;
//- Receive buffers_
mutable PtrList<List<Type>> recvBufs1_;
//- Scalar send buffers
mutable PtrList<List<solveScalar>> scalarSendBufs1_;
//- Scalar receive buffers
mutable PtrList<List<solveScalar>> scalarRecvBufs1_;
//- Neighbour coupled internal cell data //- Neighbour coupled internal cell data
mutable autoPtr<Field<Type>> patchNeighbourFieldPtr_; mutable autoPtr<Field<Type>> patchNeighbourFieldPtr_;

View File

@ -207,9 +207,15 @@ bool Foam::cyclicAMIFvPatchField<Type>::all_ready() const
recvRequests_.start(), recvRequests_.start(),
recvRequests_.size() recvRequests_.size()
) )
&& UPstream::finishedRequests
(
recvRequests1_.start(),
recvRequests1_.size()
)
) )
{ {
recvRequests_.clear(); recvRequests_.clear();
recvRequests1_.clear();
++done; ++done;
} }
@ -220,9 +226,15 @@ bool Foam::cyclicAMIFvPatchField<Type>::all_ready() const
sendRequests_.start(), sendRequests_.start(),
sendRequests_.size() sendRequests_.size()
) )
&& UPstream::finishedRequests
(
sendRequests1_.start(),
sendRequests1_.size()
)
) )
{ {
sendRequests_.clear(); sendRequests_.clear();
sendRequests1_.clear();
++done; ++done;
} }
@ -240,9 +252,15 @@ bool Foam::cyclicAMIFvPatchField<Type>::ready() const
recvRequests_.start(), recvRequests_.start(),
recvRequests_.size() recvRequests_.size()
) )
&& UPstream::finishedRequests
(
recvRequests1_.start(),
recvRequests1_.size()
)
) )
{ {
recvRequests_.clear(); recvRequests_.clear();
recvRequests1_.clear();
if if
( (
@ -251,9 +269,15 @@ bool Foam::cyclicAMIFvPatchField<Type>::ready() const
sendRequests_.start(), sendRequests_.start(),
sendRequests_.size() sendRequests_.size()
) )
&& UPstream::finishedRequests
(
sendRequests1_.start(),
sendRequests1_.size()
)
) )
{ {
sendRequests_.clear(); sendRequests_.clear();
sendRequests1_.clear();
} }
return true; return true;
@ -319,8 +343,9 @@ Foam::cyclicAMIFvPatchField<Type>::getNeighbourField
template<class Type> template<class Type>
bool Foam::cyclicAMIFvPatchField<Type>::cacheNeighbourField() bool Foam::cyclicAMIFvPatchField<Type>::cacheNeighbourField() const
{ {
return false;
return (FieldBase::localBoundaryConsistency() != 0); return (FieldBase::localBoundaryConsistency() != 0);
} }
@ -491,7 +516,7 @@ void Foam::cyclicAMIFvPatchField<Type>::initEvaluate
const cyclicAMIPolyPatch& cpp = cyclicAMIPatch_.cyclicAMIPatch(); const cyclicAMIPolyPatch& cpp = cyclicAMIPatch_.cyclicAMIPatch();
// Assert that all receives are known to have finished // Assert that all receives are known to have finished
if (!recvRequests_.empty()) if (!recvRequests_.empty() || !recvRequests1_.empty())
{ {
FatalErrorInFunction FatalErrorInFunction
<< "Outstanding recv request(s) on patch " << "Outstanding recv request(s) on patch "
@ -502,14 +527,20 @@ void Foam::cyclicAMIFvPatchField<Type>::initEvaluate
// Assume that sends are also OK // Assume that sends are also OK
sendRequests_.clear(); sendRequests_.clear();
sendRequests1_.clear();
cpp.initInterpolate cpp.initInterpolate
( (
pnf, pnf,
sendRequests_, sendRequests_,
sendBufs_,
recvRequests_, recvRequests_,
recvBufs_ sendBufs_,
recvBufs_,
sendRequests1_,
recvRequests1_,
sendBufs1_,
recvBufs1_
); );
} }
} }
@ -562,12 +593,15 @@ void Foam::cyclicAMIFvPatchField<Type>::evaluate
Field<Type>::null(), // Not used for distributed Field<Type>::null(), // Not used for distributed
recvRequests_, recvRequests_,
recvBufs_, recvBufs_,
recvRequests1_,
recvBufs1_,
defaultValues defaultValues
).ptr() ).ptr()
); );
// Receive requests all handled by last function call // Receive requests all handled by last function call
recvRequests_.clear(); recvRequests_.clear();
recvRequests1_.clear();
if (doTransform()) if (doTransform())
{ {
@ -618,7 +652,7 @@ void Foam::cyclicAMIFvPatchField<Type>::initInterfaceMatrixUpdate
const cyclicAMIPolyPatch& cpp = cyclicAMIPatch_.cyclicAMIPatch(); const cyclicAMIPolyPatch& cpp = cyclicAMIPatch_.cyclicAMIPatch();
// Assert that all receives are known to have finished // Assert that all receives are known to have finished
if (!recvRequests_.empty()) if (!recvRequests_.empty() || !recvRequests1_.empty())
{ {
FatalErrorInFunction FatalErrorInFunction
<< "Outstanding recv request(s) on patch " << "Outstanding recv request(s) on patch "
@ -629,14 +663,20 @@ void Foam::cyclicAMIFvPatchField<Type>::initInterfaceMatrixUpdate
// Assume that sends are also OK // Assume that sends are also OK
sendRequests_.clear(); sendRequests_.clear();
sendRequests1_.clear();
cpp.initInterpolate cpp.initInterpolate
( (
pnf, pnf,
sendRequests_, sendRequests_,
scalarSendBufs_,
recvRequests_, recvRequests_,
scalarRecvBufs_ scalarSendBufs_,
scalarRecvBufs_,
sendRequests1_,
recvRequests1_,
scalarSendBufs1_,
scalarRecvBufs1_
); );
} }
@ -691,11 +731,14 @@ void Foam::cyclicAMIFvPatchField<Type>::updateInterfaceMatrix
solveScalarField::null(), // Not used for distributed solveScalarField::null(), // Not used for distributed
recvRequests_, recvRequests_,
scalarRecvBufs_, scalarRecvBufs_,
recvRequests1_,
scalarRecvBufs1_,
defaultValues defaultValues
); );
// Receive requests all handled by last function call // Receive requests all handled by last function call
recvRequests_.clear(); recvRequests_.clear();
recvRequests1_.clear();
} }
else else
{ {
@ -757,7 +800,7 @@ void Foam::cyclicAMIFvPatchField<Type>::initInterfaceMatrixUpdate
const cyclicAMIPolyPatch& cpp = cyclicAMIPatch_.cyclicAMIPatch(); const cyclicAMIPolyPatch& cpp = cyclicAMIPatch_.cyclicAMIPatch();
// Assert that all receives are known to have finished // Assert that all receives are known to have finished
if (!recvRequests_.empty()) if (!recvRequests_.empty() || !recvRequests1_.empty())
{ {
FatalErrorInFunction FatalErrorInFunction
<< "Outstanding recv request(s) on patch " << "Outstanding recv request(s) on patch "
@ -768,14 +811,20 @@ void Foam::cyclicAMIFvPatchField<Type>::initInterfaceMatrixUpdate
// Assume that sends are also OK // Assume that sends are also OK
sendRequests_.clear(); sendRequests_.clear();
sendRequests1_.clear();
cpp.initInterpolate cpp.initInterpolate
( (
pnf, pnf,
sendRequests_, sendRequests_,
sendBufs_,
recvRequests_, recvRequests_,
recvBufs_ sendBufs_,
recvBufs_,
sendRequests1_,
recvRequests1_,
sendBufs1_,
recvBufs1_
); );
} }
@ -829,11 +878,14 @@ void Foam::cyclicAMIFvPatchField<Type>::updateInterfaceMatrix
Field<Type>::null(), // Not used for distributed Field<Type>::null(), // Not used for distributed
recvRequests_, recvRequests_,
recvBufs_, recvBufs_,
recvRequests1_,
recvBufs1_,
defaultValues defaultValues
); );
// Receive requests all handled by last function call // Receive requests all handled by last function call
recvRequests_.clear(); recvRequests_.clear();
recvRequests1_.clear();
} }
else else
{ {
@ -918,7 +970,7 @@ void Foam::cyclicAMIFvPatchField<Type>::manipulateMatrix
} }
// Set internalCoeffs and boundaryCoeffs in the assembly matrix // 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() // matrix.flux()
if (matrix.psi(mat).mesh().fluxRequired(this->internalField().name())) if (matrix.psi(mat).mesh().fluxRequired(this->internalField().name()))
{ {

View File

@ -113,6 +113,28 @@ class cyclicAMIFvPatchField
//- Scalar receive buffers //- Scalar receive buffers
mutable PtrList<List<solveScalar>> scalarRecvBufs_; mutable PtrList<List<solveScalar>> 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<List<Type>> sendBufs1_;
//- Receive buffers_
mutable PtrList<List<Type>> recvBufs1_;
//- Scalar send buffers
mutable PtrList<List<solveScalar>> scalarSendBufs1_;
//- Scalar receive buffers
mutable PtrList<List<solveScalar>> scalarRecvBufs1_;
//- Neighbour coupled internal cell data //- Neighbour coupled internal cell data
mutable autoPtr<Field<Type>> patchNeighbourFieldPtr_; mutable autoPtr<Field<Type>> patchNeighbourFieldPtr_;
@ -134,7 +156,7 @@ class cyclicAMIFvPatchField
virtual bool all_ready() const; virtual bool all_ready() const;
//- Use neighbour field caching //- Use neighbour field caching
static bool cacheNeighbourField(); bool cacheNeighbourField() const;
//- Return neighbour coupled internal cell data //- Return neighbour coupled internal cell data
tmp<Field<Type>> getNeighbourField(const UList<Type>&) const; tmp<Field<Type>> getNeighbourField(const UList<Type>&) const;

View File

@ -220,9 +220,14 @@ public:
( (
const Field<Type>& fld, const Field<Type>& fld,
labelRange& sendRequests, labelRange& sendRequests,
PtrList<List<Type>>& sendBuffers,
labelRange& recvRequests, labelRange& recvRequests,
PtrList<List<Type>>& recvBuffers PtrList<List<Type>>& sendBuffers,
PtrList<List<Type>>& recvBuffers,
labelRange& sendRequests1,
labelRange& recvRequests1,
PtrList<List<Type>>& sendBuffers1,
PtrList<List<Type>>& recvBuffers1
) const ) const
{ {
// Make sure areas are up-to-date // Make sure areas are up-to-date
@ -232,9 +237,14 @@ public:
( (
fld, fld,
sendRequests, sendRequests,
sendBuffers,
recvRequests, recvRequests,
recvBuffers sendBuffers,
recvBuffers,
sendRequests1,
recvRequests1,
sendBuffers1,
recvBuffers1
); );
} }
@ -243,7 +253,9 @@ public:
( (
const Field<Type>& localFld, const Field<Type>& localFld,
const labelRange& requests, // The receive requests const labelRange& requests, // The receive requests
const PtrList<List<Type>>& recvBuffers const PtrList<List<Type>>& recvBuffers,
const labelRange& requests1, // The receive requests
const PtrList<List<Type>>& recvBuffers1
) const ) const
{ {
return cyclicACMIPolyPatch_.interpolate return cyclicACMIPolyPatch_.interpolate
@ -251,6 +263,8 @@ public:
localFld, localFld,
requests, requests,
recvBuffers, recvBuffers,
requests1,
recvBuffers1,
UList<Type>() UList<Type>()
); );
} }

View File

@ -89,37 +89,18 @@ void Foam::AMIInterpolation::weightedSum
const UList<Type>& defaultValues const UList<Type>& defaultValues
) const ) const
{ {
cache_.setDirection(toSource); // Note: using non-caching AMI
weightedSum
const auto wsum = [&](List<Type>& res, const label i){ (
weightedSum lowWeightCorrection_,
( (toSource ? srcAddress_ : tgtAddress_),
lowWeightCorrection_, (toSource ? srcWeights_ : tgtWeights_),
cache_.cSrcAddress(i), (toSource ? srcWeightsSum_ : tgtWeightsSum_),
cache_.cSrcWeights(i), fld,
cache_.cSrcWeightsSum(i), multiplyWeightedOp<Type, plusEqOp<Type>>(plusEqOp<Type>()),
fld, result,
multiplyWeightedOp<Type, plusEqOp<Type>>(plusEqOp<Type>()), defaultValues
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<Type, plusEqOp<Type>>(plusEqOp<Type>()),
result,
defaultValues
);
}
} }
@ -208,7 +189,11 @@ void Foam::AMIInterpolation::interpolate
map.distribute(work); map.distribute(work);
} }
result0.resize_nocopy(srcAddress.size()); if constexpr (is_contiguous_scalar<Type>::value)
{
result0 = Zero;
}
weightedSum weightedSum
( (
lowWeightCorrection_, lowWeightCorrection_,
@ -248,7 +233,11 @@ void Foam::AMIInterpolation::interpolate
map.distribute(work); map.distribute(work);
} }
result1.resize_nocopy(srcAddress.size()); if constexpr (is_contiguous_scalar<Type>::value)
{
result1 = Zero;
}
weightedSum weightedSum
( (
lowWeightCorrection_, lowWeightCorrection_,
@ -309,6 +298,12 @@ void Foam::AMIInterpolation::interpolate
} }
result.resize_nocopy(srcAddress.size()); result.resize_nocopy(srcAddress.size());
if constexpr (is_contiguous_scalar<Type>::value)
{
result = Zero;
}
weightedSum weightedSum
( (
lowWeightCorrection_, lowWeightCorrection_,

View File

@ -67,9 +67,7 @@ Foam::cyclicACMIGAMGInterfaceField::cyclicACMIGAMGInterfaceField
GAMGInterfaceField(GAMGCp, fineInterface), GAMGInterfaceField(GAMGCp, fineInterface),
cyclicACMIInterface_(refCast<const cyclicACMIGAMGInterface>(GAMGCp)), cyclicACMIInterface_(refCast<const cyclicACMIGAMGInterface>(GAMGCp)),
doTransform_(false), doTransform_(false),
rank_(0), rank_(0)
sendRequests_(),
recvRequests_()
{ {
const cyclicAMILduInterfaceField& p = const cyclicAMILduInterfaceField& p =
refCast<const cyclicAMILduInterfaceField>(fineInterface); refCast<const cyclicAMILduInterfaceField>(fineInterface);
@ -89,9 +87,7 @@ Foam::cyclicACMIGAMGInterfaceField::cyclicACMIGAMGInterfaceField
GAMGInterfaceField(GAMGCp, doTransform, rank), GAMGInterfaceField(GAMGCp, doTransform, rank),
cyclicACMIInterface_(refCast<const cyclicACMIGAMGInterface>(GAMGCp)), cyclicACMIInterface_(refCast<const cyclicACMIGAMGInterface>(GAMGCp)),
doTransform_(doTransform), doTransform_(doTransform),
rank_(rank), rank_(rank)
sendRequests_(),
recvRequests_()
{} {}
@ -104,9 +100,7 @@ Foam::cyclicACMIGAMGInterfaceField::cyclicACMIGAMGInterfaceField
GAMGInterfaceField(GAMGCp, is), GAMGInterfaceField(GAMGCp, is),
cyclicACMIInterface_(refCast<const cyclicACMIGAMGInterface>(GAMGCp)), cyclicACMIInterface_(refCast<const cyclicACMIGAMGInterface>(GAMGCp)),
doTransform_(readBool(is)), doTransform_(readBool(is)),
rank_(readLabel(is)), rank_(readLabel(is))
sendRequests_(),
recvRequests_()
{} {}
@ -120,9 +114,7 @@ Foam::cyclicACMIGAMGInterfaceField::cyclicACMIGAMGInterfaceField
GAMGInterfaceField(GAMGCp, local), GAMGInterfaceField(GAMGCp, local),
cyclicACMIInterface_(refCast<const cyclicACMIGAMGInterface>(GAMGCp)), cyclicACMIInterface_(refCast<const cyclicACMIGAMGInterface>(GAMGCp)),
doTransform_(false), doTransform_(false),
rank_(0), rank_(0)
sendRequests_(),
recvRequests_()
{ {
const auto& p = refCast<const cyclicACMILduInterfaceField>(local); const auto& p = refCast<const cyclicACMILduInterfaceField>(local);
@ -142,9 +134,15 @@ bool Foam::cyclicACMIGAMGInterfaceField::ready() const
recvRequests_.start(), recvRequests_.start(),
recvRequests_.size() recvRequests_.size()
) )
&& UPstream::finishedRequests
(
recvRequests1_.start(),
recvRequests1_.size()
)
) )
{ {
recvRequests_.clear(); recvRequests_.clear();
recvRequests1_.clear();
if if
( (
@ -153,9 +151,15 @@ bool Foam::cyclicACMIGAMGInterfaceField::ready() const
sendRequests_.start(), sendRequests_.start(),
sendRequests_.size() sendRequests_.size()
) )
&& UPstream::finishedRequests
(
sendRequests1_.start(),
sendRequests1_.size()
)
) )
{ {
sendRequests_.clear(); sendRequests_.clear();
sendRequests1_.clear();
} }
return true; return true;
@ -210,15 +214,9 @@ void Foam::cyclicACMIGAMGInterfaceField::initInterfaceMatrixUpdate
// Transform according to the transformation tensors // Transform according to the transformation tensors
transformCoupleField(pnf, cmpt); transformCoupleField(pnf, cmpt);
const auto& map =
(
cyclicACMIInterface_.owner()
? AMI.tgtMap()
: AMI.srcMap()
);
// Assert that all receives are known to have finished // Assert that all receives are known to have finished
if (!recvRequests_.empty()) if (!recvRequests_.empty() || !recvRequests1_.empty())
{ {
FatalErrorInFunction FatalErrorInFunction
<< "Outstanding recv request(s) on patch " << "Outstanding recv request(s) on patch "
@ -226,22 +224,63 @@ void Foam::cyclicACMIGAMGInterfaceField::initInterfaceMatrixUpdate
<< abort(FatalError); << abort(FatalError);
} }
// Assume that sends are also OK const auto& cache = AMI.cache();
sendRequests_.clear();
// Insert send/receive requests (non-blocking). See e.g. if (cache.index0() == -1 && cache.index1() == -1)
// cyclicAMIPolyPatchTemplates.C {
const label oldWarnComm = UPstream::commWarn(AMI.comm()); const auto& map =
map.send (
( cyclicACMIInterface_.owner()
pnf, ? AMI.tgtMap()
sendRequests_, : AMI.srcMap()
scalarSendBufs_, );
recvRequests_,
scalarRecvBufs_, // Insert send/receive requests (non-blocking). See e.g.
19462+cyclicACMIInterface_.index() // unique offset + patch index // cyclicAMIPolyPatchTemplates.C
); const label oldWarnComm = UPstream::commWarn(AMI.comm());
UPstream::commWarn(oldWarnComm); 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); this->updatedMatrix(false);
@ -260,6 +299,8 @@ void Foam::cyclicACMIGAMGInterfaceField::updateInterfaceMatrix
const Pstream::commsTypes const Pstream::commsTypes
) const ) const
{ {
typedef multiplyWeightedOp<scalar, plusEqOp<scalar>> opType;
const labelUList& faceCells = lduAddr.patchAddr(patchId); const labelUList& faceCells = lduAddr.patchAddr(patchId);
const auto& AMI = const auto& AMI =
@ -269,48 +310,122 @@ void Foam::cyclicACMIGAMGInterfaceField::updateInterfaceMatrix
: cyclicACMIInterface_.neighbPatch().AMI() : cyclicACMIInterface_.neighbPatch().AMI()
); );
DebugPout<< "cyclicACMIGAMGInterfaceField::updateInterfaceMatrix() :" const auto& cache = AMI.cache();
<< " interface:" << cyclicACMIInterface_.index()
<< " size:" << cyclicACMIInterface_.size()
<< " owner:" << cyclicACMIInterface_.owner()
<< " AMI distributed:" << AMI.distributed()
<< endl;
if (AMI.distributed() && AMI.comm() != -1) if (AMI.distributed() && AMI.comm() != -1)
{ {
const auto& map = if (cache.index0() == -1 && cache.index1() == -1)
( {
cyclicACMIInterface_.owner() const auto& map =
? AMI.tgtMap() (
: AMI.srcMap() cyclicACMIInterface_.owner()
); ? AMI.tgtMap()
: AMI.srcMap()
);
// Receive (= copy) data from buffers into work. TBD: receive directly // Receive (= copy) data from buffers into work. TBD: receive directly
// into slices of work. // into slices of work.
solveScalarField work; solveScalarField work;
map.receive map.receive
( (
recvRequests_, recvRequests_,
scalarRecvBufs_, scalarRecvBufs_,
work, work,
19462+cyclicACMIInterface_.index() // unique offset + patch index 19462+cyclicACMIInterface_.index() // unique offset + patch index
); );
// Receive requests all handled by last function call // Receive requests all handled by last function call
recvRequests_.clear(); recvRequests_.clear();
solveScalarField pnf(faceCells.size(), Zero); solveScalarField pnf(faceCells.size(), Zero);
AMI.weightedSum AMI.weightedSum
( (
cyclicACMIInterface_.owner(), cyclicACMIInterface_.owner(),
work, work,
pnf, // result pnf, // result
solveScalarField::null() solveScalarField::null()
); );
// Add result using coefficients // Add result using coefficients
this->addToInternalField(result, !add, faceCells, coeffs, pnf); 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<scalar>()),
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<scalar>()),
pnf,
solveScalarField::null()
);
pnf *= cache.weight();
// Add result using coefficients
this->addToInternalField(result, !add, faceCells, coeffs, pnf);
}
}
} }
else else
{ {
@ -318,23 +433,72 @@ void Foam::cyclicACMIGAMGInterfaceField::updateInterfaceMatrix
const labelUList& nbrFaceCells = const labelUList& nbrFaceCells =
lduAddr.patchAddr(cyclicACMIInterface_.neighbPatchID()); lduAddr.patchAddr(cyclicACMIInterface_.neighbPatchID());
solveScalarField pnf(psiInternal, nbrFaceCells); solveScalarField work(psiInternal, nbrFaceCells);
// Transform according to the transformation tensors // 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 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<scalar>()),
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<scalar>()),
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); this->updatedMatrix(true);

View File

@ -83,6 +83,20 @@ class cyclicACMIGAMGInterfaceField
//- Scalar receive buffers //- Scalar receive buffers
mutable PtrList<List<solveScalar>> scalarRecvBufs_; mutable PtrList<List<solveScalar>> 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<List<solveScalar>> scalarSendBufs1_;
//- Scalar receive buffers
mutable PtrList<List<solveScalar>> scalarRecvBufs1_;
// Private Member Functions // Private Member Functions

View File

@ -67,9 +67,7 @@ Foam::cyclicAMIGAMGInterfaceField::cyclicAMIGAMGInterfaceField
GAMGInterfaceField(GAMGCp, fineInterface), GAMGInterfaceField(GAMGCp, fineInterface),
cyclicAMIInterface_(refCast<const cyclicAMIGAMGInterface>(GAMGCp)), cyclicAMIInterface_(refCast<const cyclicAMIGAMGInterface>(GAMGCp)),
doTransform_(false), doTransform_(false),
rank_(0), rank_(0)
sendRequests_(),
recvRequests_()
{ {
const cyclicAMILduInterfaceField& p = const cyclicAMILduInterfaceField& p =
refCast<const cyclicAMILduInterfaceField>(fineInterface); refCast<const cyclicAMILduInterfaceField>(fineInterface);
@ -89,9 +87,7 @@ Foam::cyclicAMIGAMGInterfaceField::cyclicAMIGAMGInterfaceField
GAMGInterfaceField(GAMGCp, doTransform, rank), GAMGInterfaceField(GAMGCp, doTransform, rank),
cyclicAMIInterface_(refCast<const cyclicAMIGAMGInterface>(GAMGCp)), cyclicAMIInterface_(refCast<const cyclicAMIGAMGInterface>(GAMGCp)),
doTransform_(doTransform), doTransform_(doTransform),
rank_(rank), rank_(rank)
sendRequests_(),
recvRequests_()
{} {}
@ -104,9 +100,7 @@ Foam::cyclicAMIGAMGInterfaceField::cyclicAMIGAMGInterfaceField
GAMGInterfaceField(GAMGCp, is), GAMGInterfaceField(GAMGCp, is),
cyclicAMIInterface_(refCast<const cyclicAMIGAMGInterface>(GAMGCp)), cyclicAMIInterface_(refCast<const cyclicAMIGAMGInterface>(GAMGCp)),
doTransform_(readBool(is)), doTransform_(readBool(is)),
rank_(readLabel(is)), rank_(readLabel(is))
sendRequests_(),
recvRequests_()
{} {}
@ -120,9 +114,7 @@ Foam::cyclicAMIGAMGInterfaceField::cyclicAMIGAMGInterfaceField
GAMGInterfaceField(GAMGCp, local), GAMGInterfaceField(GAMGCp, local),
cyclicAMIInterface_(refCast<const cyclicAMIGAMGInterface>(GAMGCp)), cyclicAMIInterface_(refCast<const cyclicAMIGAMGInterface>(GAMGCp)),
doTransform_(false), doTransform_(false),
rank_(0), rank_(0)
sendRequests_(), // assume no requests in flight for input field
recvRequests_()
{ {
const auto& p = refCast<const cyclicAMILduInterfaceField>(local); const auto& p = refCast<const cyclicAMILduInterfaceField>(local);
@ -142,9 +134,15 @@ bool Foam::cyclicAMIGAMGInterfaceField::ready() const
recvRequests_.start(), recvRequests_.start(),
recvRequests_.size() recvRequests_.size()
) )
&& UPstream::finishedRequests
(
recvRequests1_.start(),
recvRequests1_.size()
)
) )
{ {
recvRequests_.clear(); recvRequests_.clear();
recvRequests1_.clear();
if if
( (
@ -153,9 +151,15 @@ bool Foam::cyclicAMIGAMGInterfaceField::ready() const
sendRequests_.start(), sendRequests_.start(),
sendRequests_.size() sendRequests_.size()
) )
&& UPstream::finishedRequests
(
sendRequests1_.start(),
sendRequests1_.size()
)
) )
{ {
sendRequests_.clear(); sendRequests_.clear();
sendRequests1_.clear();
} }
return true; return true;
@ -183,7 +187,6 @@ void Foam::cyclicAMIGAMGInterfaceField::initInterfaceMatrixUpdate
? cyclicAMIInterface_.AMI() ? cyclicAMIInterface_.AMI()
: cyclicAMIInterface_.neighbPatch().AMI() : cyclicAMIInterface_.neighbPatch().AMI()
); );
if (AMI.distributed() && AMI.comm() != -1) if (AMI.distributed() && AMI.comm() != -1)
{ {
//DebugPout<< "cyclicAMIFvPatchField::initInterfaceMatrixUpdate() :" //DebugPout<< "cyclicAMIFvPatchField::initInterfaceMatrixUpdate() :"
@ -211,15 +214,8 @@ void Foam::cyclicAMIGAMGInterfaceField::initInterfaceMatrixUpdate
// Transform according to the transformation tensors // Transform according to the transformation tensors
transformCoupleField(pnf, cmpt); transformCoupleField(pnf, cmpt);
const auto& map =
(
cyclicAMIInterface_.owner()
? AMI.tgtMap()
: AMI.srcMap()
);
// Assert that all receives are known to have finished // Assert that all receives are known to have finished
if (!recvRequests_.empty()) if (!recvRequests_.empty() || !recvRequests1_.empty())
{ {
FatalErrorInFunction FatalErrorInFunction
<< "Outstanding recv request(s) on patch " << "Outstanding recv request(s) on patch "
@ -227,22 +223,63 @@ void Foam::cyclicAMIGAMGInterfaceField::initInterfaceMatrixUpdate
<< abort(FatalError); << abort(FatalError);
} }
// Assume that sends are also OK const auto& cache = AMI.cache();
sendRequests_.clear();
// Insert send/receive requests (non-blocking). See e.g. if (cache.index0() == -1 && cache.index1() == -1)
// cyclicAMIPolyPatchTemplates.C {
const label oldWarnComm = UPstream::commWarn(AMI.comm()); const auto& map =
map.send (
( cyclicAMIInterface_.owner()
pnf, ? AMI.tgtMap()
sendRequests_, : AMI.srcMap()
scalarSendBufs_, );
recvRequests_,
scalarRecvBufs_, // Insert send/receive requests (non-blocking). See e.g.
19462+cyclicAMIInterface_.index() // unique offset + patch index // cyclicAMIPolyPatchTemplates.C
); const label oldWarnComm = UPstream::commWarn(AMI.comm());
UPstream::commWarn(oldWarnComm); 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); this->updatedMatrix(false);
@ -261,6 +298,8 @@ void Foam::cyclicAMIGAMGInterfaceField::updateInterfaceMatrix
const Pstream::commsTypes commsType const Pstream::commsTypes commsType
) const ) const
{ {
typedef multiplyWeightedOp<scalar, plusEqOp<scalar>> opType;
const labelUList& faceCells = lduAddr.patchAddr(patchId); const labelUList& faceCells = lduAddr.patchAddr(patchId);
const auto& AMI = const auto& AMI =
@ -284,6 +323,8 @@ void Foam::cyclicAMIGAMGInterfaceField::updateInterfaceMatrix
// << " AMI low-weight:" << AMI.applyLowWeightCorrection() // << " AMI low-weight:" << AMI.applyLowWeightCorrection()
// << endl; // << endl;
const auto& cache = AMI.cache();
if (AMI.distributed() && AMI.comm() != -1) if (AMI.distributed() && AMI.comm() != -1)
{ {
if (commsType != UPstream::commsTypes::nonBlocking) if (commsType != UPstream::commsTypes::nonBlocking)
@ -293,38 +334,118 @@ void Foam::cyclicAMIGAMGInterfaceField::updateInterfaceMatrix
<< exit(FatalError); << exit(FatalError);
} }
const auto& map = if (cache.index0() == -1 && cache.index1() == -1)
( {
cyclicAMIInterface_.owner() const auto& map =
? AMI.tgtMap() (
: AMI.srcMap() cyclicAMIInterface_.owner()
); ? AMI.tgtMap()
: AMI.srcMap()
);
// Receive (= copy) data from buffers into work. TBD: receive directly // Receive (= copy) data from buffers into work. TBD: receive directly
// into slices of work. // into slices of work.
solveScalarField work; solveScalarField work;
map.receive map.receive
( (
recvRequests_, recvRequests_,
scalarRecvBufs_, scalarRecvBufs_,
work, work,
19462+cyclicAMIInterface_.index() // unique offset + patch index 19462+cyclicAMIInterface_.index() // unique offset + patch index
); );
// Receive requests all handled by last function call // Receive requests all handled by last function call
recvRequests_.clear(); recvRequests_.clear();
solveScalarField pnf(faceCells.size(), Zero); solveScalarField pnf(faceCells.size(), Zero);
AMI.weightedSum AMI.weightedSum
( (
cyclicAMIInterface_.owner(), cyclicAMIInterface_.owner(),
work, work,
pnf, // result pnf, // result
defaultValues defaultValues
); );
// Add result using coefficients // Add result using coefficients
this->addToInternalField(result, !add, faceCells, coeffs, pnf); 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<scalar>()),
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<scalar>()),
pnf,
defaultValues
);
pnf *= cache.weight();
// Add result using coefficients
this->addToInternalField(result, !add, faceCells, coeffs, pnf);
}
}
} }
else else
{ {
@ -337,17 +458,68 @@ void Foam::cyclicAMIGAMGInterfaceField::updateInterfaceMatrix
// Transform according to the transformation tensors // Transform according to the transformation tensors
transformCoupleField(work, cmpt); transformCoupleField(work, cmpt);
solveScalarField pnf(faceCells.size(), Zero); solveScalarField pnf(faceCells.size());
AMI.weightedSum
(
cyclicAMIInterface_.owner(),
work,
pnf, // result
defaultValues
);
// Add result using coefficients if (cache.index0() == -1 && cache.index1() == -1)
this->addToInternalField(result, !add, faceCells, coeffs, pnf); {
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<scalar>()),
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<scalar>()),
pnf,
defaultValues
);
pnf *= cache.weight();
// Add result using coefficients
this->addToInternalField(result, !add, faceCells, coeffs, pnf);
}
}
} }
this->updatedMatrix(true); this->updatedMatrix(true);

View File

@ -83,6 +83,21 @@ class cyclicAMIGAMGInterfaceField
mutable PtrList<List<solveScalar>> scalarRecvBufs_; mutable PtrList<List<solveScalar>> 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<List<solveScalar>> scalarSendBufs1_;
//- Scalar receive buffers
mutable PtrList<List<solveScalar>> scalarRecvBufs1_;
// Private Member Functions // Private Member Functions
//- No copy construct //- No copy construct

View File

@ -415,6 +415,8 @@ void Foam::cyclicAMIPolyPatch::resetAMI(const UList<point>& points) const
if (returnReduceOr(restoredFromCache, comm)) if (returnReduceOr(restoredFromCache, comm))
{ {
// Restored AMI weight and addressing from cache - all done // Restored AMI weight and addressing from cache - all done
Info<< "AMI: weights and addresses restored from cache" << endl;
return; return;
} }
} }

View File

@ -523,9 +523,14 @@ public:
( (
const Field<Type>& fld, const Field<Type>& fld,
labelRange& sendRequests, labelRange& sendRequests,
PtrList<List<Type>>& sendBuffers,
labelRange& recvRequests, labelRange& recvRequests,
PtrList<List<Type>>& recvBuffers PtrList<List<Type>>& sendBuffers,
PtrList<List<Type>>& recvBuffers,
labelRange& sendRequests1,
labelRange& recvRequests1,
PtrList<List<Type>>& sendBuffers1,
PtrList<List<Type>>& recvBuffers1
) const; ) const;
template<class Type> template<class Type>
@ -533,9 +538,14 @@ public:
( (
const Field<Type>& fld, const Field<Type>& fld,
labelRange& sendRequests, labelRange& sendRequests,
PtrList<List<Type>>& sendBuffers,
labelRange& recvRequests, labelRange& recvRequests,
PtrList<List<Type>>& recvBuffers PtrList<List<Type>>& sendBuffers,
PtrList<List<Type>>& recvBuffers,
labelRange& sendRequests1,
labelRange& recvRequests1,
PtrList<List<Type>>& sendBuffers1,
PtrList<List<Type>>& recvBuffers1
) const; ) const;
template<class Type> template<class Type>
@ -544,6 +554,8 @@ public:
const Field<Type>& localFld, const Field<Type>& localFld,
const labelRange& requests, // The receive requests const labelRange& requests, // The receive requests
const PtrList<List<Type>>& recvBuffers, const PtrList<List<Type>>& recvBuffers,
const labelRange& requests1, // The receive requests
const PtrList<List<Type>>& recvBuffers1,
const UList<Type>& defaultValues const UList<Type>& defaultValues
) const; ) const;

View File

@ -63,6 +63,7 @@ Foam::tmp<Foam::Field<Type>> Foam::cyclicAMIPolyPatch::interpolate
if constexpr (transform_supported) if constexpr (transform_supported)
{ {
// Only creates the co-ord system if using periodic AMI
cs.reset(cylindricalCS()); cs.reset(cylindricalCS());
} }
@ -176,27 +177,73 @@ void Foam::cyclicAMIPolyPatch::initInterpolateUntransformed
( (
const Field<Type>& fld, const Field<Type>& fld,
labelRange& sendRequests, labelRange& sendRequests,
PtrList<List<Type>>& sendBuffers,
labelRange& recvRequests, labelRange& recvRequests,
PtrList<List<Type>>& recvBuffers PtrList<List<Type>>& sendBuffers,
PtrList<List<Type>>& recvBuffers,
labelRange& sendRequests1,
labelRange& recvRequests1,
PtrList<List<Type>>& sendBuffers1,
PtrList<List<Type>>& recvBuffers1
) const ) const
{ {
const auto& AMI = (owner() ? this->AMI() : neighbPatch().AMI()); const auto& AMI = (owner() ? this->AMI() : neighbPatch().AMI());
if (AMI.distributed() && AMI.comm() != -1) 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) if (cache.index0() == -1 && cache.index1() == -1)
map.send {
( const auto& map = (owner() ? AMI.tgtMap() : AMI.srcMap());
fld,
sendRequests, // Insert send/receive requests (non-blocking)
sendBuffers, map.send
recvRequests, (
recvBuffers, fld,
3894+this->index() // unique offset + patch index 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<Type>& fld, const Field<Type>& fld,
labelRange& sendRequests, labelRange& sendRequests,
PtrList<List<Type>>& sendBuffers,
labelRange& recvRequests, labelRange& recvRequests,
PtrList<List<Type>>& recvBuffers PtrList<List<Type>>& sendBuffers,
PtrList<List<Type>>& recvBuffers,
labelRange& sendRequests1,
labelRange& recvRequests1,
PtrList<List<Type>>& sendBuffers1,
PtrList<List<Type>>& recvBuffers1
) const ) const
{ {
const auto& AMI = (owner() ? this->AMI() : neighbPatch().AMI()); const auto& AMI = (owner() ? this->AMI() : neighbPatch().AMI());
@ -221,32 +273,17 @@ void Foam::cyclicAMIPolyPatch::initInterpolate
// Can rotate fields (vector and non-spherical tensors) // Can rotate fields (vector and non-spherical tensors)
constexpr bool transform_supported = is_rotational_vectorspace_v<Type>; constexpr bool transform_supported = is_rotational_vectorspace_v<Type>;
[[maybe_unused]]
autoPtr<coordSystem::cylindrical> cs;
if constexpr (transform_supported) 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(); const cyclicAMIPolyPatch& nbrPp = this->neighbPatch();
Field<Type> localFld(fld.size()); Field<Type> 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())); const tensorField nbrT(cs().R(nbrPp.faceCentres()));
Foam::invTransform(localFld, nbrT, fld); Foam::invTransform(localFld, nbrT, fld);
@ -256,9 +293,30 @@ void Foam::cyclicAMIPolyPatch::initInterpolate
( (
localFld, localFld,
sendRequests, sendRequests,
sendBuffers,
recvRequests, 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::Field<Type>> Foam::cyclicAMIPolyPatch::interpolate
const Field<Type>& localFld, const Field<Type>& localFld,
const labelRange& requests, const labelRange& requests,
const PtrList<List<Type>>& recvBuffers, const PtrList<List<Type>>& recvBuffers,
const labelRange& requests1,
const PtrList<List<Type>>& recvBuffers1,
const UList<Type>& defaultValues const UList<Type>& defaultValues
) const ) const
{ {
auto tresult = tmp<Field<Type>>::New(this->size(), Zero); auto tresult = tmp<Field<Type>>::New(this->size(), Zero);
const auto& AMI = (owner() ? this->AMI() : neighbPatch().AMI()); const auto& AMI = (owner() ? this->AMI() : neighbPatch().AMI());
const auto& cache = AMI.cache();
cache.setDirection(owner());
Field<Type> work; Field<Type> work;
Field<Type> work1;
if (AMI.distributed()) if (AMI.distributed())
{ {
if (AMI.comm() == -1) if (AMI.comm() == -1)
@ -285,71 +348,157 @@ Foam::tmp<Foam::Field<Type>> Foam::cyclicAMIPolyPatch::interpolate
return tresult; 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 // Receive (= copy) data from buffers into work. TBD: receive
// into slices of work. // directly into slices of work.
map.receive map.receive
( (
requests, requests,
recvBuffers, recvBuffers,
work, work,
3894+this->index() // unique offset + patch index 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<Type>& fld = (AMI.distributed() ? work : localFld); const Field<Type>& fld = (AMI.distributed() ? work : localFld);
const Field<Type>& fld1 = (AMI.distributed() ? work1 : localFld);
// Rotate fields (vector and non-spherical tensors) // Rotate fields (vector and non-spherical tensors)
constexpr bool transform_supported = is_rotational_vectorspace_v<Type>; constexpr bool transform_supported = is_rotational_vectorspace_v<Type>;
[[maybe_unused]] // Rotate fields (vector and non-spherical tensors) for periodic AMI
autoPtr<coordSystem::cylindrical> cs; tensorField ownTransform;
Field<Type> localDeflt;
// Rotate fields (vector and non-spherical tensors)
if constexpr (transform_supported) 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) if (cs)
{
AMI.weightedSum
(
owner(),
fld,
tresult.ref(),
defaultValues
);
}
else if constexpr (transform_supported)
{
const tensorField ownT(cs().R(this->faceCentres()));
Field<Type> localDeflt(defaultValues.size());
if (defaultValues.size() == size())
{ {
// Transform default values into cylindrical coords (using ownTransform = cs().R(this->faceCentres());
// *this faceCentres) localDeflt = defaultValues;
// We get in UList (why? Copied from cyclicAMI). Convert to
// Field so we can use transformField routines.
const SubField<Type> defaultSubFld(defaultValues);
const Field<Type>& defaultFld(defaultSubFld);
Foam::invTransform(localDeflt, ownT, defaultFld);
}
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<Type> defaultSubFld(defaultValues);
const Field<Type>& 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 AMI.weightedSum
( (
owner(), owner(),
fld, fld,
tresult.ref(), tresult.ref(),
localDeflt localDefaultValues
); );
// Transform back // 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<Type, plusEqOp<Type>>(plusEqOp<Type>()),
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<Field<Type>>::New(this->size(), Zero);
AMIInterpolation::weightedSum
(
AMI.lowWeightCorrection(),
cache.cSrcAddress1(),
cache.cSrcWeights1(),
cache.cSrcWeightsSum1(),
fld1,
multiplyWeightedOp<Type, plusEqOp<Type>>(plusEqOp<Type>()),
tresult1.ref(),
localDefaultValues
);
if (ownTransform.size())
{
Foam::transform(tresult1.ref(), ownTransform, tresult1());
}
tresult1.ref() *= cache.weight();
tresult.ref() += tresult1();
}
return tresult;
}
} }