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