Salome HOME
Addition of the 2 new unstructured mesh types.
[modules/med.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 /*!
1372  * Checks if \a this and \a other meshes are geometrically equivalent with high
1373  * probability, else an exception is thrown. The meshes are considered equivalent if
1374  * (1) meshes contain the same number of nodes and the same number of elements of the
1375  * same types (2) three cells of the two meshes (first, last and middle) are based
1376  * on coincident nodes (with a specified precision).
1377  *  \param [in] other - the mesh to compare with.
1378  *  \param [in] prec - the precision used to compare nodes of the two meshes.
1379  *  \throw If the two meshes do not match.
1380  */
1381 void MEDCoupling1SGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception)
1382 {
1383   MEDCouplingPointSet::checkFastEquivalWith(other,prec);
1384   const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
1385   if(!otherC)
1386     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : Two meshes are not unstructured with single static geometric type !");
1387   const DataArrayInt *c1(_conn),*c2(otherC->_conn);
1388   if(c1==c2)
1389     return;
1390   if(!c1 || !c2)
1391     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !");
1392   if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
1393     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !");
1394   if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
1395     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !");
1396   if(c1->getHashCode()!=c2->getHashCode())
1397     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : nodal connectivity differs");
1398 }
1399
1400 MEDCouplingPointSet *MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const
1401 {
1402   if(!other)
1403     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : input other is null !");
1404   const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
1405   if(!otherC)
1406     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !");
1407   std::vector<const MEDCoupling1SGTUMesh *> ms(2);
1408   ms[0]=this;
1409   ms[1]=otherC;
1410   return Merge1SGTUMeshesOnSameCoords(ms);
1411 }
1412
1413 void MEDCoupling1SGTUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const throw(INTERP_KERNEL::Exception)
1414 {
1415   checkFullyDefined();
1416   int nbOfNodes=getNumberOfNodes();
1417   int *revNodalIndxPtr=(int *)malloc((nbOfNodes+1)*sizeof(int));
1418   revNodalIndx->useArray(revNodalIndxPtr,true,C_DEALLOC,nbOfNodes+1,1);
1419   std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
1420   const int *conn=_conn->begin();
1421   int nbOfCells=getNumberOfCells();
1422   int nbOfEltsInRevNodal=0;
1423   int nbOfNodesPerCell=getNumberOfNodesPerCell();
1424   for(int eltId=0;eltId<nbOfCells;eltId++)
1425     {
1426       for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1427         {
1428           if(conn[0]>=0 && conn[0]<nbOfNodes)
1429             {
1430               nbOfEltsInRevNodal++;
1431               revNodalIndxPtr[conn[0]+1]++;
1432             }
1433           else
1434             {
1435               std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !";
1436               throw INTERP_KERNEL::Exception(oss.str().c_str());
1437             }
1438         }
1439     }
1440   std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<int>());
1441   conn=_conn->begin();
1442   int *revNodalPtr=(int *)malloc((nbOfEltsInRevNodal)*sizeof(int));
1443   revNodal->useArray(revNodalPtr,true,C_DEALLOC,nbOfEltsInRevNodal,1);
1444   std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
1445   for(int eltId=0;eltId<nbOfCells;eltId++)
1446     {
1447       for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1448         {
1449           *std::find_if(revNodalPtr+revNodalIndxPtr[*conn],revNodalPtr+revNodalIndxPtr[*conn+1],std::bind2nd(std::equal_to<int>(),-1))=eltId;
1450         }
1451     }
1452 }
1453
1454 /*!
1455  * Use \a nodalConn array as nodal connectivity of \a this. The input \a nodalConn pointer can be null.
1456  */
1457 void MEDCoupling1SGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn) throw(INTERP_KERNEL::Exception)
1458 {
1459   if(nodalConn)
1460     nodalConn->incrRef();
1461   _conn=nodalConn;
1462   declareAsNew();
1463 }
1464
1465 /*!
1466  * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it.
1467  */
1468 DataArrayInt *MEDCoupling1SGTUMesh::getNodalConnectivity() const throw(INTERP_KERNEL::Exception)
1469 {
1470   const DataArrayInt *ret(_conn);
1471   return const_cast<DataArrayInt *>(ret);
1472 }
1473
1474 /*!
1475  * Allocates memory to store an estimation of the given number of cells. Closer is the estimation to the number of cells effectively inserted,
1476  * less will be the needs to realloc. If the number of cells to be inserted is not known simply put 0 to this parameter.
1477  * If a nodal connectivity previouly existed before the call of this method, it will be reset.
1478  *
1479  *  \param [in] nbOfCells - estimation of the number of cell \a this mesh will contain.
1480  */
1481 void MEDCoupling1SGTUMesh::allocateCells(int nbOfCells) throw(INTERP_KERNEL::Exception)
1482 {
1483   if(nbOfCells<0)
1484     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::allocateCells : the input number of cells should be >= 0 !");
1485   _conn=DataArrayInt::New();
1486   _conn->reserve(getNumberOfNodesPerCell()*nbOfCells);
1487   declareAsNew();
1488 }
1489
1490 /*!
1491  * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ).
1492  *
1493  * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add.
1494  * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
1495  * \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
1496  *        attached to \a this.
1497  * \thow If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
1498  */
1499 void MEDCoupling1SGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd) throw(INTERP_KERNEL::Exception)
1500 {
1501   int sz=(int)std::distance(nodalConnOfCellBg,nodalConnOfCellEnd);
1502   int ref=getNumberOfNodesPerCell();
1503   if(sz==ref)
1504     {
1505       DataArrayInt *c(_conn);
1506       if(c)
1507         c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd);
1508       else
1509         throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1SGTUMesh::allocateCells before !");
1510     }
1511   else
1512     {
1513       std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::insertNextCell : input nodal size (" << sz << ") does not match number of nodes per cell of this (";
1514       oss << ref << ") !";
1515       throw INTERP_KERNEL::Exception(oss.str().c_str());
1516     }
1517 }
1518
1519 /*!
1520  * This method builds the dual mesh of \a this and returns it.
1521  * 
1522  * \return MEDCoupling1SGTUMesh * - newly object created to be managed by the caller.
1523  * \throw If \a this is not a mesh containing only simplex cells.
1524  * \throw If \a this is not correctly allocated (coordinates and connectivities have to be correctly set !).
1525  * \throw If at least one node in \a this is orphan (without any simplex cell lying on it !)
1526  */
1527 MEDCoupling1GTUMesh *MEDCoupling1SGTUMesh::computeDualMesh() const throw(INTERP_KERNEL::Exception)
1528 {
1529   const INTERP_KERNEL::CellModel& cm(getCellModel());
1530   if(!cm.isSimplex())
1531     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh : this mesh is not a simplex mesh ! Please invoke simplexize of tetrahedrize on this before calling this method !");
1532   switch(getMeshDimension())
1533     {
1534     case 3:
1535       return computeDualMesh3D();
1536     case 2:
1537       return computeDualMesh2D();
1538     default:
1539       throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh : meshdimension must be in [2,3] !");
1540     }
1541 }
1542
1543 MEDCoupling1DGTUMesh *MEDCoupling1SGTUMesh::computeDualMesh3D() const throw(INTERP_KERNEL::Exception)
1544 {
1545   static const int DUAL_TETRA_0[36]={
1546     4,1,0, 6,0,3, 7,3,1,
1547     4,0,1, 5,2,0, 8,1,2,
1548     6,3,0, 5,0,2, 9,2,3,
1549     7,1,3, 9,3,2, 8,2,1
1550   };
1551   static const int DUAL_TETRA_1[36]={
1552     8,4,10, 11,5,8, 10,7,11,
1553     9,4,8, 8,5,12, 12,6,9,
1554     10,4,9, 9,6,13, 13,7,10,
1555     12,5,11, 13,6,12, 11,7,13
1556   };
1557   static const int FACEID_NOT_SH_NODE[4]={2,3,1,0};
1558   if(getCellModelEnum()!=INTERP_KERNEL::NORM_TETRA4)
1559     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh3D : only TETRA4 supported !");
1560   checkFullyDefined();
1561   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> thisu(buildUnstructured());
1562   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revNodArr(DataArrayInt::New()),revNodIArr(DataArrayInt::New());
1563   thisu->getReverseNodalConnectivity(revNodArr,revNodIArr);
1564   const int *revNod(revNodArr->begin()),*revNodI(revNodIArr->begin()),*nodal(_conn->begin());
1565   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d1Arr(DataArrayInt::New()),di1Arr(DataArrayInt::New()),rd1Arr(DataArrayInt::New()),rdi1Arr(DataArrayInt::New());
1566   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> edges(thisu->explode3DMeshTo1D(d1Arr,di1Arr,rd1Arr,rdi1Arr));
1567   const int *d1(d1Arr->begin());
1568   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d2Arr(DataArrayInt::New()),di2Arr(DataArrayInt::New()),rd2Arr(DataArrayInt::New()),rdi2Arr(DataArrayInt::New());
1569   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> faces(thisu->buildDescendingConnectivity(d2Arr,di2Arr,rd2Arr,rdi2Arr));  thisu=0;
1570   const int *d2(d2Arr->begin()),*rd2(rd2Arr->begin()),*rdi2(rdi2Arr->begin());
1571   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> edgesBaryArr(edges->getBarycenterAndOwner()),facesBaryArr(faces->getBarycenterAndOwner()),baryArr(getBarycenterAndOwner());
1572   const int nbOfNodes(getNumberOfNodes()),offset0(nbOfNodes+faces->getNumberOfCells()),offset1(offset0+edges->getNumberOfCells());
1573   edges=0; faces=0;
1574   std::vector<const DataArrayDouble *> v(4); v[0]=getCoords(); v[1]=facesBaryArr; v[2]=edgesBaryArr; v[3]=baryArr;
1575   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> zeArr(DataArrayDouble::Aggregate(v)); baryArr=0; edgesBaryArr=0; facesBaryArr=0;
1576   std::string name("DualOf_"); name+=getName();
1577   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(name.c_str(),INTERP_KERNEL::NORM_POLYHED)); ret->setCoords(zeArr);
1578   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),ciArr(DataArrayInt::New()); ciArr->alloc(nbOfNodes+1,1); ciArr->setIJ(0,0,0); cArr->alloc(0,1);
1579   for(int i=0;i<nbOfNodes;i++,revNodI++)
1580     {
1581       int nbOfCellsSharingNode(revNodI[1]-revNodI[0]);
1582       if(nbOfCellsSharingNode==0)
1583         {
1584           std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeDualMesh3D : Node #" << i << " is orphan !"; 
1585           throw INTERP_KERNEL::Exception(oss.str().c_str());
1586         }
1587       for(int j=0;j<nbOfCellsSharingNode;j++)
1588         {
1589           int curCellId(revNod[revNodI[0]+j]);
1590           const int *connOfCurCell(nodal+4*curCellId);
1591           std::size_t nodePosInCurCell(std::distance(connOfCurCell,std::find(connOfCurCell,connOfCurCell+4,i)));
1592           if(j!=0) cArr->pushBackSilent(-1);
1593           int tmp[14];
1594           //
1595           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;
1596           tmp[2]=curCellId+offset1; tmp[3]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+2]]+nbOfNodes;
1597           tmp[4]=-1;
1598           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;
1599           tmp[7]=curCellId+offset1; tmp[8]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+5]]+nbOfNodes;
1600           tmp[9]=-1;
1601           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;
1602           tmp[12]=curCellId+offset1; tmp[13]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+8]]+nbOfNodes;
1603           cArr->insertAtTheEnd(tmp,tmp+14);
1604           int kk(0);
1605           for(int k=0;k<4;k++)
1606             {
1607               if(FACEID_NOT_SH_NODE[nodePosInCurCell]!=k)
1608                 {
1609                   const int *faceId(d2+4*curCellId+k);
1610                   if(rdi2[*faceId+1]-rdi2[*faceId]==1)
1611                     {
1612                       int tmp2[5]; tmp2[0]=-1; tmp2[1]=i;
1613                       tmp2[2]=d1[6*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+0]-8]+offset0;
1614                       tmp2[3]=d2[4*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+1]-4]+nbOfNodes;
1615                       tmp2[4]=d1[6*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+2]-8]+offset0;
1616                       cArr->insertAtTheEnd(tmp2,tmp2+5);
1617                     }
1618                   kk++;
1619                 }
1620             }
1621         }
1622       ciArr->setIJ(i+1,0,cArr->getNumberOfTuples());
1623     }
1624   ret->setNodalConnectivity(cArr,ciArr);
1625   return ret.retn();
1626 }
1627
1628 MEDCoupling1DGTUMesh *MEDCoupling1SGTUMesh::computeDualMesh2D() const throw(INTERP_KERNEL::Exception)
1629 {
1630   static const int DUAL_TRI_0[6]={0,2, 1,0, 2,1};
1631   static const int DUAL_TRI_1[6]={-3,+5, +3,-4, +4,-5};
1632   static const int FACEID_NOT_SH_NODE[3]={1,2,0};
1633   if(getCellModelEnum()!=INTERP_KERNEL::NORM_TRI3)
1634     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh2D : only TRI3 supported !");
1635   checkFullyDefined();
1636   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> thisu(buildUnstructured());
1637   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revNodArr(DataArrayInt::New()),revNodIArr(DataArrayInt::New());
1638   thisu->getReverseNodalConnectivity(revNodArr,revNodIArr);
1639   const int *revNod(revNodArr->begin()),*revNodI(revNodIArr->begin()),*nodal(_conn->begin());
1640   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d2Arr(DataArrayInt::New()),di2Arr(DataArrayInt::New()),rd2Arr(DataArrayInt::New()),rdi2Arr(DataArrayInt::New());
1641   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> edges(thisu->buildDescendingConnectivity(d2Arr,di2Arr,rd2Arr,rdi2Arr));  thisu=0;
1642   const int *d2(d2Arr->begin()),*rd2(rd2Arr->begin()),*rdi2(rdi2Arr->begin());
1643   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> edgesBaryArr(edges->getBarycenterAndOwner()),baryArr(getBarycenterAndOwner());
1644   const int nbOfNodes(getNumberOfNodes()),offset0(nbOfNodes+edges->getNumberOfCells());
1645   edges=0;
1646   std::vector<const DataArrayDouble *> v(3); v[0]=getCoords(); v[1]=edgesBaryArr; v[2]=baryArr;
1647   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> zeArr(DataArrayDouble::Aggregate(v)); baryArr=0; edgesBaryArr=0;
1648   std::string name("DualOf_"); name+=getName();
1649   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(name.c_str(),INTERP_KERNEL::NORM_POLYGON)); ret->setCoords(zeArr);
1650   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),ciArr(DataArrayInt::New()); ciArr->alloc(nbOfNodes+1,1); ciArr->setIJ(0,0,0); cArr->alloc(0,1);
1651   for(int i=0;i<nbOfNodes;i++,revNodI++)
1652     {
1653       int nbOfCellsSharingNode(revNodI[1]-revNodI[0]);
1654       if(nbOfCellsSharingNode==0)
1655         {
1656           std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeDualMesh2D : Node #" << i << " is orphan !"; 
1657           throw INTERP_KERNEL::Exception(oss.str().c_str());
1658         }
1659       std::vector< std::vector<int> > polyg;
1660       for(int j=0;j<nbOfCellsSharingNode;j++)
1661         {
1662           int curCellId(revNod[revNodI[0]+j]);
1663           const int *connOfCurCell(nodal+3*curCellId);
1664           std::size_t nodePosInCurCell(std::distance(connOfCurCell,std::find(connOfCurCell,connOfCurCell+4,i)));
1665           std::vector<int> locV(3);
1666           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;
1667           polyg.push_back(locV);
1668           int kk(0);
1669           for(int k=0;k<3;k++)
1670             {
1671               if(FACEID_NOT_SH_NODE[nodePosInCurCell]!=k)
1672                 {
1673                   const int *edgeId(d2+3*curCellId+k);
1674                   if(rdi2[*edgeId+1]-rdi2[*edgeId]==1)
1675                     {
1676                       std::vector<int> locV2(2);
1677                       int zeLocEdgeIdRel(DUAL_TRI_1[2*nodePosInCurCell+kk]);
1678                       if(zeLocEdgeIdRel>0)
1679                         {  locV2[0]=d2[3*curCellId+zeLocEdgeIdRel-3]+nbOfNodes;  locV2[1]=i; }
1680                       else
1681                         {  locV2[0]=i; locV2[1]=d2[3*curCellId-zeLocEdgeIdRel-3]+nbOfNodes; }
1682                       polyg.push_back(locV2);
1683                     }
1684                   kk++;
1685                 }
1686             }
1687         }
1688       std::vector<int> zePolyg(MEDCoupling1DGTUMesh::BuildAPolygonFromParts(polyg));
1689       cArr->insertAtTheEnd(zePolyg.begin(),zePolyg.end());
1690       ciArr->setIJ(i+1,0,cArr->getNumberOfTuples());
1691     }
1692   ret->setNodalConnectivity(cArr,ciArr);
1693   return ret.retn();
1694 }
1695
1696 //== 
1697
1698 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New()
1699 {
1700   return new MEDCoupling1DGTUMesh;
1701 }
1702
1703 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const char *name, INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception)
1704 {
1705   if(type==INTERP_KERNEL::NORM_ERROR)
1706     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
1707   const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
1708   if(!cm.isDynamic())
1709     {
1710       std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::New : the input geometric type " << cm.getRepr() << " is static ! Only dynamic types are allowed here !";
1711       throw INTERP_KERNEL::Exception(oss.str().c_str());
1712     }
1713   return new MEDCoupling1DGTUMesh(name,cm);
1714 }
1715
1716 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh()
1717 {
1718 }
1719
1720 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const char *name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm)
1721 {
1722 }
1723
1724 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const MEDCoupling1DGTUMesh& other, bool recDeepCpy):MEDCoupling1GTUMesh(other,recDeepCpy),_conn(other._conn)
1725 {
1726   if(recDeepCpy)
1727     {
1728       const DataArrayInt *c(other._conn);
1729       if(c)
1730         _conn=c->deepCpy();
1731       c=other._conn_indx;
1732       if(c)
1733         _conn_indx=c->deepCpy();
1734     }
1735 }
1736
1737 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::clone(bool recDeepCpy) const
1738 {
1739   return new MEDCoupling1DGTUMesh(*this,recDeepCpy);
1740 }
1741
1742 /*!
1743  * This method behaves mostly like MEDCoupling1DGTUMesh::deepCpy method, except that only nodal connectivity arrays are deeply copied.
1744  * The coordinates are shared between \a this and the returned instance.
1745  * 
1746  * \return MEDCouplingUMesh * - A new object instance holding the copy of \a this (deep for connectivity, shallow for coordiantes)
1747  * \sa MEDCoupling1DGTUMesh::deepCpy
1748  */
1749 MEDCouplingPointSet *MEDCoupling1DGTUMesh::deepCpyConnectivityOnly() const throw(INTERP_KERNEL::Exception)
1750 {
1751   checkCoherency();
1752   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(clone(false));
1753   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(_conn->deepCpy()),ci(_conn_indx->deepCpy());
1754   ret->setNodalConnectivity(c,ci);
1755   return ret.retn();
1756 }
1757
1758 void MEDCoupling1DGTUMesh::updateTime() const
1759 {
1760   MEDCoupling1GTUMesh::updateTime();
1761   const DataArrayInt *c(_conn);
1762   if(c)
1763     updateTimeWith(*c);
1764   c=_conn_indx;
1765   if(c)
1766     updateTimeWith(*c);
1767 }
1768
1769 std::size_t MEDCoupling1DGTUMesh::getHeapMemorySize() const
1770 {
1771   std::size_t ret=0;
1772   const DataArrayInt *c(_conn);
1773   if(c)
1774     ret+=c->getHeapMemorySize();
1775   c=_conn_indx;
1776   if(c)
1777     ret+=c->getHeapMemorySize();
1778   return MEDCoupling1GTUMesh::getHeapMemorySize()+ret;
1779 }
1780
1781 MEDCouplingMesh *MEDCoupling1DGTUMesh::deepCpy() const
1782 {
1783   return clone(true);
1784 }
1785
1786 bool MEDCoupling1DGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception)
1787 {
1788   if(!other)
1789     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualIfNotWhy : input other pointer is null !");
1790   std::ostringstream oss; oss.precision(15);
1791   const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
1792   if(!otherC)
1793     {
1794       reason="mesh given in input is not castable in MEDCoupling1DGTUMesh !";
1795       return false;
1796     }
1797   if(!MEDCoupling1GTUMesh::isEqualIfNotWhy(other,prec,reason))
1798     return false;
1799   const DataArrayInt *c1(_conn),*c2(otherC->_conn);
1800   if(c1==c2)
1801     return true;
1802   if(!c1 || !c2)
1803     {
1804       reason="in connectivity of single dynamic geometric type exactly one among this and other is null !";
1805       return false;
1806     }
1807   if(!c1->isEqualIfNotWhy(*c2,reason))
1808     {
1809       reason.insert(0,"Nodal connectivity DataArrayInt differs : ");
1810       return false;
1811     }
1812   c1=_conn_indx; c2=otherC->_conn_indx;
1813   if(c1==c2)
1814     return true;
1815   if(!c1 || !c2)
1816     {
1817       reason="in connectivity index of single dynamic geometric type exactly one among this and other is null !";
1818       return false;
1819     }
1820   if(!c1->isEqualIfNotWhy(*c2,reason))
1821     {
1822       reason.insert(0,"Nodal connectivity index DataArrayInt differs : ");
1823       return false;
1824     }
1825   return true;
1826 }
1827
1828 bool MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
1829 {
1830   if(!other)
1831     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
1832   const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
1833   if(!otherC)
1834     return false;
1835   if(!MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(other,prec))
1836     return false;
1837   const DataArrayInt *c1(_conn),*c2(otherC->_conn);
1838   if(c1==c2)
1839     return true;
1840   if(!c1 || !c2)
1841     return false;
1842   if(!c1->isEqualWithoutConsideringStr(*c2))
1843     return false;
1844   return true;
1845   c1=_conn_indx; c2=otherC->_conn_indx;
1846   if(c1==c2)
1847     return true;
1848   if(!c1 || !c2)
1849     return false;
1850   if(!c1->isEqualWithoutConsideringStr(*c2))
1851     return false;
1852   return true;
1853 }
1854
1855 /*!
1856  * Checks if \a this and \a other meshes are geometrically equivalent with high
1857  * probability, else an exception is thrown. The meshes are considered equivalent if
1858  * (1) meshes contain the same number of nodes and the same number of elements of the
1859  * same types (2) three cells of the two meshes (first, last and middle) are based
1860  * on coincident nodes (with a specified precision).
1861  *  \param [in] other - the mesh to compare with.
1862  *  \param [in] prec - the precision used to compare nodes of the two meshes.
1863  *  \throw If the two meshes do not match.
1864  */
1865 void MEDCoupling1DGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception)
1866 {
1867   MEDCouplingPointSet::checkFastEquivalWith(other,prec);
1868   const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
1869   if(!otherC)
1870     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : Two meshes are not unstructured with single dynamic geometric type !");
1871   const DataArrayInt *c1(_conn),*c2(otherC->_conn);
1872   if(c1!=c2)
1873     {
1874       if(!c1 || !c2)
1875         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !");
1876       if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
1877         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !");
1878       if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
1879         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !");
1880       if(c1->getHashCode()!=c2->getHashCode())
1881         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity differs");
1882     }
1883   c1=_conn_indx; c2=otherC->_conn_indx;
1884   if(c1!=c2)
1885     {
1886       if(!c1 || !c2)
1887         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity index only in one of the 2 meshes !");
1888       if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
1889         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, only one is allocated !");
1890       if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
1891         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, must have 1 and only 1 component !");
1892       if(c1->getHashCode()!=c2->getHashCode())
1893         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity index differs");
1894     }
1895 }
1896
1897 void MEDCoupling1DGTUMesh::checkCoherencyOfConnectivity() const throw(INTERP_KERNEL::Exception)
1898 {
1899   const DataArrayInt *c1(_conn);
1900   if(c1)
1901     {
1902       if(c1->getNumberOfComponents()!=1)
1903         throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !");
1904       if(c1->getInfoOnComponent(0)!="")
1905         throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !");
1906       c1->checkAllocated();
1907     }
1908   else
1909     throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !");
1910   //
1911   int sz2=_conn->getNumberOfTuples();
1912   c1=_conn_indx;
1913   if(c1)
1914     {
1915       if(c1->getNumberOfComponents()!=1)
1916         throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to be with number of components set to one !");
1917       c1->checkAllocated();
1918       if(c1->getNumberOfTuples()<1)
1919         throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have a a size of 1 at least !");
1920       if(c1->getInfoOnComponent(0)!="")
1921         throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have no info on its single component !");
1922       int f=c1->front(),ll=c1->back();
1923       if(f<0 || f>=sz2)
1924         {
1925           std::ostringstream oss; oss << "Nodal connectivity index array first value (" << f << ") is expected to be exactly in [0," << sz2 << ") !";
1926           throw INTERP_KERNEL::Exception(oss.str().c_str());
1927         }
1928       if(ll<0 || ll>sz2)
1929         {
1930           std::ostringstream oss; oss << "Nodal connectivity index array last value (" << ll << ") is expected to be exactly in [0," << sz2 << "] !";
1931           throw INTERP_KERNEL::Exception(oss.str().c_str());
1932         }
1933       if(f>ll)
1934         {
1935           std::ostringstream oss; oss << "Nodal connectivity index array looks very bad (not increasing monotonic) because front (" << f << ") is greater that back (" << ll << ") !";
1936           throw INTERP_KERNEL::Exception(oss.str().c_str());
1937         }
1938     }
1939   else
1940     throw INTERP_KERNEL::Exception("Nodal connectivity index array not defined !");
1941   int szOfC1Exp=_conn_indx->back();
1942   if(sz2<szOfC1Exp)
1943     {
1944       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() << " !";
1945       throw INTERP_KERNEL::Exception(oss.str().c_str());
1946     }
1947 }
1948
1949 /*!
1950  * 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.
1951  * In addition you are sure that the length of nodal connectivity index array is bigger than or equal to one.
1952  * In addition you are also sure that length of nodal connectivity is coherent with the content of the last value in the index array.
1953  */
1954 void MEDCoupling1DGTUMesh::checkCoherency() const throw(INTERP_KERNEL::Exception)
1955 {
1956   MEDCouplingPointSet::checkCoherency();
1957   checkCoherencyOfConnectivity();
1958 }
1959
1960 void MEDCoupling1DGTUMesh::checkCoherency1(double eps) const throw(INTERP_KERNEL::Exception)
1961 {
1962   checkCoherency();
1963   const DataArrayInt *c1(_conn),*c2(_conn_indx);
1964   if(!c2->isMonotonic(true))
1965     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkCoherency1 : the nodal connectivity index is expected to be increasing monotinic !");
1966   //
1967   int nbOfTuples=c1->getNumberOfTuples();
1968   int nbOfNodes=getNumberOfNodes();
1969   const int *w(c1->begin());
1970   for(int i=0;i<nbOfTuples;i++,w++)
1971     {
1972       if(*w==-1) continue;
1973       if(*w<0 || *w>=nbOfNodes)
1974         {
1975           std::ostringstream oss; oss << "At pos #" << i << " of nodal connectivity array references to node id #" << *w << " must be in [0," << nbOfNodes << ") !";
1976           throw INTERP_KERNEL::Exception(oss.str().c_str());
1977         }
1978     }
1979 }
1980
1981 void MEDCoupling1DGTUMesh::checkCoherency2(double eps) const throw(INTERP_KERNEL::Exception)
1982 {
1983   checkCoherency1(eps);
1984 }
1985
1986 int MEDCoupling1DGTUMesh::getNumberOfCells() const
1987 {
1988   checkCoherencyOfConnectivity();//do not remove
1989   return _conn_indx->getNumberOfTuples()-1;
1990 }
1991
1992 /*!
1993  * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
1994  * For each cell in \b this the number of nodes constituting cell is computed.
1995  * For each polyhedron cell, the sum of the number of nodes of each face constituting polyhedron cell is returned.
1996  * So for pohyhedrons some nodes can be counted several times in the returned result.
1997  * 
1998  * \return a newly allocated array
1999  */
2000 DataArrayInt *MEDCoupling1DGTUMesh::computeNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
2001 {
2002   checkCoherency();
2003   _conn_indx->checkMonotonic(true);
2004   if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2005     return _conn_indx->deltaShiftIndex();
2006   // for polyhedrons
2007   int nbOfCells=_conn_indx->getNumberOfTuples()-1;
2008   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2009   ret->alloc(nbOfCells,1);
2010   int *retPtr=ret->getPointer();
2011   const int *ci=_conn_indx->begin(),*c=_conn->begin();
2012   for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2013     *retPtr=ci[1]-ci[0]-std::count(c+ci[0],c+ci[1],-1);
2014   return ret.retn();
2015 }
2016
2017 /*!
2018  * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
2019  * For each cell in \b this the number of faces constituting (entity of dimension this->getMeshDimension()-1) cell is computed.
2020  * 
2021  * \return a newly allocated array
2022  */
2023 DataArrayInt *MEDCoupling1DGTUMesh::computeNbOfFacesPerCell() const throw(INTERP_KERNEL::Exception)
2024 {
2025   checkCoherency();
2026   _conn_indx->checkMonotonic(true);
2027   if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED && getCellModelEnum()!=INTERP_KERNEL::NORM_QPOLYG)
2028     return _conn_indx->deltaShiftIndex();
2029   if(getCellModelEnum()==INTERP_KERNEL::NORM_QPOLYG)
2030     {
2031       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=_conn_indx->deltaShiftIndex();
2032       ret->applyDivideBy(2);
2033       return ret.retn();
2034     }
2035   // for polyhedrons
2036   int nbOfCells=_conn_indx->getNumberOfTuples()-1;
2037   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2038   ret->alloc(nbOfCells,1);
2039   int *retPtr=ret->getPointer();
2040   const int *ci=_conn_indx->begin(),*c=_conn->begin();
2041   for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2042     *retPtr=std::count(c+ci[0],c+ci[1],-1)+1;
2043   return ret.retn();
2044 }
2045
2046 /*!
2047  * This method computes effective number of nodes per cell. That is to say nodes appearing several times in nodal connectivity of a cell,
2048  * will be counted only once here whereas it will be counted several times in MEDCoupling1DGTUMesh::computeNbOfNodesPerCell method.
2049  *
2050  * \return DataArrayInt * - new object to be deallocated by the caller.
2051  * \sa MEDCoupling1DGTUMesh::computeNbOfNodesPerCell
2052  */
2053 DataArrayInt *MEDCoupling1DGTUMesh::computeEffectiveNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
2054 {
2055   checkCoherency();
2056   _conn_indx->checkMonotonic(true);
2057   int nbOfCells(_conn_indx->getNumberOfTuples()-1);
2058   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2059   ret->alloc(nbOfCells,1);
2060   int *retPtr(ret->getPointer());
2061   const int *ci(_conn_indx->begin()),*c(_conn->begin());
2062   if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2063     {
2064       for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2065         {
2066           std::set<int> s(c+ci[0],c+ci[1]);
2067           *retPtr=(int)s.size();
2068         }
2069     }
2070   else
2071     {
2072       for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2073         {
2074           std::set<int> s(c+ci[0],c+ci[1]); s.erase(-1);
2075           *retPtr=(int)s.size();
2076         }
2077     }
2078   return ret.retn();
2079 }
2080
2081 void MEDCoupling1DGTUMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
2082 {
2083   int nbOfCells(getNumberOfCells());//performs checks
2084   if(cellId>=0 && cellId<nbOfCells)
2085     {
2086       int strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0);
2087       int nbOfNodes=stp-strt;
2088       if(nbOfNodes<0)
2089         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::getNodeIdsOfCell : the index array is invalid ! Should be increasing monotonic !");
2090       conn.resize(nbOfNodes);
2091       std::copy(_conn->begin()+strt,_conn->begin()+stp,conn.begin());
2092     }
2093   else
2094     {
2095       std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !";
2096       throw INTERP_KERNEL::Exception(oss.str().c_str());
2097     }
2098 }
2099
2100 int MEDCoupling1DGTUMesh::getNumberOfNodesInCell(int cellId) const throw(INTERP_KERNEL::Exception)
2101 {
2102   int nbOfCells(getNumberOfCells());//performs checks
2103   if(cellId>=0 && cellId<nbOfCells)
2104     {
2105       const int *conn(_conn->begin());
2106       int strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0);
2107       return stp-strt-std::count(conn+strt,conn+stp,-1);
2108     }
2109   else
2110     {
2111       std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNumberOfNodesInCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !";
2112       throw INTERP_KERNEL::Exception(oss.str().c_str());
2113     }
2114 }
2115
2116 std::string MEDCoupling1DGTUMesh::simpleRepr() const
2117 {
2118   static const char msg0[]="No coordinates specified !";
2119   std::ostringstream ret;
2120   ret << "Single dynamic geometic type (" << _cm->getRepr() << ") unstructured mesh with name : \"" << getName() << "\"\n";
2121   ret << "Description of mesh : \"" << getDescription() << "\"\n";
2122   int tmpp1,tmpp2;
2123   double tt=getTime(tmpp1,tmpp2);
2124   ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
2125   ret << "Iteration : " << tmpp1  << " Order : " << tmpp2 << "\n";
2126   ret << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : ";
2127   if(_coords!=0)
2128     {
2129       const int spaceDim=getSpaceDimension();
2130       ret << spaceDim << "\nInfo attached on space dimension : ";
2131       for(int i=0;i<spaceDim;i++)
2132         ret << "\"" << _coords->getInfoOnComponent(i) << "\" ";
2133       ret << "\n";
2134     }
2135   else
2136     ret << msg0 << "\n";
2137   ret << "Number of nodes : ";
2138   if(_coords!=0)
2139     ret << getNumberOfNodes() << "\n";
2140   else
2141     ret << msg0 << "\n";
2142   ret << "Number of cells : ";
2143   bool isOK=true;
2144   try { checkCoherency(); } catch(INTERP_KERNEL::Exception& e)
2145     {
2146       ret << "Nodal connectivity arrays are not set or badly set !\n";
2147       isOK=false;
2148     }
2149   if(isOK)
2150     ret << getNumberOfCells() << "\n";
2151   ret << "Cell type : " << _cm->getRepr() << "\n";
2152   return ret.str();
2153 }
2154
2155 std::string MEDCoupling1DGTUMesh::advancedRepr() const
2156 {
2157   std::ostringstream ret;
2158   ret << simpleRepr();
2159   ret << "\nCoordinates array : \n___________________\n\n";
2160   if(_coords)
2161     _coords->reprWithoutNameStream(ret);
2162   else
2163     ret << "No array set !\n";
2164   ret << "\n\nNodal Connectivity : \n____________________\n\n";
2165   //
2166   bool isOK=true;
2167   try { checkCoherency1(); } catch(INTERP_KERNEL::Exception& e)
2168     {
2169       ret << "Nodal connectivity arrays are not set or badly set !\n";
2170       isOK=false;
2171     }
2172   if(!isOK)
2173     return ret.str();
2174   int nbOfCells=getNumberOfCells();
2175   const int *ci=_conn_indx->begin(),*c=_conn->begin();
2176   for(int i=0;i<nbOfCells;i++,ci++)
2177     {
2178       ret << "Cell #" << i << " : ";
2179       std::copy(c+ci[0],c+ci[1],std::ostream_iterator<int>(ret," "));
2180       ret << "\n";
2181     }
2182   return ret.str();
2183 }
2184
2185 DataArrayDouble *MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
2186 {
2187   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
2188   int spaceDim=getSpaceDimension();
2189   int nbOfCells=getNumberOfCells();//checkCoherency()
2190   int nbOfNodes=getNumberOfNodes();
2191   ret->alloc(nbOfCells,spaceDim);
2192   double *ptToFill=ret->getPointer();
2193   const double *coor=_coords->begin();
2194   const int *nodal=_conn->begin(),*nodali=_conn_indx->begin();
2195   nodal+=nodali[0];
2196   if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2197     {
2198       for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
2199         {
2200           std::fill(ptToFill,ptToFill+spaceDim,0.);
2201           if(nodali[0]<nodali[1])// >= to avoid division by 0.
2202             {
2203               for(int j=nodali[0];j<nodali[1];j++,nodal++)
2204                 {
2205                   if(*nodal>=0 && *nodal<nbOfNodes)
2206                     std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
2207                   else
2208                     {
2209                       std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," <<   nbOfNodes << ") !";
2210                       throw INTERP_KERNEL::Exception(oss.str().c_str());
2211                     }
2212                   std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./(nodali[1]-nodali[0])));
2213                 }
2214             }
2215           else
2216             {
2217               std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : at cell #" << i << " the nodal index array is invalid !";
2218               throw INTERP_KERNEL::Exception(oss.str().c_str());
2219             }
2220         }
2221     }
2222   else
2223     {
2224       for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
2225         {
2226           std::fill(ptToFill,ptToFill+spaceDim,0.);
2227           if(nodali[0]<nodali[1])// >= to avoid division by 0.
2228             {
2229               int nbOfNod=0;
2230               for(int j=nodali[0];j<nodali[1];j++,nodal++)
2231                 {
2232                   if(*nodal==-1) continue;
2233                   if(*nodal>=0 && *nodal<nbOfNodes)
2234                     {
2235                       std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
2236                       nbOfNod++;
2237                     }
2238                   else
2239                     {
2240                       std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," <<   nbOfNodes << ") !";
2241                       throw INTERP_KERNEL::Exception(oss.str().c_str());
2242                     }
2243                 }
2244               if(nbOfNod!=0)
2245                 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./nbOfNod));
2246               else
2247                 {
2248                   std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : no nodes in cell #" << i << " !";
2249                   throw INTERP_KERNEL::Exception(oss.str().c_str());
2250                 }
2251             }
2252           else
2253             {
2254               std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron)  : at cell #" << i << " the nodal index array is invalid !";
2255               throw INTERP_KERNEL::Exception(oss.str().c_str());
2256             }
2257         }
2258     }
2259   return ret.retn();
2260 }
2261
2262 void MEDCoupling1DGTUMesh::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception)
2263 {
2264   int nbCells=getNumberOfCells();
2265   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::New();
2266   o2n->useArray(old2NewBg,false,C_DEALLOC,nbCells,1);
2267   if(check)
2268     o2n=o2n->checkAndPreparePermutation();
2269   //
2270   const int *o2nPtr=o2n->getPointer();
2271   const int *conn=_conn->begin(),*conni=_conn_indx->begin();
2272   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New();
2273   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI=DataArrayInt::New();
2274   newConn->alloc(_conn->getNumberOfTuples(),1); newConnI->alloc(nbCells,1);
2275   newConn->copyStringInfoFrom(*_conn); newConnI->copyStringInfoFrom(*_conn_indx);
2276   //
2277   int *newC=newConn->getPointer(),*newCI=newConnI->getPointer();
2278   for(int i=0;i<nbCells;i++)
2279     {
2280       int newPos=o2nPtr[i];
2281       int sz=conni[i+1]-conni[i];
2282       if(sz>=0)
2283         newCI[newPos]=sz;
2284       else
2285         {
2286           std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberCells : the index nodal array is invalid for cell #" << i << " !";
2287           throw INTERP_KERNEL::Exception(oss.str().c_str());
2288         }
2289     }
2290   newConnI->computeOffsets2(); newCI=newConnI->getPointer();
2291   //
2292   for(int i=0;i<nbCells;i++,conni++)
2293     {
2294       int sz=conni[1]-conni[0];
2295       int newp=o2nPtr[i];
2296       std::copy(conn+conni[0],conn+conni[1],newC+newCI[newp]);
2297     }
2298   _conn=newConn;
2299   _conn_indx=newConnI;
2300 }
2301
2302 MEDCouplingMesh *MEDCoupling1DGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
2303 {
2304   if(other->getType()!=SINGLE_DYNAMIC_GEO_TYPE_UNSTRUCTURED)
2305     throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single dynamic geo type each other !");
2306   const MEDCoupling1DGTUMesh *otherC=static_cast<const MEDCoupling1DGTUMesh *>(other);
2307   return Merge1DGTUMeshes(this,otherC);
2308 }
2309
2310 MEDCouplingUMesh *MEDCoupling1DGTUMesh::buildUnstructured() const throw(INTERP_KERNEL::Exception)
2311 {
2312   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName().c_str(),getMeshDimension());
2313   ret->setCoords(getCoords());
2314   const int *nodalConn=_conn->begin(),*nodalConnI=_conn_indx->begin();
2315   int nbCells=getNumberOfCells();//checkCoherency
2316   int geoType=(int)getCellModelEnum();
2317   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New(); c->alloc(nbCells+_conn->getNumberOfTuples(),1);
2318   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cI=DataArrayInt::New(); cI->alloc(nbCells+1);
2319   int *cPtr=c->getPointer(),*ciPtr=cI->getPointer();
2320   ciPtr[0]=0;
2321   for(int i=0;i<nbCells;i++,ciPtr++)
2322     {
2323       int sz=nodalConnI[i+1]-nodalConnI[i];
2324       if(sz>=0)
2325         {
2326           *cPtr++=geoType;
2327           cPtr=std::copy(nodalConn+nodalConnI[i],nodalConn+nodalConnI[i+1],cPtr);
2328           ciPtr[1]=ciPtr[0]+sz+1;
2329         }
2330       else
2331         {
2332           std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::buildUnstructured : Invalid for nodal index for cell #" << i << " !";
2333           throw INTERP_KERNEL::Exception(oss.str().c_str());
2334         }
2335     }
2336   ret->setConnectivity(c,cI,true);
2337   return ret.retn();
2338 }
2339
2340 /*!
2341  * Do nothing for the moment, because there is no policy that allows to split polygons, polyhedrons ... into simplexes
2342  */
2343 DataArrayInt *MEDCoupling1DGTUMesh::simplexize(int policy) throw(INTERP_KERNEL::Exception)
2344 {
2345   int nbOfCells=getNumberOfCells();
2346   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2347   ret->alloc(nbOfCells,1);
2348   ret->iota(0);
2349   return ret.retn();
2350 }
2351
2352 void MEDCoupling1DGTUMesh::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
2353 {
2354   stream << "MEDCoupling1DGTUMesh C++ instance at " << this << ". Type=" << _cm->getRepr() << ". Name : \"" << getName() << "\".";
2355   stream << " Mesh dimension : " << getMeshDimension() << ".";
2356   if(!_coords)
2357     { stream << " No coordinates set !"; return ; }
2358   if(!_coords->isAllocated())
2359     { stream << " Coordinates set but not allocated !"; return ; }
2360   stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
2361   stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
2362   bool isOK=true;
2363   try { checkCoherency(); } catch(INTERP_KERNEL::Exception& e)
2364     {
2365       stream << std::endl << "Nodal connectivity NOT set properly !\n";
2366       isOK=false;
2367     }
2368   if(isOK)
2369     stream << std::endl << "Number of cells : " << getNumberOfCells() << ".";
2370 }
2371
2372 void MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other) throw(INTERP_KERNEL::Exception)
2373 {
2374   if(!other)
2375     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is null !");
2376   const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2377   if(!otherC)
2378     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1DGTUMesh instance !");
2379   setNodalConnectivity(otherC->getNodalConnectivity(),otherC->getNodalConnectivityIndex());
2380 }
2381
2382 MEDCouplingPointSet *MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const
2383 {
2384   if(!other)
2385     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : input other is null !");
2386   const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2387   if(!otherC)
2388     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !");
2389   std::vector<const MEDCoupling1DGTUMesh *> ms(2);
2390   ms[0]=this;
2391   ms[1]=otherC;
2392   return Merge1DGTUMeshesOnSameCoords(ms);
2393 }
2394
2395 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const
2396 {
2397   checkCoherency();
2398   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName().c_str(),*_cm));
2399   ret->setCoords(_coords);
2400   DataArrayInt *c=0,*ci=0;
2401   MEDCouplingUMesh::ExtractFromIndexedArrays(begin,end,_conn,_conn_indx,c,ci);
2402   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
2403   ret->setNodalConnectivity(c,ci);
2404   return ret.retn();
2405 }
2406
2407 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const
2408 {
2409   checkCoherency();
2410   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName().c_str(),*_cm));
2411   ret->setCoords(_coords);
2412   DataArrayInt *c=0,*ci=0;
2413   MEDCouplingUMesh::ExtractFromIndexedArrays2(start,end,step,_conn,_conn_indx,c,ci);
2414   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
2415   ret->setNodalConnectivity(c,ci);
2416   return ret.retn();
2417 }
2418
2419 void MEDCoupling1DGTUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const throw(INTERP_KERNEL::Exception)
2420 {
2421   int sz((int)nodeIdsInUse.size());
2422   int nbCells(getNumberOfCells());
2423   const int *w(_conn->begin()),*wi(_conn_indx->begin());
2424   for(int i=0;i<nbCells;i++,wi++)
2425     for(const int *pt=w+wi[0];pt!=w+wi[1];pt++)
2426       if(*pt!=-1)
2427         {
2428           if(*pt>=0 && *pt<sz)
2429             nodeIdsInUse[*pt]=true;
2430           else
2431             {
2432               std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeNodeIdsAlg : At cell #" << i << " presence of node id #" << *pt << " should be in [0," << sz << ") !";
2433               throw INTERP_KERNEL::Exception(oss.str().c_str());
2434             }
2435         }
2436 }
2437
2438 void MEDCoupling1DGTUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const throw(INTERP_KERNEL::Exception)
2439 {
2440   checkFullyDefined();
2441   int nbOfNodes=getNumberOfNodes();
2442   int *revNodalIndxPtr=(int *)malloc((nbOfNodes+1)*sizeof(int));
2443   revNodalIndx->useArray(revNodalIndxPtr,true,C_DEALLOC,nbOfNodes+1,1);
2444   std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
2445   const int *conn=_conn->begin(),*conni=_conn_indx->begin();
2446   int nbOfCells=getNumberOfCells();
2447   int nbOfEltsInRevNodal=0;
2448   for(int eltId=0;eltId<nbOfCells;eltId++)
2449     {
2450       int nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
2451       if(nbOfNodesPerCell>=0)
2452         {
2453           for(int j=0;j<nbOfNodesPerCell;j++)
2454             {
2455               int nodeId=conn[conni[eltId]+j];
2456               if(nodeId==-1) continue;            
2457               if(nodeId>=0 && nodeId<nbOfNodes)
2458                 {
2459                   nbOfEltsInRevNodal++;
2460                   revNodalIndxPtr[nodeId+1]++;
2461                 }
2462               else
2463                 {
2464                   std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !";
2465                   throw INTERP_KERNEL::Exception(oss.str().c_str());
2466                 }
2467             }
2468         }
2469       else
2470         {
2471           std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << "nodal connectivity is invalid !";
2472           throw INTERP_KERNEL::Exception(oss.str().c_str());
2473         }
2474     }
2475   std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<int>());
2476   conn=_conn->begin();
2477   int *revNodalPtr=(int *)malloc((nbOfEltsInRevNodal)*sizeof(int));
2478   revNodal->useArray(revNodalPtr,true,C_DEALLOC,nbOfEltsInRevNodal,1);
2479   std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
2480   for(int eltId=0;eltId<nbOfCells;eltId++)
2481     {
2482       int nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
2483       for(int j=0;j<nbOfNodesPerCell;j++)
2484         {
2485           int nodeId=conn[conni[eltId]+j];
2486           if(nodeId!=-1)
2487             *std::find_if(revNodalPtr+revNodalIndxPtr[nodeId],revNodalPtr+revNodalIndxPtr[nodeId+1],std::bind2nd(std::equal_to<int>(),-1))=eltId;
2488         }
2489     }
2490 }
2491
2492 void MEDCoupling1DGTUMesh::checkFullyDefined() const throw(INTERP_KERNEL::Exception)
2493 {
2494   if(!((const DataArrayInt *)_conn) || !((const DataArrayInt *)_conn_indx) || !((const DataArrayDouble *)_coords))
2495     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFullyDefined : part of this is not fully defined.");
2496 }
2497
2498 bool MEDCoupling1DGTUMesh::isEmptyMesh(const std::vector<int>& tinyInfo) const
2499 {
2500   throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEmptyMesh : not implemented yet !");
2501 }
2502
2503 /*!
2504  * Finds nodes not used in any cell and returns an array giving a new id to every node
2505  * by excluding the unused nodes, for which the array holds -1. The result array is
2506  * a mapping in "Old to New" mode. 
2507  *  \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
2508  *  \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a
2509  *          this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
2510  *          if the node is unused or a new id else. The caller is to delete this
2511  *          array using decrRef() as it is no more needed.  
2512  *  \throw If the coordinates array is not set.
2513  *  \throw If the nodal connectivity of cells is not defined.
2514  *  \throw If the nodal connectivity includes an invalid id.
2515  */
2516 DataArrayInt *MEDCoupling1DGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const throw(INTERP_KERNEL::Exception)
2517 {
2518   nbrOfNodesInUse=-1;
2519   int nbOfNodes=getNumberOfNodes();
2520   int nbOfCells=getNumberOfCells();//checkCoherency
2521   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2522   ret->alloc(nbOfNodes,1);
2523   int *traducer=ret->getPointer();
2524   std::fill(traducer,traducer+nbOfNodes,-1);
2525   const int *conn=_conn->begin(),*conni(_conn_indx->begin());
2526   for(int i=0;i<nbOfCells;i++,conni++)
2527     {
2528       int nbNodesPerCell=conni[1]-conni[0];
2529       for(int j=0;j<nbNodesPerCell;j++)
2530         {
2531           int nodeId=conn[conni[0]+j];
2532           if(nodeId==-1) continue;
2533           if(nodeId>=0 && nodeId<nbOfNodes)
2534             traducer[nodeId]=1;
2535           else
2536             {
2537               std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsInUse : In cell #" << i  << " presence of node id " <<  nodeId << " not in [0," << nbOfNodes << ") !";
2538               throw INTERP_KERNEL::Exception(oss.str().c_str());
2539             }
2540         }
2541     }
2542   nbrOfNodesInUse=(int)std::count(traducer,traducer+nbOfNodes,1);
2543   std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
2544   return ret.retn();
2545 }
2546
2547 /*!
2548  * Changes ids of nodes within the nodal connectivity arrays according to a permutation
2549  * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
2550  * This method is a generalization of shiftNodeNumbersInConn().
2551  *  \warning This method performs no check of validity of new ids. **Use it with care !**
2552  *  \param [in] newNodeNumbersO2N - a permutation array, of length \a
2553  *         this->getNumberOfNodes(), in "Old to New" mode. 
2554  *         See \ref MEDCouplingArrayRenumbering for more info on renumbering modes.
2555  *  \throw If the nodal connectivity of cells is not defined.
2556  */
2557 void MEDCoupling1DGTUMesh::renumberNodesInConn(const int *newNodeNumbersO2N)
2558 {
2559   getNumberOfCells();//only to check that all is well defined.
2560   //
2561   int nbElemsIn=getNumberOfNodes();
2562   int nbOfTuples=_conn->getNumberOfTuples();
2563   int *pt=_conn->getPointer();
2564   for(int i=0;i<nbOfTuples;i++,pt++)
2565     {
2566       if(*pt==-1) continue;
2567       if(*pt>=0 && *pt<nbElemsIn)
2568         *pt=newNodeNumbersO2N[*pt];
2569       else
2570         {
2571           std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberNodesInConn : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn;
2572           throw INTERP_KERNEL::Exception(oss.str().c_str());
2573         }
2574     }
2575   _conn->declareAsNew();
2576   //
2577   updateTime();
2578 }
2579
2580 /*!
2581  * Keeps from \a this only cells which constituing point id are in the ids specified by [\a begin,\a end).
2582  * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
2583  * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not.
2584  * If \a fullyIn is true only cells whose ids are \b fully contained in [\a begin,\a end) tab will be kept.
2585  *
2586  * \param [in] begin input start of array of node ids.
2587  * \param [in] end input end of array of node ids.
2588  * \param [in] fullyIn input that specifies if all node ids must be in [\a begin,\a end) array to consider cell to be in.
2589  * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end.
2590  */
2591 void MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const
2592 {
2593   int nbOfCells=getNumberOfCells();
2594   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1);
2595   int tmp=-1;
2596   int sz=_conn->getMaxValue(tmp); sz=std::max(sz,0)+1;
2597   std::vector<bool> fastFinder(sz,false);
2598   for(const int *work=begin;work!=end;work++)
2599     if(*work>=0 && *work<sz)
2600       fastFinder[*work]=true;
2601   const int *conn=_conn->begin(),*conni=_conn_indx->begin();
2602   for(int i=0;i<nbOfCells;i++,conni++)
2603     {
2604       int ref=0,nbOfHit=0;
2605       int nbNodesPerCell=conni[1]-conni[0];
2606       if(nbNodesPerCell>=0)
2607         {
2608           for(int j=0;j<nbNodesPerCell;j++)
2609             {
2610               int nodeId=conn[conni[0]+j];
2611               if(nodeId>=0)
2612                 {
2613                   ref++;
2614                   if(fastFinder[nodeId])
2615                     nbOfHit++;
2616                 }
2617             }
2618         }
2619       else
2620         {
2621           std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds : invalid index array for cell #" << i << " !";
2622           throw INTERP_KERNEL::Exception(oss.str().c_str());
2623         }
2624       if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn))
2625         cellIdsKept->pushBackSilent(i);
2626     }
2627   cellIdsKeptArr=cellIdsKept.retn();
2628 }
2629
2630 void MEDCoupling1DGTUMesh::allocateCells(int nbOfCells) throw(INTERP_KERNEL::Exception)
2631 {
2632   if(nbOfCells<0)
2633     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::allocateCells : the input number of cells should be >= 0 !");
2634   _conn=DataArrayInt::New();
2635   _conn->reserve(nbOfCells*3);
2636   _conn_indx=DataArrayInt::New();
2637   _conn_indx->reserve(nbOfCells+1); _conn_indx->pushBackSilent(0);
2638   declareAsNew();
2639 }
2640
2641 /*!
2642  * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ).
2643  *
2644  * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add.
2645  * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
2646  * \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
2647  *        attached to \a this.
2648  * \thow If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
2649  */
2650 void MEDCoupling1DGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd) throw(INTERP_KERNEL::Exception)
2651 {
2652   int sz=(int)std::distance(nodalConnOfCellBg,nodalConnOfCellEnd);
2653   DataArrayInt *c(_conn),*c2(_conn_indx);
2654   if(c && c2)
2655     {
2656       int pos=c2->back();
2657       if(pos==c->getNumberOfTuples())
2658         {
2659           c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd);
2660           c2->pushBackSilent(pos+sz);
2661         }
2662       else
2663         {
2664           std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::insertNextCell : The nodal index array (end=" << pos << ") mismatches with nodal array (length=" << c->getNumberOfTuples() << ") !";
2665           throw INTERP_KERNEL::Exception(oss.str().c_str());
2666         }
2667     }
2668   else
2669     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1DGTUMesh::allocateCells before !");
2670 }
2671
2672 void MEDCoupling1DGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn, DataArrayInt *nodalConnIndex) throw(INTERP_KERNEL::Exception)
2673 {
2674   if(nodalConn)
2675     nodalConn->incrRef();
2676   _conn=nodalConn;
2677   if(nodalConnIndex)
2678     nodalConnIndex->incrRef();
2679   _conn_indx=nodalConnIndex;
2680   declareAsNew();
2681 }
2682
2683 /*!
2684  * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it.
2685  */
2686 DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivity() const throw(INTERP_KERNEL::Exception)
2687 {
2688   const DataArrayInt *ret(_conn);
2689   return const_cast<DataArrayInt *>(ret);
2690 }
2691
2692 /*!
2693  * \return DataArrayInt * - the internal reference to the nodal connectivity index. The caller is not reponsible to deallocate it.
2694  */
2695 DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivityIndex() const throw(INTERP_KERNEL::Exception)
2696 {
2697   const DataArrayInt *ret(_conn_indx);
2698   return const_cast<DataArrayInt *>(ret);
2699 }
2700
2701 /*!
2702  * See the definition of the nodal connectivity pack \ref MEDCoupling1DGTUMesh::isPacked "here".
2703  * This method tries to build a new instance geometrically equivalent to \a this, by limiting at most the number of new object (nodal connectivity).
2704  * 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.
2705  *
2706  * 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.
2707  * 
2708  * \param [out] isShallowCpyOfNodalConnn - tells if the returned instance share the same pair of nodal connectivity arrays (true) or if nodal
2709  *              connectivity arrays are different (false)
2710  * \return a new object to be managed by the caller.
2711  * 
2712  * \sa MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity, MEDCoupling1DGTUMesh::isPacked
2713  */
2714 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::copyWithNodalConnectivityPacked(bool& isShallowCpyOfNodalConnn) const throw(INTERP_KERNEL::Exception)
2715 {
2716   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName().c_str(),*_cm));
2717   DataArrayInt *nc=0,*nci=0;
2718   isShallowCpyOfNodalConnn=retrievePackedNodalConnectivity(nc,nci);
2719   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ncs(nc),ncis(nci);
2720   ret->_conn=ncs; ret->_conn_indx=ncis;
2721   ret->setCoords(getCoords());
2722   return ret.retn();
2723 }
2724
2725 /*!
2726  * This method allows to compute, if needed, the packed nodal connectivity pair.
2727  * Indeed, it is possible to store in \a this a nodal connectivity array bigger than ranges convered by nodal connectivity index array.
2728  * 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.
2729  * 
2730  * 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)
2731  * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
2732  *
2733  * 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
2734  * will be returned.
2735  * 
2736  * This method return 3 elements.
2737  * \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
2738  *                          this pointer can be seen as a new object, that is to managed by the caller.
2739  * \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
2740  *                              this pointer can be seen as a new object, that is to managed by the caller.
2741  * \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
2742  * output parameters are newly created objects.
2743  *
2744  * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkCoherency test
2745  */
2746 bool MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity(DataArrayInt *&nodalConn, DataArrayInt *&nodalConnIndx) const throw(INTERP_KERNEL::Exception)
2747 {
2748   if(isPacked())//performs the checkCoherency
2749     {
2750       const DataArrayInt *c0(_conn),*c1(_conn_indx);
2751       nodalConn=const_cast<DataArrayInt *>(c0); nodalConnIndx=const_cast<DataArrayInt *>(c1);
2752       nodalConn->incrRef(); nodalConnIndx->incrRef();
2753       return true;
2754     }
2755   int bg=_conn_indx->front(),end=_conn_indx->back();
2756   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nc(_conn->selectByTupleId2(bg,end,1));
2757   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nci(_conn_indx->deepCpy());
2758   nci->applyLin(1,-bg);
2759   nodalConn=nc.retn(); nodalConnIndx=nci.retn();
2760   return false;
2761 }
2762
2763 /*
2764  * 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)
2765  * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
2766  * If nodal connectivity index points to a subpart of nodal connectivity index false will be returned.
2767  * \return bool - true if \a this looks packed, false is not.
2768  *
2769  * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkCoherency test
2770  */
2771 bool MEDCoupling1DGTUMesh::isPacked() const throw(INTERP_KERNEL::Exception)
2772 {
2773   checkCoherency();
2774   return _conn_indx->front()==0 && _conn_indx->back()==_conn->getNumberOfTuples();
2775 }
2776
2777 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(const MEDCoupling1DGTUMesh *mesh1, const MEDCoupling1DGTUMesh *mesh2) throw(INTERP_KERNEL::Exception)
2778 {
2779   std::vector<const MEDCoupling1DGTUMesh *> tmp(2);
2780   tmp[0]=const_cast<MEDCoupling1DGTUMesh *>(mesh1); tmp[1]=const_cast<MEDCoupling1DGTUMesh *>(mesh2);
2781   return Merge1DGTUMeshes(tmp);
2782 }
2783
2784 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(std::vector<const MEDCoupling1DGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
2785 {
2786   std::size_t sz=a.size();
2787   if(sz==0)
2788     return Merge1DGTUMeshesLL(a);
2789   for(std::size_t ii=0;ii<sz;ii++)
2790     if(!a[ii])
2791       {
2792         std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::Merge1DGTUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !";
2793         throw INTERP_KERNEL::Exception(oss.str().c_str());
2794       }
2795   const INTERP_KERNEL::CellModel *cm=&(a[0]->getCellModel());
2796   for(std::size_t ii=0;ii<sz;ii++)
2797     if(&(a[ii]->getCellModel())!=cm)
2798       throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : all items must have the same geo type !");
2799   std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > bb(sz);
2800   std::vector< const MEDCoupling1DGTUMesh * > aa(sz);
2801   int spaceDim=-3;
2802   for(std::size_t i=0;i<sz && spaceDim==-3;i++)
2803     {
2804       const MEDCoupling1DGTUMesh *cur=a[i];
2805       const DataArrayDouble *coo=cur->getCoords();
2806       if(coo)
2807         spaceDim=coo->getNumberOfComponents();
2808     }
2809   if(spaceDim==-3)
2810     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : no spaceDim specified ! unable to perform merge !");
2811   for(std::size_t i=0;i<sz;i++)
2812     {
2813       bb[i]=a[i]->buildSetInstanceFromThis(spaceDim);
2814       aa[i]=bb[i];
2815     }
2816   return Merge1DGTUMeshesLL(aa);
2817 }
2818
2819 /*!
2820  * \throw If presence of a null instance in the input vector \a a.
2821  * \throw If a is empty
2822  */
2823 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords(std::vector<const MEDCoupling1DGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
2824 {
2825   if(a.empty())
2826     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : input array must be NON EMPTY !");
2827   std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin();
2828   if(!(*it))
2829     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : null instance in the first element of input vector !");
2830   std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > objs(a.size());
2831   std::vector<const DataArrayInt *> ncs(a.size()),ncis(a.size());
2832   int nbOfCells=(*it)->getNumberOfCells();
2833   const DataArrayDouble *coords=(*it)->getCoords();
2834   const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
2835   bool tmp;
2836   objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp);
2837   ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex();
2838   it++;
2839   for(int i=1;it!=a.end();i++,it++)
2840     {
2841       if(!(*it))
2842         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : presence of null instance !");
2843       if(cm!=&((*it)->getCellModel()))
2844         throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !");
2845       (*it)->getNumberOfCells();//to check that all is OK
2846       objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp);
2847       ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex();
2848       if(coords!=(*it)->getCoords())
2849         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : not lying on same coords !");
2850     }
2851   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm));
2852   ret->setCoords(coords);
2853   ret->_conn=DataArrayInt::Aggregate(ncs);
2854   ret->_conn_indx=DataArrayInt::AggregateIndexes(ncis);
2855   return ret.retn();
2856 }
2857
2858 /*!
2859  * 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)
2860  */
2861 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesLL(std::vector<const MEDCoupling1DGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
2862 {
2863   if(a.empty())
2864     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : input array must be NON EMPTY !");
2865   std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > objs(a.size());
2866   std::vector<const DataArrayInt *> ncs(a.size()),ncis(a.size());
2867   std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin();
2868   std::vector<int> nbNodesPerElt(a.size());
2869   int nbOfCells=(*it)->getNumberOfCells();
2870   bool tmp;
2871   objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp);
2872   ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex();
2873   nbNodesPerElt[0]=0;
2874   int prevNbOfNodes=(*it)->getNumberOfNodes();
2875   const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
2876   it++;
2877   for(int i=1;it!=a.end();i++,it++)
2878     {
2879       if(cm!=&((*it)->getCellModel()))
2880         throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !");
2881       objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp);
2882       ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex();
2883       nbOfCells+=(*it)->getNumberOfCells();
2884       nbNodesPerElt[i]=nbNodesPerElt[i-1]+prevNbOfNodes;
2885       prevNbOfNodes=(*it)->getNumberOfNodes();
2886     }
2887   std::vector<const MEDCouplingPointSet *> aps(a.size());
2888   std::copy(a.begin(),a.end(),aps.begin());
2889   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> pts=MergeNodesArray(aps);
2890   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm));
2891   ret->setCoords(pts);
2892   ret->_conn=AggregateNodalConnAndShiftNodeIds(ncs,nbNodesPerElt);
2893   ret->_conn_indx=DataArrayInt::AggregateIndexes(ncis);
2894   return ret.retn();
2895 }
2896
2897 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::buildSetInstanceFromThis(int spaceDim) const throw(INTERP_KERNEL::Exception)
2898 {
2899   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName().c_str(),*_cm));
2900   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1,tmp2;
2901   const DataArrayInt *nodalConn(_conn),*nodalConnI(_conn_indx);
2902   if(!nodalConn)
2903     {
2904       tmp1=DataArrayInt::New(); tmp1->alloc(0,1);
2905     }
2906   else
2907     tmp1=_conn;
2908   ret->_conn=tmp1;
2909   //
2910   if(!nodalConnI)
2911     {
2912       tmp2=DataArrayInt::New(); tmp2->alloc(1,1); tmp2->setIJ(0,0,0);
2913     }
2914   else
2915     tmp2=_conn_indx;
2916   ret->_conn_indx=tmp2;
2917   //
2918   if(!_coords)
2919     {
2920       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim);
2921       ret->setCoords(coords);
2922     }
2923   else
2924     ret->setCoords(_coords);
2925   return ret.retn();
2926 }
2927
2928 std::vector<int> MEDCoupling1DGTUMesh::BuildAPolygonFromParts(const std::vector< std::vector<int> >& parts) throw(INTERP_KERNEL::Exception)
2929 {
2930   std::vector<int> ret;
2931   if(parts.empty())
2932     return ret;
2933   ret.insert(ret.end(),parts[0].begin(),parts[0].end());
2934   int ref(ret.back());
2935   std::size_t sz(parts.size()),nbh(1);
2936   std::vector<bool> b(sz,true); b[0]=false;
2937   while(nbh<sz)
2938     {
2939       std::size_t i(0);
2940       for(;i<sz;i++) if(b[i] && parts[i].front()==ref) { ret.insert(ret.end(),parts[i].begin()+1,parts[i].end()); nbh++; break; }
2941       if(i<sz)
2942         ref=ret.back();
2943       else
2944         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::BuildAPolygonFromParts : the input vector is not a part of a single polygon !");
2945     }
2946   if(ret.back()==ret.front())
2947     ret.pop_back();
2948   return ret;
2949 }
2950
2951 /*!
2952  * This method performs an aggregation of \a nodalConns (as DataArrayInt::Aggregate does) but in addition of that a shift is applied on the 
2953  * values contained in \a nodalConns using corresponding offset specified in input \a offsetInNodeIdsPerElt.
2954  * But it also manage the values -1, that have a semantic in MEDCoupling1DGTUMesh class (separator for polyhedron).
2955  *
2956  * \param [in] nodalConns - a list of nodal connectivity arrays same size than \a offsetInNodeIdsPerElt.
2957  * \param [in] offsetInNodeIdsPerElt - a list of offsets to apply.
2958  * \return DataArrayInt * - A new object (to be managed by the caller) that is the result of the aggregation.
2959  * \throw If \a nodalConns or \a offsetInNodeIdsPerElt are empty.
2960  * \throw If \a nodalConns and \a offsetInNodeIdsPerElt have not the same size.
2961  * \throw If presence of null pointer in \a nodalConns.
2962  * \throw If presence of not allocated or array with not exactly one component in \a nodalConns.
2963  */
2964 DataArrayInt *MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds(const std::vector<const DataArrayInt *>& nodalConns, const std::vector<int>& offsetInNodeIdsPerElt) throw(INTERP_KERNEL::Exception)
2965 {
2966   std::size_t sz1(nodalConns.size()),sz2(offsetInNodeIdsPerElt.size());
2967   if(sz1!=sz2)
2968     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : input vectors do not have the same size !");
2969   if(sz1==0)
2970     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : empty vectors in input !");
2971   int nbOfTuples=0;
2972   for(std::vector<const DataArrayInt *>::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++)
2973     {
2974       if(!(*it))
2975         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of null pointer in input vector !");
2976       if(!(*it)->isAllocated())
2977         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of non allocated array in input vector !");
2978       if((*it)->getNumberOfComponents()!=1)
2979         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of array with not exactly one component !");
2980       nbOfTuples+=(*it)->getNumberOfTuples();
2981     }
2982   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
2983   int *pt=ret->getPointer();
2984   int i=0;
2985   for(std::vector<const DataArrayInt *>::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++,i++)
2986     {
2987       int curNbt=(*it)->getNumberOfTuples();
2988       const int *inPt=(*it)->begin();
2989       int offset=offsetInNodeIdsPerElt[i];
2990       for(int j=0;j<curNbt;j++,pt++)
2991         {
2992           if(inPt[j]!=-1)
2993             *pt=inPt[j]+offset;
2994           else
2995             *pt=-1;
2996         }
2997     }
2998   return ret.retn();
2999 }
3000
3001 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const MEDCouplingUMesh *m) throw(INTERP_KERNEL::Exception)
3002 {
3003   if(!m)
3004     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : input mesh is null !");
3005   std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes());
3006   if(gts.size()!=1)
3007     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : input mesh must have exactly one geometric type !");
3008   int geoType((int)*gts.begin());
3009   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(m->getName().c_str(),*gts.begin()));
3010   ret->setCoords(m->getCoords()); ret->setDescription(m->getDescription().c_str());
3011   int nbCells(m->getNumberOfCells());
3012   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()),connI(DataArrayInt::New());
3013   conn->alloc(m->getMeshLength()-nbCells,1); connI->alloc(nbCells+1,1);
3014   int *c(conn->getPointer()),*ci(connI->getPointer()); *ci=0;
3015   const int *cin(m->getNodalConnectivity()->begin()),*ciin(m->getNodalConnectivityIndex()->begin());
3016   for(int i=0;i<nbCells;i++,ciin++,ci++)
3017     {
3018       if(cin[ciin[0]]==geoType)
3019         {
3020           if(ciin[1]-ciin[0]>=1)
3021             {
3022               c=std::copy(cin+ciin[0]+1,cin+ciin[1],c);
3023               ci[1]=ci[0]+ciin[1]-ciin[0]-1;
3024             }
3025           else
3026             {
3027               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 !";
3028               throw INTERP_KERNEL::Exception(oss.str().c_str());
3029             }
3030         }
3031       else
3032         {
3033           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 !";
3034           throw INTERP_KERNEL::Exception(oss.str().c_str());
3035         }
3036     }
3037   ret->setNodalConnectivity(conn,connI);
3038   return ret.retn();
3039 }