Salome HOME
On the road of addition of optimized unstructured mesh with a single geometric type.
[tools/medcoupling.git] / src / MEDCoupling / MEDCoupling1GTUMesh.cxx
1 // Copyright (C) 2007-2013  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 // Author : Anthony Geay (CEA/DEN)
20
21 #include "MEDCoupling1GTUMesh.hxx"
22 #include "MEDCouplingUMesh.hxx"
23 #include "MEDCouplingFieldDouble.hxx"
24
25 #include "SplitterTetra.hxx"
26
27 using namespace ParaMEDMEM;
28
29 MEDCoupling1GTUMesh::MEDCoupling1GTUMesh(const char *name, const INTERP_KERNEL::CellModel& cm):_cm(&cm)
30 {
31   setName(name);
32 }
33
34 MEDCoupling1GTUMesh::MEDCoupling1GTUMesh(const MEDCoupling1GTUMesh& other, bool recDeepCpy):MEDCouplingPointSet(other,recDeepCpy),_cm(other._cm)
35 {
36 }
37
38 MEDCoupling1GTUMesh *MEDCoupling1GTUMesh::New(const char *name, INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception)
39 {
40   if(type==INTERP_KERNEL::NORM_ERROR)
41     throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
42   const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
43   if(!cm.isDynamic())
44     return MEDCoupling1SGTUMesh::New(name,type);
45   throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : not implemented yet !");
46 }
47
48 const INTERP_KERNEL::CellModel& MEDCoupling1GTUMesh::getCellModel() const throw(INTERP_KERNEL::Exception)
49 {
50   return *_cm;
51 }
52
53 INTERP_KERNEL::NormalizedCellType MEDCoupling1GTUMesh::getCellModelEnum() const throw(INTERP_KERNEL::Exception)
54 {
55   return _cm->getEnum();
56 }
57
58 int MEDCoupling1GTUMesh::getMeshDimension() const
59 {
60   return (int)_cm->getDimension();
61 }
62
63 /*!
64  * This method returns a newly allocated array containing cell ids (ascendingly sorted) whose geometric type are equal to type.
65  * This method does not throw exception if geometric type \a type is not in \a this.
66  * This method throws an INTERP_KERNEL::Exception if meshdimension of \b this is not equal to those of \b type.
67  * The coordinates array is not considered here.
68  *
69  * \param [in] type the geometric type
70  * \return cell ids in this having geometric type \a type.
71  */
72 DataArrayInt *MEDCoupling1GTUMesh::giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception)
73 {
74   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
75   if(type==getCellModelEnum())
76     ret->alloc(getNumberOfCells(),1);
77   else
78     ret->alloc(0,1);
79   ret->iota();
80   return ret.retn();
81 }
82
83 /*!
84  * Returns nb of cells having the geometric type \a type. No throw if no cells in \a this has the geometric type \a type.
85  */
86 int MEDCoupling1GTUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const
87 {
88   return type==getCellModelEnum()?getNumberOfCells():0;
89 }
90
91 /*!
92  * Returns a type of a cell by its id.
93  *  \param [in] cellId - the id of the cell of interest.
94  *  \return INTERP_KERNEL::NormalizedCellType - enumeration item describing the cell type.
95  *  \throw If \a cellId is invalid. Valid range is [0, \a this->getNumberOfCells() ).
96  */
97 INTERP_KERNEL::NormalizedCellType MEDCoupling1GTUMesh::getTypeOfCell(int cellId) const
98 {
99   if(cellId>=0 && cellId<getNumberOfCells())
100     return getCellModelEnum();
101   std::ostringstream oss; oss << "MEDCoupling1GTUMesh::getTypeOfCell : Requesting type of cell #" << cellId << " but it should be in [0," << getNumberOfCells() << ") !";
102   throw INTERP_KERNEL::Exception(oss.str().c_str());
103 }
104
105 /*!
106  * Returns a set of all cell types available in \a this mesh.
107  * \return std::set<INTERP_KERNEL::NormalizedCellType> - the set of cell types.
108  * \warning this method does not throw any exception even if \a this is not defined.
109  */
110 std::set<INTERP_KERNEL::NormalizedCellType> MEDCoupling1GTUMesh::getAllGeoTypes() const
111 {
112   std::set<INTERP_KERNEL::NormalizedCellType> ret;
113   ret.insert(getCellModelEnum());
114   return ret;
115 }
116
117 /*!
118  * This method expects that \a this is sorted by types. If not an exception will be thrown.
119  * This method returns in the same format as code (see MEDCouplingUMesh::checkTypeConsistencyAndContig or MEDCouplingUMesh::splitProfilePerType) how
120  * \a this is composed in cell types.
121  * The returned array is of size 3*n where n is the number of different types present in \a this. 
122  * For every k in [0,n] ret[3*k+2]==0 because it has no sense here. 
123  * This parameter is kept only for compatibility with other methode listed above.
124  */
125 std::vector<int> MEDCoupling1GTUMesh::getDistributionOfTypes() const throw(INTERP_KERNEL::Exception)
126 {
127   std::vector<int> ret(3);
128   ret[0]=(int)getCellModelEnum(); ret[1]=getNumberOfCells(); ret[2]=0;
129   return ret;
130 }
131
132 /*!
133  * 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.
134  * 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.
135  * This method has 1 input \a profile and 3 outputs \a code \a idsInPflPerType and \a idsPerType.
136  * 
137  * \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.
138  * \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,
139  *              \a idsInPflPerType[i] stores the tuple ids in \a profile that correspond to the geometric type code[3*i+0]
140  * \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.
141  *              This vector can be empty in case of all geometric type cells are fully covered in ascending in the given input \a profile.
142  * 
143  * \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.
144  *
145  * \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
146  *
147  *  \b Example1: <br>
148  *          - Before \a this has 3 cells \a profile contains [0,1,2]
149  *          - After \a code contains [NORM_...,nbCells,-1], \a idsInPflPerType [[0,1,2]] and \a idsPerType is empty <br>
150  * 
151  *  \b Example2: <br>
152  *          - Before \a this has 3 cells \a profile contains [1,2]
153  *          - After \a code contains [NORM_...,nbCells,0], \a idsInPflPerType [[0,1]] and \a idsPerType is [[1,2]] <br>
154
155  */
156 void MEDCoupling1GTUMesh::splitProfilePerType(const DataArrayInt *profile, std::vector<int>& code, std::vector<DataArrayInt *>& idsInPflPerType, std::vector<DataArrayInt *>& idsPerType) const throw(INTERP_KERNEL::Exception)
157 {
158   if(!profile)
159     throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::splitProfilePerType : input profile is NULL !");
160   if(profile->getNumberOfComponents()!=1)
161     throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::splitProfilePerType : input profile should have exactly one component !");
162   int nbTuples=profile->getNumberOfTuples();
163   int nbOfCells=getNumberOfCells();
164   code.resize(3); idsInPflPerType.resize(1);
165   code[0]=(int)getCellModelEnum(); code[1]=nbOfCells;
166   idsInPflPerType.resize(1);
167   if(profile->isIdentity() && nbTuples==nbOfCells)
168     {
169       code[2]=-1;
170       idsInPflPerType[0]=const_cast<DataArrayInt *>(profile); idsInPflPerType[0]->incrRef();
171       idsPerType.clear(); 
172     }
173   code[2]=0;
174   profile->checkAllIdsInRange(0,nbOfCells);
175   idsPerType.resize(1);
176   idsPerType[0]=const_cast<DataArrayInt *>(profile); idsPerType[0]->incrRef();
177   idsInPflPerType[0]=DataArrayInt::Range(0,nbTuples,1);
178 }
179
180 /*!
181  * This method tries to minimize at most the number of deep copy.
182  * So if \a idsPerType is not empty it can be returned directly (without copy, but with ref count incremented) in return.
183  * 
184  * \sa MEDCouplingUMesh::checkTypeConsistencyAndContig
185  */
186 DataArrayInt *MEDCoupling1GTUMesh::checkTypeConsistencyAndContig(const std::vector<int>& code, const std::vector<const DataArrayInt *>& idsPerType) const throw(INTERP_KERNEL::Exception)
187 {
188   int nbOfCells=getNumberOfCells();
189   if(code.size()!=3)
190     throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : invalid input code should be exactly of size 3 !");
191   if(code[0]!=(int)getCellModelEnum())
192     {
193       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() << ") !";
194       throw INTERP_KERNEL::Exception(oss.str().c_str());
195     }
196   if(code[2]==-1)
197     {
198       if(code[1]==nbOfCells)
199         return 0;
200       else
201         {
202           std::ostringstream oss; oss << "MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : mismatch between the number of cells in this (" << nbOfCells << ") and the number of non profile (" << code[1] << ") !";
203           throw INTERP_KERNEL::Exception(oss.str().c_str());
204         }
205     }
206   if(code[2]!=0)
207     throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : single geo type mesh ! 0 or -1 is expected at pos #2 of input code !");
208   if(idsPerType.size()!=1)
209     throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : input code points to DataArrayInt #0 whereas the size of idsPerType is not equal to 1 !");
210   const DataArrayInt *pfl=idsPerType[0];
211   if(!pfl)
212     throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : the input code points to a NULL DataArrayInt at rank 0 !");
213   if(pfl->getNumberOfComponents()!=1)
214     throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : input profile should have exactly one component !");
215   pfl->checkAllIdsInRange(0,nbOfCells);
216   pfl->incrRef();
217   return const_cast<DataArrayInt *>(pfl);
218 }
219
220 void MEDCoupling1GTUMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData) const throw(INTERP_KERNEL::Exception)
221 {
222   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
223   m->writeVTKLL(ofs,cellData,pointData);
224 }
225
226 std::string MEDCoupling1GTUMesh::getVTKDataSetType() const throw(INTERP_KERNEL::Exception)
227 {
228   return std::string("UnstructuredGrid");
229 }
230
231 bool MEDCoupling1GTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception)
232 {
233   if(!MEDCouplingPointSet::isEqualIfNotWhy(other,prec,reason))
234     return false;
235   if(!other)
236     throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::isEqualIfNotWhy : input other pointer is null !");
237   const MEDCoupling1GTUMesh *otherC=dynamic_cast<const MEDCoupling1GTUMesh *>(other);
238   if(!otherC)
239     {
240       reason="mesh given in input is not castable in MEDCouplingSGTUMesh !";
241       return false;
242     }
243   if(&_cm!=&otherC->_cm)
244     {
245       reason="mismatch in geometric type !";
246       return false;
247     }
248   return true;
249 }
250
251 bool MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
252 {
253   if(!MEDCouplingPointSet::isEqualWithoutConsideringStr(other,prec))
254     return false;
255   if(!other)
256     throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
257   const MEDCoupling1GTUMesh *otherC=dynamic_cast<const MEDCoupling1GTUMesh *>(other);
258   if(!otherC)
259     return false;
260   if(&_cm!=&otherC->_cm)
261     return false;
262   return true;
263 }
264
265 void MEDCoupling1GTUMesh::checkCoherency() const throw(INTERP_KERNEL::Exception)
266 {
267   MEDCouplingPointSet::checkCoherency();
268 }
269
270 DataArrayDouble *MEDCoupling1GTUMesh::getBarycenterAndOwner() const
271 {
272   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
273   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=m->getBarycenterAndOwner();
274   return ret.retn();
275 }
276
277 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::getMeasureField(bool isAbs) const
278 {
279   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
280   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=m->getMeasureField(isAbs);
281   ret->setMesh(this);
282   return ret.retn();
283 }
284
285 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::getMeasureFieldOnNode(bool isAbs) const
286 {
287   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
288   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=m->getMeasureFieldOnNode(isAbs);
289   ret->setMesh(this);
290   return ret.retn();
291 }
292
293 /*!
294  * to improve perf !
295  */
296 int MEDCoupling1GTUMesh::getCellContainingPoint(const double *pos, double eps) const
297 {
298   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
299   return m->getCellContainingPoint(pos,eps);
300 }
301
302 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::buildOrthogonalField() const
303 {
304   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
305   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=m->buildOrthogonalField();
306   ret->setMesh(this);
307   return ret.retn();
308 }
309
310 DataArrayInt *MEDCoupling1GTUMesh::getCellsInBoundingBox(const double *bbox, double eps) const
311 {
312   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
313   return m->getCellsInBoundingBox(bbox,eps);
314 }
315
316 DataArrayInt *MEDCoupling1GTUMesh::getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps)
317 {
318   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
319   return m->getCellsInBoundingBox(bbox,eps);
320 }
321
322 MEDCouplingPointSet *MEDCoupling1GTUMesh::buildFacePartOfMySelfNode(const int *start, const int *end, bool fullyIn) const
323 {
324   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
325   return m->buildFacePartOfMySelfNode(start,end,fullyIn);
326 }
327
328 DataArrayInt *MEDCoupling1GTUMesh::findBoundaryNodes() const
329 {
330   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
331   return m->findBoundaryNodes();
332 }
333
334 MEDCouplingPointSet *MEDCoupling1GTUMesh::buildBoundaryMesh(bool keepCoords) const
335 {
336   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
337   return m->buildBoundaryMesh(keepCoords);
338 }
339
340 void MEDCoupling1GTUMesh::findCommonCells(int compType, int startCellId, DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr) const throw(INTERP_KERNEL::Exception)
341 {
342   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
343   m->findCommonCells(compType,startCellId,commonCellsArr,commonCellsIArr);
344 }
345
346 //==
347
348 MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh(const MEDCoupling1SGTUMesh& other, bool recDeepCpy):MEDCoupling1GTUMesh(other,recDeepCpy),_conn(other._conn)
349 {
350   if(recDeepCpy)
351     {
352       const DataArrayInt *c(other._conn);
353       if(c)
354         _conn=c->deepCpy();
355     }
356 }
357
358 MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh(const char *name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm)
359 {
360 }
361
362 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New(const char *name, INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception)
363 {
364   if(type==INTERP_KERNEL::NORM_ERROR)
365     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
366   const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
367   if(cm.isDynamic())
368     {
369       std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::New : the input geometric type " << cm.getRepr() << " is dynamic ! Only static type are dealed here !";
370       throw INTERP_KERNEL::Exception(oss.str().c_str());
371     }
372   return new MEDCoupling1SGTUMesh(name,cm);
373 }
374
375 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::clone(bool recDeepCpy) const
376 {
377   return new MEDCoupling1SGTUMesh(*this,recDeepCpy);
378 }
379
380 void MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other) throw(INTERP_KERNEL::Exception)
381 {
382   if(!other)
383     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom : input pointer is null !");
384   const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
385   if(!otherC)
386     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1SGTUMesh instance !");
387   setNodalConnectivity(otherC->getNodalConnectivity());
388 }
389
390 void MEDCoupling1SGTUMesh::updateTime() const
391 {
392   MEDCoupling1GTUMesh::updateTime();
393   const DataArrayInt *c(_conn);
394   if(c)
395     updateTimeWith(*c);
396 }
397
398 std::size_t MEDCoupling1SGTUMesh::getHeapMemorySize() const
399 {
400   std::size_t ret=0;
401   const DataArrayInt *c(_conn);
402   if(c)
403     ret+=c->getHeapMemorySize();
404   return MEDCouplingPointSet::getHeapMemorySize()+ret;
405 }
406
407 MEDCouplingMesh *MEDCoupling1SGTUMesh::deepCpy() const
408 {
409   return clone(true);
410 }
411
412 bool MEDCoupling1SGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception)
413 {
414   if(!other)
415     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEqualIfNotWhy : input other pointer is null !");
416   std::ostringstream oss; oss.precision(15);
417   const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
418   if(!otherC)
419     {
420       reason="mesh given in input is not castable in MEDCoupling1SGTUMesh !";
421       return false;
422     }
423   if(!MEDCoupling1GTUMesh::isEqualIfNotWhy(other,prec,reason))
424     return false;
425   const DataArrayInt *c1(_conn),*c2(otherC->_conn);
426   if(c1==c2)
427     return true;
428   if(!c1 || !c2)
429     {
430       reason="in connectivity of single static geometric type exactly one among this and other is null !";
431       return false;
432     }
433   if(!c1->isEqualIfNotWhy(*c2,reason))
434     {
435       reason.insert(0,"Nodal connectivity DataArrayInt differ : ");
436       return false;
437     }
438   return true;
439 }
440
441 bool MEDCoupling1SGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
442 {
443   if(!other)
444     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
445   const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
446   if(!otherC)
447     return false;
448   if(!MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(other,prec))
449     return false;
450   const DataArrayInt *c1(_conn),*c2(otherC->_conn);
451   if(c1==c2)
452     return true;
453   if(!c1 || !c2)
454     return false;
455   if(!c1->isEqualWithoutConsideringStr(*c2))
456     return false;
457   return true;
458 }
459
460 void MEDCoupling1SGTUMesh::checkCoherency() const throw(INTERP_KERNEL::Exception)
461 {
462   MEDCoupling1SGTUMesh::checkCoherency();
463   const DataArrayInt *c1(_conn);
464   if(c1)
465     {
466       if(c1->getNumberOfComponents()!=1)
467         throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !");
468       if(c1->getInfoOnComponent(0)!="")
469         throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !");
470       c1->checkAllocated();
471     }
472   else
473     throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !");
474 }
475
476 void MEDCoupling1SGTUMesh::checkCoherency1(double eps) const throw(INTERP_KERNEL::Exception)
477 {
478   checkCoherency();
479   const DataArrayInt *c1(_conn);
480   int nbOfTuples=c1->getNumberOfTuples();
481   int nbOfNodesPerCell=(int)_cm->getNumberOfNodes();
482   if(nbOfTuples%nbOfNodesPerCell!=0)
483     {
484       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 !";
485       throw INTERP_KERNEL::Exception(oss.str().c_str());
486     }
487   int nbOfNodes=getNumberOfNodes();
488   int nbOfCells=nbOfTuples/nbOfNodesPerCell;
489   const int *w(c1->begin());
490   for(int i=0;i<nbOfCells;i++)
491     for(int j=0;j<nbOfNodesPerCell;j++,w++)
492       {
493         if(*w<0 || *w>=nbOfNodes)
494           {
495             std::ostringstream oss; oss << "At node #" << j << " of  cell #" << i << ", is equal to " << *w << " must be in [0," << nbOfNodes << ") !";
496             throw INTERP_KERNEL::Exception(oss.str().c_str());
497           }
498       }
499 }
500
501 void MEDCoupling1SGTUMesh::checkCoherency2(double eps) const throw(INTERP_KERNEL::Exception)
502 {
503   checkCoherency1(eps);
504 }
505
506 int MEDCoupling1SGTUMesh::getNumberOfCells() const
507 {
508   int nbOfTuples=getNodalConnectivityLength();
509   int nbOfNodesPerCell=getNumberOfNodesPerCell();
510   if(nbOfTuples%nbOfNodesPerCell!=0)
511     {
512       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 !";
513       throw INTERP_KERNEL::Exception(oss.str().c_str());
514     }
515   return nbOfTuples/nbOfNodesPerCell;
516 }
517
518 int MEDCoupling1SGTUMesh::getNumberOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
519 {
520   checkNonDynamicGeoType();
521   return (int)_cm->getNumberOfNodes();
522 }
523
524 int MEDCoupling1SGTUMesh::getNodalConnectivityLength() const throw(INTERP_KERNEL::Exception)
525 {
526   const DataArrayInt *c1(_conn);
527   if(!c1)
528     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::getNodalConnectivityLength : no connectivity set !");
529   if(c1->getNumberOfComponents()!=1)
530     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::getNodalConnectivityLength : Nodal connectivity array set must have exactly one component !");
531   if(!c1->isAllocated())
532     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::getNodalConnectivityLength : Nodal connectivity array must be allocated !");
533   return c1->getNumberOfTuples();
534 }
535
536 DataArrayInt *MEDCoupling1SGTUMesh::computeNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
537 {
538   checkNonDynamicGeoType();
539   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
540   ret->alloc(getNumberOfCells(),1);
541   ret->fillWithValue((int)_cm->getNumberOfNodes());
542   return ret.retn();
543 }
544
545 DataArrayInt *MEDCoupling1SGTUMesh::computeNbOfFacesPerCell() const throw(INTERP_KERNEL::Exception)
546 {
547   checkNonDynamicGeoType();
548   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
549   ret->alloc(getNumberOfCells(),1);
550   ret->fillWithValue((int)_cm->getNumberOfSons());
551   return ret.retn();
552 }
553
554 void MEDCoupling1SGTUMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
555 {
556   int sz=getNumberOfNodesPerCell();
557   conn.resize(sz);
558   if(cellId>=0 && cellId<getNumberOfCells())
559     std::copy(_conn->begin()+cellId*sz,_conn->begin()+(cellId+1)*sz,conn.begin());
560   else
561     {
562       std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << getNumberOfCells() << ") !";
563       throw INTERP_KERNEL::Exception(oss.str().c_str());
564     }
565 }
566
567 void MEDCoupling1SGTUMesh::checkNonDynamicGeoType() const throw(INTERP_KERNEL::Exception)
568 {
569   if(_cm->isDynamic())
570     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkNonDynamicGeoType : internal error ! the internal geo type is dynamic ! should be static !");
571 }
572
573 std::string MEDCoupling1SGTUMesh::simpleRepr() const
574 {
575   static const char msg0[]="No coordinates specified !";
576   std::ostringstream ret;
577   ret << "Single static geometic type unstructured mesh with name : \"" << getName() << "\"\n";
578   ret << "Description of mesh : \"" << getDescription() << "\"\n";
579   int tmpp1,tmpp2;
580   double tt=getTime(tmpp1,tmpp2);
581   ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
582   ret << "Iteration : " << tmpp1  << " Order : " << tmpp2 << "\n";
583   ret << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : ";
584   if(_coords!=0)
585     {
586       const int spaceDim=getSpaceDimension();
587       ret << spaceDim << "\nInfo attached on space dimension : ";
588       for(int i=0;i<spaceDim;i++)
589         ret << "\"" << _coords->getInfoOnComponent(i) << "\" ";
590       ret << "\n";
591     }
592   else
593     ret << msg0 << "\n";
594   ret << "Number of nodes : ";
595   if(_coords!=0)
596     ret << getNumberOfNodes() << "\n";
597   else
598     ret << msg0 << "\n";
599   ret << "Number of cells : ";
600   if((const DataArrayInt *)_conn)
601     {
602       if(_conn->isAllocated())
603         {
604           if(_conn->getNumberOfComponents()==1)
605             ret << getNumberOfCells() << "\n";
606           else
607             ret << "Nodal connectivity array specified and allocated but with not exactly one component !" << "\n";
608         }
609       else
610         ret << "Nodal connectivity array specified but not allocated !" << "\n";
611     }
612   else
613     ret << "No connectivity specified !" << "\n";
614   ret << "Cell type : " << _cm->getRepr() << "\n";
615   return ret.str();
616 }
617
618 std::string MEDCoupling1SGTUMesh::advancedRepr() const
619 {
620   std::ostringstream ret;
621   ret << simpleRepr();
622   ret << "\nCoordinates array : \n___________________\n\n";
623   if(_coords)
624     _coords->reprWithoutNameStream(ret);
625   else
626     ret << "No array set !\n";
627   ret << "\n\nConnectivity array : \n____________________\n\n";
628   //
629   if((const DataArrayInt *)_conn)
630     {
631       if(_conn->isAllocated())
632         {
633           if(_conn->getNumberOfComponents()==1)
634             {
635              int nbOfCells=getNumberOfCells();
636              int sz=getNumberOfNodesPerCell();
637              const int *connPtr=_conn->begin();
638              for(int i=0;i<nbOfCells;i++,connPtr+=sz)
639                {
640                  ret << "Cell #" << i << " : ";
641                  std::copy(connPtr,connPtr+sz,std::ostream_iterator<int>(ret," "));
642                  ret << "\n";
643                }
644             }
645           else
646             ret << "Nodal connectivity array specified and allocated but with not exactly one component !" << "\n";
647         }
648       else
649         ret << "Nodal connectivity array specified but not allocated !" << "\n";
650     }
651   else
652     ret << "No connectivity specified !" << "\n";
653   return ret.str();
654 }
655
656 DataArrayDouble *MEDCoupling1SGTUMesh::computeIsoBarycenterOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
657 {
658   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
659   int spaceDim=getSpaceDimension();
660   int nbOfCells=getNumberOfCells();
661   int nbOfNodes=getNumberOfNodes();
662   ret->alloc(nbOfCells,spaceDim);
663   double *ptToFill=ret->getPointer();
664   const double *coor=_coords->begin();
665   const int *nodal=_conn->begin();
666   int sz=getNumberOfNodesPerCell();
667   double coeff=1./(double)sz;
668   for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim)
669     {
670       std::fill(ptToFill,ptToFill+spaceDim,0.);
671       for(int j=0;j<sz;j++,nodal++)
672         if(*nodal>=0 && *nodal<nbOfNodes)
673           std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
674         else
675           {
676             std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," <<   nbOfNodes << ") !";
677             throw INTERP_KERNEL::Exception(oss.str().c_str());
678           }
679       std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),coeff));
680     }
681   return ret.retn();
682 }
683
684 void MEDCoupling1SGTUMesh::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception)
685 {
686   int nbCells=getNumberOfCells();
687   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::New();
688   o2n->useArray(old2NewBg,false,C_DEALLOC,nbCells,1);
689   if(check)
690     o2n=o2n->checkAndPreparePermutation();
691   //
692   const int *conn=_conn->begin();
693   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> n2o=o2n->invertArrayO2N2N2O(nbCells);
694   const int *n2oPtr=n2o->begin();
695   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New();
696   newConn->alloc(_conn->getNumberOfTuples(),1);
697   newConn->copyStringInfoFrom(*_conn);
698   int sz=getNumberOfNodesPerCell();
699   //
700   int *newC=newConn->getPointer();
701   for(int i=0;i<nbCells;i++,newC+=sz)
702     {
703       int pos=n2oPtr[i];
704       std::copy(conn+pos*sz,conn+(pos+1)*sz,newC);
705     }
706   _conn=newConn;
707 }
708
709 /*!
710  * Keeps from \a this only cells which constituing point id are in the ids specified by [\a begin,\a end).
711  * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
712  * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not.
713  * If \a fullyIn is true only cells whose ids are \b fully contained in [\a begin,\a end) tab will be kept.
714  *
715  * \param [in] begin input start of array of node ids.
716  * \param [in] end input end of array of node ids.
717  * \param [in] fullyIn input that specifies if all node ids must be in [\a begin,\a end) array to consider cell to be in.
718  * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end.
719  */
720 void MEDCoupling1SGTUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const
721 {
722   int nbOfCells=getNumberOfCells();
723   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1);
724   int tmp=-1;
725   int sz=_conn->getMaxValue(tmp); sz=std::max(sz,0)+1;
726   std::vector<bool> fastFinder(sz,false);
727   for(const int *work=begin;work!=end;work++)
728     if(*work>=0 && *work<sz)
729       fastFinder[*work]=true;
730   const int *conn=_conn->begin();
731   int nbNodesPerCell=getNumberOfNodesPerCell();
732   for(int i=0;i<nbOfCells;i++,conn+=nbNodesPerCell)
733     {
734       int ref=0,nbOfHit=0;
735       for(int j=0;j<nbNodesPerCell;j++)
736         if(conn[j]>=0)
737           {
738             ref++;
739             if(fastFinder[conn[j]])
740               nbOfHit++;
741           }
742       if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn))
743         cellIdsKept->pushBackSilent(i);
744     }
745   cellIdsKeptArr=cellIdsKept.retn();
746 }
747
748 MEDCouplingMesh *MEDCoupling1SGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
749 {
750   if(other->getType()!=SINGLE_STATIC_GEO_TYPE_UNSTRUCTURED)
751     throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single static geo type each other !");
752   const MEDCoupling1SGTUMesh *otherC=static_cast<const MEDCoupling1SGTUMesh *>(other);
753   return Merge1SGTUMeshes(this,otherC);
754 }
755
756 MEDCouplingUMesh *MEDCoupling1SGTUMesh::buildUnstructured() const throw(INTERP_KERNEL::Exception)
757 {
758   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName(),getMeshDimension());
759   ret->setCoords(getCoords());
760   const int *nodalConn=_conn->begin();
761   int nbCells=getNumberOfCells();
762   int nbNodesPerCell=getNumberOfNodesPerCell();
763   int geoType=(int)getCellModelEnum();
764   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New(); c->alloc(nbCells*(nbNodesPerCell+1),1);
765   int *cPtr=c->getPointer();
766   for(int i=0;i<nbCells;i++,nodalConn+=nbNodesPerCell)
767     {
768       *cPtr++=geoType;
769       cPtr=std::copy(nodalConn,nodalConn+nbNodesPerCell,cPtr);
770     }
771   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cI=DataArrayInt::Range(0,(nbCells+1)*(nbNodesPerCell+1),nbNodesPerCell+1);
772   ret->setConnectivity(c,cI,true);
773   return ret.retn();
774 }
775
776 DataArrayInt *MEDCoupling1SGTUMesh::simplexize(int policy) throw(INTERP_KERNEL::Exception)
777 {
778   switch(policy)
779     {
780     case 0:
781       return simplexizePol0();
782     case 1:
783       return simplexizePol1();
784     case (int) INTERP_KERNEL::PLANAR_FACE_5:
785       return simplexizePlanarFace5();
786     case (int) INTERP_KERNEL::PLANAR_FACE_6:
787       return simplexizePlanarFace6();
788     default:
789       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)");
790     }
791 }
792
793 /*!
794  * \return DataArrayInt * - the permutation array in "Old to New" mode. For more 
795  *         info on "Old to New" mode see \ref MEDCouplingArrayRenumbering. The caller
796  *         is to delete this array using decrRef() as it is no more needed.
797  */
798 DataArrayInt *MEDCoupling1SGTUMesh::mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes)
799 {
800   DataArrayInt *ret=buildPermArrayForMergeNode(precision,-1,areNodesMerged,newNbOfNodes);
801   if(areNodesMerged)
802     renumberNodes(ret->getConstPointer(),newNbOfNodes);
803   return ret;
804 }
805
806 /*!
807  * \return DataArrayInt * - the permutation array in "Old to New" mode. For more 
808  *         info on "Old to New" mode see \ref MEDCouplingArrayRenumbering. The caller
809  *         is to delete this array using decrRef() as it is no more needed.
810  */
811 DataArrayInt *MEDCoupling1SGTUMesh::mergeNodes2(double precision, bool& areNodesMerged, int& newNbOfNodes)
812 {
813   DataArrayInt *ret=buildPermArrayForMergeNode(precision,-1,areNodesMerged,newNbOfNodes);
814   if(areNodesMerged)
815     renumberNodes2(ret->getConstPointer(),newNbOfNodes);
816   return ret;
817 }
818
819 /*!
820  * Removes unused nodes (the node coordinates array is shorten) and returns an array
821  * mapping between new and old node ids in "Old to New" mode. -1 values in the returned
822  * array mean that the corresponding old node is no more used. 
823  *  \return DataArrayInt * - a new instance of DataArrayInt of length \a
824  *           this->getNumberOfNodes() before call of this method. The caller is to
825  *           delete this array using decrRef() as it is no more needed. 
826  *  \throw If the coordinates array is not set.
827  *  \throw If the nodal connectivity of cells is not defined.
828  *  \throw If the nodal connectivity includes an invalid id.
829  *
830  *  \ref cpp_mcumesh_zipCoordsTraducer "Here is a C++ example".<br>
831  *  \ref  py_mcumesh_zipCoordsTraducer "Here is a Python example".
832  */
833 DataArrayInt *MEDCoupling1SGTUMesh::zipCoordsTraducer() throw(INTERP_KERNEL::Exception)
834 {
835   int newNbOfNodes=-1;
836   DataArrayInt *traducer=getNodeIdsInUse(newNbOfNodes);
837   renumberNodes(traducer->getConstPointer(),newNbOfNodes);
838   return traducer;
839 }
840
841 /// @cond INTERNAL
842
843 struct MEDCouplingAccVisit
844 {
845   MEDCouplingAccVisit():_new_nb_of_nodes(0) { }
846   int operator()(int val) { if(val!=-1) return _new_nb_of_nodes++; else return -1; }
847   int _new_nb_of_nodes;
848 };
849
850 /// @endcond
851
852 /*!
853  * Finds nodes not used in any cell and returns an array giving a new id to every node
854  * by excluding the unused nodes, for which the array holds -1. The result array is
855  * a mapping in "Old to New" mode. 
856  *  \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
857  *  \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a
858  *          this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
859  *          if the node is unused or a new id else. The caller is to delete this
860  *          array using decrRef() as it is no more needed.  
861  *  \throw If the coordinates array is not set.
862  *  \throw If the nodal connectivity of cells is not defined.
863  *  \throw If the nodal connectivity includes an invalid id.
864  */
865 DataArrayInt *MEDCoupling1SGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const throw(INTERP_KERNEL::Exception)
866 {
867   nbrOfNodesInUse=-1;
868   int nbOfNodes=getNumberOfNodes();
869   int nbOfCells=getNumberOfCells();
870   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
871   ret->alloc(nbOfNodes,1);
872   int *traducer=ret->getPointer();
873   std::fill(traducer,traducer+nbOfNodes,-1);
874   const int *conn=_conn->begin();
875   int nbNodesPerCell=getNumberOfNodesPerCell();
876   for(int i=0;i<nbOfCells;i++)
877     for(int j=0;j<nbNodesPerCell;j++)
878       if(conn[j]>=0 && conn[j]<nbOfNodes)
879         traducer[conn[j]]=1;
880       else
881         {
882           std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsInUse : In cell #" << i  << " presence of node id " <<  conn[j] << " not in [0," << nbOfNodes << ") !";
883           throw INTERP_KERNEL::Exception(oss.str().c_str());
884         }
885   nbrOfNodesInUse=(int)std::count(traducer,traducer+nbOfNodes,1);
886   std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
887   return ret.retn();
888 }
889
890 /*!
891  * Changes ids of nodes within the nodal connectivity arrays according to a permutation
892  * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
893  * This method is a generalization of shiftNodeNumbersInConn().
894  *  \warning This method performs no check of validity of new ids. **Use it with care !**
895  *  \param [in] newNodeNumbersO2N - a permutation array, of length \a
896  *         this->getNumberOfNodes(), in "Old to New" mode. 
897  *         See \ref MEDCouplingArrayRenumbering for more info on renumbering modes.
898  *  \throw If the nodal connectivity of cells is not defined.
899  */
900 void MEDCoupling1SGTUMesh::renumberNodesInConn(const int *newNodeNumbersO2N)
901 {
902   getNumberOfCells();//only to check that all is well defined.
903   _conn->renumberInPlace(newNodeNumbersO2N);
904   updateTime();
905 }
906
907 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(const MEDCoupling1SGTUMesh *mesh1, const MEDCoupling1SGTUMesh *mesh2) throw(INTERP_KERNEL::Exception)
908 {
909   std::vector<const MEDCoupling1SGTUMesh *> tmp(2);
910   tmp[0]=const_cast<MEDCoupling1SGTUMesh *>(mesh1); tmp[1]=const_cast<MEDCoupling1SGTUMesh *>(mesh2);
911   return Merge1SGTUMeshes(tmp);
912 }
913
914 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(std::vector<const MEDCoupling1SGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
915 {
916   std::size_t sz=a.size();
917   if(sz==0)
918     return Merge1SGTUMeshesLL(a);
919   for(std::size_t ii=0;ii<sz;ii++)
920     if(!a[ii])
921       {
922         std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::Merge1SGTUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !";
923         throw INTERP_KERNEL::Exception(oss.str().c_str());
924       }
925   const INTERP_KERNEL::CellModel *cm=&(a[0]->getCellModel());
926   for(std::size_t ii=0;ii<sz;ii++)
927     if(&(a[ii]->getCellModel())!=cm)
928       throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : all items must have the same geo type !");
929   std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> > bb(sz);
930   std::vector< const MEDCoupling1SGTUMesh * > aa(sz);
931   int spaceDim=-3;
932   for(std::size_t i=0;i<sz && spaceDim==-3;i++)
933     {
934       const MEDCoupling1SGTUMesh *cur=a[i];
935       const DataArrayDouble *coo=cur->getCoords();
936       if(coo)
937         spaceDim=coo->getNumberOfComponents();
938     }
939   if(spaceDim==-3)
940     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : no spaceDim specified ! unable to perform merge !");
941   for(std::size_t i=0;i<sz;i++)
942     {
943       bb[i]=a[i]->buildSetInstanceFromThis(spaceDim);
944       aa[i]=bb[i];
945     }
946   return Merge1SGTUMeshesLL(aa);
947 }
948
949 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords(std::vector<const MEDCoupling1SGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
950 {
951   if(a.empty())
952     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : input array must be NON EMPTY !");
953   std::vector<const MEDCoupling1SGTUMesh *>::const_iterator it=a.begin();
954   if(!(*it))
955     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : presence of null instance !");
956   int nbOfCells=(*it)->getNumberOfCells();
957   const DataArrayDouble *coords=(*it)->getCoords();
958   const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
959   int nbNodesPerCell=(*it)->getNumberOfNodesPerCell();
960   for(;it!=a.end();it++)
961     {
962       if(cm!=&((*it)->getCellModel()))
963         throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !");
964       nbOfCells+=(*it)->getNumberOfCells();
965       if(coords!=(*it)->getCoords())
966         throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : not lying on same coords !");
967     }
968   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh("merge",*cm));
969   ret->setCoords(coords);
970   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New();
971   c->alloc(nbOfCells*nbNodesPerCell,1);
972   int *cPtr=c->getPointer();
973   int offset=0;
974   for(it=a.begin();it!=a.end();it++)
975     {
976       int curConnLgth=(*it)->getNodalConnectivityLength();
977       const int *curC=(*it)->_conn->begin();
978       cPtr=std::copy(curC,curC+curConnLgth,cPtr);
979     }
980   //
981   ret->_conn=c;
982   return ret.retn();
983 }
984
985 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesLL(std::vector<const MEDCoupling1SGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
986 {
987   if(a.empty())
988     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : input array must be NON EMPTY !");
989   std::vector<const MEDCoupling1SGTUMesh *>::const_iterator it=a.begin();
990   int nbOfCells=(*it)->getNumberOfCells();
991   const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
992   int nbNodesPerCell=(*it)->getNumberOfNodesPerCell();
993   for(;it!=a.end();it++)
994     {
995       if(cm!=&((*it)->getCellModel()))
996         throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !");
997       nbOfCells+=(*it)->getNumberOfCells();
998     }
999   std::vector<const MEDCouplingPointSet *> aps(a.size());
1000   std::copy(a.begin(),a.end(),aps.begin());
1001   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> pts=MergeNodesArray(aps);
1002   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh("merge",*cm));
1003   ret->setCoords(pts);
1004   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New();
1005   c->alloc(nbOfCells*nbNodesPerCell,1);
1006   int *cPtr=c->getPointer();
1007   int offset=0;
1008   for(it=a.begin();it!=a.end();it++)
1009     {
1010       int curConnLgth=(*it)->getNodalConnectivityLength();
1011       const int *curC=(*it)->_conn->begin();
1012       cPtr=std::transform(curC,curC+curConnLgth,cPtr,std::bind2nd(std::plus<int>(),offset));
1013       offset+=(*it)->getNumberOfNodes();
1014     }
1015   //
1016   ret->_conn=c;
1017   return ret.retn();
1018 }
1019
1020 MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const
1021 {
1022   int ncell=getNumberOfCells();
1023   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
1024   ret->setCoords(_coords);
1025   std::size_t nbOfElemsRet=std::distance(begin,end);
1026   const int *inConn=_conn->getConstPointer();
1027   int sz=getNumberOfNodesPerCell();
1028   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connRet=DataArrayInt::New(); connRet->alloc((int)nbOfElemsRet*sz,1);
1029   int *connPtr=connRet->getPointer();
1030   for(const int *work=begin;work!=end;work++,connPtr+=sz)
1031     {
1032       if(*work>=0 && *work<ncell)
1033         std::copy(inConn+(work[0])*sz,inConn+(work[0]+1)*sz,connPtr);
1034       else
1035         {
1036           std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords : On pos #" << std::distance(begin,work) << " input cell id =" << *work << " should be in [0," << ncell << ") !";
1037           throw INTERP_KERNEL::Exception(oss.str().c_str());
1038         }
1039     }
1040   ret->_conn=connRet;
1041   ret->copyTinyInfoFrom(this);
1042   return ret.retn();
1043 }
1044
1045 MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const
1046 {
1047   int ncell=getNumberOfCells();
1048   int nbOfElemsRet=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2 : ");
1049   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
1050   ret->setCoords(_coords);
1051   const int *inConn=_conn->getConstPointer();
1052   int sz=getNumberOfNodesPerCell();
1053   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connRet=DataArrayInt::New(); connRet->alloc((int)nbOfElemsRet*sz,1);
1054   int *connPtr=connRet->getPointer();
1055   int curId=start;
1056   for(int i=0;i<nbOfElemsRet;i++,connPtr+=sz,curId+=step)
1057     {
1058       if(curId>=0 && curId<ncell)
1059         std::copy(inConn+curId*sz,inConn+(curId+1)*sz,connPtr);
1060       else
1061         {
1062           std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2 : On pos #" << i << " input cell id =" << curId  << " should be in [0," << ncell << ") !";
1063           throw INTERP_KERNEL::Exception(oss.str().c_str());
1064         }
1065     }
1066   ret->_conn=connRet;
1067   ret->copyTinyInfoFrom(this);
1068   return ret.retn();
1069 }
1070
1071 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::buildSetInstanceFromThis(int spaceDim) const throw(INTERP_KERNEL::Exception)
1072 {
1073   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm));
1074   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1;
1075   const DataArrayInt *nodalConn(_conn);
1076   if(!nodalConn)
1077     {
1078       tmp1=DataArrayInt::New(); tmp1->alloc(0,1);
1079     }
1080   else
1081     {
1082       tmp1=_conn;
1083       tmp1->incrRef();
1084     }
1085   ret->_conn=tmp1;
1086   if(!_coords)
1087     {
1088       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim);
1089       ret->setCoords(coords);
1090     }
1091   else
1092     ret->setCoords(_coords);
1093   return ret.retn();
1094 }
1095
1096 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePol0() throw(INTERP_KERNEL::Exception)
1097 {
1098   int nbOfCells=getNumberOfCells();
1099   if(getCellModelEnum()!=INTERP_KERNEL::NORM_QUAD4)
1100     return DataArrayInt::Range(0,nbOfCells,1);
1101   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(2*3*nbOfCells,1);
1102   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(2*nbOfCells,1);
1103   const int *c(_conn->begin());
1104   int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1105   for(int i=0;i<nbOfCells;i++,c+=4,newConnPtr+=6,retPtr+=2)
1106     {
1107       newConnPtr[0]=c[0]; newConnPtr[1]=c[1]; newConnPtr[2]=c[2];
1108       newConnPtr[3]=c[0]; newConnPtr[4]=c[2]; newConnPtr[5]=c[3];
1109       retPtr[0]=i; retPtr[1]=i;
1110     }
1111   _conn=newConn;
1112   _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TRI3);
1113   updateTime();
1114   return ret.retn();
1115 }
1116
1117 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePol1() throw(INTERP_KERNEL::Exception)
1118 {
1119   int nbOfCells=getNumberOfCells();
1120   if(getCellModelEnum()!=INTERP_KERNEL::NORM_QUAD4)
1121     return DataArrayInt::Range(0,nbOfCells,1);
1122   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(2*3*nbOfCells,1);
1123   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(2*nbOfCells,1);
1124   const int *c(_conn->begin());
1125   int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1126   for(int i=0;i<nbOfCells;i++,c+=4,newConnPtr+=6,retPtr+=2)
1127     {
1128       newConnPtr[0]=c[0]; newConnPtr[1]=c[1]; newConnPtr[2]=c[3];
1129       newConnPtr[3]=c[1]; newConnPtr[4]=c[2]; newConnPtr[5]=c[3];
1130       retPtr[0]=i; retPtr[1]=i;
1131     }
1132   _conn=newConn;
1133   _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TRI3);
1134   updateTime();
1135   return ret.retn();
1136 }
1137
1138 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePlanarFace5() throw(INTERP_KERNEL::Exception)
1139 {
1140   int nbOfCells=getNumberOfCells();
1141   if(getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA8)
1142     return DataArrayInt::Range(0,nbOfCells,1);
1143   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(5*4*nbOfCells,1);
1144   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(5*nbOfCells,1);
1145   const int *c(_conn->begin());
1146   int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1147   for(int i=0;i<nbOfCells;i++,c+=8,newConnPtr+=20,retPtr+=5)
1148     {
1149       for(int j=0;j<20;j++)
1150         newConnPtr[j]=c[INTERP_KERNEL::SPLIT_NODES_5_WO[j]];
1151       retPtr[0]=i; retPtr[1]=i; retPtr[2]=i; retPtr[3]=i; retPtr[4]=i;
1152     }
1153   _conn=newConn;
1154   _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TETRA4);
1155   updateTime();
1156   return ret.retn();
1157 }
1158
1159 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePlanarFace6() throw(INTERP_KERNEL::Exception)
1160 {
1161   int nbOfCells=getNumberOfCells();
1162   if(getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA8)
1163     return DataArrayInt::Range(0,nbOfCells,1);
1164   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(6*4*nbOfCells,1);
1165   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(6*nbOfCells,1);
1166   const int *c(_conn->begin());
1167   int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1168   for(int i=0;i<nbOfCells;i++,c+=8,newConnPtr+=20,retPtr+=6)
1169     {
1170       for(int j=0;j<24;j++)
1171         newConnPtr[j]=c[INTERP_KERNEL::SPLIT_NODES_6_WO[j]];
1172       retPtr[0]=i; retPtr[1]=i; retPtr[2]=i; retPtr[3]=i; retPtr[4]=i; retPtr[5]=i;
1173     }
1174   _conn=newConn;
1175   _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TETRA4);
1176   updateTime();
1177   return ret.retn();
1178 }
1179
1180 void MEDCoupling1SGTUMesh::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1181 {
1182   stream << "MEDCoupling1SGTUMesh C++ instance at " << this << ". Name : \"" << getName() << "\".";
1183   stream << " Mesh dimension : " << getMeshDimension() << ".";
1184   if(!_coords)
1185     { stream << " No coordinates set !"; return ; }
1186   if(!_coords->isAllocated())
1187     { stream << " Coordinates set but not allocated !"; return ; }
1188   stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
1189   stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
1190   if(!(const DataArrayInt *)_conn)
1191     { stream << std::endl << "Nodal connectivity NOT set !"; return ; }
1192   if(_conn->isAllocated())
1193     {
1194       if(_conn->getNumberOfComponents()==1)
1195         stream << std::endl << "Number of cells : " << getNumberOfCells() << ".";
1196     }
1197 }
1198
1199 void MEDCoupling1SGTUMesh::checkFullyDefined() const throw(INTERP_KERNEL::Exception)
1200 {
1201   if(!((const DataArrayInt *)_conn) || !((const DataArrayDouble *)_coords))
1202     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFullyDefined : part of this is not fully defined.");
1203 }
1204
1205 /*!
1206  * First step of unserialization process.
1207  */
1208 bool MEDCoupling1SGTUMesh::isEmptyMesh(const std::vector<int>& tinyInfo) const
1209 {
1210   throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEmptyMesh : not implemented yet !");
1211 }
1212
1213 /*!
1214  * Checks if \a this and \a other meshes are geometrically equivalent with high
1215  * probability, else an exception is thrown. The meshes are considered equivalent if
1216  * (1) meshes contain the same number of nodes and the same number of elements of the
1217  * same types (2) three cells of the two meshes (first, last and middle) are based
1218  * on coincident nodes (with a specified precision).
1219  *  \param [in] other - the mesh to compare with.
1220  *  \param [in] prec - the precision used to compare nodes of the two meshes.
1221  *  \throw If the two meshes do not match.
1222  */
1223 void MEDCoupling1SGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception)
1224 {
1225   MEDCouplingPointSet::checkFastEquivalWith(other,prec);
1226   const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
1227   if(!otherC)
1228     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : Two meshes are not not unstructured with single static geometric type !");
1229 }
1230
1231 MEDCouplingPointSet *MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const
1232 {
1233   if(!other)
1234     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : input other is null !");
1235   const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
1236   if(!otherC)
1237     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !");
1238   std::vector<const MEDCoupling1SGTUMesh *> ms(2);
1239   ms[0]=this;
1240   ms[1]=otherC;
1241   return Merge1SGTUMeshesOnSameCoords(ms);
1242 }
1243
1244 void MEDCoupling1SGTUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const throw(INTERP_KERNEL::Exception)
1245 {
1246   checkFullyDefined();
1247   int nbOfNodes=getNumberOfNodes();
1248   int *revNodalIndxPtr=(int *)malloc((nbOfNodes+1)*sizeof(int));
1249   revNodalIndx->useArray(revNodalIndxPtr,true,C_DEALLOC,nbOfNodes+1,1);
1250   std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
1251   const int *conn=_conn->begin();
1252   int nbOfCells=getNumberOfCells();
1253   int nbOfEltsInRevNodal=0;
1254   int nbOfNodesPerCell=getNumberOfNodesPerCell();
1255   for(int eltId=0;eltId<nbOfCells;eltId++)
1256     {
1257       for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1258         {
1259           if(conn[0]>=0 && conn[0]<nbOfNodes)
1260             {
1261               nbOfEltsInRevNodal++;
1262               revNodalIndxPtr[conn[0]+1]++;
1263             }
1264           else
1265             {
1266               std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !";
1267               throw INTERP_KERNEL::Exception(oss.str().c_str());
1268             }
1269         }
1270     }
1271   std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<int>());
1272   conn=_conn->begin();
1273   int *revNodalPtr=(int *)malloc((nbOfEltsInRevNodal)*sizeof(int));
1274   revNodal->useArray(revNodalPtr,true,C_DEALLOC,nbOfEltsInRevNodal,1);
1275   std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
1276   for(int eltId=0;eltId<nbOfCells;eltId++)
1277     {
1278       for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1279         {
1280           *std::find_if(revNodalPtr+revNodalIndxPtr[*conn],revNodalPtr+revNodalIndxPtr[*conn+1],std::bind2nd(std::equal_to<int>(),-1))=eltId;
1281         }
1282     }
1283 }
1284
1285 /*!
1286  * Use \a nodalConn array as nodal connectivity of \a this. The input \a nodalConn pointer can be null.
1287  * This method tests, if the input \a nodalConn is not null, that :
1288  * - it has one component.
1289  * - the number of tuples compatible with the number of node per cell.
1290  */
1291 void MEDCoupling1SGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn) throw(INTERP_KERNEL::Exception)
1292 {
1293   if(!nodalConn)
1294     {
1295       _conn=nodalConn;
1296       return;
1297     }
1298   const DataArrayInt *c1(nodalConn);
1299   if(c1->getNumberOfComponents()!=1)
1300     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::setNodalConnectivity : input nodal connectivity array set must have exactly one component !");
1301   if(!c1->isAllocated())
1302     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::setNodalConnectivity : input nodal connectivity array must be allocated !");
1303   int nbTuples=c1->getNumberOfTuples();
1304   if(nbTuples%getNumberOfNodesPerCell()!=0)
1305     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::setNodalConnectivity : input nodal connectivity number of tuples is incompatible with geometric type !");
1306   nodalConn->incrRef();
1307   _conn=nodalConn;
1308   declareAsNew();
1309 }
1310
1311 /*!
1312  * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it.
1313  */
1314 DataArrayInt *MEDCoupling1SGTUMesh::getNodalConnectivity() const throw(INTERP_KERNEL::Exception)
1315 {
1316   const DataArrayInt *ret(_conn);
1317   return const_cast<DataArrayInt *>(ret);
1318 }
1319
1320 /*!
1321  * Allocates memory to store an estimation of the given number of cells. Closer is the estimation to the number of cells effectively inserted,
1322  * less will be the needs to realloc. If the number of cells to be inserted is not known simply put 0 to this parameter.
1323  * If a nodal connectivity previouly existed before the call of this method, it will be reset.
1324  *
1325  *  \param [in] nbOfCells - estimation of the number of cell \a this mesh will contain.
1326  */
1327 void MEDCoupling1SGTUMesh::allocateCells(int nbOfCells) throw(INTERP_KERNEL::Exception)
1328 {
1329   if(nbOfCells<0)
1330     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::allocateCells : the input number of cells should be >= 0 !");
1331   _conn=DataArrayInt::New();
1332   _conn->reserve(getNumberOfNodesPerCell()*nbOfCells);
1333   declareAsNew();
1334 }
1335
1336 /*!
1337  * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ).
1338  *
1339  * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add.
1340  * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
1341  * \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
1342  *        attached to \a this.
1343  * \thow If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
1344  */
1345 void MEDCoupling1SGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd) throw(INTERP_KERNEL::Exception)
1346 {
1347   int sz=(int)std::distance(nodalConnOfCellBg,nodalConnOfCellEnd);
1348   int ref=getNumberOfNodesPerCell();
1349   if(sz==ref)
1350     {
1351       DataArrayInt *c(_conn);
1352       if(c)
1353         c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd);
1354       else
1355         throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1SGTUMesh::allocateCells before !");
1356     }
1357   else
1358     {
1359       std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::insertNextCell : input nodal size (" << sz << ") does not match number of nodes per cell of this (";
1360       oss << ref << ") !";
1361       throw INTERP_KERNEL::Exception(oss.str().c_str());
1362     }
1363 }