Salome HOME
nearly ready for the single geo type in MEDLoader
[tools/medcoupling.git] / src / MEDCoupling / MEDCoupling1GTUMesh.cxx
1 // Copyright (C) 2007-2013  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 // Author : Anthony Geay (CEA/DEN)
20
21 #include "MEDCoupling1GTUMesh.hxx"
22 #include "MEDCouplingUMesh.hxx"
23 #include "MEDCouplingFieldDouble.hxx"
24
25 #include "SplitterTetra.hxx"
26
27 using namespace ParaMEDMEM;
28
29 MEDCoupling1GTUMesh::MEDCoupling1GTUMesh(const char *name, const INTERP_KERNEL::CellModel& cm):_cm(&cm)
30 {
31   setName(name);
32 }
33
34 MEDCoupling1GTUMesh::MEDCoupling1GTUMesh(const MEDCoupling1GTUMesh& other, bool recDeepCpy):MEDCouplingPointSet(other,recDeepCpy),_cm(other._cm)
35 {
36 }
37
38 MEDCoupling1GTUMesh *MEDCoupling1GTUMesh::New(const char *name, INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception)
39 {
40   if(type==INTERP_KERNEL::NORM_ERROR)
41     throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
42   const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
43   if(!cm.isDynamic())
44     return MEDCoupling1SGTUMesh::New(name,type);
45   else
46     return MEDCoupling1DGTUMesh::New(name,type);
47 }
48
49 const INTERP_KERNEL::CellModel& MEDCoupling1GTUMesh::getCellModel() const throw(INTERP_KERNEL::Exception)
50 {
51   return *_cm;
52 }
53
54 INTERP_KERNEL::NormalizedCellType MEDCoupling1GTUMesh::getCellModelEnum() const throw(INTERP_KERNEL::Exception)
55 {
56   return _cm->getEnum();
57 }
58
59 int MEDCoupling1GTUMesh::getMeshDimension() const
60 {
61   return (int)_cm->getDimension();
62 }
63
64 /*!
65  * This method returns a newly allocated array containing cell ids (ascendingly sorted) whose geometric type are equal to type.
66  * This method does not throw exception if geometric type \a type is not in \a this.
67  * This method throws an INTERP_KERNEL::Exception if meshdimension of \b this is not equal to those of \b type.
68  * The coordinates array is not considered here.
69  *
70  * \param [in] type the geometric type
71  * \return cell ids in this having geometric type \a type.
72  */
73 DataArrayInt *MEDCoupling1GTUMesh::giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception)
74 {
75   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
76   if(type==getCellModelEnum())
77     ret->alloc(getNumberOfCells(),1);
78   else
79     ret->alloc(0,1);
80   ret->iota();
81   return ret.retn();
82 }
83
84 /*!
85  * Returns nb of cells having the geometric type \a type. No throw if no cells in \a this has the geometric type \a type.
86  */
87 int MEDCoupling1GTUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const
88 {
89   return type==getCellModelEnum()?getNumberOfCells():0;
90 }
91
92 /*!
93  * Returns a type of a cell by its id.
94  *  \param [in] cellId - the id of the cell of interest.
95  *  \return INTERP_KERNEL::NormalizedCellType - enumeration item describing the cell type.
96  *  \throw If \a cellId is invalid. Valid range is [0, \a this->getNumberOfCells() ).
97  */
98 INTERP_KERNEL::NormalizedCellType MEDCoupling1GTUMesh::getTypeOfCell(int cellId) const
99 {
100   if(cellId>=0 && cellId<getNumberOfCells())
101     return getCellModelEnum();
102   std::ostringstream oss; oss << "MEDCoupling1GTUMesh::getTypeOfCell : Requesting type of cell #" << cellId << " but it should be in [0," << getNumberOfCells() << ") !";
103   throw INTERP_KERNEL::Exception(oss.str().c_str());
104 }
105
106 /*!
107  * Returns a set of all cell types available in \a this mesh.
108  * \return std::set<INTERP_KERNEL::NormalizedCellType> - the set of cell types.
109  * \warning this method does not throw any exception even if \a this is not defined.
110  */
111 std::set<INTERP_KERNEL::NormalizedCellType> MEDCoupling1GTUMesh::getAllGeoTypes() const
112 {
113   std::set<INTERP_KERNEL::NormalizedCellType> ret;
114   ret.insert(getCellModelEnum());
115   return ret;
116 }
117
118 /*!
119  * This method expects that \a this is sorted by types. If not an exception will be thrown.
120  * This method returns in the same format as code (see MEDCouplingUMesh::checkTypeConsistencyAndContig or MEDCouplingUMesh::splitProfilePerType) how
121  * \a this is composed in cell types.
122  * The returned array is of size 3*n where n is the number of different types present in \a this. 
123  * For every k in [0,n] ret[3*k+2]==0 because it has no sense here. 
124  * This parameter is kept only for compatibility with other methode listed above.
125  */
126 std::vector<int> MEDCoupling1GTUMesh::getDistributionOfTypes() const throw(INTERP_KERNEL::Exception)
127 {
128   std::vector<int> ret(3);
129   ret[0]=(int)getCellModelEnum(); ret[1]=getNumberOfCells(); ret[2]=0;
130   return ret;
131 }
132
133 /*!
134  * 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.
135  * 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.
136  * This method has 1 input \a profile and 3 outputs \a code \a idsInPflPerType and \a idsPerType.
137  * 
138  * \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.
139  * \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,
140  *              \a idsInPflPerType[i] stores the tuple ids in \a profile that correspond to the geometric type code[3*i+0]
141  * \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.
142  *              This vector can be empty in case of all geometric type cells are fully covered in ascending in the given input \a profile.
143  * 
144  * \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.
145  *
146  * \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
147  *
148  *  \b Example1: <br>
149  *          - Before \a this has 3 cells \a profile contains [0,1,2]
150  *          - After \a code contains [NORM_...,nbCells,-1], \a idsInPflPerType [[0,1,2]] and \a idsPerType is empty <br>
151  * 
152  *  \b Example2: <br>
153  *          - Before \a this has 3 cells \a profile contains [1,2]
154  *          - After \a code contains [NORM_...,nbCells,0], \a idsInPflPerType [[0,1]] and \a idsPerType is [[1,2]] <br>
155
156  */
157 void MEDCoupling1GTUMesh::splitProfilePerType(const DataArrayInt *profile, std::vector<int>& code, std::vector<DataArrayInt *>& idsInPflPerType, std::vector<DataArrayInt *>& idsPerType) const throw(INTERP_KERNEL::Exception)
158 {
159   if(!profile)
160     throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::splitProfilePerType : input profile is NULL !");
161   if(profile->getNumberOfComponents()!=1)
162     throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::splitProfilePerType : input profile should have exactly one component !");
163   int nbTuples=profile->getNumberOfTuples();
164   int nbOfCells=getNumberOfCells();
165   code.resize(3); idsInPflPerType.resize(1);
166   code[0]=(int)getCellModelEnum(); code[1]=nbTuples;
167   idsInPflPerType.resize(1);
168   if(profile->isIdentity() && nbTuples==nbOfCells)
169     {
170       code[2]=-1;
171       idsInPflPerType[0]=const_cast<DataArrayInt *>(profile); idsInPflPerType[0]->incrRef();
172       idsPerType.clear();
173       return ;
174     }
175   code[2]=0;
176   profile->checkAllIdsInRange(0,nbOfCells);
177   idsPerType.resize(1);
178   idsPerType[0]=const_cast<DataArrayInt *>(profile); idsPerType[0]->incrRef();
179   idsInPflPerType[0]=DataArrayInt::Range(0,nbTuples,1);
180 }
181
182 /*!
183  * This method tries to minimize at most the number of deep copy.
184  * So if \a idsPerType is not empty it can be returned directly (without copy, but with ref count incremented) in return.
185  * 
186  * \sa MEDCouplingUMesh::checkTypeConsistencyAndContig
187  */
188 DataArrayInt *MEDCoupling1GTUMesh::checkTypeConsistencyAndContig(const std::vector<int>& code, const std::vector<const DataArrayInt *>& idsPerType) const throw(INTERP_KERNEL::Exception)
189 {
190   int nbOfCells=getNumberOfCells();
191   if(code.size()!=3)
192     throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : invalid input code should be exactly of size 3 !");
193   if(code[0]!=(int)getCellModelEnum())
194     {
195       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() << ") !";
196       throw INTERP_KERNEL::Exception(oss.str().c_str());
197     }
198   if(code[2]==-1)
199     {
200       if(code[1]==nbOfCells)
201         return 0;
202       else
203         {
204           std::ostringstream oss; oss << "MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : mismatch between the number of cells in this (" << nbOfCells << ") and the number of non profile (" << code[1] << ") !";
205           throw INTERP_KERNEL::Exception(oss.str().c_str());
206         }
207     }
208   if(code[2]!=0)
209     throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : single geo type mesh ! 0 or -1 is expected at pos #2 of input code !");
210   if(idsPerType.size()!=1)
211     throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : input code points to DataArrayInt #0 whereas the size of idsPerType is not equal to 1 !");
212   const DataArrayInt *pfl=idsPerType[0];
213   if(!pfl)
214     throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : the input code points to a NULL DataArrayInt at rank 0 !");
215   if(pfl->getNumberOfComponents()!=1)
216     throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : input profile should have exactly one component !");
217   pfl->checkAllIdsInRange(0,nbOfCells);
218   pfl->incrRef();
219   return const_cast<DataArrayInt *>(pfl);
220 }
221
222 void MEDCoupling1GTUMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData) const throw(INTERP_KERNEL::Exception)
223 {
224   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
225   m->writeVTKLL(ofs,cellData,pointData);
226 }
227
228 std::string MEDCoupling1GTUMesh::getVTKDataSetType() const throw(INTERP_KERNEL::Exception)
229 {
230   return std::string("UnstructuredGrid");
231 }
232
233 std::size_t MEDCoupling1GTUMesh::getHeapMemorySize() const
234 {
235   return MEDCouplingPointSet::getHeapMemorySize();
236 }
237
238 bool MEDCoupling1GTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception)
239 {
240   if(!MEDCouplingPointSet::isEqualIfNotWhy(other,prec,reason))
241     return false;
242   if(!other)
243     throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::isEqualIfNotWhy : input other pointer is null !");
244   const MEDCoupling1GTUMesh *otherC=dynamic_cast<const MEDCoupling1GTUMesh *>(other);
245   if(!otherC)
246     {
247       reason="mesh given in input is not castable in MEDCouplingSGTUMesh !";
248       return false;
249     }
250   if(_cm!=otherC->_cm)
251     {
252       reason="mismatch in geometric type !";
253       return false;
254     }
255   return true;
256 }
257
258 bool MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
259 {
260   if(!MEDCouplingPointSet::isEqualWithoutConsideringStr(other,prec))
261     return false;
262   if(!other)
263     throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
264   const MEDCoupling1GTUMesh *otherC=dynamic_cast<const MEDCoupling1GTUMesh *>(other);
265   if(!otherC)
266     return false;
267   if(_cm!=otherC->_cm)
268     return false;
269   return true;
270 }
271
272 void MEDCoupling1GTUMesh::checkCoherency() const throw(INTERP_KERNEL::Exception)
273 {
274   MEDCouplingPointSet::checkCoherency();
275 }
276
277 DataArrayDouble *MEDCoupling1GTUMesh::getBarycenterAndOwner() const
278 {
279   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
280   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=m->getBarycenterAndOwner();
281   return ret.retn();
282 }
283
284 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::getMeasureField(bool isAbs) const
285 {
286   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
287   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=m->getMeasureField(isAbs);
288   ret->setMesh(this);
289   return ret.retn();
290 }
291
292 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::getMeasureFieldOnNode(bool isAbs) const
293 {
294   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
295   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=m->getMeasureFieldOnNode(isAbs);
296   ret->setMesh(this);
297   return ret.retn();
298 }
299
300 /*!
301  * to improve perf !
302  */
303 int MEDCoupling1GTUMesh::getCellContainingPoint(const double *pos, double eps) const
304 {
305   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
306   return m->getCellContainingPoint(pos,eps);
307 }
308
309 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::buildOrthogonalField() const
310 {
311   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
312   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=m->buildOrthogonalField();
313   ret->setMesh(this);
314   return ret.retn();
315 }
316
317 DataArrayInt *MEDCoupling1GTUMesh::getCellsInBoundingBox(const double *bbox, double eps) const
318 {
319   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
320   return m->getCellsInBoundingBox(bbox,eps);
321 }
322
323 DataArrayInt *MEDCoupling1GTUMesh::getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps)
324 {
325   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
326   return m->getCellsInBoundingBox(bbox,eps);
327 }
328
329 MEDCouplingPointSet *MEDCoupling1GTUMesh::buildFacePartOfMySelfNode(const int *start, const int *end, bool fullyIn) const
330 {
331   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
332   return m->buildFacePartOfMySelfNode(start,end,fullyIn);
333 }
334
335 DataArrayInt *MEDCoupling1GTUMesh::findBoundaryNodes() const
336 {
337   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
338   return m->findBoundaryNodes();
339 }
340
341 MEDCouplingPointSet *MEDCoupling1GTUMesh::buildBoundaryMesh(bool keepCoords) const
342 {
343   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
344   return m->buildBoundaryMesh(keepCoords);
345 }
346
347 void MEDCoupling1GTUMesh::findCommonCells(int compType, int startCellId, DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr) const throw(INTERP_KERNEL::Exception)
348 {
349   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
350   m->findCommonCells(compType,startCellId,commonCellsArr,commonCellsIArr);
351 }
352
353 //==
354
355 MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh(const MEDCoupling1SGTUMesh& other, bool recDeepCpy):MEDCoupling1GTUMesh(other,recDeepCpy),_conn(other._conn)
356 {
357   if(recDeepCpy)
358     {
359       const DataArrayInt *c(other._conn);
360       if(c)
361         _conn=c->deepCpy();
362     }
363 }
364
365 MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh(const char *name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm)
366 {
367 }
368
369 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New(const char *name, INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception)
370 {
371   if(type==INTERP_KERNEL::NORM_ERROR)
372     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
373   const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
374   if(cm.isDynamic())
375     {
376       std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::New : the input geometric type " << cm.getRepr() << " is dynamic ! Only static types are allowed here !";
377       throw INTERP_KERNEL::Exception(oss.str().c_str());
378     }
379   return new MEDCoupling1SGTUMesh(name,cm);
380 }
381
382 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::clone(bool recDeepCpy) const
383 {
384   return new MEDCoupling1SGTUMesh(*this,recDeepCpy);
385 }
386
387 void MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other) throw(INTERP_KERNEL::Exception)
388 {
389   if(!other)
390     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom : input pointer is null !");
391   const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
392   if(!otherC)
393     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1SGTUMesh instance !");
394   setNodalConnectivity(otherC->getNodalConnectivity());
395 }
396
397 void MEDCoupling1SGTUMesh::updateTime() const
398 {
399   MEDCoupling1GTUMesh::updateTime();
400   const DataArrayInt *c(_conn);
401   if(c)
402     updateTimeWith(*c);
403 }
404
405 std::size_t MEDCoupling1SGTUMesh::getHeapMemorySize() const
406 {
407   std::size_t ret=0;
408   const DataArrayInt *c(_conn);
409   if(c)
410     ret+=c->getHeapMemorySize();
411   return MEDCoupling1GTUMesh::getHeapMemorySize()+ret;
412 }
413
414 MEDCouplingMesh *MEDCoupling1SGTUMesh::deepCpy() const
415 {
416   return clone(true);
417 }
418
419 bool MEDCoupling1SGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception)
420 {
421   if(!other)
422     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEqualIfNotWhy : input other pointer is null !");
423   std::ostringstream oss; oss.precision(15);
424   const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
425   if(!otherC)
426     {
427       reason="mesh given in input is not castable in MEDCoupling1SGTUMesh !";
428       return false;
429     }
430   if(!MEDCoupling1GTUMesh::isEqualIfNotWhy(other,prec,reason))
431     return false;
432   const DataArrayInt *c1(_conn),*c2(otherC->_conn);
433   if(c1==c2)
434     return true;
435   if(!c1 || !c2)
436     {
437       reason="in connectivity of single static geometric type exactly one among this and other is null !";
438       return false;
439     }
440   if(!c1->isEqualIfNotWhy(*c2,reason))
441     {
442       reason.insert(0,"Nodal connectivity DataArrayInt differ : ");
443       return false;
444     }
445   return true;
446 }
447
448 bool MEDCoupling1SGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
449 {
450   if(!other)
451     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
452   const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
453   if(!otherC)
454     return false;
455   if(!MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(other,prec))
456     return false;
457   const DataArrayInt *c1(_conn),*c2(otherC->_conn);
458   if(c1==c2)
459     return true;
460   if(!c1 || !c2)
461     return false;
462   if(!c1->isEqualWithoutConsideringStr(*c2))
463     return false;
464   return true;
465 }
466
467 void MEDCoupling1SGTUMesh::checkCoherency() const throw(INTERP_KERNEL::Exception)
468 {
469   MEDCouplingPointSet::checkCoherency();
470   const DataArrayInt *c1(_conn);
471   if(c1)
472     {
473       if(c1->getNumberOfComponents()!=1)
474         throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !");
475       if(c1->getInfoOnComponent(0)!="")
476         throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !");
477       c1->checkAllocated();
478     }
479   else
480     throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !");
481 }
482
483 void MEDCoupling1SGTUMesh::checkCoherency1(double eps) const throw(INTERP_KERNEL::Exception)
484 {
485   checkCoherency();
486   const DataArrayInt *c1(_conn);
487   int nbOfTuples=c1->getNumberOfTuples();
488   int nbOfNodesPerCell=(int)_cm->getNumberOfNodes();
489   if(nbOfTuples%nbOfNodesPerCell!=0)
490     {
491       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 !";
492       throw INTERP_KERNEL::Exception(oss.str().c_str());
493     }
494   int nbOfNodes=getNumberOfNodes();
495   int nbOfCells=nbOfTuples/nbOfNodesPerCell;
496   const int *w(c1->begin());
497   for(int i=0;i<nbOfCells;i++)
498     for(int j=0;j<nbOfNodesPerCell;j++,w++)
499       {
500         if(*w<0 || *w>=nbOfNodes)
501           {
502             std::ostringstream oss; oss << "At node #" << j << " of  cell #" << i << ", is equal to " << *w << " must be in [0," << nbOfNodes << ") !";
503             throw INTERP_KERNEL::Exception(oss.str().c_str());
504           }
505       }
506 }
507
508 void MEDCoupling1SGTUMesh::checkCoherency2(double eps) const throw(INTERP_KERNEL::Exception)
509 {
510   checkCoherency1(eps);
511 }
512
513 int MEDCoupling1SGTUMesh::getNumberOfCells() const
514 {
515   int nbOfTuples=getNodalConnectivityLength();
516   int nbOfNodesPerCell=getNumberOfNodesPerCell();
517   if(nbOfTuples%nbOfNodesPerCell!=0)
518     {
519       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 !";
520       throw INTERP_KERNEL::Exception(oss.str().c_str());
521     }
522   return nbOfTuples/nbOfNodesPerCell;
523 }
524
525 int MEDCoupling1SGTUMesh::getNumberOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
526 {
527   checkNonDynamicGeoType();
528   return (int)_cm->getNumberOfNodes();
529 }
530
531 int MEDCoupling1SGTUMesh::getNodalConnectivityLength() const throw(INTERP_KERNEL::Exception)
532 {
533   const DataArrayInt *c1(_conn);
534   if(!c1)
535     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::getNodalConnectivityLength : no connectivity set !");
536   if(c1->getNumberOfComponents()!=1)
537     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::getNodalConnectivityLength : Nodal connectivity array set must have exactly one component !");
538   if(!c1->isAllocated())
539     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::getNodalConnectivityLength : Nodal connectivity array must be allocated !");
540   return c1->getNumberOfTuples();
541 }
542
543 DataArrayInt *MEDCoupling1SGTUMesh::computeNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
544 {
545   checkNonDynamicGeoType();
546   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
547   ret->alloc(getNumberOfCells(),1);
548   ret->fillWithValue((int)_cm->getNumberOfNodes());
549   return ret.retn();
550 }
551
552 DataArrayInt *MEDCoupling1SGTUMesh::computeNbOfFacesPerCell() const throw(INTERP_KERNEL::Exception)
553 {
554   checkNonDynamicGeoType();
555   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
556   ret->alloc(getNumberOfCells(),1);
557   ret->fillWithValue((int)_cm->getNumberOfSons());
558   return ret.retn();
559 }
560
561 void MEDCoupling1SGTUMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
562 {
563   int sz=getNumberOfNodesPerCell();
564   conn.resize(sz);
565   if(cellId>=0 && cellId<getNumberOfCells())
566     std::copy(_conn->begin()+cellId*sz,_conn->begin()+(cellId+1)*sz,conn.begin());
567   else
568     {
569       std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << getNumberOfCells() << ") !";
570       throw INTERP_KERNEL::Exception(oss.str().c_str());
571     }
572 }
573
574 void MEDCoupling1SGTUMesh::checkNonDynamicGeoType() const throw(INTERP_KERNEL::Exception)
575 {
576   if(_cm->isDynamic())
577     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkNonDynamicGeoType : internal error ! the internal geo type is dynamic ! should be static !");
578 }
579
580 std::string MEDCoupling1SGTUMesh::simpleRepr() const
581 {
582   static const char msg0[]="No coordinates specified !";
583   std::ostringstream ret;
584   ret << "Single static geometic type (" << _cm->getRepr() << ") unstructured mesh with name : \"" << getName() << "\"\n";
585   ret << "Description of mesh : \"" << getDescription() << "\"\n";
586   int tmpp1,tmpp2;
587   double tt=getTime(tmpp1,tmpp2);
588   ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
589   ret << "Iteration : " << tmpp1  << " Order : " << tmpp2 << "\n";
590   ret << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : ";
591   if(_coords!=0)
592     {
593       const int spaceDim=getSpaceDimension();
594       ret << spaceDim << "\nInfo attached on space dimension : ";
595       for(int i=0;i<spaceDim;i++)
596         ret << "\"" << _coords->getInfoOnComponent(i) << "\" ";
597       ret << "\n";
598     }
599   else
600     ret << msg0 << "\n";
601   ret << "Number of nodes : ";
602   if(_coords!=0)
603     ret << getNumberOfNodes() << "\n";
604   else
605     ret << msg0 << "\n";
606   ret << "Number of cells : ";
607   if((const DataArrayInt *)_conn)
608     {
609       if(_conn->isAllocated())
610         {
611           if(_conn->getNumberOfComponents()==1)
612             ret << getNumberOfCells() << "\n";
613           else
614             ret << "Nodal connectivity array specified and allocated but with not exactly one component !" << "\n";
615         }
616       else
617         ret << "Nodal connectivity array specified but not allocated !" << "\n";
618     }
619   else
620     ret << "No connectivity specified !" << "\n";
621   ret << "Cell type : " << _cm->getRepr() << "\n";
622   return ret.str();
623 }
624
625 std::string MEDCoupling1SGTUMesh::advancedRepr() const
626 {
627   std::ostringstream ret;
628   ret << simpleRepr();
629   ret << "\nCoordinates array : \n___________________\n\n";
630   if(_coords)
631     _coords->reprWithoutNameStream(ret);
632   else
633     ret << "No array set !\n";
634   ret << "\n\nConnectivity array : \n____________________\n\n";
635   //
636   if((const DataArrayInt *)_conn)
637     {
638       if(_conn->isAllocated())
639         {
640           if(_conn->getNumberOfComponents()==1)
641             {
642              int nbOfCells=getNumberOfCells();
643              int sz=getNumberOfNodesPerCell();
644              const int *connPtr=_conn->begin();
645              for(int i=0;i<nbOfCells;i++,connPtr+=sz)
646                {
647                  ret << "Cell #" << i << " : ";
648                  std::copy(connPtr,connPtr+sz,std::ostream_iterator<int>(ret," "));
649                  ret << "\n";
650                }
651             }
652           else
653             ret << "Nodal connectivity array specified and allocated but with not exactly one component !" << "\n";
654         }
655       else
656         ret << "Nodal connectivity array specified but not allocated !" << "\n";
657     }
658   else
659     ret << "No connectivity specified !" << "\n";
660   return ret.str();
661 }
662
663 DataArrayDouble *MEDCoupling1SGTUMesh::computeIsoBarycenterOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
664 {
665   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
666   int spaceDim=getSpaceDimension();
667   int nbOfCells=getNumberOfCells();//checkCoherency()
668   int nbOfNodes=getNumberOfNodes();
669   ret->alloc(nbOfCells,spaceDim);
670   double *ptToFill=ret->getPointer();
671   const double *coor=_coords->begin();
672   const int *nodal=_conn->begin();
673   int sz=getNumberOfNodesPerCell();
674   double coeff=1./(double)sz;
675   for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim)
676     {
677       std::fill(ptToFill,ptToFill+spaceDim,0.);
678       for(int j=0;j<sz;j++,nodal++)
679         if(*nodal>=0 && *nodal<nbOfNodes)
680           std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
681         else
682           {
683             std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," <<   nbOfNodes << ") !";
684             throw INTERP_KERNEL::Exception(oss.str().c_str());
685           }
686       std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),coeff));
687     }
688   return ret.retn();
689 }
690
691 void MEDCoupling1SGTUMesh::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception)
692 {
693   int nbCells=getNumberOfCells();
694   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::New();
695   o2n->useArray(old2NewBg,false,C_DEALLOC,nbCells,1);
696   if(check)
697     o2n=o2n->checkAndPreparePermutation();
698   //
699   const int *conn=_conn->begin();
700   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> n2o=o2n->invertArrayO2N2N2O(nbCells);
701   const int *n2oPtr=n2o->begin();
702   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New();
703   newConn->alloc(_conn->getNumberOfTuples(),1);
704   newConn->copyStringInfoFrom(*_conn);
705   int sz=getNumberOfNodesPerCell();
706   //
707   int *newC=newConn->getPointer();
708   for(int i=0;i<nbCells;i++,newC+=sz)
709     {
710       int pos=n2oPtr[i];
711       std::copy(conn+pos*sz,conn+(pos+1)*sz,newC);
712     }
713   _conn=newConn;
714 }
715
716 /*!
717  * Keeps from \a this only cells which constituing point id are in the ids specified by [\a begin,\a end).
718  * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
719  * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not.
720  * If \a fullyIn is true only cells whose ids are \b fully contained in [\a begin,\a end) tab will be kept.
721  *
722  * \param [in] begin input start of array of node ids.
723  * \param [in] end input end of array of node ids.
724  * \param [in] fullyIn input that specifies if all node ids must be in [\a begin,\a end) array to consider cell to be in.
725  * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end.
726  */
727 void MEDCoupling1SGTUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const
728 {
729   int nbOfCells=getNumberOfCells();
730   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1);
731   int tmp=-1;
732   int sz=_conn->getMaxValue(tmp); sz=std::max(sz,0)+1;
733   std::vector<bool> fastFinder(sz,false);
734   for(const int *work=begin;work!=end;work++)
735     if(*work>=0 && *work<sz)
736       fastFinder[*work]=true;
737   const int *conn=_conn->begin();
738   int nbNodesPerCell=getNumberOfNodesPerCell();
739   for(int i=0;i<nbOfCells;i++,conn+=nbNodesPerCell)
740     {
741       int ref=0,nbOfHit=0;
742       for(int j=0;j<nbNodesPerCell;j++)
743         if(conn[j]>=0)
744           {
745             ref++;
746             if(fastFinder[conn[j]])
747               nbOfHit++;
748           }
749       if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn))
750         cellIdsKept->pushBackSilent(i);
751     }
752   cellIdsKeptArr=cellIdsKept.retn();
753 }
754
755 MEDCouplingMesh *MEDCoupling1SGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
756 {
757   if(other->getType()!=SINGLE_STATIC_GEO_TYPE_UNSTRUCTURED)
758     throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single static geo type each other !");
759   const MEDCoupling1SGTUMesh *otherC=static_cast<const MEDCoupling1SGTUMesh *>(other);
760   return Merge1SGTUMeshes(this,otherC);
761 }
762
763 MEDCouplingUMesh *MEDCoupling1SGTUMesh::buildUnstructured() const throw(INTERP_KERNEL::Exception)
764 {
765   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName(),getMeshDimension());
766   ret->setCoords(getCoords());
767   const int *nodalConn=_conn->begin();
768   int nbCells=getNumberOfCells();
769   int nbNodesPerCell=getNumberOfNodesPerCell();
770   int geoType=(int)getCellModelEnum();
771   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New(); c->alloc(nbCells*(nbNodesPerCell+1),1);
772   int *cPtr=c->getPointer();
773   for(int i=0;i<nbCells;i++,nodalConn+=nbNodesPerCell)
774     {
775       *cPtr++=geoType;
776       cPtr=std::copy(nodalConn,nodalConn+nbNodesPerCell,cPtr);
777     }
778   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cI=DataArrayInt::Range(0,(nbCells+1)*(nbNodesPerCell+1),nbNodesPerCell+1);
779   ret->setConnectivity(c,cI,true);
780   return ret.retn();
781 }
782
783 DataArrayInt *MEDCoupling1SGTUMesh::simplexize(int policy) throw(INTERP_KERNEL::Exception)
784 {
785   switch(policy)
786     {
787     case 0:
788       return simplexizePol0();
789     case 1:
790       return simplexizePol1();
791     case (int) INTERP_KERNEL::PLANAR_FACE_5:
792       return simplexizePlanarFace5();
793     case (int) INTERP_KERNEL::PLANAR_FACE_6:
794       return simplexizePlanarFace6();
795     default:
796       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)");
797     }
798 }
799
800 /// @cond INTERNAL
801
802 struct MEDCouplingAccVisit
803 {
804   MEDCouplingAccVisit():_new_nb_of_nodes(0) { }
805   int operator()(int val) { if(val!=-1) return _new_nb_of_nodes++; else return -1; }
806   int _new_nb_of_nodes;
807 };
808
809 /// @endcond
810
811 /*!
812  * Finds nodes not used in any cell and returns an array giving a new id to every node
813  * by excluding the unused nodes, for which the array holds -1. The result array is
814  * a mapping in "Old to New" mode. 
815  *  \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
816  *  \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a
817  *          this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
818  *          if the node is unused or a new id else. The caller is to delete this
819  *          array using decrRef() as it is no more needed.  
820  *  \throw If the coordinates array is not set.
821  *  \throw If the nodal connectivity of cells is not defined.
822  *  \throw If the nodal connectivity includes an invalid id.
823  */
824 DataArrayInt *MEDCoupling1SGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const throw(INTERP_KERNEL::Exception)
825 {
826   nbrOfNodesInUse=-1;
827   int nbOfNodes=getNumberOfNodes();
828   int nbOfCells=getNumberOfCells();
829   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
830   ret->alloc(nbOfNodes,1);
831   int *traducer=ret->getPointer();
832   std::fill(traducer,traducer+nbOfNodes,-1);
833   const int *conn=_conn->begin();
834   int nbNodesPerCell=getNumberOfNodesPerCell();
835   for(int i=0;i<nbOfCells;i++)
836     for(int j=0;j<nbNodesPerCell;j++,conn++)
837       if(*conn>=0 && *conn<nbOfNodes)
838         traducer[*conn]=1;
839       else
840         {
841           std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsInUse : In cell #" << i  << " presence of node id " <<  conn[j] << " not in [0," << nbOfNodes << ") !";
842           throw INTERP_KERNEL::Exception(oss.str().c_str());
843         }
844   nbrOfNodesInUse=(int)std::count(traducer,traducer+nbOfNodes,1);
845   std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
846   return ret.retn();
847 }
848
849 /*!
850  * Changes ids of nodes within the nodal connectivity arrays according to a permutation
851  * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
852  * This method is a generalization of shiftNodeNumbersInConn().
853  *  \warning This method performs no check of validity of new ids. **Use it with care !**
854  *  \param [in] newNodeNumbersO2N - a permutation array, of length \a
855  *         this->getNumberOfNodes(), in "Old to New" mode. 
856  *         See \ref MEDCouplingArrayRenumbering for more info on renumbering modes.
857  *  \throw If the nodal connectivity of cells is not defined.
858  */
859 void MEDCoupling1SGTUMesh::renumberNodesInConn(const int *newNodeNumbersO2N)
860 {
861   getNumberOfCells();//only to check that all is well defined.
862   _conn->transformWithIndArr(newNodeNumbersO2N,newNodeNumbersO2N+getNumberOfNodes());
863   updateTime();
864 }
865
866 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(const MEDCoupling1SGTUMesh *mesh1, const MEDCoupling1SGTUMesh *mesh2) throw(INTERP_KERNEL::Exception)
867 {
868   std::vector<const MEDCoupling1SGTUMesh *> tmp(2);
869   tmp[0]=const_cast<MEDCoupling1SGTUMesh *>(mesh1); tmp[1]=const_cast<MEDCoupling1SGTUMesh *>(mesh2);
870   return Merge1SGTUMeshes(tmp);
871 }
872
873 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(std::vector<const MEDCoupling1SGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
874 {
875   std::size_t sz=a.size();
876   if(sz==0)
877     return Merge1SGTUMeshesLL(a);
878   for(std::size_t ii=0;ii<sz;ii++)
879     if(!a[ii])
880       {
881         std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::Merge1SGTUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !";
882         throw INTERP_KERNEL::Exception(oss.str().c_str());
883       }
884   const INTERP_KERNEL::CellModel *cm=&(a[0]->getCellModel());
885   for(std::size_t ii=0;ii<sz;ii++)
886     if(&(a[ii]->getCellModel())!=cm)
887       throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : all items must have the same geo type !");
888   std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> > bb(sz);
889   std::vector< const MEDCoupling1SGTUMesh * > aa(sz);
890   int spaceDim=-3;
891   for(std::size_t i=0;i<sz && spaceDim==-3;i++)
892     {
893       const MEDCoupling1SGTUMesh *cur=a[i];
894       const DataArrayDouble *coo=cur->getCoords();
895       if(coo)
896         spaceDim=coo->getNumberOfComponents();
897     }
898   if(spaceDim==-3)
899     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : no spaceDim specified ! unable to perform merge !");
900   for(std::size_t i=0;i<sz;i++)
901     {
902       bb[i]=a[i]->buildSetInstanceFromThis(spaceDim);
903       aa[i]=bb[i];
904     }
905   return Merge1SGTUMeshesLL(aa);
906 }
907
908 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords(std::vector<const MEDCoupling1SGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
909 {
910   if(a.empty())
911     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : input array must be NON EMPTY !");
912   std::vector<const MEDCoupling1SGTUMesh *>::const_iterator it=a.begin();
913   if(!(*it))
914     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : presence of null instance !");
915   std::vector<const DataArrayInt *> ncs(a.size());
916   int nbOfCells=(*it)->getNumberOfCells();
917   const DataArrayDouble *coords=(*it)->getCoords();
918   const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
919   int nbNodesPerCell=(*it)->getNumberOfNodesPerCell();
920   ncs[0]=(*it)->getNodalConnectivity();
921   it++;
922   for(int i=1;it!=a.end();i++,it++)
923     {
924       if(cm!=&((*it)->getCellModel()))
925         throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !");
926       (*it)->getNumberOfCells();//to check that all is OK
927       ncs[i]=(*it)->getNodalConnectivity();
928       if(coords!=(*it)->getCoords())
929         throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : not lying on same coords !");
930     }
931   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh("merge",*cm));
932   ret->setCoords(coords);
933   ret->_conn=DataArrayInt::Aggregate(ncs);
934   return ret.retn();
935 }
936
937 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesLL(std::vector<const MEDCoupling1SGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
938 {
939   if(a.empty())
940     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : input array must be NON EMPTY !");
941   std::vector<const MEDCoupling1SGTUMesh *>::const_iterator it=a.begin();
942   int nbOfCells=(*it)->getNumberOfCells();
943   const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
944   int nbNodesPerCell=(*it)->getNumberOfNodesPerCell();
945   it++;
946   for(;it!=a.end();it++)
947     {
948       if(cm!=&((*it)->getCellModel()))
949         throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !");
950       nbOfCells+=(*it)->getNumberOfCells();
951     }
952   std::vector<const MEDCouplingPointSet *> aps(a.size());
953   std::copy(a.begin(),a.end(),aps.begin());
954   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> pts=MergeNodesArray(aps);
955   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh("merge",*cm));
956   ret->setCoords(pts);
957   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New();
958   c->alloc(nbOfCells*nbNodesPerCell,1);
959   int *cPtr=c->getPointer();
960   int offset=0;
961   for(it=a.begin();it!=a.end();it++)
962     {
963       int curConnLgth=(*it)->getNodalConnectivityLength();
964       const int *curC=(*it)->_conn->begin();
965       cPtr=std::transform(curC,curC+curConnLgth,cPtr,std::bind2nd(std::plus<int>(),offset));
966       offset+=(*it)->getNumberOfNodes();
967     }
968   //
969   ret->setNodalConnectivity(c);
970   return ret.retn();
971 }
972
973 MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const
974 {
975   int ncell=getNumberOfCells();
976   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
977   ret->setCoords(_coords);
978   std::size_t nbOfElemsRet=std::distance(begin,end);
979   const int *inConn=_conn->getConstPointer();
980   int sz=getNumberOfNodesPerCell();
981   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connRet=DataArrayInt::New(); connRet->alloc((int)nbOfElemsRet*sz,1);
982   int *connPtr=connRet->getPointer();
983   for(const int *work=begin;work!=end;work++,connPtr+=sz)
984     {
985       if(*work>=0 && *work<ncell)
986         std::copy(inConn+(work[0])*sz,inConn+(work[0]+1)*sz,connPtr);
987       else
988         {
989           std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords : On pos #" << std::distance(begin,work) << " input cell id =" << *work << " should be in [0," << ncell << ") !";
990           throw INTERP_KERNEL::Exception(oss.str().c_str());
991         }
992     }
993   ret->_conn=connRet;
994   ret->copyTinyInfoFrom(this);
995   return ret.retn();
996 }
997
998 MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const
999 {
1000   int ncell=getNumberOfCells();
1001   int nbOfElemsRet=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2 : ");
1002   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
1003   ret->setCoords(_coords);
1004   const int *inConn=_conn->getConstPointer();
1005   int sz=getNumberOfNodesPerCell();
1006   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connRet=DataArrayInt::New(); connRet->alloc((int)nbOfElemsRet*sz,1);
1007   int *connPtr=connRet->getPointer();
1008   int curId=start;
1009   for(int i=0;i<nbOfElemsRet;i++,connPtr+=sz,curId+=step)
1010     {
1011       if(curId>=0 && curId<ncell)
1012         std::copy(inConn+curId*sz,inConn+(curId+1)*sz,connPtr);
1013       else
1014         {
1015           std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2 : On pos #" << i << " input cell id =" << curId  << " should be in [0," << ncell << ") !";
1016           throw INTERP_KERNEL::Exception(oss.str().c_str());
1017         }
1018     }
1019   ret->_conn=connRet;
1020   ret->copyTinyInfoFrom(this);
1021   return ret.retn();
1022 }
1023
1024 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::buildSetInstanceFromThis(int spaceDim) const throw(INTERP_KERNEL::Exception)
1025 {
1026   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
1027   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1;
1028   const DataArrayInt *nodalConn(_conn);
1029   if(!nodalConn)
1030     {
1031       tmp1=DataArrayInt::New(); tmp1->alloc(0,1);
1032     }
1033   else
1034     tmp1=_conn;
1035   ret->_conn=tmp1;
1036   if(!_coords)
1037     {
1038       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim);
1039       ret->setCoords(coords);
1040     }
1041   else
1042     ret->setCoords(_coords);
1043   return ret.retn();
1044 }
1045
1046 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePol0() throw(INTERP_KERNEL::Exception)
1047 {
1048   int nbOfCells=getNumberOfCells();
1049   if(getCellModelEnum()!=INTERP_KERNEL::NORM_QUAD4)
1050     return DataArrayInt::Range(0,nbOfCells,1);
1051   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(2*3*nbOfCells,1);
1052   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(2*nbOfCells,1);
1053   const int *c(_conn->begin());
1054   int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1055   for(int i=0;i<nbOfCells;i++,c+=4,newConnPtr+=6,retPtr+=2)
1056     {
1057       newConnPtr[0]=c[0]; newConnPtr[1]=c[1]; newConnPtr[2]=c[2];
1058       newConnPtr[3]=c[0]; newConnPtr[4]=c[2]; newConnPtr[5]=c[3];
1059       retPtr[0]=i; retPtr[1]=i;
1060     }
1061   _conn=newConn;
1062   _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TRI3);
1063   updateTime();
1064   return ret.retn();
1065 }
1066
1067 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePol1() throw(INTERP_KERNEL::Exception)
1068 {
1069   int nbOfCells=getNumberOfCells();
1070   if(getCellModelEnum()!=INTERP_KERNEL::NORM_QUAD4)
1071     return DataArrayInt::Range(0,nbOfCells,1);
1072   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(2*3*nbOfCells,1);
1073   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(2*nbOfCells,1);
1074   const int *c(_conn->begin());
1075   int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1076   for(int i=0;i<nbOfCells;i++,c+=4,newConnPtr+=6,retPtr+=2)
1077     {
1078       newConnPtr[0]=c[0]; newConnPtr[1]=c[1]; newConnPtr[2]=c[3];
1079       newConnPtr[3]=c[1]; newConnPtr[4]=c[2]; newConnPtr[5]=c[3];
1080       retPtr[0]=i; retPtr[1]=i;
1081     }
1082   _conn=newConn;
1083   _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TRI3);
1084   updateTime();
1085   return ret.retn();
1086 }
1087
1088 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePlanarFace5() throw(INTERP_KERNEL::Exception)
1089 {
1090   int nbOfCells=getNumberOfCells();
1091   if(getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA8)
1092     return DataArrayInt::Range(0,nbOfCells,1);
1093   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(5*4*nbOfCells,1);
1094   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(5*nbOfCells,1);
1095   const int *c(_conn->begin());
1096   int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1097   for(int i=0;i<nbOfCells;i++,c+=8,newConnPtr+=20,retPtr+=5)
1098     {
1099       for(int j=0;j<20;j++)
1100         newConnPtr[j]=c[INTERP_KERNEL::SPLIT_NODES_5_WO[j]];
1101       retPtr[0]=i; retPtr[1]=i; retPtr[2]=i; retPtr[3]=i; retPtr[4]=i;
1102     }
1103   _conn=newConn;
1104   _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TETRA4);
1105   updateTime();
1106   return ret.retn();
1107 }
1108
1109 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePlanarFace6() throw(INTERP_KERNEL::Exception)
1110 {
1111   int nbOfCells=getNumberOfCells();
1112   if(getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA8)
1113     return DataArrayInt::Range(0,nbOfCells,1);
1114   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(6*4*nbOfCells,1);
1115   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(6*nbOfCells,1);
1116   const int *c(_conn->begin());
1117   int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1118   for(int i=0;i<nbOfCells;i++,c+=8,newConnPtr+=24,retPtr+=6)
1119     {
1120       for(int j=0;j<24;j++)
1121         newConnPtr[j]=c[INTERP_KERNEL::SPLIT_NODES_6_WO[j]];
1122       retPtr[0]=i; retPtr[1]=i; retPtr[2]=i; retPtr[3]=i; retPtr[4]=i; retPtr[5]=i;
1123     }
1124   _conn=newConn;
1125   _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TETRA4);
1126   updateTime();
1127   return ret.retn();
1128 }
1129
1130 void MEDCoupling1SGTUMesh::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1131 {
1132   stream << "MEDCoupling1SGTUMesh C++ instance at " << this << ". Type=" << _cm->getRepr() << ". Name : \"" << getName() << "\".";
1133   stream << " Mesh dimension : " << getMeshDimension() << ".";
1134   if(!_coords)
1135     { stream << " No coordinates set !"; return ; }
1136   if(!_coords->isAllocated())
1137     { stream << " Coordinates set but not allocated !"; return ; }
1138   stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
1139   stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
1140   if(!(const DataArrayInt *)_conn)
1141     { stream << std::endl << "Nodal connectivity NOT set !"; return ; }
1142   if(_conn->isAllocated())
1143     {
1144       if(_conn->getNumberOfComponents()==1)
1145         stream << std::endl << "Number of cells : " << getNumberOfCells() << ".";
1146     }
1147 }
1148
1149 void MEDCoupling1SGTUMesh::checkFullyDefined() const throw(INTERP_KERNEL::Exception)
1150 {
1151   if(!((const DataArrayInt *)_conn) || !((const DataArrayDouble *)_coords))
1152     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFullyDefined : part of this is not fully defined.");
1153 }
1154
1155 /*!
1156  * First step of unserialization process.
1157  */
1158 bool MEDCoupling1SGTUMesh::isEmptyMesh(const std::vector<int>& tinyInfo) const
1159 {
1160   throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEmptyMesh : not implemented yet !");
1161 }
1162
1163 /*!
1164  * Checks if \a this and \a other meshes are geometrically equivalent with high
1165  * probability, else an exception is thrown. The meshes are considered equivalent if
1166  * (1) meshes contain the same number of nodes and the same number of elements of the
1167  * same types (2) three cells of the two meshes (first, last and middle) are based
1168  * on coincident nodes (with a specified precision).
1169  *  \param [in] other - the mesh to compare with.
1170  *  \param [in] prec - the precision used to compare nodes of the two meshes.
1171  *  \throw If the two meshes do not match.
1172  */
1173 void MEDCoupling1SGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception)
1174 {
1175   MEDCouplingPointSet::checkFastEquivalWith(other,prec);
1176   const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
1177   if(!otherC)
1178     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : Two meshes are not not unstructured with single static geometric type !");
1179   const DataArrayInt *c1(_conn),*c2(otherC->_conn);
1180   if(c1==c2)
1181     return;
1182   if(!c1 || !c2)
1183     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !");
1184   if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
1185     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !");
1186   if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
1187     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !");
1188   if(c1->getHashCode()!=c2->getHashCode())
1189     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : nodal connectivity differs");
1190 }
1191
1192 MEDCouplingPointSet *MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const
1193 {
1194   if(!other)
1195     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : input other is null !");
1196   const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
1197   if(!otherC)
1198     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !");
1199   std::vector<const MEDCoupling1SGTUMesh *> ms(2);
1200   ms[0]=this;
1201   ms[1]=otherC;
1202   return Merge1SGTUMeshesOnSameCoords(ms);
1203 }
1204
1205 void MEDCoupling1SGTUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const throw(INTERP_KERNEL::Exception)
1206 {
1207   checkFullyDefined();
1208   int nbOfNodes=getNumberOfNodes();
1209   int *revNodalIndxPtr=(int *)malloc((nbOfNodes+1)*sizeof(int));
1210   revNodalIndx->useArray(revNodalIndxPtr,true,C_DEALLOC,nbOfNodes+1,1);
1211   std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
1212   const int *conn=_conn->begin();
1213   int nbOfCells=getNumberOfCells();
1214   int nbOfEltsInRevNodal=0;
1215   int nbOfNodesPerCell=getNumberOfNodesPerCell();
1216   for(int eltId=0;eltId<nbOfCells;eltId++)
1217     {
1218       for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1219         {
1220           if(conn[0]>=0 && conn[0]<nbOfNodes)
1221             {
1222               nbOfEltsInRevNodal++;
1223               revNodalIndxPtr[conn[0]+1]++;
1224             }
1225           else
1226             {
1227               std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !";
1228               throw INTERP_KERNEL::Exception(oss.str().c_str());
1229             }
1230         }
1231     }
1232   std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<int>());
1233   conn=_conn->begin();
1234   int *revNodalPtr=(int *)malloc((nbOfEltsInRevNodal)*sizeof(int));
1235   revNodal->useArray(revNodalPtr,true,C_DEALLOC,nbOfEltsInRevNodal,1);
1236   std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
1237   for(int eltId=0;eltId<nbOfCells;eltId++)
1238     {
1239       for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1240         {
1241           *std::find_if(revNodalPtr+revNodalIndxPtr[*conn],revNodalPtr+revNodalIndxPtr[*conn+1],std::bind2nd(std::equal_to<int>(),-1))=eltId;
1242         }
1243     }
1244 }
1245
1246 /*!
1247  * Use \a nodalConn array as nodal connectivity of \a this. The input \a nodalConn pointer can be null.
1248  */
1249 void MEDCoupling1SGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn) throw(INTERP_KERNEL::Exception)
1250 {
1251   if(nodalConn)
1252     nodalConn->incrRef();
1253   _conn=nodalConn;
1254   declareAsNew();
1255 }
1256
1257 /*!
1258  * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it.
1259  */
1260 DataArrayInt *MEDCoupling1SGTUMesh::getNodalConnectivity() const throw(INTERP_KERNEL::Exception)
1261 {
1262   const DataArrayInt *ret(_conn);
1263   return const_cast<DataArrayInt *>(ret);
1264 }
1265
1266 /*!
1267  * Allocates memory to store an estimation of the given number of cells. Closer is the estimation to the number of cells effectively inserted,
1268  * less will be the needs to realloc. If the number of cells to be inserted is not known simply put 0 to this parameter.
1269  * If a nodal connectivity previouly existed before the call of this method, it will be reset.
1270  *
1271  *  \param [in] nbOfCells - estimation of the number of cell \a this mesh will contain.
1272  */
1273 void MEDCoupling1SGTUMesh::allocateCells(int nbOfCells) throw(INTERP_KERNEL::Exception)
1274 {
1275   if(nbOfCells<0)
1276     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::allocateCells : the input number of cells should be >= 0 !");
1277   _conn=DataArrayInt::New();
1278   _conn->reserve(getNumberOfNodesPerCell()*nbOfCells);
1279   declareAsNew();
1280 }
1281
1282 /*!
1283  * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ).
1284  *
1285  * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add.
1286  * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
1287  * \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
1288  *        attached to \a this.
1289  * \thow If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
1290  */
1291 void MEDCoupling1SGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd) throw(INTERP_KERNEL::Exception)
1292 {
1293   int sz=(int)std::distance(nodalConnOfCellBg,nodalConnOfCellEnd);
1294   int ref=getNumberOfNodesPerCell();
1295   if(sz==ref)
1296     {
1297       DataArrayInt *c(_conn);
1298       if(c)
1299         c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd);
1300       else
1301         throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1SGTUMesh::allocateCells before !");
1302     }
1303   else
1304     {
1305       std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::insertNextCell : input nodal size (" << sz << ") does not match number of nodes per cell of this (";
1306       oss << ref << ") !";
1307       throw INTERP_KERNEL::Exception(oss.str().c_str());
1308     }
1309 }
1310
1311 //== find static tony
1312
1313 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const char *name, INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception)
1314 {
1315   if(type==INTERP_KERNEL::NORM_ERROR)
1316     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
1317   const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
1318   if(!cm.isDynamic())
1319     {
1320       std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::New : the input geometric type " << cm.getRepr() << " is static ! Only dynamic types are allowed here !";
1321       throw INTERP_KERNEL::Exception(oss.str().c_str());
1322     }
1323   return new MEDCoupling1DGTUMesh(name,cm);
1324 }
1325
1326 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const char *name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm)
1327 {
1328 }
1329
1330 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const MEDCoupling1DGTUMesh& other, bool recDeepCpy):MEDCoupling1GTUMesh(other,recDeepCpy),_conn(other._conn)
1331 {
1332   if(recDeepCpy)
1333     {
1334       const DataArrayInt *c(other._conn);
1335       if(c)
1336         _conn=c->deepCpy();
1337       c=other._conn_indx;
1338       if(c)
1339         _conn_indx=c->deepCpy();
1340     }
1341 }
1342
1343 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::clone(bool recDeepCpy) const
1344 {
1345   return new MEDCoupling1DGTUMesh(*this,recDeepCpy);
1346 }
1347
1348 void MEDCoupling1DGTUMesh::updateTime() const
1349 {
1350   MEDCoupling1GTUMesh::updateTime();
1351   const DataArrayInt *c(_conn);
1352   if(c)
1353     updateTimeWith(*c);
1354   c=_conn_indx;
1355   if(c)
1356     updateTimeWith(*c);
1357 }
1358
1359 std::size_t MEDCoupling1DGTUMesh::getHeapMemorySize() const
1360 {
1361   std::size_t ret=0;
1362   const DataArrayInt *c(_conn);
1363   if(c)
1364     ret+=c->getHeapMemorySize();
1365   c=_conn_indx;
1366   if(c)
1367     ret+=c->getHeapMemorySize();
1368   return MEDCoupling1GTUMesh::getHeapMemorySize()+ret;
1369 }
1370
1371 MEDCouplingMesh *MEDCoupling1DGTUMesh::deepCpy() const
1372 {
1373   return clone(true);
1374 }
1375
1376 bool MEDCoupling1DGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception)
1377 {
1378   if(!other)
1379     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualIfNotWhy : input other pointer is null !");
1380   std::ostringstream oss; oss.precision(15);
1381   const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
1382   if(!otherC)
1383     {
1384       reason="mesh given in input is not castable in MEDCoupling1DGTUMesh !";
1385       return false;
1386     }
1387   if(!MEDCoupling1GTUMesh::isEqualIfNotWhy(other,prec,reason))
1388     return false;
1389   const DataArrayInt *c1(_conn),*c2(otherC->_conn);
1390   if(c1==c2)
1391     return true;
1392   if(!c1 || !c2)
1393     {
1394       reason="in connectivity of single dynamic geometric type exactly one among this and other is null !";
1395       return false;
1396     }
1397   if(!c1->isEqualIfNotWhy(*c2,reason))
1398     {
1399       reason.insert(0,"Nodal connectivity DataArrayInt differs : ");
1400       return false;
1401     }
1402   c1=_conn_indx; c2=otherC->_conn_indx;
1403   if(c1==c2)
1404     return true;
1405   if(!c1 || !c2)
1406     {
1407       reason="in connectivity index of single dynamic geometric type exactly one among this and other is null !";
1408       return false;
1409     }
1410   if(!c1->isEqualIfNotWhy(*c2,reason))
1411     {
1412       reason.insert(0,"Nodal connectivity index DataArrayInt differs : ");
1413       return false;
1414     }
1415   return true;
1416 }
1417
1418 bool MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
1419 {
1420   if(!other)
1421     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
1422   const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
1423   if(!otherC)
1424     return false;
1425   if(!MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(other,prec))
1426     return false;
1427   const DataArrayInt *c1(_conn),*c2(otherC->_conn);
1428   if(c1==c2)
1429     return true;
1430   if(!c1 || !c2)
1431     return false;
1432   if(!c1->isEqualWithoutConsideringStr(*c2))
1433     return false;
1434   return true;
1435   c1=_conn_indx; c2=otherC->_conn_indx;
1436   if(c1==c2)
1437     return true;
1438   if(!c1 || !c2)
1439     return false;
1440   if(!c1->isEqualWithoutConsideringStr(*c2))
1441     return false;
1442   return true;
1443 }
1444
1445 /*!
1446  * Checks if \a this and \a other meshes are geometrically equivalent with high
1447  * probability, else an exception is thrown. The meshes are considered equivalent if
1448  * (1) meshes contain the same number of nodes and the same number of elements of the
1449  * same types (2) three cells of the two meshes (first, last and middle) are based
1450  * on coincident nodes (with a specified precision).
1451  *  \param [in] other - the mesh to compare with.
1452  *  \param [in] prec - the precision used to compare nodes of the two meshes.
1453  *  \throw If the two meshes do not match.
1454  */
1455 void MEDCoupling1DGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception)
1456 {
1457   MEDCouplingPointSet::checkFastEquivalWith(other,prec);
1458   const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
1459   if(!otherC)
1460     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : Two meshes are not not unstructured with single static geometric type !");
1461   const DataArrayInt *c1(_conn),*c2(otherC->_conn);
1462   if(c1!=c2)
1463     {
1464       if(!c1 || !c2)
1465         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !");
1466       if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
1467         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !");
1468       if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
1469         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !");
1470       if(c1->getHashCode()!=c2->getHashCode())
1471         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity differs");
1472     }
1473   c1=_conn_indx; c2=otherC->_conn_indx;
1474   if(c1!=c2)
1475     {
1476       if(!c1 || !c2)
1477         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity index only in one of the 2 meshes !");
1478       if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
1479         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, only one is allocated !");
1480       if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
1481         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, must have 1 and only 1 component !");
1482       if(c1->getHashCode()!=c2->getHashCode())
1483         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity index differs");
1484     }
1485 }
1486
1487 /*!
1488  * 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.
1489  * In addition you are sure that the length of nodal connectivity index array is bigger than or equal to one.
1490  * In addition you are also sure that length of nodal connectivity is coherent with the content of the last value in the index array.
1491  */
1492 void MEDCoupling1DGTUMesh::checkCoherency() const throw(INTERP_KERNEL::Exception)
1493 {
1494   MEDCouplingPointSet::checkCoherency();
1495   const DataArrayInt *c1(_conn);
1496   if(c1)
1497     {
1498       if(c1->getNumberOfComponents()!=1)
1499         throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !");
1500       if(c1->getInfoOnComponent(0)!="")
1501         throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !");
1502       c1->checkAllocated();
1503     }
1504   else
1505     throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !");
1506   //
1507   int sz2=_conn->getNumberOfTuples();
1508   c1=_conn_indx;
1509   if(c1)
1510     {
1511       if(c1->getNumberOfComponents()!=1)
1512         throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to be with number of components set to one !");
1513       c1->checkAllocated();
1514       if(c1->getNumberOfTuples()<1)
1515         throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have a a size of 1 at least !");
1516       if(c1->getInfoOnComponent(0)!="")
1517         throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have no info on its single component !");
1518       int f=c1->front(),ll=c1->back();
1519       if(f<0 || f>=sz2)
1520         {
1521           std::ostringstream oss; oss << "Nodal connectivity index array first value (" << f << ") is expected to be exactly in [0," << sz2 << ") !";
1522           throw INTERP_KERNEL::Exception(oss.str().c_str());
1523         }
1524       if(ll<0 || ll>sz2)
1525         {
1526           std::ostringstream oss; oss << "Nodal connectivity index array last value (" << ll << ") is expected to be exactly in [0," << sz2 << "] !";
1527           throw INTERP_KERNEL::Exception(oss.str().c_str());
1528         }
1529       if(f>ll)
1530         {
1531           std::ostringstream oss; oss << "Nodal connectivity index array looks very bad (not increasing monotonic) because front (" << f << ") is greater that back (" << ll << ") !";
1532           throw INTERP_KERNEL::Exception(oss.str().c_str());
1533         }
1534     }
1535   else
1536     throw INTERP_KERNEL::Exception("Nodal connectivity index array not defined !");
1537   int szOfC1Exp=_conn_indx->back();
1538   if(sz2<szOfC1Exp)
1539     {
1540       std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::checkCoherency : The expected length of nodal connectivity array regarding index is " << szOfC1Exp << " but the actual size of it is " << c1->getNumberOfTuples() << " !";
1541       throw INTERP_KERNEL::Exception(oss.str().c_str());
1542     }
1543 }
1544
1545 void MEDCoupling1DGTUMesh::checkCoherency1(double eps) const throw(INTERP_KERNEL::Exception)
1546 {
1547   checkCoherency();
1548   const DataArrayInt *c1(_conn),*c2(_conn_indx);
1549   if(!c2->isMonotonic(true))
1550     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkCoherency1 : the nodal connectivity index is expected to be increasing monotinic !");
1551   //
1552   int nbOfTuples=c1->getNumberOfTuples();
1553   int nbOfNodes=getNumberOfNodes();
1554   const int *w(c1->begin());
1555   for(int i=0;i<nbOfTuples;i++,w++)
1556     {
1557       if(*w==-1) continue;
1558       if(*w<0 || *w>=nbOfNodes)
1559         {
1560           std::ostringstream oss; oss << "At pos #" << i << " of nodal connectivity array references to node id #" << *w << " must be in [0," << nbOfNodes << ") !";
1561           throw INTERP_KERNEL::Exception(oss.str().c_str());
1562         }
1563     }
1564 }
1565
1566 void MEDCoupling1DGTUMesh::checkCoherency2(double eps) const throw(INTERP_KERNEL::Exception)
1567 {
1568   checkCoherency1(eps);
1569 }
1570
1571 int MEDCoupling1DGTUMesh::getNumberOfCells() const
1572 {
1573   checkCoherency();//do not remove
1574   return _conn_indx->getNumberOfTuples()-1;
1575 }
1576
1577 /*!
1578  * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
1579  * For each cell in \b this the number of nodes constituting cell is computed.
1580  * For each polyhedron cell, the sum of the number of nodes of each face constituting polyhedron cell is returned.
1581  * So for pohyhedrons some nodes can be counted several times in the returned result.
1582  * 
1583  * \return a newly allocated array
1584  */
1585 DataArrayInt *MEDCoupling1DGTUMesh::computeNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
1586 {
1587   checkCoherency();
1588   _conn_indx->checkMonotonic(true);
1589   if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
1590     return _conn_indx->deltaShiftIndex();
1591   // for polyhedrons
1592   int nbOfCells=_conn_indx->getNumberOfTuples()-1;
1593   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
1594   ret->alloc(nbOfCells,1);
1595   int *retPtr=ret->getPointer();
1596   const int *ci=_conn_indx->begin(),*c=_conn->begin();
1597   for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
1598     *retPtr=ci[1]-ci[0]-std::count(c+ci[0],c+ci[1],-1);
1599   return ret.retn();
1600 }
1601
1602 /*!
1603  * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
1604  * For each cell in \b this the number of faces constituting (entity of dimension this->getMeshDimension()-1) cell is computed.
1605  * 
1606  * \return a newly allocated array
1607  */
1608 DataArrayInt *MEDCoupling1DGTUMesh::computeNbOfFacesPerCell() const throw(INTERP_KERNEL::Exception)
1609 {
1610   checkCoherency();
1611   _conn_indx->checkMonotonic(true);
1612   if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED && getCellModelEnum()!=INTERP_KERNEL::NORM_QPOLYG)
1613     return _conn_indx->deltaShiftIndex();
1614   if(getCellModelEnum()==INTERP_KERNEL::NORM_QPOLYG)
1615     {
1616       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=_conn_indx->deltaShiftIndex();
1617       ret->applyDivideBy(2);
1618       return ret.retn();
1619     }
1620   // for polyhedrons
1621   int nbOfCells=_conn_indx->getNumberOfTuples()-1;
1622   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
1623   ret->alloc(nbOfCells,1);
1624   int *retPtr=ret->getPointer();
1625   const int *ci=_conn_indx->begin(),*c=_conn->begin();
1626   for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
1627     *retPtr=std::count(c+ci[0],c+ci[1],-1)+1;
1628   return ret.retn();
1629 }
1630
1631 void MEDCoupling1DGTUMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
1632 {
1633   int nbOfCells=getNumberOfCells();//performs checks
1634   if(cellId>=0 && cellId<nbOfCells)
1635     {
1636       int strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0);
1637       int nbOfNodes=stp-strt;
1638       if(nbOfNodes<0)
1639         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::getNodeIdsOfCell : the index array is invalid ! Should be increasing monotonic !");
1640       conn.resize(nbOfNodes);
1641       std::copy(_conn->begin()+strt,_conn->begin()+stp,conn.begin());
1642     }
1643   else
1644     {
1645       std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !";
1646       throw INTERP_KERNEL::Exception(oss.str().c_str());
1647     }
1648 }
1649
1650 std::string MEDCoupling1DGTUMesh::simpleRepr() const
1651 {
1652   static const char msg0[]="No coordinates specified !";
1653   std::ostringstream ret;
1654   ret << "Single dynamic geometic type (" << _cm->getRepr() << ") unstructured mesh with name : \"" << getName() << "\"\n";
1655   ret << "Description of mesh : \"" << getDescription() << "\"\n";
1656   int tmpp1,tmpp2;
1657   double tt=getTime(tmpp1,tmpp2);
1658   ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
1659   ret << "Iteration : " << tmpp1  << " Order : " << tmpp2 << "\n";
1660   ret << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : ";
1661   if(_coords!=0)
1662     {
1663       const int spaceDim=getSpaceDimension();
1664       ret << spaceDim << "\nInfo attached on space dimension : ";
1665       for(int i=0;i<spaceDim;i++)
1666         ret << "\"" << _coords->getInfoOnComponent(i) << "\" ";
1667       ret << "\n";
1668     }
1669   else
1670     ret << msg0 << "\n";
1671   ret << "Number of nodes : ";
1672   if(_coords!=0)
1673     ret << getNumberOfNodes() << "\n";
1674   else
1675     ret << msg0 << "\n";
1676   ret << "Number of cells : ";
1677   bool isOK=true;
1678   try { checkCoherency(); } catch(INTERP_KERNEL::Exception& e)
1679     {
1680       ret << "Nodal connectivity arrays are not set or badly set !\n";
1681       isOK=false;
1682     }
1683   if(isOK)
1684     ret << getNumberOfCells() << "\n";
1685   ret << "Cell type : " << _cm->getRepr() << "\n";
1686   return ret.str();
1687 }
1688
1689 std::string MEDCoupling1DGTUMesh::advancedRepr() const
1690 {
1691   std::ostringstream ret;
1692   ret << simpleRepr();
1693   ret << "\nCoordinates array : \n___________________\n\n";
1694   if(_coords)
1695     _coords->reprWithoutNameStream(ret);
1696   else
1697     ret << "No array set !\n";
1698   ret << "\n\nNodal Connectivity : \n____________________\n\n";
1699   //
1700   bool isOK=true;
1701   try { checkCoherency1(); } catch(INTERP_KERNEL::Exception& e)
1702     {
1703       ret << "Nodal connectivity arrays are not set or badly set !\n";
1704       isOK=false;
1705     }
1706   if(!isOK)
1707     return ret.str();
1708   int nbOfCells=getNumberOfCells();
1709   const int *ci=_conn_indx->begin(),*c=_conn->begin();
1710   for(int i=0;i<nbOfCells;i++,ci++)
1711     {
1712       ret << "Cell #" << i << " : ";
1713       std::copy(c+ci[0],c+ci[1],std::ostream_iterator<int>(ret," "));
1714       ret << "\n";
1715     }
1716   return ret.str();
1717 }
1718
1719 DataArrayDouble *MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
1720 {
1721   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1722   int spaceDim=getSpaceDimension();
1723   int nbOfCells=getNumberOfCells();//checkCoherency()
1724   int nbOfNodes=getNumberOfNodes();
1725   ret->alloc(nbOfCells,spaceDim);
1726   double *ptToFill=ret->getPointer();
1727   const double *coor=_coords->begin();
1728   const int *nodal=_conn->begin(),*nodali=_conn_indx->begin();
1729   nodal+=nodali[0];
1730   if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
1731     {
1732       for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
1733         {
1734           std::fill(ptToFill,ptToFill+spaceDim,0.);
1735           if(nodali[0]>=nodali[1])// >= to avoid division by 0.
1736             {
1737               for(int j=nodali[0];j<nodali[1];j++,nodal++)
1738                 {
1739                   if(*nodal>=0 && *nodal<nbOfNodes)
1740                     std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
1741                   else
1742                     {
1743                       std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," <<   nbOfNodes << ") !";
1744                       throw INTERP_KERNEL::Exception(oss.str().c_str());
1745                     }
1746                   std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./(nodali[1]-nodali[0])));
1747                 }
1748             }
1749           else
1750             {
1751               std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : at cell #" << i << " the nodal index array is invalid !";
1752               throw INTERP_KERNEL::Exception(oss.str().c_str());
1753             }
1754         }
1755     }
1756   else
1757     {
1758       for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
1759         {
1760           std::fill(ptToFill,ptToFill+spaceDim,0.);
1761           if(nodali[0]>=nodali[1])// >= to avoid division by 0.
1762             {
1763               int nbOfNod=0;
1764               for(int j=nodali[0];j<nodali[1];j++,nodal++)
1765                 {
1766                   if(*nodal==-1) continue;
1767                   if(*nodal>=0 && *nodal<nbOfNodes)
1768                     {
1769                       std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
1770                       nbOfNod++;
1771                     }
1772                   else
1773                     {
1774                       std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," <<   nbOfNodes << ") !";
1775                       throw INTERP_KERNEL::Exception(oss.str().c_str());
1776                     }
1777                 }
1778               if(nbOfNod!=0)
1779                 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./nbOfNod));
1780               else
1781                 {
1782                   std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : no nodes in cell #" << i << " !";
1783                   throw INTERP_KERNEL::Exception(oss.str().c_str());
1784                 }
1785             }
1786           else
1787             {
1788               std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron)  : at cell #" << i << " the nodal index array is invalid !";
1789               throw INTERP_KERNEL::Exception(oss.str().c_str());
1790             }
1791         }
1792     }
1793   return ret.retn();
1794 }
1795
1796 void MEDCoupling1DGTUMesh::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception)
1797 {
1798   int nbCells=getNumberOfCells();
1799   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::New();
1800   o2n->useArray(old2NewBg,false,C_DEALLOC,nbCells,1);
1801   if(check)
1802     o2n=o2n->checkAndPreparePermutation();
1803   //
1804   const int *conn=_conn->begin(),*conni=_conn_indx->begin();
1805   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> n2o=o2n->invertArrayO2N2N2O(nbCells);
1806   const int *n2oPtr=n2o->begin();
1807   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New();
1808   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI=DataArrayInt::New();
1809   newConn->alloc(_conn->getNumberOfTuples(),1); newConnI->alloc(nbCells,1);
1810   newConn->copyStringInfoFrom(*_conn); newConnI->copyStringInfoFrom(*_conn_indx);
1811   //
1812   int *newC=newConn->getPointer(),*newCI=newConnI->getPointer();
1813   for(int i=0;i<nbCells;i++)
1814     {
1815       int sz=conni[i+1]-conni[i];
1816       if(sz>=0)
1817         newCI[n2oPtr[i]]=sz;
1818       else
1819         {
1820           std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberCells : the index nodal array is invalid for cell #" << i << " !";
1821           throw INTERP_KERNEL::Exception(oss.str().c_str());
1822         }
1823     }
1824   newConnI->computeOffsets2(); newCI=newConnI->getPointer();
1825   //
1826   for(int i=0;i<nbCells;i++,conni++)
1827     {
1828       int sz=conni[1]-conni[0];
1829       int newp=n2oPtr[i];
1830       std::copy(conn+conni[0],conn+conni[1],newC+newCI[newp]);
1831     }
1832   _conn=newConn;
1833 }
1834
1835 MEDCouplingMesh *MEDCoupling1DGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
1836 {
1837   if(other->getType()!=SINGLE_DYNAMIC_GEO_TYPE_UNSTRUCTURED)
1838     throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single dynamic geo type each other !");
1839   const MEDCoupling1DGTUMesh *otherC=static_cast<const MEDCoupling1DGTUMesh *>(other);
1840   return Merge1DGTUMeshes(this,otherC);
1841 }
1842
1843 MEDCouplingUMesh *MEDCoupling1DGTUMesh::buildUnstructured() const throw(INTERP_KERNEL::Exception)
1844 {
1845   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName(),getMeshDimension());
1846   ret->setCoords(getCoords());
1847   const int *nodalConn=_conn->begin(),*nodalConnI=_conn_indx->begin();
1848   int nbCells=getNumberOfCells();//checkCoherency
1849   int geoType=(int)getCellModelEnum();
1850   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New(); c->alloc(nbCells+_conn->getNumberOfTuples(),1);
1851   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cI=DataArrayInt::New(); cI->alloc(nbCells+1);
1852   int *cPtr=c->getPointer(),*ciPtr=cI->getPointer();
1853   ciPtr[0]=0;
1854   for(int i=0;i<nbCells;i++,ciPtr++)
1855     {
1856       int sz=nodalConnI[i+1]-nodalConnI[i];
1857       if(sz>=0)
1858         {
1859           *cPtr++=geoType;
1860           cPtr=std::copy(nodalConn+nodalConnI[i],nodalConn+nodalConnI[i+1],cPtr);
1861           ciPtr[1]=ciPtr[0]+sz+1;
1862         }
1863       else
1864         {
1865           std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::buildUnstructured : Invalid for nodal index for cell #" << i << " !";
1866           throw INTERP_KERNEL::Exception(oss.str().c_str());
1867         }
1868     }
1869   ret->setConnectivity(c,cI,true);
1870   return ret.retn();
1871 }
1872
1873 /*!
1874  * Do nothing for the moment, because there is no policy that allows to split polygons, polyhedrons ... into simplexes
1875  */
1876 DataArrayInt *MEDCoupling1DGTUMesh::simplexize(int policy) throw(INTERP_KERNEL::Exception)
1877 {
1878   int nbOfCells=getNumberOfCells();
1879   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
1880   ret->alloc(nbOfCells,1);
1881   ret->iota(0);
1882   return ret.retn();
1883 }
1884
1885 void MEDCoupling1DGTUMesh::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1886 {
1887   stream << "MEDCoupling1DGTUMesh C++ instance at " << this << ". Type=" << _cm->getRepr() << ". Name : \"" << getName() << "\".";
1888   stream << " Mesh dimension : " << getMeshDimension() << ".";
1889   if(!_coords)
1890     { stream << " No coordinates set !"; return ; }
1891   if(!_coords->isAllocated())
1892     { stream << " Coordinates set but not allocated !"; return ; }
1893   stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
1894   stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
1895   bool isOK=true;
1896   try { checkCoherency(); } catch(INTERP_KERNEL::Exception& e)
1897     {
1898       stream << std::endl << "Nodal connectivity NOT set properly !\n";
1899       isOK=false;
1900     }
1901   if(isOK)
1902     stream << std::endl << "Number of cells : " << getNumberOfCells() << ".";
1903 }
1904
1905 void MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other) throw(INTERP_KERNEL::Exception)
1906 {
1907   if(!other)
1908     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is null !");
1909   const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
1910   if(!otherC)
1911     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1DGTUMesh instance !");
1912   setNodalConnectivity(otherC->getNodalConnectivity(),otherC->getNodalConnectivityIndex());
1913 }
1914
1915 MEDCouplingPointSet *MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const
1916 {
1917   if(!other)
1918     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : input other is null !");
1919   const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
1920   if(!otherC)
1921     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !");
1922   std::vector<const MEDCoupling1DGTUMesh *> ms(2);
1923   ms[0]=this;
1924   ms[1]=otherC;
1925   return Merge1DGTUMeshesOnSameCoords(ms);
1926 }
1927
1928 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const
1929 {
1930   checkCoherency();
1931   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
1932   ret->setCoords(_coords);
1933   DataArrayInt *c=0,*ci=0;
1934   MEDCouplingUMesh::ExtractFromIndexedArrays(begin,end,_conn,_conn_indx,c,ci);
1935   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
1936   ret->setNodalConnectivity(c,ci);
1937   return ret.retn();
1938 }
1939
1940 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const
1941 {
1942   checkCoherency();
1943   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
1944   ret->setCoords(_coords);
1945   DataArrayInt *c=0,*ci=0;
1946   MEDCouplingUMesh::ExtractFromIndexedArrays2(start,end,step,_conn,_conn_indx,c,ci);
1947   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
1948   ret->setNodalConnectivity(c,ci);
1949   return ret.retn();
1950 }
1951
1952 void MEDCoupling1DGTUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const throw(INTERP_KERNEL::Exception)
1953 {
1954   checkFullyDefined();
1955   int nbOfNodes=getNumberOfNodes();
1956   int *revNodalIndxPtr=(int *)malloc((nbOfNodes+1)*sizeof(int));
1957   revNodalIndx->useArray(revNodalIndxPtr,true,C_DEALLOC,nbOfNodes+1,1);
1958   std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
1959   const int *conn=_conn->begin(),*conni=_conn_indx->begin();
1960   int nbOfCells=getNumberOfCells();
1961   int nbOfEltsInRevNodal=0;
1962   for(int eltId=0;eltId<nbOfCells;eltId++)
1963     {
1964       int nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
1965       if(nbOfNodesPerCell>=0)
1966         {
1967           for(int j=0;j<nbOfNodesPerCell;j++)
1968             {
1969               int nodeId=conn[conni[eltId]+j];
1970               if(nodeId==-1) continue;            
1971               if(nodeId>=0 && nodeId<nbOfNodes)
1972                 {
1973                   nbOfEltsInRevNodal++;
1974                   revNodalIndxPtr[nodeId+1]++;
1975                 }
1976               else
1977                 {
1978                   std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !";
1979                   throw INTERP_KERNEL::Exception(oss.str().c_str());
1980                 }
1981             }
1982         }
1983       else
1984         {
1985           std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << "nodal connectivity is invalid !";
1986           throw INTERP_KERNEL::Exception(oss.str().c_str());
1987         }
1988     }
1989   std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<int>());
1990   conn=_conn->begin();
1991   int *revNodalPtr=(int *)malloc((nbOfEltsInRevNodal)*sizeof(int));
1992   revNodal->useArray(revNodalPtr,true,C_DEALLOC,nbOfEltsInRevNodal,1);
1993   std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
1994   for(int eltId=0;eltId<nbOfCells;eltId++)
1995     {
1996       int nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
1997       for(int j=0;j<nbOfNodesPerCell;j++)
1998         {
1999           int nodeId=conn[conni[eltId]+j];
2000           if(nodeId!=-1)
2001             *std::find_if(revNodalPtr+revNodalIndxPtr[nodeId],revNodalPtr+revNodalIndxPtr[nodeId+1],std::bind2nd(std::equal_to<int>(),-1))=eltId;
2002         }
2003     }
2004 }
2005
2006 void MEDCoupling1DGTUMesh::checkFullyDefined() const throw(INTERP_KERNEL::Exception)
2007 {
2008   if(!((const DataArrayInt *)_conn) || !((const DataArrayInt *)_conn_indx) || !((const DataArrayDouble *)_coords))
2009     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFullyDefined : part of this is not fully defined.");
2010 }
2011
2012 bool MEDCoupling1DGTUMesh::isEmptyMesh(const std::vector<int>& tinyInfo) const
2013 {
2014   throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEmptyMesh : not implemented yet !");
2015 }
2016
2017 /*!
2018  * Finds nodes not used in any cell and returns an array giving a new id to every node
2019  * by excluding the unused nodes, for which the array holds -1. The result array is
2020  * a mapping in "Old to New" mode. 
2021  *  \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
2022  *  \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a
2023  *          this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
2024  *          if the node is unused or a new id else. The caller is to delete this
2025  *          array using decrRef() as it is no more needed.  
2026  *  \throw If the coordinates array is not set.
2027  *  \throw If the nodal connectivity of cells is not defined.
2028  *  \throw If the nodal connectivity includes an invalid id.
2029  */
2030 DataArrayInt *MEDCoupling1DGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const throw(INTERP_KERNEL::Exception)
2031 {
2032   nbrOfNodesInUse=-1;
2033   int nbOfNodes=getNumberOfNodes();
2034   int nbOfCells=getNumberOfCells();//checkCoherency
2035   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2036   ret->alloc(nbOfNodes,1);
2037   int *traducer=ret->getPointer();
2038   std::fill(traducer,traducer+nbOfNodes,-1);
2039   const int *conn=_conn->begin(),*conni(_conn_indx->begin());
2040   for(int i=0;i<nbOfCells;i++,conni++)
2041     {
2042       int nbNodesPerCell=conni[1]-conni[0];
2043       for(int j=0;j<nbNodesPerCell;j++)
2044         {
2045           int nodeId=conn[conni[0]+j];
2046           if(nodeId==-1) continue;
2047           if(nodeId>=0 && nodeId<nbOfNodes)
2048             traducer[*conn]=1;
2049           else
2050             {
2051               std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsInUse : In cell #" << i  << " presence of node id " <<  nodeId << " not in [0," << nbOfNodes << ") !";
2052               throw INTERP_KERNEL::Exception(oss.str().c_str());
2053             }
2054         }
2055     }
2056   nbrOfNodesInUse=(int)std::count(traducer,traducer+nbOfNodes,1);
2057   std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
2058   return ret.retn();
2059 }
2060
2061 /*!
2062  * Changes ids of nodes within the nodal connectivity arrays according to a permutation
2063  * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
2064  * This method is a generalization of shiftNodeNumbersInConn().
2065  *  \warning This method performs no check of validity of new ids. **Use it with care !**
2066  *  \param [in] newNodeNumbersO2N - a permutation array, of length \a
2067  *         this->getNumberOfNodes(), in "Old to New" mode. 
2068  *         See \ref MEDCouplingArrayRenumbering for more info on renumbering modes.
2069  *  \throw If the nodal connectivity of cells is not defined.
2070  */
2071 void MEDCoupling1DGTUMesh::renumberNodesInConn(const int *newNodeNumbersO2N)
2072 {
2073   getNumberOfCells();//only to check that all is well defined.
2074   //
2075   int nbElemsIn=getNumberOfNodes();
2076   int nbOfTuples=_conn->getNumberOfTuples();
2077   int *pt=_conn->getPointer();
2078   for(int i=0;i<nbOfTuples;i++,pt++)
2079     {
2080       if(*pt==-1) continue;
2081       if(*pt>=0 && *pt<nbElemsIn)
2082         *pt=newNodeNumbersO2N[*pt];
2083       else
2084         {
2085           std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberNodesInConn : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn;
2086           throw INTERP_KERNEL::Exception(oss.str().c_str());
2087         }
2088     }
2089   _conn->declareAsNew();
2090   //
2091   updateTime();
2092 }
2093
2094 /*!
2095  * Keeps from \a this only cells which constituing point id are in the ids specified by [\a begin,\a end).
2096  * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
2097  * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not.
2098  * If \a fullyIn is true only cells whose ids are \b fully contained in [\a begin,\a end) tab will be kept.
2099  *
2100  * \param [in] begin input start of array of node ids.
2101  * \param [in] end input end of array of node ids.
2102  * \param [in] fullyIn input that specifies if all node ids must be in [\a begin,\a end) array to consider cell to be in.
2103  * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end.
2104  */
2105 void MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const
2106 {
2107   int nbOfCells=getNumberOfCells();
2108   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1);
2109   int tmp=-1;
2110   int sz=_conn->getMaxValue(tmp); sz=std::max(sz,0)+1;
2111   std::vector<bool> fastFinder(sz,false);
2112   for(const int *work=begin;work!=end;work++)
2113     if(*work>=0 && *work<sz)
2114       fastFinder[*work]=true;
2115   const int *conn=_conn->begin(),*conni=_conn_indx->begin();
2116   for(int i=0;i<nbOfCells;i++,conni++)
2117     {
2118       int ref=0,nbOfHit=0;
2119       int nbNodesPerCell=conni[1]-conni[0];
2120       if(nbNodesPerCell>=0)
2121         {
2122           for(int j=0;j<nbNodesPerCell;j++)
2123             {
2124               int nodeId=conn[conni[0]+j];
2125               if(nodeId>=0)
2126                 {
2127                   ref++;
2128                   if(fastFinder[nodeId])
2129                     nbOfHit++;
2130                 }
2131             }
2132         }
2133       else
2134         {
2135           std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds : invalid index array for cell #" << i << " !";
2136           throw INTERP_KERNEL::Exception(oss.str().c_str());
2137         }
2138       if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn))
2139         cellIdsKept->pushBackSilent(i);
2140     }
2141   cellIdsKeptArr=cellIdsKept.retn();
2142 }
2143
2144 void MEDCoupling1DGTUMesh::allocateCells(int nbOfCells) throw(INTERP_KERNEL::Exception)
2145 {
2146   if(nbOfCells<0)
2147     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::allocateCells : the input number of cells should be >= 0 !");
2148   _conn=DataArrayInt::New();
2149   _conn->reserve(nbOfCells*3);
2150   _conn_indx=DataArrayInt::New();
2151   _conn_indx->reserve(nbOfCells+1); _conn_indx->pushBackSilent(0);
2152   declareAsNew();
2153 }
2154
2155 /*!
2156  * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ).
2157  *
2158  * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add.
2159  * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
2160  * \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
2161  *        attached to \a this.
2162  * \thow If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
2163  */
2164 void MEDCoupling1DGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd) throw(INTERP_KERNEL::Exception)
2165 {
2166   int sz=(int)std::distance(nodalConnOfCellBg,nodalConnOfCellEnd);
2167   DataArrayInt *c(_conn),*c2(_conn_indx);
2168   if(c && c2)
2169     {
2170       int pos=c2->back();
2171       if(pos==c->getNumberOfTuples())
2172         {
2173           c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd);
2174           c2->pushBackSilent(pos+sz);
2175         }
2176       else
2177         {
2178           std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::insertNextCell : The nodal index array (end=" << pos << ") mismatches with nodal array (length=" << c->getNumberOfTuples() << ") !";
2179           throw INTERP_KERNEL::Exception(oss.str().c_str());
2180         }
2181     }
2182   else
2183     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1DGTUMesh::allocateCells before !");
2184 }
2185
2186 void MEDCoupling1DGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn, DataArrayInt *nodalConnIndex) throw(INTERP_KERNEL::Exception)
2187 {
2188   if(nodalConn)
2189     nodalConn->incrRef();
2190   _conn=nodalConn;
2191   if(nodalConnIndex)
2192     nodalConnIndex->incrRef();
2193   _conn_indx=nodalConnIndex;
2194   declareAsNew();
2195 }
2196
2197 /*!
2198  * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it.
2199  */
2200 DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivity() const throw(INTERP_KERNEL::Exception)
2201 {
2202   const DataArrayInt *ret(_conn);
2203   return const_cast<DataArrayInt *>(ret);
2204 }
2205
2206 /*!
2207  * \return DataArrayInt * - the internal reference to the nodal connectivity index. The caller is not reponsible to deallocate it.
2208  */
2209 DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivityIndex() const throw(INTERP_KERNEL::Exception)
2210 {
2211   const DataArrayInt *ret(_conn_indx);
2212   return const_cast<DataArrayInt *>(ret);
2213 }
2214
2215 /*!
2216  * See the definition of the nodal connectivity pack \ref MEDCoupling1DGTUMesh::isPacked "here".
2217  * This method tries to build a new instance geometrically equivalent to \a this, by limiting at most the number of new object (nodal connectivity).
2218  * 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.
2219  *
2220  * 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.
2221  * 
2222  * \param [out] isShallowCpyOfNodalConnn - tells if the returned instance share the same pair of nodal connectivity arrays (true) or if nodal
2223  *              connectivity arrays are different (false)
2224  * \return a new object to be managed by the caller.
2225  * 
2226  * \sa MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity, MEDCoupling1DGTUMesh::isPacked
2227  */
2228 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::copyWithNodalConnectivityPacked(bool& isShallowCpyOfNodalConnn) const throw(INTERP_KERNEL::Exception)
2229 {
2230   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
2231   DataArrayInt *nc=0,*nci=0;
2232   isShallowCpyOfNodalConnn=retrievePackedNodalConnectivity(nc,nci);
2233   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ncs(nc),ncis(nci);
2234   ret->_conn=ncs; ret->_conn_indx=ncis;
2235   ret->setCoords(getCoords());
2236   return ret.retn();
2237 }
2238
2239 /*!
2240  * This method allows to compute, if needed, the packed nodal connectivity pair.
2241  * Indeed, it is possible to store in \a this a nodal connectivity array bigger than ranges convered by nodal connectivity index array.
2242  * 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.
2243  * 
2244  * 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)
2245  * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
2246  *
2247  * 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
2248  * will be returned.
2249  * 
2250  * This method return 3 elements.
2251  * \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
2252  *                          this pointer can be seen as a new object, that is to managed by the caller.
2253  * \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
2254  *                              this pointer can be seen as a new object, that is to managed by the caller.
2255  * \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
2256  * output parameters are newly created objects.
2257  *
2258  * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkCoherency test
2259  */
2260 bool MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity(DataArrayInt *&nodalConn, DataArrayInt *&nodalConnIndx) const throw(INTERP_KERNEL::Exception)
2261 {
2262   if(isPacked())//performs the checkCoherency
2263     {
2264       const DataArrayInt *c0(_conn),*c1(_conn_indx);
2265       nodalConn=const_cast<DataArrayInt *>(c0); nodalConnIndx=const_cast<DataArrayInt *>(c1);
2266       nodalConn->incrRef(); nodalConnIndx->incrRef();
2267       return true;
2268     }
2269   int bg=_conn_indx->front(),end=_conn_indx->back();
2270   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nc(_conn->selectByTupleId2(bg,end,1));
2271   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nci(_conn_indx->deepCpy());
2272   nci->applyLin(1,-bg);
2273   nodalConn=nc.retn(); nodalConnIndx=nci.retn();
2274   return false;
2275 }
2276
2277 /*
2278  * 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)
2279  * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
2280  * If nodal connectivity index points to a subpart of nodal connectivity index false will be returned.
2281  * \return bool - true if \a this looks packed, false is not.
2282  *
2283  * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkCoherency test
2284  */
2285 bool MEDCoupling1DGTUMesh::isPacked() const throw(INTERP_KERNEL::Exception)
2286 {
2287   checkCoherency();
2288   return _conn_indx->front()==0 && _conn_indx->back()==_conn->getNumberOfTuples();
2289 }
2290
2291 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(const MEDCoupling1DGTUMesh *mesh1, const MEDCoupling1DGTUMesh *mesh2) throw(INTERP_KERNEL::Exception)
2292 {
2293   std::vector<const MEDCoupling1DGTUMesh *> tmp(2);
2294   tmp[0]=const_cast<MEDCoupling1DGTUMesh *>(mesh1); tmp[1]=const_cast<MEDCoupling1DGTUMesh *>(mesh2);
2295   return Merge1DGTUMeshes(tmp);
2296 }
2297
2298 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(std::vector<const MEDCoupling1DGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
2299 {
2300   std::size_t sz=a.size();
2301   if(sz==0)
2302     return Merge1DGTUMeshesLL(a);
2303   for(std::size_t ii=0;ii<sz;ii++)
2304     if(!a[ii])
2305       {
2306         std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::Merge1DGTUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !";
2307         throw INTERP_KERNEL::Exception(oss.str().c_str());
2308       }
2309   const INTERP_KERNEL::CellModel *cm=&(a[0]->getCellModel());
2310   for(std::size_t ii=0;ii<sz;ii++)
2311     if(&(a[ii]->getCellModel())!=cm)
2312       throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : all items must have the same geo type !");
2313   std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > bb(sz);
2314   std::vector< const MEDCoupling1DGTUMesh * > aa(sz);
2315   int spaceDim=-3;
2316   for(std::size_t i=0;i<sz && spaceDim==-3;i++)
2317     {
2318       const MEDCoupling1DGTUMesh *cur=a[i];
2319       const DataArrayDouble *coo=cur->getCoords();
2320       if(coo)
2321         spaceDim=coo->getNumberOfComponents();
2322     }
2323   if(spaceDim==-3)
2324     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : no spaceDim specified ! unable to perform merge !");
2325   for(std::size_t i=0;i<sz;i++)
2326     {
2327       bb[i]=a[i]->buildSetInstanceFromThis(spaceDim);
2328       aa[i]=bb[i];
2329     }
2330   return Merge1DGTUMeshesLL(aa);
2331 }
2332
2333 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords(std::vector<const MEDCoupling1DGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
2334 {
2335   if(a.empty())
2336     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : input array must be NON EMPTY !");
2337   std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin();
2338   if(!(*it))
2339     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : presence of null instance !");
2340   std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > objs(a.size());
2341   std::vector<const DataArrayInt *> ncs(a.size()),ncis(a.size());
2342   int nbOfCells=(*it)->getNumberOfCells();
2343   const DataArrayDouble *coords=(*it)->getCoords();
2344   const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
2345   bool tmp;
2346   objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp);
2347   ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex();
2348   it++;
2349   for(int i=1;it!=a.end();i++,it++)
2350     {
2351       if(cm!=&((*it)->getCellModel()))
2352         throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !");
2353       (*it)->getNumberOfCells();//to check that all is OK
2354       objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp);
2355       ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex();
2356       if(coords!=(*it)->getCoords())
2357         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : not lying on same coords !");
2358     }
2359   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm));
2360   ret->setCoords(coords);
2361   ret->_conn=DataArrayInt::Aggregate(ncs);
2362   ret->_conn_indx=DataArrayInt::AggregateIndexes(ncis);
2363   return ret.retn();
2364 }
2365
2366 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesLL(std::vector<const MEDCoupling1DGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
2367 {
2368   //tony
2369 }
2370
2371 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::buildSetInstanceFromThis(int spaceDim) const throw(INTERP_KERNEL::Exception)
2372 {
2373   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
2374   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1,tmp2;
2375   const DataArrayInt *nodalConn(_conn),*nodalConnI(_conn_indx);
2376   if(!nodalConn)
2377     {
2378       tmp1=DataArrayInt::New(); tmp1->alloc(0,1);
2379     }
2380   else
2381     tmp1=_conn;
2382   ret->_conn=tmp1;
2383   //
2384   if(!nodalConnI)
2385     {
2386       tmp2=DataArrayInt::New(); tmp2->alloc(1,1); tmp2->setIJ(0,0,0);
2387     }
2388   else
2389     tmp2=_conn_indx;
2390   ret->_conn_indx=tmp2;
2391   //
2392   if(!_coords)
2393     {
2394       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim);
2395       ret->setCoords(coords);
2396     }
2397   else
2398     ret->setCoords(_coords);
2399   return ret.retn();
2400 }