39 NamedEnum<refinementRegions::refineMode, 5>::
52 Foam::refinementRegions::refineModeNames_;
57 void Foam::refinementRegions::setAndCheckLevels
67 modes_[shelli] == refineMode::inside
68 || modes_[shelli] == refineMode::outside
71 if (!allGeometry_[shells_[shelli]].hasVolumeType())
74 <<
"Shell " << shell.
name()
75 <<
" is not closed so testing for '" 76 << refineModeNames_[modes_[shelli]]
77 <<
"' may fail." <<
endl;
80 distances_[shelli].setSize(0);
81 levels_[shelli].setSize(1);
83 if (dict.
found(
"levels") && !(dict.
found(
"level")))
88 if (distLevels.size() != 1)
91 <<
"For refinement mode " 92 << refineModeNames_[modes_[shelli]]
93 <<
" specify only one distance+level." 94 <<
" (its distance gets discarded)" 98 levels_[shelli][0] = distLevels[0].second();
102 if (dict.
found(
"levels"))
105 <<
"Found both 'level' and 'levels' entries, using 'level'." 112 if (modes_[shelli] == refineMode::inside)
114 Info<<
"Refinement level " << levels_[shelli][0]
115 <<
" for all cells inside " << shell.
name() <<
endl;
119 Info<<
"Refinement level " << levels_[shelli][0]
120 <<
" for all cells outside " << shell.
name() <<
endl;
125 modes_[shelli] == refineMode::insideSpan
126 || modes_[shelli] == refineMode::outsideSpan
129 if (!allGeometry_[shells_[shelli]].hasVolumeType())
132 <<
"Shell " << shell.
name()
133 <<
" is not closed so testing for '" 134 << refineModeNames_[modes_[shelli]]
135 <<
"' may fail." <<
endl;
138 distances_[shelli].setSize(1);
139 levels_[shelli].setSize(1);
141 distances_[shelli][0] = distLevel.
first();
142 levels_[shelli][0] = distLevel.second();
144 if (modes_[shelli] == refineMode::insideSpan)
146 Info<<
"Refinement level " << levels_[shelli][0]
147 <<
" for all cells inside " << shell.
name()
148 <<
" within distance " << distances_[shelli][0] <<
endl;
152 Info<<
"Refinement level " << levels_[shelli][0]
153 <<
" for all cells outside " << shell.
name()
154 <<
" within distance " << distances_[shelli][0] <<
endl;
162 distances_[shelli].
setSize(distLevels.size());
163 levels_[shelli].setSize(distLevels.size());
167 distances_[shelli][j] = distLevels[j].first();
168 levels_[shelli][j] = distLevels[j].second();
175 (distances_[shelli][j] <= distances_[shelli][j-1])
176 || (levels_[shelli][j] > levels_[shelli][j-1])
180 <<
"For refinement mode " 181 << refineModeNames_[modes_[shelli]]
182 <<
" : Refinement should be specified in order" 183 <<
" of increasing distance" 184 <<
" (and decreasing refinement level)." <<
endl 185 <<
"Distance:" << distances_[shelli][j]
186 <<
" refinementLevel:" << levels_[shelli][j]
194 Info<<
"Refinement level according to distance to " 197 forAll(levels_[shelli], j)
199 Info<<
" level " << levels_[shelli][j]
200 <<
" for all cells within " << distances_[shelli][j]
201 <<
" metre." <<
endl;
208 void Foam::refinementRegions::orient()
213 bool hasSurface =
false;
223 if (shell.triSurface::size())
229 boundBox shellBb(points[0], points[0]);
233 const point& pt = points[i];
246 const point outsidePt = overallBb.
max() + overallBb.
span();
257 && isA<triSurfaceMesh>(s)
262 refCast<const triSurfaceMesh>(
s)
282 Info<<
"refinementRegions : Flipped orientation of surface " 284 <<
" so point " << outsidePt <<
" is outside." <<
endl;
292 Foam::scalar Foam::refinementRegions::interpolate
305 tsm.triSurface::operator[](index)
311 return closeness[lf[0]]*bary[0]
312 + closeness[lf[1]]*bary[1]
313 + closeness[lf[2]]*bary[2];
317 void Foam::refinementRegions::findHigherLevel
321 const scalar level0EdgeLength,
325 const labelList& levels = levels_[shelli];
340 label candidatei = 0;
346 if (levels[leveli] > maxLevel[pointi])
348 candidates[candidatei] = pt[pointi];
349 candidateMap[candidatei] = pointi;
350 candidateDistSqr[candidatei] =
sqr(distances[leveli]);
356 candidates.setSize(candidatei);
357 candidateMap.setSize(candidatei);
358 candidateDistSqr.setSize(candidatei);
362 allGeometry_[shells_[shelli]].findNearest
370 forAll(nearInfo, candidatei)
372 if (nearInfo[candidatei].hit())
378 mag(nearInfo[candidatei].hitPoint()-candidates[candidatei])
381 label pointi = candidateMap[candidatei];
384 maxLevel[pointi] = levels[minDistI+1];
390 modes_[shelli] == refineMode::insideSpan
391 || modes_[shelli] == refineMode::outsideSpan
395 refCast<const triSurfaceMesh>(allGeometry_[shells_[shelli]]);
403 label candidatei = 0;
407 if (levels[0] > maxLevel[pointi])
409 candidates[candidatei] = pt[pointi];
410 candidateMap[candidatei] = pointi;
411 candidateDistSqr[candidatei] =
sqr(distances_[shelli][0]);
415 candidates.setSize(candidatei);
416 candidateMap.setSize(candidatei);
417 candidateDistSqr.setSize(candidatei);
431 cellsAcrossSpan_[shelli]*level0EdgeLength/(1 << (levels[0] - 1))
435 forAll(nearInfo, candidatei)
437 if (nearInfo[candidatei].hit())
445 nearInfo[candidatei].rawPoint(),
446 nearInfo[candidatei].index()
454 log2(cellsAcrossSpan_[shelli]*level0EdgeLength/span) + 1
457 maxLevel[candidateMap[candidatei]] =
min(levels[0], level);
461 maxLevel[candidateMap[candidatei]] = levels[0];
475 label candidatei = 0;
479 if (levels[0] > maxLevel[pointi])
481 candidates[candidatei] = pt[pointi];
482 candidateMap[candidatei] = pointi;
486 candidates.
setSize(candidatei);
487 candidateMap.setSize(candidatei);
491 allGeometry_[shells_[shelli]].getVolumeType(candidates, volType);
495 label pointi = candidateMap[i];
500 modes_[shelli] == refineMode::inside
504 modes_[shelli] == refineMode::outside
509 maxLevel[pointi] = levels[0];
524 allGeometry_(allGeometry)
532 const word& geomName = allGeometry_.names()[geomi];
534 if (shellsDict.
found(geomName))
541 shells_.setSize(shelli);
542 modes_.setSize(shelli);
543 distances_.setSize(shelli);
544 levels_.setSize(shelli);
545 cellsAcrossSpan_.setSize(shelli);
546 closeness_.setSize(shelli);
551 forAll(allGeometry_.names(), geomi)
553 const word& geomName = allGeometry_.names()[geomi];
562 shells_[shelli] = geomi;
563 modes_[shelli] = refineModeNames_.read(dict.
lookup(
"mode"));
566 setAndCheckLevels(shelli, dict);
570 modes_[shelli] == refineMode::insideSpan
571 || modes_[shelli] == refineMode::outsideSpan
576 if (isA<triSurfaceMesh>(surface))
578 dict.
lookup(
"cellsAcrossSpan") >> cellsAcrossSpan_[shelli];
581 refCast<const triSurfaceMesh>(surface);
593 modes_[shelli] == refineMode::insideSpan
598 surface.searchableSurface::time().constant(),
601 surface.searchableSurface::time()
603 surface.searchableSurface::time(),
615 <<
"Surface " << surface.
name()
616 <<
" is not a triSurface as required by" 618 << refineModeNames_[refineMode::insideSpan]
619 <<
" and " << refineModeNames_[refineMode::outsideSpan]
628 if (unmatchedKeys.size() > 0)
633 ) <<
"Not all entries in refinementRegions dictionary were used." 634 <<
" The following entries were not used : " 635 << unmatchedKeys.sortedToc()
650 label overallMax = 0;
654 overallMax =
max(overallMax,
max(levels_[shelli]));
661 void Foam::refinementRegions::findHigherLevel
665 const scalar level0EdgeLength,
674 findHigherLevel(pt, shelli, level0EdgeLength, maxLevel);
A HashTable with keys but without contents.
bool found(const word &, bool recursive=false, bool patternMatch=true) const
Search dictionary for given keyword.
#define forAll(list, i)
Loop across all elements in list.
A triangle primitive used to calculate face areas and swept volumes.
layerAndWeight max(const layerAndWeight &a, const layerAndWeight &b)
const word & name() const
Return name.
const entry * lookupEntryPtr(const word &, bool recursive, bool patternMatch) const
Find and return an entry data stream pointer if present.
const keyType & keyword() const
Return keyword.
errorManipArg< error, int > exit(error &err, const int errNo=1)
barycentric2D pointToBarycentric(const point &pt) const
Calculate the barycentric coordinates from the given point.
A list of keyword definitions, which are a keyword followed by any number of values (e...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
label log2(label i)
Return the log base 2 by successive bit-shifting of the given label.
A 2-tuple for storing two objects of different types.
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
const Type1 & first() const
Return first.
virtual tmp< pointField > points() const
Get the points that define the surface.
bool interpolate(const vector &p1, const vector &p2, const vector &o, vector &n, scalar l)
dimensionedSymmTensor sqr(const dimensionedVector &dv)
void size(const label)
Override size to be inconsistent with allocated storage.
virtual void findNearest(const pointField &sample, const scalarField &nearestDistSqr, List< pointIndexHit > &) const
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:
#define forAllReverse(list, i)
Reverse loop across all elements in list.
virtual const dictionary & dict() const =0
Return dictionary if this entry is a dictionary.
Tuple2< scalar, label > nearInfo
Private class for finding nearest.
scalar distance(const vector &p1, const vector &p2)
A bounding box defined in terms of the points at its extremities.
Base class of (analytical or triangulated) surface. Encapsulates all the search routines. WIP.
Initialise the NamedEnum HashTable from the static list of names.
bool erase(T *p)
Remove the specified element from the list and delete it.
wordList toc() const
Return the table of contents.
const dimensionSet dimLength
A surface geometry formed of discrete facets, e.g. triangles and/or quadrilaterals, defined in a file using formats such as Wavefront OBJ, or stereolithography STL.
Templated 2D Barycentric derived from VectorSpace. Has 3 components, one of which is redundant...
gmvFile<< "tracers "<< particles.size()<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().x()<< " ";}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().y()<< " ";}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
refinementRegions(const searchableSurfaces &allGeometry, const dictionary &shellsDict)
Construct from geometry and dictionary.
static const word & geometryDir()
Return the geometry directory name.
A class for handling words, derived from string.
Container for searchableSurfaces.
layerAndWeight min(const layerAndWeight &a, const layerAndWeight &b)
Triangle with additional region number.
label readLabel(Istream &is)
void setSize(const label)
Reset size of List.
const point & max() const
Maximum point defining the bounding box.
bool set(const Key &, const T &newElmt)
Assign a new hashedEntry, overwriting existing entries.
static const boundBox invertedBox
A very large inverted boundBox: min/max == +/- vGreat.
#define WarningInFunction
Report a warning using Foam::Warning.
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
const wordList & names() const
const List< FaceType > & localFaces() const
Return patch faces addressing into local point list.
vector span() const
The bounding box span (from minimum to maximum)
label findLower(const ListType &, typename ListType::const_reference, const label stary, const BinaryOp &bop)
Find last element < given value in sorted list and return index,.
dimensioned< scalar > mag(const dimensioned< Type > &)
#define IOWarningInFunction(ios)
Report an IO warning using Foam::Warning.
const point & min() const
Minimum point defining the bounding box.
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
label maxLevel() const
Highest shell level.
A keyword and a list of tokens is an 'entry'.
ITstream & lookup(const word &, bool recursive=false, bool patternMatch=true) const
Find and return an entry data stream.