FreeFOAM The Cross-Platform CFD Toolkit
faceCoupleInfo.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 | Copyright (C) 1991-2010 OpenCFD Ltd.
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 <OpenFOAM/pointField.H>
139 
140 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
141 
142 namespace Foam
143 {
144 
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 \*---------------------------------------------------------------------------*/
157 
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 inbetween 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  //- Write edges
222  static void writeOBJ
223  (
224  const fileName& fName,
225  const edgeList& edges,
226  const pointField& points,
227  const bool compact = true
228  );
229 
230  //- Write edges
231  static void writeOBJ
232  (
233  const fileName& fName,
234  const pointField& points0,
235  const pointField& points1
236  );
237 
238  //- Write connections between corresponding points and faces
239  // as .obj files.
240  void writePointsFaces() const;
241 
242  //- Write connections between corresponding edges as .obj files.
243  void writeEdges(const labelList&, const labelList&) const;
244 
245 
246  // Edge handling/matching
247 
248  //- Find corresponding edges on patch when having only a map for
249  // the points.
250  labelList findMappedEdges
251  (
252  const edgeList& edges,
253  const labelList& pointMap,
255  );
256 
257  //- Check if edge on slavePatch corresponds to an edge between faces
258  // in two different polyPatches on the mesh.
259  bool regionEdge(const polyMesh&, const label slaveEdgeI) const;
260 
261  //- Finds edge connected to point most aligned with master edge.
262  label mostAlignedCutEdge
263  (
264  const bool report,
265  const polyMesh& slaveMesh,
266  const bool patchDivision,
267  const labelList& cutToMasterEdges,
268  const labelList& cutToSlaveEdges,
269  const label pointI,
270  const label edgeStart,
271  const label edgeEnd
272  ) const;
273 
274  //- From (many-to-one) map of cut edges to master edges determine
275  // points inbetween. I.e. just string up the edges. Stores this
276  // all on cutEdgeToPoints_
277  void setCutEdgeToPoints(const labelList& cutToMasterEdges);
278 
279  // Face matching
280 
281  //- Matches two faces.Determines rotation for f1 to match up
282  // with f0, i.e. the index in f0 of
283  // the first point of f1.
284  static label matchFaces
285  (
286  const scalar absTol,
287  const pointField& points0,
288  const face& f0,
289  const pointField& points1,
290  const face& f1,
291  const bool sameOrientation
292  );
293 
294  //- Matches points on patch to points on cut.
295  static bool matchPointsThroughFaces
296  (
297  const scalar absTol,
298  const pointField& cutPoints,
299  const faceList& cutFaces,
300  const pointField& patchPoints,
301  const faceList& patchFaces,
302  const bool sameOrientation,
303 
304  labelList& patchToCutPoints, // patch to (uncompacted) cut points
305  labelList& cutToCompact, // compaction list
306  labelList& compactToCut // compaction list
307  );
308 
309  //- Returns max distance to masterF of any point on cutF.
310  static scalar maxDistance
311  (
312  const face& cutF,
313  const pointField& cutPoints,
314  const face& masterF,
315  const pointField& masterPoints
316  );
317 
318  //- Finds matching (boundary)face centres.
319  // Since faces identical uses geometric match on face centres.
320  static void findPerfectMatchingFaces
321  (
322  const primitiveMesh& mesh0,
323  const primitiveMesh& mesh1,
324  const scalar absTol,
325 
326  labelList& mesh0Faces,
327  labelList& mesh1Faces
328  );
329 
330  //- Find matching (boundary)faces. Matching if slave is on top of
331  // master face (slaves is subdivision of master)
332  static void findSlavesCoveringMaster
333  (
334  const primitiveMesh& mesh0,
335  const primitiveMesh& mesh1,
336  const scalar absTol,
337 
338  labelList& mesh0Faces,
339  labelList& mesh1Faces
340  );
341 
342  //- Grow cutToMasterFace across 'internal' edges.
343  label growCutFaces(const labelList&, Map<labelList>&);
344 
345  void checkMatch(const labelList& cutToMasterEdges) const;
346 
347  //- Gets a list of cutFaces (that use a master edge) and the
348  // candidate master faces.
349  // Checks among these master faces if there is only one remaining
350  // unmatched one.
351  label matchEdgeFaces(const labelList&, Map<labelList>& candidates);
352 
353  //- Gets a list of cutFaces (that use a master edge) and the
354  // candidate master faces.
355  // Finds most aligned master face.
356  label geometricMatchEdgeFaces(Map<labelList>& candidates);
357 
358  //- Used by perfectPointMatch. Determine match from cut points to
359  // slave points (for perfect matching faces)
360  void perfectSlavePointMatch(const scalar absTol);
361 
362  //- Find point and edge correspondence for perfect matching faces
363  void perfectPointMatch(const scalar absTol, const bool);
364 
365  //- Find point and edge correspondence for slaves being subdivision of
366  // master.
367  void subDivisionMatch
368  (
369  const polyMesh& slaveMesh,
370  const bool patchDivision,
371  const scalar absTol
372  );
373 
374 public:
375 
376  //- Runtime type information
377  ClassName("faceCoupleInfo");
378 
379 
380  // Constructors
381 
382  //- Construct from two meshes and absolute tolerance.
383  // Finds out matches geometrically. No checking for nonsense match.
384  // Tolerance is absolute one so use with care.
385  // perfectMatch : each point/edge/face has corresponding point on other
386  // side
387  // if this is false then assumes slave is subdivision.
388  // Matching then will work only for non-warped faces
389  // since does nearest-to-face comparison with absTol.
391  (
392  const polyMesh& mesh0,
393  const polyMesh& mesh1,
394  const scalar absTol,
395  const bool perfectMatch
396  );
397 
398  //- Construct from meshes and subset of mesh faces
399  // (i.e. indirectPrimitivePatch addressing)
400  // All faces in patch are considered matched (but don't have to be
401  // ordered)
402  // perfectMatch : each point/edge/face has corresponding point on other
403  // side
404  // orderedFaces : faces in patch are ordered (so masterAddressing[i]
405  // matches slaveAddressing[i])
406  // patchDivision: faces in slave mesh that originate from the
407  // same master face have the same patch. Used by some triangulation
408  // methods.
410  (
411  const polyMesh& masterMesh,
412  const labelList& masterAddressing,
413  const polyMesh& slaveMesh,
414  const labelList& slaveAddressing,
415  const scalar absTol,
416  const bool perfectMatch,
417  const bool orderedFaces,
418  const bool patchDivision
419  );
420 
421 
422  // Destructor
423 
424  ~faceCoupleInfo();
425 
426 
427 
428  // Member Functions
429 
430  //- Utility functions
431 
432  //- Get patch face labels
433  static labelList faceLabels(const polyPatch&);
434 
435  //- Create Map from List
436  static Map<label> makeMap(const labelList&);
437  static Map<labelList> makeMap(const labelListList&);
438 
439 
440  // Access
441 
442  //- Addressing engine for coupled faces on mesh0
444  {
445  return masterPatchPtr_();
446  }
447 
448  //- Addressing engine for coupled faces on mesh1
450  {
451  return slavePatchPtr_();
452  }
453 
454  //- Addressing engine for combined set of faces.
456  {
457  return cutFacesPtr_();
458  }
459 
460  //- Points for combined set of faces.
461  const pointField& cutPoints() const
462  {
463  return cutPoints_;
464  }
465 
466 
467  // Addressing from meshes to cut and vice versa.
468 
469  //- Master face for every face on cut. Will always be at least
470  // one but there might be multiple cut faces pointing to the same
471  // master
473  {
474  return cutToMasterFaces_;
475  }
477  {
478  return masterToCutPoints_;
479  }
480 
481  const labelList& cutToSlaveFaces() const
482  {
483  return cutToSlaveFaces_;
484  }
486  {
487  return slaveToCutPoints_;
488  }
489 
490  //- From two cut points (original edge) to list of inserted
491  // points
493  {
494  return cutEdgeToPoints_;
495  }
496 
497  };
498 
499 
500 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
501 
502 } // End namespace Foam
503 
504 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
505 
506 #ifdef NoRepository
508 #endif
509 
510 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
511 
512 #endif
513 
514 // ************************ vim: set sw=4 sts=4 et: ************************ //