Salome HOME
Pickelization of MEDFileUMesh objects.
authorAnthony Geay <anthony.geay@edf.fr>
Wed, 25 Mar 2015 17:53:41 +0000 (18:53 +0100)
committerAnthony Geay <anthony.geay@edf.fr>
Wed, 25 Mar 2015 17:53:41 +0000 (18:53 +0100)
13 files changed:
src/MEDCalculator/Swig/MEDCalculator.i
src/MEDCoupling/MEDCouplingPartDefinition.cxx
src/MEDCoupling/MEDCouplingPartDefinition.hxx
src/MEDCoupling_Swig/CMakeLists.txt
src/MEDCoupling_Swig/MEDCouplingBasicsTest.py
src/MEDCoupling_Swig/MEDCouplingCommon.i
src/MEDLoader/MEDFileMesh.cxx
src/MEDLoader/MEDFileMesh.hxx
src/MEDLoader/MEDFileMeshLL.cxx
src/MEDLoader/MEDFileMeshLL.hxx
src/MEDLoader/Swig/MEDLoader.i
src/MEDLoader/Swig/MEDLoaderCommon.i
src/MEDLoader/Swig/MEDLoaderTest3.py

index b5e287a87d9527749d9ca361e04653e0652f8be2..d9468fdb65e2d2d2755455890950aa093d4b90eb 100644 (file)
@@ -428,4 +428,15 @@ def ParaMEDMEMMEDCouplingExtrudedMeshnew(cls,*args):
     return _MEDCalculator.MEDCouplingExtrudedMesh____new___(cls,args)
 %}
 
+%pythoncode %{
+def ParaMEDMEMMEDFileUMeshnew(cls,*args):
+    import _MEDCalculator
+    return _MEDCalculator.MEDFileUMesh____new___(cls,args)
+%}
+
 %include "MEDCouplingFinalize.i"
+
+%pythoncode %{
+MEDFileUMesh.__new__=classmethod(ParaMEDMEMMEDFileUMeshnew)
+del ParaMEDMEMMEDFileUMeshnew
+%}
index 0eb44d63109bebaa59441e435867bf5c3ebe6e35..7523d938ba7d7ae2b906f66f1e9de27ae252d3bc 100644 (file)
@@ -32,6 +32,24 @@ PartDefinition *PartDefinition::New(DataArrayInt *listOfIds)
   return DataArrayPartDefinition::New(listOfIds);
 }
 
+PartDefinition *PartDefinition::Unserialize(std::vector<int>& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI)
+{
+  if(tinyInt.empty())
+    {
+      MEDCouplingAutoRefCountObjectPtr<PartDefinition> ret(DataArrayPartDefinition::New(bigArraysI.back()));
+      bigArraysI.pop_back();
+      return ret.retn();
+    }
+  else if(tinyInt.size()==3)
+    {
+      MEDCouplingAutoRefCountObjectPtr<PartDefinition> ret(SlicePartDefinition::New(tinyInt[0],tinyInt[1],tinyInt[2]));
+      tinyInt.erase(tinyInt.begin(),tinyInt.begin()+3);
+      return ret.retn();
+    }
+  else
+    throw INTERP_KERNEL::Exception("PartDefinition::Unserialize");
+}
+
 PartDefinition::~PartDefinition()
 {
 }
@@ -41,6 +59,45 @@ DataArrayPartDefinition *DataArrayPartDefinition::New(DataArrayInt *listOfIds)
   return new DataArrayPartDefinition(listOfIds);
 }
 
+bool DataArrayPartDefinition::isEqual(const PartDefinition *other, std::string& what) const
+{
+  if(!other)
+    {
+      what="DataArrayPartDefinition::isEqual : other is null, this is not null !";
+      return false;
+    }
+  const DataArrayPartDefinition *otherC(dynamic_cast<const DataArrayPartDefinition *>(other));
+  if(!otherC)
+    {
+      what="DataArrayPartDefinition::isEqual : other is not DataArrayPartDefinition !";
+      return false;
+    }
+  const DataArrayInt *arr0(_arr),*arr1(otherC->_arr);
+  if(!arr0 && !arr1)
+    return true;
+  if((arr0 && !arr1) || (!arr0 && arr1))
+    {
+      what="DataArrayPartDefinition::isEqual : array is not defined both in other and this !";
+      return false;
+    }
+  std::string what1;
+  bool ret(arr0->isEqualIfNotWhy(*arr1,what1));
+  if(!ret)
+    {
+      what=std::string("DataArrayPartDefinition::isEqual : arrays are not equal :\n")+what1;
+      return false;
+    }
+  return true;
+}
+
+DataArrayPartDefinition *DataArrayPartDefinition::deepCpy() const
+{
+  const DataArrayInt *arr(_arr);
+  if(!arr)
+    throw INTERP_KERNEL::Exception("DataArrayPartDefinition::deepCpy : array is null !");
+  return DataArrayPartDefinition::New(const_cast<DataArrayInt *>(arr));
+}
+
 int DataArrayPartDefinition::getNumberOfElems() const
 {
   checkInternalArrayOK();
@@ -127,6 +184,11 @@ PartDefinition *DataArrayPartDefinition::tryToSimplify() const
     }
 }
 
+void DataArrayPartDefinition::serialize(std::vector<int>& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI) const
+{
+  bigArraysI.push_back(_arr);
+}
+
 DataArrayInt *DataArrayPartDefinition::toDAI() const
 {
   checkInternalArrayOK();
@@ -196,6 +258,33 @@ SlicePartDefinition *SlicePartDefinition::New(int start, int stop, int step)
   return new SlicePartDefinition(start,stop,step);
 }
 
