1 #include <../src/sys/classes/viewer/impls/draw/vdraw.h> /*I "petscdraw.h" I*/ 2 #include <petscviewer.h> /*I "petscviewer.h" I*/ 3 4 static PetscErrorCode PetscViewerDestroy_Draw(PetscViewer v) 5 { 6 PetscInt i; 7 PetscViewer_Draw *vdraw = (PetscViewer_Draw *)v->data; 8 9 PetscFunctionBegin; 10 PetscCheck(!vdraw->singleton_made, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Destroying PetscViewer without first restoring singleton"); 11 for (i = 0; i < vdraw->draw_max; i++) { 12 PetscCall(PetscDrawAxisDestroy(&vdraw->drawaxis[i])); 13 PetscCall(PetscDrawLGDestroy(&vdraw->drawlg[i])); 14 PetscCall(PetscDrawDestroy(&vdraw->draw[i])); 15 } 16 PetscCall(PetscFree(vdraw->display)); 17 PetscCall(PetscFree(vdraw->title)); 18 PetscCall(PetscFree3(vdraw->draw, vdraw->drawlg, vdraw->drawaxis)); 19 PetscCall(PetscFree(vdraw->bounds)); 20 PetscCall(PetscFree(vdraw->drawtype)); 21 PetscCall(PetscFree(v->data)); 22 PetscFunctionReturn(PETSC_SUCCESS); 23 } 24 25 static PetscErrorCode PetscViewerFlush_Draw(PetscViewer v) 26 { 27 PetscInt i; 28 PetscViewer_Draw *vdraw = (PetscViewer_Draw *)v->data; 29 30 PetscFunctionBegin; 31 for (i = 0; i < vdraw->draw_max; i++) { 32 if (vdraw->draw[i]) PetscCall(PetscDrawFlush(vdraw->draw[i])); 33 } 34 PetscFunctionReturn(PETSC_SUCCESS); 35 } 36 37 /*@ 38 PetscViewerDrawBaseAdd - add to the base integer that is added to the `windownumber` passed to `PetscViewerDrawGetDraw()` 39 40 Logically Collective 41 42 Input Parameters: 43 + viewer - the `PetscViewer` (created with `PetscViewerDrawOpen()`) 44 - windownumber - how much to add to the base 45 46 Level: developer 47 48 Note: 49 A `PETSCVIEWERDRAW` may have multiple `PetscDraw` subwindows, this increases the number of the subwindow that is returned with `PetscViewerDrawGetDraw()` 50 51 .seealso: [](sec_viewers), `PetscViewerDrawGetLG()`, `PetscViewerDrawGetAxis()`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`, `PetscViewerDrawBaseSet()` 52 @*/ 53 PetscErrorCode PetscViewerDrawBaseAdd(PetscViewer viewer, PetscInt windownumber) 54 { 55 PetscViewer_Draw *vdraw; 56 PetscBool isdraw; 57 58 PetscFunctionBegin; 59 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 60 PetscValidLogicalCollectiveInt(viewer, windownumber, 2); 61 PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw)); 62 PetscCheck(isdraw, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Must be draw type PetscViewer"); 63 vdraw = (PetscViewer_Draw *)viewer->data; 64 65 PetscCheck(windownumber + vdraw->draw_base >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Resulting base %" PetscInt_FMT " cannot be negative", windownumber + vdraw->draw_base); 66 vdraw->draw_base += windownumber; 67 PetscFunctionReturn(PETSC_SUCCESS); 68 } 69 70 /*@ 71 PetscViewerDrawBaseSet - sets the base integer that is added to the `windownumber` passed to `PetscViewerDrawGetDraw()` 72 73 Logically Collective 74 75 Input Parameters: 76 + viewer - the `PetscViewer` (created with `PetscViewerDrawOpen()`) 77 - windownumber - value to set the base 78 79 Level: developer 80 81 Note: 82 A `PETSCVIEWERDRAW` may have multiple `PetscDraw` subwindows, this increases the number of the subwindow that is returned with `PetscViewerDrawGetDraw()` 83 84 .seealso: [](sec_viewers), `PetscViewerDrawGetLG()`, `PetscViewerDrawGetAxis()`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`, `PetscViewerDrawBaseAdd()` 85 @*/ 86 PetscErrorCode PetscViewerDrawBaseSet(PetscViewer viewer, PetscInt windownumber) 87 { 88 PetscViewer_Draw *vdraw; 89 PetscBool isdraw; 90 91 PetscFunctionBegin; 92 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 93 PetscValidLogicalCollectiveInt(viewer, windownumber, 2); 94 PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw)); 95 PetscCheck(isdraw, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Must be draw type PetscViewer"); 96 vdraw = (PetscViewer_Draw *)viewer->data; 97 98 PetscCheck(windownumber >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Resulting base %" PetscInt_FMT " cannot be negative", windownumber); 99 vdraw->draw_base = windownumber; 100 PetscFunctionReturn(PETSC_SUCCESS); 101 } 102 103 PetscErrorCode PetscViewerDrawResize(PetscViewer v, int w, int h) 104 { 105 PetscViewer_Draw *vdraw; 106 PetscBool isdraw; 107 108 PetscFunctionBegin; 109 PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 1); 110 PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERDRAW, &isdraw)); 111 if (!isdraw) PetscFunctionReturn(PETSC_SUCCESS); 112 vdraw = (PetscViewer_Draw *)v->data; 113 114 if (w >= 1) vdraw->w = w; 115 if (h >= 1) vdraw->h = h; 116 PetscFunctionReturn(PETSC_SUCCESS); 117 } 118 119 PetscErrorCode PetscViewerDrawSetInfo(PetscViewer v, const char display[], const char title[], int x, int y, int w, int h) 120 { 121 PetscViewer_Draw *vdraw; 122 PetscBool isdraw; 123 124 PetscFunctionBegin; 125 PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 1); 126 PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERDRAW, &isdraw)); 127 if (!isdraw) PetscFunctionReturn(PETSC_SUCCESS); 128 vdraw = (PetscViewer_Draw *)v->data; 129 130 PetscCall(PetscStrallocpy(display, &vdraw->display)); 131 PetscCall(PetscStrallocpy(title, &vdraw->title)); 132 if (w >= 1) vdraw->w = w; 133 if (h >= 1) vdraw->h = h; 134 PetscFunctionReturn(PETSC_SUCCESS); 135 } 136 137 PetscErrorCode PetscViewerDrawSetTitle(PetscViewer v, const char title[]) 138 { 139 PetscViewer_Draw *vdraw; 140 PetscBool isdraw; 141 142 PetscFunctionBegin; 143 PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 1); 144 PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERDRAW, &isdraw)); 145 if (!isdraw) PetscFunctionReturn(PETSC_SUCCESS); 146 vdraw = (PetscViewer_Draw *)v->data; 147 148 PetscCall(PetscFree(vdraw->title)); 149 PetscCall(PetscStrallocpy(title, &vdraw->title)); 150 PetscFunctionReturn(PETSC_SUCCESS); 151 } 152 153 PetscErrorCode PetscViewerDrawGetTitle(PetscViewer v, const char *title[]) 154 { 155 PetscViewer_Draw *vdraw; 156 PetscBool isdraw; 157 158 PetscFunctionBegin; 159 PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 1); 160 PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERDRAW, &isdraw)); 161 PetscCheck(isdraw, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Must be draw type PetscViewer"); 162 vdraw = (PetscViewer_Draw *)v->data; 163 164 *title = vdraw->title; 165 PetscFunctionReturn(PETSC_SUCCESS); 166 } 167 168 /*@ 169 PetscViewerDrawOpen - Opens a `PetscDraw` window for use as a `PetscViewer` with type 170 `PETSCVIEWERDRAW`. 171 172 Collective 173 174 Input Parameters: 175 + comm - communicator that will share window 176 . display - the X display on which to open, or `NULL` for the local machine 177 . title - the title to put in the title bar, or `NULL` for no title 178 . x - horizontal screen coordinate of the upper left corner of window, or use `PETSC_DECIDE` 179 . y - vertical screen coordinate of the upper left corner of window, or use `PETSC_DECIDE` 180 . w - window width in pixels, or may use `PETSC_DECIDE` or `PETSC_DRAW_FULL_SIZE`, `PETSC_DRAW_HALF_SIZE`,`PETSC_DRAW_THIRD_SIZE`, `PETSC_DRAW_QUARTER_SIZE` 181 - h - window height in pixels, or may use `PETSC_DECIDE` or `PETSC_DRAW_FULL_SIZE`, `PETSC_DRAW_HALF_SIZE`,`PETSC_DRAW_THIRD_SIZE`, `PETSC_DRAW_QUARTER_SIZE` 182 183 Output Parameter: 184 . viewer - the `PetscViewer` 185 186 Options Database Keys: 187 + -draw_type - use x or null 188 . -nox - Disables all x-windows output 189 . -display <name> - Specifies name of machine for the X display 190 . -geometry <x,y,w,h> - allows setting the window location and size 191 - -draw_pause <pause> - Sets time (in seconds) that the 192 program pauses after PetscDrawPause() has been called 193 (0 is default, -1 implies until user input). 194 195 Level: beginner 196 197 Notes: 198 If you want to do graphics in this window, you must call `PetscViewerDrawGetDraw()` and 199 perform the graphics on the `PetscDraw` object. 200 201 Format options include\: 202 + `PETSC_VIEWER_DRAW_BASIC` - displays with basic format 203 - `PETSC_VIEWER_DRAW_LG` - displays using a line graph 204 205 Fortran Notes: 206 Whenever indicating null character data in a Fortran code, 207 `PETSC_NULL_CHARACTER` must be employed; using NULL is not 208 correct for character data! Thus, `PETSC_NULL_CHARACTER` can be 209 used for the display and title input parameters. 210 211 .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscDrawCreate()`, `PetscViewerDestroy()`, `PetscViewerDrawGetDraw()`, `PetscViewerCreate()`, `PETSC_VIEWER_DRAW_`, 212 `PETSC_VIEWER_DRAW_WORLD`, `PETSC_VIEWER_DRAW_SELF` 213 @*/ 214 PetscErrorCode PetscViewerDrawOpen(MPI_Comm comm, const char display[], const char title[], int x, int y, int w, int h, PetscViewer *viewer) 215 { 216 PetscFunctionBegin; 217 PetscCall(PetscViewerCreate(comm, viewer)); 218 PetscCall(PetscViewerSetType(*viewer, PETSCVIEWERDRAW)); 219 PetscCall(PetscViewerDrawSetInfo(*viewer, display, title, x, y, w, h)); 220 PetscFunctionReturn(PETSC_SUCCESS); 221 } 222 223 #include <petsc/private/drawimpl.h> 224 225 static PetscErrorCode PetscViewerGetSubViewer_Draw(PetscViewer viewer, MPI_Comm comm, PetscViewer *sviewer) 226 { 227 PetscMPIInt rank; 228 PetscInt i; 229 PetscViewer_Draw *vdraw = (PetscViewer_Draw *)viewer->data, *svdraw; 230 231 PetscFunctionBegin; 232 PetscCheck(!vdraw->singleton_made, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Trying to get SubViewer without first restoring previous"); 233 /* only processor zero can use the PetscViewer draw singleton */ 234 PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank)); 235 if (rank == 0) { 236 PetscMPIInt flg; 237 PetscDraw draw, sdraw; 238 239 PetscCallMPI(MPI_Comm_compare(PETSC_COMM_SELF, comm, &flg)); 240 PetscCheck(flg == MPI_IDENT || flg == MPI_CONGRUENT, PETSC_COMM_SELF, PETSC_ERR_SUP, "PetscViewerGetSubViewer() for PETSCVIEWERDRAW requires a singleton MPI_Comm"); 241 PetscCall(PetscViewerCreate(comm, sviewer)); 242 PetscCall(PetscViewerSetType(*sviewer, PETSCVIEWERDRAW)); 243 svdraw = (PetscViewer_Draw *)(*sviewer)->data; 244 (*sviewer)->format = viewer->format; 245 for (i = 0; i < vdraw->draw_max; i++) { /* XXX this is wrong if svdraw->draw_max (initially 5) < vdraw->draw_max */ 246 if (vdraw->draw[i]) PetscCall(PetscDrawGetSingleton(vdraw->draw[i], &svdraw->draw[i])); 247 } 248 PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw)); 249 PetscCall(PetscViewerDrawGetDraw(*sviewer, 0, &sdraw)); 250 if (draw->savefilename) { 251 PetscCall(PetscDrawSetSave(sdraw, draw->savefilename)); 252 sdraw->savefilecount = draw->savefilecount; 253 sdraw->savesinglefile = draw->savesinglefile; 254 sdraw->savemoviefps = draw->savemoviefps; 255 sdraw->saveonclear = draw->saveonclear; 256 sdraw->saveonflush = draw->saveonflush; 257 } 258 if (draw->savefinalfilename) PetscCall(PetscDrawSetSaveFinalImage(sdraw, draw->savefinalfilename)); 259 } else { 260 PetscDraw draw; 261 PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw)); 262 } 263 vdraw->singleton_made = PETSC_TRUE; 264 PetscFunctionReturn(PETSC_SUCCESS); 265 } 266 267 static PetscErrorCode PetscViewerRestoreSubViewer_Draw(PetscViewer viewer, MPI_Comm comm, PetscViewer *sviewer) 268 { 269 PetscMPIInt rank; 270 PetscInt i; 271 PetscViewer_Draw *vdraw = (PetscViewer_Draw *)viewer->data, *svdraw; 272 273 PetscFunctionBegin; 274 PetscCheck(vdraw->singleton_made, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Trying to restore a singleton that was not gotten"); 275 PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank)); 276 if (rank == 0) { 277 PetscDraw draw, sdraw; 278 279 PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw)); 280 PetscCall(PetscViewerDrawGetDraw(*sviewer, 0, &sdraw)); 281 if (draw->savefilename) { 282 draw->savefilecount = sdraw->savefilecount; 283 PetscCallMPI(MPI_Bcast(&draw->savefilecount, 1, MPIU_INT, 0, PetscObjectComm((PetscObject)draw))); 284 } 285 svdraw = (PetscViewer_Draw *)(*sviewer)->data; 286 for (i = 0; i < vdraw->draw_max; i++) { 287 if (vdraw->draw[i] && svdraw->draw[i]) PetscCall(PetscDrawRestoreSingleton(vdraw->draw[i], &svdraw->draw[i])); 288 } 289 PetscCall(PetscFree3(svdraw->draw, svdraw->drawlg, svdraw->drawaxis)); 290 PetscCall(PetscFree((*sviewer)->data)); 291 PetscCall(PetscHeaderDestroy(sviewer)); 292 } else { 293 PetscDraw draw; 294 295 PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw)); 296 if (draw->savefilename) PetscCallMPI(MPI_Bcast(&draw->savefilecount, 1, MPIU_INT, 0, PetscObjectComm((PetscObject)draw))); 297 } 298 299 vdraw->singleton_made = PETSC_FALSE; 300 PetscFunctionReturn(PETSC_SUCCESS); 301 } 302 303 static PetscErrorCode PetscViewerSetFromOptions_Draw(PetscViewer v, PetscOptionItems PetscOptionsObject) 304 { 305 PetscReal bounds[16]; 306 PetscInt nbounds = 16; 307 PetscBool flg; 308 309 PetscFunctionBegin; 310 PetscOptionsHeadBegin(PetscOptionsObject, "Draw PetscViewer Options"); 311 PetscCall(PetscOptionsRealArray("-draw_bounds", "Bounds to put on plots axis", "PetscViewerDrawSetBounds", bounds, &nbounds, &flg)); 312 if (flg) PetscCall(PetscViewerDrawSetBounds(v, nbounds / 2, bounds)); 313 PetscOptionsHeadEnd(); 314 PetscFunctionReturn(PETSC_SUCCESS); 315 } 316 317 static PetscErrorCode PetscViewerView_Draw(PetscViewer viewer, PetscViewer v) 318 { 319 PetscDraw draw; 320 PetscInt i; 321 PetscViewer_Draw *vdraw = (PetscViewer_Draw *)viewer->data; 322 PetscBool iascii; 323 324 PetscFunctionBegin; 325 PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERASCII, &iascii)); 326 if (iascii) PetscCall(PetscViewerASCIIPrintf(v, "Draw viewer is of type %s\n", vdraw->drawtype)); 327 /* If the PetscViewer has just been created then no vdraw->draw yet 328 exists so this will not actually call the viewer on any draws. */ 329 for (i = 0; i < vdraw->draw_base; i++) { 330 if (vdraw->draw[i]) { 331 PetscCall(PetscViewerDrawGetDraw(viewer, i, &draw)); 332 PetscCall(PetscDrawView(draw, v)); 333 } 334 } 335 PetscFunctionReturn(PETSC_SUCCESS); 336 } 337 338 /*MC 339 PETSCVIEWERDRAW - A viewer that generates graphics, either to the screen or a file 340 341 Level: beginner 342 343 .seealso: [](sec_viewers), `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`, `PETSC_VIEWER_DRAW_()`, `PETSC_VIEWER_DRAW_SELF`, `PETSC_VIEWER_DRAW_WORLD`, 344 `PetscViewerCreate()`, `PetscViewerASCIIOpen()`, `PetscViewerBinaryOpen()`, `PETSCVIEWERBINARY`, 345 `PetscViewerMatlabOpen()`, `VecView()`, `DMView()`, `PetscViewerMatlabPutArray()`, `PETSCVIEWERASCII`, `PETSCVIEWERMATLAB`, 346 `PetscViewerFileSetName()`, `PetscViewerFileSetMode()`, `PetscViewerFormat`, `PetscViewerType`, `PetscViewerSetType()` 347 M*/ 348 PETSC_EXTERN PetscErrorCode PetscViewerCreate_Draw(PetscViewer viewer) 349 { 350 PetscViewer_Draw *vdraw; 351 352 PetscFunctionBegin; 353 PetscCall(PetscNew(&vdraw)); 354 viewer->data = (void *)vdraw; 355 356 viewer->ops->flush = PetscViewerFlush_Draw; 357 viewer->ops->view = PetscViewerView_Draw; 358 viewer->ops->destroy = PetscViewerDestroy_Draw; 359 viewer->ops->setfromoptions = PetscViewerSetFromOptions_Draw; 360 viewer->ops->getsubviewer = PetscViewerGetSubViewer_Draw; 361 viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_Draw; 362 363 /* these are created on the fly if requested */ 364 vdraw->draw_max = 5; 365 vdraw->draw_base = 0; 366 vdraw->w = PETSC_DECIDE; 367 vdraw->h = PETSC_DECIDE; 368 369 PetscCall(PetscCalloc3(vdraw->draw_max, &vdraw->draw, vdraw->draw_max, &vdraw->drawlg, vdraw->draw_max, &vdraw->drawaxis)); 370 vdraw->singleton_made = PETSC_FALSE; 371 PetscFunctionReturn(PETSC_SUCCESS); 372 } 373 374 /*@ 375 PetscViewerDrawClear - Clears a `PetscDraw` graphic associated with a `PetscViewer`. 376 377 Not Collective 378 379 Input Parameter: 380 . viewer - the `PetscViewer` 381 382 Level: intermediate 383 384 .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`, 385 @*/ 386 PetscErrorCode PetscViewerDrawClear(PetscViewer viewer) 387 { 388 PetscViewer_Draw *vdraw; 389 PetscBool isdraw; 390 PetscInt i; 391 392 PetscFunctionBegin; 393 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 394 PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw)); 395 if (!isdraw) PetscFunctionReturn(PETSC_SUCCESS); 396 vdraw = (PetscViewer_Draw *)viewer->data; 397 398 for (i = 0; i < vdraw->draw_max; i++) { 399 if (vdraw->draw[i]) PetscCall(PetscDrawClear(vdraw->draw[i])); 400 } 401 PetscFunctionReturn(PETSC_SUCCESS); 402 } 403 404 /*@ 405 PetscViewerDrawGetPause - Gets the pause value (how long to pause before an image is changed) in the `PETSCVIEWERDRAW` `PetscViewer` 406 407 Not Collective 408 409 Input Parameter: 410 . viewer - the `PetscViewer` 411 412 Output Parameter: 413 . pause - the pause value 414 415 Level: intermediate 416 417 .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`, 418 @*/ 419 PetscErrorCode PetscViewerDrawGetPause(PetscViewer viewer, PetscReal *pause) 420 { 421 PetscViewer_Draw *vdraw; 422 PetscBool isdraw; 423 PetscInt i; 424 PetscDraw draw; 425 426 PetscFunctionBegin; 427 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 428 PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw)); 429 if (!isdraw) { 430 *pause = 0.0; 431 PetscFunctionReturn(PETSC_SUCCESS); 432 } 433 vdraw = (PetscViewer_Draw *)viewer->data; 434 435 for (i = 0; i < vdraw->draw_max; i++) { 436 if (vdraw->draw[i]) { 437 PetscCall(PetscDrawGetPause(vdraw->draw[i], pause)); 438 PetscFunctionReturn(PETSC_SUCCESS); 439 } 440 } 441 /* none exist yet so create one and get its pause */ 442 PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw)); 443 PetscCall(PetscDrawGetPause(draw, pause)); 444 PetscFunctionReturn(PETSC_SUCCESS); 445 } 446 447 /*@ 448 PetscViewerDrawSetPause - Sets a pause for each `PetscDraw` in the `PETSCVIEWERDRAW` `PetscViewer` 449 450 Not Collective 451 452 Input Parameters: 453 + viewer - the `PetscViewer` 454 - pause - the pause value 455 456 Level: intermediate 457 458 .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`, 459 @*/ 460 PetscErrorCode PetscViewerDrawSetPause(PetscViewer viewer, PetscReal pause) 461 { 462 PetscViewer_Draw *vdraw; 463 PetscBool isdraw; 464 PetscInt i; 465 466 PetscFunctionBegin; 467 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 468 PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw)); 469 if (!isdraw) PetscFunctionReturn(PETSC_SUCCESS); 470 vdraw = (PetscViewer_Draw *)viewer->data; 471 472 vdraw->pause = pause; 473 for (i = 0; i < vdraw->draw_max; i++) { 474 if (vdraw->draw[i]) PetscCall(PetscDrawSetPause(vdraw->draw[i], pause)); 475 } 476 PetscFunctionReturn(PETSC_SUCCESS); 477 } 478 479 /*@ 480 PetscViewerDrawSetHold - Holds previous image when drawing new image in a `PETSCVIEWERDRAW` 481 482 Not Collective 483 484 Input Parameters: 485 + viewer - the `PetscViewer` 486 - hold - `PETSC_TRUE` indicates to hold the previous image 487 488 Level: intermediate 489 490 .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`, 491 @*/ 492 PetscErrorCode PetscViewerDrawSetHold(PetscViewer viewer, PetscBool hold) 493 { 494 PetscViewer_Draw *vdraw; 495 PetscBool isdraw; 496 497 PetscFunctionBegin; 498 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 499 PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw)); 500 if (!isdraw) PetscFunctionReturn(PETSC_SUCCESS); 501 vdraw = (PetscViewer_Draw *)viewer->data; 502 503 vdraw->hold = hold; 504 PetscFunctionReturn(PETSC_SUCCESS); 505 } 506 507 /*@ 508 PetscViewerDrawGetHold - Checks if the `PETSCVIEWERDRAW` `PetscViewer` holds previous image when drawing new image 509 510 Not Collective 511 512 Input Parameter: 513 . viewer - the `PetscViewer` 514 515 Output Parameter: 516 . hold - indicates to hold or not 517 518 Level: intermediate 519 520 .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`, 521 @*/ 522 PetscErrorCode PetscViewerDrawGetHold(PetscViewer viewer, PetscBool *hold) 523 { 524 PetscViewer_Draw *vdraw; 525 PetscBool isdraw; 526 527 PetscFunctionBegin; 528 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 529 PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw)); 530 if (!isdraw) { 531 *hold = PETSC_FALSE; 532 PetscFunctionReturn(PETSC_SUCCESS); 533 } 534 vdraw = (PetscViewer_Draw *)viewer->data; 535 536 *hold = vdraw->hold; 537 PetscFunctionReturn(PETSC_SUCCESS); 538 } 539 540 /* 541 The variable Petsc_Viewer_Draw_keyval is used to indicate an MPI attribute that 542 is attached to a communicator, in this case the attribute is a PetscViewer. 543 */ 544 PetscMPIInt Petsc_Viewer_Draw_keyval = MPI_KEYVAL_INVALID; 545 546 /*@C 547 PETSC_VIEWER_DRAW_ - Creates a window `PETSCVIEWERDRAW` `PetscViewer` shared by all processors 548 in an MPI communicator. 549 550 Collective 551 552 Input Parameter: 553 . comm - the MPI communicator to share the window `PetscViewer` 554 555 Level: intermediate 556 557 Notes: 558 This object is destroyed in `PetscFinalize()`, `PetscViewerDestroy()` should never be called on it 559 560 Unlike almost all other PETSc routines, `PETSC_VIEWER_DRAW_()` does not return 561 an error code. The window is usually used in the form 562 .vb 563 XXXView(XXX object, PETSC_VIEWER_DRAW_(comm)); 564 .ve 565 566 .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewer`, `PETSC_VIEWER_DRAW_WORLD`, `PETSC_VIEWER_DRAW_SELF`, `PetscViewerDrawOpen()`, 567 @*/ 568 PetscViewer PETSC_VIEWER_DRAW_(MPI_Comm comm) 569 { 570 PetscMPIInt flag; 571 PetscViewer viewer; 572 MPI_Comm ncomm; 573 574 PetscFunctionBegin; 575 PetscCallNull(PetscCommDuplicate(comm, &ncomm, NULL)); 576 if (Petsc_Viewer_Draw_keyval == MPI_KEYVAL_INVALID) { PetscCallMPINull(MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN, MPI_COMM_NULL_DELETE_FN, &Petsc_Viewer_Draw_keyval, NULL)); } 577 PetscCallMPINull(MPI_Comm_get_attr(ncomm, Petsc_Viewer_Draw_keyval, (void **)&viewer, &flag)); 578 if (!flag) { /* PetscViewer not yet created */ 579 PetscCallNull(PetscViewerDrawOpen(ncomm, NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 300, 300, &viewer)); 580 PetscCallNull(PetscObjectRegisterDestroy((PetscObject)viewer)); 581 PetscCallMPINull(MPI_Comm_set_attr(ncomm, Petsc_Viewer_Draw_keyval, (void *)viewer)); 582 } 583 PetscCallNull(PetscCommDestroy(&ncomm)); 584 PetscFunctionReturn(viewer); 585 } 586 587 /*@ 588 PetscViewerDrawSetBounds - sets the upper and lower bounds to be used in plotting in a `PETSCVIEWERDRAW` `PetscViewer` 589 590 Collective 591 592 Input Parameters: 593 + viewer - the Petsc`Viewer` (created with `PetscViewerDrawOpen()`) 594 . nbounds - number of plots that can be made with this viewer, for example the dof passed to `DMDACreate()` 595 - 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, ..... 596 597 Options Database Key: 598 . -draw_bounds minF0,maxF0,minF1,maxF1 - the lower left and upper right bounds 599 600 Level: intermediate 601 602 Note: 603 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 604 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 605 this viewer. Otherwise the color to physical value meaning changes with each new image if this is not set. 606 607 .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewerDrawGetLG()`, `PetscViewerDrawGetAxis()`, `PetscViewerDrawOpen()` 608 @*/ 609 PetscErrorCode PetscViewerDrawSetBounds(PetscViewer viewer, PetscInt nbounds, const PetscReal *bounds) 610 { 611 PetscViewer_Draw *vdraw; 612 PetscBool isdraw; 613 614 PetscFunctionBegin; 615 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 616 PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw)); 617 if (!isdraw) PetscFunctionReturn(PETSC_SUCCESS); 618 vdraw = (PetscViewer_Draw *)viewer->data; 619 620 vdraw->nbounds = nbounds; 621 PetscCall(PetscFree(vdraw->bounds)); 622 PetscCall(PetscMalloc1(2 * nbounds, &vdraw->bounds)); 623 PetscCall(PetscArraycpy(vdraw->bounds, bounds, 2 * nbounds)); 624 PetscFunctionReturn(PETSC_SUCCESS); 625 } 626 627 /*@C 628 PetscViewerDrawGetBounds - gets the upper and lower bounds to be used in plotting set with `PetscViewerDrawSetBounds()` 629 630 Collective 631 632 Input Parameter: 633 . viewer - the `PetscViewer` (created with `PetscViewerDrawOpen()`) 634 635 Output Parameters: 636 + nbounds - number of plots that can be made with this viewer, for example the dof passed to `DMDACreate()` 637 - 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, ..... 638 639 Level: intermediate 640 641 .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewerDrawGetLG()`, `PetscViewerDrawGetAxis()`, `PetscViewerDrawOpen()`, `PetscViewerDrawSetBounds()` 642 @*/ 643 PetscErrorCode PetscViewerDrawGetBounds(PetscViewer viewer, PetscInt *nbounds, const PetscReal *bounds[]) 644 { 645 PetscViewer_Draw *vdraw; 646 PetscBool isdraw; 647 648 PetscFunctionBegin; 649 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 650 PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw)); 651 if (!isdraw) { 652 if (nbounds) *nbounds = 0; 653 if (bounds) *bounds = NULL; 654 PetscFunctionReturn(PETSC_SUCCESS); 655 } 656 vdraw = (PetscViewer_Draw *)viewer->data; 657 658 if (nbounds) *nbounds = vdraw->nbounds; 659 if (bounds) *bounds = vdraw->bounds; 660 PetscFunctionReturn(PETSC_SUCCESS); 661 } 662 663 /*@C 664 PetscViewerMonitorLGSetUp - sets up a viewer to be used by line graph monitoring routines such as `KSPMonitorResidualDrawLG()` 665 666 Collective 667 668 Input Parameters: 669 + viewer - the viewer in which to display the line graphs, it not a `PETSCVIEWERDRAW` it will set to that `PetscViewerType` 670 . host - the host to open the window on, 'NULL' indicates the local host 671 . title - the title at the top of the window 672 . metric - the label above the graph 673 . l - the number of curves 674 . names - the names of each curve to be used in displaying the legend. May be 'NULL' 675 . x - horizontal screen coordinate of the upper left corner of window, or use `PETSC_DECIDE` 676 . y - vertical screen coordinate of the upper left corner of window, or use `PETSC_DECIDE` 677 . m - window width in pixels, or may use `PETSC_DECIDE` or `PETSC_DRAW_FULL_SIZE`, `PETSC_DRAW_HALF_SIZE`,`PETSC_DRAW_THIRD_SIZE`, `PETSC_DRAW_QUARTER_SIZE` 678 - n - window height in pixels, or may use `PETSC_DECIDE` or `PETSC_DRAW_FULL_SIZE`, `PETSC_DRAW_HALF_SIZE`,`PETSC_DRAW_THIRD_SIZE`, `PETSC_DRAW_QUARTER_SIZE` 679 680 Level: developer 681 682 .seealso: `PetscViewer()`, `PETSCVIEWERDRAW`, `PetscViewerDrawGetDrawLG()`, `PetscViewerDrawOpen()`, `PetscViewerDrawSetInfo()` 683 @*/ 684 PetscErrorCode PetscViewerMonitorLGSetUp(PetscViewer viewer, const char host[], const char title[], const char metric[], PetscInt l, const char *names[], int x, int y, int m, int n) PeNS 685 { 686 PetscDrawAxis axis; 687 PetscDrawLG lg; 688 689 PetscFunctionBegin; 690 PetscCall(PetscViewerSetType(viewer, PETSCVIEWERDRAW)); 691 PetscCall(PetscViewerDrawSetInfo(viewer, host, title, x, y, m, n)); 692 PetscCall(PetscViewerDrawGetDrawLG(viewer, 0, &lg)); 693 if (names) PetscCall(PetscDrawLGSetLegend(lg, names)); 694 PetscCall(PetscDrawLGSetFromOptions(lg)); 695 PetscCall(PetscDrawLGGetAxis(lg, &axis)); 696 PetscCall(PetscDrawAxisSetLabels(axis, "Convergence", "Iteration", metric)); 697 PetscFunctionReturn(PETSC_SUCCESS); 698 } 699