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