48 bool Foam::searchableSurfaces::connected
55 const edge&
e =
s.edges()[edgeI];
57 const edge meshE(
mp[
e[0]],
mp[
e[1]]);
63 if (meshE.otherVertex(
f[i]) != -1)
72 vector eVec(meshE.vec(
s.points()));
73 scalar magEVec(
mag(eVec));
74 if (magEVec > ROOTVSMALL)
77 scalar magArea(
mag(
n));
78 if (magArea > ROOTVSMALL)
81 if (
mag(
n&(eVec/magEVec)) < SMALL)
99 Foam::searchableSurfaces::searchableSurfaces(
const label size)
197 Foam::searchableSurfaces::searchableSurfaces
201 const bool singleRegionName
205 names_(topDict.size()),
206 regionNames_(topDict.size()),
207 allSurfaces_(
identity(topDict.size()))
211 for (
const entry& dEntry : topDict)
213 if (!dEntry.isDict())
216 <<
"Found non-dictionary entry " << dEntry
217 <<
" in top-level dictionary " << topDict
221 const word&
key = dEntry.keyword();
224 names_[surfI] =
dict.getOrDefault<
word>(
"name",
key);
233 namedIO().rename(
key);
250 const wordList& localNames =
s.regions();
252 wordList& rNames = regionNames_[surfI];
255 if (singleRegionName && localNames.
size() == 1)
257 rNames[0] = names_[surfI];
261 forAll(localNames, regionI)
263 rNames[regionI] = names_[surfI] +
'_' + localNames[regionI];
268 if (
dict.found(
"regions"))
272 for (
const entry& dEntry : regionsDict)
276 const word&
key = dEntry.keyword();
279 label index = localNames.
find(
key);
284 <<
"Unknown region name " <<
key 285 <<
" for surface " <<
s.name() <<
nl 286 <<
"Valid region names are " << localNames
291 rNames[index] = regionDict.
get<
word>(
"name");
302 regionNames_.setSize(surfI);
311 const word& wantedName
314 return names_.find(wantedName);
320 const word& surfaceName,
324 const label surfaceIndex = findSurfaceID(surfaceName);
326 return this->operator[](surfaceIndex).regions().find(
regionName);
454 Info<<
"Checking for closedness." <<
endl;
457 bool hasError =
false;
461 if (!
operator[](surfI).hasVolumeType())
468 <<
" : not closed" <<
endl;
471 if (isA<triSurface>(
operator[](surfI)))
473 const triSurface&
s =
dynamic_cast<const triSurface&
> 479 label nSingleEdges = 0;
482 if (edgeFaces[edgeI].size() == 1)
488 label nMultEdges = 0;
491 if (edgeFaces[edgeI].size() > 2)
497 if (report && (nSingleEdges != 0 || nMultEdges != 0))
499 Info<<
" connected to one face : " 500 << nSingleEdges <<
nl 501 <<
" connected to >2 faces : " 502 << nMultEdges <<
endl;
521 Info<<
"Checking for normal orientation." <<
endl;
524 bool hasError =
false;
528 if (isA<triSurface>(
operator[](surfI)))
530 const triSurface&
s =
dynamic_cast<const triSurface&
> 547 <<
" : has multiple orientation zones (" 548 << nZones <<
")" <<
endl;
565 const scalar maxRatio,
571 Info<<
"Checking for size." <<
endl;
574 bool hasError =
false;
578 const boundBox& bb = operator[](i).bounds();
580 for (label j = i+1; j < size(); j++)
582 scalar ratio = bb.mag()/operator[](j).bounds().mag();
584 if (ratio > maxRatio || ratio < 1.0/maxRatio)
591 <<
" bounds differ from " <<
names()[j]
592 <<
" by more than a factor 100:" <<
nl 593 <<
" bounding box : " << bb <<
nl 594 <<
" bounding box : " << operator[](j).bounds()
613 const scalar tolerance,
614 autoPtr<coordSetWriter>& setWriter,
620 Info<<
"Checking for intersection." <<
endl;
625 bool hasError =
false;
629 if (isA<triSurfaceMesh>(
operator[](i)))
631 const triSurfaceMesh& s0 =
dynamic_cast<const triSurfaceMesh&
> 635 const edgeList& edges0 = s0.edges();
636 const pointField& localPoints0 = s0.localPoints();
643 const edge&
e = edges0[edgeI];
644 start[edgeI] = localPoints0[
e[0]];
645 end[edgeI] = localPoints0[
e[1]];
651 List<pointIndexHit> hits;
668 operator[](j).findLineAny(start,
end, hits);
671 DynamicField<point> intersections(edges0.size()/100);
672 DynamicField<label> intersectionEdge(intersections.capacity());
679 && (i != j || !connected(s0, edgeI, hits[edgeI]))
682 intersections.append(hits[edgeI].
point());
683 intersectionEdge.append(edgeI);
696 <<
" intersects " <<
names()[j]
701 if (setWriter && setWriter->enabled())
708 std::move(intersections),
713 auto&
writer = *setWriter;
720 s0.searchableSurface::time().path()
721 / (track.name() +
"_edgeIndex")
730 Info<<
" Wrote intersection locations to " 753 const scalar minQuality,
759 Info<<
"Checking for triangle quality." <<
endl;
762 bool hasError =
false;
766 if (isA<triSurface>(
operator[](surfI)))
768 const triSurface&
s =
dynamic_cast<const triSurface&
> 776 const labelledTri&
f =
s[facei];
798 <<
" : has " << nBadTris <<
" bad quality triangles " 799 <<
" (quality < " << minQuality <<
")" <<
endl;
821 label noFailedChecks = 0;
823 if (checkClosed(report))
828 if (checkNormalOrientation(report))
832 return noFailedChecks;
838 const scalar maxRatio,
840 autoPtr<coordSetWriter>& setWriter,
841 const scalar minQuality,
845 label noFailedChecks = 0;
847 if (maxRatio > 0 && checkSizes(maxRatio, report))
852 if (checkIntersection(tol, setWriter, report))
857 if (checkQuality(minQuality, report))
862 return noFailedChecks;
877 const searchableSurface&
s = operator[](surfI);
879 Info<<
" type : " <<
s.type() <<
nl 880 <<
" size : " <<
s.globalSize() <<
nl;
881 if (isA<triSurfaceMesh>(
s))
883 const triSurfaceMesh& ts =
dynamic_cast<const triSurfaceMesh&
>(
s);
884 Info<<
" edges : " << ts.nEdges() <<
nl 885 <<
" points : " << ts.points()().size() <<
nl;
887 Info<<
" bounds : " <<
s.bounds() <<
nl 888 <<
" closed : " << Switch(
s.hasVolumeType()) <<
endl;
893 Info<<
" patches : ";
897 if (i < unique.size()-1)
916 const label surfI = findSurfaceID(surfName);
921 <<
"Surface named " << surfName <<
" not found." <<
nl 922 <<
"Available surface names: " << names_ <<
endl 926 return operator[](surfI);
935 const label surfI = findSurfaceID(surfName);
940 <<
"Surface named " << surfName <<
" not found." <<
nl 941 <<
"Available surface names: " << names_ <<
endl 945 return operator[](surfI);
void size(const label n)
Older name for setAddressableSize.
List< word > names(const UPtrList< T > &list, const UnaryMatchPredicate &matcher)
List of names generated by calling name() for each list item and filtered for matches.
label checkTopology(const bool report) const
All topological checks. Return number of failed checks.
errorManipArg< error, int > exit(error &err, const int errNo=1)
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
vtk::lineWriter writer(edgeCentres, edgeList::null(), fileName(aMesh.time().globalPath()/"finiteArea-edgesCentres"))
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
A list of keyword definitions, which are a keyword followed by a number of values (eg...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
List< edge > edgeList
List of edge.
static void findNearest(const PtrList< searchableSurface > &, const labelList &surfacesToTest, const pointField &, const scalarField &nearestDistSqr, labelList &surfaces, List< pointIndexHit > &)
Find nearest. Return -1 (and a miss()) or surface and nearest.
void findAnyIntersection(const pointField &start, const pointField &end, labelList &surfaces, List< pointIndexHit > &) const
Find any intersection. Return hit point information and.
constexpr char nl
The newline '\n' character (0x0a)
wordList patchTypes(nPatches)
scalarField samples(nIntervals, Zero)
Ostream & endl(Ostream &os)
Add newline and flush stream.
PointIndexHit< point > pointIndexHit
A PointIndexHit with a 3D point.
label findSurfaceID(const word &name) const
Find index of surface. Return -1 if not found.
A bounding box defined in terms of min/max extrema points.
Base class of (analytical or triangulated) surface. Encapsulates all the search routines. WIP.
static void findAllIntersections(const PtrList< searchableSurface > &, const labelList &surfacesToTest, const pointField &start, const pointField &end, labelListList &surfaces, List< List< pointIndexHit >> &surfaceHits)
Find all intersections in order from start to end. Returns for.
T get(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a T. FatalIOError if not found, or if the number of tokens is incorrect.
boundBox bounds() const
Calculate bounding box.
void findNearestIntersection(const pointField &start, const pointField &end, labelList &surface1, List< pointIndexHit > &hit1, labelList &surface2, List< pointIndexHit > &hit2) const
List< labelList > labelListList
List of labelList.
label findSurfaceRegionID(const word &surfaceName, const word ®ionName) const
void write(const word &fieldName, const UList< Type > &field)
Write primitive field of CellData (Poly or Line) or PointData values.
bool checkIntersection(const scalar tol, autoPtr< coordSetWriter > &setWriter, const bool report) const
Do surfaces self-intersect or intersect others.
bool checkNormalOrientation(const bool report) const
Are all (triangulated) surfaces consistent normal orientation.
Various functions to operate on Lists.
#define forAll(list, i)
Loop across all elements in list.
HashSet< label, Hash< label > > labelHashSet
A HashSet of labels, uses label hasher.
vectorField pointField
pointField is a vectorField.
const dimensionedScalar e
Elementary charge.
void setSize(const label n)
Alias for resize()
void findNearest(const pointField &, const scalarField &nearestDistSqr, labelList &surfaces, List< pointIndexHit > &) const
Find nearest. Return -1 (and a miss()) or surface and nearest.
static void findNearestIntersection(const PtrList< searchableSurface > &allSurfaces, const labelList &surfacesToTest, const pointField &start, const pointField &end, labelList &surface1, List< pointIndexHit > &hit1, labelList &surface2, List< pointIndexHit > &hit2)
Find intersections of edge nearest to both endpoints.
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...
A class for handling words, derived from Foam::string.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
HashSet< word, Hash< word > > wordHashSet
A HashSet of words, uses string hasher.
friend Ostream & operator(Ostream &os, const UPtrList< T > &list)
Write UPtrList to Ostream.
static void findAnyIntersection(const PtrList< searchableSurface > &, const labelList &surfacesToTest, const pointField &start, const pointField &end, labelList &surfaces, List< pointIndexHit > &)
Find any intersection. Return hit point information and.
errorManip< error > abort(error &err)
label find(const T &val) const
Find index of the first occurrence of the value.
constexpr auto end(C &c) -> decltype(c.end())
Return iterator to the end of the container c.
OBJstream os(runTime.globalPath()/outputName)
virtual bool open(const fileName &file, bool parallel=UPstream::parRun())
Open file for writing (creates parent directory).
defineTypeNameAndDebug(combustionModel, 0)
void setSize(const label newLen)
Same as resize()
void findAllIntersections(const pointField &start, const pointField &end, labelListList &surfaces, List< List< pointIndexHit >> &) const
Find all intersections in order from start to end. Returns for.
List< word > wordList
List of word.
const searchableSurface & operator[](const word &) const
Return const reference to searchableSurface by name.
vector point
Point is a vector.
label checkGeometry(const scalar maxRatio, const scalar tolerance, autoPtr< coordSetWriter > &setWriter, const scalar minQuality, const bool report) const
All geometric checks. Return number of failed checks.
Foam::word regionName(args.getOrDefault< word >("region", Foam::polyMesh::defaultRegion))
auto key(const Type &t) -> typename std::enable_if< std::is_enum< Type >::value, typename std::underlying_type< Type >::type >::type
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers...
void close()
End the file contents and close the file after writing.
static autoPtr< searchableSurface > New(const word &surfaceType, const IOobject &io, const dictionary &dict)
Return a reference to the selected searchableSurface.
triangle< point, const point & > triPointRef
A triangle using referred points.
List< label > sortedToc(const UList< bool > &bools)
Return the (sorted) values corresponding to 'true' entries.
messageStream Info
Information stream (stdout output on master, null elsewhere)
bool checkQuality(const scalar minQuality, const bool report) const
Check triangle quality.
Pointer management similar to std::unique_ptr, with some additional methods and type checking...
List< label > labelList
A List of labels.
IOobject io("surfaceFilmProperties", mesh.time().constant(), mesh, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE, IOobject::NO_REGISTER)
bool checkClosed(const bool report) const
Are all surfaces closed and manifold.
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.
void writeStats(const List< wordList > &, Ostream &) const
Write some stats.
Defines the attributes of an object for which implicit objectRegistry management is supported...
bool checkSizes(const scalar maxRatio, const bool report) const
Are all bounding boxes of similar size.
const dimensionedScalar mp
Proton mass.
static boundBox bounds(const PtrList< searchableSurface > &allSurfaces, const labelUList &surfacesToTest)
Find the boundBox of the selected surfaces.
A keyword and a list of tokens is an 'entry'.