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