]> SALOME platform Git repositories - tools/medcoupling.git/blob - src/MEDCoupling/MEDCoupling1GTUMesh.cxx
Salome HOME
On the road of the ParaMEDReader. MEDLoader can load partially a MEDFileUMesh from...
[tools/medcoupling.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  * This method returns all node ids used in \b this. The data array returned has to be dealt by the caller.
1010  * The returned node ids are sortes ascendingly. This method is closed to MEDCoupling1SGTUMesh::getNodeIdsInUse except
1011  * the format of returned DataArrayInt instance.
1012  *
1013  * \return a newly allocated DataArrayInt sorted ascendingly of fetched node ids.
1014  * \sa MEDCoupling1SGTUMesh::getNodeIdsInUse
1015  */
1016 DataArrayInt *MEDCoupling1SGTUMesh::computeFetchedNodeIds() const
1017 {
1018   checkCoherencyOfConnectivity();
1019   int nbNodes(getNumberOfNodes());
1020   std::vector<bool> fetchedNodes(nbNodes,false);
1021   computeNodeIdsAlg(fetchedNodes);
1022   int sz((int)std::count(fetchedNodes.begin(),fetchedNodes.end(),true));
1023   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
1024   int *retPtr(ret->getPointer());
1025   for(int i=0;i<nbNodes;i++)
1026     if(fetchedNodes[i])
1027       *retPtr++=i;
1028   return ret.retn();
1029 }
1030
1031 /*!
1032  * Finds nodes not used in any cell and returns an array giving a new id to every node
1033  * by excluding the unused nodes, for which the array holds -1. The result array is
1034  * a mapping in "Old to New" mode. 
1035  *  \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
1036  *  \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a
1037  *          this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
1038  *          if the node is unused or a new id else. The caller is to delete this
1039  *          array using decrRef() as it is no more needed.  
1040  *  \throw If the coordinates array is not set.
1041  *  \throw If the nodal connectivity of cells is not defined.
1042  *  \throw If the nodal connectivity includes an invalid id.
1043  *  \sa MEDCoupling1SGTUMesh::computeFetchedNodeIds
1044  */
1045 DataArrayInt *MEDCoupling1SGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const
1046 {
1047   nbrOfNodesInUse=-1;
1048   int nbOfNodes=getNumberOfNodes();
1049   int nbOfCells=getNumberOfCells();
1050   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
1051   ret->alloc(nbOfNodes,1);
1052   int *traducer=ret->getPointer();
1053   std::fill(traducer,traducer+nbOfNodes,-1);
1054   const int *conn=_conn->begin();
1055   int nbNodesPerCell=getNumberOfNodesPerCell();
1056   for(int i=0;i<nbOfCells;i++)
1057     for(int j=0;j<nbNodesPerCell;j++,conn++)
1058       if(*conn>=0 && *conn<nbOfNodes)
1059         traducer[*conn]=1;
1060       else
1061         {
1062           std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsInUse : In cell #" << i  << " presence of node id " <<  conn[j] << " not in [0," << nbOfNodes << ") !";
1063           throw INTERP_KERNEL::Exception(oss.str().c_str());
1064         }
1065   nbrOfNodesInUse=(int)std::count(traducer,traducer+nbOfNodes,1);
1066   std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
1067   return ret.retn();
1068 }
1069
1070 /*!
1071  *  Same than renumberNodesInConn(const int *) except that here the format of old-to-new traducer is using map instead
1072  *  of array. This method is dedicated for renumbering from a big set of nodes the a tiny set of nodes which is the case during extraction
1073  *  of a big mesh.
1074  */
1075 void MEDCoupling1SGTUMesh::renumberNodesInConn(const std::map<int,int>& newNodeNumbersO2N)
1076 {
1077   getNumberOfCells();//only to check that all is well defined.
1078   int *begPtr(_conn->getPointer());
1079   int nbElt(_conn->getNumberOfTuples());
1080   int *endPtr(begPtr+nbElt);
1081   for(int *it=begPtr;it!=endPtr;it++)
1082     {
1083       std::map<int,int>::const_iterator it2(newNodeNumbersO2N.find(*it));
1084       if(it2!=newNodeNumbersO2N.end())
1085         {
1086           *it=(*it2).second;
1087         }
1088       else
1089         {
1090           std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::renumberNodesInConn : At pos #" << std::distance(begPtr,it) << " of nodal connectivity value is " << *it << ". Not in map !";
1091           throw INTERP_KERNEL::Exception(oss.str().c_str());
1092         }
1093     }
1094   updateTime();
1095 }
1096
1097 /*!
1098  * Changes ids of nodes within the nodal connectivity arrays according to a permutation
1099  * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
1100  * This method is a generalization of shiftNodeNumbersInConn().
1101  *  \warning This method performs no check of validity of new ids. **Use it with care !**
1102  *  \param [in] newNodeNumbersO2N - a permutation array, of length \a
1103  *         this->getNumberOfNodes(), in "Old to New" mode. 
1104  *         See \ref MEDCouplingArrayRenumbering for more info on renumbering modes.
1105  *  \throw If the nodal connectivity of cells is not defined.
1106  */
1107 void MEDCoupling1SGTUMesh::renumberNodesInConn(const int *newNodeNumbersO2N)
1108 {
1109   getNumberOfCells();//only to check that all is well defined.
1110   _conn->transformWithIndArr(newNodeNumbersO2N,newNodeNumbersO2N+getNumberOfNodes());
1111   updateTime();
1112 }
1113
1114 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(const MEDCoupling1SGTUMesh *mesh1, const MEDCoupling1SGTUMesh *mesh2)
1115 {
1116   std::vector<const MEDCoupling1SGTUMesh *> tmp(2);
1117   tmp[0]=const_cast<MEDCoupling1SGTUMesh *>(mesh1); tmp[1]=const_cast<MEDCoupling1SGTUMesh *>(mesh2);
1118   return Merge1SGTUMeshes(tmp);
1119 }
1120
1121 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(std::vector<const MEDCoupling1SGTUMesh *>& a)
1122 {
1123   std::size_t sz=a.size();
1124   if(sz==0)
1125     return Merge1SGTUMeshesLL(a);
1126   for(std::size_t ii=0;ii<sz;ii++)
1127     if(!a[ii])
1128       {
1129         std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::Merge1SGTUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !";
1130         throw INTERP_KERNEL::Exception(oss.str().c_str());
1131       }
1132   const INTERP_KERNEL::CellModel *cm=&(a[0]->getCellModel());
1133   for(std::size_t ii=0;ii<sz;ii++)
1134     if(&(a[ii]->getCellModel())!=cm)
1135       throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : all items must have the same geo type !");
1136   std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> > bb(sz);
1137   std::vector< const MEDCoupling1SGTUMesh * > aa(sz);
1138   int spaceDim=-3;
1139   for(std::size_t i=0;i<sz && spaceDim==-3;i++)
1140     {
1141       const MEDCoupling1SGTUMesh *cur=a[i];
1142       const DataArrayDouble *coo=cur->getCoords();
1143       if(coo)
1144         spaceDim=coo->getNumberOfComponents();
1145     }
1146   if(spaceDim==-3)
1147     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : no spaceDim specified ! unable to perform merge !");
1148   for(std::size_t i=0;i<sz;i++)
1149     {
1150       bb[i]=a[i]->buildSetInstanceFromThis(spaceDim);
1151       aa[i]=bb[i];
1152     }
1153   return Merge1SGTUMeshesLL(aa);
1154 }
1155
1156 /*!
1157  * \throw If presence of a null instance in the input vector \a a.
1158  * \throw If a is empty
1159  */
1160 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords(std::vector<const MEDCoupling1SGTUMesh *>& a)
1161 {
1162   if(a.empty())
1163     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : input array must be NON EMPTY !");
1164   std::vector<const MEDCoupling1SGTUMesh *>::const_iterator it=a.begin();
1165   if(!(*it))
1166     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : null instance in the first element of input vector !");
1167   std::vector<const DataArrayInt *> ncs(a.size());
1168   (*it)->getNumberOfCells();//to check that all is OK
1169   const DataArrayDouble *coords=(*it)->getCoords();
1170   const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
1171   ncs[0]=(*it)->getNodalConnectivity();
1172   it++;
1173   for(int i=1;it!=a.end();i++,it++)
1174     {
1175       if(!(*it))
1176         throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : presence of a null instance in the input vector !");
1177       if(cm!=&((*it)->getCellModel()))
1178         throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !");
1179       (*it)->getNumberOfCells();//to check that all is OK
1180       ncs[i]=(*it)->getNodalConnectivity();
1181       if(coords!=(*it)->getCoords())
1182         throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : not lying on same coords !");
1183     }
1184   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh("merge",*cm));
1185   ret->setCoords(coords);
1186   ret->_conn=DataArrayInt::Aggregate(ncs);
1187   return ret.retn();
1188 }
1189
1190 /*!
1191  * 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)
1192  */
1193 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesLL(std::vector<const MEDCoupling1SGTUMesh *>& a)
1194 {
1195   if(a.empty())
1196     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : input array must be NON EMPTY !");
1197   std::vector<const MEDCoupling1SGTUMesh *>::const_iterator it=a.begin();
1198   int nbOfCells=(*it)->getNumberOfCells();
1199   const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
1200   int nbNodesPerCell=(*it)->getNumberOfNodesPerCell();
1201   it++;
1202   for(;it!=a.end();it++)
1203     {
1204       if(cm!=&((*it)->getCellModel()))
1205         throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !");
1206       nbOfCells+=(*it)->getNumberOfCells();
1207     }
1208   std::vector<const MEDCouplingPointSet *> aps(a.size());
1209   std::copy(a.begin(),a.end(),aps.begin());
1210   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> pts=MergeNodesArray(aps);
1211   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh("merge",*cm));
1212   ret->setCoords(pts);
1213   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New();
1214   c->alloc(nbOfCells*nbNodesPerCell,1);
1215   int *cPtr=c->getPointer();
1216   int offset=0;
1217   for(it=a.begin();it!=a.end();it++)
1218     {
1219       int curConnLgth=(*it)->getNodalConnectivityLength();
1220       const int *curC=(*it)->_conn->begin();
1221       cPtr=std::transform(curC,curC+curConnLgth,cPtr,std::bind2nd(std::plus<int>(),offset));
1222       offset+=(*it)->getNumberOfNodes();
1223     }
1224   //
1225   ret->setNodalConnectivity(c);
1226   return ret.retn();
1227 }
1228
1229 MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const
1230 {
1231   int ncell=getNumberOfCells();
1232   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
1233   ret->setCoords(_coords);
1234   std::size_t nbOfElemsRet=std::distance(begin,end);
1235   const int *inConn=_conn->getConstPointer();
1236   int sz=getNumberOfNodesPerCell();
1237   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connRet=DataArrayInt::New(); connRet->alloc((int)nbOfElemsRet*sz,1);
1238   int *connPtr=connRet->getPointer();
1239   for(const int *work=begin;work!=end;work++,connPtr+=sz)
1240     {
1241       if(*work>=0 && *work<ncell)
1242         std::copy(inConn+(work[0])*sz,inConn+(work[0]+1)*sz,connPtr);
1243       else
1244         {
1245           std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords : On pos #" << std::distance(begin,work) << " input cell id =" << *work << " should be in [0," << ncell << ") !";
1246           throw INTERP_KERNEL::Exception(oss.str().c_str());
1247         }
1248     }
1249   ret->_conn=connRet;
1250   ret->copyTinyInfoFrom(this);
1251   return ret.retn();
1252 }
1253
1254 MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const
1255 {
1256   int ncell=getNumberOfCells();
1257   int nbOfElemsRet=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2 : ");
1258   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
1259   ret->setCoords(_coords);
1260   const int *inConn=_conn->getConstPointer();
1261   int sz=getNumberOfNodesPerCell();
1262   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connRet=DataArrayInt::New(); connRet->alloc((int)nbOfElemsRet*sz,1);
1263   int *connPtr=connRet->getPointer();
1264   int curId=start;
1265   for(int i=0;i<nbOfElemsRet;i++,connPtr+=sz,curId+=step)
1266     {
1267       if(curId>=0 && curId<ncell)
1268         std::copy(inConn+curId*sz,inConn+(curId+1)*sz,connPtr);
1269       else
1270         {
1271           std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2 : On pos #" << i << " input cell id =" << curId  << " should be in [0," << ncell << ") !";
1272           throw INTERP_KERNEL::Exception(oss.str().c_str());
1273         }
1274     }
1275   ret->_conn=connRet;
1276   ret->copyTinyInfoFrom(this);
1277   return ret.retn();
1278 }
1279
1280 void MEDCoupling1SGTUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const
1281 {
1282   int sz((int)nodeIdsInUse.size());
1283   for(const int *conn=_conn->begin();conn!=_conn->end();conn++)
1284     {
1285       if(*conn>=0 && *conn<sz)
1286        nodeIdsInUse[*conn]=true;
1287       else
1288         {
1289           std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeFetchedNodeIds : At pos #" << std::distance(_conn->begin(),conn) << " value is " << *conn << " must be in [0," << sz << ") !";
1290           throw INTERP_KERNEL::Exception(oss.str().c_str());
1291         }
1292     }
1293 }
1294
1295 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::buildSetInstanceFromThis(int spaceDim) const
1296 {
1297   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
1298   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1;
1299   const DataArrayInt *nodalConn(_conn);
1300   if(!nodalConn)
1301     {
1302       tmp1=DataArrayInt::New(); tmp1->alloc(0,1);
1303     }
1304   else
1305     tmp1=_conn;
1306   ret->_conn=tmp1;
1307   if(!_coords)
1308     {
1309       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim);
1310       ret->setCoords(coords);
1311     }
1312   else
1313     ret->setCoords(_coords);
1314   return ret.retn();
1315 }
1316
1317 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePol0()
1318 {
1319   int nbOfCells=getNumberOfCells();
1320   if(getCellModelEnum()!=INTERP_KERNEL::NORM_QUAD4)
1321     return DataArrayInt::Range(0,nbOfCells,1);
1322   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(2*3*nbOfCells,1);
1323   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(2*nbOfCells,1);
1324   const int *c(_conn->begin());
1325   int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1326   for(int i=0;i<nbOfCells;i++,c+=4,newConnPtr+=6,retPtr+=2)
1327     {
1328       newConnPtr[0]=c[0]; newConnPtr[1]=c[1]; newConnPtr[2]=c[2];
1329       newConnPtr[3]=c[0]; newConnPtr[4]=c[2]; newConnPtr[5]=c[3];
1330       retPtr[0]=i; retPtr[1]=i;
1331     }
1332   _conn=newConn;
1333   _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TRI3);
1334   updateTime();
1335   return ret.retn();
1336 }
1337
1338 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePol1()
1339 {
1340   int nbOfCells=getNumberOfCells();
1341   if(getCellModelEnum()!=INTERP_KERNEL::NORM_QUAD4)
1342     return DataArrayInt::Range(0,nbOfCells,1);
1343   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(2*3*nbOfCells,1);
1344   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(2*nbOfCells,1);
1345   const int *c(_conn->begin());
1346   int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1347   for(int i=0;i<nbOfCells;i++,c+=4,newConnPtr+=6,retPtr+=2)
1348     {
1349       newConnPtr[0]=c[0]; newConnPtr[1]=c[1]; newConnPtr[2]=c[3];
1350       newConnPtr[3]=c[1]; newConnPtr[4]=c[2]; newConnPtr[5]=c[3];
1351       retPtr[0]=i; retPtr[1]=i;
1352     }
1353   _conn=newConn;
1354   _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TRI3);
1355   updateTime();
1356   return ret.retn();
1357 }
1358
1359 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePlanarFace5()
1360 {
1361   int nbOfCells=getNumberOfCells();
1362   if(getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA8)
1363     return DataArrayInt::Range(0,nbOfCells,1);
1364   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(5*4*nbOfCells,1);
1365   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(5*nbOfCells,1);
1366   const int *c(_conn->begin());
1367   int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1368   for(int i=0;i<nbOfCells;i++,c+=8,newConnPtr+=20,retPtr+=5)
1369     {
1370       for(int j=0;j<20;j++)
1371         newConnPtr[j]=c[INTERP_KERNEL::SPLIT_NODES_5_WO[j]];
1372       retPtr[0]=i; retPtr[1]=i; retPtr[2]=i; retPtr[3]=i; retPtr[4]=i;
1373     }
1374   _conn=newConn;
1375   _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TETRA4);
1376   updateTime();
1377   return ret.retn();
1378 }
1379
1380 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePlanarFace6()
1381 {
1382   int nbOfCells=getNumberOfCells();
1383   if(getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA8)
1384     return DataArrayInt::Range(0,nbOfCells,1);
1385   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(6*4*nbOfCells,1);
1386   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(6*nbOfCells,1);
1387   const int *c(_conn->begin());
1388   int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1389   for(int i=0;i<nbOfCells;i++,c+=8,newConnPtr+=24,retPtr+=6)
1390     {
1391       for(int j=0;j<24;j++)
1392         newConnPtr[j]=c[INTERP_KERNEL::SPLIT_NODES_6_WO[j]];
1393       retPtr[0]=i; retPtr[1]=i; retPtr[2]=i; retPtr[3]=i; retPtr[4]=i; retPtr[5]=i;
1394     }
1395   _conn=newConn;
1396   _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TETRA4);
1397   updateTime();
1398   return ret.retn();
1399 }
1400
1401 void MEDCoupling1SGTUMesh::reprQuickOverview(std::ostream& stream) const
1402 {
1403   stream << "MEDCoupling1SGTUMesh C++ instance at " << this << ". Type=" << _cm->getRepr() << ". Name : \"" << getName() << "\".";
1404   stream << " Mesh dimension : " << getMeshDimension() << ".";
1405   if(!_coords)
1406     { stream << " No coordinates set !"; return ; }
1407   if(!_coords->isAllocated())
1408     { stream << " Coordinates set but not allocated !"; return ; }
1409   stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
1410   stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
1411   if(!(const DataArrayInt *)_conn)
1412     { stream << std::endl << "Nodal connectivity NOT set !"; return ; }
1413   if(_conn->isAllocated())
1414     {
1415       if(_conn->getNumberOfComponents()==1)
1416         stream << std::endl << "Number of cells : " << getNumberOfCells() << ".";
1417     }
1418 }
1419
1420 void MEDCoupling1SGTUMesh::checkFullyDefined() const
1421 {
1422   if(!((const DataArrayInt *)_conn) || !((const DataArrayDouble *)_coords))
1423     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFullyDefined : part of this is not fully defined.");
1424 }
1425
1426 /*!
1427  * First step of unserialization process.
1428  */
1429 bool MEDCoupling1SGTUMesh::isEmptyMesh(const std::vector<int>& tinyInfo) const
1430 {
1431   throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEmptyMesh : not implemented yet !");
1432 }
1433
1434 void MEDCoupling1SGTUMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const
1435 {
1436   int it,order;
1437   double time=getTime(it,order);
1438   tinyInfo.clear(); tinyInfoD.clear(); littleStrings.clear();
1439   //
1440   littleStrings.push_back(getName());
1441   littleStrings.push_back(getDescription());
1442   littleStrings.push_back(getTimeUnit());
1443   //
1444   std::vector<std::string> littleStrings2,littleStrings3;
1445   if((const DataArrayDouble *)_coords)
1446     _coords->getTinySerializationStrInformation(littleStrings2);
1447   if((const DataArrayInt *)_conn)
1448     _conn->getTinySerializationStrInformation(littleStrings3);
1449   int sz0((int)littleStrings2.size()),sz1((int)littleStrings3.size());
1450   littleStrings.insert(littleStrings.end(),littleStrings2.begin(),littleStrings2.end());
1451   littleStrings.insert(littleStrings.end(),littleStrings3.begin(),littleStrings3.end());
1452   //
1453   tinyInfo.push_back(getCellModelEnum());
1454   tinyInfo.push_back(it);
1455   tinyInfo.push_back(order);
1456   std::vector<int> tinyInfo2,tinyInfo3;
1457   if((const DataArrayDouble *)_coords)
1458     _coords->getTinySerializationIntInformation(tinyInfo2);
1459   if((const DataArrayInt *)_conn)
1460     _conn->getTinySerializationIntInformation(tinyInfo3);
1461   int sz2((int)tinyInfo2.size()),sz3((int)tinyInfo3.size());
1462   tinyInfo.push_back(sz0); tinyInfo.push_back(sz1); tinyInfo.push_back(sz2); tinyInfo.push_back(sz3);
1463   tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
1464   tinyInfo.insert(tinyInfo.end(),tinyInfo3.begin(),tinyInfo3.end());
1465   //
1466   tinyInfoD.push_back(time);
1467 }
1468
1469 void MEDCoupling1SGTUMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
1470 {
1471   std::vector<int> tinyInfo2(tinyInfo.begin()+7,tinyInfo.begin()+7+tinyInfo[5]);
1472   std::vector<int> tinyInfo1(tinyInfo.begin()+7+tinyInfo[5],tinyInfo.begin()+7+tinyInfo[5]+tinyInfo[6]);
1473   a1->resizeForUnserialization(tinyInfo1);
1474   a2->resizeForUnserialization(tinyInfo2);
1475 }
1476
1477 void MEDCoupling1SGTUMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const
1478 {
1479   int sz(0);
1480   if((const DataArrayInt *)_conn)
1481     if(_conn->isAllocated())
1482       sz=_conn->getNbOfElems();
1483   a1=DataArrayInt::New();
1484   a1->alloc(sz,1);
1485   if(sz!=0 && (const DataArrayInt *)_conn)
1486     std::copy(_conn->begin(),_conn->end(),a1->getPointer());
1487   sz=0;
1488   if((const DataArrayDouble *)_coords)
1489     if(_coords->isAllocated())
1490       sz=_coords->getNbOfElems();
1491   a2=DataArrayDouble::New();
1492   a2->alloc(sz,1);
1493   if(sz!=0 && (const DataArrayDouble *)_coords)
1494     std::copy(_coords->begin(),_coords->end(),a2->getPointer());
1495 }
1496
1497 void MEDCoupling1SGTUMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,
1498                                            const std::vector<std::string>& littleStrings)
1499 {
1500   INTERP_KERNEL::NormalizedCellType gt((INTERP_KERNEL::NormalizedCellType)tinyInfo[0]);
1501   _cm=&INTERP_KERNEL::CellModel::GetCellModel(gt);
1502   setName(littleStrings[0]);
1503   setDescription(littleStrings[1]);
1504   setTimeUnit(littleStrings[2]);
1505   setTime(tinyInfoD[0],tinyInfo[1],tinyInfo[2]);
1506   int sz0(tinyInfo[3]),sz1(tinyInfo[4]),sz2(tinyInfo[5]),sz3(tinyInfo[6]);
1507   //
1508   _coords=DataArrayDouble::New();
1509   std::vector<int> tinyInfo2(tinyInfo.begin()+7,tinyInfo.begin()+7+sz2);
1510   _coords->resizeForUnserialization(tinyInfo2);
1511   std::copy(a2->begin(),a2->end(),_coords->getPointer());
1512   _conn=DataArrayInt::New();
1513   std::vector<int> tinyInfo3(tinyInfo.begin()+7+sz2,tinyInfo.begin()+7+sz2+sz3);
1514   _conn->resizeForUnserialization(tinyInfo3);
1515   std::copy(a1->begin(),a1->end(),_conn->getPointer());
1516   std::vector<std::string> littleStrings2(littleStrings.begin()+3,littleStrings.begin()+3+sz0);
1517   _coords->finishUnserialization(tinyInfo2,littleStrings2);
1518   std::vector<std::string> littleStrings3(littleStrings.begin()+3+sz0,littleStrings.begin()+3+sz0+sz1);
1519   _conn->finishUnserialization(tinyInfo3,littleStrings3);
1520 }
1521
1522 /*!
1523  * Checks if \a this and \a other meshes are geometrically equivalent with high
1524  * probability, else an exception is thrown. The meshes are considered equivalent if
1525  * (1) meshes contain the same number of nodes and the same number of elements of the
1526  * same types (2) three cells of the two meshes (first, last and middle) are based
1527  * on coincident nodes (with a specified precision).
1528  *  \param [in] other - the mesh to compare with.
1529  *  \param [in] prec - the precision used to compare nodes of the two meshes.
1530  *  \throw If the two meshes do not match.
1531  */
1532 void MEDCoupling1SGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const
1533 {
1534   MEDCouplingPointSet::checkFastEquivalWith(other,prec);
1535   const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
1536   if(!otherC)
1537     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : Two meshes are not unstructured with single static geometric type !");
1538   const DataArrayInt *c1(_conn),*c2(otherC->_conn);
1539   if(c1==c2)
1540     return;
1541   if(!c1 || !c2)
1542     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !");
1543   if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
1544     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !");
1545   if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
1546     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !");
1547   if(c1->getHashCode()!=c2->getHashCode())
1548     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : nodal connectivity differs");
1549 }
1550
1551 MEDCouplingPointSet *MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const
1552 {
1553   if(!other)
1554     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : input other is null !");
1555   const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
1556   if(!otherC)
1557     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !");
1558   std::vector<const MEDCoupling1SGTUMesh *> ms(2);
1559   ms[0]=this;
1560   ms[1]=otherC;
1561   return Merge1SGTUMeshesOnSameCoords(ms);
1562 }
1563
1564 void MEDCoupling1SGTUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const
1565 {
1566   checkFullyDefined();
1567   int nbOfNodes=getNumberOfNodes();
1568   int *revNodalIndxPtr=(int *)malloc((nbOfNodes+1)*sizeof(int));
1569   revNodalIndx->useArray(revNodalIndxPtr,true,C_DEALLOC,nbOfNodes+1,1);
1570   std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
1571   const int *conn=_conn->begin();
1572   int nbOfCells=getNumberOfCells();
1573   int nbOfEltsInRevNodal=0;
1574   int nbOfNodesPerCell=getNumberOfNodesPerCell();
1575   for(int eltId=0;eltId<nbOfCells;eltId++)
1576     {
1577       for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1578         {
1579           if(conn[0]>=0 && conn[0]<nbOfNodes)
1580             {
1581               nbOfEltsInRevNodal++;
1582               revNodalIndxPtr[conn[0]+1]++;
1583             }
1584           else
1585             {
1586               std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !";
1587               throw INTERP_KERNEL::Exception(oss.str().c_str());
1588             }
1589         }
1590     }
1591   std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<int>());
1592   conn=_conn->begin();
1593   int *revNodalPtr=(int *)malloc((nbOfEltsInRevNodal)*sizeof(int));
1594   revNodal->useArray(revNodalPtr,true,C_DEALLOC,nbOfEltsInRevNodal,1);
1595   std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
1596   for(int eltId=0;eltId<nbOfCells;eltId++)
1597     {
1598       for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1599         {
1600           *std::find_if(revNodalPtr+revNodalIndxPtr[*conn],revNodalPtr+revNodalIndxPtr[*conn+1],std::bind2nd(std::equal_to<int>(),-1))=eltId;
1601         }
1602     }
1603 }
1604
1605 /*!
1606  * Use \a nodalConn array as nodal connectivity of \a this. The input \a nodalConn pointer can be null.
1607  */
1608 void MEDCoupling1SGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn)
1609 {
1610   if(nodalConn)
1611     nodalConn->incrRef();
1612   _conn=nodalConn;
1613   declareAsNew();
1614 }
1615
1616 /*!
1617  * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it.
1618  */
1619 DataArrayInt *MEDCoupling1SGTUMesh::getNodalConnectivity() const
1620 {
1621   const DataArrayInt *ret(_conn);
1622   return const_cast<DataArrayInt *>(ret);
1623 }
1624
1625 /*!
1626  * Allocates memory to store an estimation of the given number of cells. Closer is the estimation to the number of cells effectively inserted,
1627  * less will be the needs to realloc. If the number of cells to be inserted is not known simply put 0 to this parameter.
1628  * If a nodal connectivity previouly existed before the call of this method, it will be reset.
1629  *
1630  *  \param [in] nbOfCells - estimation of the number of cell \a this mesh will contain.
1631  */
1632 void MEDCoupling1SGTUMesh::allocateCells(int nbOfCells)
1633 {
1634   if(nbOfCells<0)
1635     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::allocateCells : the input number of cells should be >= 0 !");
1636   _conn=DataArrayInt::New();
1637   _conn->reserve(getNumberOfNodesPerCell()*nbOfCells);
1638   declareAsNew();
1639 }
1640
1641 /*!
1642  * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ).
1643  *
1644  * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add.
1645  * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
1646  * \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
1647  *        attached to \a this.
1648  * \thow If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
1649  */
1650 void MEDCoupling1SGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd)
1651 {
1652   int sz=(int)std::distance(nodalConnOfCellBg,nodalConnOfCellEnd);
1653   int ref=getNumberOfNodesPerCell();
1654   if(sz==ref)
1655     {
1656       DataArrayInt *c(_conn);
1657       if(c)
1658         c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd);
1659       else
1660         throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1SGTUMesh::allocateCells before !");
1661     }
1662   else
1663     {
1664       std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::insertNextCell : input nodal size (" << sz << ") does not match number of nodes per cell of this (";
1665       oss << ref << ") !";
1666       throw INTERP_KERNEL::Exception(oss.str().c_str());
1667     }
1668 }
1669
1670 /*!
1671  * This method builds the dual mesh of \a this and returns it.
1672  * 
1673  * \return MEDCoupling1SGTUMesh * - newly object created to be managed by the caller.
1674  * \throw If \a this is not a mesh containing only simplex cells.
1675  * \throw If \a this is not correctly allocated (coordinates and connectivities have to be correctly set !).
1676  * \throw If at least one node in \a this is orphan (without any simplex cell lying on it !)
1677  */
1678 MEDCoupling1GTUMesh *MEDCoupling1SGTUMesh::computeDualMesh() const
1679 {
1680   const INTERP_KERNEL::CellModel& cm(getCellModel());
1681   if(!cm.isSimplex())
1682     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh : this mesh is not a simplex mesh ! Please invoke simplexize of tetrahedrize on this before calling this method !");
1683   switch(getMeshDimension())
1684   {
1685     case 3:
1686       return computeDualMesh3D();
1687     case 2:
1688       return computeDualMesh2D();
1689     default:
1690       throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh : meshdimension must be in [2,3] !");
1691   }
1692 }
1693
1694 /*!
1695  * This method explode each NORM_HEXA8 cells in \a this into 6 NORM_QUAD4 cells and put the result into the MEDCoupling1SGTUMesh returned instance.
1696  * 
1697  * \return MEDCoupling1SGTUMesh * - a newly allocated instances (to be managed by the caller) storing the result of the explosion.
1698  * \throw If \a this is not a mesh containing only NORM_HEXA8 cells.
1699  * \throw If \a this is not properly allocated.
1700  */
1701 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::explodeEachHexa8To6Quad4() const
1702 {
1703   const INTERP_KERNEL::CellModel& cm(getCellModel());
1704   if(cm.getEnum()!=INTERP_KERNEL::NORM_HEXA8)
1705     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::explodeEachHexa8To6Quad4 : this method can be applied only on HEXA8 mesh !");
1706   int nbHexa8(getNumberOfCells());
1707   const int *inConnPtr(getNodalConnectivity()->begin());
1708   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(MEDCoupling1SGTUMesh::New(getName(),INTERP_KERNEL::NORM_QUAD4));
1709   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(DataArrayInt::New()); c->alloc(nbHexa8*6*4,1);
1710   int *cPtr(c->getPointer());
1711   for(int i=0;i<nbHexa8;i++,inConnPtr+=8)
1712     {
1713       for(int j=0;j<6;j++,cPtr+=4)
1714         cm.fillSonCellNodalConnectivity(j,inConnPtr,cPtr);
1715     }
1716   ret->setCoords(getCoords());
1717   ret->setNodalConnectivity(c);
1718   return ret.retn();
1719 }
1720
1721 /*!
1722  * This method starts from an unstructured mesh that hides in reality a cartesian mesh.
1723  * If it is not the case, an exception will be thrown.
1724  * This method returns three objects : The cartesian mesh geometrically equivalent to \a this (within a precision of \a eps) and a permutation of cells
1725  * and a permutation of nodes.
1726  *
1727  * - this[cellPerm[i]]=ret[i]
1728  *
1729  * \param [out] cellPerm the permutation array of size \c this->getNumberOfCells()
1730  * \param [out] nodePerm the permutation array of size \c this->getNumberOfNodes()
1731  * \return MEDCouplingCMesh * - a newly allocated mesh that is the result of the structurization of \a this.
1732  */
1733 MEDCouplingCMesh *MEDCoupling1SGTUMesh::structurizeMe(DataArrayInt *& cellPerm, DataArrayInt *& nodePerm, double eps) const
1734 {
1735   checkCoherency();
1736   int spaceDim(getSpaceDimension()),meshDim(getMeshDimension()),nbNodes(getNumberOfNodes());
1737   if(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(meshDim)!=getCellModelEnum())
1738     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::structurizeMe : the unique geo type in this is not compatible with the geometric type regarding mesh dimension !");
1739   MEDCouplingAutoRefCountObjectPtr<MEDCouplingCMesh> cm(MEDCouplingCMesh::New());
1740   for(int i=0;i<spaceDim;i++)
1741     {
1742       std::vector<int> tmp(1,i);
1743       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> elt(static_cast<DataArrayDouble*>(getCoords()->keepSelectedComponents(tmp)));
1744       elt=elt->getDifferentValues(eps);
1745       elt->sort(true);
1746       cm->setCoordsAt(i,elt);
1747     }
1748   if(nbNodes!=cm->getNumberOfNodes())
1749     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 ?");
1750   try
1751   { cm->copyTinyInfoFrom(this); }
1752   catch(INTERP_KERNEL::Exception&) { }
1753   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> um(cm->buildUnstructured()),self(buildUnstructured());
1754   self->checkGeoEquivalWith(um,12,eps,cellPerm,nodePerm);
1755   return cm.retn();
1756 }
1757
1758 /// @cond INTERNAL
1759
1760 bool UpdateHexa8Cell(int validAxis, int neighId, const int *validConnQuad4NeighSide, int *allFacesNodalConn, int *myNeighbours)
1761 {
1762   static const int TAB[48]={
1763     0,1,2,3,4,5,6,7,//0
1764     4,7,6,5,0,3,2,1,//1
1765     0,3,7,4,1,2,6,5,//2
1766     4,0,3,7,5,1,2,6,//3
1767     5,1,0,4,6,2,3,7,//4
1768     3,7,4,0,2,6,5,1 //5
1769   };
1770   static const int TAB2[6]={0,0,3,3,3,3};
1771   if(myNeighbours[validAxis]==neighId && allFacesNodalConn[4*validAxis+0]==validConnQuad4NeighSide[TAB2[validAxis]])
1772     return true;
1773   int oldAxis((int)std::distance(myNeighbours,std::find(myNeighbours,myNeighbours+6,neighId)));
1774   std::size_t pos(std::distance(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS,std::find(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS,MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS+6,oldAxis)));
1775   std::size_t pos0(pos/2),pos1(pos%2);
1776   int oldAxisOpp(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS[2*pos0+(pos1+1)%2]);
1777   int oldConn[8],myConn2[8]={-1,-1,-1,-1,-1,-1,-1,-1},myConn[8],edgeConn[2],allFacesTmp[24],neighTmp[6];
1778   oldConn[0]=allFacesNodalConn[0]; oldConn[1]=allFacesNodalConn[1]; oldConn[2]=allFacesNodalConn[2]; oldConn[3]=allFacesNodalConn[3];
1779   oldConn[4]=allFacesNodalConn[4]; oldConn[5]=allFacesNodalConn[7]; oldConn[6]=allFacesNodalConn[6]; oldConn[7]=allFacesNodalConn[5];
1780   const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_HEXA8));
1781   for(int i=0;i<4;i++)
1782     myConn2[i]=validConnQuad4NeighSide[(4-i+TAB2[validAxis])%4];
1783   for(int i=0;i<4;i++)
1784     {
1785       int nodeId(myConn2[i]);//the node id for which the opposite one will be found
1786       bool found(false);
1787       INTERP_KERNEL::NormalizedCellType typeOfSon;
1788       for(int j=0;j<12 && !found;j++)
1789         {
1790           cm.fillSonEdgesNodalConnectivity3D(j,oldConn,-1,edgeConn,typeOfSon);
1791           if(edgeConn[0]==nodeId || edgeConn[1]==nodeId)
1792             {
1793               if(std::find(allFacesNodalConn+4*oldAxisOpp,allFacesNodalConn+4*oldAxisOpp+4,edgeConn[0]==nodeId?edgeConn[1]:edgeConn[0])!=allFacesNodalConn+4*oldAxisOpp+4)
1794                 {
1795                   myConn2[i+4]=edgeConn[0]==nodeId?edgeConn[1]:edgeConn[0];
1796                   found=true;
1797                 }
1798             }
1799         }
1800       if(!found)
1801         throw INTERP_KERNEL::Exception("UpdateHexa8Cell : Internal Error !");
1802     }
1803   const int *myTab(TAB+8*validAxis);
1804   for(int i=0;i<8;i++)
1805     myConn[i]=myConn2[myTab[i]];
1806   for(int i=0;i<6;i++)
1807     {
1808       cm.fillSonCellNodalConnectivity(i,myConn,allFacesTmp+4*i);
1809       std::set<int> s(allFacesTmp+4*i,allFacesTmp+4*i+4);
1810       bool found(false);
1811       for(int j=0;j<6 && !found;j++)
1812         {
1813           std::set<int> s1(allFacesNodalConn+4*j,allFacesNodalConn+4*j+4);
1814           if(s==s1)
1815             {
1816               neighTmp[i]=myNeighbours[j];
1817               found=true;
1818             }
1819         }
1820       if(!found)
1821         throw INTERP_KERNEL::Exception("UpdateHexa8Cell : Internal Error #2 !");
1822     }
1823   std::copy(allFacesTmp,allFacesTmp+24,allFacesNodalConn);
1824   std::copy(neighTmp,neighTmp+6,myNeighbours);
1825   return false;
1826 }
1827
1828 /// @endcond
1829
1830 /*!
1831  * 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
1832  * homogeneous. If it succeeds the result of MEDCouplingUMesh::tetrahedrize will return a conform mesh.
1833  *
1834  * \return DataArrayInt * - a newly allocated array (to be managed by the caller) containing renumbered cell ids.
1835  *
1836  * \throw If \a this is not a mesh containing only NORM_HEXA8 cells.
1837  * \throw If \a this is not properly allocated.
1838  * \sa MEDCouplingUMesh::tetrahedrize, MEDCouplingUMesh::simplexize.
1839  */
1840 DataArrayInt *MEDCoupling1SGTUMesh::sortHexa8EachOther()
1841 {
1842   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> quads(explodeEachHexa8To6Quad4());//checks that only hexa8
1843   int nbHexa8(getNumberOfCells()),*cQuads(quads->getNodalConnectivity()->getPointer());
1844   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> neighOfQuads(DataArrayInt::New()); neighOfQuads->alloc(nbHexa8*6,1); neighOfQuads->fillWithValue(-1);
1845   int *ptNeigh(neighOfQuads->getPointer());
1846   {//neighOfQuads tells for each face of each Quad8 which cell (if!=-1) is connected to this face.
1847     MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> quadsTmp(quads->buildUnstructured());
1848     MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ccSafe,cciSafe;
1849     DataArrayInt *cc(0),*cci(0);
1850     quadsTmp->findCommonCells(3,0,cc,cci);
1851     ccSafe=cc; cciSafe=cci;
1852     const int *ccPtr(ccSafe->begin()),nbOfPair(cci->getNumberOfTuples()-1);
1853     for(int i=0;i<nbOfPair;i++)
1854       { ptNeigh[ccPtr[2*i+0]]=ccPtr[2*i+1]/6; ptNeigh[ccPtr[2*i+1]]=ccPtr[2*i+0]/6; }
1855   }
1856   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
1857   std::vector<bool> fetched(nbHexa8,false);
1858   std::vector<bool>::iterator it(std::find(fetched.begin(),fetched.end(),false));
1859   while(it!=fetched.end())//it will turns as time as number of connected zones
1860     {
1861       int cellId((int)std::distance(fetched.begin(),it));//it is the seed of the connected zone.
1862       std::set<int> s; s.insert(cellId);//s contains already organized.
1863       while(!s.empty())
1864         {
1865           std::set<int> sNext;
1866           for(std::set<int>::const_iterator it0=s.begin();it0!=s.end();it0++)
1867             {
1868               fetched[*it0]=true;
1869               int *myNeighb(ptNeigh+6*(*it0));
1870               for(int i=0;i<6;i++)
1871                 {
1872                   if(myNeighb[i]!=-1 && !fetched[myNeighb[i]])
1873                     {
1874                       std::size_t pos(std::distance(HEXA8_FACE_PAIRS,std::find(HEXA8_FACE_PAIRS,HEXA8_FACE_PAIRS+6,i)));
1875                       std::size_t pos0(pos/2),pos1(pos%2);
1876                       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]))
1877                         ret->pushBackSilent(myNeighb[i]);
1878                       fetched[myNeighb[i]]=true;
1879                       sNext.insert(myNeighb[i]);
1880                     }
1881                 }
1882             }
1883           s=sNext;
1884         }
1885       it=std::find(fetched.begin(),fetched.end(),false);
1886     }
1887   if(!ret->empty())
1888     {
1889       int *conn(getNodalConnectivity()->getPointer());
1890       for(const int *pt=ret->begin();pt!=ret->end();pt++)
1891         {
1892           int cellId(*pt);
1893           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];
1894           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];
1895         }
1896       declareAsNew();
1897     }
1898   return ret.retn();
1899 }
1900
1901 MEDCoupling1DGTUMesh *MEDCoupling1SGTUMesh::computeDualMesh3D() const
1902 {
1903   static const int DUAL_TETRA_0[36]={
1904     4,1,0, 6,0,3, 7,3,1,
1905     4,0,1, 5,2,0, 8,1,2,
1906     6,3,0, 5,0,2, 9,2,3,
1907     7,1,3, 9,3,2, 8,2,1
1908   };
1909   static const int DUAL_TETRA_1[36]={
1910     8,4,10, 11,5,8, 10,7,11,
1911     9,4,8, 8,5,12, 12,6,9,
1912     10,4,9, 9,6,13, 13,7,10,
1913     12,5,11, 13,6,12, 11,7,13
1914   };
1915   static const int FACEID_NOT_SH_NODE[4]={2,3,1,0};
1916   if(getCellModelEnum()!=INTERP_KERNEL::NORM_TETRA4)
1917     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh3D : only TETRA4 supported !");
1918   checkFullyDefined();
1919   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> thisu(buildUnstructured());
1920   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revNodArr(DataArrayInt::New()),revNodIArr(DataArrayInt::New());
1921   thisu->getReverseNodalConnectivity(revNodArr,revNodIArr);
1922   const int *revNod(revNodArr->begin()),*revNodI(revNodIArr->begin()),*nodal(_conn->begin());
1923   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d1Arr(DataArrayInt::New()),di1Arr(DataArrayInt::New()),rd1Arr(DataArrayInt::New()),rdi1Arr(DataArrayInt::New());
1924   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> edges(thisu->explode3DMeshTo1D(d1Arr,di1Arr,rd1Arr,rdi1Arr));
1925   const int *d1(d1Arr->begin());
1926   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d2Arr(DataArrayInt::New()),di2Arr(DataArrayInt::New()),rd2Arr(DataArrayInt::New()),rdi2Arr(DataArrayInt::New());
1927   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> faces(thisu->buildDescendingConnectivity(d2Arr,di2Arr,rd2Arr,rdi2Arr));  thisu=0;
1928   const int *d2(d2Arr->begin()),*rdi2(rdi2Arr->begin());
1929   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> edgesBaryArr(edges->getBarycenterAndOwner()),facesBaryArr(faces->getBarycenterAndOwner()),baryArr(getBarycenterAndOwner());
1930   const int nbOfNodes(getNumberOfNodes()),offset0(nbOfNodes+faces->getNumberOfCells()),offset1(offset0+edges->getNumberOfCells());
1931   edges=0; faces=0;
1932   std::vector<const DataArrayDouble *> v(4); v[0]=getCoords(); v[1]=facesBaryArr; v[2]=edgesBaryArr; v[3]=baryArr;
1933   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> zeArr(DataArrayDouble::Aggregate(v)); baryArr=0; edgesBaryArr=0; facesBaryArr=0;
1934   std::string name("DualOf_"); name+=getName();
1935   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(name,INTERP_KERNEL::NORM_POLYHED)); ret->setCoords(zeArr);
1936   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),ciArr(DataArrayInt::New()); ciArr->alloc(nbOfNodes+1,1); ciArr->setIJ(0,0,0); cArr->alloc(0,1);
1937   for(int i=0;i<nbOfNodes;i++,revNodI++)
1938     {
1939       int nbOfCellsSharingNode(revNodI[1]-revNodI[0]);
1940       if(nbOfCellsSharingNode==0)
1941         {
1942           std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeDualMesh3D : Node #" << i << " is orphan !"; 
1943           throw INTERP_KERNEL::Exception(oss.str().c_str());
1944         }
1945       for(int j=0;j<nbOfCellsSharingNode;j++)
1946         {
1947           int curCellId(revNod[revNodI[0]+j]);
1948           const int *connOfCurCell(nodal+4*curCellId);
1949           std::size_t nodePosInCurCell(std::distance(connOfCurCell,std::find(connOfCurCell,connOfCurCell+4,i)));
1950           if(j!=0) cArr->pushBackSilent(-1);
1951           int tmp[14];
1952           //
1953           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;
1954           tmp[2]=curCellId+offset1; tmp[3]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+2]]+nbOfNodes;
1955           tmp[4]=-1;
1956           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;
1957           tmp[7]=curCellId+offset1; tmp[8]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+5]]+nbOfNodes;
1958           tmp[9]=-1;
1959           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;
1960           tmp[12]=curCellId+offset1; tmp[13]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+8]]+nbOfNodes;
1961           cArr->insertAtTheEnd(tmp,tmp+14);
1962           int kk(0);
1963           for(int k=0;k<4;k++)
1964             {
1965               if(FACEID_NOT_SH_NODE[nodePosInCurCell]!=k)
1966                 {
1967                   const int *faceId(d2+4*curCellId+k);
1968                   if(rdi2[*faceId+1]-rdi2[*faceId]==1)
1969                     {
1970                       int tmp2[5]; tmp2[0]=-1; tmp2[1]=i;
1971                       tmp2[2]=d1[6*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+0]-8]+offset0;
1972                       tmp2[3]=d2[4*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+1]-4]+nbOfNodes;
1973                       tmp2[4]=d1[6*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+2]-8]+offset0;
1974                       cArr->insertAtTheEnd(tmp2,tmp2+5);
1975                     }
1976                   kk++;
1977                 }
1978             }
1979         }
1980       ciArr->setIJ(i+1,0,cArr->getNumberOfTuples());
1981     }
1982   ret->setNodalConnectivity(cArr,ciArr);
1983   return ret.retn();
1984 }
1985
1986 MEDCoupling1DGTUMesh *MEDCoupling1SGTUMesh::computeDualMesh2D() const
1987 {
1988   static const int DUAL_TRI_0[6]={0,2, 1,0, 2,1};
1989   static const int DUAL_TRI_1[6]={-3,+5, +3,-4, +4,-5};
1990   static const int FACEID_NOT_SH_NODE[3]={1,2,0};
1991   if(getCellModelEnum()!=INTERP_KERNEL::NORM_TRI3)
1992     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh2D : only TRI3 supported !");
1993   checkFullyDefined();
1994   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> thisu(buildUnstructured());
1995   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revNodArr(DataArrayInt::New()),revNodIArr(DataArrayInt::New());
1996   thisu->getReverseNodalConnectivity(revNodArr,revNodIArr);
1997   const int *revNod(revNodArr->begin()),*revNodI(revNodIArr->begin()),*nodal(_conn->begin());
1998   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d2Arr(DataArrayInt::New()),di2Arr(DataArrayInt::New()),rd2Arr(DataArrayInt::New()),rdi2Arr(DataArrayInt::New());
1999   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> edges(thisu->buildDescendingConnectivity(d2Arr,di2Arr,rd2Arr,rdi2Arr));  thisu=0;
2000   const int *d2(d2Arr->begin()),*rdi2(rdi2Arr->begin());
2001   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> edgesBaryArr(edges->getBarycenterAndOwner()),baryArr(getBarycenterAndOwner());
2002   const int nbOfNodes(getNumberOfNodes()),offset0(nbOfNodes+edges->getNumberOfCells());
2003   edges=0;
2004   std::vector<const DataArrayDouble *> v(3); v[0]=getCoords(); v[1]=edgesBaryArr; v[2]=baryArr;
2005   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> zeArr(DataArrayDouble::Aggregate(v)); baryArr=0; edgesBaryArr=0;
2006   std::string name("DualOf_"); name+=getName();
2007   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(name,INTERP_KERNEL::NORM_POLYGON)); ret->setCoords(zeArr);
2008   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),ciArr(DataArrayInt::New()); ciArr->alloc(nbOfNodes+1,1); ciArr->setIJ(0,0,0); cArr->alloc(0,1);
2009   for(int i=0;i<nbOfNodes;i++,revNodI++)
2010     {
2011       int nbOfCellsSharingNode(revNodI[1]-revNodI[0]);
2012       if(nbOfCellsSharingNode==0)
2013         {
2014           std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeDualMesh2D : Node #" << i << " is orphan !"; 
2015           throw INTERP_KERNEL::Exception(oss.str().c_str());
2016         }
2017       std::vector< std::vector<int> > polyg;
2018       for(int j=0;j<nbOfCellsSharingNode;j++)
2019         {
2020           int curCellId(revNod[revNodI[0]+j]);
2021           const int *connOfCurCell(nodal+3*curCellId);
2022           std::size_t nodePosInCurCell(std::distance(connOfCurCell,std::find(connOfCurCell,connOfCurCell+4,i)));
2023           std::vector<int> locV(3);
2024           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;
2025           polyg.push_back(locV);
2026           int kk(0);
2027           for(int k=0;k<3;k++)
2028             {
2029               if(FACEID_NOT_SH_NODE[nodePosInCurCell]!=k)
2030                 {
2031                   const int *edgeId(d2+3*curCellId+k);
2032                   if(rdi2[*edgeId+1]-rdi2[*edgeId]==1)
2033                     {
2034                       std::vector<int> locV2(2);
2035                       int zeLocEdgeIdRel(DUAL_TRI_1[2*nodePosInCurCell+kk]);
2036                       if(zeLocEdgeIdRel>0)
2037                         {  locV2[0]=d2[3*curCellId+zeLocEdgeIdRel-3]+nbOfNodes;  locV2[1]=i; }
2038                       else
2039                         {  locV2[0]=i; locV2[1]=d2[3*curCellId-zeLocEdgeIdRel-3]+nbOfNodes; }
2040                       polyg.push_back(locV2);
2041                     }
2042                   kk++;
2043                 }
2044             }
2045         }
2046       std::vector<int> zePolyg(MEDCoupling1DGTUMesh::BuildAPolygonFromParts(polyg));
2047       cArr->insertAtTheEnd(zePolyg.begin(),zePolyg.end());
2048       ciArr->setIJ(i+1,0,cArr->getNumberOfTuples());
2049     }
2050   ret->setNodalConnectivity(cArr,ciArr);
2051   return ret.retn();
2052 }
2053
2054 /*!
2055  * This method aggregate the bbox of each cell and put it into bbox 
2056  *
2057  * \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)
2058  *                         For all other cases this input parameter is ignored.
2059  * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components.
2060  * 
2061  * \throw If \a this is not fully set (coordinates and connectivity).
2062  * \throw If a cell in \a this has no valid nodeId.
2063  */
2064 DataArrayDouble *MEDCoupling1SGTUMesh::getBoundingBoxForBBTree(double arcDetEps) const
2065 {
2066   int spaceDim(getSpaceDimension()),nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes()),nbOfNodesPerCell(getNumberOfNodesPerCell());
2067   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim);
2068   double *bbox(ret->getPointer());
2069   for(int i=0;i<nbOfCells*spaceDim;i++)
2070     {
2071       bbox[2*i]=std::numeric_limits<double>::max();
2072       bbox[2*i+1]=-std::numeric_limits<double>::max();
2073     }
2074   const double *coordsPtr(_coords->getConstPointer());
2075   const int *conn(_conn->getConstPointer());
2076   for(int i=0;i<nbOfCells;i++)
2077     {
2078       int kk(0);
2079       for(int j=0;j<nbOfNodesPerCell;j++,conn++)
2080         {
2081           int nodeId(*conn);
2082           if(nodeId>=0 && nodeId<nbOfNodes)
2083             {
2084               for(int k=0;k<spaceDim;k++)
2085                 {
2086                   bbox[2*spaceDim*i+2*k]=std::min(bbox[2*spaceDim*i+2*k],coordsPtr[spaceDim*nodeId+k]);
2087                   bbox[2*spaceDim*i+2*k+1]=std::max(bbox[2*spaceDim*i+2*k+1],coordsPtr[spaceDim*nodeId+k]);
2088                 }
2089               kk++;
2090             }
2091         }
2092       if(kk==0)
2093         {
2094           std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getBoundingBoxForBBTree : cell #" << i << " contains no valid nodeId !";
2095           throw INTERP_KERNEL::Exception(oss.str().c_str());
2096         }
2097     }
2098   return ret.retn();
2099 }
2100
2101 //== 
2102
2103 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New()
2104 {
2105   return new MEDCoupling1DGTUMesh;
2106 }
2107
2108 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const std::string& name, INTERP_KERNEL::NormalizedCellType type)
2109 {
2110   if(type==INTERP_KERNEL::NORM_ERROR)
2111     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
2112   const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
2113   if(!cm.isDynamic())
2114     {
2115       std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::New : the input geometric type " << cm.getRepr() << " is static ! Only dynamic types are allowed here !";
2116       throw INTERP_KERNEL::Exception(oss.str().c_str());
2117     }
2118   return new MEDCoupling1DGTUMesh(name,cm);
2119 }
2120
2121 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh()
2122 {
2123 }
2124
2125 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const std::string& name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm)
2126 {
2127 }
2128
2129 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const MEDCoupling1DGTUMesh& other, bool recDeepCpy):MEDCoupling1GTUMesh(other,recDeepCpy),_conn(other._conn)
2130 {
2131   if(recDeepCpy)
2132     {
2133       const DataArrayInt *c(other._conn);
2134       if(c)
2135         _conn=c->deepCpy();
2136       c=other._conn_indx;
2137       if(c)
2138         _conn_indx=c->deepCpy();
2139     }
2140 }
2141
2142 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::clone(bool recDeepCpy) const
2143 {
2144   return new MEDCoupling1DGTUMesh(*this,recDeepCpy);
2145 }
2146
2147 /*!
2148  * This method behaves mostly like MEDCoupling1DGTUMesh::deepCpy method, except that only nodal connectivity arrays are deeply copied.
2149  * The coordinates are shared between \a this and the returned instance.
2150  * 
2151  * \return MEDCouplingUMesh * - A new object instance holding the copy of \a this (deep for connectivity, shallow for coordiantes)
2152  * \sa MEDCoupling1DGTUMesh::deepCpy
2153  */
2154 MEDCouplingPointSet *MEDCoupling1DGTUMesh::deepCpyConnectivityOnly() const
2155 {
2156   checkCoherency();
2157   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(clone(false));
2158   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(_conn->deepCpy()),ci(_conn_indx->deepCpy());
2159   ret->setNodalConnectivity(c,ci);
2160   return ret.retn();
2161 }
2162
2163 void MEDCoupling1DGTUMesh::updateTime() const
2164 {
2165   MEDCoupling1GTUMesh::updateTime();
2166   const DataArrayInt *c(_conn);
2167   if(c)
2168     updateTimeWith(*c);
2169   c=_conn_indx;
2170   if(c)
2171     updateTimeWith(*c);
2172 }
2173
2174 std::size_t MEDCoupling1DGTUMesh::getHeapMemorySizeWithoutChildren() const
2175 {
2176   return MEDCoupling1GTUMesh::getHeapMemorySizeWithoutChildren();
2177 }
2178
2179 std::vector<const BigMemoryObject *> MEDCoupling1DGTUMesh::getDirectChildrenWithNull() const
2180 {
2181   std::vector<const BigMemoryObject *> ret(MEDCoupling1GTUMesh::getDirectChildrenWithNull());
2182   ret.push_back((const DataArrayInt *)_conn);
2183   ret.push_back((const DataArrayInt *)_conn_indx);
2184   return ret;
2185 }
2186
2187 MEDCouplingMesh *MEDCoupling1DGTUMesh::deepCpy() const
2188 {
2189   return clone(true);
2190 }
2191
2192 bool MEDCoupling1DGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const
2193 {
2194   if(!other)
2195     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualIfNotWhy : input other pointer is null !");
2196   std::ostringstream oss; oss.precision(15);
2197   const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2198   if(!otherC)
2199     {
2200       reason="mesh given in input is not castable in MEDCoupling1DGTUMesh !";
2201       return false;
2202     }
2203   if(!MEDCoupling1GTUMesh::isEqualIfNotWhy(other,prec,reason))
2204     return false;
2205   const DataArrayInt *c1(_conn),*c2(otherC->_conn);
2206   if(c1==c2)
2207     return true;
2208   if(!c1 || !c2)
2209     {
2210       reason="in connectivity of single dynamic geometric type exactly one among this and other is null !";
2211       return false;
2212     }
2213   if(!c1->isEqualIfNotWhy(*c2,reason))
2214     {
2215       reason.insert(0,"Nodal connectivity DataArrayInt differs : ");
2216       return false;
2217     }
2218   c1=_conn_indx; c2=otherC->_conn_indx;
2219   if(c1==c2)
2220     return true;
2221   if(!c1 || !c2)
2222     {
2223       reason="in connectivity index of single dynamic geometric type exactly one among this and other is null !";
2224       return false;
2225     }
2226   if(!c1->isEqualIfNotWhy(*c2,reason))
2227     {
2228       reason.insert(0,"Nodal connectivity index DataArrayInt differs : ");
2229       return false;
2230     }
2231   return true;
2232 }
2233
2234 bool MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
2235 {
2236   if(!other)
2237     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
2238   const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2239   if(!otherC)
2240     return false;
2241   if(!MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(other,prec))
2242     return false;
2243   const DataArrayInt *c1(_conn),*c2(otherC->_conn);
2244   if(c1==c2)
2245     return true;
2246   if(!c1 || !c2)
2247     return false;
2248   if(!c1->isEqualWithoutConsideringStr(*c2))
2249     return false;
2250   return true;
2251   c1=_conn_indx; c2=otherC->_conn_indx;
2252   if(c1==c2)
2253     return true;
2254   if(!c1 || !c2)
2255     return false;
2256   if(!c1->isEqualWithoutConsideringStr(*c2))
2257     return false;
2258   return true;
2259 }
2260
2261 /*!
2262  * Checks if \a this and \a other meshes are geometrically equivalent with high
2263  * probability, else an exception is thrown. The meshes are considered equivalent if
2264  * (1) meshes contain the same number of nodes and the same number of elements of the
2265  * same types (2) three cells of the two meshes (first, last and middle) are based
2266  * on coincident nodes (with a specified precision).
2267  *  \param [in] other - the mesh to compare with.
2268  *  \param [in] prec - the precision used to compare nodes of the two meshes.
2269  *  \throw If the two meshes do not match.
2270  */
2271 void MEDCoupling1DGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const
2272 {
2273   MEDCouplingPointSet::checkFastEquivalWith(other,prec);
2274   const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2275   if(!otherC)
2276     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : Two meshes are not unstructured with single dynamic geometric type !");
2277   const DataArrayInt *c1(_conn),*c2(otherC->_conn);
2278   if(c1!=c2)
2279     {
2280       if(!c1 || !c2)
2281         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !");
2282       if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
2283         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !");
2284       if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
2285         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !");
2286       if(c1->getHashCode()!=c2->getHashCode())
2287         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity differs");
2288     }
2289   c1=_conn_indx; c2=otherC->_conn_indx;
2290   if(c1!=c2)
2291     {
2292       if(!c1 || !c2)
2293         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity index only in one of the 2 meshes !");
2294       if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
2295         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, only one is allocated !");
2296       if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
2297         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, must have 1 and only 1 component !");
2298       if(c1->getHashCode()!=c2->getHashCode())
2299         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity index differs");
2300     }
2301 }
2302
2303 void MEDCoupling1DGTUMesh::checkCoherencyOfConnectivity() const
2304 {
2305   const DataArrayInt *c1(_conn);
2306   if(c1)
2307     {
2308       if(c1->getNumberOfComponents()!=1)
2309         throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !");
2310       if(c1->getInfoOnComponent(0)!="")
2311         throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !");
2312       c1->checkAllocated();
2313     }
2314   else
2315     throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !");
2316   //
2317   int sz2=_conn->getNumberOfTuples();
2318   c1=_conn_indx;
2319   if(c1)
2320     {
2321       if(c1->getNumberOfComponents()!=1)
2322         throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to be with number of components set to one !");
2323       c1->checkAllocated();
2324       if(c1->getNumberOfTuples()<1)
2325         throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have a a size of 1 at least !");
2326       if(c1->getInfoOnComponent(0)!="")
2327         throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have no info on its single component !");
2328       int f=c1->front(),ll=c1->back();
2329       if(f<0 || f>=sz2)
2330         {
2331           std::ostringstream oss; oss << "Nodal connectivity index array first value (" << f << ") is expected to be exactly in [0," << sz2 << ") !";
2332           throw INTERP_KERNEL::Exception(oss.str().c_str());
2333         }
2334       if(ll<0 || ll>sz2)
2335         {
2336           std::ostringstream oss; oss << "Nodal connectivity index array last value (" << ll << ") is expected to be exactly in [0," << sz2 << "] !";
2337           throw INTERP_KERNEL::Exception(oss.str().c_str());
2338         }
2339       if(f>ll)
2340         {
2341           std::ostringstream oss; oss << "Nodal connectivity index array looks very bad (not increasing monotonic) because front (" << f << ") is greater that back (" << ll << ") !";
2342           throw INTERP_KERNEL::Exception(oss.str().c_str());
2343         }
2344     }
2345   else
2346     throw INTERP_KERNEL::Exception("Nodal connectivity index array not defined !");
2347   int szOfC1Exp=_conn_indx->back();
2348   if(sz2<szOfC1Exp)
2349     {
2350       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() << " !";
2351       throw INTERP_KERNEL::Exception(oss.str().c_str());
2352     }
2353 }
2354
2355 /*!
2356  * 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.
2357  * In addition you are sure that the length of nodal connectivity index array is bigger than or equal to one.
2358  * In addition you are also sure that length of nodal connectivity is coherent with the content of the last value in the index array.
2359  */
2360 void MEDCoupling1DGTUMesh::checkCoherency() const
2361 {
2362   MEDCouplingPointSet::checkCoherency();
2363   checkCoherencyOfConnectivity();
2364 }
2365
2366 void MEDCoupling1DGTUMesh::checkCoherency1(double eps) const
2367 {
2368   checkCoherency();
2369   const DataArrayInt *c1(_conn),*c2(_conn_indx);
2370   if(!c2->isMonotonic(true))
2371     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkCoherency1 : the nodal connectivity index is expected to be increasing monotinic !");
2372   //
2373   int nbOfTuples=c1->getNumberOfTuples();
2374   int nbOfNodes=getNumberOfNodes();
2375   const int *w(c1->begin());
2376   for(int i=0;i<nbOfTuples;i++,w++)
2377     {
2378       if(*w==-1) continue;
2379       if(*w<0 || *w>=nbOfNodes)
2380         {
2381           std::ostringstream oss; oss << "At pos #" << i << " of nodal connectivity array references to node id #" << *w << " must be in [0," << nbOfNodes << ") !";
2382           throw INTERP_KERNEL::Exception(oss.str().c_str());
2383         }
2384     }
2385 }
2386
2387 void MEDCoupling1DGTUMesh::checkCoherency2(double eps) const
2388 {
2389   checkCoherency1(eps);
2390 }
2391
2392 int MEDCoupling1DGTUMesh::getNumberOfCells() const
2393 {
2394   checkCoherencyOfConnectivity();//do not remove
2395   return _conn_indx->getNumberOfTuples()-1;
2396 }
2397
2398 /*!
2399  * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
2400  * For each cell in \b this the number of nodes constituting cell is computed.
2401  * For each polyhedron cell, the sum of the number of nodes of each face constituting polyhedron cell is returned.
2402  * So for pohyhedrons some nodes can be counted several times in the returned result.
2403  * 
2404  * \return a newly allocated array
2405  */
2406 DataArrayInt *MEDCoupling1DGTUMesh::computeNbOfNodesPerCell() const
2407 {
2408   checkCoherency();
2409   _conn_indx->checkMonotonic(true);
2410   if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2411     return _conn_indx->deltaShiftIndex();
2412   // for polyhedrons
2413   int nbOfCells=_conn_indx->getNumberOfTuples()-1;
2414   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2415   ret->alloc(nbOfCells,1);
2416   int *retPtr=ret->getPointer();
2417   const int *ci=_conn_indx->begin(),*c=_conn->begin();
2418   for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2419     *retPtr=ci[1]-ci[0]-std::count(c+ci[0],c+ci[1],-1);
2420   return ret.retn();
2421 }
2422
2423 /*!
2424  * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
2425  * For each cell in \b this the number of faces constituting (entity of dimension this->getMeshDimension()-1) cell is computed.
2426  * 
2427  * \return a newly allocated array
2428  */
2429 DataArrayInt *MEDCoupling1DGTUMesh::computeNbOfFacesPerCell() const
2430 {
2431   checkCoherency();
2432   _conn_indx->checkMonotonic(true);
2433   if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED && getCellModelEnum()!=INTERP_KERNEL::NORM_QPOLYG)
2434     return _conn_indx->deltaShiftIndex();
2435   if(getCellModelEnum()==INTERP_KERNEL::NORM_QPOLYG)
2436     {
2437       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=_conn_indx->deltaShiftIndex();
2438       ret->applyDivideBy(2);
2439       return ret.retn();
2440     }
2441   // for polyhedrons
2442   int nbOfCells=_conn_indx->getNumberOfTuples()-1;
2443   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2444   ret->alloc(nbOfCells,1);
2445   int *retPtr=ret->getPointer();
2446   const int *ci=_conn_indx->begin(),*c=_conn->begin();
2447   for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2448     *retPtr=std::count(c+ci[0],c+ci[1],-1)+1;
2449   return ret.retn();
2450 }
2451
2452 /*!
2453  * This method computes effective number of nodes per cell. That is to say nodes appearing several times in nodal connectivity of a cell,
2454  * will be counted only once here whereas it will be counted several times in MEDCoupling1DGTUMesh::computeNbOfNodesPerCell method.
2455  *
2456  * \return DataArrayInt * - new object to be deallocated by the caller.
2457  * \sa MEDCoupling1DGTUMesh::computeNbOfNodesPerCell
2458  */
2459 DataArrayInt *MEDCoupling1DGTUMesh::computeEffectiveNbOfNodesPerCell() const
2460 {
2461   checkCoherency();
2462   _conn_indx->checkMonotonic(true);
2463   int nbOfCells(_conn_indx->getNumberOfTuples()-1);
2464   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2465   ret->alloc(nbOfCells,1);
2466   int *retPtr(ret->getPointer());
2467   const int *ci(_conn_indx->begin()),*c(_conn->begin());
2468   if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2469     {
2470       for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2471         {
2472           std::set<int> s(c+ci[0],c+ci[1]);
2473           *retPtr=(int)s.size();
2474         }
2475     }
2476   else
2477     {
2478       for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2479         {
2480           std::set<int> s(c+ci[0],c+ci[1]); s.erase(-1);
2481           *retPtr=(int)s.size();
2482         }
2483     }
2484   return ret.retn();
2485 }
2486
2487 void MEDCoupling1DGTUMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
2488 {
2489   int nbOfCells(getNumberOfCells());//performs checks
2490   if(cellId>=0 && cellId<nbOfCells)
2491     {
2492       int strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0);
2493       int nbOfNodes=stp-strt;
2494       if(nbOfNodes<0)
2495         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::getNodeIdsOfCell : the index array is invalid ! Should be increasing monotonic !");
2496       conn.resize(nbOfNodes);
2497       std::copy(_conn->begin()+strt,_conn->begin()+stp,conn.begin());
2498     }
2499   else
2500     {
2501       std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !";
2502       throw INTERP_KERNEL::Exception(oss.str().c_str());
2503     }
2504 }
2505
2506 int MEDCoupling1DGTUMesh::getNumberOfNodesInCell(int cellId) const
2507 {
2508   int nbOfCells(getNumberOfCells());//performs checks
2509   if(cellId>=0 && cellId<nbOfCells)
2510     {
2511       const int *conn(_conn->begin());
2512       int strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0);
2513       return stp-strt-std::count(conn+strt,conn+stp,-1);
2514     }
2515   else
2516     {
2517       std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNumberOfNodesInCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !";
2518       throw INTERP_KERNEL::Exception(oss.str().c_str());
2519     }
2520 }
2521
2522 std::string MEDCoupling1DGTUMesh::simpleRepr() const
2523 {
2524   static const char msg0[]="No coordinates specified !";
2525   std::ostringstream ret;
2526   ret << "Single dynamic geometic type (" << _cm->getRepr() << ") unstructured mesh with name : \"" << getName() << "\"\n";
2527   ret << "Description of mesh : \"" << getDescription() << "\"\n";
2528   int tmpp1,tmpp2;
2529   double tt=getTime(tmpp1,tmpp2);
2530   ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
2531   ret << "Iteration : " << tmpp1  << " Order : " << tmpp2 << "\n";
2532   ret << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : ";
2533   if(_coords!=0)
2534     {
2535       const int spaceDim=getSpaceDimension();
2536       ret << spaceDim << "\nInfo attached on space dimension : ";
2537       for(int i=0;i<spaceDim;i++)
2538         ret << "\"" << _coords->getInfoOnComponent(i) << "\" ";
2539       ret << "\n";
2540     }
2541   else
2542     ret << msg0 << "\n";
2543   ret << "Number of nodes : ";
2544   if(_coords!=0)
2545     ret << getNumberOfNodes() << "\n";
2546   else
2547     ret << msg0 << "\n";
2548   ret << "Number of cells : ";
2549   bool isOK=true;
2550   try { checkCoherency(); } catch(INTERP_KERNEL::Exception& /* e */)
2551   {
2552       ret << "Nodal connectivity arrays are not set or badly set !\n";
2553       isOK=false;
2554   }
2555   if(isOK)
2556     ret << getNumberOfCells() << "\n";
2557   ret << "Cell type : " << _cm->getRepr() << "\n";
2558   return ret.str();
2559 }
2560
2561 std::string MEDCoupling1DGTUMesh::advancedRepr() const
2562 {
2563   std::ostringstream ret;
2564   ret << simpleRepr();
2565   ret << "\nCoordinates array : \n___________________\n\n";
2566   if(_coords)
2567     _coords->reprWithoutNameStream(ret);
2568   else
2569     ret << "No array set !\n";
2570   ret << "\n\nNodal Connectivity : \n____________________\n\n";
2571   //
2572   bool isOK=true;
2573   try { checkCoherency1(); } catch(INTERP_KERNEL::Exception& /* e */)
2574   {
2575       ret << "Nodal connectivity arrays are not set or badly set !\n";
2576       isOK=false;
2577   }
2578   if(!isOK)
2579     return ret.str();
2580   int nbOfCells=getNumberOfCells();
2581   const int *ci=_conn_indx->begin(),*c=_conn->begin();
2582   for(int i=0;i<nbOfCells;i++,ci++)
2583     {
2584       ret << "Cell #" << i << " : ";
2585       std::copy(c+ci[0],c+ci[1],std::ostream_iterator<int>(ret," "));
2586       ret << "\n";
2587     }
2588   return ret.str();
2589 }
2590
2591 DataArrayDouble *MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell() const
2592 {
2593   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
2594   int spaceDim=getSpaceDimension();
2595   int nbOfCells=getNumberOfCells();//checkCoherency()
2596   int nbOfNodes=getNumberOfNodes();
2597   ret->alloc(nbOfCells,spaceDim);
2598   double *ptToFill=ret->getPointer();
2599   const double *coor=_coords->begin();
2600   const int *nodal=_conn->begin(),*nodali=_conn_indx->begin();
2601   nodal+=nodali[0];
2602   if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2603     {
2604       for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
2605         {
2606           std::fill(ptToFill,ptToFill+spaceDim,0.);
2607           if(nodali[0]<nodali[1])// >= to avoid division by 0.
2608             {
2609               for(int j=nodali[0];j<nodali[1];j++,nodal++)
2610                 {
2611                   if(*nodal>=0 && *nodal<nbOfNodes)
2612                     std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
2613                   else
2614                     {
2615                       std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," <<   nbOfNodes << ") !";
2616                       throw INTERP_KERNEL::Exception(oss.str().c_str());
2617                     }
2618                   std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./(nodali[1]-nodali[0])));
2619                 }
2620             }
2621           else
2622             {
2623               std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : at cell #" << i << " the nodal index array is invalid !";
2624               throw INTERP_KERNEL::Exception(oss.str().c_str());
2625             }
2626         }
2627     }
2628   else
2629     {
2630       for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
2631         {
2632           std::fill(ptToFill,ptToFill+spaceDim,0.);
2633           if(nodali[0]<nodali[1])// >= to avoid division by 0.
2634             {
2635               int nbOfNod=0;
2636               for(int j=nodali[0];j<nodali[1];j++,nodal++)
2637                 {
2638                   if(*nodal==-1) continue;
2639                   if(*nodal>=0 && *nodal<nbOfNodes)
2640                     {
2641                       std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
2642                       nbOfNod++;
2643                     }
2644                   else
2645                     {
2646                       std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," <<   nbOfNodes << ") !";
2647                       throw INTERP_KERNEL::Exception(oss.str().c_str());
2648                     }
2649                 }
2650               if(nbOfNod!=0)
2651                 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./nbOfNod));
2652               else
2653                 {
2654                   std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : no nodes in cell #" << i << " !";
2655                   throw INTERP_KERNEL::Exception(oss.str().c_str());
2656                 }
2657             }
2658           else
2659             {
2660               std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron)  : at cell #" << i << " the nodal index array is invalid !";
2661               throw INTERP_KERNEL::Exception(oss.str().c_str());
2662             }
2663         }
2664     }
2665   return ret.retn();
2666 }
2667
2668 void MEDCoupling1DGTUMesh::renumberCells(const int *old2NewBg, bool check)
2669 {
2670   int nbCells=getNumberOfCells();
2671   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::New();
2672   o2n->useArray(old2NewBg,false,C_DEALLOC,nbCells,1);
2673   if(check)
2674     o2n=o2n->checkAndPreparePermutation();
2675   //
2676   const int *o2nPtr=o2n->getPointer();
2677   const int *conn=_conn->begin(),*conni=_conn_indx->begin();
2678   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New();
2679   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI=DataArrayInt::New();
2680   newConn->alloc(_conn->getNumberOfTuples(),1); newConnI->alloc(nbCells,1);
2681   newConn->copyStringInfoFrom(*_conn); newConnI->copyStringInfoFrom(*_conn_indx);
2682   //
2683   int *newC=newConn->getPointer(),*newCI=newConnI->getPointer();
2684   for(int i=0;i<nbCells;i++)
2685     {
2686       int newPos=o2nPtr[i];
2687       int sz=conni[i+1]-conni[i];
2688       if(sz>=0)
2689         newCI[newPos]=sz;
2690       else
2691         {
2692           std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberCells : the index nodal array is invalid for cell #" << i << " !";
2693           throw INTERP_KERNEL::Exception(oss.str().c_str());
2694         }
2695     }
2696   newConnI->computeOffsets2(); newCI=newConnI->getPointer();
2697   //
2698   for(int i=0;i<nbCells;i++,conni++)
2699     {
2700       int newp=o2nPtr[i];
2701       std::copy(conn+conni[0],conn+conni[1],newC+newCI[newp]);
2702     }
2703   _conn=newConn;
2704   _conn_indx=newConnI;
2705 }
2706
2707 MEDCouplingMesh *MEDCoupling1DGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
2708 {
2709   if(other->getType()!=SINGLE_DYNAMIC_GEO_TYPE_UNSTRUCTURED)
2710     throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single dynamic geo type each other !");
2711   const MEDCoupling1DGTUMesh *otherC=static_cast<const MEDCoupling1DGTUMesh *>(other);
2712   return Merge1DGTUMeshes(this,otherC);
2713 }
2714
2715 MEDCouplingUMesh *MEDCoupling1DGTUMesh::buildUnstructured() const
2716 {
2717   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName(),getMeshDimension());
2718   ret->setCoords(getCoords());
2719   const int *nodalConn=_conn->begin(),*nodalConnI=_conn_indx->begin();
2720   int nbCells=getNumberOfCells();//checkCoherency
2721   int geoType=(int)getCellModelEnum();
2722   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New(); c->alloc(nbCells+_conn->getNumberOfTuples(),1);
2723   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cI=DataArrayInt::New(); cI->alloc(nbCells+1);
2724   int *cPtr=c->getPointer(),*ciPtr=cI->getPointer();
2725   ciPtr[0]=0;
2726   for(int i=0;i<nbCells;i++,ciPtr++)
2727     {
2728       int sz=nodalConnI[i+1]-nodalConnI[i];
2729       if(sz>=0)
2730         {
2731           *cPtr++=geoType;
2732           cPtr=std::copy(nodalConn+nodalConnI[i],nodalConn+nodalConnI[i+1],cPtr);
2733           ciPtr[1]=ciPtr[0]+sz+1;
2734         }
2735       else
2736         {
2737           std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::buildUnstructured : Invalid for nodal index for cell #" << i << " !";
2738           throw INTERP_KERNEL::Exception(oss.str().c_str());
2739         }
2740     }
2741   ret->setConnectivity(c,cI,true);
2742   try
2743   { ret->copyTinyInfoFrom(this); }
2744   catch(INTERP_KERNEL::Exception&) { }
2745   return ret.retn();
2746 }
2747
2748 /*!
2749  * Do nothing for the moment, because there is no policy that allows to split polygons, polyhedrons ... into simplexes
2750  */
2751 DataArrayInt *MEDCoupling1DGTUMesh::simplexize(int policy)
2752 {
2753   int nbOfCells=getNumberOfCells();
2754   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2755   ret->alloc(nbOfCells,1);
2756   ret->iota(0);
2757   return ret.retn();
2758 }
2759
2760 void MEDCoupling1DGTUMesh::reprQuickOverview(std::ostream& stream) const
2761 {
2762   stream << "MEDCoupling1DGTUMesh C++ instance at " << this << ". Type=" << _cm->getRepr() << ". Name : \"" << getName() << "\".";
2763   stream << " Mesh dimension : " << getMeshDimension() << ".";
2764   if(!_coords)
2765     { stream << " No coordinates set !"; return ; }
2766   if(!_coords->isAllocated())
2767     { stream << " Coordinates set but not allocated !"; return ; }
2768   stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
2769   stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
2770   bool isOK=true;
2771   try { checkCoherency(); } catch(INTERP_KERNEL::Exception&  /* e */)
2772   {
2773       stream << std::endl << "Nodal connectivity NOT set properly !\n";
2774       isOK=false;
2775   }
2776   if(isOK)
2777     stream << std::endl << "Number of cells : " << getNumberOfCells() << ".";
2778 }
2779
2780 void MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other)
2781 {
2782   if(!other)
2783     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is null !");
2784   const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2785   if(!otherC)
2786     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1DGTUMesh instance !");
2787   setNodalConnectivity(otherC->getNodalConnectivity(),otherC->getNodalConnectivityIndex());
2788 }
2789
2790 MEDCouplingPointSet *MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const
2791 {
2792   if(!other)
2793     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : input other is null !");
2794   const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2795   if(!otherC)
2796     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !");
2797   std::vector<const MEDCoupling1DGTUMesh *> ms(2);
2798   ms[0]=this;
2799   ms[1]=otherC;
2800   return Merge1DGTUMeshesOnSameCoords(ms);
2801 }
2802
2803 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const
2804 {
2805   checkCoherency();
2806   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
2807   ret->setCoords(_coords);
2808   DataArrayInt *c=0,*ci=0;
2809   MEDCouplingUMesh::ExtractFromIndexedArrays(begin,end,_conn,_conn_indx,c,ci);
2810   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
2811   ret->setNodalConnectivity(c,ci);
2812   return ret.retn();
2813 }
2814
2815 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const
2816 {
2817   checkCoherency();
2818   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
2819   ret->setCoords(_coords);
2820   DataArrayInt *c=0,*ci=0;
2821   MEDCouplingUMesh::ExtractFromIndexedArrays2(start,end,step,_conn,_conn_indx,c,ci);
2822   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
2823   ret->setNodalConnectivity(c,ci);
2824   return ret.retn();
2825 }
2826
2827 void MEDCoupling1DGTUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const
2828 {
2829   checkCoherency2();
2830   int sz((int)nodeIdsInUse.size());
2831   for(const int *conn=_conn->begin();conn!=_conn->end();conn++)
2832     {
2833       if(*conn>=0 && *conn<sz)
2834         nodeIdsInUse[*conn]=true;
2835       else
2836         {
2837           if(*conn!=-1)
2838             {
2839               std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeNodeIdsAlg : At pos #" << std::distance(_conn->begin(),conn) << " value is " << *conn << " must be in [0," << sz << ") !";
2840               throw INTERP_KERNEL::Exception(oss.str().c_str());
2841             }
2842         }
2843     }
2844 }
2845
2846 void MEDCoupling1DGTUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const
2847 {
2848   checkFullyDefined();
2849   int nbOfNodes=getNumberOfNodes();
2850   int *revNodalIndxPtr=(int *)malloc((nbOfNodes+1)*sizeof(int));
2851   revNodalIndx->useArray(revNodalIndxPtr,true,C_DEALLOC,nbOfNodes+1,1);
2852   std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
2853   const int *conn=_conn->begin(),*conni=_conn_indx->begin();
2854   int nbOfCells=getNumberOfCells();
2855   int nbOfEltsInRevNodal=0;
2856   for(int eltId=0;eltId<nbOfCells;eltId++)
2857     {
2858       int nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
2859       if(nbOfNodesPerCell>=0)
2860         {
2861           for(int j=0;j<nbOfNodesPerCell;j++)
2862             {
2863               int nodeId=conn[conni[eltId]+j];
2864               if(nodeId==-1) continue;            
2865               if(nodeId>=0 && nodeId<nbOfNodes)
2866                 {
2867                   nbOfEltsInRevNodal++;
2868                   revNodalIndxPtr[nodeId+1]++;
2869                 }
2870               else
2871                 {
2872                   std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !";
2873                   throw INTERP_KERNEL::Exception(oss.str().c_str());
2874                 }
2875             }
2876         }
2877       else
2878         {
2879           std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << "nodal connectivity is invalid !";
2880           throw INTERP_KERNEL::Exception(oss.str().c_str());
2881         }
2882     }
2883   std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<int>());
2884   conn=_conn->begin();
2885   int *revNodalPtr=(int *)malloc((nbOfEltsInRevNodal)*sizeof(int));
2886   revNodal->useArray(revNodalPtr,true,C_DEALLOC,nbOfEltsInRevNodal,1);
2887   std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
2888   for(int eltId=0;eltId<nbOfCells;eltId++)
2889     {
2890       int nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
2891       for(int j=0;j<nbOfNodesPerCell;j++)
2892         {
2893           int nodeId=conn[conni[eltId]+j];
2894           if(nodeId!=-1)
2895             *std::find_if(revNodalPtr+revNodalIndxPtr[nodeId],revNodalPtr+revNodalIndxPtr[nodeId+1],std::bind2nd(std::equal_to<int>(),-1))=eltId;
2896         }
2897     }
2898 }
2899
2900 void MEDCoupling1DGTUMesh::checkFullyDefined() const
2901 {
2902   if(!((const DataArrayInt *)_conn) || !((const DataArrayInt *)_conn_indx) || !((const DataArrayDouble *)_coords))
2903     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFullyDefined : part of this is not fully defined.");
2904 }
2905
2906 bool MEDCoupling1DGTUMesh::isEmptyMesh(const std::vector<int>& tinyInfo) const
2907 {
2908   throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEmptyMesh : not implemented yet !");
2909 }
2910
2911 void MEDCoupling1DGTUMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const
2912 {
2913   int it,order;
2914   double time=getTime(it,order);
2915   tinyInfo.clear(); tinyInfoD.clear(); littleStrings.clear();
2916   //
2917   littleStrings.push_back(getName());
2918   littleStrings.push_back(getDescription());
2919   littleStrings.push_back(getTimeUnit());
2920   //
2921   std::vector<std::string> littleStrings2,littleStrings3,littleStrings4;
2922   if((const DataArrayDouble *)_coords)
2923     _coords->getTinySerializationStrInformation(littleStrings2);
2924   if((const DataArrayInt *)_conn)
2925     _conn->getTinySerializationStrInformation(littleStrings3);
2926   if((const DataArrayInt *)_conn_indx)
2927     _conn_indx->getTinySerializationStrInformation(littleStrings4);
2928   int sz0((int)littleStrings2.size()),sz1((int)littleStrings3.size()),sz2((int)littleStrings4.size());
2929   littleStrings.insert(littleStrings.end(),littleStrings2.begin(),littleStrings2.end());
2930   littleStrings.insert(littleStrings.end(),littleStrings3.begin(),littleStrings3.end());
2931   littleStrings.insert(littleStrings.end(),littleStrings4.begin(),littleStrings4.end());
2932   //
2933   tinyInfo.push_back(getCellModelEnum());
2934   tinyInfo.push_back(it);
2935   tinyInfo.push_back(order);
2936   std::vector<int> tinyInfo2,tinyInfo3,tinyInfo4;
2937   if((const DataArrayDouble *)_coords)
2938     _coords->getTinySerializationIntInformation(tinyInfo2);
2939   if((const DataArrayInt *)_conn)
2940     _conn->getTinySerializationIntInformation(tinyInfo3);
2941   if((const DataArrayInt *)_conn_indx)
2942     _conn_indx->getTinySerializationIntInformation(tinyInfo4);
2943   int sz3((int)tinyInfo2.size()),sz4((int)tinyInfo3.size()),sz5((int)tinyInfo4.size());
2944   tinyInfo.push_back(sz0); tinyInfo.push_back(sz1); tinyInfo.push_back(sz2); tinyInfo.push_back(sz3); tinyInfo.push_back(sz4);  tinyInfo.push_back(sz5);
2945   tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
2946   tinyInfo.insert(tinyInfo.end(),tinyInfo3.begin(),tinyInfo3.end());
2947   tinyInfo.insert(tinyInfo.end(),tinyInfo4.begin(),tinyInfo4.end());
2948   //
2949   tinyInfoD.push_back(time);
2950 }
2951
2952 void MEDCoupling1DGTUMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
2953 {
2954   std::vector<int> tinyInfo2(tinyInfo.begin()+9,tinyInfo.begin()+9+tinyInfo[6]);
2955   std::vector<int> tinyInfo1(tinyInfo.begin()+9+tinyInfo[6],tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7]);
2956   std::vector<int> tinyInfo12(tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7],tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7]+tinyInfo[8]);
2957   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p1(DataArrayInt::New()); p1->resizeForUnserialization(tinyInfo1);
2958   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p2(DataArrayInt::New()); p2->resizeForUnserialization(tinyInfo12);
2959   std::vector<const DataArrayInt *> v(2); v[0]=p1; v[1]=p2;
2960   p2=DataArrayInt::Aggregate(v);
2961   a2->resizeForUnserialization(tinyInfo2);
2962   a1->alloc(p2->getNbOfElems(),1);
2963 }
2964
2965 void MEDCoupling1DGTUMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const
2966 {
2967   int sz(0);
2968   if((const DataArrayInt *)_conn)
2969     if(_conn->isAllocated())
2970       sz=_conn->getNbOfElems();
2971   if((const DataArrayInt *)_conn_indx)
2972     if(_conn_indx->isAllocated())
2973       sz+=_conn_indx->getNbOfElems();
2974   a1=DataArrayInt::New();
2975   a1->alloc(sz,1);
2976   int *work(a1->getPointer());
2977   if(sz!=0 && (const DataArrayInt *)_conn)
2978     work=std::copy(_conn->begin(),_conn->end(),a1->getPointer());
2979   if(sz!=0 && (const DataArrayInt *)_conn_indx)
2980     std::copy(_conn_indx->begin(),_conn_indx->end(),work);
2981   sz=0;
2982   if((const DataArrayDouble *)_coords)
2983     if(_coords->isAllocated())
2984       sz=_coords->getNbOfElems();
2985   a2=DataArrayDouble::New();
2986   a2->alloc(sz,1);
2987   if(sz!=0 && (const DataArrayDouble *)_coords)
2988     std::copy(_coords->begin(),_coords->end(),a2->getPointer());
2989 }
2990
2991 void MEDCoupling1DGTUMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,
2992                                            const std::vector<std::string>& littleStrings)
2993 {
2994   INTERP_KERNEL::NormalizedCellType gt((INTERP_KERNEL::NormalizedCellType)tinyInfo[0]);
2995   _cm=&INTERP_KERNEL::CellModel::GetCellModel(gt);
2996   setName(littleStrings[0]);
2997   setDescription(littleStrings[1]);
2998   setTimeUnit(littleStrings[2]);
2999   setTime(tinyInfoD[0],tinyInfo[1],tinyInfo[2]);
3000   int sz0(tinyInfo[3]),sz1(tinyInfo[4]),sz2(tinyInfo[5]),sz3(tinyInfo[6]),sz4(tinyInfo[7]),sz5(tinyInfo[8]);
3001   //
3002   _coords=DataArrayDouble::New();
3003   std::vector<int> tinyInfo2(tinyInfo.begin()+9,tinyInfo.begin()+9+sz3);
3004   _coords->resizeForUnserialization(tinyInfo2);
3005   std::copy(a2->begin(),a2->end(),_coords->getPointer());
3006   _conn=DataArrayInt::New();
3007   std::vector<int> tinyInfo3(tinyInfo.begin()+9+sz3,tinyInfo.begin()+9+sz3+sz4);
3008   _conn->resizeForUnserialization(tinyInfo3);
3009   std::copy(a1->begin(),a1->begin()+_conn->getNbOfElems(),_conn->getPointer());
3010   _conn_indx=DataArrayInt::New();
3011   std::vector<int> tinyInfo4(tinyInfo.begin()+9+sz3+sz4,tinyInfo.begin()+9+sz3+sz4+sz5);
3012   _conn_indx->resizeForUnserialization(tinyInfo4);
3013   std::copy(a1->begin()+_conn->getNbOfElems(),a1->end(),_conn_indx->getPointer());
3014   std::vector<std::string> littleStrings2(littleStrings.begin()+3,littleStrings.begin()+3+sz0);
3015   _coords->finishUnserialization(tinyInfo2,littleStrings2);
3016   std::vector<std::string> littleStrings3(littleStrings.begin()+3+sz0,littleStrings.begin()+3+sz0+sz1);
3017   _conn->finishUnserialization(tinyInfo3,littleStrings3);
3018   std::vector<std::string> littleStrings4(littleStrings.begin()+3+sz0+sz1,littleStrings.begin()+3+sz0+sz1+sz2);
3019   _conn_indx->finishUnserialization(tinyInfo4,littleStrings4);
3020 }
3021
3022 /*!
3023  * Finds nodes not used in any cell and returns an array giving a new id to every node
3024  * by excluding the unused nodes, for which the array holds -1. The result array is
3025  * a mapping in "Old to New" mode.
3026  *  \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
3027  *  \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a
3028  *          this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
3029  *          if the node is unused or a new id else. The caller is to delete this
3030  *          array using decrRef() as it is no more needed.
3031  *  \throw If the coordinates array is not set.
3032  *  \throw If the nodal connectivity of cells is not defined.
3033  *  \throw If the nodal connectivity includes an invalid id.
3034  *  \sa MEDCoupling1DGTUMesh::computeFetchedNodeIds
3035  */
3036 DataArrayInt *MEDCoupling1DGTUMesh::computeFetchedNodeIds() const
3037 {
3038   checkCoherency2();
3039   int nbNodes(getNumberOfNodes());
3040   std::vector<bool> fetchedNodes(nbNodes,false);
3041   computeNodeIdsAlg(fetchedNodes);
3042   int sz((int)std::count(fetchedNodes.begin(),fetchedNodes.end(),true));
3043   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
3044   int *retPtr(ret->getPointer());
3045   for(int i=0;i<nbNodes;i++)
3046     if(fetchedNodes[i])
3047       *retPtr++=i;
3048   return ret.retn();
3049 }
3050
3051 /*!
3052  * Finds nodes not used in any cell and returns an array giving a new id to every node
3053  * by excluding the unused nodes, for which the array holds -1. The result array is
3054  * a mapping in "Old to New" mode. 
3055  *  \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
3056  *  \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a
3057  *          this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
3058  *          if the node is unused or a new id else. The caller is to delete this
3059  *          array using decrRef() as it is no more needed.  
3060  *  \throw If the coordinates array is not set.
3061  *  \throw If the nodal connectivity of cells is not defined.
3062  *  \throw If the nodal connectivity includes an invalid id.
3063  *  \sa MEDCoupling1DGTUMesh::computeFetchedNodeIds
3064  */
3065 DataArrayInt *MEDCoupling1DGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const
3066 {
3067   nbrOfNodesInUse=-1;
3068   int nbOfNodes=getNumberOfNodes();
3069   int nbOfCells=getNumberOfCells();//checkCoherency
3070   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
3071   ret->alloc(nbOfNodes,1);
3072   int *traducer=ret->getPointer();
3073   std::fill(traducer,traducer+nbOfNodes,-1);
3074   const int *conn=_conn->begin(),*conni(_conn_indx->begin());
3075   for(int i=0;i<nbOfCells;i++,conni++)
3076     {
3077       int nbNodesPerCell=conni[1]-conni[0];
3078       for(int j=0;j<nbNodesPerCell;j++)
3079         {
3080           int nodeId=conn[conni[0]+j];
3081           if(nodeId==-1) continue;
3082           if(nodeId>=0 && nodeId<nbOfNodes)
3083             traducer[nodeId]=1;
3084           else
3085             {
3086               std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsInUse : In cell #" << i  << " presence of node id " <<  nodeId << " not in [0," << nbOfNodes << ") !";
3087               throw INTERP_KERNEL::Exception(oss.str().c_str());
3088             }
3089         }
3090     }
3091   nbrOfNodesInUse=(int)std::count(traducer,traducer+nbOfNodes,1);
3092   std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
3093   return ret.retn();
3094 }
3095
3096 /*!
3097  *  Same than renumberNodesInConn(const int *) except that here the format of old-to-new traducer is using map instead
3098  *  of array. This method is dedicated for renumbering from a big set of nodes the a tiny set of nodes which is the case during extraction
3099  *  of a big mesh.
3100  */
3101 void MEDCoupling1DGTUMesh::renumberNodesInConn(const std::map<int,int>& newNodeNumbersO2N)
3102 {
3103   getNumberOfCells();//only to check that all is well defined.
3104   //
3105   int nbElemsIn(getNumberOfNodes()),nbOfTuples(_conn->getNumberOfTuples());
3106   int *pt(_conn->getPointer());
3107   for(int i=0;i<nbOfTuples;i++,pt++)
3108     {
3109       if(*pt==-1) continue;
3110       if(*pt>=0 && *pt<nbElemsIn)
3111         {
3112           std::map<int,int>::const_iterator it(newNodeNumbersO2N.find(*pt));
3113           if(it!=newNodeNumbersO2N.end())
3114             *pt=(*it).second;
3115           else
3116             {
3117               std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberNodesInConn : At pos #" << i << " of connectivity, node id is " << *pt << ". Not in keys of input map !";
3118               throw INTERP_KERNEL::Exception(oss.str().c_str());
3119             }
3120         }
3121       else
3122         {
3123           std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberNodesInConn : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn;
3124           throw INTERP_KERNEL::Exception(oss.str().c_str());
3125         }
3126     }
3127   //
3128   updateTime();
3129 }
3130
3131 /*!
3132  * Changes ids of nodes within the nodal connectivity arrays according to a permutation
3133  * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
3134  * This method is a generalization of shiftNodeNumbersInConn().
3135  *  \warning This method performs no check of validity of new ids. **Use it with care !**
3136  *  \param [in] newNodeNumbersO2N - a permutation array, of length \a
3137  *         this->getNumberOfNodes(), in "Old to New" mode. 
3138  *         See \ref MEDCouplingArrayRenumbering for more info on renumbering modes.
3139  *  \throw If the nodal connectivity of cells is not defined.
3140  */
3141 void MEDCoupling1DGTUMesh::renumberNodesInConn(const int *newNodeNumbersO2N)
3142 {
3143   getNumberOfCells();//only to check that all is well defined.
3144   //
3145   int nbElemsIn(getNumberOfNodes()),nbOfTuples(_conn->getNumberOfTuples());
3146   int *pt(_conn->getPointer());
3147   for(int i=0;i<nbOfTuples;i++,pt++)
3148     {
3149       if(*pt==-1) continue;
3150       if(*pt>=0 && *pt<nbElemsIn)
3151         *pt=newNodeNumbersO2N[*pt];
3152       else
3153         {
3154           std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberNodesInConn : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn;
3155           throw INTERP_KERNEL::Exception(oss.str().c_str());
3156         }
3157     }
3158   //
3159   updateTime();
3160 }
3161
3162 /*!
3163  * Keeps from \a this only cells which constituing point id are in the ids specified by [\a begin,\a end).
3164  * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
3165  * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not.
3166  * If \a fullyIn is true only cells whose ids are \b fully contained in [\a begin,\a end) tab will be kept.
3167  *
3168  * \param [in] begin input start of array of node ids.
3169  * \param [in] end input end of array of node ids.
3170  * \param [in] fullyIn input that specifies if all node ids must be in [\a begin,\a end) array to consider cell to be in.
3171  * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end.
3172  */
3173 void MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const
3174 {
3175   int nbOfCells=getNumberOfCells();
3176   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1);
3177   int tmp=-1;
3178   int sz=_conn->getMaxValue(tmp); sz=std::max(sz,0)+1;
3179   std::vector<bool> fastFinder(sz,false);
3180   for(const int *work=begin;work!=end;work++)
3181     if(*work>=0 && *work<sz)
3182       fastFinder[*work]=true;
3183   const int *conn=_conn->begin(),*conni=_conn_indx->begin();
3184   for(int i=0;i<nbOfCells;i++,conni++)
3185     {
3186       int ref=0,nbOfHit=0;
3187       int nbNodesPerCell=conni[1]-conni[0];
3188       if(nbNodesPerCell>=0)
3189         {
3190           for(int j=0;j<nbNodesPerCell;j++)
3191             {
3192               int nodeId=conn[conni[0]+j];
3193               if(nodeId>=0)
3194                 {
3195                   ref++;
3196                   if(fastFinder[nodeId])
3197                     nbOfHit++;
3198                 }
3199             }
3200         }
3201       else
3202         {
3203           std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds : invalid index array for cell #" << i << " !";
3204           throw INTERP_KERNEL::Exception(oss.str().c_str());
3205         }
3206       if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn))
3207         cellIdsKept->pushBackSilent(i);
3208     }
3209   cellIdsKeptArr=cellIdsKept.retn();
3210 }
3211
3212 void MEDCoupling1DGTUMesh::allocateCells(int nbOfCells)
3213 {
3214   if(nbOfCells<0)
3215     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::allocateCells : the input number of cells should be >= 0 !");
3216   _conn=DataArrayInt::New();
3217   _conn->reserve(nbOfCells*3);
3218   _conn_indx=DataArrayInt::New();
3219   _conn_indx->reserve(nbOfCells+1); _conn_indx->pushBackSilent(0);
3220   declareAsNew();
3221 }
3222
3223 /*!
3224  * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ).
3225  *
3226  * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add.
3227  * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
3228  * \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
3229  *        attached to \a this.
3230  * \thow If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
3231  */
3232 void MEDCoupling1DGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd)
3233 {
3234   int sz=(int)std::distance(nodalConnOfCellBg,nodalConnOfCellEnd);
3235   DataArrayInt *c(_conn),*c2(_conn_indx);
3236   if(c && c2)
3237     {
3238       int pos=c2->back();
3239       if(pos==c->getNumberOfTuples())
3240         {
3241           c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd);
3242           c2->pushBackSilent(pos+sz);
3243         }
3244       else
3245         {
3246           std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::insertNextCell : The nodal index array (end=" << pos << ") mismatches with nodal array (length=" << c->getNumberOfTuples() << ") !";
3247           throw INTERP_KERNEL::Exception(oss.str().c_str());
3248         }
3249     }
3250   else
3251     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1DGTUMesh::allocateCells before !");
3252 }
3253
3254 void MEDCoupling1DGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn, DataArrayInt *nodalConnIndex)
3255 {
3256   if(nodalConn)
3257     nodalConn->incrRef();
3258   _conn=nodalConn;
3259   if(nodalConnIndex)
3260     nodalConnIndex->incrRef();
3261   _conn_indx=nodalConnIndex;
3262   declareAsNew();
3263 }
3264
3265 /*!
3266  * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it.
3267  */
3268 DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivity() const
3269 {
3270   const DataArrayInt *ret(_conn);
3271   return const_cast<DataArrayInt *>(ret);
3272 }
3273
3274 /*!
3275  * \return DataArrayInt * - the internal reference to the nodal connectivity index. The caller is not reponsible to deallocate it.
3276  */
3277 DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivityIndex() const
3278 {
3279   const DataArrayInt *ret(_conn_indx);
3280   return const_cast<DataArrayInt *>(ret);
3281 }
3282
3283 /*!
3284  * See the definition of the nodal connectivity pack \ref MEDCoupling1DGTUMesh::isPacked "here".
3285  * This method tries to build a new instance geometrically equivalent to \a this, by limiting at most the number of new object (nodal connectivity).
3286  * 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.
3287  *
3288  * 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.
3289  * 
3290  * \param [out] isShallowCpyOfNodalConnn - tells if the returned instance share the same pair of nodal connectivity arrays (true) or if nodal
3291  *              connectivity arrays are different (false)
3292  * \return a new object to be managed by the caller.
3293  * 
3294  * \sa MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity, MEDCoupling1DGTUMesh::isPacked
3295  */
3296 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::copyWithNodalConnectivityPacked(bool& isShallowCpyOfNodalConnn) const
3297 {
3298   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
3299   DataArrayInt *nc=0,*nci=0;
3300   isShallowCpyOfNodalConnn=retrievePackedNodalConnectivity(nc,nci);
3301   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ncs(nc),ncis(nci);
3302   ret->_conn=ncs; ret->_conn_indx=ncis;
3303   ret->setCoords(getCoords());
3304   return ret.retn();
3305 }
3306
3307 /*!
3308  * This method allows to compute, if needed, the packed nodal connectivity pair.
3309  * Indeed, it is possible to store in \a this a nodal connectivity array bigger than ranges convered by nodal connectivity index array.
3310  * 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.
3311  * 
3312  * 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)
3313  * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
3314  *
3315  * 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
3316  * will be returned.
3317  * 
3318  * This method return 3 elements.
3319  * \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
3320  *                          this pointer can be seen as a new object, that is to managed by the caller.
3321  * \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
3322  *                              this pointer can be seen as a new object, that is to managed by the caller.
3323  * \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
3324  * output parameters are newly created objects.
3325  *
3326  * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkCoherency test
3327  */
3328 bool MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity(DataArrayInt *&nodalConn, DataArrayInt *&nodalConnIndx) const
3329 {
3330   if(isPacked())//performs the checkCoherency
3331     {
3332       const DataArrayInt *c0(_conn),*c1(_conn_indx);
3333       nodalConn=const_cast<DataArrayInt *>(c0); nodalConnIndx=const_cast<DataArrayInt *>(c1);
3334       nodalConn->incrRef(); nodalConnIndx->incrRef();
3335       return true;
3336     }
3337   int bg=_conn_indx->front(),end=_conn_indx->back();
3338   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nc(_conn->selectByTupleId2(bg,end,1));
3339   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nci(_conn_indx->deepCpy());
3340   nci->applyLin(1,-bg);
3341   nodalConn=nc.retn(); nodalConnIndx=nci.retn();
3342   return false;
3343 }
3344
3345 /*
3346  * 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)
3347  * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
3348  * If nodal connectivity index points to a subpart of nodal connectivity index false will be returned.
3349  * \return bool - true if \a this looks packed, false is not.
3350  *
3351  * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkCoherency test
3352  */
3353 bool MEDCoupling1DGTUMesh::isPacked() const
3354 {
3355   checkCoherency();
3356   return _conn_indx->front()==0 && _conn_indx->back()==_conn->getNumberOfTuples();
3357 }
3358
3359 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(const MEDCoupling1DGTUMesh *mesh1, const MEDCoupling1DGTUMesh *mesh2)
3360 {
3361   std::vector<const MEDCoupling1DGTUMesh *> tmp(2);
3362   tmp[0]=const_cast<MEDCoupling1DGTUMesh *>(mesh1); tmp[1]=const_cast<MEDCoupling1DGTUMesh *>(mesh2);
3363   return Merge1DGTUMeshes(tmp);
3364 }
3365
3366 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(std::vector<const MEDCoupling1DGTUMesh *>& a)
3367 {
3368   std::size_t sz=a.size();
3369   if(sz==0)
3370     return Merge1DGTUMeshesLL(a);
3371   for(std::size_t ii=0;ii<sz;ii++)
3372     if(!a[ii])
3373       {
3374         std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::Merge1DGTUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !";
3375         throw INTERP_KERNEL::Exception(oss.str().c_str());
3376       }
3377   const INTERP_KERNEL::CellModel *cm=&(a[0]->getCellModel());
3378   for(std::size_t ii=0;ii<sz;ii++)
3379     if(&(a[ii]->getCellModel())!=cm)
3380       throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : all items must have the same geo type !");
3381   std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > bb(sz);
3382   std::vector< const MEDCoupling1DGTUMesh * > aa(sz);
3383   int spaceDim=-3;
3384   for(std::size_t i=0;i<sz && spaceDim==-3;i++)
3385     {
3386       const MEDCoupling1DGTUMesh *cur=a[i];
3387       const DataArrayDouble *coo=cur->getCoords();
3388       if(coo)
3389         spaceDim=coo->getNumberOfComponents();
3390     }
3391   if(spaceDim==-3)
3392     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : no spaceDim specified ! unable to perform merge !");
3393   for(std::size_t i=0;i<sz;i++)
3394     {
3395       bb[i]=a[i]->buildSetInstanceFromThis(spaceDim);
3396       aa[i]=bb[i];
3397     }
3398   return Merge1DGTUMeshesLL(aa);
3399 }
3400
3401 /*!
3402  * \throw If presence of a null instance in the input vector \a a.
3403  * \throw If a is empty
3404  */
3405 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords(std::vector<const MEDCoupling1DGTUMesh *>& a)
3406 {
3407   if(a.empty())
3408     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : input array must be NON EMPTY !");
3409   std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin();
3410   if(!(*it))
3411     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : null instance in the first element of input vector !");
3412   std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > objs(a.size());
3413   std::vector<const DataArrayInt *> ncs(a.size()),ncis(a.size());
3414   (*it)->getNumberOfCells();//to check that all is OK
3415   const DataArrayDouble *coords=(*it)->getCoords();
3416   const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
3417   bool tmp;
3418   objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp);
3419   ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex();
3420   it++;
3421   for(int i=1;it!=a.end();i++,it++)
3422     {
3423       if(!(*it))
3424         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : presence of null instance !");
3425       if(cm!=&((*it)->getCellModel()))
3426         throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !");
3427       (*it)->getNumberOfCells();//to check that all is OK
3428       objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp);
3429       ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex();
3430       if(coords!=(*it)->getCoords())
3431         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : not lying on same coords !");
3432     }
3433   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm));
3434   ret->setCoords(coords);
3435   ret->_conn=DataArrayInt::Aggregate(ncs);
3436   ret->_conn_indx=DataArrayInt::AggregateIndexes(ncis);
3437   return ret.retn();
3438 }
3439
3440 /*!
3441  * 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)
3442  */
3443 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesLL(std::vector<const MEDCoupling1DGTUMesh *>& a)
3444 {
3445   if(a.empty())
3446     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : input array must be NON EMPTY !");
3447   std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > objs(a.size());
3448   std::vector<const DataArrayInt *> ncs(a.size()),ncis(a.size());
3449   std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin();
3450   std::vector<int> nbNodesPerElt(a.size());
3451   int nbOfCells=(*it)->getNumberOfCells();
3452   bool tmp;
3453   objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp);
3454   ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex();
3455   nbNodesPerElt[0]=0;
3456   int prevNbOfNodes=(*it)->getNumberOfNodes();
3457   const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
3458   it++;
3459   for(int i=1;it!=a.end();i++,it++)
3460     {
3461       if(cm!=&((*it)->getCellModel()))
3462         throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !");
3463       objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp);
3464       ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex();
3465       nbOfCells+=(*it)->getNumberOfCells();
3466       nbNodesPerElt[i]=nbNodesPerElt[i-1]+prevNbOfNodes;
3467       prevNbOfNodes=(*it)->getNumberOfNodes();
3468     }
3469   std::vector<const MEDCouplingPointSet *> aps(a.size());
3470   std::copy(a.begin(),a.end(),aps.begin());
3471   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> pts=MergeNodesArray(aps);
3472   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm));
3473   ret->setCoords(pts);
3474   ret->_conn=AggregateNodalConnAndShiftNodeIds(ncs,nbNodesPerElt);
3475   ret->_conn_indx=DataArrayInt::AggregateIndexes(ncis);
3476   return ret.retn();
3477 }
3478
3479 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::buildSetInstanceFromThis(int spaceDim) const
3480 {
3481   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
3482   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1,tmp2;
3483   const DataArrayInt *nodalConn(_conn),*nodalConnI(_conn_indx);
3484   if(!nodalConn)
3485     {
3486       tmp1=DataArrayInt::New(); tmp1->alloc(0,1);
3487     }
3488   else
3489     tmp1=_conn;
3490   ret->_conn=tmp1;
3491   //
3492   if(!nodalConnI)
3493     {
3494       tmp2=DataArrayInt::New(); tmp2->alloc(1,1); tmp2->setIJ(0,0,0);
3495     }
3496   else
3497     tmp2=_conn_indx;
3498   ret->_conn_indx=tmp2;
3499   //
3500   if(!_coords)
3501     {
3502       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim);
3503       ret->setCoords(coords);
3504     }
3505   else
3506     ret->setCoords(_coords);
3507   return ret.retn();
3508 }
3509
3510 /*!
3511  * This method aggregate the bbox of each cell and put it into bbox parameter.
3512  * 
3513  * \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)
3514  *                         For all other cases this input parameter is ignored.
3515  * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components.
3516  * 
3517  * \throw If \a this is not fully set (coordinates and connectivity).
3518  * \throw If a cell in \a this has no valid nodeId.
3519  */
3520 DataArrayDouble *MEDCoupling1DGTUMesh::getBoundingBoxForBBTree(double arcDetEps) const
3521 {
3522   checkFullyDefined();
3523   int spaceDim(getSpaceDimension()),nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes());
3524   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim);
3525   double *bbox(ret->getPointer());
3526   for(int i=0;i<nbOfCells*spaceDim;i++)
3527     {
3528       bbox[2*i]=std::numeric_limits<double>::max();
3529       bbox[2*i+1]=-std::numeric_limits<double>::max();
3530     }
3531   const double *coordsPtr(_coords->getConstPointer());
3532   const int *conn(_conn->getConstPointer()),*connI(_conn_indx->getConstPointer());
3533   for(int i=0;i<nbOfCells;i++)
3534     {
3535       int offset=connI[i];
3536       int nbOfNodesForCell(connI[i+1]-offset),kk(0);
3537       for(int j=0;j<nbOfNodesForCell;j++)
3538         {
3539           int nodeId=conn[offset+j];
3540           if(nodeId>=0 && nodeId<nbOfNodes)
3541             {
3542               for(int k=0;k<spaceDim;k++)
3543                 {
3544                   bbox[2*spaceDim*i+2*k]=std::min(bbox[2*spaceDim*i+2*k],coordsPtr[spaceDim*nodeId+k]);
3545                   bbox[2*spaceDim*i+2*k+1]=std::max(bbox[2*spaceDim*i+2*k+1],coordsPtr[spaceDim*nodeId+k]);
3546                 }
3547               kk++;
3548             }
3549         }
3550       if(kk==0)
3551         {
3552           std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getBoundingBoxForBBTree : cell #" << i << " contains no valid nodeId !";
3553           throw INTERP_KERNEL::Exception(oss.str().c_str());
3554         }
3555     }
3556   return ret.retn();
3557 }
3558
3559 std::vector<int> MEDCoupling1DGTUMesh::BuildAPolygonFromParts(const std::vector< std::vector<int> >& parts)
3560 {
3561   std::vector<int> ret;
3562   if(parts.empty())
3563     return ret;
3564   ret.insert(ret.end(),parts[0].begin(),parts[0].end());
3565   int ref(ret.back());
3566   std::size_t sz(parts.size()),nbh(1);
3567   std::vector<bool> b(sz,true); b[0]=false;
3568   while(nbh<sz)
3569     {
3570       std::size_t i(0);
3571       for(;i<sz;i++) if(b[i] && parts[i].front()==ref) { ret.insert(ret.end(),parts[i].begin()+1,parts[i].end()); nbh++; break; }
3572       if(i<sz)
3573         ref=ret.back();
3574       else
3575         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::BuildAPolygonFromParts : the input vector is not a part of a single polygon !");
3576     }
3577   if(ret.back()==ret.front())
3578     ret.pop_back();
3579   return ret;
3580 }
3581
3582 /*!
3583  * This method performs an aggregation of \a nodalConns (as DataArrayInt::Aggregate does) but in addition of that a shift is applied on the 
3584  * values contained in \a nodalConns using corresponding offset specified in input \a offsetInNodeIdsPerElt.
3585  * But it also manage the values -1, that have a semantic in MEDCoupling1DGTUMesh class (separator for polyhedron).
3586  *
3587  * \param [in] nodalConns - a list of nodal connectivity arrays same size than \a offsetInNodeIdsPerElt.
3588  * \param [in] offsetInNodeIdsPerElt - a list of offsets to apply.
3589  * \return DataArrayInt * - A new object (to be managed by the caller) that is the result of the aggregation.
3590  * \throw If \a nodalConns or \a offsetInNodeIdsPerElt are empty.
3591  * \throw If \a nodalConns and \a offsetInNodeIdsPerElt have not the same size.
3592  * \throw If presence of null pointer in \a nodalConns.
3593  * \throw If presence of not allocated or array with not exactly one component in \a nodalConns.
3594  */
3595 DataArrayInt *MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds(const std::vector<const DataArrayInt *>& nodalConns, const std::vector<int>& offsetInNodeIdsPerElt)
3596 {
3597   std::size_t sz1(nodalConns.size()),sz2(offsetInNodeIdsPerElt.size());
3598   if(sz1!=sz2)
3599     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : input vectors do not have the same size !");
3600   if(sz1==0)
3601     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : empty vectors in input !");
3602   int nbOfTuples=0;
3603   for(std::vector<const DataArrayInt *>::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++)
3604     {
3605       if(!(*it))
3606         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of null pointer in input vector !");
3607       if(!(*it)->isAllocated())
3608         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of non allocated array in input vector !");
3609       if((*it)->getNumberOfComponents()!=1)
3610         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of array with not exactly one component !");
3611       nbOfTuples+=(*it)->getNumberOfTuples();
3612     }
3613   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
3614   int *pt=ret->getPointer();
3615   int i=0;
3616   for(std::vector<const DataArrayInt *>::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++,i++)
3617     {
3618       int curNbt=(*it)->getNumberOfTuples();
3619       const int *inPt=(*it)->begin();
3620       int offset=offsetInNodeIdsPerElt[i];
3621       for(int j=0;j<curNbt;j++,pt++)
3622         {
3623           if(inPt[j]!=-1)
3624             *pt=inPt[j]+offset;
3625           else
3626             *pt=-1;
3627         }
3628     }
3629   return ret.retn();
3630 }
3631
3632 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const MEDCouplingUMesh *m)
3633 {
3634   if(!m)
3635     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : input mesh is null !");
3636   std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes());
3637   if(gts.size()!=1)
3638     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : input mesh must have exactly one geometric type !");
3639   int geoType((int)*gts.begin());
3640   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(m->getName(),*gts.begin()));
3641   ret->setCoords(m->getCoords()); ret->setDescription(m->getDescription());
3642   int nbCells(m->getNumberOfCells());
3643   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()),connI(DataArrayInt::New());
3644   conn->alloc(m->getMeshLength()-nbCells,1); connI->alloc(nbCells+1,1);
3645   int *c(conn->getPointer()),*ci(connI->getPointer()); *ci=0;
3646   const int *cin(m->getNodalConnectivity()->begin()),*ciin(m->getNodalConnectivityIndex()->begin());
3647   for(int i=0;i<nbCells;i++,ciin++,ci++)
3648     {
3649       if(cin[ciin[0]]==geoType)
3650         {
3651           if(ciin[1]-ciin[0]>=1)
3652             {
3653               c=std::copy(cin+ciin[0]+1,cin+ciin[1],c);
3654               ci[1]=ci[0]+ciin[1]-ciin[0]-1;
3655             }
3656           else
3657             {
3658               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 !";
3659               throw INTERP_KERNEL::Exception(oss.str().c_str());
3660             }
3661         }
3662       else
3663         {
3664           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 !";
3665           throw INTERP_KERNEL::Exception(oss.str().c_str());
3666         }
3667     }
3668   ret->setNodalConnectivity(conn,connI);
3669   return ret.retn();
3670 }