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