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