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