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