X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FMEDLoader%2FMEDFileFieldOverView.cxx;h=11c411960cf0ce9a642446d9cee853d39d3b6d79;hb=19a65812ae7b522811413fff6e642d1273b13d48;hp=591cb407939c17b05f8c06b720fd6e23392aadd7;hpb=3503a880fc4d019f41e5c35fef1b81a2da14e097;p=tools%2Fmedcoupling.git diff --git a/src/MEDLoader/MEDFileFieldOverView.cxx b/src/MEDLoader/MEDFileFieldOverView.cxx index 591cb4079..11c411960 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-2021 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 @@ -22,12 +22,14 @@ #include "MEDFileField.hxx" #include "MEDFileMesh.hxx" +#include "MEDCouplingFieldDiscretization.hxx" #include "CellModel.hxx" -using namespace ParaMEDMEM; +using namespace MEDCoupling; -const unsigned char MEDMeshMultiLev::PARAMEDMEM_2_VTKTYPE[MEDMeshMultiLev::PARAMEDMEM_2_VTKTYPE_LGTH]= - {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::PARAMEDMEM_2_VTKTYPE=MEDCOUPLING2VTKTYPETRADUCER; + +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[]="???"; @@ -39,31 +41,34 @@ MEDFileMeshStruct *MEDFileMeshStruct::New(const MEDFileMesh *mesh) 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++) + for(std::vector< std::vector >::const_iterator it0=_geo_types_distrib.begin();it0!=_geo_types_distrib.end();it0++) ret+=(*it0).capacity()*sizeof(int); - ret+=_geo_types_distrib.capacity()*sizeof(std::vector); + ret+=_geo_types_distrib.capacity()*sizeof(std::vector); return ret; } -std::vector MEDFileMeshStruct::getDirectChildren() const +std::vector MEDFileMeshStruct::getDirectChildrenWithNull() 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 { int j=0; - for(std::vector< std::vector >::const_iterator it1=_geo_types_distrib.begin();it1!=_geo_types_distrib.end();it1++,j--) + for(std::vector< std::vector >::const_iterator it1=_geo_types_distrib.begin();it1!=_geo_types_distrib.end();it1++,j--) { std::size_t sz=(*it1).size(); if(sz%3!=0) @@ -76,9 +81,12 @@ 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 +/*! + * \sa MEDFileMeshStruct::doesManageGeoType + */ +mcIdType 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++) + 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) @@ -91,6 +99,42 @@ 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]=(mcIdType)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(); @@ -114,7 +158,7 @@ std::size_t MEDMeshMultiLev::getHeapMemorySizeWithoutChildren() const return 0; } -std::vector MEDMeshMultiLev::getDirectChildren() const +std::vector MEDMeshMultiLev::getDirectChildrenWithNull() const { return std::vector(); } @@ -135,7 +179,7 @@ MEDMeshMultiLev *MEDMeshMultiLev::New(const MEDFileMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities) +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 !"); @@ -151,19 +195,27 @@ MEDMeshMultiLev *MEDMeshMultiLev::New(const MEDFileMesh *m, const std::vector levs(1,0); - MEDCouplingAutoRefCountObjectPtr ret(MEDMeshMultiLev::New(m,levs)); + MCAuto ret(MEDMeshMultiLev::New(m,m->getNonEmptyLevels())); ret->selectPartOfNodes(pflOnNode); return ret.retn(); } -void MEDMeshMultiLev::setNodeReduction(const DataArrayInt *nr) +void MEDMeshMultiLev::setNodeReduction(const DataArrayIdType *nr) { if(nr) nr->incrRef(); - _node_reduction=const_cast(nr); + _node_reduction=const_cast(nr); +} + +void MEDMeshMultiLev::setCellReduction(const DataArrayIdType *cr) +{ + if(_pfls.size()!=1) + throw INTERP_KERNEL::Exception("MEDMeshMultiLev::setCellReduction : can be used only for single geo type mesh !"); + _pfls[0]=const_cast(cr); + if(cr) + cr->incrRef(); } bool MEDMeshMultiLev::isFastlyTheSameStruct(const MEDFileField1TSStructItem& fst, const MEDFileFieldGlobsReal *globs) const @@ -174,9 +226,11 @@ bool MEDMeshMultiLev::isFastlyTheSameStruct(const MEDFileField1TSStructItem& fst throw INTERP_KERNEL::Exception("MEDMeshMultiLev::isFastlyTheSameStruct : unexpected situation for nodes !"); const MEDFileField1TSStructItem2& p(fst[0]); std::string pflName(p.getPflName()); - const DataArrayInt *nr(_node_reduction); + const DataArrayIdType *nr(_node_reduction); if(pflName.empty() && !nr) return true; + if(!pflName.empty() && !nr) + return false; if(pflName==nr->getName()) return true; return false; @@ -186,8 +240,8 @@ bool MEDMeshMultiLev::isFastlyTheSameStruct(const MEDFileField1TSStructItem& fst std::size_t sz(fst.getNumberOfItems()); if(sz!=_geo_types.size()) return false; - int strt(0); - for(std::size_t i=0;i ret(const_cast(vals)); ret->incrRef(); + MCAuto ret(const_cast(vals)); ret->incrRef(); if(isFastlyTheSameStruct(fst,globs)) return ret.retn(); else @@ -210,109 +264,98 @@ DataArray *MEDMeshMultiLev::buildDataArray(const MEDFileField1TSStructItem& fst, * \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 +void MEDMeshMultiLev::retrieveFamilyIdsOnCells(DataArrayIdType *& famIds, bool& isWithoutCopy) const { - const DataArrayInt *fids(_cell_fam_ids); + const DataArrayIdType *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 ; } + { famIds=const_cast(fids); famIds->incrRef(); isWithoutCopy=_mesh->isObjectInTheProgeny(famIds); return ; } //bad luck the slowest part isWithoutCopy=false; - std::vector< MEDCouplingAutoRefCountObjectPtr > retSafe(sz); - std::vector< const DataArrayInt *> ret(sz); - int start(0); + std::vector< MCAuto > retSafe(sz); + std::vector< const DataArrayIdType *> ret(sz); + mcIdType start(0); for(std::size_t i=0;i tmp(fids->selectByTupleId2(start,start+lgth,1)); + MCAuto tmp(fids->selectByTupleIdSafeSlice(start,start+lgth,1)); retSafe[i]=tmp->selectByTupleIdSafe(pfl->begin(),pfl->end()); } else { - retSafe[i]=fids->selectByTupleId2(start,start+lgth,1); + retSafe[i]=fids->selectByTupleIdSafeSlice(start,start+lgth,1); } ret[i]=retSafe[i]; start+=lgth; } - famIds=DataArrayInt::Aggregate(ret); + famIds=DataArrayIdType::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 +void MEDMeshMultiLev::retrieveNumberIdsOnCells(DataArrayIdType *& numIds, bool& isWithoutCopy) const { - const DataArrayInt *nids(_cell_num_ids); + const DataArrayIdType *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 ; } + { numIds=const_cast(nids); numIds->incrRef(); isWithoutCopy=_mesh->isObjectInTheProgeny(numIds); return ; } //bad luck the slowest part isWithoutCopy=false; - std::vector< MEDCouplingAutoRefCountObjectPtr > retSafe(sz); - std::vector< const DataArrayInt *> ret(sz); - int start(0); + std::vector< MCAuto > retSafe(sz); + std::vector< const DataArrayIdType *> ret(sz); + mcIdType start(0); for(std::size_t i=0;i tmp(nids->selectByTupleId2(start,start+lgth,1)); + MCAuto tmp(nids->selectByTupleIdSafeSlice(start,start+lgth,1)); retSafe[i]=tmp->selectByTupleIdSafe(pfl->begin(),pfl->end()); } else { - retSafe[i]=nids->selectByTupleId2(start,start+lgth,1); + retSafe[i]=nids->selectByTupleIdSafeSlice(start,start+lgth,1); } ret[i]=retSafe[i]; start+=lgth; } - numIds=DataArrayInt::Aggregate(ret); + numIds=DataArrayIdType::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 +void MEDMeshMultiLev::retrieveFamilyIdsOnNodes(DataArrayIdType *& famIds, bool& isWithoutCopy) const { - const DataArrayInt *fids(_node_fam_ids); + const DataArrayIdType *fids(_node_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=_node_fam_ids_nocpy; return ; } - //bad luck the slowest part - const DataArrayInt *nr(_node_reduction); + const DataArrayIdType *nr(_node_reduction); if(nr) { isWithoutCopy=false; @@ -320,8 +363,8 @@ void MEDMeshMultiLev::retrieveFamilyIdsOnNodes(DataArrayInt *& famIds, bool& isW } else { - isWithoutCopy=_node_fam_ids_nocpy; - famIds=const_cast(fids); famIds->incrRef(); + famIds=const_cast(fids); famIds->incrRef(); + isWithoutCopy=_mesh->isObjectInTheProgeny(famIds); } } @@ -329,23 +372,12 @@ void MEDMeshMultiLev::retrieveFamilyIdsOnNodes(DataArrayInt *& famIds, bool& isW * \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 +void MEDMeshMultiLev::retrieveNumberIdsOnNodes(DataArrayIdType *& numIds, bool& isWithoutCopy) const { - const DataArrayInt *fids(_node_num_ids); + const DataArrayIdType *fids(_node_num_ids); if(!fids) { numIds=0; isWithoutCopy=true; return ; } - std::size_t sz(_geo_types.size()); - bool presenceOfPfls(false); - for(std::size_t i=0;i(fids); numIds->incrRef(); isWithoutCopy=_node_num_ids_nocpy; return ; } - //bad luck the slowest part - const DataArrayInt *nr(_node_reduction); + const DataArrayIdType *nr(_node_reduction); if(nr) { isWithoutCopy=false; @@ -353,41 +385,66 @@ void MEDMeshMultiLev::retrieveNumberIdsOnNodes(DataArrayInt *& numIds, bool& isW } else { - isWithoutCopy=_node_num_ids_nocpy; - numIds=const_cast(fids); numIds->incrRef(); + numIds=const_cast(fids); numIds->incrRef(); + isWithoutCopy=_mesh->isObjectInTheProgeny(numIds); } } -void MEDMeshMultiLev::setFamilyIdsOnCells(DataArrayInt *famIds, bool isNoCopy) +/*! + * This method returns, if any, a new object containing the global node ids **BUT CONTRARY TO OTHER RETRIEVE METHODS** the returned object is always a NON AGGREGATED object. So the returned object if not null + * can be used as this safely. + */ +DataArrayIdType *MEDMeshMultiLev::retrieveGlobalNodeIdsIfAny() const +{ + const MEDFileUMesh *umesh(dynamic_cast(_mesh)); + if(!umesh) + return 0; + const PartDefinition *pd(umesh->getPartDefAtLevel(1)); + if(!pd) + return 0; + MCAuto tmp(pd->toDAI()); + const DataArrayIdType *tmpCpp(tmp); + if(!tmpCpp) + return 0; + // + const DataArrayIdType *nr(_node_reduction); + if(nr) + return tmp->selectByTupleIdSafe(nr->begin(),nr->end()); + else + return tmp->deepCopy();// Yes a deep copy is needed because this method has to return a non aggregated object ! +} + +std::vector< INTERP_KERNEL::NormalizedCellType > MEDMeshMultiLev::getGeoTypes() const +{ + return _geo_types; +} + +void MEDMeshMultiLev::setFamilyIdsOnCells(DataArrayIdType *famIds) { _cell_fam_ids=famIds; if(famIds) famIds->incrRef(); - _cell_fam_ids_nocpy=isNoCopy; } -void MEDMeshMultiLev::setNumberIdsOnCells(DataArrayInt *numIds, bool isNoCopy) +void MEDMeshMultiLev::setNumberIdsOnCells(DataArrayIdType *numIds) { _cell_num_ids=numIds; if(numIds) numIds->incrRef(); - _cell_num_ids_nocpy=isNoCopy; } -void MEDMeshMultiLev::setFamilyIdsOnNodes(DataArrayInt *famIds, bool isNoCopy) +void MEDMeshMultiLev::setFamilyIdsOnNodes(DataArrayIdType *famIds) { _node_fam_ids=famIds; if(famIds) famIds->incrRef(); - _node_fam_ids_nocpy=isNoCopy; } -void MEDMeshMultiLev::setNumberIdsOnNodes(DataArrayInt *numIds, bool isNoCopy) +void MEDMeshMultiLev::setNumberIdsOnNodes(DataArrayIdType *numIds) { _node_num_ids=numIds; if(numIds) numIds->incrRef(); - _node_num_ids_nocpy=isNoCopy; } std::string MEDMeshMultiLev::getPflNameOfId(int id) const @@ -395,7 +452,7 @@ std::string MEDMeshMultiLev::getPflNameOfId(int id) const std::size_t sz(_pfls.size()); if(id<0 || id>=(int)sz) throw INTERP_KERNEL::Exception("MEDMeshMultiLev::getPflNameOfId : invalid input id !"); - const DataArrayInt *pfl(_pfls[id]); + const DataArrayIdType *pfl(_pfls[id]); if(!pfl) return std::string(""); return pfl->getName(); @@ -405,16 +462,16 @@ std::string MEDMeshMultiLev::getPflNameOfId(int id) const * 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 +mcIdType MEDMeshMultiLev::getNumberOfCells(INTERP_KERNEL::NormalizedCellType t) const { std::size_t sz(_nb_entities.size()); for(std::size_t i=0;ideepCpy(); + return vals->deepCopy(); if(pflName.empty() && nr) - throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for nodes 2 !"); + throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for nodes 2 !"); if(!pflName.empty() && nr) { - MEDCouplingAutoRefCountObjectPtr p1(globs->getProfile(pflName.c_str())->deepCpy()); - MEDCouplingAutoRefCountObjectPtr p2(nr->deepCpy()); + MCAuto p1(globs->getProfile(pflName.c_str())->deepCopy()); + MCAuto p2(nr->deepCopy()); p1->sort(true); p2->sort(true); if(!p1->isEqualWithoutConsideringStr(*p2)) - throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for nodes 3 !"); - p1=DataArrayInt::FindPermutationFromFirstToSecond(globs->getProfile(pflName.c_str()),nr); - MEDCouplingAutoRefCountObjectPtr ret(vals->deepCpy()); + throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : it appears that a profile on nodes does not cover the cells correctly !"); + p1=DataArrayIdType::FindPermutationFromFirstToSecond(globs->getProfile(pflName.c_str()),nr); + MCAuto ret(vals->deepCopy()); ret->renumberInPlace(p1->begin()); return ret.retn(); } if(!pflName.empty() && !nr) { - MEDCouplingAutoRefCountObjectPtr p1(globs->getProfile(pflName.c_str())->deepCpy()); + MCAuto p1(globs->getProfile(pflName.c_str())->deepCopy()); p1->sort(true); - if(!p1->isIdentity() || p1->getNumberOfTuples()!=getNumberOfNodes()) + if(!p1->isIota(getNumberOfNodes())) throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for nodes 4 !"); - MEDCouplingAutoRefCountObjectPtr ret(vals->deepCpy()); + MCAuto ret(vals->deepCopy()); ret->renumberInPlace(globs->getProfile(pflName.c_str())->begin()); return ret.retn(); } @@ -463,13 +520,13 @@ DataArray *MEDMeshMultiLev::constructDataArray(const MEDFileField1TSStructItem& 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()); + std::vector< MCAuto > arrSafe(s.size()); int iii(0); - int nc(vals->getNumberOfComponents()); + mcIdType nc(ToIdType(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 DataArrayInt *thisP(_pfls[iii]); + const DataArrayIdType *thisP(_pfls[iii]); std::vector ps; for(std::size_t i=0;igetNbOfIntegrationPts(globs)); - const DataArrayInt *otherP(ps[0]->getPfl(globs)); + const DataArrayIdType *otherP(ps[0]->getPfl(globs)); const std::pair& strtStop(ps[0]->getStartStop()); - MEDCouplingAutoRefCountObjectPtr ret(vals->selectByTupleId2(strtStop.first,strtStop.second,1)); + MCAuto ret(vals->selectByTupleIdSafeSlice(strtStop.first,strtStop.second,1)); if(!thisP && !otherP) { arrSafe[iii]=ret; arr[iii]=ret; @@ -492,10 +549,10 @@ DataArray *MEDMeshMultiLev::constructDataArray(const MEDFileField1TSStructItem& } if(thisP && otherP) { - MEDCouplingAutoRefCountObjectPtr p1(otherP->invertArrayN2O2O2N(getNumberOfCells(ps[0]->getGeo()))); - MEDCouplingAutoRefCountObjectPtr p2(thisP->deepCpy()); + MCAuto p1(otherP->invertArrayN2O2O2N(getNumberOfCells(ps[0]->getGeo()))); + MCAuto p2(thisP->deepCopy()); p2->transformWithIndArr(p1->begin(),p1->end()); - //p1=p2->getIdsNotEqual(-1); + //p1=p2->findIdsNotEqual(-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; @@ -503,10 +560,10 @@ DataArray *MEDMeshMultiLev::constructDataArray(const MEDFileField1TSStructItem& } if(!thisP && otherP) { - MEDCouplingAutoRefCountObjectPtr p1(otherP->deepCpy()); + MCAuto p1(otherP->deepCopy()); p1->sort(true); p1->checkAllIdsInRange(0,getNumberOfCells(ps[0]->getGeo())); - p1=DataArrayInt::FindPermutationFromFirstToSecond(otherP,p1); + p1=DataArrayIdType::FindPermutationFromFirstToSecond(otherP,p1); ret->rearrange(nbi*nc); ret->renumberInPlace(p1->begin()); ret->rearrange(nc); ret->setInfoOnComponents(compInfo); arrSafe[iii]=ret; arr[iii]=ret; continue; @@ -515,47 +572,47 @@ DataArray *MEDMeshMultiLev::constructDataArray(const MEDFileField1TSStructItem& } else { - std::vector< const DataArrayInt * >otherPS(ps.size()); + std::vector< const DataArrayIdType * >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()); + std::vector< MCAuto > arr2Safe(ps.size()); + std::vector< const DataArrayIdType * > nbis(ps.size()); + std::vector< MCAuto > 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 DataArrayIdType *otherPfl((*it2)->getPfl(globs)); const std::pair& strtStop((*it2)->getStartStop()); - MEDCouplingAutoRefCountObjectPtr ret2(vals->selectByTupleId2(strtStop.first,strtStop.second,1)); + MCAuto ret2(vals->selectByTupleIdSafeSlice(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); + nbisSafe[jj]=DataArrayIdType::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; + MCAuto arr3(DataArray::Aggregate(arr2)); + MCAuto otherP(DataArrayIdType::Aggregate(otherPS)); + MCAuto zenbis(DataArrayIdType::Aggregate(nbis)); + MCAuto otherPN(otherP->invertArrayN2O2O2N(getNumberOfCells(*it))); + MCAuto p1; if(thisP) - p1=DataArrayInt::FindPermutationFromFirstToSecond(otherP,thisP); + p1=DataArrayIdType::FindPermutationFromFirstToSecond(otherP,thisP); else - p1=otherP->deepCpy(); - MEDCouplingAutoRefCountObjectPtr zenbisN(zenbis->renumber(p1->begin())); - zenbisN->computeOffsets2(); + p1=otherP->deepCopy(); + MCAuto zenbisN(zenbis->renumber(p1->begin())); + zenbisN->computeOffsetsFull(); 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 DataArrayIdType *otherPfl((*it2)->getPfl(globs)); const std::pair& strtStop((*it2)->getStartStop()); - MEDCouplingAutoRefCountObjectPtr ret2(vals->selectByTupleId2(strtStop.first,strtStop.second,1)); + MCAuto ret2(vals->selectByTupleIdSafeSlice(strtStop.first,strtStop.second,1)); // - MEDCouplingAutoRefCountObjectPtr p2(otherPfl->deepCpy()); + MCAuto p2(otherPfl->deepCopy()); p2->transformWithIndArr(otherPN->begin(),otherPN->end()); p2->transformWithIndArr(p1->begin(),p1->end()); - MEDCouplingAutoRefCountObjectPtr idsN(p2->buildExplicitArrByRanges(zenbisN)); + MCAuto idsN(p2->buildExplicitArrByRanges(zenbisN)); arr3->setPartOfValuesBase3(ret2,idsN->begin(),idsN->end(),0,nc,1); } arrSafe[iii]=arr3; arr[iii]=arr3; @@ -566,11 +623,54 @@ DataArray *MEDMeshMultiLev::constructDataArray(const MEDFileField1TSStructItem& } } -MEDMeshMultiLev::MEDMeshMultiLev():_nb_nodes(0),_cell_fam_ids_nocpy(false) +/*! + * 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 DataArrayIdType *verticesToAdd, DataArrayIdType *nr) { + mcIdType 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 DataArrayIdType *cf(_cell_fam_ids),*cn(_cell_num_ids),*nf(_node_fam_ids),*nn(_node_num_ids); + if(cf) + { + MCAuto tmp; + std::vector a(2); + a[0]=cf; + if(nf) + tmp=nf->selectByTupleIdSafe(verticesToAdd->begin(),verticesToAdd->end()); + else + { + tmp=DataArrayIdType::New(); tmp->alloc(nbOfVertices,1); tmp->fillWithZero(); + } + a[1]=tmp; + _cell_fam_ids=DataArrayIdType::Aggregate(a); + } + if(cn) + { + MCAuto tmp; + std::vector a(2); + a[0]=cn; + if(nn) + tmp=nn->selectByTupleIdSafe(verticesToAdd->begin(),verticesToAdd->end()); + else + { + tmp=DataArrayIdType::New(); tmp->alloc(nbOfVertices,1); tmp->fillWithZero(); + } + a[1]=tmp; + _cell_num_ids=DataArrayIdType::Aggregate(a); + } } -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),_cell_fam_ids_nocpy(false),_cell_num_ids_nocpy(false),_node_fam_ids_nocpy(false),_node_num_ids_nocpy(false) +MEDMeshMultiLev::MEDMeshMultiLev(const MEDFileMesh *mesh):_mesh(mesh),_nb_nodes(0) +{ +} + +MEDMeshMultiLev::MEDMeshMultiLev(const MEDFileMesh *mesh, mcIdType nbNodes, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities):_mesh(mesh),_geo_types(gts),_nb_entities(nbEntities),_nb_nodes(nbNodes) { std::size_t sz(_geo_types.size()); if(sz!=pfls.size() || sz!=nbEntities.size()) @@ -580,11 +680,11 @@ MEDMeshMultiLev::MEDMeshMultiLev(int nbNodes, const std::vectorincrRef(); - _pfls[i]=const_cast(pfls[i]); + _pfls[i]=const_cast(pfls[i]); } } -MEDMeshMultiLev::MEDMeshMultiLev(const MEDMeshMultiLev& other):RefCountObject(other),_pfls(other._pfls),_geo_types(other._geo_types),_nb_entities(other._nb_entities),_node_reduction(other._node_reduction),_nb_nodes(other._nb_nodes),_cell_fam_ids(other._cell_fam_ids),_cell_fam_ids_nocpy(other._cell_fam_ids_nocpy),_cell_num_ids(other._cell_num_ids),_cell_num_ids_nocpy(other._cell_num_ids_nocpy),_node_fam_ids(other._node_fam_ids),_node_fam_ids_nocpy(other._node_fam_ids_nocpy),_node_num_ids(other._node_num_ids),_node_num_ids_nocpy(other._node_num_ids_nocpy) +MEDMeshMultiLev::MEDMeshMultiLev(const MEDMeshMultiLev& other):RefCountObject(other),_mesh(other._mesh),_pfls(other._pfls),_geo_types(other._geo_types),_nb_entities(other._nb_entities),_node_reduction(other._node_reduction),_nb_nodes(other._nb_nodes),_cell_fam_ids(other._cell_fam_ids),_cell_num_ids(other._cell_num_ids),_node_fam_ids(other._node_fam_ids),_node_num_ids(other._node_num_ids) { } @@ -595,7 +695,7 @@ MEDUMeshMultiLev *MEDUMeshMultiLev::New(const MEDFileUMesh *m, const std::vector 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 !"); @@ -606,6 +706,10 @@ 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); @@ -622,19 +726,19 @@ MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDFileUMesh *m, const std::vector _nb_entities[i]=obj->getNumberOfCells(); } // ids fields management - _cell_fam_ids_nocpy=(levs.size()==1); - if(_cell_fam_ids_nocpy) + bool cellFamIdsNoCpy(levs.size()==1); + if(cellFamIdsNoCpy) { - const DataArrayInt *tmp(m->getFamilyFieldAtLevel(levs[0])); + const DataArrayIdType *tmp(m->getFamilyFieldAtLevel(levs[0])); if(tmp) { tmp->incrRef(); - _cell_fam_ids=(const_cast(tmp)); + _cell_fam_ids=(const_cast(tmp)); } } else { - std::vector tmps(levs.size()); + std::vector tmps(levs.size()); bool f(true); for(std::size_t i=0;i if(!tmps[i]) f=false; } - if(f) - _cell_fam_ids=DataArrayInt::Aggregate(tmps); + if(f && !tmps.empty()) + _cell_fam_ids=DataArrayIdType::Aggregate(tmps); } - _cell_num_ids_nocpy=(levs.size()==1); - if(_cell_num_ids_nocpy) + bool cellNumIdsNoCpy(levs.size()==1); + if(cellNumIdsNoCpy) { - const DataArrayInt *tmp(m->getNumberFieldAtLevel(levs[0])); + const DataArrayIdType *tmp(m->getNumberFieldAtLevel(levs[0])); if(tmp) { tmp->incrRef(); - _cell_num_ids=(const_cast(tmp)); + _cell_num_ids=(const_cast(tmp)); } } else { - std::vector tmps(levs.size()); + std::vector tmps(levs.size()); bool n(true); for(std::size_t i=0;i if(!tmps[i]) n=false; } - if(n) - _cell_num_ids=DataArrayInt::Aggregate(tmps); + if(n && !tmps.empty()) + _cell_num_ids=DataArrayIdType::Aggregate(tmps); } // node part - _node_fam_ids_nocpy=true; { - const DataArrayInt *tmp(m->getFamilyFieldAtLevel(1)); + const DataArrayIdType *tmp(m->getFamilyFieldAtLevel(1)); if(tmp) { tmp->incrRef(); - _node_fam_ids=(const_cast(tmp)); + _node_fam_ids=(const_cast(tmp)); } } - _node_num_ids_nocpy=true; { - const DataArrayInt *tmp(m->getNumberFieldAtLevel(1)); + const DataArrayIdType *tmp(m->getNumberFieldAtLevel(1)); if(tmp) { tmp->incrRef(); - _node_num_ids=(const_cast(tmp)); + _node_num_ids=(const_cast(tmp)); } } } -MEDUMeshMultiLev *MEDUMeshMultiLev::New(const MEDFileUMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities) +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) @@ -717,28 +819,23 @@ MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDFileUMesh *m, const std::vectorgetMeshDimension()); if(isSameDim && isNoPfl && m->getGeoTypesAtLevel(lev)==gts)//optimized part { - _cell_fam_ids_nocpy=true; - const DataArrayInt *famIds(m->getFamilyFieldAtLevel(lev)); + const DataArrayIdType *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)); + { _cell_fam_ids=const_cast(famIds); famIds->incrRef(); } + const DataArrayIdType *numIds(m->getNumberFieldAtLevel(lev)); if(numIds) - { _cell_num_ids=const_cast(numIds); numIds->incrRef(); } - _node_fam_ids_nocpy=true; + { _cell_num_ids=const_cast(numIds); numIds->incrRef(); } famIds=m->getFamilyFieldAtLevel(1); if(famIds) - { _node_fam_ids=const_cast(famIds); famIds->incrRef(); } - _node_num_ids_nocpy=true; + { _node_fam_ids=const_cast(famIds); famIds->incrRef(); } numIds=m->getNumberFieldAtLevel(1); if(numIds) - { _node_num_ids=const_cast(numIds); numIds->incrRef(); } + { _node_num_ids=const_cast(numIds); numIds->incrRef(); } return ; } // - _cell_fam_ids_nocpy=false; - std::vector< MEDCouplingAutoRefCountObjectPtr > famIdsSafe(sz); - std::vector famIds(sz); + std::vector< MCAuto > famIdsSafe(sz); + std::vector famIds(sz); bool f(true); for(std::size_t i=0;i > numIdsSafe(sz); - std::vector numIds(sz); + _cell_fam_ids=DataArrayIdType::Aggregate(famIds); + std::vector< MCAuto > numIdsSafe(sz); + std::vector numIds(sz); bool n(true); for(std::size_t i=0;igetFamilyFieldAtLevel(1)); + const DataArrayIdType *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)); + { _node_fam_ids=const_cast(nodeFamIds); nodeFamIds->incrRef(); } + const DataArrayIdType *nodeNumIds(m->getNumberFieldAtLevel(1)); if(nodeNumIds) - { _node_num_ids=const_cast(nodeNumIds); nodeNumIds->incrRef(); } -} - -void MEDUMeshMultiLev::selectPartOfNodes(const DataArrayInt *pflNodes) -{ - if(!pflNodes || !pflNodes->isAllocated()) - return ; - std::size_t sz(_parts.size()); - std::vector< MEDCouplingAutoRefCountObjectPtr > a(sz); - std::vector< const DataArrayInt *> aa(sz); - for(std::size_t i=0;i m(_parts[i]); - if(pfl) - m=dynamic_cast(_parts[i]->buildPartOfMySelfKeepCoords(pfl->begin(),pfl->end())); - DataArrayInt *cellIds=0; - m->fillCellIdsToKeepFromNodeIds(pflNodes->begin(),pflNodes->end(),true,cellIds); - MEDCouplingAutoRefCountObjectPtr cellIdsSafe(cellIds); - MEDCouplingAutoRefCountObjectPtr m2(m->buildPartOfMySelfKeepCoords(cellIds->begin(),cellIds->end())); - int tmp=-1; - 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); - _node_reduction->sort(true); - _node_reduction=_node_reduction->buildUnique(); + { _node_num_ids=const_cast(nodeNumIds); nodeNumIds->incrRef(); } +} + +void MEDUMeshMultiLev::selectPartOfNodes(const DataArrayIdType *pflNodes) +{ + if(!pflNodes || !pflNodes->isAllocated()) + return ; + std::size_t sz(_parts.size()); + std::vector< MCAuto > a(sz); + std::vector< const DataArrayIdType *> aa(sz); + for(std::size_t i=0;i m(_parts[i]); + if(pfl) + m=dynamic_cast(_parts[i]->buildPartOfMySelfKeepCoords(pfl->begin(),pfl->end())); + DataArrayIdType *cellIds=0; + m->fillCellIdsToKeepFromNodeIds(pflNodes->begin(),pflNodes->end(),true,cellIds); + MCAuto cellIdsSafe(cellIds); + MCAuto m2(m->buildPartOfMySelfKeepCoords(cellIds->begin(),cellIds->end())); + mcIdType tmp=-1; + MCAuto 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; + } + if(!aa.empty()) + _node_reduction=DataArrayIdType::Aggregate(aa);//general case + else + _node_reduction=pflNodes->deepCopy();//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... + MCAuto pflNodes2(pflNodes->deepCopy()); + pflNodes2->sort(true); + MCAuto diff(pflNodes2->buildSubstractionOptimized(_node_reduction)); + appendVertices(diff,pflNodes2); } MEDMeshMultiLev *MEDUMeshMultiLev::prepare() const @@ -809,11 +914,11 @@ 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) { } -MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDStructuredMeshMultiLev& other, const MEDCouplingAutoRefCountObjectPtr& part):MEDMeshMultiLev(other) +MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDStructuredMeshMultiLev& other, const MCAuto& part):MEDMeshMultiLev(other) { _parts.resize(1); _parts[0]=part; @@ -823,67 +928,68 @@ MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDStructuredMeshMultiLev& other, const } /*! + * To be called only once ! Because due to some optimizations (sometimes aggressive) the internal state can be changed... * 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 +bool MEDUMeshMultiLev::buildVTUArrays(DataArrayDouble *& coords, DataArrayByte *&types, DataArrayIdType *&cellLocations, DataArrayIdType *& cells, DataArrayIdType *&faceLocations, DataArrayIdType *&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(); - int szBCE(0),szD(0),szF(0); + MCAuto a(const_cast(tmp)); tmp->incrRef(); + mcIdType szBCE(0),szD(0),szF(0); bool isPolyh(false); int iii(0); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_parts.begin();it!=_parts.end();it++,iii++) + for(std::vector< MCAuto >::const_iterator it=_parts.begin();it!=_parts.end();it++,iii++) { const MEDCoupling1GTUMesh *cur(*it); if(!cur) throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::getVTUArrays : a part is null !"); // - const DataArrayInt *pfl(_pfls[iii]); - MEDCouplingAutoRefCountObjectPtr cur2; + const DataArrayIdType *pfl(_pfls[iii]); + MCAuto cur2; if(!pfl) { cur2=const_cast(cur); cur2->incrRef(); } else { cur2=dynamic_cast(cur->buildPartOfMySelfKeepCoords(pfl->begin(),pfl->end())); cur=cur2; } // - int curNbCells(cur->getNumberOfCells()); + mcIdType curNbCells(cur->getNumberOfCells()); szBCE+=curNbCells; if((*it)->getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED) szD+=cur->getNodalConnectivity()->getNumberOfTuples()+curNbCells; else { isPolyh=true; - MEDCouplingAutoRefCountObjectPtr tmp2(cur->computeEffectiveNbOfNodesPerCell()); - szD+=tmp2->accumulate(0)+curNbCells; + MCAuto tmp2(cur->computeEffectiveNbOfNodesPerCell()); + szD+=tmp2->accumulate((std::size_t)0)+curNbCells; szF+=2*curNbCells+cur->getNodalConnectivity()->getNumberOfTuples(); } } - MEDCouplingAutoRefCountObjectPtr b(DataArrayByte::New()); b->alloc(szBCE,1); char *bPtr(b->getPointer()); - MEDCouplingAutoRefCountObjectPtr c(DataArrayInt::New()); c->alloc(szBCE,1); int *cPtr(c->getPointer()); - MEDCouplingAutoRefCountObjectPtr d(DataArrayInt::New()); d->alloc(szD,1); int *dPtr(d->getPointer()); - MEDCouplingAutoRefCountObjectPtr e(DataArrayInt::New()),f(DataArrayInt::New()); int *ePtr(0),*fPtr(0); + MCAuto b(DataArrayByte::New()); b->alloc(szBCE,1); char *bPtr(b->getPointer()); + MCAuto c(DataArrayIdType::New()); c->alloc(szBCE,1); mcIdType *cPtr(c->getPointer()); + MCAuto d(DataArrayIdType::New()); d->alloc(szD,1); mcIdType *dPtr(d->getPointer()); + MCAuto e(DataArrayIdType::New()),f(DataArrayIdType::New()); mcIdType *ePtr(0),*fPtr(0); if(isPolyh) { e->alloc(szBCE,1); ePtr=e->getPointer(); f->alloc(szF,1); fPtr=f->getPointer(); } - int k(0); + mcIdType k(0); iii=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_parts.begin();it!=_parts.end();it++,iii++) + for(std::vector< MCAuto >::const_iterator it=_parts.begin();it!=_parts.end();it++,iii++) { const MEDCoupling1GTUMesh *cur(*it); // - const DataArrayInt *pfl(_pfls[iii]); - MEDCouplingAutoRefCountObjectPtr cur2; + const DataArrayIdType *pfl(_pfls[iii]); + MCAuto cur2; if(!pfl) { cur2=const_cast(cur); cur2->incrRef(); } else { cur2=dynamic_cast(cur->buildPartOfMySelfKeepCoords(pfl->begin(),pfl->end())); cur=cur2; } // - int curNbCells(cur->getNumberOfCells()); + mcIdType curNbCells(cur->getNumberOfCells()); int gt((int)cur->getCellModelEnum()); if(gt<0 || gt>=PARAMEDMEM_2_VTKTYPE_LGTH) throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::getVTUArrays : invalid geometric type !"); @@ -893,41 +999,54 @@ bool MEDUMeshMultiLev::buildVTUArrays(DataArrayDouble *& coords, DataArrayByte * std::fill(bPtr,bPtr+curNbCells,gtvtk); bPtr+=curNbCells; const MEDCoupling1SGTUMesh *scur(dynamic_cast(cur)); const MEDCoupling1DGTUMesh *dcur(dynamic_cast(cur)); - const int *connPtr(cur->getNodalConnectivity()->begin()); + const mcIdType *connPtr(cur->getNodalConnectivity()->begin()); if(!scur && !dcur) throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::getVTUArrays : internal error !"); if(scur) { - int nnpc(scur->getNumberOfNodesPerCell()); - for(int i=0;igetCellModelEnum()!=INTERP_KERNEL::NORM_HEXA27) + { + mcIdType nnpc(scur->getNumberOfNodesPerCell()); + for(mcIdType i=0;igetNodalConnectivityIndex()->begin()); + const mcIdType *connIPtr(dcur->getNodalConnectivityIndex()->begin()); if(cur->getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED) { for(int i=0;i s(connPtr+connIPtr[0],connPtr+connIPtr[1]); s.erase(-1); - *dPtr++=(int)s.size(); + std::set s(connPtr+connIPtr[0],connPtr+connIPtr[1]); s.erase(-1); + *dPtr++=(mcIdType)s.size(); dPtr=std::copy(s.begin(),s.end(),dPtr); - *cPtr++=k; k+=(int)s.size()+1; + *cPtr++=k; k+=(mcIdType)s.size()+1; } } if(isPolyh) @@ -937,16 +1056,16 @@ bool MEDUMeshMultiLev::buildVTUArrays(DataArrayDouble *& coords, DataArrayByte * { std::fill(ePtr,ePtr+curNbCells,-1); ePtr+=curNbCells; } else { - int kk(0); + mcIdType kk(0); for(int i=0;iisObjectInTheProgeny(coords); } -void MEDUMeshMultiLev::reorderNodesIfNecessary(MEDCouplingAutoRefCountObjectPtr& coords, DataArrayInt *nodalConnVTK, DataArrayInt *polyhedNodalConnVTK) const +void MEDUMeshMultiLev::reorderNodesIfNecessary(MCAuto& coords, DataArrayIdType *nodalConnVTK, DataArrayIdType *polyhedNodalConnVTK) const { - const DataArrayInt *nr(_node_reduction); + const DataArrayIdType *nr(_node_reduction); if(!nr) return ; - int sz(coords->getNumberOfTuples()); + if(nodalConnVTK->empty() && !polyhedNodalConnVTK) + { + coords=(coords->selectByTupleIdSafe(nr->begin(),nr->end())); + return ; + } + mcIdType sz(coords->getNumberOfTuples()); std::vector b(sz,false); - const int *work(nodalConnVTK->begin()),*endW(nodalConnVTK->end()); + const mcIdType *work(nodalConnVTK->begin()),*endW(nodalConnVTK->end()); while(work!=endW) { - int nb(*work++); - for(int i=0;i=0 && *workbegin(); endW=polyhedNodalConnVTK->end(); while(work!=endW) { - int nb(*work++); - for(int i=0;i=0 && *workgetNumberOfTuples()) + std::size_t szExp(std::count(b.begin(),b.end(),true)); + if(ToIdType(szExp)!=nr->getNumberOfTuples()) throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::reorderNodesIfNecessary : internal error #3 !"); // Go renumbering ! - MEDCouplingAutoRefCountObjectPtr o2n(DataArrayInt::New()); o2n->alloc(sz,1); - int *o2nPtr(o2n->getPointer()); + MCAuto o2n(DataArrayIdType::New()); o2n->alloc(sz,1); + mcIdType *o2nPtr(o2n->getPointer()); int newId(0); for(int i=0;ibegin()); - MEDCouplingAutoRefCountObjectPtr n2o(o2n->invertArrayO2N2N2O(nr->getNumberOfTuples())); - MEDCouplingAutoRefCountObjectPtr perm(DataArrayInt::FindPermutationFromFirstToSecond(n2o,nr)); - const int *permPtr(perm->begin()); - int *work2(nodalConnVTK->getPointer()),*endW2(nodalConnVTK->getPointer()+nodalConnVTK->getNumberOfTuples()); + const mcIdType *o2nPtrc(o2n->begin()); + MCAuto n2o(o2n->invertArrayO2N2N2O(nr->getNumberOfTuples())); + MCAuto perm(DataArrayIdType::FindPermutationFromFirstToSecond(n2o,nr)); + const mcIdType *permPtr(perm->begin()); + mcIdType *work2(nodalConnVTK->getPointer()),*endW2(nodalConnVTK->getPointer()+nodalConnVTK->getNumberOfTuples()); while(work2!=endW2) { - int nb(*work2++); - for(int i=0;igetPointer(); endW2=polyhedNodalConnVTK->getPointer()+polyhedNodalConnVTK->getNumberOfTuples(); while(work2!=endW2) { - int nb(*work2++); - for(int i=0;iselectByTupleIdSafe(nr->begin(),nr->end())); } + +void MEDUMeshMultiLev::appendVertices(const DataArrayIdType *verticesToAdd, DataArrayIdType *nr) +{ + mcIdType nbOfCells(verticesToAdd->getNumberOfTuples());//it is not a bug cells are NORM_POINT1 + MEDMeshMultiLev::appendVertices(verticesToAdd,nr); + MCAuto elt(MEDCoupling1SGTUMesh::New("",INTERP_KERNEL::NORM_POINT1)); + elt->allocateCells(nbOfCells); + for(mcIdType 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()); + MCAuto elt2((MEDCoupling1SGTUMesh *)elt); elt2->incrRef(); + _parts.push_back(elt2); +} + //= -MEDStructuredMeshMultiLev::MEDStructuredMeshMultiLev() +MEDStructuredMeshMultiLev::MEDStructuredMeshMultiLev(const MEDFileStructuredMesh *m, const std::vector& lev):MEDMeshMultiLev(m),_is_internal(true) +{ + initStdFieldOfIntegers(m); +} + +MEDStructuredMeshMultiLev::MEDStructuredMeshMultiLev(const MEDFileStructuredMesh *m, mcIdType nbOfNodes, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities):MEDMeshMultiLev(m,nbOfNodes,gts,pfls,nbEntities),_is_internal(true) +{ + initStdFieldOfIntegers(m); +} + +MEDStructuredMeshMultiLev::MEDStructuredMeshMultiLev(const MEDStructuredMeshMultiLev& other):MEDMeshMultiLev(other),_is_internal(true),_face_fam_ids(other._face_fam_ids),_face_num_ids(other._face_num_ids) { } -MEDStructuredMeshMultiLev::MEDStructuredMeshMultiLev(const MEDFileStructuredMesh *m, const std::vector& lev) +void MEDStructuredMeshMultiLev::initStdFieldOfIntegers(const MEDFileStructuredMesh *m) { // ids fields management - _cell_fam_ids_nocpy=true; _cell_num_ids_nocpy=true; - const DataArrayInt *tmp(0); + const DataArrayIdType *tmp(0); tmp=m->getFamilyFieldAtLevel(0); if(tmp) { tmp->incrRef(); - _cell_fam_ids=const_cast(tmp); + _cell_fam_ids=const_cast(tmp); } tmp=m->getNumberFieldAtLevel(0); if(tmp) { tmp->incrRef(); - _cell_num_ids=const_cast(tmp); + _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); + _node_fam_ids=const_cast(tmp); } tmp=m->getNumberFieldAtLevel(1); if(tmp) { tmp->incrRef(); - _node_num_ids=const_cast(tmp); + _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(nbOfNodes,gts,pfls,nbEntities) -{ - // ids fields management - _cell_fam_ids_nocpy=true; _cell_num_ids_nocpy=true; - const DataArrayInt *tmp(0); - tmp=m->getFamilyFieldAtLevel(0); + // faces (if any) + tmp=m->getFamilyFieldAtLevel(-1); if(tmp) { tmp->incrRef(); - _cell_fam_ids=const_cast(tmp); + _face_fam_ids=const_cast(tmp); } - tmp=m->getNumberFieldAtLevel(0); + tmp=m->getNumberFieldAtLevel(-1); if(tmp) { tmp->incrRef(); - _cell_num_ids=const_cast(tmp); + _face_num_ids=const_cast(tmp); } - // - _node_fam_ids_nocpy=true; _node_num_ids_nocpy=true; - tmp=0; - tmp=m->getFamilyFieldAtLevel(1); +} + +void MEDStructuredMeshMultiLev::moveFaceToCell() const +{ + const_cast(this)->_cell_fam_ids=_face_fam_ids; const_cast(this)->_face_fam_ids=0; + const_cast(this)->_cell_num_ids=_face_num_ids; const_cast(this)->_face_num_ids=0; +} + +bool MEDStructuredMeshMultiLev::prepareForImplicitUnstructuredMeshCase(MEDMeshMultiLev *&ret) const +{ + ret=0; + if(_geo_types.empty()) + return false; + if(_geo_types.size()!=1) + throw INTERP_KERNEL::Exception("MEDStructuredMeshMultiLev::prepareForImplicitUnstructuredMeshCase only one geo types supported at most supported for the moment !"); + INTERP_KERNEL::NormalizedCellType gt(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(_mesh->getMeshDimension())); + if(_geo_types[0]==gt) + return false; + MEDCoupling1GTUMesh *facesIfPresent((static_cast(_mesh))->getImplicitFaceMesh()); + if(!facesIfPresent) + return false; + const DataArrayIdType *pfl(0),*nr(_node_reduction); + if(!_pfls.empty()) + pfl=_pfls[0]; + MCAuto facesIfPresent2(facesIfPresent); facesIfPresent->incrRef(); + moveFaceToCell(); + MCAuto ret2(new MEDUMeshMultiLev(*this,facesIfPresent2)); + if(pfl) + ret2->setCellReduction(pfl); + 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) +{ + const DataArrayIdType *tmp(0); + tmp=m->getFamilyFieldAtLevel(-1); if(tmp) { tmp->incrRef(); - _node_fam_ids=const_cast(tmp); + _cell_fam_ids=const_cast(tmp); } - tmp=m->getNumberFieldAtLevel(1); + tmp=m->getNumberFieldAtLevel(-1); if(tmp) { tmp->incrRef(); - _node_num_ids=const_cast(tmp); + _cell_num_ids=const_cast(tmp); } } -void MEDStructuredMeshMultiLev::selectPartOfNodes(const DataArrayInt *pflNodes) +void MEDStructuredMeshMultiLev::selectPartOfNodes(const DataArrayIdType *pflNodes) { if(!pflNodes || !pflNodes->isAllocated()) return ; - std::vector ngs(getNodeGridStructure()); - MEDCouplingAutoRefCountObjectPtr conn(MEDCouplingStructuredMesh::Build1GTNodalConnectivity(&ngs[0],&ngs[0]+ngs.size())); - MEDCouplingAutoRefCountObjectPtr m(MEDCoupling1SGTUMesh::New("",MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(ngs.size()))); + std::vector ngs(getNodeGridStructure()); + MCAuto conn(MEDCouplingStructuredMesh::Build1GTNodalConnectivity(&ngs[0],&ngs[0]+ngs.size())); + MCAuto m(MEDCoupling1SGTUMesh::New("",MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension((int)ngs.size()))); m->setNodalConnectivity(conn); - const DataArrayInt *pfl(_pfls[0]); + const DataArrayIdType *pfl(_pfls[0]); if(pfl) { m=dynamic_cast(m->buildPartOfMySelfKeepCoords(pfl->begin(),pfl->end())); } - DataArrayInt *cellIds=0; + DataArrayIdType *cellIds=0; m->fillCellIdsToKeepFromNodeIds(pflNodes->begin(),pflNodes->end(),true,cellIds); - MEDCouplingAutoRefCountObjectPtr cellIdsSafe(cellIds); - MEDCouplingAutoRefCountObjectPtr m2(m->buildPartOfMySelfKeepCoords(cellIds->begin(),cellIds->end())); - int tmp=-1; + MCAuto cellIdsSafe(cellIds); + MCAuto m2(m->buildPartOfMySelfKeepCoords(cellIds->begin(),cellIds->end())); + mcIdType tmp=-1; _node_reduction=m2->getNodeIdsInUse(tmp); if(pfl) _pfls[0]=pfl->selectByTupleIdSafe(cellIds->begin(),cellIds->end()); @@ -1144,10 +1324,6 @@ 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) @@ -1155,7 +1331,7 @@ MEDCMeshMultiLev *MEDCMeshMultiLev::New(const MEDFileCMesh *m, const std::vector return new MEDCMeshMultiLev(m,levs); } -MEDCMeshMultiLev *MEDCMeshMultiLev::New(const MEDFileCMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities) +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); } @@ -1166,44 +1342,48 @@ MEDCMeshMultiLev::MEDCMeshMultiLev(const MEDFileCMesh *m, const std::vector 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,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 !"); if(gts.size()!=1 || pfls.size()!=1) - throw INTERP_KERNEL::Exception("MEDCMeshMultiLev constructor 2 : lengthes of gts and pfls must be equal to one !"); + throw INTERP_KERNEL::Exception("MEDCMeshMultiLev constructor 2 : lengths of gts and pfls must be equal to one !"); int mdim(m->getMeshDimension()); 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 +std::vector MEDCMeshMultiLev::getNodeGridStructure() const { - std::vector ret(_coords.size()); + std::vector ret(_coords.size()); for(std::size_t i=0;i<_coords.size();i++) ret[i]=_coords[i]->getNumberOfTuples(); return ret; @@ -1211,65 +1391,75 @@ std::vector MEDCMeshMultiLev::getNodeGridStructure() const MEDMeshMultiLev *MEDCMeshMultiLev::prepare() const { - const DataArrayInt *pfl(_pfls[0]),*nr(_node_reduction); - MEDCouplingAutoRefCountObjectPtr nnr; - std::vector cgs,ngs(getNodeGridStructure()); + MEDMeshMultiLev *retSpecific(0); + if(prepareForImplicitUnstructuredMeshCase(retSpecific)) + return retSpecific; + const DataArrayIdType *pfl(0),*nr(_node_reduction); + if(!_pfls.empty()) + pfl=_pfls[0]; + MCAuto nnr; + std::vector cgs,ngs(getNodeGridStructure()); cgs.resize(ngs.size()); - std::transform(ngs.begin(),ngs.end(),cgs.begin(),std::bind2nd(std::plus(),-1)); + std::transform(ngs.begin(),ngs.end(),cgs.begin(),std::bind(std::plus(),std::placeholders::_1,-1)); if(pfl) { - std::vector< std::pair > cellParts; - MEDCouplingAutoRefCountObjectPtr ret2; + std::vector< std::pair > cellParts; + MCAuto ret2; if(MEDCouplingStructuredMesh::IsPartStructured(pfl->begin(),pfl->end(),cgs,cellParts)) { - MEDCouplingAutoRefCountObjectPtr ret(new MEDCMeshMultiLev(*this)); + MCAuto ret(new MEDCMeshMultiLev(*this)); + ret->_is_internal=false; if(nr) - { nnr=nr->deepCpy(); nnr->sort(true); ret->setNodeReduction(nnr); } + { nnr=nr->deepCopy(); nnr->sort(true); ret->setNodeReduction(nnr); } ret->_nb_entities[0]=pfl->getNumberOfTuples(); ret->_pfls[0]=0; - std::vector< MEDCouplingAutoRefCountObjectPtr > coords(_coords.size()); + std::vector< MCAuto > coords(_coords.size()); for(std::size_t i=0;i<_coords.size();i++) - coords[i]=_coords[i]->selectByTupleId2(cellParts[i].first,cellParts[i].second+1,1); + coords[i]=_coords[i]->selectByTupleIdSafeSlice(cellParts[i].first,cellParts[i].second+1,1); ret->_coords=coords; ret2=(MEDCMeshMultiLev *)ret; ret2->incrRef(); } else { - MEDCouplingAutoRefCountObjectPtr m(MEDCouplingCMesh::New()); - for(std::size_t i=0;i m(MEDCouplingCMesh::New()); + for(unsigned int i=0;isetCoordsAt(i,_coords[i]); - MEDCouplingAutoRefCountObjectPtr m2(m->build1SGTUnstructured()); - MEDCouplingAutoRefCountObjectPtr m3=dynamic_cast(m2->buildPartOfMySelfKeepCoords(pfl->begin(),pfl->end())); - MEDCouplingAutoRefCountObjectPtr ret(new MEDUMeshMultiLev(*this,m3)); + MCAuto m2(m->build1SGTUnstructured()); + MCAuto m3=dynamic_cast(m2->buildPartOfMySelfKeepCoords(pfl->begin(),pfl->end())); + MCAuto ret(new MEDUMeshMultiLev(*this,m3)); if(nr) - { m3->zipCoords(); nnr=nr->deepCpy(); nnr->sort(true); ret->setNodeReduction(nnr); } + { m3->zipCoords(); nnr=nr->deepCopy(); nnr->sort(true); ret->setNodeReduction(nnr); } ret2=(MEDUMeshMultiLev *)ret; ret2->incrRef(); } - const DataArrayInt *famIds(_cell_fam_ids),*numIds(_cell_num_ids); + const DataArrayIdType *famIds(_cell_fam_ids),*numIds(_cell_num_ids); if(famIds) { - MEDCouplingAutoRefCountObjectPtr tmp(famIds->selectByTupleIdSafe(pfl->begin(),pfl->end())); - ret2->setFamilyIdsOnCells(tmp,false); + MCAuto tmp(famIds->selectByTupleIdSafe(pfl->begin(),pfl->end())); + ret2->setFamilyIdsOnCells(tmp); } if(numIds) { - MEDCouplingAutoRefCountObjectPtr tmp(numIds->selectByTupleIdSafe(pfl->begin(),pfl->end())); - ret2->setNumberIdsOnCells(tmp,false); + MCAuto tmp(numIds->selectByTupleIdSafe(pfl->begin(),pfl->end())); + ret2->setNumberIdsOnCells(tmp); } return ret2.retn(); - + } else { - MEDCouplingAutoRefCountObjectPtr ret(new MEDCMeshMultiLev(*this)); + MCAuto ret(new MEDCMeshMultiLev(*this)); if(nr) - { nnr=nr->deepCpy(); nnr->sort(true); ret->setNodeReduction(nnr); } + { nnr=nr->deepCopy(); nnr->sort(true); ret->setNodeReduction(nnr); } return ret.retn(); } } -std::vector< DataArrayDouble * > MEDCMeshMultiLev::buildVTUArrays() const +/*! + * \a param [out] isInternal if true the returned pointers are those in main data structure. If false those pointers have been built especially 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& gts, const std::vector& pfls, const std::vector& nbEntities) +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); } @@ -1306,56 +1496,65 @@ 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,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(); + throw INTERP_KERNEL::Exception("MEDCurveLinearMeshMultiLev constructor 2 : lengths of gts and pfls must be equal to one !"); + 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 +std::vector MEDCurveLinearMeshMultiLev::getNodeGridStructure() const { return _structure; } MEDMeshMultiLev *MEDCurveLinearMeshMultiLev::prepare() const { - const DataArrayInt *pfl(_pfls[0]),*nr(_node_reduction); - MEDCouplingAutoRefCountObjectPtr nnr; - std::vector cgs,ngs(getNodeGridStructure()); + MEDMeshMultiLev *retSpecific(0); + if(prepareForImplicitUnstructuredMeshCase(retSpecific)) + return retSpecific; + const DataArrayIdType *pfl(0),*nr(_node_reduction); + if(!_pfls.empty()) + pfl=_pfls[0]; + MCAuto nnr; + std::vector cgs,ngs(getNodeGridStructure()); cgs.resize(ngs.size()); - std::transform(ngs.begin(),ngs.end(),cgs.begin(),std::bind2nd(std::plus(),-1)); + std::transform(ngs.begin(),ngs.end(),cgs.begin(),std::bind(std::plus(),std::placeholders::_1,-1)); if(pfl) { - std::vector< std::pair > cellParts,nodeParts; - MEDCouplingAutoRefCountObjectPtr ret2; + std::vector< std::pair > cellParts,nodeParts; + MCAuto ret2; if(MEDCouplingStructuredMesh::IsPartStructured(pfl->begin(),pfl->end(),cgs,cellParts)) { nodeParts=cellParts; - std::vector st(ngs.size()); + std::vector st(ngs.size()); for(std::size_t i=0;i p(MEDCouplingStructuredMesh::BuildExplicitIdsFrom(ngs,nodeParts)); - MEDCouplingAutoRefCountObjectPtr ret(new MEDCurveLinearMeshMultiLev(*this)); + MCAuto p(MEDCouplingStructuredMesh::BuildExplicitIdsFrom(ngs,nodeParts)); + MCAuto ret(new MEDCurveLinearMeshMultiLev(*this)); + ret->_is_internal=false; if(nr) - { nnr=nr->deepCpy(); nnr->sort(true); ret->setNodeReduction(nnr); } + { nnr=nr->deepCopy(); nnr->sort(true); ret->setNodeReduction(nnr); } ret->_nb_entities[0]=pfl->getNumberOfTuples(); ret->_pfls[0]=0; ret->_coords=_coords->selectByTupleIdSafe(p->begin(),p->end()); @@ -1364,39 +1563,40 @@ MEDMeshMultiLev *MEDCurveLinearMeshMultiLev::prepare() const } else { - MEDCouplingAutoRefCountObjectPtr m(MEDCouplingCurveLinearMesh::New()); + MCAuto m(MEDCouplingCurveLinearMesh::New()); m->setCoords(_coords); m->setNodeGridStructure(&_structure[0],&_structure[0]+_structure.size()); - MEDCouplingAutoRefCountObjectPtr m2(m->build1SGTUnstructured()); - MEDCouplingAutoRefCountObjectPtr m3=dynamic_cast(m2->buildPartOfMySelfKeepCoords(pfl->begin(),pfl->end())); - MEDCouplingAutoRefCountObjectPtr ret(new MEDUMeshMultiLev(*this,m3)); + MCAuto m2(m->build1SGTUnstructured()); + MCAuto m3=dynamic_cast(m2->buildPartOfMySelfKeepCoords(pfl->begin(),pfl->end())); + MCAuto ret(new MEDUMeshMultiLev(*this,m3)); if(nr) - { m3->zipCoords(); nnr=nr->deepCpy(); nnr->sort(true); ret->setNodeReduction(nnr); } + { m3->zipCoords(); nnr=nr->deepCopy(); nnr->sort(true); ret->setNodeReduction(nnr); } ret2=(MEDUMeshMultiLev *)ret; ret2->incrRef(); } - const DataArrayInt *famIds(_cell_fam_ids),*numIds(_cell_num_ids); + const DataArrayIdType *famIds(_cell_fam_ids),*numIds(_cell_num_ids); if(famIds) { - MEDCouplingAutoRefCountObjectPtr tmp(famIds->selectByTupleIdSafe(pfl->begin(),pfl->end())); - ret2->setFamilyIdsOnCells(tmp,false); + MCAuto tmp(famIds->selectByTupleIdSafe(pfl->begin(),pfl->end())); + ret2->setFamilyIdsOnCells(tmp); } if(numIds) { - MEDCouplingAutoRefCountObjectPtr tmp(numIds->selectByTupleIdSafe(pfl->begin(),pfl->end())); - ret2->setNumberIdsOnCells(tmp,false); + MCAuto tmp(numIds->selectByTupleIdSafe(pfl->begin(),pfl->end())); + ret2->setNumberIdsOnCells(tmp); } return ret2.retn(); } else { - MEDCouplingAutoRefCountObjectPtr ret(new MEDCurveLinearMeshMultiLev(*this)); + MCAuto ret(new MEDCurveLinearMeshMultiLev(*this)); if(nr) - { nnr=nr->deepCpy(); nnr->sort(true); ret->setNodeReduction(nnr); } + { nnr=nr->deepCopy(); nnr->sort(true); ret->setNodeReduction(nnr); } return ret.retn(); } } -void MEDCurveLinearMeshMultiLev::buildVTUArrays(DataArrayDouble *&coords, std::vector& nodeStrct) const +void MEDCurveLinearMeshMultiLev::buildVTUArrays(DataArrayDouble *&coords, std::vector& nodeStrct, bool& isInternal) const { + isInternal=_is_internal; nodeStrct=_structure; const DataArrayDouble *coo(_coords); if(!coo) @@ -1410,20 +1610,25 @@ MEDFileField1TSStructItem2::MEDFileField1TSStructItem2() { } -MEDFileField1TSStructItem2::MEDFileField1TSStructItem2(INTERP_KERNEL::NormalizedCellType a, const std::pair& b, const std::string& c, const std::string& d):_geo_type(a),_start_end(b),_pfl(DataArrayInt::New()),_loc(d),_nb_of_entity(-1) +MEDFileField1TSStructItem2::MEDFileField1TSStructItem2(INTERP_KERNEL::NormalizedCellType a, const std::pair& b, const std::string& c, const std::string& d):_geo_type(a),_start_end(b),_pfl(DataArrayIdType::New()),_loc(d),_nb_of_entity(-1) { _pfl->setName(c.c_str()); } void MEDFileField1TSStructItem2::checkWithMeshStructForCells(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) { - int nbOfEnt=mst->getNumberOfElemsOfGeoType(_geo_type); + if(!mst->doesManageGeoType(_geo_type)) + { + MEDFileMeshStruct *mstUnConstCasted(const_cast(mst)); + mstUnConstCasted->appendIfImplicitType(_geo_type); + } + mcIdType nbOfEnt=mst->getNumberOfElemsOfGeoType(_geo_type); checkInRange(nbOfEnt,1,globs); } void MEDFileField1TSStructItem2::checkWithMeshStructForGaussNE(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) { - int nbOfEnt=mst->getNumberOfElemsOfGeoType(_geo_type); + mcIdType nbOfEnt=mst->getNumberOfElemsOfGeoType(_geo_type); const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_geo_type); checkInRange(nbOfEnt,(int)cm.getNumberOfNodes(),globs); } @@ -1435,7 +1640,7 @@ void MEDFileField1TSStructItem2::checkWithMeshStructForGaussPT(const MEDFileMesh if(_loc.empty()) throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::checkWithMeshStructForGaussPT : no localization specified !"); const MEDFileFieldLoc& loc=globs->getLocalization(_loc.c_str()); - int nbOfEnt=mst->getNumberOfElemsOfGeoType(_geo_type); + mcIdType nbOfEnt=mst->getNumberOfElemsOfGeoType(_geo_type); checkInRange(nbOfEnt,loc.getNumberOfGaussPoints(),globs); } @@ -1444,9 +1649,9 @@ int MEDFileField1TSStructItem2::getNbOfIntegrationPts(const MEDFileFieldGlobsRea if(_loc.empty()) { if(getPflName().empty()) - return (_start_end.second-_start_end.first)/_nb_of_entity; + return (int)((_start_end.second-_start_end.first)/_nb_of_entity); else - return (_start_end.second-_start_end.first)/getPfl(globs)->getNumberOfTuples(); + return (int)((_start_end.second-_start_end.first)/getPfl(globs)->getNumberOfTuples()); } else { @@ -1460,7 +1665,7 @@ std::string MEDFileField1TSStructItem2::getPflName() const return _pfl->getName(); } -const DataArrayInt *MEDFileField1TSStructItem2::getPfl(const MEDFileFieldGlobsReal *globs) const +const DataArrayIdType *MEDFileField1TSStructItem2::getPfl(const MEDFileFieldGlobsReal *globs) const { if(!_pfl->isAllocated()) { @@ -1474,30 +1679,30 @@ const DataArrayInt *MEDFileField1TSStructItem2::getPfl(const MEDFileFieldGlobsRe } /*! - * \param [in] nbOfEntity - number of entity that can be either cells or nodes. Not other possiblity. + * \param [in] nbOfEntity - number of entity that can be either cells or nodes. Not other possibility. * \param [in] nip - number of integration points. 1 for ON_CELLS and NO_NODES */ -void MEDFileField1TSStructItem2::checkInRange(int nbOfEntity, int nip, const MEDFileFieldGlobsReal *globs) +void MEDFileField1TSStructItem2::checkInRange(mcIdType nbOfEntity, int nip, const MEDFileFieldGlobsReal *globs) { _nb_of_entity=nbOfEntity; if(_pfl->getName().empty()) { if(nbOfEntity!=(_start_end.second-_start_end.first)/nip) - throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::checkInRange : Mismatch between number of entities and size of node field !"); + throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::checkInRange : Mismatch between number of entities and size of field !"); return ; } else { if(!globs) throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::checkInRange : Presence of a profile on field whereas no globals found in file !"); - const DataArrayInt *pfl=globs->getProfile(_pfl->getName().c_str()); + const DataArrayIdType *pfl=globs->getProfile(_pfl->getName().c_str()); if(!pfl) throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::checkInRange : Presence of a profile on field whereas no such profile found in file !"); pfl->checkAllIdsInRange(0,nbOfEntity); } } -bool MEDFileField1TSStructItem2::isFastlyEqual(int& startExp, INTERP_KERNEL::NormalizedCellType gt, const char *pflName) const +bool MEDFileField1TSStructItem2::isFastlyEqual(mcIdType& startExp, INTERP_KERNEL::NormalizedCellType gt, const std::string& pflName) const { if(startExp!=_start_end.first) return false; @@ -1509,7 +1714,7 @@ bool MEDFileField1TSStructItem2::isFastlyEqual(int& startExp, INTERP_KERNEL::Nor return true; } -bool MEDFileField1TSStructItem2::operator==(const MEDFileField1TSStructItem2& other) const throw(INTERP_KERNEL::Exception) +bool MEDFileField1TSStructItem2::operator==(const MEDFileField1TSStructItem2& other) const { //_nb_of_entity is not taken into account here. It is not a bug, because no mesh consideration needed here to perform fast compare. //idem for _loc. It is not an effective attribute for support comparison. @@ -1526,7 +1731,7 @@ bool MEDFileField1TSStructItem2::isCellSupportEqual(const MEDFileField1TSStructI return false; if(_pfl->getName().empty() && other._pfl->getName().empty()) return true; - const DataArrayInt *pfl1(getPfl(globs)),*pfl2(other.getPfl(globs)); + const DataArrayIdType *pfl1(getPfl(globs)),*pfl2(other.getPfl(globs)); return pfl1->isEqualWithoutConsideringStr(*pfl2); } @@ -1545,9 +1750,9 @@ MEDFileField1TSStructItem2 MEDFileField1TSStructItem2::BuildAggregationOf(const if(objs.size()==1) return MEDFileField1TSStructItem2(*objs[0]); INTERP_KERNEL::NormalizedCellType gt(objs[0]->_geo_type); - int nbEntityRef(objs[0]->_nb_of_entity); + mcIdType nbEntityRef(objs[0]->_nb_of_entity); std::size_t sz(objs.size()); - std::vector arrs(sz); + std::vector arrs(sz); for(std::size_t i=0;igetProfile(obj->_pfl->getName().c_str()); } - MEDCouplingAutoRefCountObjectPtr arr(DataArrayInt::Aggregate(arrs)); + MCAuto arr(DataArrayIdType::Aggregate(arrs)); arr->sort(); - int oldNbTuples(arr->getNumberOfTuples()); + mcIdType oldNbTuples(arr->getNumberOfTuples()); arr=arr->buildUnique(); if(oldNbTuples!=arr->getNumberOfTuples()) throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::BuildAggregationOf : some entities are present several times !"); - if(arr->isIdentity() && oldNbTuples==nbEntityRef) + if(arr->isIota(nbEntityRef)) { - std::pair p(0,nbEntityRef); + std::pair p(0,nbEntityRef); std::string a,b; MEDFileField1TSStructItem2 ret(gt,p,a,b); ret._nb_of_entity=nbEntityRef; @@ -1576,7 +1781,7 @@ MEDFileField1TSStructItem2 MEDFileField1TSStructItem2::BuildAggregationOf(const else { arr->setName(NEWLY_CREATED_PFL_NAME); - std::pair p(0,oldNbTuples); + std::pair p(0,oldNbTuples); std::string a,b; MEDFileField1TSStructItem2 ret(gt,p,a,b); ret._nb_of_entity=nbEntityRef; @@ -1591,12 +1796,10 @@ std::size_t MEDFileField1TSStructItem2::getHeapMemorySizeWithoutChildren() const return ret; } -std::vector MEDFileField1TSStructItem2::getDirectChildren() const +std::vector MEDFileField1TSStructItem2::getDirectChildrenWithNull() const { std::vector ret; - const DataArrayInt *pfl(_pfl); - if(pfl) - ret.push_back(pfl); + ret.push_back((const DataArrayIdType *)_pfl); return ret; } @@ -1609,10 +1812,10 @@ MEDFileField1TSStructItem::MEDFileField1TSStructItem(TypeOfField a, const std::v void MEDFileField1TSStructItem::checkWithMeshStruct(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) { switch(_type) - { + { case ON_NODES: { - int nbOfEnt=mst->getNumberOfNodes(); + mcIdType nbOfEnt=mst->getNumberOfNodes(); if(_items.size()!=1) throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::checkWithMeshStruct : for nodes field only one subdivision supported !"); _items[0].checkInRange(nbOfEnt,1,globs); @@ -1638,10 +1841,10 @@ void MEDFileField1TSStructItem::checkWithMeshStruct(const MEDFileMeshStruct *mst } default: throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::checkWithMeshStruct : not managed field type !"); - } + } } -bool MEDFileField1TSStructItem::operator==(const MEDFileField1TSStructItem& other) const throw(INTERP_KERNEL::Exception) +bool MEDFileField1TSStructItem::operator==(const MEDFileField1TSStructItem& other) const { if(_type!=other._type) return false; @@ -1741,19 +1944,24 @@ bool MEDFileField1TSStructItem::isCompatibleWithNodesDiscr(const MEDFileField1TS int theFirstLevFull; bool ret0=isFullyOnOneLev(meshSt,theFirstLevFull); const MEDFileField1TSStructItem2& otherNodeIt(other._items[0]); + mcIdType nbOfNodes(meshSt->getNumberOfNodes()); if(otherNodeIt.getPflName().empty()) {//on all nodes if(!ret0) return false; - return theFirstLevFull==0; + std::vector nodesFetched(nbOfNodes,false); + meshSt->getTheMesh()->whichAreNodesFetched(*this,globs,nodesFetched); + if(std::find(nodesFetched.begin(),nodesFetched.end(),false)==nodesFetched.end()) + return theFirstLevFull==0; + else + return false; } else { - const DataArrayInt *pfl=globs->getProfile(otherNodeIt.getPflName().c_str()); - MEDCouplingAutoRefCountObjectPtr cpyPfl(pfl->deepCpy()); + const DataArrayIdType *pfl=globs->getProfile(otherNodeIt.getPflName().c_str()); + MCAuto cpyPfl(pfl->deepCopy()); cpyPfl->sort(); - int nbOfNodes(meshSt->getNumberOfNodes()); - if(cpyPfl->isIdentity() && cpyPfl->getNumberOfTuples()==nbOfNodes) + if(cpyPfl->isIota(nbOfNodes)) {//on all nodes also ! if(!ret0) return false; @@ -1794,7 +2002,7 @@ bool MEDFileField1TSStructItem::isFullyOnOneLev(const MEDFileMeshStruct *meshSt, return false; } -const MEDFileField1TSStructItem2& MEDFileField1TSStructItem::operator[](std::size_t i) const throw(INTERP_KERNEL::Exception) +const MEDFileField1TSStructItem2& MEDFileField1TSStructItem::operator[](std::size_t i) const { if(i>=_items.size()) throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::operator[] : input is not in valid range !"); @@ -1807,7 +2015,7 @@ std::size_t MEDFileField1TSStructItem::getHeapMemorySizeWithoutChildren() const return ret; } -std::vector MEDFileField1TSStructItem::getDirectChildren() const +std::vector MEDFileField1TSStructItem::getDirectChildrenWithNull() const { std::vector ret; for(std::vector< MEDFileField1TSStructItem2 >::const_iterator it=_items.begin();it!=_items.end();it++) @@ -1819,8 +2027,8 @@ MEDMeshMultiLev *MEDFileField1TSStructItem::buildFromScratchDataSetSupportOnCell { std::size_t sz(_items.size()); std::vector a0(sz); - std::vector a1(sz); - std::vector a2(sz); + std::vector a1(sz); + std::vector a2(sz); std::size_t i(0); for(std::vector< MEDFileField1TSStructItem2 >::const_iterator it=_items.begin();it!=_items.end();it++,i++) { @@ -1831,29 +2039,51 @@ 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; std::vector< MEDFileField1TSStructItem2 > anItems; // 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 !"); - bool isFirst=true; + if(typesF[0].empty()) + throw INTERP_KERNEL::Exception("MEDFileField1TSStruct : internal error #1 bis !"); + TypeOfField atype(typesF[0][0]); for(std::size_t i=0;i MEDFileField1TSStruct::getDirectChildren() const +std::vector MEDFileField1TSStruct::getDirectChildrenWithNull() const { std::vector ret; for(std::vector::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++) @@ -1980,7 +2218,7 @@ MEDMeshMultiLev *MEDFileField1TSStruct::buildFromScratchDataSetSupport(const MED int pos0(-1),pos1(-1); if(presenceOfCellDiscr(pos0)) { - MEDCouplingAutoRefCountObjectPtr ret(_already_checked[pos0].buildFromScratchDataSetSupportOnCells(mst,globs)); + MCAuto ret(_already_checked[pos0].buildFromScratchDataSetSupportOnCells(mst,globs)); if(presenceOfPartialNodeDiscr(pos1)) ret->setNodeReduction(_already_checked[pos1][0].getPfl(globs)); return ret.retn(); @@ -1988,9 +2226,8 @@ 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)); @@ -2014,9 +2251,27 @@ 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. + * If true is returned the pos of the easiest is returned. The easiest is the first element in \a this having the less split subparts. */ bool MEDFileField1TSStruct::presenceOfCellDiscr(int& pos) const { @@ -2078,30 +2333,35 @@ MEDFileFastCellSupportComparator::MEDFileFastCellSupportComparator(const MEDFile _f1ts_cmps.resize(nbPts); for(int i=0;i elt=ref->getTimeStepAtPos(i); - _f1ts_cmps[i]=MEDFileField1TSStruct::New(elt,_mesh_comp); - _f1ts_cmps[i]->checkWithMeshStruct(_mesh_comp,elt); + MCAuto elt=ref->getTimeStepAtPos(i); + try + { + _f1ts_cmps[i]=MEDFileField1TSStruct::New(elt,_mesh_comp); + _f1ts_cmps[i]->checkWithMeshStruct(_mesh_comp,elt); + } + catch(INTERP_KERNEL::Exception& e) + { + std::ostringstream oss; oss << "Problem in field with name \"" << ref->getName() << "\"" << std::endl; + oss << "More Details : " << e.what(); + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } } } std::size_t MEDFileFastCellSupportComparator::getHeapMemorySizeWithoutChildren() const { - std::size_t ret(_f1ts_cmps.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr)); + std::size_t ret(_f1ts_cmps.capacity()*sizeof(MCAuto)); return ret; } -std::vector MEDFileFastCellSupportComparator::getDirectChildren() const +std::vector MEDFileFastCellSupportComparator::getDirectChildrenWithNull() const { std::vector ret; const MEDFileMeshStruct *mst(_mesh_comp); if(mst) 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.push_back(cur); - } + for(std::vector< MCAuto >::const_iterator it=_f1ts_cmps.begin();it!=_f1ts_cmps.end();it++) + ret.push_back((const MEDFileField1TSStruct *)*it); return ret; } @@ -2115,7 +2375,7 @@ bool MEDFileFastCellSupportComparator::isEqual(const MEDFileAnyTypeFieldMultiTS } for(int i=0;i elt=other->getTimeStepAtPos(i); + MCAuto elt=other->getTimeStepAtPos(i); if(!_f1ts_cmps[i]->isEqualConsideringThePast(elt,_mesh_comp)) if(!_f1ts_cmps[i]->isSupportSameAs(elt,_mesh_comp)) return false; @@ -2133,7 +2393,7 @@ bool MEDFileFastCellSupportComparator::isCompatibleWithNodesDiscr(const MEDFileA } for(int i=0;i elt=other->getTimeStepAtPos(i); + MCAuto elt=other->getTimeStepAtPos(i); if(!_f1ts_cmps[i]->isCompatibleWithNodesDiscr(elt,_mesh_comp)) return false; } @@ -2167,3 +2427,24 @@ bool MEDFileFastCellSupportComparator::isDataSetSupportEqualToThePreviousOne(int const MEDFileField1TSStruct *objRef(_f1ts_cmps[timeStepId-1]); return objRef->isDataSetSupportFastlyEqualTo(*obj,globs); } + +int MEDFileFastCellSupportComparator::getNumberOfTS() const +{ + return (int)_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); +}