]> SALOME platform Git repositories - tools/medcoupling.git/commitdiff
Salome HOME
Some new functionalities
authorageay <ageay>
Wed, 11 Mar 2009 17:55:43 +0000 (17:55 +0000)
committerageay <ageay>
Wed, 11 Mar 2009 17:55:43 +0000 (17:55 +0000)
src/ParaMEDMEM/MEDLoader/MEDLoader.cxx
src/ParaMEDMEM/MEDLoader/MEDLoader.hxx

index 2cabfb740fa6368c8e4d36a8a1d9226c329158b2..e6f2b517873ee3754a396f405ede4eac4d04b2c1 100644 (file)
@@ -21,6 +21,7 @@
 #include "ParaMESH.hxx"
 #include "BlockTopology.hxx"
 #include "MEDCouplingUMesh.hxx"
+#include "MEDCouplingFieldDouble.hxx"
 
 extern "C"
 {
@@ -31,46 +32,61 @@ extern "C"
 #include <cstring>
 #include <sstream>
 #include <fstream>
+#include <iterator>
+#include <algorithm>
+#include <numeric>
 
-med_geometrie_element typmai[MED_NBR_GEOMETRIE_MAILLE] = { MED_POINT1,
-                                                           MED_SEG2,
-                                                           MED_SEG3,
-                                                           MED_TRIA3,
-                                                           MED_TRIA6,
-                                                           MED_QUAD4,
-                                                           MED_QUAD8,
-                                                           MED_TETRA4,
-                                                           MED_TETRA10,
-                                                           MED_HEXA8,
-                                                           MED_HEXA20,
-                                                           MED_PENTA6,
-                                                           MED_PENTA15,
-                                                           MED_PYRA5,
-                                                           MED_PYRA13 };
-
-INTERP_KERNEL::NormalizedCellType typmai2[MED_NBR_GEOMETRIE_MAILLE] = { INTERP_KERNEL::NORM_ERROR,
-                                                                        INTERP_KERNEL::NORM_SEG2,
-                                                                        INTERP_KERNEL::NORM_SEG3,
-                                                                        INTERP_KERNEL::NORM_TRI3,
-                                                                        INTERP_KERNEL::NORM_TRI6,
-                                                                        INTERP_KERNEL::NORM_QUAD4,
-                                                                        INTERP_KERNEL::NORM_QUAD8,
-                                                                        INTERP_KERNEL::NORM_TETRA4,
-                                                                        INTERP_KERNEL::NORM_TETRA10,
-                                                                        INTERP_KERNEL::NORM_HEXA8,
-                                                                        INTERP_KERNEL::NORM_HEXA20,
-                                                                        INTERP_KERNEL::NORM_PENTA6,
-                                                                        INTERP_KERNEL::NORM_PENTA15,
-                                                                        INTERP_KERNEL::NORM_PYRA5,
-                                                                        INTERP_KERNEL::NORM_PYRA13 };
+med_geometrie_element typmai[MED_NBR_GEOMETRIE_MAILLE+2] = { MED_POINT1,
+                                                             MED_SEG2,
+                                                             MED_SEG3,
+                                                             MED_TRIA3,
+                                                             MED_TRIA6,
+                                                             MED_QUAD4,
+                                                             MED_QUAD8,
+                                                             MED_TETRA4,
+                                                             MED_TETRA10,
+                                                             MED_HEXA8,
+                                                             MED_HEXA20,
+                                                             MED_PENTA6,
+                                                             MED_PENTA15,
+                                                             MED_PYRA5,
+                                                             MED_PYRA13,
+                                                             MED_POLYGONE,
+                                                             MED_POLYEDRE };
+
+med_geometrie_element typmainoeud[1] = { MED_NONE };
+
+INTERP_KERNEL::NormalizedCellType typmai2[MED_NBR_GEOMETRIE_MAILLE+2] = { INTERP_KERNEL::NORM_ERROR,
+                                                                          INTERP_KERNEL::NORM_SEG2,
+                                                                          INTERP_KERNEL::NORM_SEG3,
+                                                                          INTERP_KERNEL::NORM_TRI3,
+                                                                          INTERP_KERNEL::NORM_TRI6,
+                                                                          INTERP_KERNEL::NORM_QUAD4,
+                                                                          INTERP_KERNEL::NORM_QUAD8,
+                                                                          INTERP_KERNEL::NORM_TETRA4,
+                                                                          INTERP_KERNEL::NORM_TETRA10,
+                                                                          INTERP_KERNEL::NORM_HEXA8,
+                                                                          INTERP_KERNEL::NORM_HEXA20,
+                                                                          INTERP_KERNEL::NORM_PENTA6,
+                                                                          INTERP_KERNEL::NORM_PENTA15,
+                                                                          INTERP_KERNEL::NORM_PYRA5,
+                                                                          INTERP_KERNEL::NORM_PYRA13,
+                                                                          INTERP_KERNEL::NORM_POLYGON,
+                                                                          INTERP_KERNEL::NORM_POLYHED };
 
 using namespace ParaMEDMEM;
 
 const char WHITE_SPACES[]=" \n";
 
-MEDLoader::MEDConnOfOneElemType::MEDConnOfOneElemType(INTERP_KERNEL::NormalizedCellType type, int *conn, int lgth):_lgth(lgth),
-                                                                                                                   _conn(conn),_global(0),
-                                                                                                                   _type(type)
+/*!
+ * @param lgth is the size of fam tab. For classical types conn is size of 'lgth'*number_of_nodes_in_type.
+ * @param index is optionnal only for polys. Set it to 0 if it is not the case.
+ * @param connLgth is the size of conn in the case of poly. Unsued if it is not the case.
+ */
+MEDLoader::MEDConnOfOneElemType::MEDConnOfOneElemType(INTERP_KERNEL::NormalizedCellType type, int *conn, int *index, int *fam, int lgth, int connLgth):_lgth(lgth),_fam(fam),
+                                                                                                                                                       _conn(conn),_index(index),
+                                                                                                                                                       _global(0),_type(type),
+                                                                                                                                                       _conn_lgth(connLgth)
 {
 }
 
@@ -86,10 +102,21 @@ void MEDLoader::MEDConnOfOneElemType::setGlobal(int *global)
 
 void MEDLoader::MEDConnOfOneElemType::releaseArray()
 {
+  delete [] _fam;
   delete [] _conn;
+  delete [] _index;
   delete [] _global;
 }
 
+MEDLoader::MEDFieldDoublePerCellType::MEDFieldDoublePerCellType(INTERP_KERNEL::NormalizedCellType type, double *values, int ncomp, int nval):_nval(nval),_ncomp(ncomp),_values(values),_type(type)
+{
+}
+
+void MEDLoader::MEDFieldDoublePerCellType::releaseArray()
+{
+  delete [] _values;
+}
+
 std::string buildStringFromFortran(const char *expr, int lgth)
 {
   std::string ret(expr,lgth);
@@ -106,29 +133,407 @@ std::string buildStringFromFortran(const char *expr, int lgth)
 
 namespace MEDLoader
 {
-  med_int getIdFromMeshName(med_idt fid, const char *meshName) throw(INTERP_KERNEL::Exception)
+  std::vector<std::string> getMeshNamesFid(med_idt fid)
   {
-    if(meshName==0)
-      return 1;
-    med_int n=MEDnMaa(fid);
-    if(n==0)
-      throw INTERP_KERNEL::Exception("No mesh in file.");
     med_maillage type_maillage;
     char maillage_description[MED_TAILLE_DESC+1];
     med_int dim;
     char nommaa[MED_TAILLE_NOM+1];
-    std::ostringstream os;
-    for(med_int i=1;i<=n;i++)
+    med_int n=MEDnMaa(fid);
+    std::vector<std::string> ret(n);
+    for(int i=0;i<n;i++)
       {
-        MEDmaaInfo(fid,i,nommaa,&dim,&type_maillage,maillage_description);
+        MEDmaaInfo(fid,i+1,nommaa,&dim,&type_maillage,maillage_description);
         std::string cur=buildStringFromFortran(nommaa,sizeof(nommaa));
-        if(cur==meshName)
-          return i;
-        os << "\'" << cur.c_str() << "\' "; 
+        ret[i]=cur;
+      }
+    return ret;
+  }
+
+  std::vector<std::string> GetMeshNames(const char *fileName)
+  {
+    med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE);
+    std::vector<std::string> ret=getMeshNamesFid(fid);
+    MEDfermer(fid);
+    return ret;
+  }
+
+  std::vector<std::string> GetMeshFamilyNames(const char *fileName, const char *meshName)
+  {
+    med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE);
+    med_int nfam=MEDnFam(fid,(char *)meshName);
+    std::vector<std::string> ret(nfam);
+    char nomfam[MED_TAILLE_NOM+1];
+    med_int numfam;
+    for(int i=0;i<nfam;i++)
+      {
+        int ngro=MEDnGroupe(fid,(char *)meshName,i+1);
+        med_int natt=MEDnAttribut(fid,(char *)meshName,i+1);
+        med_int *attide=new int[natt];
+        med_int *attval=new int[natt];
+        char *attdes=new char[MED_TAILLE_DESC*natt+1];
+        char *gro=new char[MED_TAILLE_LNOM*ngro+1];
+        MEDfamInfo(fid,(char *)meshName,i+1,nomfam,&numfam,attide,attval,attdes,&natt,gro,&ngro);
+        std::string cur=buildStringFromFortran(nomfam,sizeof(nomfam));
+        ret[i]=cur;
+        delete [] attdes;
+        delete [] gro;
+        delete [] attide;
+        delete [] attval;
+      }
+    MEDfermer(fid);
+    return ret;
+  }
+  
+  std::vector<std::string> GetMeshGroupsNames(const char *fileName, const char *meshName)
+  {
+    med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE);
+    med_int nfam=MEDnFam(fid,(char *)meshName);
+    std::vector<std::string> ret;
+    char nomfam[MED_TAILLE_NOM+1];
+    med_int numfam;
+    for(int i=0;i<nfam;i++)
+      {
+        int ngro=MEDnGroupe(fid,(char *)meshName,i+1);
+        med_int natt=MEDnAttribut(fid,(char *)meshName,i+1);
+        med_int *attide=new int[natt];
+        med_int *attval=new int[natt];
+        char *attdes=new char[MED_TAILLE_DESC*natt+1];
+        char *gro=new char[MED_TAILLE_LNOM*ngro+1];
+        MEDfamInfo(fid,(char *)meshName,i+1,nomfam,&numfam,attide,attval,attdes,&natt,gro,&ngro);
+       for(int j=0;j<ngro;j++)
+         {
+           std::string cur=buildStringFromFortran(gro+j*MED_TAILLE_LNOM,MED_TAILLE_LNOM);
+           if(std::find(ret.begin(),ret.end(),cur)==ret.end())
+             ret.push_back(cur);
+         }
+        delete [] attdes;
+        delete [] gro;
+        delete [] attide;
+        delete [] attval;
+      }
+    MEDfermer(fid);
+    return ret;
+  }
+
+  std::vector<std::string> GetCellFieldNamesOnMesh(const char *fileName, const char *meshName)
+  {
+    std::vector<std::string> ret;
+    med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE);
+    med_int nbFields=MEDnChamp(fid,0);
+    //
+    med_type_champ typcha;
+    //med_int nbpdtnor=0,pflsize,*pflval,lnsize;
+    med_int ngauss=0;
+    med_int numdt=0,numo=0,nbrefmaa;
+    med_float dt=0.0;
+    med_booleen local;
+    //char pflname[MED_TAILLE_NOM+1]="";
+    //char locname[MED_TAILLE_NOM+1]="";
+    char maa_ass[MED_TAILLE_NOM+1]="";
+    char dt_unit[MED_TAILLE_PNOM+1]="";
+    char nomcha[MED_TAILLE_NOM+1]="";
+    //
+    for(int i=0;i<nbFields;i++)
+      {
+        med_int ncomp=MEDnChamp(fid,i+1);
+        char *comp=new char[ncomp*MED_TAILLE_PNOM+1];
+        char *unit=new char[ncomp*MED_TAILLE_PNOM+1];
+        MEDchampInfo(fid,i+1,nomcha,&typcha,comp,unit,ncomp);
+        std::string curFieldName=buildStringFromFortran(nomcha,MED_TAILLE_NOM+1);
+        delete [] comp;
+        delete [] unit;
+        bool found=false;
+        for(int j=0;j<MED_NBR_GEOMETRIE_MAILLE+2 && !found;j++)
+          {
+            med_int nbPdt=MEDnPasdetemps(fid,nomcha,MED_MAILLE,typmai[j]);
+            if(nbPdt>0)
+              {
+                MEDpasdetempsInfo(fid,nomcha,MED_MAILLE,typmai[j],1, &ngauss, &numdt, &numo, dt_unit,&dt, maa_ass, &local, &nbrefmaa);
+                std::string curMeshName=buildStringFromFortran(maa_ass,MED_TAILLE_NOM+1);
+                if(curMeshName==meshName)
+                  {
+                    found=true;
+                    ret.push_back(curFieldName);
+                  }
+              }
+          }
+      }
+    MEDfermer(fid);
+    return ret;
+  }
+
+  std::vector<std::string> GetNodeFieldNamesOnMesh(const char *fileName, const char *meshName)
+  {
+        std::vector<std::string> ret;
+    med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE);
+    med_int nbFields=MEDnChamp(fid,0);
+    //
+    med_type_champ typcha;
+    med_int ngauss=0;
+    med_int numdt=0,numo=0,nbrefmaa;
+    med_float dt=0.0;
+    med_booleen local;
+    char maa_ass[MED_TAILLE_NOM+1]="";
+    char dt_unit[MED_TAILLE_PNOM+1]="";
+    char nomcha[MED_TAILLE_NOM+1]="";
+    //
+    for(int i=0;i<nbFields;i++)
+      {
+        med_int ncomp=MEDnChamp(fid,i+1);
+        char *comp=new char[ncomp*MED_TAILLE_PNOM+1];
+        char *unit=new char[ncomp*MED_TAILLE_PNOM+1];
+        MEDchampInfo(fid,i+1,nomcha,&typcha,comp,unit,ncomp);
+        std::string curFieldName=buildStringFromFortran(nomcha,MED_TAILLE_NOM+1);
+        delete [] comp;
+        delete [] unit;
+        bool found=false;
+        med_int nbPdt=MEDnPasdetemps(fid,nomcha,MED_NOEUD,MED_NONE);
+        if(nbPdt>0)
+          {
+            MEDpasdetempsInfo(fid,nomcha,MED_NOEUD,MED_NONE,1, &ngauss, &numdt, &numo, dt_unit,&dt, maa_ass, &local, &nbrefmaa);
+            std::string curMeshName=buildStringFromFortran(maa_ass,MED_TAILLE_NOM+1);
+            if(curMeshName==meshName)
+              {
+                found=true;
+                ret.push_back(curFieldName);
+              }
+          }
+      }
+    MEDfermer(fid);
+    return ret;
+  }
+
+  std::vector< std::pair<int,int> > GetCellFieldIterations(const char *fileName, const char *fieldName)
+  {
+    std::vector< std::pair<int,int> > ret;
+    med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE);
+    med_int nbFields=MEDnChamp(fid,0);
+    //
+    med_type_champ typcha;
+    med_int ngauss=0;
+    med_int numdt=0,numo=0,nbrefmaa;
+    med_float dt=0.0;
+    med_booleen local;
+    char maa_ass[MED_TAILLE_NOM+1]="";
+    char dt_unit[MED_TAILLE_PNOM+1]="";
+    char nomcha[MED_TAILLE_NOM+1]="";
+    //
+    for(int i=0;i<nbFields;i++)
+      {
+        med_int ncomp=MEDnChamp(fid,i+1);
+        char *comp=new char[ncomp*MED_TAILLE_PNOM+1];
+        char *unit=new char[ncomp*MED_TAILLE_PNOM+1];
+        MEDchampInfo(fid,i+1,nomcha,&typcha,comp,unit,ncomp);
+        std::string curFieldName=buildStringFromFortran(nomcha,MED_TAILLE_NOM+1);
+        delete [] comp;
+        delete [] unit;
+        if(curFieldName==fieldName)
+          {
+            bool found=false;
+            for(int j=0;j<MED_NBR_GEOMETRIE_MAILLE+2 && !found;j++)
+              {
+                med_int nbPdt=MEDnPasdetemps(fid,nomcha,MED_MAILLE,typmai[j]);
+                for(int k=0;k<nbPdt;k++)
+                  {
+                    MEDpasdetempsInfo(fid,nomcha,MED_MAILLE,typmai[j],k+1, &ngauss, &numdt, &numo, dt_unit,&dt, maa_ass, &local, &nbrefmaa);
+                    found=true;
+                    ret.push_back(std::make_pair(numdt,numo));
+                  }
+              }
+          }
+      }
+    MEDfermer(fid);
+    return ret;
+  }
+
+  std::vector< std::pair<int,int> > GetNodeFieldIterations(const char *fileName, const char *fieldName)
+  {
+    std::vector< std::pair<int,int> > ret;
+    med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE);
+    med_int nbFields=MEDnChamp(fid,0);
+    //
+    med_type_champ typcha;
+    med_int ngauss=0;
+    med_int numdt=0,numo=0,nbrefmaa;
+    med_float dt=0.0;
+    med_booleen local;
+    char maa_ass[MED_TAILLE_NOM+1]="";
+    char dt_unit[MED_TAILLE_PNOM+1]="";
+    char nomcha[MED_TAILLE_NOM+1]="";
+    //
+    for(int i=0;i<nbFields;i++)
+      {
+        med_int ncomp=MEDnChamp(fid,i+1);
+        char *comp=new char[ncomp*MED_TAILLE_PNOM+1];
+        char *unit=new char[ncomp*MED_TAILLE_PNOM+1];
+        MEDchampInfo(fid,i+1,nomcha,&typcha,comp,unit,ncomp);
+        std::string curFieldName=buildStringFromFortran(nomcha,MED_TAILLE_NOM+1);
+        delete [] comp;
+        delete [] unit;
+        if(curFieldName==fieldName)
+          {
+            med_int nbPdt=MEDnPasdetemps(fid,nomcha,MED_NOEUD,MED_NONE);
+            for(int k=0;k<nbPdt;k++)
+              {
+                MEDpasdetempsInfo(fid,nomcha,MED_NOEUD,MED_NONE,k+1, &ngauss, &numdt, &numo, dt_unit,&dt, maa_ass, &local, &nbrefmaa);
+                ret.push_back(std::make_pair(numdt,numo));
+              }
+          }
+      }
+    MEDfermer(fid);
+    return ret;
+  }
+
+  void readFieldDoubleDataInMedFile(const char *fileName, const char *meshName, const char *fieldName, std::list<MEDLoader::MEDFieldDoublePerCellType>& field,
+                                    int iteration, int order, ParaMEDMEM::TypeOfField typeOfOutField, double& time)
+  {
+    time=0.;
+    med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE);
+    med_int nbFields=MEDnChamp(fid,0);
+    //
+    med_type_champ typcha;
+    char nomcha[MED_TAILLE_NOM+1]="";
+    char pflname [MED_TAILLE_NOM+1]="";
+    char locname [MED_TAILLE_NOM+1]="";
+    std::map<ParaMEDMEM::TypeOfField, med_entite_maillage> tabEnt;
+    std::map<ParaMEDMEM::TypeOfField, med_geometrie_element *> tabType;
+    std::map<ParaMEDMEM::TypeOfField, int> tabTypeLgth;
+    tabEnt[ON_CELLS]=MED_MAILLE;
+    tabType[ON_CELLS]=typmai;
+    tabTypeLgth[ON_CELLS]=MED_NBR_GEOMETRIE_MAILLE+2;
+    tabEnt[ON_NODES]=MED_NOEUD;
+    tabType[ON_NODES]=typmainoeud;
+    tabTypeLgth[ON_NODES]=1;
+    //
+    for(int i=0;i<nbFields;i++)
+      {
+        med_int ncomp=MEDnChamp(fid,i+1);
+        char *comp=new char[ncomp*MED_TAILLE_PNOM+1];
+        char *unit=new char[ncomp*MED_TAILLE_PNOM+1];
+        MEDchampInfo(fid,i+1,nomcha,&typcha,comp,unit,ncomp);
+        std::string curFieldName=buildStringFromFortran(nomcha,MED_TAILLE_NOM+1);
+        delete [] comp;
+        delete [] unit;
+        if(curFieldName==fieldName)
+          {
+            bool found=false;
+            for(int j=0;j<tabTypeLgth[typeOfOutField] && !found;j++)
+              {
+                med_int nbPdt=MEDnPasdetemps(fid,nomcha,tabEnt[typeOfOutField],typmai[j]);
+                if(nbPdt>0)
+                  {
+                    int nval=MEDnVal(fid,(char *)fieldName,tabEnt[typeOfOutField],tabType[typeOfOutField][j],iteration,order,(char *)meshName,MED_COMPACT);
+                    double *valr=new double[ncomp*nval];
+                    MEDchampLire(fid,(char *)meshName,(char *)fieldName,(unsigned char*)valr,MED_FULL_INTERLACE,MED_ALL,locname,
+                                 pflname,MED_COMPACT,tabEnt[typeOfOutField],tabType[typeOfOutField][j],iteration,order);
+                    field.push_back(MEDFieldDoublePerCellType(typmai2[j],valr,ncomp,nval));
+                  }
+              }
+          }
+      }
+    MEDfermer(fid);
+  }
+
+  std::vector<int> getIdsFromFamilies(const char *fileName, const char *meshName, const std::vector<std::string>& fams)
+  {
+    std::vector<int> ret;
+    med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE);
+    med_int nfam=MEDnFam(fid,(char *)meshName);
+    char nomfam[MED_TAILLE_NOM+1];
+    med_int numfam;
+    for(int i=0;i<nfam;i++)
+      {
+        int ngro=MEDnGroupe(fid,(char *)meshName,i+1);
+        med_int natt=MEDnAttribut(fid,(char *)meshName,i+1);
+        med_int *attide=new int[natt];
+        med_int *attval=new int[natt];
+        char *attdes=new char[MED_TAILLE_DESC*natt+1];
+        char *gro=new char[MED_TAILLE_LNOM*ngro+1];
+        MEDfamInfo(fid,(char *)meshName,i+1,nomfam,&numfam,attide,attval,attdes,&natt,gro,&ngro);
+        std::string cur=buildStringFromFortran(nomfam,sizeof(nomfam));
+       if(std::find(fams.begin(),fams.end(),cur)!=fams.end())
+         ret.push_back(numfam);
+        delete [] attdes;
+        delete [] gro;
+        delete [] attide;
+        delete [] attval;
+      }
+    MEDfermer(fid);
+    return ret;
+  }
+
+    std::vector<int> getIdsFromGroups(const char *fileName, const char *meshName, const std::vector<std::string>& grps)
+  {
+    std::vector<int> ret;
+    med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE);
+    med_int nfam=MEDnFam(fid,(char *)meshName);
+    char nomfam[MED_TAILLE_NOM+1];
+    med_int numfam;
+    for(int i=0;i<nfam;i++)
+      {
+        int ngro=MEDnGroupe(fid,(char *)meshName,i+1);
+        med_int natt=MEDnAttribut(fid,(char *)meshName,i+1);
+        med_int *attide=new int[natt];
+        med_int *attval=new int[natt];
+        char *attdes=new char[MED_TAILLE_DESC*natt+1];
+        char *gro=new char[MED_TAILLE_LNOM*ngro+1];
+        MEDfamInfo(fid,(char *)meshName,i+1,nomfam,&numfam,attide,attval,attdes,&natt,gro,&ngro);
+        std::string cur=buildStringFromFortran(nomfam,sizeof(nomfam));
+       for(int j=0;j<ngro;j++)
+         {
+           std::string cur=buildStringFromFortran(gro+j*MED_TAILLE_LNOM,MED_TAILLE_LNOM);
+           if(std::find(grps.begin(),grps.end(),cur)!=grps.end())
+             {
+               ret.push_back(numfam);
+               break;
+             }
+         }
+        delete [] attdes;
+        delete [] gro;
+        delete [] attide;
+        delete [] attval;
+      }
+    MEDfermer(fid);
+    return ret;
+  }
+
+  med_int getIdFromMeshName(med_idt fid, const char *meshName) throw(INTERP_KERNEL::Exception)
+  {
+    if(meshName==0)
+      return 1;
+    std::string meshNameStr(meshName);
+    if(meshNameStr=="?")
+      return 1;
+    std::vector<std::string> meshes=getMeshNamesFid(fid);
+    if(meshes.empty())
+      throw INTERP_KERNEL::Exception("No mesh in file");
+    std::vector<std::string>::iterator iter=std::find(meshes.begin(),meshes.end(),meshNameStr);
+    if(iter==meshes.end())
+      {
+        std::ostringstream os2;
+        os2 << "MeshName '" << meshName << "' not in file : meshes available : ";
+        std::copy(meshes.begin(),meshes.end(),std::ostream_iterator<std::string>(os2," "));
+        throw INTERP_KERNEL::Exception(os2.str().c_str());
+      }
+    return iter-meshes.begin()+1;
+  }
+
+  /*!
+   * This methods allows to merger all entities and to considerate only cell types.
+   */
+  void dispatchElems(int nbOfElemCell, int nbOfElemFace, int& nbOfElem, med_entite_maillage& whichEntity)
+  {
+    if(nbOfElemCell>=nbOfElemFace)
+      {
+        whichEntity=MED_MAILLE;
+        nbOfElem=nbOfElemCell;
+      }
+    else
+      {
+        whichEntity=MED_FACE;
+        nbOfElem=nbOfElemFace;
       }
-    std::ostringstream os2;
-    os2 << "MeshName '" << meshName << "' not in file : meshes available : " << os.str();
-    throw INTERP_KERNEL::Exception(os2.str().c_str());
   }
 
   void readUMeshDataInMedFile(med_idt fid, med_int meshId, double *&coords, int& nCoords, int& spaceDim, std::list<MEDLoader::MEDConnOfOneElemType>& conn)
