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