Salome HOME
Improve message in case of throw for end user.
[tools/medcoupling.git] / src / MEDLoader / MEDFileField.cxx
index 4c082e21fafee6122636ba411146996bebf97233..173bbcd52d64481de2962e709147594848eb80d7 100644 (file)
@@ -475,13 +475,14 @@ void MEDFileFieldPerMeshPerTypePerDisc::goReadZeValuesInFile(med_idt fid, const
     {
       if(!_profile.empty())
         throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::goReadZeValuesInFile : not implemented !");
+      INTERP_KERNEL::AutoPtr<char> pflname(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE)),locname(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE));
+      int profilesize,nbi;
+      int overallNval(MEDfieldnValueWithProfile(fid,fieldName.c_str(),iteration,order,menti,mgeoti,_profile_it+1,MED_COMPACT_PFLMODE,pflname,&profilesize,locname,&nbi));
       const SlicePartDefinition *spd(dynamic_cast<const SlicePartDefinition *>(pd));
       if(spd)
         {
-          int profilesize,nbi,start,stop,step;
+          int start,stop,step;
           spd->getSlice(start,stop,step);
-          INTERP_KERNEL::AutoPtr<char> pflname(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE)),locname(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE));
-          int overallNval(MEDfieldnValueWithProfile(fid,fieldName.c_str(),iteration,order,menti,mgeoti,_profile_it+1,MED_COMPACT_PFLMODE,pflname,&profilesize,locname,&nbi));
           int nbOfEltsToLoad(DataArray::GetNumberOfItemGivenBES(start,stop,step,"MEDFileFieldPerMeshPerTypePerDisc::goReadZeValuesInFile"));
           med_filter filter=MED_FILTER_INIT;
           MEDfilterBlockOfEntityCr(fid,/*nentity*/overallNval,/*nvaluesperentity*/nbi,/*nconstituentpervalue*/nbOfCompo,
@@ -492,6 +493,29 @@ void MEDFileFieldPerMeshPerTypePerDisc::goReadZeValuesInFile(med_idt fid, const
           MEDfilterClose(&filter);
           return ;
         }
+      const DataArrayPartDefinition *dpd(dynamic_cast<const DataArrayPartDefinition *>(pd));
+      if(dpd)
+        {
+          dpd->checkCoherency();
+          MEDCouplingAutoRefCountObjectPtr<DataArrayInt> myIds(dpd->toDAI());
+          int a(myIds->getMinValueInArray()),b(myIds->getMaxValueInArray());
+          myIds->applyLin(1,-a);
+          int nbOfEltsToLoad(b-a+1);
+          med_filter filter=MED_FILTER_INIT;
+          {//TODO : manage int32 !
+            MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> tmp(DataArrayDouble::New());
+            tmp->alloc(nbOfEltsToLoad,nbOfCompo);
+            MEDfilterBlockOfEntityCr(fid,/*nentity*/overallNval,/*nvaluesperentity*/nbi,/*nconstituentpervalue*/nbOfCompo,
+                                     MED_ALL_CONSTITUENT,MED_FULL_INTERLACE,MED_COMPACT_STMODE,MED_NO_PROFILE,
+                                     /*start*/a+1,/*stride*/1,/*count*/1,/*blocksize*/nbOfEltsToLoad,
+                                     /*lastblocksize=useless because count=1*/0,&filter);
+            MEDfieldValueAdvancedRd(fid,fieldName.c_str(),iteration,order,menti,mgeoti,&filter,reinterpret_cast<unsigned char *>(tmp->getPointer()));
+            MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> feeder(DataArrayDouble::New());
+            feeder->useExternalArrayWithRWAccess(reinterpret_cast<double *>(startFeedingPtr),_nval,nbOfCompo);
+            feeder->setContigPartOfSelectedValues(0,tmp,myIds);
+          }
+          MEDfilterClose(&filter);
+        }
       else
         throw INTERP_KERNEL::Exception("Not implemented yet for not slices!");
     }
