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 | Copyright (C) 2011-2015 OpenFOAM Foundation
6  \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 Application
25  surfaceRedistributePar
26 
27 Description
28  (Re)distribution of triSurface. Either takes an undecomposed surface
29  or an already decomposed surface and redistributes it so that each
30  processor has all triangles that overlap its mesh.
31 
32 Note
33  - best decomposition option is hierarchGeomDecomp since
34  guarantees square decompositions.
35  - triangles might be present on multiple processors.
36  - merging uses geometric tolerance so take care with writing precision.
37 
38 \*---------------------------------------------------------------------------*/
39 
40 #include "argList.H"
41 #include "Time.H"
42 #include "polyMesh.H"
44 #include "mapDistribute.H"
45 
46 using namespace Foam;
47 
48 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
49 
50 // Print on master all the per-processor surface stats.
51 void writeProcStats
52 (
53  const triSurface& s,
55 )
56 {
57  // Determine surface bounding boxes, faces, points
59  {
60  surfBb[Pstream::myProcNo()] = treeBoundBox(s.points());
61  Pstream::gatherList(surfBb);
62  Pstream::scatterList(surfBb);
63  }
64 
66  nPoints[Pstream::myProcNo()] = s.points().size();
69 
70  labelList nFaces(Pstream::nProcs());
71  nFaces[Pstream::myProcNo()] = s.size();
72  Pstream::gatherList(nFaces);
73  Pstream::scatterList(nFaces);
74 
75  forAll(surfBb, procI)
76  {
77  Info<< "processor" << procI << nl;
78 
79  const List<treeBoundBox>& bbs = meshBb[procI];
80  if (bbs.size())
81  {
82  Info<< "\tMesh bounds : " << bbs[0] << nl;
83  for (label i = 1; i < bbs.size(); i++)
84  {
85  Info<< "\t " << bbs[i]<< nl;
86  }
87  }
88  Info<< "\tSurface bounding box : " << surfBb[procI] << nl
89  << "\tTriangles : " << nFaces[procI] << nl
90  << "\tVertices : " << nPoints[procI]
91  << endl;
92  }
93  Info<< endl;
94 }
95 
96 
97 
98 int main(int argc, char *argv[])
99 {
101  (
102  "redistribute a triSurface"
103  );
104 
105  argList::validArgs.append("triSurfaceMesh");
106  argList::validArgs.append("distributionType");
108  (
109  "keepNonMapped",
110  "preserve surface outside of mesh bounds"
111  );
112 
113  #include "setRootCase.H"
114  #include "createTime.H"
115  runTime.functionObjects().off();
116 
117  const fileName surfFileName = args[1];
118  const word distTypeName = args[2];
119  const label distType =
121 
122  Info<< "Reading surface from " << surfFileName << nl << nl
123  << "Using distribution method "
124  << distTypeName << nl << endl;
125 
126  const bool keepNonMapped = args.options().found("keepNonMapped");
127 
128  if (keepNonMapped)
129  {
130  Info<< "Preserving surface outside of mesh bounds." << nl << endl;
131  }
132  else
133  {
134  Info<< "Removing surface outside of mesh bounds." << nl << endl;
135  }
136 
137 
138  if (!Pstream::parRun())
139  {
141  << "Please run this program on the decomposed case."
142  << " It will read surface " << surfFileName
143  << " and decompose it such that it overlaps the mesh bounding box."
144  << exit(FatalError);
145  }
146 
147 
148  Random rndGen(653213);
149 
150  // Determine mesh bounding boxes:
152  if (distType == distributedTriSurfaceMesh::FOLLOW)
153  {
154  #include "createPolyMesh.H"
155 
157  (
158  1,
160  (
161  boundBox(mesh.points(), false)
162  ).extend(rndGen, 1e-3)
163  );
166  }
167 
168 
169 
170  // Temporarily: override master-only checking
171  regIOobject::fileCheckTypes oldCheckType =
173 
174  if (oldCheckType == regIOobject::timeStampMaster)
175  {
177  }
178  else if (oldCheckType == regIOobject::inotifyMaster)
179  {
181  }
182 
183 
184 
185  IOobject io
186  (
187  surfFileName, // name
188  //runTime.findInstance("triSurface", surfFileName), // instance
189  runTime.constant(), // instance
190  "triSurface", // local
191  runTime, // registry
194  );
195 
196  const fileName actualPath(io.filePath());
197  fileName localPath(actualPath);
198  localPath.replace(runTime.rootPath() + '/', "");
199 
200 
202 
203  if (actualPath == io.objectPath())
204  {
205  Info<< "Loading local (decomposed) surface " << localPath << nl <<endl;
206  surfMeshPtr.reset(new distributedTriSurfaceMesh(io));
207  }
208  else
209  {
210  Info<< "Loading undecomposed surface " << localPath
211  << " on master only" << endl;
212 
213  triSurface s;
214  List<treeBoundBox> bbs;
215  if (Pstream::master())
216  {
217  // Actually load the surface
218  triSurfaceMesh surf(io);
219  s = surf;
221  }
222  else
223  {
225  }
226 
228  dict.add("distributionType", distTypeName);
229  dict.add("mergeDistance", SMALL);
230  dict.add("bounds", bbs);
231 
232  // Scatter patch information
233  Pstream::scatter(s.patches());
234 
235  // Construct distributedTrisurfaceMesh from components
236  IOobject notReadIO(io);
237  notReadIO.readOpt() = IOobject::NO_READ;
238  surfMeshPtr.reset(new distributedTriSurfaceMesh(notReadIO, s, dict));
239  }
240 
241  distributedTriSurfaceMesh& surfMesh = surfMeshPtr();
242 
243 
244  // Write per-processor stats
245  Info<< "Before redistribution:" << endl;
246  writeProcStats(surfMesh, meshBb);
247 
248 
249  // Do redistribution
250  Info<< "Redistributing surface" << nl << endl;
252  autoPtr<mapDistribute> pointMap;
253  surfMesh.distribute
254  (
256  keepNonMapped,
257  faceMap,
258  pointMap
259  );
260  faceMap.clear();
261  pointMap.clear();
262 
263  Info<< endl;
264 
265 
266  // Write per-processor stats
267  Info<< "After redistribution:" << endl;
268  writeProcStats(surfMesh, meshBb);
269 
270 
271  Info<< "Writing surface." << nl << endl;
272  surfMesh.objectRegistry::write();
273 
274 
276 
277 
278  Info<< "End\n" << endl;
279 
280  return 0;
281 }
282 
283 
284 // ************************************************************************* //
Foam::argList::validArgs
static SLList< string > validArgs
A list of valid (mandatory) arguments.
Definition: argList.H:143
Foam::Random
Simple random number generator.
Definition: Random.H:49
Foam::polyMesh::points
virtual const pointField & points() const
Return raw points.
Definition: polyMesh.C:979
Foam::IOobject
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:91
distributedTriSurfaceMesh.H
Foam::faceMap
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
Definition: blockMeshMergeFast.C:90
Foam::word
A class for handling words, derived from string.
Definition: word.H:59
Foam::fileName
A class for handling file names.
Definition: fileName.H:69
Foam::IOobject::AUTO_WRITE
@ AUTO_WRITE
Definition: IOobject.H:117
Foam::argList::addNote
static void addNote(const string &)
Add extra notes for the usage information.
Definition: argList.C:139
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:406
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:205
Foam::boundBox::invertedBox
static const boundBox invertedBox
A very large inverted boundBox: min/max == +/- VGREAT.
Definition: boundBox.H:79
Foam::UPstream::nProcs
static label nProcs(const label communicator=0)
Number of processes in parallel run.
Definition: UPstream.H:387
Foam::treeBoundBox
Standard boundBox + extra functionality for use in octree.
Definition: treeBoundBox.H:75
Foam::regIOobject::inotify
@ inotify
Definition: regIOobject.H:72
Foam::UPstream::parRun
static bool & parRun()
Is this a parallel run?
Definition: UPstream.H:377
Foam::distributedTriSurfaceMesh::distributionTypeNames_
static const NamedEnum< distributionType, 3 > distributionTypeNames_
Definition: distributedTriSurfaceMesh.H:88
Foam::argList::addBoolOption
static void addBoolOption(const word &opt, const string &usage="")
Add to a bool option to validOptions with usage information.
Definition: argList.C:98
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:147
Foam::surfMesh
A surface mesh consisting of general polygon faces.
Definition: surfMesh.H:55
Foam::IOobject::MUST_READ
@ MUST_READ
Definition: IOobject.H:108
Foam::triSurfaceMesh
IOoject and searching on triSurface.
Definition: triSurfaceMesh.H:63
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
polyMesh.H
meshBb
List< treeBoundBox > meshBb(1, treeBoundBox(boundBox(coarseMesh.points(), false)).extend(rndGen, 1e-3))
nPoints
label nPoints
Definition: gmvOutputHeader.H:2
Foam::regIOobject::timeStamp
@ timeStamp
Definition: regIOobject.H:70
Foam::argList::options
const Foam::HashTable< string > & options() const
Return options.
Definition: argListI.H:90
Foam::label
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
Foam::triSurface
Triangulated surface description with patch information.
Definition: triSurface.H:57
Foam::treeBoundBox::extend
treeBoundBox extend(Random &, const scalar s) const
Return slightly wider bounding box.
Definition: treeBoundBoxI.H:317
Foam::IOobject::NO_READ
@ NO_READ
Definition: IOobject.H:111
Foam::nl
static const char nl
Definition: Ostream.H:260
Foam::Info
messageStream Info
argList.H
main
int main(int argc, char *argv[])
Definition: postCalc.C:54
Foam::regIOobject::fileCheckTypes
fileCheckTypes
Types of communications.
Definition: regIOobject.H:68
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::FatalError
error FatalError
Foam::dictionary
A list of keyword definitions, which are a keyword followed by any number of values (e....
Definition: dictionary.H:137
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:18
Foam
Namespace for OpenFOAM.
Definition: combustionModel.C:30
Foam::e
const double e
Elementary charge.
Definition: doubleFloat.H:94
s
gmvFile<< "tracers "<< particles.size()<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().x()<< " ";}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().y()<< " ";}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().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))
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
Foam::UPstream::myProcNo
static int myProcNo(const label communicator=0)
Number of this process (starting from masterNo() = 0)
Definition: UPstream.H:405
Foam::UPstream::master
static bool master(const label communicator=0)
Am I the master process.
Definition: UPstream.H:399
Foam::regIOobject::fileModificationChecking
static fileCheckTypes fileModificationChecking
Definition: regIOobject.H:128
Foam::autoPtr
An auto-pointer similar to the STL auto_ptr but with automatic casting to a reference to the type and...
Definition: PtrList.H:117
setRootCase.H
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:318
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:49
Foam::distributedTriSurfaceMesh::FOLLOW
@ FOLLOW
Definition: distributedTriSurfaceMesh.H:83
Foam::regIOobject::inotifyMaster
@ inotifyMaster
Definition: regIOobject.H:73
Foam::boundBox::greatBox
static const boundBox greatBox
A very large boundBox: min/max == -/+ VGREAT.
Definition: boundBox.H:76
mapDistribute.H
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:59
Foam::distributedTriSurfaceMesh
IOoject and searching on distributed triSurface. All processor hold (possibly overlapping) part of th...
Definition: distributedTriSurfaceMesh.H:73
createTime.H
Foam::boundBox
A bounding box defined in terms of the points at its extremities.
Definition: boundBox.H:55
Foam::autoPtr::clear
void clear()
Delete object (if the pointer is valid) and set pointer to NULL.
Definition: autoPtrI.H:126
Foam::autoPtr::reset
void reset(T *=0)
If object pointer already set, delete object and set to given.
Definition: autoPtrI.H:114
Foam::List::size
void size(const label)
Override size to be inconsistent with allocated storage.
args
Foam::argList args(argc, argv)
createPolyMesh.H
rndGen
cachedRandom rndGen(label(0), -1)
Foam::dictionary::add
bool add(entry *, bool mergeEntry=false)
Add a new entry.
Definition: dictionary.C:729
Foam::regIOobject::timeStampMaster
@ timeStampMaster
Definition: regIOobject.H:71