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