Salome HOME
New functionality: colinearizeKeepingConform2D().
[tools/medcoupling.git] / src / INTERP_KERNEL / CellModel.cxx
index dae609b3b741e7ded3a87393ea8b1cdf13a2f77a..8b45eaadc306f0b279289ae2e87b51aeb9740f09 100644 (file)
@@ -1,9 +1,9 @@
-// Copyright (C) 2007-2012  CEA/DEN, EDF R&D
+// Copyright (C) 2007-2016  CEA/DEN, EDF R&D
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 // License as published by the Free Software Foundation; either
-// version 2.1 of the License.
+// version 2.1 of the License, or (at your option) any later version.
 //
 // This library is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
 //
 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
-// Author : Anthony Geay (CEA/DEN)
+// Author : Anthony Geay (EDF R&D)
 
 #include "CellModel.hxx"
 
 #include "InterpKernelException.hxx"
+#include "DiameterCalculator.hxx"
+#include "OrientationInverter.hxx"
 
 #include <algorithm>
 #include <sstream>
@@ -34,7 +36,7 @@ namespace INTERP_KERNEL
                                             "NORM_SEG4", "", "", "", "NORM_TETRA4",//10->14
                                             "NORM_PYRA5", "NORM_PENTA6", "", "NORM_HEXA8", "",//15->19
                                             "NORM_TETRA10", "", "NORM_HEXGP12", "NORM_PYRA13", "",//20->24
-                                            "NORM_PENTA15", "", "NORM_HEXA27", "", "",//25->29
+                                            "NORM_PENTA15", "", "NORM_HEXA27", "NORM_PENTA18", "",//25->29
                                             "NORM_HEXA20", "NORM_POLYHED", "NORM_QPOLYG", "NORM_POLYL", "",//30->34
                                             "", "", "", "", "",//35->39
                                             "NORM_ERROR"};
@@ -98,6 +100,7 @@ namespace INTERP_KERNEL
     _map_of_unique_instance.insert(std::make_pair(NORM_HEXGP12,CellModel(NORM_HEXGP12)));
     _map_of_unique_instance.insert(std::make_pair(NORM_PYRA13,CellModel(NORM_PYRA13)));
     _map_of_unique_instance.insert(std::make_pair(NORM_PENTA15,CellModel(NORM_PENTA15)));
+    _map_of_unique_instance.insert(std::make_pair(NORM_PENTA18,CellModel(NORM_PENTA18)));
     _map_of_unique_instance.insert(std::make_pair(NORM_HEXA20,CellModel(NORM_HEXA20)));
     _map_of_unique_instance.insert(std::make_pair(NORM_HEXA27,CellModel(NORM_HEXA27)));
     _map_of_unique_instance.insert(std::make_pair(NORM_POLYGON,CellModel(NORM_POLYGON)));
@@ -358,6 +361,26 @@ namespace INTERP_KERNEL
           _little_sons_con[8][0]=2; _little_sons_con[8][1]=5; _little_sons_con[8][2]=14;
         }
         break;
