Salome HOME
Improve message in case of throw for end user.
[tools/medcoupling.git] / src / MEDLoader / MEDFileFieldOverView.cxx
index a677c4b05629368989f9458e3918244c2b425d35..105508eb1ea93fcedea87a968d5ef6ff8e0850be 100644 (file)
 #include "MEDFileField.hxx"
 #include "MEDFileMesh.hxx"
 
+#include "MEDCouplingFieldDiscretization.hxx"
 #include "CellModel.hxx"
 
 using namespace ParaMEDMEM;
 
 const unsigned char MEDMeshMultiLev::PARAMEDMEM_2_VTKTYPE[MEDMeshMultiLev::PARAMEDMEM_2_VTKTYPE_LGTH]=
-  {1,3,21,5,9,7,22,34,23,28,255,255,255,255,10,14,13,255,12,255,24,255,16,27,255,26,255,29,255,255,25,42,36,4};
+{1,3,21,5,9,7,22,34,23,28,255,255,255,255,10,14,13,255,12,255,24,255,16,27,255,26,255,29,255,255,25,42,36,4};
+
+const unsigned char MEDMeshMultiLev::HEXA27_PERM_ARRAY[27]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,24,22,21,23,20,25,26};
 
 const char MEDFileField1TSStructItem2::NEWLY_CREATED_PFL_NAME[]="???";
 
@@ -45,7 +48,7 @@ std::size_t MEDFileMeshStruct::getHeapMemorySizeWithoutChildren() const
   return ret;
 }
 
-std::vector<const BigMemoryObject *> MEDFileMeshStruct::getDirectChildren() const
+std::vector<const BigMemoryObject *> MEDFileMeshStruct::getDirectChildrenWithNull() const
 {
   return std::vector<const BigMemoryObject *>();
 }
@@ -79,6 +82,9 @@ int MEDFileMeshStruct::getLevelOfGeoType(INTERP_KERNEL::NormalizedCellType t) co
   throw INTERP_KERNEL::Exception("MEDFileMeshStruct::getLevelOfGeoType : The specified geometric type is not present in the mesh structure !");
 }
 
+/*!
+ * \sa MEDFileMeshStruct::doesManageGeoType
+ */
 int MEDFileMeshStruct::getNumberOfElemsOfGeoType(INTERP_KERNEL::NormalizedCellType t) const
 {
   for(std::vector< std::vector<int> >::const_iterator it1=_geo_types_distrib.begin();it1!=_geo_types_distrib.end();it1++)
@@ -94,6 +100,42 @@ int MEDFileMeshStruct::getNumberOfElemsOfGeoType(INTERP_KERNEL::NormalizedCellTy
   throw INTERP_KERNEL::Exception("The specified geometric type is not present in the mesh structure !");
 }
 
+/*!
+ * \sa MEDFileMeshStruct::getNumberOfElemsOfGeoType
+ */
+bool MEDFileMeshStruct::doesManageGeoType(INTERP_KERNEL::NormalizedCellType t) const
+{
+  for(std::vector< std::vector<int> >::const_iterator it1=_geo_types_distrib.begin();it1!=_geo_types_distrib.end();it1++)
+    {
+      std::size_t sz=(*it1).size();
+      if(sz%3!=0)
+        throw INTERP_KERNEL::Exception("MEDFileMeshStruct::doesManageGeoType : internal error in code !");
+      std::size_t nbGeo=sz/3;
+      for(std::size_t i=0;i<nbGeo;i++)
+        if((*it1)[3*i]==(int)t)
+          return true;
+    }
+  return false;
+}
+
+void MEDFileMeshStruct::appendIfImplicitType(INTERP_KERNEL::NormalizedCellType t)
+{
+  if(!_mesh->hasImplicitPart())
+    throw INTERP_KERNEL::Exception("MEDFileMeshStruct::appendIfImplicitType : by default no implicit geo type can be appended !");
+  static const char MSG[]="MEDFileMeshStruct::appendIfImplicitType : the distribution does not looks like structured standard !";
+  if(_geo_types_distrib.size()!=1)
+    throw INTERP_KERNEL::Exception(MSG);
+  std::size_t sz(_geo_types_distrib[0].size());
+  if(sz%3!=0)
+    throw INTERP_KERNEL::Exception("MEDFileMeshStruct::appendIfImplicitType : internal error in code !");
+  std::size_t nbGeo(sz/3);
+  if(nbGeo!=1)
+    throw INTERP_KERNEL::Exception(MSG);
+  std::vector<int> arr(3); arr[0]=(int)t; arr[1]=_mesh->buildImplicitPartIfAny(t); arr[2]=-1;
+  _geo_types_distrib.push_back(arr);
+}
+
+
 int MEDFileMeshStruct::getNumberOfLevs() const
 {
   return (int)_geo_types_distrib.size();
@@ -117,7 +159,7 @@ std::size_t MEDMeshMultiLev::getHeapMemorySizeWithoutChildren() const
   return 0;
 }
 
-std::vector<const BigMemoryObject *> MEDMeshMultiLev::getDirectChildren() const
+std::vector<const BigMemoryObject *> MEDMeshMultiLev::getDirectChildrenWithNull() const
 {
   return std::vector<const BigMemoryObject *>();
 }
@@ -168,6 +210,15 @@ void MEDMeshMultiLev::setNodeReduction(const DataArrayInt *nr)
   _node_reduction=const_cast<DataArrayInt*>(nr);
 }
 
