46 Foam::shellSurfaces::refineModeNames_
48 { refineMode::INSIDE,
"inside" },
49 { refineMode::OUTSIDE,
"outside" },
50 { refineMode::DISTANCE,
"distance" },
56 void Foam::shellSurfaces::setAndCheckLevels
59 const List<Tuple2<scalar, label>>& distLevels
62 const searchableSurface& shell = allGeometry_[shells_[shellI]];
64 if (modes_[shellI] !=
DISTANCE && distLevels.size() != 1)
67 <<
"For refinement mode " 68 << refineModeNames_[modes_[shellI]]
69 <<
" specify only one distance+level." 70 <<
" (its distance gets discarded)" 74 distances_[shellI].
setSize(distLevels.size());
75 levels_[shellI].
setSize(distLevels.size());
79 distances_[shellI][j] = distLevels[j].
first();
80 levels_[shellI][j] = distLevels[j].second();
82 if (levels_[shellI][j] < -1)
85 <<
"Shell " << shell.name()
86 <<
" has illegal refinement level " 97 (distances_[shellI][j] <= distances_[shellI][j-1])
98 || (levels_[shellI][j] > levels_[shellI][j-1])
102 <<
"For refinement mode " 103 << refineModeNames_[modes_[shellI]]
104 <<
" : Refinement should be specified in order" 105 <<
" of increasing distance" 106 <<
" (and decreasing refinement level)." <<
endl 107 <<
"Distance:" << distances_[shellI][j]
108 <<
" refinementLevel:" << levels_[shellI][j]
118 Info<<
"Refinement level according to distance to " 119 << shell.name() <<
endl;
120 forAll(levels_[shellI], j)
122 Info<<
" level " << levels_[shellI][j]
123 <<
" for all cells within " << distances_[shellI][j]
124 <<
" metre." <<
endl;
130 if (!shell.hasVolumeType())
133 <<
"Shell " << shell.name()
134 <<
" does not support testing for " 135 << refineModeNames_[modes_[shellI]] <<
endl 136 <<
"Probably it is not closed." 142 if (modes_[shellI] ==
INSIDE)
144 Info<<
"Refinement level " << levels_[shellI][0]
145 <<
" for all cells inside " << shell.name() <<
endl;
149 Info<<
"Refinement level " << levels_[shellI][0]
150 <<
" for all cells outside " << shell.name() <<
endl;
160 void Foam::shellSurfaces::orient()
165 bool hasSurface =
false;
169 const searchableSurface&
s = allGeometry_[shells_[shellI]];
173 modes_[shellI] != DISTANCE
174 && isA<triSurfaceMesh>(
s)
175 && !isA<distributedTriSurfaceMesh>(
s)
180 const triSurfaceMesh& shell = refCast<const triSurfaceMesh>(
s);
181 if (shell.triSurface::size())
184 overallBb.add(
s.bounds());
191 const point outsidePt = overallBb.max() + overallBb.span();
197 const searchableSurface&
s = allGeometry_[shells_[shellI]];
201 modes_[shellI] != DISTANCE
202 && isA<triSurfaceMesh>(
s)
203 && !isA<distributedTriSurfaceMesh>(
s)
206 triSurfaceMesh& shell =
const_cast<triSurfaceMesh&
> 208 refCast<const triSurfaceMesh>(
s)
219 if (anyFlipped && !dryRun_)
228 Info<<
"shellSurfaces : Flipped orientation of surface " 230 <<
" so point " << outsidePt <<
" is outside." <<
endl;
239 void Foam::shellSurfaces::findHigherLevel
246 const labelList& levels = levels_[shellI];
248 if (modes_[shellI] == DISTANCE)
260 label candidateI = 0;
266 if (levels[levelI] > maxLevel[pointi])
268 candidateMap[candidateI] = pointi;
269 candidateDistSqr[candidateI] =
sqr(distances[levelI]);
275 candidateMap.setSize(candidateI);
276 candidateDistSqr.setSize(candidateI);
279 List<pointIndexHit> nearInfo;
280 allGeometry_[shells_[shellI]].findNearest
290 if (nearInfo[i].hit())
292 const label pointi = candidateMap[i];
298 nearInfo[i].
point().dist(pt[pointi])
302 maxLevel[pointi] = levels[minDistI+1];
315 label candidateI = 0;
319 if (levels[0] > maxLevel[pointi])
321 candidates[candidateI] = pt[pointi];
322 candidateMap[candidateI] = pointi;
326 candidates.setSize(candidateI);
327 candidateMap.setSize(candidateI);
330 List<volumeType> volType;
331 allGeometry_[shells_[shellI]].getVolumeType(candidates, volType);
335 label pointi = candidateMap[i];
340 modes_[shellI] == INSIDE
344 modes_[shellI] == OUTSIDE
349 maxLevel[pointi] = levels[0];
356 void Foam::shellSurfaces::findHigherGapLevel
362 List<FixedList<label, 3>>& gapInfo,
363 List<volumeType>& gapMode
367 const FixedList<label, 3>& info = extendedGapLevel_[shellI][0];
368 const volumeType
mode = extendedGapMode_[shellI][0];
375 if (modes_[shellI] == DISTANCE)
378 const scalar
distance = distances_[shellI][0];
382 label candidateI = 0;
386 if (ptLevel[pointI] >= info[1] && ptLevel[pointI] < info[2])
388 candidateMap[candidateI] = pointI;
393 candidateMap.setSize(candidateI);
394 candidateDistSqr.setSize(candidateI);
397 List<pointIndexHit> nearInfo;
398 allGeometry_[shells_[shellI]].findNearest
408 if (nearInfo[i].hit())
410 const label pointI = candidateMap[i];
411 gapShell[pointI] = shellI;
412 gapInfo[pointI] = info;
413 gapMode[pointI] =
mode;
423 label candidateI = 0;
427 if (ptLevel[pointI] >= info[1] && ptLevel[pointI] < info[2])
429 candidateMap[candidateI++] = pointI;
432 candidateMap.setSize(candidateI);
435 List<volumeType> volType;
436 allGeometry_[shells_[shellI]].getVolumeType
444 const label pointI = candidateMap[i];
450 (modes_[shellI] == INSIDE && isInside)
451 || (modes_[shellI] == OUTSIDE && !isInside)
453 && info[2] > gapInfo[pointI][2]
456 gapShell[pointI] = shellI;
457 gapInfo[pointI] = info;
458 gapMode[pointI] =
mode;
465 void Foam::shellSurfaces::findLevel
473 const labelList& levels = levels_[shellI];
475 if (modes_[shellI] == DISTANCE)
488 label candidateI = 0;
492 if (shell[pointI] == -1)
496 if (levels[levelI] <= minLevel[pointI])
498 candidates[candidateI] = pt[pointI];
499 candidateMap[candidateI] = pointI;
500 candidateDistSqr[candidateI] =
sqr(distances[levelI]);
507 candidates.setSize(candidateI);
508 candidateMap.setSize(candidateI);
509 candidateDistSqr.setSize(candidateI);
512 List<pointIndexHit> nearInfo;
513 allGeometry_[shells_[shellI]].findNearest
523 if (nearInfo[i].hit())
529 nearInfo[i].
point().dist(candidates[i])
532 label pointI = candidateMap[i];
535 shell[pointI] = shellI;
536 minLevel[pointI] = levels[minDistI+1];
549 label candidateI = 0;
553 if (shell[pointI] == -1 && levels[0] <= minLevel[pointI])
555 candidates[candidateI] = pt[pointI];
556 candidateMap[candidateI] = pointI;
560 candidates.setSize(candidateI);
561 candidateMap.setSize(candidateI);
564 List<volumeType> volType;
565 allGeometry_[shells_[shellI]].getVolumeType(candidates, volType);
572 modes_[shellI] == INSIDE
576 modes_[shellI] == OUTSIDE
581 label pointI = candidateMap[i];
582 shell[pointI] = shellI;
583 minLevel[pointI] = levels[0];
594 const searchableSurfaces& allGeometry,
595 const dictionary& shellsDict,
599 allGeometry_(allGeometry),
606 for (
const word& geomName : allGeometry_.
names())
608 if (shellsDict.found(geomName))
616 shells_.setSize(shellI);
620 dirLevels_.setSize(shellI);
621 smoothDirection_.
setSize(shellI);
622 nSmoothExpansion_.
setSize(shellI);
623 nSmoothPosition_.
setSize(shellI);
625 extendedGapLevel_.setSize(shellI);
626 extendedGapMode_.setSize(shellI);
627 selfProximity_.
setSize(shellI);
629 const FixedList<label, 3> nullGapLevel({0, 0, 0});
636 const word& geomName = allGeometry_.
names()[geomI];
638 const entry* eptr = shellsDict.findEntry(geomName,
keyType::REGEX);
642 const dictionary&
dict = eptr->dict();
643 unmatchedKeys.erase(eptr->keyword());
645 shells_[shellI] = geomI;
646 modes_[shellI] = refineModeNames_.
get(
"mode",
dict);
649 setAndCheckLevels(shellI,
dict.lookup(
"levels"));
655 dirLevels_[shellI] = Tuple2<labelPair,labelVector>
660 const entry* levelPtr =
667 ITstream& is = levelPtr->stream();
669 is.readBegin(
"levelIncrement");
670 is >> dirLevels_[shellI].first().first()
671 >> dirLevels_[shellI].first().second()
672 >> dirLevels_[shellI].second();
673 is.readEnd(
"levelIncrement");
675 if (modes_[shellI] ==
INSIDE)
679 Info<<
"Additional directional refinement level" 680 <<
" for all cells inside " << geomName <<
endl;
683 else if (modes_[shellI] ==
OUTSIDE)
687 Info<<
"Additional directional refinement level" 688 <<
" for all cells outside " << geomName <<
endl;
694 <<
"Unsupported mode " 695 << refineModeNames_[modes_[shellI]]
703 nSmoothExpansion_[shellI] = 0;
704 nSmoothPosition_[shellI] = 0;
705 smoothDirection_[shellI] =
706 dict.getOrDefault(
"smoothDirection", vector::zero);
708 if (smoothDirection_[shellI] != vector::zero)
710 dict.readEntry(
"nSmoothExpansion", nSmoothExpansion_[shellI]);
711 dict.readEntry(
"nSmoothPosition", nSmoothPosition_[shellI]);
720 const searchableSurface&
surface = allGeometry_[geomI];
723 FixedList<label, 3> gapSpec
731 extendedGapLevel_[shellI].setSize(
regionNames.size());
732 extendedGapLevel_[shellI] = gapSpec;
734 extendedGapMode_[shellI].setSize(
regionNames.size());
735 extendedGapMode_[shellI] =
742 dict.getOrDefault<
bool>(
"gapSelf",
true)
748 if (
dict.found(
"regions"))
750 const dictionary& regionsDict =
dict.subDict(
"regions");
756 const dictionary& regionDict = regionsDict.subDict
760 FixedList<label, 3> gapSpec
762 regionDict.getOrDefault
768 extendedGapLevel_[shellI][regionI] = gapSpec;
770 extendedGapMode_[shellI][regionI] =
778 selfProximity_[shellI][regionI] =
779 regionDict.getOrDefault<
bool>
788 if (extendedGapLevel_[shellI][0][0] > 0)
790 Info<<
"Refinement level up to " 791 << extendedGapLevel_[shellI][0][2]
792 <<
" for all cells in gaps for shell " 795 if (distances_[shellI].size() > 1)
798 << distances_[shellI] <<
" to detect gaps for shell " 807 if (unmatchedKeys.size() > 0)
810 <<
"Not all entries in refinementRegions dictionary were used." 811 <<
" The following entries were not used : " 812 << unmatchedKeys.sortedToc()
828 label overallMax = 0;
831 overallMax =
max(overallMax,
max(levels_[shellI]));
841 forAll(extendedGapLevel_, shelli)
843 const List<FixedList<label, 3>>& levels = extendedGapLevel_[shelli];
846 surfaceMax[shelli] =
max(surfaceMax[shelli], levels[i][2]);
856 forAll(dirLevels_, shelli)
858 levels[shelli] = dirLevels_[shelli].first();
866 return nSmoothExpansion_;
872 return smoothDirection_;
878 return nSmoothPosition_;
882 void Foam::shellSurfaces::findHigherLevel
894 findHigherLevel(pt, shelli, maxLevel);
899 void Foam::shellSurfaces::findHigherGapLevel
904 List<FixedList<label, 3>>& gapInfo,
905 List<volumeType>& gapMode
908 gapShell.setSize(pt.size());
911 gapInfo.setSize(pt.size());
912 gapInfo = FixedList<label, 3>({0, 0, 0});
914 gapMode.setSize(pt.size());
919 findHigherGapLevel(pt, ptLevel, shelli, gapShell, gapInfo, gapMode);
924 void Foam::shellSurfaces::findHigherGapLevel
928 List<FixedList<label, 3>>& gapInfo,
929 List<volumeType>& gapMode
933 findHigherGapLevel(pt, ptLevel, gapShell, gapInfo, gapMode);
937 void Foam::shellSurfaces::findLevel
951 findLevel(pt, shelli, minLevel, shell);
965 shell.setSize(pt.size());
968 List<volumeType> volType;
971 DynamicList<label> candidateMap(pt.size());
975 if (modes_[shelli] == INSIDE || modes_[shelli] == OUTSIDE)
978 const label addLevel = dirLevels_[shelli].second()[dir];
981 candidateMap.clear();
984 label level = ptLevel[celli];
988 level >= selectLevels.first()
989 && level <= selectLevels.second()
990 && dirLevel[celli] < level+addLevel
993 candidateMap.append(celli);
999 allGeometry_[shells_[shelli]].getVolumeType(candidatePt, volType);
1007 modes_[shelli] == INSIDE
1011 modes_[shelli] == OUTSIDE
1016 shell[candidateMap[i]] = shelli;
EnumType get(const word &enumName) const
The enumeration corresponding to the given name.
const T & first() const noexcept
Access the first element.
void size(const label n)
Older name for setAddressableSize.
labelPairList directionalSelectLevel() const
Min and max cell level for directional refinement.
label findLower(const ListType &input, const T &val, const label start, const ComparePredicate &comp)
Binary search to find the index of the last element in a sorted list that is less than value...
errorManipArg< error, int > exit(error &err, const int errNo=1)
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
dimensionedSymmTensor sqr(const dimensionedVector &dv)
refineMode
Volume refinement controls.
T & first()
Access first element of the list, position [0].
Ostream & endl(Ostream &os)
Add newline and flush stream.
static bool orient(triSurface &, const point &, const bool orientOutside)
Flip faces such that normals are consistent with point:
const labelList & nSmoothExpansion() const
Per shell the directional smoothing iterations.
scalar distance(const vector &p1, const vector &p2)
label maxLevel() const
Highest shell level.
List< labelPair > labelPairList
List of labelPair.
#define forAll(list, i)
Loop across all elements in list.
vectorField pointField
pointField is a vectorField.
void setSize(const label n)
Alias for resize()
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
HashSet< word, Hash< word > > wordHashSet
A HashSet of words, uses string hasher.
A location inside the volume.
A location outside the volume.
labelList maxGapLevel() const
Highest shell gap level.
const wordList surface
Standard surface field types (scalar, vector, tensor, etc)
A location that is partly inside and outside.
void findDirectionalLevel(const pointField &pt, const labelList &ptLevel, const labelList &dirLevel, const direction dir, labelList &shell) const
Find any shell (or -1) with higher wanted directional level.
Pair< label > labelPair
A pair of labels.
shellSurfaces(const searchableSurfaces &allGeometry, const dictionary &shellsDict, const bool dryRun=false)
Construct from geometry and dictionary.
const vectorField & smoothDirection() const
Per shell the smoothing direction.
const labelList & nSmoothPosition() const
Per shell the positional smoothing iterations.
List< word > wordList
List of word.
vector point
Point is a vector.
#define WarningInFunction
Report a warning using Foam::Warning.
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
const wordList & names() const
Surface names, not region names.
messageStream Info
Information stream (stdout output on master, null elsewhere)
#define IOWarningInFunction(ios)
Report an IO warning using Foam::Warning.
#define forAllReverse(list, i)
Reverse loop across all elements in list.
List< label > labelList
A List of labels.
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
bool returnReduceOr(const bool value, const label comm=UPstream::worldComm)
Perform logical (or) MPI Allreduce on a copy. Uses UPstream::reduceOr.
mode_t mode(const fileName &name, const bool followLink=true)
Return the file mode, normally following symbolic links.
static const Vector< label > zero
IOerror FatalIOError
Error stream (stdout output on all processes), with additional 'FOAM FATAL IO ERROR' header text and ...
static constexpr const zero Zero
Global zero (0)