1 2 /* 3 Plots vectors obtained with DMDACreate2d() 4 */ 5 6 #include <petsc/private/dmdaimpl.h> /*I "petscdmda.h" I*/ 7 #include <petsc/private/glvisvecimpl.h> 8 #include <petsc/private/viewerhdf5impl.h> 9 #include <petscdraw.h> 10 11 /* 12 The data that is passed into the graphics callback 13 */ 14 typedef struct { 15 PetscMPIInt rank; 16 PetscInt m,n,dof,k; 17 PetscReal xmin,xmax,ymin,ymax,min,max; 18 const PetscScalar *xy,*v; 19 PetscBool showaxis,showgrid; 20 const char *name0,*name1; 21 } ZoomCtx; 22 23 /* 24 This does the drawing for one particular field 25 in one particular set of coordinates. It is a callback 26 called from PetscDrawZoom() 27 */ 28 PetscErrorCode VecView_MPI_Draw_DA2d_Zoom(PetscDraw draw,void *ctx) 29 { 30 ZoomCtx *zctx = (ZoomCtx*)ctx; 31 PetscInt m,n,i,j,k,dof,id,c1,c2,c3,c4; 32 PetscReal min,max,x1,x2,x3,x4,y_1,y2,y3,y4; 33 const PetscScalar *xy,*v; 34 PetscErrorCode ierr; 35 36 PetscFunctionBegin; 37 m = zctx->m; 38 n = zctx->n; 39 dof = zctx->dof; 40 k = zctx->k; 41 xy = zctx->xy; 42 v = zctx->v; 43 min = zctx->min; 44 max = zctx->max; 45 46 /* PetscDraw the contour plot patch */ 47 ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 48 for (j=0; j<n-1; j++) { 49 for (i=0; i<m-1; i++) { 50 id = i+j*m; 51 x1 = PetscRealPart(xy[2*id]); 52 y_1 = PetscRealPart(xy[2*id+1]); 53 c1 = PetscDrawRealToColor(PetscRealPart(v[k+dof*id]),min,max); 54 55 id = i+j*m+1; 56 x2 = PetscRealPart(xy[2*id]); 57 y2 = PetscRealPart(xy[2*id+1]); 58 c2 = PetscDrawRealToColor(PetscRealPart(v[k+dof*id]),min,max); 59 60 id = i+j*m+1+m; 61 x3 = PetscRealPart(xy[2*id]); 62 y3 = PetscRealPart(xy[2*id+1]); 63 c3 = PetscDrawRealToColor(PetscRealPart(v[k+dof*id]),min,max); 64 65 id = i+j*m+m; 66 x4 = PetscRealPart(xy[2*id]); 67 y4 = PetscRealPart(xy[2*id+1]); 68 c4 = PetscDrawRealToColor(PetscRealPart(v[k+dof*id]),min,max); 69 70 CHKERRQ(PetscDrawTriangle(draw,x1,y_1,x2,y2,x3,y3,c1,c2,c3)); 71 CHKERRQ(PetscDrawTriangle(draw,x1,y_1,x3,y3,x4,y4,c1,c3,c4)); 72 if (zctx->showgrid) { 73 CHKERRQ(PetscDrawLine(draw,x1,y_1,x2,y2,PETSC_DRAW_BLACK)); 74 CHKERRQ(PetscDrawLine(draw,x2,y2,x3,y3,PETSC_DRAW_BLACK)); 75 CHKERRQ(PetscDrawLine(draw,x3,y3,x4,y4,PETSC_DRAW_BLACK)); 76 CHKERRQ(PetscDrawLine(draw,x4,y4,x1,y_1,PETSC_DRAW_BLACK)); 77 } 78 } 79 } 80 if (zctx->showaxis && !zctx->rank) { 81 if (zctx->name0 || zctx->name1) { 82 PetscReal xl,yl,xr,yr,x,y; 83 CHKERRQ(PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr)); 84 x = xl + .30*(xr - xl); 85 xl = xl + .01*(xr - xl); 86 y = yr - .30*(yr - yl); 87 yl = yl + .01*(yr - yl); 88 if (zctx->name0) CHKERRQ(PetscDrawString(draw,x,yl,PETSC_DRAW_BLACK,zctx->name0)); 89 if (zctx->name1) CHKERRQ(PetscDrawStringVertical(draw,xl,y,PETSC_DRAW_BLACK,zctx->name1)); 90 } 91 /* 92 Ideally we would use the PetscDrawAxis object to manage displaying the coordinate limits 93 but that may require some refactoring. 94 */ 95 { 96 double xmin = (double)zctx->xmin, ymin = (double)zctx->ymin; 97 double xmax = (double)zctx->xmax, ymax = (double)zctx->ymax; 98 char value[16]; size_t len; PetscReal w; 99 CHKERRQ(PetscSNPrintf(value,16,"%0.2e",xmin)); 100 CHKERRQ(PetscDrawString(draw,xmin,ymin - .05*(ymax - ymin),PETSC_DRAW_BLACK,value)); 101 CHKERRQ(PetscSNPrintf(value,16,"%0.2e",xmax)); 102 CHKERRQ(PetscStrlen(value,&len)); 103 CHKERRQ(PetscDrawStringGetSize(draw,&w,NULL)); 104 CHKERRQ(PetscDrawString(draw,xmax - len*w,ymin - .05*(ymax - ymin),PETSC_DRAW_BLACK,value)); 105 CHKERRQ(PetscSNPrintf(value,16,"%0.2e",ymin)); 106 CHKERRQ(PetscDrawString(draw,xmin - .05*(xmax - xmin),ymin,PETSC_DRAW_BLACK,value)); 107 CHKERRQ(PetscSNPrintf(value,16,"%0.2e",ymax)); 108 CHKERRQ(PetscDrawString(draw,xmin - .05*(xmax - xmin),ymax,PETSC_DRAW_BLACK,value)); 109 } 110 } 111 ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 112 PetscFunctionReturn(0); 113 } 114 115 PetscErrorCode VecView_MPI_Draw_DA2d(Vec xin,PetscViewer viewer) 116 { 117 DM da,dac,dag; 118 PetscInt N,s,M,w,ncoors = 4; 119 const PetscInt *lx,*ly; 120 PetscReal coors[4]; 121 PetscDraw draw,popup; 122 PetscBool isnull,useports = PETSC_FALSE; 123 MPI_Comm comm; 124 Vec xlocal,xcoor,xcoorl; 125 DMBoundaryType bx,by; 126 DMDAStencilType st; 127 ZoomCtx zctx; 128 PetscDrawViewPorts *ports = NULL; 129 PetscViewerFormat format; 130 PetscInt *displayfields; 131 PetscInt ndisplayfields,i,nbounds; 132 const PetscReal *bounds; 133 134 PetscFunctionBegin; 135 zctx.showgrid = PETSC_FALSE; 136 zctx.showaxis = PETSC_TRUE; 137 138 CHKERRQ(PetscViewerDrawGetDraw(viewer,0,&draw)); 139 CHKERRQ(PetscDrawIsNull(draw,&isnull)); 140 if (isnull) PetscFunctionReturn(0); 141 142 CHKERRQ(PetscViewerDrawGetBounds(viewer,&nbounds,&bounds)); 143 144 CHKERRQ(VecGetDM(xin,&da)); 145 PetscCheck(da,PetscObjectComm((PetscObject)xin),PETSC_ERR_ARG_WRONG,"Vector not generated from a DMDA"); 146 147 CHKERRQ(PetscObjectGetComm((PetscObject)xin,&comm)); 148 CHKERRMPI(MPI_Comm_rank(comm,&zctx.rank)); 149 150 CHKERRQ(DMDAGetInfo(da,NULL,&M,&N,NULL,&zctx.m,&zctx.n,NULL,&w,&s,&bx,&by,NULL,&st)); 151 CHKERRQ(DMDAGetOwnershipRanges(da,&lx,&ly,NULL)); 152 153 /* 154 Obtain a sequential vector that is going to contain the local values plus ONE layer of 155 ghosted values to draw the graphics from. We also need its corresponding DMDA (dac) that will 156 update the local values pluse ONE layer of ghost values. 157 */ 158 CHKERRQ(PetscObjectQuery((PetscObject)da,"GraphicsGhosted",(PetscObject*)&xlocal)); 159 if (!xlocal) { 160 if (bx != DM_BOUNDARY_NONE || by != DM_BOUNDARY_NONE || s != 1 || st != DMDA_STENCIL_BOX) { 161 /* 162 if original da is not of stencil width one, or periodic or not a box stencil then 163 create a special DMDA to handle one level of ghost points for graphics 164 */ 165 CHKERRQ(DMDACreate2d(comm,DM_BOUNDARY_NONE,DM_BOUNDARY_NONE,DMDA_STENCIL_BOX,M,N,zctx.m,zctx.n,w,1,lx,ly,&dac)); 166 CHKERRQ(DMSetUp(dac)); 167 CHKERRQ(PetscInfo(da,"Creating auxilary DMDA for managing graphics ghost points\n")); 168 } else { 169 /* otherwise we can use the da we already have */ 170 dac = da; 171 } 172 /* create local vector for holding ghosted values used in graphics */ 173 CHKERRQ(DMCreateLocalVector(dac,&xlocal)); 174 if (dac != da) { 175 /* don't keep any public reference of this DMDA, is is only available through xlocal */ 176 CHKERRQ(PetscObjectDereference((PetscObject)dac)); 177 } else { 178 /* remove association between xlocal and da, because below we compose in the opposite 179 direction and if we left this connect we'd get a loop, so the objects could 180 never be destroyed */ 181 CHKERRQ(PetscObjectRemoveReference((PetscObject)xlocal,"__PETSc_dm")); 182 } 183 CHKERRQ(PetscObjectCompose((PetscObject)da,"GraphicsGhosted",(PetscObject)xlocal)); 184 CHKERRQ(PetscObjectDereference((PetscObject)xlocal)); 185 } else { 186 if (bx != DM_BOUNDARY_NONE || by != DM_BOUNDARY_NONE || s != 1 || st != DMDA_STENCIL_BOX) { 187 CHKERRQ(VecGetDM(xlocal, &dac)); 188 } else { 189 dac = da; 190 } 191 } 192 193 /* 194 Get local (ghosted) values of vector 195 */ 196 CHKERRQ(DMGlobalToLocalBegin(dac,xin,INSERT_VALUES,xlocal)); 197 CHKERRQ(DMGlobalToLocalEnd(dac,xin,INSERT_VALUES,xlocal)); 198 CHKERRQ(VecGetArrayRead(xlocal,&zctx.v)); 199 200 /* 201 Get coordinates of nodes 202 */ 203 CHKERRQ(DMGetCoordinates(da,&xcoor)); 204 if (!xcoor) { 205 CHKERRQ(DMDASetUniformCoordinates(da,0.0,1.0,0.0,1.0,0.0,0.0)); 206 CHKERRQ(DMGetCoordinates(da,&xcoor)); 207 } 208 209 /* 210 Determine the min and max coordinates in plot 211 */ 212 CHKERRQ(VecStrideMin(xcoor,0,NULL,&zctx.xmin)); 213 CHKERRQ(VecStrideMax(xcoor,0,NULL,&zctx.xmax)); 214 CHKERRQ(VecStrideMin(xcoor,1,NULL,&zctx.ymin)); 215 CHKERRQ(VecStrideMax(xcoor,1,NULL,&zctx.ymax)); 216 CHKERRQ(PetscOptionsGetBool(NULL,NULL,"-draw_contour_axis",&zctx.showaxis,NULL)); 217 if (zctx.showaxis) { 218 coors[0] = zctx.xmin - .05*(zctx.xmax - zctx.xmin); coors[1] = zctx.ymin - .05*(zctx.ymax - zctx.ymin); 219 coors[2] = zctx.xmax + .05*(zctx.xmax - zctx.xmin); coors[3] = zctx.ymax + .05*(zctx.ymax - zctx.ymin); 220 } else { 221 coors[0] = zctx.xmin; coors[1] = zctx.ymin; coors[2] = zctx.xmax; coors[3] = zctx.ymax; 222 } 223 CHKERRQ(PetscOptionsGetRealArray(NULL,NULL,"-draw_coordinates",coors,&ncoors,NULL)); 224 CHKERRQ(PetscInfo(da,"Preparing DMDA 2d contour plot coordinates %g %g %g %g\n",(double)coors[0],(double)coors[1],(double)coors[2],(double)coors[3])); 225 226 /* 227 Get local ghosted version of coordinates 228 */ 229 CHKERRQ(PetscObjectQuery((PetscObject)da,"GraphicsCoordinateGhosted",(PetscObject*)&xcoorl)); 230 if (!xcoorl) { 231 /* create DMDA to get local version of graphics */ 232 CHKERRQ(DMDACreate2d(comm,DM_BOUNDARY_NONE,DM_BOUNDARY_NONE,DMDA_STENCIL_BOX,M,N,zctx.m,zctx.n,2,1,lx,ly,&dag)); 233 CHKERRQ(DMSetUp(dag)); 234 CHKERRQ(PetscInfo(dag,"Creating auxilary DMDA for managing graphics coordinates ghost points\n")); 235 CHKERRQ(DMCreateLocalVector(dag,&xcoorl)); 236 CHKERRQ(PetscObjectCompose((PetscObject)da,"GraphicsCoordinateGhosted",(PetscObject)xcoorl)); 237 CHKERRQ(PetscObjectDereference((PetscObject)dag)); 238 CHKERRQ(PetscObjectDereference((PetscObject)xcoorl)); 239 } else { 240 CHKERRQ(VecGetDM(xcoorl,&dag)); 241 } 242 CHKERRQ(DMGlobalToLocalBegin(dag,xcoor,INSERT_VALUES,xcoorl)); 243 CHKERRQ(DMGlobalToLocalEnd(dag,xcoor,INSERT_VALUES,xcoorl)); 244 CHKERRQ(VecGetArrayRead(xcoorl,&zctx.xy)); 245 CHKERRQ(DMDAGetCoordinateName(da,0,&zctx.name0)); 246 CHKERRQ(DMDAGetCoordinateName(da,1,&zctx.name1)); 247 248 /* 249 Get information about size of area each processor must do graphics for 250 */ 251 CHKERRQ(DMDAGetInfo(dac,NULL,&M,&N,NULL,NULL,NULL,NULL,&zctx.dof,NULL,&bx,&by,NULL,NULL)); 252 CHKERRQ(DMDAGetGhostCorners(dac,NULL,NULL,NULL,&zctx.m,&zctx.n,NULL)); 253 CHKERRQ(PetscOptionsGetBool(NULL,NULL,"-draw_contour_grid",&zctx.showgrid,NULL)); 254 255 CHKERRQ(DMDASelectFields(da,&ndisplayfields,&displayfields)); 256 CHKERRQ(PetscViewerGetFormat(viewer,&format)); 257 CHKERRQ(PetscOptionsGetBool(NULL,NULL,"-draw_ports",&useports,NULL)); 258 if (format == PETSC_VIEWER_DRAW_PORTS) useports = PETSC_TRUE; 259 if (useports) { 260 CHKERRQ(PetscViewerDrawGetDraw(viewer,0,&draw)); 261 CHKERRQ(PetscDrawCheckResizedWindow(draw)); 262 CHKERRQ(PetscDrawClear(draw)); 263 CHKERRQ(PetscDrawViewPortsCreate(draw,ndisplayfields,&ports)); 264 } 265 266 /* 267 Loop over each field; drawing each in a different window 268 */ 269 for (i=0; i<ndisplayfields; i++) { 270 zctx.k = displayfields[i]; 271 272 /* determine the min and max value in plot */ 273 CHKERRQ(VecStrideMin(xin,zctx.k,NULL,&zctx.min)); 274 CHKERRQ(VecStrideMax(xin,zctx.k,NULL,&zctx.max)); 275 if (zctx.k < nbounds) { 276 zctx.min = bounds[2*zctx.k]; 277 zctx.max = bounds[2*zctx.k+1]; 278 } 279 if (zctx.min == zctx.max) { 280 zctx.min -= 1.e-12; 281 zctx.max += 1.e-12; 282 } 283 CHKERRQ(PetscInfo(da,"DMDA 2d contour plot min %g max %g\n",(double)zctx.min,(double)zctx.max)); 284 285 if (useports) { 286 CHKERRQ(PetscDrawViewPortsSet(ports,i)); 287 } else { 288 const char *title; 289 CHKERRQ(PetscViewerDrawGetDraw(viewer,i,&draw)); 290 CHKERRQ(DMDAGetFieldName(da,zctx.k,&title)); 291 if (title) CHKERRQ(PetscDrawSetTitle(draw,title)); 292 } 293 294 CHKERRQ(PetscDrawGetPopup(draw,&popup)); 295 CHKERRQ(PetscDrawScalePopup(popup,zctx.min,zctx.max)); 296 CHKERRQ(PetscDrawSetCoordinates(draw,coors[0],coors[1],coors[2],coors[3])); 297 CHKERRQ(PetscDrawZoom(draw,VecView_MPI_Draw_DA2d_Zoom,&zctx)); 298 if (!useports) CHKERRQ(PetscDrawSave(draw)); 299 } 300 if (useports) { 301 CHKERRQ(PetscViewerDrawGetDraw(viewer,0,&draw)); 302 CHKERRQ(PetscDrawSave(draw)); 303 } 304 305 CHKERRQ(PetscDrawViewPortsDestroy(ports)); 306 CHKERRQ(PetscFree(displayfields)); 307 CHKERRQ(VecRestoreArrayRead(xcoorl,&zctx.xy)); 308 CHKERRQ(VecRestoreArrayRead(xlocal,&zctx.v)); 309 PetscFunctionReturn(0); 310 } 311 312 #if defined(PETSC_HAVE_HDF5) 313 static PetscErrorCode VecGetHDF5ChunkSize(DM_DA *da, Vec xin, PetscInt dimension, PetscInt timestep, hsize_t *chunkDims) 314 { 315 PetscMPIInt comm_size; 316 hsize_t chunk_size, target_size, dim; 317 hsize_t vec_size = sizeof(PetscScalar)*da->M*da->N*da->P*da->w; 318 hsize_t avg_local_vec_size,KiB = 1024,MiB = KiB*KiB,GiB = MiB*KiB,min_size = MiB; 319 hsize_t max_chunks = 64*KiB; /* HDF5 internal limitation */ 320 hsize_t max_chunk_size = 4*GiB; /* HDF5 internal limitation */ 321 PetscInt zslices=da->p, yslices=da->n, xslices=da->m; 322 323 PetscFunctionBegin; 324 CHKERRMPI(MPI_Comm_size(PetscObjectComm((PetscObject)xin), &comm_size)); 325 avg_local_vec_size = (hsize_t) PetscCeilInt(vec_size,comm_size); /* we will attempt to use this as the chunk size */ 326 327 target_size = (hsize_t) PetscMin((PetscInt64)vec_size,PetscMin((PetscInt64)max_chunk_size,PetscMax((PetscInt64)avg_local_vec_size,PetscMax(PetscCeilInt64(vec_size,max_chunks),(PetscInt64)min_size)))); 328 /* following line uses sizeof(PetscReal) instead of sizeof(PetscScalar) because the last dimension of chunkDims[] captures the 2* when complex numbers are being used */ 329 chunk_size = (hsize_t) PetscMax(1,chunkDims[0])*PetscMax(1,chunkDims[1])*PetscMax(1,chunkDims[2])*PetscMax(1,chunkDims[3])*PetscMax(1,chunkDims[4])*PetscMax(1,chunkDims[5])*sizeof(PetscReal); 330 331 /* 332 if size/rank > max_chunk_size, we need radical measures: even going down to 333 avg_local_vec_size is not enough, so we simply use chunk size of 4 GiB no matter 334 what, composed in the most efficient way possible. 335 N.B. this minimises the number of chunks, which may or may not be the optimal 336 solution. In a BG, for example, the optimal solution is probably to make # chunks = # 337 IO nodes involved, but this author has no access to a BG to figure out how to 338 reliably find the right number. And even then it may or may not be enough. 339 */ 340 if (avg_local_vec_size > max_chunk_size) { 341 /* check if we can just split local z-axis: is that enough? */ 342 zslices = PetscCeilInt(vec_size,da->p*max_chunk_size)*zslices; 343 if (zslices > da->P) { 344 /* lattice is too large in xy-directions, splitting z only is not enough */ 345 zslices = da->P; 346 yslices = PetscCeilInt(vec_size,zslices*da->n*max_chunk_size)*yslices; 347 if (yslices > da->N) { 348 /* lattice is too large in x-direction, splitting along z, y is not enough */ 349 yslices = da->N; 350 xslices = PetscCeilInt(vec_size,zslices*yslices*da->m*max_chunk_size)*xslices; 351 } 352 } 353 dim = 0; 354 if (timestep >= 0) { 355 ++dim; 356 } 357 /* prefer to split z-axis, even down to planar slices */ 358 if (dimension == 3) { 359 chunkDims[dim++] = (hsize_t) da->P/zslices; 360 chunkDims[dim++] = (hsize_t) da->N/yslices; 361 chunkDims[dim++] = (hsize_t) da->M/xslices; 362 } else { 363 /* This is a 2D world exceeding 4GiB in size; yes, I've seen them, even used myself */ 364 chunkDims[dim++] = (hsize_t) da->N/yslices; 365 chunkDims[dim++] = (hsize_t) da->M/xslices; 366 } 367 chunk_size = (hsize_t) PetscMax(1,chunkDims[0])*PetscMax(1,chunkDims[1])*PetscMax(1,chunkDims[2])*PetscMax(1,chunkDims[3])*PetscMax(1,chunkDims[4])*PetscMax(1,chunkDims[5])*sizeof(double); 368 } else { 369 if (target_size < chunk_size) { 370 /* only change the defaults if target_size < chunk_size */ 371 dim = 0; 372 if (timestep >= 0) { 373 ++dim; 374 } 375 /* prefer to split z-axis, even down to planar slices */ 376 if (dimension == 3) { 377 /* try splitting the z-axis to core-size bits, i.e. divide chunk size by # comm_size in z-direction */ 378 if (target_size >= chunk_size/da->p) { 379 /* just make chunks the size of <local_z>x<whole_world_y>x<whole_world_x>x<dof> */ 380 chunkDims[dim] = (hsize_t) PetscCeilInt(da->P,da->p); 381 } else { 382 /* oops, just splitting the z-axis is NOT ENOUGH, need to split more; let's be 383 radical and let everyone write all they've got */ 384 chunkDims[dim++] = (hsize_t) PetscCeilInt(da->P,da->p); 385 chunkDims[dim++] = (hsize_t) PetscCeilInt(da->N,da->n); 386 chunkDims[dim++] = (hsize_t) PetscCeilInt(da->M,da->m); 387 } 388 } else { 389 /* This is a 2D world exceeding 4GiB in size; yes, I've seen them, even used myself */ 390 if (target_size >= chunk_size/da->n) { 391 /* just make chunks the size of <local_z>x<whole_world_y>x<whole_world_x>x<dof> */ 392 chunkDims[dim] = (hsize_t) PetscCeilInt(da->N,da->n); 393 } else { 394 /* oops, just splitting the z-axis is NOT ENOUGH, need to split more; let's be 395 radical and let everyone write all they've got */ 396 chunkDims[dim++] = (hsize_t) PetscCeilInt(da->N,da->n); 397 chunkDims[dim++] = (hsize_t) PetscCeilInt(da->M,da->m); 398 } 399 400 } 401 chunk_size = (hsize_t) PetscMax(1,chunkDims[0])*PetscMax(1,chunkDims[1])*PetscMax(1,chunkDims[2])*PetscMax(1,chunkDims[3])*PetscMax(1,chunkDims[4])*PetscMax(1,chunkDims[5])*sizeof(double); 402 } else { 403 /* precomputed chunks are fine, we don't need to do anything */ 404 } 405 } 406 PetscFunctionReturn(0); 407 } 408 #endif 409 410 #if defined(PETSC_HAVE_HDF5) 411 PetscErrorCode VecView_MPI_HDF5_DA(Vec xin,PetscViewer viewer) 412 { 413 PetscViewer_HDF5 *hdf5 = (PetscViewer_HDF5*) viewer->data; 414 DM dm; 415 DM_DA *da; 416 hid_t filespace; /* file dataspace identifier */ 417 hid_t chunkspace; /* chunk dataset property identifier */ 418 hid_t dset_id; /* dataset identifier */ 419 hid_t memspace; /* memory dataspace identifier */ 420 hid_t file_id; 421 hid_t group; 422 hid_t memscalartype; /* scalar type for mem (H5T_NATIVE_FLOAT or H5T_NATIVE_DOUBLE) */ 423 hid_t filescalartype; /* scalar type for file (H5T_NATIVE_FLOAT or H5T_NATIVE_DOUBLE) */ 424 hsize_t dim; 425 hsize_t maxDims[6]={0}, dims[6]={0}, chunkDims[6]={0}, count[6]={0}, offset[6]={0}; /* we depend on these being sane later on */ 426 PetscBool timestepping=PETSC_FALSE, dim2, spoutput; 427 PetscInt timestep=PETSC_MIN_INT, dimension; 428 const PetscScalar *x; 429 const char *vecname; 430 431 PetscFunctionBegin; 432 CHKERRQ(PetscViewerHDF5OpenGroup(viewer, &file_id, &group)); 433 CHKERRQ(PetscViewerHDF5IsTimestepping(viewer, ×tepping)); 434 if (timestepping) { 435 CHKERRQ(PetscViewerHDF5GetTimestep(viewer, ×tep)); 436 } 437 CHKERRQ(PetscViewerHDF5GetBaseDimension2(viewer,&dim2)); 438 CHKERRQ(PetscViewerHDF5GetSPOutput(viewer,&spoutput)); 439 440 CHKERRQ(VecGetDM(xin,&dm)); 441 PetscCheck(dm,PetscObjectComm((PetscObject)xin),PETSC_ERR_ARG_WRONG,"Vector not generated from a DMDA"); 442 da = (DM_DA*)dm->data; 443 CHKERRQ(DMGetDimension(dm, &dimension)); 444 445 /* Create the dataspace for the dataset. 446 * 447 * dims - holds the current dimensions of the dataset 448 * 449 * maxDims - holds the maximum dimensions of the dataset (unlimited 450 * for the number of time steps with the current dimensions for the 451 * other dimensions; so only additional time steps can be added). 452 * 453 * chunkDims - holds the size of a single time step (required to 454 * permit extending dataset). 455 */ 456 dim = 0; 457 if (timestep >= 0) { 458 dims[dim] = timestep+1; 459 maxDims[dim] = H5S_UNLIMITED; 460 chunkDims[dim] = 1; 461 ++dim; 462 } 463 if (dimension == 3) { 464 CHKERRQ(PetscHDF5IntCast(da->P,dims+dim)); 465 maxDims[dim] = dims[dim]; 466 chunkDims[dim] = dims[dim]; 467 ++dim; 468 } 469 if (dimension > 1) { 470 CHKERRQ(PetscHDF5IntCast(da->N,dims+dim)); 471 maxDims[dim] = dims[dim]; 472 chunkDims[dim] = dims[dim]; 473 ++dim; 474 } 475 CHKERRQ(PetscHDF5IntCast(da->M,dims+dim)); 476 maxDims[dim] = dims[dim]; 477 chunkDims[dim] = dims[dim]; 478 ++dim; 479 if (da->w > 1 || dim2) { 480 CHKERRQ(PetscHDF5IntCast(da->w,dims+dim)); 481 maxDims[dim] = dims[dim]; 482 chunkDims[dim] = dims[dim]; 483 ++dim; 484 } 485 #if defined(PETSC_USE_COMPLEX) 486 dims[dim] = 2; 487 maxDims[dim] = dims[dim]; 488 chunkDims[dim] = dims[dim]; 489 ++dim; 490 #endif 491 492 CHKERRQ(VecGetHDF5ChunkSize(da, xin, dimension, timestep, chunkDims)); 493 494 PetscStackCallHDF5Return(filespace,H5Screate_simple,(dim, dims, maxDims)); 495 496 #if defined(PETSC_USE_REAL_SINGLE) 497 memscalartype = H5T_NATIVE_FLOAT; 498 filescalartype = H5T_NATIVE_FLOAT; 499 #elif defined(PETSC_USE_REAL___FLOAT128) 500 #error "HDF5 output with 128 bit floats not supported." 501 #elif defined(PETSC_USE_REAL___FP16) 502 #error "HDF5 output with 16 bit floats not supported." 503 #else 504 memscalartype = H5T_NATIVE_DOUBLE; 505 if (spoutput == PETSC_TRUE) filescalartype = H5T_NATIVE_FLOAT; 506 else filescalartype = H5T_NATIVE_DOUBLE; 507 #endif 508 509 /* Create the dataset with default properties and close filespace */ 510 CHKERRQ(PetscObjectGetName((PetscObject)xin,&vecname)); 511 if (!H5Lexists(group, vecname, H5P_DEFAULT)) { 512 /* Create chunk */ 513 PetscStackCallHDF5Return(chunkspace,H5Pcreate,(H5P_DATASET_CREATE)); 514 PetscStackCallHDF5(H5Pset_chunk,(chunkspace, dim, chunkDims)); 515 516 PetscStackCallHDF5Return(dset_id,H5Dcreate2,(group, vecname, filescalartype, filespace, H5P_DEFAULT, chunkspace, H5P_DEFAULT)); 517 } else { 518 PetscStackCallHDF5Return(dset_id,H5Dopen2,(group, vecname, H5P_DEFAULT)); 519 PetscStackCallHDF5(H5Dset_extent,(dset_id, dims)); 520 } 521 PetscStackCallHDF5(H5Sclose,(filespace)); 522 523 /* Each process defines a dataset and writes it to the hyperslab in the file */ 524 dim = 0; 525 if (timestep >= 0) { 526 offset[dim] = timestep; 527 ++dim; 528 } 529 if (dimension == 3) CHKERRQ(PetscHDF5IntCast(da->zs,offset + dim++)); 530 if (dimension > 1) CHKERRQ(PetscHDF5IntCast(da->ys,offset + dim++)); 531 CHKERRQ(PetscHDF5IntCast(da->xs/da->w,offset + dim++)); 532 if (da->w > 1 || dim2) offset[dim++] = 0; 533 #if defined(PETSC_USE_COMPLEX) 534 offset[dim++] = 0; 535 #endif 536 dim = 0; 537 if (timestep >= 0) { 538 count[dim] = 1; 539 ++dim; 540 } 541 if (dimension == 3) CHKERRQ(PetscHDF5IntCast(da->ze - da->zs,count + dim++)); 542 if (dimension > 1) CHKERRQ(PetscHDF5IntCast(da->ye - da->ys,count + dim++)); 543 CHKERRQ(PetscHDF5IntCast((da->xe - da->xs)/da->w,count + dim++)); 544 if (da->w > 1 || dim2) CHKERRQ(PetscHDF5IntCast(da->w,count + dim++)); 545 #if defined(PETSC_USE_COMPLEX) 546 count[dim++] = 2; 547 #endif 548 PetscStackCallHDF5Return(memspace,H5Screate_simple,(dim, count, NULL)); 549 PetscStackCallHDF5Return(filespace,H5Dget_space,(dset_id)); 550 PetscStackCallHDF5(H5Sselect_hyperslab,(filespace, H5S_SELECT_SET, offset, NULL, count, NULL)); 551 552 CHKERRQ(VecGetArrayRead(xin, &x)); 553 PetscStackCallHDF5(H5Dwrite,(dset_id, memscalartype, memspace, filespace, hdf5->dxpl_id, x)); 554 PetscStackCallHDF5(H5Fflush,(file_id, H5F_SCOPE_GLOBAL)); 555 CHKERRQ(VecRestoreArrayRead(xin, &x)); 556 557 #if defined(PETSC_USE_COMPLEX) 558 { 559 PetscBool tru = PETSC_TRUE; 560 CHKERRQ(PetscViewerHDF5WriteObjectAttribute(viewer,(PetscObject)xin,"complex",PETSC_BOOL,&tru)); 561 } 562 #endif 563 if (timestepping) { 564 CHKERRQ(PetscViewerHDF5WriteObjectAttribute(viewer,(PetscObject)xin,"timestepping",PETSC_BOOL,×tepping)); 565 } 566 567 /* Close/release resources */ 568 if (group != file_id) { 569 PetscStackCallHDF5(H5Gclose,(group)); 570 } 571 PetscStackCallHDF5(H5Sclose,(filespace)); 572 PetscStackCallHDF5(H5Sclose,(memspace)); 573 PetscStackCallHDF5(H5Dclose,(dset_id)); 574 CHKERRQ(PetscInfo(xin,"Wrote Vec object with name %s\n",vecname)); 575 PetscFunctionReturn(0); 576 } 577 #endif 578 579 extern PetscErrorCode VecView_MPI_Draw_DA1d(Vec,PetscViewer); 580 581 #if defined(PETSC_HAVE_MPIIO) 582 static PetscErrorCode DMDAArrayMPIIO(DM da,PetscViewer viewer,Vec xin,PetscBool write) 583 { 584 MPI_File mfdes; 585 PetscMPIInt gsizes[4],lsizes[4],lstarts[4],asiz,dof; 586 MPI_Datatype view; 587 const PetscScalar *array; 588 MPI_Offset off; 589 MPI_Aint ub,ul; 590 PetscInt type,rows,vecrows,tr[2]; 591 DM_DA *dd = (DM_DA*)da->data; 592 PetscBool skipheader; 593 594 PetscFunctionBegin; 595 CHKERRQ(VecGetSize(xin,&vecrows)); 596 CHKERRQ(PetscViewerBinaryGetSkipHeader(viewer,&skipheader)); 597 if (!write) { 598 /* Read vector header. */ 599 if (!skipheader) { 600 CHKERRQ(PetscViewerBinaryRead(viewer,tr,2,NULL,PETSC_INT)); 601 type = tr[0]; 602 rows = tr[1]; 603 PetscCheckFalse(type != VEC_FILE_CLASSID,PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_WRONG,"Not vector next in file"); 604 PetscCheckFalse(rows != vecrows,PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_SIZ,"Vector in file not same size as DMDA vector"); 605 } 606 } else { 607 tr[0] = VEC_FILE_CLASSID; 608 tr[1] = vecrows; 609 if (!skipheader) { 610 CHKERRQ(PetscViewerBinaryWrite(viewer,tr,2,PETSC_INT)); 611 } 612 } 613 614 CHKERRQ(PetscMPIIntCast(dd->w,&dof)); 615 gsizes[0] = dof; 616 CHKERRQ(PetscMPIIntCast(dd->M,gsizes+1)); 617 CHKERRQ(PetscMPIIntCast(dd->N,gsizes+2)); 618 CHKERRQ(PetscMPIIntCast(dd->P,gsizes+3)); 619 lsizes[0] = dof; 620 CHKERRQ(PetscMPIIntCast((dd->xe-dd->xs)/dof,lsizes+1)); 621 CHKERRQ(PetscMPIIntCast(dd->ye-dd->ys,lsizes+2)); 622 CHKERRQ(PetscMPIIntCast(dd->ze-dd->zs,lsizes+3)); 623 lstarts[0] = 0; 624 CHKERRQ(PetscMPIIntCast(dd->xs/dof,lstarts+1)); 625 CHKERRQ(PetscMPIIntCast(dd->ys,lstarts+2)); 626 CHKERRQ(PetscMPIIntCast(dd->zs,lstarts+3)); 627 CHKERRMPI(MPI_Type_create_subarray(da->dim+1,gsizes,lsizes,lstarts,MPI_ORDER_FORTRAN,MPIU_SCALAR,&view)); 628 CHKERRMPI(MPI_Type_commit(&view)); 629 630 CHKERRQ(PetscViewerBinaryGetMPIIODescriptor(viewer,&mfdes)); 631 CHKERRQ(PetscViewerBinaryGetMPIIOOffset(viewer,&off)); 632 CHKERRMPI(MPI_File_set_view(mfdes,off,MPIU_SCALAR,view,(char*)"native",MPI_INFO_NULL)); 633 CHKERRQ(VecGetArrayRead(xin,&array)); 634 asiz = lsizes[1]*(lsizes[2] > 0 ? lsizes[2] : 1)*(lsizes[3] > 0 ? lsizes[3] : 1)*dof; 635 if (write) { 636 CHKERRQ(MPIU_File_write_all(mfdes,(PetscScalar*)array,asiz,MPIU_SCALAR,MPI_STATUS_IGNORE)); 637 } else { 638 CHKERRQ(MPIU_File_read_all(mfdes,(PetscScalar*)array,asiz,MPIU_SCALAR,MPI_STATUS_IGNORE)); 639 } 640 CHKERRMPI(MPI_Type_get_extent(view,&ul,&ub)); 641 CHKERRQ(PetscViewerBinaryAddMPIIOOffset(viewer,ub)); 642 CHKERRQ(VecRestoreArrayRead(xin,&array)); 643 CHKERRMPI(MPI_Type_free(&view)); 644 PetscFunctionReturn(0); 645 } 646 #endif 647 648 PetscErrorCode VecView_MPI_DA(Vec xin,PetscViewer viewer) 649 { 650 DM da; 651 PetscInt dim; 652 Vec natural; 653 PetscBool isdraw,isvtk,isglvis; 654 #if defined(PETSC_HAVE_HDF5) 655 PetscBool ishdf5; 656 #endif 657 const char *prefix,*name; 658 PetscViewerFormat format; 659 660 PetscFunctionBegin; 661 CHKERRQ(VecGetDM(xin,&da)); 662 PetscCheck(da,PetscObjectComm((PetscObject)xin),PETSC_ERR_ARG_WRONG,"Vector not generated from a DMDA"); 663 CHKERRQ(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw)); 664 CHKERRQ(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERVTK,&isvtk)); 665 #if defined(PETSC_HAVE_HDF5) 666 CHKERRQ(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,&ishdf5)); 667 #endif 668 CHKERRQ(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERGLVIS,&isglvis)); 669 if (isdraw) { 670 CHKERRQ(DMDAGetInfo(da,&dim,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL)); 671 if (dim == 1) { 672 CHKERRQ(VecView_MPI_Draw_DA1d(xin,viewer)); 673 } else if (dim == 2) { 674 CHKERRQ(VecView_MPI_Draw_DA2d(xin,viewer)); 675 } else SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"Cannot graphically view vector associated with this dimensional DMDA %D",dim); 676 } else if (isvtk) { /* Duplicate the Vec */ 677 Vec Y; 678 CHKERRQ(VecDuplicate(xin,&Y)); 679 if (((PetscObject)xin)->name) { 680 /* If xin was named, copy the name over to Y. The duplicate names are safe because nobody else will ever see Y. */ 681 CHKERRQ(PetscObjectSetName((PetscObject)Y,((PetscObject)xin)->name)); 682 } 683 CHKERRQ(VecCopy(xin,Y)); 684 { 685 PetscObject dmvtk; 686 PetscBool compatible,compatibleSet; 687 CHKERRQ(PetscViewerVTKGetDM(viewer,&dmvtk)); 688 if (dmvtk) { 689 PetscValidHeaderSpecific((DM)dmvtk,DM_CLASSID,2); 690 CHKERRQ(DMGetCompatibility(da,(DM)dmvtk,&compatible,&compatibleSet)); 691 PetscCheck(compatibleSet && compatible,PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_INCOMP,"Cannot confirm compatibility of DMs associated with Vecs viewed in the same VTK file. Check that grids are the same."); 692 } 693 CHKERRQ(PetscViewerVTKAddField(viewer,(PetscObject)da,DMDAVTKWriteAll,PETSC_DEFAULT,PETSC_VTK_POINT_FIELD,PETSC_FALSE,(PetscObject)Y)); 694 } 695 #if defined(PETSC_HAVE_HDF5) 696 } else if (ishdf5) { 697 CHKERRQ(VecView_MPI_HDF5_DA(xin,viewer)); 698 #endif 699 } else if (isglvis) { 700 CHKERRQ(VecView_GLVis(xin,viewer)); 701 } else { 702 #if defined(PETSC_HAVE_MPIIO) 703 PetscBool isbinary,isMPIIO; 704 705 CHKERRQ(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary)); 706 if (isbinary) { 707 CHKERRQ(PetscViewerBinaryGetUseMPIIO(viewer,&isMPIIO)); 708 if (isMPIIO) { 709 CHKERRQ(DMDAArrayMPIIO(da,viewer,xin,PETSC_TRUE)); 710 PetscFunctionReturn(0); 711 } 712 } 713 #endif 714 715 /* call viewer on natural ordering */ 716 CHKERRQ(PetscObjectGetOptionsPrefix((PetscObject)xin,&prefix)); 717 CHKERRQ(DMDACreateNaturalVector(da,&natural)); 718 CHKERRQ(PetscObjectSetOptionsPrefix((PetscObject)natural,prefix)); 719 CHKERRQ(DMDAGlobalToNaturalBegin(da,xin,INSERT_VALUES,natural)); 720 CHKERRQ(DMDAGlobalToNaturalEnd(da,xin,INSERT_VALUES,natural)); 721 CHKERRQ(PetscObjectGetName((PetscObject)xin,&name)); 722 CHKERRQ(PetscObjectSetName((PetscObject)natural,name)); 723 724 CHKERRQ(PetscViewerGetFormat(viewer,&format)); 725 if (format == PETSC_VIEWER_BINARY_MATLAB) { 726 /* temporarily remove viewer format so it won't trigger in the VecView() */ 727 CHKERRQ(PetscViewerPushFormat(viewer,PETSC_VIEWER_DEFAULT)); 728 } 729 730 ((PetscObject)natural)->donotPetscObjectPrintClassNamePrefixType = PETSC_TRUE; 731 CHKERRQ(VecView(natural,viewer)); 732 ((PetscObject)natural)->donotPetscObjectPrintClassNamePrefixType = PETSC_FALSE; 733 734 if (format == PETSC_VIEWER_BINARY_MATLAB) { 735 MPI_Comm comm; 736 FILE *info; 737 const char *fieldname; 738 char fieldbuf[256]; 739 PetscInt dim,ni,nj,nk,pi,pj,pk,dof,n; 740 741 /* set the viewer format back into the viewer */ 742 CHKERRQ(PetscViewerPopFormat(viewer)); 743 CHKERRQ(PetscObjectGetComm((PetscObject)viewer,&comm)); 744 CHKERRQ(PetscViewerBinaryGetInfoPointer(viewer,&info)); 745 CHKERRQ(DMDAGetInfo(da,&dim,&ni,&nj,&nk,&pi,&pj,&pk,&dof,NULL,NULL,NULL,NULL,NULL)); 746 CHKERRQ(PetscFPrintf(comm,info,"#--- begin code written by PetscViewerBinary for MATLAB format ---#\n")); 747 CHKERRQ(PetscFPrintf(comm,info,"#$$ tmp = PetscBinaryRead(fd); \n")); 748 if (dim == 1) { CHKERRQ(PetscFPrintf(comm,info,"#$$ tmp = reshape(tmp,%d,%d);\n",dof,ni)); } 749 if (dim == 2) { CHKERRQ(PetscFPrintf(comm,info,"#$$ tmp = reshape(tmp,%d,%d,%d);\n",dof,ni,nj)); } 750 if (dim == 3) { CHKERRQ(PetscFPrintf(comm,info,"#$$ tmp = reshape(tmp,%d,%d,%d,%d);\n",dof,ni,nj,nk)); } 751 752 for (n=0; n<dof; n++) { 753 CHKERRQ(DMDAGetFieldName(da,n,&fieldname)); 754 if (!fieldname || !fieldname[0]) { 755 CHKERRQ(PetscSNPrintf(fieldbuf,sizeof fieldbuf,"field%D",n)); 756 fieldname = fieldbuf; 757 } 758 if (dim == 1) { CHKERRQ(PetscFPrintf(comm,info,"#$$ Set.%s.%s = squeeze(tmp(%d,:))';\n",name,fieldname,n+1)); } 759 if (dim == 2) { CHKERRQ(PetscFPrintf(comm,info,"#$$ Set.%s.%s = squeeze(tmp(%d,:,:))';\n",name,fieldname,n+1)); } 760 if (dim == 3) { CHKERRQ(PetscFPrintf(comm,info,"#$$ Set.%s.%s = permute(squeeze(tmp(%d,:,:,:)),[2 1 3]);\n",name,fieldname,n+1));} 761 } 762 CHKERRQ(PetscFPrintf(comm,info,"#$$ clear tmp; \n")); 763 CHKERRQ(PetscFPrintf(comm,info,"#--- end code written by PetscViewerBinary for MATLAB format ---#\n\n")); 764 } 765 766 CHKERRQ(VecDestroy(&natural)); 767 } 768 PetscFunctionReturn(0); 769 } 770 771 #if defined(PETSC_HAVE_HDF5) 772 PetscErrorCode VecLoad_HDF5_DA(Vec xin, PetscViewer viewer) 773 { 774 PetscViewer_HDF5 *hdf5 = (PetscViewer_HDF5*) viewer->data; 775 DM da; 776 int dim,rdim; 777 hsize_t dims[6]={0},count[6]={0},offset[6]={0}; 778 PetscBool dim2=PETSC_FALSE,timestepping=PETSC_FALSE; 779 PetscInt dimension,timestep=PETSC_MIN_INT,dofInd; 780 PetscScalar *x; 781 const char *vecname; 782 hid_t filespace; /* file dataspace identifier */ 783 hid_t dset_id; /* dataset identifier */ 784 hid_t memspace; /* memory dataspace identifier */ 785 hid_t file_id,group; 786 hid_t scalartype; /* scalar type (H5T_NATIVE_FLOAT or H5T_NATIVE_DOUBLE) */ 787 DM_DA *dd; 788 789 PetscFunctionBegin; 790 #if defined(PETSC_USE_REAL_SINGLE) 791 scalartype = H5T_NATIVE_FLOAT; 792 #elif defined(PETSC_USE_REAL___FLOAT128) 793 #error "HDF5 output with 128 bit floats not supported." 794 #elif defined(PETSC_USE_REAL___FP16) 795 #error "HDF5 output with 16 bit floats not supported." 796 #else 797 scalartype = H5T_NATIVE_DOUBLE; 798 #endif 799 800 CHKERRQ(PetscViewerHDF5OpenGroup(viewer, &file_id, &group)); 801 CHKERRQ(PetscObjectGetName((PetscObject)xin,&vecname)); 802 CHKERRQ(PetscViewerHDF5CheckTimestepping_Internal(viewer, vecname)); 803 CHKERRQ(PetscViewerHDF5IsTimestepping(viewer, ×tepping)); 804 if (timestepping) { 805 CHKERRQ(PetscViewerHDF5GetTimestep(viewer, ×tep)); 806 } 807 CHKERRQ(VecGetDM(xin,&da)); 808 dd = (DM_DA*)da->data; 809 CHKERRQ(DMGetDimension(da, &dimension)); 810 811 /* Open dataset */ 812 PetscStackCallHDF5Return(dset_id,H5Dopen2,(group, vecname, H5P_DEFAULT)); 813 814 /* Retrieve the dataspace for the dataset */ 815 PetscStackCallHDF5Return(filespace,H5Dget_space,(dset_id)); 816 PetscStackCallHDF5Return(rdim,H5Sget_simple_extent_dims,(filespace, dims, NULL)); 817 818 /* Expected dimension for holding the dof's */ 819 #if defined(PETSC_USE_COMPLEX) 820 dofInd = rdim-2; 821 #else 822 dofInd = rdim-1; 823 #endif 824 825 /* The expected number of dimensions, assuming basedimension2 = false */ 826 dim = dimension; 827 if (dd->w > 1) ++dim; 828 if (timestep >= 0) ++dim; 829 #if defined(PETSC_USE_COMPLEX) 830 ++dim; 831 #endif 832 833 /* In this case the input dataset have one extra, unexpected dimension. */ 834 if (rdim == dim+1) { 835 /* In this case the block size unity */ 836 if (dd->w == 1 && dims[dofInd] == 1) dim2 = PETSC_TRUE; 837 838 /* Special error message for the case where dof does not match the input file */ 839 else PetscCheckFalse(dd->w != (PetscInt) dims[dofInd],PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED, "Number of dofs in file is %D, not %D as expected",(PetscInt)dims[dofInd],dd->w); 840 841 /* Other cases where rdim != dim cannot be handled currently */ 842 } else PetscCheckFalse(rdim != dim,PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED, "Dimension of array in file is %d, not %d as expected with dof = %D",rdim,dim,dd->w); 843 844 /* Set up the hyperslab size */ 845 dim = 0; 846 if (timestep >= 0) { 847 offset[dim] = timestep; 848 count[dim] = 1; 849 ++dim; 850 } 851 if (dimension == 3) { 852 CHKERRQ(PetscHDF5IntCast(dd->zs,offset + dim)); 853 CHKERRQ(PetscHDF5IntCast(dd->ze - dd->zs,count + dim)); 854 ++dim; 855 } 856 if (dimension > 1) { 857 CHKERRQ(PetscHDF5IntCast(dd->ys,offset + dim)); 858 CHKERRQ(PetscHDF5IntCast(dd->ye - dd->ys,count + dim)); 859 ++dim; 860 } 861 CHKERRQ(PetscHDF5IntCast(dd->xs/dd->w,offset + dim)); 862 CHKERRQ(PetscHDF5IntCast((dd->xe - dd->xs)/dd->w,count + dim)); 863 ++dim; 864 if (dd->w > 1 || dim2) { 865 offset[dim] = 0; 866 CHKERRQ(PetscHDF5IntCast(dd->w,count + dim)); 867 ++dim; 868 } 869 #if defined(PETSC_USE_COMPLEX) 870 offset[dim] = 0; 871 count[dim] = 2; 872 ++dim; 873 #endif 874 875 /* Create the memory and filespace */ 876 PetscStackCallHDF5Return(memspace,H5Screate_simple,(dim, count, NULL)); 877 PetscStackCallHDF5(H5Sselect_hyperslab,(filespace, H5S_SELECT_SET, offset, NULL, count, NULL)); 878 879 CHKERRQ(VecGetArray(xin, &x)); 880 PetscStackCallHDF5(H5Dread,(dset_id, scalartype, memspace, filespace, hdf5->dxpl_id, x)); 881 CHKERRQ(VecRestoreArray(xin, &x)); 882 883 /* Close/release resources */ 884 if (group != file_id) { 885 PetscStackCallHDF5(H5Gclose,(group)); 886 } 887 PetscStackCallHDF5(H5Sclose,(filespace)); 888 PetscStackCallHDF5(H5Sclose,(memspace)); 889 PetscStackCallHDF5(H5Dclose,(dset_id)); 890 PetscFunctionReturn(0); 891 } 892 #endif 893 894 PetscErrorCode VecLoad_Binary_DA(Vec xin, PetscViewer viewer) 895 { 896 DM da; 897 Vec natural; 898 const char *prefix; 899 PetscInt bs; 900 PetscBool flag; 901 DM_DA *dd; 902 #if defined(PETSC_HAVE_MPIIO) 903 PetscBool isMPIIO; 904 #endif 905 906 PetscFunctionBegin; 907 CHKERRQ(VecGetDM(xin,&da)); 908 dd = (DM_DA*)da->data; 909 #if defined(PETSC_HAVE_MPIIO) 910 CHKERRQ(PetscViewerBinaryGetUseMPIIO(viewer,&isMPIIO)); 911 if (isMPIIO) { 912 CHKERRQ(DMDAArrayMPIIO(da,viewer,xin,PETSC_FALSE)); 913 PetscFunctionReturn(0); 914 } 915 #endif 916 917 CHKERRQ(PetscObjectGetOptionsPrefix((PetscObject)xin,&prefix)); 918 CHKERRQ(DMDACreateNaturalVector(da,&natural)); 919 CHKERRQ(PetscObjectSetName((PetscObject)natural,((PetscObject)xin)->name)); 920 CHKERRQ(PetscObjectSetOptionsPrefix((PetscObject)natural,prefix)); 921 CHKERRQ(VecLoad(natural,viewer)); 922 CHKERRQ(DMDANaturalToGlobalBegin(da,natural,INSERT_VALUES,xin)); 923 CHKERRQ(DMDANaturalToGlobalEnd(da,natural,INSERT_VALUES,xin)); 924 CHKERRQ(VecDestroy(&natural)); 925 CHKERRQ(PetscInfo(xin,"Loading vector from natural ordering into DMDA\n")); 926 CHKERRQ(PetscOptionsGetInt(NULL,((PetscObject)xin)->prefix,"-vecload_block_size",&bs,&flag)); 927 if (flag && bs != dd->w) { 928 CHKERRQ(PetscInfo(xin,"Block size in file %D not equal to DMDA's dof %D\n",bs,dd->w)); 929 } 930 PetscFunctionReturn(0); 931 } 932 933 PetscErrorCode VecLoad_Default_DA(Vec xin, PetscViewer viewer) 934 { 935 DM da; 936 PetscBool isbinary; 937 #if defined(PETSC_HAVE_HDF5) 938 PetscBool ishdf5; 939 #endif 940 941 PetscFunctionBegin; 942 CHKERRQ(VecGetDM(xin,&da)); 943 PetscCheck(da,PetscObjectComm((PetscObject)xin),PETSC_ERR_ARG_WRONG,"Vector not generated from a DMDA"); 944 945 #if defined(PETSC_HAVE_HDF5) 946 CHKERRQ(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,&ishdf5)); 947 #endif 948 CHKERRQ(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary)); 949 950 if (isbinary) { 951 CHKERRQ(VecLoad_Binary_DA(xin,viewer)); 952 #if defined(PETSC_HAVE_HDF5) 953 } else if (ishdf5) { 954 CHKERRQ(VecLoad_HDF5_DA(xin,viewer)); 955 #endif 956 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Viewer type %s not supported for vector loading", ((PetscObject)viewer)->type_name); 957 PetscFunctionReturn(0); 958 } 959