Salome HOME
002298a14829ccd5696bd475c6a1cbd9716fe655
[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 /*!
388  * This method behaves mostly like MEDCoupling1SGTUMesh::deepCpy method, except that only nodal connectivity arrays are deeply copied.
389  * The coordinates are shared between \a this and the returned instance.
390  * 
391  * \return MEDCouplingUMesh * - A new object instance holding the copy of \a this (deep for connectivity, shallow for coordiantes)
392  * \sa MEDCoupling1SGTUMesh::deepCpy
393  */
394 MEDCouplingPointSet *MEDCoupling1SGTUMesh::deepCpyConnectivityOnly() const throw(INTERP_KERNEL::Exception)
395 {
396   checkCoherency();
397   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(clone(false));
398   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(_conn->deepCpy());
399   ret->setNodalConnectivity(c);
400   return ret.retn();
401 }
402
403 void MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other) throw(INTERP_KERNEL::Exception)
404 {
405   if(!other)
406     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom : input pointer is null !");
407   const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
408   if(!otherC)
409     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1SGTUMesh instance !");
410   setNodalConnectivity(otherC->getNodalConnectivity());
411 }
412
413 void MEDCoupling1SGTUMesh::updateTime() const
414 {
415   MEDCoupling1GTUMesh::updateTime();
416   const DataArrayInt *c(_conn);
417   if(c)
418     updateTimeWith(*c);
419 }
420
421 std::size_t MEDCoupling1SGTUMesh::getHeapMemorySize() const
422 {
423   std::size_t ret=0;
424   const DataArrayInt *c(_conn);
425   if(c)
426     ret+=c->getHeapMemorySize();
427   return MEDCoupling1GTUMesh::getHeapMemorySize()+ret;
428 }
429
430 MEDCouplingMesh *MEDCoupling1SGTUMesh::deepCpy() const
431 {
432   return clone(true);
433 }
434
435 bool MEDCoupling1SGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception)
436 {
437   if(!other)
438     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEqualIfNotWhy : input other pointer is null !");
439   std::ostringstream oss; oss.precision(15);
440   const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
441   if(!otherC)
442     {
443       reason="mesh given in input is not castable in MEDCoupling1SGTUMesh !";
444       return false;
445     }
446   if(!MEDCoupling1GTUMesh::isEqualIfNotWhy(other,prec,reason))
447     return false;
448   const DataArrayInt *c1(_conn),*c2(otherC->_conn);
449   if(c1==c2)
450     return true;
451   if(!c1 || !c2)
452     {
453       reason="in connectivity of single static geometric type exactly one among this and other is null !";
454       return false;
455     }
456   if(!c1->isEqualIfNotWhy(*c2,reason))
457     {
458       reason.insert(0,"Nodal connectivity DataArrayInt differ : ");
459       return false;
460     }
461   return true;
462 }
463
464 bool MEDCoupling1SGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
465 {
466   if(!other)
467     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
468   const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
469   if(!otherC)
470     return false;
471   if(!MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(other,prec))
472     return false;
473   const DataArrayInt *c1(_conn),*c2(otherC->_conn);
474   if(c1==c2)
475     return true;
476   if(!c1 || !c2)
477     return false;
478   if(!c1->isEqualWithoutConsideringStr(*c2))
479     return false;
480   return true;
481 }
482
483 void MEDCoupling1SGTUMesh::checkCoherency() const throw(INTERP_KERNEL::Exception)
484 {
485   MEDCouplingPointSet::checkCoherency();
486   const DataArrayInt *c1(_conn);
487   if(c1)
488     {
489       if(c1->getNumberOfComponents()!=1)
490         throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !");
491       if(c1->getInfoOnComponent(0)!="")
492         throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !");
493       c1->checkAllocated();
494     }
495   else
496     throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !");
497 }
498
499 void MEDCoupling1SGTUMesh::checkCoherency1(double eps) const throw(INTERP_KERNEL::Exception)
500 {
501   checkCoherency();
502   const DataArrayInt *c1(_conn);
503   int nbOfTuples=c1->getNumberOfTuples();
504   int nbOfNodesPerCell=(int)_cm->getNumberOfNodes();
505   if(nbOfTuples%nbOfNodesPerCell!=0)
506     {
507       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 !";
508       throw INTERP_KERNEL::Exception(oss.str().c_str());
509     }
510   int nbOfNodes=getNumberOfNodes();
511   int nbOfCells=nbOfTuples/nbOfNodesPerCell;
512   const int *w(c1->begin());
513   for(int i=0;i<nbOfCells;i++)
514     for(int j=0;j<nbOfNodesPerCell;j++,w++)
515       {
516         if(*w<0 || *w>=nbOfNodes)
517           {
518             std::ostringstream oss; oss << "At node #" << j << " of  cell #" << i << ", is equal to " << *w << " must be in [0," << nbOfNodes << ") !";
519             throw INTERP_KERNEL::Exception(oss.str().c_str());
520           }
521       }
522 }
523
524 void MEDCoupling1SGTUMesh::checkCoherency2(double eps) const throw(INTERP_KERNEL::Exception)
525 {
526   checkCoherency1(eps);
527 }
528
529 int MEDCoupling1SGTUMesh::getNumberOfCells() const
530 {
531   int nbOfTuples=getNodalConnectivityLength();
532   int nbOfNodesPerCell=getNumberOfNodesPerCell();
533   if(nbOfTuples%nbOfNodesPerCell!=0)
534     {
535       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 !";
536       throw INTERP_KERNEL::Exception(oss.str().c_str());
537     }
538   return nbOfTuples/nbOfNodesPerCell;
539 }
540
541 int MEDCoupling1SGTUMesh::getNumberOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
542 {
543   checkNonDynamicGeoType();
544   return (int)_cm->getNumberOfNodes();
545 }
546
547 int MEDCoupling1SGTUMesh::getNodalConnectivityLength() const throw(INTERP_KERNEL::Exception)
548 {
549   const DataArrayInt *c1(_conn);
550   if(!c1)
551     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::getNodalConnectivityLength : no connectivity set !");
552   if(c1->getNumberOfComponents()!=1)
553     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::getNodalConnectivityLength : Nodal connectivity array set must have exactly one component !");
554   if(!c1->isAllocated())
555     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::getNodalConnectivityLength : Nodal connectivity array must be allocated !");
556   return c1->getNumberOfTuples();
557 }
558
559 DataArrayInt *MEDCoupling1SGTUMesh::computeNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
560 {
561   checkNonDynamicGeoType();
562   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
563   ret->alloc(getNumberOfCells(),1);
564   ret->fillWithValue((int)_cm->getNumberOfNodes());
565   return ret.retn();
566 }
567
568 DataArrayInt *MEDCoupling1SGTUMesh::computeNbOfFacesPerCell() const throw(INTERP_KERNEL::Exception)
569 {
570   checkNonDynamicGeoType();
571   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
572   ret->alloc(getNumberOfCells(),1);
573   ret->fillWithValue((int)_cm->getNumberOfSons());
574   return ret.retn();
575 }
576
577 void MEDCoupling1SGTUMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
578 {
579   int sz=getNumberOfNodesPerCell();
580   conn.resize(sz);
581   if(cellId>=0 && cellId<getNumberOfCells())
582     std::copy(_conn->begin()+cellId*sz,_conn->begin()+(cellId+1)*sz,conn.begin());
583   else
584     {
585       std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << getNumberOfCells() << ") !";
586       throw INTERP_KERNEL::Exception(oss.str().c_str());
587     }
588 }
589
590 void MEDCoupling1SGTUMesh::checkNonDynamicGeoType() const throw(INTERP_KERNEL::Exception)
591 {
592   if(_cm->isDynamic())
593     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkNonDynamicGeoType : internal error ! the internal geo type is dynamic ! should be static !");
594 }
595
596 std::string MEDCoupling1SGTUMesh::simpleRepr() const
597 {
598   static const char msg0[]="No coordinates specified !";
599   std::ostringstream ret;
600   ret << "Single static geometic type (" << _cm->getRepr() << ") unstructured mesh with name : \"" << getName() << "\"\n";
601   ret << "Description of mesh : \"" << getDescription() << "\"\n";
602   int tmpp1,tmpp2;
603   double tt=getTime(tmpp1,tmpp2);
604   ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
605   ret << "Iteration : " << tmpp1  << " Order : " << tmpp2 << "\n";
606   ret << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : ";
607   if(_coords!=0)
608     {
609       const int spaceDim=getSpaceDimension();
610       ret << spaceDim << "\nInfo attached on space dimension : ";
611       for(int i=0;i<spaceDim;i++)
612         ret << "\"" << _coords->getInfoOnComponent(i) << "\" ";
613       ret << "\n";
614     }
615   else
616     ret << msg0 << "\n";
617   ret << "Number of nodes : ";
618   if(_coords!=0)
619     ret << getNumberOfNodes() << "\n";
620   else
621     ret << msg0 << "\n";
622   ret << "Number of cells : ";
623   if((const DataArrayInt *)_conn)
624     {
625       if(_conn->isAllocated())
626         {
627           if(_conn->getNumberOfComponents()==1)
628             ret << getNumberOfCells() << "\n";
629           else
630             ret << "Nodal connectivity array specified and allocated but with not exactly one component !" << "\n";
631         }
632       else
633         ret << "Nodal connectivity array specified but not allocated !" << "\n";
634     }
635   else
636     ret << "No connectivity specified !" << "\n";
637   ret << "Cell type : " << _cm->getRepr() << "\n";
638   return ret.str();
639 }
640
641 std::string MEDCoupling1SGTUMesh::advancedRepr() const
642 {
643   std::ostringstream ret;
644   ret << simpleRepr();
645   ret << "\nCoordinates array : \n___________________\n\n";
646   if(_coords)
647     _coords->reprWithoutNameStream(ret);
648   else
649     ret << "No array set !\n";
650   ret << "\n\nConnectivity array : \n____________________\n\n";
651   //
652   if((const DataArrayInt *)_conn)
653     {
654       if(_conn->isAllocated())
655         {
656           if(_conn->getNumberOfComponents()==1)
657             {
658              int nbOfCells=getNumberOfCells();
659              int sz=getNumberOfNodesPerCell();
660              const int *connPtr=_conn->begin();
661              for(int i=0;i<nbOfCells;i++,connPtr+=sz)
662                {
663                  ret << "Cell #" << i << " : ";
664                  std::copy(connPtr,connPtr+sz,std::ostream_iterator<int>(ret," "));
665                  ret << "\n";
666                }
667             }
668           else
669             ret << "Nodal connectivity array specified and allocated but with not exactly one component !" << "\n";
670         }
671       else
672         ret << "Nodal connectivity array specified but not allocated !" << "\n";
673     }
674   else
675     ret << "No connectivity specified !" << "\n";
676   return ret.str();
677 }
678
679 DataArrayDouble *MEDCoupling1SGTUMesh::computeIsoBarycenterOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
680 {
681   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
682   int spaceDim=getSpaceDimension();
683   int nbOfCells=getNumberOfCells();//checkCoherency()
684   int nbOfNodes=getNumberOfNodes();
685   ret->alloc(nbOfCells,spaceDim);
686   double *ptToFill=ret->getPointer();
687   const double *coor=_coords->begin();
688   const int *nodal=_conn->begin();
689   int sz=getNumberOfNodesPerCell();
690   double coeff=1./(double)sz;
691   for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim)
692     {
693       std::fill(ptToFill,ptToFill+spaceDim,0.);
694       for(int j=0;j<sz;j++,nodal++)
695         if(*nodal>=0 && *nodal<nbOfNodes)
696           std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
697         else
698           {
699             std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," <<   nbOfNodes << ") !";
700             throw INTERP_KERNEL::Exception(oss.str().c_str());
701           }
702       std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),coeff));
703     }
704   return ret.retn();
705 }
706
707 void MEDCoupling1SGTUMesh::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception)
708 {
709   int nbCells=getNumberOfCells();
710   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::New();
711   o2n->useArray(old2NewBg,false,C_DEALLOC,nbCells,1);
712   if(check)
713     o2n=o2n->checkAndPreparePermutation();
714   //
715   const int *conn=_conn->begin();
716   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> n2o=o2n->invertArrayO2N2N2O(nbCells);
717   const int *n2oPtr=n2o->begin();
718   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New();
719   newConn->alloc(_conn->getNumberOfTuples(),1);
720   newConn->copyStringInfoFrom(*_conn);
721   int sz=getNumberOfNodesPerCell();
722   //
723   int *newC=newConn->getPointer();
724   for(int i=0;i<nbCells;i++,newC+=sz)
725     {
726       int pos=n2oPtr[i];
727       std::copy(conn+pos*sz,conn+(pos+1)*sz,newC);
728     }
729   _conn=newConn;
730 }
731
732 /*!
733  * Keeps from \a this only cells which constituing point id are in the ids specified by [\a begin,\a end).
734  * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
735  * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not.
736  * If \a fullyIn is true only cells whose ids are \b fully contained in [\a begin,\a end) tab will be kept.
737  *
738  * \param [in] begin input start of array of node ids.
739  * \param [in] end input end of array of node ids.
740  * \param [in] fullyIn input that specifies if all node ids must be in [\a begin,\a end) array to consider cell to be in.
741  * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end.
742  */
743 void MEDCoupling1SGTUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const
744 {
745   int nbOfCells=getNumberOfCells();
746   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1);
747   int tmp=-1;
748   int sz=_conn->getMaxValue(tmp); sz=std::max(sz,0)+1;
749   std::vector<bool> fastFinder(sz,false);
750   for(const int *work=begin;work!=end;work++)
751     if(*work>=0 && *work<sz)
752       fastFinder[*work]=true;
753   const int *conn=_conn->begin();
754   int nbNodesPerCell=getNumberOfNodesPerCell();
755   for(int i=0;i<nbOfCells;i++,conn+=nbNodesPerCell)
756     {
757       int ref=0,nbOfHit=0;
758       for(int j=0;j<nbNodesPerCell;j++)
759         if(conn[j]>=0)
760           {
761             ref++;
762             if(fastFinder[conn[j]])
763               nbOfHit++;
764           }
765       if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn))
766         cellIdsKept->pushBackSilent(i);
767     }
768   cellIdsKeptArr=cellIdsKept.retn();
769 }
770
771 MEDCouplingMesh *MEDCoupling1SGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
772 {
773   if(other->getType()!=SINGLE_STATIC_GEO_TYPE_UNSTRUCTURED)
774     throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single static geo type each other !");
775   const MEDCoupling1SGTUMesh *otherC=static_cast<const MEDCoupling1SGTUMesh *>(other);
776   return Merge1SGTUMeshes(this,otherC);
777 }
778
779 MEDCouplingUMesh *MEDCoupling1SGTUMesh::buildUnstructured() const throw(INTERP_KERNEL::Exception)
780 {
781   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName(),getMeshDimension());
782   ret->setCoords(getCoords());
783   const int *nodalConn=_conn->begin();
784   int nbCells=getNumberOfCells();
785   int nbNodesPerCell=getNumberOfNodesPerCell();
786   int geoType=(int)getCellModelEnum();
787   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New(); c->alloc(nbCells*(nbNodesPerCell+1),1);
788   int *cPtr=c->getPointer();
789   for(int i=0;i<nbCells;i++,nodalConn+=nbNodesPerCell)
790     {
791       *cPtr++=geoType;
792       cPtr=std::copy(nodalConn,nodalConn+nbNodesPerCell,cPtr);
793     }
794   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cI=DataArrayInt::Range(0,(nbCells+1)*(nbNodesPerCell+1),nbNodesPerCell+1);
795   ret->setConnectivity(c,cI,true);
796   return ret.retn();
797 }
798
799 DataArrayInt *MEDCoupling1SGTUMesh::simplexize(int policy) throw(INTERP_KERNEL::Exception)
800 {
801   switch(policy)
802     {
803     case 0:
804       return simplexizePol0();
805     case 1:
806       return simplexizePol1();
807     case (int) INTERP_KERNEL::PLANAR_FACE_5:
808       return simplexizePlanarFace5();
809     case (int) INTERP_KERNEL::PLANAR_FACE_6:
810       return simplexizePlanarFace6();
811     default:
812       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)");
813     }
814 }
815
816 /// @cond INTERNAL
817
818 struct MEDCouplingAccVisit
819 {
820   MEDCouplingAccVisit():_new_nb_of_nodes(0) { }
821   int operator()(int val) { if(val!=-1) return _new_nb_of_nodes++; else return -1; }
822   int _new_nb_of_nodes;
823 };
824
825 /// @endcond
826
827 /*!
828  * Finds nodes not used in any cell and returns an array giving a new id to every node
829  * by excluding the unused nodes, for which the array holds -1. The result array is
830  * a mapping in "Old to New" mode. 
831  *  \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
832  *  \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a
833  *          this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
834  *          if the node is unused or a new id else. The caller is to delete this
835  *          array using decrRef() as it is no more needed.  
836  *  \throw If the coordinates array is not set.
837  *  \throw If the nodal connectivity of cells is not defined.
838  *  \throw If the nodal connectivity includes an invalid id.
839  */
840 DataArrayInt *MEDCoupling1SGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const throw(INTERP_KERNEL::Exception)
841 {
842   nbrOfNodesInUse=-1;
843   int nbOfNodes=getNumberOfNodes();
844   int nbOfCells=getNumberOfCells();
845   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
846   ret->alloc(nbOfNodes,1);
847   int *traducer=ret->getPointer();
848   std::fill(traducer,traducer+nbOfNodes,-1);
849   const int *conn=_conn->begin();
850   int nbNodesPerCell=getNumberOfNodesPerCell();
851   for(int i=0;i<nbOfCells;i++)
852     for(int j=0;j<nbNodesPerCell;j++,conn++)
853       if(*conn>=0 && *conn<nbOfNodes)
854         traducer[*conn]=1;
855       else
856         {
857           std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsInUse : In cell #" << i  << " presence of node id " <<  conn[j] << " not in [0," << nbOfNodes << ") !";
858           throw INTERP_KERNEL::Exception(oss.str().c_str());
859         }
860   nbrOfNodesInUse=(int)std::count(traducer,traducer+nbOfNodes,1);
861   std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
862   return ret.retn();
863 }
864
865 /*!
866  * Changes ids of nodes within the nodal connectivity arrays according to a permutation
867  * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
868  * This method is a generalization of shiftNodeNumbersInConn().
869  *  \warning This method performs no check of validity of new ids. **Use it with care !**
870  *  \param [in] newNodeNumbersO2N - a permutation array, of length \a
871  *         this->getNumberOfNodes(), in "Old to New" mode. 
872  *         See \ref MEDCouplingArrayRenumbering for more info on renumbering modes.
873  *  \throw If the nodal connectivity of cells is not defined.
874  */
875 void MEDCoupling1SGTUMesh::renumberNodesInConn(const int *newNodeNumbersO2N)
876 {
877   getNumberOfCells();//only to check that all is well defined.
878   _conn->transformWithIndArr(newNodeNumbersO2N,newNodeNumbersO2N+getNumberOfNodes());
879   updateTime();
880 }
881
882 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(const MEDCoupling1SGTUMesh *mesh1, const MEDCoupling1SGTUMesh *mesh2) throw(INTERP_KERNEL::Exception)
883 {
884   std::vector<const MEDCoupling1SGTUMesh *> tmp(2);
885   tmp[0]=const_cast<MEDCoupling1SGTUMesh *>(mesh1); tmp[1]=const_cast<MEDCoupling1SGTUMesh *>(mesh2);
886   return Merge1SGTUMeshes(tmp);
887 }
888
889 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(std::vector<const MEDCoupling1SGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
890 {
891   std::size_t sz=a.size();
892   if(sz==0)
893     return Merge1SGTUMeshesLL(a);
894   for(std::size_t ii=0;ii<sz;ii++)
895     if(!a[ii])
896       {
897         std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::Merge1SGTUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !";
898         throw INTERP_KERNEL::Exception(oss.str().c_str());
899       }
900   const INTERP_KERNEL::CellModel *cm=&(a[0]->getCellModel());
901   for(std::size_t ii=0;ii<sz;ii++)
902     if(&(a[ii]->getCellModel())!=cm)
903       throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : all items must have the same geo type !");
904   std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> > bb(sz);
905   std::vector< const MEDCoupling1SGTUMesh * > aa(sz);
906   int spaceDim=-3;
907   for(std::size_t i=0;i<sz && spaceDim==-3;i++)
908     {
909       const MEDCoupling1SGTUMesh *cur=a[i];
910       const DataArrayDouble *coo=cur->getCoords();
911       if(coo)
912         spaceDim=coo->getNumberOfComponents();
913     }
914   if(spaceDim==-3)
915     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : no spaceDim specified ! unable to perform merge !");
916   for(std::size_t i=0;i<sz;i++)
917     {
918       bb[i]=a[i]->buildSetInstanceFromThis(spaceDim);
919       aa[i]=bb[i];
920     }
921   return Merge1SGTUMeshesLL(aa);
922 }
923
924 /*!
925  * \throw If presence of a null instance in the input vector \a a.
926  * \throw If a is empty
927  */
928 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords(std::vector<const MEDCoupling1SGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
929 {
930   if(a.empty())
931     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : input array must be NON EMPTY !");
932   std::vector<const MEDCoupling1SGTUMesh *>::const_iterator it=a.begin();
933   if(!(*it))
934     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : null instance in the first element of input vector !");
935   std::vector<const DataArrayInt *> ncs(a.size());
936   int nbOfCells=(*it)->getNumberOfCells();
937   const DataArrayDouble *coords=(*it)->getCoords();
938   const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
939   int nbNodesPerCell=(*it)->getNumberOfNodesPerCell();
940   ncs[0]=(*it)->getNodalConnectivity();
941   it++;
942   for(int i=1;it!=a.end();i++,it++)
943     {
944       if(!(*it))
945         throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : presence of a null instance in the input vector !");
946       if(cm!=&((*it)->getCellModel()))
947         throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !");
948       (*it)->getNumberOfCells();//to check that all is OK
949       ncs[i]=(*it)->getNodalConnectivity();
950       if(coords!=(*it)->getCoords())
951         throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : not lying on same coords !");
952     }
953   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh("merge",*cm));
954   ret->setCoords(coords);
955   ret->_conn=DataArrayInt::Aggregate(ncs);
956   return ret.retn();
957 }
958
959 /*!
960  * Assume that all instances in \a a are non null. If null it leads to a crash. That's why this method is assigned to be low level (LL)
961  */
962 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesLL(std::vector<const MEDCoupling1SGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
963 {
964   if(a.empty())
965     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : input array must be NON EMPTY !");
966   std::vector<const MEDCoupling1SGTUMesh *>::const_iterator it=a.begin();
967   int nbOfCells=(*it)->getNumberOfCells();
968   const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
969   int nbNodesPerCell=(*it)->getNumberOfNodesPerCell();
970   it++;
971   for(;it!=a.end();it++)
972     {
973       if(cm!=&((*it)->getCellModel()))
974         throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !");
975       nbOfCells+=(*it)->getNumberOfCells();
976     }
977   std::vector<const MEDCouplingPointSet *> aps(a.size());
978   std::copy(a.begin(),a.end(),aps.begin());
979   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> pts=MergeNodesArray(aps);
980   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh("merge",*cm));
981   ret->setCoords(pts);
982   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New();
983   c->alloc(nbOfCells*nbNodesPerCell,1);
984   int *cPtr=c->getPointer();
985   int offset=0;
986   for(it=a.begin();it!=a.end();it++)
987     {
988       int curConnLgth=(*it)->getNodalConnectivityLength();
989       const int *curC=(*it)->_conn->begin();
990       cPtr=std::transform(curC,curC+curConnLgth,cPtr,std::bind2nd(std::plus<int>(),offset));
991       offset+=(*it)->getNumberOfNodes();
992     }
993   //
994   ret->setNodalConnectivity(c);
995   return ret.retn();
996 }
997
998 MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const
999 {
1000   int ncell=getNumberOfCells();
1001   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
1002   ret->setCoords(_coords);
1003   std::size_t nbOfElemsRet=std::distance(begin,end);
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   for(const int *work=begin;work!=end;work++,connPtr+=sz)
1009     {
1010       if(*work>=0 && *work<ncell)
1011         std::copy(inConn+(work[0])*sz,inConn+(work[0]+1)*sz,connPtr);
1012       else
1013         {
1014           std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords : On pos #" << std::distance(begin,work) << " input cell id =" << *work << " should be in [0," << ncell << ") !";
1015           throw INTERP_KERNEL::Exception(oss.str().c_str());
1016         }
1017     }
1018   ret->_conn=connRet;
1019   ret->copyTinyInfoFrom(this);
1020   return ret.retn();
1021 }
1022
1023 MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const
1024 {
1025   int ncell=getNumberOfCells();
1026   int nbOfElemsRet=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2 : ");
1027   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
1028   ret->setCoords(_coords);
1029   const int *inConn=_conn->getConstPointer();
1030   int sz=getNumberOfNodesPerCell();
1031   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connRet=DataArrayInt::New(); connRet->alloc((int)nbOfElemsRet*sz,1);
1032   int *connPtr=connRet->getPointer();
1033   int curId=start;
1034   for(int i=0;i<nbOfElemsRet;i++,connPtr+=sz,curId+=step)
1035     {
1036       if(curId>=0 && curId<ncell)
1037         std::copy(inConn+curId*sz,inConn+(curId+1)*sz,connPtr);
1038       else
1039         {
1040           std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2 : On pos #" << i << " input cell id =" << curId  << " should be in [0," << ncell << ") !";
1041           throw INTERP_KERNEL::Exception(oss.str().c_str());
1042         }
1043     }
1044   ret->_conn=connRet;
1045   ret->copyTinyInfoFrom(this);
1046   return ret.retn();
1047 }
1048
1049 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::buildSetInstanceFromThis(int spaceDim) const throw(INTERP_KERNEL::Exception)
1050 {
1051   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
1052   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1;
1053   const DataArrayInt *nodalConn(_conn);
1054   if(!nodalConn)
1055     {
1056       tmp1=DataArrayInt::New(); tmp1->alloc(0,1);
1057     }
1058   else
1059     tmp1=_conn;
1060   ret->_conn=tmp1;
1061   if(!_coords)
1062     {
1063       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim);
1064       ret->setCoords(coords);
1065     }
1066   else
1067     ret->setCoords(_coords);
1068   return ret.retn();
1069 }
1070
1071 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePol0() throw(INTERP_KERNEL::Exception)
1072 {
1073   int nbOfCells=getNumberOfCells();
1074   if(getCellModelEnum()!=INTERP_KERNEL::NORM_QUAD4)
1075     return DataArrayInt::Range(0,nbOfCells,1);
1076   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(2*3*nbOfCells,1);
1077   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(2*nbOfCells,1);
1078   const int *c(_conn->begin());
1079   int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1080   for(int i=0;i<nbOfCells;i++,c+=4,newConnPtr+=6,retPtr+=2)
1081     {
1082       newConnPtr[0]=c[0]; newConnPtr[1]=c[1]; newConnPtr[2]=c[2];
1083       newConnPtr[3]=c[0]; newConnPtr[4]=c[2]; newConnPtr[5]=c[3];
1084       retPtr[0]=i; retPtr[1]=i;
1085     }
1086   _conn=newConn;
1087   _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TRI3);
1088   updateTime();
1089   return ret.retn();
1090 }
1091
1092 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePol1() throw(INTERP_KERNEL::Exception)
1093 {
1094   int nbOfCells=getNumberOfCells();
1095   if(getCellModelEnum()!=INTERP_KERNEL::NORM_QUAD4)
1096     return DataArrayInt::Range(0,nbOfCells,1);
1097   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(2*3*nbOfCells,1);
1098   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(2*nbOfCells,1);
1099   const int *c(_conn->begin());
1100   int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1101   for(int i=0;i<nbOfCells;i++,c+=4,newConnPtr+=6,retPtr+=2)
1102     {
1103       newConnPtr[0]=c[0]; newConnPtr[1]=c[1]; newConnPtr[2]=c[3];
1104       newConnPtr[3]=c[1]; newConnPtr[4]=c[2]; newConnPtr[5]=c[3];
1105       retPtr[0]=i; retPtr[1]=i;
1106     }
1107   _conn=newConn;
1108   _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TRI3);
1109   updateTime();
1110   return ret.retn();
1111 }
1112
1113 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePlanarFace5() throw(INTERP_KERNEL::Exception)
1114 {
1115   int nbOfCells=getNumberOfCells();
1116   if(getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA8)
1117     return DataArrayInt::Range(0,nbOfCells,1);
1118   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(5*4*nbOfCells,1);
1119   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(5*nbOfCells,1);
1120   const int *c(_conn->begin());
1121   int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1122   for(int i=0;i<nbOfCells;i++,c+=8,newConnPtr+=20,retPtr+=5)
1123     {
1124       for(int j=0;j<20;j++)
1125         newConnPtr[j]=c[INTERP_KERNEL::SPLIT_NODES_5_WO[j]];
1126       retPtr[0]=i; retPtr[1]=i; retPtr[2]=i; retPtr[3]=i; retPtr[4]=i;
1127     }
1128   _conn=newConn;
1129   _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TETRA4);
1130   updateTime();
1131   return ret.retn();
1132 }
1133
1134 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePlanarFace6() throw(INTERP_KERNEL::Exception)
1135 {
1136   int nbOfCells=getNumberOfCells();
1137   if(getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA8)
1138     return DataArrayInt::Range(0,nbOfCells,1);
1139   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(6*4*nbOfCells,1);
1140   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(6*nbOfCells,1);
1141   const int *c(_conn->begin());
1142   int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1143   for(int i=0;i<nbOfCells;i++,c+=8,newConnPtr+=24,retPtr+=6)
1144     {
1145       for(int j=0;j<24;j++)
1146         newConnPtr[j]=c[INTERP_KERNEL::SPLIT_NODES_6_WO[j]];
1147       retPtr[0]=i; retPtr[1]=i; retPtr[2]=i; retPtr[3]=i; retPtr[4]=i; retPtr[5]=i;
1148     }
1149   _conn=newConn;
1150   _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TETRA4);
1151   updateTime();
1152   return ret.retn();
1153 }
1154
1155 void MEDCoupling1SGTUMesh::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1156 {
1157   stream << "MEDCoupling1SGTUMesh C++ instance at " << this << ". Type=" << _cm->getRepr() << ". Name : \"" << getName() << "\".";
1158   stream << " Mesh dimension : " << getMeshDimension() << ".";
1159   if(!_coords)
1160     { stream << " No coordinates set !"; return ; }
1161   if(!_coords->isAllocated())
1162     { stream << " Coordinates set but not allocated !"; return ; }
1163   stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
1164   stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
1165   if(!(const DataArrayInt *)_conn)
1166     { stream << std::endl << "Nodal connectivity NOT set !"; return ; }
1167   if(_conn->isAllocated())
1168     {
1169       if(_conn->getNumberOfComponents()==1)
1170         stream << std::endl << "Number of cells : " << getNumberOfCells() << ".";
1171     }
1172 }
1173
1174 void MEDCoupling1SGTUMesh::checkFullyDefined() const throw(INTERP_KERNEL::Exception)
1175 {
1176   if(!((const DataArrayInt *)_conn) || !((const DataArrayDouble *)_coords))
1177     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFullyDefined : part of this is not fully defined.");
1178 }
1179
1180 /*!
1181  * First step of unserialization process.
1182  */
1183 bool MEDCoupling1SGTUMesh::isEmptyMesh(const std::vector<int>& tinyInfo) const
1184 {
1185   throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEmptyMesh : not implemented yet !");
1186 }
1187
1188 /*!
1189  * Checks if \a this and \a other meshes are geometrically equivalent with high
1190  * probability, else an exception is thrown. The meshes are considered equivalent if
1191  * (1) meshes contain the same number of nodes and the same number of elements of the
1192  * same types (2) three cells of the two meshes (first, last and middle) are based
1193  * on coincident nodes (with a specified precision).
1194  *  \param [in] other - the mesh to compare with.
1195  *  \param [in] prec - the precision used to compare nodes of the two meshes.
1196  *  \throw If the two meshes do not match.
1197  */
1198 void MEDCoupling1SGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception)
1199 {
1200   MEDCouplingPointSet::checkFastEquivalWith(other,prec);
1201   const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
1202   if(!otherC)
1203     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : Two meshes are not not unstructured with single static geometric type !");
1204   const DataArrayInt *c1(_conn),*c2(otherC->_conn);
1205   if(c1==c2)
1206     return;
1207   if(!c1 || !c2)
1208     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !");
1209   if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
1210     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !");
1211   if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
1212     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !");
1213   if(c1->getHashCode()!=c2->getHashCode())
1214     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : nodal connectivity differs");
1215 }
1216
1217 MEDCouplingPointSet *MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const
1218 {
1219   if(!other)
1220     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : input other is null !");
1221   const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
1222   if(!otherC)
1223     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !");
1224   std::vector<const MEDCoupling1SGTUMesh *> ms(2);
1225   ms[0]=this;
1226   ms[1]=otherC;
1227   return Merge1SGTUMeshesOnSameCoords(ms);
1228 }
1229
1230 void MEDCoupling1SGTUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const throw(INTERP_KERNEL::Exception)
1231 {
1232   checkFullyDefined();
1233   int nbOfNodes=getNumberOfNodes();
1234   int *revNodalIndxPtr=(int *)malloc((nbOfNodes+1)*sizeof(int));
1235   revNodalIndx->useArray(revNodalIndxPtr,true,C_DEALLOC,nbOfNodes+1,1);
1236   std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
1237   const int *conn=_conn->begin();
1238   int nbOfCells=getNumberOfCells();
1239   int nbOfEltsInRevNodal=0;
1240   int nbOfNodesPerCell=getNumberOfNodesPerCell();
1241   for(int eltId=0;eltId<nbOfCells;eltId++)
1242     {
1243       for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1244         {
1245           if(conn[0]>=0 && conn[0]<nbOfNodes)
1246             {
1247               nbOfEltsInRevNodal++;
1248               revNodalIndxPtr[conn[0]+1]++;
1249             }
1250           else
1251             {
1252               std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !";
1253               throw INTERP_KERNEL::Exception(oss.str().c_str());
1254             }
1255         }
1256     }
1257   std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<int>());
1258   conn=_conn->begin();
1259   int *revNodalPtr=(int *)malloc((nbOfEltsInRevNodal)*sizeof(int));
1260   revNodal->useArray(revNodalPtr,true,C_DEALLOC,nbOfEltsInRevNodal,1);
1261   std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
1262   for(int eltId=0;eltId<nbOfCells;eltId++)
1263     {
1264       for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1265         {
1266           *std::find_if(revNodalPtr+revNodalIndxPtr[*conn],revNodalPtr+revNodalIndxPtr[*conn+1],std::bind2nd(std::equal_to<int>(),-1))=eltId;
1267         }
1268     }
1269 }
1270
1271 /*!
1272  * Use \a nodalConn array as nodal connectivity of \a this. The input \a nodalConn pointer can be null.
1273  */
1274 void MEDCoupling1SGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn) throw(INTERP_KERNEL::Exception)
1275 {
1276   if(nodalConn)
1277     nodalConn->incrRef();
1278   _conn=nodalConn;
1279   declareAsNew();
1280 }
1281
1282 /*!
1283  * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it.
1284  */
1285 DataArrayInt *MEDCoupling1SGTUMesh::getNodalConnectivity() const throw(INTERP_KERNEL::Exception)
1286 {
1287   const DataArrayInt *ret(_conn);
1288   return const_cast<DataArrayInt *>(ret);
1289 }
1290
1291 /*!
1292  * Allocates memory to store an estimation of the given number of cells. Closer is the estimation to the number of cells effectively inserted,
1293  * less will be the needs to realloc. If the number of cells to be inserted is not known simply put 0 to this parameter.
1294  * If a nodal connectivity previouly existed before the call of this method, it will be reset.
1295  *
1296  *  \param [in] nbOfCells - estimation of the number of cell \a this mesh will contain.
1297  */
1298 void MEDCoupling1SGTUMesh::allocateCells(int nbOfCells) throw(INTERP_KERNEL::Exception)
1299 {
1300   if(nbOfCells<0)
1301     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::allocateCells : the input number of cells should be >= 0 !");
1302   _conn=DataArrayInt::New();
1303   _conn->reserve(getNumberOfNodesPerCell()*nbOfCells);
1304   declareAsNew();
1305 }
1306
1307 /*!
1308  * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ).
1309  *
1310  * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add.
1311  * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
1312  * \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
1313  *        attached to \a this.
1314  * \thow If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
1315  */
1316 void MEDCoupling1SGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd) throw(INTERP_KERNEL::Exception)
1317 {
1318   int sz=(int)std::distance(nodalConnOfCellBg,nodalConnOfCellEnd);
1319   int ref=getNumberOfNodesPerCell();
1320   if(sz==ref)
1321     {
1322       DataArrayInt *c(_conn);
1323       if(c)
1324         c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd);
1325       else
1326         throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1SGTUMesh::allocateCells before !");
1327     }
1328   else
1329     {
1330       std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::insertNextCell : input nodal size (" << sz << ") does not match number of nodes per cell of this (";
1331       oss << ref << ") !";
1332       throw INTERP_KERNEL::Exception(oss.str().c_str());
1333     }
1334 }
1335
1336 //== find static tony
1337
1338 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const char *name, INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception)
1339 {
1340   if(type==INTERP_KERNEL::NORM_ERROR)
1341     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
1342   const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
1343   if(!cm.isDynamic())
1344     {
1345       std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::New : the input geometric type " << cm.getRepr() << " is static ! Only dynamic types are allowed here !";
1346       throw INTERP_KERNEL::Exception(oss.str().c_str());
1347     }
1348   return new MEDCoupling1DGTUMesh(name,cm);
1349 }
1350
1351 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const char *name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm)
1352 {
1353 }
1354
1355 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const MEDCoupling1DGTUMesh& other, bool recDeepCpy):MEDCoupling1GTUMesh(other,recDeepCpy),_conn(other._conn)
1356 {
1357   if(recDeepCpy)
1358     {
1359       const DataArrayInt *c(other._conn);
1360       if(c)
1361         _conn=c->deepCpy();
1362       c=other._conn_indx;
1363       if(c)
1364         _conn_indx=c->deepCpy();
1365     }
1366 }
1367
1368 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::clone(bool recDeepCpy) const
1369 {
1370   return new MEDCoupling1DGTUMesh(*this,recDeepCpy);
1371 }
1372
1373 /*!
1374  * This method behaves mostly like MEDCoupling1DGTUMesh::deepCpy method, except that only nodal connectivity arrays are deeply copied.
1375  * The coordinates are shared between \a this and the returned instance.
1376  * 
1377  * \return MEDCouplingUMesh * - A new object instance holding the copy of \a this (deep for connectivity, shallow for coordiantes)
1378  * \sa MEDCoupling1DGTUMesh::deepCpy
1379  */
1380 MEDCouplingPointSet *MEDCoupling1DGTUMesh::deepCpyConnectivityOnly() const throw(INTERP_KERNEL::Exception)
1381 {
1382   checkCoherency();
1383   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(clone(false));
1384   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(_conn->deepCpy()),ci(_conn_indx->deepCpy());
1385   ret->setNodalConnectivity(c,ci);
1386   return ret.retn();
1387 }
1388
1389 void MEDCoupling1DGTUMesh::updateTime() const
1390 {
1391   MEDCoupling1GTUMesh::updateTime();
1392   const DataArrayInt *c(_conn);
1393   if(c)
1394     updateTimeWith(*c);
1395   c=_conn_indx;
1396   if(c)
1397     updateTimeWith(*c);
1398 }
1399
1400 std::size_t MEDCoupling1DGTUMesh::getHeapMemorySize() const
1401 {
1402   std::size_t ret=0;
1403   const DataArrayInt *c(_conn);
1404   if(c)
1405     ret+=c->getHeapMemorySize();
1406   c=_conn_indx;
1407   if(c)
1408     ret+=c->getHeapMemorySize();
1409   return MEDCoupling1GTUMesh::getHeapMemorySize()+ret;
1410 }
1411
1412 MEDCouplingMesh *MEDCoupling1DGTUMesh::deepCpy() const
1413 {
1414   return clone(true);
1415 }
1416
1417 bool MEDCoupling1DGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception)
1418 {
1419   if(!other)
1420     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualIfNotWhy : input other pointer is null !");
1421   std::ostringstream oss; oss.precision(15);
1422   const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
1423   if(!otherC)
1424     {
1425       reason="mesh given in input is not castable in MEDCoupling1DGTUMesh !";
1426       return false;
1427     }
1428   if(!MEDCoupling1GTUMesh::isEqualIfNotWhy(other,prec,reason))
1429     return false;
1430   const DataArrayInt *c1(_conn),*c2(otherC->_conn);
1431   if(c1==c2)
1432     return true;
1433   if(!c1 || !c2)
1434     {
1435       reason="in connectivity of single dynamic geometric type exactly one among this and other is null !";
1436       return false;
1437     }
1438   if(!c1->isEqualIfNotWhy(*c2,reason))
1439     {
1440       reason.insert(0,"Nodal connectivity DataArrayInt differs : ");
1441       return false;
1442     }
1443   c1=_conn_indx; c2=otherC->_conn_indx;
1444   if(c1==c2)
1445     return true;
1446   if(!c1 || !c2)
1447     {
1448       reason="in connectivity index of single dynamic geometric type exactly one among this and other is null !";
1449       return false;
1450     }
1451   if(!c1->isEqualIfNotWhy(*c2,reason))
1452     {
1453       reason.insert(0,"Nodal connectivity index DataArrayInt differs : ");
1454       return false;
1455     }
1456   return true;
1457 }
1458
1459 bool MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
1460 {
1461   if(!other)
1462     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
1463   const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
1464   if(!otherC)
1465     return false;
1466   if(!MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(other,prec))
1467     return false;
1468   const DataArrayInt *c1(_conn),*c2(otherC->_conn);
1469   if(c1==c2)
1470     return true;
1471   if(!c1 || !c2)
1472     return false;
1473   if(!c1->isEqualWithoutConsideringStr(*c2))
1474     return false;
1475   return true;
1476   c1=_conn_indx; c2=otherC->_conn_indx;
1477   if(c1==c2)
1478     return true;
1479   if(!c1 || !c2)
1480     return false;
1481   if(!c1->isEqualWithoutConsideringStr(*c2))
1482     return false;
1483   return true;
1484 }
1485
1486 /*!
1487  * Checks if \a this and \a other meshes are geometrically equivalent with high
1488  * probability, else an exception is thrown. The meshes are considered equivalent if
1489  * (1) meshes contain the same number of nodes and the same number of elements of the
1490  * same types (2) three cells of the two meshes (first, last and middle) are based
1491  * on coincident nodes (with a specified precision).
1492  *  \param [in] other - the mesh to compare with.
1493  *  \param [in] prec - the precision used to compare nodes of the two meshes.
1494  *  \throw If the two meshes do not match.
1495  */
1496 void MEDCoupling1DGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception)
1497 {
1498   MEDCouplingPointSet::checkFastEquivalWith(other,prec);
1499   const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
1500   if(!otherC)
1501     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : Two meshes are not not unstructured with single static geometric type !");
1502   const DataArrayInt *c1(_conn),*c2(otherC->_conn);
1503   if(c1!=c2)
1504     {
1505       if(!c1 || !c2)
1506         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !");
1507       if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
1508         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !");
1509       if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
1510         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !");
1511       if(c1->getHashCode()!=c2->getHashCode())
1512         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity differs");
1513     }
1514   c1=_conn_indx; c2=otherC->_conn_indx;
1515   if(c1!=c2)
1516     {
1517       if(!c1 || !c2)
1518         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity index only in one of the 2 meshes !");
1519       if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
1520         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, only one is allocated !");
1521       if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
1522         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, must have 1 and only 1 component !");
1523       if(c1->getHashCode()!=c2->getHashCode())
1524         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity index differs");
1525     }
1526 }
1527
1528 /*!
1529  * 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.
1530  * In addition you are sure that the length of nodal connectivity index array is bigger than or equal to one.
1531  * In addition you are also sure that length of nodal connectivity is coherent with the content of the last value in the index array.
1532  */
1533 void MEDCoupling1DGTUMesh::checkCoherency() const throw(INTERP_KERNEL::Exception)
1534 {
1535   MEDCouplingPointSet::checkCoherency();
1536   const DataArrayInt *c1(_conn);
1537   if(c1)
1538     {
1539       if(c1->getNumberOfComponents()!=1)
1540         throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !");
1541       if(c1->getInfoOnComponent(0)!="")
1542         throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !");
1543       c1->checkAllocated();
1544     }
1545   else
1546     throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !");
1547   //
1548   int sz2=_conn->getNumberOfTuples();
1549   c1=_conn_indx;
1550   if(c1)
1551     {
1552       if(c1->getNumberOfComponents()!=1)
1553         throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to be with number of components set to one !");
1554       c1->checkAllocated();
1555       if(c1->getNumberOfTuples()<1)
1556         throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have a a size of 1 at least !");
1557       if(c1->getInfoOnComponent(0)!="")
1558         throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have no info on its single component !");
1559       int f=c1->front(),ll=c1->back();
1560       if(f<0 || f>=sz2)
1561         {
1562           std::ostringstream oss; oss << "Nodal connectivity index array first value (" << f << ") is expected to be exactly in [0," << sz2 << ") !";
1563           throw INTERP_KERNEL::Exception(oss.str().c_str());
1564         }
1565       if(ll<0 || ll>sz2)
1566         {
1567           std::ostringstream oss; oss << "Nodal connectivity index array last value (" << ll << ") is expected to be exactly in [0," << sz2 << "] !";
1568           throw INTERP_KERNEL::Exception(oss.str().c_str());
1569         }
1570       if(f>ll)
1571         {
1572           std::ostringstream oss; oss << "Nodal connectivity index array looks very bad (not increasing monotonic) because front (" << f << ") is greater that back (" << ll << ") !";
1573           throw INTERP_KERNEL::Exception(oss.str().c_str());
1574         }
1575     }
1576   else
1577     throw INTERP_KERNEL::Exception("Nodal connectivity index array not defined !");
1578   int szOfC1Exp=_conn_indx->back();
1579   if(sz2<szOfC1Exp)
1580     {
1581       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() << " !";
1582       throw INTERP_KERNEL::Exception(oss.str().c_str());
1583     }
1584 }
1585
1586 void MEDCoupling1DGTUMesh::checkCoherency1(double eps) const throw(INTERP_KERNEL::Exception)
1587 {
1588   checkCoherency();
1589   const DataArrayInt *c1(_conn),*c2(_conn_indx);
1590   if(!c2->isMonotonic(true))
1591     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkCoherency1 : the nodal connectivity index is expected to be increasing monotinic !");
1592   //
1593   int nbOfTuples=c1->getNumberOfTuples();
1594   int nbOfNodes=getNumberOfNodes();
1595   const int *w(c1->begin());
1596   for(int i=0;i<nbOfTuples;i++,w++)
1597     {
1598       if(*w==-1) continue;
1599       if(*w<0 || *w>=nbOfNodes)
1600         {
1601           std::ostringstream oss; oss << "At pos #" << i << " of nodal connectivity array references to node id #" << *w << " must be in [0," << nbOfNodes << ") !";
1602           throw INTERP_KERNEL::Exception(oss.str().c_str());
1603         }
1604     }
1605 }
1606
1607 void MEDCoupling1DGTUMesh::checkCoherency2(double eps) const throw(INTERP_KERNEL::Exception)
1608 {
1609   checkCoherency1(eps);
1610 }
1611
1612 int MEDCoupling1DGTUMesh::getNumberOfCells() const
1613 {
1614   checkCoherency();//do not remove
1615   return _conn_indx->getNumberOfTuples()-1;
1616 }
1617
1618 /*!
1619  * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
1620  * For each cell in \b this the number of nodes constituting cell is computed.
1621  * For each polyhedron cell, the sum of the number of nodes of each face constituting polyhedron cell is returned.
1622  * So for pohyhedrons some nodes can be counted several times in the returned result.
1623  * 
1624  * \return a newly allocated array
1625  */
1626 DataArrayInt *MEDCoupling1DGTUMesh::computeNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
1627 {
1628   checkCoherency();
1629   _conn_indx->checkMonotonic(true);
1630   if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
1631     return _conn_indx->deltaShiftIndex();
1632   // for polyhedrons
1633   int nbOfCells=_conn_indx->getNumberOfTuples()-1;
1634   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
1635   ret->alloc(nbOfCells,1);
1636   int *retPtr=ret->getPointer();
1637   const int *ci=_conn_indx->begin(),*c=_conn->begin();
1638   for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
1639     *retPtr=ci[1]-ci[0]-std::count(c+ci[0],c+ci[1],-1);
1640   return ret.retn();
1641 }
1642
1643 /*!
1644  * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
1645  * For each cell in \b this the number of faces constituting (entity of dimension this->getMeshDimension()-1) cell is computed.
1646  * 
1647  * \return a newly allocated array
1648  */
1649 DataArrayInt *MEDCoupling1DGTUMesh::computeNbOfFacesPerCell() const throw(INTERP_KERNEL::Exception)
1650 {
1651   checkCoherency();
1652   _conn_indx->checkMonotonic(true);
1653   if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED && getCellModelEnum()!=INTERP_KERNEL::NORM_QPOLYG)
1654     return _conn_indx->deltaShiftIndex();
1655   if(getCellModelEnum()==INTERP_KERNEL::NORM_QPOLYG)
1656     {
1657       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=_conn_indx->deltaShiftIndex();
1658       ret->applyDivideBy(2);
1659       return ret.retn();
1660     }
1661   // for polyhedrons
1662   int nbOfCells=_conn_indx->getNumberOfTuples()-1;
1663   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
1664   ret->alloc(nbOfCells,1);
1665   int *retPtr=ret->getPointer();
1666   const int *ci=_conn_indx->begin(),*c=_conn->begin();
1667   for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
1668     *retPtr=std::count(c+ci[0],c+ci[1],-1)+1;
1669   return ret.retn();
1670 }
1671
1672 void MEDCoupling1DGTUMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
1673 {
1674   int nbOfCells=getNumberOfCells();//performs checks
1675   if(cellId>=0 && cellId<nbOfCells)
1676     {
1677       int strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0);
1678       int nbOfNodes=stp-strt;
1679       if(nbOfNodes<0)
1680         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::getNodeIdsOfCell : the index array is invalid ! Should be increasing monotonic !");
1681       conn.resize(nbOfNodes);
1682       std::copy(_conn->begin()+strt,_conn->begin()+stp,conn.begin());
1683     }
1684   else
1685     {
1686       std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !";
1687       throw INTERP_KERNEL::Exception(oss.str().c_str());
1688     }
1689 }
1690
1691 std::string MEDCoupling1DGTUMesh::simpleRepr() const
1692 {
1693   static const char msg0[]="No coordinates specified !";
1694   std::ostringstream ret;
1695   ret << "Single dynamic geometic type (" << _cm->getRepr() << ") unstructured mesh with name : \"" << getName() << "\"\n";
1696   ret << "Description of mesh : \"" << getDescription() << "\"\n";
1697   int tmpp1,tmpp2;
1698   double tt=getTime(tmpp1,tmpp2);
1699   ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
1700   ret << "Iteration : " << tmpp1  << " Order : " << tmpp2 << "\n";
1701   ret << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : ";
1702   if(_coords!=0)
1703     {
1704       const int spaceDim=getSpaceDimension();
1705       ret << spaceDim << "\nInfo attached on space dimension : ";
1706       for(int i=0;i<spaceDim;i++)
1707         ret << "\"" << _coords->getInfoOnComponent(i) << "\" ";
1708       ret << "\n";
1709     }
1710   else
1711     ret << msg0 << "\n";
1712   ret << "Number of nodes : ";
1713   if(_coords!=0)
1714     ret << getNumberOfNodes() << "\n";
1715   else
1716     ret << msg0 << "\n";
1717   ret << "Number of cells : ";
1718   bool isOK=true;
1719   try { checkCoherency(); } catch(INTERP_KERNEL::Exception& e)
1720     {
1721       ret << "Nodal connectivity arrays are not set or badly set !\n";
1722       isOK=false;
1723     }
1724   if(isOK)
1725     ret << getNumberOfCells() << "\n";
1726   ret << "Cell type : " << _cm->getRepr() << "\n";
1727   return ret.str();
1728 }
1729
1730 std::string MEDCoupling1DGTUMesh::advancedRepr() const
1731 {
1732   std::ostringstream ret;
1733   ret << simpleRepr();
1734   ret << "\nCoordinates array : \n___________________\n\n";
1735   if(_coords)
1736     _coords->reprWithoutNameStream(ret);
1737   else
1738     ret << "No array set !\n";
1739   ret << "\n\nNodal Connectivity : \n____________________\n\n";
1740   //
1741   bool isOK=true;
1742   try { checkCoherency1(); } catch(INTERP_KERNEL::Exception& e)
1743     {
1744       ret << "Nodal connectivity arrays are not set or badly set !\n";
1745       isOK=false;
1746     }
1747   if(!isOK)
1748     return ret.str();
1749   int nbOfCells=getNumberOfCells();
1750   const int *ci=_conn_indx->begin(),*c=_conn->begin();
1751   for(int i=0;i<nbOfCells;i++,ci++)
1752     {
1753       ret << "Cell #" << i << " : ";
1754       std::copy(c+ci[0],c+ci[1],std::ostream_iterator<int>(ret," "));
1755       ret << "\n";
1756     }
1757   return ret.str();
1758 }
1759
1760 DataArrayDouble *MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
1761 {
1762   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1763   int spaceDim=getSpaceDimension();
1764   int nbOfCells=getNumberOfCells();//checkCoherency()
1765   int nbOfNodes=getNumberOfNodes();
1766   ret->alloc(nbOfCells,spaceDim);
1767   double *ptToFill=ret->getPointer();
1768   const double *coor=_coords->begin();
1769   const int *nodal=_conn->begin(),*nodali=_conn_indx->begin();
1770   nodal+=nodali[0];
1771   if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
1772     {
1773       for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
1774         {
1775           std::fill(ptToFill,ptToFill+spaceDim,0.);
1776           if(nodali[0]<nodali[1])// >= to avoid division by 0.
1777             {
1778               for(int j=nodali[0];j<nodali[1];j++,nodal++)
1779                 {
1780                   if(*nodal>=0 && *nodal<nbOfNodes)
1781                     std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
1782                   else
1783                     {
1784                       std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," <<   nbOfNodes << ") !";
1785                       throw INTERP_KERNEL::Exception(oss.str().c_str());
1786                     }
1787                   std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./(nodali[1]-nodali[0])));
1788                 }
1789             }
1790           else
1791             {
1792               std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : at cell #" << i << " the nodal index array is invalid !";
1793               throw INTERP_KERNEL::Exception(oss.str().c_str());
1794             }
1795         }
1796     }
1797   else
1798     {
1799       for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
1800         {
1801           std::fill(ptToFill,ptToFill+spaceDim,0.);
1802           if(nodali[0]<nodali[1])// >= to avoid division by 0.
1803             {
1804               int nbOfNod=0;
1805               for(int j=nodali[0];j<nodali[1];j++,nodal++)
1806                 {
1807                   if(*nodal==-1) continue;
1808                   if(*nodal>=0 && *nodal<nbOfNodes)
1809                     {
1810                       std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
1811                       nbOfNod++;
1812                     }
1813                   else
1814                     {
1815                       std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," <<   nbOfNodes << ") !";
1816                       throw INTERP_KERNEL::Exception(oss.str().c_str());
1817                     }
1818                 }
1819               if(nbOfNod!=0)
1820                 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./nbOfNod));
1821               else
1822                 {
1823                   std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : no nodes in cell #" << i << " !";
1824                   throw INTERP_KERNEL::Exception(oss.str().c_str());
1825                 }
1826             }
1827           else
1828             {
1829               std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron)  : at cell #" << i << " the nodal index array is invalid !";
1830               throw INTERP_KERNEL::Exception(oss.str().c_str());
1831             }
1832         }
1833     }
1834   return ret.retn();
1835 }
1836
1837 void MEDCoupling1DGTUMesh::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception)
1838 {
1839   int nbCells=getNumberOfCells();
1840   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::New();
1841   o2n->useArray(old2NewBg,false,C_DEALLOC,nbCells,1);
1842   if(check)
1843     o2n=o2n->checkAndPreparePermutation();
1844   //
1845   const int *o2nPtr=o2n->getPointer();
1846   const int *conn=_conn->begin(),*conni=_conn_indx->begin();
1847   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New();
1848   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI=DataArrayInt::New();
1849   newConn->alloc(_conn->getNumberOfTuples(),1); newConnI->alloc(nbCells,1);
1850   newConn->copyStringInfoFrom(*_conn); newConnI->copyStringInfoFrom(*_conn_indx);
1851   //
1852   int *newC=newConn->getPointer(),*newCI=newConnI->getPointer();
1853   for(int i=0;i<nbCells;i++)
1854     {
1855       int newPos=o2nPtr[i];
1856       int sz=conni[i+1]-conni[i];
1857       if(sz>=0)
1858         newCI[newPos]=sz;
1859       else
1860         {
1861           std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberCells : the index nodal array is invalid for cell #" << i << " !";
1862           throw INTERP_KERNEL::Exception(oss.str().c_str());
1863         }
1864     }
1865   newConnI->computeOffsets2(); newCI=newConnI->getPointer();
1866   //
1867   for(int i=0;i<nbCells;i++,conni++)
1868     {
1869       int sz=conni[1]-conni[0];
1870       int newp=o2nPtr[i];
1871       std::copy(conn+conni[0],conn+conni[1],newC+newCI[newp]);
1872     }
1873   _conn=newConn;
1874   _conn_indx=newConnI;
1875 }
1876
1877 MEDCouplingMesh *MEDCoupling1DGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
1878 {
1879   if(other->getType()!=SINGLE_DYNAMIC_GEO_TYPE_UNSTRUCTURED)
1880     throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single dynamic geo type each other !");
1881   const MEDCoupling1DGTUMesh *otherC=static_cast<const MEDCoupling1DGTUMesh *>(other);
1882   return Merge1DGTUMeshes(this,otherC);
1883 }
1884
1885 MEDCouplingUMesh *MEDCoupling1DGTUMesh::buildUnstructured() const throw(INTERP_KERNEL::Exception)
1886 {
1887   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName(),getMeshDimension());
1888   ret->setCoords(getCoords());
1889   const int *nodalConn=_conn->begin(),*nodalConnI=_conn_indx->begin();
1890   int nbCells=getNumberOfCells();//checkCoherency
1891   int geoType=(int)getCellModelEnum();
1892   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New(); c->alloc(nbCells+_conn->getNumberOfTuples(),1);
1893   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cI=DataArrayInt::New(); cI->alloc(nbCells+1);
1894   int *cPtr=c->getPointer(),*ciPtr=cI->getPointer();
1895   ciPtr[0]=0;
1896   for(int i=0;i<nbCells;i++,ciPtr++)
1897     {
1898       int sz=nodalConnI[i+1]-nodalConnI[i];
1899       if(sz>=0)
1900         {
1901           *cPtr++=geoType;
1902           cPtr=std::copy(nodalConn+nodalConnI[i],nodalConn+nodalConnI[i+1],cPtr);
1903           ciPtr[1]=ciPtr[0]+sz+1;
1904         }
1905       else
1906         {
1907           std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::buildUnstructured : Invalid for nodal index for cell #" << i << " !";
1908           throw INTERP_KERNEL::Exception(oss.str().c_str());
1909         }
1910     }
1911   ret->setConnectivity(c,cI,true);
1912   return ret.retn();
1913 }
1914
1915 /*!
1916  * Do nothing for the moment, because there is no policy that allows to split polygons, polyhedrons ... into simplexes
1917  */
1918 DataArrayInt *MEDCoupling1DGTUMesh::simplexize(int policy) throw(INTERP_KERNEL::Exception)
1919 {
1920   int nbOfCells=getNumberOfCells();
1921   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
1922   ret->alloc(nbOfCells,1);
1923   ret->iota(0);
1924   return ret.retn();
1925 }
1926
1927 void MEDCoupling1DGTUMesh::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1928 {
1929   stream << "MEDCoupling1DGTUMesh C++ instance at " << this << ". Type=" << _cm->getRepr() << ". Name : \"" << getName() << "\".";
1930   stream << " Mesh dimension : " << getMeshDimension() << ".";
1931   if(!_coords)
1932     { stream << " No coordinates set !"; return ; }
1933   if(!_coords->isAllocated())
1934     { stream << " Coordinates set but not allocated !"; return ; }
1935   stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
1936   stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
1937   bool isOK=true;
1938   try { checkCoherency(); } catch(INTERP_KERNEL::Exception& e)
1939     {
1940       stream << std::endl << "Nodal connectivity NOT set properly !\n";
1941       isOK=false;
1942     }
1943   if(isOK)
1944     stream << std::endl << "Number of cells : " << getNumberOfCells() << ".";
1945 }
1946
1947 void MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other) throw(INTERP_KERNEL::Exception)
1948 {
1949   if(!other)
1950     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is null !");
1951   const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
1952   if(!otherC)
1953     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1DGTUMesh instance !");
1954   setNodalConnectivity(otherC->getNodalConnectivity(),otherC->getNodalConnectivityIndex());
1955 }
1956
1957 MEDCouplingPointSet *MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const
1958 {
1959   if(!other)
1960     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : input other is null !");
1961   const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
1962   if(!otherC)
1963     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !");
1964   std::vector<const MEDCoupling1DGTUMesh *> ms(2);
1965   ms[0]=this;
1966   ms[1]=otherC;
1967   return Merge1DGTUMeshesOnSameCoords(ms);
1968 }
1969
1970 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const
1971 {
1972   checkCoherency();
1973   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
1974   ret->setCoords(_coords);
1975   DataArrayInt *c=0,*ci=0;
1976   MEDCouplingUMesh::ExtractFromIndexedArrays(begin,end,_conn,_conn_indx,c,ci);
1977   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
1978   ret->setNodalConnectivity(c,ci);
1979   return ret.retn();
1980 }
1981
1982 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const
1983 {
1984   checkCoherency();
1985   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
1986   ret->setCoords(_coords);
1987   DataArrayInt *c=0,*ci=0;
1988   MEDCouplingUMesh::ExtractFromIndexedArrays2(start,end,step,_conn,_conn_indx,c,ci);
1989   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
1990   ret->setNodalConnectivity(c,ci);
1991   return ret.retn();
1992 }
1993
1994 void MEDCoupling1DGTUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const throw(INTERP_KERNEL::Exception)
1995 {
1996   checkFullyDefined();
1997   int nbOfNodes=getNumberOfNodes();
1998   int *revNodalIndxPtr=(int *)malloc((nbOfNodes+1)*sizeof(int));
1999   revNodalIndx->useArray(revNodalIndxPtr,true,C_DEALLOC,nbOfNodes+1,1);
2000   std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
2001   const int *conn=_conn->begin(),*conni=_conn_indx->begin();
2002   int nbOfCells=getNumberOfCells();
2003   int nbOfEltsInRevNodal=0;
2004   for(int eltId=0;eltId<nbOfCells;eltId++)
2005     {
2006       int nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
2007       if(nbOfNodesPerCell>=0)
2008         {
2009           for(int j=0;j<nbOfNodesPerCell;j++)
2010             {
2011               int nodeId=conn[conni[eltId]+j];
2012               if(nodeId==-1) continue;            
2013               if(nodeId>=0 && nodeId<nbOfNodes)
2014                 {
2015                   nbOfEltsInRevNodal++;
2016                   revNodalIndxPtr[nodeId+1]++;
2017                 }
2018               else
2019                 {
2020                   std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !";
2021                   throw INTERP_KERNEL::Exception(oss.str().c_str());
2022                 }
2023             }
2024         }
2025       else
2026         {
2027           std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << "nodal connectivity is invalid !";
2028           throw INTERP_KERNEL::Exception(oss.str().c_str());
2029         }
2030     }
2031   std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<int>());
2032   conn=_conn->begin();
2033   int *revNodalPtr=(int *)malloc((nbOfEltsInRevNodal)*sizeof(int));
2034   revNodal->useArray(revNodalPtr,true,C_DEALLOC,nbOfEltsInRevNodal,1);
2035   std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
2036   for(int eltId=0;eltId<nbOfCells;eltId++)
2037     {
2038       int nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
2039       for(int j=0;j<nbOfNodesPerCell;j++)
2040         {
2041           int nodeId=conn[conni[eltId]+j];
2042           if(nodeId!=-1)
2043             *std::find_if(revNodalPtr+revNodalIndxPtr[nodeId],revNodalPtr+revNodalIndxPtr[nodeId+1],std::bind2nd(std::equal_to<int>(),-1))=eltId;
2044         }
2045     }
2046 }
2047
2048 void MEDCoupling1DGTUMesh::checkFullyDefined() const throw(INTERP_KERNEL::Exception)
2049 {
2050   if(!((const DataArrayInt *)_conn) || !((const DataArrayInt *)_conn_indx) || !((const DataArrayDouble *)_coords))
2051     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFullyDefined : part of this is not fully defined.");
2052 }
2053
2054 bool MEDCoupling1DGTUMesh::isEmptyMesh(const std::vector<int>& tinyInfo) const
2055 {
2056   throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEmptyMesh : not implemented yet !");
2057 }
2058
2059 /*!
2060  * Finds nodes not used in any cell and returns an array giving a new id to every node
2061  * by excluding the unused nodes, for which the array holds -1. The result array is
2062  * a mapping in "Old to New" mode. 
2063  *  \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
2064  *  \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a
2065  *          this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
2066  *          if the node is unused or a new id else. The caller is to delete this
2067  *          array using decrRef() as it is no more needed.  
2068  *  \throw If the coordinates array is not set.
2069  *  \throw If the nodal connectivity of cells is not defined.
2070  *  \throw If the nodal connectivity includes an invalid id.
2071  */
2072 DataArrayInt *MEDCoupling1DGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const throw(INTERP_KERNEL::Exception)
2073 {
2074   nbrOfNodesInUse=-1;
2075   int nbOfNodes=getNumberOfNodes();
2076   int nbOfCells=getNumberOfCells();//checkCoherency
2077   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2078   ret->alloc(nbOfNodes,1);
2079   int *traducer=ret->getPointer();
2080   std::fill(traducer,traducer+nbOfNodes,-1);
2081   const int *conn=_conn->begin(),*conni(_conn_indx->begin());
2082   for(int i=0;i<nbOfCells;i++,conni++)
2083     {
2084       int nbNodesPerCell=conni[1]-conni[0];
2085       for(int j=0;j<nbNodesPerCell;j++)
2086         {
2087           int nodeId=conn[conni[0]+j];
2088           if(nodeId==-1) continue;
2089           if(nodeId>=0 && nodeId<nbOfNodes)
2090             traducer[*conn]=1;
2091           else
2092             {
2093               std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsInUse : In cell #" << i  << " presence of node id " <<  nodeId << " not in [0," << nbOfNodes << ") !";
2094               throw INTERP_KERNEL::Exception(oss.str().c_str());
2095             }
2096         }
2097     }
2098   nbrOfNodesInUse=(int)std::count(traducer,traducer+nbOfNodes,1);
2099   std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
2100   return ret.retn();
2101 }
2102
2103 /*!
2104  * Changes ids of nodes within the nodal connectivity arrays according to a permutation
2105  * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
2106  * This method is a generalization of shiftNodeNumbersInConn().
2107  *  \warning This method performs no check of validity of new ids. **Use it with care !**
2108  *  \param [in] newNodeNumbersO2N - a permutation array, of length \a
2109  *         this->getNumberOfNodes(), in "Old to New" mode. 
2110  *         See \ref MEDCouplingArrayRenumbering for more info on renumbering modes.
2111  *  \throw If the nodal connectivity of cells is not defined.
2112  */
2113 void MEDCoupling1DGTUMesh::renumberNodesInConn(const int *newNodeNumbersO2N)
2114 {
2115   getNumberOfCells();//only to check that all is well defined.
2116   //
2117   int nbElemsIn=getNumberOfNodes();
2118   int nbOfTuples=_conn->getNumberOfTuples();
2119   int *pt=_conn->getPointer();
2120   for(int i=0;i<nbOfTuples;i++,pt++)
2121     {
2122       if(*pt==-1) continue;
2123       if(*pt>=0 && *pt<nbElemsIn)
2124         *pt=newNodeNumbersO2N[*pt];
2125       else
2126         {
2127           std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberNodesInConn : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn;
2128           throw INTERP_KERNEL::Exception(oss.str().c_str());
2129         }
2130     }
2131   _conn->declareAsNew();
2132   //
2133   updateTime();
2134 }
2135
2136 /*!
2137  * Keeps from \a this only cells which constituing point id are in the ids specified by [\a begin,\a end).
2138  * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
2139  * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not.
2140  * If \a fullyIn is true only cells whose ids are \b fully contained in [\a begin,\a end) tab will be kept.
2141  *
2142  * \param [in] begin input start of array of node ids.
2143  * \param [in] end input end of array of node ids.
2144  * \param [in] fullyIn input that specifies if all node ids must be in [\a begin,\a end) array to consider cell to be in.
2145  * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end.
2146  */
2147 void MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const
2148 {
2149   int nbOfCells=getNumberOfCells();
2150   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1);
2151   int tmp=-1;
2152   int sz=_conn->getMaxValue(tmp); sz=std::max(sz,0)+1;
2153   std::vector<bool> fastFinder(sz,false);
2154   for(const int *work=begin;work!=end;work++)
2155     if(*work>=0 && *work<sz)
2156       fastFinder[*work]=true;
2157   const int *conn=_conn->begin(),*conni=_conn_indx->begin();
2158   for(int i=0;i<nbOfCells;i++,conni++)
2159     {
2160       int ref=0,nbOfHit=0;
2161       int nbNodesPerCell=conni[1]-conni[0];
2162       if(nbNodesPerCell>=0)
2163         {
2164           for(int j=0;j<nbNodesPerCell;j++)
2165             {
2166               int nodeId=conn[conni[0]+j];
2167               if(nodeId>=0)
2168                 {
2169                   ref++;
2170                   if(fastFinder[nodeId])
2171                     nbOfHit++;
2172                 }
2173             }
2174         }
2175       else
2176         {
2177           std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds : invalid index array for cell #" << i << " !";
2178           throw INTERP_KERNEL::Exception(oss.str().c_str());
2179         }
2180       if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn))
2181         cellIdsKept->pushBackSilent(i);
2182     }
2183   cellIdsKeptArr=cellIdsKept.retn();
2184 }
2185
2186 void MEDCoupling1DGTUMesh::allocateCells(int nbOfCells) throw(INTERP_KERNEL::Exception)
2187 {
2188   if(nbOfCells<0)
2189     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::allocateCells : the input number of cells should be >= 0 !");
2190   _conn=DataArrayInt::New();
2191   _conn->reserve(nbOfCells*3);
2192   _conn_indx=DataArrayInt::New();
2193   _conn_indx->reserve(nbOfCells+1); _conn_indx->pushBackSilent(0);
2194   declareAsNew();
2195 }
2196
2197 /*!
2198  * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ).
2199  *
2200  * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add.
2201  * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
2202  * \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
2203  *        attached to \a this.
2204  * \thow If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
2205  */
2206 void MEDCoupling1DGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd) throw(INTERP_KERNEL::Exception)
2207 {
2208   int sz=(int)std::distance(nodalConnOfCellBg,nodalConnOfCellEnd);
2209   DataArrayInt *c(_conn),*c2(_conn_indx);
2210   if(c && c2)
2211     {
2212       int pos=c2->back();
2213       if(pos==c->getNumberOfTuples())
2214         {
2215           c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd);
2216           c2->pushBackSilent(pos+sz);
2217         }
2218       else
2219         {
2220           std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::insertNextCell : The nodal index array (end=" << pos << ") mismatches with nodal array (length=" << c->getNumberOfTuples() << ") !";
2221           throw INTERP_KERNEL::Exception(oss.str().c_str());
2222         }
2223     }
2224   else
2225     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1DGTUMesh::allocateCells before !");
2226 }
2227
2228 void MEDCoupling1DGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn, DataArrayInt *nodalConnIndex) throw(INTERP_KERNEL::Exception)
2229 {
2230   if(nodalConn)
2231     nodalConn->incrRef();
2232   _conn=nodalConn;
2233   if(nodalConnIndex)
2234     nodalConnIndex->incrRef();
2235   _conn_indx=nodalConnIndex;
2236   declareAsNew();
2237 }
2238
2239 /*!
2240  * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it.
2241  */
2242 DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivity() const throw(INTERP_KERNEL::Exception)
2243 {
2244   const DataArrayInt *ret(_conn);
2245   return const_cast<DataArrayInt *>(ret);
2246 }
2247
2248 /*!
2249  * \return DataArrayInt * - the internal reference to the nodal connectivity index. The caller is not reponsible to deallocate it.
2250  */
2251 DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivityIndex() const throw(INTERP_KERNEL::Exception)
2252 {
2253   const DataArrayInt *ret(_conn_indx);
2254   return const_cast<DataArrayInt *>(ret);
2255 }
2256
2257 /*!
2258  * See the definition of the nodal connectivity pack \ref MEDCoupling1DGTUMesh::isPacked "here".
2259  * This method tries to build a new instance geometrically equivalent to \a this, by limiting at most the number of new object (nodal connectivity).
2260  * 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.
2261  *
2262  * 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.
2263  * 
2264  * \param [out] isShallowCpyOfNodalConnn - tells if the returned instance share the same pair of nodal connectivity arrays (true) or if nodal
2265  *              connectivity arrays are different (false)
2266  * \return a new object to be managed by the caller.
2267  * 
2268  * \sa MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity, MEDCoupling1DGTUMesh::isPacked
2269  */
2270 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::copyWithNodalConnectivityPacked(bool& isShallowCpyOfNodalConnn) const throw(INTERP_KERNEL::Exception)
2271 {
2272   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
2273   DataArrayInt *nc=0,*nci=0;
2274   isShallowCpyOfNodalConnn=retrievePackedNodalConnectivity(nc,nci);
2275   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ncs(nc),ncis(nci);
2276   ret->_conn=ncs; ret->_conn_indx=ncis;
2277   ret->setCoords(getCoords());
2278   return ret.retn();
2279 }
2280
2281 /*!
2282  * This method allows to compute, if needed, the packed nodal connectivity pair.
2283  * Indeed, it is possible to store in \a this a nodal connectivity array bigger than ranges convered by nodal connectivity index array.
2284  * 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.
2285  * 
2286  * 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)
2287  * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
2288  *
2289  * 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
2290  * will be returned.
2291  * 
2292  * This method return 3 elements.
2293  * \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
2294  *                          this pointer can be seen as a new object, that is to managed by the caller.
2295  * \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
2296  *                              this pointer can be seen as a new object, that is to managed by the caller.
2297  * \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
2298  * output parameters are newly created objects.
2299  *
2300  * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkCoherency test
2301  */
2302 bool MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity(DataArrayInt *&nodalConn, DataArrayInt *&nodalConnIndx) const throw(INTERP_KERNEL::Exception)
2303 {
2304   if(isPacked())//performs the checkCoherency
2305     {
2306       const DataArrayInt *c0(_conn),*c1(_conn_indx);
2307       nodalConn=const_cast<DataArrayInt *>(c0); nodalConnIndx=const_cast<DataArrayInt *>(c1);
2308       nodalConn->incrRef(); nodalConnIndx->incrRef();
2309       return true;
2310     }
2311   int bg=_conn_indx->front(),end=_conn_indx->back();
2312   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nc(_conn->selectByTupleId2(bg,end,1));
2313   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nci(_conn_indx->deepCpy());
2314   nci->applyLin(1,-bg);
2315   nodalConn=nc.retn(); nodalConnIndx=nci.retn();
2316   return false;
2317 }
2318
2319 /*
2320  * 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)
2321  * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
2322  * If nodal connectivity index points to a subpart of nodal connectivity index false will be returned.
2323  * \return bool - true if \a this looks packed, false is not.
2324  *
2325  * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkCoherency test
2326  */
2327 bool MEDCoupling1DGTUMesh::isPacked() const throw(INTERP_KERNEL::Exception)
2328 {
2329   checkCoherency();
2330   return _conn_indx->front()==0 && _conn_indx->back()==_conn->getNumberOfTuples();
2331 }
2332
2333 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(const MEDCoupling1DGTUMesh *mesh1, const MEDCoupling1DGTUMesh *mesh2) throw(INTERP_KERNEL::Exception)
2334 {
2335   std::vector<const MEDCoupling1DGTUMesh *> tmp(2);
2336   tmp[0]=const_cast<MEDCoupling1DGTUMesh *>(mesh1); tmp[1]=const_cast<MEDCoupling1DGTUMesh *>(mesh2);
2337   return Merge1DGTUMeshes(tmp);
2338 }
2339
2340 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(std::vector<const MEDCoupling1DGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
2341 {
2342   std::size_t sz=a.size();
2343   if(sz==0)
2344     return Merge1DGTUMeshesLL(a);
2345   for(std::size_t ii=0;ii<sz;ii++)
2346     if(!a[ii])
2347       {
2348         std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::Merge1DGTUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !";
2349         throw INTERP_KERNEL::Exception(oss.str().c_str());
2350       }
2351   const INTERP_KERNEL::CellModel *cm=&(a[0]->getCellModel());
2352   for(std::size_t ii=0;ii<sz;ii++)
2353     if(&(a[ii]->getCellModel())!=cm)
2354       throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : all items must have the same geo type !");
2355   std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > bb(sz);
2356   std::vector< const MEDCoupling1DGTUMesh * > aa(sz);
2357   int spaceDim=-3;
2358   for(std::size_t i=0;i<sz && spaceDim==-3;i++)
2359     {
2360       const MEDCoupling1DGTUMesh *cur=a[i];
2361       const DataArrayDouble *coo=cur->getCoords();
2362       if(coo)
2363         spaceDim=coo->getNumberOfComponents();
2364     }
2365   if(spaceDim==-3)
2366     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : no spaceDim specified ! unable to perform merge !");
2367   for(std::size_t i=0;i<sz;i++)
2368     {
2369       bb[i]=a[i]->buildSetInstanceFromThis(spaceDim);
2370       aa[i]=bb[i];
2371     }
2372   return Merge1DGTUMeshesLL(aa);
2373 }
2374
2375 /*!
2376  * \throw If presence of a null instance in the input vector \a a.
2377  * \throw If a is empty
2378  */
2379 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords(std::vector<const MEDCoupling1DGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
2380 {
2381   if(a.empty())
2382     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : input array must be NON EMPTY !");
2383   std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin();
2384   if(!(*it))
2385     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : null instance in the first element of input vector !");
2386   std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > objs(a.size());
2387   std::vector<const DataArrayInt *> ncs(a.size()),ncis(a.size());
2388   int nbOfCells=(*it)->getNumberOfCells();
2389   const DataArrayDouble *coords=(*it)->getCoords();
2390   const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
2391   bool tmp;
2392   objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp);
2393   ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex();
2394   it++;
2395   for(int i=1;it!=a.end();i++,it++)
2396     {
2397       if(!(*it))
2398         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : presence of null instance !");
2399       if(cm!=&((*it)->getCellModel()))
2400         throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !");
2401       (*it)->getNumberOfCells();//to check that all is OK
2402       objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp);
2403       ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex();
2404       if(coords!=(*it)->getCoords())
2405         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : not lying on same coords !");
2406     }
2407   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm));
2408   ret->setCoords(coords);
2409   ret->_conn=DataArrayInt::Aggregate(ncs);
2410   ret->_conn_indx=DataArrayInt::AggregateIndexes(ncis);
2411   return ret.retn();
2412 }
2413
2414 /*!
2415  * Assume that all instances in \a a are non null. If null it leads to a crash. That's why this method is assigned to be low level (LL)
2416  */
2417 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesLL(std::vector<const MEDCoupling1DGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
2418 {
2419   if(a.empty())
2420     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : input array must be NON EMPTY !");
2421   std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > objs(a.size());
2422   std::vector<const DataArrayInt *> ncs(a.size()),ncis(a.size());
2423   std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin();
2424   std::vector<int> nbNodesPerElt(a.size());
2425   int nbOfCells=(*it)->getNumberOfCells();
2426   bool tmp;
2427   objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp);
2428   ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex();
2429   nbNodesPerElt[0]=0;
2430   int prevNbOfNodes=(*it)->getNumberOfNodes();
2431   const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
2432   it++;
2433   for(int i=1;it!=a.end();i++,it++)
2434     {
2435       if(cm!=&((*it)->getCellModel()))
2436         throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !");
2437       objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp);
2438       ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex();
2439       nbOfCells+=(*it)->getNumberOfCells();
2440       nbNodesPerElt[i]=nbNodesPerElt[i-1]+prevNbOfNodes;
2441       prevNbOfNodes=(*it)->getNumberOfNodes();
2442     }
2443   std::vector<const MEDCouplingPointSet *> aps(a.size());
2444   std::copy(a.begin(),a.end(),aps.begin());
2445   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> pts=MergeNodesArray(aps);
2446   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm));
2447   ret->setCoords(pts);
2448   ret->_conn=AggregateNodalConnAndShiftNodeIds(ncs,nbNodesPerElt);
2449   ret->_conn_indx=DataArrayInt::AggregateIndexes(ncis);
2450   return ret.retn();
2451 }
2452
2453 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::buildSetInstanceFromThis(int spaceDim) const throw(INTERP_KERNEL::Exception)
2454 {
2455   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm));
2456   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1,tmp2;
2457   const DataArrayInt *nodalConn(_conn),*nodalConnI(_conn_indx);
2458   if(!nodalConn)
2459     {
2460       tmp1=DataArrayInt::New(); tmp1->alloc(0,1);
2461     }
2462   else
2463     tmp1=_conn;
2464   ret->_conn=tmp1;
2465   //
2466   if(!nodalConnI)
2467     {
2468       tmp2=DataArrayInt::New(); tmp2->alloc(1,1); tmp2->setIJ(0,0,0);
2469     }
2470   else
2471     tmp2=_conn_indx;
2472   ret->_conn_indx=tmp2;
2473   //
2474   if(!_coords)
2475     {
2476       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim);
2477       ret->setCoords(coords);
2478     }
2479   else
2480     ret->setCoords(_coords);
2481   return ret.retn();
2482 }
2483
2484 /*!
2485  * This method performs an aggregation of \a nodalConns (as DataArrayInt::Aggregate does) but in addition of that a shift is applied on the 
2486  * values contained in \a nodalConns using corresponding offset specified in input \a offsetInNodeIdsPerElt.
2487  * But it also manage the values -1, that have a semantic in MEDCoupling1DGTUMesh class (separator for polyhedron).
2488  *
2489  * \param [in] nodalConns - a list of nodal connectivity arrays same size than \a offsetInNodeIdsPerElt.
2490  * \param [in] offsetInNodeIdsPerElt - a list of offsets to apply.
2491  * \return DataArrayInt * - A new object (to be managed by the caller) that is the result of the aggregation.
2492  * \throw If \a nodalConns or \a offsetInNodeIdsPerElt are empty.
2493  * \throw If \a nodalConns and \a offsetInNodeIdsPerElt have not the same size.
2494  * \throw If presence of null pointer in \a nodalConns.
2495  * \throw If presence of not allocated or array with not exactly one component in \a nodalConns.
2496  */
2497 DataArrayInt *MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds(const std::vector<const DataArrayInt *>& nodalConns, const std::vector<int>& offsetInNodeIdsPerElt) throw(INTERP_KERNEL::Exception)
2498 {
2499   std::size_t sz1(nodalConns.size()),sz2(offsetInNodeIdsPerElt.size());
2500   if(sz1!=sz2)
2501     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : input vectors do not have the same size !");
2502   if(sz1==0)
2503     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : empty vectors in input !");
2504   int nbOfTuples=0;
2505   for(std::vector<const DataArrayInt *>::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++)
2506     {
2507       if(!(*it))
2508         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of null pointer in input vector !");
2509       if(!(*it)->isAllocated())
2510         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of non allocated array in input vector !");
2511       if((*it)->getNumberOfComponents()!=1)
2512         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of array with not exactly one component !");
2513       nbOfTuples+=(*it)->getNumberOfTuples();
2514     }
2515   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
2516   int *pt=ret->getPointer();
2517   int i=0;
2518   for(std::vector<const DataArrayInt *>::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++,i++)
2519     {
2520       int curNbt=(*it)->getNumberOfTuples();
2521       const int *inPt=(*it)->begin();
2522       int offset=offsetInNodeIdsPerElt[i];
2523       for(int j=0;j<curNbt;j++,pt++)
2524         {
2525           if(inPt[j]!=-1)
2526             *pt=inPt[j]+offset;
2527           else
2528             *pt=-1;
2529         }
2530     }
2531   return ret.retn();
2532 }