ENH: GAMGAgglomeration: optional updateInterval for moving mesh cases.

This commit is contained in:
Mattijs Janssens 2024-11-25 13:38:00 +00:00 committed by Andrew Heather
parent 96ccae977e
commit e54791019a
37 changed files with 580 additions and 72 deletions

View File

@ -247,6 +247,9 @@ Foam::GAMGAgglomeration::GAMGAgglomeration
maxLevels_(50),
updateInterval_(controlDict.getOrDefault<label>("updateInterval", 1)),
requireUpdate_(false),
nCellsInCoarsestLevel_
(
controlDict.getOrDefault<label>("nCellsInCoarsestLevel", 10)
@ -313,6 +316,12 @@ const Foam::GAMGAgglomeration& Foam::GAMGAgglomeration::New
if (agglomPtr)
{
if (agglomPtr->requireUpdate_)
{
mesh.thisDb().checkOut(const_cast<GAMGAgglomeration*>(agglomPtr));
return GAMGAgglomeration::New(mesh, controlDict);
}
return *agglomPtr;
}
@ -369,6 +378,12 @@ const Foam::GAMGAgglomeration& Foam::GAMGAgglomeration::New
if (agglomPtr)
{
if (agglomPtr->requireUpdate_)
{
mesh.thisDb().checkOut(const_cast<GAMGAgglomeration*>(agglomPtr));
return GAMGAgglomeration::New(matrix, controlDict);
}
return *agglomPtr;
}
@ -421,6 +436,12 @@ const Foam::GAMGAgglomeration& Foam::GAMGAgglomeration::New
if (agglomPtr)
{
if (agglomPtr->requireUpdate_)
{
mesh.thisDb().checkOut(const_cast<GAMGAgglomeration*>(agglomPtr));
return GAMGAgglomeration::New(mesh, controlDict);
}
return *agglomPtr;
}
@ -476,6 +497,25 @@ Foam::GAMGAgglomeration::~GAMGAgglomeration()
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::GAMGAgglomeration::requiresUpdate() const
{
return
(updateInterval_ > 0)
&& ((mesh_.thisDb().time().timeIndex() % updateInterval_) == 0);
}
bool Foam::GAMGAgglomeration::movePoints()
{
if (requiresUpdate())
{
requireUpdate_ = true;
}
// What to return?
return requireUpdate_;
}
const Foam::lduMesh& Foam::GAMGAgglomeration::meshLevel
(
const label i

View File

@ -30,6 +30,26 @@ Class
Description
Geometric agglomerated algebraic multigrid agglomeration class.
Example of the specification in fvSolution:
\verbatim
{
solver GAMG;
smoother symGaussSeidel;
// Whether to cache the agglomeration
cacheAgglomeration yes;
// Optionally update every updateInterval mesh motion. Default is 1.
updateInterval 10;
// Optionally agglomerate coarsest-level across processors
processorAgglomerator masterCoarsest;
nMasters 2;
tolerance 1e-2;
relTol 0;
}
\endverbatim
SourceFiles
GAMGAgglomeration.C
GAMGAgglomerationTemplates.C
@ -65,14 +85,14 @@ class GAMGProcAgglomeration;
class GAMGAgglomeration
:
public MeshObject<lduMesh, GeometricMeshObject, GAMGAgglomeration>
public MeshObject<lduMesh, MoveableMeshObject, GAMGAgglomeration>
{
// Private Typedefs
typedef MeshObject
<
lduMesh,
GeometricMeshObject,
MoveableMeshObject,
GAMGAgglomeration
> MeshObject_type;
@ -84,6 +104,12 @@ protected:
//- Max number of levels
const label maxLevels_;
//- Update agglomeration every updateInterval_ steps
const label updateInterval_;
//- Does agglomeration require update
mutable bool requireUpdate_;
//- Number of cells in coarsest level
label nCellsInCoarsestLevel_;
@ -161,6 +187,9 @@ protected:
// Protected Member Functions
//- Does the agglomeration need to be fully updated?
bool requiresUpdate() const;
//- Assemble coarse mesh addressing
void agglomerateLduAddressing(const label fineLevelIndex);
@ -335,6 +364,10 @@ public:
// Member Functions
//- Update when the mesh moves
virtual bool movePoints();
// Access
label size() const

View File

@ -29,6 +29,8 @@ License
#include "algebraicPairGAMGAgglomeration.H"
#include "lduMatrix.H"
#include "addToRunTimeSelectionTable.H"
//#include "cyclicAMILduInterface.H"
//#include "cyclicACMILduInterface.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -72,4 +74,208 @@ Foam::algebraicPairGAMGAgglomeration::algebraicPairGAMGAgglomeration
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::algebraicPairGAMGAgglomeration::movePoints()
{
const bool ok = pairGAMGAgglomeration::movePoints();
if (!requireUpdate_)
{
// TBD. For now commented out since cyclicAMI not known in this library.
/*
// movePoints lower down did not trigger update. Update in case of
// cyclicAMI since contains addressing across patches and patches
// have moved.
bool hasCyclicAMI = false;
if (!processorAgglomerate())
{
const auto& fineInterfaces = interfaceLevel(0);
forAll(fineInterfaces, inti)
{
if (fineInterfaces.set(inti))
{
const auto& intf = fineInterfaces[inti];
if
(
isA<cyclicAMILduInterface>(intf)
|| isA<cyclicACMILduInterface>(intf)
)
{
hasCyclicAMI = true;
DebugPoutInFunction
<< "Detected cyclicA(C)MI at interface " << inti
<< ".Redoing patch agglomeration" << endl;
break;
}
}
}
}
if (hasCyclicAMI)
{
// Redo the interface agglomeration
for
(
label fineLevelIndex = 0;
fineLevelIndex < size();
fineLevelIndex++
)
{
// Near complete copy of boundary handling in
// GAMGAgglomeration::agglomerateLduAddressing
const auto& fineMesh = meshLevel(fineLevelIndex);
const auto& fineInterfaces = interfaceLevel(fineLevelIndex);
const lduAddressing& fineMeshAddr = fineMesh.lduAddr();
// Get restriction map for current level
const labelField& restrictMap =
restrictAddressing(fineLevelIndex);
const label startOfRequests = UPstream::nRequests();
forAll(fineInterfaces, inti)
{
if (fineInterfaces.set(inti))
{
const auto& intf = fineInterfaces[inti];
if
(
isA<cyclicAMILduInterface>(intf)
|| isA<cyclicACMILduInterface>(intf)
)
{
if (fineLevelIndex == 0)
{
intf.initInternalFieldTransfer
(
Pstream::commsTypes::nonBlocking,
restrictMap,
fineMeshAddr.patchAddr(inti)
);
}
else
{
intf.initInternalFieldTransfer
(
Pstream::commsTypes::nonBlocking,
restrictMap
);
}
}
}
}
// Wait for comms to finised
UPstream::waitRequests(startOfRequests);
// New coarse-level interfaces
//lduInterfacePtrsList coarseInterfaces(fineInterfaces.size());
forAll(fineInterfaces, inti)
{
if (fineInterfaces.set(inti))
{
const auto& intf = fineInterfaces[inti];
if
(
isA<cyclicAMILduInterface>(intf)
|| isA<cyclicACMILduInterface>(intf)
)
{
tmp<labelField> restrictMapInternalField;
// The finest mesh uses patchAddr from the
// original lduAdressing.
// the coarser levels create thei own adressing for
// faceCells
if (fineLevelIndex == 0)
{
restrictMapInternalField =
intf.interfaceInternalField
(
restrictMap,
fineMeshAddr.patchAddr(inti)
);
}
else
{
restrictMapInternalField =
intf.interfaceInternalField
(
restrictMap
);
}
tmp<labelField> nbrRestrictMapInternalField =
intf.internalFieldTransfer
(
Pstream::commsTypes::nonBlocking,
restrictMap
);
lduPrimitiveMesh& coarseMesh =
meshLevels_[fineLevelIndex];
autoPtr<GAMGInterface> coarseIntf
(
GAMGInterface::New
(
inti,
coarseMesh.rawInterfaces(),
intf,
restrictMapInternalField(),
nbrRestrictMapInternalField(),
fineLevelIndex,
fineMesh.comm()
)
);
//coarseInterfaces.set(inti, coarseIntf.ptr());
coarseMesh.interfaces().set
(
inti,
coarseIntf.ptr()
);
coarseMesh.primitiveInterfaces().set
(
inti,
&coarseMesh.interfaces()[inti]
);
}
}
}
//meshLevels_[fineLevelIndex].addInterfaces
//(
// coarseInterfaces,
// lduPrimitiveMesh::nonBlockingSchedule
// <
// processorGAMGInterface
// >
// (
// coarseInterfaces
// )
//);
}
}
if (debug)
{
printLevels();
}
*/
}
return ok;
}
// ************************************************************************* //

View File

@ -67,6 +67,12 @@ public:
const lduMatrix& matrix,
const dictionary& controlDict
);
// Member Functions
//- Update when the mesh moves
virtual bool movePoints();
};

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2023 OpenCFD Ltd.
Copyright (C) 2023-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -30,6 +30,9 @@ License
#include "fvMesh.H"
#include "surfaceFields.H"
#include "addToRunTimeSelectionTable.H"
#include "cyclicAMIGAMGInterface.H"
#include "cyclicACMIGAMGInterface.H"
//#include "processorGAMGInterface.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -65,6 +68,13 @@ Foam::faceAreaPairGAMGAgglomeration::faceAreaPairGAMGAgglomeration
{
const fvMesh& fvmesh = refCast<const fvMesh>(mesh);
if (pairGAMGAgglomeration::requiresUpdate())
{
// This is the <=2406 logic. Apply perturbation to avoid jagged
// agglomerations on axis-aligned meshes
DebugPoutInFunction<< "Agglomerate with perturbation" << endl;
//agglomerate(mesh, sqrt(fvmesh.magSf().primitiveField()));
agglomerate
(
@ -83,6 +93,23 @@ Foam::faceAreaPairGAMGAgglomeration::faceAreaPairGAMGAgglomeration
true
);
}
else
{
// In partial updating mode. Use Galilean invariant agglomeration
// to e.g. have constant agglomeration for solid body rotation. Also
// scale with face area to be consistent with (most) discretisation.
DebugPoutInFunction<< "Agglomerate with faceArea magnitude" << endl;
agglomerate
(
nCellsInCoarsestLevel_,
0, //mesh,
mag(fvmesh.magSf().primitiveField()),
true
);
}
}
Foam::faceAreaPairGAMGAgglomeration::faceAreaPairGAMGAgglomeration
@ -95,6 +122,13 @@ Foam::faceAreaPairGAMGAgglomeration::faceAreaPairGAMGAgglomeration
:
pairGAMGAgglomeration(mesh, controlDict)
{
if (pairGAMGAgglomeration::requiresUpdate())
{
// This is the <=2406 logic. Apply perturbation to avoid jagged
// agglomerations on axis-aligned meshes
DebugPoutInFunction<< "Agglomerate with perturbation" << endl;
//agglomerate(mesh, sqrt(mag(faceAreas)));
agglomerate
(
@ -113,6 +147,223 @@ Foam::faceAreaPairGAMGAgglomeration::faceAreaPairGAMGAgglomeration
true
);
}
else
{
// In partial updating mode. Use Galilean invariant agglomeration
// to e.g. have constant agglomeration for solid body rotation. Also
// scale with face area to be consistent with (most) discretisation.
DebugPoutInFunction<< "Agglomerate with faceArea magnitude" << endl;
agglomerate
(
nCellsInCoarsestLevel_,
0, //mesh,
mag(faceAreas),
true
);
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::faceAreaPairGAMGAgglomeration::movePoints()
{
const bool ok = pairGAMGAgglomeration::movePoints();
if (!requireUpdate_)
{
// movePoints lower down did not trigger update. Update in case of
// cyclicAMI since contains addressing across patches and patches
// have moved.
bool hasCyclicAMI = false;
if (!processorAgglomerate())
{
const auto& fineInterfaces = interfaceLevel(0);
forAll(fineInterfaces, inti)
{
if (fineInterfaces.set(inti))
{
const auto& intf = fineInterfaces[inti];
if
(
isA<cyclicAMILduInterface>(intf)
|| isA<cyclicACMILduInterface>(intf)
)
{
hasCyclicAMI = true;
DebugPoutInFunction
<< "Detected cyclicA(C)MI at interface " << inti
<< ".Redoing patch agglomeration" << endl;
break;
}
}
}
}
if (hasCyclicAMI)
{
// Redo the interface agglomeration
for
(
label fineLevelIndex = 0;
fineLevelIndex < size();
fineLevelIndex++
)
{
// Near complete copy of boundary handling in
// GAMGAgglomeration::agglomerateLduAddressing
const auto& fineMesh = meshLevel(fineLevelIndex);
const auto& fineInterfaces = interfaceLevel(fineLevelIndex);
const lduAddressing& fineMeshAddr = fineMesh.lduAddr();
// Get restriction map for current level
const labelField& restrictMap =
restrictAddressing(fineLevelIndex);
const label startOfRequests = UPstream::nRequests();
forAll(fineInterfaces, inti)
{
if (fineInterfaces.set(inti))
{
const auto& intf = fineInterfaces[inti];
if
(
isA<cyclicAMILduInterface>(intf)
|| isA<cyclicACMILduInterface>(intf)
)
{
if (fineLevelIndex == 0)
{
intf.initInternalFieldTransfer
(
Pstream::commsTypes::nonBlocking,
restrictMap,
fineMeshAddr.patchAddr(inti)
);
}
else
{
intf.initInternalFieldTransfer
(
Pstream::commsTypes::nonBlocking,
restrictMap
);
}
}
}
}
// Wait for comms to finised
UPstream::waitRequests(startOfRequests);
// New coarse-level interfaces
//lduInterfacePtrsList coarseInterfaces(fineInterfaces.size());
forAll(fineInterfaces, inti)
{
if (fineInterfaces.set(inti))
{
const auto& intf = fineInterfaces[inti];
if
(
isA<cyclicAMILduInterface>(intf)
|| isA<cyclicACMILduInterface>(intf)
)
{
tmp<labelField> restrictMapInternalField;
// The finest mesh uses patchAddr from the
// original lduAdressing.
// the coarser levels create thei own adressing for
// faceCells
if (fineLevelIndex == 0)
{
restrictMapInternalField =
intf.interfaceInternalField
(
restrictMap,
fineMeshAddr.patchAddr(inti)
);
}
else
{
restrictMapInternalField =
intf.interfaceInternalField
(
restrictMap
);
}
tmp<labelField> nbrRestrictMapInternalField =
intf.internalFieldTransfer
(
Pstream::commsTypes::nonBlocking,
restrictMap
);
lduPrimitiveMesh& coarseMesh =
meshLevels_[fineLevelIndex];
autoPtr<GAMGInterface> coarseIntf
(
GAMGInterface::New
(
inti,
coarseMesh.rawInterfaces(),
intf,
restrictMapInternalField(),
nbrRestrictMapInternalField(),
fineLevelIndex,
fineMesh.comm()
)
);
//coarseInterfaces.set(inti, coarseIntf.ptr());
coarseMesh.interfaces().set
(
inti,
coarseIntf.ptr()
);
coarseMesh.primitiveInterfaces().set
(
inti,
&coarseMesh.interfaces()[inti]
);
}
}
}
//meshLevels_[fineLevelIndex].addInterfaces
//(
// coarseInterfaces,
// lduPrimitiveMesh::nonBlockingSchedule
// <
// processorGAMGInterface
// >
// (
// coarseInterfaces
// )
//);
}
}
if (debug)
{
printLevels();
}
}
return ok;
}
// ************************************************************************* //

View File

@ -76,6 +76,12 @@ public:
const vectorField& faceAreas,
const dictionary& controlDict
);
// Member Functions
//- Update when the mesh moves
virtual bool movePoints();
};

View File

@ -22,8 +22,8 @@ solvers
tolerance 1e-2;
relTol 0;
smoother GaussSeidel;
//cacheAgglomeration no; // keep agglom during pimple
maxIter 50;
cacheAgglomeration yes; // Store agglomeration
updateInterval -1; // Never redo agglomeration
}
p

