X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FMEDLoader%2FMEDFileMesh.cxx;h=f07c99ce462ffef190cbeb2cc11b1382b6b3d0d0;hb=701d5a29e2682e1687b49bc61e09b9d7b38d2110;hp=a8997f5bdacbbe8c05f71f07b48b1ecf8f05c33c;hpb=a99624dca70a078db8c723b92c8eb5cc361ea833;p=tools%2Fmedcoupling.git diff --git a/src/MEDLoader/MEDFileMesh.cxx b/src/MEDLoader/MEDFileMesh.cxx index a8997f5bd..f07c99ce4 100644 --- a/src/MEDLoader/MEDFileMesh.cxx +++ b/src/MEDLoader/MEDFileMesh.cxx @@ -32,6 +32,8 @@ #include #include +extern med_geometry_type typmai3[34]; + using namespace ParaMEDMEM; const char MEDFileMesh::DFT_FAM_NAME[]="FAMILLE_ZERO"; @@ -54,7 +56,7 @@ std::size_t MEDFileMesh::getHeapMemorySizeWithoutChildren() const return ret; } -std::vector MEDFileMesh::getDirectChildren() const +std::vector MEDFileMesh::getDirectChildrenWithNull() const { return std::vector(); } @@ -84,7 +86,7 @@ MEDFileMesh *MEDFileMesh::New(const std::string& fileName, MEDFileMeshReadSelect std::string dummy2; MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2); switch(meshType) - { + { case UNSTRUCTURED: { MEDCouplingAutoRefCountObjectPtr ret=MEDFileUMesh::New(); @@ -108,7 +110,7 @@ MEDFileMesh *MEDFileMesh::New(const std::string& fileName, MEDFileMeshReadSelect std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << ms.front() << "' exists but unsupported type yet !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } - } + } } /*! @@ -134,7 +136,7 @@ MEDFileMesh *MEDFileMesh::New(const std::string& fileName, const std::string& mN std::string dummy2; MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2); switch(meshType) - { + { case UNSTRUCTURED: { MEDCouplingAutoRefCountObjectPtr ret=MEDFileUMesh::New(); @@ -158,7 +160,7 @@ MEDFileMesh *MEDFileMesh::New(const std::string& fileName, const std::string& mN std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << mName << "' exists but unsupported type yet !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } - } + } } /*! @@ -253,7 +255,7 @@ void MEDFileMesh::setName(const std::string& name) */ void MEDFileMesh::clearNonDiscrAttributes() const { - + } bool MEDFileMesh::changeNames(const std::vector< std::pair >& modifTab) @@ -813,7 +815,7 @@ bool MEDFileMesh::areGrpsEqual(const MEDFileMesh *other, std::string& what) cons { oss << " Group \"" << (*it).first << "\" on following families :\n"; for(std::vector::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++) - oss << " \"" << *it2 << "\n"; + oss << " \"" << *it2 << "\n"; } oss << "Second group description :\n"; for(std::map >::const_iterator it=other->_groups.begin();it!=other->_groups.end();it++) @@ -900,14 +902,14 @@ void MEDFileMesh::addFamily(const std::string& familyName, int famId) std::map::const_iterator it=_families.find(fname); if(it==_families.end()) { - for(std::map::const_iterator it2=_families.begin();it2!=_families.end();it2++) - if((*it2).second==famId) - { - std::ostringstream oss; - oss << "MEDFileMesh::addFamily : Family \"" << (*it2).first << "\" already exists with specified id : " << famId << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - _families[fname]=famId; + for(std::map::const_iterator it2=_families.begin();it2!=_families.end();it2++) + if((*it2).second==famId) + { + std::ostringstream oss; + oss << "MEDFileMesh::addFamily : Family \"" << (*it2).first << "\" already exists with specified id : " << famId << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + _families[fname]=famId; } else { @@ -1981,6 +1983,40 @@ MEDFileUMesh *MEDFileUMesh::New() return new MEDFileUMesh; } +/*! + * This method loads from file with name \a fileName the mesh called \a mName as New does. The difference is that + * here only a part of cells contained in the file will be loaded. The selection of cell is specified using the two consecutive parameters + * \a types and \a slicPerTyp. This method allows to load from a mesh (typically huge) in a MED file a part of cells of that mesh. + * The part of cells is specified using triplet (start,stop,step) for each geometric type. Only nodes lying on selected cells will be loaded to reduce + * at most the memory consumtion. + * + * \param [in] fileName - the name of the file. + * \param [in] mName - the name of the mesh to be read. + * \param [in] types - the list of the geo types of which some part will be taken. A geometric type in \a types must appear only once at most. + * \param [in] slicPerType - an array of size 3 times larger than \a types that specifies for each type in \a types (in the same order) resp the start, the stop and the step. + * \param [in] dt - the iteration, that is to say the first element of the pair that locates the asked time step. + * \param [in] it - the order, that is to say the second element of the pair that locates the asked time step. + * \param [in] mrs - the request for what to be loaded. + * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this mesh using decrRef() as it is no more needed. + */ +MEDFileUMesh *MEDFileUMesh::LoadPartOf(const std::string& fileName, const std::string& mName, const std::vector& types, const std::vector& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs) +{ + MEDFileUtilities::CheckFileForRead(fileName); + MEDFileUtilities::AutoFid fid(MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY)); + return MEDFileUMesh::LoadPartOf(fid,mName,types,slicPerTyp,dt,it,mrs); +} + +/*! + * Please refer to the other MEDFileUMesh::LoadPartOf method that has the same semantic and the same parameter (excepted the first). + * This method is \b NOT wrapped into python. + */ +MEDFileUMesh *MEDFileUMesh::LoadPartOf(med_idt fid, const std::string& mName, const std::vector& types, const std::vector& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs) +{ + MEDCouplingAutoRefCountObjectPtr ret(MEDFileUMesh::New()); + ret->loadPartUMeshFromFile(fid,mName,types,slicPerTyp,dt,it,mrs); + return ret.retn(); +} + std::size_t MEDFileUMesh::getHeapMemorySizeWithoutChildren() const { std::size_t ret(MEDFileMesh::getHeapMemorySizeWithoutChildren()); @@ -1988,22 +2024,17 @@ std::size_t MEDFileUMesh::getHeapMemorySizeWithoutChildren() const return ret; } -std::vector MEDFileUMesh::getDirectChildren() const +std::vector MEDFileUMesh::getDirectChildrenWithNull() const { - std::vector ret(MEDFileMesh::getDirectChildren()); - if((const DataArrayDouble*)_coords) - ret.push_back((const DataArrayDouble*)_coords); - if((const DataArrayInt *)_fam_coords) - ret.push_back((const DataArrayInt *)_fam_coords); - if((const DataArrayInt *)_num_coords) - ret.push_back((const DataArrayInt *)_num_coords); - if((const DataArrayInt *)_rev_num_coords) - ret.push_back((const DataArrayInt *)_rev_num_coords); - if((const DataArrayAsciiChar *)_name_coords) - ret.push_back((const DataArrayAsciiChar *)_name_coords); + std::vector ret(MEDFileMesh::getDirectChildrenWithNull()); + ret.push_back((const DataArrayDouble*)_coords); + ret.push_back((const DataArrayInt *)_fam_coords); + ret.push_back((const DataArrayInt *)_num_coords); + ret.push_back((const DataArrayInt *)_rev_num_coords); + ret.push_back((const DataArrayAsciiChar *)_name_coords); + ret.push_back((const PartDefinition *)_part_coords); for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++) - if((const MEDFileUMeshSplitL1*) *it) - ret.push_back((const MEDFileUMeshSplitL1*) *it); + ret.push_back((const MEDFileUMeshSplitL1*) *it); return ret; } @@ -2188,27 +2219,60 @@ MEDFileUMesh::MEDFileUMesh() MEDFileUMesh::MEDFileUMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) try - { +{ loadUMeshFromFile(fid,mName,dt,it,mrs); - } +} catch(INTERP_KERNEL::Exception& e) - { +{ throw e; - } +} +/*! + * This method loads only a part of specified cells (given by range of cell ID per geometric type) + * See MEDFileUMesh::LoadPartOf for detailed description. + * + * \sa loadUMeshFromFile + */ +void MEDFileUMesh::loadPartUMeshFromFile(med_idt fid, const std::string& mName, const std::vector& types, const std::vector& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs) +{ + MEDFileUMeshL2 loaderl2; + ParaMEDMEM::MEDCouplingMeshType meshType; + int dummy0,dummy1; + std::string dummy2; + int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2)); + if(meshType!=UNSTRUCTURED) + { + std::ostringstream oss; oss << "loadPartUMeshFromFile : Trying to load as unstructured an existing mesh with name '" << mName << "' !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + loaderl2.loadPart(fid,mid,mName,types,slicPerTyp,dt,it,mrs); + dispatchLoadedPart(fid,loaderl2,mName,mrs); +} + +/*! + * This method loads \b all \b the \b mesh \a mName in the file with \a fid descriptor. + * + * \sa loadPartUMeshFromFile + */ void MEDFileUMesh::loadUMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) { MEDFileUMeshL2 loaderl2; ParaMEDMEM::MEDCouplingMeshType meshType; int dummy0,dummy1; std::string dummy2; - int mid=MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2); + int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2)); if(meshType!=UNSTRUCTURED) { std::ostringstream oss; oss << "Trying to load as unstructured an existing mesh with name '" << mName << "' !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } loaderl2.loadAll(fid,mid,mName,dt,it,mrs); + dispatchLoadedPart(fid,loaderl2,mName,mrs); + +} + +void MEDFileUMesh::dispatchLoadedPart(med_idt fid, const MEDFileUMeshL2& loaderl2, const std::string& mName, MEDFileMeshReadSelector *mrs) +{ int lev=loaderl2.getNumberOfLevels(); _ms.resize(lev); for(int i=0;iisNodeNameFieldReading()) _name_coords=loaderl2.getCoordsName(); + _part_coords=loaderl2.getPartDefOfCoo(); computeRevNum(); } @@ -2692,6 +2757,21 @@ const DataArrayAsciiChar *MEDFileUMesh::getNameFieldAtLevel(int meshDimRelToMaxE return l1->getNameField(); } +/*! + * This method returns for a specified relative level \a meshDimRelToMaxExt the part effectively read (if the instance is the result of the read of a file). + * + * \param [in] meshDimRelToMaxExt - the extended relative level for which the part definition is requested. + * \param [in] gt - The input geometric type for which the part definition is requested. + * \return the part definition owned by \a this. So no need to deallocate the returned instance. + */ +const PartDefinition *MEDFileUMesh::getPartDefAtLevel(int meshDimRelToMaxExt, INTERP_KERNEL::NormalizedCellType gt) const +{ + if(meshDimRelToMaxExt==1) + return _part_coords; + const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt)); + return l1->getPartDef(gt); +} + int MEDFileUMesh::getNumberOfNodes() const { const DataArrayDouble *coo=_coords; @@ -2700,6 +2780,20 @@ int MEDFileUMesh::getNumberOfNodes() const return coo->getNumberOfTuples(); } +bool MEDFileUMesh::hasImplicitPart() const +{ + return false; +} + +int MEDFileUMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const +{ + throw INTERP_KERNEL::Exception("MEDFileUMesh::buildImplicitPartIfAny : unstructured meshes do not have implicit part !"); +} + +void MEDFileUMesh::releaseImplicitPartIfAny() const +{ +} + void MEDFileUMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector& nodesFetched) const { std::size_t sz(st.getNumberOfItems()); @@ -3087,6 +3181,18 @@ DataArrayInt *MEDFileUMesh::extractNumberFieldOnGeoType(INTERP_KERNEL::Normalize return sp->extractNumberFieldOnGeoType(gt); } +/*! + * This method returns for specified geometric type \a gt the relative level to \a this. + * If the relative level is empty an exception will be thrown. + */ +int MEDFileUMesh::getRelativeLevOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const +{ + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt); + int ret((int)cm.getDimension()-getMeshDimension()); + getMeshAtLevSafe(ret);//To test that returned value corresponds to a valid level. + return ret; +} + const MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) const { if(meshDimRelToMaxExt==1) @@ -3103,7 +3209,7 @@ const MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) { - if(meshDimRelToMaxExt==1) + if(meshDimRelToMaxExt==1) throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !"); if(meshDimRelToMaxExt>1) throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !"); @@ -3327,7 +3433,7 @@ bool MEDFileUMesh::unPolyze(std::vector& oldCode, std::vector& newCode bool hasChanged=m->unPolyze(); DataArrayInt *fake=0; MEDCouplingAutoRefCountObjectPtr o2nCellsPart=m->getLevArrPerCellTypes(MEDCouplingUMesh::MEDMEM_ORDER, - MEDCouplingUMesh::MEDMEM_ORDER+MEDCouplingUMesh::N_MEDMEM_ORDER,fake); + MEDCouplingUMesh::MEDMEM_ORDER+MEDCouplingUMesh::N_MEDMEM_ORDER,fake); fake->decrRef(); renumCellsSplited.push_back(o2nCellsPart); memorySaverIfThrow.push_back(o2nCellsPart); if(hasChanged) @@ -3960,21 +4066,21 @@ std::size_t MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren() const return MEDFileMesh::getHeapMemorySizeWithoutChildren(); } -std::vector MEDFileStructuredMesh::getDirectChildren() const -{ - std::vector ret(MEDFileMesh::getDirectChildren()); - if((const DataArrayInt *)_fam_nodes) - ret.push_back((const DataArrayInt *)_fam_nodes); - if((const DataArrayInt *)_num_nodes) - ret.push_back((const DataArrayInt *)_num_nodes); - if((const DataArrayInt *)_fam_cells) - ret.push_back((const DataArrayInt *)_fam_cells); - if((const DataArrayInt *)_num_cells) - ret.push_back((const DataArrayInt *)_num_nodes); - if((const DataArrayInt *)_rev_num_nodes) - ret.push_back((const DataArrayInt *)_rev_num_nodes); - if((const DataArrayInt *)_rev_num_cells) - ret.push_back((const DataArrayInt *)_rev_num_cells); +std::vector MEDFileStructuredMesh::getDirectChildrenWithNull() const +{ + std::vector ret(MEDFileMesh::getDirectChildrenWithNull()); + ret.push_back((const DataArrayInt *)_fam_nodes); + ret.push_back((const DataArrayInt *)_num_nodes); + ret.push_back((const DataArrayAsciiChar *)_names_nodes); + ret.push_back((const DataArrayInt *)_fam_cells); + ret.push_back((const DataArrayInt *)_num_cells); + ret.push_back((const DataArrayAsciiChar *)_names_cells); + ret.push_back((const DataArrayInt *)_fam_faces); + ret.push_back((const DataArrayInt *)_num_faces); + ret.push_back((const DataArrayInt *)_rev_num_nodes); + ret.push_back((const DataArrayAsciiChar *)_names_faces); + ret.push_back((const DataArrayInt *)_rev_num_cells); + ret.push_back((const MEDCoupling1SGTUMesh*)_faces_if_necessary); return ret; } @@ -3991,6 +4097,11 @@ int MEDFileStructuredMesh::getMaxAbsFamilyIdInArrays() const int val=_fam_cells->getMaxValue(tmp); ret=std::max(ret,std::abs(val)); } + if((const DataArrayInt *)_fam_faces) + { + int val=_fam_faces->getMaxValue(tmp); + ret=std::max(ret,std::abs(val)); + } return ret; } @@ -4007,6 +4118,11 @@ int MEDFileStructuredMesh::getMaxFamilyIdInArrays() const int val=_fam_cells->getMaxValue(tmp); ret=std::max(ret,val); } + if((const DataArrayInt *)_fam_faces) + { + int val=_fam_faces->getMaxValue(tmp); + ret=std::max(ret,val); + } return ret; } @@ -4023,6 +4139,11 @@ int MEDFileStructuredMesh::getMinFamilyIdInArrays() const int val=_fam_cells->getMinValue(tmp); ret=std::min(ret,val); } + if((const DataArrayInt *)_fam_faces) + { + int val=_fam_faces->getMinValue(tmp); + ret=std::min(ret,val); + } return ret; } @@ -4068,6 +4189,22 @@ bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::s return false; } } + famc1=_fam_faces; + famc2=otherC->_fam_faces; + if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0)) + { + what="Mismatch of families arr on faces ! One is defined and not other !"; + return false; + } + if(famc1) + { + bool ret=famc1->isEqual(*famc2); + if(!ret) + { + what="Families arr on faces differ !"; + return false; + } + } famc1=_num_nodes; famc2=otherC->_num_nodes; if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0)) @@ -4100,6 +4237,22 @@ bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::s return false; } } + famc1=_num_faces; + famc2=otherC->_num_faces; + if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0)) + { + what="Mismatch of numbering arr on faces ! One is defined and not other !"; + return false; + } + if(famc1) + { + bool ret=famc1->isEqual(*famc2); + if(!ret) + { + what="Numbering arr on faces differ !"; + return false; + } + } const DataArrayAsciiChar *d1=_names_cells; const DataArrayAsciiChar *d2=otherC->_names_cells; if((d1==0 && d2!=0) || (d1!=0 && d2==0)) @@ -4116,6 +4269,22 @@ bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::s return false; } } + d1=_names_faces; + d2=otherC->_names_faces; + if((d1==0 && d2!=0) || (d1!=0 && d2==0)) + { + what="Mismatch of naming arr on faces ! One is defined and not other !"; + return false; + } + if(d1) + { + bool ret=d1->isEqual(*d2); + if(!ret) + { + what="Naming arr on faces differ !"; + return false; + } + } d1=_names_nodes; d2=otherC->_names_nodes; if((d1==0 && d2!=0) || (d1!=0 && d2==0)) @@ -4150,6 +4319,12 @@ void MEDFileStructuredMesh::clearNonDiscrAttributes() const tmp=_num_cells; if(tmp) (const_cast(tmp))->setName(""); + tmp=_fam_faces; + if(tmp) + (const_cast(tmp))->setName(""); + tmp=_num_faces; + if(tmp) + (const_cast(tmp))->setName(""); } /*! @@ -4166,43 +4341,67 @@ void MEDFileStructuredMesh::clearNonDiscrAttributes() const */ DataArrayInt *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector& fams, bool renum) const { - if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1) - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : Only available for levels 0 or 1 !"); - std::vector famIds=getFamiliesIds(fams); - if(meshDimRelToMaxExt==1) - { - if((const DataArrayInt *)_fam_nodes) - { - MEDCouplingAutoRefCountObjectPtr da; - if(!famIds.empty()) - da=_fam_nodes->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size()); - else - da=_fam_nodes->getIdsEqualList(0,0); - if(renum) - return MEDFileUMeshSplitL1::Renumber(_num_nodes,da); - else - return da.retn(); - } - else - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on nodes !"); - } - else - { - if((const DataArrayInt *)_fam_cells) - { - MEDCouplingAutoRefCountObjectPtr da; - if(!famIds.empty()) - da=_fam_cells->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size()); - else - da=_fam_cells->getIdsEqualList(0,0); - if(renum) - return MEDFileUMeshSplitL1::Renumber(_num_cells,da); - else - return da.retn(); - } - else - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on cells !"); - } + std::vector famIds(getFamiliesIds(fams)); + switch(meshDimRelToMaxExt) + { + case 1: + { + if((const DataArrayInt *)_fam_nodes) + { + MEDCouplingAutoRefCountObjectPtr da; + if(!famIds.empty()) + da=_fam_nodes->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size()); + else + da=_fam_nodes->getIdsEqualList(0,0); + if(renum) + return MEDFileUMeshSplitL1::Renumber(_num_nodes,da); + else + return da.retn(); + } + else + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on nodes !"); + break; + } + case 0: + { + if((const DataArrayInt *)_fam_cells) + { + MEDCouplingAutoRefCountObjectPtr da; + if(!famIds.empty()) + da=_fam_cells->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size()); + else + da=_fam_cells->getIdsEqualList(0,0); + if(renum) + return MEDFileUMeshSplitL1::Renumber(_num_cells,da); + else + return da.retn(); + } + else + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on cells !"); + break; + } + case -1: + { + if((const DataArrayInt *)_fam_faces) + { + MEDCouplingAutoRefCountObjectPtr da; + if(!famIds.empty()) + da=_fam_faces->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size()); + else + da=_fam_faces->getIdsEqualList(0,0); + if(renum) + return MEDFileUMeshSplitL1::Renumber(_num_faces,da); + else + return da.retn(); + } + else + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on faces !"); + break; + } + default: + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : input meshDimRelative must be in [0,1,-1] !"); + } + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : unmanaged case !"); } /*! @@ -4212,27 +4411,39 @@ DataArrayInt *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, cons * \param [in] famArr - the array of the family field. * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh. * \throw If \a famArr has an invalid size. - * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1. + * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1 and \a meshDimRelToMaxExt != -1. */ void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr) { - if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1) - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 !"); - const MEDCouplingStructuredMesh *mesh=getStructuredMesh(); + const MEDCouplingStructuredMesh *mesh(getStructuredMesh()); if(!mesh) throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : no structured mesh specified ! Impossible to set family array !"); - if(meshDimRelToMaxExt==0) - { - int nbCells=mesh->getNumberOfCells(); - famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !"); - _fam_cells=famArr; - } - else - { - int nbNodes=mesh->getNumberOfNodes(); - famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !"); - _fam_nodes=famArr; - } + switch(meshDimRelToMaxExt) + { + case 0: + { + int nbCells=mesh->getNumberOfCells(); + famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !"); + _fam_cells=famArr; + break; + } + case 1: + { + int nbNodes=mesh->getNumberOfNodes(); + famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !"); + _fam_nodes=famArr; + break; + } + case -1: + { + int nbCells=mesh->getNumberOfCellsOfSubLevelMesh(); + famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of faces of mesh !"); + _fam_faces=famArr; + break; + } + default: + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : Only available for levels 0 or 1 or -1 !"); + } if(famArr) famArr->incrRef(); } @@ -4247,23 +4458,35 @@ void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayI */ void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr) { - if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1) - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 !"); const MEDCouplingStructuredMesh *mesh=getStructuredMesh(); if(!mesh) throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : no structured mesh specified ! Impossible to set number array !"); - if(meshDimRelToMaxExt==0) - { - int nbCells=mesh->getNumberOfCells(); - renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of cells of mesh !"); - _num_cells=renumArr; - } - else - { - int nbNodes=mesh->getNumberOfNodes(); - renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !"); - _num_nodes=renumArr; - } + switch(meshDimRelToMaxExt) + { + case 0: + { + int nbCells=mesh->getNumberOfCells(); + renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of cells of mesh !"); + _num_cells=renumArr; + break; + } + case 1: + { + int nbNodes=mesh->getNumberOfNodes(); + renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !"); + _num_nodes=renumArr; + break; + } + case -1: + { + int nbCells=mesh->getNumberOfCellsOfSubLevelMesh(); + renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of faces of mesh !"); + _num_faces=renumArr; + break; + } + default: + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 or -1 !"); + } if(renumArr) renumArr->incrRef(); } @@ -4277,23 +4500,34 @@ void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayIn */ void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr) { - if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1) - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : Only available for levels 0 or 1 !"); - const MEDCouplingStructuredMesh *mesh=getStructuredMesh(); + const MEDCouplingStructuredMesh *mesh(getStructuredMesh()); if(!mesh) throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : no structured mesh specified ! Impossible to set names array !"); - if(meshDimRelToMaxExt==0) - { - int nbCells=mesh->getNumberOfCells(); - nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of cells of mesh !"); - _names_cells=nameArr; - } - else - { - int nbNodes=mesh->getNumberOfNodes(); - nameArr->checkNbOfTuplesAndComp(nbNodes,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of nodes of mesh !"); - _names_nodes=nameArr; - } + switch(meshDimRelToMaxExt) + { + case 0: + { + int nbCells=mesh->getNumberOfCells(); + nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of cells of mesh !"); + _names_cells=nameArr; + break; + } + case 1: + { + int nbNodes=mesh->getNumberOfNodes(); + nameArr->checkNbOfTuplesAndComp(nbNodes,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of nodes of mesh !"); + _names_nodes=nameArr; + break; + } + case -1: + { + int nbCells=mesh->getNumberOfCellsOfSubLevelMesh(); + nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of faces of mesh !"); + _names_cells=nameArr; + } + default: + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : Only available for levels 0 or 1 or -1 !"); + } if(nameArr) nameArr->incrRef(); } @@ -4307,12 +4541,17 @@ void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArra */ const DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const { - if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1) - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 !"); - if(meshDimRelToMaxExt==0) - return _fam_cells; - else - return _fam_nodes; + switch(meshDimRelToMaxExt) + { + case 0: + return _fam_cells; + case 1: + return _fam_nodes; + case -1: + return _fam_faces; + default: + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !"); + } } /*! @@ -4324,12 +4563,17 @@ const DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelT */ const DataArrayInt *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const { - if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1) - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 !"); - if(meshDimRelToMaxExt==0) - return _num_cells; - else - return _num_nodes; + switch(meshDimRelToMaxExt) + { + case 0: + return _num_cells; + case 1: + return _num_nodes; + case -1: + return _num_faces; + default: + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 or -1 !"); + } } /*! @@ -4373,12 +4617,17 @@ const DataArrayInt *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimR const DataArrayAsciiChar *MEDFileStructuredMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const { - if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1) - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNameFieldAtLevel : Only available for levels 0 or 1 !"); - if(meshDimRelToMaxExt==0) - return _names_cells; - else - return _names_nodes; + switch(meshDimRelToMaxExt) + { + case 0: + return _names_cells; + case 1: + return _names_nodes; + case -1: + return _names_faces; + default: + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNameFieldAtLevel : Only available for levels 0 or 1 or -1 !"); + } } /*! @@ -4408,11 +4657,13 @@ std::vector MEDFileStructuredMesh::getNonEmptyLevelsExt() const std::vector MEDFileStructuredMesh::getFamArrNonEmptyLevelsExt() const { std::vector ret; - const DataArrayInt *famNodes(_fam_nodes),*famCells(_fam_cells); + const DataArrayInt *famNodes(_fam_nodes),*famCells(_fam_cells),*famFaces(_fam_faces); if(famNodes) ret.push_back(1); if(famCells) ret.push_back(0); + if(famFaces) + ret.push_back(-1); return ret; } @@ -4422,11 +4673,13 @@ std::vector MEDFileStructuredMesh::getFamArrNonEmptyLevelsExt() const std::vector MEDFileStructuredMesh::getNumArrNonEmptyLevelsExt() const { std::vector ret; - const DataArrayInt *numNodes(_num_nodes),*numCells(_num_cells); + const DataArrayInt *numNodes(_num_nodes),*numCells(_num_cells),*numFaces(_num_faces); if(numNodes) ret.push_back(1); if(numCells) ret.push_back(0); + if(numFaces) + ret.push_back(-1); return ret; } @@ -4436,9 +4689,13 @@ std::vector MEDFileStructuredMesh::getNumArrNonEmptyLevelsExt() const std::vector MEDFileStructuredMesh::getNameArrNonEmptyLevelsExt() const { std::vector ret; - const DataArrayAsciiChar *namesCells(_names_cells); + const DataArrayAsciiChar *namesNodes(_names_nodes),*namesCells(_names_cells),*namesFaces(_names_faces); + if(namesNodes) + ret.push_back(1); if(namesCells) ret.push_back(0); + if(namesFaces) + ret.push_back(-1); return ret; } @@ -4459,6 +4716,9 @@ void MEDFileStructuredMesh::changeFamilyIdArr(int oldId, int newId) arr=_fam_cells; if(arr) arr->changeValue(oldId,newId); + arr=_fam_faces; + if(arr) + arr->changeValue(oldId,newId); } void MEDFileStructuredMesh::deepCpyAttributes() @@ -4467,10 +4727,20 @@ void MEDFileStructuredMesh::deepCpyAttributes() _fam_nodes=_fam_nodes->deepCpy(); if((const DataArrayInt*)_num_nodes) _num_nodes=_num_nodes->deepCpy(); + if((const DataArrayAsciiChar*)_names_nodes) + _names_nodes=_names_nodes->deepCpy(); if((const DataArrayInt*)_fam_cells) _fam_cells=_fam_cells->deepCpy(); if((const DataArrayInt*)_num_cells) _num_cells=_num_cells->deepCpy(); + if((const DataArrayAsciiChar*)_names_cells) + _names_cells=_names_cells->deepCpy(); + if((const DataArrayInt*)_fam_faces) + _fam_faces=_fam_faces->deepCpy(); + if((const DataArrayInt*)_num_faces) + _num_faces=_num_faces->deepCpy(); + if((const DataArrayAsciiChar*)_names_faces) + _names_faces=_names_faces->deepCpy(); if((const DataArrayInt*)_rev_num_nodes) _rev_num_nodes=_rev_num_nodes->deepCpy(); if((const DataArrayInt*)_rev_num_cells) @@ -4486,7 +4756,7 @@ void MEDFileStructuredMesh::deepCpyAttributes() /*! * Returns a pointer to MEDCouplingStructuredMesh held by \a this. - * \param [in] meshDimRelToMax - it must be \c 0. + * \param [in] meshDimRelToMax - it must be \c 0 or \c -1. * \param [in] renum - it must be \c false. * \return MEDCouplingMesh * - a pointer to MEDCouplingMesh that the caller is to * delete using decrRef() as it is no more needed. @@ -4495,12 +4765,28 @@ MEDCouplingMesh *MEDFileStructuredMesh::getGenMeshAtLevel(int meshDimRelToMax, b { if(renum) throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support renumbering ! To do it perform request of renum array directly !"); - if(meshDimRelToMax!=0) - throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support multi level for mesh 0 expected as input !"); - const MEDCouplingStructuredMesh *m=getStructuredMesh(); - if(m) - m->incrRef(); - return const_cast(m); + const MEDCouplingStructuredMesh *m(getStructuredMesh()); + switch(meshDimRelToMax) + { + case 0: + { + if(m) + m->incrRef(); + return const_cast(m); + } + case -1: + { + if(!m) + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGenMeshAtLevel : level -1 requested must be non empty to be able to compute unstructured sub mesh !"); + buildMinusOneImplicitPartIfNeeded(); + MEDCouplingMesh *ret(_faces_if_necessary); + if(ret) + ret->incrRef(); + return ret; + } + default: + throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support multi level for mesh 0 expected as input !"); + } } /*! @@ -4511,15 +4797,20 @@ MEDCouplingMesh *MEDFileStructuredMesh::getGenMeshAtLevel(int meshDimRelToMax, b */ int MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const { - if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1) - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : Only available for levels 0 or 1 !"); - const MEDCouplingStructuredMesh *cmesh=getStructuredMesh(); + const MEDCouplingStructuredMesh *cmesh(getStructuredMesh()); if(!cmesh) throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : No structured mesh set !"); - if(meshDimRelToMaxExt==0) - return cmesh->getNumberOfCells(); - else - return cmesh->getNumberOfNodes(); + switch(meshDimRelToMaxExt) + { + case 0: + return cmesh->getNumberOfCells(); + case 1: + return cmesh->getNumberOfNodes(); + case -1: + return cmesh->getNumberOfCellsOfSubLevelMesh(); + default: + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : Only available for levels 0 or 1 or -1 !"); + } } int MEDFileStructuredMesh::getNumberOfNodes() const @@ -4530,13 +4821,88 @@ int MEDFileStructuredMesh::getNumberOfNodes() const return cmesh->getNumberOfNodes(); } +bool MEDFileStructuredMesh::hasImplicitPart() const +{ + return true; +} + +/*! + * \sa MEDFileStructuredMesh::getImplicitFaceMesh + */ +int MEDFileStructuredMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const +{ + static const char MSG[]="MEDFileStructuredMesh::buildImplicitPartIfAny : the given geo type is not manageable by a structured mesh !"; + const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary); + if(!zeFaceMesh) + { + const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))); + if(cm.getReverseExtrudedType()!=gt) + throw INTERP_KERNEL::Exception(MSG); + buildImplicitPart(); + return getStructuredMesh()->getNumberOfCellsOfSubLevelMesh(); + } + else + { + if(gt!=zeFaceMesh->getCellModelEnum()) + throw INTERP_KERNEL::Exception(MSG); + return zeFaceMesh->getNumberOfCells(); + } +} + +void MEDFileStructuredMesh::buildMinusOneImplicitPartIfNeeded() const +{ + const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary); + if(!zeFaceMesh) + buildImplicitPart(); +} + +void MEDFileStructuredMesh::buildImplicitPart() const +{ + const MEDCouplingStructuredMesh *mcmesh(getStructuredMesh()); + if(!mcmesh) + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::buildImplicitPart : Unable to build the implicit part of structured mesh because no structured mesh at level 0 defined !"); + _faces_if_necessary=mcmesh->build1SGTSubLevelMesh(); +} + +void MEDFileStructuredMesh::releaseImplicitPartIfAny() const +{ + _faces_if_necessary=0; +} + +/*! + * Retrieves the internal pointer (no decrRef requested) of the implicit face mesh if any. + * To force to build it you can invoke MEDFileStructuredMesh::buildImplicitPartIfAny method. + * + * \sa MEDFileStructuredMesh::buildImplicitPartIfAny + */ +MEDCoupling1SGTUMesh *MEDFileStructuredMesh::getImplicitFaceMesh() const +{ + return _faces_if_necessary; +} + std::vector MEDFileStructuredMesh::getGeoTypesAtLevel(int meshDimRelToMax) const { - if(meshDimRelToMax!=0) - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only one level available for structured meshes ! Input 0 is mandatory !"); const MEDCouplingStructuredMesh *cmesh(getStructuredMesh()); - std::vector ret(1,cmesh->getTypeOfCell(0)); - return ret; + if(!cmesh) + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : No structured mesh set !"); + switch(meshDimRelToMax) + { + case 0: + { + std::vector ret(1,cmesh->getTypeOfCell(0)); + return ret; + } + case -1: + { + int mdim(cmesh->getMeshDimension()); + if(mdim<1) + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only one level available for structured meshes ! Input 0 is mandatory or 0D mesh !"); + std::vector ret(1,MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(mdim-1)); + return ret; + } + default: + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only 2 levels available at most : 0 and -1 !"); + } } void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector& nodesFetched) const @@ -4569,25 +4935,47 @@ void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem med_geometry_type MEDFileStructuredMesh::GetGeoTypeFromMeshDim(int meshDim) { - med_geometry_type geoTypeReq=MED_NONE; - switch(meshDim) + INTERP_KERNEL::NormalizedCellType ct(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(meshDim)); + return typmai3[ct]; +} + +void MEDFileStructuredMesh::LoadStrMeshDAFromFile(med_idt fid, int meshDim, int dt, int it, const std::string& mName, MEDFileMeshReadSelector *mrs, + MEDCouplingAutoRefCountObjectPtr& famCells, MEDCouplingAutoRefCountObjectPtr& numCells, MEDCouplingAutoRefCountObjectPtr& namesCells) +{ + med_bool chgt=MED_FALSE,trsf=MED_FALSE; + med_geometry_type geoTypeReq=MEDFileStructuredMesh::GetGeoTypeFromMeshDim(meshDim); + int nbOfElt(0); + nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf); + if(nbOfElt>0) { - case 3: - geoTypeReq=MED_HEXA8; - break; - case 2: - geoTypeReq=MED_QUAD4; - break; - case 1: - geoTypeReq=MED_SEG2; - break; - case 0: - geoTypeReq=MED_POINT1; - break; - default: - throw INTERP_KERNEL::Exception("Invalid meshdim detected for structured mesh ! Must be in (1,2,3) !"); + if(!mrs || mrs->isCellFamilyFieldReading()) + { + famCells=DataArrayInt::New(); + famCells->alloc(nbOfElt,1); + MEDmeshEntityFamilyNumberRd(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,famCells->getPointer()); + } + } + nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NUMBER,MED_NODAL,&chgt,&trsf); + if(nbOfElt>0) + { + if(!mrs || mrs->isCellNumFieldReading()) + { + numCells=DataArrayInt::New(); + numCells->alloc(nbOfElt,1); + MEDmeshEntityNumberRd(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,numCells->getPointer()); + } + } + nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NAME,MED_NODAL,&chgt,&trsf); + if(nbOfElt>0) + { + if(!mrs || mrs->isCellNameFieldReading()) + { + namesCells=DataArrayAsciiChar::New(); + namesCells->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end + MEDmeshEntityNameRd(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,namesCells->getPointer()); + namesCells->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end + } } - return geoTypeReq; } void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) @@ -4607,9 +4995,11 @@ void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt if(!mrs || mrs->isNodeFamilyFieldReading()) { int nbNodes(getNumberOfNodes()); + if(nbOfElt>nbNodes) + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::loadStrMeshFromFile : invalid size of family node array regarding number of nodes in this ! File seems to be corrupted !"); _fam_nodes=DataArrayInt::New(); _fam_nodes->alloc(nbNodes,1);//yes nbNodes and not nbOfElt see next line. - if(nbNodes!=nbOfElt)//yes it appends some times... It explains surely the mdump implementation. Bug revealed by PARAVIS EDF #2475 on structured.med file where only 12 first nodes are !=0 so nbOfElt=12 and nbOfNodes=378... + if(nbNodes>nbOfElt)//yes it appends some times... It explains surely the mdump implementation. Bug revealed by PARAVIS EDF #2475 on structured.med file where only 12 first nodes are !=0 so nbOfElt=12 and nbOfNodes=378... _fam_nodes->fillWithZero(); MEDmeshEntityFamilyNumberRd(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_fam_nodes->getPointer()); } @@ -4624,39 +5014,6 @@ void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt MEDmeshEntityNumberRd(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_num_nodes->getPointer()); } } - int meshDim=getStructuredMesh()->getMeshDimension(); - med_geometry_type geoTypeReq=GetGeoTypeFromMeshDim(meshDim); - nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf); - if(nbOfElt>0) - { - if(!mrs || mrs->isCellFamilyFieldReading()) - { - _fam_cells=DataArrayInt::New(); - _fam_cells->alloc(nbOfElt,1); - MEDmeshEntityFamilyNumberRd(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,_fam_cells->getPointer()); - } - } - nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NUMBER,MED_NODAL,&chgt,&trsf); - if(nbOfElt>0) - { - if(!mrs || mrs->isCellNumFieldReading()) - { - _num_cells=DataArrayInt::New(); - _num_cells->alloc(nbOfElt,1); - MEDmeshEntityNumberRd(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,_num_cells->getPointer()); - } - } - nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NAME,MED_NODAL,&chgt,&trsf); - if(nbOfElt>0) - { - if(!mrs || mrs->isCellNameFieldReading()) - { - _names_cells=DataArrayAsciiChar::New(); - _names_cells->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end - MEDmeshEntityNameRd(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,_names_cells->getPointer()); - _names_cells->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end - } - } nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NAME,MED_NODAL,&chgt,&trsf); if(nbOfElt>0) { @@ -4668,19 +5025,27 @@ void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt _names_nodes->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end } } + int meshDim(getStructuredMesh()->getMeshDimension()); + LoadStrMeshDAFromFile(fid,meshDim,dt,it,mName,mrs,_fam_cells,_num_cells,_names_cells); + if(meshDim>=1) + LoadStrMeshDAFromFile(fid,meshDim-1,dt,it,mName,mrs,_fam_faces,_num_faces,_names_faces); } void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const std::string& maa) const { - int meshDim=getStructuredMesh()->getMeshDimension(); - med_geometry_type geoTypeReq=GetGeoTypeFromMeshDim(meshDim); + int meshDim(getStructuredMesh()->getMeshDimension()); + med_geometry_type geoTypeReq(GetGeoTypeFromMeshDim(meshDim)),geoTypeReq2(GetGeoTypeFromMeshDim(meshDim-1)); // if((const DataArrayInt *)_fam_cells) MEDmeshEntityFamilyNumberWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_fam_cells->getNumberOfTuples(),_fam_cells->getConstPointer()); + if((const DataArrayInt *)_fam_faces) + MEDmeshEntityFamilyNumberWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_fam_faces->getNumberOfTuples(),_fam_faces->getConstPointer()); if((const DataArrayInt *)_fam_nodes) MEDmeshEntityFamilyNumberWr(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_fam_nodes->getNumberOfTuples(),_fam_nodes->getConstPointer()); if((const DataArrayInt *)_num_cells) MEDmeshEntityNumberWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_num_cells->getNumberOfTuples(),_num_cells->getConstPointer()); + if((const DataArrayInt *)_num_faces) + MEDmeshEntityNumberWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_num_faces->getNumberOfTuples(),_num_faces->getConstPointer()); if((const DataArrayInt *)_num_nodes) MEDmeshEntityNumberWr(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_num_nodes->getNumberOfTuples(),_num_nodes->getConstPointer()); if((const DataArrayAsciiChar *)_names_cells) @@ -4693,6 +5058,16 @@ void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const std::string& ma } MEDmeshEntityNameWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_names_cells->getNumberOfTuples(),_names_cells->getConstPointer()); } + if((const DataArrayAsciiChar *)_names_faces) + { + if(_names_faces->getNumberOfComponents()!=MED_SNAME_SIZE) + { + std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on faces with number of components set to " << MED_SNAME_SIZE; + oss << " ! The array has " << _names_faces->getNumberOfComponents() << " components !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + MEDmeshEntityNameWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_names_faces->getNumberOfTuples(),_names_faces->getConstPointer()); + } if((const DataArrayAsciiChar *)_names_nodes) { if(_names_nodes->getNumberOfComponents()!=MED_SNAME_SIZE) @@ -4770,11 +5145,10 @@ std::size_t MEDFileCMesh::getHeapMemorySizeWithoutChildren() const return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren(); } -std::vector MEDFileCMesh::getDirectChildren() const +std::vector MEDFileCMesh::getDirectChildrenWithNull() const { - std::vector ret(MEDFileStructuredMesh::getDirectChildren()); - if((const MEDCouplingCMesh *)_cmesh) - ret.push_back((const MEDCouplingCMesh *)_cmesh); + std::vector ret(MEDFileStructuredMesh::getDirectChildrenWithNull()); + ret.push_back((const MEDCouplingCMesh *)_cmesh); return ret; } @@ -4893,13 +5267,13 @@ MEDFileCMesh::MEDFileCMesh() MEDFileCMesh::MEDFileCMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) try - { +{ loadCMeshFromFile(fid,mName,dt,it,mrs); - } +} catch(INTERP_KERNEL::Exception& e) - { +{ throw e; - } +} void MEDFileCMesh::loadCMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) { @@ -5027,11 +5401,10 @@ std::size_t MEDFileCurveLinearMesh::getHeapMemorySizeWithoutChildren() const return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren(); } -std::vector MEDFileCurveLinearMesh::getDirectChildren() const +std::vector MEDFileCurveLinearMesh::getDirectChildrenWithNull() const { - std::vector ret(MEDFileStructuredMesh::getDirectChildren()); - if((const MEDCouplingCurveLinearMesh *)_clmesh) - ret.push_back((const MEDCouplingCurveLinearMesh *)_clmesh); + std::vector ret(MEDFileStructuredMesh::getDirectChildrenWithNull()); + ret.push_back((const MEDCouplingCurveLinearMesh *)_clmesh); return ret; } @@ -5146,13 +5519,13 @@ MEDFileCurveLinearMesh::MEDFileCurveLinearMesh() MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) try - { +{ loadCLMeshFromFile(fid,mName,dt,it,mrs); - } +} catch(INTERP_KERNEL::Exception& e) - { +{ throw e; - } +} void MEDFileCurveLinearMesh::writeLL(med_idt fid) const { @@ -5182,7 +5555,7 @@ void MEDFileCurveLinearMesh::writeLL(med_idt fid) const MEDmeshGridTypeWr(fid,maa,MED_CURVILINEAR_GRID); std::vector nodeGridSt=_clmesh->getNodeGridStructure(); MEDmeshGridStructWr(fid,maa,_iteration,_order,_time,&nodeGridSt[0]); - + MEDmeshNodeCoordinateWr(fid,maa,_iteration,_order,_time,MED_FULL_INTERLACE,coords->getNumberOfTuples(),coords->begin()); // std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE)); @@ -5240,15 +5613,11 @@ std::size_t MEDFileMeshMultiTS::getHeapMemorySizeWithoutChildren() const return _mesh_one_ts.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr); } -std::vector MEDFileMeshMultiTS::getDirectChildren() const +std::vector MEDFileMeshMultiTS::getDirectChildrenWithNull() const { std::vector ret; for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++) - { - const MEDFileMesh *cur(*it); - if(cur) - ret.push_back(cur); - } + ret.push_back((const MEDFileMesh *)*it); return ret; } @@ -5326,13 +5695,13 @@ MEDFileMeshMultiTS::MEDFileMeshMultiTS() MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName) try - { +{ std::vector ms=MEDLoader::GetMeshNames(fileName); if(ms.empty()) - { - std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } + { + std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } MEDFileUtilities::CheckFileForRead(fileName); MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); int dt,it; @@ -5340,21 +5709,21 @@ try std::string dummy2; MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2); loadFromFile(fileName,ms.front()); - } +} catch(INTERP_KERNEL::Exception& e) - { +{ throw e; - } +} MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName, const std::string& mName) try - { +{ loadFromFile(fileName,mName); - } +} catch(INTERP_KERNEL::Exception& e) - { +{ throw e; - } +} MEDFileMeshes *MEDFileMeshes::New() { @@ -5396,6 +5765,7 @@ MEDFileMeshesIterator *MEDFileMeshes::iterator() return new MEDFileMeshesIterator(this); } +/** Return a borrowed reference (caller is not responsible) */ MEDFileMesh *MEDFileMeshes::getMeshAtPos(int i) const { if(i<0 || i>=(int)_meshes.size()) @@ -5406,6 +5776,7 @@ MEDFileMesh *MEDFileMeshes::getMeshAtPos(int i) const return _meshes[i]->getOneTimeStep(); } +/** Return a borrowed reference (caller is not responsible) */ MEDFileMesh *MEDFileMeshes::getMeshWithName(const std::string& mname) const { std::vector ms=getMeshesNames(); @@ -5501,12 +5872,12 @@ MEDFileMeshes::MEDFileMeshes() MEDFileMeshes::MEDFileMeshes(const std::string& fileName) try - { +{ loadFromFile(fileName); - } +} catch(INTERP_KERNEL::Exception& /*e*/) - { - } +{ +} MEDFileMeshes *MEDFileMeshes::deepCpy() const { @@ -5525,15 +5896,11 @@ std::size_t MEDFileMeshes::getHeapMemorySizeWithoutChildren() const return _meshes.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr)); } -std::vector MEDFileMeshes::getDirectChildren() const +std::vector MEDFileMeshes::getDirectChildrenWithNull() const { std::vector ret; for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_meshes.begin();it!=_meshes.end();it++) - { - const MEDFileMeshMultiTS *cur(*it); - if(cur) - ret.push_back(cur); - } + ret.push_back((const MEDFileMeshMultiTS *)*it); return ret; }