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