+bool SlicePartDefinition::isEqual(const PartDefinition *other, std::string& what) const
+{
+  if(!other)
+    {
+      what="SlicePartDefinition::isEqual : other is null, this is not null !";
+      return false;
+    }
+  const SlicePartDefinition *otherC(dynamic_cast<const SlicePartDefinition *>(other));
+  if(!otherC)
+    {
+      what="SlicePartDefinition::isEqual : other is not SlicePartDefinition !";
+      return false;
+    }
+  bool ret((_start==otherC->_start) && (_stop==otherC->_stop) && (_step==otherC->_step));
+  if(!ret)
+    {
+      what="SlicePartDefinition::isEqual : values are not the same !";
+      return false;
+    }
+  return true;
+}
+
+SlicePartDefinition *SlicePartDefinition::deepCpy() const
+{
+  return SlicePartDefinition::New(_start,_stop,_step);
+}
+
 DataArrayInt *SlicePartDefinition::toDAI() const
 {
   return DataArrayInt::Range(_start,_stop,_step);
@@ -254,6 +343,13 @@ PartDefinition *SlicePartDefinition::tryToSimplify() const
   return ret;
 }
 
+void SlicePartDefinition::serialize(std::vector<int>& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI) const
+{
+  tinyInt.push_back(_start);
+  tinyInt.push_back(_stop);
+  tinyInt.push_back(_step);
+}
+
 std::string SlicePartDefinition::getRepr() const
 {
   std::ostringstream oss;
index d81d0824a907e7213325918693ed51088d7d0814..49bc3d3796b94fa5fb99662b780a6bbb87a8e169 100644 (file)
@@ -32,6 +32,9 @@ namespace ParaMEDMEM
   public:
     MEDCOUPLING_EXPORT static PartDefinition *New(int start, int stop, int step);
     MEDCOUPLING_EXPORT static PartDefinition *New(DataArrayInt *listOfIds);
+    MEDCOUPLING_EXPORT static PartDefinition *Unserialize(std::vector<int>& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI);
+    MEDCOUPLING_EXPORT virtual bool isEqual(const PartDefinition *other, std::string& what) const = 0;
+    MEDCOUPLING_EXPORT virtual PartDefinition *deepCpy() const = 0;
     MEDCOUPLING_EXPORT virtual DataArrayInt *toDAI() const = 0;
     MEDCOUPLING_EXPORT virtual int getNumberOfElems() const = 0;
     MEDCOUPLING_EXPORT virtual PartDefinition *operator+(const PartDefinition& other) const = 0;
@@ -39,6 +42,7 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT virtual PartDefinition *composeWith(const PartDefinition *other) const = 0;
     MEDCOUPLING_EXPORT virtual void checkCoherency() const = 0;
     MEDCOUPLING_EXPORT virtual PartDefinition *tryToSimplify() const = 0;
+    MEDCOUPLING_EXPORT virtual void serialize(std::vector<int>& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI) const = 0;
   protected:
     virtual ~PartDefinition();
   };
