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