cyclicAMIPolyPatchTopologyChange.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) 2019-2020 OpenCFD Ltd.
9-------------------------------------------------------------------------------
10License
11 This file is part of OpenFOAM.
12
13 OpenFOAM is free software: you can redistribute it and/or modify it
14 under the terms of the GNU General Public License as published by
15 the Free Software Foundation, either version 3 of the License, or
16 (at your option) any later version.
17
18 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25
26\*---------------------------------------------------------------------------*/
27
28#include "cyclicAMIPolyPatch.H"
29#include "SubField.H"
30#include "vectorList.H"
31#include "polyTopoChange.H"
32
33// * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * * //
34
36{
38
39 // Note: only used for topology update (createAMIFaces_ flag)
40 if (!createAMIFaces_)
41 {
43 << "Attempted to perform topology update when createAMIFaces_ "
44 << "flag is set to false"
45 << abort(FatalError);
46 }
47
48 if (boundaryMesh().mesh().hasCellVolumes())
49 {
51 << "Mesh already has volumes set!"
52 << endl;
53 }
54
57
59 << "Patch:" << name() << " before: sum(mag(faceAreas)):"
60 << gSum(mag(faceAreas)) << nl
61 << "Patch:" << name() << " before: sum(mag(faceAreas0)):"
62 << gSum(mag(faceAreas0_)) << endl;
63
66 {
67 DebugInfo << "Moving face centres" << endl;
69 }
70
73
75 << "Patch:" << name() << " after: sum(mag(faceAreas)):"
76 << gSum(mag(faceAreas)) << nl
77 << "Patch:" << name() << " after: sum(mag(faceAreas0)):"
78 << gSum(mag(faceAreas0_)) << endl;
79}
80
81
83{
85
86 // Note: only used for topology update (createAMIFaces_ flag)
87 if (!createAMIFaces_)
88 {
90 << "Attempted to perform topology update when createAMIFaces_ "
91 << "flag is set to false"
92 << abort(FatalError);
93 }
94
95 if (!owner())
96 {
97 return false;
98 }
99
100 bool changeRequired = false;
101
102 // Remove any faces that we inserted to create the 1-to-1 match...
103
104 const cyclicAMIPolyPatch& nbr = neighbPatch();
105
106 const label newSrcFaceStart = srcFaceIDs_.size();
107
108 if (newSrcFaceStart != 0)
109 {
110 for (label facei = newSrcFaceStart; facei < size(); ++facei)
111 {
112 changeRequired = true;
113 label meshFacei = start() + facei;
114 topoChange.removeFace(meshFacei, -1);
115 }
116 }
117
118 const label newTgtFaceStart = tgtFaceIDs_.size();
119
120 if (newTgtFaceStart != 0)
121 {
122 for (label facei = newTgtFaceStart; facei < nbr.size(); ++facei)
123 {
124 changeRequired = true;
125 label meshFacei = nbr.start() + facei;
126 topoChange.removeFace(meshFacei, -1);
127 }
128 }
129
130 srcFaceIDs_.clear();
131 tgtFaceIDs_.clear();
132
133 return changeRequired;
134}
135
136
138{
140
141 // Note: only used for topology update (createAMIFaces_ flag = true)
142 if (!createAMIFaces_)
143 {
145 << "Attempted to perform topology update when createAMIFaces_ "
146 << "flag is set to false"
147 << abort(FatalError);
148 }
149
150 bool changedFaces = false;
151 const cyclicAMIPolyPatch& nbr = neighbPatch();
152
153 polyMesh& mesh = const_cast<polyMesh&>(boundaryMesh().mesh());
154 const faceZoneMesh& faceZones = mesh.faceZones();
155
156 // First face address and weight are used to manipulate the
157 // original face - all other addresses and weights are used to
158 // create additional faces
159 const labelListList& srcToTgtAddr = AMI().srcAddress();
160 const labelListList& tgtToSrcAddr = AMI().tgtAddress();
161
162 const label nSrcFace = srcToTgtAddr.size();
163 const label nTgtFace = tgtToSrcAddr.size();
164
165 srcFaceIDs_.setSize(nSrcFace);
166 tgtFaceIDs_.setSize(nTgtFace);
167
168 label nNewSrcFaces = 0;
169 forAll(srcToTgtAddr, srcFacei)
170 {
171 const labelList& tgtAddr = srcToTgtAddr[srcFacei];
172
173 // No tgt faces linked to srcFacei (ACMI)
174 if (tgtAddr.empty()) continue;
175
176 srcFaceIDs_[srcFacei].setSize(tgtAddr.size());
177 srcFaceIDs_[srcFacei][0] = srcFacei;
178
179 const label meshFacei = start() + srcFacei;
180 for (label addri = 1; addri < tgtAddr.size(); ++addri)
181 {
182 changedFaces = true;
183
184 // Note: new faces reuse originating face points
185 // - but areas are scaled by the weights (later)
186
187 // New source face for each target face address
188 srcFaceIDs_[srcFacei][addri] = nNewSrcFaces + nSrcFace;
189 ++nNewSrcFaces;
190 (void)topoChange.addFace
191 (
192 mesh.faces()[meshFacei], // modified face
193 mesh.faceOwner()[meshFacei], // owner
194 -1, // neighbour
195 -1, // master point
196 -1, // master edge
197 meshFacei, // master face
198 false, // face flip
199 index(), // patch for face
200 faceZones.whichZone(meshFacei), // zone for original face
201 false // face flip in zone
202 );
203 }
204 }
205
206 label nNewTgtFaces = 0;
207 forAll(tgtToSrcAddr, tgtFacei)
208 {
209 const labelList& srcAddr = tgtToSrcAddr[tgtFacei];
210
211 // No src faces linked to tgtFacei (ACMI)
212 if (srcAddr.empty()) continue;
213
214 tgtFaceIDs_[tgtFacei].setSize(srcAddr.size());
215 tgtFaceIDs_[tgtFacei][0] = tgtFacei;
216
217 const label meshFacei = nbr.start() + tgtFacei;
218 for (label addri = 1; addri < srcAddr.size(); ++addri)
219 {
220 changedFaces = true;
221
222 // Note: new faces reuse originating face points
223 // - but areas are scaled by the weights (later)
224
225 // New target face for each source face address
226 tgtFaceIDs_[tgtFacei][addri] = nNewTgtFaces + nTgtFace;
227 ++nNewTgtFaces;
228
229 (void)topoChange.addFace
230 (
231 mesh.faces()[meshFacei], // modified face
232 mesh.faceOwner()[meshFacei], // owner
233 -1, // neighbour
234 -1, // master point
235 -1, // master edge
236 meshFacei, // master face
237 false, // face flip
238 nbr.index(), // patch for face
239 faceZones.whichZone(meshFacei), // zone for original face
240 false // face flip in zone
241 );
242 }
243 }
244
245 Info<< "AMI: Patch " << name() << " additional faces: "
246 << returnReduce(nNewSrcFaces, sumOp<label>()) << nl
247 << "AMI: Patch " << nbr.name() << " additional faces: "
248 << returnReduce(nNewTgtFaces, sumOp<label>())
249 << endl;
250
251 if (debug)
252 {
253 Pout<< "New faces - " << name() << ": " << nNewSrcFaces
254 << " " << nbr.name() << ": " << nNewTgtFaces << endl;
255 }
256
257 return returnReduce(changedFaces, orOp<bool>());
258}
259
260
262{
263 // Create new mesh faces so that there is a 1-to-1 correspondence
264 // between faces on each side of the AMI
265
266 // Note: only used for topology update (createAMIFaces_ flag)
267 if (!createAMIFaces_)
268 {
270 << "Attempted to perform topology update when createAMIFaces_ "
271 << "flag is set to false"
272 << abort(FatalError);
273 }
274
275
277
278 if (!owner())
279 {
280 return;
281 }
282
283 const cyclicAMIPolyPatch& nbr = neighbPatch();
284
285 vectorField& nbrFaceAreas0 = nbr.faceAreas0();
286 vectorField& nbrFaceCentres0 = nbr.faceCentres0();
287
288 // Scale the new face areas and set the centroids
289 // Note:
290 // - storing local copies so that they can be re-applied after the call to
291 // movePoints that will reset any changes to the areas and centroids
292 //
293 // - For AMI, src and tgt patches should be the same
294 // - For ACMI they are likely to be different!
295 faceAreas0_ = faceAreas();
296 faceCentres0_ = faceCentres();
297 nbrFaceAreas0 = nbr.faceAreas();
298 nbrFaceCentres0 = nbr.faceCentres();
299
300 // Original AMI info (based on the mesh state when the AMI was evaluated)
301 const labelListList& srcToTgtAddr0 = AMIPtr_->srcAddress();
302 const labelListList& tgtToSrcAddr0 = AMIPtr_->tgtAddress();
303 const pointListList& srcCtr0 = AMIPtr_->srcCentroids();
304 const scalarListList& srcToTgtWght0 = AMIPtr_->srcWeights();
305
306 // New addressing on new mesh (extended by polyTopoChange)
307 labelListList srcToTgtAddr1(size(), labelList());
308 labelListList tgtToSrcAddr1(nbr.size(), labelList());
309
310 // Need to calc new parallel maps (mesh has changed since AMI was computed)
311 autoPtr<mapDistribute> srcToTgtMap1;
312 autoPtr<mapDistribute> tgtToSrcMap1;
313
314 if (AMIPtr_->singlePatchProc() == -1)
315 {
316 // Parallel running
317
318 // Global index based on old patch sizes (when AMI was computed)
319 globalIndex globalSrcFaces0(srcToTgtAddr0.size());
320 globalIndex globalTgtFaces0(tgtToSrcAddr0.size());
321
322 // Global index based on new patch sizes
323 globalIndex globalSrcFaces1(size());
324 globalIndex globalTgtFaces1(nbr.size());
325
326
327 // Gather source side info
328 // =======================
329
330 // Note: using new global index for addressing, and distributed using
331 // the old AMI map
332 labelListList newTgtGlobalFaces(tgtFaceIDs_);
333 forAll(newTgtGlobalFaces, tgtFacei)
334 {
335 globalTgtFaces1.inplaceToGlobal(newTgtGlobalFaces[tgtFacei]);
336 }
337 AMIPtr_->tgtMap().distribute(newTgtGlobalFaces);
338
339 // Now have new tgt face indices for each src face
340
341 labelList globalSrcFaceIDs(identity(srcToTgtAddr0.size()));
342 globalSrcFaces0.inplaceToGlobal(globalSrcFaceIDs);
343 AMIPtr_->srcMap().distribute(globalSrcFaceIDs);
344 // globalSrcFaceIDs now has remote data for each srcFacei0 known to the
345 // tgt patch
346
347 List<List<point>> globalSrcCtrs0(srcCtr0);
348 AMIPtr_->srcMap().distribute(globalSrcCtrs0);
349
350 labelList globalTgtFaceIDs(identity(tgtToSrcAddr0.size()));
351 globalTgtFaces0.inplaceToGlobal(globalTgtFaceIDs);
352 AMIPtr_->tgtMap().distribute(globalTgtFaceIDs);
353 // globalTgtFaceIDs now has remote data for each tgtFacei0 known to the
354 // src patch
355
356 // For debug - send tgt face centres and compare against mapped src
357 // face centres
358 //List<List<point>> globalTgtCtrs0(tgtCtr0);
359 //AMIPtr_->tgtMap().distribute(globalTgtCtrs0);
360
361 labelListList globalTgtToSrcAddr(tgtToSrcAddr0);
362 forAll(tgtToSrcAddr0, tgtFacei0)
363 {
364 forAll(tgtToSrcAddr0[tgtFacei0], addri)
365 {
366 const label globalSrcFacei =
367 globalSrcFaceIDs[tgtToSrcAddr0[tgtFacei0][addri]];
368 globalTgtToSrcAddr[tgtFacei0][addri] = globalSrcFacei;
369 }
370 }
371 AMIPtr_->tgtMap().distribute(globalTgtToSrcAddr);
372
373 labelListList globalSrcToTgtAddr(srcToTgtAddr0);
374 forAll(srcToTgtAddr0, srcFacei0)
375 {
376 forAll(srcToTgtAddr0[srcFacei0], addri)
377 {
378 const label globalTgtFacei =
379 globalTgtFaceIDs[srcToTgtAddr0[srcFacei0][addri]];
380 globalSrcToTgtAddr[srcFacei0][addri] = globalTgtFacei;
381 }
382 }
383 AMIPtr_->srcMap().distribute(globalSrcToTgtAddr);
384
385 label nError = 0;
386 forAll(srcToTgtAddr0, srcFacei0)
387 {
388 const labelList& newSrcFaces = srcFaceIDs_[srcFacei0];
389
390 forAll(newSrcFaces, i)
391 {
392 const label srcFacei1 = newSrcFaces[i];
393
394 // What index did srcFacei0 appear in tgtToSrc0 list?
395 // - if first index, all ok
396 // - else tgt face has been moved to according to tgtFaceIDs_
397 const label tgtFacei0 = srcToTgtAddr0[srcFacei0][i];
398 const label addri =
399 globalTgtToSrcAddr[tgtFacei0].find
400 (
401 globalSrcFaceIDs[srcFacei0]
402 );
403
404 if (addri == -1)
405 {
406 ++nError;
407 continue;
408
409 if (debug)
410 {
411 Pout<< "Unable to find global source face "
412 << globalSrcFaceIDs[srcFacei0]
413 << " in globalTgtToSrcAddr[" << tgtFacei0 << "]: "
414 << globalTgtToSrcAddr[tgtFacei0]
415 << endl;
416 }
417 }
418
419 const label tgtFacei1 = newTgtGlobalFaces[tgtFacei0][addri];
420
421 // Sanity check to see that we've picked the correct face
422 // point tgtCtr0(globalTgtCtrs0[tgtFacei0][addri]);
423 // Pout<< "srcCtr:" << srcCtr0[srcFacei0][i]
424 // << " tgtCtr:" << tgtCtr0 << endl;
425
426 srcToTgtAddr1[srcFacei1] = labelList(1, tgtFacei1);
427 faceAreas0_[srcFacei1] *= srcToTgtWght0[srcFacei0][i];
428 faceCentres0_[srcFacei1] = srcCtr0[srcFacei0][i];
429 }
430 }
431
432 if (nError)
433 {
435 << "Unable to find " << nError << " global source faces"
436 << abort(FatalError);
437 }
438
439
440 // Gather Target side info
441 // =======================
442
443 labelListList newSrcGlobalFaces(srcFaceIDs_);
444 forAll(newSrcGlobalFaces, srcFacei)
445 {
446 globalSrcFaces1.inplaceToGlobal(newSrcGlobalFaces[srcFacei]);
447 }
448
449 AMIPtr_->srcMap().distribute(newSrcGlobalFaces);
450
451 // Now have new src face indices for each tgt face
452 forAll(tgtToSrcAddr0, tgtFacei0)
453 {
454 const labelList& newTgtFaces = tgtFaceIDs_[tgtFacei0];
455 forAll(newTgtFaces, i)
456 {
457 const label srcFacei0 = tgtToSrcAddr0[tgtFacei0][i];
458
459 const label addri =
460 globalSrcToTgtAddr[srcFacei0].find
461 (
462 globalTgtFaceIDs[tgtFacei0]
463 );
464
465 if (addri == -1)
466 {
467 ++nError;
468 continue;
469
470 if (debug)
471 {
472 Pout<< "Unable to find global target face "
473 << globalTgtFaceIDs[tgtFacei0]
474 << " in globalSrcToTgtAddr[" << srcFacei0 << "]: "
475 << globalSrcToTgtAddr[srcFacei0]
476 << endl;
477 }
478 }
479
480 const label srcFacei1 = newSrcGlobalFaces[srcFacei0][addri];
481
482 // Sanity check to see that we've picked the correct face
483 point srcCtr0(globalSrcCtrs0[srcFacei0][addri]);
484 reverseTransformPosition(srcCtr0, srcFacei0);
485
486 const label tgtFacei1 = newTgtFaces[i];
487 tgtToSrcAddr1[tgtFacei1] = labelList(1, srcFacei1);
488 nbrFaceCentres0[tgtFacei1] = srcCtr0;
489 }
490 }
491
492 if (nError)
493 {
495 << "Unable to find " << nError << " global target faces"
496 << abort(FatalError);
497 }
498
499 // Update the maps
500 {
501 List<Map<label>> cMap;
502 srcToTgtMap1.reset
503 (
504 new mapDistribute(globalSrcFaces1, tgtToSrcAddr1, cMap)
505 );
506 }
507 {
508 List<Map<label>> cMap;
509 tgtToSrcMap1.reset
510 (
511 new mapDistribute(globalTgtFaces1, srcToTgtAddr1, cMap)
512 );
513 }
514
515 // Reset tgt patch areas using the new map
516 vectorList newSrcGlobalFaceAreas(faceAreas0_);
517
518 srcToTgtMap1->distribute(newSrcGlobalFaceAreas);
519 forAll(nbrFaceAreas0, tgtFacei)
520 {
521 if (!tgtToSrcAddr1[tgtFacei].empty())
522 {
523 const label srcFacei = tgtToSrcAddr1[tgtFacei][0];
524 nbrFaceAreas0[tgtFacei] = -newSrcGlobalFaceAreas[srcFacei];
525 }
526 }
527 }
528 else
529 {
530 label nError = 0;
531 forAll(srcToTgtAddr0, srcFacei0)
532 {
533 const labelList& srcFaceTgtAddr0 = srcToTgtAddr0[srcFacei0];
534 const scalarList& srcFaceTgtWght0 = srcToTgtWght0[srcFacei0];
535 const pointList& srcFaceTgtCtr0 = srcCtr0[srcFacei0];
536 forAll(srcFaceTgtAddr0, addri)
537 {
538 const label srcFacei1 = srcFaceIDs_[srcFacei0][addri];
539
540 // Find which slot srcFacei0 appears in tgt->src addressing
541 const label tgtFacei0 = srcFaceTgtAddr0[addri];
542 const label tgtAddri0 =
543 tgtToSrcAddr0[tgtFacei0].find(srcFacei0);
544
545 if (tgtAddri0 == -1)
546 {
547 ++nError;
548 continue;
549
550 if (debug)
551 {
552 Pout<< "Unable to find source face " << srcFacei0
553 << " in tgtToSrcAddr0[" << tgtFacei0 << "]: "
554 << tgtToSrcAddr0[tgtFacei0]
555 << endl;
556 }
557 }
558
559 const label tgtFacei1 = tgtFaceIDs_[tgtFacei0][tgtAddri0];
560
561 faceAreas0_[srcFacei1] *= srcFaceTgtWght0[addri];
562 nbrFaceAreas0[tgtFacei1] = -faceAreas0_[srcFacei1];
563
564 point pt(srcFaceTgtCtr0[addri]);
565 faceCentres0_[srcFacei1] = pt;
566 reverseTransformPosition(pt, srcFacei0);
567 nbrFaceCentres0[tgtFacei1] = pt;
568
569 // SANITY CHECK
570 // Info<< "srcPt:" << srcFaceCentres[srcFacei1]
571 // << " tgtPt:" << tgtFaceCentres[tgtFacei1] << endl;
572
573 srcToTgtAddr1[srcFacei1] = labelList(1, tgtFacei1);
574 tgtToSrcAddr1[tgtFacei1] = labelList(1, srcFacei1);
575 }
576 }
577
578 if (nError)
579 {
581 << "Unable to find " << nError
582 << " source faces in tgtToSrcAddr0"
583 << abort(FatalError);
584 }
585 }
586
587 scalarListList newSrcToTgtWeights(srcToTgtAddr1.size());
588 forAll(srcToTgtAddr1, facei)
589 {
590 if (srcToTgtAddr1[facei].size())
591 {
592 newSrcToTgtWeights[facei] = scalarList(1, scalar(1));
593 }
594 else
595 {
596 // No connection - effect of face removed by setting area to a
597 // a small value
598 faceAreas0_[facei] *= tolerance_;
599 }
600 }
601
602 scalarListList newTgtToSrcWeights(tgtToSrcAddr1.size());
603 forAll(tgtToSrcAddr1, facei)
604 {
605 if (tgtToSrcAddr1[facei].size())
606 {
607 newTgtToSrcWeights[facei] = scalarList(1, scalar(1));
608 }
609 else
610 {
611 // No connection - effect of face removed by setting area to a
612 // a small value
613 nbrFaceAreas0[facei] *= tolerance_;
614 }
615 }
616
617 // Reset the AMI addressing and weights to reflect the new 1-to-1
618 // correspondence
619 AMIPtr_->reset
620 (
621 std::move(srcToTgtMap1),
622 std::move(tgtToSrcMap1),
623 std::move(srcToTgtAddr1),
624 std::move(newSrcToTgtWeights),
625 std::move(tgtToSrcAddr1),
626 std::move(newTgtToSrcWeights)
627 );
628
629 // Need to set areas, e.g. for agglomeration to (re-)normalisation weights
630 AMIPtr_->srcMagSf() = mag(faceAreas0_);
631 AMIPtr_->tgtMagSf() = mag(nbrFaceAreas0);
632
633 if (debug)
634 {
635 Pout<< "cyclicAMIPolyPatch : " << name()
636 << " constructed AMI with " << nl
637 << " " << "srcAddress:" << AMIPtr_().srcAddress().size()
638 << nl
639 << " " << "tgAddress :" << AMIPtr_().tgtAddress().size()
640 << nl << endl;
641 }
642}
643
644
645// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
646
648{
650
651 createAMIFaces_ = true;
652
653 return true;
654}
655
656
658{
660
661 if (createAMIFaces_ && owner())
662 {
663 // Calculate the AMI using the new points
664 // Note: mesh still has old points
665 resetAMI(topoChange.points());
666
667 removeAMIFaces(topoChange);
668
669 addAMIFaces(topoChange);
670
671 return true;
672 }
673
674 return false;
675}
676
677
678// ************************************************************************* //
void setSize(const label n)
Alias for resize()
Definition: List.H:218
void clear()
Clear the list, i.e. set size to zero.
Definition: ListI.H:116
SubField is a Field obtained as a section of another Field, without its own allocation....
Definition: SubField.H:62
bool empty() const noexcept
True if the UList is empty (ie, size() is zero)
Definition: UListI.H:427
label find(const T &val, label pos=0) const
Find index of the first occurrence of the value.
Definition: UList.C:212
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
label whichZone(const label objectIndex) const
Given a global object index, return the zone it is in.
Definition: ZoneMesh.C:288
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition: autoPtr.H:66
void reset(autoPtr< T > &&other) noexcept
Delete managed object and set to new given pointer.
Definition: autoPtrI.H:117
Addressing for all faces on surface of mesh. Can either be read from polyMesh or from triSurface....
Definition: boundaryMesh.H:63
const bMesh & mesh() const
Definition: boundaryMesh.H:206
Cyclic patch for Arbitrary Mesh Interface (AMI)
vectorField & faceAreas0() const
Return access to the initial face areas.
bool createAMIFaces_
Flag to indicate that new AMI faces will created.
virtual bool addAMIFaces(polyTopoChange &topoChange)
Collect faces to add in the topoChange container.
vectorField faceCentres0_
Temporary storage for AMI face centres.
virtual bool removeAMIFaces(polyTopoChange &topoChange)
Collect faces to remove in the topoChange container.
virtual bool setTopology(polyTopoChange &topoChange)
Set topology changes in the polyTopoChange object.
vectorField faceAreas0_
Temporary storage for AMI face areas.
virtual bool changeTopology() const
Return true if this patch changes the mesh topology.
virtual void setAMIFaces()
Set properties of newly inserted faces after topological changes.
vectorField & faceCentres0() const
Return access to the initial face centres.
bool moveFaceCentres_
Move face centres (default = no)
Calculates a unique integer (label so might not have enough room - 2G max) for processor + local inde...
Definition: globalIndex.H:68
void inplaceToGlobal(labelUList &labels) const
From local to global index (inplace)
Definition: globalIndexI.H:303
Class containing processor-to-processor mapping information.
label index() const noexcept
The index of this patch in the boundaryMesh.
const word & name() const noexcept
The patch name.
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:81
const faceZoneMesh & faceZones() const noexcept
Return face zone mesh.
Definition: polyMesh.H:498
virtual const faceList & faces() const
Return raw faces.
Definition: polyMesh.C:1108
virtual const labelList & faceOwner() const
Return face owner.
Definition: polyMesh.C:1121
const vectorField::subField faceAreas() const
Return face normals.
Definition: polyPatch.C:327
label start() const
Return start label of this patch in the polyMesh face list.
Definition: polyPatch.H:364
const vectorField::subField faceCentres() const
Return face centres.
Definition: polyPatch.C:321
Direct mesh changes based on v1.3 polyTopoChange syntax.
void removeFace(const label facei, const label mergeFacei)
Remove/merge face.
label addFace(const face &f, const label own, const label nei, const label masterPointID, const label masterEdgeID, const label masterFaceID, const bool flipFaceFlux, const label patchID, const label zoneID, const bool zoneFlip)
Add face to cells. Return new face label.
const DynamicList< point > & points() const
Points. Shrunk after constructing mesh (or calling of compact())
dynamicFvMesh & mesh
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
#define DebugInfo
Report an information message using Foam::Info.
#define WarningInFunction
Report a warning using Foam::Warning.
#define DebugInFunction
Report an information message using Foam::Info.
Type gSum(const FieldField< Field, Type > &f)
labelList identity(const label len, label start=0)
Return an identity map of the given length with (map[i] == i)
Definition: labelList.C:38
List< label > labelList
A List of labels.
Definition: List.H:66
messageStream Info
Information stream (stdout output on master, null elsewhere)
List< scalar > scalarList
A List of scalars.
Definition: scalarList.H:64
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:372
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
errorManip< error > abort(error &err)
Definition: errorManip.H:144
error FatalError
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:59
T returnReduce(const T &value, const BinaryOp &bop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Reduce (copy) and return value.
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
constexpr char nl
The newline '\n' character (0x0a)
Definition: Ostream.H:53
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:333