+void MEDMeshMultiLev::setCellReduction(const DataArrayInt *cr)
+{
+  if(_pfls.size()!=1)
+    throw INTERP_KERNEL::Exception("MEDMeshMultiLev::setCellReduction : can be used only for single geo type mesh !");
+  _pfls[0]=const_cast<DataArrayInt*>(cr);
+  if(cr)
+    cr->incrRef();
+}
+
 bool MEDMeshMultiLev::isFastlyTheSameStruct(const MEDFileField1TSStructItem& fst, const MEDFileFieldGlobsReal *globs) const
 {
   if(fst.getType()==ON_NODES)
@@ -228,7 +279,7 @@ void MEDMeshMultiLev::retrieveFamilyIdsOnCells(DataArrayInt *& famIds, bool& isW
         presenceOfPfls=true;
     }
   if(!presenceOfPfls)
-    { famIds=const_cast<DataArrayInt *>(fids); famIds->incrRef(); isWithoutCopy=_cell_fam_ids_nocpy; return ; }
+    { famIds=const_cast<DataArrayInt *>(fids); famIds->incrRef(); isWithoutCopy=_mesh->isObjectInTheProgeny(famIds); return ; }
   //bad luck the slowest part
   isWithoutCopy=false;
   std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > retSafe(sz);
@@ -271,7 +322,7 @@ void MEDMeshMultiLev::retrieveNumberIdsOnCells(DataArrayInt *& numIds, bool& isW
         presenceOfPfls=true;
     }
   if(!presenceOfPfls)
-    { numIds=const_cast<DataArrayInt *>(nids); numIds->incrRef(); isWithoutCopy=_cell_num_ids_nocpy; return ; }
+    { numIds=const_cast<DataArrayInt *>(nids); numIds->incrRef(); isWithoutCopy=_mesh->isObjectInTheProgeny(numIds); return ; }
   //bad luck the slowest part
   isWithoutCopy=false;
   std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > retSafe(sz);
@@ -313,8 +364,8 @@ void MEDMeshMultiLev::retrieveFamilyIdsOnNodes(DataArrayInt *& famIds, bool& isW
     }
   else
     {
-      isWithoutCopy=_node_fam_ids_nocpy;
       famIds=const_cast<DataArrayInt *>(fids); famIds->incrRef();
+      isWithoutCopy=_mesh->isObjectInTheProgeny(famIds);
     }
 }
 
@@ -335,8 +386,8 @@ void MEDMeshMultiLev::retrieveNumberIdsOnNodes(DataArrayInt *& numIds, bool& isW
     }
   else
     {
-      isWithoutCopy=_node_num_ids_nocpy;
       numIds=const_cast<DataArrayInt *>(fids); numIds->incrRef();
+      isWithoutCopy=_mesh->isObjectInTheProgeny(numIds);
     }
 }
 
@@ -345,36 +396,32 @@ std::vector< INTERP_KERNEL::NormalizedCellType > MEDMeshMultiLev::getGeoTypes()
   return _geo_types;
 }
 
-void MEDMeshMultiLev::setFamilyIdsOnCells(DataArrayInt *famIds, bool isNoCopy)
+void MEDMeshMultiLev::setFamilyIdsOnCells(DataArrayInt *famIds)
 {
   _cell_fam_ids=famIds;
   if(famIds)
     famIds->incrRef();
-  _cell_fam_ids_nocpy=isNoCopy;
 }
 
-void MEDMeshMultiLev::setNumberIdsOnCells(DataArrayInt *numIds, bool isNoCopy)
+void MEDMeshMultiLev::setNumberIdsOnCells(DataArrayInt *numIds)
 {
   _cell_num_ids=numIds;
   if(numIds)
     numIds->incrRef();
-  _cell_num_ids_nocpy=isNoCopy;
 }
 
-void MEDMeshMultiLev::setFamilyIdsOnNodes(DataArrayInt *famIds, bool isNoCopy)
+void MEDMeshMultiLev::setFamilyIdsOnNodes(DataArrayInt *famIds)
 {
   _node_fam_ids=famIds;
   if(famIds)
     famIds->incrRef();
-  _node_fam_ids_nocpy=isNoCopy;
 }
 
-void MEDMeshMultiLev::setNumberIdsOnNodes(DataArrayInt *numIds, bool isNoCopy)
+void MEDMeshMultiLev::setNumberIdsOnNodes(DataArrayInt *numIds)
 {
   _node_num_ids=numIds;
   if(numIds)
     numIds->incrRef();
-  _node_num_ids_nocpy=isNoCopy;
 }
 
 std::string MEDMeshMultiLev::getPflNameOfId(int id) const
@@ -397,7 +444,7 @@ int MEDMeshMultiLev::getNumberOfCells(INTERP_KERNEL::NormalizedCellType t) const
   std::size_t sz(_nb_entities.size());
   for(std::size_t i=0;i<sz;i++)
     if(_geo_types[i]==t)
-        return _nb_entities[i];
+      return _nb_entities[i];
   throw INTERP_KERNEL::Exception("MEDMeshMultiLev::getNumberOfCells : not existing geometric type in this !");
 }
 
@@ -418,7 +465,7 @@ DataArray *MEDMeshMultiLev::constructDataArray(const MEDFileField1TSStructItem&
       if(pflName.empty() && !nr)
         return vals->deepCpy();
       if(pflName.empty() && nr)
-         throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for nodes 2 !");
+        throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for nodes 2 !");
       if(!pflName.empty() && nr)
         {
           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p1(globs->getProfile(pflName.c_str())->deepCpy());
@@ -579,7 +626,6 @@ void MEDMeshMultiLev::appendVertices(const DataArrayInt *verticesToAdd, DataArra
         }
       a[1]=tmp;
       _cell_fam_ids=DataArrayInt::Aggregate(a);
-      _cell_fam_ids_nocpy=false;
     }
   if(cn)
     {
@@ -594,15 +640,14 @@ void MEDMeshMultiLev::appendVertices(const DataArrayInt *verticesToAdd, DataArra
         }
       a[1]=tmp;
       _cell_num_ids=DataArrayInt::Aggregate(a);
-      _cell_num_ids_nocpy=false;
     }
 }
 
-MEDMeshMultiLev::MEDMeshMultiLev():_nb_nodes(0),_cell_fam_ids_nocpy(false)
+MEDMeshMultiLev::MEDMeshMultiLev(const MEDFileMesh *mesh):_mesh(mesh),_nb_nodes(0)
 {
 }
 
-MEDMeshMultiLev::MEDMeshMultiLev(int nbNodes, const std::vector<INTERP_KERNEL::NormalizedCellType>& gts, const std::vector<const DataArrayInt *>& pfls, const std::vector<int>& nbEntities):_geo_types(gts),_nb_entities(nbEntities),_nb_nodes(nbNodes),_cell_fam_ids_nocpy(false),_cell_num_ids_nocpy(false),_node_fam_ids_nocpy(false),_node_num_ids_nocpy(false)
+MEDMeshMultiLev::MEDMeshMultiLev(const MEDFileMesh *mesh, int nbNodes, const std::vector<INTERP_KERNEL::NormalizedCellType>& gts, const std::vector<const DataArrayInt *>& pfls, const std::vector<int>& nbEntities):_mesh(mesh),_geo_types(gts),_nb_entities(nbEntities),_nb_nodes(nbNodes)
 {
   std::size_t sz(_geo_types.size());
   if(sz!=pfls.size() || sz!=nbEntities.size())
@@ -616,7 +661,7 @@ MEDMeshMultiLev::MEDMeshMultiLev(int nbNodes, const std::vector<INTERP_KERNEL::N
     }
 }
 
