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