82 static const scalar defaultMergeTol = 1
e-7;
92 const label masterMeshProcStart,
93 const label masterMeshProcEnd,
95 const label meshToAddProcStart,
96 const label meshToAddProcEnd,
98 const scalar mergeDist
101 if (fullMatch || masterMesh.
nCells() == 0)
126 forAll(masterPatches, patchi)
130 if (isA<processorPolyPatch>(
pp))
134 label proci=meshToAddProcStart;
135 proci<meshToAddProcEnd;
139 const string toProcString(
"to" +
name(proci));
141 pp.name().rfind(toProcString)
142 == (
pp.name().size()-toProcString.size())
145 label meshFacei =
pp.start();
148 masterFaces.append(meshFacei++);
156 masterFaces.shrink();
170 forAll(addPatches, patchi)
174 if (isA<processorPolyPatch>(
pp))
176 bool isConnected =
false;
180 label mergedProci=masterMeshProcStart;
181 !isConnected && (mergedProci < masterMeshProcEnd);
187 label proci = meshToAddProcStart;
188 proci < meshToAddProcEnd;
192 const word fromProcString
197 if (
pp.name() == fromProcString)
207 label meshFacei =
pp.start();
210 addFaces.append(meshFacei++);
235 const scalar mergeDist,
251 Info<<
"mergeSharedPoints : detected " << pointToMaster.size()
252 <<
" points that are to be merged." <<
endl;
273 forAll(pointProcAddressing, proci)
275 labelList& constructMap = pointProcAddressing[proci];
279 label oldPointi = constructMap[i];
282 label
newPointi = map().reversePointMap()[oldPointi];
295 <<
"Problem. oldPointi:" << oldPointi
313 for (
const Time& procDb : databases)
320 if (pointsInstance != procDb.timeName())
323 <<
"Your time was specified as " << procDb.timeName()
324 <<
" but there is no polyMesh/points in that time." <<
nl 325 <<
"(points file at " << pointsInstance <<
')' <<
nl 326 <<
"Please rerun with the correct time specified" 327 <<
" (through the -constant, -time or -latestTime " 328 <<
"(at your option)." 332 Info<<
"Reading points from " 334 <<
" for time = " << procDb.timeName()
358 void writeDistribution
381 forAll(cellProcAddressing, proci)
383 const labelList& pCells = cellProcAddressing[proci];
387 cellDecomposition.write();
389 Info<<
nl <<
"Wrote decomposition to " 390 << cellDecomposition.objectRelPath()
391 <<
" for use in manual decomposition." <<
endl;
419 forAll(cellDecomposition, celli)
421 cellDist[celli] = cellDecomposition[celli];
424 cellDist.correctBoundaryConditions();
427 Info<<
nl <<
"Wrote decomposition to " 428 << cellDist.objectRelPath()
429 <<
" (volScalarField) for visualization." 452 Info<<
nl <<
"Writing merged mesh to " 458 <<
"Failed writing polyMesh." 467 const label masterInternalFaces,
496 Info<<
"Writing addressing : " << outputDir <<
nl;
500 Info<<
" pointProcAddressing" <<
endl;
501 ioAddr.
rename(
"pointProcAddressing");
505 Info<<
" faceProcAddressing" <<
endl;
506 ioAddr.
rename(
"faceProcAddressing");
507 labelIOList faceProcAddr(ioAddr, faceProcAddressing);
511 forAll(faceProcAddr, procFacei)
513 const label masterFacei = faceProcAddr[procFacei];
517 !procMesh.isInternalFace(procFacei)
518 && masterFacei < masterInternalFaces
524 label procOwn = procMesh.faceOwner()[procFacei];
525 label masterOwn = masterOwner[masterFacei];
527 if (cellProcAddressing[procOwn] == masterOwn)
530 faceProcAddr[procFacei]++;
535 faceProcAddr[procFacei] = -1 - faceProcAddr[procFacei];
541 faceProcAddr[procFacei]++;
545 faceProcAddr.write();
549 Info<<
" cellProcAddressing" <<
endl;
550 ioAddr.
rename(
"cellProcAddressing");
555 Info<<
" boundaryProcAddressing" <<
endl;
556 ioAddr.
rename(
"boundaryProcAddressing");
566 "Merge individual processor meshes back into one master mesh.\n" 567 "Use if the original master mesh has been deleted or the processor meshes\n" 568 "have been modified (topology change).\n" 569 "This tool will write the resulting mesh to a new time step and construct\n" 570 "xxxxProcAddressing files in the processor meshes so reconstructPar can be\n" 571 "used to regenerate the fields on the master mesh.\n\n" 572 "Not well tested & use at your own risk!\n\n";
576 int main(
int argc,
char *argv[])
580 "Reconstruct a mesh using geometric/topological information only" 593 "Create procAddressing only without overwriting the mesh" 599 "The merge distance relative to the bounding box size (default 1e-7)" 604 "Do (slower) geometric matching on all boundary faces" 609 "Do matching on processor faces only" 614 "Write cell distribution as a labelList - for use with 'manual' " 615 "decomposition method or as a volScalarField for post-processing." 625 const bool fullMatch =
args.
found(
"fullMatch");
626 const bool procMatch =
args.
found(
"procMatch");
627 const bool writeCellDist =
args.
found(
"cellDist");
629 const bool writeAddrOnly =
args.
found(
"addressing-only");
631 const scalar mergeTol =
636 Info<<
"Use geometric matching on all boundary faces." <<
nl <<
endl;
640 Info<<
"Use geometric matching on correct procBoundaries only." <<
nl 641 <<
"This assumes a correct decomposition." <<
endl;
645 Info<<
"Merge assuming correct, fully matched procBoundaries." <<
nl 649 if (fullMatch || procMatch)
651 const scalar writeTol =
654 Info<<
"Merge tolerance : " << mergeTol <<
nl 655 <<
"Write tolerance : " << writeTol <<
endl;
660 && mergeTol < writeTol
664 <<
"Your current settings specify ASCII writing with " 666 <<
"Your merging tolerance (" << mergeTol <<
")" 667 <<
" is finer than this." <<
endl 668 <<
"Please change your writeFormat to binary" 669 <<
" or increase the writePrecision" <<
endl 670 <<
"or adjust the merge tolerance (-mergeTol)." 684 <<
"No regions specified or detected." 704 <<
"No processor* directories found" 711 Info<<
"Found " << nProcs <<
" processor directories" <<
endl;
714 Info<<
" Reading database " 737 databases[0].times(),
750 databases[proci].setTime(timeDirs[timei], timei);
756 label nMeshChanged = 0;
780 hasRegionMesh[regioni] =
true;
799 if (!hasRegionMesh[regioni])
819 label masterInternalFaces;
831 const scalar mergeDist = mergeTol*bb.
mag();
833 Info<<
"Overall mesh bounding box : " << bb <<
nl 834 <<
"Relative tolerance : " << mergeTol <<
nl 835 <<
"Absolute matching distance : " << mergeDist <<
nl 842 for (label proci=0; proci<nProcs; proci++)
874 boundProcAddressing[proci] =
899 renumber(map().addedCellMap(), cellProcAddressing[proci]);
900 renumber(map().addedFaceMap(), faceProcAddressing[proci]);
901 renumber(map().addedPointMap(), pointProcAddressing[proci]);
902 renumber(map().addedPatchMap(), boundProcAddressing[proci]);
904 for (label step=2; step<nProcs*2; step*=2)
906 for (label proci=0; proci<nProcs; proci+=step)
908 label next = proci + step/2;
914 Info<<
"Merging mesh " << proci <<
" with " 939 for (label mergedI=proci; mergedI<next; mergedI++)
944 cellProcAddressing[mergedI]
950 faceProcAddressing[mergedI]
956 pointProcAddressing[mergedI]
963 boundProcAddressing[mergedI]
971 addedI<
min(proci+step, nProcs);
977 map().addedCellMap(),
978 cellProcAddressing[addedI]
983 map().addedFaceMap(),
984 faceProcAddressing[addedI]
989 map().addedPointMap(),
990 pointProcAddressing[addedI]
995 map().addedPatchMap(),
996 boundProcAddressing[addedI]
1000 masterMesh.
set(next,
nullptr);
1004 for (label proci=0; proci<nProcs; proci++)
1006 Info<<
"Reading mesh to add from " 1007 << databases[proci].caseName()
1008 <<
" for time = " << databases[proci].timeName()
1014 mergeSharedPoints(mergeDist,masterMesh[0],pointProcAddressing);
1018 masterOwner = masterMesh[0].
faceOwner();
1024 <<
"Disabled writing of merged mesh (-addressing-only)" 1030 writeMesh(masterMesh[0], cellProcAddressing);
1046 for (label proci=0; proci<nProcs; proci++)
1102 const labelList& procFaces = localBoundaryFace[proci];
1103 remoteFaceStart[proci].
setSize(procFaces.
size(), 0);
1118 patchMap[proci].
setSize(nGlobalPatches);
1130 const labelList oldFaceOwner(fvMeshes[0].faceOwner());
1143 boundProcAddressing,
1156 const auto&
pp =
pbm[patchi];
1157 if (!isA<processorPolyPatch>(
pp) ||
pp.size())
1159 oldToNew[patchi] = newi++;
1162 const label nNonProcPatches = newi;
1167 if (oldToNew[patchi] == -1)
1169 oldToNew[patchi] = newi++;
1180 masterMeshPtr.
cref(fvMeshes[0]);
1184 const fvMesh& masterMesh = masterMeshPtr();
1204 <<
"Disabled writing of merged mesh (-addressing-only)" 1209 Time& masterTime =
const_cast<Time&
>(masterMesh.
time());
1216 writeMesh(masterMesh, cellProcAddressing);
1226 masterTime.
caseName() = oldCaseName;
1234 Info<<
"Reconstructing addressing from processor meshes" 1235 <<
" to the newly reconstructed mesh" <<
nl <<
endl;
1239 Info<<
"Processor " << proci <<
nl 1240 <<
"Read processor mesh: " 1255 masterInternalFaces,
1258 cellProcAddressing[proci],
1259 faceProcAddressing[proci],
1260 pointProcAddressing[proci],
1261 boundProcAddressing[proci]
static const word & zeroGradientType() noexcept
The type name for zeroGradient patch fields.
const polyBoundaryMesh & pbm
const Type & value() const noexcept
Return const reference to value.
static void addNote(const string ¬e)
Add extra notes for the usage information.
void size(const label n)
Older name for setAddressableSize.
fileName path() const
Return path = rootPath/caseName. Same as TimePaths::path()
Info<< "Creating field kinetic energy K\"<< endl;volScalarField K("K", 0.5 *magSqr(U));if(U.nOldTimes()){ volVectorField *Uold=&U.oldTime();volScalarField *Kold=&K.oldTime();*Kold==0.5 *magSqr(*Uold);while(Uold->nOldTimes()) { Uold=&Uold-> oldTime()
A class for handling file names.
errorManipArg< error, int > exit(error &err, const int errNo=1)
const fileName & facesInstance() const
Return the current instance directory for faces.
label nPoints() const noexcept
Number of mesh points.
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
const word & regionName() const
The mesh region name or word::null if polyMesh::defaultRegion.
IntListType renumber(const labelUList &oldToNew, const IntListType &input)
Renumber the values within a list.
const fileName & caseName() const noexcept
Return case name.
constexpr char nl
The newline '\n' character (0x0a)
bool empty() const noexcept
True if List is empty (ie, size() is zero)
UIndirectList< label > labelUIndList
UIndirectList of labels.
static word meshSubDir
Return the mesh sub-directory name (usually "polyMesh")
static word newName(const label myProcNo, const label neighbProcNo)
Return the name of a processorPolyPatch ("procBoundary..") constructed from the pair of processor IDs...
Ostream & endl(Ostream &os)
Add newline and flush stream.
fileName relativePath(const fileName &input, const bool caseTag=false) const
Return the input relative to the globalPath by stripping off a leading value of the globalPath...
static unsigned int defaultPrecision() noexcept
Return the default precision.
static void addBoolOption(const word &optName, const string &usage="", bool advanced=false)
Add a bool option to validOptions with usage information.
static void noParallel()
Remove the parallel options.
refPtr< fileOperation > fileHandler(std::nullptr_t)
Delete current file handler - forwards to fileOperation::handler()
A bounding box defined in terms of min/max extrema points.
Ignore writing from objectRegistry::writeObject()
const dimensionSet dimless
Dimensionless.
T getOrDefault(const word &optName, const T &deflt) const
Get a value from the named option if present, or return default.
const Time & time() const
Return the top-level database.
const T & cref() const
Return const reference to the object or to the contents of a (non-null) managed pointer.
label nFaces() const noexcept
Number of mesh faces.
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
A class for managing references or pointers (no reference counting)
instantList select(const instantList ×) const
Select a list of Time values that are within the ranges.
bool processorCase() const noexcept
True if this is a processor case.
bool allowFunctionObjects() const
The controlDict 'functions' entry is allowed to be used.
#define forAll(list, i)
Loop across all elements in list.
void write(vtk::formatter &fmt, const Type &val, const label n=1)
Component-wise write of a value (N times)
bool allowLibs() const
The controlDict 'libs' entry is allowed to be used. (eg, has not been disabled by the -no-libs option...
void add(const boundBox &bb)
Extend to include the second box.
static void removeFiles(const polyMesh &)
Helper: remove all sets files from mesh instance.
bool returnReduceAnd(const bool value, const label comm=UPstream::worldComm)
Perform logical (and) MPI Allreduce on a copy. Uses UPstream::reduceAnd.
const dimensionedScalar e
Elementary charge.
void setSize(const label n)
Alias for resize()
virtual void updateMesh(const mapPolyMesh &mpm)
Update mesh corresponding to the given map.
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
labelList identity(const label len, label start=0)
Return an identity map of the given length with (map[i] == i), works like std::iota() but returning a...
static void mergePoints(const polyMesh &, const Map< label > &pointToMaster, polyTopoChange &meshMod)
Helper: Merge points.
const polyBoundaryMesh & boundaryMesh() const noexcept
Return boundary mesh.
A class for handling words, derived from Foam::string.
const Time & time() const noexcept
Return time registry.
static word defaultRegion
Return the default region name.
scalar mag() const
The magnitude/length of the bounding box diagonal.
label size() const noexcept
The number of entries in the list.
Foam::PtrList< Foam::fvMesh > meshes(regionNames.size())
static autoPtr< mapAddedPolyMesh > add(fvMesh &mesh0, const fvMesh &mesh1, const faceCoupleInfo &coupleInfo, const bool validBoundary=true, const bool fullyMapped=false)
Inplace add mesh to fvMesh. Maps all stored fields. Returns map.
virtual const labelList & faceOwner() const
Return face owner.
static const word null
An empty word.
static void addOption(const word &optName, const string ¶m="", const string &usage="", bool advanced=false)
Add an option to validOptions with usage information.
virtual void setTime(const Time &t)
Reset the time and time-index to those of the given time.
label nInternalFaces() const noexcept
Number of internal faces.
label timeIndex() const noexcept
Return the current time index.
static word controlDictName
The default control dictionary name (normally "controlDict")
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
A list of pointers to objects of type <T>, without allocation/deallocation management of the pointers...
errorManip< error > abort(error &err)
const T * set(const label i) const
Return const pointer to element (can be nullptr), or nullptr for out-of-range access (ie...
const fileName & caseName() const noexcept
Return case name (parallel run) or global case (serial run)
static label procPatchPairs(const UPtrList< polyMesh > &meshes, List< DynamicList< label >> &localPatch, List< DynamicList< label >> &remoteMesh, List< DynamicList< label >> &remotePatch)
Helper: find pairs of processor patches. Return number of non-processor patches.
virtual bool write(const bool writeOnProc=true) const
Write mesh using IO settings from time.
A polyBoundaryMesh is a polyPatch list with additional search methods and registered IO...
static void addVerboseOption(const string &usage="", bool advanced=false)
Enable a 'verbose' bool option, with usage information.
static word timeName(const scalar t, const int precision=precision_)
Return a time name for the given scalar time value formatted with the given precision.
const word & constant() const noexcept
Return constant name.
const fileName & rootPath() const noexcept
Return root path.
const faceZoneMesh & faceZones() const noexcept
Return face zone mesh.
virtual void rename(const word &newName)
Rename.
fileName path() const
Return the full path to the (processor local) case.
dimensionedScalar pow(const dimensionedScalar &ds, const dimensionedScalar &expt)
const pointZoneMesh & pointZones() const noexcept
Return point zone mesh.
static void patchFacePairs(const UPtrList< polyMesh > &meshes, const List< DynamicList< label >> &localPatch, const List< DynamicList< label >> &remoteMesh, const List< DynamicList< label >> &remotePatch, labelListList &localBoundaryFace, labelListList &remoteFaceMesh, labelListList &remoteBoundaryFace)
Helper: expand list of coupled patches into pairs of coupled faces.
Foam::word regionName(args.getOrDefault< word >("region", Foam::polyMesh::defaultRegion))
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
label nCells() const noexcept
Number of mesh cells.
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers...
Mesh data needed to do the Finite Volume discretisation.
Direct mesh changes based on v1.3 polyTopoChange syntax.
fileName meshDir() const
Return the local mesh directory (dbDir()/meshSubDir)
const cellZoneMesh & cellZones() const noexcept
Return cell zone mesh.
messageStream Info
Information stream (stdout output on master, null elsewhere)
Pointer management similar to std::unique_ptr, with some additional methods and type checking...
Mesh consisting of general polyhedral cells.
IOstreamOption::streamFormat writeFormat() const noexcept
Get write stream format.
static autoPtr< T > New(Args &&... args)
Construct autoPtr with forwarding arguments.
A patch is a list of labels that address the faces in the global face list.
Foam::argList args(argc, argv)
A IOList wrapper for writing external data.
Defines the attributes of an object for which implicit objectRegistry management is supported...
A primitive field of type <T> with automated input and output.
static void writeMaps(Ostream &os, const word &key, const labelListList &maps)
static const word & regionName(const word ®ion)
The mesh region name or word::null if polyMesh::defaultRegion.
Do not request registration (bool: false)
static Map< label > findSharedPoints(const polyMesh &, const scalar mergeTol)
Find topologically and geometrically shared points.
bool found(const word &optName) const
Return true if the named option is found.
static void addOptions(const bool constant=true, const bool withZero=false)
Add timeSelector options to argList::validOptions.
bool set(const Key &key, const T &obj)
Copy assign a new entry, overwriting existing entries.
uindirectPrimitivePatch pp(UIndirectList< face >(mesh.faces(), faceLabels), mesh.points())
static constexpr const zero Zero
Global zero (0)