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