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