X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FMEDCoupling%2FMEDCouplingStructuredMesh.cxx;h=a6b9706fdb84a3dcfba4ff8bbfab5b5995dbc6a6;hb=e7835cba1eb17f50ef4e130c2cb8d0f54bc25083;hp=6328cb325b4a49678758c5bff53ca7e01a619ace;hpb=e8f6d0c2ecb69600ee7cc75a309f266aafd50a1b;p=tools%2Fmedcoupling.git diff --git a/src/MEDCoupling/MEDCouplingStructuredMesh.cxx b/src/MEDCoupling/MEDCouplingStructuredMesh.cxx index 6328cb325..a6b9706fd 100644 --- a/src/MEDCoupling/MEDCouplingStructuredMesh.cxx +++ b/src/MEDCoupling/MEDCouplingStructuredMesh.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2014 CEA/DEN, EDF R&D +// Copyright (C) 2007-2016 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 @@ -23,16 +23,17 @@ #include "MEDCouplingMemArray.hxx" #include "MEDCoupling1GTUMesh.hxx" #include "MEDCouplingUMesh.hxx" +#include "MEDCouplingIMesh.hxx"//tony to throw when optimization will be performed in AssignPartOfFieldOfDoubleUsing #include -using namespace ParaMEDMEM; +using namespace MEDCoupling; MEDCouplingStructuredMesh::MEDCouplingStructuredMesh() { } -MEDCouplingStructuredMesh::MEDCouplingStructuredMesh(const MEDCouplingStructuredMesh& other, bool deepCopy):MEDCouplingMesh(other) +MEDCouplingStructuredMesh::MEDCouplingStructuredMesh(const MEDCouplingStructuredMesh& other, bool deepCpy):MEDCouplingMesh(other) { } @@ -55,7 +56,7 @@ bool MEDCouplingStructuredMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, do return MEDCouplingMesh::isEqualIfNotWhy(other,prec,reason); } -INTERP_KERNEL::NormalizedCellType MEDCouplingStructuredMesh::getTypeOfCell(int cellId) const +INTERP_KERNEL::NormalizedCellType MEDCouplingStructuredMesh::getTypeOfCell(std::size_t cellId) const { return GetGeoTypeGivenMeshDimension(getMeshDimension()); } @@ -84,19 +85,19 @@ std::set MEDCouplingStructuredMesh::getAllGeo return ret2; } -int MEDCouplingStructuredMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const +std::size_t MEDCouplingStructuredMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const { - int ret=getNumberOfCells(); + std::size_t ret(getNumberOfCells()); if(type==getTypeOfCell(0)) return ret; - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(getTypeOfCell(0)); + const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(getTypeOfCell(0))); std::ostringstream oss; oss << "MEDCouplingStructuredMesh::getNumberOfCellsWithType : no specified type ! Type available is " << cm.getRepr() << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } DataArrayInt *MEDCouplingStructuredMesh::giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const { - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); + MCAuto ret=DataArrayInt::New(); if(getTypeOfCell(0)==type) { ret->alloc(getNumberOfCells(),1); @@ -110,7 +111,7 @@ DataArrayInt *MEDCouplingStructuredMesh::giveCellsWithType(INTERP_KERNEL::Normal DataArrayInt *MEDCouplingStructuredMesh::computeNbOfNodesPerCell() const { int nbCells=getNumberOfCells(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); + MCAuto ret=DataArrayInt::New(); ret->alloc(nbCells,1); const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(getTypeOfCell(0)); ret->fillWithValue((int)cm.getNumberOfNodes()); @@ -120,7 +121,7 @@ DataArrayInt *MEDCouplingStructuredMesh::computeNbOfNodesPerCell() const DataArrayInt *MEDCouplingStructuredMesh::computeNbOfFacesPerCell() const { int nbCells=getNumberOfCells(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); + MCAuto ret=DataArrayInt::New(); ret->alloc(nbCells,1); const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(getTypeOfCell(0)); ret->fillWithValue((int)cm.getNumberOfSons()); @@ -139,7 +140,7 @@ DataArrayInt *MEDCouplingStructuredMesh::computeEffectiveNbOfNodesPerCell() cons return computeNbOfNodesPerCell(); } -void MEDCouplingStructuredMesh::getNodeIdsOfCell(int cellId, std::vector& conn) const +void MEDCouplingStructuredMesh::getNodeIdsOfCell(std::size_t cellId, std::vector& conn) const { int meshDim=getMeshDimension(); int tmpCell[3],tmpNode[3]; @@ -309,21 +310,21 @@ 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 +void MEDCouplingStructuredMesh::splitProfilePerType(const DataArrayInt *profile, std::vector& code, std::vector& idsInPflPerType, std::vector& idsPerType, bool smartPflKiller) const { 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(); + int nbTuples(profile->getNumberOfTuples()); int nbOfCells=getNumberOfCells(); code.resize(3); idsInPflPerType.resize(1); code[0]=(int)getTypeOfCell(0); code[1]=nbOfCells; idsInPflPerType.resize(1); - if(profile->isIdentity() && nbTuples==nbOfCells) + if(smartPflKiller && profile->isIota(nbOfCells)) { code[2]=-1; - idsInPflPerType[0]=0; + idsInPflPerType[0]=profile->deepCopy(); idsPerType.clear(); return ; } @@ -331,12 +332,16 @@ void MEDCouplingStructuredMesh::splitProfilePerType(const DataArrayInt *profile, code[2]=0; profile->checkAllIdsInRange(0,nbOfCells); idsPerType.resize(1); - idsPerType[0]=profile->deepCpy(); + idsPerType[0]=profile->deepCopy(); idsInPflPerType[0]=DataArrayInt::Range(0,nbTuples,1); } /*! * Creates a new unstructured mesh (MEDCoupling1SGTUMesh) from \a this structured one. + * + * In the returned mesh, the nodes are ordered with the first axis varying first: (X0,Y0), (X1,Y0), ... (X0,Y1), (X1,Y1), ... + * and the cells are ordered with the same logic, i.e. in (i,j) notation: (0,0), (1,0), (2,0), ... (0,1), (1,1), ... + * * \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]. @@ -346,11 +351,11 @@ MEDCoupling1SGTUMesh *MEDCouplingStructuredMesh::build1SGTUnstructured() const int meshDim(getMeshDimension()),spaceDim(getSpaceDimensionOnNodeStruct()); if((meshDim<0 || meshDim>3) || (spaceDim<0 || spaceDim>3)) throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::build1SGTUnstructured : meshdim and spacedim must be in [1,2,3] !"); - MEDCouplingAutoRefCountObjectPtr coords(getCoordinatesAndOwner()); + MCAuto coords(getCoordinatesAndOwner()); int ns[3]; getNodeGridStructure(ns); - MEDCouplingAutoRefCountObjectPtr conn(Build1GTNodalConnectivity(ns,ns+spaceDim)); - MEDCouplingAutoRefCountObjectPtr ret(MEDCoupling1SGTUMesh::New(getName(),GetGeoTypeGivenMeshDimension(meshDim))); + MCAuto conn(Build1GTNodalConnectivity(ns,ns+spaceDim)); + MCAuto ret(MEDCoupling1SGTUMesh::New(getName(),GetGeoTypeGivenMeshDimension(meshDim))); ret->setNodalConnectivity(conn); ret->setCoords(coords); try { ret->copyTinyInfoFrom(this); } @@ -369,24 +374,28 @@ MEDCoupling1SGTUMesh *MEDCouplingStructuredMesh::build1SGTSubLevelMesh() const int meshDim(getMeshDimension()); if(meshDim<1 || meshDim>3) throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::build1SGTSubLevelMesh : meshdim must be in [2,3] !"); - MEDCouplingAutoRefCountObjectPtr coords(getCoordinatesAndOwner()); + MCAuto coords(getCoordinatesAndOwner()); int ns[3]; getNodeGridStructure(ns); - MEDCouplingAutoRefCountObjectPtr conn(Build1GTNodalConnectivityOfSubLevelMesh(ns,ns+meshDim)); - MEDCouplingAutoRefCountObjectPtr ret(MEDCoupling1SGTUMesh::New(getName(),GetGeoTypeGivenMeshDimension(meshDim-1))); + MCAuto conn(Build1GTNodalConnectivityOfSubLevelMesh(ns,ns+meshDim)); + MCAuto ret(MEDCoupling1SGTUMesh::New(getName(),GetGeoTypeGivenMeshDimension(meshDim-1))); ret->setNodalConnectivity(conn); ret->setCoords(coords); return ret.retn(); } /*! * Creates a new unstructured mesh (MEDCouplingUMesh) from \a this structured one. + * + * In the returned mesh, the nodes are ordered with the first axis varying first: (X0,Y0), (X1,Y0), ... (X0,Y1), (X1,Y1), ... + * and the cells are ordered with the same logic, i.e. in (i,j) notation: (0,0), (1,0), (2,0), ... (0,1), (1,1), ... + * * \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 { - MEDCouplingAutoRefCountObjectPtr ret0(build1SGTUnstructured()); + MCAuto ret0(build1SGTUnstructured()); return ret0->buildUnstructured(); } @@ -402,10 +411,8 @@ MEDCouplingUMesh *MEDCouplingStructuredMesh::buildUnstructured() const */ MEDCouplingMesh *MEDCouplingStructuredMesh::buildPart(const int *start, const int *end) const { - MEDCouplingUMesh *um=buildUnstructured(); - MEDCouplingMesh *ret=um->buildPart(start,end); - um->decrRef(); - return ret; + MCAuto um(buildUnstructured()); + return um->buildPart(start,end); } MEDCouplingMesh *MEDCouplingStructuredMesh::buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const @@ -414,24 +421,22 @@ MEDCouplingMesh *MEDCouplingStructuredMesh::buildPartAndReduceNodes(const int *s std::vector< std::pair > cellPartFormat,nodePartFormat; if(IsPartStructured(start,end,cgs,cellPartFormat)) { - MEDCouplingAutoRefCountObjectPtr ret(buildStructuredSubPart(cellPartFormat)); + MCAuto 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); + MCAuto tmp1(BuildExplicitIdsFrom(getNodeGridStructure(),nodePartFormat)); + MCAuto tmp2(DataArrayInt::New()); tmp2->alloc(getNumberOfNodes(),1); tmp2->fillWithValue(-1); - MEDCouplingAutoRefCountObjectPtr tmp3(DataArrayInt::New()); tmp3->alloc(tmp1->getNumberOfTuples(),1); tmp3->iota(0); + MCAuto 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; + MCAuto um(buildUnstructured()); + return um->buildPartAndReduceNodes(start,end,arr); } } @@ -452,17 +457,16 @@ MEDCouplingFieldDouble *MEDCouplingStructuredMesh::buildOrthogonalField() const { if(getMeshDimension()!=2) throw INTERP_KERNEL::Exception("Expected a MEDCouplingStructuredMesh with meshDim == 2 !"); - MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - DataArrayDouble *array=DataArrayDouble::New(); - int nbOfCells=getNumberOfCells(); + MCAuto ret(MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME)); + MCAuto array(DataArrayDouble::New()); + int nbOfCells(getNumberOfCells()); array->alloc(nbOfCells,3); - double *vals=array->getPointer(); + double *vals(array->getPointer()); for(int i=0;isetArray(array); - array->decrRef(); ret->setMesh(this); - return ret; + return ret.retn(); } void MEDCouplingStructuredMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const @@ -631,7 +635,7 @@ DataArrayInt *MEDCouplingStructuredMesh::Build1GTNodalConnectivity(const int *no { case 0: { - MEDCouplingAutoRefCountObjectPtr conn(DataArrayInt::New()); + MCAuto conn(DataArrayInt::New()); conn->alloc(1,1); conn->setIJ(0,0,0); return conn.retn(); } @@ -660,6 +664,85 @@ DataArrayInt *MEDCouplingStructuredMesh::Build1GTNodalConnectivityOfSubLevelMesh } } +/*! + * This method returns the list of ids sorted ascendingly of entities that are in the corner in ghost zone. + * The ids are returned in a newly created DataArrayInt having a single component. + * + * \param [in] st - The structure \b without ghost cells. + * \param [in] ghostLev - The size of the ghost zone (>=0) + * \return DataArrayInt * - The DataArray containing all the ids the caller is to deallocate. + */ +DataArrayInt *MEDCouplingStructuredMesh::ComputeCornersGhost(const std::vector& st, int ghostLev) +{ + if(ghostLev<0) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ComputeCornersGhost : ghost lev must be >= 0 !"); + std::size_t dim(st.size()); + MCAuto ret(DataArrayInt::New()); + switch(dim) + { + case 1: + { + ret->alloc(2*ghostLev,1); + int *ptr(ret->getPointer()); + for(int i=0;i= 0 !"); + for(int i=0;i= 0 !"); + ret->alloc(4*ghostLev,1); + int *ptr(ret->getPointer()); + for(int i=0;i= 0 !"); + ret->alloc(8*ghostLev,1); + int *ptr(ret->getPointer()); + int zeOffsetZ((offsetX+2*ghostLev)*(offsetY+2*ghostLev)); + for(int i=0;i=0;i--,j++) + { + *ptr++=i*(2*ghostLev+offsetX+1)+j*zeOffsetZ+zeOffsetZ2; + *ptr++=offsetX+2*ghostLev-1+i*(2*ghostLev+offsetX-1)+j*zeOffsetZ+zeOffsetZ2; + *ptr++=(2*ghostLev+offsetX)*(offsetY+ghostLev)+ghostLev-1+(ghostLev-i-1)*(2*ghostLev+offsetX-1)+j*zeOffsetZ+zeOffsetZ2; + *ptr++=(2*ghostLev+offsetX)*(offsetY+ghostLev)+offsetX+ghostLev+(ghostLev-i-1)*(2*ghostLev+offsetX+1)+j*zeOffsetZ+zeOffsetZ2; + } + break; + } + default: + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ComputeCornersGhost : Only dimensions 1, 2 and 3 are supported actually !"); + } + return ret.retn(); +} + /*! * This method retrieves the number of entities (it can be cells or nodes) given a range in compact standard format * used in methods like BuildExplicitIdsFrom,IsPartStructured. @@ -669,7 +752,6 @@ DataArrayInt *MEDCouplingStructuredMesh::Build1GTNodalConnectivityOfSubLevelMesh int MEDCouplingStructuredMesh::DeduceNumberOfGivenRangeInCompactFrmt(const std::vector< std::pair >& partCompactFormat) { int ret(1); - bool isFetched(false); std::size_t ii(0); for(std::vector< std::pair >::const_iterator it=partCompactFormat.begin();it!=partCompactFormat.end();it++,ii++) { @@ -679,13 +761,9 @@ int MEDCouplingStructuredMesh::DeduceNumberOfGivenRangeInCompactFrmt(const std:: std::ostringstream oss; oss << "MEDCouplingStructuredMesh::DeduceNumberOfGivenRangeInCompactFrmt : invalid input at dimension " << ii << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } - if(b-a>0) - { - isFetched=true; - ret*=(b-a); - } + ret*=(b-a); } - return isFetched?ret:0; + return ret; } int MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(const std::vector& st) @@ -729,14 +807,17 @@ void MEDCouplingStructuredMesh::FindTheWidestAxisOfGivenRangeInCompactFrmt(const * \a partCompactFormat that contains all the True in \a crit. The returned vector of boolean is the field reduced to that part. * So the number of True is equal in \a st and in returned vector of boolean. * + * \param [in] minPatchLgth - minimum length that the patch may have for all directions. * \param [in] st - The structure per axis of the structured mesh considered. * \param [in] crit - The field of boolean (for performance reasons) lying on the mesh defined by \a st. * \param [out] partCompactFormat - The minimal part of \a st containing all the true of \a crit. * \param [out] reducedCrit - The reduction of \a criterion on \a partCompactFormat. * \return - The number of True in \a st (that is equal to those in \a reducedCrit) */ -int MEDCouplingStructuredMesh::FindMinimalPartOf(const std::vector& st, const std::vector& crit, std::vector& reducedCrit, std::vector< std::pair >& partCompactFormat) +int MEDCouplingStructuredMesh::FindMinimalPartOf(int minPatchLgth, const std::vector& st, const std::vector& crit, std::vector& reducedCrit, std::vector< std::pair >& partCompactFormat) { + if(minPatchLgth<0) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::FindMinimalPartOf : the input minPatchLgth has to be >=0 !"); if((int)crit.size()!=DeduceNumberOfGivenStructure(st)) throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::FindMinimalPartOf : size of vector of boolean is invalid regarding the declared structure !"); int ret(-1); @@ -760,6 +841,29 @@ int MEDCouplingStructuredMesh::FindMinimalPartOf(const std::vector& st, con default: throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::FindMinimalPartOf : only dimension 1, 2 and 3 are supported actually !"); } + std::vector dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(partCompactFormat)); + int i(0); + for(std::vector< std::pair >::iterator it=partCompactFormat.begin();it!=partCompactFormat.end();it++,i++) + { + if(st[i]st[i]) + { + (*it).first-=(*it).second-st[i]; + (*it).second=st[i]; + } + } + } ExtractFieldOfBoolFrom(st,crit,partCompactFormat,reducedCrit); return ret; } @@ -861,11 +965,11 @@ std::vector< std::vector > MEDCouplingStructuredMesh::ComputeSignaturePerAx DataArrayInt *MEDCouplingStructuredMesh::Build1GTNodalConnectivity1D(const int *nodeStBg) { - int nbOfCells(*nodeStBg-1); - MEDCouplingAutoRefCountObjectPtr conn(DataArrayInt::New()); + std::size_t nbOfCells(*nodeStBg-1); + MCAuto conn(DataArrayInt::New()); conn->alloc(2*nbOfCells,1); int *cp=conn->getPointer(); - for(int i=0;i conn(DataArrayInt::New()); + std::size_t n1(nodeStBg[0]-1),n2(nodeStBg[1]-1); + MCAuto conn(DataArrayInt::New()); conn->alloc(4*n1*n2,1); - int *cp=conn->getPointer(); - int pos=0; - for(int j=0;jgetPointer()); + std::size_t pos(0); + for(std::size_t j=0;j conn(DataArrayInt::New()); + std::size_t n1(nodeStBg[0]-1),n2(nodeStBg[1]-1),n3(nodeStBg[2]-1); + MCAuto conn(DataArrayInt::New()); conn->alloc(8*n1*n2*n3,1); - int *cp=conn->getPointer(); - int pos=0; - for(int k=0;kgetPointer()); + std::size_t pos(0); + for(std::size_t k=0;k ngs(3); int n0(nodeStBg[0]-1),n1(nodeStBg[1]-1),n2(nodeStBg[2]-1); ngs[0]=n0; ngs[1]=n1; ngs[2]=n2; int off0(nodeStBg[0]),off1(nodeStBg[0]*nodeStBg[1]); - MEDCouplingAutoRefCountObjectPtr conn(DataArrayInt::New()); + MCAuto conn(DataArrayInt::New()); conn->alloc(4*GetNumberOfCellsOfSubLevelMesh(ngs,3)); int *cp(conn->getPointer()); //X @@ -962,7 +1063,16 @@ int MEDCouplingStructuredMesh::FindMinimalPartOf1D(const std::vector& st, c } } if(ret==0) - return ret; + { + std::size_t sz(st.size()); + partCompactFormat.resize(sz); + for(std::size_t i=0;i& st, c } } if(ret==0) - return ret; + { + std::size_t sz(st.size()); + partCompactFormat.resize(sz); + for(std::size_t i=0;i& st, c } } if(ret==0) - return ret; + { + std::size_t sz(st.size()); + partCompactFormat.resize(sz); + for(std::size_t i=0;i ngs(2); int n0(nodeStBg[0]-1),n1(nodeStBg[1]-1); ngs[0]=n0; ngs[1]=n1; int off0(nodeStBg[0]); - MEDCouplingAutoRefCountObjectPtr conn(DataArrayInt::New()); + MCAuto conn(DataArrayInt::New()); conn->alloc(2*GetNumberOfCellsOfSubLevelMesh(ngs,2)); int *cp(conn->getPointer()); //X @@ -1111,10 +1239,10 @@ int MEDCouplingStructuredMesh::getNodeIdFromPos(int i, int j, int k) const } -int MEDCouplingStructuredMesh::getNumberOfCells() const +std::size_t MEDCouplingStructuredMesh::getNumberOfCells() const { std::vector ngs(getNodeGridStructure()); - int ret(1); + std::size_t ret(1); bool isCatched(false); std::size_t ii(0); for(std::vector::const_iterator it=ngs.begin();it!=ngs.end();it++,ii++) @@ -1143,9 +1271,55 @@ int MEDCouplingStructuredMesh::getNumberOfNodes() const return ret; } -void MEDCouplingStructuredMesh::GetPosFromId(int nodeId, int meshDim, const int *split, int *res) +/*! + * This method returns for a cell which id is \a cellId the location (locX,locY,locZ) of this cell in \a this. + * + * \param [in] cellId + * \return - A vector of size this->getMeshDimension() + * \throw if \a cellId not in [ 0, this->getNumberOfCells() ) + */ +std::vector MEDCouplingStructuredMesh::getLocationFromCellId(int cellId) const +{ + int meshDim(getMeshDimension()); + std::vector ret(meshDim); + std::vector struc(getCellGridStructure()); + int nbCells(std::accumulate(struc.begin(),struc.end(),1,std::multiplies())); + if(cellId<0 || cellId>=nbCells) + { + std::ostringstream oss; oss << "MEDCouplingStructuredMesh::getLocationFromCellId : Input cell id (" << cellId << ") is invalid ! Should be in [0," << nbCells << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + std::vector spt(GetSplitVectFromStruct(struc)); + GetPosFromId(cellId,meshDim,&spt[0],&ret[0]); + return ret; +} + +/*! + * This method returns for a node which id is \a nodeId the location (locX,locY,locZ) of this node in \a this. + * + * \param [in] nodeId + * \return - A vector of size this->getSpaceDimension() + * \throw if \a cellId not in [ 0, this->getNumberOfNodes() ) + */ +std::vector MEDCouplingStructuredMesh::getLocationFromNodeId(int nodeId) const { - int work=nodeId; + int spaceDim(getSpaceDimension()); + std::vector ret(spaceDim); + std::vector struc(getNodeGridStructure()); + int nbNodes(std::accumulate(struc.begin(),struc.end(),1,std::multiplies())); + if(nodeId<0 || nodeId>=nbNodes) + { + std::ostringstream oss; oss << "MEDCouplingStructuredMesh::getLocationFromNodeId : Input node id (" << nodeId << ") is invalid ! Should be in [0," << nbNodes << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + std::vector spt(GetSplitVectFromStruct(struc)); + GetPosFromId(nodeId,spaceDim,&spt[0],&ret[0]); + return ret; +} + +void MEDCouplingStructuredMesh::GetPosFromId(int eltId, int meshDim, const int *split, int *res) +{ + int work(eltId); for(int i=meshDim-1;i>=0;i--) { int pos=work/split[i]; @@ -1161,6 +1335,30 @@ std::vector MEDCouplingStructuredMesh::getCellGridStructure() const return ret; } +/*! + * This method returns the squareness of \a this (quadrature). \a this is expected to be with a mesh dimension equal to 2 or 3. + */ +double MEDCouplingStructuredMesh::computeSquareness() const +{ + std::vector cgs(getCellGridStructure()); + if(cgs.empty()) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::computeSquareness : empty mesh !"); + std::size_t dim(cgs.size()); + if(dim==1) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::computeSquareness : A segment cannot be square !"); + if(dim<4) + { + int minAx(cgs[0]),maxAx(cgs[0]); + for(std::size_t i=1;i > MEDCouplingStructuredMesh::GetCompactFrmtFromD /*! * This method returns the intersection zone of two ranges (in compact format) \a r1 and \a r2. * This method will throw exception if on one axis the intersection is empty. + * + * \sa AreRangesIntersect */ std::vector< std::pair > MEDCouplingStructuredMesh::IntersectRanges(const std::vector< std::pair >& r1, const std::vector< std::pair >& r2) { @@ -1348,6 +1548,36 @@ std::vector< std::pair > MEDCouplingStructuredMesh::IntersectRanges(con return ret; } +/*! + * This method states if \a r1 and \a r2 do overlap of not. If yes you can call IntersectRanges to know the intersection area. + * + * \sa IntersectRanges + */ +bool MEDCouplingStructuredMesh::AreRangesIntersect(const std::vector< std::pair >& r1, const std::vector< std::pair >& r2) +{ + std::size_t sz(r1.size()); + if(sz!=r2.size()) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::AreRangesIntersect : the two ranges must have the same dimension !"); + for(std::size_t i=0;ir1[i].second) + { + std::ostringstream oss; oss << "MEDCouplingStructuredMesh::AreRangesIntersect : On axis " << i << " of range r1, end is before start !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(r2[i].first>r2[i].second) + { + std::ostringstream oss; oss << "MEDCouplingStructuredMesh::AreRangesIntersect : On axis " << i << " of range r2, end is before start !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(r1[i].second<=r2[i].first) + return false; + if(r1[i].first>=r2[i].second) + return false; + } + return true; +} + /*! * This method is close to BuildExplicitIdsFrom except that instead of returning a DataArrayInt instance containing explicit ids it * enable elems in the vector of booleans (for performance reasons). As it is method for performance, this method is \b not @@ -1483,7 +1713,7 @@ DataArrayDouble *MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom(const std:: throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom : invalid size of input array of double regarding the structure !"); std::vector dims(GetDimensionsFromCompactFrmt(partCompactFormat)); int nbOfTuplesOfOutField(DeduceNumberOfGivenStructure(dims)),nbComp(fieldOfDbl->getNumberOfComponents()); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayDouble::New()); ret->alloc(nbOfTuplesOfOutField,nbComp); + MCAuto ret(DataArrayDouble::New()); ret->alloc(nbOfTuplesOfOutField,nbComp); ret->copyStringInfoFrom(*fieldOfDbl); double *ptRet(ret->getPointer()); const double *fieldOfDblPtr(fieldOfDbl->begin()); @@ -1525,6 +1755,20 @@ DataArrayDouble *MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom(const std:: return ret.retn(); } +/*! + * This method assign a part of values in \a fieldOfDbl using entirely values of \b other. + * + * \param [in] st - the structure of \a fieldOfDbl. + * \param [in,out] fieldOfDbl - the array that will be partially filled using \a other. + * \param [in] partCompactFormat - the specification of the part. + * \param [in] other - the array that will be used to fill \a fieldOfDbl. + */ +void MEDCouplingStructuredMesh::AssignPartOfFieldOfDoubleUsing(const std::vector& st, DataArrayDouble *fieldOfDbl, const std::vector< std::pair >& partCompactFormat, const DataArrayDouble *other) +{//to be optimized + std::vector facts(st.size(),1.); + MEDCouplingIMesh::CondenseFineToCoarse(st,other,partCompactFormat,facts,fieldOfDbl); +} + /*! * This method changes the reference of a part of structured mesh \a partOfBigInAbs define in absolute reference to a new reference \a bigInAbs. * So this method only performs a translation by doing \a partOfBigRelativeToBig = \a partOfBigInAbs - \a bigInAbs @@ -1643,10 +1887,10 @@ std::vector MEDCouplingStructuredMesh::FindTranslationFrom(const std::vecto /*! * This method builds the explicit entity array from the structure in \a st and the range in \a partCompactFormat. - * If the range contains invalid values regarding sructure an exception will be thrown. + * If the range contains invalid values regarding structure an exception will be thrown. * * \return DataArrayInt * - a new object. - * \sa MEDCouplingStructuredMesh::IsPartStructured, MEDCouplingStructuredMesh::DeduceNumberOfGivenRangeInCompactFrmt, SwitchOnIdsFrom, ExtractFieldOfBoolFrom, ExtractFieldOfDoubleFrom + * \sa MEDCouplingStructuredMesh::IsPartStructured, MEDCouplingStructuredMesh::DeduceNumberOfGivenRangeInCompactFrmt, SwitchOnIdsFrom, ExtractFieldOfBoolFrom, ExtractFieldOfDoubleFrom, MultiplyPartOf */ DataArrayInt *MEDCouplingStructuredMesh::BuildExplicitIdsFrom(const std::vector& st, const std::vector< std::pair >& partCompactFormat) { @@ -1660,12 +1904,12 @@ DataArrayInt *MEDCouplingStructuredMesh::BuildExplicitIdsFrom(const std::vector< 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) + if(partCompactFormat[i].second ret(DataArrayInt::New()); + MCAuto ret(DataArrayInt::New()); ret->alloc(nbOfItems,1); int *pt(ret->getPointer()); switch(st.size()) @@ -1706,6 +1950,148 @@ DataArrayInt *MEDCouplingStructuredMesh::BuildExplicitIdsFrom(const std::vector< return ret.retn(); } +/*! + * This method multiplies by \a factor values in tuples located by \a part in \a da. + * + * \param [in] st - the structure of grid ( \b without considering ghost cells). + * \param [in] part - the part in the structure ( \b without considering ghost cells) contained in grid whose structure is defined by \a st. + * \param [in] factor - the factor, the tuples in \a da will be multiply by. + * \param [in,out] da - The DataArray in which only tuples specified by \a part will be modified. + * + * \sa BuildExplicitIdsFrom + */ +void MEDCouplingStructuredMesh::MultiplyPartOf(const std::vector& st, const std::vector< std::pair >& part, double factor, DataArrayDouble *da) +{ + if(!da || !da->isAllocated()) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::MultiplyPartOf : DataArrayDouble instance must be not NULL and allocated !"); + if(st.size()!=part.size()) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::MultiplyPartOf : input arrays must have the same size !"); + std::vector dims(st.size()); + for(std::size_t i=0;ist[i]) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::MultiplyPartOf : invalid input range 1 !"); + if(part[i].second<0 || part[i].second>st[i]) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::MultiplyPartOf : invalid input range 2 !"); + if(part[i].secondgetNumberOfComponents()); + if(da->getNumberOfTuples()!=nbOfTuplesExp) + { + std::ostringstream oss; oss << "MEDCouplingStructuredMesh::MultiplyPartOf : invalid nb of tuples ! Expected " << nbOfTuplesExp << " having " << da->getNumberOfTuples() << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + double *pt(da->getPointer()); + switch(st.size()) + { + case 3: + { + for(int i=0;i(),factor)); + } + } + } + break; + } + case 2: + { + for(int j=0;j(),factor)); + } + } + break; + } + case 1: + { + for(int k=0;k(),factor)); + } + break; + } + default: + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::MultiplyPartOf : Dimension supported are 1,2 or 3 !"); + } +} + +/*! + * This method multiplies by \a factor values in tuples located by \a part in \a da. + * + * \param [in] st - the structure of grid ( \b without considering ghost cells). + * \param [in] part - the part in the structure ( \b without considering ghost cells) contained in grid whose structure is defined by \a st. + * \param [in] ghostSize - \a ghostSize must be >= 0. + * \param [in] factor - the factor, the tuples in \a da will be multiply by. + * \param [in,out] da - The DataArray in which only tuples specified by \a part will be modified. + * + * \sa MultiplyPartOf, PutInGhostFormat + */ +void MEDCouplingStructuredMesh::MultiplyPartOfByGhost(const std::vector& st, const std::vector< std::pair >& part, int ghostSize, double factor, DataArrayDouble *da) +{ + std::vector stWG; + std::vector< std::pair > partWG; + PutInGhostFormat(ghostSize,st,part,stWG,partWG); + MultiplyPartOf(stWG,partWG,factor,da); +} + +/*! + * This method multiplies by \a factor values in tuples located by \a part in \a da. + * + * \param [in] st - the structure of grid ( \b without considering ghost cells). + * \param [in] part - the part in the structure ( \b without considering ghost cells) contained in grid whose structure is defined by \a st. + * \param [in] ghostSize - \a ghostSize must be >= 0. + * \param [out] stWithGhost - the structure considering ghost cells. + * \param [out] partWithGhost - the part considering the ghost cells. + * + * \sa MultiplyPartOf, PutInGhostFormat + */ +void MEDCouplingStructuredMesh::PutInGhostFormat(int ghostSize, const std::vector& st, const std::vector< std::pair >& part, std::vector& stWithGhost, std::vector< std::pair >&partWithGhost) +{ + if(ghostSize<0) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::PutInGhostFormat : ghost size must be >= 0 !"); + std::size_t dim(part.size()); + if(st.size()!=dim) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::PutInGhostFormat : the dimension of input vectors must be the same !"); + for(std::size_t i=0;ipart[i].second || part[i].second>st[i]) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::PutInGhostFormat : the specified part is invalid ! The begin must be >= 0 and <= end ! The end must be <= to the size at considered dimension !"); + stWithGhost.resize(st.size()); + std::transform(st.begin(),st.end(),stWithGhost.begin(),std::bind2nd(std::plus(),2*ghostSize)); + partWithGhost=part; + ApplyGhostOnCompactFrmt(partWithGhost,ghostSize); +} + +/*! + * \param [in,out] partBeforeFact - the part of a image mesh in compact format that will be put in ghost reference. + * \param [in] ghostSize - the ghost size of zone for all axis. + */ +void MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(std::vector< std::pair >& partBeforeFact, int ghostSize) +{ + if(ghostSize<0) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt : ghost size must be >= 0 !"); + std::size_t sz(partBeforeFact.size()); + for(std::size_t i=0;i& cgs, int mdim) { int ret(0);