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