1454e267fSLisandro Dalcin 2af0996ceSBarry Smith #include <petsc/private/dmdaimpl.h> /*I "petscdmda.h" I*/ 3454e267fSLisandro Dalcin 4454e267fSLisandro Dalcin #undef __FUNCT__ 52dde6fd4SLisandro Dalcin #define __FUNCT__ "DMDAGetElements_1D" 62dde6fd4SLisandro Dalcin static PetscErrorCode DMDAGetElements_1D(DM dm,PetscInt *nel,PetscInt *nen,const PetscInt *e[]) 7454e267fSLisandro Dalcin { 8454e267fSLisandro Dalcin PetscErrorCode ierr; 9454e267fSLisandro Dalcin DM_DA *da = (DM_DA*)dm->data; 10454e267fSLisandro Dalcin PetscInt i,xs,xe,Xs,Xe; 11454e267fSLisandro Dalcin PetscInt cnt=0; 125fd66863SKarl Rupp 13454e267fSLisandro Dalcin PetscFunctionBegin; 14454e267fSLisandro Dalcin if (!da->e) { 1598b2d131SBarry Smith if (!da->s) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Cannot get elements for DMDA with zero stencil width"); 16454e267fSLisandro Dalcin ierr = DMDAGetCorners(dm,&xs,0,0,&xe,0,0);CHKERRQ(ierr); 17454e267fSLisandro Dalcin ierr = DMDAGetGhostCorners(dm,&Xs,0,0,&Xe,0,0);CHKERRQ(ierr); 18454e267fSLisandro Dalcin xe += xs; Xe += Xs; if (xs != Xs) xs -= 1; 19454e267fSLisandro Dalcin da->ne = 1*(xe - xs - 1); 20854ce69bSBarry Smith ierr = PetscMalloc1(1 + 2*da->ne,&da->e);CHKERRQ(ierr); 21454e267fSLisandro Dalcin for (i=xs; i<xe-1; i++) { 22454e267fSLisandro Dalcin da->e[cnt++] = (i-Xs); 23454e267fSLisandro Dalcin da->e[cnt++] = (i-Xs+1); 24454e267fSLisandro Dalcin } 25454e267fSLisandro Dalcin } 26454e267fSLisandro Dalcin *nel = da->ne; 27454e267fSLisandro Dalcin *nen = 2; 28454e267fSLisandro Dalcin *e = da->e; 29454e267fSLisandro Dalcin PetscFunctionReturn(0); 30454e267fSLisandro Dalcin } 31454e267fSLisandro Dalcin 32454e267fSLisandro Dalcin #undef __FUNCT__ 332dde6fd4SLisandro Dalcin #define __FUNCT__ "DMDAGetElements_2D" 342dde6fd4SLisandro Dalcin static PetscErrorCode DMDAGetElements_2D(DM dm,PetscInt *nel,PetscInt *nen,const PetscInt *e[]) 35454e267fSLisandro Dalcin { 36454e267fSLisandro Dalcin PetscErrorCode ierr; 37454e267fSLisandro Dalcin DM_DA *da = (DM_DA*)dm->data; 38454e267fSLisandro Dalcin PetscInt i,xs,xe,Xs,Xe; 39454e267fSLisandro Dalcin PetscInt j,ys,ye,Ys,Ye; 40454e267fSLisandro Dalcin PetscInt cnt=0, cell[4], ns=2, nn=3; 41454e267fSLisandro Dalcin PetscInt c, split[] = {0,1,3, 42454e267fSLisandro Dalcin 2,3,1}; 435fd66863SKarl Rupp 44454e267fSLisandro Dalcin PetscFunctionBegin; 45454e267fSLisandro Dalcin if (!da->e) { 4698b2d131SBarry Smith if (!da->s) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Cannot get elements for DMDA with zero stencil width"); 47454e267fSLisandro Dalcin if (da->elementtype == DMDA_ELEMENT_P1) {ns=2; nn=3;} 48454e267fSLisandro Dalcin if (da->elementtype == DMDA_ELEMENT_Q1) {ns=1; nn=4;} 49454e267fSLisandro Dalcin ierr = DMDAGetCorners(dm,&xs,&ys,0,&xe,&ye,0);CHKERRQ(ierr); 50454e267fSLisandro Dalcin ierr = DMDAGetGhostCorners(dm,&Xs,&Ys,0,&Xe,&Ye,0);CHKERRQ(ierr); 51454e267fSLisandro Dalcin xe += xs; Xe += Xs; if (xs != Xs) xs -= 1; 52454e267fSLisandro Dalcin ye += ys; Ye += Ys; if (ys != Ys) ys -= 1; 53454e267fSLisandro Dalcin da->ne = ns*(xe - xs - 1)*(ye - ys - 1); 54854ce69bSBarry Smith ierr = PetscMalloc1(1 + nn*da->ne,&da->e);CHKERRQ(ierr); 55454e267fSLisandro Dalcin for (j=ys; j<ye-1; j++) { 56454e267fSLisandro Dalcin for (i=xs; i<xe-1; i++) { 57454e267fSLisandro Dalcin cell[0] = (i-Xs ) + (j-Ys )*(Xe-Xs); 58454e267fSLisandro Dalcin cell[1] = (i-Xs+1) + (j-Ys )*(Xe-Xs); 59454e267fSLisandro Dalcin cell[2] = (i-Xs+1) + (j-Ys+1)*(Xe-Xs); 60454e267fSLisandro Dalcin cell[3] = (i-Xs ) + (j-Ys+1)*(Xe-Xs); 61454e267fSLisandro Dalcin if (da->elementtype == DMDA_ELEMENT_P1) { 628865f1eaSKarl Rupp for (c=0; c<ns*nn; c++) da->e[cnt++] = cell[split[c]]; 63454e267fSLisandro Dalcin } 64454e267fSLisandro Dalcin if (da->elementtype == DMDA_ELEMENT_Q1) { 658865f1eaSKarl Rupp for (c=0; c<ns*nn; c++) da->e[cnt++] = cell[c]; 66454e267fSLisandro Dalcin } 67454e267fSLisandro Dalcin } 68454e267fSLisandro Dalcin } 69454e267fSLisandro Dalcin } 70454e267fSLisandro Dalcin *nel = da->ne; 71454e267fSLisandro Dalcin *nen = nn; 72454e267fSLisandro Dalcin *e = da->e; 73454e267fSLisandro Dalcin PetscFunctionReturn(0); 74454e267fSLisandro Dalcin } 75454e267fSLisandro Dalcin 76454e267fSLisandro Dalcin #undef __FUNCT__ 772dde6fd4SLisandro Dalcin #define __FUNCT__ "DMDAGetElements_3D" 782dde6fd4SLisandro Dalcin static PetscErrorCode DMDAGetElements_3D(DM dm,PetscInt *nel,PetscInt *nen,const PetscInt *e[]) 79454e267fSLisandro Dalcin { 80454e267fSLisandro Dalcin PetscErrorCode ierr; 81454e267fSLisandro Dalcin DM_DA *da = (DM_DA*)dm->data; 82454e267fSLisandro Dalcin PetscInt i,xs,xe,Xs,Xe; 83454e267fSLisandro Dalcin PetscInt j,ys,ye,Ys,Ye; 84454e267fSLisandro Dalcin PetscInt k,zs,ze,Zs,Ze; 85454e267fSLisandro Dalcin PetscInt cnt=0, cell[8], ns=6, nn=4; 86454e267fSLisandro Dalcin PetscInt c, split[] = {0,1,3,7, 87454e267fSLisandro Dalcin 0,1,7,4, 88454e267fSLisandro Dalcin 1,2,3,7, 89454e267fSLisandro Dalcin 1,2,7,6, 90454e267fSLisandro Dalcin 1,4,5,7, 91454e267fSLisandro Dalcin 1,5,6,7}; 925fd66863SKarl Rupp 93454e267fSLisandro Dalcin PetscFunctionBegin; 94454e267fSLisandro Dalcin if (!da->e) { 9598b2d131SBarry Smith if (!da->s) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Cannot get elements for DMDA with zero stencil width"); 96454e267fSLisandro Dalcin if (da->elementtype == DMDA_ELEMENT_P1) {ns=6; nn=4;} 97454e267fSLisandro Dalcin if (da->elementtype == DMDA_ELEMENT_Q1) {ns=1; nn=8;} 98454e267fSLisandro Dalcin ierr = DMDAGetCorners(dm,&xs,&ys,&zs,&xe,&ye,&ze);CHKERRQ(ierr); 99454e267fSLisandro Dalcin ierr = DMDAGetGhostCorners(dm,&Xs,&Ys,&Zs,&Xe,&Ye,&Ze);CHKERRQ(ierr); 100454e267fSLisandro Dalcin xe += xs; Xe += Xs; if (xs != Xs) xs -= 1; 101454e267fSLisandro Dalcin ye += ys; Ye += Ys; if (ys != Ys) ys -= 1; 102454e267fSLisandro Dalcin ze += zs; Ze += Zs; if (zs != Zs) zs -= 1; 103454e267fSLisandro Dalcin da->ne = ns*(xe - xs - 1)*(ye - ys - 1)*(ze - zs - 1); 104854ce69bSBarry Smith ierr = PetscMalloc1(1 + nn*da->ne,&da->e);CHKERRQ(ierr); 105454e267fSLisandro Dalcin for (k=zs; k<ze-1; k++) { 106454e267fSLisandro Dalcin for (j=ys; j<ye-1; j++) { 107454e267fSLisandro Dalcin for (i=xs; i<xe-1; i++) { 108454e267fSLisandro Dalcin cell[0] = (i-Xs ) + (j-Ys )*(Xe-Xs) + (k-Zs )*(Xe-Xs)*(Ye-Ys); 109454e267fSLisandro Dalcin cell[1] = (i-Xs+1) + (j-Ys )*(Xe-Xs) + (k-Zs )*(Xe-Xs)*(Ye-Ys); 110454e267fSLisandro Dalcin cell[2] = (i-Xs+1) + (j-Ys+1)*(Xe-Xs) + (k-Zs )*(Xe-Xs)*(Ye-Ys); 111454e267fSLisandro Dalcin cell[3] = (i-Xs ) + (j-Ys+1)*(Xe-Xs) + (k-Zs )*(Xe-Xs)*(Ye-Ys); 112454e267fSLisandro Dalcin cell[4] = (i-Xs ) + (j-Ys )*(Xe-Xs) + (k-Zs+1)*(Xe-Xs)*(Ye-Ys); 113454e267fSLisandro Dalcin cell[5] = (i-Xs+1) + (j-Ys )*(Xe-Xs) + (k-Zs+1)*(Xe-Xs)*(Ye-Ys); 114454e267fSLisandro Dalcin cell[6] = (i-Xs+1) + (j-Ys+1)*(Xe-Xs) + (k-Zs+1)*(Xe-Xs)*(Ye-Ys); 115454e267fSLisandro Dalcin cell[7] = (i-Xs ) + (j-Ys+1)*(Xe-Xs) + (k-Zs+1)*(Xe-Xs)*(Ye-Ys); 116454e267fSLisandro Dalcin if (da->elementtype == DMDA_ELEMENT_P1) { 1178865f1eaSKarl Rupp for (c=0; c<ns*nn; c++) da->e[cnt++] = cell[split[c]]; 118454e267fSLisandro Dalcin } 119454e267fSLisandro Dalcin if (da->elementtype == DMDA_ELEMENT_Q1) { 1208865f1eaSKarl Rupp for (c=0; c<ns*nn; c++) da->e[cnt++] = cell[c]; 121454e267fSLisandro Dalcin } 122454e267fSLisandro Dalcin } 123454e267fSLisandro Dalcin } 124454e267fSLisandro Dalcin } 125454e267fSLisandro Dalcin } 126454e267fSLisandro Dalcin *nel = da->ne; 127454e267fSLisandro Dalcin *nen = nn; 128454e267fSLisandro Dalcin *e = da->e; 129454e267fSLisandro Dalcin PetscFunctionReturn(0); 130454e267fSLisandro Dalcin } 131454e267fSLisandro Dalcin 1322dde6fd4SLisandro Dalcin /*@C 1332dde6fd4SLisandro Dalcin DMDASetElementType - Sets the element type to be returned by DMDAGetElements() 1342dde6fd4SLisandro Dalcin 1352dde6fd4SLisandro Dalcin Not Collective 1362dde6fd4SLisandro Dalcin 1372dde6fd4SLisandro Dalcin Input Parameter: 1382dde6fd4SLisandro Dalcin . da - the DMDA object 1392dde6fd4SLisandro Dalcin 1402dde6fd4SLisandro Dalcin Output Parameters: 1412dde6fd4SLisandro Dalcin . etype - the element type, currently either DMDA_ELEMENT_P1 or ELEMENT_Q1 1422dde6fd4SLisandro Dalcin 1432dde6fd4SLisandro Dalcin Level: intermediate 1442dde6fd4SLisandro Dalcin 1452dde6fd4SLisandro Dalcin .seealso: DMDAElementType, DMDAGetElementType(), DMDAGetElements(), DMDARestoreElements() 1462dde6fd4SLisandro Dalcin @*/ 147454e267fSLisandro Dalcin #undef __FUNCT__ 1482dde6fd4SLisandro Dalcin #define __FUNCT__ "DMDASetElementType" 1492dde6fd4SLisandro Dalcin PetscErrorCode DMDASetElementType(DM da, DMDAElementType etype) 1502dde6fd4SLisandro Dalcin { 1512dde6fd4SLisandro Dalcin DM_DA *dd = (DM_DA*)da->data; 1522dde6fd4SLisandro Dalcin PetscErrorCode ierr; 1532dde6fd4SLisandro Dalcin 1542dde6fd4SLisandro Dalcin PetscFunctionBegin; 1552dde6fd4SLisandro Dalcin PetscValidHeaderSpecific(da,DM_CLASSID,1); 1562dde6fd4SLisandro Dalcin PetscValidLogicalCollectiveEnum(da,etype,2); 1572dde6fd4SLisandro Dalcin if (dd->elementtype != etype) { 1582dde6fd4SLisandro Dalcin ierr = PetscFree(dd->e);CHKERRQ(ierr); 1598865f1eaSKarl Rupp 1602dde6fd4SLisandro Dalcin dd->elementtype = etype; 1612dde6fd4SLisandro Dalcin dd->ne = 0; 1620298fd71SBarry Smith dd->e = NULL; 1632dde6fd4SLisandro Dalcin } 1642dde6fd4SLisandro Dalcin PetscFunctionReturn(0); 1652dde6fd4SLisandro Dalcin } 1662dde6fd4SLisandro Dalcin 1672dde6fd4SLisandro Dalcin /*@C 1682dde6fd4SLisandro Dalcin DMDAGetElementType - Gets the element type to be returned by DMDAGetElements() 1692dde6fd4SLisandro Dalcin 1702dde6fd4SLisandro Dalcin Not Collective 1712dde6fd4SLisandro Dalcin 1722dde6fd4SLisandro Dalcin Input Parameter: 1732dde6fd4SLisandro Dalcin . da - the DMDA object 1742dde6fd4SLisandro Dalcin 1752dde6fd4SLisandro Dalcin Output Parameters: 1762dde6fd4SLisandro Dalcin . etype - the element type, currently either DMDA_ELEMENT_P1 or ELEMENT_Q1 1772dde6fd4SLisandro Dalcin 1782dde6fd4SLisandro Dalcin Level: intermediate 1792dde6fd4SLisandro Dalcin 1802dde6fd4SLisandro Dalcin .seealso: DMDAElementType, DMDASetElementType(), DMDAGetElements(), DMDARestoreElements() 1812dde6fd4SLisandro Dalcin @*/ 1822dde6fd4SLisandro Dalcin #undef __FUNCT__ 1832dde6fd4SLisandro Dalcin #define __FUNCT__ "DMDAGetElementType" 1842dde6fd4SLisandro Dalcin PetscErrorCode DMDAGetElementType(DM da, DMDAElementType *etype) 1852dde6fd4SLisandro Dalcin { 1862dde6fd4SLisandro Dalcin DM_DA *dd = (DM_DA*)da->data; 1875fd66863SKarl Rupp 1882dde6fd4SLisandro Dalcin PetscFunctionBegin; 1892dde6fd4SLisandro Dalcin PetscValidHeaderSpecific(da,DM_CLASSID,1); 1902dde6fd4SLisandro Dalcin PetscValidPointer(etype,2); 1912dde6fd4SLisandro Dalcin *etype = dd->elementtype; 1922dde6fd4SLisandro Dalcin PetscFunctionReturn(0); 1932dde6fd4SLisandro Dalcin } 1942dde6fd4SLisandro Dalcin 1952dde6fd4SLisandro Dalcin /*@C 1962dde6fd4SLisandro Dalcin DMDAGetElements - Gets an array containing the indices (in local coordinates) 1972dde6fd4SLisandro Dalcin of all the local elements 1982dde6fd4SLisandro Dalcin 1992dde6fd4SLisandro Dalcin Not Collective 2002dde6fd4SLisandro Dalcin 2012dde6fd4SLisandro Dalcin Input Parameter: 2022dde6fd4SLisandro Dalcin . dm - the DM object 2032dde6fd4SLisandro Dalcin 2042dde6fd4SLisandro Dalcin Output Parameters: 2052dde6fd4SLisandro Dalcin + nel - number of local elements 2062dde6fd4SLisandro Dalcin . nen - number of element nodes 207c2cd2aa3SJed Brown - e - the local indices of the elements' vertices 2082dde6fd4SLisandro Dalcin 2092dde6fd4SLisandro Dalcin Level: intermediate 2102dde6fd4SLisandro Dalcin 211009f0576SBarry Smith Notes: Each process uniquely owns a subset of the elements. That is no element is owned by two or more processes. 212009f0576SBarry Smith 213009f0576SBarry Smith If on each process you integrate over its owned elements and use ADD_VALUES in Vec/MatSetValuesLocal() then you'll obtain the correct result. 214009f0576SBarry Smith 215c2cd2aa3SJed Brown .seealso: DMDAElementType, DMDASetElementType(), DMDARestoreElements(), VecSetValuesLocal(), MatSetValuesLocal(), DMGlobalToLocalBegin(), DMLocalToGlobalBegin() 2162dde6fd4SLisandro Dalcin @*/ 2172dde6fd4SLisandro Dalcin #undef __FUNCT__ 2182dde6fd4SLisandro Dalcin #define __FUNCT__ "DMDAGetElements" 2192dde6fd4SLisandro Dalcin PetscErrorCode DMDAGetElements(DM dm,PetscInt *nel,PetscInt *nen,const PetscInt *e[]) 220454e267fSLisandro Dalcin { 221c73cfb54SMatthew G. Knepley PetscInt dim; 222454e267fSLisandro Dalcin PetscErrorCode ierr; 22399c57625SBarry Smith DM_DA *dd = (DM_DA*)dm->data; 2245fd66863SKarl Rupp 225454e267fSLisandro Dalcin PetscFunctionBegin; 226*9192b5d6SBarry Smith if (dd->stencil_type == DMDA_STENCIL_STAR) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DMDAGetElement() requires you use a stencil type of DMDA_STENCIL_BOX"); 227c73cfb54SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 228c73cfb54SMatthew G. Knepley if (dim==-1) { 2290298fd71SBarry Smith *nel = 0; *nen = 0; *e = NULL; 230c73cfb54SMatthew G. Knepley } else if (dim==1) { 2312dde6fd4SLisandro Dalcin ierr = DMDAGetElements_1D(dm,nel,nen,e);CHKERRQ(ierr); 232c73cfb54SMatthew G. Knepley } else if (dim==2) { 2332dde6fd4SLisandro Dalcin ierr = DMDAGetElements_2D(dm,nel,nen,e);CHKERRQ(ierr); 234c73cfb54SMatthew G. Knepley } else if (dim==3) { 2352dde6fd4SLisandro Dalcin ierr = DMDAGetElements_3D(dm,nel,nen,e);CHKERRQ(ierr); 236c73cfb54SMatthew G. Knepley } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"DMDA dimension not 1, 2, or 3, it is %D\n",dim); 237454e267fSLisandro Dalcin PetscFunctionReturn(0); 238454e267fSLisandro Dalcin } 2392dde6fd4SLisandro Dalcin 2402dde6fd4SLisandro Dalcin #undef __FUNCT__ 2412dde6fd4SLisandro Dalcin #define __FUNCT__ "DMDARestoreElements" 2422dde6fd4SLisandro Dalcin /*@C 243009f0576SBarry Smith DMDARestoreElements - Restores the array obtained with DMDAGetElements() 2442dde6fd4SLisandro Dalcin 2452dde6fd4SLisandro Dalcin Not Collective 2462dde6fd4SLisandro Dalcin 2472dde6fd4SLisandro Dalcin Input Parameter: 2482dde6fd4SLisandro Dalcin + dm - the DM object 2492dde6fd4SLisandro Dalcin . nel - number of local elements 2502dde6fd4SLisandro Dalcin . nen - number of element nodes 251c2cd2aa3SJed Brown - e - the local indices of the elements' vertices 2522dde6fd4SLisandro Dalcin 2532dde6fd4SLisandro Dalcin Level: intermediate 2542dde6fd4SLisandro Dalcin 255009f0576SBarry Smith Note: You should not access these values after you have called this routine. 256009f0576SBarry Smith 257c67aec63SBarry Smith This restore signals the DMDA object that you no longer need access to the array information. 258009f0576SBarry Smith 2592dde6fd4SLisandro Dalcin .seealso: DMDAElementType, DMDASetElementType(), DMDAGetElements() 2602dde6fd4SLisandro Dalcin @*/ 2612dde6fd4SLisandro Dalcin PetscErrorCode DMDARestoreElements(DM dm,PetscInt *nel,PetscInt *nen,const PetscInt *e[]) 2622dde6fd4SLisandro Dalcin { 2632dde6fd4SLisandro Dalcin PetscFunctionBegin; 2642dde6fd4SLisandro Dalcin PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2652dde6fd4SLisandro Dalcin PetscValidIntPointer(nel,2); 2662dde6fd4SLisandro Dalcin PetscValidIntPointer(nen,3); 2672dde6fd4SLisandro Dalcin PetscValidPointer(e,4); 2689cc8bc54SJed Brown *nel = 0; 2699cc8bc54SJed Brown *nen = -1; 2709cc8bc54SJed Brown *e = NULL; 2712dde6fd4SLisandro Dalcin PetscFunctionReturn(0); 2722dde6fd4SLisandro Dalcin } 273