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