Salome HOME
d525358af19cf248506f3df94ee7f70a2effead2
[tools/medcoupling.git] / src / MEDLoader / MEDFileMeshLL.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 "MEDFileMeshLL.hxx"
22 #include "MEDFileMesh.hxx"
23 #include "MEDLoaderBase.hxx"
24 #include "MEDFileSafeCaller.txx"
25 #include "MEDFileMeshReadSelector.hxx"
26
27 #include "MEDCouplingUMesh.hxx"
28
29 #include "InterpKernelAutoPtr.hxx"
30 #include "CellModel.hxx"
31
32 #include <set>
33 #include <iomanip>
34
35 extern med_geometry_type typmai[MED_N_CELL_FIXED_GEO];
36 extern INTERP_KERNEL::NormalizedCellType typmai2[MED_N_CELL_FIXED_GEO];
37 extern med_geometry_type typmainoeud[1];
38
39 using namespace MEDCoupling;
40
41 const char MEDFileMeshL2::ZE_SEP_FOR_FAMILY_KILLERS[]="!/__\\!";//important start by - because ord('!')==33 the smallest (!=' ') to preserve orders at most.
42
43 int MEDFileMeshL2::ZE_SEP2_FOR_FAMILY_KILLERS=4;
44
45 std::vector<std::string> MeshCls::getAxisInfoOnMesh(med_idt fid, const std::string& mName, MEDCoupling::MEDCouplingMeshType& meshType, MEDCoupling::MEDCouplingAxisType& axType, int& nstep, int& Mdim, MEDFileString& description, MEDFileString& dtunit, MEDFileString& univName) const
46 {
47   med_mesh_type type_maillage;
48   med_int spaceDim;
49   med_sorting_type stype;
50   med_axis_type axistype;
51   int naxis(MEDmeshnAxis(fid,getID()));
52   INTERP_KERNEL::AutoPtr<char> nameTmp(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE));
53   INTERP_KERNEL::AutoPtr<char> axisname(MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE));
54   INTERP_KERNEL::AutoPtr<char> axisunit(MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE));
55   INTERP_KERNEL::AutoPtr<char> univTmp(MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE));
56   if(MEDmeshInfo(fid,getID(),nameTmp,&spaceDim,&Mdim,&type_maillage,description.getPointer(),dtunit.getPointer(),
57       &stype,&nstep,&axistype,axisname,axisunit)!=0)
58     throw INTERP_KERNEL::Exception("A problem has been detected when trying to get info on mesh !");
59   MEDmeshUniversalNameRd(fid,nameTmp,univName.getPointer());// do not protect  MEDFILESAFECALLERRD0 call : Thanks to fra.med.
60   axType=MEDFileMeshL2::TraduceAxisType(axistype);
61   switch(type_maillage)
62   {
63     case MED_UNSTRUCTURED_MESH:
64       meshType=UNSTRUCTURED;
65       break;
66     case MED_STRUCTURED_MESH:
67       {
68         med_grid_type gt;
69         MEDFILESAFECALLERRD0(MEDmeshGridTypeRd,(fid,mName.c_str(),&gt));
70         switch(gt)
71         {
72           case MED_CARTESIAN_GRID:
73             meshType=CARTESIAN;
74             break;
75           case MED_CURVILINEAR_GRID:
76             meshType=CURVE_LINEAR;
77             break;
78         case MED_POLAR_GRID:// this is not a bug. A MED file POLAR_GRID is deal by CARTESIAN MEDLoader
79             meshType=CARTESIAN;
80             break;
81           default:
82             throw INTERP_KERNEL::Exception("MEDFileMeshL2::getAxisInfoOnMesh : unrecognized structured mesh type ! Supported are :\n - cartesian\n - curve linear\n");
83         }
84         break;
85       }
86     default:
87       throw INTERP_KERNEL::Exception("MEDFileMeshL2::getMeshIdFromName : unrecognized mesh type !");
88   }
89   //
90   std::vector<std::string> infosOnComp(naxis);
91   for(int i=0;i<naxis;i++)
92     {
93       std::string info(MEDLoaderBase::buildUnionUnit(((char *)axisname)+i*MED_SNAME_SIZE,MED_SNAME_SIZE,((char *)axisunit)+i*MED_SNAME_SIZE,MED_SNAME_SIZE));
94       infosOnComp[i]=info;
95     }
96   return infosOnComp;
97 }
98
99 double MeshCls::checkMeshTimeStep(med_idt fid, const std::string& mName, int nstep, int dt, int it) const
100 {
101   bool found=false;
102   med_int numdt,numit;
103   med_float dtt;
104   std::vector< std::pair<int,int> > p(nstep);
105   for(int i=0;i<nstep;i++)
106     {
107       MEDFILESAFECALLERRD0(MEDmeshComputationStepInfo,(fid,mName.c_str(),i+1,&numdt,&numit,&dtt));
108       p[i]=std::make_pair((int)numdt,(int)numit);
109       found=(numdt==dt) && (numit==it);
110       if (found) break;
111     }
112   if(!found)
113     {
114       std::ostringstream oss; oss << "No such iteration=" << dt << ",order=" << it << " numbers found for mesh '" << mName << "' ! ";
115       oss << "Possibilities are : ";
116       for(int i=0;i<nstep;i++)
117         oss << "(" << p[i].first << "," << p[i].second << "), ";
118       throw INTERP_KERNEL::Exception(oss.str().c_str());
119     }
120   return dtt;
121 }
122
123 std::vector<std::string> StructMeshCls::getAxisInfoOnMesh(med_idt fid, const std::string& mName, MEDCoupling::MEDCouplingMeshType& meshType, MEDCoupling::MEDCouplingAxisType& axType, int& nstep, int& Mdim, MEDFileString& description, MEDFileString& dtunit, MEDFileString& univName) const
124 {
125   INTERP_KERNEL::AutoPtr<char> msn(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE));
126   INTERP_KERNEL::AutoPtr<char> zeDescription(MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE));
127   med_axis_type medAxType;
128   int nAxis(MEDsupportMeshnAxis(fid,getID()));
129   INTERP_KERNEL::AutoPtr<char> axisName(new char[MED_SNAME_SIZE*nAxis+1]),axisUnit(new char[MED_SNAME_SIZE*nAxis+1]);
130   int spaceDim(0),meshDim(0);
131   MEDFILESAFECALLERRD0(MEDsupportMeshInfo,(fid,getID(),msn,&spaceDim,&meshDim,zeDescription,&medAxType,axisName,axisUnit));
132   std::string descriptionCpp(MEDLoaderBase::buildStringFromFortran(zeDescription,MED_COMMENT_SIZE));
133   description.set(descriptionCpp.c_str());
134   dtunit.clear(); univName.clear(); meshType=UNSTRUCTURED; nstep=1;
135   axType=MEDFileMeshL2::TraduceAxisType(medAxType);
136   //int nmodels(0);
137   //med_bool chgt=MED_FALSE,trsf=MED_FALSE;
138   //nmodels=MEDmeshnEntity(fid,_name.c_str(),MED_NO_DT,MED_NO_IT,MED_STRUCT_ELEMENT,MED_GEO_ALL,MED_CONNECTIVITY,MED_NODAL,&chgt,&trsf);
139   std::vector<std::string> ret;
140   for(int i=0;i<nAxis;i++)
141     {
142       std::string info(DataArray::BuildInfoFromVarAndUnit(MEDLoaderBase::buildStringFromFortran(axisName+i*MED_SNAME_SIZE,MED_SNAME_SIZE),
143                                                           MEDLoaderBase::buildStringFromFortran(axisUnit+i*MED_SNAME_SIZE,MED_SNAME_SIZE)));
144       ret.push_back(info);
145     }
146   return ret;
147 }
148
149 double StructMeshCls::checkMeshTimeStep(med_idt fid, const std::string& mName, int nstep, int dt, int it) const
150 {
151   return 0.;
152 }
153
154 MEDFileMeshL2::MEDFileMeshL2():_name(MED_NAME_SIZE),_description(MED_COMMENT_SIZE),_univ_name(MED_LNAME_SIZE),_dt_unit(MED_LNAME_SIZE)
155 {
156 }
157
158 std::size_t MEDFileMeshL2::getHeapMemorySizeWithoutChildren() const
159 {
160   return 0;
161 }
162
163 std::vector<const BigMemoryObject *> MEDFileMeshL2::getDirectChildrenWithNull() const
164 {
165   return std::vector<const BigMemoryObject *>();
166 }
167
168 INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> MEDFileMeshL2::GetMeshIdFromName(med_idt fid, const std::string& mName, MEDCoupling::MEDCouplingMeshType& meshType, MEDCoupling::MEDCouplingAxisType& axType, int& dt, int& it, std::string& dtunit1)
169 {
170   med_mesh_type type_maillage;
171   char maillage_description[MED_COMMENT_SIZE+1];
172   char dtunit[MED_LNAME_SIZE+1];
173   med_int spaceDim,dim;
174   char nommaa[MED_NAME_SIZE+1];
175   med_int n=MEDnMesh(fid);
176   char found(0);
177   int ret=-1;
178   med_sorting_type stype;
179   std::vector<std::string> ms;
180   int nstep;
181   med_axis_type axistype;
182   for(int i=0;i<n && found==0;i++)
183     {
184       int naxis(MEDmeshnAxis(fid,i+1));
185       INTERP_KERNEL::AutoPtr<char> axisname(MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE)),axisunit(MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE));
186       MEDFILESAFECALLERRD0(MEDmeshInfo,(fid,i+1,nommaa,&spaceDim,&dim,&type_maillage,maillage_description,dtunit,&stype,&nstep,&axistype,axisname,axisunit));      
187       dtunit1=MEDLoaderBase::buildStringFromFortran(dtunit,sizeof(dtunit));
188       std::string cur(MEDLoaderBase::buildStringFromFortran(nommaa,sizeof(nommaa)));
189       ms.push_back(cur);
190       if(cur==mName)
191         {
192           found=1;
193           ret=i+1;
194         }
195     }
196   if(found==0)
197     {//last chance ! Is it a support mesh ?
198       int nbSM(MEDnSupportMesh(fid));
199       for(int i=0;i<nbSM && found==0;i++)
200         {
201           int naxis(MEDsupportMeshnAxis(fid,i+1));
202           INTERP_KERNEL::AutoPtr<char> axisname(MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE)),axisunit(MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE));
203           MEDFILESAFECALLERRD0(MEDsupportMeshInfo,(fid,i+1,nommaa,&spaceDim,&dim,maillage_description,&axistype,axisname,axisunit));
204           std::string cur(MEDLoaderBase::buildStringFromFortran(nommaa,sizeof(nommaa)));
205           ms.push_back(cur);
206           if(cur==mName)
207             {
208               found=2;
209               ret=i+1;
210             }
211         }
212     }
213   ////////////////////////
214   switch(found)
215     {
216     case 1:
217       {
218         axType=TraduceAxisType(axistype);
219         switch(type_maillage)
220           {
221           case MED_UNSTRUCTURED_MESH:
222             meshType=UNSTRUCTURED;
223             break;
224           case MED_STRUCTURED_MESH:
225             {
226               med_grid_type gt;
227               MEDFILESAFECALLERRD0(MEDmeshGridTypeRd,(fid,mName.c_str(),&gt));
228               switch(gt)
229                 {
230                 case MED_CARTESIAN_GRID:
231                   meshType=CARTESIAN;
232                   break;
233                 case MED_CURVILINEAR_GRID:
234                   meshType=CURVE_LINEAR;
235                   break;
236                 case MED_POLAR_GRID:// this is not a bug. A MED file POLAR_GRID is deal by CARTESIAN MEDLoader
237                   meshType=CARTESIAN;
238                   break;
239                 default:
240                   throw INTERP_KERNEL::Exception("MEDFileMeshL2::getMeshIdFromName : unrecognized structured mesh type ! Supported are :\n - cartesian\n - curve linear\n");
241                 }
242               break;
243             }
244           default:
245             throw INTERP_KERNEL::Exception("MEDFileMeshL2::getMeshIdFromName : unrecognized mesh type !");
246           }
247         med_int numdt,numit;
248         med_float dtt;
249         MEDFILESAFECALLERRD0(MEDmeshComputationStepInfo,(fid,mName.c_str(),1,&numdt,&numit,&dtt));
250         dt=numdt; it=numit;
251         return new MeshCls(ret);
252       }
253     case 2:
254       {
255         meshType=UNSTRUCTURED;
256         dt=MED_NO_DT; it=MED_NO_IT; dtunit1.clear();
257         axType=axType=TraduceAxisType(axistype);
258         return new StructMeshCls(ret);
259       }
260     default:
261       {
262         std::ostringstream oss;
263         oss << "No such meshname (" << mName <<  ") in file ! Must be in : ";
264         std::copy(ms.begin(),ms.end(),std::ostream_iterator<std::string>(oss,", "));
265         throw INTERP_KERNEL::Exception(oss.str().c_str());
266       }
267     }
268   
269 }
270
271 /*!
272  * non static and non const method because _description, _dt_unit... are set in this method.
273  */
274 std::vector<std::string> MEDFileMeshL2::getAxisInfoOnMesh(med_idt fid, const MeshOrStructMeshCls *mId, const std::string& mName, MEDCoupling::MEDCouplingMeshType& meshType, MEDCoupling::MEDCouplingAxisType& axType, int& nstep, int& Mdim)
275 {
276   return mId->getAxisInfoOnMesh(fid,mName,meshType,axType,nstep,Mdim,_description,_dt_unit,_univ_name);
277 }
278
279 void MEDFileMeshL2::ReadFamiliesAndGrps(med_idt fid, const std::string& meshName, std::map<std::string,int>& fams, std::map<std::string, std::vector<std::string> >& grps, MEDFileMeshReadSelector *mrs)
280 {
281   if(mrs && !(mrs->isCellFamilyFieldReading() || mrs->isNodeFamilyFieldReading()))
282     return ;
283   char nomfam[MED_NAME_SIZE+1];
284   med_int numfam;
285   int nfam=MEDnFamily(fid,meshName.c_str());
286   std::vector< std::pair<std::string,std::pair<int,std::vector<std::string> > > > crudeFams(nfam);
287   for(int i=0;i<nfam;i++)
288     {
289       int ngro=MEDnFamilyGroup(fid,meshName.c_str(),i+1);
290       med_int natt=MEDnFamily23Attribute(fid,meshName.c_str(),i+1);
291       INTERP_KERNEL::AutoPtr<med_int> attide=new med_int[natt];
292       INTERP_KERNEL::AutoPtr<med_int> attval=new med_int[natt];
293       INTERP_KERNEL::AutoPtr<char> attdes=new char[MED_COMMENT_SIZE*natt+1];
294       INTERP_KERNEL::AutoPtr<char> gro=new char[MED_LNAME_SIZE*ngro+1];
295       MEDfamily23Info(fid,meshName.c_str(),i+1,nomfam,attide,attval,attdes,&numfam,gro);
296       std::string famName(MEDLoaderBase::buildStringFromFortran(nomfam,MED_NAME_SIZE));
297       std::vector<std::string> grps(ngro);
298       for(int j=0;j<ngro;j++)
299         grps[j]=MEDLoaderBase::buildStringFromFortran(gro+j*MED_LNAME_SIZE,MED_LNAME_SIZE);
300       crudeFams[i]=std::pair<std::string,std::pair<int,std::vector<std::string> > >(famName,std::pair<int,std::vector<std::string> >(numfam,grps));
301     }
302   RenameFamiliesFromFileToMemInternal(crudeFams);
303   for(std::vector< std::pair<std::string,std::pair<int,std::vector<std::string> > > >::const_iterator it0=crudeFams.begin();it0!=crudeFams.end();it0++)
304     {
305       fams[(*it0).first]=(*it0).second.first;
306       for(std::vector<std::string>::const_iterator it1=(*it0).second.second.begin();it1!=(*it0).second.second.end();it1++)
307         grps[*it1].push_back((*it0).first);
308     }
309 }
310
311 void MEDFileMeshL2::WriteFamiliesAndGrps(med_idt fid, const std::string& mname, const std::map<std::string,int>& fams, const std::map<std::string, std::vector<std::string> >& grps, int tooLongStrPol)
312 {
313   std::vector< std::pair<std::string,std::pair<int,std::vector<std::string> > > > crudeFams(fams.size());
314   std::size_t ii(0);
315   for(std::map<std::string,int>::const_iterator it=fams.begin();it!=fams.end();it++,ii++)
316     {
317       std::vector<std::string> grpsOfFam;
318       for(std::map<std::string, std::vector<std::string> >::const_iterator it1=grps.begin();it1!=grps.end();it1++)
319         {
320           if(std::find((*it1).second.begin(),(*it1).second.end(),(*it).first)!=(*it1).second.end())
321             grpsOfFam.push_back((*it1).first);
322         }
323       crudeFams[ii]=std::pair<std::string,std::pair<int,std::vector<std::string> > >((*it).first,std::pair<int,std::vector<std::string> >((*it).second,grpsOfFam));
324     }
325   RenameFamiliesFromMemToFileInternal(crudeFams);
326   for(std::vector< std::pair<std::string,std::pair<int,std::vector<std::string> > > >::const_iterator it=crudeFams.begin();it!=crudeFams.end();it++)
327     {
328       int ngro((*it).second.second.size());
329       INTERP_KERNEL::AutoPtr<char> groName=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE*ngro);
330       int i=0;
331       for(std::vector<std::string>::const_iterator it2=(*it).second.second.begin();it2!=(*it).second.second.end();it2++,i++)
332         MEDLoaderBase::safeStrCpy2((*it2).c_str(),MED_LNAME_SIZE-1,groName+i*MED_LNAME_SIZE,tooLongStrPol);
333       INTERP_KERNEL::AutoPtr<char> famName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
334       MEDLoaderBase::safeStrCpy((*it).first.c_str(),MED_NAME_SIZE,famName,tooLongStrPol);
335       int ret=MEDfamilyCr(fid,mname.c_str(),famName,(*it).second.first,ngro,groName);
336       ret++;
337     }
338 }
339
340 void MEDFileMeshL2::RenameFamiliesPatternInternal(std::vector< std::pair<std::string,std::pair<int,std::vector<std::string> > > >& crudeFams, RenameFamiliesPatternFunc func)
341 {
342   std::size_t ii(0);
343   std::vector<std::string> fams(crudeFams.size());
344   for(std::vector< std::pair<std::string,std::pair<int,std::vector<std::string> > > >::const_iterator it=crudeFams.begin();it!=crudeFams.end();it++,ii++)
345     fams[ii]=(*it).first;
346   if(!func(fams))
347     return ;
348   ii=0;
349   for(std::vector< std::pair<std::string,std::pair<int,std::vector<std::string> > > >::iterator it=crudeFams.begin();it!=crudeFams.end();it++,ii++)
350     (*it).first=fams[ii];
351 }
352
353 /*!
354  * This method is dedicated to the killers that use a same family name to store different family ids. MED file API authorizes it.
355  * So this method renames families (if needed generaly not !) in order to have a discriminant name for families.
356  */
357 void MEDFileMeshL2::RenameFamiliesFromFileToMemInternal(std::vector< std::pair<std::string,std::pair<int,std::vector<std::string> > > >& crudeFams)
358 {
359   RenameFamiliesPatternInternal(crudeFams,RenameFamiliesFromFileToMem);
360 }
361
362 bool MEDFileMeshL2::RenameFamiliesFromFileToMem(std::vector< std::string >& famNames)
363 {
364   std::map<std::string,int> m;
365   std::set<std::string> s;
366   for(std::vector< std::string >::const_iterator it=famNames.begin();it!=famNames.end();it++)
367     {
368       if(s.find(*it)!=s.end())
369         m[*it]=0;
370       s.insert(*it);
371     }
372   if(m.empty())
373     return false;// the general case !
374   for(std::vector< std::string >::iterator it=famNames.begin();it!=famNames.end();it++)
375     {
376       std::map<std::string,int>::iterator it2(m.find(*it));
377       if(it2!=m.end())
378         {
379           std::ostringstream oss; oss << *it << ZE_SEP_FOR_FAMILY_KILLERS << std::setfill('0') << std::setw(ZE_SEP2_FOR_FAMILY_KILLERS) << (*it2).second++;
380           *it=oss.str();
381         }
382     }
383   return true;
384 }
385
386 /*!
387  * This method is dedicated to the killers that use a same family name to store different family ids. MED file API authorizes it.
388  * So this method renames families (if needed generaly not !) in order to have a discriminant name for families.
389  */
390 void MEDFileMeshL2::RenameFamiliesFromMemToFileInternal(std::vector< std::pair<std::string,std::pair<int,std::vector<std::string> > > >& crudeFams)
391 {
392   RenameFamiliesPatternInternal(crudeFams,RenameFamiliesFromMemToFile);
393 }
394
395 bool MEDFileMeshL2::RenameFamiliesFromMemToFile(std::vector< std::string >& famNames)
396 {
397   bool isSmthingStrange(false);
398   for(std::vector< std::string >::const_iterator it=famNames.begin();it!=famNames.end();it++)
399     {
400       std::size_t found((*it).find(ZE_SEP_FOR_FAMILY_KILLERS));
401       if(found!=std::string::npos)
402         isSmthingStrange=true;
403     }
404   if(!isSmthingStrange)
405     return false;
406   // pattern matching
407   std::map< std::string, std::vector<std::string> > m;
408   for(std::vector< std::string >::const_iterator it=famNames.begin();it!=famNames.end();it++)
409     {
410       std::size_t found((*it).find(ZE_SEP_FOR_FAMILY_KILLERS));
411       if(found!=std::string::npos && found>=1)
412         {
413           std::string s1((*it).substr(found+sizeof(ZE_SEP_FOR_FAMILY_KILLERS)-1));
414           if(s1.size()!=ZE_SEP2_FOR_FAMILY_KILLERS)
415             continue;
416           int k(-1);
417           std::istringstream iss(s1);
418           iss >> k;
419           bool isOK((iss.rdstate() & ( std::istream::failbit | std::istream::eofbit)) == std::istream::eofbit);
420           if(isOK && k>=0)
421             {
422               std::string s0((*it).substr(0,found));
423               m[s0].push_back(*it);
424             }
425         }
426     }
427   if(m.empty())
428     return false;
429   // filtering
430   std::map<std::string,std::string> zeMap;
431   for(std::map< std::string, std::vector<std::string> >::const_iterator it=m.begin();it!=m.end();it++)
432     {
433       if((*it).second.size()==1)
434         continue;
435       for(std::vector<std::string>::const_iterator it1=(*it).second.begin();it1!=(*it).second.end();it1++)
436         zeMap[*it1]=(*it).first;
437     }
438   if(zeMap.empty())
439     return false;
440   // traduce
441   for(std::vector< std::string >::iterator it=famNames.begin();it!=famNames.end();it++)
442     {
443       std::map<std::string,std::string>::iterator it1(zeMap.find(*it));
444       if(it1!=zeMap.end())
445         *it=(*it1).second;
446     }    
447   return true;
448 }
449
450 MEDCoupling::MEDCouplingAxisType MEDFileMeshL2::TraduceAxisType(med_axis_type at)
451 {
452   switch(at)
453     {
454     case MED_CARTESIAN:
455       return AX_CART;
456     case MED_CYLINDRICAL:
457       return AX_CYL;
458     case MED_SPHERICAL:
459       return AX_SPHER;
460     case MED_UNDEF_AXIS_TYPE:
461       return AX_CART;
462     default:
463       throw INTERP_KERNEL::Exception("MEDFileMeshL2::TraduceAxisType : unrecognized axis type !");
464     }
465 }
466
467 MEDCoupling::MEDCouplingAxisType MEDFileMeshL2::TraduceAxisTypeStruct(med_grid_type gt)
468 {
469   switch(gt)
470     {
471     case MED_CARTESIAN_GRID:
472       return AX_CART;
473     case MED_POLAR_GRID:
474       return AX_CYL;
475     default:
476       throw INTERP_KERNEL::Exception("MEDFileMeshL2::TraduceAxisTypeStruct : only Cartesian and Cylindrical supported by MED file !");
477     }
478 }
479
480 med_axis_type MEDFileMeshL2::TraduceAxisTypeRev(MEDCoupling::MEDCouplingAxisType at)
481 {
482   switch(at)
483     {
484     case AX_CART:
485       return MED_CARTESIAN;
486     case AX_CYL:
487       return MED_CYLINDRICAL;
488     case AX_SPHER:
489       return MED_SPHERICAL;
490     default:
491       throw INTERP_KERNEL::Exception("MEDFileMeshL2::TraduceAxisTypeRev : unrecognized axis type !");
492     }
493 }
494
495 med_grid_type MEDFileMeshL2::TraduceAxisTypeRevStruct(MEDCoupling::MEDCouplingAxisType at)
496 {
497   switch(at)
498     {
499     case AX_CART:
500       return MED_CARTESIAN_GRID;
501     case AX_CYL:
502       return MED_POLAR_GRID;
503     case AX_SPHER:
504       return MED_POLAR_GRID;
505     default:
506       throw INTERP_KERNEL::Exception("MEDFileMeshL2::TraduceAxisTypeRevStruct : unrecognized axis type !");
507     }
508 }
509
510 MEDFileUMeshL2::MEDFileUMeshL2()
511 {
512 }
513
514 std::vector<std::string> MEDFileUMeshL2::loadCommonPart(med_idt fid, const MeshOrStructMeshCls *mId, const std::string& mName, int dt, int it, int& Mdim)
515 {
516   Mdim=-3;
517   _name.set(mName.c_str());
518   int nstep;
519   MEDCoupling::MEDCouplingMeshType meshType;
520   MEDCoupling::MEDCouplingAxisType dummy3;
521   std::vector<std::string> ret(getAxisInfoOnMesh(fid,mId,mName.c_str(),meshType,dummy3,nstep,Mdim));
522   if(nstep==0)
523     {
524       Mdim=-4;
525       return std::vector<std::string>();
526     }
527   if(meshType!=UNSTRUCTURED)
528     throw INTERP_KERNEL::Exception("Invalid mesh type ! You are expected an unstructured one whereas in file it is not an unstructured !");
529   _time=mId->checkMeshTimeStep(fid,mName,nstep,dt,it);
530   _iteration=dt;
531   _order=it;
532   return ret;
533 }
534
535 void MEDFileUMeshL2::loadAll(med_idt fid, const MeshOrStructMeshCls *mId, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
536 {
537   int Mdim;
538   std::vector<std::string> infosOnComp(loadCommonPart(fid,mId,mName,dt,it,Mdim));
539   if(Mdim==-4)
540     return ;
541   loadConnectivity(fid,Mdim,mName,dt,it,mrs);//to improve check (dt,it) coherency
542   loadCoords(fid,infosOnComp,mName,dt,it);
543 }
544
545 void MEDFileUMeshL2::loadPart(med_idt fid, const MeshOrStructMeshCls *mId, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<int>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs)
546 {
547   int Mdim;
548   std::vector<std::string> infosOnComp(loadCommonPart(fid,mId,mName,dt,it,Mdim));
549   if(Mdim==-4)
550     return ;
551   loadPartOfConnectivity(fid,Mdim,mName,types,slicPerTyp,dt,it,mrs);
552   med_bool changement,transformation;
553   int nCoords(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_COORDINATE,MED_NO_CMODE,&changement,&transformation));
554   std::vector<bool> fetchedNodeIds(nCoords,false);
555   for(std::vector< std::vector< MCAuto<MEDFileUMeshPerType> > >::const_iterator it0=_per_type_mesh.begin();it0!=_per_type_mesh.end();it0++)
556     for(std::vector< MCAuto<MEDFileUMeshPerType> >::const_iterator it1=(*it0).begin();it1!=(*it0).end();it1++)
557       (*it1)->getMesh()->computeNodeIdsAlg(fetchedNodeIds);
558   int nMin(std::distance(fetchedNodeIds.begin(),std::find(fetchedNodeIds.begin(),fetchedNodeIds.end(),true)));
559   int nMax(std::distance(fetchedNodeIds.rbegin(),std::find(fetchedNodeIds.rbegin(),fetchedNodeIds.rend(),true)));
560   nMax=nCoords-nMax;
561   for(std::vector< std::vector< MCAuto<MEDFileUMeshPerType> > >::const_iterator it0=_per_type_mesh.begin();it0!=_per_type_mesh.end();it0++)
562     for(std::vector< MCAuto<MEDFileUMeshPerType> >::const_iterator it1=(*it0).begin();it1!=(*it0).end();it1++)
563       (*it1)->getMesh()->renumberNodesWithOffsetInConn(-nMin);
564   loadPartCoords(fid,infosOnComp,mName,dt,it,nMin,nMax);
565 }
566
567 void MEDFileUMeshL2::loadConnectivity(med_idt fid, int mdim, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
568 {
569   _per_type_mesh.resize(1);
570   _per_type_mesh[0].clear();
571   for(int j=0;j<MED_N_CELL_FIXED_GEO;j++)
572     {
573       MEDFileUMeshPerType *tmp(MEDFileUMeshPerType::New(fid,mName.c_str(),dt,it,mdim,typmai[j],typmai2[j],mrs));
574       if(tmp)
575         _per_type_mesh[0].push_back(tmp);
576     }
577   sortTypes();
578 }
579
580 void MEDFileUMeshL2::loadPartOfConnectivity(med_idt fid, int mdim, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<int>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs)
581 {
582   std::size_t nbOfTypes(types.size());
583   if(slicPerTyp.size()!=3*nbOfTypes)
584     throw INTERP_KERNEL::Exception("MEDFileUMeshL2::loadPartOfConnectivity : The size of slicPerTyp array is expected to be equal to 3 times size of array types !");
585   std::set<INTERP_KERNEL::NormalizedCellType> types2(types.begin(),types.end());
586   if(types2.size()!=nbOfTypes)
587     throw INTERP_KERNEL::Exception("MEDFileUMeshL2::loadPartOfConnectivity : the geometric types in types array must appear once !");
588   _per_type_mesh.resize(1);
589   _per_type_mesh[0].clear();
590   for(std::size_t ii=0;ii<nbOfTypes;ii++)
591     {
592       int strt(slicPerTyp[3*ii+0]),stp(slicPerTyp[3*ii+1]),step(slicPerTyp[3*ii+2]);
593       MCAuto<MEDFileUMeshPerType> tmp(MEDFileUMeshPerType::NewPart(fid,mName.c_str(),dt,it,mdim,types[ii],strt,stp,step,mrs));
594       _per_type_mesh[0].push_back(tmp);
595     }
596   sortTypes();
597 }
598
599 void MEDFileUMeshL2::loadCoords(med_idt fid, const std::vector<std::string>& infosOnComp, const std::string& mName, int dt, int it)
600 {
601   int spaceDim((int)infosOnComp.size());
602   med_bool changement,transformation;
603   int nCoords(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_COORDINATE,MED_NO_CMODE,&changement,&transformation));
604   _coords=DataArrayDouble::New();
605   _coords->alloc(nCoords,spaceDim);
606   double *coordsPtr(_coords->getPointer());
607   if (nCoords)
608     MEDFILESAFECALLERRD0(MEDmeshNodeCoordinateRd,(fid,mName.c_str(),dt,it,MED_FULL_INTERLACE,coordsPtr));
609   if(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,MED_FAMILY_NUMBER,MED_NODAL,&changement,&transformation)>0)
610     {
611       _fam_coords=DataArrayInt::New();
612       _fam_coords->alloc(nCoords,1);
613       MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,_fam_coords->getPointer()));
614     }
615   else
616     _fam_coords=0;
617   if(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,MED_NUMBER,MED_NODAL,&changement,&transformation)>0)
618     {
619       _num_coords=DataArrayInt::New();
620       _num_coords->alloc(nCoords,1);
621       MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,_num_coords->getPointer()));
622     }
623   else
624     _num_coords=0;
625   if(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,MED_NAME,MED_NODAL,&changement,&transformation)>0)
626     {
627       _name_coords=DataArrayAsciiChar::New();
628       _name_coords->alloc(nCoords+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
629       MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,_name_coords->getPointer()));
630       _name_coords->reAlloc(nCoords);//not a bug to avoid the memory corruption due to last \0 at the end
631     }
632   else
633     _name_coords=0;
634   for(int i=0;i<spaceDim;i++)
635     _coords->setInfoOnComponent(i,infosOnComp[i]);
636 }
637
638 void MEDFileUMeshL2::loadPartCoords(med_idt fid, const std::vector<std::string>& infosOnComp, const std::string& mName, int dt, int it, int nMin, int nMax)
639 {
640   med_bool changement,transformation;
641   int spaceDim((int)infosOnComp.size()),nCoords(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_COORDINATE,MED_NO_CMODE,&changement,&transformation));
642   _coords=DataArrayDouble::New();
643   int nbNodesToLoad(nMax-nMin);
644   _coords->alloc(nbNodesToLoad,spaceDim);
645   med_filter filter=MED_FILTER_INIT,filter2=MED_FILTER_INIT;
646   MEDfilterBlockOfEntityCr(fid,/*nentity*/nCoords,/*nvaluesperentity*/1,/*nconstituentpervalue*/spaceDim,
647                            MED_ALL_CONSTITUENT,MED_FULL_INTERLACE,MED_COMPACT_STMODE,MED_NO_PROFILE,
648                            /*start*/nMin+1,/*stride*/1,/*count*/1,/*blocksize*/nbNodesToLoad,
649                            /*lastblocksize=useless because count=1*/0,&filter);
650   MEDFILESAFECALLERRD0(MEDmeshNodeCoordinateAdvancedRd,(fid,mName.c_str(),dt,it,&filter,_coords->getPointer()));
651   _part_coords=PartDefinition::New(nMin,nMax,1);
652   MEDfilterClose(&filter);
653   MEDfilterBlockOfEntityCr(fid,nCoords,1,1,MED_ALL_CONSTITUENT,MED_FULL_INTERLACE,MED_COMPACT_STMODE,
654                            MED_NO_PROFILE,nMin+1,1,1,nbNodesToLoad,0,&filter2);
655   if(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,MED_FAMILY_NUMBER,MED_NODAL,&changement,&transformation)>0)
656     {
657       _fam_coords=DataArrayInt::New();
658       _fam_coords->alloc(nbNodesToLoad,1);
659       MEDFILESAFECALLERRD0(MEDmeshEntityAttributeAdvancedRd,(fid,mName.c_str(),MED_FAMILY_NUMBER,dt,it,MED_NODE,MED_NO_GEOTYPE,&filter2,_fam_coords->getPointer()));
660     }
661   else
662     _fam_coords=0;
663   if(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,MED_NUMBER,MED_NODAL,&changement,&transformation)>0)
664     {
665       _num_coords=DataArrayInt::New();
666       _num_coords->alloc(nbNodesToLoad,1);
667       MEDFILESAFECALLERRD0(MEDmeshEntityAttributeAdvancedRd,(fid,mName.c_str(),MED_NUMBER,dt,it,MED_NODE,MED_NO_GEOTYPE,&filter2,_num_coords->getPointer()));
668     }
669   else
670     _num_coords=0;
671   if(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,MED_NAME,MED_NODAL,&changement,&transformation)>0)
672     {
673       _name_coords=DataArrayAsciiChar::New();
674       _name_coords->alloc(nbNodesToLoad+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
675       MEDFILESAFECALLERRD0(MEDmeshEntityAttributeAdvancedRd,(fid,mName.c_str(),MED_NAME,dt,it,MED_NODE,MED_NO_GEOTYPE,&filter2,_name_coords->getPointer()));
676       _name_coords->reAlloc(nbNodesToLoad);//not a bug to avoid the memory corruption due to last \0 at the end
677     }
678   else
679     _name_coords=0;
680   MEDfilterClose(&filter2);
681   _coords->setInfoOnComponents(infosOnComp);
682 }
683
684 void MEDFileUMeshL2::sortTypes()
685 {
686   std::set<int> mdims;
687   std::vector< MCAuto<MEDFileUMeshPerType> > tmp(_per_type_mesh[0]);
688   _per_type_mesh.clear();
689   for(std::vector< MCAuto<MEDFileUMeshPerType> >::const_iterator it=tmp.begin();it!=tmp.end();it++)
690     mdims.insert((*it)->getDim());
691   if(mdims.empty())
692     return;
693   int mdim=*mdims.rbegin();
694   _per_type_mesh.resize(mdim+1);
695   for(int dim=mdim+1;dim!=0;dim--)
696     {
697       std::vector< MCAuto<MEDFileUMeshPerType> >& elt=_per_type_mesh[mdim+1-dim];
698       for(std::vector< MCAuto<MEDFileUMeshPerType> >::const_iterator it=tmp.begin();it!=tmp.end();it++)
699         if((*it)->getDim()==dim-1)
700           elt.push_back(*it);
701     }
702   // suppression of contiguous empty levels at the end of _per_type_mesh.
703   int nbOfUselessLev=0;
704   bool isFirst=true;
705   for(std::vector< std::vector< MCAuto<MEDFileUMeshPerType> > >::reverse_iterator it2=_per_type_mesh.rbegin();it2!=_per_type_mesh.rend();it2++)
706     {
707       if((*it2).empty() && isFirst)
708         {
709           nbOfUselessLev++;
710         }
711       else
712         isFirst=false;
713     }
714   _per_type_mesh.resize(_per_type_mesh.size()-nbOfUselessLev);
715 }
716
717 void MEDFileUMeshL2::WriteCoords(med_idt fid, const std::string& mname, int dt, int it, double time, const DataArrayDouble *coords, const DataArrayInt *famCoords, const DataArrayInt *numCoords, const DataArrayAsciiChar *nameCoords)
718 {
719   if(!coords)
720     return ;
721   MEDFILESAFECALLERWR0(MEDmeshNodeCoordinateWr,(fid,mname.c_str(),dt,it,time,MED_FULL_INTERLACE,coords->getNumberOfTuples(),coords->getConstPointer()));
722   if(famCoords)
723     MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,mname.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,famCoords->getNumberOfTuples(),famCoords->getConstPointer()));
724   if(numCoords)
725     MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,mname.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,numCoords->getNumberOfTuples(),numCoords->getConstPointer()));
726   if(nameCoords)
727     {
728       if(nameCoords->getNumberOfComponents()!=MED_SNAME_SIZE)
729         {
730           std::ostringstream oss; oss << " MEDFileUMeshL2::WriteCoords : expected a name field on nodes with number of components set to " << MED_SNAME_SIZE;
731           oss << " ! The array has " << nameCoords->getNumberOfComponents() << " components !";
732           throw INTERP_KERNEL::Exception(oss.str().c_str());
733         }
734       MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,mname.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,nameCoords->getNumberOfTuples(),nameCoords->getConstPointer()));
735     }
736 }
737
738 bool MEDFileUMeshL2::isFamDefinedOnLev(int levId) const
739 {
740   for(std::vector< MCAuto<MEDFileUMeshPerType> >::const_iterator it=_per_type_mesh[levId].begin();it!=_per_type_mesh[levId].end();it++)
741     if((*it)->getFam()==0)
742       return false;
743   return true;
744 }
745
746 bool MEDFileUMeshL2::isNumDefinedOnLev(int levId) const
747 {
748   for(std::vector< MCAuto<MEDFileUMeshPerType> >::const_iterator it=_per_type_mesh[levId].begin();it!=_per_type_mesh[levId].end();it++)
749     if((*it)->getNum()==0)
750       return false;
751   return true;
752 }
753
754 bool MEDFileUMeshL2::isNamesDefinedOnLev(int levId) const
755 {
756   for(std::vector< MCAuto<MEDFileUMeshPerType> >::const_iterator it=_per_type_mesh[levId].begin();it!=_per_type_mesh[levId].end();it++)
757     if((*it)->getNames()==0)
758       return false;
759   return true;
760 }
761
762 MEDFileCMeshL2::MEDFileCMeshL2():_ax_type(AX_CART)
763 {
764 }
765
766 void MEDFileCMeshL2::loadAll(med_idt fid, const MeshOrStructMeshCls *mId, const std::string& mName, int dt, int it)
767 {
768   _name.set(mName.c_str());
769   int nstep;
770   int Mdim;
771   MEDCoupling::MEDCouplingMeshType meshType;
772   MEDCoupling::MEDCouplingAxisType dummy3;
773   std::vector<std::string> infosOnComp(getAxisInfoOnMesh(fid,mId,mName.c_str(),meshType,dummy3,nstep,Mdim));
774   if(meshType!=CARTESIAN)
775     throw INTERP_KERNEL::Exception("Invalid mesh type ! You are expected a structured one whereas in file it is not a structured !");
776   _time=mId->checkMeshTimeStep(fid,mName,nstep,dt,it);
777   _iteration=dt;
778   _order=it;
779   //
780   med_grid_type gridtype;
781   MEDFILESAFECALLERRD0(MEDmeshGridTypeRd,(fid,mName.c_str(),&gridtype));
782   if(gridtype!=MED_CARTESIAN_GRID && gridtype!=MED_POLAR_GRID)
783     throw INTERP_KERNEL::Exception("Invalid rectilinear mesh ! Only cartesian and polar are supported !");
784   _ax_type=TraduceAxisTypeStruct(gridtype);
785   _cmesh=MEDCouplingCMesh::New();
786   for(int i=0;i<Mdim;i++)
787     {
788       med_data_type dataTypeReq=GetDataTypeCorrespondingToSpaceId(i);
789       med_bool chgt=MED_FALSE,trsf=MED_FALSE;
790       int nbOfElt(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,dataTypeReq,MED_NO_CMODE,&chgt,&trsf));
791       MCAuto<DataArrayDouble> da=DataArrayDouble::New();
792       da->alloc(nbOfElt,1);
793       da->setInfoOnComponent(0,infosOnComp[i]);
794       MEDFILESAFECALLERRD0(MEDmeshGridIndexCoordinateRd,(fid,mName.c_str(),dt,it,i+1,da->getPointer()));
795       _cmesh->setCoordsAt(i,da);
796     }
797 }
798
799 med_data_type MEDFileCMeshL2::GetDataTypeCorrespondingToSpaceId(int id)
800 {
801   switch(id)
802   {
803     case 0:
804       return MED_COORDINATE_AXIS1;
805     case 1:
806       return MED_COORDINATE_AXIS2;
807     case 2:
808       return MED_COORDINATE_AXIS3;
809     default:
810       throw INTERP_KERNEL::Exception("Invalid meshdim detected in Cartesian Grid !");
811   }
812 }
813
814 MEDFileCLMeshL2::MEDFileCLMeshL2()
815 {
816 }
817
818 void MEDFileCLMeshL2::loadAll(med_idt fid, const MeshOrStructMeshCls *mId, const std::string& mName, int dt, int it)
819 {
820   _name.set(mName.c_str());
821   int nstep;
822   int Mdim;
823   MEDCoupling::MEDCouplingMeshType meshType;
824   MEDCoupling::MEDCouplingAxisType dummy3;
825   std::vector<std::string> infosOnComp(getAxisInfoOnMesh(fid,mId,mName,meshType,dummy3,nstep,Mdim));
826   if(meshType!=CURVE_LINEAR)
827     throw INTERP_KERNEL::Exception("Invalid mesh type ! You are expected a structured one whereas in file it is not a structured !");
828   _time=mId->checkMeshTimeStep(fid,mName,nstep,dt,it);
829   _iteration=dt;
830   _order=it;
831   //
832   _clmesh=MEDCouplingCurveLinearMesh::New();
833   INTERP_KERNEL::AutoPtr<int> stGrid=new int[Mdim];
834   MEDFILESAFECALLERRD0(MEDmeshGridStructRd,(fid,mName.c_str(),dt,it,stGrid));
835   _clmesh->setNodeGridStructure(stGrid,((int *)stGrid)+Mdim);
836   med_bool chgt=MED_FALSE,trsf=MED_FALSE;
837   int nbNodes(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_COORDINATE,MED_NO_CMODE,&chgt,&trsf));
838   MCAuto<DataArrayDouble> da=DataArrayDouble::New();
839   da->alloc(nbNodes,infosOnComp.size());
840   da->setInfoOnComponents(infosOnComp);
841   MEDFILESAFECALLERRD0(MEDmeshNodeCoordinateRd,(fid,mName.c_str(),dt,it,MED_FULL_INTERLACE,da->getPointer()));
842   _clmesh->setCoords(da);
843 }
844
845 MEDFileUMeshPermCompute::MEDFileUMeshPermCompute(const MEDFileUMeshSplitL1* st):_st(st),_mpt_time(0),_num_time(0)
846 {
847 }
848
849 /*!
850  * Warning it returns an instance to deallocate !!!!
851  */
852 MEDFileUMeshPermCompute::operator MEDCouplingUMesh *() const
853 {
854   _st->_num->updateTime();
855   if((MEDCouplingUMesh *)_m==0)
856     {
857       updateTime();
858       _m=static_cast<MEDCouplingUMesh *>(_st->_m_by_types.getUmesh()->deepCopy());
859       _m->renumberCells(_st->_num->getConstPointer(),true);
860       return _m.retn();
861     }
862   else
863     {
864       if(_mpt_time==_st->_m_by_types.getTimeOfThis() && _num_time==_st->_num->getTimeOfThis())
865         return _m.retn();
866       else
867         {
868           updateTime();
869           _m=static_cast<MEDCouplingUMesh *>(_st->_m_by_types.getUmesh()->deepCopy());
870           _m->renumberCells(_st->_num->getConstPointer(),true);
871           return _m.retn();
872         }
873     }
874 }
875
876 void MEDFileUMeshPermCompute::operator=(MEDCouplingUMesh *m)
877 {
878   _m=m;
879 }
880
881 void MEDFileUMeshPermCompute::updateTime() const
882 {
883   _mpt_time=_st->_m_by_types.getTimeOfThis();
884   _num_time=_st->_num->getTimeOfThis();
885 }
886
887 std::vector<const BigMemoryObject *> MEDFileUMeshPermCompute::getDirectChildrenWithNull() const
888 {
889   std::vector<const BigMemoryObject *> ret;
890   ret.push_back((const MEDCouplingUMesh *)_m);
891   return ret;
892 }
893
894 std::size_t MEDFileUMeshPermCompute::getHeapMemorySizeWithoutChildren() const
895 {
896   return sizeof(MEDFileUMeshPermCompute);
897 }
898
899 MEDFileUMeshSplitL1::MEDFileUMeshSplitL1(const MEDFileUMeshSplitL1& other):RefCountObject(other),_m_by_types(other._m_by_types),_fam(other._fam),_num(other._num),_names(other._names),_rev_num(other._rev_num),_m(this)
900 {
901 }
902
903 MEDFileUMeshSplitL1::MEDFileUMeshSplitL1(const MEDFileUMeshL2& l2, const std::string& mName, int id):_m(this)
904 {
905   const std::vector< MCAuto<MEDFileUMeshPerType> >& v=l2.getLev(id);
906   if(v.empty())
907     return;
908   int sz=v.size();
909   std::vector<const MEDCoupling1GTUMesh *> ms(sz);
910   std::vector<const DataArrayInt *> fams(sz),nums(sz);
911   std::vector<const DataArrayChar *> names(sz);
912   std::vector<const PartDefinition *> pds(sz);
913   for(int i=0;i<sz;i++)
914     {
915       MEDCoupling1GTUMesh *elt(v[i]->getMesh());
916       MCAuto<DataArrayDouble> tmp2=l2.getCoords();
917       elt->setCoords(tmp2);
918       ms[i]=elt;
919       pds[i]=v[i]->getPartDef();
920     }
921   _m_by_types.assignParts(ms);
922   _m_by_types.assignDefParts(pds);
923   if(l2.isFamDefinedOnLev(id))
924     {
925       for(int i=0;i<sz;i++)
926         fams[i]=v[i]->getFam();
927       if(sz!=1)
928         _fam=DataArrayInt::Aggregate(fams);
929       else
930         {
931           fams[0]->incrRef();
932           _fam=const_cast<DataArrayInt *>(fams[0]);
933         }
934     }
935   if(l2.isNumDefinedOnLev(id))
936     {
937       for(int i=0;i<sz;i++)
938         nums[i]=v[i]->getNum();
939       if(sz!=1)
940         _num=DataArrayInt::Aggregate(nums);
941       else
942         {
943           nums[0]->incrRef();
944           _num=const_cast<DataArrayInt *>(nums[0]);
945         }
946       computeRevNum();
947     }
948   if(l2.isNamesDefinedOnLev(id))
949     {
950       for(int i=0;i<sz;i++)
951         names[i]=v[i]->getNames();
952       _names=dynamic_cast<DataArrayAsciiChar *>(DataArrayChar::Aggregate(names));
953     }
954 }
955
956 MEDFileUMeshSplitL1::MEDFileUMeshSplitL1(MEDCoupling1GTUMesh *m):_m(this)
957 {
958   std::vector< const MEDCoupling1GTUMesh * > v(1);
959   v[0]=m;
960   assignParts(v);
961 }
962
963 MEDFileUMeshSplitL1::MEDFileUMeshSplitL1(MEDCouplingUMesh *m):_m(this)
964 {
965   assignMesh(m,true);
966 }
967
968 MEDFileUMeshSplitL1::MEDFileUMeshSplitL1(MEDCouplingUMesh *m, bool newOrOld):_m(this)
969 {
970   assignMesh(m,newOrOld);
971 }
972
973 void MEDFileUMeshSplitL1::setName(const std::string& name)
974 {
975   _m_by_types.setName(name);
976 }
977
978 std::size_t MEDFileUMeshSplitL1::getHeapMemorySizeWithoutChildren() const
979 {
980   return 0;
981 }
982
983 std::vector<const BigMemoryObject *> MEDFileUMeshSplitL1::getDirectChildrenWithNull() const
984 {
985   std::vector<const BigMemoryObject *> ret;
986   ret.push_back(&_m_by_types);
987   ret.push_back(&_m);
988   ret.push_back((const DataArrayInt*)_fam);
989   ret.push_back((const DataArrayInt*)_num);
990   ret.push_back((const DataArrayInt*)_rev_num);
991   ret.push_back((const DataArrayAsciiChar*)_names);
992   return ret;
993 }
994
995 MEDFileUMeshSplitL1 *MEDFileUMeshSplitL1::shallowCpyUsingCoords(DataArrayDouble *coords) const
996 {
997   MCAuto<MEDFileUMeshSplitL1> ret(new MEDFileUMeshSplitL1(*this));
998   ret->_m_by_types.shallowCpyMeshes();
999   ret->_m_by_types.setCoords(coords);
1000   return ret.retn();
1001 }
1002
1003 MEDFileUMeshSplitL1 *MEDFileUMeshSplitL1::deepCopy(DataArrayDouble *coords) const
1004 {
1005   MCAuto<MEDFileUMeshSplitL1> ret(new MEDFileUMeshSplitL1(*this));
1006   ret->_m_by_types=_m_by_types.deepCopy(coords);
1007   if((const DataArrayInt *)_fam)
1008     ret->_fam=_fam->deepCopy();
1009   if((const DataArrayInt *)_num)
1010     ret->_num=_num->deepCopy();
1011   if((const DataArrayInt *)_rev_num)
1012     ret->_rev_num=_rev_num->deepCopy();
1013   if((const DataArrayAsciiChar *)_names)
1014     ret->_names=_names->deepCopy();
1015   return ret.retn();
1016 }
1017
1018 void MEDFileUMeshSplitL1::checkConsistency() const
1019 {
1020   if (!_fam || _fam->getNumberOfTuples() != getSize())
1021     throw INTERP_KERNEL::Exception("MEDFileUMeshSplitL1::checkConsistency(): internal family array has an invalid size!");
1022   int nbCells = getSize();
1023   if (_num)
1024     {
1025       _num->checkNbOfTuplesAndComp(nbCells,1,"MEDFileUMeshSplitL1::checkConsistency(): inconsistent internal node numbering array!");
1026       int pos;
1027       int maxValue=_num->getMaxValue(pos);
1028       if (!_rev_num || _rev_num->getNumberOfTuples() != (maxValue+1))
1029         throw INTERP_KERNEL::Exception("MEDFileUMeshSplitL1::checkConsistency(): inconsistent internal revert node numbering array!");
1030     }
1031   if ((_num && !_rev_num) || (!_num && _rev_num))
1032     throw INTERP_KERNEL::Exception("MEDFileUMeshSplitL1::checkConsistency(): inconsistent internal numbering arrays (one is null)!");
1033   if (_num && !_num->hasUniqueValues())
1034     throw INTERP_KERNEL::Exception("MEDFileUMeshSplitL1::checkConsistency(): inconsistent internal node numbering array: duplicates found!");
1035   if (_names)
1036     _names->checkNbOfTuplesAndComp(nbCells,1,"MEDFileUMeshSplitL1::checkConsistency(): internal cell naming array has an invalid size!");
1037
1038   _m_by_types.checkConsistency();
1039 }
1040
1041 bool MEDFileUMeshSplitL1::isEqual(const MEDFileUMeshSplitL1 *other, double eps, std::string& what) const
1042 {
1043   if(!_m_by_types.isEqual(other->_m_by_types,eps,what))
1044     return false;
1045   const DataArrayInt *d1=_fam;
1046   const DataArrayInt *d2=other->_fam;
1047   if((d1==0 && d2!=0) || (d1!=0 && d2==0))
1048     {
1049       what="Presence of family arr in one sublevel and not in other!";
1050       return false;
1051     }
1052   if(d1)
1053     if(!d1->isEqual(*d2))
1054       {
1055         what="family arr at a sublevel are not deeply equal !";
1056         return false;
1057       }
1058   d1=_num;
1059   d2=other->_num;
1060   if((d1==0 && d2!=0) || (d1!=0 && d2==0))
1061     {
1062       what="Presence of cell numbering arr in one sublevel and not in other!";
1063       return false;
1064     }
1065   if(d1)
1066     if(!d1->isEqual(*d2))
1067       {
1068         what="Numbering cell arr at a sublevel are not deeply equal !";
1069         return false;
1070       }
1071   const DataArrayAsciiChar *e1=_names;
1072   const DataArrayAsciiChar *e2=other->_names;
1073   if((e1==0 && e2!=0) || (e1!=0 && e2==0))
1074     {
1075       what="Presence of cell names arr in one sublevel and not in other!";
1076       return false;
1077     }
1078   if(e1)
1079     if(!e1->isEqual(*e2))
1080       {
1081         what="Name cell arr at a sublevel are not deeply equal !";
1082         return false;
1083       }
1084   return true;
1085 }
1086
1087 void MEDFileUMeshSplitL1::synchronizeTinyInfo(const MEDFileMesh& master) const
1088 {
1089   _m_by_types.synchronizeTinyInfo(master);
1090 }
1091
1092 void MEDFileUMeshSplitL1::clearNonDiscrAttributes() const
1093 {
1094   _m_by_types.clearNonDiscrAttributes();
1095 }
1096
1097 void MEDFileUMeshSplitL1::ClearNonDiscrAttributes(const MEDCouplingMesh *tmp)
1098 {
1099   if(!tmp)
1100     return ;
1101   (const_cast<MEDCouplingMesh *>(tmp))->setName("");
1102   (const_cast<MEDCouplingMesh *>(tmp))->setDescription("");
1103   (const_cast<MEDCouplingMesh *>(tmp))->setTime(0.,-1,-1);
1104   (const_cast<MEDCouplingMesh *>(tmp))->setTimeUnit("");
1105 }
1106
1107 void MEDFileUMeshSplitL1::setCoords(DataArrayDouble *coords)
1108 {
1109   _m_by_types.setCoords(coords);
1110 }
1111
1112 void MEDFileUMeshSplitL1::assignMesh(MEDCouplingUMesh *m, bool newOrOld)
1113 {
1114   if(newOrOld)
1115     {
1116       m->incrRef();
1117       _m=m;
1118       _m_by_types.assignUMesh(dynamic_cast<MEDCouplingUMesh *>(m->deepCopy()));
1119       MCAuto<DataArrayInt> da=_m_by_types.getUmesh()->getRenumArrForConsecutiveCellTypesSpec(typmai2,typmai2+MED_N_CELL_FIXED_GEO);
1120       if(!da->isIota(m->getNumberOfCells()))
1121         {
1122           _num=da->invertArrayO2N2N2O(m->getNumberOfCells());
1123           _m.updateTime();
1124           computeRevNum();
1125           _m_by_types.getUmesh()->renumberCells(da->getConstPointer(),false);
1126         }
1127     }
1128   else
1129     {
1130       if(!m->checkConsecutiveCellTypesAndOrder(typmai2,typmai2+MED_N_CELL_FIXED_GEO))
1131         throw INTERP_KERNEL::Exception("MEDFileUMeshSplitL1::assignMesh(): the mesh does not follow the MED file numbering convention! Invoke sortCellsInMEDFileFrmt() first!");
1132       m->incrRef();
1133       _m_by_types.assignUMesh(m);
1134     }
1135   assignCommonPart();
1136 }
1137
1138 void MEDFileUMeshSplitL1::forceComputationOfParts() const
1139 {
1140   _m_by_types.forceComputationOfPartsFromUMesh();
1141 }
1142
1143 void MEDFileUMeshSplitL1::assignParts(const std::vector< const MEDCoupling1GTUMesh * >& mParts)
1144 {
1145   _m_by_types.assignParts(mParts);
1146   assignCommonPart();
1147 }
1148
1149 MEDFileUMeshSplitL1::MEDFileUMeshSplitL1():_m(this)
1150 {
1151 }
1152
1153 void MEDFileUMeshSplitL1::assignCommonPart()
1154 {
1155   _fam=DataArrayInt::New();
1156   _fam->alloc(_m_by_types.getSize(),1);
1157   _fam->fillWithValue(0);
1158 }
1159
1160 bool MEDFileUMeshSplitL1::empty() const
1161 {
1162   return _m_by_types.empty();
1163 }
1164
1165 bool MEDFileUMeshSplitL1::presenceOfOneFams(const std::vector<int>& ids) const
1166 {
1167   const DataArrayInt *fam=_fam;
1168   if(!fam)
1169     return false;
1170   return fam->presenceOfValue(ids);
1171 }
1172
1173 int MEDFileUMeshSplitL1::getMeshDimension() const
1174 {
1175   return _m_by_types.getMeshDimension();
1176 }
1177
1178 void MEDFileUMeshSplitL1::simpleRepr(std::ostream& oss) const
1179 {
1180   std::vector<int> code=_m_by_types.getDistributionOfTypes();
1181   int nbOfTypes=code.size()/3;
1182   for(int i=0;i<nbOfTypes;i++)
1183     {
1184       INTERP_KERNEL::NormalizedCellType typ=(INTERP_KERNEL::NormalizedCellType) code[3*i];
1185       oss << "    - Number of cells with type " << INTERP_KERNEL::CellModel::GetCellModel(typ).getRepr() << " : " << code[3*i+1] << std::endl;
1186     }
1187 }
1188
1189 int MEDFileUMeshSplitL1::getSize() const
1190 {
1191   return _m_by_types.getSize();
1192 }
1193
1194 MEDCouplingUMesh *MEDFileUMeshSplitL1::getFamilyPart(const int *idsBg, const int *idsEnd, bool renum) const
1195 {
1196   MCAuto<DataArrayInt> eltsToKeep=_fam->findIdsEqualList(idsBg,idsEnd);
1197   MEDCouplingUMesh *m=(MEDCouplingUMesh *)_m_by_types.getUmesh()->buildPartOfMySelf(eltsToKeep->getConstPointer(),eltsToKeep->getConstPointer()+eltsToKeep->getNumberOfTuples(),true);
1198   if(renum)
1199     return renumIfNeeded(m,eltsToKeep->getConstPointer());
1200   return m;
1201 }
1202
1203 DataArrayInt *MEDFileUMeshSplitL1::getFamilyPartArr(const int *idsBg, const int *idsEnd, bool renum) const
1204 {
1205   MCAuto<DataArrayInt> da=_fam->findIdsEqualList(idsBg,idsEnd);
1206   if(renum)
1207     return renumIfNeededArr(da);
1208   return da.retn();
1209 }
1210
1211 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileUMeshSplitL1::getGeoTypes() const
1212 {
1213   return _m_by_types.getGeoTypes();
1214 }
1215
1216 int MEDFileUMeshSplitL1::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const
1217 {
1218   return _m_by_types.getNumberOfCellsWithType(ct);
1219 }
1220
1221 MEDCouplingUMesh *MEDFileUMeshSplitL1::getWholeMesh(bool renum) const
1222 {
1223   MCAuto<MEDCouplingUMesh> tmp;
1224   if(renum && ((const DataArrayInt *)_num))
1225     tmp=_m;
1226   else
1227     { tmp=_m_by_types.getUmesh(); if(tmp) tmp->incrRef(); }
1228   return tmp.retn();
1229 }
1230
1231 int MEDFileUMeshSplitL1::getNumberOfCells() const
1232 {
1233   return _m_by_types.getNumberOfCells();
1234 }
1235
1236 DataArrayInt *MEDFileUMeshSplitL1::extractFamilyFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
1237 {
1238   const DataArrayInt *fam(_fam);
1239   if(!fam)
1240     return 0;
1241   int start(0),stop(0);
1242   _m_by_types.getStartStopOfGeoTypeWithoutComputation(gt,start,stop);
1243   return fam->selectByTupleIdSafeSlice(start,stop,1);
1244 }
1245
1246 DataArrayInt *MEDFileUMeshSplitL1::extractNumberFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
1247 {
1248   const DataArrayInt *num(_num);
1249   if(!num)
1250     return 0;
1251   int start(0),stop(0);
1252   _m_by_types.getStartStopOfGeoTypeWithoutComputation(gt,start,stop);
1253   return num->selectByTupleIdSafeSlice(start,stop,1);
1254 }
1255
1256 DataArrayInt *MEDFileUMeshSplitL1::getOrCreateAndGetFamilyField()
1257 {
1258   if((DataArrayInt *)_fam)
1259     return _fam;
1260   int nbOfTuples=_m_by_types.getSize();
1261   _fam=DataArrayInt::New(); _fam->alloc(nbOfTuples,1); _fam->fillWithZero();
1262   return _fam;
1263 }
1264
1265 const DataArrayInt *MEDFileUMeshSplitL1::getFamilyField() const
1266 {
1267   return _fam;
1268 }
1269
1270 const DataArrayInt *MEDFileUMeshSplitL1::getNumberField() const
1271 {
1272   return _num;
1273 }
1274
1275 const DataArrayInt *MEDFileUMeshSplitL1::getRevNumberField() const
1276 {
1277   return _rev_num;
1278 }
1279
1280 const DataArrayAsciiChar *MEDFileUMeshSplitL1::getNameField() const
1281 {
1282   return _names;
1283 }
1284
1285 const PartDefinition *MEDFileUMeshSplitL1::getPartDef(INTERP_KERNEL::NormalizedCellType gt) const
1286 {
1287   return _m_by_types.getPartDefOfWithoutComputation(gt);
1288 }
1289
1290 void MEDFileUMeshSplitL1::eraseFamilyField()
1291 {
1292   _fam->fillWithZero();
1293 }
1294
1295 /*!
1296  * This method ignores _m and _m_by_types.
1297  */
1298 void MEDFileUMeshSplitL1::setGroupsFromScratch(const std::vector<const MEDCouplingUMesh *>& ms, std::map<std::string,int>& familyIds,
1299                                                std::map<std::string, std::vector<std::string> >& groups)
1300 {
1301   std::vector< DataArrayInt * > corr;
1302   _m=MEDCouplingUMesh::FuseUMeshesOnSameCoords(ms,0,corr);
1303   std::vector< MCAuto<DataArrayInt> > corrMSafe(corr.begin(),corr.end());
1304   std::vector< std::vector<int> > fidsOfGroups;
1305   std::vector< const DataArrayInt * > corr2(corr.begin(),corr.end());
1306   _fam=DataArrayInt::MakePartition(corr2,((MEDCouplingUMesh *)_m)->getNumberOfCells(),fidsOfGroups);
1307   int nbOfCells=((MEDCouplingUMesh *)_m)->getNumberOfCells();
1308   std::map<int,std::string> newfams;
1309   std::map<int,int> famIdTrad;
1310   TraduceFamilyNumber(fidsOfGroups,familyIds,famIdTrad,newfams);
1311   int *w=_fam->getPointer();
1312   for(int i=0;i<nbOfCells;i++,w++)
1313     *w=famIdTrad[*w];
1314 }
1315
1316 void MEDFileUMeshSplitL1::write(med_idt fid, const std::string& mName, int mdim) const
1317 {
1318   std::vector<MEDCoupling1GTUMesh *> ms(_m_by_types.getParts());
1319   int start=0;
1320   for(std::vector<MEDCoupling1GTUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
1321     {
1322       int nbCells=(*it)->getNumberOfCells();
1323       int end=start+nbCells;
1324       MCAuto<DataArrayInt> fam,num;
1325       MCAuto<DataArrayAsciiChar> names;
1326       if((const DataArrayInt *)_fam)
1327         fam=_fam->subArray(start,end);
1328       if((const DataArrayInt *)_num)
1329         num=_num->subArray(start,end);
1330       if((const DataArrayAsciiChar *)_names)
1331         names=static_cast<DataArrayAsciiChar *>(_names->subArray(start,end));
1332       MEDFileUMeshPerType::Write(fid,mName,mdim,(*it),fam,num,names);
1333       start=end;
1334     }
1335 }
1336
1337 void MEDFileUMeshSplitL1::renumberNodesInConn(const int *newNodeNumbersO2N)
1338 {
1339   _m_by_types.renumberNodesInConnWithoutComputation(newNodeNumbersO2N);
1340 }
1341
1342 void MEDFileUMeshSplitL1::serialize(std::vector<int>& tinyInt, std::vector< MCAuto<DataArrayInt> >& bigArraysI) const
1343 {
1344   bigArraysI.push_back(_fam);
1345   bigArraysI.push_back(_num);
1346   _m_by_types.serialize(tinyInt,bigArraysI);
1347 }
1348
1349 void MEDFileUMeshSplitL1::unserialize(const std::string& name, DataArrayDouble *coo, std::vector<int>& tinyInt, std::vector< MCAuto<DataArrayInt> >& bigArraysI)
1350 {
1351   _fam=bigArraysI.back(); bigArraysI.pop_back();
1352   _num=bigArraysI.back(); bigArraysI.pop_back();
1353   _m_by_types.unserialize(name,coo,tinyInt,bigArraysI);
1354 }
1355
1356 void MEDFileUMeshSplitL1::changeFamilyIdArr(int oldId, int newId)
1357 {
1358   DataArrayInt *arr=_fam;
1359   if(arr)
1360     arr->changeValue(oldId,newId);
1361 }
1362
1363 void MEDFileUMeshSplitL1::setFamilyArr(DataArrayInt *famArr)
1364 {
1365   if(!famArr)
1366     {
1367       _fam=0;
1368       return ;
1369     }
1370   int sz(_m_by_types.getSize());
1371   famArr->checkNbOfTuplesAndComp(sz,1,"MEDFileUMeshSplitL1::setFamilyArr : Problem in size of Family arr ! ");
1372   famArr->incrRef();
1373   _fam=famArr;
1374 }
1375
1376 DataArrayInt *MEDFileUMeshSplitL1::getFamilyField()
1377 {
1378   return _fam;
1379 }
1380
1381 void MEDFileUMeshSplitL1::setRenumArr(DataArrayInt *renumArr)
1382 {
1383   if(!renumArr)
1384     {
1385       _num=0;
1386       _rev_num=0;
1387       return ;
1388     }
1389   int sz(_m_by_types.getSize());
1390   renumArr->checkNbOfTuplesAndComp(sz,1,"MEDFileUMeshSplitL1::setRenumArr : Problem in size of numbering arr ! ");
1391   renumArr->incrRef();
1392   _num=renumArr;
1393   computeRevNum();
1394 }
1395
1396 void MEDFileUMeshSplitL1::setNameArr(DataArrayAsciiChar *nameArr)
1397 {
1398   if(!nameArr)
1399     {
1400       _names=0;
1401       return ;
1402     }
1403   int sz(_m_by_types.getSize());
1404   nameArr->checkNbOfTuplesAndComp(sz,MED_SNAME_SIZE,"MEDFileUMeshSplitL1::setNameArr : Problem in size of name arr ! ");
1405   nameArr->incrRef();
1406   _names=nameArr;
1407 }
1408
1409 MEDCouplingUMesh *MEDFileUMeshSplitL1::Renumber2(const DataArrayInt *renum, MEDCouplingUMesh *m, const int *cellIds)
1410 {
1411   if(renum==0)
1412     return m;
1413   if(cellIds==0)
1414     m->renumberCells(renum->getConstPointer(),true);
1415   else
1416     {
1417       MCAuto<DataArrayInt> locnum=renum->selectByTupleId(cellIds,cellIds+m->getNumberOfCells());
1418       m->renumberCells(locnum->getConstPointer(),true);
1419     }
1420   return m;
1421 }
1422
1423 MEDFileUMeshSplitL1 *MEDFileUMeshSplitL1::Unserialize(const std::string& name, DataArrayDouble *coo, std::vector<int>& tinyInt, std::vector< MCAuto<DataArrayInt> >& bigArraysI)
1424 {
1425   MCAuto<MEDFileUMeshSplitL1> ret(new MEDFileUMeshSplitL1);
1426   ret->unserialize(name,coo,tinyInt,bigArraysI);
1427   return ret.retn();
1428 }
1429
1430 MEDCouplingUMesh *MEDFileUMeshSplitL1::renumIfNeeded(MEDCouplingUMesh *m, const int *cellIds) const
1431 {
1432   return Renumber2(_num,m,cellIds);
1433 }
1434
1435 DataArrayInt *MEDFileUMeshSplitL1::Renumber(const DataArrayInt *renum, const DataArrayInt *da)
1436 {
1437   if((const DataArrayInt *)renum==0)
1438     {
1439       da->incrRef();
1440       return const_cast<DataArrayInt *>(da);
1441     }
1442   return renum->selectByTupleId(da->getConstPointer(),da->getConstPointer()+da->getNumberOfTuples());
1443 }
1444
1445 DataArrayInt *MEDFileUMeshSplitL1::renumIfNeededArr(const DataArrayInt *da) const
1446 {
1447   return Renumber(_num,da);
1448 }
1449
1450 std::vector<int> MEDFileUMeshSplitL1::GetNewFamiliesNumber(int nb, const std::map<std::string,int>& families)
1451 {
1452   int id=-1;
1453   for(std::map<std::string,int>::const_iterator it=families.begin();it!=families.end();it++)
1454     id=std::max(id,(*it).second);
1455   if(id==-1)
1456     id=0;
1457   std::vector<int> ret(nb);
1458   for(int i=1;i<=nb;i++)
1459     ret[i]=id+i;
1460   return ret;
1461 }
1462
1463 void MEDFileUMeshSplitL1::TraduceFamilyNumber(const std::vector< std::vector<int> >& fidsGrps, std::map<std::string,int>& familyIds,
1464                                               std::map<int,int>& famIdTrad, std::map<int,std::string>& newfams)
1465 {
1466   std::set<int> allfids;
1467   //tony
1468 }
1469
1470 void MEDFileUMeshSplitL1::computeRevNum() const
1471 {
1472   int pos;
1473   int maxValue=_num->getMaxValue(pos);
1474   _rev_num=_num->invertArrayN2O2O2N(maxValue+1);
1475 }
1476
1477 //=
1478
1479 MEDFileUMeshAggregateCompute::MEDFileUMeshAggregateCompute():_mp_time(0),_m_time(0)
1480 {
1481 }
1482
1483 void MEDFileUMeshAggregateCompute::setName(const std::string& name)
1484 {
1485   if(_m_time>=_mp_time)
1486     {
1487       MEDCouplingUMesh *um(_m);
1488       if(um)
1489         um->setName(name);
1490     }
1491   if(_mp_time>=_m_time)
1492     {
1493       for(std::vector< MCAuto<MEDCoupling1GTUMesh> >::iterator it=_m_parts.begin();it!=_m_parts.end();it++)
1494         {
1495           MEDCoupling1GTUMesh *tmp(*it);
1496           if(tmp)
1497             tmp->setName(name);
1498         }
1499     }
1500 }
1501
1502 void MEDFileUMeshAggregateCompute::assignParts(const std::vector< const MEDCoupling1GTUMesh * >& mParts)
1503 {
1504   std::size_t sz(mParts.size());
1505   std::vector< MCAuto<MEDCoupling1GTUMesh> > ret(sz);
1506   for(std::size_t i=0;i<sz;i++)
1507     {
1508       const MEDCoupling1GTUMesh *elt(mParts[i]);
1509       if(!elt)
1510         throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::assignParts : presence of null pointer !");
1511       ret[i]=const_cast<MEDCoupling1GTUMesh *>(elt); elt->incrRef();
1512     }
1513   _m_parts=ret;
1514   _part_def.clear(); _part_def.resize(sz);
1515   _mp_time=std::max(_mp_time,_m_time)+1;
1516   _m=0;
1517 }
1518
1519 void MEDFileUMeshAggregateCompute::assignDefParts(const std::vector<const PartDefinition *>& partDefs)
1520 {
1521   if(_mp_time<_m_time)
1522     throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::assignDefParts : the parts require a computation !");
1523   std::size_t sz(partDefs.size());
1524   if(_part_def.size()!=partDefs.size() || _part_def.size()!=_m_parts.size())
1525     throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::assignDefParts : sizes of vectors of part definition mismatch !");
1526   for(std::size_t i=0;i<sz;i++)
1527     {
1528       const PartDefinition *elt(partDefs[i]);
1529       if(elt)
1530         elt->incrRef();
1531       _part_def[i]=const_cast<PartDefinition*>(elt);
1532     }
1533 }
1534
1535 void MEDFileUMeshAggregateCompute::assignUMesh(MEDCouplingUMesh *m)
1536 {
1537   _m=m;
1538   _m_parts.clear();
1539   _m_time=std::max(_mp_time,_m_time)+1;
1540 }
1541
1542 MEDCouplingUMesh *MEDFileUMeshAggregateCompute::getUmesh() const
1543 {
1544   if(_mp_time<=_m_time)
1545     return _m;
1546   std::vector< const MEDCoupling1GTUMesh *> mp(_m_parts.size());
1547   std::copy(_m_parts.begin(),_m_parts.end(),mp.begin());
1548   _m=MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh(mp);
1549   _m_parts.clear();//to avoid memory peak !
1550   _m_time=_mp_time+1;//+1 is important ! That is to say that only _m is OK not _m_parts because cleared !
1551   return _m;
1552 }
1553
1554 int MEDFileUMeshAggregateCompute::getNumberOfCells() const
1555 {
1556   if(_mp_time<=_m_time)
1557     return _m->getNumberOfCells();
1558   int ret(0);
1559   for(std::vector< MCAuto<MEDCoupling1GTUMesh> >::const_iterator it=_m_parts.begin();it!=_m_parts.end();it++)
1560     ret+=(*it)->getNumberOfCells();
1561   return ret;
1562 }
1563
1564 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileUMeshAggregateCompute::getGeoTypes() const
1565 {
1566   if(_mp_time>=_m_time)
1567     {
1568       std::size_t sz(_m_parts.size());
1569       std::vector<INTERP_KERNEL::NormalizedCellType> ret(sz);
1570       for(std::size_t i=0;i<sz;i++)
1571         ret[i]=_m_parts[i]->getCellModelEnum();
1572       return ret;
1573     }
1574   else
1575     return _m->getAllGeoTypesSorted();
1576 }
1577
1578 int MEDFileUMeshAggregateCompute::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const
1579 {
1580   if(_mp_time>=_m_time)
1581     {
1582       for(std::vector< MCAuto<MEDCoupling1GTUMesh> >::const_iterator it=_m_parts.begin();it!=_m_parts.end();it++)
1583         {
1584           const MEDCoupling1GTUMesh *elt(*it);
1585           if(elt && elt->getCellModelEnum()==ct)
1586             return elt->getNumberOfCells();
1587         }
1588       return 0;
1589     }
1590   else
1591     return _m->getNumberOfCellsWithType(ct);
1592 }
1593
1594 std::vector<MEDCoupling1GTUMesh *> MEDFileUMeshAggregateCompute::retrievePartsWithoutComputation() const
1595 {
1596   if(_mp_time<_m_time)
1597     throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getPartsWithoutComputation : the parts require a computation !");
1598   //
1599   std::vector<MEDCoupling1GTUMesh *> ret(_m_parts.size());
1600   std::size_t i(0);
1601   for(std::vector< MCAuto<MEDCoupling1GTUMesh> >::const_iterator it=_m_parts.begin();it!=_m_parts.end();it++,i++)
1602     {
1603       const MEDCoupling1GTUMesh *elt(*it);
1604       ret[i]=const_cast<MEDCoupling1GTUMesh *>(elt);
1605     }
1606   return ret;
1607 }
1608
1609 std::vector<MEDCoupling1GTUMesh *> MEDFileUMeshAggregateCompute::getParts() const
1610 {
1611   if(_mp_time<_m_time)
1612     forceComputationOfPartsFromUMesh();
1613   return retrievePartsWithoutComputation();
1614 }
1615
1616 MEDCoupling1GTUMesh *MEDFileUMeshAggregateCompute::retrievePartWithoutComputation(INTERP_KERNEL::NormalizedCellType gt) const
1617 {
1618   std::vector<MEDCoupling1GTUMesh *> v(retrievePartsWithoutComputation());
1619   std::size_t sz(v.size());
1620   for(std::size_t i=0;i<sz;i++)
1621     {
1622       if(v[i])
1623         if(v[i]->getCellModelEnum()==gt)
1624           return v[i];
1625     }
1626   throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getPartWithoutComputation : the geometric type is not existing !");
1627 }
1628
1629 void MEDFileUMeshAggregateCompute::getStartStopOfGeoTypeWithoutComputation(INTERP_KERNEL::NormalizedCellType gt, int& start, int& stop) const
1630 {
1631   start=0; stop=0;
1632   std::vector<MEDCoupling1GTUMesh *> v(retrievePartsWithoutComputation());
1633   std::size_t sz(v.size());
1634   for(std::size_t i=0;i<sz;i++)
1635     {
1636       if(v[i])
1637         {
1638           if(v[i]->getCellModelEnum()==gt)
1639             {
1640               stop=start+v[i]->getNumberOfCells();
1641               return;
1642             }
1643           else
1644             start+=v[i]->getNumberOfCells();
1645         }
1646     }
1647   throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getStartStopOfGeoTypeWithoutComputation : the geometric type is not existing !");
1648 }
1649
1650 void MEDFileUMeshAggregateCompute::renumberNodesInConnWithoutComputation(const int *newNodeNumbersO2N)
1651 {
1652   if(_mp_time>_m_time)
1653     {
1654       for(std::vector< MCAuto<MEDCoupling1GTUMesh> >::iterator it=_m_parts.begin();it!=_m_parts.end();it++)
1655         {
1656           MEDCoupling1GTUMesh *m(*it);
1657           if(m)
1658             m->renumberNodesInConn(newNodeNumbersO2N);
1659         }
1660     }
1661   else
1662     {
1663       MEDCouplingUMesh *m(getUmesh());
1664       if(!m)
1665         return;
1666       m->renumberNodesInConn(newNodeNumbersO2N);
1667     }
1668 }
1669
1670 void MEDFileUMeshAggregateCompute::forceComputationOfPartsFromUMesh() const
1671 {
1672   const MEDCouplingUMesh *m(_m);
1673   if(!m)
1674     {
1675       if(_m_parts.empty())
1676         throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::forceComputationOfPartsFromUMesh : null UMesh !");
1677       else
1678         return ;// no needs to compte parts they are already here !
1679     }
1680   std::vector<MEDCouplingUMesh *> ms(m->splitByType());
1681   std::vector< MCAuto<MEDCouplingUMesh> > msMSafe(ms.begin(),ms.end());
1682   std::size_t sz(msMSafe.size());
1683   _m_parts.resize(sz);
1684   for(std::size_t i=0;i<sz;i++)
1685     _m_parts[i]=MEDCoupling1GTUMesh::New(ms[i]);
1686   _part_def.clear();
1687   _part_def.resize(_m_parts.size());
1688   _mp_time=std::max(_mp_time,_m_time);
1689 }
1690
1691 const PartDefinition *MEDFileUMeshAggregateCompute::getPartDefOfWithoutComputation(INTERP_KERNEL::NormalizedCellType gt) const
1692 {
1693   if(_mp_time<_m_time)
1694     throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getPartDefOfWithoutComputation : the parts require a computation !");
1695   if(_m_parts.size()!=_part_def.size())
1696     throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getPartDefOfWithoutComputation : size of arrays are expected to be the same !");
1697   std::size_t sz(_m_parts.size());
1698   for(std::size_t i=0;i<sz;i++)
1699     {
1700       const MEDCoupling1GTUMesh *mesh(_m_parts[i]);
1701       if(mesh)
1702         if(mesh->getCellModelEnum()==gt)
1703           return _part_def[i];
1704     }
1705   throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getPartDefOfWithoutComputation : The input geo type is not existing in this !");
1706 }
1707
1708 void MEDFileUMeshAggregateCompute::serialize(std::vector<int>& tinyInt, std::vector< MCAuto<DataArrayInt> >& bigArraysI) const
1709 {
1710   if(_mp_time<_m_time)
1711     throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::serialize : the parts require a computation !");
1712   std::size_t sz(_m_parts.size());
1713   tinyInt.push_back((int)sz);
1714   for(std::size_t i=0;i<sz;i++)
1715     {
1716       const MEDCoupling1GTUMesh *mesh(_m_parts[i]);
1717       if(!mesh)
1718         throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::serialize : one part is empty !");
1719       tinyInt.push_back(mesh->getCellModelEnum());
1720       const MEDCoupling1SGTUMesh *mesh1(dynamic_cast<const MEDCoupling1SGTUMesh *>(mesh));
1721       const MEDCoupling1DGTUMesh *mesh2(dynamic_cast<const MEDCoupling1DGTUMesh *>(mesh));
1722       if(mesh1)
1723         {
1724           DataArrayInt *elt(mesh1->getNodalConnectivity());
1725           if(elt)
1726             elt->incrRef();
1727           MCAuto<DataArrayInt> elt1(elt);
1728           bigArraysI.push_back(elt1);
1729         }
1730       else if(mesh2)
1731         {
1732           DataArrayInt *elt1(mesh2->getNodalConnectivity()),*elt2(mesh2->getNodalConnectivityIndex());
1733           if(elt1)
1734             elt1->incrRef();
1735           if(elt2)
1736             elt2->incrRef();
1737           MCAuto<DataArrayInt> elt11(elt1),elt22(elt2);
1738           bigArraysI.push_back(elt11); bigArraysI.push_back(elt22);
1739         }
1740       else
1741         throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::serialize : unrecognized single geo type mesh !");
1742       const PartDefinition *pd(_part_def[i]);
1743       if(!pd)
1744         tinyInt.push_back(-1);
1745       else
1746         {
1747           std::vector<int> tinyTmp;
1748           pd->serialize(tinyTmp,bigArraysI);
1749           tinyInt.push_back((int)tinyTmp.size());
1750           tinyInt.insert(tinyInt.end(),tinyTmp.begin(),tinyTmp.end());
1751         }
1752     }
1753 }
1754
1755 void MEDFileUMeshAggregateCompute::unserialize(const std::string& name, DataArrayDouble *coo, std::vector<int>& tinyInt, std::vector< MCAuto<DataArrayInt> >& bigArraysI)
1756 {
1757   int nbParts(tinyInt.back()); tinyInt.pop_back();
1758   _part_def.clear(); _part_def.resize(nbParts);
1759   _m_parts.clear(); _m_parts.resize(nbParts);
1760   for(int i=0;i<nbParts;i++)
1761     {
1762       INTERP_KERNEL::NormalizedCellType tp((INTERP_KERNEL::NormalizedCellType) tinyInt.back()); tinyInt.pop_back();
1763       MCAuto<MEDCoupling1GTUMesh> mesh(MEDCoupling1GTUMesh::New(name,tp));
1764       mesh->setCoords(coo);
1765       MEDCoupling1SGTUMesh *mesh1(dynamic_cast<MEDCoupling1SGTUMesh *>((MEDCoupling1GTUMesh *) mesh));
1766       MEDCoupling1DGTUMesh *mesh2(dynamic_cast<MEDCoupling1DGTUMesh *>((MEDCoupling1GTUMesh *) mesh));
1767       if(mesh1)
1768         {
1769           mesh1->setNodalConnectivity(bigArraysI.back()); bigArraysI.pop_back();
1770         }
1771       else if(mesh2)
1772         {
1773           MCAuto<DataArrayInt> elt0,elt1;
1774           elt0=bigArraysI.back(); bigArraysI.pop_back();
1775           elt1=bigArraysI.back(); bigArraysI.pop_back();
1776           mesh2->setNodalConnectivity(elt0,elt1);
1777         }
1778       else
1779         throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::unserialize : unrecognized single geo type mesh !");
1780       _m_parts[i]=mesh;
1781       int pdid(tinyInt.back()); tinyInt.pop_back();
1782       if(pdid!=-1)
1783         _part_def[i]=PartDefinition::Unserialize(tinyInt,bigArraysI);
1784       _mp_time=std::max(_mp_time,_m_time)+1;
1785     }
1786 }
1787
1788 /*!
1789  * This method returns true if \a this is stored split by type false if stored in a merged unstructured mesh.
1790  */
1791 bool MEDFileUMeshAggregateCompute::isStoredSplitByType() const
1792 {
1793   return _mp_time>=_m_time;
1794 }
1795
1796 std::size_t MEDFileUMeshAggregateCompute::getTimeOfThis() const
1797 {
1798   if(_mp_time>_m_time)
1799     return getTimeOfParts();
1800   if(_m_time>_mp_time)
1801     return getTimeOfUMesh();
1802   return std::max(getTimeOfParts(),getTimeOfUMesh());
1803 }
1804
1805 std::size_t MEDFileUMeshAggregateCompute::getTimeOfParts() const
1806 {
1807   std::size_t ret(0);
1808   for(std::vector< MCAuto<MEDCoupling1GTUMesh> >::const_iterator it=_m_parts.begin();it!=_m_parts.end();it++)
1809     {
1810       const MEDCoupling1GTUMesh *elt(*it);
1811       if(!elt)
1812         throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getTimeOfParts : null obj in parts !");
1813       ret=std::max(ret,elt->getTimeOfThis());
1814     }
1815   if(ret==0)
1816     throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getTimeOfParts : parts is empty !");
1817   return ret;
1818 }
1819
1820 std::size_t MEDFileUMeshAggregateCompute::getTimeOfUMesh() const
1821 {
1822   const MEDCouplingUMesh *m(_m);
1823   if(!m)
1824     throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getTimeOfUMesh : unmesh is null !");
1825   return m->getTimeOfThis();
1826 }
1827
1828 std::size_t MEDFileUMeshAggregateCompute::getHeapMemorySizeWithoutChildren() const
1829 {
1830   std::size_t ret(_m_parts.size()*sizeof(MCAuto<MEDCoupling1GTUMesh>));
1831   return ret;
1832 }
1833
1834 std::vector<const BigMemoryObject *> MEDFileUMeshAggregateCompute::getDirectChildrenWithNull() const
1835 {
1836   std::vector<const BigMemoryObject *> ret;
1837   for(std::vector< MCAuto<MEDCoupling1GTUMesh> >::const_iterator it=_m_parts.begin();it!=_m_parts.end();it++)
1838     ret.push_back((const MEDCoupling1GTUMesh *)*it);
1839   ret.push_back((const MEDCouplingUMesh *)_m);
1840   return ret;
1841 }
1842
1843 MEDFileUMeshAggregateCompute MEDFileUMeshAggregateCompute::deepCopy(DataArrayDouble *coords) const
1844 {
1845   MEDFileUMeshAggregateCompute ret;
1846   ret._m_parts.resize(_m_parts.size());
1847   for(std::size_t i=0;i<_m_parts.size();i++)
1848     {
1849       const MEDCoupling1GTUMesh *elt(_m_parts[i]);
1850       if(elt)
1851         {
1852           ret._m_parts[i]=static_cast<MEDCoupling::MEDCoupling1GTUMesh*>(elt->deepCopy());
1853           ret._m_parts[i]->setCoords(coords);
1854         }
1855     }
1856   ret._mp_time=_mp_time; ret._m_time=_m_time;
1857   if((const MEDCouplingUMesh *)_m)
1858     {
1859       ret._m=static_cast<MEDCoupling::MEDCouplingUMesh*>(_m->deepCopy());
1860       ret._m->setCoords(coords);
1861     }
1862   std::size_t sz(_part_def.size());
1863   ret._part_def.clear(); ret._part_def.resize(sz);
1864   for(std::size_t i=0;i<sz;i++)
1865     {
1866       const PartDefinition *elt(_part_def[i]);
1867       if(elt)
1868         ret._part_def[i]=elt->deepCopy();
1869     }
1870   return ret;
1871 }
1872
1873 void MEDFileUMeshAggregateCompute::shallowCpyMeshes()
1874 {
1875   for(std::vector< MCAuto<MEDCoupling1GTUMesh> >::iterator it=_m_parts.begin();it!=_m_parts.end();it++)
1876     {
1877       const MEDCoupling1GTUMesh *elt(*it);
1878       if(elt)
1879         {
1880           MCAuto<MEDCouplingMesh> elt2(elt->clone(false));
1881           *it=DynamicCastSafe<MEDCouplingMesh,MEDCoupling1GTUMesh>(elt2);
1882         }
1883     }
1884   const MEDCouplingUMesh *m(_m);
1885   if(m)
1886     _m=m->clone(false);
1887 }
1888
1889 bool MEDFileUMeshAggregateCompute::isEqual(const MEDFileUMeshAggregateCompute& other, double eps, std::string& what) const
1890 {
1891   const MEDCouplingUMesh *m1(getUmesh());
1892   const MEDCouplingUMesh *m2(other.getUmesh());
1893   if((m1==0 && m2!=0) || (m1!=0 && m2==0))
1894     {
1895       what="Presence of mesh in one sublevel and not in other!";
1896       return false;
1897     }
1898   if(m1)
1899     {
1900       std::string what2;
1901       if(!m1->isEqualIfNotWhy(m2,eps,what2))
1902         {
1903           what=std::string("meshes at a sublevel are not deeply equal (")+what2+std::string(")!");
1904           return false;
1905         }
1906     }
1907   std::size_t sz(_part_def.size());
1908   if(sz!=other._part_def.size())
1909     {
1910       what=std::string("number of subdivision per geo type for part definition is not the same !");
1911       return false;
1912     }
1913   for(std::size_t i=0;i<sz;i++)
1914     {
1915       const PartDefinition *pd0(_part_def[i]),*pd1(other._part_def[i]);
1916       if(!pd0 && !pd1)
1917         continue;
1918       if((!pd0 && pd1) || (pd0 && !pd1))
1919         {
1920           what=std::string("a cell part def is defined only for one among this or other !");
1921           return false;
1922         }
1923       bool ret(pd0->isEqual(pd1,what));
1924       if(!ret)
1925         return false;
1926     }
1927   return true;
1928 }
1929
1930 void MEDFileUMeshAggregateCompute::checkConsistency() const
1931 {
1932   if(_mp_time >= _m_time)
1933     for(std::vector< MCAuto<MEDCoupling1GTUMesh> >::const_iterator it=_m_parts.begin();
1934         it!=_m_parts.end(); it++)
1935       (*it)->checkConsistency();
1936   else
1937     _m->checkConsistency();
1938 }
1939
1940 void MEDFileUMeshAggregateCompute::clearNonDiscrAttributes() const
1941 {
1942   for(std::vector< MCAuto<MEDCoupling1GTUMesh> >::const_iterator it=_m_parts.begin();it!=_m_parts.end();it++)
1943     MEDFileUMeshSplitL1::ClearNonDiscrAttributes(*it);
1944   MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_m);
1945 }
1946
1947 void MEDFileUMeshAggregateCompute::synchronizeTinyInfo(const MEDFileMesh& master) const
1948 {
1949   for(std::vector< MCAuto<MEDCoupling1GTUMesh> >::const_iterator it=_m_parts.begin();it!=_m_parts.end();it++)
1950     {
1951       const MEDCoupling1GTUMesh *tmp(*it);
1952       if(tmp)
1953         {
1954           (const_cast<MEDCoupling1GTUMesh *>(tmp))->setName(master.getName().c_str());
1955           (const_cast<MEDCoupling1GTUMesh *>(tmp))->setDescription(master.getDescription().c_str());
1956           (const_cast<MEDCoupling1GTUMesh *>(tmp))->setTime(master.getTimeValue(),master.getIteration(),master.getOrder());
1957           (const_cast<MEDCoupling1GTUMesh *>(tmp))->setTimeUnit(master.getTimeUnit());
1958         }
1959     }
1960   const MEDCouplingUMesh *m(_m);
1961   if(m)
1962     {
1963       (const_cast<MEDCouplingUMesh *>(m))->setName(master.getName().c_str());
1964       (const_cast<MEDCouplingUMesh *>(m))->setDescription(master.getDescription().c_str());
1965       (const_cast<MEDCouplingUMesh *>(m))->setTime(master.getTimeValue(),master.getIteration(),master.getOrder());
1966       (const_cast<MEDCouplingUMesh *>(m))->setTimeUnit(master.getTimeUnit());
1967     }
1968 }
1969
1970 bool MEDFileUMeshAggregateCompute::empty() const
1971 {
1972   if(_mp_time<_m_time)
1973     return ((const MEDCouplingUMesh *)_m)==0;
1974   //else _mp_time>=_m_time)
1975   return _m_parts.empty();
1976 }
1977
1978 int MEDFileUMeshAggregateCompute::getMeshDimension() const
1979 {
1980   if(_mp_time<_m_time)
1981     {
1982       const MEDCouplingUMesh *m(_m);
1983       if(!m)
1984         throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getMeshDimension : no umesh in this !");
1985       return m->getMeshDimension();
1986     }
1987   else
1988     {
1989       if(_m_parts.empty())
1990         throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getMeshDimension : part mesh is empty !");
1991       const MEDCoupling1GTUMesh *m(_m_parts[0]);
1992       if(!m)
1993         throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getMeshDimension : part mesh contains null instance !");
1994       return m->getMeshDimension();
1995     }
1996 }
1997
1998 std::vector<int> MEDFileUMeshAggregateCompute::getDistributionOfTypes() const
1999 {
2000   if(_mp_time<_m_time)
2001     {
2002       const MEDCouplingUMesh *m(_m);
2003       if(!m)
2004         throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getDistributionOfTypes : no umesh in this !");
2005       return m->getDistributionOfTypes();
2006     }
2007   else
2008     {
2009       std::vector<int> ret;
2010       for(std::vector< MCAuto<MEDCoupling1GTUMesh> >::const_iterator it=_m_parts.begin();it!=_m_parts.end();it++)
2011         {
2012           const MEDCoupling1GTUMesh *tmp(*it);
2013           if(!tmp)
2014             throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getDistributionOfTypes : part mesh contains null instance !");
2015           std::vector<int> ret0(tmp->getDistributionOfTypes());
2016           ret.insert(ret.end(),ret0.begin(),ret0.end());
2017         }
2018       return ret;
2019     }
2020 }
2021
2022 int MEDFileUMeshAggregateCompute::getSize() const
2023 {
2024   if(_mp_time<_m_time)
2025     {
2026       const MEDCouplingUMesh *m(_m);
2027       if(!m)
2028         throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getSize : no umesh in this !");
2029       return m->getNumberOfCells();
2030     }
2031   else
2032     {
2033       int ret=0;
2034       for(std::vector< MCAuto<MEDCoupling1GTUMesh> >::const_iterator it=_m_parts.begin();it!=_m_parts.end();it++)
2035         {
2036           const MEDCoupling1GTUMesh *m(*it);
2037           if(!m)
2038             throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getSize : part mesh contains null instance !");
2039           ret+=m->getNumberOfCells();
2040         }
2041       return ret;
2042     }
2043 }
2044
2045 void MEDFileUMeshAggregateCompute::setCoords(DataArrayDouble *coords)
2046 {
2047   for(std::vector< MCAuto<MEDCoupling1GTUMesh> >::iterator it=_m_parts.begin();it!=_m_parts.end();it++)
2048     {
2049       MEDCoupling1GTUMesh *tmp(*it);
2050       if(tmp)
2051         (*it)->setCoords(coords);
2052     }
2053   MEDCouplingUMesh *m(_m);
2054   if(m)
2055     m->setCoords(coords);
2056 }