Salome HOME
Unwarnigization
[tools/medcoupling.git] / src / MEDCoupling / MEDCouplingExtrudedMesh.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 "MEDCouplingExtrudedMesh.hxx"
22 #include "MEDCouplingUMesh.hxx"
23 #include "MEDCouplingMemArray.hxx"
24 #include "MEDCouplingFieldDouble.hxx"
25 #include "MEDCouplingAutoRefCountObjectPtr.hxx"
26 #include "CellModel.hxx"
27
28 #include "InterpolationUtils.hxx"
29
30 #include <limits>
31 #include <algorithm>
32 #include <functional>
33 #include <iterator>
34 #include <sstream>
35 #include <cmath>
36 #include <list>
37 #include <set>
38
39 using namespace ParaMEDMEM;
40
41 /*!
42  * Build an extruded mesh instance from 3D and 2D unstructured mesh lying on the \b same \b coords.
43  * @param mesh3D 3D unstructured mesh.
44  * @param mesh2D 2D unstructured mesh lying on the same coordinates than mesh3D. \b Warning mesh2D is \b not \b const
45  * because the mesh is aggregated and potentially modified by rotate or translate method.
46  * @param cell2DId Id of cell in mesh2D mesh where the computation of 1D mesh will be done.
47  */
48 MEDCouplingExtrudedMesh *MEDCouplingExtrudedMesh::New(const MEDCouplingUMesh *mesh3D, const MEDCouplingUMesh *mesh2D, int cell2DId)
49 {
50   return new MEDCouplingExtrudedMesh(mesh3D,mesh2D,cell2DId);
51 }
52
53 /*!
54  * This constructor is here only for unserialisation process.
55  * This constructor is normally completely useless for end user.
56  */
57 MEDCouplingExtrudedMesh *MEDCouplingExtrudedMesh::New()
58 {
59   return new MEDCouplingExtrudedMesh;
60 }
61
62 MEDCouplingMeshType MEDCouplingExtrudedMesh::getType() const
63 {
64   return EXTRUDED;
65 }
66
67 std::size_t MEDCouplingExtrudedMesh::getHeapMemorySizeWithoutChildren() const
68 {
69   return MEDCouplingMesh::getHeapMemorySizeWithoutChildren();
70 }
71
72 std::vector<const BigMemoryObject *> MEDCouplingExtrudedMesh::getDirectChildren() const
73 {
74   std::vector<const BigMemoryObject *> ret;
75   if(_mesh2D)
76     ret.push_back(_mesh2D);
77   if(_mesh1D)
78     ret.push_back(_mesh1D);
79   if(_mesh3D_ids)
80     ret.push_back(_mesh3D_ids);
81   return ret;
82 }
83
84 /*!
85  * This method copyies all tiny strings from other (name and components name).
86  * @throw if other and this have not same mesh type.
87  */
88 void MEDCouplingExtrudedMesh::copyTinyStringsFrom(const MEDCouplingMesh *other)
89 {
90   const MEDCouplingExtrudedMesh *otherC=dynamic_cast<const MEDCouplingExtrudedMesh *>(other);
91   if(!otherC)
92     throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::copyTinyStringsFrom : meshes have not same type !");
93   MEDCouplingMesh::copyTinyStringsFrom(other);
94   _mesh2D->copyTinyStringsFrom(otherC->_mesh2D);
95   _mesh1D->copyTinyStringsFrom(otherC->_mesh1D);
96 }
97
98 MEDCouplingExtrudedMesh::MEDCouplingExtrudedMesh(const MEDCouplingUMesh *mesh3D, const MEDCouplingUMesh *mesh2D, int cell2DId)
99 try:_mesh2D(const_cast<MEDCouplingUMesh *>(mesh2D)),_mesh1D(MEDCouplingUMesh::New()),_mesh3D_ids(0),_cell_2D_id(cell2DId)
100 {
101   if(_mesh2D!=0)
102     _mesh2D->incrRef();
103   computeExtrusion(mesh3D);
104   setName(mesh3D->getName().c_str());
105 }
106 catch(INTERP_KERNEL::Exception& e)
107   {
108     if(_mesh2D)
109       _mesh2D->decrRef();
110     if(_mesh1D)
111       _mesh1D->decrRef();
112     if(_mesh3D_ids)
113       _mesh3D_ids->decrRef();
114     throw e;
115   }
116
117 MEDCouplingExtrudedMesh::MEDCouplingExtrudedMesh():_mesh2D(0),_mesh1D(0),_mesh3D_ids(0),_cell_2D_id(-1)
118 {
119 }
120
121 MEDCouplingExtrudedMesh::MEDCouplingExtrudedMesh(const MEDCouplingExtrudedMesh& other, bool deepCopy):MEDCouplingMesh(other),_cell_2D_id(other._cell_2D_id)
122 {
123   if(deepCopy)
124     {
125       _mesh2D=other._mesh2D->clone(true);
126       _mesh1D=other._mesh1D->clone(true);
127       _mesh3D_ids=other._mesh3D_ids->deepCpy();
128     }
129   else
130     {
131       _mesh2D=other._mesh2D;
132       if(_mesh2D)
133         _mesh2D->incrRef();
134       _mesh1D=other._mesh1D;
135       if(_mesh1D)
136         _mesh1D->incrRef();
137       _mesh3D_ids=other._mesh3D_ids;
138       if(_mesh3D_ids)
139         _mesh3D_ids->incrRef();
140     }
141 }
142
143 int MEDCouplingExtrudedMesh::getNumberOfCells() const
144 {
145   return _mesh2D->getNumberOfCells()*_mesh1D->getNumberOfCells();
146 }
147
148 int MEDCouplingExtrudedMesh::getNumberOfNodes() const
149 {
150   return _mesh2D->getNumberOfNodes();
151 }
152
153 int MEDCouplingExtrudedMesh::getSpaceDimension() const
154 {
155   return 3;
156 }
157
158 int MEDCouplingExtrudedMesh::getMeshDimension() const
159 {
160   return 3;
161 }
162
163 MEDCouplingMesh *MEDCouplingExtrudedMesh::deepCpy() const
164 {
165   return clone(true);
166 }
167
168 MEDCouplingExtrudedMesh *MEDCouplingExtrudedMesh::clone(bool recDeepCpy) const
169 {
170   return new MEDCouplingExtrudedMesh(*this,recDeepCpy);
171 }
172
173 bool MEDCouplingExtrudedMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const
174 {
175   if(!other)
176     throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::isEqualIfNotWhy : input other pointer is null !");
177   const MEDCouplingExtrudedMesh *otherC=dynamic_cast<const MEDCouplingExtrudedMesh *>(other);
178   std::ostringstream oss;
179   if(!otherC)
180     {
181       reason="mesh given in input is not castable in MEDCouplingExtrudedMesh !";
182       return false;
183     }
184   if(!MEDCouplingMesh::isEqualIfNotWhy(other,prec,reason))
185     return false;
186   if(!_mesh2D->isEqualIfNotWhy(otherC->_mesh2D,prec,reason))
187     {
188       reason.insert(0,"Mesh2D unstructured meshes differ : ");
189       return false;
190     }
191   if(!_mesh1D->isEqualIfNotWhy(otherC->_mesh1D,prec,reason))
192     {
193       reason.insert(0,"Mesh1D unstructured meshes differ : ");
194       return false;
195     }
196   if(!_mesh3D_ids->isEqualIfNotWhy(*otherC->_mesh3D_ids,reason))
197     {
198       reason.insert(0,"Mesh3D ids DataArrayInt instances differ : ");
199       return false;
200     }
201   if(_cell_2D_id!=otherC->_cell_2D_id)
202     {
203       oss << "Cell 2D id of the two extruded mesh differ : this = " << _cell_2D_id << " other = " <<  otherC->_cell_2D_id;
204       reason=oss.str();
205       return false;
206     }
207   return true;
208 }
209
210 bool MEDCouplingExtrudedMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
211 {
212   const MEDCouplingExtrudedMesh *otherC=dynamic_cast<const MEDCouplingExtrudedMesh *>(other);
213   if(!otherC)
214     return false;
215   if(!_mesh2D->isEqualWithoutConsideringStr(otherC->_mesh2D,prec))
216     return false;
217   if(!_mesh1D->isEqualWithoutConsideringStr(otherC->_mesh1D,prec))
218     return false;
219   if(!_mesh3D_ids->isEqualWithoutConsideringStr(*otherC->_mesh3D_ids))
220     return false;
221   if(_cell_2D_id!=otherC->_cell_2D_id)
222     return false;
223   return true;
224 }
225
226 void MEDCouplingExtrudedMesh::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
227                                                    DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception)
228 {
229   throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::checkDeepEquivalWith : not implemented yet !");
230 }
231
232 void MEDCouplingExtrudedMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
233                                                               DataArrayInt *&cellCor) const throw(INTERP_KERNEL::Exception)
234 {
235   throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::checkDeepEquivalOnSameNodesWith : not implemented yet !");
236 }
237
238 INTERP_KERNEL::NormalizedCellType MEDCouplingExtrudedMesh::getTypeOfCell(int cellId) const
239 {
240   const int *ids=_mesh3D_ids->getConstPointer();
241   int nbOf3DCells=_mesh3D_ids->getNumberOfTuples();
242   const int *where=std::find(ids,ids+nbOf3DCells,cellId);
243   if(where==ids+nbOf3DCells)
244     throw INTERP_KERNEL::Exception("Invalid cellId specified >= getNumberOfCells() !");
245   int nbOfCells2D=_mesh2D->getNumberOfCells();
246   int locId=((int)std::distance(ids,where))%nbOfCells2D;
247   INTERP_KERNEL::NormalizedCellType tmp=_mesh2D->getTypeOfCell(locId);
248   return INTERP_KERNEL::CellModel::GetCellModel(tmp).getExtrudedType();
249 }
250
251 std::set<INTERP_KERNEL::NormalizedCellType> MEDCouplingExtrudedMesh::getAllGeoTypes() const
252 {
253   const std::set<INTERP_KERNEL::NormalizedCellType>& ret2D=_mesh2D->getAllTypes();
254   std::set<INTERP_KERNEL::NormalizedCellType> ret;
255   for(std::set<INTERP_KERNEL::NormalizedCellType>::const_iterator it=ret2D.begin();it!=ret2D.end();it++)
256     ret.insert(INTERP_KERNEL::CellModel::GetCellModel(*it).getExtrudedType());
257   return ret;
258 }
259
260 DataArrayInt *MEDCouplingExtrudedMesh::giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const
261 {
262   const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
263   INTERP_KERNEL::NormalizedCellType revExtTyp=cm.getReverseExtrudedType();
264   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
265   if(revExtTyp==INTERP_KERNEL::NORM_ERROR)
266     {
267       ret->alloc(0,1);
268       return ret.retn();
269     }
270   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=_mesh2D->giveCellsWithType(revExtTyp);
271   int nbOfLevs=_mesh1D->getNumberOfCells();
272   int nbOfCells2D=_mesh2D->getNumberOfCells();
273   int nbOfTuples=tmp->getNumberOfTuples();
274   ret->alloc(nbOfLevs*nbOfTuples,1);
275   int *pt=ret->getPointer();
276   for(int i=0;i<nbOfLevs;i++,pt+=nbOfTuples)
277     std::transform(tmp->begin(),tmp->end(),pt,std::bind2nd(std::plus<int>(),i*nbOfCells2D));
278   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=ret->renumberR(_mesh3D_ids->begin());
279   ret2->sort();
280   return ret2.retn();
281 }
282
283 DataArrayInt *MEDCouplingExtrudedMesh::computeNbOfNodesPerCell() const
284 {
285   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2D=_mesh2D->computeNbOfNodesPerCell();
286   int nbOfLevs=_mesh1D->getNumberOfCells();
287   int nbOfCells2D=_mesh2D->getNumberOfCells();
288   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret3D=DataArrayInt::New(); ret3D->alloc(nbOfLevs*nbOfCells2D,1);
289   int *pt=ret3D->getPointer();
290   for(int i=0;i<nbOfLevs;i++,pt+=nbOfCells2D)
291      std::copy(ret2D->begin(),ret2D->end(),pt);
292   ret3D->applyLin(2,0,0);
293   return ret3D->renumberR(_mesh3D_ids->begin());
294 }
295
296 DataArrayInt *MEDCouplingExtrudedMesh::computeNbOfFacesPerCell() const
297 {
298   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2D=_mesh2D->computeNbOfNodesPerCell();
299   int nbOfLevs=_mesh1D->getNumberOfCells();
300   int nbOfCells2D=_mesh2D->getNumberOfCells();
301   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret3D=DataArrayInt::New(); ret3D->alloc(nbOfLevs*nbOfCells2D,1);
302   int *pt=ret3D->getPointer();
303   for(int i=0;i<nbOfLevs;i++,pt+=nbOfCells2D)
304      std::copy(ret2D->begin(),ret2D->end(),pt);
305   ret3D->applyLin(2,2,0);
306   return ret3D->renumberR(_mesh3D_ids->begin());
307 }
308
309 DataArrayInt *MEDCouplingExtrudedMesh::computeEffectiveNbOfNodesPerCell() const
310 {
311   return computeNbOfNodesPerCell();
312 }
313
314 int MEDCouplingExtrudedMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const
315 {
316   int ret=0;
317   int nbOfCells2D=_mesh2D->getNumberOfCells();
318   for(int i=0;i<nbOfCells2D;i++)
319     {
320       INTERP_KERNEL::NormalizedCellType t=_mesh2D->getTypeOfCell(i);
321       if(INTERP_KERNEL::CellModel::GetCellModel(t).getExtrudedType()==type)
322         ret++;
323     }
324   return ret*_mesh1D->getNumberOfCells();
325 }
326
327 void MEDCouplingExtrudedMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
328 {
329   int nbOfCells2D=_mesh2D->getNumberOfCells();
330   int nbOfNodes2D=_mesh2D->getNumberOfNodes();
331   int locId=cellId%nbOfCells2D;
332   int lev=cellId/nbOfCells2D;
333   std::vector<int> tmp,tmp2;
334   _mesh2D->getNodeIdsOfCell(locId,tmp);
335   tmp2=tmp;
336   std::transform(tmp.begin(),tmp.end(),tmp.begin(),std::bind2nd(std::plus<int>(),nbOfNodes2D*lev));
337   std::transform(tmp2.begin(),tmp2.end(),tmp2.begin(),std::bind2nd(std::plus<int>(),nbOfNodes2D*(lev+1)));
338   conn.insert(conn.end(),tmp.begin(),tmp.end());
339   conn.insert(conn.end(),tmp2.begin(),tmp2.end());
340 }
341
342 void MEDCouplingExtrudedMesh::getCoordinatesOfNode(int nodeId, std::vector<double>& coo) const
343 {
344   int nbOfNodes2D=_mesh2D->getNumberOfNodes();
345   int locId=nodeId%nbOfNodes2D;
346   int lev=nodeId/nbOfNodes2D;
347   std::vector<double> tmp,tmp2;
348   _mesh2D->getCoordinatesOfNode(locId,tmp);
349   tmp2=tmp;
350   int spaceDim=_mesh1D->getSpaceDimension();
351   const double *z=_mesh1D->getCoords()->getConstPointer();
352   std::transform(tmp.begin(),tmp.end(),z+lev*spaceDim,tmp.begin(),std::plus<double>());
353   std::transform(tmp2.begin(),tmp2.end(),z+(lev+1)*spaceDim,tmp2.begin(),std::plus<double>());
354   coo.insert(coo.end(),tmp.begin(),tmp.end());
355   coo.insert(coo.end(),tmp2.begin(),tmp2.end());
356 }
357
358 std::string MEDCouplingExtrudedMesh::simpleRepr() const
359 {
360   std::ostringstream ret;
361   ret << "3D Extruded mesh from a 2D Surf Mesh with name : \"" << getName() << "\"\n";
362   ret << "Description of mesh : \"" << getDescription() << "\"\n";
363   int tmpp1,tmpp2;
364   double tt=getTime(tmpp1,tmpp2);
365   ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
366   ret << "Iteration : " << tmpp1  << " Order : " << tmpp2 << "\n";
367   ret << "Cell id where 1D mesh has been deduced : " << _cell_2D_id << "\n";
368   ret << "Number of cells : " << getNumberOfCells() << "(" << _mesh2D->getNumberOfCells() << "x" << _mesh1D->getNumberOfCells() << ")\n";
369   ret << "1D Mesh info : _____________________\n\n\n";
370   ret << _mesh1D->simpleRepr();
371   ret << "\n\n\n2D Mesh info : _____________________\n\n\n" << _mesh2D->simpleRepr() << "\n\n\n";
372   return ret.str();
373 }
374
375 std::string MEDCouplingExtrudedMesh::advancedRepr() const
376 {
377   std::ostringstream ret;
378   ret << "3D Extruded mesh from a 2D Surf Mesh with name : \"" << getName() << "\"\n";
379   ret << "Description of mesh : \"" << getDescription() << "\"\n";
380   int tmpp1,tmpp2;
381   double tt=getTime(tmpp1,tmpp2);
382   ret << "Time attached to the mesh (unit) : " << tt << " (" << getTimeUnit() << ")\n";
383   ret << "Iteration : " << tmpp1  << " Order : " << tmpp2 << "\n";
384   ret << "Cell id where 1D mesh has been deduced : " << _cell_2D_id << "\n";
385   ret << "Number of cells : " << getNumberOfCells() << "(" << _mesh2D->getNumberOfCells() << "x" << _mesh1D->getNumberOfCells() << ")\n";
386   ret << "1D Mesh info : _____________________\n\n\n";
387   ret << _mesh1D->advancedRepr();
388   ret << "\n\n\n2D Mesh info : _____________________\n\n\n" << _mesh2D->advancedRepr() << "\n\n\n";
389   ret << "3D cell ids per level :\n";
390   return ret.str();
391 }
392
393 void MEDCouplingExtrudedMesh::checkCoherency() const throw (INTERP_KERNEL::Exception)
394 {
395 }
396
397 void MEDCouplingExtrudedMesh::checkCoherency1(double eps) const
398 {
399   checkCoherency();
400 }
401
402 void MEDCouplingExtrudedMesh::checkCoherency2(double eps) const
403 {
404   checkCoherency1(eps);
405 }
406
407 void MEDCouplingExtrudedMesh::getBoundingBox(double *bbox) const
408 {
409   double bbox2D[6];
410   _mesh2D->getBoundingBox(bbox2D);
411   const double *nodes1D=_mesh1D->getCoords()->getConstPointer();
412   int nbOfNodes1D=_mesh1D->getNumberOfNodes();
413   double bbox1DMin[3],bbox1DMax[3],tmp[3];
414   std::fill(bbox1DMin,bbox1DMin+3,std::numeric_limits<double>::max());
415   std::fill(bbox1DMax,bbox1DMax+3,-(std::numeric_limits<double>::max()));
416   for(int i=0;i<nbOfNodes1D;i++)
417     {
418       std::transform(nodes1D+3*i,nodes1D+3*(i+1),bbox1DMin,bbox1DMin,static_cast<const double& (*)(const double&, const double&)>(std::min<double>));
419       std::transform(nodes1D+3*i,nodes1D+3*(i+1),bbox1DMax,bbox1DMax,static_cast<const double& (*)(const double&, const double&)>(std::max<double>));
420     }
421   std::transform(bbox1DMax,bbox1DMax+3,bbox1DMin,tmp,std::minus<double>());
422   int id=(int)std::distance(tmp,std::max_element(tmp,tmp+3));
423   bbox[0]=bbox1DMin[0]; bbox[1]=bbox1DMax[0];
424   bbox[2]=bbox1DMin[1]; bbox[3]=bbox1DMax[1];
425   bbox[4]=bbox1DMin[2]; bbox[5]=bbox1DMax[2];
426   bbox[2*id+1]+=tmp[id];
427 }
428
429 void MEDCouplingExtrudedMesh::updateTime() const
430 {
431   if(_mesh2D)
432     {
433       updateTimeWith(*_mesh2D);
434     }
435   if(_mesh1D)
436     {
437       updateTimeWith(*_mesh1D);
438     }
439 }
440
441 void MEDCouplingExtrudedMesh::renumberCells(const int *old2NewBg, bool check)
442 {
443   throw INTERP_KERNEL::Exception("Functionnality of renumbering cells unavailable for ExtrudedMesh");
444 }
445
446 MEDCouplingUMesh *MEDCouplingExtrudedMesh::build3DUnstructuredMesh() const
447 {
448   MEDCouplingUMesh *ret=_mesh2D->buildExtrudedMesh(_mesh1D,0);
449   const int *renum=_mesh3D_ids->getConstPointer();
450   ret->renumberCells(renum,false);
451   ret->setName(getName().c_str());
452   return ret;
453 }
454
455 MEDCouplingUMesh *MEDCouplingExtrudedMesh::buildUnstructured() const
456 {
457   return build3DUnstructuredMesh();
458 }
459
460 MEDCouplingFieldDouble *MEDCouplingExtrudedMesh::getMeasureField(bool) const
461 {
462   std::string name="MeasureOfMesh_";
463   name+=getName();
464   MEDCouplingFieldDouble *ret2D=_mesh2D->getMeasureField(true);
465   MEDCouplingFieldDouble *ret1D=_mesh1D->getMeasureField(true);
466   const double *ret2DPtr=ret2D->getArray()->getConstPointer();
467   const double *ret1DPtr=ret1D->getArray()->getConstPointer();
468   int nbOf2DCells=_mesh2D->getNumberOfCells();
469   int nbOf1DCells=_mesh1D->getNumberOfCells();
470   int nbOf3DCells=nbOf2DCells*nbOf1DCells;
471   const int *renum=_mesh3D_ids->getConstPointer();
472   MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME);
473   ret->setMesh(this);
474   ret->synchronizeTimeWithMesh();
475   DataArrayDouble *da=DataArrayDouble::New();
476   da->alloc(nbOf3DCells,1);
477   double *retPtr=da->getPointer();
478   for(int i=0;i<nbOf1DCells;i++)
479     for(int j=0;j<nbOf2DCells;j++)
480       retPtr[renum[i*nbOf2DCells+j]]=ret2DPtr[j]*ret1DPtr[i];
481   ret->setArray(da);
482   da->decrRef();
483   ret->setName(name.c_str());
484   ret2D->decrRef();
485   ret1D->decrRef();
486   return ret;
487 }
488
489 MEDCouplingFieldDouble *MEDCouplingExtrudedMesh::getMeasureFieldOnNode(bool isAbs) const
490 {
491   //not implemented yet
492   return 0;
493 }
494
495 MEDCouplingFieldDouble *MEDCouplingExtrudedMesh::buildOrthogonalField() const
496 {
497   throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::buildOrthogonalField : This method has no sense for MEDCouplingExtrudedMesh that is 3D !");
498 }
499
500 int MEDCouplingExtrudedMesh::getCellContainingPoint(const double *pos, double eps) const
501 {
502   throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::getCellContainingPoint : not implemented yet !");
503 }
504
505 MEDCouplingExtrudedMesh::~MEDCouplingExtrudedMesh()
506 {
507   if(_mesh2D)
508     _mesh2D->decrRef();
509   if(_mesh1D)
510     _mesh1D->decrRef();
511   if(_mesh3D_ids)
512     _mesh3D_ids->decrRef();
513 }
514
515 void MEDCouplingExtrudedMesh::computeExtrusion(const MEDCouplingUMesh *mesh3D)
516 {
517   const char errMsg1[]="2D mesh is empty unable to compute extrusion !";
518   const char errMsg2[]="Coords between 2D and 3D meshes are not the same ! Try MEDCouplingPointSet::tryToShareSameCoords method";
519   const char errMsg3[]="No chance to find extrusion pattern in mesh3D,mesh2D couple because nbCells3D%nbCells2D!=0 !";
520   if(_mesh2D==0 || mesh3D==0)
521     throw INTERP_KERNEL::Exception(errMsg1);
522   if(_mesh2D->getCoords()!=mesh3D->getCoords())
523     throw INTERP_KERNEL::Exception(errMsg2);
524   if(mesh3D->getNumberOfCells()%_mesh2D->getNumberOfCells()!=0)
525     throw INTERP_KERNEL::Exception(errMsg3);
526   if(!_mesh3D_ids)
527     _mesh3D_ids=DataArrayInt::New();
528   if(!_mesh1D)
529     _mesh1D=MEDCouplingUMesh::New();
530   computeExtrusionAlg(mesh3D);
531 }
532
533 void MEDCouplingExtrudedMesh::build1DExtrusion(int idIn3DDesc, int newId, int nbOf1DLev, MEDCouplingUMesh *subMesh,
534                                                const int *desc3D, const int *descIndx3D,
535                                                const int *revDesc3D, const int *revDescIndx3D,
536                                                bool computeMesh1D) throw(INTERP_KERNEL::Exception)
537 {
538   int nbOf2DCells=_mesh2D->getNumberOfCells();
539   int start=revDescIndx3D[idIn3DDesc];
540   int end=revDescIndx3D[idIn3DDesc+1];
541   if(end-start!=1)
542     {
543       std::ostringstream ost; ost << "Invalid bases 2D mesh specified : 2D cell # " <<  idIn3DDesc;
544       ost << " shared by more than 1 3D cell !!!";
545       throw INTERP_KERNEL::Exception(ost.str().c_str());
546     }
547   int current3DCell=revDesc3D[start];
548   int current2DCell=idIn3DDesc;
549   int *mesh3DIDs=_mesh3D_ids->getPointer();
550   mesh3DIDs[newId]=current3DCell;
551   const int *conn2D=subMesh->getNodalConnectivity()->getConstPointer();
552   const int *conn2DIndx=subMesh->getNodalConnectivityIndex()->getConstPointer();
553   for(int i=1;i<nbOf1DLev;i++)
554     {
555       std::vector<int> conn(conn2D+conn2DIndx[current2DCell]+1,conn2D+conn2DIndx[current2DCell+1]);
556       std::sort(conn.begin(),conn.end());
557       if(computeMesh1D)
558         computeBaryCenterOfFace(conn,i-1);
559       current2DCell=findOppositeFaceOf(current2DCell,current3DCell,conn,
560                                        desc3D,descIndx3D,conn2D,conn2DIndx);
561       start=revDescIndx3D[current2DCell];
562       end=revDescIndx3D[current2DCell+1];
563       if(end-start!=2)
564         {
565           std::ostringstream ost; ost << "Expecting to have 2 3D cells attached to 2D cell " << current2DCell << "!";
566           ost << " : Impossible or call tryToShareSameCoords method !";
567           throw INTERP_KERNEL::Exception(ost.str().c_str());
568         }
569       if(revDesc3D[start]!=current3DCell)
570         current3DCell=revDesc3D[start];
571       else
572         current3DCell=revDesc3D[start+1];
573       mesh3DIDs[i*nbOf2DCells+newId]=current3DCell;
574     }
575   if(computeMesh1D)
576     {
577       std::vector<int> conn(conn2D+conn2DIndx[current2DCell]+1,conn2D+conn2DIndx[current2DCell+1]);
578       std::sort(conn.begin(),conn.end());
579       computeBaryCenterOfFace(conn,nbOf1DLev-1);
580       current2DCell=findOppositeFaceOf(current2DCell,current3DCell,conn,
581                                        desc3D,descIndx3D,conn2D,conn2DIndx);
582       conn.clear();
583       conn.insert(conn.end(),conn2D+conn2DIndx[current2DCell]+1,conn2D+conn2DIndx[current2DCell+1]);
584       std::sort(conn.begin(),conn.end());
585       computeBaryCenterOfFace(conn,nbOf1DLev);
586     }
587 }
588
589 int MEDCouplingExtrudedMesh::findOppositeFaceOf(int current2DCell, int current3DCell, const std::vector<int>& connSorted,
590                                                 const int *desc3D, const int *descIndx3D,
591                                                 const int *conn2D, const int *conn2DIndx) throw(INTERP_KERNEL::Exception)
592 {
593   int start=descIndx3D[current3DCell];
594   int end=descIndx3D[current3DCell+1];
595   bool found=false;
596   for(const int *candidate2D=desc3D+start;candidate2D!=desc3D+end && !found;candidate2D++)
597     {
598       if(*candidate2D!=current2DCell)
599         {
600           std::vector<int> conn2(conn2D+conn2DIndx[*candidate2D]+1,conn2D+conn2DIndx[*candidate2D+1]);
601           std::sort(conn2.begin(),conn2.end());
602           std::list<int> intersect;
603           std::set_intersection(connSorted.begin(),connSorted.end(),conn2.begin(),conn2.end(),
604                                 std::insert_iterator< std::list<int> >(intersect,intersect.begin()));
605           if(intersect.empty())
606             return *candidate2D;
607         }
608     }
609   std::ostringstream ost; ost << "Impossible to find an opposite 2D face of face # " <<  current2DCell;
610   ost << " in 3D cell # " << current3DCell << " : Impossible or call tryToShareSameCoords method !";
611   throw INTERP_KERNEL::Exception(ost.str().c_str());
612 }
613
614 void MEDCouplingExtrudedMesh::computeBaryCenterOfFace(const std::vector<int>& nodalConnec, int lev1DId)
615 {
616   double *zoneToUpdate=_mesh1D->getCoords()->getPointer()+lev1DId*3;
617   std::fill(zoneToUpdate,zoneToUpdate+3,0.);
618   const double *coords=_mesh2D->getCoords()->getConstPointer();
619   for(std::vector<int>::const_iterator iter=nodalConnec.begin();iter!=nodalConnec.end();iter++)
620     std::transform(zoneToUpdate,zoneToUpdate+3,coords+3*(*iter),zoneToUpdate,std::plus<double>());
621   std::transform(zoneToUpdate,zoneToUpdate+3,zoneToUpdate,std::bind2nd(std::multiplies<double>(),(double)(1./(int)nodalConnec.size())));
622 }
623
624 int MEDCouplingExtrudedMesh::FindCorrespCellByNodalConn(const std::vector<int>& nodalConnec, const int *revNodalPtr, const int *revNodalIndxPtr) throw(INTERP_KERNEL::Exception)
625 {
626   std::vector<int>::const_iterator iter=nodalConnec.begin();
627   std::set<int> s1(revNodalPtr+revNodalIndxPtr[*iter],revNodalPtr+revNodalIndxPtr[*iter+1]);
628   iter++;
629   for(;iter!=nodalConnec.end();iter++)
630     {
631       std::set<int> s2(revNodalPtr+revNodalIndxPtr[*iter],revNodalPtr+revNodalIndxPtr[*iter+1]);
632       std::set<int> s3;
633       std::set_intersection(s1.begin(),s1.end(),s2.begin(),s2.end(),std::insert_iterator< std::set<int> >(s3,s3.end()));
634       s1=s3;
635     }
636   if(s1.size()==1)
637     return *(s1.begin());
638   std::ostringstream ostr;
639   ostr << "Cell with nodal connec : ";
640   std::copy(nodalConnec.begin(),nodalConnec.end(),std::ostream_iterator<int>(ostr," "));
641   ostr << " is not part of mesh";
642   throw INTERP_KERNEL::Exception(ostr.str().c_str());
643 }
644
645 /*!
646  * This method is callable on 1Dmeshes (meshDim==1 && spaceDim==3) returned by MEDCouplingExtrudedMesh::getMesh1D typically.
647  * These 1Dmeshes (meshDim==1 && spaceDim==3) have a special semantic because these meshes do not specify a static location but a translation along a path.
648  * This method checks that 'm1' and 'm2' are compatible, if not an exception is thrown. In case these meshes ('m1' and 'm2') are compatible 2 corresponding meshes
649  * are created ('m1r' and 'm2r') that can be used for interpolation.
650  * @param m1 input mesh with meshDim==1 and spaceDim==3
651  * @param m2 input mesh with meshDim==1 and spaceDim==3
652  * @param eps tolerance acceptable to determine compatibility
653  * @param m1r output mesh with ref count equal to 1 with meshDim==1 and spaceDim==1
654  * @param m2r output mesh with ref count equal to 1 with meshDim==1 and spaceDim==1
655  * @param v is the output normalized vector of the common direction of 'm1' and 'm2'  
656  * @throw in case that m1 and m2 are not compatible each other.
657  */
658 void MEDCouplingExtrudedMesh::Project1DMeshes(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, double eps,
659                                               MEDCouplingUMesh *&m1r, MEDCouplingUMesh *&m2r, double *v) throw(INTERP_KERNEL::Exception)
660 {
661   if(m1->getSpaceDimension()!=3 || m1->getSpaceDimension()!=3)
662     throw INTERP_KERNEL::Exception("Input meshes are expected to have a spaceDim==3 for Projec1D !");
663   m1r=m1->clone(true);
664   m2r=m2->clone(true);
665   m1r->changeSpaceDimension(1);
666   m2r->changeSpaceDimension(1);
667   std::vector<int> c;
668   std::vector<double> ref,ref2;
669   m1->getNodeIdsOfCell(0,c);
670   m1->getCoordinatesOfNode(c[0],ref);
671   m1->getCoordinatesOfNode(c[1],ref2);
672   std::transform(ref2.begin(),ref2.end(),ref.begin(),v,std::minus<double>());
673   double n=INTERP_KERNEL::norm<3>(v);
674   std::transform(v,v+3,v,std::bind2nd(std::multiplies<double>(),1/n));
675   m1->project1D(&ref[0],v,eps,m1r->getCoords()->getPointer());
676   m2->project1D(&ref[0],v,eps,m2r->getCoords()->getPointer());
677   
678 }
679
680 void MEDCouplingExtrudedMesh::rotate(const double *center, const double *vector, double angle)
681 {
682   _mesh2D->rotate(center,vector,angle);
683   _mesh1D->rotate(center,vector,angle);
684 }
685
686 void MEDCouplingExtrudedMesh::translate(const double *vector)
687 {
688   _mesh2D->translate(vector);
689   _mesh1D->translate(vector);
690 }
691
692 void MEDCouplingExtrudedMesh::scale(const double *point, double factor)
693 {
694   _mesh2D->scale(point,factor);
695   _mesh1D->scale(point,factor);
696 }
697
698 std::vector<int> MEDCouplingExtrudedMesh::getDistributionOfTypes() const
699 {
700   throw INTERP_KERNEL::Exception("Not implemented yet !");
701 }
702
703 DataArrayInt *MEDCouplingExtrudedMesh::checkTypeConsistencyAndContig(const std::vector<int>& code, const std::vector<const DataArrayInt *>& idsPerType) const
704 {
705   throw INTERP_KERNEL::Exception("Not implemented yet !");
706 }
707
708 void MEDCouplingExtrudedMesh::splitProfilePerType(const DataArrayInt *profile, std::vector<int>& code, std::vector<DataArrayInt *>& idsInPflPerType, std::vector<DataArrayInt *>& idsPerType) const
709 {
710   throw INTERP_KERNEL::Exception("Not implemented yet !");
711 }
712
713 MEDCouplingMesh *MEDCouplingExtrudedMesh::buildPart(const int *start, const int *end) const
714 {
715   // not implemented yet !
716   return 0;
717 }
718
719 MEDCouplingMesh *MEDCouplingExtrudedMesh::buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const
720 {
721   // not implemented yet !
722   return 0;
723 }
724
725 DataArrayInt *MEDCouplingExtrudedMesh::simplexize(int policy)
726 {
727   throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::simplexize : unavailable for such a type of mesh : Extruded !");
728 }
729
730 MEDCouplingMesh *MEDCouplingExtrudedMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
731 {
732   // not implemented yet !
733   return 0;
734 }
735
736 DataArrayDouble *MEDCouplingExtrudedMesh::getCoordinatesAndOwner() const
737 {
738   DataArrayDouble *arr2D=_mesh2D->getCoords();
739   DataArrayDouble *arr1D=_mesh1D->getCoords();
740   DataArrayDouble *ret=DataArrayDouble::New();
741   ret->alloc(getNumberOfNodes(),3);
742   int nbOf1DLev=_mesh1D->getNumberOfNodes();
743   int nbOf2DNodes=_mesh2D->getNumberOfNodes();
744   const double *ptSrc=arr2D->getConstPointer();
745   double *pt=ret->getPointer();
746   std::copy(ptSrc,ptSrc+3*nbOf2DNodes,pt);
747   for(int i=1;i<nbOf1DLev;i++)
748     {
749       std::copy(ptSrc,ptSrc+3*nbOf2DNodes,pt+3*i*nbOf2DNodes);
750       double vec[3];
751       std::copy(arr1D->getConstPointer()+3*i,arr1D->getConstPointer()+3*(i+1),vec);
752       std::transform(arr1D->getConstPointer()+3*(i-1),arr1D->getConstPointer()+3*i,vec,vec,std::minus<double>());
753       for(int j=0;j<nbOf2DNodes;j++)
754         std::transform(vec,vec+3,pt+3*(i*nbOf2DNodes+j),pt+3*(i*nbOf2DNodes+j),std::plus<double>());
755     }
756   return ret;
757 }
758
759 DataArrayDouble *MEDCouplingExtrudedMesh::getBarycenterAndOwner() const
760 {
761   throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::getBarycenterAndOwner : not yet implemented !");
762 }
763
764 DataArrayDouble *MEDCouplingExtrudedMesh::computeIsoBarycenterOfNodesPerCell() const
765 {
766   throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::computeIsoBarycenterOfNodesPerCell: not yet implemented !");
767 }
768
769 void MEDCouplingExtrudedMesh::computeExtrusionAlg(const MEDCouplingUMesh *mesh3D)
770 {
771   _mesh3D_ids->alloc(mesh3D->getNumberOfCells(),1);
772   int nbOf1DLev=mesh3D->getNumberOfCells()/_mesh2D->getNumberOfCells();
773   _mesh1D->setMeshDimension(1);
774   _mesh1D->allocateCells(nbOf1DLev);
775   int tmpConn[2];
776   for(int i=0;i<nbOf1DLev;i++)
777     {
778       tmpConn[0]=i;
779       tmpConn[1]=i+1;
780       _mesh1D->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,tmpConn);
781     }
782   _mesh1D->finishInsertingCells();
783   DataArrayDouble *myCoords=DataArrayDouble::New();
784   myCoords->alloc(nbOf1DLev+1,3);
785   _mesh1D->setCoords(myCoords);
786   myCoords->decrRef();
787   DataArrayInt *desc,*descIndx,*revDesc,*revDescIndx;
788   desc=DataArrayInt::New(); descIndx=DataArrayInt::New(); revDesc=DataArrayInt::New(); revDescIndx=DataArrayInt::New();
789   MEDCouplingUMesh *subMesh=mesh3D->buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx);
790   DataArrayInt *revNodal2D,*revNodalIndx2D;
791   revNodal2D=DataArrayInt::New(); revNodalIndx2D=DataArrayInt::New();
792   subMesh->getReverseNodalConnectivity(revNodal2D,revNodalIndx2D);
793   const int *nodal2D=_mesh2D->getNodalConnectivity()->getConstPointer();
794   const int *nodal2DIndx=_mesh2D->getNodalConnectivityIndex()->getConstPointer();
795   const int *revNodal2DPtr=revNodal2D->getConstPointer();
796   const int *revNodalIndx2DPtr=revNodalIndx2D->getConstPointer();
797   const int *descP=desc->getConstPointer();
798   const int *descIndxP=descIndx->getConstPointer();
799   const int *revDescP=revDesc->getConstPointer();
800   const int *revDescIndxP=revDescIndx->getConstPointer();
801   //
802   int nbOf2DCells=_mesh2D->getNumberOfCells();
803   for(int i=0;i<nbOf2DCells;i++)
804     {
805       int idInSubMesh;
806        std::vector<int> nodalConnec(nodal2D+nodal2DIndx[i]+1,nodal2D+nodal2DIndx[i+1]);
807        try
808         {
809           idInSubMesh=FindCorrespCellByNodalConn(nodalConnec,revNodal2DPtr,revNodalIndx2DPtr);
810         }
811        catch(INTERP_KERNEL::Exception& e)
812          {
813            std::ostringstream ostr; ostr << "mesh2D cell # " << i << " is not part of any cell of 3D mesh !\n";
814            ostr << e.what();
815            throw INTERP_KERNEL::Exception(ostr.str().c_str());
816          }
817        build1DExtrusion(idInSubMesh,i,nbOf1DLev,subMesh,descP,descIndxP,revDescP,revDescIndxP,i==_cell_2D_id);
818     }
819   //
820   revNodal2D->decrRef();
821   revNodalIndx2D->decrRef();
822   subMesh->decrRef();
823   desc->decrRef();
824   descIndx->decrRef();
825   revDesc->decrRef();
826   revDescIndx->decrRef();
827 }
828
829 void MEDCouplingExtrudedMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const
830 {
831   std::vector<int> tinyInfo1;
832   std::vector<std::string> ls1;
833   std::vector<double> ls3;
834   _mesh2D->getTinySerializationInformation(ls3,tinyInfo1,ls1);
835   std::vector<int> tinyInfo2;
836   std::vector<std::string> ls2;
837   std::vector<double> ls4;
838   _mesh1D->getTinySerializationInformation(ls4,tinyInfo2,ls2);
839   tinyInfo.clear(); littleStrings.clear();
840   tinyInfo.insert(tinyInfo.end(),tinyInfo1.begin(),tinyInfo1.end());
841   littleStrings.insert(littleStrings.end(),ls1.begin(),ls1.end());
842   tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
843   littleStrings.insert(littleStrings.end(),ls2.begin(),ls2.end());
844   tinyInfo.push_back(_cell_2D_id);
845   tinyInfo.push_back((int)tinyInfo1.size());
846   tinyInfo.push_back(_mesh3D_ids->getNbOfElems());
847   littleStrings.push_back(getName());
848   littleStrings.push_back(getDescription());
849 }
850
851 void MEDCouplingExtrudedMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
852 {
853   std::size_t sz=tinyInfo.size();
854   int sz1=tinyInfo[sz-2];
855   std::vector<int> ti1(tinyInfo.begin(),tinyInfo.begin()+sz1);
856   std::vector<int> ti2(tinyInfo.begin()+sz1,tinyInfo.end()-3);
857   MEDCouplingUMesh *um=MEDCouplingUMesh::New();
858   DataArrayInt *a1tmp=DataArrayInt::New();
859   DataArrayDouble *a2tmp=DataArrayDouble::New();
860   int la1=0,la2=0;
861   std::vector<std::string> ls1,ls2;
862   um->resizeForUnserialization(ti1,a1tmp,a2tmp,ls1);
863   la1+=a1tmp->getNbOfElems(); la2+=a2tmp->getNbOfElems();
864   a1tmp->decrRef(); a2tmp->decrRef();
865   a1tmp=DataArrayInt::New(); a2tmp=DataArrayDouble::New();
866   um->resizeForUnserialization(ti2,a1tmp,a2tmp,ls2);
867   la1+=a1tmp->getNbOfElems(); la2+=a2tmp->getNbOfElems();
868   a1tmp->decrRef(); a2tmp->decrRef();
869   um->decrRef();
870   //
871   a1->alloc(la1+tinyInfo[sz-1],1);
872   a2->alloc(la2,1);
873   littleStrings.resize(ls1.size()+ls2.size()+2);
874 }
875
876 void MEDCouplingExtrudedMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const
877 {
878   a1=DataArrayInt::New(); a2=DataArrayDouble::New();
879   DataArrayInt *a1_1=0,*a1_2=0;
880   DataArrayDouble *a2_1=0,*a2_2=0;
881   _mesh2D->serialize(a1_1,a2_1);
882   _mesh1D->serialize(a1_2,a2_2);
883   a1->alloc(a1_1->getNbOfElems()+a1_2->getNbOfElems()+_mesh3D_ids->getNbOfElems(),1);
884   int *ptri=a1->getPointer();
885   ptri=std::copy(a1_1->getConstPointer(),a1_1->getConstPointer()+a1_1->getNbOfElems(),ptri);
886   a1_1->decrRef();
887   ptri=std::copy(a1_2->getConstPointer(),a1_2->getConstPointer()+a1_2->getNbOfElems(),ptri);
888   a1_2->decrRef();
889   std::copy(_mesh3D_ids->getConstPointer(),_mesh3D_ids->getConstPointer()+_mesh3D_ids->getNbOfElems(),ptri);
890   a2->alloc(a2_1->getNbOfElems()+a2_2->getNbOfElems(),1);
891   double *ptrd=a2->getPointer();
892   ptrd=std::copy(a2_1->getConstPointer(),a2_1->getConstPointer()+a2_1->getNbOfElems(),ptrd);
893   a2_1->decrRef();
894   std::copy(a2_2->getConstPointer(),a2_2->getConstPointer()+a2_2->getNbOfElems(),ptrd);
895   a2_2->decrRef();
896 }
897
898 void MEDCouplingExtrudedMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, const std::vector<std::string>& littleStrings)
899 {
900   setName(littleStrings[littleStrings.size()-2].c_str());
901   setDescription(littleStrings.back().c_str());
902   std::size_t sz=tinyInfo.size();
903   int sz1=tinyInfo[sz-2];
904   _cell_2D_id=tinyInfo[sz-3];
905   std::vector<int> ti1(tinyInfo.begin(),tinyInfo.begin()+sz1);
906   std::vector<int> ti2(tinyInfo.begin()+sz1,tinyInfo.end()-3);
907   DataArrayInt *a1tmp=DataArrayInt::New();
908   DataArrayDouble *a2tmp=DataArrayDouble::New();
909   const int *a1Ptr=a1->getConstPointer();
910   const double *a2Ptr=a2->getConstPointer();
911   _mesh2D=MEDCouplingUMesh::New();
912   std::vector<std::string> ls1,ls2;
913   _mesh2D->resizeForUnserialization(ti1,a1tmp,a2tmp,ls1);
914   std::copy(a2Ptr,a2Ptr+a2tmp->getNbOfElems(),a2tmp->getPointer());
915   std::copy(a1Ptr,a1Ptr+a1tmp->getNbOfElems(),a1tmp->getPointer());
916   a2Ptr+=a2tmp->getNbOfElems();
917   a1Ptr+=a1tmp->getNbOfElems();
918   ls2.insert(ls2.end(),littleStrings.begin(),littleStrings.begin()+ls1.size());
919   std::vector<double> d1(1);
920   _mesh2D->unserialization(d1,ti1,a1tmp,a2tmp,ls2);
921   a1tmp->decrRef(); a2tmp->decrRef();
922   //
923   ls2.clear();
924   ls2.insert(ls2.end(),littleStrings.begin()+ls1.size(),littleStrings.end()-2);
925   _mesh1D=MEDCouplingUMesh::New();
926   a1tmp=DataArrayInt::New(); a2tmp=DataArrayDouble::New();
927   _mesh1D->resizeForUnserialization(ti2,a1tmp,a2tmp,ls1);
928   std::copy(a2Ptr,a2Ptr+a2tmp->getNbOfElems(),a2tmp->getPointer());
929   std::copy(a1Ptr,a1Ptr+a1tmp->getNbOfElems(),a1tmp->getPointer());
930   a1Ptr+=a1tmp->getNbOfElems();
931   _mesh1D->unserialization(d1,ti2,a1tmp,a2tmp,ls2);
932   a1tmp->decrRef(); a2tmp->decrRef();
933   //
934   _mesh3D_ids=DataArrayInt::New();
935   int szIds=(int)std::distance(a1Ptr,a1->getConstPointer()+a1->getNbOfElems());
936   _mesh3D_ids->alloc(szIds,1);
937   std::copy(a1Ptr,a1Ptr+szIds,_mesh3D_ids->getPointer());
938 }
939
940 void MEDCouplingExtrudedMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const
941 {
942   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
943   m->writeVTKLL(ofs,cellData,pointData,byteData);
944 }
945
946 void MEDCouplingExtrudedMesh::reprQuickOverview(std::ostream& stream) const
947 {
948   stream << "MEDCouplingExtrudedMesh C++ instance at " << this << ". Name : \"" << getName() << "\".";
949 }
950
951 std::string MEDCouplingExtrudedMesh::getVTKDataSetType() const
952 {
953   return _mesh2D->getVTKDataSetType();
954 }