1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
7 -------------------------------------------------------------------------------
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
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
29 Container for information needed to couple to meshes. When constructed
30 from two meshes and a geometric tolerance finds the corresponding
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)
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.
68 adding both together creates a singly connected 2x2 cavity so suddenly
69 the duplicate master points and the duplicate slave points all become
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:
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.
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
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)
132 \*---------------------------------------------------------------------------*/
134 #ifndef faceCoupleInfo_H
135 #define faceCoupleInfo_H
137 #include "pointField.H"
138 #include "indirectPrimitivePatch.H"
139 #include "primitiveFacePatch.H"
141 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
146 typedef HashTable<labelList, edge, Hash<edge> > edgeLookup;
149 // Forward declaration of classes
155 /*---------------------------------------------------------------------------*\
156 Class faceCoupleInfo Declaration
157 \*---------------------------------------------------------------------------*/
163 //- Angle matching tolerance.
164 static const scalar angleTol_;
167 autoPtr<indirectPrimitivePatch> masterPatchPtr_;
170 autoPtr<indirectPrimitivePatch> slavePatchPtr_;
173 //- Description of cut.
174 // - Cut is the matching area between the slave
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
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
195 labelList cutToMasterFaces_;
196 labelList masterToCutPoints_;
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
212 //- Calculate face centres from (subset of) faces.
213 template<template<class> class FaceList>
214 static pointField calcFaceCentres
216 const FaceList<face>&,
225 const fileName& fName,
226 const edgeList& edges,
227 const pointField& points,
228 const bool compact = true
234 const fileName& fName,
235 const pointField& points0,
236 const pointField& points1
239 //- Write connections between corresponding points and faces
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
251 labelList findMappedEdges
253 const edgeList& edges,
254 const labelList& pointMap,
255 const indirectPrimitivePatch&
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
266 const polyMesh& slaveMesh,
267 const bool patchDivision,
268 const labelList& cutToMasterEdges,
269 const labelList& cutToSlaveEdges,
271 const label edgeStart,
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);
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
288 const pointField& points0,
290 const pointField& points1,
292 const bool sameOrientation
295 //- Matches points on patch to points on cut.
296 static bool matchPointsThroughFaces
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
310 //- Returns max distance to masterF of any point on cutF.
311 static scalar maxDistance
314 const pointField& cutPoints,
316 const pointField& masterPoints
319 //- Finds matching (boundary)face centres.
320 // Since faces identical uses geometric match on face centres.
321 static void findPerfectMatchingFaces
323 const primitiveMesh& mesh0,
324 const primitiveMesh& mesh1,
327 labelList& mesh0Faces,
328 labelList& mesh1Faces
331 //- Find matching (boundary)faces. Matching if slave is on top of
332 // master face (slaves is subdivision of master)
333 static void findSlavesCoveringMaster
335 const primitiveMesh& mesh0,
336 const primitiveMesh& mesh1,
339 labelList& mesh0Faces,
340 labelList& mesh1Faces
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
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
368 void subDivisionMatch
370 const polyMesh& slaveMesh,
371 const bool patchDivision,
377 //- Runtime type information
378 ClassName("faceCoupleInfo");
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
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.
393 const polyMesh& mesh0,
394 const polyMesh& mesh1,
396 const bool perfectMatch
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
403 // perfectMatch : each point/edge/face has corresponding point on other
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
412 const polyMesh& masterMesh,
413 const labelList& masterAddressing,
414 const polyMesh& slaveMesh,
415 const labelList& slaveAddressing,
417 const bool perfectMatch,
418 const bool orderedFaces,
419 const bool patchDivision
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&);
443 //- Addressing engine for coupled faces on mesh0
444 const indirectPrimitivePatch& masterPatch() const
446 return masterPatchPtr_();
449 //- Addressing engine for coupled faces on mesh1
450 const indirectPrimitivePatch& slavePatch() const
452 return slavePatchPtr_();
455 //- Addressing engine for combined set of faces.
456 const primitiveFacePatch& cutFaces() const
458 return cutFacesPtr_();
461 //- Points for combined set of faces.
462 const pointField& cutPoints() const
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
473 const labelList& cutToMasterFaces() const
475 return cutToMasterFaces_;
477 const labelList& masterToCutPoints() const
479 return masterToCutPoints_;
482 const labelList& cutToSlaveFaces() const
484 return cutToSlaveFaces_;
486 const labelList& slaveToCutPoints() const
488 return slaveToCutPoints_;
491 //- From two cut points (original edge) to list of inserted
493 const edgeLookup& cutEdgeToPoints() const
495 return cutEdgeToPoints_;
501 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
503 } // End namespace Foam
505 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
508 # include "faceCoupleInfoTemplates.C"
511 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
515 // ************************************************************************* //