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