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 Note: 206 Whenever indicating null character data in a Fortran code, 207 `PETSC_NULL_CHARACTER` must be employed. Thus, `PETSC_NULL_CHARACTER` can be 208 used for the `display` and `title` input parameters. 209 210 .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscDrawCreate()`, `PetscViewerDestroy()`, `PetscViewerDrawGetDraw()`, `PetscViewerCreate()`, `PETSC_VIEWER_DRAW_`, 211 `PETSC_VIEWER_DRAW_WORLD`, `PETSC_VIEWER_DRAW_SELF` 212 @*/ 213 PetscErrorCode PetscViewerDrawOpen(MPI_Comm comm, const char display[], const char title[], int x, int y, int w, int h, PetscViewer *viewer) 214 { 215 PetscFunctionBegin; 216 PetscCall(PetscViewerCreate(comm, viewer)); 217 PetscCall(PetscViewerSetType(*viewer, PETSCVIEWERDRAW)); 218 PetscCall(PetscViewerDrawSetInfo(*viewer, display, title, x, y, w, h)); 219 PetscFunctionReturn(PETSC_SUCCESS); 220 } 221 222 #include <petsc/private/drawimpl.h> 223 224 static PetscErrorCode PetscViewerGetSubViewer_Draw(PetscViewer viewer, MPI_Comm comm, PetscViewer *sviewer) 225 { 226 PetscMPIInt rank; 227 PetscInt i; 228 PetscViewer_Draw *vdraw = (PetscViewer_Draw *)viewer->data, *svdraw; 229 230 PetscFunctionBegin; 231 PetscCheck(!vdraw->singleton_made, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Trying to get SubViewer without first restoring previous"); 232 /* only processor zero can use the PetscViewer draw singleton */ 233 PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank)); 234 if (rank == 0) { 235 PetscMPIInt flg; 236 PetscDraw draw, sdraw; 237 238 PetscCallMPI(MPI_Comm_compare(PETSC_COMM_SELF, comm, &flg)); 239 PetscCheck(flg == MPI_IDENT || flg == MPI_CONGRUENT, PETSC_COMM_SELF, PETSC_ERR_SUP, "PetscViewerGetSubViewer() for PETSCVIEWERDRAW requires a singleton MPI_Comm"); 240 PetscCall(PetscViewerCreate(comm, sviewer)); 241 PetscCall(PetscViewerSetType(*sviewer, PETSCVIEWERDRAW)); 242 svdraw = (PetscViewer_Draw *)(*sviewer)->data; 243 (*sviewer)->format = viewer->format; 244 for (i = 0; i < vdraw->draw_max; i++) { /* XXX this is wrong if svdraw->draw_max (initially 5) < vdraw->draw_max */ 245 if (vdraw->draw[i]) PetscCall(PetscDrawGetSingleton(vdraw->draw[i], &svdraw->draw[i])); 246 } 247 PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw)); 248 PetscCall(PetscViewerDrawGetDraw(*sviewer, 0, &sdraw)); 249 if (draw->savefilename) { 250 PetscCall(PetscDrawSetSave(sdraw, draw->savefilename)); 251 sdraw->savefilecount = draw->savefilecount; 252 sdraw->savesinglefile = draw->savesinglefile; 253 sdraw->savemoviefps = draw->savemoviefps; 254 sdraw->saveonclear = draw->saveonclear; 255 sdraw->saveonflush = draw->saveonflush; 256 } 257 if (draw->savefinalfilename) PetscCall(PetscDrawSetSaveFinalImage(sdraw, draw->savefinalfilename)); 258 } else { 259 PetscDraw draw; 260 PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw)); 261 } 262 vdraw->singleton_made = PETSC_TRUE; 263 PetscFunctionReturn(PETSC_SUCCESS); 264 } 265 266 static PetscErrorCode PetscViewerRestoreSubViewer_Draw(PetscViewer viewer, MPI_Comm comm, PetscViewer *sviewer) 267 { 268 PetscMPIInt rank; 269 PetscInt i; 270 PetscViewer_Draw *vdraw = (PetscViewer_Draw *)viewer->data, *svdraw; 271 272 PetscFunctionBegin; 273 PetscCheck(vdraw->singleton_made, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Trying to restore a singleton that was not gotten"); 274 PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank)); 275 if (rank == 0) { 276 PetscDraw draw, sdraw; 277 278 PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw)); 279 PetscCall(PetscViewerDrawGetDraw(*sviewer, 0, &sdraw)); 280 if (draw->savefilename) { 281 draw->savefilecount = sdraw->savefilecount; 282 PetscCallMPI(MPI_Bcast(&draw->savefilecount, 1, MPIU_INT, 0, PetscObjectComm((PetscObject)draw))); 283 } 284 svdraw = (PetscViewer_Draw *)(*sviewer)->data; 285 for (i = 0; i < vdraw->draw_max; i++) { 286 if (vdraw->draw[i] && svdraw->draw[i]) PetscCall(PetscDrawRestoreSingleton(vdraw->draw[i], &svdraw->draw[i])); 287 } 288 PetscCall(PetscFree3(svdraw->draw, svdraw->drawlg, svdraw->drawaxis)); 289 PetscCall(PetscFree((*sviewer)->data)); 290 PetscCall(PetscHeaderDestroy(sviewer)); 291 } else { 292 PetscDraw draw; 293 294 PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw)); 295 if (draw->savefilename) PetscCallMPI(MPI_Bcast(&draw->savefilecount, 1, MPIU_INT, 0, PetscObjectComm((PetscObject)draw))); 296 } 297 298 vdraw->singleton_made = PETSC_FALSE; 299 PetscFunctionReturn(PETSC_SUCCESS); 300 } 301 302 static PetscErrorCode PetscViewerSetFromOptions_Draw(PetscViewer v, PetscOptionItems PetscOptionsObject) 303 { 304 PetscReal bounds[16]; 305 PetscInt nbounds = 16; 306 PetscBool flg; 307 308 PetscFunctionBegin; 309 PetscOptionsHeadBegin(PetscOptionsObject, "Draw PetscViewer Options"); 310 PetscCall(PetscOptionsRealArray("-draw_bounds", "Bounds to put on plots axis", "PetscViewerDrawSetBounds", bounds, &nbounds, &flg)); 311 if (flg) PetscCall(PetscViewerDrawSetBounds(v, nbounds / 2, bounds)); 312 PetscOptionsHeadEnd(); 313 PetscFunctionReturn(PETSC_SUCCESS); 314 } 315 316 static PetscErrorCode PetscViewerView_Draw(PetscViewer viewer, PetscViewer v) 317 { 318 PetscDraw draw; 319 PetscInt i; 320 PetscViewer_Draw *vdraw = (PetscViewer_Draw *)viewer->data; 321 PetscBool iascii; 322 323 PetscFunctionBegin; 324 PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERASCII, &iascii)); 325 if (iascii) PetscCall(PetscViewerASCIIPrintf(v, "Draw viewer is of type %s\n", vdraw->drawtype)); 326 /* If the PetscViewer has just been created then no vdraw->draw yet 327 exists so this will not actually call the viewer on any draws. */ 328 for (i = 0; i < vdraw->draw_base; i++) { 329 if (vdraw->draw[i]) { 330 PetscCall(PetscViewerDrawGetDraw(viewer, i, &draw)); 331 PetscCall(PetscDrawView(draw, v)); 332 } 333 } 334 PetscFunctionReturn(PETSC_SUCCESS); 335 } 336 337 /*MC 338 PETSCVIEWERDRAW - A viewer that generates graphics, either to the screen or a file 339 340 Level: beginner 341 342 .seealso: [](sec_viewers), `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`, `PETSC_VIEWER_DRAW_()`, `PETSC_VIEWER_DRAW_SELF`, `PETSC_VIEWER_DRAW_WORLD`, 343 `PetscViewerCreate()`, `PetscViewerASCIIOpen()`, `PetscViewerBinaryOpen()`, `PETSCVIEWERBINARY`, 344 `PetscViewerMatlabOpen()`, `VecView()`, `DMView()`, `PetscViewerMatlabPutArray()`, `PETSCVIEWERASCII`, `PETSCVIEWERMATLAB`, 345 `PetscViewerFileSetName()`, `PetscViewerFileSetMode()`, `PetscViewerFormat`, `PetscViewerType`, `PetscViewerSetType()` 346 M*/ 347 PETSC_EXTERN PetscErrorCode PetscViewerCreate_Draw(PetscViewer viewer) 348 { 349 PetscViewer_Draw *vdraw; 350 351 PetscFunctionBegin; 352 PetscCall(PetscNew(&vdraw)); 353 viewer->data = (void *)vdraw; 354 355 viewer->ops->flush = PetscViewerFlush_Draw; 356 viewer->ops->view = PetscViewerView_Draw; 357 viewer->ops->destroy = PetscViewerDestroy_Draw; 358 viewer->ops->setfromoptions = PetscViewerSetFromOptions_Draw; 359 viewer->ops->getsubviewer = PetscViewerGetSubViewer_Draw; 360 viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_Draw; 361 362 /* these are created on the fly if requested */ 363 vdraw->draw_max = 5; 364 vdraw->draw_base = 0; 365 vdraw->w = PETSC_DECIDE; 366 vdraw->h = PETSC_DECIDE; 367 368 PetscCall(PetscCalloc3(vdraw->draw_max, &vdraw->draw, vdraw->draw_max, &vdraw->drawlg, vdraw->draw_max, &vdraw->drawaxis)); 369 vdraw->singleton_made = PETSC_FALSE; 370 PetscFunctionReturn(PETSC_SUCCESS); 371 } 372 373 /*@ 374 PetscViewerDrawClear - Clears a `PetscDraw` graphic associated with a `PetscViewer`. 375 376 Not Collective 377 378 Input Parameter: 379 . viewer - the `PetscViewer` 380 381 Level: intermediate 382 383 .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`, 384 @*/ 385 PetscErrorCode PetscViewerDrawClear(PetscViewer viewer) 386 { 387 PetscViewer_Draw *vdraw; 388 PetscBool isdraw; 389 PetscInt i; 390 391 PetscFunctionBegin; 392 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 393 PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw)); 394 if (!isdraw) PetscFunctionReturn(PETSC_SUCCESS); 395 vdraw = (PetscViewer_Draw *)viewer->data; 396 397 for (i = 0; i < vdraw->draw_max; i++) { 398 if (vdraw->draw[i]) PetscCall(PetscDrawClear(vdraw->draw[i])); 399 } 400 PetscFunctionReturn(PETSC_SUCCESS); 401 } 402 403 /*@ 404 PetscViewerDrawGetPause - Gets the pause value (how long to pause before an image is changed) in the `PETSCVIEWERDRAW` `PetscViewer` 405 406 Not Collective 407 408 Input Parameter: 409 . viewer - the `PetscViewer` 410 411 Output Parameter: 412 . pause - the pause value 413 414 Level: intermediate 415 416 .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`, 417 @*/ 418 PetscErrorCode PetscViewerDrawGetPause(PetscViewer viewer, PetscReal *pause) 419 { 420 PetscViewer_Draw *vdraw; 421 PetscBool isdraw; 422 PetscInt i; 423 PetscDraw draw; 424 425 PetscFunctionBegin; 426 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 427 PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw)); 428 if (!isdraw) { 429 *pause = 0.0; 430 PetscFunctionReturn(PETSC_SUCCESS); 431 } 432 vdraw = (PetscViewer_Draw *)viewer->data; 433 434 for (i = 0; i < vdraw->draw_max; i++) { 435 if (vdraw->draw[i]) { 436 PetscCall(PetscDrawGetPause(vdraw->draw[i], pause)); 437 PetscFunctionReturn(PETSC_SUCCESS); 438 } 439 } 440 /* none exist yet so create one and get its pause */ 441 PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw)); 442 PetscCall(PetscDrawGetPause(draw, pause)); 443 PetscFunctionReturn(PETSC_SUCCESS); 444 } 445 446 /*@ 447 PetscViewerDrawSetPause - Sets a pause for each `PetscDraw` in the `PETSCVIEWERDRAW` `PetscViewer` 448 449 Not Collective 450 451 Input Parameters: 452 + viewer - the `PetscViewer` 453 - pause - the pause value 454 455 Level: intermediate 456 457 .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`, 458 @*/ 459 PetscErrorCode PetscViewerDrawSetPause(PetscViewer viewer, PetscReal pause) 460 { 461 PetscViewer_Draw *vdraw; 462 PetscBool isdraw; 463 PetscInt i; 464 465 PetscFunctionBegin; 466 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 467 PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw)); 468 if (!isdraw) PetscFunctionReturn(PETSC_SUCCESS); 469 vdraw = (PetscViewer_Draw *)viewer->data; 470 471 vdraw->pause = pause; 472 for (i = 0; i < vdraw->draw_max; i++) { 473 if (vdraw->draw[i]) PetscCall(PetscDrawSetPause(vdraw->draw[i], pause)); 474 } 475 PetscFunctionReturn(PETSC_SUCCESS); 476 } 477 478 /*@ 479 PetscViewerDrawSetHold - Holds previous image when drawing new image in a `PETSCVIEWERDRAW` 480 481 Not Collective 482 483 Input Parameters: 484 + viewer - the `PetscViewer` 485 - hold - `PETSC_TRUE` indicates to hold the previous image 486 487 Level: intermediate 488 489 .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`, 490 @*/ 491 PetscErrorCode PetscViewerDrawSetHold(PetscViewer viewer, PetscBool hold) 492 { 493 PetscViewer_Draw *vdraw; 494 PetscBool isdraw; 495 496 PetscFunctionBegin; 497 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 498 PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw)); 499 if (!isdraw) PetscFunctionReturn(PETSC_SUCCESS); 500 vdraw = (PetscViewer_Draw *)viewer->data; 501 502 vdraw->hold = hold; 503 PetscFunctionReturn(PETSC_SUCCESS); 504 } 505 506 /*@ 507 PetscViewerDrawGetHold - Checks if the `PETSCVIEWERDRAW` `PetscViewer` holds previous image when drawing new image 508 509 Not Collective 510 511 Input Parameter: 512 . viewer - the `PetscViewer` 513 514 Output Parameter: 515 . hold - indicates to hold or not 516 517 Level: intermediate 518 519 .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`, 520 @*/ 521 PetscErrorCode PetscViewerDrawGetHold(PetscViewer viewer, PetscBool *hold) 522 { 523 PetscViewer_Draw *vdraw; 524 PetscBool isdraw; 525 526 PetscFunctionBegin; 527 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 528 PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw)); 529 if (!isdraw) { 530 *hold = PETSC_FALSE; 531 PetscFunctionReturn(PETSC_SUCCESS); 532 } 533 vdraw = (PetscViewer_Draw *)viewer->data; 534 535 *hold = vdraw->hold; 536 PetscFunctionReturn(PETSC_SUCCESS); 537 } 538 539 /* 540 The variable Petsc_Viewer_Draw_keyval is used to indicate an MPI attribute that 541 is attached to a communicator, in this case the attribute is a PetscViewer. 542 */ 543 PetscMPIInt Petsc_Viewer_Draw_keyval = MPI_KEYVAL_INVALID; 544 545 /*@C 546 PETSC_VIEWER_DRAW_ - Creates a window `PETSCVIEWERDRAW` `PetscViewer` shared by all processors 547 in an MPI communicator. 548 549 Collective 550 551 Input Parameter: 552 . comm - the MPI communicator to share the window `PetscViewer` 553 554 Level: intermediate 555 556 Notes: 557 This object is destroyed in `PetscFinalize()`, `PetscViewerDestroy()` should never be called on it 558 559 Unlike almost all other PETSc routines, `PETSC_VIEWER_DRAW_()` does not return 560 an error code. The window is usually used in the form 561 .vb 562 XXXView(XXX object, PETSC_VIEWER_DRAW_(comm)); 563 .ve 564 565 .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewer`, `PETSC_VIEWER_DRAW_WORLD`, `PETSC_VIEWER_DRAW_SELF`, `PetscViewerDrawOpen()`, 566 @*/ 567 PetscViewer PETSC_VIEWER_DRAW_(MPI_Comm comm) 568 { 569 PetscMPIInt flag; 570 PetscViewer viewer; 571 MPI_Comm ncomm; 572 573 PetscFunctionBegin; 574 PetscCallNull(PetscCommDuplicate(comm, &ncomm, NULL)); 575 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)); } 576 PetscCallMPINull(MPI_Comm_get_attr(ncomm, Petsc_Viewer_Draw_keyval, (void **)&viewer, &flag)); 577 if (!flag) { /* PetscViewer not yet created */ 578 PetscCallNull(PetscViewerDrawOpen(ncomm, NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 300, 300, &viewer)); 579 PetscCallNull(PetscObjectRegisterDestroy((PetscObject)viewer)); 580 PetscCallMPINull(MPI_Comm_set_attr(ncomm, Petsc_Viewer_Draw_keyval, (void *)viewer)); 581 } 582 PetscCallNull(PetscCommDestroy(&ncomm)); 583 PetscFunctionReturn(viewer); 584 } 585 586 /*@ 587 PetscViewerDrawSetBounds - sets the upper and lower bounds to be used in plotting in a `PETSCVIEWERDRAW` `PetscViewer` 588 589 Collective 590 591 Input Parameters: 592 + viewer - the `PetscViewer` (created with `PetscViewerDrawOpen()`) 593 . nbounds - number of plots that can be made with this viewer, for example the dof passed to `DMDACreate()` 594 - 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, ..... 595 596 Options Database Key: 597 . -draw_bounds minF0,maxF0,minF1,maxF1 - the lower left and upper right bounds 598 599 Level: intermediate 600 601 Note: 602 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 603 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 604 this viewer. Otherwise the color to physical value meaning changes with each new image if this is not set. 605 606 .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewerDrawGetLG()`, `PetscViewerDrawGetAxis()`, `PetscViewerDrawOpen()` 607 @*/ 608 PetscErrorCode PetscViewerDrawSetBounds(PetscViewer viewer, PetscInt nbounds, const PetscReal *bounds) 609 { 610 PetscViewer_Draw *vdraw; 611 PetscBool isdraw; 612 613 PetscFunctionBegin; 614 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 615 PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw)); 616 if (!isdraw) PetscFunctionReturn(PETSC_SUCCESS); 617 vdraw = (PetscViewer_Draw *)viewer->data; 618 619 vdraw->nbounds = nbounds; 620 PetscCall(PetscFree(vdraw->bounds)); 621 PetscCall(PetscMalloc1(2 * nbounds, &vdraw->bounds)); 622 PetscCall(PetscArraycpy(vdraw->bounds, bounds, 2 * nbounds)); 623 PetscFunctionReturn(PETSC_SUCCESS); 624 } 625 626 /*@C 627 PetscViewerDrawGetBounds - gets the upper and lower bounds to be used in plotting set with `PetscViewerDrawSetBounds()` 628 629 Collective 630 631 Input Parameter: 632 . viewer - the `PetscViewer` (created with `PetscViewerDrawOpen()`) 633 634 Output Parameters: 635 + nbounds - number of plots that can be made with this viewer, for example the dof passed to `DMDACreate()` 636 - 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, ..... 637 638 Level: intermediate 639 640 .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewerDrawGetLG()`, `PetscViewerDrawGetAxis()`, `PetscViewerDrawOpen()`, `PetscViewerDrawSetBounds()` 641 @*/ 642 PetscErrorCode PetscViewerDrawGetBounds(PetscViewer viewer, PetscInt *nbounds, const PetscReal *bounds[]) 643 { 644 PetscViewer_Draw *vdraw; 645 PetscBool isdraw; 646 647 PetscFunctionBegin; 648 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 649 PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw)); 650 if (!isdraw) { 651 if (nbounds) *nbounds = 0; 652 if (bounds) *bounds = NULL; 653 PetscFunctionReturn(PETSC_SUCCESS); 654 } 655 vdraw = (PetscViewer_Draw *)viewer->data; 656 657 if (nbounds) *nbounds = vdraw->nbounds; 658 if (bounds) *bounds = vdraw->bounds; 659 PetscFunctionReturn(PETSC_SUCCESS); 660 } 661 662 /*@C 663 PetscViewerMonitorLGSetUp - sets up a viewer to be used by line graph monitoring routines such as `KSPMonitorResidualDrawLG()` 664 665 Collective 666 667 Input Parameters: 668 + viewer - the viewer in which to display the line graphs, it not a `PETSCVIEWERDRAW` it will set to that `PetscViewerType` 669 . host - the host to open the window on, 'NULL' indicates the local host 670 . title - the title at the top of the window 671 . metric - the label above the graph 672 . l - the number of curves 673 . names - the names of each curve to be used in displaying the legend. May be 'NULL' 674 . x - horizontal screen coordinate of the upper left corner of window, or use `PETSC_DECIDE` 675 . y - vertical screen coordinate of the upper left corner of window, or use `PETSC_DECIDE` 676 . 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` 677 - 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` 678 679 Level: developer 680 681 .seealso: `PetscViewer()`, `PETSCVIEWERDRAW`, `PetscViewerDrawGetDrawLG()`, `PetscViewerDrawOpen()`, `PetscViewerDrawSetInfo()` 682 @*/ 683 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 684 { 685 PetscDrawAxis axis; 686 PetscDrawLG lg; 687 688 PetscFunctionBegin; 689 PetscCall(PetscViewerSetType(viewer, PETSCVIEWERDRAW)); 690 PetscCall(PetscViewerDrawSetInfo(viewer, host, title, x, y, m, n)); 691 PetscCall(PetscViewerDrawGetDrawLG(viewer, 0, &lg)); 692 if (names) PetscCall(PetscDrawLGSetLegend(lg, names)); 693 PetscCall(PetscDrawLGSetFromOptions(lg)); 694 PetscCall(PetscDrawLGGetAxis(lg, &axis)); 695 PetscCall(PetscDrawAxisSetLabels(axis, "Convergence", "Iteration", metric)); 696 PetscFunctionReturn(PETSC_SUCCESS); 697 } 698