X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FMEDCoupling%2FMEDCouplingStructuredMesh.cxx;h=20982788adddaabd6972ca53d2ba323e4a6fa468;hb=0c9d48870957c4a9f6f82fc8e2c569780a5f886b;hp=efb9cddf3d79901298f86d5cc6c9888dfd05741c;hpb=80f7cb5a2e7e8cc675bf86c52eea13d289c8d1c2;p=modules%2Fmed.git diff --git a/src/MEDCoupling/MEDCouplingStructuredMesh.cxx b/src/MEDCoupling/MEDCouplingStructuredMesh.cxx index efb9cddf3..20982788a 100644 --- a/src/MEDCoupling/MEDCouplingStructuredMesh.cxx +++ b/src/MEDCoupling/MEDCouplingStructuredMesh.cxx @@ -21,6 +21,7 @@ #include "MEDCouplingStructuredMesh.hxx" #include "MEDCouplingFieldDouble.hxx" #include "MEDCouplingMemArray.hxx" +#include "MEDCoupling1GTUMesh.hxx" #include "MEDCouplingUMesh.hxx" #include @@ -39,24 +40,29 @@ MEDCouplingStructuredMesh::~MEDCouplingStructuredMesh() { } -std::size_t MEDCouplingStructuredMesh::getHeapMemorySize() const +std::size_t MEDCouplingStructuredMesh::getHeapMemorySizeWithoutChildren() const { - return MEDCouplingMesh::getHeapMemorySize(); + return MEDCouplingMesh::getHeapMemorySizeWithoutChildren(); } -void MEDCouplingStructuredMesh::copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception) +void MEDCouplingStructuredMesh::copyTinyStringsFrom(const MEDCouplingMesh *other) { MEDCouplingMesh::copyTinyStringsFrom(other); } -bool MEDCouplingStructuredMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception) +bool MEDCouplingStructuredMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const { return MEDCouplingMesh::isEqualIfNotWhy(other,prec,reason); } INTERP_KERNEL::NormalizedCellType MEDCouplingStructuredMesh::getTypeOfCell(int cellId) const { - switch(getMeshDimension()) + return GetGeoTypeGivenMeshDimension(getMeshDimension()); +} + +INTERP_KERNEL::NormalizedCellType MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(int meshDim) +{ + switch(meshDim) { case 3: return INTERP_KERNEL::NORM_HEXA8; @@ -64,8 +70,10 @@ INTERP_KERNEL::NormalizedCellType MEDCouplingStructuredMesh::getTypeOfCell(int c return INTERP_KERNEL::NORM_QUAD4; case 1: return INTERP_KERNEL::NORM_SEG2; + case 0: + return INTERP_KERNEL::NORM_POINT1; default: - throw INTERP_KERNEL::Exception("Unexpected dimension for MEDCouplingCurveLinearMesh::getTypeOfCell !"); + throw INTERP_KERNEL::Exception("Unexpected dimension for MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension !"); } } @@ -86,7 +94,7 @@ int MEDCouplingStructuredMesh::getNumberOfCellsWithType(INTERP_KERNEL::Normalize throw INTERP_KERNEL::Exception(oss.str().c_str()); } -DataArrayInt *MEDCouplingStructuredMesh::giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception) +DataArrayInt *MEDCouplingStructuredMesh::giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const { MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); if(getTypeOfCell(0)==type) @@ -99,7 +107,7 @@ DataArrayInt *MEDCouplingStructuredMesh::giveCellsWithType(INTERP_KERNEL::Normal return ret.retn(); } -DataArrayInt *MEDCouplingStructuredMesh::computeNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception) +DataArrayInt *MEDCouplingStructuredMesh::computeNbOfNodesPerCell() const { int nbCells=getNumberOfCells(); MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); @@ -109,7 +117,7 @@ DataArrayInt *MEDCouplingStructuredMesh::computeNbOfNodesPerCell() const throw(I return ret.retn(); } -DataArrayInt *MEDCouplingStructuredMesh::computeNbOfFacesPerCell() const throw(INTERP_KERNEL::Exception) +DataArrayInt *MEDCouplingStructuredMesh::computeNbOfFacesPerCell() const { int nbCells=getNumberOfCells(); MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); @@ -119,6 +127,18 @@ DataArrayInt *MEDCouplingStructuredMesh::computeNbOfFacesPerCell() const throw(I return ret.retn(); } +/*! + * This method computes effective number of nodes per cell. That is to say nodes appearing several times in nodal connectivity of a cell, + * will be counted only once here whereas it will be counted several times in MEDCouplingMesh::computeNbOfNodesPerCell method. + * Here for structured mesh it returns exactly as MEDCouplingStructuredMesh::computeNbOfNodesPerCell does. + * + * \return DataArrayInt * - new object to be deallocated by the caller. + */ +DataArrayInt *MEDCouplingStructuredMesh::computeEffectiveNbOfNodesPerCell() const +{ + return computeNbOfNodesPerCell(); +} + void MEDCouplingStructuredMesh::getNodeIdsOfCell(int cellId, std::vector& conn) const { int meshDim=getMeshDimension(); @@ -133,13 +153,13 @@ void MEDCouplingStructuredMesh::getNodeIdsOfCell(int cellId, std::vector& c conn.push_back(tmp2[0]); conn.push_back(tmp2[0]+1); break; case 2: - conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]); conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]+1); - conn.push_back((tmp2[1]+1)*(tmpCell[1]+1)+tmp2[0]+1); conn.push_back((tmp2[1]+1)*(tmpCell[1]+1)+tmp2[0]); + conn.push_back(tmp2[1]*tmpNode[1]+tmp2[0]); conn.push_back(tmp2[1]*tmpNode[1]+tmp2[0]+1); + conn.push_back((tmp2[1]+1)*tmpNode[1]+tmp2[0]+1); conn.push_back((tmp2[1]+1)*tmpNode[1]+tmp2[0]); break; case 3: - conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]+tmp2[2]*tmpNode[2]); conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]+1+tmp2[2]*tmpNode[2]); + conn.push_back(tmp2[1]*tmpNode[1]+tmp2[0]+tmp2[2]*tmpNode[2]); conn.push_back(tmp2[1]*tmpNode[1]+tmp2[0]+1+tmp2[2]*tmpNode[2]); conn.push_back((tmp2[1]+1)*tmpNode[1]+tmp2[0]+1+tmp2[2]*tmpNode[2]); conn.push_back((tmp2[1]+1)*tmpNode[1]+tmp2[0]+tmp2[2]*tmpNode[2]); - conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]+(tmp2[2]+1)*tmpNode[2]); conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]+1+(tmp2[2]+1)*tmpNode[2]); + conn.push_back(tmp2[1]*tmpNode[1]+tmp2[0]+(tmp2[2]+1)*tmpNode[2]); conn.push_back(tmp2[1]*tmpNode[1]+tmp2[0]+1+(tmp2[2]+1)*tmpNode[2]); conn.push_back((tmp2[1]+1)*tmpNode[1]+tmp2[0]+1+(tmp2[2]+1)*tmpNode[2]); conn.push_back((tmp2[1]+1)*tmpNode[1]+tmp2[0]+(tmp2[2]+1)*tmpNode[2]); break; default: @@ -150,13 +170,13 @@ void MEDCouplingStructuredMesh::getNodeIdsOfCell(int cellId, std::vector& c /*! * See MEDCouplingUMesh::getDistributionOfTypes for more information */ -std::vector MEDCouplingStructuredMesh::getDistributionOfTypes() const throw(INTERP_KERNEL::Exception) +std::vector MEDCouplingStructuredMesh::getDistributionOfTypes() const { //only one type of cell std::vector ret(3); ret[0]=getTypeOfCell(0); ret[1]=getNumberOfCells(); - ret[2]=0; //ret[3*k+2]==0 because it has no sense here + ret[2]=-1; //ret[3*k+2]==-1 because it has no sense here return ret; } @@ -166,7 +186,7 @@ std::vector MEDCouplingStructuredMesh::getDistributionOfTypes() const throw * * See MEDCouplingUMesh::checkTypeConsistencyAndContig for more information */ -DataArrayInt *MEDCouplingStructuredMesh::checkTypeConsistencyAndContig(const std::vector& code, const std::vector& idsPerType) const throw(INTERP_KERNEL::Exception) +DataArrayInt *MEDCouplingStructuredMesh::checkTypeConsistencyAndContig(const std::vector& code, const std::vector& idsPerType) const { int nbOfCells=getNumberOfCells(); if(code.size()!=3) @@ -224,10 +244,10 @@ DataArrayInt *MEDCouplingStructuredMesh::checkTypeConsistencyAndContig(const std * - After \a code contains [NORM_...,nbCells,0], \a idsInPflPerType [[0,1]] and \a idsPerType is [[1,2]]
*/ -void MEDCouplingStructuredMesh::splitProfilePerType(const DataArrayInt *profile, std::vector& code, std::vector& idsInPflPerType, std::vector& idsPerType) const throw(INTERP_KERNEL::Exception) +void MEDCouplingStructuredMesh::splitProfilePerType(const DataArrayInt *profile, std::vector& code, std::vector& idsInPflPerType, std::vector& idsPerType) const { - if(!profile) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::splitProfilePerType : input profile is NULL !"); + if(!profile || !profile->isAllocated()) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::splitProfilePerType : input profile is NULL or not allocated !"); if(profile->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::splitProfilePerType : input profile should have exactly one component !"); int nbTuples=profile->getNumberOfTuples(); @@ -238,44 +258,48 @@ void MEDCouplingStructuredMesh::splitProfilePerType(const DataArrayInt *profile, if(profile->isIdentity() && nbTuples==nbOfCells) { code[2]=-1; - idsInPflPerType[0]=const_cast(profile); idsInPflPerType[0]->incrRef(); - idsPerType.clear(); + idsInPflPerType[0]=0; + idsPerType.clear(); + return ; } + code[1]=profile->getNumberOfTuples(); code[2]=0; profile->checkAllIdsInRange(0,nbOfCells); idsPerType.resize(1); - idsPerType[0]=const_cast(profile); idsPerType[0]->incrRef(); + idsPerType[0]=profile->deepCpy(); idsInPflPerType[0]=DataArrayInt::Range(0,nbTuples,1); } +/*! + * Creates a new unstructured mesh (MEDCoupling1SGTUMesh) from \a this structured one. + * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to + * delete this array using decrRef() as it is no more needed. + * \throw If \a this->getMeshDimension() is not among [1,2,3]. + */ +MEDCoupling1SGTUMesh *MEDCouplingStructuredMesh::build1SGTUnstructured() const +{ + int meshDim=getMeshDimension(); + if(meshDim<0 || meshDim>3) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::build1SGTUnstructured : meshdim must be in [1,2,3] !"); + MEDCouplingAutoRefCountObjectPtr coords(getCoordinatesAndOwner()); + int ns[3]; + getNodeGridStructure(ns); + MEDCouplingAutoRefCountObjectPtr conn(Build1GTNodalConnectivity(ns,ns+meshDim)); + MEDCouplingAutoRefCountObjectPtr ret(MEDCoupling1SGTUMesh::New(getName(),GetGeoTypeGivenMeshDimension(meshDim))); + ret->setNodalConnectivity(conn); ret->setCoords(coords); + return ret.retn(); +} + /*! * Creates a new unstructured mesh (MEDCouplingUMesh) from \a this structured one. * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to * delete this array using decrRef() as it is no more needed. * \throw If \a this->getMeshDimension() is not among [1,2,3]. */ -MEDCouplingUMesh *MEDCouplingStructuredMesh::buildUnstructured() const throw(INTERP_KERNEL::Exception) +MEDCouplingUMesh *MEDCouplingStructuredMesh::buildUnstructured() const { - int meshDim=getMeshDimension(); - MEDCouplingUMesh *ret=MEDCouplingUMesh::New(getName(),meshDim); - DataArrayDouble *coords=getCoordinatesAndOwner(); - ret->setCoords(coords); - coords->decrRef(); - switch(meshDim) - { - case 1: - fill1DUnstructuredMesh(ret); - break; - case 2: - fill2DUnstructuredMesh(ret); - break; - case 3: - fill3DUnstructuredMesh(ret); - break; - default: - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::buildUnstructured : big problem spacedim must be in 1,2 or 3 !"); - }; - return ret; + MEDCouplingAutoRefCountObjectPtr ret0(build1SGTUnstructured()); + return ret0->buildUnstructured(); } /*! @@ -298,13 +322,32 @@ MEDCouplingMesh *MEDCouplingStructuredMesh::buildPart(const int *start, const in MEDCouplingMesh *MEDCouplingStructuredMesh::buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const { - MEDCouplingUMesh *um=buildUnstructured(); - MEDCouplingMesh *ret=um->buildPartAndReduceNodes(start,end,arr); - um->decrRef(); - return ret; + std::vector cgs(getCellGridStructure()); + std::vector< std::pair > cellPartFormat,nodePartFormat; + if(IsPartStructured(start,end,cgs,cellPartFormat)) + { + MEDCouplingAutoRefCountObjectPtr ret(buildStructuredSubPart(cellPartFormat)); + nodePartFormat=cellPartFormat; + for(std::vector< std::pair >::iterator it=nodePartFormat.begin();it!=nodePartFormat.end();it++) + (*it).second++; + MEDCouplingAutoRefCountObjectPtr tmp1(BuildExplicitIdsFrom(getNodeGridStructure(),nodePartFormat)); + MEDCouplingAutoRefCountObjectPtr tmp2(DataArrayInt::New()); tmp2->alloc(getNumberOfNodes(),1); + tmp2->fillWithValue(-1); + MEDCouplingAutoRefCountObjectPtr tmp3(DataArrayInt::New()); tmp3->alloc(tmp1->getNumberOfTuples(),1); tmp3->iota(0); + tmp2->setPartOfValues3(tmp3,tmp1->begin(),tmp1->end(),0,1,1); + arr=tmp2.retn(); + return ret.retn(); + } + else + { + MEDCouplingUMesh *um=buildUnstructured(); + MEDCouplingMesh *ret=um->buildPartAndReduceNodes(start,end,arr); + um->decrRef(); + return ret; + } } -DataArrayInt *MEDCouplingStructuredMesh::simplexize(int policy) throw(INTERP_KERNEL::Exception) +DataArrayInt *MEDCouplingStructuredMesh::simplexize(int policy) { throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::simplexize : not available for Cartesian mesh !"); } @@ -334,93 +377,243 @@ MEDCouplingFieldDouble *MEDCouplingStructuredMesh::buildOrthogonalField() const return ret; } -void MEDCouplingStructuredMesh::fill1DUnstructuredMesh(MEDCouplingUMesh *m) const +void MEDCouplingStructuredMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const +{ + std::vector ngs(getNodeGridStructure()); + int dim(getSpaceDimension()); + switch(dim) + { + case 1: + return GetReverseNodalConnectivity1(ngs,revNodal,revNodalIndx); + case 2: + return GetReverseNodalConnectivity2(ngs,revNodal,revNodalIndx); + case 3: + return GetReverseNodalConnectivity3(ngs,revNodal,revNodalIndx); + default: + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::getReverseNodalConnectivity : only dimensions 1, 2 and 3 are supported !"); + } +} + +void MEDCouplingStructuredMesh::GetReverseNodalConnectivity1(const std::vector& ngs, DataArrayInt *revNodal, DataArrayInt *revNodalIndx) +{ + int nbNodes(ngs[0]); + revNodalIndx->alloc(nbNodes+1,1); + if(nbNodes==0) + { revNodal->alloc(0,1); revNodalIndx->setIJ(0,0,0); return ; } + if(nbNodes==1) + { revNodal->alloc(1,1); revNodal->setIJ(0,0,0); revNodalIndx->setIJ(0,0,0); revNodalIndx->setIJ(1,0,1); return ; } + revNodal->alloc(2*(nbNodes-1),1); + int *rn(revNodal->getPointer()),*rni(revNodalIndx->getPointer()); + *rni++=0; *rni=1; *rn++=0; + for(int i=1;i& ngs, DataArrayInt *revNodal, DataArrayInt *revNodalIndx) { - int nbOfCells=-1; - getNodeGridStructure(&nbOfCells); - nbOfCells--; - DataArrayInt *connI=DataArrayInt::New(); - connI->alloc(nbOfCells+1,1); - int *ci=connI->getPointer(); - DataArrayInt *conn=DataArrayInt::New(); - conn->alloc(3*nbOfCells,1); - ci[0]=0; + int nbNodesX(ngs[0]),nbNodesY(ngs[1]); + int nbNodes(nbNodesX*nbNodesY); + if(nbNodesX==0 || nbNodesY==0) + { revNodal->alloc(0,1); revNodalIndx->setIJ(0,0,0); return ; } + if(nbNodesX==1 || nbNodesY==1) + { std::vector ngs2(1); ngs2[0]=std::max(nbNodesX,nbNodesY); return GetReverseNodalConnectivity1(ngs2,revNodal,revNodalIndx); } + revNodalIndx->alloc(nbNodes+1,1); + int nbCellsX(nbNodesX-1),nbCellsY(nbNodesY-1); + revNodal->alloc(4*(nbNodesX-2)*(nbNodesY-2)+2*2*(nbNodesX-2)+2*2*(nbNodesY-2)+4,1); + int *rn(revNodal->getPointer()),*rni(revNodalIndx->getPointer()); + *rni++=0; *rni=1; *rn++=0; + for(int i=1;i& ngs, DataArrayInt *revNodal, DataArrayInt *revNodalIndx) +{ + int nbNodesX(ngs[0]),nbNodesY(ngs[1]),nbNodesZ(ngs[2]); + int nbNodes(nbNodesX*nbNodesY*nbNodesZ); + if(nbNodesX==0 || nbNodesY==0 || nbNodesZ==0) + { revNodal->alloc(0,1); revNodalIndx->setIJ(0,0,0); return ; } + if(nbNodesX==1 || nbNodesY==1 || nbNodesZ==1) + { + std::vector ngs2(2); + int pos(0); + bool pass(false); + for(int i=0;i<3;i++) + { + if(pass) + { ngs2[pos++]=ngs[i]; } + else + { + pass=ngs[i]==1; + if(!pass) + { ngs2[pos++]=ngs[i]; } + } + } + return GetReverseNodalConnectivity2(ngs2,revNodal,revNodalIndx); + } + revNodalIndx->alloc(nbNodes+1,1); + int nbCellsX(nbNodesX-1),nbCellsY(nbNodesY-1),nbCellsZ(nbNodesZ-1); + revNodal->alloc(8*(nbNodesX-2)*(nbNodesY-2)*(nbNodesZ-2)+4*(2*(nbNodesX-2)*(nbNodesY-2)+2*(nbNodesX-2)*(nbNodesZ-2)+2*(nbNodesY-2)*(nbNodesZ-2))+2*4*(nbNodesX-2)+2*4*(nbNodesY-2)+2*4*(nbNodesZ-2)+8,1); + int *rn(revNodal->getPointer()),*rni(revNodalIndx->getPointer()); + *rni=0; + for(int k=0;k=1 && j>=1 && i>=1) + *rn++=off00+i-1; + if(k>=1 && j>=1 && i=1 && j=1) + *rn++=off01+i-1; + if(k>=1 && j=1 && i>=1) + *rn++=off10+i-1; + if(k=1 && i=1) + *rn++=off11+i-1; + if(k conn(DataArrayInt::New()); + conn->alloc(1,1); conn->setIJ(0,0,0); + return conn.retn(); + } + case 1: + return Build1GTNodalConnectivity1D(nodeStBg); + case 2: + return Build1GTNodalConnectivity2D(nodeStBg); + case 3: + return Build1GTNodalConnectivity3D(nodeStBg); + default: + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::Build1GTNodalConnectivity : only dimension in [0,1,2,3] supported !"); + } +} + +DataArrayInt *MEDCouplingStructuredMesh::Build1GTNodalConnectivity1D(const int *nodeStBg) +{ + int nbOfCells(*nodeStBg-1); + MEDCouplingAutoRefCountObjectPtr conn(DataArrayInt::New()); + conn->alloc(2*nbOfCells,1); int *cp=conn->getPointer(); for(int i=0;isetConnectivity(conn,connI,true); - conn->decrRef(); - connI->decrRef(); + return conn.retn(); } -void MEDCouplingStructuredMesh::fill2DUnstructuredMesh(MEDCouplingUMesh *m) const +DataArrayInt *MEDCouplingStructuredMesh::Build1GTNodalConnectivity2D(const int *nodeStBg) { - int ns[2]; - getNodeGridStructure(ns); - int n1=ns[0]-1; - int n2=ns[1]-1; - DataArrayInt *connI=DataArrayInt::New(); - connI->alloc(n1*n2+1,1); - int *ci=connI->getPointer(); - DataArrayInt *conn=DataArrayInt::New(); - conn->alloc(5*n1*n2,1); - ci[0]=0; + int n1=nodeStBg[0]-1; + int n2=nodeStBg[1]-1; + MEDCouplingAutoRefCountObjectPtr conn(DataArrayInt::New()); + conn->alloc(4*n1*n2,1); int *cp=conn->getPointer(); int pos=0; for(int j=0;jsetConnectivity(conn,connI,true); - conn->decrRef(); - connI->decrRef(); + return conn.retn(); } -void MEDCouplingStructuredMesh::fill3DUnstructuredMesh(MEDCouplingUMesh *m) const +DataArrayInt *MEDCouplingStructuredMesh::Build1GTNodalConnectivity3D(const int *nodeStBg) { - int ns[3]; - getNodeGridStructure(ns); - int n1=ns[0]-1; - int n2=ns[1]-1; - int n3=ns[2]-1; - DataArrayInt *connI=DataArrayInt::New(); - connI->alloc(n1*n2*n3+1,1); - int *ci=connI->getPointer(); - DataArrayInt *conn=DataArrayInt::New(); - conn->alloc(9*n1*n2*n3,1); - ci[0]=0; + int n1=nodeStBg[0]-1; + int n2=nodeStBg[1]-1; + int n3=nodeStBg[2]-1; + MEDCouplingAutoRefCountObjectPtr conn(DataArrayInt::New()); + conn->alloc(8*n1*n2*n3,1); int *cp=conn->getPointer(); int pos=0; for(int k=0;ksetConnectivity(conn,connI,true); - conn->decrRef(); - connI->decrRef(); + return conn.retn(); } /*! @@ -435,7 +628,7 @@ int MEDCouplingStructuredMesh::getCellIdFromPos(int i, int j, int k) const { int tmp[3]={i,j,k}; int tmp2[3]; - int meshDim=getMeshDimension(); + int meshDim(getMeshDimension()); getSplitCellValues(tmp2); std::transform(tmp,tmp+meshDim,tmp2,tmp,std::multiplies()); return std::accumulate(tmp,tmp+meshDim,0); @@ -452,10 +645,10 @@ int MEDCouplingStructuredMesh::getNodeIdFromPos(int i, int j, int k) const { int tmp[3]={i,j,k}; int tmp2[3]; - int meshDim=getMeshDimension(); + int spaceDim(getSpaceDimension()); getSplitNodeValues(tmp2); - std::transform(tmp,tmp+meshDim,tmp2,tmp,std::multiplies()); - return std::accumulate(tmp,tmp+meshDim,0); + std::transform(tmp,tmp+spaceDim,tmp2,tmp,std::multiplies()); + return std::accumulate(tmp,tmp+spaceDim,0); } void MEDCouplingStructuredMesh::GetPosFromId(int nodeId, int meshDim, const int *split, int *res) @@ -468,3 +661,166 @@ void MEDCouplingStructuredMesh::GetPosFromId(int nodeId, int meshDim, const int res[i]=pos; } } + +std::vector MEDCouplingStructuredMesh::getCellGridStructure() const +{ + std::vector ret(getNodeGridStructure()); + std::transform(ret.begin(),ret.end(),ret.begin(),std::bind2nd(std::plus(),-1)); + return ret; +} + +/*! + * This method states if given part ids [ \a startIds, \a stopIds) and a structure \a st returns if it can be considered as a structured dataset. + * If true is returned \a partCompactFormat will contain the information to build the corresponding part. + * + * \sa MEDCouplingStructuredMesh::BuildExplicitIdsFrom + */ +bool MEDCouplingStructuredMesh::IsPartStructured(const int *startIds, const int *stopIds, const std::vector& st, std::vector< std::pair >& partCompactFormat) +{ + int dim((int)st.size()); + partCompactFormat.resize(dim); + if(dim<1 || dim>3) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::isPartStructured : input structure must be of dimension in [1,2,3] !"); + std::vector tmp2(dim),tmp(dim),tmp3(dim),tmp4(dim); tmp2[0]=1; + for(int i=1;i=st[dim-1]) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::IsPartStructured : first id in input is not in valid range !"); + if(sz==1) + { + for(int i=0;i=st[i]) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::IsPartStructured : last id in input is not in valid range !"); + partCompactFormat[i].second=tmp3[i]+1; + tmp4[i]=partCompactFormat[i].second-partCompactFormat[i].first; + if(tmp4[i]<=0) + return false; + szExp*=tmp4[i]; + } + if(szExp!=(int)sz) + return false; + const int *w(startIds); + switch(dim) + { + case 3: + { + for(int i=0;i& st, const std::vector< std::pair >& partCompactFormat) +{ + if(st.size()!=partCompactFormat.size()) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::BuildExplicitIdsFrom : input arrays must have the same size !"); + int nbOfItems(1); + std::vector dims(st.size()); + for(std::size_t i=0;ist[i]) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::BuildExplicitIdsFrom : invalid input range 1 !"); + if(partCompactFormat[i].second<0 || partCompactFormat[i].second>st[i]) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::BuildExplicitIdsFrom : invalid input range 2 !"); + if(partCompactFormat[i].second<=partCompactFormat[i].first) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::BuildExplicitIdsFrom : invalid input range 3 !"); + dims[i]=partCompactFormat[i].second-partCompactFormat[i].first; + nbOfItems*=dims[i]; + } + MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); + ret->alloc(nbOfItems,1); + int *pt(ret->getPointer()); + switch(st.size()) + { + case 3: + { + for(int i=0;i