X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FMEDLoader%2FMEDLoader.cxx;h=687d0bcbf35a6d6c4b3b25c6b29c96bf83af4a3b;hb=f2ab61e92f55ee52cf5196f7904f625d93c8c2d0;hp=60e8773ec517cbc912193479c5e0abef9a2416c5;hpb=293a6104470482e450701aa8061d9b244f2057d5;p=tools%2Fmedcoupling.git diff --git a/src/MEDLoader/MEDLoader.cxx b/src/MEDLoader/MEDLoader.cxx index 60e8773ec..687d0bcbf 100644 --- a/src/MEDLoader/MEDLoader.cxx +++ b/src/MEDLoader/MEDLoader.cxx @@ -1,9 +1,9 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2020 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either -// version 2.1 of the License. +// version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -21,12 +21,19 @@ #include "MEDLoader.hxx" #include "MEDLoaderBase.hxx" #include "MEDFileUtilities.hxx" +#include "MEDLoaderNS.hxx" +#include "MEDFileSafeCaller.txx" +#include "MEDFileMesh.hxx" +#include "MEDFileField.hxx" #include "CellModel.hxx" #include "MEDCouplingUMesh.hxx" #include "MEDCouplingMemArray.hxx" #include "MEDCouplingFieldDouble.hxx" +#include "MEDCouplingFieldFloat.hxx" +#include "MEDCouplingFieldInt32.hxx" #include "MEDCouplingGaussLocalization.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" +#include "MEDCouplingTraits.hxx" +#include "MCAuto.hxx" #include "InterpKernelAutoPtr.hxx" @@ -40,243 +47,206 @@ #include #include #include +#include med_geometry_type typmai[MED_N_CELL_FIXED_GEO] = { MED_POINT1, - MED_SEG2, - MED_SEG3, - MED_SEG4, - MED_TRIA3, - MED_QUAD4, - MED_TRIA6, - MED_TRIA7, - MED_QUAD8, - MED_QUAD9, - MED_TETRA4, - MED_PYRA5, - MED_PENTA6, - MED_HEXA8, - MED_OCTA12, - MED_TETRA10, - MED_PYRA13, - MED_PENTA15, - MED_HEXA20, - MED_HEXA27, - MED_POLYGON, - MED_POLYHEDRON }; + MED_SEG2, + MED_SEG3, + MED_SEG4, + MED_TRIA3, + MED_QUAD4, + MED_TRIA6, + MED_TRIA7, + MED_QUAD8, + MED_QUAD9, + MED_TETRA4, + MED_PYRA5, + MED_PENTA6, + MED_HEXA8, + MED_OCTA12, + MED_TETRA10, + MED_PYRA13, + MED_PENTA15, + MED_PENTA18, + MED_HEXA20, + MED_HEXA27, + MED_POLYGON, + MED_POLYGON2, + MED_POLYHEDRON }; med_geometry_type typmainoeud[1] = { MED_NONE }; INTERP_KERNEL::NormalizedCellType typmai2[MED_N_CELL_FIXED_GEO] = { INTERP_KERNEL::NORM_POINT1, - INTERP_KERNEL::NORM_SEG2, - INTERP_KERNEL::NORM_SEG3, - INTERP_KERNEL::NORM_SEG4, - INTERP_KERNEL::NORM_TRI3, - INTERP_KERNEL::NORM_QUAD4, - INTERP_KERNEL::NORM_TRI6, - INTERP_KERNEL::NORM_TRI7, - INTERP_KERNEL::NORM_QUAD8, - INTERP_KERNEL::NORM_QUAD9, - INTERP_KERNEL::NORM_TETRA4, - INTERP_KERNEL::NORM_PYRA5, - INTERP_KERNEL::NORM_PENTA6, - INTERP_KERNEL::NORM_HEXA8, - INTERP_KERNEL::NORM_HEXGP12, - INTERP_KERNEL::NORM_TETRA10, - INTERP_KERNEL::NORM_PYRA13, - INTERP_KERNEL::NORM_PENTA15, - INTERP_KERNEL::NORM_HEXA20, - INTERP_KERNEL::NORM_HEXA27, - INTERP_KERNEL::NORM_POLYGON, - INTERP_KERNEL::NORM_POLYHED }; - -med_geometry_type typmai3[34] = { MED_POINT1,//0 - MED_SEG2,//1 - MED_SEG3,//2 - MED_TRIA3,//3 - MED_QUAD4,//4 - MED_POLYGON,//5 - MED_TRIA6,//6 - MED_TRIA7,//7 - MED_QUAD8,//8 - MED_QUAD9,//9 - MED_SEG4,//10 - MED_NONE,//11 - MED_NONE,//12 - MED_NONE,//13 - MED_TETRA4,//14 - MED_PYRA5,//15 - MED_PENTA6,//16 - MED_NONE,//17 - MED_HEXA8,//18 - MED_NONE,//19 - MED_TETRA10,//20 - MED_NONE,//21 - MED_OCTA12,//22 - MED_PYRA13,//23 - MED_NONE,//24 - MED_PENTA15,//25 - MED_NONE,//26 - MED_HEXA27,//27 - MED_NONE,//28 - MED_NONE,//29 - MED_HEXA20,//30 - MED_POLYHEDRON,//31 - MED_NONE,//32 - MED_NONE//33 + INTERP_KERNEL::NORM_SEG2, + INTERP_KERNEL::NORM_SEG3, + INTERP_KERNEL::NORM_SEG4, + INTERP_KERNEL::NORM_TRI3, + INTERP_KERNEL::NORM_QUAD4, + INTERP_KERNEL::NORM_TRI6, + INTERP_KERNEL::NORM_TRI7, + INTERP_KERNEL::NORM_QUAD8, + INTERP_KERNEL::NORM_QUAD9, + INTERP_KERNEL::NORM_TETRA4, + INTERP_KERNEL::NORM_PYRA5, + INTERP_KERNEL::NORM_PENTA6, + INTERP_KERNEL::NORM_HEXA8, + INTERP_KERNEL::NORM_HEXGP12, + INTERP_KERNEL::NORM_TETRA10, + INTERP_KERNEL::NORM_PYRA13, + INTERP_KERNEL::NORM_PENTA15, + INTERP_KERNEL::NORM_PENTA18, + INTERP_KERNEL::NORM_HEXA20, + INTERP_KERNEL::NORM_HEXA27, + INTERP_KERNEL::NORM_POLYGON, + INTERP_KERNEL::NORM_QPOLYG, + INTERP_KERNEL::NORM_POLYHED }; + +med_geometry_type typmai3[INTERP_KERNEL::NORM_MAXTYPE] = { MED_POINT1,//0 + MED_SEG2,//1 + MED_SEG3,//2 + MED_TRIA3,//3 + MED_QUAD4,//4 + MED_POLYGON,//5 + MED_TRIA6,//6 + MED_TRIA7,//7 + MED_QUAD8,//8 + MED_QUAD9,//9 + MED_SEG4,//10 + MED_NONE,//11 + MED_NONE,//12 + MED_NONE,//13 + MED_TETRA4,//14 + MED_PYRA5,//15 + MED_PENTA6,//16 + MED_NONE,//17 + MED_HEXA8,//18 + MED_NONE,//19 + MED_TETRA10,//20 + MED_NONE,//21 + MED_OCTA12,//22 + MED_PYRA13,//23 + MED_NONE,//24 + MED_PENTA15,//25 + MED_NONE,//26 + MED_HEXA27,//27 + MED_PENTA18,//28 + MED_NONE,//29 + MED_HEXA20,//30 + MED_POLYHEDRON,//31 + MED_POLYGON2//32 }; -double MEDLoader::_EPS_FOR_NODE_COMP=1.e-12; +double _EPS_FOR_NODE_COMP=1.e-12; -int MEDLoader::_COMP_FOR_CELL=0; +int _COMP_FOR_CELL=0; -int MEDLoader::_TOO_LONG_STR=0; +int _TOO_LONG_STR=0; -using namespace ParaMEDMEM; +using namespace MEDCoupling; /// @cond INTERNAL -namespace MEDLoaderNS +INTERP_KERNEL::NormalizedCellType ConvertGeometryType(med_geometry_type geotype) { - 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); - void dispatchElems(int nbOfElemCell, int nbOfElemFace, int& nbOfElem, med_entity_type& whichEntity); - int readUMeshDimFromFile(const char *fileName, const char *meshName, std::vector& possibilities); - 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); -} - -/// @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; + INTERP_KERNEL::NormalizedCellType result=INTERP_KERNEL::NORM_ERROR; + for(int i=0; i& possibilities) { - if(_global!=global) + possibilities.clear(); + MEDFileUtilities::AutoFid fid(MEDCoupling::OpenMEDFileForRead(fileName)); + 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; + int meshId=FromMedInt(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; + med_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); + MEDFILESAFECALLERRD0(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; + MEDFILESAFECALLERRD0(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()) { - if(_global) - delete [] _global; - _global=global; + 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 ntuple, - const int *cellIdPerType, const char *locName):_ntuple(ntuple),_ncomp(ncomp),_values(values),_type(type) -{ - if(cellIdPerType) - _cell_id_per_type.insert(_cell_id_per_type.end(),cellIdPerType,cellIdPerType+ntuple); - if(locName) - _loc_name=locName; -} - -void MEDLoader::MEDFieldDoublePerCellType::releaseArray() +int MEDLoaderNS::getIdFromMeshName(med_idt fid, const std::string& meshName, std::string& trueMeshName) { - delete [] _values; + if(meshName.empty()) + { + 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 (int)( iter-meshes.begin()+1 ); } -/// @cond INTERNAL - std::vector MEDLoaderNS::getMeshNamesFid(med_idt fid) { med_mesh_type type_maillage; @@ -291,99 +261,126 @@ std::vector MEDLoaderNS::getMeshNamesFid(med_idt fid) std::vector ret(n); for(int i=0;i axisname=MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE); INTERP_KERNEL::AutoPtr axisunit=MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE); - int nstep; - MEDmeshInfo(fid,i+1,nommaa,&space_dim,&mesh_dim,&type_maillage,maillage_description,dtunit,&stype,&nstep,&axistype,axisname,axisunit); + med_int nstep; + MEDFILESAFECALLERRD0(MEDmeshInfo,(fid,i+1,nommaa,&space_dim,&mesh_dim,&type_maillage,maillage_description,dtunit,&stype,&nstep,&axistype,axisname,axisunit)); std::string cur=MEDLoaderBase::buildStringFromFortran(nommaa,sizeof(nommaa)); ret[i]=cur; } 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(med_int nbOfElemCell, med_int nbOfElemFace, med_int& nbOfElem, med_entity_type& whichEntity) { - med_idt fid=MEDfileOpen(fileName,MED_ACC_RDONLY); - char locName[MED_NAME_SIZE+1]; - int nloc=MEDnLocalization(fid); - med_geometry_type typeGeo; - 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]); - f->setGaussLocalizationOnType((*iter).getType(),refcoo,gscoo,w); + whichEntity=MED_CELL; + nbOfElem=nbOfElemCell; + } + else + { + whichEntity=MED_CELL; + nbOfElem=nbOfElemFace; } - MEDfileClose(fid); } /// @endcond -void MEDLoader::CheckFileForRead(const char *fileName) throw(INTERP_KERNEL::Exception) +void MEDCoupling::AssignStaticWritePropertiesTo(MEDCoupling::MEDFileWritable& obj) { - MEDFileUtilities::CheckFileForRead(fileName); + obj.setTooLongStrPolicy(_TOO_LONG_STR); } -std::vector MEDLoader::GetMeshNames(const char *fileName) throw(INTERP_KERNEL::Exception) +bool MEDCoupling::HasXDR() { - CheckFileForRead(fileName); - med_idt fid=MEDfileOpen(fileName,MED_ACC_RDONLY); - std::vector ret=MEDLoaderNS::getMeshNamesFid(fid); - MEDfileClose(fid); - return ret; +#ifdef HAS_XDR + return true; +#else + return false; +#endif } -std::vector< std::pair > MEDLoader::GetComponentsNamesOfField(const char *fileName, const char *fieldName) throw(INTERP_KERNEL::Exception) +std::string MEDCoupling::MEDFileVersionStr() { - 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 << "MEDFileVersionStr : internal error ! The MEDFile returned version (\"" << zeRet << "\") has not the right pattern !"; + throw INTERP_KERNEL::Exception(oss.str()); } - 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()); + return zeRet.substr(sizeof(START_EXPECTED)-1,std::string::npos); +} + +std::string MEDCoupling::MEDFileVersionOfFileStr(const std::string& fileName) +{ +#if MED_NUM_MAJEUR>3 || ( MED_NUM_MAJEUR==3 && ( (MED_NUM_MINEUR==2 && MED_NUM_RELEASE>=1) || MED_NUM_MINEUR>=3) ) + MEDFileUtilities::AutoFid fid(MEDCoupling::OpenMEDFileForRead(fileName)); + const int SZ=20; + const char START_EXPECTED[]="MED-"; + char buf[SZ]; + std::fill(buf,buf+SZ,'\0'); + MEDFILESAFECALLERRD0(MEDfileStrVersionRd,(fid,buf)); + std::string ret(buf); + std::size_t pos(ret.find(START_EXPECTED,0)); + if(pos!=0) + { + std::ostringstream oss; oss << "MEDFileVersionOfFileStr : internal error ! The MEDFile returned version (\"" << ret << "\") has not the right pattern !"; + throw INTERP_KERNEL::Exception(oss.str()); + } + return ret.substr(sizeof(START_EXPECTED)-1,std::string::npos); +#else + std::ostringstream oss; oss << "MEDFileVersionOfFileStr : is implemented with MEDFile " << MEDFileVersionStr() << " ! If you need this feature please use version >= 3.2.1."; + throw INTERP_KERNEL::Exception(oss.str()); +#endif +} + +void MEDCoupling::MEDFileVersion(int& major, int& minor, int& release) +{ + med_int majj,minn,rell; + med_err ret(MEDlibraryNumVersion(&majj,&minn,&rell)); + if(ret!=0) + throw INTERP_KERNEL::Exception("MEDFileVersion : fail to call MEDlibraryNumVersion ! It looks very bad !"); + major=FromMedInt(majj); + minor=FromMedInt(minn); + release=FromMedInt(rell); +} + +/*! + * This method sets the epsilon value used for node comparison when trying to build a profile for a field on node/cell on an already written mesh. + */ +void MEDCoupling::SetEpsilonForNodeComp(double val) +{ + _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 MEDCoupling::SetCompPolicyForCell(int val) +{ + _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 MEDCoupling::SetTooLongStrPolicy(int val) +{ + _TOO_LONG_STR=val; } /*! @@ -394,36 +391,37 @@ std::vector< std::pair > MEDLoader::GetComponentsNamesO * - the space dimension * - the number of nodes */ -std::vector< std::vector< std::pair > > MEDLoader::GetUMeshGlobalInfo(const char *fileName, const char *meshName, int &meshDim, int& spaceDim, int& numberOfNodes) throw(INTERP_KERNEL::Exception) +std::vector< std::vector< std::pair > > MEDCoupling::GetUMeshGlobalInfo(const std::string& fileName, const std::string& meshName, int &meshDim, int& spaceDim, mcIdType& numberOfNodes) { - CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY); + MEDFileUtilities::AutoFid fid(MEDCoupling::OpenMEDFileForRead(fileName)); std::set poss; char nommaa[MED_NAME_SIZE+1]; char maillage_description[MED_COMMENT_SIZE+1]; med_mesh_type type_maillage; std::string trueMeshName; - med_int meshId=MEDLoaderNS::getIdFromMeshName(fid,meshName,trueMeshName); + int meshId=MEDLoaderNS::getIdFromMeshName(fid,meshName,trueMeshName); INTERP_KERNEL::AutoPtr dt_unit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); med_sorting_type sortingType; - med_int nstep; + med_int nstep, mDim, sDim; med_axis_type axisType; - int naxis=MEDmeshnAxis(fid,meshId); + med_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,&spaceDim,&meshDim,&type_maillage,maillage_description,dt_unit,&sortingType,&nstep,&axisType,axisname,axisunit); + MEDFILESAFECALLERRD0(MEDmeshInfo,(fid,meshId,nommaa,&sDim,&mDim,&type_maillage,maillage_description,dt_unit,&sortingType,&nstep,&axisType,axisname,axisunit)); + meshDim=FromMedInt(mDim); + spaceDim=FromMedInt(sDim); if(type_maillage!=MED_UNSTRUCTURED_MESH) { - std::ostringstream oss; oss << "MEDLoader::GetUMeshGlobalInfo : Mesh \""<< meshName << "\" in file \"" << fileName; + std::ostringstream oss; oss << "GetUMeshGlobalInfo : Mesh \""<< meshName << "\" in file \"" << fileName; oss << "\" exists but it is not an unstructured mesh ! This method is not relevant for mesh types that are not unstructured !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } // limitation if(nstep!=1) - throw INTERP_KERNEL::Exception("MEDLoader::GetUMeshGlobalInfo : multisteps on mesh not managed !"); + throw INTERP_KERNEL::Exception("GetUMeshGlobalInfo : multisteps on mesh not managed !"); med_int numdt,numit; med_float dt; - MEDmeshComputationStepInfo(fid,nommaa,1,&numdt,&numit,&dt); + MEDFILESAFECALLERRD0(MEDmeshComputationStepInfo,(fid,nommaa,1,&numdt,&numit,&dt)); // endlimitation std::vector dims; std::vector< std::pair > geoTypes; @@ -431,7 +429,7 @@ std::vector< std::vector< std::pair > > M for(int i=0;i0) { INTERP_KERNEL::NormalizedCellType typp=typmai2[i]; @@ -448,16 +446,92 @@ std::vector< std::vector< std::pair > > M { ret[maxLev-dims[i]].push_back(geoTypes[i]); } - numberOfNodes=MEDmeshnEntity(fid,nommaa,numdt,numit,MED_NODE,MED_NONE,MED_COORDINATE,MED_NO_CMODE,&changement,&transformation); + numberOfNodes=ToIdType(MEDmeshnEntity(fid,nommaa,numdt,numit,MED_NODE,MED_NONE,MED_COORDINATE,MED_NO_CMODE,&changement,&transformation)); return ret; } -std::vector MEDLoader::GetMeshNamesOnField(const char *fileName, const char *fieldName) throw(INTERP_KERNEL::Exception) +void MEDCoupling::CheckFileForRead(const std::string& fileName) +{ + MEDFileUtilities::CheckFileForRead(fileName); +} + +std::vector MEDCoupling::GetMeshNames(const std::string& fileName) +{ + MEDFileUtilities::AutoFid fid(MEDCoupling::OpenMEDFileForRead(fileName)); + return MEDLoaderNS::getMeshNamesFid(fid); +} + +std::vector< std::pair > MEDCoupling::GetComponentsNamesOfField(const std::string& fileName, const std::string& fieldName) +{ + MEDFileUtilities::AutoFid fid(MEDCoupling::OpenMEDFileForRead(fileName)); + 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); + MEDFILESAFECALLERRD0(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 << "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()); +} + +// see reference : https://en.cppreference.com/w/cpp/iterator/iterator +class MEDVectorStringIterator : public std::iterator< std::input_iterator_tag, long, long, const std::string*, std::string > +{ + long _num = 0; + char *_data = nullptr; +public: + explicit MEDVectorStringIterator(long num , char *data) : _num(num),_data(data) {} + MEDVectorStringIterator& operator++() { ++_num; return *this;} + bool operator==(const MEDVectorStringIterator& other) const {return _num == other._num;} + bool operator!=(const MEDVectorStringIterator& other) const {return !(*this == other);} + reference operator*() const {return MEDLoaderBase::buildStringFromFortran(_data+_num*MED_LNAME_SIZE,MED_LNAME_SIZE);} +}; + +void MEDCoupling::GetFamiliesGroupsInfo(const std::string& fileName, const std::string& meshName, std::map& families, std::map>& groupsOnFam) +{ + MEDFileUtilities::AutoFid fid(MEDCoupling::OpenMEDFileForRead(fileName)); + med_int nbFams(MEDnFamily(fid,meshName.c_str())); + char nomfam[MED_NAME_SIZE+1]; + for(med_int i=0;i gro{new char[MED_LNAME_SIZE*nbGrps+1]}; + MEDFILESAFECALLERRD0(MEDfamilyInfo,(fid,meshName.c_str(),i+1,nomfam,&famId,gro.get())); + std::string fam(MEDLoaderBase::buildStringFromFortran(nomfam,MED_NAME_SIZE)); + families[fam] = FromMedInt(famId); + std::vector v(nbGrps); + std::copy(MEDVectorStringIterator(0,gro.get()),MEDVectorStringIterator(nbGrps,gro.get()),v.begin()); + groupsOnFam[fam] = v; + } +} + +std::vector MEDCoupling::GetMeshNamesOnField(const std::string& fileName, const std::string& fieldName) { - CheckFileForRead(fileName); std::vector ret; // - med_idt fid=MEDfileOpen(fileName,MED_ACC_RDONLY); + MEDFileUtilities::AutoFid fid(MEDCoupling::OpenMEDFileForRead(fileName)); med_int nbFields=MEDnField(fid); // med_field_type typcha; @@ -467,63 +541,59 @@ std::vector MEDLoader::GetMeshNamesOnField(const char *fileName, co // for(int i=0;i comp=new char[ncomp*MED_SNAME_SIZE+1]; INTERP_KERNEL::AutoPtr unit=new char[ncomp*MED_SNAME_SIZE+1]; med_int nbPdt; INTERP_KERNEL::AutoPtr maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - MEDfieldInfo(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt); + MEDFILESAFECALLERRD0(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) ret.push_back(meshName); } - MEDfileClose(fid); return ret; } -std::vector MEDLoader::GetMeshFamiliesNames(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception) +std::vector MEDCoupling::GetMeshFamiliesNames(const std::string& fileName, const std::string& meshName) { - CheckFileForRead(fileName); - med_idt fid=MEDfileOpen(fileName,MED_ACC_RDONLY); - med_int nfam=MEDnFamily(fid,meshName); + MEDFileUtilities::AutoFid fid(MEDCoupling::OpenMEDFileForRead(fileName)); + med_int nfam=MEDnFamily(fid,meshName.c_str()); std::vector ret(nfam); 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); + MEDfamily23Info(fid,meshName.c_str(),i+1,nomfam,attide,attval,attdes,&numfam,gro); std::string cur=MEDLoaderBase::buildStringFromFortran(nomfam,sizeof(nomfam)); ret[i]=cur; } - MEDfileClose(fid); return ret; } -std::vector MEDLoader::GetMeshFamiliesNamesOnGroup(const char *fileName, const char *meshName, const char *grpName) throw(INTERP_KERNEL::Exception) +std::vector MEDCoupling::GetMeshFamiliesNamesOnGroup(const std::string& fileName, const std::string& meshName, const std::string& grpName) { - CheckFileForRead(fileName); - med_idt fid=MEDfileOpen(fileName,MED_ACC_RDONLY); - med_int nfam=MEDnFamily(fid,meshName); + MEDFileUtilities::AutoFid fid(MEDCoupling::OpenMEDFileForRead(fileName)); + med_int nfam=MEDnFamily(fid,meshName.c_str()); std::vector ret; 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); + MEDfamily23Info(fid,meshName.c_str(),i+1,nomfam,attide,attval,attdes,&numfam,gro); std::string cur=MEDLoaderBase::buildStringFromFortran(nomfam,sizeof(nomfam)); for(int j=0;j MEDLoader::GetMeshFamiliesNamesOnGroup(const char *file ret.push_back(cur); } } - MEDfileClose(fid); return ret; } -std::vector MEDLoader::GetMeshGroupsNamesOnFamily(const char *fileName, const char *meshName, const char *famName) throw(INTERP_KERNEL::Exception) +std::vector MEDCoupling::GetMeshGroupsNamesOnFamily(const std::string& fileName, const std::string& meshName, const std::string& famName) { - CheckFileForRead(fileName); - med_idt fid=MEDfileOpen(fileName,MED_ACC_RDONLY); - med_int nfam=MEDnFamily(fid,meshName); + MEDFileUtilities::AutoFid fid(MEDCoupling::OpenMEDFileForRead(fileName)); + med_int nfam(MEDnFamily(fid,meshName.c_str())); std::vector ret; char nomfam[MED_NAME_SIZE+1]; med_int numfam; bool found=false; 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); + MEDfamily23Info(fid,meshName.c_str(),i+1,nomfam,attide,attval,attdes,&numfam,gro); std::string cur=MEDLoaderBase::buildStringFromFortran(nomfam,sizeof(nomfam)); found=(cur==famName); if(found) @@ -563,34 +631,32 @@ std::vector MEDLoader::GetMeshGroupsNamesOnFamily(const char *fileN ret.push_back(cur2); } } - MEDfileClose(fid); if(!found) { std::ostringstream oss; - oss << "MEDLoader::GetMeshGroupsNamesOnFamily : no such family \"" << famName << "\" in file \"" << fileName << "\" in mesh \"" << meshName << "\" !"; + oss << "GetMeshGroupsNamesOnFamily : no such family \"" << famName << "\" in file \"" << fileName << "\" in mesh \"" << meshName << "\" !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } return ret; } - -std::vector MEDLoader::GetMeshGroupsNames(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception) + +std::vector MEDCoupling::GetMeshGroupsNames(const std::string& fileName, const std::string& meshName) { - CheckFileForRead(fileName); - med_idt fid=MEDfileOpen(fileName,MED_ACC_RDONLY); - med_int nfam=MEDnFamily(fid,meshName); + MEDFileUtilities::AutoFid fid(MEDCoupling::OpenMEDFileForRead(fileName)); + med_int nfam=MEDnFamily(fid,meshName.c_str()); std::vector ret; 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); + MEDfamily23Info(fid,meshName.c_str(),i+1,nomfam,attide,attval,attdes,&numfam,gro); for(int j=0;j MEDLoader::GetMeshGroupsNames(const char *fileName, con ret.push_back(cur); } } - MEDfileClose(fid); return ret; } -std::vector MEDLoader::GetTypesOfField(const char *fileName, const char *meshName, const char *fieldName) throw(INTERP_KERNEL::Exception) + +std::vector MEDCoupling::GetTypesOfField(const std::string& fileName, const std::string& meshName, const std::string& fieldName) +{ + std::vector ret; + MCAuto fs(MEDFileAnyTypeFieldMultiTS::New(fileName,fieldName,false)); + if(fs->getMeshName()!=meshName) + { + std::ostringstream oss; oss << "GetTypesOfField : The field \"" << fieldName << "\" in file \"" << fileName << "\" is not lying on mesh \"" << meshName << "\""; + oss << " The name of the mesh in file is \"" << fs->getMeshName() << "\"!"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + int nbTS(fs->getNumberOfTS()); + if(nbTS==0) + return ret; + for(int i=0;i f1ts(fs->getTimeStepAtPos(i)); + std::vector tof(f1ts->getTypesOfFieldAvailable()); + for(std::vector::const_iterator it=tof.begin();it!=tof.end();it++) + if(std::find(ret.begin(),ret.end(),*it)==ret.end()) + ret.push_back(*it); + } + // sort ret to put before ON_NODES then ON_CELLS then the remaining. + std::vector ret2; + if(std::find(ret.begin(),ret.end(),ON_NODES)!=ret.end()) + ret2.push_back(ON_NODES); + if(std::find(ret.begin(),ret.end(),ON_CELLS)!=ret.end()) + ret2.push_back(ON_CELLS); + for(std::vector::const_iterator it=ret.begin();it!=ret.end();it++) + if(*it!=ON_NODES && *it!=ON_CELLS) + ret2.push_back(*it); + return ret2; +} + +std::vector MEDCoupling::GetAllFieldNames(const std::string& fileName) +{ + std::vector ret; + MEDFileUtilities::AutoFid fid(MEDCoupling::OpenMEDFileForRead(fileName)); + med_int nbFields=MEDnField(fid); + 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 nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + INTERP_KERNEL::AutoPtr maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + INTERP_KERNEL::AutoPtr dt_unit=new char[MED_LNAME_SIZE+1]; + med_int nbPdt; + med_bool localmesh; + MEDFILESAFECALLERRD0(MEDfieldInfo,(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt)); + ret.push_back(std::string(nomcha)); + } + return ret; +} + +std::vector MEDCoupling::GetAllFieldNamesOnMesh(const std::string& fileName, const std::string& meshName) { - CheckFileForRead(fileName); - std::vector ret; - med_idt fid=MEDfileOpen(fileName,MED_ACC_RDONLY); + std::vector ret; + MEDFileUtilities::AutoFid fid(MEDCoupling::OpenMEDFileForRead(fileName)); med_int nbFields=MEDnField(fid); // med_field_type typcha; - //med_int nbpdtnor=0,pflsize,*pflval,lnsize; - med_int numdt=0,numo=0; - med_float dt=0.0; - char pflname[MED_NAME_SIZE+1]=""; - char locname[MED_NAME_SIZE+1]=""; char *maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); char *nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - med_bool localmesh; // 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]; med_int nbPdt; - MEDfieldInfo(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt); + med_bool localmesh; + MEDFILESAFECALLERRD0(MEDfieldInfo,(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt)); std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1); std::string curMeshName=MEDLoaderBase::buildStringFromFortran(maa_ass,MED_NAME_SIZE+1); - if(curMeshName==meshName) - { - if(curFieldName==fieldName) - { - int profilesize,nbi; - if(nbPdt>0) - { - bool found=false; - for(int ii=0;ii0) - { - ret.push_back(ON_NODES); - found=true; - } - } - } - bool found=false; - for(int j=0;j0) - { - MEDfieldComputingStepInfo(fid,nomcha,1,&numdt,&numo,&dt); - med_int nbOfVal=MEDfieldnValueWithProfile(fid,nomcha,numdt,numo,MED_CELL,typmai[j],1,MED_COMPACT_PFLMODE, - pflname,&profilesize,locname,&nbi); - if(nbOfVal>0) - { - found=true; - ret.push_back(ON_CELLS); - } - } - } - } - } - } - delete [] maa_ass; - delete [] nomcha; - MEDfileClose(fid); - return ret; -} - -std::vector MEDLoader::GetAllFieldNames(const char *fileName) throw(INTERP_KERNEL::Exception) -{ - CheckFileForRead(fileName); - std::vector ret; - med_idt fid=MEDfileOpen(fileName,MED_ACC_RDONLY); - med_int nbFields=MEDnField(fid); - 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 nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr dt_unit=new char[MED_LNAME_SIZE+1]; - med_int nbPdt; - med_bool localmesh; - MEDfieldInfo(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt); - ret.push_back(std::string(nomcha)); - } - MEDfileClose(fid); - return ret; -} - -std::vector MEDLoader::GetAllFieldNamesOnMesh(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception) -{ - CheckFileForRead(fileName); - std::vector ret; - med_idt fid=MEDfileOpen(fileName,MED_ACC_RDONLY); - med_int nbFields=MEDnField(fid); - // - med_field_type typcha; - char *maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - char *nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - // - 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]; - med_int nbPdt; - med_bool localmesh; - MEDfieldInfo(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt); - std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1); - std::string curMeshName=MEDLoaderBase::buildStringFromFortran(maa_ass,MED_NAME_SIZE+1); - // + // if(curMeshName==meshName) ret.push_back(curFieldName); } delete [] maa_ass; delete [] nomcha; - MEDfileClose(fid); return ret; } -std::vector MEDLoader::GetFieldNamesOnMesh(ParaMEDMEM::TypeOfField type, const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception) +std::vector MEDCoupling::GetFieldNamesOnMesh(MEDCoupling::TypeOfField type, const std::string& fileName, const std::string& meshName) { - CheckFileForRead(fileName); + MEDCoupling::CheckFileForRead(fileName); switch(type) - { + { case ON_CELLS: return GetCellFieldNamesOnMesh(fileName,meshName); case ON_NODES: return GetNodeFieldNamesOnMesh(fileName,meshName); default: throw INTERP_KERNEL::Exception("Type of field specified not managed ! manages are ON_NODES or ON_CELLS !"); - } + } } -std::vector MEDLoader::GetCellFieldNamesOnMesh(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception) +std::vector MEDCoupling::GetCellFieldNamesOnMesh(const std::string& fileName, const std::string& meshName) { - CheckFileForRead(fileName); std::vector ret; - med_idt fid=MEDfileOpen(fileName,MED_ACC_RDONLY); + MEDFileUtilities::AutoFid fid(MEDCoupling::OpenMEDFileForRead(fileName)); med_int nbFields=MEDnField(fid); // med_field_type typcha; @@ -763,13 +786,13 @@ std::vector MEDLoader::GetCellFieldNamesOnMesh(const char *fileName // for(int i=0;i comp=new char[ncomp*MED_SNAME_SIZE+1]; INTERP_KERNEL::AutoPtr unit=new char[ncomp*MED_SNAME_SIZE+1]; - MEDfieldInfo(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt); + MEDFILESAFECALLERRD0(MEDfieldInfo,(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt)); std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1); std::string curMeshName=MEDLoaderBase::buildStringFromFortran(maa_ass,MED_NAME_SIZE+1); - int profilesize,nbi; + med_int profilesize,nbi; if(curMeshName==meshName) { bool found=false; @@ -777,9 +800,9 @@ std::vector MEDLoader::GetCellFieldNamesOnMesh(const char *fileName { if(nbPdt>0) { - MEDfieldComputingStepInfo(fid,nomcha,1,&numdt,&numo,&dt); - med_int nbOfVal=MEDfieldnValueWithProfile(fid,nomcha,numdt,numo,MED_CELL,typmai[j],1,MED_COMPACT_PFLMODE, - pflname,&profilesize,locname,&nbi); + MEDFILESAFECALLERRD0(MEDfieldComputingStepInfo,(fid,nomcha,1,&numdt,&numo,&dt)); + med_int nbOfVal(MEDfieldnValueWithProfile(fid,nomcha,numdt,numo,MED_CELL,typmai[j],1,MED_COMPACT_PFLMODE, + pflname,&profilesize,locname,&nbi)); if(nbOfVal>0) { found=true; @@ -789,15 +812,13 @@ std::vector MEDLoader::GetCellFieldNamesOnMesh(const char *fileName } } } - MEDfileClose(fid); return ret; } -std::vector MEDLoader::GetNodeFieldNamesOnMesh(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception) +std::vector MEDCoupling::GetNodeFieldNamesOnMesh(const std::string& fileName, const std::string& meshName) { - CheckFileForRead(fileName); std::vector ret; - med_idt fid=MEDfileOpen(fileName,MED_ACC_RDONLY); + MEDFileUtilities::AutoFid fid(MEDCoupling::OpenMEDFileForRead(fileName)); med_int nbFields=MEDnField(fid); char pflname[MED_NAME_SIZE+1]=""; char locname[MED_NAME_SIZE+1]=""; @@ -812,35 +833,32 @@ std::vector MEDLoader::GetNodeFieldNamesOnMesh(const char *fileName // for(int i=0;i comp=new char[ncomp*MED_SNAME_SIZE+1]; INTERP_KERNEL::AutoPtr unit=new char[ncomp*MED_SNAME_SIZE+1]; med_int nbPdt; - MEDfieldInfo(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt); + MEDFILESAFECALLERRD0(MEDfieldInfo,(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt)); std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1); std::string curMeshName=MEDLoaderBase::buildStringFromFortran(maa_ass,MED_NAME_SIZE+1); if(nbPdt>0) { - int profilesize,nbi; - MEDfieldComputingStepInfo(fid,nomcha,1,&numdt,&numo,&dt); - med_int nbOfVal=MEDfieldnValueWithProfile(fid,nomcha,numdt,numo,MED_NODE,MED_NONE,1,MED_COMPACT_PFLMODE, - pflname,&profilesize,locname,&nbi); + med_int profilesize,nbi; + MEDFILESAFECALLERRD0(MEDfieldComputingStepInfo,(fid,nomcha,1,&numdt,&numo,&dt)); + med_int nbOfVal(MEDfieldnValueWithProfile(fid,nomcha,numdt,numo,MED_NODE,MED_NONE,1,MED_COMPACT_PFLMODE, + pflname,&profilesize,locname,&nbi)); if(curMeshName==meshName && nbOfVal>0) { ret.push_back(curFieldName); } } } - MEDfileClose(fid); return ret; } -std::vector< std::pair< std::pair, double> > MEDLoader::GetAllFieldIterations(const char *fileName, const char *meshName, const char *fieldName) throw(INTERP_KERNEL::Exception) +std::vector< std::pair< std::pair, double> > MEDCoupling::GetAllFieldIterations(const std::string& fileName, const std::string& fieldName) { - CheckFileForRead(fileName); - std::string meshNameCpp(meshName); std::vector< std::pair< std::pair, double > > ret; - med_idt fid=MEDfileOpen(fileName,MED_ACC_RDONLY); + MEDFileUtilities::AutoFid fid(MEDCoupling::OpenMEDFileForRead(fileName)); med_int nbFields=MEDnField(fid); // med_field_type typcha; @@ -851,31 +869,37 @@ std::vector< std::pair< std::pair, double> > MEDLoader::GetAllFieldIter INTERP_KERNEL::AutoPtr nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); med_bool localmesh; // + std::ostringstream oss; oss << "GetAllFieldIterations : No field with name \"" << fieldName<< "\" in file \"" << fileName << "\" ! Possible fields are : "; for(int i=0;i comp=new char[ncomp*MED_SNAME_SIZE+1]; INTERP_KERNEL::AutoPtr unit=new char[ncomp*MED_SNAME_SIZE+1]; med_int nbPdt; - MEDfieldInfo(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt); + MEDFILESAFECALLERRD0(MEDfieldInfo,(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt)); std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1); if(curFieldName==fieldName) { for(int k=0;k::max(); for(int i=0;i comp=new char[ncomp*MED_SNAME_SIZE+1]; INTERP_KERNEL::AutoPtr unit=new char[ncomp*MED_SNAME_SIZE+1]; med_int nbPdt; - MEDfieldInfo(fid,i+1,nomcha,maa_ass,&local,&typcha,comp,unit,dt_unit,&nbPdt); + MEDFILESAFECALLERRD0(MEDfieldInfo,(fid,i+1,nomcha,maa_ass,&local,&typcha,comp,unit,dt_unit,&nbPdt)); std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1); if(curFieldName==fieldName) { found=true; for(int k=0;k > MEDLoader::GetFieldIterations(ParaMEDMEM::TypeOfField type, const char *fileName, const char *meshName, const char *fieldName) throw(INTERP_KERNEL::Exception) +std::vector< std::pair > MEDCoupling::GetFieldIterations(MEDCoupling::TypeOfField type, const std::string& fileName, const std::string& meshName, const std::string& fieldName) { - CheckFileForRead(fileName); + MEDCoupling::CheckFileForRead(fileName); switch(type) - { + { case ON_CELLS: return GetCellFieldIterations(fileName,meshName,fieldName); case ON_NODES: return GetNodeFieldIterations(fileName,meshName,fieldName); default: throw INTERP_KERNEL::Exception("Type of field specified not managed ! manages are ON_NODES or ON_CELLS !"); - } + } } -std::vector< std::pair > MEDLoader::GetCellFieldIterations(const char *fileName, const char *meshName, const char *fieldName) throw(INTERP_KERNEL::Exception) +std::vector< std::pair > MEDCoupling::GetCellFieldIterations(const std::string& fileName, const std::string& meshName, const std::string& fieldName) { - CheckFileForRead(fileName); std::string meshNameCpp(meshName); std::vector< std::pair > ret; - med_idt fid=MEDfileOpen(fileName,MED_ACC_RDONLY); + MEDFileUtilities::AutoFid fid(MEDCoupling::OpenMEDFileForRead(fileName)); med_int nbFields=MEDnField(fid); // med_field_type typcha; @@ -953,13 +975,15 @@ std::vector< std::pair > MEDLoader::GetCellFieldIterations(const char * INTERP_KERNEL::AutoPtr nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); med_bool localmesh; // + std::ostringstream oss; oss << "GetCellFieldIterations : No cell Field field with name \"" << fieldName<< "\" in file \"" << fileName << "\" ! Possible fields are : "; + std::set s2; for(int i=0;i comp=new char[ncomp*MED_SNAME_SIZE+1]; INTERP_KERNEL::AutoPtr unit=new char[ncomp*MED_SNAME_SIZE+1]; med_int nbPdt; - MEDfieldInfo(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt); + MEDFILESAFECALLERRD0(MEDfieldInfo,(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt)); std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1); if(curFieldName==fieldName) { @@ -968,30 +992,48 @@ std::vector< std::pair > MEDLoader::GetCellFieldIterations(const char * { for(int k=0;k0) + if(nbOfVal>0) { - found=true; - ret.push_back(std::make_pair(numdt,numo)); + if(meshNameCpp==maa_ass_cpp) + { + found=true; + ret.push_back(std::make_pair(numdt,numo)); + } + else + s2.insert(maa_ass_cpp); } } } } + else + { + oss << "\"" << curFieldName << "\""; + if(i!=nbFields-1) oss << ", "; + } + } + if(ret.empty()) + { + if(!s2.empty()) + { + oss << ". Cell Field \"" << fieldName << "\" exists but lies on meshes with names : \""; + std::copy(s2.begin(),s2.end(),std::ostream_iterator(oss,"\", \"")); + } + oss << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); } - MEDfileClose(fid); return ret; } -std::vector< std::pair > MEDLoader::GetNodeFieldIterations(const char *fileName, const char *meshName, const char *fieldName) throw(INTERP_KERNEL::Exception) +std::vector< std::pair > MEDCoupling::GetNodeFieldIterations(const std::string& fileName, const std::string& meshName, const std::string& fieldName) { - CheckFileForRead(fileName); std::string meshNameCpp(meshName); std::vector< std::pair > ret; - med_idt fid=MEDfileOpen(fileName,MED_ACC_RDONLY); + MEDFileUtilities::AutoFid fid(MEDCoupling::OpenMEDFileForRead(fileName)); med_int nbFields=MEDnField(fid); // med_field_type typcha; @@ -1004,1093 +1046,246 @@ std::vector< std::pair > MEDLoader::GetNodeFieldIterations(const char * INTERP_KERNEL::AutoPtr nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); med_bool localmesh; // + std::ostringstream oss; oss << "GetNodeFieldIterations : No node Field field with name \"" << fieldName<< "\" in file \"" << fileName << "\" ! Possible fields are : "; + std::set s2; for(int i=0;i comp=new char[ncomp*MED_SNAME_SIZE+1]; INTERP_KERNEL::AutoPtr unit=new char[ncomp*MED_SNAME_SIZE+1]; med_int nbPdt; - MEDfieldInfo(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt); + MEDFILESAFECALLERRD0(MEDfieldInfo,(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt)); std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1); if(curFieldName==fieldName) { for(int k=0;k0) - { - ret.push_back(std::make_pair(numdt,numo)); - } + med_int profilesize,nbi; + MEDFILESAFECALLERRD0(MEDfieldComputingStepInfo,(fid,nomcha,k+1,&numdt,&numo,&dt)); + med_int nbOfVal(MEDfieldnValueWithProfile(fid,nomcha,numdt,numo,MED_NODE,MED_NONE,1,MED_COMPACT_PFLMODE, + pflname,&profilesize,locname,&nbi)); + std::string maa_ass_cpp(maa_ass); + if(nbOfVal>0) + { + if(meshNameCpp==maa_ass_cpp) + { ret.push_back(std::make_pair(numdt,numo)); } + else + s2.insert(maa_ass_cpp); + } } } + else + { + oss << "\"" << curFieldName << "\""; + if(i!=nbFields-1) oss << ", "; + } + } + if(ret.empty()) + { + if(!s2.empty()) + { + oss << ". Node Field \"" << fieldName << "\" exists but lies on meshes with names : \""; + std::copy(s2.begin(),s2.end(),std::ostream_iterator(oss,"\", \"")); + } + oss << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); } - MEDfileClose(fid); 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) +MEDCoupling::MEDCouplingMesh *MEDCoupling::ReadMeshFromFile(const std::string& fileName, const std::string& meshName, int meshDimRelToMax) { - 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 mm(MEDFileMesh::New(fileName,meshName)); + MEDFileMesh *mmPtr(mm); + MEDFileUMesh *mmuPtr=dynamic_cast(mmPtr); + if(mmuPtr) + return mmuPtr->getMeshAtLevel(meshDimRelToMax,true); + MEDFileCMesh *mmcPtr=dynamic_cast(mmPtr); + if(mmcPtr) { - med_int ncomp=MEDfieldnComponent(fid,i+1); - INTERP_KERNEL::AutoPtr 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;iigetMesh()); ret->incrRef(); + return const_cast(ret); } + std::ostringstream oss; oss << "ReadMeshFromFile : The mesh \"" << meshName << "\" in file \"" << fileName << "\" has not a recognized type !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); } -std::vector MEDLoaderNS::getIdsFromFamilies(const char *fileName, const char *meshName, const std::vector& fams) +MEDCoupling::MEDCouplingMesh *MEDCoupling::ReadMeshFromFile(const std::string& fileName, int meshDimRelToMax) { - std::vector ret; - med_idt 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 mm(MEDFileMesh::New(fileName)); + MEDFileMesh *mmPtr(mm); + MEDFileUMesh *mmuPtr=dynamic_cast(mmPtr); + if(mmuPtr) + return mmuPtr->getMeshAtLevel(meshDimRelToMax,true); + MEDFileCMesh *mmcPtr=dynamic_cast(mmPtr); + if(mmcPtr) { - int ngro=MEDnFamilyGroup(fid,meshName,i+1); - med_int natt=MEDnFamily23Attribute(fid,meshName,i+1); - INTERP_KERNEL::AutoPtr 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); + const MEDCouplingCMesh *ret(mmcPtr->getMesh()); ret->incrRef(); + return const_cast(ret); } - MEDfileClose(fid); - return ret; + MEDFileCurveLinearMesh *mmc2Ptr=dynamic_cast(mmPtr); + if(mmc2Ptr) + { + const MEDCouplingCurveLinearMesh *ret(mmc2Ptr->getMesh()); ret->incrRef(); + return const_cast(ret); + } + std::ostringstream oss; oss << "ReadMeshFromFile (2) : The first mesh \"" << mm->getName() << "\" in file \"" << fileName << "\" has not a recognized type !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); } -std::vector MEDLoaderNS::getIdsFromGroups(const char *fileName, const char *meshName, const std::vector& grps) +MEDCoupling::MEDCouplingUMesh *MEDCoupling::ReadUMeshFromFile(const std::string& fileName, const std::string& meshName, int meshDimRelToMax) { - std::vector ret; - med_idt 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 mm(MEDFileMesh::New(fileName,meshName)); + MEDFileMesh *mmPtr(mm); + MEDFileUMesh *mmuPtr=dynamic_cast(mmPtr); + if(!mmuPtr) { - int ngro=MEDnFamilyGroup(fid,meshName,i+1); - med_int natt=MEDnFamily23Attribute(fid,meshName,i+1); - INTERP_KERNEL::AutoPtr 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;jgetMeshAtLevel(meshDimRelToMax,true); } -med_int MEDLoaderNS::getIdFromMeshName(med_idt fid, const char *meshName, std::string& trueMeshName) throw(INTERP_KERNEL::Exception) +MEDCoupling::MEDCouplingUMesh *MEDCoupling::ReadUMeshFromFile(const std::string& fileName, int meshDimRelToMax) { - if(meshName==0) + MEDCoupling::CheckFileForRead(fileName); + MCAuto mm(MEDFileMesh::New(fileName)); + MEDFileMesh *mmPtr(mm); + MEDFileUMesh *mmuPtr=dynamic_cast(mmPtr); + if(!mmuPtr) { - std::vector meshes=getMeshNamesFid(fid); - if(meshes.empty()) - throw INTERP_KERNEL::Exception("No mesh in file"); - trueMeshName=meshes[0]; - return 1; + std::ostringstream oss; oss << "ReadUMeshFromFile : With fileName=\""<< fileName << "\", meshName (the first) =\""<< mm->getName() << "\" exists but it is not an unstructured mesh !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); } - 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()) + return mmuPtr->getMeshAtLevel(meshDimRelToMax,true); +} + +int MEDCoupling::ReadUMeshDimFromFile(const std::string& fileName, const std::string& meshName) +{ + MEDCoupling::CheckFileForRead(fileName); + std::vector poss; + return MEDLoaderNS::readUMeshDimFromFile(fileName,meshName,poss); +} + +MEDCoupling::MEDCouplingUMesh *MEDCoupling::ReadUMeshFromFamilies(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::vector& fams) +{ + MEDCoupling::CheckFileForRead(fileName); + MCAuto mm(MEDFileMesh::New(fileName,meshName)); + MEDFileMesh *mmPtr(mm); + MEDFileUMesh *mmuPtr=dynamic_cast(mmPtr); + if(!mmuPtr) { - 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()); + std::ostringstream oss; oss << "ReadUMeshFromFamilies : With fileName=\""<< fileName << "\", meshName (the first) =\""<< mm->getName() << "\" exists but it is not an unstructured mesh !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); } - trueMeshName=meshName; - return iter-meshes.begin()+1; + return mmuPtr->getFamilies(meshDimRelToMax,fams,true); } -/*! - * 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) +MEDCoupling::MEDCouplingUMesh *MEDCoupling::ReadUMeshFromGroups(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::vector& grps) { - if(nbOfElemCell>=nbOfElemFace) + MEDCoupling::CheckFileForRead(fileName); + MCAuto mm=MEDFileMesh::New(fileName,meshName); + MEDFileMesh *mmPtr(mm); + MEDFileUMesh *mmuPtr=dynamic_cast(mmPtr); + if(!mmuPtr) { - whichEntity=MED_CELL; - nbOfElem=nbOfElemCell; + std::ostringstream oss; oss << "ReadUMeshFromGroups : With fileName=\""<< fileName << "\", meshName (the first) =\""<< mm->getName() << "\" exists but it is not an unstructured mesh !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); } - else + return mmuPtr->getGroups(meshDimRelToMax,grps,true); +} + +MCAuto MEDCoupling::ReadField(const std::string& fileName) +{ + std::vector fieldNames(GetAllFieldNames(fileName)); + std::size_t sz(fieldNames.size()); + if(sz==0) { - whichEntity=MED_CELL; - nbOfElem=nbOfElemFace; + std::ostringstream oss; + oss << "The file \"" << fileName << "\" contains no field !"; + throw INTERP_KERNEL::Exception(oss.str()); } + if(sz>1) + { + std::ostringstream oss; + oss << "In file \"" << fileName << "\" there are more than one field !" << std::endl; + oss << "You are invited to use ReadField(fileName, fieldName) instead to avoid misleading concerning field you want to read !" << std::endl; + oss << "For information, fields available are :" << std::endl; + for(std::vector::const_iterator it=fieldNames.begin();it!=fieldNames.end();it++) + oss << " - \"" << *it << "\"" << std::endl; + throw INTERP_KERNEL::Exception(oss.str()); + } + return ReadField(fileName,fieldNames[0]); } -/*! - * 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) +MCAuto MEDCoupling::ReadField(const std::string& fileName, const std::string& fieldName) { - possibilities.clear(); - med_idt 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;i, double> > iterations(GetAllFieldIterations(fileName,fieldName)); + std::size_t sz(iterations.size()); + if(sz==0) { - med_geometry_type curMedType=typmai[i]; - med_bool changement,transformation; - int curNbOfElemM=MEDmeshnEntity(fid,nommaa,numdt,numit,MED_CELL,curMedType,MED_CONNECTIVITY,MED_NODAL,&changement,&transformation); - int curNbOfElemF=MEDmeshnEntity(fid,nommaa,numdt,numit,MED_CELL,curMedType,MED_CONNECTIVITY,MED_NODAL,&changement,&transformation);//limitation - int curNbOfElem; - med_entity_type whichEntity; - MEDLoaderNS::dispatchElems(curNbOfElemM,curNbOfElemF,curNbOfElem,whichEntity); - if(curNbOfElem>0) - { - INTERP_KERNEL::NormalizedCellType type=typmai2[i]; - int curDim=(int)INTERP_KERNEL::CellModel::GetCellModel(type).getDimension(); - poss.insert(curDim); - } + std::ostringstream oss; + oss << "In file \"" << fileName << "\" field \"" << fieldName << "\" exists but with no time steps !"; + throw INTERP_KERNEL::Exception(oss.str()); } - MEDfileClose(fid); - if(!poss.empty()) + if(sz>1) { - ret=*poss.rbegin(); - for(std::set::const_reverse_iterator it=poss.rbegin();it!=poss.rend();it++) - possibilities.push_back(*it-ret); + std::ostringstream oss; + oss << "In file \"" << fileName << "\" field \"" << fieldName << "\" exists but with more than one time steps !" << std::endl; + oss << "You are invited to use ReadField(fileName, fieldName, iteration, order) instead to avoid misleading concerning time steps." << std::endl; + oss << "For information, time steps available for field \"" << fieldName << "\" are :" << std::endl; + for(std::vector< std::pair< std::pair, double> >::const_iterator it=iterations.begin();it!=iterations.end();it++) + oss << " - " << (*it).first.first << ", " << (*it).first.second << " (" << (*it).second << ")" << std::endl; + throw INTERP_KERNEL::Exception(oss.str()); } - else - ret=-2; - return ret; + return ReadField(fileName,fieldName,iterations[0].first.first,iterations[0].first.second); } -void MEDLoaderNS::readUMeshDataInMedFile(med_idt fid, med_int meshId, DataArrayDouble *&coords, std::list& conn, std::string& description) +MCAuto MEDCoupling::ReadField(const std::string& fileName, const std::string& fieldName, int iteration, int order) { - 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) + MCAuto f(MEDFileAnyTypeField1TS::New(fileName,fieldName,iteration,order)); + MCAuto mesh(MEDFileMesh::New(fileName,f->getMeshName())); { - unsigned ret=0; - for(typename std::list::const_iterator iter=conn.begin();iter!=conn.end();iter++) + MCAuto f1(MEDCoupling::DynamicCast(f)); + if(f1.isNotNull()) { - unsigned curDim=INTERP_KERNEL::CellModel::GetCellModel((*iter).getType()).getDimension(); - if(ret ret(f1->field(mesh)); + return MEDCoupling::DynamicCast(ret); } - return ret; } - - template - void keepSpecifiedMeshDim(typename std::list& conn, unsigned meshDim) { - for(typename std::list::iterator iter=conn.begin();iter!=conn.end();) + MCAuto f1(MEDCoupling::DynamicCast(f)); + if(f1.isNotNull()) { - unsigned curDim=INTERP_KERNEL::CellModel::GetCellModel((*iter).getType()).getDimension(); - if(curDim!=meshDim) - { - (*iter).releaseArray(); - iter=conn.erase(iter); - } - else - iter++; + MCAuto ret(f1->field(mesh)); + return MEDCoupling::DynamicCast(ret); } } - - template - void keepTypes(typename std::list& conn, const std::vector& typesToKeep) { - if(!typesToKeep.empty()) + MCAuto f1(MEDCoupling::DynamicCast(f)); + if(f1.isNotNull()) { - 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++; - } + MCAuto ret(f1->field(mesh)); + return MEDCoupling::DynamicCast(ret); } } + throw INTERP_KERNEL::Exception("MEDCoupling::ReadField : only FLOAT32, FLOAT64 and INT32 supported for the moment !"); } -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. - med_idt 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); - MEDfileClose(fid); - //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 - ParaMEDMEM::MEDCouplingUMesh *newMesh=0; - std::string mName(mesh->getName()); - 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)); - ParaMEDMEM::MEDCouplingUMesh *mesh2=0; - if(typeOfOutField==ON_CELLS) - { - if(newMesh) - mesh2=newMesh->keepSpecifiedCells((*iter).getType(),&ci[0],&ci[0]+ci.size()); - else - mesh2=mesh->keepSpecifiedCells((*iter).getType(),&ci[0],&ci[0]+ci.size()); - } - else if(typeOfOutField==ON_NODES) - { - DataArrayInt *da=0,*da2=0; - if(newMesh) - { - if((int)ci.size()!=newMesh->getNumberOfNodes()) - { - da=newMesh->getCellIdsFullyIncludedInNodeIds(&ci[0],&ci[ci.size()]); - mesh2=dynamic_cast(newMesh->buildPartAndReduceNodes(da->getConstPointer(),da->getConstPointer()+da->getNbOfElems(),da2)); - } - } - else - { - if((int)ci.size()!=mesh->getNumberOfNodes()) - { - da=mesh->getCellIdsFullyIncludedInNodeIds(&ci[0],&ci[ci.size()]); - mesh2=dynamic_cast(mesh->buildPartAndReduceNodes(da->getConstPointer(),da->getConstPointer()+da->getNbOfElems(),da2)); - // - 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()); - } - } - if(da) - da->decrRef(); - if(da2) - da2->decrRef(); - } - if(newMesh) - newMesh->decrRef(); - newMesh=mesh2; - } - } - // - ParaMEDMEM::MEDCouplingFieldDouble *ret=ParaMEDMEM::MEDCouplingFieldDouble::New(typeOfOutField,ONE_TIME); - ret->setName(fieldName); - ret->setTime(time,iteration,order); - if(newMesh) - { - newMesh->setName(mName.c_str());//retrieving mesh name to avoid renaming due to mesh restriction in case of profile. - ret->setMesh(newMesh); - newMesh->decrRef(); - } - else - ret->setMesh(mesh); - ParaMEDMEM::DataArrayDouble *arr=buildArrayFromRawData(fieldPerCellType,infos); - ret->setArray(arr); - arr->decrRef(); - // - 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) -{ - CheckFileForRead(fileName); - std::vector familiesToKeep; - std::vector typesToKeep; - unsigned meshDim; - int *cellRenum; - ParaMEDMEM::MEDCouplingUMesh *ret=MEDLoaderNS::readUMeshFromFileLev1(fileName,meshName,meshDimRelToMax,familiesToKeep,typesToKeep,meshDim,cellRenum); - if(cellRenum) - { - ret->renumberCells(cellRenum,true); - delete [] cellRenum; - } - return ret; -} - -ParaMEDMEM::MEDCouplingUMesh *MEDLoader::ReadUMeshFromFile(const char *fileName, int meshDimRelToMax) throw(INTERP_KERNEL::Exception) -{ - CheckFileForRead(fileName); - std::vector familiesToKeep; - std::vector typesToKeep; - unsigned meshDim; - int *cellRenum; - ParaMEDMEM::MEDCouplingUMesh *ret=MEDLoaderNS::readUMeshFromFileLev1(fileName,0,meshDimRelToMax,familiesToKeep,typesToKeep,meshDim,cellRenum); - if(cellRenum) - { - ret->renumberCells(cellRenum,true); - delete [] cellRenum; - } - return ret; -} - -int MEDLoader::ReadUMeshDimFromFile(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception) -{ - CheckFileForRead(fileName); - std::vector poss; - return MEDLoaderNS::readUMeshDimFromFile(fileName,meshName,poss); -} - -ParaMEDMEM::MEDCouplingUMesh *MEDLoader::ReadUMeshFromFamilies(const char *fileName, const char *meshName, int meshDimRelToMax, const std::vector& fams) throw(INTERP_KERNEL::Exception) -{ - CheckFileForRead(fileName); - std::vector familiesToKeep=MEDLoaderNS::getIdsFromFamilies(fileName,meshName,fams); - std::vector typesToKeep; - unsigned meshDim; - int *cellRenum; - ParaMEDMEM::MEDCouplingUMesh *ret=MEDLoaderNS::readUMeshFromFileLev1(fileName,meshName,meshDimRelToMax,familiesToKeep,typesToKeep,meshDim,cellRenum); - if(fams.size()==1) - ret->setName(fams.back().c_str()); - if(cellRenum) - { - ret->renumberCells(cellRenum,true); - delete [] cellRenum; - } - return ret; -} - -ParaMEDMEM::MEDCouplingUMesh *MEDLoader::ReadUMeshFromGroups(const char *fileName, const char *meshName, int meshDimRelToMax, const std::vector& grps) throw(INTERP_KERNEL::Exception) +MCAuto MEDCoupling::ReadField(MEDCoupling::TypeOfField type, const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, int iteration, int order) { - CheckFileForRead(fileName); - std::vector familiesToKeep=MEDLoaderNS::getIdsFromGroups(fileName,meshName,grps); - std::vector typesToKeep; - unsigned meshDim; - int *cellRenum; - ParaMEDMEM::MEDCouplingUMesh *ret=MEDLoaderNS::readUMeshFromFileLev1(fileName,meshName,meshDimRelToMax,familiesToKeep,typesToKeep,meshDim,cellRenum); - if(grps.size()==1) - ret->setName(grps.back().c_str()); - if(cellRenum) - { - ret->renumberCells(cellRenum,true); - delete [] cellRenum; - } - return ret; -} - -ParaMEDMEM::MEDCouplingFieldDouble *MEDLoader::ReadField(ParaMEDMEM::TypeOfField type, const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception) -{ - CheckFileForRead(fileName); + MEDCoupling::CheckFileForRead(fileName); switch(type) - { + { case ON_CELLS: return ReadFieldCell(fileName,meshName,meshDimRelToMax,fieldName,iteration,order); case ON_NODES: @@ -2101,710 +1296,264 @@ ParaMEDMEM::MEDCouplingFieldDouble *MEDLoader::ReadField(ParaMEDMEM::TypeOfField return ReadFieldGaussNE(fileName,meshName,meshDimRelToMax,fieldName,iteration,order); default: throw INTERP_KERNEL::Exception("Type of field specified not managed ! manages are ON_NODES, ON_CELLS, ON_GAUSS_PT or ON_GAUSS_NE !"); - } + } } -std::vector MEDLoader::ReadFieldsOnSameMesh(ParaMEDMEM::TypeOfField type, const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, - const std::vector >& its) throw(INTERP_KERNEL::Exception) +std::vector MEDCoupling::ReadFieldsOnSameMesh(MEDCoupling::TypeOfField type, const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, + const std::vector >& its) { if(its.empty()) - return std::vector(); - CheckFileForRead(fileName); - std::vector ret(its.size()); + return std::vector(); + MEDCoupling::CheckFileForRead(fileName); + std::vector ret(its.size()); + std::vector< MCAuto > 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; + MCAuto mm=MEDFileMesh::New(fileName,meshName); + MEDFileMesh *mmPtr(mm); + MEDFileUMesh *mmuPtr=dynamic_cast(mmPtr); + if(!mmuPtr) + throw INTERP_KERNEL::Exception("ReadFieldsOnSameMesh : only unstructured mesh is managed !"); + MCAuto m=mmuPtr->getMeshAtLevel(meshDimRelToMax); + const DataArrayIdType *o2n=mmuPtr->getNumberFieldAtLevel(meshDimRelToMax); + MCAuto 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++) + { + MCAuto ff=MEDFileField1TS::New(fileName,fieldName,(*it).first,(*it).second); + MCAuto 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; } -std::vector MEDLoader::ReadFieldsCellOnSameMesh(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, - const std::vector >& its) throw(INTERP_KERNEL::Exception) +std::vector MEDCoupling::ReadFieldsCellOnSameMesh(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, + const std::vector >& its) { return ReadFieldsOnSameMesh(ON_CELLS,fileName,meshName,meshDimRelToMax,fieldName,its); } -std::vector MEDLoader::ReadFieldsNodeOnSameMesh(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, - const std::vector >& its) throw(INTERP_KERNEL::Exception) +std::vector MEDCoupling::ReadFieldsNodeOnSameMesh(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, + const std::vector >& its) { return ReadFieldsOnSameMesh(ON_NODES,fileName,meshName,meshDimRelToMax,fieldName,its); } -std::vector MEDLoader::ReadFieldsGaussOnSameMesh(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, - const std::vector >& its) throw(INTERP_KERNEL::Exception) +std::vector MEDCoupling::ReadFieldsGaussOnSameMesh(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, + const std::vector >& its) { return ReadFieldsOnSameMesh(ON_GAUSS_PT,fileName,meshName,meshDimRelToMax,fieldName,its); } -std::vector MEDLoader::ReadFieldsGaussNEOnSameMesh(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, - const std::vector >& its) throw(INTERP_KERNEL::Exception) +std::vector MEDCoupling::ReadFieldsGaussNEOnSameMesh(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, + const std::vector >& its) { return ReadFieldsOnSameMesh(ON_GAUSS_NE,fileName,meshName,meshDimRelToMax,fieldName,its); } -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); -} - -ParaMEDMEM::MEDCouplingFieldDouble *MEDLoader::ReadFieldNode(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception) +namespace MEDCoupling { - 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); -} + template + MCAuto::FieldType> ReadFieldCellLikeT(typename MLFieldTraits::F1TSType *ff, MEDCoupling::TypeOfField type, const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, int iteration, int order) + { + MCAuto mm(MEDFileMesh::New(fileName,meshName)); + MCAuto muPtr(MEDCoupling::DynamicCast(mm)); + MCAuto m(mm->getMeshAtLevel(meshDimRelToMax,false)); + MCAuto::FieldType> ret(ff->getFieldOnMeshAtLevel(type,m)); + if(muPtr.isNotNull()) + { + const DataArrayIdType *num(muPtr->getNumberFieldAtLevel(meshDimRelToMax)); + if(num) + ret->renumberCells(num->begin()); + } + return ret; + } -/*! - * @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) -{ - med_idt fid=MEDfileOpen(fileName,forceFromScratch?MED_ACC_CREAT:MED_ACC_RDWR); - std::string meshName(mesh[0]->getName()); - if(meshName=="") + MEDCoupling::MEDCouplingField *ReadFieldCellLike(MEDCoupling::TypeOfField type, const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, int iteration, int order) + { + MCAuto f(MEDFileAnyTypeField1TS::New(fileName,fieldName,iteration,order)); { - MEDfileClose(fid); - 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 + MCAuto f1(MEDCoupling::DynamicCast(f)); + if(f1.isNotNull()) + { + MCAuto ret(ReadFieldCellLikeT(f1,type,fileName,meshName,meshDimRelToMax,fieldName,iteration,order)); + return ret.retn(); + } } - 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++) { - for(int i=0;i f1(MEDCoupling::DynamicCast(f)); + if(f1.isNotNull()) { - med_geometry_type curMedType=typmai[i]; - INTERP_KERNEL::NormalizedCellType curType=typmai2[i]; - if(allTypes.find(curType)!=allTypes.end()) - { - std::vector 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]); - } + MCAuto ret(ReadFieldCellLikeT(f1,type,fileName,meshName,meshDimRelToMax,fieldName,iteration,order)); + return ret.retn(); } } - 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()); - MEDfileClose(fid); -} - -/*! - * 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; - med_idt 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); - } - MEDfileClose(fid2); -} - -/*! - * 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); - med_idt 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); - MEDfileClose(fid); -} - -/*! - * 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(); - med_idt 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(); - int *profile=new int [ids.size()]; - std::transform(ids.begin(),ids.end(),profile,std::bind2nd(std::plus(),1)); - MEDprofileWr(fid,profileName,ids.size(),profile); - delete [] 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; - } - MEDfileClose(fid); -} - -void MEDLoaderNS::appendNodeElementProfileField(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, const int *thisMeshCellIdsPerType) -{ - med_int numdt,numo; - med_float dt; - int nbComp=f->getNumberOfComponents(); - med_idt 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(); - int *profile=new int [ids.size()]; - std::transform(ids.begin(),ids.end(),profile,std::bind2nd(std::plus(),1)); - MEDprofileWr(fid,profileName,ids.size(),profile); - delete [] 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; - } - MEDfileClose(fid); -} - -/*! - * 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; + MCAuto f1(MEDCoupling::DynamicCast(f)); + if(f1.isNotNull()) + { + MCAuto ret(ReadFieldCellLikeT(f1,type,fileName,meshName,meshDimRelToMax,fieldName,iteration,order)); + return ret.retn(); + } } - return fid; -} + throw INTERP_KERNEL::Exception("MEDCoupling::ReadFieldCell : only FLOAT32, FLOAT64 and INT32 supported for the moment !"); + } -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(); - med_idt 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: + template + MCAuto::FieldType> ReadFieldNodeT(typename MLFieldTraits::F1TSType *ff, const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, int iteration, int order) + { + MCAuto mm(MEDFileMesh::New(fileName,meshName)); + MCAuto m(mm->getMeshAtLevel(meshDimRelToMax,false)); + MCAuto::FieldType> ret(ff->getFieldOnMeshAtLevel(ON_NODES,m)); + MCAuto muPtr(MEDCoupling::DynamicCast(mm)); + if(ff->getPflsReallyUsed().empty()) { - std::list split; - prepareCellFieldDoubleForWriting(f,0,split); - int idGp=0; - for(std::list::const_iterator iter=split.begin();iter!=split.end();iter++) + if(muPtr.isNotNull()) { - 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); - int id=f->getGaussLocalizationIdOfOneType((*iter).getType()); - 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 nbOfEntity=f->getMesh()->getNumberOfCellsWithType((*iter).getType()); - 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); - 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); - pt+=nbOfValues*nbComp; + const DataArrayIdType *num(muPtr->getNumberFieldAtLevel(meshDimRelToMax)); + if(num) + ret->renumberCells(num->begin()); } - break; } - case ParaMEDMEM::ON_GAUSS_NE: + else { - std::list split; - prepareCellFieldDoubleForWriting(f,0,split); - for(std::list::const_iterator iter=split.begin();iter!=split.end();iter++) + DataArrayIdType *pfl(nullptr),*arr2(nullptr); + MCAuto::ArrayType> arr(ff->getFieldWithProfile(ON_NODES,meshDimRelToMax,mm,pfl)); + MCAuto pflSafe(pfl); + MCAuto mp(m->getCellIdsFullyIncludedInNodeIds(pfl->begin(),pfl->end())); + MCAuto mzip(static_cast(m->buildPartAndReduceNodes(mp->begin(),mp->end(),arr2))); + MCAuto arr2Safe(arr2); + MCAuto arr3(arr2->invertArrayO2N2N2O(mzip->getNumberOfNodes())); + MCAuto pflSorted(pflSafe->deepCopy()); pflSorted->sort(true); + if(!arr3->isEqualWithoutConsideringStr(*pflSorted)) + throw INTERP_KERNEL::Exception("ReadFieldNode : not implemented yet !"); + if(!arr3->isEqualWithoutConsideringStr(*pflSafe)) { - 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; + MCAuto o2n2(pflSafe->checkAndPreparePermutation()); + MCAuto n2o2(o2n2->invertArrayO2N2N2O(o2n2->getNumberOfTuples())); + mzip->renumberNodes(n2o2->begin(),n2o2->getNumberOfTuples()); + arr->setName(""); + ret->setArray(arr); } - break; + ret->setMesh(mzip); } - default: - throw INTERP_KERNEL::Exception("Not managed this type of FIELD !"); - } - MEDfileClose(fid); - 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;) - { - curType=(INTERP_KERNEL::NormalizedCellType)conn[*pt]; - const int *pt2=std::find_if(pt+1,connI+nbOfCells,ConnReaderML(conn,(int)curType)); - if(!cellIdsPerType) - split.push_back(MEDLoader::MEDFieldDoublePerCellType(curType,0,nbComp,pt2-pt,0,0)); - else - { - split.push_back(MEDLoader::MEDFieldDoublePerCellType(curType,0,nbComp,pt2-pt,wCellIdsPT,0)); - wCellIdsPT+=std::distance(pt,pt2); - } - pt=pt2; - } + return ret; + } } -void MEDLoaderNS::writeFieldAndMeshDirectly(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, bool forceFromScratch) +MEDCoupling::MEDCouplingField *MEDCoupling::ReadFieldCell(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, int iteration, int order) { - 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) - { - 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 ; - } - throw INTERP_KERNEL::Exception("The mesh underlying field is not unstructured ! Only unstructured mesh supported for writting now !"); + return ReadFieldCellLike(ON_CELLS,fileName,meshName,meshDimRelToMax,fieldName,iteration,order); } -/*! - * 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) +MEDCoupling::MEDCouplingField *MEDCoupling::ReadFieldNode(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, int iteration, int order) { - 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,(MEDCouplingUMesh *)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()) - { - 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: + MCAuto f(MEDFileAnyTypeField1TS::New(fileName,fieldName,iteration,order)); + { + MCAuto f1(MEDCoupling::DynamicCast(f)); + if(f1.isNotNull()) { - 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; + MCAuto ret(ReadFieldNodeT(f1,fileName,meshName,meshDimRelToMax,fieldName,iteration,order)); + return ret.retn(); } - case ParaMEDMEM::ON_NODES: + } + { + MCAuto f1(MEDCoupling::DynamicCast(f)); + if(f1.isNotNull()) { - appendNodeProfileField(fileName,f,da->getConstPointer()+m->getNumberOfNodes()); - break; + MCAuto ret(ReadFieldNodeT(f1,fileName,meshName,meshDimRelToMax,fieldName,iteration,order)); + return ret.retn(); } - default: + } + { + MCAuto f1(MEDCoupling::DynamicCast(f)); + if(f1.isNotNull()) { - throw INTERP_KERNEL::Exception("Not implemented other profile fitting from already written mesh for fields than on NODES and on CELLS."); + MCAuto ret(ReadFieldNodeT(f1,fileName,meshName,meshDimRelToMax,fieldName,iteration,order)); + return ret.retn(); } - } + } + throw INTERP_KERNEL::Exception("MEDCoupling::ReadFieldNode : only FLOAT32, FLOAT64 and INT32 supported for the moment !"); } -void MEDLoader::WriteUMesh(const char *fileName, const ParaMEDMEM::MEDCouplingUMesh *mesh, bool writeFromScratch) throw(INTERP_KERNEL::Exception) +MEDCoupling::MEDCouplingField *MEDCoupling::ReadFieldGauss(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, int iteration, int order) { - std::string meshName(mesh->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 !"); - int status=MEDLoaderBase::getStatusOfFile(fileName); - bool isRenumbering; - 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()); - } - std::vector meshV(1); meshV[0]=mesh; - std::vector famV(1); famV[0]=0; - if(writeFromScratch) - { - MEDLoaderNS::writeUMeshesDirectly(fileName,meshV,famV,true,isRenumbering); - return ; - } - if(status==MEDLoaderBase::NOT_EXIST) - { - MEDLoaderNS::writeUMeshesDirectly(fileName,meshV,famV,true,isRenumbering); - return; - } - else - { - std::vector meshNames=GetMeshNames(fileName); - if(std::find(meshNames.begin(),meshNames.end(),meshName)==meshNames.end()) - MEDLoaderNS::writeUMeshesDirectly(fileName,meshV,famV,false,isRenumbering); - else - { - std::ostringstream oss; oss << "File \'" << fileName << "\' already exists and has already a mesh called \""; - oss << meshName << "\" !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } + return ReadFieldCellLike(ON_GAUSS_PT,fileName,meshName,meshDimRelToMax,fieldName,iteration,order); } -void MEDLoader::WriteUMeshDep(const char *fileName, const ParaMEDMEM::MEDCouplingUMesh *mesh, bool writeFromScratch) throw(INTERP_KERNEL::Exception) +MEDCoupling::MEDCouplingField *MEDCoupling::ReadFieldGaussNE(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, int iteration, int order) { - std::string meshName(mesh->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 !"); - int status=MEDLoaderBase::getStatusOfFile(fileName); - bool isRenumbering; - 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()); - } - std::vector meshV(1); meshV[0]=mesh; - std::vector famV(1); famV[0]=0; - if(writeFromScratch) - { - MEDLoaderNS::writeUMeshesDirectly(fileName,meshV,famV,true,isRenumbering); - return ; - } - if(status==MEDLoaderBase::NOT_EXIST) - { - MEDLoaderNS::writeUMeshesDirectly(fileName,meshV,famV,true,isRenumbering); - return; - } - else - MEDLoaderNS::writeUMeshesDirectly(fileName,meshV,famV,false,isRenumbering); + return ReadFieldCellLike(ON_GAUSS_NE,fileName,meshName,meshDimRelToMax,fieldName,iteration,order); } -void MEDLoader::WriteUMeshesPartition(const char *fileName, const char *meshNameC, const std::vector& meshes, bool writeFromScratch) throw(INTERP_KERNEL::Exception) +void MEDCoupling::WriteMesh(const std::string& fileName, const MEDCoupling::MEDCouplingMesh *mesh, bool writeFromScratch) { - std::string meshName(meshNameC); - 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 2nd parameter !"); - int status=MEDLoaderBase::getStatusOfFile(fileName); - if(status!=MEDLoaderBase::EXIST_RW && status!=MEDLoaderBase::NOT_EXIST) + if(!mesh) + throw INTERP_KERNEL::Exception("WriteMesh : input mesh is null !"); + const MEDCouplingUMesh *um(dynamic_cast(mesh)); + if(um) { - 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 !"); - 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)->getName())==tmp.end()) - tmp.insert((*iter)->getName()); - else - throw INTERP_KERNEL::Exception("The names of meshes must be different each other !"); + WriteUMesh(fileName,um,writeFromScratch); + return ; } - tmp.clear(); - if(writeFromScratch) + int mod=writeFromScratch?2:0; + const MEDCoupling1GTUMesh *um2(dynamic_cast(mesh)); + if(um2) { - MEDLoaderNS::writeUMeshesPartitionDirectly(fileName,meshNameC,meshes,true); + MCAuto mmu(MEDFileUMesh::New()); + AssignStaticWritePropertiesTo(*mmu); + mmu->setMeshAtLevel(0,const_cast(um2)); + mmu->write(fileName,mod); return ; } - if(status==MEDLoaderBase::NOT_EXIST) + const MEDCouplingCMesh *um3(dynamic_cast(mesh)); + if(um3) { - MEDLoaderNS::writeUMeshesPartitionDirectly(fileName,meshNameC,meshes,true); - return; + MCAuto mmc(MEDFileCMesh::New()); + AssignStaticWritePropertiesTo(*mmc); + mmc->setMesh(const_cast(um3)); + mmc->write(fileName,mod); + return ; } - else + const MEDCouplingCurveLinearMesh *um4(dynamic_cast(mesh)); + if(um4) { - std::vector meshNames=GetMeshNames(fileName); - if(std::find(meshNames.begin(),meshNames.end(),meshName)==meshNames.end()) - MEDLoaderNS::writeUMeshesPartitionDirectly(fileName,meshNameC,meshes,false); - else - { - std::ostringstream oss; oss << "File \'" << fileName << "\' already exists and has already a mesh called \""; - oss << meshName << "\" !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } + MCAuto mmc(MEDFileCurveLinearMesh::New()); + AssignStaticWritePropertiesTo(*mmc); + mmc->setMesh(const_cast(um4)); + mmc->write(fileName,mod); + return ; } + throw INTERP_KERNEL::Exception("WriteMesh : only MEDCouplingUMesh, MEDCoupling1GTUMesh, MEDCouplingCMesh, MEDCouplingCurveLinear are dealed in this API for the moment !"); } -void MEDLoader::WriteUMeshesPartitionDep(const char *fileName, const char *meshNameC, const std::vector& meshes, bool writeFromScratch) throw(INTERP_KERNEL::Exception) +void MEDCoupling::WriteUMesh(const std::string& fileName, const MEDCoupling::MEDCouplingUMesh *mesh, bool writeFromScratch) +{ + if(!mesh) + throw INTERP_KERNEL::Exception("WriteUMesh : input mesh is null !"); + int mod=writeFromScratch?2:0; + MCAuto m(MEDFileUMesh::New()); + AssignStaticWritePropertiesTo(*m); + MCAuto mcpy(static_cast(mesh->deepCopy())); + m->setMeshAtLevel(0,mcpy,true); + m->write(fileName,mod); +} + +void MEDCoupling::WriteUMeshDep(const std::string& fileName, const MEDCoupling::MEDCouplingUMesh *mesh, bool writeFromScratch) +{ + WriteUMesh(fileName,mesh,writeFromScratch); +} + +void MEDCoupling::WriteUMeshesPartition(const std::string& fileName, const std::string& meshNameC, const std::vector& meshes, bool writeFromScratch) { std::string meshName(meshNameC); if(meshName.empty()) @@ -2815,141 +1564,257 @@ void MEDLoader::WriteUMeshesPartitionDep(const char *fileName, const char *meshN 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 !"); - 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)->getName())==tmp.end()) - tmp.insert((*iter)->getName()); - else - throw INTERP_KERNEL::Exception("The names of meshes must be different each other !"); - } - tmp.clear(); - if(writeFromScratch) - { - MEDLoaderNS::writeUMeshesPartitionDirectly(fileName,meshNameC,meshes,true); - return ; - } - if(status==MEDLoaderBase::NOT_EXIST) - { - MEDLoaderNS::writeUMeshesPartitionDirectly(fileName,meshNameC,meshes,true); - return; - } - else - { - MEDLoaderNS::writeUMeshesPartitionDirectly(fileName,meshNameC,meshes,false); - } + MCAuto m(MEDFileUMesh::New()); + AssignStaticWritePropertiesTo(*m); + m->setGroupsFromScratch(0,meshes,true); + m->setName(meshNameC); + int mod=writeFromScratch?2:0; + m->write(fileName,mod); } -void MEDLoader::WriteUMeshes(const char *fileName, const std::vector& meshes, bool writeFromScratch) throw(INTERP_KERNEL::Exception) +void MEDCoupling::WriteUMeshesPartitionDep(const std::string& fileName, const std::string& meshNameC, const std::vector& meshes, bool writeFromScratch) { - int status=MEDLoaderBase::getStatusOfFile(fileName); - if(status!=MEDLoaderBase::EXIST_RW && status!=MEDLoaderBase::NOT_EXIST) + WriteUMeshesPartition(fileName,meshNameC,meshes,writeFromScratch); +} + +void MEDCoupling::WriteUMeshes(const std::string& fileName, const std::vector& meshes, bool writeFromScratch) +{ + int mod(writeFromScratch?2:0); + MCAuto m(MEDFileUMesh::New()); + AssignStaticWritePropertiesTo(*m); + m->setMeshes(meshes,true); + m->write(fileName,mod); +} + +template +void MEDLoaderNS::writeFieldWithoutReadingAndMappingOfMeshInFile(const std::string& fileName, const typename MEDCoupling::Traits::FieldType *f, bool writeFromScratch) +{ + MCAuto< typename MLFieldTraits::F1TSType > ff(MLFieldTraits::F1TSType::New()); + AssignStaticWritePropertiesTo(*ff); + MCAuto::FieldType> f2(f->deepCopy()); + const MEDCouplingMesh *m(f2->getMesh()); + const MEDCouplingUMesh *um(dynamic_cast(m)); + const MEDCoupling1GTUMesh *um2(dynamic_cast(m)); + const MEDCouplingCMesh *um3(dynamic_cast(m)); + const MEDCouplingCurveLinearMesh *um4(dynamic_cast(m)); + MCAuto mm; + int mod(writeFromScratch?2:0); + if(um) { - std::ostringstream oss; oss << "File with name \'" << fileName << "\' has not valid permissions !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); + MCAuto mmu(MEDFileUMesh::New()); + AssignStaticWritePropertiesTo(*mmu); + MCAuto o2n(um->getRenumArrForMEDFileFrmt()); + MCAuto 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); } - 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) + else if(um2) { - MEDLoaderNS::writeUMeshesDirectly(fileName,meshes,families,true,isRenumbering); - return ; + MCAuto mmu(MEDFileUMesh::New()); + AssignStaticWritePropertiesTo(*mmu); + mmu->setMeshAtLevel(0,const_cast(um2)); + ff->setFieldNoProfileSBT(f2); + mmu->write(fileName,mod); } - if(status==MEDLoaderBase::NOT_EXIST) + else if(um3) { - MEDLoaderNS::writeUMeshesDirectly(fileName,meshes,families,true,isRenumbering); - return; + MCAuto mmc(MEDFileCMesh::New()); + AssignStaticWritePropertiesTo(*mmc); + mmc->setMesh(const_cast(um3)); + ff->setFieldNoProfileSBT(f2); + mmc->write(fileName,mod); } - else + else if(um4) { - MEDLoaderNS::writeUMeshesDirectly(fileName,meshes,families,false,isRenumbering); - return; + MCAuto mmc(MEDFileCurveLinearMesh::New()); + AssignStaticWritePropertiesTo(*mmc); + mmc->setMesh(const_cast(um4)); + ff->setFieldNoProfileSBT(f2); + mmc->write(fileName,mod); } + else + throw INTERP_KERNEL::Exception("MEDLoaderNS::writeFieldWithoutReadingAndMappingOfMeshInFile : only MEDCouplingUMesh, MEDCoupling1GTUMesh, MEDCouplingCMesh, MEDCouplingCurveLinear 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) +template +void WriteFieldT(const std::string& fileName, const typename MEDCoupling::Traits::FieldType *f, bool writeFromScratch) { - int status=MEDLoaderBase::getStatusOfFile(fileName); + if(!f) + throw INTERP_KERNEL::Exception("WriteField : input field is NULL !"); + f->checkConsistencyLight(); + 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); + std::vector meshNames(GetMeshNames(fileName)); + if(!f->getMesh()) + throw INTERP_KERNEL::Exception("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); + { + MCAuto mm(MEDFileMesh::New(fileName,f->getMesh()->getName().c_str())); + AssignStaticWritePropertiesTo(*mm); + const MEDFileMesh *mmPtr(mm); + const MEDFileUMesh *mmuPtr(dynamic_cast(mmPtr)); + if(!mmuPtr) + throw INTERP_KERNEL::Exception("WriteField : only umeshes are supported now !"); + MCAuto< typename MEDCoupling::Traits::FieldType > f2(f->deepCopy()); + MEDCouplingUMesh *m(dynamic_cast(const_cast(f2->getMesh()))); + if(!m) + throw INTERP_KERNEL::Exception("WriteField : only umesh in input field supported !"); + MCAuto o2n(m->getRenumArrForMEDFileFrmt()); + f2->renumberCells(o2n->begin(),false); + m=static_cast(const_cast(f2->getMesh())); + MCAuto mread(mmuPtr->getMeshAtLevel(m->getMeshDimension()-mm->getMeshDimension())); + if(f2->getTypeOfField()!=ON_NODES) + { + if(!m->getCoords()->isEqualWithoutConsideringStr(*mread->getCoords(),_EPS_FOR_NODE_COMP)) + m->tryToShareSameCoordsPermute(*mread,_EPS_FOR_NODE_COMP); + else + mread->setCoords(m->getCoords()); + DataArrayIdType *part(NULL); + bool b(mread->areCellsIncludedIn(m,_COMP_FOR_CELL,part)); + MCAuto partSafe(part); + if(!b) + { + std::ostringstream oss; oss << "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()); + } + MCAuto< typename MLFieldTraits::F1TSType > f1ts(MLFieldTraits::F1TSType::New()); + AssignStaticWritePropertiesTo(*f1ts); + if(part->isIota(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 + { + DataArrayIdType *part(NULL); + bool b(mread->getCoords()->areIncludedInMe(m->getCoords(),_EPS_FOR_NODE_COMP,part)); + MCAuto partSafe(part); + if(!b) + { + std::ostringstream oss; oss << "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()); + } + MCAuto< typename MLFieldTraits::F1TSType > f1ts(MLFieldTraits::F1TSType::New()); + AssignStaticWritePropertiesTo(*f1ts); + if(part->isIota(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) +void MEDCoupling::WriteField(const std::string& fileName, const MEDCoupling::MEDCouplingField *f, bool writeFromScratch) { - int status=MEDLoaderBase::getStatusOfFile(fileName); - if(status!=MEDLoaderBase::EXIST_RW && status!=MEDLoaderBase::NOT_EXIST) + if(!f) + throw INTERP_KERNEL::Exception("WriteField : input field is null !"); + { + const MEDCoupling::MEDCouplingFieldDouble *f1(dynamic_cast(f)); + if(f1) + { + WriteFieldT(fileName,f1,writeFromScratch); + return ; + } + } + { + const MEDCoupling::MEDCouplingFieldInt32 *f1(dynamic_cast(f)); + if(f1) + { + WriteFieldT(fileName,f1,writeFromScratch); + return ; + } + } + { + const MEDCoupling::MEDCouplingFieldFloat *f1(dynamic_cast(f)); + if(f1) + { + WriteFieldT(fileName,f1,writeFromScratch); + return ; + } + } + throw INTERP_KERNEL::Exception("WriteField : input field is not in FLOAT32, FLOAT64, INT32 !"); +} + +void MEDCoupling::WriteFieldDep(const std::string& fileName, const MEDCoupling::MEDCouplingField *f, bool writeFromScratch) +{ + WriteField(fileName,f,writeFromScratch); +} + +template +void WriteFieldUsingAlreadyWrittenMeshT(const std::string& fileName, const typename MEDCoupling::Traits::FieldType *f) +{ + if(!f) + throw INTERP_KERNEL::Exception("WriteFieldUsingAlreadyWrittenMeshT : input field is null !"); + f->checkConsistencyLight(); + int status(MEDLoaderBase::getStatusOfFile(fileName)); + if(status!=MEDLoaderBase::EXIST_RW) { - std::ostringstream oss; oss << "File with name \'" << fileName << "\' has not valid permissions !"; + std::ostringstream oss; oss << "File with name \'" << fileName << "\' has not valid permissions or not exists !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } - if(writeFromScratch) + MCAuto< typename MLFieldTraits::F1TSType > f1ts(MLFieldTraits::F1TSType::New()); + AssignStaticWritePropertiesTo(*f1ts); + MEDCouplingUMesh *m(dynamic_cast(const_cast(f->getMesh()))); + if(m) { - MEDLoaderNS::writeFieldAndMeshDirectly(fileName,f,true); - return ; - } - if(status==MEDLoaderBase::NOT_EXIST) - { - MEDLoaderNS::writeFieldAndMeshDirectly(fileName,f,true); - return ; + MCAuto o2n(m->getRenumArrForMEDFileFrmt()); + MCAuto< typename MEDCoupling::Traits::FieldType > f2(f->deepCopy()); + f2->renumberCells(o2n->begin(),false); + f1ts->setFieldNoProfileSBT(f2); } else - MEDLoaderNS::writeFieldAndMeshDirectly(fileName,f,false); + f1ts->setFieldNoProfileSBT(f); + f1ts->write(fileName,0); } -void MEDLoader::WriteFieldUsingAlreadyWrittenMesh(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f) throw(INTERP_KERNEL::Exception) +void MEDCoupling::WriteFieldUsingAlreadyWrittenMesh(const std::string& fileName, const MEDCoupling::MEDCouplingField *f) { - f->checkCoherency(); - int status=MEDLoaderBase::getStatusOfFile(fileName); - if(status!=MEDLoaderBase::EXIST_RW) - { - 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); + if(!f) + throw INTERP_KERNEL::Exception("WriteFieldUsingAlreadyWrittenMesh : input field is null !"); + { + const MEDCoupling::MEDCouplingFieldDouble *f1(dynamic_cast(f)); + if(f1) + WriteFieldUsingAlreadyWrittenMeshT(fileName,f1); + return ; + } + { + const MEDCoupling::MEDCouplingFieldInt32 *f1(dynamic_cast(f)); + if(f1) + WriteFieldUsingAlreadyWrittenMeshT(fileName,f1); + return ; + } + { + const MEDCoupling::MEDCouplingFieldFloat *f1(dynamic_cast(f)); + if(f1) + WriteFieldUsingAlreadyWrittenMeshT(fileName,f1); + return ; + } + throw INTERP_KERNEL::Exception("WriteFieldUsingAlreadyWrittenMesh : input field is not in FLOAT32, FLOAT64, INT32 !"); }