X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FMEDLoader%2FMEDFileFieldOverView.cxx;h=5f85bc66306cc2f3741f5a2ee50908a59029434c;hb=719fc675bcf1570685c12723bf53f2a4250622fe;hp=d77b36f1387352ae4a93857b0c6c640b498a1dd1;hpb=4331d644cba358c1c5295d4f86d7f48704c89415;p=tools%2Fmedcoupling.git diff --git a/src/MEDLoader/MEDFileFieldOverView.cxx b/src/MEDLoader/MEDFileFieldOverView.cxx index d77b36f13..5f85bc663 100644 --- a/src/MEDLoader/MEDFileFieldOverView.cxx +++ b/src/MEDLoader/MEDFileFieldOverView.cxx @@ -26,14 +26,28 @@ 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,255,255,255,255,10,14,13,255,12,255,24,255,16,27,255,26,255,29,255,255,25,42,255,4}; + +const char MEDFileField1TSStructItem2::NEWLY_CREATED_PFL_NAME[]="???"; + MEDFileMeshStruct *MEDFileMeshStruct::New(const MEDFileMesh *mesh) { return new MEDFileMeshStruct(mesh); } -std::size_t MEDFileMeshStruct::getHeapMemorySize() const +std::size_t MEDFileMeshStruct::getHeapMemorySizeWithoutChildren() const { - return 0; + std::size_t ret(0); + 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); + return ret; +} + +std::vector MEDFileMeshStruct::getDirectChildren() const +{ + return std::vector(); } MEDFileMeshStruct::MEDFileMeshStruct(const MEDFileMesh *mesh):_mesh(mesh) @@ -43,13 +57,10 @@ MEDFileMeshStruct::MEDFileMeshStruct(const MEDFileMesh *mesh):_mesh(mesh) _nb_nodes=mesh->getNumberOfNodes(); _geo_types_distrib.resize(levs.size()); for(std::vector::const_iterator lev=levs.begin();lev!=levs.end();lev++) - { - MEDCouplingAutoRefCountObjectPtr mLev=mesh->getGenMeshAtLevel(*lev); - _geo_types_distrib[-(*lev)]=mLev->getDistributionOfTypes(); - } + _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--) @@ -65,7 +76,7 @@ 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) +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++) { @@ -85,10 +96,10 @@ 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) @@ -98,6 +109,887 @@ int MEDFileMeshStruct::getNumberOfGeoTypesInLev(int relativeLev) const throw(INT //= +std::size_t MEDMeshMultiLev::getHeapMemorySizeWithoutChildren() const +{ + return 0; +} + +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 !"); + const MEDFileUMesh *um(dynamic_cast(m)); + if(um) + return MEDUMeshMultiLev::New(um,levs); + const MEDFileCMesh *cm(dynamic_cast(m)); + if(cm) + return MEDCMeshMultiLev::New(cm,levs); + const MEDFileCurveLinearMesh *clm(dynamic_cast(m)); + if(clm) + return MEDCurveLinearMeshMultiLev::New(clm,levs); + throw INTERP_KERNEL::Exception("MEDMeshMultiLev::New : unrecognized type of mesh ! Must be in [MEDFileUMesh,MEDFileCMesh,MEDFileCurveLinearMesh] !"); +} + +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 !"); + const MEDFileUMesh *um(dynamic_cast(m)); + if(um) + return MEDUMeshMultiLev::New(um,gts,pfls,nbEntities); + const MEDFileCMesh *cm(dynamic_cast(m)); + if(cm) + return MEDCMeshMultiLev::New(cm,gts,pfls,nbEntities); + const MEDFileCurveLinearMesh *clm(dynamic_cast(m)); + if(clm) + return MEDCurveLinearMeshMultiLev::New(clm,gts,pfls,nbEntities); + throw INTERP_KERNEL::Exception("MEDMeshMultiLev::New 2 : unrecognized type of mesh ! Must be in [MEDFileUMesh,MEDFileCMesh,MEDFileCurveLinearMesh] !"); +} + +MEDMeshMultiLev *MEDMeshMultiLev::NewOnlyOnNode(const MEDFileMesh *m, const DataArrayInt *pflOnNode) +{ + std::vector levs(1,0); + MEDCouplingAutoRefCountObjectPtr ret(MEDMeshMultiLev::New(m,levs)); + ret->selectPartOfNodes(pflOnNode); + return ret.retn(); +} + +void MEDMeshMultiLev::setNodeReduction(const DataArrayInt *nr) +{ + if(nr) + nr->incrRef(); + _node_reduction=const_cast(nr); +} + +bool MEDMeshMultiLev::isFastlyTheSameStruct(const MEDFileField1TSStructItem& fst, const MEDFileFieldGlobsReal *globs) const +{ + if(fst.getType()==ON_NODES) + { + if(fst.getNumberOfItems()!=1) + 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); + if(pflName.empty() && !nr) + return true; + if(pflName==nr->getName()) + return true; + return false; + } + else + { + 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(); + if(isFastlyTheSameStruct(fst,globs)) + return ret.retn(); + else + return constructDataArray(fst,globs,vals); +} + +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]); + if(!pfl) + return std::string(""); + return pfl->getName(); +} + +/*! + * 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;ideepCpy(); + if(pflName.empty() && nr) + 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()); + 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()); + ret->renumberInPlace(p1->begin()); + return ret.retn(); + } + if(!pflName.empty() && !nr) + { + MEDCouplingAutoRefCountObjectPtr p1(globs->getProfile(pflName.c_str())->deepCpy()); + p1->sort(true); + if(!p1->isIdentity() || p1->getNumberOfTuples()!=getNumberOfNodes()) + throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for nodes 4 !"); + MEDCouplingAutoRefCountObjectPtr ret(vals->deepCpy()); + ret->renumberInPlace(globs->getProfile(pflName.c_str())->begin()); + return ret.retn(); + } + throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for nodes 5 !"); + } + else + { + std::size_t sz(fst.getNumberOfItems()); + std::set 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 DataArrayInt *thisP(_pfls[iii]); + std::vector ps; + for(std::size_t i=0;igetNbOfIntegrationPts(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 !"); + } + else + { + 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; + } + } + return DataArray::Aggregate(arr); + } +} + +MEDMeshMultiLev::MEDMeshMultiLev() +{ +} + +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) +{ + std::size_t sz(_geo_types.size()); + if(sz!=pfls.size() || sz!=nbEntities.size()) + throw INTERP_KERNEL::Exception("MEDMeshMultiLev::MEDMeshMultiLev : input vector must have the same size !"); + _pfls.resize(sz); + for(std::size_t i=0;iincrRef(); + _pfls[i]=const_cast(pfls[i]); + } +} + +MEDMeshMultiLev::MEDMeshMultiLev(const MEDMeshMultiLev& other):_pfls(other._pfls),_geo_types(other._geo_types),_nb_entities(other._nb_entities),_node_reduction(other._node_reduction),_nb_nodes(other._nb_nodes) +{ +} + +//= + +MEDUMeshMultiLev *MEDUMeshMultiLev::New(const MEDFileUMesh *m, const std::vector& levs) +{ + return new MEDUMeshMultiLev(m,levs); +} + +MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDFileUMesh *m, const std::vector& levs) +{ + if(!m) + throw INTERP_KERNEL::Exception("MEDUMeshMultiLev constructor : null input pointer !"); + std::vector v; + for(std::vector::const_iterator it=levs.begin();it!=levs.end();it++) + { + std::vector vTmp(m->getDirectUndergroundSingleGeoTypeMeshes(*it)); + v.insert(v.end(),vTmp.begin(),vTmp.end()); + } + std::size_t sz(v.size()); + _parts.resize(sz); + _pfls.resize(sz); + _geo_types.resize(sz); + for(std::size_t i=0;iincrRef(); + else + throw INTERP_KERNEL::Exception("MEDUMeshMultiLev constructor : presence of a null pointer !"); + _parts[i]=obj; + _geo_types[i]=obj->getCellModelEnum(); + } +} + +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) +{ + std::size_t sz(gts.size()); + _parts.resize(sz); + for(std::size_t i=0;igetDirectUndergroundSingleGeoTypeMesh(gts[i])); + if(elt) + elt->incrRef(); + _parts[i]=elt; + } +} + +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(); +} + +MEDMeshMultiLev *MEDUMeshMultiLev::prepare() const +{ + return new MEDUMeshMultiLev(*this); +} + +MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDUMeshMultiLev& other):MEDMeshMultiLev(other),_parts(other._parts) +{ +} + +MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDStructuredMeshMultiLev& other, const MEDCouplingAutoRefCountObjectPtr& part):MEDMeshMultiLev(other) +{ + _parts.resize(1); + _parts[0]=part; + _geo_types.resize(1); _geo_types[0]=part->getCellModelEnum(); + _nb_entities.resize(1); _nb_entities[0]=part->getNumberOfCells(); + _pfls.resize(1); _pfls[0]=0; +} + +void MEDUMeshMultiLev::buildVTUArrays(DataArrayDouble *& coords, DataArrayByte *&types, DataArrayInt *&cellLocations, DataArrayInt *& cells, DataArrayInt *&faceLocations, DataArrayInt *&faces) const +{ + 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()); + 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); + bool isPolyh(false); + int iii(0); + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::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; + if(!pfl) + { cur2=const_cast(cur); cur2->incrRef(); } + else + { cur2=dynamic_cast(cur->buildPartOfMySelfKeepCoords(pfl->begin(),pfl->end())); cur=cur2; } + // + int curNbCells(cur->getNumberOfCells()); + szBCE+=curNbCells; + if((*it)->getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED) + szD+=cur->getNodalConnectivity()->getNumberOfTuples()+curNbCells; + else + { + isPolyh=true; + MEDCouplingAutoRefCountObjectPtr tmp(cur->computeEffectiveNbOfNodesPerCell()); + szD+=tmp->accumulate(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); + if(isPolyh) + { e->alloc(szBCE,1); ePtr=e->getPointer(); f->alloc(szF,1); fPtr=f->getPointer(); } + int k(0); + iii=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_parts.begin();it!=_parts.end();it++,iii++) + { + const MEDCoupling1GTUMesh *cur(*it); + // + const DataArrayInt *pfl(_pfls[iii]); + MEDCouplingAutoRefCountObjectPtr 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()); + int gt((int)cur->getCellModelEnum()); + 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==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)); + const MEDCoupling1DGTUMesh *dcur(dynamic_cast(cur)); + const int *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;igetNodalConnectivityIndex()->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(); + dPtr=std::copy(s.begin(),s.end(),dPtr); + *cPtr=k+(int)s.size(); k=*cPtr++; + } + } + if(isPolyh) + { + connIPtr=dcur->getNodalConnectivityIndex()->begin(); + if(cur->getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED) + { std::fill(ePtr,ePtr+curNbCells,-1); ePtr+=curNbCells; } + else + { + int kk(0); + for(int i=0;i& coords, DataArrayInt *nodalConnVTK, DataArrayInt *polyhedNodalConnVTK) const +{ + const DataArrayInt *nr(_node_reduction); + if(!nr) + return ; + int sz(coords->getNumberOfTuples()); + std::vector b(sz,false); + const int *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()) + throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::reorderNodesIfNecessary : internal error #3 !"); + // Go renumbering ! + MEDCouplingAutoRefCountObjectPtr o2n(DataArrayInt::New()); o2n->alloc(sz,1); + int *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()); + 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())); +} + +//= + +MEDStructuredMeshMultiLev::MEDStructuredMeshMultiLev() +{ +} + +MEDStructuredMeshMultiLev::MEDStructuredMeshMultiLev(int nbOfNodes, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities):MEDMeshMultiLev(nbOfNodes,gts,pfls,nbEntities) +{ +} + +void MEDStructuredMeshMultiLev::selectPartOfNodes(const DataArrayInt *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()))); + m->setNodalConnectivity(conn); + const DataArrayInt *pfl(_pfls[0]); + if(pfl) + { + m=dynamic_cast(m->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; + _node_reduction=m2->getNodeIdsInUse(tmp); + if(pfl) + _pfls[0]=pfl->selectByTupleIdSafe(cellIds->begin(),cellIds->end()); + else + _pfls[0]=cellIdsSafe; +} + +MEDStructuredMeshMultiLev::MEDStructuredMeshMultiLev(const MEDStructuredMeshMultiLev& other):MEDMeshMultiLev(other) +{ +} + +//= + +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) +{ + return new MEDCMeshMultiLev(m,gts,pfls,nbEntities); +} + +MEDCMeshMultiLev::MEDCMeshMultiLev(const MEDFileCMesh *m, const std::vector& 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;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; + } +} + +MEDCMeshMultiLev::MEDCMeshMultiLev(const MEDFileCMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities):MEDStructuredMeshMultiLev(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 !"); + 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(); + } +} + +MEDCMeshMultiLev::MEDCMeshMultiLev(const MEDCMeshMultiLev& other):MEDStructuredMeshMultiLev(other),_coords(other._coords) +{ +} + +std::vector MEDCMeshMultiLev::getNodeGridStructure() const +{ + std::vector ret(_coords.size()); + for(std::size_t i=0;i<_coords.size();i++) + ret[i]=_coords[i]->getNumberOfTuples(); + return ret; +} + +MEDMeshMultiLev *MEDCMeshMultiLev::prepare() const +{ + const DataArrayInt *pfl(_pfls[0]),*nr(_node_reduction); + MEDCouplingAutoRefCountObjectPtr nnr; + std::vector cgs,ngs(getNodeGridStructure()); + cgs.resize(ngs.size()); + std::transform(ngs.begin(),ngs.end(),cgs.begin(),std::bind2nd(std::plus(),-1)); + if(pfl) + { + std::vector< std::pair > cellParts; + if(MEDCouplingStructuredMesh::IsPartStructured(pfl->begin(),pfl->end(),cgs,cellParts)) + { + MEDCouplingAutoRefCountObjectPtr ret(new MEDCMeshMultiLev(*this)); + if(nr) + { nnr=nr->deepCpy(); nnr->sort(true); ret->setNodeReduction(nnr); } + ret->_nb_entities[0]=pfl->getNumberOfTuples(); + ret->_pfls[0]=0; + std::vector< MEDCouplingAutoRefCountObjectPtr > 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); + ret->_coords=coords; + return ret.retn(); + } + else + { + MEDCouplingAutoRefCountObjectPtr m(MEDCouplingCMesh::New()); + for(std::size_t 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)); + if(nr) + { m3->zipCoords(); nnr=nr->deepCpy(); nnr->sort(true); ret->setNodeReduction(nnr); } + return ret.retn(); + } + } + else + { + MEDCouplingAutoRefCountObjectPtr ret(new MEDCMeshMultiLev(*this)); + if(nr) + { nnr=nr->deepCpy(); nnr->sort(true); ret->setNodeReduction(nnr); } + return ret.retn(); + } +} + +std::vector< DataArrayDouble * > MEDCMeshMultiLev::buildVTUArrays() const +{ + std::size_t sz(_coords.size()); + std::vector< DataArrayDouble * > ret(sz); + for(std::size_t i=0;i((const DataArrayDouble *)_coords[i]); + ret[i]->incrRef(); + } + return ret; +} + +//= + +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) +{ + return new MEDCurveLinearMeshMultiLev(m,gts,pfls,nbEntities); +} + +MEDCurveLinearMeshMultiLev::MEDCurveLinearMeshMultiLev(const MEDFileCurveLinearMesh *m, const std::vector& levs) +{ + if(!m) + throw INTERP_KERNEL::Exception("MEDCurveLinearMeshMultiLev constructor : null input pointer !"); + if(levs.size()!=1 || levs[0]!=0) + throw INTERP_KERNEL::Exception("MEDCurveLinearMeshMultiLev constructor : levels supported is 0 only !"); + 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(); +} + +MEDCurveLinearMeshMultiLev::MEDCurveLinearMeshMultiLev(const MEDFileCurveLinearMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities):MEDStructuredMeshMultiLev(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(); +} + +MEDCurveLinearMeshMultiLev::MEDCurveLinearMeshMultiLev(const MEDCurveLinearMeshMultiLev& other):MEDStructuredMeshMultiLev(other),_coords(other._coords),_structure(other._structure) +{ +} + +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()); + cgs.resize(ngs.size()); + std::transform(ngs.begin(),ngs.end(),cgs.begin(),std::bind2nd(std::plus(),-1)); + if(pfl) + { + std::vector< std::pair > cellParts,nodeParts; + if(MEDCouplingStructuredMesh::IsPartStructured(pfl->begin(),pfl->end(),cgs,cellParts)) + { + nodeParts=cellParts; + std::vector st(ngs.size()); + for(std::size_t i=0;i p(MEDCouplingStructuredMesh::BuildExplicitIdsFrom(ngs,nodeParts)); + MEDCouplingAutoRefCountObjectPtr ret(new MEDCurveLinearMeshMultiLev(*this)); + 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(); + } + else + { + MEDCouplingAutoRefCountObjectPtr 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)); + if(nr) + { m3->zipCoords(); nnr=nr->deepCpy(); nnr->sort(true); ret->setNodeReduction(nnr); } + return ret.retn(); + } + } + else + { + MEDCouplingAutoRefCountObjectPtr ret(new MEDCurveLinearMeshMultiLev(*this)); + if(nr) + { nnr=nr->deepCpy(); nnr->sort(true); ret->setNodeReduction(nnr); } + return ret.retn(); + } +} + +void MEDCurveLinearMeshMultiLev::buildVTUArrays(DataArrayDouble *&coords, std::vector& nodeStrct) const +{ + nodeStrct=_structure; + const DataArrayDouble *coo(_coords); + if(!coo) + throw INTERP_KERNEL::Exception("MEDCurveLinearMeshMultiLev::buildVTUArrays : null pointer on coordinates !"); + coords=const_cast(coo); coords->incrRef(); +} + +//= + MEDFileField1TSStructItem2::MEDFileField1TSStructItem2() { } @@ -107,20 +999,20 @@ MEDFileField1TSStructItem2::MEDFileField1TSStructItem2(INTERP_KERNEL::Normalized _pfl->setName(c.c_str()); } -void MEDFileField1TSStructItem2::checkWithMeshStructForCells(MEDFileMeshStruct *mst, const MEDFileFieldGlobs *globs) throw(INTERP_KERNEL::Exception) +void MEDFileField1TSStructItem2::checkWithMeshStructForCells(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) { int nbOfEnt=mst->getNumberOfElemsOfGeoType(_geo_type); checkInRange(nbOfEnt,1,globs); } -void MEDFileField1TSStructItem2::checkWithMeshStructForGaussNE(MEDFileMeshStruct *mst, const MEDFileFieldGlobs *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(MEDFileMeshStruct *mst, const MEDFileFieldGlobs *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 !"); @@ -131,16 +1023,45 @@ void MEDFileField1TSStructItem2::checkWithMeshStructForGaussPT(MEDFileMeshStruct checkInRange(nbOfEnt,loc.getNumberOfGaussPoints(),globs); } +int MEDFileField1TSStructItem2::getNbOfIntegrationPts(const MEDFileFieldGlobsReal *globs) const +{ + if(_loc.empty()) + { + if(getPflName().empty()) + return (_start_end.second-_start_end.first)/_nb_of_entity; + else + return (_start_end.second-_start_end.first)/getPfl(globs)->getNumberOfTuples(); + } + else + { + const MEDFileFieldLoc& loc(globs->getLocalization(_loc.c_str())); + return loc.getNumberOfGaussPoints(); + } +} + std::string MEDFileField1TSStructItem2::getPflName() const { return _pfl->getName(); } +const DataArrayInt *MEDFileField1TSStructItem2::getPfl(const MEDFileFieldGlobsReal *globs) const +{ + if(!_pfl->isAllocated()) + { + if(_pfl->getName().empty()) + return 0; + else + return globs->getProfile(_pfl->getName().c_str()); + } + else + return _pfl; +} + /*! * \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 MEDFileFieldGlobs *globs) throw(INTERP_KERNEL::Exception) +void MEDFileField1TSStructItem2::checkInRange(int nbOfEntity, int nip, const MEDFileFieldGlobsReal *globs) { _nb_of_entity=nbOfEntity; if(_pfl->getName().empty()) @@ -156,17 +1077,30 @@ void MEDFileField1TSStructItem2::checkInRange(int nbOfEntity, int nip, const MED const DataArrayInt *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 !"); - if(!pfl->checkAllIdsInRange(0,nbOfEntity)) - throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::checkInRange : The profile specified is invalid !"); + pfl->checkAllIdsInRange(0,nbOfEntity); } } +bool MEDFileField1TSStructItem2::isFastlyEqual(int& startExp, INTERP_KERNEL::NormalizedCellType gt, const char *pflName) const +{ + if(startExp!=_start_end.first) + return false; + if(gt!=_geo_type) + return false; + if(getPflName()!=pflName) + return false; + startExp=_start_end.second; + return true; +} + bool MEDFileField1TSStructItem2::operator==(const MEDFileField1TSStructItem2& other) const throw(INTERP_KERNEL::Exception) { + //_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. return _geo_type==other._geo_type && _start_end==other._start_end && _pfl->getName()==other._pfl->getName(); } -bool MEDFileField1TSStructItem2::isCellSupportEqual(const MEDFileField1TSStructItem2& other) const throw(INTERP_KERNEL::Exception) +bool MEDFileField1TSStructItem2::isCellSupportEqual(const MEDFileField1TSStructItem2& other, const MEDFileFieldGlobsReal *globs) const { if(_geo_type!=other._geo_type) return false; @@ -176,13 +1110,19 @@ bool MEDFileField1TSStructItem2::isCellSupportEqual(const MEDFileField1TSStructI return false; if(_pfl->getName().empty() && other._pfl->getName().empty()) return true; - return _pfl->isEqualWithoutConsideringStr(*other._pfl); + const DataArrayInt *pfl1(getPfl(globs)),*pfl2(other.getPfl(globs)); + return pfl1->isEqualWithoutConsideringStr(*pfl2); +} + +bool MEDFileField1TSStructItem2::isNodeSupportEqual(const MEDFileField1TSStructItem2& other, const MEDFileFieldGlobsReal *globs) const +{ + return isCellSupportEqual(other,globs); } /*! * \a objs must be non empty. \a objs should contain items having same geometric type. */ -MEDFileField1TSStructItem2 MEDFileField1TSStructItem2::BuildAggregationOf(const std::vector& objs, const MEDFileFieldGlobs *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 !"); @@ -202,40 +1142,55 @@ MEDFileField1TSStructItem2 MEDFileField1TSStructItem2::BuildAggregationOf(const if(obj->_pfl->getName().empty()) throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::BuildAggregationOf : invalid situation ! Several same geo type chunk must all lie on profiles !"); arrs[i]=globs->getProfile(obj->_pfl->getName().c_str()); - MEDCouplingAutoRefCountObjectPtr arr(DataArrayInt::Aggregate(arrs)); - arr->sort(); - int 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) - { - std::pair p(0,nbEntityRef); - std::string a,b; - MEDFileField1TSStructItem2 ret(gt,p,a,b); - ret._nb_of_entity=nbEntityRef; - return ret; - } - else - { - arr->setName("???"); - std::pair p(0,oldNbTuples); - std::string a,b; - MEDFileField1TSStructItem2 ret(gt,p,a,b); - ret._nb_of_entity=nbEntityRef; - ret._pfl=arr; - return ret; - } + } + MEDCouplingAutoRefCountObjectPtr arr(DataArrayInt::Aggregate(arrs)); + arr->sort(); + int 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) + { + std::pair p(0,nbEntityRef); + std::string a,b; + MEDFileField1TSStructItem2 ret(gt,p,a,b); + ret._nb_of_entity=nbEntityRef; + return ret; + } + else + { + arr->setName(NEWLY_CREATED_PFL_NAME); + std::pair p(0,oldNbTuples); + std::string a,b; + MEDFileField1TSStructItem2 ret(gt,p,a,b); + ret._nb_of_entity=nbEntityRef; + ret._pfl=arr; + return ret; } } +std::size_t MEDFileField1TSStructItem2::getHeapMemorySizeWithoutChildren() const +{ + std::size_t ret(_loc.capacity()); + return ret; +} + +std::vector MEDFileField1TSStructItem2::getDirectChildren() const +{ + std::vector ret; + const DataArrayInt *pfl(_pfl); + if(pfl) + ret.push_back(pfl); + return ret; +} + //= MEDFileField1TSStructItem::MEDFileField1TSStructItem(TypeOfField a, const std::vector< MEDFileField1TSStructItem2 >& b):_computed(false),_type(a),_items(b) { } -void MEDFileField1TSStructItem::checkWithMeshStruct(MEDFileMeshStruct *mst, const MEDFileFieldGlobs *globs) throw(INTERP_KERNEL::Exception) +void MEDFileField1TSStructItem::checkWithMeshStruct(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) { switch(_type) { @@ -282,14 +1237,26 @@ bool MEDFileField1TSStructItem::operator==(const MEDFileField1TSStructItem& othe return true; } -bool MEDFileField1TSStructItem::isCellSupportEqual(const MEDFileField1TSStructItem& other) const throw(INTERP_KERNEL::Exception) +bool MEDFileField1TSStructItem::isCellSupportEqual(const MEDFileField1TSStructItem& other, const MEDFileFieldGlobsReal *globs) const +{ + if(_type!=other._type) + return false; + if(_items.size()!=other._items.size()) + return false; + for(std::size_t i=0;i<_items.size();i++) + if(!(_items[i].isCellSupportEqual(other._items[i],globs))) + return false; + return true; +} + +bool MEDFileField1TSStructItem::isNodeSupportEqual(const MEDFileField1TSStructItem& other, const MEDFileFieldGlobsReal *globs) const { if(_type!=other._type) return false; if(_items.size()!=other._items.size()) return false; for(std::size_t i=0;i<_items.size();i++) - if(!(_items[i].isCellSupportEqual(other._items[i]))) + if(!(_items[i].isNodeSupportEqual(other._items[i],globs))) return false; return true; } @@ -311,7 +1278,7 @@ private: INTERP_KERNEL::NormalizedCellType _geo_type; }; -MEDFileField1TSStructItem MEDFileField1TSStructItem::simplifyMeOnCellEntity(const MEDFileFieldGlobs *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 !"); @@ -338,7 +1305,7 @@ MEDFileField1TSStructItem MEDFileField1TSStructItem::simplifyMeOnCellEntity(cons const std::vector& ids=m[i].second; std::vectorobjs(ids.size()); for(std::size_t j=0;jgetNumberOfLevs()); if(nbOfLevs==0) - throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::isFullyOnExactlyOneLev : no levels in input mesh structure !"); + throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::isFullyOnOneLev : no levels in input mesh structure !"); + std::vector levs(nbOfLevs); theFirstLevFull=1; int nbOfGT=0; - bool firstShot(true); std::set gts; for(std::vector< MEDFileField1TSStructItem2 >::const_iterator it=_items.begin();it!=_items.end();it++) { @@ -401,18 +1368,15 @@ bool MEDFileField1TSStructItem::isFullyOnExactlyOneLev(const MEDFileMeshStruct * return false; INTERP_KERNEL::NormalizedCellType gt((*it).getGeo()); if(gts.find(gt)!=gts.end()) - throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::isFullyOnExactlyOneLev : internal error !"); + throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::isFullyOnOneLev : internal error !"); gts.insert(gt); int pos(meshSt->getLevelOfGeoType((*it).getGeo())); - if(firstShot) - theFirstLevFull=pos; - else - if(theFirstLevFull!=pos) - return false; - firstShot=false; - nbOfGT++; + levs[-pos]++; } - return nbOfGT==meshSt->getNumberOfGeoTypesInLev(theFirstLevFull); + for(int i=0;igetNumberOfGeoTypesInLev(-i)==levs[i]) + { theFirstLevFull=-i; return true; } + return false; } const MEDFileField1TSStructItem2& MEDFileField1TSStructItem::operator[](std::size_t i) const throw(INTERP_KERNEL::Exception) @@ -422,28 +1386,94 @@ const MEDFileField1TSStructItem2& MEDFileField1TSStructItem::operator[](std::siz return _items[i]; } +std::size_t MEDFileField1TSStructItem::getHeapMemorySizeWithoutChildren() const +{ + 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.push_back(&(*it)); + return ret; +} + +MEDMeshMultiLev *MEDFileField1TSStructItem::buildFromScratchDataSetSupportOnCells(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) const +{ + std::size_t sz(_items.size()); + std::vector a0(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++) + { + a0[i]=(*it).getGeo(); + a1[i]=(*it).getPfl(globs); + a2[i]=mst->getNumberOfElemsOfGeoType((*it).getGeo()); + } + return MEDMeshMultiLev::New(mst->getTheMesh(),a0,a1,a2); +} + +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::size_t nbOfGeoTypes(geoTypes.size()); + if(nbOfGeoTypes==0) + throw INTERP_KERNEL::Exception("MEDFileField1TSStruct : not null by empty ref !"); + bool isFirst=true; + for(std::size_t i=0;i::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++) { if((*it)==b) @@ -455,14 +1485,14 @@ 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) 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 !"); - MEDFileField1TSStructItem b(BuildItemFrom(other)); + MEDFileField1TSStructItem b(MEDFileField1TSStructItem::BuildItemFrom(other,meshSt)); if(!_already_checked[0].isEntityCell() || !b.isEntityCell()) throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::isSupportSameAs : only available on cell entities !"); - MEDFileField1TSStructItem other1(b.simplifyMeOnCellEntity(other->contentNotNull())); + MEDFileField1TSStructItem other1(b.simplifyMeOnCellEntity(other)); int found=-1,i=0; for(std::vector::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++,i++) if((*it).isComputed()) @@ -470,117 +1500,197 @@ bool MEDFileField1TSStruct::isSupportSameAs(const MEDFileAnyTypeField1TS *other) bool ret(false); if(found==-1) { - MEDFileField1TSStructItem this1(_already_checked[0].simplifyMeOnCellEntity(other->contentNotNull())); - ret=this1.isCellSupportEqual(other1); + MEDFileField1TSStructItem this1(_already_checked[0].simplifyMeOnCellEntity(other)); + ret=this1.isCellSupportEqual(other1,other); if(ret) _already_checked.push_back(this1); } else - ret=_already_checked[found].isCellSupportEqual(other1); + ret=_already_checked[found].isCellSupportEqual(other1,other); if(ret) _already_checked.push_back(b); return ret; } -bool MEDFileField1TSStruct::isCompatibleWithNodesDiscr(const MEDFileAnyTypeField1TS *other, const MEDFileMeshStruct *meshSt) throw(INTERP_KERNEL::Exception) +/*! + * \param [in] other - a field with only one spatial discretization : ON_NODES. + */ +bool MEDFileField1TSStruct::isCompatibleWithNodesDiscr(const MEDFileAnyTypeField1TS *other, const MEDFileMeshStruct *meshSt) { if(_already_checked.empty()) throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::isCompatibleWithNodesDiscr : no ref !"); - if(!_already_checked[0].isEntityCell()) - throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::isCompatibleWithNodesDiscr : only available on cell entities !"); - MEDFileField1TSStructItem other1(BuildItemFrom(other)); - // - int found=-1,i=0; - for(std::vector::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++,i++) - if((*it).isComputed()) - { found=i; break; } - bool ret(false); - if(found==-1) + MEDFileField1TSStructItem other1(MEDFileField1TSStructItem::BuildItemFrom(other,meshSt)); + if(_already_checked[0].isEntityCell()) { - MEDFileField1TSStructItem this1(_already_checked[0].simplifyMeOnCellEntity(other->contentNotNull())); - ret=this1.isCompatibleWithNodesDiscr(other1,meshSt,other->contentNotNull()); + int found=-1,i=0; + for(std::vector::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++,i++) + if((*it).isComputed()) + { found=i; break; } + bool ret(false); + if(found==-1) + { + MEDFileField1TSStructItem this1(_already_checked[0].simplifyMeOnCellEntity(other)); + ret=this1.isCompatibleWithNodesDiscr(other1,meshSt,other); + if(ret) + _already_checked.push_back(this1); + } + else + ret=_already_checked[found].isCompatibleWithNodesDiscr(other1,meshSt,other); if(ret) - _already_checked.push_back(this1); + _already_checked.push_back(other1); + return ret; } else - ret=_already_checked[found].isCompatibleWithNodesDiscr(other1,meshSt,other->contentNotNull()); - if(ret) - _already_checked.push_back(other1); + return _already_checked[0].isNodeSupportEqual(other1,other); +} + +std::size_t MEDFileField1TSStruct::getHeapMemorySizeWithoutChildren() const +{ + std::size_t ret(_already_checked.capacity()*sizeof(MEDFileField1TSStructItem)); return ret; } -std::size_t MEDFileField1TSStruct::getHeapMemorySize() const +std::vector MEDFileField1TSStruct::getDirectChildren() const { - return 0; + std::vector ret; + for(std::vector::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++) + ret.push_back(&(*it)); + return ret; } -MEDFileField1TSStructItem MEDFileField1TSStruct::BuildItemFrom(const MEDFileAnyTypeField1TS *ref) +MEDMeshMultiLev *MEDFileField1TSStruct::buildFromScratchDataSetSupport(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) const { - 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::size_t nbOfGeoTypes(geoTypes.size()); - if(nbOfGeoTypes==0) - throw INTERP_KERNEL::Exception("MEDFileField1TSStruct : not null by empty ref !"); - bool isFirst=true; - for(std::size_t i=0;i ret(_already_checked[pos0].buildFromScratchDataSetSupportOnCells(mst,globs)); + if(presenceOfPartialNodeDiscr(pos1)) + ret->setNodeReduction(_already_checked[pos1][0].getPfl(globs)); + return ret.retn(); + } + 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); + } + else + return MEDMeshMultiLev::NewOnlyOnNode(mst->getTheMesh(),_already_checked[pos1][0].getPfl(globs)); + } +} + +bool MEDFileField1TSStruct::isDataSetSupportFastlyEqualTo(const MEDFileField1TSStruct& other, const MEDFileFieldGlobsReal *globs) const +{ + int b0,b1; + bool a0(presenceOfCellDiscr(b0)),a1(presenceOfPartialNodeDiscr(b1)); + int d0,d1; + bool c0(other.presenceOfCellDiscr(d0)),c1(other.presenceOfPartialNodeDiscr(d1)); + if(a0!=c0 || a1!=c1) + return false; + if(a0) + if(!_already_checked[b0].isCellSupportEqual(other._already_checked[d0],globs)) + return false; + if(a1) + if(!_already_checked[b1].isNodeSupportEqual(other._already_checked[d1],globs)) + return false; + return true; +} + +/*! + * 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 +{ + std::size_t refSz(std::numeric_limits::max()); + bool ret(false); + int i(0); + for(std::vector::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++,i++) + { + if((*it).getType()!=ON_NODES) { - if(atype==typesF[i][j]) - anItems.push_back(MEDFileField1TSStructItem2(geoTypes[i],strtEnds[i][j],pfls[i][j],locs[i][j])); + ret=true; + std::size_t sz((*it).getNumberOfItems()); + if(refSz>sz) + { pos=i; refSz=sz; } + } + } + if(refSz==0) + throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::presenceOfCellDiscr : an element in this on entity CELL is empty !"); + return ret; +} + +/*! + * 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 +{ + int i(0); + for(std::vector::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++,i++) + { + if((*it).getType()==ON_NODES) + { + std::size_t sz((*it).getNumberOfItems()); + if(sz==1) + { + if(!(*it)[0].getPflName().empty()) + { pos=i; return true; } + } else - throw INTERP_KERNEL::Exception("MEDFileField1TSStruct : can be applied only on single spatial discretization fields ! Call SplitPerDiscretization method !"); + throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::presenceOfPartialNodeDiscr : an element in this on entity NODE is split into several parts !"); } } - return MEDFileField1TSStructItem(atype,anItems); + return false; } //= -MEDFileFastCellSupportComparator *MEDFileFastCellSupportComparator::New(const MEDFileMesh *m, const MEDFileAnyTypeFieldMultiTS *ref) throw(INTERP_KERNEL::Exception) +MEDFileFastCellSupportComparator *MEDFileFastCellSupportComparator::New(const MEDFileMeshStruct *m, const MEDFileAnyTypeFieldMultiTS *ref) { return new MEDFileFastCellSupportComparator(m,ref); } -MEDFileFastCellSupportComparator::MEDFileFastCellSupportComparator(const MEDFileMesh *m, const MEDFileAnyTypeFieldMultiTS *ref) +MEDFileFastCellSupportComparator::MEDFileFastCellSupportComparator(const MEDFileMeshStruct *m, const MEDFileAnyTypeFieldMultiTS *ref) { - _mesh_comp=MEDFileMeshStruct::New(m); + if(!m) + throw INTERP_KERNEL::Exception("MEDFileFastCellSupportComparator constructor : null input mesh struct !"); + _mesh_comp=const_cast(m); _mesh_comp->incrRef(); int nbPts=ref->getNumberOfTS(); _f1ts_cmps.resize(nbPts); for(int i=0;i elt=ref->getTimeStepAtPos(i); - _f1ts_cmps[i]=MEDFileField1TSStruct::New(elt); - _f1ts_cmps[i]->checkWithMeshStruct(_mesh_comp,elt->contentNotNull()); + _f1ts_cmps[i]=MEDFileField1TSStruct::New(elt,_mesh_comp); + _f1ts_cmps[i]->checkWithMeshStruct(_mesh_comp,elt); } } -std::size_t MEDFileFastCellSupportComparator::getHeapMemorySize() const +std::size_t MEDFileFastCellSupportComparator::getHeapMemorySizeWithoutChildren() const { - /*std::size_t part1=sizeof(MEDFileFastCellSupportComparator)+_mesh_name.capacity()+_already_passed_code1.capacity()*sizeof(std::vector)+_already_passed_code2.capacity()*sizeof(void*)+_m_geo_types_distrib.capacity()*sizeof(std::vector); - std::size_t part2=0; - for(std::vector< std::vector >::const_iterator it=_already_passed_code1.begin();it!=_already_passed_code1.end();it++) - part2+=(*it).capacity()*(sizeof(int)+sizeof(const DataArrayInt *)); - for(std::vector< std::vector >::const_iterator it2=_m_geo_types_distrib.begin();it2!=_m_geo_types_distrib.end();it2++) - part2+=(*it2).capacity()*sizeof(int); - return part1+part2;*/ - return 0; + std::size_t ret(_f1ts_cmps.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr)); + return ret; } -bool MEDFileFastCellSupportComparator::isEqual(const MEDFileAnyTypeFieldMultiTS *other) throw(INTERP_KERNEL::Exception) +std::vector MEDFileFastCellSupportComparator::getDirectChildren() 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); + } + return ret; +} + +bool MEDFileFastCellSupportComparator::isEqual(const MEDFileAnyTypeFieldMultiTS *other) { int nbPts=other->getNumberOfTS(); if(nbPts!=(int)_f1ts_cmps.size()) @@ -591,14 +1701,14 @@ bool MEDFileFastCellSupportComparator::isEqual(const MEDFileAnyTypeFieldMultiTS for(int i=0;i elt=other->getTimeStepAtPos(i); - if(!_f1ts_cmps[i]->isEqualConsideringThePast(elt)) - if(!_f1ts_cmps[i]->isSupportSameAs(elt)) + if(!_f1ts_cmps[i]->isEqualConsideringThePast(elt,_mesh_comp)) + if(!_f1ts_cmps[i]->isSupportSameAs(elt,_mesh_comp)) return false; } 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()) @@ -614,3 +1724,31 @@ bool MEDFileFastCellSupportComparator::isCompatibleWithNodesDiscr(const MEDFileA } return true; } + +MEDMeshMultiLev *MEDFileFastCellSupportComparator::buildFromScratchDataSetSupport(int timeStepId, const MEDFileFieldGlobsReal *globs) const +{ + if(timeStepId<0 || timeStepId>=(int)_f1ts_cmps.size()) + { + std::ostringstream oss; oss << "MEDFileFastCellSupportComparator::buildFromScratchDataSetSupport : requested time step id #" << timeStepId << " is not in [0," << _f1ts_cmps.size() << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + const MEDFileField1TSStruct *obj(_f1ts_cmps[timeStepId]); + if(!obj) + { + std::ostringstream oss; oss << "MEDFileFastCellSupportComparator::buildFromScratchDataSetSupport : at time step id #" << timeStepId << " no field structure overview defined !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + return obj->buildFromScratchDataSetSupport(_mesh_comp,globs); +} + +bool MEDFileFastCellSupportComparator::isDataSetSupportEqualToThePreviousOne(int timeStepId, const MEDFileFieldGlobsReal *globs) const +{ + if(timeStepId<=0 || timeStepId>=(int)_f1ts_cmps.size()) + { + std::ostringstream oss; oss << "MEDFileFastCellSupportComparator::isDataSetSupportEqualToThePreviousOne : requested time step id #" << timeStepId << " is not in [1," << _f1ts_cmps.size() << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + const MEDFileField1TSStruct *obj(_f1ts_cmps[timeStepId]); + const MEDFileField1TSStruct *objRef(_f1ts_cmps[timeStepId-1]); + return objRef->isDataSetSupportFastlyEqualTo(*obj,globs); +}