View File

@ -22,7 +22,6 @@ solvers
tolerance 1e-2;
relTol 0;
smoother GaussSeidel;
cacheAgglomeration no;
nCellsInCoarsestLevel 10;
agglomerator faceAreaPair;
mergeLevels 1;

View File

@ -22,7 +22,6 @@ solvers
tolerance 1e-2;
relTol 0;
smoother DICGaussSeidel;
cacheAgglomeration no;
maxIter 50;
}

View File

@ -22,7 +22,6 @@ solvers
tolerance 1e-8;
relTol 0;
smoother GaussSeidel;
cacheAgglomeration no;
}
pFinal

View File

@ -22,7 +22,6 @@ solvers
tolerance 1e-8;
relTol 0;
smoother GaussSeidel;
cacheAgglomeration no;
}
pFinal

View File

@ -21,7 +21,6 @@ solvers
{
solver GAMG;
smoother GaussSeidel;
cacheAgglomeration no;
tolerance 0.02;
relTol 0;

View File

@ -20,7 +20,6 @@ solvers
{
solver GAMG;
smoother GaussSeidel;
cacheAgglomeration no;
tolerance 0.02;
relTol 0;
}

View File

@ -20,7 +20,6 @@ solvers
{
solver GAMG;
smoother GaussSeidel;
cacheAgglomeration no;
tolerance 0.02;
relTol 0;
}

View File

@ -22,7 +22,6 @@ solvers
tolerance 0;
relTol 0.01;
smoother GaussSeidel;
cacheAgglomeration no;
}
pFinal

