38 void Foam::refinementFeatures::read
40 const objectRegistry&
io,
41 const PtrList<dictionary>& featDicts
46 const dictionary&
dict = featDicts[featI];
50 meshRefinement::get<fileName>
67 "extendedFeatureEdgeMesh",
74 const fileName fName(typeFilePath<extendedFeatureEdgeMesh>(extFeatObj));
85 Info<<
"Read extendedFeatureEdgeMesh " << extFeatObj.name()
87 eMeshPtr().writeStats(
Info);
91 set(featI,
new extendedFeatureEdgeMesh(extFeatObj, eMeshPtr()));
100 io.time().constant(),
108 const fileName fName(typeFilePath<featureEdgeMesh>(featObj));
113 <<
"Could not open " << featObj.objectPath()
119 const edgeMesh& eMesh = eMeshPtr();
123 Info<<
"Read edgeMesh " << featObj.name() <<
nl 125 eMesh.writeStats(
Info);
133 labelList oldToNew(eMesh.points().size(), -1);
134 DynamicField<point> newPoints(eMesh.points().size());
135 forAll(pointEdges, pointi)
137 if (pointEdges[pointi].
size() > 2)
139 oldToNew[pointi] = newPoints.size();
140 newPoints.append(eMesh.points()[pointi]);
145 label nFeatures = newPoints.size();
148 if (oldToNew[pointi] == -1)
150 oldToNew[pointi] = newPoints.size();
151 newPoints.append(eMesh.points()[pointi]);
156 const edgeList& edges = eMesh.edges();
160 const edge&
e = edges[edgeI];
161 newEdges[edgeI] = edge
172 extendedEdgeMesh eeMesh
184 List<extendedEdgeMesh::sideVolumeType>(0),
198 set(featI,
new extendedFeatureEdgeMesh(featObj, eeMesh));
201 const extendedEdgeMesh& eMesh =
operator[](featI);
203 if (
dict.found(
"levels"))
205 List<Tuple2<scalar, label>> distLevels(
dict.lookup(
"levels"));
210 <<
" : levels should be at least size 1" <<
endl 211 <<
"levels : " <<
dict.lookup(
"levels")
215 distances_[featI].
setSize(distLevels.size());
216 levels_[featI].
setSize(distLevels.size());
220 distances_[featI][j] = distLevels[j].
first();
221 levels_[featI][j] = distLevels[j].second();
223 if (levels_[featI][j] < 0)
226 <<
"Feature " << featFileName
227 <<
" has illegal refinement level " << levels_[featI][j]
236 (distances_[featI][j] <= distances_[featI][j-1])
237 || (levels_[featI][j] > levels_[featI][j-1])
241 <<
" : Refinement should be specified in order" 242 <<
" of increasing distance" 243 <<
" (and decreasing refinement level)." <<
endl 244 <<
"Distance:" << distances_[featI][j]
245 <<
" refinementLevel:" << levels_[featI][j]
258 meshRefinement::get<label>
272 Info<<
"Refinement level according to distance to " 273 << featFileName <<
" (" << eMesh.points().size() <<
" points, " 274 << eMesh.edges().size() <<
" edges)." <<
endl;
277 Info<<
" level " << levels_[featI][j]
278 <<
" for all cells within " << distances_[featI][j]
279 <<
" metre." <<
endl;
286 void Foam::refinementFeatures::buildTrees(
const label featI)
288 const extendedEdgeMesh& eMesh = operator[](featI);
290 const edgeList& edges = eMesh.edges();
300 bb.inflate(
rndGen, 1
e-4, ROOTVSMALL);
305 new indexedOctree<treeDataEdge>
307 treeDataEdge(edges,
points),
322 new indexedOctree<treeDataPoint>
324 treeDataPoint(
points, featurePoints),
336 void Foam::refinementFeatures::findHigherLevel
343 const labelList& levels = levels_[featI];
354 label candidateI = 0;
360 if (levels[levelI] > maxLevel[pointi])
362 candidates[candidateI] = pt[pointi];
363 candidateMap[candidateI] = pointi;
364 candidateDistSqr[candidateI] =
sqr(distances[levelI]);
370 candidates.setSize(candidateI);
371 candidateMap.setSize(candidateI);
372 candidateDistSqr.setSize(candidateI);
375 const indexedOctree<treeDataEdge>&
tree = edgeTrees_[featI];
377 List<pointIndexHit> nearInfo(candidates.size());
378 forAll(candidates, candidateI)
380 nearInfo[candidateI] =
tree.findNearest
382 candidates[candidateI],
383 candidateDistSqr[candidateI]
388 forAll(nearInfo, candidateI)
390 if (nearInfo[candidateI].hit())
396 nearInfo[candidateI].
point().dist(candidates[candidateI])
399 label pointi = candidateMap[candidateI];
402 maxLevel[pointi] = levels[minDistI+1];
413 if (!regionEdgeTreesPtr_)
415 regionEdgeTreesPtr_.reset
417 new PtrList<indexedOctree<treeDataEdge>>(size())
419 PtrList<indexedOctree<treeDataEdge>>& trees = regionEdgeTreesPtr_();
423 const extendedEdgeMesh& eMesh = operator[](featI);
425 const edgeList& edges = eMesh.edges();
435 bb.inflate(
rndGen, 1
e-4, ROOTVSMALL);
440 new indexedOctree<treeDataEdge>
442 treeDataEdge(edges,
points, eMesh.regionEdges()),
453 return *regionEdgeTreesPtr_;
467 distances_(featDicts.size()),
468 levels_(featDicts.size()),
469 edgeTrees_(featDicts.size()),
470 pointTrees_(featDicts.size()),
558 const scalar maxRatio,
566 os<<
"Checking for size." <<
endl;
569 bool hasError =
false;
576 for (label j = i+1; j < size(); j++)
581 scalar ratio = bb.
mag()/bb2.mag();
583 if (ratio > maxRatio || ratio < 1.0/maxRatio)
590 <<
" bounds differ from " << em2.
name()
591 <<
" by more than a factor 100:" <<
nl 592 <<
" bounding box : " << bb <<
nl 593 <<
" bounding box : " << bb2
609 <<
" bounds not fully contained in mesh"<<
nl 610 <<
" bounding box : " << bb <<
nl 611 <<
" mesh bounding box : " <<
meshBb 631 List<pointIndexHit>& nearInfo,
644 const indexedOctree<treeDataEdge>&
tree = edgeTrees_[featI];
645 const treeDataEdge& treeData =
tree.shapes();
647 if (!treeData.empty())
654 if (nearInfo[sampleI].hit())
656 distSqr = nearInfo[sampleI].point().distSqr(sample);
660 distSqr = nearestDistSqr[sampleI];
667 nearFeature[sampleI] = featI;
672 treeData.objectIndex(info.index())
674 nearNormal[sampleI] = treeData.line(info.index()).unitVec();
687 List<pointIndexHit>& nearInfo,
699 const PtrList<indexedOctree<treeDataEdge>>& regionTrees =
702 forAll(regionTrees, featI)
704 const indexedOctree<treeDataEdge>& regionTree = regionTrees[featI];
705 const treeDataEdge& treeData = regionTree.shapes();
712 if (nearInfo[sampleI].hit())
714 distSqr = nearInfo[sampleI].point().distSqr(sample);
718 distSqr = nearestDistSqr[sampleI];
722 pointIndexHit info = regionTree.findNearest(sample, distSqr);
726 nearFeature[sampleI] = featI;
731 treeData.objectIndex(info.index())
733 nearNormal[sampleI] = treeData.line(info.index()).unitVec();
803 forAll(pointTrees_, featI)
806 const auto& treeData =
tree.shapes();
808 if (!treeData.empty())
815 if (nearFeature[sampleI] != -1)
817 distSqr = nearInfo[sampleI].point().distSqr(sample);
821 distSqr = nearestDistSqr[sampleI];
828 nearFeature[sampleI] = featI;
833 treeData.objectIndex(info.
index())
842 void Foam::refinementFeatures::findHigherLevel
854 findHigherLevel(pt, featI, maxLevel);
861 scalar overallMax = -GREAT;
864 overallMax =
max(overallMax,
max(distances_[featI]));
List< labelList > labelListList
A List of labelList.
const T & operator[](const label i) const
Return const reference to the element.
void size(const label n)
Older name for setAddressableSize.
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...
static autoPtr< extendedEdgeMesh > New(const fileName &name, const word &fileType)
Select constructed from filename with given file format.
const pointField & points() const noexcept
Return points.
errorManipArg< error, int > exit(error &err, const int errNo=1)
scalar maxDistance() const
Highest distance of all features.
void findNearestPoint(const pointField &samples, const scalarField &nearestDistSqr, labelList &nearFeature, List< pointIndexHit > &nearInfo) const
Find nearest feature point. Sets.
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.
const word & name() const noexcept
Return the object name.
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
dimensionedSymmTensor sqr(const dimensionedVector &dv)
constexpr char nl
The newline '\n' character (0x0a)
static const fileName null
An empty fileName.
T & first()
Access first element of the list, position [0].
scalarField samples(nIntervals, Zero)
Ostream & endl(Ostream &os)
Add newline and flush stream.
PointIndexHit< point > pointIndexHit
A PointIndexHit with a 3D point.
A bounding box defined in terms of min/max extrema points.
This class describes the interaction of an object (often a face) and a point. It carries the info of ...
Ignore writing from objectRegistry::writeObject()
bool checkSizes(const scalar maxRatio, const boundBox &meshBb, const bool report, Ostream &os) const
Check sizes - return true if error and stream to os.
#define forAll(list, i)
Loop across all elements in list.
const point_type & point() const noexcept
Return point, no checks.
vectorField pointField
pointField is a vectorField.
const dimensionedScalar e
Elementary charge.
void setSize(const label n)
Alias for resize()
IOobject io("surfaceFilmProperties", mesh.time().constant(), mesh, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE, false)
List< edge > edgeList
A List of edges.
labelList identity(const label len, label start=0)
Return an identity map of the given length with (map[i] == i)
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
scalar mag() const
The magnitude/length of the bounding box diagonal.
label size() const noexcept
The number of elements in the list.
Tree tree(triangles.begin(), triangles.end())
static bool canRead(const fileName &name, bool verbose=false)
Can we read this file format?
label index() const noexcept
Return the hit index.
An Ostream is an abstract base class for all output systems (streams, files, token lists...
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
OBJstream os(runTime.globalPath()/outputName)
Ostream & decrIndent(Ostream &os)
Decrement the indent level.
bool hit() const noexcept
Is there a hit?
void findNearestRegionEdge(const pointField &samples, const scalarField &nearestDistSqr, labelList &nearFeature, List< pointIndexHit > &nearInfo, vectorField &nearNormal) const
Find nearest point on nearest region edge. Sets.
vector point
Point is a vector.
Non-pointer based hierarchical recursive searching.
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers...
const PtrList< indexedOctree< treeDataEdge > > & regionEdgeTrees() const
void findNearestEdge(const pointField &samples, const scalarField &nearestDistSqr, labelList &nearFeature, List< pointIndexHit > &nearInfo, vectorField &nearNormal) const
Find nearest point on nearest feature edge. Sets.
messageStream Info
Information stream (stdout output on master, null elsewhere)
Field< vector > vectorField
Specialisation of Field<T> for vector.
#define forAllReverse(list, i)
Reverse loop across all elements in list.
List< label > labelList
A List of labels.
Registry of regIOobjects.
bool returnReduceOr(const bool value, const label comm=UPstream::worldComm)
Perform logical (or) MPI Allreduce on a copy. Uses UPstream::reduceOr.
refinementFeatures(const objectRegistry &io, const PtrList< dictionary > &featDicts, const bool dryRun=false)
Construct from description.
Ostream & incrIndent(Ostream &os)
Increment the indent level.
static autoPtr< edgeMesh > New(const fileName &name, const word &fileType)
Read construct from filename with given format.
List< treeBoundBox > meshBb(1, treeBoundBox(coarseMesh.points()).extend(rndGen, 1e-3))
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)