Salome HOME
[EDF23724] : Get rid of DataArrayMedInt class not castable into DataArrayInt32 nor...
[tools/medcoupling.git] / src / MEDLoader / MEDFileMeshElt.cxx
1 // Copyright (C) 2007-2021  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 "MEDFileMeshElt.hxx"
22 #include "MEDFileSafeCaller.txx"
23 #include "MEDFileMeshReadSelector.hxx"
24 #include "MEDFileBasis.hxx"
25
26 #include "MEDCouplingUMesh.hxx"
27
28 #include "InterpKernelException.hxx"
29 #include "InterpKernelAutoPtr.hxx"
30 #include "CellModel.hxx"
31
32 #include <iostream>
33
34 // From MEDLOader.cxx TU
35 extern med_geometry_type typmai3[INTERP_KERNEL::NORM_MAXTYPE];
36
37 using namespace MEDCoupling;
38
39 MEDFileUMeshPerTypeCommon *MEDFileUMeshPerTypeCommon::New()
40 {
41   return new MEDFileUMeshPerTypeCommon;
42 }
43
44 void MEDFileUMeshPerTypeCommon::loadCommonPart(med_idt fid, const char *mName, int dt, int it, mcIdType curNbOfElem, med_geometry_type geoElt,
45                                                med_entity_type entity, MEDFileMeshReadSelector *mrs)
46 {
47   med_bool changement,transformation;
48   _fam=0;
49   if(MEDmeshnEntity(fid,mName,dt,it,entity,geoElt,MED_FAMILY_NUMBER,MED_NODAL,&changement,&transformation)>0)
50     {    
51       if(!mrs || mrs->isCellFamilyFieldReading())
52         {
53           MCAuto<DataArrayMedInt> miFam=DataArrayMedInt::New();
54           miFam->alloc(curNbOfElem,1);
55           if(MEDmeshEntityFamilyNumberRd(fid,mName,dt,it,entity,geoElt,miFam->getPointer())!=0)
56             std::fill(miFam->getPointer(),miFam->getPointer()+curNbOfElem,0);
57           _fam=FromMedIntArray<mcIdType>( miFam );
58         }
59     }
60   _num=0;
61   if(MEDmeshnEntity(fid,mName,dt,it,entity,geoElt,MED_NUMBER,MED_NODAL,&changement,&transformation)>0)
62     {
63       if(!mrs || mrs->isCellNumFieldReading())
64         {
65           MCAuto<DataArrayMedInt> miNum=DataArrayMedInt::New();
66           miNum->alloc(curNbOfElem,1);
67           if(MEDmeshEntityNumberRd(fid,mName,dt,it,entity,geoElt,miNum->getPointer())!=0)
68             miNum=0;
69           _num=FromMedIntArray<mcIdType>(miNum);
70         }
71     }
72   _names=0;
73   if(MEDmeshnEntity(fid,mName,dt,it,entity,geoElt,MED_NAME,MED_NODAL,&changement,&transformation)>0)
74     {
75       if(!mrs || mrs->isCellNameFieldReading())
76         {
77           _names=DataArrayAsciiChar::New();
78           _names->alloc(curNbOfElem+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
79           if(MEDmeshEntityNameRd(fid,mName,dt,it,entity,geoElt,_names->getPointer())!=0)
80             _names=0;
81           else
82             _names->reAlloc(curNbOfElem);//not a bug to avoid the memory corruption due to last \0 at the end
83         }
84     }
85 }
86
87 std::size_t MEDFileUMeshPerTypeCommon::getHeapMemorySizeWithoutChildren() const
88 {
89   return 0;
90 }
91
92 std::vector<const BigMemoryObject *> MEDFileUMeshPerTypeCommon::getDirectChildrenWithNull() const
93 {
94   std::vector<const BigMemoryObject *> ret;
95   ret.push_back((const DataArrayIdType *)_num);
96   ret.push_back((const DataArrayIdType *)_fam);
97   ret.push_back((const DataArrayAsciiChar *)_names);
98   return ret;
99 }
100
101 MEDFileUMeshPerType *MEDFileUMeshPerType::New(med_idt fid, const char *mName, int dt, int it, int mdim, med_geometry_type geoElt, INTERP_KERNEL::NormalizedCellType geoElt2, MEDFileMeshReadSelector *mrs)
102 {
103   med_entity_type whichEntity;
104   if(!isExisting(fid,mName,dt,it,geoElt,whichEntity))
105     return 0;
106   return new MEDFileUMeshPerType(fid,mName,dt,it,mdim,geoElt,geoElt2,whichEntity,mrs);
107 }
108
109 MEDFileUMeshPerType *MEDFileUMeshPerType::NewPart(med_idt fid, const char *mName, int dt, int it, int mdim, INTERP_KERNEL::NormalizedCellType geoElt2, mcIdType strt, mcIdType stp, mcIdType step, MEDFileMeshReadSelector *mrs)
110 {
111   int geoElt2i((int)geoElt2);
112   if(geoElt2i<0 || geoElt2i>=INTERP_KERNEL::NORM_MAXTYPE)
113     throw INTERP_KERNEL::Exception("MEDFileUMeshPerType::NewPart : Not recognized MEDCoupling/MEDLoader geometric type !");
114   med_geometry_type geoElt(typmai3[geoElt2]);
115   med_entity_type whichEntity;
116   if(!isExisting(fid,mName,dt,it,geoElt,whichEntity))
117     throw INTERP_KERNEL::Exception("MEDFileUMeshPerType::NewPart : The specified geo type is not present in the specified mesh !");
118   MCAuto<MEDFileUMeshPerType> ret(new MEDFileUMeshPerType);
119   ret->loadPart(fid,mName,dt,it,mdim,geoElt,geoElt2,whichEntity,strt,stp,step,mrs);
120   return ret.retn();
121 }
122
123 std::size_t MEDFileUMeshPerType::getHeapMemorySizeWithoutChildren() const
124 {
125   return MEDFileUMeshPerTypeCommon::getHeapMemorySizeWithoutChildren()+0;
126 }
127
128 std::vector<const BigMemoryObject *> MEDFileUMeshPerType::getDirectChildrenWithNull() const
129 {
130   std::vector<const BigMemoryObject *> ret(MEDFileUMeshPerTypeCommon::getDirectChildrenWithNull());
131   ret.push_back((const MEDCoupling1GTUMesh *)_m);
132   return ret;
133 }
134
135 bool MEDFileUMeshPerType::isExisting(med_idt fid, const char *mName, int dt, int it, med_geometry_type geoElt, med_entity_type& whichEntity)
136 {
137   static const med_entity_type entities[3]={MED_CELL,MED_DESCENDING_FACE,MED_DESCENDING_EDGE};
138   mcIdType nbOfElt=0;
139   for(int i=0;i<3;i++)
140     {
141       med_bool changement,transformation;
142       mcIdType tmp(MEDmeshnEntity(fid,mName,dt,it,entities[i],geoElt,MED_CONNECTIVITY,MED_NODAL,&changement,&transformation));
143       if(tmp>nbOfElt)
144         {
145           nbOfElt=tmp;
146           whichEntity=entities[i];
147           if(i>0)
148             std::cerr << "WARNING : MEDFile has been detected to be noncompliant with MED 3 : Please change entity in MEDFile for geotype " <<  geoElt << std::endl;
149         }
150     }
151   return nbOfElt>0;
152 }
153
154 int MEDFileUMeshPerType::getDim() const
155 {
156   return _m->getMeshDimension();
157 }
158
159 MEDFileUMeshPerType::MEDFileUMeshPerType()
160 {
161 }
162
163 MEDFileUMeshPerType::MEDFileUMeshPerType(med_idt fid, const char *mName, int dt, int it, int mdim, med_geometry_type geoElt, INTERP_KERNEL::NormalizedCellType type,
164                                          med_entity_type entity, MEDFileMeshReadSelector *mrs)
165 {
166   med_bool changement,transformation;
167   mcIdType curNbOfElem(MEDmeshnEntity(fid,mName,dt,it,entity,geoElt,MED_CONNECTIVITY,MED_NODAL,&changement,&transformation));
168   const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(type));
169   if(!cm.isDynamic())
170     {
171       loadFromStaticType(fid,mName,dt,it,mdim,curNbOfElem,geoElt,type,entity,mrs);
172       return;
173     }
174   if(type==INTERP_KERNEL::NORM_POLYGON || type==INTERP_KERNEL::NORM_QPOLYG)
175     {
176       loadPolyg(fid,mName,dt,it,mdim,curNbOfElem,geoElt,entity,mrs);
177       return;
178     }
179   //if(type==INTERP_KERNEL::NORM_POLYHED)
180   loadPolyh(fid,mName,dt,it,mdim,curNbOfElem,geoElt,entity,mrs);
181 }
182
183 void MEDFileUMeshPerType::loadPart(med_idt fid, const char *mName, int dt, int it, int mdim, med_geometry_type geoElt, INTERP_KERNEL::NormalizedCellType type,
184                                    med_entity_type entity, mcIdType strt, mcIdType end, mcIdType step, MEDFileMeshReadSelector *mrs)
185 {
186   med_bool changement,transformation;
187   mcIdType curNbOfElem(MEDmeshnEntity(fid,mName,dt,it,entity,geoElt,MED_CONNECTIVITY,MED_NODAL,&changement,&transformation));
188   const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(type));
189   _pd=PartDefinition::New(strt,end,step);
190   if(!cm.isDynamic())
191     {
192       loadPartStaticType(fid,mName,dt,it,mdim,curNbOfElem,geoElt,type,entity,strt,end,step,mrs);
193     }
194   else
195     throw INTERP_KERNEL::Exception("MEDFileUMeshPerType::loadPart : not implemented yet for the dynamic type !");
196 }
197
198 void MEDFileUMeshPerType::loadFromStaticType(med_idt fid, const char *mName, int dt, int it, int mdim, mcIdType curNbOfElem, med_geometry_type geoElt, INTERP_KERNEL::NormalizedCellType type,
199                                              med_entity_type entity, MEDFileMeshReadSelector *mrs)
200 {
201   _m=MEDCoupling1SGTUMesh::New(mName,type);
202   MEDCoupling1SGTUMesh *mc(dynamic_cast<MEDCoupling1SGTUMesh *>((MEDCoupling1GTUMesh *)_m));
203   MCAuto<DataArrayMedInt> conn(DataArrayMedInt::New());
204   mcIdType nbOfNodesPerCell(mc->getNumberOfNodesPerCell());
205   conn->alloc(nbOfNodesPerCell*curNbOfElem,1);
206   MEDFILESAFECALLERRD0(MEDmeshElementConnectivityRd,(fid,mName,dt,it,entity,geoElt,MED_NODAL,MED_FULL_INTERLACE,conn->getPointer()));
207   std::transform(conn->begin(),conn->end(),conn->getPointer(),std::bind(std::plus<med_int>(),std::placeholders::_1,-1));
208   mc->setNodalConnectivity(FromMedIntArray<mcIdType>(conn));
209   loadCommonPart(fid,mName,dt,it,curNbOfElem,geoElt,entity,mrs);
210 }
211
212 void MEDFileUMeshPerType::loadPartStaticType(med_idt fid, const char *mName, int dt, int it, int mdim, mcIdType curNbOfElem, med_geometry_type geoElt, INTERP_KERNEL::NormalizedCellType type,
213                                              med_entity_type entity, mcIdType strt, mcIdType end, mcIdType step, MEDFileMeshReadSelector *mrs)
214 {
215   if(strt<0)
216     throw INTERP_KERNEL::Exception("MEDFileUMeshPerType::loadPartStaticType : start pos is negative !");
217   if(end>curNbOfElem)
218     throw INTERP_KERNEL::Exception("MEDFileUMeshPerType::loadPartStaticType : end is after the authorized range !");
219   mcIdType nbOfEltsToLoad(DataArray::GetNumberOfItemGivenBES(strt,end,step,"MEDFileUMeshPerType::loadPartStaticType"));
220   _m=MEDCoupling1SGTUMesh::New(mName,type);
221   MEDCoupling1SGTUMesh *mc(dynamic_cast<MEDCoupling1SGTUMesh *>((MEDCoupling1GTUMesh *)_m));
222   MCAuto<DataArrayMedInt> conn(DataArrayMedInt::New());
223   mcIdType nbOfNodesPerCell(mc->getNumberOfNodesPerCell());
224   conn->alloc(nbOfNodesPerCell*nbOfEltsToLoad,1);
225   med_filter filter=MED_FILTER_INIT;
226   MEDfilterBlockOfEntityCr(fid,/*nentity*/ToMedInt(curNbOfElem),/*nvaluesperentity*/1,/*nconstituentpervalue*/ToMedInt(nbOfNodesPerCell),
227                            MED_ALL_CONSTITUENT,MED_FULL_INTERLACE,MED_COMPACT_STMODE,MED_NO_PROFILE,
228                            /*start*/ToMedInt(strt+1),/*stride*/ToMedInt(step),/*count*/1,/*blocksize*/ToMedInt(nbOfEltsToLoad),
229                            /*lastblocksize=useless because count=1*/0,&filter);
230   MEDFILESAFECALLERRD0(MEDmeshElementConnectivityAdvancedRd,(fid,mName,dt,it,entity,geoElt,MED_NODAL,&filter,conn->getPointer()));
231   MEDfilterClose(&filter);
232   std::transform(conn->begin(),conn->end(),conn->getPointer(),std::bind(std::plus<med_int>(),std::placeholders::_1,-1));
233   mc->setNodalConnectivity(FromMedIntArray<mcIdType>(conn));
234   loadPartOfCellCommonPart(fid,mName,strt,end,step,dt,it,mdim,curNbOfElem,geoElt,entity,mrs);
235 }
236
237 void MEDFileUMeshPerType::loadPartOfCellCommonPart(med_idt fid, const char *mName, mcIdType strt, mcIdType stp, mcIdType step, int dt, int it, int mdim, mcIdType curNbOfElem, med_geometry_type geoElt, med_entity_type entity, MEDFileMeshReadSelector *mrs)
238 {
239   med_bool changement,transformation;
240   _fam=0;
241   mcIdType nbOfEltsToLoad(DataArray::GetNumberOfItemGivenBES(strt,stp,step,"MEDFileUMeshPerType::loadPartOfCellCommonPart"));
242   if(MEDmeshnEntity(fid,mName,dt,it,entity,geoElt,MED_FAMILY_NUMBER,MED_NODAL,&changement,&transformation)>0)
243     {
244       if(!mrs || mrs->isCellFamilyFieldReading())
245         {
246           MCAuto<DataArrayMedInt> miFam(DataArrayMedInt::New());
247           miFam->alloc(nbOfEltsToLoad,1);
248           med_filter filter=MED_FILTER_INIT;
249           MEDfilterBlockOfEntityCr(fid,/*nentity*/ToMedInt(curNbOfElem),/*nvaluesperentity*/1,/*nconstituentpervalue*/1,
250                                    MED_ALL_CONSTITUENT,MED_FULL_INTERLACE,MED_COMPACT_STMODE,MED_NO_PROFILE,
251                                    /*start*/ToMedInt(strt+1),/*stride*/ToMedInt(step),/*count*/1,/*blocksize*/ToMedInt(nbOfEltsToLoad),
252                                    /*lastblocksize=useless because count=1*/0,&filter);
253           if(MEDmeshEntityAttributeAdvancedRd(fid,mName,MED_FAMILY_NUMBER,dt,it,entity,geoElt,&filter,miFam->getPointer())!=0)
254             miFam->fillWithZero();
255           _fam=FromMedIntArray<mcIdType>(miFam);
256           MEDfilterClose(&filter);
257         }
258     }
259   _num=0;
260   if(MEDmeshnEntity(fid,mName,dt,it,entity,geoElt,MED_NUMBER,MED_NODAL,&changement,&transformation)>0)
261     {
262       if(!mrs || mrs->isCellNumFieldReading())
263         {
264           MCAuto<DataArrayMedInt> miNum(DataArrayMedInt::New());
265           miNum->alloc(nbOfEltsToLoad,1);
266           med_filter filter=MED_FILTER_INIT;
267           MEDfilterBlockOfEntityCr(fid,/*nentity*/ToMedInt(curNbOfElem),/*nvaluesperentity*/1,/*nconstituentpervalue*/1,
268                                    MED_ALL_CONSTITUENT,MED_FULL_INTERLACE,MED_COMPACT_STMODE,MED_NO_PROFILE,
269                                    /*start*/ToMedInt(strt+1),/*stride*/ToMedInt(step),/*count*/1,/*blocksize*/ToMedInt(nbOfEltsToLoad),
270                                    /*lastblocksize=useless because count=1*/0,&filter);
271           if(MEDmeshEntityAttributeAdvancedRd(fid,mName,MED_NUMBER,dt,it,entity,geoElt,&filter,miNum->getPointer())!=0)
272             miNum->fillWithZero();
273           _num=FromMedIntArray<mcIdType>(miNum);
274           MEDfilterClose(&filter);
275         }
276     }
277   _names=0;
278   if(MEDmeshnEntity(fid,mName,dt,it,entity,geoElt,MED_NAME,MED_NODAL,&changement,&transformation)>0)
279     {
280       if(!mrs || mrs->isCellNameFieldReading())
281         {
282           _names=DataArrayAsciiChar::New();
283           _names->alloc(nbOfEltsToLoad+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
284           med_filter filter=MED_FILTER_INIT;
285           MEDfilterBlockOfEntityCr(fid,/*nentity*/ToMedInt(curNbOfElem),/*nvaluesperentity*/1,/*nconstituentpervalue*/1,
286                                    MED_ALL_CONSTITUENT,MED_FULL_INTERLACE,MED_COMPACT_STMODE,MED_NO_PROFILE,
287                                    /*start*/ToMedInt(strt+1),/*stride*/ToMedInt(step),/*count*/1,/*blocksize*/ToMedInt(nbOfEltsToLoad),
288                                    /*lastblocksize=useless because count=1*/0,&filter);
289           if(MEDmeshEntityAttributeAdvancedRd(fid,mName,MED_NAME,dt,it,entity,geoElt,&filter,_names->getPointer())!=0)
290             _names=0;
291           else
292             _names->reAlloc(nbOfEltsToLoad);//not a bug to avoid the memory corruption due to last \0 at the end
293           MEDfilterClose(&filter);
294         }
295     }
296 }
297
298 void MEDFileUMeshPerType::loadPolyg(med_idt fid, const char *mName, int dt, int it, int mdim, mcIdType arraySize, med_geometry_type geoElt,
299                                     med_entity_type entity, MEDFileMeshReadSelector *mrs)
300 {
301   med_bool changement,transformation;
302   mcIdType curNbOfElem(MEDmeshnEntity(fid,mName,dt,it,entity,geoElt,MED_INDEX_NODE,MED_NODAL,&changement,&transformation)-1);
303   _m=MEDCoupling1DGTUMesh::New(mName,geoElt==MED_POLYGON?INTERP_KERNEL::NORM_POLYGON:INTERP_KERNEL::NORM_QPOLYG);
304   MCAuto<MEDCoupling1DGTUMesh> mc(DynamicCast<MEDCoupling1GTUMesh,MEDCoupling1DGTUMesh>(_m));
305   MCAuto<DataArrayMedInt> conn(DataArrayMedInt::New()),connI(DataArrayMedInt::New());
306   conn->alloc(arraySize,1); connI->alloc(curNbOfElem+1,1);
307   MEDFILESAFECALLERRD0(MEDmeshPolygon2Rd,(fid,mName,dt,it,MED_CELL,geoElt,MED_NODAL,connI->getPointer(),conn->getPointer()));
308   std::transform(conn->begin(),conn->end(),conn->getPointer(),std::bind(std::plus<med_int>(),std::placeholders::_1,-1));
309   std::transform(connI->begin(),connI->end(),connI->getPointer(),std::bind(std::plus<med_int>(),std::placeholders::_1,-1));
310   mc->setNodalConnectivity(FromMedIntArray<mcIdType>(conn),FromMedIntArray<mcIdType>(connI));
311   loadCommonPart(fid,mName,dt,it,curNbOfElem,geoElt,entity,mrs);
312 }
313
314 void MEDFileUMeshPerType::loadPolyh(med_idt fid, const char *mName, int dt, int it, int mdim, mcIdType connFaceLgth, med_geometry_type geoElt,
315                                     med_entity_type entity, MEDFileMeshReadSelector *mrs)
316 {
317   med_bool changement,transformation;
318   med_int indexFaceLgth(MEDmeshnEntity(fid,mName,dt,it,MED_CELL,MED_POLYHEDRON,MED_INDEX_NODE,MED_NODAL,&changement,&transformation));
319   mcIdType curNbOfElem(MEDmeshnEntity(fid,mName,dt,it,MED_CELL,MED_POLYHEDRON,MED_INDEX_FACE,MED_NODAL,&changement,&transformation)-1);
320   _m=MEDCoupling1DGTUMesh::New(mName,INTERP_KERNEL::NORM_POLYHED);
321   MCAuto<MEDCoupling1DGTUMesh> mc(DynamicCastSafe<MEDCoupling1GTUMesh,MEDCoupling1DGTUMesh>(_m));
322   INTERP_KERNEL::AutoPtr<med_int> index=new med_int[curNbOfElem+1];
323   INTERP_KERNEL::AutoPtr<med_int> indexFace=new med_int[indexFaceLgth];
324   INTERP_KERNEL::AutoPtr<med_int> locConn=new med_int[connFaceLgth];
325   MEDFILESAFECALLERRD0(MEDmeshPolyhedronRd,(fid,mName,dt,it,MED_CELL,MED_NODAL,index,indexFace,locConn));
326   MCAuto<DataArrayIdType> conn(DataArrayIdType::New()),connI(DataArrayIdType::New());
327   mcIdType arraySize=connFaceLgth;
328   for(mcIdType i=0;i<curNbOfElem;i++)
329     arraySize+=index[i+1]-index[i]-1;
330   conn=DataArrayIdType::New();
331   conn->alloc(arraySize,1);
332   mcIdType *wFinalConn=conn->getPointer();
333   connI->alloc(curNbOfElem+1,1);
334   mcIdType *finalIndex(connI->getPointer());
335   finalIndex[0]=0;
336   for(mcIdType i=0;i<curNbOfElem;i++)
337     {
338       finalIndex[i+1]=finalIndex[i]+index[i+1]-index[i]-1+indexFace[index[i+1]-1]-indexFace[index[i]-1];
339       wFinalConn=std::transform(locConn+indexFace[index[i]-1]-1,locConn+indexFace[index[i]]-1,wFinalConn,std::bind(std::plus<mcIdType>(),std::placeholders::_1,-1));
340       for(mcIdType j=index[i];j<index[i+1]-1;j++)
341         {
342           *wFinalConn++=-1;
343           wFinalConn=std::transform(locConn+indexFace[j]-1,locConn+indexFace[j+1]-1,wFinalConn,std::bind(std::plus<mcIdType>(),std::placeholders::_1,-1));
344         }
345     }
346   mc->setNodalConnectivity(conn,connI);
347   loadCommonPart(fid,mName,dt,it,curNbOfElem,MED_POLYHEDRON,entity,mrs);
348 }
349
350 void MEDFileUMeshPerType::Write(med_idt fid, const std::string& mname, int mdim, const MEDCoupling1GTUMesh *m, const DataArrayIdType *fam, const DataArrayIdType *num, const DataArrayAsciiChar *names)
351 {
352   mcIdType nbOfCells=m->getNumberOfCells();
353   if(nbOfCells<1)
354     return ;
355   int dt,it;
356   double timm=m->getTime(dt,it);
357   INTERP_KERNEL::NormalizedCellType ikt=m->getTypeOfCell(0);
358   const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(ikt);
359   med_geometry_type curMedType=typmai3[(int)ikt];
360   if(!cm.isDynamic())
361     {
362       const MEDCoupling1SGTUMesh *m0(dynamic_cast<const MEDCoupling1SGTUMesh *>(m));
363       if(!m0)
364         throw INTERP_KERNEL::Exception("MEDFileUMeshPerType::Write : internal error #1 !");
365       MCAuto<DataArrayMedInt> arr(DataArrayMedInt_Copy(m0->getNodalConnectivity()));
366       std::transform(arr->begin(),arr->end(),arr->getPointer(),std::bind(std::plus<med_int>(),std::placeholders::_1,1));
367       MEDFILESAFECALLERWR0(MEDmeshElementConnectivityWr,(fid,mname.c_str(),dt,it,timm,MED_CELL,curMedType,MED_NODAL,MED_FULL_INTERLACE,ToMedInt(nbOfCells),arr->begin()));
368     }
369   else
370     {
371       const MEDCoupling1DGTUMesh *m0(dynamic_cast<const MEDCoupling1DGTUMesh *>(m));
372       if(!m0)
373         throw INTERP_KERNEL::Exception("MEDFileUMeshPerType::Write : internal error #2 !");
374       if(ikt==INTERP_KERNEL::NORM_POLYGON || ikt==INTERP_KERNEL::NORM_QPOLYG)
375         {
376           MCAuto<DataArrayMedInt> arr(DataArrayMedInt_Copy(m0->getNodalConnectivity())),arrI(DataArrayMedInt_Copy(m0->getNodalConnectivityIndex()));
377           std::transform(arr->begin(),arr->end(),arr->getPointer(),std::bind(std::plus<med_int>(),std::placeholders::_1,1));
378           std::transform(arrI->begin(),arrI->end(),arrI->getPointer(),std::bind(std::plus<med_int>(),std::placeholders::_1,1));
379           MEDFILESAFECALLERWR0(MEDmeshPolygon2Wr,(fid,mname.c_str(),dt,it,timm,MED_CELL,ikt==INTERP_KERNEL::NORM_POLYGON?MED_POLYGON:MED_POLYGON2,MED_NODAL,ToMedInt(nbOfCells+1),arrI->begin(),arr->begin()));
380         }
381       else
382         {
383           const mcIdType *conn(m0->getNodalConnectivity()->begin()),*connI(m0->getNodalConnectivityIndex()->begin());
384           mcIdType meshLgth=m0->getNodalConnectivityLength();
385           mcIdType nbOfFaces=ToIdType(std::count(conn,conn+meshLgth,-1)+nbOfCells);
386           INTERP_KERNEL::AutoPtr<med_int> tab1=new med_int[nbOfCells+1];
387           med_int *w1=tab1; *w1=1;
388           INTERP_KERNEL::AutoPtr<med_int> tab2=new med_int[nbOfFaces+1];
389           med_int *w2=tab2; *w2=1;
390           INTERP_KERNEL::AutoPtr<med_int> bigtab=new med_int[meshLgth];
391           med_int *bt=bigtab;
392           for(mcIdType i=0;i<nbOfCells;i++,w1++)
393             {
394               int nbOfFaces2=0;
395               for(const mcIdType *w=conn+connI[i];w!=conn+connI[i+1];w2++)
396                 {
397                   const mcIdType *wend=std::find(w,conn+connI[i+1],-1);
398                   bt=std::transform(w,wend,bt,std::bind(std::plus<mcIdType>(),std::placeholders::_1,1));
399                   std::size_t nbOfNode=std::distance(w,wend);
400                   w2[1]=w2[0]+(med_int)nbOfNode;
401                   if(wend!=conn+connI[i+1])
402                     w=wend+1;
403                   else
404                     w=wend;
405                   nbOfFaces2++;
406                 }
407               w1[1]=w1[0]+nbOfFaces2;
408             }
409           MEDFILESAFECALLERWR0(MEDmeshPolyhedronWr,(fid,mname.c_str(),dt,it,timm,MED_CELL,MED_NODAL,ToMedInt(nbOfCells+1),tab1,ToMedInt(nbOfFaces+1),tab2,bigtab));
410         }
411     }
412   if(fam)
413     MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,mname.c_str(),dt,it,MED_CELL,curMedType,ToMedInt(nbOfCells),ToMedIntArray<mcIdType>(fam)->getConstPointer()));
414   if(num)
415     MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,mname.c_str(),dt,it,MED_CELL,curMedType,ToMedInt(nbOfCells),ToMedIntArray<mcIdType>(num)->getConstPointer()));
416   if(names)
417     {
418       if(names->getNumberOfComponents()!=MED_SNAME_SIZE)
419         {
420           std::ostringstream oss; oss << "MEDFileUMeshPerType::write : expected a name field on cells with number of components set to " << MED_SNAME_SIZE;
421           oss << " ! The array has " << names->getNumberOfComponents() << " components !";
422           throw INTERP_KERNEL::Exception(oss.str().c_str());
423         }
424       MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,mname.c_str(),dt,it,MED_CELL,curMedType,ToMedInt(nbOfCells),names->getConstPointer()));
425     }
426 }