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 PetscDrawInitializePackage - 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 - the new width of the window 89 - h - the new height of the window 90 91 Level: intermediate 92 93 .seealso: `PetscDraw`, `PetscDrawCheckResizedWindow()` 94 @*/ 95 PetscErrorCode PetscDrawResizeWindow(PetscDraw draw, int w, int h) 96 { 97 PetscFunctionBegin; 98 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 99 PetscValidLogicalCollectiveInt(draw, w, 2); 100 PetscValidLogicalCollectiveInt(draw, h, 3); 101 PetscTryTypeMethod(draw, resizewindow, w, h); 102 PetscFunctionReturn(PETSC_SUCCESS); 103 } 104 105 /*@ 106 PetscDrawGetWindowSize - Gets the size of the window. 107 108 Not Collective 109 110 Input Parameter: 111 . draw - the window 112 113 Output Parameters: 114 + w - the window width 115 - h - the window height 116 117 Level: intermediate 118 119 .seealso: `PetscDraw`, `PetscDrawResizeWindow()`, `PetscDrawCheckResizedWindow()` 120 @*/ 121 PetscErrorCode PetscDrawGetWindowSize(PetscDraw draw, int *w, int *h) 122 { 123 PetscFunctionBegin; 124 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 125 if (w) PetscAssertPointer(w, 2); 126 if (h) PetscAssertPointer(h, 3); 127 if (w) *w = draw->w; 128 if (h) *h = draw->h; 129 PetscFunctionReturn(PETSC_SUCCESS); 130 } 131 132 /*@ 133 PetscDrawCheckResizedWindow - Checks if the user has resized the window. 134 135 Collective 136 137 Input Parameter: 138 . draw - the window 139 140 Level: advanced 141 142 .seealso: `PetscDraw`, `PetscDrawResizeWindow()` 143 @*/ 144 PetscErrorCode PetscDrawCheckResizedWindow(PetscDraw draw) 145 { 146 PetscFunctionBegin; 147 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 148 PetscTryTypeMethod(draw, checkresizedwindow); 149 PetscFunctionReturn(PETSC_SUCCESS); 150 } 151 152 /*@C 153 PetscDrawGetTitle - Gets pointer to title of a `PetscDraw` context. 154 155 Not Collective 156 157 Input Parameter: 158 . draw - the graphics context 159 160 Output Parameter: 161 . title - the title 162 163 Level: intermediate 164 165 .seealso: `PetscDraw`, `PetscDrawSetTitle()` 166 @*/ 167 PetscErrorCode PetscDrawGetTitle(PetscDraw draw, const char *title[]) 168 { 169 PetscFunctionBegin; 170 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 171 PetscAssertPointer(title, 2); 172 *title = draw->title; 173 PetscFunctionReturn(PETSC_SUCCESS); 174 } 175 176 /*@C 177 PetscDrawSetTitle - Sets the title of a `PetscDraw` context. 178 179 Collective 180 181 Input Parameters: 182 + draw - the graphics context 183 - title - the title 184 185 Level: intermediate 186 187 Notes: 188 The title is positioned in the windowing system title bar for the window. Hence it will not be saved with -draw_save 189 in the image. 190 191 A copy of the string is made, so you may destroy the 192 title string after calling this routine. 193 194 You can use `PetscDrawAxisSetLabels()` to indicate a title within the window 195 196 .seealso: `PetscDraw`, `PetscDrawGetTitle()`, `PetscDrawAppendTitle()` 197 @*/ 198 PetscErrorCode PetscDrawSetTitle(PetscDraw draw, const char title[]) 199 { 200 PetscFunctionBegin; 201 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 202 PetscAssertPointer(title, 2); 203 PetscCall(PetscFree(draw->title)); 204 PetscCall(PetscStrallocpy(title, &draw->title)); 205 PetscTryTypeMethod(draw, settitle, draw->title); 206 PetscFunctionReturn(PETSC_SUCCESS); 207 } 208 209 /*@C 210 PetscDrawAppendTitle - Appends to the title of a `PetscDraw` context. 211 212 Collective 213 214 Input Parameters: 215 + draw - the graphics context 216 - title - the title 217 218 Level: advanced 219 220 Note: 221 A copy of the string is made, so you may destroy the 222 title string after calling this routine. 223 224 .seealso: `PetscDraw`, `PetscDrawSetTitle()`, `PetscDrawGetTitle()` 225 @*/ 226 PetscErrorCode PetscDrawAppendTitle(PetscDraw draw, const char title[]) 227 { 228 PetscFunctionBegin; 229 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 230 if (title) PetscAssertPointer(title, 2); 231 if (!title || !title[0]) PetscFunctionReturn(PETSC_SUCCESS); 232 233 if (draw->title) { 234 size_t len1, len2, new_len; 235 PetscCall(PetscStrlen(draw->title, &len1)); 236 PetscCall(PetscStrlen(title, &len2)); 237 new_len = len1 + len2 + 1; 238 PetscCall(PetscRealloc(new_len * sizeof(*(draw->title)), &draw->title)); 239 PetscCall(PetscStrncpy(draw->title + len1, title, len2 + 1)); 240 } else { 241 PetscCall(PetscStrallocpy(title, &draw->title)); 242 } 243 PetscTryTypeMethod(draw, settitle, draw->title); 244 PetscFunctionReturn(PETSC_SUCCESS); 245 } 246 247 static PetscErrorCode PetscDrawDestroy_Private(PetscDraw draw) 248 { 249 PetscFunctionBegin; 250 if (!draw->ops->save && !draw->ops->getimage) PetscFunctionReturn(PETSC_SUCCESS); 251 PetscCall(PetscDrawSaveMovie(draw)); 252 if (draw->savefinalfilename) { 253 draw->savesinglefile = PETSC_TRUE; 254 PetscCall(PetscDrawSetSave(draw, draw->savefinalfilename)); 255 PetscCall(PetscDrawSave(draw)); 256 } 257 PetscCall(PetscBarrier((PetscObject)draw)); 258 PetscFunctionReturn(PETSC_SUCCESS); 259 } 260 261 /*@ 262 PetscDrawDestroy - Deletes a draw context. 263 264 Collective 265 266 Input Parameter: 267 . draw - the drawing context 268 269 Level: beginner 270 271 .seealso: `PetscDraw`, `PetscDrawCreate()` 272 @*/ 273 PetscErrorCode PetscDrawDestroy(PetscDraw *draw) 274 { 275 PetscFunctionBegin; 276 if (!*draw) PetscFunctionReturn(PETSC_SUCCESS); 277 PetscValidHeaderSpecific(*draw, PETSC_DRAW_CLASSID, 1); 278 if (--((PetscObject)(*draw))->refct > 0) PetscFunctionReturn(PETSC_SUCCESS); 279 280 if ((*draw)->pause == -2) { 281 (*draw)->pause = -1; 282 PetscCall(PetscDrawPause(*draw)); 283 } 284 285 /* if memory was published then destroy it */ 286 PetscCall(PetscObjectSAWsViewOff((PetscObject)*draw)); 287 288 PetscCall(PetscDrawDestroy_Private(*draw)); 289 290 if ((*draw)->ops->destroy) PetscCall((*(*draw)->ops->destroy)(*draw)); 291 PetscCall(PetscDrawDestroy(&(*draw)->popup)); 292 PetscCall(PetscFree((*draw)->title)); 293 PetscCall(PetscFree((*draw)->display)); 294 PetscCall(PetscFree((*draw)->savefilename)); 295 PetscCall(PetscFree((*draw)->saveimageext)); 296 PetscCall(PetscFree((*draw)->savemovieext)); 297 PetscCall(PetscFree((*draw)->savefinalfilename)); 298 PetscCall(PetscHeaderDestroy(draw)); 299 PetscFunctionReturn(PETSC_SUCCESS); 300 } 301 302 /*@ 303 PetscDrawGetPopup - Creates a popup window associated with a `PetscDraw` window. 304 305 Collective 306 307 Input Parameter: 308 . draw - the original window 309 310 Output Parameter: 311 . popup - the new popup window 312 313 Level: advanced 314 315 .seealso: `PetscDraw`, `PetscDrawScalePopup()`, `PetscDrawCreate()` 316 @*/ 317 PetscErrorCode PetscDrawGetPopup(PetscDraw draw, PetscDraw *popup) 318 { 319 PetscFunctionBegin; 320 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 321 PetscAssertPointer(popup, 2); 322 323 if (draw->popup) *popup = draw->popup; 324 else if (draw->ops->getpopup) { 325 PetscUseTypeMethod(draw, getpopup, popup); 326 if (*popup) { 327 PetscCall(PetscObjectSetOptionsPrefix((PetscObject)*popup, "popup_")); 328 (*popup)->pause = 0.0; 329 PetscCall(PetscDrawSetFromOptions(*popup)); 330 } 331 } else *popup = NULL; 332 PetscFunctionReturn(PETSC_SUCCESS); 333 } 334 335 /*@C 336 PetscDrawSetDisplay - Sets the display where a `PetscDraw` object will be displayed 337 338 Input Parameters: 339 + draw - the drawing context 340 - display - the X windows display 341 342 Level: advanced 343 344 .seealso: `PetscDraw`, `PetscDrawOpenX()`, `PetscDrawCreate()` 345 @*/ 346 PetscErrorCode PetscDrawSetDisplay(PetscDraw draw, const char display[]) 347 { 348 PetscFunctionBegin; 349 PetscCall(PetscFree(draw->display)); 350 PetscCall(PetscStrallocpy(display, &draw->display)); 351 PetscFunctionReturn(PETSC_SUCCESS); 352 } 353 354 /*@ 355 PetscDrawSetDoubleBuffer - Sets a window to be double buffered. 356 357 Logically Collective 358 359 Input Parameter: 360 . draw - the drawing context 361 362 Level: intermediate 363 364 .seealso: `PetscDraw`, `PetscDrawOpenX()`, `PetscDrawCreate()` 365 @*/ 366 PetscErrorCode PetscDrawSetDoubleBuffer(PetscDraw draw) 367 { 368 PetscFunctionBegin; 369 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 370 PetscTryTypeMethod(draw, setdoublebuffer); 371 PetscFunctionReturn(PETSC_SUCCESS); 372 } 373 374 /*@C 375 PetscDrawGetSingleton - Gain access to a `PetscDraw` object as if it were owned 376 by the one process. 377 378 Collective 379 380 Input Parameter: 381 . draw - the original window 382 383 Output Parameter: 384 . sdraw - the singleton window 385 386 Level: advanced 387 388 .seealso: `PetscDraw`, `PetscDrawRestoreSingleton()`, `PetscViewerGetSingleton()`, `PetscViewerRestoreSingleton()` 389 @*/ 390 PetscErrorCode PetscDrawGetSingleton(PetscDraw draw, PetscDraw *sdraw) 391 { 392 PetscMPIInt size; 393 394 PetscFunctionBegin; 395 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 396 PetscAssertPointer(sdraw, 2); 397 398 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)draw), &size)); 399 if (size == 1) { 400 PetscCall(PetscObjectReference((PetscObject)draw)); 401 *sdraw = draw; 402 } else { 403 if (draw->ops->getsingleton) { 404 PetscUseTypeMethod(draw, getsingleton, sdraw); 405 } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Cannot get singleton for this type %s of draw object", ((PetscObject)draw)->type_name); 406 } 407 PetscFunctionReturn(PETSC_SUCCESS); 408 } 409 410 /*@C 411 PetscDrawRestoreSingleton - Remove access to a `PetscDraw` object obtained with `PetscDrawGetSingleton()` 412 by the one process. 413 414 Collective 415 416 Input Parameters: 417 + draw - the original window 418 - sdraw - the singleton window 419 420 Level: advanced 421 422 .seealso: `PetscDraw`, `PetscDrawGetSingleton()`, `PetscViewerGetSingleton()`, `PetscViewerRestoreSingleton()` 423 @*/ 424 PetscErrorCode PetscDrawRestoreSingleton(PetscDraw draw, PetscDraw *sdraw) 425 { 426 PetscMPIInt size; 427 428 PetscFunctionBegin; 429 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 430 PetscAssertPointer(sdraw, 2); 431 PetscValidHeaderSpecific(*sdraw, PETSC_DRAW_CLASSID, 2); 432 433 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)draw), &size)); 434 if (size == 1) { 435 if (draw == *sdraw) { 436 PetscCall(PetscObjectDereference((PetscObject)draw)); 437 *sdraw = NULL; 438 } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Cannot restore singleton, it is not the parent draw"); 439 } else PetscUseTypeMethod(draw, restoresingleton, sdraw); 440 PetscFunctionReturn(PETSC_SUCCESS); 441 } 442 443 /*@C 444 PetscDrawSetVisible - Sets if the drawing surface (the 'window') is visible on its display. 445 446 Input Parameters: 447 + draw - the drawing window 448 - visible - if the surface should be visible 449 450 Level: intermediate 451 452 .seealso: `PetscDraw` 453 @*/ 454 PetscErrorCode PetscDrawSetVisible(PetscDraw draw, PetscBool visible) 455 { 456 PetscFunctionBegin; 457 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 458 PetscTryTypeMethod(draw, setvisible, visible); 459 PetscFunctionReturn(PETSC_SUCCESS); 460 } 461