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