1 2 #include <../src/sys/classes/viewer/impls/draw/vdraw.h> /*I "petscdraw.h" I*/ 3 #include <petscviewer.h> /*I "petscviewer.h" I*/ 4 5 static PetscErrorCode PetscViewerDestroy_Draw(PetscViewer v) 6 { 7 PetscErrorCode ierr; 8 PetscInt i; 9 PetscViewer_Draw *vdraw = (PetscViewer_Draw*)v->data; 10 11 PetscFunctionBegin; 12 if (vdraw->singleton_made) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Destroying PetscViewer without first restoring singleton"); 13 for (i=0; i<vdraw->draw_max; i++) { 14 ierr = PetscDrawAxisDestroy(&vdraw->drawaxis[i]);CHKERRQ(ierr); 15 ierr = PetscDrawLGDestroy(&vdraw->drawlg[i]);CHKERRQ(ierr); 16 ierr = PetscDrawDestroy(&vdraw->draw[i]);CHKERRQ(ierr); 17 } 18 ierr = PetscFree(vdraw->display);CHKERRQ(ierr); 19 ierr = PetscFree(vdraw->title);CHKERRQ(ierr); 20 ierr = PetscFree3(vdraw->draw,vdraw->drawlg,vdraw->drawaxis);CHKERRQ(ierr); 21 ierr = PetscFree(vdraw->bounds);CHKERRQ(ierr); 22 ierr = PetscFree(vdraw->drawtype);CHKERRQ(ierr); 23 ierr = PetscFree(v->data);CHKERRQ(ierr); 24 PetscFunctionReturn(0); 25 } 26 27 static PetscErrorCode PetscViewerFlush_Draw(PetscViewer v) 28 { 29 PetscErrorCode ierr; 30 PetscInt i; 31 PetscViewer_Draw *vdraw = (PetscViewer_Draw*)v->data; 32 33 PetscFunctionBegin; 34 for (i=0; i<vdraw->draw_max; i++) { 35 if (vdraw->draw[i]) {ierr = PetscDrawFlush(vdraw->draw[i]);CHKERRQ(ierr);} 36 } 37 PetscFunctionReturn(0); 38 } 39 40 /*@C 41 PetscViewerDrawGetDraw - Returns PetscDraw object from PetscViewer object. 42 This PetscDraw object may then be used to perform graphics using 43 PetscDrawXXX() commands. 44 45 Collective on PetscViewer 46 47 Input Parameters: 48 + viewer - the PetscViewer (created with PetscViewerDrawOpen()) 49 - windownumber - indicates which subwindow (usually 0) 50 51 Ouput Parameter: 52 . draw - the draw object 53 54 Level: intermediate 55 56 .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen() 57 @*/ 58 PetscErrorCode PetscViewerDrawGetDraw(PetscViewer viewer,PetscInt windownumber,PetscDraw *draw) 59 { 60 PetscViewer_Draw *vdraw; 61 PetscErrorCode ierr; 62 PetscBool isdraw; 63 64 PetscFunctionBegin; 65 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 66 PetscValidLogicalCollectiveInt(viewer,windownumber,2); 67 if (draw) PetscValidPointer(draw,3); 68 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 69 if (!isdraw) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer"); 70 if (windownumber < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Window number cannot be negative"); 71 vdraw = (PetscViewer_Draw*)viewer->data; 72 73 windownumber += vdraw->draw_base; 74 if (windownumber >= vdraw->draw_max) { 75 /* allocate twice as many slots as needed */ 76 PetscInt draw_max = vdraw->draw_max; 77 PetscDraw *tdraw = vdraw->draw; 78 PetscDrawLG *drawlg = vdraw->drawlg; 79 PetscDrawAxis *drawaxis = vdraw->drawaxis; 80 81 vdraw->draw_max = 2*windownumber; 82 83 ierr = PetscCalloc3(vdraw->draw_max,&vdraw->draw,vdraw->draw_max,&vdraw->drawlg,vdraw->draw_max,&vdraw->drawaxis);CHKERRQ(ierr); 84 ierr = PetscArraycpy(vdraw->draw,tdraw,draw_max);CHKERRQ(ierr); 85 ierr = PetscArraycpy(vdraw->drawlg,drawlg,draw_max);CHKERRQ(ierr); 86 ierr = PetscArraycpy(vdraw->drawaxis,drawaxis,draw_max);CHKERRQ(ierr); 87 ierr = PetscFree3(tdraw,drawlg,drawaxis);CHKERRQ(ierr); 88 } 89 90 if (!vdraw->draw[windownumber]) { 91 char *title = vdraw->title, tmp_str[128]; 92 if (windownumber) { 93 ierr = PetscSNPrintf(tmp_str,sizeof(tmp_str),"%s:%d",vdraw->title?vdraw->title:"",windownumber);CHKERRQ(ierr); 94 title = tmp_str; 95 } 96 ierr = PetscDrawCreate(PetscObjectComm((PetscObject)viewer),vdraw->display,title,PETSC_DECIDE,PETSC_DECIDE,vdraw->w,vdraw->h,&vdraw->draw[windownumber]);CHKERRQ(ierr); 97 ierr = PetscLogObjectParent((PetscObject)viewer,(PetscObject)vdraw->draw[windownumber]);CHKERRQ(ierr); 98 if (vdraw->drawtype) { 99 ierr = PetscDrawSetType(vdraw->draw[windownumber],vdraw->drawtype);CHKERRQ(ierr); 100 } 101 ierr = PetscDrawSetPause(vdraw->draw[windownumber],vdraw->pause);CHKERRQ(ierr); 102 ierr = PetscDrawSetOptionsPrefix(vdraw->draw[windownumber],((PetscObject)viewer)->prefix);CHKERRQ(ierr); 103 ierr = PetscDrawSetFromOptions(vdraw->draw[windownumber]);CHKERRQ(ierr); 104 } 105 if (draw) *draw = vdraw->draw[windownumber]; 106 if (draw) PetscValidHeaderSpecific(*draw,PETSC_DRAW_CLASSID,3); 107 PetscFunctionReturn(0); 108 } 109 110 /*@C 111 PetscViewerDrawBaseAdd - add to the base integer that is added to the windownumber passed to PetscViewerDrawGetDraw() 112 113 Logically Collective on PetscViewer 114 115 Input Parameters: 116 + viewer - the PetscViewer (created with PetscViewerDrawOpen()) 117 - windownumber - how much to add to the base 118 119 Level: developer 120 121 .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), PetscViewerDrawBaseSet() 122 @*/ 123 PetscErrorCode PetscViewerDrawBaseAdd(PetscViewer viewer,PetscInt windownumber) 124 { 125 PetscViewer_Draw *vdraw; 126 PetscErrorCode ierr; 127 PetscBool isdraw; 128 129 PetscFunctionBegin; 130 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 131 PetscValidLogicalCollectiveInt(viewer,windownumber,2); 132 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 133 if (!isdraw) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer"); 134 vdraw = (PetscViewer_Draw*)viewer->data; 135 136 if (windownumber + vdraw->draw_base < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Resulting base %D cannot be negative",windownumber+vdraw->draw_base); 137 vdraw->draw_base += windownumber; 138 PetscFunctionReturn(0); 139 } 140 141 /*@C 142 PetscViewerDrawBaseSet - sets the base integer that is added to the windownumber passed to PetscViewerDrawGetDraw() 143 144 Logically Collective on PetscViewer 145 146 Input Parameters: 147 + viewer - the PetscViewer (created with PetscViewerDrawOpen()) 148 - windownumber - value to set the base 149 150 Level: developer 151 152 .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), PetscViewerDrawBaseAdd() 153 @*/ 154 PetscErrorCode PetscViewerDrawBaseSet(PetscViewer viewer,PetscInt windownumber) 155 { 156 PetscViewer_Draw *vdraw; 157 PetscErrorCode ierr; 158 PetscBool isdraw; 159 160 PetscFunctionBegin; 161 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 162 PetscValidLogicalCollectiveInt(viewer,windownumber,2); 163 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 164 if (!isdraw) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer"); 165 vdraw = (PetscViewer_Draw*)viewer->data; 166 167 if (windownumber < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Resulting base %D cannot be negative",windownumber); 168 vdraw->draw_base = windownumber; 169 PetscFunctionReturn(0); 170 } 171 172 /*@C 173 PetscViewerDrawGetDrawLG - Returns PetscDrawLG object from PetscViewer object. 174 This PetscDrawLG object may then be used to perform graphics using 175 PetscDrawLGXXX() commands. 176 177 Collective on PetscViewer 178 179 Input Parameter: 180 + PetscViewer - the PetscViewer (created with PetscViewerDrawOpen()) 181 - windownumber - indicates which subwindow (usually 0) 182 183 Ouput Parameter: 184 . draw - the draw line graph object 185 186 Level: intermediate 187 188 .seealso: PetscViewerDrawGetDraw(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen() 189 @*/ 190 PetscErrorCode PetscViewerDrawGetDrawLG(PetscViewer viewer,PetscInt windownumber,PetscDrawLG *drawlg) 191 { 192 PetscErrorCode ierr; 193 PetscBool isdraw; 194 PetscViewer_Draw *vdraw; 195 196 PetscFunctionBegin; 197 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 198 PetscValidLogicalCollectiveInt(viewer,windownumber,2); 199 PetscValidPointer(drawlg,3); 200 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 201 if (!isdraw) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer"); 202 if (windownumber < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Window number cannot be negative"); 203 vdraw = (PetscViewer_Draw*)viewer->data; 204 205 if (windownumber+vdraw->draw_base >= vdraw->draw_max || !vdraw->draw[windownumber+vdraw->draw_base]) { 206 ierr = PetscViewerDrawGetDraw(viewer,windownumber,NULL);CHKERRQ(ierr); 207 } 208 if (!vdraw->drawlg[windownumber+vdraw->draw_base]) { 209 ierr = PetscDrawLGCreate(vdraw->draw[windownumber+vdraw->draw_base],1,&vdraw->drawlg[windownumber+vdraw->draw_base]);CHKERRQ(ierr); 210 ierr = PetscLogObjectParent((PetscObject)viewer,(PetscObject)vdraw->drawlg[windownumber+vdraw->draw_base]);CHKERRQ(ierr); 211 ierr = PetscDrawLGSetFromOptions(vdraw->drawlg[windownumber+vdraw->draw_base]);CHKERRQ(ierr); 212 } 213 *drawlg = vdraw->drawlg[windownumber+vdraw->draw_base]; 214 PetscFunctionReturn(0); 215 } 216 217 /*@C 218 PetscViewerDrawGetDrawAxis - Returns PetscDrawAxis object from PetscViewer object. 219 This PetscDrawAxis object may then be used to perform graphics using 220 PetscDrawAxisXXX() commands. 221 222 Collective on PetscViewer 223 224 Input Parameter: 225 + viewer - the PetscViewer (created with PetscViewerDrawOpen() 226 - windownumber - indicates which subwindow (usually 0) 227 228 Ouput Parameter: 229 . drawaxis - the draw axis object 230 231 Level: advanced 232 233 .seealso: PetscViewerDrawGetDraw(), PetscViewerDrawGetLG(), PetscViewerDrawOpen() 234 @*/ 235 PetscErrorCode PetscViewerDrawGetDrawAxis(PetscViewer viewer,PetscInt windownumber,PetscDrawAxis *drawaxis) 236 { 237 PetscErrorCode ierr; 238 PetscBool isdraw; 239 PetscViewer_Draw *vdraw; 240 241 PetscFunctionBegin; 242 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 243 PetscValidLogicalCollectiveInt(viewer,windownumber,2); 244 PetscValidPointer(drawaxis,3); 245 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 246 if (!isdraw) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer"); 247 if (windownumber < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Window number cannot be negative"); 248 vdraw = (PetscViewer_Draw*)viewer->data; 249 250 if (windownumber+vdraw->draw_base >= vdraw->draw_max || !vdraw->draw[windownumber+vdraw->draw_base]) { 251 ierr = PetscViewerDrawGetDraw(viewer,windownumber,NULL);CHKERRQ(ierr); 252 } 253 if (!vdraw->drawaxis[windownumber+vdraw->draw_base]) { 254 ierr = PetscDrawAxisCreate(vdraw->draw[windownumber+vdraw->draw_base],&vdraw->drawaxis[windownumber+vdraw->draw_base]);CHKERRQ(ierr); 255 ierr = PetscLogObjectParent((PetscObject)viewer,(PetscObject)vdraw->drawaxis[windownumber+vdraw->draw_base]);CHKERRQ(ierr); 256 } 257 *drawaxis = vdraw->drawaxis[windownumber+vdraw->draw_base]; 258 PetscFunctionReturn(0); 259 } 260 261 PetscErrorCode PetscViewerDrawResize(PetscViewer v,int w,int h) 262 { 263 PetscErrorCode ierr; 264 PetscViewer_Draw *vdraw; 265 PetscBool isdraw; 266 267 PetscFunctionBegin; 268 PetscValidHeaderSpecific(v,PETSC_VIEWER_CLASSID,1); 269 ierr = PetscObjectTypeCompare((PetscObject)v,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 270 if (!isdraw) PetscFunctionReturn(0); 271 vdraw = (PetscViewer_Draw*)v->data; 272 273 if (w >= 1) vdraw->w = w; 274 if (h >= 1) vdraw->h = h; 275 PetscFunctionReturn(0); 276 } 277 278 PetscErrorCode PetscViewerDrawSetInfo(PetscViewer v,const char display[],const char title[],int x,int y,int w,int h) 279 { 280 PetscErrorCode ierr; 281 PetscViewer_Draw *vdraw; 282 PetscBool isdraw; 283 284 PetscFunctionBegin; 285 PetscValidHeaderSpecific(v,PETSC_VIEWER_CLASSID,1); 286 ierr = PetscObjectTypeCompare((PetscObject)v,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 287 if (!isdraw) PetscFunctionReturn(0); 288 vdraw = (PetscViewer_Draw*)v->data; 289 290 ierr = PetscStrallocpy(display,&vdraw->display);CHKERRQ(ierr); 291 ierr = PetscStrallocpy(title,&vdraw->title);CHKERRQ(ierr); 292 if (w >= 1) vdraw->w = w; 293 if (h >= 1) vdraw->h = h; 294 PetscFunctionReturn(0); 295 } 296 297 PetscErrorCode PetscViewerDrawSetDrawType(PetscViewer v,PetscDrawType drawtype) 298 { 299 PetscErrorCode ierr; 300 PetscViewer_Draw *vdraw; 301 PetscBool isdraw; 302 303 PetscFunctionBegin; 304 PetscValidHeaderSpecific(v,PETSC_VIEWER_CLASSID,1); 305 ierr = PetscObjectTypeCompare((PetscObject)v,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 306 if (!isdraw) PetscFunctionReturn(0); 307 vdraw = (PetscViewer_Draw*)v->data; 308 309 ierr = PetscFree(vdraw->drawtype);CHKERRQ(ierr); 310 ierr = PetscStrallocpy(drawtype,(char**)&vdraw->drawtype);CHKERRQ(ierr); 311 PetscFunctionReturn(0); 312 } 313 314 PetscErrorCode PetscViewerDrawGetDrawType(PetscViewer v,PetscDrawType *drawtype) 315 { 316 PetscErrorCode ierr; 317 PetscViewer_Draw *vdraw; 318 PetscBool isdraw; 319 320 PetscFunctionBegin; 321 PetscValidHeaderSpecific(v,PETSC_VIEWER_CLASSID,1); 322 ierr = PetscObjectTypeCompare((PetscObject)v,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 323 if (!isdraw) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer"); 324 vdraw = (PetscViewer_Draw*)v->data; 325 326 *drawtype = vdraw->drawtype; 327 PetscFunctionReturn(0); 328 } 329 330 PetscErrorCode PetscViewerDrawSetTitle(PetscViewer v,const char title[]) 331 { 332 PetscErrorCode ierr; 333 PetscViewer_Draw *vdraw; 334 PetscBool isdraw; 335 336 PetscFunctionBegin; 337 PetscValidHeaderSpecific(v,PETSC_VIEWER_CLASSID,1); 338 ierr = PetscObjectTypeCompare((PetscObject)v,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 339 if (!isdraw) PetscFunctionReturn(0); 340 vdraw = (PetscViewer_Draw*)v->data; 341 342 ierr = PetscFree(vdraw->title);CHKERRQ(ierr); 343 ierr = PetscStrallocpy(title,&vdraw->title);CHKERRQ(ierr); 344 PetscFunctionReturn(0); 345 } 346 347 PetscErrorCode PetscViewerDrawGetTitle(PetscViewer v,const char *title[]) 348 { 349 PetscErrorCode ierr; 350 PetscViewer_Draw *vdraw; 351 PetscBool isdraw; 352 353 PetscFunctionBegin; 354 PetscValidHeaderSpecific(v,PETSC_VIEWER_CLASSID,1); 355 ierr = PetscObjectTypeCompare((PetscObject)v,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 356 if (!isdraw) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer"); 357 vdraw = (PetscViewer_Draw*)v->data; 358 359 *title = vdraw->title; 360 PetscFunctionReturn(0); 361 } 362 363 /*@C 364 PetscViewerDrawOpen - Opens a window for use as a PetscViewer. If you want to 365 do graphics in this window, you must call PetscViewerDrawGetDraw() and 366 perform the graphics on the PetscDraw object. 367 368 Collective 369 370 Input Parameters: 371 + comm - communicator that will share window 372 . display - the X display on which to open, or null for the local machine 373 . title - the title to put in the title bar, or null for no title 374 . x, y - the screen coordinates of the upper left corner of window, or use PETSC_DECIDE 375 - w, h - window width and height in pixels, or may use PETSC_DECIDE or PETSC_DRAW_FULL_SIZE, PETSC_DRAW_HALF_SIZE, 376 PETSC_DRAW_THIRD_SIZE, PETSC_DRAW_QUARTER_SIZE 377 378 Output Parameters: 379 . viewer - the PetscViewer 380 381 Format Options: 382 + PETSC_VIEWER_DRAW_BASIC - displays with basic format 383 - PETSC_VIEWER_DRAW_LG - displays using a line graph 384 385 Options Database Keys: 386 PetscViewerDrawOpen() calls PetscDrawCreate(), so see the manual page for 387 PetscDrawCreate() for runtime options, including 388 + -draw_type x or null 389 . -nox - Disables all x-windows output 390 . -display <name> - Specifies name of machine for the X display 391 . -geometry <x,y,w,h> - allows setting the window location and size 392 - -draw_pause <pause> - Sets time (in seconds) that the 393 program pauses after PetscDrawPause() has been called 394 (0 is default, -1 implies until user input). 395 396 Level: beginner 397 398 Note for Fortran Programmers: 399 Whenever indicating null character data in a Fortran code, 400 PETSC_NULL_CHARACTER must be employed; using NULL is not 401 correct for character data! Thus, PETSC_NULL_CHARACTER can be 402 used for the display and title input parameters. 403 404 .seealso: PetscDrawCreate(), PetscViewerDestroy(), PetscViewerDrawGetDraw(), PetscViewerCreate(), PETSC_VIEWER_DRAW_, 405 PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF 406 @*/ 407 PetscErrorCode PetscViewerDrawOpen(MPI_Comm comm,const char display[],const char title[],int x,int y,int w,int h,PetscViewer *viewer) 408 { 409 PetscErrorCode ierr; 410 411 PetscFunctionBegin; 412 ierr = PetscViewerCreate(comm,viewer);CHKERRQ(ierr); 413 ierr = PetscViewerSetType(*viewer,PETSCVIEWERDRAW);CHKERRQ(ierr); 414 ierr = PetscViewerDrawSetInfo(*viewer,display,title,x,y,w,h);CHKERRQ(ierr); 415 PetscFunctionReturn(0); 416 } 417 418 #include <petsc/private/drawimpl.h> 419 420 PetscErrorCode PetscViewerGetSubViewer_Draw(PetscViewer viewer,MPI_Comm comm,PetscViewer *sviewer) 421 { 422 PetscErrorCode ierr; 423 PetscMPIInt rank; 424 PetscInt i; 425 PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data,*svdraw; 426 427 PetscFunctionBegin; 428 if (vdraw->singleton_made) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Trying to get SubViewer without first restoring previous"); 429 /* only processor zero can use the PetscViewer draw singleton */ 430 if (sviewer) *sviewer = NULL; 431 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRMPI(ierr); 432 if (!rank) { 433 PetscMPIInt flg; 434 PetscDraw draw,sdraw; 435 436 ierr = MPI_Comm_compare(PETSC_COMM_SELF,comm,&flg);CHKERRMPI(ierr); 437 if (flg != MPI_IDENT && flg != MPI_CONGRUENT) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"PetscViewerGetSubViewer() for PETSCVIEWERDRAW requires a singleton MPI_Comm"); 438 ierr = PetscViewerCreate(comm,sviewer);CHKERRQ(ierr); 439 ierr = PetscViewerSetType(*sviewer,PETSCVIEWERDRAW);CHKERRQ(ierr); 440 svdraw = (PetscViewer_Draw*)(*sviewer)->data; 441 (*sviewer)->format = viewer->format; 442 for (i=0; i<vdraw->draw_max; i++) { /* XXX this is wrong if svdraw->draw_max (initially 5) < vdraw->draw_max */ 443 if (vdraw->draw[i]) {ierr = PetscDrawGetSingleton(vdraw->draw[i],&svdraw->draw[i]);CHKERRQ(ierr);} 444 } 445 ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 446 ierr = PetscViewerDrawGetDraw(*sviewer,0,&sdraw);CHKERRQ(ierr); 447 if (draw->savefilename) { 448 ierr = PetscDrawSetSave(sdraw,draw->savefilename);CHKERRQ(ierr); 449 sdraw->savefilecount = draw->savefilecount; 450 sdraw->savesinglefile = draw->savesinglefile; 451 sdraw->savemoviefps = draw->savemoviefps; 452 sdraw->saveonclear = draw->saveonclear; 453 sdraw->saveonflush = draw->saveonflush; 454 } 455 if (draw->savefinalfilename) {ierr = PetscDrawSetSaveFinalImage(sdraw,draw->savefinalfilename);CHKERRQ(ierr);} 456 } else { 457 PetscDraw draw; 458 ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 459 } 460 vdraw->singleton_made = PETSC_TRUE; 461 PetscFunctionReturn(0); 462 } 463 464 PetscErrorCode PetscViewerRestoreSubViewer_Draw(PetscViewer viewer,MPI_Comm comm,PetscViewer *sviewer) 465 { 466 PetscErrorCode ierr; 467 PetscMPIInt rank; 468 PetscInt i; 469 PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data,*svdraw; 470 471 PetscFunctionBegin; 472 if (!vdraw->singleton_made) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Trying to restore a singleton that was not gotten"); 473 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRMPI(ierr); 474 if (!rank) { 475 PetscDraw draw,sdraw; 476 477 ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 478 ierr = PetscViewerDrawGetDraw(*sviewer,0,&sdraw);CHKERRQ(ierr); 479 if (draw->savefilename) { 480 draw->savefilecount = sdraw->savefilecount; 481 ierr = MPI_Bcast(&draw->savefilecount,1,MPIU_INT,0,PetscObjectComm((PetscObject)draw));CHKERRMPI(ierr); 482 } 483 svdraw = (PetscViewer_Draw*)(*sviewer)->data; 484 for (i=0; i<vdraw->draw_max; i++) { 485 if (vdraw->draw[i] && svdraw->draw[i]) { 486 ierr = PetscDrawRestoreSingleton(vdraw->draw[i],&svdraw->draw[i]);CHKERRQ(ierr); 487 } 488 } 489 ierr = PetscFree3(svdraw->draw,svdraw->drawlg,svdraw->drawaxis);CHKERRQ(ierr); 490 ierr = PetscFree((*sviewer)->data);CHKERRQ(ierr); 491 ierr = PetscHeaderDestroy(sviewer);CHKERRQ(ierr); 492 } else { 493 PetscDraw draw; 494 495 ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 496 if (draw->savefilename) { 497 ierr = MPI_Bcast(&draw->savefilecount,1,MPIU_INT,0,PetscObjectComm((PetscObject)draw));CHKERRMPI(ierr); 498 } 499 } 500 501 vdraw->singleton_made = PETSC_FALSE; 502 PetscFunctionReturn(0); 503 } 504 505 PetscErrorCode PetscViewerSetFromOptions_Draw(PetscOptionItems *PetscOptionsObject,PetscViewer v) 506 { 507 PetscErrorCode ierr; 508 PetscReal bounds[16]; 509 PetscInt nbounds = 16; 510 PetscBool flg; 511 512 PetscFunctionBegin; 513 ierr = PetscOptionsHead(PetscOptionsObject,"Draw PetscViewer Options");CHKERRQ(ierr); 514 ierr = PetscOptionsRealArray("-draw_bounds","Bounds to put on plots axis","PetscViewerDrawSetBounds",bounds,&nbounds,&flg);CHKERRQ(ierr); 515 if (flg) { 516 ierr = PetscViewerDrawSetBounds(v,nbounds/2,bounds);CHKERRQ(ierr); 517 } 518 ierr = PetscOptionsTail();CHKERRQ(ierr); 519 PetscFunctionReturn(0); 520 } 521 522 PetscErrorCode PetscViewerView_Draw(PetscViewer viewer,PetscViewer v) 523 { 524 PetscErrorCode ierr; 525 PetscDraw draw; 526 PetscInt i; 527 PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data; 528 529 PetscFunctionBegin; 530 /* If the PetscViewer has just been created then no vdraw->draw yet 531 exists so this will not actually call the viewer on any draws. */ 532 for (i=0; i<vdraw->draw_base; i++) { 533 if (vdraw->draw[i]) { 534 ierr = PetscViewerDrawGetDraw(viewer,i,&draw);CHKERRQ(ierr); 535 ierr = PetscDrawView(draw,v);CHKERRQ(ierr); 536 } 537 } 538 PetscFunctionReturn(0); 539 } 540 541 /*MC 542 PETSCVIEWERDRAW - A viewer that generates graphics, either to the screen or a file 543 544 .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), PETSC_VIEWER_DRAW_(),PETSC_VIEWER_DRAW_SELF, PETSC_VIEWER_DRAW_WORLD, 545 PetscViewerCreate(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PETSCVIEWERBINARY, 546 PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERASCII, PETSCVIEWERMATLAB, 547 PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType() 548 549 Level: beginner 550 551 M*/ 552 PETSC_EXTERN PetscErrorCode PetscViewerCreate_Draw(PetscViewer viewer) 553 { 554 PetscErrorCode ierr; 555 PetscViewer_Draw *vdraw; 556 557 PetscFunctionBegin; 558 ierr = PetscNewLog(viewer,&vdraw);CHKERRQ(ierr); 559 viewer->data = (void*)vdraw; 560 561 viewer->ops->flush = PetscViewerFlush_Draw; 562 viewer->ops->view = PetscViewerView_Draw; 563 viewer->ops->destroy = PetscViewerDestroy_Draw; 564 viewer->ops->setfromoptions = PetscViewerSetFromOptions_Draw; 565 viewer->ops->getsubviewer = PetscViewerGetSubViewer_Draw; 566 viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_Draw; 567 568 /* these are created on the fly if requested */ 569 vdraw->draw_max = 5; 570 vdraw->draw_base = 0; 571 vdraw->w = PETSC_DECIDE; 572 vdraw->h = PETSC_DECIDE; 573 574 ierr = PetscCalloc3(vdraw->draw_max,&vdraw->draw,vdraw->draw_max,&vdraw->drawlg,vdraw->draw_max,&vdraw->drawaxis);CHKERRQ(ierr); 575 vdraw->singleton_made = PETSC_FALSE; 576 PetscFunctionReturn(0); 577 } 578 579 /*@ 580 PetscViewerDrawClear - Clears a PetscDraw graphic associated with a PetscViewer. 581 582 Not Collective 583 584 Input Parameter: 585 . viewer - the PetscViewer 586 587 Level: intermediate 588 589 .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), 590 591 @*/ 592 PetscErrorCode PetscViewerDrawClear(PetscViewer viewer) 593 { 594 PetscErrorCode ierr; 595 PetscViewer_Draw *vdraw; 596 PetscBool isdraw; 597 PetscInt i; 598 599 PetscFunctionBegin; 600 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 601 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 602 if (!isdraw) PetscFunctionReturn(0); 603 vdraw = (PetscViewer_Draw*)viewer->data; 604 605 for (i=0; i<vdraw->draw_max; i++) { 606 if (vdraw->draw[i]) {ierr = PetscDrawClear(vdraw->draw[i]);CHKERRQ(ierr);} 607 } 608 PetscFunctionReturn(0); 609 } 610 611 /*@ 612 PetscViewerDrawGetPause - Gets a pause for the first present draw 613 614 Not Collective 615 616 Input Parameter: 617 . viewer - the PetscViewer 618 619 Output Parameter: 620 . pause - the pause value 621 622 Level: intermediate 623 624 .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), 625 626 @*/ 627 PetscErrorCode PetscViewerDrawGetPause(PetscViewer viewer,PetscReal *pause) 628 { 629 PetscErrorCode ierr; 630 PetscViewer_Draw *vdraw; 631 PetscBool isdraw; 632 PetscInt i; 633 PetscDraw draw; 634 635 PetscFunctionBegin; 636 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 637 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 638 if (!isdraw) {*pause = 0.0; PetscFunctionReturn(0);} 639 vdraw = (PetscViewer_Draw*)viewer->data; 640 641 for (i=0; i<vdraw->draw_max; i++) { 642 if (vdraw->draw[i]) { 643 ierr = PetscDrawGetPause(vdraw->draw[i],pause);CHKERRQ(ierr); 644 PetscFunctionReturn(0); 645 } 646 } 647 /* none exist yet so create one and get its pause */ 648 ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 649 ierr = PetscDrawGetPause(draw,pause);CHKERRQ(ierr); 650 PetscFunctionReturn(0); 651 } 652 653 /*@ 654 PetscViewerDrawSetPause - Sets a pause for each PetscDraw in the viewer 655 656 Not Collective 657 658 Input Parameters: 659 + viewer - the PetscViewer 660 - pause - the pause value 661 662 Level: intermediate 663 664 .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), 665 666 @*/ 667 PetscErrorCode PetscViewerDrawSetPause(PetscViewer viewer,PetscReal pause) 668 { 669 PetscErrorCode ierr; 670 PetscViewer_Draw *vdraw; 671 PetscBool isdraw; 672 PetscInt i; 673 674 PetscFunctionBegin; 675 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 676 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 677 if (!isdraw) PetscFunctionReturn(0); 678 vdraw = (PetscViewer_Draw*)viewer->data; 679 680 vdraw->pause = pause; 681 for (i=0; i<vdraw->draw_max; i++) { 682 if (vdraw->draw[i]) {ierr = PetscDrawSetPause(vdraw->draw[i],pause);CHKERRQ(ierr);} 683 } 684 PetscFunctionReturn(0); 685 } 686 687 /*@ 688 PetscViewerDrawSetHold - Holds previous image when drawing new image 689 690 Not Collective 691 692 Input Parameters: 693 + viewer - the PetscViewer 694 - hold - indicates to hold or not 695 696 Level: intermediate 697 698 .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), 699 700 @*/ 701 PetscErrorCode PetscViewerDrawSetHold(PetscViewer viewer,PetscBool hold) 702 { 703 PetscErrorCode ierr; 704 PetscViewer_Draw *vdraw; 705 PetscBool isdraw; 706 707 PetscFunctionBegin; 708 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 709 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 710 if (!isdraw) PetscFunctionReturn(0); 711 vdraw = (PetscViewer_Draw*)viewer->data; 712 713 vdraw->hold = hold; 714 PetscFunctionReturn(0); 715 } 716 717 /*@ 718 PetscViewerDrawGetHold - Checks if holds previous image when drawing new image 719 720 Not Collective 721 722 Input Parameter: 723 . viewer - the PetscViewer 724 725 Output Parameter: 726 . hold - indicates to hold or not 727 728 Level: intermediate 729 730 .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), 731 732 @*/ 733 PetscErrorCode PetscViewerDrawGetHold(PetscViewer viewer,PetscBool *hold) 734 { 735 PetscErrorCode ierr; 736 PetscViewer_Draw *vdraw; 737 PetscBool isdraw; 738 739 PetscFunctionBegin; 740 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 741 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 742 if (!isdraw) {*hold = PETSC_FALSE; PetscFunctionReturn(0);} 743 vdraw = (PetscViewer_Draw*)viewer->data; 744 745 *hold = vdraw->hold; 746 PetscFunctionReturn(0); 747 } 748 749 /* ---------------------------------------------------------------------*/ 750 /* 751 The variable Petsc_Viewer_Draw_keyval is used to indicate an MPI attribute that 752 is attached to a communicator, in this case the attribute is a PetscViewer. 753 */ 754 PetscMPIInt Petsc_Viewer_Draw_keyval = MPI_KEYVAL_INVALID; 755 756 /*@C 757 PETSC_VIEWER_DRAW_ - Creates a window PetscViewer shared by all processors 758 in a communicator. 759 760 Collective 761 762 Input Parameter: 763 . comm - the MPI communicator to share the window PetscViewer 764 765 Level: intermediate 766 767 Notes: 768 Unlike almost all other PETSc routines, PETSC_VIEWER_DRAW_ does not return 769 an error code. The window is usually used in the form 770 $ XXXView(XXX object,PETSC_VIEWER_DRAW_(comm)); 771 772 .seealso: PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF, PetscViewerDrawOpen(), 773 @*/ 774 PetscViewer PETSC_VIEWER_DRAW_(MPI_Comm comm) 775 { 776 PetscErrorCode ierr; 777 PetscMPIInt flag; 778 PetscViewer viewer; 779 MPI_Comm ncomm; 780 781 PetscFunctionBegin; 782 ierr = PetscCommDuplicate(comm,&ncomm,NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);} 783 if (Petsc_Viewer_Draw_keyval == MPI_KEYVAL_INVALID) { 784 ierr = MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,MPI_COMM_NULL_DELETE_FN,&Petsc_Viewer_Draw_keyval,NULL); 785 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);} 786 } 787 ierr = MPI_Comm_get_attr(ncomm,Petsc_Viewer_Draw_keyval,(void**)&viewer,&flag); 788 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);} 789 if (!flag) { /* PetscViewer not yet created */ 790 ierr = PetscViewerDrawOpen(ncomm,NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,300,300,&viewer); 791 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");PetscFunctionReturn(NULL);} 792 ierr = PetscObjectRegisterDestroy((PetscObject)viewer); 793 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");PetscFunctionReturn(NULL);} 794 ierr = MPI_Comm_set_attr(ncomm,Petsc_Viewer_Draw_keyval,(void*)viewer); 795 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);} 796 } 797 ierr = PetscCommDestroy(&ncomm); 798 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");PetscFunctionReturn(NULL);} 799 PetscFunctionReturn(viewer); 800 } 801 802 /*@ 803 PetscViewerDrawSetBounds - sets the upper and lower bounds to be used in plotting 804 805 Collective on PetscViewer 806 807 Input Parameters: 808 + viewer - the PetscViewer (created with PetscViewerDrawOpen()) 809 . nbounds - number of plots that can be made with this viewer, for example the dof passed to DMDACreate() 810 - bounds - the actual bounds, the size of this is 2*nbounds, the values are stored in the order min F_0, max F_0, min F_1, max F_1, ..... 811 812 Options Database: 813 . -draw_bounds minF0,maxF0,minF1,maxF1 814 815 Level: intermediate 816 817 Notes: 818 this determines the colors used in 2d contour plots generated with VecView() for DMDA in 2d. Any values in the vector below or above the 819 bounds are moved to the bound value before plotting. In this way the color index from color to physical value remains the same for all plots generated with 820 this viewer. Otherwise the color to physical value meaning changes with each new image if this is not set. 821 822 .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen() 823 @*/ 824 PetscErrorCode PetscViewerDrawSetBounds(PetscViewer viewer,PetscInt nbounds,const PetscReal *bounds) 825 { 826 PetscViewer_Draw *vdraw; 827 PetscBool isdraw; 828 PetscErrorCode ierr; 829 830 PetscFunctionBegin; 831 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 832 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 833 if (!isdraw) PetscFunctionReturn(0); 834 vdraw = (PetscViewer_Draw*)viewer->data; 835 836 vdraw->nbounds = nbounds; 837 ierr = PetscFree(vdraw->bounds);CHKERRQ(ierr); 838 ierr = PetscMalloc1(2*nbounds,&vdraw->bounds);CHKERRQ(ierr); 839 ierr = PetscArraycpy(vdraw->bounds,bounds,2*nbounds);CHKERRQ(ierr); 840 PetscFunctionReturn(0); 841 } 842 843 /*@C 844 PetscViewerDrawGetBounds - gets the upper and lower bounds to be used in plotting set with PetscViewerDrawSetBounds() 845 846 Collective on PetscViewer 847 848 Input Parameter: 849 . viewer - the PetscViewer (created with PetscViewerDrawOpen()) 850 851 Output Parameters: 852 + nbounds - number of plots that can be made with this viewer, for example the dof passed to DMDACreate() 853 - bounds - the actual bounds, the size of this is 2*nbounds, the values are stored in the order min F_0, max F_0, min F_1, max F_1, ..... 854 855 Level: intermediate 856 857 .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen(), PetscViewerDrawSetBounds() 858 @*/ 859 PetscErrorCode PetscViewerDrawGetBounds(PetscViewer viewer,PetscInt *nbounds,const PetscReal **bounds) 860 { 861 PetscViewer_Draw *vdraw; 862 PetscBool isdraw; 863 PetscErrorCode ierr; 864 865 PetscFunctionBegin; 866 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 867 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 868 if (!isdraw) {if (nbounds) *nbounds = 0; if (bounds) *bounds = NULL; PetscFunctionReturn(0);} 869 vdraw = (PetscViewer_Draw*)viewer->data; 870 871 if (nbounds) *nbounds = vdraw->nbounds; 872 if (bounds) *bounds = vdraw->bounds; 873 PetscFunctionReturn(0); 874 } 875