41 void Foam::conformationSurfaces::hasBoundedVolume
43 List<volumeType>& referenceVolumeTypes
47 label totalTriangles = 0;
51 const searchableSurface& surface(allGeometry_[surfaces_[
s]]);
55 surface.hasVolumeType()
57 normalVolumeTypes_[regionOffset_[
s]]
64 List<volumeType> vTypes
70 surface.getVolumeType(pts, vTypes);
72 referenceVolumeTypes[
s] = vTypes[0];
76 <<
" surface " << surface.name()
80 if (isA<triSurface>(surface))
82 const triSurface& triSurf = refCast<const triSurface>(surface);
86 Info<<
" Checking " << surface.name() <<
endl;
90 Info<<
" Index = " << surfaces_[
s] <<
endl;
91 Info<<
" Offset = " << regionOffset_[
s] <<
endl;
102 normalVolumeTypes_[patchID]
106 sum += triSurf[sI].area(surfPts);
113 Info<<
" has " << nBaffles <<
" baffles out of " 114 << triSurf.size() <<
" triangles" <<
endl;
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,
138 featureDict.lookupOrDefault<word>(
"featureMethod",
"none");
140 if (featureMethod ==
"extendedFeatureEdgeMesh")
142 fileName feMeshName(featureDict.lookup(
"extendedFeatureEdgeMesh"));
144 Info<<
" features: " << feMeshName <<
endl;
149 new extendedFeatureEdgeMesh
154 runTime_.time().constant(),
155 "extendedFeatureEdgeMesh",
165 else if (featureMethod ==
"extractFeatures")
167 const searchableSurface& surface = allGeometry_[surfaces_[surfI]];
169 Info<<
" features: " << surface.name()
170 <<
" of type " << surface.type()
171 <<
", id: " << featureIndex <<
endl;
173 autoPtr<searchableSurfaceFeatures> ssFeatures
178 if (ssFeatures().hasFeatures())
183 ssFeatures().features()
191 << surface.name() <<
" of type " 192 << surface.type() <<
" does not have features" 196 else if (featureMethod ==
"none")
203 <<
"No valid featureMethod found for surface " << surfaceName
204 <<
nl <<
"Use \"extendedFeatureEdgeMesh\" " 205 <<
"or \"extractFeatures\"." 210 void Foam::conformationSurfaces::readFeatures
212 const dictionary& featureDict,
213 const word& surfaceName,
218 featureDict.lookupOrDefault<word>(
"featureMethod",
"none");
220 if (featureMethod ==
"extendedFeatureEdgeMesh")
222 fileName feMeshName(featureDict.lookup(
"extendedFeatureEdgeMesh"));
224 Info<<
" features: " << feMeshName <<
", id: " << featureIndex
230 new extendedFeatureEdgeMesh
235 runTime_.time().constant(),
236 "extendedFeatureEdgeMesh",
246 else if (featureMethod ==
"none")
253 <<
"No valid featureMethod found for surface " << surfaceName
254 <<
nl <<
"Use \"extendedFeatureEdgeMesh\" " 255 <<
"or \"extractFeatures\"." 263 Foam::conformationSurfaces::conformationSurfaces
267 const searchableSurfaces& allGeometry,
268 const dictionary& surfaceConformationDict
273 allGeometry_(allGeometry),
275 locationInMesh_(surfaceConformationDict.
lookup(
"locationInMesh")),
277 allGeometryToSurfaces_(),
278 normalVolumeTypes_(),
284 referenceVolumeTypes_(0)
286 const dictionary& surfacesDict
288 surfaceConformationDict.subDict(
"geometryToConformTo")
291 const dictionary& additionalFeaturesDict
293 surfaceConformationDict.subDict(
"additionalFeatures")
302 forAll(allGeometry.names(), geomI)
304 const word& geomName = allGeometry_.names()[geomI];
306 if (surfacesDict.found(geomName))
312 const label nAddFeat = additionalFeaturesDict.size();
314 Info<<
nl <<
"Reading geometryToConformTo" <<
endl;
316 allGeometryToSurfaces_.setSize(allGeometry_.size(), -1);
318 normalVolumeTypes_.setSize(surfI);
319 surfaces_.setSize(surfI);
320 surfZones_.setSize(surfI);
323 features_.setSize(surfI + nAddFeat);
327 regionOffset_.setSize(surfI, 0);
329 PtrList<dictionary> globalPatchInfo(surfI);
330 List<Map<autoPtr<dictionary>>> regionPatchInfo(surfI);
331 List<sideVolumeType> globalVolumeTypes(surfI);
332 List<Map<sideVolumeType>> regionVolumeTypes(surfI);
334 HashSet<word> unmatchedKeys(surfacesDict.toc());
337 forAll(allGeometry_.names(), geomI)
339 const word& geomName = allGeometry_.names()[geomI];
341 const entry* ePtr = surfacesDict.lookupEntryPtr(geomName,
false,
true);
345 const dictionary& dict = ePtr->dict();
346 unmatchedKeys.erase(ePtr->keyword());
348 surfaces_[surfI] = geomI;
350 const searchableSurface& surface = allGeometry_[surfaces_[surfI]];
353 if (dict.found(
"faceZone"))
355 surfZones_.set(surfI,
new surfaceZonesInfo(surface, dict));
358 allGeometryToSurfaces_[surfaces_[surfI]] = surfI;
363 allGeometry_.regionNames()[surfaces_[surfI]];
365 patchNames_.
append(regionNames);
367 globalVolumeTypes[surfI] =
371 dict.lookupOrDefault<word>
379 if (!globalVolumeTypes[surfI])
381 if (!surface.hasVolumeType())
384 <<
"Non-baffle surface " 386 <<
" does not allow inside/outside queries." 387 <<
" This usually is an error." <<
endl;
392 if (dict.found(
"patchInfo"))
397 dict.subDict(
"patchInfo").clone()
409 const wordList& rNames = surface.regions();
411 if (dict.found(
"regions"))
413 const dictionary& regionsDict = dict.subDict(
"regions");
417 const word& regionName = rNames[regionI];
419 if (regionsDict.found(regionName))
421 Info<<
" region " << regionName <<
endl;
424 const dictionary& regionDict = regionsDict.subDict
429 if (regionDict.found(
"patchInfo"))
431 regionPatchInfo[surfI].insert
434 regionDict.subDict(
"patchInfo").clone()
438 regionVolumeTypes[surfI].insert
443 regionDict.lookupOrDefault<word>
446 extendedFeatureEdgeMesh::
449 globalVolumeTypes[surfI]
455 readFeatures(regionDict, regionName, featureI);
465 if (unmatchedKeys.size() > 0)
470 ) <<
"Not all entries in conformationSurfaces dictionary were used." 471 <<
" The following entries were not used : " 472 << unmatchedKeys.sortedToc()
482 regionOffset_[surfI] = nRegions;
484 const searchableSurface& surface = allGeometry_[surfaces_[surfI]];
485 nRegions += surface.regions().size();
489 patchInfo_.setSize(nRegions);
490 normalVolumeTypes_.setSize(nRegions);
494 const searchableSurface& surface = allGeometry_[surfaces_[surfI]];
496 label nRegions = surface.regions().size();
499 for (
label i = 0; i < nRegions; i++)
501 label globalRegionI = regionOffset_[surfI] + i;
502 normalVolumeTypes_[globalRegionI] = globalVolumeTypes[surfI];
503 if (globalPatchInfo.set(surfI))
508 globalPatchInfo[surfI].clone()
515 label globalRegionI = regionOffset_[surfI] + iter.key();
517 normalVolumeTypes_[globalRegionI] =
518 regionVolumeTypes[surfI][iter.key()];
521 const Map<autoPtr<dictionary>>& localInfo = regionPatchInfo[surfI];
524 label globalRegionI = regionOffset_[surfI] + iter.key();
526 patchInfo_.set(globalRegionI, iter()().clone());
532 if (!additionalFeaturesDict.empty())
534 Info<<
nl <<
"Reading additionalFeatures" <<
endl;
539 word featureName = iter().keyword();
543 const dictionary& featureSubDict
545 additionalFeaturesDict.subDict(featureName)
548 readFeatures(featureSubDict, featureName, featureI);
552 features_.setSize(featureI);
554 globalBounds_ = treeBoundBox
561 vector newSpan = 1
e-4*globalBounds_.span();
562 globalBounds_.min() -= newSpan;
563 globalBounds_.max() += newSpan;
569 referenceVolumeTypes_.setSize
576 <<
"Testing for locationInMesh " << locationInMesh_ <<
endl;
578 hasBoundedVolume(referenceVolumeTypes_);
582 Info<<
"Names = " << allGeometry_.names() <<
endl;
583 Info<<
"Surfaces = " << surfaces_ <<
endl;
584 Info<<
"AllGeom to Surfaces = " << allGeometryToSurfaces_ <<
endl;
585 Info<<
"Volume types = " << normalVolumeTypes_ <<
endl;
586 Info<<
"Patch names = " << patchNames_ <<
endl;
587 Info<<
"Region Offset = " << regionOffset_ <<
endl;
591 Info<< features_[fI].name() <<
endl;
609 if (allGeometry_[surfaces_[
s]].overlaps(bb))
624 return wellInside(samplePts,
scalarField(samplePts.size(), 0.0));
630 const point& samplePt
642 return wellOutside(samplePts,
scalarField(samplePts.size(), 0.0));
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]]);
733 !surface.hasVolumeType()
739 List<pointIndexHit> info;
741 surface.findNearest(sample, nearestDistSqr, info);
743 vector hitDir = info[0].rawPoint() - samplePts[i];
744 hitDir /=
mag(hitDir) + small;
749 findSurfaceNearestIntersection
752 info[0].rawPoint() - 1
e-3*
mag(hitDir)*hitDir,
757 if (surfHit.hit() && hitSurface != surfaces_[
s])
767 normalVolumeTypes_[regionI]
771 insideOutsidePoint[i] = !testForInside;
779 normalVolumeTypes_[regionI]
783 insideOutsidePoint[i] = !testForInside;
790 return insideOutsidePoint;
800 return wellInOutSide(samplePts, testDistSqr,
true);
806 const point& samplePt,
820 return wellInOutSide(samplePts, testDistSqr,
false);
826 const point& samplePt,
841 List<pointIndexHit> hitInfo;
853 return hitInfo[0].hit();
866 List<pointIndexHit> hitInfo;
878 surfHit = hitInfo[0];
886 hitSurface = surfaces_[hitSurfaces[0]];
895 List<pointIndexHit>& surfHit,
900 List<List<pointIndexHit>> hitInfo;
912 surfHit = hitInfo[0];
914 hitSurface.setSize(hitSurfaces[0].size());
916 forAll(hitSurfaces[0], surfI)
922 hitSurface[surfI] = surfaces_[hitSurfaces[0][surfI]];
936 List<pointIndexHit> hitInfoStart;
938 List<pointIndexHit> hitInfoEnd;
952 surfHit = hitInfoStart[0];
960 hitSurface = surfaces_[hitSurfacesStart[0]];
968 scalar nearestDistSqr,
974 List<pointIndexHit> surfaceHits;
986 surfHit = surfaceHits[0];
994 hitSurface = surfaces_[hitSurfaces[0]];
1003 List<pointIndexHit>& surfaceHits,
1019 if (surfaceHits[i].hit())
1025 hitSurfaces[i] = surfaces_[hitSurfaces[i]];
1033 const point& sample,
1034 scalar nearestDistSqr,
1040 scalar minDistSqr = nearestDistSqr;
1045 features_[testI].nearestFeaturePoint
1054 minDistSqr =
magSqr(hitInfo.hitPoint()- sample);
1064 const point& sample,
1065 scalar nearestDistSqr,
1073 List<pointIndexHit> edgeHits;
1084 edgeHit = edgeHits[0];
1085 featureHit = featuresHit[0];
1093 List<pointIndexHit>& edgeHits,
1098 featuresHit.setSize(samples.size());
1100 edgeHits.setSize(samples.size());
1104 List<pointIndexHit> hitInfo(samples.size());
1108 features_[testI].nearestFeatureEdge
1118 if (hitInfo[pointi].hit())
1120 minDistSqr[pointi] =
magSqr 1122 hitInfo[pointi].hitPoint()
1125 edgeHits[pointi] = hitInfo[pointi];
1126 featuresHit[pointi] = testI;
1135 const point& sample,
1136 scalar nearestDistSqr,
1137 List<pointIndexHit>& edgeHits,
1138 List<label>& featuresHit
1152 features_[testI].nearestFeatureEdgeByType
1162 if (hitInfo[typeI].hit())
1164 minDistSqr[typeI] =
magSqr(hitInfo[typeI].hitPoint() - sample);
1165 edgeHits[typeI] = hitInfo[typeI];
1166 featuresHit[typeI] = testI;
1175 const point& sample,
1176 const scalar searchRadiusSqr,
1177 List<List<pointIndexHit>>& edgeHitsByFeature,
1178 List<label>& featuresHit
1191 features_[testI].allNearestFeatureEdges
1198 bool anyHit =
false;
1201 if (hitInfo[hitI].hit())
1209 edgeHitsByFeature.append(hitInfo);
1210 featuresHit.append(testI);
1218 OFstream ftStr(runTime_.time().path()/prefix +
"_allFeatures.obj");
1220 Pout<<
nl <<
"Writing all features to " << ftStr.name() <<
endl;
1226 const extendedFeatureEdgeMesh& fEM(features_[i]);
1230 ftStr <<
"g " << fEM.name() <<
endl;
1234 const edge&
e = eds[j];
1238 ftStr <<
"l " << verti-1 <<
' ' << verti <<
endl;
1253 findSurfaceAnyIntersection(ptA, ptB, surfHit, hitSurface);
1255 return getPatchID(hitSurface, surfHit);
1264 findSurfaceNearest(pt,
sqr(great), surfHit, hitSurface);
1266 return getPatchID(hitSurface, surfHit);
1272 const label hitSurface,
1283 allGeometry_[hitSurface].getRegion
1285 List<pointIndexHit>(1, surfHit),
1289 const label patchID =
1291 + regionOffset_[allGeometryToSurfaces_[hitSurface]];
1300 const label hitSurface,
1304 const label patchID = getPatchID(hitSurface, surfHit);
1311 return normalVolumeTypes_[patchID];
1317 const label hitSurface,
1318 const List<pointIndexHit>& surfHit,
1322 allGeometry_[hitSurface].getNormal(surfHit, normal);
1324 const label patchID = regionOffset_[allGeometryToSurfaces_[hitSurface]];
List< labelList > labelListList
A List of labelList.
#define forAll(list, i)
Loop across all elements in list.
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
errorManipArg< error, int > exit(error &err, const int errNo=1)
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
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)
static const Foam::NamedEnum< sideVolumeType, 4 > sideVolumeTypeNames_
Ostream & endl(Ostream &os)
Add newline and flush stream.
PointIndexHit< point > pointIndexHit
Vector< scalar > vector
A scalar version of the templated Vector.
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.
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &df)
scalarField samples(nIntervals, 0)
gmvFile<< "tracers "<< particles.size()<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().x()<< " ";}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().y()<< " ";}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().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))
vectorField pointField
pointField is a vectorField.
stressControl lookup("compactNormalStress") >> compactNormalStress
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 label nEdgeTypes
Number of possible feature edge types (i.e. number of slices)
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
void append(const T &)
Append an element at the end of the list.
sideVolumeType
Normals point to the outside.
List< label > labelList
A List of labels.
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.
forAllConstIter(PtrDictionary< phaseModel >, mixture.phases(), phase)
dimensioned< scalar > magSqr(const dimensioned< Type > &)
defineTypeNameAndDebug(combustionModel, 0)
List< word > wordList
A List of words.
vector point
Point is a vector.
#define WarningInFunction
Report a warning using Foam::Warning.
prefixOSstream Pout(cout, "Pout")
dimensioned< scalar > mag(const dimensioned< Type > &)
Field< vector > vectorField
Specialisation of Field<T> for vector.
#define IOWarningInFunction(ios)
Report an IO warning using Foam::Warning.
const doubleScalar e
Elementary charge.
static const NamedEnum< volumeType, 4 > names
static boundBox bounds(const PtrList< searchableSurface > &allSurfaces, const labelList &surfacesToTest)
Find the boundBox of the selected surfaces.