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