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