distributedTriSurfaceMesh.H
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-2017 OpenFOAM Foundation
9  Copyright (C) 2015-2022 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 Class
28  Foam::distributedTriSurfaceMesh
29 
30 Description
31  IOoject and searching on distributed triSurface. All processor hold
32  (possibly overlapping) part of the overall surface. All queries are
33  distributed to the processor that can answer it and the result sent back.
34 
35  Can work in three modes:
36  - follow : makes sure each processor has all the triangles inside the
37  externally provided bounding box (usually the mesh bounding box).
38  Guarantees minimum amount of communication since mesh-local queries
39  should be answerable without any comms.
40  - independent : surface is decomposed according to the triangle centres
41  so the decomposition might be radically different from the mesh
42  decomposition. Guarantees best memory balance but at the expense of
43  more communication.
44  - frozen : no change
45 
46  Note: addressing used:
47  distributedTriSurfaceMesh: none
48 
49  triSurfaceMesh:
50  - surf.pointFaces() : edge addressing (for volume tests only)
51  - surf.edges() : edgeTree
52  - surf.faceFaces() : only if minQuality > 0
53 
54 
55 SourceFiles
56  distributedTriSurfaceMesh.C
57 
58 \*---------------------------------------------------------------------------*/
59 
60 #ifndef Foam_distributedTriSurfaceMesh_H
61 #define Foam_distributedTriSurfaceMesh_H
62 
63 #include "triSurfaceMesh.H"
64 #include "localIOdictionary.H"
65 #include "IOdictionary.H"
66 #include "Pair.H"
67 #include "globalIndex.H"
68 #include "DynamicField.H"
69 #include "triangleFwd.H"
70 
71 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
72 
73 namespace Foam
74 {
75 
76 class mapDistribute;
78 
79 // Typedefs
80 typedef Pair<point> segment;
81 
82 
83 /*---------------------------------------------------------------------------*\
84  Class distributedTriSurfaceMesh Declaration
85 \*---------------------------------------------------------------------------*/
86 
88 :
89  public triSurfaceMesh
90 {
91 public:
92 
93  // Static data
94 
96  {
97  FOLLOW = 0,
99  DISTRIBUTED = 2,
100  FROZEN = 3
101  };
102 
104 
105 private:
106 
107  // Private member data
108 
109  //- Merging distance
110  scalar mergeDist_;
111 
112  autoPtr<IOdictionary> decomposeParDict_;
113 
114  //- Decomposition used when independently decomposing surface.
115  autoPtr<decompositionMethod> decomposer_;
116 
117  //- Bounding box settings
118  localIOdictionary dict_;
119 
120  //- Bounding boxes of all processors
121  List<List<treeBoundBox>> procBb_;
122 
123  //- Global triangle numbering
124  mutable autoPtr<globalIndex> globalTris_;
125 
126  //- The (wanted) distribution type.
127  distributionType distType_;
128 
129  //- The (current) distribution type. Used to trigger re-distribution
130  // when starting from undecomposed surface.
131  distributionType currentDistType_;
132 
133 
134  // Private Member Functions
135 
136  // Read
137 
138  //- Search for io.local directory (=triSurface) either in case
139  // directory or in parent directory
140  static word findLocalInstance(const IOobject& io);
141 
142  //- Read my additional data
143  bool read();
144 
145 
146  // Line intersection
147 
148  static bool isLocal
149  (
150  const List<treeBoundBox>& myBbs,
151  const point& start,
152  const point& end
153  );
154 
155  //- Split segment into subsegments overlapping the processor
156  // bounding box.
157  //void Foam::distributedTriSurfaceMesh::splitSegment
158  //(
159  // const label segmentI,
160  // const point& start,
161  // const point& end,
162  // const treeBoundBox& bb,
163  //
164  // DynamicList<segment>& allSegments,
165  // DynamicList<label>& allSegmentMap,
166  // DynamicList<label> sendMap
167  //) const
168 
169  //- Distribute segments into overlapping processor
170  // bounding boxes. Sort per processor.
171  void distributeSegment
172  (
173  const label,
174  const point& start,
175  const point& end,
176 
180  ) const;
181 
182  //- Divide edges into local and remote segments. Construct map to
183  // distribute and collect data.
184  autoPtr<mapDistribute> distributeSegments
185  (
186  const pointField& start,
187  const pointField& end,
188 
189  List<segment>& allSegments,
190  List<label>& allSegmentMap
191  ) const;
192 
193  //- Split edges, distribute, test and collect.
194  void findLine
195  (
196  const bool nearestIntersection,
197  const pointField& start,
198  const pointField& end,
200  ) const;
201 
202 
203  // Triangle index
204 
205 
206  //- Helper: convert local triangle indices to global ones
207  void convertTriIndices(List<pointIndexHit>& info) const;
208 
209  //- Obtains global indices from pointIndexHit and swaps them back
210  // to their original processor. Used to calculate local region
211  // and normal.
212  autoPtr<mapDistribute> calcLocalQueries
213  (
214  const List<pointIndexHit>&,
215  labelList& triangleIndex
216  ) const;
217 
218 
219  // Nearest
220 
221  //- Is location inside any of the bounding boxes
222  bool contains
223  (
224  const List<treeBoundBox>& bbs,
225  const point& sample
226  ) const;
227 
228  //- Is location inside any of the processors bb or if not
229  // does it overlap
230  Tuple2<label, scalar> findBestProcs
231  (
232  const point& centre,
233  const scalar radiusSqr,
234  boolList& procContains,
235  boolList& procOverlaps,
236  label& minProci
237  ) const;
238 
239  label calcOverlappingProcs
240  (
241  const point& centre,
242  const scalar radiusSqr,
243  boolList& overlaps
244  ) const;
245 
246  //- Calculate map to send centres+radius to processors
247  autoPtr<mapDistribute> calcLocalQueries
248  (
249  const bool includeLocalProcessor,
250  const pointField& centres,
251  const scalarField& radiusSqr,
252 
253  pointField& allCentres,
254  scalarField& allRadiusSqr,
255  labelList& allSegmentMap
256  ) const;
257 
258 
259  // Side
260 
261  //- Side of nearest point w.r.t. edge between face0 and face1
262  volumeType edgeSide
263  (
264  const point& sample,
265  const point& nearestPoint,
266  const label face0,
267  const label face1
268  ) const;
269 
270  //- Find edge-connected face
271  label findOtherFace
272  (
273  const labelListList& pointFaces,
274  const label nearFacei,
275  const label nearLabel
276  ) const;
277 
278  //- Side of nearest point on faces w.r.t. samples. Handles nearest
279  // on edge/point
280  void surfaceSide
281  (
282  const pointField& samples,
283  const List<pointIndexHit>& nearestInfo,
284  List<volumeType>& region
285  ) const;
286 
287 
288  // Caching of volume type (based on indexedOctree)
289 
290  //- Collect mid points of tree boxes
291  void collectLeafMids
292  (
293  const label nodeI,
294  DynamicField<point>& midPoints
295  ) const;
296 
297  //- Find volume type of tree boxes
298  volumeType calcVolumeType
299  (
300  const List<volumeType>& midPointTypes,
301  label& index,
302  PackedList<2>& nodeTypes,
303  const label nodeI
304  ) const;
305 
306  //- Look up any cached data. Return unknown if cannot be determined.
307  volumeType cachedVolumeType
308  (
309  const label nodeI,
310  const point& sample
311  ) const;
312 
313 
314  // Surface redistribution
315 
316  //- Calculate face-faces
317  static void calcFaceFaces
318  (
319  const triSurface& s,
320  const labelListList& pointFaces,
322  );
323 
324  //- Finds new bounds based on an independent decomposition.
325  List<List<treeBoundBox>> independentlyDistributedBbs
326  (
327  const triSurface&
328  );
329 
330  //- Does any part of triangle overlap bb.
331  static bool overlaps
332  (
333  const List<treeBoundBox>& bb,
334  const triPointRef& tri
335  );
336 
337  //- Find points used in subset
338  static void subsetMeshMap
339  (
340  const triSurface& s,
341  const boolList& include,
342  const label nIncluded,
343  labelList& newToOldPoints,
344  labelList& oldToNewPoints,
345  labelList& newToOldFaces
346  );
347 
348  //- Construct subsetted surface
349  static triSurface subsetMesh
350  (
351  const triSurface& s,
352  const labelList& newToOldPoints,
353  const labelList& oldToNewPoints,
354  const labelList& newToOldFaces
355  );
356 
357  //- Subset given marked faces
358  static triSurface subsetMesh
359  (
360  const triSurface& s,
361  const boolList& include,
362  labelList& newToOldPoints,
363  labelList& newToOldFaces
364  );
365 
366  //- Subset given marked faces
367  static triSurface subsetMesh
368  (
369  const triSurface& s,
370  const labelList& newToOldFaces,
371  labelList& newToOldPoints
372  );
373 
374  //- Find triangle otherF in allFaces.
375  static label findTriangle
376  (
377  const List<labelledTri>& allFaces,
378  const labelListList& allPointFaces,
379  const labelledTri& otherF
380  );
381 
382  //- Merge triSurface (subTris, subPoints) into allTris, allPoints.
383  static void merge
384  (
385  const scalar mergeDist,
386  const List<labelledTri>& subTris,
387  const pointField& subPoints,
388 
389  List<labelledTri>& allTris,
391 
392  labelList& faceConstructMap,
393  labelList& pointConstructMap
394  );
395 
396  //- Distribute stored fields
397  template<class Type>
398  void distributeFields(const mapDistribute& map);
399 
400 
401  //- No copy construct
403 
404  //- No copy assignment
405  void operator=(const distributedTriSurfaceMesh&) = delete;
406 
407 
408 public:
409 
410  //- Runtime type information
411  TypeName("distributedTriSurfaceMesh");
412 
413 
414  // Constructors
415 
416  //- Construct from triSurface
418  (
419  const IOobject&,
420  const triSurface&,
421  const dictionary& dict
422  );
423 
424  //- Construct read. Does findInstance to find io.local().
426 
427  //- Construct from dictionary (used by searchableSurface).
428  // Does read. Does findInstance to find io.local().
430  (
431  const IOobject& io,
432  const dictionary& dict
433  );
434 
435 
436  //- Destructor
437  virtual ~distributedTriSurfaceMesh();
438 
439  //- Clear storage
440  void clearOut();
441 
442 
443  // Member Functions
444 
445  //- Triangle indexing (demand driven)
446  const globalIndex& globalTris() const;
447 
448 
449  // searchableSurface implementation
450 
451  //- Range of global indices that can be returned.
452  virtual label globalSize() const
453  {
454  return globalTris().totalSize();
455  }
456 
457  virtual void findNearest
458  (
459  const pointField& sample,
460  const scalarField& nearestDistSqr,
461  List<pointIndexHit>&
462  ) const;
463 
464  //- Find the nearest locations for the supplied points to a
465  // particular region in the searchable surface.
466  virtual void findNearest
467  (
468  const pointField& samples,
469  const scalarField& nearestDistSqr,
470  const labelList& regionIndices,
471  List<pointIndexHit>& info
472  ) const;
473 
474  virtual void findLine
475  (
476  const pointField& start,
477  const pointField& end,
478  List<pointIndexHit>&
479  ) const;
480 
481  virtual void findLineAny
482  (
483  const pointField& start,
484  const pointField& end,
485  List<pointIndexHit>&
486  ) const;
487 
488  //- Get all intersections in order from start to end.
489  virtual void findLineAll
490  (
491  const pointField& start,
492  const pointField& end,
493  List<List<pointIndexHit>>&
494  ) const;
495 
496  //- From a set of points and indices get the region
497  virtual void getRegion
498  (
499  const List<pointIndexHit>&,
500  labelList& region
501  ) const;
502 
503  //- From a set of points and indices get the normal
504  virtual void getNormal
505  (
506  const List<pointIndexHit>&,
507  vectorField& normal
508  ) const;
509 
510  //- Determine type (inside/outside/mixed) for point. unknown if
511  // cannot be determined (e.g. non-manifold surface)
512  virtual void getVolumeType
513  (
514  const pointField&,
515  List<volumeType>&
516  ) const;
517 
518  //- Set bounds of surface. Bounds currently set as list of
519  // bounding boxes. Will do redistribution of surface to locally
520  // have all triangles overlapping bounds.
521  // Larger bounds: more triangles (memory), more fully local tests
522  // (quick).
523  // keepNonLocal = true : keep triangles that do not overlap
524  // any processor bounds.
525  // Should really be split into a routine to determine decomposition
526  // and one that does actual distribution but determining
527  // decomposition with duplicate triangle merging requires
528  // same amount as work as actual distribution.
529  virtual void distribute
530  (
531  const List<treeBoundBox>&,
532  const bool keepNonLocal,
533  autoPtr<mapDistribute>& faceMap,
534  autoPtr<mapDistribute>& pointMap
535  );
536 
537 
538  // Other
539 
540  //- WIP. From a set of hits (points and
541  // indices) get the specified field. Misses do not get set.
542  virtual void getField(const List<pointIndexHit>&, labelList&) const;
543 
544  //- Calculate the triangles that are overlapping bounds.
545  static void overlappingSurface
546  (
547  const triSurface&,
548  const List<treeBoundBox>&,
549  boolList& includedFace
550  );
551 
552  //- Subset the part of surface that is overlapping bounds.
554  (
555  const triSurface&,
556  const List<treeBoundBox>&,
557  labelList& subPointMap,
558  labelList& subFaceMap
559  );
560 
561 
562  //- Obtains global indices from pointIndexHit and swaps them back
563  // to their original processor. Used to calculate local region
564  // and normal.
566  (
567  const List<pointIndexHit>&,
568  labelList& triangleIndex
569  ) const;
570 
571 
572  //- Print some stats. Parallel aware version of
573  // triSurface::writeStats.
574  void writeStats(Ostream& os) const;
575 
576 
577  // regIOobject implementation
578 
579  //- Write using stream options
580  // Do not use the triSurfaceMesh::writeObject since it
581  // would filter out empty regions. These need to be preserved
582  // in case we want to make decisions based on the number of
583  // regions.
584  virtual bool writeObject
585  (
586  IOstreamOption streamOpt,
587  const bool writeOnProc
588  ) const;
589 
590  //- Is object global
591  virtual bool global() const
592  {
593  return false;
594  }
595 
596  //- Return complete path + object name if the file exists
597  // either in the case/processor or case otherwise null
598  virtual fileName filePath() const
599  {
601  }
602 };
603 
604 
605 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
606 
607 //- Global file type for distributedTriSurfaceMesh
608 template<>
609 struct is_globalIOobject<distributedTriSurfaceMesh> : std::true_type {};
610 
611 
612 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
613 
614 } // End namespace Foam
615 
616 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
617 
618 #ifdef NoRepository
620 #endif
621 
622 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
623 
624 #endif
625 
626 // ************************************************************************* //
virtual void getField(const List< pointIndexHit > &, labelList &) const
WIP. From a set of hits (points and.
static const Enum< distributionType > distributionTypeNames_
virtual bool writeObject(IOstreamOption streamOpt, const bool writeOnProc) const
Write using stream options.
dictionary dict
A triangle primitive used to calculate face normals and swept volumes. Uses referred points...
Definition: triangle.H:217
A class for handling file names.
Definition: fileName.H:72
virtual void findLineAny(const pointField &start, const pointField &end, List< pointIndexHit > &) const
Return any intersection on segment from start to end.
static void overlappingSurface(const triSurface &, const List< treeBoundBox > &, boolList &includedFace)
Calculate the triangles that are overlapping bounds.
A list of keyword definitions, which are a keyword followed by a number of values (eg...
Definition: dictionary.H:129
A 2-tuple for storing two objects of dissimilar types. The container is similar in purpose to std::pa...
Definition: stringOps.H:54
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: BitOps.H:56
const globalIndex & globalTris() const
Triangle indexing (demand driven)
virtual void distribute(const List< treeBoundBox > &, const bool keepNonLocal, autoPtr< mapDistribute > &faceMap, autoPtr< mapDistribute > &pointMap)
Set bounds of surface. Bounds currently set as list of.
scalarField samples(nIntervals, Zero)
Pair< point > segment
A simple container for options an IOstream can normally have.
An enumeration wrapper for classification of a location as being inside/outside of a volume...
Definition: volumeType.H:55
iterator end() noexcept
iterator to signal the end (for any HashTable)
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
virtual void getVolumeType(const pointField &, List< volumeType > &) const
Determine type (inside/outside/mixed) for point. unknown if.
IOoject and searching on triSurface.
localIOdictionary is derived from IOdictionary but excludes parallel master reading.
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Definition: POSIX.C:799
Calculates a unique integer (label so might not have enough room - 2G max) for processor + local inde...
Definition: globalIndex.H:61
const labelListList & faceFaces() const
Return face-face addressing.
label totalSize() const noexcept
The total addressed size, which corresponds to the end offset and also the sum of all localSizes...
Definition: globalIndexI.H:165
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:38
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects...
Definition: DynamicList.H:51
virtual void getRegion(const List< pointIndexHit > &, labelList &region) const
From a set of points and indices get the region.
virtual fileName filePath() const
Return complete path + object name if the file exists.
A class for handling words, derived from Foam::string.
Definition: word.H:63
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
virtual void getNormal(const List< pointIndexHit > &, vectorField &normal) const
From a set of points and indices get the normal.
fileName localFilePath(const word &typeName, const bool search=true) const
Redirect to fileHandler filePath, searching locally.
Definition: IOobject.C:536
Dynamically sized Field.
Definition: DynamicField.H:45
Abstract base class for domain decomposition.
A triFace with additional (region) index.
Definition: labelledTri.H:53
virtual void findLineAll(const pointField &start, const pointField &end, List< List< pointIndexHit >> &) const
Get all intersections in order from start to end.
InfoProxy< IOobject > info() const noexcept
Return info proxy, for printing information to a stream.
Definition: IOobject.H:955
const labelListList & pointFaces() const
Return point-face addressing.
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:56
IOoject and searching on distributed triSurface. All processor hold (possibly overlapping) part of th...
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
virtual void findNearest(const pointField &sample, const scalarField &nearestDistSqr, List< pointIndexHit > &) const
OBJstream os(runTime.globalPath()/outputName)
Class containing processor-to-processor mapping information.
tmp< pointField > allPoints(const Triangulation &t)
Extract all points in vertex-index order.
Field< vector > vectorField
Specialisation of Field<T> for vector.
Pointer management similar to std::unique_ptr, with some additional methods and type checking...
Definition: HashPtrTable.H:48
TypeName("distributedTriSurfaceMesh")
Runtime type information.
List< label > labelList
A List of labels.
Definition: List.H:62
IOobject io("surfaceFilmProperties", mesh.time().constant(), mesh, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE, IOobject::NO_REGISTER)
virtual autoPtr< mapDistribute > localQueries(const List< pointIndexHit > &, labelList &triangleIndex) const
Obtains global indices from pointIndexHit and swaps them back.
Triangulated surface description with patch information.
Definition: triSurface.H:71
virtual label globalSize() const
Range of global indices that can be returned.
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))
Defines the attributes of an object for which implicit objectRegistry management is supported...
Definition: IOobject.H:172
constexpr List() noexcept
Default construct.
Definition: ListI.H:116
Namespace for OpenFOAM.
void writeStats(Ostream &os) const
Print some stats. Parallel aware version of.
virtual bool global() const
Is object global.