Loading...
Searching...
No Matches
PatchEdgeFaceWave.C
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-2016 OpenFOAM Foundation
9 Copyright (C) 2022 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
27\*---------------------------------------------------------------------------*/
28
29#include "PatchEdgeFaceWave.H"
30#include "polyMesh.H"
31#include "globalMeshData.H"
32#include "PatchTools.H"
33
34// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
35
36// Update info for edgeI, at position pt, with information from
37// neighbouring face.
38// Updates:
39// - changedEdge_, changedEdges_,
40// - statistics: nEvals_, nUnvisitedEdges_
41template
42<
43 class PrimitivePatchType,
44 class Type,
45 class TrackingData
46>
49(
50 const label edgei,
51 const label neighbourFacei,
52 const Type& neighbourInfo,
53 Type& edgeInfo
54)
55{
56 nEvals_++;
57
58 bool wasValid = edgeInfo.valid(td_);
59
60 bool propagate =
61 edgeInfo.updateEdge
62 (
63 mesh_,
64 patch_,
65 edgei,
66 neighbourFacei,
67 neighbourInfo,
68 propagationTol_,
69 td_
70 );
71
72 if (propagate)
73 {
74 if (changedEdge_.set(edgei))
75 {
76 changedEdges_.push_back(edgei);
77 }
78 }
79
80 if (!wasValid && edgeInfo.valid(td_))
81 {
82 --nUnvisitedEdges_;
83 }
84
85 return propagate;
86}
87
88
89// Update info for facei, at position pt, with information from
90// neighbouring edge.
91// Updates:
92// - changedFace_, changedFaces_,
93// - statistics: nEvals_, nUnvisitedFace_
94template
95<
96 class PrimitivePatchType,
97 class Type,
98 class TrackingData
99>
102(
103 const label facei,
104 const label neighbourEdgeI,
105 const Type& neighbourInfo,
106 Type& faceInfo
107)
108{
109 nEvals_++;
110
111 bool wasValid = faceInfo.valid(td_);
112
113 bool propagate =
114 faceInfo.updateFace
115 (
116 mesh_,
117 patch_,
118 facei,
119 neighbourEdgeI,
120 neighbourInfo,
121 propagationTol_,
122 td_
123 );
124
125 if (propagate)
126 {
127 if (changedFace_.set(facei))
128 {
129 changedFaces_.push_back(facei);
130 }
131 }
132
133 if (!wasValid && faceInfo.valid(td_))
134 {
135 --nUnvisitedFaces_;
136 }
137
138 return propagate;
139}
140
141
142template
143<
144 class PrimitivePatchType,
145 class Type,
146 class TrackingData
147>
149syncEdges()
150{
151 const globalMeshData& globalData = mesh_.globalData();
152 const mapDistribute& map = globalData.globalEdgeSlavesMap();
153 const bitSet& cppOrientation = globalData.globalEdgeOrientation();
154
155 // Convert patch-edge data into cpp-edge data
156 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
157
158 //- Construct with all data in consistent orientation
159 List<Type> cppEdgeData(map.constructSize());
160
161 forAll(patchEdges_, i)
162 {
163 label patchEdgeI = patchEdges_[i];
164 label coupledEdgeI = coupledEdges_[i];
165
166 if (changedEdge_.test(patchEdgeI))
167 {
168 const Type& data = allEdgeInfo_[patchEdgeI];
169
170 // Patch-edge data needs to be converted into coupled-edge data
171 // (optionally flipped) and consistent in orientation with
172 // master of coupled edge (optionally flipped)
173 bool sameOrientation =
174 (
175 sameEdgeOrientation_[i]
176 == cppOrientation[coupledEdgeI]
177 );
178
179 cppEdgeData[coupledEdgeI].updateEdge
180 (
181 mesh_,
182 patch_,
183 data,
184 sameOrientation,
185 propagationTol_,
186 td_
187 );
188 }
189 }
190
191
192 // Synchronise
193 // ~~~~~~~~~~~
194
195 globalData.syncData
196 (
197 cppEdgeData,
198 globalData.globalEdgeSlaves(),
199 globalData.globalEdgeTransformedSlaves(),
200 map,
201 globalData.globalTransforms(),
202 updateOp<PrimitivePatchType, Type, TrackingData>
203 (
204 mesh_,
205 patch_,
206 propagationTol_,
207 td_
208 ),
209 transformOp<PrimitivePatchType, Type, TrackingData>
210 (
211 mesh_,
212 patch_,
213 propagationTol_,
214 td_
215 )
216 );
217
218
219 // Back from cpp-edge to patch-edge data
220 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
221
222 forAll(patchEdges_, i)
223 {
224 label patchEdgeI = patchEdges_[i];
225 label coupledEdgeI = coupledEdges_[i];
226
227 const Type& data = cppEdgeData[coupledEdgeI];
228
229 if (data.valid(td_))
230 {
231 bool sameOrientation =
232 (
233 sameEdgeOrientation_[i]
234 == cppOrientation[coupledEdgeI]
235 );
236
237 allEdgeInfo_[patchEdgeI].updateEdge
238 (
239 mesh_,
240 patch_,
241 data,
242 sameOrientation,
243 propagationTol_,
244 td_
245 );
246
247 if (changedEdge_.set(patchEdgeI))
248 {
249 changedEdges_.push_back(patchEdgeI);
250 }
251 }
252 }
253}
254
255
256// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
257
258// Iterate, propagating changedEdgesInfo across patch, until no change (or
259// maxIter reached). Initial edge values specified.
260template
262 class PrimitivePatchType,
263 class Type,
264 class TrackingData
265>
268(
269 const polyMesh& mesh,
270 const PrimitivePatchType& patch,
271 const labelList& changedEdges,
272 const List<Type>& changedEdgesInfo,
273
276
277 const label maxIter,
278 TrackingData& td
279)
280:
281 PatchEdgeFaceWaveBase(mesh, patch.nEdges(), patch.size()),
282 patch_(patch),
283 allEdgeInfo_(allEdgeInfo),
284 allFaceInfo_(allFaceInfo),
285 td_(td),
286 nEvals_(0)
287{
288 // Calculate addressing between patch_ and mesh.globalData().coupledPatch()
289 // for ease of synchronisation
291 (
292 patch_,
293 mesh_.globalData().coupledPatch(),
294
295 patchEdges_,
296 coupledEdges_,
297 sameEdgeOrientation_
298 );
299
300
301 if (allEdgeInfo_.size() != patch_.nEdges())
302 {
304 << "size of edgeInfo work array is not equal to the number"
305 << " of edges in the patch" << nl
306 << " edgeInfo :" << allEdgeInfo_.size() << nl
307 << " patch.nEdges:" << patch_.nEdges() << endl
308 << exit(FatalError);
309 }
310 if (allFaceInfo_.size() != patch_.size())
311 {
313 << "size of edgeInfo work array is not equal to the number"
314 << " of faces in the patch" << nl
315 << " faceInfo :" << allFaceInfo_.size() << nl
316 << " patch.size:" << patch_.size() << endl
317 << exit(FatalError);
318 }
319
320
321 // Set from initial changed edges data
322 setEdgeInfo(changedEdges, changedEdgesInfo);
323
324 if (debug)
325 {
326 Pout<< "Seed edges : " << nChangedEdges() << endl;
327 }
328
329 // Iterate until nothing changes
330 label iter = iterate(maxIter);
331
332 if ((maxIter > 0) && (iter >= maxIter))
333 {
335 << "Maximum number of iterations reached. Increase maxIter." << nl
336 << " maxIter:" << maxIter << nl
337 << " changedEdges:" << nChangedEdges() << nl
338 << " changedFaces:" << nChangedFaces() << endl
339 << exit(FatalError);
340 }
341}
342
343
344template
346 class PrimitivePatchType,
347 class Type,
348 class TrackingData
349>
352(
353 const polyMesh& mesh,
354 const PrimitivePatchType& patch,
357 TrackingData& td
358)
359:
360 PatchEdgeFaceWaveBase(mesh, patch.nEdges(), patch.size()),
361 patch_(patch),
362 allEdgeInfo_(allEdgeInfo),
363 allFaceInfo_(allFaceInfo),
364 td_(td),
365 nEvals_(0)
366{
367 // Calculate addressing between patch_ and mesh.globalData().coupledPatch()
368 // for ease of synchronisation
370 (
371 patch_,
372 mesh_.globalData().coupledPatch(),
373
374 patchEdges_,
375 coupledEdges_,
376 sameEdgeOrientation_
377 );
378}
379
380
381// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
382
383// Copy edge information into member data
384template
386 class PrimitivePatchType,
387 class Type,
388 class TrackingData
389>
392(
393 const labelUList& changedEdges,
394 const UList<Type>& changedEdgesInfo
395)
396{
397 forAll(changedEdges, changedEdgeI)
398 {
399 label edgeI = changedEdges[changedEdgeI];
400
401 bool wasValid = allEdgeInfo_[edgeI].valid(td_);
402
403 // Copy info for edgeI
404 allEdgeInfo_[edgeI] = changedEdgesInfo[changedEdgeI];
405
406 // Maintain count of unset edges
407 if (!wasValid && allEdgeInfo_[edgeI].valid(td_))
408 {
410 }
411
412 // Mark edgeI as changed, both on list and on edge itself.
413
414 if (changedEdge_.set(edgeI))
415 {
416 changedEdges_.push_back(edgeI);
417 }
418 }
419}
420
421
422// Propagate information from face to edge. Return number of edges changed.
423template
425 class PrimitivePatchType,
426 class Type,
427 class TrackingData
428>
431{
432 changedEdges_.clear();
433 changedEdge_ = false;
434
435 for (const label facei : changedFaces_)
436 {
437 if (!changedFace_.test(facei))
438 {
440 << "face " << facei
441 << " not marked as having been changed" << nl
442 << "This might be caused by multiple occurrences of the same"
443 << " seed edge." << abort(FatalError);
444 }
445
446 const Type& neighbourWallInfo = allFaceInfo_[facei];
447
448 // Evaluate all connected edges
449 const labelList& fEdges = patch_.faceEdges()[facei];
450
451 forAll(fEdges, fEdgeI)
452 {
453 label edgeI = fEdges[fEdgeI];
454
455 Type& currentWallInfo = allEdgeInfo_[edgeI];
456
457 if (!currentWallInfo.equal(neighbourWallInfo, td_))
458 {
459 updateEdge
460 (
461 edgeI,
462 facei,
463 neighbourWallInfo,
464 currentWallInfo
465 );
466 }
467 }
468 }
469
470
471 syncEdges();
472
473
474 if (debug)
475 {
476 Pout<< "Changed edges : " << nChangedEdges() << endl;
477 }
478
480}
481
482
483// Propagate information from edge to face. Return number of faces changed.
484template
486 class PrimitivePatchType,
487 class Type,
488 class TrackingData
489>
492{
493 changedFaces_.clear();
494 changedFace_ = false;
495
496 const labelListList& edgeFaces = patch_.edgeFaces();
497
498 for (const label edgei : changedEdges_)
499 {
500 if (!changedEdge_.test(edgei))
501 {
503 << "edge " << edgei
504 << " not marked as having been changed" << nl
505 << "This might be caused by multiple occurrences of the same"
506 << " seed edge." << abort(FatalError);
507 }
508
509 const Type& neighbourWallInfo = allEdgeInfo_[edgei];
510
511 // Evaluate all connected faces
512
513 for (const label facei : edgeFaces[edgei])
514 {
515 Type& currentWallInfo = allFaceInfo_[facei];
516
517 if (!currentWallInfo.equal(neighbourWallInfo, td_))
518 {
519 updateFace
520 (
521 facei,
522 edgei,
523 neighbourWallInfo,
524 currentWallInfo
525 );
526 }
527 }
528 }
529
530 if (debug)
531 {
532 Pout<< "Changed faces : " << nChangedFaces() << endl;
533 }
534
536}
537
538
539// Iterate
540template
542 class PrimitivePatchType,
543 class Type,
544 class TrackingData
545>
548(
549 const label maxIter
550)
551{
552 // Make sure coupled edges contain same info
553 syncEdges();
554
555 nEvals_ = 0;
556
557 label iter = 0;
558
559 while (iter < maxIter)
560 {
561 if (debug)
562 {
563 Pout<< "Iteration " << iter << endl;
564 }
565
566 label nFaces = edgeToFace();
567
568 if (debug)
569 {
570 Pout<< "Total changed faces : " << nFaces << endl;
571 }
572
573 if (nFaces == 0)
574 {
575 break;
576 }
577
578 label nEdges = faceToEdge();
579
580 if (debug)
581 {
582 Pout<< "Total changed edges : " << nEdges << nl
583 << "Total evaluations : " << nEvals_ << nl
584 << "Remaining unvisited edges : " << nUnvisitedEdges_ << nl
585 << "Remaining unvisited faces : " << nUnvisitedFaces_ << nl
586 << endl;
587 }
588
589 if (nEdges == 0)
590 {
591 break;
592 }
593
594 iter++;
595 }
596
597 return iter;
598}
599
600
601// ************************************************************************* //
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition List.H:72
label nChangedFaces() const noexcept
Current number of changed faces.
DynamicList< label > changedFaces_
List of changed faces.
bitSet changedFace_
Track if face has changed.
DynamicList< label > changedEdges_
List of changed edges.
label nChangedEdges() const noexcept
Current number of changed edges.
label nUnvisitedFaces_
Number of unvisited faces.
PatchEdgeFaceWaveBase(const polyMesh &mesh, const label nEdges, const label nFaces)
Construct with mesh reference and set initial sizes.
label nUnvisitedEdges_
Number of unvisited edges.
bitSet changedEdge_
Track if edge has changed.
const polyMesh & mesh() const noexcept
Return access to the mesh.
const polyMesh & mesh_
Reference to mesh.
Wave propagation of information along patch. Every iteration information goes through one layer of fa...
UList< Type > & allFaceInfo() const noexcept
Access allFaceInfo.
label edgeToFace()
Propagate from edge to face.
UList< Type > & allEdgeInfo() const noexcept
Access allEdgeInfo.
label iterate(const label maxIter)
Iterate until no changes or maxIter reached.
label faceToEdge()
Propagate from face to edge.
void setEdgeInfo(const labelUList &changedEdges, const UList< Type > &changedEdgesInfo)
Copy initial data into allEdgeInfo_.
static void matchEdges(const PrimitivePatch< FaceList1, PointField1 > &p1, const PrimitivePatch< FaceList2, PointField2 > &p2, labelList &p1EdgeLabels, labelList &p2EdgeLabels, bitSet &sameOrientation)
Find corresponding edges on patches sharing the same points.
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition UList.H:89
Mesh consisting of general polyhedral cells.
Definition polyMesh.H:79
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition error.H:600
wallPoints::trackData td(isBlockedFace, regionToBlockSize)
Namespace for handling debugging switches.
Definition debug.C:45
List< labelList > labelListList
List of labelList.
Definition labelList.H:38
List< label > labelList
A List of labels.
Definition List.H:62
T returnReduce(const T &value, BinaryOp bop, const int tag=UPstream::msgType(), const int communicator=UPstream::worldComm)
Perform reduction on a copy, using specified binary operation.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition Ostream.H:519
errorManip< error > abort(error &err)
Definition errorManip.H:139
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition errorManip.H:125
UList< label > labelUList
A UList of labels.
Definition UList.H:75
constexpr char nl
The newline '\n' character (0x0a).
Definition Ostream.H:50
#define forAll(list, i)
Loop across all elements in list.
Definition stdFoam.H:299