1 /* 2 Provides the registration process for PETSc PetscDraw routines 3 */ 4 #include <petsc/private/drawimpl.h> /*I "petscdraw.h" I*/ 5 #include <petscviewer.h> /*I "petscviewer.h" I*/ 6 #if defined(PETSC_HAVE_SAWS) 7 #include <petscviewersaws.h> 8 #endif 9 10 /* 11 Contains the list of registered PetscDraw routines 12 */ 13 PetscFunctionList PetscDrawList = NULL; 14 15 /*@C 16 PetscDrawView - Prints the `PetscDraw` data structure. 17 18 Collective 19 20 Input Parameters: 21 + indraw - the `PetscDraw` context 22 - viewer - visualization context 23 24 See PetscDrawSetFromOptions() for options database keys 25 26 Note: 27 The available visualization contexts include 28 + `PETSC_VIEWER_STDOUT_SELF` - standard output (default) 29 - `PETSC_VIEWER_STDOUT_WORLD` - synchronized standard 30 output where only the first processor opens 31 the file. All other processors send their 32 data to the first processor to print. 33 34 The user can open an alternative visualization context with 35 `PetscViewerASCIIOpen()` - output to a specified file. 36 37 Level: beginner 38 39 .seealso: `PetscDraw`, `PetscViewerASCIIOpen()`, `PetscViewer` 40 @*/ 41 PetscErrorCode PetscDrawView(PetscDraw indraw, PetscViewer viewer) 42 { 43 PetscBool isdraw; 44 #if defined(PETSC_HAVE_SAWS) 45 PetscBool issaws; 46 #endif 47 48 PetscFunctionBegin; 49 PetscValidHeaderSpecific(indraw, PETSC_DRAW_CLASSID, 1); 50 if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)indraw), &viewer)); 51 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 52 PetscCheckSameComm(indraw, 1, viewer, 2); 53 54 PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)indraw, viewer)); 55 PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw)); 56 #if defined(PETSC_HAVE_SAWS) 57 PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSAWS, &issaws)); 58 #endif 59 if (isdraw) { 60 PetscDraw draw; 61 char str[36]; 62 PetscReal x, y, bottom, h; 63 64 PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw)); 65 PetscCall(PetscDrawGetCurrentPoint(draw, &x, &y)); 66 PetscCall(PetscStrncpy(str, "PetscDraw: ", sizeof(str))); 67 PetscCall(PetscStrlcat(str, ((PetscObject)indraw)->type_name, sizeof(str))); 68 PetscCall(PetscDrawStringBoxed(draw, x, y, PETSC_DRAW_RED, PETSC_DRAW_BLACK, str, NULL, &h)); 69 bottom = y - h; 70 PetscCall(PetscDrawPushCurrentPoint(draw, x, bottom)); 71 #if defined(PETSC_HAVE_SAWS) 72 } else if (issaws) { 73 PetscMPIInt rank; 74 75 PetscCall(PetscObjectName((PetscObject)indraw)); 76 PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank)); 77 if (!((PetscObject)indraw)->amsmem && rank == 0) PetscCall(PetscObjectViewSAWs((PetscObject)indraw, viewer)); 78 #endif 79 } else PetscTryTypeMethod(indraw, view, viewer); 80 PetscFunctionReturn(PETSC_SUCCESS); 81 } 82 83 /*@C 84 PetscDrawViewFromOptions - View a `PetscDraw` from the option database 85 86 Collective 87 88 Input Parameters: 89 + A - the `PetscDraw` context 90 . obj - Optional object 91 - name - command line option 92 93 Level: intermediate 94 95 .seealso: `PetscDraw`, `PetscDrawView`, `PetscObjectViewFromOptions()`, `PetscDrawCreate()` 96 @*/ 97 PetscErrorCode PetscDrawViewFromOptions(PetscDraw A, PetscObject obj, const char name[]) 98 { 99 PetscFunctionBegin; 100 PetscValidHeaderSpecific(A, PETSC_DRAW_CLASSID, 1); 101 PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name)); 102 PetscFunctionReturn(PETSC_SUCCESS); 103 } 104 105 /*@C 106 PetscDrawCreate - Creates a graphics context. 107 108 Collective 109 110 Input Parameters: 111 + comm - MPI communicator 112 . display - X display when using X Windows 113 . title - optional title added to top of window 114 . x - horizonatl coordinate of lower left corner of window or `PETSC_DECIDE` 115 . y - vertical coordinate of lower left corner of window or `PETSC_DECIDE` 116 . w - width of window, `PETSC_DECIDE`, `PETSC_DRAW_HALF_SIZE`, `PETSC_DRAW_FULL_SIZE`, `PETSC_DRAW_THIRD_SIZE` or `PETSC_DRAW_QUARTER_SIZE` 117 - h - height of window, `PETSC_DECIDE`, `PETSC_DRAW_HALF_SIZE`, `PETSC_DRAW_FULL_SIZE`, `PETSC_DRAW_THIRD_SIZE` or `PETSC_DRAW_QUARTER_SIZE` 118 119 Output Parameter: 120 . indraw - location to put the `PetscDraw` context 121 122 Level: beginner 123 124 .seealso: `PetscDrawSetType()`, `PetscDrawSetFromOptions()`, `PetscDrawDestroy()`, `PetscDrawLGCreate()`, `PetscDrawSPCreate()`, 125 `PetscDrawViewPortsCreate()`, `PetscDrawViewPortsSet()`, `PetscDrawAxisCreate()`, `PetscDrawHGCreate()`, `PetscDrawBarCreate()`, 126 `PetscViewerDrawGetDraw()`, `PetscDrawSetSave()`, `PetscDrawSetSaveMovie()`, `PetscDrawSetSaveFinalImage()`, 127 `PetscDrawOpenX()`, `PetscDrawOpenImage()`, `PetscDrawIsNull()`, `PetscDrawGetPopup()`, `PetscDrawCheckResizedWindow()`, `PetscDrawResizeWindow()`, 128 `PetscDrawGetWindowSize()`, `PetscDrawLine()`, `PetscDrawArrow()`, `PetscDrawLineSetWidth()`, `PetscDrawLineGetWidth()`, `PetscDrawMarker()`, 129 `PetscDrawPoint()`, `PetscDrawRectangle()`, `PetscDrawTriangle()`, `PetscDrawEllipse()`, `PetscDrawString()`, `PetscDrawStringCentered()`, 130 `PetscDrawStringBoxed()`, `PetscDrawStringVertical()`, `PetscDrawSetViewPort()`, `PetscDrawGetViewPort()`, 131 `PetscDrawSplitViewPort()`, `PetscDrawSetTitle()`, `PetscDrawAppendTitle()`, `PetscDrawGetTitle()`, `PetscDrawSetPause()`, `PetscDrawGetPause()`, 132 `PetscDrawPause()`, `PetscDrawSetDoubleBuffer()`, `PetscDrawClear()`, `PetscDrawFlush()`, `PetscDrawGetSingleton()`, `PetscDrawGetMouseButton()`, 133 `PetscDrawZoom()`, `PetscDrawGetBoundingBox()` 134 @*/ 135 PetscErrorCode PetscDrawCreate(MPI_Comm comm, const char display[], const char title[], int x, int y, int w, int h, PetscDraw *indraw) 136 { 137 PetscDraw draw; 138 PetscReal dpause = 0.0; 139 PetscBool flag; 140 141 PetscFunctionBegin; 142 PetscCall(PetscDrawInitializePackage()); 143 *indraw = NULL; 144 PetscCall(PetscHeaderCreate(draw, PETSC_DRAW_CLASSID, "Draw", "Graphics", "Draw", comm, PetscDrawDestroy, PetscDrawView)); 145 146 draw->data = NULL; 147 PetscCall(PetscStrallocpy(display, &draw->display)); 148 PetscCall(PetscStrallocpy(title, &draw->title)); 149 draw->x = x; 150 draw->y = y; 151 draw->w = w; 152 draw->h = h; 153 draw->pause = 0.0; 154 draw->coor_xl = 0.0; 155 draw->coor_xr = 1.0; 156 draw->coor_yl = 0.0; 157 draw->coor_yr = 1.0; 158 draw->port_xl = 0.0; 159 draw->port_xr = 1.0; 160 draw->port_yl = 0.0; 161 draw->port_yr = 1.0; 162 draw->popup = NULL; 163 164 PetscCall(PetscOptionsGetReal(NULL, NULL, "-draw_pause", &dpause, &flag)); 165 if (flag) draw->pause = dpause; 166 167 draw->savefilename = NULL; 168 draw->saveimageext = NULL; 169 draw->savemovieext = NULL; 170 draw->savefilecount = 0; 171 draw->savesinglefile = PETSC_FALSE; 172 draw->savemoviefps = PETSC_DECIDE; 173 174 PetscCall(PetscDrawSetCurrentPoint(draw, .5, .9)); 175 176 draw->boundbox_xl = .5; 177 draw->boundbox_xr = .5; 178 draw->boundbox_yl = .9; 179 draw->boundbox_yr = .9; 180 181 *indraw = draw; 182 PetscFunctionReturn(PETSC_SUCCESS); 183 } 184 185 /*@C 186 PetscDrawSetType - Builds graphics object for a particular implementation 187 188 Collective 189 190 Input Parameters: 191 + draw - the graphics context 192 - type - for example, `PETSC_DRAW_X` 193 194 Options Database Key: 195 . -draw_type <type> - Sets the type; use -help for a list of available methods (for instance, x) 196 197 Level: intermediate 198 199 Note: 200 See `PetscDrawSetFromOptions()` for additional options database keys 201 202 See "petsc/include/petscdraw.h" for available methods (for instance, 203 `PETSC_DRAW_X`, `PETSC_DRAW_TIKZ` or `PETSC_DRAW_IMAGE`) 204 205 .seealso: `PetscDraw`, `PETSC_DRAW_X`, `PETSC_DRAW_TIKZ`, `PETSC_DRAW_IMAGE`, `PetscDrawSetFromOptions()`, `PetscDrawCreate()`, `PetscDrawDestroy()`, `PetscDrawType` 206 @*/ 207 PetscErrorCode PetscDrawSetType(PetscDraw draw, PetscDrawType type) 208 { 209 PetscBool match; 210 PetscBool flg = PETSC_FALSE; 211 PetscErrorCode (*r)(PetscDraw); 212 213 PetscFunctionBegin; 214 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 215 PetscAssertPointer(type, 2); 216 217 PetscCall(PetscObjectTypeCompare((PetscObject)draw, type, &match)); 218 if (match) PetscFunctionReturn(PETSC_SUCCESS); 219 220 /* User requests no graphics */ 221 PetscCall(PetscOptionsHasName(((PetscObject)draw)->options, NULL, "-nox", &flg)); 222 223 /* 224 This is not ideal, but it allows codes to continue to run if X graphics 225 was requested but is not installed on this machine. Mostly this is for 226 testing. 227 */ 228 #if !defined(PETSC_HAVE_X) 229 if (!flg) { 230 PetscCall(PetscStrcmp(type, PETSC_DRAW_X, &match)); 231 if (match) { 232 PetscBool dontwarn = PETSC_TRUE; 233 flg = PETSC_TRUE; 234 PetscCall(PetscOptionsHasName(NULL, NULL, "-nox_warning", &dontwarn)); 235 if (!dontwarn) PetscCall((*PetscErrorPrintf)("PETSc installed without X Windows on this machine\nproceeding without graphics\n")); 236 } 237 } 238 #endif 239 if (flg) { 240 PetscCall(PetscStrcmp(type, "tikz", &flg)); 241 if (!flg) type = PETSC_DRAW_NULL; 242 } 243 244 PetscCall(PetscStrcmp(type, PETSC_DRAW_NULL, &match)); 245 if (match) { 246 PetscCall(PetscOptionsHasName(NULL, NULL, "-draw_double_buffer", NULL)); 247 PetscCall(PetscOptionsHasName(NULL, NULL, "-draw_virtual", NULL)); 248 PetscCall(PetscOptionsHasName(NULL, NULL, "-draw_fast", NULL)); 249 PetscCall(PetscOptionsHasName(NULL, NULL, "-draw_ports", NULL)); 250 PetscCall(PetscOptionsHasName(NULL, NULL, "-draw_coordinates", NULL)); 251 } 252 253 PetscCall(PetscFunctionListFind(PetscDrawList, type, &r)); 254 PetscCheck(r, PetscObjectComm((PetscObject)draw), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscDraw type given: %s", type); 255 PetscTryTypeMethod(draw, destroy); 256 PetscCall(PetscMemzero(draw->ops, sizeof(struct _PetscDrawOps))); 257 PetscCall(PetscObjectChangeTypeName((PetscObject)draw, type)); 258 PetscCall((*r)(draw)); 259 PetscFunctionReturn(PETSC_SUCCESS); 260 } 261 262 /*@C 263 PetscDrawGetType - Gets the `PetscDraw` type as a string from the `PetscDraw` object. 264 265 Not Collective 266 267 Input Parameter: 268 . draw - Krylov context 269 270 Output Parameter: 271 . type - name of PetscDraw method 272 273 Level: advanced 274 275 .seealso: `PetscDraw`, `PetscDrawType`, `PetscDrawSetType()`, `PetscDrawCreate()` 276 @*/ 277 PetscErrorCode PetscDrawGetType(PetscDraw draw, PetscDrawType *type) 278 { 279 PetscFunctionBegin; 280 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 281 PetscAssertPointer(type, 2); 282 *type = ((PetscObject)draw)->type_name; 283 PetscFunctionReturn(PETSC_SUCCESS); 284 } 285 286 /*@C 287 PetscDrawRegister - Adds a method to the graphics package. 288 289 Not Collective 290 291 Input Parameters: 292 + sname - name of a new user-defined graphics class 293 - function - routine to create method context 294 295 Level: developer 296 297 Note: 298 `PetscDrawRegister()` may be called multiple times to add several user-defined graphics classes 299 300 Example Usage: 301 .vb 302 PetscDrawRegister("my_draw_type", MyDrawCreate); 303 .ve 304 305 Then, your specific graphics package can be chosen with the procedural interface via 306 $ PetscDrawSetType(ksp, "my_draw_type") 307 or at runtime via the option 308 $ -draw_type my_draw_type 309 310 .seealso: `PetscDraw`, `PetscDrawRegisterAll()`, `PetscDrawRegisterDestroy()`, `PetscDrawType`, `PetscDrawSetType()` 311 @*/ 312 PetscErrorCode PetscDrawRegister(const char *sname, PetscErrorCode (*function)(PetscDraw)) 313 { 314 PetscFunctionBegin; 315 PetscCall(PetscDrawInitializePackage()); 316 PetscCall(PetscFunctionListAdd(&PetscDrawList, sname, function)); 317 PetscFunctionReturn(PETSC_SUCCESS); 318 } 319 320 /*@C 321 PetscDrawSetOptionsPrefix - Sets the prefix used for searching for all 322 `PetscDraw` options in the database. 323 324 Logically Collective 325 326 Input Parameters: 327 + draw - the draw context 328 - prefix - the prefix to prepend to all option names 329 330 Level: advanced 331 332 .seealso: `PetscDraw`, `PetscDrawSetFromOptions()`, `PetscDrawCreate()` 333 @*/ 334 PetscErrorCode PetscDrawSetOptionsPrefix(PetscDraw draw, const char prefix[]) 335 { 336 PetscFunctionBegin; 337 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 338 PetscCall(PetscObjectSetOptionsPrefix((PetscObject)draw, prefix)); 339 PetscFunctionReturn(PETSC_SUCCESS); 340 } 341 342 /*@ 343 PetscDrawSetFromOptions - Sets the graphics type from the options database. 344 Defaults to a PETSc X Windows graphics. 345 346 Collective 347 348 Input Parameter: 349 . draw - the graphics context 350 351 Options Database Keys: 352 + -nox - do not use X graphics (ignore graphics calls, but run program correctly) 353 . -nox_warning - when X Windows support is not installed this prevents the warning message from being printed 354 . -draw_pause <pause amount> - - -1 indicates wait for mouse input, -2 indicates pause when window is to be destroyed 355 . -draw_marker_type - <x,point> 356 . -draw_save [optional filename] - (X Windows only) saves each image before it is cleared to a file 357 . -draw_save_final_image [optional filename] - (X Windows only) saves the final image displayed in a window 358 . -draw_save_movie - converts image files to a movie at the end of the run. See PetscDrawSetSave() 359 . -draw_save_single_file - saves each new image in the same file, normally each new image is saved in a new file with 'filename/filename_%d.ext' 360 . -draw_save_on_clear - saves an image on each clear, mainly for debugging 361 - -draw_save_on_flush - saves an image on each flush, mainly for debugging 362 363 Level: intermediate 364 365 Note: 366 Must be called after `PetscDrawCreate()` before the `PetscDraw` is used. 367 368 .seealso: `PetscDraw`, `PetscDrawCreate()`, `PetscDrawSetType()`, `PetscDrawSetSave()`, `PetscDrawSetSaveFinalImage()`, `PetscDrawPause()`, `PetscDrawSetPause()` 369 @*/ 370 PetscErrorCode PetscDrawSetFromOptions(PetscDraw draw) 371 { 372 PetscBool flg, nox; 373 char vtype[256]; 374 const char *def; 375 #if !defined(PETSC_USE_WINDOWS_GRAPHICS) && !defined(PETSC_HAVE_X) 376 PetscBool warn; 377 #endif 378 379 PetscFunctionBegin; 380 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 381 382 PetscCall(PetscDrawRegisterAll()); 383 384 if (((PetscObject)draw)->type_name) def = ((PetscObject)draw)->type_name; 385 else { 386 PetscCall(PetscOptionsHasName(((PetscObject)draw)->options, NULL, "-nox", &nox)); 387 def = PETSC_DRAW_NULL; 388 #if defined(PETSC_USE_WINDOWS_GRAPHICS) 389 if (!nox) def = PETSC_DRAW_WIN32; 390 #elif defined(PETSC_HAVE_X) 391 if (!nox) def = PETSC_DRAW_X; 392 #else 393 PetscCall(PetscOptionsHasName(NULL, NULL, "-nox_warning", &warn)); 394 if (!nox && !warn) PetscCall((*PetscErrorPrintf)("PETSc installed without X Windows or Microsoft Graphics on this machine\nproceeding without graphics\n")); 395 #endif 396 } 397 PetscObjectOptionsBegin((PetscObject)draw); 398 PetscCall(PetscOptionsFList("-draw_type", "Type of graphical output", "PetscDrawSetType", PetscDrawList, def, vtype, 256, &flg)); 399 if (flg) { 400 PetscCall(PetscDrawSetType(draw, vtype)); 401 } else if (!((PetscObject)draw)->type_name) { 402 PetscCall(PetscDrawSetType(draw, def)); 403 } 404 PetscCall(PetscOptionsName("-nox", "Run without graphics", "None", &nox)); 405 { 406 char filename[PETSC_MAX_PATH_LEN]; 407 char movieext[32]; 408 PetscBool image, movie; 409 PetscCall(PetscSNPrintf(filename, sizeof(filename), "%s%s", draw->savefilename ? draw->savefilename : "", draw->saveimageext ? draw->saveimageext : "")); 410 PetscCall(PetscSNPrintf(movieext, sizeof(movieext), "%s", draw->savemovieext ? draw->savemovieext : "")); 411 PetscCall(PetscOptionsString("-draw_save", "Save graphics to image file", "PetscDrawSetSave", filename, filename, sizeof(filename), &image)); 412 PetscCall(PetscOptionsString("-draw_save_movie", "Make a movie from saved images", "PetscDrawSetSaveMovie", movieext, movieext, sizeof(movieext), &movie)); 413 PetscCall(PetscOptionsInt("-draw_save_movie_fps", "Set frames per second in saved movie", PETSC_FUNCTION_NAME, draw->savemoviefps, &draw->savemoviefps, NULL)); 414 PetscCall(PetscOptionsBool("-draw_save_single_file", "Each new image replaces previous image in file", PETSC_FUNCTION_NAME, draw->savesinglefile, &draw->savesinglefile, NULL)); 415 if (image) PetscCall(PetscDrawSetSave(draw, filename)); 416 if (movie) PetscCall(PetscDrawSetSaveMovie(draw, movieext)); 417 PetscCall(PetscOptionsString("-draw_save_final_image", "Save final graphics to image file", "PetscDrawSetSaveFinalImage", filename, filename, sizeof(filename), &image)); 418 if (image) PetscCall(PetscDrawSetSaveFinalImage(draw, filename)); 419 PetscCall(PetscOptionsBool("-draw_save_on_clear", "Save graphics to file on each clear", PETSC_FUNCTION_NAME, draw->saveonclear, &draw->saveonclear, NULL)); 420 PetscCall(PetscOptionsBool("-draw_save_on_flush", "Save graphics to file on each flush", PETSC_FUNCTION_NAME, draw->saveonflush, &draw->saveonflush, NULL)); 421 } 422 PetscCall(PetscOptionsReal("-draw_pause", "Amount of time that program pauses after plots", "PetscDrawSetPause", draw->pause, &draw->pause, NULL)); 423 PetscCall(PetscOptionsEnum("-draw_marker_type", "Type of marker to use on plots", "PetscDrawSetMarkerType", PetscDrawMarkerTypes, (PetscEnum)draw->markertype, (PetscEnum *)&draw->markertype, NULL)); 424 425 /* process any options handlers added with PetscObjectAddOptionsHandler() */ 426 PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)draw, PetscOptionsObject)); 427 428 PetscCall(PetscDrawViewFromOptions(draw, NULL, "-draw_view")); 429 PetscOptionsEnd(); 430 PetscFunctionReturn(PETSC_SUCCESS); 431 } 432