@@ -153,26 +558,16 @@ namespace MEDLoader
         int curNbOfElemM=MEDnEntMaa(fid,nommaa,MED_CONN,MED_MAILLE,curMedType,MED_NOD);
         int curNbOfElemF=MEDnEntMaa(fid,nommaa,MED_CONN,MED_FACE,curMedType,MED_NOD);
         int curNbOfElem;
-        if(curNbOfElemF>curNbOfElemM)
-          {
-            curNbOfElem=curNbOfElemF;
-            whichEntity=MED_FACE;
-          }
-        else
-          {
-            curNbOfElem=curNbOfElemM;
-            whichEntity=MED_MAILLE;
-          }
+        dispatchElems(curNbOfElemM,curNbOfElemF,curNbOfElem,whichEntity);
         if(curNbOfElem>0)
           {
             int *connTab=new int[(curMedType%100)*curNbOfElem];
-            MEDLoader::MEDConnOfOneElemType elem(typmai2[i],connTab,curNbOfElem);
-            int *tmp=new int[curNbOfElem];
             int *fam=new int[curNbOfElem];
+            MEDLoader::MEDConnOfOneElemType elem(typmai2[i],connTab,0,fam,curNbOfElem,-1);
+            int *tmp=new int[curNbOfElem];
             char *noms=new char[MED_TAILLE_PNOM*curNbOfElem+1];
             MEDelementsLire(fid,nommaa,Mdim,connTab,MED_FULL_INTERLACE,noms,&inoele,tmp,&inuele,fam,curNbOfElem,whichEntity,curMedType,MED_NOD);
             delete [] tmp;
-            delete [] fam;
             delete [] noms;
             //trying to read global numbering
             int *globArr=new int[curNbOfElem];
@@ -183,172 +578,462 @@ namespace MEDLoader
             conn.push_back(elem);
           }
       }
