X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FMEDLoader%2FMEDFileMesh.cxx;h=27c1836a55fb40a3fda4eb50e375eaa6272e76cf;hb=66bc12813f1bc01afb950cbbc11fd94f8f2009ed;hp=9c7698caf9fa2411a8792decd3037be4adc5cf42;hpb=94566ff4f9e37314014461f7773330f989c9ca09;p=tools%2Fmedcoupling.git diff --git a/src/MEDLoader/MEDFileMesh.cxx b/src/MEDLoader/MEDFileMesh.cxx index 9c7698caf..27c1836a5 100644 --- a/src/MEDLoader/MEDFileMesh.cxx +++ b/src/MEDLoader/MEDFileMesh.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2015 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 @@ -19,27 +19,34 @@ // Author : Anthony Geay (CEA/DEN) #include "MEDFileMesh.hxx" -#include "MEDFileUtilities.hxx" #include "MEDFileFieldOverView.hxx" #include "MEDFileField.hxx" #include "MEDLoader.hxx" +#include "MEDLoaderNS.hxx" #include "MEDFileSafeCaller.txx" #include "MEDLoaderBase.hxx" #include "MEDCouplingUMesh.hxx" +#include "MEDCouplingMappedExtrudedMesh.hxx" +#include "MEDCouplingMemArray.txx" #include "InterpKernelAutoPtr.hxx" #include #include -extern med_geometry_type typmai3[34]; +// From MEDLOader.cxx TU +extern med_geometry_type typmai[MED_N_CELL_FIXED_GEO]; +extern INTERP_KERNEL::NormalizedCellType typmai2[MED_N_CELL_FIXED_GEO]; +extern med_geometry_type typmai3[INTERP_KERNEL::NORM_MAXTYPE]; -using namespace ParaMEDMEM; +using namespace MEDCoupling; const char MEDFileMesh::DFT_FAM_NAME[]="FAMILLE_ZERO"; -MEDFileMesh::MEDFileMesh():_order(-1),_iteration(-1),_time(0.),_univ_wr_status(true) +const char MEDFileUMesh::SPE_FAM_STR_EXTRUDED_MESH[]="HIDDEN_FAM_EXT_MESH@"; + +MEDFileMesh::MEDFileMesh():_order(-1),_iteration(-1),_time(0.),_univ_wr_status(true),_axis_type(AX_CART) { } @@ -52,14 +59,16 @@ std::size_t MEDFileMesh::getHeapMemorySizeWithoutChildren() const for(std::vector::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++) ret+=(*it2).capacity(); } - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) - ret+=(*it).first.capacity()+sizeof(int); + for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) + ret+=(*it).first.capacity()+sizeof(mcIdType); return ret; } std::vector MEDFileMesh::getDirectChildrenWithNull() const { - return std::vector(); + std::vector ret(1); + ret[0]=(const MEDFileEquivalences *)_equiv; + return ret; } /*! @@ -74,40 +83,40 @@ std::vector MEDFileMesh::getDirectChildrenWithNull() co */ MEDFileMesh *MEDFileMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs) { - std::vector ms=MEDLoader::GetMeshNames(fileName); + MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName)); + return New(fid,mrs); +} + +MEDFileMesh *MEDFileMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs) +{ + std::vector ms(MEDLoaderNS::getMeshNamesFid(fid)); if(ms.empty()) { - std::ostringstream oss; oss << "MEDFileMesh::New : no meshes in file \"" << fileName << "\" !"; + std::ostringstream oss; oss << "MEDFileMesh::New : no meshes in file \"" << FileNameFromFID(fid) << "\" !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } - MEDFileUtilities::CheckFileForRead(fileName); - ParaMEDMEM::MEDCouplingMeshType meshType; - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); + MEDCoupling::MEDCouplingMeshType meshType; int dt,it; std::string dummy2; - MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2); + MEDCoupling::MEDCouplingAxisType dummy3; + MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2); + MCAuto ret; switch(meshType) { case UNSTRUCTURED: { - MEDCouplingAutoRefCountObjectPtr ret=MEDFileUMesh::New(); - ret->loadUMeshFromFile(fid,ms.front(),dt,it,mrs); - ret->loadJointsFromFile(fid); - return (MEDFileUMesh *)ret.retn(); + ret=MEDFileUMesh::New(); + break; } case CARTESIAN: { - MEDCouplingAutoRefCountObjectPtr ret=MEDFileCMesh::New(); - ret->loadCMeshFromFile(fid,ms.front(),dt,it,mrs); - ret->loadJointsFromFile(fid); - return (MEDFileCMesh *)ret.retn(); + ret=MEDFileCMesh::New(); + break; } case CURVE_LINEAR: { - MEDCouplingAutoRefCountObjectPtr ret=MEDFileCurveLinearMesh::New(); - ret->loadCLMeshFromFile(fid,ms.front(),dt,it,mrs); - ret->loadJointsFromFile(fid); - return (MEDFileCurveLinearMesh *)ret.retn(); + ret=MEDFileCurveLinearMesh::New(); + break; } default: { @@ -115,6 +124,8 @@ MEDFileMesh *MEDFileMesh::New(const std::string& fileName, MEDFileMeshReadSelect throw INTERP_KERNEL::Exception(oss.str().c_str()); } } + ret->loadLLWithAdditionalItems(fid,ms.front(),dt,it,mrs); + return ret.retn(); } /*! @@ -136,34 +147,34 @@ MEDFileMesh *MEDFileMesh::New(const std::string& fileName, MEDFileMeshReadSelect */ MEDFileMesh *MEDFileMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs, MEDFileJoints* joints) { - MEDFileUtilities::CheckFileForRead(fileName); - ParaMEDMEM::MEDCouplingMeshType meshType; - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); + MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName)); + return New(fid,mName,dt,it,mrs,joints); +} + +MEDFileMesh *MEDFileMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs, MEDFileJoints* joints) +{ + MEDCoupling::MEDCouplingMeshType meshType; int dummy0,dummy1; std::string dummy2; - MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2); + MEDCoupling::MEDCouplingAxisType dummy3; + MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy3,dummy0,dummy1,dummy2); + MCAuto ret; switch(meshType) { case UNSTRUCTURED: { - MEDCouplingAutoRefCountObjectPtr ret=MEDFileUMesh::New(); - ret->loadUMeshFromFile(fid,mName,dt,it,mrs); - ret->loadJointsFromFile(fid,joints); - return (MEDFileUMesh *)ret.retn(); + ret=MEDFileUMesh::New(); + break; } case CARTESIAN: { - MEDCouplingAutoRefCountObjectPtr ret=MEDFileCMesh::New(); - ret->loadCMeshFromFile(fid,mName,dt,it,mrs); - ret->loadJointsFromFile(fid,joints); - return (MEDFileCMesh *)ret.retn(); + ret=MEDFileCMesh::New(); + break; } case CURVE_LINEAR: { - MEDCouplingAutoRefCountObjectPtr ret=MEDFileCurveLinearMesh::New(); - ret->loadCLMeshFromFile(fid,mName,dt,it,mrs); - ret->loadJointsFromFile(fid,joints); - return (MEDFileCurveLinearMesh *)ret.retn(); + ret=MEDFileCurveLinearMesh::New(); + break; } default: { @@ -171,6 +182,8 @@ MEDFileMesh *MEDFileMesh::New(const std::string& fileName, const std::string& mN throw INTERP_KERNEL::Exception(oss.str().c_str()); } } + ret->loadLLWithAdditionalItems(fid,mName,dt,it,mrs); + return ret.retn(); } /*! @@ -180,32 +193,17 @@ MEDFileMesh *MEDFileMesh::New(const std::string& fileName, const std::string& mN * \throw If the file is open for reading only. * \throw If the writing mode == 1 and the same data is present in an existing file. */ -void MEDFileMesh::write(med_idt fid) const +void MEDFileMesh::writeLL(med_idt fid) const { if(!existsFamily(0)) const_cast(this)->addFamily(DFT_FAM_NAME,0); if(_name.empty()) throw INTERP_KERNEL::Exception("MEDFileMesh : name is empty. MED file ask for a NON EMPTY name !"); - writeLL(fid); -} - -/*! - * Writes \a this mesh into a MED file specified by its name. - * \param [in] fileName - the MED file name. - * \param [in] mode - the writing mode. For more on \a mode, see \ref AdvMEDLoaderBasics. - * - 2 - erase; an existing file is removed. - * - 1 - append; same data should not be present in an existing file. - * - 0 - overwrite; same data present in an existing file is overwritten. - * \throw If the mesh name is not set. - * \throw If \a mode == 1 and the same data is present in an existing file. - */ -void MEDFileMesh::write(const std::string& fileName, int mode) const -{ - med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod); - std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\""; - MEDFileUtilities::CheckMEDCode(fid,fid,oss.str()); - write(fid); + writeMeshLL(fid); + writeJoints(fid); + const MEDFileEquivalences *eqs(_equiv); + if(eqs) + eqs->writeLL(fid); } /*! @@ -252,6 +250,8 @@ bool MEDFileMesh::isEqual(const MEDFileMesh *other, double eps, std::string& wha return false; if(!areFamsEqual(other,what)) return false; + if(!areEquivalencesEqual(other,what)) + return false; return true; } @@ -381,7 +381,7 @@ std::vector MEDFileMesh::getFamiliesOnGroups(const std::vector - sequence of ids of the families. * \throw If the name of a nonexistent group is specified. */ -std::vector MEDFileMesh::getFamiliesIdsOnGroup(const std::string& name) const +std::vector MEDFileMesh::getFamiliesIdsOnGroup(const std::string& name) const { std::string oname(name); std::map >::const_iterator it=_groups.find(oname); @@ -408,7 +408,7 @@ void MEDFileMesh::setFamiliesOnGroup(const std::string& name, const std::vector< _groups[oname]=fams; for(std::vector::const_iterator it1=fams.begin();it1!=fams.end();it1++) { - std::map::iterator it2=_families.find(*it1); + std::map::iterator it2=_families.find(*it1); if(it2==_families.end()) _families[*it1]=0; } @@ -422,12 +422,12 @@ void MEDFileMesh::setFamiliesOnGroup(const std::string& name, const std::vector< * \param [in] famIds - a sequence of ids of families constituting the group. * \throw If a family name is not found by its id. */ -void MEDFileMesh::setFamiliesIdsOnGroup(const std::string& name, const std::vector& famIds) +void MEDFileMesh::setFamiliesIdsOnGroup(const std::string& name, const std::vector& famIds) { std::string oname(name); std::vector fams(famIds.size()); int i=0; - for(std::vector::const_iterator it1=famIds.begin();it1!=famIds.end();it1++,i++) + for(std::vector::const_iterator it1=famIds.begin();it1!=famIds.end();it1++,i++) { std::string name2=getFamilyNameGivenId(*it1); fams[i]=name2; @@ -464,7 +464,7 @@ std::vector MEDFileMesh::getGroupsOnFamily(const std::string& name) void MEDFileMesh::setGroupsOnFamily(const std::string& famName, const std::vector& grps) { std::string fName(famName); - const std::map::const_iterator it=_families.find(fName); + const std::map::const_iterator it=_families.find(fName); if(it==_families.end()) { std::vector fams=getFamiliesNames(); @@ -506,11 +506,117 @@ std::vector MEDFileMesh::getFamiliesNames() const { std::vector ret(_families.size()); int i=0; - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++,i++) + for(std::map::const_iterator it=_families.begin();it!=_families.end();it++,i++) ret[i]=(*it).first; return ret; } +/*! + * Returns names of all families of \a this mesh but like they would be in file. + * This method is here only for MED file families gurus. If you are a kind user forget this method :-) + * This method is only useful for aggressive users that want to have in their file a same family lying both on cells and on nodes. This is not a good idea for lisibility ! + * For your information internally in memory such families are renamed to have a nicer API. + */ +std::vector MEDFileMesh::getFamiliesNamesWithFilePointOfView() const +{ + std::vector ret(getFamiliesNames()); + MEDFileMeshL2::RenameFamiliesFromMemToFile(ret); + return ret; +} + +/*! + * Returns names of groups that partly or fully appear on the level \a meshDimRelToMaxExt. + * \param [in] meshDimRelToMaxExt - a relative dimension of interest. + * \return std::vector - a sequence of group names at \a meshDimRelToMaxExt + * level. + */ +std::vector MEDFileMesh::getGroupsOnSpecifiedLev(int meshDimRelToMaxExt) const +{ + std::vector ret; + std::vector allGrps(getGroupsNames()); + for(std::vector::const_iterator it=allGrps.begin();it!=allGrps.end();it++) + { + std::vector levs(getGrpNonEmptyLevelsExt((*it))); + if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)!=levs.end()) + ret.push_back(*it); + } + return ret; +} + +/*! + * Returns all relative mesh levels (including nodes) where a given group is defined. + * \param [in] grp - the name of the group of interest. + * \return std::vector - a sequence of the relative dimensions. + */ +std::vector MEDFileMesh::getGrpNonEmptyLevelsExt(const std::string& grp) const +{ + std::vector fams(getFamiliesOnGroup(grp)); + return getFamsNonEmptyLevelsExt(fams); +} + +/*! + * Returns all relative mesh levels (**excluding nodes**) where given groups are defined. + * To include nodes, call getGrpsNonEmptyLevelsExt() method. + * \param [in] grps - a sequence of names of the groups of interest. + * \return std::vector - a sequence of the relative dimensions. + */ +std::vector MEDFileMesh::getGrpsNonEmptyLevels(const std::vector& grps) const +{ + std::vector fams(getFamiliesOnGroups(grps)); + return getFamsNonEmptyLevels(fams); +} + +/*! + * Returns all relative mesh levels (including nodes) where given groups are defined. + * \param [in] grps - a sequence of names of the groups of interest. + * \return std::vector - a sequence of the relative dimensions. + */ +std::vector MEDFileMesh::getGrpsNonEmptyLevelsExt(const std::vector& grps) const +{ + std::vector fams(getFamiliesOnGroups(grps)); + return getFamsNonEmptyLevelsExt(fams); +} + +/*! + * Returns all relative mesh levels (**excluding nodes**) where a given group is defined. + * To include nodes, call getGrpNonEmptyLevelsExt() method. + * \param [in] grp - the name of the group of interest. + * \return std::vector - a sequence of the relative dimensions. + */ +std::vector MEDFileMesh::getGrpNonEmptyLevels(const std::string& grp) const +{ + std::vector fams(getFamiliesOnGroup(grp)); + return getFamsNonEmptyLevels(fams); +} + +/*! + * Returns all relative mesh levels (**excluding nodes**) where a given family is defined. + * To include nodes, call getFamNonEmptyLevelsExt() method. + * \param [in] fam - the name of the family of interest. + * \return std::vector - a sequence of the relative dimensions. + */ +std::vector MEDFileMesh::getFamNonEmptyLevels(const std::string& fam) const +{ + std::vector fams(1,std::string(fam)); + return getFamsNonEmptyLevels(fams); +} + +/*! + * Returns all relative mesh levels (including nodes) where a given family is defined. + * \param [in] fam - the name of the family of interest. + * \return std::vector - a sequence of the relative dimensions. + */ +std::vector MEDFileMesh::getFamNonEmptyLevelsExt(const std::string& fam) const +{ + std::vector fams(1,std::string(fam)); + return getFamsNonEmptyLevelsExt(fams); +} + +std::string MEDFileMesh::GetMagicFamilyStr() +{ + return std::string(MEDFileMeshL2::ZE_SEP_FOR_FAMILY_KILLERS); +} + /*! * Changes a name of every family, included in one group only, to be same as the group name. * \throw If there are families with equal names in \a this mesh. @@ -518,8 +624,8 @@ std::vector MEDFileMesh::getFamiliesNames() const void MEDFileMesh::assignFamilyNameWithGroupName() { std::map > groups(_groups); - std::map newFams; - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) + std::map newFams; + for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) { std::vector grps=getGroupsOnFamily((*it).first); if(grps.size()==1 && groups[grps[0]].size()==1) @@ -569,6 +675,35 @@ std::vector MEDFileMesh::removeEmptyGroups() return ret; } +void MEDFileMesh::removeGroupAtLevel(int meshDimRelToMaxExt, const std::string& name) +{ + std::map >::iterator it(_groups.find(name)); + std::vector grps(getGroupsNames()); + if(it==_groups.end()) + { + std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :"; + std::copy(grps.begin(),grps.end(),std::ostream_iterator(oss," ")); + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + const std::vector &famsOnGrp((*it).second); + std::vector famIds(getFamiliesIdsOnGroup(name)); + const DataArrayIdType *famArr(getFamilyFieldAtLevel(meshDimRelToMaxExt)); + if(!famArr) + return ; + MCAuto vals(famArr->getDifferentValues()); + MCAuto famIds2(DataArrayIdType::NewFromStdVector(famIds)); + MCAuto idsToKill(famIds2->buildIntersection(vals)); + if(idsToKill->empty()) + return ; + std::vector newFamsOnGrp; + for(std::vector::const_iterator itt=famsOnGrp.begin();itt!=famsOnGrp.end();itt++) + { + if(!idsToKill->presenceOfValue(getFamilyId(*itt))) + newFamsOnGrp.push_back(*itt); + } + (*it).second=newFamsOnGrp; +} + /*! * Removes a group from \a this mesh. * \param [in] name - the name of the group to remove. @@ -576,9 +711,8 @@ std::vector MEDFileMesh::removeEmptyGroups() */ void MEDFileMesh::removeGroup(const std::string& name) { - std::string oname(name); - std::map >::iterator it=_groups.find(oname); - std::vector grps=getGroupsNames(); + std::map >::iterator it=_groups.find(name); + std::vector grps(getGroupsNames()); if(it==_groups.end()) { std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :"; @@ -596,7 +730,7 @@ void MEDFileMesh::removeGroup(const std::string& name) void MEDFileMesh::removeFamily(const std::string& name) { std::string oname(name); - std::map::iterator it=_families.find(oname); + std::map::iterator it=_families.find(oname); std::vector fams=getFamiliesNames(); if(it==_families.end()) { @@ -634,21 +768,21 @@ std::vector MEDFileMesh::removeOrphanGroups() * family field whatever its level. Groups are updated in consequence, that is to say all groups lying on orphan family, will see their families list modified. * * \return - The list of removed families names. - * \sa MEDFileMesh::removeOrphanGroups. + * \sa MEDFileMesh::removeOrphanGroups , MEDFileMesh::removeFamiliesReferedByNoGroups */ std::vector MEDFileMesh::removeOrphanFamilies() { - MEDCouplingAutoRefCountObjectPtr allFamIdsInUse=computeAllFamilyIdsInUse(); + MCAuto allFamIdsInUse=computeAllFamilyIdsInUse(); std::vector ret; - if(!((DataArrayInt*)allFamIdsInUse)) + if(!((DataArrayIdType*)allFamIdsInUse)) { ret=getFamiliesNames(); _families.clear(); _groups.clear(); return ret; } - std::map famMap; + std::map famMap; std::map > grps(_groups); - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) + for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) { if(allFamIdsInUse->presenceOfValue((*it).second)) famMap[(*it).first]=(*it).second; @@ -675,12 +809,13 @@ std::vector MEDFileMesh::removeOrphanFamilies() * this family is orphan or not. * * \warning this method is different from removeOrphanFamilies that scans family field array to find orphan families. + * \sa MEDFileMesh::removeOrphanFamilies */ void MEDFileMesh::removeFamiliesReferedByNoGroups() { - std::map fams; + std::map fams; std::set sfams; - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) + for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) sfams.insert((*it).first); for(std::map >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++) for(std::vector::const_iterator it1=(*it0).second.begin();it1!=(*it0).second.end();it1++) @@ -691,11 +826,13 @@ void MEDFileMesh::removeFamiliesReferedByNoGroups() } /*! - * This method has no impact on groups. This method only works on families. This method firstly removes families not refered by any groups in \a this, then all unused entities + * This method has no impact on groups. This method only works on families. This method firstly removes families not referred by any groups in \a this, then all unused entities * are put as belonging to family 0 ("FAMILLE_ZERO"). Finally, all orphanFamilies are killed. * This method raises an exception if "FAMILLE_ZERO" is already belonging to a group. + * + * This method also raises an exception if a family belonging to a group has also id 0 (which is not right in MED file format). You should never encounter this case using addGroup method. * - * \sa MEDFileMesh::removeOrphanFamilies + * \sa MEDFileMesh::removeOrphanFamilies, MEDFileMesh::zipFamilies */ void MEDFileMesh::rearrangeFamilies() { @@ -703,26 +840,36 @@ void MEDFileMesh::rearrangeFamilies() removeFamiliesReferedByNoGroups(); // std::vector levels(getNonEmptyLevelsExt()); - std::set idsRefed; - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) - idsRefed.insert((*it).second); + std::set idsRefed; + for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) + { + idsRefed.insert((*it).second); + if((*it).second==0) + { + if(!getGroupsOnFamily((*it).first).empty()) + { + std::ostringstream oss; oss << "MEDFileMesh::rearrangeFamilies : Not orphan family \"" << (*it).first << "\" has id 0 ! This method may alterate groups in this for such a case !"; + throw INTERP_KERNEL::Exception(oss.str()); + } + } + } for(std::vector::const_iterator it=levels.begin();it!=levels.end();it++) { - const DataArrayInt *fams(0); + const DataArrayIdType *fams(0); try { fams=getFamilyFieldAtLevel(*it); } - catch(INTERP_KERNEL::Exception& e) { } + catch(INTERP_KERNEL::Exception& ) { } if(!fams) continue; std::vector v(fams->getNumberOfTuples(),false); - for(std::set::const_iterator pt=idsRefed.begin();pt!=idsRefed.end();pt++) + for(std::set::const_iterator pt=idsRefed.begin();pt!=idsRefed.end();pt++) fams->switchOnTupleEqualTo(*pt,v); - MEDCouplingAutoRefCountObjectPtr unfetchedIds(DataArrayInt::BuildListOfSwitchedOff(v)); + MCAuto unfetchedIds(DataArrayIdType::BuildListOfSwitchedOff(v)); if(!unfetchedIds->empty()) { - MEDCouplingAutoRefCountObjectPtr newFams(fams->deepCpy()); + MCAuto newFams(fams->deepCopy()); newFams->setPartOfValuesSimple3(0,unfetchedIds->begin(),unfetchedIds->end(),0,1,1); setFamilyFieldArr(*it,newFams); } @@ -730,6 +877,83 @@ void MEDFileMesh::rearrangeFamilies() removeOrphanFamilies(); } +/*! + * This method has no impact on existing groups. This method has only impact on families behind the groups. + * This method is especially useful for MED file structures having used too much families to define their groups and that need to be merged without modification of their groups. + * To zip families, firstly this method first removes families refered by no groups (see MEDFileMesh::removeFamiliesReferedByNoGroups), then this method puts together families lying on a same set of groups. If the set of families having same groups has a length higher than 1, the families are merged into a single family + * having the name of the first family appearing in family definition and with the corresponding family ID. + */ +void MEDFileMesh::zipFamilies() +{ + checkOrphanFamilyZero(); + removeFamiliesReferedByNoGroups(); + std::map< std::set , std::vector > setOfFamilies; + // firstly, store in setOfFamilies as key the common set of groups, and as value the families having such same set of groups + for(auto fam : _families) + { + std::vector grps( this->getGroupsOnFamily( fam.first ) ); + std::set sgrps(grps.begin(),grps.end()); + setOfFamilies[sgrps].push_back(fam.first); + } + // + std::map > newGroups(_groups); + std::map newFams(_families); + std::vector levels(getNonEmptyLevelsExt()); + std::map > famIdsToSubstitute; + // iterate on all different set of groups + std::set familiesToKill; + for(auto setOfCommonGrp : setOfFamilies) + { + if( setOfCommonGrp.second.size()<=1 ) + continue; + for(auto fam=setOfCommonGrp.second.begin()+1 ; fam != setOfCommonGrp.second.end() ; fam++) + familiesToKill.insert(*fam); + } + // iterate on all different set of groups + for(auto setOfCommonGrp : setOfFamilies) + { + if( setOfCommonGrp.second.size()<=1 ) + continue; + std::string newFamName(setOfCommonGrp.second[0]); + auto newFamID(_families[newFamName]); + for(auto grpToBeModified : setOfCommonGrp.first) + { + std::vector newFamiliesForCurGrp(1,newFamName); + const std::vector& familiesOnCurGrp(_groups[grpToBeModified]); + const std::vector& familiesToZip(setOfCommonGrp.second); + std::for_each(familiesToZip.begin(),familiesToZip.end(),[&famIdsToSubstitute,this,newFamID](const std::string& elt) { famIdsToSubstitute[newFamID].push_back(this->getFamilyId(elt)); }); + // for each family shared by the current group only keep those not sharing setOfCommonGrp.second + std::for_each(familiesOnCurGrp.begin(),familiesOnCurGrp.end(),[&familiesToKill,&newFamiliesForCurGrp](const std::string& elt) + { if( familiesToKill.find(elt) == familiesToKill.end() ) { newFamiliesForCurGrp.push_back(elt); } }); + newGroups[grpToBeModified] = newFamiliesForCurGrp; + } + for(auto familyToKill = setOfCommonGrp.second.begin()+1 ; familyToKill != setOfCommonGrp.second.end(); ++familyToKill) + { + newFams.erase( newFams.find(*familyToKill) ); + } + + } + // apply modifications in datastructure + for(auto famIdsSubstSession : famIdsToSubstitute) + { + for(std::vector::const_iterator it=levels.begin();it!=levels.end();it++) + { + DataArrayIdType *fams(nullptr); + try + { + fams=getFamilyFieldAtLevel(*it); + } + catch(INTERP_KERNEL::Exception& ) { } + if(!fams) + continue; + MCAuto idsToModif(fams->findIdsEqualList(famIdsSubstSession.second.data(),famIdsSubstSession.second.data()+famIdsSubstSession.second.size())); + fams->setPartOfValuesSimple3(famIdsSubstSession.first,idsToModif->begin(),idsToModif->end(),0,1,1); + } + } + _groups = newGroups; + _families = newFams; +} + /*! * This method only checks that "FAMILLE_ZERO" is orphan (not belonging to a group). */ @@ -781,11 +1005,11 @@ void MEDFileMesh::changeGroupName(const std::string& oldName, const std::string& * \param [in] oldId - a current id of the family. * \param [in] newId - a new family id. */ -void MEDFileMesh::changeFamilyId(int oldId, int newId) +void MEDFileMesh::changeFamilyId(mcIdType oldId, mcIdType newId) { changeFamilyIdArr(oldId,newId); - std::map fam2; - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) + std::map fam2; + for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) { if((*it).second==oldId) fam2[(*it).first]=newId; @@ -805,7 +1029,7 @@ void MEDFileMesh::changeFamilyId(int oldId, int newId) void MEDFileMesh::changeFamilyName(const std::string& oldName, const std::string& newName) { std::string oname(oldName); - std::map::iterator it=_families.find(oname); + std::map::iterator it=_families.find(oname); std::vector fams=getFamiliesNames(); if(it==_families.end()) { @@ -814,13 +1038,13 @@ void MEDFileMesh::changeFamilyName(const std::string& oldName, const std::string throw INTERP_KERNEL::Exception(oss.str().c_str()); } std::string nname(newName); - std::map::iterator it2=_families.find(nname); + std::map::iterator it2=_families.find(nname); if(it2!=_families.end()) { std::ostringstream oss; oss << "Such familyname \"" << newName << " already exists ! Kill it before !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } - int cpy=(*it).second; + mcIdType cpy=(*it).second; _families.erase(it); _families[newName]=cpy; for(std::map >::iterator it3=_groups.begin();it3!=_groups.end();it3++) @@ -843,12 +1067,12 @@ bool MEDFileMesh::areFamsEqual(const MEDFileMesh *other, std::string& what) cons { if(_families==other->_families) return true; - std::map fam0; - std::map fam1; - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) + std::map fam0; + std::map fam1; + for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) if((*it).second!=0) fam0[(*it).first]=(*it).second; - for(std::map::const_iterator it=other->_families.begin();it!=other->_families.end();it++) + for(std::map::const_iterator it=other->_families.begin();it!=other->_families.end();it++) if((*it).second!=0) fam1[(*it).first]=(*it).second; return fam0==fam1; @@ -930,9 +1154,9 @@ bool MEDFileMesh::existsGroup(const std::string& groupName) const * \param [in] famId - the family id. * \return bool - \c true the family with the id \a famId exists in \a this mesh. */ -bool MEDFileMesh::existsFamily(int famId) const +bool MEDFileMesh::existsFamily(mcIdType famId) const { - for(std::map::const_iterator it2=_families.begin();it2!=_families.end();it2++) + for(std::map::const_iterator it2=_families.begin();it2!=_families.end();it2++) if((*it2).second==famId) return true; return false; @@ -954,16 +1178,16 @@ bool MEDFileMesh::existsFamily(const std::string& familyName) const * \param [in] familyName - the family name. * \param [in] id - a new id of the family. */ -void MEDFileMesh::setFamilyId(const std::string& familyName, int id) +void MEDFileMesh::setFamilyId(const std::string& familyName, mcIdType id) { std::string fname(familyName); _families[fname]=id; } -void MEDFileMesh::setFamilyIdUnique(const std::string& familyName, int id) +void MEDFileMesh::setFamilyIdUnique(const std::string& familyName, mcIdType id) { std::string fname(familyName); - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) + for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) if((*it).second==id) { if((*it).first!=familyName) @@ -981,13 +1205,13 @@ void MEDFileMesh::setFamilyIdUnique(const std::string& familyName, int id) * \param [in] famId - an id of the family. * \throw If a family with the same name or id already exists in \a this mesh. */ -void MEDFileMesh::addFamily(const std::string& familyName, int famId) +void MEDFileMesh::addFamily(const std::string& familyName, mcIdType famId) { std::string fname(familyName); - std::map::const_iterator it=_families.find(fname); + std::map::const_iterator it=_families.find(fname); if(it==_families.end()) { - for(std::map::const_iterator it2=_families.begin();it2!=_families.end();it2++) + for(std::map::const_iterator it2=_families.begin();it2!=_families.end();it2++) if((*it2).second==famId) { std::ostringstream oss; @@ -1039,12 +1263,12 @@ void MEDFileMesh::createGroupOnAll(int meshDimRelToMaxExt, const std::string& gr oss << std::endl << "Please choose an another group name or call removeGroup(\"" << grpName << "\") method !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } - const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(meshDimRelToMaxExt); + const DataArrayIdType *fieldFamIds=getFamilyFieldAtLevel(meshDimRelToMaxExt); if(fieldFamIds==0) throw INTERP_KERNEL::Exception("MEDFileMesh::createGroupOnAll : Family field arr ids is not defined for this level !"); - MEDCouplingAutoRefCountObjectPtr famIds=fieldFamIds->getDifferentValues(); + MCAuto famIds=fieldFamIds->getDifferentValues(); std::vector familiesOnWholeGroup; - for(const int *it=famIds->begin();it!=famIds->end();it++) + for(const mcIdType *it=famIds->begin();it!=famIds->end();it++) { bool tmp; familiesOnWholeGroup.push_back(findOrCreateAndGiveFamilyWithId(*it,tmp)); @@ -1061,28 +1285,28 @@ void MEDFileMesh::createGroupOnAll(int meshDimRelToMaxExt, const std::string& gr * famIds should exclusively belong. * \return bool - \c true if no modification is done in \a this mesh by this method. */ -bool MEDFileMesh::keepFamIdsOnlyOnLevs(const std::vector& famIds, const std::vector& vMeshDimRelToMaxExt) +bool MEDFileMesh::keepFamIdsOnlyOnLevs(const std::vector& famIds, const std::vector& vMeshDimRelToMaxExt) { std::set levsInput(vMeshDimRelToMaxExt.begin(),vMeshDimRelToMaxExt.end()); std::vector levs=getNonEmptyLevelsExt(); std::set levs2(levs.begin(),levs.end()); std::vector levsToTest; std::set_difference(levs2.begin(),levs2.end(),levsInput.begin(),levsInput.end(),std::back_insert_iterator< std::vector >(levsToTest)); - std::set famIds2(famIds.begin(),famIds.end()); + std::set famIds2(famIds.begin(),famIds.end()); bool ret=true; - int maxFamId=1; + mcIdType maxFamId=1; if(!_families.empty()) maxFamId=getMaxFamilyId()+1; std::vector allFams=getFamiliesNames(); for(std::vector::const_iterator it=levsToTest.begin();it!=levsToTest.end();it++) { - const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(*it); + const DataArrayIdType *fieldFamIds=getFamilyFieldAtLevel(*it); if(fieldFamIds) { - MEDCouplingAutoRefCountObjectPtr famIds3=fieldFamIds->getDifferentValues(); - std::vector tmp; - std::set_intersection(famIds3->begin(),famIds3->end(),famIds2.begin(),famIds2.end(),std::back_insert_iterator< std::vector >(tmp)); - for(std::vector::const_iterator it2=tmp.begin();it2!=tmp.end();it2++) + MCAuto famIds3=fieldFamIds->getDifferentValues(); + std::vector tmp; + std::set_intersection(famIds3->begin(),famIds3->end(),famIds2.begin(),famIds2.end(),std::back_insert_iterator< std::vector >(tmp)); + for(std::vector::const_iterator it2=tmp.begin();it2!=tmp.end();it2++) { ret=false; std::string famName=getFamilyNameGivenId(*it2); @@ -1090,7 +1314,7 @@ bool MEDFileMesh::keepFamIdsOnlyOnLevs(const std::vector& famIds, const std std::string zeName=CreateNameNotIn(oss.str(),allFams); addFamilyOnAllGroupsHaving(famName,zeName); _families[zeName]=maxFamId; - (const_cast(fieldFamIds))->changeValue(*it2,maxFamId); + (const_cast(fieldFamIds))->changeValue(*it2,maxFamId); maxFamId++; } } @@ -1152,11 +1376,24 @@ void MEDFileMesh::addFamilyOnAllGroupsHaving(const std::string& famName, const s } } +void MEDFileMesh::checkNoGroupClash(const DataArrayIdType *famArr, const std::string& grpName) const +{ + std::vector grpsNames(getGroupsNames()); + if(std::find(grpsNames.begin(),grpsNames.end(),grpName)==grpsNames.end()) + return ; + std::vector famIds(getFamiliesIdsOnGroup(grpName)); + if(famArr->presenceOfValue(famIds)) + { + std::ostringstream oss; oss << "MEDFileUMesh::addGroup : Group with name \"" << grpName << "\" already exists at specified level ! Destroy it before calling this method !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } +} + /*! * \param [in] ids ids and group name of the new group to add. The ids should be sorted and different each other (MED file norm). - * \parma [in,out] famArr family array on level of interest to be renumbered. The input pointer should be not \c NULL (no check of that will be performed) + * \param [in,out] famArr family array on level of interest to be renumbered. The input pointer should be not \c NULL (no check of that will be performed) */ -void MEDFileMesh::addGroupUnderground(bool isNodeGroup, const DataArrayInt *ids, DataArrayInt *famArr) +void MEDFileMesh::addGroupUnderground(bool isNodeGroup, const DataArrayIdType *ids, DataArrayIdType *famArr) { if(!ids) throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : NULL pointer in input !"); @@ -1164,36 +1401,31 @@ void MEDFileMesh::addGroupUnderground(bool isNodeGroup, const DataArrayInt *ids, if(grpName.empty()) throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : empty group name ! MED file format do not accept empty group name !"); ids->checkStrictlyMonotonic(true); - famArr->incrRef(); MEDCouplingAutoRefCountObjectPtr famArrTmp(famArr); - std::vector grpsNames=getGroupsNames(); - if(std::find(grpsNames.begin(),grpsNames.end(),grpName)!=grpsNames.end()) - { - std::ostringstream oss; oss << "MEDFileUMesh::addGroup : Group with name \"" << grpName << "\" already exists ! Destroy it before calling this method !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - std::list< MEDCouplingAutoRefCountObjectPtr > allFamIds(getAllNonNullFamilyIds()); + checkNoGroupClash(famArr,grpName); + MCAuto famArrTmp; famArrTmp.takeRef(famArr); + std::list< MCAuto > allFamIds(getAllNonNullFamilyIds()); allFamIds.erase(std::find(allFamIds.begin(),allFamIds.end(),famArrTmp)); - MEDCouplingAutoRefCountObjectPtr famIds=famArr->selectByTupleIdSafe(ids->begin(),ids->end()); - MEDCouplingAutoRefCountObjectPtr diffFamIds=famIds->getDifferentValues(); - std::vector familyIds; - std::vector< MEDCouplingAutoRefCountObjectPtr > idsPerfamiliyIds; - int maxVal=getTheMaxAbsFamilyId()+1; - std::map families(_families); + MCAuto famIds=famArr->selectByTupleIdSafe(ids->begin(),ids->end()); + MCAuto diffFamIds=famIds->getDifferentValues(); + std::vector familyIds; + std::vector< MCAuto > idsPerfamiliyIds; + mcIdType maxVal=getTheMaxAbsFamilyId()+1; + std::map families(_families); std::map > groups(_groups); std::vector fams; bool created(false); - for(const int *famId=diffFamIds->begin();famId!=diffFamIds->end();famId++) + for(const mcIdType *famId=diffFamIds->begin();famId!=diffFamIds->end();famId++) { - MEDCouplingAutoRefCountObjectPtr ids2Tmp=famIds->getIdsEqual(*famId); - MEDCouplingAutoRefCountObjectPtr ids2=ids->selectByTupleId(ids2Tmp->begin(),ids2Tmp->end()); - MEDCouplingAutoRefCountObjectPtr ids1=famArr->getIdsEqual(*famId); - MEDCouplingAutoRefCountObjectPtr ret0(ids1->buildSubstractionOptimized(ids2)); + MCAuto ids2Tmp=famIds->findIdsEqual(*famId); + MCAuto ids2=ids->selectByTupleId(ids2Tmp->begin(),ids2Tmp->end()); + MCAuto ids1=famArr->findIdsEqual(*famId); + MCAuto ret0(ids1->buildSubstractionOptimized(ids2)); if(ret0->empty()) { bool isFamPresent=false; - for(std::list< MEDCouplingAutoRefCountObjectPtr >::const_iterator itl=allFamIds.begin();itl!=allFamIds.end() && !isFamPresent;itl++) + for(std::list< MCAuto >::const_iterator itl=allFamIds.begin();itl!=allFamIds.end() && !isFamPresent;itl++) isFamPresent=(*itl)->presenceOfValue(*famId); - if(!isFamPresent) + if(!isFamPresent && *famId!=0) { familyIds.push_back(*famId); idsPerfamiliyIds.push_back(ret0); fams.push_back(FindOrCreateAndGiveFamilyWithId(families,*famId,created)); } // adding *famId in grp else { @@ -1223,12 +1455,19 @@ void MEDFileMesh::addGroupUnderground(bool isNodeGroup, const DataArrayInt *ids, } for(std::size_t i=0;isetPartOfValuesSimple3(familyIds[i],da->begin(),da->end(),0,1,1); } _families=families; + std::map >::iterator itt(groups.find(grpName)); + if(itt!=groups.end()) + { + std::vector& famsOnGrp((*itt).second); + famsOnGrp.insert(famsOnGrp.end(),fams.begin(),fams.end()); + } + else + groups[grpName]=fams; _groups=groups; - _groups[grpName]=fams; } void MEDFileMesh::changeAllGroupsContainingFamily(const std::string& familyNameToChange, const std::vector& newFamiliesNames) @@ -1259,7 +1498,7 @@ void MEDFileMesh::ChangeAllGroupsContainingFamily(std::map& families, int id, bool& created) +std::string MEDFileMesh::FindOrCreateAndGiveFamilyWithId(std::map& families, mcIdType id, bool& created) { std::vector famAlreadyExisting(families.size()); int ii=0; - for(std::map::const_iterator it=families.begin();it!=families.end();it++,ii++) + for(std::map::const_iterator it=families.begin();it!=families.end();it++,ii++) { if((*it).second!=id) { @@ -1299,7 +1538,7 @@ std::string MEDFileMesh::FindOrCreateAndGiveFamilyWithId(std::map& info) +void MEDFileMesh::setFamilyInfo(const std::map& info) { _families=info; } @@ -1317,16 +1556,15 @@ void MEDFileMesh::setGroupInfo(const std::map::const_iterator it=_families.find(oname); - std::vector fams=getFamiliesNames(); + std::map::const_iterator it=_families.find(name); if(it==_families.end()) { + std::vector fams(getFamiliesNames()); std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :"; std::copy(fams.begin(),fams.end(),std::ostream_iterator(oss," ")); throw INTERP_KERNEL::Exception(oss.str().c_str()); @@ -1337,16 +1575,16 @@ int MEDFileMesh::getFamilyId(const std::string& name) const /*! * Returns ids of the families having given names. * \param [in] fams - a sequence of the names of families of interest. - * \return std::vector - a sequence of the ids of families of interest. + * \return std::vector - a sequence of the ids of families of interest. * \throw If \a fams contains a name of an inexistent family. */ -std::vector MEDFileMesh::getFamiliesIds(const std::vector& fams) const +std::vector MEDFileMesh::getFamiliesIds(const std::vector& fams) const { - std::vector ret(fams.size()); + std::vector ret(fams.size()); int i=0; for(std::vector::const_iterator it=fams.begin();it!=fams.end();it++,i++) { - std::map::const_iterator it2=_families.find(*it); + std::map::const_iterator it2=_families.find(*it); if(it2==_families.end()) { std::vector fams2=getFamiliesNames(); @@ -1361,15 +1599,15 @@ std::vector MEDFileMesh::getFamiliesIds(const std::vector& fam /*! * Returns a maximal abs(id) of families in \a this mesh. - * \return int - the maximal norm of family id. + * \return mcIdType - the maximal norm of family id. * \throw If there are no families in \a this mesh. */ -int MEDFileMesh::getMaxAbsFamilyId() const +mcIdType MEDFileMesh::getMaxAbsFamilyId() const { if(_families.empty()) throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !"); - int ret=-std::numeric_limits::max(); - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) + mcIdType ret=-std::numeric_limits::max(); + for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) { ret=std::max(std::abs((*it).second),ret); } @@ -1378,15 +1616,15 @@ int MEDFileMesh::getMaxAbsFamilyId() const /*! * Returns a maximal id of families in \a this mesh. - * \return int - the maximal family id. + * \return mcIdType - the maximal family id. * \throw If there are no families in \a this mesh. */ -int MEDFileMesh::getMaxFamilyId() const +mcIdType MEDFileMesh::getMaxFamilyId() const { if(_families.empty()) throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !"); - int ret=-std::numeric_limits::max(); - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) + mcIdType ret=-std::numeric_limits::max(); + for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) { ret=std::max((*it).second,ret); } @@ -1395,15 +1633,15 @@ int MEDFileMesh::getMaxFamilyId() const /*! * Returns a minimal id of families in \a this mesh. - * \return int - the minimal family id. + * \return mcIdType - the minimal family id. * \throw If there are no families in \a this mesh. */ -int MEDFileMesh::getMinFamilyId() const +mcIdType MEDFileMesh::getMinFamilyId() const { if(_families.empty()) throw INTERP_KERNEL::Exception("MEDFileMesh::getMinFamilyId : no families set !"); - int ret=std::numeric_limits::max(); - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) + mcIdType ret=std::numeric_limits::max(); + for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) { ret=std::min((*it).second,ret); } @@ -1413,42 +1651,42 @@ int MEDFileMesh::getMinFamilyId() const /*! * Returns a maximal id of families in \a this mesh. Not only named families are * considered but all family fields as well. - * \return int - the maximal family id. + * \return mcIdType - the maximal family id. */ -int MEDFileMesh::getTheMaxAbsFamilyId() const +mcIdType MEDFileMesh::getTheMaxAbsFamilyId() const { - int m1=-std::numeric_limits::max(); - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) + mcIdType m1=-std::numeric_limits::max(); + for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) m1=std::max(std::abs((*it).second),m1); - int m2=getMaxAbsFamilyIdInArrays(); + mcIdType m2=getMaxAbsFamilyIdInArrays(); return std::max(m1,m2); } /*! * Returns a maximal id of families in \a this mesh. Not only named families are * considered but all family fields as well. - * \return int - the maximal family id. + * \return mcIdType - the maximal family id. */ -int MEDFileMesh::getTheMaxFamilyId() const +mcIdType MEDFileMesh::getTheMaxFamilyId() const { - int m1=-std::numeric_limits::max(); - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) + mcIdType m1=-std::numeric_limits::max(); + for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) m1=std::max((*it).second,m1); - int m2=getMaxFamilyIdInArrays(); + mcIdType m2=getMaxFamilyIdInArrays(); return std::max(m1,m2); } /*! * Returns a minimal id of families in \a this mesh. Not only named families are * considered but all family fields as well. - * \return int - the minimal family id. + * \return mcIdType - the minimal family id. */ -int MEDFileMesh::getTheMinFamilyId() const +mcIdType MEDFileMesh::getTheMinFamilyId() const { - int m1=std::numeric_limits::max(); - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) + mcIdType m1=std::numeric_limits::max(); + for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) m1=std::min((*it).second,m1); - int m2=getMinFamilyIdInArrays(); + mcIdType m2=getMinFamilyIdInArrays(); return std::min(m1,m2); } @@ -1457,13 +1695,13 @@ int MEDFileMesh::getTheMinFamilyId() const * * \sa MEDFileMesh::computeAllFamilyIdsInUse */ -DataArrayInt *MEDFileMesh::getAllFamiliesIdsReferenced() const +DataArrayIdType *MEDFileMesh::getAllFamiliesIdsReferenced() const { - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - std::set v; - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) + MCAuto ret=DataArrayIdType::New(); + std::set v; + for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) v.insert((*it).second); - ret->alloc((int)v.size(),1); + ret->alloc((mcIdType)v.size(),1); std::copy(v.begin(),v.end(),ret->getPointer()); return ret.retn(); } @@ -1473,15 +1711,15 @@ DataArrayInt *MEDFileMesh::getAllFamiliesIdsReferenced() const * * \sa MEDFileMesh::getAllFamiliesIdsReferenced */ -DataArrayInt *MEDFileMesh::computeAllFamilyIdsInUse() const +DataArrayIdType *MEDFileMesh::computeAllFamilyIdsInUse() const { std::vector famLevs=getFamArrNonEmptyLevelsExt(); - MEDCouplingAutoRefCountObjectPtr ret; + MCAuto ret; for(std::vector::const_iterator it=famLevs.begin();it!=famLevs.end();it++) { - const DataArrayInt *arr=getFamilyFieldAtLevel(*it);//arr not null due to spec of getFamArrNonEmptyLevelsExt - MEDCouplingAutoRefCountObjectPtr dv=arr->getDifferentValues(); - if((DataArrayInt *) ret) + const DataArrayIdType *arr=getFamilyFieldAtLevel(*it);//arr not null due to spec of getFamArrNonEmptyLevelsExt + MCAuto dv=arr->getDifferentValues(); + if((DataArrayIdType *) ret) ret=dv->buildUnion(ret); else ret=dv; @@ -1496,32 +1734,32 @@ DataArrayInt *MEDFileMesh::computeAllFamilyIdsInUse() const bool MEDFileMesh::ensureDifferentFamIdsPerLevel() { std::vector levs=getNonEmptyLevelsExt(); - std::set allFamIds; - int maxId=getMaxFamilyId()+1; - std::map > famIdsToRenum; + std::set allFamIds; + mcIdType maxId=getMaxFamilyId()+1; + std::map > famIdsToRenum; for(std::vector::const_iterator it=levs.begin();it!=levs.end();it++) { - const DataArrayInt *fam=getFamilyFieldAtLevel(*it); + const DataArrayIdType *fam=getFamilyFieldAtLevel(*it); if(fam) { - MEDCouplingAutoRefCountObjectPtr tmp=fam->getDifferentValues(); - std::set r2; + MCAuto tmp=fam->getDifferentValues(); + std::set r2; std::set_intersection(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r2,r2.end())); if(!r2.empty()) famIdsToRenum[*it].insert(famIdsToRenum[*it].end(),r2.begin(),r2.end()); - std::set r3; + std::set r3; std::set_union(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r3,r3.end())); } } if(famIdsToRenum.empty()) return true; - MEDCouplingAutoRefCountObjectPtr allIds=getAllFamiliesIdsReferenced(); - for(std::map >::const_iterator it2=famIdsToRenum.begin();it2!=famIdsToRenum.end();it2++) + MCAuto allIds=getAllFamiliesIdsReferenced(); + for(std::map >::const_iterator it2=famIdsToRenum.begin();it2!=famIdsToRenum.end();it2++) { - DataArrayInt *fam=const_cast(getFamilyFieldAtLevel((*it2).first)); - int *famIdsToChange=fam->getPointer(); - std::map ren; - for(std::vector::const_iterator it3=(*it2).second.begin();it3!=(*it2).second.end();it3++,maxId++) + DataArrayIdType *fam=const_cast(getFamilyFieldAtLevel((*it2).first)); + mcIdType *famIdsToChange=fam->getPointer(); + std::map ren; + for(std::vector::const_iterator it3=(*it2).second.begin();it3!=(*it2).second.end();it3++,maxId++) { if(allIds->presenceOfValue(*it3)) { @@ -1534,8 +1772,8 @@ bool MEDFileMesh::ensureDifferentFamIdsPerLevel() addFamilyOnGrp((*it4),newFam); } } - MEDCouplingAutoRefCountObjectPtr ids=fam->getIdsEqualList(&(*it2).second[0],&(*it2).second[0]+(*it2).second.size()); - for(const int *id=ids->begin();id!=ids->end();id++) + MCAuto ids=fam->findIdsEqualList(&(*it2).second[0],&(*it2).second[0]+(*it2).second.size()); + for(const mcIdType *id=ids->begin();id!=ids->end();id++) famIdsToChange[*id]=ren[famIdsToChange[*id]]; } return false; @@ -1551,27 +1789,27 @@ bool MEDFileMesh::ensureDifferentFamIdsPerLevel() void MEDFileMesh::normalizeFamIdsTrio() { ensureDifferentFamIdsPerLevel(); - MEDCouplingAutoRefCountObjectPtr allIds=getAllFamiliesIdsReferenced(); + MCAuto allIds=getAllFamiliesIdsReferenced(); std::vector levs=getNonEmptyLevelsExt(); std::set levsS(levs.begin(),levs.end()); std::set famsFetched; - std::map families; + std::map families; if(std::find(levs.begin(),levs.end(),0)!=levs.end()) { levsS.erase(0); - const DataArrayInt *fam=getFamilyFieldAtLevel(0); + const DataArrayIdType *fam=getFamilyFieldAtLevel(0); if(fam) { - int refId=1; - MEDCouplingAutoRefCountObjectPtr tmp=fam->getDifferentValues(); - std::map ren; - for(const int *it=tmp->begin();it!=tmp->end();it++,refId++) + mcIdType refId=1; + MCAuto tmp=fam->getDifferentValues(); + std::map ren; + for(const mcIdType *it=tmp->begin();it!=tmp->end();it++,refId++) ren[*it]=refId; - int nbOfTuples=fam->getNumberOfTuples(); - int *start=const_cast(fam)->getPointer(); - for(int *w=start;w!=start+nbOfTuples;w++) + mcIdType nbOfTuples=fam->getNumberOfTuples(); + mcIdType *start=const_cast(fam)->getPointer(); + for(mcIdType *w=start;w!=start+nbOfTuples;w++) *w=ren[*w]; - for(const int *it=tmp->begin();it!=tmp->end();it++) + for(const mcIdType *it=tmp->begin();it!=tmp->end();it++) { if(allIds->presenceOfValue(*it)) { @@ -1585,19 +1823,19 @@ void MEDFileMesh::normalizeFamIdsTrio() if(std::find(levs.begin(),levs.end(),-1)!=levs.end()) { levsS.erase(-1); - const DataArrayInt *fam=getFamilyFieldAtLevel(-1); + const DataArrayIdType *fam=getFamilyFieldAtLevel(-1); if(fam) { - int refId=-1; - MEDCouplingAutoRefCountObjectPtr tmp=fam->getDifferentValues(); - std::map ren; - for(const int *it=tmp->begin();it!=tmp->end();it++,refId--) + mcIdType refId=-1; + MCAuto tmp=fam->getDifferentValues(); + std::map ren; + for(const mcIdType *it=tmp->begin();it!=tmp->end();it++,refId--) ren[*it]=refId; - int nbOfTuples=fam->getNumberOfTuples(); - int *start=const_cast(fam)->getPointer(); - for(int *w=start;w!=start+nbOfTuples;w++) + mcIdType nbOfTuples=fam->getNumberOfTuples(); + mcIdType *start=const_cast(fam)->getPointer(); + for(mcIdType *w=start;w!=start+nbOfTuples;w++) *w=ren[*w]; - for(const int *it=tmp->begin();it!=tmp->end();it++) + for(const mcIdType *it=tmp->begin();it!=tmp->end();it++) { if(allIds->presenceOfValue(*it)) { @@ -1610,12 +1848,12 @@ void MEDFileMesh::normalizeFamIdsTrio() } for(std::set::const_iterator it2=levsS.begin();it2!=levsS.end();it2++) { - DataArrayInt *fam=const_cast(getFamilyFieldAtLevel(*it2)); + DataArrayIdType *fam=const_cast(getFamilyFieldAtLevel(*it2)); if(fam) { - MEDCouplingAutoRefCountObjectPtr tmp=fam->getDifferentValues(); + MCAuto tmp=fam->getDifferentValues(); fam->fillWithZero(); - for(const int *it3=tmp->begin();it3!=tmp->end();it3++) + for(const mcIdType *it3=tmp->begin();it3!=tmp->end();it3++) if(allIds->presenceOfValue(*it3)) { std::string famName=getFamilyNameGivenId(*it3); @@ -1643,27 +1881,27 @@ void MEDFileMesh::normalizeFamIdsTrio() void MEDFileMesh::normalizeFamIdsMEDFile() { ensureDifferentFamIdsPerLevel(); - MEDCouplingAutoRefCountObjectPtr allIds=getAllFamiliesIdsReferenced(); + MCAuto allIds=getAllFamiliesIdsReferenced(); std::vector levs=getNonEmptyLevelsExt(); std::set levsS(levs.begin(),levs.end()); std::set famsFetched; - std::map families; - int refId=1; + std::map families; + mcIdType refId=1; if(std::find(levs.begin(),levs.end(),1)!=levs.end()) { levsS.erase(1); - const DataArrayInt *fam=getFamilyFieldAtLevel(1); + const DataArrayIdType *fam=getFamilyFieldAtLevel(1); if(fam) { - MEDCouplingAutoRefCountObjectPtr tmp=fam->getDifferentValues(); - std::map ren; - for(const int *it=tmp->begin();it!=tmp->end();it++,refId++) + MCAuto tmp=fam->getDifferentValues(); + std::map ren; + for(const mcIdType *it=tmp->begin();it!=tmp->end();it++,refId++) ren[*it]=refId; - int nbOfTuples=fam->getNumberOfTuples(); - int *start=const_cast(fam)->getPointer(); - for(int *w=start;w!=start+nbOfTuples;w++) + mcIdType nbOfTuples=fam->getNumberOfTuples(); + mcIdType *start=const_cast(fam)->getPointer(); + for(mcIdType *w=start;w!=start+nbOfTuples;w++) *w=ren[*w]; - for(const int *it=tmp->begin();it!=tmp->end();it++) + for(const mcIdType *it=tmp->begin();it!=tmp->end();it++) { if(allIds->presenceOfValue(*it)) { @@ -1677,18 +1915,18 @@ void MEDFileMesh::normalizeFamIdsMEDFile() refId=-1; for(std::set::const_reverse_iterator it2=levsS.rbegin();it2!=levsS.rend();it2++) { - const DataArrayInt *fam=getFamilyFieldAtLevel(*it2); + const DataArrayIdType *fam=getFamilyFieldAtLevel(*it2); if(fam) { - MEDCouplingAutoRefCountObjectPtr tmp=fam->getDifferentValues(); - std::map ren; - for(const int *it=tmp->begin();it!=tmp->end();it++,refId--) + MCAuto tmp=fam->getDifferentValues(); + std::map ren; + for(const mcIdType *it=tmp->begin();it!=tmp->end();it++,refId--) ren[*it]=refId; - int nbOfTuples=fam->getNumberOfTuples(); - int *start=const_cast(fam)->getPointer(); - for(int *w=start;w!=start+nbOfTuples;w++) + mcIdType nbOfTuples=fam->getNumberOfTuples(); + mcIdType *start=const_cast(fam)->getPointer(); + for(mcIdType *w=start;w!=start+nbOfTuples;w++) *w=ren[*w]; - for(const int *it=tmp->begin();it!=tmp->end();it++) + for(const mcIdType *it=tmp->begin();it!=tmp->end();it++) { if(allIds->presenceOfValue(*it)) { @@ -1716,9 +1954,9 @@ void MEDFileMesh::normalizeFamIdsMEDFile() * \return std::string - the name of the found family. * \throw If no family with the given \a id exists. */ -std::string MEDFileMesh::getFamilyNameGivenId(int id) const +std::string MEDFileMesh::getFamilyNameGivenId(mcIdType id) const { - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) + for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) if((*it).second==id) return (*it).first; std::ostringstream oss; oss << "MEDFileUMesh::getFamilyNameGivenId : no such family id : " << id; @@ -1743,12 +1981,12 @@ std::string MEDFileMesh::simpleRepr() const * This method is nearly like getFamilyFieldAtLevel method. Except that if the array does not exist at the specified level \a meshDimRelToMaxExt * an empty one is created. */ -DataArrayInt *MEDFileMesh::getOrCreateAndGetFamilyFieldAtLevel(int meshDimRelToMaxExt) +DataArrayIdType *MEDFileMesh::getOrCreateAndGetFamilyFieldAtLevel(int meshDimRelToMaxExt) { - DataArrayInt *ret(getFamilyFieldAtLevel(meshDimRelToMaxExt)); + DataArrayIdType *ret(getFamilyFieldAtLevel(meshDimRelToMaxExt)); if(ret) return ret; - MEDCouplingAutoRefCountObjectPtr arr(DataArrayInt::New()); + MCAuto arr(DataArrayIdType::New()); arr->alloc(getSizeAtLevel(meshDimRelToMaxExt),1); arr->fillWithZero(); setFamilyFieldArr(meshDimRelToMaxExt,arr); @@ -1762,17 +2000,17 @@ DataArrayInt *MEDFileMesh::getOrCreateAndGetFamilyFieldAtLevel(int meshDimRelToM * \param [in] grp - the name of the group of interest. * \param [in] renum - if \c true, the optional numbers of entities, if available, are * returned instead of ids. - * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or + * \return DataArrayIdType * - a new instance of DataArrayIdType holding either ids or * numbers, if available and required, of mesh entities of the group. The caller * is to delete this array using decrRef() as it is no more needed. * \throw If the name of a nonexistent group is specified. * \throw If the family field is missing for \a meshDimRelToMaxExt. */ -DataArrayInt *MEDFileMesh::getGroupArr(int meshDimRelToMaxExt, const std::string& grp, bool renum) const +DataArrayIdType *MEDFileMesh::getGroupArr(int meshDimRelToMaxExt, const std::string& grp, bool renum) const { std::vector tmp(1); tmp[0]=grp; - DataArrayInt *ret=getGroupsArr(meshDimRelToMaxExt,tmp,renum); + DataArrayIdType *ret=getGroupsArr(meshDimRelToMaxExt,tmp,renum); ret->setName(grp); return ret; } @@ -1784,13 +2022,13 @@ DataArrayInt *MEDFileMesh::getGroupArr(int meshDimRelToMaxExt, const std::string * \param [in] grps - the names of the groups of interest. * \param [in] renum - if \c true, the optional numbers of entities, if available, are * returned instead of ids. - * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or + * \return DataArrayIdType * - a new instance of DataArrayIdType holding either ids or * numbers, if available and required, of mesh entities of the groups. The caller * is to delete this array using decrRef() as it is no more needed. * \throw If the name of a nonexistent group is present in \a grps. * \throw If the family field is missing for \a meshDimRelToMaxExt. */ -DataArrayInt *MEDFileMesh::getGroupsArr(int meshDimRelToMaxExt, const std::vector& grps, bool renum) const +DataArrayIdType *MEDFileMesh::getGroupsArr(int meshDimRelToMaxExt, const std::vector& grps, bool renum) const { std::vector fams2=getFamiliesOnGroups(grps); return getFamiliesArr(meshDimRelToMaxExt,fams2,renum); @@ -1803,16 +2041,16 @@ DataArrayInt *MEDFileMesh::getGroupsArr(int meshDimRelToMaxExt, const std::vecto * \param [in] fam - the name of the family of interest. * \param [in] renum - if \c true, the optional numbers of entities, if available, are * returned instead of ids. - * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or + * \return DataArrayIdType * - a new instance of DataArrayIdType holding either ids or * numbers, if available and required, of mesh entities of the family. The caller * is to delete this array using decrRef() as it is no more needed. * \throw If the family field is missing for \a meshDimRelToMaxExt. */ -DataArrayInt *MEDFileMesh::getFamilyArr(int meshDimRelToMaxExt, const std::string& fam, bool renum) const +DataArrayIdType *MEDFileMesh::getFamilyArr(int meshDimRelToMaxExt, const std::string& fam, bool renum) const { std::vector tmp(1); tmp[0]=fam; - DataArrayInt *ret=getFamiliesArr(meshDimRelToMaxExt,tmp,renum); + DataArrayIdType *ret=getFamiliesArr(meshDimRelToMaxExt,tmp,renum); ret->setName(fam); return ret; } @@ -1822,17 +2060,17 @@ DataArrayInt *MEDFileMesh::getFamilyArr(int meshDimRelToMaxExt, const std::strin * \param [in] grp - the name of the group of interest. * \param [in] renum - if \c true, the optional numbers of nodes, if available, are * returned instead of ids. - * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or + * \return DataArrayIdType * - a new instance of DataArrayIdType holding either ids or * numbers, if available and required, of nodes of the group. The caller * is to delete this array using decrRef() as it is no more needed. * \throw If the name of a nonexistent group is specified. * \throw If the family field is missing for nodes. */ -DataArrayInt *MEDFileMesh::getNodeGroupArr(const std::string& grp, bool renum) const +DataArrayIdType *MEDFileMesh::getNodeGroupArr(const std::string& grp, bool renum) const { std::vector tmp(1); tmp[0]=grp; - DataArrayInt *ret=getNodeGroupsArr(tmp,renum); + DataArrayIdType *ret=getNodeGroupsArr(tmp,renum); ret->setName(grp); return ret; } @@ -1842,33 +2080,33 @@ DataArrayInt *MEDFileMesh::getNodeGroupArr(const std::string& grp, bool renum) c * \param [in] grps - the names of the groups of interest. * \param [in] renum - if \c true, the optional numbers of nodes, if available, are * returned instead of ids. - * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or + * \return DataArrayIdType * - a new instance of DataArrayIdType holding either ids or * numbers, if available and required, of nodes of the groups. The caller * is to delete this array using decrRef() as it is no more needed. * \throw If the name of a nonexistent group is present in \a grps. * \throw If the family field is missing for nodes. */ -DataArrayInt *MEDFileMesh::getNodeGroupsArr(const std::vector& grps, bool renum) const +DataArrayIdType *MEDFileMesh::getNodeGroupsArr(const std::vector& grps, bool renum) const { return getGroupsArr(1,grps,renum); } /*! - * Returns ids of nodes contained in a given group. - * \param [in] grp - the name of the group of interest. + * Returns ids of nodes contained in a given family. + * \param [in] fam - the name of the family of interest. * \param [in] renum - if \c true, the optional numbers of nodes, if available, are * returned instead of ids. - * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or - * numbers, if available and required, of nodes of the group. The caller + * \return DataArrayIdType * - a new instance of DataArrayIdType holding either ids or + * numbers, if available and required, of nodes of the family. The caller * is to delete this array using decrRef() as it is no more needed. - * \throw If the name of a nonexistent group is specified. + * \throw If the name of a nonexistent family is specified. * \throw If the family field is missing for nodes. */ -DataArrayInt *MEDFileMesh::getNodeFamilyArr(const std::string& fam, bool renum) const +DataArrayIdType *MEDFileMesh::getNodeFamilyArr(const std::string& fam, bool renum) const { std::vector tmp(1); tmp[0]=fam; - DataArrayInt *ret=getNodeFamiliesArr(tmp,renum); + DataArrayIdType *ret=getNodeFamiliesArr(tmp,renum); ret->setName(fam); return ret; } @@ -1878,12 +2116,12 @@ DataArrayInt *MEDFileMesh::getNodeFamilyArr(const std::string& fam, bool renum) * \param [in] fams - the names of the families of interest. * \param [in] renum - if \c true, the optional numbers of nodes, if available, are * returned instead of ids. - * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or + * \return DataArrayIdType * - a new instance of DataArrayIdType holding either ids or * numbers, if available and required, of nodes of the families. The caller * is to delete this array using decrRef() as it is no more needed. * \throw If the family field is missing for nodes. */ -DataArrayInt *MEDFileMesh::getNodeFamiliesArr(const std::vector& fams, bool renum) const +DataArrayIdType *MEDFileMesh::getNodeFamiliesArr(const std::vector& fams, bool renum) const { return getFamiliesArr(1,fams,renum); } @@ -1900,7 +2138,7 @@ DataArrayInt *MEDFileMesh::getNodeFamiliesArr(const std::vector& fa * \throw If \a grps includes invalid ids (or numbers if \a renum == \c true ). * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh. */ -void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector& grps, bool renum) +void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector& grps, bool renum) { if(grps.empty()) return ; @@ -1908,7 +2146,7 @@ void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector grpsName2(grps.size()); int i=0; - for(std::vector::const_iterator it=grps.begin();it!=grps.end();it++,i++) + for(std::vector::const_iterator it=grps.begin();it!=grps.end();it++,i++) { grpsName.insert((*it)->getName()); grpsName2[i]=(*it)->getName(); @@ -1917,29 +2155,29 @@ void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector fam; - std::vector< std::vector > fidsOfGroups; + mcIdType sz=getSizeAtLevel(meshDimRelToMaxExt); + MCAuto fam; + std::vector< std::vector > fidsOfGroups; if(!renum) { - fam=DataArrayInt::MakePartition(grps,sz,fidsOfGroups); + fam=DataArrayIdType::MakePartition(grps,sz,fidsOfGroups); } else { - std::vector< MEDCouplingAutoRefCountObjectPtr > grps2(grps.size()); + std::vector< MCAuto > grps2(grps.size()); for(unsigned int ii=0;iisetName(grps[ii]->getName()); } - std::vector grps3(grps2.begin(),grps2.end()); - fam=DataArrayInt::MakePartition(grps3,sz,fidsOfGroups); + std::vector grps3(grps2.begin(),grps2.end()); + fam=DataArrayIdType::MakePartition(grps3,sz,fidsOfGroups); } - int offset=1; + mcIdType offset=1; if(!_families.empty()) offset=getMaxAbsFamilyId()+1; TranslateFamilyIds(meshDimRelToMaxExt==1?offset:-offset,fam,fidsOfGroups); - MEDCouplingAutoRefCountObjectPtr ids=fam->getDifferentValues(); + MCAuto ids=fam->getDifferentValues(); appendFamilyEntries(ids,fidsOfGroups,grpsName2); setFamilyFieldArr(meshDimRelToMaxExt,fam); } @@ -1949,10 +2187,10 @@ void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector >& fidsOfGrps, const std::vector& grpNames) +void MEDFileMesh::appendFamilyEntries(const DataArrayIdType *famIds, const std::vector< std::vector >& fidsOfGrps, const std::vector& grpNames) { - std::map famInv; - for(const int *it=famIds->begin();it!=famIds->end();it++) + std::map famInv; + for(const mcIdType *it=famIds->begin();it!=famIds->end();it++) { std::ostringstream oss; oss << "Family_" << (*it); @@ -1960,9 +2198,9 @@ void MEDFileMesh::appendFamilyEntries(const DataArrayInt *famIds, const std::vec famInv[*it]=oss.str(); } int i=0; - for(std::vector< std::vector >::const_iterator it1=fidsOfGrps.begin();it1!=fidsOfGrps.end();it1++,i++) + for(std::vector< std::vector >::const_iterator it1=fidsOfGrps.begin();it1!=fidsOfGrps.end();it1++,i++) { - for(std::vector::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++) + for(std::vector::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++) { _groups[grpNames[i]].push_back(famInv[*it2]); } @@ -1981,20 +2219,30 @@ std::vector MEDFileMesh::getAllGeoTypes() con return ret; } -std::vector MEDFileMesh::getDistributionOfTypes(int meshDimRelToMax) const +/*! + * \sa getAllDistributionOfTypes + */ +std::vector MEDFileMesh::getDistributionOfTypes(int meshDimRelToMax) const { - MEDCouplingAutoRefCountObjectPtr mLev(getGenMeshAtLevel(meshDimRelToMax)); + MCAuto mLev(getMeshAtLevel(meshDimRelToMax)); return mLev->getDistributionOfTypes(); } -void MEDFileMesh::TranslateFamilyIds(int offset, DataArrayInt *famArr, std::vector< std::vector >& famIdsPerGrp) +void MEDFileMesh::loadLLWithAdditionalItems(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) +{ + loadLL(fid,mName,dt,it,mrs); + loadJointsFromFile(fid); + loadEquivalences(fid); +} + +void MEDFileMesh::TranslateFamilyIds(mcIdType offset, DataArrayIdType *famArr, std::vector< std::vector >& famIdsPerGrp) { famArr->applyLin(offset>0?1:-1,offset,0); - for(std::vector< std::vector >::iterator it1=famIdsPerGrp.begin();it1!=famIdsPerGrp.end();it1++) + for(std::vector< std::vector >::iterator it1=famIdsPerGrp.begin();it1!=famIdsPerGrp.end();it1++) { if(offset<0) - std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::negate()); - std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::bind2nd(std::plus(),offset)); + std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::negate()); + std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::bind(std::plus(),std::placeholders::_1,offset)); } } @@ -2019,7 +2267,7 @@ std::string MEDFileMesh::CreateNameNotIn(const std::string& nameTry, const std:: //attempt #2 if(len>=1) { - for(std::size_t i=1;i<30;i++) + for(char i=1;i<30;i++) { std::string tmp1(nameTry.at(0),i); tmp1+=nameTry; @@ -2036,12 +2284,12 @@ std::string MEDFileMesh::CreateNameNotIn(const std::string& nameTry, const std:: throw INTERP_KERNEL::Exception("MEDFileMesh::CreateNameNotIn : impossible to find a not already used name !"); } -int MEDFileMesh::PutInThirdComponentOfCodeOffset(std::vector& code, int strt) +mcIdType MEDFileMesh::PutInThirdComponentOfCodeOffset(std::vector& code, mcIdType strt) { std::size_t nbOfChunks=code.size()/3; if(code.size()%3!=0) throw INTERP_KERNEL::Exception("MEDFileMesh::PutInThirdComponentOfCodeOffset : code has invalid size : should be of size 3*x !"); - int ret=strt; + mcIdType ret=strt; for(std::size_t i=0;i::const_iterator it=_families.begin();it!=_families.end();it++) + for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) { oss << "- Family with name \"" << (*it).first << "\" with number " << (*it).second << std::endl; oss << " - Groups lying on this family : "; @@ -2121,8 +2369,12 @@ void MEDFileMesh::getFamilyRepr(std::ostream& oss) const */ MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) { - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); + MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName)); + return New(fid,mName,dt,it,mrs); +} + +MEDFileUMesh *MEDFileUMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) +{ return new MEDFileUMesh(fid,mName,dt,it,mrs); } @@ -2138,19 +2390,49 @@ MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, const std::string& */ MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs) { - std::vector ms=MEDLoader::GetMeshNames(fileName); + MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName)); + return New(fid,mrs); +} + +template +T *NewForTheFirstMeshInFile(med_idt fid, MEDFileMeshReadSelector *mrs) +{ + std::vector ms(MEDLoaderNS::getMeshNamesFid(fid)); if(ms.empty()) { - std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !"; + std::ostringstream oss; oss << MLMeshTraits::ClassName << "::New : no meshes in file \"" << MEDFileWritable::FileNameFromFID(fid) << "\" !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); int dt,it; - ParaMEDMEM::MEDCouplingMeshType meshType; + MEDCoupling::MEDCouplingMeshType meshType; std::string dummy2; - MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2); - return new MEDFileUMesh(fid,ms.front(),dt,it,mrs); + MEDCoupling::MEDCouplingAxisType dummy3; + MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2); + return T::New(fid,ms.front(),dt,it,mrs); +} + +MEDFileUMesh *MEDFileUMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs) +{ + return NewForTheFirstMeshInFile(fid,mrs); +} + +/*! + * \b WARNING this implementation is dependent from MEDCouplingMappedExtrudedMesh::buildUnstructured ! + * \sa MEDCouplingMappedExtrudedMesh::buildUnstructured , MEDCouplingMappedExtrudedMesh::build3DUnstructuredMesh + */ +MEDFileUMesh *MEDFileUMesh::New(const MEDCouplingMappedExtrudedMesh *mem) +{ + if(!mem) + throw INTERP_KERNEL::Exception("MEDFileUMesh::New : null input vector !"); + MCAuto ret(MEDFileUMesh::New()); + MCAuto m3D(mem->buildUnstructured()); + MCAuto m2D(mem->getMesh2D()->deepCopy()); + m2D->zipCoords(); + m2D->setCoords(m3D->getCoords()); + ret->setMeshAtLevel(0,m3D); + ret->setMeshAtLevel(-1,m2D); + ret->setFamilyId(GetSpeStr4ExtMesh(),std::numeric_limits::max()-mem->get2DCellIdForExtrusion()); + return ret.retn(); } /*! @@ -2173,13 +2455,13 @@ MEDFileUMesh *MEDFileUMesh::New() * \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] slicPerTyp - 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) +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)); @@ -2190,17 +2472,44 @@ MEDFileUMesh *MEDFileUMesh::LoadPartOf(const std::string& fileName, const std::s * 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) +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()); + MCAuto ret(MEDFileUMesh::New()); ret->loadPartUMeshFromFile(fid,mName,types,slicPerTyp,dt,it,mrs); return ret.retn(); } +/*! + * This method is an helper to load only consecutive nodes chunk of data of MED file pointed by \a fileName. + * Consecutive chunk is specified classicaly by start (included) stop (excluded) format with \a startNodeId and \a stopNodeId respectively. + * This method returns 5 elements. + * + * \param [in] fileName - Name of file nodes to be read of. + * \param [in] mName - Name of the mesh inside file pointed be \a fileName nodes to be read of. + * \param [in] dt - Time iteration inside file pointed be \a fileName nodes to be read of. + * \param [in] it - Time order inside file pointed be \a fileName nodes to be read of. + * \param [in] infosOnComp - Components info of nodes to be read of. The size of string vector should be equal to space dimension of mesh to be read. + * \param [in] startNodeId - Start Node Id (included) of chunk of data to be read + * \param [in] stopNodeId - Start Node Id (included) of chunk of data to be read + * \param [out] coords - output coordinates of requested chunk (DataArrayDouble) + * \param [out] partCoords - output PartDefinition object of chunk + * \param [out] famCoords - output family id field of requested chunk (DataArrayIdType) + * \param [out] numCoords - output num id field of requested chunk (DataArrayIdType) + * \param [out] nameCoords - output names on nodes of requested chunk (DataArrayAsciiChar) + * + * \sa MEDLoaderUMesh::LoadPartOf + */ +void MEDFileUMesh::LoadPartCoords(const std::string& fileName, const std::string& mName, int dt, int it, const std::vector& infosOnComp, mcIdType startNodeId, mcIdType stopNodeId, +MCAuto& coords, MCAuto& partCoords, MCAuto& famCoords, MCAuto& numCoords, MCAuto& nameCoords) +{ + MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName)); + MEDFileUMeshL2::LoadPartCoords(fid,infosOnComp,mName,dt,it,startNodeId,stopNodeId,coords,partCoords,famCoords,numCoords,nameCoords); +} + std::size_t MEDFileUMesh::getHeapMemorySizeWithoutChildren() const { std::size_t ret(MEDFileMesh::getHeapMemorySizeWithoutChildren()); - ret+=_ms.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr)); + ret+=_ms.capacity()*(sizeof(MCAuto))+_elt_str.capacity()*sizeof(MCAuto); return ret; } @@ -2208,19 +2517,22 @@ std::vector MEDFileUMesh::getDirectChildrenWithNull() c { 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 DataArrayIdType *)_fam_coords); + ret.push_back((const DataArrayIdType *)_num_coords); + ret.push_back((const DataArrayIdType *)_global_num_coords); + ret.push_back((const DataArrayIdType *)_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++) + for(std::vector< MCAuto >::const_iterator it=_ms.begin();it!=_ms.end();it++) ret.push_back((const MEDFileUMeshSplitL1*) *it); + for(std::vector< MCAuto >::const_iterator it=_elt_str.begin();it!=_elt_str.end();it++) + ret.push_back((const MEDFileEltStruct4Mesh *)*it); return ret; } -MEDFileMesh *MEDFileUMesh::shallowCpy() const +MEDFileUMesh *MEDFileUMesh::shallowCpy() const { - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileUMesh(*this); + MCAuto ret(new MEDFileUMesh(*this)); return ret.retn(); } @@ -2229,27 +2541,30 @@ MEDFileMesh *MEDFileUMesh::createNewEmpty() const return new MEDFileUMesh; } -MEDFileMesh *MEDFileUMesh::deepCpy() const -{ - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileUMesh(*this); - if((const DataArrayDouble*)_coords) - ret->_coords=_coords->deepCpy(); - if((const DataArrayInt*)_fam_coords) - ret->_fam_coords=_fam_coords->deepCpy(); - if((const DataArrayInt*)_num_coords) - ret->_num_coords=_num_coords->deepCpy(); - if((const DataArrayInt*)_rev_num_coords) - ret->_rev_num_coords=_rev_num_coords->deepCpy(); - if((const DataArrayAsciiChar*)_name_coords) - ret->_name_coords=_name_coords->deepCpy(); +MEDFileUMesh *MEDFileUMesh::deepCopy() const +{ + MCAuto ret(new MEDFileUMesh(*this)); + ret->deepCpyEquivalences(*this); + if(_coords.isNotNull()) + ret->_coords=_coords->deepCopy(); + if(_fam_coords.isNotNull()) + ret->_fam_coords=_fam_coords->deepCopy(); + if(_num_coords.isNotNull()) + ret->_num_coords=_num_coords->deepCopy(); + if(_global_num_coords.isNotNull()) + ret->_global_num_coords=_global_num_coords->deepCopy(); + if(_rev_num_coords.isNotNull()) + ret->_rev_num_coords=_rev_num_coords->deepCopy(); + if(_name_coords.isNotNull()) + ret->_name_coords=_name_coords->deepCopy(); std::size_t i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++) + for(std::vector< MCAuto >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++) { if((const MEDFileUMeshSplitL1 *)(*it)) - ret->_ms[i]=(*it)->deepCpy(ret->_coords); + ret->_ms[i]=(*it)->deepCopy(ret->_coords); } if((const PartDefinition*)_part_coords) - ret->_part_coords=_part_coords->deepCpy(); + ret->_part_coords=_part_coords->deepCopy(); return ret.retn(); } @@ -2288,61 +2603,81 @@ bool MEDFileUMesh::isEqual(const MEDFileMesh *other, double eps, std::string& wh return false; } } - const DataArrayInt *famc1=_fam_coords; - const DataArrayInt *famc2=otherC->_fam_coords; - if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0)) + { + const DataArrayIdType *famc1(_fam_coords),*famc2(otherC->_fam_coords); + if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0)) + { + what="Mismatch of families arr on nodes ! One is defined and not other !"; + return false; + } + if(famc1) + { + bool ret=famc1->isEqual(*famc2); + if(!ret) + { + what="Families arr on node differ !"; + return false; + } + } + } + { + const DataArrayIdType *numc1(_num_coords),*numc2(otherC->_num_coords); + if((numc1==0 && numc2!=0) || (numc1!=0 && numc2==0)) + { + what="Mismatch of numbering arr on nodes ! One is defined and not other !"; + return false; + } + if(numc1) + { + bool ret=numc1->isEqual(*numc2); + if(!ret) + { + what="Numbering arr on node differ !"; + return false; + } + } + } + { + const DataArrayIdType *gnumc1(_global_num_coords),*gnumc2(otherC->_global_num_coords); + if((gnumc1==0 && gnumc2!=0) || (gnumc1!=0 && gnumc2==0)) + { + what="Mismatch of numbering arr on nodes ! One is defined and not other !"; + return false; + } + if(gnumc1) + { + bool ret=gnumc1->isEqual(*gnumc2); + if(!ret) + { + what="Global numbering arr on node differ !"; + return false; + } + } + } + { + const DataArrayAsciiChar *namec1(_name_coords),*namec2(otherC->_name_coords); + if((namec1==0 && namec2!=0) || (namec1!=0 && namec2==0)) + { + what="Mismatch of naming arr on nodes ! One is defined and not other !"; + return false; + } + if(namec1) + { + bool ret=namec1->isEqual(*namec2); + if(!ret) + { + what="Names arr on node differ !"; + return false; + } + } + } + if(_ms.size()!=otherC->_ms.size()) { - what="Mismatch of families arr on nodes ! One is defined and not other !"; + what="Number of levels differs !"; return false; } - if(famc1) - { - bool ret=famc1->isEqual(*famc2); - if(!ret) - { - what="Families arr on node differ !"; - return false; - } - } - const DataArrayInt *numc1=_num_coords; - const DataArrayInt *numc2=otherC->_num_coords; - if((numc1==0 && numc2!=0) || (numc1!=0 && numc2==0)) - { - what="Mismatch of numbering arr on nodes ! One is defined and not other !"; - return false; - } - if(numc1) - { - bool ret=numc1->isEqual(*numc2); - if(!ret) - { - what="Numbering arr on node differ !"; - return false; - } - } - const DataArrayAsciiChar *namec1=_name_coords; - const DataArrayAsciiChar *namec2=otherC->_name_coords; - if((namec1==0 && namec2!=0) || (namec1!=0 && namec2==0)) - { - what="Mismatch of naming arr on nodes ! One is defined and not other !"; - return false; - } - if(namec1) - { - bool ret=namec1->isEqual(*namec2); - if(!ret) - { - what="Names arr on node differ !"; - return false; - } - } - if(_ms.size()!=otherC->_ms.size()) - { - what="Number of levels differs !"; - return false; - } - std::size_t sz=_ms.size(); - for(std::size_t i=0;i_ms[i]; @@ -2369,36 +2704,127 @@ bool MEDFileUMesh::isEqual(const MEDFileMesh *other, double eps, std::string& wh return pd0->isEqual(pd1,what); } +/*! + * Check that the current object MEDFileUMesh is consistent. This does not check the optional renumbering of + * nodes and cells. This last item is important for SMESH, see checkSMESHConsistency(). + * \throw if any internal part (i.e. mesh sub-levels and single geometric-type meshes) are inconsistent + * \throw if internal family array is inconsistent + * \sa checkSMESHConsistency() + */ +void MEDFileUMesh::checkConsistency() const +{ + if(!_coords || !_coords->isAllocated()) + { + if(!_ms.size()) + throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but some mesh parts are present!"); + if (!_fam_coords) + throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but not the internal node family array!"); + if (_num_coords.isNotNull() || _rev_num_coords.isNotNull() || _global_num_coords.isNotNull()) + throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but not the internal node numbering array!"); + } + else + { + mcIdType nbCoo = _coords->getNumberOfTuples(); + if (_fam_coords.isNotNull()) + _fam_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent internal node family array!"); + if (_num_coords.isNotNull()) + { + _num_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent internal node numbering array!"); + mcIdType pos; + mcIdType maxValue=_num_coords->getMaxValue(pos); + if (!_rev_num_coords || _rev_num_coords->getNumberOfTuples() != (maxValue+1)) + throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal revert node numbering array!"); + } + if (_global_num_coords.isNotNull()) + { + _global_num_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent global node numbering array!"); + } + if ((_num_coords && !_rev_num_coords) || (!_num_coords && _rev_num_coords)) + throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal numbering arrays (one is null)!"); + if (_num_coords && !_num_coords->hasUniqueValues()) + throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal node numbering array: duplicates found!"); + if (_name_coords) + _name_coords->checkNbOfTuplesAndComp(nbCoo,MED_SNAME_SIZE,"MEDFileUMesh::checkConsistency(): inconsistent internal coord name array!"); + // Now sub part check: + for (std::vector< MCAuto >::const_iterator it=_ms.begin(); + it != _ms.end(); it++) + (*it)->checkConsistency(); + } +} + +/** + * Same as checkConsistency() but also checks that optional entities (edges, faces, volumes) numbers are + * consistent, i.e. the numbering is either set to null for all sub-levels (thus letting SMESH numbers the + * entities as it likes), or non overlapping between all sub-levels. + * \throw if the condition above is not respected + */ +void MEDFileUMesh::checkSMESHConsistency() const +{ + checkConsistency(); + // For all sub-levels, numbering is either always null or with void intersection: + if (_ms.size()) + { + std::vector< MCAuto >::const_iterator it=_ms.begin(); + std::vector< const DataArrayIdType * > v; + bool voidOrNot = ((*it)->_num == 0); + for (it++; it != _ms.end(); it++) + if( ((*it)->_num == 0) != voidOrNot ) + throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent numbering between mesh sub-levels!"); + else if (!voidOrNot) + v.push_back((*it)->_num); + if (!voidOrNot) + { + // don't forget the 1st one: + v.push_back(_ms[0]->_num); + MCAuto inter = DataArrayIdType::BuildIntersection(v); + if (inter->getNumberOfTuples()) + throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): overlapping entity numbering between mesh sub-levels!"); + } + } +} + +/** + * Reset optional node and cell numbering for all sub levels in this. This particularly useful to make + * sure SMESH will handle the mesh correctly, as it tries to use those numbers if given. + */ +void MEDFileUMesh::clearNodeAndCellNumbers() +{ + _num_coords.nullify(); + _rev_num_coords.nullify(); + _global_num_coords.nullify(); + for (std::vector< MCAuto >::iterator it=_ms.begin(); it != _ms.end(); it++) + { + (*it)->_num.nullify(); + (*it)->_rev_num.nullify(); + (*it)->_global_num.nullify(); + } +} + /*! * Clears redundant attributes of incorporated data arrays. */ void MEDFileUMesh::clearNonDiscrAttributes() const { MEDFileMesh::clearNonDiscrAttributes(); - const DataArrayDouble *coo1=_coords; - if(coo1) - (const_cast(coo1))->setName("");//This parameter is not discriminant for comparison - const DataArrayInt *famc1=_fam_coords; - if(famc1) - (const_cast(famc1))->setName("");//This parameter is not discriminant for comparison - const DataArrayInt *numc1=_num_coords; - if(numc1) - (const_cast(numc1))->setName("");//This parameter is not discriminant for comparison - const DataArrayAsciiChar *namc1=_name_coords; - if(namc1) - (const_cast(namc1))->setName("");//This parameter is not discriminant for comparison - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++) + if(_coords.isNotNull()) + _coords.iAmATrollConstCast()->setName("");//This parameter is not discriminant for comparison + if(_fam_coords.isNotNull()) + _fam_coords.iAmATrollConstCast()->setName("");//This parameter is not discriminant for comparison + if(_num_coords.isNotNull()) + _num_coords.iAmATrollConstCast()->setName("");//This parameter is not discriminant for comparison + if(_name_coords.isNotNull()) + _name_coords.iAmATrollConstCast()->setName("");//This parameter is not discriminant for comparison + for(std::vector< MCAuto >::const_iterator it=_ms.begin();it!=_ms.end();it++) { - const MEDFileUMeshSplitL1 *tmp=(*it); - if(tmp) - tmp->clearNonDiscrAttributes(); + if((*it).isNotNull()) + (*it)->clearNonDiscrAttributes(); } } void MEDFileUMesh::setName(const std::string& name) { - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_ms.begin();it!=_ms.end();it++) - if((MEDFileUMeshSplitL1 *)(*it)!=0) + for(std::vector< MCAuto >::iterator it=_ms.begin();it!=_ms.end();it++) + if((*it).isNotNull()) (*it)->setName(name); MEDFileMesh::setName(name); } @@ -2410,9 +2836,8 @@ MEDFileUMesh::MEDFileUMesh() MEDFileUMesh::MEDFileUMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) try { - loadUMeshFromFile(fid,mName,dt,it,mrs); - loadJointsFromFile(fid); - } + loadLLWithAdditionalItems(fid,mName,dt,it,mrs); +} catch(INTERP_KERNEL::Exception& e) { throw e; @@ -2422,15 +2847,16 @@ catch(INTERP_KERNEL::Exception& 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 + * \sa loadLL */ -void MEDFileUMesh::loadPartUMeshFromFile(med_idt fid, const std::string& mName, const std::vector& types, const std::vector& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs) +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; + MEDCoupling::MEDCouplingMeshType meshType; int dummy0,dummy1; std::string dummy2; - int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2)); + MEDCoupling::MEDCouplingAxisType dummy3; + INTERP_KERNEL::AutoCppPtr mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy3,dummy0,dummy1,dummy2)); if(meshType!=UNSTRUCTURED) { std::ostringstream oss; oss << "loadPartUMeshFromFile : Trying to load as unstructured an existing mesh with name '" << mName << "' !"; @@ -2445,8 +2871,8 @@ void MEDFileUMesh::loadPartUMeshFromFile(med_idt fid, const std::string& mName, */ void MEDFileMesh::writeJoints(med_idt fid) const { - if ( (const MEDFileJoints*) _joints ) - _joints->write(fid); + if ( _joints.isNotNull() ) + _joints->writeLL(fid); } /*! @@ -2470,12 +2896,61 @@ void MEDFileMesh::loadJointsFromFile(med_idt fid, MEDFileJoints* toUseInstedOfRe _joints = MEDFileJoints::New( fid, _name ); } +void MEDFileMesh::loadEquivalences(med_idt fid) +{ + int nbOfEq(MEDFileEquivalences::PresenceOfEquivalences(fid,_name)); + if(nbOfEq>0) + _equiv=MEDFileEquivalences::Load(fid,nbOfEq,this); +} + +void MEDFileMesh::deepCpyEquivalences(const MEDFileMesh& other) +{ + const MEDFileEquivalences *equiv(other._equiv); + if(equiv) + _equiv=equiv->deepCopy(this); +} + +bool MEDFileMesh::areEquivalencesEqual(const MEDFileMesh *other, std::string& what) const +{ + const MEDFileEquivalences *thisEq(_equiv),*otherEq(other->_equiv); + if(!thisEq && !otherEq) + return true; + if(thisEq && otherEq) + return thisEq->isEqual(otherEq,what); + else + { + what+="Equivalence differs : defined in this and not in other (or reversely) !"; + return false; + } +} + +void MEDFileMesh::getEquivalencesRepr(std::ostream& oss) const +{ + const MEDFileEquivalences *equiv(_equiv); + if(!equiv) + return ; + oss << "(******************************)\n(* EQUIVALENCES OF THE MESH : *)\n(******************************)\n"; + _equiv->getRepr(oss); +} + +void MEDFileMesh::checkCartesian() const +{ + if(getAxisType()!=AX_CART) + { + std::ostringstream oss; oss << "MEDFileMesh::checkCartesian : request for method that is dedicated to a cartesian convention ! But you are not in cartesian convention (" << DataArray::GetAxisTypeRepr(getAxisType()) << ")."; + oss << std::endl << "To perform operation you have two possibilities :" << std::endl; + oss << " - call setAxisType(AX_CART)" << std::endl; + oss << " - call cartesianize()"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } +} + /*! * \brief Return number of joints, which is equal to number of adjacent mesh domains */ -int MEDFileMesh::getNumberOfJoints() +int MEDFileMesh::getNumberOfJoints() const { - return ( (MEDFileJoints*) _joints ) ? _joints->getNumberOfJoints() : 0; + return ( (const MEDFileJoints *) _joints ) ? _joints->getNumberOfJoints() : 0; } /*! @@ -2501,13 +2976,15 @@ void MEDFileMesh::setJoints( MEDFileJoints* joints ) * * \sa loadPartUMeshFromFile */ -void MEDFileUMesh::loadUMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) +void MEDFileUMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) { MEDFileUMeshL2 loaderl2; - ParaMEDMEM::MEDCouplingMeshType meshType; + MEDCoupling::MEDCouplingMeshType meshType; int dummy0,dummy1; std::string dummy2; - int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2)); + MEDCoupling::MEDCouplingAxisType axType; + INTERP_KERNEL::AutoCppPtr mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dummy2)); + setAxisType(axType); if(meshType!=UNSTRUCTURED) { std::ostringstream oss; oss << "Trying to load as unstructured an existing mesh with name '" << mName << "' !"; @@ -2515,6 +2992,17 @@ void MEDFileUMesh::loadUMeshFromFile(med_idt fid, const std::string& mName, int } loaderl2.loadAll(fid,mid,mName,dt,it,mrs); dispatchLoadedPart(fid,loaderl2,mName,mrs); + // Structure element part... + med_int nModels(-1); + { + med_bool chgt=MED_FALSE,trsf=MED_FALSE; + nModels=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_STRUCT_ELEMENT,MED_GEO_ALL,MED_CONNECTIVITY,MED_NODAL,&chgt,&trsf); + } + if(nModels<=0) + return ; + _elt_str.resize(nModels); + for(int i=0;iisNodeNameFieldReading()) _name_coords=loaderl2.getCoordsName(); + if(!mrs || mrs->isGlobalNodeNumFieldReading()) + _global_num_coords=loaderl2.getCoordsGlobalNum(); _part_coords=loaderl2.getPartDefOfCoo(); - computeRevNum(); } MEDFileUMesh::~MEDFileUMesh() { } -void MEDFileUMesh::writeLL(med_idt fid) const +void MEDFileUMesh::writeMeshLL(med_idt fid) const { const DataArrayDouble *coo=_coords; INTERP_KERNEL::AutoPtr maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); INTERP_KERNEL::AutoPtr desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE); MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str); MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str); - int spaceDim=coo?coo->getNumberOfComponents():0; + int spaceDim=(int)(coo?coo->getNumberOfComponents():0); int mdim(0); if(!_ms.empty()) mdim=getMeshDimension(); @@ -2570,19 +3059,18 @@ void MEDFileUMesh::writeLL(med_idt fid) const std::string info=coo->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,_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,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo + MEDLoaderBase::safeStrCpy2(c.c_str(),MED_SNAME_SIZE,comp+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo + MEDLoaderBase::safeStrCpy2(u.c_str(),MED_SNAME_SIZE,unit+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo } - MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MED_CARTESIAN,comp,unit)); - MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa)); + MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit)); + if(_univ_wr_status) + MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa)); std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE)); - MEDFileUMeshL2::WriteCoords(fid,meshName,_iteration,_order,_time,_coords,_fam_coords,_num_coords,_name_coords); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++) + MEDFileUMeshL2::WriteCoords(fid,meshName,_iteration,_order,_time,_coords,_fam_coords,_num_coords,_name_coords,_global_num_coords); + for(std::vector< MCAuto >::const_iterator it=_ms.begin();it!=_ms.end();it++) if((const MEDFileUMeshSplitL1 *)(*it)!=0) (*it)->write(fid,meshName,mdim); MEDFileUMeshL2::WriteFamiliesAndGrps(fid,meshName,_families,_groups,_too_long_str); - - writeJoints(fid); } /*! @@ -2593,7 +3081,7 @@ std::vector MEDFileUMesh::getNonEmptyLevels() const { std::vector ret; int lev=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--) + for(std::vector< MCAuto >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--) if((const MEDFileUMeshSplitL1 *)(*it)!=0) if(!(*it)->empty()) ret.push_back(lev); @@ -2620,11 +3108,11 @@ std::vector MEDFileUMesh::getNonEmptyLevelsExt() const std::vector MEDFileUMesh::getFamArrNonEmptyLevelsExt() const { std::vector ret; - const DataArrayInt *famCoo(_fam_coords); + const DataArrayIdType *famCoo(_fam_coords); if(famCoo) ret.push_back(1); int lev=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--) + for(std::vector< MCAuto >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--) { const MEDFileUMeshSplitL1 *cur(*it); if(cur) @@ -2637,11 +3125,10 @@ std::vector MEDFileUMesh::getFamArrNonEmptyLevelsExt() const std::vector MEDFileUMesh::getNumArrNonEmptyLevelsExt() const { std::vector ret; - const DataArrayInt *numCoo(_num_coords); - if(numCoo) + if(_num_coords.isNotNull()) ret.push_back(1); int lev=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--) + for(std::vector< MCAuto >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--) { const MEDFileUMeshSplitL1 *cur(*it); if(cur) @@ -2658,7 +3145,7 @@ std::vector MEDFileUMesh::getNameArrNonEmptyLevelsExt() const if(nameCoo) ret.push_back(1); int lev=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--) + for(std::vector< MCAuto >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--) { const MEDFileUMeshSplitL1 *cur(*it); if(cur) @@ -2668,86 +3155,17 @@ std::vector MEDFileUMesh::getNameArrNonEmptyLevelsExt() const return ret; } -/*! - * Returns all relative mesh levels (**excluding nodes**) where a given group is defined. - * To include nodes, call getGrpNonEmptyLevelsExt() method. - * \param [in] grp - the name of the group of interest. - * \return std::vector - a sequence of the relative dimensions. - */ -std::vector MEDFileUMesh::getGrpNonEmptyLevels(const std::string& grp) const -{ - std::vector fams=getFamiliesOnGroup(grp); - return getFamsNonEmptyLevels(fams); -} - -/*! - * Returns all relative mesh levels (including nodes) where a given group is defined. - * \param [in] grp - the name of the group of interest. - * \return std::vector - a sequence of the relative dimensions. - */ -std::vector MEDFileUMesh::getGrpNonEmptyLevelsExt(const std::string& grp) const -{ - std::vector fams=getFamiliesOnGroup(grp); - return getFamsNonEmptyLevelsExt(fams); -} - -/*! - * Returns all relative mesh levels (**excluding nodes**) where a given family is defined. - * To include nodes, call getFamNonEmptyLevelsExt() method. - * \param [in] fam - the name of the family of interest. - * \return std::vector - a sequence of the relative dimensions. - */ -std::vector MEDFileUMesh::getFamNonEmptyLevels(const std::string& fam) const -{ - std::vector fams(1,std::string(fam)); - return getFamsNonEmptyLevels(fams); -} - -/*! - * Returns all relative mesh levels (including nodes) where a given family is defined. - * \param [in] fam - the name of the family of interest. - * \return std::vector - a sequence of the relative dimensions. - */ -std::vector MEDFileUMesh::getFamNonEmptyLevelsExt(const std::string& fam) const -{ - std::vector fams(1,std::string(fam)); - return getFamsNonEmptyLevelsExt(fams); -} - -/*! - * Returns all relative mesh levels (**excluding nodes**) where given groups are defined. - * To include nodes, call getGrpsNonEmptyLevelsExt() method. - * \param [in] grps - a sequence of names of the groups of interest. - * \return std::vector - a sequence of the relative dimensions. - */ -std::vector MEDFileUMesh::getGrpsNonEmptyLevels(const std::vector& grps) const -{ - std::vector fams=getFamiliesOnGroups(grps); - return getFamsNonEmptyLevels(fams); -} - -/*! - * Returns all relative mesh levels (including nodes) where given groups are defined. - * \param [in] grps - a sequence of names of the groups of interest. - * \return std::vector - a sequence of the relative dimensions. - */ -std::vector MEDFileUMesh::getGrpsNonEmptyLevelsExt(const std::vector& grps) const -{ - std::vector fams=getFamiliesOnGroups(grps); - return getFamsNonEmptyLevelsExt(fams); -} - /*! * Returns all relative mesh levels (**excluding nodes**) where given families are defined. * To include nodes, call getFamsNonEmptyLevelsExt() method. * \param [in] fams - the name of the family of interest. * \return std::vector - a sequence of the relative dimensions. */ -std::vector MEDFileUMesh::getFamsNonEmptyLevels(const std::vector& fams) const +std::vector MEDFileUMesh::getFamsNonEmptyLevels(const std::vector& fams) const { - std::vector ret; - std::vector levs=getNonEmptyLevels(); - std::vector famIds=getFamiliesIds(fams); + std::vector ret; + std::vector levs(getNonEmptyLevels()); + std::vector famIds(getFamiliesIds(fams)); for(std::vector::const_iterator it=levs.begin();it!=levs.end();it++) if(_ms[-(*it)]->presenceOfOneFams(famIds)) ret.push_back(*it); @@ -2759,16 +3177,16 @@ std::vector MEDFileUMesh::getFamsNonEmptyLevels(const std::vector - a sequence of the relative dimensions. */ -std::vector MEDFileUMesh::getFamsNonEmptyLevelsExt(const std::vector& fams) const +std::vector MEDFileUMesh::getFamsNonEmptyLevelsExt(const std::vector& fams) const { - std::vector ret0=getFamsNonEmptyLevels(fams); - const DataArrayInt *famCoords=_fam_coords; + std::vector ret0(getFamsNonEmptyLevels(fams)); + const DataArrayIdType *famCoords(_fam_coords); if(!famCoords) return ret0; - std::vector famIds=getFamiliesIds(fams); + std::vector famIds(getFamiliesIds(fams)); if(famCoords->presenceOfValue(famIds)) { - std::vector ret(ret0.size()+1); + std::vector ret(ret0.size()+1); ret[0]=1; std::copy(ret0.begin(),ret0.end(),ret.begin()+1); return ret; @@ -2777,41 +3195,22 @@ std::vector MEDFileUMesh::getFamsNonEmptyLevelsExt(const std::vector - a sequence of group names at \a meshDimRelToMaxExt - * level. - */ -std::vector MEDFileUMesh::getGroupsOnSpecifiedLev(int meshDimRelToMaxExt) const -{ - std::vector ret; - std::vector allGrps=getGroupsNames(); - for(std::vector::const_iterator it=allGrps.begin();it!=allGrps.end();it++) - { - std::vector levs=getGrpNonEmptyLevelsExt((*it)); - if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)!=levs.end()) - ret.push_back(*it); - } - return ret; -} - -int MEDFileUMesh::getMaxAbsFamilyIdInArrays() const +mcIdType MEDFileUMesh::getMaxAbsFamilyIdInArrays() const { - int ret=-std::numeric_limits::max(),tmp=-1; - if((const DataArrayInt *)_fam_coords) + mcIdType ret=-std::numeric_limits::max(),tmp=-1; + if((const DataArrayIdType *)_fam_coords) { - int val=_fam_coords->getMaxValue(tmp); + mcIdType val=_fam_coords->getMaxValue(tmp); ret=std::max(ret,std::abs(val)); } - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++) + for(std::vector< MCAuto >::const_iterator it=_ms.begin();it!=_ms.end();it++) { if((const MEDFileUMeshSplitL1 *)(*it)) { - const DataArrayInt *da=(*it)->getFamilyField(); + const DataArrayIdType *da=(*it)->getFamilyField(); if(da) { - int val=da->getMaxValue(tmp); + mcIdType val=da->getMaxValue(tmp); ret=std::max(ret,std::abs(val)); } } @@ -2819,22 +3218,22 @@ int MEDFileUMesh::getMaxAbsFamilyIdInArrays() const return ret; } -int MEDFileUMesh::getMaxFamilyIdInArrays() const +mcIdType MEDFileUMesh::getMaxFamilyIdInArrays() const { - int ret=-std::numeric_limits::max(),tmp=-1; - if((const DataArrayInt *)_fam_coords) + mcIdType ret=-std::numeric_limits::max(),tmp=-1; + if((const DataArrayIdType *)_fam_coords) { - int val=_fam_coords->getMaxValue(tmp); + mcIdType val=_fam_coords->getMaxValue(tmp); ret=std::max(ret,val); } - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++) + for(std::vector< MCAuto >::const_iterator it=_ms.begin();it!=_ms.end();it++) { if((const MEDFileUMeshSplitL1 *)(*it)) { - const DataArrayInt *da=(*it)->getFamilyField(); + const DataArrayIdType *da=(*it)->getFamilyField(); if(da) { - int val=da->getMaxValue(tmp); + mcIdType val=da->getMaxValue(tmp); ret=std::max(ret,val); } } @@ -2842,22 +3241,22 @@ int MEDFileUMesh::getMaxFamilyIdInArrays() const return ret; } -int MEDFileUMesh::getMinFamilyIdInArrays() const +mcIdType MEDFileUMesh::getMinFamilyIdInArrays() const { - int ret=std::numeric_limits::max(),tmp=-1; - if((const DataArrayInt *)_fam_coords) + mcIdType ret=std::numeric_limits::max(),tmp=-1; + if((const DataArrayIdType *)_fam_coords) { - int val=_fam_coords->getMinValue(tmp); + mcIdType val=_fam_coords->getMinValue(tmp); ret=std::min(ret,val); } - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++) + for(std::vector< MCAuto >::const_iterator it=_ms.begin();it!=_ms.end();it++) { if((const MEDFileUMeshSplitL1 *)(*it)) { - const DataArrayInt *da=(*it)->getFamilyField(); + const DataArrayIdType *da=(*it)->getFamilyField(); if(da) { - int val=da->getMinValue(tmp); + mcIdType val=da->getMinValue(tmp); ret=std::min(ret,val); } } @@ -2873,7 +3272,7 @@ int MEDFileUMesh::getMinFamilyIdInArrays() const int MEDFileUMesh::getMeshDimension() const { int lev=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev++) + for(std::vector< MCAuto >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev++) if((const MEDFileUMeshSplitL1 *)(*it)!=0) return (*it)->getMeshDimension()+lev; throw INTERP_KERNEL::Exception("MEDFileUMesh::getMeshDimension : impossible to find a mesh dimension !"); @@ -2890,7 +3289,7 @@ int MEDFileUMesh::getSpaceDimension() const const DataArrayDouble *coo=_coords; if(!coo) throw INTERP_KERNEL::Exception(" MEDFileUMesh::getSpaceDimension : no coords set !"); - return coo->getNumberOfComponents(); + return (int)coo->getNumberOfComponents(); } /*! @@ -2942,6 +3341,7 @@ std::string MEDFileUMesh::simpleRepr() const } oss << std::endl << std::endl; getFamilyRepr(oss); + getEquivalencesRepr(oss); return oss.str(); } @@ -2957,10 +3357,10 @@ std::string MEDFileUMesh::advancedRepr() const /*! * Returns number of mesh entities of a given relative dimension in \a this mesh. * \param [in] meshDimRelToMaxExt - the relative dimension of interest. - * \return int - the number of entities. + * \return mcIdType - the number of entities. * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh. */ -int MEDFileUMesh::getSizeAtLevel(int meshDimRelToMaxExt) const +mcIdType MEDFileUMesh::getSizeAtLevel(int meshDimRelToMaxExt) const { if(meshDimRelToMaxExt==1) { @@ -2974,10 +3374,10 @@ int MEDFileUMesh::getSizeAtLevel(int meshDimRelToMaxExt) const /*! * Returns the family field for mesh entities of a given dimension. * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities. - * \return const DataArrayInt * - the family field. It is an array of ids of families + * \return const DataArrayIdType * - the family field. It is an array of ids of families * each mesh entity belongs to. It can be \c NULL. */ -const DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const +const DataArrayIdType *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const { if(meshDimRelToMaxExt==1) return _fam_coords; @@ -2985,7 +3385,7 @@ const DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) return l1->getFamilyField(); } -DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) +DataArrayIdType *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) { if(meshDimRelToMaxExt==1) return _fam_coords; @@ -2996,10 +3396,10 @@ DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) /*! * Returns the optional numbers of mesh entities of a given dimension. * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities. - * \return const DataArrayInt * - the array of the entity numbers. + * \return const DataArrayIdType * - the array of the entity numbers. * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh. */ -const DataArrayInt *MEDFileUMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const +const DataArrayIdType *MEDFileUMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const { if(meshDimRelToMaxExt==1) return _num_coords; @@ -3015,6 +3415,13 @@ const DataArrayAsciiChar *MEDFileUMesh::getNameFieldAtLevel(int meshDimRelToMaxE return l1->getNameField(); } +MCAuto MEDFileUMesh::getGlobalNumFieldAtLevel(int meshDimRelToMaxExt) const +{ + if(meshDimRelToMaxExt!=1) + throw INTERP_KERNEL::Exception("MEDFileUMesh::getGlobalNumFieldAtLevel : not implemented yet for structured mesh !"); + return _global_num_coords; +} + /*! * 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). * @@ -3030,7 +3437,7 @@ const PartDefinition *MEDFileUMesh::getPartDefAtLevel(int meshDimRelToMaxExt, IN return l1->getPartDef(gt); } -int MEDFileUMesh::getNumberOfNodes() const +mcIdType MEDFileUMesh::getNumberOfNodes() const { const DataArrayDouble *coo(_coords); if(!coo) @@ -3038,7 +3445,7 @@ int MEDFileUMesh::getNumberOfNodes() const return coo->getNumberOfTuples(); } -int MEDFileUMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const +mcIdType MEDFileUMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const { const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt)); return l1->getNumberOfCells(); @@ -3049,7 +3456,7 @@ bool MEDFileUMesh::hasImplicitPart() const return false; } -int MEDFileUMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const +mcIdType MEDFileUMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const { throw INTERP_KERNEL::Exception("MEDFileUMesh::buildImplicitPartIfAny : unstructured meshes do not have implicit part !"); } @@ -3069,30 +3476,66 @@ void MEDFileUMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, con m->computeNodeIdsAlg(nodesFetched); else { - const DataArrayInt *arr(globs->getProfile(st[i].getPflName())); - MEDCouplingAutoRefCountObjectPtr m2(dynamic_cast(m->buildPartOfMySelf(arr->begin(),arr->end(),true))); + const DataArrayIdType *arr(globs->getProfile(st[i].getPflName())); + MCAuto m2(dynamic_cast(m->buildPartOfMySelf(arr->begin(),arr->end(),true))); m2->computeNodeIdsAlg(nodesFetched); } } } +MEDFileMesh *MEDFileUMesh::cartesianize() const +{ + if(getAxisType()==AX_CART) + { + incrRef(); + return const_cast(this); + } + else + { + MCAuto ret(new MEDFileUMesh(*this)); + const DataArrayDouble *coords(_coords); + if(!coords) + throw INTERP_KERNEL::Exception("MEDFileUMesh::cartesianize : coordinates are null !"); + MCAuto coordsCart(_coords->cartesianize(getAxisType())); + for(std::vector< MCAuto >::iterator it=ret->_ms.begin();it!=ret->_ms.end();it++) + if((const MEDFileUMeshSplitL1 *)(*it)) + *it=(*it)->shallowCpyUsingCoords(coordsCart); + ret->_coords=coordsCart; + ret->setAxisType(AX_CART); + return ret.retn(); + } +} + +bool MEDFileUMesh::presenceOfStructureElements() const +{ + for(std::vector< MCAuto >::const_iterator it=_elt_str.begin();it!=_elt_str.end();it++) + if((*it).isNotNull()) + return true; + return false; +} + +void MEDFileUMesh::killStructureElements() +{ + _elt_str.clear(); +} + /*! * Returns the optional numbers of mesh entities of a given dimension transformed using - * DataArrayInt::invertArrayN2O2O2N(). + * DataArrayIdType::invertArrayN2O2O2N(). * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities. - * \return const DataArrayInt * - the array of the entity numbers transformed using - * DataArrayInt::invertArrayN2O2O2N(). + * \return const DataArrayIdType * - the array of the entity numbers transformed using + * DataArrayIdType::invertArrayN2O2O2N(). * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh. */ -const DataArrayInt *MEDFileUMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const +const DataArrayIdType *MEDFileUMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const { if(meshDimRelToMaxExt==1) { - if(!((const DataArrayInt *)_num_coords)) + if(_num_coords.isNull()) throw INTERP_KERNEL::Exception("MEDFileUMesh::getRevNumberFieldAtLevel : no coordinates renum specified !"); return _rev_num_coords; } - const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt); + const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt)); return l1->getRevNumberField(); } @@ -3102,7 +3545,8 @@ const DataArrayInt *MEDFileUMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxEx */ DataArrayDouble *MEDFileUMesh::getCoords() const { - MEDCouplingAutoRefCountObjectPtr tmp(_coords); + checkCartesian(); + MCAuto tmp(_coords); if((DataArrayDouble *)tmp) { return tmp; @@ -3126,6 +3570,7 @@ DataArrayDouble *MEDFileUMesh::getCoords() const */ MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const std::string& grp, bool renum) const { + checkCartesian(); synchronizeTinyInfoOnLeaves(); std::vector tmp(1); tmp[0]=grp; @@ -3148,9 +3593,10 @@ MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const std::stri */ MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vector& grps, bool renum) const { + checkCartesian(); synchronizeTinyInfoOnLeaves(); std::vector fams2=getFamiliesOnGroups(grps); - MEDCouplingAutoRefCountObjectPtr zeRet=getFamilies(meshDimRelToMaxExt,fams2,renum); + MCAuto zeRet=getFamilies(meshDimRelToMaxExt,fams2,renum); if(grps.size()==1 && ((MEDCouplingUMesh *)zeRet)) zeRet->setName(grps[0]); return zeRet.retn(); @@ -3172,6 +3618,7 @@ MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vec */ MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const std::string& fam, bool renum) const { + checkCartesian(); synchronizeTinyInfoOnLeaves(); std::vector tmp(1); tmp[0]=fam; @@ -3194,18 +3641,19 @@ MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const std::str */ MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::vector& fams, bool renum) const { + checkCartesian(); synchronizeTinyInfoOnLeaves(); if(meshDimRelToMaxExt==1) { - MEDCouplingAutoRefCountObjectPtr arr=getFamiliesArr(1,fams,renum); - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingUMesh::New(); - MEDCouplingAutoRefCountObjectPtr c=_coords->selectByTupleId(arr->getConstPointer(),arr->getConstPointer()+arr->getNbOfElems()); + MCAuto arr=getFamiliesArr(1,fams,renum); + MCAuto ret=MEDCouplingUMesh::New(); + MCAuto c=_coords->selectByTupleId(arr->getConstPointer(),arr->getConstPointer()+arr->getNbOfElems()); ret->setCoords(c); return ret.retn(); } - std::vector famIds=getFamiliesIds(fams); + std::vector famIds=getFamiliesIds(fams); const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt); - MEDCouplingAutoRefCountObjectPtr zeRet; + MCAuto zeRet; if(!famIds.empty()) zeRet=l1->getFamilyPart(&famIds[0],&famIds[0]+famIds.size(),renum); else @@ -3222,23 +3670,23 @@ MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::v * \param [in] fams - the names of the families of interest. * \param [in] renum - if \c true, the optional numbers of entities, if available, are * returned instead of ids. - * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or + * \return DataArrayIdType * - a new instance of DataArrayIdType holding either ids or * numbers, if available and required, of mesh entities of the families. The caller * is to delete this array using decrRef() as it is no more needed. * \throw If the family field is missing for \a meshDimRelToMaxExt. */ -DataArrayInt *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector& fams, bool renum) const +DataArrayIdType *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector& fams, bool renum) const { - std::vector famIds=getFamiliesIds(fams); + std::vector famIds=getFamiliesIds(fams); if(meshDimRelToMaxExt==1) { - if((const DataArrayInt *)_fam_coords) + if((const DataArrayIdType *)_fam_coords) { - MEDCouplingAutoRefCountObjectPtr da; + MCAuto da; if(!famIds.empty()) - da=_fam_coords->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size()); + da=_fam_coords->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size()); else - da=_fam_coords->getIdsEqualList(0,0); + da=_fam_coords->findIdsEqualList(0,0); if(renum) return MEDFileUMeshSplitL1::Renumber(_num_coords,da); else @@ -3260,23 +3708,23 @@ DataArrayInt *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::ve * valid**. This is a feature, because MEDLoader does not create cells that do not exist! * To build a valid MEDCouplingUMesh from the returned one in this case, * call MEDCouplingUMesh::Build0DMeshFromCoords(). - * \param [in] meshDimRelToMax - the relative dimension of interest. + * \param [in] meshDimRelToMaxExt - the relative dimension of interest. * \param [in] renum - if \c true, the returned mesh is permuted according to the * optional numbers of mesh entities. * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to * delete using decrRef() as it is no more needed. * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh. - * \sa getGenMeshAtLevel() */ MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renum) const { + checkCartesian(); synchronizeTinyInfoOnLeaves(); if(meshDimRelToMaxExt==1) { if(!renum) { MEDCouplingUMesh *umesh=MEDCouplingUMesh::New(); - MEDCouplingAutoRefCountObjectPtr cc=_coords->deepCpy(); + MCAuto cc=_coords->deepCopy(); umesh->setCoords(cc); MEDFileUMeshSplitL1::ClearNonDiscrAttributes(umesh); umesh->setName(getName()); @@ -3287,26 +3735,7 @@ MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renu return l1->getWholeMesh(renum); } -/*! - * Returns a MEDCouplingUMesh of a given relative dimension. - * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not - * valid**. This is a feature, because MEDLoader does not create cells that do not exist! - * To build a valid MEDCouplingUMesh from the returned one in this case, - * call MEDCouplingUMesh::Build0DMeshFromCoords(). - * \param [in] meshDimRelToMax - the relative dimension of interest. - * \param [in] renum - if \c true, the returned mesh is permuted according to the - * optional numbers of mesh entities. - * \return MEDCouplingMesh * - a pointer to MEDCouplingUMesh that the caller is to - * delete using decrRef() as it is no more needed. - * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a this mesh. - * \sa getMeshAtLevel() - */ -MEDCouplingMesh *MEDFileUMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const -{ - return getMeshAtLevel(meshDimRelToMax,renum); -} - -std::vector MEDFileUMesh::getDistributionOfTypes(int meshDimRelToMax) const +std::vector MEDFileUMesh::getDistributionOfTypes(int meshDimRelToMax) const { const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMax)); return l1->getDistributionOfTypes(); @@ -3367,12 +3796,12 @@ MEDCouplingUMesh *MEDFileUMesh::getLevelM3Mesh(bool renum) const /*! * This method is for advanced users. There is two storing strategy of mesh in \a this. * Either MEDCouplingUMesh, or vector of MEDCoupling1GTUMesh instances. - * When assignement is done the first one is done, which is not optimal in write mode for MED file. + * When assignment is done the first one is done, which is not optimal in write mode for MED file. * This method allows to switch from MEDCouplingUMesh mode to MEDCoupling1GTUMesh mode. */ void MEDFileUMesh::forceComputationOfParts() const { - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++) + for(std::vector< MCAuto >::const_iterator it=_ms.begin();it!=_ms.end();it++) { const MEDFileUMeshSplitL1 *elt(*it); if(elt) @@ -3388,6 +3817,7 @@ void MEDFileUMesh::forceComputationOfParts() const */ std::vector MEDFileUMesh::getDirectUndergroundSingleGeoTypeMeshes(int meshDimRelToMax) const { + checkCartesian(); const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax)); return sp->getDirectUndergroundSingleGeoTypeMeshes(); } @@ -3399,12 +3829,37 @@ std::vector MEDFileUMesh::getDirectUndergroundSingleGeoTy */ MEDCoupling1GTUMesh *MEDFileUMesh::getDirectUndergroundSingleGeoTypeMesh(INTERP_KERNEL::NormalizedCellType gt) const { - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt); + checkCartesian(); + const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(gt)); int lev=(int)cm.getDimension()-getMeshDimension(); const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev)); return sp->getDirectUndergroundSingleGeoTypeMesh(gt); } +/*! + * This method returns for each geo types in \a this number of cells with this geo type. + * This method returns info as a vector of pair. The first element of pair is geo type and the second the number of cells associated. + * This method also returns the number of nodes of \a this (key associated is NORM_ERROR) + * + * \sa getDistributionOfTypes + */ +std::vector< std::pair > MEDFileUMesh::getAllDistributionOfTypes() const +{ + std::vector< std::pair > ret; + std::vector nel(getNonEmptyLevels()); + for(std::vector::reverse_iterator it=nel.rbegin();it!=nel.rend();it++) + { + std::vector gt(getGeoTypesAtLevel(*it)); + for(std::vector::const_iterator it1=gt.begin();it1!=gt.end();it1++) + { + mcIdType nbCells(getNumberOfCellsWithType(*it1)); + ret.push_back(std::pair(*it1,nbCells)); + } + } + ret.push_back(std::pair(INTERP_KERNEL::NORM_ERROR,getNumberOfNodes())); + return ret; +} + /*! * Given a relative level \a meshDimRelToMax it returns the sorted vector of geometric types present in \a this. * \throw if the reqsuested \a meshDimRelToMax does not exist. @@ -3415,14 +3870,21 @@ std::vector MEDFileUMesh::getGeoTypesAtLevel( return sp->getGeoTypes(); } +mcIdType MEDFileUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const +{ + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(ct); + const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe( ((int)cm.getDimension())-getMeshDimension() )); + return sp->getNumberOfCellsWithType(ct); +} + /*! * This method extracts from whole family field ids the part relative to the input parameter \a gt. * \param [in] gt - the geometric type for which the family field is asked. - * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to + * \return DataArrayIdType * - a pointer to DataArrayIdType that the caller is to * delete using decrRef() as it is no more needed. * \sa MEDFileUMesh::extractNumberFieldOnGeoType */ -DataArrayInt *MEDFileUMesh::extractFamilyFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const +DataArrayIdType *MEDFileUMesh::extractFamilyFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const { const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt); int lev=(int)cm.getDimension()-getMeshDimension(); @@ -3433,11 +3895,11 @@ DataArrayInt *MEDFileUMesh::extractFamilyFieldOnGeoType(INTERP_KERNEL::Normalize /*! * This method extracts from whole number field ids the part relative to the input parameter \a gt. * \param [in] gt - the geometric type for which the number field is asked. - * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to + * \return DataArrayIdType * - a pointer to DataArrayIdType that the caller is to * delete using decrRef() as it is no more needed. * \sa MEDFileUMesh::extractFamilyFieldOnGeoType */ -DataArrayInt *MEDFileUMesh::extractNumberFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const +DataArrayIdType *MEDFileUMesh::extractNumberFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const { const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt); int lev=(int)cm.getDimension()-getMeshDimension(); @@ -3490,7 +3952,7 @@ void MEDFileUMesh::checkMeshDimCoherency(int meshDim, int meshDimRelToMax) const if(-meshDimRelToMax>=(int)_ms.size()) throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : The meshdim of mesh is not managed by 'this' !"); int i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++) + for(std::vector< MCAuto >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++) { if(((const MEDFileUMeshSplitL1*) (*it))!=0) { @@ -3510,14 +3972,45 @@ void MEDFileUMesh::setCoords(DataArrayDouble *coords) { if(!coords) throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoords : null pointer in input !"); + if(coords==(DataArrayDouble *)_coords) + return ; coords->checkAllocated(); - int nbOfTuples=coords->getNumberOfTuples(); - _coords=coords; - coords->incrRef(); - _fam_coords=DataArrayInt::New(); + mcIdType nbOfTuples(coords->getNumberOfTuples()); + _coords.takeRef(coords); + _fam_coords=DataArrayIdType::New(); _fam_coords->alloc(nbOfTuples,1); _fam_coords->fillWithZero(); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_ms.begin();it!=_ms.end();it++) + _num_coords.nullify(); _rev_num_coords.nullify(); _name_coords.nullify(); _global_num_coords.nullify(); + for(std::vector< MCAuto >::iterator it=_ms.begin();it!=_ms.end();it++) + if((MEDFileUMeshSplitL1 *)(*it)) + (*it)->setCoords(coords); +} + +/*! + * Change coords without changing anything concerning families and numbering on nodes. + */ +void MEDFileUMesh::setCoordsForced(DataArrayDouble *coords) +{ + if(!coords) + throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoordsForced : null pointer in input !"); + if(coords==(DataArrayDouble *)_coords) + return ; + coords->checkAllocated(); + mcIdType nbOfTuples(coords->getNumberOfTuples()); + if(_coords.isNull()) + { + _coords=coords; + coords->incrRef(); + } + else + { + mcIdType oldNbTuples(_coords->getNumberOfTuples()); + if(oldNbTuples!=nbOfTuples) + throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoordsForced : number of tuples is not the same -> invoke setCoords instead !"); + _coords=coords; + coords->incrRef(); + } + for(std::vector< MCAuto >::iterator it=_ms.begin();it!=_ms.end();it++) if((MEDFileUMeshSplitL1 *)(*it)) (*it)->setCoords(coords); } @@ -3531,7 +4024,7 @@ void MEDFileUMesh::eraseGroupsAtLevel(int meshDimRelToMaxExt) { if(meshDimRelToMaxExt==1) { - if((DataArrayInt *)_fam_coords) + if((DataArrayIdType *)_fam_coords) _fam_coords->fillWithZero(); return ; } @@ -3546,17 +4039,17 @@ void MEDFileUMesh::eraseGroupsAtLevel(int meshDimRelToMaxExt) void MEDFileUMesh::optimizeFamilies() { std::vector levs=getNonEmptyLevelsExt(); - std::set allFamsIds; + std::set allFamsIds; for(std::vector::const_iterator it=levs.begin();it!=levs.end();it++) { - const DataArrayInt *ffield=getFamilyFieldAtLevel(*it); - MEDCouplingAutoRefCountObjectPtr ids=ffield->getDifferentValues(); - std::set res; + const DataArrayIdType *ffield=getFamilyFieldAtLevel(*it); + MCAuto ids=ffield->getDifferentValues(); + std::set res; std::set_union(ids->begin(),ids->end(),allFamsIds.begin(),allFamsIds.end(),std::inserter(res,res.begin())); allFamsIds=res; } std::set famNamesToKill; - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) + for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) { if(allFamsIds.find((*it).second)!=allFamsIds.end()) famNamesToKill.insert((*it).first); @@ -3583,83 +4076,102 @@ void MEDFileUMesh::optimizeFamilies() /** * \b this must be filled at level 0 and -1, typically the -1 level being (part of) the descending connectivity - * of the top level. This method build a "crack" in \b this along the group of level -1 named grpNameM1. - * The "crack" is built according to the following method: - * - all nodes along the crack which are not lying on an internal extremity of the crack are duplicated (so the - * coordinates array is extended). The - * - new (-1)-level cells are built lying on those new nodes. So the edges/faces along the crack are duplicated. - * After this operation a top-level cell bordering the crack will loose some neighbor (typically the cell which is on the - * other side of the crack is no more a neighbor) - * - finally, the connectivity of (part of) the top level-cells bordering the crack is also modified so that some cells - * bordering the crack use the newly computed nodes. + * of the top level. This method build a "crack", or an inner boundary, in \b this along the group of level -1 named grpNameM1. + * The boundary is built according to the following method: + * - all nodes along the boundary which are not lying on an internal extremity of the (-1)-level group are duplicated (so the + * coordinates array is extended). + * - new (-1)-level cells are built lying on those new nodes. So the edges/faces along the group are duplicated. A new group + * called "_dup" containing the effectively duplicated cells is created. Note that in 3D some cells of the group + * might not be duplicated at all. + * After this operation a top-level cell bordering the group will loose some neighbors (typically the cell which is on the + * other side of the group is no more a neighbor) + * - finally, the connectivity of (part of) the top level-cells bordering the group is also modified so that some cells + * bordering the newly created boundary use the newly computed nodes. + * Finally note that optional cell numbers are also affected by this method and might become invalid for SMESH. + * Use clearNodeAndCellNumbers() afterwards to ensure a proper SMESH loading. * - * \param[in] grpNameM1 name of the (-1)-level group defining the crack + * \param[in] grpNameM1 name of the (-1)-level group defining the boundary * \param[out] nodesDuplicated ids of the initial nodes which have been duplicated (and whose copy is put at the end of * the coord array) * \param[out] cellsModified ids of the cells whose connectivity has been modified (to use the newly created nodes) - * \param[out] cellsNotModified ids of the rest of cells bordering the crack whose connectivity remains unchanged. + * \param[out] cellsNotModified ids of the rest of cells bordering the new boundary whose connectivity remains unchanged. + * \sa clearNodeAndCellNumbers() */ -void MEDFileUMesh::duplicateNodesOnM1Group(const std::string& grpNameM1, DataArrayInt *&nodesDuplicated, - DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified) +void MEDFileUMesh::buildInnerBoundaryAlongM1Group(const std::string& grpNameM1, DataArrayIdType *&nodesDuplicated, + DataArrayIdType *&cellsModified, DataArrayIdType *&cellsNotModified) { + typedef MCAuto MUMesh; + typedef MCAuto DAInt; + std::vector levs=getNonEmptyLevels(); if(std::find(levs.begin(),levs.end(),0)==levs.end() || std::find(levs.begin(),levs.end(),-1)==levs.end()) - throw INTERP_KERNEL::Exception("MEDFileUMesh::duplicateNodesOnM1Group : This method works only for mesh definied on level 0 and -1 !"); - MEDCouplingAutoRefCountObjectPtr m0=getMeshAtLevel(0); - MEDCouplingAutoRefCountObjectPtr m1=getMeshAtLevel(-1); - int nbNodes=m0->getNumberOfNodes(); - MEDCouplingAutoRefCountObjectPtr m11=getGroup(-1,grpNameM1); - DataArrayInt *tmp00=0,*tmp11=0,*tmp22=0; + throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group : This method works only for mesh defined on level 0 and -1 !"); + MUMesh m0=getMeshAtLevel(0); + MUMesh m1=getMeshAtLevel(-1); + mcIdType nbNodes=m0->getNumberOfNodes(); + MUMesh m11=getGroup(-1,grpNameM1); + DataArrayIdType *tmp00=0,*tmp11=0,*tmp22=0; m0->findNodesToDuplicate(*m11,tmp00,tmp11,tmp22); - MEDCouplingAutoRefCountObjectPtr nodeIdsToDuplicate(tmp00); - MEDCouplingAutoRefCountObjectPtr cellsToModifyConn0(tmp11); - MEDCouplingAutoRefCountObjectPtr cellsToModifyConn1(tmp22); - MEDCouplingAutoRefCountObjectPtr tmp0=static_cast(m0->buildPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),true)); + DAInt nodeIdsToDuplicate(tmp00); + DAInt cellsToModifyConn0(tmp11); + DAInt cellsToModifyConn1(tmp22); + MUMesh tmp0=static_cast(m0->buildPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),true)); // node renumbering of cells in m1 impacted by duplication of node but not in group 'grpNameM1' on level -1 - MEDCouplingAutoRefCountObjectPtr descTmp0=DataArrayInt::New(),descITmp0=DataArrayInt::New(),revDescTmp0=DataArrayInt::New(),revDescITmp0=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr tmp0Desc=tmp0->buildDescendingConnectivity(descTmp0,descITmp0,revDescTmp0,revDescITmp0); + DAInt descTmp0=DataArrayIdType::New(),descITmp0=DataArrayIdType::New(),revDescTmp0=DataArrayIdType::New(),revDescITmp0=DataArrayIdType::New(); + MUMesh tmp0Desc=tmp0->buildDescendingConnectivity(descTmp0,descITmp0,revDescTmp0,revDescITmp0); descTmp0=0; descITmp0=0; revDescTmp0=0; revDescITmp0=0; - MEDCouplingAutoRefCountObjectPtr cellsInM1ToRenumW2=tmp0Desc->getCellIdsLyingOnNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),false); - MEDCouplingAutoRefCountObjectPtr cellsInM1ToRenumW3=static_cast(tmp0Desc->buildPartOfMySelf(cellsInM1ToRenumW2->begin(),cellsInM1ToRenumW2->end(),true)); - DataArrayInt *cellsInM1ToRenumW4Tmp=0; + DAInt cellsInM1ToRenumW2=tmp0Desc->getCellIdsLyingOnNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),false); + MUMesh cellsInM1ToRenumW3=static_cast(tmp0Desc->buildPartOfMySelf(cellsInM1ToRenumW2->begin(),cellsInM1ToRenumW2->end(),true)); + DataArrayIdType *cellsInM1ToRenumW4Tmp=0; m1->areCellsIncludedIn(cellsInM1ToRenumW3,2,cellsInM1ToRenumW4Tmp); - MEDCouplingAutoRefCountObjectPtr cellsInM1ToRenumW4(cellsInM1ToRenumW4Tmp); - MEDCouplingAutoRefCountObjectPtr cellsInM1ToRenumW5=cellsInM1ToRenumW4->getIdsInRange(0,m1->getNumberOfCells()); + DAInt cellsInM1ToRenumW4(cellsInM1ToRenumW4Tmp); + DAInt cellsInM1ToRenumW5=cellsInM1ToRenumW4->findIdsInRange(0,m1->getNumberOfCells()); cellsInM1ToRenumW5->transformWithIndArr(cellsInM1ToRenumW4->begin(),cellsInM1ToRenumW4->end()); - MEDCouplingAutoRefCountObjectPtr grpIds=getGroupArr(-1,grpNameM1); - MEDCouplingAutoRefCountObjectPtr cellsInM1ToRenum=cellsInM1ToRenumW5->buildSubstraction(grpIds); - MEDCouplingAutoRefCountObjectPtr m1Part=static_cast(m1->buildPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),true)); + DAInt grpIds=getGroupArr(-1,grpNameM1); + DAInt cellsInM1ToRenum=cellsInM1ToRenumW5->buildSubstraction(grpIds); + MUMesh m1Part=static_cast(m1->buildPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),true)); m1Part->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes); m1->setPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),*m1Part); // end of node renumbering of cells in m1 impacted by duplication of node but not in group of level -1 'grpNameM1' tmp0->duplicateNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end()); m0->setCoords(tmp0->getCoords()); m0->setPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),*tmp0); + _ms[0]->forceComputationOfParts(); // necessary because we modify the connectivity of some internal part m1->setCoords(m0->getCoords()); _coords=m0->getCoords(); _coords->incrRef(); - // duplication of cells in group 'grpNameM1' on level -1 + // duplication of cells in group 'grpNameM1' on level -1, but not duplicating cells for which nothing has changed m11->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes); m11->setCoords(m0->getCoords()); - std::vector v(2); v[0]=m1; v[1]=m11; - MEDCouplingAutoRefCountObjectPtr newm1=MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(v,tmp00,tmp11); - MEDCouplingAutoRefCountObjectPtr szOfCellGrpOfSameType(tmp00); - MEDCouplingAutoRefCountObjectPtr idInMsOfCellGrpOfSameType(tmp11); + DataArrayIdType * duplCells; + m1->areCellsIncludedIn(m11, 0, duplCells); + DAInt zeIds = duplCells->findIdsNotInRange(-1, m1->getNumberOfCells()-1); duplCells->decrRef(); + MUMesh m11Part=static_cast(m11->buildPartOfMySelf(zeIds->begin(),zeIds->end(),true)); + std::vector v(2); v[0]=m1; v[1]=m11Part; + MUMesh newm1=MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(v,tmp00,tmp11); + DAInt szOfCellGrpOfSameType(tmp00); + DAInt idInMsOfCellGrpOfSameType(tmp11); // newm1->setName(getName()); - const DataArrayInt *fam=getFamilyFieldAtLevel(-1); + const DataArrayIdType *fam=getFamilyFieldAtLevel(-1); if(!fam) - throw INTERP_KERNEL::Exception("MEDFileUMesh::duplicateNodesOnM1Group : internal problem !"); - MEDCouplingAutoRefCountObjectPtr newFam=DataArrayInt::New(); + throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group(): internal error no family field !"); + DAInt newFam=DataArrayIdType::New(); newFam->alloc(newm1->getNumberOfCells(),1); - int idd=getMaxFamilyId()+1; - int globStart=0,start=0,end,globEnd; - int nbOfChunks=szOfCellGrpOfSameType->getNumberOfTuples(); - for(int i=0;igetMeshDimension() == 0) + idd=getMaxFamilyId()+1; + else + idd=getMinFamilyId()-1; + mcIdType globStart=0,start=0,end,globEnd; + mcIdType nbOfChunks=szOfCellGrpOfSameType->getNumberOfTuples(); + for(mcIdType i=0;igetIJ(i,0); if(idInMsOfCellGrpOfSameType->getIJ(i,0)==0) { end=start+szOfCellGrpOfSameType->getIJ(i,0); - MEDCouplingAutoRefCountObjectPtr part=fam->selectByTupleId2(start,end,1); + DAInt part=fam->selectByTupleIdSafeSlice(start,end,1); newFam->setPartOfValues1(part,globStart,globEnd,1,0,1,1,true); start=end; } @@ -3679,69 +4191,81 @@ void MEDFileUMesh::duplicateNodesOnM1Group(const std::string& grpNameM1, DataArr fam=_fam_coords; if(fam) { - int newNbOfNodes=getCoords()->getNumberOfTuples(); - newFam=DataArrayInt::New(); newFam->alloc(newNbOfNodes,1); + mcIdType newNbOfNodes=getCoords()->getNumberOfTuples(); + newFam=DataArrayIdType::New(); newFam->alloc(newNbOfNodes,1); newFam->setPartOfValues1(fam,0,nbNodes,1,0,1,1,true); newFam->setPartOfValuesSimple1(0,nbNodes,newNbOfNodes,1,0,1,1); _fam_coords=newFam; } + + _num_coords.nullify(); _rev_num_coords.nullify(); _global_num_coords.nullify(); + + for (std::vector< MCAuto >::iterator it=_ms.begin(); + it != _ms.end(); it++) + { + (*it)->_num = 0; + (*it)->_rev_num = 0; + } nodesDuplicated=nodeIdsToDuplicate.retn(); cellsModified=cellsToModifyConn0.retn(); cellsNotModified=cellsToModifyConn1.retn(); } -/*! +/*! Similar to MEDCouplingUMesh::unPolyze(): converts all polygons (if \a this is a 2D mesh) or polyhedrons + * (if \a this is a 3D mesh) to cells of classical types. The cells remain correctly sorted by geometric type + * in this method. + * * \param [out] oldCode retrieves the distribution of types before the call if true is returned - * \param [out] newCode etrieves the distribution of types after the call if true is returned + * \param [out] newCode retrieves the distribution of types after the call if true is returned * \param [out] o2nRenumCell tells for **all levels** the old 2 new renumbering of cells. * * \return false if no modification has been performed linked to the unpolyzation. Neither cell type, not cell numbers. When false is returned no need of field on cells or on gauss renumbering. * Inversely, if true is returned, it means that distribution of cell by geometric type has changed and field on cell and field on gauss point must be renumbered. */ -bool MEDFileUMesh::unPolyze(std::vector& oldCode, std::vector& newCode, DataArrayInt *& o2nRenumCell) +bool MEDFileUMesh::unPolyze(std::vector& oldCode, std::vector& newCode, DataArrayIdType *& o2nRenumCell) { o2nRenumCell=0; oldCode.clear(); newCode.clear(); std::vector levs=getNonEmptyLevels(); bool ret=false; - std::vector< const DataArrayInt* > renumCellsSplited;//same than memorySaverIfThrow - std::vector< MEDCouplingAutoRefCountObjectPtr > memorySaverIfThrow;//same than renumCellsSplited only in case of throw - int start=0; - int end=0; + std::vector< const DataArrayIdType* > renumCellsSplited;//same than memorySaverIfThrow + std::vector< MCAuto > memorySaverIfThrow;//same than renumCellsSplited only in case of throw + mcIdType start=0; + mcIdType end=0; for(std::vector::reverse_iterator it=levs.rbegin();it!=levs.rend();it++) { - MEDCouplingAutoRefCountObjectPtr m=getMeshAtLevel(*it); - std::vector code1=m->getDistributionOfTypes(); + MCAuto m=getMeshAtLevel(*it); + std::vector code1=m->getDistributionOfTypes(); end=PutInThirdComponentOfCodeOffset(code1,start); oldCode.insert(oldCode.end(),code1.begin(),code1.end()); bool hasChanged=m->unPolyze(); - DataArrayInt *fake=0; - MEDCouplingAutoRefCountObjectPtr o2nCellsPart=m->getLevArrPerCellTypes(MEDCouplingUMesh::MEDMEM_ORDER, + DataArrayIdType *fake=0; + MCAuto o2nCellsPart=m->getLevArrPerCellTypes(MEDCouplingUMesh::MEDMEM_ORDER, MEDCouplingUMesh::MEDMEM_ORDER+MEDCouplingUMesh::N_MEDMEM_ORDER,fake); fake->decrRef(); renumCellsSplited.push_back(o2nCellsPart); memorySaverIfThrow.push_back(o2nCellsPart); if(hasChanged) { - MEDCouplingAutoRefCountObjectPtr o2nCellsPart2=o2nCellsPart->buildPermArrPerLevel(); + MCAuto o2nCellsPart2=o2nCellsPart->buildPermArrPerLevel(); m->renumberCells(o2nCellsPart2->getConstPointer(),false); ret=true; - MEDCouplingAutoRefCountObjectPtr famField2,numField2; - const DataArrayInt *famField=getFamilyFieldAtLevel(*it); if(famField) { famField->incrRef(); famField2=const_cast(famField); } - const DataArrayInt *numField=getNumberFieldAtLevel(*it); if(numField) { numField->incrRef(); numField2=const_cast(numField); } + MCAuto famField2,numField2; + const DataArrayIdType *famField=getFamilyFieldAtLevel(*it); if(famField) { famField->incrRef(); famField2=const_cast(famField); } + const DataArrayIdType *numField=getNumberFieldAtLevel(*it); if(numField) { numField->incrRef(); numField2=const_cast(numField); } setMeshAtLevel(*it,m); - std::vector code2=m->getDistributionOfTypes(); + std::vector code2=m->getDistributionOfTypes(); end=PutInThirdComponentOfCodeOffset(code2,start); newCode.insert(newCode.end(),code2.begin(),code2.end()); // - if(o2nCellsPart2->isIdentity()) + if(o2nCellsPart2->isIota(o2nCellsPart2->getNumberOfTuples())) continue; if(famField) { - MEDCouplingAutoRefCountObjectPtr newFamField=famField->renumber(o2nCellsPart2->getConstPointer()); + MCAuto newFamField=famField->renumber(o2nCellsPart2->getConstPointer()); setFamilyFieldArr(*it,newFamField); } if(numField) { - MEDCouplingAutoRefCountObjectPtr newNumField=numField->renumber(o2nCellsPart2->getConstPointer()); + MCAuto newNumField=numField->renumber(o2nCellsPart2->getConstPointer()); setRenumFieldArr(*it,newNumField); } } @@ -3753,86 +4277,209 @@ bool MEDFileUMesh::unPolyze(std::vector& oldCode, std::vector& newCode } if(ret) { - MEDCouplingAutoRefCountObjectPtr renumCells=DataArrayInt::Aggregate(renumCellsSplited); - MEDCouplingAutoRefCountObjectPtr o2nRenumCellRet=renumCells->buildPermArrPerLevel(); + MCAuto renumCells=DataArrayIdType::Aggregate(renumCellsSplited); + MCAuto o2nRenumCellRet=renumCells->buildPermArrPerLevel(); o2nRenumCell=o2nRenumCellRet.retn(); } return ret; } +/*! \cond HIDDEN_ITEMS */ struct MEDLoaderAccVisit1 { MEDLoaderAccVisit1():_new_nb_of_nodes(0) { } - int operator()(bool val) { return val?_new_nb_of_nodes++:-1; } - int _new_nb_of_nodes; + mcIdType operator()(bool val) { return val?_new_nb_of_nodes++:-1; } + mcIdType _new_nb_of_nodes; }; +/*! \endcond */ /*! - * Array returned is the correspondance in \b old \b to \b new format. The returned array is newly created and should be dealt by the caller. + * Array returned is the correspondence in \b old \b to \b new format. The returned array is newly created and should be dealt by the caller. * The maximum value stored in returned array is the number of nodes of \a this minus 1 after call of this method. * The size of returned array is the number of nodes of the old (previous to the call of this method) number of nodes. * -1 values in returned array means that the corresponding old node is no more used. * - * \return newly allocated array containing correspondance in \b old \b to \b new format. If all nodes in \a this are fetched \c NULL pointer is returned and nothing + * \return newly allocated array containing correspondence in \b old \b to \b new format. If all nodes in \a this are fetched \c NULL pointer is returned and nothing * is modified in \a this. * \throw If no coordinates are set in \a this or if there is in any available mesh in \a this a cell having a nodal connectivity containing a node id not in the range of * set coordinates. */ -DataArrayInt *MEDFileUMesh::zipCoords() +DataArrayIdType *MEDFileUMesh::zipCoords() +{ + const DataArrayDouble *coo(getCoords()); + if(!coo) + throw INTERP_KERNEL::Exception("MEDFileUMesh::zipCoords : no coordinates set in this !"); + mcIdType nbOfNodes(coo->getNumberOfTuples()); + std::vector nodeIdsInUse(nbOfNodes,false); + std::vector neLevs(getNonEmptyLevels()); + for(std::vector::const_iterator lev=neLevs.begin();lev!=neLevs.end();lev++) + { + const MEDFileUMeshSplitL1 *zeLev(getMeshAtLevSafe(*lev)); + if(zeLev->isMeshStoredSplitByType()) + { + std::vector ms(zeLev->getDirectUndergroundSingleGeoTypeMeshes()); + for(std::vector::const_iterator it=ms.begin();it!=ms.end();it++) + if(*it) + (*it)->computeNodeIdsAlg(nodeIdsInUse); + } + else + { + MCAuto mesh(zeLev->getWholeMesh(false)); + mesh->computeNodeIdsAlg(nodeIdsInUse); + } + } + mcIdType nbrOfNodesInUse((mcIdType)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true)); + if(nbrOfNodesInUse==nbOfNodes) + return 0;//no need to update _part_coords + MCAuto ret(DataArrayIdType::New()); ret->alloc(nbOfNodes,1); + std::transform(nodeIdsInUse.begin(),nodeIdsInUse.end(),ret->getPointer(),MEDLoaderAccVisit1()); + MCAuto ret2(ret->invertArrayO2N2N2OBis(nbrOfNodesInUse)); + MCAuto newCoords(coo->selectByTupleIdSafe(ret2->begin(),ret2->end())); + MCAuto newFamCoords; + MCAuto newNameCoords; + if((const DataArrayIdType *)_fam_coords) + newFamCoords=_fam_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()); + MCAuto newNumCoords,newGlobalNumCoords; + if(_num_coords.isNotNull()) + newNumCoords=_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()); + if(_global_num_coords.isNotNull()) + newGlobalNumCoords=_global_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()); + if(_name_coords.isNotNull()) + newNameCoords=static_cast(_name_coords->selectByTupleIdSafe(ret2->begin(),ret2->end())); + _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; _global_num_coords=newGlobalNumCoords; _name_coords=newNameCoords; _rev_num_coords.nullify(); + for(std::vector< MCAuto >::iterator it=_ms.begin();it!=_ms.end();it++) + { + if((MEDFileUMeshSplitL1*)*it) + { + (*it)->renumberNodesInConn(ret->begin()); + (*it)->setCoords(_coords); + } + } + // updates _part_coords + const PartDefinition *pc(_part_coords); + if(pc) + { + MCAuto tmpPD(DataArrayPartDefinition::New(ret2)); + _part_coords=tmpPD->composeWith(pc); + } + return ret.retn(); +} + +/*! + * This method is the extension of MEDCouplingUMesh::computeFetchedNodeIds. Except that here all levels are considered here. + * + * \return newly allocated array containing all nodes in \a this that are part of nodal connectivity of at least one cell in \a this whatever its level. + */ +DataArrayIdType *MEDFileUMesh::computeFetchedNodeIds() const +{ + std::vector neLevs(this->getNonEmptyLevels()); + std::vector nodesHighlighted(this->getNumberOfNodes(),false); + for(auto lev : neLevs) + { + const MEDFileUMeshSplitL1 *zeLev(this->getMeshAtLevSafe(lev)); + zeLev->highlightUsedNodes(nodesHighlighted); + } + return DataArrayIdType::BuildListOfSwitchedOn(nodesHighlighted); +} + +/*! + * This method is a const method. It computes the minimal set of node ids covered by the cell extraction of \a this. + * The extraction of \a this is specified by the extractDef \a input map. + * This map tells for each level of cells, the cells kept in the extraction. + * + * \return - a new reference of DataArrayIdType that represents sorted node ids, the extraction is lying on. + * \sa MEDFileField1TS::extractPart, MEDFileUMesh::extractPart + */ +DataArrayIdType *MEDFileUMesh::deduceNodeSubPartFromCellSubPart(const std::map >& extractDef) const +{ + std::vector levs(getNonEmptyLevels()); + std::vector fetchedNodes(getNumberOfNodes(),false); + for(std::map >::const_iterator it=extractDef.begin();it!=extractDef.end();it++) + { + if((*it).first>1) + throw INTERP_KERNEL::Exception("MEDFileUMesh::deduceNodeSubPartFromCellSubPart : invalid key ! Must be <=1 !"); + if((*it).second.isNull()) + throw INTERP_KERNEL::Exception("MEDFileUMesh::deduceNodeSubPartFromCellSubPart : presence of a value with null pointer !"); + if((*it).first==1) + continue; + if(std::find(levs.begin(),levs.end(),(*it).first)==levs.end()) + { + std::ostringstream oss; oss << "MEDFileUMesh::deduceNodeSubPartFromCellSubPart : invalid level " << (*it).first << " ! Not present in this !"; + throw INTERP_KERNEL::Exception(oss.str()); + } + MCAuto m(getMeshAtLevel((*it).first)); + MCAuto mPart(m->buildPartOfMySelf((*it).second->begin(),(*it).second->end(),true)); + mPart->computeNodeIdsAlg(fetchedNodes); + } + return DataArrayIdType::BuildListOfSwitchedOn(fetchedNodes); +} + +/*! + * This method returns a new MEDFileUMesh that is the result of the extraction of cells/nodes in \a this. + * + * \return - a new reference of MEDFileUMesh + * \sa MEDFileUMesh::deduceNodeSubPartFromCellSubPart, MEDFileFields::extractPart + */ +MEDFileUMesh *MEDFileUMesh::extractPart(const std::map >& extractDef) const { - const DataArrayDouble *coo(getCoords()); - if(!coo) - throw INTERP_KERNEL::Exception("MEDFileUMesh::zipCoords : no coordinates set in this !"); - int nbOfNodes(coo->getNumberOfTuples()); - std::vector nodeIdsInUse(nbOfNodes,false); - std::vector neLevs(getNonEmptyLevels()); - for(std::vector::const_iterator lev=neLevs.begin();lev!=neLevs.end();lev++) + MCAuto ret(MEDFileUMesh::New()); ret->setName(getName()); ret->copyFamGrpMapsFrom(*this); + std::vector levs(getNonEmptyLevels()); + for(std::map >::const_iterator it=extractDef.begin();it!=extractDef.end();it++) { - const MEDFileUMeshSplitL1 *zeLev(getMeshAtLevSafe(*lev)); - if(zeLev->isMeshStoredSplitByType()) + if((*it).first>1) + throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : invalid key ! Must be <=1 !"); + if((*it).second.isNull()) + throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : presence of a value with null pointer !"); + if((*it).first==1) + continue; + if(std::find(levs.begin(),levs.end(),(*it).first)==levs.end()) { - std::vector ms(zeLev->getDirectUndergroundSingleGeoTypeMeshes()); - for(std::vector::const_iterator it=ms.begin();it!=ms.end();it++) - if(*it) - (*it)->computeNodeIdsAlg(nodeIdsInUse); + std::ostringstream oss; oss << "MEDFileUMesh::extractPart : invalid level " << (*it).first << " ! Not present in this !"; + throw INTERP_KERNEL::Exception(oss.str()); } - else + MCAuto m(getMeshAtLevel((*it).first)); + MCAuto mPart(m->buildPartOfMySelf((*it).second->begin(),(*it).second->end(),true)); + ret->setMeshAtLevel((*it).first,mPart); + const DataArrayIdType *fam(getFamilyFieldAtLevel((*it).first)),*num(getNumberFieldAtLevel((*it).first)); + if(fam) { - MEDCouplingAutoRefCountObjectPtr mesh(zeLev->getWholeMesh(false)); - mesh->computeNodeIdsAlg(nodeIdsInUse); + MCAuto famPart(fam->selectByTupleIdSafe((*it).second->begin(),(*it).second->end())); + ret->setFamilyFieldArr((*it).first,famPart); } - } - int nbrOfNodesInUse((int)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true)); - if(nbrOfNodesInUse==nbOfNodes) - return 0;//no need to update _part_coords - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(nbOfNodes,1); - std::transform(nodeIdsInUse.begin(),nodeIdsInUse.end(),ret->getPointer(),MEDLoaderAccVisit1()); - MEDCouplingAutoRefCountObjectPtr ret2(ret->invertArrayO2N2N2OBis(nbrOfNodesInUse)); - MEDCouplingAutoRefCountObjectPtr newCoords(coo->selectByTupleIdSafe(ret2->begin(),ret2->end())); - MEDCouplingAutoRefCountObjectPtr newFamCoords; - MEDCouplingAutoRefCountObjectPtr newNameCoords; - if((const DataArrayInt *)_fam_coords) - newFamCoords=_fam_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()); - MEDCouplingAutoRefCountObjectPtr newNumCoords; - if((const DataArrayInt *)_num_coords) - newNumCoords=_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()); - if((const DataArrayAsciiChar *)_name_coords) - newNameCoords=static_cast(_name_coords->selectByTupleIdSafe(ret2->begin(),ret2->end())); - _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; _name_coords=newNameCoords; _rev_num_coords=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_ms.begin();it!=_ms.end();it++) - { - if((MEDFileUMeshSplitL1*)*it) + if(num) { - (*it)->renumberNodesInConn(ret->begin()); - (*it)->setCoords(_coords); + MCAuto numPart(num->selectByTupleIdSafe((*it).second->begin(),(*it).second->end())); + ret->setFamilyFieldArr((*it).first,numPart); } } - // updates _part_coords - const PartDefinition *pc(_part_coords); - if(pc) + std::map >::const_iterator it2(extractDef.find(1)); + if(it2!=extractDef.end()) { - MEDCouplingAutoRefCountObjectPtr tmpPD(DataArrayPartDefinition::New(ret2)); - _part_coords=tmpPD->composeWith(pc); + const DataArrayDouble *coo(ret->getCoords()); + if(!coo) + throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : trying to extract nodes whereas there is no nodes !"); + MCAuto o2nNodes(((*it2).second)->invertArrayN2O2O2N(coo->getNumberOfTuples())); + MCAuto cooPart(coo->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end())); + ret->setCoords(cooPart); + const DataArrayIdType *fam(getFamilyFieldAtLevel(1)),*num(getNumberFieldAtLevel(1)); + if(fam) + { + MCAuto famPart(fam->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end())); + ret->setFamilyFieldArr(1,famPart); + } + if(num) + { + MCAuto numPart(num->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end())); + ret->setFamilyFieldArr(1,numPart); + } + for(std::map >::const_iterator it3=extractDef.begin();it3!=extractDef.end();it3++) + { + if((*it3).first==1) + continue; + MCAuto m(ret->getMeshAtLevel((*it3).first)); + m->renumberNodesInConn(o2nNodes->begin()); + ret->setMeshAtLevel((*it3).first,m); + } } return ret.retn(); } @@ -3853,34 +4500,35 @@ DataArrayInt *MEDFileUMesh::zipCoords() */ MEDFileUMesh *MEDFileUMesh::buildExtrudedMesh(const MEDCouplingUMesh *m1D, int policy) const { + checkCartesian(); if(getMeshDimension()!=2) throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : this is expected to be with mesh dimension equal to 2 !"); - MEDCouplingAutoRefCountObjectPtr ret(MEDFileUMesh::New()); - m1D->checkCoherency(); + MCAuto ret(MEDFileUMesh::New()); + m1D->checkConsistencyLight(); if(m1D->getMeshDimension()!=1) throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : input mesh must have a mesh dimension equal to one !"); - int nbRep(m1D->getNumberOfCells()); + mcIdType nbRep(m1D->getNumberOfCells()); std::vector levs(getNonEmptyLevels()); std::vector grps(getGroupsNames()); - std::vector< MEDCouplingAutoRefCountObjectPtr > zeList; + std::vector< MCAuto > zeList; DataArrayDouble *coords(0); std::size_t nbOfLevsOut(levs.size()+1); - std::vector< MEDCouplingAutoRefCountObjectPtr > o2ns(nbOfLevsOut); + std::vector< MCAuto > o2ns(nbOfLevsOut); for(std::vector::const_iterator lev=levs.begin();lev!=levs.end();lev++) { - MEDCouplingAutoRefCountObjectPtr item(getMeshAtLevel(*lev)); + MCAuto item(getMeshAtLevel(*lev)); item=item->clone(false); item->changeSpaceDimension(3+(*lev),0.);//no problem non const but change DataArrayDouble for coordinates do not alter data - MEDCouplingAutoRefCountObjectPtr tmp(static_cast(m1D->deepCpy())); + MCAuto tmp(static_cast(m1D->deepCopy())); tmp->changeSpaceDimension(3+(*lev),0.); - MEDCouplingAutoRefCountObjectPtr elt(item->buildExtrudedMesh(tmp,policy)); + MCAuto elt(item->buildExtrudedMesh(tmp,policy)); zeList.push_back(elt); if(*lev==0) coords=elt->getCoords(); } if(!coords) throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : internal error !"); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=zeList.begin();it!=zeList.end();it++) + for(std::vector< MCAuto >::iterator it=zeList.begin();it!=zeList.end();it++) { (*it)->setName(getName()); (*it)->setCoords(coords); @@ -3888,12 +4536,12 @@ MEDFileUMesh *MEDFileUMesh::buildExtrudedMesh(const MEDCouplingUMesh *m1D, int p for(std::size_t ii=0;ii!=zeList.size();ii++) { int lev(levs[ii]); - MEDCouplingAutoRefCountObjectPtr elt(zeList[ii]); + MCAuto elt(zeList[ii]); if(lev<=-1) { - MEDCouplingAutoRefCountObjectPtr elt1(getMeshAtLevel(lev+1)); - MEDCouplingAutoRefCountObjectPtr elt2(elt1->clone(false)); - MEDCouplingAutoRefCountObjectPtr tmp(elt2->getNodalConnectivity()->deepCpy()); + MCAuto elt1(getMeshAtLevel(lev+1)); + MCAuto elt2(elt1->clone(false)); + MCAuto tmp(elt2->getNodalConnectivity()->deepCopy()); elt2->setConnectivity(tmp,elt2->getNodalConnectivityIndex()); elt2->shiftNodeNumbersInConn(nbRep*elt1->getNumberOfNodes()); elt1->setCoords(elt->getCoords()); elt2->setCoords(elt->getCoords()); @@ -3906,9 +4554,9 @@ MEDFileUMesh *MEDFileUMesh::buildExtrudedMesh(const MEDCouplingUMesh *m1D, int p o2ns[ii]=elt->sortCellsInMEDFileFrmt(); ret->setMeshAtLevel(lev,elt); } - MEDCouplingAutoRefCountObjectPtr endLev(getMeshAtLevel(levs.back())),endLev2; + MCAuto endLev(getMeshAtLevel(levs.back())),endLev2; endLev=endLev->clone(false); endLev->setCoords(coords); - MEDCouplingAutoRefCountObjectPtr tmp(endLev->getNodalConnectivity()->deepCpy()); + MCAuto tmp(endLev->getNodalConnectivity()->deepCopy()); endLev2=endLev->clone(false); endLev2->setConnectivity(tmp,endLev->getNodalConnectivityIndex()); endLev2->shiftNodeNumbersInConn(nbRep*getNumberOfNodes()); endLev=MEDCouplingUMesh::MergeUMeshesOnSameCoords(endLev,endLev2); @@ -3919,18 +4567,18 @@ MEDFileUMesh *MEDFileUMesh::buildExtrudedMesh(const MEDCouplingUMesh *m1D, int p for(std::size_t ii=0;ii!=zeList.size();ii++) { int lev(levs[ii]); - std::vector< MEDCouplingAutoRefCountObjectPtr > outGrps; - std::vector< const DataArrayInt * > outGrps2; + std::vector< MCAuto > outGrps; + std::vector< const DataArrayIdType * > outGrps2; if(lev<=-1) { for(std::vector::const_iterator grp=grps.begin();grp!=grps.end();grp++) { - MEDCouplingAutoRefCountObjectPtr grpArr(getGroupArr(lev+1,*grp)); + MCAuto grpArr(getGroupArr(lev+1,*grp)); if(!grpArr->empty()) { - MEDCouplingAutoRefCountObjectPtr grpArr1(grpArr->deepCpy()),grpArr2(grpArr->deepCpy()); - int offset0(zeList[ii]->getNumberOfCells()); - int offset1(offset0+getNumberOfCellsAtLevel(lev+1)); + MCAuto grpArr1(grpArr->deepCopy()),grpArr2(grpArr->deepCopy()); + mcIdType offset0(zeList[ii]->getNumberOfCells()); + mcIdType offset1(offset0+getNumberOfCellsAtLevel(lev+1)); grpArr1->applyLin(1,offset0); grpArr2->applyLin(1,offset1); std::ostringstream oss; oss << grpArr2->getName() << "_top"; grpArr2->setName(oss.str()); @@ -3944,18 +4592,18 @@ MEDFileUMesh *MEDFileUMesh::buildExtrudedMesh(const MEDCouplingUMesh *m1D, int p // for(std::vector::const_iterator grp=grps.begin();grp!=grps.end();grp++) { - MEDCouplingAutoRefCountObjectPtr grpArr(getGroupArr(lev,*grp)); + MCAuto grpArr(getGroupArr(lev,*grp)); if(!grpArr->empty()) { - int nbCellsB4Extrusion(getNumberOfCellsAtLevel(lev)); - std::vector< MEDCouplingAutoRefCountObjectPtr > grpArrs(nbRep); - std::vector< const DataArrayInt *> grpArrs2(nbRep); + mcIdType nbCellsB4Extrusion(getNumberOfCellsAtLevel(lev)); + std::vector< MCAuto > grpArrs(nbRep); + std::vector< const DataArrayIdType *> grpArrs2(nbRep); for(int iii=0;iiideepCpy(); grpArrs[iii]->applyLin(1,iii*nbCellsB4Extrusion); + grpArrs[iii]=grpArr->deepCopy(); grpArrs[iii]->applyLin(1,iii*nbCellsB4Extrusion); grpArrs2[iii]=grpArrs[iii]; } - MEDCouplingAutoRefCountObjectPtr grpArrExt(DataArrayInt::Aggregate(grpArrs2)); + MCAuto grpArrExt(DataArrayIdType::Aggregate(grpArrs2)); grpArrExt->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end()); std::ostringstream grpName; grpName << *grp << "_extruded"; grpArrExt->setName(grpName.str()); @@ -3965,14 +4613,14 @@ MEDFileUMesh *MEDFileUMesh::buildExtrudedMesh(const MEDCouplingUMesh *m1D, int p } ret->setGroupsAtLevel(lev,outGrps2); } - std::vector< MEDCouplingAutoRefCountObjectPtr > outGrps; - std::vector< const DataArrayInt * > outGrps2; + std::vector< MCAuto > outGrps; + std::vector< const DataArrayIdType * > outGrps2; for(std::vector::const_iterator grp=grps.begin();grp!=grps.end();grp++) { - MEDCouplingAutoRefCountObjectPtr grpArr1(getGroupArr(levs.back(),*grp)); + MCAuto grpArr1(getGroupArr(levs.back(),*grp)); if(grpArr1->empty()) continue; - MEDCouplingAutoRefCountObjectPtr grpArr2(grpArr1->deepCpy()); + MCAuto grpArr2(grpArr1->deepCopy()); std::ostringstream grpName; grpName << *grp << "_top"; grpArr2->setName(grpName.str()); grpArr2->applyLin(1,getNumberOfCellsAtLevel(levs.back())); @@ -3997,61 +4645,65 @@ MEDFileUMesh *MEDFileUMesh::buildExtrudedMesh(const MEDCouplingUMesh *m1D, int p */ MEDFileUMesh *MEDFileUMesh::linearToQuadratic(int conversionType, double eps) const { - MEDCouplingAutoRefCountObjectPtr ret(MEDFileUMesh::New()); - int initialNbNodes(getNumberOfNodes()); - MEDCouplingAutoRefCountObjectPtr m0Tmp(getMeshAtLevel(0)); - MEDCouplingAutoRefCountObjectPtr m0(dynamic_cast(m0Tmp->deepCpy())); + checkCartesian(); + MCAuto ret(MEDFileUMesh::New()); + mcIdType initialNbNodes(getNumberOfNodes()); + MCAuto m0Tmp(getMeshAtLevel(0)); + MCAuto m0(dynamic_cast(m0Tmp->deepCopy())); { - MEDCouplingAutoRefCountObjectPtr notUsed(m0->convertLinearCellsToQuadratic(conversionType)); + MCAuto notUsed(m0->convertLinearCellsToQuadratic(conversionType)); } DataArrayDouble *zeCoords(m0->getCoords()); ret->setMeshAtLevel(0,m0); std::vector levs(getNonEmptyLevels()); - const DataArrayInt *famField(getFamilyFieldAtLevel(0)); + const DataArrayIdType *famField(getFamilyFieldAtLevel(0)); if(famField) { - MEDCouplingAutoRefCountObjectPtr famFieldCpy(famField->deepCpy()); + MCAuto famFieldCpy(famField->deepCopy()); ret->setFamilyFieldArr(0,famFieldCpy); } famField=getFamilyFieldAtLevel(1); if(famField) { - MEDCouplingAutoRefCountObjectPtr fam(DataArrayInt::New()); fam->alloc(zeCoords->getNumberOfTuples(),1); + MCAuto fam(DataArrayIdType::New()); fam->alloc(zeCoords->getNumberOfTuples(),1); fam->fillWithZero(); fam->setPartOfValues1(famField,0,initialNbNodes,1,0,1,1); ret->setFamilyFieldArr(1,fam); } ret->copyFamGrpMapsFrom(*this); - MEDCouplingAutoRefCountObjectPtr partZeCoords(zeCoords->selectByTupleId2(initialNbNodes,zeCoords->getNumberOfTuples(),1)); + MCAuto partZeCoords(zeCoords->selectByTupleIdSafeSlice(initialNbNodes,zeCoords->getNumberOfTuples(),1)); for(std::vector::const_iterator lev=levs.begin();lev!=levs.end();lev++) { if(*lev==0) continue; - MEDCouplingAutoRefCountObjectPtr m1Tmp(getMeshAtLevel(*lev)); - MEDCouplingAutoRefCountObjectPtr m1(dynamic_cast(m1Tmp->deepCpy())); - { - MEDCouplingAutoRefCountObjectPtr notUsed(m1->convertLinearCellsToQuadratic(conversionType)); - } - MEDCouplingAutoRefCountObjectPtr m1Coords(m1->getCoords()->selectByTupleId2(initialNbNodes,m1->getNumberOfNodes(),1)); - DataArrayInt *b(0); - bool a(partZeCoords->areIncludedInMe(m1Coords,eps,b)); - MEDCouplingAutoRefCountObjectPtr bSafe(b); - if(!a) + MCAuto m1Tmp(getMeshAtLevel(*lev)); + MCAuto m1(dynamic_cast(m1Tmp->deepCopy())); + if(m1->getMeshDimension()!=0) { - std::ostringstream oss; oss << "MEDFileUMesh::linearCellsToQuadratic : for level " << *lev << " problem to identify nodes generated !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); + { + MCAuto notUsed(m1->convertLinearCellsToQuadratic(conversionType)); + }//kill unused notUsed var + MCAuto m1Coords(m1->getCoords()->selectByTupleIdSafeSlice(initialNbNodes,m1->getNumberOfNodes(),1)); + DataArrayIdType *b(0); + bool a(partZeCoords->areIncludedInMe(m1Coords,eps,b)); + MCAuto bSafe(b); + if(!a) + { + std::ostringstream oss; oss << "MEDFileUMesh::linearCellsToQuadratic : for level " << *lev << " problem to identify nodes generated !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + b->applyLin(1,initialNbNodes); + MCAuto l0(DataArrayIdType::New()); l0->alloc(initialNbNodes,1); l0->iota(); + std::vector v(2); v[0]=l0; v[1]=b; + MCAuto renum(DataArrayIdType::Aggregate(v)); + m1->renumberNodesInConn(renum->begin()); } - b->applyLin(1,initialNbNodes); - MEDCouplingAutoRefCountObjectPtr l0(DataArrayInt::New()); l0->alloc(initialNbNodes,1); l0->iota(); - std::vector v(2); v[0]=l0; v[1]=b; - MEDCouplingAutoRefCountObjectPtr renum(DataArrayInt::Aggregate(v)); - m1->renumberNodesInConn(renum->begin()); m1->setCoords(zeCoords); ret->setMeshAtLevel(*lev,m1); famField=getFamilyFieldAtLevel(*lev); if(famField) { - MEDCouplingAutoRefCountObjectPtr famFieldCpy(famField->deepCpy()); + MCAuto famFieldCpy(famField->deepCopy()); ret->setFamilyFieldArr(*lev,famFieldCpy); } } @@ -4070,24 +4722,25 @@ MEDFileUMesh *MEDFileUMesh::linearToQuadratic(int conversionType, double eps) co */ MEDFileUMesh *MEDFileUMesh::quadraticToLinear(double eps) const { - MEDCouplingAutoRefCountObjectPtr ret(MEDFileUMesh::New()); - MEDCouplingAutoRefCountObjectPtr m0Tmp(getMeshAtLevel(0)); - MEDCouplingAutoRefCountObjectPtr m0(dynamic_cast(m0Tmp->deepCpy())); + checkCartesian(); + MCAuto ret(MEDFileUMesh::New()); + MCAuto m0Tmp(getMeshAtLevel(0)); + MCAuto m0(dynamic_cast(m0Tmp->deepCopy())); m0->convertQuadraticCellsToLinear(); m0->zipCoords(); DataArrayDouble *zeCoords(m0->getCoords()); ret->setMeshAtLevel(0,m0); std::vector levs(getNonEmptyLevels()); - const DataArrayInt *famField(getFamilyFieldAtLevel(0)); + const DataArrayIdType *famField(getFamilyFieldAtLevel(0)); if(famField) { - MEDCouplingAutoRefCountObjectPtr famFieldCpy(famField->deepCpy()); + MCAuto famFieldCpy(famField->deepCopy()); ret->setFamilyFieldArr(0,famFieldCpy); } famField=getFamilyFieldAtLevel(1); if(famField) { - MEDCouplingAutoRefCountObjectPtr fam(famField->selectByTupleId2(0,zeCoords->getNumberOfTuples(),1)); + MCAuto fam(famField->selectByTupleIdSafeSlice(0,zeCoords->getNumberOfTuples(),1)); ret->setFamilyFieldArr(1,fam); } ret->copyFamGrpMapsFrom(*this); @@ -4095,13 +4748,13 @@ MEDFileUMesh *MEDFileUMesh::quadraticToLinear(double eps) const { if(*lev==0) continue; - MEDCouplingAutoRefCountObjectPtr m1Tmp(getMeshAtLevel(*lev)); - MEDCouplingAutoRefCountObjectPtr m1(dynamic_cast(m1Tmp->deepCpy())); + MCAuto m1Tmp(getMeshAtLevel(*lev)); + MCAuto m1(dynamic_cast(m1Tmp->deepCopy())); m1->convertQuadraticCellsToLinear(); m1->zipCoords(); - DataArrayInt *b(0); + DataArrayIdType *b(0); bool a(zeCoords->areIncludedInMe(m1->getCoords(),eps,b)); - MEDCouplingAutoRefCountObjectPtr bSafe(b); + MCAuto bSafe(b); if(!a) { std::ostringstream oss; oss << "MEDFileUMesh::quadraticToLinear : for level " << *lev << " problem to identify nodes generated !"; @@ -4113,42 +4766,268 @@ MEDFileUMesh *MEDFileUMesh::quadraticToLinear(double eps) const famField=getFamilyFieldAtLevel(*lev); if(famField) { - MEDCouplingAutoRefCountObjectPtr famFieldCpy(famField->deepCpy()); + MCAuto famFieldCpy(famField->deepCopy()); ret->setFamilyFieldArr(*lev,famFieldCpy); } } return ret.retn(); } -void MEDFileUMesh::serialize(std::vector& tinyDouble, std::vector& tinyInt, std::vector& tinyStr, std::vector< MEDCouplingAutoRefCountObjectPtr >& bigArraysI, MEDCouplingAutoRefCountObjectPtr& bigArrayD) +/*! + * Computes the symmetry of \a this. + * \return a new object. + */ +MCAuto MEDFileUMesh::symmetry3DPlane(const double point[3], const double normalVector[3]) const +{ + MCAuto ret(deepCopy()); + DataArrayDouble *myCoo(getCoords()); + if(myCoo) + { + MCAuto newCoo(myCoo->symmetry3DPlane(point,normalVector)); + ret->setCoordsForced(newCoo); + } + return ret; +} + +/*! + * Aggregate the given MEDFileUMesh objects into a single mesh. When groups are present, those are + * merged in such a way that the final mesh contain all of them. + * \return a new object. + */ +MCAuto MEDFileUMesh::Aggregate(const std::vector& meshes) +{ + if(meshes.empty()) + throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : empty input vector !"); + std::size_t sz(meshes.size()),i(0); + std::vector coos(sz); + std::vector fam_coos(sz),num_coos(sz); + for(auto it=meshes.begin();it!=meshes.end();it++,i++) + { + if(!(*it)) + throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : presence of NULL pointer in input vector !"); + coos[i]=(*it)->getCoords(); + fam_coos[i]=(*it)->getFamilyFieldAtLevel(1); + num_coos[i]=(*it)->getNumberFieldAtLevel(1); + } + const MEDFileUMesh *ref(meshes[0]); + int spaceDim(ref->getSpaceDimension()),meshDim(ref->getMeshDimension()); + std::vector levs(ref->getNonEmptyLevels()); + std::map > m_fam,m_renum; + std::map > > m_mesh2; + std::map > m_mesh; + std::map famNumMap; + std::map famNumMap_rev; + std::map > grpFamMap; + std::set< MCAuto > mem_cleanup; // Memory clean-up. At set deletion (end of method), arrays will be deallocated. + + // Identify min family number used: + mcIdType min_fam_num(0); + for(const auto& msh : meshes) + { + const std::map& locMap1(msh->getFamilyInfo()); + for(const auto& it3 : locMap1) + if(it3.second < min_fam_num) + min_fam_num = it3.second; + } + + for(const auto& msh : meshes) + { + if(msh->getSpaceDimension()!=spaceDim) + throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : space dimension must be homogeneous !"); + if(msh->getMeshDimension()!=meshDim) + throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : mesh dimension must be homogeneous !"); + if(msh->getNonEmptyLevels()!=levs) + throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : levels must be the same for elements in input vector !"); + + const std::map& locMap1(msh->getFamilyInfo()); + std::map substitute; + std::map substituteN; + bool fam_conflict(false); + for(const auto& it3 : locMap1) + { + const std::string& famName = it3.first; + mcIdType famNum = it3.second; + if (famNumMap_rev.find(famNum) != famNumMap_rev.end()) // Family number is already used! + { + // Is it used by a group of the current mesh or a group from a previous mesh? + // If not, this is OK (typically -1 familly). + bool used = false; + // Current mesh + const std::map >& locMap2(msh->getGroupInfo()); + for(const auto& it4 : locMap2) + { + const auto& famLst = it4.second; + if (std::find(famLst.begin(), famLst.end(), famName) != famLst.end()) + { used = true; break; } + } + // Previous meshes ... + if (!used) + for(const auto& it4 : grpFamMap) + { + const auto& famLst = it4.second; + if (std::find(famLst.begin(), famLst.end(), famName) != famLst.end()) + { used = true; break; } + } + + if(used) + { // Generate a new family name, and a new family number + fam_conflict = true; + std::ostringstream oss; + oss << "Family_" << --min_fam_num; // New ID + std::string new_name(oss.str()); + substitute[famName] = new_name; + substituteN[famNum] = min_fam_num; + famNumMap[new_name] = min_fam_num; + famNumMap_rev[min_fam_num] = new_name; + } + } + famNumMap[famName] = famNum; + famNumMap_rev[famNum] = famName; + } + + for(const auto& level : levs) + { + MCAuto locMesh(msh->getMeshAtLevel(level)); + m_mesh[level].push_back(locMesh); m_mesh2[level].push_back(locMesh); + m_renum[level].push_back(msh->getNumberFieldAtLevel(level)); + + // Family field - substitute new family number if needed: + if(fam_conflict) + { + DataArrayIdType* dai(msh->getFamilyFieldAtLevel(level)->deepCopy()); // Need a copy + mem_cleanup.insert(MCAuto(dai)); // Make sure array will decrRef() at end of method + for (const auto& subN : substituteN) + dai->changeValue(subN.first, subN.second); + m_fam[level].push_back(dai); + } + else + m_fam[level].push_back(msh->getFamilyFieldAtLevel(level)); // No copy needed + } + + const std::map >& locMap2(msh->getGroupInfo()); + for(const auto& grpItem : locMap2) + { + const std::string& grpName = grpItem.first; + std::vector famLst; + // Substitute family name in group description if needed: + if (fam_conflict) + { + famLst = grpItem.second; + for (const auto& sub : substitute) + std::replace(famLst.begin(), famLst.end(), sub.first, sub.second); + } + else + famLst = grpItem.second; + + // Potentially merge groups (if same name): + const auto& it = grpFamMap.find(grpName); + if (it != grpFamMap.end()) + { + // Group already exists, merge should be done. Normally we whould never + // have twice the same family name in famLstCur and famLst since we dealt with family number + // conflict just above ... + std::vector& famLstCur = (*it).second; + famLstCur.insert(famLstCur.end(), famLst.begin(), famLst.end()); + } + else + grpFamMap[grpName] = famLst; + } + } + // Easy part : nodes + MCAuto ret(MEDFileUMesh::New()); + MCAuto coo(DataArrayDouble::Aggregate(coos)); + ret->setCoords(coo); + if(std::find(fam_coos.begin(),fam_coos.end(),(const DataArrayIdType *)0)==fam_coos.end()) + { + MCAuto fam_coo(DataArrayIdType::Aggregate(fam_coos)); + ret->setFamilyFieldArr(1,fam_coo); + } + if(std::find(num_coos.begin(),num_coos.end(),(const DataArrayIdType *)0)==num_coos.end()) + { + MCAuto num_coo(DataArrayIdType::Aggregate(num_coos)); + ret->setRenumFieldArr(1,num_coo); + } + // cells + for(const auto& level : levs) + { + auto it2(m_mesh.find(level)); + if(it2==m_mesh.end()) + throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : internal error 1 !"); + MCAuto mesh(MEDCouplingUMesh::MergeUMeshes((*it2).second)); + mesh->setCoords(coo); mesh->setName(ref->getName()); + MCAuto renum(mesh->sortCellsInMEDFileFrmt()); + ret->setMeshAtLevel(level,mesh); + auto it3(m_fam.find(level)),it4(m_renum.find(level)); + if(it3==m_fam.end()) // Should never happen (all levels exist for all meshes) + throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : internal error 2!"); + if(it4==m_renum.end()) + throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : internal error 3!"); + // Set new family field if it was defined for all input meshes + const std::vector& fams((*it3).second); + if(std::find(fams.begin(),fams.end(),(const DataArrayIdType *)0)==fams.end()) + { + MCAuto famm(DataArrayIdType::Aggregate(fams)); + famm->renumberInPlace(renum->begin()); + ret->setFamilyFieldArr(level,famm); + } + // Set optional number field if defined for all input meshes: + const std::vector& renums((*it4).second); + if(std::find(renums.begin(),renums.end(),(const DataArrayIdType *)0)==renums.end()) + { + MCAuto renumm(DataArrayIdType::Aggregate(renums)); + renumm->renumberInPlace(renum->begin()); + ret->setRenumFieldArr(level,renumm); + } + } + // + ret->setFamilyInfo(famNumMap); + ret->setGroupInfo(grpFamMap); + ret->setName(ref->getName()); + return ret; +} + +MEDCouplingMappedExtrudedMesh *MEDFileUMesh::convertToExtrudedMesh() const +{ + if(getMeshDimension()!=3) + throw INTERP_KERNEL::Exception("MEDFileUMesh::convertToExtrudedMesh : works only for 3D mesh !"); + MCAuto m3D(getMeshAtLevel(0)),m2D(getMeshAtLevel(-1)); + if(m3D.isNull() || m2D.isNull()) + throw INTERP_KERNEL::Exception("MEDFileUMesh::convertToExtrudedMesh : this must be defined both at level 0 and level -1 !"); + mcIdType zeId(std::numeric_limits::max()-getFamilyId(GetSpeStr4ExtMesh())); + MCAuto ret(MEDCouplingMappedExtrudedMesh::New(m3D,m2D,zeId)); + return ret.retn(); +} + +void MEDFileUMesh::serialize(std::vector& tinyDouble, std::vector& tinyInt, std::vector& tinyStr, std::vector< MCAuto >& bigArraysI, MCAuto& bigArrayD) { clearNonDiscrAttributes(); forceComputationOfParts(); tinyDouble.clear(); tinyInt.clear(); tinyStr.clear(); bigArraysI.clear(); bigArrayD=0; - std::vector layer0; - layer0.push_back(_order); //0 i - layer0.push_back(_iteration);//1 i - layer0.push_back(getSpaceDimension());//2 i + std::vector layer0; + layer0.push_back(getAxisType());//0 i + layer0.push_back(_order); //1 i + layer0.push_back(_iteration);//2 i + layer0.push_back(getSpaceDimension());//3 i tinyDouble.push_back(_time);//0 d tinyStr.push_back(_name);//0 s tinyStr.push_back(_desc_name);//1 s for(int i=0;igetInfoOnComponent(i)); - layer0.push_back((int)_families.size());//3 i <- key info aa layer#0 - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) + layer0.push_back(ToIdType(_families.size()));//4 i <- key info aa layer#0 + for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) { tinyStr.push_back((*it).first); layer0.push_back((*it).second); } - layer0.push_back((int)_groups.size());//3+aa i <- key info bb layer#0 + layer0.push_back((mcIdType)_groups.size());//4+aa i <- key info bb layer#0 for(std::map >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++) { - layer0.push_back((int)(*it0).second.size()); + layer0.push_back(ToIdType((*it0).second.size())); tinyStr.push_back((*it0).first); for(std::vector::const_iterator it1=((*it0).second).begin();it1!=((*it0).second).end();it1++) tinyStr.push_back(*it1); } - // sizeof(layer0)==3+aa+1+bb layer#0 + // sizeof(layer0)==4+aa+1+bb layer#0 bigArrayD=_coords;// 0 bd bigArraysI.push_back(_fam_coords);// 0 bi bigArraysI.push_back(_num_coords);// 1 bi @@ -4157,15 +5036,15 @@ void MEDFileUMesh::serialize(std::vector& tinyDouble, std::vector& layer0.push_back(-1); else { - std::vector tmp0; + std::vector tmp0; pd->serialize(tmp0,bigArraysI); - tinyInt.push_back(tmp0.size()); + tinyInt.push_back(ToIdType(tmp0.size())); tinyInt.insert(tinyInt.end(),tmp0.begin(),tmp0.end()); } // - std::vector layer1; + std::vector layer1; std::vector levs(getNonEmptyLevels()); - layer1.push_back((int)levs.size());// 0 i <- key + layer1.push_back((mcIdType)levs.size());// 0 i <- key layer1.insert(layer1.end(),levs.begin(),levs.end()); for(std::vector::const_iterator it=levs.begin();it!=levs.end();it++) { @@ -4173,19 +5052,19 @@ void MEDFileUMesh::serialize(std::vector& tinyDouble, std::vector& lev->serialize(layer1,bigArraysI); } // put layers all together. - tinyInt.push_back(layer0.size()); + tinyInt.push_back(ToIdType(layer0.size())); tinyInt.insert(tinyInt.end(),layer0.begin(),layer0.end()); - tinyInt.push_back(layer1.size()); + tinyInt.push_back(ToIdType(layer1.size())); tinyInt.insert(tinyInt.end(),layer1.begin(),layer1.end()); } -void MEDFileUMesh::unserialize(std::vector& tinyDouble, std::vector& tinyInt, std::vector& tinyStr, - std::vector< MEDCouplingAutoRefCountObjectPtr >& bigArraysI, MEDCouplingAutoRefCountObjectPtr& bigArrayD) +void MEDFileUMesh::unserialize(std::vector& tinyDouble, std::vector& tinyInt, std::vector& tinyStr, + std::vector< MCAuto >& bigArraysI, MCAuto& bigArrayD) { - int sz0(tinyInt[0]); - std::vector layer0(tinyInt.begin()+1,tinyInt.begin()+1+sz0); - int sz1(tinyInt[sz0+1]); - std::vector layer1(tinyInt.begin()+2+sz0,tinyInt.begin()+2+sz0+sz1); + mcIdType sz0(tinyInt[0]); + std::vector layer0(tinyInt.begin()+1,tinyInt.begin()+1+sz0); + mcIdType sz1(tinyInt[sz0+1]); + std::vector layer1(tinyInt.begin()+2+sz0,tinyInt.begin()+2+sz0+sz1); // std::reverse(layer0.begin(),layer0.end()); std::reverse(layer1.begin(),layer1.end()); @@ -4193,9 +5072,10 @@ void MEDFileUMesh::unserialize(std::vector& tinyDouble, std::vector std::reverse(tinyStr.begin(),tinyStr.end()); std::reverse(bigArraysI.begin(),bigArraysI.end()); // - _order=layer0.back(); layer0.pop_back(); - _iteration=layer0.back(); layer0.pop_back(); - int spaceDim(layer0.back()); layer0.pop_back(); + setAxisType((MEDCouplingAxisType)layer0.back()); layer0.pop_back(); + _order=FromIdType(layer0.back()); layer0.pop_back(); + _iteration=FromIdType(layer0.back()); layer0.pop_back(); + mcIdType spaceDim(layer0.back()); layer0.pop_back(); _time=tinyDouble.back(); tinyDouble.pop_back(); _name=tinyStr.back(); tinyStr.pop_back(); _desc_name=tinyStr.back(); tinyStr.pop_back(); @@ -4205,21 +5085,21 @@ void MEDFileUMesh::unserialize(std::vector& tinyDouble, std::vector _coords->setInfoOnComponent(i,tinyStr.back()); tinyStr.pop_back(); } - int nbOfFams(layer0.back()); layer0.pop_back(); + mcIdType nbOfFams(layer0.back()); layer0.pop_back(); _families.clear(); - for(int i=0;i fams(nbOfFamsOnGrp); - for(int j=0;j& tinyDouble, std::vector _fam_coords=bigArraysI.back(); bigArraysI.pop_back(); _num_coords=bigArraysI.back(); bigArraysI.pop_back(); _part_coords=0; - int isPd(layer0.back()); layer0.pop_back(); + mcIdType isPd(layer0.back()); layer0.pop_back(); if(isPd!=-1) { - std::vector tmp0(layer0.begin(),layer0.begin()+isPd); + std::vector tmp0(layer0.begin(),layer0.begin()+isPd); layer0.erase(layer0.begin(),layer0.begin()+isPd); _part_coords=PartDefinition::Unserialize(tmp0,bigArraysI); } if(!layer0.empty()) throw INTERP_KERNEL::Exception("MEDFileUMesh::unserialize : something wrong during unserialization #1 !"); // - int nbLevs(layer1.back()); layer1.pop_back(); - std::vector levs(layer1.rbegin(),layer1.rbegin()+nbLevs); layer1.erase(layer1.end()-nbLevs,layer1.end()); + mcIdType nbLevs(layer1.back()); layer1.pop_back(); + std::vector levs(layer1.rbegin(),layer1.rbegin()+nbLevs); layer1.erase(layer1.end()-nbLevs,layer1.end()); _ms.clear(); - int maxLev(-(*std::min_element(levs.begin(),levs.end()))); + mcIdType maxLev(-(*std::min_element(levs.begin(),levs.end()))); _ms.resize(maxLev+1); - for(int i=0;i& tinyDouble, std::vector * \throw If \a ids does not respect the MED file norm. * \throw If a group with name \a ids->getName() already exists. */ -void MEDFileUMesh::addNodeGroup(const DataArrayInt *ids) +void MEDFileUMesh::addNodeGroup(const DataArrayIdType *ids) { const DataArrayDouble *coords(_coords); if(!coords) throw INTERP_KERNEL::Exception("MEDFileUMesh::addNodeGroup : no coords set !"); - int nbOfNodes(coords->getNumberOfTuples()); - if(!((DataArrayInt *)_fam_coords)) - { _fam_coords=DataArrayInt::New(); _fam_coords->alloc(nbOfNodes,1); _fam_coords->fillWithZero(); } + mcIdType nbOfNodes(coords->getNumberOfTuples()); + if(_fam_coords.isNull()) + { _fam_coords=DataArrayIdType::New(); _fam_coords->alloc(nbOfNodes,1); _fam_coords->fillWithZero(); } // addGroupUnderground(true,ids,_fam_coords); } @@ -4280,7 +5160,7 @@ void MEDFileUMesh::addNodeGroup(const DataArrayInt *ids) /*! * Adds a group of nodes/cells/faces/edges to \a this mesh. * - * \param [in] ids - a DataArrayInt providing ids and a name of the group to add. + * \param [in] ids - a DataArrayIdType providing ids and a name of the group to add. * The ids should be sorted and different each other (MED file norm). * * \warning this method can alter default "FAMILLE_ZERO" family. @@ -4292,7 +5172,7 @@ void MEDFileUMesh::addNodeGroup(const DataArrayInt *ids) * \throw If \a ids does not respect the MED file norm. * \throw If a group with name \a ids->getName() already exists. */ -void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids) +void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayIdType *ids) { std::vector levs(getNonEmptyLevelsExt()); if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end()) @@ -4303,7 +5183,7 @@ void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids) if(meshDimRelToMaxExt==1) { addNodeGroup(ids); return ; } MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(meshDimRelToMaxExt)); - DataArrayInt *fam(lev->getOrCreateAndGetFamilyField()); + DataArrayIdType *fam(lev->getOrCreateAndGetFamilyField()); addGroupUnderground(false,ids,fam); } @@ -4313,7 +5193,7 @@ void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids) * \param [in] newFamName - the new family name. * \throw If no family with the given \a id exists. */ -void MEDFileUMesh::setFamilyNameAttachedOnId(int id, const std::string& newFamName) +void MEDFileUMesh::setFamilyNameAttachedOnId(mcIdType id, const std::string& newFamName) { std::string oldName=getFamilyNameGivenId(id); _families.erase(oldName); @@ -4348,7 +5228,7 @@ void MEDFileUMesh::removeMeshAtLevel(int meshDimRelToMax) */ void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCoupling1GTUMesh *m) { - MEDCouplingAutoRefCountObjectPtr elt(new MEDFileUMeshSplitL1(m)); + MCAuto elt(new MEDFileUMeshSplitL1(m)); checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt; } @@ -4367,11 +5247,11 @@ void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCoupling1GTUMesh *m) */ void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld) { - MEDCouplingAutoRefCountObjectPtr elt(new MEDFileUMeshSplitL1(m,newOrOld)); + MCAuto elt(new MEDFileUMeshSplitL1(m,newOrOld)); checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt; } -MEDCouplingAutoRefCountObjectPtr& MEDFileUMesh::checkAndGiveEntryInSplitL1(int meshDimRelToMax, MEDCouplingPointSet *m) +MCAuto& MEDFileUMesh::checkAndGiveEntryInSplitL1(int meshDimRelToMax, MEDCouplingPointSet *m) { dealWithTinyInfo(m); std::vector levSet=getNonEmptyLevels(); @@ -4402,7 +5282,7 @@ MEDCouplingAutoRefCountObjectPtr& MEDFileUMesh::checkAndGiv * * \param [in] ms - List of unstructured meshes lying on the same coordinates and having different mesh dimesnion. * \param [in] renum - the parameter (set to false by default) that tells the beheviour if there is a mesh on \a ms that is not geo type sorted. - * If false, an exception ois thrown. If true the mesh is reordered automatically. It is highly recommanded to let this parameter to false. + * If false, an exception is thrown. If true the mesh is reordered automatically. It is highly recommended to let this parameter to false. * * \throw If \a there is a null pointer in \a ms. * \sa MEDFileUMesh::setMeshAtLevel @@ -4452,7 +5332,7 @@ void MEDFileUMesh::setMeshes(const std::vector& ms, bo * \throw If the meshes in \a ms do not share the same node coordinates array. * \throw If the node coordinates array of \a this mesh (if any) is not the same as that * of the given meshes. - * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkCoherency()). + * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkConsistencyLight()). * \throw If names of some meshes in \a ms are equal. * \throw If \a ms includes a mesh with an empty name. */ @@ -4473,11 +5353,11 @@ void MEDFileUMesh::setGroupsFromScratch(int meshDimRelToMax, const std::vector corr; - MEDCouplingAutoRefCountObjectPtr m=MEDCouplingUMesh::FuseUMeshesOnSameCoords(ms,_zipconn_pol,corr); - std::vector< MEDCouplingAutoRefCountObjectPtr > corr3(corr.begin(),corr.end()); + std::vector corr; + MCAuto m=MEDCouplingUMesh::FuseUMeshesOnSameCoords(ms,_zipconn_pol,corr); + std::vector< MCAuto > corr3(corr.begin(),corr.end()); setMeshAtLevel(meshDimRelToMax,m,renum); - std::vector corr2(corr.begin(),corr.end()); + std::vector corr2(corr.begin(),corr.end()); setGroupsAtLevel(meshDimRelToMax,corr2,true); } @@ -4496,7 +5376,7 @@ void MEDFileUMesh::setGroupsFromScratch(int meshDimRelToMax, const std::vector > corr(ms.size()); + std::vector< MCAuto > corr(ms.size()); int i=0; for(std::vector::const_iterator it=ms.begin();it!=ms.end();it++,i++) { - DataArrayInt *arr=0; + DataArrayIdType *arr=0; bool test=m->areCellsIncludedIn(*it,_zipconn_pol,arr); corr[i]=arr; if(!test) @@ -4531,7 +5411,7 @@ void MEDFileUMesh::setGroupsOnSetMesh(int meshDimRelToMax, const std::vector corr2(corr.begin(),corr.end()); + std::vector corr2(corr.begin(),corr.end()); setGroupsAtLevel(meshDimRelToMax,corr2,renum); } @@ -4541,7 +5421,7 @@ DataArrayDouble *MEDFileUMesh::checkMultiMesh(const std::vectorgetMeshDimension(); for(unsigned int i=1;icheckCoherency(); + ms[i]->checkConsistencyLight(); if(ms[i]->getCoords()!=ret) throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes must share the same coords !"); if(ms[i]->getMeshDimension()!=mdim) @@ -4558,7 +5438,7 @@ DataArrayDouble *MEDFileUMesh::checkMultiMesh(const std::vectorcheckNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setFamilyFieldArr : Problem in size of node family arr ! "); - famArr->incrRef(); - _fam_coords=famArr; + _fam_coords.takeRef(famArr); return ; } if(meshDimRelToMaxExt>1) @@ -4592,23 +5471,20 @@ void MEDFileUMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famAr * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh. * \throw If \a renumArr has an invalid size. */ -void MEDFileUMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr) +void MEDFileUMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayIdType *renumArr) { if(meshDimRelToMaxExt==1) { if(!renumArr) { - _num_coords=0; - _rev_num_coords=0; + _num_coords.nullify(); + _rev_num_coords.nullify(); return ; } - DataArrayDouble *coo(_coords); - if(!coo) + if(_coords.isNull()) throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumFieldArr : the coordinates have not been set !"); - renumArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setRenumArr : Problem in size of node numbering arr ! "); - renumArr->incrRef(); - _num_coords=renumArr; - computeRevNum(); + renumArr->checkNbOfTuplesAndComp(_coords->getNumberOfTuples(),1,"MEDFileUMesh::setRenumArr : Problem in size of node numbering arr ! "); + _num_coords.takeRef(renumArr); return ; } if(meshDimRelToMaxExt>1) @@ -4641,8 +5517,7 @@ void MEDFileUMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiCha if(!coo) throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : the coordinates have not been set !"); nameArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),MED_SNAME_SIZE,"MEDFileUMesh::setNameFieldAtLevel : Problem in size of node numbering arr ! "); - nameArr->incrRef(); - _name_coords=nameArr; + _name_coords.takeRef(nameArr); return ; } if(meshDimRelToMaxExt>1) @@ -4655,9 +5530,18 @@ void MEDFileUMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiCha return _ms[traducedRk]->setNameArr(nameArr); } +void MEDFileUMesh::setGlobalNumFieldAtLevel(int meshDimRelToMaxExt, DataArrayIdType *globalNumArr) +{ + if(meshDimRelToMaxExt!=1) + throw INTERP_KERNEL::Exception("MEDFileUMesh::setGlobalNumFieldAtLevel : Only implemented for meshDimRelToMaxExt==1 for the moment !"); + if(globalNumArr) + globalNumArr->checkNbOfTuplesAndComp(_coords->getNumberOfTuples(),1,"MEDFileUMesh::setGlobalNumFieldAtLevel : Problem in size of node global numbering arr ! "); + _global_num_coords.takeRef(globalNumArr); +} + void MEDFileUMesh::synchronizeTinyInfoOnLeaves() const { - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++) + for(std::vector< MCAuto >::const_iterator it=_ms.begin();it!=_ms.end();it++) if((const MEDFileUMeshSplitL1 *)(*it)) (*it)->synchronizeTinyInfo(*this); } @@ -4665,12 +5549,12 @@ void MEDFileUMesh::synchronizeTinyInfoOnLeaves() const /*! * This method is called by MEDFileMesh::changeFamilyId. It performs only one part of the family id modification. */ -void MEDFileUMesh::changeFamilyIdArr(int oldId, int newId) +void MEDFileUMesh::changeFamilyIdArr(mcIdType oldId, mcIdType newId) { - DataArrayInt *arr=_fam_coords; + DataArrayIdType *arr=_fam_coords; if(arr) arr->changeValue(oldId,newId); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_ms.begin();it!=_ms.end();it++) + for(std::vector< MCAuto >::iterator it=_ms.begin();it!=_ms.end();it++) { MEDFileUMeshSplitL1 *sp=(*it); if(sp) @@ -4680,20 +5564,20 @@ void MEDFileUMesh::changeFamilyIdArr(int oldId, int newId) } } -std::list< MEDCouplingAutoRefCountObjectPtr > MEDFileUMesh::getAllNonNullFamilyIds() const +std::list< MCAuto > MEDFileUMesh::getAllNonNullFamilyIds() const { - std::list< MEDCouplingAutoRefCountObjectPtr > ret; - const DataArrayInt *da(_fam_coords); + std::list< MCAuto > ret; + const DataArrayIdType *da(_fam_coords); if(da) - { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr(const_cast(da))); } - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++) + { da->incrRef(); ret.push_back(MCAuto(const_cast(da))); } + for(std::vector< MCAuto >::const_iterator it=_ms.begin();it!=_ms.end();it++) { const MEDFileUMeshSplitL1 *elt(*it); if(elt) { da=elt->getFamilyField(); if(da) - { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr(const_cast(da))); } + { da->incrRef(); ret.push_back(MCAuto(const_cast(da))); } } } return ret; @@ -4701,10 +5585,10 @@ std::list< MEDCouplingAutoRefCountObjectPtr > MEDFileUMesh::getAll void MEDFileUMesh::computeRevNum() const { - if((const DataArrayInt *)_num_coords) + if(_num_coords.isNotNull()) { - int pos; - int maxValue=_num_coords->getMaxValue(pos); + mcIdType pos; + mcIdType maxValue=_num_coords->getMaxValue(pos); _rev_num_coords=_num_coords->invertArrayN2O2O2N(maxValue+1); } } @@ -4717,79 +5601,79 @@ std::size_t MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren() const 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 DataArrayIdType *)_fam_nodes); + ret.push_back((const DataArrayIdType *)_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 DataArrayIdType *)_fam_cells); + ret.push_back((const DataArrayIdType *)_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 DataArrayIdType *)_fam_faces); + ret.push_back((const DataArrayIdType *)_num_faces); + ret.push_back((const DataArrayIdType *)_rev_num_nodes); ret.push_back((const DataArrayAsciiChar *)_names_faces); - ret.push_back((const DataArrayInt *)_rev_num_cells); + ret.push_back((const DataArrayIdType *)_rev_num_cells); ret.push_back((const MEDCoupling1SGTUMesh*)_faces_if_necessary); return ret; } -int MEDFileStructuredMesh::getMaxAbsFamilyIdInArrays() const +mcIdType MEDFileStructuredMesh::getMaxAbsFamilyIdInArrays() const { - int ret=-std::numeric_limits::max(),tmp=-1; - if((const DataArrayInt *)_fam_nodes) + mcIdType ret=-std::numeric_limits::max(),tmp=-1; + if((const DataArrayIdType *)_fam_nodes) { - int val=_fam_nodes->getMaxValue(tmp); + mcIdType val=_fam_nodes->getMaxValue(tmp); ret=std::max(ret,std::abs(val)); } - if((const DataArrayInt *)_fam_cells) + if((const DataArrayIdType *)_fam_cells) { - int val=_fam_cells->getMaxValue(tmp); + mcIdType val=_fam_cells->getMaxValue(tmp); ret=std::max(ret,std::abs(val)); } - if((const DataArrayInt *)_fam_faces) + if((const DataArrayIdType *)_fam_faces) { - int val=_fam_faces->getMaxValue(tmp); + mcIdType val=_fam_faces->getMaxValue(tmp); ret=std::max(ret,std::abs(val)); } return ret; } -int MEDFileStructuredMesh::getMaxFamilyIdInArrays() const +mcIdType MEDFileStructuredMesh::getMaxFamilyIdInArrays() const { - int ret=-std::numeric_limits::max(),tmp=-1; - if((const DataArrayInt *)_fam_nodes) + mcIdType ret=-std::numeric_limits::max(),tmp=-1; + if((const DataArrayIdType *)_fam_nodes) { - int val=_fam_nodes->getMaxValue(tmp); + mcIdType val=_fam_nodes->getMaxValue(tmp); ret=std::max(ret,val); } - if((const DataArrayInt *)_fam_cells) + if((const DataArrayIdType *)_fam_cells) { - int val=_fam_cells->getMaxValue(tmp); + mcIdType val=_fam_cells->getMaxValue(tmp); ret=std::max(ret,val); } - if((const DataArrayInt *)_fam_faces) + if((const DataArrayIdType *)_fam_faces) { - int val=_fam_faces->getMaxValue(tmp); + mcIdType val=_fam_faces->getMaxValue(tmp); ret=std::max(ret,val); } return ret; } -int MEDFileStructuredMesh::getMinFamilyIdInArrays() const +mcIdType MEDFileStructuredMesh::getMinFamilyIdInArrays() const { - int ret=std::numeric_limits::max(),tmp=-1; - if((const DataArrayInt *)_fam_nodes) + mcIdType ret=std::numeric_limits::max(),tmp=-1; + if((const DataArrayIdType *)_fam_nodes) { - int val=_fam_nodes->getMinValue(tmp); + mcIdType val=_fam_nodes->getMinValue(tmp); ret=std::min(ret,val); } - if((const DataArrayInt *)_fam_cells) + if((const DataArrayIdType *)_fam_cells) { - int val=_fam_cells->getMinValue(tmp); + mcIdType val=_fam_cells->getMinValue(tmp); ret=std::min(ret,val); } - if((const DataArrayInt *)_fam_faces) + if((const DataArrayIdType *)_fam_faces) { - int val=_fam_faces->getMinValue(tmp); + mcIdType val=_fam_faces->getMinValue(tmp); ret=std::min(ret,val); } return ret; @@ -4805,8 +5689,8 @@ bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::s what="Mesh types differ ! This is structured and other is NOT !"; return false; } - const DataArrayInt *famc1=_fam_nodes; - const DataArrayInt *famc2=otherC->_fam_nodes; + const DataArrayIdType *famc1=_fam_nodes; + const DataArrayIdType *famc2=otherC->_fam_nodes; if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0)) { what="Mismatch of families arr on nodes ! One is defined and not other !"; @@ -4955,24 +5839,24 @@ bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::s void MEDFileStructuredMesh::clearNonDiscrAttributes() const { MEDFileMesh::clearNonDiscrAttributes(); - const DataArrayInt *tmp=_fam_nodes; + const DataArrayIdType *tmp=_fam_nodes; if(tmp) - (const_cast(tmp))->setName(""); + (const_cast(tmp))->setName(""); tmp=_num_nodes; if(tmp) - (const_cast(tmp))->setName(""); + (const_cast(tmp))->setName(""); tmp=_fam_cells; if(tmp) - (const_cast(tmp))->setName(""); + (const_cast(tmp))->setName(""); tmp=_num_cells; if(tmp) - (const_cast(tmp))->setName(""); + (const_cast(tmp))->setName(""); tmp=_fam_faces; if(tmp) - (const_cast(tmp))->setName(""); + (const_cast(tmp))->setName(""); tmp=_num_faces; if(tmp) - (const_cast(tmp))->setName(""); + (const_cast(tmp))->setName(""); } /*! @@ -4982,25 +5866,25 @@ void MEDFileStructuredMesh::clearNonDiscrAttributes() const * \param [in] fams - the names of the families of interest. * \param [in] renum - if \c true, the optional numbers of entities, if available, are * returned instead of ids. - * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or + * \return DataArrayIdType * - a new instance of DataArrayIdType holding either ids or * numbers, if available and required, of mesh entities of the families. The caller * is to delete this array using decrRef() as it is no more needed. * \throw If the family field is missing for \a meshDimRelToMaxExt. */ -DataArrayInt *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector& fams, bool renum) const +DataArrayIdType *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector& fams, bool renum) const { - std::vector famIds(getFamiliesIds(fams)); + std::vector famIds(getFamiliesIds(fams)); switch(meshDimRelToMaxExt) { case 1: { - if((const DataArrayInt *)_fam_nodes) + if((const DataArrayIdType *)_fam_nodes) { - MEDCouplingAutoRefCountObjectPtr da; + MCAuto da; if(!famIds.empty()) - da=_fam_nodes->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size()); + da=_fam_nodes->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size()); else - da=_fam_nodes->getIdsEqualList(0,0); + da=_fam_nodes->findIdsEqualList(0,0); if(renum) return MEDFileUMeshSplitL1::Renumber(_num_nodes,da); else @@ -5012,13 +5896,13 @@ DataArrayInt *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, cons } case 0: { - if((const DataArrayInt *)_fam_cells) + if((const DataArrayIdType *)_fam_cells) { - MEDCouplingAutoRefCountObjectPtr da; + MCAuto da; if(!famIds.empty()) - da=_fam_cells->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size()); + da=_fam_cells->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size()); else - da=_fam_cells->getIdsEqualList(0,0); + da=_fam_cells->findIdsEqualList(0,0); if(renum) return MEDFileUMeshSplitL1::Renumber(_num_cells,da); else @@ -5030,13 +5914,13 @@ DataArrayInt *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, cons } case -1: { - if((const DataArrayInt *)_fam_faces) + if((const DataArrayIdType *)_fam_faces) { - MEDCouplingAutoRefCountObjectPtr da; + MCAuto da; if(!famIds.empty()) - da=_fam_faces->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size()); + da=_fam_faces->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size()); else - da=_fam_faces->getIdsEqualList(0,0); + da=_fam_faces->findIdsEqualList(0,0); if(renum) return MEDFileUMeshSplitL1::Renumber(_num_faces,da); else @@ -5061,7 +5945,7 @@ DataArrayInt *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, cons * \throw If \a famArr has an invalid size. * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1 and \a meshDimRelToMaxExt != -1. */ -void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr) +void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayIdType *famArr) { const MEDCouplingStructuredMesh *mesh(getStructuredMesh()); if(!mesh) @@ -5070,22 +5954,25 @@ void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayI { 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 !"); + mcIdType nbCells(mesh->getNumberOfCells()); + if(famArr) + 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 !"); + mcIdType nbNodes(mesh->getNumberOfNodes()); + if(famArr) + 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 !"); + mcIdType nbCells(mesh->getNumberOfCellsOfSubLevelMesh()); + if(famArr) + famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of faces of mesh !"); _fam_faces=famArr; break; } @@ -5104,7 +5991,7 @@ void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayI * \throw If \a renumArr has an invalid size. * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1. */ -void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr) +void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayIdType *renumArr) { const MEDCouplingStructuredMesh *mesh=getStructuredMesh(); if(!mesh) @@ -5113,21 +6000,21 @@ void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayIn { case 0: { - int nbCells=mesh->getNumberOfCells(); + mcIdType 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(); + mcIdType 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(); + mcIdType 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; @@ -5155,23 +6042,24 @@ void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArra { case 0: { - int nbCells=mesh->getNumberOfCells(); + mcIdType 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(); + mcIdType 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(); + mcIdType 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; + _names_faces=nameArr; + break; } default: throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : Only available for levels 0 or 1 or -1 !"); @@ -5180,9 +6068,14 @@ void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArra nameArr->incrRef(); } +void MEDFileStructuredMesh::setGlobalNumFieldAtLevel(int meshDimRelToMaxExt, DataArrayIdType *globalNumArr) +{ + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setGlobalNumFieldAtLevel : not implemented yet !"); +} + /*! * Adds a group of nodes to \a this mesh. - * \param [in] ids - a DataArrayInt providing ids and a name of the group to add. + * \param [in] ids - a DataArrayIdType providing ids and a name of the group to add. * The ids should be sorted and different each other (MED file norm). * * \warning this method can alter default "FAMILLE_ZERO" family. @@ -5194,7 +6087,7 @@ void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArra * \throw If \a ids does not respect the MED file norm. * \throw If a group with name \a ids->getName() already exists. */ -void MEDFileStructuredMesh::addNodeGroup(const DataArrayInt *ids) +void MEDFileStructuredMesh::addNodeGroup(const DataArrayIdType *ids) { addGroup(1,ids); } @@ -5202,7 +6095,7 @@ void MEDFileStructuredMesh::addNodeGroup(const DataArrayInt *ids) /*! * Adds a group of nodes/cells/faces/edges to \a this mesh. * - * \param [in] ids - a DataArrayInt providing ids and a name of the group to add. + * \param [in] ids - a DataArrayIdType providing ids and a name of the group to add. * The ids should be sorted and different each other (MED file norm). * * \warning this method can alter default "FAMILLE_ZERO" family. @@ -5214,9 +6107,9 @@ void MEDFileStructuredMesh::addNodeGroup(const DataArrayInt *ids) * \throw If \a ids does not respect the MED file norm. * \throw If a group with name \a ids->getName() already exists. */ -void MEDFileStructuredMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids) +void MEDFileStructuredMesh::addGroup(int meshDimRelToMaxExt, const DataArrayIdType *ids) { - DataArrayInt *fam(getOrCreateAndGetFamilyFieldAtLevel(meshDimRelToMaxExt)); + DataArrayIdType *fam(getOrCreateAndGetFamilyFieldAtLevel(meshDimRelToMaxExt)); addGroupUnderground(false,ids,fam); return ; } @@ -5224,11 +6117,11 @@ void MEDFileStructuredMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt /*! * Returns the family field for mesh entities of a given dimension. * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities. - * \return const DataArrayInt * - the family field. It is an array of ids of families + * \return const DataArrayIdType * - the family field. It is an array of ids of families * each mesh entity belongs to. It can be \c NULL. * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1. */ -const DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const +const DataArrayIdType *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const { switch(meshDimRelToMaxExt) { @@ -5246,11 +6139,11 @@ const DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelT /*! * Returns the family field for mesh entities of a given dimension. * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities. - * \return const DataArrayInt * - the family field. It is an array of ids of families + * \return const DataArrayIdType * - the family field. It is an array of ids of families * each mesh entity belongs to. It can be \c NULL. * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1. */ -DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) +DataArrayIdType *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) { switch(meshDimRelToMaxExt) { @@ -5268,11 +6161,11 @@ DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxEx /*! * Returns the optional numbers of mesh entities of a given dimension. * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities. - * \return const DataArrayInt * - the array of the entity numbers. + * \return const DataArrayIdType * - the array of the entity numbers. * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh. * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1. */ -const DataArrayInt *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const +const DataArrayIdType *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const { switch(meshDimRelToMaxExt) { @@ -5289,23 +6182,23 @@ const DataArrayInt *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelT /*! * Returns the optional numbers of mesh entities of a given dimension transformed using - * DataArrayInt::invertArrayN2O2O2N(). + * DataArrayIdType::invertArrayN2O2O2N(). * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities. - * \return const DataArrayInt * - the array of the entity numbers transformed using - * DataArrayInt::invertArrayN2O2O2N(). + * \return const DataArrayIdType * - the array of the entity numbers transformed using + * DataArrayIdType::invertArrayN2O2O2N(). * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1. * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh. */ -const DataArrayInt *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const +const DataArrayIdType *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const { if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1) throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getRevNumberFieldAtLevel : Only available for levels 0 or 1 !"); if(meshDimRelToMaxExt==0) { - if((const DataArrayInt *)_num_cells) + if((const DataArrayIdType *)_num_cells) { - int pos; - int maxValue=_num_cells->getMaxValue(pos); + mcIdType pos; + mcIdType maxValue=_num_cells->getMaxValue(pos); _rev_num_cells=_num_cells->invertArrayN2O2O2N(maxValue+1); return _rev_num_cells; } @@ -5314,10 +6207,10 @@ const DataArrayInt *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimR } else { - if((const DataArrayInt *)_num_nodes) + if((const DataArrayIdType *)_num_nodes) { - int pos; - int maxValue=_num_nodes->getMaxValue(pos); + mcIdType pos; + mcIdType maxValue=_num_nodes->getMaxValue(pos); _rev_num_nodes=_num_nodes->invertArrayN2O2O2N(maxValue+1); return _rev_num_nodes; } @@ -5341,6 +6234,11 @@ const DataArrayAsciiChar *MEDFileStructuredMesh::getNameFieldAtLevel(int meshDim } } +MCAuto MEDFileStructuredMesh::getGlobalNumFieldAtLevel(int meshDimRelToMaxExt) const +{ + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGlobalNumFieldAtLevel : not implemented yet for structured mesh !"); +} + /*! * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh. * \return std::vector - a sequence of the relative dimensions: [0]. @@ -5368,7 +6266,7 @@ std::vector MEDFileStructuredMesh::getNonEmptyLevelsExt() const std::vector MEDFileStructuredMesh::getFamArrNonEmptyLevelsExt() const { std::vector ret; - const DataArrayInt *famNodes(_fam_nodes),*famCells(_fam_cells),*famFaces(_fam_faces); + const DataArrayIdType *famNodes(_fam_nodes),*famCells(_fam_cells),*famFaces(_fam_faces); if(famNodes) ret.push_back(1); if(famCells) @@ -5384,7 +6282,7 @@ std::vector MEDFileStructuredMesh::getFamArrNonEmptyLevelsExt() const std::vector MEDFileStructuredMesh::getNumArrNonEmptyLevelsExt() const { std::vector ret; - const DataArrayInt *numNodes(_num_nodes),*numCells(_num_cells),*numFaces(_num_faces); + const DataArrayIdType *numNodes(_num_nodes),*numCells(_num_cells),*numFaces(_num_faces); if(numNodes) ret.push_back(1); if(numCells) @@ -5413,15 +6311,15 @@ std::vector MEDFileStructuredMesh::getNameArrNonEmptyLevelsExt() const /*! * no implementation here, it is not a bug, but intresically no polyhedra in \a this. */ -bool MEDFileStructuredMesh::unPolyze(std::vector& oldCode, std::vector& newCode, DataArrayInt *& o2nRenumCell) +bool MEDFileStructuredMesh::unPolyze(std::vector& oldCode, std::vector& newCode, DataArrayIdType *& o2nRenumCell) { oldCode.clear(); newCode.clear(); o2nRenumCell=0; return false; } -void MEDFileStructuredMesh::changeFamilyIdArr(int oldId, int newId) +void MEDFileStructuredMesh::changeFamilyIdArr(mcIdType oldId, mcIdType newId) { - DataArrayInt *arr=_fam_nodes; + DataArrayIdType *arr=_fam_nodes; if(arr) arr->changeValue(oldId,newId); arr=_fam_cells; @@ -5432,49 +6330,49 @@ void MEDFileStructuredMesh::changeFamilyIdArr(int oldId, int newId) arr->changeValue(oldId,newId); } -std::list< MEDCouplingAutoRefCountObjectPtr > MEDFileStructuredMesh::getAllNonNullFamilyIds() const +std::list< MCAuto > MEDFileStructuredMesh::getAllNonNullFamilyIds() const { - std::list< MEDCouplingAutoRefCountObjectPtr > ret; - const DataArrayInt *da(_fam_nodes); + std::list< MCAuto > ret; + const DataArrayIdType *da(_fam_nodes); if(da) - { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr(const_cast(da))); } + { da->incrRef(); ret.push_back(MCAuto(const_cast(da))); } da=_fam_cells; if(da) - { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr(const_cast(da))); } + { da->incrRef(); ret.push_back(MCAuto(const_cast(da))); } da=_fam_faces; if(da) - { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr(const_cast(da))); } + { da->incrRef(); ret.push_back(MCAuto(const_cast(da))); } return ret; } void MEDFileStructuredMesh::deepCpyAttributes() { - if((const DataArrayInt*)_fam_nodes) - _fam_nodes=_fam_nodes->deepCpy(); - if((const DataArrayInt*)_num_nodes) - _num_nodes=_num_nodes->deepCpy(); + if((const DataArrayIdType*)_fam_nodes) + _fam_nodes=_fam_nodes->deepCopy(); + if((const DataArrayIdType*)_num_nodes) + _num_nodes=_num_nodes->deepCopy(); 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(); + _names_nodes=_names_nodes->deepCopy(); + if((const DataArrayIdType*)_fam_cells) + _fam_cells=_fam_cells->deepCopy(); + if((const DataArrayIdType*)_num_cells) + _num_cells=_num_cells->deepCopy(); 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(); + _names_cells=_names_cells->deepCopy(); + if((const DataArrayIdType*)_fam_faces) + _fam_faces=_fam_faces->deepCopy(); + if((const DataArrayIdType*)_num_faces) + _num_faces=_num_faces->deepCopy(); 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) - _rev_num_cells=_rev_num_cells->deepCpy(); + _names_faces=_names_faces->deepCopy(); + if((const DataArrayIdType*)_rev_num_nodes) + _rev_num_nodes=_rev_num_nodes->deepCopy(); + if((const DataArrayIdType*)_rev_num_cells) + _rev_num_cells=_rev_num_cells->deepCopy(); } /*! - * Returns a pointer to mesh at the specified level (here 0 is compulsary for cartesian mesh). + * Returns a pointer to mesh at the specified level (here 0 is compulsory for cartesian mesh). * * \return a pointer to cartesian mesh that need to be managed by the caller. * \warning the returned pointer has to be managed by the caller. @@ -5487,8 +6385,9 @@ void MEDFileStructuredMesh::deepCpyAttributes() * \return MEDCouplingMesh * - a pointer to MEDCouplingMesh that the caller is to * delete using decrRef() as it is no more needed. */ -MEDCouplingMesh *MEDFileStructuredMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const +MEDCouplingMesh *MEDFileStructuredMesh::getMeshAtLevel(int meshDimRelToMax, bool renum) const { + checkCartesian(); if(renum) throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support renumbering ! To do it perform request of renum array directly !"); const MEDCouplingStructuredMesh *m(getStructuredMesh()); @@ -5503,9 +6402,9 @@ MEDCouplingMesh *MEDFileStructuredMesh::getGenMeshAtLevel(int meshDimRelToMax, b 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 !"); + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getMeshAtLevel : level -1 requested must be non empty to be able to compute unstructured sub mesh !"); buildMinusOneImplicitPartIfNeeded(); - MEDCouplingMesh *ret(_faces_if_necessary); + MEDCoupling1SGTUMesh *ret(_faces_if_necessary); if(ret) ret->incrRef(); return ret; @@ -5515,13 +6414,46 @@ MEDCouplingMesh *MEDFileStructuredMesh::getGenMeshAtLevel(int meshDimRelToMax, b } } +/*! + * Returns all relative mesh levels (**excluding nodes**) where given families are defined. + * To include nodes, call getFamsNonEmptyLevelsExt() method. + * \param [in] fams - the name of the family of interest. + * \return std::vector - a sequence of the relative dimensions. + */ +std::vector MEDFileStructuredMesh::getFamsNonEmptyLevels(const std::vector& fams) const +{ + std::vector lvls; + std::vector famIds(getFamiliesIds(fams)); + const DataArrayIdType *famCells(_fam_cells),*famFaces(_fam_faces); + if(famCells && famCells->presenceOfValue(famIds)) + lvls.push_back(0); + if(famFaces && famFaces->presenceOfValue(famIds)) + lvls.push_back(-1); + return lvls; +} + +/*! + * Returns all relative mesh levels (including nodes) where given families are defined. + * \param [in] fams - the names of the families of interest. + * \return std::vector - a sequence of the relative dimensions. + */ +std::vector MEDFileStructuredMesh::getFamsNonEmptyLevelsExt(const std::vector& fams) const +{ + std::vector lvls(getFamsNonEmptyLevels(fams)); + std::vector famIds(getFamiliesIds(fams)); + const DataArrayIdType *famNodes(_fam_nodes); + if(famNodes && famNodes->presenceOfValue(famIds)) + lvls.push_back(1); + return lvls; +} + /*! * Returns number of mesh entities of a given relative dimension in \a this mesh. * \param [in] meshDimRelToMaxExt - the relative dimension of interest. - * \return int - the number of entities. + * \return mcIdType - the number of entities. * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh. */ -int MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const +mcIdType MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const { const MEDCouplingStructuredMesh *cmesh(getStructuredMesh()); if(!cmesh) @@ -5539,7 +6471,7 @@ int MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const } } -int MEDFileStructuredMesh::getNumberOfNodes() const +mcIdType MEDFileStructuredMesh::getNumberOfNodes() const { const MEDCouplingStructuredMesh *cmesh(getStructuredMesh()); if(!cmesh) @@ -5547,7 +6479,7 @@ int MEDFileStructuredMesh::getNumberOfNodes() const return cmesh->getNumberOfNodes(); } -int MEDFileStructuredMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const +mcIdType MEDFileStructuredMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const { const MEDCouplingStructuredMesh *cmesh(getStructuredMesh()); if(!cmesh) @@ -5571,7 +6503,7 @@ bool MEDFileStructuredMesh::hasImplicitPart() const /*! * \sa MEDFileStructuredMesh::getImplicitFaceMesh */ -int MEDFileStructuredMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const +mcIdType 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); @@ -5619,6 +6551,7 @@ void MEDFileStructuredMesh::releaseImplicitPartIfAny() const */ MEDCoupling1SGTUMesh *MEDFileStructuredMesh::getImplicitFaceMesh() const { + checkCartesian(); return _faces_if_necessary; } @@ -5647,27 +6580,35 @@ std::vector MEDFileStructuredMesh::getGeoType } } +mcIdType MEDFileStructuredMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const +{ + if(ct!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension())) + return 0; + else + return getNumberOfCellsAtLevel(0); +} + void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector& nodesFetched) const { if(st.getNumberOfItems()!=1) throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : The sturture of field is not lying on single geo type ! it is not managed yet for structured mesh !"); if(st[0].getGeo()!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension())) throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : The sturture of field is not lying on expected geo type !"); - if(getNumberOfNodes()!=(int)nodesFetched.size()) + if(getNumberOfNodes()!=(mcIdType)nodesFetched.size()) throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : invalid size of array !"); if(st[0].getPflName().empty()) { std::fill(nodesFetched.begin(),nodesFetched.end(),true); return ; } - const DataArrayInt *arr(globs->getProfile(st[0].getPflName())); + const DataArrayIdType *arr(globs->getProfile(st[0].getPflName())); const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();//cmesh not null because getNumberOfNodes called before - int sz(nodesFetched.size()); - for(const int *work=arr->begin();work!=arr->end();work++) + mcIdType sz(ToIdType(nodesFetched.size())); + for(const mcIdType *work=arr->begin();work!=arr->end();work++) { - std::vector conn; + std::vector conn; cmesh->getNodeIdsOfCell(*work,conn); - for(std::vector::const_iterator it=conn.begin();it!=conn.end();it++) + for(std::vector::const_iterator it=conn.begin();it!=conn.end();it++) if(*it>=0 && *it& famCells, MEDCouplingAutoRefCountObjectPtr& numCells, MEDCouplingAutoRefCountObjectPtr& namesCells) + MCAuto& famCells, MCAuto& numCells, MCAuto& namesCells) { med_bool chgt=MED_FALSE,trsf=MED_FALSE; med_geometry_type geoTypeReq=MEDFileStructuredMesh::GetGeoTypeFromMeshDim(meshDim); - int nbOfElt(0); + mcIdType nbOfElt(0); 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()) { - famCells=DataArrayInt::New(); - famCells->alloc(nbOfElt,1); - MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,famCells->getPointer())); + MCAuto miFamCells=DataArrayMedInt::New(); + miFamCells->alloc(nbOfElt,1); + MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,miFamCells->getPointer())); + famCells = FromMedIntArray( miFamCells ); } } nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NUMBER,MED_NODAL,&chgt,&trsf); @@ -5702,9 +6644,10 @@ void MEDFileStructuredMesh::LoadStrMeshDAFromFile(med_idt fid, int meshDim, int { if(!mrs || mrs->isCellNumFieldReading()) { - numCells=DataArrayInt::New(); - numCells->alloc(nbOfElt,1); - MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,numCells->getPointer())); + MCAuto miNumCells=DataArrayMedInt::New(); + miNumCells->alloc(nbOfElt,1); + MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,miNumCells->getPointer())); + numCells = FromMedIntArray( miNumCells ); } } nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NAME,MED_NODAL,&chgt,&trsf); @@ -5731,19 +6674,20 @@ void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt setTimeUnit(strm->getTimeUnit()); MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs); med_bool chgt=MED_FALSE,trsf=MED_FALSE; - int nbOfElt(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf)); + mcIdType nbOfElt(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf)); if(nbOfElt>0) { if(!mrs || mrs->isNodeFamilyFieldReading()) { - int nbNodes(getNumberOfNodes()); + mcIdType 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. + MCAuto miFamNodes=DataArrayMedInt::New(); + miFamNodes->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... - _fam_nodes->fillWithZero(); - MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_fam_nodes->getPointer())); + miFamNodes->fillWithZero(); + MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,miFamNodes->getPointer())); + _fam_nodes = FromMedIntArray( miFamNodes ); } } nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NUMBER,MED_NODAL,&chgt,&trsf); @@ -5751,9 +6695,10 @@ void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt { if(!mrs || mrs->isNodeNumFieldReading()) { - _num_nodes=DataArrayInt::New(); - _num_nodes->alloc(nbOfElt,1); - MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_num_nodes->getPointer())); + MCAuto miNumNodes=DataArrayMedInt::New(); + miNumNodes->alloc(nbOfElt,1); + MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,miNumNodes->getPointer())); + _num_nodes = FromMedIntArray( miNumNodes ); } } nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NAME,MED_NODAL,&chgt,&trsf); @@ -5778,18 +6723,18 @@ void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const std::string& ma int meshDim(getStructuredMesh()->getMeshDimension()); med_geometry_type geoTypeReq(GetGeoTypeFromMeshDim(meshDim)),geoTypeReq2(GetGeoTypeFromMeshDim(meshDim-1)); // - if((const DataArrayInt *)_fam_cells) - MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_fam_cells->getNumberOfTuples(),_fam_cells->getConstPointer())); - if((const DataArrayInt *)_fam_faces) - MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_fam_faces->getNumberOfTuples(),_fam_faces->getConstPointer())); - if((const DataArrayInt *)_fam_nodes) - MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_fam_nodes->getNumberOfTuples(),_fam_nodes->getConstPointer())); - if((const DataArrayInt *)_num_cells) - MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_num_cells->getNumberOfTuples(),_num_cells->getConstPointer())); - if((const DataArrayInt *)_num_faces) - MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_num_faces->getNumberOfTuples(),_num_faces->getConstPointer())); - if((const DataArrayInt *)_num_nodes) - MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_num_nodes->getNumberOfTuples(),_num_nodes->getConstPointer())); + if((const DataArrayIdType *)_fam_cells) + MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,ToMedInt(_fam_cells->getNumberOfTuples()),ToMedIntArray(_fam_cells)->getConstPointer())); + if((const DataArrayIdType *)_fam_faces) + MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,ToMedInt(_fam_faces->getNumberOfTuples()),ToMedIntArray(_fam_faces)->getConstPointer())); + if((const DataArrayIdType *)_fam_nodes) + MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,ToMedInt(_fam_nodes->getNumberOfTuples()),ToMedIntArray(_fam_nodes)->getConstPointer())); + if((const DataArrayIdType *)_num_cells) + MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,ToMedInt(_num_cells->getNumberOfTuples()),ToMedIntArray(_num_cells)->getConstPointer())); + if((const DataArrayIdType *)_num_faces) + MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,ToMedInt(_num_faces->getNumberOfTuples()),ToMedIntArray(_num_faces)->getConstPointer())); + if((const DataArrayIdType *)_num_nodes) + MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,ToMedInt(_num_nodes->getNumberOfTuples()),ToMedIntArray(_num_nodes)->getConstPointer())); if((const DataArrayAsciiChar *)_names_cells) { if(_names_cells->getNumberOfComponents()!=MED_SNAME_SIZE) @@ -5798,7 +6743,7 @@ void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const std::string& ma oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } - MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_names_cells->getNumberOfTuples(),_names_cells->getConstPointer())); + MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,ToMedInt(_names_cells->getNumberOfTuples()),_names_cells->getConstPointer())); } if((const DataArrayAsciiChar *)_names_faces) { @@ -5808,7 +6753,7 @@ void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const std::string& ma oss << " ! The array has " << _names_faces->getNumberOfComponents() << " components !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } - MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_names_faces->getNumberOfTuples(),_names_faces->getConstPointer())); + MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,ToMedInt(_names_faces->getNumberOfTuples()),_names_faces->getConstPointer())); } if((const DataArrayAsciiChar *)_names_nodes) { @@ -5818,7 +6763,7 @@ void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const std::string& ma oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } - MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_names_nodes->getNumberOfTuples(),_names_nodes->getConstPointer())); + MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,ToMedInt(_names_nodes->getNumberOfTuples()),_names_nodes->getConstPointer())); } // MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa.c_str(),_families,_groups,_too_long_str); @@ -5846,19 +6791,13 @@ MEDFileCMesh *MEDFileCMesh::New() */ MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs) { - std::vector ms=MEDLoader::GetMeshNames(fileName); - if(ms.empty()) - { - std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - int dt,it; - ParaMEDMEM::MEDCouplingMeshType meshType; - std::string dummy2; - MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2); - return new MEDFileCMesh(fid,ms.front(),dt,it,mrs); + MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName)); + return New(fid,mrs); +} + +MEDFileCMesh *MEDFileCMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs) +{ + return NewForTheFirstMeshInFile(fid,mrs); } /*! @@ -5877,8 +6816,12 @@ MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, MEDFileMeshReadSele */ MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) { - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); + MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName)); + return New(fid,mName,dt,it,mrs); +} + +MEDFileCMesh *MEDFileCMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) +{ return new MEDFileCMesh(fid,mName,dt,it,mrs); } @@ -5936,9 +6879,9 @@ std::string MEDFileCMesh::advancedRepr() const return simpleRepr(); } -MEDFileMesh *MEDFileCMesh::shallowCpy() const +MEDFileCMesh *MEDFileCMesh::shallowCpy() const { - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileCMesh(*this); + MCAuto ret(new MEDFileCMesh(*this)); return ret.retn(); } @@ -5947,11 +6890,12 @@ MEDFileMesh *MEDFileCMesh::createNewEmpty() const return new MEDFileCMesh; } -MEDFileMesh *MEDFileCMesh::deepCpy() const +MEDFileCMesh *MEDFileCMesh::deepCopy() const { - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileCMesh(*this); + MCAuto ret(new MEDFileCMesh(*this)); + ret->deepCpyEquivalences(*this); if((const MEDCouplingCMesh*)_cmesh) - ret->_cmesh=static_cast(_cmesh->deepCpy()); + ret->_cmesh=static_cast(_cmesh->deepCopy()); ret->deepCpyAttributes(); return ret.retn(); } @@ -6010,20 +6954,20 @@ MEDFileCMesh::MEDFileCMesh() MEDFileCMesh::MEDFileCMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) try { - loadCMeshFromFile(fid,mName,dt,it,mrs); - loadJointsFromFile(fid); + loadLLWithAdditionalItems(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) +void MEDFileCMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) { - ParaMEDMEM::MEDCouplingMeshType meshType; + MEDCoupling::MEDCouplingMeshType meshType; int dummy0,dummy1; std::string dtunit; - int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit); + MEDCoupling::MEDCouplingAxisType axType; + INTERP_KERNEL::AutoCppPtr mid(MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit)); if(meshType!=CARTESIAN) { std::ostringstream oss; oss << "Trying to load as cartesian an existing mesh with name '" << mName << "' that is NOT cartesian !"; @@ -6031,6 +6975,7 @@ void MEDFileCMesh::loadCMeshFromFile(med_idt fid, const std::string& mName, int } MEDFileCMeshL2 loaderl2; loaderl2.loadAll(fid,mid,mName,dt,it); + setAxisType(axType); MEDCouplingCMesh *mesh=loaderl2.getMesh(); mesh->incrRef(); _cmesh=mesh; @@ -6067,7 +7012,30 @@ void MEDFileCMesh::setMesh(MEDCouplingCMesh *m) _cmesh=m; } -void MEDFileCMesh::writeLL(med_idt fid) const +MEDFileMesh *MEDFileCMesh::cartesianize() const +{ + if(getAxisType()==AX_CART) + { + incrRef(); + return const_cast(this); + } + else + { + const MEDCouplingCMesh *cmesh(getMesh()); + if(!cmesh) + throw INTERP_KERNEL::Exception("MEDFileCMesh::cartesianize : impossible to turn into cartesian because the mesh is null !"); + MCAuto clmesh(cmesh->buildCurveLinear()); + MCAuto coords(clmesh->getCoords()->cartesianize(getAxisType())); + clmesh->setCoords(coords); + MCAuto ret(MEDFileCurveLinearMesh::New()); + ret->MEDFileStructuredMesh::operator=(*this); + ret->setMesh(clmesh); + ret->setAxisType(AX_CART); + return ret.retn(); + } +} + +void MEDFileCMesh::writeMeshLL(med_idt fid) const { INTERP_KERNEL::AutoPtr maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); INTERP_KERNEL::AutoPtr desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE); @@ -6086,19 +7054,18 @@ void MEDFileCMesh::writeLL(med_idt fid) const MEDLoaderBase::safeStrCpy2(c.c_str(),MED_SNAME_SIZE-1,comp+i*MED_SNAME_SIZE,_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,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo } - MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,spaceDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit)); - MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa)); - MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MED_CARTESIAN_GRID)); + MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,spaceDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit)); + if(_univ_wr_status) + MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa)); + MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MEDFileMeshL2::TraduceAxisTypeRevStruct(getAxisType()))); for(int i=0;igetCoordsAt(i); - MEDFILESAFECALLERWR0(MEDmeshGridIndexCoordinateWr,(fid,maa,_iteration,_order,_time,i+1,da->getNumberOfTuples(),da->getConstPointer())); + MEDFILESAFECALLERWR0(MEDmeshGridIndexCoordinateWr,(fid,maa,_iteration,_order,_time,i+1,ToMedInt(da->getNumberOfTuples()),da->getConstPointer())); } // std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE)); MEDFileStructuredMesh::writeStructuredLL(fid,meshName); - - writeJoints(fid); } void MEDFileCMesh::synchronizeTinyInfoOnLeaves() const @@ -6117,27 +7084,25 @@ MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New() return new MEDFileCurveLinearMesh; } +MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs) +{ + return NewForTheFirstMeshInFile(fid,mrs); +} + MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs) { - std::vector ms=MEDLoader::GetMeshNames(fileName); - if(ms.empty()) - { - std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - int dt,it; - ParaMEDMEM::MEDCouplingMeshType meshType; - std::string dummy2; - MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2); - return new MEDFileCurveLinearMesh(fid,ms.front(),dt,it,mrs); + MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName)); + return New(fid,mrs); } MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) { - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); + MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName)); + return New(fid,mName,dt,it,mrs); +} + +MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) +{ return new MEDFileCurveLinearMesh(fid,mName,dt,it,mrs); } @@ -6153,9 +7118,9 @@ std::vector MEDFileCurveLinearMesh::getDirectChildrenWi return ret; } -MEDFileMesh *MEDFileCurveLinearMesh::shallowCpy() const +MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::shallowCpy() const { - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileCurveLinearMesh(*this); + MCAuto ret(new MEDFileCurveLinearMesh(*this)); return ret.retn(); } @@ -6164,11 +7129,12 @@ MEDFileMesh *MEDFileCurveLinearMesh::createNewEmpty() const return new MEDFileCurveLinearMesh; } -MEDFileMesh *MEDFileCurveLinearMesh::deepCpy() const +MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::deepCopy() const { - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileCurveLinearMesh(*this); + MCAuto ret(new MEDFileCurveLinearMesh(*this)); + ret->deepCpyEquivalences(*this); if((const MEDCouplingCurveLinearMesh*)_clmesh) - ret->_clmesh=static_cast(_clmesh->deepCpy()); + ret->_clmesh=static_cast(_clmesh->deepCopy()); ret->deepCpyAttributes(); return ret.retn(); } @@ -6176,10 +7142,17 @@ MEDFileMesh *MEDFileCurveLinearMesh::deepCpy() const int MEDFileCurveLinearMesh::getMeshDimension() const { if(!((const MEDCouplingCurveLinearMesh*)_clmesh)) - throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get meshdimension because no mesh set !"); + throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get mesh dimension because no mesh set !"); return _clmesh->getMeshDimension(); } +int MEDFileCurveLinearMesh::getSpaceDimension() const +{ + if(!((const MEDCouplingCurveLinearMesh*)_clmesh)) + throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get space dimension because no mesh set !"); + return _clmesh->getSpaceDimension(); +} + std::string MEDFileCurveLinearMesh::simpleRepr() const { return MEDFileStructuredMesh::simpleRepr(); @@ -6252,6 +7225,31 @@ void MEDFileCurveLinearMesh::setMesh(MEDCouplingCurveLinearMesh *m) _clmesh=m; } +MEDFileMesh *MEDFileCurveLinearMesh::cartesianize() const +{ + if(getAxisType()==AX_CART) + { + incrRef(); + return const_cast(this); + } + else + { + const MEDCouplingCurveLinearMesh *mesh(getMesh()); + if(!mesh) + throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::cartesianize : impossible to turn into cartesian because the mesh is null !"); + const DataArrayDouble *coords(mesh->getCoords()); + if(!coords) + throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::cartesianize : coordinate pointer in mesh is null !"); + MCAuto ret(new MEDFileCurveLinearMesh(*this)); + MCAuto mesh2(mesh->clone(false)); + MCAuto coordsCart(coords->cartesianize(getAxisType())); + mesh2->setCoords(coordsCart); + ret->setMesh(mesh2); + ret->setAxisType(AX_CART); + return ret.retn(); + } +} + const MEDCouplingStructuredMesh *MEDFileCurveLinearMesh::getStructuredMesh() const { synchronizeTinyInfoOnLeaves(); @@ -6265,15 +7263,14 @@ MEDFileCurveLinearMesh::MEDFileCurveLinearMesh() MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) try { - loadCLMeshFromFile(fid,mName,dt,it,mrs); - loadJointsFromFile(fid); + loadLLWithAdditionalItems(fid,mName,dt,it,mrs); } catch(INTERP_KERNEL::Exception& e) { throw e; } -void MEDFileCurveLinearMesh::writeLL(med_idt fid) const +void MEDFileCurveLinearMesh::writeMeshLL(med_idt fid) const { INTERP_KERNEL::AutoPtr maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); INTERP_KERNEL::AutoPtr desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE); @@ -6287,7 +7284,7 @@ void MEDFileCurveLinearMesh::writeLL(med_idt fid) const INTERP_KERNEL::AutoPtr unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE); const DataArrayDouble *coords=_clmesh->getCoords(); if(!coords) - throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::writeLL : no coordinates set !"); + throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::writeMeshLL : no coordinates set !"); for(int i=0;igetCoords()->getInfoOnComponent(i)); @@ -6296,26 +7293,27 @@ void MEDFileCurveLinearMesh::writeLL(med_idt fid) const MEDLoaderBase::safeStrCpy2(c.c_str(),MED_SNAME_SIZE-1,comp+i*MED_SNAME_SIZE,_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,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo } - MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit)); - MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa)); + MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit)); + if(_univ_wr_status) + MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa)); MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MED_CURVILINEAR_GRID)); - std::vector nodeGridSt=_clmesh->getNodeGridStructure(); - MEDFILESAFECALLERWR0(MEDmeshGridStructWr,(fid,maa,_iteration,_order,_time,&nodeGridSt[0])); + std::vector nodeGridSt=_clmesh->getNodeGridStructure(); + MEDFILESAFECALLERWR0(MEDmeshGridStructWr,(fid,maa,_iteration,_order,_time,ToMedIntArray(nodeGridSt)->getConstPointer())); - MEDFILESAFECALLERWR0(MEDmeshNodeCoordinateWr,(fid,maa,_iteration,_order,_time,MED_FULL_INTERLACE,coords->getNumberOfTuples(),coords->begin())); + MEDFILESAFECALLERWR0(MEDmeshNodeCoordinateWr,(fid,maa,_iteration,_order,_time,MED_FULL_INTERLACE,ToMedInt(coords->getNumberOfTuples()),coords->begin())); // std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE)); MEDFileStructuredMesh::writeStructuredLL(fid,meshName); - - writeJoints(fid); } -void MEDFileCurveLinearMesh::loadCLMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) +void MEDFileCurveLinearMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) { - ParaMEDMEM::MEDCouplingMeshType meshType; + MEDCoupling::MEDCouplingMeshType meshType; int dummy0,dummy1; std::string dtunit; - int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit); + MEDCoupling::MEDCouplingAxisType axType; + INTERP_KERNEL::AutoCppPtr mid(MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit)); + setAxisType(axType); if(meshType!=CURVE_LINEAR) { std::ostringstream oss; oss << "Trying to load as curve linear an existing mesh with name '" << mName << "' that is NOT curve linear !"; @@ -6334,37 +7332,49 @@ MEDFileMeshMultiTS *MEDFileMeshMultiTS::New() return new MEDFileMeshMultiTS; } +MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(med_idt fid) +{ + return new MEDFileMeshMultiTS(fid); +} + MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName) { - return new MEDFileMeshMultiTS(fileName); + MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName)); + return New(fid); +} + +MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(med_idt fid, const std::string& mName) +{ + return new MEDFileMeshMultiTS(fid,mName); } MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName, const std::string& mName) { - return new MEDFileMeshMultiTS(fileName,mName); + MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName)); + return New(fid,mName); } -MEDFileMeshMultiTS *MEDFileMeshMultiTS::deepCpy() const +MEDFileMeshMultiTS *MEDFileMeshMultiTS::deepCopy() const { - MEDCouplingAutoRefCountObjectPtr ret=MEDFileMeshMultiTS::New(); - std::vector< MEDCouplingAutoRefCountObjectPtr > meshOneTs(_mesh_one_ts.size()); - std::size_t i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++,i++) + MCAuto ret(MEDFileMeshMultiTS::New()); + std::vector< MCAuto > meshOneTs(_mesh_one_ts.size()); + std::size_t i(0); + for(std::vector< MCAuto >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++,i++) if((const MEDFileMesh *)*it) - meshOneTs[i]=(*it)->deepCpy(); + meshOneTs[i]=(*it)->deepCopy(); ret->_mesh_one_ts=meshOneTs; return ret.retn(); } std::size_t MEDFileMeshMultiTS::getHeapMemorySizeWithoutChildren() const { - return _mesh_one_ts.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr); + return _mesh_one_ts.capacity()*sizeof(MCAuto); } 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++) + for(std::vector< MCAuto >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++) ret.push_back((const MEDFileMesh *)*it); return ret; } @@ -6387,7 +7397,7 @@ void MEDFileMeshMultiTS::setName(const std::string& newMeshName) bool MEDFileMeshMultiTS::changeNames(const std::vector< std::pair >& modifTab) { bool ret=false; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++) + for(std::vector< MCAuto >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++) { MEDFileMesh *cur(*it); if(cur) @@ -6396,6 +7406,19 @@ bool MEDFileMeshMultiTS::changeNames(const std::vector< std::pair >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++) + { + MEDFileMesh *cur(*it); + if(cur) + { + MCAuto ccur(cur->cartesianize());// Attention ! Do not wrap these two lines because memory leak ! + *it=ccur; + } + } +} + MEDFileMesh *MEDFileMeshMultiTS::getOneTimeStep() const { if(_mesh_one_ts.empty()) @@ -6409,7 +7432,7 @@ void MEDFileMeshMultiTS::setOneTimeStep(MEDFileMesh *mesh1TimeStep) throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::setOneTimeStep : input pointer should be different from 0 !"); _mesh_one_ts.resize(1); mesh1TimeStep->incrRef(); - //MEDCouplingAutoRefCountObjectPtr toto=mesh1TimeStep; + //MCAuto toto=mesh1TimeStep; _mesh_one_ts[0]=mesh1TimeStep; } @@ -6425,18 +7448,34 @@ MEDFileJoints * MEDFileMeshMultiTS::getJoints() const */ void MEDFileMeshMultiTS::setJoints( MEDFileJoints* joints ) { - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++) + for(std::vector< MCAuto >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++) { (*it)->setJoints( joints ); } } -void MEDFileMeshMultiTS::write(med_idt fid) const +bool MEDFileMeshMultiTS::presenceOfStructureElements() const +{ + for(std::vector< MCAuto >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++) + if((*it).isNotNull()) + if((*it)->presenceOfStructureElements()) + return true; + return false; +} + +void MEDFileMeshMultiTS::killStructureElements() +{ + for(std::vector< MCAuto >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++) + if((*it).isNotNull()) + (*it)->killStructureElements(); +} + +void MEDFileMeshMultiTS::writeLL(med_idt fid) const { MEDFileJoints *joints(getJoints()); bool jointsWritten(false); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++) + for(std::vector< MCAuto >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++) { if ( jointsWritten ) const_cast(**it).setJoints( 0 ); @@ -6444,64 +7483,53 @@ void MEDFileMeshMultiTS::write(med_idt fid) const jointsWritten = true; (*it)->copyOptionsFrom(*this); - (*it)->write(fid); + (*it)->writeLL(fid); } (const_cast(this))->setJoints( joints ); // restore joints } -void MEDFileMeshMultiTS::write(const std::string& fileName, int mode) const -{ - med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod); - std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\""; - MEDFileUtilities::CheckMEDCode(fid,fid,oss.str()); - write(fid); -} - -void MEDFileMeshMultiTS::loadFromFile(const std::string& fileName, const std::string& mName) +void MEDFileMeshMultiTS::loadFromFile(med_idt fid, const std::string& mName) { - MEDFileJoints* joints = 0; + MEDFileJoints *joints(0); if ( !_mesh_one_ts.empty() && getOneTimeStep() ) { // joints of mName already read, pass them to MEDFileMesh::New() to prevent repeated reading joints = getOneTimeStep()->getJoints(); } - _mesh_one_ts.clear(); //for the moment to be improved - _mesh_one_ts.push_back( MEDFileMesh::New(fileName,mName,-1,-1,0, joints )); + _mesh_one_ts.push_back( MEDFileMesh::New(fid,mName,-1,-1,0, joints )); } MEDFileMeshMultiTS::MEDFileMeshMultiTS() { } -MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName) +MEDFileMeshMultiTS::MEDFileMeshMultiTS(med_idt fid) try { - std::vector ms=MEDLoader::GetMeshNames(fileName); + std::vector ms(MEDLoaderNS::getMeshNamesFid(fid)); if(ms.empty()) { - std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !"; + std::ostringstream oss; oss << "MEDFileMeshMultiTS : no meshes in file \"" << FileNameFromFID(fid) << "\" !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); int dt,it; - ParaMEDMEM::MEDCouplingMeshType meshType; + MEDCoupling::MEDCouplingMeshType meshType; std::string dummy2; - MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2); - loadFromFile(fileName,ms.front()); + MEDCoupling::MEDCouplingAxisType dummy3; + MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2); + loadFromFile(fid,ms.front()); } catch(INTERP_KERNEL::Exception& e) { throw e; } -MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName, const std::string& mName) +MEDFileMeshMultiTS::MEDFileMeshMultiTS(med_idt fid, const std::string& mName) try { - loadFromFile(fileName,mName); + loadFromFile(fid,mName); } catch(INTERP_KERNEL::Exception& e) { @@ -6513,34 +7541,32 @@ MEDFileMeshes *MEDFileMeshes::New() return new MEDFileMeshes; } +MEDFileMeshes *MEDFileMeshes::New(med_idt fid) +{ + return new MEDFileMeshes(fid); +} + MEDFileMeshes *MEDFileMeshes::New(const std::string& fileName) { - return new MEDFileMeshes(fileName); + MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName)); + return New(fid); } -void MEDFileMeshes::write(med_idt fid) const +void MEDFileMeshes::writeLL(med_idt fid) const { - checkCoherency(); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_meshes.begin();it!=_meshes.end();it++) + checkConsistencyLight(); + for(std::vector< MCAuto >::const_iterator it=_meshes.begin();it!=_meshes.end();it++) { (*it)->copyOptionsFrom(*this); - (*it)->write(fid); + (*it)->writeLL(fid); } } -void MEDFileMeshes::write(const std::string& fileName, int mode) const -{ - med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod); - std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\""; - MEDFileUtilities::CheckMEDCode(fid,fid,oss.str()); - checkCoherency(); - write(fid); -} +// MEDFileMeshes::writ checkConsistencyLight(); int MEDFileMeshes::getNumberOfMeshes() const { - return _meshes.size(); + return (int)_meshes.size(); } MEDFileMeshesIterator *MEDFileMeshes::iterator() @@ -6577,7 +7603,7 @@ std::vector MEDFileMeshes::getMeshesNames() const { std::vector ret(_meshes.size()); int i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++) + for(std::vector< MCAuto >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++) { const MEDFileMeshMultiTS *f=(*it); if(f) @@ -6592,21 +7618,11 @@ std::vector MEDFileMeshes::getMeshesNames() const } return ret; } -/*const MEDFileJoints* MEDFileMeshes::getJoints() const -{ - const MEDFileJoints *ret=_joints; - if(!ret) - { - std::ostringstream oss; oss << "MEDFileMeshes::getJoints : joints is not defined !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return ret; -}*/ bool MEDFileMeshes::changeNames(const std::vector< std::pair >& modifTab) { bool ret=false; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_meshes.begin();it!=_meshes.end();it++) + for(std::vector< MCAuto >::iterator it=_meshes.begin();it!=_meshes.end();it++) { MEDFileMeshMultiTS *cur(*it); if(cur) @@ -6615,6 +7631,16 @@ bool MEDFileMeshes::changeNames(const std::vector< std::pair >::iterator it=_meshes.begin();it!=_meshes.end();it++) + { + MEDFileMeshMultiTS *cur(*it); + if(cur) + cur->cartesianizeMe(); + } +} + void MEDFileMeshes::resize(int newSize) { _meshes.resize(newSize); @@ -6650,49 +7676,49 @@ void MEDFileMeshes::destroyMeshAtPos(int i) _meshes.erase(_meshes.begin()+i); } -void MEDFileMeshes::loadFromFile(const std::string& fileName) +void MEDFileMeshes::loadFromFile(med_idt fid) { - std::vector ms=MEDLoader::GetMeshNames(fileName); + std::vector ms(MEDLoaderNS::getMeshNamesFid(fid)); int i=0; _meshes.resize(ms.size()); for(std::vector::const_iterator it=ms.begin();it!=ms.end();it++,i++) - _meshes[i]=MEDFileMeshMultiTS::New(fileName,(*it)); + _meshes[i]=MEDFileMeshMultiTS::New(fid,(*it)); } MEDFileMeshes::MEDFileMeshes() { } -MEDFileMeshes::MEDFileMeshes(const std::string& fileName) +MEDFileMeshes::MEDFileMeshes(med_idt fid) try { - loadFromFile(fileName); + loadFromFile(fid); } catch(INTERP_KERNEL::Exception& /*e*/) { } -MEDFileMeshes *MEDFileMeshes::deepCpy() const +MEDFileMeshes *MEDFileMeshes::deepCopy() const { - std::vector< MEDCouplingAutoRefCountObjectPtr > meshes(_meshes.size()); + std::vector< MCAuto > meshes(_meshes.size()); std::size_t i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++) + for(std::vector< MCAuto >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++) if((const MEDFileMeshMultiTS *)*it) - meshes[i]=(*it)->deepCpy(); - MEDCouplingAutoRefCountObjectPtr ret=MEDFileMeshes::New(); + meshes[i]=(*it)->deepCopy(); + MCAuto ret(MEDFileMeshes::New()); ret->_meshes=meshes; return ret.retn(); } std::size_t MEDFileMeshes::getHeapMemorySizeWithoutChildren() const { - return _meshes.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr)); + return _meshes.capacity()*(sizeof(MCAuto)); } std::vector MEDFileMeshes::getDirectChildrenWithNull() const { std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_meshes.begin();it!=_meshes.end();it++) + for(std::vector< MCAuto >::const_iterator it=_meshes.begin();it!=_meshes.end();it++) ret.push_back((const MEDFileMeshMultiTS *)*it); return ret; } @@ -6714,12 +7740,12 @@ void MEDFileMeshes::simpleReprWithoutHeader(std::ostream& oss) const oss << " - #" << i << " \"" << mns[i] << "\"\n"; } -void MEDFileMeshes::checkCoherency() const +void MEDFileMeshes::checkConsistencyLight() const { - static const char MSG[]="MEDFileMeshes::checkCoherency : mesh at rank "; + static const char MSG[]="MEDFileMeshes::checkConsistencyLight : mesh at rank "; int i=0; std::set s; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++) + for(std::vector< MCAuto >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++) { const MEDFileMeshMultiTS *elt=(*it); if(!elt) @@ -6737,6 +7763,22 @@ void MEDFileMeshes::checkCoherency() const } } +bool MEDFileMeshes::presenceOfStructureElements() const +{ + for(std::vector< MCAuto >::const_iterator it=_meshes.begin();it!=_meshes.end();it++) + if((*it).isNotNull()) + if((*it)->presenceOfStructureElements()) + return true; + return false; +} + +void MEDFileMeshes::killStructureElements() +{ + for(std::vector< MCAuto >::iterator it=_meshes.begin();it!=_meshes.end();it++) + if((*it).isNotNull()) + (*it)->killStructureElements(); +} + MEDFileMeshesIterator::MEDFileMeshesIterator(MEDFileMeshes *ms):_ms(ms),_iter_id(0),_nb_iter(0) { if(ms) @@ -6763,3 +7805,36 @@ MEDFileMesh *MEDFileMeshesIterator::nextt() else return 0; } + +INTERP_KERNEL::NormalizedCellType MEDFileMesh::ConvertFromMEDFileGeoType(med_geometry_type geoType) +{ + med_geometry_type *pos(std::find(typmai,typmai+MED_N_CELL_FIXED_GEO,geoType)); + if(pos==typmai+MED_N_CELL_FIXED_GEO) + { + if(geoType==MED_NO_GEOTYPE) + return INTERP_KERNEL::NORM_ERROR; + std::ostringstream oss; oss << "MEDFileMesh::ConvertFromMEDFileGeoType : no entry with " << geoType << " !"; + throw INTERP_KERNEL::Exception(oss.str()); + } + return typmai2[std::distance(typmai,pos)]; +} + +TypeOfField MEDFileMesh::ConvertFromMEDFileEntity(med_entity_type etype) +{ + switch(etype) + { + case MED_NODE: + return ON_NODES; + case MED_CELL: + return ON_CELLS; + case MED_NODE_ELEMENT: + return ON_GAUSS_NE; + default: + { + std::ostringstream oss; oss << "MEDFileMesh::ConvertFromMEDFileEntity : not recognized entity " << etype << " !"; + throw INTERP_KERNEL::Exception(oss.str()); + } + } +} + +