-MEDMeshMultiLev::MEDMeshMultiLev(const MEDMeshMultiLev& other):RefCountObject(other),_pfls(other._pfls),_geo_types(other._geo_types),_nb_entities(other._nb_entities),_node_reduction(other._node_reduction),_nb_nodes(other._nb_nodes),_cell_fam_ids(other._cell_fam_ids),_cell_fam_ids_nocpy(other._cell_fam_ids_nocpy),_cell_num_ids(other._cell_num_ids),_cell_num_ids_nocpy(other._cell_num_ids_nocpy),_node_fam_ids(other._node_fam_ids),_node_fam_ids_nocpy(other._node_fam_ids_nocpy),_node_num_ids(other._node_num_ids),_node_num_ids_nocpy(other._node_num_ids_nocpy)
+MEDMeshMultiLev::MEDMeshMultiLev(const MEDMeshMultiLev& other):RefCountObject(other),_mesh(other._mesh),_pfls(other._pfls),_geo_types(other._geo_types),_nb_entities(other._nb_entities),_node_reduction(other._node_reduction),_nb_nodes(other._nb_nodes),_cell_fam_ids(other._cell_fam_ids),_cell_num_ids(other._cell_num_ids),_node_fam_ids(other._node_fam_ids),_node_num_ids(other._node_num_ids)
 {
 }
 
@@ -627,7 +672,7 @@ MEDUMeshMultiLev *MEDUMeshMultiLev::New(const MEDFileUMesh *m, const std::vector
   return new MEDUMeshMultiLev(m,levs);
 }
 
-MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDFileUMesh *m, const std::vector<int>& levs)
+MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDFileUMesh *m, const std::vector<int>& levs):MEDMeshMultiLev(m)
 {
   if(!m)
     throw INTERP_KERNEL::Exception("MEDUMeshMultiLev constructor : null input pointer !");
@@ -658,8 +703,8 @@ MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDFileUMesh *m, const std::vector<int>
       _nb_entities[i]=obj->getNumberOfCells();
     }
   // ids fields management
-  _cell_fam_ids_nocpy=(levs.size()==1);
-  if(_cell_fam_ids_nocpy)
+  bool cellFamIdsNoCpy(levs.size()==1);
+  if(cellFamIdsNoCpy)
     {
       const DataArrayInt *tmp(m->getFamilyFieldAtLevel(levs[0]));
       if(tmp)
@@ -681,8 +726,8 @@ MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDFileUMesh *m, const std::vector<int>
       if(f && !tmps.empty())
         _cell_fam_ids=DataArrayInt::Aggregate(tmps);
     }
-  _cell_num_ids_nocpy=(levs.size()==1);
-  if(_cell_num_ids_nocpy)
+  bool cellNumIdsNoCpy(levs.size()==1);
+  if(cellNumIdsNoCpy)
     {
       const DataArrayInt *tmp(m->getNumberFieldAtLevel(levs[0]));
       if(tmp)
@@ -705,7 +750,6 @@ MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDFileUMesh *m, const std::vector<int>
         _cell_num_ids=DataArrayInt::Aggregate(tmps);
     }
   // node part
-  _node_fam_ids_nocpy=true;
   {
     const DataArrayInt *tmp(m->getFamilyFieldAtLevel(1));
     if(tmp)
@@ -714,7 +758,6 @@ MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDFileUMesh *m, const std::vector<int>
         _node_fam_ids=(const_cast<DataArrayInt *>(tmp));
       }
   }
-  _node_num_ids_nocpy=true;
   {
     const DataArrayInt *tmp(m->getNumberFieldAtLevel(1));
     if(tmp)
@@ -730,7 +773,7 @@ MEDUMeshMultiLev *MEDUMeshMultiLev::New(const MEDFileUMesh *m, const std::vector
   return new MEDUMeshMultiLev(m,gts,pfls,nbEntities);
 }
 
-MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDFileUMesh *m, const std::vector<INTERP_KERNEL::NormalizedCellType>& gts, const std::vector<const DataArrayInt *>& pfls, const std::vector<int>& nbEntities):MEDMeshMultiLev(m->getNumberOfNodes(),gts,pfls,nbEntities)
+MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDFileUMesh *m, const std::vector<INTERP_KERNEL::NormalizedCellType>& gts, const std::vector<const DataArrayInt *>& pfls, const std::vector<int>& nbEntities):MEDMeshMultiLev(m,m->getNumberOfNodes(),gts,pfls,nbEntities)
 {
   std::size_t sz(gts.size());
   if(sz<1)
@@ -753,26 +796,21 @@ MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDFileUMesh *m, const std::vector<INTE
   int lev((int)dim-m->getMeshDimension());
   if(isSameDim && isNoPfl && m->getGeoTypesAtLevel(lev)==gts)//optimized part
     {
-      _cell_fam_ids_nocpy=true;
       const DataArrayInt *famIds(m->getFamilyFieldAtLevel(lev));
       if(famIds)
         { _cell_fam_ids=const_cast<DataArrayInt*>(famIds); famIds->incrRef(); }
-      _cell_num_ids_nocpy=true;
       const DataArrayInt *numIds(m->getNumberFieldAtLevel(lev));
       if(numIds)
         { _cell_num_ids=const_cast<DataArrayInt*>(numIds); numIds->incrRef(); }
-      _node_fam_ids_nocpy=true;
       famIds=m->getFamilyFieldAtLevel(1);
       if(famIds)
         { _node_fam_ids=const_cast<DataArrayInt*>(famIds); famIds->incrRef(); }
-      _node_num_ids_nocpy=true;
       numIds=m->getNumberFieldAtLevel(1);
       if(numIds)
         { _node_num_ids=const_cast<DataArrayInt*>(numIds); numIds->incrRef(); }
       return ;
     }
   //
-  _cell_fam_ids_nocpy=false;
   std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > famIdsSafe(sz);
   std::vector<const DataArrayInt *> famIds(sz);
   bool f(true);
@@ -785,7 +823,6 @@ MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDFileUMesh *m, const std::vector<INTE
     }
   if(f)
     _cell_fam_ids=DataArrayInt::Aggregate(famIds);
