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