@@ -49,6 +53,8 @@ namespace ParaMEDMEM
   {
   public:
     MEDCOUPLING_EXPORT static DataArrayPartDefinition *New(DataArrayInt *listOfIds);
+    MEDCOUPLING_EXPORT bool isEqual(const PartDefinition *other, std::string& what) const;
+    MEDCOUPLING_EXPORT DataArrayPartDefinition *deepCpy() const;
     MEDCOUPLING_EXPORT DataArrayInt *toDAI() const;
     MEDCOUPLING_EXPORT int getNumberOfElems() const;
     MEDCOUPLING_EXPORT PartDefinition *operator+(const PartDefinition& other) const;
@@ -56,6 +62,7 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT PartDefinition *composeWith(const PartDefinition *other) const;
     MEDCOUPLING_EXPORT void checkCoherency() const;
     MEDCOUPLING_EXPORT PartDefinition *tryToSimplify() const;
+    MEDCOUPLING_EXPORT void serialize(std::vector<int>& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI) const;
   private:
     DataArrayPartDefinition(DataArrayInt *listOfIds);
     void checkInternalArrayOK() const;
@@ -74,6 +81,8 @@ namespace ParaMEDMEM
   {
   public:
     MEDCOUPLING_EXPORT static SlicePartDefinition *New(int start, int stop, int step);
+    MEDCOUPLING_EXPORT bool isEqual(const PartDefinition *other, std::string& what) const;
+    MEDCOUPLING_EXPORT SlicePartDefinition *deepCpy() const;
     MEDCOUPLING_EXPORT DataArrayInt *toDAI() const;
     MEDCOUPLING_EXPORT int getNumberOfElems() const;
     MEDCOUPLING_EXPORT PartDefinition *operator+(const PartDefinition& other) const;
@@ -81,6 +90,7 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT PartDefinition *composeWith(const PartDefinition *other) const;
     MEDCOUPLING_EXPORT void checkCoherency() const;
     MEDCOUPLING_EXPORT PartDefinition *tryToSimplify() const;
+    MEDCOUPLING_EXPORT void serialize(std::vector<int>& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI) const;
     //specific method
     MEDCOUPLING_EXPORT int getEffectiveStop() const;
     MEDCOUPLING_EXPORT void getSlice(int& start, int& stop, int& step) const;
index 108897c53d9a83060acfc51fc54f8593ac5a1125..d884ce8e84ac7d6feb68899db19c43d49348dbac 100644 (file)
@@ -75,7 +75,7 @@ SET(PYFILES_TO_INSTALL ${CMAKE_CURRENT_BINARY_DIR}/MEDCoupling.py ${CMAKE_CURREN
 INSTALL_AND_COMPILE_PYTHON_FILE("${PYFILES_TO_INSTALL}" ${SALOME_INSTALL_SCRIPT_PYTHON})
 
 INSTALL(FILES MEDCoupling.i MEDCouplingCommon.i MEDCouplingRefCountObject.i MEDCouplingMemArray.i MEDCouplingFieldDiscretization.i MEDCouplingTimeDiscretization.i MEDCouplingFinalize.i MEDCouplingRemapper.i MEDCouplingTypemaps.i MEDCouplingDataArrayTypemaps.i DESTINATION ${SALOME_INSTALL_HEADERS})
-INSTALL(FILES MEDCouplingBasicsTest.py MEDCouplingRemapperTest.py MEDCouplingDataForTest.py MEDCouplingNumPyTest.py DESTINATION ${SALOME_INSTALL_SCRIPT_PYTHON})
+INSTALL(FILES MEDCouplingBasicsTest.py MEDCouplingRemapperTest.py MEDCouplingDataForTest.py MEDCouplingNumPyTest.py MEDCouplingPickleTest.py DESTINATION ${SALOME_INSTALL_SCRIPT_PYTHON})
 INSTALL(FILES MEDCouplingExamplesTest.py DESTINATION ${SALOME_INSTALL_SCRIPT_PYTHON})
 
 SALOME_GENERATE_TESTS_ENVIRONMENT(tests_env)
index d793d5fc6e316d707dafe1317d17d73a3a842270..61b4057a2984067c2c80d0c2309384e8f31558a6 100644 (file)
@@ -16234,6 +16234,8 @@ class MEDCouplingBasicsTest(unittest.TestCase):
     def testSwig2PartDefinitionComposeWith1(self):
         f=PartDefinition.New(DataArrayInt([0,1,2,3,6,7,8,9]))
         g=PartDefinition.New(4,14,1)
+        g2=g.deepCpy()
+        self.assertTrue(g2.isEqual(g)[0])
         h=f.composeWith(g)
         self.assertTrue(isinstance(h,DataArrayPartDefinition))
         self.assertTrue(h.toDAI().isEqual(DataArrayInt([4,5,6,7,10,11,12,13])))
@@ -16246,6 +16248,11 @@ class MEDCouplingBasicsTest(unittest.TestCase):
         self.assertNotEqual(p2.getHiddenCppPointer(),p.getHiddenCppPointer())
         self.assertTrue(isinstance(p2,SlicePartDefinition))
         self.assertEqual(p2.getSlice(),slice(2,11,4))
+        self.assertTrue(p2.isEqual(SlicePartDefinition(2,11,4))[0])
+        self.assertTrue(p2.isEqual(p2.deepCpy())[0])
+        self.assertTrue(not p2.isEqual(SlicePartDefinition(1,11,4))[0])
+        self.assertTrue(not p2.isEqual(SlicePartDefinition(2,10,4))[0])
+        self.assertTrue(not p2.isEqual(SlicePartDefinition(2,11,3))[0])
         pass
 
     def testSwig2DAIGetIdsStrictlyNegative1(self):
index cb242a15b6f7cca99a0c35ddaf600b34a58c954e..0b365b818b1847fdc8ea1e21cc02aab36485c8cb 100644 (file)
@@ -5731,6 +5731,23 @@ namespace ParaMEDMEM
       {
         return (*self)+other;
       }
+
+      virtual PyObject *isEqual(const PartDefinition *other) const throw(INTERP_KERNEL::Exception)
+      {
+        std::string ret1;
+        bool ret0(self->isEqual(other,ret1));
+        PyObject *ret=PyTuple_New(2);
+        PyObject *ret0Py=ret0?Py_True:Py_False;
+        Py_XINCREF(ret0Py);
+        PyTuple_SetItem(ret,0,ret0Py);
+        PyTuple_SetItem(ret,1,PyString_FromString(ret1.c_str()));
+        return ret;
+      }
+
+      virtual PyObject *deepCpy() const throw(INTERP_KERNEL::Exception)
+      {
+        return convertPartDefinition(self->deepCpy(),SWIG_POINTER_OWN | 0);
+      }
     }
   protected:
     virtual ~PartDefinition();
index 2e5203cfb78d431af8cf46fdf5b19bbf837c37b3..9071942380ea09a5acfd23bf0233262d9a95eba0 100644 (file)
@@ -2068,6 +2068,8 @@ MEDFileMesh *MEDFileUMesh::deepCpy() const
       if((const MEDFileUMeshSplitL1 *)(*it))
         ret->_ms[i]=(*it)->deepCpy(ret->_coords);
     }
+  if((const PartDefinition*)_part_coords)
+    ret->_part_coords=_part_coords->deepCpy();
   return ret.retn();
 }
 
@@ -2176,7 +2178,15 @@ bool MEDFileUMesh::isEqual(const MEDFileMesh *other, double eps, std::string& wh
             return false;
         }
     }