@@ -523,14 +547,9 @@ void MEDFileFieldPerMeshPerTypePerDisc::loadOnlyStructureOfDataRecursively(med_i
     }
   else
     {
-      const SlicePartDefinition *spd(dynamic_cast<const SlicePartDefinition *>(pd));
-      if(!spd)
-        throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::loadOnlyStructureOfDataRecursively : Part def only implemented for split one !");
       if(!_profile.empty())
         throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::loadOnlyStructureOfDataRecursively : profiles are not managed yet with part of def !");
-      int start1,stop1,step1;
-      spd->getSlice(start1,stop1,step1);
-      _nval=DataArray::GetNumberOfItemGivenBES(start1,stop1,step1,"MEDFileFieldPerMeshPerTypePerDisc::loadOnlyStructureOfDataRecursively");
+      _nval=pd->getNumberOfElems();
     }
   _start=start;
   _end=start+_nval*nbi;
@@ -1337,6 +1356,18 @@ int MEDFileFieldPerMeshPerType::getNumberOfComponents() const
   return _father->getNumberOfComponents();
 }
 
+bool MEDFileFieldPerMeshPerType::presenceOfMultiDiscPerGeoType() const
+{
+  std::size_t nb(0);
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileFieldPerMeshPerTypePerDisc> >::const_iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++)
+    {
+      const MEDFileFieldPerMeshPerTypePerDisc *fmtd(*it);
+      if(fmtd)
+        nb++;
+    }
+  return nb>1;
+}
+
 DataArray *MEDFileFieldPerMeshPerType::getOrCreateAndGetArray()
 {
   return _father->getOrCreateAndGetArray();
@@ -1493,7 +1524,7 @@ void MEDFileFieldPerMeshPerType::setLeaves(const std::vector< MEDCouplingAutoRef
  */
 bool MEDFileFieldPerMeshPerType::keepOnlySpatialDiscretization(TypeOfField tof, int &globalNum, std::vector< std::pair<int,int> >& its)
 {
-  bool ret=false;
+  bool ret(false);
   std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileFieldPerMeshPerTypePerDisc> > newPmPtPd;
   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileFieldPerMeshPerTypePerDisc> >::iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++)
     if((*it)->getType()==tof)
@@ -1510,6 +1541,25 @@ bool MEDFileFieldPerMeshPerType::keepOnlySpatialDiscretization(TypeOfField tof,
   return ret;
 }
 
+/*!
+ *  \param [in,out] globalNum a global numbering counter for the renumbering.
+ *  \param [out] its - list of pair (start,stop) kept
+ *  \return bool - false if the type of field \a tof is not contained in \a this.
+ */
+bool MEDFileFieldPerMeshPerType::keepOnlyGaussDiscretization(std::size_t idOfDisc, int &globalNum, std::vector< std::pair<int,int> >& its)
+{
+  if(_field_pm_pt_pd.size()<=idOfDisc)
+    return false;
+  MEDCouplingAutoRefCountObjectPtr<MEDFileFieldPerMeshPerTypePerDisc> elt(_field_pm_pt_pd[idOfDisc]);
+  std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileFieldPerMeshPerTypePerDisc> > newPmPtPd(1,elt);
+  std::pair<int,int> bgEnd; bgEnd.first=_field_pm_pt_pd[idOfDisc]->getStart(); bgEnd.second=_field_pm_pt_pd[idOfDisc]->getEnd();
+  elt->setNewStart(globalNum);
+  globalNum=elt->getEnd();
+  its.push_back(bgEnd);
+  _field_pm_pt_pd=newPmPtPd;
+  return true;
+}
+
 MEDFileFieldPerMeshPerType::MEDFileFieldPerMeshPerType(MEDFileFieldPerMesh *fath, INTERP_KERNEL::NormalizedCellType geoType):_father(fath),_geo_type(geoType)
 {
 }
@@ -1761,6 +1811,19 @@ int MEDFileFieldPerMesh::getNumberOfComponents() const
   return _father->getNumberOfComponents();
 }
 
+bool MEDFileFieldPerMesh::presenceOfMultiDiscPerGeoType() const
+{
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++)
+    {
+      const MEDFileFieldPerMeshPerType *fpmt(*it);
+      if(!fpmt)
+        continue;
+      if(fpmt->presenceOfMultiDiscPerGeoType())
+        return true;
+    }
+  return false;
+}
+
 DataArray *MEDFileFieldPerMesh::getOrCreateAndGetArray()
 {
   if(!_father)
@@ -2048,6 +2111,25 @@ void MEDFileFieldPerMesh::keepOnlySpatialDiscretization(TypeOfField tof, int &gl
   _field_pm_pt=ret;
 }
 
+/*!
+ * \param [in,out] globalNum a global numbering counter for the renumbering.
+ * \param [out] its - list of pair (start,stop) kept
+ */
+void MEDFileFieldPerMesh::keepOnlyGaussDiscretization(std::size_t idOfDisc, int &globalNum, std::vector< std::pair<int,int> >& its)
+{
+  std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > > ret;
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++)
+    {
+      std::vector< std::pair<int,int> > its2;
+      if((*it)->keepOnlyGaussDiscretization(idOfDisc,globalNum,its2))
+        {
+          ret.push_back(*it);
+          its.insert(its.end(),its2.begin(),its2.end());
+        }
+    }
+  _field_pm_pt=ret;
+}
+
 void MEDFileFieldPerMesh::assignNewLeaves(const std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerTypePerDisc > >& leaves)
 {
   std::map<INTERP_KERNEL::NormalizedCellType,std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerTypePerDisc> > > types;
@@ -4127,12 +4209,18 @@ bool MEDFileAnyTypeField1TSWithoutSDA::renumberEntitiesLyingOnMesh(const std::st
   return ret;
 }
 
+/*!
+ * This method splits \a this into several sub-parts so that each sub parts have exactly one spatial discretization. This method implements the minimal
+ * splitting that leads to single spatial discretization of this.
+ *
+ * \sa splitMultiDiscrPerGeoTypes
+ */
 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> > MEDFileAnyTypeField1TSWithoutSDA::splitDiscretizations() const
 {
   std::vector<INTERP_KERNEL::NormalizedCellType> types;
   std::vector< std::vector<TypeOfField> > typesF;
   std::vector< std::vector<std::string> > pfls,locs;
-  std::vector< std::vector<std::pair<int,int> > > bgEnd=getFieldSplitedByType(getMeshName().c_str(),types,typesF,pfls,locs);
+  std::vector< std::vector<std::pair<int,int> > > bgEnd(getFieldSplitedByType(getMeshName().c_str(),types,typesF,pfls,locs));
   std::set<TypeOfField> allEnt;
   for(std::vector< std::vector<TypeOfField> >::const_iterator it1=typesF.begin();it1!=typesF.end();it1++)
     for(std::vector<TypeOfField>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
@@ -4143,7 +4231,48 @@ std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA>
     {
       std::vector< std::pair<int,int> > its;
       ret[i]=shallowCpy();
-      int newLgth=ret[i]->keepOnlySpatialDiscretization(*it3,its);
+      int newLgth(ret[i]->keepOnlySpatialDiscretization(*it3,its));
+      ret[i]->updateData(newLgth,its);
+    }
+  return ret;
+}
+
+/*!
+ * This method performs a sub splitting as splitDiscretizations does but finer. This is the finest spliting level that can be done.
+ * This method implements the minimal splitting so that each returned elements are mono Gauss discretization per geometric type.
+ *
+ * \sa splitDiscretizations
+ */
+std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> > MEDFileAnyTypeField1TSWithoutSDA::splitMultiDiscrPerGeoTypes() const
+{
+  std::vector<INTERP_KERNEL::NormalizedCellType> types;
+  std::vector< std::vector<TypeOfField> > typesF;
+  std::vector< std::vector<std::string> > pfls,locs;
+  std::vector< std::vector<std::pair<int,int> > > bgEnd(getFieldSplitedByType(getMeshName().c_str(),types,typesF,pfls,locs));
+  std::set<TypeOfField> allEnt;
+  std::size_t nbOfMDPGT(0),ii(0);
+  for(std::vector< std::vector<TypeOfField> >::const_iterator it1=typesF.begin();it1!=typesF.end();it1++,ii++)
+    {
+      nbOfMDPGT=std::max(nbOfMDPGT,locs[ii].size());
+      for(std::vector<TypeOfField>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
+        allEnt.insert(*it2);
+    }
+       if(allEnt.size()!=1)
+         throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::splitMultiDiscrPerGeoTypes : this field is expected to be defined only on one spatial discretization !");
+       if(nbOfMDPGT==0)
+         throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::splitMultiDiscrPerGeoTypes : empty field !");
+  if(nbOfMDPGT==1)
+    {
+      std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> > ret0(1);
+      ret0[0]=const_cast<MEDFileAnyTypeField1TSWithoutSDA *>(this); this->incrRef();
+      return ret0;
+    }
+  std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> > ret(nbOfMDPGT);
+  for(std::size_t i=0;i<nbOfMDPGT;i++)
+    {
+      std::vector< std::pair<int,int> > its;
+      ret[i]=shallowCpy();
+      int newLgth(ret[i]->keepOnlyGaussDiscretization(i,its));
       ret[i]->updateData(newLgth,its);
     }
   return ret;
@@ -4151,12 +4280,20 @@ std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA>
 
 int MEDFileAnyTypeField1TSWithoutSDA::keepOnlySpatialDiscretization(TypeOfField tof, std::vector< std::pair<int,int> >& its)
 {
-  int globalCounter=0;
+  int globalCounter(0);
   for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++)
     (*it)->keepOnlySpatialDiscretization(tof,globalCounter,its);
   return globalCounter;
 }
 
+int MEDFileAnyTypeField1TSWithoutSDA::keepOnlyGaussDiscretization(std::size_t idOfDisc, std::vector< std::pair<int,int> >& its)
+{
+  int globalCounter(0);
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++)
+    (*it)->keepOnlyGaussDiscretization(idOfDisc,globalCounter,its);
+  return globalCounter;
+}
+
 void MEDFileAnyTypeField1TSWithoutSDA::updateData(int newLgth, const std::vector< std::pair<int,int> >& oldStartStops)
 {
   if(_nb_of_tuples_to_be_allocated>=0)
@@ -4501,6 +4638,19 @@ std::vector<std::string>& MEDFileAnyTypeField1TSWithoutSDA::getInfo()
   return arr->getInfoOnComponents();
 }
 
+bool MEDFileAnyTypeField1TSWithoutSDA::presenceOfMultiDiscPerGeoType() const
+{
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++)
+    {
+      const MEDFileFieldPerMesh *fpm(*it);
+      if(!fpm)
+        continue;
+      if(fpm->presenceOfMultiDiscPerGeoType())
+        return true;
+    }
+  return false;
+}
+
 /*!
  * Returns a new MEDCouplingFieldDouble of given type lying on a given support.
  *  \param [in] type - a spatial discretization of the new field.
@@ -5864,6 +6014,11 @@ std::vector<std::string>& MEDFileAnyTypeField1TS::getInfo()
   return contentNotNullBase()->getInfo();
 }
 
+bool MEDFileAnyTypeField1TS::presenceOfMultiDiscPerGeoType() const
+{
+  return contentNotNullBase()->presenceOfMultiDiscPerGeoType();
+}
+
 MEDFileFieldPerMeshPerTypePerDisc *MEDFileAnyTypeField1TS::getLeafGivenMeshAndTypeAndLocId(const std::string& mName, INTERP_KERNEL::NormalizedCellType typ, int locId)
 {
   return contentNotNullBase()->getLeafGivenMeshAndTypeAndLocId(mName,typ,locId);
@@ -5913,14 +6068,34 @@ std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > MEDFil
 
 /*!
  * This method returns as MEDFileAnyTypeField1TS new instances as number of spatial discretizations in \a this.
- * The returned instances are deep copy of \a this except that for globals that are share with those contained in \a this.
+ * The returned instances are shallowed copied of \a this except that for globals that are share with those contained in \a this.
  */
 std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > MEDFileAnyTypeField1TS::splitDiscretizations() const
 {
   const MEDFileAnyTypeField1TSWithoutSDA *content(_content);
   if(!content)
     throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TS::splitDiscretizations : no content in this ! Unable to split discretization !");
-  std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> > contentsSplit=content->splitDiscretizations();
+  std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> > contentsSplit(content->splitDiscretizations());
+  std::size_t sz(contentsSplit.size());
+  std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > ret(sz);
+  for(std::size_t i=0;i<sz;i++)
+    {
+      ret[i]=shallowCpy();
+      ret[i]->_content=contentsSplit[i];
+    }
+  return ret;
+}
+
+/*!
+ * This method returns as MEDFileAnyTypeField1TS new instances as number of maximal number of discretization in \a this.
+ * The returned instances are shallowed copied of \a this except that for globals that are share with those contained in \a this.
+ */
+std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > MEDFileAnyTypeField1TS::splitMultiDiscrPerGeoTypes() const
+{
+  const MEDFileAnyTypeField1TSWithoutSDA *content(_content);
+  if(!content)
+    throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TS::splitMultiDiscrPerGeoTypes : no content in this ! Unable to split discretization !");
+  std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> > contentsSplit(content->splitMultiDiscrPerGeoTypes());
   std::size_t sz(contentsSplit.size());
   std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > ret(sz);
   for(std::size_t i=0;i<sz;i++)
@@ -6903,6 +7078,19 @@ MEDFileAnyTypeFieldMultiTSWithoutSDA *MEDFileAnyTypeFieldMultiTSWithoutSDA::part
   return buildFromTimeStepIds(ids->begin(),ids->end());
 }
 
+bool MEDFileAnyTypeFieldMultiTSWithoutSDA::presenceOfMultiDiscPerGeoType() const
+{
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++)
+    {
+      const MEDFileAnyTypeField1TSWithoutSDA *cur(*it);
+      if(!cur)
+        continue;
+      if(cur->presenceOfMultiDiscPerGeoType())
+        return true;
+    }
+  return false;
+}
+
 const std::vector<std::string>& MEDFileAnyTypeFieldMultiTSWithoutSDA::getInfo() const
 {
   return _infos;
@@ -7507,7 +7695,7 @@ std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutS
       }
   for(std::size_t i=0;i<types.size();i++)
     {
-      MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA> elt=createNew();
+      MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA> elt(createNew());
       for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> >::iterator it1=ret2[i].begin();it1!=ret2[i].end();it1++)
         elt->pushBackTimeStep(*it1);//also updates infos in elt
       ret[i]=elt;
