Actual source code: dagetelem.c
petsc-3.7.1 2016-05-15
Report Typos and Errors

      2: #include <petsc/private/dmdaimpl.h>     /*I  "petscdmda.h"   I*/

      6: static PetscErrorCode DMDAGetElements_1D(DM dm,PetscInt *nel,PetscInt *nen,const PetscInt *e[])
      7: {
      9:   DM_DA          *da = (DM_DA*)dm->data;
     10:   PetscInt       i,xs,xe,Xs,Xe;
     11:   PetscInt       cnt=0;

     14:   if (!da->e) {
     15:     if (!da->s) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Cannot get elements for DMDA with zero stencil width");
     16:     DMDAGetCorners(dm,&xs,0,0,&xe,0,0);
     17:     DMDAGetGhostCorners(dm,&Xs,0,0,&Xe,0,0);
     18:     xe    += xs; Xe += Xs; if (xs != Xs) xs -= 1;
     19:     da->ne = 1*(xe - xs - 1);
     20:     PetscMalloc1(1 + 2*da->ne,&da->e);
     21:     for (i=xs; i<xe-1; i++) {
     22:       da->e[cnt++] = (i-Xs);
     23:       da->e[cnt++] = (i-Xs+1);
     24:     }
     25:   }
     26:   *nel = da->ne;
     27:   *nen = 2;
     28:   *e   = da->e;
     29:   return(0);
     30: }

     34: static PetscErrorCode DMDAGetElements_2D(DM dm,PetscInt *nel,PetscInt *nen,const PetscInt *e[])
     35: {
     37:   DM_DA          *da = (DM_DA*)dm->data;
     38:   PetscInt       i,xs,xe,Xs,Xe;
     39:   PetscInt       j,ys,ye,Ys,Ye;
     40:   PetscInt       cnt=0, cell[4], ns=2, nn=3;
     41:   PetscInt       c, split[] = {0,1,3,
     42:                                2,3,1};

     45:   if (!da->e) {
     46:     if (!da->s) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Cannot get elements for DMDA with zero stencil width");
     47:     if (da->elementtype == DMDA_ELEMENT_P1) {ns=2; nn=3;}
     48:     if (da->elementtype == DMDA_ELEMENT_Q1) {ns=1; nn=4;}
     49:     DMDAGetCorners(dm,&xs,&ys,0,&xe,&ye,0);
     50:     DMDAGetGhostCorners(dm,&Xs,&Ys,0,&Xe,&Ye,0);
     51:     xe    += xs; Xe += Xs; if (xs != Xs) xs -= 1;
     52:     ye    += ys; Ye += Ys; if (ys != Ys) ys -= 1;
     53:     da->ne = ns*(xe - xs - 1)*(ye - ys - 1);
     54:     PetscMalloc1(1 + nn*da->ne,&da->e);
     55:     for (j=ys; j<ye-1; j++) {
     56:       for (i=xs; i<xe-1; i++) {
     57:         cell[0] = (i-Xs  ) + (j-Ys  )*(Xe-Xs);
     58:         cell[1] = (i-Xs+1) + (j-Ys  )*(Xe-Xs);
     59:         cell[2] = (i-Xs+1) + (j-Ys+1)*(Xe-Xs);
     60:         cell[3] = (i-Xs  ) + (j-Ys+1)*(Xe-Xs);
     61:         if (da->elementtype == DMDA_ELEMENT_P1) {
     62:           for (c=0; c<ns*nn; c++) da->e[cnt++] = cell[split[c]];
     63:         }
     64:         if (da->elementtype == DMDA_ELEMENT_Q1) {
     65:           for (c=0; c<ns*nn; c++) da->e[cnt++] = cell[c];
     66:         }
     67:       }
     68:     }
     69:   }
     70:   *nel = da->ne;
     71:   *nen = nn;
     72:   *e   = da->e;
     73:   return(0);
     74: }

     78: static PetscErrorCode DMDAGetElements_3D(DM dm,PetscInt *nel,PetscInt *nen,const PetscInt *e[])
     79: {
     81:   DM_DA          *da = (DM_DA*)dm->data;
     82:   PetscInt       i,xs,xe,Xs,Xe;
     83:   PetscInt       j,ys,ye,Ys,Ye;
     84:   PetscInt       k,zs,ze,Zs,Ze;
     85:   PetscInt       cnt=0, cell[8], ns=6, nn=4;
     86:   PetscInt       c, split[] = {0,1,3,7,
     87:                                0,1,7,4,
     88:                                1,2,3,7,
     89:                                1,2,7,6,
     90:                                1,4,5,7,
     91:                                1,5,6,7};

     94:   if (!da->e) {
     95:     if (!da->s) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Cannot get elements for DMDA with zero stencil width");
     96:     if (da->elementtype == DMDA_ELEMENT_P1) {ns=6; nn=4;}
     97:     if (da->elementtype == DMDA_ELEMENT_Q1) {ns=1; nn=8;}
     98:     DMDAGetCorners(dm,&xs,&ys,&zs,&xe,&ye,&ze);
     99:     DMDAGetGhostCorners(dm,&Xs,&Ys,&Zs,&Xe,&Ye,&Ze);
    100:     xe    += xs; Xe += Xs; if (xs != Xs) xs -= 1;
    101:     ye    += ys; Ye += Ys; if (ys != Ys) ys -= 1;
    102:     ze    += zs; Ze += Zs; if (zs != Zs) zs -= 1;
    103:     da->ne = ns*(xe - xs - 1)*(ye - ys - 1)*(ze - zs - 1);
    104:     PetscMalloc1(1 + nn*da->ne,&da->e);
    105:     for (k=zs; k<ze-1; k++) {
    106:       for (j=ys; j<ye-1; j++) {
    107:         for (i=xs; i<xe-1; i++) {
    108:           cell[0] = (i-Xs  ) + (j-Ys  )*(Xe-Xs) + (k-Zs  )*(Xe-Xs)*(Ye-Ys);
    109:           cell[1] = (i-Xs+1) + (j-Ys  )*(Xe-Xs) + (k-Zs  )*(Xe-Xs)*(Ye-Ys);
    110:           cell[2] = (i-Xs+1) + (j-Ys+1)*(Xe-Xs) + (k-Zs  )*(Xe-Xs)*(Ye-Ys);
    111:           cell[3] = (i-Xs  ) + (j-Ys+1)*(Xe-Xs) + (k-Zs  )*(Xe-Xs)*(Ye-Ys);
    112:           cell[4] = (i-Xs  ) + (j-Ys  )*(Xe-Xs) + (k-Zs+1)*(Xe-Xs)*(Ye-Ys);
    113:           cell[5] = (i-Xs+1) + (j-Ys  )*(Xe-Xs) + (k-Zs+1)*(Xe-Xs)*(Ye-Ys);
    114:           cell[6] = (i-Xs+1) + (j-Ys+1)*(Xe-Xs) + (k-Zs+1)*(Xe-Xs)*(Ye-Ys);
    115:           cell[7] = (i-Xs  ) + (j-Ys+1)*(Xe-Xs) + (k-Zs+1)*(Xe-Xs)*(Ye-Ys);
    116:           if (da->elementtype == DMDA_ELEMENT_P1) {
    117:             for (c=0; c<ns*nn; c++) da->e[cnt++] = cell[split[c]];
    118:           }
    119:           if (da->elementtype == DMDA_ELEMENT_Q1) {
    120:             for (c=0; c<ns*nn; c++) da->e[cnt++] = cell[c];
    121:           }
    122:         }
    123:       }
    124:     }
    125:   }
    126:   *nel = da->ne;
    127:   *nen = nn;
    128:   *e   = da->e;
    129:   return(0);
    130: }

    132: /*@C
    133:       DMDASetElementType - Sets the element type to be returned by DMDAGetElements()

    135:     Not Collective

    137:    Input Parameter:
    138: .     da - the DMDA object

    140:    Output Parameters:
    141: .     etype - the element type, currently either DMDA_ELEMENT_P1 or ELEMENT_Q1

    143:    Level: intermediate

    145: .seealso: DMDAElementType, DMDAGetElementType(), DMDAGetElements(), DMDARestoreElements()
    146: @*/
    149: PetscErrorCode  DMDASetElementType(DM da, DMDAElementType etype)
    150: {
    151:   DM_DA          *dd = (DM_DA*)da->data;

    157:   if (dd->elementtype != etype) {
    158:     PetscFree(dd->e);

    160:     dd->elementtype = etype;
    161:     dd->ne          = 0;
    162:     dd->e           = NULL;
    163:   }
    164:   return(0);
    165: }

    167: /*@C
    168:       DMDAGetElementType - Gets the element type to be returned by DMDAGetElements()

    170:     Not Collective

    172:    Input Parameter:
    173: .     da - the DMDA object

    175:    Output Parameters:
    176: .     etype - the element type, currently either DMDA_ELEMENT_P1 or ELEMENT_Q1

    178:    Level: intermediate

    180: .seealso: DMDAElementType, DMDASetElementType(), DMDAGetElements(), DMDARestoreElements()
    181: @*/
    184: PetscErrorCode  DMDAGetElementType(DM da, DMDAElementType *etype)
    185: {
    186:   DM_DA *dd = (DM_DA*)da->data;

    191:   *etype = dd->elementtype;
    192:   return(0);
    193: }

    195: /*@C
    196:       DMDAGetElements - Gets an array containing the indices (in local coordinates)
    197:                  of all the local elements

    199:     Not Collective

    201:    Input Parameter:
    202: .     dm - the DM object

    204:    Output Parameters:
    205: +     nel - number of local elements
    206: .     nen - number of element nodes
    207: -     e - the local indices of the elements' vertices

    209:    Level: intermediate

    211:    Notes:
    212:      Call DMDARestoreElements() once you have finished accessing the elements.

    214:      Each process uniquely owns a subset of the elements. That is no element is owned by two or more processes.

    216:      If on each process you integrate over its owned elements and use ADD_VALUES in Vec/MatSetValuesLocal() then you'll obtain the correct result.

    218: .seealso: DMDAElementType, DMDASetElementType(), VecSetValuesLocal(), MatSetValuesLocal(), DMGlobalToLocalBegin(), DMLocalToGlobalBegin()
    219: @*/
    222: PetscErrorCode  DMDAGetElements(DM dm,PetscInt *nel,PetscInt *nen,const PetscInt *e[])
    223: {
    224:   PetscInt       dim;
    226:   DM_DA          *dd = (DM_DA*)dm->data;

    229:   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");
    230:   DMGetDimension(dm, &dim);
    231:   if (dim==-1) {
    232:     *nel = 0; *nen = 0; *e = NULL;
    233:   } else if (dim==1) {
    234:     DMDAGetElements_1D(dm,nel,nen,e);
    235:   } else if (dim==2) {
    236:     DMDAGetElements_2D(dm,nel,nen,e);
    237:   } else if (dim==3) {
    238:     DMDAGetElements_3D(dm,nel,nen,e);
    239:   } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"DMDA dimension not 1, 2, or 3, it is %D\n",dim);
    240:   return(0);
    241: }

    245: /*@C
    246:       DMDARestoreElements - Restores the array obtained with DMDAGetElements()

    248:     Not Collective

    250:    Input Parameter:
    251: +     dm - the DM object
    252: .     nel - number of local elements
    253: .     nen - number of element nodes
    254: -     e - the local indices of the elements' vertices

    256:    Level: intermediate

    258:    Note: You should not access these values after you have called this routine.

    260:          This restore signals the DMDA object that you no longer need access to the array information.

    262: .seealso: DMDAElementType, DMDASetElementType(), DMDAGetElements()
    263: @*/
    264: PetscErrorCode  DMDARestoreElements(DM dm,PetscInt *nel,PetscInt *nen,const PetscInt *e[])
    265: {
    271:   *nel = 0;
    272:   *nen = -1;
    273:   *e = NULL;
    274:   return(0);
    275: }