Salome HOME
Bug correction of MEDFileUMesh.zipCoords seen in // context.
[modules/med.git] / src / MEDLoader / MEDFileMesh.cxx
index 569c46e9cbad903e2d65ce4e6c76c373d3324db3..b48f408356975b2c7a2ac1933c4d4f69940b22fc 100644 (file)
@@ -1,9 +1,9 @@
-// Copyright (C) 2007-2013  CEA/DEN, EDF R&D
+// Copyright (C) 2007-2014  CEA/DEN, EDF R&D
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 // License as published by the Free Software Foundation; either
-// version 2.1 of the License.
+// version 2.1 of the License, or (at your option) any later version.
 //
 // This library is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -32,6 +32,8 @@
 #include <limits>
 #include <cmath>
 
+extern med_geometry_type typmai3[34];
+
 using namespace ParaMEDMEM;
 
 const char MEDFileMesh::DFT_FAM_NAME[]="FAMILLE_ZERO";
@@ -40,9 +42,9 @@ MEDFileMesh::MEDFileMesh():_order(-1),_iteration(-1),_time(0.),_univ_wr_status(t
 {
 }
 
-std::size_t MEDFileMesh::getHeapMemorySize() const
+std::size_t MEDFileMesh::getHeapMemorySizeWithoutChildren() const
 {
-  std::size_t ret=_dt_unit.capacity()+_name.capacity()+_univ_name.capacity()+_desc_name.capacity();
+  std::size_t ret(_dt_unit.capacity()+_name.capacity()+_univ_name.capacity()+_desc_name.capacity());
   for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
     {
       ret+=(*it).first.capacity()+(*it).second.capacity()*sizeof(std::string);
@@ -54,6 +56,11 @@ std::size_t MEDFileMesh::getHeapMemorySize() const
   return ret;
 }
 
+std::vector<const BigMemoryObject *> MEDFileMesh::getDirectChildrenWithNull() const
+{
+  return std::vector<const BigMemoryObject *>();
+}
+
 /*!
  * Returns a new MEDFileMesh holding the mesh data that has been read from a given MED
  * file. The first mesh in the file is loaded.
@@ -64,7 +71,7 @@ std::size_t MEDFileMesh::getHeapMemorySize() const
  *  \throw If there is no meshes in the file.
  *  \throw If the mesh in the file is of a not supported type.
  */
-MEDFileMesh *MEDFileMesh::New(const char *fileName, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
+MEDFileMesh *MEDFileMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
 {
   std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
   if(ms.empty())
@@ -74,28 +81,28 @@ MEDFileMesh *MEDFileMesh::New(const char *fileName, MEDFileMeshReadSelector *mrs
     }
   MEDFileUtilities::CheckFileForRead(fileName);
   ParaMEDMEM::MEDCouplingMeshType meshType;
-  MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
+  MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
   int dt,it;
   std::string dummy2;
-  MEDFileMeshL2::GetMeshIdFromName(fid,ms.front().c_str(),meshType,dt,it,dummy2);
+  MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
   switch(meshType)
-    {
+  {
     case UNSTRUCTURED:
       {
         MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=MEDFileUMesh::New();
-        ret->loadUMeshFromFile(fid,ms.front().c_str(),dt,it,mrs);
+        ret->loadUMeshFromFile(fid,ms.front(),dt,it,mrs);
         return (MEDFileUMesh *)ret.retn();
       }
     case CARTESIAN:
       {
         MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=MEDFileCMesh::New();
-        ret->loadCMeshFromFile(fid,ms.front().c_str(),dt,it,mrs);
+        ret->loadCMeshFromFile(fid,ms.front(),dt,it,mrs);
         return (MEDFileCMesh *)ret.retn();
       }
     case CURVE_LINEAR:
       {
         MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=MEDFileCurveLinearMesh::New();
-        ret->loadCLMeshFromFile(fid,ms.front().c_str(),dt,it,mrs);
+        ret->loadCLMeshFromFile(fid,ms.front(),dt,it,mrs);
         return (MEDFileCurveLinearMesh *)ret.retn();
       }
     default:
@@ -103,7 +110,7 @@ MEDFileMesh *MEDFileMesh::New(const char *fileName, MEDFileMeshReadSelector *mrs
         std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << ms.front() << "' exists but unsupported type yet !";
         throw INTERP_KERNEL::Exception(oss.str().c_str());
       }
-    }
+  }
 }
 
 /*!
@@ -120,16 +127,16 @@ MEDFileMesh *MEDFileMesh::New(const char *fileName, MEDFileMeshReadSelector *mrs
  *  \throw If there is no mesh with given attributes in the file.
  *  \throw If the mesh in the file is of a not supported type.
  */
-MEDFileMesh *MEDFileMesh::New(const char *fileName, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
+MEDFileMesh *MEDFileMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
 {
   MEDFileUtilities::CheckFileForRead(fileName);
   ParaMEDMEM::MEDCouplingMeshType meshType;
-  MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
+  MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
   int dummy0,dummy1;
   std::string dummy2;
   MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2);
   switch(meshType)
-    {
+  {
     case UNSTRUCTURED:
       {
         MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=MEDFileUMesh::New();
@@ -153,7 +160,7 @@ MEDFileMesh *MEDFileMesh::New(const char *fileName, const char *mName, int dt, i
         std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << mName << "' exists but unsupported type yet !";
         throw INTERP_KERNEL::Exception(oss.str().c_str());
       }
-    }
+  }
 }
 
 /*!
@@ -163,7 +170,7 @@ MEDFileMesh *MEDFileMesh::New(const char *fileName, const char *mName, int dt, i
  *  \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 throw(INTERP_KERNEL::Exception)
+void MEDFileMesh::write(med_idt fid) const
 {
   if(!existsFamily(0))
     const_cast<MEDFileMesh *>(this)->addFamily(DFT_FAM_NAME,0);
@@ -182,12 +189,12 @@ void MEDFileMesh::write(med_idt fid) const throw(INTERP_KERNEL::Exception)
  *  \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 char *fileName, int mode) const throw(INTERP_KERNEL::Exception)
+void MEDFileMesh::write(const std::string& fileName, int mode) const
 {
   med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
-  MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,medmod);
+  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().c_str());
+  MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
   write(fid);
 }
 
@@ -238,15 +245,20 @@ bool MEDFileMesh::isEqual(const MEDFileMesh *other, double eps, std::string& wha
   return true;
 }
 
+void MEDFileMesh::setName(const std::string& name)
+{
+  _name=name;
+}
+
 /*!
  * Clears redundant attributes of incorporated data arrays.
  */
 void MEDFileMesh::clearNonDiscrAttributes() const
 {
-  
+
 }
 
-bool MEDFileMesh::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab) throw(INTERP_KERNEL::Exception)
+bool MEDFileMesh::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
 {
   for(std::vector< std::pair<std::string,std::string> >::const_iterator it=modifTab.begin();it!=modifTab.end();it++)
     {
@@ -269,13 +281,52 @@ void MEDFileMesh::copyFamGrpMapsFrom(const MEDFileMesh& other)
   _families=other._families;
 }
 
+
+/*!
+ * This method clear all the groups in the map.
+ * So this method does not operate at all on arrays.
+ * So this method can lead to orphan families.
+ * 
+ * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamGrpMaps
+ */
+void MEDFileMesh::clearGrpMap()
+{
+  _groups.clear();
+}
+
+/*!
+ * This method clear all the families in the map.
+ * So this method does not operate at all on arrays.
+ * WARNING ! if there are some groups lying on cleared families, those groups will be impacted !
+ *
+ * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamGrpMaps
+ */
+void MEDFileMesh::clearFamMap()
+{
+  _families.clear();
+}
+
+/*!
+ * This method clear all the families and groups in the map.
+ * So this method does not operate at all on arrays.
+ * As all groups and families entry will be removed after 
+ * the call of MEDFileMesh::setFamilyFieldArr method with 0 or None (python) in the 2nd parameter can be useful to reduce the size of the object.
+ *
+ * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamMap
+ */
+void MEDFileMesh::clearFamGrpMaps()
+{
+  clearGrpMap();
+  clearFamMap();
+}
+
 /*!
  * Returns names of families constituting a group.
  *  \param [in] name - the name of the group of interest.
  *  \return std::vector<std::string> - a sequence of names of the families.
  *  \throw If the name of a nonexistent group is specified.
  */
-std::vector<std::string> MEDFileMesh::getFamiliesOnGroup(const char *name) const throw(INTERP_KERNEL::Exception)
+std::vector<std::string> MEDFileMesh::getFamiliesOnGroup(const std::string& name) const
 {
   std::string oname(name);
   std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.find(oname);
@@ -295,7 +346,7 @@ std::vector<std::string> MEDFileMesh::getFamiliesOnGroup(const char *name) const
  *  \return std::vector<std::string> - a sequence of names of the families.
  *  \throw If a name of a nonexistent group is present in \a grps.
  */
-std::vector<std::string> MEDFileMesh::getFamiliesOnGroups(const std::vector<std::string>& grps) const throw(INTERP_KERNEL::Exception)
+std::vector<std::string> MEDFileMesh::getFamiliesOnGroups(const std::vector<std::string>& grps) const
 {
   std::set<std::string> fams;
   for(std::vector<std::string>::const_iterator it=grps.begin();it!=grps.end();it++)
@@ -320,7 +371,7 @@ std::vector<std::string> MEDFileMesh::getFamiliesOnGroups(const std::vector<std:
  *  \return std::vector<int> - sequence of ids of the families.
  *  \throw If the name of a nonexistent group is specified.
  */
-std::vector<int> MEDFileMesh::getFamiliesIdsOnGroup(const char *name) const throw(INTERP_KERNEL::Exception)
+std::vector<int> MEDFileMesh::getFamiliesIdsOnGroup(const std::string& name) const
 {
   std::string oname(name);
   std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.find(oname);
@@ -341,7 +392,7 @@ std::vector<int> MEDFileMesh::getFamiliesIdsOnGroup(const char *name) const thro
  *  \param [in] name - the name of the group of interest.
  *  \param [in] fams - a sequence of names of families constituting the group.
  */
-void MEDFileMesh::setFamiliesOnGroup(const char *name, const std::vector<std::string>& fams) throw(INTERP_KERNEL::Exception)
+void MEDFileMesh::setFamiliesOnGroup(const std::string& name, const std::vector<std::string>& fams)
 {
   std::string oname(name);
   _groups[oname]=fams;
@@ -361,7 +412,7 @@ void MEDFileMesh::setFamiliesOnGroup(const char *name, const std::vector<std::st
  *  \param [in] famIds - a sequence of ids of families constituting the group.
  *  \throw If a family name is not found by its id.
  */
-void MEDFileMesh::setFamiliesIdsOnGroup(const char *name, const std::vector<int>& famIds) throw(INTERP_KERNEL::Exception)
+void MEDFileMesh::setFamiliesIdsOnGroup(const std::string& name, const std::vector<int>& famIds)
 {
   std::string oname(name);
   std::vector<std::string> fams(famIds.size());
@@ -379,7 +430,7 @@ void MEDFileMesh::setFamiliesIdsOnGroup(const char *name, const std::vector<int>
  *  \param [in] name - the name of the family of interest.
  *  \return std::vector<std::string> - a sequence of names of groups including the family.
  */
-std::vector<std::string> MEDFileMesh::getGroupsOnFamily(const char *name) const throw(INTERP_KERNEL::Exception)
+std::vector<std::string> MEDFileMesh::getGroupsOnFamily(const std::string& name) const
 {
   std::vector<std::string> ret;
   for(std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();it1!=_groups.end();it1++)
@@ -400,7 +451,7 @@ std::vector<std::string> MEDFileMesh::getGroupsOnFamily(const char *name) const
  *  \param [in] grps - a sequence of group names to add the family in.
  *  \throw If a family named \a famName not yet exists.
  */
-void MEDFileMesh::setGroupsOnFamily(const char *famName, const std::vector<std::string>& grps) throw(INTERP_KERNEL::Exception)
+void MEDFileMesh::setGroupsOnFamily(const std::string& famName, const std::vector<std::string>& grps)
 {
   std::string fName(famName);
   const std::map<std::string,int>::const_iterator it=_families.find(fName);
@@ -454,13 +505,13 @@ std::vector<std::string> MEDFileMesh::getFamiliesNames() const
  * Changes a name of every family, included in one group only, to be same as the group name.
  *  \throw If there are families with equal names in \a this mesh.
  */
-void MEDFileMesh::assignFamilyNameWithGroupName() throw(INTERP_KERNEL::Exception)
+void MEDFileMesh::assignFamilyNameWithGroupName()
 {
   std::map<std::string, std::vector<std::string> > groups(_groups);
   std::map<std::string,int> newFams;
   for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
     {
-      std::vector<std::string> grps=getGroupsOnFamily((*it).first.c_str());
+      std::vector<std::string> grps=getGroupsOnFamily((*it).first);
       if(grps.size()==1 && groups[grps[0]].size()==1)
         {
           if(newFams.find(grps[0])!=newFams.end())
@@ -492,7 +543,7 @@ void MEDFileMesh::assignFamilyNameWithGroupName() throw(INTERP_KERNEL::Exception
  * 
  * \return the removed groups.
  */
-std::vector<std::string> MEDFileMesh::removeEmptyGroups() throw(INTERP_KERNEL::Exception)
+std::vector<std::string> MEDFileMesh::removeEmptyGroups()
 {
   std::vector<std::string> ret;
   std::map<std::string, std::vector<std::string> > newGrps;
@@ -513,7 +564,7 @@ std::vector<std::string> MEDFileMesh::removeEmptyGroups() throw(INTERP_KERNEL::E
  *  \param [in] name - the name of the group to remove.
  *  \throw If no group with such a \a name exists.
  */
-void MEDFileMesh::removeGroup(const char *name) throw(INTERP_KERNEL::Exception)
+void MEDFileMesh::removeGroup(const std::string& name)
 {
   std::string oname(name);
   std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
@@ -532,7 +583,7 @@ void MEDFileMesh::removeGroup(const char *name) throw(INTERP_KERNEL::Exception)
  *  \param [in] name - the name of the family to remove.
  *  \throw If no family with such a \a name exists.
  */
-void MEDFileMesh::removeFamily(const char *name) throw(INTERP_KERNEL::Exception)
+void MEDFileMesh::removeFamily(const std::string& name)
 {
   std::string oname(name);
   std::map<std::string, int >::iterator it=_families.find(oname);
@@ -562,7 +613,7 @@ void MEDFileMesh::removeFamily(const char *name) throw(INTERP_KERNEL::Exception)
  *
  * \sa MEDFileMesh::removeOrphanFamilies.
  */
-std::vector<std::string> MEDFileMesh::removeOrphanGroups() throw(INTERP_KERNEL::Exception)
+std::vector<std::string> MEDFileMesh::removeOrphanGroups()
 {
   removeOrphanFamilies();
   return removeEmptyGroups();
@@ -575,7 +626,7 @@ std::vector<std::string> MEDFileMesh::removeOrphanGroups() throw(INTERP_KERNEL::
  * \return - The list of removed families names.
  * \sa MEDFileMesh::removeOrphanGroups.
  */
-std::vector<std::string> MEDFileMesh::removeOrphanFamilies() throw(INTERP_KERNEL::Exception)
+std::vector<std::string> MEDFileMesh::removeOrphanFamilies()
 {
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allFamIdsInUse=computeAllFamilyIdsInUse();
   std::vector<std::string> ret;
@@ -594,7 +645,7 @@ std::vector<std::string> MEDFileMesh::removeOrphanFamilies() throw(INTERP_KERNEL
       else
         {
           ret.push_back((*it).first);
-          std::vector<std::string> grpsOnEraseFam=getGroupsOnFamily((*it).first.c_str());
+          std::vector<std::string> grpsOnEraseFam=getGroupsOnFamily((*it).first);
           for(std::vector<std::string>::const_iterator it2=grpsOnEraseFam.begin();it2!=grpsOnEraseFam.end();it2++)
             {
               std::map<std::string, std::vector<std::string> >::iterator it3=grps.find(*it2);//it3!=grps.empty() thanks to copy
@@ -616,7 +667,7 @@ std::vector<std::string> MEDFileMesh::removeOrphanFamilies() throw(INTERP_KERNEL
  *  \throw If no group named \a oldName exists in \a this mesh.
  *  \throw If a group named \a newName already exists.
  */
-void MEDFileMesh::changeGroupName(const char *oldName, const char *newName) throw(INTERP_KERNEL::Exception)
+void MEDFileMesh::changeGroupName(const std::string& oldName, const std::string& newName)
 {
   std::string oname(oldName);
   std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
@@ -645,7 +696,7 @@ void MEDFileMesh::changeGroupName(const char *oldName, const char *newName) thro
  *  \param [in] oldId - a current id of the family.
  *  \param [in] newId - a new family id.
  */
-void MEDFileMesh::changeFamilyId(int oldId, int newId) throw(INTERP_KERNEL::Exception)
+void MEDFileMesh::changeFamilyId(int oldId, int newId)
 {
   changeFamilyIdArr(oldId,newId);
   std::map<std::string,int> fam2;
@@ -666,7 +717,7 @@ void MEDFileMesh::changeFamilyId(int oldId, int newId) throw(INTERP_KERNEL::Exce
  *  \throw If no family named \a oldName exists in \a this mesh.
  *  \throw If a family named \a newName already exists.
  */
-void MEDFileMesh::changeFamilyName(const char *oldName, const char *newName) throw(INTERP_KERNEL::Exception)
+void MEDFileMesh::changeFamilyName(const std::string& oldName, const std::string& newName)
 {
   std::string oname(oldName);
   std::map<std::string, int >::iterator it=_families.find(oname);
@@ -764,7 +815,7 @@ bool MEDFileMesh::areGrpsEqual(const MEDFileMesh *other, std::string& what) cons
         {
           oss << " Group \"" << (*it).first << "\" on following families :\n";
           for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
-        oss << "    \"" << *it2 << "\n";
+            oss << "    \"" << *it2 << "\n";
         }
       oss << "Second group description :\n";
       for(std::map<std::string, std::vector<std::string> >::const_iterator it=other->_groups.begin();it!=other->_groups.end();it++)
@@ -783,7 +834,7 @@ bool MEDFileMesh::areGrpsEqual(const MEDFileMesh *other, std::string& what) cons
  *  \param [in] groupName - the group name.
  *  \return bool - \c true the group \a groupName exists in \a this mesh.
  */
-bool MEDFileMesh::existsGroup(const char *groupName) const
+bool MEDFileMesh::existsGroup(const std::string& groupName) const
 {
   std::string grpName(groupName);
   return _groups.find(grpName)!=_groups.end();
@@ -807,7 +858,7 @@ bool MEDFileMesh::existsFamily(int famId) const
  *  \param [in] familyName - the family name.
  *  \return bool - \c true the family \a familyName exists in \a this mesh.
  */
-bool MEDFileMesh::existsFamily(const char *familyName) const
+bool MEDFileMesh::existsFamily(const std::string& familyName) const
 {
   std::string fname(familyName);
   return _families.find(fname)!=_families.end();
@@ -818,13 +869,13 @@ bool MEDFileMesh::existsFamily(const char *familyName) const
  *  \param [in] familyName - the family name.
  *  \param [in] id - a new id of the family.
  */
-void MEDFileMesh::setFamilyId(const char *familyName, int id)
+void MEDFileMesh::setFamilyId(const std::string& familyName, int id)
 {
   std::string fname(familyName);
   _families[fname]=id;
 }
 
-void MEDFileMesh::setFamilyIdUnique(const char *familyName, int id) throw(INTERP_KERNEL::Exception)
+void MEDFileMesh::setFamilyIdUnique(const std::string& familyName, int id)
 {
   std::string fname(familyName);
   for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
@@ -845,20 +896,20 @@ void MEDFileMesh::setFamilyIdUnique(const char *familyName, int id) throw(INTERP
  *  \param [in] famId - an id of the family.
  *  \throw If a family with the same name or id already exists in \a this mesh.
  */
-void MEDFileMesh::addFamily(const char *familyName, int famId) throw(INTERP_KERNEL::Exception)
+void MEDFileMesh::addFamily(const std::string& familyName, int famId)
 {
   std::string fname(familyName);
   std::map<std::string,int>::const_iterator it=_families.find(fname);
   if(it==_families.end())
     {
-       for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
-         if((*it2).second==famId)
-           {
-             std::ostringstream oss;
-             oss << "MEDFileMesh::addFamily : Family \"" << (*it2).first << "\" already exists with specified id : " << famId << " !";
-             throw INTERP_KERNEL::Exception(oss.str().c_str());
-           }
-       _families[fname]=famId;
+      for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
+        if((*it2).second==famId)
+          {
+            std::ostringstream oss;
+            oss << "MEDFileMesh::addFamily : Family \"" << (*it2).first << "\" already exists with specified id : " << famId << " !";
+            throw INTERP_KERNEL::Exception(oss.str().c_str());
+          }
+      _families[fname]=famId;
     }
   else
     {
@@ -884,7 +935,7 @@ void MEDFileMesh::addFamily(const char *familyName, int famId) throw(INTERP_KERN
  *  \throw If no mesh entities of dimension \a meshDimRelToMaxExt exist in \a this mesh.
  *  \throw If no family field of dimension \a meshDimRelToMaxExt is present in \a this mesh.
  */
-void MEDFileMesh::createGroupOnAll(int meshDimRelToMaxExt, const char *groupName) throw(INTERP_KERNEL::Exception)
+void MEDFileMesh::createGroupOnAll(int meshDimRelToMaxExt, const std::string& groupName)
 {
   std::string grpName(groupName);
   std::vector<int> levs=getNonEmptyLevelsExt();
@@ -925,7 +976,7 @@ void MEDFileMesh::createGroupOnAll(int meshDimRelToMaxExt, const char *groupName
  *          famIds should exclusively belong.
  *  \return bool - \c true if no modification is done in \a this mesh by this method.
  */
-bool MEDFileMesh::keepFamIdsOnlyOnLevs(const std::vector<int>& famIds, const std::vector<int>& vMeshDimRelToMaxExt) throw(INTERP_KERNEL::Exception)
+bool MEDFileMesh::keepFamIdsOnlyOnLevs(const std::vector<int>& famIds, const std::vector<int>& vMeshDimRelToMaxExt)
 {
   std::set<int> levsInput(vMeshDimRelToMaxExt.begin(),vMeshDimRelToMaxExt.end());
   std::vector<int> levs=getNonEmptyLevelsExt();
@@ -952,7 +1003,7 @@ bool MEDFileMesh::keepFamIdsOnlyOnLevs(const std::vector<int>& famIds, const std
               std::string famName=getFamilyNameGivenId(*it2);
               std::ostringstream oss; oss << "Family_" << maxFamId;
               std::string zeName=CreateNameNotIn(oss.str(),allFams);
-              addFamilyOnAllGroupsHaving(famName.c_str(),zeName.c_str());
+              addFamilyOnAllGroupsHaving(famName,zeName);
               _families[zeName]=maxFamId;
               (const_cast<DataArrayInt *>(fieldFamIds))->changeValue(*it2,maxFamId);
               maxFamId++;
@@ -970,7 +1021,7 @@ bool MEDFileMesh::keepFamIdsOnlyOnLevs(const std::vector<int>& famIds, const std
  *  \throw If \a grpName or \a famName is an empty string.
  *  \throw If no family named \a famName is present in \a this mesh.
  */
-void MEDFileMesh::addFamilyOnGrp(const char *grpName, const char *famName) throw(INTERP_KERNEL::Exception)
+void MEDFileMesh::addFamilyOnGrp(const std::string& grpName, const std::string& famName)
 {
   std::string grpn(grpName);
   std::string famn(famName);
@@ -1002,7 +1053,7 @@ void MEDFileMesh::addFamilyOnGrp(const char *grpName, const char *famName) throw
  * This method is quite underground because it can lead to unconsistency because family 'otherFamName' is \b not added into _families.
  * This method is used by MEDFileMesh::keepFamIdsOnlyOnLevs method.
  */
-void MEDFileMesh::addFamilyOnAllGroupsHaving(const char *famName, const char *otherFamName) throw(INTERP_KERNEL::Exception)
+void MEDFileMesh::addFamilyOnAllGroupsHaving(const std::string& famName, const std::string& otherFamName)
 {
   std::string famNameCpp(famName);
   std::string otherCpp(otherFamName);
@@ -1016,12 +1067,12 @@ void MEDFileMesh::addFamilyOnAllGroupsHaving(const char *famName, const char *ot
     }
 }
 
-void MEDFileMesh::changeAllGroupsContainingFamily(const char *familyNameToChange, const std::vector<std::string>& newFamiliesNames) throw(INTERP_KERNEL::Exception)
+void MEDFileMesh::changeAllGroupsContainingFamily(const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
 {
   ChangeAllGroupsContainingFamily(_groups,familyNameToChange,newFamiliesNames);
 }
 
-void MEDFileMesh::ChangeAllGroupsContainingFamily(std::map<std::string, std::vector<std::string> >& groups, const char *familyNameToChange, const std::vector<std::string>& newFamiliesNames) throw(INTERP_KERNEL::Exception)
+void MEDFileMesh::ChangeAllGroupsContainingFamily(std::map<std::string, std::vector<std::string> >& groups, const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
 {
   std::string fam(familyNameToChange);
   for(std::map<std::string, std::vector<std::string> >::iterator it=groups.begin();it!=groups.end();it++)
@@ -1044,7 +1095,7 @@ void MEDFileMesh::ChangeAllGroupsContainingFamily(std::map<std::string, std::vec
  *  \return std::string - the name of the existing or the created family.
  *  \throw If it is not possible to create a unique family name.
  */
-std::string MEDFileMesh::findOrCreateAndGiveFamilyWithId(int id, bool& created) throw(INTERP_KERNEL::Exception)
+std::string MEDFileMesh::findOrCreateAndGiveFamilyWithId(int id, bool& created)
 {
   return FindOrCreateAndGiveFamilyWithId(_families,id,created);
 }
@@ -1057,7 +1108,7 @@ std::string MEDFileMesh::findOrCreateAndGiveFamilyWithId(int id, bool& created)
  * will be modified.
  * This method will throws an exception if it is not possible to create a unique family name.
  */
-std::string MEDFileMesh::FindOrCreateAndGiveFamilyWithId(std::map<std::string,int>& families, int id, bool& created) throw(INTERP_KERNEL::Exception)
+std::string MEDFileMesh::FindOrCreateAndGiveFamilyWithId(std::map<std::string,int>& families, int id, bool& created)
 {
   std::vector<std::string> famAlreadyExisting(families.size());
   int ii=0;
@@ -1105,7 +1156,7 @@ void MEDFileMesh::setGroupInfo(const std::map<std::string, std::vector<std::stri
  *  \return int - the id of the family of interest.
  *  \throw If no family with such a \a name exists.
  */
-int MEDFileMesh::getFamilyId(const char *name) const throw(INTERP_KERNEL::Exception)
+int MEDFileMesh::getFamilyId(const std::string& name) const
 {
   std::string oname(name);
   std::map<std::string, int>::const_iterator it=_families.find(oname);
@@ -1125,7 +1176,7 @@ int MEDFileMesh::getFamilyId(const char *name) const throw(INTERP_KERNEL::Except
  *  \return std::vector<int> - a sequence of the ids of families of interest.
  *  \throw If \a fams contains a name of an inexistent family.
  */
-std::vector<int> MEDFileMesh::getFamiliesIds(const std::vector<std::string>& fams) const throw(INTERP_KERNEL::Exception)
+std::vector<int> MEDFileMesh::getFamiliesIds(const std::vector<std::string>& fams) const
 {
   std::vector<int> ret(fams.size());
   int i=0;
@@ -1149,7 +1200,7 @@ std::vector<int> MEDFileMesh::getFamiliesIds(const std::vector<std::string>& fam
  *  \return int - the maximal norm of family id.
  *  \throw If there are no families in \a this mesh.
  */
-int MEDFileMesh::getMaxAbsFamilyId() const throw(INTERP_KERNEL::Exception)
+int MEDFileMesh::getMaxAbsFamilyId() const
 {
   if(_families.empty())
     throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
@@ -1166,7 +1217,7 @@ int MEDFileMesh::getMaxAbsFamilyId() const throw(INTERP_KERNEL::Exception)
  *  \return int - the maximal family id.
  *  \throw If there are no families in \a this mesh.
  */
-int MEDFileMesh::getMaxFamilyId() const throw(INTERP_KERNEL::Exception)
+int MEDFileMesh::getMaxFamilyId() const
 {
   if(_families.empty())
     throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
@@ -1183,7 +1234,7 @@ int MEDFileMesh::getMaxFamilyId() const throw(INTERP_KERNEL::Exception)
  *  \return int - the minimal family id.
  *  \throw If there are no families in \a this mesh.
  */
-int MEDFileMesh::getMinFamilyId() const throw(INTERP_KERNEL::Exception)
+int MEDFileMesh::getMinFamilyId() const
 {
   if(_families.empty())
     throw INTERP_KERNEL::Exception("MEDFileMesh::getMinFamilyId : no families set !");
@@ -1200,7 +1251,7 @@ int MEDFileMesh::getMinFamilyId() const throw(INTERP_KERNEL::Exception)
  * considered but all family fields as well.
  *  \return int - the maximal family id.
  */
-int MEDFileMesh::getTheMaxAbsFamilyId() const throw(INTERP_KERNEL::Exception)
+int MEDFileMesh::getTheMaxAbsFamilyId() const
 {
   int m1=-std::numeric_limits<int>::max();
   for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
@@ -1214,7 +1265,7 @@ int MEDFileMesh::getTheMaxAbsFamilyId() const throw(INTERP_KERNEL::Exception)
  * considered but all family fields as well.
  *  \return int - the maximal family id.
  */
-int MEDFileMesh::getTheMaxFamilyId() const throw(INTERP_KERNEL::Exception)
+int MEDFileMesh::getTheMaxFamilyId() const
 {
   int m1=-std::numeric_limits<int>::max();
   for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
@@ -1228,7 +1279,7 @@ int MEDFileMesh::getTheMaxFamilyId() const throw(INTERP_KERNEL::Exception)
  * considered but all family fields as well.
  *  \return int - the minimal family id.
  */
-int MEDFileMesh::getTheMinFamilyId() const throw(INTERP_KERNEL::Exception)
+int MEDFileMesh::getTheMinFamilyId() const
 {
   int m1=std::numeric_limits<int>::max();
   for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
@@ -1242,7 +1293,7 @@ int MEDFileMesh::getTheMinFamilyId() const throw(INTERP_KERNEL::Exception)
  * 
  * \sa MEDFileMesh::computeAllFamilyIdsInUse
  */
-DataArrayInt *MEDFileMesh::getAllFamiliesIdsReferenced() const throw(INTERP_KERNEL::Exception)
+DataArrayInt *MEDFileMesh::getAllFamiliesIdsReferenced() const
 {
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
   std::set<int> v;
@@ -1258,7 +1309,7 @@ DataArrayInt *MEDFileMesh::getAllFamiliesIdsReferenced() const throw(INTERP_KERN
  * 
  * \sa MEDFileMesh::getAllFamiliesIdsReferenced
  */
-DataArrayInt *MEDFileMesh::computeAllFamilyIdsInUse() const throw(INTERP_KERNEL::Exception)
+DataArrayInt *MEDFileMesh::computeAllFamilyIdsInUse() const
 {
   std::vector<int> famLevs=getFamArrNonEmptyLevelsExt();
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret;
@@ -1278,7 +1329,7 @@ DataArrayInt *MEDFileMesh::computeAllFamilyIdsInUse() const throw(INTERP_KERNEL:
  * true is returned if no modification has been needed. false if family
  * renumbering has been needed.       
  */
-bool MEDFileMesh::ensureDifferentFamIdsPerLevel() throw(INTERP_KERNEL::Exception)
+bool MEDFileMesh::ensureDifferentFamIdsPerLevel()
 {
   std::vector<int> levs=getNonEmptyLevelsExt();
   std::set<int> allFamIds;
@@ -1311,12 +1362,12 @@ bool MEDFileMesh::ensureDifferentFamIdsPerLevel() throw(INTERP_KERNEL::Exception
           if(allIds->presenceOfValue(*it3))
             {
               std::string famName=getFamilyNameGivenId(*it3);
-              std::vector<std::string> grps=getGroupsOnFamily(famName.c_str());
+              std::vector<std::string> grps=getGroupsOnFamily(famName);
               ren[*it3]=maxId;
               bool dummy;
               std::string newFam=findOrCreateAndGiveFamilyWithId(maxId,dummy);
               for(std::vector<std::string>::const_iterator it4=grps.begin();it4!=grps.end();it4++)
-                addFamilyOnGrp((*it4).c_str(),newFam.c_str());
+                addFamilyOnGrp((*it4),newFam);
             }
         }
       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=fam->getIdsEqualList(&(*it2).second[0],&(*it2).second[0]+(*it2).second.size());
@@ -1333,7 +1384,7 @@ bool MEDFileMesh::ensureDifferentFamIdsPerLevel() throw(INTERP_KERNEL::Exception
  * This method will throw an exception if a same family id is detected in different level.
  * \warning This policy is the opposite of those in MED file documentation ...
  */
-void MEDFileMesh::normalizeFamIdsTrio() throw(INTERP_KERNEL::Exception)
+void MEDFileMesh::normalizeFamIdsTrio()
 {
   ensureDifferentFamIdsPerLevel();
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
@@ -1425,7 +1476,7 @@ void MEDFileMesh::normalizeFamIdsTrio() throw(INTERP_KERNEL::Exception)
  * This policy is those defined in the MED file format but is the opposite of those implemented in SMESH and Trio.
  * This method will throw an exception if a same family id is detected in different level.
  */
-void MEDFileMesh::normalizeFamIdsMEDFile() throw(INTERP_KERNEL::Exception)
+void MEDFileMesh::normalizeFamIdsMEDFile()
 {
   ensureDifferentFamIdsPerLevel();
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
@@ -1501,7 +1552,7 @@ void MEDFileMesh::normalizeFamIdsMEDFile() throw(INTERP_KERNEL::Exception)
  *  \return std::string - the name of the found family.
  *  \throw If no family with the given \a id exists.
  */
-std::string MEDFileMesh::getFamilyNameGivenId(int id) const throw(INTERP_KERNEL::Exception)
+std::string MEDFileMesh::getFamilyNameGivenId(int id) const
 {
   for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
     if((*it).second==id)
@@ -1537,7 +1588,7 @@ std::string MEDFileMesh::simpleRepr() const
  *  \throw If the name of a nonexistent group is specified.
  *  \throw If the family field is missing for \a meshDimRelToMaxExt.
  */
-DataArrayInt *MEDFileMesh::getGroupArr(int meshDimRelToMaxExt, const char *grp, bool renum) const throw(INTERP_KERNEL::Exception)
+DataArrayInt *MEDFileMesh::getGroupArr(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
 {
   std::vector<std::string> tmp(1);
   tmp[0]=grp;
@@ -1559,7 +1610,7 @@ DataArrayInt *MEDFileMesh::getGroupArr(int meshDimRelToMaxExt, const char *grp,
  *  \throw If the name of a nonexistent group is present in \a grps.
  *  \throw If the family field is missing for \a meshDimRelToMaxExt.
  */
-DataArrayInt *MEDFileMesh::getGroupsArr(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const throw(INTERP_KERNEL::Exception)
+DataArrayInt *MEDFileMesh::getGroupsArr(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
 {
   std::vector<std::string> fams2=getFamiliesOnGroups(grps);
   return getFamiliesArr(meshDimRelToMaxExt,fams2,renum);
@@ -1577,7 +1628,7 @@ DataArrayInt *MEDFileMesh::getGroupsArr(int meshDimRelToMaxExt, const std::vecto
  *          is to delete this array using decrRef() as it is no more needed. 
  *  \throw If the family field is missing for \a meshDimRelToMaxExt.
  */
-DataArrayInt *MEDFileMesh::getFamilyArr(int meshDimRelToMaxExt, const char *fam, bool renum) const throw(INTERP_KERNEL::Exception)
+DataArrayInt *MEDFileMesh::getFamilyArr(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
 {
   std::vector<std::string> tmp(1);
   tmp[0]=fam;
@@ -1597,7 +1648,7 @@ DataArrayInt *MEDFileMesh::getFamilyArr(int meshDimRelToMaxExt, const char *fam,
  *  \throw If the name of a nonexistent group is specified.
  *  \throw If the family field is missing for nodes.
  */
-DataArrayInt *MEDFileMesh::getNodeGroupArr(const char *grp, bool renum) const throw(INTERP_KERNEL::Exception)
+DataArrayInt *MEDFileMesh::getNodeGroupArr(const std::string& grp, bool renum) const
 {
   std::vector<std::string> tmp(1);
   tmp[0]=grp;
@@ -1617,7 +1668,7 @@ DataArrayInt *MEDFileMesh::getNodeGroupArr(const char *grp, bool renum) const th
  *  \throw If the name of a nonexistent group is present in \a grps.
  *  \throw If the family field is missing for nodes.
  */
-DataArrayInt *MEDFileMesh::getNodeGroupsArr(const std::vector<std::string>& grps, bool renum) const throw(INTERP_KERNEL::Exception)
+DataArrayInt *MEDFileMesh::getNodeGroupsArr(const std::vector<std::string>& grps, bool renum) const
 {
   return getGroupsArr(1,grps,renum);
 }
@@ -1633,7 +1684,7 @@ DataArrayInt *MEDFileMesh::getNodeGroupsArr(const std::vector<std::string>& grps
  *  \throw If the name of a nonexistent group is specified.
  *  \throw If the family field is missing for nodes.
  */
-DataArrayInt *MEDFileMesh::getNodeFamilyArr(const char *fam, bool renum) const throw(INTERP_KERNEL::Exception)
+DataArrayInt *MEDFileMesh::getNodeFamilyArr(const std::string& fam, bool renum) const
 {
   std::vector<std::string> tmp(1);
   tmp[0]=fam;
@@ -1652,7 +1703,7 @@ DataArrayInt *MEDFileMesh::getNodeFamilyArr(const char *fam, bool renum) const t
  *          is to delete this array using decrRef() as it is no more needed. 
  *  \throw If the family field is missing for nodes.
  */
-DataArrayInt *MEDFileMesh::getNodeFamiliesArr(const std::vector<std::string>& fams, bool renum) const throw(INTERP_KERNEL::Exception)
+DataArrayInt *MEDFileMesh::getNodeFamiliesArr(const std::vector<std::string>& fams, bool renum) const
 {
   return getFamiliesArr(1,fams,renum);
 }
@@ -1669,7 +1720,7 @@ DataArrayInt *MEDFileMesh::getNodeFamiliesArr(const std::vector<std::string>& fa
  *  \throw If \a grps includes invalid ids (or numbers if \a renum == \c true ).
  *  \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
  */
-void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector<const DataArrayInt *>& grps, bool renum) throw(INTERP_KERNEL::Exception)
+void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector<const DataArrayInt *>& grps, bool renum)
 {
   if(grps.empty())
     return ;
@@ -1699,7 +1750,7 @@ void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector<con
       for(unsigned int ii=0;ii<grps.size();ii++)
         {
           grps2[ii]=MEDFileUMeshSplitL1::Renumber(getRevNumberFieldAtLevel(meshDimRelToMaxExt),grps[ii]);
-          grps2[ii]->setName(grps[ii]->getName().c_str());
+          grps2[ii]->setName(grps[ii]->getName());
         }
       std::vector<const DataArrayInt *> grps3(grps2.begin(),grps2.end());
       fam=DataArrayInt::MakePartition(grps3,sz,fidsOfGroups);
@@ -1738,6 +1789,24 @@ void MEDFileMesh::appendFamilyEntries(const DataArrayInt *famIds, const std::vec
     }
 }
 
+std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileMesh::getAllGeoTypes() const
+{
+  std::vector<int> levs(getNonEmptyLevels());
+  std::vector<INTERP_KERNEL::NormalizedCellType> ret;
+  for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
+    {
+      std::vector<INTERP_KERNEL::NormalizedCellType> elts(getGeoTypesAtLevel(*it));
+      ret.insert(ret.end(),elts.begin(),elts.end());
+    }
+  return ret;
+}
+
+std::vector<int> MEDFileMesh::getDistributionOfTypes(int meshDimRelToMax) const
+{
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> mLev(getGenMeshAtLevel(meshDimRelToMax));
+  return mLev->getDistributionOfTypes();
+}
+
 void MEDFileMesh::TranslateFamilyIds(int offset, DataArrayInt *famArr, std::vector< std::vector<int> >& famIdsPerGrp)
 {
   famArr->applyLin(offset>0?1:-1,offset,0);
@@ -1754,7 +1823,7 @@ void MEDFileMesh::TranslateFamilyIds(int offset, DataArrayInt *famArr, std::vect
  * This method returns a name close to 'nameTry' so that it is not already into 'namesToAvoid'.
  * If this method fails to find such a name it will throw an exception.
  */
-std::string MEDFileMesh::CreateNameNotIn(const std::string& nameTry, const std::vector<std::string>& namesToAvoid) throw(INTERP_KERNEL::Exception)
+std::string MEDFileMesh::CreateNameNotIn(const std::string& nameTry, const std::vector<std::string>& namesToAvoid)
 {
   //attempt #0
   if(std::find(namesToAvoid.begin(),namesToAvoid.end(),nameTry)==namesToAvoid.end())
@@ -1787,7 +1856,7 @@ std::string MEDFileMesh::CreateNameNotIn(const std::string& nameTry, const std::
   throw INTERP_KERNEL::Exception("MEDFileMesh::CreateNameNotIn : impossible to find a not already used name !");
 }
 
-int MEDFileMesh::PutInThirdComponentOfCodeOffset(std::vector<int>& code, int strt) throw(INTERP_KERNEL::Exception)
+int MEDFileMesh::PutInThirdComponentOfCodeOffset(std::vector<int>& code, int strt)
 {
   std::size_t nbOfChunks=code.size()/3;
   if(code.size()%3!=0)
@@ -1807,7 +1876,7 @@ int MEDFileMesh::PutInThirdComponentOfCodeOffset(std::vector<int>& code, int str
  * If _name is not empty and that 'm' has the same name nothing is done.
  * If _name is not emplt and that 'm' has \b NOT the same name an exception is thrown.
  */
-void MEDFileMesh::dealWithTinyInfo(const MEDCouplingMesh *m) throw(INTERP_KERNEL::Exception)
+void MEDFileMesh::dealWithTinyInfo(const MEDCouplingMesh *m)
 {
   if(!m)
     throw INTERP_KERNEL::Exception("MEDFileMesh::dealWithTinyInfo : input mesh in NULL !");
@@ -1850,7 +1919,7 @@ void MEDFileMesh::getFamilyRepr(std::ostream& oss) const
     {
       oss << "- Family with name \"" << (*it).first << "\" with number " << (*it).second << std::endl;
       oss << "  - Groups lying on this family : ";
-      std::vector<std::string> grps=getGroupsOnFamily((*it).first.c_str());
+      std::vector<std::string> grps=getGroupsOnFamily((*it).first);
       std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
       oss << std::endl << std::endl;
     }
@@ -1870,10 +1939,10 @@ void MEDFileMesh::getFamilyRepr(std::ostream& oss) const
  *  \throw If there is no mesh with given attributes in the file.
  *  \throw If the mesh in the file is not an unstructured one.
  */
-MEDFileUMesh *MEDFileUMesh::New(const char *fileName, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
+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,MED_ACC_RDONLY);
+  MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
   return new MEDFileUMesh(fid,mName,dt,it,mrs);
 }
 
@@ -1887,7 +1956,7 @@ MEDFileUMesh *MEDFileUMesh::New(const char *fileName, const char *mName, int dt,
  *  \throw If there is no meshes in the file.
  *  \throw If the mesh in the file is not an unstructured one.
  */
-MEDFileUMesh *MEDFileUMesh::New(const char *fileName, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
+MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
 {
   std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
   if(ms.empty())
@@ -1896,12 +1965,12 @@ MEDFileUMesh *MEDFileUMesh::New(const char *fileName, MEDFileMeshReadSelector *m
       throw INTERP_KERNEL::Exception(oss.str().c_str());
     }
   MEDFileUtilities::CheckFileForRead(fileName);
-  MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
+  MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
   int dt,it;
   ParaMEDMEM::MEDCouplingMeshType meshType;
   std::string dummy2;
-  MEDFileMeshL2::GetMeshIdFromName(fid,ms.front().c_str(),meshType,dt,it,dummy2);
-  return new MEDFileUMesh(fid,ms.front().c_str(),dt,it,mrs);
+  MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
+  return new MEDFileUMesh(fid,ms.front(),dt,it,mrs);
 }
 
 /*!
@@ -1914,38 +1983,73 @@ MEDFileUMesh *MEDFileUMesh::New()
   return new MEDFileUMesh;
 }
 
-std::size_t MEDFileUMesh::getHeapMemorySize() const
+/*!
+ * This method loads from file with name \a fileName the mesh called \a mName as New does. The difference is that
+ * here only a part of cells contained in the file will be loaded. The selection of cell is specified using the two consecutive parameters
+ * \a types and \a slicPerTyp. This method allows to load from a mesh (typically huge) in a MED file a part of cells of that mesh.
+ * The part of cells is specified using triplet (start,stop,step) for each geometric type. Only nodes lying on selected cells will be loaded to reduce
+ * at most the memory consumtion.
+ *
+ * \param [in] fileName - the name of the file.
+ * \param [in] mName - the name of the mesh to be read.
+ * \param [in] types - the list of the geo types of which some part will be taken. A geometric type in \a types must appear only once at most.
+ * \param [in] slicPerType - an array of size 3 times larger than \a types that specifies for each type in \a types (in the same order) resp the start, the stop and the step.
+ * \param [in] dt - the iteration, that is to say the first element of the pair that locates the asked time step.
+ * \param [in] it - the order, that is to say the second element of the pair that locates the asked time step.
+ * \param [in] mrs - the request for what to be loaded.
+ * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this mesh using decrRef() as it is no more needed.
+ */
+MEDFileUMesh *MEDFileUMesh::LoadPartOf(const std::string& fileName, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<int>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs)
 {
-  std::size_t ret=MEDFileMesh::getHeapMemorySize();
-  if((const DataArrayDouble*)_coords)
-    ret+=_coords->getHeapMemorySize();
-  if((const DataArrayInt *)_fam_coords)
-    ret+=_fam_coords->getHeapMemorySize();
-  if((const DataArrayInt *)_num_coords)
-    ret+=_num_coords->getHeapMemorySize();
-  if((const DataArrayInt *)_rev_num_coords)
-    ret+=_rev_num_coords->getHeapMemorySize();
-  if((const DataArrayAsciiChar *)_name_coords)
-    ret+=_name_coords->getHeapMemorySize();
+  MEDFileUtilities::CheckFileForRead(fileName);
+  MEDFileUtilities::AutoFid fid(MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY));
+  return MEDFileUMesh::LoadPartOf(fid,mName,types,slicPerTyp,dt,it,mrs);
+}
+
+/*!
+ * Please refer to the other MEDFileUMesh::LoadPartOf method that has the same semantic and the same parameter (excepted the first).
+ * This method is \b NOT wrapped into python.
+ */
+MEDFileUMesh *MEDFileUMesh::LoadPartOf(med_idt fid, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<int>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs)
+{
+  MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(MEDFileUMesh::New());
+  ret->loadPartUMeshFromFile(fid,mName,types,slicPerTyp,dt,it,mrs);
+  return ret.retn();
+}
+
+std::size_t MEDFileUMesh::getHeapMemorySizeWithoutChildren() const
+{
+  std::size_t ret(MEDFileMesh::getHeapMemorySizeWithoutChildren());
   ret+=_ms.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1>));
+  return ret;
+}
+
+std::vector<const BigMemoryObject *> MEDFileUMesh::getDirectChildrenWithNull() const
+{
+  std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
+  ret.push_back((const DataArrayDouble*)_coords);
+  ret.push_back((const DataArrayInt *)_fam_coords);
+  ret.push_back((const DataArrayInt *)_num_coords);
+  ret.push_back((const DataArrayInt *)_rev_num_coords);
+  ret.push_back((const DataArrayAsciiChar *)_name_coords);
+  ret.push_back((const PartDefinition *)_part_coords);
   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
-    if((const MEDFileUMeshSplitL1*) *it)
-      ret+=(*it)->getHeapMemorySize();
+    ret.push_back((const MEDFileUMeshSplitL1*) *it);
   return ret;
 }
 
-MEDFileMesh *MEDFileUMesh::shallowCpy() const throw(INTERP_KERNEL::Exception)
+MEDFileMesh *MEDFileUMesh::shallowCpy() const
 {
   MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=new MEDFileUMesh(*this);
   return ret.retn();
 }
 
-MEDFileMesh *MEDFileUMesh::createNewEmpty() const throw(INTERP_KERNEL::Exception)
+MEDFileMesh *MEDFileUMesh::createNewEmpty() const
 {
   return new MEDFileUMesh;
 }
 
-MEDFileMesh *MEDFileUMesh::deepCpy() const throw(INTERP_KERNEL::Exception)
+MEDFileMesh *MEDFileUMesh::deepCpy() const
 {
   MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=new MEDFileUMesh(*this);
   if((const DataArrayDouble*)_coords)
@@ -2101,33 +2205,74 @@ void MEDFileUMesh::clearNonDiscrAttributes() const
     }
 }
 
+void MEDFileUMesh::setName(const std::string& name)
+{
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
+    if((MEDFileUMeshSplitL1 *)(*it)!=0)
+      (*it)->setName(name);
+  MEDFileMesh::setName(name);
+}
+
 MEDFileUMesh::MEDFileUMesh()
 {
 }
 
-MEDFileUMesh::MEDFileUMesh(med_idt fid, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
+MEDFileUMesh::MEDFileUMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
 try
-  {
+{
     loadUMeshFromFile(fid,mName,dt,it,mrs);
-  }
+}
 catch(INTERP_KERNEL::Exception& e)
-  {
+{
     throw e;
-  }
+}
+
+/*!
+ * This method loads only a part of specified cells (given by range of cell ID per geometric type)
+ * See MEDFileUMesh::LoadPartOf for detailed description.
+ *
+ * \sa loadUMeshFromFile
+ */
+void MEDFileUMesh::loadPartUMeshFromFile(med_idt fid, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<int>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs)
+{
+  MEDFileUMeshL2 loaderl2;
+  ParaMEDMEM::MEDCouplingMeshType meshType;
+  int dummy0,dummy1;
+  std::string dummy2;
+  int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2));
+  if(meshType!=UNSTRUCTURED)
+    {
+      std::ostringstream oss; oss << "loadPartUMeshFromFile : Trying to load as unstructured an existing mesh with name '" << mName << "' !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  loaderl2.loadPart(fid,mid,mName,types,slicPerTyp,dt,it,mrs);
+  dispatchLoadedPart(fid,loaderl2,mName,mrs);
+}
 
-void MEDFileUMesh::loadUMeshFromFile(med_idt fid, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
+/*!
+ * This method loads \b all \b the \b mesh \a mName in the file with \a fid descriptor.
+ *
+ * \sa loadPartUMeshFromFile
+ */
+void MEDFileUMesh::loadUMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
 {
   MEDFileUMeshL2 loaderl2;
   ParaMEDMEM::MEDCouplingMeshType meshType;
   int dummy0,dummy1;
   std::string dummy2;
-  int mid=MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2);
+  int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2));
   if(meshType!=UNSTRUCTURED)
     {
       std::ostringstream oss; oss << "Trying to load as unstructured an existing mesh with name '" << mName << "' !";
       throw INTERP_KERNEL::Exception(oss.str().c_str());
     }
   loaderl2.loadAll(fid,mid,mName,dt,it,mrs);
+  dispatchLoadedPart(fid,loaderl2,mName,mrs);
+
+}
+
+void MEDFileUMesh::dispatchLoadedPart(med_idt fid, const MEDFileUMeshL2& loaderl2, const std::string& mName, MEDFileMeshReadSelector *mrs)
+{
   int lev=loaderl2.getNumberOfLevels();
   _ms.resize(lev);
   for(int i=0;i<lev;i++)
@@ -2153,6 +2298,7 @@ void MEDFileUMesh::loadUMeshFromFile(med_idt fid, const char *mName, int dt, int
     _num_coords=loaderl2.getCoordsNum();
   if(!mrs || mrs->isNodeNameFieldReading())
     _name_coords=loaderl2.getCoordsName();
+  _part_coords=loaderl2.getPartDefOfCoo();
   computeRevNum();
 }
 
@@ -2160,7 +2306,7 @@ MEDFileUMesh::~MEDFileUMesh()
 {
 }
 
-void MEDFileUMesh::writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception)
+void MEDFileUMesh::writeLL(med_idt fid) const
 {
   const DataArrayDouble *coo=_coords;
   INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
@@ -2168,7 +2314,9 @@ void MEDFileUMesh::writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception)
   MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
   MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
   int spaceDim=coo?coo->getNumberOfComponents():0;
-  int mdim=getMeshDimension();
+  int mdim(0);
+  if(!_ms.empty())
+    mdim=getMeshDimension();
   INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
   INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
   for(int i=0;i<spaceDim;i++)
@@ -2181,11 +2329,12 @@ void MEDFileUMesh::writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception)
     }
   MEDmeshCr(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
   MEDmeshUniversalNameWr(fid,maa);
-  MEDFileUMeshL2::WriteCoords(fid,maa,_iteration,_order,_time,_coords,_fam_coords,_num_coords,_name_coords);
+  std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
+  MEDFileUMeshL2::WriteCoords(fid,meshName,_iteration,_order,_time,_coords,_fam_coords,_num_coords,_name_coords);
   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
     if((const MEDFileUMeshSplitL1 *)(*it)!=0)
-      (*it)->write(fid,maa,mdim);
-  MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa,_families,_groups,_too_long_str);
+      (*it)->write(fid,meshName,mdim);
+  MEDFileUMeshL2::WriteFamiliesAndGrps(fid,meshName,_families,_groups,_too_long_str);
 }
 
 /*!
@@ -2277,7 +2426,7 @@ std::vector<int> MEDFileUMesh::getNameArrNonEmptyLevelsExt() const
  *  \param [in] grp - the name of the group of interest.
  *  \return std::vector<int> - a sequence of the relative dimensions.
  */
-std::vector<int> MEDFileUMesh::getGrpNonEmptyLevels(const char *grp) const throw(INTERP_KERNEL::Exception)
+std::vector<int> MEDFileUMesh::getGrpNonEmptyLevels(const std::string& grp) const
 {
   std::vector<std::string> fams=getFamiliesOnGroup(grp);
   return getFamsNonEmptyLevels(fams);
@@ -2288,7 +2437,7 @@ std::vector<int> MEDFileUMesh::getGrpNonEmptyLevels(const char *grp) const throw
  *  \param [in] grp - the name of the group of interest.
  *  \return std::vector<int> - a sequence of the relative dimensions.
  */
-std::vector<int> MEDFileUMesh::getGrpNonEmptyLevelsExt(const char *grp) const throw(INTERP_KERNEL::Exception)
+std::vector<int> MEDFileUMesh::getGrpNonEmptyLevelsExt(const std::string& grp) const
 {
   std::vector<std::string> fams=getFamiliesOnGroup(grp);
   return getFamsNonEmptyLevelsExt(fams);
@@ -2300,7 +2449,7 @@ std::vector<int> MEDFileUMesh::getGrpNonEmptyLevelsExt(const char *grp) const th
  *  \param [in] fam - the name of the family of interest.
  *  \return std::vector<int> - a sequence of the relative dimensions.
  */
-std::vector<int> MEDFileUMesh::getFamNonEmptyLevels(const char *fam) const throw(INTERP_KERNEL::Exception)
+std::vector<int> MEDFileUMesh::getFamNonEmptyLevels(const std::string& fam) const
 {
   std::vector<std::string> fams(1,std::string(fam));
   return getFamsNonEmptyLevels(fams);
@@ -2311,7 +2460,7 @@ std::vector<int> MEDFileUMesh::getFamNonEmptyLevels(const char *fam) const throw
  *  \param [in] fam - the name of the family of interest.
  *  \return std::vector<int> - a sequence of the relative dimensions.
  */
-std::vector<int> MEDFileUMesh::getFamNonEmptyLevelsExt(const char *fam) const throw(INTERP_KERNEL::Exception)
+std::vector<int> MEDFileUMesh::getFamNonEmptyLevelsExt(const std::string& fam) const
 {
   std::vector<std::string> fams(1,std::string(fam));
   return getFamsNonEmptyLevelsExt(fams);
@@ -2323,7 +2472,7 @@ std::vector<int> MEDFileUMesh::getFamNonEmptyLevelsExt(const char *fam) const th
  *  \param [in] grps - a sequence of names of the groups of interest.
  *  \return std::vector<int> - a sequence of the relative dimensions.
  */
-std::vector<int> MEDFileUMesh::getGrpsNonEmptyLevels(const std::vector<std::string>& grps) const throw(INTERP_KERNEL::Exception)
+std::vector<int> MEDFileUMesh::getGrpsNonEmptyLevels(const std::vector<std::string>& grps) const
 {
   std::vector<std::string> fams=getFamiliesOnGroups(grps);
   return getFamsNonEmptyLevels(fams);
@@ -2334,7 +2483,7 @@ std::vector<int> MEDFileUMesh::getGrpsNonEmptyLevels(const std::vector<std::stri
  *  \param [in] grps - a sequence of names of the groups of interest.
  *  \return std::vector<int> - a sequence of the relative dimensions.
  */
-std::vector<int> MEDFileUMesh::getGrpsNonEmptyLevelsExt(const std::vector<std::string>& grps) const throw(INTERP_KERNEL::Exception)
+std::vector<int> MEDFileUMesh::getGrpsNonEmptyLevelsExt(const std::vector<std::string>& grps) const
 {
   std::vector<std::string> fams=getFamiliesOnGroups(grps);
   return getFamsNonEmptyLevelsExt(fams);
@@ -2346,7 +2495,7 @@ std::vector<int> MEDFileUMesh::getGrpsNonEmptyLevelsExt(const std::vector<std::s
  *  \param [in] fams - the name of the family of interest.
  *  \return std::vector<int> - a sequence of the relative dimensions.
  */
-std::vector<int> MEDFileUMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const throw(INTERP_KERNEL::Exception)
+std::vector<int> MEDFileUMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
 {
   std::vector<int> ret;
   std::vector<int> levs=getNonEmptyLevels();
@@ -2362,7 +2511,7 @@ std::vector<int> MEDFileUMesh::getFamsNonEmptyLevels(const std::vector<std::stri
  *  \param [in] fams - the names of the families of interest.
  *  \return std::vector<int> - a sequence of the relative dimensions.
  */
-std::vector<int> MEDFileUMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const throw(INTERP_KERNEL::Exception)
+std::vector<int> MEDFileUMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
 {
   std::vector<int> ret0=getFamsNonEmptyLevels(fams);
   const DataArrayInt *famCoords=_fam_coords;
@@ -2386,20 +2535,20 @@ std::vector<int> MEDFileUMesh::getFamsNonEmptyLevelsExt(const std::vector<std::s
  *  \return std::vector<std::string> - a sequence of group names at \a meshDimRelToMaxExt
  *          level. 
  */
-std::vector<std::string> MEDFileUMesh::getGroupsOnSpecifiedLev(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
+std::vector<std::string> MEDFileUMesh::getGroupsOnSpecifiedLev(int meshDimRelToMaxExt) const
 {
   std::vector<std::string> ret;
   std::vector<std::string> allGrps=getGroupsNames();
   for(std::vector<std::string>::const_iterator it=allGrps.begin();it!=allGrps.end();it++)
     {
-      std::vector<int> levs=getGrpNonEmptyLevelsExt((*it).c_str());
+      std::vector<int> levs=getGrpNonEmptyLevelsExt((*it));
       if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)!=levs.end())
         ret.push_back(*it);
     }
   return ret;
 }
 
-int MEDFileUMesh::getMaxAbsFamilyIdInArrays() const throw(INTERP_KERNEL::Exception)
+int MEDFileUMesh::getMaxAbsFamilyIdInArrays() const
 {
   int ret=-std::numeric_limits<int>::max(),tmp=-1;
   if((const DataArrayInt *)_fam_coords)
@@ -2422,7 +2571,7 @@ int MEDFileUMesh::getMaxAbsFamilyIdInArrays() const throw(INTERP_KERNEL::Excepti
   return ret;
 }
 
-int MEDFileUMesh::getMaxFamilyIdInArrays() const throw(INTERP_KERNEL::Exception)
+int MEDFileUMesh::getMaxFamilyIdInArrays() const
 {
   int ret=-std::numeric_limits<int>::max(),tmp=-1;
   if((const DataArrayInt *)_fam_coords)
@@ -2445,7 +2594,7 @@ int MEDFileUMesh::getMaxFamilyIdInArrays() const throw(INTERP_KERNEL::Exception)
   return ret;
 }
 
-int MEDFileUMesh::getMinFamilyIdInArrays() const throw(INTERP_KERNEL::Exception)
+int MEDFileUMesh::getMinFamilyIdInArrays() const
 {
   int ret=std::numeric_limits<int>::max(),tmp=-1;
   if((const DataArrayInt *)_fam_coords)
@@ -2473,7 +2622,7 @@ int MEDFileUMesh::getMinFamilyIdInArrays() const throw(INTERP_KERNEL::Exception)
  *  \return int - the mesh dimension.
  *  \throw If there are no cells in this mesh.
  */
-int MEDFileUMesh::getMeshDimension() const throw(INTERP_KERNEL::Exception)
+int MEDFileUMesh::getMeshDimension() const
 {
   int lev=0;
   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev++)
@@ -2488,7 +2637,7 @@ int MEDFileUMesh::getMeshDimension() const throw(INTERP_KERNEL::Exception)
  *  \return int - the space dimension of \a this mesh.
  *  \throw If the node coordinates array is not available.
  */
-int MEDFileUMesh::getSpaceDimension() const throw(INTERP_KERNEL::Exception)
+int MEDFileUMesh::getSpaceDimension() const
 {
   const DataArrayDouble *coo=_coords;
   if(!coo)
@@ -2563,7 +2712,7 @@ std::string MEDFileUMesh::advancedRepr() const
  *  \return int - the number of entities.
  *  \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
  */
-int MEDFileUMesh::getSizeAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
+int MEDFileUMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
 {
   if(meshDimRelToMaxExt==1)
     {
@@ -2580,7 +2729,7 @@ int MEDFileUMesh::getSizeAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERN
  *  \return const DataArrayInt * - the family field. It is an array of ids of families
  *          each mesh entity belongs to. It can be \c NULL.
  */
-const DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
+const DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
 {
   if(meshDimRelToMaxExt==1)
     return _fam_coords;
@@ -2594,7 +2743,7 @@ const DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
  *  \return const DataArrayInt * - the array of the entity numbers.
  *  \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
  */
-const DataArrayInt *MEDFileUMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
+const DataArrayInt *MEDFileUMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
 {
   if(meshDimRelToMaxExt==1)
     return _num_coords;
@@ -2602,7 +2751,7 @@ const DataArrayInt *MEDFileUMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt)
   return l1->getNumberField();
 }
 
-const DataArrayAsciiChar *MEDFileUMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
+const DataArrayAsciiChar *MEDFileUMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
 {
   if(meshDimRelToMaxExt==1)
     return _name_coords;
@@ -2610,7 +2759,22 @@ const DataArrayAsciiChar *MEDFileUMesh::getNameFieldAtLevel(int meshDimRelToMaxE
   return l1->getNameField();
 }
 
-int MEDFileUMesh::getNumberOfNodes() const throw(INTERP_KERNEL::Exception)
+/*!
+ * This method returns for a specified relative level \a meshDimRelToMaxExt the part effectively read (if the instance is the result of the read of a file).
+ *
+ * \param [in] meshDimRelToMaxExt - the extended relative level for which the part definition is requested.
+ * \param [in] gt - The input geometric type for which the part definition is requested.
+ * \return the part definition owned by \a this. So no need to deallocate the returned instance.
+ */
+const PartDefinition *MEDFileUMesh::getPartDefAtLevel(int meshDimRelToMaxExt, INTERP_KERNEL::NormalizedCellType gt) const
+{
+  if(meshDimRelToMaxExt==1)
+    return _part_coords;
+  const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
+  return l1->getPartDef(gt);
+}
+
+int MEDFileUMesh::getNumberOfNodes() const
 {
   const DataArrayDouble *coo=_coords;
   if(!coo)
@@ -2618,36 +2782,34 @@ int MEDFileUMesh::getNumberOfNodes() const throw(INTERP_KERNEL::Exception)
   return coo->getNumberOfTuples();
 }
 
-void MEDFileUMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const throw(INTERP_KERNEL::Exception)
+bool MEDFileUMesh::hasImplicitPart() const
+{
+  return false;
+}
+
+int MEDFileUMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
+{
+  throw INTERP_KERNEL::Exception("MEDFileUMesh::buildImplicitPartIfAny : unstructured meshes do not have implicit part !");
+}
+
+void MEDFileUMesh::releaseImplicitPartIfAny() const
+{
+}
+
+void MEDFileUMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
 {
   std::size_t sz(st.getNumberOfItems());
-  int mdim(getMeshDimension());
   for(std::size_t i=0;i<sz;i++)
     {
       INTERP_KERNEL::NormalizedCellType curGt(st[i].getGeo());
-      const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(curGt);
-      int relDim((int)cm.getDimension()-mdim);
-      MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> um(getMeshAtLevel(relDim));
-      std::vector<int> d(um->getDistributionOfTypes());
-      std::size_t nbOfTypes(d.size()/3);
-      int offset=0,nbOfEltWT=-1;
-      for(std::size_t j=0;j<nbOfTypes;j++)
-        {
-          if(d[3*j]!=(int)curGt)
-            offset+=d[3*j+1];
-          else
-            { break; nbOfEltWT=d[3*j+1]; }
-        }
-      if(nbOfEltWT==-1)
-        throw INTERP_KERNEL::Exception("MEDFileUMesh::whichAreNodesFetched : asking for a geo type not present in this !");
-      um=dynamic_cast<MEDCouplingUMesh *>(um->buildPartOfMySelf2(offset,offset+nbOfEltWT,1,true));
+      const MEDCoupling1GTUMesh *m(getDirectUndergroundSingleGeoTypeMesh(curGt));
       if(st[i].getPflName().empty())
-        um->computeNodeIdsAlg(nodesFetched);
+        m->computeNodeIdsAlg(nodesFetched);
       else
         {
-          const DataArrayInt *arr(globs->getProfile(st[i].getPflName().c_str()));
-          um=dynamic_cast<MEDCouplingUMesh *>(um->buildPartOfMySelf(arr->begin(),arr->end(),true));
-          um->computeNodeIdsAlg(nodesFetched);
+          const DataArrayInt *arr(globs->getProfile(st[i].getPflName()));
+          MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> m2(dynamic_cast<MEDCoupling1GTUMesh *>(m->buildPartOfMySelf(arr->begin(),arr->end(),true)));
+          m2->computeNodeIdsAlg(nodesFetched);
         }
     }
 }
@@ -2660,7 +2822,7 @@ void MEDFileUMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, con
  *          DataArrayInt::invertArrayN2O2O2N().
  *  \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
  */
-const DataArrayInt *MEDFileUMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
+const DataArrayInt *MEDFileUMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
 {
   if(meshDimRelToMaxExt==1)
     {
@@ -2700,7 +2862,7 @@ DataArrayDouble *MEDFileUMesh::getCoords() const
  *  \throw If the name of a nonexistent group is specified.
  *  \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
  */
-MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const char *grp, bool renum) const throw(INTERP_KERNEL::Exception)
+MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
 {
   synchronizeTinyInfoOnLeaves();
   std::vector<std::string> tmp(1);
@@ -2722,13 +2884,13 @@ MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const char *grp
  *  \throw If a name of a nonexistent group is present in \a grps.
  *  \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
  */
-MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const throw(INTERP_KERNEL::Exception)
+MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
 {
   synchronizeTinyInfoOnLeaves();
   std::vector<std::string> fams2=getFamiliesOnGroups(grps);
   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> zeRet=getFamilies(meshDimRelToMaxExt,fams2,renum);
   if(grps.size()==1 && ((MEDCouplingUMesh *)zeRet))
-    zeRet->setName(grps[0].c_str());
+    zeRet->setName(grps[0]);
   return zeRet.retn();
 }
 
@@ -2746,7 +2908,7 @@ MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vec
  *  \throw If a name of a nonexistent family is present in \a grps.
  *  \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
  */
-MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const char *fam, bool renum) const throw(INTERP_KERNEL::Exception)
+MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
 {
   synchronizeTinyInfoOnLeaves();
   std::vector<std::string> tmp(1);
@@ -2768,7 +2930,7 @@ MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const char *fa
  *  \throw If a name of a nonexistent family is present in \a fams.
  *  \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
  */
-MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const throw(INTERP_KERNEL::Exception)
+MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
 {
   synchronizeTinyInfoOnLeaves();
   if(meshDimRelToMaxExt==1)
@@ -2787,7 +2949,7 @@ MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::v
   else
     zeRet=l1->getFamilyPart(0,0,renum);
   if(fams.size()==1 && ((MEDCouplingUMesh *)zeRet))
-    zeRet->setName(fams[0].c_str());
+    zeRet->setName(fams[0]);
   return zeRet.retn();
 }
 
@@ -2803,7 +2965,7 @@ MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::v
  *          is to delete this array using decrRef() as it is no more needed. 
  *  \throw If the family field is missing for \a meshDimRelToMaxExt.
  */
-DataArrayInt *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const throw(INTERP_KERNEL::Exception)
+DataArrayInt *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
 {
   std::vector<int> famIds=getFamiliesIds(fams);
   if(meshDimRelToMaxExt==1)
@@ -2844,7 +3006,7 @@ DataArrayInt *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::ve
  *  \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
  * \sa getGenMeshAtLevel()
  */
-MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renum) const throw(INTERP_KERNEL::Exception)
+MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renum) const
 {
   synchronizeTinyInfoOnLeaves();
   if(meshDimRelToMaxExt==1)
@@ -2877,11 +3039,17 @@ MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renu
  *  \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a this mesh.
  * \sa getMeshAtLevel()
  */
-MEDCouplingMesh *MEDFileUMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const throw(INTERP_KERNEL::Exception)
+MEDCouplingMesh *MEDFileUMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const
 {
   return getMeshAtLevel(meshDimRelToMax,renum);
 }
 
+std::vector<int> MEDFileUMesh::getDistributionOfTypes(int meshDimRelToMax) const
+{
+  const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMax));
+  return l1->getDistributionOfTypes();
+}
+
 /*!
  * Returns a MEDCouplingUMesh of a relative dimension == 0.
  *  \param [in] renum - if \c true, the returned mesh is permuted according to the
@@ -2890,7 +3058,7 @@ MEDCouplingMesh *MEDFileUMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum
  *          delete using decrRef() as it is no more needed. 
  *  \throw If there are no mesh entities of the relative dimension == 0 in \a this mesh.
  */
-MEDCouplingUMesh *MEDFileUMesh::getLevel0Mesh(bool renum) const throw(INTERP_KERNEL::Exception)
+MEDCouplingUMesh *MEDFileUMesh::getLevel0Mesh(bool renum) const
 {
   return getMeshAtLevel(0,renum);
 }
@@ -2903,7 +3071,7 @@ MEDCouplingUMesh *MEDFileUMesh::getLevel0Mesh(bool renum) const throw(INTERP_KER
  *          delete using decrRef() as it is no more needed. 
  *  \throw If there are no mesh entities of the relative dimension == -1 in \a this mesh.
  */
-MEDCouplingUMesh *MEDFileUMesh::getLevelM1Mesh(bool renum) const throw(INTERP_KERNEL::Exception)
+MEDCouplingUMesh *MEDFileUMesh::getLevelM1Mesh(bool renum) const
 {
   return getMeshAtLevel(-1,renum);
 }
@@ -2916,7 +3084,7 @@ MEDCouplingUMesh *MEDFileUMesh::getLevelM1Mesh(bool renum) const throw(INTERP_KE
  *          delete using decrRef() as it is no more needed. 
  *  \throw If there are no mesh entities of the relative dimension == -2 in \a this mesh.
  */
-MEDCouplingUMesh *MEDFileUMesh::getLevelM2Mesh(bool renum) const throw(INTERP_KERNEL::Exception)
+MEDCouplingUMesh *MEDFileUMesh::getLevelM2Mesh(bool renum) const
 {
   return getMeshAtLevel(-2,renum);
 }
@@ -2929,17 +3097,34 @@ MEDCouplingUMesh *MEDFileUMesh::getLevelM2Mesh(bool renum) const throw(INTERP_KE
  *          delete using decrRef() as it is no more needed. 
  *  \throw If there are no mesh entities of the relative dimension == -3 in \a this mesh.
  */
-MEDCouplingUMesh *MEDFileUMesh::getLevelM3Mesh(bool renum) const throw(INTERP_KERNEL::Exception)
+MEDCouplingUMesh *MEDFileUMesh::getLevelM3Mesh(bool renum) const
 {
   return getMeshAtLevel(-3,renum);
 }
 
+/*!
+ * This method is for advanced users. There is two storing strategy of mesh in \a this.
+ * Either MEDCouplingUMesh, or vector of MEDCoupling1GTUMesh instances.
+ * When assignement is done the first one is done, which is not optimal in write mode for MED file.
+ * This method allows to switch from MEDCouplingUMesh mode to MEDCoupling1GTUMesh mode.
+ */
+void MEDFileUMesh::forceComputationOfParts() const
+{
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
+    {
+      const MEDFileUMeshSplitL1 *elt(*it);
+      if(elt)
+        elt->forceComputationOfParts();
+    }
+}
+
 /*!
  * This method returns a vector of mesh parts containing each exactly one geometric type.
  * This method will never launch an automatic computation of split by type (an INTERP_KERNEL::Exception will be then thrown).
  * This method is only for memory aware users.
+ * The returned pointers are **NOT** new object pointer. No need to mange them.
  */
-std::vector<MEDCoupling1GTUMesh *> MEDFileUMesh::getDirectUndergroundSingleGeoTypeMeshes(int meshDimRelToMax) const throw(INTERP_KERNEL::Exception)
+std::vector<MEDCoupling1GTUMesh *> MEDFileUMesh::getDirectUndergroundSingleGeoTypeMeshes(int meshDimRelToMax) const
 {
   const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
   return sp->getDirectUndergroundSingleGeoTypeMeshes();
@@ -2948,8 +3133,9 @@ std::vector<MEDCoupling1GTUMesh *> MEDFileUMesh::getDirectUndergroundSingleGeoTy
 /*!
  * This method returns the part of \a this having the geometric type \a gt.
  * If such part is not existing an exception will be thrown.
+ * The returned pointer is **NOT** new object pointer. No need to mange it.
  */
-MEDCoupling1GTUMesh *MEDFileUMesh::getDirectUndergroundSingleGeoTypeMesh(INTERP_KERNEL::NormalizedCellType gt) const throw(INTERP_KERNEL::Exception)
+MEDCoupling1GTUMesh *MEDFileUMesh::getDirectUndergroundSingleGeoTypeMesh(INTERP_KERNEL::NormalizedCellType gt) const
 {
   const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
   int lev=(int)cm.getDimension()-getMeshDimension();
@@ -2957,7 +3143,59 @@ MEDCoupling1GTUMesh *MEDFileUMesh::getDirectUndergroundSingleGeoTypeMesh(INTERP_
   return sp->getDirectUndergroundSingleGeoTypeMesh(gt);
 }
 
-const MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
+/*!
+ * 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.
+ */
+std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileUMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
+{
+  const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
+  return sp->getGeoTypes();
+}
+
+/*!
+ * This method extracts from whole family field ids the part relative to the input parameter \a gt.
+ * \param [in] gt - the geometric type for which the family field is asked.
+ * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
+ *          delete using decrRef() as it is no more needed.
+ * \sa MEDFileUMesh::extractNumberFieldOnGeoType
+ */
+DataArrayInt *MEDFileUMesh::extractFamilyFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
+{
+  const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
+  int lev=(int)cm.getDimension()-getMeshDimension();
+  const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
+  return sp->extractFamilyFieldOnGeoType(gt);
+}
+
+/*!
+ * This method extracts from whole number field ids the part relative to the input parameter \a gt.
+ * \param [in] gt - the geometric type for which the number field is asked.
+ * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
+ *          delete using decrRef() as it is no more needed.
+ * \sa MEDFileUMesh::extractFamilyFieldOnGeoType
+ */
+DataArrayInt *MEDFileUMesh::extractNumberFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
+{
+  const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
+  int lev=(int)cm.getDimension()-getMeshDimension();
+  const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
+  return sp->extractNumberFieldOnGeoType(gt);
+}
+
+/*!
+ * This method returns for specified geometric type \a gt the relative level to \a this.
+ * If the relative level is empty an exception will be thrown.
+ */
+int MEDFileUMesh::getRelativeLevOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
+{
+  const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
+  int ret((int)cm.getDimension()-getMeshDimension());
+  getMeshAtLevSafe(ret);//To test that returned value corresponds to a valid level.
+  return ret;
+}
+
+const MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) const
 {
   if(meshDimRelToMaxExt==1)
     throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
@@ -2971,9 +3209,9 @@ const MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt
   return _ms[tracucedRk];
 }
 
-MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) throw(INTERP_KERNEL::Exception)
+MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt)
 {
-   if(meshDimRelToMaxExt==1)
+  if(meshDimRelToMaxExt==1)
     throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
   if(meshDimRelToMaxExt>1)
     throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
@@ -2985,7 +3223,7 @@ MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) thro
   return _ms[tracucedRk];
 }
 
-void MEDFileUMesh::checkMeshDimCoherency(int meshDim, int meshDimRelToMax) const throw(INTERP_KERNEL::Exception)
+void MEDFileUMesh::checkMeshDimCoherency(int meshDim, int meshDimRelToMax) const
 {
   if(-meshDimRelToMax>=(int)_ms.size())
     throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : The meshdim of mesh is not managed by 'this' !");
@@ -3006,7 +3244,7 @@ void MEDFileUMesh::checkMeshDimCoherency(int meshDim, int meshDimRelToMax) const
  *  \param [in] coords - the new node coordinates array.
  *  \throw If \a coords == \c NULL.
  */
-void MEDFileUMesh::setCoords(DataArrayDouble *coords) throw(INTERP_KERNEL::Exception)
+void MEDFileUMesh::setCoords(DataArrayDouble *coords)
 {
   if(!coords)
     throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoords : null pointer in input !");
@@ -3027,7 +3265,7 @@ void MEDFileUMesh::setCoords(DataArrayDouble *coords) throw(INTERP_KERNEL::Excep
  *  \param [in] meshDimRelToMaxExt - the relative dimension of interest.
  *  \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
  */
-void MEDFileUMesh::eraseGroupsAtLevel(int meshDimRelToMaxExt) throw(INTERP_KERNEL::Exception)
+void MEDFileUMesh::eraseGroupsAtLevel(int meshDimRelToMaxExt)
 {
   if(meshDimRelToMaxExt==1)
     {
@@ -3043,7 +3281,7 @@ void MEDFileUMesh::eraseGroupsAtLevel(int meshDimRelToMaxExt) throw(INTERP_KERNE
 /*!
  * Removes all families with ids not present in the family fields of \a this mesh.
  */
-void MEDFileUMesh::optimizeFamilies() throw(INTERP_KERNEL::Exception)
+void MEDFileUMesh::optimizeFamilies()
 {
   std::vector<int> levs=getNonEmptyLevelsExt();
   std::set<int> allFamsIds;
@@ -3081,7 +3319,7 @@ void MEDFileUMesh::optimizeFamilies() throw(INTERP_KERNEL::Exception)
     _groups.erase(*it);
 }
 
-void MEDFileUMesh::duplicateNodesOnM1Group(const char *grpNameM1, DataArrayInt *&nodesDuplicated, DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified) throw(INTERP_KERNEL::Exception)
+void MEDFileUMesh::duplicateNodesOnM1Group(const std::string& grpNameM1, DataArrayInt *&nodesDuplicated, DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified)
 {
   std::vector<int> levs=getNonEmptyLevels();
   if(std::find(levs.begin(),levs.end(),0)==levs.end() || std::find(levs.begin(),levs.end(),-1)==levs.end())
@@ -3154,8 +3392,8 @@ void MEDFileUMesh::duplicateNodesOnM1Group(const char *grpNameM1, DataArrayInt *
   setMeshAtLevel(-1,newm1);
   setFamilyFieldArr(-1,newFam);
   std::string grpName2(grpNameM1); grpName2+="_dup";
-  addFamily(grpName2.c_str(),idd);
-  addFamilyOnGrp(grpName2.c_str(),grpName2.c_str());
+  addFamily(grpName2,idd);
+  addFamilyOnGrp(grpName2,grpName2);
   //
   fam=_fam_coords;
   if(fam)
@@ -3179,7 +3417,7 @@ void MEDFileUMesh::duplicateNodesOnM1Group(const char *grpNameM1, DataArrayInt *
  * \return false if no modification has been performed linked to the unpolyzation. Neither cell type, not cell numbers. When false is returned no need of field on cells or on gauss renumbering.
  * Inversely, if true is returned, it means that distribution of cell by geometric type has changed and field on cell and field on gauss point must be renumbered.
  */
-bool MEDFileUMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell) throw(INTERP_KERNEL::Exception)
+bool MEDFileUMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
 {
   o2nRenumCell=0; oldCode.clear(); newCode.clear();
   std::vector<int> levs=getNonEmptyLevels();
@@ -3197,7 +3435,7 @@ bool MEDFileUMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode
       bool hasChanged=m->unPolyze();
       DataArrayInt *fake=0;
       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nCellsPart=m->getLevArrPerCellTypes(MEDCouplingUMesh::MEDMEM_ORDER,
-                                                                                           MEDCouplingUMesh::MEDMEM_ORDER+MEDCouplingUMesh::N_MEDMEM_ORDER,fake);
+          MEDCouplingUMesh::MEDMEM_ORDER+MEDCouplingUMesh::N_MEDMEM_ORDER,fake);
       fake->decrRef();
       renumCellsSplited.push_back(o2nCellsPart); memorySaverIfThrow.push_back(o2nCellsPart);
       if(hasChanged)
@@ -3259,26 +3497,37 @@ struct MEDLoaderAccVisit1
  * \throw If no coordinates are set in \a this or if there is in any available mesh in \a this a cell having a nodal connectivity containing a node id not in the range of
  *  set coordinates.
  */
-DataArrayInt *MEDFileUMesh::zipCoords() throw(INTERP_KERNEL::Exception)
+DataArrayInt *MEDFileUMesh::zipCoords()
 {
-  const DataArrayDouble *coo=getCoords();
+  const DataArrayDouble *coo(getCoords());
   if(!coo)
     throw INTERP_KERNEL::Exception("MEDFileUMesh::zipCoords : no coordinates set in this !");
-  int nbOfNodes=coo->getNumberOfTuples();
+  int nbOfNodes(coo->getNumberOfTuples());
   std::vector<bool> nodeIdsInUse(nbOfNodes,false);
-  std::vector<int> neLevs=getNonEmptyLevels();
+  std::vector<int> neLevs(getNonEmptyLevels());
   for(std::vector<int>::const_iterator lev=neLevs.begin();lev!=neLevs.end();lev++)
     {
-      MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=getMeshAtLevel(*lev);
-      m->computeNodeIdsAlg(nodeIdsInUse);
+      const MEDFileUMeshSplitL1 *zeLev(getMeshAtLevSafe(*lev));
+      if(zeLev->isMeshStoredSplitByType())
+        {
+          std::vector<MEDCoupling1GTUMesh *> ms(zeLev->getDirectUndergroundSingleGeoTypeMeshes());
+          for(std::vector<MEDCoupling1GTUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
+            if(*it)
+              (*it)->computeNodeIdsAlg(nodeIdsInUse);
+        }
+      else
+        {
+          MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh(zeLev->getWholeMesh(false));
+          mesh->computeNodeIdsAlg(nodeIdsInUse);
+        }
     }
-  int nbrOfNodesInUse=(int)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true);
+  int nbrOfNodesInUse((int)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true));
   if(nbrOfNodesInUse==nbOfNodes)
-    return 0;
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfNodes,1);
+    return 0;//no need to update _part_coords
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfNodes,1);
   std::transform(nodeIdsInUse.begin(),nodeIdsInUse.end(),ret->getPointer(),MEDLoaderAccVisit1());
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=ret->invertArrayO2N2N2OBis(nbrOfNodesInUse);
-  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newCoords=coo->selectByTupleIdSafe(ret2->begin(),ret2->end());
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2(ret->invertArrayO2N2N2OBis(nbrOfNodesInUse));
+  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newCoords(coo->selectByTupleIdSafe(ret2->begin(),ret2->end()));
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFamCoords;
   MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar> newNameCoords;
   if((const DataArrayInt *)_fam_coords)
@@ -3292,7 +3541,17 @@ DataArrayInt *MEDFileUMesh::zipCoords() throw(INTERP_KERNEL::Exception)
   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
     {
       if((MEDFileUMeshSplitL1*)*it)
-        (*it)->renumberNodesInConn(ret->begin());
+        {
+          (*it)->renumberNodesInConn(ret->begin());
+          (*it)->setCoords(_coords);
+        }
+    }
+  // updates _part_coords
+  const PartDefinition *pc(_part_coords);
+  if(pc)
+    {
+      MEDCouplingAutoRefCountObjectPtr<PartDefinition> tmpPD(DataArrayPartDefinition::New(ret2));
+      _part_coords=tmpPD->composeWith(pc);
     }
   return ret.retn();
 }
@@ -3307,7 +3566,7 @@ DataArrayInt *MEDFileUMesh::zipCoords() throw(INTERP_KERNEL::Exception)
  *  \throw If \a ids does not respect the MED file norm.
  *  \throw If a group with name \a ids->getName() already exists.
  */
-void MEDFileUMesh::addNodeGroup(const DataArrayInt *ids) throw(INTERP_KERNEL::Exception)
+void MEDFileUMesh::addNodeGroup(const DataArrayInt *ids)
 {
   const DataArrayDouble *coords=_coords;
   if(!coords)
@@ -3329,7 +3588,7 @@ void MEDFileUMesh::addNodeGroup(const DataArrayInt *ids) throw(INTERP_KERNEL::Ex
  *  \throw If \a ids does not respect the MED file norm.
  *  \throw If a group with name \a ids->getName() already exists.
  */
-void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids) throw(INTERP_KERNEL::Exception)
+void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids)
 {
   std::vector<int> levs=getNonEmptyLevelsExt();
   if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
@@ -3348,7 +3607,7 @@ void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids) thr
  * \param [in] ids ids and group name of the new group to add. The ids should be sorted and different each other (MED file norm).
  * \parma [in,out] famArr family array on level of interest to be renumbered. The input pointer should be not \c NULL (no check of that will be performed)
  */
-void MEDFileUMesh::addGroupUnderground(bool isNodeGroup, const DataArrayInt *ids, DataArrayInt *famArr) throw(INTERP_KERNEL::Exception)
+void MEDFileUMesh::addGroupUnderground(bool isNodeGroup, const DataArrayInt *ids, DataArrayInt *famArr)
 {
   if(!ids)
     throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : NULL pointer in input !");
@@ -3395,7 +3654,7 @@ void MEDFileUMesh::addGroupUnderground(bool isNodeGroup, const DataArrayInt *ids
               if(existsFamily(*famId))
                 {
                   std::string locFamName2=getFamilyNameGivenId(*famId); std::vector<std::string> v(2); v[0]=locFamName2; v[1]=locFamName;
-                  ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId).c_str(),v);
+                  ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
                 }
               maxVal++;
             } // modifying all other groups on *famId to lie on maxVal and lie the grp on maxVal
@@ -3408,7 +3667,7 @@ void MEDFileUMesh::addGroupUnderground(bool isNodeGroup, const DataArrayInt *ids
           if(existsFamily(*famId))
             {
               std::string n1(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created)); std::vector<std::string> v(2); v[0]=n1; v[1]=n2;
-              ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId).c_str(),v);
+              ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
             }
           maxVal+=2;
         }
@@ -3429,7 +3688,7 @@ void MEDFileUMesh::addGroupUnderground(bool isNodeGroup, const DataArrayInt *ids
  *  \param [in] newFamName - the new family name.
  *  \throw If no family with the given \a id exists.
  */
-void MEDFileUMesh::setFamilyNameAttachedOnId(int id, const std::string& newFamName) throw(INTERP_KERNEL::Exception)
+void MEDFileUMesh::setFamilyNameAttachedOnId(int id, const std::string& newFamName)
 {
   std::string oldName=getFamilyNameGivenId(id);
   _families.erase(oldName);
@@ -3441,7 +3700,7 @@ void MEDFileUMesh::setFamilyNameAttachedOnId(int id, const std::string& newFamNa
  *  \param [in] meshDimRelToMax - the relative dimension of interest.
  *  \throw If there is no mesh at level \a meshDimRelToMax in \a this mesh.
  */
-void MEDFileUMesh::removeMeshAtLevel(int meshDimRelToMax) throw(INTERP_KERNEL::Exception)
+void MEDFileUMesh::removeMeshAtLevel(int meshDimRelToMax)
 {
   std::vector<int> levSet=getNonEmptyLevels();
   std::vector<int>::const_iterator it=std::find(levSet.begin(),levSet.end(),meshDimRelToMax);
@@ -3451,6 +3710,23 @@ void MEDFileUMesh::removeMeshAtLevel(int meshDimRelToMax) throw(INTERP_KERNEL::E
   _ms[pos]=0;
 }
 
+/*!
+ * Sets a new MEDCoupling1GTUMesh at a given level in \a this mesh.
+ *  \param [in] meshDimRelToMax - a relative level to set the mesh at.
+ *  \param [in] m - the new mesh to set.
+ *  \throw If the name or the description of \a this mesh and \a m are not empty and are
+ *         different. 
+ *  \throw If the node coordinates array is set \a this in mesh and \a m refers to
+ *         another node coordinates array.
+ *  \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
+ *         to the existing meshes of other levels of \a this mesh.
+ */
+void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCoupling1GTUMesh *m)
+{
+  MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m));
+  checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
+}
+
 /*!
  * Sets a new MEDCouplingUMesh at a given level in \a this mesh.
  *  \param [in] meshDimRelToMax - a relative level to set the mesh at.
@@ -3464,7 +3740,13 @@ void MEDFileUMesh::removeMeshAtLevel(int meshDimRelToMax) throw(INTERP_KERNEL::E
  *  \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
  *         to the existing meshes of other levels of \a this mesh.
  */
-void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld) throw(INTERP_KERNEL::Exception)
+void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld)
+{
+  MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m,newOrOld));
+  checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
+}
+
+MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1>& MEDFileUMesh::checkAndGiveEntryInSplitL1(int meshDimRelToMax, MEDCouplingPointSet *m)
 {
   dealWithTinyInfo(m);
   std::vector<int> levSet=getNonEmptyLevels();
@@ -3483,10 +3765,10 @@ void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool
       if(sz>=(int)_ms.size())
         _ms.resize(sz);
       checkMeshDimCoherency(m->getMeshDimension(),meshDimRelToMax);
-      _ms[sz-1]=new MEDFileUMeshSplitL1(m,newOrOld);
+      return _ms[sz-1];
     }
   else
-    _ms[-meshDimRelToMax]=new MEDFileUMeshSplitL1(m,newOrOld);
+    return _ms[-meshDimRelToMax];
 }
 
 /*!
@@ -3500,7 +3782,7 @@ void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool
  * \throw If \a there is a null pointer in \a ms.
  * \sa MEDFileUMesh::setMeshAtLevel
  */
-void MEDFileUMesh::setMeshes(const std::vector<const MEDCouplingUMesh *>& ms, bool renum) throw(INTERP_KERNEL::Exception)
+void MEDFileUMesh::setMeshes(const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
 {
   if(ms.empty())
     return ;
@@ -3529,7 +3811,7 @@ void MEDFileUMesh::setMeshes(const std::vector<const MEDCouplingUMesh *>& ms, bo
       setName((*it)->getName());
       setMeshAtLevel(mdim-zeDim,const_cast<MEDCouplingUMesh *>(*it),renum);
     }
-  setName(name.c_str());
+  setName(name);
 }
 
 /*!
@@ -3549,7 +3831,7 @@ void MEDFileUMesh::setMeshes(const std::vector<const MEDCouplingUMesh *>& ms, bo
  *  \throw If names of some meshes in \a ms are equal.
  *  \throw If \a ms includes a mesh with an empty name.
  */
-void MEDFileUMesh::setGroupsFromScratch(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum) throw(INTERP_KERNEL::Exception)
+void MEDFileUMesh::setGroupsFromScratch(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
 {
   if(ms.empty())
     throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : expecting a non empty vector !");
@@ -3593,7 +3875,7 @@ void MEDFileUMesh::setGroupsFromScratch(int meshDimRelToMax, const std::vector<c
  *  \throw If names of some meshes in \a ms are equal.
  *  \throw If \a ms includes a mesh with an empty name.
  */
-void MEDFileUMesh::setGroupsOnSetMesh(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum) throw(INTERP_KERNEL::Exception)
+void MEDFileUMesh::setGroupsOnSetMesh(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
 {
   if(ms.empty())
     throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : expecting a non empty vector !");
@@ -3628,7 +3910,7 @@ void MEDFileUMesh::setGroupsOnSetMesh(int meshDimRelToMax, const std::vector<con
   setGroupsAtLevel(meshDimRelToMax,corr2,renum);
 }
 
-DataArrayDouble *MEDFileUMesh::checkMultiMesh(const std::vector<const MEDCouplingUMesh *>& ms) const throw(INTERP_KERNEL::Exception)
+DataArrayDouble *MEDFileUMesh::checkMultiMesh(const std::vector<const MEDCouplingUMesh *>& ms) const
 {
   const DataArrayDouble *ret=ms[0]->getCoords();
   int mdim=ms[0]->getMeshDimension();
@@ -3651,7 +3933,7 @@ DataArrayDouble *MEDFileUMesh::checkMultiMesh(const std::vector<const MEDCouplin
  *  \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
  *  \throw If \a famArr has an invalid size.
  */
-void MEDFileUMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr) throw(INTERP_KERNEL::Exception)
+void MEDFileUMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
 {
   if(meshDimRelToMaxExt==1)
     {
@@ -3685,7 +3967,7 @@ void MEDFileUMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famAr
  *  \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
  *  \throw If \a renumArr has an invalid size.
  */
-void MEDFileUMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr) throw(INTERP_KERNEL::Exception)
+void MEDFileUMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
 {
   if(meshDimRelToMaxExt==1)
     {
@@ -3721,7 +4003,7 @@ void MEDFileUMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumA
  *  \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
  *  \throw If \a nameArr has an invalid size.
  */
-void MEDFileUMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr) throw(INTERP_KERNEL::Exception)
+void MEDFileUMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
 {
   if(meshDimRelToMaxExt==1)
     {
@@ -3758,7 +4040,7 @@ void MEDFileUMesh::synchronizeTinyInfoOnLeaves() const
 /*!
  * This method is called by MEDFileMesh::changeFamilyId. It performs only one part of the family id modification.
  */
-void MEDFileUMesh::changeFamilyIdArr(int oldId, int newId) throw(INTERP_KERNEL::Exception)
+void MEDFileUMesh::changeFamilyIdArr(int oldId, int newId)
 {
   DataArrayInt *arr=_fam_coords;
   if(arr)
@@ -3802,25 +4084,30 @@ void MEDFileUMesh::computeRevNum() const
     }
 }
 
-std::size_t MEDFileStructuredMesh::getHeapMemorySize() const
+std::size_t MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren() const
 {
-  std::size_t ret=MEDFileMesh::getHeapMemorySize();
-  if((const DataArrayInt*)_fam_nodes)
-    ret+=_fam_nodes->getHeapMemorySize();
-  if((const DataArrayInt*)_num_nodes)
-    ret+=_num_nodes->getHeapMemorySize();
-  if((const DataArrayInt*)_fam_cells)
-    ret+=_fam_cells->getHeapMemorySize();
-  if((const DataArrayInt*)_num_cells)
-    ret+=_num_cells->getHeapMemorySize();
-  if((const DataArrayInt*)_rev_num_nodes)
-    ret+=_rev_num_nodes->getHeapMemorySize();
-  if((const DataArrayInt*)_rev_num_cells)
-    ret+=_rev_num_cells->getHeapMemorySize();
+  return MEDFileMesh::getHeapMemorySizeWithoutChildren();
+}
+
+std::vector<const BigMemoryObject *> MEDFileStructuredMesh::getDirectChildrenWithNull() const
+{
+  std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
+  ret.push_back((const DataArrayInt *)_fam_nodes);
+  ret.push_back((const DataArrayInt *)_num_nodes);
+  ret.push_back((const DataArrayAsciiChar *)_names_nodes);
+  ret.push_back((const DataArrayInt *)_fam_cells);
+  ret.push_back((const DataArrayInt *)_num_cells);
+  ret.push_back((const DataArrayAsciiChar *)_names_cells);
+  ret.push_back((const DataArrayInt *)_fam_faces);
+  ret.push_back((const DataArrayInt *)_num_faces);
+  ret.push_back((const DataArrayInt *)_rev_num_nodes);
+  ret.push_back((const DataArrayAsciiChar *)_names_faces);
+  ret.push_back((const DataArrayInt *)_rev_num_cells);
+  ret.push_back((const MEDCoupling1SGTUMesh*)_faces_if_necessary);
   return ret;
 }
 
-int MEDFileStructuredMesh::getMaxAbsFamilyIdInArrays() const throw(INTERP_KERNEL::Exception)
+int MEDFileStructuredMesh::getMaxAbsFamilyIdInArrays() const
 {
   int ret=-std::numeric_limits<int>::max(),tmp=-1;
   if((const DataArrayInt *)_fam_nodes)
@@ -3833,10 +4120,15 @@ int MEDFileStructuredMesh::getMaxAbsFamilyIdInArrays() const throw(INTERP_KERNEL
       int val=_fam_cells->getMaxValue(tmp);
       ret=std::max(ret,std::abs(val));
     }
+  if((const DataArrayInt *)_fam_faces)
+    {
+      int val=_fam_faces->getMaxValue(tmp);
+      ret=std::max(ret,std::abs(val));
+    }
   return ret;
 }
 
-int MEDFileStructuredMesh::getMaxFamilyIdInArrays() const throw(INTERP_KERNEL::Exception)
+int MEDFileStructuredMesh::getMaxFamilyIdInArrays() const
 {
   int ret=-std::numeric_limits<int>::max(),tmp=-1;
   if((const DataArrayInt *)_fam_nodes)
@@ -3849,10 +4141,15 @@ int MEDFileStructuredMesh::getMaxFamilyIdInArrays() const throw(INTERP_KERNEL::E
       int val=_fam_cells->getMaxValue(tmp);
       ret=std::max(ret,val);
     }
+  if((const DataArrayInt *)_fam_faces)
+    {
+      int val=_fam_faces->getMaxValue(tmp);
+      ret=std::max(ret,val);
+    }
   return ret;
 }
 
-int MEDFileStructuredMesh::getMinFamilyIdInArrays() const throw(INTERP_KERNEL::Exception)
+int MEDFileStructuredMesh::getMinFamilyIdInArrays() const
 {
   int ret=std::numeric_limits<int>::max(),tmp=-1;
   if((const DataArrayInt *)_fam_nodes)
@@ -3865,6 +4162,11 @@ int MEDFileStructuredMesh::getMinFamilyIdInArrays() const throw(INTERP_KERNEL::E
       int val=_fam_cells->getMinValue(tmp);
       ret=std::min(ret,val);
     }
+  if((const DataArrayInt *)_fam_faces)
+    {
+      int val=_fam_faces->getMinValue(tmp);
+      ret=std::min(ret,val);
+    }
   return ret;
 }
 
@@ -3910,6 +4212,22 @@ bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::s
           return false;
         }
     }
+  famc1=_fam_faces;
+  famc2=otherC->_fam_faces;
+  if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
+    {
+      what="Mismatch of families arr on faces ! One is defined and not other !";
+      return false;
+    }
+  if(famc1)
+    {
+      bool ret=famc1->isEqual(*famc2);
+      if(!ret)
+        {
+          what="Families arr on faces differ !";
+          return false;
+        }
+    }
   famc1=_num_nodes;
   famc2=otherC->_num_nodes;
   if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
@@ -3942,6 +4260,22 @@ bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::s
           return false;
         }
     }
+  famc1=_num_faces;
+  famc2=otherC->_num_faces;
+  if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
+    {
+      what="Mismatch of numbering arr on faces ! One is defined and not other !";
+      return false;
+    }
+  if(famc1)
+    {
+      bool ret=famc1->isEqual(*famc2);
+      if(!ret)
+        {
+          what="Numbering arr on faces differ !";
+          return false;
+        }
+    }
   const DataArrayAsciiChar *d1=_names_cells;
   const DataArrayAsciiChar *d2=otherC->_names_cells;
   if((d1==0 && d2!=0) || (d1!=0 && d2==0))
@@ -3958,6 +4292,22 @@ bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::s
           return false;
         }
     }
+  d1=_names_faces;
+  d2=otherC->_names_faces;
+  if((d1==0 && d2!=0) || (d1!=0 && d2==0))
+    {
+      what="Mismatch of naming arr on faces ! One is defined and not other !";
+      return false;
+    }
+  if(d1)
+    {
+      bool ret=d1->isEqual(*d2);
+      if(!ret)
+        {
+          what="Naming arr on faces differ !";
+          return false;
+        }
+    }
   d1=_names_nodes;
   d2=otherC->_names_nodes;
   if((d1==0 && d2!=0) || (d1!=0 && d2==0))
@@ -3992,6 +4342,12 @@ void MEDFileStructuredMesh::clearNonDiscrAttributes() const
   tmp=_num_cells;
   if(tmp)
     (const_cast<DataArrayInt *>(tmp))->setName("");
+  tmp=_fam_faces;
+  if(tmp)
+    (const_cast<DataArrayInt *>(tmp))->setName("");
+  tmp=_num_faces;
+  if(tmp)
+    (const_cast<DataArrayInt *>(tmp))->setName("");
 }
 
 /*!
@@ -4006,45 +4362,69 @@ void MEDFileStructuredMesh::clearNonDiscrAttributes() const
  *          is to delete this array using decrRef() as it is no more needed. 
  *  \throw If the family field is missing for \a meshDimRelToMaxExt.
  */
-DataArrayInt *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const throw(INTERP_KERNEL::Exception)
+DataArrayInt *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
 {
-  if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
-    throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : Only available for levels 0 or 1 !");
-  std::vector<int> famIds=getFamiliesIds(fams);
-  if(meshDimRelToMaxExt==1)
-    {
-      if((const DataArrayInt *)_fam_nodes)
-        {
-          MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
-          if(!famIds.empty())
-            da=_fam_nodes->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
-          else
-            da=_fam_nodes->getIdsEqualList(0,0);
-          if(renum)
-            return MEDFileUMeshSplitL1::Renumber(_num_nodes,da);
-          else
-            return da.retn();
-        }
-      else
-        throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on nodes !");
-    }
-  else
-    {
-      if((const DataArrayInt *)_fam_cells)
-        {
-          MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
-          if(!famIds.empty())
-            da=_fam_cells->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
-          else
-            da=_fam_cells->getIdsEqualList(0,0);
-          if(renum)
-            return MEDFileUMeshSplitL1::Renumber(_num_cells,da);
-          else
-            return da.retn();
-        }
-      else
-        throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on cells !");
-    }
+  std::vector<int> famIds(getFamiliesIds(fams));
+  switch(meshDimRelToMaxExt)
+  {
+    case 1:
+      {
+        if((const DataArrayInt *)_fam_nodes)
+          {
+            MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
+            if(!famIds.empty())
+              da=_fam_nodes->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
+            else
+              da=_fam_nodes->getIdsEqualList(0,0);
+            if(renum)
+              return MEDFileUMeshSplitL1::Renumber(_num_nodes,da);
+            else
+              return da.retn();
+          }
+        else
+          throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on nodes !");
+        break;
+      }
+    case 0:
+      {
+        if((const DataArrayInt *)_fam_cells)
+          {
+            MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
+            if(!famIds.empty())
+              da=_fam_cells->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
+            else
+              da=_fam_cells->getIdsEqualList(0,0);
+            if(renum)
+              return MEDFileUMeshSplitL1::Renumber(_num_cells,da);
+            else
+              return da.retn();
+          }
+        else
+          throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on cells !");
+        break;
+      }
+    case -1:
+      {
+        if((const DataArrayInt *)_fam_faces)
+          {
+            MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
+            if(!famIds.empty())
+              da=_fam_faces->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
+            else
+              da=_fam_faces->getIdsEqualList(0,0);
+            if(renum)
+              return MEDFileUMeshSplitL1::Renumber(_num_faces,da);
+            else
+              return da.retn();
+          }
+        else
+          throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on faces !");
+        break;
+      }
+    default:
+      throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : input meshDimRelative must be in [0,1,-1] !");
+  }
+  throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : unmanaged case !");
 }
 
 /*!
@@ -4054,27 +4434,39 @@ DataArrayInt *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, cons
  *  \param [in] famArr - the array of the family field.
  *  \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
  *  \throw If \a famArr has an invalid size.
- *  \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
+ *  \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1 and \a meshDimRelToMaxExt != -1.
  */
-void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr) throw(INTERP_KERNEL::Exception)
+void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
 {
-  if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
-    throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 !");
-  const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
+  const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
   if(!mesh)
     throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : no structured mesh specified ! Impossible to set family array !");
-  if(meshDimRelToMaxExt==0)
-    {
-      int nbCells=mesh->getNumberOfCells();
-      famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !");
-      _fam_cells=famArr;
-    }
-  else
-    {
-      int nbNodes=mesh->getNumberOfNodes();
-      famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
-      _fam_nodes=famArr;
-    }
+  switch(meshDimRelToMaxExt)
+  {
+    case 0:
+      {
+        int nbCells=mesh->getNumberOfCells();
+        famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !");
+        _fam_cells=famArr;
+        break;
+      }
+    case 1:
+      {
+        int nbNodes=mesh->getNumberOfNodes();
+        famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
+        _fam_nodes=famArr;
+        break;
+      }
+    case -1:
+      {
+        int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
+        famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of faces of mesh !");
+        _fam_faces=famArr;
+        break;
+      }
+    default:
+      throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : Only available for levels 0 or 1 or -1 !");
+  }
   if(famArr)
     famArr->incrRef();
 }
@@ -4087,25 +4479,37 @@ void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayI
  *  \throw If \a renumArr has an invalid size.
  *  \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
  */
-void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr) throw(INTERP_KERNEL::Exception)
+void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
 {
-  if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
-    throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 !");
   const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
   if(!mesh)
     throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : no structured mesh specified ! Impossible to set number array !");
-  if(meshDimRelToMaxExt==0)
-    {
-      int nbCells=mesh->getNumberOfCells();
-      renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of cells of mesh !");
-      _num_cells=renumArr;
-    }
-  else
-    {
-      int nbNodes=mesh->getNumberOfNodes();
-      renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
-      _num_nodes=renumArr;
-    }
+  switch(meshDimRelToMaxExt)
+  {
+    case 0:
+      {
+        int nbCells=mesh->getNumberOfCells();
+        renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of cells of mesh !");
+        _num_cells=renumArr;
+        break;
+      }
+    case 1:
+      {
+        int nbNodes=mesh->getNumberOfNodes();
+        renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
+        _num_nodes=renumArr;
+        break;
+      }
+    case -1:
+      {
+        int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
+        renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of faces of mesh !");
+        _num_faces=renumArr;
+        break;
+      }
+    default:
+      throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 or -1 !");
+  }
   if(renumArr)
     renumArr->incrRef();
 }
@@ -4117,25 +4521,36 @@ void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayIn
  *  \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
  *  \throw If \a nameArr has an invalid size.
  */
-void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr) throw(INTERP_KERNEL::Exception)
+void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
 {
-  if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
-    throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : Only available for levels 0 or 1 !");
-  const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
+  const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
   if(!mesh)
     throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : no structured mesh specified ! Impossible to set names array !");
-  if(meshDimRelToMaxExt==0)
-    {
-      int nbCells=mesh->getNumberOfCells();
-      nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of cells of mesh !");
-      _names_cells=nameArr;
-    }
-  else
-    {
-      int nbNodes=mesh->getNumberOfNodes();
-      nameArr->checkNbOfTuplesAndComp(nbNodes,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of nodes of mesh !");
-      _names_nodes=nameArr;
-    }
+  switch(meshDimRelToMaxExt)
+  {
+    case 0:
+      {
+        int nbCells=mesh->getNumberOfCells();
+        nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of cells of mesh !");
+        _names_cells=nameArr;
+        break;
+      }
+    case 1:
+      {
+        int nbNodes=mesh->getNumberOfNodes();
+        nameArr->checkNbOfTuplesAndComp(nbNodes,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of nodes of mesh !");
+        _names_nodes=nameArr;
+        break;
+      }
+    case -1:
+      {
+        int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
+        nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of faces of mesh !");
+        _names_cells=nameArr;
+      }
+    default:
+      throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
+  }
   if(nameArr)
     nameArr->incrRef();
 }
@@ -4147,14 +4562,19 @@ void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArra
  *          each mesh entity belongs to. It can be \c NULL.
  *  \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
  */
-const DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
+const DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
 {
-  if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
-    throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 !");
-  if(meshDimRelToMaxExt==0)
-    return _fam_cells;
-  else
-    return _fam_nodes;
+  switch(meshDimRelToMaxExt)
+  {
+    case 0:
+      return _fam_cells;
+    case 1:
+      return _fam_nodes;
+    case -1:
+      return _fam_faces;
+    default:
+      throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
+  }
 }
 
 /*!
@@ -4164,14 +4584,19 @@ const DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelT
  *  \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
  *  \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
  */
-const DataArrayInt *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
+const DataArrayInt *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
 {
-  if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
-    throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 !");
-  if(meshDimRelToMaxExt==0)
-    return _num_cells;
-  else
-    return _num_nodes;
+  switch(meshDimRelToMaxExt)
+  {
+    case 0:
+      return _num_cells;
+    case 1:
+      return _num_nodes;
+    case -1:
+      return _num_faces;
+    default:
+      throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 or -1 !");
+  }
 }
 
 /*!
@@ -4183,7 +4608,7 @@ const DataArrayInt *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelT
  *  \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
  *  \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
  */
-const DataArrayInt *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
+const DataArrayInt *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
 {
   if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
     throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getRevNumberFieldAtLevel : Only available for levels 0 or 1 !");
@@ -4213,14 +4638,19 @@ const DataArrayInt *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimR
     }
 }
 
-const DataArrayAsciiChar *MEDFileStructuredMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
+const DataArrayAsciiChar *MEDFileStructuredMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
 {
-  if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
-    throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNameFieldAtLevel : Only available for levels 0 or 1 !");
-  if(meshDimRelToMaxExt==0)
-    return _names_cells;
-  else
-    return _names_nodes;
+  switch(meshDimRelToMaxExt)
+  {
+    case 0:
+      return _names_cells;
+    case 1:
+      return _names_nodes;
+    case -1:
+      return _names_faces;
+    default:
+      throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
+  }
 }
 
 /*!
@@ -4250,11 +4680,13 @@ std::vector<int> MEDFileStructuredMesh::getNonEmptyLevelsExt() const
 std::vector<int> MEDFileStructuredMesh::getFamArrNonEmptyLevelsExt() const
 {
   std::vector<int> ret;
-  const DataArrayInt *famNodes(_fam_nodes),*famCells(_fam_cells);
+  const DataArrayInt *famNodes(_fam_nodes),*famCells(_fam_cells),*famFaces(_fam_faces);
   if(famNodes)
     ret.push_back(1);
   if(famCells)
     ret.push_back(0);
+  if(famFaces)
+    ret.push_back(-1);
   return ret;
 }
 
@@ -4264,11 +4696,13 @@ std::vector<int> MEDFileStructuredMesh::getFamArrNonEmptyLevelsExt() const
 std::vector<int> MEDFileStructuredMesh::getNumArrNonEmptyLevelsExt() const
 {
   std::vector<int> ret;
-  const DataArrayInt *numNodes(_num_nodes),*numCells(_num_cells);
+  const DataArrayInt *numNodes(_num_nodes),*numCells(_num_cells),*numFaces(_num_faces);
   if(numNodes)
     ret.push_back(1);
   if(numCells)
     ret.push_back(0);
+  if(numFaces)
+    ret.push_back(-1);
   return ret;
 }
 
@@ -4278,22 +4712,26 @@ std::vector<int> MEDFileStructuredMesh::getNumArrNonEmptyLevelsExt() const
 std::vector<int> MEDFileStructuredMesh::getNameArrNonEmptyLevelsExt() const
 {
   std::vector<int> ret;
-  const DataArrayAsciiChar *namesCells(_names_cells);
+  const DataArrayAsciiChar *namesNodes(_names_nodes),*namesCells(_names_cells),*namesFaces(_names_faces);
+  if(namesNodes)
+    ret.push_back(1);
   if(namesCells)
     ret.push_back(0);
+  if(namesFaces)
+    ret.push_back(-1);
   return ret;
 }
 
 /*!
  * no implementation here, it is not a bug, but intresically no polyhedra in \a this.
  */
-bool MEDFileStructuredMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell) throw(INTERP_KERNEL::Exception)
+bool MEDFileStructuredMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
 {
   oldCode.clear(); newCode.clear(); o2nRenumCell=0;
   return false;
 }
 
-void MEDFileStructuredMesh::changeFamilyIdArr(int oldId, int newId) throw(INTERP_KERNEL::Exception)
+void MEDFileStructuredMesh::changeFamilyIdArr(int oldId, int newId)
 {
   DataArrayInt *arr=_fam_nodes;
   if(arr)
@@ -4301,18 +4739,31 @@ void MEDFileStructuredMesh::changeFamilyIdArr(int oldId, int newId) throw(INTERP
   arr=_fam_cells;
   if(arr)
     arr->changeValue(oldId,newId);
+  arr=_fam_faces;
+  if(arr)
+    arr->changeValue(oldId,newId);
 }
 
-void MEDFileStructuredMesh::deepCpyAttributes() throw(INTERP_KERNEL::Exception)
+void MEDFileStructuredMesh::deepCpyAttributes()
 {
   if((const DataArrayInt*)_fam_nodes)
     _fam_nodes=_fam_nodes->deepCpy();
   if((const DataArrayInt*)_num_nodes)
     _num_nodes=_num_nodes->deepCpy();
+  if((const DataArrayAsciiChar*)_names_nodes)
+    _names_nodes=_names_nodes->deepCpy();
   if((const DataArrayInt*)_fam_cells)
     _fam_cells=_fam_cells->deepCpy();
   if((const DataArrayInt*)_num_cells)
     _num_cells=_num_cells->deepCpy();
+  if((const DataArrayAsciiChar*)_names_cells)
+    _names_cells=_names_cells->deepCpy();
+  if((const DataArrayInt*)_fam_faces)
+    _fam_faces=_fam_faces->deepCpy();
+  if((const DataArrayInt*)_num_faces)
+    _num_faces=_num_faces->deepCpy();
+  if((const DataArrayAsciiChar*)_names_faces)
+    _names_faces=_names_faces->deepCpy();
   if((const DataArrayInt*)_rev_num_nodes)
     _rev_num_nodes=_rev_num_nodes->deepCpy();
   if((const DataArrayInt*)_rev_num_cells)
@@ -4328,21 +4779,37 @@ void MEDFileStructuredMesh::deepCpyAttributes() throw(INTERP_KERNEL::Exception)
 
 /*!
  * Returns a pointer to MEDCouplingStructuredMesh held by \a this. 
- *  \param [in] meshDimRelToMax - it must be \c 0.
+ *  \param [in] meshDimRelToMax - it must be \c 0 or \c -1.
  *  \param [in] renum - it must be \c false.
  *  \return MEDCouplingMesh * - a pointer to MEDCouplingMesh that the caller is to
  *          delete using decrRef() as it is no more needed. 
  */
-MEDCouplingMesh *MEDFileStructuredMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const throw(INTERP_KERNEL::Exception)
+MEDCouplingMesh *MEDFileStructuredMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const
 {
   if(renum)
     throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support renumbering ! To do it perform request of renum array directly !");
-  if(meshDimRelToMax!=0)
-    throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support multi level for mesh 0 expected as input !");
-  const MEDCouplingStructuredMesh *m=getStructuredMesh();
-  if(m)
-    m->incrRef();
-  return const_cast<MEDCouplingStructuredMesh *>(m);
+  const MEDCouplingStructuredMesh *m(getStructuredMesh());
+  switch(meshDimRelToMax)
+  {
+    case 0:
+      {
+        if(m)
+          m->incrRef();
+        return const_cast<MEDCouplingStructuredMesh *>(m);
+      }
+    case -1:
+      {
+        if(!m)
+          throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGenMeshAtLevel : level -1 requested must be non empty to be able to compute unstructured sub mesh !");
+        buildMinusOneImplicitPartIfNeeded();
+        MEDCouplingMesh *ret(_faces_if_necessary);
+        if(ret)
+          ret->incrRef();
+        return ret;
+      }
+    default:
+      throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support multi level for mesh 0 expected as input !");
+  }
 }
 
 /*!
@@ -4351,28 +4818,117 @@ MEDCouplingMesh *MEDFileStructuredMesh::getGenMeshAtLevel(int meshDimRelToMax, b
  *  \return int - the number of entities.
  *  \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
  */
-int MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
+int MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
 {
-  if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
-    throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : Only available for levels 0 or 1 !");
-  const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();
+  const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
   if(!cmesh)
     throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : No structured mesh set !");
-  if(meshDimRelToMaxExt==0)
-    return cmesh->getNumberOfCells();
-  else
-    return cmesh->getNumberOfNodes();
+  switch(meshDimRelToMaxExt)
+  {
+    case 0:
+      return cmesh->getNumberOfCells();
+    case 1:
+      return cmesh->getNumberOfNodes();
+    case -1:
+      return cmesh->getNumberOfCellsOfSubLevelMesh();
+    default:
+      throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : Only available for levels 0 or 1 or -1 !");
+  }
 }
 
-int MEDFileStructuredMesh::getNumberOfNodes() const throw(INTERP_KERNEL::Exception)
+int MEDFileStructuredMesh::getNumberOfNodes() const
 {
-  const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();
+  const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
   if(!cmesh)
     throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
   return cmesh->getNumberOfNodes();
 }
 
-void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const throw(INTERP_KERNEL::Exception)
+bool MEDFileStructuredMesh::hasImplicitPart() const
+{
+  return true;
+}
+
+/*!
+ * \sa MEDFileStructuredMesh::getImplicitFaceMesh
+ */
+int MEDFileStructuredMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
+{
+  static const char MSG[]="MEDFileStructuredMesh::buildImplicitPartIfAny : the given geo type is not manageable by a structured mesh !";
+  const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
+  if(!zeFaceMesh)
+    {
+      const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension())));
+      if(cm.getReverseExtrudedType()!=gt)
+        throw INTERP_KERNEL::Exception(MSG);
+      buildImplicitPart();
+      return getStructuredMesh()->getNumberOfCellsOfSubLevelMesh();
+    }
+  else
+    {
+      if(gt!=zeFaceMesh->getCellModelEnum())
+        throw INTERP_KERNEL::Exception(MSG);
+      return zeFaceMesh->getNumberOfCells();
+    }
+}
+
+void MEDFileStructuredMesh::buildMinusOneImplicitPartIfNeeded() const
+{
+  const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
+  if(!zeFaceMesh)
+    buildImplicitPart();
+}
+
+void MEDFileStructuredMesh::buildImplicitPart() const
+{
+  const MEDCouplingStructuredMesh *mcmesh(getStructuredMesh());
+  if(!mcmesh)
+    throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::buildImplicitPart : Unable to build the implicit part of structured mesh because no structured mesh at level 0 defined !");
+  _faces_if_necessary=mcmesh->build1SGTSubLevelMesh();
+}
+
+void MEDFileStructuredMesh::releaseImplicitPartIfAny() const
+{
+  _faces_if_necessary=0;
+}
+
+/*!
+ * Retrieves the internal pointer (no decrRef requested) of the implicit face mesh if any.
+ * To force to build it you can invoke MEDFileStructuredMesh::buildImplicitPartIfAny method.
+ * 
+ * \sa MEDFileStructuredMesh::buildImplicitPartIfAny
+ */
+MEDCoupling1SGTUMesh *MEDFileStructuredMesh::getImplicitFaceMesh() const
+{
+  return _faces_if_necessary;
+}
+
+std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileStructuredMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
+{
+  const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
+  if(!cmesh)
+    throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : No structured mesh set !");
+  switch(meshDimRelToMax)
+  {
+    case 0:
+      {
+        std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,cmesh->getTypeOfCell(0));
+        return ret;
+      }
+    case -1:
+      {
+        int mdim(cmesh->getMeshDimension());
+        if(mdim<1)
+          throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only one level available for structured meshes ! Input 0 is mandatory or 0D mesh !");
+        std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(mdim-1));
+        return ret;
+      }
+    default:
+      throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only 2 levels available at most : 0 and -1 !");
+  }
+}
+
+void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
 {
   if(st.getNumberOfItems()!=1)
     throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : The sturture of field is not lying on single geo type ! it is not managed yet for structured mesh !");
@@ -4385,7 +4941,7 @@ void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem
       std::fill(nodesFetched.begin(),nodesFetched.end(),true);
       return ;
     }
-  const DataArrayInt *arr(globs->getProfile(st[0].getPflName().c_str()));
+  const DataArrayInt *arr(globs->getProfile(st[0].getPflName()));
   const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();//cmesh not null because getNumberOfNodes called before
   int sz(nodesFetched.size());
   for(const int *work=arr->begin();work!=arr->end();work++)
@@ -4400,119 +4956,121 @@ void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem
     }
 }
 
-med_geometry_type MEDFileStructuredMesh::GetGeoTypeFromMeshDim(int meshDim) throw(INTERP_KERNEL::Exception)
+med_geometry_type MEDFileStructuredMesh::GetGeoTypeFromMeshDim(int meshDim)
 {
-  med_geometry_type geoTypeReq=MED_NONE;
-  switch(meshDim)
-    {
-    case 3:
-      geoTypeReq=MED_HEXA8;
-      break;
-    case 2:
-      geoTypeReq=MED_QUAD4;
-      break;
-    case 1:
-      geoTypeReq=MED_SEG2;
-      break;
-    case 0:
-      geoTypeReq=MED_POINT1;
-      break;
-    default:
-      throw INTERP_KERNEL::Exception("Invalid meshdim detected for structured mesh ! Must be in (1,2,3) !");
-    }
-  return geoTypeReq;
+  INTERP_KERNEL::NormalizedCellType ct(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(meshDim));
+  return typmai3[ct];
 }
 
-void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
+void MEDFileStructuredMesh::LoadStrMeshDAFromFile(med_idt fid, int meshDim, int dt, int it, const std::string& mName, MEDFileMeshReadSelector *mrs,
+                                                  MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& famCells, MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& numCells, MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar>& namesCells)
 {
-  setName(strm->getName());
-  setDescription(strm->getDescription());
-  setUnivName(strm->getUnivName());
-  setIteration(strm->getIteration());
-  setOrder(strm->getOrder());
-  setTimeValue(strm->getTime());
-  setTimeUnit(strm->getTimeUnit());
-  MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
   med_bool chgt=MED_FALSE,trsf=MED_FALSE;
-  int nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
+  med_geometry_type geoTypeReq=MEDFileStructuredMesh::GetGeoTypeFromMeshDim(meshDim);
+  int nbOfElt(0);
+  nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
   if(nbOfElt>0)
     {
-      if(!mrs || mrs->isNodeFamilyFieldReading())
+      if(!mrs || mrs->isCellFamilyFieldReading())
         {
-          _fam_nodes=DataArrayInt::New();
-          _fam_nodes->alloc(nbOfElt,1);
-          MEDmeshEntityFamilyNumberRd(fid,mName,dt,it,MED_NODE,MED_NONE,_fam_nodes->getPointer());
+          famCells=DataArrayInt::New();
+          famCells->alloc(nbOfElt,1);
+          MEDmeshEntityFamilyNumberRd(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,famCells->getPointer());
         }
     }
-  nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_NODE,MED_NONE,MED_NUMBER,MED_NODAL,&chgt,&trsf);
+  nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NUMBER,MED_NODAL,&chgt,&trsf);
   if(nbOfElt>0)
     {
-      if(!mrs || mrs->isNodeNumFieldReading())
+      if(!mrs || mrs->isCellNumFieldReading())
         {
-          _num_nodes=DataArrayInt::New();
-          _num_nodes->alloc(nbOfElt,1);
-          MEDmeshEntityNumberRd(fid,mName,dt,it,MED_NODE,MED_NONE,_num_nodes->getPointer());
+          numCells=DataArrayInt::New();
+          numCells->alloc(nbOfElt,1);
+          MEDmeshEntityNumberRd(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,numCells->getPointer());
         }
     }
-  int meshDim=getStructuredMesh()->getMeshDimension();
-  med_geometry_type geoTypeReq=GetGeoTypeFromMeshDim(meshDim);
-  nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
+  nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NAME,MED_NODAL,&chgt,&trsf);
   if(nbOfElt>0)
     {
-      if(!mrs || mrs->isCellFamilyFieldReading())
+      if(!mrs || mrs->isCellNameFieldReading())
         {
-          _fam_cells=DataArrayInt::New();
-          _fam_cells->alloc(nbOfElt,1);
-          MEDmeshEntityFamilyNumberRd(fid,mName,dt,it,MED_CELL,geoTypeReq,_fam_cells->getPointer());
+          namesCells=DataArrayAsciiChar::New();
+          namesCells->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
+          MEDmeshEntityNameRd(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,namesCells->getPointer());
+          namesCells->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
         }
     }
-  nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_CELL,geoTypeReq,MED_NUMBER,MED_NODAL,&chgt,&trsf);
+}
+
+void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
+{
+  setName(strm->getName());
+  setDescription(strm->getDescription());
+  setUnivName(strm->getUnivName());
+  setIteration(strm->getIteration());
+  setOrder(strm->getOrder());
+  setTimeValue(strm->getTime());
+  setTimeUnit(strm->getTimeUnit());
+  MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
+  med_bool chgt=MED_FALSE,trsf=MED_FALSE;
+  int nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
   if(nbOfElt>0)
     {
-      if(!mrs || mrs->isCellNumFieldReading())
+      if(!mrs || mrs->isNodeFamilyFieldReading())
         {
-          _num_cells=DataArrayInt::New();
-          _num_cells->alloc(nbOfElt,1);
-          MEDmeshEntityNumberRd(fid,mName,dt,it,MED_CELL,geoTypeReq,_num_cells->getPointer());
+          int nbNodes(getNumberOfNodes());
+          if(nbOfElt>nbNodes)
+            throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::loadStrMeshFromFile : invalid size of family node array regarding number of nodes in this ! File seems to be corrupted !");
+          _fam_nodes=DataArrayInt::New();
+          _fam_nodes->alloc(nbNodes,1);//yes nbNodes and not nbOfElt see next line.
+          if(nbNodes>nbOfElt)//yes it appends some times... It explains surely the mdump implementation. Bug revealed by PARAVIS EDF #2475 on structured.med file where only 12 first nodes are !=0 so nbOfElt=12 and nbOfNodes=378...
+            _fam_nodes->fillWithZero();
+          MEDmeshEntityFamilyNumberRd(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_fam_nodes->getPointer());
         }
     }
-  nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_CELL,geoTypeReq,MED_NAME,MED_NODAL,&chgt,&trsf);
+  nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NUMBER,MED_NODAL,&chgt,&trsf);
   if(nbOfElt>0)
     {
-      if(!mrs || mrs->isCellNameFieldReading())
+      if(!mrs || mrs->isNodeNumFieldReading())
         {
-          _names_cells=DataArrayAsciiChar::New();
-          _names_cells->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
-          MEDmeshEntityNameRd(fid,mName,dt,it,MED_CELL,geoTypeReq,_names_cells->getPointer());
-          _names_cells->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
+          _num_nodes=DataArrayInt::New();
+          _num_nodes->alloc(nbOfElt,1);
+          MEDmeshEntityNumberRd(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_num_nodes->getPointer());
         }
     }
-  nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_NODE,MED_NONE,MED_NAME,MED_NODAL,&chgt,&trsf);
+  nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NAME,MED_NODAL,&chgt,&trsf);
   if(nbOfElt>0)
     {
       if(!mrs || mrs->isNodeNameFieldReading())
         {
           _names_nodes=DataArrayAsciiChar::New();
           _names_nodes->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
-          MEDmeshEntityNameRd(fid,mName,dt,it,MED_NODE,MED_NONE,_names_nodes->getPointer());
+          MEDmeshEntityNameRd(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_names_nodes->getPointer());
           _names_nodes->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
         }
     }
+  int meshDim(getStructuredMesh()->getMeshDimension());
+  LoadStrMeshDAFromFile(fid,meshDim,dt,it,mName,mrs,_fam_cells,_num_cells,_names_cells);
+  if(meshDim>=1)
+    LoadStrMeshDAFromFile(fid,meshDim-1,dt,it,mName,mrs,_fam_faces,_num_faces,_names_faces);
 }
 
-void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const char *maa) const throw(INTERP_KERNEL::Exception)
+void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const std::string& maa) const
 {
-  int meshDim=getStructuredMesh()->getMeshDimension();
-  med_geometry_type geoTypeReq=GetGeoTypeFromMeshDim(meshDim);
+  int meshDim(getStructuredMesh()->getMeshDimension());
+  med_geometry_type geoTypeReq(GetGeoTypeFromMeshDim(meshDim)),geoTypeReq2(GetGeoTypeFromMeshDim(meshDim-1));
   //
   if((const DataArrayInt *)_fam_cells)
-    MEDmeshEntityFamilyNumberWr(fid,maa,_iteration,_order,MED_CELL,geoTypeReq,_fam_cells->getNumberOfTuples(),_fam_cells->getConstPointer());
+    MEDmeshEntityFamilyNumberWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_fam_cells->getNumberOfTuples(),_fam_cells->getConstPointer());
+  if((const DataArrayInt *)_fam_faces)
+    MEDmeshEntityFamilyNumberWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_fam_faces->getNumberOfTuples(),_fam_faces->getConstPointer());
   if((const DataArrayInt *)_fam_nodes)
-    MEDmeshEntityFamilyNumberWr(fid,maa,_iteration,_order,MED_NODE,MED_NONE,_fam_nodes->getNumberOfTuples(),_fam_nodes->getConstPointer());
+    MEDmeshEntityFamilyNumberWr(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_fam_nodes->getNumberOfTuples(),_fam_nodes->getConstPointer());
   if((const DataArrayInt *)_num_cells)
-    MEDmeshEntityNumberWr(fid,maa,_iteration,_order,MED_CELL,geoTypeReq,_num_cells->getNumberOfTuples(),_num_cells->getConstPointer());
+    MEDmeshEntityNumberWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_num_cells->getNumberOfTuples(),_num_cells->getConstPointer());
+  if((const DataArrayInt *)_num_faces)
+    MEDmeshEntityNumberWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_num_faces->getNumberOfTuples(),_num_faces->getConstPointer());
   if((const DataArrayInt *)_num_nodes)
-    MEDmeshEntityNumberWr(fid,maa,_iteration,_order,MED_NODE,MED_NONE,_num_nodes->getNumberOfTuples(),_num_nodes->getConstPointer());
+    MEDmeshEntityNumberWr(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_num_nodes->getNumberOfTuples(),_num_nodes->getConstPointer());
   if((const DataArrayAsciiChar *)_names_cells)
     {
       if(_names_cells->getNumberOfComponents()!=MED_SNAME_SIZE)
@@ -4521,7 +5079,17 @@ void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const char *maa) cons
           oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
           throw INTERP_KERNEL::Exception(oss.str().c_str());
         }
-      MEDmeshEntityNameWr(fid,maa,_iteration,_order,MED_CELL,geoTypeReq,_names_cells->getNumberOfTuples(),_names_cells->getConstPointer());
+      MEDmeshEntityNameWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_names_cells->getNumberOfTuples(),_names_cells->getConstPointer());
+    }
+  if((const DataArrayAsciiChar *)_names_faces)
+    {
+      if(_names_faces->getNumberOfComponents()!=MED_SNAME_SIZE)
+        {
+          std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on faces with number of components set to " << MED_SNAME_SIZE;
+          oss << " ! The array has " << _names_faces->getNumberOfComponents() << " components !";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
+      MEDmeshEntityNameWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_names_faces->getNumberOfTuples(),_names_faces->getConstPointer());
     }
   if((const DataArrayAsciiChar *)_names_nodes)
     {
@@ -4531,10 +5099,10 @@ void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const char *maa) cons
           oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
           throw INTERP_KERNEL::Exception(oss.str().c_str());
         }
-      MEDmeshEntityNameWr(fid,maa,_iteration,_order,MED_NODE,MED_NONE,_names_nodes->getNumberOfTuples(),_names_nodes->getConstPointer());
+      MEDmeshEntityNameWr(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_names_nodes->getNumberOfTuples(),_names_nodes->getConstPointer());
     }
   //
-  MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa,_families,_groups,_too_long_str);
+  MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa.c_str(),_families,_groups,_too_long_str);
 }
 
 /*!
@@ -4557,7 +5125,7 @@ MEDFileCMesh *MEDFileCMesh::New()
  *  \throw If there is no meshes in the file.
  *  \throw If the mesh in the file is not a Cartesian one.
  */
-MEDFileCMesh *MEDFileCMesh::New(const char *fileName, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
+MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
 {
   std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
   if(ms.empty())
@@ -4566,12 +5134,12 @@ MEDFileCMesh *MEDFileCMesh::New(const char *fileName, MEDFileMeshReadSelector *m
       throw INTERP_KERNEL::Exception(oss.str().c_str());
     }
   MEDFileUtilities::CheckFileForRead(fileName);
-  MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
+  MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
   int dt,it;
   ParaMEDMEM::MEDCouplingMeshType meshType;
   std::string dummy2;
-  MEDFileMeshL2::GetMeshIdFromName(fid,ms.front().c_str(),meshType,dt,it,dummy2);
-  return new MEDFileCMesh(fid,ms.front().c_str(),dt,it,mrs);
+  MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
+  return new MEDFileCMesh(fid,ms.front(),dt,it,mrs);
 }
 
 /*!
@@ -4588,18 +5156,22 @@ MEDFileCMesh *MEDFileCMesh::New(const char *fileName, MEDFileMeshReadSelector *m
  *  \throw If there is no mesh with given attributes in the file.
  *  \throw If the mesh in the file is not a Cartesian one.
  */
-MEDFileCMesh *MEDFileCMesh::New(const char *fileName, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
+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,MED_ACC_RDONLY);
+  MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
   return new MEDFileCMesh(fid,mName,dt,it,mrs);
 }
 
-std::size_t MEDFileCMesh::getHeapMemorySize() const
+std::size_t MEDFileCMesh::getHeapMemorySizeWithoutChildren() const
+{
+  return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
+}
+
+std::vector<const BigMemoryObject *> MEDFileCMesh::getDirectChildrenWithNull() const
 {
-  std::size_t ret=MEDFileStructuredMesh::getHeapMemorySize();
-  if((const MEDCouplingCMesh *)_cmesh)
-    ret+=_cmesh->getHeapMemorySize();
+  std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
+  ret.push_back((const MEDCouplingCMesh *)_cmesh);
   return ret;
 }
 
@@ -4608,13 +5180,25 @@ std::size_t MEDFileCMesh::getHeapMemorySize() const
  *  \return int - the mesh dimension.
  *  \throw If there are no cells in this mesh.
  */
-int MEDFileCMesh::getMeshDimension() const throw(INTERP_KERNEL::Exception)
+int MEDFileCMesh::getMeshDimension() const
 {
   if(!((const MEDCouplingCMesh*)_cmesh))
     throw INTERP_KERNEL::Exception("MEDFileCMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
   return _cmesh->getMeshDimension();
 }
 
+/*!
+ * Returns the dimension on nodes in \a this mesh.
+ *  \return int - the space dimension.
+ *  \throw If there are no cells in this mesh.
+ */
+int MEDFileCMesh::getSpaceDimension() const
+{
+  if(!((const MEDCouplingCMesh*)_cmesh))
+    throw INTERP_KERNEL::Exception("MEDFileCMesh::getSpaceDimension : unable to get spacedimension because no mesh set !");
+  return _cmesh->getSpaceDimension();
+}
+
 /*!
  * Returns a string describing \a this mesh.
  *  \return std::string - the mesh information string.
@@ -4633,18 +5217,18 @@ std::string MEDFileCMesh::advancedRepr() const
   return simpleRepr();
 }
 
-MEDFileMesh *MEDFileCMesh::shallowCpy() const throw(INTERP_KERNEL::Exception)
+MEDFileMesh *MEDFileCMesh::shallowCpy() const
 {
   MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=new MEDFileCMesh(*this);
   return ret.retn();
 }
 
-MEDFileMesh *MEDFileCMesh::createNewEmpty() const throw(INTERP_KERNEL::Exception)
+MEDFileMesh *MEDFileCMesh::createNewEmpty() const
 {
   return new MEDFileCMesh;
 }
 
-MEDFileMesh *MEDFileCMesh::deepCpy() const throw(INTERP_KERNEL::Exception)
+MEDFileMesh *MEDFileCMesh::deepCpy() const
 {
   MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=new MEDFileCMesh(*this);
   if((const MEDCouplingCMesh*)_cmesh)
@@ -4704,17 +5288,17 @@ MEDFileCMesh::MEDFileCMesh()
 {
 }
 
-MEDFileCMesh::MEDFileCMesh(med_idt fid, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
+MEDFileCMesh::MEDFileCMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
 try
-  {
+{
     loadCMeshFromFile(fid,mName,dt,it,mrs);
-  }
+}
 catch(INTERP_KERNEL::Exception& e)
-  {
+{
     throw e;
-  }
+}
 
-void MEDFileCMesh::loadCMeshFromFile(med_idt fid, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
+void MEDFileCMesh::loadCMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
 {
   ParaMEDMEM::MEDCouplingMeshType meshType;
   int dummy0,dummy1;
@@ -4755,7 +5339,7 @@ const MEDCouplingStructuredMesh *MEDFileCMesh::getStructuredMesh() const
  *  \throw If the name or the description of \a this mesh and \a m are not empty and are
  *         different. 
  */
-void MEDFileCMesh::setMesh(MEDCouplingCMesh *m) throw(INTERP_KERNEL::Exception)
+void MEDFileCMesh::setMesh(MEDCouplingCMesh *m)
 {
   dealWithTinyInfo(m);
   if(m)
@@ -4763,7 +5347,7 @@ void MEDFileCMesh::setMesh(MEDCouplingCMesh *m) throw(INTERP_KERNEL::Exception)
   _cmesh=m;
 }
 
-void MEDFileCMesh::writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception)
+void MEDFileCMesh::writeLL(med_idt fid) const
 {
   INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
   INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
@@ -4771,8 +5355,7 @@ void MEDFileCMesh::writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception)
   MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
   MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
   MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
-  int spaceDim=_cmesh->getSpaceDimension();
-  int meshDim=_cmesh->getMeshDimension();
+  int spaceDim(_cmesh->getSpaceDimension());
   INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
   INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
   for(int i=0;i<spaceDim;i++)
@@ -4783,7 +5366,7 @@ void MEDFileCMesh::writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception)
       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
     }
-  MEDmeshCr(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
+  MEDmeshCr(fid,maa,spaceDim,spaceDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
   MEDmeshUniversalNameWr(fid,maa);
   MEDmeshGridTypeWr(fid,maa,MED_CARTESIAN_GRID);
   for(int i=0;i<spaceDim;i++)
@@ -4792,7 +5375,8 @@ void MEDFileCMesh::writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception)
       MEDmeshGridIndexCoordinateWr(fid,maa,_iteration,_order,_time,i+1,da->getNumberOfTuples(),da->getConstPointer());
     }
   //
-  MEDFileStructuredMesh::writeStructuredLL(fid,maa);
+  std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
+  MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
 }
 
 void MEDFileCMesh::synchronizeTinyInfoOnLeaves() const
@@ -4800,10 +5384,10 @@ void MEDFileCMesh::synchronizeTinyInfoOnLeaves() const
   const MEDCouplingCMesh *cmesh=_cmesh;
   if(!cmesh)
     return;
-  (const_cast<MEDCouplingCMesh *>(cmesh))->setName(_name.c_str());
-  (const_cast<MEDCouplingCMesh *>(cmesh))->setDescription(_desc_name.c_str());
+  (const_cast<MEDCouplingCMesh *>(cmesh))->setName(_name);
+  (const_cast<MEDCouplingCMesh *>(cmesh))->setDescription(_desc_name);
   (const_cast<MEDCouplingCMesh *>(cmesh))->setTime(_time,_iteration,_order);
-  (const_cast<MEDCouplingCMesh *>(cmesh))->setTimeUnit(_dt_unit.c_str());
+  (const_cast<MEDCouplingCMesh *>(cmesh))->setTimeUnit(_dt_unit);
 }
 
 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New()
@@ -4811,7 +5395,7 @@ MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New()
   return new MEDFileCurveLinearMesh;
 }
 
-MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const char *fileName, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
+MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
 {
   std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
   if(ms.empty())
@@ -4820,41 +5404,45 @@ MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const char *fileName, MEDFil
       throw INTERP_KERNEL::Exception(oss.str().c_str());
     }
   MEDFileUtilities::CheckFileForRead(fileName);
-  MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
+  MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
   int dt,it;
   ParaMEDMEM::MEDCouplingMeshType meshType;
   std::string dummy2;
-  MEDFileMeshL2::GetMeshIdFromName(fid,ms.front().c_str(),meshType,dt,it,dummy2);
-  return new MEDFileCurveLinearMesh(fid,ms.front().c_str(),dt,it,mrs);
+  MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
+  return new MEDFileCurveLinearMesh(fid,ms.front(),dt,it,mrs);
 }
 
-MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const char *fileName, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
+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,MED_ACC_RDONLY);
+  MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
   return new MEDFileCurveLinearMesh(fid,mName,dt,it,mrs);
 }
 
-std::size_t MEDFileCurveLinearMesh::getHeapMemorySize() const
+std::size_t MEDFileCurveLinearMesh::getHeapMemorySizeWithoutChildren() const
 {
-  std::size_t ret=MEDFileStructuredMesh::getHeapMemorySize();
-  if((const MEDCouplingCurveLinearMesh *)_clmesh)
-    ret+=_clmesh->getHeapMemorySize();
+  return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
+}
+
+std::vector<const BigMemoryObject *> MEDFileCurveLinearMesh::getDirectChildrenWithNull() const
+{
+  std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
+  ret.push_back((const MEDCouplingCurveLinearMesh *)_clmesh);
   return ret;
 }
 
-MEDFileMesh *MEDFileCurveLinearMesh::shallowCpy() const throw(INTERP_KERNEL::Exception)
+MEDFileMesh *MEDFileCurveLinearMesh::shallowCpy() const
 {
   MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=new MEDFileCurveLinearMesh(*this);
   return ret.retn();
 }
 
-MEDFileMesh *MEDFileCurveLinearMesh::createNewEmpty() const throw(INTERP_KERNEL::Exception)
+MEDFileMesh *MEDFileCurveLinearMesh::createNewEmpty() const
 {
   return new MEDFileCurveLinearMesh;
 }
 
-MEDFileMesh *MEDFileCurveLinearMesh::deepCpy() const throw(INTERP_KERNEL::Exception)
+MEDFileMesh *MEDFileCurveLinearMesh::deepCpy() const
 {
   MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=new MEDFileCurveLinearMesh(*this);
   if((const MEDCouplingCurveLinearMesh*)_clmesh)
@@ -4863,7 +5451,7 @@ MEDFileMesh *MEDFileCurveLinearMesh::deepCpy() const throw(INTERP_KERNEL::Except
   return ret.retn();
 }
 
-int MEDFileCurveLinearMesh::getMeshDimension() const throw(INTERP_KERNEL::Exception)
+int MEDFileCurveLinearMesh::getMeshDimension() const
 {
   if(!((const MEDCouplingCurveLinearMesh*)_clmesh))
     throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
@@ -4922,10 +5510,10 @@ void MEDFileCurveLinearMesh::synchronizeTinyInfoOnLeaves() const
   const MEDCouplingCurveLinearMesh *clmesh=_clmesh;
   if(!clmesh)
     return;
-  (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setName(_name.c_str());
-  (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setDescription(_desc_name.c_str());
+  (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setName(_name);
+  (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setDescription(_desc_name);
   (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTime(_time,_iteration,_order);
-  (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTimeUnit(_dt_unit.c_str());
+  (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTimeUnit(_dt_unit);
 }
 
 const MEDCouplingCurveLinearMesh *MEDFileCurveLinearMesh::getMesh() const
@@ -4934,7 +5522,7 @@ const MEDCouplingCurveLinearMesh *MEDFileCurveLinearMesh::getMesh() const
   return _clmesh;
 }
 
-void MEDFileCurveLinearMesh::setMesh(MEDCouplingCurveLinearMesh *m) throw(INTERP_KERNEL::Exception)
+void MEDFileCurveLinearMesh::setMesh(MEDCouplingCurveLinearMesh *m)
 {
   dealWithTinyInfo(m);
   if(m)
@@ -4952,17 +5540,17 @@ MEDFileCurveLinearMesh::MEDFileCurveLinearMesh()
 {
 }
 
-MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
+MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
 try
-  {
+{
     loadCLMeshFromFile(fid,mName,dt,it,mrs);
-  }
+}
 catch(INTERP_KERNEL::Exception& e)
-  {
+{
     throw e;
-  }
+}
 
-void MEDFileCurveLinearMesh::writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception)
+void MEDFileCurveLinearMesh::writeLL(med_idt fid) const
 {
   INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
   INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
@@ -4990,13 +5578,14 @@ void MEDFileCurveLinearMesh::writeLL(med_idt fid) const throw(INTERP_KERNEL::Exc
   MEDmeshGridTypeWr(fid,maa,MED_CURVILINEAR_GRID);
   std::vector<int> nodeGridSt=_clmesh->getNodeGridStructure();
   MEDmeshGridStructWr(fid,maa,_iteration,_order,_time,&nodeGridSt[0]);
-  
+
   MEDmeshNodeCoordinateWr(fid,maa,_iteration,_order,_time,MED_FULL_INTERLACE,coords->getNumberOfTuples(),coords->begin());
   //
-  MEDFileStructuredMesh::writeStructuredLL(fid,maa);
+  std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
+  MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
 }
 
-void MEDFileCurveLinearMesh::loadCLMeshFromFile(med_idt fid, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
+void MEDFileCurveLinearMesh::loadCLMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
 {
   ParaMEDMEM::MEDCouplingMeshType meshType;
   int dummy0,dummy1;
@@ -5020,17 +5609,17 @@ MEDFileMeshMultiTS *MEDFileMeshMultiTS::New()
   return new MEDFileMeshMultiTS;
 }
 
-MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const char *fileName) throw(INTERP_KERNEL::Exception)
+MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName)
 {
   return new MEDFileMeshMultiTS(fileName);
 }
 
-MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const char *fileName, const char *mName) throw(INTERP_KERNEL::Exception)
+MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName, const std::string& mName)
 {
   return new MEDFileMeshMultiTS(fileName,mName);
 }
 
-MEDFileMeshMultiTS *MEDFileMeshMultiTS::deepCpy() const throw(INTERP_KERNEL::Exception)
+MEDFileMeshMultiTS *MEDFileMeshMultiTS::deepCpy() const
 {
   MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> ret=MEDFileMeshMultiTS::New();
   std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> > meshOneTs(_mesh_one_ts.size());
@@ -5042,22 +5631,27 @@ MEDFileMeshMultiTS *MEDFileMeshMultiTS::deepCpy() const throw(INTERP_KERNEL::Exc
   return ret.retn();
 }
 
-std::size_t MEDFileMeshMultiTS::getHeapMemorySize() const
+std::size_t MEDFileMeshMultiTS::getHeapMemorySizeWithoutChildren() const
+{
+  return _mesh_one_ts.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileMesh>);
+}
+
+std::vector<const BigMemoryObject *> MEDFileMeshMultiTS::getDirectChildrenWithNull() const
 {
-  std::size_t ret=_mesh_one_ts.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileMesh>);
+  std::vector<const BigMemoryObject *> ret;
   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
-    ret+=(*it)->getHeapMemorySize();
+    ret.push_back((const MEDFileMesh *)*it);
   return ret;
 }
 
-const char *MEDFileMeshMultiTS::getName() const throw(INTERP_KERNEL::Exception)
+std::string MEDFileMeshMultiTS::getName() const
 {
   if(_mesh_one_ts.empty())
     throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getName : no time steps set !");
   return _mesh_one_ts[0]->getName();
 }
 
-void MEDFileMeshMultiTS::setName(const char *newMeshName) throw(INTERP_KERNEL::Exception)
+void MEDFileMeshMultiTS::setName(const std::string& newMeshName)
 {
   std::string oldName(getName());
   std::vector< std::pair<std::string,std::string> > v(1);
@@ -5065,7 +5659,7 @@ void MEDFileMeshMultiTS::setName(const char *newMeshName) throw(INTERP_KERNEL::E
   changeNames(v);
 }
 
-bool MEDFileMeshMultiTS::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab) throw(INTERP_KERNEL::Exception)
+bool MEDFileMeshMultiTS::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
 {
   bool ret=false;
   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
@@ -5077,14 +5671,14 @@ bool MEDFileMeshMultiTS::changeNames(const std::vector< std::pair<std::string,st
   return ret;
 }
 
-MEDFileMesh *MEDFileMeshMultiTS::getOneTimeStep() const throw(INTERP_KERNEL::Exception)
+MEDFileMesh *MEDFileMeshMultiTS::getOneTimeStep() const
 {
   if(_mesh_one_ts.empty())
     throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getOneTimeStep : empty time step set !");
   return const_cast<MEDFileMesh *>(static_cast<const MEDFileMesh *>(_mesh_one_ts[0]));
 }
 
-void MEDFileMeshMultiTS::setOneTimeStep(MEDFileMesh *mesh1TimeStep) throw(INTERP_KERNEL::Exception)
+void MEDFileMeshMultiTS::setOneTimeStep(MEDFileMesh *mesh1TimeStep)
 {
   if(!mesh1TimeStep)
     throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::setOneTimeStep : input pointer should be different from 0 !");
@@ -5094,7 +5688,7 @@ void MEDFileMeshMultiTS::setOneTimeStep(MEDFileMesh *mesh1TimeStep) throw(INTERP
   _mesh_one_ts[0]=mesh1TimeStep;
 }
 
-void MEDFileMeshMultiTS::write(med_idt fid) const throw(INTERP_KERNEL::Exception)
+void MEDFileMeshMultiTS::write(med_idt fid) const
 {
   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
     {
@@ -5103,16 +5697,16 @@ void MEDFileMeshMultiTS::write(med_idt fid) const throw(INTERP_KERNEL::Exception
     }
 }
 
-void MEDFileMeshMultiTS::write(const char *fileName, int mode) const throw(INTERP_KERNEL::Exception)
+void MEDFileMeshMultiTS::write(const std::string& fileName, int mode) const
 {
   med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
-  MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,medmod);
+  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().c_str());
+  MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
   write(fid);
 }
 
-void MEDFileMeshMultiTS::loadFromFile(const char *fileName, const char *mName) throw(INTERP_KERNEL::Exception)
+void MEDFileMeshMultiTS::loadFromFile(const std::string& fileName, const std::string& mName)
 {//for the moment to be improved
   _mesh_one_ts.resize(1);
   _mesh_one_ts[0]=MEDFileMesh::New(fileName,mName,-1,-1);
@@ -5122,49 +5716,49 @@ MEDFileMeshMultiTS::MEDFileMeshMultiTS()
 {
 }
 
-MEDFileMeshMultiTS::MEDFileMeshMultiTS(const char *fileName) throw(INTERP_KERNEL::Exception)
+MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName)
 try
-  {
+{
     std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
     if(ms.empty())
-    {
-      std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
-      throw INTERP_KERNEL::Exception(oss.str().c_str());
-    }
+      {
+        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,MED_ACC_RDONLY);
+    MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
     int dt,it;
     ParaMEDMEM::MEDCouplingMeshType meshType;
     std::string dummy2;
-    MEDFileMeshL2::GetMeshIdFromName(fid,ms.front().c_str(),meshType,dt,it,dummy2);
-    loadFromFile(fileName,ms.front().c_str());
-  }
+    MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
+    loadFromFile(fileName,ms.front());
+}
 catch(INTERP_KERNEL::Exception& e)
-  {
+{
     throw e;
-  }
+}
 
-MEDFileMeshMultiTS::MEDFileMeshMultiTS(const char *fileName, const char *mName) throw(INTERP_KERNEL::Exception)
+MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName, const std::string& mName)
 try
-  {
+{
     loadFromFile(fileName,mName);
-  }
+}
 catch(INTERP_KERNEL::Exception& e)
-  {
+{
     throw e;
-  }
+}
 
 MEDFileMeshes *MEDFileMeshes::New()
 {
   return new MEDFileMeshes;
 }
 
-MEDFileMeshes *MEDFileMeshes::New(const char *fileName) throw(INTERP_KERNEL::Exception)
+MEDFileMeshes *MEDFileMeshes::New(const std::string& fileName)
 {
   return new MEDFileMeshes(fileName);
 }
 
-void MEDFileMeshes::write(med_idt fid) const throw(INTERP_KERNEL::Exception)
+void MEDFileMeshes::write(med_idt fid) const
 {
   checkCoherency();
   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
@@ -5174,27 +5768,28 @@ void MEDFileMeshes::write(med_idt fid) const throw(INTERP_KERNEL::Exception)
     }
 }
 
-void MEDFileMeshes::write(const char *fileName, int mode) const throw(INTERP_KERNEL::Exception)
+void MEDFileMeshes::write(const std::string& fileName, int mode) const
 {
   med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
-  MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,medmod);
+  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().c_str());
+  MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
   checkCoherency();
   write(fid);
 }
 
-int MEDFileMeshes::getNumberOfMeshes() const throw(INTERP_KERNEL::Exception)
+int MEDFileMeshes::getNumberOfMeshes() const
 {
   return _meshes.size();
 }
 
-MEDFileMeshesIterator *MEDFileMeshes::iterator() throw(INTERP_KERNEL::Exception)
+MEDFileMeshesIterator *MEDFileMeshes::iterator()
 {
   return new MEDFileMeshesIterator(this);
 }
 
-MEDFileMesh *MEDFileMeshes::getMeshAtPos(int i) const throw(INTERP_KERNEL::Exception)
+/** Return a borrowed reference (caller is not responsible) */
+MEDFileMesh *MEDFileMeshes::getMeshAtPos(int i) const
 {
   if(i<0 || i>=(int)_meshes.size())
     {
@@ -5204,7 +5799,8 @@ MEDFileMesh *MEDFileMeshes::getMeshAtPos(int i) const throw(INTERP_KERNEL::Excep
   return _meshes[i]->getOneTimeStep();
 }
 
-MEDFileMesh *MEDFileMeshes::getMeshWithName(const char *mname) const throw(INTERP_KERNEL::Exception)
+/** Return a borrowed reference (caller is not responsible) */
+MEDFileMesh *MEDFileMeshes::getMeshWithName(const std::string& mname) const
 {
   std::vector<std::string> ms=getMeshesNames();
   std::vector<std::string>::iterator it=std::find(ms.begin(),ms.end(),mname);
@@ -5217,7 +5813,7 @@ MEDFileMesh *MEDFileMeshes::getMeshWithName(const char *mname) const throw(INTER
   return getMeshAtPos((int)std::distance(ms.begin(),it));
 }
 
-std::vector<std::string> MEDFileMeshes::getMeshesNames() const throw(INTERP_KERNEL::Exception)
+std::vector<std::string> MEDFileMeshes::getMeshesNames() const
 {
   std::vector<std::string> ret(_meshes.size());
   int i=0;
@@ -5237,7 +5833,7 @@ std::vector<std::string> MEDFileMeshes::getMeshesNames() const throw(INTERP_KERN
   return ret;
 }
 
-bool MEDFileMeshes::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab) throw(INTERP_KERNEL::Exception)
+bool MEDFileMeshes::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
 {
   bool ret=false;
   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
@@ -5249,12 +5845,12 @@ bool MEDFileMeshes::changeNames(const std::vector< std::pair<std::string,std::st
   return ret;
 }
 
-void MEDFileMeshes::resize(int newSize) throw(INTERP_KERNEL::Exception)
+void MEDFileMeshes::resize(int newSize)
 {
   _meshes.resize(newSize);
 }
 
-void MEDFileMeshes::pushMesh(MEDFileMesh *mesh) throw(INTERP_KERNEL::Exception)
+void MEDFileMeshes::pushMesh(MEDFileMesh *mesh)
 {
   if(!mesh)
     throw INTERP_KERNEL::Exception("MEDFileMeshes::pushMesh : invalid input pointer ! should be different from 0 !");
@@ -5263,7 +5859,7 @@ void MEDFileMeshes::pushMesh(MEDFileMesh *mesh) throw(INTERP_KERNEL::Exception)
   _meshes.push_back(elt);
 }
 
-void MEDFileMeshes::setMeshAtPos(int i, MEDFileMesh *mesh) throw(INTERP_KERNEL::Exception)
+void MEDFileMeshes::setMeshAtPos(int i, MEDFileMesh *mesh)
 {
   if(!mesh)
     throw INTERP_KERNEL::Exception("MEDFileMeshes::setMeshAtPos : invalid input pointer ! should be different from 0 !");
@@ -5274,7 +5870,7 @@ void MEDFileMeshes::setMeshAtPos(int i, MEDFileMesh *mesh) throw(INTERP_KERNEL::
   _meshes[i]=elt;
 }
 
-void MEDFileMeshes::destroyMeshAtPos(int i) throw(INTERP_KERNEL::Exception)
+void MEDFileMeshes::destroyMeshAtPos(int i)
 {
   if(i<0 || i>=(int)_meshes.size())
     {
@@ -5284,29 +5880,29 @@ void MEDFileMeshes::destroyMeshAtPos(int i) throw(INTERP_KERNEL::Exception)
   _meshes.erase(_meshes.begin()+i);
 }
 
-void MEDFileMeshes::loadFromFile(const char *fileName) throw(INTERP_KERNEL::Exception)
+void MEDFileMeshes::loadFromFile(const std::string& fileName)
 {
   std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
   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).c_str());
+    _meshes[i]=MEDFileMeshMultiTS::New(fileName,(*it));
 }
 
 MEDFileMeshes::MEDFileMeshes()
 {
 }
 
-MEDFileMeshes::MEDFileMeshes(const char *fileName) throw(INTERP_KERNEL::Exception)
+MEDFileMeshes::MEDFileMeshes(const std::string& fileName)
 try
-  {
+{
     loadFromFile(fileName);
-  }
-catch(INTERP_KERNEL::Exception& e)
-  {
-  }
+}
+catch(INTERP_KERNEL::Exception& /*e*/)
+{
+}
 
-MEDFileMeshes *MEDFileMeshes::deepCpy() const throw(INTERP_KERNEL::Exception)
+MEDFileMeshes *MEDFileMeshes::deepCpy() const
 {
   std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> > meshes(_meshes.size());
   std::size_t i=0;
@@ -5318,13 +5914,17 @@ MEDFileMeshes *MEDFileMeshes::deepCpy() const throw(INTERP_KERNEL::Exception)
   return ret.retn();
 }
 
-std::size_t MEDFileMeshes::getHeapMemorySize() const
+std::size_t MEDFileMeshes::getHeapMemorySizeWithoutChildren() const
 {
-  std::size_t ret=_meshes.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS>));
+  return _meshes.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS>));
+}
+
+std::vector<const BigMemoryObject *> MEDFileMeshes::getDirectChildrenWithNull() const
+{
+  std::vector<const BigMemoryObject *> ret;
   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
-    if((const MEDFileMeshMultiTS*)*it)
-      ret+=(*it)->getHeapMemorySize();
-  return ret; 
+    ret.push_back((const MEDFileMeshMultiTS *)*it);
+  return ret;
 }
 
 std::string MEDFileMeshes::simpleRepr() const
@@ -5344,7 +5944,7 @@ void MEDFileMeshes::simpleReprWithoutHeader(std::ostream& oss) const
     oss << "  - #" << i << " \"" << mns[i] << "\"\n";
 }
 
-void MEDFileMeshes::checkCoherency() const throw(INTERP_KERNEL::Exception)
+void MEDFileMeshes::checkCoherency() const
 {
   static const char MSG[]="MEDFileMeshes::checkCoherency : mesh at rank ";
   int i=0;