46Foam::shellSurfaces::refineModeNames_
48 { refineMode::INSIDE,
"inside" },
49 { refineMode::OUTSIDE,
"outside" },
50 { refineMode::DISTANCE,
"distance" },
56void 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;
160void Foam::shellSurfaces::orient()
165 bool hasSurface =
false;
176 if (shell.triSurface::size())
179 overallBb.add(
s.bounds());
186 const point outsidePt = overallBb.max() + overallBb.span();
200 bool anyFlipped =
false;
231 if ((normal[0] & (info[0].
point()-outsidePt)) > 0)
238 if (anyFlipped && !dryRun_)
240 Info<<
"shellSurfaces : Flipped orientation of surface "
242 <<
" so point " << outsidePt <<
" is outside." <<
endl;
251void Foam::shellSurfaces::findHigherLevel
258 const labelList& levels = levels_[shellI];
260 if (modes_[shellI] == DISTANCE)
272 label candidateI = 0;
278 if (levels[levelI] > maxLevel[pointi])
280 candidateMap[candidateI] = pointi;
281 candidateDistSqr[candidateI] =
sqr(distances[levelI]);
287 candidateMap.setSize(candidateI);
288 candidateDistSqr.setSize(candidateI);
292 allGeometry_[shells_[shellI]].findNearest
302 if (nearInfo[i].hit())
304 const label pointi = candidateMap[i];
310 nearInfo[i].
point().dist(pt[pointi])
314 maxLevel[pointi] = levels[minDistI+1];
327 label candidateI = 0;
331 if (levels[0] > maxLevel[pointi])
333 candidates[candidateI] = pt[pointi];
334 candidateMap[candidateI] = pointi;
338 candidates.
setSize(candidateI);
339 candidateMap.setSize(candidateI);
343 allGeometry_[shells_[shellI]].getVolumeType(candidates, volType);
347 label pointi = candidateMap[i];
352 modes_[shellI] == INSIDE
356 modes_[shellI] == OUTSIDE
361 maxLevel[pointi] = levels[0];
368void Foam::shellSurfaces::findHigherGapLevel
387 if (modes_[shellI] == DISTANCE)
390 const scalar
distance = distances_[shellI][0];
394 label candidateI = 0;
398 if (ptLevel[pointI] >= info[1] && ptLevel[pointI] < info[2])
400 candidateMap[candidateI] = pointI;
405 candidateMap.setSize(candidateI);
406 candidateDistSqr.setSize(candidateI);
410 allGeometry_[shells_[shellI]].findNearest
420 if (nearInfo[i].hit())
422 const label pointI = candidateMap[i];
423 gapShell[pointI] = shellI;
424 gapInfo[pointI] = info;
425 gapMode[pointI] =
mode;
435 label candidateI = 0;
439 if (ptLevel[pointI] >= info[1] && ptLevel[pointI] < info[2])
441 candidateMap[candidateI++] = pointI;
444 candidateMap.
setSize(candidateI);
448 allGeometry_[shells_[shellI]].getVolumeType
456 const label pointI = candidateMap[i];
462 (modes_[shellI] == INSIDE && isInside)
463 || (modes_[shellI] == OUTSIDE && !isInside)
465 && info[2] > gapInfo[pointI][2]
468 gapShell[pointI] = shellI;
469 gapInfo[pointI] = info;
470 gapMode[pointI] =
mode;
477void Foam::shellSurfaces::findLevel
485 const labelList& levels = levels_[shellI];
487 if (modes_[shellI] == DISTANCE)
500 label candidateI = 0;
504 if (shell[pointI] == -1)
508 if (levels[levelI] <= minLevel[pointI])
510 candidates[candidateI] = pt[pointI];
511 candidateMap[candidateI] = pointI;
512 candidateDistSqr[candidateI] =
sqr(distances[levelI]);
519 candidates.setSize(candidateI);
520 candidateMap.setSize(candidateI);
521 candidateDistSqr.setSize(candidateI);
525 allGeometry_[shells_[shellI]].findNearest
535 if (nearInfo[i].hit())
541 nearInfo[i].
point().dist(candidates[i])
544 label pointI = candidateMap[i];
547 shell[pointI] = shellI;
548 minLevel[pointI] = levels[minDistI+1];
561 label candidateI = 0;
565 if (shell[pointI] == -1 && levels[0] <= minLevel[pointI])
567 candidates[candidateI] = pt[pointI];
568 candidateMap[candidateI] = pointI;
572 candidates.
setSize(candidateI);
573 candidateMap.setSize(candidateI);
577 allGeometry_[shells_[shellI]].getVolumeType(candidates, volType);
584 modes_[shellI] == INSIDE
588 modes_[shellI] == OUTSIDE
593 label pointI = candidateMap[i];
594 shell[pointI] = shellI;
595 minLevel[pointI] = levels[0];
611 allGeometry_(allGeometry),
618 for (
const word& geomName : allGeometry_.names())
620 if (shellsDict.found(geomName))
628 shells_.setSize(shellI);
629 modes_.setSize(shellI);
630 distances_.setSize(shellI);
631 levels_.setSize(shellI);
632 dirLevels_.setSize(shellI);
633 smoothDirection_.setSize(shellI);
634 nSmoothExpansion_.setSize(shellI);
635 nSmoothPosition_.setSize(shellI);
637 extendedGapLevel_.setSize(shellI);
638 extendedGapMode_.setSize(shellI);
639 selfProximity_.setSize(shellI);
646 forAll(allGeometry_.names(), geomI)
648 const word& geomName = allGeometry_.names()[geomI];
655 unmatchedKeys.
erase(eptr->keyword());
657 shells_[shellI] = geomI;
658 modes_[shellI] = refineModeNames_.get(
"mode",
dict);
661 setAndCheckLevels(shellI,
dict.
lookup(
"levels"));
672 const entry* levelPtr =
682 is >> dirLevels_[shellI].first().first()
683 >> dirLevels_[shellI].first().second()
684 >> dirLevels_[shellI].second();
685 is.readEnd(
"levelIncrement");
687 if (modes_[shellI] == INSIDE)
691 Info<<
"Additional directional refinement level"
692 <<
" for all cells inside " << geomName <<
endl;
695 else if (modes_[shellI] == OUTSIDE)
699 Info<<
"Additional directional refinement level"
700 <<
" for all cells outside " << geomName <<
endl;
706 <<
"Unsupported mode "
707 << refineModeNames_[modes_[shellI]]
715 nSmoothExpansion_[shellI] = 0;
716 nSmoothPosition_[shellI] = 0;
717 smoothDirection_[shellI] =
722 dict.
readEntry(
"nSmoothExpansion", nSmoothExpansion_[shellI]);
744 extendedGapLevel_[shellI] = gapSpec;
747 extendedGapMode_[shellI] =
751 selfProximity_[shellI].setSize
774 regionDict.getOrDefault
780 extendedGapLevel_[shellI][regionI] = gapSpec;
782 extendedGapMode_[shellI][regionI] =
790 selfProximity_[shellI][regionI] =
791 regionDict.getOrDefault<
bool>
800 if (extendedGapLevel_[shellI][0][0] > 0)
802 Info<<
"Refinement level up to "
803 << extendedGapLevel_[shellI][0][2]
804 <<
" for all cells in gaps for shell "
807 if (distances_[shellI].size() > 1)
810 << distances_[shellI] <<
" to detect gaps for shell "
819 if (unmatchedKeys.size() > 0)
822 <<
"Not all entries in refinementRegions dictionary were used."
823 <<
" The following entries were not used : "
824 << unmatchedKeys.sortedToc()
840 label overallMax = 0;
843 overallMax =
max(overallMax,
max(levels_[shellI]));
853 forAll(extendedGapLevel_, shelli)
855 const List<FixedList<label, 3>>& levels = extendedGapLevel_[shelli];
858 surfaceMax[shelli] =
max(surfaceMax[shelli], levels[i][2]);
868 forAll(dirLevels_, shelli)
870 levels[shelli] = dirLevels_[shelli].first();
878 return nSmoothExpansion_;
884 return smoothDirection_;
890 return nSmoothPosition_;
894void Foam::shellSurfaces::findHigherLevel
906 findHigherLevel(pt, shelli,
maxLevel);
911void Foam::shellSurfaces::findHigherGapLevel
916 List<FixedList<label, 3>>& gapInfo,
917 List<volumeType>& gapMode
920 gapShell.setSize(pt.size());
923 gapInfo.setSize(pt.size());
924 gapInfo = FixedList<label, 3>({0, 0, 0});
926 gapMode.setSize(pt.size());
931 findHigherGapLevel(pt, ptLevel, shelli, gapShell, gapInfo, gapMode);
936void Foam::shellSurfaces::findHigherGapLevel
940 List<FixedList<label, 3>>& gapInfo,
941 List<volumeType>& gapMode
945 findHigherGapLevel(pt, ptLevel, gapShell, gapInfo, gapMode);
949void Foam::shellSurfaces::findLevel
963 findLevel(pt, shelli, minLevel, shell);
977 shell.setSize(pt.size());
980 List<volumeType> volType;
983 DynamicList<label> candidateMap(pt.size());
987 if (modes_[shelli] == INSIDE || modes_[shelli] == OUTSIDE)
990 const label addLevel = dirLevels_[shelli].second()[dir];
993 candidateMap.clear();
996 label level = ptLevel[celli];
1000 level >= selectLevels.first()
1001 && level <= selectLevels.second()
1002 && dirLevel[celli] < level+addLevel
1005 candidateMap.append(celli);
1011 allGeometry_[shells_[shelli]].getVolumeType(candidatePt, volType);
1019 modes_[shelli] == INSIDE
1023 modes_[shelli] == OUTSIDE
1028 shell[candidateMap[i]] = shelli;
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
void clear() noexcept
Clear the addressed list, i.e. set the size to zero.
void append(const T &val)
Copy append an element to the end of this list.
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
A 1D vector of objects of type <T> with a fixed length <N>.
bool erase(T *item)
Remove the specified element from the list and delete it.
An input stream of tokens.
bool readBegin(const char *funcName)
Begin read of data chunk, starts with '('.
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
void setSize(label n)
Alias for resize().
const T & first() const noexcept
Access the first element.
const T & second() const noexcept
Access the second element.
A 2-tuple for storing two objects of dissimilar types. The container is similar in purpose to std::pa...
T & first()
Access first element of the list, position [0].
void size(const label n)
Older name for setAddressableSize.
A bounding box defined in terms of min/max extrema points.
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
const dictionary & subDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a sub-dictionary.
bool readEntry(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX, IOobjectOption::readOption readOpt=IOobjectOption::MUST_READ) const
Find entry and assign to T val. FatalIOError if it is found and the number of tokens is incorrect,...
const entry * findEntry(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find an entry (const access) with the given keyword.
T getOrDefault(const word &keyword, const T &deflt, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a T, or return the given default value. FatalIOError if it is found and the number of...
ITstream & lookup(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return an entry data stream. FatalIOError if not found, or not a stream.
bool found(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find an entry (const access) with the given keyword.
A keyword and a list of tokens is an 'entry'.
@ REGEX
Regular expression.
static bool orient(triSurface &, const point &, const bool orientOutside)
Flip faces such that normals are consistent with point:
static bool orientConsistent(triSurface &s)
Make sure surface has consistent orientation across connected.
Base class of (analytical or triangulated) surface. Encapsulates all the search routines....
Container for searchableSurfaces. The collection is specified as a dictionary. For example,...
const vectorField & smoothDirection() const
Per shell the smoothing direction.
labelList maxGapLevel() const
Highest shell gap level.
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.
shellSurfaces(const searchableSurfaces &allGeometry, const dictionary &shellsDict, const bool dryRun=false)
Construct from geometry and dictionary.
const labelList & nSmoothPosition() const
Per shell the positional smoothing iterations.
label maxLevel() const
Highest shell level.
const labelList & nSmoothExpansion() const
Per shell the directional smoothing iterations.
refineMode
Volume refinement controls.
labelPairList directionalSelectLevel() const
Min and max cell level for directional refinement.
IOoject and searching on triSurface.
An enumeration wrapper for classification of a location as being inside/outside of a volume.
@ OUTSIDE
A location outside the volume.
@ MIXED
A location that is partly inside and outside.
@ INSIDE
A location inside the volume.
A class for handling words, derived from Foam::string.
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
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))
#define IOWarningInFunction(ios)
Report an IO warning using Foam::Warning.
#define WarningInFunction
Report a warning using Foam::Warning.
const wordList surface
Standard surface field types (scalar, vector, tensor, etc).
Type & refCast(U &obj)
A dynamic_cast (for references) to Type reference.
Pair< label > labelPair
A pair of labels.
scalar distance(const vector &p1, const vector &p2)
List< word > wordList
List of word.
bool returnReduceOr(const bool value, const int communicator=UPstream::worldComm)
Perform logical (or) MPI Allreduce on a copy. Uses UPstream::reduceOr.
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
HashSet< word, Hash< word > > wordHashSet
A HashSet of words, uses string hasher.
List< labelPair > labelPairList
List of labelPair.
List< label > labelList
A List of labels.
dimensionedSymmTensor sqr(const dimensionedVector &dv)
messageStream Info
Information stream (stdout output on master, null elsewhere).
mode_t mode(const fileName &name, const bool followLink=true)
Return the file mode, normally following symbolic links.
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.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
Ostream & endl(Ostream &os)
Add newline and flush stream.
const Type * isA(const U &obj)
Attempt dynamic_cast to Type.
Field< vector > vectorField
Specialisation of Field<T> for vector.
IOerror FatalIOError
Error stream (stdout output on all processes), with additional 'FOAM FATAL IO ERROR' header text and ...
vector point
Point is a vector.
static constexpr const zero Zero
Global zero (0).
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
vectorField pointField
pointField is a vectorField.
errorManipArg< error, int > exit(error &err, const int errNo=1)
#define forAll(list, i)
Loop across all elements in list.
#define forAllReverse(list, i)
Reverse loop across all elements in list.