X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FMEDLoader%2FMEDFileMesh.cxx;h=692da3e72a8d01e5a931932101a565c078af917d;hb=8c3dcf5940836637ac7bcb000049e833c5581eb7;hp=9c7698caf9fa2411a8792decd3037be4adc5cf42;hpb=95cadd9b5d549b9eb20de896f2f4526ba65a1e1a;p=tools%2Fmedcoupling.git diff --git a/src/MEDLoader/MEDFileMesh.cxx b/src/MEDLoader/MEDFileMesh.cxx index 9c7698caf..692da3e72 100644 --- a/src/MEDLoader/MEDFileMesh.cxx +++ b/src/MEDLoader/MEDFileMesh.cxx @@ -39,7 +39,7 @@ using namespace ParaMEDMEM; const char MEDFileMesh::DFT_FAM_NAME[]="FAMILLE_ZERO"; -MEDFileMesh::MEDFileMesh():_order(-1),_iteration(-1),_time(0.),_univ_wr_status(true) +MEDFileMesh::MEDFileMesh():_order(-1),_iteration(-1),_time(0.),_univ_wr_status(true),_axis_type(AX_CART) { } @@ -59,7 +59,9 @@ std::size_t MEDFileMesh::getHeapMemorySizeWithoutChildren() const std::vector MEDFileMesh::getDirectChildrenWithNull() const { - return std::vector(); + std::vector ret(1); + ret[0]=(const MEDFileEquivalences *)_equiv; + return ret; } /*! @@ -85,29 +87,25 @@ MEDFileMesh *MEDFileMesh::New(const std::string& fileName, MEDFileMeshReadSelect MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); int dt,it; std::string dummy2; - MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2); + ParaMEDMEM::MEDCouplingAxisType dummy3; + MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2); + MEDCouplingAutoRefCountObjectPtr ret; switch(meshType) { case UNSTRUCTURED: { - MEDCouplingAutoRefCountObjectPtr ret=MEDFileUMesh::New(); - ret->loadUMeshFromFile(fid,ms.front(),dt,it,mrs); - ret->loadJointsFromFile(fid); - return (MEDFileUMesh *)ret.retn(); + ret=MEDFileUMesh::New(); + break; } case CARTESIAN: { - MEDCouplingAutoRefCountObjectPtr ret=MEDFileCMesh::New(); - ret->loadCMeshFromFile(fid,ms.front(),dt,it,mrs); - ret->loadJointsFromFile(fid); - return (MEDFileCMesh *)ret.retn(); + ret=MEDFileCMesh::New(); + break; } case CURVE_LINEAR: { - MEDCouplingAutoRefCountObjectPtr ret=MEDFileCurveLinearMesh::New(); - ret->loadCLMeshFromFile(fid,ms.front(),dt,it,mrs); - ret->loadJointsFromFile(fid); - return (MEDFileCurveLinearMesh *)ret.retn(); + ret=MEDFileCurveLinearMesh::New(); + break; } default: { @@ -115,6 +113,8 @@ MEDFileMesh *MEDFileMesh::New(const std::string& fileName, MEDFileMeshReadSelect throw INTERP_KERNEL::Exception(oss.str().c_str()); } } + ret->loadLLWithAdditionalItems(fid,ms.front(),dt,it,mrs); + return ret.retn(); } /*! @@ -141,29 +141,25 @@ MEDFileMesh *MEDFileMesh::New(const std::string& fileName, const std::string& mN MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); int dummy0,dummy1; std::string dummy2; - MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2); + ParaMEDMEM::MEDCouplingAxisType dummy3; + MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy3,dummy0,dummy1,dummy2); + MEDCouplingAutoRefCountObjectPtr ret; switch(meshType) { case UNSTRUCTURED: { - MEDCouplingAutoRefCountObjectPtr ret=MEDFileUMesh::New(); - ret->loadUMeshFromFile(fid,mName,dt,it,mrs); - ret->loadJointsFromFile(fid,joints); - return (MEDFileUMesh *)ret.retn(); + ret=MEDFileUMesh::New(); + break; } case CARTESIAN: { - MEDCouplingAutoRefCountObjectPtr ret=MEDFileCMesh::New(); - ret->loadCMeshFromFile(fid,mName,dt,it,mrs); - ret->loadJointsFromFile(fid,joints); - return (MEDFileCMesh *)ret.retn(); + ret=MEDFileCMesh::New(); + break; } case CURVE_LINEAR: { - MEDCouplingAutoRefCountObjectPtr ret=MEDFileCurveLinearMesh::New(); - ret->loadCLMeshFromFile(fid,mName,dt,it,mrs); - ret->loadJointsFromFile(fid,joints); - return (MEDFileCurveLinearMesh *)ret.retn(); + ret=MEDFileCurveLinearMesh::New(); + break; } default: { @@ -171,6 +167,8 @@ MEDFileMesh *MEDFileMesh::New(const std::string& fileName, const std::string& mN throw INTERP_KERNEL::Exception(oss.str().c_str()); } } + ret->loadLLWithAdditionalItems(fid,mName,dt,it,mrs); + return ret.retn(); } /*! @@ -187,6 +185,10 @@ void MEDFileMesh::write(med_idt fid) const if(_name.empty()) throw INTERP_KERNEL::Exception("MEDFileMesh : name is empty. MED file ask for a NON EMPTY name !"); writeLL(fid); + writeJoints(fid); + const MEDFileEquivalences *eqs(_equiv); + if(eqs) + eqs->write(fid); } /*! @@ -252,6 +254,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; } @@ -511,6 +515,24 @@ 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; +} + +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. @@ -1983,10 +2005,17 @@ std::vector MEDFileMesh::getAllGeoTypes() con std::vector MEDFileMesh::getDistributionOfTypes(int meshDimRelToMax) const { - MEDCouplingAutoRefCountObjectPtr mLev(getGenMeshAtLevel(meshDimRelToMax)); + MEDCouplingAutoRefCountObjectPtr 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); @@ -2149,7 +2178,8 @@ MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, MEDFileMeshReadSele int dt,it; ParaMEDMEM::MEDCouplingMeshType meshType; std::string dummy2; - MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2); + ParaMEDMEM::MEDCouplingAxisType dummy3; + MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2); return new MEDFileUMesh(fid,ms.front(),dt,it,mrs); } @@ -2220,7 +2250,7 @@ std::vector MEDFileUMesh::getDirectChildrenWithNull() c MEDFileMesh *MEDFileUMesh::shallowCpy() const { - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileUMesh(*this); + MEDCouplingAutoRefCountObjectPtr ret(new MEDFileUMesh(*this)); return ret.retn(); } @@ -2231,7 +2261,8 @@ MEDFileMesh *MEDFileUMesh::createNewEmpty() const MEDFileMesh *MEDFileUMesh::deepCpy() const { - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileUMesh(*this); + MEDCouplingAutoRefCountObjectPtr ret(new MEDFileUMesh(*this)); + ret->deepCpyEquivalences(*this); if((const DataArrayDouble*)_coords) ret->_coords=_coords->deepCpy(); if((const DataArrayInt*)_fam_coords) @@ -2410,9 +2441,8 @@ MEDFileUMesh::MEDFileUMesh() MEDFileUMesh::MEDFileUMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) try { - loadUMeshFromFile(fid,mName,dt,it,mrs); - loadJointsFromFile(fid); - } + loadLLWithAdditionalItems(fid,mName,dt,it,mrs); +} catch(INTERP_KERNEL::Exception& e) { throw e; @@ -2422,7 +2452,7 @@ catch(INTERP_KERNEL::Exception& e) * This method loads only a part of specified cells (given by range of cell ID per geometric type) * See MEDFileUMesh::LoadPartOf for detailed description. * - * \sa loadUMeshFromFile + * \sa loadLL */ void MEDFileUMesh::loadPartUMeshFromFile(med_idt fid, const std::string& mName, const std::vector& types, const std::vector& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs) { @@ -2430,7 +2460,8 @@ void MEDFileUMesh::loadPartUMeshFromFile(med_idt fid, const std::string& mName, ParaMEDMEM::MEDCouplingMeshType meshType; int dummy0,dummy1; std::string dummy2; - int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2)); + ParaMEDMEM::MEDCouplingAxisType dummy3; + int 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 << "' !"; @@ -2470,12 +2501,61 @@ void MEDFileMesh::loadJointsFromFile(med_idt fid, MEDFileJoints* toUseInstedOfRe _joints = MEDFileJoints::New( fid, _name ); } +void MEDFileMesh::loadEquivalences(med_idt fid) +{ + int nbOfEq(MEDFileEquivalences::PresenceOfEquivalences(fid,_name)); + if(nbOfEq>0) + _equiv=MEDFileEquivalences::Load(fid,nbOfEq,this); +} + +void MEDFileMesh::deepCpyEquivalences(const MEDFileMesh& other) +{ + const MEDFileEquivalences *equiv(other._equiv); + if(equiv) + _equiv=equiv->deepCpy(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(getAxType()!=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::GetAxTypeRepr(getAxType()) << ")."; + oss << std::endl << "To perform operation you have two possiblities :" << std::endl; + oss << " - call setAxType(AX_CART)" << std::endl; + oss << " - call cartesianize()"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } +} + /*! * \brief Return number of joints, which is equal to number of adjacent mesh domains */ -int MEDFileMesh::getNumberOfJoints() +int MEDFileMesh::getNumberOfJoints() const { - return ( (MEDFileJoints*) _joints ) ? _joints->getNumberOfJoints() : 0; + return ( (const MEDFileJoints *) _joints ) ? _joints->getNumberOfJoints() : 0; } /*! @@ -2501,13 +2581,15 @@ void MEDFileMesh::setJoints( MEDFileJoints* joints ) * * \sa loadPartUMeshFromFile */ -void MEDFileUMesh::loadUMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) +void MEDFileUMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) { MEDFileUMeshL2 loaderl2; ParaMEDMEM::MEDCouplingMeshType meshType; int dummy0,dummy1; std::string dummy2; - int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2)); + ParaMEDMEM::MEDCouplingAxisType axType; + int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dummy2)); + setAxType(axType); if(meshType!=UNSTRUCTURED) { std::ostringstream oss; oss << "Trying to load as unstructured an existing mesh with name '" << mName << "' !"; @@ -2573,16 +2655,15 @@ void MEDFileUMesh::writeLL(med_idt fid) const MEDLoaderBase::safeStrCpy2(c.c_str(),MED_SNAME_SIZE-1,comp+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo MEDLoaderBase::safeStrCpy2(u.c_str(),MED_SNAME_SIZE-1,unit+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo } - MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MED_CARTESIAN,comp,unit)); - MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa)); + MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxType()),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++) if((const MEDFileUMeshSplitL1 *)(*it)!=0) (*it)->write(fid,meshName,mdim); MEDFileUMeshL2::WriteFamiliesAndGrps(fid,meshName,_families,_groups,_too_long_str); - - writeJoints(fid); } /*! @@ -2942,6 +3023,7 @@ std::string MEDFileUMesh::simpleRepr() const } oss << std::endl << std::endl; getFamilyRepr(oss); + getEquivalencesRepr(oss); return oss.str(); } @@ -3076,6 +3158,29 @@ void MEDFileUMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, con } } +MEDFileMesh *MEDFileUMesh::cartesianize() const +{ + if(getAxType()==AX_CART) + { + incrRef(); + return const_cast(this); + } + else + { + MEDCouplingAutoRefCountObjectPtr ret(new MEDFileUMesh(*this)); + const DataArrayDouble *coords(_coords); + if(!coords) + throw INTERP_KERNEL::Exception("MEDFileUMesh::cartesianize : coordinates are null !"); + MEDCouplingAutoRefCountObjectPtr coordsCart(_coords->cartesianize(getAxType())); + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=ret->_ms.begin();it!=ret->_ms.end();it++) + if((const MEDFileUMeshSplitL1 *)(*it)) + *it=(*it)->shallowCpyUsingCoords(coordsCart); + ret->_coords=coordsCart; + ret->setAxType(AX_CART); + return ret.retn(); + } +} + /*! * Returns the optional numbers of mesh entities of a given dimension transformed using * DataArrayInt::invertArrayN2O2O2N(). @@ -3266,7 +3371,6 @@ 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 { @@ -3287,25 +3391,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)); @@ -3415,6 +3500,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. @@ -3510,6 +3602,8 @@ void MEDFileUMesh::setCoords(DataArrayDouble *coords) { if(!coords) throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoords : null pointer in input !"); + if(coords==(DataArrayDouble *)_coords) + return ; coords->checkAllocated(); int nbOfTuples=coords->getNumberOfTuples(); _coords=coords; @@ -3583,28 +3677,28 @@ void MEDFileUMesh::optimizeFamilies() /** * \b this must be filled at level 0 and -1, typically the -1 level being (part of) the descending connectivity - * of the top level. This method build a "crack" in \b this along the group of level -1 named grpNameM1. - * The "crack" is built according to the following method: - * - all nodes along the crack which are not lying on an internal extremity of the crack are duplicated (so the - * coordinates array is extended). The - * - new (-1)-level cells are built lying on those new nodes. So the edges/faces along the crack are duplicated. - * After this operation a top-level cell bordering the crack will loose some neighbor (typically the cell which is on the - * other side of the crack is no more a neighbor) - * - finally, the connectivity of (part of) the top level-cells bordering the crack is also modified so that some cells - * bordering the crack use the newly computed nodes. + * of the top level. This method build a "crack", or an inner boundary, in \b this along the group of level -1 named grpNameM1. + * The boundary is built according to the following method: + * - all nodes along the boundary which are not lying on an internal extremity of the (-1)-level group are duplicated (so the + * coordinates array is extended). + * - new (-1)-level cells are built lying on those new nodes. So the edges/faces along the group are duplicated. + * 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. * - * \param[in] grpNameM1 name of the (-1)-level group defining the crack + * \param[in] grpNameM1 name of the (-1)-level group defining the boundary * \param[out] nodesDuplicated ids of the initial nodes which have been duplicated (and whose copy is put at the end of * the coord array) * \param[out] cellsModified ids of the cells whose connectivity has been modified (to use the newly created nodes) - * \param[out] cellsNotModified ids of the rest of cells bordering the crack whose connectivity remains unchanged. + * \param[out] cellsNotModified ids of the rest of cells bordering the new boundary whose connectivity remains unchanged. */ -void MEDFileUMesh::duplicateNodesOnM1Group(const std::string& grpNameM1, DataArrayInt *&nodesDuplicated, +void MEDFileUMesh::buildInnerBoundaryAlongM1Group(const std::string& grpNameM1, DataArrayInt *&nodesDuplicated, DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified) { 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 !"); + throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group : This method works only for mesh definied on level 0 and -1 !"); MEDCouplingAutoRefCountObjectPtr m0=getMeshAtLevel(0); MEDCouplingAutoRefCountObjectPtr m1=getMeshAtLevel(-1); int nbNodes=m0->getNumberOfNodes(); @@ -3647,10 +3741,16 @@ void MEDFileUMesh::duplicateNodesOnM1Group(const std::string& grpNameM1, DataArr newm1->setName(getName()); const DataArrayInt *fam=getFamilyFieldAtLevel(-1); if(!fam) - throw INTERP_KERNEL::Exception("MEDFileUMesh::duplicateNodesOnM1Group : internal problem !"); + throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group : internal problem !"); MEDCouplingAutoRefCountObjectPtr 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;i& oldCode, std::vector& newCode 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. @@ -4029,23 +4131,26 @@ MEDFileUMesh *MEDFileUMesh::linearToQuadratic(int conversionType, double eps) co continue; MEDCouplingAutoRefCountObjectPtr m1Tmp(getMeshAtLevel(*lev)); MEDCouplingAutoRefCountObjectPtr m1(dynamic_cast(m1Tmp->deepCpy())); - { - MEDCouplingAutoRefCountObjectPtr notUsed(m1->convertLinearCellsToQuadratic(conversionType)); - } - MEDCouplingAutoRefCountObjectPtr m1Coords(m1->getCoords()->selectByTupleId2(initialNbNodes,m1->getNumberOfNodes(),1)); - DataArrayInt *b(0); - bool a(partZeCoords->areIncludedInMe(m1Coords,eps,b)); - MEDCouplingAutoRefCountObjectPtr bSafe(b); - if(!a) + if(m1->getMeshDimension()!=0) { - std::ostringstream oss; oss << "MEDFileUMesh::linearCellsToQuadratic : for level " << *lev << " problem to identify nodes generated !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); + { + MEDCouplingAutoRefCountObjectPtr notUsed(m1->convertLinearCellsToQuadratic(conversionType)); + }//kill unused notUsed var + MEDCouplingAutoRefCountObjectPtr m1Coords(m1->getCoords()->selectByTupleId2(initialNbNodes,m1->getNumberOfNodes(),1)); + DataArrayInt *b(0); + bool a(partZeCoords->areIncludedInMe(m1Coords,eps,b)); + MEDCouplingAutoRefCountObjectPtr 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); + MEDCouplingAutoRefCountObjectPtr l0(DataArrayInt::New()); l0->alloc(initialNbNodes,1); l0->iota(); + std::vector v(2); v[0]=l0; v[1]=b; + MEDCouplingAutoRefCountObjectPtr renum(DataArrayInt::Aggregate(v)); + m1->renumberNodesInConn(renum->begin()); } - b->applyLin(1,initialNbNodes); - MEDCouplingAutoRefCountObjectPtr l0(DataArrayInt::New()); l0->alloc(initialNbNodes,1); l0->iota(); - std::vector v(2); v[0]=l0; v[1]=b; - MEDCouplingAutoRefCountObjectPtr renum(DataArrayInt::Aggregate(v)); - m1->renumberNodesInConn(renum->begin()); m1->setCoords(zeCoords); ret->setMeshAtLevel(*lev,m1); famField=getFamilyFieldAtLevel(*lev); @@ -4126,21 +4231,22 @@ void MEDFileUMesh::serialize(std::vector& tinyDouble, std::vector& forceComputationOfParts(); tinyDouble.clear(); tinyInt.clear(); tinyStr.clear(); bigArraysI.clear(); bigArrayD=0; std::vector layer0; - layer0.push_back(_order); //0 i - layer0.push_back(_iteration);//1 i - layer0.push_back(getSpaceDimension());//2 i + layer0.push_back(getAxType());//0 i + layer0.push_back(_order); //1 i + layer0.push_back(_iteration);//2 i + layer0.push_back(getSpaceDimension());//3 i tinyDouble.push_back(_time);//0 d tinyStr.push_back(_name);//0 s tinyStr.push_back(_desc_name);//1 s for(int i=0;igetInfoOnComponent(i)); - layer0.push_back((int)_families.size());//3 i <- key info aa layer#0 + 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());//3+aa i <- key info bb layer#0 + 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()); @@ -4148,7 +4254,7 @@ void MEDFileUMesh::serialize(std::vector& tinyDouble, std::vector& for(std::vector::const_iterator it1=((*it0).second).begin();it1!=((*it0).second).end();it1++) tinyStr.push_back(*it1); } - // sizeof(layer0)==3+aa+1+bb layer#0 + // sizeof(layer0)==4+aa+1+bb layer#0 bigArrayD=_coords;// 0 bd bigArraysI.push_back(_fam_coords);// 0 bi bigArraysI.push_back(_num_coords);// 1 bi @@ -4193,6 +4299,7 @@ void MEDFileUMesh::unserialize(std::vector& tinyDouble, std::vector std::reverse(tinyStr.begin(),tinyStr.end()); std::reverse(bigArraysI.begin(),bigArraysI.end()); // + setAxType((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(); @@ -5487,7 +5594,7 @@ void MEDFileStructuredMesh::deepCpyAttributes() * \return MEDCouplingMesh * - a pointer to MEDCouplingMesh that the caller is to * delete using decrRef() as it is no more needed. */ -MEDCouplingMesh *MEDFileStructuredMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const +MEDCouplingMesh *MEDFileStructuredMesh::getMeshAtLevel(int meshDimRelToMax, bool renum) const { if(renum) throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support renumbering ! To do it perform request of renum array directly !"); @@ -5503,9 +5610,9 @@ MEDCouplingMesh *MEDFileStructuredMesh::getGenMeshAtLevel(int meshDimRelToMax, b case -1: { if(!m) - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGenMeshAtLevel : level -1 requested must be non empty to be able to compute unstructured sub mesh !"); + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getMeshAtLevel : level -1 requested must be non empty to be able to compute unstructured sub mesh !"); buildMinusOneImplicitPartIfNeeded(); - MEDCouplingMesh *ret(_faces_if_necessary); + MEDCoupling1SGTUMesh *ret(_faces_if_necessary); if(ret) ret->incrRef(); return ret; @@ -5647,6 +5754,14 @@ std::vector MEDFileStructuredMesh::getGeoType } } +int MEDFileStructuredMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const +{ + if(ct!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension())) + return 0; + else + return getNumberOfCellsAtLevel(0); +} + void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector& nodesFetched) const { if(st.getNumberOfItems()!=1) @@ -5857,7 +5972,8 @@ MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, MEDFileMeshReadSele int dt,it; ParaMEDMEM::MEDCouplingMeshType meshType; std::string dummy2; - MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2); + ParaMEDMEM::MEDCouplingAxisType dummy3; + MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2); return new MEDFileCMesh(fid,ms.front(),dt,it,mrs); } @@ -5938,7 +6054,7 @@ std::string MEDFileCMesh::advancedRepr() const MEDFileMesh *MEDFileCMesh::shallowCpy() const { - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileCMesh(*this); + MEDCouplingAutoRefCountObjectPtr ret(new MEDFileCMesh(*this)); return ret.retn(); } @@ -5949,7 +6065,8 @@ MEDFileMesh *MEDFileCMesh::createNewEmpty() const MEDFileMesh *MEDFileCMesh::deepCpy() const { - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileCMesh(*this); + MEDCouplingAutoRefCountObjectPtr ret(new MEDFileCMesh(*this)); + ret->deepCpyEquivalences(*this); if((const MEDCouplingCMesh*)_cmesh) ret->_cmesh=static_cast(_cmesh->deepCpy()); ret->deepCpyAttributes(); @@ -6010,20 +6127,20 @@ MEDFileCMesh::MEDFileCMesh() MEDFileCMesh::MEDFileCMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) try { - loadCMeshFromFile(fid,mName,dt,it,mrs); - loadJointsFromFile(fid); + loadLLWithAdditionalItems(fid,mName,dt,it,mrs); } catch(INTERP_KERNEL::Exception& e) { throw e; } -void MEDFileCMesh::loadCMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) +void MEDFileCMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) { ParaMEDMEM::MEDCouplingMeshType meshType; int dummy0,dummy1; std::string dtunit; - int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit); + ParaMEDMEM::MEDCouplingAxisType axType; + int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit); if(meshType!=CARTESIAN) { std::ostringstream oss; oss << "Trying to load as cartesian an existing mesh with name '" << mName << "' that is NOT cartesian !"; @@ -6031,6 +6148,7 @@ void MEDFileCMesh::loadCMeshFromFile(med_idt fid, const std::string& mName, int } MEDFileCMeshL2 loaderl2; loaderl2.loadAll(fid,mid,mName,dt,it); + setAxType(loaderl2.getAxType()); MEDCouplingCMesh *mesh=loaderl2.getMesh(); mesh->incrRef(); _cmesh=mesh; @@ -6067,6 +6185,29 @@ void MEDFileCMesh::setMesh(MEDCouplingCMesh *m) _cmesh=m; } +MEDFileMesh *MEDFileCMesh::cartesianize() const +{ + if(getAxType()==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 !"); + MEDCouplingAutoRefCountObjectPtr clmesh(cmesh->buildCurveLinear()); + MEDCouplingAutoRefCountObjectPtr coords(clmesh->getCoords()->cartesianize(getAxType())); + clmesh->setCoords(coords); + MEDCouplingAutoRefCountObjectPtr ret(MEDFileCurveLinearMesh::New()); + ret->MEDFileStructuredMesh::operator=(*this); + ret->setMesh(clmesh); + ret->setAxType(AX_CART); + return ret.retn(); + } +} + void MEDFileCMesh::writeLL(med_idt fid) const { INTERP_KERNEL::AutoPtr maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); @@ -6086,9 +6227,11 @@ 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 } + // MED_CARTESIAN and not MEDFileMeshL2::TraduceAxisTypeRev(getAxType()) ! Yes it is not a bug. The discrimination is done in MEDmeshGridTypeWr. MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,spaceDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit)); - MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa)); - MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MED_CARTESIAN_GRID)); + if(_univ_wr_status) + MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa)); + MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MEDFileMeshL2::TraduceAxisTypeRevStruct(getAxType()))); for(int i=0;igetCoordsAt(i); @@ -6097,8 +6240,6 @@ void MEDFileCMesh::writeLL(med_idt fid) const // std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE)); MEDFileStructuredMesh::writeStructuredLL(fid,meshName); - - writeJoints(fid); } void MEDFileCMesh::synchronizeTinyInfoOnLeaves() const @@ -6129,8 +6270,9 @@ MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); int dt,it; ParaMEDMEM::MEDCouplingMeshType meshType; + ParaMEDMEM::MEDCouplingAxisType dummy3; std::string dummy2; - MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2); + MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2); return new MEDFileCurveLinearMesh(fid,ms.front(),dt,it,mrs); } @@ -6155,7 +6297,7 @@ std::vector MEDFileCurveLinearMesh::getDirectChildrenWi MEDFileMesh *MEDFileCurveLinearMesh::shallowCpy() const { - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileCurveLinearMesh(*this); + MEDCouplingAutoRefCountObjectPtr ret(new MEDFileCurveLinearMesh(*this)); return ret.retn(); } @@ -6166,7 +6308,8 @@ MEDFileMesh *MEDFileCurveLinearMesh::createNewEmpty() const MEDFileMesh *MEDFileCurveLinearMesh::deepCpy() const { - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileCurveLinearMesh(*this); + MEDCouplingAutoRefCountObjectPtr ret(new MEDFileCurveLinearMesh(*this)); + ret->deepCpyEquivalences(*this); if((const MEDCouplingCurveLinearMesh*)_clmesh) ret->_clmesh=static_cast(_clmesh->deepCpy()); ret->deepCpyAttributes(); @@ -6252,6 +6395,31 @@ void MEDFileCurveLinearMesh::setMesh(MEDCouplingCurveLinearMesh *m) _clmesh=m; } +MEDFileMesh *MEDFileCurveLinearMesh::cartesianize() const +{ + if(getAxType()==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 !"); + MEDCouplingAutoRefCountObjectPtr ret(new MEDFileCurveLinearMesh(*this)); + MEDCouplingAutoRefCountObjectPtr mesh2(mesh->clone(false)); + MEDCouplingAutoRefCountObjectPtr coordsCart(coords->cartesianize(getAxType())); + mesh2->setCoords(coordsCart); + ret->setMesh(mesh2); + ret->setAxType(AX_CART); + return ret.retn(); + } +} + const MEDCouplingStructuredMesh *MEDFileCurveLinearMesh::getStructuredMesh() const { synchronizeTinyInfoOnLeaves(); @@ -6265,8 +6433,7 @@ MEDFileCurveLinearMesh::MEDFileCurveLinearMesh() MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) try { - loadCLMeshFromFile(fid,mName,dt,it,mrs); - loadJointsFromFile(fid); + loadLLWithAdditionalItems(fid,mName,dt,it,mrs); } catch(INTERP_KERNEL::Exception& e) { @@ -6296,8 +6463,9 @@ void MEDFileCurveLinearMesh::writeLL(med_idt fid) const MEDLoaderBase::safeStrCpy2(c.c_str(),MED_SNAME_SIZE-1,comp+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo MEDLoaderBase::safeStrCpy2(u.c_str(),MED_SNAME_SIZE-1,unit+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo } - MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit)); - MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa)); + MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxType()),comp,unit)); + if(_univ_wr_status) + MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa)); MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MED_CURVILINEAR_GRID)); std::vector nodeGridSt=_clmesh->getNodeGridStructure(); MEDFILESAFECALLERWR0(MEDmeshGridStructWr,(fid,maa,_iteration,_order,_time,&nodeGridSt[0])); @@ -6306,16 +6474,16 @@ void MEDFileCurveLinearMesh::writeLL(med_idt fid) const // std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE)); MEDFileStructuredMesh::writeStructuredLL(fid,meshName); - - writeJoints(fid); } -void MEDFileCurveLinearMesh::loadCLMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) +void MEDFileCurveLinearMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) { ParaMEDMEM::MEDCouplingMeshType meshType; int dummy0,dummy1; std::string dtunit; - int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit); + ParaMEDMEM::MEDCouplingAxisType axType; + int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit); + setAxType(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 !"; @@ -6396,6 +6564,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) + { + MEDCouplingAutoRefCountObjectPtr ccur(cur->cartesianize());// Attention ! Do not wrap these two lines because memory leak ! + *it=ccur; + } + } +} + MEDFileMesh *MEDFileMeshMultiTS::getOneTimeStep() const { if(_mesh_one_ts.empty()) @@ -6490,7 +6671,8 @@ try int dt,it; ParaMEDMEM::MEDCouplingMeshType meshType; std::string dummy2; - MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2); + ParaMEDMEM::MEDCouplingAxisType dummy3; + MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2); loadFromFile(fileName,ms.front()); } catch(INTERP_KERNEL::Exception& e) @@ -6592,16 +6774,6 @@ std::vector MEDFileMeshes::getMeshesNames() const } return ret; } -/*const MEDFileJoints* MEDFileMeshes::getJoints() const -{ - const MEDFileJoints *ret=_joints; - if(!ret) - { - std::ostringstream oss; oss << "MEDFileMeshes::getJoints : joints is not defined !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return ret; -}*/ bool MEDFileMeshes::changeNames(const std::vector< std::pair >& modifTab) { @@ -6615,6 +6787,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);