mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: multi-region support for reconstructParMesh (#2072)
This commit is contained in:
@ -71,7 +71,6 @@ int main(int argc, char *argv[])
|
|||||||
#include "setRootCase.H"
|
#include "setRootCase.H"
|
||||||
|
|
||||||
const auto decompFile = args.get<fileName>(1);
|
const auto decompFile = args.get<fileName>(1);
|
||||||
const bool region = args.found("region");
|
|
||||||
const bool verbose = args.found("verbose");
|
const bool verbose = args.found("verbose");
|
||||||
|
|
||||||
// Set time from database
|
// Set time from database
|
||||||
@ -87,23 +86,17 @@ int main(int argc, char *argv[])
|
|||||||
// Get region names
|
// Get region names
|
||||||
#include "getAllRegionOptions.H"
|
#include "getAllRegionOptions.H"
|
||||||
|
|
||||||
wordList regionDirs(regionNames);
|
|
||||||
if (regionDirs.size() == 1 && regionDirs[0] == polyMesh::defaultRegion)
|
|
||||||
{
|
|
||||||
regionDirs[0].clear();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Info<< "Decomposing regions: "
|
|
||||||
<< flatOutput(regionNames) << nl << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
labelList cellToProc;
|
labelList cellToProc;
|
||||||
|
|
||||||
forAll(regionNames, regioni)
|
forAll(regionNames, regioni)
|
||||||
{
|
{
|
||||||
const word& regionName = regionNames[regioni];
|
const word& regionName = regionNames[regioni];
|
||||||
const word& regionDir = regionDirs[regioni];
|
// const word& regionDir =
|
||||||
|
// (
|
||||||
|
// regionName != polyMesh::defaultRegion
|
||||||
|
// ? regionName
|
||||||
|
// : word::null
|
||||||
|
// );
|
||||||
|
|
||||||
Info<< "\n\nDecomposing mesh " << regionName << nl << endl;
|
Info<< "\n\nDecomposing mesh " << regionName << nl << endl;
|
||||||
Info<< "Create mesh..." << flush;
|
Info<< "Create mesh..." << flush;
|
||||||
|
|||||||
@ -52,7 +52,7 @@ void Foam::domainDecomposition::writeVolField
|
|||||||
false
|
false
|
||||||
),
|
),
|
||||||
this->mesh(),
|
this->mesh(),
|
||||||
dimensionedScalar("cellDist", dimless, -1),
|
dimensionedScalar(dimless, Zero),
|
||||||
zeroGradientFvPatchScalarField::typeName
|
zeroGradientFvPatchScalarField::typeName
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -172,23 +172,29 @@ int main(int argc, char *argv[])
|
|||||||
// Get region names
|
// Get region names
|
||||||
#include "getAllRegionOptions.H"
|
#include "getAllRegionOptions.H"
|
||||||
|
|
||||||
wordList regionDirs(regionNames);
|
// Determine the processor count
|
||||||
|
label nProcs{0};
|
||||||
|
|
||||||
if (regionNames.size() == 1)
|
if (regionNames.empty())
|
||||||
{
|
{
|
||||||
if (regionNames[0] == polyMesh::defaultRegion)
|
FatalErrorInFunction
|
||||||
|
<< "No regions specified or detected."
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
else if (regionNames[0] == polyMesh::defaultRegion)
|
||||||
{
|
{
|
||||||
regionDirs[0].clear();
|
nProcs = fileHandler().nProcs(args.path());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
nProcs = fileHandler().nProcs(args.path(), regionNames[0]);
|
||||||
|
|
||||||
|
if (regionNames.size() == 1)
|
||||||
{
|
{
|
||||||
Info<< "Using region: " << regionNames[0] << nl << endl;
|
Info<< "Using region: " << regionNames[0] << nl << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine the processor count
|
|
||||||
label nProcs = fileHandler().nProcs(args.path(), regionDirs[0]);
|
|
||||||
|
|
||||||
if (!nProcs)
|
if (!nProcs)
|
||||||
{
|
{
|
||||||
FatalErrorInFunction
|
FatalErrorInFunction
|
||||||
@ -261,16 +267,21 @@ int main(int argc, char *argv[])
|
|||||||
forAll(regionNames, regioni)
|
forAll(regionNames, regioni)
|
||||||
{
|
{
|
||||||
const word& regionName = regionNames[regioni];
|
const word& regionName = regionNames[regioni];
|
||||||
const word& regionDir = regionDirs[regioni];
|
const word& regionDir =
|
||||||
|
(
|
||||||
|
regionName != polyMesh::defaultRegion
|
||||||
|
? regionName
|
||||||
|
: word::null
|
||||||
|
);
|
||||||
|
|
||||||
Info<< "\n\nReconstructing fields for mesh " << regionName << nl
|
Info<< "\n\nReconstructing fields" << nl
|
||||||
<< endl;
|
<< "region=" << regionName << nl << endl;
|
||||||
|
|
||||||
if
|
if
|
||||||
(
|
(
|
||||||
newTimes
|
newTimes
|
||||||
&& regionNames.size() == 1
|
&& regionNames.size() == 1
|
||||||
&& regionDirs[0].empty()
|
&& regionDir.empty()
|
||||||
&& haveAllTimes(masterTimeDirSet, timeDirs)
|
&& haveAllTimes(masterTimeDirSet, timeDirs)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -71,6 +71,7 @@ Usage
|
|||||||
#include "polyTopoChange.H"
|
#include "polyTopoChange.H"
|
||||||
#include "extrapolatedCalculatedFvPatchFields.H"
|
#include "extrapolatedCalculatedFvPatchFields.H"
|
||||||
#include "topoSet.H"
|
#include "topoSet.H"
|
||||||
|
#include "regionProperties.H"
|
||||||
#include "fvMeshTools.H"
|
#include "fvMeshTools.H"
|
||||||
|
|
||||||
using namespace Foam;
|
using namespace Foam;
|
||||||
@ -304,31 +305,29 @@ autoPtr<mapPolyMesh> mergeSharedPoints
|
|||||||
|
|
||||||
boundBox procBounds
|
boundBox procBounds
|
||||||
(
|
(
|
||||||
const argList& args,
|
|
||||||
const PtrList<Time>& databases,
|
const PtrList<Time>& databases,
|
||||||
const word& regionDir
|
const word& regionDir
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
boundBox bb = boundBox::invertedBox;
|
boundBox bb;
|
||||||
|
|
||||||
forAll(databases, proci)
|
for (const Time& procDb : databases)
|
||||||
{
|
{
|
||||||
fileName pointsInstance
|
fileName pointsInstance
|
||||||
(
|
(
|
||||||
databases[proci].findInstance
|
procDb.findInstance
|
||||||
(
|
(
|
||||||
regionDir/polyMesh::meshSubDir,
|
regionDir/polyMesh::meshSubDir,
|
||||||
"points"
|
"points"
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (pointsInstance != databases[proci].timeName())
|
if (pointsInstance != procDb.timeName())
|
||||||
{
|
{
|
||||||
FatalErrorInFunction
|
FatalErrorInFunction
|
||||||
<< "Your time was specified as " << databases[proci].timeName()
|
<< "Your time was specified as " << procDb.timeName()
|
||||||
<< " but there is no polyMesh/points in that time." << endl
|
<< " but there is no polyMesh/points in that time." << nl
|
||||||
<< "(there is a points file in " << pointsInstance
|
<< "(points file at " << pointsInstance << ')' << nl
|
||||||
<< ")" << endl
|
|
||||||
<< "Please rerun with the correct time specified"
|
<< "Please rerun with the correct time specified"
|
||||||
<< " (through the -constant, -time or -latestTime "
|
<< " (through the -constant, -time or -latestTime "
|
||||||
<< "(at your option)."
|
<< "(at your option)."
|
||||||
@ -336,8 +335,8 @@ boundBox procBounds
|
|||||||
}
|
}
|
||||||
|
|
||||||
Info<< "Reading points from "
|
Info<< "Reading points from "
|
||||||
<< databases[proci].caseName()
|
<< procDb.caseName()
|
||||||
<< " for time = " << databases[proci].timeName()
|
<< " for time = " << procDb.timeName()
|
||||||
<< nl << endl;
|
<< nl << endl;
|
||||||
|
|
||||||
pointIOField points
|
pointIOField points
|
||||||
@ -345,13 +344,13 @@ boundBox procBounds
|
|||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
"points",
|
"points",
|
||||||
databases[proci].findInstance
|
procDb.findInstance
|
||||||
(
|
(
|
||||||
regionDir/polyMesh::meshSubDir,
|
regionDir/polyMesh::meshSubDir,
|
||||||
"points"
|
"points"
|
||||||
),
|
),
|
||||||
regionDir/polyMesh::meshSubDir,
|
regionDir/polyMesh::meshSubDir,
|
||||||
databases[proci],
|
procDb,
|
||||||
IOobject::MUST_READ,
|
IOobject::MUST_READ,
|
||||||
IOobject::NO_WRITE,
|
IOobject::NO_WRITE,
|
||||||
false
|
false
|
||||||
@ -397,10 +396,9 @@ void writeDistribution
|
|||||||
cellDecomposition.write();
|
cellDecomposition.write();
|
||||||
|
|
||||||
Info<< nl << "Wrote decomposition to "
|
Info<< nl << "Wrote decomposition to "
|
||||||
<< cellDecomposition.objectPath()
|
<< runTime.relativePath(cellDecomposition.objectPath())
|
||||||
<< " for use in manual decomposition." << endl;
|
<< " for use in manual decomposition." << endl;
|
||||||
|
|
||||||
|
|
||||||
// Write as volScalarField for postprocessing. Change time to 0
|
// Write as volScalarField for postprocessing. Change time to 0
|
||||||
// if was 'constant'
|
// if was 'constant'
|
||||||
{
|
{
|
||||||
@ -419,7 +417,8 @@ void writeDistribution
|
|||||||
runTime.timeName(),
|
runTime.timeName(),
|
||||||
masterMesh,
|
masterMesh,
|
||||||
IOobject::NO_READ,
|
IOobject::NO_READ,
|
||||||
IOobject::AUTO_WRITE
|
IOobject::NO_WRITE,
|
||||||
|
false
|
||||||
),
|
),
|
||||||
masterMesh,
|
masterMesh,
|
||||||
dimensionedScalar(dimless, Zero),
|
dimensionedScalar(dimless, Zero),
|
||||||
@ -430,12 +429,13 @@ void writeDistribution
|
|||||||
{
|
{
|
||||||
cellDist[celli] = cellDecomposition[celli];
|
cellDist[celli] = cellDecomposition[celli];
|
||||||
}
|
}
|
||||||
cellDist.correctBoundaryConditions();
|
|
||||||
|
|
||||||
|
cellDist.correctBoundaryConditions();
|
||||||
cellDist.write();
|
cellDist.write();
|
||||||
|
|
||||||
Info<< nl << "Wrote decomposition as volScalarField to "
|
Info<< nl << "Wrote decomposition to "
|
||||||
<< cellDist.name() << " for use in postprocessing."
|
<< runTime.relativePath(cellDist.objectPath())
|
||||||
|
<< " (volScalarField) for visualization."
|
||||||
<< endl;
|
<< endl;
|
||||||
|
|
||||||
// Restore time
|
// Restore time
|
||||||
@ -450,9 +450,23 @@ void writeMesh
|
|||||||
const labelListList& cellProcAddressing
|
const labelListList& cellProcAddressing
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
Info<< "\nWriting merged mesh to "
|
const word& regionDir =
|
||||||
<< mesh.time().path()/mesh.time().timeName()
|
(
|
||||||
<< nl << endl;
|
mesh.name() == polyMesh::defaultRegion
|
||||||
|
? word::null
|
||||||
|
: mesh.name()
|
||||||
|
);
|
||||||
|
|
||||||
|
const fileName outputDir
|
||||||
|
(
|
||||||
|
mesh.time().path()
|
||||||
|
/ mesh.time().timeName()
|
||||||
|
/ regionDir
|
||||||
|
/ polyMesh::meshSubDir
|
||||||
|
);
|
||||||
|
|
||||||
|
Info<< nl << "Writing merged mesh to "
|
||||||
|
<< mesh.time().relativePath(outputDir) << nl << endl;
|
||||||
|
|
||||||
if (!mesh.write())
|
if (!mesh.write())
|
||||||
{
|
{
|
||||||
@ -472,13 +486,21 @@ void writeMaps
|
|||||||
const labelUList& cellProcAddressing,
|
const labelUList& cellProcAddressing,
|
||||||
const labelUList& faceProcAddressing,
|
const labelUList& faceProcAddressing,
|
||||||
const labelUList& pointProcAddressing,
|
const labelUList& pointProcAddressing,
|
||||||
const labelUList& boundaryProcAddressing
|
const labelUList& boundProcAddressing
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
const word& regionDir =
|
||||||
|
(
|
||||||
|
procMesh.name() == polyMesh::defaultRegion
|
||||||
|
? word::null
|
||||||
|
: procMesh.name()
|
||||||
|
);
|
||||||
|
|
||||||
const fileName outputDir
|
const fileName outputDir
|
||||||
(
|
(
|
||||||
procMesh.time().caseName()
|
procMesh.time().caseName()
|
||||||
/ procMesh.facesInstance()
|
/ procMesh.facesInstance()
|
||||||
|
/ regionDir
|
||||||
/ polyMesh::meshSubDir
|
/ polyMesh::meshSubDir
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -494,16 +516,18 @@ void writeMaps
|
|||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
Info<< "Writing addressing : " << outputDir << nl;
|
||||||
|
|
||||||
// From processor point to reconstructed mesh point
|
// From processor point to reconstructed mesh point
|
||||||
|
|
||||||
Info<< "Writing pointProcAddressing to " << outputDir << endl;
|
Info<< " pointProcAddressing" << endl;
|
||||||
ioAddr.rename("pointProcAddressing");
|
ioAddr.rename("pointProcAddressing");
|
||||||
labelIOList(ioAddr, pointProcAddressing).write();
|
labelIOList(ioAddr, pointProcAddressing).write();
|
||||||
|
|
||||||
|
|
||||||
// From processor face to reconstructed mesh face
|
// From processor face to reconstructed mesh face
|
||||||
|
|
||||||
Info<< "Writing faceProcAddressing to " << outputDir << endl;
|
Info<< " faceProcAddressing" << endl;
|
||||||
ioAddr.rename("faceProcAddressing");
|
ioAddr.rename("faceProcAddressing");
|
||||||
|
|
||||||
labelIOList faceProcAddr(ioAddr, faceProcAddressing);
|
labelIOList faceProcAddr(ioAddr, faceProcAddressing);
|
||||||
@ -549,26 +573,39 @@ void writeMaps
|
|||||||
|
|
||||||
// From processor cell to reconstructed mesh cell
|
// From processor cell to reconstructed mesh cell
|
||||||
|
|
||||||
Info<< "Writing cellProcAddressing to " << outputDir << endl;
|
Info<< " cellProcAddressing" << endl;
|
||||||
ioAddr.rename("cellProcAddressing");
|
ioAddr.rename("cellProcAddressing");
|
||||||
labelIOList(ioAddr, cellProcAddressing).write();
|
labelIOList(ioAddr, cellProcAddressing).write();
|
||||||
|
|
||||||
|
|
||||||
// From processor patch to reconstructed mesh patch
|
// From processor patch to reconstructed mesh patch
|
||||||
|
|
||||||
Info<< "Writing boundaryProcAddressing to " << outputDir << endl;
|
Info<< " boundaryProcAddressing" << endl;
|
||||||
ioAddr.rename("boundaryProcAddressing");
|
ioAddr.rename("boundaryProcAddressing");
|
||||||
labelIOList(ioAddr, boundaryProcAddressing).write();
|
labelIOList(ioAddr, boundProcAddressing).write();
|
||||||
|
|
||||||
Info<< endl;
|
Info<< endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void printWarning()
|
||||||
|
{
|
||||||
|
Info<<
|
||||||
|
"Merge individual processor meshes back into one master mesh.\n"
|
||||||
|
"Use if the original master mesh has been deleted or the processor meshes\n"
|
||||||
|
"have been modified (topology change).\n"
|
||||||
|
"This tool will write the resulting mesh to a new time step and construct\n"
|
||||||
|
"xxxxProcAddressing files in the processor meshes so reconstructPar can be\n"
|
||||||
|
"used to regenerate the fields on the master mesh.\n\n"
|
||||||
|
"Not well tested & use at your own risk!\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
argList::addNote
|
argList::addNote
|
||||||
(
|
(
|
||||||
"Reconstruct a mesh using geometric information only"
|
"Reconstruct a mesh using geometric/topological information only"
|
||||||
);
|
);
|
||||||
|
|
||||||
// Enable -constant ... if someone really wants it
|
// Enable -constant ... if someone really wants it
|
||||||
@ -576,6 +613,12 @@ int main(int argc, char *argv[])
|
|||||||
timeSelector::addOptions(true, true); // constant(true), zero(true)
|
timeSelector::addOptions(true, true); // constant(true), zero(true)
|
||||||
|
|
||||||
argList::noParallel();
|
argList::noParallel();
|
||||||
|
|
||||||
|
argList::addBoolOption
|
||||||
|
(
|
||||||
|
"addressing-only",
|
||||||
|
"Create procAddressing only without overwriting the mesh"
|
||||||
|
);
|
||||||
argList::addOption
|
argList::addOption
|
||||||
(
|
(
|
||||||
"mergeTol",
|
"mergeTol",
|
||||||
@ -599,61 +642,40 @@ int main(int argc, char *argv[])
|
|||||||
"decomposition method or as a volScalarField for post-processing."
|
"decomposition method or as a volScalarField for post-processing."
|
||||||
);
|
);
|
||||||
|
|
||||||
#include "addRegionOption.H"
|
#include "addAllRegionOptions.H"
|
||||||
|
|
||||||
#include "setRootCase.H"
|
#include "setRootCase.H"
|
||||||
#include "createTime.H"
|
#include "createTime.H"
|
||||||
|
|
||||||
Info<< "This is an experimental tool which tries to merge"
|
printWarning();
|
||||||
<< " individual processor" << nl
|
|
||||||
<< "meshes back into one master mesh. Use it if the original"
|
|
||||||
<< " master mesh has" << nl
|
|
||||||
<< "been deleted or if the processor meshes have been modified"
|
|
||||||
<< " (topology change)." << nl
|
|
||||||
<< "This tool will write the resulting mesh to a new time step"
|
|
||||||
<< " and construct" << nl
|
|
||||||
<< "xxxxProcAddressing files in the processor meshes so"
|
|
||||||
<< " reconstructPar can be" << nl
|
|
||||||
<< "used to regenerate the fields on the master mesh." << nl
|
|
||||||
<< nl
|
|
||||||
<< "Not well tested & use at your own risk!" << nl
|
|
||||||
<< endl;
|
|
||||||
|
|
||||||
|
|
||||||
word regionName(polyMesh::defaultRegion);
|
|
||||||
word regionDir;
|
|
||||||
|
|
||||||
if
|
|
||||||
(
|
|
||||||
args.readIfPresent("region", regionName)
|
|
||||||
&& regionName != polyMesh::defaultRegion
|
|
||||||
)
|
|
||||||
{
|
|
||||||
regionDir = regionName;
|
|
||||||
Info<< "Operating on region " << regionName << nl << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
const bool fullMatch = args.found("fullMatch");
|
const bool fullMatch = args.found("fullMatch");
|
||||||
const bool procMatch = args.found("procMatch");
|
const bool procMatch = args.found("procMatch");
|
||||||
const bool writeCellDist = args.found("cellDist");
|
const bool writeCellDist = args.found("cellDist");
|
||||||
|
|
||||||
|
const bool writeAddrOnly = args.found("addressing-only");
|
||||||
|
|
||||||
|
const scalar mergeTol =
|
||||||
|
args.getOrDefault<scalar>("mergeTol", defaultMergeTol);
|
||||||
|
|
||||||
if (fullMatch)
|
if (fullMatch)
|
||||||
{
|
{
|
||||||
Info<< "Doing geometric matching on all boundary faces." << nl << endl;
|
Info<< "Use geometric matching on all boundary faces." << nl << endl;
|
||||||
}
|
}
|
||||||
else if (procMatch)
|
else if (procMatch)
|
||||||
{
|
{
|
||||||
Info<< "Doing geometric matching on correct procBoundaries only."
|
Info<< "Use geometric matching on correct procBoundaries only." << nl
|
||||||
<< nl << "This assumes a correct decomposition." << endl;
|
<< "This assumes a correct decomposition." << endl;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Info<< "Assuming correct, fully matched procBoundaries." << nl << endl;
|
Info<< "Merge assuming correct, fully matched procBoundaries." << nl
|
||||||
|
<< endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
scalar mergeTol = args.getOrDefault<scalar>("mergeTol", defaultMergeTol);
|
|
||||||
if (fullMatch || procMatch)
|
if (fullMatch || procMatch)
|
||||||
{
|
{
|
||||||
scalar writeTol =
|
const scalar writeTol =
|
||||||
Foam::pow(10.0, -scalar(IOstream::defaultPrecision()));
|
Foam::pow(10.0, -scalar(IOstream::defaultPrecision()));
|
||||||
|
|
||||||
Info<< "Merge tolerance : " << mergeTol << nl
|
Info<< "Merge tolerance : " << mergeTol << nl
|
||||||
@ -673,16 +695,46 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
label nProcs = fileHandler().nProcs(args.path());
|
// Get region names
|
||||||
|
#include "getAllRegionOptions.H"
|
||||||
|
|
||||||
Info<< "Found " << nProcs << " processor directories" << nl << endl;
|
// Determine the processor count
|
||||||
|
label nProcs{0};
|
||||||
|
|
||||||
|
if (regionNames.empty())
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "No regions specified or detected."
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
else if (regionNames[0] == polyMesh::defaultRegion)
|
||||||
|
{
|
||||||
|
nProcs = fileHandler().nProcs(args.path());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nProcs = fileHandler().nProcs(args.path(), regionNames[0]);
|
||||||
|
|
||||||
|
if (regionNames.size() == 1)
|
||||||
|
{
|
||||||
|
Info<< "Using region: " << regionNames[0] << nl << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!nProcs)
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "No processor* directories found"
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
// Read all time databases
|
// Read all time databases
|
||||||
PtrList<Time> databases(nProcs);
|
PtrList<Time> databases(nProcs);
|
||||||
|
|
||||||
|
Info<< "Found " << nProcs << " processor directories" << endl;
|
||||||
forAll(databases, proci)
|
forAll(databases, proci)
|
||||||
{
|
{
|
||||||
Info<< "Reading database "
|
Info<< " Reading database "
|
||||||
<< args.caseName()/("processor" + Foam::name(proci))
|
<< args.caseName()/("processor" + Foam::name(proci))
|
||||||
<< endl;
|
<< endl;
|
||||||
|
|
||||||
@ -697,6 +749,7 @@ int main(int argc, char *argv[])
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Info<< endl;
|
||||||
|
|
||||||
// Use the times list from the master processor
|
// Use the times list from the master processor
|
||||||
// and select a subset based on the command-line options
|
// and select a subset based on the command-line options
|
||||||
@ -707,19 +760,32 @@ int main(int argc, char *argv[])
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Loop over all times
|
// Loop over all times
|
||||||
forAll(timeDirs, timeI)
|
forAll(timeDirs, timei)
|
||||||
{
|
{
|
||||||
// Set time for global database
|
// Set time for global database
|
||||||
runTime.setTime(timeDirs[timeI], timeI);
|
runTime.setTime(timeDirs[timei], timei);
|
||||||
|
|
||||||
Info<< "Time = " << runTime.timeName() << nl << endl;
|
|
||||||
|
|
||||||
// Set time for all databases
|
// Set time for all databases
|
||||||
forAll(databases, proci)
|
forAll(databases, proci)
|
||||||
{
|
{
|
||||||
databases[proci].setTime(timeDirs[timeI], timeI);
|
databases[proci].setTime(timeDirs[timei], timei);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Info<< "Time = " << runTime.timeName() << endl;
|
||||||
|
|
||||||
|
// Check for any mesh changes
|
||||||
|
label nMeshChanged = 0;
|
||||||
|
boolList hasRegionMesh(regionNames.size(), false);
|
||||||
|
forAll(regionNames, regioni)
|
||||||
|
{
|
||||||
|
const word& regionName = regionNames[regioni];
|
||||||
|
const word& regionDir =
|
||||||
|
(
|
||||||
|
regionName == polyMesh::defaultRegion
|
||||||
|
? word::null
|
||||||
|
: regionName
|
||||||
|
);
|
||||||
|
|
||||||
IOobject facesIO
|
IOobject facesIO
|
||||||
(
|
(
|
||||||
"faces",
|
"faces",
|
||||||
@ -730,22 +796,55 @@ int main(int argc, char *argv[])
|
|||||||
IOobject::NO_WRITE
|
IOobject::NO_WRITE
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
// Problem: faceCompactIOList recognises both 'faceList' and
|
// Problem: faceCompactIOList recognises both 'faceList' and
|
||||||
// 'faceCompactList' so we should be lenient when doing
|
// 'faceCompactList' so we should be lenient when doing
|
||||||
// typeHeaderOk
|
// typeHeaderOk
|
||||||
if (!facesIO.typeHeaderOk<faceCompactIOList>(false))
|
|
||||||
|
const bool ok = facesIO.typeHeaderOk<faceCompactIOList>(false);
|
||||||
|
|
||||||
|
if (ok)
|
||||||
{
|
{
|
||||||
Info<< "No mesh." << nl << endl;
|
hasRegionMesh[regioni] = true;
|
||||||
|
++nMeshChanged;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for any mesh changes
|
||||||
|
if (!nMeshChanged)
|
||||||
|
{
|
||||||
|
Info<< "No meshes" << nl << endl;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Info<< endl;
|
||||||
|
|
||||||
|
forAll(regionNames, regioni)
|
||||||
|
{
|
||||||
|
const word& regionName = regionNames[regioni];
|
||||||
|
const word& regionDir =
|
||||||
|
(
|
||||||
|
regionName == polyMesh::defaultRegion
|
||||||
|
? word::null
|
||||||
|
: regionName
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!hasRegionMesh[regioni])
|
||||||
|
{
|
||||||
|
Info<< "region=" << regionName << " (no mesh)" << nl << endl;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (regionNames.size() > 1)
|
||||||
|
{
|
||||||
|
Info<< "region=" << regionName << nl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Addressing from processor to reconstructed case
|
// Addressing from processor to reconstructed case
|
||||||
labelListList cellProcAddressing(nProcs);
|
labelListList cellProcAddressing(nProcs);
|
||||||
labelListList faceProcAddressing(nProcs);
|
labelListList faceProcAddressing(nProcs);
|
||||||
labelListList pointProcAddressing(nProcs);
|
labelListList pointProcAddressing(nProcs);
|
||||||
labelListList boundaryProcAddressing(nProcs);
|
labelListList boundProcAddressing(nProcs);
|
||||||
|
|
||||||
|
|
||||||
// Internal faces on the final reconstructed mesh
|
// Internal faces on the final reconstructed mesh
|
||||||
@ -756,10 +855,11 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
if (procMatch)
|
if (procMatch)
|
||||||
{
|
{
|
||||||
// Read point on individual processors to determine merge tolerance
|
// Read point on individual processors to determine
|
||||||
|
// merge tolerance
|
||||||
// (otherwise single cell domains might give problems)
|
// (otherwise single cell domains might give problems)
|
||||||
|
|
||||||
const boundBox bb = procBounds(args, databases, regionDir);
|
const boundBox bb = procBounds(databases, regionDir);
|
||||||
const scalar mergeDist = mergeTol*bb.mag();
|
const scalar mergeDist = mergeTol*bb.mag();
|
||||||
|
|
||||||
Info<< "Overall mesh bounding box : " << bb << nl
|
Info<< "Overall mesh bounding box : " << bb << nl
|
||||||
@ -769,7 +869,6 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
|
|
||||||
// Construct empty mesh.
|
// Construct empty mesh.
|
||||||
// fvMesh** masterMesh = new fvMesh*[nProcs];
|
|
||||||
PtrList<fvMesh> masterMesh(nProcs);
|
PtrList<fvMesh> masterMesh(nProcs);
|
||||||
|
|
||||||
for (label proci=0; proci<nProcs; proci++)
|
for (label proci=0; proci<nProcs; proci++)
|
||||||
@ -804,7 +903,7 @@ int main(int argc, char *argv[])
|
|||||||
cellProcAddressing[proci] = identity(meshToAdd.nCells());
|
cellProcAddressing[proci] = identity(meshToAdd.nCells());
|
||||||
faceProcAddressing[proci] = identity(meshToAdd.nFaces());
|
faceProcAddressing[proci] = identity(meshToAdd.nFaces());
|
||||||
pointProcAddressing[proci] = identity(meshToAdd.nPoints());
|
pointProcAddressing[proci] = identity(meshToAdd.nPoints());
|
||||||
boundaryProcAddressing[proci] =
|
boundProcAddressing[proci] =
|
||||||
identity(meshToAdd.boundaryMesh().size());
|
identity(meshToAdd.boundaryMesh().size());
|
||||||
|
|
||||||
// Find geometrically shared points/faces.
|
// Find geometrically shared points/faces.
|
||||||
@ -832,7 +931,7 @@ int main(int argc, char *argv[])
|
|||||||
renumber(map().addedCellMap(), cellProcAddressing[proci]);
|
renumber(map().addedCellMap(), cellProcAddressing[proci]);
|
||||||
renumber(map().addedFaceMap(), faceProcAddressing[proci]);
|
renumber(map().addedFaceMap(), faceProcAddressing[proci]);
|
||||||
renumber(map().addedPointMap(), pointProcAddressing[proci]);
|
renumber(map().addedPointMap(), pointProcAddressing[proci]);
|
||||||
renumber(map().addedPatchMap(), boundaryProcAddressing[proci]);
|
renumber(map().addedPatchMap(), boundProcAddressing[proci]);
|
||||||
}
|
}
|
||||||
for (label step=2; step<nProcs*2; step*=2)
|
for (label step=2; step<nProcs*2; step*=2)
|
||||||
{
|
{
|
||||||
@ -844,7 +943,8 @@ int main(int argc, char *argv[])
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Info<< "Merging mesh " << proci << " with " << next << endl;
|
Info<< "Merging mesh " << proci << " with "
|
||||||
|
<< next << endl;
|
||||||
|
|
||||||
// Find geometrically shared points/faces.
|
// Find geometrically shared points/faces.
|
||||||
autoPtr<faceCoupleInfo> couples = determineCoupledFaces
|
autoPtr<faceCoupleInfo> couples = determineCoupledFaces
|
||||||
@ -892,7 +992,7 @@ int main(int argc, char *argv[])
|
|||||||
renumber
|
renumber
|
||||||
(
|
(
|
||||||
map().oldPatchMap(),
|
map().oldPatchMap(),
|
||||||
boundaryProcAddressing[mergedI]
|
boundProcAddressing[mergedI]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -925,7 +1025,7 @@ int main(int argc, char *argv[])
|
|||||||
renumber
|
renumber
|
||||||
(
|
(
|
||||||
map().addedPatchMap(),
|
map().addedPatchMap(),
|
||||||
boundaryProcAddressing[addedI]
|
boundProcAddressing[addedI]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -943,17 +1043,32 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
// See if any points on the mastermesh have become connected
|
// See if any points on the mastermesh have become connected
|
||||||
// because of connections through processor meshes.
|
// because of connections through processor meshes.
|
||||||
mergeSharedPoints(mergeDist, masterMesh[0], pointProcAddressing);
|
mergeSharedPoints(mergeDist,masterMesh[0],pointProcAddressing);
|
||||||
|
|
||||||
// Save some properties on the reconstructed mesh
|
// Save some properties on the reconstructed mesh
|
||||||
masterInternalFaces = masterMesh[0].nInternalFaces();
|
masterInternalFaces = masterMesh[0].nInternalFaces();
|
||||||
masterOwner = masterMesh[0].faceOwner();
|
masterOwner = masterMesh[0].faceOwner();
|
||||||
|
|
||||||
|
|
||||||
|
if (writeAddrOnly)
|
||||||
|
{
|
||||||
|
Info<< nl
|
||||||
|
<< "Disabled writing of merged mesh (-addressing-only)"
|
||||||
|
<< nl << nl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// Write reconstructed mesh
|
// Write reconstructed mesh
|
||||||
writeMesh(masterMesh[0], cellProcAddressing);
|
writeMesh(masterMesh[0], cellProcAddressing);
|
||||||
if (writeCellDist)
|
if (writeCellDist)
|
||||||
{
|
{
|
||||||
writeDistribution(runTime, masterMesh[0], cellProcAddressing);
|
writeDistribution
|
||||||
|
(
|
||||||
|
runTime,
|
||||||
|
masterMesh[0],
|
||||||
|
cellProcAddressing
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1057,7 +1172,7 @@ int main(int argc, char *argv[])
|
|||||||
remoteFaceProc,
|
remoteFaceProc,
|
||||||
remoteBoundaryFace,
|
remoteBoundaryFace,
|
||||||
|
|
||||||
boundaryProcAddressing,
|
boundProcAddressing,
|
||||||
cellProcAddressing,
|
cellProcAddressing,
|
||||||
faceProcAddressing,
|
faceProcAddressing,
|
||||||
pointProcAddressing
|
pointProcAddressing
|
||||||
@ -1102,9 +1217,11 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
// Number of internal faces on the final reconstructed mesh
|
// Number of internal faces on the final reconstructed mesh
|
||||||
masterInternalFaces = masterMesh.nInternalFaces();
|
masterInternalFaces = masterMesh.nInternalFaces();
|
||||||
|
|
||||||
// Owner addressing on the final reconstructed mesh
|
// Owner addressing on the final reconstructed mesh
|
||||||
masterOwner = masterMesh.faceOwner();
|
masterOwner = masterMesh.faceOwner();
|
||||||
|
|
||||||
|
|
||||||
// Write reconstructed mesh
|
// Write reconstructed mesh
|
||||||
// Override:
|
// Override:
|
||||||
// - caseName
|
// - caseName
|
||||||
@ -1112,32 +1229,48 @@ int main(int argc, char *argv[])
|
|||||||
// so the resulting mesh goes to the correct location (even with
|
// so the resulting mesh goes to the correct location (even with
|
||||||
// collated). The better way of solving this is to construct
|
// collated). The better way of solving this is to construct
|
||||||
// (zero) mesh on the undecomposed runTime.
|
// (zero) mesh on the undecomposed runTime.
|
||||||
|
|
||||||
|
if (writeAddrOnly)
|
||||||
|
{
|
||||||
|
Info<< nl
|
||||||
|
<< "Disabled writing of merged mesh (-addressing-only)"
|
||||||
|
<< nl << nl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
Time& masterTime = const_cast<Time&>(masterMesh.time());
|
Time& masterTime = const_cast<Time&>(masterMesh.time());
|
||||||
|
|
||||||
const word oldCaseName = masterTime.caseName();
|
const word oldCaseName = masterTime.caseName();
|
||||||
masterTime.caseName() = runTime.caseName();
|
masterTime.caseName() = runTime.caseName();
|
||||||
const bool oldProcCase(masterTime.processorCase(false));
|
const bool oldProcCase(masterTime.processorCase(false));
|
||||||
|
|
||||||
|
// Write reconstructed mesh
|
||||||
writeMesh(masterMesh, cellProcAddressing);
|
writeMesh(masterMesh, cellProcAddressing);
|
||||||
if (writeCellDist)
|
if (writeCellDist)
|
||||||
{
|
{
|
||||||
writeDistribution(runTime, masterMesh, cellProcAddressing);
|
writeDistribution
|
||||||
|
(
|
||||||
|
runTime,
|
||||||
|
masterMesh,
|
||||||
|
cellProcAddressing
|
||||||
|
);
|
||||||
}
|
}
|
||||||
masterTime.caseName() = oldCaseName;
|
masterTime.caseName() = oldCaseName;
|
||||||
masterTime.processorCase(oldProcCase);
|
masterTime.processorCase(oldProcCase);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Write the addressing
|
// Write the addressing
|
||||||
|
|
||||||
Info<< "Reconstructing the addressing from the processor meshes"
|
Info<< "Reconstructing addressing from processor meshes"
|
||||||
<< " to the newly reconstructed mesh" << nl << endl;
|
<< " to the newly reconstructed mesh" << nl << endl;
|
||||||
|
|
||||||
forAll(databases, proci)
|
forAll(databases, proci)
|
||||||
{
|
{
|
||||||
Info<< "Reading processor " << proci << " mesh from "
|
Info<< "Processor " << proci << nl
|
||||||
<< databases[proci].caseName() << endl;
|
<< "Read processor mesh: "
|
||||||
|
<< (databases[proci].caseName()/regionDir) << endl;
|
||||||
|
|
||||||
polyMesh procMesh
|
polyMesh procMesh
|
||||||
(
|
(
|
||||||
@ -1157,13 +1290,13 @@ int main(int argc, char *argv[])
|
|||||||
cellProcAddressing[proci],
|
cellProcAddressing[proci],
|
||||||
faceProcAddressing[proci],
|
faceProcAddressing[proci],
|
||||||
pointProcAddressing[proci],
|
pointProcAddressing[proci],
|
||||||
boundaryProcAddressing[proci]
|
boundProcAddressing[proci]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Info<< "End\n" << endl;
|
||||||
Info<< "\nEnd\n" << endl;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user