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
73 surface.getVolumeType(pts, vTypes);
75 referenceVolumeTypes[
s] = vTypes[0];
77 Info<<
" is " << referenceVolumeTypes[
s].str()
78 <<
" surface " <<
surface.name()
82 if (isA<triSurface>(surface))
84 const triSurface& triSurf = refCast<const triSurface>(surface);
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
132 const dictionary& featureDict,
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;
152 new extendedFeatureEdgeMesh
157 runTime_.time().constant(),
158 "extendedFeatureEdgeMesh",
168 else if (featureMethod ==
"extractFeatures")
170 const searchableSurface&
surface = allGeometry_[surfaces_[surfI]];
173 <<
" of type " <<
surface.type()
174 <<
", id: " << featureIndex <<
endl;
176 autoPtr<searchableSurfaceFeatures> ssFeatures
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
215 const dictionary& featureDict,
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
236 new extendedFeatureEdgeMesh
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\"."
273 const searchableSurfaces& allGeometry,
274 const dictionary& surfaceConformationDict
278 allGeometry_(allGeometry),
280 locationInMesh_(surfaceConformationDict.
get<
point>(
"locationInMesh")),
282 allGeometryToSurfaces_(),
283 normalVolumeTypes_(),
289 referenceVolumeTypes_()
291 const dictionary& surfacesDict
293 surfaceConformationDict.subDict(
"geometryToConformTo")
296 const dictionary& additionalFeaturesDict
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);
348 const dictionary&
dict = ePtr->dict();
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"))
425 const dictionary& regionsDict =
dict.subDict(
"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 vector newSpan = 1
e-4*globalBounds_.span();
571 globalBounds_.min() -= newSpan;
572 globalBounds_.max() += newSpan;
578 referenceVolumeTypes_.setSize
585 <<
"Testing for locationInMesh " << locationInMesh_ <<
endl;
587 hasBoundedVolume(referenceVolumeTypes_);
591 Info<<
"Names = " << allGeometry_.names() <<
endl;
592 Info<<
"Surfaces = " << surfaces_ <<
endl;
593 Info<<
"AllGeom to Surfaces = " << allGeometryToSurfaces_ <<
endl;
594 Info<<
"Volume types = " << normalVolumeTypes_ <<
endl;
595 Info<<
"Patch names = " << patchNames_ <<
endl;
596 Info<<
"Region Offset = " << regionOffset_ <<
endl;
600 Info<< features_[fI].name() <<
endl;
612 if (allGeometry_[surfaces_[
s]].
overlaps(bb))
633 const point& samplePt
651 const point& samplePt
663 const bool testForInside
666 List<List<volumeType>> surfaceVolumeTests
679 const searchableSurface&
surface(allGeometry_[surfaces_[
s]]);
681 const label regionI = regionOffset_[
s];
685 surface.getVolumeType(samplePts, surfaceVolumeTests[
s]);
694 Field<bool> insideOutsidePoint(samplePts.size(), testForInside);
699 List<pointIndexHit> hitInfo;
718 insideOutsidePoint[i] =
false;
725 const label regionI = regionOffset_[
s];
732 const searchableSurface&
surface(allGeometry_[surfaces_[
s]]);
742 List<pointIndexHit> info;
749 info[0].rawPoint() - samplePts[i]
755 findSurfaceNearestIntersection
758 info[0].rawPoint() - 1
e-3*
mag(hitDir)*hitDir,
763 if (surfHit.hit() && hitSurface != surfaces_[
s])
773 normalVolumeTypes_[regionI]
777 insideOutsidePoint[i] = !testForInside;
785 normalVolumeTypes_[regionI]
789 insideOutsidePoint[i] = !testForInside;
796 return insideOutsidePoint;
806 return wellInOutSide(samplePts, testDistSqr,
true);
812 const point& samplePt,
826 return wellInOutSide(samplePts, testDistSqr,
false);
832 const point& samplePt,
847 List<pointIndexHit> hitInfo;
859 return hitInfo[0].hit();
872 List<pointIndexHit> hitInfo;
884 surfHit = hitInfo[0];
892 hitSurface = surfaces_[hitSurfaces[0]];
901 List<pointIndexHit>& surfHit,
906 List<List<pointIndexHit>> hitInfo;
918 surfHit = hitInfo[0];
920 hitSurface.setSize(hitSurfaces[0].size());
922 forAll(hitSurfaces[0], surfI)
928 hitSurface[surfI] = surfaces_[hitSurfaces[0][surfI]];
942 List<pointIndexHit> hitInfoStart;
944 List<pointIndexHit> hitInfoEnd;
958 surfHit = hitInfoStart[0];
966 hitSurface = surfaces_[hitSurfacesStart[0]];
974 scalar nearestDistSqr,
980 List<pointIndexHit> surfaceHits;
992 surfHit = surfaceHits[0];
1000 hitSurface = surfaces_[hitSurfaces[0]];
1009 List<pointIndexHit>& surfaceHits,
1025 if (surfaceHits[i].hit())
1031 hitSurfaces[i] = surfaces_[hitSurfaces[i]];
1040 scalar nearestDistSqr,
1046 scalar minDistSqr = nearestDistSqr;
1051 features_[testI].nearestFeaturePoint
1071 scalar nearestDistSqr,
1079 List<pointIndexHit> edgeHits;
1090 edgeHit = edgeHits[0];
1091 featureHit = featuresHit[0];
1099 List<pointIndexHit>& edgeHits,
1114 features_[testI].nearestFeatureEdge
1124 if (hitInfo[pointi].hit())
1126 minDistSqr[pointi] =
magSqr
1128 hitInfo[pointi].hitPoint()
1131 edgeHits[pointi] = hitInfo[pointi];
1132 featuresHit[pointi] = testI;
1142 scalar nearestDistSqr,
1143 List<pointIndexHit>& edgeHits,
1144 List<label>& featuresHit
1158 features_[testI].nearestFeatureEdgeByType
1168 if (hitInfo[typeI].hit())
1170 minDistSqr[typeI] =
magSqr(hitInfo[typeI].hitPoint() -
sample);
1171 edgeHits[typeI] = hitInfo[typeI];
1172 featuresHit[typeI] = testI;
1182 const scalar searchRadiusSqr,
1183 List<List<pointIndexHit>>& edgeHitsByFeature,
1184 List<label>& featuresHit
1197 features_[testI].allNearestFeatureEdges
1204 bool anyHit =
false;
1207 if (hitInfo[hitI].hit())
1215 edgeHitsByFeature.append(hitInfo);
1216 featuresHit.append(testI);
1224 OFstream ftStr(runTime_.time().path()/prefix +
"_allFeatures.obj");
1226 Pout<<
nl <<
"Writing all features to " << ftStr.name() <<
endl;
1232 const extendedFeatureEdgeMesh& fEM(features_[i]);
1236 ftStr <<
"g " << fEM.name() <<
endl;
1240 const edge&
e = eds[j];
1244 ftStr <<
"l " << verti-1 <<
' ' << verti <<
endl;
1259 findSurfaceAnyIntersection(ptA, ptB, surfHit, hitSurface);
1261 return getPatchID(hitSurface, surfHit);
1270 findSurfaceNearest(pt,
sqr(GREAT), surfHit, hitSurface);
1272 return getPatchID(hitSurface, surfHit);
1278 const label hitSurface,
1289 allGeometry_[hitSurface].getRegion
1291 List<pointIndexHit>(1, surfHit),
1297 + regionOffset_[allGeometryToSurfaces_[hitSurface]];
1306 const label hitSurface,
1310 const label
patchID = getPatchID(hitSurface, surfHit);
1317 return normalVolumeTypes_[
patchID];
1323 const label hitSurface,
1324 const List<pointIndexHit>& surfHit,
1328 allGeometry_[hitSurface].getNormal(surfHit, normal);
1330 const label
patchID = regionOffset_[allGeometryToSurfaces_[hitSurface]];
bool outside() const
True if any coordinates are negative.
Generic templated field type.
Minimal example by using system/controlDict.functions:
std::enable_if< std::is_same< bool, TypeT >::value, bool >::type set(const label i, bool val=true)
A bitSet::set() method for a list of bool.
int overlaps
Flag to control which overlap calculations are performed.
static autoPtr< Time > New()
Construct (dummy) Time - no functionObjects or libraries.
void size(const label n)
Older name for setAddressableSize.
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)
@ BOTH
limit by both minimum and maximum values
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.
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
@ OUTSIDE
A location outside the volume.
@ INSIDE
A location inside the volume.
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
Foam::word regionName(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)
const wordList surface
Standard surface field types (scalar, vector, tensor, etc)
List< word > wordList
A List of words.
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.
PointIndexHit< point > pointIndexHit
A PointIndexHit for 3D points.
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &df)
messageStream Info
Information stream (stdout output on master, null elsewhere)
vectorField pointField
pointField is a vectorField.
vector point
Point is a vector.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
Ostream & endl(Ostream &os)
Add newline and flush stream.
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
List< labelList > labelListList
A List of labelList.
Field< vector > vectorField
Specialisation of Field<T> for vector.
static constexpr const zero Zero
Global zero (0)
HashSet< word, Hash< word > > wordHashSet
A HashSet of words, uses string hasher.
List< edge > edgeList
A List of edges.
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
errorManipArg< error, int > exit(error &err, const int errNo=1)
dimensioned< typename typeOfMag< Type >::type > magSqr(const dimensioned< Type > &dt)
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)