View File

@ -22,7 +22,6 @@ solvers
tolerance 1e-8;
relTol 0;
smoother GaussSeidel;
cacheAgglomeration no;
}
pFinal

View File

@ -22,7 +22,6 @@ solvers
tolerance 1e-2;
relTol 0;
smoother DICGaussSeidel;
cacheAgglomeration no;
nCellsInCoarsestLevel 10;
agglomerator faceAreaPair;
mergeLevels 1;

View File

@ -37,7 +37,6 @@ solvers
tolerance 1e-05;
relTol 0;
smoother DICGaussSeidel;
cacheAgglomeration no;
}
tolerance 1e-05;

View File

@ -41,7 +41,6 @@ solvers
tolerance 1e-5;
relTol 0;
smoother DICGaussSeidel;
cacheAgglomeration no;
}
tolerance 1e-05;
relTol 0;

View File

@ -40,7 +40,6 @@ solvers
nPreSweeps 0;
nPostSweeps 2;
nFinestSweeps 2;
cacheAgglomeration false;
nCellsInCoarsestLevel 10;
agglomerator faceAreaPair;
mergeLevels 1;

View File

@ -29,7 +29,6 @@ solvers
tolerance 1e-08;
relTol 0.01;
smoother DIC;
cacheAgglomeration no;
}
p_rghFinal

