44 void 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()
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)
129 void 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\"." 213 void 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\"." 269 Foam::conformationSurfaces::conformationSurfaces
273 const searchableSurfaces& allGeometry,
274 const dictionary& surfaceConformationDict
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]];
365 allGeometry_.regionNames()[surfaces_[surfI]]
370 allGeometryToSurfaces_[surfaces_[surfI]] = surfI;
375 allGeometry_.regionNames()[surfaces_[surfI]];
379 globalVolumeTypes[surfI] =
391 if (!globalVolumeTypes[surfI])
396 <<
"Non-baffle surface " 398 <<
" does not allow inside/outside queries." 399 <<
" This usually is an error." <<
endl;
436 const dictionary& regionDict = regionsDict.subDict
441 if (regionDict.found(
"patchInfo"))
443 regionPatchInfo[surfI].insert
446 regionDict.subDict(
"patchInfo").clone()
450 regionVolumeTypes[surfI].insert
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
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
663 List<List<volumeType>> surfaceVolumeTests
676 const searchableSurface&
surface(allGeometry_[surfaces_[
s]]);
678 const label regionI = regionOffset_[
s];
682 surface.getVolumeType(samplePts, surfaceVolumeTests[
s]);
691 Field<bool> insideOutsidePoint(samplePts.size(), testForInside);
696 List<pointIndexHit> hitInfo;
715 insideOutsidePoint[i] =
false;
722 const label regionI = regionOffset_[
s];
729 const searchableSurface&
surface(allGeometry_[surfaces_[
s]]);
739 List<pointIndexHit> info;
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,
844 List<pointIndexHit> hitInfo;
856 return hitInfo[0].hit();
869 List<pointIndexHit> hitInfo;
881 surfHit = hitInfo[0];
889 hitSurface = surfaces_[hitSurfaces[0]];
898 List<pointIndexHit>& surfHit,
903 List<List<pointIndexHit>> hitInfo;
915 surfHit = hitInfo[0];
917 hitSurface.setSize(hitSurfaces[0].size());
919 forAll(hitSurfaces[0], surfI)
925 hitSurface[surfI] = surfaces_[hitSurfaces[0][surfI]];
939 List<pointIndexHit> hitInfoStart;
941 List<pointIndexHit> hitInfoEnd;
955 surfHit = hitInfoStart[0];
963 hitSurface = surfaces_[hitSurfacesStart[0]];
971 scalar nearestDistSqr,
977 List<pointIndexHit> surfaceHits;
989 surfHit = surfaceHits[0];
997 hitSurface = surfaces_[hitSurfaces[0]];
1006 List<pointIndexHit>& surfaceHits,
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,
1076 List<pointIndexHit> edgeHits;
1087 edgeHit = edgeHits[0];
1088 featureHit = featuresHit[0];
1096 List<pointIndexHit>& edgeHits,
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,
1138 List<pointIndexHit>& edgeHits,
1139 List<label>& featuresHit
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,
1178 List<List<pointIndexHit>>& edgeHitsByFeature,
1179 List<label>& featuresHit
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;
1228 const extendedFeatureEdgeMesh& fEM(features_[i]);
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
1287 List<pointIndexHit>(1, surfHit),
1293 + regionOffset_[allGeometryToSurfaces_[hitSurface]];
1302 const label hitSurface,
1306 const label
patchID = getPatchID(hitSurface, surfHit);
1313 return normalVolumeTypes_[
patchID];
1319 const label hitSurface,
1320 const List<pointIndexHit>& surfHit,
1324 allGeometry_[hitSurface].getNormal(surfHit, normal);
1326 const label
patchID = regionOffset_[allGeometryToSurfaces_[hitSurface]];
List< ReturnType > get(const UPtrList< T > &list, const AccessOp &aop)
List of values generated by applying the access operation to each list item.
void size(const label n)
Older name for setAddressableSize.
static const Enum< sideVolumeType > sideVolumeTypeNames_
errorManipArg< error, int > exit(error &err, const int errNo=1)
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
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.
void append(const T &val)
Append an element at the end of the list.
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.
static autoPtr< searchableSurfaceFeatures > New(const searchableSurface &surface, const dictionary &dict)
Return a reference to the selected searchableSurfaceFeatures.
dimensionedSymmTensor sqr(const dimensionedVector &dv)
constexpr char nl
The newline '\n' character (0x0a)
scalarField samples(nIntervals, Zero)
Ostream & endl(Ostream &os)
Add newline and flush stream.
PointIndexHit< point > pointIndexHit
A PointIndexHit with a 3D point.
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.
Ignore writing from objectRegistry::writeObject()
quaternion normalised(const quaternion &q)
Return the normalised (unit) quaternion of the given quaternion.
List< labelList > labelListList
List of labelList.
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &f1, const label comm)
const dictionary & subDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a sub-dictionary.
autoPtr< dictionary > clone() const
Construct and return clone.
bool found(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find an entry (const access) with the given keyword.
#define forAll(list, i)
Loop across all elements in list.
vectorField pointField
pointField is a vectorField.
const dimensionedScalar e
Elementary charge.
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.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
sideVolumeType
Normals point to the outside.
HashSet< word, Hash< word > > wordHashSet
A HashSet of words, uses string hasher.
A location inside the volume.
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.
A location outside the volume.
const wordList surface
Standard surface field types (scalar, vector, tensor, etc)
not sure when this may be used
int debug
Static debugging option.
defineTypeNameAndDebug(combustionModel, 0)
bool erase(T *item)
Remove the specified element from the list and delete it.
List< word > wordList
List of word.
vector point
Point is a vector.
#define WarningInFunction
Report a warning using Foam::Warning.
Foam::word regionName(args.getOrDefault< word >("region", Foam::polyMesh::defaultRegion))
messageStream Info
Information stream (stdout output on master, null elsewhere)
Field< vector > vectorField
Specialisation of Field<T> for vector.
#define IOWarningInFunction(ios)
Report an IO warning using Foam::Warning.
std::enable_if_t< std::is_same_v< bool, TypeT >, bool > set(const label i, bool val=true)
A bitSet::set() method for a list of bool.
T getOrDefault(const word &keyword, const T &deflt, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a T, or return the given default value. FatalIOError if it is found and the number of...
List< label > labelList
A List of labels.
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))
static constexpr label nEdgeTypes
Number of possible feature edge types (i.e. number of slices)
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
forAllConstIters(mixture.phases(), phase)
static boundBox bounds(const PtrList< searchableSurface > &allSurfaces, const labelUList &surfacesToTest)
Find the boundBox of the selected surfaces.
static constexpr const zero Zero
Global zero (0)