Salome HOME
bos #32738 [CEA] Scaled Jacobian quality mesh measure for volumetric elements.
[modules/smesh.git] / src / SMDS / SMDS_VolumeTool.cxx
index 9e144a620aaae174eef73eaa48e66d836edb02bd..c3b9ef30f701cfdf23c036d2d50403e428171444 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2023  CEA, EDF, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 
 #include "SMDS_MeshElement.hxx"
 #include "SMDS_MeshNode.hxx"
-#include "SMDS_VtkVolume.hxx"
 #include "SMDS_Mesh.hxx"
 
-#include "utilities.h"
+#include <utilities.h>
 
 #include <map>
 #include <limits>
 #include <cmath>
+#include <cstring>
 #include <numeric>
 #include <algorithm>
 
-using namespace std;
-
 namespace
 {
 // ======================================================
@@ -82,9 +80,17 @@ static int Tetra_RE [4][4] = { // REVERSED -> FORWARD (EXTERNAL)
   { 0, 3, 2, 0 }};
 static int Tetra_nbN [] = { 3, 3, 3, 3 };
 
-//
-//     PYRAMID
-//
+/*        
+//    N1 +---------+ N2
+//       | \     / | 
+//       |  \   /  |
+//       |   \ /   |
+//       |   /+\   |     PYRAMID
+//       |  / N4\  |
+//       | /     \ |
+//       |/       \|
+//    N0 +---------+ N3
+*/
 static int Pyramid_F [5][5] = { // FORWARD == EXTERNAL
   { 0, 1, 2, 3, 0 },            // All faces have external normals
   { 0, 4, 1, 0, 4 },
@@ -361,16 +367,22 @@ struct XYZ {
   XYZ( double X, double Y, double Z ) { x = X; y = Y; z = Z; }
   XYZ( const XYZ& other )             { x = other.x; y = other.y; z = other.z; }
   XYZ( const SMDS_MeshNode* n )       { x = n->X(); y = n->Y(); z = n->Z(); }
+  double* data()                      { return &x; }
   inline XYZ operator-( const XYZ& other );
   inline XYZ operator+( const XYZ& other );
   inline XYZ Crossed( const XYZ& other );
+  inline XYZ operator-();
   inline double Dot( const XYZ& other );
   inline double Magnitude();
   inline double SquareMagnitude();
+  inline XYZ Normalize();
 };
 inline XYZ XYZ::operator-( const XYZ& Right ) {
   return XYZ(x - Right.x, y - Right.y, z - Right.z);
 }
+inline XYZ XYZ::operator-() {
+  return XYZ(-x,-y,-z);
+}
 inline XYZ XYZ::operator+( const XYZ& Right ) {
   return XYZ(x + Right.x, y + Right.y, z + Right.z);
 }
@@ -388,6 +400,13 @@ inline double XYZ::Magnitude() {
 inline double XYZ::SquareMagnitude() {
   return (x * x + y * y + z * z);
 }
+inline XYZ XYZ::Normalize() {
+  double magnitude = Magnitude();
+  if ( magnitude != 0.0 )
+    return XYZ(x /= magnitude,y /= magnitude,z /= magnitude );   
+  else
+    return XYZ(x,y,z);
+}
 
   //================================================================================
   /*!
@@ -506,7 +525,7 @@ bool SMDS_VolumeTool::Set (const SMDS_MeshElement*                  theVolume,
   myNbFaces = theVolume->NbFaces();
   if ( myVolume->IsPoly() )
   {
-    myPolyedre = dynamic_cast<const SMDS_VtkVolume*>( myVolume );
+    myPolyedre = SMDS_Mesh::DownCast<SMDS_MeshVolume>( myVolume );
     myPolyFacetOri.resize( myNbFaces, 0 );
   }
 
@@ -522,10 +541,7 @@ bool SMDS_VolumeTool::Set (const SMDS_MeshElement*                  theVolume,
   }
   else
   {
-    int iNode = 0;
-    SMDS_ElemIteratorPtr nodeIt = myVolume->nodesIterator();
-    while ( nodeIt->more() )
-      myVolumeNodes[ iNode++ ] = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
+    myVolumeNodes.assign( myVolume->begin_nodes(), myVolume->end_nodes() );
   }
 
   // check validity
@@ -698,7 +714,6 @@ static double getTetraVolume(const SMDS_MeshNode* n1,
 //function : GetSize
 //purpose  : Return element volume
 //=======================================================================
-
 double SMDS_VolumeTool::GetSize() const
 {
   double V = 0.;
@@ -710,9 +725,11 @@ double SMDS_VolumeTool::GetSize() const
     if ( !myPolyedre )
       return 0.;
 
+    SaveFacet savedFacet( myCurFace );
+
     // split a polyhedron into tetrahedrons
 
-    SaveFacet savedFacet( myCurFace );
+    bool oriOk = true;
     SMDS_VolumeTool* me = const_cast< SMDS_VolumeTool* > ( this );
     for ( int f = 0; f < NbFaces(); ++f )
     {
@@ -725,8 +742,11 @@ double SMDS_VolumeTool::GetSize() const
         p1 = p2;
       }
       V += p1.Dot( area );
+      oriOk = oriOk && IsFaceExternal( f );
     }
     V /= 6;
+    if ( !oriOk && V > 0 )
+      V *= -1;
   }
   else 
   {
@@ -846,6 +866,334 @@ double SMDS_VolumeTool::GetSize() const
   return V;
 }
 
+
+//=======================================================================
+//function : getTetraScaledJacobian
+//purpose  : Given the smesh nodes in the canonical order of the tetrahedron, return the scaled jacobian
+//=======================================================================
+static double getTetraScaledJacobian(const SMDS_MeshNode* n0,
+                                     const SMDS_MeshNode* n1,
+                                     const SMDS_MeshNode* n2,
+                                     const SMDS_MeshNode* n3)
+{
+  const double sqrt = std::sqrt(2.0);
+  // Get the coordinates
+  XYZ p0( n0 );
+  XYZ p1( n1 );
+  XYZ p2( n2 );
+  XYZ p3( n3 );
+  // Define the edges connecting the nodes
+  XYZ L0 = p1-p0;
+  XYZ L1 = p2-p1;
+  XYZ L2 = p2-p0; // invert the definition of doc to get the proper orientation of the crossed product
+  XYZ L3 = p3-p0;
+  XYZ L4 = p3-p1;
+  XYZ L5 = p3-p2;
+  double Jacobian = L2.Crossed( L0 ).Dot( L3 );
+  double norm0 = L0.Magnitude();
+  double norm1 = L1.Magnitude();
+  double norm2 = L2.Magnitude();
+  double norm3 = L3.Magnitude();
+  double norm4 = L4.Magnitude();
+  double norm5 = L5.Magnitude();
+
+  std::array<double, 5> norms{};
+  norms[0] = Jacobian;
+  norms[1] = norm3*norm4*norm5;
+  norms[2] = norm1*norm2*norm5;
+  norms[3] = norm0*norm1*norm4;
+  norms[4] = norm0*norm2*norm3;  
+
+  auto findMaxNorm = std::max_element(norms.begin(), norms.end());
+  double maxNorm = *findMaxNorm;
+
+  if ( std::fabs( maxNorm ) < std::numeric_limits<double>::min() )
+    maxNorm = std::numeric_limits<double>::max();
+
+  return Jacobian * sqrt / maxNorm;
+}
+
+//=======================================================================
+//function : getPyramidScaledJacobian
+//purpose  : Given the pyramid, compute the scaled jacobian of the four tetrahedrons and return the minimun value.
+//=======================================================================
+static double getPyramidScaledJacobian(const SMDS_MeshNode* n0,
+                                        const SMDS_MeshNode* n1,
+                                        const SMDS_MeshNode* n2,
+                                        const SMDS_MeshNode* n3,
+                                        const SMDS_MeshNode* n4)
+{ 
+  const double sqrt = std::sqrt(2.0);
+  std::array<double, 4> tetScaledJacobian{};
+  tetScaledJacobian[0] = getTetraScaledJacobian(n0, n1, n3, n4);
+  tetScaledJacobian[1] = getTetraScaledJacobian(n1, n2, n0, n4);
+  tetScaledJacobian[2] = getTetraScaledJacobian(n2, n3, n1, n4);
+  tetScaledJacobian[3] = getTetraScaledJacobian(n3, n0, n2, n4);  
+
+  auto minEntry = std::min_element(tetScaledJacobian.begin(), tetScaledJacobian.end());
+
+  double scaledJacobian = (*minEntry) * 2.0/sqrt;
+  return scaledJacobian < 1.0 ? scaledJacobian : 1.0 - (scaledJacobian - 1.0);
+}
+
+
+
+//=======================================================================
+//function : getHexaScaledJacobian
+//purpose  : Evaluate the scaled jacobian on the eight vertices of the hexahedron and return the minimal registered value
+//remark   : Follow the reference numeration described at the top of the class.
+//=======================================================================
+static double getHexaScaledJacobian(const SMDS_MeshNode* n0,
+                                    const SMDS_MeshNode* n1,
+                                    const SMDS_MeshNode* n2,
+                                    const SMDS_MeshNode* n3,
+                                    const SMDS_MeshNode* n4,
+                                    const SMDS_MeshNode* n5,
+                                    const SMDS_MeshNode* n6,
+                                    const SMDS_MeshNode* n7)
+{ 
+  // Scaled jacobian is an scalar quantity measuring the deviation of the geometry from the perfect geometry
+  // Get the coordinates
+  XYZ p0( n0 );
+  XYZ p1( n1 );
+  XYZ p2( n2 );
+  XYZ p3( n3 );
+  XYZ p4( n4 );
+  XYZ p5( n5 );
+  XYZ p6( n6 );
+  XYZ p7( n7 );
+
+  // Define the edges connecting the nodes  
+  XYZ L0  = (p1-p0).Normalize();
+  XYZ L1  = (p2-p1).Normalize();
+  XYZ L2  = (p3-p2).Normalize();
+  XYZ L3  = (p3-p0).Normalize();
+  XYZ L4  = (p4-p0).Normalize();
+  XYZ L5  = (p5-p1).Normalize();
+  XYZ L6  = (p6-p2).Normalize();
+  XYZ L7  = (p7-p3).Normalize();
+  XYZ L8  = (p5-p4).Normalize();
+  XYZ L9  = (p6-p5).Normalize();
+  XYZ L10 = (p7-p6).Normalize();
+  XYZ L11 = (p7-p4).Normalize();
+  XYZ X0  = (p1-p0+p2-p3+p6-p7+p5-p4).Normalize();
+  XYZ X1  = (p3-p0+p2-p1+p7-p4+p6-p5).Normalize();
+  XYZ X2  = (p4-p0+p7-p3+p5-p1+p6-p2).Normalize();
+  
+  std::array<double, 9> scaledJacobian{};
+  //Scaled jacobian of nodes following their numeration
+  scaledJacobian[0] =  L4.Crossed( L3).Dot( L0 );   // For L0
+  scaledJacobian[1] =  L5.Crossed(-L0).Dot( L1 );   // For L1
+  scaledJacobian[2] =  L6.Crossed(-L1).Dot( L2 );   // For L2
+  scaledJacobian[3] =  L7.Crossed(-L2).Dot(-L3 );   // For L3
+  scaledJacobian[4] = -L4.Crossed( L8).Dot( L11 );  // For L11  
+  scaledJacobian[5] = -L5.Crossed( L9).Dot(-L8 );   // For L8
+  scaledJacobian[6] = -L6.Crossed(L10).Dot(-L9 );   // For L9
+  scaledJacobian[7] = -L7.Crossed(-L11).Dot(-L10 ); // For L10
+  scaledJacobian[8] =  X2.Crossed( X1).Dot( X0 );   // For principal axes
+
+  auto minScaledJacobian = std::min_element(scaledJacobian.begin(), scaledJacobian.end());
+  return *minScaledJacobian;
+}
+
+
+//=======================================================================
+//function : getTetraNormalizedJacobian
+//purpose  : Return the jacobian of the tetrahedron based on normalized vectors
+//=======================================================================
+static double getTetraNormalizedJacobian(const SMDS_MeshNode* n0,
+                                          const SMDS_MeshNode* n1,
+                                          const SMDS_MeshNode* n2,
+                                          const SMDS_MeshNode* n3)
+{
+  const double sqrt = std::sqrt(2.0);
+  // Get the coordinates
+  XYZ p0( n0 );
+  XYZ p1( n1 );
+  XYZ p2( n2 );
+  XYZ p3( n3 );
+  // Define the normalized edges connecting the nodes
+  XYZ L0 = (p1-p0).Normalize();
+  XYZ L2 = (p2-p0).Normalize(); // invert the definition of doc to get the proper orientation of the crossed product
+  XYZ L3 = (p3-p0).Normalize();
+  return L2.Crossed( L0 ).Dot( L3 );
+}
+
+//=======================================================================
+//function : getPentaScaledJacobian
+//purpose  : Evaluate the scaled jacobian on the pentahedron based on decomposed tetrahedrons
+//=======================================================================
+/*   
+//            + N1
+//           /|\
+//          / | \
+//         /  |  \
+//        /   |   \
+//    N0 +---------+ N2
+//       |    |    |               NUMERATION RERENCE FOLLOWING POSSITIVE RIGHT HAND RULE
+//       |    + N4 |               
+//       |   / \   |               PENTAHEDRON
+//       |  /   \  |
+//       | /     \ |
+//       |/       \|
+//    N3 +---------+ N5
+//
+//          N1
+//          +
+//          |\
+//         /| \
+//        / |  \
+//    N0 +--|---+ N2               TETRAHEDRON ASSOCIATED TO N0
+//       \  |   /                  Numeration passed to getTetraScaledJacobian 
+//        \ |  /                   N0=N0; N1=N2; N2=N3; N3=N1
+//         \| /                     
+//          |/
+//          +
+//          N3
+//
+//           N1
+//           +
+//          /|\
+//         / | \
+//        /  |  \
+//    N2 +---|---+ N5             TETRAHEDRON ASSOCIATED TO N2
+//       \   |  /                 Numeration passed to getTetraScaledJacobian 
+//        \  | /                  N0=N2; N1=N5; N2=N0; N3=N1
+//         \ |/
+//          \|
+//           +
+//           N0
+//
+//           N4
+//           +
+//          /|\
+//         / | \
+//        /  |  \
+//    N3 +---|---+ N0             TETRAHEDRON ASSOCIATED TO N3
+//       \   |   /                Numeration passed to getTetraScaledJacobian 
+//        \  |  /                 N0=N3; N1=N0; N2=N5; N3=N4
+//         \ | /
+//          \|/
+//           +
+//           N5
+//
+//           N3
+//           +
+//          /|\
+//         / | \
+//        /  |  \
+//    N1 +---|---+ N2             TETRAHEDRON ASSOCIATED TO N1
+//       \   |   /                Numeration passed to getTetraScaledJacobian 
+//        \  |  /                 N0=N1; N1=N2; N2=N0; N3=N3
+//         \ | /
+//          \|/
+//           +
+//           N0
+//
+//          ...
+*/
+static double getPentaScaledJacobian(const SMDS_MeshNode* n0,
+                                     const SMDS_MeshNode* n1,
+                                     const SMDS_MeshNode* n2,
+                                     const SMDS_MeshNode* n3,
+                                     const SMDS_MeshNode* n4,
+                                     const SMDS_MeshNode* n5)
+{ 
+  std::array<double, 6> scaledJacobianOfReferenceTetra{};
+  scaledJacobianOfReferenceTetra[0] = getTetraNormalizedJacobian(n0, n2, n3, n1);  // For n0
+  scaledJacobianOfReferenceTetra[1] = getTetraNormalizedJacobian(n2, n5, n0, n1);  // For n2
+  scaledJacobianOfReferenceTetra[2] = getTetraNormalizedJacobian(n3, n0, n5, n4);  // For n3
+  scaledJacobianOfReferenceTetra[3] = getTetraNormalizedJacobian(n5, n3, n2, n4);  // For n5
+  scaledJacobianOfReferenceTetra[4] = getTetraNormalizedJacobian(n1, n2, n0, n3);  // For n1  
+  scaledJacobianOfReferenceTetra[5] = getTetraNormalizedJacobian(n4, n3, n5, n2);  // For n4
+  
+  auto minScaledJacobian = std::min_element(scaledJacobianOfReferenceTetra.begin(), scaledJacobianOfReferenceTetra.end());
+  double minScalJac = (*minScaledJacobian)* 2.0 / std::sqrt(3.0);
+
+  if (minScalJac > 0)
+    return std::min(minScalJac, std::numeric_limits<double>::max());
+
+  return std::max(minScalJac, -std::numeric_limits<double>::max());
+}
+
+//=======================================================================
+//function : getHexaPrismScaledJacobian
+//purpose  : Evaluate the scaled jacobian on the hexaprism by decomposing the goemetry into three 1hexa + 2 pentahedrons
+//=======================================================================
+static double getHexaPrismScaledJacobian(const SMDS_MeshNode* n0,
+                                          const SMDS_MeshNode* n1,
+                                          const SMDS_MeshNode* n2,
+                                          const SMDS_MeshNode* n3,
+                                          const SMDS_MeshNode* n4,
+                                          const SMDS_MeshNode* n5,
+                                          const SMDS_MeshNode* n6,
+                                          const SMDS_MeshNode* n7,
+                                          const SMDS_MeshNode* n8,
+                                          const SMDS_MeshNode* n9,
+                                          const SMDS_MeshNode* n10, 
+                                          const SMDS_MeshNode* n11)
+{ 
+  // The Pentahedron from the left
+  // n0=n0; n1=n1; n2=n2; n3=n6; n4=n7, n5=n8; 
+  double scaledJacobianPentleft = getPentaScaledJacobian( n0, n1, n2, n6, n7, n8 );
+  // The core Hexahedron
+  // n0=n0; n1=n2, n2=n3; n3=n5; n4=n6; n5=n8; n6=n9; n7=n11
+  double scaledJacobianHexa     = getHexaScaledJacobian( n0, n2, n3, n5, n6, n8, n9, n11 );
+  // The Pentahedron from the right
+  // n0=n5; n1=n4; n2=n3; n3=n11; n4=n10; n5=n9
+  double scaledJacobianPentright = getPentaScaledJacobian( n5, n4, n3, n11, n10, n9 );
+
+  return std::min( scaledJacobianHexa, std::min( scaledJacobianPentleft, scaledJacobianPentright ) );
+  
+}
+
+//=======================================================================
+//function : GetScaledJacobian
+//purpose  : Return element Scaled Jacobian using the generic definition given 
+//            in https://gitlab.kitware.com/third-party/verdict/-/blob/master/SAND2007-2853p.pdf
+//=======================================================================
+
+double SMDS_VolumeTool::GetScaledJacobian() const
+{
+  
+  // For Tetra, call directly the getTetraScaledJacobian 
+  double scaledJacobian = 0.;
+
+  VolumeType type = GetVolumeType();    
+  switch (type)
+  {
+  case TETRA:
+  case QUAD_TETRA:
+    scaledJacobian = getTetraScaledJacobian( myVolumeNodes[0], myVolumeNodes[1], myVolumeNodes[2], myVolumeNodes[3] );
+    break;    
+  case HEXA:
+  case QUAD_HEXA: 
+    scaledJacobian = getHexaScaledJacobian( myVolumeNodes[0], myVolumeNodes[1], myVolumeNodes[2], myVolumeNodes[3],
+                                            myVolumeNodes[4], myVolumeNodes[5], myVolumeNodes[6], myVolumeNodes[7] );
+    break;
+  case PYRAM:
+  case QUAD_PYRAM:  
+    scaledJacobian = getPyramidScaledJacobian( myVolumeNodes[0], myVolumeNodes[1], myVolumeNodes[2], myVolumeNodes[3], myVolumeNodes[4] );
+    break;
+  case PENTA:
+  case QUAD_PENTA:
+    scaledJacobian = getPentaScaledJacobian( myVolumeNodes[0], myVolumeNodes[1], 
+                                             myVolumeNodes[2], myVolumeNodes[3], 
+                                             myVolumeNodes[4], myVolumeNodes[5] );
+    break;
+  case HEX_PRISM: 
+    scaledJacobian = getHexaPrismScaledJacobian( myVolumeNodes[0], myVolumeNodes[1], myVolumeNodes[2], myVolumeNodes[3], 
+                                                 myVolumeNodes[4], myVolumeNodes[5], myVolumeNodes[6], myVolumeNodes[7],
+                                                 myVolumeNodes[8], myVolumeNodes[9], myVolumeNodes[10], myVolumeNodes[11]);
+    break;
+  default:
+    break;
+  }
+
+  return scaledJacobian;
+}
+
+
 //=======================================================================
 //function : GetBaryCenter
 //purpose  : 
@@ -954,8 +1302,8 @@ const int* SMDS_VolumeTool::GetFaceNodesIndices( int faceIndex ) const
 //purpose  : Return a set of face nodes.
 //=======================================================================
 
-bool SMDS_VolumeTool::GetFaceNodes (int                        faceIndex,
-                                    set<const SMDS_MeshNode*>& theFaceNodes ) const
+bool SMDS_VolumeTool::GetFaceNodes (int                             faceIndex,
+                                    std::set<const SMDS_MeshNode*>& theFaceNodes ) const
 {
   if ( !setFace( faceIndex ))
     return false;
@@ -968,7 +1316,7 @@ bool SMDS_VolumeTool::GetFaceNodes (int                        faceIndex,
 
 namespace
 {
-  struct NLink : public std::pair<int,int>
+  struct NLink : public std::pair<smIdType,smIdType>
   {
     int myOri;
     NLink(const SMDS_MeshNode* n1=0, const SMDS_MeshNode* n2=0, int ori=1 )
@@ -1060,7 +1408,7 @@ bool SMDS_VolumeTool::IsFaceExternal( int faceIndex ) const
         {
           ori = ( -minProj < maxProj ? -1 : +1 );
           double convexity = std::min( -minProj, maxProj ) / std::max( -minProj, maxProj );
-          convexity2face.insert( make_pair( convexity, iF * ori ));
+          convexity2face.insert( std::make_pair( convexity, iF * ori ));
         }
       }
       if ( faceMostConvex < 0 ) // none facet has nodes on the same side
@@ -1089,7 +1437,7 @@ bool SMDS_VolumeTool::IsFaceExternal( int faceIndex ) const
   // compare orientation of links of the facet with myFwdLinks
   ori = 0;
   setFace( faceIndex );
-  vector< NLink > links( myCurFace.myNbNodes ), links2;
+  std::vector< NLink > links( myCurFace.myNbNodes ), links2;
   for ( int i = 0; i < myCurFace.myNbNodes && !ori; ++i )
   {
     NLink link( myCurFace.myNodes[i], myCurFace.myNodes[i+1] );
@@ -1147,7 +1495,8 @@ bool SMDS_VolumeTool::IsFaceExternal( int faceIndex ) const
 
 bool SMDS_VolumeTool::projectNodesToNormal( int     faceIndex,
                                             double& minProj,
-                                            double& maxProj ) const
+                                            double& maxProj,
+                                            double* normalXYZ ) const
 {
   minProj = std::numeric_limits<double>::max();
   maxProj = std::numeric_limits<double>::min();
@@ -1155,6 +1504,9 @@ bool SMDS_VolumeTool::projectNodesToNormal( int     faceIndex,
   XYZ normal;
   if ( !GetFaceNormal( faceIndex, normal.x, normal.y, normal.z ))
     return false;
+  if ( normalXYZ )
+    memcpy( normalXYZ, normal.data(), 3*sizeof(double));
+
   XYZ p0 ( myCurFace.myNodes[0] );
   for ( size_t i = 0; i < myVolumeNodes.size(); ++i )
   {
@@ -1202,15 +1554,17 @@ bool SMDS_VolumeTool::GetFaceNormal (int faceIndex, double & X, double & Y, doub
   XYZ aVec13( p3 - p1 );
   XYZ cross = aVec12.Crossed( aVec13 );
 
-  if ( myCurFace.myNbNodes >3*iQuad ) {
-    XYZ p4 ( myCurFace.myNodes[3*iQuad] );
+  for ( int i = 3*iQuad; i < myCurFace.myNbNodes; i += iQuad )
+  {
+    XYZ p4 ( myCurFace.myNodes[i] );
     XYZ aVec14( p4 - p1 );
     XYZ cross2 = aVec13.Crossed( aVec14 );
     cross = cross + cross2;
+    aVec13 = aVec14;
   }
 
   double size = cross.Magnitude();
-  if ( size <= numeric_limits<double>::min() )
+  if ( size <= std::numeric_limits<double>::min() )
     return false;
 
   X = cross.x / size;
@@ -1321,7 +1675,7 @@ int SMDS_VolumeTool::GetOppFaceIndex( int faceIndex ) const
     case 15:
       if ( faceIndex == 0 || faceIndex == 1 )
         ind = 1 - faceIndex;
-        break;
+      break;
     case 8:
     case 12:
       if ( faceIndex <= 1 ) // top or bottom
@@ -1382,7 +1736,7 @@ bool SMDS_VolumeTool::IsLinked (const SMDS_MeshNode* theNode1,
     } else {
       d2 = 0;
     }
-    vector<const SMDS_MeshNode*>::const_iterator i;
+    std::vector<const SMDS_MeshNode*>::const_iterator i;
     for (int iface = 0; iface < myNbFaces; iface++)
     {
       from = to;
@@ -1429,8 +1783,8 @@ bool SMDS_VolumeTool::IsLinked (const int theNode1Index,
     return IsLinked(myVolumeNodes[theNode1Index], myVolumeNodes[theNode2Index]);
   }
 
-  int minInd = min( theNode1Index, theNode2Index );
-  int maxInd = max( theNode1Index, theNode2Index );
+  int minInd = std::min( theNode1Index, theNode2Index );
+  int maxInd = std::max( theNode1Index, theNode2Index );
 
   if ( minInd < 0 || maxInd > (int)myVolumeNodes.size() - 1 || maxInd == minInd )
     return false;
@@ -1481,10 +1835,10 @@ bool SMDS_VolumeTool::IsLinked (const int theNode1Index,
   case QUAD_TETRA:
     {
       switch ( minInd ) {
-      case 0: if( maxInd==4 ||  maxInd==6 ||  maxInd==7 ) return true;
-      case 1: if( maxInd==4 ||  maxInd==5 ||  maxInd==8 ) return true;
-      case 2: if( maxInd==5 ||  maxInd==6 ||  maxInd==9 ) return true;
-      case 3: if( maxInd==7 ||  maxInd==8 ||  maxInd==9 ) return true;
+      case 0: return ( maxInd==4 ||  maxInd==6 ||  maxInd==7 );
+      case 1: return ( maxInd==4 ||  maxInd==5 ||  maxInd==8 );
+      case 2: return ( maxInd==5 ||  maxInd==6 ||  maxInd==9 );
+      case 3: return ( maxInd==7 ||  maxInd==8 ||  maxInd==9 );
       default:;
       }
       break;
@@ -1492,14 +1846,14 @@ bool SMDS_VolumeTool::IsLinked (const int theNode1Index,
   case QUAD_HEXA:
     {
       switch ( minInd ) {
-      case 0: if( maxInd==8 ||  maxInd==11 ||  maxInd==16 ) return true;
-      case 1: if( maxInd==8 ||  maxInd==9 ||  maxInd==17 ) return true;
-      case 2: if( maxInd==9 ||  maxInd==10 ||  maxInd==18 ) return true;
-      case 3: if( maxInd==10 ||  maxInd==11 ||  maxInd==19 ) return true;
-      case 4: if( maxInd==12 ||  maxInd==15 ||  maxInd==16 ) return true;
-      case 5: if( maxInd==12 ||  maxInd==13 ||  maxInd==17 ) return true;
-      case 6: if( maxInd==13 ||  maxInd==14 ||  maxInd==18 ) return true;
-      case 7: if( maxInd==14 ||  maxInd==15 ||  maxInd==19 ) return true;
+      case 0: return ( maxInd==8  ||  maxInd==11 ||  maxInd==16 );
+      case 1: return ( maxInd==8  ||  maxInd==9  ||  maxInd==17 );
+      case 2: return ( maxInd==9  ||  maxInd==10 ||  maxInd==18 );
+      case 3: return ( maxInd==10 ||  maxInd==11 ||  maxInd==19 );
+      case 4: return ( maxInd==12 ||  maxInd==15 ||  maxInd==16 );
+      case 5: return ( maxInd==12 ||  maxInd==13 ||  maxInd==17 );
+      case 6: return ( maxInd==13 ||  maxInd==14 ||  maxInd==18 );
+      case 7: return ( maxInd==14 ||  maxInd==15 ||  maxInd==19 );
       default:;
       }
       break;
@@ -1507,11 +1861,11 @@ bool SMDS_VolumeTool::IsLinked (const int theNode1Index,
   case QUAD_PYRAM:
     {
       switch ( minInd ) {
-      case 0: if( maxInd==5 ||  maxInd==8 ||  maxInd==9 ) return true;
-      case 1: if( maxInd==5 ||  maxInd==6 ||  maxInd==10 ) return true;
-      case 2: if( maxInd==6 ||  maxInd==7 ||  maxInd==11 ) return true;
-      case 3: if( maxInd==7 ||  maxInd==8 ||  maxInd==12 ) return true;
-      case 4: if( maxInd==9 ||  maxInd==10 ||  maxInd==11 ||  maxInd==12 ) return true;
+      case 0: return ( maxInd==5 ||  maxInd==8  ||  maxInd==9  );
+      case 1: return ( maxInd==5 ||  maxInd==6  ||  maxInd==10 );
+      case 2: return ( maxInd==6 ||  maxInd==7  ||  maxInd==11 );
+      case 3: return ( maxInd==7 ||  maxInd==8  ||  maxInd==12 );
+      case 4: return ( maxInd==9 ||  maxInd==10 ||  maxInd==11 ||  maxInd==12 );
       default:;
       }
       break;
@@ -1519,12 +1873,12 @@ bool SMDS_VolumeTool::IsLinked (const int theNode1Index,
   case QUAD_PENTA:
     {
       switch ( minInd ) {
-      case 0: if( maxInd==6 ||  maxInd==8 ||  maxInd==12 ) return true;
-      case 1: if( maxInd==6 ||  maxInd==7 ||  maxInd==13 ) return true;
-      case 2: if( maxInd==7 ||  maxInd==8 ||  maxInd==14 ) return true;
-      case 3: if( maxInd==9 ||  maxInd==11 ||  maxInd==12 ) return true;
-      case 4: if( maxInd==9 ||  maxInd==10 ||  maxInd==13 ) return true;
-      case 5: if( maxInd==10 ||  maxInd==11 ||  maxInd==14 ) return true;
+      case 0: return ( maxInd==6  ||  maxInd==8  ||  maxInd==12 );
+      case 1: return ( maxInd==6  ||  maxInd==7  ||  maxInd==13 );
+      case 2: return ( maxInd==7  ||  maxInd==8  ||  maxInd==14 );
+      case 3: return ( maxInd==9  ||  maxInd==11 ||  maxInd==12 );
+      case 4: return ( maxInd==9  ||  maxInd==10 ||  maxInd==13 );
+      case 5: return ( maxInd==10 ||  maxInd==11 ||  maxInd==14 );
       default:;
       }
       break;
@@ -1565,7 +1919,7 @@ int SMDS_VolumeTool::GetNodeIndex(const SMDS_MeshNode* theNode) const
  */
 //================================================================================
 
-int SMDS_VolumeTool::GetAllExistingFaces(vector<const SMDS_MeshElement*> & faces) const
+int SMDS_VolumeTool::GetAllExistingFaces(std::vector<const SMDS_MeshElement*> & faces) const
 {
   faces.clear();
   SaveFacet savedFacet( myCurFace );
@@ -1606,7 +1960,7 @@ int SMDS_VolumeTool::GetAllExistingFaces(vector<const SMDS_MeshElement*> & faces
  */
 //================================================================================
 
-int SMDS_VolumeTool::GetAllExistingEdges(vector<const SMDS_MeshElement*> & edges) const
+int SMDS_VolumeTool::GetAllExistingEdges(std::vector<const SMDS_MeshElement*> & edges) const
 {
   edges.clear();
   edges.reserve( myVolumeNodes.size() * 2 );
@@ -1717,7 +2071,7 @@ bool SMDS_VolumeTool::IsFreeFace( int faceIndex, const SMDS_MeshElement** otherV
       //   int nb = myCurFace.myNbNodes;
       //   if ( myVolume->GetEntityType() != vol->GetEntityType() )
       //     nb -= ( GetCenterNodeIndex(0) > 0 );
-      //   set<const SMDS_MeshNode*> faceNodes( nodes, nodes + nb );
+      //   std::set<const SMDS_MeshNode*> faceNodes( nodes, nodes + nb );
       //   if ( SMDS_VolumeTool( vol ).GetFaceIndex( faceNodes ) < 0 )
       //     continue;
       // }
@@ -1747,7 +2101,7 @@ bool SMDS_VolumeTool::IsFreeFaceAdv( int faceIndex, const SMDS_MeshElement** oth
 
   // evaluate nb of face nodes shared by other volumes
   int maxNbShared = -1;
-  typedef map< const SMDS_MeshElement*, int > TElemIntMap;
+  typedef std::map< const SMDS_MeshElement*, int > TElemIntMap;
   TElemIntMap volNbShared;
   TElemIntMap::iterator vNbIt;
   for ( int iNode = 0; iNode < nbFaceNodes; iNode++ ) {
@@ -1756,7 +2110,7 @@ bool SMDS_VolumeTool::IsFreeFaceAdv( int faceIndex, const SMDS_MeshElement** oth
     while ( eIt->more() ) {
       const SMDS_MeshElement* elem = eIt->next();
       if ( elem != myVolume ) {
-        vNbIt = volNbShared.insert( make_pair( elem, 0 )).first;
+        vNbIt = volNbShared.insert( std::make_pair( elem, 0 )).first;
         (*vNbIt).second++;
         if ( vNbIt->second > maxNbShared )
           maxNbShared = vNbIt->second;
@@ -1855,7 +2209,7 @@ bool SMDS_VolumeTool::IsFreeFaceAdv( int faceIndex, const SMDS_MeshElement** oth
 //purpose  : Return index of a face formed by theFaceNodes
 //=======================================================================
 
-int SMDS_VolumeTool::GetFaceIndex( const set<const SMDS_MeshNode*>& theFaceNodes,
+int SMDS_VolumeTool::GetFaceIndex( const std::set<const SMDS_MeshNode*>& theFaceNodes,
                                    const int                        theFaceIndexHint ) const
 {
   if ( theFaceIndexHint >= 0 )
@@ -1898,12 +2252,12 @@ int SMDS_VolumeTool::GetFaceIndex( const set<const SMDS_MeshNode*>& theFaceNodes
 //purpose  : Return index of a face formed by theFaceNodes
 //=======================================================================
 
-/*int SMDS_VolumeTool::GetFaceIndex( const set<int>& theFaceNodesIndices )
+/*int SMDS_VolumeTool::GetFaceIndex( const std::set<int>& theFaceNodesIndices )
 {
   for ( int iFace = 0; iFace < myNbFaces; iFace++ ) {
     const int* nodes = GetFaceNodesIndices( iFace );
     int nbFaceNodes = NbFaceNodes( iFace );
-    set<int> nodeSet;
+    std::set<int> nodeSet;
     for ( int iNode = 0; iNode < nbFaceNodes; iNode++ )
       nodeSet.insert( nodes[ iNode ] );
     if ( theFaceNodesIndices == nodeSet )
@@ -1932,7 +2286,7 @@ bool SMDS_VolumeTool::setFace( int faceIndex ) const
 
   if (myVolume->IsPoly())
   {
-    if (!myPolyedre) {
+    if ( !myPolyedre ) {
       MESSAGE("Warning: bad volumic element");
       return false;
     }
@@ -2203,7 +2557,7 @@ const SMDS_MeshVolume* SMDS_VolumeTool::Element() const
 //purpose  : return element ID
 //=======================================================================
 
-int SMDS_VolumeTool::ID() const
+smIdType SMDS_VolumeTool::ID() const
 {
   return myVolume ? myVolume->GetID() : 0;
 }