From f0f625f60982875e656a1ca2b80beb062695e8da Mon Sep 17 00:00:00 2001 From: ouv Date: Wed, 13 Oct 2010 09:49:12 +0000 Subject: [PATCH] Issue 0020947: EDF 1467 SMESH: Modify the formula to calculate Aspect Ratio on quadrangles --- doc/salome/gui/SMESH/images/formula5.png | Bin 0 -> 5184 bytes doc/salome/gui/SMESH/input/aspect_ratio.doc | 8 +- src/Controls/SMESH_Controls.cxx | 118 ++++++++++++++------ 3 files changed, 86 insertions(+), 40 deletions(-) create mode 100644 doc/salome/gui/SMESH/images/formula5.png diff --git a/doc/salome/gui/SMESH/images/formula5.png b/doc/salome/gui/SMESH/images/formula5.png new file mode 100644 index 0000000000000000000000000000000000000000..823ba068dc0fc02f61f4d416ee0fb0aa90c1ca6d GIT binary patch literal 5184 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 O09f1T&Rb3U$o~SkVZ?I) literal 0 HcmV?d00001 diff --git a/doc/salome/gui/SMESH/input/aspect_ratio.doc b/doc/salome/gui/SMESH/input/aspect_ratio.doc index 070d377cc..5e1f31673 100644 --- a/doc/salome/gui/SMESH/input/aspect_ratio.doc +++ b/doc/salome/gui/SMESH/input/aspect_ratio.doc @@ -13,10 +13,10 @@ nodes is calculated by the formula: \image html formula4.png -- The Aspect Ratio of a \b quadrangle 2D element consisting of - 4 nodes is the worst (i.e. the greatest) value from all triangles - which can be built taking three nodes of the quadrangle. There are - four triangles to consider: +- The Aspect Ratio of a \b quadrangle 2D element consisting of 4 +nodes is calculated by the formula: + +\image html formula5.png \image html image138.gif diff --git a/src/Controls/SMESH_Controls.cxx b/src/Controls/SMESH_Controls.cxx index 4b370e61b..8f18f6605 100644 --- a/src/Controls/SMESH_Controls.cxx +++ b/src/Controls/SMESH_Controls.cxx @@ -465,46 +465,92 @@ double AspectRatio::GetValue( const TSequenceOfXYZ& P ) return alfa * maxLen * half_perimeter / anArea; } else if( nbNodes == 4 ) { // quadrangle - // return aspect ratio of the worst triange which can be built + // Compute lengths of the sides + std::vector< double > aLen (4); + aLen[0] = getDistance( P(1), P(2) ); + aLen[1] = getDistance( P(2), P(3) ); + aLen[2] = getDistance( P(3), P(4) ); + aLen[3] = getDistance( P(4), P(1) ); + // Compute lengths of the diagonals + std::vector< double > aDia (2); + aDia[0] = getDistance( P(1), P(3) ); + aDia[1] = getDistance( P(2), P(4) ); + // Compute areas of all triangles which can be built // taking three nodes of the quadrangle - TSequenceOfXYZ triaPnts(3); - // triangle on nodes 1 3 2 - triaPnts(1) = P(1); - triaPnts(2) = P(3); - triaPnts(3) = P(2); - double ar = GetValue( triaPnts ); - // triangle on nodes 1 3 4 - triaPnts(3) = P(4); - ar = Max ( ar, GetValue( triaPnts )); - // triangle on nodes 1 2 4 - triaPnts(2) = P(2); - ar = Max ( ar, GetValue( triaPnts )); - // triangle on nodes 3 2 4 - triaPnts(1) = P(3); - ar = Max ( ar, GetValue( triaPnts )); - - return ar; + std::vector< double > anArea (4); + anArea[0] = getArea( P(1), P(2), P(3) ); + anArea[1] = getArea( P(1), P(2), P(4) ); + anArea[2] = getArea( P(1), P(3), P(4) ); + anArea[3] = getArea( P(2), P(3), P(4) ); + // Q = alpha * L * C1 / C2, where + // + // alpha = sqrt( 1/32 ) + // L = max( L1, L2, L3, L4, D1, D2 ) + // C1 = sqrt( ( L1^2 + L1^2 + L1^2 + L1^2 ) / 4 ) + // C2 = min( S1, S2, S3, S4 ) + // Li - lengths of the edges + // Di - lengths of the diagonals + // Si - areas of the triangles + const double alpha = sqrt( 1 / 32. ); + double L = Max( aLen[ 0 ], + Max( aLen[ 1 ], + Max( aLen[ 2 ], + Max( aLen[ 3 ], + Max( aDia[ 0 ], aDia[ 1 ] ) ) ) ) ); + double C1 = sqrt( ( aLen[0] * aLen[0] + + aLen[1] * aLen[1] + + aLen[2] * aLen[2] + + aLen[3] * aLen[3] ) / 4. ); + double C2 = Min( anArea[ 0 ], + Min( anArea[ 1 ], + Min( anArea[ 2 ], anArea[ 3 ] ) ) ); + if ( C2 <= Precision::Confusion() ) + return 0.; + return alpha * L * C1 / C2; } else if( nbNodes == 8 ){ // nbNodes==8 - quadratic quadrangle - // return aspect ratio of the worst triange which can be built + // Compute lengths of the sides + std::vector< double > aLen (4); + aLen[0] = getDistance( P(1), P(3) ); + aLen[1] = getDistance( P(3), P(5) ); + aLen[2] = getDistance( P(5), P(7) ); + aLen[3] = getDistance( P(7), P(1) ); + // Compute lengths of the diagonals + std::vector< double > aDia (2); + aDia[0] = getDistance( P(1), P(5) ); + aDia[1] = getDistance( P(3), P(7) ); + // Compute areas of all triangles which can be built // taking three nodes of the quadrangle - TSequenceOfXYZ triaPnts(3); - // triangle on nodes 1 3 2 - triaPnts(1) = P(1); - triaPnts(2) = P(5); - triaPnts(3) = P(3); - double ar = GetValue( triaPnts ); - // triangle on nodes 1 3 4 - triaPnts(3) = P(7); - ar = Max ( ar, GetValue( triaPnts )); - // triangle on nodes 1 2 4 - triaPnts(2) = P(3); - ar = Max ( ar, GetValue( triaPnts )); - // triangle on nodes 3 2 4 - triaPnts(1) = P(5); - ar = Max ( ar, GetValue( triaPnts )); - - return ar; + std::vector< double > anArea (4); + anArea[0] = getArea( P(1), P(3), P(5) ); + anArea[1] = getArea( P(1), P(3), P(7) ); + anArea[2] = getArea( P(1), P(5), P(7) ); + anArea[3] = getArea( P(3), P(5), P(7) ); + // Q = alpha * L * C1 / C2, where + // + // alpha = sqrt( 1/32 ) + // L = max( L1, L2, L3, L4, D1, D2 ) + // C1 = sqrt( ( L1^2 + L1^2 + L1^2 + L1^2 ) / 4 ) + // C2 = min( S1, S2, S3, S4 ) + // Li - lengths of the edges + // Di - lengths of the diagonals + // Si - areas of the triangles + const double alpha = sqrt( 1 / 32. ); + double L = Max( aLen[ 0 ], + Max( aLen[ 1 ], + Max( aLen[ 2 ], + Max( aLen[ 3 ], + Max( aDia[ 0 ], aDia[ 1 ] ) ) ) ) ); + double C1 = sqrt( ( aLen[0] * aLen[0] + + aLen[1] * aLen[1] + + aLen[2] * aLen[2] + + aLen[3] * aLen[3] ) / 4. ); + double C2 = Min( anArea[ 0 ], + Min( anArea[ 1 ], + Min( anArea[ 2 ], anArea[ 3 ] ) ) ); + if ( C2 <= Precision::Confusion() ) + return 0.; + return alpha * L * C1 / C2; } return 0; } -- 2.39.2