Salome HOME
Merge branch 'master' of ssh://git.salome-platform.org/tools/medcoupling
[tools/medcoupling.git] / src / MEDLoader / MEDFileMesh.cxx
index 90c34e17eccc7e86f5be948a0397213895f995e0..3d59c0b9544d51bdee37dc4971d4b9ba9c913750 100644 (file)
 // Author : Anthony Geay (CEA/DEN)
 
 #include "MEDFileMesh.hxx"
-#include "MEDFileUtilities.hxx"
 #include "MEDFileFieldOverView.hxx"
 #include "MEDFileField.hxx"
 #include "MEDLoader.hxx"
+#include "MEDLoaderNS.hxx"
 #include "MEDFileSafeCaller.txx"
 #include "MEDLoaderBase.hxx"
 
 #include "MEDCouplingUMesh.hxx"
+#include "MEDCouplingMappedExtrudedMesh.hxx"
 
 #include "InterpKernelAutoPtr.hxx"
 
 #include <limits>
 #include <cmath>
 
+extern med_geometry_type                 typmai[MED_N_CELL_FIXED_GEO];
+extern INTERP_KERNEL::NormalizedCellType typmai2[MED_N_CELL_FIXED_GEO];
 extern med_geometry_type typmai3[34];
 
 using namespace MEDCoupling;
 
 const char MEDFileMesh::DFT_FAM_NAME[]="FAMILLE_ZERO";
 
+const char MEDFileUMesh::SPE_FAM_STR_EXTRUDED_MESH[]="HIDDEN_FAM_EXT_MESH@";
+
 MEDFileMesh::MEDFileMesh():_order(-1),_iteration(-1),_time(0.),_univ_wr_status(true),_axis_type(AX_CART)
 {
 }
