60 static const scalar defaultMergeTol = 1
e-7;
73 elems[i] = map[elems[i]];
86 const label masterMeshProcStart,
87 const label masterMeshProcEnd,
89 const label meshToAddProcStart,
90 const label meshToAddProcEnd,
92 const scalar mergeDist
95 if (fullMatch || masterMesh.
nCells() == 0)
127 if (isA<processorPolyPatch>(pp))
131 label proci=meshToAddProcStart;
132 proci<meshToAddProcEnd;
136 const string toProcString(
"to" +
name(proci));
138 pp.
name().rfind(toProcString)
139 == (pp.
name().size()-toProcString.size())
145 masterFaces.append(meshFacei++);
153 masterFaces.shrink();
171 if (isA<processorPolyPatch>(pp))
173 bool isConnected =
false;
177 label mergedProci=masterMeshProcStart;
178 !isConnected && (mergedProci < masterMeshProcEnd);
184 label proci = meshToAddProcStart;
185 proci < meshToAddProcEnd;
189 const word fromProcString
194 if (pp.
name() == fromProcString)
207 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];
286 constructMap[i] = -newPointi-2;
288 else if (newPointi >= 0)
295 <<
"Problem. oldPointi:" << oldPointi
309 const word& regionDir
318 databases[proci].findInstance
325 if (pointsInstance != databases[proci].
timeName())
328 <<
"Your time was specified as " << databases[proci].timeName()
329 <<
" but there is no polyMesh/points in that time." << endl
330 <<
"(there is a points file in " << pointsInstance
332 <<
"Please rerun with the correct time specified" 333 <<
" (through the -constant, -time or -latestTime " 334 <<
"(at your option)." 338 Info<<
"Reading points from " 339 << databases[proci].caseName()
340 <<
" for time = " << databases[proci].timeName()
348 databases[proci].findInstance
371 void writeCellDistance
395 forAll(cellProcAddressing, proci)
397 const labelList& pCells = cellProcAddressing[proci];
401 cellDecomposition.write();
403 Info<<
nl <<
"Wrote decomposition to " 404 << cellDecomposition.objectPath()
405 <<
" for use in manual decomposition." <<
endl;
411 const scalar oldTime = runTime.
value();
415 runTime.
setTime(0, oldIndex+1);
430 extrapolatedCalculatedFvPatchScalarField::typeName
433 forAll(cellDecomposition, celli)
435 cellDist[celli] = cellDecomposition[celli];
437 cellDist.correctBoundaryConditions();
441 Info<<
nl <<
"Wrote decomposition as volScalarField to " 442 << cellDist.name() <<
" for use in postprocessing." 446 runTime.
setTime(oldTime, oldIndex);
451 int main(
int argc,
char *argv[])
455 "reconstruct a mesh using geometric information only" 466 "specify the merge distance relative to the bounding box size " 472 "do (slower) geometric matching on all boundary faces" 477 "write cell distribution as a labelList - for use with 'manual' " 478 "decomposition method or as a volScalarField for post-processing." 485 Info<<
"This is an experimental tool which tries to merge" 486 <<
" individual processor" <<
nl 487 <<
"meshes back into one master mesh. Use it if the original" 488 <<
" master mesh has" <<
nl 489 <<
"been deleted or if the processor meshes have been modified" 490 <<
" (topology change)." <<
nl 491 <<
"This tool will write the resulting mesh to a new time step" 492 <<
" and construct" <<
nl 493 <<
"xxxxProcAddressing files in the processor meshes so" 494 <<
" reconstructPar can be" <<
nl 495 <<
"used to regenerate the fields on the master mesh." <<
nl 497 <<
"Not well tested & use at your own risk!" <<
nl 511 Info<<
"Operating on region " << regionName <<
nl <<
endl;
514 scalar mergeTol = defaultMergeTol;
519 Info<<
"Merge tolerance : " << mergeTol <<
nl 520 <<
"Write tolerance : " << writeTol <<
endl;
525 <<
"Your current settings specify ASCII writing with " 527 <<
"Your merging tolerance (" << mergeTol <<
") is finer than this." 529 <<
"Please change your writeFormat to binary" 530 <<
" or increase the writePrecision" << endl
531 <<
"or adjust the merge tolerance (-mergeTol)." 536 const bool fullMatch = args.
optionFound(
"fullMatch");
540 Info<<
"Doing geometric matching on all boundary faces." <<
nl <<
endl;
544 Info<<
"Doing geometric matching on correct procBoundaries only." 545 <<
nl <<
"This assumes a correct decomposition." <<
endl;
553 Info<<
"Found " << nProcs <<
" processor directories" <<
nl <<
endl;
561 Info<<
"Reading database " 581 databases[0].times(),
589 runTime.
setTime(timeDirs[timeI], timeI);
596 databases[proci].setTime(timeDirs[timeI], timeI);
623 const boundBox bb = procBounds(args, databases, regionDir);
624 const scalar mergeDist = mergeTol*bb.
mag();
626 Info<<
"Overall mesh bounding box : " << bb <<
nl 627 <<
"Relative tolerance : " << mergeTol <<
nl 628 <<
"Absolute matching distance : " << mergeDist <<
nl 639 label masterInternalFaces;
649 for (
label proci=0; proci<nProcs; proci++)
683 boundaryProcAddressing[proci] =
708 renumber(map().addedCellMap(), cellProcAddressing[proci]);
709 renumber(map().addedFaceMap(), faceProcAddressing[proci]);
710 renumber(map().addedPointMap(), pointProcAddressing[proci]);
711 renumber(map().addedPatchMap(), boundaryProcAddressing[proci]);
713 for (
label step=2; step<nProcs*2; step*=2)
715 for (
label proci=0; proci<nProcs; proci+=step)
717 label next = proci + step/2;
723 Info<<
"Merging mesh " << proci <<
" with " << next <<
endl;
747 for (
label mergedI=proci; mergedI<next; mergedI++)
752 cellProcAddressing[mergedI]
758 faceProcAddressing[mergedI]
764 pointProcAddressing[mergedI]
771 boundaryProcAddressing[mergedI]
779 addedI<
min(proci+step, nProcs);
785 map().addedCellMap(),
786 cellProcAddressing[addedI]
791 map().addedFaceMap(),
792 faceProcAddressing[addedI]
797 map().addedPointMap(),
798 pointProcAddressing[addedI]
803 map().addedPatchMap(),
804 boundaryProcAddressing[addedI]
808 masterMesh.
set(next,
nullptr);
812 for (
label proci=0; proci<nProcs; proci++)
814 Info<<
"Reading mesh to add from " 815 << databases[proci].caseName()
816 <<
" for time = " << databases[proci].timeName()
822 mergeSharedPoints(mergeDist, masterMesh[0], pointProcAddressing);
829 Info<<
"\nWriting merged mesh to " 833 if (!masterMesh[0].
write())
836 <<
"Failed writing polyMesh." 854 Info<<
"Reconstructing the addressing from the processor meshes" 855 <<
" to the newly reconstructed mesh" <<
nl <<
endl;
859 Info<<
"Reading processor " << proci <<
" mesh from " 860 << databases[proci].caseName() <<
endl;
875 Info<<
"Writing pointProcAddressing to " 876 << databases[proci].caseName()
877 /procMesh.facesInstance()
885 "pointProcAddressing",
886 procMesh.facesInstance(),
893 pointProcAddressing[proci]
899 Info<<
"Writing faceProcAddressing to " 900 << databases[proci].caseName()
901 /procMesh.facesInstance()
909 "faceProcAddressing",
910 procMesh.facesInstance(),
917 faceProcAddressing[proci]
922 forAll(faceProcAddr, procFacei)
924 const label masterFacei = faceProcAddr[procFacei];
928 !procMesh.isInternalFace(procFacei)
929 && masterFacei < masterInternalFaces
935 label procOwn = procMesh.faceOwner()[procFacei];
936 label masterOwn = masterOwner[masterFacei];
938 if (cellProcAddressing[proci][procOwn] == masterOwn)
941 faceProcAddr[procFacei]++;
946 faceProcAddr[procFacei] =
947 -1 - faceProcAddr[procFacei];
953 faceProcAddr[procFacei]++;
957 faceProcAddr.write();
962 Info<<
"Writing cellProcAddressing to " 963 << databases[proci].caseName()
964 /procMesh.facesInstance()
972 "cellProcAddressing",
973 procMesh.facesInstance(),
980 cellProcAddressing[proci]
987 Info<<
"Writing boundaryProcAddressing to " 988 << databases[proci].caseName()
989 /procMesh.facesInstance()
997 "boundaryProcAddressing",
998 procMesh.facesInstance(),
1005 boundaryProcAddressing[proci]
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
ListType renumber(const labelUList &oldToNew, const ListType &)
Renumber the values (not the indices) of a list.
#define forAll(list, i)
Loop across all elements in list.
fileName path() const
Return path.
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
const word & name() const
Return name.
A class for handling file names.
bool set(const label) const
Is element set.
errorManipArg< error, int > exit(error &err, const int errNo=1)
const fileName & facesInstance() const
Return the current instance directory for faces.
const double e
Elementary charge.
dimensioned< Type > max(const dimensioned< Type > &, const dimensioned< Type > &)
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
label nInternalFaces() const
const fileName & rootPath() const
Return root path.
PtrList< labelIOList > & faceProcAddressing
static word meshSubDir
Return the mesh sub-directory name (usually "polyMesh")
static unsigned int defaultPrecision()
Return the default precision.
static word defaultRegion
Return the default region name.
static word newName(const label myProcNo, const label neighbProcNo)
Return the name of a processorPolyPatch.
Ostream & endl(Ostream &os)
Add newline and flush stream.
bool optionFound(const word &opt) const
Return true if the named option is found.
static void noParallel()
Remove the parallel options.
labelList identity(const label len)
Create identity map (map[i] == i) of given length.
A bounding box defined in terms of the points at its extremities.
Xfer< T > xferCopy(const T &)
Construct by copying the contents of the arg.
static word timeName(const scalar, const int precision=precision_)
Return time name of given scalar time.
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
bool optionReadIfPresent(const word &opt, T &) const
Read a value from the named option if present.
Container for information needed to couple to meshes. When constructed from two meshes and a geometri...
vectorField pointField
pointField is a vectorField.
static void mergePoints(const polyMesh &, const Map< label > &pointToMaster, polyTopoChange &meshMod)
Helper: Merge points.
virtual void updateMesh(const mapPolyMesh &mpm)
Update the mesh corresponding to given map.
A class for handling words, derived from string.
Extract command arguments and options from the supplied argc and argv parameters. ...
scalar mag() const
The magnitude of the bounding box span.
const word & constant() const
Return constant name.
static void addOption(const word &opt, const string ¶m="", const string &usage="")
Add to an option to validOptions with usage information.
virtual const labelList & faceOwner() const
Return face owner.
const Type & value() const
Return const reference to value.
static const word null
An empty word.
virtual void setTime(const Time &)
Reset the time and time-index to those of the given time.
const fileOperation & fileHandler()
Get current file handler.
static word controlDictName
The default control dictionary name (normally "controlDict")
errorManip< error > abort(error &err)
static autoPtr< mapAddedPolyMesh > add(fvMesh &mesh0, const fvMesh &mesh1, const faceCoupleInfo &coupleInfo, const bool validBoundary=true)
Inplace add mesh to fvMesh. Maps all stored fields. Returns map.
instantList select(const instantList &) const
Select a list of Time values that are within the ranges.
const fileName & caseName() const
Return case name (parallel run) or global case (serial run)
IOstream::streamFormat writeFormat() const
Default write format.
dimensioned< Type > min(const dimensioned< Type > &, const dimensioned< Type > &)
word name(const complex &)
Return a string representation of a complex.
fileName path() const
Return the path to the caseName.
label size() const
Return the number of elements in the UPtrList.
dimensionedScalar pow(const dimensionedScalar &ds, const dimensionedScalar &expt)
const point & max() const
Maximum describing the bounding box.
bool set(const Key &, const T &newElmt)
Assign a new hashedEntry, overwriting existing entries.
static const boundBox invertedBox
A very large inverted boundBox: min/max == +/- VGREAT.
label timeIndex() const
Return current time index.
virtual label nProcs(const fileName &dir, const fileName &local="") const
Get number of processor directories/results. Used for e.g.
const dimensionSet dimless(0, 0, 0, 0, 0, 0, 0)
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
A templated 1D list of pointers to objects of type <T>, where the size of the array is known and used...
Mesh data needed to do the Finite Volume discretisation.
A List with indirect addressing.
Direct mesh changes based on v1.3 polyTopoChange syntax.
label start() const
Return start label of this patch in the polyMesh face list.
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
An auto-pointer similar to the STL auto_ptr but with automatic casting to a reference to the type and...
Mesh consisting of general polyhedral cells.
static void addBoolOption(const word &opt, const string &usage="")
Add to a bool option to validOptions with usage information.
const point & min() const
Minimum describing the bounding box.
static void addNote(const string &)
Add extra notes for the usage information.
A patch is a list of labels that address the faces in the global face list.
virtual bool write(const bool valid=true) const
Write using setting from DB.
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
A primitive field of type <T> with automated input and output.
List< cell > cellList
list of cells
static Map< label > findSharedPoints(const polyMesh &, const scalar mergeTol)
Find topologically and geometrically shared points.
static void addOptions(const bool constant=true, const bool withZero=false)
Add the options handled by timeSelector to argList::validOptions.
IOList< label > labelIOList
Label container classes.