Salome HOME
On the road
[tools/medcoupling.git] / src / MEDCoupling / MEDCoupling1GTUMesh.cxx
1 // Copyright (C) 2007-2016  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 (CEA/DEN)
20
21 #include "MEDCoupling1GTUMesh.hxx"
22 #include "MEDCouplingUMesh.hxx"
23 #include "MEDCouplingFieldDouble.hxx"
24 #include "MEDCouplingCMesh.hxx"
25
26 #include "SplitterTetra.hxx"
27 #include "DiameterCalculator.hxx"
28 #include "OrientationInverter.hxx"
29 #include "InterpKernelAutoPtr.hxx"
30
31 using namespace MEDCoupling;
32
33 const int MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS[6]={0,1,2,4,3,5};
34
35 MEDCoupling1GTUMesh::MEDCoupling1GTUMesh():_cm(0)
36 {
37 }
38
39 MEDCoupling1GTUMesh::MEDCoupling1GTUMesh(const std::string& name, const INTERP_KERNEL::CellModel& cm):_cm(&cm)
40 {
41   setName(name);
42 }
43
44 MEDCoupling1GTUMesh::MEDCoupling1GTUMesh(const MEDCoupling1GTUMesh& other, bool recDeepCpy):MEDCouplingPointSet(other,recDeepCpy),_cm(other._cm)
45 {
46 }
47
48 MEDCoupling1GTUMesh *MEDCoupling1GTUMesh::New(const std::string& name, INTERP_KERNEL::NormalizedCellType type)
49 {
50   if(type==INTERP_KERNEL::NORM_ERROR)
51     throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
52   const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
53   if(!cm.isDynamic())
54     return MEDCoupling1SGTUMesh::New(name,type);
55   else
56     return MEDCoupling1DGTUMesh::New(name,type);
57 }
58
59 MEDCoupling1GTUMesh *MEDCoupling1GTUMesh::New(const MEDCouplingUMesh *m)
60 {
61   if(!m)
62     throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : input mesh is null !");
63   std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes());
64   if(gts.size()!=1)
65     throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : input mesh must have exactly one geometric type !");
66   const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(*gts.begin());
67   if(!cm.isDynamic())
68     return MEDCoupling1SGTUMesh::New(m);
69   else
70     return MEDCoupling1DGTUMesh::New(m);
71 }
72
73 const INTERP_KERNEL::CellModel& MEDCoupling1GTUMesh::getCellModel() const
74 {
75   return *_cm;
76 }
77
78 INTERP_KERNEL::NormalizedCellType MEDCoupling1GTUMesh::getCellModelEnum() const
79 {
80   return _cm->getEnum();
81 }
82
83 int MEDCoupling1GTUMesh::getMeshDimension() const
84 {
85   return (int)_cm->getDimension();
86 }
87
88 /*!
89  * This method returns a newly allocated array containing cell ids (ascendingly sorted) whose geometric type are equal to type.
90  * This method does not throw exception if geometric type \a type is not in \a this.
91  * This method throws an INTERP_KERNEL::Exception if meshdimension of \b this is not equal to those of \b type.
92  * The coordinates array is not considered here.
93  *
94  * \param [in] type the geometric type
95  * \return cell ids in this having geometric type \a type.
96  */
97 DataArrayInt *MEDCoupling1GTUMesh::giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const
98 {
99   MCAuto<DataArrayInt> ret=DataArrayInt::New();
100   if(type==getCellModelEnum())
101     ret->alloc(getNumberOfCells(),1);
102   else
103     ret->alloc(0,1);
104   ret->iota();
105   return ret.retn();
106 }
107
108 /*!
109  * Returns nb of cells having the geometric type \a type. No throw if no cells in \a this has the geometric type \a type.
110  */
111 std::size_t MEDCoupling1GTUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const
112 {
113   return type==getCellModelEnum()?getNumberOfCells():0;
114 }
115
116 /*!
117  * Returns a type of a cell by its id.
118  *  \param [in] cellId - the id of the cell of interest.
119  *  \return INTERP_KERNEL::NormalizedCellType - enumeration item describing the cell type.
120  *  \throw If \a cellId is invalid. Valid range is [0, \a this->getNumberOfCells() ).
121  */
122 INTERP_KERNEL::NormalizedCellType MEDCoupling1GTUMesh::getTypeOfCell(std::size_t cellId) const
123 {
124   if(cellId>=0 && cellId<getNumberOfCells())
125     return getCellModelEnum();
126   std::ostringstream oss; oss << "MEDCoupling1GTUMesh::getTypeOfCell : Requesting type of cell #" << cellId << " but it should be in [0," << getNumberOfCells() << ") !";
127   throw INTERP_KERNEL::Exception(oss.str().c_str());
128 }
129
130 /*!
131  * Returns a set of all cell types available in \a this mesh.
132  * \return std::set<INTERP_KERNEL::NormalizedCellType> - the set of cell types.
133  * \warning this method does not throw any exception even if \a this is not defined.
134  */
135 std::set<INTERP_KERNEL::NormalizedCellType> MEDCoupling1GTUMesh::getAllGeoTypes() const
136 {
137   std::set<INTERP_KERNEL::NormalizedCellType> ret;
138   ret.insert(getCellModelEnum());
139   return ret;
140 }
141
142 /*!
143  * This method expects that \a this is sorted by types. If not an exception will be thrown.
144  * This method returns in the same format as code (see MEDCouplingUMesh::checkTypeConsistencyAndContig or MEDCouplingUMesh::splitProfilePerType) how
145  * \a this is composed in cell types.
146  * The returned array is of size 3*n where n is the number of different types present in \a this. 
147  * For every k in [0,n] ret[3*k+2]==-1 because it has no sense here. 
148  * This parameter is kept only for compatibility with other methode listed above.
149  */
150 std::vector<int> MEDCoupling1GTUMesh::getDistributionOfTypes() const
151 {
152   std::vector<int> ret(3);
153   ret[0]=(int)getCellModelEnum(); ret[1]=getNumberOfCells(); ret[2]=-1;
154   return ret;
155 }
156
157 /*!
158  * This method is the opposite of MEDCouplingUMesh::checkTypeConsistencyAndContig method. Given a list of cells in \a profile it returns a list of sub-profiles sorted by geo type.
159  * The result is put in the array \a idsPerType. In the returned parameter \a code, foreach i \a code[3*i+2] refers (if different from -1) to a location into the \a idsPerType.
160  * This method has 1 input \a profile and 3 outputs \a code \a idsInPflPerType and \a idsPerType.
161  * 
162  * \param [out] code is a vector of size 3*n where n is the number of different geometric type in \a this \b reduced to the profile \a profile. \a code has exactly the same semantic than in MEDCouplingUMesh::checkTypeConsistencyAndContig method.
163  * \param [out] idsInPflPerType is a vector of size of different geometric type in the subpart defined by \a profile of \a this ( equal to \a code.size()/3). For each i,
164  *              \a idsInPflPerType[i] stores the tuple ids in \a profile that correspond to the geometric type code[3*i+0]
165  * \param [out] idsPerType is a vector of size of different sub profiles needed to be defined to represent the profile \a profile for a given geometric type.
166  *              This vector can be empty in case of all geometric type cells are fully covered in ascending in the given input \a profile.
167  * 
168  * \warning for performance reasons no deep copy will be performed, if \a profile can been used as this in output parameters \a idsInPflPerType and \a idsPerType.
169  *
170  * \throw if \a profile has not exactly one component. It throws too, if \a profile contains some values not in [0,getNumberOfCells()) or if \a this is not fully defined
171  *
172  *  \b Example1: <br>
173  *          - Before \a this has 3 cells \a profile contains [0,1,2]
174  *          - After \a code contains [NORM_...,nbCells,-1], \a idsInPflPerType [[0,1,2]] and \a idsPerType is empty <br>
175  * 
176  *  \b Example2: <br>
177  *          - Before \a this has 3 cells \a profile contains [1,2]
178  *          - After \a code contains [NORM_...,nbCells,0], \a idsInPflPerType [[0,1]] and \a idsPerType is [[1,2]] <br>
179
180  */
181 void MEDCoupling1GTUMesh::splitProfilePerType(const DataArrayInt *profile, std::vector<int>& code, std::vector<DataArrayInt *>& idsInPflPerType, std::vector<DataArrayInt *>& idsPerType) const
182 {
183   if(!profile)
184     throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::splitProfilePerType : input profile is NULL !");
185   if(profile->getNumberOfComponents()!=1)
186     throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::splitProfilePerType : input profile should have exactly one component !");
187   int nbTuples(profile->getNumberOfTuples()),nbOfCells(getNumberOfCells());
188   code.resize(3); idsInPflPerType.resize(1);
189   code[0]=(int)getCellModelEnum(); code[1]=nbTuples;
190   idsInPflPerType.resize(1);
191   if(profile->isIota(nbOfCells))
192     {
193       code[2]=-1;
194       idsInPflPerType[0]=const_cast<DataArrayInt *>(profile); idsInPflPerType[0]->incrRef();
195       idsPerType.clear();
196       return ;
197     }
198   code[2]=0;
199   profile->checkAllIdsInRange(0,nbOfCells);
200   idsPerType.resize(1);
201   idsPerType[0]=const_cast<DataArrayInt *>(profile); idsPerType[0]->incrRef();
202   idsInPflPerType[0]=DataArrayInt::Range(0,nbTuples,1);
203 }
204
205 /*!
206  * This method tries to minimize at most the number of deep copy.
207  * So if \a idsPerType is not empty it can be returned directly (without copy, but with ref count incremented) in return.
208  * 
209  * \sa MEDCouplingUMesh::checkTypeConsistencyAndContig
210  */
211 DataArrayInt *MEDCoupling1GTUMesh::checkTypeConsistencyAndContig(const std::vector<int>& code, const std::vector<const DataArrayInt *>& idsPerType) const
212 {
213   int nbOfCells=getNumberOfCells();
214   if(code.size()!=3)
215     throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : invalid input code should be exactly of size 3 !");
216   if(code[0]!=(int)getCellModelEnum())
217     {
218       std::ostringstream oss; oss << "MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : Mismatch of geometric type ! Asking for " << code[0] << " whereas the geometric type is \a this is " << getCellModelEnum() << " (" << _cm->getRepr() << ") !";
219       throw INTERP_KERNEL::Exception(oss.str().c_str());
220     }
221   if(code[2]==-1)
222     {
223       if(code[1]==nbOfCells)
224         return 0;
225       else
226         {
227           std::ostringstream oss; oss << "MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : mismatch between the number of cells in this (" << nbOfCells << ") and the number of non profile (" << code[1] << ") !";
228           throw INTERP_KERNEL::Exception(oss.str().c_str());
229         }
230     }
231   if(code[2]!=0)
232     throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : single geo type mesh ! 0 or -1 is expected at pos #2 of input code !");
233   if(idsPerType.size()!=1)
234     throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : input code points to DataArrayInt #0 whereas the size of idsPerType is not equal to 1 !");
235   const DataArrayInt *pfl=idsPerType[0];
236   if(!pfl)
237     throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : the input code points to a NULL DataArrayInt at rank 0 !");
238   if(pfl->getNumberOfComponents()!=1)
239     throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : input profile should have exactly one component !");
240   pfl->checkAllIdsInRange(0,nbOfCells);
241   pfl->incrRef();
242   return const_cast<DataArrayInt *>(pfl);
243 }
244
245 void MEDCoupling1GTUMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const
246 {
247   MCAuto<MEDCouplingUMesh> m=buildUnstructured();
248   m->writeVTKLL(ofs,cellData,pointData,byteData);
249 }
250
251 std::string MEDCoupling1GTUMesh::getVTKDataSetType() const
252 {
253   return std::string("UnstructuredGrid");
254 }
255
256 std::string MEDCoupling1GTUMesh::getVTKFileExtension() const
257 {
258   return std::string("vtu");
259 }
260
261 std::size_t MEDCoupling1GTUMesh::getHeapMemorySizeWithoutChildren() const
262 {
263   return MEDCouplingPointSet::getHeapMemorySizeWithoutChildren();
264 }
265
266 bool MEDCoupling1GTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const
267 {
268   if(!MEDCouplingPointSet::isEqualIfNotWhy(other,prec,reason))
269     return false;
270   if(!other)
271     throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::isEqualIfNotWhy : input other pointer is null !");
272   const MEDCoupling1GTUMesh *otherC=dynamic_cast<const MEDCoupling1GTUMesh *>(other);
273   if(!otherC)
274     {
275       reason="mesh given in input is not castable in MEDCouplingSGTUMesh !";
276       return false;
277     }
278   if(_cm!=otherC->_cm)
279     {
280       reason="mismatch in geometric type !";
281       return false;
282     }
283   return true;
284 }
285
286 bool MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
287 {
288   if(!MEDCouplingPointSet::isEqualWithoutConsideringStr(other,prec))
289     return false;
290   if(!other)
291     throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
292   const MEDCoupling1GTUMesh *otherC=dynamic_cast<const MEDCoupling1GTUMesh *>(other);
293   if(!otherC)
294     return false;
295   if(_cm!=otherC->_cm)
296     return false;
297   return true;
298 }
299
300 void MEDCoupling1GTUMesh::checkConsistencyLight() const
301 {
302   MEDCouplingPointSet::checkConsistencyLight();
303 }
304
305 DataArrayDouble *MEDCoupling1GTUMesh::computeCellCenterOfMass() const
306 {
307   MCAuto<MEDCouplingUMesh> m=buildUnstructured();
308   MCAuto<DataArrayDouble> ret=m->computeCellCenterOfMass();
309   return ret.retn();
310 }
311
312 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::getMeasureField(bool isAbs) const
313 {
314   MCAuto<MEDCouplingUMesh> m=buildUnstructured();
315   MCAuto<MEDCouplingFieldDouble> ret=m->getMeasureField(isAbs);
316   ret->setMesh(this);
317   return ret.retn();
318 }
319
320 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::getMeasureFieldOnNode(bool isAbs) const
321 {
322   MCAuto<MEDCouplingUMesh> m=buildUnstructured();
323   MCAuto<MEDCouplingFieldDouble> ret=m->getMeasureFieldOnNode(isAbs);
324   ret->setMesh(this);
325   return ret.retn();
326 }
327
328 /*!
329  * to improve perf !
330  */
331 int MEDCoupling1GTUMesh::getCellContainingPoint(const double *pos, double eps) const
332 {
333   MCAuto<MEDCouplingUMesh> m(buildUnstructured());
334   return m->getCellContainingPoint(pos,eps);
335 }
336
337 /*!
338  * to improve perf !
339  */
340 void MEDCoupling1GTUMesh::getCellsContainingPoint(const double *pos, double eps, std::vector<int>& elts) const
341 {
342   MCAuto<MEDCouplingUMesh> m(buildUnstructured());
343   return m->getCellsContainingPoint(pos,eps,elts);
344 }
345
346 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::buildOrthogonalField() const
347 {
348   MCAuto<MEDCouplingUMesh> m=buildUnstructured();
349   MCAuto<MEDCouplingFieldDouble> ret=m->buildOrthogonalField();
350   ret->setMesh(this);
351   return ret.retn();
352 }
353
354 DataArrayInt *MEDCoupling1GTUMesh::getCellsInBoundingBox(const double *bbox, double eps) const
355 {
356   MCAuto<MEDCouplingUMesh> m=buildUnstructured();
357   return m->getCellsInBoundingBox(bbox,eps);
358 }
359
360 DataArrayInt *MEDCoupling1GTUMesh::getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps)
361 {
362   MCAuto<MEDCouplingUMesh> m=buildUnstructured();
363   return m->getCellsInBoundingBox(bbox,eps);
364 }
365
366 MEDCouplingPointSet *MEDCoupling1GTUMesh::buildFacePartOfMySelfNode(const int *start, const int *end, bool fullyIn) const
367 {
368   MCAuto<MEDCouplingUMesh> m=buildUnstructured();
369   return m->buildFacePartOfMySelfNode(start,end,fullyIn);
370 }
371
372 DataArrayInt *MEDCoupling1GTUMesh::findBoundaryNodes() const
373 {
374   MCAuto<MEDCouplingUMesh> m=buildUnstructured();
375   return m->findBoundaryNodes();
376 }
377
378 MEDCouplingPointSet *MEDCoupling1GTUMesh::buildBoundaryMesh(bool keepCoords) const
379 {
380   MCAuto<MEDCouplingUMesh> m=buildUnstructured();
381   return m->buildBoundaryMesh(keepCoords);
382 }
383
384 void MEDCoupling1GTUMesh::findCommonCells(int compType, int startCellId, DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr) const
385 {
386   MCAuto<MEDCouplingUMesh> m=buildUnstructured();
387   m->findCommonCells(compType,startCellId,commonCellsArr,commonCellsIArr);
388 }
389
390 std::size_t MEDCoupling1GTUMesh::getNodalConnectivityLength() const
391 {
392   const DataArrayInt *c1(getNodalConnectivity());
393   if(!c1)
394     throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : no connectivity set !");
395   if(c1->getNumberOfComponents()!=1)
396     throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : Nodal connectivity array set must have exactly one component !");
397   if(!c1->isAllocated())
398     throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : Nodal connectivity array must be allocated !");
399   return c1->getNumberOfTuples();
400 }
401
402 /*!
403  * This method aggregates all the meshes in \a parts to put them in a single unstructured mesh (those returned).
404  * The order of cells is the returned instance is those in the order of instances in \a parts.
405  *
406  * \param [in] parts - all not null parts of single geo type meshes to be aggreagated having the same mesh dimension and same coordinates.
407  * \return MEDCouplingUMesh * - new object to be dealt by the caller.
408  *
409  * \throw If one element is null in \a parts.
410  * \throw If not all the parts do not have the same mesh dimension.
411  * \throw If not all the parts do not share the same coordinates.
412  * \throw If not all the parts have their connectivity set properly.
413  * \throw If \a parts is empty.
414  */
415 MEDCouplingUMesh *MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh(const std::vector< const MEDCoupling1GTUMesh *>& parts)
416 {
417   if(parts.empty())
418     throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : input parts vector is empty !");
419   const MEDCoupling1GTUMesh *firstPart(parts[0]);
420   if(!firstPart)
421     throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : the first instance in input parts is null !");
422   const DataArrayDouble *coords(firstPart->getCoords());
423   int meshDim(firstPart->getMeshDimension());
424   MCAuto<MEDCouplingUMesh> ret(MEDCouplingUMesh::New(firstPart->getName(),meshDim)); ret->setDescription(firstPart->getDescription());
425   ret->setCoords(coords);
426   int nbOfCells(0),connSize(0);
427   for(std::vector< const MEDCoupling1GTUMesh *>::const_iterator it=parts.begin();it!=parts.end();it++)
428     {
429       if(!(*it))
430         throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : presence of null pointer in input vector !");
431       if((*it)->getMeshDimension()!=meshDim)
432         throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : all the instances in input vector must have same mesh dimension !");
433       if((*it)->getCoords()!=coords)
434         throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : all the instances must share the same coordinates pointer !");
435       nbOfCells+=(*it)->getNumberOfCells();
436       connSize+=(*it)->getNodalConnectivityLength();
437     }
438   MCAuto<DataArrayInt> conn(DataArrayInt::New()),connI(DataArrayInt::New());
439   connI->alloc(nbOfCells+1,1); conn->alloc(connSize+nbOfCells,1);
440   int *c(conn->getPointer()),*ci(connI->getPointer()); *ci=0;
441   for(std::vector< const MEDCoupling1GTUMesh *>::const_iterator it=parts.begin();it!=parts.end();it++)
442     {
443       int curNbCells((*it)->getNumberOfCells());
444       int geoType((int)(*it)->getCellModelEnum());
445       const int *cinPtr((*it)->getNodalConnectivity()->begin());
446       const MEDCoupling1SGTUMesh *ps(dynamic_cast<const MEDCoupling1SGTUMesh *>(*it));
447       const MEDCoupling1DGTUMesh *pd(dynamic_cast<const MEDCoupling1DGTUMesh *>(*it));
448       if(ps && !pd)
449         {
450           int nNodesPerCell(ps->getNumberOfNodesPerCell());
451           for(int i=0;i<curNbCells;i++,ci++,cinPtr+=nNodesPerCell)
452             {
453               *c++=geoType;
454               c=std::copy(cinPtr,cinPtr+nNodesPerCell,c);
455               ci[1]=ci[0]+nNodesPerCell+1;
456             }
457         }
458       else if(!ps && pd)
459         {
460           const int *ciinPtr(pd->getNodalConnectivityIndex()->begin());
461           for(int i=0;i<curNbCells;i++,ci++,ciinPtr++)
462             {
463               *c++=geoType;
464               c=std::copy(cinPtr+ciinPtr[0],cinPtr+ciinPtr[1],c);
465               ci[1]=ci[0]+ciinPtr[1]-ciinPtr[0]+1;
466             }
467         }
468       else
469         throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : presence of instance which type is not in [MEDCoupling1SGTUMesh,MEDCoupling1DGTUMesh] !");
470     }
471   ret->setConnectivity(conn,connI,true);
472   return ret.retn();
473 }
474
475 //==
476
477 MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh(const MEDCoupling1SGTUMesh& other, bool recDeepCpy):MEDCoupling1GTUMesh(other,recDeepCpy),_conn(other._conn)
478 {
479   if(recDeepCpy)
480     {
481       const DataArrayInt *c(other._conn);
482       if(c)
483         _conn=c->deepCopy();
484     }
485 }
486
487 MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh(const std::string& name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm)
488 {
489 }
490
491 MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh()
492 {
493 }
494
495 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New()
496 {
497   return new MEDCoupling1SGTUMesh;
498 }
499
500 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New(const std::string& name, INTERP_KERNEL::NormalizedCellType type)
501 {
502   if(type==INTERP_KERNEL::NORM_ERROR)
503     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
504   const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
505   if(cm.isDynamic())
506     {
507       std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::New : the input geometric type " << cm.getRepr() << " is dynamic ! Only static types are allowed here !";
508       throw INTERP_KERNEL::Exception(oss.str().c_str());
509     }
510   return new MEDCoupling1SGTUMesh(name,cm);
511 }
512
513 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New(const MEDCouplingUMesh *m)
514 {
515   if(!m)
516     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : input mesh is null !");
517   std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes());
518   if(gts.size()!=1)
519     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : input mesh must have exactly one geometric type !");
520   int geoType((int)*gts.begin());
521   MCAuto<MEDCoupling1SGTUMesh> ret(MEDCoupling1SGTUMesh::New(m->getName(),*gts.begin()));
522   ret->setCoords(m->getCoords()); ret->setDescription(m->getDescription());
523   int nbCells(m->getNumberOfCells());
524   int nbOfNodesPerCell(ret->getNumberOfNodesPerCell());
525   MCAuto<DataArrayInt> conn(DataArrayInt::New()); conn->alloc(nbCells*nbOfNodesPerCell,1);
526   int *c(conn->getPointer());
527   const int *cin(m->getNodalConnectivity()->begin()),*ciin(m->getNodalConnectivityIndex()->begin());
528   for(int i=0;i<nbCells;i++,ciin++)
529     {
530       if(cin[ciin[0]]==geoType)
531         {
532           if(ciin[1]-ciin[0]==nbOfNodesPerCell+1)
533             c=std::copy(cin+ciin[0]+1,cin+ciin[1],c);
534           else
535             {
536               std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::New(const MEDCouplingUMesh *m) : something is wrong in the input mesh at cell #" << i << " ! The size of cell is not those expected (" << nbOfNodesPerCell << ") !";
537               throw INTERP_KERNEL::Exception(oss.str().c_str());
538             }
539         }
540       else
541         {
542           std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::New(const MEDCouplingUMesh *m) : something is wrong in the input mesh at cell #" << i << " ! The geometric type is not those expected !";
543           throw INTERP_KERNEL::Exception(oss.str().c_str());
544         }
545     }
546   ret->setNodalConnectivity(conn);
547   try
548   { ret->copyTinyInfoFrom(m); }
549   catch(INTERP_KERNEL::Exception&) { }
550   return ret.retn();
551 }
552
553 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::clone(bool recDeepCpy) const
554 {
555   return new MEDCoupling1SGTUMesh(*this,recDeepCpy);
556 }
557
558 /*!
559  * This method behaves mostly like MEDCoupling1SGTUMesh::deepCopy method, except that only nodal connectivity arrays are deeply copied.
560  * The coordinates are shared between \a this and the returned instance.
561  * 
562  * \return MEDCoupling1SGTUMesh * - A new object instance holding the copy of \a this (deep for connectivity, shallow for coordiantes)
563  * \sa MEDCoupling1SGTUMesh::deepCopy
564  */
565 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::deepCopyConnectivityOnly() const
566 {
567   checkConsistencyLight();
568   MCAuto<MEDCoupling1SGTUMesh> ret(clone(false));
569   MCAuto<DataArrayInt> c(_conn->deepCopy());
570   ret->setNodalConnectivity(c);
571   return ret.retn();
572 }
573
574 void MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other)
575 {
576   if(!other)
577     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom : input pointer is null !");
578   const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
579   if(!otherC)
580     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1SGTUMesh instance !");
581   setNodalConnectivity(otherC->getNodalConnectivity());
582 }
583
584 void MEDCoupling1SGTUMesh::updateTime() const
585 {
586   MEDCoupling1GTUMesh::updateTime();
587   const DataArrayInt *c(_conn);
588   if(c)
589     updateTimeWith(*c);
590 }
591
592 std::size_t MEDCoupling1SGTUMesh::getHeapMemorySizeWithoutChildren() const
593 {
594   return MEDCoupling1GTUMesh::getHeapMemorySizeWithoutChildren();
595 }
596
597 std::vector<const BigMemoryObject *> MEDCoupling1SGTUMesh::getDirectChildrenWithNull() const
598 {
599   std::vector<const BigMemoryObject *> ret(MEDCoupling1GTUMesh::getDirectChildrenWithNull());
600   ret.push_back((const DataArrayInt *)_conn);
601   return ret;
602 }
603
604 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::deepCopy() const
605 {
606   return clone(true);
607 }
608
609 bool MEDCoupling1SGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const
610 {
611   if(!other)
612     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEqualIfNotWhy : input other pointer is null !");
613   std::ostringstream oss; oss.precision(15);
614   const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
615   if(!otherC)
616     {
617       reason="mesh given in input is not castable in MEDCoupling1SGTUMesh !";
618       return false;
619     }
620   if(!MEDCoupling1GTUMesh::isEqualIfNotWhy(other,prec,reason))
621     return false;
622   const DataArrayInt *c1(_conn),*c2(otherC->_conn);
623   if(c1==c2)
624     return true;
625   if(!c1 || !c2)
626     {
627       reason="in connectivity of single static geometric type exactly one among this and other is null !";
628       return false;
629     }
630   if(!c1->isEqualIfNotWhy(*c2,reason))
631     {
632       reason.insert(0,"Nodal connectivity DataArrayInt differ : ");
633       return false;
634     }
635   return true;
636 }
637
638 bool MEDCoupling1SGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
639 {
640   if(!other)
641     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
642   const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
643   if(!otherC)
644     return false;
645   if(!MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(other,prec))
646     return false;
647   const DataArrayInt *c1(_conn),*c2(otherC->_conn);
648   if(c1==c2)
649     return true;
650   if(!c1 || !c2)
651     return false;
652   if(!c1->isEqualWithoutConsideringStr(*c2))
653     return false;
654   return true;
655 }
656
657 void MEDCoupling1SGTUMesh::checkConsistencyOfConnectivity() const
658 {
659   const DataArrayInt *c1(_conn);
660   if(c1)
661     {
662       if(c1->getNumberOfComponents()!=1)
663         throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !");
664       if(c1->getInfoOnComponent(0)!="")
665         throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !");
666       c1->checkAllocated();
667     }
668   else
669     throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !");
670 }
671
672 void MEDCoupling1SGTUMesh::checkConsistencyLight() const
673 {
674   MEDCouplingPointSet::checkConsistencyLight();
675   checkConsistencyOfConnectivity();
676 }
677
678 void MEDCoupling1SGTUMesh::checkConsistency(double eps) const
679 {
680   checkConsistencyLight();
681   const DataArrayInt *c1(_conn);
682   int nbOfTuples=c1->getNumberOfTuples();
683   int nbOfNodesPerCell=(int)_cm->getNumberOfNodes();
684   if(nbOfTuples%nbOfNodesPerCell!=0)
685     {
686       std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::checkConsistency : the nb of tuples in conn is " << nbOfTuples << " and number of nodes per cell is " << nbOfNodesPerCell << ". But " << nbOfTuples << "%" << nbOfNodesPerCell << " !=0 !";
687       throw INTERP_KERNEL::Exception(oss.str().c_str());
688     }
689   int nbOfNodes=getNumberOfNodes();
690   int nbOfCells=nbOfTuples/nbOfNodesPerCell;
691   const int *w(c1->begin());
692   for(int i=0;i<nbOfCells;i++)
693     for(int j=0;j<nbOfNodesPerCell;j++,w++)
694       {
695         if(*w<0 || *w>=nbOfNodes)
696           {
697             std::ostringstream oss; oss << "At node #" << j << " of  cell #" << i << ", is equal to " << *w << " must be in [0," << nbOfNodes << ") !";
698             throw INTERP_KERNEL::Exception(oss.str().c_str());
699           }
700       }
701 }
702
703 std::size_t MEDCoupling1SGTUMesh::getNumberOfCells() const
704 {
705   std::size_t nbOfTuples(getNodalConnectivityLength());
706   int nbOfNodesPerCell(getNumberOfNodesPerCell());
707   if(nbOfTuples%nbOfNodesPerCell!=0)
708     {
709       std::ostringstream oss; oss << "MEDCoupling1SGTUMesh:getNumberOfCells: : the nb of tuples in conn is " << nbOfTuples << " and number of nodes per cell is " << nbOfNodesPerCell << ". But " << nbOfTuples << "%" << nbOfNodesPerCell << " !=0 !";
710       throw INTERP_KERNEL::Exception(oss.str().c_str());
711     }
712   return nbOfTuples/nbOfNodesPerCell;
713 }
714
715 int MEDCoupling1SGTUMesh::getNumberOfNodesInCell(int cellId) const
716 {
717   return getNumberOfNodesPerCell();
718 }
719
720 int MEDCoupling1SGTUMesh::getNumberOfNodesPerCell() const
721 {
722   checkNonDynamicGeoType();
723   return (int)_cm->getNumberOfNodes();
724 }
725
726 DataArrayInt *MEDCoupling1SGTUMesh::computeNbOfNodesPerCell() const
727 {
728   checkNonDynamicGeoType();
729   MCAuto<DataArrayInt> ret=DataArrayInt::New();
730   ret->alloc(getNumberOfCells(),1);
731   ret->fillWithValue((int)_cm->getNumberOfNodes());
732   return ret.retn();
733 }
734
735 DataArrayInt *MEDCoupling1SGTUMesh::computeNbOfFacesPerCell() const
736 {
737   checkNonDynamicGeoType();
738   MCAuto<DataArrayInt> ret=DataArrayInt::New();
739   ret->alloc(getNumberOfCells(),1);
740   ret->fillWithValue((int)_cm->getNumberOfSons());
741   return ret.retn();
742 }
743
744 DataArrayInt *MEDCoupling1SGTUMesh::computeEffectiveNbOfNodesPerCell() const
745 {
746   checkNonDynamicGeoType();
747   MCAuto<DataArrayInt> ret=DataArrayInt::New();
748   int nbCells(getNumberOfCells());
749   ret->alloc(nbCells,1);
750   int *retPtr(ret->getPointer());
751   int nbNodesPerCell(getNumberOfNodesPerCell());
752   const int *conn(_conn->begin());
753   for(int i=0;i<nbCells;i++,conn+=nbNodesPerCell,retPtr++)
754     {
755       std::set<int> s(conn,conn+nbNodesPerCell);
756       *retPtr=(int)s.size();
757     }
758   return ret.retn();
759 }
760
761 void MEDCoupling1SGTUMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
762 {
763   int sz=getNumberOfNodesPerCell();
764   conn.resize(sz);
765   if(cellId>=0 && cellId<getNumberOfCells())
766     std::copy(_conn->begin()+cellId*sz,_conn->begin()+(cellId+1)*sz,conn.begin());
767   else
768     {
769       std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << getNumberOfCells() << ") !";
770       throw INTERP_KERNEL::Exception(oss.str().c_str());
771     }
772 }
773
774 void MEDCoupling1SGTUMesh::checkNonDynamicGeoType() const
775 {
776   if(_cm->isDynamic())
777     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkNonDynamicGeoType : internal error ! the internal geo type is dynamic ! should be static !");
778 }
779
780 std::string MEDCoupling1SGTUMesh::simpleRepr() const
781 {
782   static const char msg0[]="No coordinates specified !";
783   std::ostringstream ret;
784   ret << "Single static geometic type (" << _cm->getRepr() << ") unstructured mesh with name : \"" << getName() << "\"\n";
785   ret << "Description of mesh : \"" << getDescription() << "\"\n";
786   int tmpp1,tmpp2;
787   double tt=getTime(tmpp1,tmpp2);
788   ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
789   ret << "Iteration : " << tmpp1  << " Order : " << tmpp2 << "\n";
790   ret << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : ";
791   if(_coords!=0)
792     {
793       const int spaceDim=getSpaceDimension();
794       ret << spaceDim << "\nInfo attached on space dimension : ";
795       for(int i=0;i<spaceDim;i++)
796         ret << "\"" << _coords->getInfoOnComponent(i) << "\" ";
797       ret << "\n";
798     }
799   else
800     ret << msg0 << "\n";
801   ret << "Number of nodes : ";
802   if(_coords!=0)
803     ret << getNumberOfNodes() << "\n";
804   else
805     ret << msg0 << "\n";
806   ret << "Number of cells : ";
807   if((const DataArrayInt *)_conn)
808     {
809       if(_conn->isAllocated())
810         {
811           if(_conn->getNumberOfComponents()==1)
812             ret << getNumberOfCells() << "\n";
813           else
814             ret << "Nodal connectivity array specified and allocated but with not exactly one component !" << "\n";
815         }
816       else
817         ret << "Nodal connectivity array specified but not allocated !" << "\n";
818     }
819   else
820     ret << "No connectivity specified !" << "\n";
821   ret << "Cell type : " << _cm->getRepr() << "\n";
822   return ret.str();
823 }
824
825 std::string MEDCoupling1SGTUMesh::advancedRepr() const
826 {
827   std::ostringstream ret;
828   ret << simpleRepr();
829   ret << "\nCoordinates array : \n___________________\n\n";
830   if(_coords)
831     _coords->reprWithoutNameStream(ret);
832   else
833     ret << "No array set !\n";
834   ret << "\n\nConnectivity array : \n____________________\n\n";
835   //
836   if((const DataArrayInt *)_conn)
837     {
838       if(_conn->isAllocated())
839         {
840           if(_conn->getNumberOfComponents()==1)
841             {
842               int nbOfCells=getNumberOfCells();
843               int sz=getNumberOfNodesPerCell();
844               const int *connPtr=_conn->begin();
845               for(int i=0;i<nbOfCells;i++,connPtr+=sz)
846                 {
847                   ret << "Cell #" << i << " : ";
848                   std::copy(connPtr,connPtr+sz,std::ostream_iterator<int>(ret," "));
849                   ret << "\n";
850                 }
851             }
852           else
853             ret << "Nodal connectivity array specified and allocated but with not exactly one component !" << "\n";
854         }
855       else
856         ret << "Nodal connectivity array specified but not allocated !" << "\n";
857     }
858   else
859     ret << "No connectivity specified !" << "\n";
860   return ret.str();
861 }
862
863 DataArrayDouble *MEDCoupling1SGTUMesh::computeIsoBarycenterOfNodesPerCell() const
864 {
865   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
866   int spaceDim=getSpaceDimension();
867   int nbOfCells=getNumberOfCells();//checkConsistencyLight()
868   int nbOfNodes=getNumberOfNodes();
869   ret->alloc(nbOfCells,spaceDim);
870   double *ptToFill=ret->getPointer();
871   const double *coor=_coords->begin();
872   const int *nodal=_conn->begin();
873   int sz=getNumberOfNodesPerCell();
874   double coeff=1./(double)sz;
875   for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim)
876     {
877       std::fill(ptToFill,ptToFill+spaceDim,0.);
878       for(int j=0;j<sz;j++,nodal++)
879         if(*nodal>=0 && *nodal<nbOfNodes)
880           std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
881         else
882           {
883             std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," <<   nbOfNodes << ") !";
884             throw INTERP_KERNEL::Exception(oss.str().c_str());
885           }
886       std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),coeff));
887     }
888   return ret.retn();
889 }
890
891 void MEDCoupling1SGTUMesh::renumberCells(const int *old2NewBg, bool check)
892 {
893   int nbCells=getNumberOfCells();
894   MCAuto<DataArrayInt> o2n=DataArrayInt::New();
895   o2n->useArray(old2NewBg,false,C_DEALLOC,nbCells,1);
896   if(check)
897     o2n=o2n->checkAndPreparePermutation();
898   //
899   const int *conn=_conn->begin();
900   MCAuto<DataArrayInt> n2o=o2n->invertArrayO2N2N2O(nbCells);
901   const int *n2oPtr=n2o->begin();
902   MCAuto<DataArrayInt> newConn=DataArrayInt::New();
903   newConn->alloc(_conn->getNumberOfTuples(),1);
904   newConn->copyStringInfoFrom(*_conn);
905   int sz=getNumberOfNodesPerCell();
906   //
907   int *newC=newConn->getPointer();
908   for(int i=0;i<nbCells;i++,newC+=sz)
909     {
910       int pos=n2oPtr[i];
911       std::copy(conn+pos*sz,conn+(pos+1)*sz,newC);
912     }
913   _conn=newConn;
914 }
915
916 /*!
917  * Keeps from \a this only cells which constituing point id are in the ids specified by [\a begin,\a end).
918  * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
919  * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not.
920  * If \a fullyIn is true only cells whose ids are \b fully contained in [\a begin,\a end) tab will be kept.
921  *
922  * \param [in] begin input start of array of node ids.
923  * \param [in] end input end of array of node ids.
924  * \param [in] fullyIn input that specifies if all node ids must be in [\a begin,\a end) array to consider cell to be in.
925  * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end.
926  */
927 void MEDCoupling1SGTUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const
928 {
929   int nbOfCells=getNumberOfCells();
930   MCAuto<DataArrayInt> cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1);
931   int tmp=-1;
932   int sz=_conn->getMaxValue(tmp); sz=std::max(sz,0)+1;
933   std::vector<bool> fastFinder(sz,false);
934   for(const int *work=begin;work!=end;work++)
935     if(*work>=0 && *work<sz)
936       fastFinder[*work]=true;
937   const int *conn=_conn->begin();
938   int nbNodesPerCell=getNumberOfNodesPerCell();
939   for(int i=0;i<nbOfCells;i++,conn+=nbNodesPerCell)
940     {
941       int ref=0,nbOfHit=0;
942       for(int j=0;j<nbNodesPerCell;j++)
943         if(conn[j]>=0)
944           {
945             ref++;
946             if(fastFinder[conn[j]])
947               nbOfHit++;
948           }
949       if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn))
950         cellIdsKept->pushBackSilent(i);
951     }
952   cellIdsKeptArr=cellIdsKept.retn();
953 }
954
955 MEDCouplingMesh *MEDCoupling1SGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
956 {
957   if(other->getType()!=SINGLE_STATIC_GEO_TYPE_UNSTRUCTURED)
958     throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single static geo type each other !");
959   const MEDCoupling1SGTUMesh *otherC=static_cast<const MEDCoupling1SGTUMesh *>(other);
960   return Merge1SGTUMeshes(this,otherC);
961 }
962
963 MEDCouplingUMesh *MEDCoupling1SGTUMesh::buildUnstructured() const
964 {
965   MCAuto<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName(),getMeshDimension());
966   ret->setCoords(getCoords());
967   const int *nodalConn=_conn->begin();
968   int nbCells=getNumberOfCells();
969   int nbNodesPerCell=getNumberOfNodesPerCell();
970   int geoType=(int)getCellModelEnum();
971   MCAuto<DataArrayInt> c=DataArrayInt::New(); c->alloc(nbCells*(nbNodesPerCell+1),1);
972   int *cPtr=c->getPointer();
973   for(int i=0;i<nbCells;i++,nodalConn+=nbNodesPerCell)
974     {
975       *cPtr++=geoType;
976       cPtr=std::copy(nodalConn,nodalConn+nbNodesPerCell,cPtr);
977     }
978   MCAuto<DataArrayInt> cI=DataArrayInt::Range(0,(nbCells+1)*(nbNodesPerCell+1),nbNodesPerCell+1);
979   ret->setConnectivity(c,cI,true);
980   try
981   { ret->copyTinyInfoFrom(this); }
982   catch(INTERP_KERNEL::Exception&) { }
983   return ret.retn();
984 }
985
986 DataArrayInt *MEDCoupling1SGTUMesh::simplexize(int policy)
987 {
988   switch(policy)
989   {
990     case 0:
991       return simplexizePol0();
992     case 1:
993       return simplexizePol1();
994     case (int) INTERP_KERNEL::PLANAR_FACE_5:
995         return simplexizePlanarFace5();
996     case (int) INTERP_KERNEL::PLANAR_FACE_6:
997         return simplexizePlanarFace6();
998     default:
999       throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::simplexize : unrecognized policy ! Must be :\n  - 0 or 1 (only available for meshdim=2) \n  - PLANAR_FACE_5, PLANAR_FACE_6  (only for meshdim=3)");
1000   }
1001 }
1002
1003 /// @cond INTERNAL
1004
1005 struct MEDCouplingAccVisit
1006 {
1007   MEDCouplingAccVisit():_new_nb_of_nodes(0) { }
1008   int operator()(int val) { if(val!=-1) return _new_nb_of_nodes++; else return -1; }
1009   int _new_nb_of_nodes;
1010 };
1011
1012 /// @endcond
1013
1014 /*!
1015  * This method returns all node ids used in \b this. The data array returned has to be dealt by the caller.
1016  * The returned node ids are sortes ascendingly. This method is closed to MEDCoupling1SGTUMesh::getNodeIdsInUse except
1017  * the format of returned DataArrayInt instance.
1018  *
1019  * \return a newly allocated DataArrayInt sorted ascendingly of fetched node ids.
1020  * \sa MEDCoupling1SGTUMesh::getNodeIdsInUse, areAllNodesFetched
1021  */
1022 DataArrayInt *MEDCoupling1SGTUMesh::computeFetchedNodeIds() const
1023 {
1024   checkConsistencyOfConnectivity();
1025   int nbNodes(getNumberOfNodes());
1026   std::vector<bool> fetchedNodes(nbNodes,false);
1027   computeNodeIdsAlg(fetchedNodes);
1028   int sz((int)std::count(fetchedNodes.begin(),fetchedNodes.end(),true));
1029   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
1030   int *retPtr(ret->getPointer());
1031   for(int i=0;i<nbNodes;i++)
1032     if(fetchedNodes[i])
1033       *retPtr++=i;
1034   return ret.retn();
1035 }
1036
1037 /*!
1038  * Finds nodes not used in any cell and returns an array giving a new id to every node
1039  * by excluding the unused nodes, for which the array holds -1. The result array is
1040  * a mapping in "Old to New" mode. 
1041  *  \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
1042  *  \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a
1043  *          this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
1044  *          if the node is unused or a new id else. The caller is to delete this
1045  *          array using decrRef() as it is no more needed.  
1046  *  \throw If the coordinates array is not set.
1047  *  \throw If the nodal connectivity of cells is not defined.
1048  *  \throw If the nodal connectivity includes an invalid id.
1049  *  \sa MEDCoupling1SGTUMesh::computeFetchedNodeIds, areAllNodesFetched
1050  */
1051 DataArrayInt *MEDCoupling1SGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const
1052 {
1053   nbrOfNodesInUse=-1;
1054   int nbOfNodes=getNumberOfNodes();
1055   int nbOfCells=getNumberOfCells();
1056   MCAuto<DataArrayInt> ret(DataArrayInt::New());
1057   ret->alloc(nbOfNodes,1);
1058   int *traducer=ret->getPointer();
1059   std::fill(traducer,traducer+nbOfNodes,-1);
1060   const int *conn=_conn->begin();
1061   int nbNodesPerCell=getNumberOfNodesPerCell();
1062   for(int i=0;i<nbOfCells;i++)
1063     for(int j=0;j<nbNodesPerCell;j++,conn++)
1064       if(*conn>=0 && *conn<nbOfNodes)
1065         traducer[*conn]=1;
1066       else
1067         {
1068           std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsInUse : In cell #" << i  << " presence of node id " <<  conn[j] << " not in [0," << nbOfNodes << ") !";
1069           throw INTERP_KERNEL::Exception(oss.str().c_str());
1070         }
1071   nbrOfNodesInUse=(int)std::count(traducer,traducer+nbOfNodes,1);
1072   std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
1073   return ret.retn();
1074 }
1075
1076 /*!
1077  * This method renumbers only nodal connectivity in \a this. The renumbering is only an offset applied. So this method is a specialization of
1078  * \a renumberNodesInConn. \b WARNING, this method does not check that the resulting node ids in the nodal connectivity is in a valid range !
1079  *
1080  * \param [in] offset - specifies the offset to be applied on each element of connectivity.
1081  *
1082  * \sa renumberNodesInConn
1083  */
1084 void MEDCoupling1SGTUMesh::renumberNodesWithOffsetInConn(int offset)
1085 {
1086   getNumberOfCells();//only to check that all is well defined.
1087   _conn->applyLin(1,offset);
1088   updateTime();
1089 }
1090
1091 /*!
1092  *  Same than renumberNodesInConn(const int *) except that here the format of old-to-new traducer is using map instead
1093  *  of array. This method is dedicated for renumbering from a big set of nodes the a tiny set of nodes which is the case during extraction
1094  *  of a big mesh.
1095  */
1096 void MEDCoupling1SGTUMesh::renumberNodesInConn(const INTERP_KERNEL::HashMap<int,int>& newNodeNumbersO2N)
1097 {
1098   getNumberOfCells();//only to check that all is well defined.
1099   int *begPtr(_conn->getPointer());
1100   int nbElt(_conn->getNumberOfTuples());
1101   int *endPtr(begPtr+nbElt);
1102   for(int *it=begPtr;it!=endPtr;it++)
1103     {
1104       INTERP_KERNEL::HashMap<int,int>::const_iterator it2(newNodeNumbersO2N.find(*it));
1105       if(it2!=newNodeNumbersO2N.end())
1106         {
1107           *it=(*it2).second;
1108         }
1109       else
1110         {
1111           std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::renumberNodesInConn : At pos #" << std::distance(begPtr,it) << " of nodal connectivity value is " << *it << ". Not in map !";
1112           throw INTERP_KERNEL::Exception(oss.str().c_str());
1113         }
1114     }
1115   updateTime();
1116 }
1117
1118 /*!
1119  * Changes ids of nodes within the nodal connectivity arrays according to a permutation
1120  * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
1121  * This method is a generalization of shiftNodeNumbersInConn().
1122  *  \warning This method performs no check of validity of new ids. **Use it with care !**
1123  *  \param [in] newNodeNumbersO2N - a permutation array, of length \a
1124  *         this->getNumberOfNodes(), in "Old to New" mode. 
1125  *         See \ref numbering for more info on renumbering modes.
1126  *  \throw If the nodal connectivity of cells is not defined.
1127  */
1128 void MEDCoupling1SGTUMesh::renumberNodesInConn(const int *newNodeNumbersO2N)
1129 {
1130   getNumberOfCells();//only to check that all is well defined.
1131   _conn->transformWithIndArr(newNodeNumbersO2N,newNodeNumbersO2N+getNumberOfNodes());
1132   updateTime();
1133 }
1134
1135 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(const MEDCoupling1SGTUMesh *mesh1, const MEDCoupling1SGTUMesh *mesh2)
1136 {
1137   std::vector<const MEDCoupling1SGTUMesh *> tmp(2);
1138   tmp[0]=const_cast<MEDCoupling1SGTUMesh *>(mesh1); tmp[1]=const_cast<MEDCoupling1SGTUMesh *>(mesh2);
1139   return Merge1SGTUMeshes(tmp);
1140 }
1141
1142 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(std::vector<const MEDCoupling1SGTUMesh *>& a)
1143 {
1144   std::size_t sz=a.size();
1145   if(sz==0)
1146     return Merge1SGTUMeshesLL(a);
1147   for(std::size_t ii=0;ii<sz;ii++)
1148     if(!a[ii])
1149       {
1150         std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::Merge1SGTUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !";
1151         throw INTERP_KERNEL::Exception(oss.str().c_str());
1152       }
1153   const INTERP_KERNEL::CellModel *cm=&(a[0]->getCellModel());
1154   for(std::size_t ii=0;ii<sz;ii++)
1155     if(&(a[ii]->getCellModel())!=cm)
1156       throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : all items must have the same geo type !");
1157   std::vector< MCAuto<MEDCoupling1SGTUMesh> > bb(sz);
1158   std::vector< const MEDCoupling1SGTUMesh * > aa(sz);
1159   int spaceDim=-3;
1160   for(std::size_t i=0;i<sz && spaceDim==-3;i++)
1161     {
1162       const MEDCoupling1SGTUMesh *cur=a[i];
1163       const DataArrayDouble *coo=cur->getCoords();
1164       if(coo)
1165         spaceDim=coo->getNumberOfComponents();
1166     }
1167   if(spaceDim==-3)
1168     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : no spaceDim specified ! unable to perform merge !");
1169   for(std::size_t i=0;i<sz;i++)
1170     {
1171       bb[i]=a[i]->buildSetInstanceFromThis(spaceDim);
1172       aa[i]=bb[i];
1173     }
1174   return Merge1SGTUMeshesLL(aa);
1175 }
1176
1177 /*!
1178  * \throw If presence of a null instance in the input vector \a a.
1179  * \throw If a is empty
1180  */
1181 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords(std::vector<const MEDCoupling1SGTUMesh *>& a)
1182 {
1183   if(a.empty())
1184     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : input array must be NON EMPTY !");
1185   std::vector<const MEDCoupling1SGTUMesh *>::const_iterator it=a.begin();
1186   if(!(*it))
1187     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : null instance in the first element of input vector !");
1188   std::vector<const DataArrayInt *> ncs(a.size());
1189   (*it)->getNumberOfCells();//to check that all is OK
1190   const DataArrayDouble *coords=(*it)->getCoords();
1191   const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
1192   ncs[0]=(*it)->getNodalConnectivity();
1193   it++;
1194   for(int i=1;it!=a.end();i++,it++)
1195     {
1196       if(!(*it))
1197         throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : presence of a null instance in the input vector !");
1198       if(cm!=&((*it)->getCellModel()))
1199         throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !");
1200       (*it)->getNumberOfCells();//to check that all is OK
1201       ncs[i]=(*it)->getNodalConnectivity();
1202       if(coords!=(*it)->getCoords())
1203         throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : not lying on same coords !");
1204     }
1205   MCAuto<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh("merge",*cm));
1206   ret->setCoords(coords);
1207   ret->_conn=DataArrayInt::Aggregate(ncs);
1208   return ret.retn();
1209 }
1210
1211 /*!
1212  * Assume that all instances in \a a are non null. If null it leads to a crash. That's why this method is assigned to be low level (LL)
1213  */
1214 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesLL(std::vector<const MEDCoupling1SGTUMesh *>& a)
1215 {
1216   if(a.empty())
1217     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : input array must be NON EMPTY !");
1218   std::vector<const MEDCoupling1SGTUMesh *>::const_iterator it=a.begin();
1219   int nbOfCells=(*it)->getNumberOfCells();
1220   const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
1221   int nbNodesPerCell=(*it)->getNumberOfNodesPerCell();
1222   it++;
1223   for(;it!=a.end();it++)
1224     {
1225       if(cm!=&((*it)->getCellModel()))
1226         throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !");
1227       nbOfCells+=(*it)->getNumberOfCells();
1228     }
1229   std::vector<const MEDCouplingPointSet *> aps(a.size());
1230   std::copy(a.begin(),a.end(),aps.begin());
1231   MCAuto<DataArrayDouble> pts=MergeNodesArray(aps);
1232   MCAuto<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh("merge",*cm));
1233   ret->setCoords(pts);
1234   MCAuto<DataArrayInt> c=DataArrayInt::New();
1235   c->alloc(nbOfCells*nbNodesPerCell,1);
1236   int *cPtr=c->getPointer();
1237   int offset=0;
1238   for(it=a.begin();it!=a.end();it++)
1239     {
1240       int curConnLgth=(*it)->getNodalConnectivityLength();
1241       const int *curC=(*it)->_conn->begin();
1242       cPtr=std::transform(curC,curC+curConnLgth,cPtr,std::bind2nd(std::plus<int>(),offset));
1243       offset+=(*it)->getNumberOfNodes();
1244     }
1245   //
1246   ret->setNodalConnectivity(c);
1247   return ret.retn();
1248 }
1249
1250 MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const
1251 {
1252   int ncell=getNumberOfCells();
1253   MCAuto<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
1254   ret->setCoords(_coords);
1255   std::size_t nbOfElemsRet=std::distance(begin,end);
1256   const int *inConn=_conn->getConstPointer();
1257   int sz=getNumberOfNodesPerCell();
1258   MCAuto<DataArrayInt> connRet=DataArrayInt::New(); connRet->alloc((int)nbOfElemsRet*sz,1);
1259   int *connPtr=connRet->getPointer();
1260   for(const int *work=begin;work!=end;work++,connPtr+=sz)
1261     {
1262       if(*work>=0 && *work<ncell)
1263         std::copy(inConn+(work[0])*sz,inConn+(work[0]+1)*sz,connPtr);
1264       else
1265         {
1266           std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords : On pos #" << std::distance(begin,work) << " input cell id =" << *work << " should be in [0," << ncell << ") !";
1267           throw INTERP_KERNEL::Exception(oss.str().c_str());
1268         }
1269     }
1270   ret->_conn=connRet;
1271   ret->copyTinyInfoFrom(this);
1272   return ret.retn();
1273 }
1274
1275 MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoordsSlice(int start, int end, int step) const
1276 {
1277   int ncell=getNumberOfCells();
1278   int nbOfElemsRet=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoordsSlice : ");
1279   MCAuto<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
1280   ret->setCoords(_coords);
1281   const int *inConn=_conn->getConstPointer();
1282   int sz=getNumberOfNodesPerCell();
1283   MCAuto<DataArrayInt> connRet=DataArrayInt::New(); connRet->alloc((int)nbOfElemsRet*sz,1);
1284   int *connPtr=connRet->getPointer();
1285   int curId=start;
1286   for(int i=0;i<nbOfElemsRet;i++,connPtr+=sz,curId+=step)
1287     {
1288       if(curId>=0 && curId<ncell)
1289         std::copy(inConn+curId*sz,inConn+(curId+1)*sz,connPtr);
1290       else
1291         {
1292           std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoordsSlice : On pos #" << i << " input cell id =" << curId  << " should be in [0," << ncell << ") !";
1293           throw INTERP_KERNEL::Exception(oss.str().c_str());
1294         }
1295     }
1296   ret->_conn=connRet;
1297   ret->copyTinyInfoFrom(this);
1298   return ret.retn();
1299 }
1300
1301 void MEDCoupling1SGTUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const
1302 {
1303   int sz((int)nodeIdsInUse.size());
1304   for(const int *conn=_conn->begin();conn!=_conn->end();conn++)
1305     {
1306       if(*conn>=0 && *conn<sz)
1307        nodeIdsInUse[*conn]=true;
1308       else
1309         {
1310           std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeFetchedNodeIds : At pos #" << std::distance(_conn->begin(),conn) << " value is " << *conn << " must be in [0," << sz << ") !";
1311           throw INTERP_KERNEL::Exception(oss.str().c_str());
1312         }
1313     }
1314 }
1315
1316 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::buildSetInstanceFromThis(int spaceDim) const
1317 {
1318   MCAuto<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
1319   MCAuto<DataArrayInt> tmp1;
1320   const DataArrayInt *nodalConn(_conn);
1321   if(!nodalConn)
1322     {
1323       tmp1=DataArrayInt::New(); tmp1->alloc(0,1);
1324     }
1325   else
1326     tmp1=_conn;
1327   ret->_conn=tmp1;
1328   if(!_coords)
1329     {
1330       MCAuto<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim);
1331       ret->setCoords(coords);
1332     }
1333   else
1334     ret->setCoords(_coords);
1335   return ret.retn();
1336 }
1337
1338 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePol0()
1339 {
1340   int nbOfCells=getNumberOfCells();
1341   if(getCellModelEnum()!=INTERP_KERNEL::NORM_QUAD4)
1342     return DataArrayInt::Range(0,nbOfCells,1);
1343   MCAuto<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(2*3*nbOfCells,1);
1344   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(2*nbOfCells,1);
1345   const int *c(_conn->begin());
1346   int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1347   for(int i=0;i<nbOfCells;i++,c+=4,newConnPtr+=6,retPtr+=2)
1348     {
1349       newConnPtr[0]=c[0]; newConnPtr[1]=c[1]; newConnPtr[2]=c[2];
1350       newConnPtr[3]=c[0]; newConnPtr[4]=c[2]; newConnPtr[5]=c[3];
1351       retPtr[0]=i; retPtr[1]=i;
1352     }
1353   _conn=newConn;
1354   _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TRI3);
1355   updateTime();
1356   return ret.retn();
1357 }
1358
1359 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePol1()
1360 {
1361   int nbOfCells=getNumberOfCells();
1362   if(getCellModelEnum()!=INTERP_KERNEL::NORM_QUAD4)
1363     return DataArrayInt::Range(0,nbOfCells,1);
1364   MCAuto<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(2*3*nbOfCells,1);
1365   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(2*nbOfCells,1);
1366   const int *c(_conn->begin());
1367   int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1368   for(int i=0;i<nbOfCells;i++,c+=4,newConnPtr+=6,retPtr+=2)
1369     {
1370       newConnPtr[0]=c[0]; newConnPtr[1]=c[1]; newConnPtr[2]=c[3];
1371       newConnPtr[3]=c[1]; newConnPtr[4]=c[2]; newConnPtr[5]=c[3];
1372       retPtr[0]=i; retPtr[1]=i;
1373     }
1374   _conn=newConn;
1375   _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TRI3);
1376   updateTime();
1377   return ret.retn();
1378 }
1379
1380 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePlanarFace5()
1381 {
1382   int nbOfCells=getNumberOfCells();
1383   if(getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA8)
1384     return DataArrayInt::Range(0,nbOfCells,1);
1385   MCAuto<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(5*4*nbOfCells,1);
1386   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(5*nbOfCells,1);
1387   const int *c(_conn->begin());
1388   int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1389   for(int i=0;i<nbOfCells;i++,c+=8,newConnPtr+=20,retPtr+=5)
1390     {
1391       for(int j=0;j<20;j++)
1392         newConnPtr[j]=c[INTERP_KERNEL::SPLIT_NODES_5_WO[j]];
1393       retPtr[0]=i; retPtr[1]=i; retPtr[2]=i; retPtr[3]=i; retPtr[4]=i;
1394     }
1395   _conn=newConn;
1396   _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TETRA4);
1397   updateTime();
1398   return ret.retn();
1399 }
1400
1401 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePlanarFace6()
1402 {
1403   int nbOfCells=getNumberOfCells();
1404   if(getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA8)
1405     return DataArrayInt::Range(0,nbOfCells,1);
1406   MCAuto<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(6*4*nbOfCells,1);
1407   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(6*nbOfCells,1);
1408   const int *c(_conn->begin());
1409   int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1410   for(int i=0;i<nbOfCells;i++,c+=8,newConnPtr+=24,retPtr+=6)
1411     {
1412       for(int j=0;j<24;j++)
1413         newConnPtr[j]=c[INTERP_KERNEL::SPLIT_NODES_6_WO[j]];
1414       retPtr[0]=i; retPtr[1]=i; retPtr[2]=i; retPtr[3]=i; retPtr[4]=i; retPtr[5]=i;
1415     }
1416   _conn=newConn;
1417   _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TETRA4);
1418   updateTime();
1419   return ret.retn();
1420 }
1421
1422 void MEDCoupling1SGTUMesh::reprQuickOverview(std::ostream& stream) const
1423 {
1424   stream << "MEDCoupling1SGTUMesh C++ instance at " << this << ". Type=" << _cm->getRepr() << ". Name : \"" << getName() << "\".";
1425   stream << " Mesh dimension : " << getMeshDimension() << ".";
1426   if(!_coords)
1427     { stream << " No coordinates set !"; return ; }
1428   if(!_coords->isAllocated())
1429     { stream << " Coordinates set but not allocated !"; return ; }
1430   stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
1431   stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
1432   if(!(const DataArrayInt *)_conn)
1433     { stream << std::endl << "Nodal connectivity NOT set !"; return ; }
1434   if(_conn->isAllocated())
1435     {
1436       if(_conn->getNumberOfComponents()==1)
1437         stream << std::endl << "Number of cells : " << getNumberOfCells() << ".";
1438     }
1439 }
1440
1441 void MEDCoupling1SGTUMesh::checkFullyDefined() const
1442 {
1443   if(!((const DataArrayInt *)_conn) || !((const DataArrayDouble *)_coords))
1444     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFullyDefined : part of this is not fully defined.");
1445 }
1446
1447 /*!
1448  * First step of unserialization process.
1449  */
1450 bool MEDCoupling1SGTUMesh::isEmptyMesh(const std::vector<int>& tinyInfo) const
1451 {
1452   throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEmptyMesh : not implemented yet !");
1453 }
1454
1455 void MEDCoupling1SGTUMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const
1456 {
1457   int it,order;
1458   double time=getTime(it,order);
1459   tinyInfo.clear(); tinyInfoD.clear(); littleStrings.clear();
1460   //
1461   littleStrings.push_back(getName());
1462   littleStrings.push_back(getDescription());
1463   littleStrings.push_back(getTimeUnit());
1464   //
1465   std::vector<std::string> littleStrings2,littleStrings3;
1466   if((const DataArrayDouble *)_coords)
1467     _coords->getTinySerializationStrInformation(littleStrings2);
1468   if((const DataArrayInt *)_conn)
1469     _conn->getTinySerializationStrInformation(littleStrings3);
1470   int sz0((int)littleStrings2.size()),sz1((int)littleStrings3.size());
1471   littleStrings.insert(littleStrings.end(),littleStrings2.begin(),littleStrings2.end());
1472   littleStrings.insert(littleStrings.end(),littleStrings3.begin(),littleStrings3.end());
1473   //
1474   tinyInfo.push_back(getCellModelEnum());
1475   tinyInfo.push_back(it);
1476   tinyInfo.push_back(order);
1477   std::vector<int> tinyInfo2,tinyInfo3;
1478   if((const DataArrayDouble *)_coords)
1479     _coords->getTinySerializationIntInformation(tinyInfo2);
1480   if((const DataArrayInt *)_conn)
1481     _conn->getTinySerializationIntInformation(tinyInfo3);
1482   int sz2((int)tinyInfo2.size()),sz3((int)tinyInfo3.size());
1483   tinyInfo.push_back(sz0); tinyInfo.push_back(sz1); tinyInfo.push_back(sz2); tinyInfo.push_back(sz3);
1484   tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
1485   tinyInfo.insert(tinyInfo.end(),tinyInfo3.begin(),tinyInfo3.end());
1486   //
1487   tinyInfoD.push_back(time);
1488 }
1489
1490 void MEDCoupling1SGTUMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
1491 {
1492   std::vector<int> tinyInfo2(tinyInfo.begin()+7,tinyInfo.begin()+7+tinyInfo[5]);
1493   std::vector<int> tinyInfo1(tinyInfo.begin()+7+tinyInfo[5],tinyInfo.begin()+7+tinyInfo[5]+tinyInfo[6]);
1494   a1->resizeForUnserialization(tinyInfo1);
1495   a2->resizeForUnserialization(tinyInfo2);
1496 }
1497
1498 void MEDCoupling1SGTUMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const
1499 {
1500   int sz(0);
1501   if((const DataArrayInt *)_conn)
1502     if(_conn->isAllocated())
1503       sz=_conn->getNbOfElems();
1504   a1=DataArrayInt::New();
1505   a1->alloc(sz,1);
1506   if(sz!=0 && (const DataArrayInt *)_conn)
1507     std::copy(_conn->begin(),_conn->end(),a1->getPointer());
1508   sz=0;
1509   if((const DataArrayDouble *)_coords)
1510     if(_coords->isAllocated())
1511       sz=_coords->getNbOfElems();
1512   a2=DataArrayDouble::New();
1513   a2->alloc(sz,1);
1514   if(sz!=0 && (const DataArrayDouble *)_coords)
1515     std::copy(_coords->begin(),_coords->end(),a2->getPointer());
1516 }
1517
1518 void MEDCoupling1SGTUMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,
1519                                            const std::vector<std::string>& littleStrings)
1520 {
1521   INTERP_KERNEL::NormalizedCellType gt((INTERP_KERNEL::NormalizedCellType)tinyInfo[0]);
1522   _cm=&INTERP_KERNEL::CellModel::GetCellModel(gt);
1523   setName(littleStrings[0]);
1524   setDescription(littleStrings[1]);
1525   setTimeUnit(littleStrings[2]);
1526   setTime(tinyInfoD[0],tinyInfo[1],tinyInfo[2]);
1527   int sz0(tinyInfo[3]),sz1(tinyInfo[4]),sz2(tinyInfo[5]),sz3(tinyInfo[6]);
1528   //
1529   _coords=DataArrayDouble::New();
1530   std::vector<int> tinyInfo2(tinyInfo.begin()+7,tinyInfo.begin()+7+sz2);
1531   _coords->resizeForUnserialization(tinyInfo2);
1532   std::copy(a2->begin(),a2->end(),_coords->getPointer());
1533   _conn=DataArrayInt::New();
1534   std::vector<int> tinyInfo3(tinyInfo.begin()+7+sz2,tinyInfo.begin()+7+sz2+sz3);
1535   _conn->resizeForUnserialization(tinyInfo3);
1536   std::copy(a1->begin(),a1->end(),_conn->getPointer());
1537   std::vector<std::string> littleStrings2(littleStrings.begin()+3,littleStrings.begin()+3+sz0);
1538   _coords->finishUnserialization(tinyInfo2,littleStrings2);
1539   std::vector<std::string> littleStrings3(littleStrings.begin()+3+sz0,littleStrings.begin()+3+sz0+sz1);
1540   _conn->finishUnserialization(tinyInfo3,littleStrings3);
1541 }
1542
1543 /*!
1544  * Checks if \a this and \a other meshes are geometrically equivalent with high
1545  * probability, else an exception is thrown. The meshes are considered equivalent if
1546  * (1) meshes contain the same number of nodes and the same number of elements of the
1547  * same types (2) three cells of the two meshes (first, last and middle) are based
1548  * on coincident nodes (with a specified precision).
1549  *  \param [in] other - the mesh to compare with.
1550  *  \param [in] prec - the precision used to compare nodes of the two meshes.
1551  *  \throw If the two meshes do not match.
1552  */
1553 void MEDCoupling1SGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const
1554 {
1555   MEDCouplingPointSet::checkFastEquivalWith(other,prec);
1556   const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
1557   if(!otherC)
1558     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : Two meshes are not unstructured with single static geometric type !");
1559   const DataArrayInt *c1(_conn),*c2(otherC->_conn);
1560   if(c1==c2)
1561     return;
1562   if(!c1 || !c2)
1563     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !");
1564   if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
1565     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !");
1566   if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
1567     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !");
1568   if(c1->getHashCode()!=c2->getHashCode())
1569     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : nodal connectivity differs");
1570 }
1571
1572 MEDCouplingPointSet *MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const
1573 {
1574   if(!other)
1575     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : input other is null !");
1576   const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
1577   if(!otherC)
1578     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !");
1579   std::vector<const MEDCoupling1SGTUMesh *> ms(2);
1580   ms[0]=this;
1581   ms[1]=otherC;
1582   return Merge1SGTUMeshesOnSameCoords(ms);
1583 }
1584
1585 void MEDCoupling1SGTUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const
1586 {
1587   checkFullyDefined();
1588   int nbOfNodes=getNumberOfNodes();
1589   int *revNodalIndxPtr=(int *)malloc((nbOfNodes+1)*sizeof(int));
1590   revNodalIndx->useArray(revNodalIndxPtr,true,C_DEALLOC,nbOfNodes+1,1);
1591   std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
1592   const int *conn=_conn->begin();
1593   int nbOfCells=getNumberOfCells();
1594   int nbOfEltsInRevNodal=0;
1595   int nbOfNodesPerCell=getNumberOfNodesPerCell();
1596   for(int eltId=0;eltId<nbOfCells;eltId++)
1597     {
1598       for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1599         {
1600           if(conn[0]>=0 && conn[0]<nbOfNodes)
1601             {
1602               nbOfEltsInRevNodal++;
1603               revNodalIndxPtr[conn[0]+1]++;
1604             }
1605           else
1606             {
1607               std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !";
1608               throw INTERP_KERNEL::Exception(oss.str().c_str());
1609             }
1610         }
1611     }
1612   std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<int>());
1613   conn=_conn->begin();
1614   int *revNodalPtr=(int *)malloc((nbOfEltsInRevNodal)*sizeof(int));
1615   revNodal->useArray(revNodalPtr,true,C_DEALLOC,nbOfEltsInRevNodal,1);
1616   std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
1617   for(int eltId=0;eltId<nbOfCells;eltId++)
1618     {
1619       for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1620         {
1621           *std::find_if(revNodalPtr+revNodalIndxPtr[*conn],revNodalPtr+revNodalIndxPtr[*conn+1],std::bind2nd(std::equal_to<int>(),-1))=eltId;
1622         }
1623     }
1624 }
1625
1626 /*!
1627  * Use \a nodalConn array as nodal connectivity of \a this. The input \a nodalConn pointer can be null.
1628  */
1629 void MEDCoupling1SGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn)
1630 {
1631   if(nodalConn)
1632     nodalConn->incrRef();
1633   _conn=nodalConn;
1634   declareAsNew();
1635 }
1636
1637 /*!
1638  * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it.
1639  */
1640 DataArrayInt *MEDCoupling1SGTUMesh::getNodalConnectivity() const
1641 {
1642   const DataArrayInt *ret(_conn);
1643   return const_cast<DataArrayInt *>(ret);
1644 }
1645
1646 /*!
1647  * Allocates memory to store an estimation of the given number of cells. Closer is the estimation to the number of cells effectively inserted,
1648  * less will be the needs to realloc. If the number of cells to be inserted is not known simply put 0 to this parameter.
1649  * If a nodal connectivity previouly existed before the call of this method, it will be reset.
1650  *
1651  *  \param [in] nbOfCells - estimation of the number of cell \a this mesh will contain.
1652  */
1653 void MEDCoupling1SGTUMesh::allocateCells(int nbOfCells)
1654 {
1655   if(nbOfCells<0)
1656     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::allocateCells : the input number of cells should be >= 0 !");
1657   _conn=DataArrayInt::New();
1658   _conn->reserve(getNumberOfNodesPerCell()*nbOfCells);
1659   declareAsNew();
1660 }
1661
1662 /*!
1663  * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ).
1664  *
1665  * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add.
1666  * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
1667  * \throw If the length of the input nodal connectivity array of the cell to add is not equal to number of nodes per cell relative to the unique geometric type
1668  *        attached to \a this.
1669  * \thow If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
1670  */
1671 void MEDCoupling1SGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd)
1672 {
1673   int sz=(int)std::distance(nodalConnOfCellBg,nodalConnOfCellEnd);
1674   int ref=getNumberOfNodesPerCell();
1675   if(sz==ref)
1676     {
1677       DataArrayInt *c(_conn);
1678       if(c)
1679         c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd);
1680       else
1681         throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1SGTUMesh::allocateCells before !");
1682     }
1683   else
1684     {
1685       std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::insertNextCell : input nodal size (" << sz << ") does not match number of nodes per cell of this (";
1686       oss << ref << ") !";
1687       throw INTERP_KERNEL::Exception(oss.str().c_str());
1688     }
1689 }
1690
1691 /*!
1692  * This method builds the dual mesh of \a this and returns it.
1693  * 
1694  * \return MEDCoupling1SGTUMesh * - newly object created to be managed by the caller.
1695  * \throw If \a this is not a mesh containing only simplex cells.
1696  * \throw If \a this is not correctly allocated (coordinates and connectivities have to be correctly set !).
1697  * \throw If at least one node in \a this is orphan (without any simplex cell lying on it !)
1698  */
1699 MEDCoupling1GTUMesh *MEDCoupling1SGTUMesh::computeDualMesh() const
1700 {
1701   const INTERP_KERNEL::CellModel& cm(getCellModel());
1702   if(!cm.isSimplex())
1703     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh : this mesh is not a simplex mesh ! Please invoke simplexize of tetrahedrize on this before calling this method !");
1704   switch(getMeshDimension())
1705   {
1706     case 3:
1707       return computeDualMesh3D();
1708     case 2:
1709       return computeDualMesh2D();
1710     default:
1711       throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh : meshdimension must be in [2,3] !");
1712   }
1713 }
1714
1715 /*!
1716  * This method explode each NORM_HEXA8 cells in \a this into 6 NORM_QUAD4 cells and put the result into the MEDCoupling1SGTUMesh returned instance.
1717  * 
1718  * \return MEDCoupling1SGTUMesh * - a newly allocated instances (to be managed by the caller) storing the result of the explosion.
1719  * \throw If \a this is not a mesh containing only NORM_HEXA8 cells.
1720  * \throw If \a this is not properly allocated.
1721  */
1722 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::explodeEachHexa8To6Quad4() const
1723 {
1724   const INTERP_KERNEL::CellModel& cm(getCellModel());
1725   if(cm.getEnum()!=INTERP_KERNEL::NORM_HEXA8)
1726     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::explodeEachHexa8To6Quad4 : this method can be applied only on HEXA8 mesh !");
1727   int nbHexa8(getNumberOfCells());
1728   const int *inConnPtr(getNodalConnectivity()->begin());
1729   MCAuto<MEDCoupling1SGTUMesh> ret(MEDCoupling1SGTUMesh::New(getName(),INTERP_KERNEL::NORM_QUAD4));
1730   MCAuto<DataArrayInt> c(DataArrayInt::New()); c->alloc(nbHexa8*6*4,1);
1731   int *cPtr(c->getPointer());
1732   for(int i=0;i<nbHexa8;i++,inConnPtr+=8)
1733     {
1734       for(int j=0;j<6;j++,cPtr+=4)
1735         cm.fillSonCellNodalConnectivity(j,inConnPtr,cPtr);
1736     }
1737   ret->setCoords(getCoords());
1738   ret->setNodalConnectivity(c);
1739   return ret.retn();
1740 }
1741
1742 /*!
1743  * This method starts from an unstructured mesh that hides in reality a cartesian mesh.
1744  * If it is not the case, an exception will be thrown.
1745  * This method returns three objects : The cartesian mesh geometrically equivalent to \a this (within a precision of \a eps) and a permutation of cells
1746  * and a permutation of nodes.
1747  *
1748  * - this[cellPerm[i]]=ret[i]
1749  *
1750  * \param [out] cellPerm the permutation array of size \c this->getNumberOfCells()
1751  * \param [out] nodePerm the permutation array of size \c this->getNumberOfNodes()
1752  * \return MEDCouplingCMesh * - a newly allocated mesh that is the result of the structurization of \a this.
1753  */
1754 MEDCouplingCMesh *MEDCoupling1SGTUMesh::structurizeMe(DataArrayInt *& cellPerm, DataArrayInt *& nodePerm, double eps) const
1755 {
1756   checkConsistencyLight();
1757   int spaceDim(getSpaceDimension()),meshDim(getMeshDimension()),nbNodes(getNumberOfNodes());
1758   if(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(meshDim)!=getCellModelEnum())
1759     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::structurizeMe : the unique geo type in this is not compatible with the geometric type regarding mesh dimension !");
1760   MCAuto<MEDCouplingCMesh> cm(MEDCouplingCMesh::New());
1761   for(int i=0;i<spaceDim;i++)
1762     {
1763       std::vector<int> tmp(1,i);
1764       MCAuto<DataArrayDouble> elt(static_cast<DataArrayDouble*>(getCoords()->keepSelectedComponents(tmp)));
1765       elt=elt->getDifferentValues(eps);
1766       elt->sort(true);
1767       cm->setCoordsAt(i,elt);
1768     }
1769   if(nbNodes!=cm->getNumberOfNodes())
1770     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::structurizeMe : considering the number of nodes after split per components in space this can't be a cartesian mesh ! Maybe your epsilon parameter is invalid ?");
1771   try
1772   { cm->copyTinyInfoFrom(this); }
1773   catch(INTERP_KERNEL::Exception&) { }
1774   MCAuto<MEDCouplingUMesh> um(cm->buildUnstructured()),self(buildUnstructured());
1775   self->checkGeoEquivalWith(um,12,eps,cellPerm,nodePerm);
1776   return cm.retn();
1777 }
1778
1779 /// @cond INTERNAL
1780
1781 bool UpdateHexa8Cell(int validAxis, int neighId, const int *validConnQuad4NeighSide, int *allFacesNodalConn, int *myNeighbours)
1782 {
1783   static const int TAB[48]={
1784     0,1,2,3,4,5,6,7,//0
1785     4,7,6,5,0,3,2,1,//1
1786     0,3,7,4,1,2,6,5,//2
1787     4,0,3,7,5,1,2,6,//3
1788     5,1,0,4,6,2,3,7,//4
1789     3,7,4,0,2,6,5,1 //5
1790   };
1791   static const int TAB2[6]={0,0,3,3,3,3};
1792   if(myNeighbours[validAxis]==neighId && allFacesNodalConn[4*validAxis+0]==validConnQuad4NeighSide[TAB2[validAxis]])
1793     return true;
1794   int oldAxis((int)std::distance(myNeighbours,std::find(myNeighbours,myNeighbours+6,neighId)));
1795   std::size_t pos(std::distance(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS,std::find(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS,MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS+6,oldAxis)));
1796   std::size_t pos0(pos/2),pos1(pos%2);
1797   int oldAxisOpp(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS[2*pos0+(pos1+1)%2]);
1798   int oldConn[8],myConn2[8]={-1,-1,-1,-1,-1,-1,-1,-1},myConn[8],edgeConn[2],allFacesTmp[24],neighTmp[6];
1799   oldConn[0]=allFacesNodalConn[0]; oldConn[1]=allFacesNodalConn[1]; oldConn[2]=allFacesNodalConn[2]; oldConn[3]=allFacesNodalConn[3];
1800   oldConn[4]=allFacesNodalConn[4]; oldConn[5]=allFacesNodalConn[7]; oldConn[6]=allFacesNodalConn[6]; oldConn[7]=allFacesNodalConn[5];
1801   const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_HEXA8));
1802   for(int i=0;i<4;i++)
1803     myConn2[i]=validConnQuad4NeighSide[(4-i+TAB2[validAxis])%4];
1804   for(int i=0;i<4;i++)
1805     {
1806       int nodeId(myConn2[i]);//the node id for which the opposite one will be found
1807       bool found(false);
1808       INTERP_KERNEL::NormalizedCellType typeOfSon;
1809       for(int j=0;j<12 && !found;j++)
1810         {
1811           cm.fillSonEdgesNodalConnectivity3D(j,oldConn,-1,edgeConn,typeOfSon);
1812           if(edgeConn[0]==nodeId || edgeConn[1]==nodeId)
1813             {
1814               if(std::find(allFacesNodalConn+4*oldAxisOpp,allFacesNodalConn+4*oldAxisOpp+4,edgeConn[0]==nodeId?edgeConn[1]:edgeConn[0])!=allFacesNodalConn+4*oldAxisOpp+4)
1815                 {
1816                   myConn2[i+4]=edgeConn[0]==nodeId?edgeConn[1]:edgeConn[0];
1817                   found=true;
1818                 }
1819             }
1820         }
1821       if(!found)
1822         throw INTERP_KERNEL::Exception("UpdateHexa8Cell : Internal Error !");
1823     }
1824   const int *myTab(TAB+8*validAxis);
1825   for(int i=0;i<8;i++)
1826     myConn[i]=myConn2[myTab[i]];
1827   for(int i=0;i<6;i++)
1828     {
1829       cm.fillSonCellNodalConnectivity(i,myConn,allFacesTmp+4*i);
1830       std::set<int> s(allFacesTmp+4*i,allFacesTmp+4*i+4);
1831       bool found(false);
1832       for(int j=0;j<6 && !found;j++)
1833         {
1834           std::set<int> s1(allFacesNodalConn+4*j,allFacesNodalConn+4*j+4);
1835           if(s==s1)
1836             {
1837               neighTmp[i]=myNeighbours[j];
1838               found=true;
1839             }
1840         }
1841       if(!found)
1842         throw INTERP_KERNEL::Exception("UpdateHexa8Cell : Internal Error #2 !");
1843     }
1844   std::copy(allFacesTmp,allFacesTmp+24,allFacesNodalConn);
1845   std::copy(neighTmp,neighTmp+6,myNeighbours);
1846   return false;
1847 }
1848
1849 /// @endcond
1850
1851 /*!
1852  * This method expects the \a this contains NORM_HEXA8 cells only. This method will sort each cells in \a this so that their numbering was
1853  * homogeneous. If it succeeds the result of MEDCouplingUMesh::tetrahedrize will return a conform mesh.
1854  *
1855  * \return DataArrayInt * - a newly allocated array (to be managed by the caller) containing renumbered cell ids.
1856  *
1857  * \throw If \a this is not a mesh containing only NORM_HEXA8 cells.
1858  * \throw If \a this is not properly allocated.
1859  * \sa MEDCouplingUMesh::tetrahedrize, MEDCouplingUMesh::simplexize.
1860  */
1861 DataArrayInt *MEDCoupling1SGTUMesh::sortHexa8EachOther()
1862 {
1863   MCAuto<MEDCoupling1SGTUMesh> quads(explodeEachHexa8To6Quad4());//checks that only hexa8
1864   int nbHexa8(getNumberOfCells()),*cQuads(quads->getNodalConnectivity()->getPointer());
1865   MCAuto<DataArrayInt> neighOfQuads(DataArrayInt::New()); neighOfQuads->alloc(nbHexa8*6,1); neighOfQuads->fillWithValue(-1);
1866   int *ptNeigh(neighOfQuads->getPointer());
1867   {//neighOfQuads tells for each face of each Quad8 which cell (if!=-1) is connected to this face.
1868     MCAuto<MEDCouplingUMesh> quadsTmp(quads->buildUnstructured());
1869     MCAuto<DataArrayInt> ccSafe,cciSafe;
1870     DataArrayInt *cc(0),*cci(0);
1871     quadsTmp->findCommonCells(3,0,cc,cci);
1872     ccSafe=cc; cciSafe=cci;
1873     const int *ccPtr(ccSafe->begin()),nbOfPair(cci->getNumberOfTuples()-1);
1874     for(int i=0;i<nbOfPair;i++)
1875       { ptNeigh[ccPtr[2*i+0]]=ccPtr[2*i+1]/6; ptNeigh[ccPtr[2*i+1]]=ccPtr[2*i+0]/6; }
1876   }
1877   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
1878   std::vector<bool> fetched(nbHexa8,false);
1879   std::vector<bool>::iterator it(std::find(fetched.begin(),fetched.end(),false));
1880   while(it!=fetched.end())//it will turns as time as number of connected zones
1881     {
1882       int cellId((int)std::distance(fetched.begin(),it));//it is the seed of the connected zone.
1883       std::set<int> s; s.insert(cellId);//s contains already organized.
1884       while(!s.empty())
1885         {
1886           std::set<int> sNext;
1887           for(std::set<int>::const_iterator it0=s.begin();it0!=s.end();it0++)
1888             {
1889               fetched[*it0]=true;
1890               int *myNeighb(ptNeigh+6*(*it0));
1891               for(int i=0;i<6;i++)
1892                 {
1893                   if(myNeighb[i]!=-1 && !fetched[myNeighb[i]])
1894                     {
1895                       std::size_t pos(std::distance(HEXA8_FACE_PAIRS,std::find(HEXA8_FACE_PAIRS,HEXA8_FACE_PAIRS+6,i)));
1896                       std::size_t pos0(pos/2),pos1(pos%2);
1897                       if(!UpdateHexa8Cell(HEXA8_FACE_PAIRS[2*pos0+(pos1+1)%2],*it0,cQuads+6*4*(*it0)+4*i,cQuads+6*4*myNeighb[i],ptNeigh+6*myNeighb[i]))
1898                         ret->pushBackSilent(myNeighb[i]);
1899                       fetched[myNeighb[i]]=true;
1900                       sNext.insert(myNeighb[i]);
1901                     }
1902                 }
1903             }
1904           s=sNext;
1905         }
1906       it=std::find(fetched.begin(),fetched.end(),false);
1907     }
1908   if(!ret->empty())
1909     {
1910       int *conn(getNodalConnectivity()->getPointer());
1911       for(const int *pt=ret->begin();pt!=ret->end();pt++)
1912         {
1913           int cellId(*pt);
1914           conn[8*cellId+0]=cQuads[24*cellId+0]; conn[8*cellId+1]=cQuads[24*cellId+1]; conn[8*cellId+2]=cQuads[24*cellId+2]; conn[8*cellId+3]=cQuads[24*cellId+3];
1915           conn[8*cellId+4]=cQuads[24*cellId+4]; conn[8*cellId+5]=cQuads[24*cellId+7]; conn[8*cellId+6]=cQuads[24*cellId+6]; conn[8*cellId+7]=cQuads[24*cellId+5];
1916         }
1917       declareAsNew();
1918     }
1919   return ret.retn();
1920 }
1921
1922 MEDCoupling1DGTUMesh *MEDCoupling1SGTUMesh::computeDualMesh3D() const
1923 {
1924   static const int DUAL_TETRA_0[36]={
1925     4,1,0, 6,0,3, 7,3,1,
1926     4,0,1, 5,2,0, 8,1,2,
1927     6,3,0, 5,0,2, 9,2,3,
1928     7,1,3, 9,3,2, 8,2,1
1929   };
1930   static const int DUAL_TETRA_1[36]={
1931     8,4,10, 11,5,8, 10,7,11,
1932     9,4,8, 8,5,12, 12,6,9,
1933     10,4,9, 9,6,13, 13,7,10,
1934     12,5,11, 13,6,12, 11,7,13
1935   };
1936   static const int FACEID_NOT_SH_NODE[4]={2,3,1,0};
1937   if(getCellModelEnum()!=INTERP_KERNEL::NORM_TETRA4)
1938     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh3D : only TETRA4 supported !");
1939   checkFullyDefined();
1940   MCAuto<MEDCouplingUMesh> thisu(buildUnstructured());
1941   MCAuto<DataArrayInt> revNodArr(DataArrayInt::New()),revNodIArr(DataArrayInt::New());
1942   thisu->getReverseNodalConnectivity(revNodArr,revNodIArr);
1943   const int *revNod(revNodArr->begin()),*revNodI(revNodIArr->begin()),*nodal(_conn->begin());
1944   MCAuto<DataArrayInt> d1Arr(DataArrayInt::New()),di1Arr(DataArrayInt::New()),rd1Arr(DataArrayInt::New()),rdi1Arr(DataArrayInt::New());
1945   MCAuto<MEDCouplingUMesh> edges(thisu->explode3DMeshTo1D(d1Arr,di1Arr,rd1Arr,rdi1Arr));
1946   const int *d1(d1Arr->begin());
1947   MCAuto<DataArrayInt> d2Arr(DataArrayInt::New()),di2Arr(DataArrayInt::New()),rd2Arr(DataArrayInt::New()),rdi2Arr(DataArrayInt::New());
1948   MCAuto<MEDCouplingUMesh> faces(thisu->buildDescendingConnectivity(d2Arr,di2Arr,rd2Arr,rdi2Arr));  thisu=0;
1949   const int *d2(d2Arr->begin()),*rdi2(rdi2Arr->begin());
1950   MCAuto<DataArrayDouble> edgesBaryArr(edges->computeCellCenterOfMass()),facesBaryArr(faces->computeCellCenterOfMass()),baryArr(computeCellCenterOfMass());
1951   const int nbOfNodes(getNumberOfNodes()),offset0(nbOfNodes+faces->getNumberOfCells()),offset1(offset0+edges->getNumberOfCells());
1952   edges=0; faces=0;
1953   std::vector<const DataArrayDouble *> v(4); v[0]=getCoords(); v[1]=facesBaryArr; v[2]=edgesBaryArr; v[3]=baryArr;
1954   MCAuto<DataArrayDouble> zeArr(DataArrayDouble::Aggregate(v)); baryArr=0; edgesBaryArr=0; facesBaryArr=0;
1955   std::string name("DualOf_"); name+=getName();
1956   MCAuto<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(name,INTERP_KERNEL::NORM_POLYHED)); ret->setCoords(zeArr);
1957   MCAuto<DataArrayInt> cArr(DataArrayInt::New()),ciArr(DataArrayInt::New()); ciArr->alloc(nbOfNodes+1,1); ciArr->setIJ(0,0,0); cArr->alloc(0,1);
1958   for(int i=0;i<nbOfNodes;i++,revNodI++)
1959     {
1960       int nbOfCellsSharingNode(revNodI[1]-revNodI[0]);
1961       if(nbOfCellsSharingNode==0)
1962         {
1963           std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeDualMesh3D : Node #" << i << " is orphan !"; 
1964           throw INTERP_KERNEL::Exception(oss.str().c_str());
1965         }
1966       for(int j=0;j<nbOfCellsSharingNode;j++)
1967         {
1968           int curCellId(revNod[revNodI[0]+j]);
1969           const int *connOfCurCell(nodal+4*curCellId);
1970           std::size_t nodePosInCurCell(std::distance(connOfCurCell,std::find(connOfCurCell,connOfCurCell+4,i)));
1971           if(j!=0) cArr->pushBackSilent(-1);
1972           int tmp[14];
1973           //
1974           tmp[0]=d1[6*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+0]-4]+offset0; tmp[1]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+1]]+nbOfNodes;
1975           tmp[2]=curCellId+offset1; tmp[3]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+2]]+nbOfNodes;
1976           tmp[4]=-1;
1977           tmp[5]=d1[6*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+3]-4]+offset0; tmp[6]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+4]]+nbOfNodes;
1978           tmp[7]=curCellId+offset1; tmp[8]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+5]]+nbOfNodes;
1979           tmp[9]=-1;
1980           tmp[10]=d1[6*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+6]-4]+offset0; tmp[11]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+7]]+nbOfNodes;
1981           tmp[12]=curCellId+offset1; tmp[13]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+8]]+nbOfNodes;
1982           cArr->insertAtTheEnd(tmp,tmp+14);
1983           int kk(0);
1984           for(int k=0;k<4;k++)
1985             {
1986               if(FACEID_NOT_SH_NODE[nodePosInCurCell]!=k)
1987                 {
1988                   const int *faceId(d2+4*curCellId+k);
1989                   if(rdi2[*faceId+1]-rdi2[*faceId]==1)
1990                     {
1991                       int tmp2[5]; tmp2[0]=-1; tmp2[1]=i;
1992                       tmp2[2]=d1[6*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+0]-8]+offset0;
1993                       tmp2[3]=d2[4*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+1]-4]+nbOfNodes;
1994                       tmp2[4]=d1[6*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+2]-8]+offset0;
1995                       cArr->insertAtTheEnd(tmp2,tmp2+5);
1996                     }
1997                   kk++;
1998                 }
1999             }
2000         }
2001       ciArr->setIJ(i+1,0,cArr->getNumberOfTuples());
2002     }
2003   ret->setNodalConnectivity(cArr,ciArr);
2004   return ret.retn();
2005 }
2006
2007 MEDCoupling1DGTUMesh *MEDCoupling1SGTUMesh::computeDualMesh2D() const
2008 {
2009   static const int DUAL_TRI_0[6]={0,2, 1,0, 2,1};
2010   static const int DUAL_TRI_1[6]={-3,+5, +3,-4, +4,-5};
2011   static const int FACEID_NOT_SH_NODE[3]={1,2,0};
2012   if(getCellModelEnum()!=INTERP_KERNEL::NORM_TRI3)
2013     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh2D : only TRI3 supported !");
2014   checkFullyDefined();
2015   MCAuto<MEDCouplingUMesh> thisu(buildUnstructured());
2016   MCAuto<DataArrayInt> revNodArr(DataArrayInt::New()),revNodIArr(DataArrayInt::New());
2017   thisu->getReverseNodalConnectivity(revNodArr,revNodIArr);
2018   const int *revNod(revNodArr->begin()),*revNodI(revNodIArr->begin()),*nodal(_conn->begin());
2019   MCAuto<DataArrayInt> d2Arr(DataArrayInt::New()),di2Arr(DataArrayInt::New()),rd2Arr(DataArrayInt::New()),rdi2Arr(DataArrayInt::New());
2020   MCAuto<MEDCouplingUMesh> edges(thisu->buildDescendingConnectivity(d2Arr,di2Arr,rd2Arr,rdi2Arr));  thisu=0;
2021   const int *d2(d2Arr->begin()),*rdi2(rdi2Arr->begin());
2022   MCAuto<DataArrayDouble> edgesBaryArr(edges->computeCellCenterOfMass()),baryArr(computeCellCenterOfMass());
2023   const int nbOfNodes(getNumberOfNodes()),offset0(nbOfNodes+edges->getNumberOfCells());
2024   edges=0;
2025   std::vector<const DataArrayDouble *> v(3); v[0]=getCoords(); v[1]=edgesBaryArr; v[2]=baryArr;
2026   MCAuto<DataArrayDouble> zeArr(DataArrayDouble::Aggregate(v)); baryArr=0; edgesBaryArr=0;
2027   std::string name("DualOf_"); name+=getName();
2028   MCAuto<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(name,INTERP_KERNEL::NORM_POLYGON)); ret->setCoords(zeArr);
2029   MCAuto<DataArrayInt> cArr(DataArrayInt::New()),ciArr(DataArrayInt::New()); ciArr->alloc(nbOfNodes+1,1); ciArr->setIJ(0,0,0); cArr->alloc(0,1);
2030   for(int i=0;i<nbOfNodes;i++,revNodI++)
2031     {
2032       int nbOfCellsSharingNode(revNodI[1]-revNodI[0]);
2033       if(nbOfCellsSharingNode==0)
2034         {
2035           std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeDualMesh2D : Node #" << i << " is orphan !"; 
2036           throw INTERP_KERNEL::Exception(oss.str().c_str());
2037         }
2038       std::vector< std::vector<int> > polyg;
2039       for(int j=0;j<nbOfCellsSharingNode;j++)
2040         {
2041           int curCellId(revNod[revNodI[0]+j]);
2042           const int *connOfCurCell(nodal+3*curCellId);
2043           std::size_t nodePosInCurCell(std::distance(connOfCurCell,std::find(connOfCurCell,connOfCurCell+4,i)));
2044           std::vector<int> locV(3);
2045           locV[0]=d2[3*curCellId+DUAL_TRI_0[2*nodePosInCurCell+0]]+nbOfNodes; locV[1]=curCellId+offset0; locV[2]=d2[3*curCellId+DUAL_TRI_0[2*nodePosInCurCell+1]]+nbOfNodes;
2046           polyg.push_back(locV);
2047           int kk(0);
2048           for(int k=0;k<3;k++)
2049             {
2050               if(FACEID_NOT_SH_NODE[nodePosInCurCell]!=k)
2051                 {
2052                   const int *edgeId(d2+3*curCellId+k);
2053                   if(rdi2[*edgeId+1]-rdi2[*edgeId]==1)
2054                     {
2055                       std::vector<int> locV2(2);
2056                       int zeLocEdgeIdRel(DUAL_TRI_1[2*nodePosInCurCell+kk]);
2057                       if(zeLocEdgeIdRel>0)
2058                         {  locV2[0]=d2[3*curCellId+zeLocEdgeIdRel-3]+nbOfNodes;  locV2[1]=i; }
2059                       else
2060                         {  locV2[0]=i; locV2[1]=d2[3*curCellId-zeLocEdgeIdRel-3]+nbOfNodes; }
2061                       polyg.push_back(locV2);
2062                     }
2063                   kk++;
2064                 }
2065             }
2066         }
2067       std::vector<int> zePolyg(MEDCoupling1DGTUMesh::BuildAPolygonFromParts(polyg));
2068       cArr->insertAtTheEnd(zePolyg.begin(),zePolyg.end());
2069       ciArr->setIJ(i+1,0,cArr->getNumberOfTuples());
2070     }
2071   ret->setNodalConnectivity(cArr,ciArr);
2072   return ret.retn();
2073 }
2074
2075 /*!
2076  * This method aggregate the bbox of each cell and put it into bbox 
2077  *
2078  * \param [in] arcDetEps - a parameter specifying in case of 2D quadratic polygon cell the detection limit between linear and arc circle. (By default 1e-12)
2079  *                         For all other cases this input parameter is ignored.
2080  * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components.
2081  * 
2082  * \throw If \a this is not fully set (coordinates and connectivity).
2083  * \throw If a cell in \a this has no valid nodeId.
2084  */
2085 DataArrayDouble *MEDCoupling1SGTUMesh::getBoundingBoxForBBTree(double arcDetEps) const
2086 {
2087   int spaceDim(getSpaceDimension()),nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes()),nbOfNodesPerCell(getNumberOfNodesPerCell());
2088   MCAuto<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim);
2089   double *bbox(ret->getPointer());
2090   for(int i=0;i<nbOfCells*spaceDim;i++)
2091     {
2092       bbox[2*i]=std::numeric_limits<double>::max();
2093       bbox[2*i+1]=-std::numeric_limits<double>::max();
2094     }
2095   const double *coordsPtr(_coords->getConstPointer());
2096   const int *conn(_conn->getConstPointer());
2097   for(int i=0;i<nbOfCells;i++)
2098     {
2099       int kk(0);
2100       for(int j=0;j<nbOfNodesPerCell;j++,conn++)
2101         {
2102           int nodeId(*conn);
2103           if(nodeId>=0 && nodeId<nbOfNodes)
2104             {
2105               for(int k=0;k<spaceDim;k++)
2106                 {
2107                   bbox[2*spaceDim*i+2*k]=std::min(bbox[2*spaceDim*i+2*k],coordsPtr[spaceDim*nodeId+k]);
2108                   bbox[2*spaceDim*i+2*k+1]=std::max(bbox[2*spaceDim*i+2*k+1],coordsPtr[spaceDim*nodeId+k]);
2109                 }
2110               kk++;
2111             }
2112         }
2113       if(kk==0)
2114         {
2115           std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getBoundingBoxForBBTree : cell #" << i << " contains no valid nodeId !";
2116           throw INTERP_KERNEL::Exception(oss.str().c_str());
2117         }
2118     }
2119   return ret.retn();
2120 }
2121
2122 /*!
2123  * Returns the cell field giving for each cell in \a this its diameter. Diameter means the max length of all possible SEG2 in the cell.
2124  *
2125  * \return a new instance of field containing the result. The returned instance has to be deallocated by the caller.
2126  */
2127 MEDCouplingFieldDouble *MEDCoupling1SGTUMesh::computeDiameterField() const
2128 {
2129   checkFullyDefined();
2130   MCAuto<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME));
2131   int nbCells(getNumberOfCells());
2132   MCAuto<DataArrayDouble> arr(DataArrayDouble::New());
2133   arr->alloc(nbCells,1);
2134   INTERP_KERNEL::AutoCppPtr<INTERP_KERNEL::DiameterCalculator> dc(_cm->buildInstanceOfDiameterCalulator(getSpaceDimension()));
2135   dc->computeFor1SGTUMeshFrmt(nbCells,_conn->begin(),getCoords()->begin(),arr->getPointer());
2136   ret->setMesh(this);
2137   ret->setArray(arr);
2138   ret->setName("Diameter");
2139   return ret.retn();
2140 }
2141
2142 /*!
2143  * This method invert orientation of all cells in \a this. 
2144  * After calling this method the absolute value of measure of cells in \a this are the same than before calling.
2145  * This method only operates on the connectivity so coordinates are not touched at all.
2146  */
2147 void MEDCoupling1SGTUMesh::invertOrientationOfAllCells()
2148 {
2149   checkConsistencyOfConnectivity();
2150   INTERP_KERNEL::AutoCppPtr<INTERP_KERNEL::OrientationInverter> oi(INTERP_KERNEL::OrientationInverter::BuildInstanceFrom(getCellModelEnum()));
2151   int nbOfNodesPerCell((int)_cm->getNumberOfNodes()),nbCells(getNumberOfCells());
2152   int *conn(_conn->getPointer());
2153   for(int i=0;i<nbCells;i++)
2154     oi->operate(conn+i*nbOfNodesPerCell,conn+(i+1)*nbOfNodesPerCell);
2155   updateTime();
2156 }
2157
2158 //== 
2159
2160 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New()
2161 {
2162   return new MEDCoupling1DGTUMesh;
2163 }
2164
2165 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const std::string& name, INTERP_KERNEL::NormalizedCellType type)
2166 {
2167   if(type==INTERP_KERNEL::NORM_ERROR)
2168     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
2169   const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
2170   if(!cm.isDynamic())
2171     {
2172       std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::New : the input geometric type " << cm.getRepr() << " is static ! Only dynamic types are allowed here !";
2173       throw INTERP_KERNEL::Exception(oss.str().c_str());
2174     }
2175   return new MEDCoupling1DGTUMesh(name,cm);
2176 }
2177
2178 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh()
2179 {
2180 }
2181
2182 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const std::string& name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm)
2183 {
2184 }
2185
2186 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const MEDCoupling1DGTUMesh& other, bool recDeepCpy):MEDCoupling1GTUMesh(other,recDeepCpy),_conn_indx(other._conn_indx),_conn(other._conn)
2187 {
2188   if(recDeepCpy)
2189     {
2190       const DataArrayInt *c(other._conn);
2191       if(c)
2192         _conn=c->deepCopy();
2193       c=other._conn_indx;
2194       if(c)
2195         _conn_indx=c->deepCopy();
2196     }
2197 }
2198
2199 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::clone(bool recDeepCpy) const
2200 {
2201   return new MEDCoupling1DGTUMesh(*this,recDeepCpy);
2202 }
2203
2204 /*!
2205  * This method behaves mostly like MEDCoupling1DGTUMesh::deepCopy method, except that only nodal connectivity arrays are deeply copied.
2206  * The coordinates are shared between \a this and the returned instance.
2207  * 
2208  * \return MEDCoupling1DGTUMesh * - A new object instance holding the copy of \a this (deep for connectivity, shallow for coordiantes)
2209  * \sa MEDCoupling1DGTUMesh::deepCopy
2210  */
2211 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::deepCopyConnectivityOnly() const
2212 {
2213   checkConsistencyLight();
2214   MCAuto<MEDCoupling1DGTUMesh> ret(clone(false));
2215   MCAuto<DataArrayInt> c(_conn->deepCopy()),ci(_conn_indx->deepCopy());
2216   ret->setNodalConnectivity(c,ci);
2217   return ret.retn();
2218 }
2219
2220 void MEDCoupling1DGTUMesh::updateTime() const
2221 {
2222   MEDCoupling1GTUMesh::updateTime();
2223   const DataArrayInt *c(_conn);
2224   if(c)
2225     updateTimeWith(*c);
2226   c=_conn_indx;
2227   if(c)
2228     updateTimeWith(*c);
2229 }
2230
2231 std::size_t MEDCoupling1DGTUMesh::getHeapMemorySizeWithoutChildren() const
2232 {
2233   return MEDCoupling1GTUMesh::getHeapMemorySizeWithoutChildren();
2234 }
2235
2236 std::vector<const BigMemoryObject *> MEDCoupling1DGTUMesh::getDirectChildrenWithNull() const
2237 {
2238   std::vector<const BigMemoryObject *> ret(MEDCoupling1GTUMesh::getDirectChildrenWithNull());
2239   ret.push_back((const DataArrayInt *)_conn);
2240   ret.push_back((const DataArrayInt *)_conn_indx);
2241   return ret;
2242 }
2243
2244 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::deepCopy() const
2245 {
2246   return clone(true);
2247 }
2248
2249 bool MEDCoupling1DGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const
2250 {
2251   if(!other)
2252     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualIfNotWhy : input other pointer is null !");
2253   std::ostringstream oss; oss.precision(15);
2254   const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2255   if(!otherC)
2256     {
2257       reason="mesh given in input is not castable in MEDCoupling1DGTUMesh !";
2258       return false;
2259     }
2260   if(!MEDCoupling1GTUMesh::isEqualIfNotWhy(other,prec,reason))
2261     return false;
2262   const DataArrayInt *c1(_conn),*c2(otherC->_conn);
2263   if(c1==c2)
2264     return true;
2265   if(!c1 || !c2)
2266     {
2267       reason="in connectivity of single dynamic geometric type exactly one among this and other is null !";
2268       return false;
2269     }
2270   if(!c1->isEqualIfNotWhy(*c2,reason))
2271     {
2272       reason.insert(0,"Nodal connectivity DataArrayInt differs : ");
2273       return false;
2274     }
2275   c1=_conn_indx; c2=otherC->_conn_indx;
2276   if(c1==c2)
2277     return true;
2278   if(!c1 || !c2)
2279     {
2280       reason="in connectivity index of single dynamic geometric type exactly one among this and other is null !";
2281       return false;
2282     }
2283   if(!c1->isEqualIfNotWhy(*c2,reason))
2284     {
2285       reason.insert(0,"Nodal connectivity index DataArrayInt differs : ");
2286       return false;
2287     }
2288   return true;
2289 }
2290
2291 bool MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
2292 {
2293   if(!other)
2294     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
2295   const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2296   if(!otherC)
2297     return false;
2298   if(!MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(other,prec))
2299     return false;
2300   const DataArrayInt *c1(_conn),*c2(otherC->_conn);
2301   if(c1==c2)
2302     return true;
2303   if(!c1 || !c2)
2304     return false;
2305   if(!c1->isEqualWithoutConsideringStr(*c2))
2306     return false;
2307   return true;
2308   c1=_conn_indx; c2=otherC->_conn_indx;
2309   if(c1==c2)
2310     return true;
2311   if(!c1 || !c2)
2312     return false;
2313   if(!c1->isEqualWithoutConsideringStr(*c2))
2314     return false;
2315   return true;
2316 }
2317
2318 /*!
2319  * Checks if \a this and \a other meshes are geometrically equivalent with high
2320  * probability, else an exception is thrown. The meshes are considered equivalent if
2321  * (1) meshes contain the same number of nodes and the same number of elements of the
2322  * same types (2) three cells of the two meshes (first, last and middle) are based
2323  * on coincident nodes (with a specified precision).
2324  *  \param [in] other - the mesh to compare with.
2325  *  \param [in] prec - the precision used to compare nodes of the two meshes.
2326  *  \throw If the two meshes do not match.
2327  */
2328 void MEDCoupling1DGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const
2329 {
2330   MEDCouplingPointSet::checkFastEquivalWith(other,prec);
2331   const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2332   if(!otherC)
2333     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : Two meshes are not unstructured with single dynamic geometric type !");
2334   const DataArrayInt *c1(_conn),*c2(otherC->_conn);
2335   if(c1!=c2)
2336     {
2337       if(!c1 || !c2)
2338         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !");
2339       if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
2340         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !");
2341       if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
2342         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !");
2343       if(c1->getHashCode()!=c2->getHashCode())
2344         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity differs");
2345     }
2346   c1=_conn_indx; c2=otherC->_conn_indx;
2347   if(c1!=c2)
2348     {
2349       if(!c1 || !c2)
2350         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity index only in one of the 2 meshes !");
2351       if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
2352         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, only one is allocated !");
2353       if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
2354         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, must have 1 and only 1 component !");
2355       if(c1->getHashCode()!=c2->getHashCode())
2356         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity index differs");
2357     }
2358 }
2359
2360 void MEDCoupling1DGTUMesh::checkConsistencyOfConnectivity() const
2361 {
2362   const DataArrayInt *c1(_conn);
2363   if(c1)
2364     {
2365       if(c1->getNumberOfComponents()!=1)
2366         throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !");
2367       if(c1->getInfoOnComponent(0)!="")
2368         throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !");
2369       c1->checkAllocated();
2370     }
2371   else
2372     throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !");
2373   //
2374   int sz2=_conn->getNumberOfTuples();
2375   c1=_conn_indx;
2376   if(c1)
2377     {
2378       if(c1->getNumberOfComponents()!=1)
2379         throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to be with number of components set to one !");
2380       c1->checkAllocated();
2381       if(c1->getNumberOfTuples()<1)
2382         throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have a a size of 1 at least !");
2383       if(c1->getInfoOnComponent(0)!="")
2384         throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have no info on its single component !");
2385       int f=c1->front(),ll=c1->back();
2386       if(f<0 || (sz2>0 && f>=sz2))
2387         {
2388           std::ostringstream oss; oss << "Nodal connectivity index array first value (" << f << ") is expected to be exactly in [0," << sz2 << ") !";
2389           throw INTERP_KERNEL::Exception(oss.str().c_str());
2390         }
2391       if(ll<0 || ll>sz2)
2392         {
2393           std::ostringstream oss; oss << "Nodal connectivity index array last value (" << ll << ") is expected to be exactly in [0," << sz2 << "] !";
2394           throw INTERP_KERNEL::Exception(oss.str().c_str());
2395         }
2396       if(f>ll)
2397         {
2398           std::ostringstream oss; oss << "Nodal connectivity index array looks very bad (not increasing monotonic) because front (" << f << ") is greater that back (" << ll << ") !";
2399           throw INTERP_KERNEL::Exception(oss.str().c_str());
2400         }
2401     }
2402   else
2403     throw INTERP_KERNEL::Exception("Nodal connectivity index array not defined !");
2404   int szOfC1Exp=_conn_indx->back();
2405   if(sz2<szOfC1Exp)
2406     {
2407       std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::checkConsistencyOfConnectivity : The expected length of nodal connectivity array regarding index is " << szOfC1Exp << " but the actual size of it is " << c1->getNumberOfTuples() << " !";
2408       throw INTERP_KERNEL::Exception(oss.str().c_str());
2409     }
2410 }
2411
2412 /*!
2413  * If \a this pass this method, you are sure that connectivity arrays are not null, with exactly one component, no name, no component name, allocated.
2414  * In addition you are sure that the length of nodal connectivity index array is bigger than or equal to one.
2415  * In addition you are also sure that length of nodal connectivity is coherent with the content of the last value in the index array.
2416  */
2417 void MEDCoupling1DGTUMesh::checkConsistencyLight() const
2418 {
2419   MEDCouplingPointSet::checkConsistencyLight();
2420   checkConsistencyOfConnectivity();
2421 }
2422
2423 void MEDCoupling1DGTUMesh::checkConsistency(double eps) const
2424 {
2425   checkConsistencyLight();
2426   const DataArrayInt *c1(_conn),*c2(_conn_indx);
2427   if(!c2->isMonotonic(true))
2428     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkConsistency : the nodal connectivity index is expected to be increasing monotinic !");
2429   //
2430   int nbOfTuples=c1->getNumberOfTuples();
2431   int nbOfNodes=getNumberOfNodes();
2432   const int *w(c1->begin());
2433   for(int i=0;i<nbOfTuples;i++,w++)
2434     {
2435       if(*w==-1) continue;
2436       if(*w<0 || *w>=nbOfNodes)
2437         {
2438           std::ostringstream oss; oss << "At pos #" << i << " of nodal connectivity array references to node id #" << *w << " must be in [0," << nbOfNodes << ") !";
2439           throw INTERP_KERNEL::Exception(oss.str().c_str());
2440         }
2441     }
2442 }
2443
2444 std::size_t MEDCoupling1DGTUMesh::getNumberOfCells() const
2445 {
2446   checkConsistencyOfConnectivity();//do not remove
2447   return _conn_indx->getNumberOfTuples()-1;
2448 }
2449
2450 /*!
2451  * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
2452  * For each cell in \b this the number of nodes constituting cell is computed.
2453  * For each polyhedron cell, the sum of the number of nodes of each face constituting polyhedron cell is returned.
2454  * So for pohyhedrons some nodes can be counted several times in the returned result.
2455  * 
2456  * \return a newly allocated array
2457  */
2458 DataArrayInt *MEDCoupling1DGTUMesh::computeNbOfNodesPerCell() const
2459 {
2460   checkConsistencyLight();
2461   _conn_indx->checkMonotonic(true);
2462   if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2463     return _conn_indx->deltaShiftIndex();
2464   // for polyhedrons
2465   int nbOfCells=_conn_indx->getNumberOfTuples()-1;
2466   MCAuto<DataArrayInt> ret=DataArrayInt::New();
2467   ret->alloc(nbOfCells,1);
2468   int *retPtr=ret->getPointer();
2469   const int *ci=_conn_indx->begin(),*c=_conn->begin();
2470   for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2471     *retPtr=ci[1]-ci[0]-std::count(c+ci[0],c+ci[1],-1);
2472   return ret.retn();
2473 }
2474
2475 /*!
2476  * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
2477  * For each cell in \b this the number of faces constituting (entity of dimension this->getMeshDimension()-1) cell is computed.
2478  * 
2479  * \return a newly allocated array
2480  */
2481 DataArrayInt *MEDCoupling1DGTUMesh::computeNbOfFacesPerCell() const
2482 {
2483   checkConsistencyLight();
2484   _conn_indx->checkMonotonic(true);
2485   if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED && getCellModelEnum()!=INTERP_KERNEL::NORM_QPOLYG)
2486     return _conn_indx->deltaShiftIndex();
2487   if(getCellModelEnum()==INTERP_KERNEL::NORM_QPOLYG)
2488     {
2489       MCAuto<DataArrayInt> ret=_conn_indx->deltaShiftIndex();
2490       ret->applyDivideBy(2);
2491       return ret.retn();
2492     }
2493   // for polyhedrons
2494   int nbOfCells=_conn_indx->getNumberOfTuples()-1;
2495   MCAuto<DataArrayInt> ret=DataArrayInt::New();
2496   ret->alloc(nbOfCells,1);
2497   int *retPtr=ret->getPointer();
2498   const int *ci=_conn_indx->begin(),*c=_conn->begin();
2499   for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2500     *retPtr=std::count(c+ci[0],c+ci[1],-1)+1;
2501   return ret.retn();
2502 }
2503
2504 /*!
2505  * This method computes effective number of nodes per cell. That is to say nodes appearing several times in nodal connectivity of a cell,
2506  * will be counted only once here whereas it will be counted several times in MEDCoupling1DGTUMesh::computeNbOfNodesPerCell method.
2507  *
2508  * \return DataArrayInt * - new object to be deallocated by the caller.
2509  * \sa MEDCoupling1DGTUMesh::computeNbOfNodesPerCell
2510  */
2511 DataArrayInt *MEDCoupling1DGTUMesh::computeEffectiveNbOfNodesPerCell() const
2512 {
2513   checkConsistencyLight();
2514   _conn_indx->checkMonotonic(true);
2515   int nbOfCells(_conn_indx->getNumberOfTuples()-1);
2516   MCAuto<DataArrayInt> ret=DataArrayInt::New();
2517   ret->alloc(nbOfCells,1);
2518   int *retPtr(ret->getPointer());
2519   const int *ci(_conn_indx->begin()),*c(_conn->begin());
2520   if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2521     {
2522       for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2523         {
2524           std::set<int> s(c+ci[0],c+ci[1]);
2525           *retPtr=(int)s.size();
2526         }
2527     }
2528   else
2529     {
2530       for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2531         {
2532           std::set<int> s(c+ci[0],c+ci[1]); s.erase(-1);
2533           *retPtr=(int)s.size();
2534         }
2535     }
2536   return ret.retn();
2537 }
2538
2539 void MEDCoupling1DGTUMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
2540 {
2541   int nbOfCells(getNumberOfCells());//performs checks
2542   if(cellId>=0 && cellId<nbOfCells)
2543     {
2544       int strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0);
2545       int nbOfNodes=stp-strt;
2546       if(nbOfNodes<0)
2547         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::getNodeIdsOfCell : the index array is invalid ! Should be increasing monotonic !");
2548       conn.resize(nbOfNodes);
2549       std::copy(_conn->begin()+strt,_conn->begin()+stp,conn.begin());
2550     }
2551   else
2552     {
2553       std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !";
2554       throw INTERP_KERNEL::Exception(oss.str().c_str());
2555     }
2556 }
2557
2558 int MEDCoupling1DGTUMesh::getNumberOfNodesInCell(int cellId) const
2559 {
2560   int nbOfCells(getNumberOfCells());//performs checks
2561   if(cellId>=0 && cellId<nbOfCells)
2562     {
2563       const int *conn(_conn->begin());
2564       int strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0);
2565       return stp-strt-std::count(conn+strt,conn+stp,-1);
2566     }
2567   else
2568     {
2569       std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNumberOfNodesInCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !";
2570       throw INTERP_KERNEL::Exception(oss.str().c_str());
2571     }
2572 }
2573
2574 std::string MEDCoupling1DGTUMesh::simpleRepr() const
2575 {
2576   static const char msg0[]="No coordinates specified !";
2577   std::ostringstream ret;
2578   ret << "Single dynamic geometic type (" << _cm->getRepr() << ") unstructured mesh with name : \"" << getName() << "\"\n";
2579   ret << "Description of mesh : \"" << getDescription() << "\"\n";
2580   int tmpp1,tmpp2;
2581   double tt=getTime(tmpp1,tmpp2);
2582   ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
2583   ret << "Iteration : " << tmpp1  << " Order : " << tmpp2 << "\n";
2584   ret << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : ";
2585   if(_coords!=0)
2586     {
2587       const int spaceDim=getSpaceDimension();
2588       ret << spaceDim << "\nInfo attached on space dimension : ";
2589       for(int i=0;i<spaceDim;i++)
2590         ret << "\"" << _coords->getInfoOnComponent(i) << "\" ";
2591       ret << "\n";
2592     }
2593   else
2594     ret << msg0 << "\n";
2595   ret << "Number of nodes : ";
2596   if(_coords!=0)
2597     ret << getNumberOfNodes() << "\n";
2598   else
2599     ret << msg0 << "\n";
2600   ret << "Number of cells : ";
2601   bool isOK=true;
2602   try { checkConsistencyLight(); } catch(INTERP_KERNEL::Exception& /* e */)
2603   {
2604       ret << "Nodal connectivity arrays are not set or badly set !\n";
2605       isOK=false;
2606   }
2607   if(isOK)
2608     ret << getNumberOfCells() << "\n";
2609   ret << "Cell type : " << _cm->getRepr() << "\n";
2610   return ret.str();
2611 }
2612
2613 std::string MEDCoupling1DGTUMesh::advancedRepr() const
2614 {
2615   std::ostringstream ret;
2616   ret << simpleRepr();
2617   ret << "\nCoordinates array : \n___________________\n\n";
2618   if(_coords)
2619     _coords->reprWithoutNameStream(ret);
2620   else
2621     ret << "No array set !\n";
2622   ret << "\n\nNodal Connectivity : \n____________________\n\n";
2623   //
2624   bool isOK=true;
2625   try { checkConsistency(); } catch(INTERP_KERNEL::Exception& /* e */)
2626   {
2627       ret << "Nodal connectivity arrays are not set or badly set !\n";
2628       isOK=false;
2629   }
2630   if(!isOK)
2631     return ret.str();
2632   int nbOfCells=getNumberOfCells();
2633   const int *ci=_conn_indx->begin(),*c=_conn->begin();
2634   for(int i=0;i<nbOfCells;i++,ci++)
2635     {
2636       ret << "Cell #" << i << " : ";
2637       std::copy(c+ci[0],c+ci[1],std::ostream_iterator<int>(ret," "));
2638       ret << "\n";
2639     }
2640   return ret.str();
2641 }
2642
2643 DataArrayDouble *MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell() const
2644 {
2645   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2646   int spaceDim=getSpaceDimension();
2647   int nbOfCells=getNumberOfCells();//checkConsistencyLight()
2648   int nbOfNodes=getNumberOfNodes();
2649   ret->alloc(nbOfCells,spaceDim);
2650   double *ptToFill=ret->getPointer();
2651   const double *coor=_coords->begin();
2652   const int *nodal=_conn->begin(),*nodali=_conn_indx->begin();
2653   nodal+=nodali[0];
2654   if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2655     {
2656       for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
2657         {
2658           std::fill(ptToFill,ptToFill+spaceDim,0.);
2659           if(nodali[0]<nodali[1])// >= to avoid division by 0.
2660             {
2661               for(int j=nodali[0];j<nodali[1];j++,nodal++)
2662                 {
2663                   if(*nodal>=0 && *nodal<nbOfNodes)
2664                     std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
2665                   else
2666                     {
2667                       std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," <<   nbOfNodes << ") !";
2668                       throw INTERP_KERNEL::Exception(oss.str().c_str());
2669                     }
2670                   std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./(nodali[1]-nodali[0])));
2671                 }
2672             }
2673           else
2674             {
2675               std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : at cell #" << i << " the nodal index array is invalid !";
2676               throw INTERP_KERNEL::Exception(oss.str().c_str());
2677             }
2678         }
2679     }
2680   else
2681     {
2682       for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
2683         {
2684           std::fill(ptToFill,ptToFill+spaceDim,0.);
2685           if(nodali[0]<nodali[1])// >= to avoid division by 0.
2686             {
2687               int nbOfNod=0;
2688               for(int j=nodali[0];j<nodali[1];j++,nodal++)
2689                 {
2690                   if(*nodal==-1) continue;
2691                   if(*nodal>=0 && *nodal<nbOfNodes)
2692                     {
2693                       std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
2694                       nbOfNod++;
2695                     }
2696                   else
2697                     {
2698                       std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," <<   nbOfNodes << ") !";
2699                       throw INTERP_KERNEL::Exception(oss.str().c_str());
2700                     }
2701                 }
2702               if(nbOfNod!=0)
2703                 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./nbOfNod));
2704               else
2705                 {
2706                   std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : no nodes in cell #" << i << " !";
2707                   throw INTERP_KERNEL::Exception(oss.str().c_str());
2708                 }
2709             }
2710           else
2711             {
2712               std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron)  : at cell #" << i << " the nodal index array is invalid !";
2713               throw INTERP_KERNEL::Exception(oss.str().c_str());
2714             }
2715         }
2716     }
2717   return ret.retn();
2718 }
2719
2720 void MEDCoupling1DGTUMesh::renumberCells(const int *old2NewBg, bool check)
2721 {
2722   int nbCells=getNumberOfCells();
2723   MCAuto<DataArrayInt> o2n=DataArrayInt::New();
2724   o2n->useArray(old2NewBg,false,C_DEALLOC,nbCells,1);
2725   if(check)
2726     o2n=o2n->checkAndPreparePermutation();
2727   //
2728   const int *o2nPtr=o2n->getPointer();
2729   const int *conn=_conn->begin(),*conni=_conn_indx->begin();
2730   MCAuto<DataArrayInt> newConn=DataArrayInt::New();
2731   MCAuto<DataArrayInt> newConnI=DataArrayInt::New();
2732   newConn->alloc(_conn->getNumberOfTuples(),1); newConnI->alloc(nbCells,1);
2733   newConn->copyStringInfoFrom(*_conn); newConnI->copyStringInfoFrom(*_conn_indx);
2734   //
2735   int *newC=newConn->getPointer(),*newCI=newConnI->getPointer();
2736   for(int i=0;i<nbCells;i++)
2737     {
2738       int newPos=o2nPtr[i];
2739       int sz=conni[i+1]-conni[i];
2740       if(sz>=0)
2741         newCI[newPos]=sz;
2742       else
2743         {
2744           std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberCells : the index nodal array is invalid for cell #" << i << " !";
2745           throw INTERP_KERNEL::Exception(oss.str().c_str());
2746         }
2747     }
2748   newConnI->computeOffsetsFull(); newCI=newConnI->getPointer();
2749   //
2750   for(int i=0;i<nbCells;i++,conni++)
2751     {
2752       int newp=o2nPtr[i];
2753       std::copy(conn+conni[0],conn+conni[1],newC+newCI[newp]);
2754     }
2755   _conn=newConn;
2756   _conn_indx=newConnI;
2757 }
2758
2759 MEDCouplingMesh *MEDCoupling1DGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
2760 {
2761   if(other->getType()!=SINGLE_DYNAMIC_GEO_TYPE_UNSTRUCTURED)
2762     throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single dynamic geo type each other !");
2763   const MEDCoupling1DGTUMesh *otherC=static_cast<const MEDCoupling1DGTUMesh *>(other);
2764   return Merge1DGTUMeshes(this,otherC);
2765 }
2766
2767 MEDCouplingUMesh *MEDCoupling1DGTUMesh::buildUnstructured() const
2768 {
2769   MCAuto<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName(),getMeshDimension());
2770   ret->setCoords(getCoords());
2771   const int *nodalConn=_conn->begin(),*nodalConnI=_conn_indx->begin();
2772   int nbCells=getNumberOfCells();//checkConsistencyLight
2773   int geoType=(int)getCellModelEnum();
2774   MCAuto<DataArrayInt> c=DataArrayInt::New(); c->alloc(nbCells+_conn->getNumberOfTuples(),1);
2775   MCAuto<DataArrayInt> cI=DataArrayInt::New(); cI->alloc(nbCells+1);
2776   int *cPtr=c->getPointer(),*ciPtr=cI->getPointer();
2777   ciPtr[0]=0;
2778   for(int i=0;i<nbCells;i++,ciPtr++)
2779     {
2780       int sz=nodalConnI[i+1]-nodalConnI[i];
2781       if(sz>=0)
2782         {
2783           *cPtr++=geoType;
2784           cPtr=std::copy(nodalConn+nodalConnI[i],nodalConn+nodalConnI[i+1],cPtr);
2785           ciPtr[1]=ciPtr[0]+sz+1;
2786         }
2787       else
2788         {
2789           std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::buildUnstructured : Invalid for nodal index for cell #" << i << " !";
2790           throw INTERP_KERNEL::Exception(oss.str().c_str());
2791         }
2792     }
2793   ret->setConnectivity(c,cI,true);
2794   try
2795   { ret->copyTinyInfoFrom(this); }
2796   catch(INTERP_KERNEL::Exception&) { }
2797   return ret.retn();
2798 }
2799
2800 /*!
2801  * Do nothing for the moment, because there is no policy that allows to split polygons, polyhedrons ... into simplexes
2802  */
2803 DataArrayInt *MEDCoupling1DGTUMesh::simplexize(int policy)
2804 {
2805   int nbOfCells=getNumberOfCells();
2806   MCAuto<DataArrayInt> ret=DataArrayInt::New();
2807   ret->alloc(nbOfCells,1);
2808   ret->iota(0);
2809   return ret.retn();
2810 }
2811
2812 void MEDCoupling1DGTUMesh::reprQuickOverview(std::ostream& stream) const
2813 {
2814   stream << "MEDCoupling1DGTUMesh C++ instance at " << this << ". Type=" << _cm->getRepr() << ". Name : \"" << getName() << "\".";
2815   stream << " Mesh dimension : " << getMeshDimension() << ".";
2816   if(!_coords)
2817     { stream << " No coordinates set !"; return ; }
2818   if(!_coords->isAllocated())
2819     { stream << " Coordinates set but not allocated !"; return ; }
2820   stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
2821   stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
2822   bool isOK=true;
2823   try { checkConsistencyLight(); } catch(INTERP_KERNEL::Exception&  /* e */)
2824   {
2825       stream << std::endl << "Nodal connectivity NOT set properly !\n";
2826       isOK=false;
2827   }
2828   if(isOK)
2829     stream << std::endl << "Number of cells : " << getNumberOfCells() << ".";
2830 }
2831
2832 void MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other)
2833 {
2834   if(!other)
2835     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is null !");
2836   const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2837   if(!otherC)
2838     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1DGTUMesh instance !");
2839   setNodalConnectivity(otherC->getNodalConnectivity(),otherC->getNodalConnectivityIndex());
2840 }
2841
2842 MEDCouplingPointSet *MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const
2843 {
2844   if(!other)
2845     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : input other is null !");
2846   const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2847   if(!otherC)
2848     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !");
2849   std::vector<const MEDCoupling1DGTUMesh *> ms(2);
2850   ms[0]=this;
2851   ms[1]=otherC;
2852   return Merge1DGTUMeshesOnSameCoords(ms);
2853 }
2854
2855 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const
2856 {
2857   checkConsistencyLight();
2858   MCAuto<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
2859   ret->setCoords(_coords);
2860   DataArrayInt *c=0,*ci=0;
2861   MEDCouplingUMesh::ExtractFromIndexedArrays(begin,end,_conn,_conn_indx,c,ci);
2862   MCAuto<DataArrayInt> cSafe(c),ciSafe(ci);
2863   ret->setNodalConnectivity(c,ci);
2864   return ret.retn();
2865 }
2866
2867 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoordsSlice(int start, int end, int step) const
2868 {
2869   checkConsistencyLight();
2870   MCAuto<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
2871   ret->setCoords(_coords);
2872   DataArrayInt *c=0,*ci=0;
2873   MEDCouplingUMesh::ExtractFromIndexedArraysSlice(start,end,step,_conn,_conn_indx,c,ci);
2874   MCAuto<DataArrayInt> cSafe(c),ciSafe(ci);
2875   ret->setNodalConnectivity(c,ci);
2876   return ret.retn();
2877 }
2878
2879 void MEDCoupling1DGTUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const
2880 {
2881   checkConsistency();
2882   int sz((int)nodeIdsInUse.size());
2883   for(const int *conn=_conn->begin();conn!=_conn->end();conn++)
2884     {
2885       if(*conn>=0 && *conn<sz)
2886         nodeIdsInUse[*conn]=true;
2887       else
2888         {
2889           if(*conn!=-1)
2890             {
2891               std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeNodeIdsAlg : At pos #" << std::distance(_conn->begin(),conn) << " value is " << *conn << " must be in [0," << sz << ") !";
2892               throw INTERP_KERNEL::Exception(oss.str().c_str());
2893             }
2894         }
2895     }
2896 }
2897
2898 void MEDCoupling1DGTUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const
2899 {
2900   checkFullyDefined();
2901   int nbOfNodes=getNumberOfNodes();
2902   int *revNodalIndxPtr=(int *)malloc((nbOfNodes+1)*sizeof(int));
2903   revNodalIndx->useArray(revNodalIndxPtr,true,C_DEALLOC,nbOfNodes+1,1);
2904   std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
2905   const int *conn=_conn->begin(),*conni=_conn_indx->begin();
2906   int nbOfCells=getNumberOfCells();
2907   int nbOfEltsInRevNodal=0;
2908   for(int eltId=0;eltId<nbOfCells;eltId++)
2909     {
2910       int nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
2911       if(nbOfNodesPerCell>=0)
2912         {
2913           for(int j=0;j<nbOfNodesPerCell;j++)
2914             {
2915               int nodeId=conn[conni[eltId]+j];
2916               if(nodeId==-1) continue;            
2917               if(nodeId>=0 && nodeId<nbOfNodes)
2918                 {
2919                   nbOfEltsInRevNodal++;
2920                   revNodalIndxPtr[nodeId+1]++;
2921                 }
2922               else
2923                 {
2924                   std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !";
2925                   throw INTERP_KERNEL::Exception(oss.str().c_str());
2926                 }
2927             }
2928         }
2929       else
2930         {
2931           std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << "nodal connectivity is invalid !";
2932           throw INTERP_KERNEL::Exception(oss.str().c_str());
2933         }
2934     }
2935   std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<int>());
2936   conn=_conn->begin();
2937   int *revNodalPtr=(int *)malloc((nbOfEltsInRevNodal)*sizeof(int));
2938   revNodal->useArray(revNodalPtr,true,C_DEALLOC,nbOfEltsInRevNodal,1);
2939   std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
2940   for(int eltId=0;eltId<nbOfCells;eltId++)
2941     {
2942       int nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
2943       for(int j=0;j<nbOfNodesPerCell;j++)
2944         {
2945           int nodeId=conn[conni[eltId]+j];
2946           if(nodeId!=-1)
2947             *std::find_if(revNodalPtr+revNodalIndxPtr[nodeId],revNodalPtr+revNodalIndxPtr[nodeId+1],std::bind2nd(std::equal_to<int>(),-1))=eltId;
2948         }
2949     }
2950 }
2951
2952 void MEDCoupling1DGTUMesh::checkFullyDefined() const
2953 {
2954   if(!((const DataArrayInt *)_conn) || !((const DataArrayInt *)_conn_indx) || !((const DataArrayDouble *)_coords))
2955     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFullyDefined : part of this is not fully defined.");
2956 }
2957
2958 bool MEDCoupling1DGTUMesh::isEmptyMesh(const std::vector<int>& tinyInfo) const
2959 {
2960   throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEmptyMesh : not implemented yet !");
2961 }
2962
2963 void MEDCoupling1DGTUMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const
2964 {
2965   int it,order;
2966   double time=getTime(it,order);
2967   tinyInfo.clear(); tinyInfoD.clear(); littleStrings.clear();
2968   //
2969   littleStrings.push_back(getName());
2970   littleStrings.push_back(getDescription());
2971   littleStrings.push_back(getTimeUnit());
2972   //
2973   std::vector<std::string> littleStrings2,littleStrings3,littleStrings4;
2974   if((const DataArrayDouble *)_coords)
2975     _coords->getTinySerializationStrInformation(littleStrings2);
2976   if((const DataArrayInt *)_conn)
2977     _conn->getTinySerializationStrInformation(littleStrings3);
2978   if((const DataArrayInt *)_conn_indx)
2979     _conn_indx->getTinySerializationStrInformation(littleStrings4);
2980   int sz0((int)littleStrings2.size()),sz1((int)littleStrings3.size()),sz2((int)littleStrings4.size());
2981   littleStrings.insert(littleStrings.end(),littleStrings2.begin(),littleStrings2.end());
2982   littleStrings.insert(littleStrings.end(),littleStrings3.begin(),littleStrings3.end());
2983   littleStrings.insert(littleStrings.end(),littleStrings4.begin(),littleStrings4.end());
2984   //
2985   tinyInfo.push_back(getCellModelEnum());
2986   tinyInfo.push_back(it);
2987   tinyInfo.push_back(order);
2988   std::vector<int> tinyInfo2,tinyInfo3,tinyInfo4;
2989   if((const DataArrayDouble *)_coords)
2990     _coords->getTinySerializationIntInformation(tinyInfo2);
2991   if((const DataArrayInt *)_conn)
2992     _conn->getTinySerializationIntInformation(tinyInfo3);
2993   if((const DataArrayInt *)_conn_indx)
2994     _conn_indx->getTinySerializationIntInformation(tinyInfo4);
2995   int sz3((int)tinyInfo2.size()),sz4((int)tinyInfo3.size()),sz5((int)tinyInfo4.size());
2996   tinyInfo.push_back(sz0); tinyInfo.push_back(sz1); tinyInfo.push_back(sz2); tinyInfo.push_back(sz3); tinyInfo.push_back(sz4);  tinyInfo.push_back(sz5);
2997   tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
2998   tinyInfo.insert(tinyInfo.end(),tinyInfo3.begin(),tinyInfo3.end());
2999   tinyInfo.insert(tinyInfo.end(),tinyInfo4.begin(),tinyInfo4.end());
3000   //
3001   tinyInfoD.push_back(time);
3002 }
3003
3004 void MEDCoupling1DGTUMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
3005 {
3006   std::vector<int> tinyInfo2(tinyInfo.begin()+9,tinyInfo.begin()+9+tinyInfo[6]);
3007   std::vector<int> tinyInfo1(tinyInfo.begin()+9+tinyInfo[6],tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7]);
3008   std::vector<int> tinyInfo12(tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7],tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7]+tinyInfo[8]);
3009   MCAuto<DataArrayInt> p1(DataArrayInt::New()); p1->resizeForUnserialization(tinyInfo1);
3010   MCAuto<DataArrayInt> p2(DataArrayInt::New()); p2->resizeForUnserialization(tinyInfo12);
3011   std::vector<const DataArrayInt *> v(2); v[0]=p1; v[1]=p2;
3012   p2=DataArrayInt::Aggregate(v);
3013   a2->resizeForUnserialization(tinyInfo2);
3014   a1->alloc(p2->getNbOfElems(),1);
3015 }
3016
3017 void MEDCoupling1DGTUMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const
3018 {
3019   int sz(0);
3020   if((const DataArrayInt *)_conn)
3021     if(_conn->isAllocated())
3022       sz=_conn->getNbOfElems();
3023   if((const DataArrayInt *)_conn_indx)
3024     if(_conn_indx->isAllocated())
3025       sz+=_conn_indx->getNbOfElems();
3026   a1=DataArrayInt::New();
3027   a1->alloc(sz,1);
3028   int *work(a1->getPointer());
3029   if(sz!=0 && (const DataArrayInt *)_conn)
3030     work=std::copy(_conn->begin(),_conn->end(),a1->getPointer());
3031   if(sz!=0 && (const DataArrayInt *)_conn_indx)
3032     std::copy(_conn_indx->begin(),_conn_indx->end(),work);
3033   sz=0;
3034   if((const DataArrayDouble *)_coords)
3035     if(_coords->isAllocated())
3036       sz=_coords->getNbOfElems();
3037   a2=DataArrayDouble::New();
3038   a2->alloc(sz,1);
3039   if(sz!=0 && (const DataArrayDouble *)_coords)
3040     std::copy(_coords->begin(),_coords->end(),a2->getPointer());
3041 }
3042
3043 void MEDCoupling1DGTUMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,
3044                                            const std::vector<std::string>& littleStrings)
3045 {
3046   INTERP_KERNEL::NormalizedCellType gt((INTERP_KERNEL::NormalizedCellType)tinyInfo[0]);
3047   _cm=&INTERP_KERNEL::CellModel::GetCellModel(gt);
3048   setName(littleStrings[0]);
3049   setDescription(littleStrings[1]);
3050   setTimeUnit(littleStrings[2]);
3051   setTime(tinyInfoD[0],tinyInfo[1],tinyInfo[2]);
3052   int sz0(tinyInfo[3]),sz1(tinyInfo[4]),sz2(tinyInfo[5]),sz3(tinyInfo[6]),sz4(tinyInfo[7]),sz5(tinyInfo[8]);
3053   //
3054   _coords=DataArrayDouble::New();
3055   std::vector<int> tinyInfo2(tinyInfo.begin()+9,tinyInfo.begin()+9+sz3);
3056   _coords->resizeForUnserialization(tinyInfo2);
3057   std::copy(a2->begin(),a2->end(),_coords->getPointer());
3058   _conn=DataArrayInt::New();
3059   std::vector<int> tinyInfo3(tinyInfo.begin()+9+sz3,tinyInfo.begin()+9+sz3+sz4);
3060   _conn->resizeForUnserialization(tinyInfo3);
3061   std::copy(a1->begin(),a1->begin()+_conn->getNbOfElems(),_conn->getPointer());
3062   _conn_indx=DataArrayInt::New();
3063   std::vector<int> tinyInfo4(tinyInfo.begin()+9+sz3+sz4,tinyInfo.begin()+9+sz3+sz4+sz5);
3064   _conn_indx->resizeForUnserialization(tinyInfo4);
3065   std::copy(a1->begin()+_conn->getNbOfElems(),a1->end(),_conn_indx->getPointer());
3066   std::vector<std::string> littleStrings2(littleStrings.begin()+3,littleStrings.begin()+3+sz0);
3067   _coords->finishUnserialization(tinyInfo2,littleStrings2);
3068   std::vector<std::string> littleStrings3(littleStrings.begin()+3+sz0,littleStrings.begin()+3+sz0+sz1);
3069   _conn->finishUnserialization(tinyInfo3,littleStrings3);
3070   std::vector<std::string> littleStrings4(littleStrings.begin()+3+sz0+sz1,littleStrings.begin()+3+sz0+sz1+sz2);
3071   _conn_indx->finishUnserialization(tinyInfo4,littleStrings4);
3072 }
3073
3074 /*!
3075  * Finds nodes not used in any cell and returns an array giving a new id to every node
3076  * by excluding the unused nodes, for which the array holds -1. The result array is
3077  * a mapping in "Old to New" mode.
3078  *  \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
3079  *  \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a
3080  *          this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
3081  *          if the node is unused or a new id else. The caller is to delete this
3082  *          array using decrRef() as it is no more needed.
3083  *  \throw If the coordinates array is not set.
3084  *  \throw If the nodal connectivity of cells is not defined.
3085  *  \throw If the nodal connectivity includes an invalid id.
3086  *  \sa MEDCoupling1DGTUMesh::getNodeIdsInUse, areAllNodesFetched
3087  */
3088 DataArrayInt *MEDCoupling1DGTUMesh::computeFetchedNodeIds() const
3089 {
3090   checkConsistency();
3091   int nbNodes(getNumberOfNodes());
3092   std::vector<bool> fetchedNodes(nbNodes,false);
3093   computeNodeIdsAlg(fetchedNodes);
3094   int sz((int)std::count(fetchedNodes.begin(),fetchedNodes.end(),true));
3095   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
3096   int *retPtr(ret->getPointer());
3097   for(int i=0;i<nbNodes;i++)
3098     if(fetchedNodes[i])
3099       *retPtr++=i;
3100   return ret.retn();
3101 }
3102
3103 /*!
3104  * Finds nodes not used in any cell and returns an array giving a new id to every node
3105  * by excluding the unused nodes, for which the array holds -1. The result array is
3106  * a mapping in "Old to New" mode. 
3107  *  \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
3108  *  \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a
3109  *          this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
3110  *          if the node is unused or a new id else. The caller is to delete this
3111  *          array using decrRef() as it is no more needed.  
3112  *  \throw If the coordinates array is not set.
3113  *  \throw If the nodal connectivity of cells is not defined.
3114  *  \throw If the nodal connectivity includes an invalid id.
3115  *  \sa MEDCoupling1DGTUMesh::computeFetchedNodeIds, areAllNodesFetched
3116  */
3117 DataArrayInt *MEDCoupling1DGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const
3118 {
3119   nbrOfNodesInUse=-1;
3120   int nbOfNodes=getNumberOfNodes();
3121   int nbOfCells=getNumberOfCells();//checkConsistencyLight
3122   MCAuto<DataArrayInt> ret=DataArrayInt::New();
3123   ret->alloc(nbOfNodes,1);
3124   int *traducer=ret->getPointer();
3125   std::fill(traducer,traducer+nbOfNodes,-1);
3126   const int *conn=_conn->begin(),*conni(_conn_indx->begin());
3127   for(int i=0;i<nbOfCells;i++,conni++)
3128     {
3129       int nbNodesPerCell=conni[1]-conni[0];
3130       for(int j=0;j<nbNodesPerCell;j++)
3131         {
3132           int nodeId=conn[conni[0]+j];
3133           if(nodeId==-1) continue;
3134           if(nodeId>=0 && nodeId<nbOfNodes)
3135             traducer[nodeId]=1;
3136           else
3137             {
3138               std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsInUse : In cell #" << i  << " presence of node id " <<  nodeId << " not in [0," << nbOfNodes << ") !";
3139               throw INTERP_KERNEL::Exception(oss.str().c_str());
3140             }
3141         }
3142     }
3143   nbrOfNodesInUse=(int)std::count(traducer,traducer+nbOfNodes,1);
3144   std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
3145   return ret.retn();
3146 }
3147
3148 /*!
3149  * This method renumbers only nodal connectivity in \a this. The renumbering is only an offset applied. So this method is a specialization of
3150  * \a renumberNodesInConn. \b WARNING, this method does not check that the resulting node ids in the nodal connectivity is in a valid range !
3151  *
3152  * \param [in] offset - specifies the offset to be applied on each element of connectivity.
3153  *
3154  * \sa renumberNodesInConn
3155  */
3156 void MEDCoupling1DGTUMesh::renumberNodesWithOffsetInConn(int offset)
3157 {
3158   getNumberOfCells();//only to check that all is well defined.
3159   //
3160   int nbOfTuples(_conn->getNumberOfTuples());
3161   int *pt(_conn->getPointer());
3162   for(int i=0;i<nbOfTuples;i++,pt++)
3163     {
3164       if(*pt==-1) continue;
3165       *pt+=offset;
3166     }
3167   //
3168   updateTime();
3169 }
3170
3171 /*!
3172  *  Same than renumberNodesInConn(const int *) except that here the format of old-to-new traducer is using map instead
3173  *  of array. This method is dedicated for renumbering from a big set of nodes the a tiny set of nodes which is the case during extraction
3174  *  of a big mesh.
3175  */
3176 void MEDCoupling1DGTUMesh::renumberNodesInConn(const INTERP_KERNEL::HashMap<int,int>& newNodeNumbersO2N)
3177 {
3178   getNumberOfCells();//only to check that all is well defined.
3179   //
3180   int nbElemsIn(getNumberOfNodes()),nbOfTuples(_conn->getNumberOfTuples());
3181   int *pt(_conn->getPointer());
3182   for(int i=0;i<nbOfTuples;i++,pt++)
3183     {
3184       if(*pt==-1) continue;
3185       if(*pt>=0 && *pt<nbElemsIn)
3186         {
3187           INTERP_KERNEL::HashMap<int,int>::const_iterator it(newNodeNumbersO2N.find(*pt));
3188           if(it!=newNodeNumbersO2N.end())
3189             *pt=(*it).second;
3190           else
3191             {
3192               std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberNodesInConn : At pos #" << i << " of connectivity, node id is " << *pt << ". Not in keys of input map !";
3193               throw INTERP_KERNEL::Exception(oss.str().c_str());
3194             }
3195         }
3196       else
3197         {
3198           std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberNodesInConn : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn;
3199           throw INTERP_KERNEL::Exception(oss.str().c_str());
3200         }
3201     }
3202   //
3203   updateTime();
3204 }
3205
3206 /*!
3207  * Changes ids of nodes within the nodal connectivity arrays according to a permutation
3208  * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
3209  * This method is a generalization of shiftNodeNumbersInConn().
3210  *  \warning This method performs no check of validity of new ids. **Use it with care !**
3211  *  \param [in] newNodeNumbersO2N - a permutation array, of length \a
3212  *         this->getNumberOfNodes(), in "Old to New" mode. 
3213  *         See \ref numbering for more info on renumbering modes.
3214  *  \throw If the nodal connectivity of cells is not defined.
3215  */
3216 void MEDCoupling1DGTUMesh::renumberNodesInConn(const int *newNodeNumbersO2N)
3217 {
3218   getNumberOfCells();//only to check that all is well defined.
3219   //
3220   int nbElemsIn(getNumberOfNodes()),nbOfTuples(_conn->getNumberOfTuples());
3221   int *pt(_conn->getPointer());
3222   for(int i=0;i<nbOfTuples;i++,pt++)
3223     {
3224       if(*pt==-1) continue;
3225       if(*pt>=0 && *pt<nbElemsIn)
3226         *pt=newNodeNumbersO2N[*pt];
3227       else
3228         {
3229           std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberNodesInConn : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn;
3230           throw INTERP_KERNEL::Exception(oss.str().c_str());
3231         }
3232     }
3233   //
3234   updateTime();
3235 }
3236
3237 /*!
3238  * Keeps from \a this only cells which constituing point id are in the ids specified by [\a begin,\a end).
3239  * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
3240  * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not.
3241  * If \a fullyIn is true only cells whose ids are \b fully contained in [\a begin,\a end) tab will be kept.
3242  *
3243  * \param [in] begin input start of array of node ids.
3244  * \param [in] end input end of array of node ids.
3245  * \param [in] fullyIn input that specifies if all node ids must be in [\a begin,\a end) array to consider cell to be in.
3246  * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end.
3247  */
3248 void MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const
3249 {
3250   int nbOfCells=getNumberOfCells();
3251   MCAuto<DataArrayInt> cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1);
3252   int tmp=-1;
3253   int sz=_conn->getMaxValue(tmp); sz=std::max(sz,0)+1;
3254   std::vector<bool> fastFinder(sz,false);
3255   for(const int *work=begin;work!=end;work++)
3256     if(*work>=0 && *work<sz)
3257       fastFinder[*work]=true;
3258   const int *conn=_conn->begin(),*conni=_conn_indx->begin();
3259   for(int i=0;i<nbOfCells;i++,conni++)
3260     {
3261       int ref=0,nbOfHit=0;
3262       int nbNodesPerCell=conni[1]-conni[0];
3263       if(nbNodesPerCell>=0)
3264         {
3265           for(int j=0;j<nbNodesPerCell;j++)
3266             {
3267               int nodeId=conn[conni[0]+j];
3268               if(nodeId>=0)
3269                 {
3270                   ref++;
3271                   if(fastFinder[nodeId])
3272                     nbOfHit++;
3273                 }
3274             }
3275         }
3276       else
3277         {
3278           std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds : invalid index array for cell #" << i << " !";
3279           throw INTERP_KERNEL::Exception(oss.str().c_str());
3280         }
3281       if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn))
3282         cellIdsKept->pushBackSilent(i);
3283     }
3284   cellIdsKeptArr=cellIdsKept.retn();
3285 }
3286
3287 void MEDCoupling1DGTUMesh::allocateCells(int nbOfCells)
3288 {
3289   if(nbOfCells<0)
3290     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::allocateCells : the input number of cells should be >= 0 !");
3291   _conn=DataArrayInt::New();
3292   _conn->reserve(nbOfCells*3);
3293   _conn_indx=DataArrayInt::New();
3294   _conn_indx->reserve(nbOfCells+1); _conn_indx->pushBackSilent(0);
3295   declareAsNew();
3296 }
3297
3298 /*!
3299  * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ).
3300  *
3301  * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add.
3302  * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
3303  * \throw If the length of the input nodal connectivity array of the cell to add is not equal to number of nodes per cell relative to the unique geometric type
3304  *        attached to \a this.
3305  * \thow If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
3306  */
3307 void MEDCoupling1DGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd)
3308 {
3309   int sz=(int)std::distance(nodalConnOfCellBg,nodalConnOfCellEnd);
3310   DataArrayInt *c(_conn),*c2(_conn_indx);
3311   if(c && c2)
3312     {
3313       int pos=c2->back();
3314       if(pos==c->getNumberOfTuples())
3315         {
3316           c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd);
3317           c2->pushBackSilent(pos+sz);
3318         }
3319       else
3320         {
3321           std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::insertNextCell : The nodal index array (end=" << pos << ") mismatches with nodal array (length=" << c->getNumberOfTuples() << ") !";
3322           throw INTERP_KERNEL::Exception(oss.str().c_str());
3323         }
3324     }
3325   else
3326     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1DGTUMesh::allocateCells before !");
3327 }
3328
3329 void MEDCoupling1DGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn, DataArrayInt *nodalConnIndex)
3330 {
3331   if(nodalConn)
3332     nodalConn->incrRef();
3333   _conn=nodalConn;
3334   if(nodalConnIndex)
3335     nodalConnIndex->incrRef();
3336   _conn_indx=nodalConnIndex;
3337   declareAsNew();
3338 }
3339
3340 /*!
3341  * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it.
3342  */
3343 DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivity() const
3344 {
3345   const DataArrayInt *ret(_conn);
3346   return const_cast<DataArrayInt *>(ret);
3347 }
3348
3349 /*!
3350  * \return DataArrayInt * - the internal reference to the nodal connectivity index. The caller is not reponsible to deallocate it.
3351  */
3352 DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivityIndex() const
3353 {
3354   const DataArrayInt *ret(_conn_indx);
3355   return const_cast<DataArrayInt *>(ret);
3356 }
3357
3358 /*!
3359  * See the definition of the nodal connectivity pack \ref MEDCoupling1DGTUMesh::isPacked "here".
3360  * This method tries to build a new instance geometrically equivalent to \a this, by limiting at most the number of new object (nodal connectivity).
3361  * Geometrically the returned mesh is equal to \a this. So if \a this is already packed, the return value is a shallow copy of \a this.
3362  *
3363  * Whatever the status of pack of \a this, the coordinates array of the returned newly created instance is the same than those in \a this.
3364  * 
3365  * \param [out] isShallowCpyOfNodalConnn - tells if the returned instance share the same pair of nodal connectivity arrays (true) or if nodal
3366  *              connectivity arrays are different (false)
3367  * \return a new object to be managed by the caller.
3368  * 
3369  * \sa MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity, MEDCoupling1DGTUMesh::isPacked
3370  */
3371 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::copyWithNodalConnectivityPacked(bool& isShallowCpyOfNodalConnn) const
3372 {
3373   MCAuto<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
3374   DataArrayInt *nc=0,*nci=0;
3375   isShallowCpyOfNodalConnn=retrievePackedNodalConnectivity(nc,nci);
3376   MCAuto<DataArrayInt> ncs(nc),ncis(nci);
3377   ret->_conn=ncs; ret->_conn_indx=ncis;
3378   ret->setCoords(getCoords());
3379   return ret.retn();
3380 }
3381
3382 /*!
3383  * This method allows to compute, if needed, the packed nodal connectivity pair.
3384  * Indeed, it is possible to store in \a this a nodal connectivity array bigger than ranges convered by nodal connectivity index array.
3385  * It is typically the case when nodalConnIndx starts with an id greater than 0, and finishes with id less than number of tuples in \c this->_conn.
3386  * 
3387  * If \a this looks packed (the front of nodal connectivity index equal to 0 and back of connectivity index equal to number of tuple of nodal connectivity array)
3388  * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
3389  *
3390  * If nodal connectivity index points to a subpart of nodal connectivity index the packed pair of arrays will be computed (new objects) and returned and false
3391  * will be returned.
3392  * 
3393  * This method return 3 elements.
3394  * \param [out] nodalConn - a pointer that can be equal to \a this->_conn if true is returned (general case). Whatever the value of return parameter
3395  *                          this pointer can be seen as a new object, that is to managed by the caller.
3396  * \param [out] nodalConnIndx - a pointer that can be equal to \a this->_conn_indx if true is returned (general case). Whatever the value of return parameter
3397  *                              this pointer can be seen as a new object, that is to managed by the caller.
3398  * \return bool - an indication of the content of the 2 output parameters. If true, \a this looks packed (general case), if true, \a this is not packed then
3399  * output parameters are newly created objects.
3400  *
3401  * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkConsistencyLight test
3402  */
3403 bool MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity(DataArrayInt *&nodalConn, DataArrayInt *&nodalConnIndx) const
3404 {
3405   if(isPacked())//performs the checkConsistencyLight
3406     {
3407       const DataArrayInt *c0(_conn),*c1(_conn_indx);
3408       nodalConn=const_cast<DataArrayInt *>(c0); nodalConnIndx=const_cast<DataArrayInt *>(c1);
3409       nodalConn->incrRef(); nodalConnIndx->incrRef();
3410       return true;
3411     }
3412   int bg=_conn_indx->front(),end=_conn_indx->back();
3413   MCAuto<DataArrayInt> nc(_conn->selectByTupleIdSafeSlice(bg,end,1));
3414   MCAuto<DataArrayInt> nci(_conn_indx->deepCopy());
3415   nci->applyLin(1,-bg);
3416   nodalConn=nc.retn(); nodalConnIndx=nci.retn();
3417   return false;
3418 }
3419
3420 /*
3421  * If \a this looks packed (the front of nodal connectivity index equal to 0 and back of connectivity index equal to number of tuple of nodal connectivity array)
3422  * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
3423  * If nodal connectivity index points to a subpart of nodal connectivity index false will be returned.
3424  * \return bool - true if \a this looks packed, false is not.
3425  *
3426  * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkConsistencyLight test
3427  */
3428 bool MEDCoupling1DGTUMesh::isPacked() const
3429 {
3430   checkConsistencyLight();
3431   return _conn_indx->front()==0 && _conn_indx->back()==_conn->getNumberOfTuples();
3432 }
3433
3434 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(const MEDCoupling1DGTUMesh *mesh1, const MEDCoupling1DGTUMesh *mesh2)
3435 {
3436   std::vector<const MEDCoupling1DGTUMesh *> tmp(2);
3437   tmp[0]=const_cast<MEDCoupling1DGTUMesh *>(mesh1); tmp[1]=const_cast<MEDCoupling1DGTUMesh *>(mesh2);
3438   return Merge1DGTUMeshes(tmp);
3439 }
3440
3441 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(std::vector<const MEDCoupling1DGTUMesh *>& a)
3442 {
3443   std::size_t sz=a.size();
3444   if(sz==0)
3445     return Merge1DGTUMeshesLL(a);
3446   for(std::size_t ii=0;ii<sz;ii++)
3447     if(!a[ii])
3448       {
3449         std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::Merge1DGTUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !";
3450         throw INTERP_KERNEL::Exception(oss.str().c_str());
3451       }
3452   const INTERP_KERNEL::CellModel *cm=&(a[0]->getCellModel());
3453   for(std::size_t ii=0;ii<sz;ii++)
3454     if(&(a[ii]->getCellModel())!=cm)
3455       throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : all items must have the same geo type !");
3456   std::vector< MCAuto<MEDCoupling1DGTUMesh> > bb(sz);
3457   std::vector< const MEDCoupling1DGTUMesh * > aa(sz);
3458   int spaceDim=-3;
3459   for(std::size_t i=0;i<sz && spaceDim==-3;i++)
3460     {
3461       const MEDCoupling1DGTUMesh *cur=a[i];
3462       const DataArrayDouble *coo=cur->getCoords();
3463       if(coo)
3464         spaceDim=coo->getNumberOfComponents();
3465     }
3466   if(spaceDim==-3)
3467     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : no spaceDim specified ! unable to perform merge !");
3468   for(std::size_t i=0;i<sz;i++)
3469     {
3470       bb[i]=a[i]->buildSetInstanceFromThis(spaceDim);
3471       aa[i]=bb[i];
3472     }
3473   return Merge1DGTUMeshesLL(aa);
3474 }
3475
3476 /*!
3477  * \throw If presence of a null instance in the input vector \a a.
3478  * \throw If a is empty
3479  */
3480 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords(std::vector<const MEDCoupling1DGTUMesh *>& a)
3481 {
3482   if(a.empty())
3483     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : input array must be NON EMPTY !");
3484   std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin();
3485   if(!(*it))
3486     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : null instance in the first element of input vector !");
3487   std::vector< MCAuto<MEDCoupling1DGTUMesh> > objs(a.size());
3488   std::vector<const DataArrayInt *> ncs(a.size()),ncis(a.size());
3489   (*it)->getNumberOfCells();//to check that all is OK
3490   const DataArrayDouble *coords=(*it)->getCoords();
3491   const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
3492   bool tmp;
3493   objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp);
3494   ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex();
3495   it++;
3496   for(int i=1;it!=a.end();i++,it++)
3497     {
3498       if(!(*it))
3499         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : presence of null instance !");
3500       if(cm!=&((*it)->getCellModel()))
3501         throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !");
3502       (*it)->getNumberOfCells();//to check that all is OK
3503       objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp);
3504       ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex();
3505       if(coords!=(*it)->getCoords())
3506         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : not lying on same coords !");
3507     }
3508   MCAuto<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm));
3509   ret->setCoords(coords);
3510   ret->_conn=DataArrayInt::Aggregate(ncs);
3511   ret->_conn_indx=DataArrayInt::AggregateIndexes(ncis);
3512   return ret.retn();
3513 }
3514
3515 /*!
3516  * Assume that all instances in \a a are non null. If null it leads to a crash. That's why this method is assigned to be low level (LL)
3517  */
3518 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesLL(std::vector<const MEDCoupling1DGTUMesh *>& a)
3519 {
3520   if(a.empty())
3521     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : input array must be NON EMPTY !");
3522   std::vector< MCAuto<MEDCoupling1DGTUMesh> > objs(a.size());
3523   std::vector<const DataArrayInt *> ncs(a.size()),ncis(a.size());
3524   std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin();
3525   std::vector<int> nbNodesPerElt(a.size());
3526   int nbOfCells=(*it)->getNumberOfCells();
3527   bool tmp;
3528   objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp);
3529   ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex();
3530   nbNodesPerElt[0]=0;
3531   int prevNbOfNodes=(*it)->getNumberOfNodes();
3532   const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
3533   it++;
3534   for(int i=1;it!=a.end();i++,it++)
3535     {
3536       if(cm!=&((*it)->getCellModel()))
3537         throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !");
3538       objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp);
3539       ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex();
3540       nbOfCells+=(*it)->getNumberOfCells();
3541       nbNodesPerElt[i]=nbNodesPerElt[i-1]+prevNbOfNodes;
3542       prevNbOfNodes=(*it)->getNumberOfNodes();
3543     }
3544   std::vector<const MEDCouplingPointSet *> aps(a.size());
3545   std::copy(a.begin(),a.end(),aps.begin());
3546   MCAuto<DataArrayDouble> pts=MergeNodesArray(aps);
3547   MCAuto<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm));
3548   ret->setCoords(pts);
3549   ret->_conn=AggregateNodalConnAndShiftNodeIds(ncs,nbNodesPerElt);
3550   ret->_conn_indx=DataArrayInt::AggregateIndexes(ncis);
3551   return ret.retn();
3552 }
3553
3554 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::buildSetInstanceFromThis(int spaceDim) const
3555 {
3556   MCAuto<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
3557   MCAuto<DataArrayInt> tmp1,tmp2;
3558   const DataArrayInt *nodalConn(_conn),*nodalConnI(_conn_indx);
3559   if(!nodalConn)
3560     {
3561       tmp1=DataArrayInt::New(); tmp1->alloc(0,1);
3562     }
3563   else
3564     tmp1=_conn;
3565   ret->_conn=tmp1;
3566   //
3567   if(!nodalConnI)
3568     {
3569       tmp2=DataArrayInt::New(); tmp2->alloc(1,1); tmp2->setIJ(0,0,0);
3570     }
3571   else
3572     tmp2=_conn_indx;
3573   ret->_conn_indx=tmp2;
3574   //
3575   if(!_coords)
3576     {
3577       MCAuto<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim);
3578       ret->setCoords(coords);
3579     }
3580   else
3581     ret->setCoords(_coords);
3582   return ret.retn();
3583 }
3584
3585 /*!
3586  * This method aggregate the bbox of each cell and put it into bbox parameter.
3587  * 
3588  * \param [in] arcDetEps - a parameter specifying in case of 2D quadratic polygon cell the detection limit between linear and arc circle. (By default 1e-12)
3589  *                         For all other cases this input parameter is ignored.
3590  * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components.
3591  * 
3592  * \throw If \a this is not fully set (coordinates and connectivity).
3593  * \throw If a cell in \a this has no valid nodeId.
3594  */
3595 DataArrayDouble *MEDCoupling1DGTUMesh::getBoundingBoxForBBTree(double arcDetEps) const
3596 {
3597   checkFullyDefined();
3598   int spaceDim(getSpaceDimension()),nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes());
3599   MCAuto<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim);
3600   double *bbox(ret->getPointer());
3601   for(int i=0;i<nbOfCells*spaceDim;i++)
3602     {
3603       bbox[2*i]=std::numeric_limits<double>::max();
3604       bbox[2*i+1]=-std::numeric_limits<double>::max();
3605     }
3606   const double *coordsPtr(_coords->getConstPointer());
3607   const int *conn(_conn->getConstPointer()),*connI(_conn_indx->getConstPointer());
3608   for(int i=0;i<nbOfCells;i++)
3609     {
3610       int offset=connI[i];
3611       int nbOfNodesForCell(connI[i+1]-offset),kk(0);
3612       for(int j=0;j<nbOfNodesForCell;j++)
3613         {
3614           int nodeId=conn[offset+j];
3615           if(nodeId>=0 && nodeId<nbOfNodes)
3616             {
3617               for(int k=0;k<spaceDim;k++)
3618                 {
3619                   bbox[2*spaceDim*i+2*k]=std::min(bbox[2*spaceDim*i+2*k],coordsPtr[spaceDim*nodeId+k]);
3620                   bbox[2*spaceDim*i+2*k+1]=std::max(bbox[2*spaceDim*i+2*k+1],coordsPtr[spaceDim*nodeId+k]);
3621                 }
3622               kk++;
3623             }
3624         }
3625       if(kk==0)
3626         {
3627           std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getBoundingBoxForBBTree : cell #" << i << " contains no valid nodeId !";
3628           throw INTERP_KERNEL::Exception(oss.str().c_str());
3629         }
3630     }
3631   return ret.retn();
3632 }
3633
3634 /*!
3635  * Returns the cell field giving for each cell in \a this its diameter. Diameter means the max length of all possible SEG2 in the cell.
3636  *
3637  * \return a new instance of field containing the result. The returned instance has to be deallocated by the caller.
3638  */
3639 MEDCouplingFieldDouble *MEDCoupling1DGTUMesh::computeDiameterField() const
3640 {
3641   throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::computeDiameterField : not implemented yet for dynamic types !");
3642 }
3643
3644 std::vector<int> MEDCoupling1DGTUMesh::BuildAPolygonFromParts(const std::vector< std::vector<int> >& parts)
3645 {
3646   std::vector<int> ret;
3647   if(parts.empty())
3648     return ret;
3649   ret.insert(ret.end(),parts[0].begin(),parts[0].end());
3650   int ref(ret.back());
3651   std::size_t sz(parts.size()),nbh(1);
3652   std::vector<bool> b(sz,true); b[0]=false;
3653   while(nbh<sz)
3654     {
3655       std::size_t i(0);
3656       for(;i<sz;i++) if(b[i] && parts[i].front()==ref) { ret.insert(ret.end(),parts[i].begin()+1,parts[i].end()); nbh++; break; }
3657       if(i<sz)
3658         ref=ret.back();
3659       else
3660         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::BuildAPolygonFromParts : the input vector is not a part of a single polygon !");
3661     }
3662   if(ret.back()==ret.front())
3663     ret.pop_back();
3664   return ret;
3665 }
3666
3667 /*!
3668  * This method invert orientation of all cells in \a this. 
3669  * After calling this method the absolute value of measure of cells in \a this are the same than before calling.
3670  * This method only operates on the connectivity so coordinates are not touched at all.
3671  */
3672 void MEDCoupling1DGTUMesh::invertOrientationOfAllCells()
3673 {
3674   checkConsistencyOfConnectivity();
3675   INTERP_KERNEL::AutoCppPtr<INTERP_KERNEL::OrientationInverter> oi(INTERP_KERNEL::OrientationInverter::BuildInstanceFrom(getCellModelEnum()));
3676   int nbCells(getNumberOfCells());
3677   const int *connI(_conn_indx->begin());
3678   int *conn(_conn->getPointer());
3679   for(int i=0;i<nbCells;i++)
3680     oi->operate(conn+connI[i],conn+connI[i+1]);
3681   updateTime();
3682 }
3683
3684 /*!
3685  * This method performs an aggregation of \a nodalConns (as DataArrayInt::Aggregate does) but in addition of that a shift is applied on the 
3686  * values contained in \a nodalConns using corresponding offset specified in input \a offsetInNodeIdsPerElt.
3687  * But it also manage the values -1, that have a semantic in MEDCoupling1DGTUMesh class (separator for polyhedron).
3688  *
3689  * \param [in] nodalConns - a list of nodal connectivity arrays same size than \a offsetInNodeIdsPerElt.
3690  * \param [in] offsetInNodeIdsPerElt - a list of offsets to apply.
3691  * \return DataArrayInt * - A new object (to be managed by the caller) that is the result of the aggregation.
3692  * \throw If \a nodalConns or \a offsetInNodeIdsPerElt are empty.
3693  * \throw If \a nodalConns and \a offsetInNodeIdsPerElt have not the same size.
3694  * \throw If presence of null pointer in \a nodalConns.
3695  * \throw If presence of not allocated or array with not exactly one component in \a nodalConns.
3696  */
3697 DataArrayInt *MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds(const std::vector<const DataArrayInt *>& nodalConns, const std::vector<int>& offsetInNodeIdsPerElt)
3698 {
3699   std::size_t sz1(nodalConns.size()),sz2(offsetInNodeIdsPerElt.size());
3700   if(sz1!=sz2)
3701     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : input vectors do not have the same size !");
3702   if(sz1==0)
3703     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : empty vectors in input !");
3704   int nbOfTuples=0;
3705   for(std::vector<const DataArrayInt *>::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++)
3706     {
3707       if(!(*it))
3708         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of null pointer in input vector !");
3709       if(!(*it)->isAllocated())
3710         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of non allocated array in input vector !");
3711       if((*it)->getNumberOfComponents()!=1)
3712         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of array with not exactly one component !");
3713       nbOfTuples+=(*it)->getNumberOfTuples();
3714     }
3715   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
3716   int *pt=ret->getPointer();
3717   int i=0;
3718   for(std::vector<const DataArrayInt *>::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++,i++)
3719     {
3720       int curNbt=(*it)->getNumberOfTuples();
3721       const int *inPt=(*it)->begin();
3722       int offset=offsetInNodeIdsPerElt[i];
3723       for(int j=0;j<curNbt;j++,pt++)
3724         {
3725           if(inPt[j]!=-1)
3726             *pt=inPt[j]+offset;
3727           else
3728             *pt=-1;
3729         }
3730     }
3731   return ret.retn();
3732 }
3733
3734 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const MEDCouplingUMesh *m)
3735 {
3736   if(!m)
3737     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : input mesh is null !");
3738   std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes());
3739   if(gts.size()!=1)
3740     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : input mesh must have exactly one geometric type !");
3741   int geoType((int)*gts.begin());
3742   MCAuto<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(m->getName(),*gts.begin()));
3743   ret->setCoords(m->getCoords()); ret->setDescription(m->getDescription());
3744   int nbCells(m->getNumberOfCells());
3745   MCAuto<DataArrayInt> conn(DataArrayInt::New()),connI(DataArrayInt::New());
3746   conn->alloc(m->getNodalConnectivityArrayLen()-nbCells,1); connI->alloc(nbCells+1,1);
3747   int *c(conn->getPointer()),*ci(connI->getPointer()); *ci=0;
3748   const int *cin(m->getNodalConnectivity()->begin()),*ciin(m->getNodalConnectivityIndex()->begin());
3749   for(int i=0;i<nbCells;i++,ciin++,ci++)
3750     {
3751       if(cin[ciin[0]]==geoType)
3752         {
3753           if(ciin[1]-ciin[0]>=1)
3754             {
3755               c=std::copy(cin+ciin[0]+1,cin+ciin[1],c);
3756               ci[1]=ci[0]+ciin[1]-ciin[0]-1;
3757             }
3758           else
3759             {
3760               std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::New(const MEDCouplingUMesh *m) : something is wrong in the input mesh at cell #" << i << " ! The size of cell is not >=0 !";
3761               throw INTERP_KERNEL::Exception(oss.str().c_str());
3762             }
3763         }
3764       else
3765         {
3766           std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::New(const MEDCouplingUMesh *m) : something is wrong in the input mesh at cell #" << i << " ! The geometric type is not those expected !";
3767           throw INTERP_KERNEL::Exception(oss.str().c_str());
3768         }
3769     }
3770   ret->setNodalConnectivity(conn,connI);
3771   return ret.retn();
3772 }