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-2024 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::readIOcontents()
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  readIOcontents();
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  readIOcontents();
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 (!readIOcontents())
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 (!readIOcontents())
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 MUST_READ, READ_IF_PRESENT or READ_MODIFIED"
741  << " suggests that a read constructor would be more appropriate."
742  << endl;
743  }
744 
745  const polyMesh& mesh = dynamic_cast<const polyMesh&>(db());
746 
747 
748  // Determine offsets into splitCells
749  labelList offsets(refs.size()+1);
750  offsets[0] = 0;
751  forAll(refs, refI)
752  {
753  const DynamicList<splitCell8>& subSplits = refs[refI].splitCells();
754  offsets[refI+1] = offsets[refI]+subSplits.size();
755  }
756 
757  // Construct merged splitCells
758  splitCells_.setSize(offsets.last());
759  forAll(refs, refI)
760  {
761  const DynamicList<splitCell8>& subSplits = refs[refI].splitCells();
762  forAll(subSplits, i)
763  {
764  splitCell8& newSplit = splitCells_[offsets[refI]+i];
765 
766  // Copy
767  newSplit = subSplits[i];
768 
769  // Offset indices
770  if (newSplit.parent_ >= 0)
771  {
772  newSplit.parent_ += offsets[refI];
773  }
774 
775  if (newSplit.addedCellsPtr_)
776  {
777  FixedList<label, 8>& splits = newSplit.addedCellsPtr_();
778 
779  forAll(splits, i)
780  {
781  if (splits[i] >= 0)
782  {
783  splits[i] += offsets[refI];
784  }
785  }
786  }
787  }
788  }
789 
790 
791  // Construct merged visibleCells
792  visibleCells_.setSize(mesh.nCells(), -1);
793  forAll(refs, refI)
794  {
795  const labelList& cellMap = cellMaps[refI];
796  const labelList& subVis = refs[refI].visibleCells();
797 
798  forAll(subVis, i)
799  {
800  label& newVis = visibleCells_[cellMap[i]];
801 
802  newVis = subVis[i];
803  if (newVis >= 0)
804  {
805  newVis += offsets[refI];
806  }
807  }
808  }
809 
810 
811  // Is active if any of the refinementHistories is active (assumes active
812  // flag parallel synchronised)
813  active_ = false;
814  forAll(refs, refI)
815  {
816  if (refs[refI].active())
817  {
818  active_ = true;
819  break;
820  }
821  }
822 
823  // Check indices.
824  checkIndices();
825 
826  if (debug)
827  {
828  Pout<< "refinementHistory::refinementHistory :"
829  << " constructed history from multiple refinementHistories :"
830  << " splitCells:" << splitCells_.size()
831  << " visibleCells:" << visibleCells_.size()
832  << endl;
833  }
834 }
835 
836 
837 Foam::refinementHistory::refinementHistory(const IOobject& io, Istream& is)
838 :
839  regIOobject(io),
840  splitCells_(is),
841  freeSplitCells_(),
842  visibleCells_(is)
843 {
844  active_ = returnReduceOr(visibleCells_.size());
845 
846  // Check indices.
847  checkIndices();
848 
849  if (debug)
850  {
851  Pout<< "refinementHistory::refinementHistory :"
852  << " constructed history from Istream"
853  << " splitCells:" << splitCells_.size()
854  << " visibleCells:" << visibleCells_.size()
855  << endl;
856  }
857 }
858 
859 
860 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
861 
863 (
864  const IOobject& io,
865  // Per visible cell the processor it is going to
866  const labelList& decomposition,
867  // Per splitCell entry the processor it moves to
868  const labelList& splitCellProc,
869  // Per splitCell entry the number of live cells that move to that processor
870  const labelList& splitCellNum,
871 
872  const label procI,
873 
874  // From old to new splitCells
875  labelList& oldToNewSplit
876 ) const
877 {
878  oldToNewSplit.setSize(splitCells_.size());
879  oldToNewSplit = -1;
880 
881  // Compacted splitCells
882  DynamicList<splitCell8> newSplitCells(splitCells_.size());
883 
884  // Loop over all entries. Note: could recurse like countProc so only
885  // visit used entries but is probably not worth it.
886 
887  forAll(splitCells_, index)
888  {
889  if (splitCellProc[index] == procI && splitCellNum[index] == 8)
890  {
891  // Entry moves in its whole to procI
892  oldToNewSplit[index] = newSplitCells.size();
893  newSplitCells.append(splitCells_[index]);
894  }
895  }
896 
897  // Add live cells that are subsetted.
898  forAll(visibleCells_, cellI)
899  {
900  label index = visibleCells_[cellI];
901 
902  if (index >= 0 && decomposition[cellI] == procI)
903  {
904  label parent = splitCells_[index].parent_;
905 
906  // Create new splitCell with parent
907  oldToNewSplit[index] = newSplitCells.size();
908  newSplitCells.append(splitCell8(parent));
909  }
910  }
911 
912  //forAll(oldToNewSplit, index)
913  //{
914  // Pout<< "old:" << index << " new:" << oldToNewSplit[index]
915  // << endl;
916  //}
917 
918  newSplitCells.shrink();
919 
920  // Renumber contents of newSplitCells
921  forAll(newSplitCells, index)
922  {
923  splitCell8& split = newSplitCells[index];
924 
925  if (split.parent_ >= 0)
926  {
927  split.parent_ = oldToNewSplit[split.parent_];
928  }
929  if (split.addedCellsPtr_)
930  {
931  FixedList<label, 8>& splits = split.addedCellsPtr_();
932 
933  forAll(splits, i)
934  {
935  if (splits[i] >= 0)
936  {
937  splits[i] = oldToNewSplit[splits[i]];
938  }
939  }
940  }
941  }
942 
943 
944  // Count number of cells
945  label nSub = 0;
946  forAll(decomposition, cellI)
947  {
948  if (decomposition[cellI] == procI)
949  {
950  nSub++;
951  }
952  }
953 
954  labelList newVisibleCells(nSub);
955  nSub = 0;
956 
957  forAll(visibleCells_, cellI)
958  {
959  if (decomposition[cellI] == procI)
960  {
961  label index = visibleCells_[cellI];
962  if (index >= 0)
963  {
964  index = oldToNewSplit[index];
965  }
966  newVisibleCells[nSub++] = index;
967  }
968  }
969 
970  return autoPtr<refinementHistory>
971  (
972  new refinementHistory
973  (
974  io,
975  newSplitCells,
976  newVisibleCells,
977  active_
978  )
979  );
980 }
981 
982 
984 (
985  const IOobject& io,
986  const labelList& cellMap
987 ) const
988 {
989  if (active_)
990  {
991  // Mark selected cells with '1'
992  labelList decomposition(visibleCells_.size(), Zero);
993  forAll(cellMap, i)
994  {
995  decomposition[cellMap[i]] = 1;
996  }
997 
998 
999  // Per splitCell entry the processor it moves to
1000  labelList splitCellProc(splitCells_.size(), -1);
1001  // Per splitCell entry the number of live cells that move to that
1002  // processor
1003  labelList splitCellNum(splitCells_.size(), Zero);
1004 
1005  forAll(visibleCells_, cellI)
1006  {
1007  label index = visibleCells_[cellI];
1008 
1009  if (index >= 0)
1010  {
1011  countProc
1012  (
1013  splitCells_[index].parent_,
1014  decomposition[cellI],
1015  splitCellProc,
1016  splitCellNum
1017  );
1018  }
1019  }
1020 
1021  labelList oldToNewSplit;
1022  return clone
1023  (
1024  io,
1025  decomposition,
1026  splitCellProc,
1027  splitCellNum,
1028  1, //procI,
1029  oldToNewSplit
1030  );
1031  }
1032  else
1033  {
1034  return autoPtr<refinementHistory>
1035  (
1036  new refinementHistory
1037  (
1038  io,
1039  List<splitCell8>(),
1040  labelList(),
1041  false
1042  )
1043  );
1044  }
1045 }
1046 
1047 
1048 void Foam::refinementHistory::resize(const label size)
1049 {
1050  label oldSize = visibleCells_.size();
1051 
1052  if (debug)
1053  {
1054  Pout<< "refinementHistory::resize from " << oldSize << " to " << size
1055  << " cells" << endl;
1056  }
1057 
1058  visibleCells_.setSize(size);
1059 
1060  // Set additional elements to -1.
1061  for (label i = oldSize; i < visibleCells_.size(); i++)
1062  {
1063  visibleCells_[i] = -1;
1064  }
1065 }
1066 
1067 
1068 void Foam::refinementHistory::updateMesh(const mapPolyMesh& map)
1069 {
1070  if (active())
1071  {
1072  const labelList& reverseCellMap = map.reverseCellMap();
1073 
1074  // Note that only the live cells need to be renumbered.
1075 
1076  labelList newVisibleCells(map.cellMap().size(), -1);
1077 
1078  forAll(visibleCells_, celli)
1079  {
1080  if (visibleCells_[celli] != -1)
1081  {
1082  label index = visibleCells_[celli];
1083 
1084  // Check not already set
1085  if (splitCells_[index].addedCellsPtr_)
1086  {
1088  << "Problem" << abort(FatalError);
1089  }
1090 
1091  label newCelli = reverseCellMap[celli];
1092 
1093  if (newCelli >= 0)
1094  {
1095  newVisibleCells[newCelli] = index;
1096  }
1097  }
1098  }
1099 
1100  if (debug)
1101  {
1102  Pout<< "refinementHistory::updateMesh : from "
1103  << visibleCells_.size()
1104  << " to " << newVisibleCells.size()
1105  << " cells" << endl;
1106  }
1108  visibleCells_.transfer(newVisibleCells);
1109  }
1110 }
1111 
1112 
1114 (
1115  const labelList& pointMap,
1116  const labelList& faceMap,
1117  const labelList& cellMap
1118 )
1119 {
1120  if (active())
1121  {
1122  labelList newVisibleCells(cellMap.size(), -1);
1123 
1124  forAll(newVisibleCells, celli)
1125  {
1126  label oldCelli = cellMap[celli];
1127 
1128  label index = visibleCells_[oldCelli];
1129 
1130  // Check that cell is live (so its parent has no refinement)
1131  if (index >= 0 && splitCells_[index].addedCellsPtr_)
1132  {
1134  << "Problem" << abort(FatalError);
1135  }
1136 
1137  newVisibleCells[celli] = index;
1138  }
1139 
1140  if (debug)
1141  {
1142  Pout<< "refinementHistory::updateMesh : from "
1143  << visibleCells_.size()
1144  << " to " << newVisibleCells.size()
1145  << " cells" << endl;
1146  }
1147 
1148  visibleCells_.transfer(newVisibleCells);
1149  }
1150 }
1151 
1152 
1153 void Foam::refinementHistory::countProc
1154 (
1155  const label index,
1156  const label newProcNo,
1157  labelList& splitCellProc,
1158  labelList& splitCellNum
1159 ) const
1160 {
1161  if (splitCellProc[index] != newProcNo)
1162  {
1163  // Different destination processor from other cells using this
1164  // parent. Reset count.
1165  splitCellProc[index] = newProcNo;
1166  splitCellNum[index] = 1;
1167  }
1168  else
1169  {
1170  splitCellNum[index]++;
1171 
1172  // Increment parent if whole splitCell moves to same processor
1173  if (splitCellNum[index] == 8)
1174  {
1175  if (debug)
1176  {
1177  Pout<< "Moving " << splitCellNum[index]
1178  << " cells originating from cell " << index
1179  << " from processor " << Pstream::myProcNo()
1180  << " to processor " << splitCellProc[index]
1181  << endl;
1182  }
1183 
1184  label parent = splitCells_[index].parent_;
1185 
1186  if (parent >= 0)
1187  {
1188  countProc(parent, newProcNo, splitCellProc, splitCellNum);
1189  }
1190  }
1191  }
1192 }
1193 
1194 
1195 void Foam::refinementHistory::distribute(const mapDistributePolyMesh& map)
1196 {
1197  if (!active())
1198  {
1200  << "Calling distribute on inactive history" << abort(FatalError);
1201  }
1202 
1203 
1204  if (!Pstream::parRun())
1205  {
1206  return;
1207  }
1208 
1209  // Remove unreferenced history.
1210  compact();
1211 
1212  //Pout<< nl << "--BEFORE:" << endl;
1213  //writeDebug();
1214  //Pout<< "---------" << nl << endl;
1215 
1216 
1217  // Distribution is only partially functional.
1218  // If all 8 cells resulting from a single parent are sent across in one
1219  // go it will also send across that part of the refinement history.
1220  // If however e.g. first 1 and then the other 7 are sent across the
1221  // history will not be reconstructed.
1222 
1223  // Determine clusters. This is per every entry in splitCells_ (that is
1224  // a parent of some refinement) a label giving the processor it goes to
1225  // if all its children are going to the same processor.
1226 
1227  // Per visible cell the processor it goes to.
1228  labelList destination(visibleCells_.size());
1229 
1230  const labelListList& subCellMap = map.cellMap().subMap();
1231 
1232  forAll(subCellMap, proci)
1233  {
1234  const labelList& newToOld = subCellMap[proci];
1235 
1236  forAll(newToOld, i)
1237  {
1238  label oldCelli = newToOld[i];
1239 
1240  destination[oldCelli] = proci;
1241  }
1242  }
1243 
1244  // Per splitCell entry the processor it moves to
1245  labelList splitCellProc(splitCells_.size(), -1);
1246  // Per splitCell entry the number of live cells that move to that processor
1247  labelList splitCellNum(splitCells_.size(), Zero);
1248 
1249  forAll(visibleCells_, celli)
1250  {
1251  label index = visibleCells_[celli];
1252 
1253  if (index >= 0)
1254  {
1255  countProc
1256  (
1257  splitCells_[index].parent_,
1258  destination[celli],
1259  splitCellProc,
1260  splitCellNum
1261  );
1262  }
1263  }
1264 
1265  //Pout<< "refinementHistory::distribute :"
1266  // << " splitCellProc:" << splitCellProc << endl;
1267  //
1268  //Pout<< "refinementHistory::distribute :"
1269  // << " splitCellNum:" << splitCellNum << endl;
1270 
1271 
1272  // Create subsetted refinement tree consisting of all parents that
1273  // move in their whole to other processor.
1274 
1275  PstreamBuffers pBufs;
1276 
1277  for (const int proci : Pstream::allProcs())
1278  {
1279  //Pout<< "-- Subetting for processor " << proci << endl;
1280 
1281  // From uncompacted to compacted splitCells.
1282  labelList oldToNew(splitCells_.size(), -1);
1283 
1284  // Compacted splitCells. Similar to subset routine below.
1285  DynamicList<splitCell8> newSplitCells(splitCells_.size());
1286 
1287  // Loop over all entries. Note: could recurse like countProc so only
1288  // visit used entries but is probably not worth it.
1289 
1290  forAll(splitCells_, index)
1291  {
1292  if (splitCellProc[index] == proci && splitCellNum[index] == 8)
1293  {
1294  // Entry moves in its whole to proci
1295  oldToNew[index] = newSplitCells.size();
1296  newSplitCells.append(splitCells_[index]);
1297  }
1298  }
1299 
1300  // Add live cells that are subsetted.
1301  forAll(visibleCells_, celli)
1302  {
1303  label index = visibleCells_[celli];
1304 
1305  if (index >= 0 && destination[celli] == proci)
1306  {
1307  label parent = splitCells_[index].parent_;
1308 
1309  // Create new splitCell with parent
1310  oldToNew[index] = newSplitCells.size();
1311  newSplitCells.append(splitCell8(parent));
1312  }
1313  }
1314 
1315  //forAll(oldToNew, index)
1316  //{
1317  // Pout<< "old:" << index << " new:" << oldToNew[index]
1318  // << endl;
1319  //}
1320 
1321  newSplitCells.shrink();
1322 
1323  // Renumber contents of newSplitCells
1324  forAll(newSplitCells, index)
1325  {
1326  splitCell8& split = newSplitCells[index];
1327 
1328  if (split.parent_ >= 0)
1329  {
1330  split.parent_ = oldToNew[split.parent_];
1331  }
1332  if (split.addedCellsPtr_)
1333  {
1334  FixedList<label, 8>& splits = split.addedCellsPtr_();
1335 
1336  forAll(splits, i)
1337  {
1338  if (splits[i] >= 0)
1339  {
1340  splits[i] = oldToNew[splits[i]];
1341  }
1342  }
1343  }
1344  }
1345 
1346 
1347  const labelList& subMap = subCellMap[proci];
1348 
1349  // New visible cells.
1350  labelList newVisibleCells(subMap.size(), -1);
1351 
1352  forAll(subMap, newCelli)
1353  {
1354  label oldCelli = subMap[newCelli];
1355 
1356  label oldIndex = visibleCells_[oldCelli];
1357 
1358  if (oldIndex >= 0)
1359  {
1360  newVisibleCells[newCelli] = oldToNew[oldIndex];
1361  }
1362  }
1363 
1364  //Pout<< nl << "--Subset for domain:" << proci << endl;
1365  //writeDebug(newVisibleCells, newSplitCells);
1366  //Pout<< "---------" << nl << endl;
1367 
1368 
1369  // Send to neighbours
1370  UOPstream toNbr(proci, pBufs);
1371  toNbr << newSplitCells << newVisibleCells;
1372  }
1373 
1374 
1375  // Wait for finish
1376  pBufs.finishedSends();
1377 
1378 
1379  // Receive from neighbours and merge
1380  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1381 
1382  // Remove all entries. Leave storage intact.
1383  splitCells_.clear();
1384 
1385  const polyMesh& mesh = dynamic_cast<const polyMesh&>(db());
1386 
1387  visibleCells_.setSize(mesh.nCells());
1388  visibleCells_ = -1;
1389 
1390  for (const int proci : Pstream::allProcs())
1391  {
1392  UIPstream fromNbr(proci, pBufs);
1393  List<splitCell8> newSplitCells(fromNbr);
1394  labelList newVisibleCells(fromNbr);
1395 
1396  //Pout<< nl << "--Received from domain:" << proci << endl;
1397  //writeDebug(newVisibleCells, newSplitCells);
1398  //Pout<< "---------" << nl << endl;
1399 
1400 
1401  // newSplitCells contain indices only into newSplitCells so
1402  // renumbering can be done here.
1403  label offset = splitCells_.size();
1404 
1405  //Pout<< "**Renumbering data from proc " << proci << " with offset "
1406  // << offset << endl;
1407 
1408  forAll(newSplitCells, index)
1409  {
1410  splitCell8& split = newSplitCells[index];
1411 
1412  if (split.parent_ >= 0)
1413  {
1414  split.parent_ += offset;
1415  }
1416  if (split.addedCellsPtr_)
1417  {
1418  FixedList<label, 8>& splits = split.addedCellsPtr_();
1419 
1420  forAll(splits, i)
1421  {
1422  if (splits[i] >= 0)
1423  {
1424  splits[i] += offset;
1425  }
1426  }
1427  }
1428 
1429  splitCells_.append(split);
1430  }
1431 
1432 
1433  // Combine visibleCell.
1434  const labelList& constructMap = map.cellMap().constructMap()[proci];
1435 
1436  forAll(newVisibleCells, i)
1437  {
1438  if (newVisibleCells[i] >= 0)
1439  {
1440  visibleCells_[constructMap[i]] = newVisibleCells[i] + offset;
1441  }
1442  }
1443  }
1444  splitCells_.shrink();
1446  //Pout<< nl << "--AFTER:" << endl;
1447  //writeDebug();
1448  //Pout<< "---------" << nl << endl;
1449 }
1450 
1451 
1453 {
1454  if (debug)
1455  {
1456  Pout<< "refinementHistory::compact() Entering with:"
1457  << " freeSplitCells_:" << freeSplitCells_.size()
1458  << " splitCells_:" << splitCells_.size()
1459  << " visibleCells_:" << visibleCells_.size()
1460  << endl;
1461 
1462  // Check all free splitCells are marked as such
1463  forAll(freeSplitCells_, i)
1464  {
1465  label index = freeSplitCells_[i];
1466 
1467  if (splitCells_[index].parent_ != -2)
1468  {
1470  << "Problem index:" << index
1471  << abort(FatalError);
1472  }
1473  }
1474 
1475  // Check none of the visible cells are marked as free
1476  forAll(visibleCells_, celli)
1477  {
1478  if
1479  (
1480  visibleCells_[celli] >= 0
1481  && splitCells_[visibleCells_[celli]].parent_ == -2
1482  )
1483  {
1485  << "Problem : visible cell:" << celli
1486  << " is marked as being free." << abort(FatalError);
1487  }
1488  }
1489  }
1490 
1491  DynamicList<splitCell8> newSplitCells(splitCells_.size());
1492 
1493  // From uncompacted to compacted splitCells.
1494  labelList oldToNew(splitCells_.size(), -1);
1495 
1496  // Mark all used splitCell entries. These are either indexed by visibleCells
1497  // or indexed from other splitCell entries.
1498 
1499  // Mark from visibleCells
1500  forAll(visibleCells_, celli)
1501  {
1502  label index = visibleCells_[celli];
1503 
1504  if (index >= 0)
1505  {
1506  // Make sure we only mark visible indices if they either have a
1507  // parent or subsplits.
1508  if
1509  (
1510  splitCells_[index].parent_ != -1
1511  || splitCells_[index].addedCellsPtr_
1512  )
1513  {
1514  markSplit(index, oldToNew, newSplitCells);
1515  }
1516  }
1517  }
1518 
1519  // Mark from splitCells
1520  forAll(splitCells_, index)
1521  {
1522  if (splitCells_[index].parent_ == -2)
1523  {
1524  // freed cell.
1525  }
1526  else if
1527  (
1528  splitCells_[index].parent_ == -1
1529  && !splitCells_[index].addedCellsPtr_
1530  )
1531  {
1532  // recombined cell. No need to keep since no parent and no subsplits
1533  // Note that gets marked if reachable from other index!
1534  }
1535  else
1536  {
1537  // Is used element.
1538  markSplit(index, oldToNew, newSplitCells);
1539  }
1540  }
1541 
1542 
1543  // Now oldToNew is fully complete and compacted elements are in
1544  // newSplitCells.
1545  // Renumber contents of newSplitCells and visibleCells.
1546  forAll(newSplitCells, index)
1547  {
1548  splitCell8& split = newSplitCells[index];
1549 
1550  if (split.parent_ >= 0)
1551  {
1552  split.parent_ = oldToNew[split.parent_];
1553  }
1554  if (split.addedCellsPtr_)
1555  {
1556  FixedList<label, 8>& splits = split.addedCellsPtr_();
1557 
1558  forAll(splits, i)
1559  {
1560  if (splits[i] >= 0)
1561  {
1562  splits[i] = oldToNew[splits[i]];
1563  }
1564  }
1565  }
1566  }
1567 
1568 
1569  if (debug)
1570  {
1571  Pout<< "refinementHistory::compact : compacted splitCells from "
1572  << splitCells_.size() << " to " << newSplitCells.size() << endl;
1573  }
1574 
1575  splitCells_.transfer(newSplitCells);
1576  freeSplitCells_.clearStorage();
1577 
1578 
1579  if (debug)
1580  {
1581  Pout<< "refinementHistory::compact() NOW:"
1582  << " freeSplitCells_:" << freeSplitCells_.size()
1583  << " splitCells_:" << splitCells_.size()
1584  << " newSplitCells:" << newSplitCells.size()
1585  << " visibleCells_:" << visibleCells_.size()
1586  << endl;
1587  }
1588 
1589 
1590  // Adapt indices in visibleCells_
1591  forAll(visibleCells_, celli)
1592  {
1593  label index = visibleCells_[celli];
1594 
1595  if (index >= 0)
1596  {
1597  // Note that oldToNew can be -1 so it resets newVisibleCells.
1598  visibleCells_[celli] = oldToNew[index];
1599  }
1600  else
1601  {
1602  // Keep -1 value.
1603  }
1604  }
1605 }
1606 
1607 
1609 {
1610  writeDebug(visibleCells_, splitCells_);
1611 }
1612 
1613 
1615 (
1616  const label celli,
1617  const labelList& addedCells
1618 )
1619 {
1620  label parentIndex = -1;
1621 
1622  if (visibleCells_[celli] != -1)
1623  {
1624  // Was already live. The current live cell becomes the
1625  // parent of the cells split off from it.
1626 
1627  parentIndex = visibleCells_[celli];
1628 
1629  // It is no longer live (note that actually celli gets alive
1630  // again below since is addedCells[0])
1631  visibleCells_[celli] = -1;
1632  }
1633  else
1634  {
1635  // Create 0th level. -1 parent to denote this.
1636  parentIndex = allocateSplitCell(-1, -1);
1637  }
1638 
1639  // Create live entries for added cells that point to the
1640  // cell they were created from (parentIndex)
1641  forAll(addedCells, i)
1642  {
1643  label addedCelli = addedCells[i];
1644 
1645  // Create entries for the split off cells. All of them
1646  // are visible.
1647  visibleCells_[addedCelli] = allocateSplitCell(parentIndex, i);
1648  }
1649 }
1650 
1651 
1653 (
1654  const label masterCelli,
1655  const labelList& combinedCells
1656 )
1657 {
1658  // Save the parent structure
1659  label parentIndex = splitCells_[visibleCells_[masterCelli]].parent_;
1660 
1661  // Remove the information for the combined cells
1662  forAll(combinedCells, i)
1663  {
1664  label celli = combinedCells[i];
1665 
1666  freeSplitCell(visibleCells_[celli]);
1667  visibleCells_[celli] = -1;
1668  }
1670  splitCell8& parentSplit = splitCells_[parentIndex];
1671  parentSplit.addedCellsPtr_.reset(nullptr);
1672  visibleCells_[masterCelli] = parentIndex;
1673 }
1674 
1675 
1677 {
1678  bool ok = readData(readStream(typeName));
1679  close();
1681  active_ = returnReduceOr(visibleCells_.size());
1682 
1683  return ok;
1684 }
1685 
1686 
1688 {
1689  is >> *this;
1690  return !is.bad();
1691 }
1692 
1693 
1696  os << *this;
1697 
1698  return os.good();
1699 }
1700 
1701 
1703 {
1704  IOobject io
1705  (
1706  "dummy",
1707  mesh.facesInstance(),
1709  mesh
1710  );
1711  fileName setsDir(io.path());
1712 
1713  if (topoSet::debug) DebugVar(setsDir);
1714 
1715  if (exists(setsDir/typeName))
1716  {
1717  rm(setsDir/typeName);
1718  }
1719 }
1720 
1721 
1722 // * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
1723 
1724 Foam::Istream& Foam::operator>>(Istream& is, refinementHistory& rh)
1725 {
1726  rh.freeSplitCells_.clearStorage();
1727 
1728  is >> rh.splitCells_ >> rh.visibleCells_;
1729 
1730  // Check indices.
1731  rh.checkIndices();
1732 
1733  return is;
1734 }
1735 
1736 
1737 Foam::Ostream& Foam::operator<<(Ostream& os, const refinementHistory& rh)
1738 {
1739  const_cast<refinementHistory&>(rh).compact();
1740 
1741  return os << "// splitCells" << nl
1742  << rh.splitCells_ << nl
1743  << "// visibleCells" << nl
1744  << rh.visibleCells_;
1745 }
1746 
1747 
1748 // ************************************************************************* //
static void syncFaceList(const polyMesh &mesh, UList< T > &faceValues, const CombineOp &cop, const bool parRun=UPstream::parRun())
Synchronize values on all mesh faces.
Definition: syncTools.H:465
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:629
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:608
bool active() const
Is there unrefinement history?
static rangeType allProcs(const label communicator=worldComm)
Range of process indices for all processes.
Definition: UPstream.H:1188
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:411
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:1061
bool headerOk()
Read and check header info. Does not check the headerClassName.
Definition: regIOobject.C:505
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:1086
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:320
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:244
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:75
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:180
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