44void Foam::conformationSurfaces::hasBoundedVolume
46 List<volumeType>& referenceVolumeTypes
50 label totalTriangles = 0;
54 const searchableSurface&
surface(allGeometry_[surfaces_[
s]]);
60 normalVolumeTypes_[regionOffset_[
s]]
67 List<volumeType> vTypes
75 referenceVolumeTypes[
s] = vTypes[0];
77 Info<<
" is " << referenceVolumeTypes[
s].str()
78 <<
" surface " <<
surface.name()
92 Info<<
" Index = " << surfaces_[
s] <<
endl;
93 Info<<
" Offset = " << regionOffset_[
s] <<
endl;
95 for (
const labelledTri&
f : triSurf)
97 const label
patchID =
f.region() + regionOffset_[
s];
106 sum +=
f.areaNormal(surfPts);
113 Info<<
" has " << nBaffles <<
" baffles out of "
114 << triSurf.size() <<
" triangles" <<
nl;
116 totalTriangles += triSurf.size();
120 Info<<
" Sum of all the surface normals (if near zero, surface is"
121 <<
" probably closed):" <<
nl
122 <<
" Note: Does not include baffle surfaces in calculation" <<
nl
123 <<
" Sum = " <<
sum/(totalTriangles + SMALL) <<
nl
124 <<
" mag(Sum) = " <<
mag(
sum)/(totalTriangles + SMALL)
129void Foam::conformationSurfaces::readFeatures
133 const word& surfaceName,
137 const word featureMethod =
138 featureDict.getOrDefault<
word>(
"featureMethod",
"none");
140 if (featureMethod ==
"extendedFeatureEdgeMesh")
144 featureDict.get<
fileName>(
"extendedFeatureEdgeMesh")
147 Info<<
" features: " << feMeshName <<
endl;
157 runTime_.time().constant(),
158 "extendedFeatureEdgeMesh",
168 else if (featureMethod ==
"extractFeatures")
173 <<
" of type " <<
surface.type()
174 <<
", id: " << featureIndex <<
endl;
181 if (ssFeatures().hasFeatures())
186 ssFeatures().features()
194 <<
surface.name() <<
" of type "
195 <<
surface.type() <<
" does not have features"
199 else if (featureMethod ==
"none")
206 <<
"No valid featureMethod found for surface " << surfaceName
207 <<
nl <<
"Use \"extendedFeatureEdgeMesh\" "
208 <<
"or \"extractFeatures\"."
213void Foam::conformationSurfaces::readFeatures
216 const word& surfaceName,
220 const word featureMethod =
221 featureDict.getOrDefault<
word>(
"featureMethod",
"none");
223 if (featureMethod ==
"extendedFeatureEdgeMesh")
227 featureDict.get<
fileName>(
"extendedFeatureEdgeMesh")
230 Info<<
" features: " << feMeshName <<
", id: " << featureIndex
241 runTime_.time().constant(),
242 "extendedFeatureEdgeMesh",
252 else if (featureMethod ==
"none")
259 <<
"No valid featureMethod found for surface " << surfaceName
260 <<
nl <<
"Use \"extendedFeatureEdgeMesh\" "
261 <<
"or \"extractFeatures\"."
269Foam::conformationSurfaces::conformationSurfaces
278 allGeometry_(allGeometry),
280 locationInMesh_(surfaceConformationDict.
get<
point>(
"locationInMesh")),
282 allGeometryToSurfaces_(),
283 normalVolumeTypes_(),
289 referenceVolumeTypes_()
293 surfaceConformationDict.subDict(
"geometryToConformTo")
298 surfaceConformationDict.subDict(
"additionalFeatures")
307 for (
const word& geomName : allGeometry_.names())
309 if (surfacesDict.found(geomName))
315 const label nAddFeat = additionalFeaturesDict.size();
317 Info<<
nl <<
"Reading geometryToConformTo" <<
endl;
319 allGeometryToSurfaces_.setSize(allGeometry_.size(), -1);
321 normalVolumeTypes_.setSize(surfI);
322 surfaces_.setSize(surfI);
323 surfZones_.setSize(surfI);
326 features_.setSize(surfI + nAddFeat);
330 regionOffset_.setSize(surfI, 0);
332 PtrList<dictionary> globalPatchInfo(surfI);
333 List<Map<autoPtr<dictionary>>> regionPatchInfo(surfI);
334 List<sideVolumeType> globalVolumeTypes(surfI);
335 List<Map<sideVolumeType>> regionVolumeTypes(surfI);
340 forAll(allGeometry_.names(), geomI)
342 const word& geomName = allGeometry_.names()[geomI];
344 const entry* ePtr = surfacesDict.findEntry(geomName, keyType::REGEX);
349 unmatchedKeys.erase(ePtr->keyword());
351 surfaces_[surfI] = geomI;
353 const searchableSurface&
surface = allGeometry_[surfaces_[surfI]];
356 if (
dict.found(
"faceZone"))
365 allGeometry_.regionNames()[surfaces_[surfI]]
370 allGeometryToSurfaces_[surfaces_[surfI]] = surfI;
375 allGeometry_.regionNames()[surfaces_[surfI]];
379 globalVolumeTypes[surfI] =
381 extendedFeatureEdgeMesh::sideVolumeTypeNames_
383 dict.getOrDefault<word>
391 if (!globalVolumeTypes[surfI])
396 <<
"Non-baffle surface "
398 <<
" does not allow inside/outside queries."
399 <<
" This usually is an error." <<
endl;
404 if (
dict.found(
"patchInfo"))
409 dict.subDict(
"patchInfo").clone()
423 if (
dict.found(
"regions"))
436 const dictionary& regionDict = regionsDict.subDict
441 if (regionDict.found(
"patchInfo"))
443 regionPatchInfo[surfI].insert
446 regionDict.subDict(
"patchInfo").clone()
450 regionVolumeTypes[surfI].insert
453 extendedFeatureEdgeMesh::sideVolumeTypeNames_
455 regionDict.getOrDefault<word>
458 extendedFeatureEdgeMesh::
461 globalVolumeTypes[surfI]
467 readFeatures(regionDict,
regionName, featureI);
477 if (unmatchedKeys.size() > 0)
480 <<
"Not all entries in conformationSurfaces dictionary were used."
481 <<
" The following entries were not used : "
482 << unmatchedKeys.sortedToc()
492 regionOffset_[surfI] = nRegions;
494 const searchableSurface&
surface = allGeometry_[surfaces_[surfI]];
499 patchInfo_.setSize(nRegions);
500 normalVolumeTypes_.setSize(nRegions);
504 const searchableSurface&
surface = allGeometry_[surfaces_[surfI]];
509 for (label i = 0; i < nRegions; i++)
511 label globalRegionI = regionOffset_[surfI] + i;
512 normalVolumeTypes_[globalRegionI] = globalVolumeTypes[surfI];
513 if (globalPatchInfo.set(surfI))
518 globalPatchInfo[surfI].clone()
525 label globalRegionI = regionOffset_[surfI] + iter.key();
527 normalVolumeTypes_[globalRegionI] =
528 regionVolumeTypes[surfI][iter.key()];
531 const Map<autoPtr<dictionary>>& localInfo = regionPatchInfo[surfI];
534 label globalRegionI = regionOffset_[surfI] + iter.key();
536 patchInfo_.set(globalRegionI, iter()().clone());
542 if (!additionalFeaturesDict.empty())
544 Info<<
nl <<
"Reading additionalFeatures" <<
endl;
547 for (
const entry& dEntry : additionalFeaturesDict)
549 const word& featureName = dEntry.keyword();
550 const dictionary& featureSubDict = dEntry.dict();
554 readFeatures(featureSubDict, featureName, featureI);
558 features_.setSize(featureI);
560 globalBounds_ = treeBoundBox
562 searchableSurfacesQueries::bounds(allGeometry_, surfaces_)
569 globalBounds_.grow(1
e-4*globalBounds_.span());
575 referenceVolumeTypes_.setSize
582 <<
"Testing for locationInMesh " << locationInMesh_ <<
endl;
584 hasBoundedVolume(referenceVolumeTypes_);
588 Info<<
"Names = " << allGeometry_.names() <<
endl;
589 Info<<
"Surfaces = " << surfaces_ <<
endl;
590 Info<<
"AllGeom to Surfaces = " << allGeometryToSurfaces_ <<
endl;
591 Info<<
"Volume types = " << normalVolumeTypes_ <<
endl;
592 Info<<
"Patch names = " << patchNames_ <<
endl;
593 Info<<
"Region Offset = " << regionOffset_ <<
endl;
597 Info<< features_[fI].name() <<
endl;
609 if (allGeometry_[surfaces_[
s]].
overlaps(bb))
630 const point& samplePt
648 const point& samplePt
660 const bool testForInside
678 const label regionI = regionOffset_[
s];
682 surface.getVolumeType(samplePts, surfaceVolumeTests[
s]);
691 Field<bool> insideOutsidePoint(samplePts.size(), testForInside);
715 insideOutsidePoint[i] =
false;
722 const label regionI = regionOffset_[
s];
741 surface.findNearest(sample, nearestDistSqr, info);
746 info[0].
point() - samplePts[i]
752 findSurfaceNearestIntersection
755 info[0].
point() - 1
e-3*
mag(hitDir)*hitDir,
760 if (surfHit.hit() && hitSurface != surfaces_[
s])
770 normalVolumeTypes_[regionI]
774 insideOutsidePoint[i] = !testForInside;
782 normalVolumeTypes_[regionI]
786 insideOutsidePoint[i] = !testForInside;
793 return insideOutsidePoint;
803 return wellInOutSide(samplePts, testDistSqr,
true);
809 const point& samplePt,
823 return wellInOutSide(samplePts, testDistSqr,
false);
829 const point& samplePt,
856 return hitInfo[0].hit();
881 surfHit = hitInfo[0];
889 hitSurface = surfaces_[hitSurfaces[0]];
915 surfHit = hitInfo[0];
917 hitSurface.setSize(hitSurfaces[0].size());
919 forAll(hitSurfaces[0], surfI)
925 hitSurface[surfI] = surfaces_[hitSurfaces[0][surfI]];
955 surfHit = hitInfoStart[0];
963 hitSurface = surfaces_[hitSurfacesStart[0]];
971 scalar nearestDistSqr,
989 surfHit = surfaceHits[0];
997 hitSurface = surfaces_[hitSurfaces[0]];
1022 if (surfaceHits[i].hit())
1028 hitSurfaces[i] = surfaces_[hitSurfaces[i]];
1036 const point& sample,
1037 scalar nearestDistSqr,
1043 scalar minDistSqr = nearestDistSqr;
1048 features_[testI].nearestFeaturePoint
1057 minDistSqr = hitInfo.point().distSqr(sample);
1067 const point& sample,
1068 scalar nearestDistSqr,
1087 edgeHit = edgeHits[0];
1088 featureHit = featuresHit[0];
1111 features_[testI].nearestFeatureEdge
1121 if (hitInfo[pointi].hit())
1123 minDistSqr[pointi] =
1124 hitInfo[pointi].point().distSqr(
samples[pointi]);
1126 edgeHits[pointi] = hitInfo[pointi];
1127 featuresHit[pointi] = testI;
1136 const point& sample,
1137 scalar nearestDistSqr,
1153 features_[testI].nearestFeatureEdgeByType
1163 if (hitInfo[typeI].hit())
1165 minDistSqr[typeI] = hitInfo[typeI].point().distSqr(sample);
1166 edgeHits[typeI] = hitInfo[typeI];
1167 featuresHit[typeI] = testI;
1176 const point& sample,
1177 const scalar searchRadiusSqr,
1192 features_[testI].allNearestFeatureEdges
1199 bool anyHit =
false;
1202 if (hitInfo[hitI].hit())
1211 edgeHitsByFeature.append(hitInfo);
1212 featuresHit.append(testI);
1220 OFstream ftStr(runTime_.time().path()/prefix +
"_allFeatures.obj");
1222 Pout<<
nl <<
"Writing all features to " << ftStr.name() <<
endl;
1232 ftStr <<
"g " << fEM.name() <<
endl;
1236 const edge&
e = eds[j];
1240 ftStr <<
"l " << verti-1 <<
' ' << verti <<
endl;
1255 findSurfaceAnyIntersection(ptA, ptB, surfHit, hitSurface);
1257 return getPatchID(hitSurface, surfHit);
1266 findSurfaceNearest(pt,
sqr(GREAT), surfHit, hitSurface);
1268 return getPatchID(hitSurface, surfHit);
1274 const label hitSurface,
1285 allGeometry_[hitSurface].getRegion
1293 + regionOffset_[allGeometryToSurfaces_[hitSurface]];
1302 const label hitSurface,
1306 const label
patchID = getPatchID(hitSurface, surfHit);
1313 return normalVolumeTypes_[
patchID];
1319 const label hitSurface,
1324 allGeometry_[hitSurface].getNormal(surfHit, normal);
1326 const label
patchID = regionOffset_[allGeometryToSurfaces_[hitSurface]];
Generic templated field type that is much like a Foam::List except that it is expected to hold numeri...
@ MUST_READ
Reading required.
@ NO_WRITE
Ignore writing from objectRegistry::writeObject().
Defines the attributes of an object for which implicit objectRegistry management is supported,...
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Output to file stream as an OSstream, normally using std::ofstream for the actual output.
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
void size(const label n)
Older name for setAddressableSize.
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
An edge is a list of two vertex labels. This can correspond to a directed graph edge or an edge on a ...
sideVolumeType
Normals point to the outside.
@ NEITHER
not sure when this may be used
static constexpr label nEdgeTypes
Number of possible feature edge types (i.e. number of slices).
A class for handling file names.
static autoPtr< searchableSurfaceFeatures > New(const searchableSurface &surface, const dictionary &dict)
Return a reference to the selected searchableSurfaceFeatures.
Base class of (analytical or triangulated) surface. Encapsulates all the search routines....
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.
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.
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.
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.
Container for searchableSurfaces. The collection is specified as a dictionary. For example,...
@ 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.
Foam::word regionName(args.getOrDefault< word >("region", Foam::polyMesh::defaultRegion))
#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 IOWarningInFunction(ios)
Report an IO warning using Foam::Warning.
#define WarningInFunction
Report a warning using Foam::Warning.
List< ReturnType > get(const UPtrList< T > &list, const AccessOp &aop)
List of values generated by applying the access operation to each list item.
const wordList surface
Standard surface field types (scalar, vector, tensor, etc).
List< edge > edgeList
List of edge.
Type & refCast(U &obj)
A dynamic_cast (for references) to Type reference.
List< word > wordList
List of word.
HashSet< word, Hash< word > > wordHashSet
A HashSet of words, uses string hasher.
List< labelList > labelListList
List of labelList.
List< label > labelList
A List of labels.
dimensionedSymmTensor sqr(const dimensionedVector &dv)
quaternion normalised(const quaternion &q)
Return the normalised (unit) quaternion of the given quaternion.
messageStream Info
Information stream (stdout output on master, null elsewhere).
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
Ostream & endl(Ostream &os)
Add newline and flush stream.
const Type * isA(const U &obj)
Attempt dynamic_cast to Type.
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
Field< vector > vectorField
Specialisation of Field<T> for vector.
vector point
Point is a vector.
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &f1, const label comm)
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...
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
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)
constexpr char nl
The newline '\n' character (0x0a).
#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)