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-2016 OpenFOAM Foundation
6  \\/ M anipulation |
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 "treeBoundBox.H"
41 #include "FixedList.H"
42 #include "argList.H"
43 #include "Time.H"
44 #include "polyMesh.H"
46 #include "mapDistribute.H"
47 #include "triSurfaceFields.H"
48 #include "Pair.H"
49 
50 using namespace Foam;
51 
52 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
53 
54 // Print on master all the per-processor surface stats.
55 void writeProcStats
56 (
57  const triSurface& s,
59 )
60 {
61  // Determine surface bounding boxes, faces, points
63  {
64  surfBb[Pstream::myProcNo()] = treeBoundBox(s.points());
65  Pstream::gatherList(surfBb);
66  Pstream::scatterList(surfBb);
67  }
68 
73 
74  labelList nFaces(Pstream::nProcs());
75  nFaces[Pstream::myProcNo()] = s.size();
76  Pstream::gatherList(nFaces);
77  Pstream::scatterList(nFaces);
78 
79  forAll(surfBb, proci)
80  {
81  const List<treeBoundBox>& bbs = meshBb[proci];
82 
83  Info<< "processor" << proci << nl
84  << "\tMesh bounds : " << bbs[0] << nl;
85  for (label i = 1; i < bbs.size(); i++)
86  {
87  Info<< "\t " << bbs[i]<< nl;
88  }
89  Info<< "\tSurface bounding box : " << surfBb[proci] << nl
90  << "\tTriangles : " << nFaces[proci] << nl
91  << "\tVertices : " << nPoints[proci]
92  << endl;
93  }
94  Info<< endl;
95 }
96 
97 
98 
99 int main(int argc, char *argv[])
100 {
102  (
103  "redistribute a triSurface"
104  );
105 
106  argList::validArgs.append("triSurfaceMesh");
107  argList::validArgs.append("distributionType");
109  (
110  "keepNonMapped",
111  "preserve surface outside of mesh bounds"
112  );
113 
114  #include "setRootCase.H"
115  #include "createTime.H"
116  runTime.functionObjects().off();
117 
118  const fileName surfFileName = args[1];
119  const word distType = args[2];
120 
121  Info<< "Reading surface from " << surfFileName << nl << nl
122  << "Using distribution method "
124  << " " << distType << 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  #include "createPolyMesh.H"
149 
150  Random rndGen(653213);
151 
152  // Determine mesh bounding boxes:
154  {
156  (
157  1,
159  (
160  boundBox(mesh.points(), false)
161  ).extend(rndGen, 1e-3)
162  );
165  }
166 
167  IOobject io
168  (
169  surfFileName, // name
170  //runTime.findInstance("triSurface", surfFileName), // instance
171  runTime.constant(), // instance
172  "triSurface", // local
173  runTime, // registry
176  );
177 
178  const fileName actualPath(io.filePath());
179  fileName localPath(actualPath);
180  localPath.replace(runTime.rootPath() + '/', "");
181 
182  if (actualPath == io.objectPath())
183  {
184  Info<< "Loading local (decomposed) surface " << localPath << nl <<endl;
185  }
186  else
187  {
188  Info<< "Loading undecomposed surface " << localPath << nl << endl;
189  }
190 
191 
192  // Create dummy dictionary for bounding boxes if does not exist.
193  if (!isFile(actualPath / "Dict"))
194  {
196  dict.add("bounds", meshBb[Pstream::myProcNo()]);
197  dict.add("distributionType", distType);
198  dict.add("mergeDistance", SMALL);
199 
200  IOdictionary ioDict
201  (
202  IOobject
203  (
204  io.name() + "Dict",
205  io.instance(),
206  io.local(),
207  io.db(),
210  false
211  ),
212  dict
213  );
214 
215  Info<< "Writing dummy bounds dictionary to " << ioDict.name()
216  << nl << endl;
217 
218  ioDict.regIOobject::writeObject
219  (
222  ioDict.time().writeCompression()
223  );
224  }
225 
226 
227  // Load surface
229  Info<< "Loaded surface" << nl << endl;
230 
231 
232  // Generate a test field
233  {
234  const triSurface& s = static_cast<const triSurface&>(surfMesh);
235 
237  (
239  (
240  IOobject
241  (
242  surfMesh.searchableSurface::name(), // name
243  surfMesh.searchableSurface::instance(), // instance
244  surfMesh.searchableSurface::local(), // local
245  surfMesh,
248  ),
249  surfMesh,
250  dimLength
251  )
252  );
253  triSurfaceVectorField& fc = fcPtr();
254 
255  forAll(fc, triI)
256  {
257  fc[triI] = s[triI].centre(s.points());
258  }
259 
260  // Steal pointer and store object on surfMesh
261  fcPtr.ptr()->store();
262  }
263 
264 
265  // Write per-processor stats
266  Info<< "Before redistribution:" << endl;
267  writeProcStats(surfMesh, meshBb);
268 
269 
270  // Do redistribution
271  Info<< "Redistributing surface" << nl << endl;
273  autoPtr<mapDistribute> pointMap;
274  surfMesh.distribute
275  (
277  keepNonMapped,
278  faceMap,
279  pointMap
280  );
281  faceMap.clear();
282  pointMap.clear();
283 
284  Info<< endl;
285 
286 
287  // Write per-processor stats
288  Info<< "After redistribution:" << endl;
289  writeProcStats(surfMesh, meshBb);
290 
291 
292  Info<< "Writing surface." << nl << endl;
293  surfMesh.searchableSurface::write();
294 
295  Info<< "End\n" << endl;
296 
297  return 0;
298 }
299 
300 
301 // ************************************************************************* //
cachedRandom rndGen(label(0),-1)
static void scatterList(const List< commsStruct > &comms, List< T > &Values, const int tag, const label comm)
Scatter data. Reverse of gatherList.
dictionary dict
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:428
List< treeBoundBox > meshBb(1, treeBoundBox(boundBox(coarseMesh.points(), false)).extend(rndGen, 1e-3))
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
A class for handling file names.
Definition: fileName.H:69
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
const double e
Elementary charge.
Definition: doubleFloat.H:78
error FatalError
A list of keyword definitions, which are a keyword followed by any number of values (e...
Definition: dictionary.H:137
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:319
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
Fields for triSurface.
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:76
static int myProcNo(const label communicator=0)
Number of this process (starting from masterNo() = 0)
Definition: UPstream.H:417
bool isFile(const fileName &, const bool checkGzip=true)
Does the name exist as a FILE in the file system?
Definition: POSIX.C:492
treeBoundBox extend(Random &, const scalar s) const
Return slightly wider bounding box.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:253
const Field< PointType > & points() const
Return reference to global points.
static SLList< string > validArgs
A list of valid (mandatory) arguments.
Definition: argList.H:154
A bounding box defined in terms of the points at its extremities.
Definition: boundBox.H:58
static const NamedEnum< distributionType, 3 > distributionTypeNames_
const Foam::HashTable< string > & options() const
Return options.
Definition: argListI.H:90
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
bool add(entry *, bool mergeEntry=false)
Add a new entry.
Definition: dictionary.C:737
virtual const pointField & points() const
Return raw points.
Definition: polyMesh.C:979
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
Definition: IOdictionary.H:53
void clear()
Delete object (if the pointer is valid) and set pointer to NULL.
Definition: autoPtrI.H:126
dynamicFvMesh & mesh
A class for handling words, derived from string.
Definition: word.H:59
label nPoints
Simple random number generator.
Definition: Random.H:49
A surface mesh consisting of general polygon faces.
Definition: surfMesh.H:55
IOoject and searching on distributed triSurface. All processor hold (possibly overlapping) part of th...
static const char nl
Definition: Ostream.H:262
static bool & parRun()
Is this a parallel run?
Definition: UPstream.H:393
static label nProcs(const label communicator=0)
Number of processes in parallel run.
Definition: UPstream.H:399
static const versionNumber currentVersion
Current version number.
Definition: IOstream.H:206
const dimensionSet dimLength(0, 1, 0, 0, 0, 0, 0)
Definition: dimensionSets.H:50
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
Standard boundBox + extra functionality for use in octree.
Definition: treeBoundBox.H:87
messageStream Info
An auto-pointer similar to the STL auto_ptr but with automatic casting to a reference to the type and...
Definition: PtrList.H:53
static void addBoolOption(const word &opt, const string &usage="")
Add to a bool option to validOptions with usage information.
Definition: argList.C:83
static void addNote(const string &)
Add extra notes for the usage information.
Definition: argList.C:124
Triangulated surface description with patch information.
Definition: triSurface.H:65
Foam::argList args(argc, argv)
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:91
static void gatherList(const List< commsStruct > &comms, List< T > &Values, const int tag, const label comm)
Gather data but keep individual values separate.
Namespace for OpenFOAM.