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