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