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