1 2 #include <petsc/private/drawimpl.h> /*I "petscdraw.h" I*/ 3 #include <petscviewer.h> 4 5 PetscClassId PETSC_DRAW_CLASSID; 6 7 static PetscBool PetscDrawPackageInitialized = PETSC_FALSE; 8 /*@C 9 PetscDrawFinalizePackage - This function destroys everything in the Petsc interface to the `PetscDraw` package. It is 10 called from `PetscFinalize()`. 11 12 Level: developer 13 14 .seealso: `PetscDraw`, `PetscFinalize()` 15 @*/ 16 PetscErrorCode PetscDrawFinalizePackage(void) 17 { 18 PetscFunctionBegin; 19 PetscCall(PetscFunctionListDestroy(&PetscDrawList)); 20 PetscDrawPackageInitialized = PETSC_FALSE; 21 PetscDrawRegisterAllCalled = PETSC_FALSE; 22 PetscFunctionReturn(PETSC_SUCCESS); 23 } 24 25 /*@C 26 PetscInitializeDrawPackage - This function initializes everything in the `PetscDraw` package. It is called 27 from PetscDLLibraryRegister_petsc() when using dynamic libraries, and on the call to `PetscInitialize()` 28 when using shared or static libraries. 29 30 Level: developer 31 32 .seealso: `PetscDraw`, `PetscInitialize()` 33 @*/ 34 PetscErrorCode PetscDrawInitializePackage(void) 35 { 36 char logList[256]; 37 PetscBool opt, pkg; 38 39 PetscFunctionBegin; 40 if (PetscDrawPackageInitialized) PetscFunctionReturn(PETSC_SUCCESS); 41 PetscDrawPackageInitialized = PETSC_TRUE; 42 /* Register Classes */ 43 PetscCall(PetscClassIdRegister("Draw", &PETSC_DRAW_CLASSID)); 44 PetscCall(PetscClassIdRegister("Draw Axis", &PETSC_DRAWAXIS_CLASSID)); 45 PetscCall(PetscClassIdRegister("Line Graph", &PETSC_DRAWLG_CLASSID)); 46 PetscCall(PetscClassIdRegister("Histogram", &PETSC_DRAWHG_CLASSID)); 47 PetscCall(PetscClassIdRegister("Bar Graph", &PETSC_DRAWBAR_CLASSID)); 48 PetscCall(PetscClassIdRegister("Scatter Plot", &PETSC_DRAWSP_CLASSID)); 49 /* Register Constructors */ 50 PetscCall(PetscDrawRegisterAll()); 51 /* Process Info */ 52 { 53 PetscClassId classids[6]; 54 55 classids[0] = PETSC_DRAW_CLASSID; 56 classids[1] = PETSC_DRAWAXIS_CLASSID; 57 classids[2] = PETSC_DRAWLG_CLASSID; 58 classids[3] = PETSC_DRAWHG_CLASSID; 59 classids[4] = PETSC_DRAWBAR_CLASSID; 60 classids[5] = PETSC_DRAWSP_CLASSID; 61 PetscCall(PetscInfoProcessClass("draw", 6, classids)); 62 } 63 /* Process summary exclusions */ 64 PetscCall(PetscOptionsGetString(NULL, NULL, "-log_exclude", logList, sizeof(logList), &opt)); 65 if (opt) { 66 PetscCall(PetscStrInList("draw", logList, ',', &pkg)); 67 if (pkg) { 68 PetscCall(PetscLogEventExcludeClass(PETSC_DRAW_CLASSID)); 69 PetscCall(PetscLogEventExcludeClass(PETSC_DRAWAXIS_CLASSID)); 70 PetscCall(PetscLogEventExcludeClass(PETSC_DRAWLG_CLASSID)); 71 PetscCall(PetscLogEventExcludeClass(PETSC_DRAWHG_CLASSID)); 72 PetscCall(PetscLogEventExcludeClass(PETSC_DRAWBAR_CLASSID)); 73 PetscCall(PetscLogEventExcludeClass(PETSC_DRAWSP_CLASSID)); 74 } 75 } 76 /* Register package finalizer */ 77 PetscCall(PetscRegisterFinalize(PetscDrawFinalizePackage)); 78 PetscFunctionReturn(PETSC_SUCCESS); 79 } 80 81 /*@ 82 PetscDrawResizeWindow - Allows one to resize a window from a program. 83 84 Collective 85 86 Input Parameters: 87 + draw - the window 88 - w,h - the new width and height of the window 89 90 Level: intermediate 91 92 .seealso: `PetscDraw`, `PetscDrawCheckResizedWindow()` 93 @*/ 94 PetscErrorCode PetscDrawResizeWindow(PetscDraw draw, int w, int h) 95 { 96 PetscFunctionBegin; 97 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 98 PetscValidLogicalCollectiveInt(draw, w, 2); 99 PetscValidLogicalCollectiveInt(draw, h, 3); 100 PetscTryTypeMethod(draw, resizewindow, w, h); 101 PetscFunctionReturn(PETSC_SUCCESS); 102 } 103 104 /*@ 105 PetscDrawGetWindowSize - Gets the size of the window. 106 107 Not Collective 108 109 Input Parameter: 110 . draw - the window 111 112 Output Parameters: 113 + w - the window width 114 - h - the window height 115 116 Level: intermediate 117 118 .seealso: `PetscDraw`, `PetscDrawResizeWindow()`, `PetscDrawCheckResizedWindow()` 119 @*/ 120 PetscErrorCode PetscDrawGetWindowSize(PetscDraw draw, int *w, int *h) 121 { 122 PetscFunctionBegin; 123 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 124 if (w) PetscValidPointer(w, 2); 125 if (h) PetscValidPointer(h, 3); 126 if (w) *w = draw->w; 127 if (h) *h = draw->h; 128 PetscFunctionReturn(PETSC_SUCCESS); 129 } 130 131 /*@ 132 PetscDrawCheckResizedWindow - Checks if the user has resized the window. 133 134 Collective 135 136 Input Parameter: 137 . draw - the window 138 139 Level: advanced 140 141 .seealso: `PetscDraw`, `PetscDrawResizeWindow()` 142 @*/ 143 PetscErrorCode PetscDrawCheckResizedWindow(PetscDraw draw) 144 { 145 PetscFunctionBegin; 146 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 147 PetscTryTypeMethod(draw, checkresizedwindow); 148 PetscFunctionReturn(PETSC_SUCCESS); 149 } 150 151 /*@C 152 PetscDrawGetTitle - Gets pointer to title of a `PetscDraw` context. 153 154 Not Collective 155 156 Input Parameter: 157 . draw - the graphics context 158 159 Output Parameter: 160 . title - the title 161 162 Level: intermediate 163 164 .seealso: `PetscDraw`, `PetscDrawSetTitle()` 165 @*/ 166 PetscErrorCode PetscDrawGetTitle(PetscDraw draw, const char *title[]) 167 { 168 PetscFunctionBegin; 169 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 170 PetscValidPointer(title, 2); 171 *title = draw->title; 172 PetscFunctionReturn(PETSC_SUCCESS); 173 } 174 175 /*@C 176 PetscDrawSetTitle - Sets the title of a `PetscDraw` context. 177 178 Collective 179 180 Input Parameters: 181 + draw - the graphics context 182 - title - the title 183 184 Level: intermediate 185 186 Notes: 187 The title is positioned in the windowing system title bar for the window. Hence it will not be saved with -draw_save 188 in the image. 189 190 A copy of the string is made, so you may destroy the 191 title string after calling this routine. 192 193 You can use `PetscDrawAxisSetLabels()` to indicate a title within the window 194 195 .seealso: `PetscDraw`, `PetscDrawGetTitle()`, `PetscDrawAppendTitle()` 196 @*/ 197 PetscErrorCode PetscDrawSetTitle(PetscDraw draw, const char title[]) 198 { 199 PetscFunctionBegin; 200 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 201 PetscValidCharPointer(title, 2); 202 PetscCall(PetscFree(draw->title)); 203 PetscCall(PetscStrallocpy(title, &draw->title)); 204 PetscTryTypeMethod(draw, settitle, draw->title); 205 PetscFunctionReturn(PETSC_SUCCESS); 206 } 207 208 /*@C 209 PetscDrawAppendTitle - Appends to the title of a `PetscDraw` context. 210 211 Collective 212 213 Input Parameters: 214 + draw - the graphics context 215 - title - the title 216 217 Level: advanced 218 219 Note: 220 A copy of the string is made, so you may destroy the 221 title string after calling this routine. 222 223 .seealso: `PetscDraw`, `PetscDrawSetTitle()`, `PetscDrawGetTitle()` 224 @*/ 225 PetscErrorCode PetscDrawAppendTitle(PetscDraw draw, const char title[]) 226 { 227 PetscFunctionBegin; 228 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 229 if (title) PetscValidCharPointer(title, 2); 230 if (!title || !title[0]) PetscFunctionReturn(PETSC_SUCCESS); 231 232 if (draw->title) { 233 size_t len1, len2, new_len; 234 PetscCall(PetscStrlen(draw->title, &len1)); 235 PetscCall(PetscStrlen(title, &len2)); 236 new_len = len1 + len2 + 1; 237 PetscCall(PetscRealloc(new_len * sizeof(*(draw->title)), &draw->title)); 238 PetscCall(PetscStrncpy(draw->title + len1, title, len2 + 1)); 239 } else { 240 PetscCall(PetscStrallocpy(title, &draw->title)); 241 } 242 PetscTryTypeMethod(draw, settitle, draw->title); 243 PetscFunctionReturn(PETSC_SUCCESS); 244 } 245 246 static PetscErrorCode PetscDrawDestroy_Private(PetscDraw draw) 247 { 248 PetscFunctionBegin; 249 if (!draw->ops->save && !draw->ops->getimage) PetscFunctionReturn(PETSC_SUCCESS); 250 PetscCall(PetscDrawSaveMovie(draw)); 251 if (draw->savefinalfilename) { 252 draw->savesinglefile = PETSC_TRUE; 253 PetscCall(PetscDrawSetSave(draw, draw->savefinalfilename)); 254 PetscCall(PetscDrawSave(draw)); 255 } 256 PetscCall(PetscBarrier((PetscObject)draw)); 257 PetscFunctionReturn(PETSC_SUCCESS); 258 } 259 260 /*@ 261 PetscDrawDestroy - Deletes a draw context. 262 263 Collective 264 265 Input Parameter: 266 . draw - the drawing context 267 268 Level: beginner 269 270 .seealso: `PetscDraw`, `PetscDrawCreate()` 271 @*/ 272 PetscErrorCode PetscDrawDestroy(PetscDraw *draw) 273 { 274 PetscFunctionBegin; 275 if (!*draw) PetscFunctionReturn(PETSC_SUCCESS); 276 PetscValidHeaderSpecific(*draw, PETSC_DRAW_CLASSID, 1); 277 if (--((PetscObject)(*draw))->refct > 0) PetscFunctionReturn(PETSC_SUCCESS); 278 279 if ((*draw)->pause == -2) { 280 (*draw)->pause = -1; 281 PetscCall(PetscDrawPause(*draw)); 282 } 283 284 /* if memory was published then destroy it */ 285 PetscCall(PetscObjectSAWsViewOff((PetscObject)*draw)); 286 287 PetscCall(PetscDrawDestroy_Private(*draw)); 288 289 if ((*draw)->ops->destroy) PetscCall((*(*draw)->ops->destroy)(*draw)); 290 PetscCall(PetscDrawDestroy(&(*draw)->popup)); 291 PetscCall(PetscFree((*draw)->title)); 292 PetscCall(PetscFree((*draw)->display)); 293 PetscCall(PetscFree((*draw)->savefilename)); 294 PetscCall(PetscFree((*draw)->saveimageext)); 295 PetscCall(PetscFree((*draw)->savemovieext)); 296 PetscCall(PetscFree((*draw)->savefinalfilename)); 297 PetscCall(PetscHeaderDestroy(draw)); 298 PetscFunctionReturn(PETSC_SUCCESS); 299 } 300 301 /*@ 302 PetscDrawGetPopup - Creates a popup window associated with a `PetscDraw` window. 303 304 Collective 305 306 Input Parameter: 307 . draw - the original window 308 309 Output Parameter: 310 . popup - the new popup window 311 312 Level: advanced 313 314 .seealso: `PetscDraw`, `PetscDrawScalePopup()`, `PetscDrawCreate()` 315 @*/ 316 PetscErrorCode PetscDrawGetPopup(PetscDraw draw, PetscDraw *popup) 317 { 318 PetscFunctionBegin; 319 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 320 PetscValidPointer(popup, 2); 321 322 if (draw->popup) *popup = draw->popup; 323 else if (draw->ops->getpopup) { 324 PetscUseTypeMethod(draw, getpopup, popup); 325 if (*popup) { 326 PetscCall(PetscObjectSetOptionsPrefix((PetscObject)*popup, "popup_")); 327 (*popup)->pause = 0.0; 328 PetscCall(PetscDrawSetFromOptions(*popup)); 329 } 330 } else *popup = NULL; 331 PetscFunctionReturn(PETSC_SUCCESS); 332 } 333 334 /*@C 335 PetscDrawSetDisplay - Sets the display where a `PetscDraw` object will be displayed 336 337 Input Parameters: 338 + draw - the drawing context 339 - display - the X windows display 340 341 Level: advanced 342 343 .seealso: `PetscDraw`, `PetscDrawOpenX()`, `PetscDrawCreate()` 344 @*/ 345 PetscErrorCode PetscDrawSetDisplay(PetscDraw draw, const char display[]) 346 { 347 PetscFunctionBegin; 348 PetscCall(PetscFree(draw->display)); 349 PetscCall(PetscStrallocpy(display, &draw->display)); 350 PetscFunctionReturn(PETSC_SUCCESS); 351 } 352 353 /*@ 354 PetscDrawSetDoubleBuffer - Sets a window to be double buffered. 355 356 Logically Collective 357 358 Input Parameter: 359 . draw - the drawing context 360 361 Level: intermediate 362 363 .seealso: `PetscDraw`, `PetscDrawOpenX()`, `PetscDrawCreate()` 364 @*/ 365 PetscErrorCode PetscDrawSetDoubleBuffer(PetscDraw draw) 366 { 367 PetscFunctionBegin; 368 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 369 PetscTryTypeMethod(draw, setdoublebuffer); 370 PetscFunctionReturn(PETSC_SUCCESS); 371 } 372 373 /*@C 374 PetscDrawGetSingleton - Gain access to a `PetscDraw` object as if it were owned 375 by the one process. 376 377 Collective 378 379 Input Parameter: 380 . draw - the original window 381 382 Output Parameter: 383 . sdraw - the singleton window 384 385 Level: advanced 386 387 .seealso: `PetscDraw`, `PetscDrawRestoreSingleton()`, `PetscViewerGetSingleton()`, `PetscViewerRestoreSingleton()` 388 @*/ 389 PetscErrorCode PetscDrawGetSingleton(PetscDraw draw, PetscDraw *sdraw) 390 { 391 PetscMPIInt size; 392 393 PetscFunctionBegin; 394 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 395 PetscValidPointer(sdraw, 2); 396 397 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)draw), &size)); 398 if (size == 1) { 399 PetscCall(PetscObjectReference((PetscObject)draw)); 400 *sdraw = draw; 401 } else { 402 if (draw->ops->getsingleton) { 403 PetscUseTypeMethod(draw, getsingleton, sdraw); 404 } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Cannot get singleton for this type %s of draw object", ((PetscObject)draw)->type_name); 405 } 406 PetscFunctionReturn(PETSC_SUCCESS); 407 } 408 409 /*@C 410 PetscDrawRestoreSingleton - Remove access to a `PetscDraw` object obtained with `PetscDrawGetSingleton()` 411 by the one process. 412 413 Collective 414 415 Input Parameters: 416 + draw - the original window 417 - sdraw - the singleton window 418 419 Level: advanced 420 421 .seealso: `PetscDraw`, `PetscDrawGetSingleton()`, `PetscViewerGetSingleton()`, `PetscViewerRestoreSingleton()` 422 @*/ 423 PetscErrorCode PetscDrawRestoreSingleton(PetscDraw draw, PetscDraw *sdraw) 424 { 425 PetscMPIInt size; 426 427 PetscFunctionBegin; 428 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 429 PetscValidPointer(sdraw, 2); 430 PetscValidHeaderSpecific(*sdraw, PETSC_DRAW_CLASSID, 2); 431 432 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)draw), &size)); 433 if (size == 1) { 434 if (draw == *sdraw) { 435 PetscCall(PetscObjectDereference((PetscObject)draw)); 436 *sdraw = NULL; 437 } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Cannot restore singleton, it is not the parent draw"); 438 } else PetscUseTypeMethod(draw, restoresingleton, sdraw); 439 PetscFunctionReturn(PETSC_SUCCESS); 440 } 441 442 /*@C 443 PetscDrawSetVisible - Sets if the drawing surface (the 'window') is visible on its display. 444 445 Input Parameters: 446 + draw - the drawing window 447 - visible - if the surface should be visible 448 449 Level: intermediate 450 451 .seealso: `PetscDraw` 452 @*/ 453 PetscErrorCode PetscDrawSetVisible(PetscDraw draw, PetscBool visible) 454 { 455 PetscFunctionBegin; 456 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 457 PetscTryTypeMethod(draw, setvisible, visible); 458 PetscFunctionReturn(PETSC_SUCCESS); 459 } 460