-  return true;
+  const PartDefinition *pd0(_part_coords),*pd1(otherC->_part_coords);
+  if(!pd0 && !pd1)
+    return true;
+  if((!pd0 && pd1) || (pd0 && !pd1))
+    {
+      what=std::string("node part def is defined only for one among this or other !");
+      return false;
+    }
+  return pd0->isEqual(pd1,what);
 }
 
 /*!
@@ -3709,6 +3719,137 @@ MEDFileUMesh *MEDFileUMesh::buildExtrudedMesh(const MEDCouplingUMesh *m1D, int p
   return ret.retn();
 }
 
+void MEDFileUMesh::serialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr, std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI, MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>& bigArrayD)
+{
+  clearNonDiscrAttributes();
+  forceComputationOfParts();
+  tinyDouble.clear(); tinyInt.clear(); tinyStr.clear(); bigArraysI.clear(); bigArrayD=0;
+  std::vector<int> layer0;
+  layer0.push_back(_order); //0 i
+  layer0.push_back(_iteration);//1 i
+  layer0.push_back(getSpaceDimension());//2 i
+  tinyDouble.push_back(_time);//0 d
+  tinyStr.push_back(_name);//0 s
+  tinyStr.push_back(_desc_name);//1 s
+  for(int i=0;i<getSpaceDimension();i++)
+    tinyStr.push_back(_coords->getInfoOnComponent(i));
+  layer0.push_back((int)_families.size());//3 i <- key info aa layer#0
+  for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
+    {
+      tinyStr.push_back((*it).first);
+      layer0.push_back((*it).second);
+    }
+  layer0.push_back((int)_groups.size());//3+aa i <- key info bb layer#0
+  for(std::map<std::string, std::vector<std::string> >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
+    {
+      layer0.push_back((int)(*it0).second.size());
+      tinyStr.push_back((*it0).first);
+      for(std::vector<std::string>::const_iterator it1=((*it0).second).begin();it1!=((*it0).second).end();it1++)
+        tinyStr.push_back(*it1);
+    }
+  // sizeof(layer0)==3+aa+1+bb layer#0
+  bigArrayD=_coords;// 0 bd
+  bigArraysI.push_back(_fam_coords);// 0 bi
+  bigArraysI.push_back(_num_coords);// 1 bi
+  const PartDefinition *pd(_part_coords);
+  if(!pd)
+    layer0.push_back(-1);
+  else
+    {
+      std::vector<int> tmp0;
+      pd->serialize(tmp0,bigArraysI);
+      tinyInt.push_back(tmp0.size());
+      tinyInt.insert(tinyInt.end(),tmp0.begin(),tmp0.end());
+    }
+  //
+  std::vector<int> layer1;
+  std::vector<int> levs(getNonEmptyLevels());
+  layer1.push_back((int)levs.size());// 0 i <- key
+  layer1.insert(layer1.end(),levs.begin(),levs.end());
+  for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
+    {
+      const MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(*it));
+      lev->serialize(layer1,bigArraysI);
+    }
+  // put layers all together.
+  tinyInt.push_back(layer0.size());
+  tinyInt.insert(tinyInt.end(),layer0.begin(),layer0.end());
+  tinyInt.push_back(layer1.size());
+  tinyInt.insert(tinyInt.end(),layer1.begin(),layer1.end());
+}
+
+void MEDFileUMesh::unserialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr,
+                               std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI, MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>& bigArrayD)
+{
+  int sz0(tinyInt[0]);
+  std::vector<int> layer0(tinyInt.begin()+1,tinyInt.begin()+1+sz0);
+  int sz1(tinyInt[sz0+1]);
+  std::vector<int> layer1(tinyInt.begin()+2+sz0,tinyInt.begin()+2+sz0+sz1);
+  //
+  std::reverse(layer0.begin(),layer0.end());
+  std::reverse(layer1.begin(),layer1.end());
+  std::reverse(tinyDouble.begin(),tinyDouble.end());
+  std::reverse(tinyStr.begin(),tinyStr.end());
+  std::reverse(bigArraysI.begin(),bigArraysI.end());
+  //
+  _order=layer0.back(); layer0.pop_back();
+  _iteration=layer0.back(); layer0.pop_back();
+  int spaceDim(layer0.back()); layer0.pop_back();
+  _time=tinyDouble.back(); tinyDouble.pop_back();
+  _name=tinyStr.back(); tinyStr.pop_back();
+  _desc_name=tinyStr.back(); tinyStr.pop_back();
+  _coords=bigArrayD; _coords->rearrange(spaceDim);
+  for(int i=0;i<spaceDim;i++)
+    {
+      _coords->setInfoOnComponent(i,tinyStr.back());
+      tinyStr.pop_back();
+    }
+  int nbOfFams(layer0.back()); layer0.pop_back();
+  _families.clear();
+  for(int i=0;i<nbOfFams;i++)
+    {
+      _families[tinyStr.back()]=layer0.back();
+      tinyStr.pop_back(); layer0.pop_back();
+    }
+  int nbGroups(layer0.back()); layer0.pop_back();
+  _groups.clear();
+  for(int i=0;i<nbGroups;i++)
+    {
+      std::string grpName(tinyStr.back()); tinyStr.pop_back();
+      int nbOfFamsOnGrp(layer0.back()); layer0.pop_back();
+      std::vector<std::string> fams(nbOfFamsOnGrp);
+      for(int j=0;j<nbOfFamsOnGrp;j++)
+        {
+          fams[j]=tinyStr.back(); tinyStr.pop_back();
+        }
+      _groups[grpName]=fams;
+    }
+  _fam_coords=bigArraysI.back(); bigArraysI.pop_back();
+  _num_coords=bigArraysI.back(); bigArraysI.pop_back();
+  _part_coords=0;
+  int isPd(layer0.back()); layer0.pop_back();
+  if(isPd!=-1)
+    {
+      std::vector<int> tmp0(layer0.begin(),layer0.begin()+isPd);
+      layer0.erase(layer0.begin(),layer0.begin()+isPd);
+      _part_coords=PartDefinition::Unserialize(tmp0,bigArraysI);
+    }
+  if(!layer0.empty())
+    throw INTERP_KERNEL::Exception("MEDFileUMesh::unserialize : something wrong during unserialization #1 !");
+  //
+  int nbLevs(layer1.back()); layer1.pop_back();
+  std::vector<int> levs(layer1.rbegin(),layer1.rbegin()+nbLevs); layer1.erase(layer1.end()-nbLevs,layer1.end());
+  _ms.clear();
+  int maxLev(-(*std::min_element(levs.begin(),levs.end())));
+  _ms.resize(maxLev+1);
+  for(int i=0;i<nbLevs;i++)
+    {
+      int lev(levs[i]);
+      int pos(-lev);
+      _ms[pos]=MEDFileUMeshSplitL1::Unserialize(_name,_coords,layer1,bigArraysI);
+    }
+}
+
 /*!
  * Adds a group of nodes to \a this mesh.
  *  \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
index ac524c16d225c9b2e62a40f34e7050c817be9dcd..6b18dc34c040801a39a4094e6a6d6094ebfcb50c 100644 (file)
@@ -286,6 +286,11 @@ namespace ParaMEDMEM
     MEDLOADER_EXPORT bool unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell);
     MEDLOADER_EXPORT DataArrayInt *zipCoords();
     MEDLOADER_EXPORT MEDFileUMesh *buildExtrudedMesh(const MEDCouplingUMesh *m1D, int policy) const;
+    // serialization
+    MEDLOADER_EXPORT void serialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr,
+                                    std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI, MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>& bigArrayD);
+    MEDLOADER_EXPORT void unserialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr,
+                                      std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI, MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>& bigArrayD);
   private:
     MEDLOADER_EXPORT ~MEDFileUMesh();
     void writeLL(med_idt fid) const;
index 7a1dbe458562a12db7cae037539f5eccf68ba5a6..7f47db7480f511e3c0c7eea5f1dd05610ca8a80f 100644 (file)
@@ -842,6 +842,10 @@ void MEDFileUMeshSplitL1::assignParts(const std::vector< const MEDCoupling1GTUMe
   assignCommonPart();
 }
 
+MEDFileUMeshSplitL1::MEDFileUMeshSplitL1():_m(this)
+{
+}
+
 void MEDFileUMeshSplitL1::assignCommonPart()
 {
   _fam=DataArrayInt::New();
@@ -1026,6 +1030,20 @@ void MEDFileUMeshSplitL1::renumberNodesInConn(const int *newNodeNumbersO2N)
   _m_by_types.renumberNodesInConnWithoutComputation(newNodeNumbersO2N);
 }
 
+void MEDFileUMeshSplitL1::serialize(std::vector<int>& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI) const
+{
+  bigArraysI.push_back(_fam);
+  bigArraysI.push_back(_num);
+  _m_by_types.serialize(tinyInt,bigArraysI);
+}
+
+void MEDFileUMeshSplitL1::unserialize(const std::string& name, DataArrayDouble *coo, std::vector<int>& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI)
+{
+  _fam=bigArraysI.back(); bigArraysI.pop_back();
+  _num=bigArraysI.back(); bigArraysI.pop_back();
+  _m_by_types.unserialize(name,coo,tinyInt,bigArraysI);
+}
+
 void MEDFileUMeshSplitL1::changeFamilyIdArr(int oldId, int newId)
 {
   DataArrayInt *arr=_fam;
@@ -1088,6 +1106,13 @@ MEDCouplingUMesh *MEDFileUMeshSplitL1::Renumber2(const DataArrayInt *renum, MEDC
   return m;
 }
 
+MEDFileUMeshSplitL1 *MEDFileUMeshSplitL1::Unserialize(const std::string& name, DataArrayDouble *coo, std::vector<int>& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI)
+{
+  MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> ret(new MEDFileUMeshSplitL1);
+  ret->unserialize(name,coo,tinyInt,bigArraysI);
+  return ret.retn();
+}
+
 MEDCouplingUMesh *MEDFileUMeshSplitL1::renumIfNeeded(MEDCouplingUMesh *m, const int *cellIds) const
 {
   return Renumber2(_num,m,cellIds);
@@ -1345,6 +1370,86 @@ const PartDefinition *MEDFileUMeshAggregateCompute::getPartDefOfWithoutComputati
   throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getPartDefOfWithoutComputation : The input geo type is not existing in this !");
 }
 
+void MEDFileUMeshAggregateCompute::serialize(std::vector<int>& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI) const
+{
+  if(_mp_time<_m_time)
+    throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::serialize : the parts require a computation !");
+  std::size_t sz(_m_parts.size());
+  tinyInt.push_back((int)sz);
+  for(std::size_t i=0;i<sz;i++)
+    {
+      const MEDCoupling1GTUMesh *mesh(_m_parts[i]);
+      if(!mesh)
+        throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::serialize : one part is empty !");
+      tinyInt.push_back(mesh->getCellModelEnum());
+      const MEDCoupling1SGTUMesh *mesh1(dynamic_cast<const MEDCoupling1SGTUMesh *>(mesh));
+      const MEDCoupling1DGTUMesh *mesh2(dynamic_cast<const MEDCoupling1DGTUMesh *>(mesh));
+      if(mesh1)
+        {
+          DataArrayInt *elt(mesh1->getNodalConnectivity());
+          if(elt)
+            elt->incrRef();
+          MEDCouplingAutoRefCountObjectPtr<DataArrayInt> elt1(elt);
+          bigArraysI.push_back(elt1);
+        }
+      else if(mesh2)
+        {
+          DataArrayInt *elt1(mesh2->getNodalConnectivity()),*elt2(mesh2->getNodalConnectivityIndex());
+          if(elt1)
+            elt1->incrRef();
+          if(elt2)
+            elt2->incrRef();
+          MEDCouplingAutoRefCountObjectPtr<DataArrayInt> elt11(elt1),elt22(elt2);
+          bigArraysI.push_back(elt11); bigArraysI.push_back(elt22);
+        }
+      else
+        throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::serialize : unrecognized single geo type mesh !");
+      const PartDefinition *pd(_part_def[i]);
+      if(!pd)
+        tinyInt.push_back(-1);
+      else
+        {
+          std::vector<int> tinyTmp;
+          pd->serialize(tinyTmp,bigArraysI);
+          tinyInt.push_back((int)tinyTmp.size());
+          tinyInt.insert(tinyInt.end(),tinyTmp.begin(),tinyTmp.end());
+        }
+    }
+}
+
+void MEDFileUMeshAggregateCompute::unserialize(const std::string& name, DataArrayDouble *coo, std::vector<int>& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI)
+{
+  int nbParts(tinyInt.back()); tinyInt.pop_back();
+  _part_def.clear(); _part_def.resize(nbParts);
+  _m_parts.clear(); _m_parts.resize(nbParts);
+  for(int i=0;i<nbParts;i++)
+    {
+      INTERP_KERNEL::NormalizedCellType tp((INTERP_KERNEL::NormalizedCellType) tinyInt.back()); tinyInt.pop_back();
+      MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> mesh(MEDCoupling1GTUMesh::New(name,tp));
+      mesh->setCoords(coo);
+      MEDCoupling1SGTUMesh *mesh1(dynamic_cast<MEDCoupling1SGTUMesh *>((MEDCoupling1GTUMesh *) mesh));
+      MEDCoupling1DGTUMesh *mesh2(dynamic_cast<MEDCoupling1DGTUMesh *>((MEDCoupling1GTUMesh *) mesh));
+      if(mesh1)
+        {
+          mesh1->setNodalConnectivity(bigArraysI.back()); bigArraysI.pop_back();
+        }
+      else if(mesh2)
+        {
+          MEDCouplingAutoRefCountObjectPtr<DataArrayInt> elt0,elt1;
+          elt0=bigArraysI.back(); bigArraysI.pop_back();
+          elt1=bigArraysI.back(); bigArraysI.pop_back();
+          mesh2->setNodalConnectivity(elt0,elt1);
+        }
+      else
+        throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::unserialize : unrecognized single geo type mesh !");
+      _m_parts[i]=mesh;
+      int pdid(tinyInt.back()); tinyInt.pop_back();
+      if(pdid!=-1)
+        _part_def[i]=PartDefinition::Unserialize(tinyInt,bigArraysI);
+      _mp_time=std::max(_mp_time,_m_time)+1;
+    }
+}
+
 /*!
  * This method returns true if \a this is stored split by type false if stored in a merged unstructured mesh.
  */
