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