faceCoupleInfo.H
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2018 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 Class
25  Foam::faceCoupleInfo
26 
27 Description
28  Container for information needed to couple to meshes. When constructed
29  from two meshes and a geometric tolerance finds the corresponding
30  boundary faces.
31 
32  The information it keeps is the set of faces&points (cutFaces,
33  cutPoints) that should replace a set of faces on the master
34  (masterPatch) and a set of faces on the slave (slavePatch)
35 
36 
37  Uses same tolerance to match faces and points on matched faces since
38  they both originate from the same points and the tolerance usually
39  comes from writing these points with limited precision (6 by default)
40 
41  -# Perfect match:
42  - one-to-one match for faces and points.
43  - the cut is always the 'most connected' of the master and slave so
44  multiple master or slave points might point to the same cut point.
45 
46  \verbatim
47  e.g. master:
48 
49  +--+
50  | |
51  | |
52  +--+
53  +--+
54  | |
55  | |
56  +--+
57  slave:
58  +--+
59  | |
60  | |
61  +--+
62  +--+
63  | |
64  | |
65  +--+
66  \endverbatim
67  adding both together creates a singly connected 2x2 cavity so suddenly
68  the duplicate master points and the duplicate slave points all become
69  a single cut point.
70 
71 
72  -# Subdivision match:
73  - Can be constructed from slave being subdivision of master with the
74  polyPatch constructor.
75  - Does not include above shared-point detection!
76 
77  Notes on multiple slave faces per master:
78 
79  As long as
80  - all master edges are present in slave
81  - slave can have extra edges/points/faces BUT all subfaces have to have
82  at least one point on a maste face.
83 
84  \verbatim
85  So master:
86  +-------+
87  | |
88  | |
89  | |
90  | |
91  | |
92  | |
93  | |
94  +-------+
95 
96  slave:
97  +---+---+
98  |\ | /|
99  | \ | / |
100  | \|/ |
101  +---+---+
102  | /|\ |
103  | / | \ |
104  |/ | \|
105  +---+---+
106  is ok.
107  \endverbatim
108 
109  For this kind of matching the order is:
110  - match cutpoint to masterpoint
111  - find those cutEdges that align with a master edge. This gives two sets
112  of cut edges: those that have a master equivalent ('border edges') and
113  those that don't ('internal edges'). The border edges now divide the
114  cutFaces into regions with the same masterFace correspondence.
115  - find cutFaces that are fully determined by the border edges they use.
116  - all cutFaces that are connected through an internal edge have the same
117  master face.
118 
119 
120  Note: matching refined faces onto master is a bit dodgy and will probably
121  only work for unwarped faces. Also it will fail if e.g. face is split
122  into 3x3 since then middle face has no point/edge in common with master.
123  (problem is in face matching (findSlavesCoveringMaster), probably
124  point/edge matching might just work)
125 
126 
127 SourceFiles
128  faceCoupleInfo.C
129 
130 
131 \*---------------------------------------------------------------------------*/
132 
133 #ifndef faceCoupleInfo_H
134 #define faceCoupleInfo_H
135 
136 #include "pointField.H"
137 #include "indirectPrimitivePatch.H"
138 #include "primitiveFacePatch.H"
139 
140 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
141 
142 namespace Foam
143 {
146 
147 
148 // Forward declaration of classes
149 class face;
150 class primitiveMesh;
151 class polyPatch;
152 class polyMesh;
153 
154 /*---------------------------------------------------------------------------*\
155  Class faceCoupleInfo Declaration
156 \*---------------------------------------------------------------------------*/
158 class faceCoupleInfo
159 {
160  // Private data
161 
162  //- Angle matching tolerance.
163  static const scalar angleTol_;
164 
165  //- Master patch
166  autoPtr<indirectPrimitivePatch> masterPatchPtr_;
167 
168  //- Slave patch
169  autoPtr<indirectPrimitivePatch> slavePatchPtr_;
170 
171 
172  //- Description of cut.
173  // - Cut is the matching area between the slave
174  // and the master.
175  // - cut is the finest of master and slave. It can never be
176  // coarser than either one of them. (so face addressing we keep is
177  // cut-to-master and cut-to-slave)
178  // - multiple master or slave points can end up becoming one cut point
179  // (so point addressing we keep is master-to-cut and slave-to-cut)
180 
181  // Cut consists of faces and points (note: could be expressed as some
182  // kind of PrimitivePatch which holds points instead of reference to
183  // them)
184  // Orientation of cutFaces should be same as masterFaces!
185  pointField cutPoints_;
186  autoPtr<primitiveFacePatch> cutFacesPtr_;
187 
188  //- Additional point coupling information. Is between points on
189  // boundary of both meshes.
190 
191  // Addressing to/from cut
192 
193  //- master
194  labelList cutToMasterFaces_;
195  labelList masterToCutPoints_;
196 
197  //- slave
198  labelList cutToSlaveFaces_;
199  labelList slaveToCutPoints_;
200 
201  //- For edges originating from splitting of edges:
202  // given the two endpoints of the unsplit edge give the list
203  // of in between vertices
204  edgeLookup cutEdgeToPoints_;
205 
206 
207  // Private Member Functions
208 
209  // Debugging
210 
211  //- Calculate face centres from (subset of) faces.
212  template<template<class> class FaceList>
213  static pointField calcFaceCentres
214  (
215  const FaceList<face>&,
216  const pointField&,
217  const label start,
218  const label size
219  );
220 
221  //- Calculate face point averages from (subset of) faces.
222  template<template<class> class FaceList>
223  static pointField calcFacePointAverages
224  (
225  const FaceList<face>&,
226  const pointField&,
227  const label start,
228  const label size
229  );
230 
231  //- Write edges
232  static void writeOBJ
233  (
234  const fileName& fName,
235  const edgeList& edges,
236  const pointField& points,
237  const bool compact = true
238  );
239 
240  //- Write edges
241  static void writeOBJ
242  (
243  const fileName& fName,
244  const pointField& points0,
245  const pointField& points1
246  );
247 
248  //- Write connections between corresponding points and faces
249  // as .obj files.
250  void writePointsFaces() const;
251 
252  //- Write connections between corresponding edges as .obj files.
253  void writeEdges(const labelList&, const labelList&) const;
254 
255 
256  // Edge handling/matching
257 
258  //- Find corresponding edges on patch when having only a map for
259  // the points.
260  labelList findMappedEdges
261  (
262  const edgeList& edges,
263  const labelList& pointMap,
265  );
266 
267  //- Check if edge on slavePatch corresponds to an edge between faces
268  // in two different polyPatches on the mesh.
269  bool regionEdge(const polyMesh&, const label slaveEdgeI) const;
270 
271  //- Finds edge connected to point most aligned with master edge.
272  label mostAlignedCutEdge
273  (
274  const bool report,
275  const polyMesh& slaveMesh,
276  const bool patchDivision,
277  const labelList& cutToMasterEdges,
278  const labelList& cutToSlaveEdges,
279  const label pointi,
280  const label edgeStart,
281  const label edgeEnd
282  ) const;
283 
284  //- From (many-to-one) map of cut edges to master edges determine
285  // points in between. I.e. just string up the edges. Stores this
286  // all on cutEdgeToPoints_
287  void setCutEdgeToPoints(const labelList& cutToMasterEdges);
288 
289  // Face matching
290 
291  //- Matches two faces.
292  // Determines rotation for f1 to match up with f0,
293  // i.e. the index in f0 of the first point of f1.
294  static label matchFaces
295  (
296  const scalar absTol,
297  const pointField& points0,
298  const face& f0,
299  const pointField& points1,
300  const face& f1,
301  const bool sameOrientation
302  );
303 
304  //- Matches points on patch to points on cut.
305  static bool matchPointsThroughFaces
306  (
307  const scalar absTol,
308  const pointField& cutPoints,
309  const faceList& cutFaces,
310  const pointField& patchPoints,
311  const faceList& patchFaces,
312  const bool sameOrientation,
313 
314  labelList& patchToCutPoints,// patch to (uncompacted) cut points
315  labelList& cutToCompact, // compaction list
316  labelList& compactToCut // compaction list
317  );
318 
319  //- Returns max distance to masterF of any point on cutF.
320  static scalar maxDistance
321  (
322  const face& cutF,
323  const pointField& cutPoints,
324  const face& masterF,
325  const pointField& masterPoints
326  );
327 
328  //- Finds matching (boundary)face centres.
329  // Since faces identical uses geometric match on face centres.
330  static void findPerfectMatchingFaces
331  (
332  const primitiveMesh& mesh0,
333  const primitiveMesh& mesh1,
334  const scalar absTol,
335 
336  labelList& mesh0Faces,
337  labelList& mesh1Faces
338  );
339 
340  //- Find matching (boundary)faces. Matching if slave is on top of
341  // master face (slaves is subdivision of master)
342  static void findSlavesCoveringMaster
343  (
344  const primitiveMesh& mesh0,
345  const primitiveMesh& mesh1,
346  const scalar absTol,
347 
348  labelList& mesh0Faces,
349  labelList& mesh1Faces
350  );
351 
352  //- Grow cutToMasterFace across 'internal' edges.
353  label growCutFaces(const labelList&, Map<labelList>&);
354 
355  void checkMatch(const labelList& cutToMasterEdges) const;
356 
357  //- Gets a list of cutFaces (that use a master edge) and the
358  // candidate master faces.
359  // Checks among these master faces if there is only one remaining
360  // unmatched one.
361  label matchEdgeFaces(const labelList&, Map<labelList>& candidates);
362 
363  //- Gets a list of cutFaces (that use a master edge) and the
364  // candidate master faces.
365  // Finds most aligned master face.
366  label geometricMatchEdgeFaces(Map<labelList>& candidates);
367 
368  //- Used by perfectPointMatch. Determine match from cut points to
369  // slave points (for perfect matching faces)
370  void perfectSlavePointMatch(const scalar absTol);
371 
372  //- Find point and edge correspondence for perfect matching faces
373  void perfectPointMatch(const scalar absTol, const bool);
374 
375  //- Find point and edge correspondence for slaves being subdivision of
376  // master.
377  void subDivisionMatch
378  (
379  const polyMesh& slaveMesh,
380  const bool patchDivision,
381  const scalar absTol
382  );
383 
384 public:
385 
386  //- Runtime type information
387  ClassName("faceCoupleInfo");
388 
389 
390  // Constructors
391 
392  //- Construct from two meshes and absolute tolerance.
393  // Finds out matches geometrically. No checking for nonsense match.
394  // Tolerance is absolute one so use with care.
395  // perfectMatch : each point/edge/face has corresponding point on other
396  // side
397  // if this is false then assumes slave is subdivision.
398  // Matching then will work only for non-warped faces
399  // since does nearest-to-face comparison with absTol.
401  (
402  const polyMesh& mesh0,
403  const polyMesh& mesh1,
404  const scalar absTol,
405  const bool perfectMatch
406  );
407 
408  //- Construct from meshes and subset of mesh faces
409  // (i.e. indirectPrimitivePatch addressing)
410  // All faces in patch are considered matched (but don't have to be
411  // ordered)
412  // perfectMatch : each point/edge/face has corresponding point on other
413  // side
414  // orderedFaces : faces in patch are ordered (so masterAddressing[i]
415  // matches slaveAddressing[i])
416  // patchDivision: faces in slave mesh that originate from the
417  // same master face have the same patch. Used by some triangulation
418  // methods.
420  (
421  const polyMesh& masterMesh,
422  const labelList& masterAddressing,
423  const polyMesh& slaveMesh,
424  const labelList& slaveAddressing,
425  const scalar absTol,
426  const bool perfectMatch,
427  const bool orderedFaces,
428  const bool patchDivision
429  );
430 
431 
432  //- Destructor
433  ~faceCoupleInfo();
434 
435 
436 
437  // Member Functions
438 
439  //- Utility functions
440 
441  //- Get patch face labels
442  static labelList faceLabels(const polyPatch&);
443 
444  //- Create Map from List
445  static Map<label> makeMap(const labelList&);
446  static Map<labelList> makeMap(const labelListList&);
447 
448 
449  // Access
450 
451  //- Addressing engine for coupled faces on mesh0
452  const indirectPrimitivePatch& masterPatch() const
453  {
454  return masterPatchPtr_();
455  }
456 
457  //- Addressing engine for coupled faces on mesh1
458  const indirectPrimitivePatch& slavePatch() const
459  {
460  return slavePatchPtr_();
461  }
462 
463  //- Addressing engine for combined set of faces.
464  const primitiveFacePatch& cutFaces() const
465  {
466  return cutFacesPtr_();
467  }
468 
469  //- Points for combined set of faces.
470  const pointField& cutPoints() const
471  {
472  return cutPoints_;
473  }
474 
475 
476  // Addressing from meshes to cut and vice versa.
477 
478  //- Master face for every face on cut. Will always be at least
479  // one but there might be multiple cut faces pointing to the same
480  // master
481  const labelList& cutToMasterFaces() const
482  {
483  return cutToMasterFaces_;
484  }
485  const labelList& masterToCutPoints() const
486  {
487  return masterToCutPoints_;
488  }
490  const labelList& cutToSlaveFaces() const
491  {
492  return cutToSlaveFaces_;
493  }
494  const labelList& slaveToCutPoints() const
495  {
496  return slaveToCutPoints_;
497  }
498 
499  //- From two cut points (original edge) to list of inserted
500  // points
501  const edgeLookup& cutEdgeToPoints() const
502  {
503  return cutEdgeToPoints_;
504  }
505 
506  };
507 
508 
509 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
510 
511 } // End namespace Foam
512 
513 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
514 
515 #ifdef NoRepository
516  #include "faceCoupleInfoTemplates.C"
517 #endif
518 
519 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
520 
521 #endif
522 
523 // ************************************************************************* //
const indirectPrimitivePatch & slavePatch() const
Addressing engine for coupled faces on mesh1.
static labelList faceLabels(const polyPatch &)
Utility functions.
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
faceCoupleInfo(const polyMesh &mesh0, const polyMesh &mesh1, const scalar absTol, const bool perfectMatch)
Construct from two meshes and absolute tolerance.
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:75
Cell-face mesh analysis engine.
Definition: primitiveMesh.H:74
const indirectPrimitivePatch & masterPatch() const
Addressing engine for coupled faces on mesh0.
const pointField & cutPoints() const
Points for combined set of faces.
const primitiveFacePatch & cutFaces() const
Addressing engine for combined set of faces.
scalar f1
Definition: createFields.H:28
Container for information needed to couple to meshes. When constructed from two meshes and a geometri...
A list of faces which address into the list of points.
const pointField & points
const labelList & cutToSlaveFaces() const
An STL-conforming hash table.
Definition: HashTable.H:62
~faceCoupleInfo()
Destructor.
static Map< label > makeMap(const labelList &)
Create Map from List.
const labelList & slaveToCutPoints() const
const labelList & masterToCutPoints() const
HashTable< labelList, edge, Hash< edge > > edgeLookup
An auto-pointer similar to the STL auto_ptr but with automatic casting to a reference to the type and...
Definition: PtrList.H:52
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:74
ClassName("faceCoupleInfo")
Runtime type information.
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:66
const edgeLookup & cutEdgeToPoints() const
From two cut points (original edge) to list of inserted.
const labelList & cutToMasterFaces() const
Master face for every face on cut. Will always be at least.
Namespace for OpenFOAM.
A HashTable to objects of type <T> with a label key.
Definition: Map.H:49