@@ -1419,6 +1524,14 @@ MEDFileUMeshAggregateCompute MEDFileUMeshAggregateCompute::deepCpy(DataArrayDoub
       ret._m=static_cast<ParaMEDMEM::MEDCouplingUMesh*>(_m->deepCpy());
       ret._m->setCoords(coords);
     }
+  std::size_t sz(_part_def.size());
+  ret._part_def.clear(); ret._part_def.resize(sz);
+  for(std::size_t i=0;i<sz;i++)
+    {
+      const PartDefinition *elt(_part_def[i]);
+      if(elt)
+        ret._part_def[i]=elt->deepCpy();
+    }
   return ret;
 }
 
@@ -1440,6 +1553,26 @@ bool MEDFileUMeshAggregateCompute::isEqual(const MEDFileUMeshAggregateCompute& o
           return false;
         }
     }
+  std::size_t sz(_part_def.size());
+  if(sz!=other._part_def.size())
+    {
+      what=std::string("number of subdivision per geo type for part definition is not the same !");
+      return false;
+    }
+  for(std::size_t i=0;i<sz;i++)
+    {
+      const PartDefinition *pd0(_part_def[i]),*pd1(other._part_def[i]);
+      if(!pd0 && !pd1)
+        continue;
+      if((!pd0 && pd1) || (pd0 && !pd1))
+        {
+          what=std::string("a cell part def is defined only for one among this or other !");
+          return false;
+        }
+      bool ret(pd0->isEqual(pd1,what));
+      if(!ret)
+        return false;
+    }
   return true;
 }
 