+    int curNbOfPolyElem;
+    int curNbOfPolyElemM=MEDnEntMaa(fid,nommaa,MED_CONN,MED_MAILLE,MED_POLYGONE,MED_NOD);
+    int curNbOfPolyElemF=MEDnEntMaa(fid,nommaa,MED_CONN,MED_FACE,MED_POLYGONE,MED_NOD);
+    med_entite_maillage whichPolyEntity;
+    dispatchElems(curNbOfPolyElemM,curNbOfPolyElemF,curNbOfPolyElem,whichPolyEntity);
+    if(curNbOfPolyElem>0)
+      {
+        med_int arraySize;
+        MEDpolygoneInfo(fid,nommaa,whichPolyEntity,MED_NOD,&arraySize);
+        int *index=new int[curNbOfPolyElem+1];
+        int *locConn=new int[arraySize];
+        int *fam=new int[curNbOfPolyElem];
+        MEDLoader::MEDConnOfOneElemType elem(INTERP_KERNEL::NORM_POLYGON,locConn,index,fam,curNbOfPolyElem,arraySize);
+        MEDpolygoneConnLire(fid,nommaa,index,curNbOfPolyElem+1,locConn,whichPolyEntity,MED_NOD);
+        MEDfamLire(fid,nommaa,fam,curNbOfPolyElem,MED_MAILLE,MED_POLYGONE);
+        conn.push_back(elem);
+      }
+    curNbOfPolyElem=MEDnEntMaa(fid,nommaa,MED_CONN,MED_MAILLE,MED_POLYEDRE,MED_NOD);
+    if(curNbOfPolyElem>0)
+      {
+        med_int indexFaceLgth,connFaceLgth;
+        MEDpolyedreInfo(fid,nommaa,MED_NOD,&indexFaceLgth,&connFaceLgth);
+        int *index=new int[curNbOfPolyElem+1];
+        int *indexFace=new int[indexFaceLgth];
+        int *locConn=new int[connFaceLgth];
+        int *fam=new int[curNbOfPolyElem];
+        MEDpolyedreConnLire(fid,nommaa,index,curNbOfPolyElem+1,indexFace,indexFaceLgth,locConn,MED_NOD);
+        MEDfamLire(fid,nommaa,fam,curNbOfPolyElem,MED_MAILLE,MED_POLYEDRE);
+        int arraySize=connFaceLgth;
+        for(int i=0;i<curNbOfPolyElem;i++)
+          arraySize+=index[i+1]-index[i]-1;
+        int *finalConn=new int[arraySize];
+        int *finalIndex=new int[curNbOfPolyElem+1];
+        finalIndex[0]=1;
+        int *wFinalConn=finalConn;
+        for(int i=0;i<curNbOfPolyElem;i++)
+          {
+            finalIndex[i+1]=finalIndex[i]+index[i+1]-index[i]-1+indexFace[index[i+1]-1]-indexFace[index[i]-1];
+            wFinalConn=std::copy(locConn+indexFace[index[i]-1]-1,locConn+indexFace[index[i]]-1,wFinalConn);
+            for(int j=index[i];j<index[i+1]-1;j++)
+              {
+                *wFinalConn++=0;
+                wFinalConn=std::copy(locConn+indexFace[j]-1,locConn+indexFace[j+1]-1,wFinalConn);
+              }
+          }
+        delete [] index;
+        delete [] locConn;
+        delete [] indexFace;
+        MEDLoader::MEDConnOfOneElemType elem(INTERP_KERNEL::NORM_POLYHED,finalConn,finalIndex,fam,curNbOfPolyElem,arraySize);
+        conn.push_back(elem);
+      }
+  }
+  
+  template<class T>
+  unsigned calculateHighestMeshDim(const std::list<T>& conn)
+  {
+    unsigned ret=0;
+    for(typename std::list<T>::const_iterator iter=conn.begin();iter!=conn.end();iter++)
+      {
+       unsigned curDim=INTERP_KERNEL::CellModel::getCellModel((*iter).getType()).getDimension();
+       if(ret<curDim)
+         ret=curDim;
+      }
+    return ret;
+  }
+  
+  template<class T>
+  void keepSpecifiedMeshDim(typename std::list<T>& conn, unsigned meshDim)
+  {
+    for(typename std::list<T>::iterator iter=conn.begin();iter!=conn.end();)
+      {
+       unsigned curDim=INTERP_KERNEL::CellModel::getCellModel((*iter).getType()).getDimension();
+       if(curDim!=meshDim)
+         {
+           (*iter).releaseArray();
+           iter=conn.erase(iter);
+         }
+       else
+         iter++;
+      }
+  }
+  
+  template<class T>
+  void keepTypes(typename std::list<T>& conn, const std::vector<INTERP_KERNEL::NormalizedCellType>& typesToKeep)
+  {
+    if(!typesToKeep.empty())
+      {
+        for(typename std::list<T>::iterator iter=conn.begin();iter!=conn.end();)
+          {
+            INTERP_KERNEL::NormalizedCellType curType=(*iter).getType();
+            if(std::find(typesToKeep.begin(),typesToKeep.end(),curType)==typesToKeep.end())
+              {
+                (*iter).releaseArray();
+                iter=conn.erase(iter);
+              }
+            else
+              iter++;
+          }
+      }
   }