+      case NORM_PENTA18:
+        {
+          _nb_of_pts=18; _nb_of_sons=5; _dim=3; _linear_type=NORM_PENTA6; _is_simplex=false;
+          _sons_type[0]=NORM_TRI6; _sons_type[1]=NORM_TRI6; _sons_type[2]=NORM_QUAD9; _sons_type[3]=NORM_QUAD9; _sons_type[4]=NORM_QUAD9;
+          _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=2; _sons_con[0][3]=6; _sons_con[0][4]=7; _sons_con[0][5]=8; _nb_of_sons_con[0]=6;
+          _sons_con[1][0]=3; _sons_con[1][1]=5; _sons_con[1][2]=4; _sons_con[1][3]=11; _sons_con[1][4]=10; _sons_con[1][5]=9; _nb_of_sons_con[1]=6;
+          _sons_con[2][0]=0; _sons_con[2][1]=3; _sons_con[2][2]=4; _sons_con[2][3]=1; _sons_con[2][4]=12; _sons_con[2][5]=9; _sons_con[2][6]=13; _sons_con[2][7]=6; _sons_con[2][8]=15; _nb_of_sons_con[2]=9;
+          _sons_con[3][0]=1; _sons_con[3][1]=4; _sons_con[3][2]=5; _sons_con[3][3]=2; _sons_con[3][4]=13; _sons_con[3][5]=10; _sons_con[3][6]=14; _sons_con[3][7]=7; _sons_con[3][8]=16; _nb_of_sons_con[3]=9;
+          _sons_con[4][0]=2; _sons_con[4][1]=4; _sons_con[4][2]=5; _sons_con[4][3]=0; _sons_con[4][4]=14; _sons_con[4][5]=11; _sons_con[4][6]=12; _sons_con[4][7]=8; _sons_con[4][8]=17; _nb_of_sons_con[4]=9; _quadratic=true;
+          _little_sons_con[0][0]=0; _little_sons_con[0][1]=1; _little_sons_con[0][2]=6;  _nb_of_little_sons=9;
+          _little_sons_con[1][0]=1; _little_sons_con[1][1]=2; _little_sons_con[1][2]=7;
+          _little_sons_con[2][0]=2; _little_sons_con[2][1]=0; _little_sons_con[2][2]=8;
+          _little_sons_con[3][0]=3; _little_sons_con[3][1]=4; _little_sons_con[3][2]=9;
+          _little_sons_con[4][0]=4; _little_sons_con[4][1]=5; _little_sons_con[4][2]=10;
+          _little_sons_con[5][0]=5; _little_sons_con[5][1]=3; _little_sons_con[5][2]=11;
+          _little_sons_con[6][0]=0; _little_sons_con[6][1]=3; _little_sons_con[6][2]=12;
+          _little_sons_con[7][0]=1; _little_sons_con[7][1]=4; _little_sons_con[7][2]=13;
+          _little_sons_con[8][0]=2; _little_sons_con[8][1]=5; _little_sons_con[8][2]=14;
+        }
+        break;
       case NORM_HEXA20:
         {
           _nb_of_pts=20; _nb_of_sons=6; _dim=3; _linear_type=NORM_HEXA8; _is_simplex=false;
@@ -365,9 +388,9 @@ namespace INTERP_KERNEL
           _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=2; _sons_con[0][3]=3; _sons_con[0][4]=8; _sons_con[0][5]=9; _sons_con[0][6]=10; _sons_con[0][7]=11; _nb_of_sons_con[0]=8;
           _sons_con[1][0]=4; _sons_con[1][1]=7; _sons_con[1][2]=6; _sons_con[1][3]=5; _sons_con[1][4]=15; _sons_con[1][5]=14; _sons_con[1][6]=13; _sons_con[1][7]=12; _nb_of_sons_con[1]=8;
           _sons_con[2][0]=0; _sons_con[2][1]=4; _sons_con[2][2]=5; _sons_con[2][3]=1; _sons_con[2][4]=16; _sons_con[2][5]=12; _sons_con[2][6]=17; _sons_con[2][7]=8; _nb_of_sons_con[2]=8;
-          _sons_con[3][0]=1; _sons_con[3][1]=5; _sons_con[3][3]=6; _sons_con[3][3]=2; _sons_con[3][4]=17; _sons_con[3][5]=13; _sons_con[3][6]=18; _sons_con[3][7]=9;_nb_of_sons_con[3]=8;
-          _sons_con[4][0]=2; _sons_con[4][1]=6; _sons_con[4][3]=7; _sons_con[4][3]=3; _sons_con[4][4]=18; _sons_con[4][5]=14; _sons_con[4][6]=19; _sons_con[4][7]=10; _nb_of_sons_con[4]=8;
-          _sons_con[5][0]=3; _sons_con[5][1]=7; _sons_con[5][3]=4; _sons_con[5][3]=0; _sons_con[5][4]=19; _sons_con[5][5]=15; _sons_con[5][6]=16; _sons_con[5][7]=11; _nb_of_sons_con[5]=8; _quadratic=true;
+          _sons_con[3][0]=1; _sons_con[3][1]=5; _sons_con[3][2]=6; _sons_con[3][3]=2; _sons_con[3][4]=17; _sons_con[3][5]=13; _sons_con[3][6]=18; _sons_con[3][7]=9;_nb_of_sons_con[3]=8;
+          _sons_con[4][0]=2; _sons_con[4][1]=6; _sons_con[4][2]=7; _sons_con[4][3]=3; _sons_con[4][4]=18; _sons_con[4][5]=14; _sons_con[4][6]=19; _sons_con[4][7]=10; _nb_of_sons_con[4]=8;
+          _sons_con[5][0]=3; _sons_con[5][1]=7; _sons_con[5][2]=4; _sons_con[5][3]=0; _sons_con[5][4]=19; _sons_con[5][5]=15; _sons_con[5][6]=16; _sons_con[5][7]=11; _nb_of_sons_con[5]=8; _quadratic=true;
           _little_sons_con[0][0]=0; _little_sons_con[0][1]=1;  _little_sons_con[0][2]=8; _nb_of_little_sons=12;
           _little_sons_con[1][0]=1; _little_sons_con[1][1]=2;  _little_sons_con[1][2]=9;
           _little_sons_con[2][0]=2; _little_sons_con[2][1]=3;  _little_sons_con[2][2]=10;
@@ -389,15 +412,15 @@ namespace INTERP_KERNEL
           _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=2; _sons_con[0][3]=3; _sons_con[0][4]=8; _sons_con[0][5]=9; _sons_con[0][6]=10; _sons_con[0][7]=11; _sons_con[0][8]=20; _nb_of_sons_con[0]=9;
           _sons_con[1][0]=4; _sons_con[1][1]=7; _sons_con[1][2]=6; _sons_con[1][3]=5; _sons_con[1][4]=15; _sons_con[1][5]=14; _sons_con[1][6]=13; _sons_con[1][7]=12; _sons_con[1][8]=25; _nb_of_sons_con[1]=9;
           _sons_con[2][0]=0; _sons_con[2][1]=4; _sons_con[2][2]=5; _sons_con[2][3]=1; _sons_con[2][4]=16; _sons_con[2][5]=12; _sons_con[2][6]=17; _sons_con[2][7]=8; _sons_con[2][8]=21; _nb_of_sons_con[2]=9;   
-          _sons_con[3][0]=1; _sons_con[3][1]=5; _sons_con[3][3]=6; _sons_con[3][3]=2; _sons_con[3][4]=17; _sons_con[3][5]=13; _sons_con[3][6]=18; _sons_con[3][7]=9; _sons_con[3][8]=22; _nb_of_sons_con[3]=9;
-          _sons_con[4][0]=2; _sons_con[4][1]=6; _sons_con[4][3]=7; _sons_con[4][3]=3; _sons_con[4][4]=18; _sons_con[4][5]=14; _sons_con[4][6]=19; _sons_con[4][7]=10; _sons_con[4][8]=23; _nb_of_sons_con[4]=9;
-          _sons_con[5][0]=3; _sons_con[5][1]=7; _sons_con[5][3]=4; _sons_con[5][3]=0; _sons_con[5][4]=19; _sons_con[5][5]=15; _sons_con[5][6]=16; _sons_con[5][7]=11; _sons_con[5][8]=24; _nb_of_sons_con[5]=9;
+          _sons_con[3][0]=1; _sons_con[3][1]=5; _sons_con[3][2]=6; _sons_con[3][3]=2; _sons_con[3][4]=17; _sons_con[3][5]=13; _sons_con[3][6]=18; _sons_con[3][7]=9; _sons_con[3][8]=22; _nb_of_sons_con[3]=9;
+          _sons_con[4][0]=2; _sons_con[4][1]=6; _sons_con[4][2]=7; _sons_con[4][3]=3; _sons_con[4][4]=18; _sons_con[4][5]=14; _sons_con[4][6]=19; _sons_con[4][7]=10; _sons_con[4][8]=23; _nb_of_sons_con[4]=9;
+          _sons_con[5][0]=3; _sons_con[5][1]=7; _sons_con[5][2]=4; _sons_con[5][3]=0; _sons_con[5][4]=19; _sons_con[5][5]=15; _sons_con[5][6]=16; _sons_con[5][7]=11; _sons_con[5][8]=24; _nb_of_sons_con[5]=9;
           _quadratic=true;
         }
         break;
       case NORM_POLYGON:
         {
-          _nb_of_pts=0; _nb_of_sons=0; _dim=2; _dyn=true; _extruded_type=NORM_POLYHED; _is_simplex=false;
+          _nb_of_pts=0; _nb_of_sons=0; _dim=2; _dyn=true; _extruded_type=NORM_POLYHED; _is_simplex=false; _quadratic_type=NORM_QPOLYG;
         }
         break;
       case NORM_POLYHED:
