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