Salome HOME
4th dimension of DataArrayDouble::findCommonTuples
[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   if(myNeighbours[validAxis]==neighId && allFacesNodalConn[4*validAxis+0]==validConnQuad4NeighSide[0])
1669     return true;
1670   int oldAxis((int)std::distance(myNeighbours,std::find(myNeighbours,myNeighbours+6,neighId)));
1671   std::size_t pos(std::distance(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS,std::find(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS,MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS+6,oldAxis)));
1672   std::size_t pos0(pos/2),pos1(pos%2);
1673   int oldAxisOpp(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS[2*pos0+(pos1+1)%2]);
1674   int oldConn[8],myConn[8]={-1,-1,-1,-1,-1,-1,-1,-1},tmpConn[4],tmpConn2[8]={0,1,2,3,4,5,6,7},edgeConn[2],allFacesTmp[24],neighTmp[6];
1675   oldConn[0]=allFacesNodalConn[0]; oldConn[1]=allFacesNodalConn[1]; oldConn[2]=allFacesNodalConn[2]; oldConn[3]=allFacesNodalConn[3];
1676   oldConn[4]=allFacesNodalConn[4]; oldConn[5]=allFacesNodalConn[7]; oldConn[6]=allFacesNodalConn[6]; oldConn[7]=allFacesNodalConn[5];
1677   const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_HEXA8));
1678   cm.fillSonCellNodalConnectivity(validAxis,tmpConn2,tmpConn);
1679   for(int i=0;i<4;i++)
1680     myConn[tmpConn[i]]=validConnQuad4NeighSide[(4-i)%4];
1681   for(int i=0;i<4;i++)
1682     {
1683       int nodeId(myConn[i]!=-1?myConn[i]:myConn[4+i]);//the node id for which the opposite one will be found
1684       bool found(false);
1685       INTERP_KERNEL::NormalizedCellType typeOfSon;
1686       for(int j=0;j<12 && !found;j++)
1687         {
1688           cm.fillSonEdgesNodalConnectivity3D(j,oldConn,-1,edgeConn,typeOfSon);
1689           if(edgeConn[0]==nodeId || edgeConn[1]==nodeId)
1690             {
1691               if(std::find(allFacesNodalConn+4*oldAxisOpp,allFacesNodalConn+4*oldAxisOpp+4,edgeConn[0]==nodeId?edgeConn[1]:edgeConn[0])!=allFacesNodalConn+4*oldAxisOpp+4)
1692                 {
1693                   if(myConn[i]==-1)
1694                     myConn[myConn[i]]=edgeConn[0]==nodeId?edgeConn[1]:edgeConn[0];
1695                   else
1696                     myConn[myConn[i]+4]=edgeConn[0]==nodeId?edgeConn[1]:edgeConn[0];
1697                   found=true;
1698                 }
1699             }
1700         }
1701       if(!found)
1702         throw INTERP_KERNEL::Exception("UpdateHexa8Cell : Internal Error !");
1703     }
1704   for(int i=0;i<6;i++)
1705     {
1706       cm.fillSonCellNodalConnectivity(i,myConn,allFacesTmp+4*i);
1707       std::set<int> s(allFacesTmp+4*i,allFacesTmp+4*i+4);
1708       bool found(false);
1709       for(int j=0;j<6 && !found;j++)
1710         {
1711           std::set<int> s1(allFacesNodalConn+4*j,allFacesNodalConn+4*j+4);
1712           if(s==s1)
1713             {
1714               neighTmp[i]=myNeighbours[j];
1715               found=true;
1716             }
1717         }
1718       if(!found)
1719         throw INTERP_KERNEL::Exception("UpdateHexa8Cell : Internal Error #2 !");
1720     }
1721   std::copy(allFacesTmp,allFacesTmp+24,allFacesNodalConn);
1722   std::copy(neighTmp,neighTmp+6,myNeighbours);
1723   return false;
1724 }
1725
1726 /// @endcond
1727
1728 /*!
1729  * 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
1730  * homogeneous. If it succeeds the result of MEDCouplingUMesh::tetrahedrize will return a conform mesh.
1731  *
1732  * \return DataArrayInt * - a newly allocated array (to be managed by the caller) containing renumbered cell ids.
1733  *
1734  * \throw If \a this is not a mesh containing only NORM_HEXA8 cells.
1735  * \throw If \a this is not properly allocated.
1736  * \sa MEDCouplingUMesh::tetrahedrize, MEDCouplingUMesh::simplexize.
1737  */
1738 DataArrayInt *MEDCoupling1SGTUMesh::sortHexa8EachOther()
1739 {
1740   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> quads(explodeEachHexa8To6Quad4());//checks that only hexa8
1741   int nbHexa8(getNumberOfCells()),*cQuads(quads->getNodalConnectivity()->getPointer());
1742   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> neighOfQuads(DataArrayInt::New()); neighOfQuads->alloc(nbHexa8*6,1); neighOfQuads->fillWithValue(-1);
1743   int *ptNeigh(neighOfQuads->getPointer());
1744   {//neighOfQuads tells for each face of each Quad8 which cell (if!=-1) is connected to this face.
1745     MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> quadsTmp(quads->buildUnstructured());
1746     MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ccSafe,cciSafe;
1747     DataArrayInt *cc(0),*cci(0);
1748     quadsTmp->findCommonCells(3,0,cc,cci);
1749     ccSafe=cc; cciSafe=cci;
1750     const int *ccPtr(ccSafe->begin()),nbOfPair(cci->getNumberOfTuples()-1);
1751     for(int i=0;i<nbOfPair;i++)
1752       { ptNeigh[ccPtr[2*i+0]]=ccPtr[2*i+1]/6; ptNeigh[ccPtr[2*i+1]]=ccPtr[2*i+0]/6; }
1753   }
1754   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
1755   std::vector<bool> fetched(nbHexa8,false);
1756   std::vector<bool>::iterator it(std::find(fetched.begin(),fetched.end(),true));
1757   while(it!=fetched.end())//it will turns as time as number of connected zones
1758     {
1759       int cellId((int)std::distance(fetched.begin(),it));//it is the seed of the connected zone.
1760       std::set<int> s; s.insert(cellId);//s contains already organized.
1761       while(!s.empty())
1762         {
1763           std::set<int> sNext;
1764           for(std::set<int>::const_iterator it0=s.begin();it0!=s.end();it0++)
1765             {
1766               fetched[*it0]=true;
1767               int *myNeighb(ptNeigh+6*(*it0));
1768               for(int i=0;i<6;i++)
1769                 {
1770                   std::size_t pos(std::distance(HEXA8_FACE_PAIRS,std::find(HEXA8_FACE_PAIRS,HEXA8_FACE_PAIRS+6,i)));
1771                   std::size_t pos0(pos/2),pos1(pos%2);
1772                   if(myNeighb[i]!=-1)
1773                     {
1774                       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]))
1775                         ret->pushBackSilent(myNeighb[i]);
1776                       sNext.insert(myNeighb[i]);
1777                     }
1778                 }
1779             }
1780           s=sNext;
1781         }
1782     }
1783   return ret.retn();
1784 }
1785
1786 MEDCoupling1DGTUMesh *MEDCoupling1SGTUMesh::computeDualMesh3D() const
1787 {
1788   static const int DUAL_TETRA_0[36]={
1789     4,1,0, 6,0,3, 7,3,1,
1790     4,0,1, 5,2,0, 8,1,2,
1791     6,3,0, 5,0,2, 9,2,3,
1792     7,1,3, 9,3,2, 8,2,1
1793   };
1794   static const int DUAL_TETRA_1[36]={
1795     8,4,10, 11,5,8, 10,7,11,
1796     9,4,8, 8,5,12, 12,6,9,
1797     10,4,9, 9,6,13, 13,7,10,
1798     12,5,11, 13,6,12, 11,7,13
1799   };
1800   static const int FACEID_NOT_SH_NODE[4]={2,3,1,0};
1801   if(getCellModelEnum()!=INTERP_KERNEL::NORM_TETRA4)
1802     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh3D : only TETRA4 supported !");
1803   checkFullyDefined();
1804   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> thisu(buildUnstructured());
1805   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revNodArr(DataArrayInt::New()),revNodIArr(DataArrayInt::New());
1806   thisu->getReverseNodalConnectivity(revNodArr,revNodIArr);
1807   const int *revNod(revNodArr->begin()),*revNodI(revNodIArr->begin()),*nodal(_conn->begin());
1808   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d1Arr(DataArrayInt::New()),di1Arr(DataArrayInt::New()),rd1Arr(DataArrayInt::New()),rdi1Arr(DataArrayInt::New());
1809   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> edges(thisu->explode3DMeshTo1D(d1Arr,di1Arr,rd1Arr,rdi1Arr));
1810   const int *d1(d1Arr->begin());
1811   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d2Arr(DataArrayInt::New()),di2Arr(DataArrayInt::New()),rd2Arr(DataArrayInt::New()),rdi2Arr(DataArrayInt::New());
1812   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> faces(thisu->buildDescendingConnectivity(d2Arr,di2Arr,rd2Arr,rdi2Arr));  thisu=0;
1813   const int *d2(d2Arr->begin()),*rdi2(rdi2Arr->begin());
1814   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> edgesBaryArr(edges->getBarycenterAndOwner()),facesBaryArr(faces->getBarycenterAndOwner()),baryArr(getBarycenterAndOwner());
1815   const int nbOfNodes(getNumberOfNodes()),offset0(nbOfNodes+faces->getNumberOfCells()),offset1(offset0+edges->getNumberOfCells());
1816   edges=0; faces=0;
1817   std::vector<const DataArrayDouble *> v(4); v[0]=getCoords(); v[1]=facesBaryArr; v[2]=edgesBaryArr; v[3]=baryArr;
1818   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> zeArr(DataArrayDouble::Aggregate(v)); baryArr=0; edgesBaryArr=0; facesBaryArr=0;
1819   std::string name("DualOf_"); name+=getName();
1820   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(name.c_str(),INTERP_KERNEL::NORM_POLYHED)); ret->setCoords(zeArr);
1821   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),ciArr(DataArrayInt::New()); ciArr->alloc(nbOfNodes+1,1); ciArr->setIJ(0,0,0); cArr->alloc(0,1);
1822   for(int i=0;i<nbOfNodes;i++,revNodI++)
1823     {
1824       int nbOfCellsSharingNode(revNodI[1]-revNodI[0]);
1825       if(nbOfCellsSharingNode==0)
1826         {
1827           std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeDualMesh3D : Node #" << i << " is orphan !"; 
1828           throw INTERP_KERNEL::Exception(oss.str().c_str());
1829         }
1830       for(int j=0;j<nbOfCellsSharingNode;j++)
1831         {
1832           int curCellId(revNod[revNodI[0]+j]);
1833           const int *connOfCurCell(nodal+4*curCellId);
1834           std::size_t nodePosInCurCell(std::distance(connOfCurCell,std::find(connOfCurCell,connOfCurCell+4,i)));
1835           if(j!=0) cArr->pushBackSilent(-1);
1836           int tmp[14];
1837           //
1838           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;
1839           tmp[2]=curCellId+offset1; tmp[3]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+2]]+nbOfNodes;
1840           tmp[4]=-1;
1841           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;
1842           tmp[7]=curCellId+offset1; tmp[8]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+5]]+nbOfNodes;
1843           tmp[9]=-1;
1844           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;
1845           tmp[12]=curCellId+offset1; tmp[13]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+8]]+nbOfNodes;
1846           cArr->insertAtTheEnd(tmp,tmp+14);
1847           int kk(0);
1848           for(int k=0;k<4;k++)
1849             {
1850               if(FACEID_NOT_SH_NODE[nodePosInCurCell]!=k)
1851                 {
1852                   const int *faceId(d2+4*curCellId+k);
1853                   if(rdi2[*faceId+1]-rdi2[*faceId]==1)
1854                     {
1855                       int tmp2[5]; tmp2[0]=-1; tmp2[1]=i;
1856                       tmp2[2]=d1[6*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+0]-8]+offset0;
1857                       tmp2[3]=d2[4*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+1]-4]+nbOfNodes;
1858                       tmp2[4]=d1[6*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+2]-8]+offset0;
1859                       cArr->insertAtTheEnd(tmp2,tmp2+5);
1860                     }
1861                   kk++;
1862                 }
1863             }
1864         }
1865       ciArr->setIJ(i+1,0,cArr->getNumberOfTuples());
1866     }
1867   ret->setNodalConnectivity(cArr,ciArr);
1868   return ret.retn();
1869 }
1870
1871 MEDCoupling1DGTUMesh *MEDCoupling1SGTUMesh::computeDualMesh2D() const
1872 {
1873   static const int DUAL_TRI_0[6]={0,2, 1,0, 2,1};
1874   static const int DUAL_TRI_1[6]={-3,+5, +3,-4, +4,-5};
1875   static const int FACEID_NOT_SH_NODE[3]={1,2,0};
1876   if(getCellModelEnum()!=INTERP_KERNEL::NORM_TRI3)
1877     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh2D : only TRI3 supported !");
1878   checkFullyDefined();
1879   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> thisu(buildUnstructured());
1880   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revNodArr(DataArrayInt::New()),revNodIArr(DataArrayInt::New());
1881   thisu->getReverseNodalConnectivity(revNodArr,revNodIArr);
1882   const int *revNod(revNodArr->begin()),*revNodI(revNodIArr->begin()),*nodal(_conn->begin());
1883   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d2Arr(DataArrayInt::New()),di2Arr(DataArrayInt::New()),rd2Arr(DataArrayInt::New()),rdi2Arr(DataArrayInt::New());
1884   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> edges(thisu->buildDescendingConnectivity(d2Arr,di2Arr,rd2Arr,rdi2Arr));  thisu=0;
1885   const int *d2(d2Arr->begin()),*rdi2(rdi2Arr->begin());
1886   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> edgesBaryArr(edges->getBarycenterAndOwner()),baryArr(getBarycenterAndOwner());
1887   const int nbOfNodes(getNumberOfNodes()),offset0(nbOfNodes+edges->getNumberOfCells());
1888   edges=0;
1889   std::vector<const DataArrayDouble *> v(3); v[0]=getCoords(); v[1]=edgesBaryArr; v[2]=baryArr;
1890   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> zeArr(DataArrayDouble::Aggregate(v)); baryArr=0; edgesBaryArr=0;
1891   std::string name("DualOf_"); name+=getName();
1892   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(name.c_str(),INTERP_KERNEL::NORM_POLYGON)); ret->setCoords(zeArr);
1893   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),ciArr(DataArrayInt::New()); ciArr->alloc(nbOfNodes+1,1); ciArr->setIJ(0,0,0); cArr->alloc(0,1);
1894   for(int i=0;i<nbOfNodes;i++,revNodI++)
1895     {
1896       int nbOfCellsSharingNode(revNodI[1]-revNodI[0]);
1897       if(nbOfCellsSharingNode==0)
1898         {
1899           std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeDualMesh2D : Node #" << i << " is orphan !"; 
1900           throw INTERP_KERNEL::Exception(oss.str().c_str());
1901         }
1902       std::vector< std::vector<int> > polyg;
1903       for(int j=0;j<nbOfCellsSharingNode;j++)
1904         {
1905           int curCellId(revNod[revNodI[0]+j]);
1906           const int *connOfCurCell(nodal+3*curCellId);
1907           std::size_t nodePosInCurCell(std::distance(connOfCurCell,std::find(connOfCurCell,connOfCurCell+4,i)));
1908           std::vector<int> locV(3);
1909           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;
1910           polyg.push_back(locV);
1911           int kk(0);
1912           for(int k=0;k<3;k++)
1913             {
1914               if(FACEID_NOT_SH_NODE[nodePosInCurCell]!=k)
1915                 {
1916                   const int *edgeId(d2+3*curCellId+k);
1917                   if(rdi2[*edgeId+1]-rdi2[*edgeId]==1)
1918                     {
1919                       std::vector<int> locV2(2);
1920                       int zeLocEdgeIdRel(DUAL_TRI_1[2*nodePosInCurCell+kk]);
1921                       if(zeLocEdgeIdRel>0)
1922                         {  locV2[0]=d2[3*curCellId+zeLocEdgeIdRel-3]+nbOfNodes;  locV2[1]=i; }
1923                       else
1924                         {  locV2[0]=i; locV2[1]=d2[3*curCellId-zeLocEdgeIdRel-3]+nbOfNodes; }
1925                       polyg.push_back(locV2);
1926                     }
1927                   kk++;
1928                 }
1929             }
1930         }
1931       std::vector<int> zePolyg(MEDCoupling1DGTUMesh::BuildAPolygonFromParts(polyg));
1932       cArr->insertAtTheEnd(zePolyg.begin(),zePolyg.end());
1933       ciArr->setIJ(i+1,0,cArr->getNumberOfTuples());
1934     }
1935   ret->setNodalConnectivity(cArr,ciArr);
1936   return ret.retn();
1937 }
1938
1939 /*!
1940  * This method aggregate the bbox of each cell and put it into bbox 
1941  *
1942  * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components.
1943  * 
1944  * \throw If \a this is not fully set (coordinates and connectivity).
1945  * \throw If a cell in \a this has no valid nodeId.
1946  */
1947 DataArrayDouble *MEDCoupling1SGTUMesh::getBoundingBoxForBBTree() const
1948 {
1949   int spaceDim(getSpaceDimension()),nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes()),nbOfNodesPerCell(getNumberOfNodesPerCell());
1950   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim);
1951   double *bbox(ret->getPointer());
1952   for(int i=0;i<nbOfCells*spaceDim;i++)
1953     {
1954       bbox[2*i]=std::numeric_limits<double>::max();
1955       bbox[2*i+1]=-std::numeric_limits<double>::max();
1956     }
1957   const double *coordsPtr(_coords->getConstPointer());
1958   const int *conn(_conn->getConstPointer());
1959   for(int i=0;i<nbOfCells;i++)
1960     {
1961       int kk(0);
1962       for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1963         {
1964           int nodeId(*conn);
1965           if(nodeId>=0 && nodeId<nbOfNodes)
1966             {
1967               for(int k=0;k<spaceDim;k++)
1968                 {
1969                   bbox[2*spaceDim*i+2*k]=std::min(bbox[2*spaceDim*i+2*k],coordsPtr[spaceDim*nodeId+k]);
1970                   bbox[2*spaceDim*i+2*k+1]=std::max(bbox[2*spaceDim*i+2*k+1],coordsPtr[spaceDim*nodeId+k]);
1971                 }
1972               kk++;
1973             }
1974         }
1975       if(kk==0)
1976         {
1977           std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getBoundingBoxForBBTree : cell #" << i << " contains no valid nodeId !";
1978           throw INTERP_KERNEL::Exception(oss.str().c_str());
1979         }
1980     }
1981   return ret.retn();
1982 }
1983
1984 //== 
1985
1986 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New()
1987 {
1988   return new MEDCoupling1DGTUMesh;
1989 }
1990
1991 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const char *name, INTERP_KERNEL::NormalizedCellType type)
1992 {
1993   if(type==INTERP_KERNEL::NORM_ERROR)
1994     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
1995   const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
1996   if(!cm.isDynamic())
1997     {
1998       std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::New : the input geometric type " << cm.getRepr() << " is static ! Only dynamic types are allowed here !";
1999       throw INTERP_KERNEL::Exception(oss.str().c_str());
2000     }
2001   return new MEDCoupling1DGTUMesh(name,cm);
2002 }
2003
2004 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh()
2005 {
2006 }
2007
2008 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const char *name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm)
2009 {
2010 }
2011
2012 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const MEDCoupling1DGTUMesh& other, bool recDeepCpy):MEDCoupling1GTUMesh(other,recDeepCpy),_conn(other._conn)
2013 {
2014   if(recDeepCpy)
2015     {
2016       const DataArrayInt *c(other._conn);
2017       if(c)
2018         _conn=c->deepCpy();
2019       c=other._conn_indx;
2020       if(c)
2021         _conn_indx=c->deepCpy();
2022     }
2023 }
2024
2025 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::clone(bool recDeepCpy) const
2026 {
2027   return new MEDCoupling1DGTUMesh(*this,recDeepCpy);
2028 }
2029
2030 /*!
2031  * This method behaves mostly like MEDCoupling1DGTUMesh::deepCpy method, except that only nodal connectivity arrays are deeply copied.
2032  * The coordinates are shared between \a this and the returned instance.
2033  * 
2034  * \return MEDCouplingUMesh * - A new object instance holding the copy of \a this (deep for connectivity, shallow for coordiantes)
2035  * \sa MEDCoupling1DGTUMesh::deepCpy
2036  */
2037 MEDCouplingPointSet *MEDCoupling1DGTUMesh::deepCpyConnectivityOnly() const
2038 {
2039   checkCoherency();
2040   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(clone(false));
2041   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(_conn->deepCpy()),ci(_conn_indx->deepCpy());
2042   ret->setNodalConnectivity(c,ci);
2043   return ret.retn();
2044 }
2045
2046 void MEDCoupling1DGTUMesh::updateTime() const
2047 {
2048   MEDCoupling1GTUMesh::updateTime();
2049   const DataArrayInt *c(_conn);
2050   if(c)
2051     updateTimeWith(*c);
2052   c=_conn_indx;
2053   if(c)
2054     updateTimeWith(*c);
2055 }
2056
2057 std::size_t MEDCoupling1DGTUMesh::getHeapMemorySizeWithoutChildren() const
2058 {
2059   return MEDCoupling1GTUMesh::getHeapMemorySizeWithoutChildren();
2060 }
2061
2062 std::vector<const BigMemoryObject *> MEDCoupling1DGTUMesh::getDirectChildren() const
2063 {
2064   std::vector<const BigMemoryObject *> ret(MEDCoupling1GTUMesh::getDirectChildren());
2065   const DataArrayInt *c(_conn);
2066   if(c)
2067     ret.push_back(c);
2068   c=_conn_indx;
2069   if(c)
2070     ret.push_back(c);
2071   return ret;
2072 }
2073
2074 MEDCouplingMesh *MEDCoupling1DGTUMesh::deepCpy() const
2075 {
2076   return clone(true);
2077 }
2078
2079 bool MEDCoupling1DGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const
2080 {
2081   if(!other)
2082     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualIfNotWhy : input other pointer is null !");
2083   std::ostringstream oss; oss.precision(15);
2084   const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2085   if(!otherC)
2086     {
2087       reason="mesh given in input is not castable in MEDCoupling1DGTUMesh !";
2088       return false;
2089     }
2090   if(!MEDCoupling1GTUMesh::isEqualIfNotWhy(other,prec,reason))
2091     return false;
2092   const DataArrayInt *c1(_conn),*c2(otherC->_conn);
2093   if(c1==c2)
2094     return true;
2095   if(!c1 || !c2)
2096     {
2097       reason="in connectivity of single dynamic geometric type exactly one among this and other is null !";
2098       return false;
2099     }
2100   if(!c1->isEqualIfNotWhy(*c2,reason))
2101     {
2102       reason.insert(0,"Nodal connectivity DataArrayInt differs : ");
2103       return false;
2104     }
2105   c1=_conn_indx; c2=otherC->_conn_indx;
2106   if(c1==c2)
2107     return true;
2108   if(!c1 || !c2)
2109     {
2110       reason="in connectivity index of single dynamic geometric type exactly one among this and other is null !";
2111       return false;
2112     }
2113   if(!c1->isEqualIfNotWhy(*c2,reason))
2114     {
2115       reason.insert(0,"Nodal connectivity index DataArrayInt differs : ");
2116       return false;
2117     }
2118   return true;
2119 }
2120
2121 bool MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
2122 {
2123   if(!other)
2124     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
2125   const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2126   if(!otherC)
2127     return false;
2128   if(!MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(other,prec))
2129     return false;
2130   const DataArrayInt *c1(_conn),*c2(otherC->_conn);
2131   if(c1==c2)
2132     return true;
2133   if(!c1 || !c2)
2134     return false;
2135   if(!c1->isEqualWithoutConsideringStr(*c2))
2136     return false;
2137   return true;
2138   c1=_conn_indx; c2=otherC->_conn_indx;
2139   if(c1==c2)
2140     return true;
2141   if(!c1 || !c2)
2142     return false;
2143   if(!c1->isEqualWithoutConsideringStr(*c2))
2144     return false;
2145   return true;
2146 }
2147
2148 /*!
2149  * Checks if \a this and \a other meshes are geometrically equivalent with high
2150  * probability, else an exception is thrown. The meshes are considered equivalent if
2151  * (1) meshes contain the same number of nodes and the same number of elements of the
2152  * same types (2) three cells of the two meshes (first, last and middle) are based
2153  * on coincident nodes (with a specified precision).
2154  *  \param [in] other - the mesh to compare with.
2155  *  \param [in] prec - the precision used to compare nodes of the two meshes.
2156  *  \throw If the two meshes do not match.
2157  */
2158 void MEDCoupling1DGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const
2159 {
2160   MEDCouplingPointSet::checkFastEquivalWith(other,prec);
2161   const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2162   if(!otherC)
2163     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : Two meshes are not unstructured with single dynamic geometric type !");
2164   const DataArrayInt *c1(_conn),*c2(otherC->_conn);
2165   if(c1!=c2)
2166     {
2167       if(!c1 || !c2)
2168         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !");
2169       if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
2170         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !");
2171       if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
2172         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !");
2173       if(c1->getHashCode()!=c2->getHashCode())
2174         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity differs");
2175     }
2176   c1=_conn_indx; c2=otherC->_conn_indx;
2177   if(c1!=c2)
2178     {
2179       if(!c1 || !c2)
2180         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity index only in one of the 2 meshes !");
2181       if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
2182         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, only one is allocated !");
2183       if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
2184         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, must have 1 and only 1 component !");
2185       if(c1->getHashCode()!=c2->getHashCode())
2186         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity index differs");
2187     }
2188 }
2189
2190 void MEDCoupling1DGTUMesh::checkCoherencyOfConnectivity() const
2191 {
2192   const DataArrayInt *c1(_conn);
2193   if(c1)
2194     {
2195       if(c1->getNumberOfComponents()!=1)
2196         throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !");
2197       if(c1->getInfoOnComponent(0)!="")
2198         throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !");
2199       c1->checkAllocated();
2200     }
2201   else
2202     throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !");
2203   //
2204   int sz2=_conn->getNumberOfTuples();
2205   c1=_conn_indx;
2206   if(c1)
2207     {
2208       if(c1->getNumberOfComponents()!=1)
2209         throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to be with number of components set to one !");
2210       c1->checkAllocated();
2211       if(c1->getNumberOfTuples()<1)
2212         throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have a a size of 1 at least !");
2213       if(c1->getInfoOnComponent(0)!="")
2214         throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have no info on its single component !");
2215       int f=c1->front(),ll=c1->back();
2216       if(f<0 || f>=sz2)
2217         {
2218           std::ostringstream oss; oss << "Nodal connectivity index array first value (" << f << ") is expected to be exactly in [0," << sz2 << ") !";
2219           throw INTERP_KERNEL::Exception(oss.str().c_str());
2220         }
2221       if(ll<0 || ll>sz2)
2222         {
2223           std::ostringstream oss; oss << "Nodal connectivity index array last value (" << ll << ") is expected to be exactly in [0," << sz2 << "] !";
2224           throw INTERP_KERNEL::Exception(oss.str().c_str());
2225         }
2226       if(f>ll)
2227         {
2228           std::ostringstream oss; oss << "Nodal connectivity index array looks very bad (not increasing monotonic) because front (" << f << ") is greater that back (" << ll << ") !";
2229           throw INTERP_KERNEL::Exception(oss.str().c_str());
2230         }
2231     }
2232   else
2233     throw INTERP_KERNEL::Exception("Nodal connectivity index array not defined !");
2234   int szOfC1Exp=_conn_indx->back();
2235   if(sz2<szOfC1Exp)
2236     {
2237       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() << " !";
2238       throw INTERP_KERNEL::Exception(oss.str().c_str());
2239     }
2240 }
2241
2242 /*!
2243  * 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.
2244  * In addition you are sure that the length of nodal connectivity index array is bigger than or equal to one.
2245  * In addition you are also sure that length of nodal connectivity is coherent with the content of the last value in the index array.
2246  */
2247 void MEDCoupling1DGTUMesh::checkCoherency() const
2248 {
2249   MEDCouplingPointSet::checkCoherency();
2250   checkCoherencyOfConnectivity();
2251 }
2252
2253 void MEDCoupling1DGTUMesh::checkCoherency1(double eps) const
2254 {
2255   checkCoherency();
2256   const DataArrayInt *c1(_conn),*c2(_conn_indx);
2257   if(!c2->isMonotonic(true))
2258     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkCoherency1 : the nodal connectivity index is expected to be increasing monotinic !");
2259   //
2260   int nbOfTuples=c1->getNumberOfTuples();
2261   int nbOfNodes=getNumberOfNodes();
2262   const int *w(c1->begin());
2263   for(int i=0;i<nbOfTuples;i++,w++)
2264     {
2265       if(*w==-1) continue;
2266       if(*w<0 || *w>=nbOfNodes)
2267         {
2268           std::ostringstream oss; oss << "At pos #" << i << " of nodal connectivity array references to node id #" << *w << " must be in [0," << nbOfNodes << ") !";
2269           throw INTERP_KERNEL::Exception(oss.str().c_str());
2270         }
2271     }
2272 }
2273
2274 void MEDCoupling1DGTUMesh::checkCoherency2(double eps) const
2275 {
2276   checkCoherency1(eps);
2277 }
2278
2279 int MEDCoupling1DGTUMesh::getNumberOfCells() const
2280 {
2281   checkCoherencyOfConnectivity();//do not remove
2282   return _conn_indx->getNumberOfTuples()-1;
2283 }
2284
2285 /*!
2286  * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
2287  * For each cell in \b this the number of nodes constituting cell is computed.
2288  * For each polyhedron cell, the sum of the number of nodes of each face constituting polyhedron cell is returned.
2289  * So for pohyhedrons some nodes can be counted several times in the returned result.
2290  * 
2291  * \return a newly allocated array
2292  */
2293 DataArrayInt *MEDCoupling1DGTUMesh::computeNbOfNodesPerCell() const
2294 {
2295   checkCoherency();
2296   _conn_indx->checkMonotonic(true);
2297   if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2298     return _conn_indx->deltaShiftIndex();
2299   // for polyhedrons
2300   int nbOfCells=_conn_indx->getNumberOfTuples()-1;
2301   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2302   ret->alloc(nbOfCells,1);
2303   int *retPtr=ret->getPointer();
2304   const int *ci=_conn_indx->begin(),*c=_conn->begin();
2305   for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2306     *retPtr=ci[1]-ci[0]-std::count(c+ci[0],c+ci[1],-1);
2307   return ret.retn();
2308 }
2309
2310 /*!
2311  * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
2312  * For each cell in \b this the number of faces constituting (entity of dimension this->getMeshDimension()-1) cell is computed.
2313  * 
2314  * \return a newly allocated array
2315  */
2316 DataArrayInt *MEDCoupling1DGTUMesh::computeNbOfFacesPerCell() const
2317 {
2318   checkCoherency();
2319   _conn_indx->checkMonotonic(true);
2320   if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED && getCellModelEnum()!=INTERP_KERNEL::NORM_QPOLYG)
2321     return _conn_indx->deltaShiftIndex();
2322   if(getCellModelEnum()==INTERP_KERNEL::NORM_QPOLYG)
2323     {
2324       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=_conn_indx->deltaShiftIndex();
2325       ret->applyDivideBy(2);
2326       return ret.retn();
2327     }
2328   // for polyhedrons
2329   int nbOfCells=_conn_indx->getNumberOfTuples()-1;
2330   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2331   ret->alloc(nbOfCells,1);
2332   int *retPtr=ret->getPointer();
2333   const int *ci=_conn_indx->begin(),*c=_conn->begin();
2334   for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2335     *retPtr=std::count(c+ci[0],c+ci[1],-1)+1;
2336   return ret.retn();
2337 }
2338
2339 /*!
2340  * This method computes effective number of nodes per cell. That is to say nodes appearing several times in nodal connectivity of a cell,
2341  * will be counted only once here whereas it will be counted several times in MEDCoupling1DGTUMesh::computeNbOfNodesPerCell method.
2342  *
2343  * \return DataArrayInt * - new object to be deallocated by the caller.
2344  * \sa MEDCoupling1DGTUMesh::computeNbOfNodesPerCell
2345  */
2346 DataArrayInt *MEDCoupling1DGTUMesh::computeEffectiveNbOfNodesPerCell() const
2347 {
2348   checkCoherency();
2349   _conn_indx->checkMonotonic(true);
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   if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2356     {
2357       for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2358         {
2359           std::set<int> s(c+ci[0],c+ci[1]);
2360           *retPtr=(int)s.size();
2361         }
2362     }
2363   else
2364     {
2365       for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2366         {
2367           std::set<int> s(c+ci[0],c+ci[1]); s.erase(-1);
2368           *retPtr=(int)s.size();
2369         }
2370     }
2371   return ret.retn();
2372 }
2373
2374 void MEDCoupling1DGTUMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
2375 {
2376   int nbOfCells(getNumberOfCells());//performs checks
2377   if(cellId>=0 && cellId<nbOfCells)
2378     {
2379       int strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0);
2380       int nbOfNodes=stp-strt;
2381       if(nbOfNodes<0)
2382         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::getNodeIdsOfCell : the index array is invalid ! Should be increasing monotonic !");
2383       conn.resize(nbOfNodes);
2384       std::copy(_conn->begin()+strt,_conn->begin()+stp,conn.begin());
2385     }
2386   else
2387     {
2388       std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !";
2389       throw INTERP_KERNEL::Exception(oss.str().c_str());
2390     }
2391 }
2392
2393 int MEDCoupling1DGTUMesh::getNumberOfNodesInCell(int cellId) const
2394 {
2395   int nbOfCells(getNumberOfCells());//performs checks
2396   if(cellId>=0 && cellId<nbOfCells)
2397     {
2398       const int *conn(_conn->begin());
2399       int strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0);
2400       return stp-strt-std::count(conn+strt,conn+stp,-1);
2401     }
2402   else
2403     {
2404       std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNumberOfNodesInCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !";
2405       throw INTERP_KERNEL::Exception(oss.str().c_str());
2406     }
2407 }
2408
2409 std::string MEDCoupling1DGTUMesh::simpleRepr() const
2410 {
2411   static const char msg0[]="No coordinates specified !";
2412   std::ostringstream ret;
2413   ret << "Single dynamic geometic type (" << _cm->getRepr() << ") unstructured mesh with name : \"" << getName() << "\"\n";
2414   ret << "Description of mesh : \"" << getDescription() << "\"\n";
2415   int tmpp1,tmpp2;
2416   double tt=getTime(tmpp1,tmpp2);
2417   ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
2418   ret << "Iteration : " << tmpp1  << " Order : " << tmpp2 << "\n";
2419   ret << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : ";
2420   if(_coords!=0)
2421     {
2422       const int spaceDim=getSpaceDimension();
2423       ret << spaceDim << "\nInfo attached on space dimension : ";
2424       for(int i=0;i<spaceDim;i++)
2425         ret << "\"" << _coords->getInfoOnComponent(i) << "\" ";
2426       ret << "\n";
2427     }
2428   else
2429     ret << msg0 << "\n";
2430   ret << "Number of nodes : ";
2431   if(_coords!=0)
2432     ret << getNumberOfNodes() << "\n";
2433   else
2434     ret << msg0 << "\n";
2435   ret << "Number of cells : ";
2436   bool isOK=true;
2437   try { checkCoherency(); } catch(INTERP_KERNEL::Exception& /* e */)
2438     {
2439       ret << "Nodal connectivity arrays are not set or badly set !\n";
2440       isOK=false;
2441     }
2442   if(isOK)
2443     ret << getNumberOfCells() << "\n";
2444   ret << "Cell type : " << _cm->getRepr() << "\n";
2445   return ret.str();
2446 }
2447
2448 std::string MEDCoupling1DGTUMesh::advancedRepr() const
2449 {
2450   std::ostringstream ret;
2451   ret << simpleRepr();
2452   ret << "\nCoordinates array : \n___________________\n\n";
2453   if(_coords)
2454     _coords->reprWithoutNameStream(ret);
2455   else
2456     ret << "No array set !\n";
2457   ret << "\n\nNodal Connectivity : \n____________________\n\n";
2458   //
2459   bool isOK=true;
2460   try { checkCoherency1(); } catch(INTERP_KERNEL::Exception& /* e */)
2461     {
2462       ret << "Nodal connectivity arrays are not set or badly set !\n";
2463       isOK=false;
2464     }
2465   if(!isOK)
2466     return ret.str();
2467   int nbOfCells=getNumberOfCells();
2468   const int *ci=_conn_indx->begin(),*c=_conn->begin();
2469   for(int i=0;i<nbOfCells;i++,ci++)
2470     {
2471       ret << "Cell #" << i << " : ";
2472       std::copy(c+ci[0],c+ci[1],std::ostream_iterator<int>(ret," "));
2473       ret << "\n";
2474     }
2475   return ret.str();
2476 }
2477
2478 DataArrayDouble *MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell() const
2479 {
2480   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
2481   int spaceDim=getSpaceDimension();
2482   int nbOfCells=getNumberOfCells();//checkCoherency()
2483   int nbOfNodes=getNumberOfNodes();
2484   ret->alloc(nbOfCells,spaceDim);
2485   double *ptToFill=ret->getPointer();
2486   const double *coor=_coords->begin();
2487   const int *nodal=_conn->begin(),*nodali=_conn_indx->begin();
2488   nodal+=nodali[0];
2489   if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2490     {
2491       for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
2492         {
2493           std::fill(ptToFill,ptToFill+spaceDim,0.);
2494           if(nodali[0]<nodali[1])// >= to avoid division by 0.
2495             {
2496               for(int j=nodali[0];j<nodali[1];j++,nodal++)
2497                 {
2498                   if(*nodal>=0 && *nodal<nbOfNodes)
2499                     std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
2500                   else
2501                     {
2502                       std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," <<   nbOfNodes << ") !";
2503                       throw INTERP_KERNEL::Exception(oss.str().c_str());
2504                     }
2505                   std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./(nodali[1]-nodali[0])));
2506                 }
2507             }
2508           else
2509             {
2510               std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : at cell #" << i << " the nodal index array is invalid !";
2511               throw INTERP_KERNEL::Exception(oss.str().c_str());
2512             }
2513         }
2514     }
2515   else
2516     {
2517       for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
2518         {
2519           std::fill(ptToFill,ptToFill+spaceDim,0.);
2520           if(nodali[0]<nodali[1])// >= to avoid division by 0.
2521             {
2522               int nbOfNod=0;
2523               for(int j=nodali[0];j<nodali[1];j++,nodal++)
2524                 {
2525                   if(*nodal==-1) continue;
2526                   if(*nodal>=0 && *nodal<nbOfNodes)
2527                     {
2528                       std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
2529                       nbOfNod++;
2530                     }
2531                   else
2532                     {
2533                       std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," <<   nbOfNodes << ") !";
2534                       throw INTERP_KERNEL::Exception(oss.str().c_str());
2535                     }
2536                 }
2537               if(nbOfNod!=0)
2538                 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./nbOfNod));
2539               else
2540                 {
2541                   std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : no nodes in cell #" << i << " !";
2542                   throw INTERP_KERNEL::Exception(oss.str().c_str());
2543                 }
2544             }
2545           else
2546             {
2547               std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron)  : at cell #" << i << " the nodal index array is invalid !";
2548               throw INTERP_KERNEL::Exception(oss.str().c_str());
2549             }
2550         }
2551     }
2552   return ret.retn();
2553 }
2554
2555 void MEDCoupling1DGTUMesh::renumberCells(const int *old2NewBg, bool check)
2556 {
2557   int nbCells=getNumberOfCells();
2558   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::New();
2559   o2n->useArray(old2NewBg,false,C_DEALLOC,nbCells,1);
2560   if(check)
2561     o2n=o2n->checkAndPreparePermutation();
2562   //
2563   const int *o2nPtr=o2n->getPointer();
2564   const int *conn=_conn->begin(),*conni=_conn_indx->begin();
2565   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New();
2566   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI=DataArrayInt::New();
2567   newConn->alloc(_conn->getNumberOfTuples(),1); newConnI->alloc(nbCells,1);
2568   newConn->copyStringInfoFrom(*_conn); newConnI->copyStringInfoFrom(*_conn_indx);
2569   //
2570   int *newC=newConn->getPointer(),*newCI=newConnI->getPointer();
2571   for(int i=0;i<nbCells;i++)
2572     {
2573       int newPos=o2nPtr[i];
2574       int sz=conni[i+1]-conni[i];
2575       if(sz>=0)
2576         newCI[newPos]=sz;
2577       else
2578         {
2579           std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberCells : the index nodal array is invalid for cell #" << i << " !";
2580           throw INTERP_KERNEL::Exception(oss.str().c_str());
2581         }
2582     }
2583   newConnI->computeOffsets2(); newCI=newConnI->getPointer();
2584   //
2585   for(int i=0;i<nbCells;i++,conni++)
2586     {
2587       int newp=o2nPtr[i];
2588       std::copy(conn+conni[0],conn+conni[1],newC+newCI[newp]);
2589     }
2590   _conn=newConn;
2591   _conn_indx=newConnI;
2592 }
2593
2594 MEDCouplingMesh *MEDCoupling1DGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
2595 {
2596   if(other->getType()!=SINGLE_DYNAMIC_GEO_TYPE_UNSTRUCTURED)
2597     throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single dynamic geo type each other !");
2598   const MEDCoupling1DGTUMesh *otherC=static_cast<const MEDCoupling1DGTUMesh *>(other);
2599   return Merge1DGTUMeshes(this,otherC);
2600 }
2601
2602 MEDCouplingUMesh *MEDCoupling1DGTUMesh::buildUnstructured() const
2603 {
2604   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName().c_str(),getMeshDimension());
2605   ret->setCoords(getCoords());
2606   const int *nodalConn=_conn->begin(),*nodalConnI=_conn_indx->begin();
2607   int nbCells=getNumberOfCells();//checkCoherency
2608   int geoType=(int)getCellModelEnum();
2609   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New(); c->alloc(nbCells+_conn->getNumberOfTuples(),1);
2610   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cI=DataArrayInt::New(); cI->alloc(nbCells+1);
2611   int *cPtr=c->getPointer(),*ciPtr=cI->getPointer();
2612   ciPtr[0]=0;
2613   for(int i=0;i<nbCells;i++,ciPtr++)
2614     {
2615       int sz=nodalConnI[i+1]-nodalConnI[i];
2616       if(sz>=0)
2617         {
2618           *cPtr++=geoType;
2619           cPtr=std::copy(nodalConn+nodalConnI[i],nodalConn+nodalConnI[i+1],cPtr);
2620           ciPtr[1]=ciPtr[0]+sz+1;
2621         }
2622       else
2623         {
2624           std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::buildUnstructured : Invalid for nodal index for cell #" << i << " !";
2625           throw INTERP_KERNEL::Exception(oss.str().c_str());
2626         }
2627     }
2628   ret->setConnectivity(c,cI,true);
2629   return ret.retn();
2630 }
2631
2632 /*!
2633  * Do nothing for the moment, because there is no policy that allows to split polygons, polyhedrons ... into simplexes
2634  */
2635 DataArrayInt *MEDCoupling1DGTUMesh::simplexize(int policy)
2636 {
2637   int nbOfCells=getNumberOfCells();
2638   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2639   ret->alloc(nbOfCells,1);
2640   ret->iota(0);
2641   return ret.retn();
2642 }
2643
2644 void MEDCoupling1DGTUMesh::reprQuickOverview(std::ostream& stream) const
2645 {
2646   stream << "MEDCoupling1DGTUMesh C++ instance at " << this << ". Type=" << _cm->getRepr() << ". Name : \"" << getName() << "\".";
2647   stream << " Mesh dimension : " << getMeshDimension() << ".";
2648   if(!_coords)
2649     { stream << " No coordinates set !"; return ; }
2650   if(!_coords->isAllocated())
2651     { stream << " Coordinates set but not allocated !"; return ; }
2652   stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
2653   stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
2654   bool isOK=true;
2655   try { checkCoherency(); } catch(INTERP_KERNEL::Exception&  /* e */)
2656     {
2657       stream << std::endl << "Nodal connectivity NOT set properly !\n";
2658       isOK=false;
2659     }
2660   if(isOK)
2661     stream << std::endl << "Number of cells : " << getNumberOfCells() << ".";
2662 }
2663
2664 void MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other)
2665 {
2666   if(!other)
2667     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is null !");
2668   const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2669   if(!otherC)
2670     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1DGTUMesh instance !");
2671   setNodalConnectivity(otherC->getNodalConnectivity(),otherC->getNodalConnectivityIndex());
2672 }
2673
2674 MEDCouplingPointSet *MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const
2675 {
2676   if(!other)
2677     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : input other is null !");
2678   const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2679   if(!otherC)
2680     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !");
2681   std::vector<const MEDCoupling1DGTUMesh *> ms(2);
2682   ms[0]=this;
2683   ms[1]=otherC;
2684   return Merge1DGTUMeshesOnSameCoords(ms);
2685 }
2686
2687 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const
2688 {
2689   checkCoherency();
2690   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName().c_str(),*_cm));
2691   ret->setCoords(_coords);
2692   DataArrayInt *c=0,*ci=0;
2693   MEDCouplingUMesh::ExtractFromIndexedArrays(begin,end,_conn,_conn_indx,c,ci);
2694   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
2695   ret->setNodalConnectivity(c,ci);
2696   return ret.retn();
2697 }
2698
2699 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const
2700 {
2701   checkCoherency();
2702   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName().c_str(),*_cm));
2703   ret->setCoords(_coords);
2704   DataArrayInt *c=0,*ci=0;
2705   MEDCouplingUMesh::ExtractFromIndexedArrays2(start,end,step,_conn,_conn_indx,c,ci);
2706   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
2707   ret->setNodalConnectivity(c,ci);
2708   return ret.retn();
2709 }
2710
2711 void MEDCoupling1DGTUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const
2712 {
2713   int sz((int)nodeIdsInUse.size());
2714   int nbCells(getNumberOfCells());
2715   const int *w(_conn->begin()),*wi(_conn_indx->begin());
2716   for(int i=0;i<nbCells;i++,wi++)
2717     for(const int *pt=w+wi[0];pt!=w+wi[1];pt++)
2718       if(*pt!=-1)
2719         {
2720           if(*pt>=0 && *pt<sz)
2721             nodeIdsInUse[*pt]=true;
2722           else
2723             {
2724               std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeNodeIdsAlg : At cell #" << i << " presence of node id #" << *pt << " should be in [0," << sz << ") !";
2725               throw INTERP_KERNEL::Exception(oss.str().c_str());
2726             }
2727         }
2728 }
2729
2730 void MEDCoupling1DGTUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const
2731 {
2732   checkFullyDefined();
2733   int nbOfNodes=getNumberOfNodes();
2734   int *revNodalIndxPtr=(int *)malloc((nbOfNodes+1)*sizeof(int));
2735   revNodalIndx->useArray(revNodalIndxPtr,true,C_DEALLOC,nbOfNodes+1,1);
2736   std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
2737   const int *conn=_conn->begin(),*conni=_conn_indx->begin();
2738   int nbOfCells=getNumberOfCells();
2739   int nbOfEltsInRevNodal=0;
2740   for(int eltId=0;eltId<nbOfCells;eltId++)
2741     {
2742       int nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
2743       if(nbOfNodesPerCell>=0)
2744         {
2745           for(int j=0;j<nbOfNodesPerCell;j++)
2746             {
2747               int nodeId=conn[conni[eltId]+j];
2748               if(nodeId==-1) continue;            
2749               if(nodeId>=0 && nodeId<nbOfNodes)
2750                 {
2751                   nbOfEltsInRevNodal++;
2752                   revNodalIndxPtr[nodeId+1]++;
2753                 }
2754               else
2755                 {
2756                   std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !";
2757                   throw INTERP_KERNEL::Exception(oss.str().c_str());
2758                 }
2759             }
2760         }
2761       else
2762         {
2763           std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << "nodal connectivity is invalid !";
2764           throw INTERP_KERNEL::Exception(oss.str().c_str());
2765         }
2766     }
2767   std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<int>());
2768   conn=_conn->begin();
2769   int *revNodalPtr=(int *)malloc((nbOfEltsInRevNodal)*sizeof(int));
2770   revNodal->useArray(revNodalPtr,true,C_DEALLOC,nbOfEltsInRevNodal,1);
2771   std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
2772   for(int eltId=0;eltId<nbOfCells;eltId++)
2773     {
2774       int nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
2775       for(int j=0;j<nbOfNodesPerCell;j++)
2776         {
2777           int nodeId=conn[conni[eltId]+j];
2778           if(nodeId!=-1)
2779             *std::find_if(revNodalPtr+revNodalIndxPtr[nodeId],revNodalPtr+revNodalIndxPtr[nodeId+1],std::bind2nd(std::equal_to<int>(),-1))=eltId;
2780         }
2781     }
2782 }
2783
2784 void MEDCoupling1DGTUMesh::checkFullyDefined() const
2785 {
2786   if(!((const DataArrayInt *)_conn) || !((const DataArrayInt *)_conn_indx) || !((const DataArrayDouble *)_coords))
2787     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFullyDefined : part of this is not fully defined.");
2788 }
2789
2790 bool MEDCoupling1DGTUMesh::isEmptyMesh(const std::vector<int>& tinyInfo) const
2791 {
2792   throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEmptyMesh : not implemented yet !");
2793 }
2794
2795 void MEDCoupling1DGTUMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const
2796 {
2797   int it,order;
2798   double time=getTime(it,order);
2799   tinyInfo.clear(); tinyInfoD.clear(); littleStrings.clear();
2800   //
2801   littleStrings.push_back(getName());
2802   littleStrings.push_back(getDescription());
2803   littleStrings.push_back(getTimeUnit());
2804   //
2805   std::vector<std::string> littleStrings2,littleStrings3,littleStrings4;
2806   if((const DataArrayDouble *)_coords)
2807     _coords->getTinySerializationStrInformation(littleStrings2);
2808   if((const DataArrayInt *)_conn)
2809     _conn->getTinySerializationStrInformation(littleStrings3);
2810   if((const DataArrayInt *)_conn_indx)
2811     _conn_indx->getTinySerializationStrInformation(littleStrings4);
2812   int sz0((int)littleStrings2.size()),sz1((int)littleStrings3.size()),sz2((int)littleStrings4.size());
2813   littleStrings.insert(littleStrings.end(),littleStrings2.begin(),littleStrings2.end());
2814   littleStrings.insert(littleStrings.end(),littleStrings3.begin(),littleStrings3.end());
2815   littleStrings.insert(littleStrings.end(),littleStrings4.begin(),littleStrings4.end());
2816   //
2817   tinyInfo.push_back(getCellModelEnum());
2818   tinyInfo.push_back(it);
2819   tinyInfo.push_back(order);
2820   std::vector<int> tinyInfo2,tinyInfo3,tinyInfo4;
2821   if((const DataArrayDouble *)_coords)
2822     _coords->getTinySerializationIntInformation(tinyInfo2);
2823   if((const DataArrayInt *)_conn)
2824     _conn->getTinySerializationIntInformation(tinyInfo3);
2825   if((const DataArrayInt *)_conn_indx)
2826     _conn_indx->getTinySerializationIntInformation(tinyInfo4);
2827   int sz3((int)tinyInfo2.size()),sz4((int)tinyInfo3.size()),sz5((int)tinyInfo4.size());
2828   tinyInfo.push_back(sz0); tinyInfo.push_back(sz1); tinyInfo.push_back(sz2); tinyInfo.push_back(sz3); tinyInfo.push_back(sz4);  tinyInfo.push_back(sz5);
2829   tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
2830   tinyInfo.insert(tinyInfo.end(),tinyInfo3.begin(),tinyInfo3.end());
2831   tinyInfo.insert(tinyInfo.end(),tinyInfo4.begin(),tinyInfo4.end());
2832   //
2833   tinyInfoD.push_back(time);
2834 }
2835
2836 void MEDCoupling1DGTUMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
2837 {
2838   std::vector<int> tinyInfo2(tinyInfo.begin()+9,tinyInfo.begin()+9+tinyInfo[6]);
2839   std::vector<int> tinyInfo1(tinyInfo.begin()+9+tinyInfo[6],tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7]);
2840   std::vector<int> tinyInfo12(tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7],tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7]+tinyInfo[8]);
2841   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p1(DataArrayInt::New()); p1->resizeForUnserialization(tinyInfo1);
2842   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p2(DataArrayInt::New()); p2->resizeForUnserialization(tinyInfo12);
2843   std::vector<const DataArrayInt *> v(2); v[0]=p1; v[1]=p2;
2844   p2=DataArrayInt::Aggregate(v);
2845   a2->resizeForUnserialization(tinyInfo2);
2846   a1->alloc(p2->getNbOfElems(),1);
2847 }
2848
2849 void MEDCoupling1DGTUMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const
2850 {
2851   int sz(0);
2852   if((const DataArrayInt *)_conn)
2853     if(_conn->isAllocated())
2854       sz=_conn->getNbOfElems();
2855   if((const DataArrayInt *)_conn_indx)
2856     if(_conn_indx->isAllocated())
2857       sz+=_conn_indx->getNbOfElems();
2858   a1=DataArrayInt::New();
2859   a1->alloc(sz,1);
2860   int *work(a1->getPointer());
2861   if(sz!=0 && (const DataArrayInt *)_conn)
2862     work=std::copy(_conn->begin(),_conn->end(),a1->getPointer());
2863   if(sz!=0 && (const DataArrayInt *)_conn_indx)
2864     std::copy(_conn_indx->begin(),_conn_indx->end(),work);
2865   sz=0;
2866   if((const DataArrayDouble *)_coords)
2867     if(_coords->isAllocated())
2868       sz=_coords->getNbOfElems();
2869   a2=DataArrayDouble::New();
2870   a2->alloc(sz,1);
2871   if(sz!=0 && (const DataArrayDouble *)_coords)
2872     std::copy(_coords->begin(),_coords->end(),a2->getPointer());
2873 }
2874
2875 void MEDCoupling1DGTUMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,
2876                                            const std::vector<std::string>& littleStrings)
2877 {
2878   INTERP_KERNEL::NormalizedCellType gt((INTERP_KERNEL::NormalizedCellType)tinyInfo[0]);
2879   _cm=&INTERP_KERNEL::CellModel::GetCellModel(gt);
2880   setName(littleStrings[0].c_str());
2881   setDescription(littleStrings[1].c_str());
2882   setTimeUnit(littleStrings[2].c_str());
2883   setTime(tinyInfoD[0],tinyInfo[1],tinyInfo[2]);
2884   int sz0(tinyInfo[3]),sz1(tinyInfo[4]),sz2(tinyInfo[5]),sz3(tinyInfo[6]),sz4(tinyInfo[7]),sz5(tinyInfo[8]);
2885   //
2886   _coords=DataArrayDouble::New();
2887   std::vector<int> tinyInfo2(tinyInfo.begin()+9,tinyInfo.begin()+9+sz3);
2888   _coords->resizeForUnserialization(tinyInfo2);
2889   std::copy(a2->begin(),a2->end(),_coords->getPointer());
2890   _conn=DataArrayInt::New();
2891   std::vector<int> tinyInfo3(tinyInfo.begin()+9+sz3,tinyInfo.begin()+9+sz3+sz4);
2892   _conn->resizeForUnserialization(tinyInfo3);
2893   std::copy(a1->begin(),a1->begin()+_conn->getNbOfElems(),_conn->getPointer());
2894   _conn_indx=DataArrayInt::New();
2895   std::vector<int> tinyInfo4(tinyInfo.begin()+9+sz3+sz4,tinyInfo.begin()+9+sz3+sz4+sz5);
2896   _conn_indx->resizeForUnserialization(tinyInfo4);
2897   std::copy(a1->begin()+_conn->getNbOfElems(),a1->end(),_conn_indx->getPointer());
2898   std::vector<std::string> littleStrings2(littleStrings.begin()+3,littleStrings.begin()+3+sz0);
2899   _coords->finishUnserialization(tinyInfo2,littleStrings2);
2900   std::vector<std::string> littleStrings3(littleStrings.begin()+3+sz0,littleStrings.begin()+3+sz0+sz1);
2901   _conn->finishUnserialization(tinyInfo3,littleStrings3);
2902   std::vector<std::string> littleStrings4(littleStrings.begin()+3+sz0+sz1,littleStrings.begin()+3+sz0+sz1+sz2);
2903   _conn_indx->finishUnserialization(tinyInfo4,littleStrings4);
2904 }
2905
2906 /*!
2907  * Finds nodes not used in any cell and returns an array giving a new id to every node
2908  * by excluding the unused nodes, for which the array holds -1. The result array is
2909  * a mapping in "Old to New" mode. 
2910  *  \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
2911  *  \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a
2912  *          this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
2913  *          if the node is unused or a new id else. The caller is to delete this
2914  *          array using decrRef() as it is no more needed.  
2915  *  \throw If the coordinates array is not set.
2916  *  \throw If the nodal connectivity of cells is not defined.
2917  *  \throw If the nodal connectivity includes an invalid id.
2918  */
2919 DataArrayInt *MEDCoupling1DGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const
2920 {
2921   nbrOfNodesInUse=-1;
2922   int nbOfNodes=getNumberOfNodes();
2923   int nbOfCells=getNumberOfCells();//checkCoherency
2924   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2925   ret->alloc(nbOfNodes,1);
2926   int *traducer=ret->getPointer();
2927   std::fill(traducer,traducer+nbOfNodes,-1);
2928   const int *conn=_conn->begin(),*conni(_conn_indx->begin());
2929   for(int i=0;i<nbOfCells;i++,conni++)
2930     {
2931       int nbNodesPerCell=conni[1]-conni[0];
2932       for(int j=0;j<nbNodesPerCell;j++)
2933         {
2934           int nodeId=conn[conni[0]+j];
2935           if(nodeId==-1) continue;
2936           if(nodeId>=0 && nodeId<nbOfNodes)
2937             traducer[nodeId]=1;
2938           else
2939             {
2940               std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsInUse : In cell #" << i  << " presence of node id " <<  nodeId << " not in [0," << nbOfNodes << ") !";
2941               throw INTERP_KERNEL::Exception(oss.str().c_str());
2942             }
2943         }
2944     }
2945   nbrOfNodesInUse=(int)std::count(traducer,traducer+nbOfNodes,1);
2946   std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
2947   return ret.retn();
2948 }
2949
2950 /*!
2951  * Changes ids of nodes within the nodal connectivity arrays according to a permutation
2952  * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
2953  * This method is a generalization of shiftNodeNumbersInConn().
2954  *  \warning This method performs no check of validity of new ids. **Use it with care !**
2955  *  \param [in] newNodeNumbersO2N - a permutation array, of length \a
2956  *         this->getNumberOfNodes(), in "Old to New" mode. 
2957  *         See \ref MEDCouplingArrayRenumbering for more info on renumbering modes.
2958  *  \throw If the nodal connectivity of cells is not defined.
2959  */
2960 void MEDCoupling1DGTUMesh::renumberNodesInConn(const int *newNodeNumbersO2N)
2961 {
2962   getNumberOfCells();//only to check that all is well defined.
2963   //
2964   int nbElemsIn=getNumberOfNodes();
2965   int nbOfTuples=_conn->getNumberOfTuples();
2966   int *pt=_conn->getPointer();
2967   for(int i=0;i<nbOfTuples;i++,pt++)
2968     {
2969       if(*pt==-1) continue;
2970       if(*pt>=0 && *pt<nbElemsIn)
2971         *pt=newNodeNumbersO2N[*pt];
2972       else
2973         {
2974           std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberNodesInConn : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn;
2975           throw INTERP_KERNEL::Exception(oss.str().c_str());
2976         }
2977     }
2978   _conn->declareAsNew();
2979   //
2980   updateTime();
2981 }
2982
2983 /*!
2984  * Keeps from \a this only cells which constituing point id are in the ids specified by [\a begin,\a end).
2985  * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
2986  * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not.
2987  * If \a fullyIn is true only cells whose ids are \b fully contained in [\a begin,\a end) tab will be kept.
2988  *
2989  * \param [in] begin input start of array of node ids.
2990  * \param [in] end input end of array of node ids.
2991  * \param [in] fullyIn input that specifies if all node ids must be in [\a begin,\a end) array to consider cell to be in.
2992  * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end.
2993  */
2994 void MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const
2995 {
2996   int nbOfCells=getNumberOfCells();
2997   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1);
2998   int tmp=-1;
2999   int sz=_conn->getMaxValue(tmp); sz=std::max(sz,0)+1;
3000   std::vector<bool> fastFinder(sz,false);
3001   for(const int *work=begin;work!=end;work++)
3002     if(*work>=0 && *work<sz)
3003       fastFinder[*work]=true;
3004   const int *conn=_conn->begin(),*conni=_conn_indx->begin();
3005   for(int i=0;i<nbOfCells;i++,conni++)
3006     {
3007       int ref=0,nbOfHit=0;
3008       int nbNodesPerCell=conni[1]-conni[0];
3009       if(nbNodesPerCell>=0)
3010         {
3011           for(int j=0;j<nbNodesPerCell;j++)
3012             {
3013               int nodeId=conn[conni[0]+j];
3014               if(nodeId>=0)
3015                 {
3016                   ref++;
3017                   if(fastFinder[nodeId])
3018                     nbOfHit++;
3019                 }
3020             }
3021         }
3022       else
3023         {
3024           std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds : invalid index array for cell #" << i << " !";
3025           throw INTERP_KERNEL::Exception(oss.str().c_str());
3026         }
3027       if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn))
3028         cellIdsKept->pushBackSilent(i);
3029     }
3030   cellIdsKeptArr=cellIdsKept.retn();
3031 }
3032
3033 void MEDCoupling1DGTUMesh::allocateCells(int nbOfCells)
3034 {
3035   if(nbOfCells<0)
3036     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::allocateCells : the input number of cells should be >= 0 !");
3037   _conn=DataArrayInt::New();
3038   _conn->reserve(nbOfCells*3);
3039   _conn_indx=DataArrayInt::New();
3040   _conn_indx->reserve(nbOfCells+1); _conn_indx->pushBackSilent(0);
3041   declareAsNew();
3042 }
3043
3044 /*!
3045  * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ).
3046  *
3047  * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add.
3048  * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
3049  * \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
3050  *        attached to \a this.
3051  * \thow If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
3052  */
3053 void MEDCoupling1DGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd)
3054 {
3055   int sz=(int)std::distance(nodalConnOfCellBg,nodalConnOfCellEnd);
3056   DataArrayInt *c(_conn),*c2(_conn_indx);
3057   if(c && c2)
3058     {
3059       int pos=c2->back();
3060       if(pos==c->getNumberOfTuples())
3061         {
3062           c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd);
3063           c2->pushBackSilent(pos+sz);
3064         }
3065       else
3066         {
3067           std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::insertNextCell : The nodal index array (end=" << pos << ") mismatches with nodal array (length=" << c->getNumberOfTuples() << ") !";
3068           throw INTERP_KERNEL::Exception(oss.str().c_str());
3069         }
3070     }
3071   else
3072     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1DGTUMesh::allocateCells before !");
3073 }
3074
3075 void MEDCoupling1DGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn, DataArrayInt *nodalConnIndex)
3076 {
3077   if(nodalConn)
3078     nodalConn->incrRef();
3079   _conn=nodalConn;
3080   if(nodalConnIndex)
3081     nodalConnIndex->incrRef();
3082   _conn_indx=nodalConnIndex;
3083   declareAsNew();
3084 }
3085
3086 /*!
3087  * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it.
3088  */
3089 DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivity() const
3090 {
3091   const DataArrayInt *ret(_conn);
3092   return const_cast<DataArrayInt *>(ret);
3093 }
3094
3095 /*!
3096  * \return DataArrayInt * - the internal reference to the nodal connectivity index. The caller is not reponsible to deallocate it.
3097  */
3098 DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivityIndex() const
3099 {
3100   const DataArrayInt *ret(_conn_indx);
3101   return const_cast<DataArrayInt *>(ret);
3102 }
3103
3104 /*!
3105  * See the definition of the nodal connectivity pack \ref MEDCoupling1DGTUMesh::isPacked "here".
3106  * This method tries to build a new instance geometrically equivalent to \a this, by limiting at most the number of new object (nodal connectivity).
3107  * 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.
3108  *
3109  * 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.
3110  * 
3111  * \param [out] isShallowCpyOfNodalConnn - tells if the returned instance share the same pair of nodal connectivity arrays (true) or if nodal
3112  *              connectivity arrays are different (false)
3113  * \return a new object to be managed by the caller.
3114  * 
3115  * \sa MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity, MEDCoupling1DGTUMesh::isPacked
3116  */
3117 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::copyWithNodalConnectivityPacked(bool& isShallowCpyOfNodalConnn) const
3118 {
3119   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName().c_str(),*_cm));
3120   DataArrayInt *nc=0,*nci=0;
3121   isShallowCpyOfNodalConnn=retrievePackedNodalConnectivity(nc,nci);
3122   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ncs(nc),ncis(nci);
3123   ret->_conn=ncs; ret->_conn_indx=ncis;
3124   ret->setCoords(getCoords());
3125   return ret.retn();
3126 }
3127
3128 /*!
3129  * This method allows to compute, if needed, the packed nodal connectivity pair.
3130  * Indeed, it is possible to store in \a this a nodal connectivity array bigger than ranges convered by nodal connectivity index array.
3131  * 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.
3132  * 
3133  * 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)
3134  * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
3135  *
3136  * 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
3137  * will be returned.
3138  * 
3139  * This method return 3 elements.
3140  * \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
3141  *                          this pointer can be seen as a new object, that is to managed by the caller.
3142  * \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
3143  *                              this pointer can be seen as a new object, that is to managed by the caller.
3144  * \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
3145  * output parameters are newly created objects.
3146  *
3147  * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkCoherency test
3148  */
3149 bool MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity(DataArrayInt *&nodalConn, DataArrayInt *&nodalConnIndx) const
3150 {
3151   if(isPacked())//performs the checkCoherency
3152     {
3153       const DataArrayInt *c0(_conn),*c1(_conn_indx);
3154       nodalConn=const_cast<DataArrayInt *>(c0); nodalConnIndx=const_cast<DataArrayInt *>(c1);
3155       nodalConn->incrRef(); nodalConnIndx->incrRef();
3156       return true;
3157     }
3158   int bg=_conn_indx->front(),end=_conn_indx->back();
3159   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nc(_conn->selectByTupleId2(bg,end,1));
3160   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nci(_conn_indx->deepCpy());
3161   nci->applyLin(1,-bg);
3162   nodalConn=nc.retn(); nodalConnIndx=nci.retn();
3163   return false;
3164 }
3165
3166 /*
3167  * 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)
3168  * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
3169  * If nodal connectivity index points to a subpart of nodal connectivity index false will be returned.
3170  * \return bool - true if \a this looks packed, false is not.
3171  *
3172  * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkCoherency test
3173  */
3174 bool MEDCoupling1DGTUMesh::isPacked() const
3175 {
3176   checkCoherency();
3177   return _conn_indx->front()==0 && _conn_indx->back()==_conn->getNumberOfTuples();
3178 }
3179
3180 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(const MEDCoupling1DGTUMesh *mesh1, const MEDCoupling1DGTUMesh *mesh2)
3181 {
3182   std::vector<const MEDCoupling1DGTUMesh *> tmp(2);
3183   tmp[0]=const_cast<MEDCoupling1DGTUMesh *>(mesh1); tmp[1]=const_cast<MEDCoupling1DGTUMesh *>(mesh2);
3184   return Merge1DGTUMeshes(tmp);
3185 }
3186
3187 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(std::vector<const MEDCoupling1DGTUMesh *>& a)
3188 {
3189   std::size_t sz=a.size();
3190   if(sz==0)
3191     return Merge1DGTUMeshesLL(a);
3192   for(std::size_t ii=0;ii<sz;ii++)
3193     if(!a[ii])
3194       {
3195         std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::Merge1DGTUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !";
3196         throw INTERP_KERNEL::Exception(oss.str().c_str());
3197       }
3198   const INTERP_KERNEL::CellModel *cm=&(a[0]->getCellModel());
3199   for(std::size_t ii=0;ii<sz;ii++)
3200     if(&(a[ii]->getCellModel())!=cm)
3201       throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : all items must have the same geo type !");
3202   std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > bb(sz);
3203   std::vector< const MEDCoupling1DGTUMesh * > aa(sz);
3204   int spaceDim=-3;
3205   for(std::size_t i=0;i<sz && spaceDim==-3;i++)
3206     {
3207       const MEDCoupling1DGTUMesh *cur=a[i];
3208       const DataArrayDouble *coo=cur->getCoords();
3209       if(coo)
3210         spaceDim=coo->getNumberOfComponents();
3211     }
3212   if(spaceDim==-3)
3213     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : no spaceDim specified ! unable to perform merge !");
3214   for(std::size_t i=0;i<sz;i++)
3215     {
3216       bb[i]=a[i]->buildSetInstanceFromThis(spaceDim);
3217       aa[i]=bb[i];
3218     }
3219   return Merge1DGTUMeshesLL(aa);
3220 }
3221
3222 /*!
3223  * \throw If presence of a null instance in the input vector \a a.
3224  * \throw If a is empty
3225  */
3226 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords(std::vector<const MEDCoupling1DGTUMesh *>& a)
3227 {
3228   if(a.empty())
3229     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : input array must be NON EMPTY !");
3230   std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin();
3231   if(!(*it))
3232     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : null instance in the first element of input vector !");
3233   std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > objs(a.size());
3234   std::vector<const DataArrayInt *> ncs(a.size()),ncis(a.size());
3235   (*it)->getNumberOfCells();//to check that all is OK
3236   const DataArrayDouble *coords=(*it)->getCoords();
3237   const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
3238   bool tmp;
3239   objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp);
3240   ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex();
3241   it++;
3242   for(int i=1;it!=a.end();i++,it++)
3243     {
3244       if(!(*it))
3245         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : presence of null instance !");
3246       if(cm!=&((*it)->getCellModel()))
3247         throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !");
3248       (*it)->getNumberOfCells();//to check that all is OK
3249       objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp);
3250       ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex();
3251       if(coords!=(*it)->getCoords())
3252         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : not lying on same coords !");
3253     }
3254   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm));
3255   ret->setCoords(coords);
3256   ret->_conn=DataArrayInt::Aggregate(ncs);
3257   ret->_conn_indx=DataArrayInt::AggregateIndexes(ncis);
3258   return ret.retn();
3259 }
3260
3261 /*!
3262  * 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)
3263  */
3264 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesLL(std::vector<const MEDCoupling1DGTUMesh *>& a)
3265 {
3266   if(a.empty())
3267     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : input array must be NON EMPTY !");
3268   std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > objs(a.size());
3269   std::vector<const DataArrayInt *> ncs(a.size()),ncis(a.size());
3270   std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin();
3271   std::vector<int> nbNodesPerElt(a.size());
3272   int nbOfCells=(*it)->getNumberOfCells();
3273   bool tmp;
3274   objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp);
3275   ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex();
3276   nbNodesPerElt[0]=0;
3277   int prevNbOfNodes=(*it)->getNumberOfNodes();
3278   const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
3279   it++;
3280   for(int i=1;it!=a.end();i++,it++)
3281     {
3282       if(cm!=&((*it)->getCellModel()))
3283         throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !");
3284       objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp);
3285       ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex();
3286       nbOfCells+=(*it)->getNumberOfCells();
3287       nbNodesPerElt[i]=nbNodesPerElt[i-1]+prevNbOfNodes;
3288       prevNbOfNodes=(*it)->getNumberOfNodes();
3289     }
3290   std::vector<const MEDCouplingPointSet *> aps(a.size());
3291   std::copy(a.begin(),a.end(),aps.begin());
3292   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> pts=MergeNodesArray(aps);
3293   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm));
3294   ret->setCoords(pts);
3295   ret->_conn=AggregateNodalConnAndShiftNodeIds(ncs,nbNodesPerElt);
3296   ret->_conn_indx=DataArrayInt::AggregateIndexes(ncis);
3297   return ret.retn();
3298 }
3299
3300 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::buildSetInstanceFromThis(int spaceDim) const
3301 {
3302   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName().c_str(),*_cm));
3303   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1,tmp2;
3304   const DataArrayInt *nodalConn(_conn),*nodalConnI(_conn_indx);
3305   if(!nodalConn)
3306     {
3307       tmp1=DataArrayInt::New(); tmp1->alloc(0,1);
3308     }
3309   else
3310     tmp1=_conn;
3311   ret->_conn=tmp1;
3312   //
3313   if(!nodalConnI)
3314     {
3315       tmp2=DataArrayInt::New(); tmp2->alloc(1,1); tmp2->setIJ(0,0,0);
3316     }
3317   else
3318     tmp2=_conn_indx;
3319   ret->_conn_indx=tmp2;
3320   //
3321   if(!_coords)
3322     {
3323       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim);
3324       ret->setCoords(coords);
3325     }
3326   else
3327     ret->setCoords(_coords);
3328   return ret.retn();
3329 }
3330
3331 /*!
3332  * This method aggregate the bbox of each cell and put it into bbox parameter.
3333  * 
3334  * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components.
3335  * 
3336  * \throw If \a this is not fully set (coordinates and connectivity).
3337  * \throw If a cell in \a this has no valid nodeId.
3338  */
3339 DataArrayDouble *MEDCoupling1DGTUMesh::getBoundingBoxForBBTree() const
3340 {
3341   checkFullyDefined();
3342   int spaceDim(getSpaceDimension()),nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes());
3343   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim);
3344   double *bbox(ret->getPointer());
3345   for(int i=0;i<nbOfCells*spaceDim;i++)
3346     {
3347       bbox[2*i]=std::numeric_limits<double>::max();
3348       bbox[2*i+1]=-std::numeric_limits<double>::max();
3349     }
3350   const double *coordsPtr(_coords->getConstPointer());
3351   const int *conn(_conn->getConstPointer()),*connI(_conn_indx->getConstPointer());
3352   for(int i=0;i<nbOfCells;i++)
3353     {
3354       int offset=connI[i];
3355       int nbOfNodesForCell(connI[i+1]-offset),kk(0);
3356       for(int j=0;j<nbOfNodesForCell;j++)
3357         {
3358           int nodeId=conn[offset+j];
3359           if(nodeId>=0 && nodeId<nbOfNodes)
3360             {
3361               for(int k=0;k<spaceDim;k++)
3362                 {
3363                   bbox[2*spaceDim*i+2*k]=std::min(bbox[2*spaceDim*i+2*k],coordsPtr[spaceDim*nodeId+k]);
3364                   bbox[2*spaceDim*i+2*k+1]=std::max(bbox[2*spaceDim*i+2*k+1],coordsPtr[spaceDim*nodeId+k]);
3365                 }
3366               kk++;
3367             }
3368         }
3369       if(kk==0)
3370         {
3371           std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getBoundingBoxForBBTree : cell #" << i << " contains no valid nodeId !";
3372           throw INTERP_KERNEL::Exception(oss.str().c_str());
3373         }
3374     }
3375   return ret.retn();
3376 }
3377
3378 std::vector<int> MEDCoupling1DGTUMesh::BuildAPolygonFromParts(const std::vector< std::vector<int> >& parts)
3379 {
3380   std::vector<int> ret;
3381   if(parts.empty())
3382     return ret;
3383   ret.insert(ret.end(),parts[0].begin(),parts[0].end());
3384   int ref(ret.back());
3385   std::size_t sz(parts.size()),nbh(1);
3386   std::vector<bool> b(sz,true); b[0]=false;
3387   while(nbh<sz)
3388     {
3389       std::size_t i(0);
3390       for(;i<sz;i++) if(b[i] && parts[i].front()==ref) { ret.insert(ret.end(),parts[i].begin()+1,parts[i].end()); nbh++; break; }
3391       if(i<sz)
3392         ref=ret.back();
3393       else
3394         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::BuildAPolygonFromParts : the input vector is not a part of a single polygon !");
3395     }
3396   if(ret.back()==ret.front())
3397     ret.pop_back();
3398   return ret;
3399 }
3400
3401 /*!
3402  * This method performs an aggregation of \a nodalConns (as DataArrayInt::Aggregate does) but in addition of that a shift is applied on the 
3403  * values contained in \a nodalConns using corresponding offset specified in input \a offsetInNodeIdsPerElt.
3404  * But it also manage the values -1, that have a semantic in MEDCoupling1DGTUMesh class (separator for polyhedron).
3405  *
3406  * \param [in] nodalConns - a list of nodal connectivity arrays same size than \a offsetInNodeIdsPerElt.
3407  * \param [in] offsetInNodeIdsPerElt - a list of offsets to apply.
3408  * \return DataArrayInt * - A new object (to be managed by the caller) that is the result of the aggregation.
3409  * \throw If \a nodalConns or \a offsetInNodeIdsPerElt are empty.
3410  * \throw If \a nodalConns and \a offsetInNodeIdsPerElt have not the same size.
3411  * \throw If presence of null pointer in \a nodalConns.
3412  * \throw If presence of not allocated or array with not exactly one component in \a nodalConns.
3413  */
3414 DataArrayInt *MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds(const std::vector<const DataArrayInt *>& nodalConns, const std::vector<int>& offsetInNodeIdsPerElt)
3415 {
3416   std::size_t sz1(nodalConns.size()),sz2(offsetInNodeIdsPerElt.size());
3417   if(sz1!=sz2)
3418     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : input vectors do not have the same size !");
3419   if(sz1==0)
3420     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : empty vectors in input !");
3421   int nbOfTuples=0;
3422   for(std::vector<const DataArrayInt *>::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++)
3423     {
3424       if(!(*it))
3425         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of null pointer in input vector !");
3426       if(!(*it)->isAllocated())
3427         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of non allocated array in input vector !");
3428       if((*it)->getNumberOfComponents()!=1)
3429         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of array with not exactly one component !");
3430       nbOfTuples+=(*it)->getNumberOfTuples();
3431     }
3432   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
3433   int *pt=ret->getPointer();
3434   int i=0;
3435   for(std::vector<const DataArrayInt *>::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++,i++)
3436     {
3437       int curNbt=(*it)->getNumberOfTuples();
3438       const int *inPt=(*it)->begin();
3439       int offset=offsetInNodeIdsPerElt[i];
3440       for(int j=0;j<curNbt;j++,pt++)
3441         {
3442           if(inPt[j]!=-1)
3443             *pt=inPt[j]+offset;
3444           else
3445             *pt=-1;
3446         }
3447     }
3448   return ret.retn();
3449 }
3450
3451 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const MEDCouplingUMesh *m)
3452 {
3453   if(!m)
3454     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : input mesh is null !");
3455   std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes());
3456   if(gts.size()!=1)
3457     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : input mesh must have exactly one geometric type !");
3458   int geoType((int)*gts.begin());
3459   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(m->getName().c_str(),*gts.begin()));
3460   ret->setCoords(m->getCoords()); ret->setDescription(m->getDescription().c_str());
3461   int nbCells(m->getNumberOfCells());
3462   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()),connI(DataArrayInt::New());
3463   conn->alloc(m->getMeshLength()-nbCells,1); connI->alloc(nbCells+1,1);
3464   int *c(conn->getPointer()),*ci(connI->getPointer()); *ci=0;
3465   const int *cin(m->getNodalConnectivity()->begin()),*ciin(m->getNodalConnectivityIndex()->begin());
3466   for(int i=0;i<nbCells;i++,ciin++,ci++)
3467     {
3468       if(cin[ciin[0]]==geoType)
3469         {
3470           if(ciin[1]-ciin[0]>=1)
3471             {
3472               c=std::copy(cin+ciin[0]+1,cin+ciin[1],c);
3473               ci[1]=ci[0]+ciin[1]-ciin[0]-1;
3474             }
3475           else
3476             {
3477               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 !";
3478               throw INTERP_KERNEL::Exception(oss.str().c_str());
3479             }
3480         }
3481       else
3482         {
3483           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 !";
3484           throw INTERP_KERNEL::Exception(oss.str().c_str());
3485         }
3486     }
3487   ret->setNodalConnectivity(conn,connI);
3488   return ret.retn();
3489 }