box.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) 2017-2020 OpenCFD Ltd.
9 -------------------------------------------------------------------------------
10 License
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 "box.H"
29 #include "mapDistribute.H"
30 #include "OFstream.H"
31 #include "meshTools.H"
32 
33 const Foam::label Foam::processorLODs::box::DROP = 0;
34 const Foam::label Foam::processorLODs::box::REFINE = 1;
35 const Foam::label Foam::processorLODs::box::FIXED = 2;
36 const Foam::label Foam::processorLODs::box::nStartUpIter = 2;
37 
38 namespace Foam
39 {
40 namespace processorLODs
41 {
43 }
44 }
45 
46 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
47 
49 (
50  const List<DynamicList<treeBoundBox>>& fixedBoxes,
51  const label iter
52 ) const
53 {
54  static label time = 0;
55 
56  OFstream os
57  (
58  "processor" + Foam::name(Pstream::myProcNo())
59  + "_time" + Foam::name(time)
60  + "_iter" + Foam::name(iter) + ".obj"
61  );
62 
63  label verti = 0;
64  for (const int proci : Pstream::allProcs())
65  {
66  if (proci == Pstream::myProcNo())
67  {
68  continue;
69  }
70 
71  const DynamicList<treeBoundBox>& procBoxes = fixedBoxes[proci];
72  forAll(procBoxes, boxi)
73  {
74  const treeBoundBox& bb = procBoxes[boxi];
75 
76  // Write the points
77  const pointField pts(bb.points());
78  for (const point& p : pts)
79  {
81  }
82 
83  // Write the box faces
84  for (const face& f : bb.faces)
85  {
86  os << 'f';
87  for (const label fpi : f)
88  {
89  os << ' ' << fpi + verti + 1;
90  }
91  os << nl;
92  }
93  verti += pts.size();
94  }
95  }
96 
97  ++time;
98 }
99 
100 
102 (
103  const label refineIter,
104  const label nTgtObjects,
105  List<labelHashSet>& fixedSendElems,
106  List<List<labelList>>& localTgtElems,
107  List<labelList>& refineFlags,
108  labelList& nElems
109 ) const
110 {
111  PstreamBuffers pBufs(Pstream::commsTypes::nonBlocking);
112 
113  // Identify src boxes that can be refined and send to all remote procs
114  for (const int proci : Pstream::allProcs())
115  {
116  if (proci != Pstream::myProcNo())
117  {
118  UOPstream toProc(proci, pBufs);
119  toProc << nObjectsOfType_ << boxes_[proci] << newToOld_[proci];
120  }
121  }
122 
123  pBufs.finishedSends();
124 
125  // Test each remote src bb with local tgt objects to identify which remote
126  // src boxes can/should be refined
127  for (const int proci : Pstream::allProcs())
128  {
129  if (proci == Pstream::myProcNo())
130  {
131  // Not refining boxes I send to myself - will be sending all local
132  // elements
133  continue;
134  }
135 
136  // Receive the subset of changing src bound boxes for proci
137  UIPstream fromProc(proci, pBufs);
138  const label nObjects = readLabel(fromProc);
139  List<treeBoundBox> remoteSrcBoxes(fromProc);
140  const List<label> newToOld(fromProc);
141 
142  if (remoteSrcBoxes.empty())
143  {
144  continue;
145  }
146 
147 
148  labelList& procRefineFlags = refineFlags[proci];
149  procRefineFlags.setSize(remoteSrcBoxes.size(), FIXED);
150 
151  if (scalar(nTgtObjects)/scalar(nObjects) < 0.1)
152  {
153  // Sending less than 10% of objects of this type
154  // - shortcut by sending all
155  fixedSendElems[proci].insert(identity(nTgtObjects));
156  nElems[proci] = nTgtObjects;
157 
158  continue;
159  }
160 
161  label nElem = 0;
162  List<labelList>& localProcTgtElems = localTgtElems[proci];
163  List<labelList> newLocalProcTgtElems(remoteSrcBoxes.size());
164 
165  forAll(remoteSrcBoxes, srcBoxi)
166  {
167  const treeBoundBox& remSrcBb = remoteSrcBoxes[srcBoxi];
168  DynamicList<label> selectedElems(maxObjectsPerLeaf_);
169 
170  if (refineIter > nStartUpIter)
171  {
172  // Iterate over cached subset of tgt elements
173  const label oldBoxi = newToOld[srcBoxi];
174  const labelList& tgtBoxElems = localProcTgtElems[oldBoxi];
175 
176  for (const label tgtObji : tgtBoxElems)
177  {
178  if (calcTgtBox(tgtObji).overlaps(remSrcBb))
179  {
180  selectedElems.append(tgtObji);
181  }
182  }
183  }
184  else
185  {
186  // Iterating over all target elements
187  for (label tgtObji = 0; tgtObji < nTgtObjects; ++tgtObji)
188  {
189  if (calcTgtBox(tgtObji).overlaps(remSrcBb))
190  {
191  selectedElems.append(tgtObji);
192  }
193  }
194  }
195 
196  nElem += selectedElems.size();
197 
198  if
199  (
200  proci == Pstream::myProcNo()
201  || selectedElems.size() < maxObjectsPerLeaf_
202  )
203  {
204  procRefineFlags[srcBoxi] = FIXED;
205  fixedSendElems[proci].insert(selectedElems);
206  }
207  else
208  {
209  procRefineFlags[srcBoxi] = REFINE;
210  if (refineIter >= nStartUpIter)
211  {
212  newLocalProcTgtElems[srcBoxi].transfer(selectedElems);
213  }
214  }
215  }
216 
217  localProcTgtElems.transfer(newLocalProcTgtElems);
218  nElems[proci] = nElem;
219  }
220 }
221 
222 
224 (
225  const label boxi,
226  const label refineIter,
227  const label nSrcElem,
228  const treeBoundBox& origBox,
229  DynamicList<treeBoundBox>& procBoxes,
230  DynamicList<labelList>& procBoxElems,
231  DynamicList<label>& procNewToOld
232 ) const
233 {
234  // Create the new boxes
235 
236  if (refineIter == nStartUpIter)
237  {
238  // Start caching the addressing
239  for (direction octant = 0; octant < 8; ++octant)
240  {
241  const treeBoundBox subBb(origBox.subBbox(octant));
242 
243  // Identify the src elements for each box
244  DynamicList<label> newElems(nSrcElem/2);
245 
246  for (label srcElemi = 0; srcElemi < nSrcElem; ++srcElemi)
247  {
248  if (subBb.overlaps(calcSrcBox(srcElemi)))
249  {
250  newElems.append(srcElemi);
251  }
252  }
253 
254  if (newElems.size())
255  {
256  procBoxes.append(subBb);
257  procBoxElems.append(newElems);
258  procNewToOld.append(boxi);
259  }
260  }
261  }
262  else
263  {
264  for (direction octant = 0; octant < 8; ++octant)
265  {
266  const treeBoundBox subBb(origBox.subBbox(octant));
267 
268  for (label srcElemi = 0; srcElemi < nSrcElem; ++srcElemi)
269  {
270  if (subBb.overlaps(calcSrcBox(srcElemi)))
271  {
272  procBoxes.append(subBb);
273  break;
274  }
275  }
276  }
277  }
278 }
279 
280 
282 (
283  const label boxi,
284  const labelList& srcAddr,
285  const treeBoundBox& origBox,
286  DynamicList<treeBoundBox>& procBoxes,
287  DynamicList<labelList>& procBoxElems,
288  DynamicList<label>& procNewToOld
289 ) const
290 {
291  // Create the new boxes
292  for (direction octant = 0; octant < 8; ++octant)
293  {
294  const treeBoundBox subBb(origBox.subBbox(octant));
295 
296  // Identify the src elements for each box
297  DynamicList<label> newElems(srcAddr.size()/2);
298 
299  for (const label srcElemi : srcAddr)
300  {
301  if (subBb.overlaps(calcSrcBox(srcElemi)))
302  {
303  newElems.append(srcElemi);
304  }
305  }
306 
307  // Only keeping new box if it overlaps src objects
308  if (newElems.size())
309  {
310  procBoxes.append(subBb);
311  procBoxElems.append(newElems);
312  procNewToOld.append(boxi);
313  }
314  }
315 }
316 
317 
319 (
320  const label refineIter,
321  const label nSrcFaces,
322  const List<labelList>& refineFlags,
323  const labelList& nElems,
324  List<DynamicList<treeBoundBox>>& fixedBoxes
325 )
326 {
327  PstreamBuffers pBufs(Pstream::commsTypes::nonBlocking);
328 
329  // Send refine info back for list of evolving src boxes
330  forAll(refineFlags, proci)
331  {
332  if (proci != Pstream::myProcNo())
333  {
334  UOPstream toProc(proci, pBufs);
335  toProc << nElems[proci] << refineFlags[proci];
336  }
337  }
338 
339  pBufs.finishedSends();
340 
341  // Receive refine refinement actions from remote procs and use to refine
342  // local src boxes
343  bool refineBoxes = false;
344  label nElem = 0;
345  List<DynamicList<label>> newToOld(Pstream::nProcs());
346 
347 
348  for (const int proci : Pstream::allProcs())
349  {
350  if (proci == Pstream::myProcNo())
351  {
352  continue;
353  }
354 
355  UIPstream fromProc(proci, pBufs);
356  nElem += readLabel(fromProc);
357  const labelList refineFlags(fromProc);
358 
359  const List<treeBoundBox>& procBoxes = boxes_[proci];
360  DynamicList<treeBoundBox> newProcBoxes(procBoxes.size());
361  DynamicList<labelList> newProcBoxElems(procBoxes.size());
362  newToOld[proci].setCapacity(boxes_[proci].size());
363  DynamicList<label>& newProcNewToOld = newToOld[proci];
364 
365 
366  forAll(procBoxes, boxi)
367  {
368  if (refineFlags[boxi] == DROP)
369  {
370  // Skip box
371  }
372  else if (refineFlags[boxi] == REFINE)
373  {
374  if (refineIter > nStartUpIter)
375  {
376  // Can use locally cached info to speed up intersection
377  // tests
378  refineBox
379  (
380  boxi,
381  boxSrcElems_[proci][boxi],
382  procBoxes[boxi],
383  newProcBoxes,
384  newProcBoxElems,
385  newProcNewToOld
386  );
387  }
388  else
389  {
390  refineBox
391  (
392  boxi,
393  refineIter,
394  nSrcFaces,
395  procBoxes[boxi],
396  newProcBoxes,
397  newProcBoxElems,
398  newProcNewToOld
399  );
400  }
401 
402  refineBoxes = true;
403  }
404  else if (refineFlags[boxi] == FIXED)
405  {
406  fixedBoxes[proci].append(procBoxes[boxi]);
407  }
408  else
409  {
411  << "Unhandled refine action " << refineFlags[boxi]
412  << abort(FatalError);
413  }
414  }
415 
416  // Only keeping boxes that are to be refined
417  boxes_[proci].transfer(newProcBoxes);
418  boxSrcElems_[proci].transfer(newProcBoxElems);
419  newToOld_[proci].transfer(newProcNewToOld);
420  }
421 
422  return returnReduce(refineBoxes, orOp<bool>());
423 }
424 
425 
427 (
428  const label nSrcElems,
429  const label nTgtElems
430 )
431 {
432  // Store elements to send - will be used to build the mapDistribute
433  List<labelHashSet> fixedSendElems(Pstream::nProcs());
434 
435  // List of local tgt elems to optimise searching for tgt elements inside
436  // remote src boxes
437  List<List<labelList>> localTgtElems(Pstream::nProcs());
438 
439  // Storage of boxes per processor - only useful for debugging
440  List<DynamicList<treeBoundBox>> fixedBoxes(Pstream::nProcs());
441 
442  // Iterate to subdivide src boxes
443  label refinementIter = 1;
444  bool refineSrcBoxes = true;
445  while (refineSrcBoxes && (refinementIter <= nRefineIterMax_))
446  {
447  // Per processor refinement info
448  List<labelList> refineFlags(Pstream::nProcs());
449  labelList nElems(Pstream::nProcs(), Zero);
450 
451  // Assess how many target elements intersect the source bounding boxes
452  // and use the info to flag how the source boxes should be refined
453  setRefineFlags
454  (
455  refinementIter,
456  nTgtElems,
457  fixedSendElems,
458  localTgtElems,
459  refineFlags,
460  nElems
461  );
462 
463  // Refine the source bounding boxes
464  refineSrcBoxes =
465  doRefineBoxes
466  (
467  refinementIter,
468  nSrcElems,
469  refineFlags,
470  nElems,
471  fixedBoxes
472  );
473 
474  ++refinementIter;
475 
476  if (debug > 1)
477  {
478  // Include any boxes that are still evolving
479  List<DynamicList<treeBoundBox>> allBoxes(fixedBoxes);
480  forAll(allBoxes, proci)
481  {
482  allBoxes[proci].append(boxes_[proci]);
483  }
484  writeBoxes(allBoxes, refinementIter);
485  }
486  }
487 
488  if (debug)
489  {
490  Pout<< "Local src boxes after " << refinementIter-1 << " iterations:"
491  << nl;
492 
493  forAll(fixedBoxes, proci)
494  {
495  // Include any boxes that are still evolving in box count
496  label nBox = fixedBoxes[proci].size() + boxes_[proci].size();
497  Pout<< " proc:" << proci << " nBoxes:" << nBox << nl;
498  }
499  Pout<< endl;
500  }
501 
502  // Convert send elems into a List<labelList>
503  List<labelList> sendElems(Pstream::nProcs());
504  forAll(localTgtElems, proci)
505  {
506  if (proci == Pstream::myProcNo() && nSrcElems)
507  {
508  sendElems[proci] = identity(nTgtElems);
509  }
510  else
511  {
512  labelHashSet& allIDs = fixedSendElems[proci];
513 
514  const List<labelList>& procBoxElems = localTgtElems[proci];
515 
516  for (const labelList& elems: procBoxElems)
517  {
518  allIDs.insert(elems);
519  }
520 
521  sendElems[proci] = allIDs.toc();
522  }
523  }
524 
525  fixedSendElems.clear();
526  localTgtElems.clear();
527 
528  if (debug)
529  {
530  Pout<< "Local objects: " << nTgtElems << " Send map:" << nl
531  << tab << "proc" << tab << "objects" << endl;
532 
533  forAll(sendElems, proci)
534  {
535  Pout<< tab << proci << tab << sendElems[proci].size()
536  << endl;
537  }
538  }
539 
540  return createLODMap(sendElems);
541 }
542 
543 
545 (
546  List<labelList>& sendElems
547 ) const
548 {
549  // Send over how many objects I need to receive
550  const label localProci = Pstream::myProcNo();
551  labelListList sendSizes(Pstream::nProcs());
552  sendSizes[localProci].setSize(Pstream::nProcs());
553  forAll(sendElems, proci)
554  {
555  sendSizes[localProci][proci] = sendElems[proci].size();
556  }
557  Pstream::gatherList(sendSizes);
558  Pstream::scatterList(sendSizes);
559 
560 
561  // Determine order of receiving
562  labelListList constructMap(Pstream::nProcs());
563 
564  // My local segment first
565  constructMap[localProci] = identity(sendElems[localProci].size());
566 
567  label segmenti = constructMap[localProci].size();
568  forAll(constructMap, proci)
569  {
570  if (proci != localProci)
571  {
572  // What I need to receive is what other processor is sending to me
573  label nRecv = sendSizes[proci][localProci];
574  constructMap[proci].setSize(nRecv);
575 
576  for (label& addr : constructMap[proci])
577  {
578  addr = segmenti++;
579  }
580  }
581  }
582 
584  (
585  new mapDistribute
586  (
587  segmenti, // size after construction
588  std::move(sendElems),
589  std::move(constructMap)
590  )
591  );
592 
593  return mapPtr;
594 }
595 
596 
597 // * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * //
598 
600 (
601  const UList<point>& srcPoints,
602  const UList<point>& tgtPoints,
603  const label maxObjectsPerLeaf,
604  const label nObjectsOfType,
605  const label nRefineIterMax
606 )
607 :
608  processorLOD(maxObjectsPerLeaf, nObjectsOfType),
609  srcPoints_(srcPoints),
610  tgtPoints_(tgtPoints),
611  boxes_(Pstream::nProcs()),
612  nRefineIterMax_(nRefineIterMax),
613  newToOld_(Pstream::nProcs()),
614  boxSrcElems_(Pstream::nProcs())
615 {
616  // Initialise each processor with a single box large enough to include all
617  // of its local src points
618  if (srcPoints_.size())
619  {
620  forAll(boxes_, proci)
621  {
622  List<treeBoundBox>& procBoxes = boxes_[proci];
623 
624  // Note: inflate to ease overlap operations and to handle 2-D
625  // axis-aligned objects
626  treeBoundBox srcBb(srcPoints_);
627  srcBb.inflate(0.01);
628 
629  DynamicList<treeBoundBox> newProcBoxes(1);
630  newProcBoxes.append(srcBb);
631  procBoxes.transfer(newProcBoxes);
632  }
633  }
634 }
635 
636 
637 // ************************************************************************* //
Foam::expressions::patchExpr::debug
int debug
Static debugging option.
Foam::processorLODs::box::doRefineBoxes
bool doRefineBoxes(const label refineIter, const label nSrcFaces, const List< labelList > &refineFlags, const labelList &nElems, List< DynamicList< treeBoundBox >> &fixedBoxes)
Apply the box refinements.
Definition: box.C:319
meshTools.H
Foam::processorLODs::box::box
box(const UList< point > &srcPoints, const UList< point > &tgtPoints, const label maxObjectsPerLeaf, const label nObjectsOfType, const label nRefineIterMax=100)
Construct from list of points.
Definition: box.C:600
p
volScalarField & p
Definition: createFieldRefs.H:8
Foam::UOPstream
Output inter-processor communications stream operating on external buffer.
Definition: UOPstream.H:57
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::processorLODs::box::nStartUpIter
static const label nStartUpIter
Number of iterations before element indices are cached.
Definition: box.H:96
Foam::HashTable::toc
List< Key > toc() const
The table of contents (the keys) in unsorted order.
Definition: HashTable.C:121
Foam::treeBoundBox::points
tmp< pointField > points() const
Vertex coordinates. In octant coding.
Definition: treeBoundBox.C:92
Foam::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
Foam::DynamicList
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
Definition: DynamicList.H:55
Foam::meshTools::writeOBJ
void writeOBJ(Ostream &os, const point &pt)
Write obj representation of a point.
Definition: meshTools.C:203
Foam::boundBox::inflate
void inflate(const scalar s)
Inflate box by factor*mag(span) in all dimensions.
Definition: boundBox.C:175
Foam::treeBoundBox
Standard boundBox with extra functionality for use in octree.
Definition: treeBoundBox.H:86
Foam::PstreamBuffers
Buffers for inter-processor communications streams (UOPstream, UIPstream).
Definition: PstreamBuffers.H:87
Foam::List::append
void append(const T &val)
Append an element at the end of the list.
Definition: ListI.H:182
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:350
Foam::processorLODs::box::setRefineFlags
void setRefineFlags(const label refineIter, const label nTgtObjects, List< labelHashSet > &fixedSendElems, List< List< labelList >> &localTgtElems, List< labelList > &refineFlags, labelList &nElems) const
Set the box refinement flags.
Definition: box.C:102
Foam::processorLODs::box::DROP
static const label DROP
Drop/discard.
Definition: box.H:70
Foam::processorLODs::box::FIXED
static const label FIXED
Fixed - do not touch.
Definition: box.H:76
Foam::Pout
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
Foam::processorLODs::box::refineBox
void refineBox(const label boxi, const label refineIter, const label nSrcElem, const treeBoundBox &origBox, DynamicList< treeBoundBox > &procBoxes, DynamicList< labelList > &procBoxElems, DynamicList< label > &procNewToOld) const
Definition: box.C:224
Foam::HashSet< label, Hash< label > >
Foam::treeBoundBox::subBbox
treeBoundBox subBbox(const direction octant) const
Sub-box of given octant. Midpoint calculated.
Definition: treeBoundBox.C:106
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
OFstream.H
Foam::processorLODs::box
Creates the parallel distribution map by describing the source and target objects using box shapes.
Definition: box.H:59
Foam::Field< vector >
Foam::name
word name(const complex &c)
Return string representation of complex.
Definition: complex.C:76
Foam::treeBoundBox::faces
static const faceList faces
Face to point addressing.
Definition: treeBoundBox.H:151
Foam::DynamicList::append
DynamicList< T, SizeMin > & append(const T &val)
Append an element to the end of this list.
Definition: DynamicListI.H:474
Foam::mapDistribute
Class containing processor-to-processor mapping information.
Definition: mapDistribute.H:163
Foam::List::transfer
void transfer(List< T > &list)
Definition: List.C:459
Foam::processorLODs::box::createMap
autoPtr< mapDistribute > createMap(const label nSrcElems, const label nTgtElems)
Definition: box.C:427
box.H
Foam::PstreamBuffers::finishedSends
void finishedSends(const bool block=true)
Mark all sends as having been done. This will start receives.
Definition: PstreamBuffers.C:80
Foam::processorLODs::defineTypeNameAndDebug
defineTypeNameAndDebug(box, 0)
Foam::processorLOD
Base class to generate a parallel distribution map for sending sufficient target objects to cover a d...
Definition: processorLOD.H:52
Foam::processorLODs::box::writeBoxes
void writeBoxes(const List< DynamicList< treeBoundBox >> &fixedBoxes, const label iter) const
Helper function to write the boxes in OBJ format.
Definition: box.C:49
Foam::FatalError
error FatalError
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:144
Foam::OFstream
Output to file stream, using an OSstream.
Definition: OFstream.H:53
Foam::autoPtr< Foam::mapDistribute >
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:381
Foam::processorLODs::box::REFINE
static const label REFINE
Refine.
Definition: box.H:73
Foam::tab
constexpr char tab
Definition: Ostream.H:384
Foam::nl
constexpr char nl
Definition: Ostream.H:385
mapDistribute.H
f
labelList f(nPoints)
Foam::Vector< scalar >
Foam::readLabel
label readLabel(const char *buf)
Parse entire buffer as a label, skipping leading/trailing whitespace.
Definition: label.H:66
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: BitOps.H:63
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
Foam::identity
labelList identity(const label len, label start=0)
Create identity map of the given length with (map[i] == i)
Definition: labelList.C:38
Foam::List::clear
void clear()
Clear the list, i.e. set size to zero.
Definition: ListI.H:115
Foam::HashSet::insert
bool insert(const Key &key)
Insert a new entry, not overwriting existing entries.
Definition: HashSet.H:181
Foam::direction
uint8_t direction
Definition: direction.H:52
Foam::face
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:72
Foam::UIPstream
Input inter-processor communications stream operating on external buffer.
Definition: UIPstream.H:56
Foam::List::setSize
void setSize(const label newSize)
Alias for resize(const label)
Definition: ListI.H:146
Foam::orOp
Definition: ops.H:234
Foam::processorLODs::box::createLODMap
autoPtr< mapDistribute > createLODMap(List< labelList > &sendElems) const
Use the current list of send elements to create the mapDistribute.
Definition: box.C:545