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