X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FMEDLoader%2FMEDFileFieldOverView.cxx;h=5493d88cd6783d7b35ab1d5a17c33fcec0dbd470;hb=84ddd4290c34f47a07b36552679129a7a347444f;hp=469ffa0dc588e383926d15cd0cfe919c621ef3d8;hpb=72a3bd0a15c77074c35ecdb2619fc47b474f8d1e;p=tools%2Fmedcoupling.git diff --git a/src/MEDLoader/MEDFileFieldOverView.cxx b/src/MEDLoader/MEDFileFieldOverView.cxx index 469ffa0dc..5493d88cd 100644 --- a/src/MEDLoader/MEDFileFieldOverView.cxx +++ b/src/MEDLoader/MEDFileFieldOverView.cxx @@ -1,9 +1,9 @@ -// Copyright (C) 2007-2013 CEA/DEN, EDF R&D +// Copyright (C) 2007-2014 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either -// version 2.1 of the License. +// version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -27,7 +27,9 @@ using namespace ParaMEDMEM; const unsigned char MEDMeshMultiLev::PARAMEDMEM_2_VTKTYPE[MEDMeshMultiLev::PARAMEDMEM_2_VTKTYPE_LGTH]= - {1,3,21,5,9,7,22,34,23,28,-1,-1,-1,-1,10,14,13,-1,12,-1,24,-1,16,27,-1,26,-1,29,-1,-1,25,42,-1,4}; + {1,3,21,5,9,7,22,34,23,28,255,255,255,255,10,14,13,255,12,255,24,255,16,27,255,26,255,29,255,255,25,42,36,4}; + +const unsigned char MEDMeshMultiLev::HEXA27_PERM_ARRAY[27]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,24,22,21,23,20,25,26}; const char MEDFileField1TSStructItem2::NEWLY_CREATED_PFL_NAME[]="???"; @@ -36,7 +38,7 @@ MEDFileMeshStruct *MEDFileMeshStruct::New(const MEDFileMesh *mesh) return new MEDFileMeshStruct(mesh); } -std::size_t MEDFileMeshStruct::getHeapMemorySize() const +std::size_t MEDFileMeshStruct::getHeapMemorySizeWithoutChildren() const { std::size_t ret(0); for(std::vector< std::vector >::const_iterator it0=_geo_types_distrib.begin();it0!=_geo_types_distrib.end();it0++) @@ -45,17 +47,25 @@ std::size_t MEDFileMeshStruct::getHeapMemorySize() const return ret; } +std::vector MEDFileMeshStruct::getDirectChildren() const +{ + return std::vector(); +} + MEDFileMeshStruct::MEDFileMeshStruct(const MEDFileMesh *mesh):_mesh(mesh) { - std::vector levs=mesh->getNonEmptyLevels(); + std::vector levs(mesh->getNonEmptyLevels()); _name=mesh->getName(); _nb_nodes=mesh->getNumberOfNodes(); - _geo_types_distrib.resize(levs.size()); - for(std::vector::const_iterator lev=levs.begin();lev!=levs.end();lev++) - _geo_types_distrib[-(*lev)]=mesh->getDistributionOfTypes(*lev); + if(!levs.empty()) + { + _geo_types_distrib.resize(-(*std::min_element(levs.begin(),levs.end()))+1); + for(std::vector::const_iterator lev=levs.begin();lev!=levs.end();lev++) + _geo_types_distrib[-(*lev)]=mesh->getDistributionOfTypes(*lev); + } } -int MEDFileMeshStruct::getLevelOfGeoType(INTERP_KERNEL::NormalizedCellType t) const throw(INTERP_KERNEL::Exception) +int MEDFileMeshStruct::getLevelOfGeoType(INTERP_KERNEL::NormalizedCellType t) const { int j=0; for(std::vector< std::vector >::const_iterator it1=_geo_types_distrib.begin();it1!=_geo_types_distrib.end();it1++,j--) @@ -71,7 +81,10 @@ int MEDFileMeshStruct::getLevelOfGeoType(INTERP_KERNEL::NormalizedCellType t) co throw INTERP_KERNEL::Exception("MEDFileMeshStruct::getLevelOfGeoType : The specified geometric type is not present in the mesh structure !"); } -int MEDFileMeshStruct::getNumberOfElemsOfGeoType(INTERP_KERNEL::NormalizedCellType t) const throw(INTERP_KERNEL::Exception) +/*! + * \sa MEDFileMeshStruct::doesManageGeoType + */ +int MEDFileMeshStruct::getNumberOfElemsOfGeoType(INTERP_KERNEL::NormalizedCellType t) const { for(std::vector< std::vector >::const_iterator it1=_geo_types_distrib.begin();it1!=_geo_types_distrib.end();it1++) { @@ -86,15 +99,51 @@ int MEDFileMeshStruct::getNumberOfElemsOfGeoType(INTERP_KERNEL::NormalizedCellTy throw INTERP_KERNEL::Exception("The specified geometric type is not present in the mesh structure !"); } +/*! + * \sa MEDFileMeshStruct::getNumberOfElemsOfGeoType + */ +bool MEDFileMeshStruct::doesManageGeoType(INTERP_KERNEL::NormalizedCellType t) const +{ + for(std::vector< std::vector >::const_iterator it1=_geo_types_distrib.begin();it1!=_geo_types_distrib.end();it1++) + { + std::size_t sz=(*it1).size(); + if(sz%3!=0) + throw INTERP_KERNEL::Exception("MEDFileMeshStruct::doesManageGeoType : internal error in code !"); + std::size_t nbGeo=sz/3; + for(std::size_t i=0;ihasImplicitPart()) + throw INTERP_KERNEL::Exception("MEDFileMeshStruct::appendIfImplicitType : by default no implicit geo type can be appended !"); + static const char MSG[]="MEDFileMeshStruct::appendIfImplicitType : the distribution does not looks like structured standard !"; + if(_geo_types_distrib.size()!=1) + throw INTERP_KERNEL::Exception(MSG); + std::size_t sz(_geo_types_distrib[0].size()); + if(sz%3!=0) + throw INTERP_KERNEL::Exception("MEDFileMeshStruct::appendIfImplicitType : internal error in code !"); + std::size_t nbGeo(sz/3); + if(nbGeo!=1) + throw INTERP_KERNEL::Exception(MSG); + std::vector arr(3); arr[0]=(int)t; arr[1]=_mesh->buildImplicitPartIfAny(t); arr[2]=-1; + _geo_types_distrib.push_back(arr); +} + + int MEDFileMeshStruct::getNumberOfLevs() const { return (int)_geo_types_distrib.size(); } -int MEDFileMeshStruct::getNumberOfGeoTypesInLev(int relativeLev) const throw(INTERP_KERNEL::Exception) +int MEDFileMeshStruct::getNumberOfGeoTypesInLev(int relativeLev) const { int pos(-relativeLev); - if(pos<0 || pos>=_geo_types_distrib.size()) + if(pos<0 || pos>=(int)_geo_types_distrib.size()) throw INTERP_KERNEL::Exception("MEDFileMeshStruct::getNumberOfGeoTypesInLev : invalid level specified !"); std::size_t sz=_geo_types_distrib[pos].size(); if(sz%3!=0) @@ -104,12 +153,17 @@ int MEDFileMeshStruct::getNumberOfGeoTypesInLev(int relativeLev) const throw(INT //= -std::size_t MEDMeshMultiLev::getHeapMemorySize() const +std::size_t MEDMeshMultiLev::getHeapMemorySizeWithoutChildren() const { return 0; } -MEDMeshMultiLev *MEDMeshMultiLev::New(const MEDFileMesh *m, const std::vector& levs) throw(INTERP_KERNEL::Exception) +std::vector MEDMeshMultiLev::getDirectChildren() const +{ + return std::vector(); +} + +MEDMeshMultiLev *MEDMeshMultiLev::New(const MEDFileMesh *m, const std::vector& levs) { if(!m) throw INTERP_KERNEL::Exception("MEDMeshMultiLev::New : null input pointer !"); @@ -125,7 +179,7 @@ MEDMeshMultiLev *MEDMeshMultiLev::New(const MEDFileMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities) throw(INTERP_KERNEL::Exception) +MEDMeshMultiLev *MEDMeshMultiLev::New(const MEDFileMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities) { if(!m) throw INTERP_KERNEL::Exception("MEDMeshMultiLev::New 2 : null input pointer !"); @@ -141,10 +195,9 @@ MEDMeshMultiLev *MEDMeshMultiLev::New(const MEDFileMesh *m, const std::vector levs(1,0); - MEDCouplingAutoRefCountObjectPtr ret(MEDMeshMultiLev::New(m,levs)); + MEDCouplingAutoRefCountObjectPtr ret(MEDMeshMultiLev::New(m,m->getNonEmptyLevels())); ret->selectPartOfNodes(pflOnNode); return ret.retn(); } @@ -156,7 +209,7 @@ void MEDMeshMultiLev::setNodeReduction(const DataArrayInt *nr) _node_reduction=const_cast(nr); } -bool MEDMeshMultiLev::isFastlyTheSameStruct(const MEDFileField1TSStructItem& fst, const MEDFileFieldGlobsReal *globs) const throw(INTERP_KERNEL::Exception) +bool MEDMeshMultiLev::isFastlyTheSameStruct(const MEDFileField1TSStructItem& fst, const MEDFileFieldGlobsReal *globs) const { if(fst.getType()==ON_NODES) { @@ -167,6 +220,8 @@ bool MEDMeshMultiLev::isFastlyTheSameStruct(const MEDFileField1TSStructItem& fst const DataArrayInt *nr(_node_reduction); if(pflName.empty() && !nr) return true; + if(!pflName.empty() && !nr) + return false; if(pflName==nr->getName()) return true; return false; @@ -187,7 +242,7 @@ bool MEDMeshMultiLev::isFastlyTheSameStruct(const MEDFileField1TSStructItem& fst } } -DataArray *MEDMeshMultiLev::buildDataArray(const MEDFileField1TSStructItem& fst, const MEDFileFieldGlobsReal *globs, const DataArray *vals) const throw(INTERP_KERNEL::Exception) +DataArray *MEDMeshMultiLev::buildDataArray(const MEDFileField1TSStructItem& fst, const MEDFileFieldGlobsReal *globs, const DataArray *vals) const { MEDCouplingAutoRefCountObjectPtr ret(const_cast(vals)); ret->incrRef(); if(isFastlyTheSameStruct(fst,globs)) @@ -196,10 +251,177 @@ DataArray *MEDMeshMultiLev::buildDataArray(const MEDFileField1TSStructItem& fst, return constructDataArray(fst,globs,vals); } +/*! + * \param [out] famIds - Can be null. If not null the instance has to be dealt by the caller (decrRef). + * \param [out] isWithoutCopy - When true the returned instance \a famIds if not null is directly those in the data structure. + */ +void MEDMeshMultiLev::retrieveFamilyIdsOnCells(DataArrayInt *& famIds, bool& isWithoutCopy) const +{ + const DataArrayInt *fids(_cell_fam_ids); + if(!fids) + { famIds=0; isWithoutCopy=true; return ; } + std::size_t sz(_geo_types.size()); + bool presenceOfPfls(false); + for(std::size_t i=0;i(fids); famIds->incrRef(); isWithoutCopy=_cell_fam_ids_nocpy; return ; } + //bad luck the slowest part + isWithoutCopy=false; + std::vector< MEDCouplingAutoRefCountObjectPtr > retSafe(sz); + std::vector< const DataArrayInt *> ret(sz); + int start(0); + for(std::size_t i=0;i tmp(fids->selectByTupleId2(start,start+lgth,1)); + retSafe[i]=tmp->selectByTupleIdSafe(pfl->begin(),pfl->end()); + } + else + { + retSafe[i]=fids->selectByTupleId2(start,start+lgth,1); + } + ret[i]=retSafe[i]; + start+=lgth; + } + famIds=DataArrayInt::Aggregate(ret); +} + +/*! + * \param [out] numIds - Can be null. If not null the instance has to be dealt by the caller (decrRef). + * \param [out] isWithoutCopy - When true the returned instance \a numIds if not null is directly those in the data structure. + */ +void MEDMeshMultiLev::retrieveNumberIdsOnCells(DataArrayInt *& numIds, bool& isWithoutCopy) const +{ + const DataArrayInt *nids(_cell_num_ids); + if(!nids) + { numIds=0; isWithoutCopy=true; return ; } + std::size_t sz(_geo_types.size()); + bool presenceOfPfls(false); + for(std::size_t i=0;i(nids); numIds->incrRef(); isWithoutCopy=_cell_num_ids_nocpy; return ; } + //bad luck the slowest part + isWithoutCopy=false; + std::vector< MEDCouplingAutoRefCountObjectPtr > retSafe(sz); + std::vector< const DataArrayInt *> ret(sz); + int start(0); + for(std::size_t i=0;i tmp(nids->selectByTupleId2(start,start+lgth,1)); + retSafe[i]=tmp->selectByTupleIdSafe(pfl->begin(),pfl->end()); + } + else + { + retSafe[i]=nids->selectByTupleId2(start,start+lgth,1); + } + ret[i]=retSafe[i]; + start+=lgth; + } + numIds=DataArrayInt::Aggregate(ret); +} + +/*! + * \param [out] famIds - Can be null. If not null the instance has to be dealt by the caller (decrRef). + * \param [out] isWithoutCopy - When true the returned instance \a famIds if not null is directly those in the data structure. + */ +void MEDMeshMultiLev::retrieveFamilyIdsOnNodes(DataArrayInt *& famIds, bool& isWithoutCopy) const +{ + const DataArrayInt *fids(_node_fam_ids); + if(!fids) + { famIds=0; isWithoutCopy=true; return ; } + const DataArrayInt *nr(_node_reduction); + if(nr) + { + isWithoutCopy=false; + famIds=fids->selectByTupleIdSafe(nr->begin(),nr->end()); + } + else + { + isWithoutCopy=_node_fam_ids_nocpy; + famIds=const_cast(fids); famIds->incrRef(); + } +} + +/*! + * \param [out] numIds - Can be null. If not null the instance has to be dealt by the caller (decrRef). + * \param [out] isWithoutCopy - When true the returned instance \a numIds if not null is directly those in the data structure. + */ +void MEDMeshMultiLev::retrieveNumberIdsOnNodes(DataArrayInt *& numIds, bool& isWithoutCopy) const +{ + const DataArrayInt *fids(_node_num_ids); + if(!fids) + { numIds=0; isWithoutCopy=true; return ; } + const DataArrayInt *nr(_node_reduction); + if(nr) + { + isWithoutCopy=false; + numIds=fids->selectByTupleIdSafe(nr->begin(),nr->end()); + } + else + { + isWithoutCopy=_node_num_ids_nocpy; + numIds=const_cast(fids); numIds->incrRef(); + } +} + +std::vector< INTERP_KERNEL::NormalizedCellType > MEDMeshMultiLev::getGeoTypes() const +{ + return _geo_types; +} + +void MEDMeshMultiLev::setFamilyIdsOnCells(DataArrayInt *famIds, bool isNoCopy) +{ + _cell_fam_ids=famIds; + if(famIds) + famIds->incrRef(); + _cell_fam_ids_nocpy=isNoCopy; +} + +void MEDMeshMultiLev::setNumberIdsOnCells(DataArrayInt *numIds, bool isNoCopy) +{ + _cell_num_ids=numIds; + if(numIds) + numIds->incrRef(); + _cell_num_ids_nocpy=isNoCopy; +} + +void MEDMeshMultiLev::setFamilyIdsOnNodes(DataArrayInt *famIds, bool isNoCopy) +{ + _node_fam_ids=famIds; + if(famIds) + famIds->incrRef(); + _node_fam_ids_nocpy=isNoCopy; +} + +void MEDMeshMultiLev::setNumberIdsOnNodes(DataArrayInt *numIds, bool isNoCopy) +{ + _node_num_ids=numIds; + if(numIds) + numIds->incrRef(); + _node_num_ids_nocpy=isNoCopy; +} + std::string MEDMeshMultiLev::getPflNameOfId(int id) const { std::size_t sz(_pfls.size()); - if(id<0 || id>=sz) + if(id<0 || id>=(int)sz) throw INTERP_KERNEL::Exception("MEDMeshMultiLev::getPflNameOfId : invalid input id !"); const DataArrayInt *pfl(_pfls[id]); if(!pfl) @@ -207,29 +429,25 @@ std::string MEDMeshMultiLev::getPflNameOfId(int id) const return pfl->getName(); } -int MEDMeshMultiLev::getNumberOfCells(INTERP_KERNEL::NormalizedCellType t) const throw(INTERP_KERNEL::Exception) +/*! + * Returns the number of cells having geometric type \a t. + * The profiles are **NOT** taken into account here. + */ +int MEDMeshMultiLev::getNumberOfCells(INTERP_KERNEL::NormalizedCellType t) const { std::size_t sz(_nb_entities.size()); for(std::size_t i=0;igetNumberOfTuples(); - } - } + if(_geo_types[i]==t) + return _nb_entities[i]; throw INTERP_KERNEL::Exception("MEDMeshMultiLev::getNumberOfCells : not existing geometric type in this !"); } -int MEDMeshMultiLev::getNumberOfNodes() const throw(INTERP_KERNEL::Exception) +int MEDMeshMultiLev::getNumberOfNodes() const { return _nb_nodes; } -DataArray *MEDMeshMultiLev::constructDataArray(const MEDFileField1TSStructItem& fst, const MEDFileFieldGlobsReal *globs, const DataArray *vals) const throw(INTERP_KERNEL::Exception) +DataArray *MEDMeshMultiLev::constructDataArray(const MEDFileField1TSStructItem& fst, const MEDFileFieldGlobsReal *globs, const DataArray *vals) const { if(fst.getType()==ON_NODES) { @@ -248,7 +466,7 @@ DataArray *MEDMeshMultiLev::constructDataArray(const MEDFileField1TSStructItem& MEDCouplingAutoRefCountObjectPtr p2(nr->deepCpy()); p1->sort(true); p2->sort(true); if(!p1->isEqualWithoutConsideringStr(*p2)) - throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for nodes 3 !"); + throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : it appears that a profile on nodes does not cover the cells correctly !"); p1=DataArrayInt::FindPermutationFromFirstToSecond(globs->getProfile(pflName.c_str()),nr); MEDCouplingAutoRefCountObjectPtr ret(vals->deepCpy()); ret->renumberInPlace(p1->begin()); @@ -269,70 +487,163 @@ DataArray *MEDMeshMultiLev::constructDataArray(const MEDFileField1TSStructItem& else { std::size_t sz(fst.getNumberOfItems()); - std::vector< MEDCouplingAutoRefCountObjectPtr > arrSafe(sz); - std::vector< const DataArray *> arr(sz); - for(std::size_t i=0;i s(_geo_types.begin(),_geo_types.end()); + if(s.size()!=_geo_types.size()) + throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for cells 2 !"); + std::vector< const DataArray *> arr(s.size()); + std::vector< MEDCouplingAutoRefCountObjectPtr > arrSafe(s.size()); + int iii(0); + int nc(vals->getNumberOfComponents()); + std::vector compInfo(vals->getInfoOnComponents()); + for(std::vector< INTERP_KERNEL::NormalizedCellType >::const_iterator it=_geo_types.begin();it!=_geo_types.end();it++,iii++) { - const MEDFileField1TSStructItem2& p(fst[i]); - const std::pair& strtStop(p.getStartStop()); - std::vector< INTERP_KERNEL::NormalizedCellType >::const_iterator it(std::find(_geo_types.begin(),_geo_types.end(),p.getGeo())); - if(it==_geo_types.end()) - throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for cells 1 !"); - if(std::find(it+1,_geo_types.end(),p.getGeo())!=_geo_types.end()) - throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for cells 2 !"); - std::size_t pos(std::distance(_geo_types.begin(),it)); - const DataArrayInt *thisP(_pfls[pos]),*otherP(p.getPfl(globs)); - MEDCouplingAutoRefCountObjectPtr ret(vals->selectByTupleId2(strtStop.first,strtStop.second,1)); - std::vector compInfo(vals->getInfoOnComponents()); - if(!thisP && !otherP) - { - arrSafe[i]=ret; arr[i]=ret; - continue; - } - int nbi(p.getNbOfIntegrationPts(globs)),nc(ret->getNumberOfComponents()); - if(!thisP && otherP) + const DataArrayInt *thisP(_pfls[iii]); + std::vector ps; + for(std::size_t i=0;i p1(otherP->deepCpy()); - p1->sort(true); - p1->checkAllIdsInRange(0,getNumberOfCells(p.getGeo())); - p1=DataArrayInt::FindPermutationFromFirstToSecond(otherP,p1); - ret->rearrange(nbi*nc); ret->renumberInPlace(p1->begin()); ret->rearrange(nc); ret->setInfoOnComponents(compInfo); - arrSafe[i]=ret; arr[i]=ret; - continue; + const MEDFileField1TSStructItem2& p(fst[i]); + if(p.getGeo()==*it) + ps.push_back(&p); } - if(thisP && otherP) + if(ps.empty()) + throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for cells 1 !"); + if(ps.size()==1) { - MEDCouplingAutoRefCountObjectPtr p1(otherP->deepCpy()); - MEDCouplingAutoRefCountObjectPtr p2(thisP->deepCpy()); - p1->sort(true); p2->sort(true); - if(!p1->isEqualWithoutConsideringStr(*p2)) - throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for cells 4 !"); - p1=DataArrayInt::FindPermutationFromFirstToSecond(otherP,thisP); - ret->rearrange(nbi*nc); ret->renumberInPlace(p1->begin()); ret->rearrange(nc); ret->setInfoOnComponents(compInfo); - arrSafe[i]=ret; arr[i]=ret; - continue; + int nbi(ps[0]->getNbOfIntegrationPts(globs)); + const DataArrayInt *otherP(ps[0]->getPfl(globs)); + const std::pair& strtStop(ps[0]->getStartStop()); + MEDCouplingAutoRefCountObjectPtr ret(vals->selectByTupleId2(strtStop.first,strtStop.second,1)); + if(!thisP && !otherP) + { + arrSafe[iii]=ret; arr[iii]=ret; + continue; + } + if(thisP && otherP) + { + MEDCouplingAutoRefCountObjectPtr p1(otherP->invertArrayN2O2O2N(getNumberOfCells(ps[0]->getGeo()))); + MEDCouplingAutoRefCountObjectPtr p2(thisP->deepCpy()); + p2->transformWithIndArr(p1->begin(),p1->end()); + //p1=p2->getIdsNotEqual(-1); + //p1=p2->selectByTupleIdSafe(p1->begin(),p1->end()); + ret->rearrange(nbi*nc); ret=ret->selectByTupleIdSafe(p2->begin(),p2->end()); ret->rearrange(nc); ret->setInfoOnComponents(compInfo); + arrSafe[iii]=ret; arr[iii]=ret; + continue; + } + if(!thisP && otherP) + { + MEDCouplingAutoRefCountObjectPtr p1(otherP->deepCpy()); + p1->sort(true); + p1->checkAllIdsInRange(0,getNumberOfCells(ps[0]->getGeo())); + p1=DataArrayInt::FindPermutationFromFirstToSecond(otherP,p1); + ret->rearrange(nbi*nc); ret->renumberInPlace(p1->begin()); ret->rearrange(nc); ret->setInfoOnComponents(compInfo); + arrSafe[iii]=ret; arr[iii]=ret; + continue; + } + throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for cells 3 !"); } - if(thisP && !otherP) + else { - MEDCouplingAutoRefCountObjectPtr p1(thisP->deepCpy()); - p1->sort(true); - if(!p1->isIdentity() || p1->getNumberOfTuples()!=p.getNbEntity()) - throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for cells 3 !"); - ret->rearrange(nbi*nc); ret->renumberInPlaceR(otherP->begin()); ret->rearrange(nc); ret->setInfoOnComponents(compInfo); - arrSafe[i]=ret; arr[i]=ret; + std::vector< const DataArrayInt * >otherPS(ps.size()); + std::vector< const DataArray * > arr2(ps.size()); + std::vector< MEDCouplingAutoRefCountObjectPtr > arr2Safe(ps.size()); + std::vector< const DataArrayInt * > nbis(ps.size()); + std::vector< MEDCouplingAutoRefCountObjectPtr > nbisSafe(ps.size()); + int jj(0); + for(std::vector::const_iterator it2=ps.begin();it2!=ps.end();it2++,jj++) + { + int nbi((*it2)->getNbOfIntegrationPts(globs)); + const DataArrayInt *otherPfl((*it2)->getPfl(globs)); + const std::pair& strtStop((*it2)->getStartStop()); + MEDCouplingAutoRefCountObjectPtr ret2(vals->selectByTupleId2(strtStop.first,strtStop.second,1)); + if(!otherPfl) + throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for cells 4 !"); + arr2[jj]=ret2; arr2Safe[jj]=ret2; otherPS[jj]=otherPfl; + nbisSafe[jj]=DataArrayInt::New(); nbisSafe[jj]->alloc(otherPfl->getNumberOfTuples(),1); nbisSafe[jj]->fillWithValue(nbi); + nbis[jj]=nbisSafe[jj]; + } + MEDCouplingAutoRefCountObjectPtr arr3(DataArray::Aggregate(arr2)); + MEDCouplingAutoRefCountObjectPtr otherP(DataArrayInt::Aggregate(otherPS)); + MEDCouplingAutoRefCountObjectPtr zenbis(DataArrayInt::Aggregate(nbis)); + MEDCouplingAutoRefCountObjectPtr otherPN(otherP->invertArrayN2O2O2N(getNumberOfCells(*it))); + MEDCouplingAutoRefCountObjectPtr p1; + if(thisP) + p1=DataArrayInt::FindPermutationFromFirstToSecond(otherP,thisP); + else + p1=otherP->deepCpy(); + MEDCouplingAutoRefCountObjectPtr zenbisN(zenbis->renumber(p1->begin())); + zenbisN->computeOffsets2(); + jj=0; + for(std::vector::const_iterator it2=ps.begin();it2!=ps.end();it2++,jj++) + { + //int nbi((*it2)->getNbOfIntegrationPts(globs)); + const DataArrayInt *otherPfl((*it2)->getPfl(globs)); + const std::pair& strtStop((*it2)->getStartStop()); + MEDCouplingAutoRefCountObjectPtr ret2(vals->selectByTupleId2(strtStop.first,strtStop.second,1)); + // + MEDCouplingAutoRefCountObjectPtr p2(otherPfl->deepCpy()); + p2->transformWithIndArr(otherPN->begin(),otherPN->end()); + p2->transformWithIndArr(p1->begin(),p1->end()); + MEDCouplingAutoRefCountObjectPtr idsN(p2->buildExplicitArrByRanges(zenbisN)); + arr3->setPartOfValuesBase3(ret2,idsN->begin(),idsN->end(),0,nc,1); + } + arrSafe[iii]=arr3; arr[iii]=arr3; continue; } - throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for cells 6 !"); } return DataArray::Aggregate(arr); } } -MEDMeshMultiLev::MEDMeshMultiLev() +/*! + * This method is called to add NORM_POINT1 cells in \a this so that orphan nodes in \a verticesToAdd will be fetched. + */ +void MEDMeshMultiLev::appendVertices(const DataArrayInt *verticesToAdd, DataArrayInt *nr) { + int nbOfVertices(verticesToAdd->getNumberOfTuples()); + std::size_t sz(_pfls.size()); + _pfls.resize(sz+1); + _geo_types.resize(sz+1,INTERP_KERNEL::NORM_POINT1); + _nb_entities.resize(sz+1,nbOfVertices); + _node_reduction=nr; nr->incrRef(); + _nb_nodes+=nbOfVertices; + const DataArrayInt *cf(_cell_fam_ids),*cn(_cell_num_ids),*nf(_node_fam_ids),*nn(_node_num_ids); + if(cf) + { + MEDCouplingAutoRefCountObjectPtr tmp; + std::vector a(2); + a[0]=cf; + if(nf) + tmp=nf->selectByTupleIdSafe(verticesToAdd->begin(),verticesToAdd->end()); + else + { + tmp=DataArrayInt::New(); tmp->alloc(nbOfVertices,1); tmp->fillWithZero(); + } + a[1]=tmp; + _cell_fam_ids=DataArrayInt::Aggregate(a); + _cell_fam_ids_nocpy=false; + } + if(cn) + { + MEDCouplingAutoRefCountObjectPtr tmp; + std::vector a(2); + a[0]=cn; + if(nn) + tmp=nn->selectByTupleIdSafe(verticesToAdd->begin(),verticesToAdd->end()); + else + { + tmp=DataArrayInt::New(); tmp->alloc(nbOfVertices,1); tmp->fillWithZero(); + } + a[1]=tmp; + _cell_num_ids=DataArrayInt::Aggregate(a); + _cell_num_ids_nocpy=false; + } } -MEDMeshMultiLev::MEDMeshMultiLev(int nbNodes, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities):_geo_types(gts),_nb_entities(nbEntities),_nb_nodes(nbNodes) +MEDMeshMultiLev::MEDMeshMultiLev(const MEDFileMesh *mesh):_mesh(mesh),_nb_nodes(0),_cell_fam_ids_nocpy(false) +{ +} + +MEDMeshMultiLev::MEDMeshMultiLev(const MEDFileMesh *mesh, int nbNodes, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities):_mesh(mesh),_geo_types(gts),_nb_entities(nbEntities),_nb_nodes(nbNodes),_cell_fam_ids_nocpy(false),_cell_num_ids_nocpy(false),_node_fam_ids_nocpy(false),_node_num_ids_nocpy(false) { std::size_t sz(_geo_types.size()); if(sz!=pfls.size() || sz!=nbEntities.size()) @@ -346,18 +657,18 @@ MEDMeshMultiLev::MEDMeshMultiLev(int nbNodes, const std::vector& levs) throw(INTERP_KERNEL::Exception) +MEDUMeshMultiLev *MEDUMeshMultiLev::New(const MEDFileUMesh *m, const std::vector& levs) { return new MEDUMeshMultiLev(m,levs); } -MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDFileUMesh *m, const std::vector& levs) +MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDFileUMesh *m, const std::vector& levs):MEDMeshMultiLev(m) { if(!m) throw INTERP_KERNEL::Exception("MEDUMeshMultiLev constructor : null input pointer !"); @@ -368,9 +679,14 @@ MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDFileUMesh *m, const std::vector v.insert(v.end(),vTmp.begin(),vTmp.end()); } std::size_t sz(v.size()); + if(v.empty()) + { + _coords=m->getCoords(); _coords->incrRef(); + } _parts.resize(sz); _pfls.resize(sz); _geo_types.resize(sz); + _nb_entities.resize(sz); for(std::size_t i=0;i throw INTERP_KERNEL::Exception("MEDUMeshMultiLev constructor : presence of a null pointer !"); _parts[i]=obj; _geo_types[i]=obj->getCellModelEnum(); + _nb_entities[i]=obj->getNumberOfCells(); + } + // ids fields management + _cell_fam_ids_nocpy=(levs.size()==1); + if(_cell_fam_ids_nocpy) + { + const DataArrayInt *tmp(m->getFamilyFieldAtLevel(levs[0])); + if(tmp) + { + tmp->incrRef(); + _cell_fam_ids=(const_cast(tmp)); + } + } + else + { + std::vector tmps(levs.size()); + bool f(true); + for(std::size_t i=0;igetFamilyFieldAtLevel(levs[i]); + if(!tmps[i]) + f=false; + } + if(f && !tmps.empty()) + _cell_fam_ids=DataArrayInt::Aggregate(tmps); + } + _cell_num_ids_nocpy=(levs.size()==1); + if(_cell_num_ids_nocpy) + { + const DataArrayInt *tmp(m->getNumberFieldAtLevel(levs[0])); + if(tmp) + { + tmp->incrRef(); + _cell_num_ids=(const_cast(tmp)); + } } + else + { + std::vector tmps(levs.size()); + bool n(true); + for(std::size_t i=0;igetNumberFieldAtLevel(levs[i]); + if(!tmps[i]) + n=false; + } + if(n && !tmps.empty()) + _cell_num_ids=DataArrayInt::Aggregate(tmps); + } + // node part + _node_fam_ids_nocpy=true; + { + const DataArrayInt *tmp(m->getFamilyFieldAtLevel(1)); + if(tmp) + { + tmp->incrRef(); + _node_fam_ids=(const_cast(tmp)); + } + } + _node_num_ids_nocpy=true; + { + const DataArrayInt *tmp(m->getNumberFieldAtLevel(1)); + if(tmp) + { + tmp->incrRef(); + _node_num_ids=(const_cast(tmp)); + } + } } -MEDUMeshMultiLev *MEDUMeshMultiLev::New(const MEDFileUMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities) throw(INTERP_KERNEL::Exception) +MEDUMeshMultiLev *MEDUMeshMultiLev::New(const MEDFileUMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities) { return new MEDUMeshMultiLev(m,gts,pfls,nbEntities); } -MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDFileUMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities):MEDMeshMultiLev(m->getNumberOfNodes(),gts,pfls,nbEntities) +MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDFileUMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities):MEDMeshMultiLev(m,m->getNumberOfNodes(),gts,pfls,nbEntities) { std::size_t sz(gts.size()); + if(sz<1) + throw INTERP_KERNEL::Exception("constructor of MEDUMeshMultiLev : number of different geo type must be >= 1 !"); + unsigned dim(INTERP_KERNEL::CellModel::GetCellModel(gts[0]).getDimension()); _parts.resize(sz); + bool isSameDim(true),isNoPfl(true); for(std::size_t i=0;igetDirectUndergroundSingleGeoTypeMesh(gts[i])); + if(INTERP_KERNEL::CellModel::GetCellModel(gts[i]).getDimension()!=dim) + isSameDim=false; + if(pfls[i]) + isNoPfl=false; if(elt) elt->incrRef(); _parts[i]=elt; } + // ids fields management + int lev((int)dim-m->getMeshDimension()); + if(isSameDim && isNoPfl && m->getGeoTypesAtLevel(lev)==gts)//optimized part + { + _cell_fam_ids_nocpy=true; + const DataArrayInt *famIds(m->getFamilyFieldAtLevel(lev)); + if(famIds) + { _cell_fam_ids=const_cast(famIds); famIds->incrRef(); } + _cell_num_ids_nocpy=true; + const DataArrayInt *numIds(m->getNumberFieldAtLevel(lev)); + if(numIds) + { _cell_num_ids=const_cast(numIds); numIds->incrRef(); } + _node_fam_ids_nocpy=true; + famIds=m->getFamilyFieldAtLevel(1); + if(famIds) + { _node_fam_ids=const_cast(famIds); famIds->incrRef(); } + _node_num_ids_nocpy=true; + numIds=m->getNumberFieldAtLevel(1); + if(numIds) + { _node_num_ids=const_cast(numIds); numIds->incrRef(); } + return ; + } + // + _cell_fam_ids_nocpy=false; + std::vector< MEDCouplingAutoRefCountObjectPtr > famIdsSafe(sz); + std::vector famIds(sz); + bool f(true); + for(std::size_t i=0;iextractFamilyFieldOnGeoType(gts[i]); + famIds[i]=famIdsSafe[i]; + if(!famIds[i]) + f=false; + } + if(f) + _cell_fam_ids=DataArrayInt::Aggregate(famIds); + _cell_num_ids_nocpy=false; + std::vector< MEDCouplingAutoRefCountObjectPtr > numIdsSafe(sz); + std::vector numIds(sz); + bool n(true); + for(std::size_t i=0;iextractNumberFieldOnGeoType(gts[i]); + numIds[i]=numIdsSafe[i]; + if(!numIds[i]) + n=false; + } + if(n) + _cell_num_ids=DataArrayInt::Aggregate(numIds); + // node ids management + _node_fam_ids_nocpy=true; + const DataArrayInt *nodeFamIds(m->getFamilyFieldAtLevel(1)); + if(nodeFamIds) + { _node_fam_ids=const_cast(nodeFamIds); nodeFamIds->incrRef(); } + _node_num_ids_nocpy=true; + const DataArrayInt *nodeNumIds(m->getNumberFieldAtLevel(1)); + if(nodeNumIds) + { _node_num_ids=const_cast(nodeNumIds); nodeNumIds->incrRef(); } } -void MEDUMeshMultiLev::selectPartOfNodes(const DataArrayInt *pflNodes) throw(INTERP_KERNEL::Exception) +void MEDUMeshMultiLev::selectPartOfNodes(const DataArrayInt *pflNodes) { if(!pflNodes || !pflNodes->isAllocated()) return ; @@ -410,7 +859,6 @@ void MEDUMeshMultiLev::selectPartOfNodes(const DataArrayInt *pflNodes) throw(INT std::vector< const DataArrayInt *> aa(sz); for(std::size_t i=0;i m(_parts[i]); if(pfl) @@ -420,23 +868,36 @@ void MEDUMeshMultiLev::selectPartOfNodes(const DataArrayInt *pflNodes) throw(INT MEDCouplingAutoRefCountObjectPtr cellIdsSafe(cellIds); MEDCouplingAutoRefCountObjectPtr m2(m->buildPartOfMySelfKeepCoords(cellIds->begin(),cellIds->end())); int tmp=-1; - a[i]=m2->getNodeIdsInUse(tmp); aa[i]=a[i]; + MEDCouplingAutoRefCountObjectPtr o2n(m2->getNodeIdsInUse(tmp)); + a[i]=o2n->invertArrayO2N2N2O(tmp); aa[i]=a[i]; if(pfl) _pfls[i]=pfl->selectByTupleIdSafe(cellIds->begin(),cellIds->end()); else _pfls[i]=cellIdsSafe; } - _node_reduction=DataArrayInt::Aggregate(aa); + if(!aa.empty()) + _node_reduction=DataArrayInt::Aggregate(aa);//general case + else + _node_reduction=pflNodes->deepCpy();//case where no cells in read mesh. _node_reduction->sort(true); _node_reduction=_node_reduction->buildUnique(); + if(_node_reduction->getNumberOfTuples()==pflNodes->getNumberOfTuples()) + return ;//This is the classical case where the input node profile corresponds perfectly to a subset of cells in _parts + if(_node_reduction->getNumberOfTuples()>pflNodes->getNumberOfTuples()) + throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::selectPartOfNodes : internal error in MEDCoupling during cell select from a list of nodes !"); + // Here the cells available in _parts is not enough to cover all the nodes in pflNodes. So adding vertices cells in _parts... + MEDCouplingAutoRefCountObjectPtr pflNodes2(pflNodes->deepCpy()); + pflNodes2->sort(true); + MEDCouplingAutoRefCountObjectPtr diff(pflNodes2->buildSubstractionOptimized(_node_reduction)); + appendVertices(diff,pflNodes2); } -MEDMeshMultiLev *MEDUMeshMultiLev::prepare() const throw(INTERP_KERNEL::Exception) +MEDMeshMultiLev *MEDUMeshMultiLev::prepare() const { return new MEDUMeshMultiLev(*this); } -MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDUMeshMultiLev& other):MEDMeshMultiLev(other),_parts(other._parts) +MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDUMeshMultiLev& other):MEDMeshMultiLev(other),_parts(other._parts),_coords(other._coords) { } @@ -449,13 +910,17 @@ MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDStructuredMeshMultiLev& other, const _pfls.resize(1); _pfls[0]=0; } -void MEDUMeshMultiLev::buildVTUArrays(DataArrayDouble *& coords, DataArrayByte *&types, DataArrayInt *&cellLocations, DataArrayInt *& cells, DataArrayInt *&faceLocations, DataArrayInt *&faces) const throw(INTERP_KERNEL::Exception) +/*! + * If returned value is false output pointer \a coords is not the internal pointer. If returned value is true output pointer \a coords is directly the internal pointer. + * If true is returned, the \a coords output parameter should be used with care (non const method call) to avoid to change the internal state of MEDFileUMesh instance. + */ +bool MEDUMeshMultiLev::buildVTUArrays(DataArrayDouble *& coords, DataArrayByte *&types, DataArrayInt *&cellLocations, DataArrayInt *& cells, DataArrayInt *&faceLocations, DataArrayInt *&faces) const { + const DataArrayDouble *tmp(0); if(_parts.empty()) - throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::getVTUArrays : empty array !"); - if(!(const MEDCoupling1GTUMesh *)_parts[0]) - throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::getVTUArrays : first part is null !"); - const DataArrayDouble *tmp(_parts[0]->getCoords()); + tmp=_coords; + else + tmp=_parts[0]->getCoords(); if(!tmp) throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::getVTUArrays : the coordinates are null !"); MEDCouplingAutoRefCountObjectPtr a(const_cast(tmp)); tmp->incrRef(); @@ -482,8 +947,8 @@ void MEDUMeshMultiLev::buildVTUArrays(DataArrayDouble *& coords, DataArrayByte * else { isPolyh=true; - MEDCouplingAutoRefCountObjectPtr tmp(cur->computeEffectiveNbOfNodesPerCell()); - szD+=tmp->accumulate(0)+curNbCells; + MEDCouplingAutoRefCountObjectPtr tmp2(cur->computeEffectiveNbOfNodesPerCell()); + szD+=tmp2->accumulate(0)+curNbCells; szF+=2*curNbCells+cur->getNodalConnectivity()->getNumberOfTuples(); } } @@ -511,7 +976,7 @@ void MEDUMeshMultiLev::buildVTUArrays(DataArrayDouble *& coords, DataArrayByte * if(gt<0 || gt>=PARAMEDMEM_2_VTKTYPE_LGTH) throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::getVTUArrays : invalid geometric type !"); unsigned char gtvtk(PARAMEDMEM_2_VTKTYPE[gt]); - if(gtvtk==-1) + if(gtvtk==255) throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::getVTUArrays : no VTK type for the requested INTERP_KERNEL geometric type !"); std::fill(bPtr,bPtr+curNbCells,gtvtk); bPtr+=curNbCells; const MEDCoupling1SGTUMesh *scur(dynamic_cast(cur)); @@ -521,12 +986,25 @@ void MEDUMeshMultiLev::buildVTUArrays(DataArrayDouble *& coords, DataArrayByte * throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::getVTUArrays : internal error !"); if(scur) { - int nnpc(scur->getNumberOfNodesPerCell()); - for(int i=0;igetCellModelEnum()!=INTERP_KERNEL::NORM_HEXA27) { - *dPtr++=nnpc; - dPtr=std::copy(connPtr,connPtr+nnpc,dPtr); - *cPtr=k+nnpc; k=*cPtr++; + int nnpc(scur->getNumberOfNodesPerCell()); + for(int i=0;i s(connPtr+connIPtr[0],connPtr+connIPtr[1]); + std::set s(connPtr+connIPtr[0],connPtr+connIPtr[1]); s.erase(-1); *dPtr++=(int)s.size(); dPtr=std::copy(s.begin(),s.end(),dPtr); - *cPtr=k+(int)s.size(); k=*cPtr++; + *cPtr++=k; k+=(int)s.size()+1; } } if(isPolyh) @@ -573,7 +1051,7 @@ void MEDUMeshMultiLev::buildVTUArrays(DataArrayDouble *& coords, DataArrayByte * fPtr=std::copy(work,work2,fPtr); work=work2+1; } - *ePtr=kk; kk+=connIPtr[1]-connIPtr[0]+2; + *ePtr++=kk; kk+=connIPtr[1]-connIPtr[0]+2; } } } @@ -583,18 +1061,26 @@ void MEDUMeshMultiLev::buildVTUArrays(DataArrayDouble *& coords, DataArrayByte * reorderNodesIfNecessary(a,d,0); else reorderNodesIfNecessary(a,d,f); + if(a->getNumberOfComponents()!=3) + a=a->changeNbOfComponents(3,0.); coords=a.retn(); types=b.retn(); cellLocations=c.retn(); cells=d.retn(); if(!isPolyh) { faceLocations=0; faces=0; } else { faceLocations=e.retn(); faces=f.retn(); } + return tmp==((DataArrayDouble *)a); } -void MEDUMeshMultiLev::reorderNodesIfNecessary(MEDCouplingAutoRefCountObjectPtr& coords, DataArrayInt *nodalConnVTK, DataArrayInt *polyhedNodalConnVTK) const throw(INTERP_KERNEL::Exception) +void MEDUMeshMultiLev::reorderNodesIfNecessary(MEDCouplingAutoRefCountObjectPtr& coords, DataArrayInt *nodalConnVTK, DataArrayInt *polyhedNodalConnVTK) const { const DataArrayInt *nr(_node_reduction); if(!nr) return ; + if(nodalConnVTK->empty() && !polyhedNodalConnVTK) + { + coords=(coords->selectByTupleIdSafe(nr->begin(),nr->end())); + return ; + } int sz(coords->getNumberOfTuples()); std::vector b(sz,false); const int *work(nodalConnVTK->begin()),*endW(nodalConnVTK->end()); @@ -665,17 +1151,141 @@ void MEDUMeshMultiLev::reorderNodesIfNecessary(MEDCouplingAutoRefCountObjectPtr< coords=(coords->selectByTupleIdSafe(nr->begin(),nr->end())); } + +void MEDUMeshMultiLev::appendVertices(const DataArrayInt *verticesToAdd, DataArrayInt *nr) +{ + int nbOfCells(verticesToAdd->getNumberOfTuples());//it is not a bug cells are NORM_POINT1 + MEDMeshMultiLev::appendVertices(verticesToAdd,nr); + MEDCouplingAutoRefCountObjectPtr elt(MEDCoupling1SGTUMesh::New("",INTERP_KERNEL::NORM_POINT1)); + elt->allocateCells(nbOfCells); + for(int i=0;igetIJ(i,0)); + elt->insertNextCell(&pt,&pt+1); + } + if(_parts.empty()) + throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::appendVertices : parts are empty !"); + elt->setCoords(_parts[0]->getCoords()); + MEDCouplingAutoRefCountObjectPtr elt2((MEDCoupling1SGTUMesh *)elt); elt2->incrRef(); + _parts.push_back(elt2); +} + //= -MEDStructuredMeshMultiLev::MEDStructuredMeshMultiLev() +MEDStructuredMeshMultiLev::MEDStructuredMeshMultiLev(const MEDFileStructuredMesh *m):MEDMeshMultiLev(m),_is_internal(true) +{ +} + +MEDStructuredMeshMultiLev::MEDStructuredMeshMultiLev(const MEDFileStructuredMesh *m, const std::vector& lev):MEDMeshMultiLev(m),_is_internal(true) +{ + // ids fields management + _cell_fam_ids_nocpy=true; _cell_num_ids_nocpy=true; + const DataArrayInt *tmp(0); + tmp=m->getFamilyFieldAtLevel(0); + if(tmp) + { + tmp->incrRef(); + _cell_fam_ids=const_cast(tmp); + } + tmp=m->getNumberFieldAtLevel(0); + if(tmp) + { + tmp->incrRef(); + _cell_num_ids=const_cast(tmp); + } + // + _node_fam_ids_nocpy=true; _node_num_ids_nocpy=true; + tmp=0; + tmp=m->getFamilyFieldAtLevel(1); + if(tmp) + { + tmp->incrRef(); + _node_fam_ids=const_cast(tmp); + } + tmp=m->getNumberFieldAtLevel(1); + if(tmp) + { + tmp->incrRef(); + _node_num_ids=const_cast(tmp); + } +} + +MEDStructuredMeshMultiLev::MEDStructuredMeshMultiLev(const MEDFileStructuredMesh *m, int nbOfNodes, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities):MEDMeshMultiLev(m,nbOfNodes,gts,pfls,nbEntities),_is_internal(true) { + // ids fields management + _cell_fam_ids_nocpy=true; _cell_num_ids_nocpy=true; + const DataArrayInt *tmp(0); + tmp=m->getFamilyFieldAtLevel(0); + if(tmp) + { + tmp->incrRef(); + _cell_fam_ids=const_cast(tmp); + } + tmp=m->getNumberFieldAtLevel(0); + if(tmp) + { + tmp->incrRef(); + _cell_num_ids=const_cast(tmp); + } + // + _node_fam_ids_nocpy=true; _node_num_ids_nocpy=true; + tmp=0; + tmp=m->getFamilyFieldAtLevel(1); + if(tmp) + { + tmp->incrRef(); + _node_fam_ids=const_cast(tmp); + } + tmp=m->getNumberFieldAtLevel(1); + if(tmp) + { + tmp->incrRef(); + _node_num_ids=const_cast(tmp); + } } -MEDStructuredMeshMultiLev::MEDStructuredMeshMultiLev(int nbOfNodes, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities):MEDMeshMultiLev(nbOfNodes,gts,pfls,nbEntities) +MEDStructuredMeshMultiLev::MEDStructuredMeshMultiLev(const MEDStructuredMeshMultiLev& other):MEDMeshMultiLev(other),_is_internal(true) { } -void MEDStructuredMeshMultiLev::selectPartOfNodes(const DataArrayInt *pflNodes) throw(INTERP_KERNEL::Exception) +bool MEDStructuredMeshMultiLev::prepareForImplicitUnstructuredMeshCase(MEDMeshMultiLev *&ret) const +{ + ret=0; + MEDCoupling1GTUMesh *facesIfPresent((static_cast(_mesh))->getImplicitFaceMesh()); + if(!facesIfPresent) + return false; + const DataArrayInt *pfl(0),*nr(_node_reduction); + if(!_pfls.empty()) + pfl=_pfls[0]; + MEDCouplingAutoRefCountObjectPtr facesIfPresent2(facesIfPresent); facesIfPresent->incrRef(); + MEDCouplingAutoRefCountObjectPtr ret2(new MEDUMeshMultiLev(*this,facesIfPresent2)); + if(pfl) + throw INTERP_KERNEL::Exception("MEDStructuredMeshMultiLev::prepareForImplicitUnstructuredMeshCase : case is not treated yet for profile on implicit unstructured mesh."); + if(nr) + throw INTERP_KERNEL::Exception("MEDStructuredMeshMultiLev::prepareForImplicitUnstructuredMeshCase : case is not treated yet for node reduction on implicit unstructured mesh."); + ret=ret2.retn(); + return true; +} + +void MEDStructuredMeshMultiLev::dealWithImplicitUnstructuredMesh(const MEDFileMesh *m) +{ + _cell_fam_ids_nocpy=true; _cell_num_ids_nocpy=true; + const DataArrayInt *tmp(0); + tmp=m->getFamilyFieldAtLevel(-1); + if(tmp) + { + tmp->incrRef(); + _cell_fam_ids=const_cast(tmp); + } + tmp=m->getNumberFieldAtLevel(-1); + if(tmp) + { + tmp->incrRef(); + _cell_num_ids=const_cast(tmp); + } +} + +void MEDStructuredMeshMultiLev::selectPartOfNodes(const DataArrayInt *pflNodes) { if(!pflNodes || !pflNodes->isAllocated()) return ; @@ -700,40 +1310,37 @@ void MEDStructuredMeshMultiLev::selectPartOfNodes(const DataArrayInt *pflNodes) _pfls[0]=cellIdsSafe; } -MEDStructuredMeshMultiLev::MEDStructuredMeshMultiLev(const MEDStructuredMeshMultiLev& other):MEDMeshMultiLev(other) -{ -} - //= -MEDCMeshMultiLev *MEDCMeshMultiLev::New(const MEDFileCMesh *m, const std::vector& levs) throw(INTERP_KERNEL::Exception) +MEDCMeshMultiLev *MEDCMeshMultiLev::New(const MEDFileCMesh *m, const std::vector& levs) { return new MEDCMeshMultiLev(m,levs); } -MEDCMeshMultiLev *MEDCMeshMultiLev::New(const MEDFileCMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities) throw(INTERP_KERNEL::Exception) +MEDCMeshMultiLev *MEDCMeshMultiLev::New(const MEDFileCMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities) { return new MEDCMeshMultiLev(m,gts,pfls,nbEntities); } -MEDCMeshMultiLev::MEDCMeshMultiLev(const MEDFileCMesh *m, const std::vector& levs) +MEDCMeshMultiLev::MEDCMeshMultiLev(const MEDFileCMesh *m, const std::vector& levs):MEDStructuredMeshMultiLev(m,levs) { if(!m) throw INTERP_KERNEL::Exception("MEDCMeshMultiLev constructor : null input pointer !"); if(levs.size()!=1 || levs[0]!=0) throw INTERP_KERNEL::Exception("MEDCMeshMultiLev constructor : levels supported is 0 only !"); - int mdim(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(m->getMeshDimension())); - _coords.resize(mdim); - for(int i=0;igetSpaceDimension()); + _coords.resize(sdim); + for(int i=0;i(m->getMesh()->getCoordsAt(i))); if(!elt) throw INTERP_KERNEL::Exception("MEDCMeshMultiLev constructor 2 : presence of null pointer for an vector of double along an axis !"); + elt->incrRef(); _coords[i]=elt; } } -MEDCMeshMultiLev::MEDCMeshMultiLev(const MEDFileCMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities):MEDStructuredMeshMultiLev(m->getNumberOfNodes(),gts,pfls,nbEntities) +MEDCMeshMultiLev::MEDCMeshMultiLev(const MEDFileCMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities):MEDStructuredMeshMultiLev(m,m->getNumberOfNodes(),gts,pfls,nbEntities) { if(!m) throw INTERP_KERNEL::Exception("MEDCMeshMultiLev constructor 2 : null input pointer !"); @@ -741,23 +1348,26 @@ MEDCMeshMultiLev::MEDCMeshMultiLev(const MEDFileCMesh *m, const std::vectorgetMeshDimension()); INTERP_KERNEL::NormalizedCellType gt(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(mdim)); - if(gt!=gts[0]) - throw INTERP_KERNEL::Exception("MEDCMeshMultiLev constructor 2 : the unique geo type is invalid regarding meshdim !"); - _coords.resize(mdim); - for(int i=0;i(m->getMesh()->getCoordsAt(i))); - if(!elt) - throw INTERP_KERNEL::Exception("MEDCMeshMultiLev constructor 2 : presence of null pointer for an vector of double along an axis !"); - _coords[i]=elt; _coords[i]->incrRef(); + _coords.resize(mdim); + for(int i=0;i(m->getMesh()->getCoordsAt(i))); + if(!elt) + throw INTERP_KERNEL::Exception("MEDCMeshMultiLev constructor 2 : presence of null pointer for an vector of double along an axis !"); + _coords[i]=elt; _coords[i]->incrRef(); + } } + else + dealWithImplicitUnstructuredMesh(m); } MEDCMeshMultiLev::MEDCMeshMultiLev(const MEDCMeshMultiLev& other):MEDStructuredMeshMultiLev(other),_coords(other._coords) { } -std::vector MEDCMeshMultiLev::getNodeGridStructure() const throw(INTERP_KERNEL::Exception) +std::vector MEDCMeshMultiLev::getNodeGridStructure() const { std::vector ret(_coords.size()); for(std::size_t i=0;i<_coords.size();i++) @@ -765,9 +1375,14 @@ std::vector MEDCMeshMultiLev::getNodeGridStructure() const throw(INTERP_KER return ret; } -MEDMeshMultiLev *MEDCMeshMultiLev::prepare() const throw(INTERP_KERNEL::Exception) +MEDMeshMultiLev *MEDCMeshMultiLev::prepare() const { - const DataArrayInt *pfl(_pfls[0]),*nr(_node_reduction); + MEDMeshMultiLev *retSpecific(0); + if(prepareForImplicitUnstructuredMeshCase(retSpecific)) + return retSpecific; + const DataArrayInt *pfl(0),*nr(_node_reduction); + if(!_pfls.empty()) + pfl=_pfls[0]; MEDCouplingAutoRefCountObjectPtr nnr; std::vector cgs,ngs(getNodeGridStructure()); cgs.resize(ngs.size()); @@ -775,9 +1390,11 @@ MEDMeshMultiLev *MEDCMeshMultiLev::prepare() const throw(INTERP_KERNEL::Exceptio if(pfl) { std::vector< std::pair > cellParts; + MEDCouplingAutoRefCountObjectPtr ret2; if(MEDCouplingStructuredMesh::IsPartStructured(pfl->begin(),pfl->end(),cgs,cellParts)) { MEDCouplingAutoRefCountObjectPtr ret(new MEDCMeshMultiLev(*this)); + ret->_is_internal=false; if(nr) { nnr=nr->deepCpy(); nnr->sort(true); ret->setNodeReduction(nnr); } ret->_nb_entities[0]=pfl->getNumberOfTuples(); @@ -786,7 +1403,7 @@ MEDMeshMultiLev *MEDCMeshMultiLev::prepare() const throw(INTERP_KERNEL::Exceptio for(std::size_t i=0;i<_coords.size();i++) coords[i]=_coords[i]->selectByTupleId2(cellParts[i].first,cellParts[i].second+1,1); ret->_coords=coords; - return ret.retn(); + ret2=(MEDCMeshMultiLev *)ret; ret2->incrRef(); } else { @@ -798,8 +1415,21 @@ MEDMeshMultiLev *MEDCMeshMultiLev::prepare() const throw(INTERP_KERNEL::Exceptio MEDCouplingAutoRefCountObjectPtr ret(new MEDUMeshMultiLev(*this,m3)); if(nr) { m3->zipCoords(); nnr=nr->deepCpy(); nnr->sort(true); ret->setNodeReduction(nnr); } - return ret.retn(); + ret2=(MEDUMeshMultiLev *)ret; ret2->incrRef(); } + const DataArrayInt *famIds(_cell_fam_ids),*numIds(_cell_num_ids); + if(famIds) + { + MEDCouplingAutoRefCountObjectPtr tmp(famIds->selectByTupleIdSafe(pfl->begin(),pfl->end())); + ret2->setFamilyIdsOnCells(tmp,false); + } + if(numIds) + { + MEDCouplingAutoRefCountObjectPtr tmp(numIds->selectByTupleIdSafe(pfl->begin(),pfl->end())); + ret2->setNumberIdsOnCells(tmp,false); + } + return ret2.retn(); + } else { @@ -810,8 +1440,12 @@ MEDMeshMultiLev *MEDCMeshMultiLev::prepare() const throw(INTERP_KERNEL::Exceptio } } -std::vector< DataArrayDouble * > MEDCMeshMultiLev::buildVTUArrays() const throw(INTERP_KERNEL::Exception) +/*! + * \a param [out] isInternal if true the returned pointers are those in main data structure. If false those pointers have been built espacially for that method. + */ +std::vector< DataArrayDouble * > MEDCMeshMultiLev::buildVTUArrays(bool& isInternal) const { + isInternal=_is_internal; std::size_t sz(_coords.size()); std::vector< DataArrayDouble * > ret(sz); for(std::size_t i=0;i MEDCMeshMultiLev::buildVTUArrays() const throw( //= -MEDCurveLinearMeshMultiLev *MEDCurveLinearMeshMultiLev::New(const MEDFileCurveLinearMesh *m, const std::vector& levs) throw(INTERP_KERNEL::Exception) +MEDCurveLinearMeshMultiLev *MEDCurveLinearMeshMultiLev::New(const MEDFileCurveLinearMesh *m, const std::vector& levs) { return new MEDCurveLinearMeshMultiLev(m,levs); } -MEDCurveLinearMeshMultiLev *MEDCurveLinearMeshMultiLev::New(const MEDFileCurveLinearMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities) throw(INTERP_KERNEL::Exception) +MEDCurveLinearMeshMultiLev *MEDCurveLinearMeshMultiLev::New(const MEDFileCurveLinearMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities) { return new MEDCurveLinearMeshMultiLev(m,gts,pfls,nbEntities); } -MEDCurveLinearMeshMultiLev::MEDCurveLinearMeshMultiLev(const MEDFileCurveLinearMesh *m, const std::vector& levs) +MEDCurveLinearMeshMultiLev::MEDCurveLinearMeshMultiLev(const MEDFileCurveLinearMesh *m, const std::vector& levs):MEDStructuredMeshMultiLev(m,levs) { if(!m) throw INTERP_KERNEL::Exception("MEDCurveLinearMeshMultiLev constructor : null input pointer !"); @@ -848,35 +1482,43 @@ MEDCurveLinearMeshMultiLev::MEDCurveLinearMeshMultiLev(const MEDFileCurveLinearM _structure=m->getMesh()->getNodeGridStructure(); } -MEDCurveLinearMeshMultiLev::MEDCurveLinearMeshMultiLev(const MEDFileCurveLinearMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities):MEDStructuredMeshMultiLev(m->getNumberOfNodes(),gts,pfls,nbEntities) +MEDCurveLinearMeshMultiLev::MEDCurveLinearMeshMultiLev(const MEDFileCurveLinearMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities):MEDStructuredMeshMultiLev(m,m->getNumberOfNodes(),gts,pfls,nbEntities) { if(!m) throw INTERP_KERNEL::Exception("MEDCurveLinearMeshMultiLev constructor 2 : null input pointer !"); if(gts.size()!=1 || pfls.size()!=1) throw INTERP_KERNEL::Exception("MEDCurveLinearMeshMultiLev constructor 2 : lengthes of gts and pfls must be equal to one !"); - int mdim(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(m->getMeshDimension())); - if(mdim!=gts[0]) - throw INTERP_KERNEL::Exception("MEDCurveLinearMeshMultiLev constructor 2 : the unique geo type is invalid regarding meshdim !"); - DataArrayDouble *coords(const_cast(m->getMesh()->getCoords())); - if(!coords) - throw INTERP_KERNEL::Exception("MEDCurveLinearMeshMultiLev constructor 2 : no coords set !"); - coords->incrRef(); - _coords=coords; - _structure=m->getMesh()->getNodeGridStructure(); + INTERP_KERNEL::NormalizedCellType gt(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(m->getMeshDimension())); + if(gt==gts[0]) + { + DataArrayDouble *coords(const_cast(m->getMesh()->getCoords())); + if(!coords) + throw INTERP_KERNEL::Exception("MEDCurveLinearMeshMultiLev constructor 2 : no coords set !"); + coords->incrRef(); + _coords=coords; + _structure=m->getMesh()->getNodeGridStructure(); + } + else + dealWithImplicitUnstructuredMesh(m); } MEDCurveLinearMeshMultiLev::MEDCurveLinearMeshMultiLev(const MEDCurveLinearMeshMultiLev& other):MEDStructuredMeshMultiLev(other),_coords(other._coords),_structure(other._structure) { } -std::vector MEDCurveLinearMeshMultiLev::getNodeGridStructure() const throw(INTERP_KERNEL::Exception) +std::vector MEDCurveLinearMeshMultiLev::getNodeGridStructure() const { return _structure; } -MEDMeshMultiLev *MEDCurveLinearMeshMultiLev::prepare() const throw(INTERP_KERNEL::Exception) +MEDMeshMultiLev *MEDCurveLinearMeshMultiLev::prepare() const { - const DataArrayInt *pfl(_pfls[0]),*nr(_node_reduction); + MEDMeshMultiLev *retSpecific(0); + if(prepareForImplicitUnstructuredMeshCase(retSpecific)) + return retSpecific; + const DataArrayInt *pfl(0),*nr(_node_reduction); + if(!_pfls.empty()) + pfl=_pfls[0]; MEDCouplingAutoRefCountObjectPtr nnr; std::vector cgs,ngs(getNodeGridStructure()); cgs.resize(ngs.size()); @@ -884,6 +1526,7 @@ MEDMeshMultiLev *MEDCurveLinearMeshMultiLev::prepare() const throw(INTERP_KERNEL if(pfl) { std::vector< std::pair > cellParts,nodeParts; + MEDCouplingAutoRefCountObjectPtr ret2; if(MEDCouplingStructuredMesh::IsPartStructured(pfl->begin(),pfl->end(),cgs,cellParts)) { nodeParts=cellParts; @@ -895,13 +1538,14 @@ MEDMeshMultiLev *MEDCurveLinearMeshMultiLev::prepare() const throw(INTERP_KERNEL } MEDCouplingAutoRefCountObjectPtr p(MEDCouplingStructuredMesh::BuildExplicitIdsFrom(ngs,nodeParts)); MEDCouplingAutoRefCountObjectPtr ret(new MEDCurveLinearMeshMultiLev(*this)); + ret->_is_internal=false; if(nr) { nnr=nr->deepCpy(); nnr->sort(true); ret->setNodeReduction(nnr); } ret->_nb_entities[0]=pfl->getNumberOfTuples(); ret->_pfls[0]=0; ret->_coords=_coords->selectByTupleIdSafe(p->begin(),p->end()); ret->_structure=st; - return ret.retn(); + ret2=(MEDCurveLinearMeshMultiLev *)ret; ret2->incrRef(); } else { @@ -912,8 +1556,20 @@ MEDMeshMultiLev *MEDCurveLinearMeshMultiLev::prepare() const throw(INTERP_KERNEL MEDCouplingAutoRefCountObjectPtr ret(new MEDUMeshMultiLev(*this,m3)); if(nr) { m3->zipCoords(); nnr=nr->deepCpy(); nnr->sort(true); ret->setNodeReduction(nnr); } - return ret.retn(); + ret2=(MEDUMeshMultiLev *)ret; ret2->incrRef(); } + const DataArrayInt *famIds(_cell_fam_ids),*numIds(_cell_num_ids); + if(famIds) + { + MEDCouplingAutoRefCountObjectPtr tmp(famIds->selectByTupleIdSafe(pfl->begin(),pfl->end())); + ret2->setFamilyIdsOnCells(tmp,false); + } + if(numIds) + { + MEDCouplingAutoRefCountObjectPtr tmp(numIds->selectByTupleIdSafe(pfl->begin(),pfl->end())); + ret2->setNumberIdsOnCells(tmp,false); + } + return ret2.retn(); } else { @@ -924,8 +1580,9 @@ MEDMeshMultiLev *MEDCurveLinearMeshMultiLev::prepare() const throw(INTERP_KERNEL } } -void MEDCurveLinearMeshMultiLev::buildVTUArrays(DataArrayDouble *&coords, std::vector& nodeStrct) const throw(INTERP_KERNEL::Exception) +void MEDCurveLinearMeshMultiLev::buildVTUArrays(DataArrayDouble *&coords, std::vector& nodeStrct, bool& isInternal) const { + isInternal=_is_internal; nodeStrct=_structure; const DataArrayDouble *coo(_coords); if(!coo) @@ -944,20 +1601,25 @@ MEDFileField1TSStructItem2::MEDFileField1TSStructItem2(INTERP_KERNEL::Normalized _pfl->setName(c.c_str()); } -void MEDFileField1TSStructItem2::checkWithMeshStructForCells(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) throw(INTERP_KERNEL::Exception) +void MEDFileField1TSStructItem2::checkWithMeshStructForCells(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) { + if(!mst->doesManageGeoType(_geo_type)) + { + MEDFileMeshStruct *mstUnConstCasted(const_cast(mst)); + mstUnConstCasted->appendIfImplicitType(_geo_type); + } int nbOfEnt=mst->getNumberOfElemsOfGeoType(_geo_type); checkInRange(nbOfEnt,1,globs); } -void MEDFileField1TSStructItem2::checkWithMeshStructForGaussNE(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) throw(INTERP_KERNEL::Exception) +void MEDFileField1TSStructItem2::checkWithMeshStructForGaussNE(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) { int nbOfEnt=mst->getNumberOfElemsOfGeoType(_geo_type); const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_geo_type); checkInRange(nbOfEnt,(int)cm.getNumberOfNodes(),globs); } -void MEDFileField1TSStructItem2::checkWithMeshStructForGaussPT(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) throw(INTERP_KERNEL::Exception) +void MEDFileField1TSStructItem2::checkWithMeshStructForGaussPT(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) { if(!globs) throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::checkWithMeshStructForGaussPT : no globals specified !"); @@ -1006,7 +1668,7 @@ const DataArrayInt *MEDFileField1TSStructItem2::getPfl(const MEDFileFieldGlobsRe * \param [in] nbOfEntity - number of entity that can be either cells or nodes. Not other possiblity. * \param [in] nip - number of integration points. 1 for ON_CELLS and NO_NODES */ -void MEDFileField1TSStructItem2::checkInRange(int nbOfEntity, int nip, const MEDFileFieldGlobsReal *globs) throw(INTERP_KERNEL::Exception) +void MEDFileField1TSStructItem2::checkInRange(int nbOfEntity, int nip, const MEDFileFieldGlobsReal *globs) { _nb_of_entity=nbOfEntity; if(_pfl->getName().empty()) @@ -1026,7 +1688,7 @@ void MEDFileField1TSStructItem2::checkInRange(int nbOfEntity, int nip, const MED } } -bool MEDFileField1TSStructItem2::isFastlyEqual(int& startExp, INTERP_KERNEL::NormalizedCellType gt, const char *pflName) const +bool MEDFileField1TSStructItem2::isFastlyEqual(int& startExp, INTERP_KERNEL::NormalizedCellType gt, const std::string& pflName) const { if(startExp!=_start_end.first) return false; @@ -1045,7 +1707,7 @@ bool MEDFileField1TSStructItem2::operator==(const MEDFileField1TSStructItem2& ot return _geo_type==other._geo_type && _start_end==other._start_end && _pfl->getName()==other._pfl->getName(); } -bool MEDFileField1TSStructItem2::isCellSupportEqual(const MEDFileField1TSStructItem2& other, const MEDFileFieldGlobsReal *globs) const throw(INTERP_KERNEL::Exception) +bool MEDFileField1TSStructItem2::isCellSupportEqual(const MEDFileField1TSStructItem2& other, const MEDFileFieldGlobsReal *globs) const { if(_geo_type!=other._geo_type) return false; @@ -1059,7 +1721,7 @@ bool MEDFileField1TSStructItem2::isCellSupportEqual(const MEDFileField1TSStructI return pfl1->isEqualWithoutConsideringStr(*pfl2); } -bool MEDFileField1TSStructItem2::isNodeSupportEqual(const MEDFileField1TSStructItem2& other, const MEDFileFieldGlobsReal *globs) const throw(INTERP_KERNEL::Exception) +bool MEDFileField1TSStructItem2::isNodeSupportEqual(const MEDFileField1TSStructItem2& other, const MEDFileFieldGlobsReal *globs) const { return isCellSupportEqual(other,globs); } @@ -1067,7 +1729,7 @@ bool MEDFileField1TSStructItem2::isNodeSupportEqual(const MEDFileField1TSStructI /*! * \a objs must be non empty. \a objs should contain items having same geometric type. */ -MEDFileField1TSStructItem2 MEDFileField1TSStructItem2::BuildAggregationOf(const std::vector& objs, const MEDFileFieldGlobsReal *globs) throw(INTERP_KERNEL::Exception) +MEDFileField1TSStructItem2 MEDFileField1TSStructItem2::BuildAggregationOf(const std::vector& objs, const MEDFileFieldGlobsReal *globs) { if(objs.empty()) throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::BuildAggregationOf : empty input !"); @@ -1114,13 +1776,18 @@ MEDFileField1TSStructItem2 MEDFileField1TSStructItem2::BuildAggregationOf(const } } -std::size_t MEDFileField1TSStructItem2::getHeapMemorySize() const +std::size_t MEDFileField1TSStructItem2::getHeapMemorySizeWithoutChildren() const { - std::size_t ret(0); + std::size_t ret(_loc.capacity()); + return ret; +} + +std::vector MEDFileField1TSStructItem2::getDirectChildren() const +{ + std::vector ret; const DataArrayInt *pfl(_pfl); if(pfl) - ret+=pfl->getHeapMemorySize(); - ret+=_loc.capacity(); + ret.push_back(pfl); return ret; } @@ -1130,7 +1797,7 @@ MEDFileField1TSStructItem::MEDFileField1TSStructItem(TypeOfField a, const std::v { } -void MEDFileField1TSStructItem::checkWithMeshStruct(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) throw(INTERP_KERNEL::Exception) +void MEDFileField1TSStructItem::checkWithMeshStruct(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) { switch(_type) { @@ -1177,7 +1844,7 @@ bool MEDFileField1TSStructItem::operator==(const MEDFileField1TSStructItem& othe return true; } -bool MEDFileField1TSStructItem::isCellSupportEqual(const MEDFileField1TSStructItem& other, const MEDFileFieldGlobsReal *globs) const throw(INTERP_KERNEL::Exception) +bool MEDFileField1TSStructItem::isCellSupportEqual(const MEDFileField1TSStructItem& other, const MEDFileFieldGlobsReal *globs) const { if(_type!=other._type) return false; @@ -1189,7 +1856,7 @@ bool MEDFileField1TSStructItem::isCellSupportEqual(const MEDFileField1TSStructIt return true; } -bool MEDFileField1TSStructItem::isNodeSupportEqual(const MEDFileField1TSStructItem& other, const MEDFileFieldGlobsReal *globs) const throw(INTERP_KERNEL::Exception) +bool MEDFileField1TSStructItem::isNodeSupportEqual(const MEDFileField1TSStructItem& other, const MEDFileFieldGlobsReal *globs) const { if(_type!=other._type) return false; @@ -1218,7 +1885,7 @@ private: INTERP_KERNEL::NormalizedCellType _geo_type; }; -MEDFileField1TSStructItem MEDFileField1TSStructItem::simplifyMeOnCellEntity(const MEDFileFieldGlobsReal *globs) const throw(INTERP_KERNEL::Exception) +MEDFileField1TSStructItem MEDFileField1TSStructItem::simplifyMeOnCellEntity(const MEDFileFieldGlobsReal *globs) const { if(!isEntityCell()) throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::simplifyMeOnCellEntity : must be on ON_CELLS, ON_GAUSS_NE or ON_GAUSS_PT !"); @@ -1256,7 +1923,7 @@ MEDFileField1TSStructItem MEDFileField1TSStructItem::simplifyMeOnCellEntity(cons /*! * \a this is expected to be ON_CELLS and simplified. */ -bool MEDFileField1TSStructItem::isCompatibleWithNodesDiscr(const MEDFileField1TSStructItem& other, const MEDFileMeshStruct *meshSt, const MEDFileFieldGlobsReal *globs) const throw(INTERP_KERNEL::Exception) +bool MEDFileField1TSStructItem::isCompatibleWithNodesDiscr(const MEDFileField1TSStructItem& other, const MEDFileMeshStruct *meshSt, const MEDFileFieldGlobsReal *globs) const { if(other._type!=ON_NODES) throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::isCompatibleWithNodesDiscr : other must be on nodes !"); @@ -1289,7 +1956,7 @@ bool MEDFileField1TSStructItem::isCompatibleWithNodesDiscr(const MEDFileField1TS } } -bool MEDFileField1TSStructItem::isFullyOnOneLev(const MEDFileMeshStruct *meshSt, int& theFirstLevFull) const throw(INTERP_KERNEL::Exception) +bool MEDFileField1TSStructItem::isFullyOnOneLev(const MEDFileMeshStruct *meshSt, int& theFirstLevFull) const { if(_type!=ON_CELLS) throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::isFullyOnOneLev : works only for ON_CELLS discretization !"); @@ -1300,7 +1967,6 @@ bool MEDFileField1TSStructItem::isFullyOnOneLev(const MEDFileMeshStruct *meshSt, throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::isFullyOnOneLev : no levels in input mesh structure !"); std::vector levs(nbOfLevs); theFirstLevFull=1; - int nbOfGT=0; std::set gts; for(std::vector< MEDFileField1TSStructItem2 >::const_iterator it=_items.begin();it!=_items.end();it++) { @@ -1321,21 +1987,26 @@ bool MEDFileField1TSStructItem::isFullyOnOneLev(const MEDFileMeshStruct *meshSt, const MEDFileField1TSStructItem2& MEDFileField1TSStructItem::operator[](std::size_t i) const throw(INTERP_KERNEL::Exception) { - if(i<0 || i>=_items.size()) + if(i>=_items.size()) throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::operator[] : input is not in valid range !"); return _items[i]; } -std::size_t MEDFileField1TSStructItem::getHeapMemorySize() const +std::size_t MEDFileField1TSStructItem::getHeapMemorySizeWithoutChildren() const { - std::size_t ret(0); + std::size_t ret(_items.size()*sizeof(MEDFileField1TSStructItem2)); + return ret; +} + +std::vector MEDFileField1TSStructItem::getDirectChildren() const +{ + std::vector ret; for(std::vector< MEDFileField1TSStructItem2 >::const_iterator it=_items.begin();it!=_items.end();it++) - ret+=(*it).getHeapMemorySize(); - ret+=_items.size()*sizeof(MEDFileField1TSStructItem2); + ret.push_back(&(*it)); return ret; } -MEDMeshMultiLev *MEDFileField1TSStructItem::buildFromScratchDataSetSupportOnCells(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) const throw(INTERP_KERNEL::Exception) +MEDMeshMultiLev *MEDFileField1TSStructItem::buildFromScratchDataSetSupportOnCells(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) const { std::size_t sz(_items.size()); std::vector a0(sz); @@ -1351,6 +2022,31 @@ MEDMeshMultiLev *MEDFileField1TSStructItem::buildFromScratchDataSetSupportOnCell return MEDMeshMultiLev::New(mst->getTheMesh(),a0,a1,a2); } +std::vector MEDFileField1TSStructItem::getGeoTypes(const MEDFileMesh *m) const +{ + std::vector ret; + if(_type==ON_NODES) + { + if(!_items.empty() && _items[0].getPflName().empty()) + { + if(m) + return m->getAllGeoTypes(); + else + return ret; + } + else + return ret; + } + for(std::vector< MEDFileField1TSStructItem2 >::const_iterator it=_items.begin();it!=_items.end();it++) + { + INTERP_KERNEL::NormalizedCellType elt((*it).getGeo()); + std::vector::iterator it2(std::find(ret.begin(),ret.end(),elt)); + if(it2==ret.end()) + ret.push_back(elt); + } + return ret; +} + MEDFileField1TSStructItem MEDFileField1TSStructItem::BuildItemFrom(const MEDFileAnyTypeField1TS *ref, const MEDFileMeshStruct *meshSt) { TypeOfField atype; @@ -1359,7 +2055,7 @@ MEDFileField1TSStructItem MEDFileField1TSStructItem::BuildItemFrom(const MEDFile std::vector< std::vector > pfls,locs; std::vector< std::vector > typesF; std::vector geoTypes; - std::vector< std::vector > > strtEnds=ref->getFieldSplitedByType(0,geoTypes,typesF,pfls,locs); + std::vector< std::vector > > strtEnds=ref->getFieldSplitedByType(std::string(),geoTypes,typesF,pfls,locs); std::size_t nbOfGeoTypes(geoTypes.size()); if(nbOfGeoTypes==0) throw INTERP_KERNEL::Exception("MEDFileField1TSStruct : not null by empty ref !"); @@ -1389,7 +2085,7 @@ MEDFileField1TSStructItem MEDFileField1TSStructItem::BuildItemFrom(const MEDFile //= -MEDFileField1TSStruct *MEDFileField1TSStruct::New(const MEDFileAnyTypeField1TS *ref, MEDFileMeshStruct *mst) throw(INTERP_KERNEL::Exception) +MEDFileField1TSStruct *MEDFileField1TSStruct::New(const MEDFileAnyTypeField1TS *ref, MEDFileMeshStruct *mst) { return new MEDFileField1TSStruct(ref,mst); } @@ -1399,14 +2095,14 @@ MEDFileField1TSStruct::MEDFileField1TSStruct(const MEDFileAnyTypeField1TS *ref, _already_checked.push_back(MEDFileField1TSStructItem::BuildItemFrom(ref,mst)); } -void MEDFileField1TSStruct::checkWithMeshStruct(MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) throw(INTERP_KERNEL::Exception) +void MEDFileField1TSStruct::checkWithMeshStruct(MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) { if(_already_checked.empty()) throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::checkWithMeshStruct : not correctly initialized !"); _already_checked.back().checkWithMeshStruct(mst,globs); } -bool MEDFileField1TSStruct::isEqualConsideringThePast(const MEDFileAnyTypeField1TS *other, const MEDFileMeshStruct *mst) const throw(INTERP_KERNEL::Exception) +bool MEDFileField1TSStruct::isEqualConsideringThePast(const MEDFileAnyTypeField1TS *other, const MEDFileMeshStruct *mst) const { MEDFileField1TSStructItem b(MEDFileField1TSStructItem::BuildItemFrom(other,mst)); for(std::vector::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++) @@ -1420,7 +2116,7 @@ bool MEDFileField1TSStruct::isEqualConsideringThePast(const MEDFileAnyTypeField1 /*! * Not const because \a other structure will be added to the \c _already_checked attribute in case of success. */ -bool MEDFileField1TSStruct::isSupportSameAs(const MEDFileAnyTypeField1TS *other, const MEDFileMeshStruct *meshSt) throw(INTERP_KERNEL::Exception) +bool MEDFileField1TSStruct::isSupportSameAs(const MEDFileAnyTypeField1TS *other, const MEDFileMeshStruct *meshSt) { if(_already_checked.empty()) throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::isSupportSameAs : no ref !"); @@ -1450,7 +2146,7 @@ bool MEDFileField1TSStruct::isSupportSameAs(const MEDFileAnyTypeField1TS *other, /*! * \param [in] other - a field with only one spatial discretization : ON_NODES. */ -bool MEDFileField1TSStruct::isCompatibleWithNodesDiscr(const MEDFileAnyTypeField1TS *other, const MEDFileMeshStruct *meshSt) throw(INTERP_KERNEL::Exception) +bool MEDFileField1TSStruct::isCompatibleWithNodesDiscr(const MEDFileAnyTypeField1TS *other, const MEDFileMeshStruct *meshSt) { if(_already_checked.empty()) throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::isCompatibleWithNodesDiscr : no ref !"); @@ -1479,16 +2175,21 @@ bool MEDFileField1TSStruct::isCompatibleWithNodesDiscr(const MEDFileAnyTypeField return _already_checked[0].isNodeSupportEqual(other1,other); } -std::size_t MEDFileField1TSStruct::getHeapMemorySize() const +std::size_t MEDFileField1TSStruct::getHeapMemorySizeWithoutChildren() const { - std::size_t ret(0); + std::size_t ret(_already_checked.capacity()*sizeof(MEDFileField1TSStructItem)); + return ret; +} + +std::vector MEDFileField1TSStruct::getDirectChildren() const +{ + std::vector ret; for(std::vector::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++) - ret+=(*it).getHeapMemorySize(); - ret+=_already_checked.capacity()*sizeof(MEDFileField1TSStructItem); + ret.push_back(&(*it)); return ret; } -MEDMeshMultiLev *MEDFileField1TSStruct::buildFromScratchDataSetSupport(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) const throw(INTERP_KERNEL::Exception) +MEDMeshMultiLev *MEDFileField1TSStruct::buildFromScratchDataSetSupport(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) const { if(_already_checked.empty()) throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::buildFromScratchDataSetSupport : No outline structure in this !"); @@ -1503,16 +2204,15 @@ MEDMeshMultiLev *MEDFileField1TSStruct::buildFromScratchDataSetSupport(const MED else { if(!presenceOfPartialNodeDiscr(pos1)) - {//we have only all nodes, no cell definition info -> level 0; - std::vector levs(1,0); - return MEDMeshMultiLev::New(mst->getTheMesh(),levs); + {//we have only all nodes, no cell definition info -> all existing levels !; + return MEDMeshMultiLev::New(mst->getTheMesh(),mst->getTheMesh()->getNonEmptyLevels()); } else return MEDMeshMultiLev::NewOnlyOnNode(mst->getTheMesh(),_already_checked[pos1][0].getPfl(globs)); } } -bool MEDFileField1TSStruct::isDataSetSupportFastlyEqualTo(const MEDFileField1TSStruct& other, const MEDFileFieldGlobsReal *globs) const throw(INTERP_KERNEL::Exception) +bool MEDFileField1TSStruct::isDataSetSupportFastlyEqualTo(const MEDFileField1TSStruct& other, const MEDFileFieldGlobsReal *globs) const { int b0,b1; bool a0(presenceOfCellDiscr(b0)),a1(presenceOfPartialNodeDiscr(b1)); @@ -1529,11 +2229,29 @@ bool MEDFileField1TSStruct::isDataSetSupportFastlyEqualTo(const MEDFileField1TSS return true; } +std::vector MEDFileField1TSStruct::getGeoTypes(const MEDFileMesh *m) const +{ + std::vector ret; + for(std::vector::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++) + { + std::vector ret2((*it).getGeoTypes(m)); + for(std::vector::const_iterator it2=ret2.begin();it2!=ret2.end();it2++) + { + if(*it2==INTERP_KERNEL::NORM_ERROR) + continue; + std::vector::iterator it3(std::find(ret.begin(),ret.end(),*it2)); + if(it3==ret.end()) + ret.push_back(*it2); + } + } + return ret; +} + /*! * Returns true if presence in \a this of discretization ON_CELLS, ON_GAUSS_PT, ON_GAUSS_NE. * If true is returned the pos of the easiest is returned. The easiest is the first element in \a this having the less splitted subparts. */ -bool MEDFileField1TSStruct::presenceOfCellDiscr(int& pos) const throw(INTERP_KERNEL::Exception) +bool MEDFileField1TSStruct::presenceOfCellDiscr(int& pos) const { std::size_t refSz(std::numeric_limits::max()); bool ret(false); @@ -1557,7 +2275,7 @@ bool MEDFileField1TSStruct::presenceOfCellDiscr(int& pos) const throw(INTERP_KER * Returns true if presence in \a this of discretization ON_NODES. * If true is returned the pos of the first element containing the single subpart. */ -bool MEDFileField1TSStruct::presenceOfPartialNodeDiscr(int& pos) const throw(INTERP_KERNEL::Exception) +bool MEDFileField1TSStruct::presenceOfPartialNodeDiscr(int& pos) const { int i(0); for(std::vector::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++,i++) @@ -1579,7 +2297,7 @@ bool MEDFileField1TSStruct::presenceOfPartialNodeDiscr(int& pos) const throw(INT //= -MEDFileFastCellSupportComparator *MEDFileFastCellSupportComparator::New(const MEDFileMeshStruct *m, const MEDFileAnyTypeFieldMultiTS *ref) throw(INTERP_KERNEL::Exception) +MEDFileFastCellSupportComparator *MEDFileFastCellSupportComparator::New(const MEDFileMeshStruct *m, const MEDFileAnyTypeFieldMultiTS *ref) { return new MEDFileFastCellSupportComparator(m,ref); } @@ -1599,23 +2317,28 @@ MEDFileFastCellSupportComparator::MEDFileFastCellSupportComparator(const MEDFile } } -std::size_t MEDFileFastCellSupportComparator::getHeapMemorySize() const +std::size_t MEDFileFastCellSupportComparator::getHeapMemorySizeWithoutChildren() const { - std::size_t ret(0); + std::size_t ret(_f1ts_cmps.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr)); + return ret; +} + +std::vector MEDFileFastCellSupportComparator::getDirectChildren() const +{ + std::vector ret; const MEDFileMeshStruct *mst(_mesh_comp); if(mst) - ret+=mst->getHeapMemorySize(); + ret.push_back(mst); for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_f1ts_cmps.begin();it!=_f1ts_cmps.end();it++) { const MEDFileField1TSStruct *cur(*it); if(cur) - ret+=cur->getHeapMemorySize()+sizeof(MEDFileField1TSStruct); + ret.push_back(cur); } - ret+=_f1ts_cmps.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr); return ret; } -bool MEDFileFastCellSupportComparator::isEqual(const MEDFileAnyTypeFieldMultiTS *other) throw(INTERP_KERNEL::Exception) +bool MEDFileFastCellSupportComparator::isEqual(const MEDFileAnyTypeFieldMultiTS *other) { int nbPts=other->getNumberOfTS(); if(nbPts!=(int)_f1ts_cmps.size()) @@ -1633,7 +2356,7 @@ bool MEDFileFastCellSupportComparator::isEqual(const MEDFileAnyTypeFieldMultiTS return true; } -bool MEDFileFastCellSupportComparator::isCompatibleWithNodesDiscr(const MEDFileAnyTypeFieldMultiTS *other) throw(INTERP_KERNEL::Exception) +bool MEDFileFastCellSupportComparator::isCompatibleWithNodesDiscr(const MEDFileAnyTypeFieldMultiTS *other) { int nbPts=other->getNumberOfTS(); if(nbPts!=(int)_f1ts_cmps.size()) @@ -1650,7 +2373,7 @@ bool MEDFileFastCellSupportComparator::isCompatibleWithNodesDiscr(const MEDFileA return true; } -MEDMeshMultiLev *MEDFileFastCellSupportComparator::buildFromScratchDataSetSupport(int timeStepId, const MEDFileFieldGlobsReal *globs) const throw(INTERP_KERNEL::Exception) +MEDMeshMultiLev *MEDFileFastCellSupportComparator::buildFromScratchDataSetSupport(int timeStepId, const MEDFileFieldGlobsReal *globs) const { if(timeStepId<0 || timeStepId>=(int)_f1ts_cmps.size()) { @@ -1666,7 +2389,7 @@ MEDMeshMultiLev *MEDFileFastCellSupportComparator::buildFromScratchDataSetSuppor return obj->buildFromScratchDataSetSupport(_mesh_comp,globs); } -bool MEDFileFastCellSupportComparator::isDataSetSupportEqualToThePreviousOne(int timeStepId, const MEDFileFieldGlobsReal *globs) const throw(INTERP_KERNEL::Exception) +bool MEDFileFastCellSupportComparator::isDataSetSupportEqualToThePreviousOne(int timeStepId, const MEDFileFieldGlobsReal *globs) const { if(timeStepId<=0 || timeStepId>=(int)_f1ts_cmps.size()) { @@ -1677,3 +2400,24 @@ bool MEDFileFastCellSupportComparator::isDataSetSupportEqualToThePreviousOne(int const MEDFileField1TSStruct *objRef(_f1ts_cmps[timeStepId-1]); return objRef->isDataSetSupportFastlyEqualTo(*obj,globs); } + +int MEDFileFastCellSupportComparator::getNumberOfTS() const +{ + return _f1ts_cmps.size(); +} + +std::vector MEDFileFastCellSupportComparator::getGeoTypesAt(int timeStepId, const MEDFileMesh *m) const +{ + if(timeStepId<0 || timeStepId>=(int)_f1ts_cmps.size()) + { + std::ostringstream oss; oss << "MEDFileFastCellSupportComparator::getGeoTypesAt : requested time step id #" << timeStepId << " is not in [0," << _f1ts_cmps.size() << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + const MEDFileField1TSStruct *elt(_f1ts_cmps[timeStepId]); + if(!elt) + { + std::ostringstream oss; oss << "MEDFileFastCellSupportComparator::getGeoTypesAt : requested time step id #" << timeStepId << " points to a NULL pointer !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + return elt->getGeoTypes(m); +}