@@ -76,15 +81,19 @@ std::vector<const BigMemoryObject *> MEDFileMesh::getDirectChildrenWithNull() co
  */
 MEDFileMesh *MEDFileMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
 {
-  std::vector<std::string> ms=MEDCoupling::GetMeshNames(fileName);
+  MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
+  return New(fid,mrs);
+}
+
+MEDFileMesh *MEDFileMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
+{
+  std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
   if(ms.empty())
     {
-      std::ostringstream oss; oss << "MEDFileMesh::New : no meshes in file \"" << fileName << "\" !";
+      std::ostringstream oss; oss << "MEDFileMesh::New : no meshes in file \"" << FileNameFromFID(fid) << "\" !";
       throw INTERP_KERNEL::Exception(oss.str().c_str());
     }
-  MEDFileUtilities::CheckFileForRead(fileName);
   MEDCoupling::MEDCouplingMeshType meshType;
-  MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
   int dt,it;
   std::string dummy2;
   MEDCoupling::MEDCouplingAxisType dummy3;
@@ -136,9 +145,13 @@ MEDFileMesh *MEDFileMesh::New(const std::string& fileName, MEDFileMeshReadSelect
  */
 MEDFileMesh *MEDFileMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs, MEDFileJoints* joints)
 {
-  MEDFileUtilities::CheckFileForRead(fileName);
+  MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
+  return New(fid,mName,dt,it,mrs,joints);
+}
+
+MEDFileMesh *MEDFileMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs, MEDFileJoints* joints)
+{
   MEDCoupling::MEDCouplingMeshType meshType;
-  MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
   int dummy0,dummy1;
   std::string dummy2;
   MEDCoupling::MEDCouplingAxisType dummy3;
@@ -178,36 +191,17 @@ MEDFileMesh *MEDFileMesh::New(const std::string& fileName, const std::string& mN
  *  \throw If the file is open for reading only.
  *  \throw If the writing mode == 1 and the same data is present in an existing file.
  */
-void MEDFileMesh::write(med_idt fid) const
+void MEDFileMesh::writeLL(med_idt fid) const
 {
   if(!existsFamily(0))
     const_cast<MEDFileMesh *>(this)->addFamily(DFT_FAM_NAME,0);
   if(_name.empty())
     throw INTERP_KERNEL::Exception("MEDFileMesh : name is empty. MED file ask for a NON EMPTY name !");
-  writeLL(fid);
+  writeMeshLL(fid);
   writeJoints(fid);
   const MEDFileEquivalences *eqs(_equiv);
   if(eqs)
-    eqs->write(fid);
-}
-
-/*!
- * Writes \a this mesh into a MED file specified by its name.
- *  \param [in] fileName - the MED file name.
- *  \param [in] mode - the writing mode. For more on \a mode, see \ref AdvMEDLoaderBasics.
- * - 2 - erase; an existing file is removed.
- * - 1 - append; same data should not be present in an existing file.
- * - 0 - overwrite; same data present in an existing file is overwritten.
- *  \throw If the mesh name is not set.
- *  \throw If \a mode == 1 and the same data is present in an existing file.
- */
-void MEDFileMesh::write(const std::string& fileName, int mode) const
-{
-  med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
-  MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
-  std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\""; 
-  MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
-  write(fid);
+    eqs->writeLL(fid);
 }
 
 /*!
@@ -2090,6 +2084,9 @@ std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileMesh::getAllGeoTypes() con
   return ret;
 }
 
+/*!
+ * \sa getAllDistributionOfTypes
+ */
 std::vector<int> MEDFileMesh::getDistributionOfTypes(int meshDimRelToMax) const
 {
   MCAuto<MEDCouplingMesh> mLev(getMeshAtLevel(meshDimRelToMax));
@@ -2237,8 +2234,12 @@ void MEDFileMesh::getFamilyRepr(std::ostream& oss) const
  */
 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
 {
-  MEDFileUtilities::CheckFileForRead(fileName);
-  MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
+  MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
+  return New(fid,mName,dt,it,mrs);
+}
+
+MEDFileUMesh *MEDFileUMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
+{
   return new MEDFileUMesh(fid,mName,dt,it,mrs);
 }
 
@@ -2254,20 +2255,49 @@ MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, const std::string&
  */
 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
 {
-  std::vector<std::string> ms(MEDCoupling::GetMeshNames(fileName));
+  MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
+  return New(fid,mrs);
+}
+
+template<class T>
+T *NewForTheFirstMeshInFile(med_idt fid, MEDFileMeshReadSelector *mrs)
+{
+  std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
   if(ms.empty())
     {
-      std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
+      std::ostringstream oss; oss << MLMeshTraits<T>::ClassName << "::New : no meshes in file \"" << MEDFileWritable::FileNameFromFID(fid) << "\" !";
       throw INTERP_KERNEL::Exception(oss.str().c_str());
     }
-  MEDFileUtilities::CheckFileForRead(fileName);
-  MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
   int dt,it;
   MEDCoupling::MEDCouplingMeshType meshType;
   std::string dummy2;
   MEDCoupling::MEDCouplingAxisType dummy3;
   MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
-  return new MEDFileUMesh(fid,ms.front(),dt,it,mrs);
+  return T::New(fid,ms.front(),dt,it,mrs);
+}
+
+MEDFileUMesh *MEDFileUMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
+{
+  return NewForTheFirstMeshInFile<MEDFileUMesh>(fid,mrs);
+}
+
+/*!
+ * \b WARNING this implementation is dependant from MEDCouplingMappedExtrudedMesh::buildUnstructured !
+ * \sa MEDCouplingMappedExtrudedMesh::buildUnstructured , MEDCouplingMappedExtrudedMesh::build3DUnstructuredMesh
+ */
+MEDFileUMesh *MEDFileUMesh::New(const MEDCouplingMappedExtrudedMesh *mem)
+{
+  if(!mem)
+    throw INTERP_KERNEL::Exception("MEDFileUMesh::New : null input vector !");
+  MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
+  MCAuto<MEDCouplingUMesh> m3D(mem->buildUnstructured());
+  MCAuto<MEDCouplingUMesh> m2D(mem->getMesh2D()->deepCopy());
+  m2D->zipCoords();
+  m2D->setCoords(m3D->getCoords());
+  ret->setMeshAtLevel(0,m3D);
+  ret->setMeshAtLevel(-1,m2D);
+  ret->setFamilyId(GetSpeStr4ExtMesh(),std::numeric_limits<int>::max()-mem->get2DCellIdForExtrusion());
+  return ret.retn();
 }
 
 /*!
@@ -2317,7 +2347,7 @@ MEDFileUMesh *MEDFileUMesh::LoadPartOf(med_idt fid, const std::string& mName, co
 std::size_t MEDFileUMesh::getHeapMemorySizeWithoutChildren() const
 {
   std::size_t ret(MEDFileMesh::getHeapMemorySizeWithoutChildren());
-  ret+=_ms.capacity()*(sizeof(MCAuto<MEDFileUMeshSplitL1>));
+  ret+=_ms.capacity()*(sizeof(MCAuto<MEDFileUMeshSplitL1>))+_elt_str.capacity()*sizeof(MCAuto<MEDFileEltStruct4Mesh>);
   return ret;
 }
 
@@ -2332,10 +2362,12 @@ std::vector<const BigMemoryObject *> MEDFileUMesh::getDirectChildrenWithNull() c
   ret.push_back((const PartDefinition *)_part_coords);
   for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
     ret.push_back((const MEDFileUMeshSplitL1*) *it);
+  for(std::vector< MCAuto<MEDFileEltStruct4Mesh> >::const_iterator it=_elt_str.begin();it!=_elt_str.end();it++)
+    ret.push_back((const MEDFileEltStruct4Mesh *)*it);
   return ret;
 }
 
-MEDFileMesh *MEDFileUMesh::shallowCpy() const
+MEDFileUMesh *MEDFileUMesh::shallowCpy() const
 {
   MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
   return ret.retn();
@@ -2346,7 +2378,7 @@ MEDFileMesh *MEDFileUMesh::createNewEmpty() const
   return new MEDFileUMesh;
 }
 
-MEDFileMesh *MEDFileUMesh::deepCopy() const
+MEDFileUMesh *MEDFileUMesh::deepCopy() const
 {
   MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
   ret->deepCpyEquivalences(*this);
@@ -2639,7 +2671,7 @@ void MEDFileUMesh::loadPartUMeshFromFile(med_idt fid, const std::string& mName,
   int dummy0,dummy1;
   std::string dummy2;
   MEDCoupling::MEDCouplingAxisType dummy3;
-  int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy3,dummy0,dummy1,dummy2));
+  INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy3,dummy0,dummy1,dummy2));
   if(meshType!=UNSTRUCTURED)
     {
       std::ostringstream oss; oss << "loadPartUMeshFromFile : Trying to load as unstructured an existing mesh with name '" << mName << "' !";
@@ -2654,8 +2686,8 @@ void MEDFileUMesh::loadPartUMeshFromFile(med_idt fid, const std::string& mName,
  */
 void MEDFileMesh::writeJoints(med_idt fid) const
 {
-  if ( (const MEDFileJoints*) _joints )
-    _joints->write(fid);
+  if ( _joints.isNotNull() )
+    _joints->writeLL(fid);
 }
 
 /*!
@@ -2766,7 +2798,7 @@ void MEDFileUMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it,
   int dummy0,dummy1;
   std::string dummy2;
   MEDCoupling::MEDCouplingAxisType axType;
-  int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dummy2));
+  INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dummy2));
   setAxisType(axType);
   if(meshType!=UNSTRUCTURED)
     {
@@ -2775,6 +2807,17 @@ void MEDFileUMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it,
     }
   loaderl2.loadAll(fid,mid,mName,dt,it,mrs);
   dispatchLoadedPart(fid,loaderl2,mName,mrs);
+  // Structure element part...
+  int nModels(-1);
+  {
+    med_bool chgt=MED_FALSE,trsf=MED_FALSE;
+    nModels=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_STRUCT_ELEMENT,MED_GEO_ALL,MED_CONNECTIVITY,MED_NODAL,&chgt,&trsf);
+  }
+  if(nModels<=0)
+    return ;
+  _elt_str.resize(nModels);
+  for(int i=0;i<nModels;i++)
+    _elt_str[i]=MEDFileEltStruct4Mesh::New(fid,mName,dt,it,i,mrs);
 }
 
 void MEDFileUMesh::dispatchLoadedPart(med_idt fid, const MEDFileUMeshL2& loaderl2, const std::string& mName, MEDFileMeshReadSelector *mrs)
@@ -2812,7 +2855,7 @@ MEDFileUMesh::~MEDFileUMesh()
 {
 }
 
-void MEDFileUMesh::writeLL(med_idt fid) const
+void MEDFileUMesh::writeMeshLL(med_idt fid) const
 {
   const DataArrayDouble *coo=_coords;
   INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
@@ -2830,8 +2873,8 @@ void MEDFileUMesh::writeLL(med_idt fid) const
       std::string info=coo->getInfoOnComponent(i);
       std::string c,u;
       MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
-      MEDLoaderBase::safeStrCpy2(c.c_str(),MED_SNAME_SIZE-1,comp+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo
-      MEDLoaderBase::safeStrCpy2(u.c_str(),MED_SNAME_SIZE-1,unit+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo
+      MEDLoaderBase::safeStrCpy2(c.c_str(),MED_SNAME_SIZE,comp+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo
+      MEDLoaderBase::safeStrCpy2(u.c_str(),MED_SNAME_SIZE,unit+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo
     }
   MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
   if(_univ_wr_status)
@@ -3271,6 +3314,19 @@ MEDFileMesh *MEDFileUMesh::cartesianize() const
     }
 }
 
+bool MEDFileUMesh::presenceOfStructureElements() const
+{
+  for(std::vector< MCAuto<MEDFileEltStruct4Mesh> >::const_iterator it=_elt_str.begin();it!=_elt_str.end();it++)
+    if((*it).isNotNull())
+      return true;
+  return false;
+}
+
+void MEDFileUMesh::killStructureElements()
+{
+  _elt_str.clear();
+}
+
 /*!
  * Returns the optional numbers of mesh entities of a given dimension transformed using
  * DataArrayInt::invertArrayN2O2O2N().
@@ -3588,6 +3644,30 @@ MEDCoupling1GTUMesh *MEDFileUMesh::getDirectUndergroundSingleGeoTypeMesh(INTERP_
   return sp->getDirectUndergroundSingleGeoTypeMesh(gt);
 }
 
+/*!
+ * This method returns for each geo types in \a this number of cells with this geo type.
+ * This method returns info as a vector of pair. The first element of pair is geo type and the second the number of cells associated.
+ * This method also returns the number of nodes of \a this (key associated is NORM_ERROR)
+ *
+ * \sa getDistributionOfTypes
+ */
+std::vector< std::pair<int,int> > MEDFileUMesh::getAllDistributionOfTypes() const
+{
+  std::vector< std::pair<int,int> > ret;
+  std::vector<int> nel(getNonEmptyLevels());
+  for(std::vector<int>::reverse_iterator it=nel.rbegin();it!=nel.rend();it++)
+    {
+      std::vector<INTERP_KERNEL::NormalizedCellType> gt(getGeoTypesAtLevel(*it));
+      for(std::vector<INTERP_KERNEL::NormalizedCellType>::const_iterator it1=gt.begin();it1!=gt.end();it1++)
+        {
+          int nbCells(getNumberOfCellsWithType(*it1));
+          ret.push_back(std::pair<int,int>(*it1,nbCells));
+        }
+    }
+  ret.push_back(std::pair<int,int>(INTERP_KERNEL::NORM_ERROR,getNumberOfNodes()));
+  return ret;
+}
+
 /*!
  * Given a relative level \a meshDimRelToMax it returns the sorted vector of geometric types present in \a this.
  * \throw if the reqsuested \a meshDimRelToMax does not exist.
@@ -3703,12 +3783,42 @@ void MEDFileUMesh::setCoords(DataArrayDouble *coords)
   if(coords==(DataArrayDouble *)_coords)
     return ;
   coords->checkAllocated();
-  int nbOfTuples=coords->getNumberOfTuples();
+  int nbOfTuples(coords->getNumberOfTuples());
   _coords=coords;
   coords->incrRef();
   _fam_coords=DataArrayInt::New();
   _fam_coords->alloc(nbOfTuples,1);
   _fam_coords->fillWithZero();
+  _num_coords=0; _rev_num_coords=0; _name_coords=0;
+  for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
+    if((MEDFileUMeshSplitL1 *)(*it))
+      (*it)->setCoords(coords);
+}
+
+/*!
+ * Change coords without changing anything concerning families and numbering on nodes.
+ */
+void MEDFileUMesh::setCoordsForced(DataArrayDouble *coords)
+{
+  if(!coords)
+    throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoordsForced : null pointer in input !");
+  if(coords==(DataArrayDouble *)_coords)
+    return ;
+  coords->checkAllocated();
+  int nbOfTuples(coords->getNumberOfTuples());
+  if(_coords.isNull())
+    {
+      _coords=coords;
+      coords->incrRef();
+    }
+  else
+    {
+      int oldNbTuples(_coords->getNumberOfTuples());
+      if(oldNbTuples!=nbOfTuples)
+        throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoordsForced : number of tuples is not the same -> invoke setCoords instead !");
+      _coords=coords;
+      coords->incrRef();
+    }
   for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
     if((MEDFileUMeshSplitL1 *)(*it))
       (*it)->setCoords(coords);
@@ -4062,6 +4172,108 @@ DataArrayInt *MEDFileUMesh::zipCoords()
   return ret.retn();
 }
 
+/*!
+ * This method is a const method. It computes the minimal set of node ids covered by the cell extraction of \a this.
+ * The extraction of \a this is specified by the extractDef \a input map.
+ * This map tells for each level of cells, the cells kept in the extraction.
+ * 
+ * \return - a new reference of DataArrayInt that represents sorted node ids, the extraction is lying on.
+ * \sa MEDFileField1TS::extractPart, MEDFileUMesh::extractPart
+ */
+DataArrayInt *MEDFileUMesh::deduceNodeSubPartFromCellSubPart(const std::map<int, MCAuto<DataArrayInt> >& extractDef) const
+{
+  std::vector<int> levs(getNonEmptyLevels());
+  std::vector<bool> fetchedNodes(getNumberOfNodes(),false);
+  for(std::map<int, MCAuto<DataArrayInt> >::const_iterator it=extractDef.begin();it!=extractDef.end();it++)
+    {
+      if((*it).first>1)
+        throw INTERP_KERNEL::Exception("MEDFileUMesh::deduceNodeSubPartFromCellSubPart : invalid key ! Must be <=1 !");
+      if((*it).second.isNull())
+        throw INTERP_KERNEL::Exception("MEDFileUMesh::deduceNodeSubPartFromCellSubPart : presence of a value with null pointer !");
+      if((*it).first==1)
+        continue;
+      if(std::find(levs.begin(),levs.end(),(*it).first)==levs.end())
+        {
+          std::ostringstream oss; oss << "MEDFileUMesh::deduceNodeSubPartFromCellSubPart : invalid level " << (*it).first << " ! Not present in this !";
+          throw INTERP_KERNEL::Exception(oss.str());
+        }
+      MCAuto<MEDCouplingUMesh> m(getMeshAtLevel((*it).first));
+      MCAuto<MEDCouplingUMesh> mPart(m->buildPartOfMySelf((*it).second->begin(),(*it).second->end(),true));
+      mPart->computeNodeIdsAlg(fetchedNodes);
+    }
+  return DataArrayInt::BuildListOfSwitchedOn(fetchedNodes);
+}
+
+/*!
+ * This method returns a new MEDFileUMesh that is the result of the extraction of cells/nodes in \a this.
+ * 
+ * \return - a new reference of MEDFileUMesh
+ * \sa MEDFileUMesh::deduceNodeSubPartFromCellSubPart, MEDFileFields::extractPart
+ */
+MEDFileUMesh *MEDFileUMesh::extractPart(const std::map<int, MCAuto<DataArrayInt> >& extractDef) const
+{
+  MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New()); ret->setName(getName()); ret->copyFamGrpMapsFrom(*this);
+  std::vector<int> levs(getNonEmptyLevels());
+  for(std::map<int, MCAuto<DataArrayInt> >::const_iterator it=extractDef.begin();it!=extractDef.end();it++)
+    {
+      if((*it).first>1)
+        throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : invalid key ! Must be <=1 !");
+      if((*it).second.isNull())
+        throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : presence of a value with null pointer !");
+      if((*it).first==1)
+        continue;
+      if(std::find(levs.begin(),levs.end(),(*it).first)==levs.end())
+        {
+          std::ostringstream oss; oss << "MEDFileUMesh::extractPart : invalid level " << (*it).first << " ! Not present in this !";
+          throw INTERP_KERNEL::Exception(oss.str());
+        }
+      MCAuto<MEDCouplingUMesh> m(getMeshAtLevel((*it).first));
+      MCAuto<MEDCouplingUMesh> mPart(m->buildPartOfMySelf((*it).second->begin(),(*it).second->end(),true));
+      ret->setMeshAtLevel((*it).first,mPart);
+      const DataArrayInt *fam(getFamilyFieldAtLevel((*it).first)),*num(getNumberFieldAtLevel((*it).first));
+      if(fam)
+        {
+          MCAuto<DataArrayInt> famPart(fam->selectByTupleIdSafe((*it).second->begin(),(*it).second->end()));
+          ret->setFamilyFieldArr((*it).first,famPart);
+        }
+      if(num)
+        {
+          MCAuto<DataArrayInt> numPart(num->selectByTupleIdSafe((*it).second->begin(),(*it).second->end()));
+          ret->setFamilyFieldArr((*it).first,numPart);
+        }
+    }
+  std::map<int, MCAuto<DataArrayInt> >::const_iterator it2(extractDef.find(1));
+  if(it2!=extractDef.end())
+    {
+      const DataArrayDouble *coo(ret->getCoords());
+      if(!coo)
+        throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : trying to extract nodes whereas there is no nodes !");
+      MCAuto<DataArrayInt> o2nNodes(((*it2).second)->invertArrayN2O2O2N(coo->getNumberOfTuples()));
+      MCAuto<DataArrayDouble> cooPart(coo->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
+      ret->setCoords(cooPart);
+      const DataArrayInt *fam(getFamilyFieldAtLevel(1)),*num(getNumberFieldAtLevel(1));
+      if(fam)
+        {
+          MCAuto<DataArrayInt> famPart(fam->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
+          ret->setFamilyFieldArr(1,famPart);
+        }
+      if(num)
+        {
+          MCAuto<DataArrayInt> numPart(num->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
+          ret->setFamilyFieldArr(1,numPart);
+        }
+      for(std::map<int, MCAuto<DataArrayInt> >::const_iterator it3=extractDef.begin();it3!=extractDef.end();it3++)
+        {
+          if((*it3).first==1)
+            continue;
+          MCAuto<MEDCouplingUMesh> m(ret->getMeshAtLevel((*it3).first));
+          m->renumberNodesInConn(o2nNodes->begin());
+          ret->setMeshAtLevel((*it3).first,m);
+        }
+    }
+  return ret.retn();
+}
+
 /*!
  * This method performs an extrusion along a path defined by \a m1D.
  * \a this is expected to be a mesh with max mesh dimension equal to 2.
@@ -4351,6 +4563,132 @@ MEDFileUMesh *MEDFileUMesh::quadraticToLinear(double eps) const
   return ret.retn();
 }
 
+/*!
+ * Computes the symmetry of \a this.
+ * \return a new object.
+ */
+MCAuto<MEDFileUMesh> MEDFileUMesh::symmetry3DPlane(const double point[3], const double normalVector[3]) const
+{
+  MCAuto<MEDFileUMesh> ret(deepCopy());
+  DataArrayDouble *myCoo(getCoords());
+  if(myCoo)
+    {
+      MCAuto<DataArrayDouble> newCoo(myCoo->symmetry3DPlane(point,normalVector));
+      ret->setCoordsForced(newCoo);
+    }
+  return ret;
+}
+
+MCAuto<MEDFileUMesh> MEDFileUMesh::Aggregate(const std::vector<const MEDFileUMesh *>& meshes)
+{
+  if(meshes.empty())
+    throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : empty input vector !");
+  std::size_t sz(meshes.size()),i(0);
+  std::vector<const DataArrayDouble *> coos(sz);
+  std::vector<const DataArrayInt *> fam_coos(sz),num_coos(sz);
+  for(std::vector<const MEDFileUMesh *>::const_iterator it=meshes.begin();it!=meshes.end();it++,i++)
+    {
+      if(!(*it))
+        throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : presence of NULL pointer in input vector !");
+      coos[i]=(*it)->getCoords();
+      fam_coos[i]=(*it)->getFamilyFieldAtLevel(1);
+      num_coos[i]=(*it)->getNumberFieldAtLevel(1);
+    }
+  const MEDFileUMesh *ref(meshes[0]);
+  int spaceDim(ref->getSpaceDimension()),meshDim(ref->getMeshDimension());
+  std::vector<int> levs(ref->getNonEmptyLevels());
+  std::map<int, std::vector<const DataArrayInt *> > m_fam,m_renum;
+  std::map<int, std::vector< MCAuto< MEDCouplingUMesh > > > m_mesh2;
+  std::map<int, std::vector<const MEDCouplingUMesh *> > m_mesh;
+  std::map<std::string,int> map1;
+  std::map<std::string, std::vector<std::string> > map2;
+  for(std::vector<const MEDFileUMesh *>::const_iterator it=meshes.begin();it!=meshes.end();it++,i++)
+    {
+      if((*it)->getSpaceDimension()!=spaceDim)
+        throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : space dimension must be homogeneous !");
+      if((*it)->getMeshDimension()!=meshDim)
+        throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : mesh dimension must be homogeneous !");
+      if((*it)->getNonEmptyLevels()!=levs)
+        throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : levels must be the same for elements in input vector !");
+      for(std::vector<int>::const_iterator it2=levs.begin();it2!=levs.end();it2++)
+        {
+          MCAuto<MEDCouplingUMesh> locMesh((*it)->getMeshAtLevel(*it2));
+          m_mesh[*it2].push_back(locMesh); m_mesh2[*it2].push_back(locMesh);
+          m_fam[*it2].push_back((*it)->getFamilyFieldAtLevel(*it2));
+          m_renum[*it2].push_back((*it)->getNumberFieldAtLevel(*it2));
+        }
+      const std::map<std::string,int>& locMap1((*it)->getFamilyInfo());
+      for(std::map<std::string,int>::const_iterator it3=locMap1.begin();it3!=locMap1.end();it3++)
+        map1[(*it3).first]=(*it3).second;
+      const std::map<std::string, std::vector<std::string> >& locMap2((*it)->getGroupInfo());
+      for(std::map<std::string, std::vector<std::string> >::const_iterator it4=locMap2.begin();it4!=locMap2.end();it4++)
+        map2[(*it4).first]=(*it4).second;
+    }
+  // Easy part : nodes
+  MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
+  MCAuto<DataArrayDouble> coo(DataArrayDouble::Aggregate(coos));
+  ret->setCoords(coo);
+  if(std::find(fam_coos.begin(),fam_coos.end(),(const DataArrayInt *)0)==fam_coos.end())
+    {
+      MCAuto<DataArrayInt> fam_coo(DataArrayInt::Aggregate(fam_coos));
+      ret->setFamilyFieldArr(1,fam_coo);
+    }
+  if(std::find(num_coos.begin(),num_coos.end(),(const DataArrayInt *)0)==num_coos.end())
+    {
+      MCAuto<DataArrayInt> num_coo(DataArrayInt::Aggregate(num_coos));
+      ret->setRenumFieldArr(1,num_coo);
+    }
+  // cells
+  for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
+    {
+      std::map<int, std::vector<const MEDCouplingUMesh *> >::const_iterator it2(m_mesh.find(*it));
+      if(it2==m_mesh.end())
+        throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : internal error 1 !");
+      MCAuto<MEDCouplingUMesh> mesh(MEDCouplingUMesh::MergeUMeshes((*it2).second));
+      mesh->setCoords(coo); mesh->setName(ref->getName());
+      MCAuto<DataArrayInt> renum(mesh->sortCellsInMEDFileFrmt());
+      ret->setMeshAtLevel(*it,mesh);
+      std::map<int, std::vector<const DataArrayInt *> >::const_iterator it3(m_fam.find(*it)),it4(m_renum.find(*it));
+      if(it3!=m_fam.end())
+        {
+          const std::vector<const DataArrayInt *>& fams((*it3).second);
+          if(std::find(fams.begin(),fams.end(),(const DataArrayInt *)0)==fams.end())
+            {
+              MCAuto<DataArrayInt> famm(DataArrayInt::Aggregate(fams));
+              famm->renumberInPlace(renum->begin());
+              ret->setFamilyFieldArr(*it,famm);
+            }
+        }
+      if(it4!=m_renum.end())
+        {
+          const std::vector<const DataArrayInt *>& renums((*it4).second);
+          if(std::find(renums.begin(),renums.end(),(const DataArrayInt *)0)==renums.end())
+            {
+              MCAuto<DataArrayInt> renumm(DataArrayInt::Aggregate(renums));
+              renumm->renumberInPlace(renum->begin());
+              ret->setRenumFieldArr(*it,renumm);
+            }
+        }
+    }
+  //
+  ret->setFamilyInfo(map1);
+  ret->setGroupInfo(map2);
+  ret->setName(ref->getName());
+  return ret;
+}
+
+MEDCouplingMappedExtrudedMesh *MEDFileUMesh::convertToExtrudedMesh() const
+{
+  if(getMeshDimension()!=3)
+    throw INTERP_KERNEL::Exception("MEDFileUMesh::convertToExtrudedMesh : works only for 3D mesh !");
+  MCAuto<MEDCouplingUMesh> m3D(getMeshAtLevel(0)),m2D(getMeshAtLevel(-1));
+  if(m3D.isNull() || m2D.isNull())
+    throw INTERP_KERNEL::Exception("MEDFileUMesh::convertToExtrudedMesh : this must be defined both at level 0 and level -1 !");
+  int zeId(std::numeric_limits<int>::max()-getFamilyId(GetSpeStr4ExtMesh()));
+  MCAuto<MEDCouplingMappedExtrudedMesh> ret(MEDCouplingMappedExtrudedMesh::New(m3D,m2D,zeId));
+  return ret.retn();
+}
+
 void MEDFileUMesh::serialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr, std::vector< MCAuto<DataArrayInt> >& bigArraysI, MCAuto<DataArrayDouble>& bigArrayD)
 {
   clearNonDiscrAttributes();
@@ -6112,20 +6450,13 @@ MEDFileCMesh *MEDFileCMesh::New()
  */
 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
 {
-  std::vector<std::string> ms(MEDCoupling::GetMeshNames(fileName));
-  if(ms.empty())
-    {
-      std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
-      throw INTERP_KERNEL::Exception(oss.str().c_str());
-    }
-  MEDFileUtilities::CheckFileForRead(fileName);
-  MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
-  int dt,it;
-  MEDCoupling::MEDCouplingMeshType meshType;
-  std::string dummy2;
-  MEDCoupling::MEDCouplingAxisType dummy3;
-  MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
-  return new MEDFileCMesh(fid,ms.front(),dt,it,mrs);
+  MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
+  return New(fid,mrs);
+}
+
+MEDFileCMesh *MEDFileCMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
+{
+  return NewForTheFirstMeshInFile<MEDFileCMesh>(fid,mrs);
 }
 
 /*!
@@ -6144,8 +6475,12 @@ MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, MEDFileMeshReadSele
  */
 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
 {
-  MEDFileUtilities::CheckFileForRead(fileName);
-  MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
+  MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
+  return New(fid,mName,dt,it,mrs);
+}
+
+MEDFileCMesh *MEDFileCMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
+{
   return new MEDFileCMesh(fid,mName,dt,it,mrs);
 }
 
@@ -6203,7 +6538,7 @@ std::string MEDFileCMesh::advancedRepr() const
   return simpleRepr();
 }
 
-MEDFileMesh *MEDFileCMesh::shallowCpy() const
+MEDFileCMesh *MEDFileCMesh::shallowCpy() const
 {
   MCAuto<MEDFileCMesh> ret(new MEDFileCMesh(*this));
   return ret.retn();
@@ -6214,7 +6549,7 @@ MEDFileMesh *MEDFileCMesh::createNewEmpty() const
   return new MEDFileCMesh;
 }
 
-MEDFileMesh *MEDFileCMesh::deepCopy() const
+MEDFileCMesh *MEDFileCMesh::deepCopy() const
 {
   MCAuto<MEDFileCMesh> ret(new MEDFileCMesh(*this));
   ret->deepCpyEquivalences(*this);
@@ -6291,7 +6626,7 @@ void MEDFileCMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it,
   int dummy0,dummy1;
   std::string dtunit;
   MEDCoupling::MEDCouplingAxisType axType;
-  int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit);
+  INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit));
   if(meshType!=CARTESIAN)
     {
       std::ostringstream oss; oss << "Trying to load as cartesian an existing mesh with name '" << mName << "' that is NOT cartesian !";
@@ -6359,7 +6694,7 @@ MEDFileMesh *MEDFileCMesh::cartesianize() const
     }
 }
 
-void MEDFileCMesh::writeLL(med_idt fid) const
+void MEDFileCMesh::writeMeshLL(med_idt fid) const
 {
   INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
   INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
@@ -6408,28 +6743,25 @@ MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New()
   return new MEDFileCurveLinearMesh;
 }
 
+MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
+{
+  return NewForTheFirstMeshInFile<MEDFileCurveLinearMesh>(fid,mrs);
+}
+
 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
 {
-  std::vector<std::string> ms(MEDCoupling::GetMeshNames(fileName));
-  if(ms.empty())
-    {
-      std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
-      throw INTERP_KERNEL::Exception(oss.str().c_str());
-    }
-  MEDFileUtilities::CheckFileForRead(fileName);
-  MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
-  int dt,it;
-  MEDCoupling::MEDCouplingMeshType meshType;
-  MEDCoupling::MEDCouplingAxisType dummy3;
-  std::string dummy2;
-  MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
-  return new MEDFileCurveLinearMesh(fid,ms.front(),dt,it,mrs);
+  MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
+  return New(fid,mrs);
 }
 
 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
 {
-  MEDFileUtilities::CheckFileForRead(fileName);
-  MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
+  MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
+  return New(fid,mName,dt,it,mrs);
+}
+
+MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
+{
   return new MEDFileCurveLinearMesh(fid,mName,dt,it,mrs);
 }
 
@@ -6445,7 +6777,7 @@ std::vector<const BigMemoryObject *> MEDFileCurveLinearMesh::getDirectChildrenWi
   return ret;
 }
 