@@ -407,13 +430,14 @@ namespace INTERP_KERNEL
         break;
       case NORM_QPOLYG:
         {
-          _nb_of_pts=0; _nb_of_sons=0; _dim=2; _dyn=true; _is_simplex=false; _quadratic=true;
+          _nb_of_pts=0; _nb_of_sons=0; _dim=2; _dyn=true; _is_simplex=false; _quadratic=true; _linear_type=NORM_POLYGON;
         }
         break;
       case NORM_POLYL:
         {
           _nb_of_pts=0; _nb_of_sons=0; _dim=1; _dyn=true; _extruded_type=NORM_POLYGON; _is_simplex=false;
         }
+        break;
       case NORM_ERROR:
         {
           _nb_of_pts=std::numeric_limits<unsigned>::max(); _nb_of_sons=std::numeric_limits<unsigned>::max(); _dim=std::numeric_limits<unsigned>::max();
@@ -449,6 +473,58 @@ namespace INTERP_KERNEL
     else//polyhedron
       return (lgth-std::count(conn,conn+lgth,-1))/2;
   }
+  
+  /*!
+   * \sa fillMicroEdgeNodalConnectivity
+   */
+  unsigned CellModel::getNumberOfMicroEdges() const
+  {
+    unsigned mul(isQuadratic()?2:1);
+    if(!isDynamic())
+      {
+        switch(getDimension())
+          {
+          case 2:
+            return mul*getNumberOfSons();
+          case 3:
+            return mul*_nb_of_little_sons;
+          default:
+            throw INTERP_KERNEL::Exception("CellModel::getNumberOfMacroEdges : only 2D and 3D cells support this !");
+          }
+      }
+    else
+      throw INTERP_KERNEL::Exception("CellModel::getNumberOfMacroEdges : not supported by dynamic type !");
+  }
+  
+  NormalizedCellType CellModel::getCorrespondingPolyType() const
+  {
+    switch(getDimension())
+      {
+      case 0:
+        return NORM_POINT1;
+      case 1:
+        {
+          if(!isQuadratic())
+            return NORM_POLYL;
+          throw INTERP_KERNEL::Exception("CellModel::getPolyType : no poly type for quadratic 1D !");
+        }
+      case 2:
+        {
+          if(!isQuadratic())
+            return NORM_POLYGON;
+          else
+            return NORM_QPOLYG;
+        }
+      case 3:
+        {
+          if(!isQuadratic())
+            return NORM_POLYHED;
+          throw INTERP_KERNEL::Exception("CellModel::getPolyType : no poly type for quadratic 3D !");
+        }
+      default:
+        throw INTERP_KERNEL::Exception("CellModel::getPolyType : only dimension 0, 1, 2, 3 are supported !");
+      }
+  }
 
   /*!
    * Equivalent to getSonType except that this method deals with dynamic type.
@@ -497,7 +573,7 @@ namespace INTERP_KERNEL
                 sonNodalConn[1]=nodalConn[(sonId+1)%lgth];
                 return 2;
               }
-            else
+            else  // NORM_QPOLYG
               {
                 sonNodalConn[0]=nodalConn[sonId];
                 sonNodalConn[1]=nodalConn[(sonId+1)%(lgth/2)];
@@ -529,7 +605,7 @@ namespace INTERP_KERNEL
   {
     if(_type==NORM_HEXA8)
       {
-        static const int permutation[6]={0,2,3,4,1};
+        static const int permutation[6]={0,2,3,4,5,1};
         return fillSonCellNodalConnectivity2(permutation[sonId],nodalConn,lgth,sonNodalConn,typeOfSon);
       }
     else
@@ -560,6 +636,96 @@ namespace INTERP_KERNEL
       throw INTERP_KERNEL::Exception("CellModel::fillSonEdgesNodalConnectivity3D : not implemented yet for NORM_POLYHED !");   
   }
 
+  /*!
+   * \sa getNumberOfMicroEdges
+   */
+  unsigned CellModel::fillMicroEdgeNodalConnectivity(int sonId, const int *nodalConn, int *sonNodalConn, NormalizedCellType& typeOfSon) const
+  {
+    if(isQuadratic())
+      {
+        int edgeId(sonId/2),subEdgeId(sonId%2);
+        typeOfSon=NORM_SEG2;
+        const unsigned *sonConn(0);
+        switch(getDimension())
+          {
+          case 2:
+            {
+              sonConn=_sons_con[edgeId];
+              break;
+            }
+          case 3:
+            {
+              sonConn=_little_sons_con[edgeId];
+              break;
+            }
+          default:
+            throw INTERP_KERNEL::Exception("CellModel::fillMicroEdgeNodalConnectivity : only 2D and 3D cells support this !");
+          }
+        const unsigned tmp[3]={sonConn[0],sonConn[2],sonConn[1]};
+        sonNodalConn[0]=nodalConn[tmp[subEdgeId]];
+        sonNodalConn[1]=nodalConn[tmp[subEdgeId+1]];
+        return 2;
+      }
+    else
+      {
+        switch(getDimension())
+          {
+          case 2:
+            return fillSonCellNodalConnectivity2(sonId,nodalConn,0,sonNodalConn,typeOfSon);
+          case 3:
+            return fillSonEdgesNodalConnectivity3D(sonId,nodalConn,0,sonNodalConn,typeOfSon);
+          default:
+            throw INTERP_KERNEL::Exception("CellModel::fillMicroEdgeNodalConnectivity : only 2D and 3D cells support this #2 !");
+          }
+      }
+  }
+
+  void CellModel::changeOrientationOf2D(int *nodalConn, unsigned int sz) const
+  {
+    if(sz<1)
+      return ;
+    if(!isQuadratic())
+      {
+        std::vector<int> tmp(sz-1);
+        std::copy(nodalConn+1,nodalConn+sz,tmp.rbegin());
+        std::copy(tmp.begin(),tmp.end(),nodalConn+1);
+      }
+    else
+      {
+        unsigned int sz2(sz/2);
+        std::vector<int> tmp0(sz2-1),tmp1(sz2);
+        std::copy(nodalConn+1,nodalConn+sz2,tmp0.rbegin());
+        std::copy(nodalConn+sz2,nodalConn+sz,tmp1.rbegin());
+        std::copy(tmp0.begin(),tmp0.end(),nodalConn+1);
+        std::copy(tmp1.begin(),tmp1.end(),nodalConn+sz2);
+      }
+  }
+
+  void CellModel::changeOrientationOf1D(int *nodalConn, unsigned int sz) const
+  {
+    if(!isDynamic())
+      {
+        if(sz==2 || sz==3)
+          {
+            std::swap(nodalConn[0],nodalConn[1]);
+            return ;
+          }
+        else if(sz==4)
+          {
+            std::swap(nodalConn[0],nodalConn[1]);
+            std::swap(nodalConn[2],nodalConn[3]);
+          }
+        else
+          throw Exception("CellModel::changeOrientationOf1D : unrecognized 1D cell type !");
+      }
+    else
+      {
+        std::vector<int> tmp(sz-1);
+        std::copy(nodalConn+1,nodalConn+sz,tmp.rbegin());
+        std::copy(tmp.begin(),tmp.end(),nodalConn+1);
+      }
+  }
+
   //================================================================================
   /*!
    * \brief Return number of nodes in sonId-th son of a Dynamic() cell
@@ -658,5 +824,194 @@ namespace INTERP_KERNEL
           }
       }
   }
+  
+  DiameterCalculator *CellModel::buildInstanceOfDiameterCalulator(int spaceDim) const
+  {
+    switch(_type)
+      {
+      case NORM_TRI3:
+        {
+          switch(spaceDim)
+            {
+            case 2:
+              return new DiameterCalulatorTRI3S2;
+            case 3:
+              return new DiameterCalulatorTRI3S3;
+            default:
+              throw Exception("CellModel::buildInstanceOfDiameterCalulator : For TRI3 only space dimension 2 and 3 implemented !");
+            }
+          break;
+        }
+      case NORM_QUAD4:
+        {
+          switch(spaceDim)
+            {
+            case 2:
+              return new DiameterCalulatorQUAD4S2;
+            case 3:
+              return new DiameterCalulatorQUAD4S3;
+            default:
+              throw Exception("CellModel::buildInstanceOfDiameterCalulator : For QUAD4 only space dimension 2 and 3 implemented !");
+            }
+          break;
+        }
+      case NORM_TRI6:
+        {
+          switch(spaceDim)
+          {
+            case 2:
+              return new DiameterCalulatorTRI6S2;
+            case 3:
+              return new DiameterCalulatorTRI6S3;
+            default:
+              throw Exception("CellModel::buildInstanceOfDiameterCalulator : For TRI6 only space dimension 2 and 3 implemented !");
+          }
+          break;
+        }
+      case NORM_TRI7:
+        {
+          switch(spaceDim)
+          {
+            case 2:
+              return new DiameterCalulatorTRI7S2;
+            case 3:
+              return new DiameterCalulatorTRI7S3;
+            default:
+              throw Exception("CellModel::buildInstanceOfDiameterCalulator : For TRI7 only space dimension 2 and 3 implemented !");
+          }
+          break;
+        }
+      case NORM_QUAD8:
+        {
+          switch(spaceDim)
+          {
+            case 2:
+              return new DiameterCalulatorQUAD8S2;
+            case 3:
+              return new DiameterCalulatorQUAD8S3;
+            default:
+              throw Exception("CellModel::buildInstanceOfDiameterCalulator : For QUAD8 only space dimension 2 and 3 implemented !");
+          }
+          break;
+        }
+      case NORM_QUAD9:
+        {
+          switch(spaceDim)
+          {
+            case 2:
+              return new DiameterCalulatorQUAD9S2;
+            case 3:
+              return new DiameterCalulatorQUAD9S3;
+            default:
+              throw Exception("CellModel::buildInstanceOfDiameterCalulator : For QUAD9 only space dimension 2 and 3 implemented !");
+          }
+          break;
+        }
+      case NORM_TETRA4:
+        {
+          if(spaceDim==3)
+            return new DiameterCalulatorTETRA4;
+          else
+            throw Exception("CellModel::buildInstanceOfDiameterCalulator : For TETRA4 space dimension 3 expected !");
+        }
+      case NORM_TETRA10:
+        {
+          if(spaceDim==3)
+            return new DiameterCalulatorTETRA10;
+          else
+            throw Exception("CellModel::buildInstanceOfDiameterCalulator : For TETRA10 space dimension 3 expected !");
+        }
+      case NORM_HEXA8:
+        {
+          if(spaceDim==3)
+            return new DiameterCalulatorHEXA8;
+          else
+            throw Exception("CellModel::buildInstanceOfDiameterCalulator : For HEXA8 space dimension 3 expected !");
+        }
+      case NORM_HEXA20:
+        {
+          if(spaceDim==3)
+            return new DiameterCalulatorHEXA20;
+          else
+            throw Exception("CellModel::buildInstanceOfDiameterCalulator : For HEXA20 space dimension 3 expected !");
+        }
+      case NORM_HEXA27:
+        {
+          if(spaceDim==3)
+            return new DiameterCalulatorHEXA27;
+          else
+            throw Exception("CellModel::buildInstanceOfDiameterCalulator : For HEXA27 space dimension 3 expected !");
+        }
+      case NORM_PENTA6:
+        {
+          if(spaceDim==3)
+            return new DiameterCalulatorPENTA6;
+          else
+            throw Exception("CellModel::buildInstanceOfDiameterCalulator : For PENTA6 space dimension 3 expected !");
+        }
+      case NORM_PENTA15:
+        {
+          if(spaceDim==3)
+            return new DiameterCalulatorPENTA15;
+          else
+            throw Exception("CellModel::buildInstanceOfDiameterCalulator : For PENTA15 space dimension 3 expected !");
+        }
+      case NORM_PYRA5:
+        {
+          if(spaceDim==3)
+            return new DiameterCalulatorPYRA5;
+          else
+            throw Exception("CellModel::buildInstanceOfDiameterCalulator : For PYRA5 space dimension 3 expected !");
+        }
+      case NORM_PYRA13:
+        {
+          if(spaceDim==3)
+            return new DiameterCalulatorPYRA13;
+          else
+            throw Exception("CellModel::buildInstanceOfDiameterCalulator : For PYRA13 space dimension 3 expected !");
+        }
+      default:
+        throw Exception("CellModel::buildInstanceOfDiameterCalulator : implemented only for TRI3, QUAD4, TETRA4, HEXA8, PENTA6, PYRA5 !");
+      }
+  }
 
+  OrientationInverter *CellModel::buildOrientationInverter() const
+  {
+    switch(_type)
+      {
+      case NORM_SEG2:
+        return new OrientationInverterSEG2;
+      case NORM_SEG3:
+        return new OrientationInverterSEG3;
+      case NORM_TRI3:
+      case NORM_QUAD4:
+        return new OrientationInverter2DLinear(getNumberOfNodes());
+      case NORM_TRI6:
+      case NORM_QUAD8:
+        return new OrientationInverter2DQuadratic(getNumberOfNodes());
+      case NORM_POLYGON:
+        return new OrientationInverterPolygon;
+      case NORM_QPOLYG:
+        return new OrientationInverterQPolygon;
+      case NORM_TETRA4:
+        return new OrientationInverterTetra4;
+      case NORM_PYRA5:
+        return new OrientationInverterPyra5;
+      case NORM_TETRA10:
+        return new OrientationInverterTetra10;
+      case NORM_PYRA13:
+        return new OrientationInverterPyra13;
+      case NORM_PENTA6:
+      case NORM_HEXA8:
+        return new OrientationInverter3DExtrusionLinear(getNumberOfNodes());
+      case NORM_PENTA15:
+      case NORM_HEXA20:
+        return new OrientationInverter3DExtrusionQuadratic(getNumberOfNodes());
+      default:
+        {
+          std::ostringstream oss; oss << "CellModel::buildOrientationInverter : not managed geometric type " << getRepr() << " yet !";
+          throw INTERP_KERNEL::Exception(oss.str());
+        }
+      }
+  }
 }