X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FMEDLoader%2FMEDFileMesh.cxx;h=3d59c0b9544d51bdee37dc4971d4b9ba9c913750;hb=b7e277ad50223814bc479c5bd64cf12abe8fc959;hp=fb40fb9eb2dfcff8a6c4df1179256309eba943db;hpb=659f8c67d0348350e12fde38fe8c4de1ff95dffe;p=tools%2Fmedcoupling.git diff --git a/src/MEDLoader/MEDFileMesh.cxx b/src/MEDLoader/MEDFileMesh.cxx index fb40fb9eb..3d59c0b95 100644 --- a/src/MEDLoader/MEDFileMesh.cxx +++ b/src/MEDLoader/MEDFileMesh.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2014 CEA/DEN, EDF R&D +// Copyright (C) 2007-2016 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,24 +19,32 @@ // 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 "InterpKernelAutoPtr.hxx" #include #include -using namespace ParaMEDMEM; +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[34]; + +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) { } @@ -54,9 +62,11 @@ std::size_t MEDFileMesh::getHeapMemorySizeWithoutChildren() const return ret; } -std::vector MEDFileMesh::getDirectChildren() const +std::vector MEDFileMesh::getDirectChildrenWithNull() const { - return std::vector(); + std::vector ret(1); + ret[0]=(const MEDFileEquivalences *)_equiv; + return ret; } /*! @@ -71,44 +81,49 @@ std::vector MEDFileMesh::getDirectChildren() const */ 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); - return (MEDFileUMesh *)ret.retn(); + ret=MEDFileUMesh::New(); + break; } case CARTESIAN: { - MEDCouplingAutoRefCountObjectPtr ret=MEDFileCMesh::New(); - ret->loadCMeshFromFile(fid,ms.front(),dt,it,mrs); - return (MEDFileCMesh *)ret.retn(); + ret=MEDFileCMesh::New(); + break; } case CURVE_LINEAR: { - MEDCouplingAutoRefCountObjectPtr ret=MEDFileCurveLinearMesh::New(); - ret->loadCLMeshFromFile(fid,ms.front(),dt,it,mrs); - return (MEDFileCurveLinearMesh *)ret.retn(); + ret=MEDFileCurveLinearMesh::New(); + break; } default: { std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << ms.front() << "' exists but unsupported type yet !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } - } + } + ret->loadLLWithAdditionalItems(fid,ms.front(),dt,it,mrs); + return ret.retn(); } /*! @@ -119,46 +134,54 @@ MEDFileMesh *MEDFileMesh::New(const std::string& fileName, MEDFileMeshReadSelect * \param [in] mName - the name of the mesh to read. * \param [in] dt - the number of a time step. * \param [in] it - the number of an iteration. + * \param [in] joints - the sub-domain joints to use instead of those that can be read + * from the MED file. Usually this joints are those just read by another iteration + * of mName mesh, when this method is called by MEDFileMeshMultiTS::New() * \return MEDFileMesh * - a new instance of MEDFileMesh. The caller is to delete this * mesh using decrRef() as it is no more needed. * \throw If the file is not readable. * \throw If there is no mesh with given attributes in the file. * \throw If the mesh in the file is of a not supported type. */ -MEDFileMesh *MEDFileMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) +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); - return (MEDFileUMesh *)ret.retn(); + ret=MEDFileUMesh::New(); + break; } case CARTESIAN: { - MEDCouplingAutoRefCountObjectPtr ret=MEDFileCMesh::New(); - ret->loadCMeshFromFile(fid,mName,dt,it,mrs); - return (MEDFileCMesh *)ret.retn(); + ret=MEDFileCMesh::New(); + break; } case CURVE_LINEAR: { - MEDCouplingAutoRefCountObjectPtr ret=MEDFileCurveLinearMesh::New(); - ret->loadCLMeshFromFile(fid,mName,dt,it,mrs); - return (MEDFileCurveLinearMesh *)ret.retn(); + ret=MEDFileCurveLinearMesh::New(); + break; } default: { std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << mName << "' exists but unsupported type yet !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } - } + } + ret->loadLLWithAdditionalItems(fid,mName,dt,it,mrs); + return ret.retn(); } /*! @@ -168,32 +191,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); } /*! @@ -240,6 +248,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; } @@ -253,7 +263,7 @@ void MEDFileMesh::setName(const std::string& name) */ void MEDFileMesh::clearNonDiscrAttributes() const { - + } bool MEDFileMesh::changeNames(const std::vector< std::pair >& modifTab) @@ -499,6 +509,112 @@ std::vector MEDFileMesh::getFamiliesNames() const 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 internaly 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. @@ -626,7 +742,7 @@ std::vector MEDFileMesh::removeOrphanGroups() */ std::vector MEDFileMesh::removeOrphanFamilies() { - MEDCouplingAutoRefCountObjectPtr allFamIdsInUse=computeAllFamilyIdsInUse(); + MCAuto allFamIdsInUse=computeAllFamilyIdsInUse(); std::vector ret; if(!((DataArrayInt*)allFamIdsInUse)) { @@ -658,6 +774,81 @@ std::vector MEDFileMesh::removeOrphanFamilies() return ret; } +/*! + * This method operates only on maps in \a this. The arrays are not considered here. So this method will remove a family (except "FAMILLE_ZERO" family) if no group lies on it whatever + * this family is orphan or not. + * + * \warning this method is different from removeOrphanFamilies that scans family field array to find orphan families. + */ +void MEDFileMesh::removeFamiliesReferedByNoGroups() +{ + std::map fams; + std::set sfams; + 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++) + sfams.erase(*it1); + for(std::set::const_iterator it=sfams.begin();it!=sfams.end();it++) + if(*it!=DFT_FAM_NAME) + _families.erase(*it); +} + +/*! + * 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 + * 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. + * + * \sa MEDFileMesh::removeOrphanFamilies + */ +void MEDFileMesh::rearrangeFamilies() +{ + checkOrphanFamilyZero(); + removeFamiliesReferedByNoGroups(); + // + std::vector levels(getNonEmptyLevelsExt()); + std::set idsRefed; + for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) + idsRefed.insert((*it).second); + for(std::vector::const_iterator it=levels.begin();it!=levels.end();it++) + { + const DataArrayInt *fams(0); + try + { + fams=getFamilyFieldAtLevel(*it); + } + catch(INTERP_KERNEL::Exception& e) { } + if(!fams) + continue; + std::vector v(fams->getNumberOfTuples(),false); + for(std::set::const_iterator pt=idsRefed.begin();pt!=idsRefed.end();pt++) + fams->switchOnTupleEqualTo(*pt,v); + MCAuto unfetchedIds(DataArrayInt::BuildListOfSwitchedOff(v)); + if(!unfetchedIds->empty()) + { + MCAuto newFams(fams->deepCopy()); + newFams->setPartOfValuesSimple3(0,unfetchedIds->begin(),unfetchedIds->end(),0,1,1); + setFamilyFieldArr(*it,newFams); + } + } + removeOrphanFamilies(); +} + +/*! + * This method only checks that "FAMILLE_ZERO" is orphan (not belonging to a group). + */ +void MEDFileMesh::checkOrphanFamilyZero() const +{ + for(std::map >::const_iterator it=_groups.begin();it!=_groups.end();it++) + { + if(std::find((*it).second.begin(),(*it).second.end(),DFT_FAM_NAME)!=(*it).second.end()) + { + std::ostringstream oss; oss << "MEDFileMesh::rearrangeFamilies : Groups \"" << (*it).first << "\" is lying on family \"" << DFT_FAM_NAME << "\" !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } +} + /*! * Renames a group in \a this mesh. * \param [in] oldName - a current name of the group to rename. @@ -813,7 +1004,7 @@ bool MEDFileMesh::areGrpsEqual(const MEDFileMesh *other, std::string& what) cons { oss << " Group \"" << (*it).first << "\" on following families :\n"; for(std::vector::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++) - oss << " \"" << *it2 << "\n"; + oss << " \"" << *it2 << "\n"; } oss << "Second group description :\n"; for(std::map >::const_iterator it=other->_groups.begin();it!=other->_groups.end();it++) @@ -900,14 +1091,14 @@ void MEDFileMesh::addFamily(const std::string& familyName, int famId) std::map::const_iterator it=_families.find(fname); if(it==_families.end()) { - for(std::map::const_iterator it2=_families.begin();it2!=_families.end();it2++) - if((*it2).second==famId) - { - std::ostringstream oss; - oss << "MEDFileMesh::addFamily : Family \"" << (*it2).first << "\" already exists with specified id : " << famId << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - _families[fname]=famId; + for(std::map::const_iterator it2=_families.begin();it2!=_families.end();it2++) + if((*it2).second==famId) + { + std::ostringstream oss; + oss << "MEDFileMesh::addFamily : Family \"" << (*it2).first << "\" already exists with specified id : " << famId << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + _families[fname]=famId; } else { @@ -955,7 +1146,7 @@ void MEDFileMesh::createGroupOnAll(int meshDimRelToMaxExt, const std::string& gr const DataArrayInt *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++) { @@ -992,7 +1183,7 @@ bool MEDFileMesh::keepFamIdsOnlyOnLevs(const std::vector& famIds, const std const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(*it); if(fieldFamIds) { - MEDCouplingAutoRefCountObjectPtr famIds3=fieldFamIds->getDifferentValues(); + 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++) @@ -1065,6 +1256,85 @@ void MEDFileMesh::addFamilyOnAllGroupsHaving(const std::string& famName, const s } } +/*! + * \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) + */ +void MEDFileMesh::addGroupUnderground(bool isNodeGroup, const DataArrayInt *ids, DataArrayInt *famArr) +{ + if(!ids) + throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : NULL pointer in input !"); + std::string grpName(ids->getName()); + 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(); MCAuto 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< MCAuto > allFamIds(getAllNonNullFamilyIds()); + allFamIds.erase(std::find(allFamIds.begin(),allFamIds.end(),famArrTmp)); + MCAuto famIds=famArr->selectByTupleIdSafe(ids->begin(),ids->end()); + MCAuto diffFamIds=famIds->getDifferentValues(); + std::vector familyIds; + std::vector< MCAuto > idsPerfamiliyIds; + int 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++) + { + 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< MCAuto >::const_iterator itl=allFamIds.begin();itl!=allFamIds.end() && !isFamPresent;itl++) + isFamPresent=(*itl)->presenceOfValue(*famId); + if(!isFamPresent) + { familyIds.push_back(*famId); idsPerfamiliyIds.push_back(ret0); fams.push_back(FindOrCreateAndGiveFamilyWithId(families,*famId,created)); } // adding *famId in grp + else + { + familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ids2); + std::string locFamName=FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created); + fams.push_back(locFamName); + if(existsFamily(*famId)) + { + std::string locFamName2=getFamilyNameGivenId(*famId); std::vector v(2); v[0]=locFamName2; v[1]=locFamName; + ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v); + } + maxVal++; + } // modifying all other groups on *famId to lie on maxVal and lie the grp on maxVal + } + else + { + familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ret0); // modifying all other groups on *famId to lie on maxVal and on maxVal+1 + familyIds.push_back(isNodeGroup?maxVal+1:-maxVal-1); idsPerfamiliyIds.push_back(ids2);//grp lie only on maxVal+1 + std::string n2(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal+1:-maxVal-1,created)); fams.push_back(n2); + if(existsFamily(*famId)) + { + std::string n1(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created)); std::vector v(2); v[0]=n1; v[1]=n2; + ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v); + } + maxVal+=2; + } + } + for(std::size_t i=0;isetPartOfValuesSimple3(familyIds[i],da->begin(),da->end(),0,1,1); + } + _families=families; + _groups=groups; + _groups[grpName]=fams; +} + void MEDFileMesh::changeAllGroupsContainingFamily(const std::string& familyNameToChange, const std::vector& newFamiliesNames) { ChangeAllGroupsContainingFamily(_groups,familyNameToChange,newFamiliesNames); @@ -1156,11 +1426,10 @@ 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()); @@ -1293,7 +1562,7 @@ int MEDFileMesh::getTheMinFamilyId() const */ DataArrayInt *MEDFileMesh::getAllFamiliesIdsReferenced() const { - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); + MCAuto ret=DataArrayInt::New(); std::set v; for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) v.insert((*it).second); @@ -1310,11 +1579,11 @@ DataArrayInt *MEDFileMesh::getAllFamiliesIdsReferenced() const DataArrayInt *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(); + MCAuto dv=arr->getDifferentValues(); if((DataArrayInt *) ret) ret=dv->buildUnion(ret); else @@ -1338,7 +1607,7 @@ bool MEDFileMesh::ensureDifferentFamIdsPerLevel() const DataArrayInt *fam=getFamilyFieldAtLevel(*it); if(fam) { - MEDCouplingAutoRefCountObjectPtr tmp=fam->getDifferentValues(); + 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()) @@ -1349,7 +1618,7 @@ bool MEDFileMesh::ensureDifferentFamIdsPerLevel() } if(famIdsToRenum.empty()) return true; - MEDCouplingAutoRefCountObjectPtr allIds=getAllFamiliesIdsReferenced(); + MCAuto allIds=getAllFamiliesIdsReferenced(); for(std::map >::const_iterator it2=famIdsToRenum.begin();it2!=famIdsToRenum.end();it2++) { DataArrayInt *fam=const_cast(getFamilyFieldAtLevel((*it2).first)); @@ -1368,7 +1637,7 @@ bool MEDFileMesh::ensureDifferentFamIdsPerLevel() addFamilyOnGrp((*it4),newFam); } } - MEDCouplingAutoRefCountObjectPtr ids=fam->getIdsEqualList(&(*it2).second[0],&(*it2).second[0]+(*it2).second.size()); + MCAuto ids=fam->findIdsEqualList(&(*it2).second[0],&(*it2).second[0]+(*it2).second.size()); for(const int *id=ids->begin();id!=ids->end();id++) famIdsToChange[*id]=ren[famIdsToChange[*id]]; } @@ -1385,7 +1654,7 @@ 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; @@ -1397,7 +1666,7 @@ void MEDFileMesh::normalizeFamIdsTrio() if(fam) { int refId=1; - MEDCouplingAutoRefCountObjectPtr tmp=fam->getDifferentValues(); + MCAuto tmp=fam->getDifferentValues(); std::map ren; for(const int *it=tmp->begin();it!=tmp->end();it++,refId++) ren[*it]=refId; @@ -1423,7 +1692,7 @@ void MEDFileMesh::normalizeFamIdsTrio() if(fam) { int refId=-1; - MEDCouplingAutoRefCountObjectPtr tmp=fam->getDifferentValues(); + MCAuto tmp=fam->getDifferentValues(); std::map ren; for(const int *it=tmp->begin();it!=tmp->end();it++,refId--) ren[*it]=refId; @@ -1447,7 +1716,7 @@ void MEDFileMesh::normalizeFamIdsTrio() DataArrayInt *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++) if(allIds->presenceOfValue(*it3)) @@ -1477,7 +1746,7 @@ 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; @@ -1489,7 +1758,7 @@ void MEDFileMesh::normalizeFamIdsMEDFile() const DataArrayInt *fam=getFamilyFieldAtLevel(1); if(fam) { - MEDCouplingAutoRefCountObjectPtr tmp=fam->getDifferentValues(); + MCAuto tmp=fam->getDifferentValues(); std::map ren; for(const int *it=tmp->begin();it!=tmp->end();it++,refId++) ren[*it]=refId; @@ -1514,7 +1783,7 @@ void MEDFileMesh::normalizeFamIdsMEDFile() const DataArrayInt *fam=getFamilyFieldAtLevel(*it2); if(fam) { - MEDCouplingAutoRefCountObjectPtr tmp=fam->getDifferentValues(); + MCAuto tmp=fam->getDifferentValues(); std::map ren; for(const int *it=tmp->begin();it!=tmp->end();it++,refId--) ren[*it]=refId; @@ -1573,6 +1842,22 @@ std::string MEDFileMesh::simpleRepr() const return oss.str(); } +/*! + * 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) +{ + DataArrayInt *ret(getFamilyFieldAtLevel(meshDimRelToMaxExt)); + if(ret) + return ret; + MCAuto arr(DataArrayInt::New()); + arr->alloc(getSizeAtLevel(meshDimRelToMaxExt),1); + arr->fillWithZero(); + setFamilyFieldArr(meshDimRelToMaxExt,arr); + return getFamilyFieldAtLevel(meshDimRelToMaxExt); +} + /*! * Returns ids of mesh entities contained in a given group of a given dimension. * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids @@ -1736,7 +2021,7 @@ void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector fam; + MCAuto fam; std::vector< std::vector > fidsOfGroups; if(!renum) { @@ -1744,7 +2029,7 @@ void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector > grps2(grps.size()); + std::vector< MCAuto > grps2(grps.size()); for(unsigned int ii=0;ii ids=fam->getDifferentValues(); + MCAuto ids=fam->getDifferentValues(); appendFamilyEntries(ids,fidsOfGroups,grpsName2); setFamilyFieldArr(meshDimRelToMaxExt,fam); } @@ -1799,12 +2084,22 @@ std::vector MEDFileMesh::getAllGeoTypes() con return ret; } +/*! + * \sa getAllDistributionOfTypes + */ std::vector MEDFileMesh::getDistributionOfTypes(int meshDimRelToMax) const { - MEDCouplingAutoRefCountObjectPtr mLev(getGenMeshAtLevel(meshDimRelToMax)); + MCAuto mLev(getMeshAtLevel(meshDimRelToMax)); return mLev->getDistributionOfTypes(); } +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(int offset, DataArrayInt *famArr, std::vector< std::vector >& famIdsPerGrp) { famArr->applyLin(offset>0?1:-1,offset,0); @@ -1939,8 +2234,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); } @@ -1956,19 +2255,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 dependant 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(); } /*! @@ -1981,35 +2310,66 @@ MEDFileUMesh *MEDFileUMesh::New() return new MEDFileUMesh; } -std::size_t MEDFileUMesh::getHeapMemorySizeWithoutChildren() const +/*! + * This method loads from file with name \a fileName the mesh called \a mName as New does. The difference is that + * here only a part of cells contained in the file will be loaded. The selection of cell is specified using the two consecutive parameters + * \a types and \a slicPerTyp. This method allows to load from a mesh (typically huge) in a MED file a part of cells of that mesh. + * The part of cells is specified using triplet (start,stop,step) for each geometric type. Only nodes lying on selected cells will be loaded to reduce + * at most the memory consumtion. + * + * \param [in] fileName - the name of the file. + * \param [in] mName - the name of the mesh to be read. + * \param [in] types - the list of the geo types of which some part will be taken. A geometric type in \a types must appear only once at most. + * \param [in] slicPerType - an array of size 3 times larger than \a types that specifies for each type in \a types (in the same order) resp the start, the stop and the step. + * \param [in] dt - the iteration, that is to say the first element of the pair that locates the asked time step. + * \param [in] it - the order, that is to say the second element of the pair that locates the asked time step. + * \param [in] mrs - the request for what to be loaded. + * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this mesh using decrRef() as it is no more needed. + */ +MEDFileUMesh *MEDFileUMesh::LoadPartOf(const std::string& fileName, const std::string& mName, const std::vector& types, const std::vector& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs) { - std::size_t ret(MEDFileMesh::getHeapMemorySizeWithoutChildren()); - ret+=_ms.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr)); - return ret; + MEDFileUtilities::CheckFileForRead(fileName); + MEDFileUtilities::AutoFid fid(MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY)); + return MEDFileUMesh::LoadPartOf(fid,mName,types,slicPerTyp,dt,it,mrs); } -std::vector MEDFileUMesh::getDirectChildren() const -{ - std::vector ret(MEDFileMesh::getDirectChildren()); - if((const DataArrayDouble*)_coords) - ret.push_back((const DataArrayDouble*)_coords); - if((const DataArrayInt *)_fam_coords) - ret.push_back((const DataArrayInt *)_fam_coords); - if((const DataArrayInt *)_num_coords) - ret.push_back((const DataArrayInt *)_num_coords); - if((const DataArrayInt *)_rev_num_coords) - ret.push_back((const DataArrayInt *)_rev_num_coords); - if((const DataArrayAsciiChar *)_name_coords) - ret.push_back((const DataArrayAsciiChar *)_name_coords); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++) - if((const MEDFileUMeshSplitL1*) *it) - ret.push_back((const MEDFileUMeshSplitL1*) *it); +/*! + * 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) +{ + MCAuto ret(MEDFileUMesh::New()); + ret->loadPartUMeshFromFile(fid,mName,types,slicPerTyp,dt,it,mrs); + return ret.retn(); +} + +std::size_t MEDFileUMesh::getHeapMemorySizeWithoutChildren() const +{ + std::size_t ret(MEDFileMesh::getHeapMemorySizeWithoutChildren()); + ret+=_ms.capacity()*(sizeof(MCAuto))+_elt_str.capacity()*sizeof(MCAuto); + return ret; +} + +std::vector MEDFileUMesh::getDirectChildrenWithNull() const +{ + std::vector ret(MEDFileMesh::getDirectChildrenWithNull()); + ret.push_back((const DataArrayDouble*)_coords); + ret.push_back((const DataArrayInt *)_fam_coords); + ret.push_back((const DataArrayInt *)_num_coords); + ret.push_back((const DataArrayInt *)_rev_num_coords); + ret.push_back((const DataArrayAsciiChar *)_name_coords); + ret.push_back((const PartDefinition *)_part_coords); + for(std::vector< 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(); } @@ -2018,25 +2378,28 @@ MEDFileMesh *MEDFileUMesh::createNewEmpty() const return new MEDFileUMesh; } -MEDFileMesh *MEDFileUMesh::deepCpy() const +MEDFileUMesh *MEDFileUMesh::deepCopy() const { - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileUMesh(*this); + MCAuto ret(new MEDFileUMesh(*this)); + ret->deepCpyEquivalences(*this); if((const DataArrayDouble*)_coords) - ret->_coords=_coords->deepCpy(); + ret->_coords=_coords->deepCopy(); if((const DataArrayInt*)_fam_coords) - ret->_fam_coords=_fam_coords->deepCpy(); + ret->_fam_coords=_fam_coords->deepCopy(); if((const DataArrayInt*)_num_coords) - ret->_num_coords=_num_coords->deepCpy(); + ret->_num_coords=_num_coords->deepCopy(); if((const DataArrayInt*)_rev_num_coords) - ret->_rev_num_coords=_rev_num_coords->deepCpy(); + ret->_rev_num_coords=_rev_num_coords->deepCopy(); if((const DataArrayAsciiChar*)_name_coords) - ret->_name_coords=_name_coords->deepCpy(); + 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->deepCopy(); return ret.retn(); } @@ -2145,7 +2508,106 @@ bool MEDFileUMesh::isEqual(const MEDFileMesh *other, double eps, std::string& wh return false; } } - return true; + const PartDefinition *pd0(_part_coords),*pd1(otherC->_part_coords); + if(!pd0 && !pd1) + return true; + if((!pd0 && pd1) || (pd0 && !pd1)) + { + what=std::string("node part def is defined only for one among this or other !"); + return false; + } + 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 || !_rev_num_coords) + throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but not the internal node numbering array!"); + } + else + { + int nbCoo = _coords->getNumberOfTuples(); + if (_fam_coords) + _fam_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent internal node family array!"); + if (_num_coords) + { + _num_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent internal node numbering array!"); + int pos; + int 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 ((_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 DataArrayInt * > 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 = DataArrayInt::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 = 0; + _rev_num_coords = 0; + for (std::vector< MCAuto >::iterator it=_ms.begin(); + it != _ms.end(); it++) + { + (*it)->_num = 0; + (*it)->_rev_num = 0; + } } /*! @@ -2166,7 +2628,7 @@ void MEDFileUMesh::clearNonDiscrAttributes() const 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++) + for(std::vector< MCAuto >::const_iterator it=_ms.begin();it!=_ms.end();it++) { const MEDFileUMeshSplitL1 *tmp=(*it); if(tmp) @@ -2176,7 +2638,7 @@ void MEDFileUMesh::clearNonDiscrAttributes() const void MEDFileUMesh::setName(const std::string& name) { - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_ms.begin();it!=_ms.end();it++) + for(std::vector< MCAuto >::iterator it=_ms.begin();it!=_ms.end();it++) if((MEDFileUMeshSplitL1 *)(*it)!=0) (*it)->setName(name); MEDFileMesh::setName(name); @@ -2188,27 +2650,178 @@ MEDFileUMesh::MEDFileUMesh() MEDFileUMesh::MEDFileUMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) try - { - loadUMeshFromFile(fid,mName,dt,it,mrs); - } +{ + loadLLWithAdditionalItems(fid,mName,dt,it,mrs); +} catch(INTERP_KERNEL::Exception& e) - { +{ throw e; - } +} + +/*! + * This method loads only a part of specified cells (given by range of cell ID per geometric type) + * See MEDFileUMesh::LoadPartOf for detailed description. + * + * \sa 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) +{ + MEDFileUMeshL2 loaderl2; + MEDCoupling::MEDCouplingMeshType meshType; + int dummy0,dummy1; + std::string 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 << "' !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + loaderl2.loadPart(fid,mid,mName,types,slicPerTyp,dt,it,mrs); + dispatchLoadedPart(fid,loaderl2,mName,mrs); +} -void MEDFileUMesh::loadUMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) +/*! + * \brief Write joints in a file + */ +void MEDFileMesh::writeJoints(med_idt fid) const +{ + if ( _joints.isNotNull() ) + _joints->writeLL(fid); +} + +/*! + * \brief Load joints in a file or use provided ones + */ +//================================================================================ +/*! + * \brief Load joints in a file or use provided ones + * \param [in] fid - MED file descriptor + * \param [in] toUseInstedOfReading - optional joints to use instead of reading, + * Usually this joints are those just read by another iteration + * of namesake mesh, when this method is called by MEDFileMeshMultiTS::New() + */ +//================================================================================ + +void MEDFileMesh::loadJointsFromFile(med_idt fid, MEDFileJoints* toUseInstedOfReading) +{ + if ( toUseInstedOfReading ) + setJoints( toUseInstedOfReading ); + else + _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 possiblities :" << 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() const +{ + return ( (const MEDFileJoints *) _joints ) ? _joints->getNumberOfJoints() : 0; +} + +/*! + * \brief Return joints with all adjacent mesh domains + */ +MEDFileJoints * MEDFileMesh::getJoints() const +{ + return const_cast(& (*_joints)); +} + +void MEDFileMesh::setJoints( MEDFileJoints* joints ) +{ + if ( joints != _joints ) + { + _joints = joints; + if ( joints ) + joints->incrRef(); + } +} + +/*! + * This method loads \b all \b the \b mesh \a mName in the file with \a fid descriptor. + * + * \sa loadPartUMeshFromFile + */ +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 << "' !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } loaderl2.loadAll(fid,mid,mName,dt,it,mrs); + dispatchLoadedPart(fid,loaderl2,mName,mrs); + // Structure element part... + 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(); + _part_coords=loaderl2.getPartDefOfCoo(); computeRevNum(); } @@ -2241,7 +2855,7 @@ 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); @@ -2249,7 +2863,9 @@ void MEDFileUMesh::writeLL(med_idt fid) const 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 mdim=getMeshDimension(); + int mdim(0); + if(!_ms.empty()) + mdim=getMeshDimension(); INTERP_KERNEL::AutoPtr comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE); INTERP_KERNEL::AutoPtr unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE); for(int i=0;igetInfoOnComponent(i); std::string c,u; MEDLoaderBase::splitIntoNameAndUnit(info,c,u); - MEDLoaderBase::safeStrCpy2(c.c_str(),MED_SNAME_SIZE-1,comp+i*MED_SNAME_SIZE,_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 } - MEDmeshCr(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MED_CARTESIAN,comp,unit); - 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++) + 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); @@ -2278,7 +2895,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); @@ -2309,7 +2926,7 @@ std::vector MEDFileUMesh::getFamArrNonEmptyLevelsExt() const 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) @@ -2326,7 +2943,7 @@ std::vector MEDFileUMesh::getNumArrNonEmptyLevelsExt() const if(numCoo) 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) @@ -2343,7 +2960,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) @@ -2353,75 +2970,6 @@ 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. @@ -2431,8 +2979,8 @@ std::vector MEDFileUMesh::getGrpsNonEmptyLevelsExt(const std::vector MEDFileUMesh::getFamsNonEmptyLevels(const std::vector& fams) const { std::vector ret; - std::vector levs=getNonEmptyLevels(); - std::vector famIds=getFamiliesIds(fams); + 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); @@ -2446,11 +2994,11 @@ std::vector MEDFileUMesh::getFamsNonEmptyLevels(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 DataArrayInt *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); @@ -2462,25 +3010,6 @@ 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 { int ret=-std::numeric_limits::max(),tmp=-1; @@ -2489,7 +3018,7 @@ int MEDFileUMesh::getMaxAbsFamilyIdInArrays() const int 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)) { @@ -2512,7 +3041,7 @@ int MEDFileUMesh::getMaxFamilyIdInArrays() const int 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)) { @@ -2535,7 +3064,7 @@ int MEDFileUMesh::getMinFamilyIdInArrays() const int 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)) { @@ -2558,7 +3087,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 !"); @@ -2627,6 +3156,7 @@ std::string MEDFileUMesh::simpleRepr() const } oss << std::endl << std::endl; getFamilyRepr(oss); + getEquivalencesRepr(oss); return oss.str(); } @@ -2666,7 +3196,15 @@ const DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) { if(meshDimRelToMaxExt==1) return _fam_coords; - const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt); + const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt)); + return l1->getFamilyField(); +} + +DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) +{ + if(meshDimRelToMaxExt==1) + return _fam_coords; + MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt)); return l1->getFamilyField(); } @@ -2692,14 +3230,49 @@ const DataArrayAsciiChar *MEDFileUMesh::getNameFieldAtLevel(int meshDimRelToMaxE return l1->getNameField(); } +/*! + * This method returns for a specified relative level \a meshDimRelToMaxExt the part effectively read (if the instance is the result of the read of a file). + * + * \param [in] meshDimRelToMaxExt - the extended relative level for which the part definition is requested. + * \param [in] gt - The input geometric type for which the part definition is requested. + * \return the part definition owned by \a this. So no need to deallocate the returned instance. + */ +const PartDefinition *MEDFileUMesh::getPartDefAtLevel(int meshDimRelToMaxExt, INTERP_KERNEL::NormalizedCellType gt) const +{ + if(meshDimRelToMaxExt==1) + return _part_coords; + const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt)); + return l1->getPartDef(gt); +} + int MEDFileUMesh::getNumberOfNodes() const { - const DataArrayDouble *coo=_coords; + const DataArrayDouble *coo(_coords); if(!coo) throw INTERP_KERNEL::Exception(" MEDFileUMesh::getNumberOfNodes : no coords set !"); return coo->getNumberOfTuples(); } +int MEDFileUMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const +{ + const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt)); + return l1->getNumberOfCells(); +} + +bool MEDFileUMesh::hasImplicitPart() const +{ + return false; +} + +int MEDFileUMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const +{ + throw INTERP_KERNEL::Exception("MEDFileUMesh::buildImplicitPartIfAny : unstructured meshes do not have implicit part !"); +} + +void MEDFileUMesh::releaseImplicitPartIfAny() const +{ +} + void MEDFileUMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector& nodesFetched) const { std::size_t sz(st.getNumberOfItems()); @@ -2712,12 +3285,48 @@ void MEDFileUMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, con else { const DataArrayInt *arr(globs->getProfile(st[i].getPflName())); - MEDCouplingAutoRefCountObjectPtr m2(dynamic_cast(m->buildPartOfMySelf(arr->begin(),arr->end(),true))); + 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(). @@ -2744,7 +3353,8 @@ const DataArrayInt *MEDFileUMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxEx */ DataArrayDouble *MEDFileUMesh::getCoords() const { - MEDCouplingAutoRefCountObjectPtr tmp(_coords); + checkCartesian(); + MCAuto tmp(_coords); if((DataArrayDouble *)tmp) { return tmp; @@ -2768,6 +3378,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; @@ -2790,9 +3401,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(); @@ -2814,6 +3426,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; @@ -2836,18 +3449,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); const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt); - MEDCouplingAutoRefCountObjectPtr zeRet; + MCAuto zeRet; if(!famIds.empty()) zeRet=l1->getFamilyPart(&famIds[0],&famIds[0]+famIds.size(),renum); else @@ -2876,11 +3490,11 @@ DataArrayInt *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::ve { if((const DataArrayInt *)_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 @@ -2908,17 +3522,17 @@ DataArrayInt *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::ve * \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()); @@ -2929,25 +3543,6 @@ 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 { const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMax)); @@ -3014,7 +3609,7 @@ MEDCouplingUMesh *MEDFileUMesh::getLevelM3Mesh(bool renum) const */ 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) @@ -3030,6 +3625,7 @@ void MEDFileUMesh::forceComputationOfParts() const */ std::vector MEDFileUMesh::getDirectUndergroundSingleGeoTypeMeshes(int meshDimRelToMax) const { + checkCartesian(); const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax)); return sp->getDirectUndergroundSingleGeoTypeMeshes(); } @@ -3041,12 +3637,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++) + { + int 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. @@ -3057,6 +3678,13 @@ std::vector MEDFileUMesh::getGeoTypesAtLevel( return sp->getGeoTypes(); } +int 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. @@ -3087,6 +3715,18 @@ DataArrayInt *MEDFileUMesh::extractNumberFieldOnGeoType(INTERP_KERNEL::Normalize return sp->extractNumberFieldOnGeoType(gt); } +/*! + * This method returns for specified geometric type \a gt the relative level to \a this. + * If the relative level is empty an exception will be thrown. + */ +int MEDFileUMesh::getRelativeLevOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const +{ + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt); + int ret((int)cm.getDimension()-getMeshDimension()); + getMeshAtLevSafe(ret);//To test that returned value corresponds to a valid level. + return ret; +} + const MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) const { if(meshDimRelToMaxExt==1) @@ -3095,7 +3735,7 @@ const MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !"); int tracucedRk=-meshDimRelToMaxExt; if(tracucedRk>=(int)_ms.size()) - throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !"); + throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !"); if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0) throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !"); return _ms[tracucedRk]; @@ -3103,13 +3743,13 @@ const MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) { - if(meshDimRelToMaxExt==1) + if(meshDimRelToMaxExt==1) throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !"); if(meshDimRelToMaxExt>1) throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !"); int tracucedRk=-meshDimRelToMaxExt; if(tracucedRk>=(int)_ms.size()) - throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !"); + throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !"); if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0) throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !"); return _ms[tracucedRk]; @@ -3120,7 +3760,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) { @@ -3140,14 +3780,46 @@ 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(); + int nbOfTuples(coords->getNumberOfTuples()); _coords=coords; coords->incrRef(); _fam_coords=DataArrayInt::New(); _fam_coords->alloc(nbOfTuples,1); _fam_coords->fillWithZero(); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_ms.begin();it!=_ms.end();it++) + _num_coords=0; _rev_num_coords=0; _name_coords=0; + 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(); + int nbOfTuples(coords->getNumberOfTuples()); + if(_coords.isNull()) + { + _coords=coords; + coords->incrRef(); + } + else + { + int 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); } @@ -3180,7 +3852,7 @@ void MEDFileUMesh::optimizeFamilies() for(std::vector::const_iterator it=levs.begin();it!=levs.end();it++) { const DataArrayInt *ffield=getFamilyFieldAtLevel(*it); - MEDCouplingAutoRefCountObjectPtr ids=ffield->getDifferentValues(); + 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; @@ -3211,57 +3883,95 @@ void MEDFileUMesh::optimizeFamilies() _groups.erase(*it); } -void MEDFileUMesh::duplicateNodesOnM1Group(const std::string& grpNameM1, DataArrayInt *&nodesDuplicated, DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified) +/** + * \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", 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 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 new boundary whose connectivity remains unchanged. + * \sa clearNodeAndCellNumbers() + */ +void MEDFileUMesh::buildInnerBoundaryAlongM1Group(const std::string& grpNameM1, DataArrayInt *&nodesDuplicated, + DataArrayInt *&cellsModified, DataArrayInt *&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); + throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group : This method works only for mesh definied on level 0 and -1 !"); + MUMesh m0=getMeshAtLevel(0); + MUMesh m1=getMeshAtLevel(-1); int nbNodes=m0->getNumberOfNodes(); - MEDCouplingAutoRefCountObjectPtr m11=getGroup(-1,grpNameM1); + MUMesh m11=getGroup(-1,grpNameM1); DataArrayInt *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=DataArrayInt::New(),descITmp0=DataArrayInt::New(),revDescTmp0=DataArrayInt::New(),revDescITmp0=DataArrayInt::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)); + DAInt cellsInM1ToRenumW2=tmp0Desc->getCellIdsLyingOnNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),false); + MUMesh cellsInM1ToRenumW3=static_cast(tmp0Desc->buildPartOfMySelf(cellsInM1ToRenumW2->begin(),cellsInM1ToRenumW2->end(),true)); DataArrayInt *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); + DataArrayInt * 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); 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=DataArrayInt::New(); newFam->alloc(newm1->getNumberOfCells(),1); - int idd=getMaxFamilyId()+1; + // Get a new family ID: care must be taken if we need a positive ID or a negative one: + // Positive ID for family of nodes, negative for all the rest. + int idd; + if (m1->getMeshDimension() == 0) + idd=getMaxFamilyId()+1; + else + idd=getMinFamilyId()-1; int globStart=0,start=0,end,globEnd; int nbOfChunks=szOfCellGrpOfSameType->getNumberOfTuples(); for(int i=0;igetIJ(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; } @@ -3296,12 +4006,24 @@ void MEDFileUMesh::duplicateNodesOnM1Group(const std::string& grpNameM1, DataArr newFam->setPartOfValuesSimple1(0,nbNodes,newNbOfNodes,1,0,1,1); _fam_coords=newFam; } + + _num_coords = 0; + _rev_num_coords = 0; + 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] o2nRenumCell tells for **all levels** the old 2 new renumbering of cells. @@ -3315,27 +4037,27 @@ bool MEDFileUMesh::unPolyze(std::vector& oldCode, std::vector& newCode 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 + std::vector< MCAuto > memorySaverIfThrow;//same than renumCellsSplited only in case of throw int start=0; int end=0; for(std::vector::reverse_iterator it=levs.rbegin();it!=levs.rend();it++) { - MEDCouplingAutoRefCountObjectPtr m=getMeshAtLevel(*it); + 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, - MEDCouplingUMesh::MEDMEM_ORDER+MEDCouplingUMesh::N_MEDMEM_ORDER,fake); + 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; + MCAuto 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); } setMeshAtLevel(*it,m); @@ -3343,16 +4065,16 @@ bool MEDFileUMesh::unPolyze(std::vector& oldCode, std::vector& newCode 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); } } @@ -3364,19 +4086,21 @@ bool MEDFileUMesh::unPolyze(std::vector& oldCode, std::vector& newCode } if(ret) { - MEDCouplingAutoRefCountObjectPtr renumCells=DataArrayInt::Aggregate(renumCellsSplited); - MEDCouplingAutoRefCountObjectPtr o2nRenumCellRet=renumCells->buildPermArrPerLevel(); + MCAuto renumCells=DataArrayInt::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; }; +/*! \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. @@ -3391,46 +4115,721 @@ struct MEDLoaderAccVisit1 */ DataArrayInt *MEDFileUMesh::zipCoords() { - const DataArrayDouble *coo=getCoords(); + const DataArrayDouble *coo(getCoords()); if(!coo) throw INTERP_KERNEL::Exception("MEDFileUMesh::zipCoords : no coordinates set in this !"); - int nbOfNodes=coo->getNumberOfTuples(); + int nbOfNodes(coo->getNumberOfTuples()); std::vector nodeIdsInUse(nbOfNodes,false); - std::vector neLevs=getNonEmptyLevels(); + std::vector neLevs(getNonEmptyLevels()); for(std::vector::const_iterator lev=neLevs.begin();lev!=neLevs.end();lev++) { - MEDCouplingAutoRefCountObjectPtr m=getMeshAtLevel(*lev); - m->computeNodeIdsAlg(nodeIdsInUse); + 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); + } } - int nbrOfNodesInUse=(int)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true); + int nbrOfNodesInUse((int)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true)); if(nbrOfNodesInUse==nbOfNodes) - return 0; - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(nbOfNodes,1); + return 0;//no need to update _part_coords + MCAuto 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; + MCAuto ret2(ret->invertArrayO2N2N2OBis(nbrOfNodesInUse)); + MCAuto newCoords(coo->selectByTupleIdSafe(ret2->begin(),ret2->end())); + MCAuto newFamCoords; + MCAuto newNameCoords; if((const DataArrayInt *)_fam_coords) newFamCoords=_fam_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()); - MEDCouplingAutoRefCountObjectPtr newNumCoords; + MCAuto 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++) + for(std::vector< MCAuto >::iterator it=_ms.begin();it!=_ms.end();it++) { if((MEDFileUMeshSplitL1*)*it) - (*it)->renumberNodesInConn(ret->begin()); + { + (*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 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 DataArrayInt that represents sorted node ids, the extraction is lying on. + * \sa MEDFileField1TS::extractPart, MEDFileUMesh::extractPart + */ +DataArrayInt *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 DataArrayInt::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 +{ + 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++) + { + 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::ostringstream oss; oss << "MEDFileUMesh::extractPart : 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)); + ret->setMeshAtLevel((*it).first,mPart); + const DataArrayInt *fam(getFamilyFieldAtLevel((*it).first)),*num(getNumberFieldAtLevel((*it).first)); + if(fam) + { + MCAuto famPart(fam->selectByTupleIdSafe((*it).second->begin(),(*it).second->end())); + ret->setFamilyFieldArr((*it).first,famPart); + } + if(num) + { + MCAuto numPart(num->selectByTupleIdSafe((*it).second->begin(),(*it).second->end())); + ret->setFamilyFieldArr((*it).first,numPart); + } + } + std::map >::const_iterator it2(extractDef.find(1)); + if(it2!=extractDef.end()) + { + 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 DataArrayInt *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(); +} + +/*! + * This method performs an extrusion along a path defined by \a m1D. + * \a this is expected to be a mesh with max mesh dimension equal to 2. + * \a m1D is expected to be a mesh with space dimesion equal to 3 and mesh dimension equal to 1. + * Mesh dimensions of returned mesh is incremented by one compared to thoose in \a this. + * This method scans all levels in \a this + * and put them in the returned mesh. All groups in \a this are also put in the returned mesh. + * + * \param [in] m1D - the mesh defining the extrusion path. + * \param [in] policy - defines the policy of extrusion (see MEDCouplingUMesh::buildExtrudedMesh for more details) + * \return - a new reference on mesh (you have to deal with using decrRef). The returned mesh will have the same name than \a this. + * + * \sa MEDCouplingUMesh::buildExtrudedMesh + */ +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 !"); + 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()); + std::vector levs(getNonEmptyLevels()); + std::vector grps(getGroupsNames()); + std::vector< MCAuto > zeList; + DataArrayDouble *coords(0); + std::size_t nbOfLevsOut(levs.size()+1); + std::vector< MCAuto > o2ns(nbOfLevsOut); + for(std::vector::const_iterator lev=levs.begin();lev!=levs.end();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 + MCAuto tmp(static_cast(m1D->deepCopy())); + tmp->changeSpaceDimension(3+(*lev),0.); + 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< MCAuto >::iterator it=zeList.begin();it!=zeList.end();it++) + { + (*it)->setName(getName()); + (*it)->setCoords(coords); + } + for(std::size_t ii=0;ii!=zeList.size();ii++) + { + int lev(levs[ii]); + MCAuto elt(zeList[ii]); + if(lev<=-1) + { + 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()); + std::vector elts(3); + elts[0]=elt; elts[1]=elt1; elts[2]=elt2; + elt=MEDCouplingUMesh::MergeUMeshesOnSameCoords(elts); + elt->setName(getName()); + } + // + o2ns[ii]=elt->sortCellsInMEDFileFrmt(); + ret->setMeshAtLevel(lev,elt); + } + MCAuto endLev(getMeshAtLevel(levs.back())),endLev2; + endLev=endLev->clone(false); endLev->setCoords(coords); + MCAuto tmp(endLev->getNodalConnectivity()->deepCopy()); + endLev2=endLev->clone(false); endLev2->setConnectivity(tmp,endLev->getNodalConnectivityIndex()); + endLev2->shiftNodeNumbersInConn(nbRep*getNumberOfNodes()); + endLev=MEDCouplingUMesh::MergeUMeshesOnSameCoords(endLev,endLev2); + o2ns[levs.size()]=endLev->sortCellsInMEDFileFrmt(); + endLev->setName(getName()); + ret->setMeshAtLevel(levs.back()-1,endLev); + // + for(std::size_t ii=0;ii!=zeList.size();ii++) + { + int lev(levs[ii]); + std::vector< MCAuto > outGrps; + std::vector< const DataArrayInt * > outGrps2; + if(lev<=-1) + { + for(std::vector::const_iterator grp=grps.begin();grp!=grps.end();grp++) + { + MCAuto grpArr(getGroupArr(lev+1,*grp)); + if(!grpArr->empty()) + { + MCAuto grpArr1(grpArr->deepCopy()),grpArr2(grpArr->deepCopy()); + int offset0(zeList[ii]->getNumberOfCells()); + int offset1(offset0+getNumberOfCellsAtLevel(lev+1)); + grpArr1->applyLin(1,offset0); grpArr2->applyLin(1,offset1); + std::ostringstream oss; oss << grpArr2->getName() << "_top"; + grpArr2->setName(oss.str()); + grpArr1->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end()); + grpArr2->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end()); + outGrps.push_back(grpArr1); outGrps.push_back(grpArr2); + outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2); + } + } + } + // + for(std::vector::const_iterator grp=grps.begin();grp!=grps.end();grp++) + { + MCAuto grpArr(getGroupArr(lev,*grp)); + if(!grpArr->empty()) + { + int nbCellsB4Extrusion(getNumberOfCellsAtLevel(lev)); + std::vector< MCAuto > grpArrs(nbRep); + std::vector< const DataArrayInt *> grpArrs2(nbRep); + for(int iii=0;iiideepCopy(); grpArrs[iii]->applyLin(1,iii*nbCellsB4Extrusion); + grpArrs2[iii]=grpArrs[iii]; + } + MCAuto grpArrExt(DataArrayInt::Aggregate(grpArrs2)); + grpArrExt->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end()); + std::ostringstream grpName; grpName << *grp << "_extruded"; + grpArrExt->setName(grpName.str()); + outGrps.push_back(grpArrExt); + outGrps2.push_back(grpArrExt); + } + } + ret->setGroupsAtLevel(lev,outGrps2); + } + std::vector< MCAuto > outGrps; + std::vector< const DataArrayInt * > outGrps2; + for(std::vector::const_iterator grp=grps.begin();grp!=grps.end();grp++) + { + MCAuto grpArr1(getGroupArr(levs.back(),*grp)); + if(grpArr1->empty()) + continue; + MCAuto grpArr2(grpArr1->deepCopy()); + std::ostringstream grpName; grpName << *grp << "_top"; + grpArr2->setName(grpName.str()); + grpArr2->applyLin(1,getNumberOfCellsAtLevel(levs.back())); + outGrps.push_back(grpArr1); outGrps.push_back(grpArr2); + outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2); + } + ret->setGroupsAtLevel(levs.back()-1,outGrps2); + return ret.retn(); +} + +/*! + * This method converts all linear cells in \a this into quadratic cells (following the \a conversionType policy). + * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance. + * Groups on nodes and families on nodes are copied directly to the returned instance without transformation. + * + * \param [in] conversionType - conversionType specifies the type of conversion expected. Only 0 (default) and 1 are supported presently. 0 those that creates the 'most' simple + * corresponding quadratic cells. 1 is those creating the 'most' complex. + * \param [in] eps - detection threshold for coordinates. + * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance. + * + * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , quadraticToLinear + */ +MEDFileUMesh *MEDFileUMesh::linearToQuadratic(int conversionType, double eps) const +{ + checkCartesian(); + MCAuto ret(MEDFileUMesh::New()); + int initialNbNodes(getNumberOfNodes()); + MCAuto m0Tmp(getMeshAtLevel(0)); + MCAuto m0(dynamic_cast(m0Tmp->deepCopy())); + { + MCAuto notUsed(m0->convertLinearCellsToQuadratic(conversionType)); + } + DataArrayDouble *zeCoords(m0->getCoords()); + ret->setMeshAtLevel(0,m0); + std::vector levs(getNonEmptyLevels()); + const DataArrayInt *famField(getFamilyFieldAtLevel(0)); + if(famField) + { + MCAuto famFieldCpy(famField->deepCopy()); + ret->setFamilyFieldArr(0,famFieldCpy); + } + famField=getFamilyFieldAtLevel(1); + if(famField) + { + MCAuto fam(DataArrayInt::New()); fam->alloc(zeCoords->getNumberOfTuples(),1); + fam->fillWithZero(); + fam->setPartOfValues1(famField,0,initialNbNodes,1,0,1,1); + ret->setFamilyFieldArr(1,fam); + } + ret->copyFamGrpMapsFrom(*this); + MCAuto partZeCoords(zeCoords->selectByTupleIdSafeSlice(initialNbNodes,zeCoords->getNumberOfTuples(),1)); + for(std::vector::const_iterator lev=levs.begin();lev!=levs.end();lev++) + { + if(*lev==0) + continue; + MCAuto m1Tmp(getMeshAtLevel(*lev)); + MCAuto m1(dynamic_cast(m1Tmp->deepCopy())); + if(m1->getMeshDimension()!=0) + { + { + MCAuto notUsed(m1->convertLinearCellsToQuadratic(conversionType)); + }//kill unused notUsed var + MCAuto m1Coords(m1->getCoords()->selectByTupleIdSafeSlice(initialNbNodes,m1->getNumberOfNodes(),1)); + DataArrayInt *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(DataArrayInt::New()); l0->alloc(initialNbNodes,1); l0->iota(); + std::vector v(2); v[0]=l0; v[1]=b; + MCAuto renum(DataArrayInt::Aggregate(v)); + m1->renumberNodesInConn(renum->begin()); + } + m1->setCoords(zeCoords); + ret->setMeshAtLevel(*lev,m1); + famField=getFamilyFieldAtLevel(*lev); + if(famField) + { + MCAuto famFieldCpy(famField->deepCopy()); + ret->setFamilyFieldArr(*lev,famFieldCpy); + } + } + return ret.retn(); +} + +/*! + * This method converts all quadratic cells in \a this into linear cells. + * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance. + * Groups on nodes and families on nodes are copied directly to the returned instance without transformation. + * + * \param [in] eps - detection threshold for coordinates. + * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance. + * + * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , linearToQuadratic + */ +MEDFileUMesh *MEDFileUMesh::quadraticToLinear(double eps) const +{ + 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)); + if(famField) + { + MCAuto famFieldCpy(famField->deepCopy()); + ret->setFamilyFieldArr(0,famFieldCpy); + } + famField=getFamilyFieldAtLevel(1); + if(famField) + { + MCAuto fam(famField->selectByTupleIdSafeSlice(0,zeCoords->getNumberOfTuples(),1)); + ret->setFamilyFieldArr(1,fam); + } + ret->copyFamGrpMapsFrom(*this); + for(std::vector::const_iterator lev=levs.begin();lev!=levs.end();lev++) + { + if(*lev==0) + continue; + MCAuto m1Tmp(getMeshAtLevel(*lev)); + MCAuto m1(dynamic_cast(m1Tmp->deepCopy())); + m1->convertQuadraticCellsToLinear(); + m1->zipCoords(); + DataArrayInt *b(0); + bool a(zeCoords->areIncludedInMe(m1->getCoords(),eps,b)); + MCAuto bSafe(b); + if(!a) + { + std::ostringstream oss; oss << "MEDFileUMesh::quadraticToLinear : for level " << *lev << " problem to identify nodes generated !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + m1->renumberNodesInConn(b->begin()); + m1->setCoords(zeCoords); + ret->setMeshAtLevel(*lev,m1); + famField=getFamilyFieldAtLevel(*lev); + if(famField) + { + MCAuto famFieldCpy(famField->deepCopy()); + ret->setFamilyFieldArr(*lev,famFieldCpy); + } + } + return ret.retn(); +} + +/*! + * 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; +} + +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(std::vector::const_iterator 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 map1; + std::map > map2; + for(std::vector::const_iterator it=meshes.begin();it!=meshes.end();it++,i++) + { + if((*it)->getSpaceDimension()!=spaceDim) + throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : space dimension must be homogeneous !"); + if((*it)->getMeshDimension()!=meshDim) + throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : mesh dimension must be homogeneous !"); + if((*it)->getNonEmptyLevels()!=levs) + throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : levels must be the same for elements in input vector !"); + for(std::vector::const_iterator it2=levs.begin();it2!=levs.end();it2++) + { + MCAuto locMesh((*it)->getMeshAtLevel(*it2)); + m_mesh[*it2].push_back(locMesh); m_mesh2[*it2].push_back(locMesh); + m_fam[*it2].push_back((*it)->getFamilyFieldAtLevel(*it2)); + m_renum[*it2].push_back((*it)->getNumberFieldAtLevel(*it2)); + } + const std::map& locMap1((*it)->getFamilyInfo()); + for(std::map::const_iterator it3=locMap1.begin();it3!=locMap1.end();it3++) + map1[(*it3).first]=(*it3).second; + const std::map >& locMap2((*it)->getGroupInfo()); + for(std::map >::const_iterator it4=locMap2.begin();it4!=locMap2.end();it4++) + map2[(*it4).first]=(*it4).second; + } + // 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 DataArrayInt *)0)==fam_coos.end()) + { + MCAuto fam_coo(DataArrayInt::Aggregate(fam_coos)); + ret->setFamilyFieldArr(1,fam_coo); + } + if(std::find(num_coos.begin(),num_coos.end(),(const DataArrayInt *)0)==num_coos.end()) + { + MCAuto num_coo(DataArrayInt::Aggregate(num_coos)); + ret->setRenumFieldArr(1,num_coo); + } + // cells + for(std::vector::const_iterator it=levs.begin();it!=levs.end();it++) + { + std::map >::const_iterator it2(m_mesh.find(*it)); + 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(*it,mesh); + std::map >::const_iterator it3(m_fam.find(*it)),it4(m_renum.find(*it)); + if(it3!=m_fam.end()) + { + const std::vector& fams((*it3).second); + if(std::find(fams.begin(),fams.end(),(const DataArrayInt *)0)==fams.end()) + { + MCAuto famm(DataArrayInt::Aggregate(fams)); + famm->renumberInPlace(renum->begin()); + ret->setFamilyFieldArr(*it,famm); + } + } + if(it4!=m_renum.end()) + { + const std::vector& renums((*it4).second); + if(std::find(renums.begin(),renums.end(),(const DataArrayInt *)0)==renums.end()) + { + MCAuto renumm(DataArrayInt::Aggregate(renums)); + renumm->renumberInPlace(renum->begin()); + ret->setRenumFieldArr(*it,renumm); + } + } } + // + ret->setFamilyInfo(map1); + ret->setGroupInfo(map2); + 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 !"); + int 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(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());//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());//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()); + 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)==4+aa+1+bb layer#0 + bigArrayD=_coords;// 0 bd + bigArraysI.push_back(_fam_coords);// 0 bi + bigArraysI.push_back(_num_coords);// 1 bi + const PartDefinition *pd(_part_coords); + if(!pd) + layer0.push_back(-1); + else + { + std::vector tmp0; + pd->serialize(tmp0,bigArraysI); + tinyInt.push_back(tmp0.size()); + tinyInt.insert(tinyInt.end(),tmp0.begin(),tmp0.end()); + } + // + std::vector layer1; + std::vector levs(getNonEmptyLevels()); + layer1.push_back((int)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++) + { + const MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(*it)); + lev->serialize(layer1,bigArraysI); + } + // put layers all together. + tinyInt.push_back(layer0.size()); + tinyInt.insert(tinyInt.end(),layer0.begin(),layer0.end()); + tinyInt.push_back(layer1.size()); + tinyInt.insert(tinyInt.end(),layer1.begin(),layer1.end()); +} + +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); + // + std::reverse(layer0.begin(),layer0.end()); + std::reverse(layer1.begin(),layer1.end()); + std::reverse(tinyDouble.begin(),tinyDouble.end()); + std::reverse(tinyStr.begin(),tinyStr.end()); + std::reverse(bigArraysI.begin(),bigArraysI.end()); + // + setAxisType((MEDCouplingAxisType)layer0.back()); layer0.pop_back(); + _order=layer0.back(); layer0.pop_back(); + _iteration=layer0.back(); layer0.pop_back(); + int 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(); + _coords=bigArrayD; _coords->rearrange(spaceDim); + for(int i=0;isetInfoOnComponent(i,tinyStr.back()); + tinyStr.pop_back(); + } + int nbOfFams(layer0.back()); layer0.pop_back(); + _families.clear(); + for(int i=0;i fams(nbOfFamsOnGrp); + for(int j=0;j 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()); + _ms.clear(); + int maxLev(-(*std::min_element(levs.begin(),levs.end()))); + _ms.resize(maxLev+1); + for(int i=0;igetName() == "". @@ -3439,10 +4838,10 @@ DataArrayInt *MEDFileUMesh::zipCoords() */ void MEDFileUMesh::addNodeGroup(const DataArrayInt *ids) { - const DataArrayDouble *coords=_coords; + const DataArrayDouble *coords(_coords); if(!coords) throw INTERP_KERNEL::Exception("MEDFileUMesh::addNodeGroup : no coords set !"); - int nbOfNodes=coords->getNumberOfTuples(); + int nbOfNodes(coords->getNumberOfTuples()); if(!((DataArrayInt *)_fam_coords)) { _fam_coords=DataArrayInt::New(); _fam_coords->alloc(nbOfNodes,1); _fam_coords->fillWithZero(); } // @@ -3451,8 +4850,13 @@ 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. * The ids should be sorted and different each other (MED file norm). + * + * \warning this method can alter default "FAMILLE_ZERO" family. + * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session. + * * \throw If the node coordinates array is not set. * \throw If \a ids == \c NULL. * \throw If \a ids->getName() == "". @@ -3461,7 +4865,7 @@ void MEDFileUMesh::addNodeGroup(const DataArrayInt *ids) */ void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids) { - std::vector levs=getNonEmptyLevelsExt(); + std::vector levs(getNonEmptyLevelsExt()); if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end()) { std::ostringstream oss; oss << "MEDFileUMesh::addGroup : level " << meshDimRelToMaxExt << " not available ! Should be in "; @@ -3469,95 +4873,16 @@ void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids) } if(meshDimRelToMaxExt==1) { addNodeGroup(ids); return ; } - MEDFileUMeshSplitL1 *lev=getMeshAtLevSafe(meshDimRelToMaxExt); - DataArrayInt *fam=lev->getOrCreateAndGetFamilyField(); + MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(meshDimRelToMaxExt)); + DataArrayInt *fam(lev->getOrCreateAndGetFamilyField()); addGroupUnderground(false,ids,fam); } /*! - * \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) - */ -void MEDFileUMesh::addGroupUnderground(bool isNodeGroup, const DataArrayInt *ids, DataArrayInt *famArr) -{ - if(!ids) - throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : NULL pointer in input !"); - std::string grpName(ids->getName()); - 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(); - 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); - std::map > groups(_groups); - std::vector fams; - bool created(false); - for(const int *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)); - if(ret0->empty()) - { - bool isFamPresent=false; - for(std::list< MEDCouplingAutoRefCountObjectPtr >::const_iterator itl=allFamIds.begin();itl!=allFamIds.end() && !isFamPresent;itl++) - isFamPresent=(*itl)->presenceOfValue(*famId); - if(!isFamPresent) - { familyIds.push_back(*famId); idsPerfamiliyIds.push_back(ret0); fams.push_back(FindOrCreateAndGiveFamilyWithId(families,*famId,created)); } // adding *famId in grp - else - { - familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ids2); - std::string locFamName=FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created); - fams.push_back(locFamName); - if(existsFamily(*famId)) - { - std::string locFamName2=getFamilyNameGivenId(*famId); std::vector v(2); v[0]=locFamName2; v[1]=locFamName; - ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v); - } - maxVal++; - } // modifying all other groups on *famId to lie on maxVal and lie the grp on maxVal - } - else - { - familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ret0); // modifying all other groups on *famId to lie on maxVal and on maxVal+1 - familyIds.push_back(isNodeGroup?maxVal+1:-maxVal-1); idsPerfamiliyIds.push_back(ids2);//grp lie only on maxVal+1 - std::string n2(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal+1:-maxVal-1,created)); fams.push_back(n2); - if(existsFamily(*famId)) - { - std::string n1(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created)); std::vector v(2); v[0]=n1; v[1]=n2; - ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v); - } - maxVal+=2; - } - } - for(std::size_t i=0;isetPartOfValuesSimple3(familyIds[i],da->begin(),da->end(),0,1,1); - } - _families=families; - _groups=groups; - _groups[grpName]=fams; -} - -/*! - * Changes a name of a family specified by its id. - * \param [in] id - the id of the family of interest. - * \param [in] newFamName - the new family name. - * \throw If no family with the given \a id exists. + * Changes a name of a family specified by its id. + * \param [in] id - the id of the family of interest. + * \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) { @@ -3594,7 +4919,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; } @@ -3613,11 +4938,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(); @@ -3698,7 +5023,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. */ @@ -3720,8 +5045,8 @@ 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()); + 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()); setGroupsAtLevel(meshDimRelToMax,corr2,true); @@ -3742,7 +5067,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++) { @@ -3787,7 +5112,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) @@ -3825,7 +5150,7 @@ void MEDFileUMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famAr throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : Dimension request is invalid (>1) !"); int traducedRk=-meshDimRelToMaxExt; if(traducedRk>=(int)_ms.size()) - throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !"); + throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !"); if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0) throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !"); return _ms[traducedRk]->setFamilyArr(famArr); @@ -3861,7 +5186,7 @@ void MEDFileUMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumA throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumArr : Dimension request is invalid (>1) !"); int traducedRk=-meshDimRelToMaxExt; if(traducedRk>=(int)_ms.size()) - throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !"); + throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !"); if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0) throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !"); return _ms[traducedRk]->setRenumArr(renumArr); @@ -3895,7 +5220,7 @@ void MEDFileUMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiCha throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : Dimension request is invalid (>1) !"); int traducedRk=-meshDimRelToMaxExt; if(traducedRk>=(int)_ms.size()) - throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !"); + throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !"); if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0) throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !"); return _ms[traducedRk]->setNameArr(nameArr); @@ -3903,7 +5228,7 @@ void MEDFileUMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiCha 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); } @@ -3916,7 +5241,7 @@ void MEDFileUMesh::changeFamilyIdArr(int oldId, int newId) DataArrayInt *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) @@ -3926,20 +5251,20 @@ void MEDFileUMesh::changeFamilyIdArr(int oldId, int newId) } } -std::list< MEDCouplingAutoRefCountObjectPtr > MEDFileUMesh::getAllNonNullFamilyIds() const +std::list< MCAuto > MEDFileUMesh::getAllNonNullFamilyIds() const { - std::list< MEDCouplingAutoRefCountObjectPtr > ret; + std::list< MCAuto > ret; const DataArrayInt *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; @@ -3960,21 +5285,21 @@ std::size_t MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren() const return MEDFileMesh::getHeapMemorySizeWithoutChildren(); } -std::vector MEDFileStructuredMesh::getDirectChildren() const -{ - std::vector ret(MEDFileMesh::getDirectChildren()); - if((const DataArrayInt *)_fam_nodes) - ret.push_back((const DataArrayInt *)_fam_nodes); - if((const DataArrayInt *)_num_nodes) - ret.push_back((const DataArrayInt *)_num_nodes); - if((const DataArrayInt *)_fam_cells) - ret.push_back((const DataArrayInt *)_fam_cells); - if((const DataArrayInt *)_num_cells) - ret.push_back((const DataArrayInt *)_num_nodes); - if((const DataArrayInt *)_rev_num_nodes) - ret.push_back((const DataArrayInt *)_rev_num_nodes); - if((const DataArrayInt *)_rev_num_cells) - ret.push_back((const DataArrayInt *)_rev_num_cells); +std::vector MEDFileStructuredMesh::getDirectChildrenWithNull() const +{ + std::vector ret(MEDFileMesh::getDirectChildrenWithNull()); + ret.push_back((const DataArrayInt *)_fam_nodes); + ret.push_back((const DataArrayInt *)_num_nodes); + ret.push_back((const DataArrayAsciiChar *)_names_nodes); + ret.push_back((const DataArrayInt *)_fam_cells); + ret.push_back((const DataArrayInt *)_num_cells); + ret.push_back((const DataArrayAsciiChar *)_names_cells); + ret.push_back((const DataArrayInt *)_fam_faces); + ret.push_back((const DataArrayInt *)_num_faces); + ret.push_back((const DataArrayInt *)_rev_num_nodes); + ret.push_back((const DataArrayAsciiChar *)_names_faces); + ret.push_back((const DataArrayInt *)_rev_num_cells); + ret.push_back((const MEDCoupling1SGTUMesh*)_faces_if_necessary); return ret; } @@ -3991,6 +5316,11 @@ int MEDFileStructuredMesh::getMaxAbsFamilyIdInArrays() const int val=_fam_cells->getMaxValue(tmp); ret=std::max(ret,std::abs(val)); } + if((const DataArrayInt *)_fam_faces) + { + int val=_fam_faces->getMaxValue(tmp); + ret=std::max(ret,std::abs(val)); + } return ret; } @@ -4007,6 +5337,11 @@ int MEDFileStructuredMesh::getMaxFamilyIdInArrays() const int val=_fam_cells->getMaxValue(tmp); ret=std::max(ret,val); } + if((const DataArrayInt *)_fam_faces) + { + int val=_fam_faces->getMaxValue(tmp); + ret=std::max(ret,val); + } return ret; } @@ -4023,6 +5358,11 @@ int MEDFileStructuredMesh::getMinFamilyIdInArrays() const int val=_fam_cells->getMinValue(tmp); ret=std::min(ret,val); } + if((const DataArrayInt *)_fam_faces) + { + int val=_fam_faces->getMinValue(tmp); + ret=std::min(ret,val); + } return ret; } @@ -4068,6 +5408,22 @@ bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::s return false; } } + famc1=_fam_faces; + famc2=otherC->_fam_faces; + if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0)) + { + what="Mismatch of families arr on faces ! One is defined and not other !"; + return false; + } + if(famc1) + { + bool ret=famc1->isEqual(*famc2); + if(!ret) + { + what="Families arr on faces differ !"; + return false; + } + } famc1=_num_nodes; famc2=otherC->_num_nodes; if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0)) @@ -4100,6 +5456,22 @@ bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::s return false; } } + famc1=_num_faces; + famc2=otherC->_num_faces; + if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0)) + { + what="Mismatch of numbering arr on faces ! One is defined and not other !"; + return false; + } + if(famc1) + { + bool ret=famc1->isEqual(*famc2); + if(!ret) + { + what="Numbering arr on faces differ !"; + return false; + } + } const DataArrayAsciiChar *d1=_names_cells; const DataArrayAsciiChar *d2=otherC->_names_cells; if((d1==0 && d2!=0) || (d1!=0 && d2==0)) @@ -4116,6 +5488,22 @@ bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::s return false; } } + d1=_names_faces; + d2=otherC->_names_faces; + if((d1==0 && d2!=0) || (d1!=0 && d2==0)) + { + what="Mismatch of naming arr on faces ! One is defined and not other !"; + return false; + } + if(d1) + { + bool ret=d1->isEqual(*d2); + if(!ret) + { + what="Naming arr on faces differ !"; + return false; + } + } d1=_names_nodes; d2=otherC->_names_nodes; if((d1==0 && d2!=0) || (d1!=0 && d2==0)) @@ -4150,6 +5538,12 @@ void MEDFileStructuredMesh::clearNonDiscrAttributes() const tmp=_num_cells; if(tmp) (const_cast(tmp))->setName(""); + tmp=_fam_faces; + if(tmp) + (const_cast(tmp))->setName(""); + tmp=_num_faces; + if(tmp) + (const_cast(tmp))->setName(""); } /*! @@ -4166,43 +5560,67 @@ void MEDFileStructuredMesh::clearNonDiscrAttributes() const */ DataArrayInt *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector& fams, bool renum) const { - if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1) - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : Only available for levels 0 or 1 !"); - std::vector famIds=getFamiliesIds(fams); - if(meshDimRelToMaxExt==1) - { - if((const DataArrayInt *)_fam_nodes) - { - MEDCouplingAutoRefCountObjectPtr da; - if(!famIds.empty()) - da=_fam_nodes->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size()); - else - da=_fam_nodes->getIdsEqualList(0,0); - if(renum) - return MEDFileUMeshSplitL1::Renumber(_num_nodes,da); - else - return da.retn(); - } - else - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on nodes !"); - } - else - { - if((const DataArrayInt *)_fam_cells) - { - MEDCouplingAutoRefCountObjectPtr da; - if(!famIds.empty()) - da=_fam_cells->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size()); - else - da=_fam_cells->getIdsEqualList(0,0); - if(renum) - return MEDFileUMeshSplitL1::Renumber(_num_cells,da); - else - return da.retn(); - } - else - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on cells !"); - } + std::vector famIds(getFamiliesIds(fams)); + switch(meshDimRelToMaxExt) + { + case 1: + { + if((const DataArrayInt *)_fam_nodes) + { + MCAuto da; + if(!famIds.empty()) + da=_fam_nodes->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size()); + else + da=_fam_nodes->findIdsEqualList(0,0); + if(renum) + return MEDFileUMeshSplitL1::Renumber(_num_nodes,da); + else + return da.retn(); + } + else + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on nodes !"); + break; + } + case 0: + { + if((const DataArrayInt *)_fam_cells) + { + MCAuto da; + if(!famIds.empty()) + da=_fam_cells->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size()); + else + da=_fam_cells->findIdsEqualList(0,0); + if(renum) + return MEDFileUMeshSplitL1::Renumber(_num_cells,da); + else + return da.retn(); + } + else + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on cells !"); + break; + } + case -1: + { + if((const DataArrayInt *)_fam_faces) + { + MCAuto da; + if(!famIds.empty()) + da=_fam_faces->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size()); + else + da=_fam_faces->findIdsEqualList(0,0); + if(renum) + return MEDFileUMeshSplitL1::Renumber(_num_faces,da); + else + return da.retn(); + } + else + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on faces !"); + break; + } + default: + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : input meshDimRelative must be in [0,1,-1] !"); + } + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : unmanaged case !"); } /*! @@ -4212,27 +5630,42 @@ DataArrayInt *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, cons * \param [in] famArr - the array of the family field. * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh. * \throw If \a famArr has an invalid size. - * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1. + * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1 and \a meshDimRelToMaxExt != -1. */ void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr) { - if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1) - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 !"); - const MEDCouplingStructuredMesh *mesh=getStructuredMesh(); + const MEDCouplingStructuredMesh *mesh(getStructuredMesh()); if(!mesh) throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : no structured mesh specified ! Impossible to set family array !"); - if(meshDimRelToMaxExt==0) - { - int nbCells=mesh->getNumberOfCells(); - famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !"); - _fam_cells=famArr; - } - else - { - int nbNodes=mesh->getNumberOfNodes(); - famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !"); - _fam_nodes=famArr; - } + switch(meshDimRelToMaxExt) + { + case 0: + { + int nbCells(mesh->getNumberOfCells()); + 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()); + 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()); + 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; + } + default: + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : Only available for levels 0 or 1 or -1 !"); + } if(famArr) famArr->incrRef(); } @@ -4247,23 +5680,35 @@ void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayI */ void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr) { - if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1) - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 !"); const MEDCouplingStructuredMesh *mesh=getStructuredMesh(); if(!mesh) throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : no structured mesh specified ! Impossible to set number array !"); - if(meshDimRelToMaxExt==0) - { - int nbCells=mesh->getNumberOfCells(); - renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of cells of mesh !"); - _num_cells=renumArr; - } - else - { - int nbNodes=mesh->getNumberOfNodes(); - renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !"); - _num_nodes=renumArr; - } + switch(meshDimRelToMaxExt) + { + case 0: + { + int nbCells=mesh->getNumberOfCells(); + renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of cells of mesh !"); + _num_cells=renumArr; + break; + } + case 1: + { + int nbNodes=mesh->getNumberOfNodes(); + renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !"); + _num_nodes=renumArr; + break; + } + case -1: + { + int nbCells=mesh->getNumberOfCellsOfSubLevelMesh(); + renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of faces of mesh !"); + _num_faces=renumArr; + break; + } + default: + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 or -1 !"); + } if(renumArr) renumArr->incrRef(); } @@ -4277,27 +5722,79 @@ void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayIn */ void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr) { - if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1) - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : Only available for levels 0 or 1 !"); - const MEDCouplingStructuredMesh *mesh=getStructuredMesh(); + const MEDCouplingStructuredMesh *mesh(getStructuredMesh()); if(!mesh) throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : no structured mesh specified ! Impossible to set names array !"); - if(meshDimRelToMaxExt==0) - { - int nbCells=mesh->getNumberOfCells(); - nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of cells of mesh !"); - _names_cells=nameArr; - } - else - { - int nbNodes=mesh->getNumberOfNodes(); - nameArr->checkNbOfTuplesAndComp(nbNodes,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of nodes of mesh !"); - _names_nodes=nameArr; - } + switch(meshDimRelToMaxExt) + { + case 0: + { + int nbCells=mesh->getNumberOfCells(); + nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of cells of mesh !"); + _names_cells=nameArr; + break; + } + case 1: + { + int nbNodes=mesh->getNumberOfNodes(); + nameArr->checkNbOfTuplesAndComp(nbNodes,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of nodes of mesh !"); + _names_nodes=nameArr; + break; + } + case -1: + { + int nbCells=mesh->getNumberOfCellsOfSubLevelMesh(); + nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of faces of mesh !"); + _names_cells=nameArr; + } + default: + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : Only available for levels 0 or 1 or -1 !"); + } if(nameArr) nameArr->incrRef(); } +/*! + * Adds a group of nodes to \a this mesh. + * \param [in] ids - a DataArrayInt 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. + * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session. + * + * \throw If the node coordinates array is not set. + * \throw If \a ids == \c NULL. + * \throw If \a ids->getName() == "". + * \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) +{ + addGroup(1,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. + * The ids should be sorted and different each other (MED file norm). + * + * \warning this method can alter default "FAMILLE_ZERO" family. + * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session. + * + * \throw If the node coordinates array is not set. + * \throw If \a ids == \c NULL. + * \throw If \a ids->getName() == "". + * \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) +{ + DataArrayInt *fam(getOrCreateAndGetFamilyFieldAtLevel(meshDimRelToMaxExt)); + addGroupUnderground(false,ids,fam); + return ; +} + /*! * Returns the family field for mesh entities of a given dimension. * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities. @@ -4307,12 +5804,39 @@ void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArra */ const DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const { - if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1) - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 !"); - if(meshDimRelToMaxExt==0) - return _fam_cells; - else - return _fam_nodes; + switch(meshDimRelToMaxExt) + { + case 0: + return _fam_cells; + case 1: + return _fam_nodes; + case -1: + return _fam_faces; + default: + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !"); + } +} + +/*! + * 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 + * each mesh entity belongs to. It can be \c NULL. + * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1. + */ +DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) +{ + switch(meshDimRelToMaxExt) + { + case 0: + return _fam_cells; + case 1: + return _fam_nodes; + case -1: + return _fam_faces; + default: + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !"); + } } /*! @@ -4324,12 +5848,17 @@ const DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelT */ const DataArrayInt *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const { - if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1) - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 !"); - if(meshDimRelToMaxExt==0) - return _num_cells; - else - return _num_nodes; + switch(meshDimRelToMaxExt) + { + case 0: + return _num_cells; + case 1: + return _num_nodes; + case -1: + return _num_faces; + default: + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 or -1 !"); + } } /*! @@ -4373,12 +5902,17 @@ const DataArrayInt *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimR const DataArrayAsciiChar *MEDFileStructuredMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const { - if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1) - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNameFieldAtLevel : Only available for levels 0 or 1 !"); - if(meshDimRelToMaxExt==0) - return _names_cells; - else - return _names_nodes; + switch(meshDimRelToMaxExt) + { + case 0: + return _names_cells; + case 1: + return _names_nodes; + case -1: + return _names_faces; + default: + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNameFieldAtLevel : Only available for levels 0 or 1 or -1 !"); + } } /*! @@ -4408,11 +5942,13 @@ std::vector MEDFileStructuredMesh::getNonEmptyLevelsExt() const std::vector MEDFileStructuredMesh::getFamArrNonEmptyLevelsExt() const { std::vector ret; - const DataArrayInt *famNodes(_fam_nodes),*famCells(_fam_cells); + const DataArrayInt *famNodes(_fam_nodes),*famCells(_fam_cells),*famFaces(_fam_faces); if(famNodes) ret.push_back(1); if(famCells) ret.push_back(0); + if(famFaces) + ret.push_back(-1); return ret; } @@ -4422,11 +5958,13 @@ std::vector MEDFileStructuredMesh::getFamArrNonEmptyLevelsExt() const std::vector MEDFileStructuredMesh::getNumArrNonEmptyLevelsExt() const { std::vector ret; - const DataArrayInt *numNodes(_num_nodes),*numCells(_num_cells); + const DataArrayInt *numNodes(_num_nodes),*numCells(_num_cells),*numFaces(_num_faces); if(numNodes) ret.push_back(1); if(numCells) ret.push_back(0); + if(numFaces) + ret.push_back(-1); return ret; } @@ -4436,9 +5974,13 @@ std::vector MEDFileStructuredMesh::getNumArrNonEmptyLevelsExt() const std::vector MEDFileStructuredMesh::getNameArrNonEmptyLevelsExt() const { std::vector ret; - const DataArrayAsciiChar *namesCells(_names_cells); + const DataArrayAsciiChar *namesNodes(_names_nodes),*namesCells(_names_cells),*namesFaces(_names_faces); + if(namesNodes) + ret.push_back(1); if(namesCells) ret.push_back(0); + if(namesFaces) + ret.push_back(-1); return ret; } @@ -4459,22 +6001,50 @@ void MEDFileStructuredMesh::changeFamilyIdArr(int oldId, int newId) arr=_fam_cells; if(arr) arr->changeValue(oldId,newId); + arr=_fam_faces; + if(arr) + arr->changeValue(oldId,newId); +} + +std::list< MCAuto > MEDFileStructuredMesh::getAllNonNullFamilyIds() const +{ + std::list< MCAuto > ret; + const DataArrayInt *da(_fam_nodes); + if(da) + { da->incrRef(); ret.push_back(MCAuto(const_cast(da))); } + da=_fam_cells; + if(da) + { da->incrRef(); ret.push_back(MCAuto(const_cast(da))); } + da=_fam_faces; + if(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(); + _fam_nodes=_fam_nodes->deepCopy(); if((const DataArrayInt*)_num_nodes) - _num_nodes=_num_nodes->deepCpy(); + _num_nodes=_num_nodes->deepCopy(); + if((const DataArrayAsciiChar*)_names_nodes) + _names_nodes=_names_nodes->deepCopy(); if((const DataArrayInt*)_fam_cells) - _fam_cells=_fam_cells->deepCpy(); + _fam_cells=_fam_cells->deepCopy(); if((const DataArrayInt*)_num_cells) - _num_cells=_num_cells->deepCpy(); + _num_cells=_num_cells->deepCopy(); + if((const DataArrayAsciiChar*)_names_cells) + _names_cells=_names_cells->deepCopy(); + if((const DataArrayInt*)_fam_faces) + _fam_faces=_fam_faces->deepCopy(); + if((const DataArrayInt*)_num_faces) + _num_faces=_num_faces->deepCopy(); + if((const DataArrayAsciiChar*)_names_faces) + _names_faces=_names_faces->deepCopy(); if((const DataArrayInt*)_rev_num_nodes) - _rev_num_nodes=_rev_num_nodes->deepCpy(); + _rev_num_nodes=_rev_num_nodes->deepCopy(); if((const DataArrayInt*)_rev_num_cells) - _rev_num_cells=_rev_num_cells->deepCpy(); + _rev_num_cells=_rev_num_cells->deepCopy(); } /*! @@ -4486,57 +6056,199 @@ void MEDFileStructuredMesh::deepCpyAttributes() /*! * Returns a pointer to MEDCouplingStructuredMesh held by \a this. - * \param [in] meshDimRelToMax - it must be \c 0. + * \param [in] meshDimRelToMax - it must be \c 0 or \c -1. * \param [in] renum - it must be \c false. * \return MEDCouplingMesh * - a pointer to MEDCouplingMesh that the caller is to * delete using decrRef() as it is no more needed. */ -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 !"); - if(meshDimRelToMax!=0) - throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support multi level for mesh 0 expected as input !"); - const MEDCouplingStructuredMesh *m=getStructuredMesh(); - if(m) - m->incrRef(); - return const_cast(m); + const MEDCouplingStructuredMesh *m(getStructuredMesh()); + switch(meshDimRelToMax) + { + case 0: + { + if(m) + m->incrRef(); + return const_cast(m); + } + case -1: + { + if(!m) + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getMeshAtLevel : level -1 requested must be non empty to be able to compute unstructured sub mesh !"); + buildMinusOneImplicitPartIfNeeded(); + MEDCoupling1SGTUMesh *ret(_faces_if_necessary); + if(ret) + ret->incrRef(); + return ret; + } + default: + throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support multi level for mesh 0 expected as input !"); + } +} + +std::vector MEDFileStructuredMesh::getFamsNonEmptyLevels(const std::vector& fams) const +{ + std::vector ret; + const DataArrayInt *famCells(_fam_cells),*famFaces(_fam_faces); + if(famCells && famCells->presenceOfValue(ret)) + ret.push_back(0); + if(famFaces && famFaces->presenceOfValue(ret)) + ret.push_back(-1); + return ret; +} + +std::vector MEDFileStructuredMesh::getFamsNonEmptyLevelsExt(const std::vector& fams) const +{ + std::vector ret(getFamsNonEmptyLevels(fams)); + const DataArrayInt *famNodes(_fam_nodes); + if(famNodes && famNodes->presenceOfValue(ret)) + ret.push_back(1); + return ret; +} + +/*! + * 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. + * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh. + */ +int MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const +{ + const MEDCouplingStructuredMesh *cmesh(getStructuredMesh()); + if(!cmesh) + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : No structured mesh set !"); + switch(meshDimRelToMaxExt) + { + case 0: + return cmesh->getNumberOfCells(); + case 1: + return cmesh->getNumberOfNodes(); + case -1: + return cmesh->getNumberOfCellsOfSubLevelMesh(); + default: + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : Only available for levels 0 or 1 or -1 !"); + } +} + +int MEDFileStructuredMesh::getNumberOfNodes() const +{ + const MEDCouplingStructuredMesh *cmesh(getStructuredMesh()); + if(!cmesh) + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !"); + return cmesh->getNumberOfNodes(); +} + +int MEDFileStructuredMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const +{ + const MEDCouplingStructuredMesh *cmesh(getStructuredMesh()); + if(!cmesh) + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !"); + switch(meshDimRelToMaxExt) + { + case 0: + return cmesh->getNumberOfCells(); + case -1: + return cmesh->getNumberOfCellsOfSubLevelMesh(); + default: + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : only meshDimRelToMax=0 and meshDimRelToMax=-1 supported !"); + } +} + +bool MEDFileStructuredMesh::hasImplicitPart() const +{ + return true; +} + +/*! + * \sa MEDFileStructuredMesh::getImplicitFaceMesh + */ +int MEDFileStructuredMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const +{ + static const char MSG[]="MEDFileStructuredMesh::buildImplicitPartIfAny : the given geo type is not manageable by a structured mesh !"; + const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary); + if(!zeFaceMesh) + { + const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))); + if(cm.getReverseExtrudedType()!=gt) + throw INTERP_KERNEL::Exception(MSG); + buildImplicitPart(); + return getStructuredMesh()->getNumberOfCellsOfSubLevelMesh(); + } + else + { + if(gt!=zeFaceMesh->getCellModelEnum()) + throw INTERP_KERNEL::Exception(MSG); + return zeFaceMesh->getNumberOfCells(); + } +} + +void MEDFileStructuredMesh::buildMinusOneImplicitPartIfNeeded() const +{ + const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary); + if(!zeFaceMesh) + buildImplicitPart(); +} + +void MEDFileStructuredMesh::buildImplicitPart() const +{ + const MEDCouplingStructuredMesh *mcmesh(getStructuredMesh()); + if(!mcmesh) + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::buildImplicitPart : Unable to build the implicit part of structured mesh because no structured mesh at level 0 defined !"); + _faces_if_necessary=mcmesh->build1SGTSubLevelMesh(); +} + +void MEDFileStructuredMesh::releaseImplicitPartIfAny() const +{ + _faces_if_necessary=0; } /*! - * 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. - * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh. + * Retrieves the internal pointer (no decrRef requested) of the implicit face mesh if any. + * To force to build it you can invoke MEDFileStructuredMesh::buildImplicitPartIfAny method. + * + * \sa MEDFileStructuredMesh::buildImplicitPartIfAny */ -int MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const +MEDCoupling1SGTUMesh *MEDFileStructuredMesh::getImplicitFaceMesh() const { - if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1) - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : Only available for levels 0 or 1 !"); - const MEDCouplingStructuredMesh *cmesh=getStructuredMesh(); - if(!cmesh) - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : No structured mesh set !"); - if(meshDimRelToMaxExt==0) - return cmesh->getNumberOfCells(); - else - return cmesh->getNumberOfNodes(); + checkCartesian(); + return _faces_if_necessary; } -int MEDFileStructuredMesh::getNumberOfNodes() const +std::vector MEDFileStructuredMesh::getGeoTypesAtLevel(int meshDimRelToMax) const { const MEDCouplingStructuredMesh *cmesh(getStructuredMesh()); if(!cmesh) - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !"); - return cmesh->getNumberOfNodes(); + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : No structured mesh set !"); + switch(meshDimRelToMax) + { + case 0: + { + std::vector ret(1,cmesh->getTypeOfCell(0)); + return ret; + } + case -1: + { + int mdim(cmesh->getMeshDimension()); + if(mdim<1) + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only one level available for structured meshes ! Input 0 is mandatory or 0D mesh !"); + std::vector ret(1,MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(mdim-1)); + return ret; + } + default: + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only 2 levels available at most : 0 and -1 !"); + } } -std::vector MEDFileStructuredMesh::getGeoTypesAtLevel(int meshDimRelToMax) const +int MEDFileStructuredMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const { - if(meshDimRelToMax!=0) - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only one level available for structured meshes ! Input 0 is mandatory !"); - const MEDCouplingStructuredMesh *cmesh(getStructuredMesh()); - std::vector ret(1,cmesh->getTypeOfCell(0)); - return ret; + if(ct!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension())) + return 0; + else + return getNumberOfCellsAtLevel(0); } void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector& nodesFetched) const @@ -4569,25 +6281,47 @@ void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem med_geometry_type MEDFileStructuredMesh::GetGeoTypeFromMeshDim(int meshDim) { - med_geometry_type geoTypeReq=MED_NONE; - switch(meshDim) + INTERP_KERNEL::NormalizedCellType ct(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(meshDim)); + return typmai3[ct]; +} + +void MEDFileStructuredMesh::LoadStrMeshDAFromFile(med_idt fid, int meshDim, int dt, int it, const std::string& mName, MEDFileMeshReadSelector *mrs, + MCAuto& famCells, MCAuto& numCells, MCAuto& namesCells) +{ + med_bool chgt=MED_FALSE,trsf=MED_FALSE; + med_geometry_type geoTypeReq=MEDFileStructuredMesh::GetGeoTypeFromMeshDim(meshDim); + int nbOfElt(0); + nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf); + if(nbOfElt>0) { - case 3: - geoTypeReq=MED_HEXA8; - break; - case 2: - geoTypeReq=MED_QUAD4; - break; - case 1: - geoTypeReq=MED_SEG2; - break; - case 0: - geoTypeReq=MED_POINT1; - break; - default: - throw INTERP_KERNEL::Exception("Invalid meshdim detected for structured mesh ! Must be in (1,2,3) !"); + if(!mrs || mrs->isCellFamilyFieldReading()) + { + famCells=DataArrayInt::New(); + famCells->alloc(nbOfElt,1); + MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,famCells->getPointer())); + } + } + nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NUMBER,MED_NODAL,&chgt,&trsf); + if(nbOfElt>0) + { + if(!mrs || mrs->isCellNumFieldReading()) + { + numCells=DataArrayInt::New(); + numCells->alloc(nbOfElt,1); + MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,numCells->getPointer())); + } + } + nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NAME,MED_NODAL,&chgt,&trsf); + if(nbOfElt>0) + { + if(!mrs || mrs->isCellNameFieldReading()) + { + namesCells=DataArrayAsciiChar::New(); + namesCells->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end + MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,namesCells->getPointer())); + namesCells->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end + } } - return geoTypeReq; } void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) @@ -4601,14 +6335,19 @@ 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); + int 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()); + 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(nbOfElt,1); - MEDmeshEntityFamilyNumberRd(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_fam_nodes->getPointer()); + _fam_nodes->alloc(nbNodes,1);//yes nbNodes and not nbOfElt see next line. + if(nbNodes>nbOfElt)//yes it appends some times... It explains surely the mdump implementation. Bug revealed by PARAVIS EDF #2475 on structured.med file where only 12 first nodes are !=0 so nbOfElt=12 and nbOfNodes=378... + _fam_nodes->fillWithZero(); + MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_fam_nodes->getPointer())); } } nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NUMBER,MED_NODAL,&chgt,&trsf); @@ -4618,40 +6357,7 @@ void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt { _num_nodes=DataArrayInt::New(); _num_nodes->alloc(nbOfElt,1); - MEDmeshEntityNumberRd(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_num_nodes->getPointer()); - } - } - int meshDim=getStructuredMesh()->getMeshDimension(); - med_geometry_type geoTypeReq=GetGeoTypeFromMeshDim(meshDim); - nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf); - if(nbOfElt>0) - { - if(!mrs || mrs->isCellFamilyFieldReading()) - { - _fam_cells=DataArrayInt::New(); - _fam_cells->alloc(nbOfElt,1); - MEDmeshEntityFamilyNumberRd(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,_fam_cells->getPointer()); - } - } - nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NUMBER,MED_NODAL,&chgt,&trsf); - if(nbOfElt>0) - { - if(!mrs || mrs->isCellNumFieldReading()) - { - _num_cells=DataArrayInt::New(); - _num_cells->alloc(nbOfElt,1); - MEDmeshEntityNumberRd(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,_num_cells->getPointer()); - } - } - nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NAME,MED_NODAL,&chgt,&trsf); - if(nbOfElt>0) - { - if(!mrs || mrs->isCellNameFieldReading()) - { - _names_cells=DataArrayAsciiChar::New(); - _names_cells->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end - MEDmeshEntityNameRd(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,_names_cells->getPointer()); - _names_cells->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end + MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_num_nodes->getPointer())); } } nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NAME,MED_NODAL,&chgt,&trsf); @@ -4661,25 +6367,33 @@ void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt { _names_nodes=DataArrayAsciiChar::New(); _names_nodes->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end - MEDmeshEntityNameRd(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_names_nodes->getPointer()); + MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_names_nodes->getPointer())); _names_nodes->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end } } + int meshDim(getStructuredMesh()->getMeshDimension()); + LoadStrMeshDAFromFile(fid,meshDim,dt,it,mName,mrs,_fam_cells,_num_cells,_names_cells); + if(meshDim>=1) + LoadStrMeshDAFromFile(fid,meshDim-1,dt,it,mName,mrs,_fam_faces,_num_faces,_names_faces); } void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const std::string& maa) const { - int meshDim=getStructuredMesh()->getMeshDimension(); - med_geometry_type geoTypeReq=GetGeoTypeFromMeshDim(meshDim); + int meshDim(getStructuredMesh()->getMeshDimension()); + med_geometry_type geoTypeReq(GetGeoTypeFromMeshDim(meshDim)),geoTypeReq2(GetGeoTypeFromMeshDim(meshDim-1)); // if((const DataArrayInt *)_fam_cells) - MEDmeshEntityFamilyNumberWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_fam_cells->getNumberOfTuples(),_fam_cells->getConstPointer()); + 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) - MEDmeshEntityFamilyNumberWr(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_fam_nodes->getNumberOfTuples(),_fam_nodes->getConstPointer()); + MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_fam_nodes->getNumberOfTuples(),_fam_nodes->getConstPointer())); if((const DataArrayInt *)_num_cells) - MEDmeshEntityNumberWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_num_cells->getNumberOfTuples(),_num_cells->getConstPointer()); + 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) - MEDmeshEntityNumberWr(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_num_nodes->getNumberOfTuples(),_num_nodes->getConstPointer()); + MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_num_nodes->getNumberOfTuples(),_num_nodes->getConstPointer())); if((const DataArrayAsciiChar *)_names_cells) { if(_names_cells->getNumberOfComponents()!=MED_SNAME_SIZE) @@ -4688,7 +6402,17 @@ 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()); } - 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,_names_cells->getNumberOfTuples(),_names_cells->getConstPointer())); + } + if((const DataArrayAsciiChar *)_names_faces) + { + if(_names_faces->getNumberOfComponents()!=MED_SNAME_SIZE) + { + std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on faces with number of components set to " << MED_SNAME_SIZE; + oss << " ! The array has " << _names_faces->getNumberOfComponents() << " components !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_names_faces->getNumberOfTuples(),_names_faces->getConstPointer())); } if((const DataArrayAsciiChar *)_names_nodes) { @@ -4698,7 +6422,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()); } - 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,_names_nodes->getNumberOfTuples(),_names_nodes->getConstPointer())); } // MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa.c_str(),_families,_groups,_too_long_str); @@ -4726,19 +6450,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); } /*! @@ -4757,8 +6475,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); } @@ -4767,11 +6489,10 @@ std::size_t MEDFileCMesh::getHeapMemorySizeWithoutChildren() const return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren(); } -std::vector MEDFileCMesh::getDirectChildren() const +std::vector MEDFileCMesh::getDirectChildrenWithNull() const { - std::vector ret(MEDFileStructuredMesh::getDirectChildren()); - if((const MEDCouplingCMesh *)_cmesh) - ret.push_back((const MEDCouplingCMesh *)_cmesh); + std::vector ret(MEDFileStructuredMesh::getDirectChildrenWithNull()); + ret.push_back((const MEDCouplingCMesh *)_cmesh); return ret; } @@ -4817,9 +6538,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(); } @@ -4828,11 +6549,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(); } @@ -4890,20 +6612,21 @@ MEDFileCMesh::MEDFileCMesh() MEDFileCMesh::MEDFileCMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) try - { - loadCMeshFromFile(fid,mName,dt,it,mrs); - } +{ + 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 !"; @@ -4911,6 +6634,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; @@ -4947,7 +6671,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); @@ -4966,13 +6713,14 @@ 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 } - MEDmeshCr(fid,maa,spaceDim,spaceDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit); - MEDmeshUniversalNameWr(fid,maa); - 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); - MEDmeshGridIndexCoordinateWr(fid,maa,_iteration,_order,_time,i+1,da->getNumberOfTuples(),da->getConstPointer()); + MEDFILESAFECALLERWR0(MEDmeshGridIndexCoordinateWr,(fid,maa,_iteration,_order,_time,i+1,da->getNumberOfTuples(),da->getConstPointer())); } // std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE)); @@ -4995,27 +6743,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); } @@ -5024,17 +6770,16 @@ std::size_t MEDFileCurveLinearMesh::getHeapMemorySizeWithoutChildren() const return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren(); } -std::vector MEDFileCurveLinearMesh::getDirectChildren() const +std::vector MEDFileCurveLinearMesh::getDirectChildrenWithNull() const { - std::vector ret(MEDFileStructuredMesh::getDirectChildren()); - if((const MEDCouplingCurveLinearMesh *)_clmesh) - ret.push_back((const MEDCouplingCurveLinearMesh *)_clmesh); + std::vector ret(MEDFileStructuredMesh::getDirectChildrenWithNull()); + ret.push_back((const MEDCouplingCurveLinearMesh *)_clmesh); return ret; } -MEDFileMesh *MEDFileCurveLinearMesh::shallowCpy() const +MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::shallowCpy() const { - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileCurveLinearMesh(*this); + MCAuto ret(new MEDFileCurveLinearMesh(*this)); return ret.retn(); } @@ -5043,11 +6788,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(); } @@ -5131,6 +6877,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(); @@ -5143,15 +6914,15 @@ MEDFileCurveLinearMesh::MEDFileCurveLinearMesh() MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) try - { - loadCLMeshFromFile(fid,mName,dt,it,mrs); - } +{ + 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); @@ -5165,7 +6936,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)); @@ -5174,24 +6945,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 } - MEDmeshCr(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit); - MEDmeshUniversalNameWr(fid,maa); - MEDmeshGridTypeWr(fid,maa,MED_CURVILINEAR_GRID); + 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(); - MEDmeshGridStructWr(fid,maa,_iteration,_order,_time,&nodeGridSt[0]); - - MEDmeshNodeCoordinateWr(fid,maa,_iteration,_order,_time,MED_FULL_INTERLACE,coords->getNumberOfTuples(),coords->begin()); + MEDFILESAFECALLERWR0(MEDmeshGridStructWr,(fid,maa,_iteration,_order,_time,&nodeGridSt[0])); + + MEDFILESAFECALLERWR0(MEDmeshNodeCoordinateWr,(fid,maa,_iteration,_order,_time,MED_FULL_INTERLACE,coords->getNumberOfTuples(),coords->begin())); // std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE)); MEDFileStructuredMesh::writeStructuredLL(fid,meshName); } -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 !"; @@ -5210,42 +6984,50 @@ 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::getDirectChildren() const +std::vector MEDFileMeshMultiTS::getDirectChildrenWithNull() const { std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++) - { - const MEDFileMesh *cur(*it); - if(cur) - ret.push_back(cur); - } + 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; } @@ -5267,7 +7049,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) @@ -5276,6 +7058,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()) @@ -5289,99 +7084,137 @@ 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; } -void MEDFileMeshMultiTS::write(med_idt fid) const +MEDFileJoints * MEDFileMeshMultiTS::getJoints() const +{ + if ( MEDFileMesh* m = getOneTimeStep() ) + return m->getJoints(); + return 0; +} + +/*! + * \brief Set Joints that are common to all time-stamps + */ +void MEDFileMeshMultiTS::setJoints( MEDFileJoints* joints ) { - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_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)->copyOptionsFrom(*this); - (*it)->write(fid); + (*it)->setJoints( joints ); } } -void MEDFileMeshMultiTS::write(const std::string& fileName, int mode) 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() { - 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); + for(std::vector< MCAuto >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++) + if((*it).isNotNull()) + (*it)->killStructureElements(); } -void MEDFileMeshMultiTS::loadFromFile(const std::string& fileName, const std::string& mName) -{//for the moment to be improved - _mesh_one_ts.resize(1); - _mesh_one_ts[0]=MEDFileMesh::New(fileName,mName,-1,-1); +void MEDFileMeshMultiTS::writeLL(med_idt fid) const +{ + MEDFileJoints *joints(getJoints()); + bool jointsWritten(false); + + for(std::vector< MCAuto >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++) + { + if ( jointsWritten ) + const_cast(**it).setJoints( 0 ); + else + jointsWritten = true; + + (*it)->copyOptionsFrom(*this); + (*it)->writeLL(fid); + } + + (const_cast(this))->setJoints( joints ); // restore joints +} + +void MEDFileMeshMultiTS::loadFromFile(med_idt fid, const std::string& mName) +{ + 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(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 << "\" !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); + { + std::ostringstream oss; oss << "MEDFileMeshMultiTS : no meshes in file \"" << FileNameFromFID(fid) << "\" !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } 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) - { +{ throw e; - } +} 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 { @@ -5393,6 +7226,7 @@ MEDFileMeshesIterator *MEDFileMeshes::iterator() return new MEDFileMeshesIterator(this); } +/** Return a borrowed reference (caller is not responsible) */ MEDFileMesh *MEDFileMeshes::getMeshAtPos(int i) const { if(i<0 || i>=(int)_meshes.size()) @@ -5403,6 +7237,7 @@ MEDFileMesh *MEDFileMeshes::getMeshAtPos(int i) const return _meshes[i]->getOneTimeStep(); } +/** Return a borrowed reference (caller is not responsible) */ MEDFileMesh *MEDFileMeshes::getMeshWithName(const std::string& mname) const { std::vector ms=getMeshesNames(); @@ -5420,7 +7255,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) @@ -5439,7 +7274,7 @@ std::vector MEDFileMeshes::getMeshesNames() const 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) @@ -5448,6 +7283,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); @@ -5483,54 +7328,50 @@ 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::getDirectChildren() const +std::vector MEDFileMeshes::getDirectChildrenWithNull() const { std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_meshes.begin();it!=_meshes.end();it++) - { - const MEDFileMeshMultiTS *cur(*it); - if(cur) - ret.push_back(cur); - } + for(std::vector< MCAuto >::const_iterator it=_meshes.begin();it!=_meshes.end();it++) + ret.push_back((const MEDFileMeshMultiTS *)*it); return ret; } @@ -5551,12 +7392,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) @@ -5574,6 +7415,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) @@ -5600,3 +7457,34 @@ 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; + default: + { + std::ostringstream oss; oss << "EDFileMesh::ConvertFromMEDFileEntity : not recognized entity " << etype << " !"; + throw INTERP_KERNEL::Exception(oss.str()); + } + } +} + +