-MEDFileMesh *MEDFileCurveLinearMesh::shallowCpy() const
+MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::shallowCpy() const
 {
   MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
   return ret.retn();
@@ -6456,7 +6788,7 @@ MEDFileMesh *MEDFileCurveLinearMesh::createNewEmpty() const
   return new MEDFileCurveLinearMesh;
 }
 
-MEDFileMesh *MEDFileCurveLinearMesh::deepCopy() const
+MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::deepCopy() const
 {
   MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
   ret->deepCpyEquivalences(*this);
@@ -6590,7 +6922,7 @@ catch(INTERP_KERNEL::Exception& e)
     throw e;
 }
 
-void MEDFileCurveLinearMesh::writeLL(med_idt fid) const
+void MEDFileCurveLinearMesh::writeMeshLL(med_idt fid) const
 {
   INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
   INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
@@ -6604,7 +6936,7 @@ void MEDFileCurveLinearMesh::writeLL(med_idt fid) const
   INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
   const DataArrayDouble *coords=_clmesh->getCoords();
   if(!coords)
-    throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::writeLL : no coordinates set !");
+    throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::writeMeshLL : no coordinates set !");
   for(int i=0;i<spaceDim;i++)
     {
       std::string info(_clmesh->getCoords()->getInfoOnComponent(i));
@@ -6632,7 +6964,7 @@ void MEDFileCurveLinearMesh::loadLL(med_idt fid, const std::string& mName, int d
   int dummy0,dummy1;
   std::string dtunit;
   MEDCoupling::MEDCouplingAxisType axType;
-  int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit);
+  INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit));
   setAxisType(axType);
   if(meshType!=CURVE_LINEAR)
     {
@@ -6652,21 +6984,33 @@ MEDFileMeshMultiTS *MEDFileMeshMultiTS::New()
   return new MEDFileMeshMultiTS;
 }
 
+MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(med_idt fid)
+{
+  return new MEDFileMeshMultiTS(fid);
+}
+
 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName)
 {
-  return new MEDFileMeshMultiTS(fileName);
+  MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
+  return New(fid);
+}
+
+MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(med_idt fid, const std::string& mName)
+{
+  return new MEDFileMeshMultiTS(fid,mName);
 }
 
 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName, const std::string& mName)
 {
-  return new MEDFileMeshMultiTS(fileName,mName);
+  MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
+  return New(fid,mName);
 }
 
 MEDFileMeshMultiTS *MEDFileMeshMultiTS::deepCopy() const
 {
-  MCAuto<MEDFileMeshMultiTS> ret=MEDFileMeshMultiTS::New();
+  MCAuto<MEDFileMeshMultiTS> ret(MEDFileMeshMultiTS::New());
   std::vector< MCAuto<MEDFileMesh> > meshOneTs(_mesh_one_ts.size());
-  std::size_t i=0;
+  std::size_t i(0);
   for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++,i++)
     if((const MEDFileMesh *)*it)
       meshOneTs[i]=(*it)->deepCopy();
@@ -6762,7 +7106,23 @@ void MEDFileMeshMultiTS::setJoints( MEDFileJoints* joints )
     }
 }
 
-void MEDFileMeshMultiTS::write(med_idt fid) const
+bool MEDFileMeshMultiTS::presenceOfStructureElements() const
+{
+  for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
+    if((*it).isNotNull())
+      if((*it)->presenceOfStructureElements())
+        return true;
+  return false;
+}
+
+void MEDFileMeshMultiTS::killStructureElements()
+{
+  for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
+    if((*it).isNotNull())
+      (*it)->killStructureElements();
+}
+
+void MEDFileMeshMultiTS::writeLL(med_idt fid) const
 {
   MEDFileJoints *joints(getJoints());
   bool jointsWritten(false);
@@ -6775,65 +7135,53 @@ void MEDFileMeshMultiTS::write(med_idt fid) const
         jointsWritten = true;
 
       (*it)->copyOptionsFrom(*this);
-      (*it)->write(fid);
+      (*it)->writeLL(fid);
     }
 
   (const_cast<MEDFileMeshMultiTS*>(this))->setJoints( joints ); // restore joints
 }
 
