refinementHistory.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-2017 OpenFOAM Foundation
9  Copyright (C) 2015-2022 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 "refinementHistory.H"
30 #include "mapPolyMesh.H"
31 #include "mapDistributePolyMesh.H"
32 #include "polyMesh.H"
33 #include "syncTools.H"
34 #include "topoSet.H"
35 
36 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
37 
38 namespace Foam
39 {
40  defineTypeNameAndDebug(refinementHistory, 0);
41 }
42 
43 
44 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
45 
46 bool Foam::refinementHistory::readContents()
47 {
48  if (isReadRequired() || (isReadOptional() && headerOk()))
49  {
50  readStream(typeName) >> *this;
51  close();
52  return true;
53  }
54 
55  return false;
56 }
57 
58 
59 void Foam::refinementHistory::writeEntry
60 (
61  const List<splitCell8>& splitCells,
62  const splitCell8& split
63 )
64 {
65  // Write me:
66  if (split.addedCellsPtr_)
67  {
68  Pout<< "parent:" << split.parent_
69  << " subCells:" << split.addedCellsPtr_()
70  << endl;
71  }
72  else
73  {
74  Pout<< "parent:" << split.parent_
75  << " no subcells"
76  << endl;
77  }
78 
79  if (split.parent_ >= 0)
80  {
81  Pout<< "parent data:" << endl;
82  // Write my parent
83  string oldPrefix = Pout.prefix();
84  Pout.prefix() = " " + oldPrefix;
85  writeEntry(splitCells, splitCells[split.parent_]);
86  Pout.prefix() = oldPrefix;
87  }
88 }
89 
90 
92 (
93  const labelList& visibleCells,
94  const List<splitCell8>& splitCells
95 )
96 {
97  string oldPrefix = Pout.prefix();
98  Pout.prefix() = "";
99 
100  forAll(visibleCells, celli)
101  {
102  label index = visibleCells[celli];
103 
104  if (index >= 0)
105  {
106  Pout<< "Cell from refinement:" << celli << " index:" << index
107  << endl;
108 
109  string oldPrefix = Pout.prefix();
110  Pout.prefix() = " " + oldPrefix;
111  writeEntry(splitCells, splitCells[index]);
112  Pout.prefix() = oldPrefix;
113  }
114  else
115  {
116  Pout<< "Unrefined cell:" << celli << " index:" << index << endl;
117  }
118  }
119  Pout.prefix() = oldPrefix;
120 }
121 
122 
123 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
124 
126 :
127  parent_(-1),
128  addedCellsPtr_(nullptr)
129 {}
130 
131 
133 :
134  parent_(parent),
135  addedCellsPtr_(nullptr)
136 {}
137 
138 
140 :
141  splitCell8()
142 {
143  is >> *this;
144 }
145 
146 
148 :
149  parent_(rhs.parent_),
150  addedCellsPtr_(rhs.addedCellsPtr_.clone()) // Copy, not steal
151 {}
152 
153 
154 // * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * * //
155 
157 {
158  // Assignment operator since autoPtr otherwise 'steals' storage.
159 
160  if (this == &rhs)
161  {
162  return; // Self-assignment is a no-op
163  }
165  parent_ = rhs.parent_;
166  addedCellsPtr_.reset(rhs.addedCellsPtr_.clone()); // Copy, not steal
167 }
168 
169 
170 bool Foam::refinementHistory::splitCell8::operator==
171 (
172  const splitCell8& rhs
173 )
174 const
175 {
176  if (parent_ != rhs.parent_)
177  {
178  return false;
179  }
180  if (bool(addedCellsPtr_) != bool(rhs.addedCellsPtr_))
181  {
182  return false;
183  }
184  else if (addedCellsPtr_) // With previous test, means rhs is also defined
185  {
186  return addedCellsPtr_() == rhs.addedCellsPtr_();
187  }
188 
189  return true;
190 }
191 
192 
193 bool Foam::refinementHistory::splitCell8::operator!=
194 (
195  const splitCell8& rhs
196 ) const
197 {
198  return !operator==(rhs);
199 }
200 
201 
202 // * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * * //
203 
204 Foam::Istream& Foam::operator>>(Istream& is, refinementHistory::splitCell8& sc)
205 {
206  labelList addedCells;
207 
208  is >> sc.parent_ >> addedCells;
209 
210  if (addedCells.size())
211  {
212  sc.addedCellsPtr_.reset(new FixedList<label, 8>(addedCells));
213  }
214  else
215  {
216  sc.addedCellsPtr_.reset(nullptr);
217  }
218 
219  return is;
220 }
221 
222 
223 Foam::Ostream& Foam::operator<<
224 (
225  Ostream& os,
226  const refinementHistory::splitCell8& sc
227 )
228 {
229  // Output as labelList so we can have 0 sized lists. Alternative is to
230  // output as fixedlist with e.g. -1 elements and check for this upon
231  // reading. However would cause much more data to be transferred.
232 
233  labelList labels;
234 
235  if (sc.addedCellsPtr_)
236  {
237  labels = sc.addedCellsPtr_();
238  }
239 
240  return os << sc.parent_ << token::SPACE << labels;
241 }
242 
243 
244 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
245 
246 void Foam::refinementHistory::checkIndices() const
247 {
248  // Check indices.
249  forAll(visibleCells_, i)
250  {
251  if (visibleCells_[i] < 0 && visibleCells_[i] >= splitCells_.size())
252  {
254  << "Illegal entry " << visibleCells_[i]
255  << " in visibleCells at location" << i << nl
256  << "It points outside the range of splitCells : 0.."
257  << splitCells_.size()-1
258  << abort(FatalError);
259  }
260  }
261 }
262 
263 
264 Foam::label Foam::refinementHistory::allocateSplitCell
265 (
266  const label parent,
267  const label i
268 )
269 {
270  label index = -1;
271 
272  if (freeSplitCells_.size())
273  {
274  index = freeSplitCells_.back();
275  freeSplitCells_.pop_back();
276 
277  splitCells_[index] = splitCell8(parent);
278  }
279  else
280  {
281  index = splitCells_.size();
282  splitCells_.push_back(splitCell8(parent));
283  }
284 
285 
286  // Update the parent field
287  if (parent >= 0)
288  {
289  splitCell8& parentSplit = splitCells_[parent];
290 
291  if (!parentSplit.addedCellsPtr_)
292  {
293  // Allocate storage on parent for the 8 subcells.
294  parentSplit.addedCellsPtr_.reset(new FixedList<label, 8>(-1));
295  }
296 
297 
298  // Store me on my parent
299  FixedList<label, 8>& parentSplits = parentSplit.addedCellsPtr_();
300 
301  parentSplits[i] = index;
302  }
303 
304  return index;
305 }
306 
307 
308 void Foam::refinementHistory::freeSplitCell(const label index)
309 {
310  splitCell8& split = splitCells_[index];
311 
312  // Make sure parent does not point to me anymore.
313  if (split.parent_ >= 0)
314  {
315  autoPtr<FixedList<label, 8>>& subCellsPtr =
316  splitCells_[split.parent_].addedCellsPtr_;
317 
318  if (subCellsPtr)
319  {
320  FixedList<label, 8>& subCells = subCellsPtr();
321 
322  label myPos = subCells.find(index);
323 
324  if (myPos == -1)
325  {
327  << "Problem: cannot find myself in"
328  << " parents' children" << abort(FatalError);
329  }
330  else
331  {
332  subCells[myPos] = -1;
333  }
334  }
335  }
336 
337  // Mark splitCell as free
338  split.parent_ = -2;
339 
340  // Add to cache of free splitCells
341  freeSplitCells_.append(index);
342 }
343 
344 
345 void Foam::refinementHistory::markSplit
346 (
347  const label index,
348  labelList& oldToNew,
349  DynamicList<splitCell8>& newSplitCells
350 ) const
351 {
352  if (oldToNew[index] == -1)
353  {
354  // Not yet compacted.
355 
356  const splitCell8& split = splitCells_[index];
357 
358  oldToNew[index] = newSplitCells.size();
359  newSplitCells.append(split);
360 
361  if (split.parent_ >= 0)
362  {
363  markSplit(split.parent_, oldToNew, newSplitCells);
364  }
365  if (split.addedCellsPtr_)
366  {
367  const FixedList<label, 8>& splits = split.addedCellsPtr_();
368 
369  forAll(splits, i)
370  {
371  if (splits[i] >= 0)
372  {
373  markSplit(splits[i], oldToNew, newSplitCells);
374  }
375  }
376  }
377  }
378 }
379 
380 
381 void Foam::refinementHistory::mark
382 (
383  const label val,
384  const label index,
385  labelList& splitToVal
386 ) const
387 {
388  splitToVal[index] = val;
389 
390  const splitCell8& split = splitCells_[index];
391 
392  if (split.addedCellsPtr_)
393  {
394  const FixedList<label, 8>& splits = split.addedCellsPtr_();
395 
396  forAll(splits, i)
397  {
398  if (splits[i] >= 0)
399  {
400  mark(val, splits[i], splitToVal);
401  }
402  }
403  }
404 }
405 
406 
407 Foam::label Foam::refinementHistory::markCommonCells
408 (
409  labelList& cellToCluster
410 ) const
411 {
412  label clusterI = 0;
413 
414  labelList splitToCluster(splitCells_.size(), -1);
415 
416  // Pass1: find top of all clusters
417  forAll(visibleCells_, cellI)
418  {
419  label index = visibleCells_[cellI];
420 
421  if (index >= 0)
422  {
423  // Find highest ancestor
424  while (splitCells_[index].parent_ != -1)
425  {
426  index = splitCells_[index].parent_;
427  }
428 
429  // Mark tree with clusterI
430  if (splitToCluster[index] == -1)
431  {
432  mark(clusterI, index, splitToCluster);
433  clusterI++;
434  }
435  }
436  }
437 
438  // Pass2: mark all cells with cluster
439  cellToCluster.setSize(visibleCells_.size(), -1);
440 
441  forAll(visibleCells_, cellI)
442  {
443  label index = visibleCells_[cellI];
444 
445  if (index >= 0)
446  {
447  cellToCluster[cellI] = splitToCluster[index];
448  }
449  }
450 
451  return clusterI;
452 }
453 
454 
456 (
457  boolList& blockedFace,
458  PtrList<labelList>& specifiedProcessorFaces,
459  labelList& specifiedProcessor,
460  List<labelPair>& explicitConnections
461 ) const
462 {
463  const polyMesh& mesh = dynamic_cast<const polyMesh&>(db());
464 
465  blockedFace.setSize(mesh.nFaces(), true);
466 
467  // Find common parent for all cells
468  labelList cellToCluster;
469  markCommonCells(cellToCluster);
470 
471 
472  // Unblock all faces inbetween same cluster
473 
474  label nUnblocked = 0;
475 
476  forAll(mesh.faceNeighbour(), faceI)
477  {
478  label ownCluster = cellToCluster[mesh.faceOwner()[faceI]];
479  label neiCluster = cellToCluster[mesh.faceNeighbour()[faceI]];
480 
481  if (ownCluster != -1 && ownCluster == neiCluster)
482  {
483  if (blockedFace[faceI])
484  {
485  blockedFace[faceI] = false;
486  nUnblocked++;
487  }
488  }
489  }
490 
492  {
493  Info<< type() << " : unblocked "
494  << returnReduce(nUnblocked, sumOp<label>()) << " faces" << endl;
495  }
496 
497  syncTools::syncFaceList(mesh, blockedFace, andEqOp<bool>());
498 }
499 
500 
502 (
503  const boolList& blockedFace,
504  const PtrList<labelList>& specifiedProcessorFaces,
505  const labelList& specifiedProcessor,
506  const List<labelPair>& explicitConnections,
507  labelList& decomposition
508 ) const
509 {
510  const polyMesh& mesh = dynamic_cast<const polyMesh&>(db());
511 
512  // Find common parent for all cells
513  labelList cellToCluster;
514  label nClusters = markCommonCells(cellToCluster);
515 
516  // Unblock all faces inbetween same cluster
517 
518 
519  labelList clusterToProc(nClusters, -1);
520 
521  label nChanged = 0;
522 
523  forAll(mesh.faceNeighbour(), faceI)
524  {
525  label own = mesh.faceOwner()[faceI];
526  label nei = mesh.faceNeighbour()[faceI];
527 
528  label ownCluster = cellToCluster[own];
529  label neiCluster = cellToCluster[nei];
530 
531  if (ownCluster != -1 && ownCluster == neiCluster)
532  {
533  if (clusterToProc[ownCluster] == -1)
534  {
535  clusterToProc[ownCluster] = decomposition[own];
536  }
537 
538  if (decomposition[own] != clusterToProc[ownCluster])
539  {
540  decomposition[own] = clusterToProc[ownCluster];
541  nChanged++;
542  }
543  if (decomposition[nei] != clusterToProc[ownCluster])
544  {
545  decomposition[nei] = clusterToProc[ownCluster];
546  nChanged++;
547  }
548  }
549  }
550 
552  {
553  Info<< type() << " : changed decomposition on "
554  << returnReduce(nChanged, sumOp<label>()) << " cells" << endl;
555  }
556 }
557 
558 
559 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
560 
562 :
563  regIOobject(io),
564  active_(false)
565 {
566  // Warn for MUST_READ_IF_MODIFIED
567  warnNoRereading<refinementHistory>();
568 
569  readContents();
570 
571  // When running in redistributePar + READ_IF_PRESENT it can happen
572  // that some processors do have refinementHistory and some don't so
573  // test for active has to be outside of above condition.
574  active_ = returnReduceOr(visibleCells_.size());
575 
576  if (debug)
577  {
578  Pout<< "refinementHistory::refinementHistory :"
579  << " constructed history from IOobject :"
580  << " splitCells:" << splitCells_.size()
581  << " visibleCells:" << visibleCells_.size()
582  << " active:" << active_
583  << endl;
584  }
585 }
586 
587 
589 (
590  const IOobject& io,
591  const List<splitCell8>& splitCells,
592  const labelList& visibleCells,
593  const bool active
594 )
595 :
596  regIOobject(io),
597  active_(active),
598  splitCells_(splitCells),
599  freeSplitCells_(),
600  visibleCells_(visibleCells)
601 {
602  // Warn for MUST_READ_IF_MODIFIED
603  warnNoRereading<refinementHistory>();
604 
605  readContents();
606 
607  // Check indices.
608  checkIndices();
609 
610  if (debug)
611  {
612  Pout<< "refinementHistory::refinementHistory :"
613  << " constructed history from IOobject or components :"
614  << " splitCells:" << splitCells_.size()
615  << " visibleCells:" << visibleCells_.size()
616  << " active:" << active_
617  << endl;
618  }
619 }
620 
621 
623 (
624  const IOobject& io,
625  const label nCells
626 )
627 :
628  regIOobject(io),
629  active_(false),
630  freeSplitCells_()
631 {
632  // Warn for MUST_READ_IF_MODIFIED
633  warnNoRereading<refinementHistory>();
634 
635  if (!readContents())
636  {
637  visibleCells_.setSize(nCells);
638  splitCells_.setCapacity(nCells);
639 
640  for (label cellI = 0; cellI < nCells; cellI++)
641  {
642  visibleCells_[cellI] = cellI;
643  splitCells_.append(splitCell8());
644  }
645  }
646 
647  active_ = returnReduceOr(visibleCells_.size());
648 
649 
650  // Check indices.
651  checkIndices();
652 
653  if (debug)
654  {
655  Pout<< "refinementHistory::refinementHistory :"
656  << " constructed history from IOobject or initial size :"
657  << " splitCells:" << splitCells_.size()
658  << " visibleCells:" << visibleCells_.size()
659  << " active:" << active_
660  << endl;
661  }
662 }
663 
664 
665 // Construct from initial number of cells (all visible)
667 (
668  const IOobject& io,
669  const label nCells,
670  const bool active
671 )
672 :
673  regIOobject(io),
674  active_(active),
675  freeSplitCells_()
676 {
677  // Warn for MUST_READ_IF_MODIFIED
678  warnNoRereading<refinementHistory>();
679 
680  if (!readContents())
681  {
682  visibleCells_.setSize(nCells);
683  splitCells_.setCapacity(nCells);
684 
685  for (label celli = 0; celli < nCells; celli++)
686  {
687  visibleCells_[celli] = celli;
688  splitCells_.append(splitCell8());
689  }
690  }
691 
692  // Check indices.
693  checkIndices();
694 
695  if (debug)
696  {
697  Pout<< "refinementHistory::refinementHistory :"
698  << " constructed history from IOobject or initial size :"
699  << " splitCells:" << splitCells_.size()
700  << " visibleCells:" << visibleCells_.size()
701  << " active:" << active_
702  << endl;
703  }
704 }
705 
706 
708 (
709  const IOobject& io,
710  const refinementHistory& rh
711 )
712 :
713  regIOobject(io),
714  active_(rh.active_),
715  splitCells_(rh.splitCells()),
716  freeSplitCells_(rh.freeSplitCells()),
717  visibleCells_(rh.visibleCells())
718 {
719  if (debug)
720  {
721  Pout<< "refinementHistory::refinementHistory : constructed initial"
722  << " history." << endl;
723  }
724 }
725 
726 
728 (
729  const IOobject& io,
730  const UPtrList<const labelList>& cellMaps,
731  const UPtrList<const refinementHistory>& refs
732 )
733 :
734  regIOobject(io),
735  active_(false)
736 {
737  if (io.isAnyRead())
738  {
740  << "read option IOobject::MUST_READ or READ_IF_PRESENT "
741  << "or MUST_READ_IF_MODIFIED"
742  << " suggests that a read constructor would be more appropriate."
743  << endl;
744  }
745 
746  const polyMesh& mesh = dynamic_cast<const polyMesh&>(db());
747 
748 
749  // Determine offsets into splitCells
750  labelList offsets(refs.size()+1);
751  offsets[0] = 0;
752  forAll(refs, refI)
753  {
754  const DynamicList<splitCell8>& subSplits = refs[refI].splitCells();
755  offsets[refI+1] = offsets[refI]+subSplits.size();
756  }
757 
758  // Construct merged splitCells
759  splitCells_.setSize(offsets.last());
760  forAll(refs, refI)
761  {
762  const DynamicList<splitCell8>& subSplits = refs[refI].splitCells();
763  forAll(subSplits, i)
764  {
765  splitCell8& newSplit = splitCells_[offsets[refI]+i];
766 
767  // Copy
768  newSplit = subSplits[i];
769 
770  // Offset indices
771  if (newSplit.parent_ >= 0)
772  {
773  newSplit.parent_ += offsets[refI];
774  }
775 
776  if (newSplit.addedCellsPtr_)
777  {
778  FixedList<label, 8>& splits = newSplit.addedCellsPtr_();
779 
780  forAll(splits, i)
781  {
782  if (splits[i] >= 0)
783  {
784  splits[i] += offsets[refI];
785  }
786  }
787  }
788  }
789  }
790 
791 
792  // Construct merged visibleCells
793  visibleCells_.setSize(mesh.nCells(), -1);
794  forAll(refs, refI)
795  {
796  const labelList& cellMap = cellMaps[refI];
797  const labelList& subVis = refs[refI].visibleCells();
798 
799  forAll(subVis, i)
800  {
801  label& newVis = visibleCells_[cellMap[i]];
802 
803  newVis = subVis[i];
804  if (newVis >= 0)
805  {
806  newVis += offsets[refI];
807  }
808  }
809  }
810 
811 
812  // Is active if any of the refinementHistories is active (assumes active
813  // flag parallel synchronised)
814  active_ = false;
815  forAll(refs, refI)
816  {
817  if (refs[refI].active())
818  {
819  active_ = true;
820  break;
821  }
822  }
823 
824  // Check indices.
825  checkIndices();
826 
827  if (debug)
828  {
829  Pout<< "refinementHistory::refinementHistory :"
830  << " constructed history from multiple refinementHistories :"
831  << " splitCells:" << splitCells_.size()
832  << " visibleCells:" << visibleCells_.size()
833  << endl;
834  }
835 }
836 
837 
838 Foam::refinementHistory::refinementHistory(const IOobject& io, Istream& is)
839 :
840  regIOobject(io),
841  splitCells_(is),
842  freeSplitCells_(),
843  visibleCells_(is)
844 {
845  active_ = returnReduceOr(visibleCells_.size());
846 
847  // Check indices.
848  checkIndices();
849 
850  if (debug)
851  {
852  Pout<< "refinementHistory::refinementHistory :"
853  << " constructed history from Istream"
854  << " splitCells:" << splitCells_.size()
855  << " visibleCells:" << visibleCells_.size()
856  << endl;
857  }
858 }
859 
860 
861 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
862 
864 (
865  const IOobject& io,
866  // Per visible cell the processor it is going to
867  const labelList& decomposition,
868  // Per splitCell entry the processor it moves to
869  const labelList& splitCellProc,
870  // Per splitCell entry the number of live cells that move to that processor
871  const labelList& splitCellNum,
872 
873  const label procI,
874 
875  // From old to new splitCells
876  labelList& oldToNewSplit
877 ) const
878 {
879  oldToNewSplit.setSize(splitCells_.size());
880  oldToNewSplit = -1;
881 
882  // Compacted splitCells
883  DynamicList<splitCell8> newSplitCells(splitCells_.size());
884 
885  // Loop over all entries. Note: could recurse like countProc so only
886  // visit used entries but is probably not worth it.
887 
888  forAll(splitCells_, index)
889  {
890  if (splitCellProc[index] == procI && splitCellNum[index] == 8)
891  {
892  // Entry moves in its whole to procI
893  oldToNewSplit[index] = newSplitCells.size();
894  newSplitCells.append(splitCells_[index]);
895  }
896  }
897 
898  // Add live cells that are subsetted.
899  forAll(visibleCells_, cellI)
900  {
901  label index = visibleCells_[cellI];
902 
903  if (index >= 0 && decomposition[cellI] == procI)
904  {
905  label parent = splitCells_[index].parent_;
906 
907  // Create new splitCell with parent
908  oldToNewSplit[index] = newSplitCells.size();
909  newSplitCells.append(splitCell8(parent));
910  }
911  }
912 
913  //forAll(oldToNewSplit, index)
914  //{
915  // Pout<< "old:" << index << " new:" << oldToNewSplit[index]
916  // << endl;
917  //}
918 
919  newSplitCells.shrink();
920 
921  // Renumber contents of newSplitCells
922  forAll(newSplitCells, index)
923  {
924  splitCell8& split = newSplitCells[index];
925 
926  if (split.parent_ >= 0)
927  {
928  split.parent_ = oldToNewSplit[split.parent_];
929  }
930  if (split.addedCellsPtr_)
931  {
932  FixedList<label, 8>& splits = split.addedCellsPtr_();
933 
934  forAll(splits, i)
935  {
936  if (splits[i] >= 0)
937  {
938  splits[i] = oldToNewSplit[splits[i]];
939  }
940  }
941  }
942  }
943 
944 
945  // Count number of cells
946  label nSub = 0;
947  forAll(decomposition, cellI)
948  {
949  if (decomposition[cellI] == procI)
950  {
951  nSub++;
952  }
953  }
954 
955  labelList newVisibleCells(nSub);
956  nSub = 0;
957 
958  forAll(visibleCells_, cellI)
959  {
960  if (decomposition[cellI] == procI)
961  {
962  label index = visibleCells_[cellI];
963  if (index >= 0)
964  {
965  index = oldToNewSplit[index];
966  }
967  newVisibleCells[nSub++] = index;
968  }
969  }
970 
971  return autoPtr<refinementHistory>
972  (
973  new refinementHistory
974  (
975  io,
976  newSplitCells,
977  newVisibleCells,
978  active_
979  )
980  );
981 }
982 
983 
985 (
986  const IOobject& io,
987  const labelList& cellMap
988 ) const
989 {
990  if (active_)
991  {
992  // Mark selected cells with '1'
993  labelList decomposition(visibleCells_.size(), Zero);
994  forAll(cellMap, i)
995  {
996  decomposition[cellMap[i]] = 1;
997  }
998 
999 
1000  // Per splitCell entry the processor it moves to
1001  labelList splitCellProc(splitCells_.size(), -1);
1002  // Per splitCell entry the number of live cells that move to that
1003  // processor
1004  labelList splitCellNum(splitCells_.size(), Zero);
1005 
1006  forAll(visibleCells_, cellI)
1007  {
1008  label index = visibleCells_[cellI];
1009 
1010  if (index >= 0)
1011  {
1012  countProc
1013  (
1014  splitCells_[index].parent_,
1015  decomposition[cellI],
1016  splitCellProc,
1017  splitCellNum
1018  );
1019  }
1020  }
1021 
1022  labelList oldToNewSplit;
1023  return clone
1024  (
1025  io,
1026  decomposition,
1027  splitCellProc,
1028  splitCellNum,
1029  1, //procI,
1030  oldToNewSplit
1031  );
1032  }
1033  else
1034  {
1035  return autoPtr<refinementHistory>
1036  (
1037  new refinementHistory
1038  (
1039  io,
1040  List<splitCell8>(),
1041  labelList(),
1042  false
1043  )
1044  );
1045  }
1046 }
1047 
1048 
1049 void Foam::refinementHistory::resize(const label size)
1050 {
1051  label oldSize = visibleCells_.size();
1052 
1053  if (debug)
1054  {
1055  Pout<< "refinementHistory::resize from " << oldSize << " to " << size
1056  << " cells" << endl;
1057  }
1058 
1059  visibleCells_.setSize(size);
1060 
1061  // Set additional elements to -1.
1062  for (label i = oldSize; i < visibleCells_.size(); i++)
1063  {
1064  visibleCells_[i] = -1;
1065  }
1066 }
1067 
1068 
1069 void Foam::refinementHistory::updateMesh(const mapPolyMesh& map)
1070 {
1071  if (active())
1072  {
1073  const labelList& reverseCellMap = map.reverseCellMap();
1074 
1075  // Note that only the live cells need to be renumbered.
1076 
1077  labelList newVisibleCells(map.cellMap().size(), -1);
1078 
1079  forAll(visibleCells_, celli)
1080  {
1081  if (visibleCells_[celli] != -1)
1082  {
1083  label index = visibleCells_[celli];
1084 
1085  // Check not already set
1086  if (splitCells_[index].addedCellsPtr_)
1087  {
1089  << "Problem" << abort(FatalError);
1090  }
1091 
1092  label newCelli = reverseCellMap[celli];
1093 
1094  if (newCelli >= 0)
1095  {
1096  newVisibleCells[newCelli] = index;
1097  }
1098  }
1099  }
1100 
1101  if (debug)
1102  {
1103  Pout<< "refinementHistory::updateMesh : from "
1104  << visibleCells_.size()
1105  << " to " << newVisibleCells.size()
1106  << " cells" << endl;
1107  }
1109  visibleCells_.transfer(newVisibleCells);
1110  }
1111 }
1112 
1113 
1115 (
1116  const labelList& pointMap,
1117  const labelList& faceMap,
1118  const labelList& cellMap
1119 )
1120 {
1121  if (active())
1122  {
1123  labelList newVisibleCells(cellMap.size(), -1);
1124 
1125  forAll(newVisibleCells, celli)
1126  {
1127  label oldCelli = cellMap[celli];
1128 
1129  label index = visibleCells_[oldCelli];
1130 
1131  // Check that cell is live (so its parent has no refinement)
1132  if (index >= 0 && splitCells_[index].addedCellsPtr_)
1133  {
1135  << "Problem" << abort(FatalError);
1136  }
1137 
1138  newVisibleCells[celli] = index;
1139  }
1140 
1141  if (debug)
1142  {
1143  Pout<< "refinementHistory::updateMesh : from "
1144  << visibleCells_.size()
1145  << " to " << newVisibleCells.size()
1146  << " cells" << endl;
1147  }
1148 
1149  visibleCells_.transfer(newVisibleCells);
1150  }
1151 }
1152 
1153 
1154 void Foam::refinementHistory::countProc
1155 (
1156  const label index,
1157  const label newProcNo,
1158  labelList& splitCellProc,
1159  labelList& splitCellNum
1160 ) const
1161 {
1162  if (splitCellProc[index] != newProcNo)
1163  {
1164  // Different destination processor from other cells using this
1165  // parent. Reset count.
1166  splitCellProc[index] = newProcNo;
1167  splitCellNum[index] = 1;
1168  }
1169  else
1170  {
1171  splitCellNum[index]++;
1172 
1173  // Increment parent if whole splitCell moves to same processor
1174  if (splitCellNum[index] == 8)
1175  {
1176  if (debug)
1177  {
1178  Pout<< "Moving " << splitCellNum[index]
1179  << " cells originating from cell " << index
1180  << " from processor " << Pstream::myProcNo()
1181  << " to processor " << splitCellProc[index]
1182  << endl;
1183  }
1184 
1185  label parent = splitCells_[index].parent_;
1186 
1187  if (parent >= 0)
1188  {
1189  countProc(parent, newProcNo, splitCellProc, splitCellNum);
1190  }
1191  }
1192  }
1193 }
1194 
1195 
1196 void Foam::refinementHistory::distribute(const mapDistributePolyMesh& map)
1197 {
1198  if (!active())
1199  {
1201  << "Calling distribute on inactive history" << abort(FatalError);
1202  }
1203 
1204 
1205  if (!Pstream::parRun())
1206  {
1207  return;
1208  }
1209 
1210  // Remove unreferenced history.
1211  compact();
1212 
1213  //Pout<< nl << "--BEFORE:" << endl;
1214  //writeDebug();
1215  //Pout<< "---------" << nl << endl;
1216 
1217 
1218  // Distribution is only partially functional.
1219  // If all 8 cells resulting from a single parent are sent across in one
1220  // go it will also send across that part of the refinement history.
1221  // If however e.g. first 1 and then the other 7 are sent across the
1222  // history will not be reconstructed.
1223 
1224  // Determine clusters. This is per every entry in splitCells_ (that is
1225  // a parent of some refinement) a label giving the processor it goes to
1226  // if all its children are going to the same processor.
1227 
1228  // Per visible cell the processor it goes to.
1229  labelList destination(visibleCells_.size());
1230 
1231  const labelListList& subCellMap = map.cellMap().subMap();
1232 
1233  forAll(subCellMap, proci)
1234  {
1235  const labelList& newToOld = subCellMap[proci];
1236 
1237  forAll(newToOld, i)
1238  {
1239  label oldCelli = newToOld[i];
1240 
1241  destination[oldCelli] = proci;
1242  }
1243  }
1244 
1245  // Per splitCell entry the processor it moves to
1246  labelList splitCellProc(splitCells_.size(), -1);
1247  // Per splitCell entry the number of live cells that move to that processor
1248  labelList splitCellNum(splitCells_.size(), Zero);
1249 
1250  forAll(visibleCells_, celli)
1251  {
1252  label index = visibleCells_[celli];
1253 
1254  if (index >= 0)
1255  {
1256  countProc
1257  (
1258  splitCells_[index].parent_,
1259  destination[celli],
1260  splitCellProc,
1261  splitCellNum
1262  );
1263  }
1264  }
1265 
1266  //Pout<< "refinementHistory::distribute :"
1267  // << " splitCellProc:" << splitCellProc << endl;
1268  //
1269  //Pout<< "refinementHistory::distribute :"
1270  // << " splitCellNum:" << splitCellNum << endl;
1271 
1272 
1273  // Create subsetted refinement tree consisting of all parents that
1274  // move in their whole to other processor.
1275  for (const int proci : Pstream::allProcs())
1276  {
1277  //Pout<< "-- Subetting for processor " << proci << endl;
1278 
1279  // From uncompacted to compacted splitCells.
1280  labelList oldToNew(splitCells_.size(), -1);
1281 
1282  // Compacted splitCells. Similar to subset routine below.
1283  DynamicList<splitCell8> newSplitCells(splitCells_.size());
1284 
1285  // Loop over all entries. Note: could recurse like countProc so only
1286  // visit used entries but is probably not worth it.
1287 
1288  forAll(splitCells_, index)
1289  {
1290  if (splitCellProc[index] == proci && splitCellNum[index] == 8)
1291  {
1292  // Entry moves in its whole to proci
1293  oldToNew[index] = newSplitCells.size();
1294  newSplitCells.append(splitCells_[index]);
1295  }
1296  }
1297 
1298  // Add live cells that are subsetted.
1299  forAll(visibleCells_, celli)
1300  {
1301  label index = visibleCells_[celli];
1302 
1303  if (index >= 0 && destination[celli] == proci)
1304  {
1305  label parent = splitCells_[index].parent_;
1306 
1307  // Create new splitCell with parent
1308  oldToNew[index] = newSplitCells.size();
1309  newSplitCells.append(splitCell8(parent));
1310  }
1311  }
1312 
1313  //forAll(oldToNew, index)
1314  //{
1315  // Pout<< "old:" << index << " new:" << oldToNew[index]
1316  // << endl;
1317  //}
1318 
1319  newSplitCells.shrink();
1320 
1321  // Renumber contents of newSplitCells
1322  forAll(newSplitCells, index)
1323  {
1324  splitCell8& split = newSplitCells[index];
1325 
1326  if (split.parent_ >= 0)
1327  {
1328  split.parent_ = oldToNew[split.parent_];
1329  }
1330  if (split.addedCellsPtr_)
1331  {
1332  FixedList<label, 8>& splits = split.addedCellsPtr_();
1333 
1334  forAll(splits, i)
1335  {
1336  if (splits[i] >= 0)
1337  {
1338  splits[i] = oldToNew[splits[i]];
1339  }
1340  }
1341  }
1342  }
1343 
1344 
1345  const labelList& subMap = subCellMap[proci];
1346 
1347  // New visible cells.
1348  labelList newVisibleCells(subMap.size(), -1);
1349 
1350  forAll(subMap, newCelli)
1351  {
1352  label oldCelli = subMap[newCelli];
1353 
1354  label oldIndex = visibleCells_[oldCelli];
1355 
1356  if (oldIndex >= 0)
1357  {
1358  newVisibleCells[newCelli] = oldToNew[oldIndex];
1359  }
1360  }
1361 
1362  //Pout<< nl << "--Subset for domain:" << proci << endl;
1363  //writeDebug(newVisibleCells, newSplitCells);
1364  //Pout<< "---------" << nl << endl;
1365 
1366 
1367  // Send to neighbours
1368  OPstream toNbr(Pstream::commsTypes::blocking, proci);
1369  toNbr << newSplitCells << newVisibleCells;
1370  }
1371 
1372 
1373  // Receive from neighbours and merge
1374  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1375 
1376  // Remove all entries. Leave storage intact.
1377  splitCells_.clear();
1378 
1379  const polyMesh& mesh = dynamic_cast<const polyMesh&>(db());
1380 
1381  visibleCells_.setSize(mesh.nCells());
1382  visibleCells_ = -1;
1383 
1384  for (const int proci : Pstream::allProcs())
1385  {
1386  IPstream fromNbr(Pstream::commsTypes::blocking, proci);
1387  List<splitCell8> newSplitCells(fromNbr);
1388  labelList newVisibleCells(fromNbr);
1389 
1390  //Pout<< nl << "--Received from domain:" << proci << endl;
1391  //writeDebug(newVisibleCells, newSplitCells);
1392  //Pout<< "---------" << nl << endl;
1393 
1394 
1395  // newSplitCells contain indices only into newSplitCells so
1396  // renumbering can be done here.
1397  label offset = splitCells_.size();
1398 
1399  //Pout<< "**Renumbering data from proc " << proci << " with offset "
1400  // << offset << endl;
1401 
1402  forAll(newSplitCells, index)
1403  {
1404  splitCell8& split = newSplitCells[index];
1405 
1406  if (split.parent_ >= 0)
1407  {
1408  split.parent_ += offset;
1409  }
1410  if (split.addedCellsPtr_)
1411  {
1412  FixedList<label, 8>& splits = split.addedCellsPtr_();
1413 
1414  forAll(splits, i)
1415  {
1416  if (splits[i] >= 0)
1417  {
1418  splits[i] += offset;
1419  }
1420  }
1421  }
1422 
1423  splitCells_.append(split);
1424  }
1425 
1426 
1427  // Combine visibleCell.
1428  const labelList& constructMap = map.cellMap().constructMap()[proci];
1429 
1430  forAll(newVisibleCells, i)
1431  {
1432  if (newVisibleCells[i] >= 0)
1433  {
1434  visibleCells_[constructMap[i]] = newVisibleCells[i] + offset;
1435  }
1436  }
1437  }
1438  splitCells_.shrink();
1440  //Pout<< nl << "--AFTER:" << endl;
1441  //writeDebug();
1442  //Pout<< "---------" << nl << endl;
1443 }
1444 
1445 
1447 {
1448  if (debug)
1449  {
1450  Pout<< "refinementHistory::compact() Entering with:"
1451  << " freeSplitCells_:" << freeSplitCells_.size()
1452  << " splitCells_:" << splitCells_.size()
1453  << " visibleCells_:" << visibleCells_.size()
1454  << endl;
1455 
1456  // Check all free splitCells are marked as such
1457  forAll(freeSplitCells_, i)
1458  {
1459  label index = freeSplitCells_[i];
1460 
1461  if (splitCells_[index].parent_ != -2)
1462  {
1464  << "Problem index:" << index
1465  << abort(FatalError);
1466  }
1467  }
1468 
1469  // Check none of the visible cells are marked as free
1470  forAll(visibleCells_, celli)
1471  {
1472  if
1473  (
1474  visibleCells_[celli] >= 0
1475  && splitCells_[visibleCells_[celli]].parent_ == -2
1476  )
1477  {
1479  << "Problem : visible cell:" << celli
1480  << " is marked as being free." << abort(FatalError);
1481  }
1482  }
1483  }
1484 
1485  DynamicList<splitCell8> newSplitCells(splitCells_.size());
1486 
1487  // From uncompacted to compacted splitCells.
1488  labelList oldToNew(splitCells_.size(), -1);
1489 
1490  // Mark all used splitCell entries. These are either indexed by visibleCells
1491  // or indexed from other splitCell entries.
1492 
1493  // Mark from visibleCells
1494  forAll(visibleCells_, celli)
1495  {
1496  label index = visibleCells_[celli];
1497 
1498  if (index >= 0)
1499  {
1500  // Make sure we only mark visible indices if they either have a
1501  // parent or subsplits.
1502  if
1503  (
1504  splitCells_[index].parent_ != -1
1505  || splitCells_[index].addedCellsPtr_
1506  )
1507  {
1508  markSplit(index, oldToNew, newSplitCells);
1509  }
1510  }
1511  }
1512 
1513  // Mark from splitCells
1514  forAll(splitCells_, index)
1515  {
1516  if (splitCells_[index].parent_ == -2)
1517  {
1518  // freed cell.
1519  }
1520  else if
1521  (
1522  splitCells_[index].parent_ == -1
1523  && !splitCells_[index].addedCellsPtr_
1524  )
1525  {
1526  // recombined cell. No need to keep since no parent and no subsplits
1527  // Note that gets marked if reachable from other index!
1528  }
1529  else
1530  {
1531  // Is used element.
1532  markSplit(index, oldToNew, newSplitCells);
1533  }
1534  }
1535 
1536 
1537  // Now oldToNew is fully complete and compacted elements are in
1538  // newSplitCells.
1539  // Renumber contents of newSplitCells and visibleCells.
1540  forAll(newSplitCells, index)
1541  {
1542  splitCell8& split = newSplitCells[index];
1543 
1544  if (split.parent_ >= 0)
1545  {
1546  split.parent_ = oldToNew[split.parent_];
1547  }
1548  if (split.addedCellsPtr_)
1549  {
1550  FixedList<label, 8>& splits = split.addedCellsPtr_();
1551 
1552  forAll(splits, i)
1553  {
1554  if (splits[i] >= 0)
1555  {
1556  splits[i] = oldToNew[splits[i]];
1557  }
1558  }
1559  }
1560  }
1561 
1562 
1563  if (debug)
1564  {
1565  Pout<< "refinementHistory::compact : compacted splitCells from "
1566  << splitCells_.size() << " to " << newSplitCells.size() << endl;
1567  }
1568 
1569  splitCells_.transfer(newSplitCells);
1570  freeSplitCells_.clearStorage();
1571 
1572 
1573  if (debug)
1574  {
1575  Pout<< "refinementHistory::compact() NOW:"
1576  << " freeSplitCells_:" << freeSplitCells_.size()
1577  << " splitCells_:" << splitCells_.size()
1578  << " newSplitCells:" << newSplitCells.size()
1579  << " visibleCells_:" << visibleCells_.size()
1580  << endl;
1581  }
1582 
1583 
1584  // Adapt indices in visibleCells_
1585  forAll(visibleCells_, celli)
1586  {
1587  label index = visibleCells_[celli];
1588 
1589  if (index >= 0)
1590  {
1591  // Note that oldToNew can be -1 so it resets newVisibleCells.
1592  visibleCells_[celli] = oldToNew[index];
1593  }
1594  else
1595  {
1596  // Keep -1 value.
1597  }
1598  }
1599 }
1600 
1601 
1603 {
1604  writeDebug(visibleCells_, splitCells_);
1605 }
1606 
1607 
1609 (
1610  const label celli,
1611  const labelList& addedCells
1612 )
1613 {
1614  label parentIndex = -1;
1615 
1616  if (visibleCells_[celli] != -1)
1617  {
1618  // Was already live. The current live cell becomes the
1619  // parent of the cells split off from it.
1620 
1621  parentIndex = visibleCells_[celli];
1622 
1623  // It is no longer live (note that actually celli gets alive
1624  // again below since is addedCells[0])
1625  visibleCells_[celli] = -1;
1626  }
1627  else
1628  {
1629  // Create 0th level. -1 parent to denote this.
1630  parentIndex = allocateSplitCell(-1, -1);
1631  }
1632 
1633  // Create live entries for added cells that point to the
1634  // cell they were created from (parentIndex)
1635  forAll(addedCells, i)
1636  {
1637  label addedCelli = addedCells[i];
1638 
1639  // Create entries for the split off cells. All of them
1640  // are visible.
1641  visibleCells_[addedCelli] = allocateSplitCell(parentIndex, i);
1642  }
1643 }
1644 
1645 
1647 (
1648  const label masterCelli,
1649  const labelList& combinedCells
1650 )
1651 {
1652  // Save the parent structure
1653  label parentIndex = splitCells_[visibleCells_[masterCelli]].parent_;
1654 
1655  // Remove the information for the combined cells
1656  forAll(combinedCells, i)
1657  {
1658  label celli = combinedCells[i];
1659 
1660  freeSplitCell(visibleCells_[celli]);
1661  visibleCells_[celli] = -1;
1662  }
1664  splitCell8& parentSplit = splitCells_[parentIndex];
1665  parentSplit.addedCellsPtr_.reset(nullptr);
1666  visibleCells_[masterCelli] = parentIndex;
1667 }
1668 
1669 
1671 {
1672  bool ok = readData(readStream(typeName));
1673  close();
1675  active_ = returnReduceOr(visibleCells_.size());
1676 
1677  return ok;
1678 }
1679 
1680 
1682 {
1683  is >> *this;
1684  return !is.bad();
1685 }
1686 
1687 
1690  os << *this;
1691 
1692  return os.good();
1693 }
1694 
1695 
1697 {
1698  IOobject io
1699  (
1700  "dummy",
1701  mesh.facesInstance(),
1703  mesh
1704  );
1705  fileName setsDir(io.path());
1706 
1707  if (topoSet::debug) DebugVar(setsDir);
1708 
1709  if (exists(setsDir/typeName))
1710  {
1711  rm(setsDir/typeName);
1712  }
1713 }
1714 
1715 
1716 // * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
1717 
1718 Foam::Istream& Foam::operator>>(Istream& is, refinementHistory& rh)
1719 {
1720  rh.freeSplitCells_.clearStorage();
1721 
1722  is >> rh.splitCells_ >> rh.visibleCells_;
1723 
1724  // Check indices.
1725  rh.checkIndices();
1726 
1727  return is;
1728 }
1729 
1730 
1731 Foam::Ostream& Foam::operator<<(Ostream& os, const refinementHistory& rh)
1732 {
1733  const_cast<refinementHistory&>(rh).compact();
1734 
1735  return os << "// splitCells" << nl
1736  << rh.splitCells_ << nl
1737  << "// visibleCells" << nl
1738  << rh.visibleCells_;
1739 }
1740 
1741 
1742 // ************************************************************************* //
void operator=(const splitCell8 &rhs)
Copy assignment (no autoPtr stealing)
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:116
autoPtr< IOobject > clone() const
Clone.
Definition: IOobject.H:621
"blocking" : (MPI_Bsend, MPI_Recv)
A class for handling file names.
Definition: fileName.H:72
bool bad() const noexcept
True if stream is corrupted.
Definition: IOstream.H:305
const fileName & facesInstance() const
Return the current instance directory for faces.
Definition: polyMesh.C:859
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:598
bool active() const
Is there unrefinement history?
static rangeType allProcs(const label communicator=worldComm)
Range of process indices for all processes.
Definition: UPstream.H:1176
An Istream is an abstract base class for all input systems (streams, files, token lists etc)...
Definition: Istream.H:57
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
regIOobject(const IOobject &io, const bool isTimeObject=false)
Construct from IOobject. The optional flag adds special handling if the object is the top-level regIO...
Definition: regIOobject.C:43
static word meshSubDir
Return the mesh sub-directory name (usually "polyMesh")
Definition: polyMesh.H:410
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
static bool & parRun() noexcept
Test if this a parallel run.
Definition: UPstream.H:1049
bool headerOk()
Read and check header info. Does not check the headerClassName.
Definition: regIOobject.C:505
static void syncFaceList(const polyMesh &mesh, UList< T > &faceValues, const CombineOp &cop)
Synchronize values on all mesh faces.
Definition: syncTools.H:432
autoPtr< FixedList< label, 8 > > addedCellsPtr_
Cells this cell was refined into.
splitCell8()
Default construct (parent = -1)
refinementHistory(const IOobject &)
Construct (read) given an IOobject.
static int myProcNo(const label communicator=worldComm)
Rank of this process in the communicator (starting from masterNo()). Can be negative if the process i...
Definition: UPstream.H:1074
T returnReduce(const T &value, const BinaryOp &bop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Perform reduction on a copy, using specified binary operation.
List< labelList > labelListList
List of labelList.
Definition: labelList.H:38
void pop_back(label n=1)
Reduce size by 1 or more elements. Can be called on an empty list.
Definition: DynamicListI.H:701
virtual bool writeData(Ostream &) const
WriteData function required for regIOobject write operation.
bool isReadOptional() const noexcept
True if (LAZY_READ) bits are set [same as READ_IF_PRESENT].
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
fileName path() const
The complete path for the object (with instance, local,...).
Definition: IOobject.C:480
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Definition: POSIX.C:799
void setSize(const label n)
Alias for resize()
Definition: List.H:316
dynamicFvMesh & mesh
void combineCells(const label masterCelli, const labelList &combinedCells)
Store combining 8 cells into master.
void close()
Close Istream.
Istream & operator>>(Istream &, directionInfo &)
Space [isspace].
Definition: token.H:131
void subset(const labelList &pointMap, const labelList &faceMap, const labelList &cellMap)
Update numbering for subsetting.
const string & prefix() const noexcept
Return the stream prefix.
const objectRegistry & db() const noexcept
Return the local objectRegistry.
Definition: IOobject.C:450
bool exists(const fileName &name, const bool checkGzip=true, const bool followLink=true)
Does the name exist (as DIRECTORY or FILE) in the file system?
Definition: POSIX.C:835
void append(const T &val)
Copy append an element to the end of this list.
Definition: DynamicList.H:584
errorManip< error > abort(error &err)
Definition: errorManip.H:139
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:56
virtual bool read()
Read object. If global number of visible cells > 0 becomes active.
virtual bool readData(Istream &)
ReadData function required for regIOobject read operation. Note:
int debug
Static debugging option.
OBJstream os(runTime.globalPath()/outputName)
defineTypeNameAndDebug(combustionModel, 0)
void compact()
Compact splitCells_. Removes all freeSplitCells_ elements.
void storeSplit(const label celli, const labelList &addedCells)
Store splitting of cell into 8.
bool isReadRequired() const noexcept
True if (MUST_READ | READ_MODIFIED) bits are set.
void updateMesh(const mapPolyMesh &)
Update numbering for mesh changes.
void distribute(const mapDistributePolyMesh &)
Update local numbering for mesh redistribution.
static bool split(const std::string &line, std::string &key, std::string &val)
Definition: cpuInfo.C:32
Ostream & operator<<(Ostream &, const boundaryPatch &p)
Write boundaryPatch as dictionary entries (without surrounding braces)
Definition: boundaryPatch.C:77
static void removeFiles(const polyMesh &)
Helper: remove all sets files from mesh instance.
void apply(const boolList &blockedFace, const PtrList< labelList > &specifiedProcessorFaces, const labelList &specifiedProcessor, const List< labelPair > &explicitConnections, labelList &decomposition) const
Apply any additional post-decomposition constraints.
#define WarningInFunction
Report a warning using Foam::Warning.
label nCells() const noexcept
Number of mesh cells.
bool good() const noexcept
True if next operation might succeed.
Definition: IOstream.H:281
T & back()
Access last element of the list, position [size()-1].
Definition: UListI.H:251
messageStream Info
Information stream (stdout output on master, null elsewhere)
#define DebugVar(var)
Report a variable name and value.
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:74
List< label > labelList
A List of labels.
Definition: List.H:62
IOobject io("surfaceFilmProperties", mesh.time().constant(), mesh, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE, IOobject::NO_REGISTER)
tmp< faMatrix< Type > > operator==(const faMatrix< Type > &, const faMatrix< Type > &)
void add(boolList &blockedFace, PtrList< labelList > &specifiedProcessorFaces, labelList &specifiedProcessor, List< labelPair > &explicitConnections) const
Add my decomposition constraints.
void writeDebug() const
Debug write.
bool returnReduceOr(const bool value, const label comm=UPstream::worldComm)
Perform logical (or) MPI Allreduce on a copy. Uses UPstream::reduceOr.
Defines the attributes of an object for which implicit objectRegistry management is supported...
Definition: IOobject.H:172
List< bool > boolList
A List of bools.
Definition: List.H:60
void resize(const label nCells)
Extend/shrink storage. additional visibleCells_ elements get.
Istream & readStream(const word &, const bool readOnProc=true)
Return Istream and check object type against that given.
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
Namespace for OpenFOAM.
bool rm(const fileName &file)
Remove a file (or its gz equivalent), returning true if successful.
Definition: POSIX.C:1404
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:127