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 PetscErrorCode ierr; 381 PetscBool flg,nox; 382 char vtype[256]; 383 const char *def; 384 #if !defined(PETSC_USE_WINDOWS_GRAPHICS) && !defined(PETSC_HAVE_X) 385 PetscBool warn; 386 #endif 387 388 PetscFunctionBegin; 389 PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1); 390 391 PetscCall(PetscDrawRegisterAll()); 392 393 if (((PetscObject)draw)->type_name) def = ((PetscObject)draw)->type_name; 394 else { 395 PetscCall(PetscOptionsHasName(((PetscObject)draw)->options,NULL,"-nox",&nox)); 396 def = PETSC_DRAW_NULL; 397 #if defined(PETSC_USE_WINDOWS_GRAPHICS) 398 if (!nox) def = PETSC_DRAW_WIN32; 399 #elif defined(PETSC_HAVE_X) 400 if (!nox) def = PETSC_DRAW_X; 401 #else 402 PetscCall(PetscOptionsHasName(NULL,NULL,"-nox_warning",&warn)); 403 if (!nox && !warn) (*PetscErrorPrintf)("PETSc installed without X Windows or Microsoft Graphics on this machine\nproceeding without graphics\n"); 404 #endif 405 } 406 ierr = PetscObjectOptionsBegin((PetscObject)draw);PetscCall(ierr); 407 PetscCall(PetscOptionsFList("-draw_type","Type of graphical output","PetscDrawSetType",PetscDrawList,def,vtype,256,&flg)); 408 if (flg) { 409 PetscCall(PetscDrawSetType(draw,vtype)); 410 } else if (!((PetscObject)draw)->type_name) { 411 PetscCall(PetscDrawSetType(draw,def)); 412 } 413 PetscCall(PetscOptionsName("-nox","Run without graphics","None",&nox)); 414 { 415 char filename[PETSC_MAX_PATH_LEN]; 416 char movieext[32]; 417 PetscBool image,movie; 418 PetscCall(PetscSNPrintf(filename,sizeof(filename),"%s%s",draw->savefilename?draw->savefilename:"",draw->saveimageext?draw->saveimageext:"")); 419 PetscCall(PetscSNPrintf(movieext,sizeof(movieext),"%s",draw->savemovieext?draw->savemovieext:"")); 420 PetscCall(PetscOptionsString("-draw_save","Save graphics to image file","PetscDrawSetSave",filename,filename,sizeof(filename),&image)); 421 PetscCall(PetscOptionsString("-draw_save_movie","Make a movie from saved images","PetscDrawSetSaveMovie",movieext,movieext,sizeof(movieext),&movie)); 422 PetscCall(PetscOptionsInt("-draw_save_movie_fps","Set frames per second in saved movie",PETSC_FUNCTION_NAME,draw->savemoviefps,&draw->savemoviefps,NULL)); 423 PetscCall(PetscOptionsBool("-draw_save_single_file","Each new image replaces previous image in file",PETSC_FUNCTION_NAME,draw->savesinglefile,&draw->savesinglefile,NULL)); 424 if (image) PetscCall(PetscDrawSetSave(draw,filename)); 425 if (movie) PetscCall(PetscDrawSetSaveMovie(draw,movieext)); 426 PetscCall(PetscOptionsString("-draw_save_final_image","Save final graphics to image file","PetscDrawSetSaveFinalImage",filename,filename,sizeof(filename),&image)); 427 if (image) PetscCall(PetscDrawSetSaveFinalImage(draw,filename)); 428 PetscCall(PetscOptionsBool("-draw_save_on_clear","Save graphics to file on each clear",PETSC_FUNCTION_NAME,draw->saveonclear,&draw->saveonclear,NULL)); 429 PetscCall(PetscOptionsBool("-draw_save_on_flush","Save graphics to file on each flush",PETSC_FUNCTION_NAME,draw->saveonflush,&draw->saveonflush,NULL)); 430 } 431 PetscCall(PetscOptionsReal("-draw_pause","Amount of time that program pauses after plots","PetscDrawSetPause",draw->pause,&draw->pause,NULL)); 432 PetscCall(PetscOptionsEnum("-draw_marker_type","Type of marker to use on plots","PetscDrawSetMarkerType",PetscDrawMarkerTypes,(PetscEnum)draw->markertype,(PetscEnum *)&draw->markertype,NULL)); 433 434 /* process any options handlers added with PetscObjectAddOptionsHandler() */ 435 PetscCall(PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)draw)); 436 437 PetscCall(PetscDrawViewFromOptions(draw,NULL,"-draw_view")); 438 ierr = PetscOptionsEnd();PetscCall(ierr); 439 PetscFunctionReturn(0); 440 } 441