ENH: overset: insert remote interpolation into lduMatrix
All remote contributions to interpolation stencils now get added as 'processor' type lduInterfaces. This guarantees a consistent matrix, e.g. initial residual is normalised to 1. Second change is the normalisation of the interpolation discretisation which uses the diagonal from the unmodified equation. This helps GAMG.
This commit is contained in:
parent
c924a3639c
commit
912009c458
@ -69,7 +69,7 @@ void printInfo(const sliceCoeffs& coeffs)
|
||||
|
||||
const auto endIter = range.cend();
|
||||
|
||||
for (const label i : {-1, (range.size()/2), range.size()})
|
||||
for (const label i : {label(-1), (range.size()/2), range.size()})
|
||||
{
|
||||
const auto iter = range.at(i);
|
||||
|
||||
|
@ -13,23 +13,27 @@ dynamicOversetFvMesh/dynamicOversetFvMesh.C
|
||||
fvMeshPrimitiveLduAddressing/fvMeshPrimitiveLduAddressing.C
|
||||
|
||||
oversetPolyPatch/oversetPolyPatch.C
|
||||
oversetPolyPatch/oversetLduInterface.C
|
||||
oversetPolyPatch/oversetFvPatch.C
|
||||
oversetPolyPatch/oversetFvPatchFields.C
|
||||
oversetPolyPatch/oversetFvsPatchFields.C
|
||||
oversetPolyPatch/oversetGAMGInterface.C
|
||||
oversetPolyPatch/oversetGAMGInterfaceField.C
|
||||
oversetPolyPatch/oversetPointPatch.C
|
||||
oversetPolyPatch/oversetPointPatchFields.C
|
||||
|
||||
/*
|
||||
oversetPolyPatch/semiImplicitOversetFvPatchFields.C
|
||||
oversetPolyPatch/oversetLduInterface.C
|
||||
oversetPolyPatch/oversetGAMGInterface.C
|
||||
oversetPolyPatch/oversetGAMGInterfaceField.C
|
||||
oversetPolyPatch/semiImplicitOversetGAMGInterfaceField.C
|
||||
*/
|
||||
|
||||
oversetAdjustPhi/oversetAdjustPhi.C
|
||||
|
||||
regionsToCell/regionsToCell.C
|
||||
|
||||
lduPrimitiveProcessorInterface/lduPrimitiveProcessorInterface.C
|
||||
|
||||
lduPrimitiveProcessorInterface/calculatedProcessorFvPatchFields.C
|
||||
lduPrimitiveProcessorInterface/GAMG/calculatedProcessorGAMGInterface.C
|
||||
lduPrimitiveProcessorInterface/GAMG/calculatedProcessorGAMGInterfaceField.C
|
||||
|
||||
LIB = $(FOAM_LIBBIN)/liboverset
|
||||
|
@ -91,41 +91,168 @@ bool Foam::dynamicOversetFvMesh::updateAddressing() const
|
||||
<< " nExtraFaces:" << nExtraFaces << endl;
|
||||
}
|
||||
|
||||
// Extract relevant remote processors
|
||||
labelList nbrProcs(localFaceCells.size());
|
||||
|
||||
// Now for the tricky bits. We want to hand out processor faces according
|
||||
// to the localFaceCells/remoteFaceCells. Ultimately we need
|
||||
// per entry in stencil:
|
||||
// - the patch (or -1 for internal faces)
|
||||
// - the face (is either an internal face index or a patch face index)
|
||||
|
||||
stencilPatches_.setSize(stencilFaces_.size());
|
||||
|
||||
// Per processor to owner (local)/neighbour (remote)
|
||||
List<DynamicList<label>> procOwner(Pstream::nProcs());
|
||||
List<DynamicList<label>> dynProcNeighbour(Pstream::nProcs());
|
||||
forAll(stencil, celli)
|
||||
{
|
||||
label nbrI = 0;
|
||||
forAll(localFaceCells, procI)
|
||||
const labelList& nbrs = stencil[celli];
|
||||
stencilPatches_[celli].setSize(nbrs.size(), -1);
|
||||
|
||||
forAll(nbrs, nbri)
|
||||
{
|
||||
if (localFaceCells[procI].size())
|
||||
const label nbrCelli = nbrs[nbri];
|
||||
if (stencilFaces_[celli][nbri] == -1)
|
||||
{
|
||||
//Pout<< " from proc:" << procI
|
||||
// << " want its local cells " << remoteFaceCells[procI]
|
||||
// << " to add to my local cells:" << localFaceCells[procI]
|
||||
// << endl;
|
||||
nbrProcs[nbrI++] = procI;
|
||||
label globalNbr = globalCellIDs[nbrCelli];
|
||||
label proci = globalNumbering.whichProcID(globalNbr);
|
||||
label remoteCelli = globalNumbering.toLocal(proci, globalNbr);
|
||||
|
||||
// Overwrite the face to be a patch face
|
||||
stencilFaces_[celli][nbri] = procOwner[proci].size();
|
||||
stencilPatches_[celli][nbri] = proci;
|
||||
procOwner[proci].append(celli);
|
||||
dynProcNeighbour[proci].append(remoteCelli);
|
||||
|
||||
//Pout<< "From neighbour proc:" << proci
|
||||
// << " allocating patchFace:" << stencilFaces_[celli][nbri]
|
||||
// << " to get remote cell " << remoteCelli
|
||||
// << " onto local cell " << celli << endl;
|
||||
}
|
||||
}
|
||||
nbrProcs.setSize(nbrI);
|
||||
}
|
||||
labelListList procNeighbour(dynProcNeighbour.size());
|
||||
forAll(procNeighbour, i)
|
||||
{
|
||||
procNeighbour[i] = std::move(dynProcNeighbour[i]);
|
||||
}
|
||||
labelListList mySendCells;
|
||||
Pstream::exchange<labelList, label>(procNeighbour, mySendCells);
|
||||
|
||||
label nbri = 0;
|
||||
forAll(procOwner, proci)
|
||||
{
|
||||
if (procOwner[proci].size())
|
||||
{
|
||||
nbri++;
|
||||
}
|
||||
if (mySendCells[proci].size())
|
||||
{
|
||||
nbri++;
|
||||
}
|
||||
}
|
||||
remoteStencilInterfaces_.setSize(nbri);
|
||||
nbri = 0;
|
||||
|
||||
// E.g. if proc1 needs some data from proc2 and proc2 needs some data from
|
||||
// proc1. We first want the pair : proc1 receive and proc2 send
|
||||
// and then the pair : proc1 send, proc2 receive
|
||||
|
||||
|
||||
labelList procToInterface(Pstream::nProcs(), -1);
|
||||
|
||||
forAll(procOwner, proci)
|
||||
{
|
||||
if (proci < Pstream::myProcNo() && procOwner[proci].size())
|
||||
{
|
||||
//Pout<< "Adding interface " << nbri
|
||||
// << " to receive my " << procOwner[proci]
|
||||
// << " from " << proci << endl;
|
||||
|
||||
procToInterface[proci] = nbri;
|
||||
remoteStencilInterfaces_.set
|
||||
(
|
||||
nbri++,
|
||||
new lduPrimitiveProcessorInterface
|
||||
(
|
||||
procOwner[proci],
|
||||
Pstream::myProcNo(),
|
||||
proci,
|
||||
tensorField(0),
|
||||
Pstream::msgType()+2
|
||||
)
|
||||
);
|
||||
}
|
||||
else if (proci > Pstream::myProcNo() && mySendCells[proci].size())
|
||||
{
|
||||
//Pout<< "Adding interface " << nbri
|
||||
// << " to send my " << mySendCells[proci]
|
||||
// << " to " << proci << endl;
|
||||
remoteStencilInterfaces_.set
|
||||
(
|
||||
nbri++,
|
||||
new lduPrimitiveProcessorInterface
|
||||
(
|
||||
mySendCells[proci],
|
||||
Pstream::myProcNo(),
|
||||
proci,
|
||||
tensorField(0),
|
||||
Pstream::msgType()+2
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
forAll(procOwner, proci)
|
||||
{
|
||||
if (proci > Pstream::myProcNo() && procOwner[proci].size())
|
||||
{
|
||||
//Pout<< "Adding interface " << nbri
|
||||
// << " to receive my " << procOwner[proci]
|
||||
// << " from " << proci << endl;
|
||||
procToInterface[proci] = nbri;
|
||||
remoteStencilInterfaces_.set
|
||||
(
|
||||
nbri++,
|
||||
new lduPrimitiveProcessorInterface
|
||||
(
|
||||
procOwner[proci],
|
||||
Pstream::myProcNo(),
|
||||
proci,
|
||||
tensorField(0),
|
||||
Pstream::msgType()+2
|
||||
)
|
||||
);
|
||||
}
|
||||
else if (proci < Pstream::myProcNo() && mySendCells[proci].size())
|
||||
{
|
||||
//Pout<< "Adding interface " << nbri
|
||||
// << " to send my " << mySendCells[proci]
|
||||
// << " to " << proci << endl;
|
||||
remoteStencilInterfaces_.set
|
||||
(
|
||||
nbri++,
|
||||
new lduPrimitiveProcessorInterface
|
||||
(
|
||||
mySendCells[proci],
|
||||
Pstream::myProcNo(),
|
||||
proci,
|
||||
tensorField(0),
|
||||
Pstream::msgType()+2
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Construct interfaces
|
||||
remoteStencilInterfaces_.setSize(nbrProcs.size());
|
||||
forAll(nbrProcs, i)
|
||||
|
||||
// Rewrite stencilPatches now we know the actual interface (procToInterface)
|
||||
for (auto& patches : stencilPatches_)
|
||||
{
|
||||
label procI = nbrProcs[i];
|
||||
remoteStencilInterfaces_.set
|
||||
(
|
||||
i,
|
||||
new lduPrimitiveProcessorInterface
|
||||
(
|
||||
localFaceCells[procI],
|
||||
Pstream::myProcNo(),
|
||||
procI,
|
||||
tensorField(0),
|
||||
Pstream::msgType()
|
||||
)
|
||||
);
|
||||
for (auto& interface : patches)
|
||||
{
|
||||
if (interface != -1)
|
||||
{
|
||||
interface = procToInterface[interface]+boundary().size();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -218,6 +345,104 @@ bool Foam::dynamicOversetFvMesh::updateAddressing() const
|
||||
}
|
||||
|
||||
|
||||
void Foam::dynamicOversetFvMesh::writeAgglomeration
|
||||
(
|
||||
const GAMGAgglomeration& agglom
|
||||
) const
|
||||
{
|
||||
labelList cellToCoarse(identity(nCells()));
|
||||
labelListList coarseToCell(invertOneToMany(nCells(), cellToCoarse));
|
||||
|
||||
// Write initial agglomeration
|
||||
{
|
||||
volScalarField scalarAgglomeration
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"agglomeration",
|
||||
this->time().timeName(),
|
||||
*this,
|
||||
IOobject::NO_READ,
|
||||
IOobject::AUTO_WRITE
|
||||
),
|
||||
*this,
|
||||
dimensionedScalar(dimless, Zero)
|
||||
);
|
||||
scalarField& fld = scalarAgglomeration.primitiveFieldRef();
|
||||
forAll(fld, celli)
|
||||
{
|
||||
fld[celli] = cellToCoarse[celli];
|
||||
}
|
||||
fld /= max(fld);
|
||||
correctBoundaryConditions
|
||||
<
|
||||
volScalarField,
|
||||
oversetFvPatchField<scalar>
|
||||
>(scalarAgglomeration.boundaryFieldRef(), false);
|
||||
scalarAgglomeration.write();
|
||||
|
||||
Info<< "Writing initial cell distribution to "
|
||||
<< this->time().timeName() << endl;
|
||||
}
|
||||
|
||||
|
||||
for (label level = 0; level < agglom.size(); level++)
|
||||
{
|
||||
const labelList& addr = agglom.restrictAddressing(level);
|
||||
label coarseSize = max(addr)+1;
|
||||
|
||||
Info<< "Level : " << level << endl
|
||||
<< returnReduce(addr.size(), sumOp<label>()) << endl
|
||||
<< " current size : "
|
||||
<< returnReduce(addr.size(), sumOp<label>()) << endl
|
||||
<< " agglomerated size : "
|
||||
<< returnReduce(coarseSize, sumOp<label>()) << endl;
|
||||
|
||||
forAll(addr, fineI)
|
||||
{
|
||||
const labelList& cellLabels = coarseToCell[fineI];
|
||||
forAll(cellLabels, i)
|
||||
{
|
||||
cellToCoarse[cellLabels[i]] = addr[fineI];
|
||||
}
|
||||
}
|
||||
coarseToCell = invertOneToMany(coarseSize, cellToCoarse);
|
||||
|
||||
// Write agglomeration
|
||||
{
|
||||
volScalarField scalarAgglomeration
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"agglomeration_" + Foam::name(level),
|
||||
this->time().timeName(),
|
||||
*this,
|
||||
IOobject::NO_READ,
|
||||
IOobject::AUTO_WRITE
|
||||
),
|
||||
*this,
|
||||
dimensionedScalar(dimless, Zero)
|
||||
);
|
||||
scalarField& fld = scalarAgglomeration.primitiveFieldRef();
|
||||
forAll(fld, celli)
|
||||
{
|
||||
fld[celli] = cellToCoarse[celli];
|
||||
}
|
||||
//if (normalise)
|
||||
//{
|
||||
// fld /= max(fld);
|
||||
//}
|
||||
correctBoundaryConditions
|
||||
<
|
||||
volScalarField,
|
||||
oversetFvPatchField<scalar>
|
||||
>(scalarAgglomeration.boundaryFieldRef(), false);
|
||||
scalarAgglomeration.write();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::dynamicOversetFvMesh::dynamicOversetFvMesh(const IOobject& io)
|
||||
@ -253,6 +478,21 @@ const Foam::lduAddressing& Foam::dynamicOversetFvMesh::lduAddr() const
|
||||
}
|
||||
|
||||
|
||||
Foam::lduInterfacePtrsList Foam::dynamicOversetFvMesh::interfaces() const
|
||||
{
|
||||
if (!active_)
|
||||
{
|
||||
return dynamicMotionSolverFvMesh::interfaces();
|
||||
}
|
||||
if (lduPtr_.empty())
|
||||
{
|
||||
// Build extended addressing
|
||||
updateAddressing();
|
||||
}
|
||||
return allInterfaces_;
|
||||
}
|
||||
|
||||
|
||||
const Foam::fvMeshPrimitiveLduAddressing&
|
||||
Foam::dynamicOversetFvMesh::primitiveLduAddr() const
|
||||
{
|
||||
|
@ -48,6 +48,7 @@ namespace Foam
|
||||
|
||||
class mapDistribute;
|
||||
class lduPrimitiveProcessorInterface;
|
||||
class GAMGAgglomeration;
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class dynamicOversetFvMesh Declaration
|
||||
@ -80,6 +81,9 @@ protected:
|
||||
//- Corresponding faces (in above lduPtr) to the stencil
|
||||
mutable labelListList stencilFaces_;
|
||||
|
||||
//- Corresponding patches (in above lduPtr) to the stencil
|
||||
mutable labelListList stencilPatches_;
|
||||
|
||||
//- From old to new face labels
|
||||
mutable labelList reverseFaceMap_;
|
||||
|
||||
@ -91,7 +95,13 @@ protected:
|
||||
|
||||
//- Debug: print matrix
|
||||
template<class Type>
|
||||
void write(Ostream&, const fvMatrix<Type>&, const lduAddressing&) const;
|
||||
void write
|
||||
(
|
||||
Ostream&,
|
||||
const fvMatrix<Type>&,
|
||||
const lduAddressing&,
|
||||
const lduInterfacePtrsList&
|
||||
) const;
|
||||
|
||||
//- Explicit interpolation of acceptor cells from donor cells
|
||||
template<class T>
|
||||
@ -111,16 +121,31 @@ protected:
|
||||
void interpolate(const wordHashSet& suppressed);
|
||||
|
||||
//- Freeze values at holes
|
||||
template<class Type>
|
||||
void freezeHoles(fvMatrix<Type>&) const;
|
||||
//template<class Type>
|
||||
//void freezeHoles(fvMatrix<Type>&) const;
|
||||
|
||||
//- Get scalar interfaces of certain type
|
||||
//template<class GeoField, class PatchType>
|
||||
//lduInterfaceFieldPtrsList scalarInterfaces(const GeoField& psi) const;
|
||||
|
||||
//- Correct boundary conditions of certain type (typeOnly = true)
|
||||
// or explicitly not of the type (typeOnly = false)
|
||||
template<class GeoField, class PatchType>
|
||||
lduInterfaceFieldPtrsList scalarInterfaces(const GeoField& psi) const;
|
||||
static void correctBoundaryConditions
|
||||
(
|
||||
typename GeoField::Boundary& bfld,
|
||||
const bool typeOnly
|
||||
);
|
||||
|
||||
//- Determine normalisation for interpolation. This equals the
|
||||
// original diagonal except stabilised for zero diagonals (possible
|
||||
// in hole cells)
|
||||
template<class Type>
|
||||
tmp<scalarField> normalisation(const fvMatrix<Type>& m) const;
|
||||
|
||||
//- Add interpolation to matrix (coefficients)
|
||||
template<class Type>
|
||||
void addInterpolation(fvMatrix<Type>&) const;
|
||||
void addInterpolation(fvMatrix<Type>&, const scalarField& norm) const;
|
||||
|
||||
//- Solve given dictionary with settings
|
||||
template<class Type>
|
||||
@ -130,6 +155,12 @@ protected:
|
||||
template<class GeoField>
|
||||
static void correctCoupledBoundaryConditions(GeoField& fld);
|
||||
|
||||
//- Debug: dump agglomeration
|
||||
void writeAgglomeration
|
||||
(
|
||||
const GAMGAgglomeration& agglom
|
||||
) const;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
@ -170,6 +201,11 @@ public:
|
||||
// primitiveLduAddr
|
||||
virtual const lduAddressing& lduAddr() const;
|
||||
|
||||
//- Return a list of pointers for each patch
|
||||
// with only those pointing to interfaces being set. If active:
|
||||
// return additional remoteStencilInterfaces_
|
||||
virtual lduInterfacePtrsList interfaces() const;
|
||||
|
||||
//- Return old to new face addressing
|
||||
const labelList& reverseFaceMap() const
|
||||
{
|
||||
|
@ -27,6 +27,9 @@ License
|
||||
#include "fvMatrix.H"
|
||||
#include "cellCellStencilObject.H"
|
||||
#include "oversetFvPatchField.H"
|
||||
#include "calculatedProcessorFvPatchField.H"
|
||||
#include "lduInterfaceFieldPtrsList.H"
|
||||
#include "processorFvPatch.H"
|
||||
|
||||
// * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
@ -107,37 +110,91 @@ void Foam::dynamicOversetFvMesh::interpolate(const wordHashSet& suppressed)
|
||||
|
||||
|
||||
template<class GeoField, class PatchType>
|
||||
Foam::lduInterfaceFieldPtrsList
|
||||
Foam::dynamicOversetFvMesh::scalarInterfaces(const GeoField& psi) const
|
||||
void Foam::dynamicOversetFvMesh::correctBoundaryConditions
|
||||
(
|
||||
typename GeoField::Boundary& bfld,
|
||||
const bool typeOnly
|
||||
)
|
||||
{
|
||||
const typename GeoField::Boundary& bpsi = psi.boundaryField();
|
||||
const label nReq = Pstream::nRequests();
|
||||
|
||||
lduInterfaceFieldPtrsList interfaces(bpsi.size());
|
||||
|
||||
forAll(interfaces, patchi)
|
||||
forAll(bfld, patchi)
|
||||
{
|
||||
if
|
||||
(
|
||||
isA<lduInterfaceField>(bpsi[patchi])
|
||||
&& isA<PatchType>(bpsi[patchi])
|
||||
)
|
||||
if (typeOnly == (isA<PatchType>(bfld[patchi]) != nullptr))
|
||||
{
|
||||
interfaces.set
|
||||
(
|
||||
patchi,
|
||||
&refCast<const lduInterfaceField>
|
||||
(
|
||||
bpsi[patchi]
|
||||
)
|
||||
);
|
||||
bfld[patchi].initEvaluate(Pstream::defaultCommsType);
|
||||
}
|
||||
}
|
||||
|
||||
// Block for any outstanding requests
|
||||
if (Pstream::parRun())
|
||||
{
|
||||
Pstream::waitRequests(nReq);
|
||||
}
|
||||
|
||||
forAll(bfld, patchi)
|
||||
{
|
||||
if (typeOnly == (isA<PatchType>(bfld[patchi]) != nullptr))
|
||||
{
|
||||
bfld[patchi].evaluate(Pstream::defaultCommsType);
|
||||
}
|
||||
}
|
||||
return interfaces;
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
void Foam::dynamicOversetFvMesh::addInterpolation(fvMatrix<Type>& m) const
|
||||
Foam::tmp<Foam::scalarField> Foam::dynamicOversetFvMesh::normalisation
|
||||
(
|
||||
const fvMatrix<Type>& m
|
||||
) const
|
||||
{
|
||||
// Determine normalisation. This is normally the original diagonal.
|
||||
// This needs to be stabilised for hole cells
|
||||
// which can have a zero diagonal. Assume that if any component has
|
||||
// a non-zero diagonal the cell does not need stabilisation.
|
||||
tmp<scalarField> tnorm(tmp<scalarField>::New(m.diag()));
|
||||
scalarField& norm = tnorm.ref();
|
||||
|
||||
// Add boundary coeffs to duplicate behaviour of fvMatrix
|
||||
const FieldField<Field, Type>& internalCoeffs = m.internalCoeffs();
|
||||
for (direction cmpt=0; cmpt<pTraits<Type>::nComponents; cmpt++)
|
||||
{
|
||||
//m.addBoundaryDiag(norm, cmpt);
|
||||
forAll(internalCoeffs, patchi)
|
||||
{
|
||||
const labelUList& fc = lduAddr().patchAddr(patchi);
|
||||
const Field<Type>& intCoeffs = internalCoeffs[patchi];
|
||||
const scalarField cmptCoeffs(intCoeffs.component(cmpt));
|
||||
forAll(fc, i)
|
||||
{
|
||||
norm[fc[i]] += cmptCoeffs[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
forAll(norm, celli)
|
||||
{
|
||||
scalar& n = norm[celli];
|
||||
if (mag(n) < SMALL)
|
||||
{
|
||||
n = 1.0; //?
|
||||
}
|
||||
else
|
||||
{
|
||||
// Restore original diagonal
|
||||
n = m.diag()[celli];
|
||||
}
|
||||
}
|
||||
return tnorm;
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
void Foam::dynamicOversetFvMesh::addInterpolation
|
||||
(
|
||||
fvMatrix<Type>& m,
|
||||
const scalarField& normalisation
|
||||
) const
|
||||
{
|
||||
const cellCellStencilObject& overlap = Stencil::New(*this);
|
||||
const List<scalarList>& wghts = overlap.cellInterpolationWeights();
|
||||
@ -161,7 +218,7 @@ void Foam::dynamicOversetFvMesh::addInterpolation(fvMatrix<Type>& m) const
|
||||
const labelUList& lowerAddr = addr.lowerAddr();
|
||||
const labelUList& ownerStartAddr = addr.ownerStartAddr();
|
||||
const labelUList& losortAddr = addr.losortAddr();
|
||||
|
||||
const lduInterfacePtrsList& interfaces = allInterfaces_;
|
||||
|
||||
if (!isA<fvMeshPrimitiveLduAddressing>(addr))
|
||||
{
|
||||
@ -179,6 +236,71 @@ void Foam::dynamicOversetFvMesh::addInterpolation(fvMatrix<Type>& m) const
|
||||
inplaceReorder(reverseFaceMap_, lower);
|
||||
|
||||
|
||||
const label nOldInterfaces = dynamicMotionSolverFvMesh::interfaces().size();
|
||||
|
||||
if (interfaces.size() > nOldInterfaces)
|
||||
{
|
||||
// Extend matrix coefficients
|
||||
m.internalCoeffs().setSize(interfaces.size());
|
||||
m.boundaryCoeffs().setSize(interfaces.size());
|
||||
|
||||
// 1b. Adapt for additional interfaces
|
||||
for
|
||||
(
|
||||
label patchi = nOldInterfaces;
|
||||
patchi < interfaces.size();
|
||||
patchi++
|
||||
)
|
||||
{
|
||||
const labelUList& fc = interfaces[patchi].faceCells();
|
||||
m.internalCoeffs().set(patchi, new Field<Type>(fc.size(), Zero));
|
||||
m.boundaryCoeffs().set(patchi, new Field<Type>(fc.size(), Zero));
|
||||
}
|
||||
|
||||
// 1c. Adapt field for additional interfaceFields (note: solver uses
|
||||
// GeometricField::scalarInterfaces() to get hold of interfaces)
|
||||
typedef GeometricField<Type, fvPatchField, volMesh> GeoField;
|
||||
|
||||
typename GeoField::Boundary& bfld =
|
||||
const_cast<GeoField&>(m.psi()).boundaryFieldRef();
|
||||
|
||||
bfld.setSize(interfaces.size());
|
||||
|
||||
|
||||
// This gets quite interesting: we do not want to add additional
|
||||
// fvPatches (since direct correspondence to polyMesh) so instead
|
||||
// add a reference to an existing processor patch
|
||||
label addPatchi = 0;
|
||||
for (label patchi = 0; patchi < nOldInterfaces; patchi++)
|
||||
{
|
||||
if (isA<processorFvPatch>(bfld[patchi].patch()))
|
||||
{
|
||||
addPatchi = patchi;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for
|
||||
(
|
||||
label patchi = nOldInterfaces;
|
||||
patchi < interfaces.size();
|
||||
patchi++
|
||||
)
|
||||
{
|
||||
bfld.set
|
||||
(
|
||||
patchi,
|
||||
new calculatedProcessorFvPatchField<Type>
|
||||
(
|
||||
interfaces[patchi],
|
||||
bfld[addPatchi].patch(), // dummy processorFvPatch
|
||||
m.psi()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 2. Adapt fvMatrix level: faceFluxCorrectionPtr
|
||||
// Question: do we need to do this?
|
||||
// This seems to be set/used only by the gaussLaplacianScheme and
|
||||
@ -207,12 +329,11 @@ void Foam::dynamicOversetFvMesh::addInterpolation(fvMatrix<Type>& m) const
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
forAll(m.internalCoeffs(), patchI)
|
||||
for (label patchi = 0; patchi < nOldInterfaces; ++patchi)
|
||||
{
|
||||
const labelUList& fc = addr.patchAddr(patchI);
|
||||
Field<Type>& intCoeffs = m.internalCoeffs()[patchI];
|
||||
Field<Type>& bouCoeffs = m.boundaryCoeffs()[patchI];
|
||||
const labelUList& fc = addr.patchAddr(patchi);
|
||||
Field<Type>& intCoeffs = m.internalCoeffs()[patchi];
|
||||
Field<Type>& bouCoeffs = m.boundaryCoeffs()[patchi];
|
||||
forAll(fc, i)
|
||||
{
|
||||
label celli = fc[i];
|
||||
@ -232,92 +353,16 @@ void Foam::dynamicOversetFvMesh::addInterpolation(fvMatrix<Type>& m) const
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: For a non-scalar matrix, in the function fvMatrix::solveSegregated
|
||||
// it uses updateInterfaceMatrix to correct for remote source contributions.
|
||||
// This unfortunately also triggers the overset interpolation which then
|
||||
// produces a non-zero source for interpolated cells.
|
||||
// The procedure below calculates this contribution 'correctionSource'
|
||||
// and subtracts it from the source later in order to compensate.
|
||||
Field<Type> correctionSource(diag.size(), Zero);
|
||||
|
||||
if (pTraits<Type>::nComponents > 1)
|
||||
{
|
||||
typedef GeometricField<Type, fvPatchField, volMesh> GeoField;
|
||||
|
||||
typename pTraits<Type>::labelType validComponents
|
||||
(
|
||||
this->template validComponents<Type>()
|
||||
);
|
||||
|
||||
// Get all the overset lduInterfaces
|
||||
lduInterfaceFieldPtrsList interfaces
|
||||
(
|
||||
scalarInterfaces<GeoField, oversetFvPatchField<Type>>
|
||||
(
|
||||
m.psi()
|
||||
)
|
||||
);
|
||||
|
||||
const Field<Type>& psiInt = m.psi().primitiveField();
|
||||
|
||||
for (direction cmpt=0; cmpt<pTraits<Type>::nComponents; cmpt++)
|
||||
{
|
||||
if (component(validComponents, cmpt) != -1)
|
||||
{
|
||||
const scalarField psiCmpt(psiInt.component(cmpt));
|
||||
scalarField corrSourceCmpt(correctionSource.component(cmpt));
|
||||
|
||||
forAll(interfaces, patchi)
|
||||
{
|
||||
if (interfaces.set(patchi))
|
||||
{
|
||||
interfaces[patchi].initInterfaceMatrixUpdate
|
||||
(
|
||||
corrSourceCmpt,
|
||||
true,
|
||||
psiCmpt,
|
||||
m.boundaryCoeffs()[patchi].component(cmpt),
|
||||
cmpt,
|
||||
Pstream::defaultCommsType
|
||||
);
|
||||
}
|
||||
}
|
||||
forAll(interfaces, patchi)
|
||||
{
|
||||
if (interfaces.set(patchi))
|
||||
{
|
||||
interfaces[patchi].updateInterfaceMatrix
|
||||
(
|
||||
corrSourceCmpt,
|
||||
true,
|
||||
psiCmpt,
|
||||
m.boundaryCoeffs()[patchi].component(cmpt),
|
||||
cmpt,
|
||||
Pstream::defaultCommsType
|
||||
);
|
||||
}
|
||||
}
|
||||
correctionSource.replace(cmpt, corrSourceCmpt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Modify matrix
|
||||
// ~~~~~~~~~~~~~
|
||||
|
||||
|
||||
|
||||
// Do hole cells. Note: maybe put into interpolationCells() loop above?
|
||||
forAll(types, celli)
|
||||
{
|
||||
if (types[celli] == cellCellStencil::HOLE)
|
||||
{
|
||||
//Pout<< "Found hole cell:" << celli
|
||||
// << " at:" << C()[celli]
|
||||
// << " ; setting value" << endl;
|
||||
|
||||
label startLabel = ownerStartAddr[celli];
|
||||
label endLabel = ownerStartAddr[celli + 1];
|
||||
|
||||
@ -335,13 +380,21 @@ void Foam::dynamicOversetFvMesh::addInterpolation(fvMatrix<Type>& m) const
|
||||
lower[facei] = 0.0;
|
||||
}
|
||||
|
||||
const scalar normalisation = V()[celli];
|
||||
diag[celli] = normalisation;
|
||||
source[celli] = normalisation*m.psi()[celli];
|
||||
diag[celli] = normalisation[celli];
|
||||
source[celli] = normalisation[celli]*m.psi()[celli];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//const globalIndex globalNumbering(V().size());
|
||||
//labelList globalCellIDs(overlap.cellInterpolationMap().constructSize());
|
||||
//forAll(V(), cellI)
|
||||
//{
|
||||
// globalCellIDs[cellI] = globalNumbering.toGlobal(cellI);
|
||||
//}
|
||||
//overlap.cellInterpolationMap().distribute(globalCellIDs);
|
||||
|
||||
|
||||
forAll(cellIDs, i)
|
||||
{
|
||||
label celli = cellIDs[i];
|
||||
@ -350,8 +403,7 @@ void Foam::dynamicOversetFvMesh::addInterpolation(fvMatrix<Type>& m) const
|
||||
const scalarList& w = wghts[celli];
|
||||
const labelList& nbrs = stencil[celli];
|
||||
const labelList& nbrFaces = stencilFaces_[celli];
|
||||
|
||||
const scalar normalisation = V()[celli];
|
||||
const labelList& nbrPatches = stencilPatches_[celli];
|
||||
|
||||
if (types[celli] == cellCellStencil::HOLE)
|
||||
{
|
||||
@ -362,55 +414,90 @@ void Foam::dynamicOversetFvMesh::addInterpolation(fvMatrix<Type>& m) const
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create interpolation stencil. Leave any non-local contributions
|
||||
// to be done by oversetFvPatchField updateMatrixInterface
|
||||
// 'correctionSource' is only applied for vector and higher
|
||||
// fvMatrix; it is zero for scalar matrices (see above).
|
||||
// Create interpolation stencil
|
||||
|
||||
diag[celli] *= (1.0-f);
|
||||
diag[celli] += normalisation*f;
|
||||
|
||||
source[celli] *= (1.0-f);
|
||||
source[celli] -= correctionSource[celli];
|
||||
|
||||
//Pout<< "Interpolating " << celli << " with factor:" << f
|
||||
// << " new diag:" << diag[celli]
|
||||
// << " new source:" << source[celli]
|
||||
// << " volume:" << V()[celli] << endl;
|
||||
|
||||
forAll(nbrs, nbri)
|
||||
{
|
||||
label patchi = nbrPatches[nbri];
|
||||
label facei = nbrFaces[nbri];
|
||||
|
||||
if (facei != -1)
|
||||
if (patchi == -1)
|
||||
{
|
||||
label nbrCelli = nbrs[nbri];
|
||||
|
||||
// Add the coefficients
|
||||
const scalar s = normalisation[celli]*f*w[nbri];
|
||||
|
||||
scalar& u = upper[facei];
|
||||
scalar& l = lower[facei];
|
||||
if (celli < nbrCelli)
|
||||
{
|
||||
u += -normalisation*f*w[nbri];
|
||||
diag[celli] += s;
|
||||
u += -s;
|
||||
}
|
||||
else
|
||||
{
|
||||
l += -normalisation*f*w[nbri];
|
||||
diag[celli] += s;
|
||||
l += -s;
|
||||
}
|
||||
}
|
||||
//else
|
||||
//{
|
||||
// Pout<< "addItnerpolation of " << celli
|
||||
// << " at:" << this->cellCentres()[celli]
|
||||
// << " zone:" << this->zoneID()[celli]
|
||||
// << " diag:" << diag[celli]
|
||||
// << " source:" << source[celli]
|
||||
// <<" : skipping remote cell:" << nbrs[nbri]
|
||||
// << " with weight:" << w[nbri]
|
||||
// << endl;
|
||||
//}
|
||||
else
|
||||
{
|
||||
// Patch face. Store in boundaryCoeffs. Note sign change.
|
||||
//const label globalCelli = globalCellIDs[nbrs[nbri]];
|
||||
//const label proci =
|
||||
// globalNumbering.whichProcID(globalCelli);
|
||||
//const label remoteCelli =
|
||||
// globalNumbering.toLocal(proci, globalCelli);
|
||||
//
|
||||
//Pout<< "for cell:" << celli
|
||||
// << " need weight from remote slot:" << nbrs[nbri]
|
||||
// << " proc:" << proci << " remote cell:" << remoteCelli
|
||||
// << " patch:" << patchi
|
||||
// << " patchFace:" << facei
|
||||
// << " weight:" << w[nbri]
|
||||
// << endl;
|
||||
|
||||
const scalar s = normalisation[celli]*f*w[nbri];
|
||||
m.boundaryCoeffs()[patchi][facei] += pTraits<Type>::one*s;
|
||||
m.internalCoeffs()[patchi][facei] += pTraits<Type>::one*s;
|
||||
|
||||
// Note: do NOT add to diagonal - this is in the
|
||||
// internalCoeffs and gets added to the diagonal
|
||||
// inside fvMatrix::solve
|
||||
}
|
||||
}
|
||||
|
||||
//if (mag(diag[celli]) < SMALL)
|
||||
//{
|
||||
// Pout<< "for cell:" << celli
|
||||
// << " at:" << this->C()[celli]
|
||||
// << " diag:" << diag[celli] << endl;
|
||||
//
|
||||
// forAll(nbrs, nbri)
|
||||
// {
|
||||
// label patchi = nbrPatches[nbri];
|
||||
// label facei = nbrFaces[nbri];
|
||||
//
|
||||
// const label globalCelli = globalCellIDs[nbrs[nbri]];
|
||||
// const label proci =
|
||||
// globalNumbering.whichProcID(globalCelli);
|
||||
// const label remoteCelli =
|
||||
// globalNumbering.toLocal(proci, globalCelli);
|
||||
//
|
||||
// Pout<< " need weight from slot:" << nbrs[nbri]
|
||||
// << " proc:" << proci << " remote cell:"
|
||||
// << remoteCelli
|
||||
// << " patch:" << patchi
|
||||
// << " patchFace:" << facei
|
||||
// << " weight:" << w[nbri]
|
||||
// << endl;
|
||||
// }
|
||||
// Pout<< endl;
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -423,9 +510,10 @@ Foam::SolverPerformance<Type> Foam::dynamicOversetFvMesh::solve
|
||||
const dictionary& dict
|
||||
) const
|
||||
{
|
||||
typedef GeometricField<Type, fvPatchField, volMesh> GeoField;
|
||||
// Check we're running with bcs that can handle implicit matrix manipulation
|
||||
const typename GeometricField<Type, fvPatchField, volMesh>::Boundary bpsi =
|
||||
m.psi().boundaryField();
|
||||
typename GeoField::Boundary& bpsi =
|
||||
const_cast<GeoField&>(m.psi()).boundaryFieldRef();
|
||||
|
||||
bool hasOverset = false;
|
||||
forAll(bpsi, patchi)
|
||||
@ -455,6 +543,9 @@ Foam::SolverPerformance<Type> Foam::dynamicOversetFvMesh::solve
|
||||
<< m.psi().name() << endl;
|
||||
}
|
||||
|
||||
// Calculate stabilised diagonal as normalisation for interpolation
|
||||
const scalarField norm(normalisation(m));
|
||||
|
||||
|
||||
// Switch to extended addressing (requires mesh::update() having been
|
||||
// called)
|
||||
@ -465,15 +556,32 @@ Foam::SolverPerformance<Type> Foam::dynamicOversetFvMesh::solve
|
||||
scalarField oldLower(m.lower());
|
||||
FieldField<Field, Type> oldInt(m.internalCoeffs());
|
||||
FieldField<Field, Type> oldBou(m.boundaryCoeffs());
|
||||
const label oldSize = bpsi.size();
|
||||
|
||||
addInterpolation(m, norm);
|
||||
|
||||
// Swap psi values so added patches have patchNeighbourField
|
||||
correctBoundaryConditions<GeoField, calculatedProcessorFvPatchField<Type>>
|
||||
(
|
||||
bpsi,
|
||||
true
|
||||
);
|
||||
|
||||
addInterpolation(m);
|
||||
|
||||
// Print a bit
|
||||
//write(Pout, m, lduAddr());
|
||||
//write(Pout, m, lduAddr(), interfaces());
|
||||
//{
|
||||
// const fvSolution& sol = static_cast<const fvSolution&>(*this);
|
||||
// const dictionary& pDict = sol.subDict("solvers").subDict("p");
|
||||
// writeAgglomeration(GAMGAgglomeration::New(m, pDict));
|
||||
//}
|
||||
|
||||
// Use lower level solver
|
||||
SolverPerformance<Type> s(dynamicMotionSolverFvMesh::solve(m, dict));
|
||||
|
||||
// Restore boundary field
|
||||
bpsi.setSize(oldSize);
|
||||
|
||||
// Restore matrix
|
||||
m.upper().transfer(oldUpper);
|
||||
m.lower().transfer(oldLower);
|
||||
@ -492,7 +600,8 @@ void Foam::dynamicOversetFvMesh::write
|
||||
(
|
||||
Ostream& os,
|
||||
const fvMatrix<Type>& m,
|
||||
const lduAddressing& addr
|
||||
const lduAddressing& addr,
|
||||
const lduInterfacePtrsList& interfaces
|
||||
) const
|
||||
{
|
||||
os << "** Matrix **" << endl;
|
||||
@ -506,6 +615,26 @@ void Foam::dynamicOversetFvMesh::write
|
||||
const Field<Type>& source = m.source();
|
||||
const scalarField& diag = m.diag();
|
||||
|
||||
|
||||
// Invert patch addressing
|
||||
labelListList cellToPatch(addr.size());
|
||||
labelListList cellToPatchFace(addr.size());
|
||||
{
|
||||
forAll(interfaces, patchi)
|
||||
{
|
||||
if (interfaces.set(patchi))
|
||||
{
|
||||
const labelUList& fc = interfaces[patchi].faceCells();
|
||||
|
||||
forAll(fc, i)
|
||||
{
|
||||
cellToPatch[fc[i]].append(patchi);
|
||||
cellToPatchFace[fc[i]].append(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
forAll(source, celli)
|
||||
{
|
||||
os << "cell:" << celli << " diag:" << diag[celli]
|
||||
@ -531,6 +660,18 @@ void Foam::dynamicOversetFvMesh::write
|
||||
<< " nbr:" << lowerAddr[facei] << " coeff:" << lower[facei]
|
||||
<< endl;
|
||||
}
|
||||
|
||||
forAll(cellToPatch[celli], i)
|
||||
{
|
||||
label patchi = cellToPatch[celli][i];
|
||||
label patchFacei = cellToPatchFace[celli][i];
|
||||
|
||||
os << " patch:" << patchi
|
||||
<< " patchface:" << patchFacei
|
||||
<< " intcoeff:" << m.internalCoeffs()[patchi][patchFacei]
|
||||
<< " boucoeff:" << m.boundaryCoeffs()[patchi][patchFacei]
|
||||
<< endl;
|
||||
}
|
||||
}
|
||||
forAll(m.internalCoeffs(), patchi)
|
||||
{
|
||||
@ -538,7 +679,22 @@ void Foam::dynamicOversetFvMesh::write
|
||||
{
|
||||
const labelUList& fc = addr.patchAddr(patchi);
|
||||
|
||||
os << "patch:" << patchi << " size:" << fc.size() << endl;
|
||||
os << "patch:" << patchi
|
||||
//<< " type:" << interfaces[patchi].type()
|
||||
<< " size:" << fc.size() << endl;
|
||||
if
|
||||
(
|
||||
interfaces.set(patchi)
|
||||
&& isA<processorLduInterface>(interfaces[patchi])
|
||||
)
|
||||
{
|
||||
const processorLduInterface& ppp =
|
||||
refCast<const processorLduInterface>(interfaces[patchi]);
|
||||
os << "(processor with my:" << ppp.myProcNo()
|
||||
<< " nbr:" << ppp.neighbProcNo()
|
||||
<< ")" << endl;
|
||||
}
|
||||
|
||||
forAll(fc, i)
|
||||
{
|
||||
os << " cell:" << fc[i]
|
||||
@ -550,15 +706,15 @@ void Foam::dynamicOversetFvMesh::write
|
||||
}
|
||||
|
||||
|
||||
lduInterfaceFieldPtrsList interfaces =
|
||||
lduInterfaceFieldPtrsList interfaceFields =
|
||||
m.psi().boundaryField().scalarInterfaces();
|
||||
forAll(interfaces, inti)
|
||||
forAll(interfaceFields, inti)
|
||||
{
|
||||
if (interfaces.set(inti))
|
||||
if (interfaceFields.set(inti))
|
||||
{
|
||||
os << "interface:" << inti
|
||||
<< " if type:" << interfaces[inti].interface().type()
|
||||
<< " fld type:" << interfaces[inti].type() << endl;
|
||||
<< " if type:" << interfaceFields[inti].interface().type()
|
||||
<< " fld type:" << interfaceFields[inti].type() << endl;
|
||||
}
|
||||
}
|
||||
|
||||
@ -577,7 +733,7 @@ void Foam::dynamicOversetFvMesh::correctCoupledBoundaryConditions(GeoField& fld)
|
||||
{
|
||||
if (bfld[patchi].coupled())
|
||||
{
|
||||
Pout<< "initEval of " << bfld[patchi].patch().name() << endl;
|
||||
//Pout<< "initEval of " << bfld[patchi].patch().name() << endl;
|
||||
bfld[patchi].initEvaluate(Pstream::defaultCommsType);
|
||||
}
|
||||
}
|
||||
@ -592,7 +748,7 @@ void Foam::dynamicOversetFvMesh::correctCoupledBoundaryConditions(GeoField& fld)
|
||||
{
|
||||
if (bfld[patchi].coupled())
|
||||
{
|
||||
Pout<< "eval of " << bfld[patchi].patch().name() << endl;
|
||||
//Pout<< "eval of " << bfld[patchi].patch().name() << endl;
|
||||
bfld[patchi].evaluate(Pstream::defaultCommsType);
|
||||
}
|
||||
}
|
||||
|
@ -192,7 +192,7 @@ Foam::labelList Foam::fvMeshPrimitiveLduAddressing::addAddressing
|
||||
// Remote cell
|
||||
faces[nbrI] = -1;
|
||||
|
||||
label globalNbr = globalCellIDs[nbrs[nbrI]];
|
||||
label globalNbr = globalCellIDs[nbrCellI];
|
||||
label procI = globalNumbering.whichProcID(globalNbr);
|
||||
label remoteCellI = globalNumbering.toLocal(procI, globalNbr);
|
||||
|
||||
|
@ -0,0 +1,221 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "calculatedProcessorGAMGInterface.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
#include "labelPairHashes.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug(calculatedProcessorGAMGInterface, 0);
|
||||
addToRunTimeSelectionTable
|
||||
(
|
||||
GAMGInterface,
|
||||
calculatedProcessorGAMGInterface,
|
||||
lduInterface
|
||||
);
|
||||
addToRunTimeSelectionTable
|
||||
(
|
||||
GAMGInterface,
|
||||
calculatedProcessorGAMGInterface,
|
||||
Istream
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::calculatedProcessorGAMGInterface::calculatedProcessorGAMGInterface
|
||||
(
|
||||
const label index,
|
||||
const lduInterfacePtrsList& coarseInterfaces,
|
||||
const lduInterface& fineInterface,
|
||||
const labelField& localRestrictAddressing,
|
||||
const labelField& neighbourRestrictAddressing,
|
||||
const label fineLevelIndex,
|
||||
const label coarseComm
|
||||
)
|
||||
:
|
||||
GAMGInterface
|
||||
(
|
||||
index,
|
||||
coarseInterfaces
|
||||
),
|
||||
comm_(coarseComm),
|
||||
myProcNo_(refCast<const processorLduInterface>(fineInterface).myProcNo()),
|
||||
neighbProcNo_
|
||||
(
|
||||
refCast<const processorLduInterface>(fineInterface).neighbProcNo()
|
||||
),
|
||||
forwardT_(refCast<const processorLduInterface>(fineInterface).forwardT()),
|
||||
tag_(refCast<const processorLduInterface>(fineInterface).tag())
|
||||
{
|
||||
// From coarse face to coarse cell
|
||||
DynamicList<label> dynFaceCells(localRestrictAddressing.size());
|
||||
// From fine face to coarse face
|
||||
DynamicList<label> dynFaceRestrictAddressing
|
||||
(
|
||||
localRestrictAddressing.size()
|
||||
);
|
||||
|
||||
// From coarse cell pair to coarse face
|
||||
labelPairLookup cellsToCoarseFace(2*localRestrictAddressing.size());
|
||||
|
||||
forAll(localRestrictAddressing, ffi)
|
||||
{
|
||||
labelPair cellPair;
|
||||
|
||||
// Do switching on master/slave indexes based on the owner/neighbour of
|
||||
// the processor index such that both sides get the same answer.
|
||||
if (myProcNo() < neighbProcNo())
|
||||
{
|
||||
// Master side
|
||||
cellPair = labelPair
|
||||
(
|
||||
localRestrictAddressing[ffi],
|
||||
neighbourRestrictAddressing[ffi]
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Slave side
|
||||
cellPair = labelPair
|
||||
(
|
||||
neighbourRestrictAddressing[ffi],
|
||||
localRestrictAddressing[ffi]
|
||||
);
|
||||
}
|
||||
|
||||
const auto fnd = cellsToCoarseFace.cfind(cellPair);
|
||||
|
||||
if (fnd.found())
|
||||
{
|
||||
// Already have coarse face
|
||||
dynFaceRestrictAddressing.append(fnd.val());
|
||||
}
|
||||
else
|
||||
{
|
||||
// New coarse face
|
||||
label coarseI = dynFaceCells.size();
|
||||
dynFaceRestrictAddressing.append(coarseI);
|
||||
dynFaceCells.append(localRestrictAddressing[ffi]);
|
||||
cellsToCoarseFace.insert(cellPair, coarseI);
|
||||
}
|
||||
}
|
||||
|
||||
faceCells_.transfer(dynFaceCells);
|
||||
faceRestrictAddressing_.transfer(dynFaceRestrictAddressing);
|
||||
}
|
||||
|
||||
|
||||
Foam::calculatedProcessorGAMGInterface::calculatedProcessorGAMGInterface
|
||||
(
|
||||
const label index,
|
||||
const lduInterfacePtrsList& coarseInterfaces,
|
||||
const labelUList& faceCells,
|
||||
const labelUList& faceRestrictAddresssing,
|
||||
const label coarseComm,
|
||||
const label myProcNo,
|
||||
const label neighbProcNo,
|
||||
const tensorField& forwardT,
|
||||
const int tag
|
||||
)
|
||||
:
|
||||
GAMGInterface
|
||||
(
|
||||
index,
|
||||
coarseInterfaces,
|
||||
faceCells,
|
||||
faceRestrictAddresssing
|
||||
),
|
||||
comm_(coarseComm),
|
||||
myProcNo_(myProcNo),
|
||||
neighbProcNo_(neighbProcNo),
|
||||
forwardT_(forwardT),
|
||||
tag_(tag)
|
||||
{}
|
||||
|
||||
|
||||
Foam::calculatedProcessorGAMGInterface::calculatedProcessorGAMGInterface
|
||||
(
|
||||
const label index,
|
||||
const lduInterfacePtrsList& coarseInterfaces,
|
||||
Istream& is
|
||||
)
|
||||
:
|
||||
GAMGInterface(index, coarseInterfaces, is),
|
||||
comm_(readLabel(is)),
|
||||
myProcNo_(readLabel(is)),
|
||||
neighbProcNo_(readLabel(is)),
|
||||
forwardT_(is),
|
||||
tag_(readLabel(is))
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::calculatedProcessorGAMGInterface::~calculatedProcessorGAMGInterface()
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::calculatedProcessorGAMGInterface::initInternalFieldTransfer
|
||||
(
|
||||
const Pstream::commsTypes commsType,
|
||||
const labelUList& iF
|
||||
) const
|
||||
{
|
||||
send(commsType, interfaceInternalField(iF)());
|
||||
}
|
||||
|
||||
|
||||
Foam::tmp<Foam::labelField>
|
||||
Foam::calculatedProcessorGAMGInterface::internalFieldTransfer
|
||||
(
|
||||
const Pstream::commsTypes commsType,
|
||||
const labelUList& iF
|
||||
) const
|
||||
{
|
||||
tmp<Field<label>> tfld(receive<label>(commsType, this->size()));
|
||||
|
||||
return tfld;
|
||||
}
|
||||
|
||||
|
||||
void Foam::calculatedProcessorGAMGInterface::write(Ostream& os) const
|
||||
{
|
||||
GAMGInterface::write(os);
|
||||
os << token::SPACE << comm_
|
||||
<< token::SPACE << myProcNo_
|
||||
<< token::SPACE << neighbProcNo_
|
||||
<< token::SPACE << forwardT_
|
||||
<< token::SPACE << tag_;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
@ -0,0 +1,199 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Class
|
||||
Foam::calculatedProcessorGAMGInterface
|
||||
|
||||
Description
|
||||
GAMG agglomerated processor interface.
|
||||
|
||||
SourceFiles
|
||||
calculatedProcessorGAMGInterface.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef calculatedProcessorGAMGInterface_H
|
||||
#define calculatedProcessorGAMGInterface_H
|
||||
|
||||
#include "GAMGInterface.H"
|
||||
#include "processorLduInterface.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class calculatedProcessorGAMGInterface Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class calculatedProcessorGAMGInterface
|
||||
:
|
||||
public GAMGInterface,
|
||||
public processorLduInterface
|
||||
{
|
||||
// Private data
|
||||
|
||||
//- Communicator to use for parallel communication
|
||||
const label comm_;
|
||||
|
||||
//- My processor rank in communicator
|
||||
label myProcNo_;
|
||||
|
||||
//- Neighbouring processor rank in communicator
|
||||
label neighbProcNo_;
|
||||
|
||||
//- Transformation tensor
|
||||
tensorField forwardT_;
|
||||
|
||||
//- Message tag used for sending
|
||||
int tag_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- No copy construct
|
||||
calculatedProcessorGAMGInterface
|
||||
(
|
||||
const calculatedProcessorGAMGInterface&
|
||||
) = delete;
|
||||
|
||||
//- No copy assignment
|
||||
void operator=(const calculatedProcessorGAMGInterface&) = delete;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("calculatedProcessor");
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from fine-level interface,
|
||||
// local and neighbour restrict addressing
|
||||
calculatedProcessorGAMGInterface
|
||||
(
|
||||
const label index,
|
||||
const lduInterfacePtrsList& coarseInterfaces,
|
||||
const lduInterface& fineInterface,
|
||||
const labelField& restrictAddressing,
|
||||
const labelField& neighbourRestrictAddressing,
|
||||
const label fineLevelIndex,
|
||||
const label coarseComm
|
||||
);
|
||||
|
||||
//- Construct from components
|
||||
calculatedProcessorGAMGInterface
|
||||
(
|
||||
const label index,
|
||||
const lduInterfacePtrsList& coarseInterfaces,
|
||||
const labelUList& faceCells,
|
||||
const labelUList& faceRestrictAddresssing,
|
||||
const label coarseComm,
|
||||
const label myProcNo,
|
||||
const label neighbProcNo,
|
||||
const tensorField& forwardT,
|
||||
const int tag
|
||||
);
|
||||
|
||||
//- Construct from Istream
|
||||
calculatedProcessorGAMGInterface
|
||||
(
|
||||
const label index,
|
||||
const lduInterfacePtrsList& coarseInterfaces,
|
||||
Istream& is
|
||||
);
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~calculatedProcessorGAMGInterface();
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
// Interface transfer functions
|
||||
|
||||
//- Initialise neighbour field transfer
|
||||
virtual void initInternalFieldTransfer
|
||||
(
|
||||
const Pstream::commsTypes commsType,
|
||||
const labelUList& iF
|
||||
) const;
|
||||
|
||||
//- Transfer and return internal field adjacent to the interface
|
||||
virtual tmp<labelField> internalFieldTransfer
|
||||
(
|
||||
const Pstream::commsTypes commsType,
|
||||
const labelUList& iF
|
||||
) const;
|
||||
|
||||
|
||||
//- Processor interface functions
|
||||
|
||||
//- Return communicator used for sending
|
||||
virtual label comm() const
|
||||
{
|
||||
return comm_;
|
||||
}
|
||||
|
||||
//- Return processor number (rank in communicator)
|
||||
virtual int myProcNo() const
|
||||
{
|
||||
return myProcNo_;
|
||||
}
|
||||
|
||||
//- Return neighbour processor number (rank in communicator)
|
||||
virtual int neighbProcNo() const
|
||||
{
|
||||
return neighbProcNo_;
|
||||
}
|
||||
|
||||
//- Return face transformation tensor
|
||||
virtual const tensorField& forwardT() const
|
||||
{
|
||||
return forwardT_;
|
||||
}
|
||||
|
||||
//- Return message tag used for sending
|
||||
virtual int tag() const
|
||||
{
|
||||
return tag_;
|
||||
}
|
||||
|
||||
|
||||
// I/O
|
||||
|
||||
//- Write to stream
|
||||
virtual void write(Ostream&) const;
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
@ -0,0 +1,206 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "calculatedProcessorGAMGInterfaceField.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
#include "lduMatrix.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug(calculatedProcessorGAMGInterfaceField, 0);
|
||||
addToRunTimeSelectionTable
|
||||
(
|
||||
GAMGInterfaceField,
|
||||
calculatedProcessorGAMGInterfaceField,
|
||||
lduInterface
|
||||
);
|
||||
addToRunTimeSelectionTable
|
||||
(
|
||||
GAMGInterfaceField,
|
||||
calculatedProcessorGAMGInterfaceField,
|
||||
lduInterfaceField
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::calculatedProcessorGAMGInterfaceField::
|
||||
calculatedProcessorGAMGInterfaceField
|
||||
(
|
||||
const GAMGInterface& GAMGCp,
|
||||
const lduInterfaceField& fineInterface
|
||||
)
|
||||
:
|
||||
GAMGInterfaceField(GAMGCp, fineInterface),
|
||||
procInterface_(refCast<const calculatedProcessorGAMGInterface>(GAMGCp)),
|
||||
doTransform_(false),
|
||||
rank_(0)
|
||||
{
|
||||
const processorLduInterfaceField& p =
|
||||
refCast<const processorLduInterfaceField>(fineInterface);
|
||||
|
||||
doTransform_ = p.doTransform();
|
||||
rank_ = p.rank();
|
||||
}
|
||||
|
||||
|
||||
Foam::calculatedProcessorGAMGInterfaceField::
|
||||
calculatedProcessorGAMGInterfaceField
|
||||
(
|
||||
const GAMGInterface& GAMGCp,
|
||||
const bool doTransform,
|
||||
const int rank
|
||||
)
|
||||
:
|
||||
GAMGInterfaceField(GAMGCp, doTransform, rank),
|
||||
procInterface_(refCast<const calculatedProcessorGAMGInterface>(GAMGCp)),
|
||||
doTransform_(doTransform),
|
||||
rank_(rank)
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::calculatedProcessorGAMGInterfaceField::
|
||||
~calculatedProcessorGAMGInterfaceField()
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::calculatedProcessorGAMGInterfaceField::initInterfaceMatrixUpdate
|
||||
(
|
||||
scalarField&,
|
||||
const bool,
|
||||
const scalarField& psiInternal,
|
||||
const scalarField&,
|
||||
const direction,
|
||||
const Pstream::commsTypes commsType
|
||||
) const
|
||||
{
|
||||
procInterface_.interfaceInternalField(psiInternal, scalarSendBuf_);
|
||||
|
||||
if
|
||||
(
|
||||
commsType == Pstream::commsTypes::nonBlocking
|
||||
&& !Pstream::floatTransfer
|
||||
)
|
||||
{
|
||||
// Fast path.
|
||||
scalarReceiveBuf_.setSize(scalarSendBuf_.size());
|
||||
outstandingRecvRequest_ = UPstream::nRequests();
|
||||
IPstream::read
|
||||
(
|
||||
Pstream::commsTypes::nonBlocking,
|
||||
procInterface_.neighbProcNo(),
|
||||
reinterpret_cast<char*>(scalarReceiveBuf_.begin()),
|
||||
scalarReceiveBuf_.byteSize(),
|
||||
procInterface_.tag(),
|
||||
comm()
|
||||
);
|
||||
|
||||
outstandingSendRequest_ = UPstream::nRequests();
|
||||
OPstream::write
|
||||
(
|
||||
Pstream::commsTypes::nonBlocking,
|
||||
procInterface_.neighbProcNo(),
|
||||
reinterpret_cast<const char*>(scalarSendBuf_.begin()),
|
||||
scalarSendBuf_.byteSize(),
|
||||
procInterface_.tag(),
|
||||
comm()
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
procInterface_.compressedSend(commsType, scalarSendBuf_);
|
||||
}
|
||||
|
||||
const_cast<calculatedProcessorGAMGInterfaceField&>(*this).updatedMatrix()
|
||||
= false;
|
||||
}
|
||||
|
||||
|
||||
void Foam::calculatedProcessorGAMGInterfaceField::updateInterfaceMatrix
|
||||
(
|
||||
scalarField& result,
|
||||
const bool add,
|
||||
const scalarField&,
|
||||
const scalarField& coeffs,
|
||||
const direction cmpt,
|
||||
const Pstream::commsTypes commsType
|
||||
) const
|
||||
{
|
||||
if (updatedMatrix())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if
|
||||
(
|
||||
commsType == Pstream::commsTypes::nonBlocking
|
||||
&& !Pstream::floatTransfer
|
||||
)
|
||||
{
|
||||
// Fast path.
|
||||
if
|
||||
(
|
||||
outstandingRecvRequest_ >= 0
|
||||
&& outstandingRecvRequest_ < Pstream::nRequests()
|
||||
)
|
||||
{
|
||||
UPstream::waitRequest(outstandingRecvRequest_);
|
||||
}
|
||||
// Recv finished so assume sending finished as well.
|
||||
outstandingSendRequest_ = -1;
|
||||
outstandingRecvRequest_ = -1;
|
||||
|
||||
// Consume straight from scalarReceiveBuf_
|
||||
|
||||
// Transform according to the transformation tensor
|
||||
transformCoupleField(scalarReceiveBuf_, cmpt);
|
||||
|
||||
// Multiply the field by coefficients and add into the result
|
||||
addToInternalField(result, !add, coeffs, scalarReceiveBuf_);
|
||||
}
|
||||
else
|
||||
{
|
||||
scalarField pnf
|
||||
(
|
||||
procInterface_.compressedReceive<scalar>(commsType, coeffs.size())
|
||||
);
|
||||
transformCoupleField(pnf, cmpt);
|
||||
|
||||
addToInternalField(result, !add, coeffs, pnf);
|
||||
}
|
||||
|
||||
const_cast<calculatedProcessorGAMGInterfaceField&>(*this).updatedMatrix()
|
||||
= true;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
@ -0,0 +1,208 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Class
|
||||
Foam::calculatedProcessorGAMGInterfaceField
|
||||
|
||||
Description
|
||||
GAMG agglomerated processor interface field.
|
||||
|
||||
SourceFiles
|
||||
calculatedProcessorGAMGInterfaceField.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef calculatedProcessorGAMGInterfaceField_H
|
||||
#define calculatedProcessorGAMGInterfaceField_H
|
||||
|
||||
#include "GAMGInterfaceField.H"
|
||||
#include "calculatedProcessorGAMGInterface.H"
|
||||
#include "processorLduInterfaceField.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class calculatedProcessorGAMGInterfaceField Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class calculatedProcessorGAMGInterfaceField
|
||||
:
|
||||
public GAMGInterfaceField,
|
||||
public processorLduInterfaceField
|
||||
{
|
||||
// Private data
|
||||
|
||||
//- Local reference cast into the processor interface
|
||||
const calculatedProcessorGAMGInterface& procInterface_;
|
||||
|
||||
//- Is the transform required
|
||||
bool doTransform_;
|
||||
|
||||
//- Rank of component for transformation
|
||||
int rank_;
|
||||
|
||||
|
||||
// Sending and receiving
|
||||
|
||||
//- Outstanding request
|
||||
mutable label outstandingSendRequest_;
|
||||
|
||||
//- Outstanding request
|
||||
mutable label outstandingRecvRequest_;
|
||||
|
||||
//- Scalar send buffer
|
||||
mutable Field<scalar> scalarSendBuf_;
|
||||
|
||||
//- Scalar receive buffer
|
||||
mutable Field<scalar> scalarReceiveBuf_;
|
||||
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- No copy construct
|
||||
calculatedProcessorGAMGInterfaceField
|
||||
(
|
||||
const calculatedProcessorGAMGInterfaceField&
|
||||
) = delete;
|
||||
|
||||
//- No copy assignment
|
||||
void operator=(const calculatedProcessorGAMGInterfaceField&) = delete;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("calculatedProcessor");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from GAMG interface and fine level interface field
|
||||
calculatedProcessorGAMGInterfaceField
|
||||
(
|
||||
const GAMGInterface& GAMGCp,
|
||||
const lduInterfaceField& fineInterface
|
||||
);
|
||||
|
||||
//- Construct from GAMG interface and fine level interface field
|
||||
calculatedProcessorGAMGInterfaceField
|
||||
(
|
||||
const GAMGInterface& GAMGCp,
|
||||
const bool doTransform,
|
||||
const int rank
|
||||
);
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~calculatedProcessorGAMGInterfaceField();
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
// Access
|
||||
|
||||
//- Return size
|
||||
label size() const
|
||||
{
|
||||
return procInterface_.size();
|
||||
}
|
||||
|
||||
|
||||
// Interface matrix update
|
||||
|
||||
//- Initialise neighbour matrix update
|
||||
virtual void initInterfaceMatrixUpdate
|
||||
(
|
||||
scalarField& result,
|
||||
const bool add,
|
||||
const scalarField& psiInternal,
|
||||
const scalarField& coeffs,
|
||||
const direction cmpt,
|
||||
const Pstream::commsTypes commsType
|
||||
) const;
|
||||
|
||||
//- Update result field based on interface functionality
|
||||
virtual void updateInterfaceMatrix
|
||||
(
|
||||
scalarField& result,
|
||||
const bool add,
|
||||
const scalarField& psiInternal,
|
||||
const scalarField& coeffs,
|
||||
const direction cmpt,
|
||||
const Pstream::commsTypes commsType
|
||||
) const;
|
||||
|
||||
|
||||
//- Processor interface functions
|
||||
|
||||
//- Return communicator used for comms
|
||||
virtual label comm() const
|
||||
{
|
||||
return procInterface_.comm();
|
||||
}
|
||||
|
||||
//- Return processor number
|
||||
virtual int myProcNo() const
|
||||
{
|
||||
return procInterface_.myProcNo();
|
||||
}
|
||||
|
||||
//- Return neighbour processor number
|
||||
virtual int neighbProcNo() const
|
||||
{
|
||||
return procInterface_.neighbProcNo();
|
||||
}
|
||||
|
||||
//- Does the interface field perform the transformation
|
||||
virtual bool doTransform() const
|
||||
{
|
||||
return doTransform_;
|
||||
}
|
||||
|
||||
//- Return face transformation tensor
|
||||
virtual const tensorField& forwardT() const
|
||||
{
|
||||
return procInterface_.forwardT();
|
||||
}
|
||||
|
||||
//- Return rank of component for transform
|
||||
virtual int rank() const
|
||||
{
|
||||
return rank_;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
@ -0,0 +1,348 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "calculatedProcessorFvPatchField.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
Foam::calculatedProcessorFvPatchField<Type>::calculatedProcessorFvPatchField
|
||||
(
|
||||
const lduInterface& interface,
|
||||
const fvPatch& p,
|
||||
const DimensionedField<Type, volMesh>& iF
|
||||
)
|
||||
:
|
||||
//lduInterfaceField(interface),
|
||||
coupledFvPatchField<Type>(p, iF),
|
||||
procInterface_(refCast<const lduPrimitiveProcessorInterface>(interface)),
|
||||
sendBuf_(interface.faceCells().size()),
|
||||
receiveBuf_(interface.faceCells().size()),
|
||||
scalarSendBuf_(interface.faceCells().size()),
|
||||
scalarReceiveBuf_(interface.faceCells().size()),
|
||||
outstandingSendRequest_(-1),
|
||||
outstandingRecvRequest_(-1)
|
||||
{}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::calculatedProcessorFvPatchField<Type>::calculatedProcessorFvPatchField
|
||||
(
|
||||
const calculatedProcessorFvPatchField<Type>& ptf
|
||||
)
|
||||
:
|
||||
//lduInterfaceField(ptf.procInterface_),
|
||||
coupledFvPatchField<Type>(ptf),
|
||||
procInterface_(ptf.procInterface_),
|
||||
sendBuf_(procInterface_.faceCells().size()),
|
||||
receiveBuf_(procInterface_.faceCells().size()),
|
||||
scalarSendBuf_(procInterface_.faceCells().size()),
|
||||
scalarReceiveBuf_(procInterface_.faceCells().size()),
|
||||
outstandingSendRequest_(-1),
|
||||
outstandingRecvRequest_(-1)
|
||||
|
||||
{}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::calculatedProcessorFvPatchField<Type>::calculatedProcessorFvPatchField
|
||||
(
|
||||
const calculatedProcessorFvPatchField<Type>& ptf,
|
||||
const DimensionedField<Type, volMesh>& iF
|
||||
)
|
||||
:
|
||||
//lduInterfaceField(ptf.procInterface_),
|
||||
coupledFvPatchField<Type>(ptf, iF),
|
||||
procInterface_(ptf.procInterface_),
|
||||
sendBuf_(procInterface_.faceCells().size()),
|
||||
receiveBuf_(procInterface_.faceCells().size()),
|
||||
scalarSendBuf_(procInterface_.faceCells().size()),
|
||||
scalarReceiveBuf_(procInterface_.faceCells().size()),
|
||||
outstandingSendRequest_(-1),
|
||||
outstandingRecvRequest_(-1)
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
bool Foam::calculatedProcessorFvPatchField<Type>::ready() const
|
||||
{
|
||||
if
|
||||
(
|
||||
this->outstandingSendRequest_ >= 0
|
||||
&& this->outstandingSendRequest_ < Pstream::nRequests()
|
||||
)
|
||||
{
|
||||
bool finished =
|
||||
UPstream::finishedRequest(this->outstandingSendRequest_);
|
||||
if (!finished)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
this->outstandingSendRequest_ = -1;
|
||||
|
||||
if
|
||||
(
|
||||
this->outstandingRecvRequest_ >= 0
|
||||
&& this->outstandingRecvRequest_ < Pstream::nRequests()
|
||||
)
|
||||
{
|
||||
bool finished =
|
||||
UPstream::finishedRequest(this->outstandingRecvRequest_);
|
||||
if (!finished)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
this->outstandingRecvRequest_ = -1;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::Field<Type>>
|
||||
Foam::calculatedProcessorFvPatchField<Type>::patchNeighbourField() const
|
||||
{
|
||||
if (debug && !this->ready())
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "On patch of size " << procInterface_.faceCells().size()
|
||||
<< " between proc " << procInterface_.myProcNo()
|
||||
<< " and " << procInterface_.neighbProcNo()
|
||||
<< " outstanding request."
|
||||
<< abort(FatalError);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
void Foam::calculatedProcessorFvPatchField<Type>::initEvaluate
|
||||
(
|
||||
const Pstream::commsTypes commsType
|
||||
)
|
||||
{
|
||||
if (Pstream::parRun())
|
||||
{
|
||||
//this->patchInternalField(sendBuf_);
|
||||
// Bypass patchInternalField since uses fvPatch addressing
|
||||
{
|
||||
const Field<Type>& iF = this->internalField();
|
||||
const labelList& fc = procInterface_.faceCells();
|
||||
sendBuf_.setSize(fc.size());
|
||||
forAll(fc, i)
|
||||
{
|
||||
sendBuf_[i] = iF[fc[i]];
|
||||
}
|
||||
}
|
||||
|
||||
// Receive straight into *this
|
||||
this->setSize(sendBuf_.size());
|
||||
outstandingRecvRequest_ = UPstream::nRequests();
|
||||
UIPstream::read
|
||||
(
|
||||
Pstream::commsTypes::nonBlocking,
|
||||
procInterface_.neighbProcNo(),
|
||||
reinterpret_cast<char*>(this->begin()),
|
||||
this->byteSize(),
|
||||
procInterface_.tag(),
|
||||
procInterface_.comm()
|
||||
);
|
||||
|
||||
outstandingSendRequest_ = UPstream::nRequests();
|
||||
UOPstream::write
|
||||
(
|
||||
Pstream::commsTypes::nonBlocking,
|
||||
procInterface_.neighbProcNo(),
|
||||
reinterpret_cast<const char*>(sendBuf_.begin()),
|
||||
this->byteSize(),
|
||||
procInterface_.tag(),
|
||||
procInterface_.comm()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
void Foam::calculatedProcessorFvPatchField<Type>::evaluate
|
||||
(
|
||||
const Pstream::commsTypes commsType
|
||||
)
|
||||
{
|
||||
if (Pstream::parRun())
|
||||
{
|
||||
if
|
||||
(
|
||||
outstandingRecvRequest_ >= 0
|
||||
&& outstandingRecvRequest_ < Pstream::nRequests()
|
||||
)
|
||||
{
|
||||
UPstream::waitRequest(outstandingRecvRequest_);
|
||||
}
|
||||
outstandingSendRequest_ = -1;
|
||||
outstandingRecvRequest_ = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
void Foam::calculatedProcessorFvPatchField<Type>::initInterfaceMatrixUpdate
|
||||
(
|
||||
scalarField& result,
|
||||
const bool add,
|
||||
const scalarField& psiInternal,
|
||||
const scalarField& coeffs,
|
||||
const direction cmpt,
|
||||
const Pstream::commsTypes commsType
|
||||
) const
|
||||
{
|
||||
// Bypass patchInternalField since uses fvPatch addressing
|
||||
const labelList& fc = procInterface_.faceCells();
|
||||
scalarSendBuf_.setSize(fc.size());
|
||||
forAll(fc, i)
|
||||
{
|
||||
scalarSendBuf_[i] = psiInternal[fc[i]];
|
||||
}
|
||||
|
||||
if (debug && !this->ready())
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "On patch " //<< interface_.name()
|
||||
<< " outstanding request."
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
|
||||
scalarReceiveBuf_.setSize(scalarSendBuf_.size());
|
||||
outstandingRecvRequest_ = UPstream::nRequests();
|
||||
UIPstream::read
|
||||
(
|
||||
Pstream::commsTypes::nonBlocking,
|
||||
procInterface_.neighbProcNo(),
|
||||
reinterpret_cast<char*>(scalarReceiveBuf_.begin()),
|
||||
scalarReceiveBuf_.byteSize(),
|
||||
procInterface_.tag(),
|
||||
procInterface_.comm()
|
||||
);
|
||||
|
||||
outstandingSendRequest_ = UPstream::nRequests();
|
||||
UOPstream::write
|
||||
(
|
||||
Pstream::commsTypes::nonBlocking,
|
||||
procInterface_.neighbProcNo(),
|
||||
reinterpret_cast<const char*>(scalarSendBuf_.begin()),
|
||||
scalarSendBuf_.byteSize(),
|
||||
procInterface_.tag(),
|
||||
procInterface_.comm()
|
||||
);
|
||||
|
||||
const_cast<lduInterfaceField&>
|
||||
(
|
||||
static_cast<const lduInterfaceField&>(*this)
|
||||
).updatedMatrix() = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<class Type>
|
||||
void Foam::calculatedProcessorFvPatchField<Type>::addToInternalField
|
||||
(
|
||||
scalarField& result,
|
||||
const bool add,
|
||||
const scalarField& coeffs,
|
||||
const scalarField& vals
|
||||
) const
|
||||
{
|
||||
const labelUList& faceCells = this->procInterface_.faceCells();
|
||||
|
||||
if (add)
|
||||
{
|
||||
forAll(faceCells, elemI)
|
||||
{
|
||||
result[faceCells[elemI]] += coeffs[elemI]*vals[elemI];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
forAll(faceCells, elemI)
|
||||
{
|
||||
result[faceCells[elemI]] -= coeffs[elemI]*vals[elemI];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
void Foam::calculatedProcessorFvPatchField<Type>::updateInterfaceMatrix
|
||||
(
|
||||
scalarField& result,
|
||||
const bool add,
|
||||
const scalarField& psiInternal,
|
||||
const scalarField& coeffs,
|
||||
const direction cmpt,
|
||||
const Pstream::commsTypes commsType
|
||||
) const
|
||||
{
|
||||
if (this->updatedMatrix())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if
|
||||
(
|
||||
outstandingRecvRequest_ >= 0
|
||||
&& outstandingRecvRequest_ < Pstream::nRequests()
|
||||
)
|
||||
{
|
||||
UPstream::waitRequest(outstandingRecvRequest_);
|
||||
}
|
||||
// Recv finished so assume sending finished as well.
|
||||
outstandingSendRequest_ = -1;
|
||||
outstandingRecvRequest_ = -1;
|
||||
|
||||
// Consume straight from scalarReceiveBuf_. Note use of our own
|
||||
// helper to avoid using fvPatch addressing
|
||||
addToInternalField(result, !add, coeffs, scalarReceiveBuf_);
|
||||
|
||||
const_cast<lduInterfaceField&>
|
||||
(
|
||||
static_cast<const lduInterfaceField&>(*this)
|
||||
).updatedMatrix() = true;
|
||||
}
|
||||
|
||||
|
||||
//template<class Type>
|
||||
//void Foam::calculatedProcessorFvPatchField<Type>::write(Ostream& os) const
|
||||
//{
|
||||
// //zeroGradientFvPatchField<Type>::write(os);
|
||||
// fvPatchField<Type>::write(os);
|
||||
// this->writeEntry("value", os);
|
||||
//}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
@ -0,0 +1,306 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Class
|
||||
Foam::calculatedProcessorFvPatchField
|
||||
|
||||
Group
|
||||
grpGenericBoundaryConditions
|
||||
|
||||
Description
|
||||
processorFvPatchField type bypassing fvPatch
|
||||
|
||||
Used to temporarily add updateInterfaceMatrix capabilities to a matrix
|
||||
during overset solving. Supplies:
|
||||
- patchNeighbourField functionality (cached in *this as per
|
||||
processorFvPatchField)
|
||||
- initEvaluate/evaluate: caching of patchNeighbourField (see above)
|
||||
- initInterfaceMatrixUpdate etc: adding of neighbouring data
|
||||
|
||||
SourceFiles
|
||||
calculatedProcessorFvPatchField.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef calculatedProcessorFvPatchField_H
|
||||
#define calculatedProcessorFvPatchField_H
|
||||
|
||||
#include "lduPrimitiveProcessorInterface.H"
|
||||
//#include "lduInterfaceField.H"
|
||||
//#include "fvPatchField.H"
|
||||
#include "coupledFvPatchField.H"
|
||||
#include "processorLduInterfaceField.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class calculatedProcessorFvPatchField Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
template<class Type>
|
||||
class calculatedProcessorFvPatchField
|
||||
:
|
||||
public processorLduInterfaceField,
|
||||
public coupledFvPatchField<Type>
|
||||
{
|
||||
protected:
|
||||
|
||||
// Private data
|
||||
|
||||
//- Local reference cast into the interface
|
||||
const lduPrimitiveProcessorInterface& procInterface_;
|
||||
|
||||
// Sending and receiving
|
||||
|
||||
//- Send buffer
|
||||
mutable Field<Type> sendBuf_;
|
||||
|
||||
//- Receive buffer
|
||||
mutable Field<Type> receiveBuf_;
|
||||
|
||||
//- Scalar send buffer
|
||||
mutable Field<scalar> scalarSendBuf_;
|
||||
|
||||
//- Scalar receive buffer
|
||||
mutable Field<scalar> scalarReceiveBuf_;
|
||||
|
||||
//- Outstanding request
|
||||
mutable label outstandingSendRequest_;
|
||||
|
||||
//- Outstanding request
|
||||
mutable label outstandingRecvRequest_;
|
||||
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
void addToInternalField
|
||||
(
|
||||
scalarField& result,
|
||||
const bool add,
|
||||
const scalarField& coeffs,
|
||||
const scalarField& vals
|
||||
) const;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("calculatedProcessor");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from patch and internal field
|
||||
calculatedProcessorFvPatchField
|
||||
(
|
||||
const lduInterface& interface,
|
||||
const fvPatch&,
|
||||
const DimensionedField<Type, volMesh>&
|
||||
);
|
||||
|
||||
//- Construct as copy
|
||||
calculatedProcessorFvPatchField
|
||||
(
|
||||
const calculatedProcessorFvPatchField<Type>&
|
||||
);
|
||||
|
||||
//- Construct and return a clone
|
||||
virtual tmp<fvPatchField<Type>> clone() const
|
||||
{
|
||||
return tmp<fvPatchField<Type>>
|
||||
(
|
||||
new calculatedProcessorFvPatchField<Type>(*this)
|
||||
);
|
||||
}
|
||||
|
||||
//- Construct as copy setting internal field reference
|
||||
calculatedProcessorFvPatchField
|
||||
(
|
||||
const calculatedProcessorFvPatchField<Type>&,
|
||||
const DimensionedField<Type, volMesh>&
|
||||
);
|
||||
|
||||
//- Construct and return a clone setting internal field reference
|
||||
virtual tmp<fvPatchField<Type>> clone
|
||||
(
|
||||
const DimensionedField<Type, volMesh>& iF
|
||||
) const
|
||||
{
|
||||
return tmp<fvPatchField<Type>>
|
||||
(
|
||||
new calculatedProcessorFvPatchField<Type>(*this, iF)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~calculatedProcessorFvPatchField() = default;
|
||||
|
||||
|
||||
// Member functions
|
||||
|
||||
// processorLduInterfaceField implementation
|
||||
|
||||
//- Return communicator used for comms
|
||||
virtual label comm() const
|
||||
{
|
||||
return procInterface_.comm();
|
||||
}
|
||||
|
||||
//- Return processor number
|
||||
virtual int myProcNo() const
|
||||
{
|
||||
return procInterface_.myProcNo();
|
||||
}
|
||||
|
||||
|
||||
//- Return neighbour processor number
|
||||
virtual int neighbProcNo() const
|
||||
{
|
||||
return procInterface_.myProcNo();
|
||||
}
|
||||
|
||||
//- Is the transform required
|
||||
virtual bool doTransform() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//- Return face transformation tensor
|
||||
virtual const tensorField& forwardT() const
|
||||
{
|
||||
return procInterface_.forwardT();
|
||||
}
|
||||
|
||||
//- Return rank of component for transform
|
||||
virtual int rank() const
|
||||
{
|
||||
return pTraits<Type>::rank;
|
||||
}
|
||||
|
||||
|
||||
// Access
|
||||
|
||||
//- Return true if this patch field is coupled. Our field supplies
|
||||
// coefficients to the fvMatrix so should behave as a
|
||||
// processorFvPatchField (in addBoundarySource it should not add
|
||||
// to the source)
|
||||
virtual bool coupled() const
|
||||
{
|
||||
if (Pstream::parRun())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//- Return neighbour field of internal field
|
||||
virtual tmp<Field<Type>> patchNeighbourField() const;
|
||||
|
||||
|
||||
// Evaluation functions
|
||||
|
||||
//- Is all data available
|
||||
virtual bool ready() const;
|
||||
|
||||
//- 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);
|
||||
|
||||
//- Initialise neighbour matrix update
|
||||
virtual void initInterfaceMatrixUpdate
|
||||
(
|
||||
scalarField& result,
|
||||
const bool add,
|
||||
const scalarField& psiInternal,
|
||||
const scalarField& coeffs,
|
||||
const direction cmpt,
|
||||
const Pstream::commsTypes commsType
|
||||
) const;
|
||||
|
||||
//- Update result field based on interface functionality
|
||||
virtual void updateInterfaceMatrix
|
||||
(
|
||||
scalarField& result,
|
||||
const bool add,
|
||||
const scalarField& psiInternal,
|
||||
const scalarField& coeffs,
|
||||
const direction cmpt,
|
||||
const Pstream::commsTypes commsType
|
||||
) const;
|
||||
|
||||
//- Initialise neighbour matrix update
|
||||
virtual void initInterfaceMatrixUpdate
|
||||
(
|
||||
Field<Type>& result,
|
||||
const bool add,
|
||||
const Field<Type>& psiInternal,
|
||||
const scalarField& coeffs,
|
||||
const Pstream::commsTypes commsType
|
||||
) const
|
||||
{
|
||||
NotImplemented;
|
||||
}
|
||||
|
||||
//- Update result field based on interface functionality
|
||||
virtual void updateInterfaceMatrix
|
||||
(
|
||||
Field<Type>& result,
|
||||
const bool add,
|
||||
const Field<Type>& psiInternal,
|
||||
const scalarField& coeffs,
|
||||
const Pstream::commsTypes commsType
|
||||
) const
|
||||
{
|
||||
NotImplemented;
|
||||
}
|
||||
|
||||
//- Write
|
||||
//virtual void write(Ostream&) const;
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#ifdef NoRepository
|
||||
#include "calculatedProcessorFvPatchField.C"
|
||||
#endif
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
@ -0,0 +1,52 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "calculatedProcessorFvPatchFields.H"
|
||||
#include "fvPatchFields.H"
|
||||
#include "volMesh.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
defineNamedTemplateTypeNameAndDebug(calculatedProcessorFvPatchScalarField, 0);
|
||||
defineNamedTemplateTypeNameAndDebug(calculatedProcessorFvPatchVectorField, 0);
|
||||
defineNamedTemplateTypeNameAndDebug
|
||||
(
|
||||
calculatedProcessorFvPatchSphericalTensorField,
|
||||
0
|
||||
);
|
||||
defineNamedTemplateTypeNameAndDebug(calculatedProcessorFvPatchSymmTensorField, 0);
|
||||
defineNamedTemplateTypeNameAndDebug(calculatedProcessorFvPatchTensorField, 0);
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// ************************************************************************* //
|
@ -0,0 +1,49 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef calculatedProcessorFvPatchFields_H
|
||||
#define calculatedProcessorFvPatchFields_H
|
||||
|
||||
#include "calculatedProcessorFvPatchField.H"
|
||||
#include "fieldTypes.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
makePatchTypeFieldTypedefs(calculatedProcessor);
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
@ -0,0 +1,50 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef calculatedProcessorFvPatchFieldsFwd_H
|
||||
#define calculatedProcessorFvPatchFieldsFwd_H
|
||||
|
||||
#include "fieldTypes.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type> class calculatedProcessorFvPatchField;
|
||||
|
||||
makePatchTypeFieldTypedefs(calculatedProcessor);
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
@ -30,7 +30,7 @@ License
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug(lduPrimitiveProcessorInterface, 0);
|
||||
defineTypeName(lduPrimitiveProcessorInterface);
|
||||
}
|
||||
|
||||
|
||||
|
@ -90,7 +90,7 @@ class lduPrimitiveProcessorInterface
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("primitiveProcessor");
|
||||
TypeName("calculatedProcessor");
|
||||
|
||||
|
||||
// Constructors
|
||||
@ -180,10 +180,13 @@ public:
|
||||
}
|
||||
|
||||
|
||||
// // I/O
|
||||
//
|
||||
// //- Write to stream
|
||||
// virtual void write(Ostream&) const;
|
||||
// Edit
|
||||
|
||||
//- Return message tag used for sending
|
||||
int& tag()
|
||||
{
|
||||
return tag_;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2016-2017 OpenCFD Ltd.
|
||||
\\ / A nd | Copyright (C) 2016-2019 OpenCFD Ltd.
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
@ -41,75 +41,4 @@ namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
Foam::tmp<Foam::labelField> Foam::oversetFvPatch::interfaceInternalField
|
||||
(
|
||||
const labelUList& internalData
|
||||
) const
|
||||
{
|
||||
return patchInternalField(internalData);
|
||||
}
|
||||
|
||||
|
||||
Foam::tmp<Foam::labelField> Foam::oversetFvPatch::internalFieldTransfer
|
||||
(
|
||||
const Pstream::commsTypes commsType,
|
||||
const labelUList& restrictMap
|
||||
) const
|
||||
{
|
||||
// Store the restrictMap. This routine gets used for
|
||||
// - GAMGAgglomeration : this is the use we want to intercept.
|
||||
// - GAMGProcAgglomeration : to find out the cell number on the other side
|
||||
// - MGridGenGAMGAgglomeration: same
|
||||
if (master())
|
||||
{
|
||||
restrictMap_ = restrictMap;
|
||||
}
|
||||
|
||||
return patchInternalField(restrictMap);
|
||||
}
|
||||
|
||||
|
||||
const Foam::labelListList& Foam::oversetFvPatch::stencil() const
|
||||
{
|
||||
const cellCellStencilObject& overlap = Stencil::New(boundaryMesh().mesh());
|
||||
|
||||
return overlap.cellStencil();
|
||||
}
|
||||
|
||||
|
||||
const Foam::mapDistribute& Foam::oversetFvPatch::cellInterpolationMap() const
|
||||
{
|
||||
const cellCellStencilObject& overlap = Stencil::New(boundaryMesh().mesh());
|
||||
return overlap.cellInterpolationMap();
|
||||
}
|
||||
|
||||
|
||||
const Foam::List<Foam::scalarList>&
|
||||
Foam::oversetFvPatch::cellInterpolationWeights() const
|
||||
{
|
||||
const cellCellStencilObject& overlap = Stencil::New(boundaryMesh().mesh());
|
||||
return overlap.cellInterpolationWeights();
|
||||
}
|
||||
|
||||
|
||||
const Foam::scalarField& Foam::oversetFvPatch::normalisation() const
|
||||
{
|
||||
return boundaryMesh().mesh().V().field();
|
||||
}
|
||||
|
||||
|
||||
const Foam::labelList& Foam::oversetFvPatch::interpolationCells() const
|
||||
{
|
||||
const cellCellStencilObject& overlap = Stencil::New(boundaryMesh().mesh());
|
||||
return overlap.interpolationCells();
|
||||
}
|
||||
|
||||
|
||||
const Foam::scalarList& Foam::oversetFvPatch::cellInterpolationWeight() const
|
||||
{
|
||||
const cellCellStencilObject& overlap = Stencil::New(boundaryMesh().mesh());
|
||||
return overlap.cellInterpolationWeight();
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
|
@ -2,7 +2,7 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2016-2017 OpenCFD Ltd.
|
||||
\\ / A nd | Copyright (C) 2016-2019 OpenCFD Ltd.
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
@ -38,8 +38,6 @@ SourceFiles
|
||||
#include "fvPatch.H"
|
||||
#include "oversetPolyPatch.H"
|
||||
#include "fvBoundaryMesh.H"
|
||||
#include "lduInterface.H"
|
||||
#include "oversetLduInterface.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
@ -52,18 +50,12 @@ namespace Foam
|
||||
|
||||
class oversetFvPatch
|
||||
:
|
||||
public lduInterface,
|
||||
public oversetLduInterface,
|
||||
public fvPatch
|
||||
{
|
||||
// Private data
|
||||
|
||||
const oversetPolyPatch& oversetPolyPatch_;
|
||||
|
||||
//- Temporary copy of the fine level restrict map. Cleared upon
|
||||
// calculating stencils below
|
||||
mutable labelList restrictMap_;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
@ -100,61 +92,11 @@ public:
|
||||
return oversetPolyPatch_.faceCells();
|
||||
}
|
||||
|
||||
|
||||
// Interface transfer functions
|
||||
|
||||
//- Return the values of the given internal data adjacent to
|
||||
// the interface as a field
|
||||
virtual tmp<labelField> interfaceInternalField
|
||||
(
|
||||
const labelUList& internalData
|
||||
) const;
|
||||
|
||||
//- Return neighbour field
|
||||
virtual tmp<labelField> internalFieldTransfer
|
||||
(
|
||||
const Pstream::commsTypes commsType,
|
||||
const labelUList& internalData
|
||||
) const;
|
||||
|
||||
|
||||
//- Overset interface functions
|
||||
|
||||
//- Name of interface (for debugging)
|
||||
virtual const word& name() const
|
||||
{
|
||||
return oversetPolyPatch_.name();
|
||||
}
|
||||
|
||||
//- Am I the master interface
|
||||
virtual bool master() const
|
||||
{
|
||||
return oversetPolyPatch_.master();
|
||||
}
|
||||
|
||||
//- GAMG restriction (fine-to-coarse)
|
||||
virtual const labelList& restrictMap() const
|
||||
{
|
||||
return restrictMap_;
|
||||
}
|
||||
|
||||
//- Donor stencil
|
||||
virtual const labelListList& stencil() const;
|
||||
|
||||
//- Map for obtaining data in stencil order
|
||||
virtual const mapDistribute& cellInterpolationMap() const;
|
||||
|
||||
//- Weights in stencil order
|
||||
virtual const List<scalarList>& cellInterpolationWeights() const;
|
||||
|
||||
//- Normalisation of matrix; for explicit contributions
|
||||
virtual const scalarField& normalisation() const;
|
||||
|
||||
//- Acceptor cells
|
||||
virtual const labelList& interpolationCells() const;
|
||||
|
||||
//- Underrelaxation for acceptor cells
|
||||
virtual const scalarList& cellInterpolationWeight() const;
|
||||
};
|
||||
|
||||
|
||||
|
@ -37,7 +37,8 @@ Foam::oversetFvPatchField<Type>::oversetFvPatchField
|
||||
const DimensionedField<Type, volMesh>& iF
|
||||
)
|
||||
:
|
||||
semiImplicitOversetFvPatchField<Type>(p, iF)
|
||||
zeroGradientFvPatchField<Type>(p, iF),
|
||||
oversetPatch_(refCast<const oversetFvPatch>(p))
|
||||
{}
|
||||
|
||||
|
||||
@ -50,7 +51,8 @@ Foam::oversetFvPatchField<Type>::oversetFvPatchField
|
||||
const fvPatchFieldMapper& mapper
|
||||
)
|
||||
:
|
||||
semiImplicitOversetFvPatchField<Type>(ptf, p, iF, mapper)
|
||||
zeroGradientFvPatchField<Type>(ptf, p, iF, mapper),
|
||||
oversetPatch_(refCast<const oversetFvPatch>(p))
|
||||
{}
|
||||
|
||||
|
||||
@ -62,7 +64,8 @@ Foam::oversetFvPatchField<Type>::oversetFvPatchField
|
||||
const dictionary& dict
|
||||
)
|
||||
:
|
||||
semiImplicitOversetFvPatchField<Type>(p, iF, dict)
|
||||
zeroGradientFvPatchField<Type>(p, iF, dict),
|
||||
oversetPatch_(refCast<const oversetFvPatch>(p, dict))
|
||||
{}
|
||||
|
||||
|
||||
@ -72,7 +75,8 @@ Foam::oversetFvPatchField<Type>::oversetFvPatchField
|
||||
const oversetFvPatchField<Type>& ptf
|
||||
)
|
||||
:
|
||||
semiImplicitOversetFvPatchField<Type>(ptf)
|
||||
zeroGradientFvPatchField<Type>(ptf),
|
||||
oversetPatch_(ptf.oversetPatch_)
|
||||
{}
|
||||
|
||||
|
||||
@ -83,7 +87,8 @@ Foam::oversetFvPatchField<Type>::oversetFvPatchField
|
||||
const DimensionedField<Type, volMesh>& iF
|
||||
)
|
||||
:
|
||||
semiImplicitOversetFvPatchField<Type>(ptf, iF)
|
||||
zeroGradientFvPatchField<Type>(ptf, iF),
|
||||
oversetPatch_(ptf.oversetPatch_)
|
||||
{}
|
||||
|
||||
|
||||
@ -211,137 +216,138 @@ void Foam::oversetFvPatchField<Type>::initEvaluate
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
void Foam::oversetFvPatchField<Type>::initInterfaceMatrixUpdate
|
||||
(
|
||||
scalarField&,
|
||||
const bool add,
|
||||
const scalarField& psiInternal,
|
||||
const scalarField&,
|
||||
const direction,
|
||||
const Pstream::commsTypes commsType
|
||||
) const
|
||||
{
|
||||
// Add remote values
|
||||
|
||||
const oversetFvPatch& ovp = this->oversetPatch_;
|
||||
|
||||
if (ovp.master())
|
||||
{
|
||||
const fvMesh& mesh = this->patch().boundaryMesh().mesh();
|
||||
|
||||
// Try to find out if the solve routine comes from the mesh
|
||||
// TBD. This should be cleaner.
|
||||
if (&mesh.lduAddr() == &mesh.fvMesh::lduAddr())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const mapDistribute& map = ovp.cellInterpolationMap();
|
||||
|
||||
// Transfer the current state (similar to processorFvPatchField). Note
|
||||
// use of separate tag to avoid clashes with any outstanding processor
|
||||
// exchanges
|
||||
if (this->pBufs_.valid())
|
||||
{
|
||||
this->pBufs_().clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
this->pBufs_.set
|
||||
(
|
||||
new PstreamBuffers
|
||||
(
|
||||
Pstream::commsTypes::nonBlocking,
|
||||
UPstream::msgType()+1
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Start sending
|
||||
map.mapDistributeBase::send(this->pBufs_(), psiInternal);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
void Foam::oversetFvPatchField<Type>::updateInterfaceMatrix
|
||||
(
|
||||
scalarField& result,
|
||||
const bool add,
|
||||
const scalarField& psiInternal,
|
||||
const scalarField& coeffs,
|
||||
const direction cmpt,
|
||||
const Pstream::commsTypes
|
||||
) const
|
||||
{
|
||||
// Add remote values
|
||||
|
||||
const oversetFvPatch& ovp = this->oversetPatch_;
|
||||
|
||||
if (ovp.master())
|
||||
{
|
||||
const fvMesh& mesh = this->patch().boundaryMesh().mesh();
|
||||
|
||||
// Try to find out if the solve routine comes from the mesh
|
||||
// TBD. This should be cleaner.
|
||||
if (&mesh.lduAddr() == &mesh.fvMesh::lduAddr())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const labelListList& stencil = ovp.stencil();
|
||||
|
||||
if (stencil.size() != psiInternal.size())
|
||||
{
|
||||
FatalErrorInFunction << "psiInternal:" << psiInternal.size()
|
||||
<< " stencil:" << stencil.size() << exit(FatalError);
|
||||
}
|
||||
|
||||
const mapDistribute& map = ovp.cellInterpolationMap();
|
||||
const List<scalarList>& wghts = ovp.cellInterpolationWeights();
|
||||
const labelList& cellIDs = ovp.interpolationCells();
|
||||
const scalarList& factor = ovp.cellInterpolationWeight();
|
||||
const scalarField& normalisation = ovp.normalisation();
|
||||
|
||||
// Since we're inside initEvaluate/evaluate there might be processor
|
||||
// comms underway. Change the tag we use.
|
||||
//scalarField work(psiInternal);
|
||||
//map.mapDistributeBase::distribute(work, UPstream::msgType()+1);
|
||||
|
||||
// Receive the outstanding data
|
||||
scalarField work;
|
||||
map.receive(this->pBufs_(), work);
|
||||
|
||||
forAll(cellIDs, i)
|
||||
{
|
||||
label celli = cellIDs[i];
|
||||
|
||||
const scalarList& w = wghts[celli];
|
||||
const labelList& nbrs = stencil[celli];
|
||||
|
||||
scalar f = factor[celli];
|
||||
const scalar norm = normalisation[celli];
|
||||
|
||||
// Add the non-local matrix contribution to psi. Note that the
|
||||
// matrix coefficients are -weights
|
||||
|
||||
if (add)
|
||||
{
|
||||
f = -1.0*f;
|
||||
}
|
||||
|
||||
forAll(nbrs, nbrI)
|
||||
{
|
||||
label slotI = nbrs[nbrI];
|
||||
if (slotI >= psiInternal.size())
|
||||
{
|
||||
result[celli] += f*norm*w[nbrI]*work[slotI];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//template<class Type>
|
||||
//void Foam::oversetFvPatchField<Type>::initInterfaceMatrixUpdate
|
||||
//(
|
||||
// scalarField&,
|
||||
// const bool add,
|
||||
// const scalarField& psiInternal,
|
||||
// const scalarField&,
|
||||
// const direction,
|
||||
// const Pstream::commsTypes commsType
|
||||
//) const
|
||||
//{
|
||||
//// // Add remote values
|
||||
////
|
||||
//// const oversetFvPatch& ovp = this->oversetPatch_;
|
||||
////
|
||||
//// if (ovp.master())
|
||||
//// {
|
||||
//// const fvMesh& mesh = this->patch().boundaryMesh().mesh();
|
||||
////
|
||||
//// // Try to find out if the solve routine comes from the mesh
|
||||
//// // TBD. This should be cleaner.
|
||||
//// if (&mesh.lduAddr() == &mesh.fvMesh::lduAddr())
|
||||
//// {
|
||||
//// return;
|
||||
//// }
|
||||
////
|
||||
//// const mapDistribute& map = ovp.cellInterpolationMap();
|
||||
////
|
||||
//// // Transfer the current state (similar to processorFvPatchField).
|
||||
//// // Note
|
||||
//// // use of separate tag to avoid clashes with any outstanding
|
||||
//// // processor exchanges
|
||||
//// if (this->pBufs_.valid())
|
||||
//// {
|
||||
//// this->pBufs_().clear();
|
||||
//// }
|
||||
//// else
|
||||
//// {
|
||||
//// this->pBufs_.set
|
||||
//// (
|
||||
//// new PstreamBuffers
|
||||
//// (
|
||||
//// Pstream::commsTypes::nonBlocking,
|
||||
//// UPstream::msgType()+1
|
||||
//// )
|
||||
//// );
|
||||
//// }
|
||||
////
|
||||
//// // Start sending
|
||||
//// map.mapDistributeBase::send(this->pBufs_(), psiInternal);
|
||||
//// }
|
||||
//}
|
||||
//
|
||||
//
|
||||
//template<class Type>
|
||||
//void Foam::oversetFvPatchField<Type>::updateInterfaceMatrix
|
||||
//(
|
||||
// scalarField& result,
|
||||
// const bool add,
|
||||
// const scalarField& psiInternal,
|
||||
// const scalarField& coeffs,
|
||||
// const direction cmpt,
|
||||
// const Pstream::commsTypes
|
||||
//) const
|
||||
//{
|
||||
//// // Add remote values
|
||||
////
|
||||
//// const oversetFvPatch& ovp = this->oversetPatch_;
|
||||
////
|
||||
//// if (ovp.master())
|
||||
//// {
|
||||
//// const fvMesh& mesh = this->patch().boundaryMesh().mesh();
|
||||
////
|
||||
//// // Try to find out if the solve routine comes from the mesh
|
||||
//// // TBD. This should be cleaner.
|
||||
//// if (&mesh.lduAddr() == &mesh.fvMesh::lduAddr())
|
||||
//// {
|
||||
//// return;
|
||||
//// }
|
||||
////
|
||||
//// const labelListList& stencil = ovp.stencil();
|
||||
////
|
||||
//// if (stencil.size() != psiInternal.size())
|
||||
//// {
|
||||
//// FatalErrorInFunction << "psiInternal:" << psiInternal.size()
|
||||
//// << " stencil:" << stencil.size() << exit(FatalError);
|
||||
//// }
|
||||
////
|
||||
//// const mapDistribute& map = ovp.cellInterpolationMap();
|
||||
//// const List<scalarList>& wghts = ovp.cellInterpolationWeights();
|
||||
//// const labelList& cellIDs = ovp.interpolationCells();
|
||||
//// const scalarList& factor = ovp.cellInterpolationWeight();
|
||||
//// const scalarField& normalisation = ovp.normalisation();
|
||||
////
|
||||
//// // Since we're inside initEvaluate/evaluate there might be processor
|
||||
//// // comms underway. Change the tag we use.
|
||||
//// //scalarField work(psiInternal);
|
||||
//// //map.mapDistributeBase::distribute(work, UPstream::msgType()+1);
|
||||
////
|
||||
//// // Receive the outstanding data
|
||||
//// scalarField work;
|
||||
//// map.receive(this->pBufs_(), work);
|
||||
////
|
||||
//// forAll(cellIDs, i)
|
||||
//// {
|
||||
//// label celli = cellIDs[i];
|
||||
////
|
||||
//// const scalarList& w = wghts[celli];
|
||||
//// const labelList& nbrs = stencil[celli];
|
||||
////
|
||||
//// scalar f = factor[celli];
|
||||
//// const scalar norm = normalisation[celli];
|
||||
////
|
||||
//// // Add the non-local matrix contribution to psi. Note that the
|
||||
//// // matrix coefficients are -weights
|
||||
////
|
||||
//// if (add)
|
||||
//// {
|
||||
//// f = -1.0*f;
|
||||
//// }
|
||||
////
|
||||
//// forAll(nbrs, nbrI)
|
||||
//// {
|
||||
//// label slotI = nbrs[nbrI];
|
||||
//// if (slotI >= psiInternal.size())
|
||||
//// {
|
||||
//// result[celli] += f*norm*w[nbrI]*work[slotI];
|
||||
//// }
|
||||
//// }
|
||||
//// }
|
||||
//// }
|
||||
//}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
|
@ -29,8 +29,7 @@ Group
|
||||
|
||||
Description
|
||||
Boundary condition for use on overset patches. To be run in combination
|
||||
with special dynamicFvMesh type that inserts local contributions into
|
||||
the matrix. This boundary condition adds the remote contributions.
|
||||
with special dynamicFvMesh type that inserts interpolation into the matrix.
|
||||
|
||||
SourceFiles
|
||||
oversetFvPatchField.C
|
||||
@ -40,7 +39,8 @@ SourceFiles
|
||||
#ifndef oversetFvPatchField_H
|
||||
#define oversetFvPatchField_H
|
||||
|
||||
#include "semiImplicitOversetFvPatchField.H"
|
||||
#include "oversetFvPatch.H"
|
||||
#include "zeroGradientFvPatchField.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
@ -54,14 +54,20 @@ namespace Foam
|
||||
template<class Type>
|
||||
class oversetFvPatchField
|
||||
:
|
||||
public semiImplicitOversetFvPatchField<Type>
|
||||
public zeroGradientFvPatchField<Type>
|
||||
{
|
||||
protected:
|
||||
|
||||
// Protected data
|
||||
|
||||
//- Local reference cast into the overset patch
|
||||
const oversetFvPatch& oversetPatch_;
|
||||
|
||||
//- Master patch ID
|
||||
mutable label masterPatchID_;
|
||||
|
||||
//- Send/receive buffer
|
||||
mutable autoPtr<PstreamBuffers> pBufs_;
|
||||
//mutable autoPtr<PstreamBuffers> pBufs_;
|
||||
|
||||
|
||||
public:
|
||||
@ -135,30 +141,30 @@ public:
|
||||
//- Initialise the evaluation of the patch field
|
||||
virtual void initEvaluate(const Pstream::commsTypes commsType);
|
||||
|
||||
using LduInterfaceField<Type>::initInterfaceMatrixUpdate;
|
||||
|
||||
//- Initialise neighbour matrix update. Add
|
||||
//- or subtract coupled contributions to matrix
|
||||
virtual void initInterfaceMatrixUpdate
|
||||
(
|
||||
scalarField&,
|
||||
const bool add,
|
||||
const scalarField&,
|
||||
const scalarField&,
|
||||
const direction,
|
||||
const Pstream::commsTypes commsType
|
||||
) const;
|
||||
|
||||
//- Update result field based on interface functionality
|
||||
virtual void updateInterfaceMatrix
|
||||
(
|
||||
scalarField& result,
|
||||
const bool add,
|
||||
const scalarField& psiInternal,
|
||||
const scalarField& coeffs,
|
||||
const direction cmpt,
|
||||
const Pstream::commsTypes commsType
|
||||
) const;
|
||||
// using LduInterfaceField<Type>::initInterfaceMatrixUpdate;
|
||||
//
|
||||
// //- Initialise neighbour matrix update. Add
|
||||
// //- or subtract coupled contributions to matrix
|
||||
// virtual void initInterfaceMatrixUpdate
|
||||
// (
|
||||
// scalarField&,
|
||||
// const bool add,
|
||||
// const scalarField&,
|
||||
// const scalarField&,
|
||||
// const direction,
|
||||
// const Pstream::commsTypes commsType
|
||||
// ) const;
|
||||
//
|
||||
// //- Update result field based on interface functionality
|
||||
// virtual void updateInterfaceMatrix
|
||||
// (
|
||||
// scalarField& result,
|
||||
// const bool add,
|
||||
// const scalarField& psiInternal,
|
||||
// const scalarField& coeffs,
|
||||
// const direction cmpt,
|
||||
// const Pstream::commsTypes commsType
|
||||
// ) const;
|
||||
};
|
||||
|
||||
|
||||
|
@ -60,10 +60,10 @@ Foam::oversetGAMGInterface::oversetGAMGInterface
|
||||
refCast<const oversetLduInterface>(fineInterface)
|
||||
)
|
||||
{
|
||||
//Pout<< "Constructing oversetGAMGInterface index:" << index
|
||||
// << " from:" << fineOversetInterface_.name()
|
||||
// << " size:" << localRestrictAddressing.size()
|
||||
// << endl;
|
||||
Pout<< "Constructing oversetGAMGInterface index:" << index
|
||||
<< " from:" << fineOversetInterface_.name()
|
||||
<< " size:" << localRestrictAddressing.size()
|
||||
<< endl;
|
||||
|
||||
// From coarse face to coarse cell
|
||||
DynamicList<label> dynFaceCells(localRestrictAddressing.size());
|
||||
|
@ -72,80 +72,80 @@ void Foam::oversetGAMGInterfaceField::updateInterfaceMatrix
|
||||
const Pstream::commsTypes commsType
|
||||
) const
|
||||
{
|
||||
//Pout<< "oversetGAMGInterfaceField::updateInterfaceMatrix: at:"
|
||||
Pout<< "oversetGAMGInterfaceField::updateInterfaceMatrix: at:"
|
||||
// << oversetInterface_.name()
|
||||
// << " nCells:" << result.size() << endl;
|
||||
<< " nCells:" << result.size() << endl;
|
||||
//
|
||||
// Add remote values
|
||||
if (oversetInterface_.master())
|
||||
{
|
||||
const labelListList& stencil = oversetInterface_.stencil();
|
||||
|
||||
if (stencil.size() != psiInternal.size())
|
||||
{
|
||||
FatalErrorInFunction << "psiInternal:" << psiInternal.size()
|
||||
<< " stencil:" << stencil.size() << exit(FatalError);
|
||||
}
|
||||
|
||||
const mapDistribute& map = oversetInterface_.cellInterpolationMap();
|
||||
const List<scalarList>& wghts =
|
||||
oversetInterface_.cellInterpolationWeights();
|
||||
const labelList& cellIDs = oversetInterface_.interpolationCells();
|
||||
const scalarList& factor = oversetInterface_.cellInterpolationWeight();
|
||||
const scalarField& normalisation = oversetInterface_.normalisation();
|
||||
|
||||
scalarField work(psiInternal);
|
||||
map.mapDistributeBase::distribute(work, UPstream::msgType()+1);
|
||||
|
||||
forAll(cellIDs, i)
|
||||
{
|
||||
label celli = cellIDs[i];
|
||||
|
||||
const scalarList& w = wghts[celli];
|
||||
const labelList& nbrs = stencil[celli];
|
||||
const scalar f = factor[celli];
|
||||
|
||||
bool hasRemote = false;
|
||||
forAll(nbrs, nbrI)
|
||||
{
|
||||
label slotI = nbrs[nbrI];
|
||||
if (slotI >= psiInternal.size())
|
||||
{
|
||||
hasRemote = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasRemote)
|
||||
{
|
||||
//Pout<< "oversetGAMGInterfaceField : Interpolating " << celli
|
||||
// << " from remote values (if any):" << endl;
|
||||
scalar s(0.0);
|
||||
forAll(nbrs, nbrI)
|
||||
{
|
||||
label slotI = nbrs[nbrI];
|
||||
if (slotI >= psiInternal.size())
|
||||
{
|
||||
//Pout<< " remote value " << work[slotI]
|
||||
// << " from slot " << slotI << " with w:" << w[nbrI]
|
||||
// << endl;
|
||||
s += w[nbrI]*work[slotI];
|
||||
}
|
||||
}
|
||||
//Pout<< "oversetGAMGInterfaceField : Interpolated value:"
|
||||
// << s << endl;
|
||||
//scalar oldPsi = result[celli];
|
||||
if (add)
|
||||
{
|
||||
s = -1.0*s;
|
||||
}
|
||||
|
||||
result[celli] += normalisation[celli]*f*s;
|
||||
//Pout<< "oversetGAMGInterfaceField : result was:" << oldPsi
|
||||
// << " now:" << result[celli] << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
// // Add remote values
|
||||
// if (oversetInterface_.master())
|
||||
// {
|
||||
// const labelListList& stencil = oversetInterface_.stencil();
|
||||
//
|
||||
// if (stencil.size() != psiInternal.size())
|
||||
// {
|
||||
// FatalErrorInFunction << "psiInternal:" << psiInternal.size()
|
||||
// << " stencil:" << stencil.size() << exit(FatalError);
|
||||
// }
|
||||
//
|
||||
// const mapDistribute& map = oversetInterface_.cellInterpolationMap();
|
||||
// const List<scalarList>& wghts =
|
||||
// oversetInterface_.cellInterpolationWeights();
|
||||
// const labelList& cellIDs = oversetInterface_.interpolationCells();
|
||||
// const scalarList& factor = oversetInterface_.cellInterpolationWeight();
|
||||
// const scalarField& normalisation = oversetInterface_.normalisation();
|
||||
//
|
||||
// scalarField work(psiInternal);
|
||||
// map.mapDistributeBase::distribute(work, UPstream::msgType()+1);
|
||||
//
|
||||
// forAll(cellIDs, i)
|
||||
// {
|
||||
// label celli = cellIDs[i];
|
||||
//
|
||||
// const scalarList& w = wghts[celli];
|
||||
// const labelList& nbrs = stencil[celli];
|
||||
// const scalar f = factor[celli];
|
||||
//
|
||||
// bool hasRemote = false;
|
||||
// forAll(nbrs, nbrI)
|
||||
// {
|
||||
// label slotI = nbrs[nbrI];
|
||||
// if (slotI >= psiInternal.size())
|
||||
// {
|
||||
// hasRemote = true;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (hasRemote)
|
||||
// {
|
||||
// //Pout<< "oversetGAMGInterfaceField : Interpolating " << celli
|
||||
// // << " from remote values (if any):" << endl;
|
||||
// scalar s(0.0);
|
||||
// forAll(nbrs, nbrI)
|
||||
// {
|
||||
// label slotI = nbrs[nbrI];
|
||||
// if (slotI >= psiInternal.size())
|
||||
// {
|
||||
// //Pout<< " remote value " << work[slotI]
|
||||
// // << " from slot " << slotI << " with w:" << w[nbrI]
|
||||
// // << endl;
|
||||
// s += w[nbrI]*work[slotI];
|
||||
// }
|
||||
// }
|
||||
// //Pout<< "oversetGAMGInterfaceField : Interpolated value:"
|
||||
// // << s << endl;
|
||||
// //scalar oldPsi = result[celli];
|
||||
// if (add)
|
||||
// {
|
||||
// s = -1.0*s;
|
||||
// }
|
||||
//
|
||||
// result[celli] += normalisation[celli]*f*s;
|
||||
// //Pout<< "oversetGAMGInterfaceField : result was:" << oldPsi
|
||||
// // << " now:" << result[celli] << endl;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
|
@ -24,6 +24,7 @@ License
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "volFields.H"
|
||||
#include "cellCellStencilObject.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
@ -34,7 +35,7 @@ Foam::semiImplicitOversetFvPatchField<Type>::semiImplicitOversetFvPatchField
|
||||
const DimensionedField<Type, volMesh>& iF
|
||||
)
|
||||
:
|
||||
LduInterfaceField<Type>(refCast<const oversetFvPatch>(p)),
|
||||
//LduInterfaceField<Type>(refCast<const oversetFvPatch>(p)),
|
||||
zeroGradientFvPatchField<Type>(p, iF),
|
||||
oversetPatch_(refCast<const oversetFvPatch>(p))
|
||||
{}
|
||||
@ -49,7 +50,7 @@ Foam::semiImplicitOversetFvPatchField<Type>::semiImplicitOversetFvPatchField
|
||||
const fvPatchFieldMapper& mapper
|
||||
)
|
||||
:
|
||||
LduInterfaceField<Type>(refCast<const oversetFvPatch>(p)),
|
||||
//LduInterfaceField<Type>(refCast<const oversetFvPatch>(p)),
|
||||
zeroGradientFvPatchField<Type>(ptf, p, iF, mapper),
|
||||
oversetPatch_(refCast<const oversetFvPatch>(p))
|
||||
{
|
||||
@ -74,7 +75,7 @@ Foam::semiImplicitOversetFvPatchField<Type>::semiImplicitOversetFvPatchField
|
||||
const dictionary& dict
|
||||
)
|
||||
:
|
||||
LduInterfaceField<Type>(refCast<const oversetFvPatch>(p)),
|
||||
//LduInterfaceField<Type>(refCast<const oversetFvPatch>(p)),
|
||||
zeroGradientFvPatchField<Type>(p, iF, dict),
|
||||
oversetPatch_(refCast<const oversetFvPatch>(p))
|
||||
{
|
||||
@ -102,7 +103,7 @@ Foam::semiImplicitOversetFvPatchField<Type>::semiImplicitOversetFvPatchField
|
||||
const semiImplicitOversetFvPatchField<Type>& ptf
|
||||
)
|
||||
:
|
||||
LduInterfaceField<Type>(ptf.oversetPatch_),
|
||||
//LduInterfaceField<Type>(ptf.oversetPatch_),
|
||||
zeroGradientFvPatchField<Type>(ptf),
|
||||
oversetPatch_(ptf.oversetPatch_)
|
||||
{}
|
||||
@ -115,7 +116,7 @@ Foam::semiImplicitOversetFvPatchField<Type>::semiImplicitOversetFvPatchField
|
||||
const DimensionedField<Type, volMesh>& iF
|
||||
)
|
||||
:
|
||||
LduInterfaceField<Type>(ptf.oversetPatch_),
|
||||
//LduInterfaceField<Type>(ptf.oversetPatch_),
|
||||
zeroGradientFvPatchField<Type>(ptf, iF),
|
||||
oversetPatch_(ptf.oversetPatch_)
|
||||
{}
|
||||
@ -198,66 +199,67 @@ void Foam::semiImplicitOversetFvPatchField<Type>::initEvaluate
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
void Foam::semiImplicitOversetFvPatchField<Type>::updateInterfaceMatrix
|
||||
(
|
||||
scalarField& result,
|
||||
const bool add,
|
||||
const scalarField& psiInternal,
|
||||
const scalarField& coeffs,
|
||||
const direction cmpt,
|
||||
const Pstream::commsTypes
|
||||
) const
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Pout<< FUNCTION_NAME << " field " << this->internalField().name()
|
||||
<< " patch " << this->patch().name() << endl;
|
||||
}
|
||||
|
||||
const oversetFvPatch& ovp = this->oversetPatch();
|
||||
|
||||
// Set all interpolated cells
|
||||
if (ovp.master())
|
||||
{
|
||||
const labelListList& stencil = ovp.stencil();
|
||||
|
||||
if (stencil.size() != psiInternal.size())
|
||||
{
|
||||
FatalErrorInFunction << "psiInternal:" << psiInternal.size()
|
||||
<< " stencil:" << stencil.size() << exit(FatalError);
|
||||
}
|
||||
|
||||
const mapDistribute& map = ovp.cellInterpolationMap();
|
||||
const List<scalarList>& wghts = ovp.cellInterpolationWeights();
|
||||
const labelList& cellIDs = ovp.interpolationCells();
|
||||
//const scalarList& factor = ovp.cellInterpolationWeight();
|
||||
|
||||
// Since we're inside initEvaluate/evaluate there might be processor
|
||||
// comms underway. Change the tag we use.
|
||||
scalarField work(psiInternal);
|
||||
map.mapDistributeBase::distribute(work, UPstream::msgType()+1);
|
||||
|
||||
forAll(cellIDs, i)
|
||||
{
|
||||
label celli = cellIDs[i];
|
||||
|
||||
const scalarList& w = wghts[celli];
|
||||
const labelList& nbrs = stencil[celli];
|
||||
|
||||
//scalar f = factor[celli];
|
||||
|
||||
scalar s(0.0);
|
||||
forAll(nbrs, nbrI)
|
||||
{
|
||||
s += w[nbrI]*work[nbrs[nbrI]];
|
||||
}
|
||||
|
||||
//Pout<< "cell:" << celli << " interpolated value:" << s << endl;
|
||||
result[celli] = s; //(1.0-f)*result[celli] + f*s;
|
||||
}
|
||||
}
|
||||
}
|
||||
//template<class Type>
|
||||
//void Foam::semiImplicitOversetFvPatchField<Type>::updateInterfaceMatrix
|
||||
//(
|
||||
// scalarField& result,
|
||||
// const bool add,
|
||||
// const scalarField& psiInternal,
|
||||
// const scalarField& coeffs,
|
||||
// const direction cmpt,
|
||||
// const Pstream::commsTypes
|
||||
//) const
|
||||
//{
|
||||
// if (debug)
|
||||
// {
|
||||
// Pout<< FUNCTION_NAME << " field " << this->internalField().name()
|
||||
// << " patch " << this->patch().name() << endl;
|
||||
// }
|
||||
//
|
||||
// const oversetFvPatch& ovp = this->oversetPatch();
|
||||
//
|
||||
// // Set all interpolated cells
|
||||
// if (ovp.master())
|
||||
// {
|
||||
// const cellCellStencilObject& overlap = Stencil::New(*this);
|
||||
// const labelListList& cellStencil = overlap.cellStencil();
|
||||
//
|
||||
// if (cellStencil.size() != psiInternal.size())
|
||||
// {
|
||||
// FatalErrorInFunction << "psiInternal:" << psiInternal.size()
|
||||
// << " stencil:" << cellStencil.size() << exit(FatalError);
|
||||
// }
|
||||
//
|
||||
// const mapDistribute& map = overlap.cellInterpolationMap();
|
||||
// const List<scalarList>& wghts = overlap.cellInterpolationWeights();
|
||||
// const labelList& cellIDs = overlap.interpolationCells();
|
||||
// //const scalarList& factor = overlap.cellInterpolationWeight();
|
||||
//
|
||||
// // Since we're inside initEvaluate/evaluate there might be processor
|
||||
// // comms underway. Change the tag we use.
|
||||
// scalarField work(psiInternal);
|
||||
// map.mapDistributeBase::distribute(work, UPstream::msgType()+1);
|
||||
//
|
||||
// forAll(cellIDs, i)
|
||||
// {
|
||||
// label celli = cellIDs[i];
|
||||
//
|
||||
// const scalarList& w = wghts[celli];
|
||||
// const labelList& nbrs = cellStencil[celli];
|
||||
//
|
||||
// //scalar f = factor[celli];
|
||||
//
|
||||
// scalar s(0.0);
|
||||
// forAll(nbrs, nbrI)
|
||||
// {
|
||||
// s += w[nbrI]*work[nbrs[nbrI]];
|
||||
// }
|
||||
//
|
||||
// //Pout<< "cell:" << celli << " interpolated value:" << s << endl;
|
||||
// result[celli] = s; //(1.0-f)*result[celli] + f*s;
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
|
||||
template<class Type>
|
||||
|
@ -57,7 +57,7 @@ namespace Foam
|
||||
template<class Type>
|
||||
class semiImplicitOversetFvPatchField
|
||||
:
|
||||
public LduInterfaceField<Type>,
|
||||
//public LduInterfaceField<Type>,
|
||||
public zeroGradientFvPatchField<Type>
|
||||
{
|
||||
protected:
|
||||
@ -158,29 +158,29 @@ public:
|
||||
//- Initialise the evaluation of the patch field
|
||||
virtual void initEvaluate(const Pstream::commsTypes commsType);
|
||||
|
||||
//- Update result field based on interface functionality
|
||||
virtual void updateInterfaceMatrix
|
||||
(
|
||||
scalarField& result,
|
||||
const bool add,
|
||||
const scalarField& psiInternal,
|
||||
const scalarField& coeffs,
|
||||
const direction cmpt,
|
||||
const Pstream::commsTypes commsType
|
||||
) const;
|
||||
|
||||
//- Update result field based on interface functionality
|
||||
virtual void updateInterfaceMatrix
|
||||
(
|
||||
Field<Type>&,
|
||||
const bool add,
|
||||
const Field<Type>&,
|
||||
const scalarField&,
|
||||
const Pstream::commsTypes commsType
|
||||
) const
|
||||
{
|
||||
NotImplemented;
|
||||
}
|
||||
// //- Update result field based on interface functionality
|
||||
// virtual void updateInterfaceMatrix
|
||||
// (
|
||||
// scalarField& result,
|
||||
// const bool add,
|
||||
// const scalarField& psiInternal,
|
||||
// const scalarField& coeffs,
|
||||
// const direction cmpt,
|
||||
// const Pstream::commsTypes commsType
|
||||
// ) const;
|
||||
//
|
||||
// //- Update result field based on interface functionality
|
||||
// virtual void updateInterfaceMatrix
|
||||
// (
|
||||
// Field<Type>&,
|
||||
// const bool add,
|
||||
// const Field<Type>&,
|
||||
// const scalarField&,
|
||||
// const Pstream::commsTypes commsType
|
||||
// ) const
|
||||
// {
|
||||
// NotImplemented;
|
||||
// }
|
||||
|
||||
|
||||
// I-O
|
||||
|
@ -73,6 +73,8 @@ void Foam::semiImplicitOversetGAMGInterfaceField::updateInterfaceMatrix
|
||||
const Pstream::commsTypes commsType
|
||||
) const
|
||||
{
|
||||
DebugVar("Here");
|
||||
|
||||
// Add remote values
|
||||
if (oversetInterface_.master())
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user