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 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  if (debug)
369  {
370  Info<<"regionSplit = " << double(timing.elapsed()) << "s\n";
371  }
372 
373  return nLocalRegions;
374 }
375 
376 
377 Foam::autoPtr<Foam::globalIndex> Foam::regionSplit::calcRegionSplit
378 (
379  const bool doGlobalRegions,
380  const boolList& blockedFace,
381  const List<labelPair>& explicitConnections,
382 
383  labelList& cellRegion
384 ) const
385 {
386  const label nLocalRegions = calcLocalRegionSplit
387  (
388  blockedFace,
389  explicitConnections,
390  cellRegion
391  );
392 
393  if (!doGlobalRegions)
394  {
395  return autoPtr<globalIndex>::New(nLocalRegions);
396  }
397 
398  return reduceRegions(nLocalRegions, blockedFace, cellRegion);
399 }
400 
401 
402 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
403 
405 (
406  const polyMesh& mesh,
407  const bool doGlobalRegions
408 )
409 :
411  labelList(mesh.nCells(), -1)
412 {
413  globalNumberingPtr_ = calcRegionSplit
414  (
415  doGlobalRegions,
416  boolList(), // No blockedFace
417  List<labelPair>(), // No explicitConnections
418  *this
419  );
420 }
421 
422 
424 (
425  const polyMesh& mesh,
426  const boolList& blockedFace,
427  const bool doGlobalRegions
428 )
429 :
431  labelList(mesh.nCells(), -1)
432 {
433  globalNumberingPtr_ = calcRegionSplit
434  (
435  doGlobalRegions,
436  blockedFace,
437  List<labelPair>(), // No explicitConnections
438  *this
439  );
440 }
441 
442 
444 (
445  const polyMesh& mesh,
446  const boolList& blockedFace,
447  const List<labelPair>& explicitConnections,
448  const bool doGlobalRegions
449 )
450 :
452  labelList(mesh.nCells(), -1)
453 {
454  globalNumberingPtr_ = calcRegionSplit
455  (
456  doGlobalRegions,
457  blockedFace,
458  explicitConnections,
459  *this
460  );
461 }
462 
463 
464 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
465 
467 (
468  const label numLocalRegions,
469  const boolList& blockedFace,
470 
471  labelList& cellRegion
472 ) const
473 {
474  clockValue timing(debug);
475 
476  if (cellRegion.size() != mesh().nCells())
477  {
479  << "The cellRegion size " << cellRegion.size()
480  << " is not equal to the of number of cells "
481  << mesh().nCells() << endl
482  << abort(FatalError);
483  }
484 
485 
486  // (numLocalRegions < 0) to signal that region information should be
487  // determined ourselves. This is not really efficient, but can be useful
488 
489  const label nLocalRegions =
490  (
491  numLocalRegions < 0
492  ? labelHashSet(cellRegion).size()
493  : numLocalRegions
494  );
495 
496 
497  // Preliminary global region numbers
498  const globalIndex globalRegions(nLocalRegions);
499 
500 
501  // Lookup table of local region to global region.
502  // Initially an identity mapping of the uncombined global values.
503 
504  Map<label> localToGlobal(2*nLocalRegions);
505  for (const label regioni : cellRegion)
506  {
507  localToGlobal.insert(regioni, globalRegions.toGlobal(regioni));
508  }
509 
510  // To update the localToGlobal mapping during traversal of the boundaries
511  // and later when finalizing things.
512  Map<label> updateLookup(2*nLocalRegions);
513 
514 
515  // Note that we use two separate maps during the process.
516  // The localToGlobal is used to map the local to global regions.
517  // Merging across processors will normally make this a many->few mapping.
518  // However, we may need to walk up and down processor boundaries several
519  // times before all the information propagates through.
520  // During these traversals, it will normally be more efficient to just
521  // update the mapping without updating the cellRegion immediately.
522  // Only after everything is finalized do we renumber all of the cell
523  // regions.
524 
525 
526  // Merge global regions
527  // ~~~~~~~~~~~~~~~~~~~~
528  // Regions across non-blocked proc patches get merged.
529  // This will set merged global regions to be the min of both.
530  // (this will create gaps in the global region list so they will get
531  // merged later on)
532 
534 
535  // Buffer for swapping boundary information
536  labelList nbrRegion(mesh().nBoundaryFaces());
537 
538  bool emitWarning = true;
539 
540  do
541  {
542  if (debug)
543  {
544  Pout<< nl << "-- Starting Iteration --" << endl;
545  }
546 
547  updateLookup.clear();
548  nbrRegion = UNASSIGNED;
549 
550  // Region information to send
551  for (const polyPatch& pp : patches)
552  {
553  if (pp.coupled())
554  {
555  const labelUList& faceCells = pp.faceCells();
556  SubList<label> patchNbrRegion
557  (
558  nbrRegion,
559  pp.size(),
560  pp.start()-mesh().nInternalFaces()
561  );
562 
563  forAll(faceCells, patchFacei)
564  {
565  const label meshFacei = pp.start()+patchFacei;
566 
567  if (!blockedFace[meshFacei])
568  {
569  // Send the most currently updated region Id
570  const label orig = cellRegion[faceCells[patchFacei]];
571 
572  patchNbrRegion[patchFacei] = localToGlobal[orig];
573  }
574  }
575  }
576  }
578 
579  // Receive and reduce region information
580  for (const polyPatch& pp : patches)
581  {
582  if (pp.coupled())
583  {
584  const labelUList& faceCells = pp.faceCells();
585  SubList<label> patchNbrRegion
586  (
587  nbrRegion,
588  pp.size(),
589  pp.start()-mesh().nInternalFaces()
590  );
591 
592  forAll(faceCells, patchFacei)
593  {
594  const label meshFacei = pp.start()+patchFacei;
595 
596  if (!blockedFace[meshFacei])
597  {
598  // Reduction by retaining the min region id.
599 
600  const label orig = cellRegion[faceCells[patchFacei]];
601 
602  const label sent = localToGlobal[orig];
603  const label recv = patchNbrRegion[patchFacei];
604 
605  if (recv == UNASSIGNED)
606  {
607  if (emitWarning)
608  {
609  Pout<<"Warning in regionSplit:"
610  " received unassigned on "
611  << pp.name() << " at patchFace "
612  << patchFacei
613  << ". Check synchronisation in caller"
614  << nl;
615  }
616  }
617  else if (recv < sent)
618  {
619  // Record the minimum value seen
620 
621  auto fnd = updateLookup.find(sent);
622  if (!fnd.found())
623  {
624  updateLookup.insert(sent, recv);
625  }
626  else if (recv < *fnd)
627  {
628  *fnd = recv;
629  }
630  }
631  }
632  }
633  }
634  }
635 
636 
637  // Note: by always using the minimum region number across the
638  // processor faces, we effect a consolidation of connected regions
639  // and converge to a unique number for each distinct region.
640 
641 
642  // Update localToGlobal according to newly exchanged information
643 
644  inplaceMapValue(updateLookup, localToGlobal);
645 
646  if (debug & 2)
647  {
648  labelList keys(localToGlobal.sortedToc());
649  labelList vals(keys.size());
650  forAll(keys, i)
651  {
652  vals[i] = localToGlobal[keys[i]];
653  }
654 
655  Pout<< "Updated local regions:" << nl
656  << "old: " << flatOutput(keys) << nl
657  << "new: " << flatOutput(vals) << endl;
658  }
659  else if (debug)
660  {
661  Pout<< "Updated " << localToGlobal.size()
662  << " local regions" << endl;
663  }
664 
665  emitWarning = false;
666  // Continue until there are no further changes
667  }
668  while (returnReduce(!updateLookup.empty(), orOp<bool>()));
669 
670 
671  //
672  // We will need compact numbers locally and non-locally
673  //
674 
675  // Determine the local compact numbering
676  label nCompact = 0;
677  {
678  labelHashSet localRegion(2*localToGlobal.size());
679 
680  forAllConstIters(localToGlobal, iter)
681  {
682  const label regioni = iter.val();
683 
684  if (globalRegions.isLocal(regioni))
685  {
686  localRegion.insert(regioni);
687  }
688  }
689 
690  nCompact = localRegion.size();
691  }
692 
693 
694  // The new global numbering using compacted local regions
695  auto globalCompactPtr = autoPtr<globalIndex>::New(nCompact);
696  const auto& globalCompact = *globalCompactPtr;
697 
698 
699  // Determine the following:
700  // - the local compact regions (store as updateLookup)
701  // - the non-local regions, ordered according to the processor on which
702  // they are local.
703 
704 
705  // The local compaction map (updated local to compact local numbering)
706  updateLookup.clear();
707 
708  labelListList sendNonLocal(Pstream::nProcs());
709 
710  {
712 
713  // Use estimate of sizing for non-local regions
714  forAll(nonLocal, proci)
715  {
716  if (proci != Pstream::myProcNo())
717  {
718  nonLocal[proci].resize
719  (
720  2*((nLocalRegions-nCompact)/Pstream::nProcs())
721  );
722  }
723  }
724 
725 
726  forAllConstIters(localToGlobal, iter)
727  {
728  const label regioni = iter.val();
729 
730  if (globalRegions.isLocal(regioni))
731  {
732  updateLookup.insert
733  (
734  regioni,
735  globalCompact.toGlobal(updateLookup.size())
736  );
737  }
738  else
739  {
740  nonLocal[globalRegions.whichProcID(regioni)].insert(regioni);
741  }
742  }
743 
744  if (debug)
745  {
746  Pout<< " per processor nonLocal regions: "
747  << flatOutput(containerSizes(nonLocal)) << endl;
748  }
749 
750 
751  // Convert to label list
752  forAll(sendNonLocal, proci)
753  {
754  sendNonLocal[proci] = nonLocal[proci].toc();
755  }
756  }
757 
758 
759  // Get the wanted region labels into recvNonLocal
760  labelListList recvNonLocal;
761  Pstream::exchange<labelList, label>
762  (
763  sendNonLocal,
764  recvNonLocal
765  );
766 
767 
768  // The recvNonLocal[proci] region labels are what proci requires.
769  // Transcribe into their compacted number.
770 
771  {
772  labelListList sendLocal(std::move(recvNonLocal));
773 
774  for (labelList& send : sendLocal)
775  {
776  for (label& regioni : send)
777  {
778  regioni = updateLookup[regioni];
779  }
780  }
781 
782  // Send back (into recvNonLocal)
783  Pstream::exchange<labelList, label>
784  (
785  sendLocal,
786  recvNonLocal
787  );
788  }
789 
790 
791  // Now recvNonLocal and sendNonLocal contain matched pairs with
792  // sendNonLocal being the non-compact region and recvNonLocal being
793  // the compact region.
794  //
795  // Insert these into the local compaction map.
796 
797  forAll(recvNonLocal, proci)
798  {
799  const labelList& send = sendNonLocal[proci];
800  const labelList& recv = recvNonLocal[proci];
801 
802  forAll(send, i)
803  {
804  updateLookup.insert(send[i], recv[i]);
805  }
806  }
807 
808 
809  // Now renumber the localToGlobal to use the final compact global values
810  inplaceMapValue(updateLookup, localToGlobal);
811 
812 
813  // Can now finally use localToGlobal to renumber cellRegion
814 
815  forAll(cellRegion, celli)
816  {
817  cellRegion[celli] = localToGlobal[cellRegion[celli]];
818  }
819 
820  if (debug)
821  {
822  Info<<"regionSplit::reduceRegions = "
823  << double(timing.elapsed()) << "s\n";
824  }
825 
826  return globalCompactPtr;
827 }
828 
829 
830 // ************************************************************************* //
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:74
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:426
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:72
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:337
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:405
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:290
Foam::clockValue::elapsed
clockValue elapsed() const
The time elapsed from now() since the start time.
Definition: clockValue.C:73
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
Foam::label
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:62
clockValue.H
Foam::MeshObject< polyMesh, TopologicalMeshObject, regionSplit >::mesh
const polyMesh & mesh() const
Definition: MeshObject.H:122
Foam::Info
messageStream Info
Information stream (uses stdout - output is on the master only)
Foam::polyPatch
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:66
Foam::OSstream::name
virtual const fileName & name() const
Return the name of the stream.
Definition: OSstream.H:91
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.
Definition: clockValue.H:51
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:444
Foam::autoPtr< Foam::globalIndex >
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:355
Foam::nl
constexpr char nl
Definition: Ostream.H:372
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:467
Foam::labelHashSet
HashSet< label, Hash< label > > labelHashSet
A HashSet with label keys and label hasher.
Definition: HashSet.H:415
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