Commit bbfda444 authored by mattijs's avatar mattijs

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.
parent 813e6b96
......@@ -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
......@@ -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
{
......
......@@ -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);
......
/*---------------------------------------------------------------------------*\
========= |
\\ / 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_;
}
// ************************************************************************* //
/*---------------------------------------------------------------------------*\
========= |
\\ / 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
// ************************************************************************* //
/*---------------------------------------------------------------------------*\
========= |
\\ / 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
);
}