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_.size()
)
&& UPstream::finishedRequests
(
recvRequests1_.start(),
recvRequests1_.size()
)
)
{
recvRequests_.clear();
recvRequests1_.clear();
++done;
}
@ -240,9 +246,15 @@ bool Foam::cyclicACMIFvPatchField<Type>::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<Type>::ready() const
recvRequests_.start(),
recvRequests_.size()
)
&& UPstream::finishedRequests
(
recvRequests1_.start(),
recvRequests1_.size()
)
)
{
recvRequests_.clear();
recvRequests1_.clear();
if
(
@ -271,9 +289,15 @@ bool Foam::cyclicACMIFvPatchField<Type>::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<Type>::initEvaluate
const Field<Type> 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<Type>::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<Type>::evaluate
(
Field<Type>::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<Type>::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<Type>::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<Type>::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<Type>::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<Type>::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<Type>::updateInterfaceMatrix
(
Field<Type>::null(), // Not used for distributed
recvRequests_,
recvBufs_
recvBufs_,
recvRequests1_,
recvBufs1_
);
// Receive requests all handled by last function call
recvRequests_.clear();
recvRequests1_.clear();
}
else
{

View File

@ -102,6 +102,28 @@ class cyclicACMIFvPatchField
//- Scalar receive buffers
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
mutable autoPtr<Field<Type>> patchNeighbourFieldPtr_;

View File

@ -207,9 +207,15 @@ bool Foam::cyclicAMIFvPatchField<Type>::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<Type>::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<Type>::ready() const
recvRequests_.start(),
recvRequests_.size()
)
&& UPstream::finishedRequests
(
recvRequests1_.start(),
recvRequests1_.size()
)
)
{
recvRequests_.clear();
recvRequests1_.clear();
if
(
@ -251,9 +269,15 @@ bool Foam::cyclicAMIFvPatchField<Type>::ready() const
sendRequests_.start(),
sendRequests_.size()
)
&& UPstream::finishedRequests
(
sendRequests1_.start(),
sendRequests1_.size()
)
)
{
sendRequests_.clear();
sendRequests1_.clear();
}
return true;
@ -319,8 +343,9 @@ Foam::cyclicAMIFvPatchField<Type>::getNeighbourField
template<class Type>
bool Foam::cyclicAMIFvPatchField<Type>::cacheNeighbourField()
bool Foam::cyclicAMIFvPatchField<Type>::cacheNeighbourField() const
{
return false;
return (FieldBase::localBoundaryConsistency() != 0);
}
@ -491,7 +516,7 @@ void Foam::cyclicAMIFvPatchField<Type>::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<Type>::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<Type>::evaluate
Field<Type>::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<Type>::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<Type>::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<Type>::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<Type>::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<Type>::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<Type>::updateInterfaceMatrix
Field<Type>::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<Type>::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()))
{

View File

@ -113,6 +113,28 @@ class cyclicAMIFvPatchField
//- Scalar receive buffers
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
mutable autoPtr<Field<Type>> 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<Field<Type>> getNeighbourField(const UList<Type>&) const;

View File

@ -220,9 +220,14 @@ public:
(
const Field<Type>& fld,
labelRange& sendRequests,
PtrList<List<Type>>& sendBuffers,
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
{
// 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<Type>& localFld,
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
{
return cyclicACMIPolyPatch_.interpolate
@ -251,6 +263,8 @@ public:
localFld,
requests,
recvBuffers,
requests1,
recvBuffers1,
UList<Type>()
);
}

View File

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

View File

@ -67,9 +67,7 @@ Foam::cyclicACMIGAMGInterfaceField::cyclicACMIGAMGInterfaceField
GAMGInterfaceField(GAMGCp, fineInterface),
cyclicACMIInterface_(refCast<const cyclicACMIGAMGInterface>(GAMGCp)),
doTransform_(false),
rank_(0),
sendRequests_(),
recvRequests_()
rank_(0)
{
const cyclicAMILduInterfaceField& p =
refCast<const cyclicAMILduInterfaceField>(fineInterface);
@ -89,9 +87,7 @@ Foam::cyclicACMIGAMGInterfaceField::cyclicACMIGAMGInterfaceField
GAMGInterfaceField(GAMGCp, doTransform, rank),
cyclicACMIInterface_(refCast<const cyclicACMIGAMGInterface>(GAMGCp)),
doTransform_(doTransform),
rank_(rank),
sendRequests_(),
recvRequests_()
rank_(rank)
{}
@ -104,9 +100,7 @@ Foam::cyclicACMIGAMGInterfaceField::cyclicACMIGAMGInterfaceField
GAMGInterfaceField(GAMGCp, is),
cyclicACMIInterface_(refCast<const cyclicACMIGAMGInterface>(GAMGCp)),
doTransform_(readBool(is)),
rank_(readLabel(is)),
sendRequests_(),
recvRequests_()
rank_(readLabel(is))
{}
@ -120,9 +114,7 @@ Foam::cyclicACMIGAMGInterfaceField::cyclicACMIGAMGInterfaceField
GAMGInterfaceField(GAMGCp, local),
cyclicACMIInterface_(refCast<const cyclicACMIGAMGInterface>(GAMGCp)),
doTransform_(false),
rank_(0),
sendRequests_(),
recvRequests_()
rank_(0)
{
const auto& p = refCast<const cyclicACMILduInterfaceField>(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<scalar, plusEqOp<scalar>> 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<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
{
@ -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<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);

View File

@ -83,6 +83,20 @@ class cyclicACMIGAMGInterfaceField
//- Scalar receive buffers
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

View File

@ -67,9 +67,7 @@ Foam::cyclicAMIGAMGInterfaceField::cyclicAMIGAMGInterfaceField
GAMGInterfaceField(GAMGCp, fineInterface),
cyclicAMIInterface_(refCast<const cyclicAMIGAMGInterface>(GAMGCp)),
doTransform_(false),
rank_(0),
sendRequests_(),
recvRequests_()
rank_(0)
{
const cyclicAMILduInterfaceField& p =
refCast<const cyclicAMILduInterfaceField>(fineInterface);
@ -89,9 +87,7 @@ Foam::cyclicAMIGAMGInterfaceField::cyclicAMIGAMGInterfaceField
GAMGInterfaceField(GAMGCp, doTransform, rank),
cyclicAMIInterface_(refCast<const cyclicAMIGAMGInterface>(GAMGCp)),
doTransform_(doTransform),
rank_(rank),
sendRequests_(),
recvRequests_()
rank_(rank)
{}
@ -104,9 +100,7 @@ Foam::cyclicAMIGAMGInterfaceField::cyclicAMIGAMGInterfaceField
GAMGInterfaceField(GAMGCp, is),
cyclicAMIInterface_(refCast<const cyclicAMIGAMGInterface>(GAMGCp)),
doTransform_(readBool(is)),
rank_(readLabel(is)),
sendRequests_(),
recvRequests_()
rank_(readLabel(is))
{}
@ -120,9 +114,7 @@ Foam::cyclicAMIGAMGInterfaceField::cyclicAMIGAMGInterfaceField
GAMGInterfaceField(GAMGCp, local),
cyclicAMIInterface_(refCast<const cyclicAMIGAMGInterface>(GAMGCp)),
doTransform_(false),
rank_(0),
sendRequests_(), // assume no requests in flight for input field
recvRequests_()
rank_(0)
{
const auto& p = refCast<const cyclicAMILduInterfaceField>(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<scalar, plusEqOp<scalar>> 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<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
{
@ -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<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);

View File

@ -83,6 +83,21 @@ class cyclicAMIGAMGInterfaceField
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
//- No copy construct

View File

@ -415,6 +415,8 @@ void Foam::cyclicAMIPolyPatch::resetAMI(const UList<point>& 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;
}
}

View File

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

View File

@ -63,6 +63,7 @@ Foam::tmp<Foam::Field<Type>> 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<Type>& fld,
labelRange& sendRequests,
PtrList<List<Type>>& sendBuffers,
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 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<Type>& fld,
labelRange& sendRequests,
PtrList<List<Type>>& sendBuffers,
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 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<Type>;
[[maybe_unused]]
autoPtr<coordSystem::cylindrical> 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<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()));
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::Field<Type>> Foam::cyclicAMIPolyPatch::interpolate
const Field<Type>& localFld,
const labelRange& requests,
const PtrList<List<Type>>& recvBuffers,
const labelRange& requests1,
const PtrList<List<Type>>& recvBuffers1,
const UList<Type>& defaultValues
) const
{
auto tresult = tmp<Field<Type>>::New(this->size(), Zero);
const auto& AMI = (owner() ? this->AMI() : neighbPatch().AMI());
const auto& cache = AMI.cache();
cache.setDirection(owner());
Field<Type> work;
Field<Type> work1;
if (AMI.distributed())
{
if (AMI.comm() == -1)
@ -285,71 +348,157 @@ Foam::tmp<Foam::Field<Type>> 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<Type>& fld = (AMI.distributed() ? work : localFld);
const Field<Type>& fld1 = (AMI.distributed() ? work1 : localFld);
// Rotate fields (vector and non-spherical tensors)
constexpr bool transform_supported = is_rotational_vectorspace_v<Type>;
[[maybe_unused]]
autoPtr<coordSystem::cylindrical> cs;
// Rotate fields (vector and non-spherical tensors) for periodic AMI
tensorField ownTransform;
Field<Type> 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<Type> 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<Type> defaultSubFld(defaultValues);
const Field<Type>& 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<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
(
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<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;
}
}