Salome HOME
Doc: indicating how to pass MPI_Comm from mpi4py
[tools/medcoupling.git] / src / INTERP_KERNEL / CellModel.cxx
1 // Copyright (C) 2007-2022  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 // Author : Anthony Geay (EDF R&D)
20
21 #include "CellModel.hxx"
22
23 #include "InterpKernelException.hxx"
24 #include "DiameterCalculator.hxx"
25 #include "OrientationInverter.hxx"
26
27 #include <algorithm>
28 #include <sstream>
29 #include <vector>
30 #include <limits>
31
32 unsigned char MEDCOUPLING2VTKTYPETRADUCER[INTERP_KERNEL::NORM_MAXTYPE+1]={1,3,21,5,9,7,22,34,23,28,35,MEDCOUPLING2VTKTYPETRADUCER_NONE,MEDCOUPLING2VTKTYPETRADUCER_NONE,MEDCOUPLING2VTKTYPETRADUCER_NONE,10,14,13,MEDCOUPLING2VTKTYPETRADUCER_NONE,12,MEDCOUPLING2VTKTYPETRADUCER_NONE,24,MEDCOUPLING2VTKTYPETRADUCER_NONE,16,27,MEDCOUPLING2VTKTYPETRADUCER_NONE,26,MEDCOUPLING2VTKTYPETRADUCER_NONE,29,32,MEDCOUPLING2VTKTYPETRADUCER_NONE,25,42,36,4};
33
34 namespace INTERP_KERNEL
35 {
36   const char *CellModel::CELL_TYPES_REPR[]={"NORM_POINT1", "NORM_SEG2", "NORM_SEG3", "NORM_TRI3", "NORM_QUAD4",// 0->4
37                                             "NORM_POLYGON", "NORM_TRI6", "NORM_TRI7" , "NORM_QUAD8", "NORM_QUAD9",//5->9
38                                             "NORM_SEG4", "", "", "", "NORM_TETRA4",//10->14
39                                             "NORM_PYRA5", "NORM_PENTA6", "", "NORM_HEXA8", "",//15->19
40                                             "NORM_TETRA10", "", "NORM_HEXGP12", "NORM_PYRA13", "",//20->24
41                                             "NORM_PENTA15", "", "NORM_HEXA27", "NORM_PENTA18", "",//25->29
42                                             "NORM_HEXA20", "NORM_POLYHED", "NORM_QPOLYG", "NORM_POLYL", "",//30->34
43                                             "", "", "", "", "",//35->39
44                                             "NORM_ERROR"};
45
46   const CellModel& CellModel::GetCellModel(NormalizedCellType type)
47   {
48     const std::map<NormalizedCellType,CellModel>& map_unique = GetMapOfUniqueInstance();
49     const std::map<NormalizedCellType,CellModel>::const_iterator iter=map_unique.find(type);
50     if(iter==map_unique.end())
51       {
52         std::ostringstream stream; stream << "no cellmodel for normalized type " << type;
53         throw Exception(stream.str().c_str());
54       }
55     return (*iter).second;
56   }
57
58   const std::map<NormalizedCellType,CellModel>& CellModel::GetMapOfUniqueInstance()
59   {
60     static std::map<NormalizedCellType,CellModel> map_of_unique_instance;
61     if(map_of_unique_instance.empty())
62       BuildUniqueInstance(map_of_unique_instance);
63     return map_of_unique_instance;
64   }
65
66   const char *CellModel::getRepr() const
67   {
68     return CELL_TYPES_REPR[(int)_type];
69   }
70
71   /*!
72    * This method is compatible with all types including dynamic one.
73    */
74   bool CellModel::isCompatibleWith(NormalizedCellType type) const
75   {
76     if(_type==type)
77       return true;
78     const CellModel& other=GetCellModel(type);
79     if(_dim!=other.getDimension())
80       return false;
81     bool b1=isQuadratic();
82     bool b2=other.isQuadratic();
83     if((b1 && !b2) || (!b1 && b2))
84       return false;
85     b1=isDynamic();
86     b2=other.isDynamic();
87     return b1 || b2;
88   }
89
90   void CellModel::BuildUniqueInstance(std::map<NormalizedCellType,CellModel>& map_unique)
91   {
92     map_unique.insert(std::make_pair(NORM_POINT1,CellModel(NORM_POINT1)));
93     map_unique.insert(std::make_pair(NORM_SEG2,CellModel(NORM_SEG2)));
94     map_unique.insert(std::make_pair(NORM_SEG3,CellModel(NORM_SEG3)));
95     map_unique.insert(std::make_pair(NORM_SEG4,CellModel(NORM_SEG4)));
96     map_unique.insert(std::make_pair(NORM_TRI3,CellModel(NORM_TRI3)));
97     map_unique.insert(std::make_pair(NORM_QUAD4,CellModel(NORM_QUAD4)));
98     map_unique.insert(std::make_pair(NORM_TRI6,CellModel(NORM_TRI6)));
99     map_unique.insert(std::make_pair(NORM_TRI7,CellModel(NORM_TRI7)));
100     map_unique.insert(std::make_pair(NORM_QUAD8,CellModel(NORM_QUAD8)));
101     map_unique.insert(std::make_pair(NORM_QUAD9,CellModel(NORM_QUAD9)));
102     map_unique.insert(std::make_pair(NORM_TETRA4,CellModel(NORM_TETRA4)));
103     map_unique.insert(std::make_pair(NORM_HEXA8,CellModel(NORM_HEXA8)));
104     map_unique.insert(std::make_pair(NORM_PYRA5,CellModel(NORM_PYRA5)));
105     map_unique.insert(std::make_pair(NORM_PENTA6,CellModel(NORM_PENTA6)));
106     map_unique.insert(std::make_pair(NORM_TETRA10,CellModel(NORM_TETRA10)));
107     map_unique.insert(std::make_pair(NORM_HEXGP12,CellModel(NORM_HEXGP12)));
108     map_unique.insert(std::make_pair(NORM_PYRA13,CellModel(NORM_PYRA13)));
109     map_unique.insert(std::make_pair(NORM_PENTA15,CellModel(NORM_PENTA15)));
110     map_unique.insert(std::make_pair(NORM_PENTA18,CellModel(NORM_PENTA18)));
111     map_unique.insert(std::make_pair(NORM_HEXA20,CellModel(NORM_HEXA20)));
112     map_unique.insert(std::make_pair(NORM_HEXA27,CellModel(NORM_HEXA27)));
113     map_unique.insert(std::make_pair(NORM_POLYGON,CellModel(NORM_POLYGON)));
114     map_unique.insert(std::make_pair(NORM_POLYHED,CellModel(NORM_POLYHED)));
115     map_unique.insert(std::make_pair(NORM_QPOLYG,CellModel(NORM_QPOLYG)));
116     map_unique.insert(std::make_pair(NORM_POLYL,CellModel(NORM_POLYL)));
117     map_unique.insert(std::make_pair(NORM_ERROR,CellModel(NORM_ERROR)));
118   }
119
120   CellModel::CellModel(NormalizedCellType type):_type(type)
121   {
122     _is_extruded=false;
123     _quadratic=false;
124     _dyn=false;
125     _extruded_type=NORM_ERROR;
126     _reverse_extruded_type=NORM_ERROR;
127     _linear_type=NORM_ERROR;
128     _quadratic_type=NORM_ERROR;
129     _quadratic_type2=NORM_ERROR;
130     _nb_of_little_sons=std::numeric_limits<unsigned>::max();
131     switch(type)
132       {
133       case NORM_POINT1:
134         {
135           _nb_of_pts=1; _nb_of_sons=0; _dim=0; _extruded_type=NORM_SEG2; _is_simplex=true;
136         }
137         break;
138       case NORM_SEG2:
139         {
140           _nb_of_pts=2; _nb_of_sons=2; _dim=1; _extruded_type=NORM_QUAD4; _quadratic_type=NORM_SEG3; _quadratic_type2=NORM_SEG3; _is_simplex=true; _is_extruded=true; _reverse_extruded_type=NORM_POINT1;
141           _sons_type[0]=NORM_POINT1; _sons_type[1]=NORM_POINT1;
142           _sons_con[0][0]=0; _nb_of_sons_con[0]=1;
143           _sons_con[1][0]=1; _nb_of_sons_con[1]=1;
144         }
145         break;
146       case NORM_SEG3:
147         {
148           _nb_of_pts=3; _nb_of_sons=3; _dim=1; _extruded_type=NORM_QUAD8; _linear_type=NORM_SEG2; _quadratic=true; _is_simplex=false;
149           _sons_type[0]=NORM_POINT1; _sons_type[1]=NORM_POINT1; _sons_type[2]=NORM_POINT1;
150           _sons_con[0][0]=0; _nb_of_sons_con[0]=1;
151           _sons_con[1][0]=1; _nb_of_sons_con[1]=1;
152           _sons_con[2][0]=2; _nb_of_sons_con[2]=1;
153         }
154         break;
155       case NORM_SEG4:
156         {
157           _nb_of_pts=4; _nb_of_sons=4; _dim=1; _linear_type=NORM_SEG2; _quadratic=true; _is_simplex=false; // no _extruded_type because no cubic 2D cell
158           _sons_type[0]=NORM_POINT1; _sons_type[1]=NORM_POINT1; _sons_type[2]=NORM_POINT1; _sons_type[3]=NORM_POINT1;
159           _sons_con[0][0]=0; _nb_of_sons_con[0]=1;
160           _sons_con[1][0]=1; _nb_of_sons_con[1]=1;
161           _sons_con[2][0]=2; _nb_of_sons_con[2]=1;
162           _sons_con[3][0]=3; _nb_of_sons_con[3]=1;
163         }
164         break;
165       case NORM_TETRA4:
166         {
167           _nb_of_pts=4; _nb_of_sons=4; _dim=3; _quadratic_type=NORM_TETRA10; _is_simplex=true;
168           _sons_type[0]=NORM_TRI3; _sons_type[1]=NORM_TRI3; _sons_type[2]=NORM_TRI3; _sons_type[3]=NORM_TRI3;
169           _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=2; _nb_of_sons_con[0]=3;
170           _sons_con[1][0]=0; _sons_con[1][1]=3; _sons_con[1][2]=1; _nb_of_sons_con[1]=3;
171           _sons_con[2][0]=1; _sons_con[2][1]=3; _sons_con[2][2]=2; _nb_of_sons_con[2]=3;
172           _sons_con[3][0]=2; _sons_con[3][1]=3; _sons_con[3][2]=0; _nb_of_sons_con[3]=3;
173           _little_sons_con[0][0]=0; _little_sons_con[0][1]=1;  _nb_of_little_sons=6;
174           _little_sons_con[1][0]=1; _little_sons_con[1][1]=2;
175           _little_sons_con[2][0]=2; _little_sons_con[2][1]=0;
176           _little_sons_con[3][0]=0; _little_sons_con[3][1]=3;
177           _little_sons_con[4][0]=1; _little_sons_con[4][1]=3;
178           _little_sons_con[5][0]=2; _little_sons_con[5][1]=3;
179         }
180         break;
181       case NORM_HEXA8:
182         {
183           _nb_of_pts=8; _nb_of_sons=6; _dim=3; _quadratic_type=NORM_HEXA20; _quadratic_type2=NORM_HEXA27; _is_simplex=false; _is_extruded=true; _reverse_extruded_type=NORM_QUAD4;
184           _sons_type[0]=NORM_QUAD4; _sons_type[1]=NORM_QUAD4; _sons_type[2]=NORM_QUAD4; _sons_type[3]=NORM_QUAD4; _sons_type[4]=NORM_QUAD4; _sons_type[5]=NORM_QUAD4;
185           _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=2; _sons_con[0][3]=3; _nb_of_sons_con[0]=4;
186           _sons_con[1][0]=4; _sons_con[1][1]=7; _sons_con[1][2]=6; _sons_con[1][3]=5; _nb_of_sons_con[1]=4;
187           _sons_con[2][0]=0; _sons_con[2][1]=4; _sons_con[2][2]=5; _sons_con[2][3]=1; _nb_of_sons_con[2]=4;
188           _sons_con[3][0]=1; _sons_con[3][1]=5; _sons_con[3][2]=6; _sons_con[3][3]=2; _nb_of_sons_con[3]=4;
189           _sons_con[4][0]=2; _sons_con[4][1]=6; _sons_con[4][2]=7; _sons_con[4][3]=3; _nb_of_sons_con[4]=4;
190           _sons_con[5][0]=3; _sons_con[5][1]=7; _sons_con[5][2]=4; _sons_con[5][3]=0; _nb_of_sons_con[5]=4;
191           _little_sons_con[0][0]=0; _little_sons_con[0][1]=1;  _nb_of_little_sons=12;
192           _little_sons_con[1][0]=1; _little_sons_con[1][1]=2;
193           _little_sons_con[2][0]=2; _little_sons_con[2][1]=3;
194           _little_sons_con[3][0]=3; _little_sons_con[3][1]=0;
195           _little_sons_con[4][0]=4; _little_sons_con[4][1]=5;
196           _little_sons_con[5][0]=5; _little_sons_con[5][1]=6;
197           _little_sons_con[6][0]=6; _little_sons_con[6][1]=7;
198           _little_sons_con[7][0]=7; _little_sons_con[7][1]=4;
199           _little_sons_con[8][0]=0; _little_sons_con[8][1]=4;
200           _little_sons_con[9][0]=1; _little_sons_con[9][1]=5;
201           _little_sons_con[10][0]=2; _little_sons_con[10][1]=6;
202           _little_sons_con[11][0]=3; _little_sons_con[11][1]=7;
203         }
204         break;
205       case NORM_QUAD4:
206         {
207           _nb_of_pts=4; _nb_of_sons=4; _dim=2; _quadratic_type=NORM_QUAD8; _quadratic_type2=NORM_QUAD9; _is_simplex=false; _is_extruded=true;
208           _sons_type[0]=NORM_SEG2; _sons_type[1]=NORM_SEG2; _sons_type[2]=NORM_SEG2; _sons_type[3]=NORM_SEG2;
209           _sons_con[0][0]=0; _sons_con[0][1]=1; _nb_of_sons_con[0]=2;
210           _sons_con[1][0]=1; _sons_con[1][1]=2; _nb_of_sons_con[1]=2;
211           _sons_con[2][0]=2; _sons_con[2][1]=3; _nb_of_sons_con[2]=2;
212           _sons_con[3][0]=3; _sons_con[3][1]=0; _nb_of_sons_con[3]=2; _extruded_type=NORM_HEXA8;
213         }
214         break;
215       case NORM_TRI3:
216         {
217           _nb_of_pts=3; _nb_of_sons=3; _dim=2; _quadratic_type=NORM_TRI6; _quadratic_type2=NORM_TRI7; _is_simplex=true;
218           _sons_type[0]=NORM_SEG2; _sons_type[1]=NORM_SEG2; _sons_type[2]=NORM_SEG2;
219           _sons_con[0][0]=0; _sons_con[0][1]=1; _nb_of_sons_con[0]=2;
220           _sons_con[1][0]=1; _sons_con[1][1]=2; _nb_of_sons_con[1]=2;
221           _sons_con[2][0]=2; _sons_con[2][1]=0; _nb_of_sons_con[2]=2; _extruded_type=NORM_PENTA6;
222         }
223         break;
224       case NORM_TRI6:
225         {
226           _nb_of_pts=6; _nb_of_sons=3; _dim=2; _linear_type=NORM_TRI3; _is_simplex=false;
227           _sons_type[0]=NORM_SEG3; _sons_type[1]=NORM_SEG3; _sons_type[2]=NORM_SEG3;
228           _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=3; _nb_of_sons_con[0]=3;
229           _sons_con[1][0]=1; _sons_con[1][1]=2; _sons_con[1][2]=4; _nb_of_sons_con[1]=3;
230           _sons_con[2][0]=2; _sons_con[2][1]=0; _sons_con[2][2]=5; _nb_of_sons_con[2]=3; _quadratic=true; _extruded_type=NORM_PENTA15;
231         }
232         break;
233       case NORM_TRI7:
234         {
235           _nb_of_pts=7; _nb_of_sons=3; _dim=2; _linear_type=NORM_TRI3; _is_simplex=false;
236           _sons_type[0]=NORM_SEG3; _sons_type[1]=NORM_SEG3; _sons_type[2]=NORM_SEG3;
237           _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=3; _nb_of_sons_con[0]=3;
238           _sons_con[1][0]=1; _sons_con[1][1]=2; _sons_con[1][2]=4; _nb_of_sons_con[1]=3;
239           _sons_con[2][0]=2; _sons_con[2][1]=0; _sons_con[2][2]=5; _nb_of_sons_con[2]=3; _quadratic=true; //no extruded type because no penta20
240         }
241         break;
242       case NORM_QUAD8:
243         {
244           _nb_of_pts=8; _nb_of_sons=4; _dim=2; _linear_type=NORM_QUAD4; _is_simplex=false;
245           _sons_type[0]=NORM_SEG3; _sons_type[1]=NORM_SEG3; _sons_type[2]=NORM_SEG3; _sons_type[3]=NORM_SEG3;
246           _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=4; _nb_of_sons_con[0]=3;
247           _sons_con[1][0]=1; _sons_con[1][1]=2; _sons_con[1][2]=5; _nb_of_sons_con[1]=3;
248           _sons_con[2][0]=2; _sons_con[2][1]=3; _sons_con[2][2]=6; _nb_of_sons_con[2]=3;
249           _sons_con[3][0]=3; _sons_con[3][1]=0; _sons_con[3][2]=7; _nb_of_sons_con[3]=3; _quadratic=true; _extruded_type=NORM_HEXA20;
250         }
251         break;
252       case NORM_QUAD9:
253         {
254           _nb_of_pts=9; _nb_of_sons=4; _dim=2; _linear_type=NORM_QUAD4; _is_simplex=false;
255           _sons_type[0]=NORM_SEG3; _sons_type[1]=NORM_SEG3; _sons_type[2]=NORM_SEG3; _sons_type[3]=NORM_SEG3;
256           _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=4; _nb_of_sons_con[0]=3;
257           _sons_con[1][0]=1; _sons_con[1][1]=2; _sons_con[1][2]=5; _nb_of_sons_con[1]=3;
258           _sons_con[2][0]=2; _sons_con[2][1]=3; _sons_con[2][2]=6; _nb_of_sons_con[2]=3;
259           _sons_con[3][0]=3; _sons_con[3][1]=0; _sons_con[3][2]=7; _nb_of_sons_con[3]=3; _quadratic=true; _extruded_type=NORM_HEXA27;
260         }
261         break;
262       case NORM_PYRA5:
263         {
264           _nb_of_pts=5; _nb_of_sons=5; _dim=3; _quadratic_type=NORM_PYRA13; _is_simplex=false;
265           _sons_type[0]=NORM_QUAD4; _sons_type[1]=NORM_TRI3; _sons_type[2]=NORM_TRI3; _sons_type[3]=NORM_TRI3; _sons_type[4]=NORM_TRI3;
266           _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=2; _sons_con[0][3]=3; _nb_of_sons_con[0]=4;
267           _sons_con[1][0]=0; _sons_con[1][1]=4; _sons_con[1][2]=1; _nb_of_sons_con[1]=3;
268           _sons_con[2][0]=1; _sons_con[2][1]=4; _sons_con[2][2]=2; _nb_of_sons_con[2]=3;
269           _sons_con[3][0]=2; _sons_con[3][1]=4; _sons_con[3][2]=3; _nb_of_sons_con[3]=3;
270           _sons_con[4][0]=3; _sons_con[4][1]=4; _sons_con[4][2]=0; _nb_of_sons_con[4]=3;
271           _little_sons_con[0][0]=0; _little_sons_con[0][1]=1;  _nb_of_little_sons=8;
272           _little_sons_con[1][0]=1; _little_sons_con[1][1]=2;
273           _little_sons_con[2][0]=2; _little_sons_con[2][1]=3;
274           _little_sons_con[3][0]=3; _little_sons_con[3][1]=0;
275           _little_sons_con[4][0]=0; _little_sons_con[4][1]=4;
276           _little_sons_con[5][0]=1; _little_sons_con[5][1]=4;
277           _little_sons_con[6][0]=2; _little_sons_con[6][1]=4;
278           _little_sons_con[7][0]=3; _little_sons_con[7][1]=4;
279         }
280         break;
281       case NORM_PENTA6:
282         {
283           _nb_of_pts=6; _nb_of_sons=5; _dim=3; _quadratic_type=NORM_PENTA15; _is_simplex=false; _is_extruded=true; _reverse_extruded_type=NORM_TRI3;
284           _sons_type[0]=NORM_TRI3; _sons_type[1]=NORM_TRI3; _sons_type[2]=NORM_QUAD4; _sons_type[3]=NORM_QUAD4; _sons_type[4]=NORM_QUAD4;
285           _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=2; _nb_of_sons_con[0]=3;
286           _sons_con[1][0]=3; _sons_con[1][1]=5; _sons_con[1][2]=4; _nb_of_sons_con[1]=3;
287           _sons_con[2][0]=0; _sons_con[2][1]=3; _sons_con[2][2]=4; _sons_con[2][3]=1; _nb_of_sons_con[2]=4;
288           _sons_con[3][0]=1; _sons_con[3][1]=4; _sons_con[3][2]=5; _sons_con[3][3]=2; _nb_of_sons_con[3]=4;
289           _sons_con[4][0]=2; _sons_con[4][1]=5; _sons_con[4][2]=3; _sons_con[4][3]=0; _nb_of_sons_con[4]=4;
290           _little_sons_con[0][0]=0; _little_sons_con[0][1]=1;  _nb_of_little_sons=9;
291           _little_sons_con[1][0]=1; _little_sons_con[1][1]=2;
292           _little_sons_con[2][0]=2; _little_sons_con[2][1]=0;
293           _little_sons_con[3][0]=3; _little_sons_con[3][1]=4;
294           _little_sons_con[4][0]=4; _little_sons_con[4][1]=5;
295           _little_sons_con[5][0]=5; _little_sons_con[5][1]=3;
296           _little_sons_con[6][0]=0; _little_sons_con[6][1]=3;
297           _little_sons_con[7][0]=1; _little_sons_con[7][1]=4;
298           _little_sons_con[8][0]=2; _little_sons_con[8][1]=5;
299         }
300         break;
301       case NORM_TETRA10:
302         {
303           _nb_of_pts=10; _nb_of_sons=4; _dim=3; _linear_type=NORM_TETRA4; _is_simplex=false;
304           _sons_type[0]=NORM_TRI6; _sons_type[1]=NORM_TRI6; _sons_type[2]=NORM_TRI6; _sons_type[3]=NORM_TRI6;
305           _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=2; _sons_con[0][3]=4; _sons_con[0][4]=5; _sons_con[0][5]=6; _nb_of_sons_con[0]=6;
306           _sons_con[1][0]=0; _sons_con[1][1]=3; _sons_con[1][2]=1; _sons_con[1][3]=7; _sons_con[1][4]=8; _sons_con[1][5]=4; _nb_of_sons_con[1]=6;
307           _sons_con[2][0]=1; _sons_con[2][1]=3; _sons_con[2][2]=2; _sons_con[2][3]=8; _sons_con[2][4]=9; _sons_con[2][5]=5; _nb_of_sons_con[2]=6;
308           _sons_con[3][0]=2; _sons_con[3][1]=3; _sons_con[3][2]=0; _sons_con[3][3]=9; _sons_con[3][4]=7; _sons_con[3][5]=6; _nb_of_sons_con[3]=6;  _quadratic=true;
309           _little_sons_con[0][0]=0; _little_sons_con[0][1]=1;  _little_sons_con[0][2]=4;  _nb_of_little_sons=6;
310           _little_sons_con[1][0]=1; _little_sons_con[1][1]=2;  _little_sons_con[1][2]=5;
311           _little_sons_con[2][0]=2; _little_sons_con[2][1]=0;  _little_sons_con[2][2]=6;
312           _little_sons_con[3][0]=0; _little_sons_con[3][1]=3;  _little_sons_con[3][2]=7;
313           _little_sons_con[4][0]=1; _little_sons_con[4][1]=3;  _little_sons_con[4][2]=8;
314           _little_sons_con[5][0]=2; _little_sons_con[5][1]=3;  _little_sons_con[5][2]=9;
315         }
316         break;
317       case NORM_HEXGP12:
318         {
319           _nb_of_pts=12; _nb_of_sons=8; _dim=3; _is_simplex=false; _is_extruded=true;
320           _sons_type[0]=NORM_POLYGON; _sons_type[1]=NORM_POLYGON; _sons_type[2]=NORM_QUAD4; _sons_type[3]=NORM_QUAD4; _sons_type[4]=NORM_QUAD4; _sons_type[5]=NORM_QUAD4;
321           _sons_type[6]=NORM_QUAD4; _sons_type[7]=NORM_QUAD4;
322           _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=2; _sons_con[0][3]=3; _sons_con[0][4]=4; _sons_con[0][5]=5; _nb_of_sons_con[0]=6;
323           _sons_con[1][0]=6; _sons_con[1][1]=11; _sons_con[1][2]=10; _sons_con[1][3]=9; _sons_con[1][4]=8; _sons_con[1][5]=7; _nb_of_sons_con[1]=6;
324           _sons_con[2][0]=0; _sons_con[2][1]=6; _sons_con[2][2]=7; _sons_con[2][3]=1; _nb_of_sons_con[2]=4;
325           _sons_con[3][0]=1; _sons_con[3][1]=7; _sons_con[3][2]=8; _sons_con[3][3]=2; _nb_of_sons_con[3]=4;
326           _sons_con[4][0]=2; _sons_con[4][1]=8; _sons_con[4][2]=9; _sons_con[4][3]=3; _nb_of_sons_con[4]=4;
327           _sons_con[5][0]=3; _sons_con[5][1]=9; _sons_con[5][2]=10; _sons_con[5][3]=4; _nb_of_sons_con[5]=4;
328           _sons_con[6][0]=4; _sons_con[6][1]=10; _sons_con[6][2]=11; _sons_con[6][3]=5; _nb_of_sons_con[6]=4;
329           _sons_con[7][0]=5; _sons_con[7][1]=11; _sons_con[7][2]=6; _sons_con[7][3]=0; _nb_of_sons_con[7]=4;
330         }
331         break;
332       case NORM_PYRA13:
333         {
334           _nb_of_pts=13; _nb_of_sons=5; _dim=3; _linear_type=NORM_PYRA5; _is_simplex=false;
335           _sons_type[0]=NORM_QUAD8; _sons_type[1]=NORM_TRI6; _sons_type[2]=NORM_TRI6; _sons_type[3]=NORM_TRI6; _sons_type[4]=NORM_TRI6;
336           _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=2; _sons_con[0][3]=3; _sons_con[0][4]=5; _sons_con[0][5]=6; _sons_con[0][6]=7; _sons_con[0][7]=8; _nb_of_sons_con[0]=8;
337           _sons_con[1][0]=0; _sons_con[1][1]=4; _sons_con[1][2]=1; _sons_con[1][3]=9; _sons_con[1][4]=10; _sons_con[1][5]=5; _nb_of_sons_con[1]=6;
338           _sons_con[2][0]=1; _sons_con[2][1]=4; _sons_con[2][2]=2; _sons_con[2][3]=10; _sons_con[2][4]=11; _sons_con[2][5]=6; _nb_of_sons_con[2]=6;
339           _sons_con[3][0]=2; _sons_con[3][1]=4; _sons_con[3][2]=3; _sons_con[3][3]=11; _sons_con[3][4]=12; _sons_con[3][5]=7;  _nb_of_sons_con[3]=6;
340           _sons_con[4][0]=3; _sons_con[4][1]=4; _sons_con[4][2]=0; _sons_con[4][3]=12; _sons_con[4][4]=9; _sons_con[4][5]=8; _nb_of_sons_con[4]=6; _quadratic=true;
341           _little_sons_con[0][0]=0; _little_sons_con[0][1]=1; _little_sons_con[0][2]=5;  _nb_of_little_sons=8;
342           _little_sons_con[1][0]=1; _little_sons_con[1][1]=2; _little_sons_con[1][2]=6;
343           _little_sons_con[2][0]=2; _little_sons_con[2][1]=3; _little_sons_con[2][2]=7;
344           _little_sons_con[3][0]=3; _little_sons_con[3][1]=0; _little_sons_con[3][2]=8;
345           _little_sons_con[4][0]=0; _little_sons_con[4][1]=4; _little_sons_con[4][2]=9;
346           _little_sons_con[5][0]=1; _little_sons_con[5][1]=4; _little_sons_con[5][2]=10;
347           _little_sons_con[6][0]=2; _little_sons_con[6][1]=4; _little_sons_con[6][2]=11;
348           _little_sons_con[7][0]=3; _little_sons_con[7][1]=4; _little_sons_con[7][2]=12;
349         }
350         break;
351       case NORM_PENTA15:
352         {
353           _nb_of_pts=15; _nb_of_sons=5; _dim=3; _linear_type=NORM_PENTA6; _is_simplex=false;
354           _sons_type[0]=NORM_TRI6; _sons_type[1]=NORM_TRI6; _sons_type[2]=NORM_QUAD8; _sons_type[3]=NORM_QUAD8; _sons_type[4]=NORM_QUAD8;
355           _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;
356           _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;
357           _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; _nb_of_sons_con[2]=8;
358           _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; _nb_of_sons_con[3]=8;
359           _sons_con[4][0]=2; _sons_con[4][1]=5; _sons_con[4][2]=3; _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; _nb_of_sons_con[4]=8; _quadratic=true;
360           _little_sons_con[0][0]=0; _little_sons_con[0][1]=1; _little_sons_con[0][2]=6;  _nb_of_little_sons=9;
361           _little_sons_con[1][0]=1; _little_sons_con[1][1]=2; _little_sons_con[1][2]=7;
362           _little_sons_con[2][0]=2; _little_sons_con[2][1]=0; _little_sons_con[2][2]=8;
363           _little_sons_con[3][0]=3; _little_sons_con[3][1]=4; _little_sons_con[3][2]=9;
364           _little_sons_con[4][0]=4; _little_sons_con[4][1]=5; _little_sons_con[4][2]=10;
365           _little_sons_con[5][0]=5; _little_sons_con[5][1]=3; _little_sons_con[5][2]=11;
366           _little_sons_con[6][0]=0; _little_sons_con[6][1]=3; _little_sons_con[6][2]=12;
367           _little_sons_con[7][0]=1; _little_sons_con[7][1]=4; _little_sons_con[7][2]=13;
368           _little_sons_con[8][0]=2; _little_sons_con[8][1]=5; _little_sons_con[8][2]=14;
369         }
370         break;
371       case NORM_PENTA18:
372         {
373           _nb_of_pts=18; _nb_of_sons=5; _dim=3; _linear_type=NORM_PENTA6; _is_simplex=false;
374           _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;
375           _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;
376           _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;
377           _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;
378           _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;
379           _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;
380           _little_sons_con[0][0]=0; _little_sons_con[0][1]=1; _little_sons_con[0][2]=6;  _nb_of_little_sons=9;
381           _little_sons_con[1][0]=1; _little_sons_con[1][1]=2; _little_sons_con[1][2]=7;
382           _little_sons_con[2][0]=2; _little_sons_con[2][1]=0; _little_sons_con[2][2]=8;
383           _little_sons_con[3][0]=3; _little_sons_con[3][1]=4; _little_sons_con[3][2]=9;
384           _little_sons_con[4][0]=4; _little_sons_con[4][1]=5; _little_sons_con[4][2]=10;
385           _little_sons_con[5][0]=5; _little_sons_con[5][1]=3; _little_sons_con[5][2]=11;
386           _little_sons_con[6][0]=0; _little_sons_con[6][1]=3; _little_sons_con[6][2]=12;
387           _little_sons_con[7][0]=1; _little_sons_con[7][1]=4; _little_sons_con[7][2]=13;
388           _little_sons_con[8][0]=2; _little_sons_con[8][1]=5; _little_sons_con[8][2]=14;
389         }
390         break;
391       case NORM_HEXA20:
392         {
393           _nb_of_pts=20; _nb_of_sons=6; _dim=3; _linear_type=NORM_HEXA8; _is_simplex=false;
394           _sons_type[0]=NORM_QUAD8; _sons_type[1]=NORM_QUAD8; _sons_type[2]=NORM_QUAD8; _sons_type[3]=NORM_QUAD8; _sons_type[4]=NORM_QUAD8; _sons_type[5]=NORM_QUAD8;
395           _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;
396           _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;
397           _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;
398           _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;
399           _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;
400           _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;
401           _little_sons_con[0][0]=0; _little_sons_con[0][1]=1;  _little_sons_con[0][2]=8; _nb_of_little_sons=12;
402           _little_sons_con[1][0]=1; _little_sons_con[1][1]=2;  _little_sons_con[1][2]=9;
403           _little_sons_con[2][0]=2; _little_sons_con[2][1]=3;  _little_sons_con[2][2]=10;
404           _little_sons_con[3][0]=3; _little_sons_con[3][1]=0;  _little_sons_con[3][2]=11;
405           _little_sons_con[4][0]=4; _little_sons_con[4][1]=5;  _little_sons_con[4][2]=12;
406           _little_sons_con[5][0]=5; _little_sons_con[5][1]=6;  _little_sons_con[5][2]=13;
407           _little_sons_con[6][0]=6; _little_sons_con[6][1]=7;  _little_sons_con[6][2]=14;
408           _little_sons_con[7][0]=7; _little_sons_con[7][1]=4;  _little_sons_con[7][2]=15;
409           _little_sons_con[8][0]=0; _little_sons_con[8][1]=4;  _little_sons_con[8][2]=16;
410           _little_sons_con[9][0]=1; _little_sons_con[9][1]=5;  _little_sons_con[9][2]=17;
411           _little_sons_con[10][0]=2; _little_sons_con[10][1]=6;  _little_sons_con[10][2]=18;
412           _little_sons_con[11][0]=3; _little_sons_con[11][1]=7;  _little_sons_con[11][2]=19;
413         }
414         break;
415       case NORM_HEXA27:
416         {
417           _nb_of_pts=27; _nb_of_sons=6; _dim=3; _linear_type=NORM_HEXA8; _is_simplex=false;
418           _sons_type[0]=NORM_QUAD9; _sons_type[1]=NORM_QUAD9; _sons_type[2]=NORM_QUAD9; _sons_type[3]=NORM_QUAD9; _sons_type[4]=NORM_QUAD9; _sons_type[5]=NORM_QUAD9;
419           _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;
420           _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;
421           _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;
422           _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;
423           _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;
424           _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;
425           _quadratic=true;
426         }
427         break;
428       case NORM_POLYGON:
429         {
430           _nb_of_pts=0; _nb_of_sons=0; _dim=2; _dyn=true; _extruded_type=NORM_POLYHED; _is_simplex=false; _quadratic_type=NORM_QPOLYG;
431         }
432         break;
433       case NORM_POLYHED:
434         {
435           _nb_of_pts=0; _nb_of_sons=0; _dim=3; _dyn=true; _is_simplex=false;
436         }
437         break;
438       case NORM_QPOLYG:
439         {
440           _nb_of_pts=0; _nb_of_sons=0; _dim=2; _dyn=true; _is_simplex=false; _quadratic=true; _linear_type=NORM_POLYGON;
441         }
442         break;
443       case NORM_POLYL:
444         {
445           _nb_of_pts=0; _nb_of_sons=0; _dim=1; _dyn=true; _extruded_type=NORM_POLYGON; _is_simplex=false;
446         }
447         break;
448       case NORM_ERROR:
449         {
450           _nb_of_pts=std::numeric_limits<unsigned>::max(); _nb_of_sons=std::numeric_limits<unsigned>::max(); _dim=std::numeric_limits<unsigned>::max();
451         }
452         break;
453       }
454   }
455
456   /*!
457    * Equivalent to getNumberOfSons except that this method deals with dynamic type.
458    */
459   unsigned CellModel::getNumberOfSons2(const mcIdType *conn, mcIdType lgth) const
460   {
461     if(!isDynamic())
462       return getNumberOfSons();
463     if(_dim==2)
464       {
465         if(_type==NORM_POLYGON)
466           return FromIdType<unsigned>(lgth);
467         else
468           return FromIdType<unsigned>(lgth/2);
469       }
470     else if(_dim==1)
471       return FromIdType<unsigned>(lgth);//NORM_POLYL
472     else
473       return (unsigned)std::count(conn,conn+lgth,-1)+1;
474   }
475
476   unsigned CellModel::getNumberOfEdgesIn3D(const mcIdType *conn, mcIdType lgth) const
477   {
478     if(!isDynamic())
479       return _nb_of_little_sons;
480     else//polyhedron
481       return FromIdType<unsigned>(lgth-ToIdType(std::count(conn,conn+lgth,-1)/2));
482   }
483
484   /*!
485    * \sa fillMicroEdgeNodalConnectivity
486    */
487   unsigned CellModel::getNumberOfMicroEdges() const
488   {
489     unsigned mul(isQuadratic()?2:1);
490     if(!isDynamic())
491       {
492         switch(getDimension())
493           {
494           case 2:
495             return mul*getNumberOfSons();
496           case 3:
497             return mul*_nb_of_little_sons;
498           default:
499             throw INTERP_KERNEL::Exception("CellModel::getNumberOfMacroEdges : only 2D and 3D cells support this !");
500           }
501       }
502     else
503       throw INTERP_KERNEL::Exception("CellModel::getNumberOfMacroEdges : not supported by dynamic type !");
504   }
505
506   NormalizedCellType CellModel::getCorrespondingPolyType() const
507   {
508     switch(getDimension())
509       {
510       case 0:
511         return NORM_POINT1;
512       case 1:
513         {
514           if(!isQuadratic())
515             return NORM_POLYL;
516           throw INTERP_KERNEL::Exception("CellModel::getPolyType : no poly type for quadratic 1D !");
517         }
518       case 2:
519         {
520           if(!isQuadratic())
521             return NORM_POLYGON;
522           else
523             return NORM_QPOLYG;
524         }
525       case 3:
526         {
527           if(!isQuadratic())
528             return NORM_POLYHED;
529           throw INTERP_KERNEL::Exception("CellModel::getPolyType : no poly type for quadratic 3D !");
530         }
531       default:
532         throw INTERP_KERNEL::Exception("CellModel::getPolyType : only dimension 0, 1, 2, 3 are supported !");
533       }
534   }
535
536   /*!
537    * Equivalent to getSonType except that this method deals with dynamic type.
538    */
539   NormalizedCellType CellModel::getSonType2(unsigned sonId) const
540   {
541     if(!isDynamic())
542       return getSonType(sonId);
543     if(_dim==2)
544       {
545         if(_type==NORM_POLYGON)
546           return NORM_SEG2;
547         else
548           return NORM_SEG3;
549       }
550     else if(_dim==1)
551       return NORM_ERROR;//NORM_POLYL
552     //polyedron
553     return NORM_POLYGON;
554   }
555
556   /*!
557    * \b WARNING this method do not manage correctly types that return true at the call of isDynamic. Use fillSonCellNodalConnectivity2 instead.
558    */
559   unsigned CellModel::fillSonCellNodalConnectivity(int sonId, const mcIdType *nodalConn, mcIdType *sonNodalConn) const
560   {
561     unsigned nbOfTurnLoop=_nb_of_sons_con[sonId];
562     const unsigned *sonConn=_sons_con[sonId];
563     for(unsigned i=0;i<nbOfTurnLoop;i++)
564       sonNodalConn[i]=nodalConn[sonConn[i]];
565     return nbOfTurnLoop;
566   }
567
568   unsigned CellModel::fillSonCellNodalConnectivity2(int sonId, const mcIdType *nodalConn, mcIdType lgth, mcIdType *sonNodalConn, NormalizedCellType& typeOfSon) const
569   {
570     typeOfSon=getSonType2(sonId);
571     if(!isDynamic())
572       return fillSonCellNodalConnectivity(sonId,nodalConn,sonNodalConn);
573     else
574       {
575         if(_dim==2)//polygon
576           {
577             if(_type==NORM_POLYGON)
578               {
579                 sonNodalConn[0]=nodalConn[sonId];
580                 sonNodalConn[1]=nodalConn[(sonId+1)%lgth];
581                 return 2;
582               }
583             else  // NORM_QPOLYG
584               {
585                 sonNodalConn[0]=nodalConn[sonId];
586                 sonNodalConn[1]=nodalConn[(sonId+1)%(lgth/2)];
587                 sonNodalConn[2]=nodalConn[sonId+(lgth/2)];
588                 return 3;
589               }
590           }
591         else if(_dim==3)
592           {//polyedron
593             const mcIdType *where=nodalConn;
594             for(int i=0;i<sonId;i++)
595               {
596                 where=std::find(where,nodalConn+lgth,-1);
597                 where++;
598               }
599             const mcIdType *where2=std::find(where,nodalConn+lgth,-1);
600             std::copy(where,where2,sonNodalConn);
601             return (unsigned)(where2-where);
602           }
603         else
604           throw INTERP_KERNEL::Exception("CellModel::fillSonCellNodalConnectivity2 : no sons on NORM_POLYL !");
605       }
606   }
607
608   /*!
609    * Equivalent to CellModel::fillSonCellNodalConnectivity2 except for HEXA8 where the order of sub faces is not has MED file numbering for transformation HEXA8->HEXA27
610    */
611   unsigned CellModel::fillSonCellNodalConnectivity4(int sonId, const mcIdType *nodalConn, mcIdType lgth, mcIdType *sonNodalConn, NormalizedCellType& typeOfSon) const
612   {
613     if(_type==NORM_HEXA8)
614       {
615         static const int permutation[6]={0,2,3,4,5,1};
616         return fillSonCellNodalConnectivity2(permutation[sonId],nodalConn,lgth,sonNodalConn,typeOfSon);
617       }
618     else
619       return fillSonCellNodalConnectivity2(sonId,nodalConn,lgth,sonNodalConn,typeOfSon);
620   }
621
622   unsigned CellModel::fillSonEdgesNodalConnectivity3D(int sonId, const mcIdType *nodalConn, mcIdType lgth, mcIdType *sonNodalConn, NormalizedCellType& typeOfSon) const
623   {
624     if(!isDynamic())
625       {
626         if(!isQuadratic())
627           {
628             typeOfSon=NORM_SEG2;
629             sonNodalConn[0]=nodalConn[_little_sons_con[sonId][0]];
630             sonNodalConn[1]=nodalConn[_little_sons_con[sonId][1]];
631             return 2;
632           }
633         else
634           {
635             typeOfSon=NORM_SEG3;
636             sonNodalConn[0]=nodalConn[_little_sons_con[sonId][0]];
637             sonNodalConn[1]=nodalConn[_little_sons_con[sonId][1]];
638             sonNodalConn[2]=nodalConn[_little_sons_con[sonId][2]];
639             return 3;
640           }
641       }
642     else
643       throw INTERP_KERNEL::Exception("CellModel::fillSonEdgesNodalConnectivity3D : not implemented yet for NORM_POLYHED !");
644   }
645
646   /*!
647    * \sa getNumberOfMicroEdges
648    */
649   unsigned CellModel::fillMicroEdgeNodalConnectivity(int sonId, const mcIdType *nodalConn, mcIdType *sonNodalConn, NormalizedCellType& typeOfSon) const
650   {
651     if(isQuadratic())
652       {
653         int edgeId(sonId/2),subEdgeId(sonId%2);
654         typeOfSon=NORM_SEG2;
655         const unsigned *sonConn(0);
656         switch(getDimension())
657           {
658           case 2:
659             {
660               sonConn=_sons_con[edgeId];
661               break;
662             }
663           case 3:
664             {
665               sonConn=_little_sons_con[edgeId];
666               break;
667             }
668           default:
669             throw INTERP_KERNEL::Exception("CellModel::fillMicroEdgeNodalConnectivity : only 2D and 3D cells support this !");
670           }
671         const unsigned tmp[3]={sonConn[0],sonConn[2],sonConn[1]};
672         sonNodalConn[0]=nodalConn[tmp[subEdgeId]];
673         sonNodalConn[1]=nodalConn[tmp[subEdgeId+1]];
674         return 2;
675       }
676     else
677       {
678         switch(getDimension())
679           {
680           case 2:
681             return fillSonCellNodalConnectivity2(sonId,nodalConn,0,sonNodalConn,typeOfSon);
682           case 3:
683             return fillSonEdgesNodalConnectivity3D(sonId,nodalConn,0,sonNodalConn,typeOfSon);
684           default:
685             throw INTERP_KERNEL::Exception("CellModel::fillMicroEdgeNodalConnectivity : only 2D and 3D cells support this #2 !");
686           }
687       }
688   }
689
690   void CellModel::changeOrientationOf2D(mcIdType *nodalConn, unsigned int sz) const
691   {
692     if(sz<1)
693       return ;
694     if(!isQuadratic())
695       {
696         std::vector<mcIdType> tmp(sz-1);
697         std::copy(nodalConn+1,nodalConn+sz,tmp.rbegin());
698         std::copy(tmp.begin(),tmp.end(),nodalConn+1);
699       }
700     else
701       {
702         unsigned int sz2(sz/2);
703         std::vector<mcIdType> tmp0(sz2-1),tmp1(sz2);
704         std::copy(nodalConn+1,nodalConn+sz2,tmp0.rbegin());
705         std::copy(nodalConn+sz2,nodalConn+sz,tmp1.rbegin());
706         std::copy(tmp0.begin(),tmp0.end(),nodalConn+1);
707         std::copy(tmp1.begin(),tmp1.end(),nodalConn+sz2);
708       }
709   }
710
711   void CellModel::changeOrientationOf1D(mcIdType *nodalConn, unsigned int sz) const
712   {
713     if(!isDynamic())
714       {
715         if(sz==2 || sz==3)
716           {
717             std::swap(nodalConn[0],nodalConn[1]);
718             return ;
719           }
720         else if(sz==4)
721           {
722             std::swap(nodalConn[0],nodalConn[1]);
723             std::swap(nodalConn[2],nodalConn[3]);
724           }
725         else
726           throw Exception("CellModel::changeOrientationOf1D : unrecognized 1D cell type !");
727       }
728     else
729       {
730         std::vector<mcIdType> tmp(sz-1);
731         std::copy(nodalConn+1,nodalConn+sz,tmp.rbegin());
732         std::copy(tmp.begin(),tmp.end(),nodalConn+1);
733       }
734   }
735
736   //================================================================================
737   /*!
738    * \brief Return number of nodes in sonId-th son of a Dynamic() cell
739    */
740   //================================================================================
741
742   unsigned CellModel::getNumberOfNodesConstituentTheSon2(unsigned sonId, const mcIdType *nodalConn, mcIdType lgth) const
743   {
744     if(!isDynamic())
745       return getNumberOfNodesConstituentTheSon(sonId);
746
747     if(_dim==2)//polygon
748       {
749         if(_type==NORM_POLYGON)
750           return 2;
751         else
752           return 3;
753       }
754     else if(_dim==3)
755       {//polyedron
756         const mcIdType *where=nodalConn;
757         for(unsigned int i=0;i<sonId;i++)
758           {
759             where=std::find(where,nodalConn+lgth,-1);
760             where++;
761           }
762         const mcIdType *where2=std::find(where,nodalConn+lgth,-1);
763         return (unsigned)(where2-where);
764       }
765     else
766       throw INTERP_KERNEL::Exception("CellModel::getNumberOfNodesConstituentTheSon2 : no sons on NORM_POLYL !");
767   }
768
769   /*!
770    * This method retrieves if cell1 represented by 'conn1' and cell2 represented by 'conn2'
771    * are equivalent by a permutation or not. This method expects to work on 1D or 2D (only mesh dimension where it is possible to have a spaceDim) strictly higher than meshDim.
772    * If not an exception will be thrown.
773    * @return True if two cells have same orientation, false if not.
774    */
775   bool CellModel::getOrientationStatus(mcIdType lgth, const mcIdType *conn1, const mcIdType *conn2) const
776   {
777     if(_dim!=1 && _dim!=2)
778       throw INTERP_KERNEL::Exception("CellModel::getOrientationStatus : invalid dimension ! Must be 1 or 2 !");
779     if(!_quadratic)
780       {
781         std::vector<mcIdType> tmp(2*lgth);
782         std::vector<mcIdType>::iterator it=std::copy(conn1,conn1+lgth,tmp.begin());
783         std::copy(conn1,conn1+lgth,it);
784         it=std::search(tmp.begin(),tmp.end(),conn2,conn2+lgth);
785         if(it==tmp.begin())
786           return true;
787         if(it!=tmp.end())
788           return _dim!=1;
789         std::vector<mcIdType>::reverse_iterator it2=std::search(tmp.rbegin(),tmp.rend(),conn2,conn2+lgth);
790         if(it2!=tmp.rend())
791           return false;
792         throw INTERP_KERNEL::Exception("CellModel::getOrientationStatus : Request of orientation status of non equal connectively cells !");
793       }
794     else
795       {
796         if(_dim!=1)
797           {
798             std::vector<mcIdType> tmp(lgth);
799             std::vector<mcIdType>::iterator it=std::copy(conn1,conn1+lgth/2,tmp.begin());
800             std::copy(conn1,conn1+lgth/2,it);
801             it=std::search(tmp.begin(),tmp.end(),conn2,conn2+lgth/2);
802             std::size_t d=std::distance(tmp.begin(),it);
803             if(it==tmp.end())
804               return false;
805             it=std::copy(conn1+lgth/2,conn1+lgth,tmp.begin());
806             std::copy(conn1+lgth/2,conn1+lgth,it);
807             it=std::search(tmp.begin(),tmp.end(),conn2,conn2+lgth);
808             if(it==tmp.end())
809               return false;
810             std::size_t d2=std::distance(tmp.begin(),it);
811             return d==d2;
812           }
813         else
814           {
815             mcIdType p=(lgth+1)/2;
816             std::vector<mcIdType> tmp(2*p);
817             std::vector<mcIdType>::iterator it=std::copy(conn1,conn1+p,tmp.begin());
818             std::copy(conn1,conn1+p,it);
819             it=std::search(tmp.begin(),tmp.end(),conn2,conn2+p);
820             std::size_t d=std::distance(tmp.begin(),it);
821             if(it==tmp.end())
822               return false;
823             tmp.resize(2*p-2);
824             it=std::copy(conn1+p,conn1+lgth,tmp.begin());
825             std::copy(conn1+p,conn1+lgth,it);
826             it=std::search(tmp.begin(),tmp.end(),conn2+p,conn2+lgth);
827             if(it==tmp.end())
828               return false;
829             std::size_t d2=std::distance(tmp.begin(),it);
830             return d==d2;
831           }
832       }
833   }
834
835   DiameterCalculator *CellModel::buildInstanceOfDiameterCalulator(int spaceDim) const
836   {
837     switch(_type)
838       {
839       case NORM_TRI3:
840         {
841           switch(spaceDim)
842             {
843             case 2:
844               return new DiameterCalulatorTRI3S2;
845             case 3:
846               return new DiameterCalulatorTRI3S3;
847             default:
848               throw Exception("CellModel::buildInstanceOfDiameterCalulator : For TRI3 only space dimension 2 and 3 implemented !");
849             }
850           break;
851         }
852       case NORM_QUAD4:
853         {
854           switch(spaceDim)
855             {
856             case 2:
857               return new DiameterCalulatorQUAD4S2;
858             case 3:
859               return new DiameterCalulatorQUAD4S3;
860             default:
861               throw Exception("CellModel::buildInstanceOfDiameterCalulator : For QUAD4 only space dimension 2 and 3 implemented !");
862             }
863           break;
864         }
865       case NORM_TRI6:
866         {
867           switch(spaceDim)
868           {
869             case 2:
870               return new DiameterCalulatorTRI6S2;
871             case 3:
872               return new DiameterCalulatorTRI6S3;
873             default:
874               throw Exception("CellModel::buildInstanceOfDiameterCalulator : For TRI6 only space dimension 2 and 3 implemented !");
875           }
876           break;
877         }
878       case NORM_TRI7:
879         {
880           switch(spaceDim)
881           {
882             case 2:
883               return new DiameterCalulatorTRI7S2;
884             case 3:
885               return new DiameterCalulatorTRI7S3;
886             default:
887               throw Exception("CellModel::buildInstanceOfDiameterCalulator : For TRI7 only space dimension 2 and 3 implemented !");
888           }
889           break;
890         }
891       case NORM_QUAD8:
892         {
893           switch(spaceDim)
894           {
895             case 2:
896               return new DiameterCalulatorQUAD8S2;
897             case 3:
898               return new DiameterCalulatorQUAD8S3;
899             default:
900               throw Exception("CellModel::buildInstanceOfDiameterCalulator : For QUAD8 only space dimension 2 and 3 implemented !");
901           }
902           break;
903         }
904       case NORM_QUAD9:
905         {
906           switch(spaceDim)
907           {
908             case 2:
909               return new DiameterCalulatorQUAD9S2;
910             case 3:
911               return new DiameterCalulatorQUAD9S3;
912             default:
913               throw Exception("CellModel::buildInstanceOfDiameterCalulator : For QUAD9 only space dimension 2 and 3 implemented !");
914           }
915           break;
916         }
917       case NORM_TETRA4:
918         {
919           if(spaceDim==3)
920             return new DiameterCalulatorTETRA4;
921           else
922             throw Exception("CellModel::buildInstanceOfDiameterCalulator : For TETRA4 space dimension 3 expected !");
923         }
924       case NORM_TETRA10:
925         {
926           if(spaceDim==3)
927             return new DiameterCalulatorTETRA10;
928           else
929             throw Exception("CellModel::buildInstanceOfDiameterCalulator : For TETRA10 space dimension 3 expected !");
930         }
931       case NORM_HEXA8:
932         {
933           if(spaceDim==3)
934             return new DiameterCalulatorHEXA8;
935           else
936             throw Exception("CellModel::buildInstanceOfDiameterCalulator : For HEXA8 space dimension 3 expected !");
937         }
938       case NORM_HEXA20:
939         {
940           if(spaceDim==3)
941             return new DiameterCalulatorHEXA20;
942           else
943             throw Exception("CellModel::buildInstanceOfDiameterCalulator : For HEXA20 space dimension 3 expected !");
944         }
945       case NORM_HEXA27:
946         {
947           if(spaceDim==3)
948             return new DiameterCalulatorHEXA27;
949           else
950             throw Exception("CellModel::buildInstanceOfDiameterCalulator : For HEXA27 space dimension 3 expected !");
951         }
952       case NORM_PENTA6:
953         {
954           if(spaceDim==3)
955             return new DiameterCalulatorPENTA6;
956           else
957             throw Exception("CellModel::buildInstanceOfDiameterCalulator : For PENTA6 space dimension 3 expected !");
958         }
959       case NORM_PENTA15:
960         {
961           if(spaceDim==3)
962             return new DiameterCalulatorPENTA15;
963           else
964             throw Exception("CellModel::buildInstanceOfDiameterCalulator : For PENTA15 space dimension 3 expected !");
965         }
966       case NORM_PYRA5:
967         {
968           if(spaceDim==3)
969             return new DiameterCalulatorPYRA5;
970           else
971             throw Exception("CellModel::buildInstanceOfDiameterCalulator : For PYRA5 space dimension 3 expected !");
972         }
973       case NORM_PYRA13:
974         {
975           if(spaceDim==3)
976             return new DiameterCalulatorPYRA13;
977           else
978             throw Exception("CellModel::buildInstanceOfDiameterCalulator : For PYRA13 space dimension 3 expected !");
979         }
980       default:
981         throw Exception("CellModel::buildInstanceOfDiameterCalulator : implemented only for TRI3, QUAD4, TETRA4, HEXA8, PENTA6, PYRA5 !");
982       }
983   }
984
985   OrientationInverter *CellModel::buildOrientationInverter() const
986   {
987     switch(_type)
988       {
989       case NORM_SEG2:
990         return new OrientationInverterSEG2;
991       case NORM_SEG3:
992         return new OrientationInverterSEG3;
993       case NORM_TRI3:
994       case NORM_QUAD4:
995         return new OrientationInverter2DLinear(getNumberOfNodes());
996       case NORM_TRI6:
997       case NORM_QUAD8:
998         return new OrientationInverter2DQuadratic(getNumberOfNodes());
999       case NORM_POLYGON:
1000         return new OrientationInverterPolygon;
1001       case NORM_QPOLYG:
1002         return new OrientationInverterQPolygon;
1003       case NORM_TETRA4:
1004         return new OrientationInverterTetra4;
1005       case NORM_PYRA5:
1006         return new OrientationInverterPyra5;
1007       case NORM_TETRA10:
1008         return new OrientationInverterTetra10;
1009       case NORM_PYRA13:
1010         return new OrientationInverterPyra13;
1011       case NORM_PENTA6:
1012       case NORM_HEXA8:
1013         return new OrientationInverter3DExtrusionLinear(getNumberOfNodes());
1014       case NORM_PENTA15:
1015       case NORM_HEXA20:
1016         return new OrientationInverter3DExtrusionQuadratic(getNumberOfNodes());
1017       default:
1018         {
1019           std::ostringstream oss; oss << "CellModel::buildOrientationInverter : not managed geometric type " << getRepr() << " yet !";
1020           throw INTERP_KERNEL::Exception(oss.str());
1021         }
1022       }
1023   }
1024 }