1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 1991-2010 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
13 the Free Software Foundation, either version 3 of the License, or
14 (at your 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, see <http://www.gnu.org/licenses/>.
28 Container for information needed to couple to meshes. When constructed
29 from two meshes and a geometric tolerance finds the corresponding
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)
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)
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.
67 adding both together creates a singly connected 2x2 cavity so suddenly
68 the duplicate master points and the duplicate slave points all become
73 - Can be constructed from slave being subdivision of master with the
74 polyPatch constructor.
75 - Does not include above shared-point detection!
77 Notes on multiple slave faces per master:
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.
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
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)
131 \*---------------------------------------------------------------------------*/
133 #ifndef faceCoupleInfo_H
134 #define faceCoupleInfo_H
136 #include "pointField.H"
137 #include "indirectPrimitivePatch.H"
138 #include "primitiveFacePatch.H"
140 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
145 typedef HashTable<labelList, edge, Hash<edge> > edgeLookup;
148 // Forward declaration of classes
154 /*---------------------------------------------------------------------------*\
155 Class faceCoupleInfo Declaration
156 \*---------------------------------------------------------------------------*/
162 //- Angle matching tolerance.
163 static const scalar angleTol_;
166 autoPtr<indirectPrimitivePatch> masterPatchPtr_;
169 autoPtr<indirectPrimitivePatch> slavePatchPtr_;
172 //- Description of cut.
173 // - Cut is the matching area between the slave
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)
181 // Cut consists of faces and points (note: could be expressed as some
182 // kind of PrimitivePatch which holds points instead of reference to
184 // Orientation of cutFaces should be same as masterFaces!
185 pointField cutPoints_;
186 autoPtr<primitiveFacePatch> cutFacesPtr_;
188 //- Additional point coupling information. Is between points on
189 // boundary of both meshes.
191 // Addressing to/from cut
194 labelList cutToMasterFaces_;
195 labelList masterToCutPoints_;
198 labelList cutToSlaveFaces_;
199 labelList slaveToCutPoints_;
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_;
207 // Private Member Functions
211 //- Calculate face centres from (subset of) faces.
212 template<template<class> class FaceList>
213 static pointField calcFaceCentres
215 const FaceList<face>&,
224 const fileName& fName,
225 const edgeList& edges,
226 const pointField& points,
227 const bool compact = true
233 const fileName& fName,
234 const pointField& points0,
235 const pointField& points1
238 //- Write connections between corresponding points and faces
240 void writePointsFaces() const;
242 //- Write connections between corresponding edges as .obj files.
243 void writeEdges(const labelList&, const labelList&) const;
246 // Edge handling/matching
248 //- Find corresponding edges on patch when having only a map for
250 labelList findMappedEdges
252 const edgeList& edges,
253 const labelList& pointMap,
254 const indirectPrimitivePatch&
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;
261 //- Finds edge connected to point most aligned with master edge.
262 label mostAlignedCutEdge
265 const polyMesh& slaveMesh,
266 const bool patchDivision,
267 const labelList& cutToMasterEdges,
268 const labelList& cutToSlaveEdges,
270 const label edgeStart,
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);
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
287 const pointField& points0,
289 const pointField& points1,
291 const bool sameOrientation
294 //- Matches points on patch to points on cut.
295 static bool matchPointsThroughFaces
298 const pointField& cutPoints,
299 const faceList& cutFaces,
300 const pointField& patchPoints,
301 const faceList& patchFaces,
302 const bool sameOrientation,
304 labelList& patchToCutPoints, // patch to (uncompacted) cut points
305 labelList& cutToCompact, // compaction list
306 labelList& compactToCut // compaction list
309 //- Returns max distance to masterF of any point on cutF.
310 static scalar maxDistance
313 const pointField& cutPoints,
315 const pointField& masterPoints
318 //- Finds matching (boundary)face centres.
319 // Since faces identical uses geometric match on face centres.
320 static void findPerfectMatchingFaces
322 const primitiveMesh& mesh0,
323 const primitiveMesh& mesh1,
326 labelList& mesh0Faces,
327 labelList& mesh1Faces
330 //- Find matching (boundary)faces. Matching if slave is on top of
331 // master face (slaves is subdivision of master)
332 static void findSlavesCoveringMaster
334 const primitiveMesh& mesh0,
335 const primitiveMesh& mesh1,
338 labelList& mesh0Faces,
339 labelList& mesh1Faces
342 //- Grow cutToMasterFace across 'internal' edges.
343 label growCutFaces(const labelList&, Map<labelList>&);
345 void checkMatch(const labelList& cutToMasterEdges) const;
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
351 label matchEdgeFaces(const labelList&, Map<labelList>& candidates);
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);
358 //- Used by perfectPointMatch. Determine match from cut points to
359 // slave points (for perfect matching faces)
360 void perfectSlavePointMatch(const scalar absTol);
362 //- Find point and edge correspondence for perfect matching faces
363 void perfectPointMatch(const scalar absTol, const bool);
365 //- Find point and edge correspondence for slaves being subdivision of
367 void subDivisionMatch
369 const polyMesh& slaveMesh,
370 const bool patchDivision,
376 //- Runtime type information
377 ClassName("faceCoupleInfo");
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
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.
392 const polyMesh& mesh0,
393 const polyMesh& mesh1,
395 const bool perfectMatch
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
402 // perfectMatch : each point/edge/face has corresponding point on other
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
411 const polyMesh& masterMesh,
412 const labelList& masterAddressing,
413 const polyMesh& slaveMesh,
414 const labelList& slaveAddressing,
416 const bool perfectMatch,
417 const bool orderedFaces,
418 const bool patchDivision
430 //- Utility functions
432 //- Get patch face labels
433 static labelList faceLabels(const polyPatch&);
435 //- Create Map from List
436 static Map<label> makeMap(const labelList&);
437 static Map<labelList> makeMap(const labelListList&);
442 //- Addressing engine for coupled faces on mesh0
443 const indirectPrimitivePatch& masterPatch() const
445 return masterPatchPtr_();
448 //- Addressing engine for coupled faces on mesh1
449 const indirectPrimitivePatch& slavePatch() const
451 return slavePatchPtr_();
454 //- Addressing engine for combined set of faces.
455 const primitiveFacePatch& cutFaces() const
457 return cutFacesPtr_();
460 //- Points for combined set of faces.
461 const pointField& cutPoints() const
467 // Addressing from meshes to cut and vice versa.
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
472 const labelList& cutToMasterFaces() const
474 return cutToMasterFaces_;
476 const labelList& masterToCutPoints() const
478 return masterToCutPoints_;
481 const labelList& cutToSlaveFaces() const
483 return cutToSlaveFaces_;
485 const labelList& slaveToCutPoints() const
487 return slaveToCutPoints_;
490 //- From two cut points (original edge) to list of inserted
492 const edgeLookup& cutEdgeToPoints() const
494 return cutEdgeToPoints_;
500 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
502 } // End namespace Foam
504 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
507 # include "faceCoupleInfoTemplates.C"
510 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
514 // ************************************************************************* //