index 9be10dab9431ec422a7b1b0bae6da2f9b991ea78..8963d6d718de0582a8141d4f0fd60fc0848c9160 100644 (file)
@@ -177,6 +177,8 @@ namespace ParaMEDMEM
     void setCoords(DataArrayDouble *coords);
     void forceComputationOfPartsFromUMesh() const;
     const PartDefinition *getPartDefOfWithoutComputation(INTERP_KERNEL::NormalizedCellType gt) const;
+    void serialize(std::vector<int>& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI) const;
+    void unserialize(const std::string& name, DataArrayDouble *coo, std::vector<int>& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI);
   private:
     std::size_t getTimeOfParts() const;
     std::size_t getTimeOfUMesh() const;
@@ -242,13 +244,18 @@ namespace ParaMEDMEM
     //
     void renumberNodesInConn(const int *newNodeNumbersO2N);
     //
+    void serialize(std::vector<int>& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI) const;
+    void unserialize(const std::string& name, DataArrayDouble *coo, std::vector<int>& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI);
+    //
     static void ClearNonDiscrAttributes(const MEDCouplingMesh *tmp);
     static std::vector<int> GetNewFamiliesNumber(int nb, const std::map<std::string,int>& families);
     static void TraduceFamilyNumber(const std::vector< std::vector<int> >& fidsGrps, std::map<std::string,int>& familyIds,
                                     std::map<int,int>& famIdTrad, std::map<int,std::string>& newfams);
     static DataArrayInt *Renumber(const DataArrayInt *renum, const DataArrayInt *da);
     static MEDCouplingUMesh *Renumber2(const DataArrayInt *renum, MEDCouplingUMesh *m, const int *cellIds);
