38void Foam::refinementFeatures::read
40 const objectRegistry&
io,
41 const PtrList<dictionary>& featDicts
67 "extendedFeatureEdgeMesh",
76 extFeatObj.typeFilePath<extendedFeatureEdgeMesh>()
88 Info<<
"Read extendedFeatureEdgeMesh " << extFeatObj.name()
90 eMeshPtr().writeStats(
Info);
94 set(featI,
new extendedFeatureEdgeMesh(extFeatObj, eMeshPtr()));
103 io.time().constant(),
113 featObj.typeFilePath<featureEdgeMesh>()
119 <<
"Could not open " << featObj.objectPath()
125 const edgeMesh& eMesh = eMeshPtr();
129 Info<<
"Read edgeMesh " << featObj.name() <<
nl
131 eMesh.writeStats(
Info);
139 labelList oldToNew(eMesh.points().size(), -1);
140 DynamicField<point> newPoints(eMesh.points().size());
141 forAll(pointEdges, pointi)
143 if (pointEdges[pointi].
size() > 2)
145 oldToNew[pointi] = newPoints.size();
146 newPoints.append(eMesh.points()[pointi]);
151 label nFeatures = newPoints.size();
154 if (oldToNew[pointi] == -1)
156 oldToNew[pointi] = newPoints.size();
157 newPoints.append(eMesh.points()[pointi]);
162 const edgeList& edges = eMesh.edges();
166 const edge&
e = edges[edgeI];
167 newEdges[edgeI] = edge
178 extendedEdgeMesh eeMesh
190 List<extendedEdgeMesh::sideVolumeType>(0),
204 set(featI,
new extendedFeatureEdgeMesh(featObj, eeMesh));
207 const extendedEdgeMesh& eMesh =
operator[](featI);
209 if (
dict.found(
"levels"))
211 List<Tuple2<scalar, label>> distLevels(
dict.lookup(
"levels"));
216 <<
" : levels should be at least size 1" <<
endl
217 <<
"levels : " <<
dict.lookup(
"levels")
221 distances_[featI].setSize(distLevels.size());
222 levels_[featI].setSize(distLevels.size());
226 distances_[featI][j] = distLevels[j].first();
227 levels_[featI][j] = distLevels[j].second();
229 if (levels_[featI][j] < 0)
232 <<
"Feature " << featFileName
233 <<
" has illegal refinement level " << levels_[featI][j]
242 (distances_[featI][j] <= distances_[featI][j-1])
243 || (levels_[featI][j] > levels_[featI][j-1])
247 <<
" : Refinement should be specified in order"
248 <<
" of increasing distance"
249 <<
" (and decreasing refinement level)." <<
endl
250 <<
"Distance:" << distances_[featI][j]
251 <<
" refinementLevel:" << levels_[featI][j]
278 Info<<
"Refinement level according to distance to "
279 << featFileName <<
" (" << eMesh.points().size() <<
" points, "
280 << eMesh.edges().size() <<
" edges)." <<
endl;
283 Info<<
" level " << levels_[featI][j]
284 <<
" for all cells within " << distances_[featI][j]
285 <<
" metre." <<
endl;
292void Foam::refinementFeatures::buildTrees(
const label featI)
296 const edgeList& edges = eMesh.edges();
306 bb.inflate(
rndGen, 1
e-4, ROOTVSMALL);
342void Foam::refinementFeatures::findHigherLevel
349 const labelList& levels = levels_[featI];
360 label candidateI = 0;
366 if (levels[levelI] > maxLevel[pointi])
368 candidates[candidateI] = pt[pointi];
369 candidateMap[candidateI] = pointi;
370 candidateDistSqr[candidateI] =
sqr(distances[levelI]);
376 candidates.setSize(candidateI);
377 candidateMap.setSize(candidateI);
378 candidateDistSqr.setSize(candidateI);
384 forAll(candidates, candidateI)
386 nearInfo[candidateI] =
tree.findNearest
388 candidates[candidateI],
389 candidateDistSqr[candidateI]
394 forAll(nearInfo, candidateI)
396 if (nearInfo[candidateI].hit())
402 nearInfo[candidateI].
point().dist(candidates[candidateI])
405 label pointi = candidateMap[candidateI];
408 maxLevel[pointi] = levels[minDistI+1];
419 if (!regionEdgeTreesPtr_)
421 regionEdgeTreesPtr_.reset
423 new PtrList<indexedOctree<treeDataEdge>>(size())
425 PtrList<indexedOctree<treeDataEdge>>& trees = regionEdgeTreesPtr_();
429 const extendedEdgeMesh& eMesh = operator[](featI);
431 const edgeList& edges = eMesh.edges();
441 bb.inflate(
rndGen, 1
e-4, ROOTVSMALL);
446 new indexedOctree<treeDataEdge>
448 treeDataEdge(edges,
points, eMesh.regionEdges()),
459 return *regionEdgeTreesPtr_;
473 distances_(featDicts.size()),
474 levels_(featDicts.size()),
475 edgeTrees_(featDicts.size()),
476 pointTrees_(featDicts.size()),
564 const scalar maxRatio,
572 os<<
"Checking for size." <<
endl;
575 bool hasError =
false;
582 for (label j = i+1; j <
size(); j++)
587 scalar ratio = bb.
mag()/bb2.
mag();
589 if (ratio > maxRatio || ratio < 1.0/maxRatio)
596 <<
" bounds differ from " << em2.
name()
597 <<
" by more than a factor 100:" <<
nl
598 <<
" bounding box : " << bb <<
nl
599 <<
" bounding box : " << bb2
615 <<
" bounds not fully contained in mesh"<<
nl
616 <<
" bounding box : " << bb <<
nl
617 <<
" mesh bounding box : " <<
meshBb
637 List<pointIndexHit>& nearInfo,
641 nearFeature.setSize(
samples.size());
643 nearInfo.setSize(
samples.size());
645 nearNormal.setSize(
samples.size());
650 const indexedOctree<treeDataEdge>&
tree = edgeTrees_[featI];
651 const treeDataEdge& treeData =
tree.shapes();
653 if (!treeData.empty())
660 if (nearInfo[sampleI].hit())
662 distSqr = nearInfo[sampleI].point().distSqr(
sample);
666 distSqr = nearestDistSqr[sampleI];
673 nearFeature[sampleI] = featI;
678 treeData.objectIndex(info.index())
680 nearNormal[sampleI] = treeData.line(info.index()).unitVec();
708 forAll(regionTrees, featI)
718 if (nearInfo[sampleI].hit())
720 distSqr = nearInfo[sampleI].point().distSqr(sample);
724 distSqr = nearestDistSqr[sampleI];
728 pointIndexHit info = regionTree.findNearest(sample, distSqr);
732 nearFeature[sampleI] = featI;
737 treeData.objectIndex(info.index())
739 nearNormal[sampleI] = treeData.line(info.index()).unitVec();
809 forAll(pointTrees_, featI)
812 const auto& treeData =
tree.shapes();
814 if (!treeData.empty())
821 if (nearFeature[sampleI] != -1)
823 distSqr = nearInfo[sampleI].point().distSqr(
sample);
827 distSqr = nearestDistSqr[sampleI];
834 nearFeature[sampleI] = featI;
839 treeData.objectIndex(info.
index())
848void Foam::refinementFeatures::findHigherLevel
860 findHigherLevel(pt, featI, maxLevel);
867 scalar overallMax = -GREAT;
870 overallMax =
max(overallMax,
max(distances_[featI]));
Minimal example by using system/controlDict.functions:
@ NO_REGISTER
Do not request registration (bool: false).
@ MUST_READ
Reading required.
@ NO_WRITE
Ignore writing from objectRegistry::writeObject().
const word & name() const noexcept
Return the object name.
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().
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
label index() const noexcept
Return the hit index.
bool hit() const noexcept
Is there a hit?
const point_type & point() const noexcept
Return point, no checks.
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers....
const extendedFeatureEdgeMesh * set(const label i) const
constexpr PtrList() noexcept
void size(const label n)
Older name for setAddressableSize.
const extendedFeatureEdgeMesh & operator[](const label i) const
label size() const noexcept
A bounding box defined in terms of min/max extrema points.
scalar mag() const
The magnitude/length of the bounding box diagonal.
void inflate(const scalar factor)
Expand box by factor*mag(span) in all dimensions.
const pointField & points() const noexcept
Return points.
const edgeList & edges() const noexcept
Return edges.
static autoPtr< edgeMesh > New(const fileName &name, const word &fileType)
Read construct from filename with given format.
Description of feature edges and points.
const labelList & regionEdges() const
Return the feature edges which are on the boundary between.
static autoPtr< extendedEdgeMesh > New(const fileName &name, const word &fileType)
Select constructed from filename with given file format.
static bool canRead(const fileName &name, bool verbose=false)
Can we read this file format?
static const fileName null
An empty fileName.
Non-pointer based hierarchical recursive searching.
const Type & shapes() const noexcept
Reference to shape.
@ REGEX
Regular expression.
Point unitVec() const
Return the unit vector (start-to-end).
static Type get(const dictionary &dict, const word &keyword, const bool noExit, enum keyType::option matchOpt=keyType::REGEX, const Type &deflt=Zero)
Wrapper around dictionary::get which does not exit.
Registry of regIOobjects.
void findNearestPoint(const pointField &samples, const scalarField &nearestDistSqr, labelList &nearFeature, List< pointIndexHit > &nearInfo) const
Find nearest feature point. Sets.
bool checkSizes(const scalar maxRatio, const boundBox &meshBb, const bool report, Ostream &os) const
Check sizes - return true if error and stream to os.
scalar maxDistance() const
Highest distance of all features.
void findNearestRegionEdge(const pointField &samples, const scalarField &nearestDistSqr, labelList &nearFeature, List< pointIndexHit > &nearInfo, vectorField &nearNormal) const
Find nearest point on nearest region edge. Sets.
void findNearestEdge(const pointField &samples, const scalarField &nearestDistSqr, labelList &nearFeature, List< pointIndexHit > &nearInfo, vectorField &nearNormal) const
Find nearest point on nearest feature edge. Sets.
const PtrList< indexedOctree< treeDataEdge > > & regionEdgeTrees() const
refinementFeatures(const objectRegistry &io, const PtrList< dictionary > &featDicts, const bool dryRun=false)
Construct from description.
Standard boundBox with extra functionality for use in octree.
Holds data for octree to work on an edges subset.
bool empty() const noexcept
Is the effective edge selection empty?
const linePointRef line(const label index) const
Geometric line for edge at specified shape index. Frequently used.
label objectIndex(const label index) const
Map from shape index to original (non-subset) edge label.
Holds (reference to) pointField. Encapsulation of data needed for octree searches....
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
OBJstream os(runTime.globalPath()/outputName)
List< edge > edgeList
List of edge.
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.
List< labelList > labelListList
List of labelList.
bool read(const char *buf, int32_t &val)
Same as readInt32.
List< label > labelList
A List of labels.
dimensionedSymmTensor sqr(const dimensionedVector &dv)
messageStream Info
Information stream (stdout output on master, null elsewhere).
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 & incrIndent(Ostream &os)
Increment the indent level.
Ostream & endl(Ostream &os)
Add newline and flush stream.
labelList identity(const label len, label start=0)
Return an identity map of the given length with (map[i] == i), works like std::iota() but returning a...
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.
PointIndexHit< point > pointIndexHit
A PointIndexHit with a 3D point.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Ostream & decrIndent(Ostream &os)
Decrement the indent level.
constexpr char nl
The newline '\n' character (0x0a).
List< treeBoundBox > meshBb(1, treeBoundBox(coarseMesh.points()).extend(rndGen, 1e-3))
Tree tree(triangles.begin(), triangles.end())
#define forAll(list, i)
Loop across all elements in list.
#define forAllReverse(list, i)
Reverse loop across all elements in list.
scalarField samples(nIntervals, Zero)