From 209c44a054546f6a709ae21c0ec535360afcd38b Mon Sep 17 00:00:00 2001 From: ageay Date: Wed, 11 Mar 2009 17:55:43 +0000 Subject: [PATCH] Some new functionalities --- src/ParaMEDMEM/MEDLoader/MEDLoader.cxx | 1123 +++++++++++++++++++----- src/ParaMEDMEM/MEDLoader/MEDLoader.hxx | 46 +- 2 files changed, 937 insertions(+), 232 deletions(-) diff --git a/src/ParaMEDMEM/MEDLoader/MEDLoader.cxx b/src/ParaMEDMEM/MEDLoader/MEDLoader.cxx index 2cabfb740..e6f2b5178 100644 --- a/src/ParaMEDMEM/MEDLoader/MEDLoader.cxx +++ b/src/ParaMEDMEM/MEDLoader/MEDLoader.cxx @@ -21,6 +21,7 @@ #include "ParaMESH.hxx" #include "BlockTopology.hxx" #include "MEDCouplingUMesh.hxx" +#include "MEDCouplingFieldDouble.hxx" extern "C" { @@ -31,46 +32,61 @@ extern "C" #include #include #include +#include +#include +#include -med_geometrie_element typmai[MED_NBR_GEOMETRIE_MAILLE] = { MED_POINT1, - MED_SEG2, - MED_SEG3, - MED_TRIA3, - MED_TRIA6, - MED_QUAD4, - MED_QUAD8, - MED_TETRA4, - MED_TETRA10, - MED_HEXA8, - MED_HEXA20, - MED_PENTA6, - MED_PENTA15, - MED_PYRA5, - MED_PYRA13 }; - -INTERP_KERNEL::NormalizedCellType typmai2[MED_NBR_GEOMETRIE_MAILLE] = { INTERP_KERNEL::NORM_ERROR, - INTERP_KERNEL::NORM_SEG2, - INTERP_KERNEL::NORM_SEG3, - INTERP_KERNEL::NORM_TRI3, - INTERP_KERNEL::NORM_TRI6, - INTERP_KERNEL::NORM_QUAD4, - INTERP_KERNEL::NORM_QUAD8, - INTERP_KERNEL::NORM_TETRA4, - INTERP_KERNEL::NORM_TETRA10, - INTERP_KERNEL::NORM_HEXA8, - INTERP_KERNEL::NORM_HEXA20, - INTERP_KERNEL::NORM_PENTA6, - INTERP_KERNEL::NORM_PENTA15, - INTERP_KERNEL::NORM_PYRA5, - INTERP_KERNEL::NORM_PYRA13 }; +med_geometrie_element typmai[MED_NBR_GEOMETRIE_MAILLE+2] = { MED_POINT1, + MED_SEG2, + MED_SEG3, + MED_TRIA3, + MED_TRIA6, + MED_QUAD4, + MED_QUAD8, + MED_TETRA4, + MED_TETRA10, + MED_HEXA8, + MED_HEXA20, + MED_PENTA6, + MED_PENTA15, + MED_PYRA5, + MED_PYRA13, + MED_POLYGONE, + MED_POLYEDRE }; + +med_geometrie_element typmainoeud[1] = { MED_NONE }; + +INTERP_KERNEL::NormalizedCellType typmai2[MED_NBR_GEOMETRIE_MAILLE+2] = { INTERP_KERNEL::NORM_ERROR, + INTERP_KERNEL::NORM_SEG2, + INTERP_KERNEL::NORM_SEG3, + INTERP_KERNEL::NORM_TRI3, + INTERP_KERNEL::NORM_TRI6, + INTERP_KERNEL::NORM_QUAD4, + INTERP_KERNEL::NORM_QUAD8, + INTERP_KERNEL::NORM_TETRA4, + INTERP_KERNEL::NORM_TETRA10, + INTERP_KERNEL::NORM_HEXA8, + INTERP_KERNEL::NORM_HEXA20, + INTERP_KERNEL::NORM_PENTA6, + INTERP_KERNEL::NORM_PENTA15, + INTERP_KERNEL::NORM_PYRA5, + INTERP_KERNEL::NORM_PYRA13, + INTERP_KERNEL::NORM_POLYGON, + INTERP_KERNEL::NORM_POLYHED }; using namespace ParaMEDMEM; const char WHITE_SPACES[]=" \n"; -MEDLoader::MEDConnOfOneElemType::MEDConnOfOneElemType(INTERP_KERNEL::NormalizedCellType type, int *conn, int lgth):_lgth(lgth), - _conn(conn),_global(0), - _type(type) +/*! + * @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. + */ +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),_type(type), + _conn_lgth(connLgth) { } @@ -86,10 +102,21 @@ void MEDLoader::MEDConnOfOneElemType::setGlobal(int *global) void MEDLoader::MEDConnOfOneElemType::releaseArray() { + delete [] _fam; delete [] _conn; + delete [] _index; delete [] _global; } +MEDLoader::MEDFieldDoublePerCellType::MEDFieldDoublePerCellType(INTERP_KERNEL::NormalizedCellType type, double *values, int ncomp, int nval):_nval(nval),_ncomp(ncomp),_values(values),_type(type) +{ +} + +void MEDLoader::MEDFieldDoublePerCellType::releaseArray() +{ + delete [] _values; +} + std::string buildStringFromFortran(const char *expr, int lgth) { std::string ret(expr,lgth); @@ -106,29 +133,407 @@ std::string buildStringFromFortran(const char *expr, int lgth) namespace MEDLoader { - med_int getIdFromMeshName(med_idt fid, const char *meshName) throw(INTERP_KERNEL::Exception) + std::vector getMeshNamesFid(med_idt fid) { - if(meshName==0) - return 1; - med_int n=MEDnMaa(fid); - if(n==0) - throw INTERP_KERNEL::Exception("No mesh in file."); med_maillage type_maillage; char maillage_description[MED_TAILLE_DESC+1]; med_int dim; char nommaa[MED_TAILLE_NOM+1]; - std::ostringstream os; - for(med_int i=1;i<=n;i++) + med_int n=MEDnMaa(fid); + std::vector ret(n); + for(int i=0;i GetMeshNames(const char *fileName) + { + med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE); + std::vector ret=getMeshNamesFid(fid); + MEDfermer(fid); + return ret; + } + + std::vector GetMeshFamilyNames(const char *fileName, const char *meshName) + { + med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE); + med_int nfam=MEDnFam(fid,(char *)meshName); + std::vector ret(nfam); + char nomfam[MED_TAILLE_NOM+1]; + med_int numfam; + for(int i=0;i GetMeshGroupsNames(const char *fileName, const char *meshName) + { + med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE); + med_int nfam=MEDnFam(fid,(char *)meshName); + std::vector ret; + char nomfam[MED_TAILLE_NOM+1]; + med_int numfam; + for(int i=0;i GetCellFieldNamesOnMesh(const char *fileName, const char *meshName) + { + std::vector ret; + med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE); + med_int nbFields=MEDnChamp(fid,0); + // + med_type_champ typcha; + //med_int nbpdtnor=0,pflsize,*pflval,lnsize; + med_int ngauss=0; + med_int numdt=0,numo=0,nbrefmaa; + med_float dt=0.0; + med_booleen local; + //char pflname[MED_TAILLE_NOM+1]=""; + //char locname[MED_TAILLE_NOM+1]=""; + char maa_ass[MED_TAILLE_NOM+1]=""; + char dt_unit[MED_TAILLE_PNOM+1]=""; + char nomcha[MED_TAILLE_NOM+1]=""; + // + for(int i=0;i0) + { + MEDpasdetempsInfo(fid,nomcha,MED_MAILLE,typmai[j],1, &ngauss, &numdt, &numo, dt_unit,&dt, maa_ass, &local, &nbrefmaa); + std::string curMeshName=buildStringFromFortran(maa_ass,MED_TAILLE_NOM+1); + if(curMeshName==meshName) + { + found=true; + ret.push_back(curFieldName); + } + } + } + } + MEDfermer(fid); + return ret; + } + + std::vector GetNodeFieldNamesOnMesh(const char *fileName, const char *meshName) + { + std::vector ret; + med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE); + med_int nbFields=MEDnChamp(fid,0); + // + med_type_champ typcha; + med_int ngauss=0; + med_int numdt=0,numo=0,nbrefmaa; + med_float dt=0.0; + med_booleen local; + char maa_ass[MED_TAILLE_NOM+1]=""; + char dt_unit[MED_TAILLE_PNOM+1]=""; + char nomcha[MED_TAILLE_NOM+1]=""; + // + for(int i=0;i0) + { + MEDpasdetempsInfo(fid,nomcha,MED_NOEUD,MED_NONE,1, &ngauss, &numdt, &numo, dt_unit,&dt, maa_ass, &local, &nbrefmaa); + std::string curMeshName=buildStringFromFortran(maa_ass,MED_TAILLE_NOM+1); + if(curMeshName==meshName) + { + found=true; + ret.push_back(curFieldName); + } + } + } + MEDfermer(fid); + return ret; + } + + std::vector< std::pair > GetCellFieldIterations(const char *fileName, const char *fieldName) + { + std::vector< std::pair > ret; + med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE); + med_int nbFields=MEDnChamp(fid,0); + // + med_type_champ typcha; + med_int ngauss=0; + med_int numdt=0,numo=0,nbrefmaa; + med_float dt=0.0; + med_booleen local; + char maa_ass[MED_TAILLE_NOM+1]=""; + char dt_unit[MED_TAILLE_PNOM+1]=""; + char nomcha[MED_TAILLE_NOM+1]=""; + // + for(int i=0;i > GetNodeFieldIterations(const char *fileName, const char *fieldName) + { + std::vector< std::pair > ret; + med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE); + med_int nbFields=MEDnChamp(fid,0); + // + med_type_champ typcha; + med_int ngauss=0; + med_int numdt=0,numo=0,nbrefmaa; + med_float dt=0.0; + med_booleen local; + char maa_ass[MED_TAILLE_NOM+1]=""; + char dt_unit[MED_TAILLE_PNOM+1]=""; + char nomcha[MED_TAILLE_NOM+1]=""; + // + for(int i=0;i& field, + int iteration, int order, ParaMEDMEM::TypeOfField typeOfOutField, double& time) + { + time=0.; + med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE); + med_int nbFields=MEDnChamp(fid,0); + // + med_type_champ typcha; + char nomcha[MED_TAILLE_NOM+1]=""; + char pflname [MED_TAILLE_NOM+1]=""; + char locname [MED_TAILLE_NOM+1]=""; + std::map tabEnt; + std::map tabType; + std::map tabTypeLgth; + tabEnt[ON_CELLS]=MED_MAILLE; + tabType[ON_CELLS]=typmai; + tabTypeLgth[ON_CELLS]=MED_NBR_GEOMETRIE_MAILLE+2; + tabEnt[ON_NODES]=MED_NOEUD; + tabType[ON_NODES]=typmainoeud; + tabTypeLgth[ON_NODES]=1; + // + for(int i=0;i0) + { + int nval=MEDnVal(fid,(char *)fieldName,tabEnt[typeOfOutField],tabType[typeOfOutField][j],iteration,order,(char *)meshName,MED_COMPACT); + double *valr=new double[ncomp*nval]; + MEDchampLire(fid,(char *)meshName,(char *)fieldName,(unsigned char*)valr,MED_FULL_INTERLACE,MED_ALL,locname, + pflname,MED_COMPACT,tabEnt[typeOfOutField],tabType[typeOfOutField][j],iteration,order); + field.push_back(MEDFieldDoublePerCellType(typmai2[j],valr,ncomp,nval)); + } + } + } + } + MEDfermer(fid); + } + + std::vector getIdsFromFamilies(const char *fileName, const char *meshName, const std::vector& fams) + { + std::vector ret; + med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE); + med_int nfam=MEDnFam(fid,(char *)meshName); + char nomfam[MED_TAILLE_NOM+1]; + med_int numfam; + for(int i=0;i getIdsFromGroups(const char *fileName, const char *meshName, const std::vector& grps) + { + std::vector ret; + med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE); + med_int nfam=MEDnFam(fid,(char *)meshName); + char nomfam[MED_TAILLE_NOM+1]; + med_int numfam; + for(int i=0;i 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()); + } + return iter-meshes.begin()+1; + } + + /*! + * This methods allows to merger all entities and to considerate only cell types. + */ + void dispatchElems(int nbOfElemCell, int nbOfElemFace, int& nbOfElem, med_entite_maillage& whichEntity) + { + if(nbOfElemCell>=nbOfElemFace) + { + whichEntity=MED_MAILLE; + nbOfElem=nbOfElemCell; + } + else + { + whichEntity=MED_FACE; + nbOfElem=nbOfElemFace; } - std::ostringstream os2; - os2 << "MeshName '" << meshName << "' not in file : meshes available : " << os.str(); - throw INTERP_KERNEL::Exception(os2.str().c_str()); } void readUMeshDataInMedFile(med_idt fid, med_int meshId, double *&coords, int& nCoords, int& spaceDim, std::list& conn) @@ -153,26 +558,16 @@ namespace MEDLoader int curNbOfElemM=MEDnEntMaa(fid,nommaa,MED_CONN,MED_MAILLE,curMedType,MED_NOD); int curNbOfElemF=MEDnEntMaa(fid,nommaa,MED_CONN,MED_FACE,curMedType,MED_NOD); int curNbOfElem; - if(curNbOfElemF>curNbOfElemM) - { - curNbOfElem=curNbOfElemF; - whichEntity=MED_FACE; - } - else - { - curNbOfElem=curNbOfElemM; - whichEntity=MED_MAILLE; - } + dispatchElems(curNbOfElemM,curNbOfElemF,curNbOfElem,whichEntity); if(curNbOfElem>0) { int *connTab=new int[(curMedType%100)*curNbOfElem]; - MEDLoader::MEDConnOfOneElemType elem(typmai2[i],connTab,curNbOfElem); - int *tmp=new int[curNbOfElem]; int *fam=new int[curNbOfElem]; + MEDLoader::MEDConnOfOneElemType elem(typmai2[i],connTab,0,fam,curNbOfElem,-1); + int *tmp=new int[curNbOfElem]; char *noms=new char[MED_TAILLE_PNOM*curNbOfElem+1]; MEDelementsLire(fid,nommaa,Mdim,connTab,MED_FULL_INTERLACE,noms,&inoele,tmp,&inuele,fam,curNbOfElem,whichEntity,curMedType,MED_NOD); delete [] tmp; - delete [] fam; delete [] noms; //trying to read global numbering int *globArr=new int[curNbOfElem]; @@ -183,172 +578,462 @@ namespace MEDLoader conn.push_back(elem); } } + int curNbOfPolyElem; + int curNbOfPolyElemM=MEDnEntMaa(fid,nommaa,MED_CONN,MED_MAILLE,MED_POLYGONE,MED_NOD); + int curNbOfPolyElemF=MEDnEntMaa(fid,nommaa,MED_CONN,MED_FACE,MED_POLYGONE,MED_NOD); + med_entite_maillage whichPolyEntity; + dispatchElems(curNbOfPolyElemM,curNbOfPolyElemF,curNbOfPolyElem,whichPolyEntity); + if(curNbOfPolyElem>0) + { + med_int arraySize; + MEDpolygoneInfo(fid,nommaa,whichPolyEntity,MED_NOD,&arraySize); + int *index=new int[curNbOfPolyElem+1]; + int *locConn=new int[arraySize]; + int *fam=new int[curNbOfPolyElem]; + MEDLoader::MEDConnOfOneElemType elem(INTERP_KERNEL::NORM_POLYGON,locConn,index,fam,curNbOfPolyElem,arraySize); + MEDpolygoneConnLire(fid,nommaa,index,curNbOfPolyElem+1,locConn,whichPolyEntity,MED_NOD); + MEDfamLire(fid,nommaa,fam,curNbOfPolyElem,MED_MAILLE,MED_POLYGONE); + conn.push_back(elem); + } + curNbOfPolyElem=MEDnEntMaa(fid,nommaa,MED_CONN,MED_MAILLE,MED_POLYEDRE,MED_NOD); + if(curNbOfPolyElem>0) + { + med_int indexFaceLgth,connFaceLgth; + MEDpolyedreInfo(fid,nommaa,MED_NOD,&indexFaceLgth,&connFaceLgth); + int *index=new int[curNbOfPolyElem+1]; + int *indexFace=new int[indexFaceLgth]; + int *locConn=new int[connFaceLgth]; + int *fam=new int[curNbOfPolyElem]; + MEDpolyedreConnLire(fid,nommaa,index,curNbOfPolyElem+1,indexFace,indexFaceLgth,locConn,MED_NOD); + MEDfamLire(fid,nommaa,fam,curNbOfPolyElem,MED_MAILLE,MED_POLYEDRE); + int arraySize=connFaceLgth; + for(int i=0;i + 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++; + } + } } -} -unsigned MEDLoader::calculateHighestMeshDim(const std::list& conn) -{ - unsigned ret=0; - for(std::list::const_iterator iter=conn.begin();iter!=conn.end();iter++) - { - unsigned curDim=INTERP_KERNEL::CellModel::getCellModel((*iter).getType()).getDimension(); - if(ret& fieldPerType) + { + 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)); + 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; + }; + + void tradMEDFileCoreFrmt2MEDCouplingUMesh(const std::list& medConnFrmt, + DataArrayInt* &conn, + DataArrayInt* &connIndex, + const std::vector& familiesToKeep) + { + bool keepAll=familiesToKeep.empty(); + if(medConnFrmt.empty()) + { + conn=0; + connIndex=0; + return ; + } + std::list::const_iterator iter=medConnFrmt.begin(); + int totalNbOfCells=0; + int totalNbOfMedConn=0; + for(;iter!=medConnFrmt.end();iter++) + { + 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(); + 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 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()) + { + *connIdxPtr=connFillId; + *connPtr++=type; + if(!isDyn) + tmpConnPtr=std::transform(sourceConn,sourceConn+nbOfNodesIn1Cell,connPtr,std::bind2nd(std::minus(),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; + } + sourceConn+=nbOfNodesIn1Cell; + } + *connIdxPtr=connFillId; + } + } + + 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'. + * @param conn input containing connectivity with MEDCoupling format. + * @param connIndex input containing connectivity index in MEDCoupling format. + * @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. + * @return nb of elements extracted. + */ + int buildMEDSubConnectivityOfOneTypeStaticTypes(DataArrayInt *conn, DataArrayInt *connIndex, INTERP_KERNEL::NormalizedCellType type, std::vector& conn4MEDFile) + { + int ret=0; + int nbOfElem=connIndex->getNbOfElems()-1; + const int *connPtr=conn->getPointer(); + const int *connIdxPtr=connIndex->getPointer(); + for(int i=0;i(),1)); + return ret; + } + + int buildMEDSubConnectivityOfOneTypesPolyg(DataArrayInt *conn, DataArrayInt *connIndex, std::vector& conn4MEDFile, std::vector& connIndex4MEDFile) + { + int ret=0; + int nbOfElem=connIndex->getNbOfElems()-1; + const int *connPtr=conn->getPointer(); + const int *connIdxPtr=connIndex->getPointer(); + connIndex4MEDFile.push_back(1); + for(int i=0;i(),1)); + return ret; + } + + int buildMEDSubConnectivityOfOneTypesPolyh(DataArrayInt *conn, DataArrayInt *connIndex, std::vector& conn4MEDFile, std::vector& connIndex4MEDFile, std::vector& connIndexRk24MEDFile) + { + return 0; + } + + /*! + * 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 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. + * @return nb of elements extracted. + */ + int buildMEDSubConnectivityOfOneType(DataArrayInt *conn, DataArrayInt *connIndex, INTERP_KERNEL::NormalizedCellType type, std::vector& conn4MEDFile, + std::vector& connIndex4MEDFile, std::vector& connIndexRk24MEDFile) + { + + const INTERP_KERNEL::CellModel& cellMod=INTERP_KERNEL::CellModel::getCellModel(type); + if(!cellMod.isDynamic()) + return buildMEDSubConnectivityOfOneTypeStaticTypes(conn,connIndex,type,conn4MEDFile); + else + { + if(type==INTERP_KERNEL::NORM_POLYGON) + return buildMEDSubConnectivityOfOneTypesPolyg(conn,connIndex,conn4MEDFile,connIndex4MEDFile); + else + return buildMEDSubConnectivityOfOneTypesPolyh(conn,connIndex,conn4MEDFile,connIndex4MEDFile,connIndexRk24MEDFile); + } + } + + /*! + * @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. + */ + MEDCouplingUMesh *readUMeshFromFileLev1(const char *fileName, const char *meshName, int meshDimRelToMax, const std::vector& ids, + const std::vector& typesToKeep, unsigned& meshDimExtract) throw(INTERP_KERNEL::Exception) + { + //Extraction data from MED file. + med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE); + med_int mid=getIdFromMeshName(fid,meshName); + double *coords; + int nCoords; + int spaceDim; + std::list conn; + readUMeshDataInMedFile(fid,mid,coords,nCoords,spaceDim,conn); + meshDimExtract=calculateHighestMeshDim(conn); + meshDimExtract=meshDimExtract+meshDimRelToMax; + keepSpecifiedMeshDim(conn,meshDimExtract); + keepTypes(conn,typesToKeep); + MEDfermer(fid); + //Put data in returned data structure. + MEDCouplingUMesh *ret=MEDCouplingUMesh::New(); + ret->setName(meshName); + ret->setMeshDimension(meshDimExtract); + // + DataArrayDouble *coordsArr=DataArrayDouble::New(); + coordsArr->useArray(coords,true,ParaMEDMEM::CPP_DEALLOC,nCoords,spaceDim); + ret->setCoords(coordsArr); + coordsArr->decrRef(); + // + DataArrayInt *connArr,*connIndexArr; + tradMEDFileCoreFrmt2MEDCouplingUMesh(conn,connArr,connIndexArr,ids); + ret->setConnectivity(connArr,connIndexArr); + //clean-up + if(connArr) + connArr->decrRef(); + if(connIndexArr) + connIndexArr->decrRef(); + releaseMEDFileCoreFrmt(conn); + return ret; + } + + ParaMEDMEM::MEDCouplingFieldDouble *readFieldDoubleLev1(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order, + ParaMEDMEM::TypeOfField typeOfOutField) + { + std::list fieldPerCellType; + double time; + readFieldDoubleDataInMedFile(fileName,meshName,fieldName,fieldPerCellType,iteration,order,typeOfOutField,time); + std::vector familiesToKeep; + std::vector typesToKeep; + if(typeOfOutField==ON_CELLS) + for(std::list::const_iterator iter=fieldPerCellType.begin();iter!=fieldPerCellType.end();iter++) + typesToKeep.push_back((*iter).getType()); + unsigned meshDim; + ParaMEDMEM::MEDCouplingUMesh *mesh=readUMeshFromFileLev1(fileName,meshName,meshDimRelToMax,familiesToKeep,typesToKeep,meshDim); + if(typeOfOutField==ON_CELLS) + keepSpecifiedMeshDim(fieldPerCellType,meshDim); + ParaMEDMEM::MEDCouplingFieldDouble *ret=ParaMEDMEM::MEDCouplingFieldDouble::New(typeOfOutField); + ret->setDtIt(iteration,order); + ret->setName(fieldName); + ret->setTime(time); + ret->setMesh(mesh); + mesh->decrRef(); + ParaMEDMEM::DataArrayDouble *arr=buildArrayFromRawData(fieldPerCellType); + ret->setArray(arr); + arr->decrRef(); + releaseMEDFileCoreFrmt(fieldPerCellType); + return ret; + } + + /*! + * This method builds the master file 'fileName' of a parallel MED file defined in 'fileNames'. + */ + void writeMasterFile(const char *fileName, const std::vector& fileNames, const char *meshName) + { + int nbOfDom=fileNames.size(); + std::ofstream fs(fileName); + fs << "#MED Fichier V 2.3" << " " << std::endl; + fs << "#"<<" " << std::endl; + fs << nbOfDom <<" " << std::endl; + for(int i=0;i& conn, unsigned meshDim) +MEDCouplingUMesh *MEDLoader::ReadUMeshFromFile(const char *fileName, const char *meshName, int meshDimRelToMax) throw(INTERP_KERNEL::Exception) { - for(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++; - } + std::vector familiesToKeep; + std::vector typesToKeep; + unsigned meshDim; + return readUMeshFromFileLev1(fileName,meshName,meshDimRelToMax,familiesToKeep,typesToKeep,meshDim); } -void MEDLoader::tradMEDFileCoreFrmt2MEDCouplingUMesh(const std::list& medConnFrmt, - DataArrayInt* &conn, - DataArrayInt* &connIndex) +ParaMEDMEM::MEDCouplingUMesh *MEDLoader::ReadUMeshFromFamilies(const char *fileName, const char *meshName, int meshDimRelToMax, const std::vector& fams) { - if(medConnFrmt.empty()) - { - conn=0; - connIndex=0; - return ; - } - std::list::const_iterator iter=medConnFrmt.begin(); - int totalNbOfCells=0; - int totalNbOfMedConn=0; - for(;iter!=medConnFrmt.end();iter++) - { - const INTERP_KERNEL::CellModel& cellMod=INTERP_KERNEL::CellModel::getCellModel((*iter).getType()); - totalNbOfCells+=(*iter).getLength(); - if(!cellMod.isDynamic()) - totalNbOfMedConn+=(*iter).getLength()*cellMod.getNumberOfNodes(); - else - throw INTERP_KERNEL::Exception("Polyg/polh not implemented yet !"); - } - 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(); - for(iter=medConnFrmt.begin();iter!=medConnFrmt.end();iter++) - { - INTERP_KERNEL::NormalizedCellType type=(*iter).getType(); - int *sourceConn=(*iter).getArray(); - const INTERP_KERNEL::CellModel& cellMod=INTERP_KERNEL::CellModel::getCellModel(type); - int nbOfCellsInCurType; - int nbOfNodesIn1Cell=cellMod.getNumberOfNodes(); - if(!cellMod.isDynamic()) - nbOfCellsInCurType=(*iter).getLength(); - else - throw INTERP_KERNEL::Exception("Polyg/polh not implemented yet !"); - if(!cellMod.isDynamic()) - { - for(int i=0;i(),1)); - connFillId+=nbOfNodesIn1Cell+1; - sourceConn+=nbOfNodesIn1Cell; - } - *connIdxPtr=connFillId; - } - } + std::vector familiesToKeep=getIdsFromFamilies(fileName,meshName,fams); + std::vector typesToKeep; + unsigned meshDim; + return readUMeshFromFileLev1(fileName,meshName,meshDimRelToMax,familiesToKeep,typesToKeep,meshDim); } -void MEDLoader::releaseMEDFileCoreFrmt(std::list& medConnFrmt) +ParaMEDMEM::MEDCouplingUMesh *MEDLoader::ReadUMeshFromGroups(const char *fileName, const char *meshName, int meshDimRelToMax, const std::vector& grps) { - for(std::list::iterator iter=medConnFrmt.begin();iter!=medConnFrmt.end();iter++) - (*iter).releaseArray(); - medConnFrmt.clear(); + std::vector familiesToKeep=getIdsFromGroups(fileName,meshName,grps); + std::vector typesToKeep; + unsigned meshDim; + return readUMeshFromFileLev1(fileName,meshName,meshDimRelToMax,familiesToKeep,typesToKeep,meshDim); } -/*! - * 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 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. - * @return nb of elements extracted. - */ -int MEDLoader::buildMEDSubConnectivityOfOneType(DataArrayInt *conn, DataArrayInt *connIndex, INTERP_KERNEL::NormalizedCellType type, std::vector& conn4MEDFile) +ParaMEDMEM::MEDCouplingFieldDouble *MEDLoader::ReadFieldDoubleCell(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order) { - int ret=0; - int nbOfElem=connIndex->getNbOfElems()-1; - const int *connPtr=conn->getPointer(); - const int *connIdxPtr=connIndex->getPointer(); - for(int i=0;i(),1)); - return ret; + return readFieldDoubleLev1(fileName,meshName,meshDimRelToMax,fieldName,iteration,order,ON_CELLS); } -MEDCouplingUMesh *MEDLoader::ReadUMeshFromFile(const char *fileName, const char *meshName, int meshDimRelToMax) throw(INTERP_KERNEL::Exception) +ParaMEDMEM::MEDCouplingFieldDouble *MEDLoader::ReadFieldDoubleNode(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order) { - //Extraction data from MED file. - med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE); - med_int mid=getIdFromMeshName(fid,meshName); - unsigned meshDimExtract; - double *coords; - int nCoords; - int spaceDim; - std::list conn; - readUMeshDataInMedFile(fid,mid,coords,nCoords,spaceDim,conn); - meshDimExtract=calculateHighestMeshDim(conn); - meshDimExtract=meshDimExtract+meshDimRelToMax; - keepSpecifiedMeshDim(conn,meshDimExtract); - MEDfermer(fid); - //Put data in returned data structure. - MEDCouplingUMesh *ret=MEDCouplingUMesh::New(); - ret->setName(meshName); - ret->setMeshDimension(meshDimExtract); - // - DataArrayDouble *coordsArr=DataArrayDouble::New(); - coordsArr->useArray(coords,true,ParaMEDMEM::CPP_DEALLOC,nCoords,spaceDim); - ret->setCoords(coordsArr); - coordsArr->decrRef(); - // - DataArrayInt *connArr,*connIndexArr; - tradMEDFileCoreFrmt2MEDCouplingUMesh(conn,connArr,connIndexArr); - ret->setConnectivity(connArr,connIndexArr); - //clean-up - if(connArr) - connArr->decrRef(); - if(connIndexArr) - connIndexArr->decrRef(); - releaseMEDFileCoreFrmt(conn); - return ret; + return readFieldDoubleLev1(fileName,meshName,meshDimRelToMax,fieldName,iteration,order,ON_NODES); } void MEDLoader::writeUMesh(const char *fileName, ParaMEDMEM::MEDCouplingUMesh *mesh) { med_idt fid=MEDouvrir((char *)fileName,MED_CREATION); + std::string meshName(mesh->getName()); + if(meshName=="") + { + MEDfermer(fid); + throw INTERP_KERNEL::Exception("MEDCouplingMesh must have a not null name !"); + } char maa[MED_TAILLE_NOM+1]; - std::fill(maa,maa+MED_TAILLE_NOM+1,'\0'); - const char *meshName=mesh->getName(); - strcpy(maa,meshName); - MEDmaaCr(fid,maa,mesh->getMeshDimension(),MED_NON_STRUCTURE,maa); + strcpy(maa,meshName.c_str()); + MEDmaaCr(fid,maa,mesh->getSpaceDimension(),MED_NON_STRUCTURE,maa); std::set allTypes(mesh->getAllTypes()); DataArrayInt *conn=mesh->getNodalConnectivity(); DataArrayInt *connIndex=mesh->getNodalConnectivityIndex(); @@ -356,15 +1041,23 @@ void MEDLoader::writeUMesh(const char *fileName, ParaMEDMEM::MEDCouplingUMesh *m std::fill(familyName,familyName+MED_TAILLE_NOM+1,'\0'); const char DftFamilyName[]="DftFamily"; std::copy(DftFamilyName,DftFamilyName+sizeof(DftFamilyName),familyName); - for(int i=0;i medConn; - int nbOfElt=buildMEDSubConnectivityOfOneType(conn,connIndex,curType,medConn); - MEDconnEcr(fid,maa,mesh->getMeshDimension(),&medConn[0],MED_FULL_INTERLACE,nbOfElt,MED_MAILLE,curMedType,MED_NOD); + std::vector medConnIndex; + std::vector medConnIndex2; + int nbOfElt=buildMEDSubConnectivityOfOneType(conn,connIndex,curType,medConn,medConnIndex,medConnIndex2); + if(curMedType!=MED_POLYGONE && curMedType!=MED_POLYEDRE) + MEDconnEcr(fid,maa,mesh->getMeshDimension(),&medConn[0],MED_FULL_INTERLACE,nbOfElt,MED_MAILLE,curMedType,MED_NOD); + else + { + if(curMedType==MED_POLYGONE) + MEDpolygoneConnEcr(fid,maa,&medConnIndex[0],medConnIndex.size(),&medConn[0],MED_MAILLE,MED_NOD); + } } } MEDfamCr(fid,maa,familyName,0,0,0,0,0,0,0); @@ -381,20 +1074,6 @@ void MEDLoader::writeUMesh(const char *fileName, ParaMEDMEM::MEDCouplingUMesh *m MEDfermer(fid); } -/*! - * This method builds the master file 'fileName' of a parallel MED file defined in 'fileNames'. - */ -void MEDLoader::writeMasterFile(const char *fileName, const std::vector& fileNames, const char *meshName) -{ - int nbOfDom=fileNames.size(); - std::ofstream fs(fileName); - fs << "#MED Fichier V 2.3" << " " << std::endl; - fs << "#"<<" " << std::endl; - fs << nbOfDom <<" " << std::endl; - for(int i=0;igetBlockTopology()->getProcGroup()->containsMyRank()) diff --git a/src/ParaMEDMEM/MEDLoader/MEDLoader.hxx b/src/ParaMEDMEM/MEDLoader/MEDLoader.hxx index b5f7065da..9e5c5db73 100644 --- a/src/ParaMEDMEM/MEDLoader/MEDLoader.hxx +++ b/src/ParaMEDMEM/MEDLoader/MEDLoader.hxx @@ -31,6 +31,7 @@ namespace ParaMEDMEM class ParaFIELD; class DataArrayInt; class MEDCouplingUMesh; + class MEDCouplingFieldDouble; } namespace MEDLoader @@ -38,29 +39,54 @@ namespace MEDLoader class MEDConnOfOneElemType { public: - MEDConnOfOneElemType(INTERP_KERNEL::NormalizedCellType type, int *conn, int lgth); + 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); 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 nval); + INTERP_KERNEL::NormalizedCellType getType() const { return _type; } + int getNbComp() const { return _ncomp; } + int getNbOfTuple() const { return _nval; } + int getNbOfValues() const { return _ncomp*_nval; } + double *getArray() const { return _values; } + void releaseArray(); + private: + int _nval; + int _ncomp; + double *_values; INTERP_KERNEL::NormalizedCellType _type; }; - unsigned calculateHighestMeshDim(const std::list& conn); - void keepSpecifiedMeshDim(std::list& conn, unsigned meshDim); - void tradMEDFileCoreFrmt2MEDCouplingUMesh(const std::list& medConnFrmt, - ParaMEDMEM::DataArrayInt* &conn, - ParaMEDMEM::DataArrayInt* &connIndex); - void releaseMEDFileCoreFrmt(std::list& medConnFrmt); - void writeMasterFile(const char *fileName, const std::vector& fileNames, const char *meshName); - int buildMEDSubConnectivityOfOneType(ParaMEDMEM::DataArrayInt *conn, ParaMEDMEM::DataArrayInt *connIndex, - INTERP_KERNEL::NormalizedCellType type, std::vector& conn4MEDFile); // + std::vector GetMeshNames(const char *fileName); + std::vector GetMeshGroupsNames(const char *fileName, const char *meshName); + std::vector GetMeshFamilyNames(const char *fileName, const char *meshName); + std::vector GetCellFieldNamesOnMesh(const char *fileName, const char *meshName); + std::vector GetNodeFieldNamesOnMesh(const char *fileName, const char *meshName); + std::vector< std::pair > GetCellFieldIterations(const char *fileName, const char *fieldName); + std::vector< std::pair > GetNodeFieldIterations(const char *fileName, const char *fieldName); + ParaMEDMEM::MEDCouplingUMesh *ReadUMeshFromFamilies(const char *fileName, const char *meshName, int meshDimRelToMax, const std::vector& fams); + ParaMEDMEM::MEDCouplingUMesh *ReadUMeshFromGroups(const char *fileName, const char *meshName, int meshDimRelToMax, const std::vector& grps); ParaMEDMEM::MEDCouplingUMesh *ReadUMeshFromFile(const char *fileName, const char *meshName=0, int meshDimRelToMax=0) throw(INTERP_KERNEL::Exception); + ParaMEDMEM::MEDCouplingFieldDouble *ReadFieldDoubleCell(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order); + ParaMEDMEM::MEDCouplingFieldDouble *ReadFieldDoubleNode(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order); void writeUMesh(const char *fileName, ParaMEDMEM::MEDCouplingUMesh *mesh); void writeParaMesh(const char *fileName, ParaMEDMEM::ParaMESH *mesh); void writeParaField(const char *fileName, const char *meshName, ParaMEDMEM::ParaFIELD *f); -- 2.39.2