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