-void MEDFileMeshMultiTS::write(const std::string& fileName, int mode) const
+void MEDFileMeshMultiTS::loadFromFile(med_idt fid, const std::string& mName)
 {
-  med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
-  MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
-  std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\""; 
-  MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
-  write(fid);
-}
-
-void MEDFileMeshMultiTS::loadFromFile(const std::string& fileName, const std::string& mName)
-{
-  MEDFileJoints* joints = 0;
+  MEDFileJoints *joints(0);
   if ( !_mesh_one_ts.empty() && getOneTimeStep() )
     {
       // joints of mName already read, pass them to MEDFileMesh::New() to prevent repeated reading
       joints = getOneTimeStep()->getJoints();
     }
-
   _mesh_one_ts.clear();  //for the moment to be improved
-  _mesh_one_ts.push_back( MEDFileMesh::New(fileName,mName,-1,-1,0, joints ));
+  _mesh_one_ts.push_back( MEDFileMesh::New(fid,mName,-1,-1,0, joints ));
 }
 
 MEDFileMeshMultiTS::MEDFileMeshMultiTS()
 {
 }
 
-MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName)
+MEDFileMeshMultiTS::MEDFileMeshMultiTS(med_idt fid)
 try
 {
-  std::vector<std::string> ms(MEDCoupling::GetMeshNames(fileName));
+  std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
     if(ms.empty())
       {
-        std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
+        std::ostringstream oss; oss << "MEDFileMeshMultiTS : no meshes in file \"" << FileNameFromFID(fid) << "\" !";
         throw INTERP_KERNEL::Exception(oss.str().c_str());
       }
-    MEDFileUtilities::CheckFileForRead(fileName);
-    MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
     int dt,it;
     MEDCoupling::MEDCouplingMeshType meshType;
     std::string dummy2;
     MEDCoupling::MEDCouplingAxisType dummy3;
     MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
-    loadFromFile(fileName,ms.front());
+    loadFromFile(fid,ms.front());
 }
 catch(INTERP_KERNEL::Exception& e)
 {
     throw e;
 }
 
-MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName, const std::string& mName)
+MEDFileMeshMultiTS::MEDFileMeshMultiTS(med_idt fid, const std::string& mName)
 try
 {
-    loadFromFile(fileName,mName);
+    loadFromFile(fid,mName);
 }
 catch(INTERP_KERNEL::Exception& e)
 {
@@ -6845,30 +7193,28 @@ MEDFileMeshes *MEDFileMeshes::New()
   return new MEDFileMeshes;
 }
 
+MEDFileMeshes *MEDFileMeshes::New(med_idt fid)
+{
+  return new MEDFileMeshes(fid);
+}
+
 MEDFileMeshes *MEDFileMeshes::New(const std::string& fileName)
 {
-  return new MEDFileMeshes(fileName);
+  MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
+  return New(fid);
 }
 
-void MEDFileMeshes::write(med_idt fid) const
+void MEDFileMeshes::writeLL(med_idt fid) const
 {
   checkConsistencyLight();
   for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
     {
       (*it)->copyOptionsFrom(*this);
-      (*it)->write(fid);
+      (*it)->writeLL(fid);
     }
 }
 
-void MEDFileMeshes::write(const std::string& fileName, int mode) const
-{
-  med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
-  MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
-  std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\""; 
-  MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
-  checkConsistencyLight();
-  write(fid);
-}
+//  MEDFileMeshes::writ checkConsistencyLight();
 
 int MEDFileMeshes::getNumberOfMeshes() const
 {
@@ -6982,23 +7328,23 @@ void MEDFileMeshes::destroyMeshAtPos(int i)
   _meshes.erase(_meshes.begin()+i);
 }
 
