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-2021 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 "decompositionModel.H"
52 
53 using namespace Foam;
54 
55 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
56 
57 // Print on master all the per-processor surface stats.
58 void writeProcStats
59 (
60  const triSurface& s,
62 )
63 {
64  // Determine surface bounding boxes, faces, points
66  {
67  surfBb[Pstream::myProcNo()] = treeBoundBox(s.points());
68  Pstream::gatherList(surfBb);
69  Pstream::scatterList(surfBb);
70  }
71 
73  nPoints[Pstream::myProcNo()] = s.points().size();
76 
77  labelList nFaces(Pstream::nProcs());
78  nFaces[Pstream::myProcNo()] = s.size();
79  Pstream::gatherList(nFaces);
80  Pstream::scatterList(nFaces);
81 
82  forAll(surfBb, proci)
83  {
84  Info<< "processor" << proci << nl;
85 
86  const List<treeBoundBox>& bbs = meshBb[proci];
87  if (bbs.size())
88  {
89  Info<< "\tMesh bounds : " << bbs[0] << nl;
90  for (label i = 1; i < bbs.size(); i++)
91  {
92  Info<< "\t " << bbs[i]<< nl;
93  }
94  }
95  Info<< "\tSurface bounding box : " << surfBb[proci] << nl
96  << "\tTriangles : " << nFaces[proci] << nl
97  << "\tVertices : " << nPoints[proci]
98  << endl;
99  }
100  Info<< endl;
101 }
102 
103 
104 
105 int main(int argc, char *argv[])
106 {
108  (
109  "Redistribute a triSurface."
110  " The specified surface must be located in the constant/triSurface"
111  " directory"
112  );
113 
114  argList::addArgument("triSurfaceMesh");
115  argList::addArgument("distributionType");
117  (
118  "keepNonMapped",
119  "Preserve surface outside of mesh bounds"
120  );
121 
122  #include "setRootCase.H"
123  #include "createTime.H"
125 
126  const auto surfFileName = args.get<fileName>(1);
127  const auto distTypeName = args.get<word>(2);
128  const label distType =
130 
131  Info<< "Reading surface from " << surfFileName << nl << nl
132  << "Using distribution method "
133  << distTypeName << nl << endl;
134 
135  const bool keepNonMapped = args.found("keepNonMapped");
136 
137  if (keepNonMapped)
138  {
139  Info<< "Preserving surface outside of mesh bounds." << nl << endl;
140  }
141  else
142  {
143  Info<< "Removing surface outside of mesh bounds." << nl << endl;
144  }
145 
146 
147  if (!Pstream::parRun())
148  {
150  << "Please run this program on the decomposed case."
151  << " It will read surface " << surfFileName
152  << " and decompose it such that it overlaps the mesh bounding box."
153  << exit(FatalError);
154  }
155 
156 
157  Random rndGen(653213);
158 
159  // For independent decomposition, ensure that distributedTriSurfaceMesh
160  // can find the alternative decomposeParDict specified via the
161  // -decomposeParDict option.
163  {
164  // Ensure demand-driven decompositionMethod finds alternative
165  // decomposeParDict location properly.
166 
167  IOdictionary* dictPtr = new IOdictionary
168  (
170  (
171  IOobject
172  (
174  runTime.system(),
175  runTime,
178  ),
179  args.getOrDefault<fileName>("decomposeParDict", "")
180  )
181  );
182 
183  // Store it on the object registry, but to be found it must also
184  // have the expected "decomposeParDict" name.
185 
187  runTime.store(dictPtr);
188  }
189 
190  // Determine mesh bounding boxes:
192  if (distType == distributedTriSurfaceMesh::FOLLOW)
193  {
194  #include "createPolyMesh.H"
195 
197  (
198  1,
200  (
201  boundBox(mesh.points(), false)
202  ).extend(rndGen, 1e-3)
203  );
206  }
207 
208  IOobject io
209  (
210  surfFileName, // name
211  //runTime.findInstance("triSurface", surfFileName), // instance
212  runTime.constant(), // instance
213  "triSurface", // local
214  runTime, // registry
217  );
218 
219  // Look for file (using searchableSurface rules)
220  const fileName actualPath(typeFilePath<searchableSurface>(io));
221  fileName localPath(actualPath);
222  localPath.replace(runTime.rootPath() + '/', "");
223 
224 
226 
227  if (actualPath == io.objectPath())
228  {
229  Info<< "Loading local (decomposed) surface " << localPath << nl <<endl;
230  surfMeshPtr.reset(new distributedTriSurfaceMesh(io));
231  }
232  else
233  {
234  Info<< "Loading undecomposed surface " << localPath
235  << " on master only" << endl;
236 
237  triSurface s;
238  List<treeBoundBox> bbs;
239  if (Pstream::master())
240  {
241  // Actually load the surface
242  const bool oldParRun = Pstream::parRun(false);
243  triSurfaceMesh surf(io);
244  Pstream::parRun(oldParRun); // Restore parallel state
245  s = surf;
247  }
248  else
249  {
251  }
252 
254  dict.add("distributionType", distTypeName);
255  dict.add("mergeDistance", SMALL);
256  dict.add("bounds", bbs);
257 
258  // Scatter patch information
259  Pstream::scatter(s.patches());
260 
261  // Construct distributedTrisurfaceMesh from components
262  IOobject notReadIO(io);
263  notReadIO.readOpt(IOobject::NO_READ);
264  surfMeshPtr.reset(new distributedTriSurfaceMesh(notReadIO, s, dict));
265  }
266 
267  distributedTriSurfaceMesh& surfMesh = surfMeshPtr();
268 
269 
270  // Write per-processor stats
271  Info<< "Before redistribution:" << endl;
272  writeProcStats(surfMesh, meshBb);
273 
274 
275  // Do redistribution
276  Info<< "Redistributing surface" << nl << endl;
278  autoPtr<mapDistribute> pointMap;
279  surfMesh.distribute
280  (
282  keepNonMapped,
283  faceMap,
284  pointMap
285  );
286  faceMap.clear();
287  pointMap.clear();
288 
289  Info<< endl;
290 
291 
292  // Write per-processor stats
293  Info<< "After redistribution:" << endl;
294  writeProcStats(surfMesh, meshBb);
295 
296 
297  Info<< "Writing surface." << nl << endl;
298  surfMesh.objectRegistry::write();
299 
300  Info<< "End\n" << endl;
301 
302  return 0;
303 }
304 
305 
306 // ************************************************************************* //
Foam::IOobject::NO_WRITE
@ NO_WRITE
Definition: IOobject.H:191
Foam::IOdictionary
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
Definition: IOdictionary.H:50
runTime
engineTime & runTime
Definition: createEngineTime.H:13
Foam::Random
Random number generator.
Definition: Random.H:55
Foam::polyMesh::points
virtual const pointField & points() const
Definition: polyMesh.C:1062
Foam::IOobject
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition: IOobject.H:165
distributedTriSurfaceMesh.H
Foam::treeBoundBox::extend
treeBoundBox extend(Random &rndGen, const scalar s) const
Definition: treeBoundBoxI.H:318
Foam::IOobject::AUTO_WRITE
@ AUTO_WRITE
Definition: IOobject.H:190
Foam::distributedTriSurfaceMesh::distributionTypeNames_
static const Enum< distributionType > distributionTypeNames_
Definition: distributedTriSurfaceMesh.H:97
Foam::faceMap
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
Definition: blockMeshMergeTopological.C:87
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:63
Foam::fileName
A class for handling file names.
Definition: fileName.H:71
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
Definition: argListI.H:300
Foam::Pstream::scatterList
static void scatterList(const List< commsStruct > &comms, List< T > &Values, const int tag, const label comm)
Definition: gatherScatterList.C:209
Foam::boundBox::invertedBox
static const boundBox invertedBox
Definition: boundBox.H:80
Foam::treeBoundBox
Standard boundBox with extra functionality for use in octree.
Definition: treeBoundBox.H:82
Foam::argList::addNote
static void addNote(const string &note)
Definition: argList.C:405
Foam::Time::functionObjects
const functionObjectList & functionObjects() const
Definition: Time.H:495
Foam::UPstream::master
static bool master(const label communicator=worldComm)
Definition: UPstream.H:453
Foam::Pstream::scatter
static void scatter(const List< commsStruct > &comms, T &Value, const int tag, const label comm)
Definition: gatherScatter.C:144
Foam::surfMesh
A surface mesh consisting of general polygon faces that has IO capabilities and a registry for storin...
Definition: surfMesh.H:59
Foam::triSurfaceMesh
IOoject and searching on triSurface.
Definition: triSurfaceMesh.H:102
Foam::endl
Ostream & endl(Ostream &os)
Definition: Ostream.H:381
meshBb
List< treeBoundBox > meshBb(1, treeBoundBox(boundBox(coarseMesh.points(), false)).extend(rndGen, 1e-3))
polyMesh.H
Foam::argList::get
T get(const label index) const
Definition: argListI.H:271
Foam::regIOobject::store
bool store()
Definition: regIOobjectI.H:30
forAll
#define forAll(list, i)
Definition: stdFoam.H:349
nPoints
label nPoints
Definition: gmvOutputHeader.H:2
Foam::decompositionModel::canonicalName
static const word canonicalName
Definition: decompositionModel.H:75
Foam::argList::addArgument
static void addArgument(const string &argName, const string &usage="")
Definition: argList.C:294
Foam::triSurface
Triangulated surface description with patch information.
Definition: triSurface.H:72
Foam::functionObjectList::off
void off()
Definition: functionObjectList.C:600
Foam::Info
messageStream Info
argList.H
Foam::IOobject::selectIO
static IOobject selectIO(const IOobject &io, const fileName &altFile, const word &ioName="")
Definition: IOobject.C:231
Foam::distributedTriSurfaceMesh::INDEPENDENT
@ INDEPENDENT
Definition: distributedTriSurfaceMesh.H:92
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:119
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
Foam
Definition: atmBoundaryLayer.C:26
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
Foam::autoPtr::reset
void reset(autoPtr< T > &&other) noexcept
Foam::argList::addBoolOption
static void addBoolOption(const word &optName, const string &usage="", bool advanced=false)
Definition: argList.C:317
Time.H
Foam::autoPtr
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition: HashPtrTable.H:49
setRootCase.H
Foam::TimePaths::system
const word & system() const
Definition: TimePathsI.H:95
FatalErrorInFunction
#define FatalErrorInFunction
Definition: error.H:465
Foam::Pstream::gatherList
static void gatherList(const List< commsStruct > &comms, List< T > &Values, const int tag, const label comm)
Definition: gatherScatterList.C:46
Foam::distributedTriSurfaceMesh::FOLLOW
@ FOLLOW
Definition: distributedTriSurfaceMesh.H:91
Foam::UPstream::myProcNo
static int myProcNo(const label communicator=worldComm)
Definition: UPstream.H:459
Foam::nl
constexpr char nl
Definition: Ostream.H:424
Foam::boundBox::greatBox
static const boundBox greatBox
Definition: boundBox.H:77
mapDistribute.H
Foam::regIOobject::rename
virtual void rename(const word &newName)
Definition: regIOobject.C:408
Foam::Time::rootPath
const fileName & rootPath() const
Definition: TimePathsI.H:43
Foam::UPstream::parRun
static bool & parRun() noexcept
Definition: UPstream.H:429
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: BitOps.H:58
Foam::distributedTriSurfaceMesh
IOoject and searching on distributed triSurface. All processor hold (possibly overlapping) part of th...
Definition: distributedTriSurfaceMesh.H:81
Foam::constant::electromagnetic::e
const dimensionedScalar e
Definition: createFields.H:11
createTime.H
Foam::autoPtr::clear
void clear() noexcept
Definition: autoPtr.H:172
Foam::boundBox
A bounding box defined in terms of min/max extrema points.
Definition: boundBox.H:57
rndGen
Random rndGen
Definition: createFields.H:23
Foam::dictionary::add
entry * add(entry *entryPtr, bool mergeEntry=false)
Definition: dictionary.C:633
decompositionModel.H
Foam::TimePaths::constant
const word & constant() const
Definition: TimePathsI.H:89
Foam::IOobject::NO_READ
@ NO_READ
Definition: IOobject.H:184
args
Foam::argList args(argc, argv)
createPolyMesh.H
Required Variables.
Foam::UPstream::nProcs
static label nProcs(const label communicator=worldComm)
Definition: UPstream.H:441
Foam::argList::found
bool found(const word &optName) const
Definition: argListI.H:171
Foam::IOobject::MUST_READ
@ MUST_READ
Definition: IOobject.H:181