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-2024 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  mutable autoPtr<IOdictionary> decomposeParDict_;
113 
114  //- Decomposition used when independently decomposing surface.
115  mutable autoPtr<decompositionMethod> decomposer_;
116 
117  //- Bounding box settings
118  localIOdictionary dict_;
119 
120  //- Use bounding boxes (default) or unique decomposition of triangles
121  //- (i.e. do not duplicate triangles)
122  bool decomposeUsingBbs_;
123 
124  //- Bounding boxes of all processors
125  List<List<treeBoundBox>> procBb_;
126 
127  //- Global triangle numbering
128  mutable autoPtr<globalIndex> globalTris_;
129 
130  //- Optional per-vertex normals. TBD: move to triSurface? or have
131  //- per-triangle 3 normals so we can interpolate and have features
132  mutable autoPtr<List<FixedList<vector, 3>>> vertexNormals_;
133 
134  //- The (wanted) distribution type.
135  distributionType distType_;
136 
137  //- The (current) distribution type. Used to trigger re-distribution
138  // when starting from undecomposed surface.
139  distributionType currentDistType_;
140 
141 
142  // Private Member Functions
143 
144  // Read
145 
146  //- Search for io.local directory (=triSurface) either in case
147  // directory or in parent directory
148  static word findLocalInstance(const IOobject& io);
149 
150  //- Read my additional data from dictionary. Additional flag to
151  //- say whether we can use master-only geometric tests.
152  bool readSettings(const bool isUndecomposed);
153 
154  //- Construction helper: generate vertex normals upon reading
155  //- undecomposed surface
156  void calcVertexNormals
157  (
158  const triSurface& surf,
160  ) const;
161 
162 
163  // Line intersection
164 
165  static bool isLocal
166  (
167  const List<treeBoundBox>& myBbs,
168  const point& start,
169  const point& end
170  );
171 
172  //- Split segment into subsegments overlapping the processor
173  // bounding box.
174  //void Foam::distributedTriSurfaceMesh::splitSegment
175  //(
176  // const label segmentI,
177  // const point& start,
178  // const point& end,
179  // const treeBoundBox& bb,
180  //
181  // DynamicList<segment>& allSegments,
182  // DynamicList<label>& allSegmentMap,
183  // DynamicList<label> sendMap
184  //) const
185 
186  //- Distribute segments into overlapping processor
187  // bounding boxes. Sort per processor.
188  void distributeSegment
189  (
190  const label,
191  const point& start,
192  const point& end,
193 
197  ) const;
198 
199  //- Divide edges into local and remote segments. Construct map to
200  // distribute and collect data.
201  autoPtr<mapDistribute> distributeSegments
202  (
203  const pointField& start,
204  const pointField& end,
205 
206  List<segment>& allSegments,
207  List<label>& allSegmentMap
208  ) const;
209 
210  //- Split edges, distribute, test and collect.
211  void findLine
212  (
213  const bool nearestIntersection,
214  const pointField& start,
215  const pointField& end,
217  ) const;
218 
219 
220  // Triangle index
221 
222 
223  //- Helper: convert local triangle indices to global ones
224  void convertTriIndices(List<pointIndexHit>& info) const;
225 
226  //- Obtains global indices from pointIndexHit and swaps them back
227  // to their original processor. Used to calculate local region
228  // and normal.
229  autoPtr<mapDistribute> calcLocalQueries
230  (
231  const List<pointIndexHit>&,
232  labelList& triangleIndex
233  ) const;
234 
235 
236  // Nearest
237 
238  //- Is location inside any of the bounding boxes
239  bool contains
240  (
241  const List<treeBoundBox>& bbs,
242  const point& sample
243  ) const;
244 
245  //- Is location inside any of the processors bb or if not
246  // does it overlap
247  Tuple2<label, scalar> findBestProcs
248  (
249  const point& centre,
250  const scalar radiusSqr,
251  boolList& procContains,
252  boolList& procOverlaps,
253  label& minProci
254  ) const;
255 
256  label calcOverlappingProcs
257  (
258  const point& centre,
259  const scalar radiusSqr,
260  boolList& overlaps
261  ) const;
262 
263  //- Calculate map to send centres+radius to processors
264  autoPtr<mapDistribute> calcLocalQueries
265  (
266  const bool includeLocalProcessor,
267  const pointField& centres,
268  const scalarField& radiusSqr,
269 
270  pointField& allCentres,
271  scalarField& allRadiusSqr,
272  labelList& allSegmentMap
273  ) const;
274 
275 
276  // Side
277 
278  //- Side of nearest point w.r.t. edge between face0 and face1
279  volumeType edgeSide
280  (
281  const point& sample,
282  const point& nearestPoint,
283  const label face0,
284  const label face1
285  ) const;
286 
287  //- Find edge-connected face
288  label findOtherFace
289  (
290  const labelListList& pointFaces,
291  const label nearFacei,
292  const label nearLabel
293  ) const;
294 
295  //- Side of nearest point on faces w.r.t. samples. Handles nearest
296  // on edge/point
297  void surfaceSide
298  (
299  const pointField& samples,
300  const List<pointIndexHit>& nearestInfo,
301  List<volumeType>& region
302  ) const;
303 
304 
305  // Caching of volume type (based on indexedOctree)
306 
307  //- Set node type on any node containing the triangle
308  volumeType markMixed
309  (
311  const label nodei,
312  const triPointRef& tri,
313  PackedList<2>& nodeTypes
314  ) const;
315 
316  //- Set node type on any node overlapping any remote triangles.
317  //- Only valid if using unique decomposition.
318  void markMixedOverlap
319  (
321  PackedList<2>& nodeTypes
322  ) const;
323 
324  //- Collect mid points of tree boxes
325  void collectLeafMids
326  (
327  const label nodeI,
328  DynamicField<point>& midPoints
329  ) const;
330 
331  //- Find volume type of tree boxes
332  volumeType calcVolumeType
333  (
334  const List<volumeType>& midPointTypes,
335  label& index,
336  PackedList<2>& nodeTypes,
337  const label nodeI
338  ) const;
339 
340  //- Calculate inside/outside of midpoint of tree nodes
341  void cacheVolumeType(PackedList<2>& nt) const;
342 
343  //- Look up any cached data. Return unknown if cannot be determined.
344  volumeType cachedVolumeType
345  (
346  const label nodeI,
347  const point& sample
348  ) const;
349 
350 
351  // Surface redistribution
352 
353  //- Calculate face-faces
354  static void calcFaceFaces
355  (
356  const triSurface& s,
357  const labelListList& pointFaces,
359  );
360 
361  //- Helper: get decompositionMethod
362  const decompositionMethod& decomposer() const;
363 
364  //- Finds new bounds based on an independent decomposition.
365  void independentlyDistributedBbs
366  (
367  const triSurface& s,
370  ) const;
371 
372  //- Does any part of triangle overlap bb.
373  static bool overlaps
374  (
375  const List<treeBoundBox>& bb,
376  const triPointRef& tri
377  );
378 
379  //- Find points used in subset
380  static void subsetMeshMap
381  (
382  const triSurface& s,
383  const boolList& include,
384  const label nIncluded,
385  labelList& newToOldPoints,
386  labelList& oldToNewPoints,
387  labelList& newToOldFaces
388  );
389 
390  //- Construct subsetted surface
391  static triSurface subsetMesh
392  (
393  const triSurface& s,
394  const labelList& newToOldPoints,
395  const labelList& oldToNewPoints,
396  const labelList& newToOldFaces
397  );
398 
399  //- Subset given marked faces
400  static triSurface subsetMesh
401  (
402  const triSurface& s,
403  const boolList& include,
404  labelList& newToOldPoints,
405  labelList& newToOldFaces
406  );
407 
408  //- Subset given marked faces
409  static triSurface subsetMesh
410  (
411  const triSurface& s,
412  const labelList& newToOldFaces,
413  labelList& newToOldPoints
414  );
415 
416  //- Find triangle otherF in allFaces.
417  static label findTriangle
418  (
419  const List<labelledTri>& allFaces,
420  const labelListList& allPointFaces,
421  const labelledTri& otherF
422  );
423 
424  //- Merge triSurface (subTris, subPoints) into allTris, allPoints.
425  static void merge
426  (
427  const scalar mergeDist,
428  const List<labelledTri>& subTris,
429  const pointField& subPoints,
430 
431  List<labelledTri>& allTris,
433 
434  labelList& faceConstructMap,
435  labelList& pointConstructMap
436  );
437 
438  //- Distribute stored fields
439  template<class Type>
440  void distributeFields(const mapDistribute& map);
441 
442 
443  //- No copy construct
445 
446  //- No copy assignment
447  void operator=(const distributedTriSurfaceMesh&) = delete;
448 
449 
450 public:
451 
452  //- Runtime type information
453  TypeName("distributedTriSurfaceMesh");
454 
455 
456  // Constructors
457 
458  //- Construct from components. Assumes triSurface is already decomposed
459  //- and dictionary contains corresponding information
461  (
462  const IOobject&,
463  const triSurface&,
464  const dictionary& dict
465  );
466 
467  //- Construct read. Does findInstance to find io.local()
468  //- - if found local : assume distributed
469  //- - if found in parent : assume undistributed. Can e.g. check for
470  //- closedness.
472 
473  //- Construct from dictionary (used by searchableSurface).
474  // Does read. Does findInstance to find io.local().
475  //- - if found local : assume distributed
476  //- - if found in parent : assume undistributed. Can e.g. check for
477  //- closedness.
479  (
480  const IOobject& io,
481  const dictionary& dict
482  );
483 
484 
485  //- Destructor
486  virtual ~distributedTriSurfaceMesh();
487 
488  //- Clear storage
489  void clearOut();
490 
491 
492  // Member Functions
493 
494  //- Triangle indexing (demand driven)
495  const globalIndex& globalTris() const;
496 
497 
498  // searchableSurface implementation
499 
500  //- Range of global indices that can be returned.
501  virtual label globalSize() const
502  {
503  return globalTris().totalSize();
504  }
505 
506  //- Flip triangles, outsideVolumeType and all cached inside/outside.
507  virtual void flip();
508 
509  virtual void findNearest
510  (
511  const pointField& sample,
512  const scalarField& nearestDistSqr,
513  List<pointIndexHit>&
514  ) const;
515 
516  //- Find the nearest locations for the supplied points to a
517  // particular region in the searchable surface.
518  virtual void findNearest
519  (
520  const pointField& samples,
521  const scalarField& nearestDistSqr,
522  const labelList& regionIndices,
523  List<pointIndexHit>& info
524  ) const;
525 
526  virtual void findLine
527  (
528  const pointField& start,
529  const pointField& end,
530  List<pointIndexHit>&
531  ) const;
532 
533  virtual void findLineAny
534  (
535  const pointField& start,
536  const pointField& end,
537  List<pointIndexHit>&
538  ) const;
539 
540  //- Get all intersections in order from start to end.
541  virtual void findLineAll
542  (
543  const pointField& start,
544  const pointField& end,
545  List<List<pointIndexHit>>&
546  ) const;
547 
548  //- From a set of points and indices get the region
549  virtual void getRegion
550  (
551  const List<pointIndexHit>&,
552  labelList& region
553  ) const;
554 
555  //- From a set of points and indices get the normal
556  virtual void getNormal
557  (
558  const List<pointIndexHit>&,
559  vectorField& normal
560  ) const;
561 
562  //- Determine type (inside/outside/mixed) for point. unknown if
563  // cannot be determined (e.g. non-manifold surface)
564  virtual void getVolumeType
565  (
566  const pointField&,
567  List<volumeType>&
568  ) const;
569 
570  //- Set bounds of surface. Bounds currently set as list of
571  // bounding boxes. Will do redistribution of surface to locally
572  // have all triangles overlapping bounds.
573  // Larger bounds: more triangles (memory), more fully local tests
574  // (quick).
575  // keepNonLocal = true : keep triangles that do not overlap
576  // any processor bounds.
577  // Should really be split into a routine to determine decomposition
578  // and one that does actual distribution but determining
579  // decomposition with duplicate triangle merging requires
580  // same amount as work as actual distribution.
581  virtual void distribute
582  (
583  const List<treeBoundBox>&,
584  const bool keepNonLocal,
585  autoPtr<mapDistribute>& faceMap,
586  autoPtr<mapDistribute>& pointMap
587  );
588 
589 
590  // Other
591 
592  //- WIP. From a set of hits (points and
593  // indices) get the specified field. Misses do not get set.
594  virtual void getField(const List<pointIndexHit>&, labelList&) const;
595 
596  //- Calculate the triangles that are overlapping bounds.
597  static void overlappingSurface
598  (
599  const triSurface&,
600  const List<treeBoundBox>&,
601  boolList& includedFace
602  );
603 
604  //- Subset the part of surface that is overlapping bounds.
606  (
607  const triSurface&,
608  const List<treeBoundBox>&,
609  labelList& subPointMap,
610  labelList& subFaceMap
611  );
612 
613 
614  //- Obtains global indices from pointIndexHit and swaps them back
615  // to their original processor. Used to calculate local region
616  // and normal.
618  (
619  const List<pointIndexHit>&,
620  labelList& triangleIndex
621  ) const;
622 
623 
624  //- Print some stats. Parallel aware version of
625  // triSurface::writeStats.
626  void writeStats(Ostream& os) const;
627 
628 
629  // regIOobject implementation
630 
631  //- Write using stream options
632  // Do not use the triSurfaceMesh::writeObject since it
633  // would filter out empty regions. These need to be preserved
634  // in case we want to make decisions based on the number of
635  // regions.
636  virtual bool writeObject
637  (
638  IOstreamOption streamOpt,
639  const bool writeOnProc
640  ) const;
641 
642  //- Is object global
643  virtual bool global() const
644  {
645  return false;
646  }
647 
648  //- Return complete path + object name if the file exists
649  // either in the case/processor or case otherwise null
650  virtual fileName filePath() const
651  {
653  }
654 };
655 
656 
657 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
658 
659 //- Global file type for distributedTriSurfaceMesh
660 template<>
661 struct is_globalIOobject<distributedTriSurfaceMesh> : std::true_type {};
662 
663 
664 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
665 
666 } // End namespace Foam
667 
668 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
669 
670 #ifdef NoRepository
672 #endif
673 
674 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
675 
676 #endif
677 
678 // ************************************************************************* //
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:233
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 1D vector of objects of type <T> with a fixed length <N>.
Definition: HashTable.H:107
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:56
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:801
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. Similar to DynamicList, but inheriting from a Field instead of a List...
Definition: DynamicField.H:46
Abstract base class for domain decomposition.
A triFace with additional (region) index.
Definition: labelledTri.H:53
Accumulating histogram of values. Specified bin resolution automatic generation of bins...
Definition: distribution.H:57
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:963
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)
triSurface()
Default construct.
Definition: triSurface.C:426
Class containing processor-to-processor mapping information.
Non-pointer based hierarchical recursive searching.
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:61
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))
virtual void flip()
Flip triangles, outsideVolumeType and all cached inside/outside.
Defines the attributes of an object for which implicit objectRegistry management is supported...
Definition: IOobject.H:180
constexpr List() noexcept
Default construct.
Definition: ListI.H:116
List< bool > boolList
A List of bools.
Definition: List.H:59
const indexedOctree< treeDataTriSurface > & tree() const
Demand driven construction of the octree.
Namespace for OpenFOAM.
void writeStats(Ostream &os) const
Print some stats. Parallel aware version of.
virtual bool global() const
Is object global.