regionSplit.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-2013 OpenFOAM Foundation
9  Copyright (C) 2018-2020 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
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 "regionSplit.H"
30 #include "cyclicPolyPatch.H"
31 #include "processorPolyPatch.H"
32 #include "globalIndex.H"
33 #include "syncTools.H"
34 #include "clockValue.H"
35 
36 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
37 
38 namespace Foam
39 {
40  defineTypeNameAndDebug(regionSplit, 0);
41 }
42 
43 static constexpr Foam::label UNASSIGNED = -1;
44 static constexpr Foam::label BLOCKED = -2;
45 
46 
47 // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
48 
49 namespace Foam
50 {
51 
52 //- The sizes of a List of containers (eg, labelHashSet)
53 template<class Container>
55 {
56  const label len = input.size();
57 
58  labelList output(len);
59 
60  for (label i = 0; i < len; ++i)
61  {
62  output[i] = input[i].size();
63  }
64 
65  return output;
66 }
67 
68 } // End namespace Foam
69 
70 
71 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
72 
73 void Foam::regionSplit::updateFacePair
74 (
75  const label face0,
76  const label face1,
77 
78  labelList& faceRegion,
79  DynamicList<label>& facesChanged
80 ) const
81 {
82  if (faceRegion[face0] == UNASSIGNED)
83  {
84  if (faceRegion[face1] >= 0)
85  {
86  faceRegion[face0] = faceRegion[face1];
87  facesChanged.append(face0);
88  }
89  else if (faceRegion[face1] == BLOCKED)
90  {
91  // face1 blocked but not face0.
92  // - illegal for coupled faces, OK for explicit connections.
93  }
94  }
95  else if (faceRegion[face0] >= 0)
96  {
97  if (faceRegion[face1] == UNASSIGNED)
98  {
99  faceRegion[face1] = faceRegion[face0];
100  facesChanged.append(face1);
101  }
102  else if (faceRegion[face1] == BLOCKED)
103  {
104  // face1 blocked but not face0.
105  // - illegal for coupled faces, OK for explicit connections.
106  }
107  else if (faceRegion[face1] != faceRegion[face0])
108  {
110  << "Problem : coupled face " << face0
111  << " on patch " << mesh().boundaryMesh().whichPatch(face0)
112  << " has region " << faceRegion[face0]
113  << " but coupled face " << face1
114  << " has region " << faceRegion[face1] << nl
115  << "Is your blocked faces specification"
116  << " synchronized across coupled boundaries?" << endl
117  << abort(FatalError);
118  }
119  }
120 }
121 
122 
123 void Foam::regionSplit::fillSeedMask
124 (
125  const List<labelPair>& explicitConnections,
126  const label seedCellId,
127  const label markValue,
128  labelList& cellRegion,
129  labelList& faceRegion
130 ) const
131 {
132  // Seed cell
133  cellRegion[seedCellId] = markValue;
134 
135  // Faces on seed cell
136  changedFaces_.clear();
137  for (const label facei : mesh().cells()[seedCellId])
138  {
139  if (faceRegion[facei] == UNASSIGNED)
140  {
141  faceRegion[facei] = markValue;
142  changedFaces_.append(facei);
143  }
144  }
145 
146  const polyBoundaryMesh& patches = mesh().boundaryMesh();
147 
148  // Loop over changed faces. FaceCellWave in small.
149 
150  while (changedFaces_.size())
151  {
152  changedCells_.clear();
153 
154  for (const label facei : changedFaces_)
155  {
156  const label own = mesh().faceOwner()[facei];
157 
158  if (cellRegion[own] == UNASSIGNED)
159  {
160  cellRegion[own] = markValue;
161  changedCells_.append(own);
162  }
163 
164  if (mesh().isInternalFace(facei))
165  {
166  const label nei = mesh().faceNeighbour()[facei];
167 
168  if (cellRegion[nei] == UNASSIGNED)
169  {
170  cellRegion[nei] = markValue;
171  changedCells_.append(nei);
172  }
173  }
174  }
175 
176  if (debug & 2)
177  {
178  Pout<< " Changed cells / faces : "
179  << changedCells_.size() << " / " << changedFaces_.size()
180  << " before sync" << endl;
181  }
182 
183  // Loop over changedCells and collect faces
184  changedFaces_.clear();
185  for (const label celli : changedCells_)
186  {
187  for (const label facei : mesh().cells()[celli])
188  {
189  if (faceRegion[facei] == UNASSIGNED)
190  {
191  faceRegion[facei] = markValue;
192  changedFaces_.append(facei);
193  }
194  }
195  }
196 
197 
198  // Update locally coupled faces
199  // Global connections are done later.
200 
201  for (const polyPatch& pp : patches)
202  {
203  if
204  (
205  isA<cyclicPolyPatch>(pp)
206  && refCast<const cyclicPolyPatch>(pp).owner()
207  )
208  {
209  // Transfer from neighbourPatch to here or vice versa.
210 
211  const cyclicPolyPatch& cycPatch =
212  refCast<const cyclicPolyPatch>(pp);
213 
214  label face0 = cycPatch.start();
215 
216  forAll(cycPatch, i)
217  {
218  const label face1 = cycPatch.transformGlobalFace(face0);
219 
220  updateFacePair
221  (
222  face0,
223  face1,
224  faceRegion,
225  changedFaces_
226  );
227 
228  ++face0;
229  }
230  }
231  }
232 
233  for (const labelPair& pr : explicitConnections)
234  {
235  updateFacePair
236  (
237  pr.first(),
238  pr.second(),
239  faceRegion,
240  changedFaces_
241  );
242  }
243 
244  if (debug & 2)
245  {
246  Pout<< " Changed faces : "
247  << changedFaces_.size()
248  << " after sync" << endl;
249  }
250  }
251 }
252 
253 
254 Foam::label Foam::regionSplit::calcLocalRegionSplit
255 (
256  const boolList& blockedFace,
257  const List<labelPair>& explicitConnections,
258 
259  labelList& cellRegion
260 ) const
261 {
262  clockValue timing(debug);
263 
264  if (debug)
265  {
266  if (blockedFace.size())
267  {
268  // Check that blockedFace is synced.
269  boolList syncBlockedFace(blockedFace);
270  syncTools::swapFaceList(mesh(), syncBlockedFace);
271 
272  forAll(syncBlockedFace, facei)
273  {
274  if (syncBlockedFace[facei] != blockedFace[facei])
275  {
277  << "Face " << facei << " not synchronised. My value:"
278  << blockedFace[facei] << " coupled value:"
279  << syncBlockedFace[facei]
280  << abort(FatalError);
281  }
282  }
283  }
284  }
285 
286  changedCells_.reserve(mesh_.nCells());
287  changedFaces_.reserve(mesh_.nFaces());
288 
289  // Region per face.
290  // -1 = unassigned
291  // -2 = blocked
292  labelList faceRegion(mesh().nFaces(), UNASSIGNED);
293 
294  if (blockedFace.size())
295  {
296  forAll(blockedFace, facei)
297  {
298  if (blockedFace[facei])
299  {
300  faceRegion[facei] = BLOCKED;
301  }
302  }
303  }
304 
305 
306  // Assign local regions
307  // ~~~~~~~~~~~~~~~~~~~~
308 
309  // Start with region 0
310  label nLocalRegions = 0;
311 
312  for (label seedCellId = 0; seedCellId < cellRegion.size(); ++seedCellId)
313  {
314  // Find next unset cell - use as seed
315 
316  for (; seedCellId < cellRegion.size(); ++seedCellId)
317  {
318  if (cellRegion[seedCellId] == UNASSIGNED)
319  {
320  break;
321  }
322  }
323 
324  if (seedCellId >= cellRegion.size())
325  {
326  break;
327  }
328 
329  fillSeedMask
330  (
331  explicitConnections,
332  seedCellId,
333  nLocalRegions,
334  cellRegion,
335  faceRegion
336  );
337 
338  ++nLocalRegions; // Next region
339  }
340 
341  // Discard temporary working data
342  changedCells_.clearStorage();
343  changedFaces_.clearStorage();
344 
345  if (debug)
346  {
347  forAll(cellRegion, celli)
348  {
349  if (cellRegion[celli] < 0)
350  {
352  << "cell:" << celli << " region:" << cellRegion[celli]
353  << abort(FatalError);
354  }
355  }
356 
357  forAll(faceRegion, facei)
358  {
359  if (faceRegion[facei] == UNASSIGNED)
360  {
362  << "face:" << facei << " region:" << faceRegion[facei]
363  << abort(FatalError);
364  }
365  }
366  }
367 
368  DebugInfo << "regionSplit = " << double(timing.elapsed()) << "s\n";
369 
370  return nLocalRegions;
371 }
372 
373 
374 Foam::autoPtr<Foam::globalIndex> Foam::regionSplit::calcRegionSplit
375 (
376  const bool doGlobalRegions,
377  const boolList& blockedFace,
378  const List<labelPair>& explicitConnections,
379 
380  labelList& cellRegion
381 ) const
382 {
383  const label nLocalRegions = calcLocalRegionSplit
384  (
385  blockedFace,
386  explicitConnections,
387  cellRegion
388  );
389 
390  if (!doGlobalRegions)
391  {
392  return autoPtr<globalIndex>::New(nLocalRegions);
393  }
394 
395  return reduceRegions(nLocalRegions, blockedFace, cellRegion);
396 }
397 
398 
399 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
400 
402 (
403  const polyMesh& mesh,
404  const bool doGlobalRegions
405 )
406 :
408  labelList(mesh.nCells(), -1)
409 {
410  globalNumberingPtr_ = calcRegionSplit
411  (
412  doGlobalRegions,
413  boolList(), // No blockedFace
414  List<labelPair>(), // No explicitConnections
415  *this
416  );
417 }
418 
419 
421 (
422  const polyMesh& mesh,
423  const boolList& blockedFace,
424  const bool doGlobalRegions
425 )
426 :
428  labelList(mesh.nCells(), -1)
429 {
430  globalNumberingPtr_ = calcRegionSplit
431  (
432  doGlobalRegions,
433  blockedFace,
434  List<labelPair>(), // No explicitConnections
435  *this
436  );
437 }
438 
439 
441 (
442  const polyMesh& mesh,
443  const boolList& blockedFace,
444  const List<labelPair>& explicitConnections,
445  const bool doGlobalRegions
446 )
447 :
449  labelList(mesh.nCells(), -1)
450 {
451  globalNumberingPtr_ = calcRegionSplit
452  (
453  doGlobalRegions,
454  blockedFace,
455  explicitConnections,
456  *this
457  );
458 }
459 
460 
461 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
462 
464 (
465  const label numLocalRegions,
466  const boolList& blockedFace,
467 
468  labelList& cellRegion
469 ) const
470 {
471  clockValue timing(debug);
472 
473  if (cellRegion.size() != mesh().nCells())
474  {
476  << "The cellRegion size " << cellRegion.size()
477  << " is not equal to the of number of cells "
478  << mesh().nCells() << endl
479  << abort(FatalError);
480  }
481 
482 
483  // (numLocalRegions < 0) to signal that region information should be
484  // determined ourselves. This is not really efficient, but can be useful
485 
486  const label nLocalRegions =
487  (
488  numLocalRegions < 0
489  ? labelHashSet(cellRegion).size()
490  : numLocalRegions
491  );
492 
493 
494  // Preliminary global region numbers
495  const globalIndex globalRegions(nLocalRegions);
496 
497 
498  // Lookup table of local region to global region.
499  // Initially an identity mapping of the uncombined global values.
500 
501  Map<label> localToGlobal(2*nLocalRegions);
502  for (const label regioni : cellRegion)
503  {
504  localToGlobal.insert(regioni, globalRegions.toGlobal(regioni));
505  }
506 
507  // To update the localToGlobal mapping during traversal of the boundaries
508  // and later when finalizing things.
509  Map<label> updateLookup(2*nLocalRegions);
510 
511 
512  // Note that we use two separate maps during the process.
513  // The localToGlobal is used to map the local to global regions.
514  // Merging across processors will normally make this a many->few mapping.
515  // However, we may need to walk up and down processor boundaries several
516  // times before all the information propagates through.
517  // During these traversals, it will normally be more efficient to just
518  // update the mapping without updating the cellRegion immediately.
519  // Only after everything is finalized do we renumber all of the cell
520  // regions.
521 
522 
523  // Merge global regions
524  // ~~~~~~~~~~~~~~~~~~~~
525  // Regions across non-blocked proc patches get merged.
526  // This will set merged global regions to be the min of both.
527  // (this will create gaps in the global region list so they will get
528  // merged later on)
529 
531 
532  // Buffer for swapping boundary information
533  labelList nbrRegion(mesh().nBoundaryFaces());
534 
535  bool emitWarning = true;
536 
537  do
538  {
539  if (debug)
540  {
541  Pout<< nl << "-- Starting Iteration --" << endl;
542  }
543 
544  updateLookup.clear();
545  nbrRegion = UNASSIGNED;
546 
547  // Region information to send
548  for (const polyPatch& pp : patches)
549  {
550  if (pp.coupled())
551  {
552  const labelUList& faceCells = pp.faceCells();
553  SubList<label> patchNbrRegion
554  (
555  nbrRegion,
556  pp.size(),
557  pp.start()-mesh().nInternalFaces()
558  );
559 
560  forAll(faceCells, patchFacei)
561  {
562  const label meshFacei = pp.start()+patchFacei;
563 
564  if (!blockedFace[meshFacei])
565  {
566  // Send the most currently updated region Id
567  const label orig = cellRegion[faceCells[patchFacei]];
568 
569  patchNbrRegion[patchFacei] = localToGlobal[orig];
570  }
571  }
572  }
573  }
575 
576  // Receive and reduce region information
577  for (const polyPatch& pp : patches)
578  {
579  if (pp.coupled())
580  {
581  const labelUList& faceCells = pp.faceCells();
582  SubList<label> patchNbrRegion
583  (
584  nbrRegion,
585  pp.size(),
586  pp.start()-mesh().nInternalFaces()
587  );
588 
589  forAll(faceCells, patchFacei)
590  {
591  const label meshFacei = pp.start()+patchFacei;
592 
593  if (!blockedFace[meshFacei])
594  {
595  // Reduction by retaining the min region id.
596 
597  const label orig = cellRegion[faceCells[patchFacei]];
598 
599  const label sent = localToGlobal[orig];
600  const label recv = patchNbrRegion[patchFacei];
601 
602  if (recv == UNASSIGNED)
603  {
604  if (emitWarning)
605  {
606  Pout<<"Warning in regionSplit:"
607  " received unassigned on "
608  << pp.name() << " at patchFace "
609  << patchFacei
610  << ". Check synchronisation in caller"
611  << nl;
612  }
613  }
614  else if (recv < sent)
615  {
616  // Record the minimum value seen
617 
618  auto fnd = updateLookup.find(sent);
619  if (!fnd.found())
620  {
621  updateLookup.insert(sent, recv);
622  }
623  else if (recv < *fnd)
624  {
625  *fnd = recv;
626  }
627  }
628  }
629  }
630  }
631  }
632 
633 
634  // Note: by always using the minimum region number across the
635  // processor faces, we effect a consolidation of connected regions
636  // and converge to a unique number for each distinct region.
637 
638 
639  // Update localToGlobal according to newly exchanged information
640 
641  inplaceMapValue(updateLookup, localToGlobal);
642 
643  if (debug & 2)
644  {
645  labelList keys(localToGlobal.sortedToc());
646  labelList vals(keys.size());
647  forAll(keys, i)
648  {
649  vals[i] = localToGlobal[keys[i]];
650  }
651 
652  Pout<< "Updated local regions:" << nl
653  << "old: " << flatOutput(keys) << nl
654  << "new: " << flatOutput(vals) << endl;
655  }
656  else if (debug)
657  {
658  Pout<< "Updated " << localToGlobal.size()
659  << " local regions" << endl;
660  }
661 
662  emitWarning = false;
663  // Continue until there are no further changes
664  }
665  while (returnReduce(!updateLookup.empty(), orOp<bool>()));
666 
667 
668  //
669  // We will need compact numbers locally and non-locally
670  //
671 
672  // Determine the local compact numbering
673  label nCompact = 0;
674  {
675  labelHashSet localRegion(2*localToGlobal.size());
676 
677  forAllConstIters(localToGlobal, iter)
678  {
679  const label regioni = iter.val();
680 
681  if (globalRegions.isLocal(regioni))
682  {
683  localRegion.insert(regioni);
684  }
685  }
686 
687  nCompact = localRegion.size();
688  }
689 
690 
691  // The new global numbering using compacted local regions
692  auto globalCompactPtr = autoPtr<globalIndex>::New(nCompact);
693  const auto& globalCompact = *globalCompactPtr;
694 
695 
696  // Determine the following:
697  // - the local compact regions (store as updateLookup)
698  // - the non-local regions, ordered according to the processor on which
699  // they are local.
700 
701 
702  // The local compaction map (updated local to compact local numbering)
703  updateLookup.clear();
704 
705  labelListList sendNonLocal(Pstream::nProcs());
706 
707  {
709 
710  // Use estimate of sizing for non-local regions
711  forAll(nonLocal, proci)
712  {
713  if (proci != Pstream::myProcNo())
714  {
715  nonLocal[proci].resize
716  (
717  2*((nLocalRegions-nCompact)/Pstream::nProcs())
718  );
719  }
720  }
721 
722 
723  forAllConstIters(localToGlobal, iter)
724  {
725  const label regioni = iter.val();
726 
727  if (globalRegions.isLocal(regioni))
728  {
729  updateLookup.insert
730  (
731  regioni,
732  globalCompact.toGlobal(updateLookup.size())
733  );
734  }
735  else
736  {
737  nonLocal[globalRegions.whichProcID(regioni)].insert(regioni);
738  }
739  }
740 
741  if (debug)
742  {
743  Pout<< " per processor nonLocal regions: "
744  << flatOutput(containerSizes(nonLocal)) << endl;
745  }
746 
747 
748  // Convert to label list
749  forAll(sendNonLocal, proci)
750  {
751  sendNonLocal[proci] = nonLocal[proci].toc();
752  }
753  }
754 
755 
756  // Get the wanted region labels into recvNonLocal
757  labelListList recvNonLocal;
758  Pstream::exchange<labelList, label>
759  (
760  sendNonLocal,
761  recvNonLocal
762  );
763 
764 
765  // The recvNonLocal[proci] region labels are what proci requires.
766  // Transcribe into their compacted number.
767 
768  {
769  labelListList sendLocal(std::move(recvNonLocal));
770 
771  for (labelList& send : sendLocal)
772  {
773  for (label& regioni : send)
774  {
775  regioni = updateLookup[regioni];
776  }
777  }
778 
779  // Send back (into recvNonLocal)
780  Pstream::exchange<labelList, label>
781  (
782  sendLocal,
783  recvNonLocal
784  );
785  }
786 
787 
788  // Now recvNonLocal and sendNonLocal contain matched pairs with
789  // sendNonLocal being the non-compact region and recvNonLocal being
790  // the compact region.
791  //
792  // Insert these into the local compaction map.
793 
794  forAll(recvNonLocal, proci)
795  {
796  const labelList& send = sendNonLocal[proci];
797  const labelList& recv = recvNonLocal[proci];
798 
799  forAll(send, i)
800  {
801  updateLookup.insert(send[i], recv[i]);
802  }
803  }
804 
805 
806  // Now renumber the localToGlobal to use the final compact global values
807  inplaceMapValue(updateLookup, localToGlobal);
808 
809 
810  // Can now finally use localToGlobal to renumber cellRegion
811 
812  forAll(cellRegion, celli)
813  {
814  cellRegion[celli] = localToGlobal[cellRegion[celli]];
815  }
816 
817  DebugInfo
818  <<"regionSplit::reduceRegions = " << double(timing.elapsed()) << "s\n";
819 
820  return globalCompactPtr;
821 }
822 
823 
824 // ************************************************************************* //
Foam::expressions::patchExpr::debug
int debug
Static debugging option.
Foam::autoPtr::New
static autoPtr< T > New(Args &&... args)
Construct autoPtr of T with forwarding arguments.
Foam::labelList
List< label > labelList
A List of labels.
Definition: List.H:71
Foam::HashTable::size
label size() const noexcept
The number of elements in table.
Definition: HashTableI.H:52
UNASSIGNED
static constexpr Foam::label UNASSIGNED
Definition: regionSplit.C:43
Foam::returnReduce
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
Definition: PstreamReduceOps.H:94
Foam::polyBoundaryMesh
A polyBoundaryMesh is a polyPatch list with additional search methods and registered IO.
Definition: polyBoundaryMesh.H:62
cyclicPolyPatch.H
Foam::primitiveMesh::nInternalFaces
label nInternalFaces() const
Number of internal faces.
Definition: primitiveMeshI.H:78
Foam::SubList
A List obtained as a section of another List.
Definition: SubList.H:53
globalIndex.H
Foam::UPstream::nProcs
static label nProcs(const label communicator=0)
Number of processes in parallel run.
Definition: UPstream.H:427
Foam::Map< label >
Foam::syncTools::swapBoundaryFaceList
static void swapBoundaryFaceList(const polyMesh &mesh, UList< T > &faceValues)
Swap coupled boundary face values. Uses eqOp.
Definition: syncTools.H:439
Foam::boolList
List< bool > boolList
A List of bools.
Definition: List.H:69
Foam::globalIndex::isLocal
bool isLocal(const label i) const
Is on local processor.
Definition: globalIndexI.H:148
Foam::List::append
void append(const T &val)
Append an element at the end of the list.
Definition: ListI.H:182
Foam::polyMesh::boundaryMesh
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
Definition: polyMesh.H:435
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:350
Foam::Pout
prefixOSstream Pout
An Ostream wrapper for parallel output to std::cout.
Foam::HashSet< label, Hash< label > >
syncTools.H
Foam::polyMesh
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:77
Foam::regionSplit::regionSplit
regionSplit(const polyMesh &mesh, const bool doGlobalRegions=Pstream::parRun())
Construct from mesh.
Definition: regionSplit.C:402
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::clockValue::elapsed
clockValue elapsed() const
The time duration elapsed until now() since the start point.
Definition: clockValueI.H:76
Foam::labelPair
Pair< label > labelPair
A pair of labels.
Definition: Pair.H:54
Foam::primitiveMesh::nCells
label nCells() const
Number of mesh cells.
Definition: primitiveMeshI.H:96
clockValue.H
Foam::MeshObject< polyMesh, TopologicalMeshObject, regionSplit >::mesh
const polyMesh & mesh() const
Definition: MeshObject.H:122
Foam::polyPatch
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:67
Foam::OSstream::name
virtual const fileName & name() const
Return the name of the stream.
Definition: OSstream.H:107
Foam::containerSizes
static labelList containerSizes(const UList< Container > &input)
The sizes of a List of containers (eg, labelHashSet)
Definition: regionSplit.C:54
Foam::polyMesh::faceOwner
virtual const labelList & faceOwner() const
Return face owner.
Definition: polyMesh.C:1076
regionSplit.H
Foam::polyBoundaryMesh::whichPatch
label whichPatch(const label faceIndex) const
Return patch index for a given face label.
Definition: polyBoundaryMesh.C:805
Foam::inplaceMapValue
label inplaceMapValue(const labelUList &oldToNew, Container &input)
Map values. Ignore negative values.
Foam::List::resize
void resize(const label newSize)
Adjust allocated size of list.
Definition: ListI.H:139
Foam::clockValue
Access to high-resolution clock value with some basic operations. Used to calculate time durations,...
Definition: clockValue.H:53
Foam::FatalError
error FatalError
processorPolyPatch.H
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
Foam::PtrList::clear
void clear()
Clear the PtrList. Delete allocated entries and set size to zero.
Definition: PtrListI.H:100
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:137
Foam::globalIndex
Calculates a unique integer (label so might not have enough room - 2G max) for processor + local inde...
Definition: globalIndex.H:68
BLOCKED
static constexpr Foam::label BLOCKED
Definition: regionSplit.C:44
Foam::UPstream::myProcNo
static int myProcNo(const label communicator=0)
Number of this process (starting from masterNo() = 0)
Definition: UPstream.H:445
Foam::autoPtr< Foam::globalIndex >
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:372
DebugInfo
#define DebugInfo
Report an information message using Foam::Info.
Definition: messageStream.H:354
Foam::nl
constexpr char nl
Definition: Ostream.H:385
forAllConstIters
forAllConstIters(mixture.phases(), phase)
Definition: pEqn.H:28
Foam::flatOutput
FlatOutput< Container > flatOutput(const Container &obj, label len=0)
Global flatOutput function.
Definition: FlatOutput.H:85
Foam::syncTools::swapFaceList
static void swapFaceList(const polyMesh &mesh, UList< T > &faceValues)
Swap coupled face values. Uses eqOp.
Definition: syncTools.H:472
Foam::List< label >
Foam::globalIndex::whichProcID
label whichProcID(const label i) const
Which processor does global come from? Binary search.
Definition: globalIndexI.H:235
Foam::UList
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: HashTable.H:103
patches
const polyBoundaryMesh & patches
Definition: convertProcessorPatches.H:65
Foam::UList::size
void size(const label n) noexcept
Override size to be inconsistent with allocated storage.
Definition: UListI.H:360
Foam::MeshObject
Templated abstract base-class for optional mesh objects used to automate their allocation to the mesh...
Definition: MeshObject.H:88
cells
const cellShapeList & cells
Definition: gmvOutputHeader.H:3
Foam::regionSplit::reduceRegions
autoPtr< globalIndex > reduceRegions(const label numLocalRegions, const boolList &blockedFace, labelList &cellRegion) const
Manually consolidate the regions globally by swapping information.
Definition: regionSplit.C:464
Foam::labelHashSet
HashSet< label, Hash< label > > labelHashSet
A HashSet with label keys and label hasher.
Definition: HashSet.H:410
Foam::orOp
Definition: ops.H:234
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)
Foam::faceCells
Smooth ATC in cells next to a set of patches supplied by type.
Definition: faceCells.H:56
Foam::polyMesh::faceNeighbour
virtual const labelList & faceNeighbour() const
Return face neighbour.
Definition: polyMesh.C:1082
Foam::globalIndex::toGlobal
label toGlobal(const label i) const
From local to global index.
Definition: globalIndexI.H:164