-void MEDFileMeshes::loadFromFile(const std::string& fileName)
+void MEDFileMeshes::loadFromFile(med_idt fid)
 {
-  std::vector<std::string> ms(MEDCoupling::GetMeshNames(fileName));
+  std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
   int i=0;
   _meshes.resize(ms.size());
   for(std::vector<std::string>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
-    _meshes[i]=MEDFileMeshMultiTS::New(fileName,(*it));
+    _meshes[i]=MEDFileMeshMultiTS::New(fid,(*it));
 }
 
 MEDFileMeshes::MEDFileMeshes()
 {
 }
 
-MEDFileMeshes::MEDFileMeshes(const std::string& fileName)
+MEDFileMeshes::MEDFileMeshes(med_idt fid)
 try
 {
-    loadFromFile(fileName);
+    loadFromFile(fid);
 }
 catch(INTERP_KERNEL::Exception& /*e*/)
 {
@@ -7011,7 +7357,7 @@ MEDFileMeshes *MEDFileMeshes::deepCopy() const
   for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
     if((const MEDFileMeshMultiTS *)*it)
       meshes[i]=(*it)->deepCopy();
-  MCAuto<MEDFileMeshes> ret=MEDFileMeshes::New();
+  MCAuto<MEDFileMeshes> ret(MEDFileMeshes::New());
   ret->_meshes=meshes;
   return ret.retn();
 }
@@ -7069,6 +7415,22 @@ void MEDFileMeshes::checkConsistencyLight() const
     }
 }
 
