From: Anthony Geay Date: Mon, 24 Apr 2017 06:57:24 +0000 (+0200) Subject: UMesh.computeEnlargedNeighborsOfNodes X-Git-Tag: V8_4_0a1~80 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=1ec2dd8dd33667f280691ed44f58f1c6d9015ce3;p=tools%2Fmedcoupling.git UMesh.computeEnlargedNeighborsOfNodes --- diff --git a/src/MEDCoupling/MEDCouplingUMesh.cxx b/src/MEDCoupling/MEDCouplingUMesh.cxx index 2757c52ae..5b703368c 100644 --- a/src/MEDCoupling/MEDCouplingUMesh.cxx +++ b/src/MEDCoupling/MEDCouplingUMesh.cxx @@ -589,18 +589,15 @@ void MEDCouplingUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double void MEDCouplingUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const { checkFullyDefined(); - int nbOfNodes=getNumberOfNodes(); + int nbOfNodes(getNumberOfNodes()); int *revNodalIndxPtr=(int *)malloc((nbOfNodes+1)*sizeof(int)); revNodalIndx->useArray(revNodalIndxPtr,true,C_DEALLOC,nbOfNodes+1,1); std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0); - const int *conn=_nodal_connec->getConstPointer(); - const int *connIndex=_nodal_connec_index->getConstPointer(); - int nbOfCells=getNumberOfCells(); - int nbOfEltsInRevNodal=0; + const int *conn(_nodal_connec->begin()),*connIndex(_nodal_connec_index->begin()); + int nbOfCells(getNumberOfCells()),nbOfEltsInRevNodal(0); for(int eltId=0;eltId=0)//for polyhedrons { @@ -838,10 +835,10 @@ void MEDCouplingUMesh::ComputeNeighborsOfCellsAdv(const DataArrayInt *desc, cons { if(!desc || !descIndx || !revDesc || !revDescIndx) throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ComputeNeighborsOfCellsAdv some input array is empty !"); - const int *descPtr=desc->getConstPointer(); - const int *descIPtr=descIndx->getConstPointer(); - const int *revDescPtr=revDesc->getConstPointer(); - const int *revDescIPtr=revDescIndx->getConstPointer(); + const int *descPtr=desc->begin(); + const int *descIPtr=descIndx->begin(); + const int *revDescPtr=revDesc->begin(); + const int *revDescIPtr=revDescIndx->begin(); // int nbCells=descIndx->getNumberOfTuples()-1; MCAuto out0=DataArrayInt::New(); @@ -863,6 +860,35 @@ void MEDCouplingUMesh::ComputeNeighborsOfCellsAdv(const DataArrayInt *desc, cons neighborsIndx=out1.retn(); } +/*! + * Explodes \a this into edges whatever its dimension. + */ +MCAuto MEDCouplingUMesh::explodeIntoEdges(MCAuto& desc, MCAuto& descIndex, MCAuto& revDesc, MCAuto& revDescIndx) const +{ + checkFullyDefined(); + int mdim(getMeshDimension()); + desc=DataArrayInt::New(); descIndex=DataArrayInt::New(); revDesc=DataArrayInt::New(); revDescIndx=DataArrayInt::New(); + MCAuto mesh1D; + switch(mdim) + { + case 3: + { + mesh1D=explode3DMeshTo1D(desc,descIndex,revDesc,revDescIndx); + break; + } + case 2: + { + mesh1D=buildDescendingConnectivity(desc,descIndex,revDesc,revDescIndx); + break; + } + default: + { + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::computeNeighborsOfNodes : Mesh dimension supported are [3,2] !"); + } + } + return mesh1D; +} + /*! * \b WARNING this method do the assumption that connectivity lies on the coordinates set. * For speed reasons no check of this will be done. This method calls @@ -877,13 +903,15 @@ void MEDCouplingUMesh::ComputeNeighborsOfCellsAdv(const DataArrayInt *desc, cons * The number of tuples is equal to the last values in \b neighborsIndx. * \param [out] neighborsIdx is an array of size this->getNumberOfCells()+1 newly allocated and should * be dealt by the caller. This arrays allow to use the first output parameter \b neighbors. + * + * \sa MEDCouplingUMesh::computeEnlargedNeighborsOfNodes */ void MEDCouplingUMesh::computeNeighborsOfNodes(DataArrayInt *&neighbors, DataArrayInt *&neighborsIdx) const { checkFullyDefined(); int mdim(getMeshDimension()),nbNodes(getNumberOfNodes()); MCAuto desc(DataArrayInt::New()),descIndx(DataArrayInt::New()),revDesc(DataArrayInt::New()),revDescIndx(DataArrayInt::New()); - MCAuto mesh1D; + MCConstAuto mesh1D; switch(mdim) { case 3: @@ -898,8 +926,7 @@ void MEDCouplingUMesh::computeNeighborsOfNodes(DataArrayInt *&neighbors, DataArr } case 1: { - mesh1D=const_cast(this); - mesh1D->incrRef(); + mesh1D.takeRef(this); break; } default: @@ -922,6 +949,45 @@ void MEDCouplingUMesh::computeNeighborsOfNodes(DataArrayInt *&neighbors, DataArr neighborsIdx=descIndx.retn(); } +/*! + * Computes enlarged neighbors for each nodes in \a this. The behavior of this method is close to MEDCouplingUMesh::computeNeighborsOfNodes except that the neighborhood of each node is wider here. + * A node j is considered to be in the neighborhood of i if and only if there is a cell in \a this containing in its nodal connectivity both i and j. + * This method is useful to find ghost cells of a part of a mesh with a code based on fields on nodes. + * + * \sa MEDCouplingUMesh::computeNeighborsOfNodes + */ +void MEDCouplingUMesh::computeEnlargedNeighborsOfNodes(MCAuto &neighbors, MCAuto& neighborsIdx) const +{ + checkFullyDefined(); + int nbOfNodes(getNumberOfNodes()); + const int *conn(_nodal_connec->begin()),*connIndex(_nodal_connec_index->begin()); + int nbOfCells(getNumberOfCells()); + std::vector< std::set > st0(nbOfNodes); + for(int eltId=0;eltId s(strtNdlConnOfCurCell,endNdlConnOfCurCell); s.erase(-1); //for polyhedrons + for(std::set::const_iterator iter2=s.begin();iter2!=s.end();iter2++) + st0[*iter2].insert(s.begin(),s.end()); + } + neighborsIdx=DataArrayInt::New(); neighborsIdx->alloc(nbOfNodes+1,1); neighborsIdx->setIJ(0,0,0); + { + int *neighIdx(neighborsIdx->getPointer()); + for(std::vector< std::set >::const_iterator it=st0.begin();it!=st0.end();it++,neighIdx++) + neighIdx[1]=neighIdx[0]+(*it).size()-1; + } + neighbors=DataArrayInt::New(); neighbors->alloc(neighborsIdx->back(),1); + { + const int *neighIdx(neighborsIdx->begin()); + int *neigh(neighbors->getPointer()),nodeId(0); + for(std::vector< std::set >::const_iterator it=st0.begin();it!=st0.end();it++,neighIdx++,nodeId++) + { + std::set s(*it); s.erase(nodeId); + std::copy(s.begin(),s.end(),neigh+*neighIdx); + } + } +} + /*! * Converts specified cells to either polygons (if \a this is a 2D mesh) or * polyhedrons (if \a this is a 3D mesh). The cells to convert are specified by an @@ -954,7 +1020,7 @@ void MEDCouplingUMesh::convertToPolyTypes(const int *cellIdsToConvertBg, const i int nbOfCells(getNumberOfCells()); if(dim==2) { - const int *connIndex=_nodal_connec_index->getConstPointer(); + const int *connIndex=_nodal_connec_index->begin(); int *conn=_nodal_connec->getPointer(); for(const int *iter=cellIdsToConvertBg;iter!=cellIdsToConvertEnd;iter++) { diff --git a/src/MEDCoupling/MEDCouplingUMesh.hxx b/src/MEDCoupling/MEDCouplingUMesh.hxx index efab092eb..caf5554d4 100644 --- a/src/MEDCoupling/MEDCouplingUMesh.hxx +++ b/src/MEDCoupling/MEDCouplingUMesh.hxx @@ -120,6 +120,7 @@ namespace MEDCoupling MEDCOUPLING_EXPORT bool areCellsIncludedIn(const MEDCouplingUMesh *other, int compType, DataArrayInt *& arr) const; MEDCOUPLING_EXPORT bool areCellsIncludedInPolicy7(const MEDCouplingUMesh *other, DataArrayInt *& arr) const; MEDCOUPLING_EXPORT void getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const; + MEDCOUPLING_EXPORT MCAuto explodeIntoEdges(MCAuto& desc, MCAuto& descIndex, MCAuto& revDesc, MCAuto& revDescIndx) const; MEDCOUPLING_EXPORT MEDCouplingUMesh *explode3DMeshTo1D(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const; MEDCOUPLING_EXPORT MEDCouplingUMesh *buildDescendingConnectivity(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const; MEDCOUPLING_EXPORT MEDCouplingUMesh *buildDescendingConnectivity2(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const; @@ -129,6 +130,7 @@ namespace MEDCoupling MEDCOUPLING_EXPORT static void ComputeNeighborsOfCellsAdv(const DataArrayInt *desc, const DataArrayInt *descI, const DataArrayInt *revDesc, const DataArrayInt *revDescI, DataArrayInt *&neighbors, DataArrayInt *&neighborsIdx); MEDCOUPLING_EXPORT void computeNeighborsOfNodes(DataArrayInt *&neighbors, DataArrayInt *&neighborsIdx) const; + MEDCOUPLING_EXPORT void computeEnlargedNeighborsOfNodes(MCAuto &neighbors, MCAuto& neighborsIdx) const; MEDCOUPLING_EXPORT MEDCouplingUMesh *mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const; MEDCOUPLING_EXPORT MEDCouplingUMesh *buildPartOfMySelf(const int *begin, const int *end, bool keepCoords=true) const; MEDCOUPLING_EXPORT MEDCouplingUMesh *buildPartOfMySelfSlice(int start, int end, int step, bool keepCoords=true) const; diff --git a/src/MEDCoupling_Swig/MEDCouplingBasicsTest5.py b/src/MEDCoupling_Swig/MEDCouplingBasicsTest5.py index 474c6ab7c..e05a86736 100644 --- a/src/MEDCoupling_Swig/MEDCouplingBasicsTest5.py +++ b/src/MEDCoupling_Swig/MEDCouplingBasicsTest5.py @@ -4518,6 +4518,29 @@ class MEDCouplingBasicsTest5(unittest.TestCase): d4.sortEachPairToMakeALinkedList() self.assertTrue(d4.fromLinkedListOfPairToList().isEqual(zeRes)) pass + + def testUMeshExplodeIntoEdges1(self): + m=MEDCouplingCMesh() ; arr=DataArrayDouble(5) ; arr.iota() ; m.setCoords(arr,arr,arr) ; m=m.buildUnstructured() + self.assertEqual(m.getMeshDimension(),3) + a0,a1,a2,a3,a4=m.explodeIntoEdges() + b0,b1,b2,b3,b4=m.explode3DMeshTo1D() + self.assertTrue(a0.isEqual(b0,1e-12)) + self.assertTrue(a1.isEqual(b1)) ; self.assertTrue(a2.isEqual(b2)) ; self.assertTrue(a3.isEqual(b3)) ; self.assertTrue(a4.isEqual(b4)) + # + m=MEDCouplingCMesh() ; arr=DataArrayDouble(5) ; arr.iota() ; m.setCoords(arr,arr) ; m=m.buildUnstructured() + self.assertEqual(m.getMeshDimension(),2) + a0,a1,a2,a3,a4=m.explodeIntoEdges() + b0,b1,b2,b3,b4=m.buildDescendingConnectivity() + self.assertTrue(a0.isEqual(b0,1e-12)) + self.assertTrue(a1.isEqual(b1)) ; self.assertTrue(a2.isEqual(b2)) ; self.assertTrue(a3.isEqual(b3)) ; self.assertTrue(a4.isEqual(b4)) + pass + + def testUMeshComputeEnlargedNeighborsOfNodes(self): + m=MEDCouplingCMesh() ; arr=DataArrayDouble(4) ; arr.iota() ; m.setCoords(arr,arr) ; m=m.buildUnstructured() + a,b=m.computeEnlargedNeighborsOfNodes() + self.assertTrue(a.isEqual(DataArrayInt([1,4,5,0,2,4,5,6,1,3,5,6,7,2,6,7,0,1,5,8,9,0,1,2,4,6,8,9,10,1,2,3,5,7,9,10,11,2,3,6,10,11,4,5,9,12,13,4,5,6,8,10,12,13,14,5,6,7,9,11,13,14,15,6,7,10,14,15,8,9,13,8,9,10,12,14,9,10,11,13,15,10,11,14]))) + self.assertTrue(b.isEqual(DataArrayInt([0,3,8,13,16,21,29,37,42,47,55,63,68,71,76,81,84]))) + pass pass diff --git a/src/MEDCoupling_Swig/MEDCouplingCommon.i b/src/MEDCoupling_Swig/MEDCouplingCommon.i index a1a557ecc..fb5745154 100644 --- a/src/MEDCoupling_Swig/MEDCouplingCommon.i +++ b/src/MEDCoupling_Swig/MEDCouplingCommon.i @@ -2665,6 +2665,19 @@ namespace MEDCoupling return ret; } + PyObject *explodeIntoEdges() const throw(INTERP_KERNEL::Exception) + { + MCAuto desc,descIndex,revDesc,revDescIndx; + MCAuto m(self->explodeIntoEdges(desc,descIndex,revDesc,revDescIndx)); + PyObject *ret=PyTuple_New(5); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(m.retn()),SWIGTYPE_p_MEDCoupling__MEDCouplingUMesh, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(desc.retn()),SWIGTYPE_p_MEDCoupling__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,2,SWIG_NewPointerObj(SWIG_as_voidptr(descIndex.retn()),SWIGTYPE_p_MEDCoupling__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,3,SWIG_NewPointerObj(SWIG_as_voidptr(revDesc.retn()),SWIGTYPE_p_MEDCoupling__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,4,SWIG_NewPointerObj(SWIG_as_voidptr(revDescIndx.retn()),SWIGTYPE_p_MEDCoupling__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + PyObject *explodeMeshIntoMicroEdges() const throw(INTERP_KERNEL::Exception) { MCAuto d0=DataArrayInt::New(); @@ -2732,6 +2745,16 @@ namespace MEDCoupling PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(neighborsIdx),SWIGTYPE_p_MEDCoupling__DataArrayInt, SWIG_POINTER_OWN | 0 )); return ret; } + + PyObject *computeEnlargedNeighborsOfNodes() const throw(INTERP_KERNEL::Exception) + { + MCAuto neighbors,neighborsIdx; + self->computeEnlargedNeighborsOfNodes(neighbors,neighborsIdx); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(neighbors.retn()),SWIGTYPE_p_MEDCoupling__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(neighborsIdx.retn()),SWIGTYPE_p_MEDCoupling__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } PyObject *computeCellNeighborhoodFromNodesOne(const DataArrayInt *nodeNeigh, const DataArrayInt *nodeNeighI) const throw(INTERP_KERNEL::Exception) {