Back to index

salome-med  6.5.0
MEDFileMeshLL.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D
00002 //
00003 // This library is free software; you can redistribute it and/or
00004 // modify it under the terms of the GNU Lesser General Public
00005 // License as published by the Free Software Foundation; either
00006 // version 2.1 of the License.
00007 //
00008 // This library is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011 // Lesser General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU Lesser General Public
00014 // License along with this library; if not, write to the Free Software
00015 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00016 //
00017 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00018 //
00019 
00020 #include "MEDFileMeshLL.hxx"
00021 #include "MEDFileMesh.hxx"
00022 #include "MEDLoaderBase.hxx"
00023 
00024 #include "MEDCouplingUMesh.hxx"
00025 
00026 #include "InterpKernelAutoPtr.hxx"
00027 #include "CellModel.hxx"
00028 
00029 #include <set>
00030 
00031 extern med_geometry_type typmai[MED_N_CELL_FIXED_GEO];
00032 extern INTERP_KERNEL::NormalizedCellType typmai2[MED_N_CELL_FIXED_GEO];
00033 extern med_geometry_type typmainoeud[1];
00034 
00035 using namespace ParaMEDMEM;
00036 
00037 MEDFileMeshL2::MEDFileMeshL2():_name(MED_NAME_SIZE),_description(MED_COMMENT_SIZE),_dt_unit(MED_LNAME_SIZE)
00038 {
00039 }
00040 
00041 int MEDFileMeshL2::GetMeshIdFromName(med_idt fid, const char *mname, ParaMEDMEM::MEDCouplingMeshType& meshType, int& dt, int& it, std::string& dtunit1) throw(INTERP_KERNEL::Exception)
00042 {
00043   med_mesh_type type_maillage;
00044   char maillage_description[MED_COMMENT_SIZE+1];
00045   char dtunit[MED_LNAME_SIZE+1];
00046   med_int spaceDim,dim;
00047   char nommaa[MED_NAME_SIZE+1];
00048   med_int n=MEDnMesh(fid);
00049   bool found=false;
00050   int ret=-1;
00051   med_sorting_type stype;
00052   std::vector<std::string> ms;
00053   int nstep;
00054   med_axis_type axistype;
00055   for(int i=0;i<n && !found;i++)
00056     {
00057       int naxis=MEDmeshnAxis(fid,i+1);
00058       INTERP_KERNEL::AutoPtr<char> axisname=MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE);
00059       INTERP_KERNEL::AutoPtr<char> axisunit=MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE);
00060       MEDmeshInfo(fid,i+1,nommaa,&spaceDim,&dim,&type_maillage,maillage_description,dtunit,&stype,&nstep,&axistype,axisname,axisunit);
00061       dtunit1=MEDLoaderBase::buildStringFromFortran(dtunit,sizeof(dtunit));
00062       std::string cur=MEDLoaderBase::buildStringFromFortran(nommaa,sizeof(nommaa));
00063       ms.push_back(cur);
00064       if(cur==mname)
00065         {
00066           found=true;
00067           ret=i+1;
00068         }
00069     }
00070   if(!found)
00071     {
00072       std::ostringstream oss;
00073       oss << "No such meshname (" << mname <<  ") in file ! Must be in :";
00074       std::copy(ms.begin(),ms.end(),std::ostream_iterator<std::string>(oss,", "));
00075       throw INTERP_KERNEL::Exception(oss.str().c_str());
00076     }
00077   switch(type_maillage)
00078     {
00079     case MED_UNSTRUCTURED_MESH:
00080       meshType=UNSTRUCTURED;
00081       break;
00082     case MED_STRUCTURED_MESH:
00083       meshType=CARTESIAN;
00084       break;
00085     default:
00086       throw INTERP_KERNEL::Exception("MEDFileUMeshL2::getMeshIdFromName : unrecognized mesh type !");
00087     }
00088   med_int numdt,numit;
00089   med_float dtt;
00090   MEDmeshComputationStepInfo(fid,mname,1,&numdt,&numit,&dtt);
00091   dt=numdt; it=numit;
00092   return ret;
00093 }
00094 
00095 double MEDFileMeshL2::CheckMeshTimeStep(med_idt fid, const char *mName, int nstep, int dt, int it) throw(INTERP_KERNEL::Exception)
00096 {
00097   bool found=false;
00098   med_int numdt,numit;
00099   med_float dtt;
00100   std::vector< std::pair<int,int> > p(nstep);
00101   for(int i=0;i<nstep;i++)
00102     {
00103       MEDmeshComputationStepInfo(fid,mName,i+1,&numdt,&numit,&dtt);
00104       p[i]=std::make_pair<int,int>(numdt,numit);
00105       found=(numdt==dt) && (numit==numit);
00106     }
00107   if(!found)
00108     {
00109       std::ostringstream oss; oss << "No such iteration=" << dt << ",order=" << it << " numbers found for mesh '" << mName << "' ! ";
00110       oss << "Possibilities are : ";
00111       for(int i=0;i<nstep;i++)
00112         oss << "(" << p[i].first << "," << p[i].second << "), ";
00113       throw INTERP_KERNEL::Exception(oss.str().c_str());
00114     }
00115   return dtt;
00116 }
00117 
00118 std::vector<std::string> MEDFileMeshL2::getAxisInfoOnMesh(med_idt fid, int mId, const char *mName, ParaMEDMEM::MEDCouplingMeshType& meshType, int& nstep, int& Mdim) throw(INTERP_KERNEL::Exception)
00119 {
00120   med_mesh_type type_maillage;
00121   med_int spaceDim;
00122   med_sorting_type stype;
00123   med_axis_type axistype;
00124   int naxis=MEDmeshnAxis(fid,mId);
00125   INTERP_KERNEL::AutoPtr<char> nameTmp=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
00126   INTERP_KERNEL::AutoPtr<char> axisname=MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE);
00127   INTERP_KERNEL::AutoPtr<char> axisunit=MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE);
00128   if(MEDmeshInfo(fid,mId,nameTmp,&spaceDim,&Mdim,&type_maillage,_description.getPointer(),_dt_unit.getPointer(),
00129                  &stype,&nstep,&axistype,axisname,axisunit)!=0)
00130     throw INTERP_KERNEL::Exception("A problem has been detected when trying to get info on mesh !");
00131   switch(type_maillage)
00132     {
00133     case MED_UNSTRUCTURED_MESH:
00134       meshType=UNSTRUCTURED;
00135       break;
00136     case MED_STRUCTURED_MESH:
00137       meshType=CARTESIAN;
00138       break;
00139     default:
00140       throw INTERP_KERNEL::Exception("MEDFileUMeshL2::getMeshIdFromName : unrecognized mesh type !");
00141     }
00142   //
00143   std::vector<std::string> infosOnComp(naxis);
00144   for(int i=0;i<naxis;i++)
00145     {
00146       std::string info=MEDLoaderBase::buildUnionUnit(((char *)axisname)+i*MED_SNAME_SIZE,MED_SNAME_SIZE,((char *)axisunit)+i*MED_SNAME_SIZE,MED_SNAME_SIZE);
00147       infosOnComp[i]=info;
00148     }
00149   return infosOnComp;
00150 }
00151 
00152 void MEDFileMeshL2::ReadFamiliesAndGrps(med_idt fid, const char *meshName, std::map<std::string,int>& fams, std::map<std::string, std::vector<std::string> >& grps)
00153 {
00154   char nomfam[MED_NAME_SIZE+1];
00155   med_int numfam;
00156   int nfam=MEDnFamily(fid,meshName);
00157   for(int i=0;i<nfam;i++)
00158     {
00159       int ngro=MEDnFamilyGroup(fid,meshName,i+1);
00160       med_int natt=MEDnFamily23Attribute(fid,meshName,i+1);
00161       INTERP_KERNEL::AutoPtr<med_int> attide=new med_int[natt];
00162       INTERP_KERNEL::AutoPtr<med_int> attval=new med_int[natt];
00163       INTERP_KERNEL::AutoPtr<char> attdes=new char[MED_COMMENT_SIZE*natt+1];
00164       INTERP_KERNEL::AutoPtr<char> gro=new char[MED_LNAME_SIZE*ngro+1];
00165       MEDfamily23Info(fid,meshName,i+1,nomfam,attide,attval,attdes,&numfam,gro);
00166       std::string famName=MEDLoaderBase::buildStringFromFortran(nomfam,MED_NAME_SIZE);
00167       fams[famName]=numfam;
00168       for(int j=0;j<ngro;j++)
00169         {
00170           std::string groupname=MEDLoaderBase::buildStringFromFortran(gro+j*MED_LNAME_SIZE,MED_LNAME_SIZE);
00171           grps[groupname].push_back(famName);
00172         }
00173     }
00174 }
00175 
00176 void MEDFileMeshL2::WriteFamiliesAndGrps(med_idt fid, const char *mname, const std::map<std::string,int>& fams, const std::map<std::string, std::vector<std::string> >& grps, int tooLongStrPol)
00177 {
00178   for(std::map<std::string,int>::const_iterator it=fams.begin();it!=fams.end();it++)
00179     {
00180       std::vector<std::string> grpsOfFam;
00181       for(std::map<std::string, std::vector<std::string> >::const_iterator it1=grps.begin();it1!=grps.end();it1++)
00182         {
00183           if(std::find((*it1).second.begin(),(*it1).second.end(),(*it).first)!=(*it1).second.end())
00184             grpsOfFam.push_back((*it1).first);
00185         }
00186       int ngro=grpsOfFam.size();
00187       INTERP_KERNEL::AutoPtr<char> groName=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE*ngro);
00188       int i=0;
00189       for(std::vector<std::string>::const_iterator it2=grpsOfFam.begin();it2!=grpsOfFam.end();it2++,i++)
00190         MEDLoaderBase::safeStrCpy2((*it2).c_str(),MED_LNAME_SIZE-1,groName+i*MED_LNAME_SIZE,tooLongStrPol);
00191       INTERP_KERNEL::AutoPtr<char> famName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
00192       MEDLoaderBase::safeStrCpy((*it).first.c_str(),MED_NAME_SIZE,famName,tooLongStrPol);
00193       int ret=MEDfamilyCr(fid,mname,famName,(*it).second,ngro,groName);
00194       ret++;
00195     }
00196 }
00197 
00198 MEDFileUMeshL2::MEDFileUMeshL2()
00199 {
00200 }
00201 
00202 void MEDFileUMeshL2::loadAll(med_idt fid, int mId, const char *mName, int dt, int it)
00203 {
00204   _name.set(mName);
00205   int nstep;
00206   int Mdim;
00207   ParaMEDMEM::MEDCouplingMeshType meshType;
00208   std::vector<std::string> infosOnComp=getAxisInfoOnMesh(fid,mId,mName,meshType,nstep,Mdim);
00209   if(meshType!=UNSTRUCTURED)
00210     throw INTERP_KERNEL::Exception("Invalid mesh type ! You are expected an unstructured one whereas in file it is not an unstructured !");
00211   _time=CheckMeshTimeStep(fid,mName,nstep,dt,it);
00212   _iteration=dt;
00213   _order=it;
00214   loadConnectivity(fid,Mdim,mName,dt,it);//to improve check (dt,it) coherency
00215   loadCoords(fid,mId,infosOnComp,mName,dt,it);
00216 }
00217 
00218 void MEDFileUMeshL2::loadConnectivity(med_idt fid, int mdim, const char *mName, int dt, int it)
00219 {
00220   _per_type_mesh.resize(1);
00221   _per_type_mesh[0].clear();
00222   for(int j=0;j<MED_N_CELL_FIXED_GEO;j++)
00223     {
00224       MEDFileUMeshPerType *tmp=MEDFileUMeshPerType::New(fid,mName,dt,it,mdim,typmai[j],typmai2[j]);
00225       if(tmp)
00226         _per_type_mesh[0].push_back(tmp);
00227     }
00228   sortTypes();
00229 }
00230 
00231 void MEDFileUMeshL2::loadCoords(med_idt fid, int mId, const std::vector<std::string>& infosOnComp, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception)
00232 {
00233   int spaceDim=infosOnComp.size();
00234   med_bool changement,transformation;
00235   int nCoords=MEDmeshnEntity(fid,mName,dt,it,MED_NODE,MED_NONE,MED_COORDINATE,MED_NO_CMODE,&changement,&transformation);
00236   _coords=DataArrayDouble::New();
00237   _coords->alloc(nCoords,spaceDim);
00238   double *coordsPtr=_coords->getPointer();
00239   MEDmeshNodeCoordinateRd(fid,mName,dt,it,MED_FULL_INTERLACE,coordsPtr);
00240   _fam_coords=DataArrayInt::New();
00241   _fam_coords->alloc(nCoords,1);
00242   _num_coords=DataArrayInt::New();
00243   _num_coords->alloc(nCoords,1);
00244   if(MEDmeshnEntity(fid,mName,dt,it,MED_NODE,MED_NO_GEOTYPE,MED_FAMILY_NUMBER,MED_NODAL,&changement,&transformation)>0)
00245     MEDmeshEntityFamilyNumberRd(fid,mName,dt,it,MED_NODE,MED_NO_GEOTYPE,_fam_coords->getPointer());
00246   else
00247     _fam_coords=0;
00248   if(MEDmeshnEntity(fid,mName,dt,it,MED_NODE,MED_NO_GEOTYPE,MED_NUMBER,MED_NODAL,&changement,&transformation)>0)
00249     MEDmeshEntityNumberRd(fid,mName,dt,it,MED_NODE,MED_NO_GEOTYPE,_num_coords->getPointer());
00250   else
00251     _num_coords=0;
00252   for(int i=0;i<spaceDim;i++)
00253     _coords->setInfoOnComponent(i,infosOnComp[i].c_str());
00254 }
00255 
00256 void MEDFileUMeshL2::sortTypes()
00257 {
00258   std::set<int> mdims;
00259   std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshPerType> > tmp(_per_type_mesh[0]);
00260   _per_type_mesh.clear();
00261   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshPerType> >::const_iterator it=tmp.begin();it!=tmp.end();it++)
00262     mdims.insert((*it)->getDim());
00263   if(mdims.empty())
00264     return;
00265   int mdim=*mdims.rbegin();
00266   _per_type_mesh.resize(mdim+1);
00267   for(int dim=mdim+1;dim!=0;dim--)
00268     {
00269       std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshPerType> >& elt=_per_type_mesh[mdim+1-dim];
00270       for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshPerType> >::const_iterator it=tmp.begin();it!=tmp.end();it++)
00271         if((*it)->getDim()==dim-1)
00272           elt.push_back(*it);
00273     }
00274   // suppression of contiguous empty levels at the end of _per_type_mesh.
00275   int nbOfUselessLev=0;
00276   bool isFirst=true;
00277   for(std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshPerType> > >::reverse_iterator it2=_per_type_mesh.rbegin();it2!=_per_type_mesh.rend();it2++)
00278     {
00279       if((*it2).empty() && isFirst)
00280         {
00281           nbOfUselessLev++;
00282         }
00283       else
00284         isFirst=false;
00285     }
00286   _per_type_mesh.resize(_per_type_mesh.size()-nbOfUselessLev);
00287 }
00288 
00289 void MEDFileUMeshL2::WriteCoords(med_idt fid, const char *mname, int dt, int it, double time, const DataArrayDouble *coords, const DataArrayInt *famCoords, const DataArrayInt *numCoords)
00290 {
00291   if(!coords)
00292     return ;
00293   MEDmeshNodeCoordinateWr(fid,mname,dt,it,time,MED_FULL_INTERLACE,coords->getNumberOfTuples(),coords->getConstPointer());
00294   if(famCoords)
00295     MEDmeshEntityFamilyNumberWr(fid,mname,dt,it,MED_NODE,MED_NO_GEOTYPE,famCoords->getNumberOfTuples(),famCoords->getConstPointer());
00296   if(numCoords)
00297     MEDmeshEntityNumberWr(fid,mname,dt,it,MED_NODE,MED_NO_GEOTYPE,numCoords->getNumberOfTuples(),numCoords->getConstPointer());
00298 }
00299 
00300 bool MEDFileUMeshL2::isFamDefinedOnLev(int levId) const
00301 {
00302   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshPerType> >::const_iterator it=_per_type_mesh[levId].begin();it!=_per_type_mesh[levId].end();it++)
00303     if((*it)->getFam()==0)
00304       return false;
00305   return true;
00306 }
00307 
00308 bool MEDFileUMeshL2::isNumDefinedOnLev(int levId) const
00309 {
00310   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshPerType> >::const_iterator it=_per_type_mesh[levId].begin();it!=_per_type_mesh[levId].end();it++)
00311     if((*it)->getNum()==0)
00312       return false;
00313   return true;
00314 }
00315 
00316 MEDFileCMeshL2::MEDFileCMeshL2()
00317 {
00318 }
00319 
00320 void MEDFileCMeshL2::loadAll(med_idt fid, int mId, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception)
00321 {
00322   _name.set(mName);
00323   int nstep;
00324   int Mdim;
00325   ParaMEDMEM::MEDCouplingMeshType meshType;
00326   std::vector<std::string> infosOnComp=getAxisInfoOnMesh(fid,mId,mName,meshType,nstep,Mdim);
00327   if(meshType!=CARTESIAN)
00328     throw INTERP_KERNEL::Exception("Invalid mesh type ! You are expected a structured one whereas in file it is not a structured !");
00329   _time=CheckMeshTimeStep(fid,mName,nstep,dt,it);
00330   _iteration=dt;
00331   _order=it;
00332   //
00333   med_grid_type gridtype;
00334   MEDmeshGridTypeRd(fid,mName,&gridtype);
00335   if(gridtype!=MED_CARTESIAN_GRID)
00336     throw INTERP_KERNEL::Exception("Invalid cartesion mesh type ! Only Cartesian Grid supported ! Curvilinear grid will come soon !");
00337   _cmesh=MEDCouplingCMesh::New();
00338   for(int i=0;i<Mdim;i++)
00339     {
00340       med_data_type dataTypeReq=GetDataTypeCorrespondingToSpaceId(i);
00341       med_bool chgt=MED_FALSE,trsf=MED_FALSE;
00342       int nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_NODE,MED_NONE,dataTypeReq,MED_NO_CMODE,&chgt,&trsf);
00343       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> da=DataArrayDouble::New();
00344       da->alloc(nbOfElt,1);
00345       da->setInfoOnComponent(0,infosOnComp[i].c_str());
00346       MEDmeshGridIndexCoordinateRd(fid,mName,dt,it,i+1,da->getPointer());
00347       _cmesh->setCoordsAt(i,da);
00348     }
00349 }
00350 
00351 med_data_type MEDFileCMeshL2::GetDataTypeCorrespondingToSpaceId(int id) throw(INTERP_KERNEL::Exception)
00352 {
00353   switch(id)
00354     {
00355     case 0:
00356       return MED_COORDINATE_AXIS1;
00357     case 1:
00358       return MED_COORDINATE_AXIS2;
00359     case 2:
00360       return MED_COORDINATE_AXIS3;
00361     default:
00362       throw INTERP_KERNEL::Exception("Invalid meshdim detected in Cartesian Grid !");
00363     }
00364 }
00365 
00366 MEDFileUMeshPermCompute::MEDFileUMeshPermCompute(const MEDFileUMeshSplitL1* st):_st(st),_mpt_time(0),_num_time(0)
00367 {
00368 }
00369 
00373 MEDFileUMeshPermCompute::operator MEDCouplingUMesh *() const
00374 {
00375   _st->_m_by_types->updateTime();
00376   _st->_num->updateTime();
00377   if((MEDCouplingUMesh *)_m==0)
00378     {
00379       updateTime();
00380       MEDCouplingUMesh *ret=(MEDCouplingUMesh *)_st->_m_by_types->deepCpy();
00381       _m=ret;
00382       _m->renumberCells(_st->_num->getConstPointer(),true);
00383       ret->incrRef();
00384       return ret;
00385     }
00386   else
00387     {
00388       if(_mpt_time==_st->_m_by_types->getTimeOfThis() && _num_time==_st->_num->getTimeOfThis())
00389         {
00390           _m->incrRef();
00391           return _m;
00392         }
00393       else
00394         {
00395           updateTime();
00396           MEDCouplingUMesh *ret=(MEDCouplingUMesh *)_st->_m_by_types->deepCpy();
00397           _m=ret;
00398           _m->renumberCells(_st->_num->getConstPointer(),true);
00399           ret->incrRef();
00400           return ret;
00401         }
00402     }
00403 }
00404 
00405 void MEDFileUMeshPermCompute::operator=(MEDCouplingUMesh *m)
00406 {
00407   _m=m;
00408 }
00409 
00410 void MEDFileUMeshPermCompute::updateTime() const
00411 {
00412   _mpt_time=_st->_m_by_types->getTimeOfThis();
00413   _num_time=_st->_num->getTimeOfThis();
00414 }
00415 
00416 MEDFileUMeshSplitL1::MEDFileUMeshSplitL1(const MEDFileUMeshL2& l2, const char *mName, int id):_m(this)
00417 {
00418   const std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshPerType> >& v=l2.getLev(id);
00419   if(v.empty())
00420     return;
00421   int sz=v.size();
00422   std::vector<const MEDCouplingUMesh *> ms(sz);
00423   for(int i=0;i<sz;i++)
00424     {
00425       MEDCouplingUMesh *tmp=MEDCouplingUMesh::New("",v[i]->getDim());
00426       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> tmp2=l2.getCoords();
00427       tmp->setCoords(tmp2);
00428       tmp->setConnectivity(const_cast<DataArrayInt *>(v[i]->getNodal()),const_cast<DataArrayInt *>(v[i]->getNodalIndex()));
00429       ms[i]=tmp;
00430     }
00431   _m_by_types=MEDCouplingUMesh::MergeUMeshesOnSameCoords(ms);
00432   _m_by_types->setName(mName);
00433   if(l2.isFamDefinedOnLev(id))
00434     {
00435       int nbOfCells=_m_by_types->getNumberOfCells();
00436       _fam=DataArrayInt::New();
00437       _fam->alloc(nbOfCells,1);
00438       int *w=_fam->getPointer();
00439       for(int i=0;i<sz;i++)
00440         w=std::copy(v[i]->getFam()->getConstPointer(),v[i]->getFam()->getConstPointer()+v[i]->getFam()->getNumberOfTuples(),w);
00441     }
00442   if(l2.isNumDefinedOnLev(id))
00443     {
00444       int nbOfCells=_m_by_types->getNumberOfCells();
00445       _num=DataArrayInt::New();
00446       _num->alloc(nbOfCells,1);
00447       int *w=_num->getPointer();
00448       for(int i=0;i<sz;i++)
00449         w=std::copy(v[i]->getNum()->getConstPointer(),v[i]->getNum()->getConstPointer()+v[i]->getNum()->getNumberOfTuples(),w);
00450       computeRevNum();
00451     }
00452   for(int i=0;i<sz;i++)
00453     (const_cast<MEDCouplingUMesh *>(ms[i]))->decrRef();//const cast under control to avoid a copy of array
00454 }
00455 
00456 MEDFileUMeshSplitL1::MEDFileUMeshSplitL1(MEDCouplingUMesh *m):_m(this)
00457 {
00458   assignMesh(m,true);
00459 }
00460 
00461 MEDFileUMeshSplitL1::MEDFileUMeshSplitL1(MEDCouplingUMesh *m, bool newOrOld):_m(this)
00462 {
00463   assignMesh(m,newOrOld);
00464 }
00465 
00466 bool MEDFileUMeshSplitL1::isEqual(const MEDFileUMeshSplitL1 *other, double eps, std::string& what) const
00467 {
00468   const MEDCouplingUMesh *m1=_m_by_types;
00469   const MEDCouplingUMesh *m2=other->_m_by_types;
00470   if((m1==0 && m2!=0) || (m1!=0 && m2==0))
00471     {
00472       what="Presence of mesh in one sublevel and not in other!";
00473       return false;
00474     }
00475   if(m1)
00476     if(!m1->isEqual(m2,eps))
00477       {
00478         what="meshes at a sublevel are not deeply equal !";
00479         return false;
00480       }
00481   const DataArrayInt *d1=_fam;
00482   const DataArrayInt *d2=other->_fam;
00483   if((d1==0 && d2!=0) || (d1!=0 && d2==0))
00484     {
00485       what="Presence of family arr in one sublevel and not in other!";
00486       return false;
00487     }
00488   if(d1)
00489     if(!d1->isEqual(*d2))
00490       {
00491         what="family arr at a sublevel are not deeply equal !";
00492         return false;
00493       }
00494   d1=_num;
00495   d2=other->_num;
00496   if((d1==0 && d2!=0) || (d1!=0 && d2==0))
00497     {
00498       what="Presence of cell numbering arr in one sublevel and not in other!";
00499       return false;
00500     }
00501   if(d1)
00502     if(!d1->isEqual(*d2))
00503       {
00504         what="Numbering cell arr at a sublevel are not deeply equal !";
00505         return false;
00506       }
00507   return true;
00508 }
00509 
00510 void MEDFileUMeshSplitL1::synchronizeTinyInfo(const MEDFileMesh& master) const
00511 {
00512   const MEDCouplingUMesh *tmp=_m_by_types;
00513   if(!tmp)
00514     return ;
00515   (const_cast<MEDCouplingUMesh *>(tmp))->setName(master.getName());
00516   (const_cast<MEDCouplingUMesh *>(tmp))->setDescription(master.getDescription());
00517   (const_cast<MEDCouplingUMesh *>(tmp))->setTime(master.getTimeValue(),master.getIteration(),master.getOrder());
00518   (const_cast<MEDCouplingUMesh *>(tmp))->setTimeUnit(master.getTimeUnit());
00519 }
00520 
00521 void MEDFileUMeshSplitL1::clearNonDiscrAttributes() const
00522 {
00523   ClearNonDiscrAttributes(_m_by_types);
00524 }
00525 
00526 void MEDFileUMeshSplitL1::ClearNonDiscrAttributes(const MEDCouplingMesh *tmp)
00527 {
00528   if(!tmp)
00529     return ;
00530   (const_cast<MEDCouplingMesh *>(tmp))->setName("");
00531   (const_cast<MEDCouplingMesh *>(tmp))->setDescription("");
00532   (const_cast<MEDCouplingMesh *>(tmp))->setTime(0.,-1,-1);
00533   (const_cast<MEDCouplingMesh *>(tmp))->setTimeUnit("");
00534 }
00535 
00536 void MEDFileUMeshSplitL1::assignMesh(MEDCouplingUMesh *m, bool newOrOld) throw(INTERP_KERNEL::Exception)
00537 {
00538   if(newOrOld)
00539     {
00540       m->incrRef();
00541       _m=m;
00542       _m_by_types=(MEDCouplingUMesh *)m->deepCpy();
00543       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da=_m_by_types->getRenumArrForConsecutiveCellTypesSpec(typmai2,typmai2+MED_N_CELL_FIXED_GEO);
00544       if(!da->isIdentity())
00545         {
00546           _num=da->invertArrayO2N2N2O(m->getNumberOfCells());
00547           _m.updateTime();
00548           computeRevNum();
00549           _m_by_types->renumberCells(da->getConstPointer(),false);
00550         }
00551     }
00552   else
00553     {
00554       if(!m->checkConsecutiveCellTypesAndOrder(typmai2,typmai2+MED_N_CELL_FIXED_GEO))
00555         throw INTERP_KERNEL::Exception("MEDFileUMeshSplitL1::assignMesh : the mode of mesh setting expects to follow the MED file numbering convention ! it is not the case !");
00556       m->incrRef();
00557       _m_by_types=m;
00558     }
00559   _fam=DataArrayInt::New();
00560   _fam->alloc(m->getNumberOfCells(),1);
00561   _fam->fillWithValue(0);
00562 }
00563 
00564 bool MEDFileUMeshSplitL1::empty() const
00565 {
00566   return ((const MEDCouplingUMesh *)_m_by_types)==0;
00567 }
00568 
00569 bool MEDFileUMeshSplitL1::presenceOfOneFams(const std::vector<int>& ids) const
00570 {
00571   const DataArrayInt *fam=_fam;
00572   if(!fam)
00573     return false;
00574   return fam->presenceOfValue(ids);
00575 }
00576 
00577 int MEDFileUMeshSplitL1::getMeshDimension() const
00578 {
00579   return _m_by_types->getMeshDimension();
00580 }
00581 
00582 void MEDFileUMeshSplitL1::simpleRepr(std::ostream& oss) const
00583 {
00584   std::vector<int> code=_m_by_types->getDistributionOfTypes();
00585   int nbOfTypes=code.size()/3;
00586   for(int i=0;i<nbOfTypes;i++)
00587     {
00588       INTERP_KERNEL::NormalizedCellType typ=(INTERP_KERNEL::NormalizedCellType) code[3*i];
00589       oss << "    - Number of cells with type " << INTERP_KERNEL::CellModel::GetCellModel(typ).getRepr() << " : " << code[3*i+1] << std::endl;
00590     }
00591 }
00592 
00593 int MEDFileUMeshSplitL1::getSize() const throw(INTERP_KERNEL::Exception)
00594 {
00595   if((const MEDCouplingUMesh *)_m_by_types==0)
00596     throw INTERP_KERNEL::Exception("MEDFileUMeshSplitL1::getSize : no mesh specified at level !");
00597   return _m_by_types->getNumberOfCells();
00598 }
00599 
00600 MEDCouplingUMesh *MEDFileUMeshSplitL1::getFamilyPart(const std::vector<int>& ids, bool renum) const
00601 {
00602   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> eltsToKeep=_fam->getIdsEqualList(ids);
00603   MEDCouplingUMesh *m=(MEDCouplingUMesh *)_m_by_types->buildPartOfMySelf(eltsToKeep->getConstPointer(),eltsToKeep->getConstPointer()+eltsToKeep->getNumberOfTuples(),true);
00604   if(renum)
00605     return renumIfNeeded(m,eltsToKeep->getConstPointer());
00606   return m;
00607 }
00608 
00609 DataArrayInt *MEDFileUMeshSplitL1::getFamilyPartArr(const std::vector<int>& ids, bool renum) const
00610 {
00611   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da=_fam->getIdsEqualList(ids);
00612   if(renum)
00613     return renumIfNeededArr(da);
00614   da->incrRef();
00615   return da;
00616 }
00617 
00618 MEDCouplingUMesh *MEDFileUMeshSplitL1::getWholeMesh(bool renum) const
00619 {
00620   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp;
00621   if(renum)
00622     tmp=_m;
00623   else
00624     tmp=_m_by_types;
00625   tmp->incrRef();
00626   return tmp;
00627 }
00628 
00629 const DataArrayInt *MEDFileUMeshSplitL1::getFamilyField() const
00630 {
00631   return _fam;
00632 }
00633 
00634 const DataArrayInt *MEDFileUMeshSplitL1::getNumberField() const
00635 {
00636   return _num;
00637 }
00638 
00639 const DataArrayInt *MEDFileUMeshSplitL1::getRevNumberField() const
00640 {
00641   return _rev_num;
00642 }
00643 
00644 void MEDFileUMeshSplitL1::eraseFamilyField()
00645 {
00646   _fam->fillWithZero();
00647 }
00648 
00652 void MEDFileUMeshSplitL1::setGroupsFromScratch(const std::vector<const MEDCouplingUMesh *>& ms, std::map<std::string,int>& familyIds,
00653                                                std::map<std::string, std::vector<std::string> >& groups) throw(INTERP_KERNEL::Exception)
00654 {
00655   int sz=ms.size();
00656   std::vector< DataArrayInt * > corr;
00657   _m=MEDCouplingUMesh::FuseUMeshesOnSameCoords(ms,0,corr);
00658   std::vector< std::vector<int> > fidsOfGroups;
00659   std::vector< const DataArrayInt * > corr2(corr.begin(),corr.end());
00660   _fam=DataArrayInt::MakePartition(corr2,((MEDCouplingUMesh *)_m)->getNumberOfCells(),fidsOfGroups);
00661   int nbOfCells=((MEDCouplingUMesh *)_m)->getNumberOfCells();
00662   std::map<int,std::string> newfams;
00663   std::map<int,int> famIdTrad;
00664   TraduceFamilyNumber(fidsOfGroups,familyIds,famIdTrad,newfams);
00665   for(int i=0;i<sz;i++)
00666     corr[i]->decrRef();
00667   int *w=_fam->getPointer();
00668   for(int i=0;i<nbOfCells;i++,w++)
00669     *w=famIdTrad[*w];
00670 }
00671 
00672 void MEDFileUMeshSplitL1::write(med_idt fid, const char *mName, int mdim) const
00673 {
00674   std::vector<MEDCouplingUMesh *> ms=_m_by_types->splitByType();
00675   int start=0;
00676   for(std::vector<MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
00677     {
00678       int nbCells=(*it)->getNumberOfCells();
00679       int end=start+nbCells;
00680       DataArrayInt *fam=0,*num=0;
00681       if((const DataArrayInt *)_fam)
00682         fam=_fam->substr(start,end);
00683       if((const DataArrayInt *)_num)
00684         num=_num->substr(start,end);
00685       MEDFileUMeshPerType::write(fid,mName,mdim,(*it),fam,num);
00686       if(fam)
00687         fam->decrRef();
00688       if(num)
00689         num->decrRef();
00690       (*it)->decrRef();
00691       start=end;
00692     }
00693 }
00694 
00695 void MEDFileUMeshSplitL1::changeFamilyIdArr(int oldId, int newId) throw(INTERP_KERNEL::Exception)
00696 {
00697   DataArrayInt *arr=_fam;
00698   if(arr)
00699     arr->changeValue(oldId,newId);
00700 }
00701 
00702 void MEDFileUMeshSplitL1::setFamilyArr(DataArrayInt *famArr)
00703 {
00704   famArr->incrRef();
00705   _fam=famArr;
00706 }
00707 
00708 void MEDFileUMeshSplitL1::setRenumArr(DataArrayInt *renumArr)
00709 {
00710   renumArr->incrRef();
00711   _num=renumArr;
00712   computeRevNum();
00713 }
00714 
00715 MEDCouplingUMesh *MEDFileUMeshSplitL1::Renumber2(const DataArrayInt *renum, MEDCouplingUMesh *m, const int *cellIds)
00716 {
00717   if(renum==0)
00718     return m;
00719   if(cellIds==0)
00720     m->renumberCells(renum->getConstPointer(),true);
00721   else
00722     {
00723       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> locnum=renum->selectByTupleId(cellIds,cellIds+m->getNumberOfCells());
00724       m->renumberCells(locnum->getConstPointer(),true);
00725     }
00726   return m;
00727 }
00728 
00729 MEDCouplingUMesh *MEDFileUMeshSplitL1::renumIfNeeded(MEDCouplingUMesh *m, const int *cellIds) const
00730 {
00731   return Renumber2(_num,m,cellIds);
00732 }
00733 
00734 DataArrayInt *MEDFileUMeshSplitL1::Renumber(const DataArrayInt *renum, const DataArrayInt *da)
00735 {
00736   if((const DataArrayInt *)renum==0)
00737     {
00738       da->incrRef();
00739       return const_cast<DataArrayInt *>(da);
00740     }
00741   return renum->selectByTupleId(da->getConstPointer(),da->getConstPointer()+da->getNumberOfTuples());
00742 }
00743 
00744 DataArrayInt *MEDFileUMeshSplitL1::renumIfNeededArr(const DataArrayInt *da) const
00745 {
00746   return Renumber(_num,da);
00747 }
00748 
00749 std::vector<int> MEDFileUMeshSplitL1::GetNewFamiliesNumber(int nb, const std::map<std::string,int>& families)
00750 {
00751   int id=-1;
00752   for(std::map<std::string,int>::const_iterator it=families.begin();it!=families.end();it++)
00753     id=std::max(id,(*it).second);
00754   if(id==-1)
00755     id=0;
00756   std::vector<int> ret(nb);
00757   for(int i=1;i<=nb;i++)
00758     ret[i]=id+i;
00759   return ret;
00760 }
00761 
00762 void MEDFileUMeshSplitL1::TraduceFamilyNumber(const std::vector< std::vector<int> >& fidsGrps, std::map<std::string,int>& familyIds,
00763                                               std::map<int,int>& famIdTrad, std::map<int,std::string>& newfams)
00764 {
00765   std::set<int> allfids;
00766   
00767 }
00768 
00769 void MEDFileUMeshSplitL1::computeRevNum() const
00770 {
00771   int pos;
00772   int maxValue=_num->getMaxValue(pos);
00773   _rev_num=_num->invertArrayN2O2O2N(maxValue+1);
00774 }