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