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