+bool MEDFileMeshes::presenceOfStructureElements() const
+{
+  for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
+    if((*it).isNotNull())
+      if((*it)->presenceOfStructureElements())
+        return true;
+  return false;
+}
+
+void MEDFileMeshes::killStructureElements()
+{
+  for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
+    if((*it).isNotNull())
+      (*it)->killStructureElements();
+}
+
 MEDFileMeshesIterator::MEDFileMeshesIterator(MEDFileMeshes *ms):_ms(ms),_iter_id(0),_nb_iter(0)
 {
   if(ms)
@@ -7095,3 +7457,34 @@ MEDFileMesh *MEDFileMeshesIterator::nextt()
   else
     return 0;
 }
+
+INTERP_KERNEL::NormalizedCellType MEDFileMesh::ConvertFromMEDFileGeoType(med_geometry_type geoType)
+{
+  med_geometry_type *pos(std::find(typmai,typmai+MED_N_CELL_FIXED_GEO,geoType));
+  if(pos==typmai+MED_N_CELL_FIXED_GEO)
+    {
+      if(geoType==MED_NO_GEOTYPE)
+        return INTERP_KERNEL::NORM_ERROR;
+      std::ostringstream oss; oss << "MEDFileMesh::ConvertFromMEDFileGeoType : no entry with " << geoType << " !"; 
+      throw INTERP_KERNEL::Exception(oss.str());
+    }
+  return typmai2[std::distance(typmai,pos)];
+}
+
+TypeOfField MEDFileMesh::ConvertFromMEDFileEntity(med_entity_type etype)
+{
+  switch(etype)
+    {
+    case MED_NODE:
+      return ON_NODES;
+    case MED_CELL:
+      return ON_CELLS;
+    default:
+      {
+        std::ostringstream oss; oss << "EDFileMesh::ConvertFromMEDFileEntity : not recognized entity " << etype << " !";
+        throw INTERP_KERNEL::Exception(oss.str());
+      }
+    }
+}
+
+