-}
 
-unsigned MEDLoader::calculateHighestMeshDim(const std::list<MEDLoader::MEDConnOfOneElemType>& conn)
-{
-  unsigned ret=0;
-  for(std::list<MEDLoader::MEDConnOfOneElemType>::const_iterator iter=conn.begin();iter!=conn.end();iter++)
-    {
-      unsigned curDim=INTERP_KERNEL::CellModel::getCellModel((*iter).getType()).getDimension();
-      if(ret<curDim)
-        ret=curDim;
-    }
-  return ret;
+  class FieldPerTypeAccumulator
+  {
+  public:
+    int operator()(int res, const MEDLoader::MEDFieldDoublePerCellType& elt) { return res+elt.getNbOfTuple(); }
+  };
+
+  class FieldPerTypeCopier
+  {
+  public:
+    FieldPerTypeCopier(double *ptr):_ptr(ptr) { }
+    void operator()(const MEDLoader::MEDFieldDoublePerCellType& elt) { _ptr=std::copy(elt.getArray(),elt.getArray()+elt.getNbOfValues(),_ptr); }
+  private:
+    double *_ptr;
+  };
+
+  ParaMEDMEM::DataArrayDouble *buildArrayFromRawData(const std::list<MEDLoader::MEDFieldDoublePerCellType>& fieldPerType)
+  {
+    ParaMEDMEM::DataArrayDouble *ret=ParaMEDMEM::DataArrayDouble::New();
+    int totalNbOfTuple=std::accumulate(fieldPerType.begin(),fieldPerType.end(),0,FieldPerTypeAccumulator());
+    int nbOfComp=(*fieldPerType.begin()).getNbComp();
+    double *ptr=new double[nbOfComp*totalNbOfTuple];
+    ret->useArray(ptr,true,ParaMEDMEM::CPP_DEALLOC,totalNbOfTuple,nbOfComp);
+    std::for_each(fieldPerType.begin(),fieldPerType.end(),FieldPerTypeCopier(ptr));
+    return ret;
+  }
+
+  class PolyCounterForFams
+  {
+  public:
+    PolyCounterForFams(int id, const int *index):_id(id),_index(index),_count(0),_sigma(0) { }
+    void operator()(int val) { if(val==_id) _sigma+=_index[_count+1]-_index[_count]; _count++; }
+    int getSigma() const { return _sigma; }
+  private:
+    int _id;
+    const int *_index;
+    int _count;
+    int _sigma;
+  };
+
+  void tradMEDFileCoreFrmt2MEDCouplingUMesh(const std::list<MEDLoader::MEDConnOfOneElemType>& medConnFrmt,
+                                                      DataArrayInt* &conn,
+                                                      DataArrayInt* &connIndex,
+                                                      const std::vector<int>& familiesToKeep)
+  {
+    bool keepAll=familiesToKeep.empty();
+    if(medConnFrmt.empty())
+      {
+       conn=0;
+       connIndex=0;
+       return ;
+      }
+    std::list<MEDLoader::MEDConnOfOneElemType>::const_iterator iter=medConnFrmt.begin();
+    int totalNbOfCells=0;
+    int totalNbOfMedConn=0;
+    for(;iter!=medConnFrmt.end();iter++)
+      {
+       const INTERP_KERNEL::CellModel& cellMod=INTERP_KERNEL::CellModel::getCellModel((*iter).getType());
+       if(keepAll)
+          totalNbOfCells+=(*iter).getLength();
+       else
+         for(std::vector<int>::const_iterator iter2=familiesToKeep.begin();iter2!=familiesToKeep.end();iter2++)
+            totalNbOfCells+=std::count((*iter).getFam(),(*iter).getFam()+(*iter).getLength(),*iter2);
+       if(!cellMod.isDynamic())
+         if(keepAll)
+           totalNbOfMedConn+=(*iter).getLength()*cellMod.getNumberOfNodes();
+         else
+           for(std::vector<int>::const_iterator iter2=familiesToKeep.begin();iter2!=familiesToKeep.end();iter2++)
+             totalNbOfMedConn+=std::count((*iter).getFam(),(*iter).getFam()+(*iter).getLength(),*iter2)*cellMod.getNumberOfNodes();
+       else
+          if(keepAll)
+            totalNbOfMedConn+=(*iter).getConnLength();
+          else
+            for(std::vector<int>::const_iterator iter2=familiesToKeep.begin();iter2!=familiesToKeep.end();iter2++)
+              {
+                PolyCounterForFams res=std::for_each((*iter).getFam(),(*iter).getFam()+(*iter).getLength(),PolyCounterForFams(*iter2,(*iter).getIndex()));
+                totalNbOfMedConn+=res.getSigma();
+              }
+      }
+    connIndex=DataArrayInt::New();
+    conn=DataArrayInt::New();
+    connIndex->alloc(totalNbOfCells+1,1);
+    int *connIdxPtr=connIndex->getPointer();
+    int connFillId=0;
+    conn->alloc(totalNbOfMedConn+totalNbOfCells,1);
+    int *connPtr=conn->getPointer();
+    for(iter=medConnFrmt.begin();iter!=medConnFrmt.end();iter++)
+      {
+       INTERP_KERNEL::NormalizedCellType type=(*iter).getType();
+       const int *sourceConn=(*iter).getArray();
+        const int *sourceIndex=(*iter).getIndex();
+       const INTERP_KERNEL::CellModel& cellMod=INTERP_KERNEL::CellModel::getCellModel(type);
+       int nbOfCellsInCurType;
+       int nbOfNodesIn1Cell=cellMod.getNumberOfNodes();
+        nbOfCellsInCurType=(*iter).getLength();
+        bool isDyn=cellMod.isDynamic();
+        int *tmpConnPtr;
+        for(int i=0;i<nbOfCellsInCurType;i++)
+          {
+            if(keepAll)
+              {
+                *connIdxPtr=connFillId;
+                *connPtr++=type;
+                if(!isDyn)
+                  tmpConnPtr=std::transform(sourceConn,sourceConn+nbOfNodesIn1Cell,connPtr,std::bind2nd(std::minus<int>(),1));
+                else
+                  tmpConnPtr=std::transform(sourceConn,sourceConn+sourceIndex[i+1]-sourceIndex[i],connPtr,std::bind2nd(std::minus<int>(),1));
+                connIdxPtr++;
+                nbOfNodesIn1Cell=tmpConnPtr-connPtr;
+                connFillId+=nbOfNodesIn1Cell+1;
+                connPtr=tmpConnPtr;
+              }
+            else if(std::find(familiesToKeep.begin(),familiesToKeep.end(),(*iter).getFam()[i])!=familiesToKeep.end())
+              {
+                *connIdxPtr=connFillId;
+                *connPtr++=type;
+                if(!isDyn)
+                  tmpConnPtr=std::transform(sourceConn,sourceConn+nbOfNodesIn1Cell,connPtr,std::bind2nd(std::minus<int>(),1));
+                else
+                  tmpConnPtr=std::transform(sourceConn,sourceConn+sourceIndex[i+1]-sourceIndex[i],connPtr,std::bind2nd(std::minus<int>(),1));
+                connIdxPtr++;
+                nbOfNodesIn1Cell=tmpConnPtr-connPtr;
+                connFillId+=nbOfNodesIn1Cell+1;
+                connPtr=tmpConnPtr;
+              }
+            sourceConn+=nbOfNodesIn1Cell;
+          }
+        *connIdxPtr=connFillId;
+      }
+  }
+  
+  template<class T>
+  void releaseMEDFileCoreFrmt(typename std::list<T>& medConnFrmt)
+  {
+    for(typename std::list<T>::iterator iter=medConnFrmt.begin();iter!=medConnFrmt.end();iter++)
+      (*iter).releaseArray();
+    medConnFrmt.clear();
+  }
+
+  /*!
+   * This method builds a sub set of connectivity for a given type 'type'.
+   * @param conn input containing connectivity with MEDCoupling format.
+   * @param connIndex input containing connectivity index in MEDCoupling format.
+   * @param type input specifying which cell types will be extracted in conn4MEDFile. 
+   * @param conn4MEDFile output containing the connectivity directly understandable by MEDFile; conn4MEDFile has to be empty before this method called.
+   * @param connIndex4MEDFile output containing index connectivity understandable by MEDFile; only used by polygons and polyhedrons (it is face nodal connec).
+   * @param connIndexRk24MEDFile output containing index of rank 2 understandable by MEDFile; only used by polyhedrons.
+   * @return nb of elements extracted.
+   */
+  int buildMEDSubConnectivityOfOneTypeStaticTypes(DataArrayInt *conn, DataArrayInt *connIndex, INTERP_KERNEL::NormalizedCellType type, std::vector<int>& conn4MEDFile)
+  {
+    int ret=0;
+    int nbOfElem=connIndex->getNbOfElems()-1;
+    const int *connPtr=conn->getPointer();
+    const int *connIdxPtr=connIndex->getPointer();
+    for(int i=0;i<nbOfElem;i++)
+      {
+       int delta=connIdxPtr[1]-connIdxPtr[0];
+       if(*connPtr==type)
+         {
+           conn4MEDFile.insert(conn4MEDFile.end(),connPtr+1,connPtr+delta);
+           ret++;
+          }
+       connIdxPtr++;
+       connPtr+=delta;
+      }
+    std::transform(conn4MEDFile.begin(),conn4MEDFile.end(),conn4MEDFile.begin(),std::bind2nd(std::plus<int>(),1));
+    return ret;
+  }
+
+  int buildMEDSubConnectivityOfOneTypesPolyg(DataArrayInt *conn, DataArrayInt *connIndex, std::vector<int>& conn4MEDFile, std::vector<int>& connIndex4MEDFile)
+  {
+    int ret=0;
+    int nbOfElem=connIndex->getNbOfElems()-1;
+    const int *connPtr=conn->getPointer();
+    const int *connIdxPtr=connIndex->getPointer();
+    connIndex4MEDFile.push_back(1);
+    for(int i=0;i<nbOfElem;i++)
+      {
+        int delta=connIdxPtr[1]-connIdxPtr[0];
+       if(*connPtr==INTERP_KERNEL::NORM_POLYGON)
+         {
+           conn4MEDFile.insert(conn4MEDFile.end(),connPtr+1,connPtr+delta);
+            connIndex4MEDFile.push_back(connIndex4MEDFile.back()+delta-1);
+           ret++;
+          }
+        connIdxPtr++;
+       connPtr+=delta;
+      }
+    std::transform(conn4MEDFile.begin(),conn4MEDFile.end(),conn4MEDFile.begin(),std::bind2nd(std::plus<int>(),1));
+    return ret;
+  }
+  
+  int buildMEDSubConnectivityOfOneTypesPolyh(DataArrayInt *conn, DataArrayInt *connIndex, std::vector<int>& conn4MEDFile, std::vector<int>& connIndex4MEDFile, std::vector<int>& connIndexRk24MEDFile)
+  {
+    return 0;
+  }
+  
+  /*!
+   * This method builds a sub set of connectivity for a given type 'type'.
+   * @param conn input containing connectivity with MEDCoupling format.
+   * @param connIndex input containing connectivity index in MEDCoupling format.
+   * @param type input specifying which cell types will be extracted in conn4MEDFile. 
+   * @param conn4MEDFile output containing the connectivity directly understandable by MEDFile; conn4MEDFile has to be empty before this method called.
+   * @param connIndex4MEDFile output containing index connectivity understandable by MEDFile; only used by polygons and polyhedrons (it is face nodal connec).
+   * @param connIndexRk24MEDFile output containing index of rank 2 understandable by MEDFile; only used by polyhedrons.
+   * @return nb of elements extracted.
+   */
+  int buildMEDSubConnectivityOfOneType(DataArrayInt *conn, DataArrayInt *connIndex, INTERP_KERNEL::NormalizedCellType type, std::vector<int>& conn4MEDFile,
+                                       std::vector<int>& connIndex4MEDFile, std::vector<int>& connIndexRk24MEDFile)
+  {
+    
+    const INTERP_KERNEL::CellModel& cellMod=INTERP_KERNEL::CellModel::getCellModel(type);
+    if(!cellMod.isDynamic())
+      return buildMEDSubConnectivityOfOneTypeStaticTypes(conn,connIndex,type,conn4MEDFile);
+    else
+      {
+        if(type==INTERP_KERNEL::NORM_POLYGON)
+          return buildMEDSubConnectivityOfOneTypesPolyg(conn,connIndex,conn4MEDFile,connIndex4MEDFile);
+        else
+          return buildMEDSubConnectivityOfOneTypesPolyh(conn,connIndex,conn4MEDFile,connIndex4MEDFile,connIndexRk24MEDFile);
+      }
+  }
+  
+  /*!
+   * @param ids is a in vector containing families ids whose cells have to be kept. If empty all cells are kept.
+   * @param typesToKeep is a in vector that indicates which types to keep after dimension filtering.
+   * @param meshDimExtract out parameter that gives the mesh dimension.
+   */
+  MEDCouplingUMesh *readUMeshFromFileLev1(const char *fileName, const char *meshName, int meshDimRelToMax, const std::vector<int>& ids,
+                                          const std::vector<INTERP_KERNEL::NormalizedCellType>& typesToKeep, unsigned& meshDimExtract) throw(INTERP_KERNEL::Exception)
+  {
+  //Extraction data from MED file.
+    med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE);
+    med_int mid=getIdFromMeshName(fid,meshName);
+    double *coords;
+    int nCoords;
+    int spaceDim;
+    std::list<MEDLoader::MEDConnOfOneElemType> conn;
+    readUMeshDataInMedFile(fid,mid,coords,nCoords,spaceDim,conn);
+    meshDimExtract=calculateHighestMeshDim<MEDConnOfOneElemType>(conn);
+    meshDimExtract=meshDimExtract+meshDimRelToMax;
+    keepSpecifiedMeshDim<MEDConnOfOneElemType>(conn,meshDimExtract);
+    keepTypes<MEDConnOfOneElemType>(conn,typesToKeep);
+    MEDfermer(fid);
+    //Put data in returned data structure.
+    MEDCouplingUMesh *ret=MEDCouplingUMesh::New();
+    ret->setName(meshName);
+    ret->setMeshDimension(meshDimExtract);
+    //
+    DataArrayDouble *coordsArr=DataArrayDouble::New();
+    coordsArr->useArray(coords,true,ParaMEDMEM::CPP_DEALLOC,nCoords,spaceDim);
+    ret->setCoords(coordsArr);
+    coordsArr->decrRef();
+    //
+    DataArrayInt *connArr,*connIndexArr;
+    tradMEDFileCoreFrmt2MEDCouplingUMesh(conn,connArr,connIndexArr,ids);
+    ret->setConnectivity(connArr,connIndexArr);
+    //clean-up
+    if(connArr)
+      connArr->decrRef();
+    if(connIndexArr)
+      connIndexArr->decrRef();
+    releaseMEDFileCoreFrmt<MEDLoader::MEDConnOfOneElemType>(conn);
+    return ret;
+  }
+
+  ParaMEDMEM::MEDCouplingFieldDouble *readFieldDoubleLev1(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order,
+                                                          ParaMEDMEM::TypeOfField typeOfOutField)
+  {
+    std::list<MEDLoader::MEDFieldDoublePerCellType> fieldPerCellType;
+    double time;
+    readFieldDoubleDataInMedFile(fileName,meshName,fieldName,fieldPerCellType,iteration,order,typeOfOutField,time);
+    std::vector<int> familiesToKeep;
+    std::vector<INTERP_KERNEL::NormalizedCellType> typesToKeep;
+    if(typeOfOutField==ON_CELLS)
+      for(std::list<MEDLoader::MEDFieldDoublePerCellType>::const_iterator iter=fieldPerCellType.begin();iter!=fieldPerCellType.end();iter++)
+        typesToKeep.push_back((*iter).getType());
+    unsigned meshDim;
+    ParaMEDMEM::MEDCouplingUMesh *mesh=readUMeshFromFileLev1(fileName,meshName,meshDimRelToMax,familiesToKeep,typesToKeep,meshDim);
+    if(typeOfOutField==ON_CELLS)
+      keepSpecifiedMeshDim<MEDFieldDoublePerCellType>(fieldPerCellType,meshDim);
+    ParaMEDMEM::MEDCouplingFieldDouble *ret=ParaMEDMEM::MEDCouplingFieldDouble::New(typeOfOutField);
+    ret->setDtIt(iteration,order);
+    ret->setName(fieldName);
+    ret->setTime(time);
+    ret->setMesh(mesh);
+    mesh->decrRef();
+    ParaMEDMEM::DataArrayDouble *arr=buildArrayFromRawData(fieldPerCellType);
+    ret->setArray(arr);
+    arr->decrRef();
+    releaseMEDFileCoreFrmt<MEDLoader::MEDFieldDoublePerCellType>(fieldPerCellType);
+    return ret;
+  }
+  
+  /*!
+   * This method builds the master file 'fileName' of a parallel MED file defined in 'fileNames'.
+   */
+  void writeMasterFile(const char *fileName, const std::vector<std::string>& fileNames, const char *meshName)
+  {
+    int nbOfDom=fileNames.size();
+    std::ofstream fs(fileName);
+    fs << "#MED Fichier V 2.3" << " " << std::endl;
+    fs << "#"<<" " << std::endl;
+    fs << nbOfDom <<" " << std::endl;
+    for(int i=0;i<nbOfDom;i++)
+      fs << meshName << " " << i+1 << " " << meshName << "_" << i+1 << " localhost " << fileNames[i] << " " << std::endl;
+  }
 }
 