@@ -7516,6 +7704,43 @@ std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutS
   return ret;
 }
 
+/*!
+ * Contrary to splitDiscretizations method this method makes the hypothesis that the times series are **NOT** impacted by the splitting of multi discretization.
+ */
+std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA> > MEDFileAnyTypeFieldMultiTSWithoutSDA::splitMultiDiscrPerGeoTypes() const
+{
+  std::size_t sz(_time_steps.size());
+  std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> > > items(sz);
+  std::size_t szOut(std::numeric_limits<std::size_t>::max());
+  for(std::size_t i=0;i<sz;i++)
+    {
+      const MEDFileAnyTypeField1TSWithoutSDA *timeStep(_time_steps[i]);
+      if(!timeStep)
+        {
+          std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTSWithoutSDA::splitMultiDiscrPerGeoTypes : time step #" << i << " is null !";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
+      items[i]=timeStep->splitMultiDiscrPerGeoTypes();
+      if(szOut==std::numeric_limits<std::size_t>::max())
+        szOut=items[i].size();
+      else
+        if(items[i].size()!=szOut)
+          throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTSWithoutSDA::splitMultiDiscrPerGeoTypes : The splitting per discretization is expected to be same among time steps !");
+    }
+  if(szOut==std::numeric_limits<std::size_t>::max())
+    throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTSWithoutSDA::splitMultiDiscrPerGeoTypes : empty field !");
+  std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA> > ret(szOut);
+  for(std::size_t i=0;i<szOut;i++)
+    {
+      MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA> elt(createNew());
+      for(std::size_t j=0;j<sz;j++)
+        elt->pushBackTimeStep(items[j][i]);
+      ret[i]=elt;
+      elt->MEDFileFieldNameScope::operator=(*this);
+    }
+  return ret;
+}
+
 void MEDFileAnyTypeFieldMultiTSWithoutSDA::copyTinyInfoFrom(const MEDCouplingFieldDouble *field, const DataArray *arr)
 {
   _name=field->getName();
@@ -8160,6 +8385,11 @@ const std::vector<std::string>& MEDFileAnyTypeFieldMultiTS::getInfo() const
   return contentNotNullBase()->getInfo();
 }
 
+bool MEDFileAnyTypeFieldMultiTS::presenceOfMultiDiscPerGeoType() const
+{
+  return contentNotNullBase()->presenceOfMultiDiscPerGeoType();
+}
+
 void MEDFileAnyTypeFieldMultiTS::setInfo(const std::vector<std::string>& info)
 {
   return contentNotNullBase()->setInfo(info);
@@ -8294,14 +8524,34 @@ std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > ME
 
 /*!
  * This method returns as MEDFileAnyTypeFieldMultiTS new instances as number of discretizations over time steps in \a this.
- * The returned instances are deep copy of \a this except that for globals that are share with those contained in \a this.
+ * The returned instances are shallow copied of \a this included globals that are share with those contained in \a this.
  */
 std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > MEDFileAnyTypeFieldMultiTS::splitDiscretizations() const
 {
   const MEDFileAnyTypeFieldMultiTSWithoutSDA *content(_content);
   if(!content)
     throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::splitDiscretizations : no content in this ! Unable to split discretizations !");
-  std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA> > contentsSplit=content->splitDiscretizations();
+  std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA> > contentsSplit(content->splitDiscretizations());
+  std::size_t sz(contentsSplit.size());
+  std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > ret(sz);
+  for(std::size_t i=0;i<sz;i++)
+    {
+      ret[i]=shallowCpy();
+      ret[i]->_content=contentsSplit[i];
+    }
+  return ret;
+}
+
+/*!
+ * This method returns as MEDFileAnyTypeFieldMultiTS new instances as number of sub-discretizations over time steps in \a this.
+ * The returned instances are shallow copied of \a this included globals that are share with those contained in \a this.
+ */
+std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > MEDFileAnyTypeFieldMultiTS::splitMultiDiscrPerGeoTypes() const
+{
+  const MEDFileAnyTypeFieldMultiTSWithoutSDA *content(_content);
+  if(!content)
+    throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::splitMultiDiscrPerGeoTypes : no content in this ! Unable to split discretizations !");
+  std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA> > contentsSplit(content->splitMultiDiscrPerGeoTypes());
   std::size_t sz(contentsSplit.size());
   std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > ret(sz);
   for(std::size_t i=0;i<sz;i++)