View File

@ -32,7 +32,6 @@ solvers
tolerance 1e-05;
relTol 0;
smoother DICGaussSeidel;
cacheAgglomeration no;
}
tolerance 1e-05;

View File

@ -32,7 +32,6 @@ solvers
tolerance 1e-05;
relTol 0;
smoother DICGaussSeidel;
cacheAgglomeration no;
}
tolerance 1e-05;

View File

@ -32,7 +32,6 @@ solvers
tolerance 1e-05;
relTol 0;
smoother DICGaussSeidel;
cacheAgglomeration no;
}
tolerance 1e-05;

View File

@ -32,7 +32,6 @@ solvers
tolerance 1e-05;
relTol 0;
smoother DICGaussSeidel;
cacheAgglomeration no;
}
tolerance 1e-05;

View File

@ -32,7 +32,6 @@ solvers
tolerance 1e-05;
relTol 0;
smoother DICGaussSeidel;
cacheAgglomeration no;
}
tolerance 1e-05;

View File

@ -32,7 +32,6 @@ solvers
tolerance 1e-05;
relTol 0;
smoother DICGaussSeidel;
cacheAgglomeration no;
}
tolerance 1e-05;

View File

@ -22,7 +22,6 @@ solvers
tolerance 1e-5;
relTol 0;
smoother GaussSeidel;
cacheAgglomeration false;
nCellsInCoarsestLevel 10;
agglomerator faceAreaPair;
mergeLevels 1;