-  _cell_num_ids_nocpy=false;
   std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > numIdsSafe(sz);
   std::vector<const DataArrayInt *> numIds(sz);
   bool n(true);
@@ -799,11 +836,9 @@ MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDFileUMesh *m, const std::vector<INTE
   if(n)
     _cell_num_ids=DataArrayInt::Aggregate(numIds);
   // node ids management
-  _node_fam_ids_nocpy=true;
   const DataArrayInt *nodeFamIds(m->getFamilyFieldAtLevel(1));
   if(nodeFamIds)
     { _node_fam_ids=const_cast<DataArrayInt*>(nodeFamIds); nodeFamIds->incrRef(); }
-  _node_num_ids_nocpy=true;
   const DataArrayInt *nodeNumIds(m->getNumberFieldAtLevel(1));
   if(nodeNumIds)
     { _node_num_ids=const_cast<DataArrayInt*>(nodeNumIds); nodeNumIds->incrRef(); }
@@ -811,44 +846,44 @@ MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDFileUMesh *m, const std::vector<INTE
 
 void MEDUMeshMultiLev::selectPartOfNodes(const DataArrayInt *pflNodes)
 {
-   if(!pflNodes || !pflNodes->isAllocated())
-     return ;
-   std::size_t sz(_parts.size());
-   std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > a(sz);
-   std::vector< const DataArrayInt *> aa(sz);
-   for(std::size_t i=0;i<sz;i++)
-     {
-       const DataArrayInt *pfl(_pfls[i]);
-       MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> m(_parts[i]);
-       if(pfl)
-         m=dynamic_cast<MEDCoupling1GTUMesh *>(_parts[i]->buildPartOfMySelfKeepCoords(pfl->begin(),pfl->end()));
-       DataArrayInt *cellIds=0;
-       m->fillCellIdsToKeepFromNodeIds(pflNodes->begin(),pflNodes->end(),true,cellIds);
-       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIdsSafe(cellIds);
-       MEDCouplingAutoRefCountObjectPtr<MEDCouplingPointSet> m2(m->buildPartOfMySelfKeepCoords(cellIds->begin(),cellIds->end()));
-       int tmp=-1;
-       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n(m2->getNodeIdsInUse(tmp));
-       a[i]=o2n->invertArrayO2N2N2O(tmp); aa[i]=a[i];
-       if(pfl)
-         _pfls[i]=pfl->selectByTupleIdSafe(cellIds->begin(),cellIds->end());
-       else
-         _pfls[i]=cellIdsSafe;
-     }
-   if(!aa.empty())
-     _node_reduction=DataArrayInt::Aggregate(aa);//general case
-   else
-     _node_reduction=pflNodes->deepCpy();//case where no cells in read mesh.
-   _node_reduction->sort(true);
-   _node_reduction=_node_reduction->buildUnique();
-   if(_node_reduction->getNumberOfTuples()==pflNodes->getNumberOfTuples())
-     return ;//This is the classical case where the input node profile corresponds perfectly to a subset of cells in _parts
-   if(_node_reduction->getNumberOfTuples()>pflNodes->getNumberOfTuples())
-     throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::selectPartOfNodes : internal error in MEDCoupling during cell select from a list of nodes !");
-   // Here the cells available in _parts is not enough to cover all the nodes in pflNodes. So adding vertices cells in _parts...
-   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> pflNodes2(pflNodes->deepCpy());
-   pflNodes2->sort(true);
-   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> diff(pflNodes2->buildSubstractionOptimized(_node_reduction));
-   appendVertices(diff,pflNodes2);
+  if(!pflNodes || !pflNodes->isAllocated())
+    return ;
+  std::size_t sz(_parts.size());
+  std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > a(sz);
+  std::vector< const DataArrayInt *> aa(sz);
+  for(std::size_t i=0;i<sz;i++)
+    {
+      const DataArrayInt *pfl(_pfls[i]);
+      MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> m(_parts[i]);
+      if(pfl)
+        m=dynamic_cast<MEDCoupling1GTUMesh *>(_parts[i]->buildPartOfMySelfKeepCoords(pfl->begin(),pfl->end()));
+      DataArrayInt *cellIds=0;
+      m->fillCellIdsToKeepFromNodeIds(pflNodes->begin(),pflNodes->end(),true,cellIds);
+      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIdsSafe(cellIds);
+      MEDCouplingAutoRefCountObjectPtr<MEDCouplingPointSet> m2(m->buildPartOfMySelfKeepCoords(cellIds->begin(),cellIds->end()));
+      int tmp=-1;
+      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n(m2->getNodeIdsInUse(tmp));
+      a[i]=o2n->invertArrayO2N2N2O(tmp); aa[i]=a[i];
+      if(pfl)
+        _pfls[i]=pfl->selectByTupleIdSafe(cellIds->begin(),cellIds->end());
+      else
+        _pfls[i]=cellIdsSafe;
+    }
+  if(!aa.empty())
+    _node_reduction=DataArrayInt::Aggregate(aa);//general case
+  else
+    _node_reduction=pflNodes->deepCpy();//case where no cells in read mesh.
+  _node_reduction->sort(true);
+  _node_reduction=_node_reduction->buildUnique();
+  if(_node_reduction->getNumberOfTuples()==pflNodes->getNumberOfTuples())
+    return ;//This is the classical case where the input node profile corresponds perfectly to a subset of cells in _parts
+  if(_node_reduction->getNumberOfTuples()>pflNodes->getNumberOfTuples())
+    throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::selectPartOfNodes : internal error in MEDCoupling during cell select from a list of nodes !");
+  // Here the cells available in _parts is not enough to cover all the nodes in pflNodes. So adding vertices cells in _parts...
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> pflNodes2(pflNodes->deepCpy());
+  pflNodes2->sort(true);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> diff(pflNodes2->buildSubstractionOptimized(_node_reduction));
+  appendVertices(diff,pflNodes2);
 }
 
 MEDMeshMultiLev *MEDUMeshMultiLev::prepare() const
