diff --git a/applications/utilities/mesh/generation/Allwmake b/applications/utilities/mesh/generation/Allwmake index ef28f9aaf581f6d71d65e0f6b2a0085c1768c307..48ca530c96933f6c31bf4f126658efc9f607fd51 100755 --- a/applications/utilities/mesh/generation/Allwmake +++ b/applications/utilities/mesh/generation/Allwmake @@ -4,12 +4,15 @@ set -x wmake blockMesh wmake all extrude -wmake extrude2DMesh + +extrude2DMesh/Allwmake + wmake snappyHexMesh if [ -d "$CGAL_ARCH_PATH" ] then - cd cvMesh && ./Allwmake + cvMesh/Allwmake + cv2DMesh/Allwmake fi # ----------------------------------------------------------------- end-of-file diff --git a/applications/utilities/mesh/generation/cv2DMesh/Allwclean b/applications/utilities/mesh/generation/cv2DMesh/Allwclean new file mode 100755 index 0000000000000000000000000000000000000000..d0ae53e41503d0ccd189b47c40f83dc193030e03 --- /dev/null +++ b/applications/utilities/mesh/generation/cv2DMesh/Allwclean @@ -0,0 +1,8 @@ +#!/bin/sh +cd ${0%/*} || exit 1 # run from this directory +set -x + +wclean libso conformalVoronoi2DMesh +wclean + +# ----------------------------------------------------------------- end-of-file diff --git a/applications/utilities/mesh/generation/cv2DMesh/Allwmake b/applications/utilities/mesh/generation/cv2DMesh/Allwmake new file mode 100755 index 0000000000000000000000000000000000000000..54868499573cf6b3ce989a211b0fd1be7944c490 --- /dev/null +++ b/applications/utilities/mesh/generation/cv2DMesh/Allwmake @@ -0,0 +1,8 @@ +#!/bin/sh +cd ${0%/*} || exit 1 # run from this directory +set -x + +wmake libso conformalVoronoi2DMesh +wmake + +# ----------------------------------------------------------------- end-of-file diff --git a/applications/utilities/mesh/generation/cv2DMesh/CGALTriangulation2Ddefs.H b/applications/utilities/mesh/generation/cv2DMesh/CGALTriangulation2Ddefs.H new file mode 100644 index 0000000000000000000000000000000000000000..1485226d98ce2814ee8862864582744a73675930 --- /dev/null +++ b/applications/utilities/mesh/generation/cv2DMesh/CGALTriangulation2Ddefs.H @@ -0,0 +1,82 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2007-2011 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Typedefs + CGALTriangulation2Ddefs + +Description + CGAL data structures used for 2D Delaunay meshing. + + Define CGAL_INEXACT to use Exact_predicates_inexact_constructions kernel + otherwise the more robust but much less efficient + Exact_predicates_exact_constructions will be used. + + Define CGAL_HIERARCHY to use hierarchical Delaunay triangulation which is + faster but uses more memory than the standard Delaunay triangulation. + +\*---------------------------------------------------------------------------*/ + +#ifndef CGALTriangulation2Ddefs_H +#define CGALTriangulation2Ddefs_H + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#include "CGAL/Delaunay_triangulation_2.h" + +#include "indexedVertex.H" +#include "indexedFace.H" + +#ifdef CGAL_INEXACT + // Fast kernel using a double as the storage type but the triangulation + // may fail + #include "CGAL/Exact_predicates_inexact_constructions_kernel.h" + typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +#else + // Very robust but expensive kernel + #include "CGAL/Exact_predicates_exact_constructions_kernel.h" + typedef CGAL::Exact_predicates_exact_constructions_kernel K; +#endif + +typedef CGAL::indexedVertex<K> Vb; +typedef CGAL::indexedFace<K> Fb; + +#ifdef CGAL_HIERARCHY + // Data structures for hierarchical Delaunay triangulation which is more + // efficient but also uses more storage + #include "CGAL/Triangulation_hierarchy_2.h" + typedef CGAL::Triangulation_hierarchy_vertex_base_2<Vb> Vbh; + typedef CGAL::Triangulation_data_structure_2<Vbh, Fb> Tds; + typedef CGAL::Delaunay_triangulation_2<K, Tds> DT; + typedef CGAL::Triangulation_hierarchy_2<DT> Delaunay; +#else + // Data structures for standard Delaunay triangulation + typedef CGAL::Triangulation_data_structure_2<Vb, Fb> Tds; + typedef CGAL::Delaunay_triangulation_2<K, Tds> Delaunay; +#endif + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/applications/utilities/mesh/generation/cv2DMesh/CV2D.C b/applications/utilities/mesh/generation/cv2DMesh/CV2D.C new file mode 100644 index 0000000000000000000000000000000000000000..aa45a88b3e9fd47319a5332a0899d28492a0a943 --- /dev/null +++ b/applications/utilities/mesh/generation/cv2DMesh/CV2D.C @@ -0,0 +1,1050 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2007-2011 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*----------------------------------------------------------------------------*/ + +#include "CV2D.H" +#include "Random.H" +#include "transform.H" +#include "IFstream.H" +#include "uint.H" +#include "ulong.H" + +namespace Foam +{ + +defineTypeNameAndDebug(CV2D, 0); + +} + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +void Foam::CV2D::insertBoundingBox() +{ + Info<< "insertBoundingBox: creating bounding mesh" << endl; + scalar bigSpan = 10*meshControls().span(); + insertPoint(point2D(-bigSpan, -bigSpan), Vb::FAR_POINT); + insertPoint(point2D(-bigSpan, bigSpan), Vb::FAR_POINT); + insertPoint(point2D(bigSpan, -bigSpan), Vb::FAR_POINT); + insertPoint(point2D(bigSpan, bigSpan), Vb::FAR_POINT); +} + + +void Foam::CV2D::fast_restore_Delaunay(Vertex_handle vh) +{ + int i; + Face_handle f = vh->face(), next, start(f); + + do + { + i=f->index(vh); + if (!is_infinite(f)) + { + if (!internal_flip(f, cw(i))) external_flip(f, i); + if (f->neighbor(i) == start) start = f; + } + f = f->neighbor(cw(i)); + } while (f != start); +} + +void Foam::CV2D::external_flip(Face_handle& f, int i) +{ + Face_handle n = f->neighbor(i); + + if + ( + CGAL::ON_POSITIVE_SIDE + != side_of_oriented_circle(n, f->vertex(i)->point()) + ) return; + + flip(f, i); + i = n->index(f->vertex(i)); + external_flip(n, i); +} + +bool Foam::CV2D::internal_flip(Face_handle& f, int i) +{ + Face_handle n = f->neighbor(i); + + if + ( + CGAL::ON_POSITIVE_SIDE + != side_of_oriented_circle(n, f->vertex(i)->point()) + ) + { + return false; + } + + flip(f, i); + + return true; +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::CV2D::CV2D +( + const Time& runTime, + const dictionary& cvMeshDict +) +: + Delaunay(), + runTime_(runTime), + rndGen_(64293*Pstream::myProcNo()), + allGeometry_ + ( + IOobject + ( + "cvSearchableSurfaces", + runTime_.constant(), + "triSurface", + runTime_, + IOobject::MUST_READ, + IOobject::NO_WRITE + ), + cvMeshDict.subDict("geometry") + ), + qSurf_ + ( + runTime_, + rndGen_, + allGeometry_, + cvMeshDict.subDict("surfaceConformation") + ), + controls_(cvMeshDict, qSurf_.globalBounds()), + cellSizeControl_ + ( + allGeometry_, + cvMeshDict.subDict("motionControl") + ), + z_ + ( + point + ( + cvMeshDict.subDict("surfaceConformation").lookup("locationInMesh") + ).z() + ), + startOfInternalPoints_(0), + startOfSurfacePointPairs_(0), + startOfBoundaryConformPointPairs_(0), + featurePoints_() +{ + Info<< meshControls() << endl; + + insertBoundingBox(); + insertFeaturePoints(); +} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::CV2D::~CV2D() +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +void Foam::CV2D::insertPoints +( + const point2DField& points, + const scalar nearness +) +{ + Info<< "insertInitialPoints(const point2DField& points): "; + + startOfInternalPoints_ = number_of_vertices(); + label nVert = startOfInternalPoints_; + + // Add the points and index them + forAll(points, i) + { + const point2D& p = points[i]; + + if (qSurf_.wellInside(toPoint3D(p), nearness)) + { + insert(toPoint(p))->index() = nVert++; + } + else + { + Warning + << "Rejecting point " << p << " outside surface" << endl; + } + } + + Info<< nVert << " vertices inserted" << endl; + + if (meshControls().objOutput()) + { + // Checking validity of triangulation + assert(is_valid()); + + writeTriangles("initial_triangles.obj", true); + writeFaces("initial_faces.obj", true); + } +} + + +void Foam::CV2D::insertPoints(const fileName& pointFileName) +{ + IFstream pointsFile(pointFileName); + + if (pointsFile.good()) + { + insertPoints + ( + point2DField(pointsFile), + 0.5*meshControls().minCellSize2() + ); + } + else + { + FatalErrorIn("insertInitialPoints") + << "Could not open pointsFile " << pointFileName + << exit(FatalError); + } +} + + +void Foam::CV2D::insertGrid() +{ + Info<< "insertInitialGrid: "; + + startOfInternalPoints_ = number_of_vertices(); + label nVert = startOfInternalPoints_; + + scalar x0 = qSurf_.globalBounds().min().x(); + scalar xR = qSurf_.globalBounds().max().x() - x0; + int ni = int(xR/meshControls().minCellSize()) + 1; + scalar deltax = xR/ni; + + scalar y0 = qSurf_.globalBounds().min().y(); + scalar yR = qSurf_.globalBounds().max().y() - y0; + int nj = int(yR/meshControls().minCellSize()) + 1; + scalar deltay = yR/nj; + + Random rndGen(1321); + scalar pert = meshControls().randomPerturbation()*min(deltax, deltay); + + for (int i=0; i<ni; i++) + { + for (int j=0; j<nj; j++) + { + point p(x0 + i*deltax, y0 + j*deltay, 0); + + if (meshControls().randomiseInitialGrid()) + { + p.x() += pert*(rndGen.scalar01() - 0.5); + p.y() += pert*(rndGen.scalar01() - 0.5); + } + + if (qSurf_.wellInside(p, 0.5*meshControls().minCellSize2())) + { + insert(Point(p.x(), p.y()))->index() = nVert++; + } + } + } + + Info<< nVert << " vertices inserted" << endl; + + if (meshControls().objOutput()) + { + // Checking validity of triangulation + assert(is_valid()); + + writeTriangles("initial_triangles.obj", true); + writeFaces("initial_faces.obj", true); + } +} + + +void Foam::CV2D::insertSurfacePointPairs() +{ + startOfSurfacePointPairs_ = number_of_vertices(); + + if (meshControls().insertSurfaceNearestPointPairs()) + { + insertSurfaceNearestPointPairs(); + } + + write("nearest"); + + // Insertion of point-pairs for near-points may cause protrusions + // so insertBoundaryConformPointPairs must be executed last + if (meshControls().insertSurfaceNearPointPairs()) + { + insertSurfaceNearPointPairs(); + } + + startOfBoundaryConformPointPairs_ = number_of_vertices(); +} + + +void Foam::CV2D::boundaryConform() +{ + if (!meshControls().insertSurfaceNearestPointPairs()) + { + markNearBoundaryPoints(); + } + + // Mark all the faces as SAVE_CHANGED + for + ( + Triangulation::Finite_faces_iterator fit = finite_faces_begin(); + fit != finite_faces_end(); + fit++ + ) + { + fit->faceIndex() = Fb::SAVE_CHANGED; + } + + for (label iter=1; iter<=meshControls().maxBoundaryConformingIter(); iter++) + { + label nIntersections = insertBoundaryConformPointPairs + ( + "surfaceIntersections_" + Foam::name(iter) + ".obj" + ); + + if (nIntersections == 0) + { + break; + } + else + { + Info<< "BC iteration " << iter << ": " + << nIntersections << " point-pairs inserted" << endl; + } + + // Any faces changed by insertBoundaryConformPointPairs will now + // be marked CHANGED, mark those as SAVE_CHANGED and those that + // remained SAVE_CHANGED as UNCHANGED + for + ( + Triangulation::Finite_faces_iterator fit = finite_faces_begin(); + fit != finite_faces_end(); + fit++ + ) + { + if (fit->faceIndex() == Fb::SAVE_CHANGED) + { + fit->faceIndex() = Fb::UNCHANGED; + } + else if (fit->faceIndex() == Fb::CHANGED) + { + fit->faceIndex() = Fb::SAVE_CHANGED; + } + } + } + + Info<< nl; + + write("boundary"); +} + + +void Foam::CV2D::removeSurfacePointPairs() +{ + for + ( + Triangulation::Finite_vertices_iterator vit = finite_vertices_begin(); + vit != finite_vertices_end(); + ++vit + ) + { + if (vit->index() >= startOfSurfacePointPairs_) + { + remove(vit); + } + } +} + + +void Foam::CV2D::newPoints(const scalar relaxation) +{ + Info<< "newPointsFromVertices: "; + + Field<point2D> dualVertices(number_of_faces()); + + label dualVerti = 0; + + // Find the dual point of each tetrahedron and assign it an index. + for + ( + Triangulation::Finite_faces_iterator fit = finite_faces_begin(); + fit != finite_faces_end(); + ++fit + ) + { + fit->faceIndex() = -1; + + if + ( + fit->vertex(0)->internalOrBoundaryPoint() + || fit->vertex(1)->internalOrBoundaryPoint() + || fit->vertex(2)->internalOrBoundaryPoint() + ) + { + fit->faceIndex() = dualVerti; + + dualVertices[dualVerti] = toPoint2D(circumcenter(fit)); + + dualVerti++; + } + } + + dualVertices.setSize(dualVerti); + + Field<vector2D> displacementAccumulator + ( + startOfSurfacePointPairs_, + vector2D::zero + ); + + // Calculate target size and alignment for vertices + scalarField sizes + ( + number_of_vertices(), + meshControls().minCellSize() + ); + + Field<vector2D> alignments + ( + number_of_vertices(), + vector2D(1, 0) + ); + + for + ( + Triangulation::Finite_vertices_iterator vit = finite_vertices_begin(); + vit != finite_vertices_end(); + ++vit + ) + { + if (vit->internalOrBoundaryPoint()) + { + point2D vert = toPoint2D(vit->point()); + + // alignment and size determination + pointIndexHit pHit; + label hitSurface = -1; + + qSurf_.findSurfaceNearest + ( + toPoint3D(vert), + meshControls().span2(), + pHit, + hitSurface + ); + + if (pHit.hit()) + { + vectorField norm(1); + allGeometry_[hitSurface].getNormal + ( + List<pointIndexHit>(1, pHit), + norm + ); + + alignments[vit->index()] = toPoint2D(norm[0]); + + sizes[vit->index()] = + cellSizeControl_.cellSize(toPoint3D(vit->point())); + } + } + } + + // Info<< "Calculated alignments" << endl; + + scalar cosAlignmentAcceptanceAngle = 0.68; + + // Upper and lower edge length ratios for weight + scalar u = 1.0; + scalar l = 0.7; + + PackedBoolList pointToBeRetained(startOfSurfacePointPairs_, true); + + std::list<Point> pointsToInsert; + + for + ( + Triangulation::Finite_edges_iterator eit = finite_edges_begin(); + eit != finite_edges_end(); + eit++ + ) + { + Vertex_handle vA = eit->first->vertex(cw(eit->second)); + Vertex_handle vB = eit->first->vertex(ccw(eit->second)); + + if (!vA->internalOrBoundaryPoint() || !vB->internalOrBoundaryPoint()) + { + continue; + } + + const point2D& dualV1 = dualVertices[eit->first->faceIndex()]; + const point2D& dualV2 = + dualVertices[eit->first->neighbor(eit->second)->faceIndex()]; + + scalar dualEdgeLength = mag(dualV1 - dualV2); + + point2D dVA = toPoint2D(vA->point()); + point2D dVB = toPoint2D(vB->point()); + + Field<vector2D> alignmentDirsA(2); + + alignmentDirsA[0] = alignments[vA->index()]; + alignmentDirsA[1] = vector2D + ( + -alignmentDirsA[0].y(), + alignmentDirsA[0].x() + ); + + Field<vector2D> alignmentDirsB(2); + + alignmentDirsB[0] = alignments[vB->index()]; + alignmentDirsB[1] = vector2D + ( + -alignmentDirsB[0].y(), + alignmentDirsB[0].x() + ); + + Field<vector2D> alignmentDirs(2); + + forAll(alignmentDirsA, aA) + { + const vector2D& a(alignmentDirsA[aA]); + + scalar maxDotProduct = 0.0; + + forAll(alignmentDirsB, aB) + { + const vector2D& b(alignmentDirsB[aB]); + + scalar dotProduct = a & b; + + if (mag(dotProduct) > maxDotProduct) + { + maxDotProduct = mag(dotProduct); + + alignmentDirs[aA] = a + sign(dotProduct)*b; + + alignmentDirs[aA] /= mag(alignmentDirs[aA]); + } + } + } + + vector2D rAB = dVA - dVB; + + scalar rABMag = mag(rAB); + + forAll(alignmentDirs, aD) + { + vector2D& alignmentDir = alignmentDirs[aD]; + + if ((rAB & alignmentDir) < 0) + { + // swap the direction of the alignment so that has the + // same sense as rAB + alignmentDir *= -1; + } + + scalar alignmentDotProd = ((rAB/rABMag) & alignmentDir); + + if (alignmentDotProd > cosAlignmentAcceptanceAngle) + { + scalar targetFaceSize = + 0.5*(sizes[vA->index()] + sizes[vB->index()]); + + // Test for changing aspect ratio on second alignment (first + // alignment is neartest surface normal) + // if (aD == 1) + // { + // targetFaceSize *= 2.0; + // } + + alignmentDir *= 0.5*targetFaceSize; + + vector2D delta = alignmentDir - 0.5*rAB; + + if (dualEdgeLength < 0.7*targetFaceSize) + { + delta *= 0; + } + else if (dualEdgeLength < targetFaceSize) + { + delta *= + ( + dualEdgeLength + /(targetFaceSize*(u - l)) + - 1/((u/l) - 1) + ); + } + + if + ( + vA->internalPoint() + && vB->internalPoint() + && rABMag > 1.75*targetFaceSize + && dualEdgeLength > 0.05*targetFaceSize + && alignmentDotProd > 0.93 + ) + { + // Point insertion + pointsToInsert.push_back(toPoint(0.5*(dVA + dVB))); + } + else if + ( + (vA->internalPoint() || vB->internalPoint()) + && rABMag < 0.65*targetFaceSize + ) + { + // Point removal + + // Only insert a point at the midpoint of the short edge + // if neither attached point has already been identified + // to be removed. + if + ( + pointToBeRetained[vA->index()] == true + && pointToBeRetained[vB->index()] == true + ) + { + pointsToInsert.push_back(toPoint(0.5*(dVA + dVB))); + } + + if (vA->internalPoint()) + { + pointToBeRetained[vA->index()] = false; + } + + if (vB->internalPoint()) + { + pointToBeRetained[vB->index()] = false; + } + } + else + { + if (vA->internalPoint()) + { + displacementAccumulator[vA->index()] += delta; + } + + if (vB->internalPoint()) + { + displacementAccumulator[vB->index()] += -delta; + } + } + } + } + } + + vector2D totalDisp = sum(displacementAccumulator); + scalar totalDist = sum(mag(displacementAccumulator)); + + // Relax the calculated displacement + displacementAccumulator *= relaxation; + + label numberOfNewPoints = pointsToInsert.size(); + + for + ( + Triangulation::Finite_vertices_iterator vit = finite_vertices_begin(); + vit != finite_vertices_end(); + ++vit + ) + { + if (vit->internalPoint()) + { + if (pointToBeRetained[vit->index()]) + { + pointsToInsert.push_front + ( + toPoint + ( + toPoint2D(vit->point()) + + displacementAccumulator[vit->index()] + ) + ); + } + } + } + + // Clear the triangulation and reinsert the bounding box and feature points. + // This is faster than removing and moving points. + this->clear(); + + insertBoundingBox(); + + reinsertFeaturePoints(); + + startOfInternalPoints_ = number_of_vertices(); + + label nVert = startOfInternalPoints_; + + Info<< "Inserting " << numberOfNewPoints << " new points" << endl; + + // Use the range insert as it is faster than individually inserting points. + insert(pointsToInsert.begin(), pointsToInsert.end()); + + for + ( + Delaunay::Finite_vertices_iterator vit = finite_vertices_begin(); + vit != finite_vertices_end(); + ++vit + ) + { + if + ( + vit->type() == Vb::INTERNAL_POINT + && vit->index() == Vb::INTERNAL_POINT + ) + { + vit->index() = nVert++; + } + } + + Info<< " Total displacement = " << totalDisp << nl + << " Total distance = " << totalDist << nl + << " Points added = " << pointsToInsert.size() + << endl; + + write("internal"); + + insertSurfacePointPairs(); + + boundaryConform(); + + +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// Old Method +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +// for +// ( +// Triangulation::Finite_vertices_iterator vit = finite_vertices_begin(); +// vit != finite_vertices_end(); +// ++vit +// ) +// { +// if (vit->internalPoint()) +// { +// // Current dual-cell defining vertex ("centre") +// point2DFromPoint defVert0 = toPoint2D(vit->point()); + +// Triangulation::Edge_circulator ec = incident_edges(vit); +// Triangulation::Edge_circulator ecStart = ec; + +// // Circulate around the edges to find the first which is not +// // infinite +// do +// { +// if (!is_infinite(ec)) break; +// } while (++ec != ecStart); + +// // Store the start-end of the first non-infinte edge +// point2D de0 = toPoint2D(circumcenter(ec->first)); + +// // Keep track of the maximum edge length^2 +// scalar maxEdgeLen2 = 0.0; + +// // Keep track of the index of the longest edge +// label edgecd0i = -1; + +// // Edge counter +// label edgei = 0; + +// do +// { +// if (!is_infinite(ec)) +// { +// // Get the end of the current edge +// point2D de1 = toPoint2D +// ( +// circumcenter(ec->first->neighbor(ec->second)) +// ); + +// // Store the current edge vector +// edges[edgei] = de1 - de0; + +// // Store the edge mid-point in the vertices array +// vertices[edgei] = 0.5*(de1 + de0); + +// // Move the current edge end into the edge start for the +// // next iteration +// de0 = de1; + +// // Keep track of the longest edge + +// scalar edgeLen2 = magSqr(edges[edgei]); + +// if (edgeLen2 > maxEdgeLen2) +// { +// maxEdgeLen2 = edgeLen2; +// edgecd0i = edgei; +// } + +// edgei++; +// } +// } while (++ec != ecStart); + +// // Initialise cd0 such that the mesh will align +// // in in the x-y directions +// vector2D cd0(1, 0); + +// if (meshControls().relaxOrientation()) +// { +// // Get the longest edge from the array and use as the primary +// // direction of the coordinate system of the "square" cell +// cd0 = edges[edgecd0i]; +// } + +// if (meshControls().nearWallAlignedDist() > 0) +// { +// pointIndexHit pHit = qSurf_.tree().findNearest +// ( +// toPoint3D(defVert0), +// meshControls().nearWallAlignedDist2() +// ); + +// if (pHit.hit()) +// { +// cd0 = toPoint2D(faceNormals[pHit.index()]); +// } +// } + +// // Rotate by 45deg needed to create an averaging procedure which +// // encourages the cells to be square +// cd0 = vector2D(cd0.x() + cd0.y(), cd0.y() - cd0.x()); + +// // Normalise the primary coordinate direction +// cd0 /= mag(cd0); + +// // Calculate the orthogonal coordinate direction +// vector2D cd1(-cd0.y(), cd0.x()); + + +// // Restart the circulator +// ec = ecStart; + +// // ... and the counter +// edgei = 0; + +// // Initialise the displacement for the centre and sum-weights +// vector2D disp = vector2D::zero; +// scalar sumw = 0; + +// do +// { +// if (!is_infinite(ec)) +// { +// // Pick up the current edge +// const vector2D& ei = edges[edgei]; + +// // Calculate the centre to edge-centre vector +// vector2D deltai = vertices[edgei] - defVert0; + +// // Set the weight for this edge contribution +// scalar w = 1; + +// if (meshControls().squares()) +// { +// w = magSqr(deltai.x()*ei.y() - deltai.y()*ei.x()); +// // alternative weights +// //w = mag(deltai.x()*ei.y() - deltai.y()*ei.x()); +// //w = magSqr(ei)*mag(deltai); + +// // Use the following for an ~square mesh +// // Find the coordinate contributions for this edge delta +// scalar cd0deltai = cd0 & deltai; +// scalar cd1deltai = cd1 & deltai; + +// // Create a "square" displacement +// if (mag(cd0deltai) > mag(cd1deltai)) +// { +// disp += (w*cd0deltai)*cd0; +// } +// else +// { +// disp += (w*cd1deltai)*cd1; +// } +// } +// else +// { +// // Use this for a hexagon/pentagon mesh +// disp += w*deltai; +// } + +// // Sum the weights +// sumw += w; +// } +// else +// { +// FatalErrorIn("CV2D::newPoints() const") +// << "Infinite triangle found in internal mesh" +// << exit(FatalError); +// } + +// edgei++; + +// } while (++ec != ecStart); + +// // Calculate the average displacement +// disp /= sumw; +// totalDisp += disp; +// totalDist += mag(disp); + +// // Move the point by a fraction of the average displacement +// movePoint(vit, defVert0 + relaxation*disp); +// } +// } + +// Info << "\nTotal displacement = " << totalDisp +// << " total distance = " << totalDist << endl; +} + + +//void Foam::CV2D::moveInternalPoints(const point2DField& newPoints) +//{ +// label pointI = 0; + +// for +// ( +// Triangulation::Finite_vertices_iterator vit = finite_vertices_begin(); +// vit != finite_vertices_end(); +// ++vit +// ) +// { +// if (vit->internalPoint()) +// { +// movePoint(vit, newPoints[pointI++]); +// } +// } +//} + + +void Foam::CV2D::extractPatches +( + wordList& patchNames, + labelList& patchSizes, + EdgeMap<label>& mapEdgesRegion +) const +{ + label nPatches = qSurf_.patchNames().size() + 1; + label defaultPatchIndex = qSurf_.patchNames().size(); + + patchNames.setSize(nPatches); + patchSizes.setSize(nPatches, 0); + mapEdgesRegion.clear(); + + const wordList& existingPatches = qSurf_.patchNames(); + + forAll(existingPatches, sP) + { + patchNames[sP] = existingPatches[sP]; + } + + patchNames[defaultPatchIndex] = "CV2D_default_patch"; + + for + ( + Triangulation::Finite_edges_iterator eit = finite_edges_begin(); + eit != finite_edges_end(); + ++eit + ) + { + Face_handle fOwner = eit->first; + Face_handle fNeighbor = fOwner->neighbor(eit->second); + + Vertex_handle vA = fOwner->vertex(cw(eit->second)); + Vertex_handle vB = fOwner->vertex(ccw(eit->second)); + + if + ( + (vA->internalOrBoundaryPoint() && !vB->internalOrBoundaryPoint()) + || (vB->internalOrBoundaryPoint() && !vA->internalOrBoundaryPoint()) + ) + { + point ptA = toPoint3D(vA->point()); + point ptB = toPoint3D(vB->point()); + + label patchIndex = qSurf_.findPatch(ptA, ptB); + + if (patchIndex == -1) + { + patchIndex = defaultPatchIndex; + + WarningIn("Foam::CV2D::extractPatches") + << "Dual face found that is not on a surface " + << "patch. Adding to CV2D_default_patch." + << endl; + } + + edge e(fOwner->faceIndex(), fNeighbor->faceIndex()); + patchSizes[patchIndex]++; + mapEdgesRegion.insert(e, patchIndex); + } + } +} + + +void Foam::CV2D::write() const +{ + if (meshControls().objOutput()) + { + writeFaces("allFaces.obj", false); + writeFaces("faces.obj", true); + writeTriangles("allTriangles.obj", false); + writeTriangles("triangles.obj", true); + writePatch("patch.pch"); + } +} + + +void Foam::CV2D::write(const word& stage) const +{ + if (meshControls().objOutput()) + { + Foam::mkDir(stage + "Faces"); + Foam::mkDir(stage + "Triangles"); + + writeFaces + ( + stage + + "Faces/allFaces_" + + runTime_.timeName() + + ".obj", + false + ); + + writeTriangles + ( + stage + + "Triangles/allTriangles_" + + runTime_.timeName() + + ".obj", + false + ); + } +} + + +// ************************************************************************* // diff --git a/applications/utilities/mesh/generation/cv2DMesh/CV2D.H b/applications/utilities/mesh/generation/cv2DMesh/CV2D.H new file mode 100644 index 0000000000000000000000000000000000000000..305420e73f9c6d6ffb3bbb5d784c40dd349c6bb0 --- /dev/null +++ b/applications/utilities/mesh/generation/cv2DMesh/CV2D.H @@ -0,0 +1,471 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2007-2011 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + CV2D + +Description + Conformal-Voronoi 2D automatic mesher with grid or read initial points + and point position relaxation with optional "squarification". + + There are a substantial number of options to this mesher read from + CV2DMesherDict file e.g.: + + // Min cell size used in tolerances when inserting points for + // boundary conforming. + // Also used to as the grid spacing usind in insertGrid. + minCellSize 0.05; + + // Feature angle used to inser feature points + // 0 = all features, 180 = no features + featureAngle 45; + + // Maximum quadrant angle allowed at a concave corner before + // additional "mitering" lines are added + maxQuadAngle 110; + + // Should the mesh be square-dominated or of unbiased hexagons + squares yes; + + // Near-wall region where cells are aligned with the wall specified as a + // number of cell layers + nearWallAlignedDist 3; + + // Chose if the cell orientation should relax during the iterations + // or remain fixed to the x-y directions + relaxOrientation no; + + // Insert near-boundary point mirror or point-pairs + insertSurfaceNearestPointPairs yes; + + // Mirror near-boundary points rather than insert point-pairs + mirrorPoints no; + + // Insert point-pairs vor dual-cell vertices very near the surface + insertSurfaceNearPointPairs yes; + + // Choose if to randomise the initial grid created by insertGrid. + randomiseInitialGrid yes; + + // Perturbation fraction, 1 = cell-size. + randomPurturbation 0.1; + + // Number of relaxation iterations. + nIterations 5; + + // Relaxation factor at the start of the iteration sequence. + // 0.5 is a sensible maximum and < 0.2 converges better. + relaxationFactorStart 0.8; + + // Relaxation factor at the end of the iteration sequence. + // Should be <= relaxationFactorStart + relaxationFactorEnd 0; + + writeInitialTriangulation no; + writeFeatureTriangulation no; + writeNearestTriangulation no; + writeInsertedPointPairs no; + writeFinalTriangulation yes; + + // Maximum number of iterations used in boundaryConform. + maxBoundaryConformingIter 5; + + minEdgeLenCoeff 0.5; + maxNotchLenCoeff 0.3; + minNearPointDistCoeff 0.25; + ppDistCoeff 0.05; + +SourceFiles + CGALTriangulation2Ddefs.H + indexedVertex.H + indexedFace.H + CV2DI.H + CV2D.C + CV2DIO.C + tolerances.C + controls.C + insertFeaturePoints.C + insertSurfaceNearestPointPairs.C + insertSurfaceNearPointPairs.C + insertBoundaryConformPointPairs.C + +\*---------------------------------------------------------------------------*/ + +#ifndef CV2D_H +#define CV2D_H + +#define CGAL_INEXACT +#define CGAL_HIERARCHY + +#include "CGALTriangulation2Ddefs.H" + +#include "Time.H" +#include "point2DFieldFwd.H" +#include "dictionary.H" +#include "Switch.H" +#include "PackedBoolList.H" +#include "EdgeMap.H" +#include "cv2DControls.H" +#include "tolerances.H" +#include "meshTools.H" +#include "triSurface.H" +#include "searchableSurfaces.H" +#include "conformationSurfaces.H" +#include "cellSizeControlSurfaces.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class CV2D Declaration +\*---------------------------------------------------------------------------*/ + +class CV2D +: + public Delaunay +{ + +private: + + // Private data + + //- The time registry of the application + const Time& runTime_; + + mutable Random rndGen_; + + //- The surface to mesh + //const querySurface& qSurf_; + //- All geometry of the meshing process, including surfaces to be + // conformed to and those to be used for refinement + searchableSurfaces allGeometry_; + + conformationSurfaces qSurf_; + + //- Meshing controls + cv2DControls controls_; + + //- The cell size control object + cellSizeControlSurfaces cellSizeControl_; + + //- z-level + scalar z_; + + //- Keep track of the start of the internal points + label startOfInternalPoints_; + + //- Keep track of the start of the surface point-pairs + label startOfSurfacePointPairs_; + + //- Keep track of the boundary conform point-pairs + // stored after the insertion of the surface point-pairs in case + // the boundary conform function is called more than once without + // removing and insertin the surface point-pairs + label startOfBoundaryConformPointPairs_; + + //- Store the feature points + std::list<Vb> featurePoints_; + + //- Temporary storage for a dual-cell + static const label maxNvert = 20; + mutable point2D vertices[maxNvert+1]; + mutable vector2D edges[maxNvert+1]; + + + // Private Member Functions + + //- Disallow default bitwise copy construct + CV2D(const CV2D&); + + //- Disallow default bitwise assignment + void operator=(const CV2D&); + + + //- Insert point and return it's index + inline label insertPoint + ( + const point2D& pt, + const label type + ); + + //- Insert point and return it's index + inline label insertPoint + ( + const point2D& pt, + const label index, + const label type + ); + + inline label insertPoint + ( + const Point& p, + const label index, + const label type + ); + + inline bool insertMirrorPoint + ( + const point2D& nearSurfPt, + const point2D& surfPt + ); + + //- Insert a point-pair at a distance ppDist either side of + // surface point point surfPt in the direction n + inline void insertPointPair + ( + const scalar mirrorDist, + const point2D& surfPt, + const vector2D& n + ); + + //- Create the initial mesh from the bounding-box + void insertBoundingBox(); + + //- Check if a point is within a line. + bool on2DLine(const point2D& p, const linePointRef& line); + + //- Insert point groups at the feature points. + void insertFeaturePoints(); + + //- Re-insert point groups at the feature points. + void reinsertFeaturePoints(); + + //- Insert point-pairs at the given set of points using the surface + // normals corresponding to the given set of surface triangles + // and write the inserted point locations to the given file. + void insertPointPairs + ( + const DynamicList<point2D>& nearSurfacePoints, + const DynamicList<point2D>& surfacePoints, + const DynamicList<label>& surfaceTris, + const DynamicList<label>& surfaceHits, + const fileName fName + ); + + //- Check to see if dual cell specified by given vertex iterator + // intersects the boundary and hence reqires a point-pair. + bool dualCellSurfaceIntersection + ( + const Triangulation::Finite_vertices_iterator& vit + ) const; + + //- Insert point-pairs at the nearest points on the surface to the + // control vertex of dual-cells which intersect the boundary in order + // to provide a boundary-layer mesh. + // NB: This is not guaranteed to close the boundary + void insertSurfaceNearestPointPairs(); + + //- Insert point-pairs at small dual-cell edges on the surface in order + // to improve the boundary-layer mesh generated by + // insertSurfaceNearestPointPairs. + void insertSurfaceNearPointPairs(); + + //- Insert point-pair and correcting the Finite_vertices_iterator + // to account for the additional vertices + void insertPointPair + ( + Triangulation::Finite_vertices_iterator& vit, + const point2D& p, + const label trii, + const label hitSurface + ); + + //- Insert point-pair at the best intersection point between the lines + // from the dual-cell real centroid and it's vertices and the surface. + bool insertPointPairAtIntersection + ( + Triangulation::Finite_vertices_iterator& vit, + const point2D& defVert, + const point2D vertices[], + const scalar maxProtSize + ); + + //- Insert point-pairs corresponding to dual-cells which intersect + // the boundary surface + label insertBoundaryConformPointPairs(const fileName& fName); + + void markNearBoundaryPoints(); + + //- Restore the Delaunay contraint + void fast_restore_Delaunay(Vertex_handle vh); + + // Flip operations used by fast_restore_Delaunay + void external_flip(Face_handle& f, int i); + bool internal_flip(Face_handle& f, int i); + + //- Write all the faces and all the triangles at a particular stage. + void write(const word& stage) const; + + +public: + + //- Runtime type information + ClassName("CV2D"); + + + // Constructors + + //- Construct for given surface + CV2D + ( + const Time& runTime, + const dictionary& controlDict + ); + + + //- Destructor + ~CV2D(); + + + // Member Functions + + // Access + + inline const cv2DControls& meshControls() const; + + + // Conversion functions between point2D, point and Point + + inline const point2D& toPoint2D(const point&) const; + inline const point2DField toPoint2D(const pointField&) const; + inline point toPoint3D(const point2D&) const; + + #ifdef CGAL_INEXACT + typedef const point2D& point2DFromPoint; + typedef const Point& PointFromPoint2D; + #else + typedef point2D point2DFromPoint; + typedef Point PointFromPoint2D; + #endif + + inline point2DFromPoint toPoint2D(const Point&) const; + inline PointFromPoint2D toPoint(const point2D&) const; + inline point toPoint3D(const Point&) const; + + + // Point insertion + + //- Create the initial mesh from the given internal points. + // Points must be inside the boundary by at least nearness + // otherwise they are ignored. + void insertPoints + ( + const point2DField& points, + const scalar nearness + ); + + //- Create the initial mesh from the internal points in the given + // file. Points outside the geometry are ignored. + void insertPoints(const fileName& pointFileName); + + //- Create the initial mesh as a regular grid of points. + // Points outside the geometry are ignored. + void insertGrid(); + + //- Insert all surface point-pairs from + // insertSurfaceNearestPointPairs and + // findIntersectionForOutsideCentroid + void insertSurfacePointPairs(); + + //- Insert point-pairs where there are protrusions into + // or out of the surface + void boundaryConform(); + + + // Point removal + + //- Remove the point-pairs introduced by insertSurfacePointPairs + // and boundaryConform + void removeSurfacePointPairs(); + + + // Point motion + + inline void movePoint(const Vertex_handle& vh, const Point& P); + + //- Move the internal points to the given new locations and update + // the triangulation to ensure it is Delaunay + // void moveInternalPoints(const point2DField& newPoints); + + //- Calculate the displacements to create the new points + void newPoints(const scalar relaxation); + + //- Extract patch names and sizes. + void extractPatches + ( + wordList& patchNames, + labelList& patchSizes, + EdgeMap<label>& mapEdgesRegion + ) const; + + // Write + + //- Write internal points to .obj file + void writePoints(const fileName& fName, bool internalOnly) const; + + //- Write triangles as .obj file + void writeTriangles(const fileName& fName, bool internalOnly) const; + + //- Write dual faces as .obj file + void writeFaces(const fileName& fName, bool internalOnly) const; + + //- Calculates dual points (circumcentres of tets) and faces + // (point-cell walk of tets). + // Returns: + // - dualPoints (in triangle ordering) + // - dualFaces (compacted) + void calcDual + ( + point2DField& dualPoints, + faceList& dualFaces, + wordList& patchNames, + labelList& patchSizes, + EdgeMap<label>& mapEdgesRegion + ) const; + + //- Write patch + void writePatch(const fileName& fName) const; + + void write() const; +}; + + +inline bool boundaryTriangle(const CV2D::Face_handle fc); +inline bool outsideTriangle(const CV2D::Face_handle fc); + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#include "CV2DI.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/applications/utilities/mesh/generation/cv2DMesh/CV2DI.H b/applications/utilities/mesh/generation/cv2DMesh/CV2DI.H new file mode 100644 index 0000000000000000000000000000000000000000..c96f47ab45fe877ba77647c48a2ccba8c57af3ee --- /dev/null +++ b/applications/utilities/mesh/generation/cv2DMesh/CV2DI.H @@ -0,0 +1,221 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2007-2011 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +inline Foam::label Foam::CV2D::insertPoint +( + const point2D& p, + const label type +) +{ + uint nVert = number_of_vertices(); + + return insertPoint(toPoint(p), nVert, type); +} + + +inline Foam::label Foam::CV2D::insertPoint +( + const point2D& p, + const label index, + const label type +) +{ + return insertPoint(toPoint(p), index, type); +} + + +inline Foam::label Foam::CV2D::insertPoint +( + const Point& p, + const label index, + const label type +) +{ + uint nVert = number_of_vertices(); + + Vertex_handle vh = insert(p); + + if (nVert == number_of_vertices()) + { + WarningIn("Foam::CV2D::insertPoint") + << "Failed to insert point " << toPoint2D(p) << endl; + } + else + { + vh->index() = index; + vh->type() = type; + } + + return vh->index(); +} + + +inline bool Foam::CV2D::insertMirrorPoint +( + const point2D& nearSurfPt, + const point2D& surfPt +) +{ + point2D mirrorPoint(2*surfPt - nearSurfPt); + + if (qSurf_.outside(toPoint3D(mirrorPoint))) + { + insertPoint(mirrorPoint, Vb::MIRROR_POINT); + return true; + } + else + { + return false; + } +} + + +inline void Foam::CV2D::insertPointPair +( + const scalar ppDist, + const point2D& surfPt, + const vector2D& n +) +{ + vector2D ppDistn = ppDist*n; + + label master = insertPoint + ( + surfPt - ppDistn, + number_of_vertices() + 1 + ); + + insertPoint(surfPt + ppDistn, master); +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +inline const Foam::cv2DControls& Foam::CV2D::meshControls() const +{ + return controls_; +} + +inline const Foam::point2D& Foam::CV2D::toPoint2D(const point& p) const +{ + return reinterpret_cast<const point2D&>(p); +} + +inline const Foam::point2DField Foam::CV2D::toPoint2D(const pointField& p) const +{ + point2DField temp(p.size()); + forAll(temp, pointI) + { + temp[pointI] = point2D(p[pointI].x(), p[pointI].y()); + } + return temp; +} + +inline Foam::point Foam::CV2D::toPoint3D(const point2D& p) const +{ + return point(p.x(), p.y(), z_); +} + + +#ifdef CGAL_INEXACT + +inline Foam::CV2D::point2DFromPoint Foam::CV2D::toPoint2D(const Point& P) const +{ + return reinterpret_cast<point2DFromPoint>(P); +} + +inline Foam::CV2D::PointFromPoint2D Foam::CV2D::toPoint(const point2D& p) const +{ + return reinterpret_cast<PointFromPoint2D>(p); +} + +#else + +inline Foam::CV2D::point2DFromPoint Foam::CV2D::toPoint2D(const Point& P) const +{ + return point2D(CGAL::to_double(P.x()), CGAL::to_double(P.y())); +} + +inline Foam::CV2D::PointFromPoint2D Foam::CV2D::toPoint(const point2D& p) const +{ + return Point(p.x(), p.y()); +} + +#endif + + +inline Foam::point Foam::CV2D::toPoint3D(const Point& P) const +{ + return point(CGAL::to_double(P.x()), CGAL::to_double(P.y()), z_); +} + + +inline void Foam::CV2D::movePoint(const Vertex_handle& vh, const Point& P) +{ + int i = vh->index(); + int t = vh->type(); + + remove(vh); + + Vertex_handle newVh = insert(P); + + newVh->index() = i; + newVh->type() = t; + + // label i = vh->index(); + // move(vh, P); + // vh->index() = i; + + //vh->set_point(P); + //fast_restore_Delaunay(vh); +} + + +// * * * * * * * * * * * * * * * Friend Functions * * * * * * * * * * * * * // + +inline bool Foam::boundaryTriangle(const CV2D::Face_handle fc) +{ + return boundaryTriangle + ( + *fc->vertex(0), + *fc->vertex(1), + *fc->vertex(2) + ); +} + +inline bool Foam::outsideTriangle(const CV2D::Face_handle fc) +{ + return outsideTriangle + ( + *fc->vertex(0), + *fc->vertex(1), + *fc->vertex(2) + ); +} + + +// ************************************************************************* // diff --git a/applications/utilities/mesh/generation/cv2DMesh/CV2DIO.C b/applications/utilities/mesh/generation/cv2DMesh/CV2DIO.C new file mode 100644 index 0000000000000000000000000000000000000000..60e4fa6113403596987e913b9bbdfc4c6348d6f9 --- /dev/null +++ b/applications/utilities/mesh/generation/cv2DMesh/CV2DIO.C @@ -0,0 +1,304 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2007-2011 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "CV2D.H" +#include "OFstream.H" + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +void Foam::CV2D::writePoints(const fileName& fName, bool internalOnly) const +{ + Info<< "Writing points to " << fName << nl << endl; + OFstream str(fName); + + for + ( + Triangulation::Finite_vertices_iterator vit = finite_vertices_begin(); + vit != finite_vertices_end(); + ++vit + ) + { + if (!internalOnly || vit->internalOrBoundaryPoint()) + { + meshTools::writeOBJ(str, toPoint3D(vit->point())); + } + } +} + + +void Foam::CV2D::writeTriangles(const fileName& fName, bool internalOnly) const +{ + Info<< "Writing triangles to " << fName << nl << endl; + OFstream str(fName); + + labelList vertexMap(number_of_vertices(), -2); + label verti = 0; + + for + ( + Triangulation::Finite_vertices_iterator vit = finite_vertices_begin(); + vit != finite_vertices_end(); + ++vit + ) + { + if (!internalOnly || !vit->farPoint()) + { + vertexMap[vit->index()] = verti++; + meshTools::writeOBJ(str, toPoint3D(vit->point())); + } + } + + for + ( + Triangulation::Finite_faces_iterator fit = finite_faces_begin(); + fit != finite_faces_end(); + ++fit + ) + { + if + ( + !internalOnly + || ( + fit->vertex(0)->internalOrBoundaryPoint() + || fit->vertex(1)->internalOrBoundaryPoint() + || fit->vertex(2)->internalOrBoundaryPoint() + ) + ) + { + str << "f"; + for (label i = 0; i < 3; ++i) + { + str << " " << vertexMap[fit->vertex(i)->index()] + 1; + } + str << nl; + } + } +} + + +void Foam::CV2D::writeFaces(const fileName& fName, bool internalOnly) const +{ + Info<< "Writing dual faces to " << fName << nl << endl; + OFstream str(fName); + + label dualVerti = 0; + + for + ( + Triangulation::Finite_faces_iterator fit = finite_faces_begin(); + fit != finite_faces_end(); + ++fit + ) + { + if + ( + !internalOnly + || ( + fit->vertex(0)->internalOrBoundaryPoint() + || fit->vertex(1)->internalOrBoundaryPoint() + || fit->vertex(2)->internalOrBoundaryPoint() + ) + ) + { + fit->faceIndex() = dualVerti++; + meshTools::writeOBJ(str, toPoint3D(circumcenter(fit))); + } + else + { + fit->faceIndex() = -1; + } + } + + for + ( + Triangulation::Finite_vertices_iterator vit = finite_vertices_begin(); + vit != finite_vertices_end(); + ++vit + ) + { + if (!internalOnly || vit->internalOrBoundaryPoint()) + { + Face_circulator fcStart = incident_faces(vit); + Face_circulator fc = fcStart; + + str<< 'f'; + + do + { + if (!is_infinite(fc)) + { + if (fc->faceIndex() < 0) + { + FatalErrorIn + ( + "Foam::CV2D::writeFaces" + "(const fileName& fName, bool internalOnly)" + )<< "Dual face uses vertex defined by a triangle" + " defined by an external point" + << exit(FatalError); + } + + str<< ' ' << fc->faceIndex() + 1; + } + } while (++fc != fcStart); + + str<< nl; + } + } +} + + +void Foam::CV2D::calcDual +( + point2DField& dualPoints, + faceList& dualFaces, + wordList& patchNames, + labelList& patchSizes, + EdgeMap<label>& mapEdgesRegion +) const +{ + // Dual points stored in triangle order. + dualPoints.setSize(number_of_faces()); + label dualVerti = 0; + + for + ( + Triangulation::Finite_faces_iterator fit = finite_faces_begin(); + fit != finite_faces_end(); + ++fit + ) + { + if + ( + fit->vertex(0)->internalOrBoundaryPoint() + || fit->vertex(1)->internalOrBoundaryPoint() + || fit->vertex(2)->internalOrBoundaryPoint() + ) + { + fit->faceIndex() = dualVerti; + + dualPoints[dualVerti++] = toPoint2D(circumcenter(fit)); + } + else + { + fit->faceIndex() = -1; + } + } + + dualPoints.setSize(dualVerti); + + extractPatches(patchNames, patchSizes, mapEdgesRegion); + + forAll(patchNames, patchI) + { + Info<< "Patch " << patchNames[patchI] + << " has size " << patchSizes[patchI] << endl; + } + + // Create dual faces + // ~~~~~~~~~~~~~~~~~ + + dualFaces.setSize(number_of_vertices()); + label dualFacei = 0; + labelList faceVerts(maxNvert); + + for + ( + Triangulation::Finite_vertices_iterator vit = finite_vertices_begin(); + vit != finite_vertices_end(); + ++vit + ) + { + if (vit->internalOrBoundaryPoint()) + { + Face_circulator fcStart = incident_faces(vit); + Face_circulator fc = fcStart; + label verti = 0; + + do + { + if (!is_infinite(fc)) + { + if (fc->faceIndex() < 0) + { + FatalErrorIn + ( + "Foam::CV2D::calcDual" + "(point2DField& dualPoints, faceList& dualFaces)" + )<< "Dual face uses vertex defined by a triangle" + " defined by an external point" + << exit(FatalError); + } + + // Look up the index of the triangle + faceVerts[verti++] = fc->faceIndex(); + } + } while (++fc != fcStart); + + if (faceVerts.size() > 2) + { + dualFaces[dualFacei++] = + face(labelList::subList(faceVerts, verti)); + } + else + { + Info<< "From triangle point:" << vit->index() + << " coord:" << toPoint2D(vit->point()) + << " generated illegal dualFace:" << faceVerts + << endl; + } + } + } + + dualFaces.setSize(dualFacei); +} + + +void Foam::CV2D::writePatch(const fileName& fName) const +{ + point2DField dual2DPoints; + faceList dualFaces; + wordList patchNames; + labelList patchSizes; + EdgeMap<label> mapEdgesRegion; + + calcDual(dual2DPoints, dualFaces, patchNames, patchSizes, mapEdgesRegion); + pointField dualPoints(dual2DPoints.size()); + forAll(dualPoints, ip) + { + dualPoints[ip] = toPoint3D(dual2DPoints[ip]); + } + + // Dump as primitive patch to be read by extrudeMesh. + OFstream str(fName); + + Info<< "Writing patch to be used with extrudeMesh to file " << fName + << endl; + + str << dualPoints << nl << dualFaces << nl; +} + + +// ************************************************************************* // diff --git a/applications/utilities/mesh/generation/cv2DMesh/Make/files b/applications/utilities/mesh/generation/cv2DMesh/Make/files new file mode 100755 index 0000000000000000000000000000000000000000..ddc8c9df9274934597248c74d55e313879f3a8da --- /dev/null +++ b/applications/utilities/mesh/generation/cv2DMesh/Make/files @@ -0,0 +1,13 @@ +#include CGAL_FILES + +CV2D.C +insertFeaturePoints.C +insertSurfaceNearestPointPairs.C +insertSurfaceNearPointPairs.C +insertBoundaryConformPointPairs.C +CV2DIO.C +shortEdgeFilter2D.C +cv2DMesh.C + +EXE = $(FOAM_APPBIN)/cv2DMesh + diff --git a/applications/utilities/mesh/generation/cv2DMesh/Make/options b/applications/utilities/mesh/generation/cv2DMesh/Make/options new file mode 100755 index 0000000000000000000000000000000000000000..82659091b69ddf13c3ae892a944a9825a119ed93 --- /dev/null +++ b/applications/utilities/mesh/generation/cv2DMesh/Make/options @@ -0,0 +1,34 @@ +EXE_DEBUG = -DFULLDEBUG -g -O0 +EXE_FROUNDING_MATH = -frounding-math +EXE_NDEBUG = -DNDEBUG + +include $(GENERAL_RULES)/CGAL +FFLAGS = -DCGAL_FILES='"${CGAL_ARCH_PATH}/share/files"' + +EXE_INC = \ + ${EXE_FROUNDING_MATH} \ + ${EXE_NDEBUG} \ + ${CGAL_INC} \ + -I$(FOAM_APP)/utilities/mesh/generation/extrude2DMesh/extrude2DMesh/lnInclude \ + -I$(FOAM_APP)/utilities/mesh/generation/extrude/extrudeModel/lnInclude \ + -IconformalVoronoi2DMesh/lnInclude \ + -I$(FOAM_APP)/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/lnInclude \ + -I$(LIB_SRC)/finiteVolume/lnInclude \ + -I$(LIB_SRC)/meshTools/lnInclude \ + -I$(LIB_SRC)/surfMesh/lnInclude \ + -I$(LIB_SRC)/edgeMesh/lnInclude \ + -I$(LIB_SRC)/dynamicMesh/lnInclude \ + -I$(LIB_SRC)/triSurface/lnInclude + +EXE_LIBS = \ + $(CGAL_LIBS) \ + -lextrude2DMesh \ + -lextrudeModel \ + -lcv2DMesh \ + -lconformalVoronoiMesh \ + -lmeshTools \ + -lsurfMesh \ + -ledgeMesh \ + -ltriSurface \ + -ldynamicMesh \ + -ldecompositionMethods diff --git a/applications/utilities/mesh/generation/cv2DMesh/conformalVoronoi2DMesh/Make/files b/applications/utilities/mesh/generation/cv2DMesh/conformalVoronoi2DMesh/Make/files new file mode 100755 index 0000000000000000000000000000000000000000..b05aa47e45d0deb95d574ba8422510b294649d16 --- /dev/null +++ b/applications/utilities/mesh/generation/cv2DMesh/conformalVoronoi2DMesh/Make/files @@ -0,0 +1,4 @@ +cv2DControls/cv2DControls.C + +LIB = $(FOAM_LIBBIN)/libcv2DMesh + diff --git a/applications/utilities/mesh/generation/cv2DMesh/conformalVoronoi2DMesh/Make/options b/applications/utilities/mesh/generation/cv2DMesh/conformalVoronoi2DMesh/Make/options new file mode 100755 index 0000000000000000000000000000000000000000..79be6f3a7dd8fa81ba203d5ab8572c446c43a6c7 --- /dev/null +++ b/applications/utilities/mesh/generation/cv2DMesh/conformalVoronoi2DMesh/Make/options @@ -0,0 +1,3 @@ +EXE_INC = + +LIB_LIBS = diff --git a/applications/utilities/mesh/generation/cv2DMesh/conformalVoronoi2DMesh/cv2DControls/cv2DControls.C b/applications/utilities/mesh/generation/cv2DMesh/conformalVoronoi2DMesh/cv2DControls/cv2DControls.C new file mode 100644 index 0000000000000000000000000000000000000000..b2b92a845f0b0c9263c19d640d00f164a8907de0 --- /dev/null +++ b/applications/utilities/mesh/generation/cv2DMesh/conformalVoronoi2DMesh/cv2DControls/cv2DControls.C @@ -0,0 +1,149 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2007-2011 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*----------------------------------------------------------------------------*/ + +#include "cv2DControls.H" + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + + +Foam::cv2DControls::cv2DControls +( + const dictionary& controlDict, + const boundBox& bb +) +: + dict_(controlDict), + + motionControl_(controlDict.subDict("motionControl")), + conformationControl_(controlDict.subDict("surfaceConformation")), + + minCellSize_(readScalar(motionControl_.lookup("minCellSize"))), + minCellSize2_(Foam::sqr(minCellSize_)), + + maxQuadAngle_(readScalar(conformationControl_.lookup("maxQuadAngle"))), + + nearWallAlignedDist_ + ( + readScalar(motionControl_.lookup("nearWallAlignedDist"))*minCellSize_ + ), + nearWallAlignedDist2_(Foam::sqr(nearWallAlignedDist_)), + + insertSurfaceNearestPointPairs_ + ( + conformationControl_.lookup("insertSurfaceNearestPointPairs") + ), + mirrorPoints_(conformationControl_.lookup("mirrorPoints")), + insertSurfaceNearPointPairs_ + ( + conformationControl_.lookup("insertSurfaceNearPointPairs") + ), + + objOutput_(motionControl_.lookupOrDefault<Switch>("objOutput", false)), + + randomiseInitialGrid_(conformationControl_.lookup("randomiseInitialGrid")), + randomPerturbation_ + ( + readScalar(conformationControl_.lookup("randomPerturbation")) + ), + + maxBoundaryConformingIter_ + ( + readLabel(conformationControl_.lookup("maxBoundaryConformingIter")) + ), + + span_ + ( + max(mag(bb.max().x()), mag(bb.min().x())) + + max(mag(bb.max().y()), mag(bb.min().y())) + ), + span2_(Foam::sqr(span_)), + + minEdgeLen_ + ( + readScalar(conformationControl_.lookup("minEdgeLenCoeff")) + *minCellSize_ + ), + minEdgeLen2_(Foam::sqr(minEdgeLen_)), + + maxNotchLen_ + ( + readScalar(conformationControl_.lookup("maxNotchLenCoeff")) + *minCellSize_ + ), + maxNotchLen2_(Foam::sqr(maxNotchLen_)), + + minNearPointDist_ + ( + readScalar(conformationControl_.lookup("minNearPointDistCoeff")) + *minCellSize_ + ), + minNearPointDist2_(Foam::sqr(minNearPointDist_)), + + ppDist_ + ( + readScalar(conformationControl_.lookup("pointPairDistanceCoeff")) + *minCellSize_ + ) +{} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::cv2DControls::~cv2DControls() +{} + + +// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // + +void Foam::cv2DControls::write(Ostream& os) const +{ + os.indentLevel() = 1; + os.precision(2); + os.flags(ios_base::scientific); + + os << nl << "Outputting CV2D Mesher controls:" << nl + << token::BEGIN_BLOCK << nl + << indent << "minCellSize2_ : " << minCellSize2_ << nl + << indent << "span_ / span2_ : " << span_ << " / " << span2_ << nl + << indent << "maxNotchLen2_ : " << maxNotchLen2_ << nl + << indent << "minNearPointDist2_ : " << minNearPointDist2_ << nl + << indent << "nearWallAlignedDist2_ : " << nearWallAlignedDist2_ << nl + << indent << "ppDist_ : " << ppDist_ << nl + << indent << "minEdgeLen2_ : " << minEdgeLen2_ << nl + << token::END_BLOCK << endl; +} + + +// * * * * * * * * * * * * * * IOStream operators * * * * * * * * * * * * * // + +Foam::Ostream& Foam::operator<<(Ostream& os, const cv2DControls& s) +{ + s.write(os); + return os; +} + + + +// ************************************************************************* // diff --git a/applications/utilities/mesh/generation/cv2DMesh/conformalVoronoi2DMesh/cv2DControls/cv2DControls.H b/applications/utilities/mesh/generation/cv2DMesh/conformalVoronoi2DMesh/cv2DControls/cv2DControls.H new file mode 100644 index 0000000000000000000000000000000000000000..0d1f47b1ca0190a2bb9866adfffb971d0f4efde8 --- /dev/null +++ b/applications/utilities/mesh/generation/cv2DMesh/conformalVoronoi2DMesh/cv2DControls/cv2DControls.H @@ -0,0 +1,257 @@ +/*--------------------------------*- C++ -*----------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011-2011 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::cv2DControls + +Description + Controls for the 2D CV mesh generator. + +SourceFiles + cv2DControls.C + cv2DControlsI.H + +\*---------------------------------------------------------------------------*/ + +#ifndef cv2DControls_H +#define cv2DControls_H + +#include "Switch.H" +#include "dictionary.H" +#include "boundBox.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class cv2DControls Declaration +\*---------------------------------------------------------------------------*/ + +class cv2DControls +{ + // Private data + + //- Description of data_ + const dictionary& dict_; + + const dictionary& motionControl_; + + const dictionary& conformationControl_; + + + // Private Member Functions + + //- Disallow default bitwise copy construct + cv2DControls(const cv2DControls&); + + //- Disallow default bitwise assignment + void operator=(const cv2DControls&); + + +public: + + // Controls + + //- Minimum cell size below which protusions through the surface are + // not split + scalar minCellSize_; + + //- Square of minCellSize + scalar minCellSize2_; + + //- Maximum quadrant angle allowed at a concave corner before + // additional "mitering" lines are added + scalar maxQuadAngle_; + + //- Near-wall region where cells are aligned with the wall + scalar nearWallAlignedDist_; + + //- Square of nearWallAlignedDist + scalar nearWallAlignedDist2_; + + //- Insert near-boundary point mirror or point-pairs + Switch insertSurfaceNearestPointPairs_; + + //- Mirror near-boundary points rather than insert point-pairs + Switch mirrorPoints_; + + //- Insert point-pairs vor dual-cell vertices very near the surface + Switch insertSurfaceNearPointPairs_; + + Switch objOutput_; + + Switch randomiseInitialGrid_; + + scalar randomPerturbation_; + + label maxBoundaryConformingIter_; + + + // Tolerances + + //- Maximum cartesian span of the geometry + scalar span_; + + //- Square of span + scalar span2_; + + //- Minumum edge-length of the cell size below which protusions + // through the surface are not split + scalar minEdgeLen_; + + //- Square of minEdgeLen + scalar minEdgeLen2_; + + //- Maximum notch size below which protusions into the surface are + // not filled + scalar maxNotchLen_; + + //- Square of maxNotchLen + scalar maxNotchLen2_; + + //- The minimum distance alowed between a dual-cell vertex + // and the surface before a point-pair is introduced + scalar minNearPointDist_; + + //- Square of minNearPoint + scalar minNearPointDist2_; + + //- Distance between boundary conforming point-pairs + scalar ppDist_; + + //- Square of ppDist + scalar ppDist2_; + + + // Constructors + + cv2DControls + ( + const dictionary& controlDict, + const boundBox& bb + ); + + + //- Destructor + ~cv2DControls(); + + + // Member Functions + + // Access + + //- Return the minimum cell size + inline scalar minCellSize() const; + + //- Return the square of the minimum cell size + inline scalar minCellSize2() const; + + //- Return the maximum quadrant angle + inline scalar maxQuadAngle() const; + + //- Return number of layers to align with the nearest wall + inline scalar nearWallAlignedDist() const; + + //- Return square of nearWallAlignedDist + inline scalar nearWallAlignedDist2() const; + + //- Return insertSurfaceNearestPointPairs Switch + inline Switch insertSurfaceNearestPointPairs() const; + + //- Return mirrorPoints Switch + inline Switch mirrorPoints() const; + + //- Return insertSurfaceNearPointPairs Switch + inline Switch insertSurfaceNearPointPairs() const; + + //- Return the objOutput Switch + inline Switch objOutput() const; + + //- Return the randomise initial point layout Switch + inline Switch randomiseInitialGrid() const; + + //- Return the random perturbation factor + inline scalar randomPerturbation() const; + + //- Return the maximum number of boundary conformation iterations + inline label maxBoundaryConformingIter() const; + + //- Return the span + inline scalar span() const; + + //- Return the span squared + inline scalar span2() const; + + //- Return the minEdgeLen + inline scalar minEdgeLen() const; + + //- Return the minEdgeLen squared + inline scalar minEdgeLen2() const; + + //- Return the maxNotchLen + inline scalar maxNotchLen() const; + + //- Return the maxNotchLen squared + inline scalar maxNotchLen2() const; + + //- Return the minNearPointDist + inline scalar minNearPointDist() const; + + //- Return the minNearPointDist squared + inline scalar minNearPointDist2() const; + + //- Return the ppDist + inline scalar ppDist() const; + + + // Write + + //- Write controls to output stream. + void write(Ostream& os) const; + + //- Ostream Operator + friend Ostream& operator<< + ( + Ostream& os, + const cv2DControls& s + ); + + +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#include "cv2DControlsI.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/applications/utilities/mesh/generation/cv2DMesh/conformalVoronoi2DMesh/cv2DControls/cv2DControlsI.H b/applications/utilities/mesh/generation/cv2DMesh/conformalVoronoi2DMesh/cv2DControls/cv2DControlsI.H new file mode 100644 index 0000000000000000000000000000000000000000..3ff16735a8372fe6e2f1cd21981ced0a8a48cd01 --- /dev/null +++ b/applications/utilities/mesh/generation/cv2DMesh/conformalVoronoi2DMesh/cv2DControls/cv2DControlsI.H @@ -0,0 +1,153 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + + +inline Foam::scalar Foam::cv2DControls::minCellSize() const +{ + return minCellSize_; +} + + +inline Foam::scalar Foam::cv2DControls::minCellSize2() const +{ + return minCellSize2_; +} + + +inline Foam::scalar Foam::cv2DControls::maxQuadAngle() const +{ + return maxQuadAngle_; +} + + +inline Foam::scalar Foam::cv2DControls::nearWallAlignedDist() const +{ + return nearWallAlignedDist_; +} + + +inline Foam::scalar Foam::cv2DControls::nearWallAlignedDist2() const +{ + return nearWallAlignedDist2_; +} + + +inline Foam::Switch Foam::cv2DControls::insertSurfaceNearestPointPairs() const +{ + return insertSurfaceNearestPointPairs_; +} + + +inline Foam::Switch Foam::cv2DControls::mirrorPoints() const +{ + return mirrorPoints_; +} + + +inline Foam::Switch Foam::cv2DControls::insertSurfaceNearPointPairs() const +{ + return insertSurfaceNearPointPairs_; +} + + +inline Foam::Switch Foam::cv2DControls::objOutput() const +{ + return objOutput_; +} + + +inline Foam::Switch Foam::cv2DControls::randomiseInitialGrid() const +{ + return randomiseInitialGrid_; +} + + +inline Foam::scalar Foam::cv2DControls::randomPerturbation() const +{ + return randomPerturbation_; +} + + +inline Foam::label Foam::cv2DControls::maxBoundaryConformingIter() const +{ + return maxBoundaryConformingIter_; +} + + +inline Foam::scalar Foam::cv2DControls::span() const +{ + return span_; +} + + +inline Foam::scalar Foam::cv2DControls::span2() const +{ + return span2_; +} + + +inline Foam::scalar Foam::cv2DControls::minEdgeLen() const +{ + return minEdgeLen_; +} + + +inline Foam::scalar Foam::cv2DControls::minEdgeLen2() const +{ + return minEdgeLen2_; +} + + +inline Foam::scalar Foam::cv2DControls::maxNotchLen() const +{ + return maxNotchLen_; +} + + +inline Foam::scalar Foam::cv2DControls::maxNotchLen2() const +{ + return maxNotchLen2_; +} + + +inline Foam::scalar Foam::cv2DControls::minNearPointDist() const +{ + return minNearPointDist_; +} + + +inline Foam::scalar Foam::cv2DControls::minNearPointDist2() const +{ + return minNearPointDist2_; +} + + +inline Foam::scalar Foam::cv2DControls::ppDist() const +{ + return ppDist_; +} + + +// ************************************************************************* // diff --git a/applications/utilities/mesh/generation/cv2DMesh/cv2DMesh.C b/applications/utilities/mesh/generation/cv2DMesh/cv2DMesh.C new file mode 100644 index 0000000000000000000000000000000000000000..09fe6261f67faab9d9128f2ac1936e7a5b06e5a0 --- /dev/null +++ b/applications/utilities/mesh/generation/cv2DMesh/cv2DMesh.C @@ -0,0 +1,251 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2007-2011 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Application + cv2DMesh + +Description + Conformal-Voronoi 2D extruding automatic mesher with grid or read + initial points and point position relaxation with optional + "squarification". + +\*---------------------------------------------------------------------------*/ + +#include "CV2D.H" +#include "argList.H" + +#include "MeshedSurfaces.H" +#include "shortEdgeFilter2D.H" +#include "extrude2DMesh.H" +#include "polyMesh.H" +#include "patchToPoly2DMesh.H" +#include "extrudeModel.H" +#include "polyTopoChange.H" +#include "edgeCollapser.H" +#include "relaxationModel.H" + +using namespace Foam; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +// Main program: + +int main(int argc, char *argv[]) +{ + argList::noParallel(); + argList::validArgs.clear(); + argList::validOptions.insert("pointsFile", "<filename>"); + + #include "addOverwriteOption.H" + + #include "setRootCase.H" + #include "createTime.H" + + // Read control dictionary + // ~~~~~~~~~~~~~~~~~~~~~~~ + dictionary controlDict(IFstream("system/" + args.executable() + "Dict")()); + dictionary shortEdgeFilterDict(controlDict.subDict("shortEdgeFilter")); + dictionary extrusionDict(controlDict.subDict("extrusion")); + + Switch extrude(extrusionDict.lookup("extrude")); + const bool overwrite = args.optionFound("overwrite"); + + autoPtr<relaxationModel> relax + ( + relaxationModel::New + ( + controlDict.subDict("motionControl"), + runTime + ) + ); + + // Read and triangulation + // ~~~~~~~~~~~~~~~~~~~~~~ + CV2D mesh(runTime, controlDict); + if (args.options().found("pointsFile")) + { + fileName pointFileName(IStringStream(args.options()["pointsFile"])()); + mesh.insertPoints(pointFileName); + mesh.insertSurfacePointPairs(); + mesh.boundaryConform(); + } + else + { + mesh.insertGrid(); + mesh.insertSurfacePointPairs(); + mesh.boundaryConform(); + } + + while (runTime.loop()) + { + Info<< nl << "Time = " << runTime.timeName() << endl; + + Info<< "Relaxation = " << relax->relaxation() << endl; + + mesh.newPoints(relax->relaxation()); + } + + mesh.write(); + + Info<< "Finished Delaunay in = " + << runTime.cpuTimeIncrement() << " s." << endl; + + Info<< "Begin filtering short edges:" << endl; + shortEdgeFilter2D sef(mesh, shortEdgeFilterDict); + + sef.filter(); + + Info<< "Meshed surface after edge filtering :" << endl; + sef.fMesh().writeStats(Info); + + Info<< "Write .obj file of the 2D mesh: MeshedSurface.obj" << endl; + sef.fMesh().write("MeshedSurface.obj"); + + Info<< "Finished filtering in = " + << runTime.cpuTimeIncrement() << " s." << endl; + + Info<< "Begin constructing a polyMesh:" << endl; + + patchToPoly2DMesh poly2DMesh + ( + sef.fMesh(), + sef.patchNames(), + sef.patchSizes(), + sef.mapEdgesRegion() + ); + + poly2DMesh.createMesh(); + + polyMesh pMesh + ( + IOobject + ( + polyMesh::defaultRegion, + runTime.constant(), + runTime, + IOobject::NO_READ, + IOobject::NO_WRITE, + false + ), + xferMove(poly2DMesh.points()), + xferMove(poly2DMesh.faces()), + xferMove(poly2DMesh.owner()), + xferMove(poly2DMesh.neighbour()) + ); + + Info<< "Constructing patches." << endl; + List<polyPatch*> patches(poly2DMesh.patchNames().size()); + + forAll(patches, patchI) + { + patches[patchI] = new polyPatch + ( + poly2DMesh.patchNames()[patchI], + poly2DMesh.patchSizes()[patchI], + poly2DMesh.patchStarts()[patchI], + patchI, + pMesh.boundaryMesh() + ); + } + + pMesh.addPatches(patches); + + if (extrude) + { + Info<< "Begin extruding the polyMesh:" << endl; + + { + // Point generator + autoPtr<extrudeModel> model(extrudeModel::New(extrusionDict)); + + extrude2DMesh extruder(pMesh, extrusionDict, model()); + + extruder.addFrontBackPatches(); + + polyTopoChange meshMod(pMesh.boundaryMesh().size()); + + extruder.setRefinement(meshMod); + + autoPtr<mapPolyMesh> morphMap = meshMod.changeMesh(pMesh, false); + + pMesh.updateMesh(morphMap); + } + + { + edgeCollapser collapser(pMesh); + + const edgeList& edges = pMesh.edges(); + const pointField& points = pMesh.points(); + + const boundBox& bb = pMesh.bounds(); + const scalar mergeDim = 1E-4 * bb.minDim(); + + forAll(edges, edgeI) + { + const edge& e = edges[edgeI]; + + scalar d = e.mag(points); + + if (d < mergeDim) + { + Info<< "Merging edge " << e << " since length " << d + << " << " << mergeDim << endl; + + // Collapse edge to e[0] + collapser.collapseEdge(edgeI, e[0]); + } + } + + polyTopoChange meshModCollapse(pMesh); + + collapser.setRefinement(meshModCollapse); + + // Create a mesh from topo changes. + autoPtr<mapPolyMesh> morphMap = + meshModCollapse.changeMesh(pMesh, false); + + pMesh.updateMesh(morphMap); + } + + if (!overwrite) + { + runTime++; + } + else + { + pMesh.setInstance("constant"); + } + + } + + pMesh.write(); + + Info<< "Finished extruding in = " + << runTime.cpuTimeIncrement() << " s." << endl; + + Info<< nl << "End\n" << endl; + + return 0; +} + + +// ************************************************************************* // diff --git a/applications/utilities/mesh/generation/cv2DMesh/cv2DMeshDict b/applications/utilities/mesh/generation/cv2DMesh/cv2DMeshDict new file mode 100644 index 0000000000000000000000000000000000000000..0ef6d2a0c4794677e257056a9a23d3b1e59975d2 --- /dev/null +++ b/applications/utilities/mesh/generation/cv2DMesh/cv2DMeshDict @@ -0,0 +1,208 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: dev | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ + +FoamFile +{ + version 2.0; + format ascii; + + root ""; + case ""; + instance ""; + local ""; + + class dictionary; + object cv2DMeshDict; +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + + +geometry +{ + laurence_clean_preciser.stl + { + name laurence_clean_preciser; + type closedTriSurfaceMesh; + //type triSurfaceMesh; + } +// refinementBox +// { +// type searchableBox; +// min (-0.5 0.35 -1000); +// max (-0.5 0.35 1000); +// } +// refinementSphere +// { +// type searchableSphere; +// centre (0.85 0.4 0.0); +// radius 0.01; +// } +} + +surfaceConformation +{ + locationInMesh (-2.8 0.7 0.5); + + pointPairDistanceCoeff 0.005; + + minEdgeLenCoeff 0.005; + + maxNotchLenCoeff 0.003; + + minNearPointDistCoeff 0.0025; + + maxQuadAngle 125; + + // Insert near-boundary point mirror or point-pairs + insertSurfaceNearestPointPairs yes; + + // Mirror near-boundary points rather than insert point-pairs + mirrorPoints no; + + // Insert point-pairs vor dual-cell vertices very near the surface + insertSurfaceNearPointPairs yes; + + // Maximum number of iterations used in boundaryConform. + maxBoundaryConformingIter 5; + + geometryToConformTo + { + laurence_clean_preciser + { + featureMethod extendedFeatureEdgeMesh; + extendedFeatureEdgeMesh "laurence_clean_preciser.extendedFeatureEdgeMesh"; + } + } + + additionalFeatures + { + } + + // Choose if to randomise the initial grid created by insertGrid. + randomiseInitialGrid yes; + + // Perturbation fraction, 1 = cell-size. + randomPerturbation 0.1; + +} + + +motionControl +{ + defaultCellSize 0.05; + + // Assign a priority to all requests for cell sizes, the highest overrules. + defaultPriority 0; + + cellSizeControlGeometry + { + laurence_clean_preciser + { + priority 1; + mode bothSides; + cellSizeFunction linearDistance; + linearDistanceCoeffs + { + distanceCellSize 0.05; + surfaceCellSize 0.01; + distance 0.5; + } + uniformCoeffs + { + cellSize 0.01; + } + } +// refinementBox +// { +// priority 1; +// mode outside; +// cellSizeFunction linearDistance; +// linearDistanceCoeffs +// { +// distanceCellSize 0.04; +// surfaceCellSize 0.005; +// distance 0.2; +// } +// } +// refinementSphere +// { +// priority 1; +// mode outside; +// cellSizeFunction linearDistance; +// linearDistanceCoeffs +// { +// distanceCellSize 0.04; +// surfaceCellSize 0.005; +// distance 0.2; +// } +// } + } + + relaxationModel adaptiveLinear; + + adaptiveLinearCoeffs + { + relaxationStart 0.5; + relaxationEnd 0.0; + } + + objOutput no; + + // Near-wall region where cells are aligned with the wall specified as a number + // of cell layers + nearWallAlignedDist 3; + +} + +shortEdgeFilter +{ + // Factor to multiply the average of a face's edge lengths by. + // If an edge of that face is smaller than that value then delete it. + shortEdgeFilterFactor 0.2; + + // Weighting for the lengths of edges that are attached to the boundaries. + // Used when calculating the length of an edge. Default 2.0. + edgeAttachedToBoundaryFactor 2.0; +} + +extrusion +{ + extrude on; + + extrudeModel linearDirection; + //extrudeModel wedge; + + patchInfo + { + //type empty; + //startFace + } + + patchType empty; + //patchType wedge; + + nLayers 1; + + expansionRatio 1.0; //0.9; + + linearDirectionCoeffs + { + direction (0 0 1); + thickness 0.1; + } + + wedgeCoeffs + { + axisPt (0 0 0); + axis (1 0 0); + angle 10; + } + + thickness 0.1; +} diff --git a/applications/utilities/mesh/generation/cv2DMesh/featuresMissingFrom2D.org b/applications/utilities/mesh/generation/cv2DMesh/featuresMissingFrom2D.org new file mode 100644 index 0000000000000000000000000000000000000000..857c41f31c3293d52b5e7f7105e524e9285399aa --- /dev/null +++ b/applications/utilities/mesh/generation/cv2DMesh/featuresMissingFrom2D.org @@ -0,0 +1,3 @@ +* Displacement limiting + +http://en.wikipedia.org/wiki/Geometric_algebra diff --git a/applications/utilities/mesh/generation/cv2DMesh/indexedFace.H b/applications/utilities/mesh/generation/cv2DMesh/indexedFace.H new file mode 100644 index 0000000000000000000000000000000000000000..4cea4a7c51f6f11f83a861b017154350b7d8de4b --- /dev/null +++ b/applications/utilities/mesh/generation/cv2DMesh/indexedFace.H @@ -0,0 +1,147 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2007-2011 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + indexedFace + +Description + An indexed form of CGAL::Triangulation_face_base_2<K> used to keep + track of the vertices in the triangulation. + +\*---------------------------------------------------------------------------*/ + +#ifndef indexedFace_H +#define indexedFace_H + +#include <CGAL/Triangulation_2.h> +#include "indexedVertex.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace CGAL +{ + +/*---------------------------------------------------------------------------*\ + Class indexedFace Declaration +\*---------------------------------------------------------------------------*/ + +template<class Gt, class Fb=CGAL::Triangulation_face_base_2<Gt> > +class indexedFace +: + public Fb +{ + // Private data + + //- The index for this triangle face + // -1: triangle and changed and associated data needs updating + // >=0: index of triangles, set by external update algorithm + int index_; + + +public: + + enum faceTypes + { + UNCHANGED = 0, + CHANGED = -1, + SAVE_CHANGED = -2 + }; + + typedef typename Fb::Vertex_handle Vertex_handle; + typedef typename Fb::Face_handle Face_handle; + + template < typename TDS2 > + struct Rebind_TDS + { + typedef typename Fb::template Rebind_TDS<TDS2>::Other Fb2; + typedef indexedFace<Gt, Fb2> Other; + }; + + + indexedFace() + : + Fb(), + index_(CHANGED) + {} + + indexedFace(Vertex_handle v0, Vertex_handle v1, Vertex_handle v2) + : + Fb(v0, v1, v2), + index_(CHANGED) + {} + + indexedFace + ( + Vertex_handle v0, + Vertex_handle v1, + Vertex_handle v2, + Face_handle n0, + Face_handle n1, + Face_handle n2 + ) + : + Fb(v0, v1, v2, n0, n1, n2), + index_(CHANGED) + {} + + + void set_vertex(int i, Vertex_handle v) + { + index_ = CHANGED; + Fb::set_vertex(i, v); + } + + void set_vertices() + { + index_ = CHANGED; + Fb::set_vertices(); + } + + void set_vertices(Vertex_handle v0, Vertex_handle v1, Vertex_handle v2) + { + index_ = CHANGED; + Fb::set_vertices(v0, v1, v2); + } + + + int& faceIndex() + { + return index_; + } + + int faceIndex() const + { + return index_; + } +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace CGAL + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/applications/utilities/mesh/generation/cv2DMesh/indexedVertex.H b/applications/utilities/mesh/generation/cv2DMesh/indexedVertex.H new file mode 100644 index 0000000000000000000000000000000000000000..cda593840d98c9f22da247940af5fedd1701270f --- /dev/null +++ b/applications/utilities/mesh/generation/cv2DMesh/indexedVertex.H @@ -0,0 +1,268 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2007-2011 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + indexedVertex + +Description + An indexed form of CGAL::Triangulation_vertex_base_2<K> used to keep + track of the vertices in the triangulation. + +\*---------------------------------------------------------------------------*/ + +#ifndef indexedVertex_H +#define indexedVertex_H + +#include <CGAL/Triangulation_2.h> + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace CGAL +{ + +/*---------------------------------------------------------------------------*\ + Class indexedVertex Declaration +\*---------------------------------------------------------------------------*/ + +template<class Gt, class Vb=CGAL::Triangulation_vertex_base_2<Gt> > +class indexedVertex +: + public Vb +{ + // Private data + + //- The index for this triangle vertex + int index_; + + //- Index of pair-point : + // NEAR_BOUNDARY_POINT : internal near boundary point. + // INTERNAL_POINT : internal point. + // FAR_POINT : far-point. + // >= 0 : part of point-pair. Index of other point. + // Lowest numbered is inside one (master). + int type_; + + +public: + + enum pointTypes + { + NEAR_BOUNDARY_POINT = -4, + INTERNAL_POINT = -3, + MIRROR_POINT = -2, + FAR_POINT = -1 + }; + + typedef typename Vb::Vertex_handle Vertex_handle; + typedef typename Vb::Face_handle Face_handle; + typedef typename Vb::Point Point; + + template<typename TDS2> + struct Rebind_TDS + { + typedef typename Vb::template Rebind_TDS<TDS2>::Other Vb2; + typedef indexedVertex<Gt,Vb2> Other; + }; + + + indexedVertex() + : + Vb(), + index_(INTERNAL_POINT), + type_(INTERNAL_POINT) + {} + + indexedVertex(const Point& p) + : + Vb(p), + index_(INTERNAL_POINT), + type_(INTERNAL_POINT) + {} + + indexedVertex(const Point& p, const int index, const int& type) + : + Vb(p), + index_(index), + type_(type) + {} + + indexedVertex(const Point& p, Face_handle f) + : + Vb(f, p), + index_(INTERNAL_POINT), + type_(INTERNAL_POINT) + {} + + indexedVertex(Face_handle f) + : + Vb(f), + index_(INTERNAL_POINT), + type_(INTERNAL_POINT) + {} + + + int& index() + { + return index_; + } + + int index() const + { + return index_; + } + + + int& type() + { + return type_; + } + + int type() const + { + return type_; + } + + + //- Is point a far-point + inline bool farPoint() const + { + return type_ == FAR_POINT; + } + + //- Is point internal, i.e. not on boundary + inline bool internalPoint() const + { + return type_ <= INTERNAL_POINT; + } + + //- Is point internal and near the boundary + inline bool nearBoundary() const + { + return type_ == NEAR_BOUNDARY_POINT; + } + + //- Set the point to be near the boundary + inline void setNearBoundary() + { + type_ = NEAR_BOUNDARY_POINT; + } + + //- Is point a mirror point + inline bool mirrorPoint() const + { + return type_ == MIRROR_POINT; + } + + //- Either master or slave of pointPair. + inline bool pairPoint() const + { + return type_ >= 0; + } + + //- Master of a pointPair is the lowest numbered one. + inline bool ppMaster() const + { + if (type_ > index_) + { + return true; + } + else + { + return false; + } + } + + //- Slave of a pointPair is the highest numbered one. + inline bool ppSlave() const + { + if (type_ >= 0 && type_ < index_) + { + return true; + } + else + { + return false; + } + } + + //- Either original internal point or master of pointPair. + inline bool internalOrBoundaryPoint() const + { + return internalPoint() || ppMaster(); + } + + //- Is point near the boundary or part of the boundary definition + inline bool nearOrOnBoundary() const + { + return pairPoint() || mirrorPoint() || nearBoundary(); + } + + //- Do the two given vertices consitute a boundary point-pair + inline friend bool pointPair + ( + const indexedVertex& v0, + const indexedVertex& v1 + ) + { + return v0.index_ == v1.type_ || v1.index_ == v0.type_; + } + + //- Do the three given vertices consitute a boundary triangle + inline friend bool boundaryTriangle + ( + const indexedVertex& v0, + const indexedVertex& v1, + const indexedVertex& v2 + ) + { + return (v0.pairPoint() && pointPair(v1, v2)) + || (v1.pairPoint() && pointPair(v2, v0)) + || (v2.pairPoint() && pointPair(v0, v1)); + } + + //- Do the three given vertices consitute an outside triangle + inline friend bool outsideTriangle + ( + const indexedVertex& v0, + const indexedVertex& v1, + const indexedVertex& v2 + ) + { + return (v0.farPoint() || v0.ppSlave()) + || (v1.farPoint() || v1.ppSlave()) + || (v2.farPoint() || v2.ppSlave()); + } + +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace CGAL + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/applications/utilities/mesh/generation/cv2DMesh/insertBoundaryConformPointPairs.C b/applications/utilities/mesh/generation/cv2DMesh/insertBoundaryConformPointPairs.C new file mode 100644 index 0000000000000000000000000000000000000000..b4cf64091c92aa83937c057366d0b758401d9131 --- /dev/null +++ b/applications/utilities/mesh/generation/cv2DMesh/insertBoundaryConformPointPairs.C @@ -0,0 +1,323 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2007-2011 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*----------------------------------------------------------------------------*/ + +#include "CV2D.H" + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +void Foam::CV2D::insertPointPair +( + Triangulation::Finite_vertices_iterator& vit, + const point2D& p, + const label trii, + const label hitSurface +) +{ + if + ( + !meshControls().mirrorPoints() + || !insertMirrorPoint(toPoint2D(vit->point()), p) + ) + { + pointIndexHit pHit + ( + true, + toPoint3D(p), + trii + ); + + vectorField norm(1); + qSurf_.geometry()[hitSurface].getNormal + ( + List<pointIndexHit>(1, pHit), + norm + ); + + insertPointPair + ( + meshControls().ppDist(), + p, + toPoint2D(norm[0]) + ); + } + + vit = Triangulation::Finite_vertices_iterator + ( + CGAL::Filter_iterator + < + Triangulation::All_vertices_iterator, + Triangulation::Infinite_tester + >(finite_vertices_end(), vit.predicate(), vit.base()) + ); +} + + +bool Foam::CV2D::insertPointPairAtIntersection +( + Triangulation::Finite_vertices_iterator& vit, + const point2D& defVert, + const point2D vertices[], + const scalar maxProtSize2 +) +{ + bool found = false; + point2D interPoint; + label interTri = -1; + label interHitSurface = -1; + scalar interDist2 = 0; + + Face_circulator fcStart = incident_faces(vit); + Face_circulator fc = fcStart; + label vi = 0; + + do + { + if (!is_infinite(fc)) + { + pointIndexHit pHit; + label hitSurface = -1; + + qSurf_.findSurfaceNearestIntersection + ( + toPoint3D(defVert), + toPoint3D(vertices[vi]), + pHit, + hitSurface + ); + + if (pHit.hit()) + { + scalar dist2 = + magSqr(toPoint2D(pHit.hitPoint()) - vertices[vi]); + + // Check the point is further away than the furthest so far + if (dist2 > interDist2) + { + scalar mps2 = maxProtSize2; + + // If this is a boundary triangle reset the tolerance + // to avoid finding a hit point very close to a boundary + // vertex + if (boundaryTriangle(fc)) + { + mps2 = meshControls().maxNotchLen2(); + } + + if (dist2 > mps2) + { + found = true; + interPoint = toPoint2D(pHit.hitPoint()); + interTri = pHit.index(); + interDist2 = dist2; + interHitSurface = hitSurface; + } + } + } + + vi++; + } + } while (++fc != fcStart); + + if (found) + { + insertPointPair(vit, interPoint, interTri, interHitSurface); + return true; + } + else + { + return false; + } +} + + +Foam::label Foam::CV2D::insertBoundaryConformPointPairs +( + const fileName& fName +) +{ + label nIntersections = 0; + + for + ( + Triangulation::Finite_vertices_iterator vit = finite_vertices_begin(); + vit != finite_vertices_end(); + vit++ + ) + { + // Consider only those points part of point-pairs or near boundary + if (!vit->nearOrOnBoundary()) + { + continue; + } + + // Counter-clockwise circulator + Face_circulator fcStart = incident_faces(vit); + Face_circulator fc = fcStart; + + bool infinite = false; + bool changed = false; + + do + { + if (is_infinite(fc)) + { + infinite = true; + break; + } + else if (fc->faceIndex() < Fb::UNCHANGED) + { + changed = true; + break; + } + } while (++fc != fcStart); + + // If the dual-cell is connected to the infinite point or none of the + // faces whose circumcentres it uses have changed ignore + if (infinite || !changed) continue; + + fc = fcStart; + label nVerts = 0; + + do + { + vertices[nVerts++] = toPoint2D(circumcenter(fc)); + + if (nVerts == maxNvert) + { + break; + } + } while (++fc != fcStart); + + // Check if dual-cell has a large number of faces in which case + // assumed to be in the far-field and reject + if (nVerts == maxNvert) continue; + + // Set n+1 vertex to the first vertex for easy circulating + vertices[nVerts] = vertices[0]; + + // Convert triangle vertex to OpenFOAM point + point2DFromPoint defVert = toPoint2D(vit->point()); + + scalar maxProtSize2 = meshControls().maxNotchLen2(); + + if (vit->internalOrBoundaryPoint()) + { + // Calculate metrics of the dual-cell + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + // The perimeter of the dual-cell + scalar perimeter = 0; + + // Twice the area of the dual-cell + scalar areaT2 = 0; + + for (int vi=0; vi<nVerts; vi++) + { + vector2D edge(vertices[vi+1] - vertices[vi]); + perimeter += mag(edge); + vector2D otherEdge = defVert - vertices[vi]; + areaT2 += mag(edge.x()*otherEdge.y() - edge.y()*otherEdge.x()); + } + + // If the dual-cell is very small reject refinement + if (areaT2 < meshControls().minEdgeLen2()) continue; + + // Estimate the cell width + scalar cellWidth = areaT2/perimeter; + + + // Check dimensions of dual-cell + /* + // Quick rejection of dual-cell refinement based on it's perimeter + if (perimeter < 2*meshControls().minCellSize()) continue; + + // Also check the area of the cell and reject refinement + // if it is less than that allowed + if (areaT2 < meshControls().minCellSize2()) continue; + + // Estimate the cell width and reject refinement if it is less than + // that allowed + if (cellWidth < 0.5*meshControls().minEdgeLen()) continue; + */ + + if + ( + perimeter > 2*meshControls().minCellSize() + && areaT2 > meshControls().minCellSize2() + && cellWidth > 0.5*meshControls().minEdgeLen() + ) + { + maxProtSize2 = 0.25*meshControls().maxNotchLen2(); + } + } + + if (insertPointPairAtIntersection(vit, defVert, vertices, maxProtSize2)) + { + nIntersections++; + } + } + + return nIntersections; +} + + +void Foam::CV2D::markNearBoundaryPoints() +{ + label count = 0; + for + ( + Triangulation::Finite_vertices_iterator vit = finite_vertices_begin(); + vit != finite_vertices_end(); + vit++ + ) + { + if (vit->internalPoint()) + { + point vert(toPoint3D(vit->point())); + + pointIndexHit pHit; + label hitSurface = -1; + + qSurf_.findSurfaceNearest + ( + vert, + 4*meshControls().minCellSize2(), + pHit, + hitSurface + ); + + if (pHit.hit()) + { + vit->setNearBoundary(); + ++count; + } + } + } + + Info<< count << " points marked as being near a boundary" << endl; +} + + +// ************************************************************************* // diff --git a/applications/utilities/mesh/generation/cv2DMesh/insertFeaturePoints.C b/applications/utilities/mesh/generation/cv2DMesh/insertFeaturePoints.C new file mode 100644 index 0000000000000000000000000000000000000000..4765dc28bb9e847a1dbf229fa377729fbb8e3789 --- /dev/null +++ b/applications/utilities/mesh/generation/cv2DMesh/insertFeaturePoints.C @@ -0,0 +1,397 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2007-2011 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*----------------------------------------------------------------------------*/ + +#include "CV2D.H" +#include "plane.H" +#include "triSurfaceTools.H" +#include "unitConversion.H" + + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + + +bool Foam::CV2D::on2DLine(const point2D& p, const linePointRef& line) +{ + const point2D& a = toPoint2D(line.start()); + const point2D& b = toPoint2D(line.end()); + + if + ( + p.x() < min(a.x(), b.x()) + || p.x() > max(a.x(), b.x()) + || p.y() < min(a.y(), b.y()) + || p.y() > max(a.y(), b.y()) + ) + { + return false; + } + + return true; +} + + +// Create feature points/edges by creating a triplet in the corner. +// (this triplet will have as its circumcentre the feature) +void Foam::CV2D::insertFeaturePoints() +{ + featurePoints_.clear(); + label nVert = number_of_vertices(); + + const PtrList<extendedFeatureEdgeMesh>& feMeshes + ( + qSurf_.features() + ); + + if (feMeshes.empty()) + { + WarningIn("CV2D::insertFeaturePoints") + << "Extended Feature Edge Mesh is empty so no feature points will " + << "be found." << nl + << " Use: featureMethod extendedFeatureEdgeMesh;" << nl + << endl; + } + + forAll(feMeshes, i) + { + const extendedFeatureEdgeMesh& feMesh(feMeshes[i]); + const edgeList& edges = feMesh.edges(); + const pointField& points = feMesh.points(); + + if (debug) + { + label nConvex = feMesh.concaveStart() - feMesh.convexStart(); + label nConcave = feMesh.mixedStart() - feMesh.concaveStart(); + label nMixed = feMesh.nonFeatureStart() - feMesh.mixedStart(); + label nExternal = feMesh.internalStart() - feMesh.externalStart(); + label nInternal = feMesh.flatStart() - feMesh.internalStart(); + label nFlat = feMesh.openStart() - feMesh.flatStart(); + label nOpen = feMesh.multipleStart() - feMesh.openStart(); + label nMultiple = edges.size() - feMesh.multipleStart(); + + Info<< "Inserting Feature Points:" << nl + << " Convex points: " << nConvex << nl + << " Concave points: " << nConcave << nl + << " Mixed points: " << nMixed << nl + << " External edges: " << nExternal << nl + << " Internal edges: " << nInternal << nl + << " Flat edges: " << nFlat << nl + << " Open edges: " << nOpen << nl + << " Multiple edges: " << nMultiple << endl; + } + + // Args: (base point, normal) + // @todo allow user to input this + plane zPlane(vector(0, 0, z_), vector(0, 0, 1)); + + if (debug) + { + Info<< " plane: " << zPlane << " " << z_ << endl; + } + + forAll(edges, edgeI) + { + const edge& e = feMesh.edges()[edgeI]; + + const point& ep0 = points[e.start()]; + const point& ep1 = points[e.end()]; + + const linePointRef line(ep0, ep1); + + scalar intersect = zPlane.lineIntersect(line); + + point2D featPoint = toPoint2D(intersect * (ep1 - ep0) + ep0); + + if (on2DLine(featPoint, line)) + { + vector2DField fpn = toPoint2D(feMesh.edgeNormals(edgeI)); + + vector2D cornerNormal = sum(fpn); + cornerNormal /= mag(cornerNormal); + + if (debug) + { + Info<< nl << " line: " << line << nl + << " vec: " << line.vec() << nl + << " featurePoint: " << featPoint << nl + << " line length: " << line.mag() << nl + << " intersect: " << intersect << endl; + } + + if + ( + feMesh.getEdgeStatus(edgeI) + == extendedFeatureEdgeMesh::EXTERNAL + ) + { + // Convex Point + Foam::point2D internalPt = + featPoint - meshControls().ppDist()*cornerNormal; + + if (debug) + { + Info<< "PREC: " << internalPt << nl + << " : " << featPoint << nl + << " : " << meshControls().ppDist() << nl + << " : " << cornerNormal << endl; + } + + featurePoints_.push_back + ( + Vb + ( + toPoint(internalPt), + nVert, + nVert + 1 + ) + ); + label masterPtIndex = nVert++; + + forAll(fpn, nI) + { + const vector n3D(fpn[nI][0], fpn[nI][1], 0.0); + + plane planeN = plane(toPoint3D(featPoint), n3D); + + Foam::point2D externalPt = + internalPt + + ( + 2.0 + * planeN.distance(toPoint3D(internalPt)) + * fpn[nI] + ); + + featurePoints_.push_back + ( + Vb + ( + toPoint(externalPt), + nVert++, + masterPtIndex + ) + ); + + if (debug) + { + Info<< " side point: " << externalPt << endl; + } + } + + if (debug) + { + Info<< "Convex Point: " << featPoint << nl + << " corner norm: " << cornerNormal << nl + << " reference: " << internalPt << endl; + } + } + else if + ( + feMesh.getEdgeStatus(edgeI) + == extendedFeatureEdgeMesh::INTERNAL + ) + { + // Concave Point + Foam::point2D externalPt = + featPoint + meshControls().ppDist()*cornerNormal; + + Foam::point2D refPt = + featPoint - meshControls().ppDist()*cornerNormal; + + label slavePointIndex = 0; + + scalar totalAngle = + radToDeg + ( + constant::mathematical::pi + + acos(mag(fpn[0] & fpn[1])) + ); + + // Number of quadrants the angle should be split into + int nQuads = + int(totalAngle/meshControls().maxQuadAngle()) + 1; + + // The number of additional master points needed to + //obtain the required number of quadrants. + int nAddPoints = min(max(nQuads - 2, 0), 2); + + // index of reflMaster + label reflectedMaster = nVert + 2 + nAddPoints; + + if (debug) + { + Info<< "Concave Point: " << featPoint << nl + << " corner norm: " << cornerNormal << nl + << " external: " << externalPt << nl + << " reference: " << refPt << nl + << " angle: " << totalAngle << nl + << " nQuads: " << nQuads << nl + << " nAddPoints: " << nAddPoints << endl; + } + + forAll(fpn, nI) + { + const vector n3D(fpn[nI][0], fpn[nI][1], 0.0); + + plane planeN = plane(toPoint3D(featPoint), n3D); + + Foam::point2D internalPt = + externalPt + - ( + 2.0 + * planeN.distance(toPoint3D(externalPt)) + * fpn[nI] + ); + + featurePoints_.push_back + ( + Vb + ( + toPoint(internalPt), + nVert, + reflectedMaster + ) + ); + slavePointIndex = nVert++; + + if (debug) + { + Info<< "Internal Point: " << internalPt << endl; + } + } + + if (nAddPoints == 1) + { + // One additional point is the reflection of the slave + // point, i.e., the original reference point + featurePoints_.push_back + ( + Vb + ( + toPoint(refPt), + nVert++, + reflectedMaster + ) + ); + + if (debug) + { + Info<< "ref Point: " << refPt << endl; + } + } + else if (nAddPoints == 2) + { + point2D reflectedAa = + refPt - ((featPoint - externalPt) & fpn[1])*fpn[1]; + + featurePoints_.push_back + ( + Vb + ( + toPoint(reflectedAa), + nVert++, + reflectedMaster + ) + ); + + point2D reflectedBb = + refPt - ((featPoint - externalPt) & fpn[0])*fpn[0]; + + featurePoints_.push_back + ( + Vb + ( + toPoint(reflectedBb), + nVert++, + reflectedMaster + ) + ); + + if (debug) + { + Info<< "refA Point: " << reflectedAa << nl + << "refb Point: " << reflectedBb << endl; + } + } + + featurePoints_.push_back + ( + Vb + ( + toPoint(externalPt), + nVert++, + slavePointIndex + ) + ); + } + else + { + WarningIn("void Foam::CV2D::insertFeaturePoints()") + << "Feature Edge " << edges[edgeI] << nl + << " points(" << points[edges[edgeI].start()] + << ", " << points[edges[edgeI].end()] << ")" << nl + << " is not labelled as either concave or convex, it" + << " is labelled as (#2 = flat): " + << feMesh.getEdgeStatus(edgeI) << endl; + } + } + else + { + WarningIn("void Foam::CV2D::insertFeaturePoints()") + << "Point " << featPoint << " is not on the line " + << line << endl; + } + } + } + + // Insert the feature points. + reinsertFeaturePoints(); + + if (meshControls().objOutput()) + { + writePoints("feat_allPoints.obj", false); + writeFaces("feat_allFaces.obj", false); + writeFaces("feat_faces.obj", true); + writeTriangles("feat_triangles.obj", true); + } +} + + +void Foam::CV2D::reinsertFeaturePoints() +{ + for + ( + std::list<Vb>::iterator vit=featurePoints_.begin(); + vit != featurePoints_.end(); + ++vit + ) + { + insertPoint + ( + toPoint2D(vit->point()), + vit->index(), + vit->type() + ); + } +} +// ************************************************************************* // diff --git a/applications/utilities/mesh/generation/cv2DMesh/insertSurfaceNearPointPairs.C b/applications/utilities/mesh/generation/cv2DMesh/insertSurfaceNearPointPairs.C new file mode 100644 index 0000000000000000000000000000000000000000..0773e41138dc75e0940c4f759d60bfb595fd6f34 --- /dev/null +++ b/applications/utilities/mesh/generation/cv2DMesh/insertSurfaceNearPointPairs.C @@ -0,0 +1,114 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2007-2011 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*----------------------------------------------------------------------------*/ + +#include "CV2D.H" + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +void Foam::CV2D::insertSurfaceNearPointPairs() +{ + Info<< "insertSurfaceNearPointPairs: "; + + label nNearPoints = 0; + + for + ( + Triangulation::Finite_edges_iterator eit = finite_edges_begin(); + eit != finite_edges_end(); + eit++ + ) + { + Vertex_handle v0h = eit->first->vertex(cw(eit->second)); + Vertex_handle v1h = eit->first->vertex(ccw(eit->second)); + + if (v0h->ppMaster() && v1h->ppMaster()) + { + point2DFromPoint v0(toPoint2D(v0h->point())); + point2DFromPoint v1(toPoint2D(v1h->point())); + + // Check that the two triangle vertices are further apart than the + // minimum cell size + if (magSqr(v1 - v0) > meshControls().minCellSize2()) + { + point2D e0(toPoint2D(circumcenter(eit->first))); + + point2D e1 + ( + toPoint2D(circumcenter(eit->first->neighbor(eit->second))) + ); + + // Calculate the length^2 of the edge normal to the surface + scalar edgeLen2 = magSqr(e0 - e1); + + if (edgeLen2 < meshControls().minNearPointDist2()) + { + pointIndexHit pHit; + label hitSurface = -1; + + qSurf_.findSurfaceNearest + ( + toPoint3D(e0), + meshControls().minEdgeLen2(), + pHit, + hitSurface + ); + + if (pHit.hit()) + { + vectorField norm(1); + qSurf_.geometry()[hitSurface].getNormal + ( + List<pointIndexHit>(1, pHit), + norm + ); + + insertPointPair + ( + meshControls().ppDist(), + toPoint2D(pHit.hitPoint()), + toPoint2D(norm[0]) + ); + + nNearPoints++; + + // Correct the edge iterator for the change in the + // number of edges following the point-pair insertion + eit = Finite_edges_iterator + ( + finite_edges_end().base(), + eit.predicate(), + eit.base() + ); + } + } + } + } + } + + Info<< nNearPoints << " point-pairs inserted" << endl; +} + + +// ************************************************************************* // diff --git a/applications/utilities/mesh/generation/cv2DMesh/insertSurfaceNearestPointPairs.C b/applications/utilities/mesh/generation/cv2DMesh/insertSurfaceNearestPointPairs.C new file mode 100644 index 0000000000000000000000000000000000000000..e04955ab0886f9886e2c6f9865505f8e069233e3 --- /dev/null +++ b/applications/utilities/mesh/generation/cv2DMesh/insertSurfaceNearestPointPairs.C @@ -0,0 +1,244 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2007-2011 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*----------------------------------------------------------------------------*/ + +#include "CV2D.H" + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +bool Foam::CV2D::dualCellSurfaceIntersection +( + const Triangulation::Finite_vertices_iterator& vit +) const +{ + Triangulation::Edge_circulator ecStart = incident_edges(vit); + Triangulation::Edge_circulator ec = ecStart; + + do + { + if (!is_infinite(ec)) + { + point e0 = toPoint3D(circumcenter(ec->first)); + + // If edge end is outside bounding box then edge cuts boundary + if (!qSurf_.globalBounds().contains(e0)) + { + return true; + } + + point e1 = toPoint3D(circumcenter(ec->first->neighbor(ec->second))); + + // If other edge end is ouside bounding box then edge cuts boundary + if (!qSurf_.globalBounds().contains(e1)) + { + return true; + } + + if (magSqr(e1 - e0) > meshControls().minEdgeLen2()) + { + if (qSurf_.findSurfaceAnyIntersection(e0, e1)) + { + return true; + } + } + } + + } while (++ec != ecStart); + + return false; +} + + +void Foam::CV2D::insertPointPairs +( + const DynamicList<point2D>& nearSurfacePoints, + const DynamicList<point2D>& surfacePoints, + const DynamicList<label>& surfaceTris, + const DynamicList<label>& surfaceHits, + const fileName fName +) +{ + if (meshControls().mirrorPoints()) + { + forAll(surfacePoints, ppi) + { + insertMirrorPoint + ( + nearSurfacePoints[ppi], + surfacePoints[ppi] + ); + } + } + else + { + forAll(surfacePoints, ppi) + { + pointIndexHit pHit + ( + true, + toPoint3D(surfacePoints[ppi]), + surfaceTris[ppi] + ); + + vectorField norm(1); + qSurf_.geometry()[surfaceHits[ppi]].getNormal + ( + List<pointIndexHit>(1, pHit), + norm + ); + + insertPointPair + ( + meshControls().ppDist(), + surfacePoints[ppi], + toPoint2D(norm[0]) + ); + } + } + + Info<< surfacePoints.size() << " point-pairs inserted" << endl; + + if (meshControls().objOutput()) + { + OFstream str(fName); + label vertI = 0; + + forAll(surfacePoints, ppi) + { + meshTools::writeOBJ(str, toPoint3D(surfacePoints[ppi])); + vertI++; + } + + Info<< "insertPointPairs: Written " << surfacePoints.size() + << " inserted point-pair locations to file " + << str.name() << endl; + } +} + + +void Foam::CV2D::insertSurfaceNearestPointPairs() +{ + Info<< "insertSurfaceNearestPointPairs: "; + + label nSurfacePointsEst = + min + ( + number_of_vertices(), + size_t(10*sqrt(scalar(number_of_vertices()))) + ); + + DynamicList<point2D> nearSurfacePoints(nSurfacePointsEst); + DynamicList<point2D> surfacePoints(nSurfacePointsEst); + DynamicList<label> surfaceTris(nSurfacePointsEst); + DynamicList<label> surfaceHits(nSurfacePointsEst); + + // Local references to surface mesh addressing +// const pointField& localPoints = qSurf_.localPoints(); +// const labelListList& edgeFaces = qSurf_.edgeFaces(); +// const vectorField& faceNormals = qSurf_.faceNormals(); +// const labelListList& faceEdges = qSurf_.faceEdges(); + + for + ( + Triangulation::Finite_vertices_iterator vit = finite_vertices_begin(); + vit != finite_vertices_end(); + vit++ + ) + { + if (vit->internalPoint()) + { + point2DFromPoint vert(toPoint2D(vit->point())); + + pointIndexHit pHit; + label hitSurface = -1; + + qSurf_.findSurfaceNearest + ( + toPoint3D(vert), + 4*meshControls().minCellSize2(), + pHit, + hitSurface + ); + + if (pHit.hit()) + { + vit->setNearBoundary(); + + // Reference to the nearest triangle +// const labelledTri& f = qSurf_[hitSurface]; + +// // Find where point is on triangle. +// // Note tolerance needed is relative one +// // (used in comparing normalized [0..1] triangle coordinates). +// label nearType, nearLabel; +// triPointRef +// ( +// localPoints[f[0]], +// localPoints[f[1]], +// localPoints[f[2]] +// ).classify(pHit.hitPoint(), nearType, nearLabel); + +// // If point is on a edge check if it is an internal feature + +// bool internalFeatureEdge = false; + +// if (nearType == triPointRef::EDGE) +// { +// label edgeI = faceEdges[hitSurface][nearLabel]; +// const labelList& eFaces = edgeFaces[edgeI]; + +// if +// ( +// eFaces.size() == 2 +// && (faceNormals[eFaces[0]] & faceNormals[eFaces[1]]) +// < -0.2 +// ) +// { +// internalFeatureEdge = true; +// } +// } + + if (dualCellSurfaceIntersection(vit)) //&& !internalFeatureEdge) + { + nearSurfacePoints.append(vert); + surfacePoints.append(toPoint2D(pHit.hitPoint())); + surfaceTris.append(pHit.index()); + surfaceHits.append(hitSurface); + } + } + } + } + + insertPointPairs + ( + nearSurfacePoints, + surfacePoints, + surfaceTris, + surfaceHits, + "surfaceNearestIntersections.obj" + ); +} + + +// ************************************************************************* // diff --git a/applications/utilities/mesh/generation/cv2DMesh/shortEdgeFilter2D.C b/applications/utilities/mesh/generation/cv2DMesh/shortEdgeFilter2D.C new file mode 100644 index 0000000000000000000000000000000000000000..5e960cb558fe3118f9eaf3df280c6be05a69d965 --- /dev/null +++ b/applications/utilities/mesh/generation/cv2DMesh/shortEdgeFilter2D.C @@ -0,0 +1,505 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms_ of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "shortEdgeFilter2D.H" + +namespace Foam +{ + +defineTypeNameAndDebug(shortEdgeFilter2D, 0); + +} + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::shortEdgeFilter2D::shortEdgeFilter2D +( + const Foam::CV2D& cv2Dmesh, + const dictionary& dict +) +: + cv2Dmesh_(cv2Dmesh), + shortEdgeFilterFactor_(readScalar(dict.lookup("shortEdgeFilterFactor"))), + edgeAttachedToBoundaryFactor_ + ( + dict.lookupOrDefault<scalar>("edgeAttachedToBoundaryFactor", 2.0) + ), + patchNames_(wordList()), + patchSizes_(labelList()), + mapEdgesRegion_() +{ + point2DField points2D; + faceList faces; + + cv2Dmesh.calcDual + ( + points2D, + faces, + patchNames_, + patchSizes_, + mapEdgesRegion_ + ); + + pointField points(points2D.size()); + forAll(points, ip) + { + points[ip] = cv2Dmesh.toPoint3D(points2D[ip]); + } + + points2D.clear(); + + ms_ = MeshedSurface<face>(xferMove(points), xferMove(faces)); + + Info<< "Meshed surface stats before edge filtering :" << endl; + ms_.writeStats(Info); + + if (debug) + { + writeInfo(Info); + + ms_.write("MeshedSurface_preFilter.obj"); + } +} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::shortEdgeFilter2D::~shortEdgeFilter2D() +{} + + +// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // + +void +Foam::shortEdgeFilter2D::filter() +{ + // These are global indices. + const pointField& points = ms_.points(); + const edgeList& edges = ms_.edges(); + const faceList& faces = ms_.faces(); + const labelList& meshPoints = ms_.meshPoints(); + const labelList& boundaryPoints = ms_.boundaryPoints(); + + label maxChain = 0; + label nPointsToRemove = 0; + + labelList pointsToRemove(ms_.points().size(), -1); + + // List of number of vertices in a face. + labelList newFaceVertexCount(faces.size(), -1); + forAll(faces, faceI) + { + newFaceVertexCount[faceI] = faces[faceI].size(); + } + + // Check if the point is a boundary point. Flag if it is so that + // it will not be deleted. + boolList boundaryPointFlags(points.size(), false); + // This has been removed, otherwise small edges on the boundary are not + // removed. + /* forAll(boundaryPointFlags, pointI) + { + forAll(boundaryPoints, bPoint) + { + if (meshPoints[boundaryPoints[bPoint]] == pointI) + { + boundaryPointFlags[pointI] = true; + } + } + }*/ + + // Check if an edge has a boundary point. It it does the edge length + // will be doubled when working out its length. + Info<< " Marking edges attached to boundaries." << endl; + boolList edgeAttachedToBoundary(edges.size(), false); + forAll(edges, edgeI) + { + const edge& e = edges[edgeI]; + const label startVertex = e.start(); + const label endVertex = e.end(); + + forAll(boundaryPoints, bPoint) + { + if + ( + boundaryPoints[bPoint] == startVertex + || boundaryPoints[bPoint] == endVertex + ) + { + edgeAttachedToBoundary[edgeI] = true; + } + } + } + + forAll(edges, edgeI) + { + const edge& e = edges[edgeI]; + + // get the vertices of that edge. + const label startVertex = e.start(); + const label endVertex = e.end(); + + scalar edgeLength = + mag + ( + points[meshPoints[e.start()]] + - points[meshPoints[e.end()]] + ); + + if (edgeAttachedToBoundary[edgeI]) + { + edgeLength *= edgeAttachedToBoundaryFactor_; + } + + scalar shortEdgeFilterValue = 0.0; + + const labelList& psEdges = ms_.pointEdges()[startVertex]; + const labelList& peEdges = ms_.pointEdges()[endVertex]; + + forAll(psEdges, psEdgeI) + { + const edge& psE = edges[psEdges[psEdgeI]]; + if (edgeI != psEdges[psEdgeI]) + { + shortEdgeFilterValue += + mag + ( + points[meshPoints[psE.start()]] + -points[meshPoints[psE.end()]] + ); + } + } + + forAll(peEdges, peEdgeI) + { + const edge& peE = edges[peEdges[peEdgeI]]; + if (edgeI != peEdges[peEdgeI]) + { + shortEdgeFilterValue += + mag + ( + points[meshPoints[peE.start()]] + -points[meshPoints[peE.end()]] + ); + } + } + + shortEdgeFilterValue *= + shortEdgeFilterFactor_ + /(psEdges.size() + peEdges.size() - 2); + + if (edgeLength < shortEdgeFilterValue) + { + bool flagDegenerateFace = false; + const labelList& pFaces = ms_.pointFaces()[startVertex]; + + forAll(pFaces, pFaceI) + { + const face& f = ms_.localFaces()[pFaces[pFaceI]]; + forAll(f, fp) + { + // If the edge is part of this face... + if (f[fp] == endVertex) + { + // If deleting vertex would create a triangle, don't! + if (newFaceVertexCount[pFaces[pFaceI]] < 4) + { + flagDegenerateFace = true; + } + else + { + newFaceVertexCount[pFaces[pFaceI]]--; + } + } + // If the edge is not part of this face... + else + { + // Deleting vertex of a triangle... + if (newFaceVertexCount[pFaces[pFaceI]] < 3) + { + flagDegenerateFace = true; + } + } + } + } + + // This if statement determines whether a point should be deleted. + if + ( + pointsToRemove[meshPoints[startVertex]] == -1 + && pointsToRemove[meshPoints[endVertex]] == -1 + && !boundaryPointFlags[meshPoints[startVertex]] + && !flagDegenerateFace + ) + { + pointsToRemove[meshPoints[startVertex]] = + meshPoints[endVertex]; + ++nPointsToRemove; + } + } + } + + label totalNewPoints = points.size() - nPointsToRemove; + + pointField newPoints(totalNewPoints, vector(0, 0, 0)); + labelList newPointNumbers(points.size(), -1); + label numberRemoved=0; + + forAll(points, pointI) + { + // If the point is NOT going to be removed. + if (pointsToRemove[pointI] == -1) + { + newPoints[pointI-numberRemoved] = points[pointI]; + newPointNumbers[pointI] = pointI-numberRemoved; + } + else + { + numberRemoved++; + } + } + + // Need a new faceList + faceList newFaces(faces.size()); + label newFaceI = 0; + + labelList newFace; + label newFaceSize = 0; + + // Now need to iterate over the faces and remove points. Global index. + forAll(faces, faceI) + { + const face& f = faces[faceI]; + + newFace.clear(); + newFace.setSize(f.size()); + newFaceSize = 0; + + forAll(f, fp) + { + label pointI = f[fp]; + // If not removing the point, then add it to the new face. + if (pointsToRemove[pointI] == -1) + { + newFace[newFaceSize++] = newPointNumbers[pointI]; + } + else + { + label newPointI = pointsToRemove[pointI]; + // Replace deleted point with point that it is being + // collapsed to. + if + ( + f.nextLabel(fp) != newPointI + && f.prevLabel(fp) != newPointI + ) + { + label pChain = newPointI; + label totalChain = 0; + for (label nChain = 0; nChain <= totalChain; ++nChain) + { + if (newPointNumbers[pChain] != -1) + { + newFace[newFaceSize++] = newPointNumbers[pChain]; + newPointNumbers[pointI] + = newPointNumbers[pChain]; + maxChain = max(totalChain, maxChain); + } + else + { + WarningIn("shortEdgeFilter") + << "Point " << pChain + << " marked for deletion as well as point " + << pointI << nl + << " Incrementing maxChain by 1 from " + << totalChain << " to " << totalChain + 1 + << endl; + totalChain++; + } + pChain = pointsToRemove[pChain]; + } + } + else + { + if (newPointNumbers[newPointI] != -1) + { + newPointNumbers[pointI] = newPointNumbers[newPointI]; + } + } + } + } + + newFace.setSize(newFaceSize); + + if (newFace.size() > 2) + { + newFaces[newFaceI++] = face(newFace); + } + else + { + FatalErrorIn("shortEdgeFilter") + << "Only " << newFace.size() << " in face " << faceI + << exit(FatalError); + } + } + + newFaces.setSize(newFaceI); + + MeshedSurface<face> fMesh + ( + xferMove(newPoints), + xferMove(newFaces), + xferCopy(List<surfZone>()) + ); + + const Map<int>& fMeshPointMap = fMesh.meshPointMap(); + + // Reset patchSizes_ + patchSizes_.clear(); + patchSizes_.setSize(patchNames_.size(), 0); + + label equalEdges = 0; + label notFound = 0; + label matches = 0; + label negativeLabels = 0; + + forAll(newPointNumbers, pointI) + { + if (newPointNumbers[pointI] == -1) + { + WarningIn("shortEdgeFilter") + << pointI << " will be deleted and " << newPointNumbers[pointI] + << ", so it will not be replaced. " + << "This will cause edges to be deleted." << endl; + } + } + + // Create new EdgeMap. + Info<< "Creating new EdgeMap." << endl; + EdgeMap<label> newMapEdgesRegion(mapEdgesRegion_.size()); + + for + ( + label bEdgeI = ms_.nInternalEdges(); + bEdgeI < edges.size(); + ++bEdgeI + ) + { + label p1 = meshPoints[edges[bEdgeI][0]]; + label p2 = meshPoints[edges[bEdgeI][1]]; + + edge e(p1, p2); + + if (mapEdgesRegion_.found(e)) + { + if + ( + newPointNumbers[p1] != -1 + && newPointNumbers[p2] != -1 + ) + { + if (newPointNumbers[p1] != newPointNumbers[p2]) + { + label region = mapEdgesRegion_.find(e)(); + newMapEdgesRegion.insert + ( + edge + ( + fMeshPointMap[newPointNumbers[p1]], + fMeshPointMap[newPointNumbers[p2]] + ), + region + ); + patchSizes_[region]++; + matches++; + } + else + { + equalEdges++; + } + } + else + { + negativeLabels++; + } + } + else + { + notFound++; + } + } + + if (debug) + { + Info<< "EdgeMapping :" << nl + << " Matches : " << matches << nl + << " Equal : " << equalEdges << nl + << " Negative : " << negativeLabels << nl + << " Not Found: " << notFound << endl; + } + + mapEdgesRegion_.transfer(newMapEdgesRegion); + + ms_.transfer(fMesh); + + Info<< " Maximum number of chained collapses = " << maxChain << endl; + + if (debug) + { + writeInfo(Info); + } +} + + +void Foam::shortEdgeFilter2D::writeInfo(Ostream& os) +{ + os << "Short Edge Filtering Information:" << nl + << " shortEdgeFilterFactor: " << shortEdgeFilterFactor_ << nl + << " edgeAttachedToBoundaryFactor: " << edgeAttachedToBoundaryFactor_ + << endl; + + forAll(patchNames_, patchI) + { + os << " Patch " << patchNames_[patchI] + << ", size " << patchSizes_[patchI] << endl; + } + + os << " There are " << mapEdgesRegion_.size() + << " boundary edges." << endl; + + os << " Mesh Info:" << nl + << " Points: " << ms_.nPoints() << nl + << " Faces: " << ms_.size() << nl + << " Edges: " << ms_.nEdges() << nl + << " Internal: " << ms_.nInternalEdges() << nl + << " External: " << ms_.nEdges() - ms_.nInternalEdges() + << endl; +} + + +// ************************************************************************* // diff --git a/applications/utilities/mesh/generation/cv2DMesh/shortEdgeFilter2D.H b/applications/utilities/mesh/generation/cv2DMesh/shortEdgeFilter2D.H new file mode 100644 index 0000000000000000000000000000000000000000..1a100bcb200d6dd604f4fa25bd2a3dc904cf3989 --- /dev/null +++ b/applications/utilities/mesh/generation/cv2DMesh/shortEdgeFilter2D.H @@ -0,0 +1,136 @@ +/*--------------------------------*- C++ -*----------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011-2011 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::shortEdgeFilter2D + +Description + This class filters short edges generated by the CV2D mesher. + +SourceFiles + shortEdgeFilter2D.C + +\*---------------------------------------------------------------------------*/ + +#ifndef shortEdgeFilter2D_H +#define shortEdgeFilter2D_H + +#include "MeshedSurfaces.H" +#include "CV2D.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class shortEdgeFilter2D Declaration +\*---------------------------------------------------------------------------*/ + +class shortEdgeFilter2D +{ + // Private data + + //- Description of data_ + const CV2D& cv2Dmesh_; + + MeshedSurface<face> ms_; + + const scalar shortEdgeFilterFactor_; + + const scalar edgeAttachedToBoundaryFactor_; + + wordList patchNames_; + + labelList patchSizes_; + + EdgeMap<label> mapEdgesRegion_; + + + // Private Member Functions + + //- Disallow default bitwise copy construct + shortEdgeFilter2D(const shortEdgeFilter2D&); + + //- Disallow default bitwise assignment + void operator=(const shortEdgeFilter2D&); + + +public: + + //- Runtime type information + ClassName("shortEdgeFilter2D"); + + // Constructors + + shortEdgeFilter2D + ( + const CV2D& cv2Dmesh, + const dictionary& dict + ); + + + //- Destructor + ~shortEdgeFilter2D(); + + + // Access Functions + + const wordList& patchNames() const + { + return patchNames_; + } + + const labelList& patchSizes() const + { + return patchSizes_; + } + + const EdgeMap<label>& mapEdgesRegion() const + { + return mapEdgesRegion_; + } + + const MeshedSurface<face>& fMesh() const + { + return ms_; + } + + // Member Functions + + void filter(); + + void writeInfo(Ostream& os); + +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/applications/utilities/mesh/generation/cvMesh/changesLaurence b/applications/utilities/mesh/generation/cvMesh/changesLaurence new file mode 100644 index 0000000000000000000000000000000000000000..5f55eff4624d66db182879be4d9a515a9c1ac581 --- /dev/null +++ b/applications/utilities/mesh/generation/cvMesh/changesLaurence @@ -0,0 +1,5 @@ +wmake/rules/General/CGAL + + -lboost_thread + -lboost_thread-mt + diff --git a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeControlSurfaces.C b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeControlSurfaces.C index 8f7ed466732363fe5f9e54131bf5f3781239ac69..0fa17fc86aeabf8e950ea5c791a7e17e178e0da1 100644 --- a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeControlSurfaces.C +++ b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeControlSurfaces.C @@ -152,12 +152,10 @@ bool Foam::cellSizeControlSurfaces::evalCellSizeFunctions Foam::cellSizeControlSurfaces::cellSizeControlSurfaces ( - const conformalVoronoiMesh& cvMesh, const searchableSurfaces& allGeometry, const dictionary& motionControlDict ) : - cvMesh_(cvMesh), allGeometry_(allGeometry), surfaces_(), cellSizeFunctions_(), @@ -223,7 +221,6 @@ Foam::cellSizeControlSurfaces::cellSizeControlSurfaces cellSizeFunction::New ( surfaceSubDict, - cvMesh, surface ) ); @@ -284,40 +281,41 @@ Foam::scalar Foam::cellSizeControlSurfaces::cellSize { scalar size = defaultCellSize_; - bool anyFunctionFound = evalCellSizeFunctions(pt, size); - - if (!anyFunctionFound) - { - // Check if the point in question was actually inside the domain, if - // not, then it may be falling back to an inappropriate default size. - - if (cvMesh_.geometryToConformTo().outside(pt)) - { - pointIndexHit surfHit; - label hitSurface; - - cvMesh_.geometryToConformTo().findSurfaceNearest - ( - pt, - sqr(GREAT), - surfHit, - hitSurface - ); - - if (!surfHit.hit()) - { - FatalErrorIn - ( - "Foam::scalar Foam::cellSizeControlSurfaces::cellSize" - "(" - "const point& pt" - ") const" - ) - << "Point " << pt << " did not find a nearest surface point" - << nl << exit(FatalError) << endl; - } - } - } +// bool anyFunctionFound = evalCellSizeFunctions(pt, size); + evalCellSizeFunctions(pt, size); + +//if (!anyFunctionFound) +//{ +// // Check if the point in question was actually inside the domain, if +// // not, then it may be falling back to an inappropriate default size. + +// if (cvMesh_.geometryToConformTo().outside(pt)) +// { +// pointIndexHit surfHit; +// label hitSurface; + +// cvMesh_.geometryToConformTo().findSurfaceNearest +// ( +// pt, +// sqr(GREAT), +// surfHit, +// hitSurface +// ); + +// if (!surfHit.hit()) +// { +// FatalErrorIn +// ( +// "Foam::scalar Foam::cellSizeControlSurfaces::cellSize" +// "(" +// "const point& pt" +// ") const" +// ) +// << "Point " << pt << " did not find a nearest surface point" +// << nl << exit(FatalError) << endl; +// } +// } +//} return size; } diff --git a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeControlSurfaces.H b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeControlSurfaces.H index 17dfd10325bf73d011b6f27c0092f4836e1901f6..4b6c53bc2acb1eae64104a600358f67585e159dc 100644 --- a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeControlSurfaces.H +++ b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeControlSurfaces.H @@ -57,9 +57,6 @@ class cellSizeControlSurfaces { // Private data - //- Reference to the conformalVoronoiMesh holding this object - const conformalVoronoiMesh& cvMesh_; - //- Reference to the searchableSurfaces object holding all geometry data const searchableSurfaces& allGeometry_; @@ -106,7 +103,6 @@ public: // searchableSurfaces cellSizeControlSurfaces ( - const conformalVoronoiMesh& cvMesh, const searchableSurfaces& allGeometry, const dictionary& motionControlDict ); diff --git a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeFunction/cellSizeFunction/cellSizeFunction.C b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeFunction/cellSizeFunction/cellSizeFunction.C index 9d7cc3084ab5ee02cdf4b5c978a25589dd43c0ba..37d6c7825ae74b4df60a6e540f9332a443efc41a 100644 --- a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeFunction/cellSizeFunction/cellSizeFunction.C +++ b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeFunction/cellSizeFunction/cellSizeFunction.C @@ -45,12 +45,10 @@ cellSizeFunction::cellSizeFunction ( const word& type, const dictionary& cellSizeFunctionDict, - const conformalVoronoiMesh& cvMesh, const searchableSurface& surface ) : dictionary(cellSizeFunctionDict), - cvMesh_(cvMesh), surface_(surface), coeffsDict_(subDict(type + "Coeffs")), sideMode_(), @@ -99,7 +97,6 @@ cellSizeFunction::cellSizeFunction autoPtr<cellSizeFunction> cellSizeFunction::New ( const dictionary& cellSizeFunctionDict, - const conformalVoronoiMesh& cvMesh, const searchableSurface& surface ) { @@ -130,7 +127,7 @@ autoPtr<cellSizeFunction> cellSizeFunction::New return autoPtr<cellSizeFunction> ( - cstrIter()(cellSizeFunctionDict, cvMesh, surface) + cstrIter()(cellSizeFunctionDict, surface) ); } diff --git a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeFunction/cellSizeFunction/cellSizeFunction.H b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeFunction/cellSizeFunction/cellSizeFunction.H index 82535194a85e63a7c52cae10d534bdfa3d6299e9..6b33ec7ca7714c676d04e39a636f439e29da817a 100644 --- a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeFunction/cellSizeFunction/cellSizeFunction.H +++ b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeFunction/cellSizeFunction/cellSizeFunction.H @@ -81,9 +81,6 @@ protected: // Protected data - //- Reference to the conformalVoronoiMesh holding this cvs object - const conformalVoronoiMesh& cvMesh_; - //- Reference to the searchableSurface that cellSizeFunction // relates to const searchableSurface& surface_; @@ -120,10 +117,9 @@ public: dictionary, ( const dictionary& cellSizeFunctionDict, - const conformalVoronoiMesh& cvMesh, const searchableSurface& surface ), - (cellSizeFunctionDict, cvMesh, surface) + (cellSizeFunctionDict, surface) ); @@ -134,7 +130,6 @@ public: ( const word& type, const dictionary& cellSizeFunctionDict, - const conformalVoronoiMesh& cvMesh, const searchableSurface& surface ); @@ -145,7 +140,6 @@ public: static autoPtr<cellSizeFunction> New ( const dictionary& cellSizeFunctionDict, - const conformalVoronoiMesh& cvMesh, const searchableSurface& surface ); diff --git a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeFunction/linearDistance/linearDistance.C b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeFunction/linearDistance/linearDistance.C index 702ac53bc6827e864a6c72a8d4e9b23069f89f0f..0874d9fc8231a9745f923ff4039aac41139cd4bc 100644 --- a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeFunction/linearDistance/linearDistance.C +++ b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeFunction/linearDistance/linearDistance.C @@ -42,11 +42,10 @@ addToRunTimeSelectionTable(cellSizeFunction, linearDistance, dictionary); linearDistance::linearDistance ( const dictionary& initialPointsDict, - const conformalVoronoiMesh& cvMesh, const searchableSurface& surface ) : - cellSizeFunction(typeName, initialPointsDict, cvMesh, surface), + cellSizeFunction(typeName, initialPointsDict, surface), surfaceCellSize_(readScalar(coeffsDict().lookup("surfaceCellSize"))), distanceCellSize_(readScalar(coeffsDict().lookup("distanceCellSize"))), distance_(readScalar(coeffsDict().lookup("distance"))), diff --git a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeFunction/linearDistance/linearDistance.H b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeFunction/linearDistance/linearDistance.H index 9799a1f7d069eb61859fed0c3240348df6ead35f..0906680150b6e0d9a61d92c4164e5f248fb42dc2 100644 --- a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeFunction/linearDistance/linearDistance.H +++ b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeFunction/linearDistance/linearDistance.H @@ -87,7 +87,6 @@ public: linearDistance ( const dictionary& initialPointsDict, - const conformalVoronoiMesh& cvMesh, const searchableSurface& surface ); diff --git a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeFunction/linearSpatial/linearSpatial.C b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeFunction/linearSpatial/linearSpatial.C index 1caeca1ffa242fb6ff31b00f93703e42e8fccd55..d877ffee64504a81848c7e3fe019415a977871f4 100644 --- a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeFunction/linearSpatial/linearSpatial.C +++ b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeFunction/linearSpatial/linearSpatial.C @@ -42,11 +42,10 @@ addToRunTimeSelectionTable(cellSizeFunction, linearSpatial, dictionary); linearSpatial::linearSpatial ( const dictionary& initialPointsDict, - const conformalVoronoiMesh& cvMesh, const searchableSurface& surface ) : - cellSizeFunction(typeName, initialPointsDict, cvMesh, surface), + cellSizeFunction(typeName, initialPointsDict, surface), referencePoint_(coeffsDict().lookup("referencePoint")), referenceCellSize_(readScalar(coeffsDict().lookup("referenceCellSize"))), direction_(coeffsDict().lookup("direction")), diff --git a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeFunction/linearSpatial/linearSpatial.H b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeFunction/linearSpatial/linearSpatial.H index 177f92fdf9326d9dccd9354fb4950dbe3dc3bd94..faf4d52359422eba3afd2bd94d86fba0d687f90f 100644 --- a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeFunction/linearSpatial/linearSpatial.H +++ b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeFunction/linearSpatial/linearSpatial.H @@ -85,7 +85,6 @@ public: linearSpatial ( const dictionary& initialPointsDict, - const conformalVoronoiMesh& cvMesh, const searchableSurface& surface ); diff --git a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeFunction/surfaceOffsetLinearDistance/surfaceOffsetLinearDistance.C b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeFunction/surfaceOffsetLinearDistance/surfaceOffsetLinearDistance.C index 40960a81238608a670303554ee2418313dfc040d..bb7ffa6a9a11417c097897ca35701f6ad76de1f1 100644 --- a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeFunction/surfaceOffsetLinearDistance/surfaceOffsetLinearDistance.C +++ b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeFunction/surfaceOffsetLinearDistance/surfaceOffsetLinearDistance.C @@ -46,11 +46,10 @@ addToRunTimeSelectionTable surfaceOffsetLinearDistance::surfaceOffsetLinearDistance ( const dictionary& initialPointsDict, - const conformalVoronoiMesh& cvMesh, const searchableSurface& surface ) : - cellSizeFunction(typeName, initialPointsDict, cvMesh, surface), + cellSizeFunction(typeName, initialPointsDict, surface), surfaceCellSize_(readScalar(coeffsDict().lookup("surfaceCellSize"))), distanceCellSize_(readScalar(coeffsDict().lookup("distanceCellSize"))), surfaceOffset_(readScalar(coeffsDict().lookup("surfaceOffset"))), diff --git a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeFunction/surfaceOffsetLinearDistance/surfaceOffsetLinearDistance.H b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeFunction/surfaceOffsetLinearDistance/surfaceOffsetLinearDistance.H index 2b341181028472f5a77c1bb27aa9996b9f75cd0b..2b1d3a6f0e293dbbccf86cca27fabf8f721a9c61 100644 --- a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeFunction/surfaceOffsetLinearDistance/surfaceOffsetLinearDistance.H +++ b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeFunction/surfaceOffsetLinearDistance/surfaceOffsetLinearDistance.H @@ -94,7 +94,6 @@ public: surfaceOffsetLinearDistance ( const dictionary& initialPointsDict, - const conformalVoronoiMesh& cvMesh, const searchableSurface& surface ); diff --git a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeFunction/uniform/uniform.C b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeFunction/uniform/uniform.C index b8f3ffa6f4612dbebc35e0779d045778c6a797d6..e9a06786b48e28d65f2909c23f93062b6a7d997d 100644 --- a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeFunction/uniform/uniform.C +++ b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeFunction/uniform/uniform.C @@ -41,11 +41,10 @@ addToRunTimeSelectionTable(cellSizeFunction, uniform, dictionary); uniform::uniform ( const dictionary& initialPointsDict, - const conformalVoronoiMesh& cvMesh, const searchableSurface& surface ) : - cellSizeFunction(typeName, initialPointsDict, cvMesh, surface), + cellSizeFunction(typeName, initialPointsDict, surface), cellSize_(readScalar(coeffsDict().lookup("cellSize"))) {} diff --git a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeFunction/uniform/uniform.H b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeFunction/uniform/uniform.H index 156e09a24fbd58dd39d5de1d2b2eac5e2f2dab18..ea3031aad1aa6f45742a3a9a7e77200282467773 100644 --- a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeFunction/uniform/uniform.H +++ b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeFunction/uniform/uniform.H @@ -69,7 +69,6 @@ public: uniform ( const dictionary& initialPointsDict, - const conformalVoronoiMesh& cvMesh, const searchableSurface& surface ); diff --git a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeFunction/uniformDistance/uniformDistance.C b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeFunction/uniformDistance/uniformDistance.C index cba741fce2a0d6e09d541486e48a709e3c34d70a..e67eceaa8cd331c8009c5ccd98306de7d11196cf 100644 --- a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeFunction/uniformDistance/uniformDistance.C +++ b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeFunction/uniformDistance/uniformDistance.C @@ -41,11 +41,10 @@ addToRunTimeSelectionTable(cellSizeFunction, uniformDistance, dictionary); uniformDistance::uniformDistance ( const dictionary& initialPointsDict, - const conformalVoronoiMesh& cvMesh, const searchableSurface& surface ) : - cellSizeFunction(typeName, initialPointsDict, cvMesh, surface), + cellSizeFunction(typeName, initialPointsDict, surface), cellSize_(readScalar(coeffsDict().lookup("cellSize"))), distance_(readScalar(coeffsDict().lookup("distance"))), distanceSqr_(sqr(distance_)) diff --git a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeFunction/uniformDistance/uniformDistance.H b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeFunction/uniformDistance/uniformDistance.H index 78f06a2054f382a865da8b0cbae6a880a30a25e2..bbd87fd548cf4f7713607e27b612731772f30962 100644 --- a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeFunction/uniformDistance/uniformDistance.H +++ b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeFunction/uniformDistance/uniformDistance.H @@ -75,7 +75,6 @@ public: uniformDistance ( const dictionary& initialPointsDict, - const conformalVoronoiMesh& cvMesh, const searchableSurface& surface ); diff --git a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.C b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.C index 3c7720e92ac94d3119e0ec9eef8a7725c85415c8..dd58fc5141707e9f78bad63d01d6bb5ecf5bd1b6 100644 --- a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.C +++ b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.C @@ -1925,13 +1925,13 @@ Foam::conformalVoronoiMesh::conformalVoronoiMesh ), geometryToConformTo_ ( - *this, + runTime_, + rndGen_, allGeometry_, cvMeshDict.subDict("surfaceConformation") ), cellSizeControl_ ( - *this, allGeometry_, cvMeshDict.subDict("motionControl") ), @@ -1958,7 +1958,7 @@ Foam::conformalVoronoiMesh::conformalVoronoiMesh relaxationModel::New ( cvMeshDict.subDict("motionControl"), - *this + runTime_ ) ), faceAreaWeightModel_ diff --git a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformationSurfaces/conformationSurfaces.C b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformationSurfaces/conformationSurfaces.C index 9ad5ab6b3e02e25a089c8f2cf681e4f5cf991c6c..5e8a8d729746c8bf0c29a6203f56ca15a1e92521 100644 --- a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformationSurfaces/conformationSurfaces.C +++ b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformationSurfaces/conformationSurfaces.C @@ -30,12 +30,14 @@ License Foam::conformationSurfaces::conformationSurfaces ( - const conformalVoronoiMesh& cvMesh, + const Time& runTime, + Random& rndGen, const searchableSurfaces& allGeometry, const dictionary& surfaceConformationDict ) : - cvMesh_(cvMesh), + runTime_(runTime), + rndGen_(rndGen), allGeometry_(allGeometry), features_(), locationInMesh_(surfaceConformationDict.lookup("locationInMesh")), @@ -139,9 +141,9 @@ Foam::conformationSurfaces::conformationSurfaces IOobject ( feMeshName, - cvMesh_.time().constant(), + runTime_.time().constant(), "extendedFeatureEdgeMesh", - cvMesh_.time(), + runTime_.time(), IOobject::MUST_READ, IOobject::NO_WRITE ) @@ -211,9 +213,9 @@ Foam::conformationSurfaces::conformationSurfaces IOobject ( feMeshName, - cvMesh_.time().constant(), + runTime_.time().constant(), "extendedFeatureEdgeMesh", - cvMesh_.time(), + runTime_.time(), IOobject::MUST_READ, IOobject::NO_WRITE ) @@ -232,7 +234,7 @@ Foam::conformationSurfaces::conformationSurfaces // Extend the global bounds to stop the bound box sitting on the surfaces // to be conformed to - globalBounds_ = globalBounds_.extend(cvMesh_.rndGen(), 1e-4); + globalBounds_ = globalBounds_.extend(rndGen_, 1e-4); // Look at all surfaces at determine whether the locationInMesh point is // inside or outside each, to establish a signature for the domain to be @@ -730,7 +732,7 @@ void Foam::conformationSurfaces::findEdgeNearestByType void Foam::conformationSurfaces::writeFeatureObj(const fileName& prefix) const { - OFstream ftStr(cvMesh_.time().path()/prefix + "_allFeatures.obj"); + OFstream ftStr(runTime_.time().path()/prefix + "_allFeatures.obj"); Pout<< nl << "Writing all features to " << ftStr.name() << endl; diff --git a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformationSurfaces/conformationSurfaces.H b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformationSurfaces/conformationSurfaces.H index 4db3f15862634fedd23045500f0271b05341c21f..b541bed0032027034eaf4a4d77a73df8af49fdf6 100644 --- a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformationSurfaces/conformationSurfaces.H +++ b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformationSurfaces/conformationSurfaces.H @@ -56,8 +56,9 @@ class conformationSurfaces { // Private data - //- Reference to the conformalVoronoiMesh holding this object - const conformalVoronoiMesh& cvMesh_; + const Time& runTime_; + + Random& rndGen_; //- Reference to the searchableSurfaces object holding all geometry data const searchableSurfaces& allGeometry_; @@ -114,7 +115,8 @@ public: // searchableSurfaces conformationSurfaces ( - const conformalVoronoiMesh& cvMesh, + const Time& runTime, + Random& rndGen, const searchableSurfaces& allGeometry, const dictionary& surfaceConformationDict ); diff --git a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/relaxationModel/adaptiveLinear/adaptiveLinear.C b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/relaxationModel/adaptiveLinear/adaptiveLinear.C index e5589a92e1a4164f05f741f2413a4319b4a15609..a1967da49da35ff489c7995a2dc0ea002c6085c5 100644 --- a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/relaxationModel/adaptiveLinear/adaptiveLinear.C +++ b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/relaxationModel/adaptiveLinear/adaptiveLinear.C @@ -41,13 +41,13 @@ addToRunTimeSelectionTable(relaxationModel, adaptiveLinear, dictionary); adaptiveLinear::adaptiveLinear ( const dictionary& relaxationDict, - const conformalVoronoiMesh& cvMesh + const Time& runTime ) : - relaxationModel(typeName, relaxationDict, cvMesh), + relaxationModel(typeName, relaxationDict, runTime), relaxationStart_(readScalar(coeffDict().lookup("relaxationStart"))), relaxationEnd_(readScalar(coeffDict().lookup("relaxationEnd"))), - lastTimeValue_(cvMesh_.time().timeOutputValue()), + lastTimeValue_(runTime_.time().timeOutputValue()), relaxation_(relaxationStart_) {} @@ -56,24 +56,24 @@ adaptiveLinear::adaptiveLinear scalar adaptiveLinear::relaxation() { - if (cvMesh_.time().timeOutputValue() > lastTimeValue_) + if (runTime_.time().timeOutputValue() > lastTimeValue_) { - scalar currentRelxation = relaxation_; + scalar currentRelaxation = relaxation_; relaxation_ -= (relaxation_ - relaxationEnd_) /( ( - cvMesh_.time().endTime().value() - - cvMesh_.time().timeOutputValue() + runTime_.time().endTime().value() + - runTime_.time().timeOutputValue() ) - /(cvMesh_.time().timeOutputValue() - lastTimeValue_) + /(runTime_.time().timeOutputValue() - lastTimeValue_) + 1 ); - lastTimeValue_ = cvMesh_.time().timeOutputValue(); + lastTimeValue_ = runTime_.time().timeOutputValue(); - return currentRelxation; + return currentRelaxation; } return relaxation_; diff --git a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/relaxationModel/adaptiveLinear/adaptiveLinear.H b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/relaxationModel/adaptiveLinear/adaptiveLinear.H index 11a79c39d33447a6b877376e711c5d71b3b02a6d..ecb4c32d4d483e0b3da7fd82117c90a2853ccc65 100644 --- a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/relaxationModel/adaptiveLinear/adaptiveLinear.H +++ b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/relaxationModel/adaptiveLinear/adaptiveLinear.H @@ -83,7 +83,7 @@ public: adaptiveLinear ( const dictionary& relaxationDict, - const conformalVoronoiMesh& cvMesh + const Time& runTime ); diff --git a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/relaxationModel/rampHoldFall/rampHoldFall.C b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/relaxationModel/rampHoldFall/rampHoldFall.C index 17ffeab33f7fcef0bc87c0f3eefb1b4e04642edb..92b42313deda759a91ea9ae69c7a03f02d591e4e 100644 --- a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/relaxationModel/rampHoldFall/rampHoldFall.C +++ b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/relaxationModel/rampHoldFall/rampHoldFall.C @@ -41,10 +41,10 @@ addToRunTimeSelectionTable(relaxationModel, rampHoldFall, dictionary); rampHoldFall::rampHoldFall ( const dictionary& relaxationDict, - const conformalVoronoiMesh& cvMesh + const Time& runTime ) : - relaxationModel(typeName, relaxationDict, cvMesh), + relaxationModel(typeName, relaxationDict, runTime), rampStartRelaxation_(readScalar(coeffDict().lookup("rampStartRelaxation"))), holdRelaxation_(readScalar(coeffDict().lookup("holdRelaxation"))), fallEndRelaxation_(readScalar(coeffDict().lookup("fallEndRelaxation"))), @@ -62,10 +62,10 @@ rampHoldFall::rampHoldFall scalar rampHoldFall::relaxation() { - scalar t = cvMesh_.time().timeOutputValue(); + scalar t = runTime_.time().timeOutputValue(); - scalar tStart = cvMesh_.time().startTime().value(); - scalar tEnd = cvMesh_.time().endTime().value(); + scalar tStart = runTime_.time().startTime().value(); + scalar tEnd = runTime_.time().endTime().value(); scalar tSpan = tEnd - tStart; if (tSpan < VSMALL) diff --git a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/relaxationModel/rampHoldFall/rampHoldFall.H b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/relaxationModel/rampHoldFall/rampHoldFall.H index 6c65e15880f7c38bbc07c4ecff055f5629217b04..db814749f122a5cd7541383a167854cdc23a2107 100644 --- a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/relaxationModel/rampHoldFall/rampHoldFall.H +++ b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/relaxationModel/rampHoldFall/rampHoldFall.H @@ -88,7 +88,7 @@ public: rampHoldFall ( const dictionary& relaxationDict, - const conformalVoronoiMesh& cvMesh + const Time& runTime ); diff --git a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/relaxationModel/relaxationModel/relaxationModel.C b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/relaxationModel/relaxationModel/relaxationModel.C index dd7aee89809e7919c9ba76476851525edb0353ee..91daf73f355cb8d38fc700a92485793c8bb93b3f 100644 --- a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/relaxationModel/relaxationModel/relaxationModel.C +++ b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/relaxationModel/relaxationModel/relaxationModel.C @@ -43,11 +43,11 @@ relaxationModel::relaxationModel ( const word& type, const dictionary& relaxationDict, - const conformalVoronoiMesh& cvMesh + const Time& runTime ) : dictionary(relaxationDict), - cvMesh_(cvMesh), + runTime_(runTime), coeffDict_(subDict(type + "Coeffs")) {} @@ -57,7 +57,7 @@ relaxationModel::relaxationModel autoPtr<relaxationModel> relaxationModel::New ( const dictionary& relaxationDict, - const conformalVoronoiMesh& cvMesh + const Time& runTime ) { word relaxationModelTypeName @@ -85,7 +85,7 @@ autoPtr<relaxationModel> relaxationModel::New << exit(FatalError); } - return autoPtr<relaxationModel>(cstrIter()(relaxationDict, cvMesh)); + return autoPtr<relaxationModel>(cstrIter()(relaxationDict, runTime)); } diff --git a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/relaxationModel/relaxationModel/relaxationModel.H b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/relaxationModel/relaxationModel/relaxationModel.H index d60390ae9a62fb2dd11fb608adad80524d64ffb1..5517098f0596d7264e950e8f3a97b58ec1a860fd 100644 --- a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/relaxationModel/relaxationModel/relaxationModel.H +++ b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/relaxationModel/relaxationModel/relaxationModel.H @@ -37,7 +37,7 @@ SourceFiles #define relaxationModel_H #include "point.H" -#include "conformalVoronoiMesh.H" +#include "Time.H" #include "dictionary.H" #include "autoPtr.H" #include "runTimeSelectionTables.H" @@ -61,7 +61,7 @@ protected: // Protected data //- Reference to the conformalVoronoiMesh holding this cvControls object - const conformalVoronoiMesh& cvMesh_; + const Time& runTime_; //- Method coeffs dictionary dictionary coeffDict_; @@ -92,9 +92,9 @@ public: dictionary, ( const dictionary& relaxationDict, - const conformalVoronoiMesh& cvMesh + const Time& runTime ), - (relaxationDict, cvMesh) + (relaxationDict, runTime) ); @@ -105,7 +105,7 @@ public: ( const word& type, const dictionary& relaxationDict, - const conformalVoronoiMesh& cvMesh + const Time& runTime ); @@ -115,7 +115,7 @@ public: static autoPtr<relaxationModel> New ( const dictionary& relaxationDict, - const conformalVoronoiMesh& cvMesh + const Time& runTime ); diff --git a/applications/utilities/mesh/generation/extrude/Allwmake b/applications/utilities/mesh/generation/extrude/Allwmake index 091ec04743818a08fa9bb59f76c73b547f2174be..5f09893321f37f8063e6e976ac8f809f841a48bb 100755 --- a/applications/utilities/mesh/generation/extrude/Allwmake +++ b/applications/utilities/mesh/generation/extrude/Allwmake @@ -4,6 +4,8 @@ set -x wmake libso extrudeModel wmake extrudeMesh + +wmake libso extrudeToRegionMesh/createShellMesh wmake extrudeToRegionMesh diff --git a/applications/utilities/mesh/generation/extrude/extrudeToRegionMesh/Make/files b/applications/utilities/mesh/generation/extrude/extrudeToRegionMesh/Make/files index 28ac7de544f74c5f83b46a863cf0647a8179800a..22606204b5d1c68e7ed507b72c0e2b0c952529d6 100644 --- a/applications/utilities/mesh/generation/extrude/extrudeToRegionMesh/Make/files +++ b/applications/utilities/mesh/generation/extrude/extrudeToRegionMesh/Make/files @@ -1,4 +1,3 @@ -createShellMesh.C extrudeToRegionMesh.C EXE = $(FOAM_APPBIN)/extrudeToRegionMesh diff --git a/applications/utilities/mesh/generation/extrude/extrudeToRegionMesh/Make/options b/applications/utilities/mesh/generation/extrude/extrudeToRegionMesh/Make/options index 201089b74fc76ccd7b4e8fd02aeefac0ef788857..5732f9761dbd1621922793350690be076fe144b3 100644 --- a/applications/utilities/mesh/generation/extrude/extrudeToRegionMesh/Make/options +++ b/applications/utilities/mesh/generation/extrude/extrudeToRegionMesh/Make/options @@ -1,11 +1,13 @@ EXE_INC = \ -I../extrudeModel/lnInclude \ + -IcreateShellMesh/lnInclude \ -I$(LIB_SRC)/finiteVolume/lnInclude \ -I$(LIB_SRC)/meshTools/lnInclude \ -I$(LIB_SRC)/dynamicMesh/lnInclude EXE_LIBS = \ -lextrudeModel \ + -lcreateShellMesh \ -lfiniteVolume \ -lmeshTools \ -ldynamicMesh diff --git a/applications/utilities/mesh/generation/extrude/extrudeToRegionMesh/createShellMesh/Make/files b/applications/utilities/mesh/generation/extrude/extrudeToRegionMesh/createShellMesh/Make/files new file mode 100644 index 0000000000000000000000000000000000000000..4aa716f0220d590095857d4d07940c486a3b4ea3 --- /dev/null +++ b/applications/utilities/mesh/generation/extrude/extrudeToRegionMesh/createShellMesh/Make/files @@ -0,0 +1,3 @@ +createShellMesh.C + +LIB = $(FOAM_LIBBIN)/libcreateShellMesh diff --git a/applications/utilities/mesh/generation/extrude/extrudeToRegionMesh/createShellMesh/Make/options b/applications/utilities/mesh/generation/extrude/extrudeToRegionMesh/createShellMesh/Make/options new file mode 100644 index 0000000000000000000000000000000000000000..295f0b0bc956185f982b81ddf6eaa4e2869850e1 --- /dev/null +++ b/applications/utilities/mesh/generation/extrude/extrudeToRegionMesh/createShellMesh/Make/options @@ -0,0 +1,9 @@ +EXE_INC = \ + -I$(LIB_SRC)/finiteVolume/lnInclude \ + -I$(LIB_SRC)/meshTools/lnInclude \ + -I$(LIB_SRC)/dynamicMesh/lnInclude -DFULLDEBUG -g -O0 + +LIB_LIBS = \ + -lfiniteVolume \ + -lmeshTools \ + -ldynamicMesh diff --git a/applications/utilities/mesh/generation/extrude/extrudeToRegionMesh/createShellMesh.C b/applications/utilities/mesh/generation/extrude/extrudeToRegionMesh/createShellMesh/createShellMesh.C similarity index 99% rename from applications/utilities/mesh/generation/extrude/extrudeToRegionMesh/createShellMesh.C rename to applications/utilities/mesh/generation/extrude/extrudeToRegionMesh/createShellMesh/createShellMesh.C index 6bfe6ca62e7c64c6960609011f282335aa4d653c..13aefeac1060812e0264e8b87e2c7606bf254e96 100644 --- a/applications/utilities/mesh/generation/extrude/extrudeToRegionMesh/createShellMesh.C +++ b/applications/utilities/mesh/generation/extrude/extrudeToRegionMesh/createShellMesh/createShellMesh.C @@ -509,7 +509,6 @@ void Foam::createShellMesh::setRefinement } } - // Introduce original points // ~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -526,13 +525,12 @@ void Foam::createShellMesh::setRefinement ); pointToPointMap.append(pointI); - //Pout<< "Added bottom point " << addedPointI - // << " at " << patch_.localPoints()[pointI] - // << " from point " << pointI - // << endl; +// Pout<< "Added bottom point " << pointToPointMap[pointI] +// << " at " << patch_.localPoints()[pointI] +// << " from point " << pointI +// << endl; } - // Introduce new points (one for every region) // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -543,6 +541,7 @@ void Foam::createShellMesh::setRefinement point pt = patch_.localPoints()[pointI]; point disp = firstLayerDisp[regionI]; + for (label layerI = 0; layerI < nLayers; layerI++) { pt += disp; @@ -676,7 +675,7 @@ void Foam::createShellMesh::setRefinement { FatalErrorIn("createShellMesh::setRefinement(..)") << "external/feature edge:" << edgeI - << " has " << eFaces.size() << " connected extruded faces " + << " has " << eFaces.size() << " connected extruded faces" << " but only " << ePatches.size() << " boundary faces defined." << exit(FatalError); } diff --git a/applications/utilities/mesh/generation/extrude/extrudeToRegionMesh/createShellMesh.H b/applications/utilities/mesh/generation/extrude/extrudeToRegionMesh/createShellMesh/createShellMesh.H similarity index 100% rename from applications/utilities/mesh/generation/extrude/extrudeToRegionMesh/createShellMesh.H rename to applications/utilities/mesh/generation/extrude/extrudeToRegionMesh/createShellMesh/createShellMesh.H diff --git a/applications/utilities/mesh/generation/extrude2DMesh/Allwclean b/applications/utilities/mesh/generation/extrude2DMesh/Allwclean new file mode 100755 index 0000000000000000000000000000000000000000..44537ed68bad409595e8570f7fa983e0753c6928 --- /dev/null +++ b/applications/utilities/mesh/generation/extrude2DMesh/Allwclean @@ -0,0 +1,8 @@ +#!/bin/sh +cd ${0%/*} || exit 1 # run from this directory +set -x + +wclean libso extrude2DMesh +wclean + +# ----------------------------------------------------------------- end-of-file diff --git a/applications/utilities/mesh/generation/extrude2DMesh/Allwmake b/applications/utilities/mesh/generation/extrude2DMesh/Allwmake new file mode 100755 index 0000000000000000000000000000000000000000..6f54612ffe710adcc912c9baed4eb8a97cae1f91 --- /dev/null +++ b/applications/utilities/mesh/generation/extrude2DMesh/Allwmake @@ -0,0 +1,8 @@ +#!/bin/sh +cd ${0%/*} || exit 1 # run from this directory +set -x + +wmake libso extrude2DMesh +wmake + +# ----------------------------------------------------------------- end-of-file diff --git a/applications/utilities/mesh/generation/extrude2DMesh/Make/files b/applications/utilities/mesh/generation/extrude2DMesh/Make/files index 8cc4bd86cdfe7a24a9eefb19037eeabc80556be6..a30e03b5b777b11c704ab5af3823045c1c112a72 100644 --- a/applications/utilities/mesh/generation/extrude2DMesh/Make/files +++ b/applications/utilities/mesh/generation/extrude2DMesh/Make/files @@ -1,4 +1,3 @@ -extrude2DMesh.C extrude2DMeshApp.C EXE = $(FOAM_APPBIN)/extrude2DMesh diff --git a/applications/utilities/mesh/generation/extrude2DMesh/Make/options b/applications/utilities/mesh/generation/extrude2DMesh/Make/options index ef62d4a7c3c65d44da1fa188e10f07e081fd35c1..8adfe67b36e15e255eb2af9850933535e3f8b3b4 100644 --- a/applications/utilities/mesh/generation/extrude2DMesh/Make/options +++ b/applications/utilities/mesh/generation/extrude2DMesh/Make/options @@ -1,10 +1,12 @@ EXE_INC = \ - /* -DFULLDEBUG -g -O0 */ \ - -I$(LIB_SRC)/meshTools/lnInclude \ + -I$(LIB_SRC)/finiteVolume/lnInclude \ + -I$(LIB_SRC)/surfMesh/lnInclude \ -I$(LIB_SRC)/dynamicMesh/lnInclude \ - -I$(LIB_SRC)/finiteVolume/lnInclude + -Iextrude2DMesh/lnInclude \ + -I../extrude/extrudeModel/lnInclude EXE_LIBS = \ - -lmeshTools \ + -lsurfMesh \ -ldynamicMesh \ - -lfiniteVolume + -lextrude2DMesh \ + -lextrudeModel diff --git a/applications/utilities/mesh/generation/extrude2DMesh/extrude2DMesh.C b/applications/utilities/mesh/generation/extrude2DMesh/extrude2DMesh.C deleted file mode 100644 index 69dc8d66ba4d22a2e9afad83cad279405b5602b7..0000000000000000000000000000000000000000 --- a/applications/utilities/mesh/generation/extrude2DMesh/extrude2DMesh.C +++ /dev/null @@ -1,263 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation - \\/ M anipulation | -------------------------------------------------------------------------------- -License - This file is part of OpenFOAM. - - OpenFOAM is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - OpenFOAM is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. - -\*---------------------------------------------------------------------------*/ - -#include "extrude2DMesh.H" -#include "polyMesh.H" -#include "polyTopoChange.H" - -// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // - -namespace Foam -{ - -defineTypeNameAndDebug(extrude2DMesh, 0); - -} - -// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // - - -// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // - -// Construct from mesh -Foam::extrude2DMesh::extrude2DMesh(const polyMesh& mesh) -: - mesh_(mesh) -{} - - -// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // - -void Foam::extrude2DMesh::setRefinement -( - const direction extrudeDir, - const scalar thickness, - const label frontPatchI, - polyTopoChange& meshMod -) const -{ - for (label cellI = 0; cellI < mesh_.nCells(); cellI++) - { - meshMod.addCell - ( - -1, //masterPointID, - -1, //masterEdgeID, - -1, //masterFaceID, - cellI, //masterCellID, - mesh_.cellZones().whichZone(cellI) //zoneID - ); - } - - - // Generate points - // ~~~~~~~~~~~~~~~ - - forAll(mesh_.points(), pointI) - { - meshMod.addPoint - ( - mesh_.points()[pointI], - pointI, - -1, // zoneID - true // inCell - ); - } - - //Info<< "Adding offsetted points." << nl << endl; - forAll(mesh_.points(), pointI) - { - point newPoint(mesh_.points()[pointI]); - newPoint[extrudeDir] += thickness; - - meshMod.addPoint - ( - newPoint, - pointI, - -1, // zoneID - true // inCell - ); - } - - - // Generate faces - // ~~~~~~~~~~~~~~ - - const faceList& faces = mesh_.faces(); - const polyBoundaryMesh& patches = mesh_.boundaryMesh(); - - for (label faceI = 0; faceI < mesh_.nInternalFaces(); faceI++) - { - label zoneID = mesh_.faceZones().whichZone(faceI); - bool zoneFlip = false; - if (zoneID != -1) - { - const faceZone& fZone = mesh_.faceZones()[zoneID]; - zoneFlip = fZone.flipMap()[fZone.whichFace(faceI)]; - } - - face newFace(4); - const face& f = faces[faceI]; - newFace[0] = f[0]; - newFace[1] = f[1]; - newFace[2] = f[1]+mesh_.nPoints(); - newFace[3] = f[0]+mesh_.nPoints(); - - meshMod.addFace - ( - newFace, - mesh_.faceOwner()[faceI], // own - mesh_.faceNeighbour()[faceI], // nei - -1, // masterPointID - -1, // masterEdgeID - faceI, // masterFaceID - false, // flipFaceFlux - -1, // patchID - zoneID, // zoneID - zoneFlip // zoneFlip - ); - } - - forAll(patches, patchI) - { - label startFaceI = patches[patchI].start(); - label endFaceI = startFaceI + patches[patchI].size(); - - for (label faceI = startFaceI; faceI < endFaceI; faceI++) - { - label zoneID = mesh_.faceZones().whichZone(faceI); - bool zoneFlip = false; - if (zoneID != -1) - { - const faceZone& fZone = mesh_.faceZones()[zoneID]; - zoneFlip = fZone.flipMap()[fZone.whichFace(faceI)]; - } - - face newFace(4); - const face& f = faces[faceI]; - newFace[0] = f[0]; - newFace[1] = f[1]; - newFace[2] = f[1]+mesh_.nPoints(); - newFace[3] = f[0]+mesh_.nPoints(); - - meshMod.addFace - ( - newFace, - mesh_.faceOwner()[faceI], // own - -1, // nei - -1, // masterPointID - -1, // masterEdgeID - faceI, // masterFaceID - false, // flipFaceFlux - patchI, // patchID - zoneID, // zoneID - zoneFlip // zoneFlip - ); - } - } - - - // Generate front and back faces - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - forAll(mesh_.cells(), cellI) - { - const cell& cFaces = mesh_.cells()[cellI]; - - // Make a loop out of faces. - const face& f = faces[cFaces[0]]; - - face frontFace(cFaces.size()); - frontFace[0] = f[0]; - - label nextPointI = f[1]; - label nextFaceI = cFaces[0]; - - for (label i = 1; i < frontFace.size(); i++) - { - frontFace[i] = nextPointI; - - // Find face containing pointI - forAll(cFaces, cFaceI) - { - label faceI = cFaces[cFaceI]; - if (faceI != nextFaceI) - { - const face& f = faces[faceI]; - - if (f[0] == nextPointI) - { - nextPointI = f[1]; - nextFaceI = faceI; - break; - } - else if (f[1] == nextPointI) - { - nextPointI = f[0]; - nextFaceI = faceI; - break; - } - } - } - } - - - // Add back face. - meshMod.addFace - ( - frontFace.reverseFace(), - cellI, // own - -1, // nei - -1, // masterPointID - -1, // masterEdgeID - cFaces[0], // masterFaceID - false, // flipFaceFlux - frontPatchI, // patchID - -1, // zoneID - false // zoneFlip - ); - - // Offset to create front face. - forAll(frontFace, fp) - { - frontFace[fp] += mesh_.nPoints(); - } - meshMod.addFace - ( - frontFace, - cellI, // own - -1, // nei - -1, // masterPointID - -1, // masterEdgeID - cFaces[0], // masterFaceID - false, // flipFaceFlux - frontPatchI, // patchID - -1, // zoneID - false // zoneFlip - ); - } -} - - -// ************************************************************************* // diff --git a/applications/utilities/mesh/generation/extrude2DMesh/extrude2DMesh/Make/files b/applications/utilities/mesh/generation/extrude2DMesh/extrude2DMesh/Make/files new file mode 100644 index 0000000000000000000000000000000000000000..95083a24fbdedcb18bc4db8aa7ed1739a0e4d3e6 --- /dev/null +++ b/applications/utilities/mesh/generation/extrude2DMesh/extrude2DMesh/Make/files @@ -0,0 +1,5 @@ +extrude2DMesh/extrude2DMesh.C + +patchToPoly2DMesh/patchToPoly2DMesh.C + +LIB = $(FOAM_LIBBIN)/libextrude2DMesh diff --git a/applications/utilities/mesh/generation/extrude2DMesh/extrude2DMesh/Make/options b/applications/utilities/mesh/generation/extrude2DMesh/extrude2DMesh/Make/options new file mode 100644 index 0000000000000000000000000000000000000000..8ace7c50daad576ef0b060bf048908f4cf8d073a --- /dev/null +++ b/applications/utilities/mesh/generation/extrude2DMesh/extrude2DMesh/Make/options @@ -0,0 +1,13 @@ +EXE_INC = \ + /* -DFULLDEBUG -g -O0 */ \ + -I$(LIB_SRC)/meshTools/lnInclude \ + -I$(LIB_SRC)/dynamicMesh/lnInclude \ + -I$(LIB_SRC)/finiteVolume/lnInclude \ + -I$(LIB_SRC)/surfMesh/lnInclude \ + -I$(FOAM_APP)/utilities/mesh/generation/extrude/extrudeModel/lnInclude + +LIB_LIBS = \ + -lmeshTools \ + -ldynamicMesh \ + -lsurfMesh \ + -lfiniteVolume diff --git a/applications/utilities/mesh/generation/extrude2DMesh/extrude2DMesh/extrude2DMesh/extrude2DMesh.C b/applications/utilities/mesh/generation/extrude2DMesh/extrude2DMesh/extrude2DMesh/extrude2DMesh.C new file mode 100644 index 0000000000000000000000000000000000000000..ff1a4aeacca079fb35108e9f386b3ff0381e8efd --- /dev/null +++ b/applications/utilities/mesh/generation/extrude2DMesh/extrude2DMesh/extrude2DMesh/extrude2DMesh.C @@ -0,0 +1,588 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "extrude2DMesh.H" +#include "polyMesh.H" +#include "polyTopoChange.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + +defineTypeNameAndDebug(extrude2DMesh, 0); + +} + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +void Foam::extrude2DMesh::check2D() const +{ + const faceList& faces = mesh_.faces(); + forAll(faces, faceI) + { + if (faces[faceI].size() != 2) + { + FatalErrorIn("extrude2DMesh.C") + << "Face " << faceI << " size " << faces[faceI].size() + << " is not of size 2 so mesh is not proper two-dimensional." + << exit(FatalError); + } + } +} + + +//void Foam::extrude2DMesh::findExtrudeDirection() +//{ +// scalar minRange = GREAT; + +// for (direction dir = 0; dir < 3; dir++) +// { +// scalarField cmpts(mesh_.points().component(dir)); + +// scalar range = max(cmpts)-min(cmpts); + +// Info<< "Direction:" << dir << " range:" << range << endl; + +// if (range < minRange) +// { +// minRange = range; +// extrudeDir_ = dir; +// } +// } + +// Info<< "Extruding in direction " << extrudeDir_ +// << " with thickness " << thickness_ << nl +// << endl; +//} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::extrude2DMesh::extrude2DMesh +( + polyMesh& mesh, + const dictionary& dict, + const extrudeModel& model +) +: + mesh_(mesh), + dict_(dict), + //patchDict_(dict.subDict("patchInfo")), + model_(model), + modelType_(dict.lookup("extrudeModel")), + patchType_(dict.lookup("patchType")), + frontPatchI_(-1), + backPatchI_(-1) +{ + check2D(); +} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::extrude2DMesh::~extrude2DMesh() +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +void Foam::extrude2DMesh::addFrontBackPatches() +{ + const polyBoundaryMesh& patches = mesh_.boundaryMesh(); + + frontPatchI_ = patches.findPatchID("front"); + backPatchI_ = patches.findPatchID("back"); + + // Add patch. + List<polyPatch*> newPatches(patches.size() + 2); + + forAll(patches, patchI) + { + const polyPatch& pp = patches[patchI]; + + newPatches[patchI] = + pp.clone + ( + patches, + newPatches.size(), + pp.size(), + pp.start() + ).ptr(); + } + + if (frontPatchI_ == -1) + { + frontPatchI_ = patches.size(); + + newPatches[frontPatchI_] = + polyPatch::New + ( + patchType_, + "front", + 0, + mesh_.nFaces(), + frontPatchI_, + patches + ).ptr(); + +// newPatches[frontPatchI_] = polyPatch::New +// ( +// "front", +// patchDict_, +// frontPatchI_, +// patches +// ).ptr(); + + Info<< "Adding patch " << newPatches[frontPatchI_]->name() + << " at index " << frontPatchI_ + << " for front faces." << nl << endl; + } + + if (backPatchI_ == -1) + { + backPatchI_ = patches.size() + 1; + + newPatches[backPatchI_] = + polyPatch::New + ( + patchType_, + "back", + 0, + mesh_.nFaces(), + backPatchI_, + patches + ).ptr(); + +// newPatches[frontPatchI_] = polyPatch::New +// ( +// "back", +// patchDict_, +// backPatchI_, +// patches +// ).ptr(); + + Info<< "Adding patch " << newPatches[backPatchI_]->name() + << " at index " << backPatchI_ + << " for back faces." << nl << endl; + } + + mesh_.removeBoundary(); + mesh_.addPatches(newPatches); +} + + +void Foam::extrude2DMesh::setRefinement +( + polyTopoChange& meshMod +) +{ + const label nLayers = model_.nLayers(); + const pointField& points = mesh_.points(); + label nFaces = 0; + + for (label layer = 0; layer < nLayers; ++layer) + { + label offset = layer * mesh_.nCells(); + + forAll(mesh_.cells(), cellI) + { + meshMod.addCell + ( + -1, //masterPointID, + -1, //masterEdgeID, + -1, //masterFaceID, + cellI + offset, //masterCellID, + mesh_.cellZones().whichZone(cellI) //zoneID + ); + } + } + + + // Generate points + // ~~~~~~~~~~~~~~~ + + for (label layer = 0; layer <= nLayers; ++layer) + { + label offset = layer * points.size(); + + forAll(points, pointI) + { + // Don't need the surface normal for either linearDirection or + // wedge. Will need to add to be able to use others. + point newPoint = model_ + ( + points[pointI], + vector(), + layer + ); + + meshMod.addPoint + ( + newPoint, + pointI + offset, + -1, // zoneID + true // inCell + ); + } + + Pout<< "Added " << points.size() << " points to layer " + << layer << endl; + } + + + // Generate faces + // ~~~~~~~~~~~~~~ + + const faceList& faces = mesh_.faces(); + const polyBoundaryMesh& patches = mesh_.boundaryMesh(); + + for (label layer = 0; layer < nLayers; ++layer) + { + label currentLayerOffset = layer * mesh_.nPoints(); + label nextLayerOffset = currentLayerOffset + mesh_.nPoints(); + + for (label faceI = 0; faceI < mesh_.nInternalFaces(); faceI++) + { + label zoneID = mesh_.faceZones().whichZone(faceI); + bool zoneFlip = false; + if (zoneID != -1) + { + const faceZone& fZone = mesh_.faceZones()[zoneID]; + zoneFlip = fZone.flipMap()[fZone.whichFace(faceI)]; + } + + face newFace(4); + const face& f = faces[faceI]; + newFace[0] = f[0] + currentLayerOffset; + newFace[1] = f[1] + currentLayerOffset; + newFace[2] = f[1] + nextLayerOffset; + newFace[3] = f[0] + nextLayerOffset; + +//{ +// vector n = newFace.normal(pointField(meshMod.points())); +// label own = mesh_.faceOwner()[faceI]; +// const labelList& ownPoints = mesh_.cellPoints()[own]; +// point ownCc = sum(pointField(mesh_.points(), ownPoints))/ownPoints.size(); +// label nei = mesh_.faceNeighbour()[faceI]; +// const labelList& neiPoints = mesh_.cellPoints()[nei]; +// point neiCc = sum(pointField(mesh_.points(), neiPoints))/neiPoints.size(); +// vector d = neiCc - ownCc; + +// Pout<< "face:" << faceI << " at:" << f.centre(mesh_.points()) << endl +// << " own:" << own << " at:" << ownCc << endl +// << " nei:" << nei << " at:" << neiCc << endl +// << " sign:" << (n & d) << endl +// << endl; +//} + + label offset = layer * mesh_.nCells(); + + meshMod.addFace + ( + newFace, + mesh_.faceOwner()[faceI] + offset, // own + mesh_.faceNeighbour()[faceI] + offset, // nei + -1, // masterPointID + -1, // masterEdgeID + nFaces++, // masterFaceID + false, // flipFaceFlux + -1, // patchID + zoneID, // zoneID + zoneFlip // zoneFlip + ); + + if (debug) + { + Info<< newFace << " " + << mesh_.faceOwner()[faceI] + offset << " " + << mesh_.faceNeighbour()[faceI] + offset << " " + << nFaces - 1 + << endl; + } + } + } + + forAll(patches, patchI) + { + for (label layer=0; layer < nLayers; layer++) + { + label currentLayerOffset = layer*mesh_.nPoints(); + label nextLayerOffset = currentLayerOffset + mesh_.nPoints(); + + label startFaceI = patches[patchI].start(); + label endFaceI = startFaceI + patches[patchI].size(); + + for (label faceI = startFaceI; faceI < endFaceI; faceI++) + { + label zoneID = mesh_.faceZones().whichZone(faceI); + bool zoneFlip = false; + if (zoneID != -1) + { + const faceZone& fZone = mesh_.faceZones()[zoneID]; + zoneFlip = fZone.flipMap()[fZone.whichFace(faceI)]; + } + + face newFace(4); + const face& f = faces[faceI]; + newFace[0] = f[0] + currentLayerOffset; + newFace[1] = f[1] + currentLayerOffset; + newFace[2] = f[1] + nextLayerOffset; + newFace[3] = f[0] + nextLayerOffset; + + label offset = layer * mesh_.nCells(); + + meshMod.addFace + ( + newFace, + mesh_.faceOwner()[faceI] + offset, // own + -1, // nei + -1, // masterPointID + -1, // masterEdgeID + nFaces++, // masterFaceID + false, // flipFaceFlux + patchI, // patchID + zoneID, // zoneID + zoneFlip // zoneFlip + ); + + if (debug) + { + Info<< newFace << " " + << mesh_.faceOwner()[faceI] + offset << " " + << nFaces - 1 + << endl; + } + } + } + } + + // Add extra internal faces that need special treatment for owners and + // neighbours. + forAll(mesh_.cells(), cellI) + { + const cell& cFaces = mesh_.cells()[cellI]; + + face frontFace(cFaces.size()); + + // Make a loop out of faces. + label nextFaceI = cFaces[0]; + + const face& f = faces[nextFaceI]; + + label nextPointI; + if (mesh_.faceOwner()[nextFaceI] == cellI) + { + frontFace[0] = f[0]; + nextPointI = f[1]; + } + else + { + frontFace[0] = f[1]; + nextPointI = f[0]; + } + + + for (label i = 1; i < frontFace.size(); i++) + { + frontFace[i] = nextPointI; + + // Find face containing pointI + forAll(cFaces, cFaceI) + { + label faceI = cFaces[cFaceI]; + if (faceI != nextFaceI) + { + const face& f = faces[faceI]; + + if (f[0] == nextPointI) + { + nextPointI = f[1]; + nextFaceI = faceI; + break; + } + else if (f[1] == nextPointI) + { + nextPointI = f[0]; + nextFaceI = faceI; + break; + } + } + } + } + + for (label layer = 0; layer < nLayers - 1; ++layer) + { + // Offset to create front face. + forAll(frontFace, fp) + { + frontFace[fp] += mesh_.nPoints(); + } + + label offset = layer * mesh_.nCells(); + + label nei = -1; + if (layer != nLayers - 1) + { + nei = cellI + offset + mesh_.nCells(); + } + + meshMod.addFace + ( + frontFace, + cellI + offset, // own + nei, // nei + -1, // masterPointID + -1, // masterEdgeID + nFaces++, // masterFaceID + false, // flipFaceFlux + -1, // patchID + -1, // zoneID + false // zoneFlip + ); + + if (debug) + { + Info<< frontFace << " " + << cellI + offset << " " + << nei << " " + << nFaces - 1 + << endl; + } + } + } + + // Generate front and back faces + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + forAll(mesh_.cells(), cellI) + { + const cell& cFaces = mesh_.cells()[cellI]; + + face frontFace(cFaces.size()); + + // Make a loop out of faces. + label nextFaceI = cFaces[0]; + + const face& f = faces[nextFaceI]; + + label nextPointI; + if (mesh_.faceOwner()[nextFaceI] == cellI) + { + frontFace[0] = f[0]; + nextPointI = f[1]; + } + else + { + frontFace[0] = f[1]; + nextPointI = f[0]; + } + + + for (label i = 1; i < frontFace.size(); i++) + { + frontFace[i] = nextPointI; + + // Find face containing pointI + forAll(cFaces, cFaceI) + { + label faceI = cFaces[cFaceI]; + if (faceI != nextFaceI) + { + const face& f = faces[faceI]; + + if (f[0] == nextPointI) + { + nextPointI = f[1]; + nextFaceI = faceI; + break; + } + else if (f[1] == nextPointI) + { + nextPointI = f[0]; + nextFaceI = faceI; + break; + } + } + } + } + + // Add back face. + meshMod.addFace + ( + frontFace.reverseFace(), + cellI, // own + -1, // nei + -1, // masterPointID + -1, // masterEdgeID + nFaces++, // masterFaceID + false, // flipFaceFlux + backPatchI_, // patchID + -1, // zoneID + false // zoneFlip + ); + + if (debug) + { + Info<< nl<<frontFace.reverseFace() << " " + << cellI << " " + << nFaces - 1 + << endl; + } + + // Offset to create front face. + forAll(frontFace, fp) + { + frontFace[fp] += mesh_.nPoints()* (nLayers); + } + + label offset = (nLayers - 1) * mesh_.nCells(); + + meshMod.addFace + ( + frontFace, + cellI + offset, // own + -1, // nei + -1, // masterPointID + -1, // masterEdgeID + nFaces++, // masterFaceID + false, // flipFaceFlux + frontPatchI_, // patchID + -1, // zoneID + false // zoneFlip + ); + + if (debug) + { + Info<< frontFace << " " + << cellI + offset << " " + << nFaces - 1 + << endl; + } + } +} + + +// ************************************************************************* // diff --git a/applications/utilities/mesh/generation/extrude2DMesh/extrude2DMesh.H b/applications/utilities/mesh/generation/extrude2DMesh/extrude2DMesh/extrude2DMesh/extrude2DMesh.H similarity index 67% rename from applications/utilities/mesh/generation/extrude2DMesh/extrude2DMesh.H rename to applications/utilities/mesh/generation/extrude2DMesh/extrude2DMesh/extrude2DMesh/extrude2DMesh.H index cdeb787946ec1595a17cdd4a1e82df37f5443a41..0733b5e236b3bece57412e1bb9f88208b1d86975 100644 --- a/applications/utilities/mesh/generation/extrude2DMesh/extrude2DMesh.H +++ b/applications/utilities/mesh/generation/extrude2DMesh/extrude2DMesh/extrude2DMesh/extrude2DMesh.H @@ -25,8 +25,8 @@ Class Foam::extrude2DMesh Description - Given 2D mesh insert all the topology changes to extrude. Does not work - in parallel + Given a 2D mesh insert all the topology changes to extrude. Does not work + in parallel. SourceFiles extrude2DMesh.C @@ -36,9 +36,12 @@ SourceFiles #ifndef extrude2DMesh_H #define extrude2DMesh_H +#include "typeInfo.H" #include "label.H" #include "scalar.H" -#include "typeInfo.H" +#include "labelList.H" +#include "dictionary.H" +#include "extrudeModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -50,6 +53,7 @@ class polyMesh; class polyTopoChange; class mapPolyMesh; class mapDistributePolyMesh; +class polyBoundaryMesh; /*---------------------------------------------------------------------------*\ Class extrude2DMesh Declaration @@ -60,8 +64,34 @@ class extrude2DMesh // Private data //- Reference to 2D mesh - const polyMesh& mesh_; + polyMesh& mesh_; + + const dictionary dict_; + + //const dictionary patchDict_; + + const extrudeModel& model_; + + const word modelType_; + + const word patchType_; + + label frontPatchI_; + label backPatchI_; + + // Private Member Functions + + //- Check the mesh is 2D + void check2D() const; + //- Find extrusion direction + //void findExtrudeDirection(); + + //- Disallow default bitwise copy construct + extrude2DMesh(const extrude2DMesh&); + + //- Disallow default bitwise assignment + void operator=(const extrude2DMesh&); public: @@ -70,21 +100,25 @@ public: // Constructors + extrude2DMesh + ( + polyMesh&, + const dictionary& dict, + const extrudeModel& model + ); - //- Construct from mesh - extrude2DMesh(const polyMesh&); + + //- Destructor + ~extrude2DMesh(); // Member Functions + //- Add front and back patches + void addFrontBackPatches(); + //- Play commands into polyTopoChange to extrude mesh. - void setRefinement - ( - const direction extrudeDir, - const scalar thickness, - const label frontPatchI, - polyTopoChange& - ) const; + void setRefinement(polyTopoChange&); //- Force recalculation of locally stored data on topological change void updateMesh(const mapPolyMesh&) @@ -93,6 +127,17 @@ public: //- Force recalculation of locally stored data for mesh distribution void distribute(const mapDistributePolyMesh&) {} + + label frontPatchI() const + { + return frontPatchI_; + } + + label backPatchI() const + { + return backPatchI_; + } + }; diff --git a/applications/utilities/mesh/generation/extrude2DMesh/extrude2DMesh/patchToPoly2DMesh/patchToPoly2DMesh.C b/applications/utilities/mesh/generation/extrude2DMesh/extrude2DMesh/patchToPoly2DMesh/patchToPoly2DMesh.C new file mode 100644 index 0000000000000000000000000000000000000000..30c7a0334afb1ff5e6499e32458a56575fa7ce1c --- /dev/null +++ b/applications/utilities/mesh/generation/extrude2DMesh/extrude2DMesh/patchToPoly2DMesh/patchToPoly2DMesh.C @@ -0,0 +1,333 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "patchToPoly2DMesh.H" +#include "PatchTools.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + + +// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // + + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +void Foam::patchToPoly2DMesh::flipFaceOrder() +{ + const edgeList& edges = patch_.edges(); + const faceList& localFaces = patch_.localFaces(); + const labelList& meshPoints = patch_.meshPoints(); + + Info<< "Flipping face order if necessary." << endl; + forAll(edges, edgeI) + { + const edge& e = edges[edgeI]; + + faces_[edgeI].setSize(2); + + label edgeOwner = owner_[edgeI]; + + const face& f = localFaces[edgeOwner]; + + label fp = findIndex(f, e[0]); + + if (f.nextLabel(fp) != e[1]) + { + Info<< "Flipping face " << faces_[edgeI] << endl; + faces_[edgeI][0] = meshPoints[e[1]]; + faces_[edgeI][1] = meshPoints[e[0]]; + } + else + { + faces_[edgeI][0] = meshPoints[e[0]]; + faces_[edgeI][1] = meshPoints[e[1]]; + } + } +} + + +void Foam::patchToPoly2DMesh::createNeighbours() +{ + const edgeList& edges = patch_.edges(); + const labelListList& edgeFaces = patch_.edgeFaces(); + + Info<< "Calculating neighbours." << endl; + forAll(edges, edgeI) + { + const labelList& eFaces = edgeFaces[edgeI]; + if (eFaces.size() == 2) + { + if (owner_[edgeI] == eFaces[0]) + { + neighbour_[edgeI] = eFaces[1]; + } + else + { + neighbour_[edgeI] = eFaces[0]; + } + } + else if (eFaces.size() == 1) + { + continue; + } + else + { + FatalErrorIn("polyMesh neighbour construction") + << abort(FatalError); + } + } +} + + +Foam::labelList Foam::patchToPoly2DMesh::internalFaceOrder() +{ + const labelListList& cellFaces = patch_.faceEdges(); + + labelList oldToNew(owner_.size(), -1); + + label newFaceI = 0; + + forAll(cellFaces, cellI) + { + const labelList& cFaces = cellFaces[cellI]; + // Neighbouring cells + SortableList<label> nbr(cFaces.size(), -1); + + forAll(cFaces, cfI) + { + if (cFaces[cfI] < neighbour_.size()) + { + label nbrFaceI = neighbour_[cFaces[cfI]]; + + // Internal face. Get cell on other side. + if (nbrFaceI == cellI) + { + nbrFaceI = owner_[cellI]; + } + + if (cellI < nbrFaceI) + { + // CellI is master + nbr[cfI] = nbrFaceI; + } + } + } + + nbr.sort(); + + forAll(nbr, i) + { + if (nbr[i] != -1) + { + oldToNew[cFaces[nbr.indices()[i]]] = newFaceI++; + } + } + } + + return oldToNew; +} + + +void Foam::patchToPoly2DMesh::addPatchFacesToFaces() +{ + const labelList& meshPoints = patch_.meshPoints(); + + label offset = patch_.nInternalEdges(); + face f(2); + + forAll(patchNames_, patchI) + { + forAllConstIter(EdgeMap<label>, mapEdgesRegion_, eIter) + { + if (eIter() == patchI) + { + f[0] = meshPoints[eIter.key().start()]; + f[1] = meshPoints[eIter.key().end()]; + faces_[offset++] = f; + } + } + } + + f.clear(); +} + + +void Foam::patchToPoly2DMesh::addPatchFacesToOwner() +{ + const label nInternalEdges = patch_.nInternalEdges(); + const faceList& faces = patch_.faces(); + const label nExternalEdges = patch_.edges().size() - nInternalEdges; + const labelList& meshPoints = patch_.meshPoints(); + + // Reorder patch faces on owner list. + labelList newOwner = owner_; + + label nMatched = 0; + + for + ( + label bFaceI = nInternalEdges; + bFaceI < faces_.size(); + ++bFaceI + ) + { + const face& e = faces_[bFaceI]; + + bool matched = false; + + for + ( + label bEdgeI = nInternalEdges; + bEdgeI < faces_.size(); + ++bEdgeI + ) + { + if + ( + e[0] == meshPoints[patch_.edges()[bEdgeI][0]] + && e[1] == meshPoints[patch_.edges()[bEdgeI][1]] + ) + { + const face& f = faces[owner_[bEdgeI]]; + + label fp = findIndex(f, e[0]); + + newOwner[bFaceI] = owner_[bEdgeI]; + + if (f.nextLabel(fp) != e[1]) + { + Info<< "Flipping" << endl; + + faces_[bFaceI][0] = e[1]; + faces_[bFaceI][1] = e[0]; + } + + nMatched++; + + matched = true; + } + else if + ( + e[0] == meshPoints[patch_.edges()[bEdgeI][1]] + && e[1] == meshPoints[patch_.edges()[bEdgeI][0]] + ) + { + Info<< "Warning: Wrong orientation." << endl; + nMatched++; + matched = true; + } + } + if (!matched) + { + Info<< "No match for edge." << endl; + } + } + + if (nMatched != nExternalEdges) + { + Info<< "Number of matched edges, " << nMatched + << ", does not match number of external edges, " + << nExternalEdges << endl; + } + + owner_ = newOwner.xfer(); +} + + +void Foam::patchToPoly2DMesh::createPolyMeshComponents() +{ + flipFaceOrder(); + + createNeighbours(); + + // New function for returning a map of old faces to new faces. + labelList oldToNew = internalFaceOrder(); + + inplaceReorder(oldToNew, faces_); + inplaceReorder(oldToNew, owner_); + inplaceReorder(oldToNew, neighbour_); + + // Add patches. + addPatchFacesToFaces(); + + addPatchFacesToOwner(); +} + +// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +//- Construct from a primitivePatch +Foam::patchToPoly2DMesh::patchToPoly2DMesh +( + const MeshedSurface<face>& patch, + const wordList& patchNames, + const labelList& patchSizes, + const EdgeMap<label>& mapEdgesRegion +) +: + patch_(patch), + patchNames_(patchNames), + patchSizes_(patchSizes), + patchStarts_(patchNames.size(), 0), + mapEdgesRegion_(mapEdgesRegion), + points_(patch.points()), + faces_(patch.nEdges()), + owner_(PatchTools::edgeOwner(patch)), + neighbour_(patch.nInternalEdges()) +{} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::patchToPoly2DMesh::~patchToPoly2DMesh() +{} + + +// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // + +void Foam::patchToPoly2DMesh::createMesh() +{ + createPolyMeshComponents(); + + label startFace = patch_.nInternalEdges(); + forAll(patchNames_, patchI) + { + patchStarts_[patchI] = startFace; + startFace += patchSizes_[patchI]; + } +} + +// * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * * // + + +// * * * * * * * * * * * * * * Friend Functions * * * * * * * * * * * * * * // + + +// * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * * // + + +// ************************************************************************* // diff --git a/applications/utilities/mesh/generation/extrude2DMesh/extrude2DMesh/patchToPoly2DMesh/patchToPoly2DMesh.H b/applications/utilities/mesh/generation/extrude2DMesh/extrude2DMesh/patchToPoly2DMesh/patchToPoly2DMesh.H new file mode 100644 index 0000000000000000000000000000000000000000..a07f73f0d4b8dfd0bea1dfac851cb748bbce0618 --- /dev/null +++ b/applications/utilities/mesh/generation/extrude2DMesh/extrude2DMesh/patchToPoly2DMesh/patchToPoly2DMesh.H @@ -0,0 +1,165 @@ +/*--------------------------------*- C++ -*----------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011-2011 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::patchToPoly2DMesh + +Description + Convert a primitivePatch into a 2D polyMesh. + +SourceFiles + patchToPoly2DMesh.C + +\*---------------------------------------------------------------------------*/ + +#ifndef patchToPoly2DMesh_H +#define patchToPoly2DMesh_H + +#include "EdgeMap.H" +#include "MeshedSurface.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class patchToPoly2DMesh Declaration +\*---------------------------------------------------------------------------*/ + +class patchToPoly2DMesh +{ + // Private data + + const MeshedSurface<face>& patch_; + + const wordList& patchNames_; + + const labelList& patchSizes_; + + labelList patchStarts_; + + const EdgeMap<label>& mapEdgesRegion_; + + pointField points_; + faceList faces_; + labelList owner_; + labelList neighbour_; + + //- Description of data_ + void flipFaceOrder(); + + void createNeighbours(); + + labelList internalFaceOrder(); + + void addPatchFacesToFaces(); + + void addPatchFacesToOwner(); + + void createPolyMeshComponents(); + + + // Private Member Functions + + //- Disallow default bitwise copy construct + patchToPoly2DMesh(const patchToPoly2DMesh&); + + //- Disallow default bitwise assignment + void operator=(const patchToPoly2DMesh&); + + +public: + + // Constructors + + //- Construct from a primitivePatch + patchToPoly2DMesh + ( + const MeshedSurface<face>& patch, + const wordList& patchNames, + const labelList& patchSizes, + const EdgeMap<label>& mapEdgesRegion + ); + + + //- Destructor + ~patchToPoly2DMesh(); + + + // Member Functions + + // Access + pointField& points() + { + return points_; + } + + faceList& faces() + { + return faces_; + } + + labelList& owner() + { + return owner_; + } + + labelList& neighbour() + { + return neighbour_; + } + + const wordList& patchNames() const + { + return patchNames_; + } + + const labelList& patchSizes() const + { + return patchSizes_; + } + + const labelList& patchStarts() const + { + return patchStarts_; + } + // Check + + // Edit + void createMesh(); + + // Write + +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/applications/utilities/mesh/generation/extrude2DMesh/extrude2DMeshApp.C b/applications/utilities/mesh/generation/extrude2DMesh/extrude2DMeshApp.C index 364ee98b79d64ff93448fd8e69ca1aaa36596b9c..4bb6b97b1616b5d11b86c5ee99e878d423efcfe3 100644 --- a/applications/utilities/mesh/generation/extrude2DMesh/extrude2DMeshApp.C +++ b/applications/utilities/mesh/generation/extrude2DMesh/extrude2DMeshApp.C @@ -28,13 +28,6 @@ Description Takes 2D mesh (all faces 2 points only, no front and back faces) and creates a 3D mesh by extruding with specified thickness. -Usage - - - extrude2DMesh thickness - - \param thickness \n - Thickness (in metre) of slab. - Note Not sure about the walking of the faces to create the front and back faces. @@ -43,155 +36,261 @@ Note #include "argList.H" #include "Time.H" #include "polyMesh.H" -#include "polyTopoChange.H" #include "extrude2DMesh.H" -#include "emptyPolyPatch.H" +#include "extrudeModel.H" +#include "polyTopoChange.H" +#include "MeshedSurface.H" +#include "edgeCollapser.H" +#include "addPatchCellLayer.H" +#include "patchToPoly2DMesh.H" using namespace Foam; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // -// Main program: +enum ExtrudeMode +{ + POLYMESH2D, + MESHEDSURFACE +}; -int main(int argc, char *argv[]) +namespace Foam { -# include "addOverwriteOption.H" - argList::validArgs.append("thickness"); + template<> + const char* NamedEnum<ExtrudeMode, 2>::names[] = + { + "polyMesh2D", + "MeshedSurface" + }; +} -# include "setRootCase.H" -# include "createTime.H" - runTime.functionObjects().off(); -# include "createPolyMesh.H" - const word oldInstance = mesh.pointsInstance(); +static const NamedEnum<ExtrudeMode, 2> ExtrudeModeNames; - const scalar thickness = args.argRead<scalar>(1); - const bool overwrite = args.optionFound("overwrite"); +//pointField moveInitialPoints +//( +// primitiveFacePatch& fMesh, +// const extrudeModel& model +//) +//{ +// pointField layer0Points(fMesh.nPoints()); +// pointField layer1Points(fMesh.nPoints()); +// pointField displacement(fMesh.nPoints()); - // Check that mesh is 2D - // ~~~~~~~~~~~~~~~~~~~~~ +// forAll(layer0Points, pointI) +// { +// const labelList& meshPoints = fMesh.meshPoints(); +// label meshPointI = meshPoints[pointI]; - const faceList& faces = mesh.faces(); - forAll(faces, faceI) - { - if (faces[faceI].size() != 2) - { - FatalErrorIn(args.executable()) - << "Face " << faceI << " size " << faces[faceI].size() - << " is not of size 2 so mesh is not proper two-dimensional." - << exit(FatalError); - } - } +// layer0Points[meshPointI] = model +// ( +// fMesh.points()[meshPointI], +// fMesh.pointNormals()[pointI], +// 0 +// ); +// layer1Points[meshPointI] = model +// ( +// fMesh.points()[meshPointI], +// fMesh.pointNormals()[pointI], +// 1 +// ); - // Find extrude direction - // ~~~~~~~~~~~~~~~~~~~~~~ +// displacement[pointI] = +// layer1Points[meshPointI] +// - layer0Points[meshPointI]; +// } - scalar minRange = GREAT; - direction extrudeDir = 4; //illegal value. +// fMesh.movePoints(layer0Points); - for (direction dir = 0; dir < 3; dir++) - { - scalarField cmpts(mesh.points().component(dir)); +// return displacement; +//} - scalar range = max(cmpts)-min(cmpts); - Info<< "Direction:" << dir << " range:" << range << endl; +// Main program: - if (range < minRange) - { - minRange = range; - extrudeDir = dir; - } - } +int main(int argc, char *argv[]) +{ + argList::validArgs.append("surfaceFormat"); - Info<< "Extruding in direction " << extrudeDir - << " with thickness " << thickness << nl - << endl; + #include "setRootCase.H" + Info<< "Create time\n" << endl; + Time runTimeExtruded + ( + Time::controlDictName, + args.rootPath(), + args.caseName() + ); - const polyBoundaryMesh& patches = mesh.boundaryMesh(); + runTimeExtruded.functionObjects().off(); + const ExtrudeMode surfaceFormat = ExtrudeModeNames[args[1]]; - // Add front and back patch - // ~~~~~~~~~~~~~~~~~~~~~~~~ + Info<< "Extruding from " << ExtrudeModeNames[surfaceFormat] + << " at time " << runTimeExtruded.timeName() << endl; - label frontPatchI = patches.findPatchID("frontAndBack"); + IOdictionary extrude2DMeshDict + ( + IOobject + ( + "extrude2DMeshDict", + runTimeExtruded.system(), + runTimeExtruded, + IOobject::MUST_READ, + IOobject::NO_WRITE, + false + ) + ); - if (frontPatchI == -1) + // Point generator + autoPtr<extrudeModel> model(extrudeModel::New(extrude2DMeshDict)); + + autoPtr<MeshedSurface<face> > fMesh; + + autoPtr<polyMesh> mesh; + + autoPtr<polyTopoChange> meshMod; + + labelListList extrudeEdgePatches; + + if (surfaceFormat == MESHEDSURFACE) { - // Add patch. - List<polyPatch*> newPatches(patches.size()+1); + fMesh.set(new MeshedSurface<face>("MeshedSurface.obj")); - forAll(patches, patchI) - { - const polyPatch& pp = patches[patchI]; + EdgeMap<label> edgeRegionMap; + wordList patchNames(1, "default"); + labelList patchSizes(1, fMesh().nEdges() - fMesh().nInternalEdges()); - newPatches[patchI] = pp.clone - ( - patches, - newPatches.size(), - pp.size(), - pp.start() - ).ptr(); + const edgeList& edges = fMesh().edges(); + forAll(edges, edgeI) + { + if (!fMesh().isInternalEdge(edgeI)) + { + edgeRegionMap.insert(edges[edgeI], 0); + } } - frontPatchI = patches.size(); - - newPatches[frontPatchI] = new emptyPolyPatch + patchToPoly2DMesh poly2DMesh ( - "frontAndBack", - 0, - mesh.nFaces(), - frontPatchI, - patches + fMesh(), + patchNames, + patchSizes, + edgeRegionMap ); - Info<< "Adding empty patch " << newPatches[frontPatchI]->name() - << " at index " << frontPatchI - << " for front and back faces." << nl << endl; + poly2DMesh.createMesh(); - mesh.removeBoundary(); - mesh.addPatches(newPatches); - } + mesh.set + ( + new polyMesh + ( + IOobject + ( + polyMesh::defaultRegion, + runTimeExtruded.constant(), + runTimeExtruded, + IOobject::NO_READ, + IOobject::NO_WRITE, + false + ), + xferMove(poly2DMesh.points()), + xferMove(poly2DMesh.faces()), + xferMove(poly2DMesh.owner()), + xferMove(poly2DMesh.neighbour()) + ) + ); + Info<< "Constructing patches." << endl; + List<polyPatch*> patches(poly2DMesh.patchNames().size()); + forAll(patches, patchI) + { + patches[patchI] = new polyPatch + ( + poly2DMesh.patchNames()[patchI], + poly2DMesh.patchSizes()[patchI], + poly2DMesh.patchStarts()[patchI], + patchI, + mesh().boundaryMesh() + ); + } - // Topo changes container. Initialise with number of patches. - polyTopoChange meshMod(mesh.boundaryMesh().size()); + mesh().addPatches(patches); + } + else if (surfaceFormat == POLYMESH2D) + { + mesh.set + ( + new polyMesh + ( + Foam::IOobject + ( + Foam::polyMesh::defaultRegion, + runTimeExtruded.timeName(), + runTimeExtruded, + Foam::IOobject::MUST_READ + ) + ) + ); + } // Engine to extrude mesh - extrude2DMesh extruder(mesh); + extrude2DMesh extruder(mesh(), extrude2DMeshDict, model()); - // Insert changes into meshMod - extruder.setRefinement - ( - extrudeDir, - thickness, - frontPatchI, - meshMod - ); + extruder.addFrontBackPatches(); + + meshMod.set(new polyTopoChange(mesh().boundaryMesh().size())); + + extruder.setRefinement(meshMod()); // Create a mesh from topo changes. - autoPtr<mapPolyMesh> morphMap = meshMod.changeMesh(mesh, false); + autoPtr<mapPolyMesh> morphMap = meshMod().changeMesh(mesh(), false); - mesh.updateMesh(morphMap); + mesh().updateMesh(morphMap); - if (!overwrite) - { - runTime++; - } - else { - mesh.setInstance(oldInstance); + edgeCollapser collapser(mesh()); + + const edgeList& edges = mesh().edges(); + const pointField& points = mesh().points(); + + const boundBox& bb = mesh().bounds(); + const scalar mergeDim = 1E-4 * bb.minDim(); + + forAll(edges, edgeI) + { + const edge& e = edges[edgeI]; + + scalar d = e.mag(points); + + if (d < mergeDim) + { + Info<< "Merging edge " << e << " since length " << d + << " << " << mergeDim << nl; + + // Collapse edge to e[0] + collapser.collapseEdge(edgeI, e[0]); + } + } + + polyTopoChange meshModCollapse(mesh()); + + collapser.setRefinement(meshModCollapse); + + // Create a mesh from topo changes. + autoPtr<mapPolyMesh> morphMap + = meshModCollapse.changeMesh(mesh(), false); + + mesh().updateMesh(morphMap); } // Take over refinement levels and write to new time directory. - Pout<< "Writing extruded mesh to time " << runTime.timeName() << nl - << endl; + Pout<< "\nWriting extruded mesh to time = " << runTimeExtruded.timeName() + << nl << endl; - mesh.write(); + mesh().write(); Pout<< "End\n" << endl; diff --git a/applications/utilities/mesh/generation/extrude2DMesh/extrude2DMeshDict b/applications/utilities/mesh/generation/extrude2DMesh/extrude2DMeshDict new file mode 100644 index 0000000000000000000000000000000000000000..5e53c29c886fa05b2158b0d032d85b5f6ed148b7 --- /dev/null +++ b/applications/utilities/mesh/generation/extrude2DMesh/extrude2DMeshDict @@ -0,0 +1,46 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: dev | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ + +FoamFile +{ + version 2.0; + format ascii; + + root ""; + case ""; + instance ""; + local ""; + + class dictionary; + object extrude2DMeshDict; +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +extrudeModel linearDirection; +//extrudeModel wedge; + +patchType empty; +//patchType wedge; + +nLayers 1; + +expansionRatio 1.0; + +linearDirectionCoeffs +{ + direction (0 0 1); + thickness 0.1; +} + +wedgeCoeffs +{ + axisPt (0 0 0); + axis (1 0 0); + angle 10; +} diff --git a/applications/utilities/mesh/manipulation/polyDualMesh/meshDualiser.C b/applications/utilities/mesh/manipulation/polyDualMesh/meshDualiser.C index ea88cf6198bfa5de24ce1f6b1a419591a29b23f9..9ef58b47e40934bcf8a0a2cc5c14953b333769f4 100644 --- a/applications/utilities/mesh/manipulation/polyDualMesh/meshDualiser.C +++ b/applications/utilities/mesh/manipulation/polyDualMesh/meshDualiser.C @@ -49,19 +49,17 @@ void Foam::meshDualiser::checkPolyTopoChange(const polyTopoChange& meshMod) } labelList oldToNew; - pointField newPoints; - bool hasMerged = mergePoints + label nUnique = mergePoints ( points, 1E-6, false, - oldToNew, - newPoints + oldToNew ); - if (hasMerged) + if (nUnique < points.size()) { - labelListList newToOld(invertOneToMany(newPoints.size(), oldToNew)); + labelListList newToOld(invertOneToMany(nUnique, oldToNew)); forAll(newToOld, newI) { @@ -225,17 +223,15 @@ Foam::label Foam::meshDualiser::addInternalFace pointField facePoints(meshMod.points(), newFace); labelList oldToNew; - pointField newPoints; - bool hasMerged = mergePoints + label nUnique = mergePoints ( facePoints, 1E-6, false, - oldToNew, - newPoints + oldToNew ); - if (hasMerged) + if (nUnique < facePoints.size()) { FatalErrorIn("addInternalFace(..)") << "verts:" << verts << " newFace:" << newFace diff --git a/applications/utilities/mesh/manipulation/renumberMesh/Make/options b/applications/utilities/mesh/manipulation/renumberMesh/Make/options index b5e293282a48fcc11891c2222ad3a6b75ee23d2f..2981cf30bea351bd387501cbaa5c65443ae6b769 100644 --- a/applications/utilities/mesh/manipulation/renumberMesh/Make/options +++ b/applications/utilities/mesh/manipulation/renumberMesh/Make/options @@ -2,6 +2,7 @@ EXE_INC = \ -I$(LIB_SRC)/meshTools/lnInclude \ -I$(LIB_SRC)/dynamicMesh/lnInclude \ -I$(LIB_SRC)/finiteVolume/lnInclude \ + -I$(LIB_SRC)/renumberMethods/lnInclude \ -I$(LIB_SRC)/parallel/decompose/decompositionMethods/lnInclude EXE_LIBS = \ @@ -9,4 +10,5 @@ EXE_LIBS = \ -ldynamicMesh \ -lfiniteVolume \ -lgenericPatchFields \ + -lrenumberMethods \ -ldecompositionMethods diff --git a/applications/utilities/mesh/manipulation/renumberMesh/renumberMesh.C b/applications/utilities/mesh/manipulation/renumberMesh/renumberMesh.C index 8d9b0c91ebab1b0c35cb032be821c1c711c7292a..791f68cf98b971857449ff053c754adb0e8e2350 100644 --- a/applications/utilities/mesh/manipulation/renumberMesh/renumberMesh.C +++ b/applications/utilities/mesh/manipulation/renumberMesh/renumberMesh.C @@ -28,6 +28,9 @@ Description Renumbers the cell list in order to reduce the bandwidth, reading and renumbering all fields from all the time directories. + By default uses bandCompression (CuthillMcKee) but will + read system/renumberMeshDict if present and use the method from there. + \*---------------------------------------------------------------------------*/ #include "argList.H" @@ -37,16 +40,52 @@ Description #include "ReadFields.H" #include "volFields.H" #include "surfaceFields.H" -#include "bandCompression.H" -#include "faceSet.H" #include "SortableList.H" #include "decompositionMethod.H" -#include "fvMeshSubset.H" +#include "renumberMethod.H" #include "zeroGradientFvPatchFields.H" +#include "CuthillMcKeeRenumber.H" using namespace Foam; +// Create named field from labelList for postprocessing +tmp<volScalarField> createScalarField +( + const fvMesh& mesh, + const word& name, + const labelList& elems +) +{ + tmp<volScalarField> tfld + ( + new volScalarField + ( + IOobject + ( + name, + mesh.time().timeName(), + mesh, + IOobject::NO_READ, + IOobject::AUTO_WRITE, + false + ), + mesh, + dimensionedScalar("zero", dimless, 0), + zeroGradientFvPatchScalarField::typeName + ) + ); + volScalarField& fld = tfld(); + + forAll(fld, cellI) + { + fld[cellI] = elems[cellI]; + } + + return tfld; +} + + // Calculate band of matrix label getBand(const labelList& owner, const labelList& neighbour) { @@ -65,56 +104,111 @@ label getBand(const labelList& owner, const labelList& neighbour) } -// Return new to old cell numbering -labelList regionBandCompression +// Determine upper-triangular face order +labelList getFaceOrder ( - const fvMesh& mesh, - const labelList& cellToRegion + const primitiveMesh& mesh, + const labelList& cellOrder // new to old cell ) { - Pout<< "Determining cell order:" << endl; - - labelList cellOrder(cellToRegion.size()); + labelList reverseCellOrder(invert(cellOrder.size(), cellOrder)); - label nRegions = max(cellToRegion)+1; + labelList oldToNewFace(mesh.nFaces(), -1); - labelListList regionToCells(invertOneToMany(nRegions, cellToRegion)); + label newFaceI = 0; - label cellI = 0; + labelList nbr; + labelList order; - forAll(regionToCells, regionI) + forAll(cellOrder, newCellI) { - Pout<< " region " << regionI << " starts at " << cellI << endl; + label oldCellI = cellOrder[newCellI]; + + const cell& cFaces = mesh.cells()[oldCellI]; + + // Neighbouring cells + nbr.setSize(cFaces.size()); + + forAll(cFaces, i) + { + label faceI = cFaces[i]; + + if (mesh.isInternalFace(faceI)) + { + // Internal face. Get cell on other side. + label nbrCellI = reverseCellOrder[mesh.faceNeighbour()[faceI]]; + if (nbrCellI == newCellI) + { + nbrCellI = reverseCellOrder[mesh.faceOwner()[faceI]]; + } - // Per region do a reordering. - fvMeshSubset subsetter(mesh); - subsetter.setLargeCellSubset(cellToRegion, regionI); - const fvMesh& subMesh = subsetter.subMesh(); - labelList subCellOrder(bandCompression(subMesh.cellCells())); + if (newCellI < nbrCellI) + { + // CellI is master + nbr[i] = nbrCellI; + } + else + { + // nbrCell is master. Let it handle this face. + nbr[i] = -1; + } + } + else + { + // External face. Do later. + nbr[i] = -1; + } + } - const labelList& cellMap = subsetter.cellMap(); + order.setSize(nbr.size()); + sortedOrder(nbr, order); - forAll(subCellOrder, i) + forAll(order, i) { - cellOrder[cellI++] = cellMap[subCellOrder[i]]; + label index = order[i]; + if (nbr[index] != -1) + { + oldToNewFace[cFaces[index]] = newFaceI++; + } } } - Pout<< endl; - return cellOrder; + // Leave patch faces intact. + for (label faceI = newFaceI; faceI < mesh.nFaces(); faceI++) + { + oldToNewFace[faceI] = faceI; + } + + + // Check done all faces. + forAll(oldToNewFace, faceI) + { + if (oldToNewFace[faceI] == -1) + { + FatalErrorIn + ( + "getFaceOrder" + "(const primitiveMesh&, const labelList&, const labelList&)" + ) << "Did not determine new position" + << " for face " << faceI + << abort(FatalError); + } + } + + return invert(mesh.nFaces(), oldToNewFace); } // Determine face order such that inside region faces are sorted // upper-triangular but inbetween region faces are handled like boundary faces. -labelList regionFaceOrder +labelList getRegionFaceOrder ( const primitiveMesh& mesh, const labelList& cellOrder, // new to old cell const labelList& cellToRegion // old cell to region ) { - Pout<< "Determining face order:" << endl; + //Pout<< "Determining face order:" << endl; labelList reverseCellOrder(invert(cellOrder.size(), cellOrder)); @@ -131,8 +225,8 @@ labelList regionFaceOrder if (cellToRegion[oldCellI] != prevRegion) { prevRegion = cellToRegion[oldCellI]; - Pout<< " region " << prevRegion << " internal faces start at " - << newFaceI << endl; + //Pout<< " region " << prevRegion << " internal faces start at " + // << newFaceI << endl; } const cell& cFaces = mesh.cells()[oldCellI]; @@ -219,9 +313,9 @@ labelList regionFaceOrder if (prevKey != key) { - Pout<< " faces inbetween region " << key/nRegions - << " and " << key%nRegions - << " start at " << newFaceI << endl; + //Pout<< " faces inbetween region " << key/nRegions + // << " and " << key%nRegions + // << " start at " << newFaceI << endl; prevKey = key; } @@ -243,14 +337,14 @@ labelList regionFaceOrder { FatalErrorIn ( - "polyDualMesh::getFaceOrder" - "(const labelList&, const labelList&, const label) const" + "getRegionFaceOrder" + "(const primitveMesh&, const labelList&, const labelList&)" ) << "Did not determine new position" << " for face " << faceI << abort(FatalError); } } - Pout<< endl; + //Pout<< endl; return invert(mesh.nFaces(), oldToNewFace); } @@ -365,10 +459,11 @@ autoPtr<mapPolyMesh> reorderMesh int main(int argc, char *argv[]) { - argList::addBoolOption + argList::addOption ( - "blockOrder", - "order cells into regions (using decomposition)" + "blockSize", + "block size", + "order cells into blocks (using decomposition) before ordering" ); argList::addBoolOption ( @@ -400,12 +495,23 @@ int main(int argc, char *argv[]) # include "createNamedMesh.H" const word oldInstance = mesh.pointsInstance(); - const bool blockOrder = args.optionFound("blockOrder"); - if (blockOrder) + label blockSize = 0; + args.optionReadIfPresent("blockSize", blockSize, 0); + + if (blockSize > 0) { - Info<< "Ordering cells into regions (using decomposition);" + Info<< "Ordering cells into regions of size " << blockSize + << " (using decomposition);" << " ordering faces into region-internal and region-external." << nl << endl; + + if (blockSize < 0 || blockSize >= mesh.nCells()) + { + FatalErrorIn(args.executable()) + << "Block size " << blockSize << " should be positive integer" + << " and less than the number of cells in the mesh." + << exit(FatalError); + } } const bool orderPoints = args.optionFound("orderPoints"); @@ -432,6 +538,37 @@ int main(int argc, char *argv[]) << returnReduce(band, maxOp<label>()) << nl << endl; + // Construct renumberMethod + IOobject io + ( + "renumberMeshDict", + runTime.system(), + mesh, + IOobject::MUST_READ_IF_MODIFIED, + IOobject::NO_WRITE + ); + + autoPtr<renumberMethod> renumberPtr; + + if (io.headerOk()) + { + Info<< "Detected local " << runTime.system()/io.name() << "." << nl + << "Using this to select renumberMethod." << nl << endl; + renumberPtr = renumberMethod::New(IOdictionary(io)); + } + else + { + Info<< "No local " << runTime.system()/io.name() + << " dictionary found. Using default renumberMethod." << nl + << endl; + dictionary renumberDict; + renumberPtr.reset(new CuthillMcKeeRenumber(renumberDict)); + } + + Info<< "Selecting renumberMethod " << renumberPtr().type() << nl << endl; + + + // Read parallel reconstruct maps labelIOList cellProcAddressing ( @@ -521,14 +658,21 @@ int main(int argc, char *argv[]) PtrList<surfaceTensorField> stFlds; ReadFields(mesh, objects, stFlds); + Info<< endl; - autoPtr<mapPolyMesh> map; + // From renumbering: + // - from new cell/face back to original cell/face + labelList cellOrder; + labelList faceOrder; - if (blockOrder) + if (blockSize > 0) { // Renumbering in two phases. Should be done in one so mapping of // fields is done correctly! + label nBlocks = mesh.nCells() / blockSize; + Info<< "nBlocks = " << nBlocks << endl; + // Read decomposePar dictionary IOdictionary decomposeDict ( @@ -541,6 +685,8 @@ int main(int argc, char *argv[]) IOobject::NO_WRITE ) ); + decomposeDict.set("numberOfSubdomains", nBlocks); + autoPtr<decompositionMethod> decomposePtr = decompositionMethod::New ( decomposeDict @@ -556,80 +702,99 @@ int main(int argc, char *argv[]) ); // For debugging: write out region - { - volScalarField cellDist - ( - IOobject - ( - "cellDist", - runTime.timeName(), - mesh, - IOobject::NO_READ, - IOobject::NO_WRITE, - false - ), - mesh, - dimensionedScalar("cellDist", dimless, 0), - zeroGradientFvPatchScalarField::typeName - ); + createScalarField + ( + mesh, + "cellDist", + cellToRegion + )().write(); - forAll(cellToRegion, cellI) - { - cellDist[cellI] = cellToRegion[cellI]; - } + Info<< nl << "Written decomposition as volScalarField to " + << "cellDist for use in postprocessing." + << nl << endl; - cellDist.write(); - Info<< nl << "Written decomposition as volScalarField to " - << cellDist.name() << " for use in postprocessing." - << nl << endl; + // Find point per region + pointField regionPoints(nBlocks, vector::zero); + forAll(cellToRegion, cellI) + { + regionPoints[cellToRegion[cellI]] = mesh.cellCentres()[cellI]; } // Use block based renumbering. - //labelList cellOrder(bandCompression(mesh.cellCells())); - labelList cellOrder(regionBandCompression(mesh, cellToRegion)); + // Detemines old to new cell ordering + labelList reverseCellOrder = renumberPtr().renumber + ( + mesh, + cellToRegion, + regionPoints + ); + + cellOrder = invert(mesh.nCells(), reverseCellOrder); // Determine new to old face order with new cell numbering - labelList faceOrder + faceOrder = getRegionFaceOrder ( - regionFaceOrder - ( - mesh, - cellOrder, - cellToRegion - ) + mesh, + cellOrder, + cellToRegion + ); + } + else + { + // Detemines old to new cell ordering + labelList reverseCellOrder = renumberPtr().renumber + ( + mesh, + mesh.cellCentres() ); - if (!overwrite) - { - runTime++; - } + cellOrder = invert(mesh.nCells(), reverseCellOrder); - // Change the mesh. - map = reorderMesh(mesh, cellOrder, faceOrder); + // Determine new to old face order with new cell numbering + faceOrder = getFaceOrder + ( + mesh, + cellOrder // new to old cell + ); } - else + + + if (!overwrite) { - // Use built-in renumbering. + runTime++; + } - polyTopoChange meshMod(mesh); - if (!overwrite) - { - runTime++; - } + // Change the mesh. + autoPtr<mapPolyMesh> map = reorderMesh(mesh, cellOrder, faceOrder); - // Change the mesh. - map = meshMod.changeMesh + + if (orderPoints) + { + polyTopoChange meshMod(mesh); + autoPtr<mapPolyMesh> pointOrderMap = meshMod.changeMesh ( mesh, - false, // inflate - true, // parallel sync - true, // cell ordering - orderPoints // point ordering + false, //inflate + true, //syncParallel + false, //orderCells + orderPoints //orderPoints + ); + // Combine point reordering into map. + const_cast<labelList&>(map().pointMap()) = UIndirectList<label> + ( + map().pointMap(), + pointOrderMap().pointMap() + )(); + inplaceRenumber + ( + pointOrderMap().reversePointMap(), + const_cast<labelList&>(map().reversePointMap()) ); } + // Update fields mesh.updateMesh(map); @@ -767,6 +932,24 @@ int main(int argc, char *argv[]) if (writeMaps) { + // For debugging: write out region + createScalarField + ( + mesh, + "origCellID", + map().cellMap() + )().write(); + createScalarField + ( + mesh, + "cellID", + identity(mesh.nCells()) + )().write(); + Info<< nl << "Written current cellID and origCellID as volScalarField" + << " for use in postprocessing." + << nl << endl; + + labelIOList ( IOobject diff --git a/applications/utilities/mesh/manipulation/renumberMesh/renumberMeshDict b/applications/utilities/mesh/manipulation/renumberMesh/renumberMeshDict new file mode 100644 index 0000000000000000000000000000000000000000..7ff33fc530ed8f5303ed060a89fd3dfe9094f0f3 --- /dev/null +++ b/applications/utilities/mesh/manipulation/renumberMesh/renumberMeshDict @@ -0,0 +1,51 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: dev | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + note "mesh renumbering dictionary"; + object renumberMeshDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +method CuthillMcKee; +//method manual; +//method random; +//method spring; + +CuthillMcKeeCoeffs +{ + // Reverse CuthillMcKee (RCM) or plain + reverse true; +} + + +manualCoeffs +{ + // In system directory: old to new labelIOList + dataFile "cellMap"; +} + + +springCoeffs +{ + // Maximum jump of cell indices. Is fraction of number of cells + maxCo 0.01; + + // Limit the amount of movement; the fraction maxCo gets decreased + // with every iteration + freezeFraction 0.999; + + // Maximum number of iterations + maxIter 1000; +} + + +// ************************************************************************* // diff --git a/applications/utilities/surface/surfaceConvert/surfaceConvert.C b/applications/utilities/surface/surfaceConvert/surfaceConvert.C index 504262012c0abf14e2f781b51441bd1616c3071d..66af664ad7d844c9e979563e6d82a537c3a3f076 100644 --- a/applications/utilities/surface/surfaceConvert/surfaceConvert.C +++ b/applications/utilities/surface/surfaceConvert/surfaceConvert.C @@ -49,6 +49,7 @@ Note #include "triSurface.H" #include "OFstream.H" #include "OSspecific.H" +#include "Time.H" using namespace Foam; @@ -83,9 +84,25 @@ int main(int argc, char *argv[]) "factor", "geometry scaling factor - default is 1" ); + argList::addOption + ( + "writePrecision", + "label", + "write to output with the specified precision" + ); argList args(argc, argv); + if (args.optionFound("writePrecision")) + { + label writePrecision = args.optionRead<label>("writePrecision"); + + IOstream::defaultPrecision(writePrecision); + Sout.precision(writePrecision); + + Info<< "Output write precision set to " << writePrecision << endl; + } + const fileName importName = args[1]; const fileName exportName = args[2]; diff --git a/applications/utilities/surface/surfaceFeatureExtract/surfaceFeatureExtract.C b/applications/utilities/surface/surfaceFeatureExtract/surfaceFeatureExtract.C index d98b3fb8370a17bcf4f22ca9ce573ceff0aed772..5f6ee05fb1202f8f801d16f9498287de8e309aeb 100644 --- a/applications/utilities/surface/surfaceFeatureExtract/surfaceFeatureExtract.C +++ b/applications/utilities/surface/surfaceFeatureExtract/surfaceFeatureExtract.C @@ -44,6 +44,7 @@ Description #include "indexedOctree.H" #include "treeDataEdge.H" #include "unitConversion.H" +#include "plane.H" using namespace Foam; @@ -94,6 +95,56 @@ void deleteBox } +bool onLine(const point& p, const linePointRef& line) +{ + const point& a = line.start(); + const point& b = line.end(); + + if + ( + ( p.x() < min(a.x(), b.x()) || p.x() > max(a.x(), b.x()) ) + || ( p.y() < min(a.y(), b.y()) || p.y() > max(a.y(), b.y()) ) + || ( p.z() < min(a.z(), b.z()) || p.z() > max(a.z(), b.z()) ) + ) + { + return false; + } + + return true; +} + + +// Deletes all edges inside/outside bounding box from set. +void deleteEdges +( + const triSurface& surf, + const plane& cutPlane, + List<surfaceFeatures::edgeStatus>& edgeStat +) +{ + const pointField& points = surf.points(); + const labelList& meshPoints = surf.meshPoints(); + + forAll(edgeStat, edgeI) + { + const edge& e = surf.edges()[edgeI]; + const point& p0 = points[meshPoints[e.start()]]; + const point& p1 = points[meshPoints[e.end()]]; + const linePointRef line(p0, p1); + + // If edge does not intersect the plane, delete. + scalar intersect = cutPlane.lineIntersect(line); + + point featPoint = intersect * (p1 - p0) + p0; + + if (!onLine(featPoint, line)) + { + edgeStat[edgeI] = surfaceFeatures::NONE; + } + } +} + + void drawHitProblem ( label fI, @@ -270,6 +321,12 @@ int main(int argc, char *argv[]) "manifoldEdgesOnly", "remove any non-manifold (open or more than two connected faces) edges" ); + argList::addOption + ( + "plane", + "(nx ny nz)(z0 y0 z0)", + "use a plane to create feature edges for 2D meshing" + ); # ifdef ENABLE_CURVATURE argList::addBoolOption @@ -454,6 +511,21 @@ int main(int argc, char *argv[]) } } + if (args.optionFound("plane")) + { + plane cutPlane(args.optionLookup("plane")()); + + deleteEdges + ( + surf, + cutPlane, + edgeStat + ); + + Info<< "Only edges that intersect the plane with normal " + << cutPlane.normal() << " and base point " << cutPlane.refPoint() + << " will be included as feature edges."<< endl; + } surfaceFeatures newSet(surf); newSet.setFromStatus(edgeStat); @@ -475,7 +547,6 @@ int main(int argc, char *argv[]) << endl; // Extracting and writing a extendedFeatureEdgeMesh - extendedFeatureEdgeMesh feMesh ( newSet, diff --git a/src/OpenFOAM/Make/files b/src/OpenFOAM/Make/files index da569b2e2113f39cd7b1c4401847cc2938f3e715..cbd98885739d0a9f300d2630dc591c273cf59ffd 100644 --- a/src/OpenFOAM/Make/files +++ b/src/OpenFOAM/Make/files @@ -45,6 +45,7 @@ primitives/Tensor/lists/symmTensorList.C primitives/Tensor/lists/tensorList.C primitives/Vector/complexVector/complexVector.C +primitives/Vector/floatVector/floatVector.C primitives/Vector/labelVector/labelVector.C primitives/Vector/vector/vector.C primitives/Vector/lists/vectorList.C @@ -501,7 +502,6 @@ meshes/treeBoundBox/treeBoundBox.C meshTools = meshes/meshTools $(meshTools)/matchPoints.C -$(meshTools)/mergePoints.C fields/UniformDimensionedFields/uniformDimensionedFields.C fields/cloud/cloud.C diff --git a/src/OpenFOAM/meshes/bandCompression/bandCompression.C b/src/OpenFOAM/meshes/bandCompression/bandCompression.C index 5c31a2121d6128cadff0512f4c4a2cb05b0353db..cec9dc9c6c717f30db9d84c8dd5366302411b6a8 100644 --- a/src/OpenFOAM/meshes/bandCompression/bandCompression.C +++ b/src/OpenFOAM/meshes/bandCompression/bandCompression.C @@ -26,6 +26,7 @@ Description matrix is reduced. The algorithm uses a simple search through the neighbour list + See http://en.wikipedia.org/wiki/Cuthill-McKee_algorithm \*---------------------------------------------------------------------------*/ diff --git a/src/OpenFOAM/meshes/bandCompression/bandCompression.H b/src/OpenFOAM/meshes/bandCompression/bandCompression.H index 25e863fd472f0b1c3f7b681efb5fe7408780ad14..8cbad9fbded857b79d60fa7927a5e44ca9466a4a 100644 --- a/src/OpenFOAM/meshes/bandCompression/bandCompression.H +++ b/src/OpenFOAM/meshes/bandCompression/bandCompression.H @@ -46,6 +46,8 @@ namespace Foam //- Renumbers the addressing to reduce the band of the matrix. // The algorithm uses a simple search through the neighbour list +// Returns the order in which the cells need to be visited (i.e. ordered to +// original) labelList bandCompression(const labelListList& addressing); } // End namespace Foam diff --git a/src/OpenFOAM/meshes/meshTools/mergePoints.C b/src/OpenFOAM/meshes/meshTools/mergePoints.C index 6ecb53352722bd0cd5af54832b3d4c6a2917bdc6..954c6aa86e9bb73d3557358ed7c0fc186da567ec 100644 --- a/src/OpenFOAM/meshes/meshTools/mergePoints.C +++ b/src/OpenFOAM/meshes/meshTools/mergePoints.C @@ -23,25 +23,25 @@ License \*---------------------------------------------------------------------------*/ -#include "mergePoints.H" -#include "SortableList.H" #include "ListOps.H" +#include "point.H" +#include "Field.H" // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // -bool Foam::mergePoints +template<class Type> +Foam::label Foam::mergePoints ( - const UList<point>& points, + const UList<Type>& points, const scalar mergeTol, const bool verbose, labelList& pointMap, - List<point>& newPoints, - const point& origin + const Type& origin ) { - point compareOrigin = origin; + Type compareOrigin = origin; - if (origin == point(VGREAT, VGREAT, VGREAT)) + if (origin == Type::max) { if (points.size()) { @@ -53,12 +53,9 @@ bool Foam::mergePoints pointMap.setSize(points.size()); pointMap = -1; - // Storage for merged points - newPoints.setSize(points.size()); - if (points.empty()) { - return false; + return points.size(); } // We're comparing distance squared to origin first. @@ -70,33 +67,56 @@ bool Foam::mergePoints // x^2+y^2+z^2 + 2*mergeTol*(x+z+y) + mergeTol^2*... // so the difference will be 2*mergeTol*(x+y+z) - const scalar mergeTolSqr = sqr(mergeTol); + const scalar mergeTolSqr = Foam::sqr(scalar(mergeTol)); // Sort points by magSqr - const pointField d(points - compareOrigin); - SortableList<scalar> sortedMagSqr(magSqr(d)); - scalarField sortedTol(points.size()); - forAll(sortedMagSqr.indices(), sortI) + const Field<Type> d(points - compareOrigin); + + List<scalar> magSqrD(d.size()); + forAll(d, pointI) { - const point& pt = d[sortedMagSqr.indices()[sortI]]; - sortedTol[sortI] = 2*mergeTol*(mag(pt.x())+mag(pt.y())+mag(pt.z())); + magSqrD[pointI] = magSqr(d[pointI]); } + labelList order; + sortedOrder(magSqrD, order); + + + Field<scalar> sortedTol(points.size()); + forAll(order, sortI) + { + label pointI = order[sortI]; - bool hasMerged = false; + // Convert to scalar precision + const point pt + ( + scalar(d[pointI].x()), + scalar(d[pointI].y()), + scalar(d[pointI].z()) + ); + sortedTol[sortI] = 2*mergeTol*(mag(pt.x())+mag(pt.y())+mag(pt.z())); + } label newPointI = 0; // Handle 0th point separately (is always unique) - label pointI = sortedMagSqr.indices()[0]; - pointMap[pointI] = newPointI; - newPoints[newPointI++] = points[pointI]; + label pointI = order[0]; + pointMap[pointI] = newPointI++; - for (label sortI = 1; sortI < sortedMagSqr.size(); sortI++) + for (label sortI = 1; sortI < order.size(); sortI++) { // Get original point index - label pointI = sortedMagSqr.indices()[sortI]; + label pointI = order[sortI]; + const scalar mag2 = magSqrD[order[sortI]]; + // Convert to scalar precision + const point pt + ( + scalar(points[pointI].x()), + scalar(points[pointI].y()), + scalar(points[pointI].z()) + ); + // Compare to previous points to find equal one. label equalPointI = -1; @@ -105,17 +125,19 @@ bool Foam::mergePoints ( label prevSortI = sortI - 1; prevSortI >= 0 - && mag - ( - sortedMagSqr[prevSortI] - - sortedMagSqr[sortI] - ) <= sortedTol[sortI]; + && (mag(magSqrD[order[prevSortI]] - mag2) <= sortedTol[sortI]); prevSortI-- ) { - label prevPointI = sortedMagSqr.indices()[prevSortI]; + label prevPointI = order[prevSortI]; + const point prevPt + ( + scalar(points[prevPointI].x()), + scalar(points[prevPointI].y()), + scalar(points[prevPointI].z()) + ); - if (magSqr(points[pointI] - points[prevPointI]) <= mergeTolSqr) + if (magSqr(pt - prevPt) <= mergeTolSqr) { // Found match. equalPointI = prevPointI; @@ -130,8 +152,6 @@ bool Foam::mergePoints // Same coordinate as equalPointI. Map to same new point. pointMap[pointI] = pointMap[equalPointI]; - hasMerged = true; - if (verbose) { Pout<< "Foam::mergePoints : Merging points " @@ -144,14 +164,41 @@ bool Foam::mergePoints else { // Differs. Store new point. - pointMap[pointI] = newPointI; - newPoints[newPointI++] = points[pointI]; + pointMap[pointI] = newPointI++; } } - newPoints.setSize(newPointI); + return newPointI; +} + + +template<class Type> +bool Foam::mergePoints +( + const UList<Type>& points, + const scalar mergeTol, + const bool verbose, + labelList& pointMap, + List<Type>& newPoints, + const Type& origin = Type::zero +) +{ + label nUnique = mergePoints + ( + points, + mergeTol, + verbose, + pointMap, + origin + ); + + newPoints.setSize(nUnique); + forAll(pointMap, pointI) + { + newPoints[pointMap[pointI]] = points[pointI]; + } - return hasMerged; + return (nUnique != points.size()); } diff --git a/src/OpenFOAM/meshes/meshTools/mergePoints.H b/src/OpenFOAM/meshes/meshTools/mergePoints.H index d6a1bb17369e933e1d1e9607c5454ed61a99a765..92f1f1071f3eea0c7ef134b1ba8180cac66a0364 100644 --- a/src/OpenFOAM/meshes/meshTools/mergePoints.H +++ b/src/OpenFOAM/meshes/meshTools/mergePoints.H @@ -32,8 +32,8 @@ SourceFiles #ifndef mergePoints_H #define mergePoints_H -#include "scalarField.H" -#include "pointField.H" +#include "scalar.H" +#include "labelList.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -44,23 +44,41 @@ namespace Foam Function mergePoints Declaration \*---------------------------------------------------------------------------*/ -//- Sort & merge points. All points closer than/equal mergeTol get merged. -// Outputs the new unique points and a map from old to new. Returns -// true if anything merged, false otherwise. +//- Sorts and merges points. All points closer than/equal mergeTol get merged. +// Returns the number of unique points and a map from old to new. +template<class Type> +label mergePoints +( + const UList<Type>& points, + const scalar mergeTol, + const bool verbose, + labelList& pointMap, + const Type& origin = Type::zero +); + +//- Sorts and merges points. Determines new points. Returns true if anything +// merged (though newPoints still sorted even if not merged). +template<class Type> bool mergePoints ( - const UList<point>& points, + const UList<Type>& points, const scalar mergeTol, const bool verbose, labelList& pointMap, - List<point>& newPoints, - const point& origin = point::zero + List<Type>& newPoints, + const Type& origin = Type::zero ); } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +#ifdef NoRepository +# include "mergePoints.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + #endif // ************************************************************************* // diff --git a/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalIndex.C b/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalIndex.C index a432ae889b3d8427593eca6e618b3ee26fb9ef4b..8ecd6ab8f98cee3891b2794f87d663528b0230b3 100644 --- a/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalIndex.C +++ b/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalIndex.C @@ -27,14 +27,22 @@ License // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // -Foam::globalIndex::globalIndex(const label localSize, const int tag) +Foam::globalIndex::globalIndex +( + const label localSize, + const int tag, + const bool parallel +) : offsets_(Pstream::nProcs()+1) { - labelList localSizes(Pstream::nProcs()); + labelList localSizes(Pstream::nProcs(), 0); localSizes[Pstream::myProcNo()] = localSize; - Pstream::gatherList(localSizes, tag); - Pstream::scatterList(localSizes, tag); + if (parallel) + { + Pstream::gatherList(localSizes, tag); + Pstream::scatterList(localSizes, tag); + } label offset = 0; offsets_[0] = 0; diff --git a/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalIndex.H b/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalIndex.H index 1bd83470508c40cb5283167a266612c01c7eacba..c712066f4a18218ec320e7c0b33c5acbd1449371 100644 --- a/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalIndex.H +++ b/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalIndex.H @@ -72,7 +72,12 @@ public: // Constructors //- Construct from local max size - globalIndex(const label localSize, const int tag = Pstream::msgType()); + globalIndex + ( + const label localSize, + const int tag = Pstream::msgType(), + const bool parallel = true // use parallel comms + ); //- Construct from Istream globalIndex(Istream& is); diff --git a/src/OpenFOAM/meshes/polyMesh/polyBoundaryMesh/polyBoundaryMesh.H b/src/OpenFOAM/meshes/polyMesh/polyBoundaryMesh/polyBoundaryMesh.H index 211d9148e941d6a6a799f149265dcecaadea0dae..62d6f4a5e1e8b6d2013dcc459cc3c657caf61c61 100644 --- a/src/OpenFOAM/meshes/polyMesh/polyBoundaryMesh/polyBoundaryMesh.H +++ b/src/OpenFOAM/meshes/polyMesh/polyBoundaryMesh/polyBoundaryMesh.H @@ -159,7 +159,7 @@ public: labelList findIndices ( const keyType&, - const bool usePatchGroups = false + const bool usePatchGroups = true ) const; //- Return patch index for the first match, return -1 if not found @@ -184,7 +184,7 @@ public: ( const UList<wordRe>& patchNames, const bool warnNotFound = true, - const bool usePatchGroups = false + const bool usePatchGroups = true ) const; //- Check whether all procs have all patches and in same order. Return diff --git a/src/OpenFOAM/primitives/Vector/floatVector/floatVector.C b/src/OpenFOAM/primitives/Vector/floatVector/floatVector.C new file mode 100644 index 0000000000000000000000000000000000000000..d88ac70f1f4afc6e25a6a7694155a671d48f7c66 --- /dev/null +++ b/src/OpenFOAM/primitives/Vector/floatVector/floatVector.C @@ -0,0 +1,70 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Description + Vector of floats. + +\*---------------------------------------------------------------------------*/ + +#include "floatVector.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +template<> +const char* const floatVector::typeName = "floatVector"; + +template<> +const char* floatVector::componentNames[] = {"x", "y", "z"}; + +template<> +const floatVector floatVector::zero(0, 0, 0); + +template<> +const floatVector floatVector::one(1, 1, 1); + +template<> +const floatVector floatVector::max +( + floatScalarVGREAT, + floatScalarVGREAT, + floatScalarVGREAT +); + +template<> +const floatVector floatVector::min +( + -floatScalarVGREAT, + -floatScalarVGREAT, + -floatScalarVGREAT +); + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// ************************************************************************* // diff --git a/src/OpenFOAM/primitives/Vector/floatVector/floatVector.H b/src/OpenFOAM/primitives/Vector/floatVector/floatVector.H new file mode 100644 index 0000000000000000000000000000000000000000..438adc17765c911b1a1c4a233a0ddc0d436d8538 --- /dev/null +++ b/src/OpenFOAM/primitives/Vector/floatVector/floatVector.H @@ -0,0 +1,64 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Typedef + Foam::floatVector + +Description + A float version of vector + +SourceFiles + floatVector.C + +\*---------------------------------------------------------------------------*/ + +#ifndef floatVector_H +#define floatVector_H + +#include "Vector.H" +#include "contiguous.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +typedef Vector<float> floatVector; + + +//- Data associated with floatVector type are contiguous +template<> +inline bool contiguous<floatVector>() {return true;} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/dynamicMesh/fvMeshDistribute/fvMeshDistribute.C b/src/dynamicMesh/fvMeshDistribute/fvMeshDistribute.C index 10ac331363c8f4217b4b382b075ac2f722b846e7..3ce3d4a51bda1f701dbd9270588e6cdaadcd8095 100644 --- a/src/dynamicMesh/fvMeshDistribute/fvMeshDistribute.C +++ b/src/dynamicMesh/fvMeshDistribute/fvMeshDistribute.C @@ -36,7 +36,6 @@ License #include "removeCells.H" #include "polyModifyFace.H" #include "polyRemovePoint.H" -#include "mergePoints.H" #include "mapDistributePolyMesh.H" #include "surfaceFields.H" #include "syncTools.H" diff --git a/src/dynamicMesh/polyMeshAdder/polyMeshAdder.C b/src/dynamicMesh/polyMeshAdder/polyMeshAdder.C index c2cde770f2e5807024066cf86c6b75af1f9b98f2..348f61db2bf8f7d09514e0d70fe3f5cad5ac42cb 100644 --- a/src/dynamicMesh/polyMeshAdder/polyMeshAdder.C +++ b/src/dynamicMesh/polyMeshAdder/polyMeshAdder.C @@ -1859,24 +1859,22 @@ Foam::Map<Foam::label> Foam::polyMeshAdder::findSharedPoints ); labelList toMergedPoints; - pointField mergedPoints; - bool hasMerged = Foam::mergePoints + label nUnique = Foam::mergePoints ( connectedPoints, mergeDist, false, - toMergedPoints, - mergedPoints + toMergedPoints ); - if (hasMerged) + if (nUnique < connectedPoints.size()) { // Invert toMergedPoints const labelListList mergeSets ( invertOneToMany ( - mergedPoints.size(), + nUnique, toMergedPoints ) ); @@ -1919,8 +1917,7 @@ Foam::Map<Foam::label> Foam::polyMeshAdder::findSharedPoints //- Old: geometric merging. Causes problems for two close shared points. //labelList sharedToMerged; - //pointField mergedPoints; - //bool hasMerged = Foam::mergePoints + //label nUnique = Foam::mergePoints //( // pointField // ( @@ -1929,8 +1926,7 @@ Foam::Map<Foam::label> Foam::polyMeshAdder::findSharedPoints // ), // mergeDist, // false, - // sharedToMerged, - // mergedPoints + // sharedToMerged //); // //// Find out which sets of points get merged and create a map from @@ -1938,7 +1934,7 @@ Foam::Map<Foam::label> Foam::polyMeshAdder::findSharedPoints // //Map<label> pointToMaster(10*sharedToMerged.size()); // - //if (hasMerged) + //if (nUnique < sharedPointLabels.size()) //{ // labelListList mergeSets // ( diff --git a/src/dynamicMesh/polyTopoChange/polyTopoChange/addPatchCellLayer.C b/src/dynamicMesh/polyTopoChange/polyTopoChange/addPatchCellLayer.C index 01e8c984ec0497a34495ae2e87e1eb0adb7c050b..7f11fb638d1dfcea7b7181169a528bb557c73e3c 100644 --- a/src/dynamicMesh/polyTopoChange/polyTopoChange/addPatchCellLayer.C +++ b/src/dynamicMesh/polyTopoChange/polyTopoChange/addPatchCellLayer.C @@ -34,7 +34,6 @@ License #include "polyModifyFace.H" #include "polyAddCell.H" #include "globalIndex.H" -#include "dummyTransform.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // diff --git a/src/finiteVolume/fields/fvPatchFields/derived/codedMixed/codedMixedFvPatchField.H b/src/finiteVolume/fields/fvPatchFields/derived/codedMixed/codedMixedFvPatchField.H index 40038efeed18ae3d528e3d53f8c2816760fd8cd2..2b7c97478ecfbe204648d2d5ee897740797f0b8c 100644 --- a/src/finiteVolume/fields/fvPatchFields/derived/codedMixed/codedMixedFvPatchField.H +++ b/src/finiteVolume/fields/fvPatchFields/derived/codedMixed/codedMixedFvPatchField.H @@ -38,7 +38,9 @@ Description code #{ - operator==(min(10, 0.1*this->db().time().value())); + this->refValue() = min(10, 0.1*this->db().time().value()); + this->refGrad() = vector::zero; + this->valueFraction() = 1.0; #}; //codeInclude @@ -58,13 +60,15 @@ Description which would have a corresponding entry \verbatim - rampedMixed - { - code - #{ - operator==(min(10, 0.1*this->db().time().value())); - #}; - } + rampedMixed + { + code + #{ + this->refValue() = min(10, 0.1*this->db().time().value()); + this->refGrad() = vector::zero; + this->valueFraction() = 1.0; + #}; + } \endverbatim SeeAlso diff --git a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.C b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.C index f442f72827f435ebd68e977fea872bf4c5fd6ce2..67d4fec174ed7203a3ba8735cb68a387d71289e8 100644 --- a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.C +++ b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.C @@ -47,6 +47,7 @@ Description #include "IOmanip.H" #include "globalIndex.H" #include "DynamicField.H" +#include "PatchTools.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // @@ -369,7 +370,16 @@ void Foam::autoLayerDriver::handleFeatureAngle autoPtr<OFstream> str; if (debug) { - str.reset(new OFstream(mesh.time().path()/"featureEdges.obj")); + str.reset + ( + new OFstream + ( + mesh.time().path() + / "featureEdges_" + + meshRefiner_.timeName() + + ".obj" + ) + ); Info<< "Writing feature edges to " << str().name() << endl; } @@ -1220,49 +1230,19 @@ void Foam::autoLayerDriver::getPatchDisplacement const vectorField& faceNormals = pp.faceNormals(); const labelListList& pointFaces = pp.pointFaces(); const pointField& localPoints = pp.localPoints(); - const labelList& meshPoints = pp.meshPoints(); // Determine pointNormal // ~~~~~~~~~~~~~~~~~~~~~ - pointField pointNormals(pp.nPoints(), vector::zero); - { - labelList nPointFaces(pp.nPoints(), 0); - - forAll(faceNormals, faceI) - { - const face& f = pp.localFaces()[faceI]; - - forAll(f, fp) - { - pointNormals[f[fp]] += faceNormals[faceI]; - nPointFaces[f[fp]] ++; - } - } - - syncTools::syncPointList - ( - mesh, - meshPoints, - pointNormals, - plusEqOp<vector>(), - vector::zero // null value - ); - - syncTools::syncPointList + pointField pointNormals + ( + PatchTools::pointNormals ( mesh, - meshPoints, - nPointFaces, - plusEqOp<label>(), - label(0) // null value - ); - - forAll(pointNormals, i) - { - pointNormals[i] /= nPointFaces[i]; - } - } + pp, + pp.addressing() + ) + ); // Determine local length scale on patch @@ -2266,7 +2246,11 @@ void Foam::autoLayerDriver::addLayers { const_cast<Time&>(mesh.time())++; Info<< "Writing baffled mesh to " << meshRefiner_.timeName() << endl; - mesh.write(); + meshRefiner_.write + ( + debug, + mesh.time().path()/meshRefiner_.timeName() + ); } @@ -2732,7 +2716,7 @@ void Foam::autoLayerDriver::addLayers { dumpDisplacement ( - mesh.time().path()/"layer", + mesh.time().path()/"layer_" + meshRefiner_.timeName(), pp(), patchDisp, extrudeStatus @@ -2744,7 +2728,11 @@ void Foam::autoLayerDriver::addLayers // See comment in autoSnapDriver why we should not remove meshPhi // using mesh.clearPout(). - mesh.write(); + meshRefiner_.write + ( + debug, + mesh.time().path()/meshRefiner_.timeName() + ); } diff --git a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriverShrink.C b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriverShrink.C index 614fd204b3c3b78aaed0aa917b6b08c37d133f81..5731562575b50d515d75b641459f4f1ddf200cab 100644 --- a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriverShrink.C +++ b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriverShrink.C @@ -33,6 +33,9 @@ Description #include "motionSmoother.H" #include "pointData.H" #include "PointEdgeWave.H" +#include "OFstream.H" +#include "meshTools.H" +#include "PatchTools.H" // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // @@ -334,11 +337,25 @@ bool Foam::autoLayerDriver::isMaxEdge return false; } - v0 /= magV0; - v1 /= magV1; - // Test angle. - if ((v0 & v1) < minCos) + //- Detect based on vector to nearest point differing for both endpoints + //v0 /= magV0; + //v1 /= magV1; + // + //// Test angle. + //if ((v0 & v1) < minCos) + //{ + // return true; + //} + //else + //{ + // return false; + //} + + //- Detect based on extrusion vector differing for both endpoints + // the idea is that e.g. a sawtooth wall can still be extruded + // successfully as long as it is done all to the same direction. + if ((pointWallDist[e[0]].v() & pointWallDist[e[1]].v()) < minCos) { return true; } @@ -670,7 +687,6 @@ void Foam::autoLayerDriver::medialAxisSmoothingInfo const pointField& points = mesh.points(); const indirectPrimitivePatch& pp = meshMover.patch(); - const vectorField& faceNormals = pp.faceNormals(); const labelList& meshPoints = pp.meshPoints(); // Predetermine mesh edges @@ -700,44 +716,15 @@ void Foam::autoLayerDriver::medialAxisSmoothingInfo // Determine pointNormal // ~~~~~~~~~~~~~~~~~~~~~ - pointField pointNormals(pp.nPoints(), vector::zero); - { - labelList nPointFaces(pp.nPoints(), 0); - - forAll(faceNormals, faceI) - { - const face& f = pp.localFaces()[faceI]; - - forAll(f, fp) - { - pointNormals[f[fp]] += faceNormals[faceI]; - nPointFaces[f[fp]] ++; - } - } - - syncTools::syncPointList - ( - mesh, - meshPoints, - pointNormals, - plusEqOp<vector>(), - vector::zero // null value - ); - - syncTools::syncPointList + pointField pointNormals + ( + PatchTools::pointNormals ( mesh, - meshPoints, - nPointFaces, - plusEqOp<label>(), - label(0) // null value - ); - - forAll(pointNormals, i) - { - pointNormals[i] /= nPointFaces[i]; - } - } + pp, + pp.addressing() + ) + ); // Smooth patch normal vectors smoothPatchNormals @@ -1012,6 +999,26 @@ void Foam::autoLayerDriver::shrinkMeshMedialDistance label numThicknessRatioExclude = 0; // reduce thickness where thickness/medial axis distance large + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + autoPtr<OFstream> str; + label vertI = 0; + if (debug) + { + str.reset + ( + new OFstream + ( + mesh.time().path() + / "thicknessRatioExcludePoints_" + + meshRefiner_.timeName() + + ".obj" + ) + ); + Info<< "Writing points with too large a extrusion distance to " + << str().name() << endl; + } + forAll(meshPoints, patchPointI) { if (extrudeStatus[patchPointI] != NOEXTRUDE) @@ -1025,6 +1032,20 @@ void Foam::autoLayerDriver::shrinkMeshMedialDistance if (thicknessRatio > maxThicknessToMedialRatio) { // Truncate thickness. + if (debug) + { + Pout<< "truncating displacement at " + << mesh.points()[pointI] + << " from " << thickness[patchPointI] + << " to " + << 0.5 + *( + minThickness[patchPointI] + +thickness[patchPointI] + ) + << endl; + } + thickness[patchPointI] = 0.5*(minThickness[patchPointI]+thickness[patchPointI]); @@ -1033,6 +1054,16 @@ void Foam::autoLayerDriver::shrinkMeshMedialDistance * patchDisp[patchPointI] / (mag(patchDisp[patchPointI]) + VSMALL); numThicknessRatioExclude++; + + if (str.valid()) + { + const point& pt = mesh.points()[pointI]; + meshTools::writeOBJ(str(), pt); + vertI++; + meshTools::writeOBJ(str(), pt+patchDisp[patchPointI]); + vertI++; + str()<< "l " << vertI-1 << ' ' << vertI << nl; + } } } } @@ -1121,6 +1152,31 @@ void Foam::autoLayerDriver::shrinkMeshMedialDistance *dispVec[pointI]; } + if (debug) + { + const_cast<Time&>(mesh.time())++; + Info<< "Writing wanted-displacement mesh (possibly illegal) to " + << meshRefiner_.timeName() << endl; + pointField oldPoints(mesh.points()); + meshMover.movePoints + ( + ( + mesh.points() + + ( + meshMover.scale().internalField() + * displacement.internalField() + ) + )() + ); + meshRefiner_.write + ( + debug, + mesh.time().path()/meshRefiner_.timeName() + ); + meshMover.movePoints(oldPoints); + } + + // Current faces to check. Gets modified in meshMover.scaleMesh labelList checkFaces(identity(mesh.nFaces())); diff --git a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoSnapDriver.C b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoSnapDriver.C index dcb2c6cca5dc9d4af4b7aa0786b5aa7c6c650698..ea29efbb8454bcc368960ac1887ec7648eb9937b 100644 --- a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoSnapDriver.C +++ b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoSnapDriver.C @@ -63,27 +63,26 @@ Foam::label Foam::autoSnapDriver::getCollocatedPoints ) { labelList pointMap; - pointField newPoints; - bool hasMerged = mergePoints + label nUnique = mergePoints ( points, // points tol, // mergeTol false, // verbose - pointMap, - newPoints + pointMap ); + bool hasMerged = (nUnique < points.size()); if (!returnReduce(hasMerged, orOp<bool>())) { return 0; } - // Determine which newPoints are referenced more than once + // Determine which merged points are referenced more than once label nCollocated = 0; // Per old point the newPoint. Or -1 (not set yet) or -2 (already seen // twice) - labelList firstOldPoint(newPoints.size(), -1); + labelList firstOldPoint(nUnique, -1); forAll(pointMap, oldPointI) { label newPointI = pointMap[oldPointI]; diff --git a/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinementProblemCells.C b/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinementProblemCells.C index 1b1b3ba39677b50031986c50821e3ac9a26001ec..296029b7d517b2ad61c66988672bd58ca0be66f8 100644 --- a/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinementProblemCells.C +++ b/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinementProblemCells.C @@ -31,7 +31,6 @@ License #include "pointSet.H" #include "faceSet.H" #include "indirectPrimitivePatch.H" -#include "OFstream.H" #include "cellSet.H" #include "searchableSurfaces.H" #include "polyMeshGeometry.H" diff --git a/src/meshTools/triSurface/triSurfaceTools/triSurfaceTools.C b/src/meshTools/triSurface/triSurfaceTools/triSurfaceTools.C index 451d00c03d56060f2bfee18f77529cfad4e9580b..022d6fb8218149404dcc72e150693fc36de1de53 100644 --- a/src/meshTools/triSurface/triSurfaceTools/triSurfaceTools.C +++ b/src/meshTools/triSurface/triSurfaceTools/triSurfaceTools.C @@ -2096,7 +2096,8 @@ Foam::triSurface Foam::triSurfaceTools::mergePoints ( newTriangles, surf.patches(), - newPoints + newPoints, + true //reuse storage ); } else diff --git a/src/parallel/decompose/decompositionMethods/decompositionMethod/decompositionMethod.C b/src/parallel/decompose/decompositionMethods/decompositionMethod/decompositionMethod.C index 1808fc84ab5b554a0af4aca1008d712de3586cb0..363000bad676bb4b17168ab4056093b6264ee71c 100644 --- a/src/parallel/decompose/decompositionMethods/decompositionMethod/decompositionMethod.C +++ b/src/parallel/decompose/decompositionMethods/decompositionMethod/decompositionMethod.C @@ -96,6 +96,7 @@ Foam::labelList Foam::decompositionMethod::decompose mesh, fineToCoarse, coarsePoints.size(), + true, // use global cell labels coarseCellCells ); @@ -158,6 +159,7 @@ void Foam::decompositionMethod::calcCellCells const polyMesh& mesh, const labelList& agglom, const label nCoarse, + const bool parallel, CompactListList<label>& cellCells ) { @@ -169,7 +171,7 @@ void Foam::decompositionMethod::calcCellCells // Create global cell numbers // ~~~~~~~~~~~~~~~~~~~~~~~~~~ - globalIndex globalAgglom(nCoarse); + globalIndex globalAgglom(nCoarse, Pstream::msgType(), parallel); // Get agglomerate owner on other side of coupled faces @@ -181,7 +183,7 @@ void Foam::decompositionMethod::calcCellCells { const polyPatch& pp = patches[patchI]; - if (pp.coupled()) + if (pp.coupled() && (parallel || !isA<processorPolyPatch>(pp))) { label faceI = pp.start(); label bFaceI = pp.start() - mesh.nInternalFaces(); @@ -203,77 +205,6 @@ void Foam::decompositionMethod::calcCellCells syncTools::swapBoundaryFaceList(mesh, globalNeighbour); - - //// Determine the cellCells (in agglomeration numbering) on coupled faces - //// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // - //labelListList globalCellCells(mesh.nFaces()-mesh.nInternalFaces()); - // - //// Current set of face neighbours for the current cell - //labelHashSet cCells; - // - //forAll(patches, patchI) - //{ - // const polyPatch& pp = patches[patchI]; - // - // if (pp.coupled()) - // { - // label faceI = pp.start(); - // label bFaceI = pp.start() - mesh.nInternalFaces(); - // - // forAll(pp, i) - // { - // label cellI = faceOwner[faceI]; - // label globalCellI = globalAgglom.toGlobal(agglom[cellI]); - // - // // First check if agglomerated across coupled patches at all - // // so we don't use memory if not needed - // if (globalNeighbour[bFaceI] == globalCellI) - // { - // cCells.clear(); - // - // const cell& cFaces = mesh.cells()[cellI]; - // - // forAll(cFaces, i) - // { - // if (mesh.isInternalFace(cFaces[i])) - // { - // label otherCellI = faceOwner[cFaces[i]]; - // if (otherCellI == cellI) - // { - // otherCellI = faceNeighbour[cFaces[i]]; - // } - // - // cCells.insert - // ( - // globalAgglom.toGlobal - // ( - // agglom[otherCellI] - // ) - // ); - // } - // } - // globalCellCells[bFaceI] = cCells.toc(); - // } - // - // bFaceI++; - // faceI++; - // } - // } - //} - // - //// Get the cell on the other side of coupled patches - //syncTools::syncBoundaryFaceList - //( - // mesh, - // globalCellCells, - // eqOp<labelList>(), - // dummyTransform() - //); - - - - // Count number of faces (internal + coupled) // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -293,7 +224,7 @@ void Foam::decompositionMethod::calcCellCells { const polyPatch& pp = patches[patchI]; - if (pp.coupled()) + if (pp.coupled() && (parallel || !isA<processorPolyPatch>(pp))) { label faceI = pp.start(); label bFaceI = pp.start()-mesh.nInternalFaces(); @@ -302,18 +233,6 @@ void Foam::decompositionMethod::calcCellCells { label own = agglom[faceOwner[faceI]]; - //const labelList& cCells = globalCellCells[bFaceI]; - // - //forAll(cCells, i) - //{ - // label globalNei = cCells[i]; - // - // // Allow only processor-local agglomeration - // if (globalAgglom.isLocal(globalNei)) - // { - // nFacesPerCell[own]++; - // } - //} label globalNei = globalNeighbour[bFaceI]; if ( @@ -365,18 +284,6 @@ void Foam::decompositionMethod::calcCellCells { label own = agglom[faceOwner[faceI]]; - //const labelList& cCells = globalCellCells[bFaceI]; - // - //forAll(cCells, i) - //{ - // label globalNei = cCells[i]; - // - // // Allow only processor-local agglomeration - // if (globalAgglom.isLocal(globalNei)) - // { - // m[offsets[own] + nFacesPerCell[own]++] = globalNei; - // } - //} label globalNei = globalNeighbour[bFaceI]; if ( diff --git a/src/parallel/decompose/decompositionMethods/decompositionMethod/decompositionMethod.H b/src/parallel/decompose/decompositionMethods/decompositionMethod/decompositionMethod.H index b81119fb0b204b2d8e23c697788c59819d37c83e..9e58cd5ddc9015f5f07a54da1557aef596181c79 100644 --- a/src/parallel/decompose/decompositionMethods/decompositionMethod/decompositionMethod.H +++ b/src/parallel/decompose/decompositionMethods/decompositionMethod/decompositionMethod.H @@ -57,15 +57,6 @@ protected: label nProcessors_; - //- Helper: determine (global) cellCells from mesh agglomeration. - static void calcCellCells - ( - const polyMesh& mesh, - const labelList& agglom, - const label nCoarse, - CompactListList<label>& cellCells - ); - private: // Private Member Functions @@ -224,6 +215,24 @@ public: const pointField& cc ); + + // Other + + //- Helper: determine (local or global) cellCells from mesh + // agglomeration. + // local : connections are in local indices. Coupled across + // cyclics but not processor patches. + // global : connections are in global indices. Coupled across + // cyclics and processor patches. + static void calcCellCells + ( + const polyMesh& mesh, + const labelList& agglom, + const label nCoarse, + const bool global, + CompactListList<label>& cellCells + ); + }; diff --git a/src/parallel/decompose/decompositionMethods/multiLevelDecomp/multiLevelDecomp.C b/src/parallel/decompose/decompositionMethods/multiLevelDecomp/multiLevelDecomp.C index 19ae049335608c0fce09323ed46b6f0e84b89e56..927df123abfbb74e6067087a2af4fcbed7aaa14e 100644 --- a/src/parallel/decompose/decompositionMethods/multiLevelDecomp/multiLevelDecomp.C +++ b/src/parallel/decompose/decompositionMethods/multiLevelDecomp/multiLevelDecomp.C @@ -383,7 +383,7 @@ Foam::labelList Foam::multiLevelDecomp::decompose ) { CompactListList<label> cellCells; - calcCellCells(mesh, identity(cc.size()), cc.size(), cellCells); + calcCellCells(mesh, identity(cc.size()), cc.size(), true, cellCells); labelField finalDecomp(cc.size(), 0); labelList cellMap(identity(cc.size())); diff --git a/src/parallel/decompose/ptscotchDecomp/ptscotchDecomp.C b/src/parallel/decompose/ptscotchDecomp/ptscotchDecomp.C index b27b011e841004a7c799018c5f4be20749d092bb..54be6ad834a93dd7299f28079dde493ac349e213 100644 --- a/src/parallel/decompose/ptscotchDecomp/ptscotchDecomp.C +++ b/src/parallel/decompose/ptscotchDecomp/ptscotchDecomp.C @@ -755,7 +755,14 @@ Foam::labelList Foam::ptscotchDecomp::decompose CompactListList<label> cellCells; - calcCellCells(mesh, identity(mesh.nCells()), mesh.nCells(), cellCells); + calcCellCells + ( + mesh, + identity(mesh.nCells()), + mesh.nCells(), + true, + cellCells + ); // Decompose using default weights List<int> finalDecomp; @@ -807,7 +814,14 @@ Foam::labelList Foam::ptscotchDecomp::decompose // adjncy : contains neighbours (= edges in graph) // xadj(celli) : start of information in adjncy for celli CompactListList<label> cellCells; - calcCellCells(mesh, agglom, agglomPoints.size(), cellCells); + calcCellCells + ( + mesh, + agglom, + agglomPoints.size(), + true, + cellCells + ); // Decompose using weights List<int> finalDecomp; diff --git a/src/parallel/decompose/scotchDecomp/scotchDecomp.C b/src/parallel/decompose/scotchDecomp/scotchDecomp.C index ecfde107023300a8f7cf9d564dcd9d149e9e0670..d81af37b00a4acfb6471dfd3acd16637c59da1ec 100644 --- a/src/parallel/decompose/scotchDecomp/scotchDecomp.C +++ b/src/parallel/decompose/scotchDecomp/scotchDecomp.C @@ -589,7 +589,14 @@ Foam::labelList Foam::scotchDecomp::decompose // Calculate local or global (if Pstream::parRun()) connectivity CompactListList<label> cellCells; - calcCellCells(mesh, identity(mesh.nCells()), mesh.nCells(), cellCells); + calcCellCells + ( + mesh, + identity(mesh.nCells()), + mesh.nCells(), + true, + cellCells + ); // Decompose using default weights List<int> finalDecomp; @@ -634,7 +641,14 @@ Foam::labelList Foam::scotchDecomp::decompose // Calculate local or global (if Pstream::parRun()) connectivity CompactListList<label> cellCells; - calcCellCells(mesh, agglom, agglomPoints.size(), cellCells); + calcCellCells + ( + mesh, + agglom, + agglomPoints.size(), + true, + cellCells + ); // Decompose using weights List<int> finalDecomp; diff --git a/src/renumberMethods/CuthillMcKeeRenumber/CuthillMcKeeRenumber.C b/src/renumberMethods/CuthillMcKeeRenumber/CuthillMcKeeRenumber.C new file mode 100644 index 0000000000000000000000000000000000000000..e1ec010335a749f08f2869a1f0c5ea8ff992b6d6 --- /dev/null +++ b/src/renumberMethods/CuthillMcKeeRenumber/CuthillMcKeeRenumber.C @@ -0,0 +1,112 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "CuthillMcKeeRenumber.H" +#include "addToRunTimeSelectionTable.H" +#include "bandCompression.H" +#include "decompositionMethod.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(CuthillMcKeeRenumber, 0); + + addToRunTimeSelectionTable + ( + renumberMethod, + CuthillMcKeeRenumber, + dictionary + ); +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::CuthillMcKeeRenumber::CuthillMcKeeRenumber(const dictionary& renumberDict) +: + renumberMethod(renumberDict), + reverse_ + ( + renumberDict.found(typeName + "Coeffs") + ? Switch(renumberDict.subDict(typeName + "Coeffs").lookup("reverse")) + : Switch(false) + ) +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +Foam::labelList Foam::CuthillMcKeeRenumber::renumber +( + const polyMesh& mesh, + const pointField& points +) +{ + CompactListList<label> cellCells; + decompositionMethod::calcCellCells + ( + mesh, + identity(mesh.nCells()), + mesh.nCells(), + false, // local only + cellCells + ); + + labelList orderedToOld = bandCompression(cellCells()); + + if (reverse_) + { + for (label i = 0; i < orderedToOld.size()/2; i++) + { + Swap(orderedToOld[i], orderedToOld[orderedToOld.size()-i-1]); + } + } + + return invert(orderedToOld.size(), orderedToOld); +} + + +Foam::labelList Foam::CuthillMcKeeRenumber::renumber +( + const labelListList& cellCells, + const pointField& points +) +{ + labelList orderedToOld = bandCompression(cellCells); + + if (reverse_) + { + for (label i = 0; i < orderedToOld.size()/2; i++) + { + Swap(orderedToOld[i], orderedToOld[orderedToOld.size()-i-1]); + } + } + + return invert(orderedToOld.size(), orderedToOld); +} + + +// ************************************************************************* // diff --git a/src/renumberMethods/CuthillMcKeeRenumber/CuthillMcKeeRenumber.H b/src/renumberMethods/CuthillMcKeeRenumber/CuthillMcKeeRenumber.H new file mode 100644 index 0000000000000000000000000000000000000000..90a81692e02108cf90e4bb3484afd8d0c28e1b1d --- /dev/null +++ b/src/renumberMethods/CuthillMcKeeRenumber/CuthillMcKeeRenumber.H @@ -0,0 +1,118 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::CuthillMcKeeRenumber + +Description + Cuthill-McKee renumbering + +SourceFiles + CuthillMcKeeRenumber.C + +\*---------------------------------------------------------------------------*/ + +#ifndef CuthillMcKeeRenumber_H +#define CuthillMcKeeRenumber_H + +#include "renumberMethod.H" +#include "Switch.H" + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class CuthillMcKeeRenumber Declaration +\*---------------------------------------------------------------------------*/ + +class CuthillMcKeeRenumber +: + public renumberMethod +{ + // Private data + + const Switch reverse_; + + + // Private Member Functions + + //- Disallow default bitwise copy construct and assignment + void operator=(const CuthillMcKeeRenumber&); + CuthillMcKeeRenumber(const CuthillMcKeeRenumber&); + + +public: + + //- Runtime type information + TypeName("CuthillMcKee"); + + + // Constructors + + //- Construct given the renumber dictionary + CuthillMcKeeRenumber(const dictionary& renumberDict); + + //- Destructor + virtual ~CuthillMcKeeRenumber() + {} + + + // Member Functions + + //- Return for every coordinate the wanted processor number. + // We need a polyMesh (to be able to load the file) + virtual labelList renumber(const pointField&) + { + notImplemented("CuthillMcKeeRenumber::renumber(const pointField&)"); + return labelList(0); + } + + //- Return for every coordinate the wanted processor number. Use the + // mesh connectivity (if needed) + virtual labelList renumber + ( + const polyMesh& mesh, + const pointField& cc + ); + + //- Return for every cell the new cell label. + // The connectivity is equal to mesh.cellCells() except + // - the connections are across coupled patches + virtual labelList renumber + ( + const labelListList& cellCells, + const pointField& cc + ); + +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/renumberMethods/Make/files b/src/renumberMethods/Make/files new file mode 100644 index 0000000000000000000000000000000000000000..fb366f73c4d994bf2f23c7b452731b2599933ccb --- /dev/null +++ b/src/renumberMethods/Make/files @@ -0,0 +1,7 @@ +renumberMethod/renumberMethod.C +manualRenumber/manualRenumber.C +CuthillMcKeeRenumber/CuthillMcKeeRenumber.C +randomRenumber/randomRenumber.C +springRenumber/springRenumber.C + +LIB = $(FOAM_LIBBIN)/librenumberMethods diff --git a/src/renumberMethods/Make/options b/src/renumberMethods/Make/options new file mode 100644 index 0000000000000000000000000000000000000000..03cb68d94683cbf98c9e3f9a0426943c7365dd6b --- /dev/null +++ b/src/renumberMethods/Make/options @@ -0,0 +1,7 @@ +EXE_INC = \ + -I$(LIB_SRC)/parallel/decompose/decompositionMethods/lnInclude \ + -I$(LIB_SRC)/meshTools/lnInclude + +LIB_LIBS = \ + -ldecompositionMethods \ + -lmeshTools diff --git a/src/renumberMethods/manualRenumber/manualRenumber.C b/src/renumberMethods/manualRenumber/manualRenumber.C new file mode 100644 index 0000000000000000000000000000000000000000..40989264b5032e3caef7202dafa747db6e773ab3 --- /dev/null +++ b/src/renumberMethods/manualRenumber/manualRenumber.C @@ -0,0 +1,137 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "manualRenumber.H" +#include "addToRunTimeSelectionTable.H" +#include "IFstream.H" +#include "labelIOList.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(manualRenumber, 0); + + addToRunTimeSelectionTable + ( + renumberMethod, + manualRenumber, + dictionary + ); +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::manualRenumber::manualRenumber(const dictionary& renumberDict) +: + renumberMethod(renumberDict), + dataFile_ + ( + renumberDict.subDict(typeName+"Coeffs").lookup("dataFile") + ) +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +Foam::labelList Foam::manualRenumber::renumber +( + const polyMesh& mesh, + const pointField& points +) +{ + labelIOList oldToNew + ( + IOobject + ( + dataFile_, + mesh.facesInstance(), + mesh, + IOobject::MUST_READ, + IOobject::AUTO_WRITE, + false + ) + ); + + // check if the final renumbering is OK + + if (oldToNew.size() != points.size()) + { + FatalErrorIn + ( + "manualRenumber::renumber(const pointField&, const scalarField&)" + ) << "Size of renumber list does not correspond " + << "to the number of points. Size: " + << oldToNew.size() << " Number of points: " + << points.size() + << ".\n" << "Manual renumbering data read from file " + << dataFile_ << "." << endl + << exit(FatalError); + } + + // Invert to see if one to one + labelList newToOld(points.size(), -1); + forAll(oldToNew, i) + { + label newI = oldToNew[i]; + + if (newI < 0 || newI >= oldToNew.size()) + { + FatalErrorIn + ( + "manualRenumber::renumber(const pointField&" + ", const scalarField&)" + ) << "Renumbering is not one-to-one. Index " + << i << " maps onto " << newI + << ".\n" << "Manual renumbering data read from file " + << dataFile_ << "." << endl + << exit(FatalError); + } + + if (newToOld[newI] == -1) + { + newToOld[newI] = i; + } + else + { + FatalErrorIn + ( + "manualRenumber::renumber(const pointField&" + ", const scalarField&)" + ) << "Renumbering is not one-to-one. Both index " + << newToOld[newI] + << " and " << i << " map onto " << newI + << ".\n" << "Manual renumbering data read from file " + << dataFile_ << "." << endl + << exit(FatalError); + } + } + + return oldToNew; +} + + +// ************************************************************************* // diff --git a/src/renumberMethods/manualRenumber/manualRenumber.H b/src/renumberMethods/manualRenumber/manualRenumber.H new file mode 100644 index 0000000000000000000000000000000000000000..9aa0d76c065bb44cb4fb02eab3c666bf05c76cee --- /dev/null +++ b/src/renumberMethods/manualRenumber/manualRenumber.H @@ -0,0 +1,125 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::manualRenumber + +Description + Renumber given a cell-to-new cell association in a file + +SourceFiles + manualRenumber.C + +\*---------------------------------------------------------------------------*/ + +#ifndef manualRenumber_H +#define manualRenumber_H + +#include "renumberMethod.H" + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class manualRenumber Declaration +\*---------------------------------------------------------------------------*/ + +class manualRenumber +: + public renumberMethod +{ + // Private data + + const fileName dataFile_; + + + // Private Member Functions + + //- Disallow default bitwise copy construct and assignment + void operator=(const manualRenumber&); + manualRenumber(const manualRenumber&); + + +public: + + //- Runtime type information + TypeName("manual"); + + + // Constructors + + //- Construct given the renumber dictionary + manualRenumber(const dictionary& renumberDict); + + //- Destructor + virtual ~manualRenumber() + {} + + + // Member Functions + + //- Return for every coordinate the wanted processor number. + // We need a polyMesh (to be able to load the file) + virtual labelList renumber(const pointField&) + { + notImplemented("manualRenumber::renumber(const pointField&)"); + return labelList(0); + } + + //- Return for every coordinate the wanted processor number. Use the + // mesh connectivity (if needed) + virtual labelList renumber + ( + const polyMesh& mesh, + const pointField& cc + ); + + //- Return for every cell the new cell label. + // The connectivity is equal to mesh.cellCells() except + // - the connections are across coupled patches + virtual labelList renumber + ( + const labelListList& cellCells, + const pointField& cc + ) + { + notImplemented + ( + "manualRenumber::renumber" + "(const labelListList&, const pointField&)" + ); + return labelList(0); + } + +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/renumberMethods/randomRenumber/randomRenumber.C b/src/renumberMethods/randomRenumber/randomRenumber.C new file mode 100644 index 0000000000000000000000000000000000000000..27ddc29c3f2cdda7c90d157cc5a220ca65da4c98 --- /dev/null +++ b/src/renumberMethods/randomRenumber/randomRenumber.C @@ -0,0 +1,96 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "randomRenumber.H" +#include "addToRunTimeSelectionTable.H" +#include "Random.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(randomRenumber, 0); + + addToRunTimeSelectionTable + ( + renumberMethod, + randomRenumber, + dictionary + ); +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::randomRenumber::randomRenumber(const dictionary& renumberDict) +: + renumberMethod(renumberDict) +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +Foam::labelList Foam::randomRenumber::renumber +( + const pointField& points +) +{ + Random rndGen(0); + + labelList oldToNew(identity(points.size())); + + for (label iter = 0; iter < 10; iter++) + { + forAll(oldToNew, i) + { + label j = rndGen.integer(0, oldToNew.size()-1); + Swap(oldToNew[i], oldToNew[j]); + } + } + return oldToNew; +} + + +Foam::labelList Foam::randomRenumber::renumber +( + const polyMesh& mesh, + const pointField& points +) +{ + return renumber(points); +} + + +Foam::labelList Foam::randomRenumber::renumber +( + const labelListList& cellCells, + const pointField& points +) +{ + return renumber(points); +} + + +// ************************************************************************* // diff --git a/src/renumberMethods/randomRenumber/randomRenumber.H b/src/renumberMethods/randomRenumber/randomRenumber.H new file mode 100644 index 0000000000000000000000000000000000000000..54d63d2835e046cb3a7305d21d6872d47d95b2ff --- /dev/null +++ b/src/renumberMethods/randomRenumber/randomRenumber.H @@ -0,0 +1,107 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::randomRenumber + +Description + Random renumber. Just to see effect of renumbering. + +SourceFiles + randomRenumber.C + +\*---------------------------------------------------------------------------*/ + +#ifndef randomRenumber_H +#define randomRenumber_H + +#include "renumberMethod.H" + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class randomRenumber Declaration +\*---------------------------------------------------------------------------*/ + +class randomRenumber +: + public renumberMethod +{ + // Private Member Functions + + //- Disallow default bitwise copy construct and assignment + void operator=(const randomRenumber&); + randomRenumber(const randomRenumber&); + + +public: + + //- Runtime type information + TypeName("random"); + + + // Constructors + + //- Construct given the renumber dictionary + randomRenumber(const dictionary& renumberDict); + + //- Destructor + virtual ~randomRenumber() + {} + + + // Member Functions + + //- Return for every coordinate the wanted processor number. + // We need a polyMesh (to be able to load the file) + virtual labelList renumber(const pointField&); + + //- Return for every coordinate the wanted processor number. Use the + // mesh connectivity (if needed) + virtual labelList renumber + ( + const polyMesh& mesh, + const pointField& cc + ); + + //- Return for every cell the new cell label. + // The connectivity is equal to mesh.cellCells() except + // - the connections are across coupled patches + virtual labelList renumber + ( + const labelListList& cellCells, + const pointField& cc + ); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/renumberMethods/renumberMethod/renumberMethod.C b/src/renumberMethods/renumberMethod/renumberMethod.C new file mode 100644 index 0000000000000000000000000000000000000000..53138673b834b98567b79141014bd20821ead9f7 --- /dev/null +++ b/src/renumberMethods/renumberMethod/renumberMethod.C @@ -0,0 +1,131 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +InClass + renumberMethod + +\*---------------------------------------------------------------------------*/ + +#include "renumberMethod.H" +#include "decompositionMethod.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(renumberMethod, 0); + defineRunTimeSelectionTable(renumberMethod, dictionary); +} + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +Foam::autoPtr<Foam::renumberMethod> Foam::renumberMethod::New +( + const dictionary& renumberDict +) +{ + const word methodType(renumberDict.lookup("method")); + + //Info<< "Selecting renumberMethod " << methodType << endl; + + dictionaryConstructorTable::iterator cstrIter = + dictionaryConstructorTablePtr_->find(methodType); + + if (cstrIter == dictionaryConstructorTablePtr_->end()) + { + FatalErrorIn + ( + "renumberMethod::New" + "(const dictionary& renumberDict)" + ) << "Unknown renumberMethod " + << methodType << nl << nl + << "Valid renumberMethods are : " << endl + << dictionaryConstructorTablePtr_->sortedToc() + << exit(FatalError); + } + + return autoPtr<renumberMethod>(cstrIter()(renumberDict)); +} + + +Foam::labelList Foam::renumberMethod::renumber +( + const polyMesh& mesh, + const pointField& points +) +{ + CompactListList<label> cellCells; + decompositionMethod::calcCellCells + ( + mesh, + identity(mesh.nCells()), + mesh.nCells(), + false, // local only + cellCells + ); + + // Renumber based on agglomerated points + return renumber(cellCells(), points); +} + + +Foam::labelList Foam::renumberMethod::renumber +( + const polyMesh& mesh, + const labelList& fineToCoarse, + const pointField& coarsePoints +) +{ + CompactListList<label> coarseCellCells; + decompositionMethod::calcCellCells + ( + mesh, + fineToCoarse, + coarsePoints.size(), + false, // local only + coarseCellCells + ); + + // Renumber based on agglomerated points + labelList coarseDistribution + ( + renumber + ( + coarseCellCells(), + coarsePoints + ) + ); + + // Rework back into renumbering for original mesh_ + labelList fineDistribution(fineToCoarse.size()); + + forAll(fineDistribution, i) + { + fineDistribution[i] = coarseDistribution[fineToCoarse[i]]; + } + + return fineDistribution; +} + + +// ************************************************************************* // diff --git a/src/renumberMethods/renumberMethod/renumberMethod.H b/src/renumberMethods/renumberMethod/renumberMethod.H new file mode 100644 index 0000000000000000000000000000000000000000..b4b6e89f220be61a890d156559feb49d7edd6d2a --- /dev/null +++ b/src/renumberMethods/renumberMethod/renumberMethod.H @@ -0,0 +1,161 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::renumberMethod + +Description + Abstract base class for renumbering + +SourceFiles + renumberMethod.C + +\*---------------------------------------------------------------------------*/ + +#ifndef renumberMethod_H +#define renumberMethod_H + +#include "polyMesh.H" +#include "pointField.H" +#include "CompactListList.H" + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class renumberMethod Declaration +\*---------------------------------------------------------------------------*/ + +class renumberMethod +{ + +protected: + + // Protected data + + const dictionary& renumberDict_; + +private: + + // Private Member Functions + + //- Disallow default bitwise copy construct and assignment + renumberMethod(const renumberMethod&); + void operator=(const renumberMethod&); + + +public: + + //- Runtime type information + TypeName("renumberMethod"); + + + // Declare run-time constructor selection tables + + declareRunTimeSelectionTable + ( + autoPtr, + renumberMethod, + dictionary, + ( + const dictionary& renumberDict + ), + (renumberDict) + ); + + + // Selectors + + //- Return a reference to the selected renumbering method + static autoPtr<renumberMethod> New + ( + const dictionary& renumberDict + ); + + + // Constructors + + //- Construct given the renumber dictionary + renumberMethod(const dictionary& renumberDict) + : + renumberDict_(renumberDict) + {} + + + //- Destructor + virtual ~renumberMethod() + {} + + + // Member Functions + + //- Return for every cell the new cell label. + // This is only defined for geometric renumberMethods. + virtual labelList renumber(const pointField&) + { + notImplemented + ( + "renumberMethod:renumber(const pointField&)" + ); + return labelList(0); + } + + //- Return for every cell the new cell label. Use the + // mesh connectivity (if needed) + virtual labelList renumber(const polyMesh&, const pointField&); + + //- Return for every cell the new cell label. Gets + // passed agglomeration map (from fine to coarse cells) and coarse + // cell + // location. Can be overridden by renumberMethods that provide this + // functionality natively. Coarse cells are local to the processor + // (if in parallel). If you want to have coarse cells spanning + // processors use the globalCellCells instead. + virtual labelList renumber + ( + const polyMesh& mesh, + const labelList& cellToRegion, + const pointField& regionPoints + ); + + //- Return for every cell the new cell label. + // The connectivity is equal to mesh.cellCells() except + // - the connections are across coupled patches + virtual labelList renumber + ( + const labelListList& cellCells, + const pointField& cc + ) = 0; + +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/renumberMethods/springRenumber/springRenumber.C b/src/renumberMethods/springRenumber/springRenumber.C new file mode 100644 index 0000000000000000000000000000000000000000..5c6fa49350b6b3e7e0fbe2ff1516df590910f933 --- /dev/null +++ b/src/renumberMethods/springRenumber/springRenumber.C @@ -0,0 +1,172 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "springRenumber.H" +#include "addToRunTimeSelectionTable.H" +#include "decompositionMethod.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(springRenumber, 0); + + addToRunTimeSelectionTable + ( + renumberMethod, + springRenumber, + dictionary + ); +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::springRenumber::springRenumber(const dictionary& renumberDict) +: + renumberMethod(renumberDict), + dict_(renumberDict.subDict(typeName+"Coeffs")), + maxCo_(readScalar(dict_.lookup("maxCo"))), + maxIter_(readLabel(dict_.lookup("maxIter"))), + freezeFraction_(readScalar(dict_.lookup("freezeFraction"))) +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +Foam::labelList Foam::springRenumber::renumber +( + const polyMesh& mesh, + const pointField& points +) +{ + CompactListList<label> cellCells; + decompositionMethod::calcCellCells + ( + mesh, + identity(mesh.nCells()), + mesh.nCells(), + false, // local only + cellCells + ); + + return renumber(cellCells(), points); +} + + +Foam::labelList Foam::springRenumber::renumber +( + const labelListList& cellCells, + const pointField& points +) +{ + // Look at cell index as a 1D position parameter. + // Move cells to the average 'position' of their neighbour. + + scalarField position(cellCells.size()); + forAll(position, cellI) + { + position[cellI] = cellI; + } + + labelList oldToNew(identity(cellCells.size())); + + scalar maxCo = maxCo_ * cellCells.size(); + + for (label iter = 0; iter < maxIter_; iter++) + { + //Pout<< "Iteration : " << iter << nl + // << "------------" + // << endl; + + //Pout<< "Position :" << nl + // << " min : " << min(position) << nl + // << " max : " << max(position) << nl + // << " avg : " << average(position) << nl + // << endl; + + // Sum force per cell. + scalarField sumForce(cellCells.size(), 0.0); + forAll(cellCells, oldCellI) + { + const labelList& cCells = cellCells[oldCellI]; + label cellI = oldToNew[oldCellI]; + + forAll(cCells, i) + { + label nbrCellI = oldToNew[cCells[i]]; + + sumForce[cellI] += (position[nbrCellI]-position[cellI]); + } + } + + //Pout<< "Force :" << nl + // << " min : " << min(sumForce) << nl + // << " max : " << max(sumForce) << nl + // << " avgMag : " << average(mag(sumForce)) << nl + // << "DeltaT : " << deltaT << nl + // << endl; + + // Limit displacement + scalar deltaT = maxCo / max(mag(sumForce)); + + Info<< "Iter:" << iter + << " maxCo:" << maxCo + << " deltaT:" << deltaT + << " average force:" << average(mag(sumForce)) << endl; + + // Determine displacement. + scalarField displacement = deltaT*sumForce; + + //Pout<< "Displacement :" << nl + // << " min : " << min(displacement) << nl + // << " max : " << max(displacement) << nl + // << " avgMag : " << average(mag(displacement)) << nl + // << endl; + + // Calculate new position and scale to be within original range + // (0..nCells-1) for ease of postprocessing. + position += displacement; + position -= min(position); + position *= (position.size()-1)/max(position); + + // Slowly freeze. + maxCo *= freezeFraction_; + } + + //writeOBJ("endPosition.obj", cellCells, position); + + // Move cells to new position + labelList shuffle; + sortedOrder(position, shuffle); + + // Reorder oldToNew + inplaceReorder(shuffle, oldToNew); + + return oldToNew; +} + + +// ************************************************************************* // diff --git a/src/renumberMethods/springRenumber/springRenumber.H b/src/renumberMethods/springRenumber/springRenumber.H new file mode 100644 index 0000000000000000000000000000000000000000..d6ee7f00c1172a417095821915fd9d2c16c52248 --- /dev/null +++ b/src/renumberMethods/springRenumber/springRenumber.H @@ -0,0 +1,132 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::springRenumber + +Description + Use spring analogy - attract neighbouring cells according to the distance + of their cell indices. + + // Maximum jump of cell indices. Is fraction of number of cells + maxCo 0.1; + + // Limit the amount of movement; the fraction maxCo gets decreased + // with every iteration. + freezeFraction 0.9; + + // Maximum number of iterations + maxIter 1000; + +SourceFiles + springRenumber.C + +\*---------------------------------------------------------------------------*/ + +#ifndef springRenumber_H +#define springRenumber_H + +#include "renumberMethod.H" + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class springRenumber Declaration +\*---------------------------------------------------------------------------*/ + +class springRenumber +: + public renumberMethod +{ + // Private data + + const dictionary& dict_; + + const scalar maxCo_; + + const label maxIter_; + + const scalar freezeFraction_; + + // Private Member Functions + + //- Disallow default bitwise copy construct and assignment + void operator=(const springRenumber&); + springRenumber(const springRenumber&); + + +public: + + //- Runtime type information + TypeName("spring"); + + + // Constructors + + //- Construct given the renumber dictionary + springRenumber(const dictionary& renumberDict); + + //- Destructor + virtual ~springRenumber() + {} + + + // Member Functions + + //- Return for every coordinate the wanted processor number. + virtual labelList renumber(const pointField&) + { + notImplemented("springRenumber::renumber(const pointField&)"); + return labelList(0); + } + + //- Return for every coordinate the wanted processor number. Use the + // mesh connectivity (if needed) + virtual labelList renumber + ( + const polyMesh& mesh, + const pointField& cc + ); + + //- Return for every cell the new cell label. + // The connectivity is equal to mesh.cellCells() except + // - the connections are across coupled patches + virtual labelList renumber + ( + const labelListList& cellCells, + const pointField& cc + ); + +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/triSurface/triSurface/interfaces/STL/readSTLASCII.L b/src/triSurface/triSurface/interfaces/STL/readSTLASCII.L index 393104a7b5324bb1af0fd712502747f3ac35efc4..ddefb95a8542ba170526c11a022e23bf3bc5def3 100644 --- a/src/triSurface/triSurface/interfaces/STL/readSTLASCII.L +++ b/src/triSurface/triSurface/interfaces/STL/readSTLASCII.L @@ -33,8 +33,10 @@ License #include "IFstream.H" #include "triSurface.H" -#include "STLpoint.H" +#include "floatVector.H" #include "OSspecific.H" +#include "mergePoints.H" +//#include "memInfo.H" using namespace Foam; @@ -77,8 +79,8 @@ class STLLexer label lineNo_; word startError_; - DynamicList<STLpoint> STLpoints_; - //DynamicList<STLpoint> STLnormals_; + DynamicList<floatVector> STLpoints_; + //DynamicList<floatVector > STLnormals_; DynamicList<label> STLlabels_; HashTable<label, word> STLsolidNames_; @@ -103,12 +105,12 @@ public: return nTriangles_; } - DynamicList<STLpoint>& STLpoints() + DynamicList<floatVector>& STLpoints() { return STLpoints_; } - //DynamicList<STLpoint>& STLnormals() + //DynamicList<floatVector>& STLnormals() //{ // return STLnormals_; //} @@ -202,8 +204,8 @@ endsolid {space}("endsolid"|"ENDSOLID")({some_space}{word})* // End of read character pointer returned by strtof // char* endPtr; - STLpoint normal; - STLpoint vertex; + floatVector normal; + floatVector vertex; label cmpt = 0; // component index used for reading vertex static const char* stateNames[7] = @@ -387,16 +389,25 @@ bool triSurface::readSTLASCII(const fileName& STLfileName) << exit(FatalError); } + //memInfo memStat; + + //memStat.update(); + //Pout<< "At start:" << memStat.rss() << endl; + // Create the lexer obtaining the approximate number of vertices in the STL // from the file size STLLexer lexer(&STLstream.stdStream(), Foam::fileSize(STLfileName)/400); while (lexer.lex() != 0) {} - DynamicList<STLpoint>& STLpoints = lexer.STLpoints(); + //memStat.update(); + //Pout<< "After lexing:" << memStat.rss() << endl; + + DynamicList<floatVector>& STLpoints = lexer.STLpoints(); + DynamicList<label>& STLlabels = lexer.STLlabels(); /* - DynamicList<STLpoint>& STLnormals = lexer.STLnormals(); + DynamicList<floatVector>& STLnormals = lexer.STLnormals(); if (STLpoints.size() != 3*STLnormals.size()) { @@ -410,35 +421,51 @@ bool triSurface::readSTLASCII(const fileName& STLfileName) } */ - pointField rawPoints(STLpoints.size()); + labelList pointMap; + label nUniquePoints = mergePoints + ( + STLpoints, + 100*SMALL, // merge distance + false, // verbose + pointMap + ); - forAll(rawPoints, i) - { - rawPoints[i] = STLpoints[i]; - } + //memStat.update(); + //Pout<< "After merging:" << memStat.rss() << endl; - STLpoints.clear(); + + pointField& sp = storedPoints(); setSize(lexer.nTriangles()); - DynamicList<label>& STLlabels = lexer.STLlabels(); + sp.setSize(nUniquePoints); + forAll(STLpoints, pointI) + { + const floatVector& pt = STLpoints[pointI]; + sp[pointMap[pointI]] = vector + ( + scalar(pt.x()), + scalar(pt.y()), + scalar(pt.z()) + ); + } // Assign triangles - label pointi = 0; + label pointI = 0; forAll(*this, i) { - operator[](i)[0] = pointi++; - operator[](i)[1] = pointi++; - operator[](i)[2] = pointi++; + operator[](i)[0] = pointMap[pointI++]; + operator[](i)[1] = pointMap[pointI++]; + operator[](i)[2] = pointMap[pointI++]; operator[](i).region() = STLlabels[i]; } - STLlabels.clear(); + //memStat.update(); + //Pout<< "After assigning:" << memStat.rss() << endl; - // Assign coordinates - storedPoints().transfer(rawPoints); - // Stitch all points within SMALL meters. - stitchTriangles(); + STLpoints.clear(); + STLlabels.clear(); + // Convert solidNames into regionNames patches_.setSize(lexer.STLsolidNames().size()); @@ -457,6 +484,9 @@ bool triSurface::readSTLASCII(const fileName& STLfileName) // Fill in the missing information in the patches setDefaultPatches(); + //memStat.update(); + //Pout<< "After patchifying:" << memStat.rss() << endl; + return true; } diff --git a/src/triSurface/triSurface/interfaces/STL/readSTLBINARY.C b/src/triSurface/triSurface/interfaces/STL/readSTLBINARY.C index bf5d032b7ec226d3b438021cfd23f24d6dd0c28f..624aa1ada0af42ce97e93c08d4ad696bf2892abe 100644 --- a/src/triSurface/triSurface/interfaces/STL/readSTLBINARY.C +++ b/src/triSurface/triSurface/interfaces/STL/readSTLBINARY.C @@ -28,7 +28,8 @@ License #include "IFstream.H" #include "OSspecific.H" #include "gzstream.h" - +#include "floatVector.H" +#include "mergePoints.H" // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // @@ -94,40 +95,55 @@ bool Foam::triSurface::readSTLBINARY(const fileName& STLfileName) // Everything OK so go ahead and read the triangles. // Allocate storage for raw points - pointField rawPoints(3*nTris); - - // Allocate storage for triangles + List<floatVector> STLpoints(3*nTris); setSize(nTris); - label rawPointI = 0; + label pointI = 0; - // Read the triangles - forAll(*this, i) + for (label i = 0; i < nTris; i++) { // Read an STL triangle STLtriangle stlTri(STLfile); - // Set the rawPoints to the vertices of the STL triangle - // and set the point labels of the labelledTri - rawPoints[rawPointI] = stlTri.a(); - operator[](i)[0] = rawPointI++; - - rawPoints[rawPointI] = stlTri.b(); - operator[](i)[1] = rawPointI++; - - rawPoints[rawPointI] = stlTri.c(); - operator[](i)[2] = rawPointI++; - + // Set the STLpoints to the vertices of the STL triangle + STLpoints[pointI++] = stlTri.a(); + STLpoints[pointI++] = stlTri.b(); + STLpoints[pointI++] = stlTri.c(); operator[](i).region() = stlTri.region(); } - //STLfile.close(); + // Stitch points + labelList pointMap; + label nUniquePoints = mergePoints + ( + STLpoints, + 10*SMALL, // merge distance + false, // verbose + pointMap // old to new + ); + + pointField& sp = storedPoints(); - // Assign coordinates - storedPoints().transfer(rawPoints); + sp.setSize(nUniquePoints); + forAll(STLpoints, pointI) + { + const floatVector& pt = STLpoints[pointI]; + sp[pointMap[pointI]] = vector + ( + scalar(pt.x()), + scalar(pt.y()), + scalar(pt.z()) + ); + } - // Stitch all points within SMALL meters. - stitchTriangles(); + // Assign triangles + pointI = 0; + forAll(*this, i) + { + operator[](i)[0] = pointMap[pointI++]; + operator[](i)[1] = pointMap[pointI++]; + operator[](i)[2] = pointMap[pointI++]; + } return true; } diff --git a/wmake/rules/General/CGAL b/wmake/rules/General/CGAL index 126640dc0cf2f7e1c4dd84814e5fbe5526fd0add..3586a1de38517b79974e6337c72de4db4e56e028 100644 --- a/wmake/rules/General/CGAL +++ b/wmake/rules/General/CGAL @@ -9,4 +9,5 @@ CGAL_LIBS = \ -L$(MPFR_ARCH_PATH)/lib \ -L$(BOOST_ARCH_PATH)/lib \ -lmpfr \ - -lboost_thread + -I/usr/lib64 \ + -lboost_thread-mt