From ecab63cc58160b8e180d530573af0c0eb8a4cb3f Mon Sep 17 00:00:00 2001 From: graham Date: Thu, 14 Jan 2010 13:32:51 +0000 Subject: [PATCH] Changing indexedCell to store an integer count of the number of times a dual vertex has been limited. Allowing the face filtering to continue after warning that mesh quality cannot be satisfied based on a control Switch. The filtering terminates when the number of wrongFaces is less than or equal to the intial number. There is a possiblity that the filtering will never converge in this mode (or in fact, any other). For example, if a face is on the brink of being "wrong" and a face motion on the other side of the cell moves the cell centre enough to make it "wrong", then the limiting mechanism won't be able to pick this up and stop it, unless limiting is applied to all points of all cells that are connected to a point that is on a wrong face. This can be done if a vertex on a face has been limited many (say > 4) times. --- .../conformalVoronoiMesh.C | 10 +-- .../conformalVoronoiMesh.H | 4 +- .../conformalVoronoiMeshCalcDualMesh.C | 86 +++++++++---------- .../conformalVoronoiMesh/indexedCell.H | 23 +++-- .../cvControls/cvControls.C | 9 ++ .../cvControls/cvControls.H | 17 ++-- .../cvControls/cvControlsI.H | 9 +- 7 files changed, 89 insertions(+), 69 deletions(-) diff --git a/src/mesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.C b/src/mesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.C index e146e488a0..351d0b9c49 100644 --- a/src/mesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.C +++ b/src/mesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.C @@ -1030,7 +1030,7 @@ Foam::face Foam::conformalVoronoiMesh::buildDualFace } -Foam::scalar Foam::conformalVoronoiMesh::minFilterLimit +Foam::label Foam::conformalVoronoiMesh::maxFilterCount ( const Triangulation::Finite_edges_iterator& eit ) const @@ -1038,7 +1038,7 @@ Foam::scalar Foam::conformalVoronoiMesh::minFilterLimit Cell_circulator ccStart = incident_cells(*eit); Cell_circulator cc = ccStart; - scalar minFilterLimit = GREAT; + label maxFC = 0; do { @@ -1057,16 +1057,16 @@ Foam::scalar Foam::conformalVoronoiMesh::minFilterLimit << exit(FatalError); } - if (cc->filterLimit() < minFilterLimit) + if (cc->filterCount() > maxFC) { - minFilterLimit = cc->filterLimit(); + maxFC = cc->filterCount(); } cc++; } while (cc != ccStart); - return minFilterLimit; + return maxFC; } diff --git a/src/mesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.H b/src/mesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.H index 095ddc5a18..0a62fc2ee0 100644 --- a/src/mesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.H +++ b/src/mesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.H @@ -357,10 +357,10 @@ private: const Triangulation::Finite_edges_iterator& eit ) const; - //- Finds the minimum filterLimit of the dual vertices + //- Finds the maximum filterCount of the dual vertices // (Delaunay cells) that form the dual face produced by the // supplied edge - scalar minFilterLimit + label maxFilterCount ( const Triangulation::Finite_edges_iterator& eit ) const; diff --git a/src/mesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshCalcDualMesh.C b/src/mesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshCalcDualMesh.C index 489401a77d..1fcff45b23 100644 --- a/src/mesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshCalcDualMesh.C +++ b/src/mesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshCalcDualMesh.C @@ -76,6 +76,18 @@ void Foam::conformalVoronoiMesh::calcDualMesh } } + // Make all filterCount values zero + + for + ( + Triangulation::Finite_cells_iterator cit = finite_cells_begin(); + cit != finite_cells_end(); + ++cit + ) + { + cit->filterCount() = 0; + } + indexDualVertices(points); { @@ -100,14 +112,22 @@ void Foam::conformalVoronoiMesh::calcDualMesh if (nInitialBadQualityFaces > 0) { - Info<< "A mesh could not be produced to satisfy the specified quality " - << "criteria. The quality and the surface conformation controls " - << "can be altered and the internalDelaunayVertices read in to try " - << "again, or more cell size resolution and motion iterations can " - << "be applied in areas where problems are occurring." + Info<< nl + << "A mesh could not be produced to satisfy the specified " + << "quality criteria." << nl + << "The quality and the surface conformation controls " + << "can be altered and the internalDelaunayVertices read in " + << "to try again, or more cell size resolution and motion " + << "iterations can be applied in areas where problems are " + << "occurring." << endl; } - else + + if + ( + nInitialBadQualityFaces == 0 + || cvMeshControls().continueFilteringOnBadInitialPolyMesh() + ) { label nBadQualityFaces = 0; @@ -141,7 +161,7 @@ void Foam::conformalVoronoiMesh::calcDualMesh Info<< "Found " << nBadQualityFaces << " bad quality faces" << endl; - } while (nBadQualityFaces > 0); + } while (nBadQualityFaces > nInitialBadQualityFaces); } // Final dual face and owner neighbour construction @@ -477,7 +497,7 @@ void Foam::conformalVoronoiMesh::smoothSurface(pointField& pts) { label ptI = cit->cellIndex(); - if (cit->filterLimit() < 1.0) + if (cit->filterCount() > 0) { // This vertex has been limited, skip continue; @@ -578,9 +598,9 @@ Foam::label Foam::conformalVoronoiMesh::smoothSurfaceDualFaces continue; } - scalar minFL = minFilterLimit(eit); + label maxFC = maxFilterCount(eit); - if (minFL < 1.0) + if (maxFC > 0) { // A vertex on this face has been limited, skip continue; @@ -755,9 +775,9 @@ Foam::label Foam::conformalVoronoiMesh::collapseFaces continue; } - scalar minFL = minFilterLimit(eit); + label maxFC = maxFilterCount(eit); - if (minFL < 1.0) + if (maxFC > 0) { // A vertex on this face has been limited, skip continue; @@ -817,7 +837,7 @@ Foam::conformalVoronoiMesh::collapseFace scalar collapseSizeLimitCoeff ) const { - bool limitToQuadsOrTris = true; + bool limitToQuadsOrTris = false; bool allowEarlyCollapseToPoint = true; @@ -1297,7 +1317,7 @@ Foam::label Foam::conformalVoronoiMesh::checkPolyMeshQuality } } - Info<< "Cells with fewer than 4 faces : " + Info<< "Cells with more than 1 but fewer than 4 faces : " << nInvalidPolyhedra << endl; PackedBoolList ptToBeLimited(pts.size(), false); @@ -1350,7 +1370,10 @@ Foam::label Foam::conformalVoronoiMesh::checkPolyMeshQuality // } - // Limit Delaunay cell filter values + // Apply Delaunay cell filterCounts and determine the maximum + // overall filterCount + + label maxFilterCount = 0; for ( @@ -1365,42 +1388,17 @@ Foam::label Foam::conformalVoronoiMesh::checkPolyMeshQuality { if (ptToBeLimited[cI] == true) { - cit->filterLimit() *= 0.75; + cit->filterCount()++; } - } - } - // Determine the minimum minFilterLimit - - scalar minMinFilterLimit = GREAT; - - for - ( - Triangulation::Finite_edges_iterator eit = finite_edges_begin(); - eit != finite_edges_end(); - ++eit - ) - { - Cell_handle c = eit->first; - Vertex_handle vA = c->vertex(eit->second); - Vertex_handle vB = c->vertex(eit->third); - - if - ( - vA->internalOrBoundaryPoint() - || vB->internalOrBoundaryPoint() - ) - { - scalar minFL = minFilterLimit(eit); - - if (minFL < minMinFilterLimit) + if (cit->filterCount() > maxFilterCount) { - minMinFilterLimit = minFL; + maxFilterCount = cit->filterCount(); } } } - Info<< "minMinFilterLimit " << minMinFilterLimit << endl; + Info<< "maxFilterCount " << maxFilterCount << endl; return wrongFaces.size(); diff --git a/src/mesh/conformalVoronoiMesh/conformalVoronoiMesh/indexedCell.H b/src/mesh/conformalVoronoiMesh/conformalVoronoiMesh/indexedCell.H index 91ac79c57a..7afa7a55e5 100644 --- a/src/mesh/conformalVoronoiMesh/conformalVoronoiMesh/indexedCell.H +++ b/src/mesh/conformalVoronoiMesh/conformalVoronoiMesh/indexedCell.H @@ -36,7 +36,6 @@ Description #include #include "indexedVertex.H" -#include "scalar.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -54,12 +53,12 @@ class indexedCell { // Private data - //- The index for this tetrahedral cell + //- The index for this Delaunay tetrahedral cell int index_; - //- The applicable fraction of the face filtering mechanism - // controls - Foam::scalar filterLimit_; + //- The number of times that this Delaunay cell has been limited + // during filtering + int filterCount_; public: @@ -79,7 +78,7 @@ public: : Cb(), index_(-1), - filterLimit_(1.0) + filterCount_(0) {} @@ -90,7 +89,7 @@ public: : Cb(v0, v1, v2, v3), index_(-1), - filterLimit_(1.0) + filterCount_(0) {} @@ -108,7 +107,7 @@ public: : Cb(v0, v1, v2, v3, n0, n1, n2, n3), index_(-1), - filterLimit_(1.0) + filterCount_(0) {} @@ -124,15 +123,15 @@ public: } - inline Foam::scalar& filterLimit() + inline int& filterCount() { - return filterLimit_; + return filterCount_; } - inline Foam::scalar filterLimit() const + inline int filterCount() const { - return filterLimit_; + return filterCount_; } }; diff --git a/src/mesh/conformalVoronoiMesh/cvControls/cvControls.C b/src/mesh/conformalVoronoiMesh/cvControls/cvControls.C index 06612354c4..53e1d5309b 100644 --- a/src/mesh/conformalVoronoiMesh/cvControls/cvControls.C +++ b/src/mesh/conformalVoronoiMesh/cvControls/cvControls.C @@ -157,6 +157,15 @@ Foam::cvControls::cvControls filteringDict.lookup("mergeClosenessCoeff") ); + continueFilteringOnBadInitialPolyMesh_ = Switch + ( + filteringDict.lookupOrDefault + ( + "continueFilteringOnBadInitialPolyMesh", + false + ) + ); + surfaceStepFaceAngle_ = readScalar ( filteringDict.lookup("surfaceStepFaceAngle") diff --git a/src/mesh/conformalVoronoiMesh/cvControls/cvControls.H b/src/mesh/conformalVoronoiMesh/cvControls/cvControls.H index 1570e29eea..5d62f228cc 100644 --- a/src/mesh/conformalVoronoiMesh/cvControls/cvControls.H +++ b/src/mesh/conformalVoronoiMesh/cvControls/cvControls.H @@ -147,10 +147,18 @@ class cvControls // polyMesh filtering controls + //- Upper limit on the size of faces to be filtered from, + // fraction of the local target cell size + scalar filterSizeCoeff_; + //- Upper limit on how close two dual vertices can be before // being merged, fraction of the local target cell size scalar mergeClosenessCoeff_; + //- If the mesh quality criteria cannot be satisfied, continue + // with filtering anyway? + Switch continueFilteringOnBadInitialPolyMesh_; + //- The maximum allowed angle between a boundary face normal // and the local surface normal before face will be // aggressively collapsed @@ -173,10 +181,6 @@ class cvControls // the local target cell size scalar maxCollapseFaceToPointSideLengthCoeff_; - //- Upper limit on the size of faces to be filtered from, - // fraction of the local target cell size - scalar filterSizeCoeff_; - // Private Member Functions @@ -244,7 +248,7 @@ public: inline label surfaceConformationRebuildFrequency() const; //- Return the objOutput Switch - inline bool objOutput() const; + inline Switch objOutput() const; //- Return the number of alignmentSearchSpokes to use inline label alignmentSearchSpokes() const; @@ -270,6 +274,9 @@ public: //- Return the mergeClosenessCoeff inline scalar mergeClosenessCoeff() const; + //- Return the continueFilteringOnBadInitialPolyMesh Switch + inline Switch continueFilteringOnBadInitialPolyMesh() const; + //- Return the surfaceStepFaceAngle inline scalar surfaceStepFaceAngle() const; diff --git a/src/mesh/conformalVoronoiMesh/cvControls/cvControlsI.H b/src/mesh/conformalVoronoiMesh/cvControls/cvControlsI.H index 7220148a0e..3fe37fe44d 100644 --- a/src/mesh/conformalVoronoiMesh/cvControls/cvControlsI.H +++ b/src/mesh/conformalVoronoiMesh/cvControls/cvControlsI.H @@ -98,7 +98,7 @@ inline Foam::label Foam::cvControls::surfaceConformationRebuildFrequency() const } -inline bool Foam::cvControls::objOutput() const +inline Foam::Switch Foam::cvControls::objOutput() const { return objOutput_; } @@ -152,6 +152,13 @@ inline Foam::scalar Foam::cvControls::mergeClosenessCoeff() const } +inline Foam::Switch +Foam::cvControls::continueFilteringOnBadInitialPolyMesh() const +{ + return continueFilteringOnBadInitialPolyMesh_; +} + + inline Foam::scalar Foam::cvControls::surfaceStepFaceAngle() const { return surfaceStepFaceAngle_;