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