+    static MEDFileUMeshSplitL1 *Unserialize(const std::string& name, DataArrayDouble *coo, std::vector<int>& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI);
   private:
+    MEDFileUMeshSplitL1();
     void assignCommonPart();
     MEDCouplingUMesh *renumIfNeeded(MEDCouplingUMesh *m, const int *cellIds) const;
     DataArrayInt *renumIfNeededArr(const DataArrayInt *da) const;
index ab8d676ed77f572cce5382babdd9efe36837879b..d85b638165bcf60afbf5f590a45bbb586292235f 100644 (file)
@@ -134,4 +134,15 @@ def ParaMEDMEMMEDCouplingExtrudedMeshnew(cls,*args):
     return _MEDLoader.MEDCouplingExtrudedMesh____new___(cls,args)
 %}
 
+%pythoncode %{
+def ParaMEDMEMMEDFileUMeshnew(cls,*args):
+    import _MEDLoader
+    return _MEDLoader.MEDFileUMesh____new___(cls,args)
+%}
+
 %include "MEDCouplingFinalize.i"
+
+%pythoncode %{
+MEDFileUMesh.__new__=classmethod(ParaMEDMEMMEDFileUMeshnew)
+del ParaMEDMEMMEDFileUMeshnew
+%}
index 31da32de03098cab7c24de88269fe3cab276c521..e069accbc61706da8f6e42eee32c0b06d4fb7518 100644 (file)
@@ -799,6 +799,12 @@ namespace ParaMEDMEM
            return MEDFileUMesh::New();
          }
 
+         // serialization
+         static PyObject *___new___(PyObject *cls, PyObject *args) throw(INTERP_KERNEL::Exception)
+         {
+           return NewMethWrapCallInitOnlyIfEmptyDictInInput(cls,args,"MEDFileUMesh");
+         }
+
          static MEDFileUMesh *LoadPartOf(const std::string& fileName, const std::string& mName, PyObject *types, const std::vector<int>& slicPerTyp, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0) throw(INTERP_KERNEL::Exception)
          {
            std::vector<int> typesCpp1;
@@ -810,6 +816,90 @@ namespace ParaMEDMEM
            return MEDFileUMesh::LoadPartOf(fileName,mName,typesCpp2,slicPerTyp,dt,it,mrs);
          }
 
