fvMeshDistributors: New library for mesh redistribution and load-balancing
Basic support is now provided for dynamic mesh redistribution, particularly for
load-balancing. The mesh distributor is selected in the optional 'distributor'
entry in dynamicMeshDict, for example in the
multiphase/interFoam/RAS/floatingObject tutorial case when run in parallel using
the new Allrun-parallel script
distributor
{
type decomposer;
libs ("libfvMeshDistributors.so");
redistributionInterval 10;
}
in which the 'decomposer' form of redistribution is selected to call the mesh
decomposition method specified in decomposeParDict to re-decompose the mesh for
redistribution. The redistributionInterval entry specifies how frequently mesh
redistribution takes place, in the above every 10th time-step. An optional
maxImbalance entry is also provided to control redistribution based on the cell
distribution imbalance:
Class
Foam::fvMeshDistributor::decomposer
Description
Dynamic mesh redistribution using the decomposer
Usage
Example of single field based refinement in all cells:
\verbatim
distributor
{
type decomposer;
libs ("libfvMeshDistributors.so");
// How often to redistribute
redistributionInterval 10;
// Maximum fractional cell distribution imbalance
// before rebalancing
maxImbalance 0.1;
}
\endverbatim
Currently mesh refinement/unrefinement and motion with redistribution is
supported but many aspects of OpenFOAM are not yet and will require further
development, in particular fvModels and Lagrangian.
Also only the geometry-based simple and hierarchical decomposition method are
well behaved for redistribution, scotch and ptScotch cause dramatic changes in
mesh distribution with a corresponding heavy communications overhead limiting
their usefulness or at least the frequency with which they should be called to
redistribute the mesh.
This commit is contained in:
@ -48,6 +48,7 @@ parallel/Allwmake $targetType $*
|
|||||||
|
|
||||||
wmake $targetType fvMeshMovers
|
wmake $targetType fvMeshMovers
|
||||||
wmake $targetType fvMeshTopoChangers
|
wmake $targetType fvMeshTopoChangers
|
||||||
|
wmake $targetType fvMeshDistributors
|
||||||
wmake $targetType conversion
|
wmake $targetType conversion
|
||||||
wmake $targetType sampling
|
wmake $targetType sampling
|
||||||
|
|
||||||
|
|||||||
@ -206,9 +206,6 @@ Foam::polyMesh::readUpdateState Foam::polyMesh::readUpdate()
|
|||||||
|
|
||||||
if (boundaryChanged)
|
if (boundaryChanged)
|
||||||
{
|
{
|
||||||
WarningInFunction
|
|
||||||
<< "boundary changed, proceed with care." << endl;
|
|
||||||
|
|
||||||
boundary_.clear();
|
boundary_.clear();
|
||||||
boundary_.setSize(newBoundary.size());
|
boundary_.setSize(newBoundary.size());
|
||||||
|
|
||||||
|
|||||||
@ -218,7 +218,6 @@ Foam::labelList Foam::fvMeshDistribute::select
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Check all procs have same names and in exactly same order.
|
|
||||||
void Foam::fvMeshDistribute::checkEqualWordList
|
void Foam::fvMeshDistribute::checkEqualWordList
|
||||||
(
|
(
|
||||||
const string& msg,
|
const string& msg,
|
||||||
@ -264,7 +263,6 @@ Foam::wordList Foam::fvMeshDistribute::mergeWordList(const wordList& procNames)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Print some info on mesh.
|
|
||||||
void Foam::fvMeshDistribute::printMeshInfo(const fvMesh& mesh)
|
void Foam::fvMeshDistribute::printMeshInfo(const fvMesh& mesh)
|
||||||
{
|
{
|
||||||
Pout<< "Primitives:" << nl
|
Pout<< "Primitives:" << nl
|
||||||
@ -351,7 +349,6 @@ void Foam::fvMeshDistribute::printCoupleInfo
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Finds (non-empty) patch that exposed internal and proc faces can be put into.
|
|
||||||
Foam::label Foam::fvMeshDistribute::findInternalPatch() const
|
Foam::label Foam::fvMeshDistribute::findInternalPatch() const
|
||||||
{
|
{
|
||||||
const polyBoundaryMesh& patches = mesh_.boundaryMesh();
|
const polyBoundaryMesh& patches = mesh_.boundaryMesh();
|
||||||
@ -369,42 +366,23 @@ Foam::label Foam::fvMeshDistribute::findInternalPatch() const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (internalPatchi != -1)
|
if (internalPatchi == -1)
|
||||||
{
|
|
||||||
return internalPatchi;
|
|
||||||
}
|
|
||||||
|
|
||||||
label nonEmptyPatchi = -1;
|
|
||||||
|
|
||||||
forAllReverse(patches, patchi)
|
|
||||||
{
|
|
||||||
const polyPatch& pp = patches[patchi];
|
|
||||||
|
|
||||||
if (!isA<emptyPolyPatch>(pp) && !pp.coupled())
|
|
||||||
{
|
|
||||||
nonEmptyPatchi = patchi;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nonEmptyPatchi == -1)
|
|
||||||
{
|
{
|
||||||
FatalErrorInFunction
|
FatalErrorInFunction
|
||||||
<< "Cannot find a patch which is neither of type empty nor"
|
<< "Cannot find a internal patch in " << patches.names() << nl
|
||||||
<< " coupled in patches " << patches.names() << endl
|
<< " of types " << patches.types() << nl
|
||||||
<< "There has to be at least one such patch for"
|
<< " An internal patch must be provided for the exposed "
|
||||||
<< " distribution to work" << abort(FatalError);
|
" internal faces." << exit(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
{
|
{
|
||||||
Pout<< "findInternalPatch : using patch " << nonEmptyPatchi
|
Pout<< "findInternalPatch : using patch " << internalPatchi
|
||||||
<< " name:" << patches[nonEmptyPatchi].name()
|
<< " name:" << patches[internalPatchi].name()
|
||||||
<< " type:" << patches[nonEmptyPatchi].type()
|
<< " type:" << patches[internalPatchi].type()
|
||||||
<< " to put exposed faces into." << endl;
|
<< " for the exposed internal faces." << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Do additional test for processor patches intermingled with non-proc
|
// Do additional test for processor patches intermingled with non-proc
|
||||||
// patches.
|
// patches.
|
||||||
label procPatchi = -1;
|
label procPatchi = -1;
|
||||||
@ -427,12 +405,10 @@ Foam::label Foam::fvMeshDistribute::findInternalPatch() const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nonEmptyPatchi;
|
return internalPatchi;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Delete all processor patches. Move any processor faces into the last
|
|
||||||
// non-processor patch.
|
|
||||||
Foam::autoPtr<Foam::mapPolyMesh> Foam::fvMeshDistribute::deleteProcPatches
|
Foam::autoPtr<Foam::mapPolyMesh> Foam::fvMeshDistribute::deleteProcPatches
|
||||||
(
|
(
|
||||||
const label destinationPatch
|
const label destinationPatch
|
||||||
@ -504,7 +480,6 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::fvMeshDistribute::deleteProcPatches
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Repatch the mesh.
|
|
||||||
Foam::autoPtr<Foam::mapPolyMesh> Foam::fvMeshDistribute::repatch
|
Foam::autoPtr<Foam::mapPolyMesh> Foam::fvMeshDistribute::repatch
|
||||||
(
|
(
|
||||||
const labelList& newPatchID, // per boundary face -1 or new patchID
|
const labelList& newPatchID, // per boundary face -1 or new patchID
|
||||||
@ -621,11 +596,6 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::fvMeshDistribute::repatch
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Detect shared points. Need processor patches to be present.
|
|
||||||
// Background: when adding bits of mesh one can get points which
|
|
||||||
// share the same position but are only detectable to be topologically
|
|
||||||
// the same point when doing parallel analysis. This routine will
|
|
||||||
// merge those points.
|
|
||||||
Foam::autoPtr<Foam::mapPolyMesh> Foam::fvMeshDistribute::mergeSharedPoints
|
Foam::autoPtr<Foam::mapPolyMesh> Foam::fvMeshDistribute::mergeSharedPoints
|
||||||
(
|
(
|
||||||
const labelList& pointToGlobalMaster,
|
const labelList& pointToGlobalMaster,
|
||||||
@ -1006,7 +976,6 @@ void Foam::fvMeshDistribute::getCouplingData
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Subset the neighbourCell/neighbourProc fields
|
|
||||||
void Foam::fvMeshDistribute::subsetCouplingData
|
void Foam::fvMeshDistribute::subsetCouplingData
|
||||||
(
|
(
|
||||||
const fvMesh& mesh,
|
const fvMesh& mesh,
|
||||||
@ -1085,8 +1054,6 @@ void Foam::fvMeshDistribute::subsetCouplingData
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Find cells on mesh whose faceID/procID match the neighbour cell/proc of
|
|
||||||
// domainMesh. Store the matching face.
|
|
||||||
void Foam::fvMeshDistribute::findCouples
|
void Foam::fvMeshDistribute::findCouples
|
||||||
(
|
(
|
||||||
const primitiveMesh& mesh,
|
const primitiveMesh& mesh,
|
||||||
@ -1161,7 +1128,6 @@ void Foam::fvMeshDistribute::findCouples
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Map data on boundary faces to new mesh (resulting from adding two meshes)
|
|
||||||
Foam::labelList Foam::fvMeshDistribute::mapBoundaryData
|
Foam::labelList Foam::fvMeshDistribute::mapBoundaryData
|
||||||
(
|
(
|
||||||
const primitiveMesh& mesh, // mesh after adding
|
const primitiveMesh& mesh, // mesh after adding
|
||||||
@ -1235,7 +1201,6 @@ Foam::labelList Foam::fvMeshDistribute::mapPointData
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Remove cells. Add all exposed faces to patch oldInternalPatchi
|
|
||||||
Foam::autoPtr<Foam::mapPolyMesh> Foam::fvMeshDistribute::doRemoveCells
|
Foam::autoPtr<Foam::mapPolyMesh> Foam::fvMeshDistribute::doRemoveCells
|
||||||
(
|
(
|
||||||
const labelList& cellsToRemove,
|
const labelList& cellsToRemove,
|
||||||
@ -1320,8 +1285,6 @@ void Foam::fvMeshDistribute::mapFields(const mapPolyMesh& map)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Delete and add processor patches. Changes mesh and returns per neighbour proc
|
|
||||||
// the processor patchID.
|
|
||||||
void Foam::fvMeshDistribute::addProcPatches
|
void Foam::fvMeshDistribute::addProcPatches
|
||||||
(
|
(
|
||||||
const labelList& nbrProc, // Processor that neighbour is now on
|
const labelList& nbrProc, // Processor that neighbour is now on
|
||||||
@ -1424,7 +1387,6 @@ void Foam::fvMeshDistribute::addProcPatches
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Get boundary faces to be repatched. Is -1 or new patchID
|
|
||||||
Foam::labelList Foam::fvMeshDistribute::getBoundaryPatch
|
Foam::labelList Foam::fvMeshDistribute::getBoundaryPatch
|
||||||
(
|
(
|
||||||
const labelList& nbrProc, // new processor per boundary face
|
const labelList& nbrProc, // new processor per boundary face
|
||||||
@ -1455,7 +1417,6 @@ Foam::labelList Foam::fvMeshDistribute::getBoundaryPatch
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Send mesh and coupling data.
|
|
||||||
void Foam::fvMeshDistribute::sendMesh
|
void Foam::fvMeshDistribute::sendMesh
|
||||||
(
|
(
|
||||||
const label domain,
|
const label domain,
|
||||||
@ -1624,7 +1585,6 @@ void Foam::fvMeshDistribute::sendMesh
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Receive mesh. Opposite of sendMesh
|
|
||||||
Foam::autoPtr<Foam::fvMesh> Foam::fvMeshDistribute::receiveMesh
|
Foam::autoPtr<Foam::fvMesh> Foam::fvMeshDistribute::receiveMesh
|
||||||
(
|
(
|
||||||
const label domain,
|
const label domain,
|
||||||
@ -1749,7 +1709,6 @@ Foam::autoPtr<Foam::fvMesh> Foam::fvMeshDistribute::receiveMesh
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
// Construct from components
|
|
||||||
Foam::fvMeshDistribute::fvMeshDistribute(fvMesh& mesh)
|
Foam::fvMeshDistribute::fvMeshDistribute(fvMesh& mesh)
|
||||||
:
|
:
|
||||||
mesh_(mesh)
|
mesh_(mesh)
|
||||||
@ -2002,12 +1961,8 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
|
|||||||
const wordList dimTensors(mesh_.names(volTensorField::Internal::typeName));
|
const wordList dimTensors(mesh_.names(volTensorField::Internal::typeName));
|
||||||
checkEqualWordList("volTensorField::Internal", dimTensors);
|
checkEqualWordList("volTensorField::Internal", dimTensors);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Find patch to temporarily put exposed and processor faces into.
|
// Find patch to temporarily put exposed and processor faces into.
|
||||||
label oldInternalPatchi = findInternalPatch();
|
const label oldInternalPatchi = findInternalPatch();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Delete processor patches, starting from the back. Move all faces into
|
// Delete processor patches, starting from the back. Move all faces into
|
||||||
// oldInternalPatchi.
|
// oldInternalPatchi.
|
||||||
|
|||||||
@ -103,7 +103,7 @@ class fvMeshDistribute
|
|||||||
|
|
||||||
// Patch handling
|
// Patch handling
|
||||||
|
|
||||||
//- Find patch to put exposed internal faces into
|
//- Find internal patch to put exposed internal faces into
|
||||||
label findInternalPatch() const;
|
label findInternalPatch() const;
|
||||||
|
|
||||||
//- Save boundary fields
|
//- Save boundary fields
|
||||||
@ -138,8 +138,11 @@ class fvMeshDistribute
|
|||||||
void correctProcessorPatchFields();
|
void correctProcessorPatchFields();
|
||||||
|
|
||||||
//- Delete all processor patches. Move any processor faces into
|
//- Delete all processor patches. Move any processor faces into
|
||||||
// patchi.
|
// destinationPatch
|
||||||
autoPtr<mapPolyMesh> deleteProcPatches(const label patchi);
|
autoPtr<mapPolyMesh> deleteProcPatches
|
||||||
|
(
|
||||||
|
const label destinationPatch
|
||||||
|
);
|
||||||
|
|
||||||
//- Repatch the mesh. This is only necessary for the proc
|
//- Repatch the mesh. This is only necessary for the proc
|
||||||
// boundary faces. newPatchID is over all boundary faces: -1 or
|
// boundary faces. newPatchID is over all boundary faces: -1 or
|
||||||
@ -154,6 +157,12 @@ class fvMeshDistribute
|
|||||||
|
|
||||||
//- Merge any local points that were remotely coupled.
|
//- Merge any local points that were remotely coupled.
|
||||||
// constructPointMap is adapted for the new point labels.
|
// constructPointMap is adapted for the new point labels.
|
||||||
|
//
|
||||||
|
// Detect shared points. Need processor patches to be present.
|
||||||
|
// Background: when adding bits of mesh one can get points which
|
||||||
|
// share the same position but are only detectable to be
|
||||||
|
// topologically the same point when doing parallel analysis. This
|
||||||
|
// routine will merge those points.
|
||||||
autoPtr<mapPolyMesh> mergeSharedPoints
|
autoPtr<mapPolyMesh> mergeSharedPoints
|
||||||
(
|
(
|
||||||
const labelList& pointToGlobalMaster,
|
const labelList& pointToGlobalMaster,
|
||||||
|
|||||||
@ -313,31 +313,6 @@ void Foam::fvMeshDistribute::correctProcessorPatchFields()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
inline Type max
|
|
||||||
(
|
|
||||||
const pointPatchField<Type>& f
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return pTraits<Type>::min;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
inline Type min
|
|
||||||
(
|
|
||||||
const pointPatchField<Type>& f
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return pTraits<Type>::max;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class GeoField>
|
template<class GeoField>
|
||||||
void Foam::fvMeshDistribute::sendFields
|
void Foam::fvMeshDistribute::sendFields
|
||||||
(
|
(
|
||||||
|
|||||||
3
src/fvMeshDistributors/Make/files
Normal file
3
src/fvMeshDistributors/Make/files
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
decomposer/fvMeshDistributorDecomposer.C
|
||||||
|
|
||||||
|
LIB = $(FOAM_LIBBIN)/libfvMeshDistributors
|
||||||
14
src/fvMeshDistributors/Make/options
Normal file
14
src/fvMeshDistributors/Make/options
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
EXE_INC = \
|
||||||
|
-I$(LIB_SRC)/parallel/decompose/decompositionMethods/lnInclude \
|
||||||
|
-I$(LIB_SRC)/triSurface/lnInclude \
|
||||||
|
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||||
|
-I$(LIB_SRC)/dynamicMesh/lnInclude \
|
||||||
|
-I$(LIB_SRC)/finiteVolume/lnInclude
|
||||||
|
|
||||||
|
LIB_LIBS = \
|
||||||
|
-ldecompositionMethods \
|
||||||
|
-L$(FOAM_LIBBIN)/dummy -lscotchDecomp -lptscotchDecomp \
|
||||||
|
-ltriSurface \
|
||||||
|
-lmeshTools \
|
||||||
|
-ldynamicMesh \
|
||||||
|
-lfiniteVolume
|
||||||
200
src/fvMeshDistributors/decomposer/fvMeshDistributorDecomposer.C
Normal file
200
src/fvMeshDistributors/decomposer/fvMeshDistributorDecomposer.C
Normal file
@ -0,0 +1,200 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration | Website: https://openfoam.org
|
||||||
|
\\ / A nd | Copyright (C) 2021 OpenFOAM Foundation
|
||||||
|
\\/ 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 "fvMeshDistributorDecomposer.H"
|
||||||
|
#include "decompositionMethod.H"
|
||||||
|
#include "fvMeshDistribute.H"
|
||||||
|
#include "mapDistributePolyMesh.H"
|
||||||
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
namespace fvMeshDistributors
|
||||||
|
{
|
||||||
|
defineTypeNameAndDebug(decomposer, 0);
|
||||||
|
addToRunTimeSelectionTable
|
||||||
|
(
|
||||||
|
fvMeshDistributor,
|
||||||
|
decomposer,
|
||||||
|
fvMesh
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::fvMeshDistributors::decomposer::readDict()
|
||||||
|
{
|
||||||
|
const dictionary& decomposerDict(dict());
|
||||||
|
|
||||||
|
redistributionInterval_ =
|
||||||
|
decomposerDict.lookupOrDefault("redistributionInterval", 10);
|
||||||
|
|
||||||
|
maxImbalance_ =
|
||||||
|
decomposerDict.lookupOrDefault<scalar>("maxImbalance", 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::fvMeshDistributors::decomposer::redecompose()
|
||||||
|
{
|
||||||
|
fvMesh& mesh = this->mesh();
|
||||||
|
|
||||||
|
IOdictionary decompositionDict
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
"decomposeParDict",
|
||||||
|
mesh.time().system(),
|
||||||
|
mesh,
|
||||||
|
IOobject::MUST_READ_IF_MODIFIED,
|
||||||
|
IOobject::NO_WRITE
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
labelList finalDecomp;
|
||||||
|
|
||||||
|
// Create decompositionMethod and new decomposition
|
||||||
|
{
|
||||||
|
autoPtr<decompositionMethod> decomposer
|
||||||
|
(
|
||||||
|
decompositionMethod::New
|
||||||
|
(
|
||||||
|
decompositionDict
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!decomposer().parallelAware())
|
||||||
|
{
|
||||||
|
WarningInFunction
|
||||||
|
<< "You have selected decomposition method "
|
||||||
|
<< decomposer().typeName
|
||||||
|
<< " which does" << endl
|
||||||
|
<< "not synchronise the decomposition across"
|
||||||
|
<< " processor patches." << endl
|
||||||
|
<< " You might want to select a decomposition method which"
|
||||||
|
<< " is aware of this. Continuing."
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
finalDecomp = decomposer().decompose(mesh, mesh.cellCentres());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mesh distribution engine
|
||||||
|
fvMeshDistribute distributor(mesh);
|
||||||
|
|
||||||
|
// Do actual sending/receiving of mesh
|
||||||
|
autoPtr<mapDistributePolyMesh> map = distributor.distribute(finalDecomp);
|
||||||
|
|
||||||
|
mesh.distribute(map);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::fvMeshDistributors::decomposer::decomposer(fvMesh& mesh)
|
||||||
|
:
|
||||||
|
fvMeshDistributor(mesh),
|
||||||
|
redistributionInterval_(1),
|
||||||
|
maxImbalance_(0.1),
|
||||||
|
timeIndex_(-1)
|
||||||
|
{
|
||||||
|
readDict();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::fvMeshDistributors::decomposer::~decomposer()
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
bool Foam::fvMeshDistributors::decomposer::update()
|
||||||
|
{
|
||||||
|
if
|
||||||
|
(
|
||||||
|
Pstream::nProcs() > 1
|
||||||
|
&& mesh().time().timeIndex() > 1
|
||||||
|
&& timeIndex_ != mesh().time().timeIndex()
|
||||||
|
&& mesh().time().timeIndex() % redistributionInterval_ == 0
|
||||||
|
)
|
||||||
|
{
|
||||||
|
timeIndex_ = mesh().time().timeIndex();
|
||||||
|
|
||||||
|
const scalar idealNCells =
|
||||||
|
mesh().globalData().nTotalCells()/Pstream::nProcs();
|
||||||
|
|
||||||
|
const scalar imbalance = returnReduce
|
||||||
|
(
|
||||||
|
mag(1 - mesh().nCells()/idealNCells),
|
||||||
|
maxOp<scalar>()
|
||||||
|
);
|
||||||
|
|
||||||
|
if (imbalance > maxImbalance_)
|
||||||
|
{
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
Info<< "Redistributing mesh with imbalance "
|
||||||
|
<< imbalance << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
redecompose();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::fvMeshDistributors::decomposer::updateMesh(const mapPolyMesh&)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::fvMeshDistributors::decomposer::distribute
|
||||||
|
(
|
||||||
|
const mapDistributePolyMesh&
|
||||||
|
)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::fvMeshDistributors::decomposer::write(const bool write) const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
148
src/fvMeshDistributors/decomposer/fvMeshDistributorDecomposer.H
Normal file
148
src/fvMeshDistributors/decomposer/fvMeshDistributorDecomposer.H
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration | Website: https://openfoam.org
|
||||||
|
\\ / A nd | Copyright (C) 2021 OpenFOAM Foundation
|
||||||
|
\\/ 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::fvMeshDistributor::decomposer
|
||||||
|
|
||||||
|
Description
|
||||||
|
Dynamic mesh redistribution using the decomposer
|
||||||
|
|
||||||
|
Usage
|
||||||
|
Example of single field based refinement in all cells:
|
||||||
|
\verbatim
|
||||||
|
distributor
|
||||||
|
{
|
||||||
|
type decomposer;
|
||||||
|
|
||||||
|
libs ("libfvMeshDistributors.so");
|
||||||
|
|
||||||
|
// How often to redistribute
|
||||||
|
redistributionInterval 10;
|
||||||
|
|
||||||
|
// Maximum fractional cell distribution imbalance
|
||||||
|
// before rebalancing
|
||||||
|
maxImbalance 0.1;
|
||||||
|
}
|
||||||
|
\endverbatim
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
fvMeshDistributorDecomposer.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef fvMeshDistributorDecomposer_H
|
||||||
|
#define fvMeshDistributorDecomposer_H
|
||||||
|
|
||||||
|
#include "fvMeshDistributor.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
namespace fvMeshDistributors
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class decomposer Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class decomposer
|
||||||
|
:
|
||||||
|
public fvMeshDistributor
|
||||||
|
{
|
||||||
|
// Private Member Data
|
||||||
|
|
||||||
|
//- Time-step interval between redistribution calls
|
||||||
|
label redistributionInterval_;
|
||||||
|
|
||||||
|
//- Maximum imbalance between the ideal number of cells per processor
|
||||||
|
// and the maximum or minimum as a ratio mag(1 - nCells/idealNcells)
|
||||||
|
scalar maxImbalance_;
|
||||||
|
|
||||||
|
//- The time index used for updating
|
||||||
|
label timeIndex_;
|
||||||
|
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Read the projection parameters from dictionary
|
||||||
|
void readDict();
|
||||||
|
|
||||||
|
//- Re-decompose the mesh for redistribution
|
||||||
|
void redecompose();
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//- Runtime type information
|
||||||
|
TypeName("decomposer");
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from fvMesh
|
||||||
|
explicit decomposer(fvMesh& mesh);
|
||||||
|
|
||||||
|
//- Disallow default bitwise copy construction
|
||||||
|
decomposer(const decomposer&) = delete;
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
virtual ~decomposer();
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
//- Distribute the mesh
|
||||||
|
virtual bool update();
|
||||||
|
|
||||||
|
//- Update corresponding to the given map
|
||||||
|
virtual void updateMesh(const mapPolyMesh&);
|
||||||
|
|
||||||
|
//- Update corresponding to the given distribution map
|
||||||
|
virtual void distribute(const mapDistributePolyMesh&);
|
||||||
|
|
||||||
|
|
||||||
|
// Writing
|
||||||
|
|
||||||
|
//- Write using given format, version and compression
|
||||||
|
virtual bool write(const bool write = true) const;
|
||||||
|
|
||||||
|
|
||||||
|
// Member Operators
|
||||||
|
|
||||||
|
//- Disallow default bitwise assignment
|
||||||
|
void operator=(const decomposer&) = delete;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace fvMeshDistributors
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -161,33 +161,10 @@ Foam::fvMesh::readUpdateState Foam::processorMeshes::readUpdate()
|
|||||||
// Check if any new meshes need to be read.
|
// Check if any new meshes need to be read.
|
||||||
fvMesh::readUpdateState procStat = meshes_[proci].readUpdate();
|
fvMesh::readUpdateState procStat = meshes_[proci].readUpdate();
|
||||||
|
|
||||||
/*
|
if (procStat > stat)
|
||||||
if (procStat != fvMesh::UNCHANGED)
|
|
||||||
{
|
|
||||||
Info<< "Processor " << proci
|
|
||||||
<< " at time " << databases_[proci].timeName()
|
|
||||||
<< " detected mesh change " << procStat
|
|
||||||
<< endl;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Combine into overall mesh change status
|
|
||||||
if (stat == fvMesh::UNCHANGED)
|
|
||||||
{
|
{
|
||||||
stat = procStat;
|
stat = procStat;
|
||||||
}
|
}
|
||||||
else if (stat != procStat)
|
|
||||||
{
|
|
||||||
FatalErrorInFunction
|
|
||||||
<< "Processor " << proci
|
|
||||||
<< " has a different polyMesh at time "
|
|
||||||
<< databases_[proci].timeName()
|
|
||||||
<< " compared to any previous processors." << nl
|
|
||||||
<< "Please check time " << databases_[proci].timeName()
|
|
||||||
<< " directories on all processors for consistent"
|
|
||||||
<< " mesh files."
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if
|
if
|
||||||
@ -199,6 +176,7 @@ Foam::fvMesh::readUpdateState Foam::processorMeshes::readUpdate()
|
|||||||
// Reread all meshes and addressing
|
// Reread all meshes and addressing
|
||||||
read();
|
read();
|
||||||
}
|
}
|
||||||
|
|
||||||
return stat;
|
return stat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -20,6 +20,8 @@ internalField uniform (0 0 0);
|
|||||||
|
|
||||||
boundaryField
|
boundaryField
|
||||||
{
|
{
|
||||||
|
#includeEtc "caseDicts/setConstraintTypes"
|
||||||
|
|
||||||
stationaryWalls
|
stationaryWalls
|
||||||
{
|
{
|
||||||
type noSlip;
|
type noSlip;
|
||||||
|
|||||||
@ -20,6 +20,8 @@ internalField uniform 0;
|
|||||||
|
|
||||||
boundaryField
|
boundaryField
|
||||||
{
|
{
|
||||||
|
#includeEtc "caseDicts/setConstraintTypes"
|
||||||
|
|
||||||
stationaryWalls
|
stationaryWalls
|
||||||
{
|
{
|
||||||
type zeroGradient;
|
type zeroGradient;
|
||||||
|
|||||||
@ -20,6 +20,8 @@ internalField uniform 0.1;
|
|||||||
|
|
||||||
boundaryField
|
boundaryField
|
||||||
{
|
{
|
||||||
|
#includeEtc "caseDicts/setConstraintTypes"
|
||||||
|
|
||||||
stationaryWalls
|
stationaryWalls
|
||||||
{
|
{
|
||||||
type epsilonWallFunction;
|
type epsilonWallFunction;
|
||||||
|
|||||||
@ -20,6 +20,8 @@ internalField uniform 0.1;
|
|||||||
|
|
||||||
boundaryField
|
boundaryField
|
||||||
{
|
{
|
||||||
|
#includeEtc "caseDicts/setConstraintTypes"
|
||||||
|
|
||||||
stationaryWalls
|
stationaryWalls
|
||||||
{
|
{
|
||||||
type kqRWallFunction;
|
type kqRWallFunction;
|
||||||
|
|||||||
@ -20,6 +20,8 @@ internalField uniform 0;
|
|||||||
|
|
||||||
boundaryField
|
boundaryField
|
||||||
{
|
{
|
||||||
|
#includeEtc "caseDicts/setConstraintTypes"
|
||||||
|
|
||||||
stationaryWalls
|
stationaryWalls
|
||||||
{
|
{
|
||||||
type nutkWallFunction;
|
type nutkWallFunction;
|
||||||
|
|||||||
@ -20,6 +20,8 @@ internalField uniform 0;
|
|||||||
|
|
||||||
boundaryField
|
boundaryField
|
||||||
{
|
{
|
||||||
|
#includeEtc "caseDicts/setConstraintTypes"
|
||||||
|
|
||||||
stationaryWalls
|
stationaryWalls
|
||||||
{
|
{
|
||||||
type fixedFluxPressure;
|
type fixedFluxPressure;
|
||||||
|
|||||||
@ -20,6 +20,8 @@ internalField uniform (0 0 0);
|
|||||||
|
|
||||||
boundaryField
|
boundaryField
|
||||||
{
|
{
|
||||||
|
#includeEtc "caseDicts/setConstraintTypes"
|
||||||
|
|
||||||
stationaryWalls
|
stationaryWalls
|
||||||
{
|
{
|
||||||
type fixedValue;
|
type fixedValue;
|
||||||
|
|||||||
@ -4,13 +4,10 @@ cd ${0%/*} || exit 1 # Run from this directory
|
|||||||
# Source tutorial run functions
|
# Source tutorial run functions
|
||||||
. $WM_PROJECT_DIR/bin/tools/RunFunctions
|
. $WM_PROJECT_DIR/bin/tools/RunFunctions
|
||||||
|
|
||||||
# Set application name
|
|
||||||
application=$(getApplication)
|
|
||||||
|
|
||||||
runApplication blockMesh
|
runApplication blockMesh
|
||||||
runApplication topoSet
|
runApplication topoSet
|
||||||
runApplication subsetMesh -overwrite c0 -patch floatingObject -noFields
|
runApplication subsetMesh -overwrite c0 -patch floatingObject -noFields
|
||||||
runApplication setFields
|
runApplication setFields
|
||||||
runApplication $application
|
runApplication $(getApplication)
|
||||||
|
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
|
|||||||
17
tutorials/multiphase/interFoam/RAS/floatingObject/Allrun-parallel
Executable file
17
tutorials/multiphase/interFoam/RAS/floatingObject/Allrun-parallel
Executable file
@ -0,0 +1,17 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
cd ${0%/*} || exit 1 # Run from this directory
|
||||||
|
|
||||||
|
# Source tutorial run functions
|
||||||
|
. $WM_PROJECT_DIR/bin/tools/RunFunctions
|
||||||
|
|
||||||
|
runApplication blockMesh
|
||||||
|
runApplication topoSet
|
||||||
|
runApplication subsetMesh -overwrite c0 -patch floatingObject -noFields
|
||||||
|
runApplication setFields
|
||||||
|
|
||||||
|
runApplication decomposePar
|
||||||
|
runParallel $(getApplication)
|
||||||
|
runApplication reconstructParMesh
|
||||||
|
runApplication reconstructPar
|
||||||
|
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
@ -120,4 +120,14 @@ topoChanger
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
distributor
|
||||||
|
{
|
||||||
|
type decomposer;
|
||||||
|
|
||||||
|
libs ("libfvMeshDistributors.so");
|
||||||
|
|
||||||
|
redistributionInterval 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
@ -46,6 +46,7 @@ boundary
|
|||||||
(0 4 7 3)
|
(0 4 7 3)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
atmosphere
|
atmosphere
|
||||||
{
|
{
|
||||||
type patch;
|
type patch;
|
||||||
@ -54,11 +55,18 @@ boundary
|
|||||||
(4 5 6 7)
|
(4 5 6 7)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
floatingObject
|
floatingObject
|
||||||
{
|
{
|
||||||
type wall;
|
type wall;
|
||||||
faces ();
|
faces ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal
|
||||||
|
{
|
||||||
|
type internal;
|
||||||
|
faces ();
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -16,7 +16,7 @@ FoamFile
|
|||||||
|
|
||||||
numberOfSubdomains 8;
|
numberOfSubdomains 8;
|
||||||
|
|
||||||
method scotch;
|
method hierarchical;
|
||||||
|
|
||||||
simpleCoeffs
|
simpleCoeffs
|
||||||
{
|
{
|
||||||
@ -25,7 +25,7 @@ simpleCoeffs
|
|||||||
|
|
||||||
hierarchicalCoeffs
|
hierarchicalCoeffs
|
||||||
{
|
{
|
||||||
n (2 2 1);
|
n (2 2 2);
|
||||||
order xyz;
|
order xyz;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user