]> SALOME platform Git repositories - tools/medcoupling.git/blob - src/MEDCoupling/MEDCoupling1GTUMesh.cxx
Salome HOME
Fix clang compilation (template instanciations) + clang warnings
[tools/medcoupling.git] / src / MEDCoupling / MEDCoupling1GTUMesh.cxx
1 // Copyright (C) 2007-2020  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 }
2306
2307 /*!
2308  * Checks if \a this and \a other meshes are geometrically equivalent with high
2309  * probability, else an exception is thrown. The meshes are considered equivalent if
2310  * (1) meshes contain the same number of nodes and the same number of elements of the
2311  * same types (2) three cells of the two meshes (first, last and middle) are based
2312  * on coincident nodes (with a specified precision).
2313  *  \param [in] other - the mesh to compare with.
2314  *  \param [in] prec - the precision used to compare nodes of the two meshes.
2315  *  \throw If the two meshes do not match.
2316  */
2317 void MEDCoupling1DGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const
2318 {
2319   MEDCouplingPointSet::checkFastEquivalWith(other,prec);
2320   const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2321   if(!otherC)
2322     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : Two meshes are not unstructured with single dynamic geometric type !");
2323   const DataArrayIdType *c1(_conn),*c2(otherC->_conn);
2324   if(c1!=c2)
2325     {
2326       if(!c1 || !c2)
2327         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !");
2328       if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
2329         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !");
2330       if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
2331         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !");
2332       if(c1->getHashCode()!=c2->getHashCode())
2333         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity differs");
2334     }
2335   c1=_conn_indx; c2=otherC->_conn_indx;
2336   if(c1!=c2)
2337     {
2338       if(!c1 || !c2)
2339         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity index only in one of the 2 meshes !");
2340       if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
2341         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, only one is allocated !");
2342       if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
2343         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, must have 1 and only 1 component !");
2344       if(c1->getHashCode()!=c2->getHashCode())
2345         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity index differs");
2346     }
2347 }
2348
2349 void MEDCoupling1DGTUMesh::checkConsistencyOfConnectivity() const
2350 {
2351   const DataArrayIdType *c1(_conn);
2352   if(c1)
2353     {
2354       if(c1->getNumberOfComponents()!=1)
2355         throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !");
2356       if(c1->getInfoOnComponent(0)!="")
2357         throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !");
2358       c1->checkAllocated();
2359     }
2360   else
2361     throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !");
2362   //
2363   mcIdType sz2(_conn->getNumberOfTuples());
2364   c1=_conn_indx;
2365   if(c1)
2366     {
2367       if(c1->getNumberOfComponents()!=1)
2368         throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to be with number of components set to one !");
2369       c1->checkAllocated();
2370       if(c1->getNumberOfTuples()<1)
2371         throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have a a size of 1 at least !");
2372       if(c1->getInfoOnComponent(0)!="")
2373         throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have no info on its single component !");
2374       mcIdType f=c1->front(),ll=c1->back();
2375       if(f<0 || (sz2>0 && f>=sz2))
2376         {
2377           std::ostringstream oss; oss << "Nodal connectivity index array first value (" << f << ") is expected to be exactly in [0," << sz2 << ") !";
2378           throw INTERP_KERNEL::Exception(oss.str().c_str());
2379         }
2380       if(ll<0 || ll>sz2)
2381         {
2382           std::ostringstream oss; oss << "Nodal connectivity index array last value (" << ll << ") is expected to be exactly in [0," << sz2 << "] !";
2383           throw INTERP_KERNEL::Exception(oss.str().c_str());
2384         }
2385       if(f>ll)
2386         {
2387           std::ostringstream oss; oss << "Nodal connectivity index array looks very bad (not increasing monotonic) because front (" << f << ") is greater that back (" << ll << ") !";
2388           throw INTERP_KERNEL::Exception(oss.str().c_str());
2389         }
2390     }
2391   else
2392     throw INTERP_KERNEL::Exception("Nodal connectivity index array not defined !");
2393   mcIdType szOfC1Exp=_conn_indx->back();
2394   if(sz2<szOfC1Exp)
2395     {
2396       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() << " !";
2397       throw INTERP_KERNEL::Exception(oss.str().c_str());
2398     }
2399 }
2400
2401 /*!
2402  * 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.
2403  * In addition you are sure that the length of nodal connectivity index array is bigger than or equal to one.
2404  * In addition you are also sure that length of nodal connectivity is coherent with the content of the last value in the index array.
2405  */
2406 void MEDCoupling1DGTUMesh::checkConsistencyLight() const
2407 {
2408   MEDCouplingPointSet::checkConsistencyLight();
2409   checkConsistencyOfConnectivity();
2410 }
2411
2412 void MEDCoupling1DGTUMesh::checkConsistency(double eps) const
2413 {
2414   checkConsistencyLight();
2415   const DataArrayIdType *c1(_conn),*c2(_conn_indx);
2416   if(!c2->isMonotonic(true))
2417     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkConsistency : the nodal connectivity index is expected to be increasing monotinic !");
2418   //
2419   mcIdType nbOfTuples(c1->getNumberOfTuples());
2420   mcIdType nbOfNodes=getNumberOfNodes();
2421   const mcIdType *w(c1->begin());
2422   for(mcIdType i=0;i<nbOfTuples;i++,w++)
2423     {
2424       if(*w==-1) continue;
2425       if(*w<0 || *w>=nbOfNodes)
2426         {
2427           std::ostringstream oss; oss << "At pos #" << i << " of nodal connectivity array references to node id #" << *w << " must be in [0," << nbOfNodes << ") !";
2428           throw INTERP_KERNEL::Exception(oss.str().c_str());
2429         }
2430     }
2431 }
2432
2433 mcIdType MEDCoupling1DGTUMesh::getNumberOfCells() const
2434 {
2435   checkConsistencyOfConnectivity();//do not remove
2436   return _conn_indx->getNumberOfTuples()-1;
2437 }
2438
2439 /*!
2440  * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
2441  * For each cell in \b this the number of nodes constituting cell is computed.
2442  * For each polyhedron cell, the sum of the number of nodes of each face constituting polyhedron cell is returned.
2443  * So for pohyhedrons some nodes can be counted several times in the returned result.
2444  * 
2445  * \return a newly allocated array
2446  */
2447 DataArrayIdType *MEDCoupling1DGTUMesh::computeNbOfNodesPerCell() const
2448 {
2449   checkConsistencyLight();
2450   _conn_indx->checkMonotonic(true);
2451   if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2452     return _conn_indx->deltaShiftIndex();
2453   // for polyhedrons
2454   mcIdType nbOfCells=_conn_indx->getNumberOfTuples()-1;
2455   MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
2456   ret->alloc(nbOfCells,1);
2457   mcIdType *retPtr=ret->getPointer();
2458   const mcIdType *ci=_conn_indx->begin(),*c=_conn->begin();
2459   for(mcIdType i=0;i<nbOfCells;i++,retPtr++,ci++)
2460     *retPtr=int(ci[1]-ci[0]-ToIdType(std::count(c+ci[0],c+ci[1],-1)));
2461   return ret.retn();
2462 }
2463
2464 /*!
2465  * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
2466  * For each cell in \b this the number of faces constituting (entity of dimension this->getMeshDimension()-1) cell is computed.
2467  * 
2468  * \return a newly allocated array
2469  */
2470 DataArrayIdType *MEDCoupling1DGTUMesh::computeNbOfFacesPerCell() const
2471 {
2472   checkConsistencyLight();
2473   _conn_indx->checkMonotonic(true);
2474   if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED && getCellModelEnum()!=INTERP_KERNEL::NORM_QPOLYG)
2475     return _conn_indx->deltaShiftIndex();
2476   if(getCellModelEnum()==INTERP_KERNEL::NORM_QPOLYG)
2477     {
2478       MCAuto<DataArrayIdType> ret=_conn_indx->deltaShiftIndex();
2479       ret->applyDivideBy(2);
2480       return ret.retn();
2481     }
2482   // for polyhedrons
2483   mcIdType nbOfCells=_conn_indx->getNumberOfTuples()-1;
2484   MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
2485   ret->alloc(nbOfCells,1);
2486   mcIdType *retPtr=ret->getPointer();
2487   const mcIdType *ci=_conn_indx->begin(),*c=_conn->begin();
2488   for(mcIdType i=0;i<nbOfCells;i++,retPtr++,ci++)
2489     *retPtr=ToIdType(std::count(c+ci[0],c+ci[1],-1))+1;
2490   return ret.retn();
2491 }
2492
2493 /*!
2494  * This method computes effective number of nodes per cell. That is to say nodes appearing several times in nodal connectivity of a cell,
2495  * will be counted only once here whereas it will be counted several times in MEDCoupling1DGTUMesh::computeNbOfNodesPerCell method.
2496  *
2497  * \return DataArrayIdType * - new object to be deallocated by the caller.
2498  * \sa MEDCoupling1DGTUMesh::computeNbOfNodesPerCell
2499  */
2500 DataArrayIdType *MEDCoupling1DGTUMesh::computeEffectiveNbOfNodesPerCell() const
2501 {
2502   checkConsistencyLight();
2503   _conn_indx->checkMonotonic(true);
2504   mcIdType nbOfCells=_conn_indx->getNumberOfTuples()-1;
2505   MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
2506   ret->alloc(nbOfCells,1);
2507   mcIdType *retPtr(ret->getPointer());
2508   const mcIdType *ci(_conn_indx->begin()),*c(_conn->begin());
2509   if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2510     {
2511       for(mcIdType i=0;i<nbOfCells;i++,retPtr++,ci++)
2512         {
2513           std::set<mcIdType> s(c+ci[0],c+ci[1]);
2514           *retPtr=ToIdType(s.size());
2515         }
2516     }
2517   else
2518     {
2519       for(mcIdType i=0;i<nbOfCells;i++,retPtr++,ci++)
2520         {
2521           std::set<mcIdType> s(c+ci[0],c+ci[1]); s.erase(-1);
2522           *retPtr=ToIdType(s.size());
2523         }
2524     }
2525   return ret.retn();
2526 }
2527
2528 void MEDCoupling1DGTUMesh::getNodeIdsOfCell(mcIdType cellId, std::vector<mcIdType>& conn) const
2529 {
2530   mcIdType nbOfCells(getNumberOfCells());//performs checks
2531   if(cellId<nbOfCells)
2532     {
2533       mcIdType strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0);
2534       mcIdType nbOfNodes=stp-strt;
2535       if(nbOfNodes<0)
2536         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::getNodeIdsOfCell : the index array is invalid ! Should be increasing monotonic !");
2537       conn.resize(nbOfNodes);
2538       std::copy(_conn->begin()+strt,_conn->begin()+stp,conn.begin());
2539     }
2540   else
2541     {
2542       std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !";
2543       throw INTERP_KERNEL::Exception(oss.str().c_str());
2544     }
2545 }
2546
2547 mcIdType MEDCoupling1DGTUMesh::getNumberOfNodesInCell(mcIdType cellId) const
2548 {
2549   mcIdType nbOfCells=getNumberOfCells();//performs checks
2550   if(cellId>=0 && cellId<nbOfCells)
2551     {
2552       const mcIdType *conn(_conn->begin());
2553       mcIdType strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0);
2554       return stp-strt-ToIdType(std::count(conn+strt,conn+stp,-1));
2555     }
2556   else
2557     {
2558       std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNumberOfNodesInCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !";
2559       throw INTERP_KERNEL::Exception(oss.str().c_str());
2560     }
2561 }
2562
2563 std::string MEDCoupling1DGTUMesh::simpleRepr() const
2564 {
2565   static const char msg0[]="No coordinates specified !";
2566   std::ostringstream ret;
2567   ret << "Single dynamic geometic type (" << _cm->getRepr() << ") unstructured mesh with name : \"" << getName() << "\"\n";
2568   ret << "Description of mesh : \"" << getDescription() << "\"\n";
2569   int tmpp1,tmpp2;
2570   double tt=getTime(tmpp1,tmpp2);
2571   ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
2572   ret << "Iteration : " << tmpp1  << " Order : " << tmpp2 << "\n";
2573   ret << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : ";
2574   if(_coords!=0)
2575     {
2576       const int spaceDim=getSpaceDimension();
2577       ret << spaceDim << "\nInfo attached on space dimension : ";
2578       for(int i=0;i<spaceDim;i++)
2579         ret << "\"" << _coords->getInfoOnComponent(i) << "\" ";
2580       ret << "\n";
2581     }
2582   else
2583     ret << msg0 << "\n";
2584   ret << "Number of nodes : ";
2585   if(_coords!=0)
2586     ret << getNumberOfNodes() << "\n";
2587   else
2588     ret << msg0 << "\n";
2589   ret << "Number of cells : ";
2590   bool isOK=true;
2591   try { checkConsistencyLight(); } catch(INTERP_KERNEL::Exception& /* e */)
2592   {
2593       ret << "Nodal connectivity arrays are not set or badly set !\n";
2594       isOK=false;
2595   }
2596   if(isOK)
2597     ret << getNumberOfCells() << "\n";
2598   ret << "Cell type : " << _cm->getRepr() << "\n";
2599   return ret.str();
2600 }
2601
2602 std::string MEDCoupling1DGTUMesh::advancedRepr() const
2603 {
2604   std::ostringstream ret;
2605   ret << simpleRepr();
2606   ret << "\nCoordinates array : \n___________________\n\n";
2607   if(_coords)
2608     _coords->reprWithoutNameStream(ret);
2609   else
2610     ret << "No array set !\n";
2611   ret << "\n\nNodal Connectivity : \n____________________\n\n";
2612   //
2613   bool isOK=true;
2614   try { checkConsistency(); } catch(INTERP_KERNEL::Exception& /* e */)
2615   {
2616       ret << "Nodal connectivity arrays are not set or badly set !\n";
2617       isOK=false;
2618   }
2619   if(!isOK)
2620     return ret.str();
2621   mcIdType nbOfCells=getNumberOfCells();
2622   const mcIdType *ci=_conn_indx->begin(),*c=_conn->begin();
2623   for(mcIdType i=0;i<nbOfCells;i++,ci++)
2624     {
2625       ret << "Cell #" << i << " : ";
2626       std::copy(c+ci[0],c+ci[1],std::ostream_iterator<int>(ret," "));
2627       ret << "\n";
2628     }
2629   return ret.str();
2630 }
2631
2632 DataArrayDouble *MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell() const
2633 {
2634   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2635   int spaceDim=getSpaceDimension();
2636   mcIdType nbOfCells=getNumberOfCells();//checkConsistencyLight()
2637   mcIdType nbOfNodes=getNumberOfNodes();
2638   ret->alloc(nbOfCells,spaceDim);
2639   double *ptToFill=ret->getPointer();
2640   const double *coor=_coords->begin();
2641   const mcIdType *nodal=_conn->begin(),*nodali=_conn_indx->begin();
2642   nodal+=nodali[0];
2643   if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2644     {
2645       for(mcIdType i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
2646         {
2647           std::fill(ptToFill,ptToFill+spaceDim,0.);
2648           if(nodali[0]<nodali[1])// >= to avoid division by 0.
2649             {
2650               for(mcIdType j=nodali[0];j<nodali[1];j++,nodal++)
2651                 {
2652                   if(*nodal>=0 && *nodal<nbOfNodes)
2653                     std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
2654                   else
2655                     {
2656                       std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," <<   nbOfNodes << ") !";
2657                       throw INTERP_KERNEL::Exception(oss.str().c_str());
2658                     }
2659                   std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./double(nodali[1]-nodali[0])));
2660                 }
2661             }
2662           else
2663             {
2664               std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : at cell #" << i << " the nodal index array is invalid !";
2665               throw INTERP_KERNEL::Exception(oss.str().c_str());
2666             }
2667         }
2668     }
2669   else
2670     {
2671       for(mcIdType i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
2672         {
2673           std::fill(ptToFill,ptToFill+spaceDim,0.);
2674           if(nodali[0]<nodali[1])// >= to avoid division by 0.
2675             {
2676               int nbOfNod=0;
2677               for(mcIdType j=nodali[0];j<nodali[1];j++,nodal++)
2678                 {
2679                   if(*nodal==-1) continue;
2680                   if(*nodal>=0 && *nodal<nbOfNodes)
2681                     {
2682                       std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
2683                       nbOfNod++;
2684                     }
2685                   else
2686                     {
2687                       std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," <<   nbOfNodes << ") !";
2688                       throw INTERP_KERNEL::Exception(oss.str().c_str());
2689                     }
2690                 }
2691               if(nbOfNod!=0)
2692                 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./nbOfNod));
2693               else
2694                 {
2695                   std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : no nodes in cell #" << i << " !";
2696                   throw INTERP_KERNEL::Exception(oss.str().c_str());
2697                 }
2698             }
2699           else
2700             {
2701               std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron)  : at cell #" << i << " the nodal index array is invalid !";
2702               throw INTERP_KERNEL::Exception(oss.str().c_str());
2703             }
2704         }
2705     }
2706   return ret.retn();
2707 }
2708
2709 void MEDCoupling1DGTUMesh::renumberCells(const mcIdType *old2NewBg, bool check)
2710 {
2711   mcIdType nbCells=getNumberOfCells();
2712   MCAuto<DataArrayIdType> o2n=DataArrayIdType::New();
2713   o2n->useArray(old2NewBg,false,DeallocType::C_DEALLOC,nbCells,1);
2714   if(check)
2715     o2n=o2n->checkAndPreparePermutation();
2716   //
2717   const mcIdType *o2nPtr=o2n->getPointer();
2718   const mcIdType *conn=_conn->begin(),*conni=_conn_indx->begin();
2719   MCAuto<DataArrayIdType> newConn=DataArrayIdType::New();
2720   MCAuto<DataArrayIdType> newConnI=DataArrayIdType::New();
2721   newConn->alloc(_conn->getNumberOfTuples(),1); newConnI->alloc(nbCells,1);
2722   newConn->copyStringInfoFrom(*_conn); newConnI->copyStringInfoFrom(*_conn_indx);
2723   //
2724   mcIdType *newC=newConn->getPointer(),*newCI=newConnI->getPointer();
2725   for(mcIdType i=0;i<nbCells;i++)
2726     {
2727       mcIdType newPos=o2nPtr[i];
2728       mcIdType sz=conni[i+1]-conni[i];
2729       if(sz>=0)
2730         newCI[newPos]=sz;
2731       else
2732         {
2733           std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberCells : the index nodal array is invalid for cell #" << i << " !";
2734           throw INTERP_KERNEL::Exception(oss.str().c_str());
2735         }
2736     }
2737   newConnI->computeOffsetsFull(); newCI=newConnI->getPointer();
2738   //
2739   for(mcIdType i=0;i<nbCells;i++,conni++)
2740     {
2741       mcIdType newp=o2nPtr[i];
2742       std::copy(conn+conni[0],conn+conni[1],newC+newCI[newp]);
2743     }
2744   _conn=newConn;
2745   _conn_indx=newConnI;
2746 }
2747
2748 MEDCouplingMesh *MEDCoupling1DGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
2749 {
2750   if(other->getType()!=SINGLE_DYNAMIC_GEO_TYPE_UNSTRUCTURED)
2751     throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single dynamic geo type each other !");
2752   const MEDCoupling1DGTUMesh *otherC=static_cast<const MEDCoupling1DGTUMesh *>(other);
2753   return Merge1DGTUMeshes(this,otherC);
2754 }
2755
2756 MEDCouplingUMesh *MEDCoupling1DGTUMesh::buildUnstructured() const
2757 {
2758   MCAuto<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName(),getMeshDimension());
2759   ret->setCoords(getCoords());
2760   const mcIdType *nodalConn=_conn->begin(),*nodalConnI=_conn_indx->begin();
2761   mcIdType nbCells=getNumberOfCells();//checkConsistencyLight
2762   mcIdType geoType=ToIdType(getCellModelEnum());
2763   MCAuto<DataArrayIdType> c=DataArrayIdType::New(); c->alloc(nbCells+_conn->getNumberOfTuples(),1);
2764   MCAuto<DataArrayIdType> cI=DataArrayIdType::New(); cI->alloc(nbCells+1);
2765   mcIdType *cPtr=c->getPointer(),*ciPtr=cI->getPointer();
2766   ciPtr[0]=0;
2767   for(mcIdType i=0;i<nbCells;i++,ciPtr++)
2768     {
2769       mcIdType sz=nodalConnI[i+1]-nodalConnI[i];
2770       if(sz>=0)
2771         {
2772           *cPtr++=geoType;
2773           cPtr=std::copy(nodalConn+nodalConnI[i],nodalConn+nodalConnI[i+1],cPtr);
2774           ciPtr[1]=ciPtr[0]+sz+1;
2775         }
2776       else
2777         {
2778           std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::buildUnstructured : Invalid for nodal index for cell #" << i << " !";
2779           throw INTERP_KERNEL::Exception(oss.str().c_str());
2780         }
2781     }
2782   ret->setConnectivity(c,cI,true);
2783   try
2784   { ret->copyTinyInfoFrom(this); }
2785   catch(INTERP_KERNEL::Exception&) { }
2786   return ret.retn();
2787 }
2788
2789 /*!
2790  * Do nothing for the moment, because there is no policy that allows to split polygons, polyhedrons ... into simplexes
2791  */
2792 DataArrayIdType *MEDCoupling1DGTUMesh::simplexize(int policy)
2793 {
2794   mcIdType nbOfCells=getNumberOfCells();
2795   MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
2796   ret->alloc(nbOfCells,1);
2797   ret->iota(0);
2798   return ret.retn();
2799 }
2800
2801 void MEDCoupling1DGTUMesh::reprQuickOverview(std::ostream& stream) const
2802 {
2803   stream << "MEDCoupling1DGTUMesh C++ instance at " << this << ". Type=" << _cm->getRepr() << ". Name : \"" << getName() << "\".";
2804   stream << " Mesh dimension : " << getMeshDimension() << ".";
2805   if(!_coords)
2806     { stream << " No coordinates set !"; return ; }
2807   if(!_coords->isAllocated())
2808     { stream << " Coordinates set but not allocated !"; return ; }
2809   stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
2810   stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
2811   bool isOK=true;
2812   try { checkConsistencyLight(); } catch(INTERP_KERNEL::Exception&  /* e */)
2813   {
2814       stream << std::endl << "Nodal connectivity NOT set properly !\n";
2815       isOK=false;
2816   }
2817   if(isOK)
2818     stream << std::endl << "Number of cells : " << getNumberOfCells() << ".";
2819 }
2820
2821 void MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other)
2822 {
2823   if(!other)
2824     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is null !");
2825   const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2826   if(!otherC)
2827     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1DGTUMesh instance !");
2828   setNodalConnectivity(otherC->getNodalConnectivity(),otherC->getNodalConnectivityIndex());
2829 }
2830
2831 MEDCouplingPointSet *MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const
2832 {
2833   if(!other)
2834     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : input other is null !");
2835   const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2836   if(!otherC)
2837     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !");
2838   std::vector<const MEDCoupling1DGTUMesh *> ms(2);
2839   ms[0]=this;
2840   ms[1]=otherC;
2841   return Merge1DGTUMeshesOnSameCoords(ms);
2842 }
2843
2844 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords(const mcIdType *begin, const mcIdType *end) const
2845 {
2846   checkConsistencyLight();
2847   MCAuto<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
2848   ret->setCoords(_coords);
2849   DataArrayIdType *c=0,*ci=0;
2850   DataArrayIdType::ExtractFromIndexedArrays(begin,end,_conn,_conn_indx,c,ci);
2851   MCAuto<DataArrayIdType> cSafe(c),ciSafe(ci);
2852   ret->setNodalConnectivity(c,ci);
2853   return ret.retn();
2854 }
2855
2856 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoordsSlice(mcIdType start, mcIdType end, mcIdType step) const
2857 {
2858   checkConsistencyLight();
2859   MCAuto<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
2860   ret->setCoords(_coords);
2861   DataArrayIdType *c=0,*ci=0;
2862   DataArrayIdType::ExtractFromIndexedArraysSlice(start,end,step,_conn,_conn_indx,c,ci);
2863   MCAuto<DataArrayIdType> cSafe(c),ciSafe(ci);
2864   ret->setNodalConnectivity(c,ci);
2865   return ret.retn();
2866 }
2867
2868 void MEDCoupling1DGTUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const
2869 {
2870   checkConsistency();
2871   mcIdType sz(ToIdType(nodeIdsInUse.size()));
2872   for(const mcIdType *conn=_conn->begin();conn!=_conn->end();conn++)
2873     {
2874       if(*conn>=0 && *conn<sz)
2875         nodeIdsInUse[*conn]=true;
2876       else
2877         {
2878           if(*conn!=-1)
2879             {
2880               std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeNodeIdsAlg : At pos #" << std::distance(_conn->begin(),conn) << " value is " << *conn << " must be in [0," << sz << ") !";
2881               throw INTERP_KERNEL::Exception(oss.str().c_str());
2882             }
2883         }
2884     }
2885 }
2886
2887 void MEDCoupling1DGTUMesh::getReverseNodalConnectivity(DataArrayIdType *revNodal, DataArrayIdType *revNodalIndx) const
2888 {
2889   checkFullyDefined();
2890   mcIdType nbOfNodes=getNumberOfNodes();
2891   mcIdType *revNodalIndxPtr=(mcIdType *)malloc((nbOfNodes+1)*sizeof(mcIdType));
2892   revNodalIndx->useArray(revNodalIndxPtr,true,DeallocType::C_DEALLOC,nbOfNodes+1,1);
2893   std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
2894   const mcIdType *conn=_conn->begin(),*conni=_conn_indx->begin();
2895   mcIdType nbOfCells=getNumberOfCells();
2896   mcIdType nbOfEltsInRevNodal=0;
2897   for(mcIdType eltId=0;eltId<nbOfCells;eltId++)
2898     {
2899       mcIdType nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
2900       if(nbOfNodesPerCell>=0)
2901         {
2902           for(mcIdType j=0;j<nbOfNodesPerCell;j++)
2903             {
2904               mcIdType nodeId=conn[conni[eltId]+j];
2905               if(nodeId==-1) continue;            
2906               if(nodeId>=0 && nodeId<nbOfNodes)
2907                 {
2908                   nbOfEltsInRevNodal++;
2909                   revNodalIndxPtr[nodeId+1]++;
2910                 }
2911               else
2912                 {
2913                   std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !";
2914                   throw INTERP_KERNEL::Exception(oss.str().c_str());
2915                 }
2916             }
2917         }
2918       else
2919         {
2920           std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << "nodal connectivity is invalid !";
2921           throw INTERP_KERNEL::Exception(oss.str().c_str());
2922         }
2923     }
2924   std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<mcIdType>());
2925   conn=_conn->begin();
2926   mcIdType *revNodalPtr=(mcIdType *)malloc((nbOfEltsInRevNodal)*sizeof(mcIdType));
2927   revNodal->useArray(revNodalPtr,true,DeallocType::C_DEALLOC,nbOfEltsInRevNodal,1);
2928   std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
2929   for(mcIdType eltId=0;eltId<nbOfCells;eltId++)
2930     {
2931       mcIdType nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
2932       for(mcIdType j=0;j<nbOfNodesPerCell;j++)
2933         {
2934           mcIdType nodeId=conn[conni[eltId]+j];
2935           if(nodeId!=-1)
2936             *std::find_if(revNodalPtr+revNodalIndxPtr[nodeId],revNodalPtr+revNodalIndxPtr[nodeId+1],std::bind2nd(std::equal_to<mcIdType>(),-1))=eltId;
2937         }
2938     }
2939 }
2940
2941 void MEDCoupling1DGTUMesh::checkFullyDefined() const
2942 {
2943   if(!((const DataArrayIdType *)_conn) || !((const DataArrayIdType *)_conn_indx) || !((const DataArrayDouble *)_coords))
2944     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFullyDefined : part of this is not fully defined.");
2945 }
2946
2947 bool MEDCoupling1DGTUMesh::isEmptyMesh(const std::vector<mcIdType>& tinyInfo) const
2948 {
2949   throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEmptyMesh : not implemented yet !");
2950 }
2951
2952 void MEDCoupling1DGTUMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<mcIdType>& tinyInfo, std::vector<std::string>& littleStrings) const
2953 {
2954   int it,order;
2955   double time=getTime(it,order);
2956   tinyInfo.clear(); tinyInfoD.clear(); littleStrings.clear();
2957   //
2958   littleStrings.push_back(getName());
2959   littleStrings.push_back(getDescription());
2960   littleStrings.push_back(getTimeUnit());
2961   //
2962   std::vector<std::string> littleStrings2,littleStrings3,littleStrings4;
2963   if((const DataArrayDouble *)_coords)
2964     _coords->getTinySerializationStrInformation(littleStrings2);
2965   if((const DataArrayIdType *)_conn)
2966     _conn->getTinySerializationStrInformation(littleStrings3);
2967   if((const DataArrayIdType *)_conn_indx)
2968     _conn_indx->getTinySerializationStrInformation(littleStrings4);
2969   mcIdType sz0(ToIdType(littleStrings2.size())),sz1(ToIdType(littleStrings3.size())),sz2(ToIdType(littleStrings4.size()));
2970   littleStrings.insert(littleStrings.end(),littleStrings2.begin(),littleStrings2.end());
2971   littleStrings.insert(littleStrings.end(),littleStrings3.begin(),littleStrings3.end());
2972   littleStrings.insert(littleStrings.end(),littleStrings4.begin(),littleStrings4.end());
2973   //
2974   tinyInfo.push_back(getCellModelEnum());
2975   tinyInfo.push_back(it);
2976   tinyInfo.push_back(order);
2977   std::vector<mcIdType> tinyInfo2,tinyInfo3,tinyInfo4;
2978   if((const DataArrayDouble *)_coords)
2979     _coords->getTinySerializationIntInformation(tinyInfo2);
2980   if((const DataArrayIdType *)_conn)
2981     _conn->getTinySerializationIntInformation(tinyInfo3);
2982   if((const DataArrayIdType *)_conn_indx)
2983     _conn_indx->getTinySerializationIntInformation(tinyInfo4);
2984   mcIdType sz3(ToIdType(tinyInfo2.size())),sz4(ToIdType(tinyInfo3.size())),sz5(ToIdType(tinyInfo4.size()));
2985   tinyInfo.push_back(sz0); tinyInfo.push_back(sz1); tinyInfo.push_back(sz2); tinyInfo.push_back(sz3); tinyInfo.push_back(sz4);  tinyInfo.push_back(sz5);
2986   tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
2987   tinyInfo.insert(tinyInfo.end(),tinyInfo3.begin(),tinyInfo3.end());
2988   tinyInfo.insert(tinyInfo.end(),tinyInfo4.begin(),tinyInfo4.end());
2989   //
2990   tinyInfoD.push_back(time);
2991 }
2992
2993 void MEDCoupling1DGTUMesh::resizeForUnserialization(const std::vector<mcIdType>& tinyInfo, DataArrayIdType *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
2994 {
2995   std::vector<mcIdType> tinyInfo2(tinyInfo.begin()+9,tinyInfo.begin()+9+tinyInfo[6]);
2996   std::vector<mcIdType> tinyInfo1(tinyInfo.begin()+9+tinyInfo[6],tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7]);
2997   std::vector<mcIdType> tinyInfo12(tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7],tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7]+tinyInfo[8]);
2998   MCAuto<DataArrayIdType> p1(DataArrayIdType::New()); p1->resizeForUnserialization(tinyInfo1);
2999   MCAuto<DataArrayIdType> p2(DataArrayIdType::New()); p2->resizeForUnserialization(tinyInfo12);
3000   std::vector<const DataArrayIdType *> v(2); v[0]=p1; v[1]=p2;
3001   p2=DataArrayIdType::Aggregate(v);
3002   a2->resizeForUnserialization(tinyInfo2);
3003   a1->alloc(p2->getNbOfElems(),1);
3004 }
3005
3006 void MEDCoupling1DGTUMesh::serialize(DataArrayIdType *&a1, DataArrayDouble *&a2) const
3007 {
3008   mcIdType sz(0);
3009   if((const DataArrayIdType *)_conn)
3010     if(_conn->isAllocated())
3011       sz=_conn->getNbOfElems();
3012   if((const DataArrayIdType *)_conn_indx)
3013     if(_conn_indx->isAllocated())
3014       sz+=_conn_indx->getNbOfElems();
3015   a1=DataArrayIdType::New();
3016   a1->alloc(sz,1);
3017   mcIdType *work(a1->getPointer());
3018   if(sz!=0 && (const DataArrayIdType *)_conn)
3019     work=std::copy(_conn->begin(),_conn->end(),a1->getPointer());
3020   if(sz!=0 && (const DataArrayIdType *)_conn_indx)
3021     std::copy(_conn_indx->begin(),_conn_indx->end(),work);
3022   sz=0;
3023   if((const DataArrayDouble *)_coords)
3024     if(_coords->isAllocated())
3025       sz=_coords->getNbOfElems();
3026   a2=DataArrayDouble::New();
3027   a2->alloc(sz,1);
3028   if(sz!=0 && (const DataArrayDouble *)_coords)
3029     std::copy(_coords->begin(),_coords->end(),a2->getPointer());
3030 }
3031
3032 void MEDCoupling1DGTUMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<mcIdType>& tinyInfo, const DataArrayIdType *a1, DataArrayDouble *a2,
3033                                            const std::vector<std::string>& littleStrings)
3034 {
3035   INTERP_KERNEL::NormalizedCellType gt((INTERP_KERNEL::NormalizedCellType)tinyInfo[0]);
3036   _cm=&INTERP_KERNEL::CellModel::GetCellModel(gt);
3037   setName(littleStrings[0]);
3038   setDescription(littleStrings[1]);
3039   setTimeUnit(littleStrings[2]);
3040   setTime(tinyInfoD[0],FromIdType<int>(tinyInfo[1]),FromIdType<int>(tinyInfo[2]));
3041   mcIdType sz0(tinyInfo[3]),sz1(tinyInfo[4]),sz2(tinyInfo[5]),sz3(tinyInfo[6]),sz4(tinyInfo[7]),sz5(tinyInfo[8]);
3042   //
3043   _coords=DataArrayDouble::New();
3044   std::vector<mcIdType> tinyInfo2(tinyInfo.begin()+9,tinyInfo.begin()+9+sz3);
3045   _coords->resizeForUnserialization(tinyInfo2);
3046   std::copy(a2->begin(),a2->end(),_coords->getPointer());
3047   _conn=DataArrayIdType::New();
3048   std::vector<mcIdType> tinyInfo3(tinyInfo.begin()+9+sz3,tinyInfo.begin()+9+sz3+sz4);
3049   _conn->resizeForUnserialization(tinyInfo3);
3050   std::copy(a1->begin(),a1->begin()+_conn->getNbOfElems(),_conn->getPointer());
3051   _conn_indx=DataArrayIdType::New();
3052   std::vector<mcIdType> tinyInfo4(tinyInfo.begin()+9+sz3+sz4,tinyInfo.begin()+9+sz3+sz4+sz5);
3053   _conn_indx->resizeForUnserialization(tinyInfo4);
3054   std::copy(a1->begin()+_conn->getNbOfElems(),a1->end(),_conn_indx->getPointer());
3055   std::vector<std::string> littleStrings2(littleStrings.begin()+3,littleStrings.begin()+3+sz0);
3056   _coords->finishUnserialization(tinyInfo2,littleStrings2);
3057   std::vector<std::string> littleStrings3(littleStrings.begin()+3+sz0,littleStrings.begin()+3+sz0+sz1);
3058   _conn->finishUnserialization(tinyInfo3,littleStrings3);
3059   std::vector<std::string> littleStrings4(littleStrings.begin()+3+sz0+sz1,littleStrings.begin()+3+sz0+sz1+sz2);
3060   _conn_indx->finishUnserialization(tinyInfo4,littleStrings4);
3061 }
3062
3063 /*!
3064  * Finds nodes not used in any cell and returns an array giving a new id to every node
3065  * by excluding the unused nodes, for which the array holds -1. The result array is
3066  * a mapping in "Old to New" mode.
3067  *  \return DataArrayIdType * - a new instance of DataArrayIdType. Its length is \a
3068  *          this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
3069  *          if the node is unused or a new id else. The caller is to delete this
3070  *          array using decrRef() as it is no more needed.
3071  *  \throw If the coordinates array is not set.
3072  *  \throw If the nodal connectivity of cells is not defined.
3073  *  \throw If the nodal connectivity includes an invalid id.
3074  *  \sa MEDCoupling1DGTUMesh::getNodeIdsInUse, areAllNodesFetched
3075  */
3076 DataArrayIdType *MEDCoupling1DGTUMesh::computeFetchedNodeIds() const
3077 {
3078   checkConsistency();
3079   mcIdType nbNodes(getNumberOfNodes());
3080   std::vector<bool> fetchedNodes(nbNodes,false);
3081   computeNodeIdsAlg(fetchedNodes);
3082   mcIdType sz(ToIdType(std::count(fetchedNodes.begin(),fetchedNodes.end(),true)));
3083   MCAuto<DataArrayIdType> ret(DataArrayIdType::New()); ret->alloc(sz,1);
3084   mcIdType *retPtr(ret->getPointer());
3085   for(mcIdType i=0;i<nbNodes;i++)
3086     if(fetchedNodes[i])
3087       *retPtr++=i;
3088   return ret.retn();
3089 }
3090
3091 /*!
3092  * Finds nodes not used in any cell and returns an array giving a new id to every node
3093  * by excluding the unused nodes, for which the array holds -1. The result array is
3094  * a mapping in "Old to New" mode. 
3095  *  \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
3096  *  \return DataArrayIdType * - a new instance of DataArrayIdType. Its length is \a
3097  *          this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
3098  *          if the node is unused or a new id else. The caller is to delete this
3099  *          array using decrRef() as it is no more needed.  
3100  *  \throw If the coordinates array is not set.
3101  *  \throw If the nodal connectivity of cells is not defined.
3102  *  \throw If the nodal connectivity includes an invalid id.
3103  *  \sa MEDCoupling1DGTUMesh::computeFetchedNodeIds, areAllNodesFetched
3104  */
3105 DataArrayIdType *MEDCoupling1DGTUMesh::getNodeIdsInUse(mcIdType& nbrOfNodesInUse) const
3106 {
3107   nbrOfNodesInUse=-1;
3108   mcIdType nbOfNodes=getNumberOfNodes();
3109   mcIdType nbOfCells=getNumberOfCells();//checkConsistencyLight
3110   MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
3111   ret->alloc(nbOfNodes,1);
3112   mcIdType *traducer=ret->getPointer();
3113   std::fill(traducer,traducer+nbOfNodes,-1);
3114   const mcIdType *conn=_conn->begin(),*conni(_conn_indx->begin());
3115   for(mcIdType i=0;i<nbOfCells;i++,conni++)
3116     {
3117       mcIdType nbNodesPerCell=conni[1]-conni[0];
3118       for(mcIdType j=0;j<nbNodesPerCell;j++)
3119         {
3120           mcIdType nodeId=conn[conni[0]+j];
3121           if(nodeId==-1) continue;
3122           if(nodeId>=0 && nodeId<nbOfNodes)
3123             traducer[nodeId]=1;
3124           else
3125             {
3126               std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsInUse : In cell #" << i  << " presence of node id " <<  nodeId << " not in [0," << nbOfNodes << ") !";
3127               throw INTERP_KERNEL::Exception(oss.str().c_str());
3128             }
3129         }
3130     }
3131   nbrOfNodesInUse=ToIdType(std::count(traducer,traducer+nbOfNodes,1));
3132   std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
3133   return ret.retn();
3134 }
3135
3136 /*!
3137  * This method renumbers only nodal connectivity in \a this. The renumbering is only an offset applied. So this method is a specialization of
3138  * \a renumberNodesInConn. \b WARNING, this method does not check that the resulting node ids in the nodal connectivity is in a valid range !
3139  *
3140  * \param [in] offset - specifies the offset to be applied on each element of connectivity.
3141  *
3142  * \sa renumberNodesInConn
3143  */
3144 void MEDCoupling1DGTUMesh::renumberNodesWithOffsetInConn(mcIdType offset)
3145 {
3146   getNumberOfCells();//only to check that all is well defined.
3147   //
3148   mcIdType nbOfTuples(_conn->getNumberOfTuples());
3149   mcIdType *pt(_conn->getPointer());
3150   for(mcIdType i=0;i<nbOfTuples;i++,pt++)
3151     {
3152       if(*pt==-1) continue;
3153       *pt+=offset;
3154     }
3155   //
3156   updateTime();
3157 }
3158
3159 /*!
3160  *  Same than renumberNodesInConn(const mcIdType *) except that here the format of old-to-new traducer is using map instead
3161  *  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
3162  *  of a big mesh.
3163  */
3164 void MEDCoupling1DGTUMesh::renumberNodesInConn(const INTERP_KERNEL::HashMap<mcIdType,mcIdType>& newNodeNumbersO2N)
3165 {
3166   this->renumberNodesInConnT< INTERP_KERNEL::HashMap<mcIdType,mcIdType> >(newNodeNumbersO2N);
3167 }
3168
3169 /*!
3170  *  Same than renumberNodesInConn(const mcIdType *) except that here the format of old-to-new traducer is using map instead
3171  *  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
3172  *  of a big mesh.
3173  */
3174 void MEDCoupling1DGTUMesh::renumberNodesInConn(const std::map<mcIdType,mcIdType>& newNodeNumbersO2N)
3175 {
3176   this->renumberNodesInConnT< std::map<mcIdType,mcIdType> >(newNodeNumbersO2N);
3177 }
3178
3179 /*!
3180  * Changes ids of nodes within the nodal connectivity arrays according to a permutation
3181  * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
3182  * This method is a generalization of shiftNodeNumbersInConn().
3183  *  \warning This method performs no check of validity of new ids. **Use it with care !**
3184  *  \param [in] newNodeNumbersO2N - a permutation array, of length \a
3185  *         this->getNumberOfNodes(), in "Old to New" mode. 
3186  *         See \ref numbering for more info on renumbering modes.
3187  *  \throw If the nodal connectivity of cells is not defined.
3188  */
3189 void MEDCoupling1DGTUMesh::renumberNodesInConn(const mcIdType *newNodeNumbersO2N)
3190 {
3191   getNumberOfCells();//only to check that all is well defined.
3192   //
3193   mcIdType nbElemsIn(getNumberOfNodes()),nbOfTuples(_conn->getNumberOfTuples());
3194   mcIdType *pt(_conn->getPointer());
3195   for(mcIdType i=0;i<nbOfTuples;i++,pt++)
3196     {
3197       if(*pt==-1) continue;
3198       if(*pt>=0 && *pt<nbElemsIn)
3199         *pt=newNodeNumbersO2N[*pt];
3200       else
3201         {
3202           std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberNodesInConn : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn;
3203           throw INTERP_KERNEL::Exception(oss.str().c_str());
3204         }
3205     }
3206   //
3207   updateTime();
3208 }
3209
3210 /*!
3211  * Keeps from \a this only cells which constituing point id are in the ids specified by [\a begin,\a end).
3212  * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
3213  * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not.
3214  * If \a fullyIn is true only cells whose ids are \b fully contained in [\a begin,\a end) tab will be kept.
3215  *
3216  * \param [in] begin input start of array of node ids.
3217  * \param [in] end input end of array of node ids.
3218  * \param [in] fullyIn input that specifies if all node ids must be in [\a begin,\a end) array to consider cell to be in.
3219  * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end.
3220  */
3221 void MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds(const mcIdType *begin, const mcIdType *end, bool fullyIn, DataArrayIdType *&cellIdsKeptArr) const
3222 {
3223   mcIdType nbOfCells=getNumberOfCells();
3224   MCAuto<DataArrayIdType> cellIdsKept=DataArrayIdType::New(); cellIdsKept->alloc(0,1);
3225   mcIdType tmp=-1;
3226   mcIdType sz=_conn->getMaxValue(tmp); sz=std::max(sz,ToIdType(0))+1;
3227   std::vector<bool> fastFinder(sz,false);
3228   for(const mcIdType *work=begin;work!=end;work++)
3229     if(*work>=0 && *work<sz)
3230       fastFinder[*work]=true;
3231   const mcIdType *conn=_conn->begin(),*conni=_conn_indx->begin();
3232   for(mcIdType i=0;i<nbOfCells;i++,conni++)
3233     {
3234       int ref=0,nbOfHit=0;
3235       mcIdType nbNodesPerCell=conni[1]-conni[0];
3236       if(nbNodesPerCell>=0)
3237         {
3238           for(mcIdType j=0;j<nbNodesPerCell;j++)
3239             {
3240               mcIdType nodeId=conn[conni[0]+j];
3241               if(nodeId>=0)
3242                 {
3243                   ref++;
3244                   if(fastFinder[nodeId])
3245                     nbOfHit++;
3246                 }
3247             }
3248         }
3249       else
3250         {
3251           std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds : invalid index array for cell #" << i << " !";
3252           throw INTERP_KERNEL::Exception(oss.str().c_str());
3253         }
3254       if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn))
3255         cellIdsKept->pushBackSilent(i);
3256     }
3257   cellIdsKeptArr=cellIdsKept.retn();
3258 }
3259
3260 void MEDCoupling1DGTUMesh::allocateCells(mcIdType nbOfCells)
3261 {
3262   if(nbOfCells<0)
3263     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::allocateCells : the input number of cells should be >= 0 !");
3264   _conn=DataArrayIdType::New();
3265   _conn->reserve(nbOfCells*3);
3266   _conn_indx=DataArrayIdType::New();
3267   _conn_indx->reserve(nbOfCells+1); _conn_indx->pushBackSilent(0);
3268   declareAsNew();
3269 }
3270
3271 /*!
3272  * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ).
3273  *
3274  * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add.
3275  * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
3276  * \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
3277  *        attached to \a this.
3278  * \throw If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
3279  */
3280 void MEDCoupling1DGTUMesh::insertNextCell(const mcIdType *nodalConnOfCellBg, const mcIdType *nodalConnOfCellEnd)
3281 {
3282   std::size_t sz(std::distance(nodalConnOfCellBg,nodalConnOfCellEnd));
3283   DataArrayIdType *c(_conn),*c2(_conn_indx);
3284   if(c && c2)
3285     {
3286       mcIdType pos=c2->back();
3287       if(pos==c->getNumberOfTuples())
3288         {
3289           c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd);
3290           c2->pushBackSilent(pos+ToIdType(sz));
3291         }
3292       else
3293         {
3294           std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::insertNextCell : The nodal index array (end=" << pos << ") mismatches with nodal array (length=" << c->getNumberOfTuples() << ") !";
3295           throw INTERP_KERNEL::Exception(oss.str().c_str());
3296         }
3297     }
3298   else
3299     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1DGTUMesh::allocateCells before !");
3300 }
3301
3302 void MEDCoupling1DGTUMesh::setNodalConnectivity(DataArrayIdType *nodalConn, DataArrayIdType *nodalConnIndex)
3303 {
3304   if(nodalConn)
3305     nodalConn->incrRef();
3306   _conn=nodalConn;
3307   if(nodalConnIndex)
3308     nodalConnIndex->incrRef();
3309   _conn_indx=nodalConnIndex;
3310   declareAsNew();
3311 }
3312
3313 /*!
3314  * \return DataArrayIdType * - the internal reference to the nodal connectivity. The caller is not responsible to deallocate it.
3315  */
3316 DataArrayIdType *MEDCoupling1DGTUMesh::getNodalConnectivity() const
3317 {
3318   const DataArrayIdType *ret(_conn);
3319   return const_cast<DataArrayIdType *>(ret);
3320 }
3321
3322 /*!
3323  * \return DataArrayIdType * - the internal reference to the nodal connectivity index. The caller is not responsible to deallocate it.
3324  */
3325 DataArrayIdType *MEDCoupling1DGTUMesh::getNodalConnectivityIndex() const
3326 {
3327   const DataArrayIdType *ret(_conn_indx);
3328   return const_cast<DataArrayIdType *>(ret);
3329 }
3330
3331 /*!
3332  * See the definition of the nodal connectivity pack \ref MEDCoupling1DGTUMesh::isPacked "here".
3333  * This method tries to build a new instance geometrically equivalent to \a this, by limiting at most the number of new object (nodal connectivity).
3334  * 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.
3335  *
3336  * 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.
3337  * 
3338  * \param [out] isShallowCpyOfNodalConnn - tells if the returned instance share the same pair of nodal connectivity arrays (true) or if nodal
3339  *              connectivity arrays are different (false)
3340  * \return a new object to be managed by the caller.
3341  * 
3342  * \sa MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity, MEDCoupling1DGTUMesh::isPacked
3343  */
3344 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::copyWithNodalConnectivityPacked(bool& isShallowCpyOfNodalConnn) const
3345 {
3346   MCAuto<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
3347   DataArrayIdType *nc=0,*nci=0;
3348   isShallowCpyOfNodalConnn=retrievePackedNodalConnectivity(nc,nci);
3349   MCAuto<DataArrayIdType> ncs(nc),ncis(nci);
3350   ret->_conn=ncs; ret->_conn_indx=ncis;
3351   ret->setCoords(getCoords());
3352   return ret.retn();
3353 }
3354
3355 /*!
3356  * This method allows to compute, if needed, the packed nodal connectivity pair.
3357  * Indeed, it is possible to store in \a this a nodal connectivity array bigger than ranges covered by nodal connectivity index array.
3358  * 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.
3359  * 
3360  * 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)
3361  * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
3362  *
3363  * 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
3364  * will be returned.
3365  * 
3366  * This method return 3 elements.
3367  * \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
3368  *                          this pointer can be seen as a new object, that is to managed by the caller.
3369  * \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
3370  *                              this pointer can be seen as a new object, that is to managed by the caller.
3371  * \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
3372  * output parameters are newly created objects.
3373  *
3374  * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkConsistencyLight test
3375  */
3376 bool MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity(DataArrayIdType *&nodalConn, DataArrayIdType *&nodalConnIndx) const
3377 {
3378   if(isPacked())//performs the checkConsistencyLight
3379     {
3380       const DataArrayIdType *c0(_conn),*c1(_conn_indx);
3381       nodalConn=const_cast<DataArrayIdType *>(c0); nodalConnIndx=const_cast<DataArrayIdType *>(c1);
3382       nodalConn->incrRef(); nodalConnIndx->incrRef();
3383       return true;
3384     }
3385   mcIdType bg=_conn_indx->front(),end=_conn_indx->back();
3386   MCAuto<DataArrayIdType> nc(_conn->selectByTupleIdSafeSlice(bg,end,1));
3387   MCAuto<DataArrayIdType> nci(_conn_indx->deepCopy());
3388   nci->applyLin(1,-bg);
3389   nodalConn=nc.retn(); nodalConnIndx=nci.retn();
3390   return false;
3391 }
3392
3393 /*
3394  * 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)
3395  * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
3396  * If nodal connectivity index points to a subpart of nodal connectivity index false will be returned.
3397  * \return bool - true if \a this looks packed, false is not.
3398  *
3399  * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkConsistencyLight test
3400  */
3401 bool MEDCoupling1DGTUMesh::isPacked() const
3402 {
3403   checkConsistencyLight();
3404   return _conn_indx->front()==0 && _conn_indx->back()==_conn->getNumberOfTuples();
3405 }
3406
3407 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(const MEDCoupling1DGTUMesh *mesh1, const MEDCoupling1DGTUMesh *mesh2)
3408 {
3409   std::vector<const MEDCoupling1DGTUMesh *> tmp(2);
3410   tmp[0]=const_cast<MEDCoupling1DGTUMesh *>(mesh1); tmp[1]=const_cast<MEDCoupling1DGTUMesh *>(mesh2);
3411   return Merge1DGTUMeshes(tmp);
3412 }
3413
3414 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(std::vector<const MEDCoupling1DGTUMesh *>& a)
3415 {
3416   std::size_t sz=a.size();
3417   if(sz==0)
3418     return Merge1DGTUMeshesLL(a);
3419   for(std::size_t ii=0;ii<sz;ii++)
3420     if(!a[ii])
3421       {
3422         std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::Merge1DGTUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !";
3423         throw INTERP_KERNEL::Exception(oss.str().c_str());
3424       }
3425   const INTERP_KERNEL::CellModel *cm=&(a[0]->getCellModel());
3426   for(std::size_t ii=0;ii<sz;ii++)
3427     if(&(a[ii]->getCellModel())!=cm)
3428       throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : all items must have the same geo type !");
3429   std::vector< MCAuto<MEDCoupling1DGTUMesh> > bb(sz);
3430   std::vector< const MEDCoupling1DGTUMesh * > aa(sz);
3431   std::size_t spaceDimUndef=-3, spaceDim=spaceDimUndef;
3432   for(std::size_t i=0;i<sz && spaceDim==spaceDimUndef;i++)
3433     {
3434       const MEDCoupling1DGTUMesh *cur=a[i];
3435       const DataArrayDouble *coo=cur->getCoords();
3436       if(coo)
3437         spaceDim=coo->getNumberOfComponents();
3438     }
3439   if(spaceDim==spaceDimUndef)
3440     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : no spaceDim specified ! unable to perform merge !");
3441   for(std::size_t i=0;i<sz;i++)
3442     {
3443       bb[i]=a[i]->buildSetInstanceFromThis(spaceDim);
3444       aa[i]=bb[i];
3445     }
3446   return Merge1DGTUMeshesLL(aa);
3447 }
3448
3449 /*!
3450  * \throw If presence of a null instance in the input vector \a a.
3451  * \throw If a is empty
3452  */
3453 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords(std::vector<const MEDCoupling1DGTUMesh *>& a)
3454 {
3455   if(a.empty())
3456     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : input array must be NON EMPTY !");
3457   std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin();
3458   if(!(*it))
3459     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : null instance in the first element of input vector !");
3460   std::vector< MCAuto<MEDCoupling1DGTUMesh> > objs(a.size());
3461   std::vector<const DataArrayIdType *> ncs(a.size()),ncis(a.size());
3462   (*it)->getNumberOfCells();//to check that all is OK
3463   const DataArrayDouble *coords=(*it)->getCoords();
3464   const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
3465   bool tmp;
3466   objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp);
3467   ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex();
3468   it++;
3469   for(int i=1;it!=a.end();i++,it++)
3470     {
3471       if(!(*it))
3472         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : presence of null instance !");
3473       if(cm!=&((*it)->getCellModel()))
3474         throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !");
3475       (*it)->getNumberOfCells();//to check that all is OK
3476       objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp);
3477       ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex();
3478       if(coords!=(*it)->getCoords())
3479         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : not lying on same coords !");
3480     }
3481   MCAuto<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm));
3482   ret->setCoords(coords);
3483   ret->_conn=DataArrayIdType::Aggregate(ncs);
3484   ret->_conn_indx=DataArrayIdType::AggregateIndexes(ncis);
3485   return ret.retn();
3486 }
3487
3488 /*!
3489  * 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)
3490  */
3491 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesLL(std::vector<const MEDCoupling1DGTUMesh *>& a)
3492 {
3493   if(a.empty())
3494     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : input array must be NON EMPTY !");
3495   std::vector< MCAuto<MEDCoupling1DGTUMesh> > objs(a.size());
3496   std::vector<const DataArrayIdType *> ncs(a.size()),ncis(a.size());
3497   std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin();
3498   std::vector<mcIdType> nbNodesPerElt(a.size());
3499   std::size_t nbOfCells=(*it)->getNumberOfCells();
3500   bool tmp;
3501   objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp);
3502   ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex();
3503   nbNodesPerElt[0]=0;
3504   mcIdType prevNbOfNodes=(*it)->getNumberOfNodes();
3505   const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
3506   it++;
3507   for(int i=1;it!=a.end();i++,it++)
3508     {
3509       if(cm!=&((*it)->getCellModel()))
3510         throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !");
3511       objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp);
3512       ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex();
3513       nbOfCells+=(*it)->getNumberOfCells();
3514       nbNodesPerElt[i]=nbNodesPerElt[i-1]+prevNbOfNodes;
3515       prevNbOfNodes=(*it)->getNumberOfNodes();
3516     }
3517   std::vector<const MEDCouplingPointSet *> aps(a.size());
3518   std::copy(a.begin(),a.end(),aps.begin());
3519   MCAuto<DataArrayDouble> pts=MergeNodesArray(aps);
3520   MCAuto<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm));
3521   ret->setCoords(pts);
3522   ret->_conn=AggregateNodalConnAndShiftNodeIds(ncs,nbNodesPerElt);
3523   ret->_conn_indx=DataArrayIdType::AggregateIndexes(ncis);
3524   return ret.retn();
3525 }
3526
3527 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::buildSetInstanceFromThis(std::size_t spaceDim) const
3528 {
3529   MCAuto<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
3530   MCAuto<DataArrayIdType> tmp1,tmp2;
3531   const DataArrayIdType *nodalConn(_conn),*nodalConnI(_conn_indx);
3532   if(!nodalConn)
3533     {
3534       tmp1=DataArrayIdType::New(); tmp1->alloc(0,1);
3535     }
3536   else
3537     tmp1=_conn;
3538   ret->_conn=tmp1;
3539   //
3540   if(!nodalConnI)
3541     {
3542       tmp2=DataArrayIdType::New(); tmp2->alloc(1,1); tmp2->setIJ(0,0,0);
3543     }
3544   else
3545     tmp2=_conn_indx;
3546   ret->_conn_indx=tmp2;
3547   //
3548   if(!_coords)
3549     {
3550       MCAuto<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim);
3551       ret->setCoords(coords);
3552     }
3553   else
3554     ret->setCoords(_coords);
3555   return ret.retn();
3556 }
3557
3558 /*!
3559  * This method aggregate the bbox of each cell and put it into bbox parameter.
3560  * 
3561  * \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)
3562  *                         For all other cases this input parameter is ignored.
3563  * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components.
3564  * 
3565  * \throw If \a this is not fully set (coordinates and connectivity).
3566  * \throw If a cell in \a this has no valid nodeId.
3567  */
3568 DataArrayDouble *MEDCoupling1DGTUMesh::getBoundingBoxForBBTree(double arcDetEps) const
3569 {
3570   checkFullyDefined();
3571   mcIdType spaceDim(getSpaceDimension()),nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes());
3572   MCAuto<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim);
3573   double *bbox(ret->getPointer());
3574   for(mcIdType i=0;i<nbOfCells*spaceDim;i++)
3575     {
3576       bbox[2*i]=std::numeric_limits<double>::max();
3577       bbox[2*i+1]=-std::numeric_limits<double>::max();
3578     }
3579   const double *coordsPtr(_coords->getConstPointer());
3580   const mcIdType *conn(_conn->getConstPointer()),*connI(_conn_indx->getConstPointer());
3581   for(mcIdType i=0;i<nbOfCells;i++)
3582     {
3583       mcIdType offset=connI[i];
3584       mcIdType nbOfNodesForCell(connI[i+1]-offset),kk(0);
3585       for(mcIdType j=0;j<nbOfNodesForCell;j++)
3586         {
3587           mcIdType nodeId=conn[offset+j];
3588           if(nodeId>=0 && nodeId<nbOfNodes)
3589             {
3590               for(int k=0;k<spaceDim;k++)
3591                 {
3592                   bbox[2*spaceDim*i+2*k]=std::min(bbox[2*spaceDim*i+2*k],coordsPtr[spaceDim*nodeId+k]);
3593                   bbox[2*spaceDim*i+2*k+1]=std::max(bbox[2*spaceDim*i+2*k+1],coordsPtr[spaceDim*nodeId+k]);
3594                 }
3595               kk++;
3596             }
3597         }
3598       if(kk==0)
3599         {
3600           std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getBoundingBoxForBBTree : cell #" << i << " contains no valid nodeId !";
3601           throw INTERP_KERNEL::Exception(oss.str().c_str());
3602         }
3603     }
3604   return ret.retn();
3605 }
3606
3607 /*!
3608  * 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.
3609  *
3610  * \return a new instance of field containing the result. The returned instance has to be deallocated by the caller.
3611  */
3612 MEDCouplingFieldDouble *MEDCoupling1DGTUMesh::computeDiameterField() const
3613 {
3614   throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::computeDiameterField : not implemented yet for dynamic types !");
3615 }
3616
3617 std::vector<mcIdType> MEDCoupling1DGTUMesh::BuildAPolygonFromParts(const std::vector< std::vector<mcIdType> >& parts)
3618 {
3619   std::vector<mcIdType> ret;
3620   if(parts.empty())
3621     return ret;
3622   ret.insert(ret.end(),parts[0].begin(),parts[0].end());
3623   mcIdType ref(ret.back());
3624   std::size_t sz(parts.size()),nbh(1);
3625   std::vector<bool> b(sz,true); b[0]=false;
3626   while(nbh<sz)
3627     {
3628       std::size_t i(0);
3629       for(;i<sz;i++) if(b[i] && parts[i].front()==ref) { ret.insert(ret.end(),parts[i].begin()+1,parts[i].end()); nbh++; break; }
3630       if(i<sz)
3631         ref=ret.back();
3632       else
3633         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::BuildAPolygonFromParts : the input vector is not a part of a single polygon !");
3634     }
3635   if(ret.back()==ret.front())
3636     ret.pop_back();
3637   return ret;
3638 }
3639
3640 /*!
3641  * This method invert orientation of all cells in \a this. 
3642  * After calling this method the absolute value of measure of cells in \a this are the same than before calling.
3643  * This method only operates on the connectivity so coordinates are not touched at all.
3644  */
3645 void MEDCoupling1DGTUMesh::invertOrientationOfAllCells()
3646 {
3647   checkConsistencyOfConnectivity();
3648   INTERP_KERNEL::AutoCppPtr<INTERP_KERNEL::OrientationInverter> oi(INTERP_KERNEL::OrientationInverter::BuildInstanceFrom(getCellModelEnum()));
3649   mcIdType nbCells=getNumberOfCells();
3650   const mcIdType *connI(_conn_indx->begin());
3651   mcIdType *conn(_conn->getPointer());
3652   for(mcIdType i=0;i<nbCells;i++)
3653     oi->operate(conn+connI[i],conn+connI[i+1]);
3654   updateTime();
3655 }
3656
3657 /*!
3658  * This method performs an aggregation of \a nodalConns (as DataArrayIdType::Aggregate does) but in addition of that a shift is applied on the 
3659  * values contained in \a nodalConns using corresponding offset specified in input \a offsetInNodeIdsPerElt.
3660  * But it also manage the values -1, that have a semantic in MEDCoupling1DGTUMesh class (separator for polyhedron).
3661  *
3662  * \param [in] nodalConns - a list of nodal connectivity arrays same size than \a offsetInNodeIdsPerElt.
3663  * \param [in] offsetInNodeIdsPerElt - a list of offsets to apply.
3664  * \return DataArrayIdType * - A new object (to be managed by the caller) that is the result of the aggregation.
3665  * \throw If \a nodalConns or \a offsetInNodeIdsPerElt are empty.
3666  * \throw If \a nodalConns and \a offsetInNodeIdsPerElt have not the same size.
3667  * \throw If presence of null pointer in \a nodalConns.
3668  * \throw If presence of not allocated or array with not exactly one component in \a nodalConns.
3669  */
3670 DataArrayIdType *MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds(const std::vector<const DataArrayIdType *>& nodalConns, const std::vector<mcIdType>& offsetInNodeIdsPerElt)
3671 {
3672   std::size_t sz1(nodalConns.size()),sz2(offsetInNodeIdsPerElt.size());
3673   if(sz1!=sz2)
3674     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : input vectors do not have the same size !");
3675   if(sz1==0)
3676     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : empty vectors in input !");
3677   mcIdType nbOfTuples=0;
3678   for(std::vector<const DataArrayIdType *>::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++)
3679     {
3680       if(!(*it))
3681         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of null pointer in input vector !");
3682       if(!(*it)->isAllocated())
3683         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of non allocated array in input vector !");
3684       if((*it)->getNumberOfComponents()!=1)
3685         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of array with not exactly one component !");
3686       nbOfTuples+=(*it)->getNumberOfTuples();
3687     }
3688   MCAuto<DataArrayIdType> ret=DataArrayIdType::New(); ret->alloc(nbOfTuples,1);
3689   mcIdType *pt=ret->getPointer();
3690   mcIdType i=0;
3691   for(std::vector<const DataArrayIdType *>::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++,i++)
3692     {
3693       mcIdType curNbt=(*it)->getNumberOfTuples();
3694       const mcIdType *inPt=(*it)->begin();
3695       mcIdType offset=offsetInNodeIdsPerElt[i];
3696       for(mcIdType j=0;j<curNbt;j++,pt++)
3697         {
3698           if(inPt[j]!=-1)
3699             *pt=inPt[j]+offset;
3700           else
3701             *pt=-1;
3702         }
3703     }
3704   return ret.retn();
3705 }
3706
3707 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const MEDCouplingUMesh *m)
3708 {
3709   if(!m)
3710     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : input mesh is null !");
3711   std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes());
3712   if(gts.size()!=1)
3713     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : input mesh must have exactly one geometric type !");
3714   mcIdType geoType(ToIdType(*gts.begin()));
3715   MCAuto<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(m->getName(),*gts.begin()));
3716   ret->setCoords(m->getCoords()); ret->setDescription(m->getDescription());
3717   mcIdType nbCells=m->getNumberOfCells();
3718   MCAuto<DataArrayIdType> conn(DataArrayIdType::New()),connI(DataArrayIdType::New());
3719   conn->alloc(m->getNodalConnectivityArrayLen()-nbCells,1); connI->alloc(nbCells+1,1);
3720   mcIdType *c(conn->getPointer()),*ci(connI->getPointer()); *ci=0;
3721   const mcIdType *cin(m->getNodalConnectivity()->begin()),*ciin(m->getNodalConnectivityIndex()->begin());
3722   for(mcIdType i=0;i<nbCells;i++,ciin++,ci++)
3723     {
3724       if(cin[ciin[0]]==geoType)
3725         {
3726           if(ciin[1]-ciin[0]>=1)
3727             {
3728               c=std::copy(cin+ciin[0]+1,cin+ciin[1],c);
3729               ci[1]=ci[0]+ciin[1]-ciin[0]-1;
3730             }
3731           else
3732             {
3733               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 !";
3734               throw INTERP_KERNEL::Exception(oss.str().c_str());
3735             }
3736         }
3737       else
3738         {
3739           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 !";
3740           throw INTERP_KERNEL::Exception(oss.str().c_str());
3741         }
3742     }
3743   ret->setNodalConnectivity(conn,connI);
3744   return ret.retn();
3745 }