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)
324 if (pointsInstance != procDb.timeName())
327 <<
"Your time was specified as " << procDb.timeName()
328 <<
" but there is no polyMesh/points in that time." <<
nl 329 <<
"(points file at " << pointsInstance <<
')' <<
nl 330 <<
"Please rerun with the correct time specified" 331 <<
" (through the -constant, -time or -latestTime " 332 <<
"(at your option)." 336 Info<<
"Reading points from " 338 <<
" for time = " << procDb.timeName()
366 void writeDistribution
389 forAll(cellProcAddressing, proci)
391 const labelList& pCells = cellProcAddressing[proci];
395 cellDecomposition.write();
397 Info<<
nl <<
"Wrote decomposition to " 398 << cellDecomposition.objectRelPath()
399 <<
" for use in manual decomposition." <<
endl;
427 forAll(cellDecomposition, celli)
429 cellDist[celli] = cellDecomposition[celli];
432 cellDist.correctBoundaryConditions();
435 Info<<
nl <<
"Wrote decomposition to " 436 << cellDist.objectRelPath()
437 <<
" (volScalarField) for visualization." 460 Info<<
nl <<
"Writing merged mesh to " 466 <<
"Failed writing polyMesh." 475 const label masterInternalFaces,
504 Info<<
"Writing addressing : " << outputDir <<
nl;
508 Info<<
" pointProcAddressing" <<
endl;
509 ioAddr.
rename(
"pointProcAddressing");
513 Info<<
" faceProcAddressing" <<
endl;
514 ioAddr.
rename(
"faceProcAddressing");
515 labelIOList faceProcAddr(ioAddr, faceProcAddressing);
519 forAll(faceProcAddr, procFacei)
521 const label masterFacei = faceProcAddr[procFacei];
525 !procMesh.isInternalFace(procFacei)
526 && masterFacei < masterInternalFaces
532 label procOwn = procMesh.faceOwner()[procFacei];
533 label masterOwn = masterOwner[masterFacei];
535 if (cellProcAddressing[procOwn] == masterOwn)
538 faceProcAddr[procFacei]++;
543 faceProcAddr[procFacei] = -1 - faceProcAddr[procFacei];
549 faceProcAddr[procFacei]++;
553 faceProcAddr.write();
557 Info<<
" cellProcAddressing" <<
endl;
558 ioAddr.
rename(
"cellProcAddressing");
563 Info<<
" boundaryProcAddressing" <<
endl;
564 ioAddr.
rename(
"boundaryProcAddressing");
574 "Merge individual processor meshes back into one master mesh.\n" 575 "Use if the original master mesh has been deleted or the processor meshes\n" 576 "have been modified (topology change).\n" 577 "This tool will write the resulting mesh to a new time step and construct\n" 578 "xxxxProcAddressing files in the processor meshes so reconstructPar can be\n" 579 "used to regenerate the fields on the master mesh.\n\n" 580 "Not well tested & use at your own risk!\n\n";
584 int main(
int argc,
char *argv[])
588 "Reconstruct a mesh using geometric/topological information only" 601 "Create procAddressing only without overwriting the mesh" 607 "The merge distance relative to the bounding box size (default 1e-7)" 612 "Do (slower) geometric matching on all boundary faces" 617 "Do matching on processor faces only" 622 "Write cell distribution as a labelList - for use with 'manual' " 623 "decomposition method or as a volScalarField for post-processing." 633 const bool fullMatch =
args.
found(
"fullMatch");
634 const bool procMatch =
args.
found(
"procMatch");
635 const bool writeCellDist =
args.
found(
"cellDist");
637 const bool writeAddrOnly =
args.
found(
"addressing-only");
639 const scalar mergeTol =
644 Info<<
"Use geometric matching on all boundary faces." <<
nl <<
endl;
648 Info<<
"Use geometric matching on correct procBoundaries only." <<
nl 649 <<
"This assumes a correct decomposition." <<
endl;
653 Info<<
"Merge assuming correct, fully matched procBoundaries." <<
nl 657 if (fullMatch || procMatch)
659 const scalar writeTol =
662 Info<<
"Merge tolerance : " << mergeTol <<
nl 663 <<
"Write tolerance : " << writeTol <<
endl;
668 && mergeTol < writeTol
672 <<
"Your current settings specify ASCII writing with " 674 <<
"Your merging tolerance (" << mergeTol <<
")" 675 <<
" is finer than this." <<
endl 676 <<
"Please change your writeFormat to binary" 677 <<
" or increase the writePrecision" <<
endl 678 <<
"or adjust the merge tolerance (-mergeTol)." 692 <<
"No regions specified or detected." 712 <<
"No processor* directories found" 719 Info<<
"Found " << nProcs <<
" processor directories" <<
endl;
722 Info<<
" Reading database " 745 databases[0].times(),
758 databases[proci].setTime(timeDirs[timei], timei);
764 label nMeshChanged = 0;
788 hasRegionMesh[regioni] =
true;
807 if (!hasRegionMesh[regioni])
827 label masterInternalFaces;
839 const scalar mergeDist = mergeTol*bb.
mag();
841 Info<<
"Overall mesh bounding box : " << bb <<
nl 842 <<
"Relative tolerance : " << mergeTol <<
nl 843 <<
"Absolute matching distance : " << mergeDist <<
nl 850 for (label proci=0; proci<nProcs; proci++)
882 boundProcAddressing[proci] =
907 renumber(map().addedCellMap(), cellProcAddressing[proci]);
908 renumber(map().addedFaceMap(), faceProcAddressing[proci]);
909 renumber(map().addedPointMap(), pointProcAddressing[proci]);
910 renumber(map().addedPatchMap(), boundProcAddressing[proci]);
912 for (label step=2; step<nProcs*2; step*=2)
914 for (label proci=0; proci<nProcs; proci+=step)
916 label next = proci + step/2;
922 Info<<
"Merging mesh " << proci <<
" with " 947 for (label mergedI=proci; mergedI<next; mergedI++)
952 cellProcAddressing[mergedI]
958 faceProcAddressing[mergedI]
964 pointProcAddressing[mergedI]
971 boundProcAddressing[mergedI]
979 addedI<
min(proci+step, nProcs);
985 map().addedCellMap(),
986 cellProcAddressing[addedI]
991 map().addedFaceMap(),
992 faceProcAddressing[addedI]
997 map().addedPointMap(),
998 pointProcAddressing[addedI]
1003 map().addedPatchMap(),
1004 boundProcAddressing[addedI]
1008 masterMesh.
set(next,
nullptr);
1012 for (label proci=0; proci<nProcs; proci++)
1014 Info<<
"Reading mesh to add from " 1015 << databases[proci].caseName()
1016 <<
" for time = " << databases[proci].timeName()
1022 mergeSharedPoints(mergeDist,masterMesh[0],pointProcAddressing);
1026 masterOwner = masterMesh[0].
faceOwner();
1032 <<
"Disabled writing of merged mesh (-addressing-only)" 1038 writeMesh(masterMesh[0], cellProcAddressing);
1054 for (label proci=0; proci<nProcs; proci++)
1110 const labelList& procFaces = localBoundaryFace[proci];
1111 remoteFaceStart[proci].
setSize(procFaces.
size(), 0);
1126 patchMap[proci].
setSize(nGlobalPatches);
1138 const labelList oldFaceOwner(fvMeshes[0].faceOwner());
1151 boundProcAddressing,
1164 const auto&
pp =
pbm[patchi];
1165 if (!isA<processorPolyPatch>(
pp) ||
pp.size())
1167 oldToNew[patchi] = newi++;
1170 const label nNonProcPatches = newi;
1175 if (oldToNew[patchi] == -1)
1177 oldToNew[patchi] = newi++;
1188 masterMeshPtr.
cref(fvMeshes[0]);
1192 const fvMesh& masterMesh = masterMeshPtr();
1212 <<
"Disabled writing of merged mesh (-addressing-only)" 1217 Time& masterTime =
const_cast<Time&
>(masterMesh.
time());
1224 writeMesh(masterMesh, cellProcAddressing);
1234 masterTime.
caseName() = oldCaseName;
1242 Info<<
"Reconstructing addressing from processor meshes" 1243 <<
" to the newly reconstructed mesh" <<
nl <<
endl;
1247 Info<<
"Processor " << proci <<
nl 1248 <<
"Read processor mesh: " 1263 masterInternalFaces,
1266 cellProcAddressing[proci],
1267 faceProcAddressing[proci],
1268 pointProcAddressing[proci],
1269 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 (not the indices) of 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)