View File

@ -22,7 +22,6 @@ solvers
tolerance 1e-5;
relTol 0;
smoother GaussSeidel;
cacheAgglomeration false;
nCellsInCoarsestLevel 10;
agglomerator faceAreaPair;
mergeLevels 1;

View File

@ -22,7 +22,6 @@ solvers
tolerance 1e-5;
relTol 0;
smoother GaussSeidel;
cacheAgglomeration false;
nCellsInCoarsestLevel 10;
agglomerator faceAreaPair;
mergeLevels 1;

View File

@ -22,7 +22,6 @@ solvers
tolerance 1e-5;
relTol 0;
smoother GaussSeidel;
cacheAgglomeration false;
nCellsInCoarsestLevel 10;
agglomerator faceAreaPair;
mergeLevels 1;

View File

@ -22,7 +22,6 @@ solvers
tolerance 1e-5;
relTol 0;
smoother GaussSeidel;
cacheAgglomeration false;
nCellsInCoarsestLevel 10;
agglomerator faceAreaPair;
mergeLevels 1;

View File

@ -39,7 +39,6 @@ solvers
tolerance 1e-08;
relTol 0.01;
smoother DIC;
cacheAgglomeration no;
}
p_rghFinal

View File

@ -38,7 +38,6 @@ solvers
tolerance 1e-05;
relTol 0;
smoother DICGaussSeidel;
cacheAgglomeration no;
}
tolerance 1e-05;

