ENH: add non-blocking handling for cyclicAMI (#2963)
Co-authored-by: Mark Olesen <>
This commit is contained in:
parent
539d538d5a
commit
69169c5abe
@ -26,9 +26,11 @@ License
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "cyclicAMIPolyPatch.H"
|
||||
#include "mapDistributeBase.H"
|
||||
#include "AMIInterpolation.H"
|
||||
#include "fvMatrix.H"
|
||||
#include "volFields.H"
|
||||
//#include "cylicFvPatchField.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
@ -41,7 +43,10 @@ Foam::cyclicAMIFvPatchField<Type>::cyclicAMIFvPatchField
|
||||
:
|
||||
cyclicAMILduInterfaceField(),
|
||||
coupledFvPatchField<Type>(p, iF),
|
||||
cyclicAMIPatch_(refCast<const cyclicAMIFvPatch>(p))
|
||||
cyclicAMIPatch_(refCast<const cyclicAMIFvPatch>(p)),
|
||||
sendRequests_(0),
|
||||
recvRequests_(0),
|
||||
patchNeighbourFieldPtr_(nullptr)
|
||||
{}
|
||||
|
||||
|
||||
@ -55,12 +60,15 @@ Foam::cyclicAMIFvPatchField<Type>::cyclicAMIFvPatchField
|
||||
:
|
||||
cyclicAMILduInterfaceField(),
|
||||
coupledFvPatchField<Type>(p, iF, dict, IOobjectOption::NO_READ),
|
||||
cyclicAMIPatch_(refCast<const cyclicAMIFvPatch>(p, dict))
|
||||
cyclicAMIPatch_(refCast<const cyclicAMIFvPatch>(p, dict)),
|
||||
sendRequests_(0),
|
||||
recvRequests_(0),
|
||||
patchNeighbourFieldPtr_(nullptr)
|
||||
{
|
||||
if (!isA<cyclicAMIFvPatch>(p))
|
||||
{
|
||||
FatalIOErrorInFunction(dict)
|
||||
<< " patch type '" << p.type()
|
||||
<< "\n patch type '" << p.type()
|
||||
<< "' not constraint type '" << typeName << "'"
|
||||
<< "\n for patch " << p.name()
|
||||
<< " of field " << this->internalField().name()
|
||||
@ -68,12 +76,24 @@ Foam::cyclicAMIFvPatchField<Type>::cyclicAMIFvPatchField
|
||||
<< exit(FatalIOError);
|
||||
}
|
||||
|
||||
// Use 'value' supplied, or set to coupled or internal field
|
||||
// Handle neighbour value first, before any evaluate()
|
||||
const auto* hasNeighbValue =
|
||||
dict.findEntry("neighbourValue", keyType::LITERAL);
|
||||
|
||||
if (hasNeighbValue)
|
||||
{
|
||||
patchNeighbourFieldPtr_.reset
|
||||
(
|
||||
new Field<Type>(*hasNeighbValue, p.size())
|
||||
);
|
||||
}
|
||||
|
||||
// Use 'value' supplied, or evaluate (if coupled) or set to internal field
|
||||
if (!this->readValueEntry(dict))
|
||||
{
|
||||
if (this->coupled())
|
||||
{
|
||||
this->evaluate(Pstream::commsTypes::blocking);
|
||||
this->evaluate(UPstream::commsTypes::nonBlocking);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -94,8 +114,19 @@ Foam::cyclicAMIFvPatchField<Type>::cyclicAMIFvPatchField
|
||||
:
|
||||
cyclicAMILduInterfaceField(),
|
||||
coupledFvPatchField<Type>(ptf, p, iF, mapper),
|
||||
cyclicAMIPatch_(refCast<const cyclicAMIFvPatch>(p))
|
||||
cyclicAMIPatch_(refCast<const cyclicAMIFvPatch>(p)),
|
||||
sendRequests_(0),
|
||||
recvRequests_(0),
|
||||
patchNeighbourFieldPtr_(nullptr)
|
||||
{
|
||||
if (ptf.patchNeighbourFieldPtr_)
|
||||
{
|
||||
patchNeighbourFieldPtr_.reset
|
||||
(
|
||||
new Field<Type>(ptf.patchNeighbourFieldPtr_(), mapper)
|
||||
);
|
||||
}
|
||||
|
||||
if (!isA<cyclicAMIFvPatch>(this->patch()))
|
||||
{
|
||||
FatalErrorInFunction
|
||||
@ -106,6 +137,12 @@ Foam::cyclicAMIFvPatchField<Type>::cyclicAMIFvPatchField
|
||||
<< " in file " << this->internalField().objectPath()
|
||||
<< exit(FatalError);
|
||||
}
|
||||
if (debug && !ptf.all_ready())
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Outstanding request(s) on patch " << cyclicAMIPatch_.name()
|
||||
<< abort(FatalError);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -117,8 +154,18 @@ Foam::cyclicAMIFvPatchField<Type>::cyclicAMIFvPatchField
|
||||
:
|
||||
cyclicAMILduInterfaceField(),
|
||||
coupledFvPatchField<Type>(ptf),
|
||||
cyclicAMIPatch_(ptf.cyclicAMIPatch_)
|
||||
{}
|
||||
cyclicAMIPatch_(ptf.cyclicAMIPatch_),
|
||||
sendRequests_(0),
|
||||
recvRequests_(0),
|
||||
patchNeighbourFieldPtr_(ptf.patchNeighbourFieldPtr_.clone())
|
||||
{
|
||||
if (debug && !ptf.all_ready())
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Outstanding request(s) on patch " << cyclicAMIPatch_.name()
|
||||
<< abort(FatalError);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
@ -130,43 +177,111 @@ Foam::cyclicAMIFvPatchField<Type>::cyclicAMIFvPatchField
|
||||
:
|
||||
cyclicAMILduInterfaceField(),
|
||||
coupledFvPatchField<Type>(ptf, iF),
|
||||
cyclicAMIPatch_(ptf.cyclicAMIPatch_)
|
||||
{}
|
||||
cyclicAMIPatch_(ptf.cyclicAMIPatch_),
|
||||
sendRequests_(0),
|
||||
recvRequests_(0),
|
||||
patchNeighbourFieldPtr_(ptf.patchNeighbourFieldPtr_.clone())
|
||||
{
|
||||
if (debug && !ptf.all_ready())
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Outstanding request(s) on patch " << cyclicAMIPatch_.name()
|
||||
<< abort(FatalError);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
bool Foam::cyclicAMIFvPatchField<Type>::coupled() const
|
||||
bool Foam::cyclicAMIFvPatchField<Type>::all_ready() const
|
||||
{
|
||||
return cyclicAMIPatch_.coupled();
|
||||
int done = 0;
|
||||
|
||||
if
|
||||
(
|
||||
UPstream::finishedRequests
|
||||
(
|
||||
recvRequests_.start(),
|
||||
recvRequests_.size()
|
||||
)
|
||||
)
|
||||
{
|
||||
recvRequests_.clear();
|
||||
++done;
|
||||
}
|
||||
|
||||
if
|
||||
(
|
||||
UPstream::finishedRequests
|
||||
(
|
||||
sendRequests_.start(),
|
||||
sendRequests_.size()
|
||||
)
|
||||
)
|
||||
{
|
||||
sendRequests_.clear();
|
||||
++done;
|
||||
}
|
||||
|
||||
return (done == 2);
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
bool Foam::cyclicAMIFvPatchField<Type>::ready() const
|
||||
{
|
||||
if
|
||||
(
|
||||
UPstream::finishedRequests
|
||||
(
|
||||
recvRequests_.start(),
|
||||
recvRequests_.size()
|
||||
)
|
||||
)
|
||||
{
|
||||
recvRequests_.clear();
|
||||
|
||||
if
|
||||
(
|
||||
UPstream::finishedRequests
|
||||
(
|
||||
sendRequests_.start(),
|
||||
sendRequests_.size()
|
||||
)
|
||||
)
|
||||
{
|
||||
sendRequests_.clear();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::Field<Type>>
|
||||
Foam::cyclicAMIFvPatchField<Type>::patchNeighbourField() const
|
||||
Foam::cyclicAMIFvPatchField<Type>::patchNeighbourField
|
||||
(
|
||||
const Field<Type>& iField
|
||||
) const
|
||||
{
|
||||
const Field<Type>& iField = this->primitiveField();
|
||||
|
||||
// By pass polyPatch to get nbrId. Instead use cyclicAMIFvPatch virtual
|
||||
// Bypass polyPatch to get nbrId. Instead use cyclicAMIFvPatch virtual
|
||||
// neighbPatch()
|
||||
const cyclicAMIFvPatch& neighbPatch = cyclicAMIPatch_.neighbPatch();
|
||||
const labelUList& nbrFaceCells = neighbPatch.faceCells();
|
||||
|
||||
Field<Type> pnf(iField, nbrFaceCells);
|
||||
Field<Type> defaultValues;
|
||||
|
||||
tmp<Field<Type>> tpnf;
|
||||
if (cyclicAMIPatch_.applyLowWeightCorrection())
|
||||
{
|
||||
Field<Type> pnfInternal(iField, cyclicAMIPatch_.faceCells());
|
||||
defaultValues = Field<Type>(iField, cyclicAMIPatch_.faceCells());
|
||||
}
|
||||
|
||||
tpnf = cyclicAMIPatch_.interpolate(pnf, pnfInternal);
|
||||
}
|
||||
else
|
||||
{
|
||||
tpnf = cyclicAMIPatch_.interpolate(pnf);
|
||||
}
|
||||
tmp<Field<Type>> tpnf = cyclicAMIPatch_.interpolate(pnf, defaultValues);
|
||||
|
||||
if (doTransform())
|
||||
{
|
||||
@ -177,6 +292,40 @@ Foam::cyclicAMIFvPatchField<Type>::patchNeighbourField() const
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::Field<Type>>
|
||||
Foam::cyclicAMIFvPatchField<Type>::patchNeighbourField() const
|
||||
{
|
||||
if (this->ownerAMI().distributed())
|
||||
{
|
||||
if (!this->ready())
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Outstanding recv request(s) on patch "
|
||||
<< cyclicAMIPatch_.name()
|
||||
<< " field " << this->internalField().name()
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
// Initialise if not done in construct-from-dictionary
|
||||
if (!patchNeighbourFieldPtr_)
|
||||
{
|
||||
// Do interpolation and store result
|
||||
patchNeighbourFieldPtr_.reset
|
||||
(
|
||||
patchNeighbourField(this->primitiveField()).ptr()
|
||||
);
|
||||
}
|
||||
return patchNeighbourFieldPtr_();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Do interpolation
|
||||
return patchNeighbourField(this->primitiveField());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
const Foam::cyclicAMIFvPatchField<Type>&
|
||||
Foam::cyclicAMIFvPatchField<Type>::neighbourPatchField() const
|
||||
@ -194,6 +343,150 @@ Foam::cyclicAMIFvPatchField<Type>::neighbourPatchField() const
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
void Foam::cyclicAMIFvPatchField<Type>::initEvaluate
|
||||
(
|
||||
const Pstream::commsTypes commsType
|
||||
)
|
||||
{
|
||||
if (!this->updated())
|
||||
{
|
||||
this->updateCoeffs();
|
||||
}
|
||||
|
||||
if (this->ownerAMI().distributed())
|
||||
{
|
||||
if (commsType != UPstream::commsTypes::nonBlocking)
|
||||
{
|
||||
// Invalidate old field - or flag as fatal?
|
||||
patchNeighbourFieldPtr_.reset(nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
// Start sending
|
||||
|
||||
// By-pass polyPatch to get nbrId. Instead use cyclicAMIFvPatch virtual
|
||||
// neighbPatch()
|
||||
const cyclicAMIFvPatch& neighbPatch = cyclicAMIPatch_.neighbPatch();
|
||||
const labelUList& nbrFaceCells = neighbPatch.faceCells();
|
||||
const Field<Type> pnf(this->primitiveField(), nbrFaceCells);
|
||||
|
||||
const cyclicAMIPolyPatch& cpp = cyclicAMIPatch_.cyclicAMIPatch();
|
||||
|
||||
cpp.initInterpolate
|
||||
(
|
||||
pnf,
|
||||
sendRequests_,
|
||||
sendBufs_,
|
||||
recvRequests_,
|
||||
recvBufs_
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
void Foam::cyclicAMIFvPatchField<Type>::evaluate
|
||||
(
|
||||
const Pstream::commsTypes commsType
|
||||
)
|
||||
{
|
||||
if (!this->updated())
|
||||
{
|
||||
this->updateCoeffs();
|
||||
}
|
||||
|
||||
const auto& AMI = this->ownerAMI();
|
||||
|
||||
if (AMI.distributed())
|
||||
{
|
||||
// Calculate patchNeighbourField
|
||||
if (commsType != UPstream::commsTypes::nonBlocking)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Can only evaluate distributed AMI with nonBlocking"
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
patchNeighbourFieldPtr_.reset(nullptr);
|
||||
|
||||
const cyclicAMIPolyPatch& cpp = cyclicAMIPatch_.cyclicAMIPatch();
|
||||
|
||||
Field<Type> defaultValues;
|
||||
if (AMI.applyLowWeightCorrection())
|
||||
{
|
||||
defaultValues = this->patchInternalField();
|
||||
}
|
||||
|
||||
patchNeighbourFieldPtr_.reset
|
||||
(
|
||||
cpp.interpolate
|
||||
(
|
||||
Field<Type>::null(), // Not used for distributed
|
||||
recvRequests_,
|
||||
recvBufs_,
|
||||
defaultValues
|
||||
).ptr()
|
||||
);
|
||||
auto& patchNeighbourField = patchNeighbourFieldPtr_.ref();
|
||||
|
||||
if (doTransform())
|
||||
{
|
||||
// In-place transform
|
||||
transform(patchNeighbourField, forwardT(), patchNeighbourField);
|
||||
}
|
||||
}
|
||||
|
||||
// Use patchNeighbourField() and patchInternalField() to obtain face value
|
||||
coupledFvPatchField<Type>::evaluate(commsType);
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
void Foam::cyclicAMIFvPatchField<Type>::initInterfaceMatrixUpdate
|
||||
(
|
||||
solveScalarField& result,
|
||||
const bool add,
|
||||
const lduAddressing& lduAddr,
|
||||
const label patchId,
|
||||
const solveScalarField& psiInternal,
|
||||
const scalarField& coeffs,
|
||||
const direction cmpt,
|
||||
const Pstream::commsTypes commsType
|
||||
) const
|
||||
{
|
||||
if (this->ownerAMI().distributed())
|
||||
{
|
||||
// Start sending
|
||||
if (commsType != UPstream::commsTypes::nonBlocking)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Can only evaluate distributed AMI with nonBlocking"
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
const labelUList& nbrFaceCells =
|
||||
lduAddr.patchAddr(cyclicAMIPatch_.neighbPatchID());
|
||||
|
||||
solveScalarField pnf(psiInternal, nbrFaceCells);
|
||||
|
||||
// Transform according to the transformation tensors
|
||||
transformCoupleField(pnf, cmpt);
|
||||
|
||||
const cyclicAMIPolyPatch& cpp = cyclicAMIPatch_.cyclicAMIPatch();
|
||||
|
||||
cpp.initInterpolate
|
||||
(
|
||||
pnf,
|
||||
sendRequests_,
|
||||
scalarSendBufs_,
|
||||
recvRequests_,
|
||||
scalarRecvBufs_
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
void Foam::cyclicAMIFvPatchField<Type>::updateInterfaceMatrix
|
||||
(
|
||||
@ -204,27 +497,63 @@ void Foam::cyclicAMIFvPatchField<Type>::updateInterfaceMatrix
|
||||
const solveScalarField& psiInternal,
|
||||
const scalarField& coeffs,
|
||||
const direction cmpt,
|
||||
const Pstream::commsTypes
|
||||
const Pstream::commsTypes commsType
|
||||
) const
|
||||
{
|
||||
const labelUList& nbrFaceCells =
|
||||
lduAddr.patchAddr(cyclicAMIPatch_.neighbPatchID());
|
||||
|
||||
solveScalarField pnf(psiInternal, nbrFaceCells);
|
||||
|
||||
const labelUList& faceCells = lduAddr.patchAddr(patchId);
|
||||
|
||||
// Transform according to the transformation tensors
|
||||
transformCoupleField(pnf, cmpt);
|
||||
const auto& AMI =
|
||||
(
|
||||
cyclicAMIPatch_.owner()
|
||||
? cyclicAMIPatch_.AMI()
|
||||
: cyclicAMIPatch_.neighbPatch().AMI()
|
||||
);
|
||||
|
||||
if (cyclicAMIPatch_.applyLowWeightCorrection())
|
||||
solveScalarField pnf;
|
||||
|
||||
if (this->ownerAMI().distributed())
|
||||
{
|
||||
solveScalarField pif(psiInternal, faceCells);
|
||||
pnf = cyclicAMIPatch_.interpolate(pnf, pif);
|
||||
if (commsType != UPstream::commsTypes::nonBlocking)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Can only evaluate distributed AMI with nonBlocking"
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
solveScalarField defaultValues;
|
||||
if (AMI.applyLowWeightCorrection())
|
||||
{
|
||||
defaultValues = solveScalarField(psiInternal, faceCells);
|
||||
}
|
||||
|
||||
const cyclicAMIPolyPatch& cpp = cyclicAMIPatch_.cyclicAMIPatch();
|
||||
|
||||
pnf =
|
||||
cpp.interpolate
|
||||
(
|
||||
solveScalarField::null(), // Not used for distributed
|
||||
recvRequests_,
|
||||
scalarRecvBufs_,
|
||||
defaultValues
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
pnf = cyclicAMIPatch_.interpolate(pnf);
|
||||
solveScalarField defaultValues;
|
||||
if (cyclicAMIPatch_.applyLowWeightCorrection())
|
||||
{
|
||||
defaultValues = solveScalarField(psiInternal, faceCells);
|
||||
}
|
||||
|
||||
const labelUList& nbrFaceCells =
|
||||
lduAddr.patchAddr(cyclicAMIPatch_.neighbPatchID());
|
||||
|
||||
pnf = solveScalarField(psiInternal, nbrFaceCells);
|
||||
|
||||
// Transform according to the transformation tensors
|
||||
transformCoupleField(pnf, cmpt);
|
||||
|
||||
pnf = cyclicAMIPatch_.interpolate(pnf, defaultValues);
|
||||
}
|
||||
|
||||
// Multiply the field by coefficients and add into the result
|
||||
@ -232,6 +561,51 @@ void Foam::cyclicAMIFvPatchField<Type>::updateInterfaceMatrix
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
void Foam::cyclicAMIFvPatchField<Type>::initInterfaceMatrixUpdate
|
||||
(
|
||||
Field<Type>& result,
|
||||
const bool add,
|
||||
const lduAddressing& lduAddr,
|
||||
const label patchId,
|
||||
const Field<Type>& psiInternal,
|
||||
const scalarField& coeffs,
|
||||
const Pstream::commsTypes commsType
|
||||
) const
|
||||
{
|
||||
const auto& AMI = this->ownerAMI();
|
||||
|
||||
if (AMI.distributed())
|
||||
{
|
||||
if (commsType != UPstream::commsTypes::nonBlocking)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Can only evaluate distributed AMI with nonBlocking"
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
const labelUList& nbrFaceCells =
|
||||
lduAddr.patchAddr(cyclicAMIPatch_.neighbPatchID());
|
||||
|
||||
Field<Type> pnf(psiInternal, nbrFaceCells);
|
||||
|
||||
// Transform according to the transformation tensors
|
||||
transformCoupleField(pnf);
|
||||
|
||||
const cyclicAMIPolyPatch& cpp = cyclicAMIPatch_.cyclicAMIPatch();
|
||||
|
||||
cpp.initInterpolate
|
||||
(
|
||||
pnf,
|
||||
sendRequests_,
|
||||
sendBufs_,
|
||||
recvRequests_,
|
||||
recvBufs_
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
void Foam::cyclicAMIFvPatchField<Type>::updateInterfaceMatrix
|
||||
(
|
||||
@ -241,28 +615,59 @@ void Foam::cyclicAMIFvPatchField<Type>::updateInterfaceMatrix
|
||||
const label patchId,
|
||||
const Field<Type>& psiInternal,
|
||||
const scalarField& coeffs,
|
||||
const Pstream::commsTypes
|
||||
const Pstream::commsTypes commsType
|
||||
) const
|
||||
{
|
||||
const labelUList& nbrFaceCells =
|
||||
lduAddr.patchAddr(cyclicAMIPatch_.neighbPatchID());
|
||||
const labelUList& faceCells = lduAddr.patchAddr(patchId);
|
||||
|
||||
Field<Type> pnf(psiInternal, nbrFaceCells);
|
||||
const auto& AMI = this->ownerAMI();
|
||||
|
||||
// Transform according to the transformation tensors
|
||||
transformCoupleField(pnf);
|
||||
Field<Type> pnf;
|
||||
|
||||
if (cyclicAMIPatch_.applyLowWeightCorrection())
|
||||
if (AMI.distributed())
|
||||
{
|
||||
Field<Type> pif(psiInternal, cyclicAMIPatch_.faceCells());
|
||||
pnf = cyclicAMIPatch_.interpolate(pnf, pif);
|
||||
if (commsType != UPstream::commsTypes::nonBlocking)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Can only evaluate distributed AMI with nonBlocking"
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
const cyclicAMIPolyPatch& cpp = cyclicAMIPatch_.cyclicAMIPatch();
|
||||
|
||||
Field<Type> defaultValues;
|
||||
if (AMI.applyLowWeightCorrection())
|
||||
{
|
||||
defaultValues = Field<Type>(psiInternal, faceCells);
|
||||
}
|
||||
|
||||
pnf =
|
||||
cpp.interpolate
|
||||
(
|
||||
Field<Type>::null(), // Not used for distributed
|
||||
recvRequests_,
|
||||
recvBufs_,
|
||||
defaultValues
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
pnf = cyclicAMIPatch_.interpolate(pnf);
|
||||
}
|
||||
const labelUList& nbrFaceCells =
|
||||
lduAddr.patchAddr(cyclicAMIPatch_.neighbPatchID());
|
||||
|
||||
const labelUList& faceCells = lduAddr.patchAddr(patchId);
|
||||
Field<Type> pnf(psiInternal, nbrFaceCells);
|
||||
|
||||
// Transform according to the transformation tensors
|
||||
transformCoupleField(pnf);
|
||||
|
||||
Field<Type> defaultValues;
|
||||
if (cyclicAMIPatch_.applyLowWeightCorrection())
|
||||
{
|
||||
defaultValues = Field<Type>(psiInternal, faceCells);
|
||||
}
|
||||
|
||||
pnf = cyclicAMIPatch_.interpolate(pnf, defaultValues);
|
||||
}
|
||||
|
||||
// Multiply the field by coefficients and add into the result
|
||||
this->addToInternalField(result, !add, faceCells, coeffs, pnf);
|
||||
@ -277,10 +682,9 @@ void Foam::cyclicAMIFvPatchField<Type>::manipulateMatrix
|
||||
const direction cmpt
|
||||
)
|
||||
{
|
||||
|
||||
if (this->cyclicAMIPatch().owner())
|
||||
{
|
||||
label index = this->patch().index();
|
||||
const label index = this->patch().index();
|
||||
|
||||
const label globalPatchID =
|
||||
matrix.lduMeshAssembly().patchLocalToGlobalMap()[mat][index];
|
||||
@ -376,7 +780,8 @@ Foam::cyclicAMIFvPatchField<Type>::coeffs
|
||||
matrix.lduMeshAssembly().cellBoundMap()[mat][index].size()
|
||||
);
|
||||
|
||||
Field<scalar> mapCoeffs(nSubFaces, Zero);
|
||||
auto tmapCoeffs = tmp<Field<scalar>>::New(nSubFaces, Zero);
|
||||
auto& mapCoeffs = tmapCoeffs.ref();
|
||||
|
||||
const scalarListList& srcWeight =
|
||||
cyclicAMIPatch_.cyclicAMIPatch().AMI().srcWeights();
|
||||
@ -394,7 +799,7 @@ Foam::cyclicAMIFvPatchField<Type>::coeffs
|
||||
}
|
||||
}
|
||||
|
||||
return tmp<Field<scalar>>(new Field<scalar>(mapCoeffs));
|
||||
return tmapCoeffs;
|
||||
}
|
||||
|
||||
|
||||
@ -408,7 +813,7 @@ void Foam::cyclicAMIFvPatchField<Type>::collectStencilData
|
||||
List<Type2>& expandedData
|
||||
)
|
||||
{
|
||||
expandedData.setSize(stencil.size());
|
||||
expandedData.resize_nocopy(stencil.size());
|
||||
if (mapPtr)
|
||||
{
|
||||
Type2 work(data);
|
||||
@ -417,7 +822,7 @@ void Foam::cyclicAMIFvPatchField<Type>::collectStencilData
|
||||
forAll(stencil, facei)
|
||||
{
|
||||
const labelList& slots = stencil[facei];
|
||||
expandedData[facei].append
|
||||
expandedData[facei].push_back
|
||||
(
|
||||
UIndirectList<typename Type2::value_type>(work, slots)
|
||||
);
|
||||
@ -428,7 +833,7 @@ void Foam::cyclicAMIFvPatchField<Type>::collectStencilData
|
||||
forAll(stencil, facei)
|
||||
{
|
||||
const labelList& slots = stencil[facei];
|
||||
expandedData[facei].append
|
||||
expandedData[facei].push_back
|
||||
(
|
||||
UIndirectList<typename Type2::value_type>(data, slots)
|
||||
);
|
||||
@ -442,8 +847,12 @@ void Foam::cyclicAMIFvPatchField<Type>::write(Ostream& os) const
|
||||
{
|
||||
fvPatchField<Type>::write(os);
|
||||
fvPatchField<Type>::writeValueEntry(os);
|
||||
|
||||
if (patchNeighbourFieldPtr_)
|
||||
{
|
||||
patchNeighbourFieldPtr_->writeEntry("neighbourValue", os);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
Copyright (C) 2019-2023 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -41,16 +41,24 @@ Usage
|
||||
<patchName>
|
||||
{
|
||||
type cyclicAMI;
|
||||
value <initial value>;
|
||||
neighbourValue <initial value of neighbour patch cells>;
|
||||
}
|
||||
\endverbatim
|
||||
|
||||
Note
|
||||
The outer boundary of the patch pairs must be similar, i.e. if the owner
|
||||
patch is transformed to the neighbour patch, the outer perimiter of each
|
||||
patch is transformed to the neighbour patch, the outer perimeter of each
|
||||
patch should be identical (or very similar).
|
||||
|
||||
The \c neighbourValue is only needed when running distributed,
|
||||
i.e. the neighbour cells are on a different processor from the owner cells.
|
||||
It guarantees consistent restart e.g. when doing a snGrad and avoids
|
||||
additional communication.
|
||||
|
||||
See also
|
||||
Foam::AMIInterpolation
|
||||
Foam::processorFvPatchField
|
||||
|
||||
SourceFiles
|
||||
cyclicAMIFvPatchField.C
|
||||
@ -79,14 +87,55 @@ class cyclicAMIFvPatchField
|
||||
virtual public cyclicAMILduInterfaceField,
|
||||
public coupledFvPatchField<Type>
|
||||
{
|
||||
// Private data
|
||||
// Private Data
|
||||
|
||||
//- Local reference cast into the cyclic patch
|
||||
const cyclicAMIFvPatch& cyclicAMIPatch_;
|
||||
|
||||
|
||||
// Sending and receiving (distributed AMI)
|
||||
|
||||
//- Current range of send requests (non-blocking)
|
||||
mutable labelRange sendRequests_;
|
||||
|
||||
//- Current range of recv requests (non-blocking)
|
||||
mutable labelRange recvRequests_;
|
||||
|
||||
//- Send buffers
|
||||
mutable PtrList<List<Type>> sendBufs_;
|
||||
|
||||
//- Receive buffers_
|
||||
mutable PtrList<List<Type>> recvBufs_;
|
||||
|
||||
//- Scalar send buffers
|
||||
mutable PtrList<List<solveScalar>> scalarSendBufs_;
|
||||
|
||||
//- Scalar receive buffers
|
||||
mutable PtrList<List<solveScalar>> scalarRecvBufs_;
|
||||
|
||||
//- Neighbour coupled internal cell data
|
||||
mutable autoPtr<Field<Type>> patchNeighbourFieldPtr_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Return the AMI corresponding to the owner side
|
||||
const AMIPatchToPatchInterpolation& ownerAMI() const
|
||||
{
|
||||
return
|
||||
(
|
||||
cyclicAMIPatch_.owner()
|
||||
? cyclicAMIPatch_.AMI()
|
||||
: cyclicAMIPatch_.neighbPatch().AMI()
|
||||
);
|
||||
}
|
||||
|
||||
//- All receive/send requests have completed
|
||||
virtual bool all_ready() const;
|
||||
|
||||
//- Return neighbour coupled internal cell data
|
||||
tmp<Field<Type>> patchNeighbourField(const Field<Type>&) const;
|
||||
|
||||
//- Return neighbour side field given internal fields
|
||||
template<class Type2>
|
||||
tmp<Field<Type2>> neighbourSideField
|
||||
@ -103,7 +152,6 @@ class cyclicAMIFvPatchField
|
||||
const label
|
||||
) const;
|
||||
|
||||
|
||||
template<class Type2>
|
||||
void collectStencilData
|
||||
(
|
||||
@ -178,28 +226,54 @@ public:
|
||||
}
|
||||
|
||||
|
||||
// Member functions
|
||||
// Member Functions
|
||||
|
||||
// Access
|
||||
|
||||
//- Return local reference cast into the cyclic AMI patch
|
||||
const cyclicAMIFvPatch& cyclicAMIPatch() const
|
||||
{
|
||||
return cyclicAMIPatch_;
|
||||
}
|
||||
//- Return local reference cast into the cyclic AMI patch
|
||||
const cyclicAMIFvPatch& cyclicAMIPatch() const noexcept
|
||||
{
|
||||
return cyclicAMIPatch_;
|
||||
}
|
||||
|
||||
|
||||
// Evaluation functions
|
||||
// Coupling
|
||||
|
||||
//- Return true if coupled. Note that the underlying patch
|
||||
// is not coupled() - the points don't align.
|
||||
virtual bool coupled() const;
|
||||
//- Return true if coupled. Note that the underlying patch
|
||||
// is not coupled() - the points don't align.
|
||||
virtual bool coupled() const { return cyclicAMIPatch_.coupled(); }
|
||||
|
||||
//- Return neighbour coupled internal cell data
|
||||
virtual tmp<Field<Type>> patchNeighbourField() const;
|
||||
//- Are all (receive) data available?
|
||||
virtual bool ready() const;
|
||||
|
||||
//- Return reference to neighbour patchField
|
||||
const cyclicAMIFvPatchField<Type>& neighbourPatchField() const;
|
||||
//- Return neighbour coupled internal cell data
|
||||
virtual tmp<Field<Type>> patchNeighbourField() const;
|
||||
|
||||
//- Return reference to neighbour patchField
|
||||
const cyclicAMIFvPatchField<Type>& neighbourPatchField() const;
|
||||
|
||||
|
||||
// Evaluation
|
||||
|
||||
//- Initialise the evaluation of the patch field
|
||||
virtual void initEvaluate(const Pstream::commsTypes commsType);
|
||||
|
||||
//- Evaluate the patch field
|
||||
virtual void evaluate(const Pstream::commsTypes commsType);
|
||||
|
||||
|
||||
// Coupled interface functionality
|
||||
|
||||
//- Initialise neighbour matrix update
|
||||
virtual void initInterfaceMatrixUpdate
|
||||
(
|
||||
solveScalarField& result,
|
||||
const bool add,
|
||||
const lduAddressing& lduAddr,
|
||||
const label patchId,
|
||||
const solveScalarField& psiInternal,
|
||||
const scalarField& coeffs,
|
||||
const direction cmpt,
|
||||
const Pstream::commsTypes commsType
|
||||
) const;
|
||||
|
||||
//- Update result field based on interface functionality
|
||||
virtual void updateInterfaceMatrix
|
||||
@ -214,6 +288,18 @@ public:
|
||||
const Pstream::commsTypes commsType
|
||||
) const;
|
||||
|
||||
//- Initialise neighbour matrix update
|
||||
virtual void initInterfaceMatrixUpdate
|
||||
(
|
||||
Field<Type>& result,
|
||||
const bool add,
|
||||
const lduAddressing& lduAddr,
|
||||
const label patchId,
|
||||
const Field<Type>& psiInternal,
|
||||
const scalarField& coeffs,
|
||||
const Pstream::commsTypes commsType
|
||||
) const;
|
||||
|
||||
//- Update result field based on interface functionality
|
||||
virtual void updateInterfaceMatrix
|
||||
(
|
||||
@ -236,7 +322,7 @@ public:
|
||||
);
|
||||
|
||||
|
||||
// Cyclic AMI coupled interface functions
|
||||
// Coupled interface functions
|
||||
|
||||
//- Does the patch field perform the transformation
|
||||
virtual bool doTransform() const
|
||||
|
@ -26,8 +26,11 @@ License
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "cyclicAMIFvPatchFields.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
#include "cyclicAMIPolyPatch.H"
|
||||
#include "mapDistributeBase.H"
|
||||
#include "AMIInterpolation.H"
|
||||
#include "volFields.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
|
@ -25,8 +25,8 @@ License
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef cyclicAMIFvPatchFields_H
|
||||
#define cyclicAMIFvPatchFields_H
|
||||
#ifndef Foam_cyclicAMIFvPatchFields_H
|
||||
#define Foam_cyclicAMIFvPatchFields_H
|
||||
|
||||
#include "cyclicAMIFvPatchField.H"
|
||||
#include "fieldTypes.H"
|
||||
|
@ -762,25 +762,27 @@ bool Foam::AMIInterpolation::calculate
|
||||
|
||||
if (srcTotalSize == 0)
|
||||
{
|
||||
DebugInfo<< "AMI: no source faces present - no addressing constructed"
|
||||
DebugInfo
|
||||
<< "AMI: no source faces present - no addressing constructed"
|
||||
<< endl;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Info<< indent
|
||||
<< "AMI: Patch source faces: " << srcTotalSize << nl
|
||||
<< "AMI: Patch target faces: " << tgtTotalSize << endl;
|
||||
|
||||
singlePatchProc_ = calcDistribution(srcPatch, tgtPatch);
|
||||
|
||||
if (debug)
|
||||
Info<< indent << "AMI: Patch source faces: " << srcTotalSize << nl
|
||||
<< indent << "AMI: Patch target faces: " << tgtTotalSize << nl;
|
||||
|
||||
if (distributed())
|
||||
{
|
||||
Info<< "AMIInterpolation:" << nl
|
||||
<< " singlePatchProc:" << singlePatchProc_ << nl
|
||||
<< endl;
|
||||
Info<< indent << "AMI: distributed" << endl;
|
||||
}
|
||||
|
||||
DebugInfo
|
||||
<< "AMI: patch proc:" << singlePatchProc_
|
||||
<< endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -506,6 +506,30 @@ public:
|
||||
|
||||
// Low-level
|
||||
|
||||
//- Weighted sum of contributions
|
||||
template<class Type, class CombineOp>
|
||||
static void weightedSum
|
||||
(
|
||||
const scalar lowWeightCorrection,
|
||||
const labelListList& allSlots,
|
||||
const scalarListList& allWeights,
|
||||
const scalarField& weightsSum,
|
||||
const UList<Type>& fld,
|
||||
const CombineOp& cop,
|
||||
List<Type>& result,
|
||||
const UList<Type>& defaultValues
|
||||
);
|
||||
|
||||
//- Weighted sum of contributions
|
||||
template<class Type>
|
||||
void weightedSum
|
||||
(
|
||||
const bool interpolateToSource,
|
||||
const UList<Type>& fld,
|
||||
List<Type>& result,
|
||||
const UList<Type>& defaultValues
|
||||
) const;
|
||||
|
||||
//- Interpolate from target to source with supplied op
|
||||
//- to combine existing value with remote value and weight
|
||||
template<class Type, class CombineOp>
|
||||
|
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2017 OpenFOAM Foundation
|
||||
Copyright (C) 2015-2018 OpenCFD Ltd.
|
||||
Copyright (C) 2015-2023 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -31,6 +31,78 @@ License
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
template<class Type, class CombineOp>
|
||||
void Foam::AMIInterpolation::weightedSum
|
||||
(
|
||||
const scalar lowWeightCorrection,
|
||||
const labelListList& allSlots,
|
||||
const scalarListList& allWeights,
|
||||
const scalarField& weightsSum,
|
||||
const UList<Type>& fld,
|
||||
const CombineOp& cop,
|
||||
List<Type>& result,
|
||||
const UList<Type>& defaultValues
|
||||
)
|
||||
{
|
||||
if (lowWeightCorrection > 0)
|
||||
{
|
||||
forAll(result, facei)
|
||||
{
|
||||
if (weightsSum[facei] < lowWeightCorrection)
|
||||
{
|
||||
result[facei] = defaultValues[facei];
|
||||
}
|
||||
else
|
||||
{
|
||||
const labelList& slots = allSlots[facei];
|
||||
const scalarList& weights = allWeights[facei];
|
||||
|
||||
forAll(slots, i)
|
||||
{
|
||||
cop(result[facei], facei, fld[slots[i]], weights[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
forAll(result, facei)
|
||||
{
|
||||
const labelList& slots = allSlots[facei];
|
||||
const scalarList& weights = allWeights[facei];
|
||||
|
||||
forAll(slots, i)
|
||||
{
|
||||
cop(result[facei], facei, fld[slots[i]], weights[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
void Foam::AMIInterpolation::weightedSum
|
||||
(
|
||||
const bool interpolateToSource,
|
||||
const UList<Type>& fld,
|
||||
List<Type>& result,
|
||||
const UList<Type>& defaultValues
|
||||
) const
|
||||
{
|
||||
weightedSum
|
||||
(
|
||||
lowWeightCorrection_,
|
||||
(interpolateToSource ? srcAddress_ : tgtAddress_),
|
||||
(interpolateToSource ? srcWeights_ : tgtWeights_),
|
||||
(interpolateToSource ? srcWeightsSum_ : tgtWeightsSum_),
|
||||
fld,
|
||||
multiplyWeightedOp<Type, plusEqOp<Type>>(plusEqOp<Type>()),
|
||||
result,
|
||||
defaultValues
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
template<class Type, class CombineOp>
|
||||
void Foam::AMIInterpolation::interpolateToTarget
|
||||
(
|
||||
@ -51,69 +123,43 @@ void Foam::AMIInterpolation::interpolateToTarget
|
||||
<< " supplied field = " << fld.size()
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
if (lowWeightCorrection_ > 0)
|
||||
else if
|
||||
(
|
||||
(lowWeightCorrection_ > 0)
|
||||
&& (defaultValues.size() != tgtAddress_.size())
|
||||
)
|
||||
{
|
||||
if (defaultValues.size() != tgtAddress_.size())
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Employing default values when sum of weights falls below "
|
||||
<< lowWeightCorrection_
|
||||
<< " but supplied default field size is not equal to target "
|
||||
<< "patch size" << nl
|
||||
<< " default values = " << defaultValues.size() << nl
|
||||
<< " target patch = " << tgtAddress_.size() << nl
|
||||
<< abort(FatalError);
|
||||
}
|
||||
FatalErrorInFunction
|
||||
<< "Employing default values when sum of weights falls below "
|
||||
<< lowWeightCorrection_
|
||||
<< " but supplied default field size is not equal to target "
|
||||
<< "patch size" << nl
|
||||
<< " default values = " << defaultValues.size() << nl
|
||||
<< " target patch = " << tgtAddress_.size() << nl
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
result.setSize(tgtAddress_.size());
|
||||
List<Type> work;
|
||||
|
||||
if (distributed())
|
||||
{
|
||||
const mapDistribute& map = srcMapPtr_();
|
||||
|
||||
List<Type> work(fld);
|
||||
work = fld; // deep copy
|
||||
map.distribute(work);
|
||||
|
||||
forAll(result, facei)
|
||||
{
|
||||
if (tgtWeightsSum_[facei] < lowWeightCorrection_)
|
||||
{
|
||||
result[facei] = defaultValues[facei];
|
||||
}
|
||||
else
|
||||
{
|
||||
const labelList& faces = tgtAddress_[facei];
|
||||
const scalarList& weights = tgtWeights_[facei];
|
||||
|
||||
forAll(faces, i)
|
||||
{
|
||||
cop(result[facei], facei, work[faces[i]], weights[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
forAll(result, facei)
|
||||
{
|
||||
if (tgtWeightsSum_[facei] < lowWeightCorrection_)
|
||||
{
|
||||
result[facei] = defaultValues[facei];
|
||||
}
|
||||
else
|
||||
{
|
||||
const labelList& faces = tgtAddress_[facei];
|
||||
const scalarList& weights = tgtWeights_[facei];
|
||||
|
||||
forAll(faces, i)
|
||||
{
|
||||
cop(result[facei], facei, fld[faces[i]], weights[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
weightedSum
|
||||
(
|
||||
lowWeightCorrection_,
|
||||
tgtAddress_,
|
||||
tgtWeights_,
|
||||
tgtWeightsSum_,
|
||||
(distributed() ? work : fld),
|
||||
cop,
|
||||
result,
|
||||
defaultValues
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -137,69 +183,43 @@ void Foam::AMIInterpolation::interpolateToSource
|
||||
<< " supplied field = " << fld.size()
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
if (lowWeightCorrection_ > 0)
|
||||
else if
|
||||
(
|
||||
(lowWeightCorrection_ > 0)
|
||||
&& (defaultValues.size() != srcAddress_.size())
|
||||
)
|
||||
{
|
||||
if (defaultValues.size() != srcAddress_.size())
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Employing default values when sum of weights falls below "
|
||||
<< lowWeightCorrection_
|
||||
<< " but supplied default field size is not equal to source "
|
||||
<< "patch size" << nl
|
||||
<< " default values = " << defaultValues.size() << nl
|
||||
<< " source patch = " << srcAddress_.size() << nl
|
||||
<< abort(FatalError);
|
||||
}
|
||||
FatalErrorInFunction
|
||||
<< "Employing default values when sum of weights falls below "
|
||||
<< lowWeightCorrection_
|
||||
<< " but number of default values is not equal to source "
|
||||
<< "patch size" << nl
|
||||
<< " default values = " << defaultValues.size() << nl
|
||||
<< " source patch = " << srcAddress_.size() << nl
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
result.setSize(srcAddress_.size());
|
||||
List<Type> work;
|
||||
|
||||
if (distributed())
|
||||
{
|
||||
const mapDistribute& map = tgtMapPtr_();
|
||||
|
||||
List<Type> work(fld);
|
||||
work = fld; // deep copy
|
||||
map.distribute(work);
|
||||
|
||||
forAll(result, facei)
|
||||
{
|
||||
if (srcWeightsSum_[facei] < lowWeightCorrection_)
|
||||
{
|
||||
result[facei] = defaultValues[facei];
|
||||
}
|
||||
else
|
||||
{
|
||||
const labelList& faces = srcAddress_[facei];
|
||||
const scalarList& weights = srcWeights_[facei];
|
||||
|
||||
forAll(faces, i)
|
||||
{
|
||||
cop(result[facei], facei, work[faces[i]], weights[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
forAll(result, facei)
|
||||
{
|
||||
if (srcWeightsSum_[facei] < lowWeightCorrection_)
|
||||
{
|
||||
result[facei] = defaultValues[facei];
|
||||
}
|
||||
else
|
||||
{
|
||||
const labelList& faces = srcAddress_[facei];
|
||||
const scalarList& weights = srcWeights_[facei];
|
||||
|
||||
forAll(faces, i)
|
||||
{
|
||||
cop(result[facei], facei, fld[faces[i]], weights[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
weightedSum
|
||||
(
|
||||
lowWeightCorrection_,
|
||||
srcAddress_,
|
||||
srcWeights_,
|
||||
srcWeightsSum_,
|
||||
(distributed() ? work : fld),
|
||||
cop,
|
||||
result,
|
||||
defaultValues
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2016-2021 OpenCFD Ltd.
|
||||
Copyright (C) 2016-2023 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -294,30 +294,29 @@ Foam::cyclicAMIPolyPatch::cylindricalCS() const
|
||||
if (periodicID != -1)
|
||||
{
|
||||
// Get the periodic patch
|
||||
const coupledPolyPatch& perPp
|
||||
(
|
||||
refCast<const coupledPolyPatch>
|
||||
(
|
||||
boundaryMesh()[periodicID]
|
||||
)
|
||||
);
|
||||
const coupledPolyPatch& perPp =
|
||||
refCast<const coupledPolyPatch>(boundaryMesh()[periodicID]);
|
||||
|
||||
if (!perPp.parallel())
|
||||
{
|
||||
vector axis(Zero);
|
||||
point axisPoint(Zero);
|
||||
if (isA<cyclicPolyPatch>(perPp))
|
||||
|
||||
if
|
||||
(
|
||||
const cyclicPolyPatch* cpp = isA<cyclicPolyPatch>(perPp)
|
||||
)
|
||||
{
|
||||
axis =
|
||||
refCast<const cyclicPolyPatch>(perPp).rotationAxis();
|
||||
axisPoint =
|
||||
refCast<const cyclicPolyPatch>(perPp).rotationCentre();
|
||||
axis = cpp->rotationAxis();
|
||||
axisPoint = cpp->rotationCentre();
|
||||
}
|
||||
else if (isA<cyclicAMIPolyPatch>(perPp))
|
||||
else if
|
||||
(
|
||||
const cyclicAMIPolyPatch* cpp = isA<cyclicAMIPolyPatch>(perPp)
|
||||
)
|
||||
{
|
||||
axis =
|
||||
refCast<const cyclicAMIPolyPatch>(perPp).rotationAxis();
|
||||
axisPoint =
|
||||
refCast<const cyclicAMIPolyPatch>(perPp).rotationCentre();
|
||||
axis = cpp->rotationAxis();
|
||||
axisPoint = cpp->rotationCentre();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2018-2021 OpenCFD Ltd.
|
||||
Copyright (C) 2018-2023 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -47,9 +47,10 @@ SourceFiles
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef cyclicAMIPolyPatch_H
|
||||
#define cyclicAMIPolyPatch_H
|
||||
#ifndef Foam_cyclicAMIPolyPatch_H
|
||||
#define Foam_cyclicAMIPolyPatch_H
|
||||
|
||||
#include "AMIInterpolation.H"
|
||||
#include "coupledPolyPatch.H"
|
||||
#include "AMIPatchToPatchInterpolation.H"
|
||||
#include "polyBoundaryMesh.H"
|
||||
@ -87,7 +88,7 @@ class cyclicAMIPolyPatch
|
||||
|
||||
protected:
|
||||
|
||||
// Protected data
|
||||
// Protected Data
|
||||
|
||||
//- Name of other half
|
||||
mutable word nbrPatchName_;
|
||||
@ -286,7 +287,7 @@ public:
|
||||
}
|
||||
|
||||
//- Construct and return a clone, resetting the face list
|
||||
// and boundary mesh
|
||||
//- and boundary mesh
|
||||
virtual autoPtr<polyPatch> clone
|
||||
(
|
||||
const polyBoundaryMesh& bm,
|
||||
@ -467,7 +468,7 @@ public:
|
||||
) const;
|
||||
|
||||
//- Transform a patch-based direction from this side to
|
||||
// nbr side
|
||||
//- nbr side
|
||||
virtual void reverseTransformDirection
|
||||
(
|
||||
vector& d,
|
||||
@ -512,6 +513,38 @@ public:
|
||||
) const;
|
||||
|
||||
|
||||
// Interpolations (non-blocking). Subject to change
|
||||
|
||||
template<class Type>
|
||||
void initInterpolateUntransformed
|
||||
(
|
||||
const Field<Type>& fld,
|
||||
labelRange& sendRequests,
|
||||
PtrList<List<Type>>& sendBuffers,
|
||||
labelRange& recvRequests,
|
||||
PtrList<List<Type>>& recvBuffers
|
||||
) const;
|
||||
|
||||
template<class Type>
|
||||
void initInterpolate
|
||||
(
|
||||
const Field<Type>& fld,
|
||||
labelRange& sendRequests,
|
||||
PtrList<List<Type>>& sendBuffers,
|
||||
labelRange& recvRequests,
|
||||
PtrList<List<Type>>& recvBuffers
|
||||
) const;
|
||||
|
||||
template<class Type>
|
||||
tmp<Field<Type>> interpolate
|
||||
(
|
||||
const Field<Type>& localFld,
|
||||
const labelRange& requests, // The receive requests
|
||||
const PtrList<List<Type>>& recvBuffers,
|
||||
const UList<Type>& defaultValues
|
||||
) const;
|
||||
|
||||
|
||||
//- Calculate the patch geometry
|
||||
virtual void calcGeometry
|
||||
(
|
||||
|
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2021 OpenCFD Ltd.
|
||||
Copyright (C) 2021-2023 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -53,96 +53,96 @@ Foam::tmp<Foam::Field<Type>> Foam::cyclicAMIPolyPatch::interpolate
|
||||
const UList<Type>& defaultValues
|
||||
) const
|
||||
{
|
||||
if (pTraits<Type>::rank == 0)
|
||||
autoPtr<coordSystem::cylindrical> cs;
|
||||
|
||||
// Similar to doTransform.
|
||||
// - could also check if !std::is_same<sphericalTensor, Type>:value
|
||||
|
||||
if (is_vectorspace<Type>::value)
|
||||
{
|
||||
cs.reset(cylindricalCS());
|
||||
}
|
||||
|
||||
if (!cs)
|
||||
{
|
||||
return interpolateUntransformed(fld, defaultValues);
|
||||
}
|
||||
else
|
||||
{
|
||||
autoPtr<coordSystem::cylindrical> cs(cylindricalCS());
|
||||
if (!cs)
|
||||
{
|
||||
return interpolateUntransformed(fld, defaultValues);
|
||||
}
|
||||
else
|
||||
{
|
||||
const cyclicAMIPolyPatch& nbrPp = this->neighbPatch();
|
||||
const cyclicAMIPolyPatch& nbrPp = this->neighbPatch();
|
||||
|
||||
if (debug)
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "cyclicAMIPolyPatch::interpolate :"
|
||||
<< " patch:" << this->name()
|
||||
<< " size:" << this->size()
|
||||
<< " nbrPatch:" << nbrPp.name()
|
||||
<< " size:" << nbrPp.size()
|
||||
<< endl;
|
||||
}
|
||||
|
||||
if (fld.size() != nbrPp.size())
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Patch:" << this->name()
|
||||
<< " size:" << this->size()
|
||||
<< " neighbour patch:" << nbrPp.name()
|
||||
<< " size:" << nbrPp.size()
|
||||
<< " fld size:" << fld.size()
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
|
||||
Field<Type> localFld(fld.size());
|
||||
|
||||
// Transform to cylindrical coords
|
||||
{
|
||||
const tensorField nbrT(cs().R(nbrPp.faceCentres()));
|
||||
Foam::invTransform(localFld, nbrT, fld);
|
||||
}
|
||||
|
||||
if (debug&2)
|
||||
{
|
||||
const vectorField::subField nbrFc(nbrPp.faceCentres());
|
||||
|
||||
Pout<< "On patch:" << this->name()
|
||||
<< " size:" << this->size()
|
||||
<< " fc:" << gAverage(this->faceCentres())
|
||||
<< " getting remote data from:" << nbrPp.name()
|
||||
<< " size:" << nbrPp.size()
|
||||
<< " fc:" << gAverage(nbrFc)
|
||||
<< endl;
|
||||
|
||||
forAll(fld, i)
|
||||
{
|
||||
Pout<< "cyclicAMIPolyPatch::interpolate :"
|
||||
<< " patch:" << this->name()
|
||||
<< " size:" << this->size()
|
||||
<< " nbrPatch:" << nbrPp.name()
|
||||
<< " size:" << nbrPp.size()
|
||||
Pout<< "At:" << nbrFc[i] << nl
|
||||
<< " cart:" << fld[i] << nl
|
||||
<< " cyli:" << localFld[i] << nl
|
||||
<< endl;
|
||||
}
|
||||
|
||||
if (fld.size() != nbrPp.size())
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Patch:" << this->name()
|
||||
<< " size:" << this->size()
|
||||
<< " neighbour patch:" << nbrPp.name()
|
||||
<< " size:" << nbrPp.size()
|
||||
<< " fld size:" << fld.size()
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
|
||||
auto tlocalFld(tmp<Field<Type>>::New(fld.size()));
|
||||
Field<Type>& localFld = tlocalFld.ref();
|
||||
|
||||
// Transform to cylindrical coords
|
||||
{
|
||||
tmp<tensorField> nbrT(cs().R(nbrPp.faceCentres()));
|
||||
localFld = Foam::invTransform(nbrT(), fld);
|
||||
}
|
||||
|
||||
if (debug&2)
|
||||
{
|
||||
const vectorField::subField nbrFc(nbrPp.faceCentres());
|
||||
|
||||
Pout<< "On patch:" << this->name()
|
||||
<< " size:" << this->size()
|
||||
<< " fc:" << gAverage(this->faceCentres())
|
||||
<< " getting remote data from:" << nbrPp.name()
|
||||
<< " size:" << nbrPp.size()
|
||||
<< " fc:" << gAverage(nbrFc)
|
||||
<< endl;
|
||||
|
||||
forAll(fld, i)
|
||||
{
|
||||
Pout<< "At:" << nbrFc[i] << nl
|
||||
<< " cart:" << fld[i] << nl
|
||||
<< " cyli:" << localFld[i] << nl
|
||||
<< endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const tmp<tensorField> T(cs().R(this->faceCentres()));
|
||||
|
||||
List<Type> localDeflt(defaultValues.size());
|
||||
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);
|
||||
localDeflt = Foam::invTransform(T(), defaultFld);
|
||||
}
|
||||
|
||||
// Do the actual interpolation and interpolate back to cartesian
|
||||
// coords
|
||||
return Foam::transform
|
||||
(
|
||||
T,
|
||||
interpolateUntransformed(localFld, localDeflt)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
const tensorField ownT(cs().R(this->faceCentres()));
|
||||
|
||||
Field<Type> localDeflt(defaultValues.size());
|
||||
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, ownT, defaultFld);
|
||||
}
|
||||
|
||||
// Do the actual interpolation and interpolate back to cartesian
|
||||
return Foam::transform
|
||||
(
|
||||
ownT,
|
||||
interpolateUntransformed(localFld, localDeflt)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -158,6 +158,160 @@ Foam::tmp<Foam::Field<Type>> Foam::cyclicAMIPolyPatch::interpolate
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
void Foam::cyclicAMIPolyPatch::initInterpolateUntransformed
|
||||
(
|
||||
const Field<Type>& fld,
|
||||
labelRange& sendRequests,
|
||||
PtrList<List<Type>>& sendBuffers,
|
||||
labelRange& recvRequests,
|
||||
PtrList<List<Type>>& recvBuffers
|
||||
) const
|
||||
{
|
||||
const auto& AMI = (owner() ? this->AMI() : neighbPatch().AMI());
|
||||
|
||||
if (AMI.distributed())
|
||||
{
|
||||
const auto& map = (owner() ? AMI.tgtMap() : AMI.srcMap());
|
||||
|
||||
// Insert send/receive requests (non-blocking)
|
||||
map.send(fld, sendRequests, sendBuffers, recvRequests, recvBuffers);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
void Foam::cyclicAMIPolyPatch::initInterpolate
|
||||
(
|
||||
const Field<Type>& fld,
|
||||
labelRange& sendRequests,
|
||||
PtrList<List<Type>>& sendBuffers,
|
||||
labelRange& recvRequests,
|
||||
PtrList<List<Type>>& recvBuffers
|
||||
) const
|
||||
{
|
||||
const auto& AMI = (owner() ? this->AMI() : neighbPatch().AMI());
|
||||
|
||||
if (!AMI.distributed())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
autoPtr<coordSystem::cylindrical> cs;
|
||||
|
||||
if (is_vectorspace<Type>::value)
|
||||
{
|
||||
cs.reset(cylindricalCS());
|
||||
}
|
||||
|
||||
if (!cs)
|
||||
{
|
||||
initInterpolateUntransformed
|
||||
(
|
||||
fld,
|
||||
sendRequests,
|
||||
sendBuffers,
|
||||
recvRequests,
|
||||
recvBuffers
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
const cyclicAMIPolyPatch& nbrPp = this->neighbPatch();
|
||||
|
||||
Field<Type> localFld(fld.size());
|
||||
|
||||
// Transform to cylindrical coords
|
||||
{
|
||||
const tensorField nbrT(cs().R(nbrPp.faceCentres()));
|
||||
Foam::invTransform(localFld, nbrT, fld);
|
||||
}
|
||||
|
||||
initInterpolateUntransformed
|
||||
(
|
||||
localFld,
|
||||
sendRequests,
|
||||
sendBuffers,
|
||||
recvRequests,
|
||||
recvBuffers
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::Field<Type>> Foam::cyclicAMIPolyPatch::interpolate
|
||||
(
|
||||
const Field<Type>& localFld,
|
||||
const labelRange& requests,
|
||||
const PtrList<List<Type>>& recvBuffers,
|
||||
const UList<Type>& defaultValues
|
||||
) const
|
||||
{
|
||||
const auto& AMI = (owner() ? this->AMI() : neighbPatch().AMI());
|
||||
const auto& map = (owner() ? AMI.tgtMap() : AMI.srcMap());
|
||||
|
||||
Field<Type> work;
|
||||
if (AMI.distributed())
|
||||
{
|
||||
// Receive (= copy) data from buffers into work. TBD: receive directly
|
||||
// into slices of work.
|
||||
map.receive(requests, recvBuffers, work);
|
||||
}
|
||||
const Field<Type>& fld = (AMI.distributed() ? work : localFld);
|
||||
|
||||
auto tresult = tmp<Field<Type>>::New(this->size(), Zero);
|
||||
|
||||
// Note: tresult is optionally in transformed coord system
|
||||
autoPtr<coordSystem::cylindrical> cs;
|
||||
|
||||
if (is_vectorspace<Type>::value)
|
||||
{
|
||||
cs.reset(cylindricalCS());
|
||||
}
|
||||
|
||||
if (!cs)
|
||||
{
|
||||
AMI.weightedSum
|
||||
(
|
||||
owner(),
|
||||
fld,
|
||||
tresult.ref(),
|
||||
defaultValues
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
const tensorField ownT(cs().R(this->faceCentres()));
|
||||
|
||||
Field<Type> localDeflt(defaultValues.size());
|
||||
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, ownT, defaultFld);
|
||||
}
|
||||
|
||||
AMI.weightedSum
|
||||
(
|
||||
owner(),
|
||||
fld,
|
||||
tresult.ref(),
|
||||
localDeflt
|
||||
);
|
||||
|
||||
// Transform back
|
||||
Foam::transform(tresult.ref(), ownT, tresult());
|
||||
}
|
||||
|
||||
return tresult;
|
||||
}
|
||||
|
||||
|
||||
template<class Type, class CombineOp>
|
||||
void Foam::cyclicAMIPolyPatch::interpolate
|
||||
(
|
||||
@ -168,26 +322,37 @@ void Foam::cyclicAMIPolyPatch::interpolate
|
||||
) const
|
||||
{
|
||||
//- Commented out for now since called with non-primitives (e.g. wallPoint
|
||||
// from FaceCellWave) - these are missing the pTraits<Type>::rank and
|
||||
// Foam::transform
|
||||
// from FaceCellWave) - missing Foam::transform, Foam::invTransform
|
||||
/*
|
||||
autoPtr<coordSystem::cylindrical> cs(cylindricalCS());
|
||||
autoPtr<coordSystem::cylindrical> cs;
|
||||
|
||||
if (cs && pTraits<Type>::rank > 0)
|
||||
if (is_vectorspace<Type>::value)
|
||||
{
|
||||
cs.reset(cylindricalCS());
|
||||
}
|
||||
|
||||
if (cs)
|
||||
{
|
||||
const cyclicAMIPolyPatch& nbrPp = this->neighbPatch();
|
||||
|
||||
tmp<tensorField> nbrT(cs().R(nbrPp.faceCentres()));
|
||||
|
||||
result = Foam::invTransform(nbrT, result);
|
||||
List<Type> localDeflt(defaultValues.size());
|
||||
if (defaultValues.size() == nbrT().size())
|
||||
// Transform to cylindrical coords
|
||||
{
|
||||
const tensorField nbrT(cs().R(nbrPp.faceCentres()));
|
||||
Foam::invTransform(result, nbrT, result);
|
||||
}
|
||||
|
||||
const tensorField ownT(cs().R(this->faceCentres()));
|
||||
|
||||
Field<Type> localDeflt(defaultValues.size());
|
||||
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);
|
||||
localDeflt = Foam::invTransform(nbrT, defaultFld);
|
||||
Foam::invTransform(localDeflt, ownT, defaultFld);
|
||||
}
|
||||
|
||||
// Do actual AMI interpolation
|
||||
@ -213,8 +378,7 @@ void Foam::cyclicAMIPolyPatch::interpolate
|
||||
}
|
||||
|
||||
// Transform back. Result is now at *this
|
||||
const vectorField::subField fc(this->faceCentres());
|
||||
result = Foam::transform(cs().R(fc), result);
|
||||
Foam::transform(result, ownT, result);
|
||||
}
|
||||
else
|
||||
*/
|
||||
|
93
tutorials/basic/laplacianFoam/implicitAMI-nonblocking/0/T
Normal file
93
tutorials/basic/laplacianFoam/implicitAMI-nonblocking/0/T
Normal file
@ -0,0 +1,93 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v2312 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class volScalarField;
|
||||
object T;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
dimensions [0 0 0 1 0 0 0];
|
||||
|
||||
internalField uniform 0;
|
||||
|
||||
boundaryField
|
||||
{
|
||||
cyclicAMI
|
||||
{
|
||||
type cyclicAMI;
|
||||
value $internalField;
|
||||
}
|
||||
|
||||
// solid1
|
||||
solid1_top
|
||||
{
|
||||
type uniformFixedValue;
|
||||
uniformValue 1;
|
||||
}
|
||||
solid1_left
|
||||
{
|
||||
type zeroGradient;
|
||||
}
|
||||
solid1_right
|
||||
{
|
||||
type zeroGradient;
|
||||
}
|
||||
|
||||
// solid2
|
||||
solid2_left
|
||||
{
|
||||
type zeroGradient;
|
||||
}
|
||||
solid2_right
|
||||
{
|
||||
type zeroGradient;
|
||||
}
|
||||
solid2_bottom
|
||||
{
|
||||
type uniformFixedValue;
|
||||
uniformValue 0;
|
||||
}
|
||||
|
||||
|
||||
// solid1
|
||||
solid1_b_top
|
||||
{
|
||||
type uniformFixedValue;
|
||||
uniformValue 1;
|
||||
}
|
||||
solid1_b_left
|
||||
{
|
||||
type zeroGradient;
|
||||
}
|
||||
solid1_b_right
|
||||
{
|
||||
type zeroGradient;
|
||||
}
|
||||
|
||||
|
||||
// solid2
|
||||
solid2_b_left
|
||||
{
|
||||
type zeroGradient;
|
||||
}
|
||||
solid2_b_right
|
||||
{
|
||||
type zeroGradient;
|
||||
}
|
||||
solid2_b_bottom
|
||||
{
|
||||
type uniformFixedValue;
|
||||
uniformValue 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
14
tutorials/basic/laplacianFoam/implicitAMI-nonblocking/Allrun
Executable file
14
tutorials/basic/laplacianFoam/implicitAMI-nonblocking/Allrun
Executable file
@ -0,0 +1,14 @@
|
||||
#!/bin/sh
|
||||
cd "${0%/*}" || exit # Run from this directory
|
||||
. ${WM_PROJECT_DIR:?}/bin/tools/RunFunctions # Tutorial run functions
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
# restore0Dir
|
||||
|
||||
runApplication blockMesh
|
||||
|
||||
runApplication decomposePar
|
||||
|
||||
runParallel $(getApplication)
|
||||
|
||||
#------------------------------------------------------------------------------
|
@ -0,0 +1,21 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v2306 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
location "constant";
|
||||
object transportProperties;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
DT 4e-05;
|
||||
|
||||
|
||||
// ************************************************************************* //
|
@ -0,0 +1,269 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v2312 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
object blockMeshDict;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
scale 1;
|
||||
|
||||
vertices
|
||||
(
|
||||
// solid1
|
||||
(-0.1 0.00 -0.05)
|
||||
( 0.1 0.00 -0.05)
|
||||
( 0.1 0.04 -0.05)
|
||||
(-0.1 0.04 -0.05)
|
||||
(-0.1 0.00 0.05)
|
||||
( 0.1 0.00 0.05)
|
||||
( 0.1 0.04 0.05)
|
||||
(-0.1 0.04 0.05)
|
||||
|
||||
|
||||
// solid2
|
||||
(-0.1 -0.04 -0.05)
|
||||
( 0.1 -0.04 -0.05)
|
||||
( 0.1 0.00 -0.05)
|
||||
(-0.1 0.00 -0.05)
|
||||
(-0.1 -0.04 0.05)
|
||||
( 0.1 -0.04 0.05)
|
||||
( 0.1 0.00 0.05)
|
||||
(-0.1 0.00 0.05)
|
||||
|
||||
// solid1_b
|
||||
( 0.2 0.00 -0.05)
|
||||
( 0.4 0.00 -0.05)
|
||||
( 0.4 0.04 -0.05)
|
||||
( 0.2 0.04 -0.05)
|
||||
( 0.2 0.00 0.05)
|
||||
( 0.4 0.00 0.05)
|
||||
( 0.4 0.04 0.05)
|
||||
( 0.2 0.04 0.05)
|
||||
|
||||
|
||||
// solid2_b
|
||||
( 0.2 -0.04 -0.05)
|
||||
( 0.4 -0.04 -0.05)
|
||||
( 0.4 0.00 -0.05)
|
||||
( 0.2 0.00 -0.05)
|
||||
( 0.2 -0.04 0.05)
|
||||
( 0.4 -0.04 0.05)
|
||||
( 0.4 0.00 0.05)
|
||||
( 0.2 0.00 0.05)
|
||||
);
|
||||
|
||||
blocks
|
||||
(
|
||||
hex (0 1 2 3 4 5 6 7) solid1 (5 10 1) simpleGrading (1 1 1)
|
||||
hex (8 9 10 11 12 13 14 15) solid2 (4 10 1) simpleGrading (1 1 1)
|
||||
|
||||
hex (16 17 18 19 20 21 22 23) solid1_b (3 7 1) simpleGrading (1 1 1)
|
||||
hex (24 25 26 27 28 29 30 31) solid2_b (7 7 1) simpleGrading (1 1 1)
|
||||
);
|
||||
|
||||
edges
|
||||
(
|
||||
);
|
||||
|
||||
boundary
|
||||
(
|
||||
solid1_bottom
|
||||
{
|
||||
type cyclicAMI;
|
||||
inGroups (coupleGroup);
|
||||
coupleGroup coupleGroup;
|
||||
faces
|
||||
(
|
||||
(1 5 4 0)
|
||||
);
|
||||
}
|
||||
solid1_top
|
||||
{
|
||||
type wall;
|
||||
faces
|
||||
(
|
||||
(3 7 6 2)
|
||||
);
|
||||
}
|
||||
solid1_left
|
||||
{
|
||||
type wall;
|
||||
faces
|
||||
(
|
||||
(0 4 7 3)
|
||||
);
|
||||
}
|
||||
solid1_right
|
||||
{
|
||||
type wall;
|
||||
faces
|
||||
(
|
||||
(2 6 5 1)
|
||||
);
|
||||
}
|
||||
solid1_frontAndBack
|
||||
{
|
||||
type empty;
|
||||
faces
|
||||
(
|
||||
(0 3 2 1)
|
||||
(4 5 6 7)
|
||||
);
|
||||
}
|
||||
|
||||
solid2_bottom
|
||||
{
|
||||
type wall;
|
||||
faces
|
||||
(
|
||||
(9 13 12 8)
|
||||
);
|
||||
}
|
||||
solid2_top
|
||||
{
|
||||
type cyclicAMI;
|
||||
inGroups (coupleGroup);
|
||||
coupleGroup coupleGroup;
|
||||
|
||||
faces
|
||||
(
|
||||
(11 15 14 10)
|
||||
);
|
||||
}
|
||||
solid2_left
|
||||
{
|
||||
type wall;
|
||||
faces
|
||||
(
|
||||
(8 12 15 11)
|
||||
);
|
||||
}
|
||||
solid2_right
|
||||
{
|
||||
type wall;
|
||||
faces
|
||||
(
|
||||
(10 14 13 9)
|
||||
);
|
||||
}
|
||||
|
||||
solid2_frontAndBack
|
||||
{
|
||||
type empty;
|
||||
faces
|
||||
(
|
||||
(8 11 10 9)
|
||||
(12 13 14 15)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// block b
|
||||
// ~~~~~~~
|
||||
|
||||
solid1_b_bottom
|
||||
{
|
||||
type cyclicAMI;
|
||||
inGroups (coupleGroup_b);
|
||||
coupleGroup coupleGroup_b;
|
||||
faces
|
||||
(
|
||||
(17 21 20 16)
|
||||
);
|
||||
}
|
||||
solid1_b_top
|
||||
{
|
||||
type wall;
|
||||
faces
|
||||
(
|
||||
(19 23 22 18)
|
||||
);
|
||||
}
|
||||
solid1_b_left
|
||||
{
|
||||
type wall;
|
||||
faces
|
||||
(
|
||||
(16 20 23 19)
|
||||
);
|
||||
}
|
||||
solid1_b_right
|
||||
{
|
||||
type wall;
|
||||
faces
|
||||
(
|
||||
(18 22 21 17)
|
||||
);
|
||||
}
|
||||
solid1_b_frontAndBack
|
||||
{
|
||||
type empty;
|
||||
faces
|
||||
(
|
||||
(16 19 18 17)
|
||||
(20 21 22 23)
|
||||
);
|
||||
}
|
||||
|
||||
solid2_b_bottom
|
||||
{
|
||||
type wall;
|
||||
faces
|
||||
(
|
||||
//(9 13 12 8)
|
||||
(25 29 28 24)
|
||||
);
|
||||
}
|
||||
solid2_b_top
|
||||
{
|
||||
type cyclicAMI;
|
||||
inGroups (coupleGroup_b);
|
||||
coupleGroup coupleGroup_b;
|
||||
|
||||
faces
|
||||
(
|
||||
//(11 15 14 10)
|
||||
(27 31 30 26)
|
||||
);
|
||||
}
|
||||
solid2_b_left
|
||||
{
|
||||
type wall;
|
||||
faces
|
||||
(
|
||||
//(8 12 15 11)
|
||||
(24 28 31 27)
|
||||
);
|
||||
}
|
||||
solid2_b_right
|
||||
{
|
||||
type wall;
|
||||
faces
|
||||
(
|
||||
//(10 14 13 9)
|
||||
(26 30 29 25)
|
||||
);
|
||||
}
|
||||
solid2_b_frontAndBack
|
||||
{
|
||||
type empty;
|
||||
faces
|
||||
(
|
||||
//(8 11 10 9)
|
||||
(24 27 26 25)
|
||||
//(12 13 14 15)
|
||||
(28 29 30 31)
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
// ************************************************************************* //
|
@ -0,0 +1,50 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v2312 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
location "system";
|
||||
object controlDict;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
application laplacianFoam;
|
||||
|
||||
startFrom latestTime;
|
||||
|
||||
startTime 0;
|
||||
|
||||
stopAt endTime;
|
||||
|
||||
endTime 2;
|
||||
|
||||
deltaT 1;
|
||||
|
||||
//writeControl runTime;
|
||||
//writeInterval 0.1;
|
||||
writeControl timeStep;
|
||||
writeInterval 1;
|
||||
|
||||
purgeWrite 0;
|
||||
|
||||
writeFormat ascii;
|
||||
|
||||
writePrecision 6;
|
||||
|
||||
writeCompression off;
|
||||
|
||||
timeFormat general;
|
||||
|
||||
timePrecision 6;
|
||||
|
||||
runTimeModifiable true;
|
||||
|
||||
|
||||
// ************************************************************************* //
|
@ -0,0 +1,26 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v2312 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
object decomposeParDict;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
//- The total number of domains (mandatory)
|
||||
numberOfSubdomains 4;
|
||||
|
||||
//- The decomposition method (mandatory)
|
||||
method hierarchical;
|
||||
n (4 1 1);
|
||||
|
||||
// NOTE: no patch constraints!
|
||||
|
||||
// ************************************************************************* //
|
@ -0,0 +1,52 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v2312 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
location "system";
|
||||
object fvSchemes;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
ddtSchemes
|
||||
{
|
||||
default steadyState; //Euler;
|
||||
}
|
||||
|
||||
gradSchemes
|
||||
{
|
||||
default Gauss linear;
|
||||
grad(T) Gauss linear;
|
||||
}
|
||||
|
||||
divSchemes
|
||||
{
|
||||
default none;
|
||||
}
|
||||
|
||||
laplacianSchemes
|
||||
{
|
||||
default none;
|
||||
laplacian(DT,T) Gauss linear corrected;
|
||||
laplacian(DTV,T) Gauss linear corrected;
|
||||
}
|
||||
|
||||
interpolationSchemes
|
||||
{
|
||||
default linear;
|
||||
}
|
||||
|
||||
snGradSchemes
|
||||
{
|
||||
default corrected;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
@ -0,0 +1,35 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v2312 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
location "system";
|
||||
object fvSolution;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
solvers
|
||||
{
|
||||
T
|
||||
{
|
||||
solver PCG;
|
||||
preconditioner DIC;
|
||||
tolerance 1e-06;
|
||||
relTol 0;
|
||||
}
|
||||
}
|
||||
|
||||
SIMPLE
|
||||
{
|
||||
nNonOrthogonalCorrectors 2;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
Loading…
Reference in New Issue
Block a user