diff --git a/src/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.C b/src/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.C index f03249f78a..343118e073 100644 --- a/src/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.C +++ b/src/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.C @@ -28,6 +28,7 @@ License #include "initialPointsMethod.H" #include "uint.H" #include "ulong.H" +#include "surfaceFeatures.H" // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // @@ -72,7 +73,7 @@ bool Foam::conformalVoronoiMesh::dualCellSurfaceIntersection } // Check for the edge passing through a surface - if (geometryToConformTo_.findAnyIntersection(dE0, dE1)) + if (geometryToConformTo_.findSurfaceAnyIntersection(dE0, dE1)) { return true; } @@ -132,7 +133,7 @@ void Foam::conformalVoronoiMesh::calcDualMesh ) ); - scalar minEdgeLenSqr = Foam::sqr(defaultCellSize*minimumEdgeLengthCoeff); + scalar minEdgeLenSqr = sqr(defaultCellSize*minimumEdgeLengthCoeff); // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -774,7 +775,7 @@ Foam::conformalVoronoiMesh::conformalVoronoiMesh { timeCheck(); - insertFeaturePoints(); + conformToFeaturePoints(); timeCheck(); insertInitialPoints(); @@ -846,9 +847,11 @@ void Foam::conformalVoronoiMesh::insertSurfacePointPairs } -void Foam::conformalVoronoiMesh::insertFeaturePoints() +void Foam::conformalVoronoiMesh::conformToFeaturePoints() { - Info<< nl << "Inserting feature points" << endl; + Info<< nl << "Conforming to feature points" << endl; + + Info<< " Conforming to " << "XXX" << " feature locations" << nl << " Inserting " << "YYY" << " points" << endl; @@ -942,7 +945,11 @@ void Foam::conformalVoronoiMesh::conformToSurface() // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - for(label iterationNo = 0; iterationNo < 1; iterationNo++) + // Surface protrusion conformation + + label nIterations = 1; + + for(label iterationNo = 0; iterationNo < nIterations; iterationNo++) { DynamicList surfacePpDist; DynamicList surfacePoints; @@ -963,14 +970,11 @@ void Foam::conformalVoronoiMesh::conformToSurface() // TODO Need to have a function to recover the local cell size, // use the defaultCellSize for the moment - scalar searchDistanceSqr = Foam::sqr - ( - defaultCellSize*surfDepthCoeff - ); + scalar searchDistanceSqr = sqr(defaultCellSize*surfDepthCoeff); pointIndexHit pHit; vector normal; - geometryToConformTo_.findNearestAndNormal + geometryToConformTo_.findSurfaceNearestAndNormal ( vert, searchDistanceSqr, @@ -984,6 +988,10 @@ void Foam::conformalVoronoiMesh::conformToSurface() if (dualCellSurfaceIntersection(vit)) { + // If the point is within a given distance of a feature + // edge, shift it to being an edge control point + // instead, this will prevent "pits" forming. + surfacePpDist.append(defaultCellSize*ppDistCoeff); surfacePoints.append(pHit.hitPoint()); surfaceNormals.append(normal); @@ -992,9 +1000,9 @@ void Foam::conformalVoronoiMesh::conformToSurface() } } - Info<< nl < edgeGenerationPoints; + + for + ( + Triangulation::Finite_vertices_iterator vit = + finite_vertices_begin(); + vit != finite_vertices_end(); + vit++ + ) + { + if (vit->nearBoundary()) + { + if (dualCellSurfaceIntersection(vit)) + { + // Test to see if near to an edge, conform to the nearest + // point on that edge if so. + + edgeGenerationPoints.append(topoint(vit->point())); + } + } + } + + writePoints + ( + "edgeGenerationLocations_" + name(iterationNo) + ".obj", + edgeGenerationPoints + ); + } } diff --git a/src/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.H b/src/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.H index 571e1d0e61..4b054837a5 100644 --- a/src/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.H +++ b/src/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.H @@ -94,7 +94,7 @@ class conformalVoronoiMesh //- Store the feature constraining points to be reinserted after a //- triangulation clear - List featureConstrainingVertices_; + List featureVertices_; //- Method for inserting initial points. Runtime selectable. autoPtr initialPointsMethod_; @@ -134,7 +134,7 @@ class conformalVoronoiMesh ); //- Insert point groups at the feature points. - void insertFeaturePoints(); + void conformToFeaturePoints(); //- Reinsert stored feature point defining points. void reinsertFeaturePoints(); diff --git a/src/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshIO.C b/src/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshIO.C index ea741b1d63..cd768021a2 100644 --- a/src/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshIO.C +++ b/src/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshIO.C @@ -107,7 +107,6 @@ void Foam::conformalVoronoiMesh::writeMesh() Info<< nl << "Writing polyMesh to constant." << endl; - polyMesh pMesh ( io, diff --git a/src/conformalVoronoiMesh/conformalVoronoiMesh/indexedVertex.H b/src/conformalVoronoiMesh/conformalVoronoiMesh/indexedVertex.H index 310a3044f7..e932f2b2a2 100644 --- a/src/conformalVoronoiMesh/conformalVoronoiMesh/indexedVertex.H +++ b/src/conformalVoronoiMesh/conformalVoronoiMesh/indexedVertex.H @@ -191,6 +191,12 @@ public: return type_ <= INTERNAL_POINT; } + //- Set the point to be internal + inline void setInternal() + { + type_ = INTERNAL_POINT; + } + //- Is point internal and near the boundary inline bool nearBoundary() const { diff --git a/src/conformalVoronoiMesh/conformationSurfaces/conformationSurfaces.C b/src/conformalVoronoiMesh/conformationSurfaces/conformationSurfaces.C index abde13e3f1..b5f6601d4e 100644 --- a/src/conformalVoronoiMesh/conformationSurfaces/conformationSurfaces.C +++ b/src/conformalVoronoiMesh/conformationSurfaces/conformationSurfaces.C @@ -38,22 +38,10 @@ Foam::conformationSurfaces::conformationSurfaces : cvMesh_(cvMesh), allGeometry_(allGeometry), - features_ - ( - IOobject - ( - "features", - cvMesh_.time().constant(), - "featureEdgeMesh", - cvMesh_.time(), - IOobject::NO_READ, - IOobject::NO_WRITE - ), - pointField(0), - edgeList(0) - ), + features_(), locationInMesh_(surfaceConformationDict.lookup("locationInMesh")), - surfaces_(0), + surfaces_(), + baffleSurfaces_(), bounds_() { const dictionary& surfacesDict @@ -61,13 +49,21 @@ Foam::conformationSurfaces::conformationSurfaces surfaceConformationDict.subDict("geometryToConformTo") ); + Info<< nl << "Reading geometryToConformTo." << endl; + surfaces_.setSize(surfacesDict.size()); + baffleSurfaces_.setSize(surfacesDict.size()); + + features_.setSize(surfacesDict.size()); + label surfI = 0; forAllConstIter(dictionary, surfacesDict, iter) { - surfaces_[surfI] = allGeometry_.findSurfaceID(iter().keyword()); + word surfaceName = iter().keyword(); + + surfaces_[surfI] = allGeometry_.findSurfaceID(surfaceName); if (surfaces_[surfI] < 0) { @@ -77,10 +73,87 @@ Foam::conformationSurfaces::conformationSurfaces << exit(FatalError); } + const dictionary& surfaceSubDict(surfacesDict.subDict(surfaceName)); + + baffleSurfaces_[surfI] = Switch + ( + surfaceSubDict.lookupOrDefault("baffleSurface", false) + ); + + word featureMethod = surfaceSubDict.lookupOrDefault + ( + "featureMethod", + word("none") + ); + + if (featureMethod == "featureEdgeMesh") + { + fileName feMeshName(surfaceSubDict.lookup("featureEdgeMesh")); + + features_.set + ( + surfI, + new featureEdgeMesh + ( + IOobject + ( + feMeshName, + cvMesh_.time().findInstance + ( + "featureEdgeMesh", feMeshName + ), + "featureEdgeMesh", + cvMesh_.time(), + IOobject::MUST_READ, + IOobject::NO_WRITE + ) + ) + ); + } + else if (featureMethod == "extractFeatures") + { + notImplemented + ( + "conformationSurfaces::conformationSurfaces, " + "else if (featureMethod == \"extractFeatures\")" + ); + } + else if (featureMethod == "none") + { + fileName feMeshName(surfaceSubDict.lookup("featureEdgeMesh")); + + features_.set + ( + surfI, + new featureEdgeMesh + ( + IOobject + ( + feMeshName, + cvMesh_.time().constant(), + "featureEdgeMesh", + cvMesh_.time(), + IOobject::NO_READ, + IOobject::NO_WRITE, + false + ) + ) + ); + } + else + { + FatalErrorIn("Foam::conformationSurfaces::conformationSurfaces") + << "No valid featureMethod found for surface " << surfaceName + << nl << "Use \"featureEdgeMesh\" or \"extractFeatures\"." + << exit(FatalError); + } + surfI++; } bounds_ = searchableSurfacesQueries::bounds(allGeometry_, surfaces_); + + writeFeatureObj("cvMesh"); } @@ -233,7 +306,7 @@ Foam::Field Foam::conformationSurfaces::wellOutside } -bool Foam::conformationSurfaces::findAnyIntersection +bool Foam::conformationSurfaces::findSurfaceAnyIntersection ( point start, point end @@ -256,7 +329,7 @@ bool Foam::conformationSurfaces::findAnyIntersection } -void Foam::conformationSurfaces::findNearestAndNormal +void Foam::conformationSurfaces::findSurfaceNearestAndNormal ( const point& sample, scalar nearestDistSqr, @@ -294,4 +367,150 @@ void Foam::conformationSurfaces::findNearestAndNormal } +void Foam::conformationSurfaces::findSurfaceNearestAndNormal +( + const pointField& samples, + scalarField nearestDistSqr, + List& hitInfo, + vectorField& normals +) const +{ + labelList hitSurfaces; + + searchableSurfacesQueries::findNearest + ( + allGeometry_, + surfaces_, + samples, + nearestDistSqr, + hitSurfaces, + hitInfo + ); + + forAll(hitInfo, i) + { + const pointIndexHit& pHit(hitInfo[i]); + + if (pHit.hit()) + { + // hitSurfaces has returned the index of the entry in surfaces_ that + // was found, not the index of the surface in allGeometry_, + // translating this to the surface in allGeometry_ for the normal + // lookup. + + hitSurfaces[i] = surfaces_[hitSurfaces[i]]; + + vectorField norm(1); + + allGeometry_[hitSurfaces[i]].getNormal + ( + List(1, pHit), + norm + ); + + normals[i] = norm[0]; + } + } +} + + +void Foam::conformationSurfaces::findEdgeNearest +( + const pointField& samples, + const scalarField& nearestDistSqr +) const +{ + + labelList nearestSurfaces; + List nearestInfo; + + // Initialise + nearestSurfaces.setSize(samples.size()); + nearestSurfaces = -1; + nearestInfo.setSize(samples.size()); + + // Work arrays + scalarField minDistSqr(nearestDistSqr); + List hitInfo(samples.size()); + + forAll(features_, testI) + { + features_[testI].nearestFeatureEdge + ( + samples, + minDistSqr, + hitInfo + ); + + // Update minDistSqr and arguments + forAll(hitInfo, pointI) + { + if (hitInfo[pointI].hit()) + { + minDistSqr[pointI] = magSqr + ( + hitInfo[pointI].hitPoint() + - samples[pointI] + ); + nearestInfo[pointI] = hitInfo[pointI]; + nearestSurfaces[pointI] = testI; + } + } + } + + OFstream edgeNearestStr("testFindEdgeNearest.obj"); + Pout<< "Writing edge nearest points to " << edgeNearestStr.name() << endl; + + forAll(nearestInfo, i) + { + if (nearestInfo[i].hit()) + { + meshTools::writeOBJ(edgeNearestStr, nearestInfo[i].hitPoint()); + } + } + + // labelList& edgeLabel; + // pointField& edgePoint; + // List& adjacentNormals; + + // edgeLabel.setSize(samples.size()); + // edgePoint.setSize(samples.size()); + // adjacentNormals.setSize(samples.size()); + + // edgeLabel[i] = pHit.index(); + // edgePoint[i] = pHit.hitPoint(); + // adjacentNormals[i] = edgeNormals(edgeLabel[i]); +} + + +void Foam::conformationSurfaces::writeFeatureObj +( + const fileName& prefix +) const +{ + OFstream ftStr(prefix + "_allFeatures.obj"); + Pout<< nl << "Writing all features to " << ftStr.name() << endl; + + label verti = 0; + + forAll(features_, i) + { + const featureEdgeMesh& fEM(features_[i]); + const pointField pts(fEM.points()); + const edgeList eds(fEM.edges()); + + ftStr << "g " << fEM.name() << endl; + + forAll(eds, j) + { + const edge& e = eds[j]; + + meshTools::writeOBJ(ftStr, pts[e[0]]); verti++; + meshTools::writeOBJ(ftStr, pts[e[1]]); verti++; + ftStr << "l " << verti-1 << ' ' << verti << endl; + } + } +} + + // ************************************************************************* // diff --git a/src/conformalVoronoiMesh/conformationSurfaces/conformationSurfaces.H b/src/conformalVoronoiMesh/conformationSurfaces/conformationSurfaces.H index 1ec6734fd9..f6d9c3f245 100644 --- a/src/conformalVoronoiMesh/conformationSurfaces/conformationSurfaces.H +++ b/src/conformalVoronoiMesh/conformationSurfaces/conformationSurfaces.H @@ -65,8 +65,8 @@ class conformationSurfaces //- Reference to the searchableSurfaces object holding all geometry data const searchableSurfaces& allGeometry_; - //- Feature Edges and points - featureEdgeMesh features_; + //- A list of featureEdge meshes + PtrList features_; //- The location in the mesh that specifies which portion of surfaces is // to be meshed. @@ -75,6 +75,10 @@ class conformationSurfaces //- Indices of surfaces in allGeometry that are to be conformed to labelList surfaces_; + //- A boolean value for each surface to be conformed to specifying if it + // is to be treated as a baffle + boolList baffleSurfaces_; + //- The overall boundBox of all of the surfaces to be conformed to boundBox bounds_; @@ -113,6 +117,9 @@ public: // of the geometry inline const searchableSurfaces& geometry() const; + //- Return the object holding the feature points and edges + inline const PtrList& features() const; + //- Return the surface indices inline const labelList& surfaces() const; @@ -145,11 +152,11 @@ public: ) const; // Finding if the line joining start and end intersects the surface - bool findAnyIntersection(point start, point end) const; + bool findSurfaceAnyIntersection(point start, point end) const; //- Find the nearest point to the sample and return it to the // pointIndexHit, and the normal at the hit location, if found. - void findNearestAndNormal + void findSurfaceNearestAndNormal ( const point& sample, scalar nearestDistSqr, @@ -157,8 +164,25 @@ public: vector& normal ) const; + void findSurfaceNearestAndNormal + ( + const pointField& sample, + scalarField nearestDistSqr, + List& pHit, + vectorField& normal + ) const; - // Member Operators + //- Find the nearest point on any feature edge + void findEdgeNearest + ( + const pointField& samples, + const scalarField& nearestDistSqr + ) const; + + // Write + + //- Write all components of all the featureEdgeMeshes as an obj file + void writeFeatureObj(const fileName& prefix) const; }; diff --git a/src/conformalVoronoiMesh/conformationSurfaces/conformationSurfacesI.H b/src/conformalVoronoiMesh/conformationSurfaces/conformationSurfacesI.H index 0b2538aa42..d713c480a2 100644 --- a/src/conformalVoronoiMesh/conformationSurfaces/conformationSurfacesI.H +++ b/src/conformalVoronoiMesh/conformationSurfaces/conformationSurfacesI.H @@ -26,7 +26,7 @@ License // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // -// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // const Foam::searchableSurfaces& Foam::conformationSurfaces::geometry() const { @@ -34,6 +34,13 @@ const Foam::searchableSurfaces& Foam::conformationSurfaces::geometry() const } +const Foam::PtrList& +Foam::conformationSurfaces::features() const +{ + return features_; +} + + const Foam::labelList& Foam::conformationSurfaces::surfaces() const { return surfaces_;