View File

@ -39,7 +39,6 @@ solvers
tolerance 1e-2;
relTol 0;
smoother DICGaussSeidel;
cacheAgglomeration no;
maxIter 50;
}

View File

@ -44,7 +44,6 @@ solvers
nPreSweeps 0;
nPostSweeps 2;
nFinestSweeps 2;
cacheAgglomeration false;
nCellsInCoarsestLevel 10;
agglomerator faceAreaPair;
mergeLevels 1;
@ -63,7 +62,6 @@ solvers
nPreSweeps 0;
nPostSweeps 2;
nFinestSweeps 2;
cacheAgglomeration true;
nCellsInCoarsestLevel 10;
agglomerator faceAreaPair;
mergeLevels 1;
@ -82,7 +80,6 @@ solvers
nPreSweeps 2;
nPostSweeps 2;
nFinestSweeps 2;
cacheAgglomeration true;
nCellsInCoarsestLevel 10;
agglomerator faceAreaPair;
mergeLevels 1;

View File

@ -44,7 +44,6 @@ solvers
nPreSweeps 0;
nPostSweeps 2;
nFinestSweeps 2;
cacheAgglomeration false;
nCellsInCoarsestLevel 10;
agglomerator faceAreaPair;
mergeLevels 1;
@ -63,7 +62,6 @@ solvers
nPreSweeps 0;
nPostSweeps 2;
nFinestSweeps 2;
cacheAgglomeration true;
nCellsInCoarsestLevel 10;
agglomerator faceAreaPair;
mergeLevels 1;
@ -82,7 +80,6 @@ solvers
nPreSweeps 2;
nPostSweeps 2;
nFinestSweeps 2;
cacheAgglomeration true;
nCellsInCoarsestLevel 10;
agglomerator faceAreaPair;
mergeLevels 1;