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