xref: /petsc/src/dm/impls/da/gr2.c (revision 4e6118eedf9e3cd4e1d2a9fd94ca99819fa45add)
147c6ae99SBarry Smith 
247c6ae99SBarry Smith /*
3aa219208SBarry Smith    Plots vectors obtained with DMDACreate2d()
447c6ae99SBarry Smith */
547c6ae99SBarry Smith 
6b45d2f2cSJed Brown #include <petsc-private/daimpl.h>      /*I  "petscdmda.h"   I*/
7b45d2f2cSJed Brown #include <petsc-private/vecimpl.h>
847c6ae99SBarry Smith 
947c6ae99SBarry Smith /*
1047c6ae99SBarry Smith         The data that is passed into the graphics callback
1147c6ae99SBarry Smith */
1247c6ae99SBarry Smith typedef struct {
1347c6ae99SBarry Smith   PetscInt     m,n,step,k;
1447c6ae99SBarry Smith   PetscReal    min,max,scale;
1547c6ae99SBarry Smith   PetscScalar  *xy,*v;
1647c6ae99SBarry Smith   PetscBool    showgrid;
1747c6ae99SBarry Smith } ZoomCtx;
1847c6ae99SBarry Smith 
1947c6ae99SBarry Smith /*
2047c6ae99SBarry Smith        This does the drawing for one particular field
2147c6ae99SBarry Smith     in one particular set of coordinates. It is a callback
2247c6ae99SBarry Smith     called from PetscDrawZoom()
2347c6ae99SBarry Smith */
2447c6ae99SBarry Smith #undef __FUNCT__
2547c6ae99SBarry Smith #define __FUNCT__ "VecView_MPI_Draw_DA2d_Zoom"
2647c6ae99SBarry Smith PetscErrorCode VecView_MPI_Draw_DA2d_Zoom(PetscDraw draw,void *ctx)
2747c6ae99SBarry Smith {
2847c6ae99SBarry Smith   ZoomCtx        *zctx = (ZoomCtx*)ctx;
2947c6ae99SBarry Smith   PetscErrorCode ierr;
3047c6ae99SBarry Smith   PetscInt       m,n,i,j,k,step,id,c1,c2,c3,c4;
3147c6ae99SBarry Smith   PetscReal      s,min,x1,x2,x3,x4,y_1,y2,y3,y4;
3247c6ae99SBarry Smith   PetscScalar   *v,*xy;
3347c6ae99SBarry Smith 
3447c6ae99SBarry Smith   PetscFunctionBegin;
3547c6ae99SBarry Smith   m    = zctx->m;
3647c6ae99SBarry Smith   n    = zctx->n;
3747c6ae99SBarry Smith   step = zctx->step;
3847c6ae99SBarry Smith   k    = zctx->k;
3947c6ae99SBarry Smith   v    = zctx->v;
4047c6ae99SBarry Smith   xy   = zctx->xy;
4147c6ae99SBarry Smith   s    = zctx->scale;
4247c6ae99SBarry Smith   min  = zctx->min;
4347c6ae99SBarry Smith 
4447c6ae99SBarry Smith   /* PetscDraw the contour plot patch */
4547c6ae99SBarry Smith   for (j=0; j<n-1; j++) {
4647c6ae99SBarry Smith     for (i=0; i<m-1; i++) {
4747c6ae99SBarry Smith #if !defined(PETSC_USE_COMPLEX)
4847c6ae99SBarry Smith       id = i+j*m;    x1 = xy[2*id];y_1 = xy[2*id+1];c1 = (int)(PETSC_DRAW_BASIC_COLORS+s*(v[k+step*id]-min));
4947c6ae99SBarry Smith       id = i+j*m+1;  x2 = xy[2*id];y2  = y_1;       c2 = (int)(PETSC_DRAW_BASIC_COLORS+s*(v[k+step*id]-min));
5047c6ae99SBarry Smith       id = i+j*m+1+m;x3 = x2;      y3  = xy[2*id+1];c3 = (int)(PETSC_DRAW_BASIC_COLORS+s*(v[k+step*id]-min));
5147c6ae99SBarry Smith       id = i+j*m+m;  x4 = x1;      y4  = y3;        c4 = (int)(PETSC_DRAW_BASIC_COLORS+s*(v[k+step*id]-min));
5247c6ae99SBarry Smith #else
5347c6ae99SBarry Smith       id = i+j*m;    x1 = PetscRealPart(xy[2*id]);y_1 = PetscRealPart(xy[2*id+1]);c1 = (int)(PETSC_DRAW_BASIC_COLORS+s*(PetscRealPart(v[k+step*id])-min));
5447c6ae99SBarry Smith       id = i+j*m+1;  x2 = PetscRealPart(xy[2*id]);y2  = y_1;       c2 = (int)(PETSC_DRAW_BASIC_COLORS+s*(PetscRealPart(v[k+step*id])-min));
5547c6ae99SBarry Smith       id = i+j*m+1+m;x3 = x2;      y3  = PetscRealPart(xy[2*id+1]);c3 = (int)(PETSC_DRAW_BASIC_COLORS+s*(PetscRealPart(v[k+step*id])-min));
5647c6ae99SBarry Smith       id = i+j*m+m;  x4 = x1;      y4  = y3;        c4 = (int)(PETSC_DRAW_BASIC_COLORS+s*(PetscRealPart(v[k+step*id])-min));
5747c6ae99SBarry Smith #endif
5847c6ae99SBarry Smith       ierr = PetscDrawTriangle(draw,x1,y_1,x2,y2,x3,y3,c1,c2,c3);CHKERRQ(ierr);
5947c6ae99SBarry Smith       ierr = PetscDrawTriangle(draw,x1,y_1,x3,y3,x4,y4,c1,c3,c4);CHKERRQ(ierr);
6047c6ae99SBarry Smith       if (zctx->showgrid) {
6147c6ae99SBarry Smith         ierr = PetscDrawLine(draw,x1,y_1,x2,y2,PETSC_DRAW_BLACK);CHKERRQ(ierr);
6247c6ae99SBarry Smith         ierr = PetscDrawLine(draw,x2,y2,x3,y3,PETSC_DRAW_BLACK);CHKERRQ(ierr);
6347c6ae99SBarry Smith         ierr = PetscDrawLine(draw,x3,y3,x4,y4,PETSC_DRAW_BLACK);CHKERRQ(ierr);
6447c6ae99SBarry Smith         ierr = PetscDrawLine(draw,x4,y4,x1,y_1,PETSC_DRAW_BLACK);CHKERRQ(ierr);
6547c6ae99SBarry Smith       }
6647c6ae99SBarry Smith     }
6747c6ae99SBarry Smith   }
6847c6ae99SBarry Smith   PetscFunctionReturn(0);
6947c6ae99SBarry Smith }
7047c6ae99SBarry Smith 
7147c6ae99SBarry Smith #undef __FUNCT__
7247c6ae99SBarry Smith #define __FUNCT__ "VecView_MPI_Draw_DA2d"
7347c6ae99SBarry Smith PetscErrorCode VecView_MPI_Draw_DA2d(Vec xin,PetscViewer viewer)
7447c6ae99SBarry Smith {
759a42bb27SBarry Smith   DM                 da,dac,dag;
7647c6ae99SBarry Smith   PetscErrorCode     ierr;
7747c6ae99SBarry Smith   PetscMPIInt        rank;
78f7923d8aSBarry Smith   PetscInt           N,s,M,w;
7947c6ae99SBarry Smith   const PetscInt     *lx,*ly;
8047c6ae99SBarry Smith   PetscReal          coors[4],ymin,ymax,xmin,xmax;
8147c6ae99SBarry Smith   PetscDraw          draw,popup;
8247c6ae99SBarry Smith   PetscBool          isnull,useports = PETSC_FALSE;
8347c6ae99SBarry Smith   MPI_Comm           comm;
8447c6ae99SBarry Smith   Vec                xlocal,xcoor,xcoorl;
851321219cSEthan Coon   DMDABoundaryType   bx,by;
86aa219208SBarry Smith   DMDAStencilType    st;
8747c6ae99SBarry Smith   ZoomCtx            zctx;
88f8631f9bSBarry Smith   PetscDrawViewPorts *ports = PETSC_NULL;
8947c6ae99SBarry Smith   PetscViewerFormat  format;
9020d0051dSBarry Smith   PetscInt           *displayfields;
9167dd0837SBarry Smith   PetscInt           ndisplayfields,i,nbounds;
9267dd0837SBarry Smith   const PetscReal    *bounds;
9347c6ae99SBarry Smith 
9447c6ae99SBarry Smith   PetscFunctionBegin;
9547c6ae99SBarry Smith   zctx.showgrid = PETSC_FALSE;
9647c6ae99SBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
9747c6ae99SBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); if (isnull) PetscFunctionReturn(0);
9803193ff8SBarry Smith   ierr = PetscViewerDrawGetBounds(viewer,&nbounds,&bounds);CHKERRQ(ierr);
9947c6ae99SBarry Smith 
100c688c046SMatthew G Knepley   ierr = VecGetDM(xin,&da);CHKERRQ(ierr);
101aa219208SBarry Smith   if (!da) SETERRQ(((PetscObject)xin)->comm,PETSC_ERR_ARG_WRONG,"Vector not generated from a DMDA");
10247c6ae99SBarry Smith 
10347c6ae99SBarry Smith   ierr = PetscObjectGetComm((PetscObject)xin,&comm);CHKERRQ(ierr);
10447c6ae99SBarry Smith   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
10547c6ae99SBarry Smith 
1061321219cSEthan Coon   ierr = DMDAGetInfo(da,0,&M,&N,0,&zctx.m,&zctx.n,0,&w,&s,&bx,&by,0,&st);CHKERRQ(ierr);
107aa219208SBarry Smith   ierr = DMDAGetOwnershipRanges(da,&lx,&ly,PETSC_NULL);CHKERRQ(ierr);
10847c6ae99SBarry Smith 
10947c6ae99SBarry Smith   /*
11047c6ae99SBarry Smith         Obtain a sequential vector that is going to contain the local values plus ONE layer of
111aa219208SBarry Smith      ghosted values to draw the graphics from. We also need its corresponding DMDA (dac) that will
11247c6ae99SBarry Smith      update the local values pluse ONE layer of ghost values.
11347c6ae99SBarry Smith   */
11447c6ae99SBarry Smith   ierr = PetscObjectQuery((PetscObject)da,"GraphicsGhosted",(PetscObject*)&xlocal);CHKERRQ(ierr);
11547c6ae99SBarry Smith   if (!xlocal) {
116f7923d8aSBarry Smith     if (bx !=  DMDA_BOUNDARY_NONE || by !=  DMDA_BOUNDARY_NONE || s != 1 || st != DMDA_STENCIL_BOX) {
11747c6ae99SBarry Smith       /*
11847c6ae99SBarry Smith          if original da is not of stencil width one, or periodic or not a box stencil then
119aa219208SBarry Smith          create a special DMDA to handle one level of ghost points for graphics
12047c6ae99SBarry Smith       */
1211321219cSEthan Coon       ierr = DMDACreate2d(comm,DMDA_BOUNDARY_NONE,DMDA_BOUNDARY_NONE,DMDA_STENCIL_BOX,M,N,zctx.m,zctx.n,w,1,lx,ly,&dac);CHKERRQ(ierr);
122aa219208SBarry Smith       ierr = PetscInfo(da,"Creating auxilary DMDA for managing graphics ghost points\n");CHKERRQ(ierr);
12347c6ae99SBarry Smith     } else {
12447c6ae99SBarry Smith       /* otherwise we can use the da we already have */
12547c6ae99SBarry Smith       dac = da;
12647c6ae99SBarry Smith     }
12747c6ae99SBarry Smith     /* create local vector for holding ghosted values used in graphics */
128564755cdSBarry Smith     ierr = DMCreateLocalVector(dac,&xlocal);CHKERRQ(ierr);
12947c6ae99SBarry Smith     if (dac != da) {
130aa219208SBarry Smith       /* don't keep any public reference of this DMDA, is is only available through xlocal */
131f7923d8aSBarry Smith       ierr = PetscObjectDereference((PetscObject)dac);CHKERRQ(ierr);
13247c6ae99SBarry Smith     } else {
13347c6ae99SBarry Smith       /* remove association between xlocal and da, because below we compose in the opposite
13447c6ae99SBarry Smith          direction and if we left this connect we'd get a loop, so the objects could
13547c6ae99SBarry Smith          never be destroyed */
136c688c046SMatthew G Knepley       ierr = PetscObjectRemoveReference((PetscObject)xlocal,"__PETSc_dm");CHKERRQ(ierr);
13747c6ae99SBarry Smith     }
13847c6ae99SBarry Smith     ierr = PetscObjectCompose((PetscObject)da,"GraphicsGhosted",(PetscObject)xlocal);CHKERRQ(ierr);
13947c6ae99SBarry Smith     ierr = PetscObjectDereference((PetscObject)xlocal);CHKERRQ(ierr);
14047c6ae99SBarry Smith   } else {
141f7923d8aSBarry Smith     if (bx !=  DMDA_BOUNDARY_NONE || by !=  DMDA_BOUNDARY_NONE || s != 1 || st != DMDA_STENCIL_BOX) {
142c688c046SMatthew G Knepley       ierr = VecGetDM(xlocal, &dac);CHKERRQ(ierr);
143f7923d8aSBarry Smith     } else {
144f7923d8aSBarry Smith       dac = da;
14547c6ae99SBarry Smith     }
14647c6ae99SBarry Smith   }
14747c6ae99SBarry Smith 
14847c6ae99SBarry Smith   /*
14947c6ae99SBarry Smith       Get local (ghosted) values of vector
15047c6ae99SBarry Smith   */
1519a42bb27SBarry Smith   ierr = DMGlobalToLocalBegin(dac,xin,INSERT_VALUES,xlocal);CHKERRQ(ierr);
1529a42bb27SBarry Smith   ierr = DMGlobalToLocalEnd(dac,xin,INSERT_VALUES,xlocal);CHKERRQ(ierr);
15347c6ae99SBarry Smith   ierr = VecGetArray(xlocal,&zctx.v);CHKERRQ(ierr);
15447c6ae99SBarry Smith 
15547c6ae99SBarry Smith   /* get coordinates of nodes */
1566636e97aSMatthew G Knepley   ierr = DMGetCoordinates(da,&xcoor);CHKERRQ(ierr);
15747c6ae99SBarry Smith   if (!xcoor) {
158aa219208SBarry Smith     ierr = DMDASetUniformCoordinates(da,0.0,1.0,0.0,1.0,0.0,0.0);CHKERRQ(ierr);
1596636e97aSMatthew G Knepley     ierr = DMGetCoordinates(da,&xcoor);CHKERRQ(ierr);
16047c6ae99SBarry Smith   }
16147c6ae99SBarry Smith 
16247c6ae99SBarry Smith   /*
16347c6ae99SBarry Smith       Determine the min and max  coordinates in plot
16447c6ae99SBarry Smith   */
16547c6ae99SBarry Smith   ierr = VecStrideMin(xcoor,0,PETSC_NULL,&xmin);CHKERRQ(ierr);
16647c6ae99SBarry Smith   ierr = VecStrideMax(xcoor,0,PETSC_NULL,&xmax);CHKERRQ(ierr);
16747c6ae99SBarry Smith   ierr = VecStrideMin(xcoor,1,PETSC_NULL,&ymin);CHKERRQ(ierr);
16847c6ae99SBarry Smith   ierr = VecStrideMax(xcoor,1,PETSC_NULL,&ymax);CHKERRQ(ierr);
16947c6ae99SBarry Smith   coors[0] = xmin - .05*(xmax- xmin); coors[2] = xmax + .05*(xmax - xmin);
17047c6ae99SBarry Smith   coors[1] = ymin - .05*(ymax- ymin); coors[3] = ymax + .05*(ymax - ymin);
171aa219208SBarry Smith   ierr = PetscInfo4(da,"Preparing DMDA 2d contour plot coordinates %G %G %G %G\n",coors[0],coors[1],coors[2],coors[3]);CHKERRQ(ierr);
17247c6ae99SBarry Smith 
17347c6ae99SBarry Smith   /*
17447c6ae99SBarry Smith        get local ghosted version of coordinates
17547c6ae99SBarry Smith   */
17647c6ae99SBarry Smith   ierr = PetscObjectQuery((PetscObject)da,"GraphicsCoordinateGhosted",(PetscObject*)&xcoorl);CHKERRQ(ierr);
17747c6ae99SBarry Smith   if (!xcoorl) {
178aa219208SBarry Smith     /* create DMDA to get local version of graphics */
1791321219cSEthan Coon     ierr = DMDACreate2d(comm,DMDA_BOUNDARY_NONE,DMDA_BOUNDARY_NONE,DMDA_STENCIL_BOX,M,N,zctx.m,zctx.n,2,1,lx,ly,&dag);CHKERRQ(ierr);
180aa219208SBarry Smith     ierr = PetscInfo(dag,"Creating auxilary DMDA for managing graphics coordinates ghost points\n");CHKERRQ(ierr);
181564755cdSBarry Smith     ierr = DMCreateLocalVector(dag,&xcoorl);CHKERRQ(ierr);
18247c6ae99SBarry Smith     ierr = PetscObjectCompose((PetscObject)da,"GraphicsCoordinateGhosted",(PetscObject)xcoorl);CHKERRQ(ierr);
183f7923d8aSBarry Smith     ierr = PetscObjectDereference((PetscObject)dag);CHKERRQ(ierr);
18447c6ae99SBarry Smith     ierr = PetscObjectDereference((PetscObject)xcoorl);CHKERRQ(ierr);
18547c6ae99SBarry Smith   } else {
186c688c046SMatthew G Knepley     ierr = VecGetDM(xcoorl,&dag);CHKERRQ(ierr);
18747c6ae99SBarry Smith   }
1889a42bb27SBarry Smith   ierr = DMGlobalToLocalBegin(dag,xcoor,INSERT_VALUES,xcoorl);CHKERRQ(ierr);
1899a42bb27SBarry Smith   ierr = DMGlobalToLocalEnd(dag,xcoor,INSERT_VALUES,xcoorl);CHKERRQ(ierr);
19047c6ae99SBarry Smith   ierr = VecGetArray(xcoorl,&zctx.xy);CHKERRQ(ierr);
19147c6ae99SBarry Smith 
19247c6ae99SBarry Smith   /*
19347c6ae99SBarry Smith         Get information about size of area each processor must do graphics for
19447c6ae99SBarry Smith   */
1951321219cSEthan Coon   ierr = DMDAGetInfo(dac,0,&M,&N,0,0,0,0,&zctx.step,0,&bx,&by,0,0);CHKERRQ(ierr);
196f7923d8aSBarry Smith   ierr = DMDAGetGhostCorners(dac,0,0,0,&zctx.m,&zctx.n,0);CHKERRQ(ierr);
19747c6ae99SBarry Smith 
198671f6225SBarry Smith   ierr = PetscOptionsGetBool(PETSC_NULL,"-draw_contour_grid",&zctx.showgrid,PETSC_NULL);CHKERRQ(ierr);
199*4e6118eeSBarry Smith 
200*4e6118eeSBarry Smith   ierr = DMDASelectFields(da,&ndisplayfields,&displayfields);CHKERRQ(ierr);
20147c6ae99SBarry Smith 
20247c6ae99SBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
203671f6225SBarry Smith   ierr = PetscOptionsGetBool(PETSC_NULL,"-draw_ports",&useports,PETSC_NULL);CHKERRQ(ierr);
20447c6ae99SBarry Smith   if (useports || format == PETSC_VIEWER_DRAW_PORTS){
20547c6ae99SBarry Smith     ierr = PetscDrawSynchronizedClear(draw);CHKERRQ(ierr);
20620d0051dSBarry Smith     ierr = PetscDrawViewPortsCreate(draw,ndisplayfields,&ports);CHKERRQ(ierr);
20747c6ae99SBarry Smith   }
20820d0051dSBarry Smith 
20947c6ae99SBarry Smith   /*
21047c6ae99SBarry Smith      Loop over each field; drawing each in a different window
21147c6ae99SBarry Smith   */
21220d0051dSBarry Smith   for (i=0; i<ndisplayfields; i++) {
21320d0051dSBarry Smith     zctx.k = displayfields[i];
21447c6ae99SBarry Smith     if (useports) {
21520d0051dSBarry Smith       ierr = PetscDrawViewPortsSet(ports,i);CHKERRQ(ierr);
2169332fd86SBarry Smith     } else {
2179332fd86SBarry Smith       ierr = PetscViewerDrawGetDraw(viewer,i,&draw);CHKERRQ(ierr);
21847c6ae99SBarry Smith     }
21947c6ae99SBarry Smith 
22047c6ae99SBarry Smith     /*
22147c6ae99SBarry Smith         Determine the min and max color in plot
22247c6ae99SBarry Smith     */
22347c6ae99SBarry Smith     ierr = VecStrideMin(xin,zctx.k,PETSC_NULL,&zctx.min);CHKERRQ(ierr);
22447c6ae99SBarry Smith     ierr = VecStrideMax(xin,zctx.k,PETSC_NULL,&zctx.max);CHKERRQ(ierr);
22567dd0837SBarry Smith     if (zctx.k < nbounds) {
22667dd0837SBarry Smith       zctx.min = PetscMin(zctx.min,bounds[2*zctx.k]);
22767dd0837SBarry Smith       zctx.max = PetscMax(zctx.max,bounds[2*zctx.k+1]);
22867dd0837SBarry Smith     }
22947c6ae99SBarry Smith     if (zctx.min == zctx.max) {
23047c6ae99SBarry Smith       zctx.min -= 1.e-12;
23147c6ae99SBarry Smith       zctx.max += 1.e-12;
23247c6ae99SBarry Smith     }
23347c6ae99SBarry Smith 
23447c6ae99SBarry Smith     if (!rank) {
23547c6ae99SBarry Smith       const char *title;
23647c6ae99SBarry Smith 
237aa219208SBarry Smith       ierr = DMDAGetFieldName(da,zctx.k,&title);CHKERRQ(ierr);
23847c6ae99SBarry Smith       if (title) {
23947c6ae99SBarry Smith         ierr = PetscDrawSetTitle(draw,title);CHKERRQ(ierr);
24047c6ae99SBarry Smith       }
24147c6ae99SBarry Smith     }
24247c6ae99SBarry Smith     ierr = PetscDrawSetCoordinates(draw,coors[0],coors[1],coors[2],coors[3]);CHKERRQ(ierr);
243aa219208SBarry Smith     ierr = PetscInfo2(da,"DMDA 2d contour plot min %G max %G\n",zctx.min,zctx.max);CHKERRQ(ierr);
24447c6ae99SBarry Smith 
24547c6ae99SBarry Smith     ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr);
24647c6ae99SBarry Smith     if (popup) {ierr = PetscDrawScalePopup(popup,zctx.min,zctx.max);CHKERRQ(ierr);}
24747c6ae99SBarry Smith 
24847c6ae99SBarry Smith     zctx.scale = (245.0 - PETSC_DRAW_BASIC_COLORS)/(zctx.max - zctx.min);
24947c6ae99SBarry Smith 
25047c6ae99SBarry Smith     ierr = PetscDrawZoom(draw,VecView_MPI_Draw_DA2d_Zoom,&zctx);CHKERRQ(ierr);
25147c6ae99SBarry Smith   }
25220d0051dSBarry Smith   ierr = PetscFree(displayfields);CHKERRQ(ierr);
2536bf464f9SBarry Smith   ierr = PetscDrawViewPortsDestroy(ports);CHKERRQ(ierr);
25447c6ae99SBarry Smith 
25547c6ae99SBarry Smith   ierr = VecRestoreArray(xcoorl,&zctx.xy);CHKERRQ(ierr);
25647c6ae99SBarry Smith   ierr = VecRestoreArray(xlocal,&zctx.v);CHKERRQ(ierr);
25747c6ae99SBarry Smith   PetscFunctionReturn(0);
25847c6ae99SBarry Smith }
25947c6ae99SBarry Smith 
26047c6ae99SBarry Smith 
26147c6ae99SBarry Smith #if defined(PETSC_HAVE_HDF5)
26247c6ae99SBarry Smith #undef __FUNCT__
26347c6ae99SBarry Smith #define __FUNCT__ "VecView_MPI_HDF5_DA"
26447c6ae99SBarry Smith PetscErrorCode VecView_MPI_HDF5_DA(Vec xin,PetscViewer viewer)
26547c6ae99SBarry Smith {
2669b2a5a86SJed Brown   DM             dm;
2679b2a5a86SJed Brown   DM_DA          *da;
26847c6ae99SBarry Smith   hid_t          filespace;  /* file dataspace identifier */
2698e2ae6d7SMichael Kraus   hid_t          chunkspace; /* chunk dataset property identifier */
27047c6ae99SBarry Smith   hid_t	         plist_id;   /* property list identifier */
27147c6ae99SBarry Smith   hid_t          dset_id;    /* dataset identifier */
27247c6ae99SBarry Smith   hid_t          memspace;   /* memory dataspace identifier */
27347c6ae99SBarry Smith   hid_t          file_id;
27415214e8eSMatthew G Knepley   hid_t          group;
2758e2ae6d7SMichael Kraus   hid_t          scalartype; /* scalar type (H5T_NATIVE_FLOAT or H5T_NATIVE_DOUBLE) */
27647c6ae99SBarry Smith   herr_t         status;
2778e2ae6d7SMichael Kraus   hsize_t        i, dim;
2788e2ae6d7SMichael Kraus   hsize_t        maxDims[6], dims[6], chunkDims[6], count[6], offset[6];
27915214e8eSMatthew G Knepley   PetscInt       timestep;
2808e2ae6d7SMichael Kraus   PetscScalar    *x;
2818e2ae6d7SMichael Kraus   const char     *vecname;
28215214e8eSMatthew G Knepley   PetscErrorCode ierr;
28347c6ae99SBarry Smith 
28447c6ae99SBarry Smith   PetscFunctionBegin;
28515214e8eSMatthew G Knepley   ierr = PetscViewerHDF5OpenGroup(viewer, &file_id, &group);CHKERRQ(ierr);
2868e2ae6d7SMichael Kraus   ierr = PetscViewerHDF5GetTimestep(viewer, &timestep);CHKERRQ(ierr);
28715214e8eSMatthew G Knepley 
288c688c046SMatthew G Knepley   ierr = VecGetDM(xin,&dm);CHKERRQ(ierr);
2899b2a5a86SJed Brown   if (!dm) SETERRQ(((PetscObject)xin)->comm,PETSC_ERR_ARG_WRONG,"Vector not generated from a DMDA");
2909b2a5a86SJed Brown   da = (DM_DA*)dm->data;
29147c6ae99SBarry Smith 
2928e2ae6d7SMichael Kraus   /* Create the dataspace for the dataset.
2938e2ae6d7SMichael Kraus    *
2948e2ae6d7SMichael Kraus    * dims - holds the current dimensions of the dataset
2958e2ae6d7SMichael Kraus    *
2968e2ae6d7SMichael Kraus    * maxDims - holds the maximum dimensions of the dataset (unlimited
2978e2ae6d7SMichael Kraus    * for the number of time steps with the current dimensions for the
2988e2ae6d7SMichael Kraus    * other dimensions; so only additional time steps can be added).
2998e2ae6d7SMichael Kraus    *
3008e2ae6d7SMichael Kraus    * chunkDims - holds the size of a single time step (required to
3018e2ae6d7SMichael Kraus    * permit extending dataset).
3028e2ae6d7SMichael Kraus    */
3038e2ae6d7SMichael Kraus   dim = 0;
3048e2ae6d7SMichael Kraus   if (timestep >= 0) {
3058e2ae6d7SMichael Kraus     dims[dim]      = timestep+1;
3068e2ae6d7SMichael Kraus     maxDims[dim]   = H5S_UNLIMITED;
3078e2ae6d7SMichael Kraus     chunkDims[dim] = 1;
3088e2ae6d7SMichael Kraus     ++dim;
3098e2ae6d7SMichael Kraus   }
3108e2ae6d7SMichael Kraus   if (da->dim == 3) {
3118e2ae6d7SMichael Kraus     dims[dim]      = PetscHDF5IntCast(da->P);
3128e2ae6d7SMichael Kraus     maxDims[dim]   = dims[dim];
3138e2ae6d7SMichael Kraus     chunkDims[dim] = dims[dim];
3148e2ae6d7SMichael Kraus     ++dim;
3158e2ae6d7SMichael Kraus   }
3168e2ae6d7SMichael Kraus   if (da->dim > 1) {
3178e2ae6d7SMichael Kraus     dims[dim]      = PetscHDF5IntCast(da->N);
3188e2ae6d7SMichael Kraus     maxDims[dim]   = dims[dim];
3198e2ae6d7SMichael Kraus     chunkDims[dim] = dims[dim];
3208e2ae6d7SMichael Kraus     ++dim;
3218e2ae6d7SMichael Kraus   }
3228e2ae6d7SMichael Kraus   dims[dim]    = PetscHDF5IntCast(da->M);
3238e2ae6d7SMichael Kraus   maxDims[dim]   = dims[dim];
3248e2ae6d7SMichael Kraus   chunkDims[dim] = dims[dim];
3258e2ae6d7SMichael Kraus   ++dim;
3268e2ae6d7SMichael Kraus   if (da->w > 1) {
3278e2ae6d7SMichael Kraus     dims[dim]      = PetscHDF5IntCast(da->w);
3288e2ae6d7SMichael Kraus     maxDims[dim]   = dims[dim];
3298e2ae6d7SMichael Kraus     chunkDims[dim] = dims[dim];
3308e2ae6d7SMichael Kraus     ++dim;
3318e2ae6d7SMichael Kraus   }
33247c6ae99SBarry Smith #if defined(PETSC_USE_COMPLEX)
3338e2ae6d7SMichael Kraus     dims[dim]      = 2;
3348e2ae6d7SMichael Kraus     maxDims[dim]   = dims[dim];
3358e2ae6d7SMichael Kraus     chunkDims[dim] = dims[dim];
3368e2ae6d7SMichael Kraus     ++dim;
33747c6ae99SBarry Smith #endif
3388e2ae6d7SMichael Kraus   for (i=0; i < dim; ++i)
3398e2ae6d7SMichael Kraus   filespace = H5Screate_simple(dim, dims, maxDims);
34047c6ae99SBarry Smith   if (filespace == -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Cannot H5Screate_simple()");
34147c6ae99SBarry Smith 
34215214e8eSMatthew G Knepley #if defined(PETSC_USE_REAL_SINGLE)
34315214e8eSMatthew G Knepley   scalartype = H5T_NATIVE_FLOAT;
34415214e8eSMatthew G Knepley #elif defined(PETSC_USE_REAL___FLOAT128)
34515214e8eSMatthew G Knepley #error "HDF5 output with 128 bit floats not supported."
34615214e8eSMatthew G Knepley #else
34715214e8eSMatthew G Knepley   scalartype = H5T_NATIVE_DOUBLE;
34815214e8eSMatthew G Knepley #endif
34915214e8eSMatthew G Knepley 
35047c6ae99SBarry Smith   /* Create the dataset with default properties and close filespace */
35147c6ae99SBarry Smith   ierr = PetscObjectGetName((PetscObject)xin,&vecname);CHKERRQ(ierr);
35215214e8eSMatthew G Knepley   if (!H5Lexists(group, vecname, H5P_DEFAULT)) {
3538e2ae6d7SMichael Kraus     /* Create chunk */
3548e2ae6d7SMichael Kraus     chunkspace = H5Pcreate(H5P_DATASET_CREATE);
3558e2ae6d7SMichael Kraus     if (chunkspace == -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Cannot H5Pcreate()");
3568e2ae6d7SMichael Kraus     status = H5Pset_chunk(chunkspace, dim, chunkDims); CHKERRQ(status);
3578e2ae6d7SMichael Kraus 
35847c6ae99SBarry Smith #if (H5_VERS_MAJOR * 10000 + H5_VERS_MINOR * 100 + H5_VERS_RELEASE >= 10800)
3598e2ae6d7SMichael Kraus     dset_id = H5Dcreate2(group, vecname, scalartype, filespace, H5P_DEFAULT, chunkspace, H5P_DEFAULT);
36047c6ae99SBarry Smith #else
36115214e8eSMatthew G Knepley     dset_id = H5Dcreate(group, vecname, scalartype, filespace, H5P_DEFAULT);
36247c6ae99SBarry Smith #endif
36347c6ae99SBarry Smith     if (dset_id == -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Cannot H5Dcreate2()");
36415214e8eSMatthew G Knepley   } else {
36515214e8eSMatthew G Knepley     dset_id = H5Dopen2(group, vecname, H5P_DEFAULT);
36615214e8eSMatthew G Knepley     status = H5Dset_extent(dset_id, dims);CHKERRQ(status);
36715214e8eSMatthew G Knepley   }
36847c6ae99SBarry Smith   status = H5Sclose(filespace);CHKERRQ(status);
36947c6ae99SBarry Smith 
37047c6ae99SBarry Smith   /* Each process defines a dataset and writes it to the hyperslab in the file */
3718e2ae6d7SMichael Kraus   dim = 0;
3728e2ae6d7SMichael Kraus   if (timestep >= 0) {
3738e2ae6d7SMichael Kraus     offset[dim] = timestep;
3748e2ae6d7SMichael Kraus     ++dim;
3758e2ae6d7SMichael Kraus   }
3768e2ae6d7SMichael Kraus   if (da->dim == 3) offset[dim++] = PetscHDF5IntCast(da->zs);
3778e2ae6d7SMichael Kraus   if (da->dim > 1)  offset[dim++] = PetscHDF5IntCast(da->ys);
3788e2ae6d7SMichael Kraus   offset[dim++] = PetscHDF5IntCast(da->xs/da->w);
3798e2ae6d7SMichael Kraus   if (da->w > 1) offset[dim++] = 0;
38047c6ae99SBarry Smith #if defined(PETSC_USE_COMPLEX)
3818e2ae6d7SMichael Kraus   offset[dim++] = 0;
38247c6ae99SBarry Smith #endif
3838e2ae6d7SMichael Kraus   dim = 0;
3848e2ae6d7SMichael Kraus   if (timestep >= 0) {
3858e2ae6d7SMichael Kraus     count[dim] = 1;
3868e2ae6d7SMichael Kraus     ++dim;
3878e2ae6d7SMichael Kraus   }
3888e2ae6d7SMichael Kraus   if (da->dim == 3) count[dim++] = PetscHDF5IntCast(da->ze - da->zs);
3898e2ae6d7SMichael Kraus   if (da->dim > 1)  count[dim++] = PetscHDF5IntCast(da->ye - da->ys);
3908e2ae6d7SMichael Kraus   count[dim++] = PetscHDF5IntCast((da->xe - da->xs)/da->w);
3918e2ae6d7SMichael Kraus   if (da->w > 1) count[dim++] = PetscHDF5IntCast(da->w);
39247c6ae99SBarry Smith #if defined(PETSC_USE_COMPLEX)
3938e2ae6d7SMichael Kraus   count[dim++] = 2;
39447c6ae99SBarry Smith #endif
39547c6ae99SBarry Smith   memspace = H5Screate_simple(dim, count, NULL);
39647c6ae99SBarry Smith   if (memspace == -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Cannot H5Screate_simple()");
39747c6ae99SBarry Smith 
39847c6ae99SBarry Smith   filespace = H5Dget_space(dset_id);
39947c6ae99SBarry Smith   if (filespace == -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Cannot H5Dget_space()");
40047c6ae99SBarry Smith   status = H5Sselect_hyperslab(filespace, H5S_SELECT_SET, offset, NULL, count, NULL);CHKERRQ(status);
40147c6ae99SBarry Smith 
40247c6ae99SBarry Smith   /* Create property list for collective dataset write */
40347c6ae99SBarry Smith   plist_id = H5Pcreate(H5P_DATASET_XFER);
40447c6ae99SBarry Smith   if (plist_id == -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Cannot H5Pcreate()");
40547c6ae99SBarry Smith #if defined(PETSC_HAVE_H5PSET_FAPL_MPIO)
40647c6ae99SBarry Smith   status = H5Pset_dxpl_mpio(plist_id, H5FD_MPIO_COLLECTIVE);CHKERRQ(status);
40747c6ae99SBarry Smith #endif
40847c6ae99SBarry Smith   /* To write dataset independently use H5Pset_dxpl_mpio(plist_id, H5FD_MPIO_INDEPENDENT) */
40947c6ae99SBarry Smith 
41047c6ae99SBarry Smith   ierr = VecGetArray(xin, &x);CHKERRQ(ierr);
41115214e8eSMatthew G Knepley   status = H5Dwrite(dset_id, scalartype, memspace, filespace, plist_id, x);CHKERRQ(status);
41247c6ae99SBarry Smith   status = H5Fflush(file_id, H5F_SCOPE_GLOBAL);CHKERRQ(status);
41347c6ae99SBarry Smith   ierr = VecRestoreArray(xin, &x);CHKERRQ(ierr);
41447c6ae99SBarry Smith 
41547c6ae99SBarry Smith   /* Close/release resources */
41615214e8eSMatthew G Knepley   if (group != file_id) {
41715214e8eSMatthew G Knepley     status = H5Gclose(group);CHKERRQ(status);
41815214e8eSMatthew G Knepley   }
41947c6ae99SBarry Smith   status = H5Pclose(plist_id);CHKERRQ(status);
42047c6ae99SBarry Smith   status = H5Sclose(filespace);CHKERRQ(status);
42147c6ae99SBarry Smith   status = H5Sclose(memspace);CHKERRQ(status);
42247c6ae99SBarry Smith   status = H5Dclose(dset_id);CHKERRQ(status);
42347c6ae99SBarry Smith   ierr = PetscInfo1(xin,"Wrote Vec object with name %s\n",vecname);CHKERRQ(ierr);
42447c6ae99SBarry Smith   PetscFunctionReturn(0);
42547c6ae99SBarry Smith }
42647c6ae99SBarry Smith #endif
42747c6ae99SBarry Smith 
42809573ac7SBarry Smith extern PetscErrorCode VecView_MPI_Draw_DA1d(Vec,PetscViewer);
42947c6ae99SBarry Smith 
43047c6ae99SBarry Smith #if defined(PETSC_HAVE_MPIIO)
43147c6ae99SBarry Smith #undef __FUNCT__
432aa219208SBarry Smith #define __FUNCT__ "DMDAArrayMPIIO"
433aa219208SBarry Smith static PetscErrorCode DMDAArrayMPIIO(DM da,PetscViewer viewer,Vec xin,PetscBool  write)
43447c6ae99SBarry Smith {
43547c6ae99SBarry Smith   PetscErrorCode    ierr;
43647c6ae99SBarry Smith   MPI_File          mfdes;
43747c6ae99SBarry Smith   PetscMPIInt       gsizes[4],lsizes[4],lstarts[4],asiz,dof;
43847c6ae99SBarry Smith   MPI_Datatype      view;
43947c6ae99SBarry Smith   const PetscScalar *array;
44047c6ae99SBarry Smith   MPI_Offset        off;
44147c6ae99SBarry Smith   MPI_Aint          ub,ul;
44247c6ae99SBarry Smith   PetscInt          type,rows,vecrows,tr[2];
44347c6ae99SBarry Smith   DM_DA             *dd = (DM_DA*)da->data;
44447c6ae99SBarry Smith 
44547c6ae99SBarry Smith   PetscFunctionBegin;
44647c6ae99SBarry Smith   ierr = VecGetSize(xin,&vecrows);CHKERRQ(ierr);
44747c6ae99SBarry Smith   if (!write) {
44847c6ae99SBarry Smith     /* Read vector header. */
44947c6ae99SBarry Smith     ierr = PetscViewerBinaryRead(viewer,tr,2,PETSC_INT);CHKERRQ(ierr);
45047c6ae99SBarry Smith     type = tr[0];
45147c6ae99SBarry Smith     rows = tr[1];
45247c6ae99SBarry Smith     if (type != VEC_FILE_CLASSID) SETERRQ(((PetscObject)da)->comm,PETSC_ERR_ARG_WRONG,"Not vector next in file");
453aa219208SBarry Smith     if (rows != vecrows) SETERRQ(((PetscObject)da)->comm,PETSC_ERR_ARG_SIZ,"Vector in file not same size as DMDA vector");
45447c6ae99SBarry Smith   } else {
45547c6ae99SBarry Smith     tr[0] = VEC_FILE_CLASSID;
45647c6ae99SBarry Smith     tr[1] = vecrows;
45747c6ae99SBarry Smith     ierr = PetscViewerBinaryWrite(viewer,tr,2,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr);
45847c6ae99SBarry Smith   }
45947c6ae99SBarry Smith 
46047c6ae99SBarry Smith   dof = PetscMPIIntCast(dd->w);
46147c6ae99SBarry Smith   gsizes[0]  = dof; gsizes[1] = PetscMPIIntCast(dd->M); gsizes[2] = PetscMPIIntCast(dd->N); gsizes[3] = PetscMPIIntCast(dd->P);
46247c6ae99SBarry Smith   lsizes[0]  = dof;lsizes[1] = PetscMPIIntCast((dd->xe-dd->xs)/dof); lsizes[2] = PetscMPIIntCast(dd->ye-dd->ys); lsizes[3] = PetscMPIIntCast(dd->ze-dd->zs);
46347c6ae99SBarry Smith   lstarts[0] = 0;  lstarts[1] = PetscMPIIntCast(dd->xs/dof); lstarts[2] = PetscMPIIntCast(dd->ys); lstarts[3] = PetscMPIIntCast(dd->zs);
46447c6ae99SBarry Smith   ierr = MPI_Type_create_subarray(dd->dim+1,gsizes,lsizes,lstarts,MPI_ORDER_FORTRAN,MPIU_SCALAR,&view);CHKERRQ(ierr);
46547c6ae99SBarry Smith   ierr = MPI_Type_commit(&view);CHKERRQ(ierr);
46647c6ae99SBarry Smith 
46747c6ae99SBarry Smith   ierr = PetscViewerBinaryGetMPIIODescriptor(viewer,&mfdes);CHKERRQ(ierr);
46847c6ae99SBarry Smith   ierr = PetscViewerBinaryGetMPIIOOffset(viewer,&off);CHKERRQ(ierr);
46947c6ae99SBarry Smith   ierr = MPI_File_set_view(mfdes,off,MPIU_SCALAR,view,(char *)"native",MPI_INFO_NULL);CHKERRQ(ierr);
47047c6ae99SBarry Smith   ierr = VecGetArrayRead(xin,&array);CHKERRQ(ierr);
47147c6ae99SBarry Smith   asiz = lsizes[1]*(lsizes[2] > 0 ? lsizes[2] : 1)*(lsizes[3] > 0 ? lsizes[3] : 1)*dof;
47247c6ae99SBarry Smith   if (write) {
47347c6ae99SBarry Smith     ierr = MPIU_File_write_all(mfdes,(PetscScalar*)array,asiz,MPIU_SCALAR,MPI_STATUS_IGNORE);CHKERRQ(ierr);
47447c6ae99SBarry Smith   } else {
47547c6ae99SBarry Smith     ierr = MPIU_File_read_all(mfdes,(PetscScalar*)array,asiz,MPIU_SCALAR,MPI_STATUS_IGNORE);CHKERRQ(ierr);
47647c6ae99SBarry Smith   }
47747c6ae99SBarry Smith   ierr = MPI_Type_get_extent(view,&ul,&ub);CHKERRQ(ierr);
47847c6ae99SBarry Smith   ierr = PetscViewerBinaryAddMPIIOOffset(viewer,ub);CHKERRQ(ierr);
47947c6ae99SBarry Smith   ierr = VecRestoreArrayRead(xin,&array);CHKERRQ(ierr);
48047c6ae99SBarry Smith   ierr = MPI_Type_free(&view);CHKERRQ(ierr);
48147c6ae99SBarry Smith   PetscFunctionReturn(0);
48247c6ae99SBarry Smith }
48347c6ae99SBarry Smith #endif
48447c6ae99SBarry Smith 
48547c6ae99SBarry Smith EXTERN_C_BEGIN
48647c6ae99SBarry Smith #undef __FUNCT__
48747c6ae99SBarry Smith #define __FUNCT__ "VecView_MPI_DA"
4887087cfbeSBarry Smith PetscErrorCode  VecView_MPI_DA(Vec xin,PetscViewer viewer)
48947c6ae99SBarry Smith {
4909a42bb27SBarry Smith   DM             da;
49147c6ae99SBarry Smith   PetscErrorCode ierr;
49247c6ae99SBarry Smith   PetscInt       dim;
49347c6ae99SBarry Smith   Vec            natural;
4944061b8bfSJed Brown   PetscBool      isdraw,isvtk;
49547c6ae99SBarry Smith #if defined(PETSC_HAVE_HDF5)
49647c6ae99SBarry Smith   PetscBool      ishdf5;
49747c6ae99SBarry Smith #endif
4983f3fd955SJed Brown   const char     *prefix,*name;
49947c6ae99SBarry Smith 
50047c6ae99SBarry Smith   PetscFunctionBegin;
501c688c046SMatthew G Knepley   ierr = VecGetDM(xin,&da);CHKERRQ(ierr);
502aa219208SBarry Smith   if (!da) SETERRQ(((PetscObject)xin)->comm,PETSC_ERR_ARG_WRONG,"Vector not generated from a DMDA");
503251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
504251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERVTK,&isvtk);CHKERRQ(ierr);
50547c6ae99SBarry Smith #if defined(PETSC_HAVE_HDF5)
506251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,&ishdf5);CHKERRQ(ierr);
50747c6ae99SBarry Smith #endif
50847c6ae99SBarry Smith   if (isdraw) {
5091321219cSEthan Coon     ierr = DMDAGetInfo(da,&dim,0,0,0,0,0,0,0,0,0,0,0,0);CHKERRQ(ierr);
51047c6ae99SBarry Smith     if (dim == 1) {
51147c6ae99SBarry Smith       ierr = VecView_MPI_Draw_DA1d(xin,viewer);CHKERRQ(ierr);
51247c6ae99SBarry Smith     } else if (dim == 2) {
51347c6ae99SBarry Smith       ierr = VecView_MPI_Draw_DA2d(xin,viewer);CHKERRQ(ierr);
51447c6ae99SBarry Smith     } else {
515aa219208SBarry Smith       SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Cannot graphically view vector associated with this dimensional DMDA %D",dim);
51647c6ae99SBarry Smith     }
5174061b8bfSJed Brown   } else if (isvtk) {           /* Duplicate the Vec and hold a reference to the DM */
5184061b8bfSJed Brown     Vec Y;
5194061b8bfSJed Brown     ierr = PetscObjectReference((PetscObject)da);CHKERRQ(ierr);
5204061b8bfSJed Brown     ierr = VecDuplicate(xin,&Y);CHKERRQ(ierr);
521b51b94faSJed Brown     if (((PetscObject)xin)->name) {
522b51b94faSJed Brown       /* If xin was named, copy the name over to Y. The duplicate names are safe because nobody else will ever see Y. */
523b51b94faSJed Brown       ierr = PetscObjectSetName((PetscObject)Y,((PetscObject)xin)->name);CHKERRQ(ierr);
524b51b94faSJed Brown     }
5254061b8bfSJed Brown     ierr = VecCopy(xin,Y);CHKERRQ(ierr);
52662b69a3fSMatthew G Knepley     ierr = PetscViewerVTKAddField(viewer,(PetscObject)da,DMDAVTKWriteAll,PETSC_VTK_POINT_FIELD,(PetscObject)Y);CHKERRQ(ierr);
52747c6ae99SBarry Smith #if defined(PETSC_HAVE_HDF5)
52847c6ae99SBarry Smith   } else if (ishdf5) {
52947c6ae99SBarry Smith     ierr = VecView_MPI_HDF5_DA(xin,viewer);CHKERRQ(ierr);
53047c6ae99SBarry Smith #endif
53147c6ae99SBarry Smith   } else {
53247c6ae99SBarry Smith #if defined(PETSC_HAVE_MPIIO)
53347c6ae99SBarry Smith     PetscBool  isbinary,isMPIIO;
53447c6ae99SBarry Smith 
535251f4c67SDmitry Karpeev     ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
53647c6ae99SBarry Smith     if (isbinary) {
53747c6ae99SBarry Smith       ierr = PetscViewerBinaryGetMPIIO(viewer,&isMPIIO);CHKERRQ(ierr);
53847c6ae99SBarry Smith       if (isMPIIO) {
539aa219208SBarry Smith        ierr = DMDAArrayMPIIO(da,viewer,xin,PETSC_TRUE);CHKERRQ(ierr);
54047c6ae99SBarry Smith        PetscFunctionReturn(0);
54147c6ae99SBarry Smith       }
54247c6ae99SBarry Smith     }
54347c6ae99SBarry Smith #endif
54447c6ae99SBarry Smith 
54547c6ae99SBarry Smith     /* call viewer on natural ordering */
54647c6ae99SBarry Smith     ierr = PetscObjectGetOptionsPrefix((PetscObject)xin,&prefix);CHKERRQ(ierr);
547aa219208SBarry Smith     ierr = DMDACreateNaturalVector(da,&natural);CHKERRQ(ierr);
54847c6ae99SBarry Smith     ierr = PetscObjectSetOptionsPrefix((PetscObject)natural,prefix);CHKERRQ(ierr);
549aa219208SBarry Smith     ierr = DMDAGlobalToNaturalBegin(da,xin,INSERT_VALUES,natural);CHKERRQ(ierr);
550aa219208SBarry Smith     ierr = DMDAGlobalToNaturalEnd(da,xin,INSERT_VALUES,natural);CHKERRQ(ierr);
5513f3fd955SJed Brown     ierr = PetscObjectGetName((PetscObject)xin,&name);CHKERRQ(ierr);
5523f3fd955SJed Brown     ierr = PetscObjectSetName((PetscObject)natural,name);CHKERRQ(ierr);
55347c6ae99SBarry Smith     ierr = VecView(natural,viewer);CHKERRQ(ierr);
554fcfd50ebSBarry Smith     ierr = VecDestroy(&natural);CHKERRQ(ierr);
55547c6ae99SBarry Smith   }
55647c6ae99SBarry Smith   PetscFunctionReturn(0);
55747c6ae99SBarry Smith }
55847c6ae99SBarry Smith EXTERN_C_END
55947c6ae99SBarry Smith 
56047c6ae99SBarry Smith #if defined(PETSC_HAVE_HDF5)
56147c6ae99SBarry Smith #undef __FUNCT__
56247c6ae99SBarry Smith #define __FUNCT__ "VecLoad_HDF5_DA"
56347c6ae99SBarry Smith PetscErrorCode VecLoad_HDF5_DA(Vec xin, PetscViewer viewer)
56447c6ae99SBarry Smith {
5659a42bb27SBarry Smith   DM             da;
56647c6ae99SBarry Smith   PetscErrorCode ierr;
56725578ef6SJed Brown   hsize_t        dim;
56847c6ae99SBarry Smith   hsize_t        count[5];
56947c6ae99SBarry Smith   hsize_t        offset[5];
57047c6ae99SBarry Smith   PetscInt       cnt = 0;
57147c6ae99SBarry Smith   PetscScalar    *x;
57247c6ae99SBarry Smith   const char     *vecname;
57347c6ae99SBarry Smith   hid_t          filespace; /* file dataspace identifier */
57447c6ae99SBarry Smith   hid_t	         plist_id;  /* property list identifier */
57547c6ae99SBarry Smith   hid_t          dset_id;   /* dataset identifier */
57647c6ae99SBarry Smith   hid_t          memspace;  /* memory dataspace identifier */
57747c6ae99SBarry Smith   hid_t          file_id;
57847c6ae99SBarry Smith   herr_t         status;
5799c7c4993SBarry Smith   DM_DA          *dd;
58047c6ae99SBarry Smith 
58147c6ae99SBarry Smith   PetscFunctionBegin;
58247c6ae99SBarry Smith   ierr = PetscViewerHDF5GetFileId(viewer, &file_id);CHKERRQ(ierr);
583c688c046SMatthew G Knepley   ierr = VecGetDM(xin,&da);CHKERRQ(ierr);
5849c7c4993SBarry Smith   dd = (DM_DA*)da->data;
58547c6ae99SBarry Smith 
58647c6ae99SBarry Smith   /* Create the dataspace for the dataset */
58747c6ae99SBarry Smith   dim       = PetscHDF5IntCast(dd->dim + ((dd->w == 1) ? 0 : 1));
58847c6ae99SBarry Smith #if defined(PETSC_USE_COMPLEX)
58947c6ae99SBarry Smith   dim++;
59047c6ae99SBarry Smith #endif
59147c6ae99SBarry Smith 
59247c6ae99SBarry Smith   /* Create the dataset with default properties and close filespace */
59347c6ae99SBarry Smith   ierr = PetscObjectGetName((PetscObject)xin,&vecname);CHKERRQ(ierr);
59447c6ae99SBarry Smith #if (H5_VERS_MAJOR * 10000 + H5_VERS_MINOR * 100 + H5_VERS_RELEASE >= 10800)
59547c6ae99SBarry Smith   dset_id = H5Dopen2(file_id, vecname, H5P_DEFAULT);
59647c6ae99SBarry Smith #else
59747c6ae99SBarry Smith   dset_id = H5Dopen(file_id, vecname);
59847c6ae99SBarry Smith #endif
59947c6ae99SBarry Smith   if (dset_id == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Cannot H5Dopen2() with Vec named %s",vecname);
60047c6ae99SBarry Smith   filespace = H5Dget_space(dset_id);
60147c6ae99SBarry Smith 
60247c6ae99SBarry Smith   /* Each process defines a dataset and reads it from the hyperslab in the file */
60347c6ae99SBarry Smith   cnt = 0;
60447c6ae99SBarry Smith   if (dd->dim == 3) offset[cnt++] = PetscHDF5IntCast(dd->zs);
60547c6ae99SBarry Smith   if (dd->dim > 1)  offset[cnt++] = PetscHDF5IntCast(dd->ys);
60647c6ae99SBarry Smith   offset[cnt++] = PetscHDF5IntCast(dd->xs/dd->w);
60747c6ae99SBarry Smith   if (dd->w > 1) offset[cnt++] = 0;
60847c6ae99SBarry Smith #if defined(PETSC_USE_COMPLEX)
60947c6ae99SBarry Smith   offset[cnt++] = 0;
61047c6ae99SBarry Smith #endif
61147c6ae99SBarry Smith   cnt = 0;
61247c6ae99SBarry Smith   if (dd->dim == 3) count[cnt++] = PetscHDF5IntCast(dd->ze - dd->zs);
61347c6ae99SBarry Smith   if (dd->dim > 1)  count[cnt++] = PetscHDF5IntCast(dd->ye - dd->ys);
61447c6ae99SBarry Smith   count[cnt++] = PetscHDF5IntCast((dd->xe - dd->xs)/dd->w);
61547c6ae99SBarry Smith   if (dd->w > 1) count[cnt++] = PetscHDF5IntCast(dd->w);
61647c6ae99SBarry Smith #if defined(PETSC_USE_COMPLEX)
61747c6ae99SBarry Smith   count[cnt++] = 2;
61847c6ae99SBarry Smith #endif
61947c6ae99SBarry Smith   memspace = H5Screate_simple(dim, count, NULL);
62047c6ae99SBarry Smith   if (memspace == -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Cannot H5Screate_simple()");
62147c6ae99SBarry Smith 
62247c6ae99SBarry Smith   status = H5Sselect_hyperslab(filespace, H5S_SELECT_SET, offset, NULL, count, NULL);CHKERRQ(status);
62347c6ae99SBarry Smith 
62447c6ae99SBarry Smith   /* Create property list for collective dataset write */
62547c6ae99SBarry Smith   plist_id = H5Pcreate(H5P_DATASET_XFER);
62647c6ae99SBarry Smith   if (plist_id == -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Cannot H5Pcreate()");
62747c6ae99SBarry Smith #if defined(PETSC_HAVE_H5PSET_FAPL_MPIO)
62847c6ae99SBarry Smith   status = H5Pset_dxpl_mpio(plist_id, H5FD_MPIO_COLLECTIVE);CHKERRQ(status);
62947c6ae99SBarry Smith #endif
63047c6ae99SBarry Smith   /* To write dataset independently use H5Pset_dxpl_mpio(plist_id, H5FD_MPIO_INDEPENDENT) */
63147c6ae99SBarry Smith 
63247c6ae99SBarry Smith   ierr = VecGetArray(xin, &x);CHKERRQ(ierr);
63347c6ae99SBarry Smith   status = H5Dread(dset_id, H5T_NATIVE_DOUBLE, memspace, filespace, plist_id, x);CHKERRQ(status);
63447c6ae99SBarry Smith   ierr = VecRestoreArray(xin, &x);CHKERRQ(ierr);
63547c6ae99SBarry Smith 
63647c6ae99SBarry Smith   /* Close/release resources */
63747c6ae99SBarry Smith   status = H5Pclose(plist_id);CHKERRQ(status);
63847c6ae99SBarry Smith   status = H5Sclose(filespace);CHKERRQ(status);
63947c6ae99SBarry Smith   status = H5Sclose(memspace);CHKERRQ(status);
64047c6ae99SBarry Smith   status = H5Dclose(dset_id);CHKERRQ(status);
64147c6ae99SBarry Smith   PetscFunctionReturn(0);
64247c6ae99SBarry Smith }
64347c6ae99SBarry Smith #endif
64447c6ae99SBarry Smith 
64547c6ae99SBarry Smith #undef __FUNCT__
64647c6ae99SBarry Smith #define __FUNCT__ "VecLoad_Binary_DA"
64747c6ae99SBarry Smith PetscErrorCode VecLoad_Binary_DA(Vec xin, PetscViewer viewer)
64847c6ae99SBarry Smith {
6499a42bb27SBarry Smith   DM             da;
65047c6ae99SBarry Smith   PetscErrorCode ierr;
65147c6ae99SBarry Smith   Vec            natural;
65247c6ae99SBarry Smith   const char     *prefix;
65347c6ae99SBarry Smith   PetscInt       bs;
65447c6ae99SBarry Smith   PetscBool      flag;
65547c6ae99SBarry Smith   DM_DA          *dd;
65647c6ae99SBarry Smith #if defined(PETSC_HAVE_MPIIO)
65747c6ae99SBarry Smith   PetscBool      isMPIIO;
65847c6ae99SBarry Smith #endif
65947c6ae99SBarry Smith 
66047c6ae99SBarry Smith   PetscFunctionBegin;
661c688c046SMatthew G Knepley   ierr = VecGetDM(xin,&da);CHKERRQ(ierr);
66247c6ae99SBarry Smith   dd   = (DM_DA*)da->data;
66347c6ae99SBarry Smith #if defined(PETSC_HAVE_MPIIO)
66447c6ae99SBarry Smith   ierr = PetscViewerBinaryGetMPIIO(viewer,&isMPIIO);CHKERRQ(ierr);
66547c6ae99SBarry Smith   if (isMPIIO) {
666aa219208SBarry Smith     ierr = DMDAArrayMPIIO(da,viewer,xin,PETSC_FALSE);CHKERRQ(ierr);
66747c6ae99SBarry Smith     PetscFunctionReturn(0);
66847c6ae99SBarry Smith   }
66947c6ae99SBarry Smith #endif
67047c6ae99SBarry Smith 
67147c6ae99SBarry Smith   ierr = PetscObjectGetOptionsPrefix((PetscObject)xin,&prefix);CHKERRQ(ierr);
672aa219208SBarry Smith   ierr = DMDACreateNaturalVector(da,&natural);CHKERRQ(ierr);
67347c6ae99SBarry Smith   ierr = PetscObjectSetName((PetscObject)natural,((PetscObject)xin)->name);CHKERRQ(ierr);
67447c6ae99SBarry Smith   ierr = PetscObjectSetOptionsPrefix((PetscObject)natural,prefix);CHKERRQ(ierr);
67547c6ae99SBarry Smith   ierr = VecLoad_Binary(natural,viewer);CHKERRQ(ierr);
676aa219208SBarry Smith   ierr = DMDANaturalToGlobalBegin(da,natural,INSERT_VALUES,xin);CHKERRQ(ierr);
677aa219208SBarry Smith   ierr = DMDANaturalToGlobalEnd(da,natural,INSERT_VALUES,xin);CHKERRQ(ierr);
678fcfd50ebSBarry Smith   ierr = VecDestroy(&natural);CHKERRQ(ierr);
679aa219208SBarry Smith   ierr = PetscInfo(xin,"Loading vector from natural ordering into DMDA\n");CHKERRQ(ierr);
68047c6ae99SBarry Smith   ierr = PetscOptionsGetInt(((PetscObject)xin)->prefix,"-vecload_block_size",&bs,&flag);CHKERRQ(ierr);
68147c6ae99SBarry Smith   if (flag && bs != dd->w) {
682aa219208SBarry Smith     ierr = PetscInfo2(xin,"Block size in file %D not equal to DMDA's dof %D\n",bs,dd->w);CHKERRQ(ierr);
68347c6ae99SBarry Smith   }
68447c6ae99SBarry Smith   PetscFunctionReturn(0);
68547c6ae99SBarry Smith }
68647c6ae99SBarry Smith 
68747c6ae99SBarry Smith EXTERN_C_BEGIN
68847c6ae99SBarry Smith #undef __FUNCT__
68947c6ae99SBarry Smith #define __FUNCT__ "VecLoad_Default_DA"
6907087cfbeSBarry Smith PetscErrorCode  VecLoad_Default_DA(Vec xin, PetscViewer viewer)
69147c6ae99SBarry Smith {
69247c6ae99SBarry Smith   PetscErrorCode ierr;
6939a42bb27SBarry Smith   DM             da;
69447c6ae99SBarry Smith   PetscBool      isbinary;
69547c6ae99SBarry Smith #if defined(PETSC_HAVE_HDF5)
69647c6ae99SBarry Smith   PetscBool      ishdf5;
69747c6ae99SBarry Smith #endif
69847c6ae99SBarry Smith 
69947c6ae99SBarry Smith   PetscFunctionBegin;
700c688c046SMatthew G Knepley   ierr = VecGetDM(xin,&da);CHKERRQ(ierr);
701aa219208SBarry Smith   if (!da) SETERRQ(((PetscObject)xin)->comm,PETSC_ERR_ARG_WRONG,"Vector not generated from a DMDA");
70247c6ae99SBarry Smith 
70347c6ae99SBarry Smith #if defined(PETSC_HAVE_HDF5)
704251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,&ishdf5);CHKERRQ(ierr);
70547c6ae99SBarry Smith #endif
706251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
70747c6ae99SBarry Smith 
70847c6ae99SBarry Smith   if (isbinary) {
70947c6ae99SBarry Smith     ierr = VecLoad_Binary_DA(xin,viewer);CHKERRQ(ierr);
71047c6ae99SBarry Smith #if defined(PETSC_HAVE_HDF5)
71147c6ae99SBarry Smith   } else if (ishdf5) {
71247c6ae99SBarry Smith     ierr = VecLoad_HDF5_DA(xin,viewer);CHKERRQ(ierr);
71347c6ae99SBarry Smith #endif
714d34fcf5fSBarry Smith   } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Viewer type %s not supported for vector loading", ((PetscObject)viewer)->type_name);
71547c6ae99SBarry Smith   PetscFunctionReturn(0);
71647c6ae99SBarry Smith }
71747c6ae99SBarry Smith EXTERN_C_END
718