64 auto fnd = facesPerEdge.
find(
e);
67 label&
count = fnd.val();
77 <<
"Incorrect matched edge " << fnd.key()
103 Pout<<
"triSurfaceMesh::isSurfaceClosed:"
105 <<
" determining closedness for surface with "
215 for (
const auto&
f : ts)
220 const bool okFace = addFaceToEdge(
f.edge(fp), facesPerEdge);
226 Pout<<
"triSurfaceMesh::isSurfaceClosed :"
228 <<
" surface is non-manifold" <<
endl;
237 bool haveWarned =
false;
240 if (iter.val() != 2 && iter.val() != -1)
244 Pout<<
"triSurfaceMesh::isSurfaceClosed :"
246 <<
" surface is open" <<
endl;
255 if (iter.val() == -1)
262 <<
" is closed but has inconsistent face orientation"
264 <<
" at edge " <<
pts[iter.key().first()]
265 <<
pts[iter.key().second()]
267 <<
" This means it probably cannot be used"
268 <<
" for inside/outside queries."
269 <<
" Suppressing further messages." <<
endl;
279 Pout<<
"triSurfaceMesh::isSurfaceClosed :"
281 <<
" surface is closed" <<
endl;
291 searchableSurface(
io),
306 triSurfaceRegionSearch(static_cast<const
triSurface&>(*this)),
373 fName_ = triSurface::relativeFilePath
375 static_cast<const searchableSurface&>(*this),
383 scalar scaleFactor{0};
384 if (
dict.getOrDefault(
"scale", scaleFactor) && scaleFactor > 0)
386 Info<< searchableSurface::name()
387 <<
" : using scale " << scaleFactor << endl;
395 Info<< searchableSurface::name()
396 <<
" : ignoring triangles with quality < "
397 << minQuality_ <<
" for normals calculation." << endl;
429 const bool searchGlobal(r == localOrGlobal || r == masterOnly);
431 const fileName actualFile
434 ? io.globalFilePath(typeName)
435 : io.localFilePath(typeName)
445 Pout<<
"triSurfaceMesh(const IOobject& io) :"
446 <<
" loading surface " << io.objectPath()
447 <<
" local filePath:" << io.localFilePath(typeName)
448 <<
" from:" << actualFile << endl;
459 && ((actualFile.empty() || actualFile != localFile))
471 Pout<<
"triSurfaceMesh(const IOobject& io) :"
482 Pout<<
"triSurfaceMesh(const IOobject& io) :"
494 Pout<<
"triSurfaceMesh(const IOobject& io) :"
535 const word surfType(dict.getOrDefault<word>(
"fileType", word::null));
538 const scalar scaleFactor(dict.getOrDefault<scalar>(
"scale", 0));
540 const bool searchGlobal(r == localOrGlobal || r == masterOnly);
545 ? io.globalFilePath(typeName)
546 : io.localFilePath(typeName)
555 if (dict.readIfPresent(
"file", fName_, keyType::LITERAL))
557 fName_ = relativeFilePath
559 static_cast<const searchableSurface&>(*this),
568 Pout<<
"triSurfaceMesh(const IOobject& io, const dictionary&) :"
569 <<
" loading surface " <<
io.objectPath()
570 <<
" local filePath:" <<
io.localFilePath(
typeName)
571 <<
" from:" << actualFile <<
endl;
582 const fileName localFile(
io.localFilePath(
typeName));
587 && ((actualFile.empty() || actualFile != localFile))
594 triSurface s2(actualFile, surfType, scaleFactor);
600 Pout<<
"triSurfaceMesh(const IOobject& io) :"
607 triSurface s2(actualFile, surfType, scaleFactor);
611 Pout<<
"triSurfaceMesh(const IOobject& io) :"
619 triSurface s2(actualFile, surfType, scaleFactor);
623 Pout<<
"triSurfaceMesh(const IOobject& io) :"
634 <<
" : using scale " << scaleFactor <<
endl;
645 <<
" : ignoring triangles with quality < "
646 << minQuality_ <<
" for normals calculation." <<
endl;
673 auto&
pts = tpts.ref();
712 const point& fc = centres[facei];
713 for (
const label pointi :
f)
715 radiusSqr[facei] =
max(radiusSqr[facei], fc.
distSqr(
pts[pointi]));
744 Pout<<
"triSurfaceMesh::movePoints :"
756 const label
event = getEvent();
768 Pout<<
"triSurfaceMesh::movePoints: finished moving points" <<
endl;
780 Pout<<
"triSurfaceMesh::edgeTree :"
782 <<
" constructing tree for " << nEdges() - nInternalEdges()
783 <<
" boundary edges" <<
endl;
787 const labelRange bEdges(nInternalEdges(), nBoundaryEdges());
813 Pout<<
"triSurfaceMesh::edgeTree : "
814 <<
"calculating edge tree for bb:" << bb <<
endl;
817 const scalar oldTol =
838 Pout<<
"triSurfaceMesh::edgeTree :"
839 <<
" finished constructing tree for "
840 << nEdges() - nInternalEdges()
841 <<
" boundary edges" <<
endl;
851 if (regions_.empty())
853 regions_.setSize(
patches().size());
865 if (surfaceClosed_ == -1)
867 if (isSurfaceClosed())
890 Pout<<
"triSurfaceMesh::outsideVolumeType :"
892 <<
" triggering outsidePoint:" << outsidePt
893 <<
" orientation" <<
endl;
900 getVolumeType(
pointField(1, outsidePt), outsideVolTypes);
901 outsideVolType_ = outsideVolTypes[0];
905 Pout<<
"triSurfaceMesh::outsideVolumeType :"
906 <<
" finished outsidePoint:" << outsidePt
920 Pout<<
"triSurfaceMesh::flip :"
922 <<
" with current orientation "
931 triSurface&
s = *
this;
963 List<pointIndexHit>& info
968 Pout<<
"triSurfaceMesh::findNearest :"
970 <<
" trying to find nearest for " <<
samples.size()
971 <<
" samples with max sphere "
978 Pout<<
"triSurfaceMesh::findNearest :"
979 <<
" finished trying to find nearest for " <<
samples.
size()
980 <<
" samples" <<
endl;
990 List<pointIndexHit>& info
995 Pout<<
"triSurfaceMesh::findNearest :"
997 <<
" trying to find nearest and region for " <<
samples.size()
998 <<
" samples with max sphere "
1011 Pout<<
"triSurfaceMesh::findNearest :"
1012 <<
" finished trying to find nearest and region for "
1022 List<pointIndexHit>& info
1027 Pout<<
"triSurfaceMesh::findLine :"
1029 <<
" intersecting with "
1030 << start.size() <<
" rays" <<
endl;
1035 Pout<<
"triSurfaceMesh::findLine :"
1036 <<
" finished intersecting with "
1037 << start.size() <<
" rays" <<
endl;
1046 List<pointIndexHit>& info
1051 Pout<<
"triSurfaceMesh::findLineAny :"
1053 <<
" intersecting with "
1054 << start.size() <<
" rays" <<
endl;
1059 Pout<<
"triSurfaceMesh::findLineAny :"
1060 <<
" finished intersecting with "
1061 << start.size() <<
" rays" <<
endl;
1070 List<List<pointIndexHit>>& info
1075 Pout<<
"triSurfaceMesh::findLineAll :"
1077 <<
" intersecting with "
1078 << start.size() <<
" rays" <<
endl;
1083 Pout<<
"triSurfaceMesh::findLineAll :"
1084 <<
" finished intersecting with "
1085 << start.size() <<
" rays" <<
endl;
1092 const List<pointIndexHit>& info,
1098 Pout<<
"triSurfaceMesh::getRegion :"
1100 <<
" getting region for "
1101 << info.size() <<
" triangles" <<
endl;
1103 region.setSize(info.size());
1117 Pout<<
"triSurfaceMesh::getRegion :"
1118 <<
" finished getting region for "
1119 << info.size() <<
" triangles" <<
endl;
1126 const List<pointIndexHit>& info,
1132 Pout<<
"triSurfaceMesh::getNormal :"
1134 <<
" getting normal for "
1135 << info.size() <<
" triangles" <<
endl;
1143 if (minQuality_ >= 0)
1154 const label facei = info[i].index();
1155 normal[i] =
s[facei].unitNormal(
pts);
1157 scalar qual =
s[facei].tri(
pts).quality();
1159 if (qual < minQuality_)
1162 const labelList& fFaces = faceFaces[facei];
1164 for (
const label nbri : fFaces)
1166 scalar nbrQual =
s[nbri].tri(
pts).quality();
1170 normal[i] =
s[nbri].unitNormal(
pts);
1188 const label facei = info[i].index();
1191 normal[i] =
s[facei].unitNormal(
pts);
1202 Pout<<
"triSurfaceMesh::getNormal :"
1203 <<
" finished getting normal for "
1204 << info.size() <<
" triangles" <<
endl;
1211 auto* fldPtr = getObjectPtr<triSurfaceLabelField>(
"values");
1215 (*fldPtr).field() = values;
1241 Pout<<
"triSurfaceMesh::setField :"
1243 <<
" finished setting field for "
1251 const List<pointIndexHit>& info,
1255 const auto* fldPtr = getObjectPtr<triSurfaceLabelField>(
"values");
1259 const auto&
fld = *fldPtr;
1261 values.setSize(info.size());
1267 values[i] =
fld[info[i].index()];
1273 Pout<<
"triSurfaceMesh::setField :"
1275 <<
" finished getting field for "
1276 << info.size() <<
" triangles" <<
endl;
1284 List<volumeType>& volType
1287 const scalar oldTol =
1292 Pout<<
"triSurfaceMesh::getVolumeType :"
1294 <<
" finding orientation for " <<
points.size()
1295 <<
" samples" <<
endl;
1304 if (
tree().bb().contains(pt))
1307 volType[pointi] =
tree().getVolumeType(pt);
1309 else if (hasVolumeType())
1314 outsideVolType_ =
tree().shapes().getVolumeType(
tree(), pt);
1316 volType[pointi] = outsideVolType_;
1321 volType[pointi] =
tree().shapes().getVolumeType(
tree(), pt);
1329 Pout<<
"triSurfaceMesh::getVolumeType :"
1330 <<
" finished finding orientation for " <<
points.
size()
1331 <<
" samples" <<
endl;
1339 const bool writeOnProc
1347 instance !=
runTime.timeName()
1348 && instance !=
runTime.system()
1349 && instance !=
runTime.caseSystem()
1350 && instance !=
runTime.constant()
1351 && instance !=
runTime.caseConstant()
1354 const_cast<triSurfaceMesh&
>(*this).searchableSurface::instance() =
1356 const_cast<triSurfaceMesh&
>(*this).objectRegistry::instance() =
1368 if (!fullPath.isAbsolute())
1379 if (!
mkDir(fullPath.path()))
Macros for easy insertion into run-time selection tables.
#define addToRunTimeSelectionTable(baseType, thisType, argNames)
Add to construction table with typeName as the key.
Info<< nl;Info<< "Write faMesh in vtk format:"<< nl;{ vtk::uindirectPatchWriter writer(aMesh.patch(), fileName(aMesh.time().globalPath()/vtkBaseFileName));writer.writeGeometry();globalIndex procAddr(aMesh.nFaces());labelList cellIDs;if(UPstream::master()) { cellIDs.resize(procAddr.totalSize());for(const labelRange &range :procAddr.ranges()) { auto slice=cellIDs.slice(range);slice=identity(range);} } writer.beginCellData(4);writer.writeProcIDs();writer.write("cellID", cellIDs);writer.write("area", aMesh.S().field());writer.write("normal", aMesh.faceAreaNormals());writer.beginPointData(1);writer.write("normal", aMesh.pointAreaNormals());Info<< " "<< writer.output().name()<< nl;}{ vtk::lineWriter writer(aMesh.points(), aMesh.edges(), fileName(aMesh.time().globalPath()/(vtkBaseFileName+"-edges")));writer.writeGeometry();writer.beginCellData(4);writer.writeProcIDs();{ Field< scalar > fld(faMeshTools::flattenEdgeField(aMesh.magLe(), true))
Map from edge (expressed as its endpoints) to value. Hashing (and ==) on an edge is symmetric.
bool insert(const Key &key, const T &obj)
Copy insert a new entry, not overwriting existing entries.
iterator find(const Key &key)
Find and return an iterator set at the hashed entry.
@ REGISTER
Request registration (bool: true).
readOption readOpt() const noexcept
Get the read option.
writeOption writeOpt() const noexcept
Get the write option.
@ NO_READ
Nothing to be read.
@ AUTO_WRITE
Automatically write from objectRegistry::writeObject().
Defines the attributes of an object for which implicit objectRegistry management is supported,...
const Time & time() const noexcept
Return Time associated with the objectRegistry.
const word & name() const noexcept
Return the object name.
const objectRegistry & db() const noexcept
Return the local objectRegistry.
InfoProxy< IOobject > info() const noexcept
Return info proxy, for printing information to a stream.
const fileName & local() const noexcept
Read access to local path component.
const fileName & instance() const noexcept
Read access to instance path component.
fileName objectPath() const
The complete path + object name.
A simple container for options an IOstream can normally have.
IntType size() const noexcept
The size of the range.
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().
static const List< T > & null() noexcept
Return a null List (reference to a nullObject). Behaves like an empty List.
A list of faces which address into the list of points.
label nBoundaryEdges() const
::Foam::List< labelledTri > FaceListType
const edgeList & edges() const
label nInternalEdges() const
bool hasFaceCentres() const
const Field< point_type > & localPoints() const
const Field< point_type > & points() const noexcept
const Field< point_type > & faceCentres() const
const labelListList & faceFaces() const
A non-owning sub-view of a List (allocated or unallocated storage).
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
static word timeName(const scalar t, const int precision=precision_)
Return a time name for the given scalar time value formatted with the given precision.
bool empty() const noexcept
True if List is empty (ie, size() is zero).
label size() const noexcept
The number of elements in the container.
void size(const label n)
Older name for setAddressableSize.
T & operator[](const label i)
Return element of UList.
static bool parRun(const bool on) noexcept
Set as parallel run on/off.
static bool master(const label communicator=worldComm)
True if process corresponds to the master rank in the communicator.
@ broadcast
broadcast [MPI]
static bool & parRun() noexcept
Test if this a parallel run.
scalar distSqr(const Vector< Cmpt > &v2) const
The L2-norm distance squared from another vector. The magSqr() of the difference.
A bounding box defined in terms of min/max extrema points.
void inflate(const scalar factor)
Expand box by factor*mag(span) in all dimensions.
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
bool readIfPresent(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX) const
Find an entry if present, and assign to T val. FatalIOError if it is found and the number of tokens i...
An edge is a list of two vertex labels. This can correspond to a directed graph edge or an edge on a ...
static int compare(const edge &a, const edge &b)
Compare edges.
A class for handling file names.
static std::string path(const std::string &str)
Return directory path name (part before last /).
static bool isAbsolute(const std::string &str)
Return true if filename starts with a '/' or '\' or (windows-only) with a filesystem-root.
static scalar & perturbTol() noexcept
Get the perturbation tolerance.
Non-pointer based hierarchical recursive searching.
A range or interval of labels defined by a start and a size.
A triFace with additional (region) index.
Registry of regIOobjects.
bool contains(const word &name, const bool recursive=false) const
Does the registry contain the regIOobject object (by name).
const Time & time() const noexcept
Return time registry.
label count(const char *clsName) const
The number of objects of the given class name.
label getEvent() const
Return new event number.
Type * getObjectPtr(const word &name, const bool recursive=false) const
Return non-const pointer to the object of the given Type, using a const-cast to have it behave like a...
label eventNo() const noexcept
Event number at last update.
Base class of (analytical or triangulated) surface. Encapsulates all the search routines....
virtual const boundBox & bounds() const
Return const reference to boundBox.
string & expand(const bool allowEmpty=false)
Inplace expand initial tags, tildes, and all occurrences of environment variables as per stringOps::e...
A class for managing temporary objects.
static tmp< T > New(Args &&... args)
Construct tmp with forwarding arguments.
Standard boundBox with extra functionality for use in octree.
Holds data for octree to work on an edges subset.
IOoject and searching on triSurface.
label surfaceClosed_
Is surface closed.
virtual label size() const
Range of local indices that can be returned.
virtual bool writeObject(IOstreamOption streamOpt, const bool writeOnProc) const
Write using stream options.
virtual void flip()
Flip triangles, outsideVolumeType and all cached inside/outside.
wordList regions_
Names of regions.
volumeType outsideVolType_
If surface is closed, what is type of outside points.
virtual ~triSurfaceMesh()
Destructor.
virtual void findLine(const pointField &start, const pointField &end, List< pointIndexHit > &) const
Find first intersection on segment from start to end.
virtual void findLineAll(const pointField &start, const pointField &end, List< List< pointIndexHit > > &) const
Get all intersections in order from start to end.
virtual bool overlaps(const boundBox &bb) const
Does any part of the surface overlap the supplied bound box?
const indexedOctree< treeDataEdge > & edgeTree() const
Demand driven construction of octree for boundary edges.
virtual void findLineAny(const pointField &start, const pointField &end, List< pointIndexHit > &) const
Return any intersection on segment from start to end.
virtual void boundingSpheres(pointField ¢res, scalarField &radiusSqr) const
Get bounding spheres (centre and radius squared). Any point.
virtual void getVolumeType(const pointField &points, List< volumeType > &volType) const
Determine type (inside/outside/mixed) for point.
scalar minQuality_
Optional min triangle quality. Triangles below this get.
autoPtr< indexedOctree< treeDataEdge > > edgeTree_
Search tree for boundary edges.
virtual void setField(const labelList &values)
WIP. Store element-wise field.
virtual void getField(const List< pointIndexHit > &, labelList &) const
WIP. From a set of hits (points and.
triSurfaceMesh(const triSurfaceMesh &)=delete
No copy construct.
virtual void getNormal(const List< pointIndexHit > &, vectorField &normal) const
From a set of points and indices get the normal.
fileName fName_
Supplied fileName override.
virtual void getRegion(const List< pointIndexHit > &, labelList ®ion) const
From a set of points and indices get the region.
virtual void movePoints(const pointField &)
Move points.
virtual const wordList & regions() const
Names of regions.
virtual bool hasVolumeType() const
Whether supports volume type (below) - i.e. whether is closed.
bool isSurfaceClosed() const
Check whether surface is closed without calculating any permanent.
virtual void findNearest(const pointField &sample, const scalarField &nearestDistSqr, List< pointIndexHit > &) const
virtual tmp< pointField > coordinates() const
Get representative set of element coordinates.
static word meshSubDir
Return the mesh sub-directory name (usually "triSurface").
virtual volumeType outsideVolumeType() const
If surface is closed, what is type of points outside bounds.
static bool addFaceToEdge(const edge &, EdgeMap< label > &)
Helper function for isSurfaceClosed.
void clearOut()
Clear storage.
virtual tmp< pointField > points() const
Get the points that define the surface.
Helper class to search on triSurface. Creates an octree for each region of the surface and only searc...
void findNearest(const pointField &samples, const scalarField &nearestDistSqr, const labelList ®ionIndices, List< pointIndexHit > &info) const
Find the nearest point on the surface out of the regions.
void flip()
Flip orientation.
void clearOut()
Clear storage.
void findLineAll(const pointField &start, const pointField &end, List< List< pointIndexHit > > &info) const
Calculate all intersections from start to end.
scalar tolerance() const
Return tolerance to use in searches.
void findLine(const pointField &start, const pointField &end, List< pointIndexHit > &info) const
void findLineAny(const pointField &start, const pointField &end, List< pointIndexHit > &info) const
label maxTreeDepth() const
Return max tree depth of octree.
void findNearest(const pointField &samples, const scalarField &nearestDistSqr, List< pointIndexHit > &info) const
Triangulated surface description with patch information.
triSurface()
Default construct.
void transfer(triSurface &surf)
Alter contents by transferring (triangles, points) components.
void write(Ostream &os) const
Write to Ostream in simple OpenFOAM format.
const geometricSurfacePatchList & patches() const noexcept
virtual void movePoints(const pointField &pts)
Move points.
An enumeration wrapper for classification of a location as being inside/outside of a volume.
static const Enum< volumeType::type > names
Names for the classification enumeration.
@ OUTSIDE
A location outside the volume.
@ INSIDE
A location inside the volume.
A class for handling words, derived from Foam::string.
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
const polyBoundaryMesh & patches
PtrList< coordinateSystem > coordinates(solidRegions.size())
#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 WarningInFunction
Report a warning using Foam::Warning.
List< T > values(const HashTable< T, Key, Hash > &tbl, const bool doSort=false)
List of values from HashTable, optionally sorted.
Namespace for bounding specifications. At the moment, mostly for tables.
Namespace for handling debugging switches.
List< word > wordList
List of word.
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
DimensionedField< label, triSurfaceGeoMesh > triSurfaceLabelField
const dimensionSet dimless
Dimensionless.
List< labelList > labelListList
List of labelList.
List< label > labelList
A List of labels.
dimensionedSymmTensor sqr(const dimensionedVector &dv)
bool mkDir(const fileName &pathName, mode_t mode=0777)
Make a directory and return an error if it could not be created.
messageStream Info
Information stream (stdout output on master, null elsewhere).
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
const word GlobalIOList< Tuple2< scalar, vector > >::typeName("scalarVectorTable")
Ostream & endl(Ostream &os)
Add newline and flush stream.
dimensionedScalar sqrt(const dimensionedScalar &ds)
Field< vector > vectorField
Specialisation of Field<T> for vector.
Field< label > labelField
Specialisation of Field<T> for label.
vector point
Point is a vector.
static constexpr const zero Zero
Global zero (0).
bool isFile(const fileName &name, const bool checkGzip=true, const bool followLink=true)
Does the name exist as a FILE in the file system?
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
vectorField pointField
pointField is a vectorField.
errorManipArg< error, int > exit(error &err, const int errNo=1)
constexpr char nl
The newline '\n' character (0x0a).
Tree tree(triangles.begin(), triangles.end())
#define forAll(list, i)
Loop across all elements in list.
#define forAllConstIters(container, iter)
Iterate across all elements of the container object with const access.
scalarField samples(nIntervals, Zero)