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