From de9c52d8eeac85f4cd60c9498dc121c055c28392 Mon Sep 17 00:00:00 2001 From: ageay Date: Tue, 25 Jun 2013 15:43:46 +0000 Subject: [PATCH] On the road of reimplementation of basic MEDLoader API with advanced one. --- src/MEDLoader/MEDFileMesh.cxx | 43 + src/MEDLoader/MEDFileMesh.hxx | 3 +- src/MEDLoader/MEDLoader.cxx | 2216 ++++---------------------- src/MEDLoader/MEDLoader.hxx | 47 - src/MEDLoader/Swig/MEDLoaderCommon.i | 23 +- src/MEDLoader/Swig/MEDLoaderTest3.py | 2 +- 6 files changed, 421 insertions(+), 1913 deletions(-) diff --git a/src/MEDLoader/MEDFileMesh.cxx b/src/MEDLoader/MEDFileMesh.cxx index 0230171c8..0158c3cdb 100644 --- a/src/MEDLoader/MEDFileMesh.cxx +++ b/src/MEDLoader/MEDFileMesh.cxx @@ -3425,6 +3425,49 @@ void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool _ms[-meshDimRelToMax]=new MEDFileUMeshSplitL1(m,newOrOld); } +/*! + * This method allows to set at once the content of different levels in \a this. + * This method is equivalent to a series of call to MEDFileUMesh::setMeshAtLevel. + * + * \param [in] ms - List of unstructured meshes lying on the same coordinates and having different mesh dimesnion. + * \param [in] renum - the parameter (set to false by default) that tells the beheviour if there is a mesh on \a ms that is not geo type sorted. + * If false, an exception ois thrown. If true the mesh is reordered automatically. It is highly recommanded to let this parameter to false. + * + * \throw If \a there is a null pointer in \a ms. + * \sa MEDFileUMesh::setMeshAtLevel + */ +void MEDFileUMesh::setMeshes(const std::vector& ms, bool renum) throw(INTERP_KERNEL::Exception) +{ + if(ms.empty()) + return ; + const MEDCouplingUMesh *mRef=ms[0]; + if(!mRef) + throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in the first element of input meshes !"); + std::string name(mRef->getName()); + const DataArrayDouble *coo(mRef->getCoords()); + std::set s; + int zeDim=-1; + for(std::vector::const_iterator it=ms.begin();it!=ms.end();it++) + { + const MEDCouplingUMesh *cur(*it); + if(!cur) + throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in input vector of meshes !"); + if(coo!=cur->getCoords()) + throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes do not share the same coordinates !"); + int mdim=cur->getMeshDimension(); + zeDim=std::max(zeDim,mdim); + if(s.find(mdim)!=s.end()) + throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes must share the same coordinates pointer, and should have different mesh dimension each other !"); + } + for(std::vector::const_iterator it=ms.begin();it!=ms.end();it++) + { + int mdim=(*it)->getMeshDimension(); + setName((*it)->getName()); + setMeshAtLevel(mdim-zeDim,const_cast(*it),renum); + } + setName(name.c_str()); +} + /*! * Creates one MEDCouplingUMesh at a given level in \a this mesh from a sequence of * meshes each representing a group, and creates corresponding groups in \a this mesh. diff --git a/src/MEDLoader/MEDFileMesh.hxx b/src/MEDLoader/MEDFileMesh.hxx index 4e5158932..f17081e04 100644 --- a/src/MEDLoader/MEDFileMesh.hxx +++ b/src/MEDLoader/MEDFileMesh.hxx @@ -243,8 +243,9 @@ namespace ParaMEDMEM void addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids) throw(INTERP_KERNEL::Exception); void removeMeshAtLevel(int meshDimRelToMax) throw(INTERP_KERNEL::Exception); void setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld=false) throw(INTERP_KERNEL::Exception); + void setMeshes(const std::vector& ms, bool renum=false) throw(INTERP_KERNEL::Exception); void setGroupsFromScratch(int meshDimRelToMax, const std::vector& ms, bool renum=false) throw(INTERP_KERNEL::Exception); - void setGroupsOnSetMesh(int meshDimRelToMax, const std::vector& ms, bool renum) throw(INTERP_KERNEL::Exception); + void setGroupsOnSetMesh(int meshDimRelToMax, const std::vector& ms, bool renum=false) throw(INTERP_KERNEL::Exception); void optimizeFamilies() throw(INTERP_KERNEL::Exception); // tools void duplicateNodesOnM1Group(const char *grpNameM1, DataArrayInt *&nodesDuplicated, DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified) throw(INTERP_KERNEL::Exception); diff --git a/src/MEDLoader/MEDLoader.cxx b/src/MEDLoader/MEDLoader.cxx index 88e97da55..ee807d027 100644 --- a/src/MEDLoader/MEDLoader.cxx +++ b/src/MEDLoader/MEDLoader.cxx @@ -22,6 +22,7 @@ #include "MEDLoaderBase.hxx" #include "MEDFileUtilities.hxx" #include "MEDFileMesh.hxx" +#include "MEDFileField.hxx" #include "CellModel.hxx" #include "MEDCouplingUMesh.hxx" #include "MEDCouplingMemArray.hxx" @@ -138,146 +139,105 @@ using namespace ParaMEDMEM; namespace MEDLoaderNS { - class FieldPerTypeCopier - { - public: - FieldPerTypeCopier(double *ptr):_ptr(ptr) { } - void operator()(const MEDLoader::MEDFieldDoublePerCellType& elt) { _ptr=std::copy(elt.getArray(),elt.getArray()+elt.getNbOfValues(),_ptr); } - private: - double *_ptr; - }; - - class ConnReaderML - { - public: - ConnReaderML(const int *c, int val):_conn(c),_val(val) { } - bool operator() (const int& pos) { return _conn[pos]!=_val; } - private: - const int *_conn; - int _val; - }; - - std::vector getMeshNamesFid(med_idt fid); - void readFieldDoubleDataInMedFile(const char *fileName, const char *meshName, const char *fieldName, - int iteration, int order, ParaMEDMEM::TypeOfField typeOfOutField, - std::list& field, - double& time, std::vector& infos); - std::vector getIdsFromFamilies(const char *fileName, const char *meshName, const std::vector& fams); - std::vector getIdsFromGroups(const char *fileName, const char *meshName, const std::vector& grps); - med_int getIdFromMeshName(med_idt fid, const char *meshName, std::string& trueMeshName) throw(INTERP_KERNEL::Exception); + int readUMeshDimFromFile(const char *fileName, const char *meshName, std::vector& possibilities); void dispatchElems(int nbOfElemCell, int nbOfElemFace, int& nbOfElem, med_entity_type& whichEntity); - int readUMeshDimFromFile(const char *fileName, const char *meshName, std::vector& possibilities);//to keep - void readUMeshDataInMedFile(med_idt fid, med_int meshId, DataArrayDouble *&coords, std::list& conn, std::string& desc); - int buildMEDSubConnectivityOfOneType(const std::vector& conn, const std::vector& connIndex, const std::vector& families, INTERP_KERNEL::NormalizedCellType type, - std::vector& conn4MEDFile, std::vector& connIndex4MEDFile, std::vector& connIndexRk24MEDFile, - std::vector& fam4MEDFile, std::vector& renumber); - MEDCouplingUMesh *readUMeshFromFileLev1(const char *fileName, const char *meshName, int meshDimRelToMax, const std::vector& ids, - const std::vector& typesToKeep, unsigned& meshDimExtract, int *&cellRenum) throw(INTERP_KERNEL::Exception); - void tradMEDFileCoreFrmt2MEDCouplingUMesh(const std::list& medConnFrmt, - const std::vector& familiesToKeep, - DataArrayInt* &conn, - DataArrayInt* &connIndex, - int *&cellRenum); - ParaMEDMEM::DataArrayDouble *buildArrayFromRawData(const std::list& fieldPerType, - const std::vector& infos); - int buildMEDSubConnectivityOfOneTypesPolyg(const std::vector& conn, const std::vector& connIndex, const std::vector& families, - std::vector& conn4MEDFile, std::vector& connIndex4MEDFile, std::vector& fam4MEDFile, std::vector& renumber); - int buildMEDSubConnectivityOfOneTypesPolyh(const std::vector&conn, const std::vector& connIndex, const std::vector& families, - std::vector& conn4MEDFile, std::vector& connIndex4MEDFile, std::vector& connIndexRk24MEDFile, - std::vector& fam4MEDFile, std::vector& renumber); - int buildMEDSubConnectivityOfOneTypeStaticTypes(const std::vector& conn, const std::vector& connIndex, const std::vector& families, - INTERP_KERNEL::NormalizedCellType type, std::vector& conn4MEDFile, std::vector& fam4MEDFile, std::vector& renumber); - ParaMEDMEM::MEDCouplingFieldDouble *readFieldDoubleLev1(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order, - ParaMEDMEM::TypeOfField typeOfOutField) throw(INTERP_KERNEL::Exception); - ParaMEDMEM::MEDCouplingFieldDouble *readFieldDoubleLev2(const char *fileName, ParaMEDMEM::TypeOfField typeOfOutField, unsigned meshDim, const int *renumCell, const ParaMEDMEM::MEDCouplingUMesh *mesh, - const std::vector& infos, const char *fieldName, int iteration, int order, double time, - std::list& fieldPerCellType) throw(INTERP_KERNEL::Exception); - med_idt appendFieldSimpleAtt(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, med_int& numdt, med_int& numo, med_float& dt); - void appendFieldDirectly(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f); - void appendNodeProfileField(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, const int *thisMeshNodeIds); - void appendCellProfileField(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, const int *thisMeshCellIds); - void appendNodeElementProfileField(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, const int *thisMeshCellIds); - void prepareCellFieldDoubleForWriting(const ParaMEDMEM::MEDCouplingFieldDouble *f, const int *cellIds, std::list& split); - void fillGaussDataOnField(const char *fileName, const std::list& data, MEDCouplingFieldDouble *f); - void writeUMeshesDirectly(const char *fileName, const std::vector& mesh, const std::vector& families, bool forceFromScratch, bool &isRenumbering); - void writeUMeshesPartitionDirectly(const char *fileName, const char *meshName, const std::vector& meshes, bool forceFromScratch); - void writeFieldAndMeshDirectly(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, bool forceFromScratch); - void writeFieldTryingToFitExistingMesh(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f); + void writeFieldWithoutReadingAndMappingOfMeshInFile(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, bool writeFromScratch); + med_int getIdFromMeshName(med_idt fid, const char *meshName, std::string& trueMeshName) throw(INTERP_KERNEL::Exception); + std::vector getMeshNamesFid(med_idt fid); } /// @endcond -/*! - * This method sets the epsilon value used for node comparison when trying to buid a profile for a field on node/cell on an already written mesh. - */ -void MEDLoader::SetEpsilonForNodeComp(double val) throw(INTERP_KERNEL::Exception) -{ - _EPS_FOR_NODE_COMP=val; -} - -/*! - * This method sets the policy comparison when trying to fit the already written mesh on a field. The semantic of the policy is specified in MEDCouplingUMesh::zipConnectivityTraducer. - */ -void MEDLoader::SetCompPolicyForCell(int val) throw(INTERP_KERNEL::Exception) -{ - _COMP_FOR_CELL=val; -} -/*! - * This method set the behaviour of MEDLoader when a too long string is seen in datastructure before copy it in MED file. - * By default (0) an exception is thrown. If equal to 1 a warning is emitted in std_err but no exception is thrown. - */ -void MEDLoader::SetTooLongStrPolicy(int val) throw(INTERP_KERNEL::Exception) -{ - _TOO_LONG_STR=val; -} +/// @cond INTERNAL /*! - * @param lgth is the size of fam tab. For classical types conn is size of 'lgth'*number_of_nodes_in_type. - * @param index is optionnal only for polys. Set it to 0 if it is not the case. - * @param connLgth is the size of conn in the case of poly. Unsued if it is not the case. + * This method returns a first quick overview of mesh with name 'meshName' into the file 'fileName'. + * @param possibilities the relativeToMeshDim authorized to returned maxdim. This vector is systematically cleared at the begin of this method. + * @return the maximal mesh dimension of specified mesh. If nothing found -1 is returned. */ -MEDLoader::MEDConnOfOneElemType::MEDConnOfOneElemType(INTERP_KERNEL::NormalizedCellType type, int *conn, int *index, int *fam, int lgth, int connLgth):_lgth(lgth),_fam(fam), - _conn(conn),_index(index), - _global(0),_conn_lgth(connLgth), - _type(type) -{ -} - -void MEDLoader::MEDConnOfOneElemType::setGlobal(int *global) +int MEDLoaderNS::readUMeshDimFromFile(const char *fileName, const char *meshName, std::vector& possibilities) { - if(_global!=global) + possibilities.clear(); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY); + int ret; + std::set poss; + char nommaa[MED_NAME_SIZE+1]; + char maillage_description[MED_COMMENT_SIZE+1]; + med_mesh_type type_maillage; + med_int Sdim,Mdim; + std::string trueMeshName; + med_int meshId=getIdFromMeshName(fid,meshName,trueMeshName); + INTERP_KERNEL::AutoPtr dt_unit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); + med_sorting_type sortingType; + med_int nstep; + med_axis_type axisType; + int naxis=MEDmeshnAxis(fid,meshId); + INTERP_KERNEL::AutoPtr axisname=MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE); + INTERP_KERNEL::AutoPtr axisunit=MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE); + MEDmeshInfo(fid,meshId,nommaa,&Sdim,&Mdim,&type_maillage,maillage_description,dt_unit,&sortingType,&nstep,&axisType,axisname,axisunit); + // limitation + if(nstep!=1) + { + throw INTERP_KERNEL::Exception("multisteps on mesh not managed yet !"); + } + med_int numdt,numit; + med_float dt; + MEDmeshComputationStepInfo(fid,nommaa,1,&numdt,&numit,&dt); + // endlimitation + for(int i=0;i0) + { + INTERP_KERNEL::NormalizedCellType type=typmai2[i]; + int curDim=(int)INTERP_KERNEL::CellModel::GetCellModel(type).getDimension(); + poss.insert(curDim); + } } + if(!poss.empty()) + { + ret=*poss.rbegin(); + for(std::set::const_reverse_iterator it=poss.rbegin();it!=poss.rend();it++) + possibilities.push_back(*it-ret); + } + else + ret=-2; + return ret; } -void MEDLoader::MEDConnOfOneElemType::releaseArray() -{ - delete [] _fam; - delete [] _conn; - delete [] _index; - delete [] _global; -} - -MEDLoader::MEDFieldDoublePerCellType::MEDFieldDoublePerCellType(INTERP_KERNEL::NormalizedCellType type, double *values, int ncomp, int nGeoElt, int nbi, - const int *cellIdPerType, const char *locName):_ngeo_elt(nGeoElt),_nbi(nbi),_ncomp(ncomp),_values(values),_type(type) -{ - if(cellIdPerType) - _cell_id_per_type.insert(_cell_id_per_type.end(),cellIdPerType,cellIdPerType+nGeoElt); - if(locName) - _loc_name=locName; -} - -void MEDLoader::MEDFieldDoublePerCellType::releaseArray() +med_int MEDLoaderNS::getIdFromMeshName(med_idt fid, const char *meshName, std::string& trueMeshName) throw(INTERP_KERNEL::Exception) { - delete [] _values; + if(meshName==0) + { + std::vector meshes=getMeshNamesFid(fid); + if(meshes.empty()) + throw INTERP_KERNEL::Exception("No mesh in file"); + trueMeshName=meshes[0]; + return 1; + } + std::string meshNameStr(meshName); + std::vector meshes=getMeshNamesFid(fid); + if(meshes.empty()) + throw INTERP_KERNEL::Exception("No mesh in file"); + std::vector::iterator iter=std::find(meshes.begin(),meshes.end(),meshNameStr); + if(iter==meshes.end()) + { + std::ostringstream os2; + os2 << "MeshName '" << meshName << "' not in file : meshes available : "; + std::copy(meshes.begin(),meshes.end(),std::ostream_iterator(os2," ")); + throw INTERP_KERNEL::Exception(os2.str().c_str()); + } + trueMeshName=meshName; + return iter-meshes.begin()+1; } -/// @cond INTERNAL - std::vector MEDLoaderNS::getMeshNamesFid(med_idt fid) { med_mesh_type type_maillage; @@ -303,96 +263,48 @@ std::vector MEDLoaderNS::getMeshNamesFid(med_idt fid) return ret; } -void MEDLoaderNS::fillGaussDataOnField(const char *fileName, const std::list& data, MEDCouplingFieldDouble *f) +/*! + * This methods allows to merger all entities and to considerate only cell types. + */ +void MEDLoaderNS::dispatchElems(int nbOfElemCell, int nbOfElemFace, int& nbOfElem, med_entity_type& whichEntity) { - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY); - char locName[MED_NAME_SIZE+1]; - int nloc=MEDnLocalization(fid); - med_geometry_type typeGeo; - int offset=0; - for(std::list::const_iterator iter=data.begin();iter!=data.end();iter++) + if(nbOfElemCell>=nbOfElemFace) { - const std::string& loc=(*iter).getLocName(); - int idLoc=1; - int nbOfGaussPt=-1; - med_int spaceDim; - for(;idLoc<=nloc;idLoc++) - { - char geointerpname[MED_NAME_SIZE+1]=""; - char ipointstructmeshname[MED_NAME_SIZE+1]=""; - med_int nsectionmeshcell; - med_geometry_type sectiongeotype; - MEDlocalizationInfo(fid,idLoc,locName,&typeGeo,&spaceDim,&nbOfGaussPt, geointerpname, ipointstructmeshname, &nsectionmeshcell, - §iongeotype); - if(loc==locName) - break; - } - int dim=(int)INTERP_KERNEL::CellModel::GetCellModel((*iter).getType()).getDimension(); - int nbPtPerCell=(int)INTERP_KERNEL::CellModel::GetCellModel((*iter).getType()).getNumberOfNodes(); - std::vector refcoo(nbPtPerCell*dim),gscoo(nbOfGaussPt*dim),w(nbOfGaussPt); - MEDlocalizationRd(fid,(*iter).getLocName().c_str(),MED_FULL_INTERLACE,&refcoo[0],&gscoo[0],&w[0]); - if((*iter).getCellIdPerType().empty()) - f->setGaussLocalizationOnType((*iter).getType(),refcoo,gscoo,w); - else - { - MEDCouplingAutoRefCountObjectPtr pfl=DataArrayInt::New(); - pfl->alloc((*iter).getCellIdPerType().size(),1); - pfl->iota(offset); - f->setGaussLocalizationOnCells(pfl->begin(),pfl->end(),refcoo,gscoo,w); - } - offset+=(*iter).getNbOfGeoElt(); + whichEntity=MED_CELL; + nbOfElem=nbOfElemCell; + } + else + { + whichEntity=MED_CELL; + nbOfElem=nbOfElemFace; } } /// @endcond -void MEDLoader::CheckFileForRead(const char *fileName) throw(INTERP_KERNEL::Exception) +/*! + * This method sets the epsilon value used for node comparison when trying to buid a profile for a field on node/cell on an already written mesh. + */ +void MEDLoader::SetEpsilonForNodeComp(double val) throw(INTERP_KERNEL::Exception) { - MEDFileUtilities::CheckFileForRead(fileName); + _EPS_FOR_NODE_COMP=val; } -std::vector MEDLoader::GetMeshNames(const char *fileName) throw(INTERP_KERNEL::Exception) +/*! + * This method sets the policy comparison when trying to fit the already written mesh on a field. The semantic of the policy is specified in MEDCouplingUMesh::zipConnectivityTraducer. + */ +void MEDLoader::SetCompPolicyForCell(int val) throw(INTERP_KERNEL::Exception) { - CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY); - std::vector ret=MEDLoaderNS::getMeshNamesFid(fid); - return ret; + _COMP_FOR_CELL=val; } -std::vector< std::pair > MEDLoader::GetComponentsNamesOfField(const char *fileName, const char *fieldName) throw(INTERP_KERNEL::Exception) +/*! + * This method set the behaviour of MEDLoader when a too long string is seen in datastructure before copy it in MED file. + * By default (0) an exception is thrown. If equal to 1 a warning is emitted in std_err but no exception is thrown. + */ +void MEDLoader::SetTooLongStrPolicy(int val) throw(INTERP_KERNEL::Exception) { - CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY); - med_int nbFields=MEDnField(fid); - std::vector fields(nbFields); - med_field_type typcha; - for(int i=0;i comp=new char[ncomp*MED_SNAME_SIZE+1]; - INTERP_KERNEL::AutoPtr unit=new char[ncomp*MED_SNAME_SIZE+1]; - INTERP_KERNEL::AutoPtr dt_unit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); - med_int nbPdt; - med_bool localmesh; - INTERP_KERNEL::AutoPtr maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - MEDfieldInfo(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt); - std::string meshName=MEDLoaderBase::buildStringFromFortran(maa_ass,MED_NAME_SIZE); - std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1); - if(curFieldName==fieldName) - { - std::vector< std::pair > ret(ncomp); - for(int j=0;j(MEDLoaderBase::buildStringFromFortran(((char *)comp)+j*MED_SNAME_SIZE,MED_SNAME_SIZE), - MEDLoaderBase::buildStringFromFortran(((char *)unit)+j*MED_SNAME_SIZE,MED_SNAME_SIZE)); - return ret; - } - fields[i]=curFieldName; - } - std::ostringstream oss; oss << "MEDLoader::GetComponentsNamesOfField : no such field \"" << fieldName << "\" in file \"" << fileName << "\" !" << std::endl; - oss << "Possible field names are : " << std::endl; - std::copy(fields.begin(),fields.end(),std::ostream_iterator(oss," ")); - throw INTERP_KERNEL::Exception(oss.str().c_str()); + _TOO_LONG_STR=val; } /*! @@ -461,6 +373,55 @@ std::vector< std::vector< std::pair > > M return ret; } +void MEDLoader::CheckFileForRead(const char *fileName) throw(INTERP_KERNEL::Exception) +{ + MEDFileUtilities::CheckFileForRead(fileName); +} + +std::vector MEDLoader::GetMeshNames(const char *fileName) throw(INTERP_KERNEL::Exception) +{ + CheckFileForRead(fileName); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY); + std::vector ret=MEDLoaderNS::getMeshNamesFid(fid); + return ret; +} + +std::vector< std::pair > MEDLoader::GetComponentsNamesOfField(const char *fileName, const char *fieldName) throw(INTERP_KERNEL::Exception) +{ + CheckFileForRead(fileName); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY); + med_int nbFields=MEDnField(fid); + std::vector fields(nbFields); + med_field_type typcha; + for(int i=0;i comp=new char[ncomp*MED_SNAME_SIZE+1]; + INTERP_KERNEL::AutoPtr unit=new char[ncomp*MED_SNAME_SIZE+1]; + INTERP_KERNEL::AutoPtr dt_unit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); + med_int nbPdt; + med_bool localmesh; + INTERP_KERNEL::AutoPtr maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + INTERP_KERNEL::AutoPtr nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + MEDfieldInfo(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt); + std::string meshName=MEDLoaderBase::buildStringFromFortran(maa_ass,MED_NAME_SIZE); + std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1); + if(curFieldName==fieldName) + { + std::vector< std::pair > ret(ncomp); + for(int j=0;j(MEDLoaderBase::buildStringFromFortran(((char *)comp)+j*MED_SNAME_SIZE,MED_SNAME_SIZE), + MEDLoaderBase::buildStringFromFortran(((char *)unit)+j*MED_SNAME_SIZE,MED_SNAME_SIZE)); + return ret; + } + fields[i]=curFieldName; + } + std::ostringstream oss; oss << "MEDLoader::GetComponentsNamesOfField : no such field \"" << fieldName << "\" in file \"" << fileName << "\" !" << std::endl; + oss << "Possible field names are : " << std::endl; + std::copy(fields.begin(),fields.end(),std::ostream_iterator(oss," ")); + throw INTERP_KERNEL::Exception(oss.str().c_str()); +} + std::vector MEDLoader::GetMeshNamesOnField(const char *fileName, const char *fieldName) throw(INTERP_KERNEL::Exception) { CheckFileForRead(fileName); @@ -1076,998 +1037,7 @@ std::vector< std::pair > MEDLoader::GetNodeFieldIterations(const char * return ret; } -/*! - * This method reads all the content of a field 'fieldName' at a time specified by (iteration,order) lying on a mesh 'meshName' with a specified type 'TypeOfOutField' - * The returned values are strored in 'field' (sorted by type of cell), time corresponding to field, and 'infos' to load properly little strings. - * The principle of this method is to put into 'field' only data that fulfills \b perfectly request. - */ -void MEDLoaderNS::readFieldDoubleDataInMedFile(const char *fileName, const char *meshName, const char *fieldName, - int iteration, int order, ParaMEDMEM::TypeOfField typeOfOutField, - std::list& field, - double& time, std::vector& infos) -{ - time=0.; - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY); - med_int nbFields=MEDnField(fid); - // - med_field_type typcha; - char nomcha[MED_NAME_SIZE+1]=""; - char pflname [MED_NAME_SIZE+1]=""; - char locname [MED_NAME_SIZE+1]=""; - std::map tabEnt; - std::map tabType; - std::map tabTypeLgth; - med_bool localmesh; - bool found=false; - tabEnt[ON_CELLS]=MED_CELL; - tabType[ON_CELLS]=typmai; - tabTypeLgth[ON_CELLS]=MED_N_CELL_FIXED_GEO; - tabEnt[ON_NODES]=MED_NODE; - tabType[ON_NODES]=typmainoeud; - tabTypeLgth[ON_NODES]=1; - tabEnt[ON_GAUSS_PT]=MED_CELL; - tabType[ON_GAUSS_PT]=typmai; - tabTypeLgth[ON_GAUSS_PT]=MED_N_CELL_FIXED_GEO; - tabEnt[ON_GAUSS_NE]=MED_NODE_ELEMENT; - tabType[ON_GAUSS_NE]=typmai; - tabTypeLgth[ON_GAUSS_NE]=MED_N_CELL_FIXED_GEO; - // - for(int i=0;i comp=new char[ncomp*MED_SNAME_SIZE+1]; - INTERP_KERNEL::AutoPtr unit=new char[ncomp*MED_SNAME_SIZE+1]; - INTERP_KERNEL::AutoPtr dt_unit=new char[MED_LNAME_SIZE+1]; - INTERP_KERNEL::AutoPtr maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - med_int nbPdt; - MEDfieldInfo(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt); - std::string curMeshName=MEDLoaderBase::buildStringFromFortran(maa_ass,MED_NAME_SIZE+1); - std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1); - found=(curFieldName==fieldName) && (curMeshName==meshName); - if(found) - { - infos.resize(ncomp); - for(int ii=0;ii MEDLoaderNS::getIdsFromFamilies(const char *fileName, const char *meshName, const std::vector& fams) -{ - std::vector ret; - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY); - med_int nfam=MEDnFamily(fid,meshName); - char nomfam[MED_NAME_SIZE+1]; - med_int numfam; - for(int i=0;i attide=new med_int[natt]; - INTERP_KERNEL::AutoPtr attval=new med_int[natt]; - INTERP_KERNEL::AutoPtr attdes=new char[MED_COMMENT_SIZE*natt+1]; - INTERP_KERNEL::AutoPtr gro=new char[MED_LNAME_SIZE*ngro+1]; - MEDfamily23Info(fid,meshName,i+1,nomfam,attide,attval,attdes,&numfam,gro); - std::string cur=MEDLoaderBase::buildStringFromFortran(nomfam,sizeof(nomfam)); - if(std::find(fams.begin(),fams.end(),cur)!=fams.end()) - ret.push_back(numfam); - } - return ret; -} - -std::vector MEDLoaderNS::getIdsFromGroups(const char *fileName, const char *meshName, const std::vector& grps) -{ - std::vector ret; - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY); - med_int nfam=MEDnFamily(fid,meshName); - char nomfam[MED_NAME_SIZE+1]; - med_int numfam; - for(int i=0;i attide=new med_int[natt]; - INTERP_KERNEL::AutoPtr attval=new med_int[natt]; - INTERP_KERNEL::AutoPtr attdes=new char[MED_COMMENT_SIZE*natt+1]; - INTERP_KERNEL::AutoPtr gro=new char[MED_LNAME_SIZE*ngro+1]; - MEDfamily23Info(fid,meshName,i+1,nomfam,attide,attval,attdes,&numfam,gro); - std::string cur=MEDLoaderBase::buildStringFromFortran(nomfam,sizeof(nomfam)); - for(int j=0;j meshes=getMeshNamesFid(fid); - if(meshes.empty()) - throw INTERP_KERNEL::Exception("No mesh in file"); - trueMeshName=meshes[0]; - return 1; - } - std::string meshNameStr(meshName); - std::vector meshes=getMeshNamesFid(fid); - if(meshes.empty()) - throw INTERP_KERNEL::Exception("No mesh in file"); - std::vector::iterator iter=std::find(meshes.begin(),meshes.end(),meshNameStr); - if(iter==meshes.end()) - { - std::ostringstream os2; - os2 << "MeshName '" << meshName << "' not in file : meshes available : "; - std::copy(meshes.begin(),meshes.end(),std::ostream_iterator(os2," ")); - throw INTERP_KERNEL::Exception(os2.str().c_str()); - } - trueMeshName=meshName; - return iter-meshes.begin()+1; -} - -/*! - * This methods allows to merger all entities and to considerate only cell types. - */ -void MEDLoaderNS::dispatchElems(int nbOfElemCell, int nbOfElemFace, int& nbOfElem, med_entity_type& whichEntity) -{ - if(nbOfElemCell>=nbOfElemFace) - { - whichEntity=MED_CELL; - nbOfElem=nbOfElemCell; - } - else - { - whichEntity=MED_CELL; - nbOfElem=nbOfElemFace; - } -} - -/*! - * This method returns a first quick overview of mesh with name 'meshName' into the file 'fileName'. - * @param possibilities the relativeToMeshDim authorized to returned maxdim. This vector is systematically cleared at the begin of this method. - * @return the maximal mesh dimension of specified mesh. If nothing found -1 is returned. - */ -int MEDLoaderNS::readUMeshDimFromFile(const char *fileName, const char *meshName, std::vector& possibilities) -{ - possibilities.clear(); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY); - int ret; - std::set poss; - char nommaa[MED_NAME_SIZE+1]; - char maillage_description[MED_COMMENT_SIZE+1]; - med_mesh_type type_maillage; - med_int Sdim,Mdim; - std::string trueMeshName; - med_int meshId=getIdFromMeshName(fid,meshName,trueMeshName); - INTERP_KERNEL::AutoPtr dt_unit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); - med_sorting_type sortingType; - med_int nstep; - med_axis_type axisType; - int naxis=MEDmeshnAxis(fid,meshId); - INTERP_KERNEL::AutoPtr axisname=MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE); - INTERP_KERNEL::AutoPtr axisunit=MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE); - MEDmeshInfo(fid,meshId,nommaa,&Sdim,&Mdim,&type_maillage,maillage_description,dt_unit,&sortingType,&nstep,&axisType,axisname,axisunit); - // limitation - if(nstep!=1) - { - throw INTERP_KERNEL::Exception("multisteps on mesh not managed yet !"); - } - med_int numdt,numit; - med_float dt; - MEDmeshComputationStepInfo(fid,nommaa,1,&numdt,&numit,&dt); - // endlimitation - for(int i=0;i0) - { - INTERP_KERNEL::NormalizedCellType type=typmai2[i]; - int curDim=(int)INTERP_KERNEL::CellModel::GetCellModel(type).getDimension(); - poss.insert(curDim); - } - } - if(!poss.empty()) - { - ret=*poss.rbegin(); - for(std::set::const_reverse_iterator it=poss.rbegin();it!=poss.rend();it++) - possibilities.push_back(*it-ret); - } - else - ret=-2; - return ret; -} - -void MEDLoaderNS::readUMeshDataInMedFile(med_idt fid, med_int meshId, DataArrayDouble *&coords, std::list& conn, std::string& description) -{ - char nommaa[MED_NAME_SIZE+1]; - char maillage_description[MED_COMMENT_SIZE+1]; - med_mesh_type type_maillage; - med_int Mdim; - med_int Sdim; - INTERP_KERNEL::AutoPtr dt_unit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); - med_sorting_type sortingType; - med_int nstep; - med_axis_type axisType; - med_int numdt,numit; - med_float dt; - med_bool changement,transformation; - // endlimitation - Sdim=MEDmeshnAxis(fid,1); - INTERP_KERNEL::AutoPtr comp=MEDLoaderBase::buildEmptyString(Sdim*MED_SNAME_SIZE); - INTERP_KERNEL::AutoPtr unit=MEDLoaderBase::buildEmptyString(Sdim*MED_SNAME_SIZE); - MEDmeshInfo(fid,meshId,nommaa,&Sdim,&Mdim,&type_maillage,maillage_description,dt_unit,&sortingType,&nstep,&axisType,comp,unit); - description=MEDLoaderBase::buildStringFromFortran(maillage_description,sizeof(maillage_description)); - MEDmeshComputationStepInfo(fid,nommaa,1,&numdt,&numit,&dt); - int spaceDim=std::max((int)Mdim,(int)Sdim); - int nCoords=MEDmeshnEntity(fid,nommaa,numdt,numit,MED_NODE,MED_NONE,MED_COORDINATE,MED_NO_CMODE,&changement,&transformation); - // limitation - if(nstep!=1) - { - throw INTERP_KERNEL::Exception("multisteps on mesh not managed yet !"); - } - coords=DataArrayDouble::New(); - coords->alloc(nCoords,spaceDim); - double *coordsPtr=coords->getPointer(); - MEDmeshNodeCoordinateRd(fid,nommaa,numdt,numit,MED_FULL_INTERLACE,coordsPtr); - for(int i=0;isetInfoOnComponent(i,info.c_str()); - } - for(int i=0;i0) - { - int *connTab=new int[(curMedType%100)*curNbOfElem]; - int *fam=new int[curNbOfElem]; - MEDLoader::MEDConnOfOneElemType elem(typmai2[i],connTab,0,fam,curNbOfElem,-1); - char *noms=new char[MED_SNAME_SIZE*curNbOfElem+1]; - med_bool withname=MED_FALSE,withnumber=MED_FALSE,withfam=MED_FALSE; - int *globArr=new int[curNbOfElem]; - MEDmeshElementRd(fid,nommaa,numdt,numit,whichEntity,curMedType,MED_NODAL,MED_FULL_INTERLACE,connTab,&withname,noms,&withnumber,globArr,&withfam,fam); - if(!withfam) - std::fill(fam,fam+curNbOfElem,0); - delete [] noms; - //trying to read global numbering - if(withnumber) - elem.setGlobal(globArr); - else - delete [] globArr; - //limitation manage withfam==false - conn.push_back(elem); - } - } - int curNbOfPolyElem; - int curNbOfPolyElemM=MEDmeshnEntity(fid,nommaa,numdt,numit,MED_CELL,MED_POLYGON,MED_INDEX_NODE,MED_NODAL,&changement,&transformation)-1; - int curNbOfPolyElemF=MEDmeshnEntity(fid,nommaa,numdt,numit,MED_CELL,MED_POLYGON,MED_INDEX_NODE,MED_NODAL,&changement,&transformation)-1;//limitation - med_entity_type whichPolyEntity; - MEDLoaderNS::dispatchElems(curNbOfPolyElemM,curNbOfPolyElemF,curNbOfPolyElem,whichPolyEntity); - if(curNbOfPolyElem>0) - { - med_int arraySize=MEDmeshnEntity(fid,nommaa,numdt,numit,MED_CELL,MED_POLYGON,MED_CONNECTIVITY,MED_NODAL,&changement,&transformation); - int *index=new int[curNbOfPolyElem+1]; - int *locConn=new int[arraySize]; - int *fam=new int[curNbOfPolyElem]; - int *globArr=new int[curNbOfPolyElem]; - MEDLoader::MEDConnOfOneElemType elem(INTERP_KERNEL::NORM_POLYGON,locConn,index,fam,curNbOfPolyElem,arraySize); - MEDmeshPolygonRd(fid,nommaa,numdt,numit,MED_CELL,MED_NODAL,index,locConn); - if(MEDmeshnEntity(fid,nommaa,numdt,numit,MED_CELL,MED_POLYGON,MED_FAMILY_NUMBER,MED_NODAL,&changement,&transformation)>0) - { - if(MEDmeshEntityFamilyNumberRd(fid,nommaa,numdt,numit,MED_CELL,MED_POLYGON,fam)!=0) - std::fill(fam,fam+curNbOfPolyElem,0); - } - else - std::fill(fam,fam+curNbOfPolyElem,0); - if(MEDmeshnEntity(fid,nommaa,numdt,numit,MED_CELL,MED_POLYGON,MED_NUMBER,MED_NODAL,&changement,&transformation)>0) - { - if(MEDmeshEntityNumberRd(fid,nommaa,numdt,numit,whichPolyEntity,MED_POLYGON,globArr)==0) - elem.setGlobal(globArr); - else - delete [] globArr; - } - else - delete [] globArr; - conn.push_back(elem); - } - curNbOfPolyElem=MEDmeshnEntity(fid,nommaa,numdt,numit,MED_CELL,MED_POLYHEDRON,MED_INDEX_FACE,MED_NODAL,&changement,&transformation)-1; - if(curNbOfPolyElem>0) - { - med_int indexFaceLgth,connFaceLgth; - indexFaceLgth=MEDmeshnEntity(fid,nommaa,numdt,numit,MED_CELL,MED_POLYHEDRON,MED_INDEX_NODE,MED_NODAL,&changement,&transformation); - connFaceLgth=MEDmeshnEntity(fid,nommaa,numdt,numit,MED_CELL,MED_POLYHEDRON,MED_CONNECTIVITY,MED_NODAL,&changement,&transformation); - INTERP_KERNEL::AutoPtr index=new int[curNbOfPolyElem+1]; - INTERP_KERNEL::AutoPtr indexFace=new int[indexFaceLgth]; - INTERP_KERNEL::AutoPtr locConn=new int[connFaceLgth]; - int *fam=new int[curNbOfPolyElem]; - int *globArr=new int[curNbOfPolyElem]; - MEDmeshPolyhedronRd(fid,nommaa,numdt,numit,MED_CELL,MED_NODAL,index,indexFace,locConn); - if(MEDmeshnEntity(fid,nommaa,numdt,numit,whichPolyEntity,MED_POLYHEDRON,MED_FAMILY_NUMBER,MED_NODAL,&changement,&transformation)>0) - { - if(MEDmeshEntityFamilyNumberRd(fid,nommaa,numdt,numit,whichPolyEntity,MED_POLYHEDRON,fam)!=0) - std::fill(fam,fam+curNbOfPolyElem,0); - } - else - std::fill(fam,fam+curNbOfPolyElem,0); - int arraySize=connFaceLgth; - for(int i=0;i0) - { - if(MEDmeshEntityNumberRd(fid,nommaa,numdt,numit,whichPolyEntity,MED_POLYHEDRON,globArr)==0) - elem.setGlobal(globArr); - else - delete [] globArr; - } - else - delete [] globArr; - conn.push_back(elem); - } -} - -/// @cond INTERNAL - -namespace MEDLoaderNS -{ - template - unsigned calculateHighestMeshDim(const std::list& conn) - { - unsigned ret=0; - for(typename std::list::const_iterator iter=conn.begin();iter!=conn.end();iter++) - { - unsigned curDim=INTERP_KERNEL::CellModel::GetCellModel((*iter).getType()).getDimension(); - if(ret - void keepSpecifiedMeshDim(typename std::list& conn, unsigned meshDim) - { - for(typename std::list::iterator iter=conn.begin();iter!=conn.end();) - { - unsigned curDim=INTERP_KERNEL::CellModel::GetCellModel((*iter).getType()).getDimension(); - if(curDim!=meshDim) - { - (*iter).releaseArray(); - iter=conn.erase(iter); - } - else - iter++; - } - } - - template - void keepTypes(typename std::list& conn, const std::vector& typesToKeep) - { - if(!typesToKeep.empty()) - { - for(typename std::list::iterator iter=conn.begin();iter!=conn.end();) - { - INTERP_KERNEL::NormalizedCellType curType=(*iter).getType(); - if(std::find(typesToKeep.begin(),typesToKeep.end(),curType)==typesToKeep.end()) - { - (*iter).releaseArray(); - iter=conn.erase(iter); - } - else - iter++; - } - } - } -} - -class FieldPerTypeAccumulator -{ -public: - int operator()(int res, const MEDLoader::MEDFieldDoublePerCellType& elt) { return res+elt.getNbOfTuple(); } -}; - -ParaMEDMEM::DataArrayDouble *MEDLoaderNS::buildArrayFromRawData(const std::list& fieldPerType, - const std::vector& infos) -{ - ParaMEDMEM::DataArrayDouble *ret=ParaMEDMEM::DataArrayDouble::New(); - int totalNbOfTuple=std::accumulate(fieldPerType.begin(),fieldPerType.end(),0,FieldPerTypeAccumulator()); - int nbOfComp=(*fieldPerType.begin()).getNbComp(); - double *ptr=new double[nbOfComp*totalNbOfTuple]; - ret->useArray(ptr,true,ParaMEDMEM::CPP_DEALLOC,totalNbOfTuple,nbOfComp); - std::for_each(fieldPerType.begin(),fieldPerType.end(),FieldPerTypeCopier(ptr)); - for(int i=0;isetInfoOnComponent(i,infos[i].c_str()); - return ret; -} - -class PolyCounterForFams -{ -public: - PolyCounterForFams(int id, const int *index):_id(id),_index(index),_count(0),_sigma(0) { } - void operator()(int val) { if(val==_id) _sigma+=_index[_count+1]-_index[_count]; _count++; } - int getSigma() const { return _sigma; } -private: - int _id; - const int *_index; - int _count; - int _sigma; -}; - -/*! - * This method fills unstructured connectivity using basic MED file format 'medConnFrmt'. - * If in each elements of 'medConnFrmt' a renumbering cell array is found the aggregate array 'cellRenum' is returned. - */ -void MEDLoaderNS::tradMEDFileCoreFrmt2MEDCouplingUMesh(const std::list& medConnFrmt, - const std::vector& familiesToKeep, - DataArrayInt* &conn, - DataArrayInt* &connIndex, - int *&cellRenum) -{ - bool keepAll=familiesToKeep.empty(); - if(medConnFrmt.empty()) - { - conn=0; - connIndex=0; - cellRenum=0; - return ; - } - std::list::const_iterator iter=medConnFrmt.begin(); - int totalNbOfCells=0; - int totalNbOfMedConn=0; - bool renumber=true; - cellRenum=0; - for(;iter!=medConnFrmt.end();iter++) - { - if((*iter).getGlobal()==0) - renumber=false; - const INTERP_KERNEL::CellModel& cellMod=INTERP_KERNEL::CellModel::GetCellModel((*iter).getType()); - if(keepAll) - totalNbOfCells+=(*iter).getLength(); - else - for(std::vector::const_iterator iter2=familiesToKeep.begin();iter2!=familiesToKeep.end();iter2++) - totalNbOfCells+=std::count((*iter).getFam(),(*iter).getFam()+(*iter).getLength(),*iter2); - if(!cellMod.isDynamic()) - if(keepAll) - totalNbOfMedConn+=(*iter).getLength()*cellMod.getNumberOfNodes(); - else - for(std::vector::const_iterator iter2=familiesToKeep.begin();iter2!=familiesToKeep.end();iter2++) - totalNbOfMedConn+=std::count((*iter).getFam(),(*iter).getFam()+(*iter).getLength(),*iter2)*cellMod.getNumberOfNodes(); - else - if(keepAll) - totalNbOfMedConn+=(*iter).getConnLength(); - else - for(std::vector::const_iterator iter2=familiesToKeep.begin();iter2!=familiesToKeep.end();iter2++) - { - PolyCounterForFams res=std::for_each((*iter).getFam(),(*iter).getFam()+(*iter).getLength(),PolyCounterForFams(*iter2,(*iter).getIndex())); - totalNbOfMedConn+=res.getSigma(); - } - } - connIndex=DataArrayInt::New(); - conn=DataArrayInt::New(); - connIndex->alloc(totalNbOfCells+1,1); - int *connIdxPtr=connIndex->getPointer(); - int connFillId=0; - conn->alloc(totalNbOfMedConn+totalNbOfCells,1); - int *connPtr=conn->getPointer(); - if(renumber) - cellRenum=new int[totalNbOfCells]; - int *renumW=cellRenum; - for(iter=medConnFrmt.begin();iter!=medConnFrmt.end();iter++) - { - INTERP_KERNEL::NormalizedCellType type=(*iter).getType(); - const int *sourceConn=(*iter).getArray(); - const int *sourceIndex=(*iter).getIndex(); - const int *globalNum=(*iter).getGlobal(); - const INTERP_KERNEL::CellModel& cellMod=INTERP_KERNEL::CellModel::GetCellModel(type); - int nbOfCellsInCurType; - int nbOfNodesIn1Cell=cellMod.getNumberOfNodes(); - nbOfCellsInCurType=(*iter).getLength(); - bool isDyn=cellMod.isDynamic(); - int *tmpConnPtr; - for(int i=0;i(),1)); - else - tmpConnPtr=std::transform(sourceConn,sourceConn+sourceIndex[i+1]-sourceIndex[i],connPtr,std::bind2nd(std::minus(),1)); - connIdxPtr++; - nbOfNodesIn1Cell=tmpConnPtr-connPtr; - connFillId+=nbOfNodesIn1Cell+1; - connPtr=tmpConnPtr; - } - else if(std::find(familiesToKeep.begin(),familiesToKeep.end(),(*iter).getFam()[i])!=familiesToKeep.end()) - {//duplication of next 3 lines needed. - *connIdxPtr=connFillId; - *connPtr++=type; - if(renumber) - *renumW++=globalNum[i]; - if(!isDyn) - tmpConnPtr=std::transform(sourceConn,sourceConn+nbOfNodesIn1Cell,connPtr,std::bind2nd(std::minus(),1)); - else//The duplication of code is motivated by the line underneath. - tmpConnPtr=std::transform((*iter).getArray()+sourceIndex[i]-1,(*iter).getArray()+sourceIndex[i+1]-1,connPtr,std::bind2nd(std::minus(),1)); - connIdxPtr++; - nbOfNodesIn1Cell=tmpConnPtr-connPtr; - connFillId+=nbOfNodesIn1Cell+1; - connPtr=tmpConnPtr; - } - sourceConn+=nbOfNodesIn1Cell; - } - *connIdxPtr=connFillId; - } -} - -namespace MEDLoaderNS -{ - template - void releaseMEDFileCoreFrmt(typename std::list& medConnFrmt) - { - for(typename std::list::iterator iter=medConnFrmt.begin();iter!=medConnFrmt.end();iter++) - (*iter).releaseArray(); - medConnFrmt.clear(); - } -} - -/*! - * This method builds a sub set of connectivity for a given type 'type'. \b WARNING connV,connVIndex and familiesV must have same size ! - * @param connV input containing connectivity with MEDCoupling format. - * @param connVIndex input containing connectivity index in MEDCoupling format. - * @param familiesV input that may be equal to 0. This specifies an array specifying cell family foreach cell. - * @param type input specifying which cell types will be extracted in conn4MEDFile. - * @param conn4MEDFile output containing the connectivity directly understandable by MEDFile; conn4MEDFile has to be empty before this method called. - * @param connIndex4MEDFile output containing index connectivity understandable by MEDFile; only used by polygons and polyhedrons (it is face nodal connec). - * @param connIndexRk24MEDFile output containing index of rank 2 understandable by MEDFile; only used by polyhedrons. - * @param fam4MEDFile output containing family number of cells whose type is 'type'. This output is updated only if 'families' is different than 0. - * @return nb of elements extracted. - */ -int MEDLoaderNS::buildMEDSubConnectivityOfOneTypeStaticTypes(const std::vector& connV, const std::vector& connVIndex, const std::vector& familiesV, - INTERP_KERNEL::NormalizedCellType type, std::vector& conn4MEDFile, std::vector& fam4MEDFile, std::vector& renumber) -{ - int ret=0; - int nbOfMeshes=connV.size(); - int renumOffset=0; - for(int i=0;igetNbOfElems()-1; - const int *connPtr=conn->getConstPointer(); - const int *connIdxPtr=connIndex->getConstPointer(); - const int *famPtr=0; - if(families) - famPtr=families->getConstPointer(); - for(int ii=0;ii(),1)); - return ret; -} - -int MEDLoaderNS::buildMEDSubConnectivityOfOneTypesPolyg(const std::vector&connV, const std::vector& connVIndex, const std::vector& familiesV, - std::vector& conn4MEDFile, std::vector& connIndex4MEDFile, std::vector& fam4MEDFile, std::vector& renumber) -{ - int ret=0; - int nbOfMeshes=connV.size(); - connIndex4MEDFile.push_back(1); - int renumOffset=0; - for(int i=0;igetNbOfElems()-1; - const int *connPtr=conn->getConstPointer(); - const int *connIdxPtr=connIndex->getConstPointer(); - const int *famPtr=0; - if(families) - famPtr=families->getConstPointer(); - for(int ii=0;ii(),1)); - return ret; -} - -int MEDLoaderNS::buildMEDSubConnectivityOfOneTypesPolyh(const std::vector& connV, const std::vector& connVIndex, const std::vector& familiesV, - std::vector& conn4MEDFile, std::vector& connIndex4MEDFile, std::vector& connIndexRk24MEDFile, - std::vector& fam4MEDFile, std::vector& renumber) -{ - int ret=0; - int nbOfMeshes=connV.size(); - connIndexRk24MEDFile.push_back(1); - connIndex4MEDFile.push_back(1); - int renumOffset=0; - for(int i=0;igetNbOfElems()-1; - const int *connPtr=conn->getConstPointer(); - const int *connIdxPtr=connIndex->getConstPointer(); - const int *famPtr=0; - if(families) - famPtr=families->getConstPointer(); - for(int ii=0;ii(),1)); - return ret; -} - -/*! - * This method builds a sub set of connectivity for a given type 'type'. - * @param conn input containing connectivity with MEDCoupling format. - * @param connIndex input containing connectivity index in MEDCoupling format. - * @param families input containing, if any, the family number of each cells - * @param type input specifying which cell types will be extracted in conn4MEDFile. - * @param conn4MEDFile output containing the connectivity directly understandable by MEDFile; conn4MEDFile has to be empty before this method called. - * @param connIndex4MEDFile output containing index connectivity understandable by MEDFile; only used by polygons and polyhedrons (it is face nodal connec). - * @param connIndexRk24MEDFile output containing index of rank 2 understandable by MEDFile; only used by polyhedrons. - * @param fam4MEDFile output containing families id of cells whose type is 'type'. - * @return nb of elements extracted. - */ -int MEDLoaderNS::buildMEDSubConnectivityOfOneType(const std::vector& conn, const std::vector& connIndex, const std::vector& families, - INTERP_KERNEL::NormalizedCellType type, std::vector& conn4MEDFile, - std::vector& connIndex4MEDFile, std::vector& connIndexRk24MEDFile, std::vector& fam4MEDFile, std::vector& renumber) -{ - - const INTERP_KERNEL::CellModel& cellMod=INTERP_KERNEL::CellModel::GetCellModel(type); - if(!cellMod.isDynamic()) - return buildMEDSubConnectivityOfOneTypeStaticTypes(conn,connIndex,families,type,conn4MEDFile,fam4MEDFile,renumber); - else - { - if(type==INTERP_KERNEL::NORM_POLYGON) - return buildMEDSubConnectivityOfOneTypesPolyg(conn,connIndex,families,conn4MEDFile,connIndex4MEDFile,fam4MEDFile,renumber); - else - return buildMEDSubConnectivityOfOneTypesPolyh(conn,connIndex,families,conn4MEDFile,connIndex4MEDFile,connIndexRk24MEDFile,fam4MEDFile,renumber); - } -} - -/*! - * @param ids is a in vector containing families ids whose cells have to be kept. If empty all cells are kept. - * @param typesToKeep is a in vector that indicates which types to keep after dimension filtering. - * @param meshDimExtract out parameter that gives the mesh dimension. - * @param cellRenum out parameter that specifies the renumbering (if !=0) of cells in file. - */ -MEDCouplingUMesh *MEDLoaderNS::readUMeshFromFileLev1(const char *fileName, const char *meshName, int meshDimRelToMax, const std::vector& ids, - const std::vector& typesToKeep, unsigned& meshDimExtract, int *&cellRenum) throw(INTERP_KERNEL::Exception) -{ - if(meshDimRelToMax>0) - throw INTERP_KERNEL::Exception("meshDimRelToMax must be <=0 !"); - //Extraction data from MED file. - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY); - std::string trueMeshName; - med_int mid=getIdFromMeshName(fid,meshName,trueMeshName); - DataArrayDouble *coords=0; - std::list conn; - std::string descr; - readUMeshDataInMedFile(fid,mid,coords,conn,descr); - meshDimExtract=MEDLoaderNS::calculateHighestMeshDim(conn); - meshDimExtract=meshDimExtract+meshDimRelToMax; - MEDLoaderNS::keepSpecifiedMeshDim(conn,meshDimExtract); - MEDLoaderNS::keepTypes(conn,typesToKeep); - //Put data in returned data structure. - MEDCouplingUMesh *ret=MEDCouplingUMesh::New(); - ret->setName(trueMeshName.c_str()); - ret->setDescription(descr.c_str()); - ret->setMeshDimension(meshDimExtract); - // - ret->setCoords(coords); - coords->decrRef(); - // - DataArrayInt *connArr,*connIndexArr; - tradMEDFileCoreFrmt2MEDCouplingUMesh(conn,ids,connArr,connIndexArr,cellRenum); - ret->setConnectivity(connArr,connIndexArr); - //clean-up - if(connArr) - connArr->decrRef(); - if(connIndexArr) - connIndexArr->decrRef(); - releaseMEDFileCoreFrmt(conn); - return ret; -} - -ParaMEDMEM::MEDCouplingFieldDouble *MEDLoaderNS::readFieldDoubleLev2(const char *fileName, ParaMEDMEM::TypeOfField typeOfOutField, unsigned meshDim, const int *cellRenum, const ParaMEDMEM::MEDCouplingUMesh *mesh, - const std::vector& infos, const char *fieldName, int iteration, int order, double time, - std::list& fieldPerCellType) throw(INTERP_KERNEL::Exception) -{ - if(typeOfOutField==ON_CELLS || typeOfOutField==ON_GAUSS_PT || typeOfOutField==ON_GAUSS_NE) - MEDLoaderNS::keepSpecifiedMeshDim(fieldPerCellType,meshDim); - if(fieldPerCellType.empty()) - { - std::ostringstream oss; oss << "Error on reading file \"" << fileName << "\" meshName=\"" << mesh->getName(); - oss << std::endl << "FieldName=\"" << fieldName << "\" (iteration=" << iteration << ",order=" << order << ")" << std::endl; - if(typeOfOutField==ON_CELLS || typeOfOutField==ON_GAUSS_PT || typeOfOutField==ON_GAUSS_NE) - oss << "Request for cell field, maybe it is an ON_NODES field ?"; - else - oss << "Request for a node field, maybe it is an ON_CELLS field ?"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - //for profiles - MEDCouplingAutoRefCountObjectPtr newMesh; - std::string mName(mesh->getName()); - if(typeOfOutField==ON_NODES) - { - for(std::list::const_iterator iter=fieldPerCellType.begin();iter!=fieldPerCellType.end();iter++) - { - const std::vector& cellIds=(*iter).getCellIdPerType(); - if(!cellIds.empty()) - { - std::vector ci(cellIds.size()); - std::transform(cellIds.begin(),cellIds.end(),ci.begin(),std::bind2nd(std::plus(),-1)); - MEDCouplingAutoRefCountObjectPtr mesh2; - MEDCouplingAutoRefCountObjectPtr da,da2; - if((const ParaMEDMEM::MEDCouplingUMesh *)newMesh) - { - if((int)ci.size()!=newMesh->getNumberOfNodes()) - { - da=newMesh->getCellIdsFullyIncludedInNodeIds(&ci[0],&ci[ci.size()]); - DataArrayInt *tmpp=0; - mesh2=dynamic_cast(newMesh->buildPartAndReduceNodes(da->begin(),da->end(),tmpp)); da2=tmpp; - } - } - else - { - if((int)ci.size()!=mesh->getNumberOfNodes()) - { - da=mesh->getCellIdsFullyIncludedInNodeIds(&ci[0],&ci[ci.size()]); - DataArrayInt *tmpp=0; - mesh2=dynamic_cast(mesh->buildPartAndReduceNodes(da->begin(),da->end(),tmpp)); da2=tmpp; - // - int nnodes=mesh2->getNumberOfNodes(); - MEDCouplingAutoRefCountObjectPtr da3=DataArrayInt::New(); - const int *da2Ptr=da2->getConstPointer(); - da3->alloc(nnodes,1); - int *da3Ptr=da3->getPointer(); - for(int i=0;i<(int)ci.size();i++) - { - int val=da2Ptr[ci[i]]; - if(val!=-1) - da3Ptr[val]=i; - } - mesh2->renumberNodes(da3->getConstPointer(),nnodes); - } - else - { - mesh2=mesh->clone(true); - da=DataArrayInt::New(); - da->alloc((int)ci.size(),1); - std::copy(ci.begin(),ci.end(),da->getPointer()); - da2=da->invertArrayO2N2N2O(ci.size()); - mesh2->renumberNodes(da2->getConstPointer(),(int)ci.size()); - } - } - newMesh=mesh2; - } - } - } - else - { - newMesh=const_cast(static_cast(mesh)); mesh->incrRef(); - std::vector types; - for(std::list::const_iterator iter=fieldPerCellType.begin();iter!=fieldPerCellType.end();iter++) - if(std::find(types.begin(),types.end(),(*iter).getType())==types.end()) - types.push_back((*iter).getType()); - for(std::vector::const_iterator it=types.begin();it!=types.end();it++) - { - std::vector cids; - for(std::list::const_iterator iter=fieldPerCellType.begin();iter!=fieldPerCellType.end();iter++) - { - if((*iter).getType()==*it) - { - const std::vector& cellIds=(*iter).getCellIdPerType(); - if(!cellIds.empty()) - std::transform(cellIds.begin(),cellIds.end(),std::back_insert_iterator< std::vector >(cids),std::bind2nd(std::plus(),-1)); - } - } - if(!cids.empty()) - newMesh=newMesh->keepSpecifiedCells(*it,&cids[0],&cids[0]+cids.size()); - } - } - // - ParaMEDMEM::MEDCouplingFieldDouble *ret=ParaMEDMEM::MEDCouplingFieldDouble::New(typeOfOutField,ONE_TIME); - ret->setName(fieldName); - ret->setTime(time,iteration,order); - ParaMEDMEM::DataArrayDouble *arr=buildArrayFromRawData(fieldPerCellType,infos); - ret->setArray(arr); - arr->decrRef(); - if((const ParaMEDMEM::MEDCouplingUMesh *)newMesh) - { - newMesh->setName(mName.c_str());//retrieving mesh name to avoid renaming due to mesh restriction in case of profile. - ret->setMesh(newMesh); - } - else - ret->setMesh(mesh); - if(typeOfOutField==ON_GAUSS_PT) - fillGaussDataOnField(fileName,fieldPerCellType,ret); - if(cellRenum) - ret->renumberCellsWithoutMesh(cellRenum,true); - return ret; -} - -ParaMEDMEM::MEDCouplingFieldDouble *MEDLoaderNS::readFieldDoubleLev1(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order, - ParaMEDMEM::TypeOfField typeOfOutField) throw(INTERP_KERNEL::Exception) -{ - std::list fieldPerCellType; - double time; - std::vector infos; - readFieldDoubleDataInMedFile(fileName,meshName,fieldName,iteration,order,typeOfOutField,fieldPerCellType,time,infos); - std::vector familiesToKeep; - std::vector typesToKeep; - if(typeOfOutField==ON_CELLS || typeOfOutField==ON_GAUSS_PT || typeOfOutField==ON_GAUSS_NE) - for(std::list::const_iterator iter=fieldPerCellType.begin();iter!=fieldPerCellType.end();iter++) - typesToKeep.push_back((*iter).getType()); - unsigned meshDim; - int *cellRenum; - if(fieldPerCellType.empty()) - { - std::ostringstream oss; oss << "Error on reading file \"" << fileName << "\" meshName=\"" << meshName << "\" meshDimRelToMax=" << meshDimRelToMax; - oss << std::endl << "FieldName=\"" << fieldName << "\" (iteration=" << iteration << ",order=" << order << ")" << std::endl; - if(typeOfOutField==ON_CELLS || typeOfOutField==ON_GAUSS_PT || typeOfOutField==ON_GAUSS_NE) - oss << "Request for cell field, maybe it is a node instead or by changing meshDimRelToMax ?"; - else - oss << "Request for a node field, maybe it is a cell field instead ?"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - MEDCouplingAutoRefCountObjectPtr mesh=readUMeshFromFileLev1(fileName,meshName,meshDimRelToMax,familiesToKeep,typesToKeep,meshDim,cellRenum); - ParaMEDMEM::MEDCouplingFieldDouble *ret=readFieldDoubleLev2(fileName,typeOfOutField,meshDim,cellRenum,mesh,infos,fieldName,iteration,order,time,fieldPerCellType); - if(cellRenum) - mesh->renumberCells(cellRenum,true); - //clean-up - delete [] cellRenum; - releaseMEDFileCoreFrmt(fieldPerCellType); - return ret; -} - -/// @endcond - -MEDCouplingUMesh *MEDLoader::ReadUMeshFromFile(const char *fileName, const char *meshName, int meshDimRelToMax) throw(INTERP_KERNEL::Exception) +MEDCouplingUMesh *MEDLoader::ReadUMeshFromFile(const char *fileName, const char *meshName, int meshDimRelToMax) throw(INTERP_KERNEL::Exception) { CheckFileForRead(fileName); MEDCouplingAutoRefCountObjectPtr mm=MEDFileMesh::New(fileName,meshName); @@ -2155,37 +1125,33 @@ std::vector MEDLoader::ReadFieldsOnSameMes return std::vector(); CheckFileForRead(fileName); std::vector ret(its.size()); + std::vector< MEDCouplingAutoRefCountObjectPtr > retSafe(its.size()); if(its.empty()) return ret; //Retrieving mesh of rank 0 and field on rank 0 too. - std::list fieldPerCellType; - double time; - std::vector infos; - MEDLoaderNS::readFieldDoubleDataInMedFile(fileName,meshName,fieldName,its[0].first,its[0].second,type,fieldPerCellType,time,infos); - std::vector familiesToKeep; - std::vector typesToKeep; - if(type==ON_CELLS || type==ON_GAUSS_PT || type==ON_GAUSS_NE) - for(std::list::const_iterator iter=fieldPerCellType.begin();iter!=fieldPerCellType.end();iter++) - typesToKeep.push_back((*iter).getType()); - unsigned meshDim; - int *cellRenum; - MEDCouplingAutoRefCountObjectPtr m1=MEDLoaderNS::readUMeshFromFileLev1(fileName,meshName,meshDimRelToMax,familiesToKeep,typesToKeep,meshDim,cellRenum); - ret[0]=MEDLoaderNS::readFieldDoubleLev2(fileName,type,meshDim,cellRenum,m1,infos,fieldName,its[0].first,its[0].second,time,fieldPerCellType); - if(cellRenum) - m1->renumberCells(cellRenum,true); - MEDLoaderNS::releaseMEDFileCoreFrmt(fieldPerCellType); - // - for(int itId=1;itId<(int)its.size();itId++) - { - std::list fieldPerCellType2; - double timmee; - std::vector infoss; - MEDLoaderNS::readFieldDoubleDataInMedFile(fileName,meshName,fieldName,its[itId].first,its[itId].second,type,fieldPerCellType2,timmee,infoss); - ret[itId]=MEDLoaderNS::readFieldDoubleLev2(fileName,type,meshDim,cellRenum,m1,infoss,fieldName,its[itId].first,its[itId].second,timmee,fieldPerCellType2); - //clean-up - MEDLoaderNS::releaseMEDFileCoreFrmt(fieldPerCellType2); - } - delete [] cellRenum; + MEDCouplingAutoRefCountObjectPtr mm=MEDFileMesh::New(fileName,meshName); + MEDFileMesh *mmPtr(mm); + MEDFileUMesh *mmuPtr=dynamic_cast(mmPtr); + if(!mmuPtr) + throw INTERP_KERNEL::Exception("MEDLoader::ReadFieldsOnSameMesh : only unstructured mesh is managed !"); + MEDCouplingAutoRefCountObjectPtr m=mmuPtr->getMeshAtLevel(meshDimRelToMax); + const DataArrayInt *o2n=mmuPtr->getNumberFieldAtLevel(meshDimRelToMax); + MEDCouplingAutoRefCountObjectPtr m2(m->clone(true)); + if(o2n) + m2->renumberCells(o2n->begin(),true); + int i=0; + for(std::vector >::const_iterator it=its.begin();it!=its.end();it++,i++) + { + MEDCouplingAutoRefCountObjectPtr ff=MEDFileField1TS::New(fileName,fieldName,(*it).first,(*it).second); + MEDCouplingAutoRefCountObjectPtr retElt=ff->getFieldOnMeshAtLevel(type,m); + if(o2n) + retElt->renumberCells(o2n->begin(),true); + retElt->setMesh(m2); + retSafe[i]=retElt; + } + i=0; + for(std::vector >::const_iterator it=its.begin();it!=its.end();it++,i++) + ret[i]=retSafe[i].retn(); return ret; } @@ -2215,604 +1181,95 @@ std::vector MEDLoader::ReadFieldsGaussNEOn ParaMEDMEM::MEDCouplingFieldDouble *MEDLoader::ReadFieldCell(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception) { - return MEDLoaderNS::readFieldDoubleLev1(fileName,meshName,meshDimRelToMax,fieldName,iteration,order,ON_CELLS); + MEDCouplingAutoRefCountObjectPtr ff=MEDFileField1TS::New(fileName,fieldName,iteration,order); + MEDCouplingAutoRefCountObjectPtr mm=MEDFileMesh::New(fileName,meshName); + MEDCouplingAutoRefCountObjectPtr m=mm->getGenMeshAtLevel(meshDimRelToMax,false); + MEDFileMesh *mPtr(mm); + MEDFileUMesh *muPtr=dynamic_cast(mPtr); + MEDCouplingAutoRefCountObjectPtr ret=ff->getFieldOnMeshAtLevel(ON_CELLS,m); + if(muPtr) + { + const DataArrayInt *num=muPtr->getNumberFieldAtLevel(meshDimRelToMax); + if(num) + ret->renumberCells(num->begin()); + } + return ret.retn(); } ParaMEDMEM::MEDCouplingFieldDouble *MEDLoader::ReadFieldNode(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception) { - return MEDLoaderNS::readFieldDoubleLev1(fileName,meshName,meshDimRelToMax,fieldName,iteration,order,ON_NODES); -} - -ParaMEDMEM::MEDCouplingFieldDouble *MEDLoader::ReadFieldGauss(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception) -{ - return MEDLoaderNS::readFieldDoubleLev1(fileName,meshName,meshDimRelToMax,fieldName,iteration,order,ON_GAUSS_PT); -} - -ParaMEDMEM::MEDCouplingFieldDouble *MEDLoader::ReadFieldGaussNE(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception) -{ - return MEDLoaderNS::readFieldDoubleLev1(fileName,meshName,meshDimRelToMax,fieldName,iteration,order,ON_GAUSS_NE); -} - -/*! - * @param families input parameter that specifies the field on int on each cells of 'mesh'. - * @param isRenumbering output parameter that specifies if a renumbering of mesh has been needed. - */ -void MEDLoaderNS::writeUMeshesDirectly(const char *fileName, const std::vector& mesh, const std::vector& families, bool forceFromScratch, bool &isRenumbering) -{ - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,forceFromScratch?MED_ACC_CREAT:MED_ACC_RDWR); - std::string meshName(mesh[0]->getName()); - if(meshName=="") - throw INTERP_KERNEL::Exception("MEDCouplingMesh must have a not null name !"); - isRenumbering=false; - bool isFamilies=true; - std::vector conn; - std::vector connIndex; - std::set allTypes; - for(std::vector::const_iterator iter=mesh.begin();iter!=mesh.end();iter++) - { - isRenumbering|=!(*iter)->checkConsecutiveCellTypesAndOrder(typmai2,typmai2+MED_N_CELL_FIXED_GEO); - isFamilies&=(families[std::distance(mesh.begin(),iter)]!=0); - conn.push_back((*iter)->getNodalConnectivity()); - connIndex.push_back((*iter)->getNodalConnectivityIndex()); - const std::set& curTypes=(*iter)->getAllTypes(); - allTypes.insert(curTypes.begin(),curTypes.end()); - } - INTERP_KERNEL::AutoPtr maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE); - MEDLoaderBase::safeStrCpy(meshName.c_str(),MED_NAME_SIZE,maa,MEDLoader::_TOO_LONG_STR); - MEDLoaderBase::safeStrCpy(mesh[0]->getDescription(),MED_COMMENT_SIZE,desc,MEDLoader::_TOO_LONG_STR); - const int spaceDim=mesh[0]->getSpaceDimension(); - const int meshDim=mesh[0]->getMeshDimension(); - const DataArrayDouble *arr=mesh[0]->getCoords(); - INTERP_KERNEL::AutoPtr comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE); - INTERP_KERNEL::AutoPtr unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE); - for(int i=0;igetInfoOnComponent(i); - std::string c,u; - MEDLoaderBase::splitIntoNameAndUnit(info,c,u); - MEDLoaderBase::safeStrCpy2(c.c_str(),MED_SNAME_SIZE-1,comp+i*MED_SNAME_SIZE,MEDLoader::_TOO_LONG_STR);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo - MEDLoaderBase::safeStrCpy2(u.c_str(),MED_SNAME_SIZE-1,unit+i*MED_SNAME_SIZE,MEDLoader::_TOO_LONG_STR);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo - } - MEDmeshCr(fid,maa,spaceDim,meshDim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MED_CARTESIAN,comp,unit); - for(std::vector::const_iterator iter=mesh.begin();iter!=mesh.end();iter++) + MEDCouplingAutoRefCountObjectPtr ff=MEDFileField1TS::New(fileName,fieldName,iteration,order); + MEDCouplingAutoRefCountObjectPtr mm=MEDFileMesh::New(fileName,meshName); + MEDCouplingAutoRefCountObjectPtr m=mm->getGenMeshAtLevel(meshDimRelToMax,false); + MEDFileMesh *mPtr(mm); + MEDCouplingAutoRefCountObjectPtr ret=ff->getFieldOnMeshAtLevel(ON_NODES,m); + MEDFileUMesh *muPtr=dynamic_cast(mPtr); + if(ff->getPflsReallyUsed().empty()) { - for(int i=0;i medConn; - std::vector medConnIndex; - std::vector medConnIndex2; - std::vector fam; - std::vector renumber; - int nbOfElt=MEDLoaderNS::buildMEDSubConnectivityOfOneType(conn,connIndex,families,curType,medConn,medConnIndex,medConnIndex2,fam,renumber); - if(curMedType!=MED_POLYGON && curMedType!=MED_POLYHEDRON) - MEDmeshElementConnectivityWr(fid,maa,-1,-1,0.,MED_CELL,curMedType,MED_NODAL,MED_FULL_INTERLACE,nbOfElt,&medConn[0]); - else - { - if(curMedType==MED_POLYGON) - MEDmeshPolygonWr(fid,maa,-1,-1,0.,MED_CELL,MED_NODAL,medConnIndex.size(),&medConnIndex[0],&medConn[0]); - if(curMedType==MED_POLYHEDRON) - { - MEDmeshPolyhedronWr(fid,maa,-1,-1,0.,MED_CELL,MED_NODAL,medConnIndex2.size(),&medConnIndex2[0],medConnIndex.size(),&medConnIndex[0], - &medConn[0]); - } - } - if(isFamilies) - MEDmeshEntityFamilyNumberWr(fid,maa,-1,-1,MED_CELL,curMedType,nbOfElt,&fam[0]); - if(isRenumbering) - MEDmeshEntityNumberWr(fid,maa,-1,-1,MED_CELL,curMedType,nbOfElt,&renumber[0]); - } + const DataArrayInt *num=muPtr->getNumberFieldAtLevel(meshDimRelToMax); + if(num) + ret->renumberCells(num->begin()); } } - char familyName[MED_NAME_SIZE+1]; - std::fill(familyName,familyName+MED_NAME_SIZE+1,'\0'); - const char DftFamilyName[]="DftFamily"; - std::copy(DftFamilyName,DftFamilyName+sizeof(DftFamilyName),familyName); - MEDfamilyCr(fid,maa,familyName,0,0,0); - - MEDmeshNodeCoordinateWr(fid,maa,-1,-1,0.,MED_FULL_INTERLACE,mesh[0]->getNumberOfNodes(),arr->getConstPointer()); -} - -/*! - * In this method meshes are assumed to shared the same coords. - * This method makes the assumption that 'meshes' is not empty, no check on that is done (responsability of the caller) - */ -void MEDLoaderNS::writeUMeshesPartitionDirectly(const char *fileName, const char *meshName, const std::vector& meshes, bool forceFromScratch) -{ - std::string meshNameCpp(meshName); - INTERP_KERNEL::AutoPtr maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - MEDLoaderBase::safeStrCpy(meshName,MED_NAME_SIZE,maa,MEDLoader::_TOO_LONG_STR); - if(meshNameCpp=="") - throw INTERP_KERNEL::Exception("writeUMeshesPartitionDirectly : Invalid meshName : Must be different from \"\" !"); - std::vector< DataArrayInt * > corr; - MEDCouplingAutoRefCountObjectPtr m=ParaMEDMEM::MEDCouplingUMesh::FuseUMeshesOnSameCoords(meshes,0,corr); - m->setName(meshName); - std::vector< std::vector > fidsOfGroups; - std::vector< const DataArrayInt * > corr2(corr.begin(),corr.end()); - MEDCouplingAutoRefCountObjectPtr arr2=DataArrayInt::MakePartition(corr2,m->getNumberOfCells(),fidsOfGroups); - for(std::vector< DataArrayInt * >::iterator it=corr.begin();it!=corr.end();it++) - (*it)->decrRef(); - bool isRenumbering; - std::vector mv(1); mv[0]=m; - std::vector famv(1); famv[0]=arr2; - writeUMeshesDirectly(fileName,mv,famv,forceFromScratch,isRenumbering); - // families creation - std::set familyIds; - for(std::vector< std::vector >::const_iterator it1=fidsOfGroups.begin();it1!=fidsOfGroups.end();it1++) - for(std::vector::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++) - familyIds.insert(*it2); - std::vector< std::vector > gidsOfFamilies(familyIds.size()); - int fid=0; - for(std::set::const_iterator it=familyIds.begin();it!=familyIds.end();it++,fid++) - { - int gid=0; - for(std::vector< std::vector >::const_iterator it1=fidsOfGroups.begin();it1!=fidsOfGroups.end();it1++,gid++) - for(std::vector::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++) - if(*it2==*it) - gidsOfFamilies[fid].push_back(gid); - } - fid=0; - MEDFileUtilities::AutoFid fid2=MEDfileOpen(fileName,MED_ACC_RDWR); - for(std::set::const_iterator it=familyIds.begin();it!=familyIds.end();it++,fid++) - { - int ngro=gidsOfFamilies[fid].size(); - INTERP_KERNEL::AutoPtr groName=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE*ngro); - for(int i=0;igetName(),MED_LNAME_SIZE-1,groName+i*MED_LNAME_SIZE,MEDLoader::_TOO_LONG_STR);//MED_LNAME_SIZE-1 to avoid to write '\0' on next compo - std::ostringstream oss; oss << "Family_" << *it; - INTERP_KERNEL::AutoPtr famName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - MEDLoaderBase::safeStrCpy(oss.str().c_str(),MED_NAME_SIZE,famName,MEDLoader::_TOO_LONG_STR); - MEDfamilyCr(fid2,maa,famName,*it,ngro,groName); - } -} - -/*! - * This method makes the assumption that f->getMesh() nodes are fully included in already written mesh in 'fileName'. - * @param thisMeshNodeIds points to a tab of size f->getMesh()->getNumberOfNodes() that says for a node i in f->getMesh() that its id is thisMeshNodeIds[i] is already written mesh. - */ -void MEDLoaderNS::appendNodeProfileField(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, const int *thisMeshNodeIds) -{ - med_int numdt,numo; - med_float dt; - INTERP_KERNEL::AutoPtr nommaa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - MEDLoaderBase::safeStrCpy(f->getMesh()->getName(),MED_NAME_SIZE,nommaa,MEDLoader::_TOO_LONG_STR); - MEDFileUtilities::AutoFid fid=appendFieldSimpleAtt(fileName,f,numdt,numo,dt); - int nbOfNodes=f->getMesh()->getNumberOfNodes(); - const double *pt=f->getArray()->getConstPointer(); - INTERP_KERNEL::AutoPtr profile=new int[nbOfNodes]; - std::ostringstream oss; oss << "Pfln" << f->getName(); - INTERP_KERNEL::AutoPtr profileName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - MEDLoaderBase::safeStrCpy(oss.str().c_str(),MED_NAME_SIZE,profileName,MEDLoader::_TOO_LONG_STR); - std::transform(thisMeshNodeIds,thisMeshNodeIds+nbOfNodes,(int *)profile,std::bind2nd(std::plus(),1)); - MEDprofileWr(fid,profileName,nbOfNodes,profile); - MEDfieldValueWithProfileWr(fid,f->getName(),numdt,numo,dt,MED_NODE,MED_NONE,MED_COMPACT_PFLMODE,profileName,MED_NO_LOCALIZATION,MED_FULL_INTERLACE,MED_ALL_CONSTITUENT,nbOfNodes,(const unsigned char*)pt); -} - -/*! - * This method makes the assumption that f->getMesh() cells are fully included in already written mesh in 'fileName'. - * @param thisMeshCellIdsPerType points to a tab of size f->getMesh()->getNumberOfCells() that says for a cell i in f->getMesh() that its id is thisMeshCellIds[i] of corresponding type is already written mesh. - */ -void MEDLoaderNS::appendCellProfileField(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, const int *thisMeshCellIdsPerType) -{ - med_int numdt,numo; - med_float dt; - int nbComp=f->getNumberOfComponents(); - MEDFileUtilities::AutoFid fid=appendFieldSimpleAtt(fileName,f,numdt,numo,dt); - std::list split; - prepareCellFieldDoubleForWriting(f,thisMeshCellIdsPerType,split); - const double *pt=f->getArray()->getConstPointer(); - int number=0; - for(std::list::const_iterator iter=split.begin();iter!=split.end();iter++) - { - INTERP_KERNEL::AutoPtr nommaa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - MEDLoaderBase::safeStrCpy(f->getMesh()->getName(),MED_NAME_SIZE,nommaa,MEDLoader::_TOO_LONG_STR); - INTERP_KERNEL::AutoPtr profileName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - std::ostringstream oss; oss << "Pfl" << f->getName() << "_" << number++; - MEDLoaderBase::safeStrCpy(oss.str().c_str(),MED_NAME_SIZE,profileName,MEDLoader::_TOO_LONG_STR); - const std::vector& ids=(*iter).getCellIdPerType(); - INTERP_KERNEL::AutoPtr profile=new int [ids.size()]; - std::transform(ids.begin(),ids.end(),(int *)profile,std::bind2nd(std::plus(),1)); - MEDprofileWr(fid,profileName,ids.size(),profile); - MEDfieldValueWithProfileWr(fid,f->getName(),numdt,numo,dt,MED_CELL,typmai3[(int)(*iter).getType()],MED_COMPACT_PFLMODE,profileName, - MED_NO_LOCALIZATION,MED_FULL_INTERLACE,MED_ALL_CONSTITUENT,(*iter).getNbOfTuple(),(const unsigned char*)pt); - pt+=(*iter).getNbOfTuple()*nbComp; - } -} - -void MEDLoaderNS::appendNodeElementProfileField(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, const int *thisMeshCellIdsPerType) -{ - med_int numdt,numo; - med_float dt; - int nbComp=f->getNumberOfComponents(); - MEDFileUtilities::AutoFid fid=appendFieldSimpleAtt(fileName,f,numdt,numo,dt); - std::list split; - prepareCellFieldDoubleForWriting(f,thisMeshCellIdsPerType,split); - const double *pt=f->getArray()->getConstPointer(); - int number=0; - for(std::list::const_iterator iter=split.begin();iter!=split.end();iter++) - { - INTERP_KERNEL::AutoPtr nommaa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - MEDLoaderBase::safeStrCpy(f->getMesh()->getName(),MED_NAME_SIZE,nommaa,MEDLoader::_TOO_LONG_STR); - INTERP_KERNEL::AutoPtr profileName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - std::ostringstream oss; oss << "Pfl" << f->getName() << "_" << number++; - MEDLoaderBase::safeStrCpy(oss.str().c_str(),MED_NAME_SIZE,profileName,MEDLoader::_TOO_LONG_STR); - const std::vector& ids=(*iter).getCellIdPerType(); - INTERP_KERNEL::AutoPtr profile=new int [ids.size()]; - std::transform(ids.begin(),ids.end(),(int *)profile,std::bind2nd(std::plus(),1)); - MEDprofileWr(fid,profileName,ids.size(),profile); - int nbPtPerCell=(int)INTERP_KERNEL::CellModel::GetCellModel((*iter).getType()).getNumberOfNodes(); - int nbOfEntity=f->getMesh()->getNumberOfCellsWithType((*iter).getType()); - int nbOfValues=nbPtPerCell*nbOfEntity; - MEDfieldValueWithProfileWr(fid,f->getName(),numdt,numo,dt,MED_NODE_ELEMENT,typmai3[(int)(*iter).getType()], - MED_COMPACT_PFLMODE,profileName, - MED_NO_LOCALIZATION,MED_FULL_INTERLACE,MED_ALL_CONSTITUENT, - nbOfEntity,(const unsigned char*)pt); - pt+=nbOfValues*nbComp; - } -} - -/*! - * This method performs the classical job for fields before any values setting. - */ -med_idt MEDLoaderNS::appendFieldSimpleAtt(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, med_int& numdt, med_int& numo, med_float& dt) -{ - std::string fieldName(f->getName()); - if(fieldName.empty()) - throw INTERP_KERNEL::Exception("MEDLoaderNS::appendFieldSimpleAtt : Trying to store a field with no name ! MED file format requires a NON EMPTY field name !"); - med_idt fid=MEDfileOpen(fileName,MED_ACC_RDWR); - int nbComp=f->getNumberOfComponents(); - INTERP_KERNEL::AutoPtr comp=MEDLoaderBase::buildEmptyString(nbComp*MED_SNAME_SIZE); - INTERP_KERNEL::AutoPtr unit=MEDLoaderBase::buildEmptyString(nbComp*MED_SNAME_SIZE); - for(int i=0;igetArray()->getInfoOnComponent(i); - std::string c,u; - MEDLoaderBase::splitIntoNameAndUnit(info,c,u); - MEDLoaderBase::safeStrCpy2(c.c_str(),MED_SNAME_SIZE-1,comp+i*MED_SNAME_SIZE,MEDLoader::_TOO_LONG_STR); - MEDLoaderBase::safeStrCpy2(u.c_str(),MED_SNAME_SIZE-1,unit+i*MED_SNAME_SIZE,MEDLoader::_TOO_LONG_STR); - } - INTERP_KERNEL::AutoPtr dt_unit=MEDLoaderBase::buildEmptyString(MED_SNAME_SIZE); - INTERP_KERNEL::AutoPtr maaname=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr fname=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - MEDLoaderBase::safeStrCpy(f->getName(),MED_NAME_SIZE,fname,MEDLoader::_TOO_LONG_STR); - MEDLoaderBase::safeStrCpy(f->getMesh()->getName(),MED_NAME_SIZE,maaname,MEDLoader::_TOO_LONG_STR); - MEDLoaderBase::safeStrCpy(f->getTimeUnit(),MED_SNAME_SIZE,dt_unit,MEDLoader::_TOO_LONG_STR); - MEDfieldCr(fid,fname,MED_FLOAT64,nbComp,comp,unit,dt_unit,maaname); - ParaMEDMEM::TypeOfTimeDiscretization td=f->getTimeDiscretization(); - if(td==ParaMEDMEM::NO_TIME) - { - numdt=MED_NO_DT; numo=MED_NO_IT; dt=0.0; - } - else if(td==ParaMEDMEM::ONE_TIME) - { - int tmp1,tmp2; - double tmp0=f->getTime(tmp1,tmp2); - numdt=(med_int)tmp1; numo=(med_int)tmp2; - dt=(med_float)tmp0; - } - return fid; -} - -void MEDLoaderNS::appendFieldDirectly(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f2) -{ - med_int numdt,numo; - med_float dt; - //renumbering - const ParaMEDMEM::MEDCouplingFieldDouble *f=f2; - const MEDCouplingMesh *mesh=f->getMesh(); - const MEDCouplingUMesh *meshC=dynamic_cast(mesh); - if(!meshC) - throw INTERP_KERNEL::Exception("Not implemented yet for not unstructured mesh !"); - bool renum=!meshC->checkConsecutiveCellTypesAndOrder(typmai2,typmai2+MED_N_CELL_FIXED_GEO); - if(renum) - { - ParaMEDMEM::MEDCouplingFieldDouble *f3=f2->clone(true); - MEDCouplingAutoRefCountObjectPtr da=meshC->getRenumArrForConsecutiveCellTypesSpec(typmai2,typmai2+MED_N_CELL_FIXED_GEO); - f3->renumberCells(da->getConstPointer(),false); - f=f3; - } - //end renumbering - int nbComp=f->getNumberOfComponents(); - MEDFileUtilities::AutoFid fid=appendFieldSimpleAtt(fileName,f,numdt,numo,dt); - const double *pt=f->getArray()->getConstPointer(); - INTERP_KERNEL::AutoPtr nommaa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - MEDLoaderBase::safeStrCpy(f->getMesh()->getName(),MED_NAME_SIZE,nommaa,MEDLoader::_TOO_LONG_STR); - switch(f->getTypeOfField()) - { - case ParaMEDMEM::ON_CELLS: - { - std::list split; - prepareCellFieldDoubleForWriting(f,0,split); - for(std::list::const_iterator iter=split.begin();iter!=split.end();iter++) - { - MEDfieldValueWithProfileWr(fid,f->getName(),numdt,numo,dt,MED_CELL,typmai3[(int)(*iter).getType()],MED_COMPACT_PFLMODE, - MED_ALLENTITIES_PROFILE,MED_NO_LOCALIZATION,MED_FULL_INTERLACE,MED_ALL_CONSTITUENT,(*iter).getNbOfTuple(),(const unsigned char*)pt); - pt+=(*iter).getNbOfTuple()*nbComp; - } - break; - } - case ParaMEDMEM::ON_NODES: - { - int nbOfTuples=f->getArray()->getNumberOfTuples(); - MEDfieldValueWithProfileWr(fid,f->getName(),numdt,numo,dt,MED_NODE,MED_NONE,MED_COMPACT_PFLMODE, - MED_ALLENTITIES_PROFILE,MED_NO_LOCALIZATION,MED_FULL_INTERLACE,MED_ALL_CONSTITUENT,nbOfTuples,(const unsigned char*)pt); - break; - } - case ParaMEDMEM::ON_GAUSS_PT: - { - INTERP_KERNEL::AutoPtr profileName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - std::list split; - prepareCellFieldDoubleForWriting(f,0,split); - int idGp=0,offset=0,offset2=0; - const double *pt2=0; - INTERP_KERNEL::NormalizedCellType prevType=INTERP_KERNEL::NORM_ERROR; - for(std::list::const_iterator iter=split.begin();iter!=split.end();iter++) - { - if((*iter).getType()!=prevType) - { - offset=offset2; - prevType=(*iter).getType(); - } - INTERP_KERNEL::AutoPtr nomGauss=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - std::ostringstream oss; oss << "GP_" << f->getName() << idGp++; - MEDLoaderBase::safeStrCpy(oss.str().c_str(),MED_NAME_SIZE,nomGauss,MEDLoader::_TOO_LONG_STR); - std::ostringstream ossPfl; - int id=-1,nbOfEntity=-1; - MEDCouplingAutoRefCountObjectPtr arrTmp; - if((*iter).getCellIdPerType().empty()) - { - id=f->getGaussLocalizationIdOfOneType((*iter).getType()); - nbOfEntity=f->getMesh()->getNumberOfCellsWithType((*iter).getType()); - } - else - { - id=f->getGaussLocalizationIdOfOneCell((*iter).getCellIdPerType()[0]+offset); - nbOfEntity=(int)(*iter).getCellIdPerType().size(); - ossPfl << "Pfl" << f->getName() << "_" << id; - MEDLoaderBase::safeStrCpy(ossPfl.str().c_str(),MED_NAME_SIZE,profileName,MEDLoader::_TOO_LONG_STR); - INTERP_KERNEL::AutoPtr profile=new int[(*iter).getCellIdPerType().size()]; - std::transform((*iter).getCellIdPerType().begin(),(*iter).getCellIdPerType().end(),(int *)profile,std::bind2nd(std::plus(),1)); - MEDprofileWr(fid,profileName,(*iter).getCellIdPerType().size(),profile); - // - MEDCouplingAutoRefCountObjectPtr da3=DataArrayInt::New(); - da3->useArray(const_cast(&((*iter).getCellIdPerType()[0])),false,CPP_DEALLOC,(int)(*iter).getCellIdPerType().size(),1); - MEDCouplingAutoRefCountObjectPtr da4=da3->deepCpy(); - da4->applyLin(1,offset); - // - const MEDCouplingFieldDiscretizationGauss *disc2=static_cast(f->getDiscretization()); - MEDCouplingAutoRefCountObjectPtr arr=disc2->getOffsetArr(f->getMesh()); - MEDCouplingAutoRefCountObjectPtr tmp=DataArrayInt::New(); - int trueNval=0; - for(const int *pt3=da4->begin();pt3!=da4->end();pt3++) - trueNval+=arr->getIJ(*pt3+1,0)-arr->getIJ(*pt3,0); - tmp->alloc(trueNval,1); - int *tmpPtr=tmp->getPointer(); - for(const int *pt3=da4->begin();pt3!=da4->end();pt3++) - for(int j=arr->getIJ(*pt3,0);jgetIJ(*pt3+1,0);j++) - *tmpPtr++=j; - arrTmp=f->getArray()->selectByTupleId(tmp->begin(),tmp->end()); - pt2=arrTmp->getConstPointer(); - } - const MEDCouplingGaussLocalization& gl=f->getGaussLocalization(id); - MEDlocalizationWr(fid,nomGauss,typmai3[(int)(*iter).getType()],mesh->getMeshDimension(),&gl.getRefCoords()[0],MED_FULL_INTERLACE, - gl.getNumberOfGaussPt(),&gl.getGaussCoords()[0],&gl.getWeights()[0],MED_NO_INTERPOLATION, MED_NO_MESH_SUPPORT); - int nbOfValues=gl.getNumberOfGaussPt()*nbOfEntity; - INTERP_KERNEL::AutoPtr fieldname=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - MEDLoaderBase::safeStrCpy(f->getName(),MED_NAME_SIZE,fieldname,MEDLoader::_TOO_LONG_STR); - if((*iter).getCellIdPerType().empty()) - { - MEDfieldValueWithProfileWr(fid,fieldname,numdt,numo,dt,MED_CELL,typmai3[(int)(*iter).getType()],MED_COMPACT_PFLMODE, - MED_ALLENTITIES_PROFILE,nomGauss,MED_FULL_INTERLACE,MED_ALL_CONSTITUENT,nbOfEntity,(const unsigned char*)pt); - } - else - MEDfieldValueWithProfileWr(fid,fieldname,numdt,numo,dt,MED_CELL,typmai3[(int)(*iter).getType()],MED_COMPACT_PFLMODE, - profileName,nomGauss,MED_FULL_INTERLACE,MED_ALL_CONSTITUENT,nbOfEntity,(const unsigned char*)pt2); - pt+=nbOfValues*nbComp; - offset2+=(*iter).getNbOfGeoElt(); - } - break; - } - case ParaMEDMEM::ON_GAUSS_NE: - { - std::list split; - prepareCellFieldDoubleForWriting(f,0,split); - for(std::list::const_iterator iter=split.begin();iter!=split.end();iter++) - { - int nbPtPerCell=(int)INTERP_KERNEL::CellModel::GetCellModel((*iter).getType()).getNumberOfNodes(); - int nbOfEntity=f->getMesh()->getNumberOfCellsWithType((*iter).getType()); - int nbOfValues=nbPtPerCell*nbOfEntity; - MEDfieldValueWithProfileWr(fid,f->getName(),numdt,numo,dt,MED_NODE_ELEMENT,typmai3[(int)(*iter).getType()],MED_COMPACT_PFLMODE, - MED_ALLENTITIES_PROFILE,MED_NO_LOCALIZATION,MED_FULL_INTERLACE,MED_ALL_CONSTITUENT,nbOfEntity,(const unsigned char*)pt); - pt+=nbOfValues*nbComp; - } - break; - } - default: - throw INTERP_KERNEL::Exception("Not managed this type of FIELD !"); - } - if(renum) - f->decrRef(); -} - -/*! - * This method splits field 'f' into types to be ready for writing. - * @param cellIdsPerType this parameter can be 0 if not in profile mode. If it is != 0 this array is of size f->getMesh()->getNumberOfCells(). - */ -void MEDLoaderNS::prepareCellFieldDoubleForWriting(const ParaMEDMEM::MEDCouplingFieldDouble *f, const int *cellIdsPerType, std::list& split) -{ - int nbComp=f->getNumberOfComponents(); - const MEDCouplingMesh *mesh=f->getMesh(); - const MEDCouplingUMesh *meshC=dynamic_cast(mesh); - if(!meshC) - throw INTERP_KERNEL::Exception("Not implemented yet for not unstructured mesh !"); - if(!meshC->checkConsecutiveCellTypesAndOrder(typmai2,typmai2+MED_N_CELL_FIXED_GEO)) - throw INTERP_KERNEL::Exception("Unstructuded mesh has not consecutive cell types !"); - const int *connI=meshC->getNodalConnectivityIndex()->getConstPointer(); - const int *conn=meshC->getNodalConnectivity()->getConstPointer(); - int nbOfCells=meshC->getNumberOfCells(); - INTERP_KERNEL::NormalizedCellType curType; - const int *wCellIdsPT=cellIdsPerType; - for(const int *pt=connI;pt!=connI+nbOfCells;) + else { - curType=(INTERP_KERNEL::NormalizedCellType)conn[*pt]; - const int *pt2=std::find_if(pt+1,connI+nbOfCells,ConnReaderML(conn,(int)curType)); - int szOfChunk=std::distance(pt,pt2); - if(f->getTypeOfField()!=ON_GAUSS_PT) - { - if(!cellIdsPerType) - split.push_back(MEDLoader::MEDFieldDoublePerCellType(curType,0,nbComp,szOfChunk,1,0,0)); - else - { - split.push_back(MEDLoader::MEDFieldDoublePerCellType(curType,0,nbComp,szOfChunk,1,wCellIdsPT,0)); - wCellIdsPT+=szOfChunk; - } - } - else + DataArrayInt *pfl=0,*arr2=0; + MEDCouplingAutoRefCountObjectPtr arr=ff->getFieldWithProfile(ON_NODES,meshDimRelToMax,mm,pfl); + MEDCouplingAutoRefCountObjectPtr pflSafe(pfl); + MEDCouplingAutoRefCountObjectPtr mp=m->getCellIdsFullyIncludedInNodeIds(pfl->begin(),pfl->end()); + MEDCouplingAutoRefCountObjectPtr mzip=static_cast(m->buildPartAndReduceNodes(mp->begin(),mp->end(),arr2)); + MEDCouplingAutoRefCountObjectPtr arr2Safe(arr2); + MEDCouplingAutoRefCountObjectPtr arr3=arr2->invertArrayO2N2N2O(mzip->getNumberOfNodes()); + MEDCouplingAutoRefCountObjectPtr pflSorted(pflSafe->deepCpy()); pflSorted->sort(true); + if(!arr3->isEqualWithoutConsideringStr(*pflSorted)) + throw INTERP_KERNEL::Exception("MEDLoader::ReadFieldNode : not implemented yet !"); + if(!arr3->isEqualWithoutConsideringStr(*pflSafe)) { - const MEDCouplingFieldDiscretizationGauss *disc=static_cast(f->getDiscretization()); - const DataArrayInt *arr=disc->getArrayOfDiscIds(); - MEDCouplingAutoRefCountObjectPtr da,daTmp1; - if(!cellIdsPerType) - da=arr->selectByTupleId2(std::distance(connI,pt),std::distance(connI,pt2),1); - else - { - daTmp1=DataArrayInt::New(); - daTmp1->useArray(const_cast(cellIdsPerType),false,CPP_DEALLOC,szOfChunk,1); - MEDCouplingAutoRefCountObjectPtr daTmp2=daTmp1->deepCpy(); - daTmp2->applyLin(1,std::distance(connI,pt)); - da=arr->selectByTupleId(daTmp2->begin(),daTmp2->end()); - } - std::vector differentIds; - std::vector parts=da->partitionByDifferentValues(differentIds); - std::vector< MEDCouplingAutoRefCountObjectPtr > partsAuto(parts.size()); - int jj=0; - for(std::vector::const_iterator it=parts.begin();it!=parts.end();it++,jj++) - partsAuto[jj]=parts[jj]; - jj=0; - for(std::vector::const_iterator it=parts.begin();it!=parts.end();it++,jj++) - { - if(!cellIdsPerType) - { - if(parts[jj]->getNumberOfTuples()==szOfChunk && parts[jj]->isIdentity()) - split.push_back(MEDLoader::MEDFieldDoublePerCellType(curType,0,nbComp,szOfChunk,1,0,0)); - else - split.push_back(MEDLoader::MEDFieldDoublePerCellType(curType,0,nbComp,parts[jj]->getNumberOfTuples(),1,parts[jj]->getConstPointer(),0)); - } - else - { - MEDCouplingAutoRefCountObjectPtr tmp=daTmp1->selectByTupleId(parts[jj]->begin(),parts[jj]->end()); - split.push_back(MEDLoader::MEDFieldDoublePerCellType(curType,0,nbComp,tmp->getNumberOfTuples(),1,tmp->getConstPointer(),0)); - } - } - if(!cellIdsPerType) - wCellIdsPT+=szOfChunk; + MEDCouplingAutoRefCountObjectPtr o2n2=pflSafe->checkAndPreparePermutation(); + MEDCouplingAutoRefCountObjectPtr n2o2=o2n2->invertArrayO2N2N2O(o2n2->getNumberOfTuples()); + mzip->renumberNodes(n2o2->begin(),n2o2->getNumberOfTuples()); + arr->setName(""); + ret->setArray(arr); } - pt=pt2; + ret->setMesh(mzip); } + return ret.retn(); } -void MEDLoaderNS::writeFieldAndMeshDirectly(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, bool forceFromScratch) +ParaMEDMEM::MEDCouplingFieldDouble *MEDLoader::ReadFieldGauss(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception) { - f->checkCoherency(); - std::string meshName(f->getMesh()->getName()); - if(meshName.empty()) - throw INTERP_KERNEL::Exception("Trying to write a mesh (f->getMesh()) with no name ! MED file format needs a not empty mesh name !"); - std::string fieldName(f->getName()); - if(fieldName.empty()) - throw INTERP_KERNEL::Exception("Trying to write a field with no name ! MED file format needs a not empty field name !"); - MEDCouplingUMesh *mesh=dynamic_cast(const_cast(f->getMesh())); - if(mesh) + MEDCouplingAutoRefCountObjectPtr ff=MEDFileField1TS::New(fileName,fieldName,iteration,order); + MEDCouplingAutoRefCountObjectPtr mm=MEDFileMesh::New(fileName,meshName); + MEDCouplingAutoRefCountObjectPtr m=mm->getGenMeshAtLevel(meshDimRelToMax,false); + MEDFileMesh *mPtr(mm); + MEDFileUMesh *muPtr=dynamic_cast(mPtr); + MEDCouplingAutoRefCountObjectPtr ret=ff->getFieldOnMeshAtLevel(ON_GAUSS_PT,m); + if(muPtr) { - bool isRenumbering; - std::vector meshV(1); meshV[0]=mesh; - std::vector famV(1); famV[0]=0; - writeUMeshesDirectly(fileName,meshV,famV,forceFromScratch,isRenumbering); - if(isRenumbering) - { - MEDCouplingAutoRefCountObjectPtr f2=f->clone(true); - MEDCouplingAutoRefCountObjectPtr da=mesh->getRenumArrForConsecutiveCellTypesSpec(typmai2,typmai2+MED_N_CELL_FIXED_GEO); - f2->renumberCells(da->getConstPointer(),false); - appendFieldDirectly(fileName,f2); - } - else - appendFieldDirectly(fileName,f); - return ; + const DataArrayInt *num=muPtr->getNumberFieldAtLevel(meshDimRelToMax); + if(num) + ret->renumberCells(num->begin()); } - throw INTERP_KERNEL::Exception("The mesh underlying field is not unstructured ! Only unstructured mesh supported for writting now !"); + return ret.retn(); } -/*! - * When called this method expectes that file 'fileName' is already existing and has a mesh with name equal to - * f->getMesh()->getName(). If not the behaviour of this method is not warranted. - * This method reads the corresponding mesh into the file and try to fit it with f->getMesh(). - * If it appears that f->getMesh() equals exactly mesh into the file - */ -void MEDLoaderNS::writeFieldTryingToFitExistingMesh(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f) +ParaMEDMEM::MEDCouplingFieldDouble *MEDLoader::ReadFieldGaussNE(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception) { - std::vector poss; - int mDimInFile=MEDLoaderNS::readUMeshDimFromFile(fileName,f->getMesh()->getName(),poss); - int mdim=f->getMesh()->getMeshDimension(); - int f2=mdim-mDimInFile; - if(std::find(poss.begin(),poss.end(),f2)==poss.end()) - { - std::ostringstream oss; oss << "Trying to fit with the existing \"" << f->getMesh()->getName() << "mesh in file \"" << fileName; - oss << "\" but meshdimension does not match !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - MEDCouplingAutoRefCountObjectPtr m=MEDLoader::ReadUMeshFromFile(fileName,f->getMesh()->getName(),f2); - MEDCouplingAutoRefCountObjectPtr m2=MEDCouplingUMesh::MergeUMeshes(m,static_cast(f->getMesh())); - bool areNodesMerged; - int newNbOfNodes; - MEDCouplingAutoRefCountObjectPtr da=m2->mergeNodes(MEDLoader::_EPS_FOR_NODE_COMP,areNodesMerged,newNbOfNodes); - if(!areNodesMerged || newNbOfNodes!=m->getNumberOfNodes()) - { - std::ostringstream oss; oss << "Nodes in already written mesh \"" << f->getMesh()->getName() << "\" in file \"" << fileName << "\" does not fit coordinates of unstructured grid f->getMesh() !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - switch(f->getTypeOfField()) + MEDCouplingAutoRefCountObjectPtr ff=MEDFileField1TS::New(fileName,fieldName,iteration,order); + MEDCouplingAutoRefCountObjectPtr mm=MEDFileMesh::New(fileName,meshName); + MEDCouplingAutoRefCountObjectPtr m=mm->getGenMeshAtLevel(meshDimRelToMax,false); + MEDFileMesh *mPtr(mm); + MEDFileUMesh *muPtr=dynamic_cast(mPtr); + MEDCouplingAutoRefCountObjectPtr ret=ff->getFieldOnMeshAtLevel(ON_GAUSS_NE,m); + if(muPtr) { - case ParaMEDMEM::ON_CELLS: - { - MEDCouplingAutoRefCountObjectPtr da2=m2->zipConnectivityTraducer(MEDLoader::_COMP_FOR_CELL); - if(m2->getNumberOfCells()!=m->getNumberOfCells()) - { - std::ostringstream oss1; oss1 << "Cells in already written mesh \"" << f->getMesh()->getName() << "\" in file \"" << fileName << "\" does not fit connectivity of unstructured grid f->getMesh() !"; - throw INTERP_KERNEL::Exception(oss1.str().c_str()); - } - da=m2->convertCellArrayPerGeoType(da2); - MEDCouplingAutoRefCountObjectPtr da3=da->substr(m2->getNumberOfCells()); - da2=m2->convertCellArrayPerGeoType(da3); - appendCellProfileField(fileName,f,da2->getConstPointer()); - break; - } - case ParaMEDMEM::ON_GAUSS_NE: - { - MEDCouplingAutoRefCountObjectPtr da2=m2->zipConnectivityTraducer(MEDLoader::_COMP_FOR_CELL); - if(m2->getNumberOfCells()!=m->getNumberOfCells()) - { - std::ostringstream oss1; oss1 << "Cells in already written mesh \"" << f->getMesh()->getName() << "\" in file \"" << fileName << "\" does not fit connectivity of unstructured grid f->getMesh() !"; - throw INTERP_KERNEL::Exception(oss1.str().c_str()); - } - da=m2->convertCellArrayPerGeoType(da2); - MEDCouplingAutoRefCountObjectPtr da3=da->substr(m2->getNumberOfCells()); - da2=m2->convertCellArrayPerGeoType(da3); - appendNodeElementProfileField(fileName,f,da2->getConstPointer()); - break; - } - case ParaMEDMEM::ON_NODES: - { - appendNodeProfileField(fileName,f,da->getConstPointer()+m->getNumberOfNodes()); - break; - } - default: - { - throw INTERP_KERNEL::Exception("Not implemented other profile fitting from already written mesh for fields than on NODES and on CELLS."); - } + const DataArrayInt *num=muPtr->getNumberFieldAtLevel(meshDimRelToMax); + if(num) + ret->renumberCells(num->begin()); } + return ret.retn(); } void MEDLoader::WriteUMesh(const char *fileName, const ParaMEDMEM::MEDCouplingUMesh *mesh, bool writeFromScratch) throw(INTERP_KERNEL::Exception) @@ -2855,102 +1312,129 @@ void MEDLoader::WriteUMeshesPartitionDep(const char *fileName, const char *meshN void MEDLoader::WriteUMeshes(const char *fileName, const std::vector& meshes, bool writeFromScratch) throw(INTERP_KERNEL::Exception) { - int status=MEDLoaderBase::getStatusOfFile(fileName); - if(status!=MEDLoaderBase::EXIST_RW && status!=MEDLoaderBase::NOT_EXIST) - { - std::ostringstream oss; oss << "File with name \'" << fileName << "\' has not valid permissions !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(meshes.empty()) - throw INTERP_KERNEL::Exception("List of meshes must be not empty !"); - std::string meshName(meshes[0]->getName()); - if(meshName.empty()) - throw INTERP_KERNEL::Exception("Trying to write a unstructured mesh with no name ! MED file format needs a not empty mesh name : change name of first element of 2nd parameter !"); - const DataArrayDouble *coords=meshes.front()->getCoords(); - for(std::vector::const_iterator iter=meshes.begin();iter!=meshes.end();iter++) - if(coords!=(*iter)->getCoords()) - throw INTERP_KERNEL::Exception("Meshes does not not share the same coordinates : try method MEDCouplingPointSet::tryToShareSameCoords !"); - std::set tmp; - for(std::vector::const_iterator iter=meshes.begin();iter!=meshes.end();iter++) - { - if(tmp.find((*iter)->getMeshDimension())==tmp.end()) - tmp.insert((*iter)->getMeshDimension()); - else - throw INTERP_KERNEL::Exception("The mesh dimension of meshes must be different each other !"); - } - tmp.clear(); - bool isRenumbering; - std::vector families(meshes.size()); - if(writeFromScratch) - { - MEDLoaderNS::writeUMeshesDirectly(fileName,meshes,families,true,isRenumbering); - return ; - } - if(status==MEDLoaderBase::NOT_EXIST) + int mod=writeFromScratch?2:0; + MEDCouplingAutoRefCountObjectPtr m=MEDFileUMesh::New(); + m->setMeshes(meshes,true); + m->write(fileName,mod); +} + +void MEDLoaderNS::writeFieldWithoutReadingAndMappingOfMeshInFile(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, bool writeFromScratch) +{ + MEDCouplingAutoRefCountObjectPtr ff=MEDFileField1TS::New(); + MEDCouplingAutoRefCountObjectPtr f2(f->deepCpy()); + const MEDCouplingMesh *m=f2->getMesh(); + const MEDCouplingUMesh *um=dynamic_cast(m); + MEDCouplingAutoRefCountObjectPtr mm; + int mod=writeFromScratch?2:0; + if(um) { - MEDLoaderNS::writeUMeshesDirectly(fileName,meshes,families,true,isRenumbering); - return; + MEDCouplingAutoRefCountObjectPtr mmu=MEDFileUMesh::New(); + MEDCouplingAutoRefCountObjectPtr o2n=um->getRenumArrForMEDFileFrmt(); + MEDCouplingAutoRefCountObjectPtr n2o=o2n->invertArrayO2N2N2O(o2n->getNumberOfTuples()); + f2->renumberCells(o2n->begin(),false); + mmu->setMeshAtLevel(0,const_cast(static_cast(f2->getMesh()))); + mmu->setRenumFieldArr(0,n2o); + ff->setFieldNoProfileSBT(f2); + mmu->write(fileName,mod); } else - { - MEDLoaderNS::writeUMeshesDirectly(fileName,meshes,families,false,isRenumbering); - return; - } + throw INTERP_KERNEL::Exception("MEDLoaderNS::writeFieldWithoutReadingAndMappingOfMeshInFile : only umeshes are dealed in this API for the moment !"); + ff->write(fileName,0); } void MEDLoader::WriteField(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, bool writeFromScratch) throw(INTERP_KERNEL::Exception) { + if(!f) + throw INTERP_KERNEL::Exception("MEDLoader::WriteField : input field is NULL !"); + f->checkCoherency(); int status=MEDLoaderBase::getStatusOfFile(fileName); if(status!=MEDLoaderBase::EXIST_RW && status!=MEDLoaderBase::NOT_EXIST) { std::ostringstream oss; oss << "File with name \'" << fileName << "\' has not valid permissions !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } - if(writeFromScratch) - { - MEDLoaderNS::writeFieldAndMeshDirectly(fileName,f,true); - return ; - } - if(status==MEDLoaderBase::NOT_EXIST) + if(writeFromScratch || (!writeFromScratch && status==MEDLoaderBase::NOT_EXIST)) { - MEDLoaderNS::writeFieldAndMeshDirectly(fileName,f,true); - return ; + MEDLoaderNS::writeFieldWithoutReadingAndMappingOfMeshInFile(fileName,f,true); } else { std::vector meshNames=GetMeshNames(fileName); + if(!f->getMesh()) + throw INTERP_KERNEL::Exception("MEDLoader::WriteField : trying to write a field with no mesh !"); std::string fileNameCpp(f->getMesh()->getName()); if(std::find(meshNames.begin(),meshNames.end(),fileNameCpp)==meshNames.end()) - MEDLoaderNS::writeFieldAndMeshDirectly(fileName,f,false); + MEDLoaderNS::writeFieldWithoutReadingAndMappingOfMeshInFile(fileName,f,false); else - MEDLoaderNS::writeFieldTryingToFitExistingMesh(fileName,f); + { + MEDCouplingAutoRefCountObjectPtr mm=MEDFileMesh::New(fileName,f->getMesh()->getName()); + const MEDFileMesh *mmPtr(mm); + const MEDFileUMesh *mmuPtr=dynamic_cast(mmPtr); + if(!mmuPtr) + throw INTERP_KERNEL::Exception("MEDLoader::WriteField : only umeshes are supported now !"); + MEDCouplingAutoRefCountObjectPtr f2(f->deepCpy()); + MEDCouplingUMesh *m=dynamic_cast(const_cast(f2->getMesh())); + if(!m) + throw INTERP_KERNEL::Exception("MEDLoader::WriteField : only umesh in input field supported !"); + MEDCouplingAutoRefCountObjectPtr o2n=m->getRenumArrForMEDFileFrmt(); + f2->renumberCells(o2n->begin(),false); + m=static_cast(const_cast(f2->getMesh())); + MEDCouplingAutoRefCountObjectPtr mread=mmuPtr->getMeshAtLevel(m->getMeshDimension()-mm->getMeshDimension()); + if(f2->getTypeOfField()!=ON_NODES) + { + m->tryToShareSameCoordsPermute(*mread,_EPS_FOR_NODE_COMP); + DataArrayInt *part=0; + bool b=mread->areCellsIncludedIn(m,_COMP_FOR_CELL,part); + MEDCouplingAutoRefCountObjectPtr partSafe(part); + if(!b) + { + std::ostringstream oss; oss << "MEDLoader::WriteField : The file \""<< fileName << "\" already contains a mesh named \""<< f->getMesh()->getName() << "\" and this mesh in the file is not compatible (a subpart) with the mesh you intend to write ! This is maybe due to a too strict policy ! Try with to lease it by calling SetCompPolicyForCell !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + MEDCouplingAutoRefCountObjectPtr f1ts=MEDFileField1TS::New(); + if(part->isIdentity() && part->getNumberOfTuples()==mread->getNumberOfCells()) + f1ts->setFieldNoProfileSBT(f2); + else + { + part->setName(f1ts->createNewNameOfPfl().c_str()); + f1ts->setFieldProfile(f2,mm,m->getMeshDimension()-mm->getMeshDimension(),part); + } + f1ts->write(fileName,0); + return ; + } + else + { + DataArrayInt *part=0; + bool b=mread->getCoords()->areIncludedInMe(m->getCoords(),_EPS_FOR_NODE_COMP,part); + MEDCouplingAutoRefCountObjectPtr partSafe(part); + if(!b) + { + std::ostringstream oss; oss << "MEDLoader::WriteField : The file \""<< fileName << "\" already contains a mesh named \""<< f->getMesh()->getName() << "\" and this mesh in the file is not compatible (a subpart regarding nodes) with the mesh you intend to write ! This is maybe due to a too strict epsilon ! Try with to lease it by calling SetEpsilonForNodeComp !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + MEDCouplingAutoRefCountObjectPtr f1ts=MEDFileField1TS::New(); + if(part->isIdentity() && part->getNumberOfTuples()==mread->getNumberOfNodes()) + f1ts->setFieldNoProfileSBT(f2); + else + { + part->setName(f1ts->createNewNameOfPfl().c_str()); + f1ts->setFieldProfile(f2,mm,m->getMeshDimension()-mm->getMeshDimension(),part); + } + f1ts->write(fileName,0); + } + } } } void MEDLoader::WriteFieldDep(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, bool writeFromScratch) throw(INTERP_KERNEL::Exception) { - int status=MEDLoaderBase::getStatusOfFile(fileName); - if(status!=MEDLoaderBase::EXIST_RW && status!=MEDLoaderBase::NOT_EXIST) - { - std::ostringstream oss; oss << "File with name \'" << fileName << "\' has not valid permissions !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(writeFromScratch) - { - MEDLoaderNS::writeFieldAndMeshDirectly(fileName,f,true); - return ; - } - if(status==MEDLoaderBase::NOT_EXIST) - { - MEDLoaderNS::writeFieldAndMeshDirectly(fileName,f,true); - return ; - } - else - MEDLoaderNS::writeFieldAndMeshDirectly(fileName,f,false); + WriteField(fileName,f,writeFromScratch); } void MEDLoader::WriteFieldUsingAlreadyWrittenMesh(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f) throw(INTERP_KERNEL::Exception) { + if(!f) + throw INTERP_KERNEL::Exception("MEDLoader::WriteFieldUsingAlreadyWrittenMesh : input field is null !"); f->checkCoherency(); int status=MEDLoaderBase::getStatusOfFile(fileName); if(status!=MEDLoaderBase::EXIST_RW) @@ -2958,5 +1442,13 @@ void MEDLoader::WriteFieldUsingAlreadyWrittenMesh(const char *fileName, const Pa std::ostringstream oss; oss << "File with name \'" << fileName << "\' has not valid permissions or not exists !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } - MEDLoaderNS::appendFieldDirectly(fileName,f); + MEDCouplingAutoRefCountObjectPtr f1ts=MEDFileField1TS::New(); + MEDCouplingUMesh *m=dynamic_cast(const_cast(f->getMesh())); + if(!m) + throw INTERP_KERNEL::Exception("MEDLoader::WriteFieldUsingAlreadyWrittenMesh : only umesh in input field supported !"); + MEDCouplingAutoRefCountObjectPtr o2n=m->getRenumArrForMEDFileFrmt(); + MEDCouplingAutoRefCountObjectPtr f2(f->deepCpy()); + f2->renumberCells(o2n->begin(),false); + f1ts->setFieldNoProfileSBT(f2); + f1ts->write(fileName,0); } diff --git a/src/MEDLoader/MEDLoader.hxx b/src/MEDLoader/MEDLoader.hxx index 4d2077a1e..27dede9fc 100644 --- a/src/MEDLoader/MEDLoader.hxx +++ b/src/MEDLoader/MEDLoader.hxx @@ -39,53 +39,6 @@ namespace ParaMEDMEM class MEDLOADER_EXPORT MEDLoader { public: -/// @cond INTERNAL - class MEDConnOfOneElemType - { - public: - MEDConnOfOneElemType(INTERP_KERNEL::NormalizedCellType type, int *conn, int *index, int *fam, int lgth, int connLgth); - INTERP_KERNEL::NormalizedCellType getType() const { return _type; } - int getLength() const { return _lgth; } - int getConnLength() const { return _conn_lgth; } - int *getArray() const { return _conn; } - int *getIndex() const { return _index; } - int *getFam() const { return _fam; } - void setGlobal(int *global); - const int *getGlobal() const { return _global; } - void releaseArray(); - private: - int _lgth; - int *_fam; - int *_conn; - int *_index; - int *_global; - int _conn_lgth; - INTERP_KERNEL::NormalizedCellType _type; - }; - - class MEDFieldDoublePerCellType - { - public: - MEDFieldDoublePerCellType(INTERP_KERNEL::NormalizedCellType type, double *values, int ncomp, int nGeoElt, int nbi, const int *cellIdPerType, const char *locName); - INTERP_KERNEL::NormalizedCellType getType() const { return _type; } - int getNbComp() const { return _ncomp; } - int getNbOfGeoElt() const { return _ngeo_elt; } - int getNbOfTuple() const { return _nbi*_ngeo_elt; } - int getNbOfValues() const { return _ncomp*_nbi*_ngeo_elt; } - double *getArray() const { return _values; } - const std::string& getLocName() const { return _loc_name; } - const std::vector& getCellIdPerType() const { return _cell_id_per_type; } - void releaseArray(); - private: - int _ngeo_elt; - int _nbi; - int _ncomp; - double *_values; - std::string _loc_name; - std::vector _cell_id_per_type; - INTERP_KERNEL::NormalizedCellType _type; - }; -/// @endcond static void SetEpsilonForNodeComp(double val) throw(INTERP_KERNEL::Exception); static void SetCompPolicyForCell(int val) throw(INTERP_KERNEL::Exception); static void SetTooLongStrPolicy(int val) throw(INTERP_KERNEL::Exception); diff --git a/src/MEDLoader/Swig/MEDLoaderCommon.i b/src/MEDLoader/Swig/MEDLoaderCommon.i index 60cac09fb..7003e6752 100644 --- a/src/MEDLoader/Swig/MEDLoaderCommon.i +++ b/src/MEDLoader/Swig/MEDLoaderCommon.i @@ -663,8 +663,6 @@ namespace ParaMEDMEM void addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids) throw(INTERP_KERNEL::Exception); void removeMeshAtLevel(int meshDimRelToMax) throw(INTERP_KERNEL::Exception); void setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld=false) throw(INTERP_KERNEL::Exception); - void setGroupsFromScratch(int meshDimRelToMax, const std::vector& ms, bool renum=false) throw(INTERP_KERNEL::Exception); - void setGroupsOnSetMesh(int meshDimRelToMax, const std::vector& ms, bool renum) throw(INTERP_KERNEL::Exception); void optimizeFamilies() throw(INTERP_KERNEL::Exception); DataArrayInt *zipCoords() throw(INTERP_KERNEL::Exception); %extend @@ -699,6 +697,27 @@ namespace ParaMEDMEM self->setGroupsAtLevel(meshDimRelToMaxExt,grps,renum); } + void setMeshes(PyObject *li, bool renum=false) throw(INTERP_KERNEL::Exception) + { + std::vector ms; + convertFromPyObjVectorOfObj(li,SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh,"MEDCouplingUMesh",ms); + self->setMeshes(ms,renum); + } + + void setGroupsFromScratch(int meshDimRelToMax, PyObject *li, bool renum=false) throw(INTERP_KERNEL::Exception) + { + std::vector ms; + convertFromPyObjVectorOfObj(li,SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh,"MEDCouplingUMesh",ms); + self->setGroupsFromScratch(meshDimRelToMax,ms,renum); + } + + void setGroupsOnSetMesh(int meshDimRelToMax, PyObject *li, bool renum=false) throw(INTERP_KERNEL::Exception) + { + std::vector ms; + convertFromPyObjVectorOfObj(li,SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh,"MEDCouplingUMesh",ms); + self->setGroupsOnSetMesh(meshDimRelToMax,ms,renum); + } + DataArrayDouble *getCoords() const throw(INTERP_KERNEL::Exception) { DataArrayDouble *ret=self->getCoords(); diff --git a/src/MEDLoader/Swig/MEDLoaderTest3.py b/src/MEDLoader/Swig/MEDLoaderTest3.py index 1e99f137c..1fc851a50 100644 --- a/src/MEDLoader/Swig/MEDLoaderTest3.py +++ b/src/MEDLoader/Swig/MEDLoaderTest3.py @@ -981,7 +981,7 @@ class MEDLoaderTest(unittest.TestCase): def testMEDFieldBug1(self): fname="Pyfile13.med" d=MEDFileData.New(fname) - self.assertEqual(('GP_MyFirstFieldOnGaussPoint0', 'GP_MyFirstFieldOnGaussPoint1', 'GP_MyFirstFieldOnGaussPoint2'),d.getFields().getFieldAtPos(0).getLocs()) + self.assertEqual(('Loc_MyFirstFieldOnGaussPoint_NORM_QUAD4_1','Loc_MyFirstFieldOnGaussPoint_NORM_TRI3_0','Loc_MyFirstFieldOnGaussPoint_NORM_TRI6_2'),d.getFields().getFieldAtPos(0).getLocs()) pass def testMEDMesh8(self): -- 2.30.2