mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: add decomposePar -dry-run option
- can be used to test the behaviour of the decomposion and its characteristics without writing any decomposition to disk. Combine with -cellDist to visualize the expected decomposition result.
This commit is contained in:
@ -2,6 +2,7 @@ decomposePar.C
|
||||
domainDecomposition.C
|
||||
domainDecompositionMesh.C
|
||||
domainDecompositionDistribute.C
|
||||
domainDecompositionDryRun.C
|
||||
dimFieldDecomposer.C
|
||||
pointFieldDecomposer.C
|
||||
faMeshDecomposition.C
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2017 OpenFOAM Foundation
|
||||
\\/ M anipulation | Copyright (C) 2016-2017 OpenCFD Ltd.
|
||||
\\/ M anipulation | Copyright (C) 2016-2018 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -35,9 +35,12 @@ Usage
|
||||
\b decomposePar [OPTION]
|
||||
|
||||
Options:
|
||||
- \par -dry-run
|
||||
Test without actually decomposing
|
||||
|
||||
- \par -cellDist
|
||||
Write the cell distribution as a labelList, for use with 'manual'
|
||||
decomposition method or as a volScalarField for post-processing.
|
||||
decomposition method and as a volScalarField for visualization.
|
||||
|
||||
- \par -region \<regionName\>
|
||||
Decompose named region. Does not check for existence of processor*.
|
||||
@ -83,6 +86,7 @@ Usage
|
||||
#include "fvCFD.H"
|
||||
#include "IOobjectList.H"
|
||||
#include "domainDecomposition.H"
|
||||
#include "domainDecompositionDryRun.H"
|
||||
#include "labelIOField.H"
|
||||
#include "labelFieldIOField.H"
|
||||
#include "scalarIOField.H"
|
||||
@ -239,10 +243,21 @@ int main(int argc, char *argv[])
|
||||
"operate on all regions in regionProperties"
|
||||
);
|
||||
argList::addBoolOption
|
||||
(
|
||||
"dry-run",
|
||||
"Test without writing the decomposition. "
|
||||
"Changes -cellDist to only write volScalarField."
|
||||
);
|
||||
argList::addBoolOption
|
||||
(
|
||||
"verbose",
|
||||
"Additional verbosity"
|
||||
);
|
||||
argList::addBoolOption
|
||||
(
|
||||
"cellDist",
|
||||
"write cell distribution as a labelList - for use with 'manual' "
|
||||
"decomposition method or as a volScalarField for post-processing."
|
||||
"Write cell distribution as a labelList - for use with 'manual' "
|
||||
"decomposition method and as a volScalarField for visualization."
|
||||
);
|
||||
argList::addBoolOption
|
||||
(
|
||||
@ -280,13 +295,17 @@ int main(int argc, char *argv[])
|
||||
|
||||
#include "setRootCase.H"
|
||||
|
||||
const bool dryrun = args.found("dry-run");
|
||||
const bool optRegion = args.found("region");
|
||||
const bool allRegions = args.found("allRegions");
|
||||
const bool writeCellDist = args.found("cellDist");
|
||||
const bool verbose = args.found("verbose");
|
||||
|
||||
// Most of these are ignored for dry-run (not triggered anywhere)
|
||||
const bool copyZero = args.found("copyZero");
|
||||
const bool copyUniform = args.found("copyUniform");
|
||||
const bool decomposeSets = !args.found("noSets");
|
||||
const bool ifRequiredDecomposition = args.found("ifRequired");
|
||||
const bool decomposeIfRequired = args.found("ifRequired");
|
||||
|
||||
bool decomposeFieldsOnly = args.found("fields");
|
||||
bool forceOverwrite = args.found("force");
|
||||
@ -294,8 +313,18 @@ int main(int argc, char *argv[])
|
||||
|
||||
// Set time from database
|
||||
#include "createTime.H"
|
||||
// Allow override of time
|
||||
instantList times = timeSelector::selectIfPresent(runTime, args);
|
||||
|
||||
// Allow override of time (unless dry-run)
|
||||
instantList times;
|
||||
if (dryrun)
|
||||
{
|
||||
Info<< "\ndry-run: ignoring -copy*, -fields, -force, time selection"
|
||||
<< nl;
|
||||
}
|
||||
else
|
||||
{
|
||||
times = timeSelector::selectIfPresent(runTime, args);
|
||||
}
|
||||
|
||||
|
||||
// Allow override of decomposeParDict location
|
||||
@ -305,7 +334,7 @@ int main(int argc, char *argv[])
|
||||
wordList regionNames;
|
||||
if (allRegions)
|
||||
{
|
||||
Info<< "Decomposing all regions in regionProperties" << nl << endl;
|
||||
Info<< "Decomposing all regions in regionProperties" << nl << nl;
|
||||
regionProperties rp(runTime);
|
||||
|
||||
wordHashSet names;
|
||||
@ -329,6 +358,29 @@ int main(int argc, char *argv[])
|
||||
const word& regionDir =
|
||||
(regionName == fvMesh::defaultRegion ? word::null : regionName);
|
||||
|
||||
if (dryrun)
|
||||
{
|
||||
Info<< "dry-run: decomposing mesh " << regionName << nl << nl
|
||||
<< "Create mesh..." << flush;
|
||||
|
||||
domainDecompositionDryRun decompTest
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
regionName,
|
||||
runTime.timeName(),
|
||||
runTime,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
),
|
||||
decompDictFile
|
||||
);
|
||||
|
||||
decompTest.execute(writeCellDist, verbose);
|
||||
continue;
|
||||
}
|
||||
|
||||
Info<< "\n\nDecomposing mesh " << regionName << nl << endl;
|
||||
|
||||
// Determine the existing processor count directly
|
||||
@ -346,7 +398,7 @@ int main(int argc, char *argv[])
|
||||
(
|
||||
"decomposeParDict",
|
||||
runTime.time().system(),
|
||||
regionDir, // use region if non-standard
|
||||
regionDir, // region (if non-default)
|
||||
runTime,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::NO_WRITE,
|
||||
@ -378,9 +430,9 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
bool procDirsProblem = true;
|
||||
|
||||
if (ifRequiredDecomposition && nProcs == nDomains)
|
||||
if (decomposeIfRequired && nProcs == nDomains)
|
||||
{
|
||||
// we can reuse the decomposition
|
||||
// We can reuse the decomposition
|
||||
decomposeFieldsOnly = true;
|
||||
procDirsProblem = false;
|
||||
forceOverwrite = false;
|
||||
@ -485,28 +537,7 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
const labelList& procIds = mesh.cellToProc();
|
||||
|
||||
// Write the decomposition as labelList for use with 'manual'
|
||||
// decomposition method.
|
||||
labelIOList cellDecomposition
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"cellDecomposition",
|
||||
mesh.facesInstance(),
|
||||
mesh,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
),
|
||||
procIds
|
||||
);
|
||||
cellDecomposition.write();
|
||||
|
||||
Info<< nl << "Wrote decomposition to "
|
||||
<< cellDecomposition.objectPath()
|
||||
<< " for use in manual decomposition." << endl;
|
||||
|
||||
// Write as volScalarField for postprocessing.
|
||||
// Write decomposition as volScalarField for visualization
|
||||
volScalarField cellDist
|
||||
(
|
||||
IOobject
|
||||
@ -531,8 +562,29 @@ int main(int argc, char *argv[])
|
||||
cellDist.write();
|
||||
|
||||
Info<< nl << "Wrote decomposition as volScalarField to "
|
||||
<< cellDist.name() << " for use in postprocessing."
|
||||
<< cellDist.name() << " for visualization."
|
||||
<< endl;
|
||||
|
||||
// Write decomposition as labelList for use with 'manual'
|
||||
// decomposition method.
|
||||
labelIOList cellDecomposition
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"cellDecomposition",
|
||||
mesh.facesInstance(),
|
||||
mesh,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
),
|
||||
procIds
|
||||
);
|
||||
cellDecomposition.write();
|
||||
|
||||
Info<< nl << "Wrote decomposition to "
|
||||
<< cellDecomposition.objectPath()
|
||||
<< " for use in manual decomposition." << endl;
|
||||
}
|
||||
|
||||
fileOperations::collatedFileOperation::maxThreadFileBufferSize =
|
||||
|
||||
@ -159,8 +159,10 @@ public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from IOobjects (for mesh and optional non-standard
|
||||
//- decomposeParDict location)
|
||||
//- Construct from components.
|
||||
// \param io the IOobject for mesh
|
||||
// \param decompDictFile optional non-standard location for the
|
||||
// decomposeParDict file
|
||||
domainDecomposition
|
||||
(
|
||||
const IOobject& io,
|
||||
@ -186,7 +188,7 @@ public:
|
||||
return distributed_;
|
||||
}
|
||||
|
||||
//- Decompose mesh.
|
||||
//- Decompose mesh
|
||||
void decomposeMesh();
|
||||
|
||||
//- Write decomposition
|
||||
|
||||
@ -0,0 +1,200 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2018 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 "domainDecompositionDryRun.H"
|
||||
#include "volFields.H"
|
||||
#include "decompositionModel.H"
|
||||
#include "decompositionInformation.H"
|
||||
#include "zeroGradientFvPatchFields.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::domainDecompositionDryRun::domainDecompositionDryRun
|
||||
(
|
||||
const IOobject& io,
|
||||
const fileName& decompDictFile,
|
||||
const label nDomains,
|
||||
const word& methodName
|
||||
)
|
||||
:
|
||||
mesh_(io),
|
||||
decompDictFile_(decompDictFile),
|
||||
nDomainsOverride_(nDomains),
|
||||
methodNameOverride_(methodName)
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::domainDecompositionDryRun::execute
|
||||
(
|
||||
const bool writeCellDist,
|
||||
const bool verbose
|
||||
)
|
||||
{
|
||||
cpuTime decompositionTime;
|
||||
|
||||
Info<< "\nCalculating distribution of cells. nCells = "
|
||||
<< mesh_.nCells() << endl;
|
||||
|
||||
const decompositionModel& model = decompositionModel::New
|
||||
(
|
||||
mesh_,
|
||||
decompDictFile_
|
||||
);
|
||||
|
||||
// Allow overrides for testing
|
||||
|
||||
dictionary& modelDict = const_cast<decompositionModel&>(model);
|
||||
|
||||
if (nDomainsOverride_ > 0)
|
||||
{
|
||||
modelDict.add
|
||||
(
|
||||
word("numberOfSubdomains"),
|
||||
nDomainsOverride_,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
if (!methodNameOverride_.empty())
|
||||
{
|
||||
modelDict.add
|
||||
(
|
||||
word("method"),
|
||||
methodNameOverride_,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
scalarField cellWeights;
|
||||
word weightName;
|
||||
if (model.readIfPresent("weightField", weightName))
|
||||
{
|
||||
volScalarField weights
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
weightName,
|
||||
mesh_.time().timeName(),
|
||||
mesh_,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::NO_WRITE
|
||||
),
|
||||
mesh_
|
||||
);
|
||||
cellWeights = weights.primitiveField();
|
||||
}
|
||||
|
||||
decompositionMethod& method = model.decomposer();
|
||||
|
||||
CompactListList<label> cellCells;
|
||||
decompositionMethod::calcCellCells
|
||||
(
|
||||
mesh_,
|
||||
identity(mesh_.nCells()),
|
||||
mesh_.nCells(),
|
||||
false,
|
||||
cellCells
|
||||
);
|
||||
|
||||
labelList cellToProc = method.decompose(mesh_, cellWeights);
|
||||
|
||||
Info<< "\nFinished decomposition into "
|
||||
<< method.nDomains() << " domains in "
|
||||
<< decompositionTime.elapsedCpuTime() << " s" << nl << nl;
|
||||
|
||||
decompositionInformation info
|
||||
(
|
||||
cellCells,
|
||||
cellToProc,
|
||||
method.nDomains()
|
||||
);
|
||||
|
||||
if (writeCellDist)
|
||||
{
|
||||
// Write decomposition as volScalarField for visualization
|
||||
volScalarField cellDist
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"cellDist",
|
||||
mesh_.time().timeName(),
|
||||
mesh_,
|
||||
IOobject::NO_READ,
|
||||
IOobject::AUTO_WRITE
|
||||
),
|
||||
mesh_,
|
||||
dimensionedScalar("cellDist", dimless, -1),
|
||||
zeroGradientFvPatchScalarField::typeName
|
||||
);
|
||||
|
||||
forAll(cellToProc, celli)
|
||||
{
|
||||
cellDist[celli] = cellToProc[celli];
|
||||
}
|
||||
|
||||
cellDist.correctBoundaryConditions();
|
||||
cellDist.write();
|
||||
|
||||
Info<< "Wrote decomposition as volScalarField for visualization:"
|
||||
<< nl << cellDist.objectPath() << nl;
|
||||
|
||||
// Less likely that this is actually required, but may be useful...
|
||||
//
|
||||
// // Write decomposition as labelList for use with 'manual'
|
||||
// // decomposition method.
|
||||
// labelIOList cellDecomposition
|
||||
// (
|
||||
// IOobject
|
||||
// (
|
||||
// "cellDecomposition",
|
||||
// mesh_.facesInstance(),
|
||||
// mesh_,
|
||||
// IOobject::NO_READ,
|
||||
// IOobject::NO_WRITE,
|
||||
// false
|
||||
// ),
|
||||
// std::move(cellToProc)
|
||||
// );
|
||||
// cellDecomposition.write();
|
||||
//
|
||||
// Info<< "Wrote decomposition for use in manual decomposition:"
|
||||
// << nl << cellDecomposition.objectPath() << nl;
|
||||
// #endif
|
||||
|
||||
Info<< nl;
|
||||
}
|
||||
|
||||
if (verbose)
|
||||
{
|
||||
info.printDetails(Info);
|
||||
Info<< nl;
|
||||
}
|
||||
info.printSummary(Info);
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,102 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2018 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::domainDecompositionDryRun
|
||||
|
||||
Description
|
||||
Testing of domain decomposition for finite-volume meshes
|
||||
|
||||
SourceFiles
|
||||
domainDecompositionDryRun.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef domainDecompositionDryRun_H
|
||||
#define domainDecompositionDryRun_H
|
||||
|
||||
#include "fvMesh.H"
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class domainDecompositionDryRun Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class domainDecompositionDryRun
|
||||
{
|
||||
// Private Data
|
||||
|
||||
//- The mesh
|
||||
fvMesh mesh_;
|
||||
|
||||
//- Optional non-standard file for decomposeParDict
|
||||
const fileName decompDictFile_;
|
||||
|
||||
//- Optional override for numberOfSubdomains in decomposeParDict
|
||||
const label nDomainsOverride_;
|
||||
|
||||
//- Optional override for method in decomposeParDict
|
||||
const word methodNameOverride_;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from components.
|
||||
// \param io the IOobject for mesh
|
||||
// \param decompDictFile optional non-standard location for the
|
||||
// decomposeParDict file
|
||||
// \param nDomains optional override value for numberOfSubdomains
|
||||
// \param methodName optional override value for decomposition method
|
||||
domainDecompositionDryRun
|
||||
(
|
||||
const IOobject& io,
|
||||
const fileName& decompDictFile = "",
|
||||
const label nDomains = 0,
|
||||
const word& methodName = ""
|
||||
);
|
||||
|
||||
|
||||
//- Destructor
|
||||
~domainDecompositionDryRun() = default;
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Perform dry-run
|
||||
void execute(const bool writeCellDist, const bool verbose = false);
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -135,8 +135,10 @@ public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from fvMesh (for mesh and optional non-standard
|
||||
//- decomposeParDict location)
|
||||
//- Construct from components.
|
||||
// \param mesh the fvMesh
|
||||
// \param decompDictFile optional non-standard location for the
|
||||
// decomposeParDict file
|
||||
faMeshDecomposition
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
|
||||
Reference in New Issue
Block a user