-void MEDLoader::keepSpecifiedMeshDim(std::list<MEDLoader::MEDConnOfOneElemType>& conn, unsigned meshDim)
+MEDCouplingUMesh *MEDLoader::ReadUMeshFromFile(const char *fileName, const char *meshName, int meshDimRelToMax) throw(INTERP_KERNEL::Exception)
 {
-  for(std::list<MEDLoader::MEDConnOfOneElemType>::iterator iter=conn.begin();iter!=conn.end();)
-    {
-      unsigned curDim=INTERP_KERNEL::CellModel::getCellModel((*iter).getType()).getDimension();
-      if(curDim!=meshDim)
-        {
-          (*iter).releaseArray();
-          iter=conn.erase(iter);
-        }
-      else
-        iter++;
-    }
+  std::vector<int> familiesToKeep;
+  std::vector<INTERP_KERNEL::NormalizedCellType> typesToKeep;
+  unsigned meshDim;
+  return readUMeshFromFileLev1(fileName,meshName,meshDimRelToMax,familiesToKeep,typesToKeep,meshDim);
 }
 
-void MEDLoader::tradMEDFileCoreFrmt2MEDCouplingUMesh(const std::list<MEDLoader::MEDConnOfOneElemType>& medConnFrmt,
-                                                     DataArrayInt* &conn,
-                                                     DataArrayInt* &connIndex)
+ParaMEDMEM::MEDCouplingUMesh *MEDLoader::ReadUMeshFromFamilies(const char *fileName, const char *meshName, int meshDimRelToMax, const std::vector<std::string>& fams)
 {
-  if(medConnFrmt.empty())
-    {
-      conn=0;
-      connIndex=0;
-      return ;
-    }
-  std::list<MEDLoader::MEDConnOfOneElemType>::const_iterator iter=medConnFrmt.begin();
-  int totalNbOfCells=0;
-  int totalNbOfMedConn=0;
-  for(;iter!=medConnFrmt.end();iter++)
-    {
-      const INTERP_KERNEL::CellModel& cellMod=INTERP_KERNEL::CellModel::getCellModel((*iter).getType());
-      totalNbOfCells+=(*iter).getLength();
-      if(!cellMod.isDynamic())
-        totalNbOfMedConn+=(*iter).getLength()*cellMod.getNumberOfNodes();
-      else
-        throw INTERP_KERNEL::Exception("Polyg/polh not implemented yet !");
-    }
-  connIndex=DataArrayInt::New();
-  conn=DataArrayInt::New();
-  connIndex->alloc(totalNbOfCells+1,1);
-  int *connIdxPtr=connIndex->getPointer();
-  int connFillId=0;
-  conn->alloc(totalNbOfMedConn+totalNbOfCells,1);
-  int *connPtr=conn->getPointer();
-  for(iter=medConnFrmt.begin();iter!=medConnFrmt.end();iter++)
-    {
-      INTERP_KERNEL::NormalizedCellType type=(*iter).getType();
-      int *sourceConn=(*iter).getArray();
-      const INTERP_KERNEL::CellModel& cellMod=INTERP_KERNEL::CellModel::getCellModel(type);
-      int nbOfCellsInCurType;
-      int nbOfNodesIn1Cell=cellMod.getNumberOfNodes();
-      if(!cellMod.isDynamic())
-        nbOfCellsInCurType=(*iter).getLength();
-      else
-        throw INTERP_KERNEL::Exception("Polyg/polh not implemented yet !");
-      if(!cellMod.isDynamic())
-        {
-          for(int i=0;i<nbOfCellsInCurType;i++,connIdxPtr++)
-            {
-              *connIdxPtr=connFillId;
-              *connPtr++=type;
-              connPtr=std::transform(sourceConn,sourceConn+nbOfNodesIn1Cell,connPtr,std::bind2nd(std::minus<int>(),1));
-              connFillId+=nbOfNodesIn1Cell+1;
-              sourceConn+=nbOfNodesIn1Cell;
-            }
-          *connIdxPtr=connFillId;
-        }
-    }
+  std::vector<int> familiesToKeep=getIdsFromFamilies(fileName,meshName,fams);
+  std::vector<INTERP_KERNEL::NormalizedCellType> typesToKeep;
+  unsigned meshDim;
+  return readUMeshFromFileLev1(fileName,meshName,meshDimRelToMax,familiesToKeep,typesToKeep,meshDim);
 }
 
