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