Actual source code: daview.c

      1: #define PETSCDM_DLL

      3: /*
      4:   Code for manipulating distributed regular arrays in parallel.
      5: */

     7:  #include src/dm/da/daimpl.h
      8: #if defined(PETSC_HAVE_PNETCDF)
     10: #include "pnetcdf.h"
     12: #endif

     15: #if defined(PETSC_HAVE_MATLAB)
     16: #include "mat.h"   /* Matlab include file */

     20: PetscErrorCode DAView_Matlab(DA da,PetscViewer viewer)
     21: {
     23:   PetscMPIInt    rank;
     24:   PetscInt       dim,m,n,p,dof,swidth;
     25:   DAStencilType  stencil;
     26:   DAPeriodicType periodic;
     27:   mxArray        *mx;
     28:   const char     *fnames[] = {"dimension","m","n","p","dof","stencil_width","periodicity","stencil_type"};

     31:   MPI_Comm_rank(da->comm,&rank);
     32:   if (!rank) {
     33:     DAGetInfo(da,&dim,&m,&n,&p,0,0,0,&dof,&swidth,&periodic,&stencil);
     34:     mx = mxCreateStructMatrix(1,1,8,(const char **)fnames);
     35:     if (!mx) SETERRQ(PETSC_ERR_LIB,"Unable to generate Matlab struct array to hold DA informations");
     36:     mxSetFieldByNumber(mx,0,0,mxCreateDoubleScalar((double)dim));
     37:     mxSetFieldByNumber(mx,0,1,mxCreateDoubleScalar((double)m));
     38:     mxSetFieldByNumber(mx,0,2,mxCreateDoubleScalar((double)n));
     39:     mxSetFieldByNumber(mx,0,3,mxCreateDoubleScalar((double)p));
     40:     mxSetFieldByNumber(mx,0,4,mxCreateDoubleScalar((double)dof));
     41:     mxSetFieldByNumber(mx,0,5,mxCreateDoubleScalar((double)swidth));
     42:     mxSetFieldByNumber(mx,0,6,mxCreateDoubleScalar((double)periodic));
     43:     mxSetFieldByNumber(mx,0,7,mxCreateDoubleScalar((double)stencil));
     44:     PetscObjectName((PetscObject)da);
     45:     PetscViewerMatlabPutVariable(viewer,da->name,mx);
     46:   }
     47:   return(0);
     48: }
     49: #endif

     53: PetscErrorCode DAView_Binary(DA da,PetscViewer viewer)
     54: {
     56:   PetscMPIInt    rank;
     57:   PetscInt       i,dim,m,n,p,dof,swidth,M,N,P;
     58:   size_t         j,len;
     59:   DAStencilType  stencil;
     60:   DAPeriodicType periodic;
     61:   MPI_Comm       comm;

     64:   PetscObjectGetComm((PetscObject)da,&comm);

     66:   DAGetInfo(da,&dim,&m,&n,&p,&M,&N,&P,&dof,&swidth,&periodic,&stencil);
     67:   MPI_Comm_rank(comm,&rank);
     68:   if (!rank) {
     69:     FILE *file;

     71:     PetscViewerBinaryGetInfoPointer(viewer,&file);
     72:     if (file) {
     73:       char fieldname[PETSC_MAX_PATH_LEN];

     75:       PetscFPrintf(PETSC_COMM_SELF,file,"-daload_info %D,%D,%D,%D,%D,%D,%D,%D\n",dim,m,n,p,dof,swidth,stencil,periodic);
     76:       for (i=0; i<dof; i++) {
     77:         if (da->fieldname[i]) {
     78:           PetscStrncpy(fieldname,da->fieldname[i],PETSC_MAX_PATH_LEN);
     79:           PetscStrlen(fieldname,&len);
     80:           len  = PetscMin(PETSC_MAX_PATH_LEN,len);
     81:           for (j=0; j<len; j++) {
     82:             if (fieldname[j] == ' ') fieldname[j] = '_';
     83:           }
     84:           PetscFPrintf(PETSC_COMM_SELF,file,"-daload_fieldname_%D %s\n",i,fieldname);
     85:         }
     86:       }
     87:       if (da->coordinates) { /* save the DA's coordinates */
     88:         PetscFPrintf(PETSC_COMM_SELF,file,"-daload_coordinates\n");
     89:       }
     90:     }
     91:   }

     93:   /* save the coordinates if they exist to disk (in the natural ordering) */
     94:   if (da->coordinates) {
     95:     DA       dac;
     96:     PetscInt *lx,*ly,*lz;
     97:     Vec      natural;

     99:     /* create the appropriate DA to map to natural ordering */
    100:     DAGetOwnershipRange(da,&lx,&ly,&lz);
    101:     if (dim == 1) {
    102:       DACreate1d(comm,DA_NONPERIODIC,m,dim,0,lx,&dac);
    103:     } else if (dim == 2) {
    104:       DACreate2d(comm,DA_NONPERIODIC,DA_STENCIL_BOX,m,n,M,N,dim,0,lx,ly,&dac);
    105:     } else if (dim == 3) {
    106:       DACreate3d(comm,DA_NONPERIODIC,DA_STENCIL_BOX,m,n,p,M,N,P,dim,0,lx,ly,lz,&dac);
    107:     } else {
    108:       SETERRQ1(PETSC_ERR_ARG_CORRUPT,"Dimension is not 1 2 or 3: %D\n",dim);
    109:     }
    110:     DACreateNaturalVector(dac,&natural);
    111:     PetscObjectSetOptionsPrefix((PetscObject)natural,"coor_");
    112:     DAGlobalToNaturalBegin(dac,da->coordinates,INSERT_VALUES,natural);
    113:     DAGlobalToNaturalEnd(dac,da->coordinates,INSERT_VALUES,natural);
    114:     VecView(natural,viewer);
    115:     VecDestroy(natural);
    116:     DADestroy(dac);
    117:   }

    119:   return(0);
    120: }

    124: /*@C
    125:    DAView - Visualizes a distributed array object.

    127:    Collective on DA

    129:    Input Parameters:
    130: +  da - the distributed array
    131: -  ptr - an optional visualization context

    133:    Notes:
    134:    The available visualization contexts include
    135: +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
    136: .     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
    137:          output where only the first processor opens
    138:          the file.  All other processors send their
    139:          data to the first processor to print.
    140: -     PETSC_VIEWER_DRAW_WORLD - to default window

    142:    The user can open alternative visualization contexts with
    143: +    PetscViewerASCIIOpen() - Outputs vector to a specified file
    144: -    PetscViewerDrawOpen() - Outputs vector to an X window display

    146:    Default Output Format:
    147:   (for 3d arrays)
    148: .vb
    149:    Processor [proc] M  N  P  m  n  p  w  s
    150:    X range: xs xe, Y range: ys, ye, Z range: zs, ze

    152:    where
    153:       M,N,P - global dimension in each direction of the array
    154:       m,n,p - corresponding number of procs in each dimension
    155:       w - number of degrees of freedom per node
    156:       s - stencil width
    157:       xs, xe - internal local starting/ending grid points
    158:                in x-direction, (augmented to handle multiple
    159:                degrees of freedom per node)
    160:       ys, ye - local starting/ending grid points in y-direction
    161:       zs, ze - local starting/ending grid points in z-direction
    162: .ve

    164:    Options Database Key:
    165: .  -da_view - Calls DAView() at the conclusion of DACreate1d(),
    166:               DACreate2d(), and DACreate3d()

    168:    Level: beginner

    170:    Notes:
    171:    Use DAGetCorners() and DAGetGhostCorners() to get the starting
    172:    and ending grid points (ghost points) in each direction.

    174:    When drawing the DA grid it only draws the logical grid and does not
    175:    respect the grid coordinates set with DASetCoordinates()

    177: .keywords: distributed array, view, visualize

    179: .seealso: PetscViewerASCIIOpen(), PetscViewerDrawOpen(), DAGetInfo(), DAGetCorners(),
    180:           DAGetGhostCorners()
    181: @*/
    182: PetscErrorCode PETSCDM_DLLEXPORT DAView(DA da,PetscViewer viewer)
    183: {
    185:   PetscInt i,dof = da->w;
    186:   PetscTruth iascii,fieldsnamed = PETSC_FALSE,isbinary;
    187: #if defined(PETSC_HAVE_MATLAB)
    188:   PetscTruth ismatlab;
    189: #endif

    193:   if (!viewer) viewer = PETSC_VIEWER_STDOUT_(da->comm);

    196:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
    197:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_BINARY,&isbinary);
    198: #if defined(PETSC_HAVE_MATLAB)
    199:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_MATLAB,&ismatlab);
    200: #endif
    201:   if (iascii) {
    202:     for (i=0; i<dof; i++) {
    203:       if (da->fieldname[i]) {
    204:         fieldsnamed = PETSC_TRUE;
    205:         break;
    206:       }
    207:     }
    208:     if (fieldsnamed) {
    209:       PetscViewerASCIIPrintf(viewer,"FieldNames: ");
    210:       for (i=0; i<dof; i++) {
    211:         if (da->fieldname[i]) {
    212:           PetscViewerASCIIPrintf(viewer,"%s ",da->fieldname[i]);
    213:         } else {
    214:           PetscViewerASCIIPrintf(viewer,"(not named) ");
    215:         }
    216:       }
    217:       PetscViewerASCIIPrintf(viewer,"\n");
    218:     }
    219:   }
    220:   if (isbinary){
    221:     DAView_Binary(da,viewer);
    222: #if defined(PETSC_HAVE_MATLAB)
    223:   } else if (ismatlab) {
    224:     DAView_Matlab(da,viewer);
    225: #endif
    226:   } else {
    227:     (*da->ops->view)(da,viewer);
    228:   }
    229:   return(0);
    230: }

    234: /*@C
    235:    DAGetInfo - Gets information about a given distributed array.

    237:    Not Collective

    239:    Input Parameter:
    240: .  da - the distributed array

    242:    Output Parameters:
    243: +  dim     - dimension of the distributed array (1, 2, or 3)
    244: .  M, N, P - global dimension in each direction of the array
    245: .  m, n, p - corresponding number of procs in each dimension
    246: .  dof     - number of degrees of freedom per node
    247: .  s       - stencil width
    248: .  wrap    - type of periodicity, on of DA_NONPERIODIC, DA_XPERIODIC, DA_YPERIODIC,
    249:              DA_XYPERIODIC, DA_XYZPERIODIC, DA_XZPERIODIC, DA_YZPERIODIC,DA_ZPERIODIC
    250: -  st      - stencil type, either DA_STENCIL_STAR or DA_STENCIL_BOX

    252:    Level: beginner
    253:
    254:    Note:
    255:    Use PETSC_NULL (PETSC_NULL_INTEGER in Fortran) in place of any output parameter that is not of interest.

    257: .keywords: distributed array, get, information

    259: .seealso: DAView(), DAGetCorners(), DAGetLocalInfo()
    260: @*/
    261: PetscErrorCode PETSCDM_DLLEXPORT DAGetInfo(DA da,PetscInt *dim,PetscInt *M,PetscInt *N,PetscInt *P,PetscInt *m,PetscInt *n,PetscInt *p,PetscInt *dof,PetscInt *s,DAPeriodicType *wrap,DAStencilType *st)
    262: {
    265:   if (dim)  *dim  = da->dim;
    266:   if (M)    *M    = da->M;
    267:   if (N)    *N    = da->N;
    268:   if (P)    *P    = da->P;
    269:   if (m)    *m    = da->m;
    270:   if (n)    *n    = da->n;
    271:   if (p)    *p    = da->p;
    272:   if (dof)  *dof  = da->w;
    273:   if (s)    *s    = da->s;
    274:   if (wrap) *wrap = da->wrap;
    275:   if (st)   *st   = da->stencil_type;
    276:   return(0);
    277: }

    281: /*@C
    282:    DAGetLocalInfo - Gets information about a given distributed array and this processors location in it

    284:    Not Collective

    286:    Input Parameter:
    287: .  da - the distributed array

    289:    Output Parameters:
    290: .  dainfo - structure containing the information

    292:    Level: beginner
    293:
    294: .keywords: distributed array, get, information

    296: .seealso: DAGetInfo(), DAGetCorners()
    297: @*/
    298: PetscErrorCode PETSCDM_DLLEXPORT DAGetLocalInfo(DA da,DALocalInfo *info)
    299: {
    300:   PetscInt w;

    305:   info->da   = da;
    306:   info->dim  = da->dim;
    307:   info->mx   = da->M;
    308:   info->my   = da->N;
    309:   info->mz   = da->P;
    310:   info->dof  = da->w;
    311:   info->sw   = da->s;
    312:   info->pt   = da->wrap;
    313:   info->st   = da->stencil_type;

    315:   /* since the xs, xe ... have all been multiplied by the number of degrees
    316:      of freedom per cell, w = da->w, we divide that out before returning.*/
    317:   w = da->w;
    318:   info->xs = da->xs/w;
    319:   info->xm = (da->xe - da->xs)/w;
    320:   /* the y and z have NOT been multiplied by w */
    321:   info->ys = da->ys;
    322:   info->ym = (da->ye - da->ys);
    323:   info->zs = da->zs;
    324:   info->zm = (da->ze - da->zs);

    326:   info->gxs = da->Xs/w;
    327:   info->gxm = (da->Xe - da->Xs)/w;
    328:   /* the y and z have NOT been multiplied by w */
    329:   info->gys = da->Ys;
    330:   info->gym = (da->Ye - da->Ys);
    331:   info->gzs = da->Zs;
    332:   info->gzm = (da->Ze - da->Zs);
    333:   return(0);
    334: }