@@ -870,6 +905,7 @@ MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDStructuredMeshMultiLev& other, const
 }
 
 /*! 
+ * To be called only once ! Because due to some optimizations (sometimes aggressive) the internal state can be changed...
  * If returned value is false output pointer \a coords is not the internal pointer. If returned value is true output pointer \a coords is directly the internal pointer.
  * If true is returned, the \a coords output parameter should be used with care (non const method call) to avoid to change the internal state of MEDFileUMesh instance.
  */
@@ -945,12 +981,25 @@ bool MEDUMeshMultiLev::buildVTUArrays(DataArrayDouble *& coords, DataArrayByte *
         throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::getVTUArrays : internal error !");
       if(scur)
         {
-          int nnpc(scur->getNumberOfNodesPerCell());
-          for(int i=0;i<curNbCells;i++,connPtr+=nnpc)
+          if(cur->getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA27)
             {
-              *dPtr++=nnpc;
-              dPtr=std::copy(connPtr,connPtr+nnpc,dPtr);
-              *cPtr++=k; k+=nnpc+1;
+              int nnpc(scur->getNumberOfNodesPerCell());
+              for(int i=0;i<curNbCells;i++,connPtr+=nnpc)
+                {
+                  *dPtr++=nnpc;
+                  dPtr=std::copy(connPtr,connPtr+nnpc,dPtr);
+                  *cPtr++=k; k+=nnpc+1;
+                }
+            }
+          else
+            {
+              for(int i=0;i<curNbCells;i++,connPtr+=27)
+                {
+                  *dPtr++=27;
+                  for(int j=0;j<27;j++,dPtr++)
+                    *dPtr=connPtr[HEXA27_PERM_ARRAY[j]];
+                  *cPtr++=k; k+=28;
+                }
             }
           if(isPolyh)
             { std::fill(ePtr,ePtr+curNbCells,-1); ePtr+=curNbCells; }
@@ -964,7 +1013,7 @@ bool MEDUMeshMultiLev::buildVTUArrays(DataArrayDouble *& coords, DataArrayByte *
                 {
                   *dPtr++=connIPtr[1]-connIPtr[0];
                   dPtr=std::copy(connPtr+connIPtr[0],connPtr+connIPtr[1],dPtr);
-                  *cPtr++=k; k+=connIPtr[1]-connIPtr[0];
+                  *cPtr++=k; k+=connIPtr[1]-connIPtr[0]+1;
                 }
             }
           else
@@ -1014,7 +1063,7 @@ bool MEDUMeshMultiLev::buildVTUArrays(DataArrayDouble *& coords, DataArrayByte *
     { faceLocations=0; faces=0; }
   else
     { faceLocations=e.retn(); faces=f.retn(); }
-  return tmp==((DataArrayDouble *)a);
+  return _mesh->isObjectInTheProgeny(coords);
 }
 
 void MEDUMeshMultiLev::reorderNodesIfNecessary(MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>& coords, DataArrayInt *nodalConnVTK, DataArrayInt *polyhedNodalConnVTK) const
@@ -1118,14 +1167,23 @@ void MEDUMeshMultiLev::appendVertices(const DataArrayInt *verticesToAdd, DataArr
 
 //=
 
-MEDStructuredMeshMultiLev::MEDStructuredMeshMultiLev():_is_internal(true)
+MEDStructuredMeshMultiLev::MEDStructuredMeshMultiLev(const MEDFileStructuredMesh *m, const std::vector<int>& lev):MEDMeshMultiLev(m),_is_internal(true)
+{
+  initStdFieldOfIntegers(m);
+}
+
+MEDStructuredMeshMultiLev::MEDStructuredMeshMultiLev(const MEDFileStructuredMesh *m, int nbOfNodes, const std::vector<INTERP_KERNEL::NormalizedCellType>& gts, const std::vector<const DataArrayInt *>& pfls, const std::vector<int>& nbEntities):MEDMeshMultiLev(m,nbOfNodes,gts,pfls,nbEntities),_is_internal(true)
+{
+  initStdFieldOfIntegers(m);
+}
+
+MEDStructuredMeshMultiLev::MEDStructuredMeshMultiLev(const MEDStructuredMeshMultiLev& other):MEDMeshMultiLev(other),_is_internal(true),_face_fam_ids(other._face_fam_ids),_face_num_ids(other._face_num_ids)
 {
 }
 
-MEDStructuredMeshMultiLev::MEDStructuredMeshMultiLev(const MEDFileStructuredMesh *m, const std::vector<int>& lev):_is_internal(true)
+void MEDStructuredMeshMultiLev::initStdFieldOfIntegers(const MEDFileStructuredMesh *m)
 {
   // ids fields management
-  _cell_fam_ids_nocpy=true; _cell_num_ids_nocpy=true;
   const DataArrayInt *tmp(0);
   tmp=m->getFamilyFieldAtLevel(0);
   if(tmp)
@@ -1140,7 +1198,6 @@ MEDStructuredMeshMultiLev::MEDStructuredMeshMultiLev(const MEDFileStructuredMesh
       _cell_num_ids=const_cast<DataArrayInt *>(tmp);
     }
   //
-  _node_fam_ids_nocpy=true; _node_num_ids_nocpy=true;
   tmp=0;
   tmp=m->getFamilyFieldAtLevel(1);
   if(tmp)
@@ -1154,46 +1211,71 @@ MEDStructuredMeshMultiLev::MEDStructuredMeshMultiLev(const MEDFileStructuredMesh
       tmp->incrRef();
       _node_num_ids=const_cast<DataArrayInt *>(tmp);
     }
-}
-
-MEDStructuredMeshMultiLev::MEDStructuredMeshMultiLev(const MEDFileStructuredMesh *m, int nbOfNodes, const std::vector<INTERP_KERNEL::NormalizedCellType>& gts, const std::vector<const DataArrayInt *>& pfls, const std::vector<int>& nbEntities):MEDMeshMultiLev(nbOfNodes,gts,pfls,nbEntities),_is_internal(true)
-{
-  // ids fields management
-  _cell_fam_ids_nocpy=true; _cell_num_ids_nocpy=true;
-  const DataArrayInt *tmp(0);
-  tmp=m->getFamilyFieldAtLevel(0);
+  // faces (if any)
+  tmp=m->getFamilyFieldAtLevel(-1);
   if(tmp)
     {
       tmp->incrRef();
-      _cell_fam_ids=const_cast<DataArrayInt *>(tmp);
+      _face_fam_ids=const_cast<DataArrayInt *>(tmp);
     }
-  tmp=m->getNumberFieldAtLevel(0);
+  tmp=m->getNumberFieldAtLevel(-1);
   if(tmp)
     {
       tmp->incrRef();
-      _cell_num_ids=const_cast<DataArrayInt *>(tmp);
+      _face_num_ids=const_cast<DataArrayInt *>(tmp);
     }
-  //
-  _node_fam_ids_nocpy=true; _node_num_ids_nocpy=true;
-  tmp=0;
-  tmp=m->getFamilyFieldAtLevel(1);
+}
+
+void MEDStructuredMeshMultiLev::moveFaceToCell() const
+{
+  const_cast<MEDStructuredMeshMultiLev *>(this)->_cell_fam_ids=_face_fam_ids; const_cast<MEDStructuredMeshMultiLev *>(this)->_face_fam_ids=0;
+  const_cast<MEDStructuredMeshMultiLev *>(this)->_cell_num_ids=_face_num_ids; const_cast<MEDStructuredMeshMultiLev *>(this)->_face_num_ids=0;
+}
+
+bool MEDStructuredMeshMultiLev::prepareForImplicitUnstructuredMeshCase(MEDMeshMultiLev *&ret) const
+{
+  ret=0;
+  if(_geo_types.empty())
+    return false;
+  if(_geo_types.size()!=1)
+    throw INTERP_KERNEL::Exception("MEDStructuredMeshMultiLev::prepareForImplicitUnstructuredMeshCase only one geo types supported at most supported for the moment !");
+  INTERP_KERNEL::NormalizedCellType gt(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(_mesh->getMeshDimension()));
+  if(_geo_types[0]==gt)
+    return false;
+  MEDCoupling1GTUMesh *facesIfPresent((static_cast<const MEDFileStructuredMesh *>(_mesh))->getImplicitFaceMesh());
+  if(!facesIfPresent)
+    return false;
+  const DataArrayInt *pfl(0),*nr(_node_reduction);
+  if(!_pfls.empty())
+    pfl=_pfls[0];
+  MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> facesIfPresent2(facesIfPresent); facesIfPresent->incrRef();
+  moveFaceToCell();
+  MEDCouplingAutoRefCountObjectPtr<MEDUMeshMultiLev> ret2(new MEDUMeshMultiLev(*this,facesIfPresent2));
+  if(pfl)
+    ret2->setCellReduction(pfl);
+  if(nr)
+    throw INTERP_KERNEL::Exception("MEDStructuredMeshMultiLev::prepareForImplicitUnstructuredMeshCase : case is not treated yet for node reduction on implicit unstructured mesh.");
+  ret=ret2.retn();
+  return true;
+}
+
+void MEDStructuredMeshMultiLev::dealWithImplicitUnstructuredMesh(const MEDFileMesh *m)
+{
+  const DataArrayInt *tmp(0);
+  tmp=m->getFamilyFieldAtLevel(-1);
   if(tmp)
     {
       tmp->incrRef();
-      _node_fam_ids=const_cast<DataArrayInt *>(tmp);
+      _cell_fam_ids=const_cast<DataArrayInt *>(tmp);
     }
-  tmp=m->getNumberFieldAtLevel(1);
+  tmp=m->getNumberFieldAtLevel(-1);
   if(tmp)
     {
       tmp->incrRef();
-      _node_num_ids=const_cast<DataArrayInt *>(tmp);
+      _cell_num_ids=const_cast<DataArrayInt *>(tmp);
     }
 }
 
-MEDStructuredMeshMultiLev::MEDStructuredMeshMultiLev(const MEDStructuredMeshMultiLev& other):MEDMeshMultiLev(other),_is_internal(true)
-{
-}
-
 void MEDStructuredMeshMultiLev::selectPartOfNodes(const DataArrayInt *pflNodes)
 {
   if(!pflNodes || !pflNodes->isAllocated())
@@ -1257,16 +1339,19 @@ MEDCMeshMultiLev::MEDCMeshMultiLev(const MEDFileCMesh *m, const std::vector<INTE
     throw INTERP_KERNEL::Exception("MEDCMeshMultiLev constructor 2 : lengthes of gts and pfls must be equal to one !");
   int mdim(m->getMeshDimension());
   INTERP_KERNEL::NormalizedCellType gt(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(mdim));
-  if(gt!=gts[0])
-    throw INTERP_KERNEL::Exception("MEDCMeshMultiLev constructor 2 : the unique geo type is invalid regarding meshdim !");
-  _coords.resize(mdim);
-  for(int i=0;i<mdim;i++)
+  if(gt==gts[0])
     {
-      DataArrayDouble *elt(const_cast<DataArrayDouble *>(m->getMesh()->getCoordsAt(i)));
-      if(!elt)
-        throw INTERP_KERNEL::Exception("MEDCMeshMultiLev constructor 2 : presence of null pointer for an vector of double along an axis !");
-      _coords[i]=elt; _coords[i]->incrRef();
+      _coords.resize(mdim);
+      for(int i=0;i<mdim;i++)
+        {
+          DataArrayDouble *elt(const_cast<DataArrayDouble *>(m->getMesh()->getCoordsAt(i)));
+          if(!elt)
+            throw INTERP_KERNEL::Exception("MEDCMeshMultiLev constructor 2 : presence of null pointer for an vector of double along an axis !");
+          _coords[i]=elt; _coords[i]->incrRef();
+        }
     }
+  else
+    dealWithImplicitUnstructuredMesh(m);
 }
 
 MEDCMeshMultiLev::MEDCMeshMultiLev(const MEDCMeshMultiLev& other):MEDStructuredMeshMultiLev(other),_coords(other._coords)
@@ -1283,6 +1368,9 @@ std::vector<int> MEDCMeshMultiLev::getNodeGridStructure() const
 
 MEDMeshMultiLev *MEDCMeshMultiLev::prepare() const
 {
+  MEDMeshMultiLev *retSpecific(0);
+  if(prepareForImplicitUnstructuredMeshCase(retSpecific))
+    return retSpecific;
   const DataArrayInt *pfl(0),*nr(_node_reduction);
   if(!_pfls.empty())
     pfl=_pfls[0];
@@ -1324,15 +1412,15 @@ MEDMeshMultiLev *MEDCMeshMultiLev::prepare() const
       if(famIds)
         {
           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp(famIds->selectByTupleIdSafe(pfl->begin(),pfl->end()));
-          ret2->setFamilyIdsOnCells(tmp,false);
+          ret2->setFamilyIdsOnCells(tmp);
         }
       if(numIds)
         {
           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp(numIds->selectByTupleIdSafe(pfl->begin(),pfl->end()));
-          ret2->setNumberIdsOnCells(tmp,false);
+          ret2->setNumberIdsOnCells(tmp);
         }
       return ret2.retn();
-      
+
     }
   else
     {
@@ -1391,15 +1479,18 @@ MEDCurveLinearMeshMultiLev::MEDCurveLinearMeshMultiLev(const MEDFileCurveLinearM
     throw INTERP_KERNEL::Exception("MEDCurveLinearMeshMultiLev constructor 2 : null input pointer !");
   if(gts.size()!=1 || pfls.size()!=1)
     throw INTERP_KERNEL::Exception("MEDCurveLinearMeshMultiLev constructor 2 : lengthes of gts and pfls must be equal to one !");
-  int mdim(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(m->getMeshDimension()));
-  if(mdim!=gts[0])
-    throw INTERP_KERNEL::Exception("MEDCurveLinearMeshMultiLev constructor 2 : the unique geo type is invalid regarding meshdim !");
-  DataArrayDouble *coords(const_cast<DataArrayDouble *>(m->getMesh()->getCoords()));
-  if(!coords)
-    throw INTERP_KERNEL::Exception("MEDCurveLinearMeshMultiLev constructor 2 : no coords set !");
-  coords->incrRef();
-  _coords=coords;
-  _structure=m->getMesh()->getNodeGridStructure();
+  INTERP_KERNEL::NormalizedCellType gt(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(m->getMeshDimension()));
+  if(gt==gts[0])
+    {
+      DataArrayDouble *coords(const_cast<DataArrayDouble *>(m->getMesh()->getCoords()));
+      if(!coords)
+        throw INTERP_KERNEL::Exception("MEDCurveLinearMeshMultiLev constructor 2 : no coords set !");
+      coords->incrRef();
+      _coords=coords;
+      _structure=m->getMesh()->getNodeGridStructure();
+    }
+  else
+    dealWithImplicitUnstructuredMesh(m);
 }
 
 MEDCurveLinearMeshMultiLev::MEDCurveLinearMeshMultiLev(const MEDCurveLinearMeshMultiLev& other):MEDStructuredMeshMultiLev(other),_coords(other._coords),_structure(other._structure)
@@ -1413,6 +1504,9 @@ std::vector<int> MEDCurveLinearMeshMultiLev::getNodeGridStructure() const
 
 MEDMeshMultiLev *MEDCurveLinearMeshMultiLev::prepare() const
 {
+  MEDMeshMultiLev *retSpecific(0);
+  if(prepareForImplicitUnstructuredMeshCase(retSpecific))
+    return retSpecific;
   const DataArrayInt *pfl(0),*nr(_node_reduction);
   if(!_pfls.empty())
     pfl=_pfls[0];
@@ -1459,12 +1553,12 @@ MEDMeshMultiLev *MEDCurveLinearMeshMultiLev::prepare() const
       if(famIds)
         {
           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp(famIds->selectByTupleIdSafe(pfl->begin(),pfl->end()));
-          ret2->setFamilyIdsOnCells(tmp,false);
+          ret2->setFamilyIdsOnCells(tmp);
         }
       if(numIds)
         {
           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp(numIds->selectByTupleIdSafe(pfl->begin(),pfl->end()));
-          ret2->setNumberIdsOnCells(tmp,false);
+          ret2->setNumberIdsOnCells(tmp);
         }
       return ret2.retn();
     }
@@ -1500,6 +1594,11 @@ MEDFileField1TSStructItem2::MEDFileField1TSStructItem2(INTERP_KERNEL::Normalized
 
 void MEDFileField1TSStructItem2::checkWithMeshStructForCells(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs)
 {
+  if(!mst->doesManageGeoType(_geo_type))
+    {
+      MEDFileMeshStruct *mstUnConstCasted(const_cast<MEDFileMeshStruct *>(mst));
+      mstUnConstCasted->appendIfImplicitType(_geo_type);
+    }
   int nbOfEnt=mst->getNumberOfElemsOfGeoType(_geo_type);
   checkInRange(nbOfEnt,1,globs);
 }
@@ -1566,7 +1665,7 @@ void MEDFileField1TSStructItem2::checkInRange(int nbOfEntity, int nip, const MED
   if(_pfl->getName().empty())
     {
       if(nbOfEntity!=(_start_end.second-_start_end.first)/nip)
-        throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::checkInRange : Mismatch between number of entities and size of node field !");
+        throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::checkInRange : Mismatch between number of entities and size of field !");
       return ;
     }
   else
@@ -1592,7 +1691,7 @@ bool MEDFileField1TSStructItem2::isFastlyEqual(int& startExp, INTERP_KERNEL::Nor
   return true;
 }
 
-bool MEDFileField1TSStructItem2::operator==(const MEDFileField1TSStructItem2& other) const throw(INTERP_KERNEL::Exception)
+bool MEDFileField1TSStructItem2::operator==(const MEDFileField1TSStructItem2& other) const
 {
   //_nb_of_entity is not taken into account here. It is not a bug, because no mesh consideration needed here to perform fast compare.
   //idem for _loc. It is not an effective attribute for support comparison.
@@ -1674,12 +1773,10 @@ std::size_t MEDFileField1TSStructItem2::getHeapMemorySizeWithoutChildren() const
   return ret;
 }
 
-std::vector<const BigMemoryObject *> MEDFileField1TSStructItem2::getDirectChildren() const
+std::vector<const BigMemoryObject *> MEDFileField1TSStructItem2::getDirectChildrenWithNull() const
 {
   std::vector<const BigMemoryObject *> ret;
-  const DataArrayInt *pfl(_pfl);
-  if(pfl)
-    ret.push_back(pfl);
+  ret.push_back((const DataArrayInt *)_pfl);
   return ret;
 }
 
@@ -1692,7 +1789,7 @@ MEDFileField1TSStructItem::MEDFileField1TSStructItem(TypeOfField a, const std::v
 void MEDFileField1TSStructItem::checkWithMeshStruct(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs)
 {
   switch(_type)
-    {
+  {
     case ON_NODES:
       {
         int nbOfEnt=mst->getNumberOfNodes();
@@ -1721,10 +1818,10 @@ void MEDFileField1TSStructItem::checkWithMeshStruct(const MEDFileMeshStruct *mst
       }
     default:
       throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::checkWithMeshStruct : not managed field type !");
-    }
+  }
 }
 
-bool MEDFileField1TSStructItem::operator==(const MEDFileField1TSStructItem& other) const throw(INTERP_KERNEL::Exception)
+bool MEDFileField1TSStructItem::operator==(const MEDFileField1TSStructItem& other) const
 {
   if(_type!=other._type)
     return false;
@@ -1877,7 +1974,7 @@ bool MEDFileField1TSStructItem::isFullyOnOneLev(const MEDFileMeshStruct *meshSt,
   return false;
 }
 
-const MEDFileField1TSStructItem2& MEDFileField1TSStructItem::operator[](std::size_t i) const throw(INTERP_KERNEL::Exception)
+const MEDFileField1TSStructItem2& MEDFileField1TSStructItem::operator[](std::size_t i) const
 {
   if(i>=_items.size())
     throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::operator[] : input is not in valid range !");
@@ -1890,7 +1987,7 @@ std::size_t MEDFileField1TSStructItem::getHeapMemorySizeWithoutChildren() const
   return ret;
 }
 
-std::vector<const BigMemoryObject *> MEDFileField1TSStructItem::getDirectChildren() const
+std::vector<const BigMemoryObject *> MEDFileField1TSStructItem::getDirectChildrenWithNull() const
 {
   std::vector<const BigMemoryObject *> ret;
   for(std::vector< MEDFileField1TSStructItem2 >::const_iterator it=_items.begin();it!=_items.end();it++)
@@ -1941,7 +2038,6 @@ std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileField1TSStructItem::getGeo
 
 MEDFileField1TSStructItem MEDFileField1TSStructItem::BuildItemFrom(const MEDFileAnyTypeField1TS *ref, const MEDFileMeshStruct *meshSt)
 {
-  TypeOfField atype;
   std::vector< MEDFileField1TSStructItem2 > anItems;
   //
   std::vector< std::vector<std::string> > pfls,locs;
@@ -1951,17 +2047,15 @@ MEDFileField1TSStructItem MEDFileField1TSStructItem::BuildItemFrom(const MEDFile
   std::size_t nbOfGeoTypes(geoTypes.size());
   if(nbOfGeoTypes==0)
     throw INTERP_KERNEL::Exception("MEDFileField1TSStruct : not null by empty ref  !");
-  bool isFirst=true;
+  if(typesF[0].empty())
+    throw INTERP_KERNEL::Exception("MEDFileField1TSStruct : internal error #1 bis !");
+  TypeOfField atype(typesF[0][0]);
   for(std::size_t i=0;i<nbOfGeoTypes;i++)
     {
       std::size_t sz=typesF[i].size();
       if(strtEnds[i].size()<1 || sz<1 || pfls[i].size()<1)
         throw INTERP_KERNEL::Exception("MEDFileField1TSStruct : internal error #1 !");
       //
-      if(isFirst)
-        atype=typesF[i][0];
-      isFirst=false;
-      //
       for(std::size_t j=0;j<sz;j++)
         {
           if(atype==typesF[i][j])
@@ -1971,7 +2065,15 @@ MEDFileField1TSStructItem MEDFileField1TSStructItem::BuildItemFrom(const MEDFile
         }
     }
   MEDFileField1TSStructItem ret(atype,anItems);
-  ret.checkWithMeshStruct(meshSt,ref);
+  try
+    {
+      ret.checkWithMeshStruct(meshSt,ref);
+    }
+  catch(INTERP_KERNEL::Exception& e)
+    {
+      std::ostringstream oss; oss << e.what() << " (" << MEDCouplingFieldDiscretization::GetTypeOfFieldRepr(ret.getType()) << ")";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
   return ret;
 }
 
@@ -2073,7 +2175,7 @@ std::size_t MEDFileField1TSStruct::getHeapMemorySizeWithoutChildren() const
   return ret;
 }
 
-std::vector<const BigMemoryObject *> MEDFileField1TSStruct::getDirectChildren() const
+std::vector<const BigMemoryObject *> MEDFileField1TSStruct::getDirectChildrenWithNull() const
 {
   std::vector<const BigMemoryObject *> ret;
   for(std::vector<MEDFileField1TSStructItem>::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++)
@@ -2204,8 +2306,17 @@ MEDFileFastCellSupportComparator::MEDFileFastCellSupportComparator(const MEDFile
   for(int i=0;i<nbPts;i++)
     {
       MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TS> elt=ref->getTimeStepAtPos(i);
-      _f1ts_cmps[i]=MEDFileField1TSStruct::New(elt,_mesh_comp);
-      _f1ts_cmps[i]->checkWithMeshStruct(_mesh_comp,elt);
+      try
+        {
+          _f1ts_cmps[i]=MEDFileField1TSStruct::New(elt,_mesh_comp);
+          _f1ts_cmps[i]->checkWithMeshStruct(_mesh_comp,elt);
+        }
+      catch(INTERP_KERNEL::Exception& e)
+        {
+          std::ostringstream oss; oss << "Problem in field with name \"" << ref->getName() << "\"" << std::endl;
+          oss << "More Details : " << e.what();
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
     }
 }
 
@@ -2215,18 +2326,14 @@ std::size_t MEDFileFastCellSupportComparator::getHeapMemorySizeWithoutChildren()
   return ret;
 }
 
-std::vector<const BigMemoryObject *> MEDFileFastCellSupportComparator::getDirectChildren() const
+std::vector<const BigMemoryObject *> MEDFileFastCellSupportComparator::getDirectChildrenWithNull() const
 {
   std::vector<const BigMemoryObject *> ret;
   const MEDFileMeshStruct *mst(_mesh_comp);
   if(mst)
     ret.push_back(mst);
   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileField1TSStruct> >::const_iterator it=_f1ts_cmps.begin();it!=_f1ts_cmps.end();it++)
-    {
-      const MEDFileField1TSStruct *cur(*it);
-      if(cur)
-        ret.push_back(cur);
-    }
+    ret.push_back((const MEDFileField1TSStruct *)*it);
   return ret;
 }