Salome HOME
Merge from V6_main 01/04/2013
[tools/medcoupling.git] / src / MEDCoupling / MEDCouplingCurveLinearMesh.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 "MEDCouplingCurveLinearMesh.hxx"
22 #include "MEDCouplingPointSet.hxx"
23 #include "MEDCouplingMemArray.hxx"
24 #include "MEDCouplingFieldDouble.hxx"
25
26 #include "VolSurfUser.txx"
27 #include "PointLocatorAlgos.txx"
28
29 #include <functional>
30 #include <algorithm>
31 #include <sstream>
32 #include <numeric>
33
34 using namespace ParaMEDMEM;
35
36 MEDCouplingCurveLinearMesh::MEDCouplingCurveLinearMesh():_coords(0),_structure(0)
37 {
38 }
39
40 MEDCouplingCurveLinearMesh::MEDCouplingCurveLinearMesh(const MEDCouplingCurveLinearMesh& other, bool deepCopy):MEDCouplingStructuredMesh(other,deepCopy),_structure(other._structure)
41 {
42   if(deepCopy)
43     {
44       if((const DataArrayDouble *)other._coords)
45         _coords=other._coords->deepCpy();
46     }
47   else
48     _coords=other._coords;
49 }
50
51 MEDCouplingCurveLinearMesh::~MEDCouplingCurveLinearMesh()
52 {
53 }
54
55 MEDCouplingCurveLinearMesh *MEDCouplingCurveLinearMesh::New()
56 {
57   return new MEDCouplingCurveLinearMesh;
58 }
59
60 MEDCouplingCurveLinearMesh *MEDCouplingCurveLinearMesh::New(const char *meshName)
61 {
62   MEDCouplingCurveLinearMesh *ret=new MEDCouplingCurveLinearMesh;
63   ret->setName(meshName);
64   return ret;
65 }
66
67 MEDCouplingMesh *MEDCouplingCurveLinearMesh::deepCpy() const
68 {
69   return clone(true);
70 }
71
72 MEDCouplingCurveLinearMesh *MEDCouplingCurveLinearMesh::clone(bool recDeepCpy) const
73 {
74   return new MEDCouplingCurveLinearMesh(*this,recDeepCpy);
75 }
76
77 void MEDCouplingCurveLinearMesh::updateTime() const
78 {
79   if((const DataArrayDouble *)_coords)
80     updateTimeWith(*_coords);
81 }
82
83 std::size_t MEDCouplingCurveLinearMesh::getHeapMemorySize() const
84 {
85   std::size_t ret=0;
86   ret+=_structure.capacity()*sizeof(int);
87   if((const DataArrayDouble *)_coords)
88     ret+=_coords->getHeapMemorySize();
89   return MEDCouplingStructuredMesh::getHeapMemorySize()+ret;
90 }
91
92 /*!
93  * This method copyies all tiny strings from other (name and components name).
94  * @throw if other and this have not same mesh type.
95  */
96 void MEDCouplingCurveLinearMesh::copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception)
97
98   const MEDCouplingCurveLinearMesh *otherC=dynamic_cast<const MEDCouplingCurveLinearMesh *>(other);
99   if(!otherC)
100     throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::copyTinyStringsFrom : meshes have not same type !");
101   MEDCouplingStructuredMesh::copyTinyStringsFrom(other);
102   if((DataArrayDouble *)_coords && (const DataArrayDouble *)otherC->_coords)
103     _coords->copyStringInfoFrom(*otherC->_coords);
104 }
105
106 bool MEDCouplingCurveLinearMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception)
107 {
108   if(!other)
109     throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::isEqualIfNotWhy : input other pointer is null !");
110   const MEDCouplingCurveLinearMesh *otherC=dynamic_cast<const MEDCouplingCurveLinearMesh *>(other);
111   if(!otherC)
112     {
113       reason="mesh given in input is not castable in MEDCouplingCurveLinearMesh !";
114       return false;
115     }
116   if(!MEDCouplingStructuredMesh::isEqualIfNotWhy(other,prec,reason))
117     return false;
118   std::ostringstream oss; oss.precision(15);
119   if(((const DataArrayDouble *)_coords && ((const DataArrayDouble *)otherC->_coords)==0) || (((const DataArrayDouble *)_coords)==0 && (const DataArrayDouble *)otherC->_coords))
120     {
121       oss << "Only one CurveLinearMesh between the two this and other has its coordinates defined !";
122       reason=oss.str();
123       return false;
124     }
125   if((const DataArrayDouble *)_coords)
126     {
127       if(!_coords->isEqualIfNotWhy(*(otherC->_coords),prec,reason))
128         {
129           oss << "Coordinates DataArrayDouble of differ :";
130           reason.insert(0,oss.str());
131           return false;
132         }
133       if(_structure!=otherC->_structure)
134         { reason="CurveLinearMesh structures differ !"; return false; }
135     }
136   return true;
137 }
138
139 bool MEDCouplingCurveLinearMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
140 {
141   const MEDCouplingCurveLinearMesh *otherC=dynamic_cast<const MEDCouplingCurveLinearMesh *>(other);
142   if(!otherC)
143     return false;
144   if(((const DataArrayDouble *)_coords && ((const DataArrayDouble *)otherC->_coords)==0) || (((const DataArrayDouble *)_coords)==0 && (const DataArrayDouble *)otherC->_coords))
145     return false;
146   if((const DataArrayDouble *)_coords)
147     {
148       if(!_coords->isEqualWithoutConsideringStr(*(otherC->_coords),prec))
149         return false;
150       if(_structure!=otherC->_structure)
151         return false;
152     }
153   return true;
154 }
155
156 void MEDCouplingCurveLinearMesh::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
157                                             DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception)
158 {
159   if(!isEqualWithoutConsideringStr(other,prec))
160     throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::checkDeepEquivalWith : Meshes are not the same !");
161 }
162
163 /*!
164  * Nothing is done here (except to check that the other is a ParaMEDMEM::MEDCouplingCurveLinearMesh instance too).
165  * The user intend that the nodes are the same, so by construction of ParaMEDMEM::MEDCouplingCurveLinearMesh, 'this' and 'other' are the same !
166  */
167 void MEDCouplingCurveLinearMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
168                                                        DataArrayInt *&cellCor) const throw(INTERP_KERNEL::Exception)
169 {
170   const MEDCouplingCurveLinearMesh *otherC=dynamic_cast<const MEDCouplingCurveLinearMesh *>(other);
171   if(!otherC)
172     throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::checkDeepEquivalOnSameNodesWith : other is NOT a cartesian mesh ! Impossible to check equivalence !");
173 }
174
175 void MEDCouplingCurveLinearMesh::checkCoherency() const throw(INTERP_KERNEL::Exception)
176 {
177   std::size_t sz=_structure.size(),i=0,nbOfNodes=1;
178   if(sz<1)
179     throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::checkCoherency : structure should have a lgth of size 1 at least !");
180   for(std::vector<int>::const_iterator it=_structure.begin();it!=_structure.end();it++,i++)
181     {
182       if((*it)<1)
183         { std::ostringstream oss; oss << "MEDCouplingCurveLinearMesh::checkCoherency : At pos #" << i << " of structure value is " << *it << "should be >= 1 !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); }
184       nbOfNodes*=*it;
185     }
186   if(!((const DataArrayDouble *)_coords))
187     throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::checkCoherency : the array is not set !");
188   if(!_coords->isAllocated())
189     throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::checkCoherency : the array is not allocated !");
190   if(_coords->getNumberOfComponents()<1)
191     throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::checkCoherency : the array should have >= 1 components !");
192   if(_coords->getNumberOfTuples()!=(int)nbOfNodes)
193     {
194       std::ostringstream oss; oss << "MEDCouplingCurveLinearMesh::checkCoherency : structure said that number of nodes should be equal to " << nbOfNodes << " but number of tuples in array is equal to " << _coords->getNumberOfTuples() << " !";
195       throw INTERP_KERNEL::Exception(oss.str().c_str());
196     }
197 }
198
199 void MEDCouplingCurveLinearMesh::checkCoherency1(double eps) const throw(INTERP_KERNEL::Exception)
200 {
201   checkCoherency();
202 }
203
204 void MEDCouplingCurveLinearMesh::checkCoherency2(double eps) const throw(INTERP_KERNEL::Exception)
205 {
206   checkCoherency1(eps);
207 }
208
209 int MEDCouplingCurveLinearMesh::getNumberOfCells() const
210 {
211   checkCoherency();
212   std::size_t nbOfCells=1,i=0;
213   for(std::vector<int>::const_iterator it=_structure.begin();it!=_structure.end();it++,i++)
214     nbOfCells*=(*it)-1;
215   return (int)nbOfCells;
216 }
217
218 int MEDCouplingCurveLinearMesh::getNumberOfNodes() const
219 {
220   checkCoherency();
221   std::size_t nbOfNodes=1;
222   for(std::vector<int>::const_iterator it=_structure.begin();it!=_structure.end();it++)
223     nbOfNodes*=(*it);
224   return (int)nbOfNodes;
225 }
226
227 void MEDCouplingCurveLinearMesh::getSplitCellValues(int *res) const
228 {
229   int meshDim=getMeshDimension();
230   for(int l=0;l<meshDim;l++)
231     {
232       int val=1;
233       for(int p=0;p<meshDim-l-1;p++)
234         val*=_structure[p]-1;
235       res[meshDim-l-1]=val;
236     }
237 }
238
239 void MEDCouplingCurveLinearMesh::getSplitNodeValues(int *res) const
240 {
241   int meshDim=getMeshDimension();
242   for(int l=0;l<meshDim;l++)
243     {
244       int val=1;
245       for(int p=0;p<meshDim-l-1;p++)
246         val*=_structure[p];
247       res[meshDim-l-1]=val;
248     }
249 }
250
251 void MEDCouplingCurveLinearMesh::getNodeGridStructure(int *res) const
252 {
253   std::copy(_structure.begin(),_structure.end(),res);
254 }
255
256 int MEDCouplingCurveLinearMesh::getSpaceDimension() const
257 {
258   if(!((const DataArrayDouble *)_coords))
259     throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getSpaceDimension : no array set ! impossible to deduce a space dimension !");
260   return _coords->getNumberOfComponents();
261 }
262
263 int MEDCouplingCurveLinearMesh::getMeshDimension() const
264 {
265   return (int)_structure.size();
266 }
267
268 void MEDCouplingCurveLinearMesh::getCoordinatesOfNode(int nodeId, std::vector<double>& coo) const throw(INTERP_KERNEL::Exception)
269 {
270   if(!((const DataArrayDouble *)_coords))
271     throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getCoordinatesOfNode : Coordinates not set !");
272   int nbOfCompo=_coords->getNumberOfComponents();
273   if(nodeId>=0 && nodeId<_coords->getNumberOfTuples())
274     coo.insert(coo.end(),_coords->begin()+nodeId*nbOfCompo,_coords->begin()+(nodeId+1)*nbOfCompo);
275   else
276     { std::ostringstream oss; oss << "MEDCouplingCurveLinearMesh::getCoordinatesOfNode : nodeId has to be in [0," << _coords->getNumberOfTuples() << ") !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); }
277 }
278
279 std::string MEDCouplingCurveLinearMesh::simpleRepr() const
280 {
281   std::ostringstream ret;
282   ret << "Curve linear mesh with name : \"" << getName() << "\"\n";
283   ret << "Description of mesh : \"" << getDescription() << "\"\n";
284   int tmpp1,tmpp2;
285   double tt=getTime(tmpp1,tmpp2);
286   ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
287   ret << "Iteration : " << tmpp1  << " Order : " << tmpp2 << "\n";
288   ret << "The nodal stucture of curve linear mesh is : [";
289   std::copy(_structure.begin(),_structure.end(),std::ostream_iterator<int>(ret,",")); ret << "]\n";
290   ret << "The coords array is this : ";
291   if((const DataArrayDouble *)_coords)
292     _coords->reprZipWithoutNameStream(ret);
293   else
294     ret << "no array specified !";
295   return ret.str();
296 }
297
298 std::string MEDCouplingCurveLinearMesh::advancedRepr() const
299 {
300   return simpleRepr();
301 }
302
303 DataArrayDouble *MEDCouplingCurveLinearMesh::getCoords() throw(INTERP_KERNEL::Exception)
304 {
305   return _coords;
306 }
307
308 const DataArrayDouble *MEDCouplingCurveLinearMesh::getCoords() const throw(INTERP_KERNEL::Exception)
309 {
310   return _coords;
311 }
312
313 void MEDCouplingCurveLinearMesh::setCoords(const DataArrayDouble *coords) throw(INTERP_KERNEL::Exception)
314 {
315   if(coords!=(const DataArrayDouble *)_coords)
316     {
317       _coords=const_cast<DataArrayDouble *>(coords);
318       if(coords)
319         coords->incrRef();
320       declareAsNew();
321     }
322 }
323
324 void MEDCouplingCurveLinearMesh::setNodeGridStructure(const int *gridStructBg, const int *gridStructEnd) throw(INTERP_KERNEL::Exception)
325 {
326   _structure.resize(0);
327   _structure.insert(_structure.end(),gridStructBg,gridStructEnd);
328 }
329
330 std::vector<int> MEDCouplingCurveLinearMesh::getNodeGridStructure() const throw(INTERP_KERNEL::Exception)
331 {
332   return _structure;
333 }
334
335 void MEDCouplingCurveLinearMesh::getBoundingBox(double *bbox) const
336 {
337   if(!((const DataArrayDouble *)_coords))
338     throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getBoundingBox : Coordinates not set !");
339   _coords->getMinMaxPerComponent(bbox);
340 }
341
342 MEDCouplingFieldDouble *MEDCouplingCurveLinearMesh::getMeasureField(bool isAbs) const
343 {
344   checkCoherency();
345   int meshDim=getMeshDimension();
346   std::string name="MeasureOfMesh_"; name+=getName();
347   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> field=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME);
348   field->setName(name.c_str()); field->setMesh(const_cast<MEDCouplingCurveLinearMesh *>(this)); field->synchronizeTimeWithMesh();
349   switch(meshDim)
350     {
351     case 3:
352       { getMeasureFieldMeshDim3(isAbs,field); return field.retn(); }
353     case 2:
354       { getMeasureFieldMeshDim2(isAbs,field); return field.retn(); }
355     case 1:
356       { getMeasureFieldMeshDim1(isAbs,field); return field.retn(); }
357     default:
358       throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getMeasureField : mesh dimension must be in [1,2,3] !");
359     }
360 }
361
362 /*!
363  * \param [in,out] f field feeded with good values.
364  * \sa MEDCouplingCurveLinearMesh::getMeasureField
365  */
366 void MEDCouplingCurveLinearMesh::getMeasureFieldMeshDim1(bool isAbs, MEDCouplingFieldDouble *field) const throw(INTERP_KERNEL::Exception)
367 {
368   int nbnodes=getNumberOfNodes();
369   int spaceDim=getSpaceDimension();
370   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr=DataArrayDouble::New(); field->setArray(arr);
371   if(nbnodes==0)
372     { arr->alloc(0,1); return; }
373   if(spaceDim==1)
374     {
375       arr->alloc(nbnodes-1,1);
376       std::transform(_coords->begin()+1,_coords->end(),_coords->begin(),arr->getPointer(),std::minus<double>());
377       if(isAbs)
378         arr->abs();
379     }
380   else
381     {
382       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> tmp=DataArrayDouble::New(); tmp->alloc(nbnodes-1,spaceDim);
383       std::transform(_coords->begin()+spaceDim,_coords->end(),_coords->begin(),tmp->getPointer(),std::minus<double>());
384       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> tmp2=tmp->magnitude(); field->setArray(tmp2);
385     }
386 }
387
388 /*!
389  * \param [in,out] f field feeded with good values.
390  * \sa MEDCouplingCurveLinearMesh::getMeasureField
391  */
392 void MEDCouplingCurveLinearMesh::getMeasureFieldMeshDim2(bool isAbs, MEDCouplingFieldDouble *field) const throw(INTERP_KERNEL::Exception)
393 {
394   int nbcells=getNumberOfCells();
395   int spaceDim=getSpaceDimension();
396   if(spaceDim!=2 && spaceDim!=3)
397     throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getMeasureFieldMeshDim2 : with meshDim 2 only space dimension 2 and 3 are possible !");
398   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr=DataArrayDouble::New(); field->setArray(arr);
399   arr->alloc(nbcells,1);
400   double *pt=arr->getPointer();
401   const double *coords=_coords->begin();
402   int nX=_structure[0]-1;
403   int conn[4];
404   for(int i=0;i<nbcells;i++,pt++)
405     {
406       int cy=i/nX,cx=i-cy*nX;
407       conn[0]=cy*(nX+1)+cx; conn[1]=(cy+1)*(nX+1)+cx; conn[2]=(cy+1)*(nX+1)+1+cx; conn[3]=cy*(nX+1)+cx+1;
408       *pt=INTERP_KERNEL::computeVolSurfOfCell2<int,INTERP_KERNEL::ALL_C_MODE>(INTERP_KERNEL::NORM_QUAD4,conn,4,coords,spaceDim);
409     }
410   if(isAbs)
411     arr->abs();
412 }
413
414 /*!
415  * \param [in,out] f field feeded with good values.
416  * \sa MEDCouplingCurveLinearMesh::getMeasureField
417  */
418 void MEDCouplingCurveLinearMesh::getMeasureFieldMeshDim3(bool isAbs, MEDCouplingFieldDouble *field) const throw(INTERP_KERNEL::Exception)
419 {
420   int nbcells=getNumberOfCells();
421   int spaceDim=getSpaceDimension();
422   if(spaceDim!=3)
423     throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getMeasureFieldMeshDim3 : with meshDim 3 only space dimension 3 is possible !");
424   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr=DataArrayDouble::New(); field->setArray(arr);
425   arr->alloc(nbcells,1);
426   double *pt=arr->getPointer();
427   const double *coords=_coords->begin();
428   int nX=_structure[0]-1,nY=(_structure[0]-1)*(_structure[1]-1);
429   int nY1=_structure[0]*_structure[1];
430   int conn[8];
431   for(int i=0;i<nbcells;i++,pt++)
432     {
433       int cz=i/nY;
434       int cy=(i-cz*nY)/nX;
435       int cx=(i-cz*nY)-nX*cy;
436       conn[0]=cz*nY1+cy*(nX+1)+cx; conn[1]=cz*nY1+(cy+1)*(nX+1)+cx; conn[2]=cz*nY1+(cy+1)*(nX+1)+1+cx; conn[3]=cz*nY1+cy*(nX+1)+cx+1;
437       conn[4]=(cz+1)*nY1+cy*(nX+1)+cx; conn[5]=(cz+1)*nY1+(cy+1)*(nX+1)+cx; conn[6]=(cz+1)*nY1+(cy+1)*(nX+1)+1+cx; conn[7]=(cz+1)*nY1+cy*(nX+1)+cx+1;
438       *pt=INTERP_KERNEL::computeVolSurfOfCell2<int,INTERP_KERNEL::ALL_C_MODE>(INTERP_KERNEL::NORM_HEXA8,conn,8,coords,3);
439     }
440   if(isAbs)
441     arr->abs();
442 }
443
444 /*!
445  * not implemented yet !
446  */
447 MEDCouplingFieldDouble *MEDCouplingCurveLinearMesh::getMeasureFieldOnNode(bool isAbs) const
448 {
449   throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getMeasureFieldOnNode : not implemented yet !");
450 }
451
452 MEDCouplingFieldDouble *MEDCouplingCurveLinearMesh::buildOrthogonalField() const
453 {
454   if(getMeshDimension()!=2)
455     throw INTERP_KERNEL::Exception("Expected a cmesh with meshDim == 2 !");
456   MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME);
457   DataArrayDouble *array=DataArrayDouble::New();
458   int nbOfCells=getNumberOfCells();
459   array->alloc(nbOfCells,3);
460   double *vals=array->getPointer();
461   for(int i=0;i<nbOfCells;i++)
462     { vals[3*i]=0.; vals[3*i+1]=0.; vals[3*i+2]=1.; }
463   ret->setArray(array);
464   array->decrRef();
465   ret->setMesh(this);
466   return ret;
467 }
468
469 /// @cond INTERNAL
470
471 namespace ParaMEDMEM
472 {
473   template<const int SPACEDIMM>
474   class DummyClsMCL
475   {
476   public:
477     static const int MY_SPACEDIM=SPACEDIMM;
478     static const int MY_MESHDIM=8;
479     typedef int MyConnType;
480     static const INTERP_KERNEL::NumberingPolicy My_numPol=INTERP_KERNEL::ALL_C_MODE;
481     // begin
482     // useless, but for windows compilation ...
483     const double* getCoordinatesPtr() const { return 0; }
484     const int* getConnectivityPtr() const { return 0; }
485     const int* getConnectivityIndexPtr() const { return 0; }
486     INTERP_KERNEL::NormalizedCellType getTypeOfElement(int) const { return (INTERP_KERNEL::NormalizedCellType)0; }
487     // end
488   };
489 }
490
491 /// @endcond
492
493 int MEDCouplingCurveLinearMesh::getCellContainingPoint(const double *pos, double eps) const
494 {
495   checkCoherency();
496   int spaceDim=getSpaceDimension();
497   const double *coords=_coords->getConstPointer();
498   int nodeId=-1;
499   _coords->distanceToTuple(pos,pos+spaceDim,nodeId);
500   if(nodeId<0)
501     throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getCellContainingPoint : internal problem 1 !");
502   int conn[8];
503   int nbOfNodes=getNumberOfNodes();
504   if(nbOfNodes==1)
505     throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getCellContainingPoint : No cells in this !");
506   switch(getMeshDimension())
507     {
508     case 1:
509       if(spaceDim==1)
510         {
511           if(nodeId>0)
512             {
513               conn[0]=nodeId-1; conn[1]=nodeId;
514               if(INTERP_KERNEL::PointLocatorAlgos<DummyClsMCL<1> >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_SEG2,coords,conn,2,eps))
515                 return nodeId-1;
516             }
517           if(nodeId<nbOfNodes-1)
518             {
519               conn[0]=nodeId; conn[1]=nodeId+1;
520               if(INTERP_KERNEL::PointLocatorAlgos<DummyClsMCL<1> >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_SEG2,coords,conn,2,eps))
521                 return nodeId;
522             }
523         }
524     case 2:
525       if(spaceDim==2)
526         {
527           int ny=nodeId/_structure[0],nx=nodeId-ny*_structure[0];
528           if(nx>0 && ny>0)
529             {
530               conn[0]=nx-1+_structure[0]*(ny-1); conn[1]=nx-1+_structure[0]*ny; conn[2]=nx+_structure[0]*ny; conn[3]=nx+_structure[0]*(ny-1);
531               if(INTERP_KERNEL::PointLocatorAlgos<DummyClsMCL<2> >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_QUAD4,coords,conn,4,eps))
532                 return nx-1+(ny-1)*_structure[0];
533             }
534           if(nx<_structure[0]-1 && ny>0)
535             {
536               conn[0]=nx+_structure[0]*(ny-1); conn[1]=nx+_structure[0]*ny; conn[2]=nx+1+_structure[0]*ny; conn[3]=nx+1+_structure[0]*(ny-1);
537               if(INTERP_KERNEL::PointLocatorAlgos<DummyClsMCL<2> >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_QUAD4,coords,conn,4,eps))
538                 return nx+(ny-1)*_structure[0];
539             }
540           if(nx>0 && ny<_structure[1]-1)
541             {
542               conn[0]=nx-1+_structure[0]*ny; conn[1]=nx-1+_structure[0]*(ny+1); conn[2]=nx+_structure[0]*(ny+1); conn[3]=nx+_structure[0]*ny;
543               if(INTERP_KERNEL::PointLocatorAlgos<DummyClsMCL<2> >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_QUAD4,coords,conn,4,eps))
544                 return nx-1+ny*_structure[0];
545             }
546           if(nx<_structure[0]-1 && ny<_structure[1]-1)
547             {
548               conn[0]=nx+_structure[0]*ny; conn[1]=nx+_structure[0]*(ny+1); conn[2]=nx+1+_structure[0]*(ny+1); conn[3]=nx+1+_structure[0]*ny;
549               if(INTERP_KERNEL::PointLocatorAlgos<DummyClsMCL<2> >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_QUAD4,coords,conn,4,eps))
550                 return nx+ny*_structure[0];
551             }
552         }
553     case 3:
554       {
555         if(spaceDim==3)
556           {
557             int nY=_structure[0]*_structure[1];
558             int nz=nodeId/_structure[1]; int ny=(nodeId-nz*nY)/_structure[0]; int nx=(nodeId-nz*nY)-_structure[0]*ny;
559             if(nx>0 && ny>0 && nz>0)
560               {
561                 conn[0]=nx-1+_structure[0]*(ny-1)+nY*(nz-1); conn[1]=nx-1+_structure[2]*ny+nY*(nz-1); conn[2]=nx+_structure[2]*ny+nY*(nz-1); conn[3]=nx+_structure[0]*(ny-1)+nY*(nz-1);
562                 conn[4]=nx-1+_structure[0]*(ny-1)+nY*nz; conn[5]=nx-1+_structure[0]*ny+nY*nz; conn[6]=nx+_structure[0]*ny+nY*nz; conn[7]=nx+_structure[0]*(ny-1)+nY*nz;
563                 if(INTERP_KERNEL::PointLocatorAlgos<DummyClsMCL<3> >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_HEXA8,coords,conn,8,eps))
564                   return nx-1+(ny-1)*_structure[0]+(nz-1)*nY;
565               }
566             if(nx<_structure[0]-1 && ny>0 && nz>0)
567               {
568                 conn[0]=nx+_structure[0]*(ny-1)+nY*(nz-1); conn[1]=nx+_structure[0]*ny+nY*(nz-1); conn[2]=nx+1+_structure[0]*ny+nY*(nz-1); conn[3]=nx+1+_structure[0]*(ny-1)+nY*(nz-1);
569                 conn[4]=nx+_structure[0]*(ny-1)+nY*nz; conn[5]=nx+_structure[0]*ny+nY*nz; conn[6]=nx+1+_structure[0]*ny+nY*nz; conn[7]=nx+1+_structure[0]*(ny-1)+nY*nz;
570                 if(INTERP_KERNEL::PointLocatorAlgos<DummyClsMCL<3> >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_HEXA8,coords,conn,8,eps))
571                   return nx+(ny-1)*_structure[0]+(nz-1)*nY;
572               }
573             if(nx>0 && ny<_structure[1]-1 && nz>0)
574               {
575                 conn[0]=nx-1+_structure[0]*ny+nY*(nz-1); conn[1]=nx-1+_structure[0]*(ny+1)+nY*(nz-1); conn[2]=nx+_structure[0]*(ny+1)+nY*(nz-1); conn[3]=nx+_structure[0]*ny+nY*(nz-1);
576                 conn[4]=nx-1+_structure[0]*ny+nY*nz; conn[5]=nx-1+_structure[0]*(ny+1)+nY*nz; conn[6]=nx+_structure[0]*(ny+1)+nY*nz; conn[7]=nx+_structure[0]*ny+nY*nz;
577                 if(INTERP_KERNEL::PointLocatorAlgos<DummyClsMCL<3> >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_HEXA8,coords,conn,8,eps))
578                   return nx-1+ny*_structure[0]+(nz-1)*nY;
579               }
580             if(nx<_structure[0]-1 && ny<_structure[1]-1 && nz>0)
581               {
582                 conn[0]=nx+_structure[0]*ny+nY*(nz-1); conn[1]=nx+_structure[0]*(ny+1)+nY*(nz-1); conn[2]=nx+1+_structure[0]*(ny+1)+nY*(nz-1); conn[3]=nx+1+_structure[0]*ny+nY*(nz-1);
583                 conn[4]=nx+_structure[0]*ny+nY*nz; conn[5]=nx+_structure[0]*(ny+1)+nY*nz; conn[6]=nx+1+_structure[0]*(ny+1)+nY*nz; conn[7]=nx+1+_structure[0]*ny+nY*nz;
584                 if(INTERP_KERNEL::PointLocatorAlgos<DummyClsMCL<3> >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_HEXA8,coords,conn,8,eps))
585                   return nx+ny*_structure[0]+(nz-1)*nY;
586               }
587             if(nx>0 && ny>0 && nz<_structure[2]-1)
588               {
589                 conn[0]=nx-1+_structure[0]*(ny-1)+nY*(nz-1); conn[1]=nx-1+_structure[2]*ny+nY*(nz-1); conn[2]=nx+_structure[2]*ny+nY*(nz-1); conn[3]=nx+_structure[0]*(ny-1)+nY*(nz-1);
590                 conn[4]=nx-1+_structure[0]*(ny-1)+nY*nz; conn[5]=nx-1+_structure[0]*ny+nY*nz; conn[6]=nx+_structure[0]*ny+nY*nz; conn[7]=nx+_structure[0]*(ny-1)+nY*nz;
591                 if(INTERP_KERNEL::PointLocatorAlgos<DummyClsMCL<3> >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_HEXA8,coords,conn,8,eps))
592                   return nx-1+(ny-1)*_structure[0]+nz*nY;
593               }
594             if(nx<_structure[0]-1 && ny>0 && nz<_structure[2]-1)
595               {
596                 conn[0]=nx+_structure[0]*(ny-1)+nY*(nz-1); conn[1]=nx+_structure[0]*ny+nY*(nz-1); conn[2]=nx+1+_structure[0]*ny+nY*(nz-1); conn[3]=nx+1+_structure[0]*(ny-1)+nY*(nz-1);
597                 conn[4]=nx+_structure[0]*(ny-1)+nY*nz; conn[5]=nx+_structure[0]*ny+nY*nz; conn[6]=nx+1+_structure[0]*ny+nY*nz; conn[7]=nx+1+_structure[0]*(ny-1)+nY*nz;
598                 if(INTERP_KERNEL::PointLocatorAlgos<DummyClsMCL<3> >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_HEXA8,coords,conn,8,eps))
599                   return nx+(ny-1)*_structure[0]+nz*nY;
600               }
601             if(nx>0 && ny<_structure[1]-1 && nz<_structure[2]-1)
602               {
603                 conn[0]=nx-1+_structure[0]*ny+nY*(nz-1); conn[1]=nx-1+_structure[0]*(ny+1)+nY*(nz-1); conn[2]=nx+_structure[0]*(ny+1)+nY*(nz-1); conn[3]=nx+_structure[0]*ny+nY*(nz-1);
604                 conn[4]=nx-1+_structure[0]*ny+nY*nz; conn[5]=nx-1+_structure[0]*(ny+1)+nY*nz; conn[6]=nx+_structure[0]*(ny+1)+nY*nz; conn[7]=nx+_structure[0]*ny+nY*nz;
605                 if(INTERP_KERNEL::PointLocatorAlgos<DummyClsMCL<3> >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_HEXA8,coords,conn,8,eps))
606                   return nx-1+ny*_structure[0]+nz*nY;
607               }
608             if(nx<_structure[0]-1 && ny<_structure[1]-1 && nz<_structure[2]-1)
609               {
610                 conn[0]=nx+_structure[0]*ny+nY*(nz-1); conn[1]=nx+_structure[0]*(ny+1)+nY*(nz-1); conn[2]=nx+1+_structure[0]*(ny+1)+nY*(nz-1); conn[3]=nx+1+_structure[0]*ny+nY*(nz-1);
611                 conn[4]=nx+_structure[0]*ny+nY*nz; conn[5]=nx+_structure[0]*(ny+1)+nY*nz; conn[6]=nx+1+_structure[0]*(ny+1)+nY*nz; conn[7]=nx+1+_structure[0]*ny+nY*nz;
612                 if(INTERP_KERNEL::PointLocatorAlgos<DummyClsMCL<3> >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_HEXA8,coords,conn,8,eps))
613                   return nx+ny*_structure[0]+nz*nY;
614               }
615           }
616       }
617     default:
618       throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getCellContainingPoint : mesh dimension managed are 1, 2 or 3 !");
619     }
620 }
621
622 void MEDCouplingCurveLinearMesh::rotate(const double *center, const double *vector, double angle)
623 {
624   if(!((DataArrayDouble *)_coords))
625     throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::rotate : no coordinates set !");
626   int spaceDim=getSpaceDimension();
627   int nbNodes=_coords->getNumberOfTuples();
628   double *coords=_coords->getPointer();
629   if(spaceDim==3)
630     MEDCouplingPointSet::Rotate3DAlg(center,vector,angle,nbNodes,coords);
631   else if(spaceDim==2)
632     MEDCouplingPointSet::Rotate2DAlg(center,angle,nbNodes,coords);
633   else
634     throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::rotate : invalid space dim for rotation must be 2 or 3");
635   _coords->declareAsNew();
636   updateTime();
637 }
638
639 void MEDCouplingCurveLinearMesh::translate(const double *vector)
640 {
641   if(!vector)
642     throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::translate : NULL input point !");
643   if(!((DataArrayDouble *)_coords))
644     throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::translate : no coordinates set !");
645   double *coords=_coords->getPointer();
646   int nbNodes=getNumberOfNodes();
647   int dim=getSpaceDimension();
648   for(int i=0; i<nbNodes; i++)
649     for(int idim=0; idim<dim;idim++)
650       coords[i*dim+idim]+=vector[idim];
651   _coords->declareAsNew();
652   updateTime();
653 }
654
655 void MEDCouplingCurveLinearMesh::scale(const double *point, double factor)
656 {
657   if(!point)
658     throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::scale : NULL input point !");
659   if(!((DataArrayDouble *)_coords))
660     throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::scale : no coordinates set !");
661   double *coords=_coords->getPointer();
662   int nbNodes=_coords->getNumberOfTuples();
663   int dim=_coords->getNumberOfComponents();
664   for(int i=0;i<nbNodes;i++)
665     {
666       std::transform(coords+i*dim,coords+(i+1)*dim,point,coords+i*dim,std::minus<double>());
667       std::transform(coords+i*dim,coords+(i+1)*dim,coords+i*dim,std::bind2nd(std::multiplies<double>(),factor));
668       std::transform(coords+i*dim,coords+(i+1)*dim,point,coords+i*dim,std::plus<double>());
669     }
670   _coords->declareAsNew();
671   updateTime();
672 }
673
674 MEDCouplingMesh *MEDCouplingCurveLinearMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
675 {
676   throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::mergeMyselfWith : not available for CurveLinear Mesh !");
677 }
678
679 DataArrayDouble *MEDCouplingCurveLinearMesh::getCoordinatesAndOwner() const
680 {
681   DataArrayDouble *ret=const_cast<DataArrayDouble *>((const DataArrayDouble *)_coords);
682   if(ret)
683     ret->incrRef();
684   return ret;
685 }
686
687 DataArrayDouble *MEDCouplingCurveLinearMesh::getBarycenterAndOwner() const
688 {
689   checkCoherency();
690   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
691   int spaceDim=getSpaceDimension();
692   int meshDim=getMeshDimension();
693   int nbOfCells=getNumberOfCells();
694   ret->alloc(nbOfCells,spaceDim);
695   ret->copyStringInfoFrom(*getCoords());
696   switch(meshDim)
697     {
698     case 3:
699       { getBarycenterAndOwnerMeshDim3(ret); return ret.retn(); }
700     case 2:
701       { getBarycenterAndOwnerMeshDim2(ret); return ret.retn(); }
702     case 1:
703       { getBarycenterAndOwnerMeshDim1(ret); return ret.retn(); }
704     default:
705       throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getBarycenterAndOwner : mesh dimension must be in [1,2,3] !");
706     }
707 }
708
709 DataArrayDouble *MEDCouplingCurveLinearMesh::computeIsoBarycenterOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
710 {
711   return MEDCouplingCurveLinearMesh::getBarycenterAndOwner();
712 }
713
714 /*!
715  * \param [in,out] bary Barycenter array feeded with good values.
716  * \sa MEDCouplingCurveLinearMesh::getBarycenterAndOwner
717  */
718 void MEDCouplingCurveLinearMesh::getBarycenterAndOwnerMeshDim3(DataArrayDouble *bary) const
719 {
720   int nbOfCells=getNumberOfCells();
721   double *ptToFill=bary->getPointer();
722   const double *coor=_coords->getConstPointer();
723   if(getSpaceDimension()!=3)
724     throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getBarycenterAndOwnerMeshDim3 : with meshDim 3 only space dimension 3 is possible !");
725   int nX=_structure[0]-1,nY=(_structure[0]-1)*(_structure[1]-1);
726   int nY1=_structure[0]*_structure[1];
727   int conn[8];
728   for(int i=0;i<nbOfCells;i++)
729     {
730       int cz=i/nY;
731       int cy=(i-cz*nY)/nX;
732       int cx=(i-cz*nY)-nX*cy;
733       conn[0]=cz*nY1+cy*(nX+1)+cx+1; conn[1]=cz*nY1+cy*(nX+1)+cx; conn[2]=cz*nY1+(cy+1)*(nX+1)+cx; conn[3]=cz*nY1+(cy+1)*(nX+1)+1+cx;
734       conn[4]=(cz+1)*nY1+cy*(nX+1)+cx+1; conn[5]=(cz+1)*nY1+cy*(nX+1)+cx; conn[6]=(cz+1)*nY1+(cy+1)*(nX+1)+cx; conn[7]=(cz+1)*nY1+(cy+1)*(nX+1)+1+cx;
735       INTERP_KERNEL::computeBarycenter2<int,INTERP_KERNEL::ALL_C_MODE>(INTERP_KERNEL::NORM_HEXA8,conn,8,coor,3,ptToFill);
736       ptToFill+=3;
737     }
738 }
739
740 /*!
741  * \param [in,out] bary Barycenter array feeded with good values.
742  * \sa MEDCouplingCurveLinearMesh::getBarycenterAndOwner
743  */
744 void MEDCouplingCurveLinearMesh::getBarycenterAndOwnerMeshDim2(DataArrayDouble *bary) const
745 {
746   int nbcells=getNumberOfCells();
747   int spaceDim=getSpaceDimension();
748   double *ptToFill=bary->getPointer();
749   const double *coor=_coords->getConstPointer();
750   if(spaceDim!=2 && spaceDim!=3)
751     throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getBarycenterAndOwnerMeshDim2 : with meshDim 2 only space dimension 2 and 3 are possible !");
752   int nX=_structure[0]-1;
753   int conn[4];
754   for(int i=0;i<nbcells;i++)
755     {
756       int cy=i/nX,cx=i-cy*nX;
757       conn[0]=cy*(nX+1)+cx; conn[1]=(cy+1)*(nX+1)+cx; conn[2]=(cy+1)*(nX+1)+1+cx; conn[3]=cy*(nX+1)+cx+1;
758       INTERP_KERNEL::computeBarycenter2<int,INTERP_KERNEL::ALL_C_MODE>(INTERP_KERNEL::NORM_QUAD4,conn,4,coor,spaceDim,ptToFill);
759       ptToFill+=spaceDim;
760     }
761 }
762
763 /*!
764  * \param [in,out] bary Barycenter array feeded with good values.
765  * \sa MEDCouplingCurveLinearMesh::getBarycenterAndOwner
766  */
767 void MEDCouplingCurveLinearMesh::getBarycenterAndOwnerMeshDim1(DataArrayDouble *bary) const
768 {
769   int spaceDim=getSpaceDimension();
770   std::transform(_coords->begin()+spaceDim,_coords->end(),_coords->begin(),bary->getPointer(),std::plus<double>());
771   std::transform(bary->begin(),bary->end(),bary->getPointer(),std::bind2nd(std::multiplies<double>(),0.5));
772 }
773
774 void MEDCouplingCurveLinearMesh::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception)
775 {
776   throw INTERP_KERNEL::Exception("Functionnality of renumbering cell not available for CurveLinear Mesh !");
777 }
778
779 void MEDCouplingCurveLinearMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const
780 {
781   int it,order;
782   double time=getTime(it,order);
783   tinyInfo.clear();
784   tinyInfoD.clear();
785   littleStrings.clear();
786   littleStrings.push_back(getName());
787   littleStrings.push_back(getDescription());
788   littleStrings.push_back(getTimeUnit());
789   //
790   std::vector<std::string> littleStrings2;
791   if((const DataArrayDouble *)_coords)
792     _coords->getTinySerializationStrInformation(littleStrings2);
793   littleStrings.insert(littleStrings.end(),littleStrings2.begin(),littleStrings2.end());
794   //
795   tinyInfo.push_back(it);
796   tinyInfo.push_back(order);
797   tinyInfo.push_back((int)_structure.size());
798   for(std::vector<int>::const_iterator itt=_structure.begin();itt!=_structure.end();itt++)
799     tinyInfo.push_back(*itt);
800   std::vector<int> tinyInfo2;
801   if((const DataArrayDouble *)_coords)
802     _coords->getTinySerializationIntInformation(tinyInfo2);
803   tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
804   //
805   tinyInfoD.push_back(time);
806 }
807
808 void MEDCouplingCurveLinearMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
809 {
810   a1->alloc(tinyInfo[2],1);
811   std::vector<int> tinyInfo2(tinyInfo.begin()+3+tinyInfo[2],tinyInfo.end());
812   a2->resizeForUnserialization(tinyInfo2);
813 }
814
815 void MEDCouplingCurveLinearMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const
816 {
817   a1=DataArrayInt::New();
818   a1->alloc((int)_structure.size(),1);
819   int *ptr=a1->getPointer();
820   for(std::vector<int>::const_iterator it=_structure.begin();it!=_structure.end();it++,ptr++)
821     *ptr=(*it);
822   int sz=0;
823   if((const DataArrayDouble *)_coords)
824     if(_coords->isAllocated())
825       sz=_coords->getNbOfElems();
826   a2=DataArrayDouble::New();
827   a2->alloc(sz,1);
828   if(sz!=0 && (const DataArrayDouble *)_coords)
829     std::copy(_coords->begin(),_coords->end(),a2->getPointer());
830 }
831
832 void MEDCouplingCurveLinearMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,
833                                                  const std::vector<std::string>& littleStrings)
834 {
835   setName(littleStrings[0].c_str());
836   setDescription(littleStrings[1].c_str());
837   setTimeUnit(littleStrings[2].c_str());
838   setTime(tinyInfoD[0],tinyInfo[0],tinyInfo[1]);
839   int sz=tinyInfo[2];
840   _structure.resize(sz);
841   for(int i=0;i<sz;i++)
842     _structure[i]=tinyInfo[3+i];
843   if((int)tinyInfo.size()>sz+3)
844     {
845       _coords=DataArrayDouble::New();
846       std::vector<int> tinyInfo2(tinyInfo.begin()+3+sz,tinyInfo.end());
847       _coords->resizeForUnserialization(tinyInfo2);
848       std::copy(a2->begin(),a2->end(),_coords->getPointer());
849       std::vector<std::string> littleStrings2(littleStrings.begin()+3,littleStrings.end());
850       _coords->finishUnserialization(tinyInfo2,littleStrings2);
851     }
852 }
853
854 void MEDCouplingCurveLinearMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData) const throw(INTERP_KERNEL::Exception)
855 {
856   std::ostringstream extent;
857   int meshDim=(int)_structure.size();
858   if(meshDim<=0 || meshDim>3)
859     throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::writeVTKLL : meshDim invalid ! must be in [1,2,3] !");
860   for(int i=0;i<3;i++)
861     { int val=i<meshDim?_structure[i]-1:0; extent << "0 " <<  val << " "; }
862   ofs << "  <" << getVTKDataSetType() << " WholeExtent=\"" << extent.str() << "\">\n";
863   ofs << "    <Piece Extent=\"" << extent.str() << "\">\n";
864   ofs << "      <PointData>\n" << pointData << std::endl;
865   ofs << "      </PointData>\n";
866   ofs << "      <CellData>\n" << cellData << std::endl;
867   ofs << "      </CellData>\n";
868   ofs << "      <Points>\n";
869   if(getSpaceDimension()==3)
870     _coords->writeVTK(ofs,8,"Points");
871   else
872     {
873       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coo=_coords->changeNbOfComponents(3,0.);
874       coo->writeVTK(ofs,8,"Points");
875     }
876   ofs << "      </Points>\n";
877   ofs << "    </Piece>\n";
878   ofs << "  </" << getVTKDataSetType() << ">\n";
879 }
880
881 void MEDCouplingCurveLinearMesh::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
882 {
883   stream << "MEDCouplingCurveLinearMesh C++ instance at " << this << ".";
884 }
885
886 std::string MEDCouplingCurveLinearMesh::getVTKDataSetType() const throw(INTERP_KERNEL::Exception)
887 {
888   return std::string("StructuredGrid");
889 }