-void MEDLoader::releaseMEDFileCoreFrmt(std::list<MEDLoader::MEDConnOfOneElemType>& medConnFrmt)
+ParaMEDMEM::MEDCouplingUMesh *MEDLoader::ReadUMeshFromGroups(const char *fileName, const char *meshName, int meshDimRelToMax, const std::vector<std::string>& grps)
 {
-  for(std::list<MEDLoader::MEDConnOfOneElemType>::iterator iter=medConnFrmt.begin();iter!=medConnFrmt.end();iter++)
-    (*iter).releaseArray();
-  medConnFrmt.clear();
+  std::vector<int> familiesToKeep=getIdsFromGroups(fileName,meshName,grps);
+  std::vector<INTERP_KERNEL::NormalizedCellType> typesToKeep;
+  unsigned meshDim;
+  return readUMeshFromFileLev1(fileName,meshName,meshDimRelToMax,familiesToKeep,typesToKeep,meshDim);
 }
 
-/*!
- * This method builds a sub set of connectivity for a given type 'type'.
- * @param conn input containing connectivity with MEDCoupling format.
- * @param connIndex input containing connectivity index in MEDCoupling format.
- * @param type input specifying which cell types will be extracted in conn4MEDFile. 
- * @param conn4MEDFile output containing the connectivity directly understandable by MEDFile; conn4MEDFile has to be empty before this method called.
- * @return nb of elements extracted.
- */
-int MEDLoader::buildMEDSubConnectivityOfOneType(DataArrayInt *conn, DataArrayInt *connIndex, INTERP_KERNEL::NormalizedCellType type, std::vector<int>& conn4MEDFile)
+ParaMEDMEM::MEDCouplingFieldDouble *MEDLoader::ReadFieldDoubleCell(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order)
 {
-  int ret=0;
-  int nbOfElem=connIndex->getNbOfElems()-1;
-  const int *connPtr=conn->getPointer();
-  const int *connIdxPtr=connIndex->getPointer();
-  for(int i=0;i<nbOfElem;i++)
-    {
-      int delta=connIdxPtr[1]-connIdxPtr[0];
-      if(*connPtr==type)
-        {
-          conn4MEDFile.insert(conn4MEDFile.end(),connPtr+1,connPtr+delta);
-          ret++;
-        }
-      connIdxPtr++;
-      connPtr+=delta;
-    }
-  std::transform(conn4MEDFile.begin(),conn4MEDFile.end(),conn4MEDFile.begin(),std::bind2nd(std::plus<int>(),1));
-  return ret;
+  return readFieldDoubleLev1(fileName,meshName,meshDimRelToMax,fieldName,iteration,order,ON_CELLS);
 }
 