+         PyObject *__getnewargs__() throw(INTERP_KERNEL::Exception)
+         {// put an empty dict in input to say to __new__ to call __init__...
+           PyObject *ret(PyTuple_New(1));
+           PyObject *ret0(PyDict_New());
+           PyTuple_SetItem(ret,0,ret0);
+           return ret;
+         }
+
+         PyObject *__getstate__() throw(INTERP_KERNEL::Exception)
+         {
+           std::vector<double> a0;
+           std::vector<int> a1;
+           std::vector<std::string> a2;
+           std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > a3;
+           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> a4;
+           self->serialize(a0,a1,a2,a3,a4);
+           PyObject *ret(PyTuple_New(5));
+           PyTuple_SetItem(ret,0,convertDblArrToPyList2(a0));
+           PyTuple_SetItem(ret,1,convertIntArrToPyList2(a1));
+           int sz(a2.size());
+           PyObject *ret2(PyList_New(sz));
+           for(int i=0;i<sz;i++)
+             PyList_SetItem(ret2,i,PyString_FromString(a2[i].c_str()));
+           PyTuple_SetItem(ret,2,ret2);
+           sz=a3.size();
+           PyObject *ret3(PyList_New(sz));
+           for(int i=0;i<sz;i++)
+             {
+               DataArrayInt *elt(a3[i]);
+               if(elt)
+                 elt->incrRef();
+               PyList_SetItem(ret3,i,SWIG_NewPointerObj(SWIG_as_voidptr(elt),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ));
+             }
+           PyTuple_SetItem(ret,3,ret3);
+           DataArrayDouble *ret4(a4);
+           if(ret4)
+             ret4->incrRef();
+           PyTuple_SetItem(ret,4,SWIG_NewPointerObj(SWIG_as_voidptr(ret4),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ));
+           return ret;
+         }
+
+         void __setstate__(PyObject *inp) throw(INTERP_KERNEL::Exception)
+         {
+           static const char MSG[]="MEDFileUMesh.__setstate__ : expected input is a tuple of size 4 !";
+           if(!PyTuple_Check(inp))
+             throw INTERP_KERNEL::Exception(MSG);
+           int sz(PyTuple_Size(inp));
+           if(sz!=5)
+             throw INTERP_KERNEL::Exception(MSG);
+           std::vector<double> a0;
+           std::vector<int> a1;
+           std::vector<std::string> a2;
+           std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > a3;
+           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> a4;
+           //
+           PyObject *a0py(PyTuple_GetItem(inp,0)),*a1py(PyTuple_GetItem(inp,1)),*a2py(PyTuple_GetItem(inp,2));
+           int tmp(-1);
+           fillArrayWithPyListDbl3(a0py,tmp,a0);
+           convertPyToNewIntArr3(a1py,a1);
+           fillStringVector(a2py,a2);
+           //
+           PyObject *b0py(PyTuple_GetItem(inp,3)),*b1py(PyTuple_GetItem(inp,4));
+           void *argp(0);
+           int status(SWIG_ConvertPtr(b1py,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble,0|0));
+           if(!SWIG_IsOK(status))
+             throw INTERP_KERNEL::Exception(MSG);
+           a4=reinterpret_cast<DataArrayDouble *>(argp);
+           if((DataArrayDouble *)a4)
+             a4->incrRef();
+           {
+             std::vector< DataArrayInt * > a3Tmp;
+             convertFromPyObjVectorOfObj<ParaMEDMEM::DataArrayInt *>(b0py,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,"DataArrayInt",a3Tmp);
+             std::size_t sz(a3Tmp.size());
+             a3.resize(sz);
+             for(std::size_t i=0;i<sz;i++)
+               {
+                 a3[i]=a3Tmp[i];
+                 if(a3Tmp[i])
+                   a3Tmp[i]->incrRef();
+               }
+             self->unserialize(a0,a1,a2,a3,a4);
+           }
+         }
+
          void setMeshes(PyObject *li, bool renum=false) throw(INTERP_KERNEL::Exception)
          {
            std::vector<const MEDCouplingUMesh *> ms;
index 43d51acc08488b8b193303d52599ac0e35f4a4b4..19f8e6e861a418bd8ea14f9f30f984413ed8225d 100644 (file)
@@ -3942,6 +3942,98 @@ class MEDLoaderTest(unittest.TestCase):
         mm3D.setName("MeshExtruded")
         mm3D.write(fileName,0)
         pass
+
+    @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy")
+    def testMEDFileUMeshPickeling1(self):
+        import cPickle
+        outFileName="Pyfile86.med"
+        c=DataArrayDouble([-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ],9,2)
+        c.setInfoOnComponents(["aa","bbb"])
+        targetConn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4]
+        m=MEDCouplingUMesh();
+        m.setMeshDimension(2);
+        m.allocateCells(5);
+        m.insertNextCell(NORM_TRI3,3,targetConn[4:7])
+        m.insertNextCell(NORM_TRI3,3,targetConn[7:10])
+        m.insertNextCell(NORM_QUAD4,4,targetConn[0:4])
+        m.insertNextCell(NORM_POLYGON,4,targetConn[10:14])
+        m.insertNextCell(NORM_POLYGON,4,targetConn[14:18])
+        m.finishInsertingCells();
+        m.setCoords(c)
+        m.checkCoherency()
+        m1=MEDCouplingUMesh.New();
+        m1.setMeshDimension(1);
+        m1.allocateCells(3);
+        m1.insertNextCell(NORM_SEG2,2,[1,4])
+        m1.insertNextCell(NORM_SEG2,2,[3,6])
+        m1.insertNextCell(NORM_SEG3,3,[2,8,5])
+        m1.finishInsertingCells();
+        m1.setCoords(c)
+        m1.checkCoherency()
+        m2=MEDCouplingUMesh.New();
+        m2.setMeshDimension(0);
+        m2.allocateCells(4);
+        m2.insertNextCell(NORM_POINT1,1,[1])
+        m2.insertNextCell(NORM_POINT1,1,[3])
+        m2.insertNextCell(NORM_POINT1,1,[2])
+        m2.insertNextCell(NORM_POINT1,1,[6])
+        m2.finishInsertingCells();
+        m2.setCoords(c)
+        m2.checkCoherency()
+        #
+        mm=MEDFileUMesh.New()
+        self.assertTrue(mm.getUnivNameWrStatus())
+        mm.setName("MyFirstMEDCouplingMEDmesh")
+        mm.setDescription("IHopeToConvinceLastMEDMEMUsers")
+        mm.setCoords(c)
+        mm.setMeshAtLevel(-1,m1);
+        mm.setMeshAtLevel(0,m);
+        mm.setRenumFieldArr(0,DataArrayInt([32,41,50,56,7]))
+        mm.setMeshAtLevel(-2,m2);
+        mm.setRenumFieldArr(-2,DataArrayInt([102,52,45,63]))
+        # playing with groups
+        g1_2=DataArrayInt.New()
+        g1_2.setValues([1,3],2,1)
+        g1_2.setName("G1")
+        g2_2=DataArrayInt.New()
+        g2_2.setValues([1,2,3],3,1)
+        g2_2.setName("G2")
+        mm.setGroupsAtLevel(0,[g1_2,g2_2],False)
+        g1_1=DataArrayInt.New()
+        g1_1.setValues([0,1,2],3,1)
+        g1_1.setName("G1")
+        g2_1=DataArrayInt.New()
+        g2_1.setValues([0,2],2,1)
+        g2_1.setName("G2")
+        mm.setGroupsAtLevel(-1,[g1_1,g2_1],False)
+        g1_N=DataArrayInt.New()
+        g1_N.setValues(range(8),8,1)
+        g1_N.setName("G1")
+        g2_N=DataArrayInt.New()
+        g2_N.setValues(range(9),9,1)
+        g2_N.setName("G2")
+        mm.setGroupsAtLevel(1,[g1_N,g2_N],False)
+        mm.createGroupOnAll(0,"GrpOnAllCell")
+        # check content of mm
+        t=mm.getGroupArr(0,"G1",False)
+        self.assertTrue(g1_2.isEqual(t));
+        t=mm.getGroupArr(0,"G2",False)
+        self.assertTrue(g2_2.isEqual(t));
+        t=mm.getGroupArr(-1,"G1",False)
+        self.assertTrue(g1_1.isEqual(t));
+        t=mm.getGroupArr(-1,"G2",False)
+        self.assertTrue(g2_1.isEqual(t));
+        t=mm.getGroupArr(1,"G1",False)
+        self.assertTrue(g1_N.isEqual(t));
+        t=mm.getGroupArr(1,"G2",False)
+        self.assertTrue(g2_N.isEqual(t));
+        self.assertTrue(mm.existsGroup("GrpOnAllCell"));
+        t=mm.getGroupArr(0,"GrpOnAllCell")
+        #
+        st=cPickle.dumps(mm,cPickle.HIGHEST_PROTOCOL)
+        mm2=cPickle.loads(st)
+        self.assertTrue(mm.isEqual(mm2,1e-12)[0])
+        pass
     pass
 
 unittest.main()