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