surfaceRedistributePar.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2016 OpenFOAM Foundation
9  Copyright (C) 2015-2018 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 Application
28  surfaceRedistributePar
29 
30 Group
31  grpSurfaceUtilities
32 
33 Description
34  (Re)distribution of triSurface. Either takes an undecomposed surface
35  or an already decomposed surface and redistributes it so that each
36  processor has all triangles that overlap its mesh.
37 
38 Note
39  - best decomposition option is hierarchical since it guarantees
40  square decompositions.
41  - triangles might be present on multiple processors.
42  - merging uses geometric tolerance so take care with writing precision.
43 
44 \*---------------------------------------------------------------------------*/
45 
46 #include "argList.H"
47 #include "Time.H"
48 #include "polyMesh.H"
50 #include "mapDistribute.H"
51 #include "localIOdictionary.H"
52 #include "decompositionModel.H"
53 
54 using namespace Foam;
55 
56 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
57 
58 // Print on master all the per-processor surface stats.
59 void writeProcStats
60 (
61  const triSurface& s,
63 )
64 {
65  // Determine surface bounding boxes, faces, points
67  {
68  surfBb[Pstream::myProcNo()] = treeBoundBox(s.points());
69  Pstream::gatherList(surfBb);
70  Pstream::scatterList(surfBb);
71  }
72 
74  nPoints[Pstream::myProcNo()] = s.points().size();
77 
78  labelList nFaces(Pstream::nProcs());
79  nFaces[Pstream::myProcNo()] = s.size();
80  Pstream::gatherList(nFaces);
81  Pstream::scatterList(nFaces);
82 
83  forAll(surfBb, proci)
84  {
85  Info<< "processor" << proci << nl;
86 
87  const List<treeBoundBox>& bbs = meshBb[proci];
88  if (bbs.size())
89  {
90  Info<< "\tMesh bounds : " << bbs[0] << nl;
91  for (label i = 1; i < bbs.size(); i++)
92  {
93  Info<< "\t " << bbs[i]<< nl;
94  }
95  }
96  Info<< "\tSurface bounding box : " << surfBb[proci] << nl
97  << "\tTriangles : " << nFaces[proci] << nl
98  << "\tVertices : " << nPoints[proci]
99  << endl;
100  }
101  Info<< endl;
102 }
103 
104 
105 
106 int main(int argc, char *argv[])
107 {
109  (
110  "Redistribute a triSurface."
111  " The specified surface must be located in the constant/triSurface"
112  " directory"
113  );
114 
115  argList::addArgument("triSurfaceMesh");
116  argList::addArgument("distributionType");
118  (
119  "keepNonMapped",
120  "Preserve surface outside of mesh bounds"
121  );
122 
123  #include "setRootCase.H"
124  #include "createTime.H"
126 
127  const fileName surfFileName = args[1];
128  const word distTypeName = args[2];
129  const label distType =
131 
132  Info<< "Reading surface from " << surfFileName << nl << nl
133  << "Using distribution method "
134  << distTypeName << nl << endl;
135 
136  const bool keepNonMapped = args.found("keepNonMapped");
137 
138  if (keepNonMapped)
139  {
140  Info<< "Preserving surface outside of mesh bounds." << nl << endl;
141  }
142  else
143  {
144  Info<< "Removing surface outside of mesh bounds." << nl << endl;
145  }
146 
147 
148  if (!Pstream::parRun())
149  {
151  << "Please run this program on the decomposed case."
152  << " It will read surface " << surfFileName
153  << " and decompose it such that it overlaps the mesh bounding box."
154  << exit(FatalError);
155  }
156 
157 
158  Random rndGen(653213);
159 
160  // For independent decomposition, ensure that distributedTriSurfaceMesh
161  // can find the alternative decomposeParDict specified via the
162  // -decomposeParDict option.
164  {
165  // Ensure demand-driven decompositionMethod finds alternative
166  // decomposeParDict location properly.
167 
168  IOdictionary* dictPtr = new IOdictionary
169  (
171  (
172  IOobject
173  (
175  runTime.system(),
176  runTime,
179  ),
180  args.getOrDefault<fileName>("decomposeParDict", "")
181  )
182  );
183 
184  // Store it on the object registry, but to be found it must also
185  // have the expected "decomposeParDict" name.
186 
188  runTime.store(dictPtr);
189  }
190 
191  // Determine mesh bounding boxes:
193  if (distType == distributedTriSurfaceMesh::FOLLOW)
194  {
195  #include "createPolyMesh.H"
196 
198  (
199  1,
201  (
202  boundBox(mesh.points(), false)
203  ).extend(rndGen, 1e-3)
204  );
207  }
208 
209  IOobject io
210  (
211  surfFileName, // name
212  //runTime.findInstance("triSurface", surfFileName), // instance
213  runTime.constant(), // instance
214  "triSurface", // local
215  runTime, // registry
218  );
219 
220  // Look for file (using searchableSurface rules)
221  const fileName actualPath(typeFilePath<searchableSurface>(io));
222  fileName localPath(actualPath);
223  localPath.replace(runTime.rootPath() + '/', "");
224 
225 
227 
228  if (actualPath == io.objectPath())
229  {
230  Info<< "Loading local (decomposed) surface " << localPath << nl <<endl;
231  surfMeshPtr.reset(new distributedTriSurfaceMesh(io));
232  }
233  else
234  {
235  Info<< "Loading undecomposed surface " << localPath
236  << " on master only" << endl;
237 
238  triSurface s;
239  List<treeBoundBox> bbs;
240  if (Pstream::master())
241  {
242  // Actually load the surface
243  const bool oldParRun = Pstream::parRun();
244  Pstream::parRun() = false;
245  triSurfaceMesh surf(io);
246  Pstream::parRun() = oldParRun;
247  s = surf;
249  }
250  else
251  {
253  }
254 
256  dict.add("distributionType", distTypeName);
257  dict.add("mergeDistance", SMALL);
258  dict.add("bounds", bbs);
259 
260  // Scatter patch information
261  Pstream::scatter(s.patches());
262 
263  // Construct distributedTrisurfaceMesh from components
264  IOobject notReadIO(io);
265  notReadIO.readOpt() = IOobject::NO_READ;
266  surfMeshPtr.reset(new distributedTriSurfaceMesh(notReadIO, s, dict));
267  }
268 
269  distributedTriSurfaceMesh& surfMesh = surfMeshPtr();
270 
271 
272  // Write per-processor stats
273  Info<< "Before redistribution:" << endl;
274  writeProcStats(surfMesh, meshBb);
275 
276 
277  // Do redistribution
278  Info<< "Redistributing surface" << nl << endl;
280  autoPtr<mapDistribute> pointMap;
281  surfMesh.distribute
282  (
284  keepNonMapped,
285  faceMap,
286  pointMap
287  );
288  faceMap.clear();
289  pointMap.clear();
290 
291  Info<< endl;
292 
293 
294  // Write per-processor stats
295  Info<< "After redistribution:" << endl;
296  writeProcStats(surfMesh, meshBb);
297 
298 
299  Info<< "Writing surface." << nl << endl;
300  surfMesh.objectRegistry::write();
301 
302  Info<< "End\n" << endl;
303 
304  return 0;
305 }
306 
307 
308 // ************************************************************************* //
Foam::IOobject::NO_WRITE
Definition: IOobject.H:130
Foam::IOdictionary
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
Definition: IOdictionary.H:54
runTime
engineTime & runTime
Definition: createEngineTime.H:13
Foam::autoPtr::reset
void reset(T *p=nullptr) noexcept
Delete managed object and set to new given pointer.
Definition: autoPtrI.H:109
Foam::Random
Random number generator.
Definition: Random.H:59
Foam::polyMesh::points
virtual const pointField & points() const
Return raw points.
Definition: polyMesh.C:1038
Foam::IOobject
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition: IOobject.H:104
distributedTriSurfaceMesh.H
Foam::treeBoundBox::extend
treeBoundBox extend(Random &rndGen, const scalar s) const
Return slightly wider bounding box.
Definition: treeBoundBoxI.H:325
Foam::IOobject::AUTO_WRITE
Definition: IOobject.H:129
Foam::distributedTriSurfaceMesh::distributionTypeNames_
static const Enum< distributionType > distributionTypeNames_
Definition: distributedTriSurfaceMesh.H:101
Foam::faceMap
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
Definition: blockMeshMergeTopological.C:94
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:62
Foam::fileName
A class for handling file names.
Definition: fileName.H:69
s
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
Definition: gmvOutputSpray.H:25
Foam::argList::getOrDefault
T getOrDefault(const word &optName, const T &deflt) const
Get a value from the named option if present, or return default.
Definition: argListI.H:286
Foam::Pstream::scatterList
static void scatterList(const List< commsStruct > &comms, List< T > &Values, const int tag, const label comm)
Scatter data. Reverse of gatherList.
Definition: gatherScatterList.C:215
Foam::boundBox::invertedBox
static const boundBox invertedBox
A large inverted boundBox: min/max == +/- ROOTVGREAT.
Definition: boundBox.H:86
Foam::UPstream::nProcs
static label nProcs(const label communicator=0)
Number of processes in parallel run.
Definition: UPstream.H:427
Foam::treeBoundBox
Standard boundBox with extra functionality for use in octree.
Definition: treeBoundBox.H:87
Foam::UPstream::parRun
static bool & parRun()
Is this a parallel run?
Definition: UPstream.H:415
Foam::argList::addNote
static void addNote(const string &note)
Add extra notes for the usage information.
Definition: argList.C:413
Foam::Time::functionObjects
const functionObjectList & functionObjects() const
Return the list of function objects.
Definition: Time.H:499
Foam::Pstream::scatter
static void scatter(const List< commsStruct > &comms, T &Value, const int tag, const label comm)
Scatter data. Distribute without modification. Reverse of gather.
Definition: gatherScatter.C:150
Foam::surfMesh
A surface mesh consisting of general polygon faces that has IO capabilities and a registry for storin...
Definition: surfMesh.H:63
Foam::triSurfaceMesh
IOoject and searching on triSurface.
Definition: triSurfaceMesh.H:106
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:350
meshBb
List< treeBoundBox > meshBb(1, treeBoundBox(boundBox(coarseMesh.points(), false)).extend(rndGen, 1e-3))
polyMesh.H
Foam::regIOobject::store
bool store()
Definition: regIOobjectI.H:37
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
nPoints
label nPoints
Definition: gmvOutputHeader.H:2
Foam::decompositionModel::canonicalName
static const word canonicalName
Definition: decompositionModel.H:80
Foam::argList::addArgument
static void addArgument(const string &argName, const string &usage="")
Append a (mandatory) argument to validArgs.
Definition: argList.C:302
Foam::triSurface
Triangulated surface description with patch information.
Definition: triSurface.H:76
Foam::functionObjectList::off
void off()
Switch the function objects off.
Definition: functionObjectList.C:573
Foam::Info
messageStream Info
Information stream (uses stdout - output is on the master only)
argList.H
Foam::IOobject::selectIO
static IOobject selectIO(const IOobject &io, const fileName &altFile, const word &ioName="")
Return the IOobject, but also consider an alternative file name.
Definition: IOobject.C:214
Foam::distributedTriSurfaceMesh::INDEPENDENT
Definition: distributedTriSurfaceMesh.H:96
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::FatalError
error FatalError
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:121
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::UPstream::myProcNo
static int myProcNo(const label communicator=0)
Number of this process (starting from masterNo() = 0)
Definition: UPstream.H:445
Foam::UPstream::master
static bool master(const label communicator=0)
Am I the master process.
Definition: UPstream.H:439
Foam::argList::addBoolOption
static void addBoolOption(const word &optName, const string &usage="", bool advanced=false)
Add a bool option to validOptions with usage information.
Definition: argList.C:325
Time.H
Foam::autoPtr
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition: HashPtrTable.H:53
setRootCase.H
Foam::TimePaths::system
const word & system() const
Return system name.
Definition: TimePathsI.H:94
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:372
Foam::Pstream::gatherList
static void gatherList(const List< commsStruct > &comms, List< T > &Values, const int tag, const label comm)
Gather data but keep individual values separate.
Definition: gatherScatterList.C:52
Foam::distributedTriSurfaceMesh::FOLLOW
Definition: distributedTriSurfaceMesh.H:95
Foam::nl
constexpr char nl
Definition: Ostream.H:385
Foam::boundBox::greatBox
static const boundBox greatBox
A large boundBox: min/max == -/+ ROOTVGREAT.
Definition: boundBox.H:83
mapDistribute.H
Foam::regIOobject::rename
virtual void rename(const word &newName)
Rename.
Definition: regIOobject.C:432
Foam::Time::rootPath
const fileName & rootPath() const
Return root path.
Definition: TimePathsI.H:42
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: HashTable.H:102
Foam::distributedTriSurfaceMesh
IOoject and searching on distributed triSurface. All processor hold (possibly overlapping) part of th...
Definition: distributedTriSurfaceMesh.H:85
Foam::constant::electromagnetic::e
const dimensionedScalar e
Elementary charge.
Definition: createFields.H:11
createTime.H
localIOdictionary.H
Foam::autoPtr::clear
void clear() noexcept
Same as reset(nullptr)
Definition: autoPtr.H:178
Foam::boundBox
A bounding box defined in terms of min/max extrema points.
Definition: boundBox.H:63
rndGen
Random rndGen
Definition: createFields.H:23
Foam::dictionary::add
entry * add(entry *entryPtr, bool mergeEntry=false)
Add a new entry.
Definition: dictionary.C:708
decompositionModel.H
Foam::TimePaths::constant
const word & constant() const
Return constant name.
Definition: TimePathsI.H:88
Foam::IOobject::NO_READ
Definition: IOobject.H:123
args
Foam::argList args(argc, argv)
createPolyMesh.H
Foam::argList::found
bool found(const word &optName) const
Return true if the named option is found.
Definition: argListI.H:157
Foam::IOobject::MUST_READ
Definition: IOobject.H:120