-MEDCouplingUMesh *MEDLoader::ReadUMeshFromFile(const char *fileName, const char *meshName, int meshDimRelToMax) throw(INTERP_KERNEL::Exception)
+ParaMEDMEM::MEDCouplingFieldDouble *MEDLoader::ReadFieldDoubleNode(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order)
 {
-  //Extraction data from MED file.
-  med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE);
-  med_int mid=getIdFromMeshName(fid,meshName);
-  unsigned meshDimExtract;
-  double *coords;
-  int nCoords;
-  int spaceDim;
-  std::list<MEDLoader::MEDConnOfOneElemType> conn;
-  readUMeshDataInMedFile(fid,mid,coords,nCoords,spaceDim,conn);
-  meshDimExtract=calculateHighestMeshDim(conn);
-  meshDimExtract=meshDimExtract+meshDimRelToMax;
-  keepSpecifiedMeshDim(conn,meshDimExtract);
-  MEDfermer(fid);
-  //Put data in returned data structure.
-  MEDCouplingUMesh *ret=MEDCouplingUMesh::New();
-  ret->setName(meshName);
-  ret->setMeshDimension(meshDimExtract);
-  //
-  DataArrayDouble *coordsArr=DataArrayDouble::New();
-  coordsArr->useArray(coords,true,ParaMEDMEM::CPP_DEALLOC,nCoords,spaceDim);
-  ret->setCoords(coordsArr);
-  coordsArr->decrRef();
-  //
-  DataArrayInt *connArr,*connIndexArr;
-  tradMEDFileCoreFrmt2MEDCouplingUMesh(conn,connArr,connIndexArr);
-  ret->setConnectivity(connArr,connIndexArr);
-  //clean-up
-  if(connArr)
-    connArr->decrRef();
-  if(connIndexArr)
-    connIndexArr->decrRef();
-  releaseMEDFileCoreFrmt(conn);
-  return ret;
+  return readFieldDoubleLev1(fileName,meshName,meshDimRelToMax,fieldName,iteration,order,ON_NODES);
 }
 
 void MEDLoader::writeUMesh(const char *fileName, ParaMEDMEM::MEDCouplingUMesh *mesh)
 {
   med_idt fid=MEDouvrir((char *)fileName,MED_CREATION);
+  std::string meshName(mesh->getName());
+  if(meshName=="")
+    {
+      MEDfermer(fid);
+      throw INTERP_KERNEL::Exception("MEDCouplingMesh must have a not null name !");
+    }
   char maa[MED_TAILLE_NOM+1];
-  std::fill(maa,maa+MED_TAILLE_NOM+1,'\0');
-  const char *meshName=mesh->getName();
-  strcpy(maa,meshName);
-  MEDmaaCr(fid,maa,mesh->getMeshDimension(),MED_NON_STRUCTURE,maa);
+  strcpy(maa,meshName.c_str());
+  MEDmaaCr(fid,maa,mesh->getSpaceDimension(),MED_NON_STRUCTURE,maa);
   std::set<INTERP_KERNEL::NormalizedCellType> allTypes(mesh->getAllTypes());
   DataArrayInt *conn=mesh->getNodalConnectivity();
   DataArrayInt *connIndex=mesh->getNodalConnectivityIndex();
@@ -356,15 +1041,23 @@ void MEDLoader::writeUMesh(const char *fileName, ParaMEDMEM::MEDCouplingUMesh *m
   std::fill(familyName,familyName+MED_TAILLE_NOM+1,'\0');
   const char DftFamilyName[]="DftFamily";
   std::copy(DftFamilyName,DftFamilyName+sizeof(DftFamilyName),familyName);
-  for(int i=0;i<MED_NBR_GEOMETRIE_MAILLE;i++)
+  for(int i=0;i<MED_NBR_GEOMETRIE_MAILLE+2;i++)
     {
       med_geometrie_element curMedType=typmai[i];
       INTERP_KERNEL::NormalizedCellType curType=typmai2[i];
       if(allTypes.find(curType)!=allTypes.end())
         {
           std::vector<int> medConn;
-          int nbOfElt=buildMEDSubConnectivityOfOneType(conn,connIndex,curType,medConn);
-          MEDconnEcr(fid,maa,mesh->getMeshDimension(),&medConn[0],MED_FULL_INTERLACE,nbOfElt,MED_MAILLE,curMedType,MED_NOD);
+          std::vector<int> medConnIndex;
+          std::vector<int> medConnIndex2;
+          int nbOfElt=buildMEDSubConnectivityOfOneType(conn,connIndex,curType,medConn,medConnIndex,medConnIndex2);
+          if(curMedType!=MED_POLYGONE && curMedType!=MED_POLYEDRE)
+            MEDconnEcr(fid,maa,mesh->getMeshDimension(),&medConn[0],MED_FULL_INTERLACE,nbOfElt,MED_MAILLE,curMedType,MED_NOD);
+          else
+            {
+              if(curMedType==MED_POLYGONE)
+                MEDpolygoneConnEcr(fid,maa,&medConnIndex[0],medConnIndex.size(),&medConn[0],MED_MAILLE,MED_NOD);
+            }
         }
     }
   MEDfamCr(fid,maa,familyName,0,0,0,0,0,0,0);
@@ -381,20 +1074,6 @@ void MEDLoader::writeUMesh(const char *fileName, ParaMEDMEM::MEDCouplingUMesh *m
   MEDfermer(fid);
 }
 
-/*!
- * This method builds the master file 'fileName' of a parallel MED file defined in 'fileNames'.
- */
-void MEDLoader::writeMasterFile(const char *fileName, const std::vector<std::string>& fileNames, const char *meshName)
-{
-  int nbOfDom=fileNames.size();
-  std::ofstream fs(fileName);
-  fs << "#MED Fichier V 2.3" << " " << std::endl;
-  fs << "#"<<" " << std::endl;
-  fs << nbOfDom <<" " << std::endl;
-  for(int i=0;i<nbOfDom;i++)
-    fs << meshName << " " << i+1 << " " << meshName << "_" << i+1 << " localhost " << fileNames[i] << " " << std::endl;
-}
-
 void MEDLoader::writeParaMesh(const char *fileName, ParaMEDMEM::ParaMESH *mesh)
 {
   if(!mesh->getBlockTopology()->getProcGroup()->containsMyRank())
index b5f7065da6d27bdfc7b53ccb7a317ea10f203f5f..9e5c5db7379a48d3ba711b5692aeb075cf12f1c1 100644 (file)
@@ -31,6 +31,7 @@ namespace ParaMEDMEM
   class ParaFIELD;
   class DataArrayInt;
   class MEDCouplingUMesh;
+  class MEDCouplingFieldDouble;
 }
 
 namespace MEDLoader
@@ -38,29 +39,54 @@ namespace MEDLoader
   class MEDConnOfOneElemType
   {
   public:
-    MEDConnOfOneElemType(INTERP_KERNEL::NormalizedCellType type, int *conn, int lgth);
+    MEDConnOfOneElemType(INTERP_KERNEL::NormalizedCellType type, int *conn, int *index, int *fam, int lgth, int connLgth);
     INTERP_KERNEL::NormalizedCellType getType() const { return _type; }
     int getLength() const { return _lgth; }
+    int getConnLength() const { return _conn_lgth; }
     int *getArray() const { return _conn; }
+    int *getIndex() const { return _index; }
+    int *getFam() const { return _fam; }
     void setGlobal(int *global);
     void releaseArray();
   private:
     int _lgth;
+    int *_fam;
     int *_conn;
+    int *_index;
     int *_global;
+    int _conn_lgth;
+    INTERP_KERNEL::NormalizedCellType _type;
+  };
+
+  class MEDFieldDoublePerCellType
+  {
+  public:
+    MEDFieldDoublePerCellType(INTERP_KERNEL::NormalizedCellType type, double *values, int ncomp, int nval);
+    INTERP_KERNEL::NormalizedCellType getType() const { return _type; }
+    int getNbComp() const { return _ncomp; }
+    int getNbOfTuple() const { return _nval; }
+    int getNbOfValues() const { return _ncomp*_nval; }
+    double *getArray() const { return _values; }
+    void releaseArray();
+  private:
+    int _nval;
+    int _ncomp;
+    double *_values;
     INTERP_KERNEL::NormalizedCellType _type;
   };
-  unsigned calculateHighestMeshDim(const std::list<MEDConnOfOneElemType>& conn);
-  void keepSpecifiedMeshDim(std::list<MEDConnOfOneElemType>& conn, unsigned meshDim);
-  void tradMEDFileCoreFrmt2MEDCouplingUMesh(const std::list<MEDConnOfOneElemType>& medConnFrmt,
-                                            ParaMEDMEM::DataArrayInt* &conn,
-                                            ParaMEDMEM::DataArrayInt* &connIndex);
-  void releaseMEDFileCoreFrmt(std::list<MEDLoader::MEDConnOfOneElemType>& medConnFrmt);
-  void writeMasterFile(const char *fileName, const std::vector<std::string>& fileNames, const char *meshName);
-  int buildMEDSubConnectivityOfOneType(ParaMEDMEM::DataArrayInt *conn, ParaMEDMEM::DataArrayInt *connIndex,
-                                       INTERP_KERNEL::NormalizedCellType type, std::vector<int>& conn4MEDFile);
   //
+  std::vector<std::string> GetMeshNames(const char *fileName);
+  std::vector<std::string> GetMeshGroupsNames(const char *fileName, const char *meshName);
+  std::vector<std::string> GetMeshFamilyNames(const char *fileName, const char *meshName);
+  std::vector<std::string> GetCellFieldNamesOnMesh(const char *fileName, const char *meshName);
+  std::vector<std::string> GetNodeFieldNamesOnMesh(const char *fileName, const char *meshName);
+  std::vector< std::pair<int,int> > GetCellFieldIterations(const char *fileName, const char *fieldName);
+  std::vector< std::pair<int,int> > GetNodeFieldIterations(const char *fileName, const char *fieldName);
+  ParaMEDMEM::MEDCouplingUMesh *ReadUMeshFromFamilies(const char *fileName, const char *meshName, int meshDimRelToMax, const std::vector<std::string>& fams);
+  ParaMEDMEM::MEDCouplingUMesh *ReadUMeshFromGroups(const char *fileName, const char *meshName, int meshDimRelToMax, const std::vector<std::string>& grps);
   ParaMEDMEM::MEDCouplingUMesh *ReadUMeshFromFile(const char *fileName, const char *meshName=0, int meshDimRelToMax=0) throw(INTERP_KERNEL::Exception);
+  ParaMEDMEM::MEDCouplingFieldDouble *ReadFieldDoubleCell(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order);
+  ParaMEDMEM::MEDCouplingFieldDouble *ReadFieldDoubleNode(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order);
   void writeUMesh(const char *fileName, ParaMEDMEM::MEDCouplingUMesh *mesh);
   void writeParaMesh(const char *fileName, ParaMEDMEM::ParaMESH *mesh);
   void writeParaField(const char *fileName, const char *meshName, ParaMEDMEM::ParaFIELD *f);