From 983b9cfa3c80af2d006aa1fe75be7863b005316d Mon Sep 17 00:00:00 2001 From: ageay Date: Fri, 17 Jun 2011 15:15:16 +0000 Subject: [PATCH] Auto multi fetching. --- src/MEDCoupling_Swig/MEDCoupling.i | 2 + src/MEDLoader/MEDFileData.cxx | 99 +++++++++++++ src/MEDLoader/MEDFileData.hxx | 54 +++++++ src/MEDLoader/MEDFileField.cxx | 186 +++++++++++++++++++++--- src/MEDLoader/MEDFileField.hxx | 20 ++- src/MEDLoader/MEDFileMesh.cxx | 206 +++++++++++++++++++++++++++ src/MEDLoader/MEDFileMesh.hxx | 42 +++++- src/MEDLoader/Swig/MEDLoader.i | 88 +++++++++++- src/MEDLoader/Swig/MEDLoaderTest3.py | 39 +++++ 9 files changed, 710 insertions(+), 26 deletions(-) create mode 100644 src/MEDLoader/MEDFileData.cxx create mode 100644 src/MEDLoader/MEDFileData.hxx diff --git a/src/MEDCoupling_Swig/MEDCoupling.i b/src/MEDCoupling_Swig/MEDCoupling.i index b2df2ddf7..65261b0c8 100644 --- a/src/MEDCoupling_Swig/MEDCoupling.i +++ b/src/MEDCoupling_Swig/MEDCoupling.i @@ -272,6 +272,8 @@ using namespace INTERP_KERNEL; %feature("unref") MEDCouplingField "$this->decrRef();" %feature("unref") MEDCouplingFieldDouble "$this->decrRef();" %feature("unref") MEDCouplingMultiFields "$this->decrRef();" +%feature("unref") MEDCouplingFieldTemplate "$this->decrRef();" +%feature("unref") MEDCouplingMultiFields "$this->decrRef();" %rename(assign) *::operator=; %ignore ParaMEDMEM::RefCountObject::decrRef; diff --git a/src/MEDLoader/MEDFileData.cxx b/src/MEDLoader/MEDFileData.cxx new file mode 100644 index 000000000..7f9d1804a --- /dev/null +++ b/src/MEDLoader/MEDFileData.cxx @@ -0,0 +1,99 @@ +// Copyright (C) 2007-2011 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "MEDFileData.hxx" + +using namespace ParaMEDMEM; + +MEDFileData *MEDFileData::New(const char *fileName) throw(INTERP_KERNEL::Exception) +{ + return new MEDFileData(fileName); +} + +MEDFileData *MEDFileData::New() +{ + return new MEDFileData; +} + +MEDFileFields *MEDFileData::getFields() const +{ + return const_cast(static_cast(_fields)); +} + +MEDFileMeshes *MEDFileData::getMeshes() const +{ + return const_cast(static_cast(_meshes)); +} + +void MEDFileData::setFields(MEDFileFields *fields) throw(INTERP_KERNEL::Exception) +{ + if(!fields) + throw INTERP_KERNEL::Exception("MEDFileData::setFields : input pointer is null !"); + fields->incrRef(); + _fields=fields; +} + +void MEDFileData::setMeshes(MEDFileMeshes *meshes) throw(INTERP_KERNEL::Exception) +{ + if(!meshes) + throw INTERP_KERNEL::Exception("MEDFileData::setMeshes : input pointer is null !"); + meshes->incrRef(); + _meshes=meshes; +} + +int MEDFileData::getNumberOfFields() const throw(INTERP_KERNEL::Exception) +{ + const MEDFileFields *f=_fields; + if(!f) + throw INTERP_KERNEL::Exception("MEDFileData::getNumberOfFields : no fields set !"); + return f->getNumberOfFields(); +} + +int MEDFileData::getNumberOfMeshes() const throw(INTERP_KERNEL::Exception) +{ + const MEDFileMeshes *m=_meshes; + if(!m) + throw INTERP_KERNEL::Exception("MEDFileData::getNumberOfMeshes : no meshes set !"); + return m->getNumberOfMeshes(); +} + +MEDFileData::MEDFileData() +{ +} + +MEDFileData::MEDFileData(const char *fileName) throw(INTERP_KERNEL::Exception) +try + { + _fields=MEDFileFields::New(fileName); + _meshes=MEDFileMeshes::New(fileName); + } +catch(INTERP_KERNEL::Exception& e) + { + throw e; + } + +void MEDFileData::write(const char *fileName, int mode) const throw(INTERP_KERNEL::Exception) +{ + const MEDFileMeshes *ms=_meshes; + if(ms) + ms->write(fileName,mode); + const MEDFileFields *fs=_fields; + if(fs) + fs->write(fileName,mode); +} diff --git a/src/MEDLoader/MEDFileData.hxx b/src/MEDLoader/MEDFileData.hxx new file mode 100644 index 000000000..2fb00eaf2 --- /dev/null +++ b/src/MEDLoader/MEDFileData.hxx @@ -0,0 +1,54 @@ +// Copyright (C) 2007-2011 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef __MEDFILEDATA_HXX__ +#define __MEDFILEDATA_HXX__ + +#include "MEDCouplingAutoRefCountObjectPtr.hxx" +#include "MEDFileField.hxx" +#include "MEDFileMesh.hxx" + +namespace ParaMEDMEM +{ + /*! + * User class. + */ + class MEDFileData : public RefCountObject, public MEDFileWritable + { + public: + static MEDFileData *New(const char *fileName) throw(INTERP_KERNEL::Exception); + static MEDFileData *New(); + MEDFileFields *getFields() const; + MEDFileMeshes *getMeshes() const; + void setFields(MEDFileFields *fields) throw(INTERP_KERNEL::Exception); + void setMeshes(MEDFileMeshes *meshes) throw(INTERP_KERNEL::Exception); + int getNumberOfFields() const throw(INTERP_KERNEL::Exception); + int getNumberOfMeshes() const throw(INTERP_KERNEL::Exception); + // + void write(const char *fileName, int mode) const throw(INTERP_KERNEL::Exception); + private: + MEDFileData(); + MEDFileData(const char *fileName) throw(INTERP_KERNEL::Exception); + private: + MEDCouplingAutoRefCountObjectPtr _fields; + MEDCouplingAutoRefCountObjectPtr _meshes; + }; +} + +#endif diff --git a/src/MEDLoader/MEDFileField.cxx b/src/MEDLoader/MEDFileField.cxx index 1ff27e908..e5832ec7e 100644 --- a/src/MEDLoader/MEDFileField.cxx +++ b/src/MEDLoader/MEDFileField.cxx @@ -530,7 +530,10 @@ void MEDFileFieldPerMeshPerType::finishLoading(med_idt fid, TypeOfField type) th void MEDFileFieldPerMeshPerType::writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception) { for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++) - (*it)->writeLL(fid); + { + (*it)->copyOptionsFrom(*this); + (*it)->writeLL(fid); + } } med_entity_type MEDFileFieldPerMeshPerType::ConvertIntoMEDFileType(TypeOfField ikType, INTERP_KERNEL::NormalizedCellType ikGeoType, med_geometry_type& medfGeoType) @@ -630,7 +633,10 @@ void MEDFileFieldPerMesh::writeLL(med_idt fid) const throw(INTERP_KERNEL::Except { int nbOfTypes=_field_pm_pt.size(); for(int i=0;iwriteLL(fid); + { + _field_pm_pt[i]->copyOptionsFrom(*this); + _field_pm_pt[i]->writeLL(fid); + } } void MEDFileFieldPerMesh::getDimension(int& dim) const @@ -1305,9 +1311,36 @@ void MEDFileField1TSWithoutDAS::writeLL(med_idt fid) const throw(INTERP_KERNEL:: throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutDAS::writeLL : empty field !"); if(_field_per_mesh.size()>1) throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutDAS::writeLL : In MED3.0 mode in writting mode only ONE underlying mesh supported !"); + _field_per_mesh[0]->copyOptionsFrom(*this); _field_per_mesh[0]->writeLL(fid); } +/*! + * SBT means Sort By Type. + * This method is the most basic method to assign field in this. Basic in sense that no renumbering is done. Underlying mesh in 'field' is globaly ignored except for type contiguous check. + * + */ +void MEDFileField1TSWithoutDAS::setFieldNoProfileSBT(const MEDCouplingFieldDouble *field, MEDFieldFieldGlobs& glob) throw(INTERP_KERNEL::Exception) +{ + const MEDCouplingMesh *mesh=field->getMesh(); + // + TypeOfField type=field->getTypeOfField(); + if(type!=ON_NODES) + { + std::vector code=MEDFileField1TSWithoutDAS::CheckSBTMesh(mesh); + copyTinyInfoFrom(field); + // + int pos=addNewEntryIfNecessary(mesh); + _field_per_mesh[pos]->assignFieldNoProfile(code,field,glob); + } + else + { + copyTinyInfoFrom(field); + int pos=addNewEntryIfNecessary(mesh); + _field_per_mesh[pos]->assignNodeFieldNoProfile(field,glob); + } +} + MEDCouplingFieldDouble *MEDFileField1TSWithoutDAS::getFieldAtLevel(TypeOfField type, int meshDimRelToMax, const char *mName, int renumPol, const MEDFieldFieldGlobs *glob) const throw(INTERP_KERNEL::Exception) { MEDCouplingAutoRefCountObjectPtr mm; @@ -1602,23 +1635,7 @@ MEDCouplingFieldDouble *MEDFileField1TS::getFieldAtLevelOld(TypeOfField type, co void MEDFileField1TS::setFieldNoProfileSBT(const MEDCouplingFieldDouble *field) throw(INTERP_KERNEL::Exception) { _file_name=""; - const MEDCouplingMesh *mesh=field->getMesh(); - // - TypeOfField type=field->getTypeOfField(); - if(type!=ON_NODES) - { - std::vector code=MEDFileField1TSWithoutDAS::CheckSBTMesh(mesh); - copyTinyInfoFrom(field); - // - int pos=addNewEntryIfNecessary(mesh); - _field_per_mesh[pos]->assignFieldNoProfile(code,field,*this); - } - else - { - copyTinyInfoFrom(field); - int pos=addNewEntryIfNecessary(mesh); - _field_per_mesh[pos]->assignNodeFieldNoProfile(field,*this); - } + MEDFileField1TSWithoutDAS::setFieldNoProfileSBT(field,*this); } MEDFileFieldMultiTSWithoutDAS *MEDFileFieldMultiTSWithoutDAS::New(med_idt fid, const char *fieldName, int id, const std::vector& infos, int nbOfStep) throw(INTERP_KERNEL::Exception) @@ -1626,12 +1643,16 @@ MEDFileFieldMultiTSWithoutDAS *MEDFileFieldMultiTSWithoutDAS::New(med_idt fid, c return new MEDFileFieldMultiTSWithoutDAS(fid,fieldName,id,infos,nbOfStep); } +MEDFileFieldMultiTSWithoutDAS::MEDFileFieldMultiTSWithoutDAS() +{ +} + MEDFileFieldMultiTSWithoutDAS::MEDFileFieldMultiTSWithoutDAS(const char *fieldName):_name(fieldName) { } MEDFileFieldMultiTSWithoutDAS::MEDFileFieldMultiTSWithoutDAS(med_idt fid, const char *fieldName, int id, const std::vector& infos, int nbOfStep) throw(INTERP_KERNEL::Exception) -try:_name(fieldName) +try:_name(fieldName),_infos(infos) { finishLoading(fid,nbOfStep); } @@ -1676,6 +1697,41 @@ void MEDFileFieldMultiTSWithoutDAS::finishLoading(med_idt fid, int nbPdt) throw( } } +void MEDFileFieldMultiTSWithoutDAS::copyTinyInfoFrom(const MEDCouplingFieldDouble *field) throw(INTERP_KERNEL::Exception) +{ + _name=field->getName(); + if(_name.empty()) + throw INTERP_KERNEL::Exception("MEDFileFieldMultiTSWithoutDAS::copyTinyInfoFrom : unsupported fields with no name in MED file !"); + const DataArrayDouble *arr=field->getArray(); + if(!arr) + throw INTERP_KERNEL::Exception("MEDFileFieldMultiTSWithoutDAS::copyTinyInfoFrom : no array set !"); + _infos=arr->getInfoOnComponent(); +} + +void MEDFileFieldMultiTSWithoutDAS::checkCoherencyOfTinyInfo(const MEDCouplingFieldDouble *field) const throw(INTERP_KERNEL::Exception) +{ + static const char MSG[]="MEDFileFieldMultiTSWithoutDAS::checkCoherencyOfTinyInfo : invalid "; + if(_name!=field->getName()) + { + std::ostringstream oss; oss << MSG << "name ! should be \"" << _name; + oss << "\" and it is set in input field to \"" << field->getName() << "\" !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + const DataArrayDouble *arr=field->getArray(); + if(!arr) + throw INTERP_KERNEL::Exception("MEDFileFieldMultiTSWithoutDAS::checkCoherencyOfTinyInfo : no array set !"); + if(_infos!=arr->getInfoOnComponent()) + { + std::ostringstream oss; oss << MSG << "components ! should be \""; + std::copy(_infos.begin(),_infos.end(),std::ostream_iterator(oss,", ")); + oss << " But compo in input fields are : "; + std::vector tmp=arr->getInfoOnComponent(); + std::copy(tmp.begin(),tmp.end(),std::ostream_iterator(oss,", ")); + oss << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } +} + void MEDFileFieldMultiTSWithoutDAS::writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception) { if(_time_steps.empty()) @@ -1773,6 +1829,11 @@ std::vector MEDFileFieldMultiTSWithoutDAS::getLocsReallyUsed2() con return ret; } +MEDFileFieldMultiTS *MEDFileFieldMultiTS::New() +{ + return new MEDFileFieldMultiTS; +} + MEDFileFieldMultiTS *MEDFileFieldMultiTS::New(const char *fileName, const char *fieldName) throw(INTERP_KERNEL::Exception) { return new MEDFileFieldMultiTS(fileName,fieldName); @@ -1822,6 +1883,28 @@ MEDCouplingFieldDouble *MEDFileFieldMultiTS::getFieldAtLevelOld(TypeOfField type return myF1TS.getFieldAtLevel(type,meshDimRelToMax,mname,renumPol,this); } +void MEDFileFieldMultiTS::appendFieldNoProfileSBT(const MEDCouplingFieldDouble *field) throw(INTERP_KERNEL::Exception) +{ + if(_time_steps.empty()) + { + MEDCouplingAutoRefCountObjectPtr obj=new MEDFileField1TSWithoutDAS; + obj->setFieldNoProfileSBT(field,*this); + copyTinyInfoFrom(field); + _time_steps.push_back(obj); + } + else + { + checkCoherencyOfTinyInfo(field); + MEDCouplingAutoRefCountObjectPtr obj=new MEDFileField1TSWithoutDAS; + obj->setFieldNoProfileSBT(field,*this); + _time_steps.push_back(obj); + } +} + +MEDFileFieldMultiTS::MEDFileFieldMultiTS() +{ +} + MEDFileFieldMultiTS::MEDFileFieldMultiTS(const char *fileName, const char *fieldName) throw(INTERP_KERNEL::Exception) try:MEDFileFieldMultiTSWithoutDAS(fieldName),MEDFieldFieldGlobs(fileName) { @@ -1878,6 +1961,11 @@ std::vector MEDFileFieldMultiTS::getLocsReallyUsed() const return getLocsReallyUsed2(); } +MEDFileFields *MEDFileFields::New() +{ + return new MEDFileFields; +} + MEDFileFields *MEDFileFields::New(const char *fileName) throw(INTERP_KERNEL::Exception) { return new MEDFileFields(fileName); @@ -1888,6 +1976,10 @@ int MEDFileFields::getNumberOfFields() const return _fields.size(); } +MEDFileFields::MEDFileFields() +{ +} + MEDFileFields::MEDFileFields(const char *fileName) throw(INTERP_KERNEL::Exception) try:MEDFieldFieldGlobs(fileName) { @@ -1909,8 +2001,8 @@ try:MEDFieldFieldGlobs(fileName) MEDfieldInfo(fid,i+1,nomcha,nomMaa,&localMesh,&typcha,comp,unit,dtunit,&nbOfStep); std::vector infos(ncomp); for(int j=0;j >::const_iterator it=_fields.begin();it!=_fields.end();it++,i++) + { + const MEDFileFieldMultiTSWithoutDAS *elt=*it; + if(!elt) + { + std::ostringstream oss; oss << "MEDFileFields::write : at rank #" << i << "/" << _fields.size() << " field is empty !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + elt->copyOptionsFrom(*this); + elt->writeLL(fid); + } +} + std::vector MEDFileFields::getPflsReallyUsed() const { std::vector ret; @@ -1956,3 +2066,35 @@ std::vector MEDFileFields::getLocsReallyUsed() const return ret; } +void MEDFileFields::resize(int newSize) throw(INTERP_KERNEL::Exception) +{ + _fields.resize(newSize); +} + +void MEDFileFields::pushField(MEDFileFieldMultiTS *field) throw(INTERP_KERNEL::Exception) +{ + if(!field) + throw INTERP_KERNEL::Exception("MEDFileFields::pushMesh : invalid input pointer ! should be different from 0 !"); + field->incrRef(); + _fields.push_back(field); +} + +void MEDFileFields::setFieldAtPos(int i, MEDFileFieldMultiTS *field) throw(INTERP_KERNEL::Exception) +{ + if(!field) + throw INTERP_KERNEL::Exception("MEDFileFields::setFieldAtPos : invalid input pointer ! should be different from 0 !"); + if(i>=_fields.size()) + _fields.resize(i+1); + field->incrRef(); + _fields[i]=field; +} + +void MEDFileFields::destroyFieldAtPos(int i) throw(INTERP_KERNEL::Exception) +{ + if(i<0 || i>=_fields.size()) + { + std::ostringstream oss; oss << "MEDFileFields::destroyMeshAtPos : Invalid given id in input (" << i << ") should be in [0," << _fields.size() << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + _fields.erase(_fields.begin()+i); +} diff --git a/src/MEDLoader/MEDFileField.hxx b/src/MEDLoader/MEDFileField.hxx index 36675bf1f..b1d90a3f7 100644 --- a/src/MEDLoader/MEDFileField.hxx +++ b/src/MEDLoader/MEDFileField.hxx @@ -252,6 +252,8 @@ namespace ParaMEDMEM std::vector getLocsReallyUsed2() const; static void CheckMeshDimRel(int meshDimRelToMax) throw(INTERP_KERNEL::Exception); static std::vector CheckSBTMesh(const MEDCouplingMesh *mesh) throw(INTERP_KERNEL::Exception); + // + void setFieldNoProfileSBT(const MEDCouplingFieldDouble *field, MEDFieldFieldGlobs& glob) throw(INTERP_KERNEL::Exception); public: MEDCouplingFieldDouble *getFieldAtLevel(TypeOfField type, int meshDimRelToMax, const char *mName, int renumPol, const MEDFieldFieldGlobs *glob) const throw(INTERP_KERNEL::Exception); MEDCouplingFieldDouble *getFieldOnMeshAtLevel(TypeOfField type, int meshDimRelToMax, int renumPol, const MEDFieldFieldGlobs *glob, const MEDFileMesh *mesh) const throw(INTERP_KERNEL::Exception); @@ -260,6 +262,7 @@ namespace ParaMEDMEM int addNewEntryIfNecessary(const MEDCouplingMesh *mesh) throw(INTERP_KERNEL::Exception); int getMeshIdFromMeshName(const char *mName) const throw(INTERP_KERNEL::Exception); MEDFileField1TSWithoutDAS(const char *fieldName, int csit, int iteration, int order, const std::vector& infos); + public: MEDFileField1TSWithoutDAS(); protected: std::string _name; @@ -301,6 +304,7 @@ namespace ParaMEDMEM static MEDFileFieldMultiTSWithoutDAS *New(med_idt fid, const char *fieldName, int id, const std::vector& infos, int nbOfStep) throw(INTERP_KERNEL::Exception); int getNumberOfTS() const; std::vector< std::pair > getIterations() const; + void writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception); public: std::vector getPflsReallyUsed2() const; std::vector getLocsReallyUsed2() const; @@ -310,10 +314,12 @@ namespace ParaMEDMEM const std::vector& getInfo() const throw(INTERP_KERNEL::Exception); std::string getMeshName() const throw(INTERP_KERNEL::Exception); std::string getDtUnit() const throw(INTERP_KERNEL::Exception); + MEDFileFieldMultiTSWithoutDAS(); MEDFileFieldMultiTSWithoutDAS(const char *fieldName); MEDFileFieldMultiTSWithoutDAS(med_idt fid, const char *fieldName, int id, const std::vector& infos, int nbOfStep) throw(INTERP_KERNEL::Exception); void finishLoading(med_idt fid, int nbPdt) throw(INTERP_KERNEL::Exception); - void writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception); + void copyTinyInfoFrom(const MEDCouplingFieldDouble *field) throw(INTERP_KERNEL::Exception); + void checkCoherencyOfTinyInfo(const MEDCouplingFieldDouble *field) const throw(INTERP_KERNEL::Exception); protected: std::string _name; std::vector _infos; @@ -326,16 +332,20 @@ namespace ParaMEDMEM class MEDFileFieldMultiTS : public MEDFileFieldMultiTSWithoutDAS, public MEDFieldFieldGlobs { public: + static MEDFileFieldMultiTS *New(); static MEDFileFieldMultiTS *New(const char *fileName, const char *fieldName) throw(INTERP_KERNEL::Exception); void write(const char *fileName, int mode) const throw(INTERP_KERNEL::Exception); MEDCouplingFieldDouble *getFieldAtLevel(TypeOfField type, int iteration, int order, int meshDimRelToMax, int renumPol=0) const throw(INTERP_KERNEL::Exception); MEDCouplingFieldDouble *getFieldOnMeshAtLevel(TypeOfField type, int iteration, int order, int meshDimRelToMax, const MEDFileMesh *mesh, int renumPol=0) const throw(INTERP_KERNEL::Exception); MEDCouplingFieldDouble *getFieldOnMeshAtLevel(TypeOfField type, int iteration, int order, const MEDCouplingMesh *mesh, int renumPol=0) const throw(INTERP_KERNEL::Exception); MEDCouplingFieldDouble *getFieldAtLevelOld(TypeOfField type, const char *mname, int iteration, int order, int meshDimRelToMax, int renumPol=0) const throw(INTERP_KERNEL::Exception); + // + void appendFieldNoProfileSBT(const MEDCouplingFieldDouble *field) throw(INTERP_KERNEL::Exception); private: std::vector getPflsReallyUsed() const; std::vector getLocsReallyUsed() const; private: + MEDFileFieldMultiTS(); MEDFileFieldMultiTS(const char *fileName, const char *fieldName) throw(INTERP_KERNEL::Exception); }; @@ -345,12 +355,20 @@ namespace ParaMEDMEM class MEDFileFields : public RefCountObject, public MEDFieldFieldGlobs, public MEDFileWritable { public: + static MEDFileFields *New(); static MEDFileFields *New(const char *fileName) throw(INTERP_KERNEL::Exception); + void write(const char *fileName, int mode) const throw(INTERP_KERNEL::Exception); int getNumberOfFields() const; + // + void resize(int newSize) throw(INTERP_KERNEL::Exception); + void pushField(MEDFileFieldMultiTS *field) throw(INTERP_KERNEL::Exception); + void setFieldAtPos(int i, MEDFileFieldMultiTS *field) throw(INTERP_KERNEL::Exception); + void destroyFieldAtPos(int i) throw(INTERP_KERNEL::Exception); private: std::vector getPflsReallyUsed() const; std::vector getLocsReallyUsed() const; private: + MEDFileFields(); MEDFileFields(const char *fileName) throw(INTERP_KERNEL::Exception); private: std::vector< MEDCouplingAutoRefCountObjectPtr > _fields; diff --git a/src/MEDLoader/MEDFileMesh.cxx b/src/MEDLoader/MEDFileMesh.cxx index 3d66475b0..4c03dd94d 100644 --- a/src/MEDLoader/MEDFileMesh.cxx +++ b/src/MEDLoader/MEDFileMesh.cxx @@ -1975,3 +1975,209 @@ const DataArrayInt *MEDFileCMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxEx throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no node renumbering for a request on reverse numbering !"); } } + + +MEDFileMeshMultiTS *MEDFileMeshMultiTS::New() +{ + return new MEDFileMeshMultiTS; +} + +MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const char *fileName) throw(INTERP_KERNEL::Exception) +{ + return new MEDFileMeshMultiTS(fileName); +} + +MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const char *fileName, const char *mName) throw(INTERP_KERNEL::Exception) +{ + return new MEDFileMeshMultiTS(fileName,mName); +} + +const char *MEDFileMeshMultiTS::getName() const throw(INTERP_KERNEL::Exception) +{ + if(_mesh_one_ts.empty()) + throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getName : no time steps set !"); + return _mesh_one_ts[0]->getName(); +} + +MEDFileMesh *MEDFileMeshMultiTS::getOneTimeStep() const throw(INTERP_KERNEL::Exception) +{ + if(_mesh_one_ts.empty()) + throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getOneTimeStep : empty time step set !"); + return const_cast(static_cast(_mesh_one_ts[0])); +} + +void MEDFileMeshMultiTS::setOneTimeStep(MEDFileMesh *mesh1TimeStep) throw(INTERP_KERNEL::Exception) +{ + if(!mesh1TimeStep) + throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::setOneTimeStep : input pointer should be different from 0 !"); + _mesh_one_ts.resize(1); + mesh1TimeStep->incrRef(); + //MEDCouplingAutoRefCountObjectPtr toto=mesh1TimeStep; + _mesh_one_ts[0]=mesh1TimeStep; +} + +void MEDFileMeshMultiTS::write(const char *fileName, int mode) const throw(INTERP_KERNEL::Exception) +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++) + { + (*it)->copyOptionsFrom(*this); + (*it)->write(fileName,mode); + } +} + +void MEDFileMeshMultiTS::loadFromFile(const char *fileName, const char *mName) throw(INTERP_KERNEL::Exception) +{//for the moment to be improved + _mesh_one_ts.resize(1); + _mesh_one_ts[0]=MEDFileMesh::New(fileName,mName,-1,-1); +} + +MEDFileMeshMultiTS::MEDFileMeshMultiTS() +{ +} + +MEDFileMeshMultiTS::MEDFileMeshMultiTS(const char *fileName) throw(INTERP_KERNEL::Exception) +try + { + std::vector ms=MEDLoader::GetMeshNames(fileName); + if(ms.empty()) + { + std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + MEDFileUtilities::CheckFileForRead(fileName); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY); + int dt,it; + ParaMEDMEM::MEDCouplingMeshType meshType; + std::string dummy2; + MEDFileMeshL2::GetMeshIdFromName(fid,ms.front().c_str(),meshType,dt,it,dummy2); + loadFromFile(fileName,ms.front().c_str()); + } +catch(INTERP_KERNEL::Exception& e) + { + throw e; + } + +MEDFileMeshMultiTS::MEDFileMeshMultiTS(const char *fileName, const char *mName) throw(INTERP_KERNEL::Exception) +try + { + loadFromFile(fileName,mName); + } +catch(INTERP_KERNEL::Exception& e) + { + throw e; + } + +MEDFileMeshes *MEDFileMeshes::New() +{ + return new MEDFileMeshes; +} + +MEDFileMeshes *MEDFileMeshes::New(const char *fileName) throw(INTERP_KERNEL::Exception) +{ + return new MEDFileMeshes(fileName); +} + +void MEDFileMeshes::write(const char *fileName, int mode) const throw(INTERP_KERNEL::Exception) +{ + checkCoherency(); + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_meshes.begin();it!=_meshes.end();it++) + { + (*it)->copyOptionsFrom(*this); + (*it)->write(fileName,mode); + } +} + +int MEDFileMeshes::getNumberOfMeshes() const throw(INTERP_KERNEL::Exception) +{ + return _meshes.size(); +} + +MEDFileMesh *MEDFileMeshes::getMeshAtPos(int i) const throw(INTERP_KERNEL::Exception) +{ + if(i<0 || i>=(int)_meshes.size()) + { + std::ostringstream oss; oss << "MEDFileMeshes::getMeshAtPos : invalid mesh id given in parameter ! Should be in [0;" << _meshes.size() << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + return _meshes[i]->getOneTimeStep(); +} + +void MEDFileMeshes::resize(int newSize) throw(INTERP_KERNEL::Exception) +{ + _meshes.resize(newSize); +} + +void MEDFileMeshes::pushMesh(MEDFileMesh *mesh) throw(INTERP_KERNEL::Exception) +{ + if(!mesh) + throw INTERP_KERNEL::Exception("MEDFileMeshes::pushMesh : invalid input pointer ! should be different from 0 !"); + MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New(); + elt->setOneTimeStep(mesh); + _meshes.push_back(elt); +} + +void MEDFileMeshes::setMeshAtPos(int i, MEDFileMesh *mesh) throw(INTERP_KERNEL::Exception) +{ + if(!mesh) + throw INTERP_KERNEL::Exception("MEDFileMeshes::setMeshAtPos : invalid input pointer ! should be different from 0 !"); + if(i>=_meshes.size()) + _meshes.resize(i+1); + MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New(); + elt->setOneTimeStep(mesh); + _meshes[i]=elt; +} + +void MEDFileMeshes::destroyMeshAtPos(int i) throw(INTERP_KERNEL::Exception) +{ + if(i<0 || i>=_meshes.size()) + { + std::ostringstream oss; oss << "MEDFileMeshes::destroyMeshAtPos : Invalid given id in input (" << i << ") should be in [0," << _meshes.size() << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + _meshes.erase(_meshes.begin()+i); +} + +void MEDFileMeshes::loadFromFile(const char *fileName) throw(INTERP_KERNEL::Exception) +{ + std::vector ms=MEDLoader::GetMeshNames(fileName); + int i=0; + _meshes.resize(ms.size()); + for(std::vector::const_iterator it=ms.begin();it!=ms.end();it++,i++) + _meshes[i]=MEDFileMeshMultiTS::New(fileName,(*it).c_str()); +} + +MEDFileMeshes::MEDFileMeshes() +{ +} + +MEDFileMeshes::MEDFileMeshes(const char *fileName) throw(INTERP_KERNEL::Exception) +try + { + loadFromFile(fileName); + } +catch(INTERP_KERNEL::Exception& e) + { + } + +void MEDFileMeshes::checkCoherency() const throw(INTERP_KERNEL::Exception) +{ + static const char MSG[]="MEDFileMeshes::checkCoherency : mesh at rank "; + int i=0; + std::set s; + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++) + { + const MEDFileMeshMultiTS *elt=(*it); + if(!elt) + { + std::ostringstream oss; oss << MSG << i << "/" << _meshes.size() << " is empty !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + std::size_t sz=s.size(); + s.insert(std::string((*it)->getName())); + if(s.size()==sz) + { + std::ostringstream oss; oss << MSG << i << " has a name (\"" << (*it)->getName() << "\") already used by an another mesh in list !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } +} diff --git a/src/MEDLoader/MEDFileMesh.hxx b/src/MEDLoader/MEDFileMesh.hxx index 257e68111..cc8b78e69 100644 --- a/src/MEDLoader/MEDFileMesh.hxx +++ b/src/MEDLoader/MEDFileMesh.hxx @@ -190,7 +190,6 @@ namespace ParaMEDMEM mutable MEDCouplingAutoRefCountObjectPtr _rev_num_coords; }; - class MEDFileCMesh : public MEDFileMesh { friend class MEDFileMesh; @@ -226,6 +225,47 @@ namespace ParaMEDMEM mutable MEDCouplingAutoRefCountObjectPtr _rev_num_nodes; mutable MEDCouplingAutoRefCountObjectPtr _rev_num_cells; }; + + class MEDFileMeshMultiTS : public RefCountObject, public MEDFileWritable + { + public: + static MEDFileMeshMultiTS *New(); + static MEDFileMeshMultiTS *New(const char *fileName) throw(INTERP_KERNEL::Exception); + static MEDFileMeshMultiTS *New(const char *fileName, const char *mName) throw(INTERP_KERNEL::Exception); + const char *getName() const throw(INTERP_KERNEL::Exception); + MEDFileMesh *getOneTimeStep() const throw(INTERP_KERNEL::Exception); + void write(const char *fileName, int mode) const throw(INTERP_KERNEL::Exception); + void setOneTimeStep(MEDFileMesh *mesh1TimeStep) throw(INTERP_KERNEL::Exception); + private: + void loadFromFile(const char *fileName, const char *mName) throw(INTERP_KERNEL::Exception); + MEDFileMeshMultiTS(); + MEDFileMeshMultiTS(const char *fileName) throw(INTERP_KERNEL::Exception); + MEDFileMeshMultiTS(const char *fileName, const char *mName) throw(INTERP_KERNEL::Exception); + private: + std::vector< MEDCouplingAutoRefCountObjectPtr > _mesh_one_ts; + }; + + class MEDFileMeshes : public RefCountObject, public MEDFileWritable + { + public: + static MEDFileMeshes *New(); + static MEDFileMeshes *New(const char *fileName) throw(INTERP_KERNEL::Exception); + void write(const char *fileName, int mode) const throw(INTERP_KERNEL::Exception); + int getNumberOfMeshes() const throw(INTERP_KERNEL::Exception); + MEDFileMesh *getMeshAtPos(int i) const throw(INTERP_KERNEL::Exception); + // + void resize(int newSize) throw(INTERP_KERNEL::Exception); + void pushMesh(MEDFileMesh *mesh) throw(INTERP_KERNEL::Exception); + void setMeshAtPos(int i, MEDFileMesh *mesh) throw(INTERP_KERNEL::Exception); + void destroyMeshAtPos(int i) throw(INTERP_KERNEL::Exception); + private: + void checkCoherency() const throw(INTERP_KERNEL::Exception); + void loadFromFile(const char *fileName) throw(INTERP_KERNEL::Exception); + MEDFileMeshes(); + MEDFileMeshes(const char *fileName) throw(INTERP_KERNEL::Exception); + private: + std::vector< MEDCouplingAutoRefCountObjectPtr > _meshes; + }; } #endif diff --git a/src/MEDLoader/Swig/MEDLoader.i b/src/MEDLoader/Swig/MEDLoader.i index 76897ec63..8f8dc2e4a 100644 --- a/src/MEDLoader/Swig/MEDLoader.i +++ b/src/MEDLoader/Swig/MEDLoader.i @@ -28,6 +28,7 @@ #include "MEDLoader.hxx" #include "MEDFileMesh.hxx" #include "MEDFileField.hxx" +#include "MEDFileData.hxx" #include "MEDLoaderTypemaps.i" using namespace ParaMEDMEM; @@ -72,6 +73,10 @@ using namespace ParaMEDMEM; %newobject ParaMEDMEM::MEDFileUMesh::getLevelM2Mesh; %newobject ParaMEDMEM::MEDFileUMesh::getLevelM3Mesh; %newobject ParaMEDMEM::MEDFileCMesh::New; +%newobject ParaMEDMEM::MEDFileMeshMultiTS::New; +%newobject ParaMEDMEM::MEDFileMeshMultiTS::getOneTimeStep; +%newobject ParaMEDMEM::MEDFileMeshes::New; +%newobject ParaMEDMEM::MEDFileMeshes::getMeshAtPos; %newobject ParaMEDMEM::MEDFileFields::New; %newobject ParaMEDMEM::MEDFileFieldMultiTS::New; @@ -83,6 +88,17 @@ using namespace ParaMEDMEM; %newobject ParaMEDMEM::MEDFileField1TS::getFieldOnMeshAtLevel; %newobject ParaMEDMEM::MEDFileField1TS::getFieldAtLevelOld; +%newobject ParaMEDMEM::MEDFileData::New; + +%feature("unref") MEDFileMesh "$this->decrRef();" +%feature("unref") MEDFileUMesh "$this->decrRef();" +%feature("unref") MEDFileCMesh "$this->decrRef();" +%feature("unref") MEDFileMeshMultiTS "$this->decrRef();" +%feature("unref") MEDFileMeshes "$this->decrRef();" +%feature("unref") MEDFileField1TS "$this->decrRef();" +%feature("unref") MEDFileFieldMultiTS "$this->decrRef();" +%feature("unref") MEDFileFields "$this->decrRef();" + class MEDLoader { public: @@ -450,6 +466,51 @@ namespace ParaMEDMEM } }; + class MEDFileMeshMultiTS : public RefCountObject, public MEDFileWritable + { + public: + static MEDFileMeshMultiTS *New(); + static MEDFileMeshMultiTS *New(const char *fileName) throw(INTERP_KERNEL::Exception); + static MEDFileMeshMultiTS *New(const char *fileName, const char *mName) throw(INTERP_KERNEL::Exception); + const char *getName() const throw(INTERP_KERNEL::Exception); + void write(const char *fileName, int mode) const throw(INTERP_KERNEL::Exception); + void setOneTimeStep(MEDFileMesh *mesh1TimeStep) throw(INTERP_KERNEL::Exception); + %extend + { + MEDFileMesh *getOneTimeStep() const throw(INTERP_KERNEL::Exception) + { + MEDFileMesh *ret=self->getOneTimeStep(); + if(ret) + ret->incrRef(); + return ret; + } + } + }; + + class MEDFileMeshes : public RefCountObject, public MEDFileWritable + { + public: + static MEDFileMeshes *New(); + static MEDFileMeshes *New(const char *fileName) throw(INTERP_KERNEL::Exception); + void write(const char *fileName, int mode) const throw(INTERP_KERNEL::Exception); + int getNumberOfMeshes() const throw(INTERP_KERNEL::Exception); + // + void resize(int newSize) throw(INTERP_KERNEL::Exception); + void pushMesh(MEDFileMesh *mesh) throw(INTERP_KERNEL::Exception); + void setMeshAtPos(int i, MEDFileMesh *mesh) throw(INTERP_KERNEL::Exception); + void destroyMeshAtPos(int i) throw(INTERP_KERNEL::Exception); + %extend + { + MEDFileMesh *getMeshAtPos(int i) const throw(INTERP_KERNEL::Exception) + { + MEDFileMesh *ret=self->getMeshAtPos(i); + if(ret) + ret->incrRef(); + return ret; + } + } + }; + class MEDFieldFieldGlobs { public: @@ -525,20 +586,43 @@ namespace ParaMEDMEM class MEDFileFieldMultiTS : public MEDFileFieldMultiTSWithoutDAS, public MEDFieldFieldGlobs, public MEDFileWritable { public: + static MEDFileFieldMultiTS *New(); static MEDFileFieldMultiTS *New(const char *fileName, const char *fieldName) throw(INTERP_KERNEL::Exception); void write(const char *fileName, int mode) const throw(INTERP_KERNEL::Exception); MEDCouplingFieldDouble *getFieldAtLevel(TypeOfField type, int iteration, int order, int meshDimRelToMax, int renumPol=0) const throw(INTERP_KERNEL::Exception); MEDCouplingFieldDouble *getFieldOnMeshAtLevel(TypeOfField type, int iteration, int order, int meshDimRelToMax, const MEDFileMesh *mesh, int renumPol=0) const throw(INTERP_KERNEL::Exception); MEDCouplingFieldDouble *getFieldOnMeshAtLevel(TypeOfField type, int iteration, int order, const MEDCouplingMesh *mesh, int renumPol=0) const throw(INTERP_KERNEL::Exception); MEDCouplingFieldDouble *getFieldAtLevelOld(TypeOfField type, const char *mname, int iteration, int order, int meshDimRelToMax, int renumPol=0) const throw(INTERP_KERNEL::Exception); + // + void appendFieldNoProfileSBT(const MEDCouplingFieldDouble *field) throw(INTERP_KERNEL::Exception); }; class MEDFileFields : public RefCountObject, public MEDFieldFieldGlobs, public MEDFileWritable { public: + static MEDFileFields *New(); static MEDFileFields *New(const char *fileName) throw(INTERP_KERNEL::Exception); + void write(const char *fileName, int mode) const throw(INTERP_KERNEL::Exception); int getNumberOfFields() const; - std::vector getPfls() const; - std::vector getLocs() const; + // + void resize(int newSize) throw(INTERP_KERNEL::Exception); + void pushField(MEDFileFieldMultiTS *field) throw(INTERP_KERNEL::Exception); + void setFieldAtPos(int i, MEDFileFieldMultiTS *field) throw(INTERP_KERNEL::Exception); + void destroyFieldAtPos(int i) throw(INTERP_KERNEL::Exception); + }; + + class MEDFileData : public RefCountObject, public MEDFileWritable + { + public: + static MEDFileData *New(const char *fileName) throw(INTERP_KERNEL::Exception); + static MEDFileData *New(); + MEDFileFields *getFields() const; + MEDFileMeshes *getMeshes() const; + void setFields(MEDFileFields *fields) throw(INTERP_KERNEL::Exception); + void setMeshes(MEDFileMeshes *meshes) throw(INTERP_KERNEL::Exception); + int getNumberOfFields() const throw(INTERP_KERNEL::Exception); + int getNumberOfMeshes() const throw(INTERP_KERNEL::Exception); + // + void write(const char *fileName, int mode) const throw(INTERP_KERNEL::Exception); }; } diff --git a/src/MEDLoader/Swig/MEDLoaderTest3.py b/src/MEDLoader/Swig/MEDLoaderTest3.py index 0c2313666..72ffb5eea 100644 --- a/src/MEDLoader/Swig/MEDLoaderTest3.py +++ b/src/MEDLoader/Swig/MEDLoaderTest3.py @@ -490,6 +490,45 @@ class MEDLoaderTest(unittest.TestCase): self.assertTrue(f1.isEqual(f2,1e-12,1e-12)) # pass + def testMEDFileData1(self): + fname="Pyfile29.med" + d=MEDFileData.New() + # + m1=MEDLoaderDataForTest.build1DMesh_1() + mm1=MEDFileUMesh.New() ; mm1.setCoords(m1.getCoords()) ; mm1.setMeshAtLevel(0,m1) ; mm1.setName(m1.getName()) + mmm1=MEDFileMeshMultiTS.New() ; + mmm1.setOneTimeStep(mm1) + m2=MEDLoaderDataForTest.build2DCurveMesh_1() + mm2=MEDFileUMesh.New() ; mm2.setCoords(m2.getCoords()) ; mm2.setMeshAtLevel(0,m2) ; mm2.setName(m2.getName()) + mmm2=MEDFileMeshMultiTS.New() ; mmm2.setOneTimeStep(mm2) + ms=MEDFileMeshes.New(); ms.setMeshAtPos(0,mm1) ; ms.setMeshAtPos(1,mm2) + d.setMeshes(ms) + # + ff1=MEDFileFieldMultiTS.New() + ff21=MEDFileFieldMultiTS.New() + ff22=MEDFileFieldMultiTS.New() + f1=m1.getMeasureField(True) ; f1.setName("f1") ; f1=f1.buildNewTimeReprFromThis(ONE_TIME,False) + f1.getArray().setInfoOnComponent(0,"power [kW]") + ff1.appendFieldNoProfileSBT(f1) + f21=m2.getMeasureField(True) ; f21.setName("f21") ; f21=f21.buildNewTimeReprFromThis(ONE_TIME,False) + f21.getArray().setInfoOnComponent(0,"sta [mm]") ; + ff21.appendFieldNoProfileSBT(f21) + f22=f21.deepCpy() ; f22.setName("f22") ; f22=f22.buildNewTimeReprFromThis(ONE_TIME,False) ; + f22.applyFunc(2,"3*x*IVec+2*x*JVec") + f22.getArray().setInfoOnComponent(0,"distance [km]") ; f22.getArray().setInfoOnComponent(1,"displacement [cm]") + ff22.appendFieldNoProfileSBT(f22) + fs=MEDFileFields.New() + fs.pushField(ff1) ; fs.pushField(ff21) ; fs.pushField(ff22) + d.setFields(fs) + # + d.write(fname,0) + # + d2=MEDFileData.New(fname) + self.assertEqual(2,d2.getNumberOfMeshes()) + self.assertEqual(3,d2.getNumberOfFields()) + m1bis=d2.getMeshes().getMeshAtPos(0).getMeshAtLevel(0) + self.assertTrue(m1.isEqual(m1bis,1e-12)) + pass pass unittest.main() -- 2.39.2