From: Anthony Geay Date: Wed, 25 Mar 2015 17:53:41 +0000 (+0100) Subject: Pickelization of MEDFileUMesh objects. X-Git-Tag: V7_6_0a1~4 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=ab49be7cd5006def43ec524d5fbfed30e7721432;p=modules%2Fmed.git Pickelization of MEDFileUMesh objects. --- diff --git a/src/MEDCalculator/Swig/MEDCalculator.i b/src/MEDCalculator/Swig/MEDCalculator.i index b5e287a87..d9468fdb6 100644 --- a/src/MEDCalculator/Swig/MEDCalculator.i +++ b/src/MEDCalculator/Swig/MEDCalculator.i @@ -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 +%} diff --git a/src/MEDCoupling/MEDCouplingPartDefinition.cxx b/src/MEDCoupling/MEDCouplingPartDefinition.cxx index 0eb44d631..7523d938b 100644 --- a/src/MEDCoupling/MEDCouplingPartDefinition.cxx +++ b/src/MEDCoupling/MEDCouplingPartDefinition.cxx @@ -32,6 +32,24 @@ PartDefinition *PartDefinition::New(DataArrayInt *listOfIds) return DataArrayPartDefinition::New(listOfIds); } +PartDefinition *PartDefinition::Unserialize(std::vector& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr >& bigArraysI) +{ + if(tinyInt.empty()) + { + MEDCouplingAutoRefCountObjectPtr ret(DataArrayPartDefinition::New(bigArraysI.back())); + bigArraysI.pop_back(); + return ret.retn(); + } + else if(tinyInt.size()==3) + { + MEDCouplingAutoRefCountObjectPtr 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(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(arr)); +} + int DataArrayPartDefinition::getNumberOfElems() const { checkInternalArrayOK(); @@ -127,6 +184,11 @@ PartDefinition *DataArrayPartDefinition::tryToSimplify() const } } +void DataArrayPartDefinition::serialize(std::vector& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr >& 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(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& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr >& bigArraysI) const +{ + tinyInt.push_back(_start); + tinyInt.push_back(_stop); + tinyInt.push_back(_step); +} + std::string SlicePartDefinition::getRepr() const { std::ostringstream oss; diff --git a/src/MEDCoupling/MEDCouplingPartDefinition.hxx b/src/MEDCoupling/MEDCouplingPartDefinition.hxx index d81d0824a..49bc3d379 100644 --- a/src/MEDCoupling/MEDCouplingPartDefinition.hxx +++ b/src/MEDCoupling/MEDCouplingPartDefinition.hxx @@ -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& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr >& 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& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr >& 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& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr >& 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& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr >& bigArraysI) const; //specific method MEDCOUPLING_EXPORT int getEffectiveStop() const; MEDCOUPLING_EXPORT void getSlice(int& start, int& stop, int& step) const; diff --git a/src/MEDCoupling_Swig/CMakeLists.txt b/src/MEDCoupling_Swig/CMakeLists.txt index 108897c53..d884ce8e8 100644 --- a/src/MEDCoupling_Swig/CMakeLists.txt +++ b/src/MEDCoupling_Swig/CMakeLists.txt @@ -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) diff --git a/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py b/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py index d793d5fc6..61b4057a2 100644 --- a/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py +++ b/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py @@ -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): diff --git a/src/MEDCoupling_Swig/MEDCouplingCommon.i b/src/MEDCoupling_Swig/MEDCouplingCommon.i index cb242a15b..0b365b818 100644 --- a/src/MEDCoupling_Swig/MEDCouplingCommon.i +++ b/src/MEDCoupling_Swig/MEDCouplingCommon.i @@ -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(); diff --git a/src/MEDLoader/MEDFileMesh.cxx b/src/MEDLoader/MEDFileMesh.cxx index 2e5203cfb..907194238 100644 --- a/src/MEDLoader/MEDFileMesh.cxx +++ b/src/MEDLoader/MEDFileMesh.cxx @@ -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& tinyDouble, std::vector& tinyInt, std::vector& tinyStr, std::vector< MEDCouplingAutoRefCountObjectPtr >& bigArraysI, MEDCouplingAutoRefCountObjectPtr& bigArrayD) +{ + clearNonDiscrAttributes(); + forceComputationOfParts(); + tinyDouble.clear(); tinyInt.clear(); tinyStr.clear(); bigArraysI.clear(); bigArrayD=0; + std::vector 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;igetInfoOnComponent(i)); + layer0.push_back((int)_families.size());//3 i <- key info aa layer#0 + for(std::map::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 >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++) + { + layer0.push_back((int)(*it0).second.size()); + tinyStr.push_back((*it0).first); + for(std::vector::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 tmp0; + pd->serialize(tmp0,bigArraysI); + tinyInt.push_back(tmp0.size()); + tinyInt.insert(tinyInt.end(),tmp0.begin(),tmp0.end()); + } + // + std::vector layer1; + std::vector levs(getNonEmptyLevels()); + layer1.push_back((int)levs.size());// 0 i <- key + layer1.insert(layer1.end(),levs.begin(),levs.end()); + for(std::vector::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& tinyDouble, std::vector& tinyInt, std::vector& tinyStr, + std::vector< MEDCouplingAutoRefCountObjectPtr >& bigArraysI, MEDCouplingAutoRefCountObjectPtr& bigArrayD) +{ + int sz0(tinyInt[0]); + std::vector layer0(tinyInt.begin()+1,tinyInt.begin()+1+sz0); + int sz1(tinyInt[sz0+1]); + std::vector 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;isetInfoOnComponent(i,tinyStr.back()); + tinyStr.pop_back(); + } + int nbOfFams(layer0.back()); layer0.pop_back(); + _families.clear(); + for(int i=0;i fams(nbOfFamsOnGrp); + for(int j=0;j 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 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& oldCode, std::vector& newCode, DataArrayInt *& o2nRenumCell); MEDLOADER_EXPORT DataArrayInt *zipCoords(); MEDLOADER_EXPORT MEDFileUMesh *buildExtrudedMesh(const MEDCouplingUMesh *m1D, int policy) const; + // serialization + MEDLOADER_EXPORT void serialize(std::vector& tinyDouble, std::vector& tinyInt, std::vector& tinyStr, + std::vector< MEDCouplingAutoRefCountObjectPtr >& bigArraysI, MEDCouplingAutoRefCountObjectPtr& bigArrayD); + MEDLOADER_EXPORT void unserialize(std::vector& tinyDouble, std::vector& tinyInt, std::vector& tinyStr, + std::vector< MEDCouplingAutoRefCountObjectPtr >& bigArraysI, MEDCouplingAutoRefCountObjectPtr& bigArrayD); private: MEDLOADER_EXPORT ~MEDFileUMesh(); void writeLL(med_idt fid) const; diff --git a/src/MEDLoader/MEDFileMeshLL.cxx b/src/MEDLoader/MEDFileMeshLL.cxx index 7a1dbe458..7f47db748 100644 --- a/src/MEDLoader/MEDFileMeshLL.cxx +++ b/src/MEDLoader/MEDFileMeshLL.cxx @@ -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& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr >& 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& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr >& 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& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr >& bigArraysI) +{ + MEDCouplingAutoRefCountObjectPtr 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& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr >& 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;igetCellModelEnum()); + const MEDCoupling1SGTUMesh *mesh1(dynamic_cast(mesh)); + const MEDCoupling1DGTUMesh *mesh2(dynamic_cast(mesh)); + if(mesh1) + { + DataArrayInt *elt(mesh1->getNodalConnectivity()); + if(elt) + elt->incrRef(); + MEDCouplingAutoRefCountObjectPtr 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 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 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& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr >& 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 mesh(MEDCoupling1GTUMesh::New(name,tp)); + mesh->setCoords(coo); + MEDCoupling1SGTUMesh *mesh1(dynamic_cast((MEDCoupling1GTUMesh *) mesh)); + MEDCoupling1DGTUMesh *mesh2(dynamic_cast((MEDCoupling1GTUMesh *) mesh)); + if(mesh1) + { + mesh1->setNodalConnectivity(bigArraysI.back()); bigArraysI.pop_back(); + } + else if(mesh2) + { + MEDCouplingAutoRefCountObjectPtr 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(_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;ideepCpy(); + } 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;iisEqual(pd1,what)); + if(!ret) + return false; + } return true; } diff --git a/src/MEDLoader/MEDFileMeshLL.hxx b/src/MEDLoader/MEDFileMeshLL.hxx index 9be10dab9..8963d6d71 100644 --- a/src/MEDLoader/MEDFileMeshLL.hxx +++ b/src/MEDLoader/MEDFileMeshLL.hxx @@ -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& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr >& bigArraysI) const; + void unserialize(const std::string& name, DataArrayDouble *coo, std::vector& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr >& 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& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr >& bigArraysI) const; + void unserialize(const std::string& name, DataArrayDouble *coo, std::vector& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr >& bigArraysI); + // static void ClearNonDiscrAttributes(const MEDCouplingMesh *tmp); static std::vector GetNewFamiliesNumber(int nb, const std::map& families); static void TraduceFamilyNumber(const std::vector< std::vector >& fidsGrps, std::map& familyIds, std::map& famIdTrad, std::map& 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& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr >& bigArraysI); private: + MEDFileUMeshSplitL1(); void assignCommonPart(); MEDCouplingUMesh *renumIfNeeded(MEDCouplingUMesh *m, const int *cellIds) const; DataArrayInt *renumIfNeededArr(const DataArrayInt *da) const; diff --git a/src/MEDLoader/Swig/MEDLoader.i b/src/MEDLoader/Swig/MEDLoader.i index ab8d676ed..d85b63816 100644 --- a/src/MEDLoader/Swig/MEDLoader.i +++ b/src/MEDLoader/Swig/MEDLoader.i @@ -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 +%} diff --git a/src/MEDLoader/Swig/MEDLoaderCommon.i b/src/MEDLoader/Swig/MEDLoaderCommon.i index 31da32de0..e069accbc 100644 --- a/src/MEDLoader/Swig/MEDLoaderCommon.i +++ b/src/MEDLoader/Swig/MEDLoaderCommon.i @@ -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& slicPerTyp, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0) throw(INTERP_KERNEL::Exception) { std::vector 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 a0; + std::vector a1; + std::vector a2; + std::vector< MEDCouplingAutoRefCountObjectPtr > a3; + MEDCouplingAutoRefCountObjectPtr 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;iincrRef(); + 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 a0; + std::vector a1; + std::vector a2; + std::vector< MEDCouplingAutoRefCountObjectPtr > a3; + MEDCouplingAutoRefCountObjectPtr 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(argp); + if((DataArrayDouble *)a4) + a4->incrRef(); + { + std::vector< DataArrayInt * > a3Tmp; + convertFromPyObjVectorOfObj(b0py,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,"DataArrayInt",a3Tmp); + std::size_t sz(a3Tmp.size()); + a3.resize(sz); + for(std::size_t i=0;iincrRef(); + } + self->unserialize(a0,a1,a2,a3,a4); + } + } + void setMeshes(PyObject *li, bool renum=false) throw(INTERP_KERNEL::Exception) { std::vector ms; diff --git a/src/MEDLoader/Swig/MEDLoaderTest3.py b/src/MEDLoader/Swig/MEDLoaderTest3.py index 43d51acc0..19f8e6e86 100644 --- a/src/MEDLoader/Swig/MEDLoaderTest3.py +++ b/src/MEDLoader/Swig/MEDLoaderTest3.py @@ -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()