60 static const scalar defaultMergeTol = 1
e-7;
73 elems[i] = map[elems[i]];
89 const scalar mergeDist
92 if (fullMatch || masterMesh.
nCells() == 0)
112 const string toProcString(
"to" +
name(proci));
126 isA<processorPolyPatch>(pp)
128 pp.
name().rfind(toProcString)
129 == (pp.
name().size()-toProcString.size())
136 masterFaces.append(meshFacei++);
140 masterFaces.shrink();
158 if (isA<processorPolyPatch>(pp))
160 bool isConnected =
false;
162 for (
label mergedProci = 0; mergedProci < proci; mergedProci++)
164 const word fromProcString
169 if (pp.
name() == fromProcString)
181 addFaces.append(meshFacei++);
209 const scalar mergeDist,
225 Info<<
"mergeSharedPoints : detected " << pointToMaster.size()
226 <<
" points that are to be merged." <<
endl;
247 forAll(pointProcAddressing, proci)
249 labelList& constructMap = pointProcAddressing[proci];
253 label oldPointi = constructMap[i];
256 label newPointi = map().reversePointMap()[oldPointi];
260 constructMap[i] = -newPointi-2;
262 else if (newPointi >= 0)
269 <<
"Problem. oldPointi:" << oldPointi
283 const word& regionDir
292 databases[proci].findInstance
299 if (pointsInstance != databases[proci].
timeName())
302 <<
"Your time was specified as " << databases[proci].timeName()
303 <<
" but there is no polyMesh/points in that time." << endl
304 <<
"(there is a points file in " << pointsInstance
306 <<
"Please rerun with the correct time specified" 307 <<
" (through the -constant, -time or -latestTime " 308 <<
"(at your option)." 312 Info<<
"Reading points from " 313 << databases[proci].caseName()
314 <<
" for time = " << databases[proci].timeName()
322 databases[proci].findInstance
345 void writeCellDistance
369 forAll(cellProcAddressing, proci)
371 const labelList& pCells = cellProcAddressing[proci];
375 cellDecomposition.write();
377 Info<<
nl <<
"Wrote decomposition to " 378 << cellDecomposition.objectPath()
379 <<
" for use in manual decomposition." <<
endl;
385 const scalar oldTime = runTime.
value();
389 runTime.
setTime(0, oldIndex+1);
404 extrapolatedCalculatedFvPatchScalarField::typeName
407 forAll(cellDecomposition, celli)
409 cellDist[celli] = cellDecomposition[celli];
411 cellDist.correctBoundaryConditions();
415 Info<<
nl <<
"Wrote decomposition as volScalarField to " 416 << cellDist.name() <<
" for use in postprocessing." 420 runTime.
setTime(oldTime, oldIndex);
425 int main(
int argc,
char *argv[])
429 "reconstruct a mesh using geometric information only" 440 "specify the merge distance relative to the bounding box size " 446 "do (slower) geometric matching on all boundary faces" 451 "write cell distribution as a labelList - for use with 'manual' " 452 "decomposition method or as a volScalarField for post-processing." 459 Info<<
"This is an experimental tool which tries to merge" 460 <<
" individual processor" <<
nl 461 <<
"meshes back into one master mesh. Use it if the original" 462 <<
" master mesh has" <<
nl 463 <<
"been deleted or if the processor meshes have been modified" 464 <<
" (topology change)." <<
nl 465 <<
"This tool will write the resulting mesh to a new time step" 466 <<
" and construct" <<
nl 467 <<
"xxxxProcAddressing files in the processor meshes so" 468 <<
" reconstructPar can be" <<
nl 469 <<
"used to regenerate the fields on the master mesh." <<
nl 471 <<
"Not well tested & use at your own risk!" <<
nl 485 Info<<
"Operating on region " << regionName <<
nl <<
endl;
488 scalar mergeTol = defaultMergeTol;
493 Info<<
"Merge tolerance : " << mergeTol <<
nl 494 <<
"Write tolerance : " << writeTol <<
endl;
499 <<
"Your current settings specify ASCII writing with " 501 <<
"Your merging tolerance (" << mergeTol <<
") is finer than this." 503 <<
"Please change your writeFormat to binary" 504 <<
" or increase the writePrecision" << endl
505 <<
"or adjust the merge tolerance (-mergeTol)." 510 const bool fullMatch = args.
optionFound(
"fullMatch");
514 Info<<
"Doing geometric matching on all boundary faces." <<
nl <<
endl;
518 Info<<
"Doing geometric matching on correct procBoundaries only." 519 <<
nl <<
"This assumes a correct decomposition." <<
endl;
540 Info<<
"Found " << nProcs <<
" processor directories" <<
nl <<
endl;
548 Info<<
"Reading database " 568 databases[0].times(),
576 runTime.
setTime(timeDirs[timeI], timeI);
583 databases[proci].setTime(timeDirs[timeI], timeI);
588 /databases[0].timeName()
592 if (!
isFile(meshPath/
"faces"))
602 const boundBox bb = procBounds(args, databases, regionDir);
603 const scalar mergeDist = mergeTol*bb.
mag();
605 Info<<
"Overall mesh bounding box : " << bb <<
nl 606 <<
"Relative tolerance : " << mergeTol <<
nl 607 <<
"Absolute matching distance : " << mergeDist <<
nl 618 label masterInternalFaces;
625 Info<<
"Constructing empty mesh to add to." <<
nl <<
endl;
640 for (
label proci = 0; proci < nProcs; proci++)
642 Info<<
"Reading mesh to add from " 643 << databases[proci].caseName()
644 <<
" for time = " << databases[proci].timeName()
661 boundaryProcAddressing[proci] =
690 for (
label mergedI = 0; mergedI < proci; mergedI++)
692 renumber(map().oldCellMap(), cellProcAddressing[mergedI]);
693 renumber(map().oldFaceMap(), faceProcAddressing[mergedI]);
694 renumber(map().oldPointMap(), pointProcAddressing[mergedI]);
699 boundaryProcAddressing[mergedI]
704 renumber(map().addedCellMap(), cellProcAddressing[proci]);
705 renumber(map().addedFaceMap(), faceProcAddressing[proci]);
706 renumber(map().addedPointMap(), pointProcAddressing[proci]);
707 renumber(map().addedPatchMap(), boundaryProcAddressing[proci]);
714 mergeSharedPoints(mergeDist, masterMesh, pointProcAddressing);
721 Info<<
"\nWriting merged mesh to " 725 if (!masterMesh.
write())
728 <<
"Failed writing polyMesh." 734 writeCellDistance(runTime, masterMesh, cellProcAddressing);
741 Info<<
"Reconstructing the addressing from the processor meshes" 742 <<
" to the newly reconstructed mesh" <<
nl <<
endl;
746 Info<<
"Reading processor " << proci <<
" mesh from " 747 << databases[proci].caseName() <<
endl;
762 Info<<
"Writing pointProcAddressing to " 763 << databases[proci].caseName()
764 /procMesh.facesInstance()
772 "pointProcAddressing",
773 procMesh.facesInstance(),
780 pointProcAddressing[proci]
786 Info<<
"Writing faceProcAddressing to " 787 << databases[proci].caseName()
788 /procMesh.facesInstance()
796 "faceProcAddressing",
797 procMesh.facesInstance(),
804 faceProcAddressing[proci]
809 forAll(faceProcAddr, procFacei)
811 label masterFacei = faceProcAddr[procFacei];
815 !procMesh.isInternalFace(procFacei)
816 && masterFacei < masterInternalFaces
822 label procOwn = procMesh.faceOwner()[procFacei];
823 label masterOwn = masterOwner[masterFacei];
825 if (cellProcAddressing[proci][procOwn] == masterOwn)
828 faceProcAddr[procFacei]++;
833 faceProcAddr[procFacei] =
834 -1 - faceProcAddr[procFacei];
840 faceProcAddr[procFacei]++;
844 faceProcAddr.write();
849 Info<<
"Writing cellProcAddressing to " 850 << databases[proci].caseName()
851 /procMesh.facesInstance()
859 "cellProcAddressing",
860 procMesh.facesInstance(),
867 cellProcAddressing[proci]
874 Info<<
"Writing boundaryProcAddressing to " 875 << databases[proci].caseName()
876 /procMesh.facesInstance()
884 "boundaryProcAddressing",
885 procMesh.facesInstance(),
892 boundaryProcAddressing[proci]
label timeIndex() const
Return current time index.
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.
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
A class for handling file names.
errorManipArg< error, int > exit(error &err, const int errNo=1)
const double e
Elementary charge.
const point & min() const
Minimum describing the bounding box.
const fileName & facesInstance() const
Return the current instance directory for faces.
dimensioned< Type > max(const dimensioned< Type > &, const dimensioned< Type > &)
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
PtrList< labelIOList > & faceProcAddressing
static word meshSubDir
Return the mesh sub-directory name (usually "polyMesh")
static unsigned int defaultPrecision()
Return the default precision.
bool optionReadIfPresent(const word &opt, T &) const
Read a value from the named option if present.
bool isFile(const fileName &, const bool checkGzip=true)
Does the name exist as a FILE in the file system?
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.
const point & max() const
Maximum describing the bounding box.
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.
const Type & value() const
Return const reference to value.
instantList select(const instantList &) const
Select a list of Time values that are within the ranges.
bool isDir(const fileName &)
Does the name exist as a DIRECTORY in the file system?
static word timeName(const scalar, const int precision=precision_)
Return time name of given scalar time.
const fileName & rootPath() const
Return root path.
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
Container for information needed to couple to meshes. When constructed from two meshes and a geometri...
const fileName & caseName() const
Return case name (parallel run) or global case (serial run)
scalar mag() const
The magnitude of the bounding box span.
vectorField pointField
pointField is a vectorField.
label start() const
Return start label of this patch in the polyMesh face list.
bool optionFound(const word &opt) const
Return true if the named option is found.
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. ...
bool set(const label) const
Is element set.
static void addOption(const word &opt, const string ¶m="", const string &usage="")
Add to an option to validOptions with usage information.
static const word null
An empty word.
const word & constant() const
Return constant name.
virtual void setTime(const Time &)
Reset the time and time-index to those of the given time.
IOstream::streamFormat writeFormat() const
Default write format.
const word & name() const
Return name.
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.
dimensioned< Type > min(const dimensioned< Type > &, const dimensioned< Type > &)
word name(const complex &)
Return a string representation of a complex.
dimensionedScalar pow(const dimensionedScalar &ds, const dimensionedScalar &expt)
static const boundBox invertedBox
A very large inverted boundBox: min/max == +/- VGREAT.
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.
virtual bool write() const
Write using setting from DB.
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.
static void addNote(const string &)
Add extra notes for the usage information.
virtual const labelList & faceOwner() const
Return face owner.
A patch is a list of labels that address the faces in the global face list.
fileName path() const
Return path.
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
label nInternalFaces() const
virtual bool write() const
Write mesh using IO settings from time.
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.
label size() const
Return the number of elements in the UPtrList.