1 2 #include <../src/sys/classes/viewer/impls/draw/vdraw.h> /*I "petscdraw.h" I*/ 3 4 #undef __FUNCT__ 5 #define __FUNCT__ "PetscViewerDestroy_Draw" 6 PetscErrorCode PetscViewerDestroy_Draw(PetscViewer v) 7 { 8 PetscErrorCode ierr; 9 PetscInt i; 10 PetscViewer_Draw *vdraw = (PetscViewer_Draw*)v->data; 11 12 PetscFunctionBegin; 13 if (vdraw->singleton_made) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Destroying PetscViewer without first restoring singleton"); 14 for (i=0; i<vdraw->draw_max; i++) { 15 ierr = PetscDrawAxisDestroy(&vdraw->drawaxis[i]);CHKERRQ(ierr); 16 ierr = PetscDrawLGDestroy(&vdraw->drawlg[i]);CHKERRQ(ierr); 17 ierr = PetscDrawDestroy(&vdraw->draw[i]);CHKERRQ(ierr); 18 } 19 20 ierr = PetscFree(vdraw->display);CHKERRQ(ierr); 21 ierr = PetscFree(vdraw->title);CHKERRQ(ierr); 22 ierr = PetscFree3(vdraw->draw,vdraw->drawlg,vdraw->drawaxis);CHKERRQ(ierr); 23 ierr = PetscFree(vdraw->bounds);CHKERRQ(ierr); 24 ierr = PetscFree(vdraw);CHKERRQ(ierr); 25 PetscFunctionReturn(0); 26 } 27 28 #undef __FUNCT__ 29 #define __FUNCT__ "PetscViewerFlush_Draw" 30 PetscErrorCode PetscViewerFlush_Draw(PetscViewer v) 31 { 32 PetscErrorCode ierr; 33 PetscInt i; 34 PetscViewer_Draw *vdraw = (PetscViewer_Draw*)v->data; 35 36 PetscFunctionBegin; 37 for (i=0; i<vdraw->draw_max; i++) { 38 if (vdraw->draw[i]) {ierr = PetscDrawSynchronizedFlush(vdraw->draw[i]);CHKERRQ(ierr);} 39 } 40 PetscFunctionReturn(0); 41 } 42 43 #undef __FUNCT__ 44 #define __FUNCT__ "PetscViewerDrawGetDraw" 45 /*@C 46 PetscViewerDrawGetDraw - Returns PetscDraw object from PetscViewer object. 47 This PetscDraw object may then be used to perform graphics using 48 PetscDrawXXX() commands. 49 50 Not collective (but PetscDraw returned will be parallel object if PetscViewer is) 51 52 Input Parameters: 53 + viewer - the PetscViewer (created with PetscViewerDrawOpen()) 54 - windownumber - indicates which subwindow (usually 0) 55 56 Ouput Parameter: 57 . draw - the draw object 58 59 Level: intermediate 60 61 Concepts: drawing^accessing PetscDraw context from PetscViewer 62 Concepts: graphics 63 64 .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen() 65 @*/ 66 PetscErrorCode PetscViewerDrawGetDraw(PetscViewer viewer,PetscInt windownumber,PetscDraw *draw) 67 { 68 PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data; 69 PetscErrorCode ierr; 70 PetscBool isdraw; 71 char *title; 72 73 PetscFunctionBegin; 74 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 75 if (draw) PetscValidPointer(draw,3); 76 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 77 if (!isdraw) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer"); 78 if (windownumber < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Window number cannot be negative"); 79 windownumber += vdraw->draw_base; 80 if (windownumber >= vdraw->draw_max) { 81 /* allocate twice as many slots as needed */ 82 PetscInt draw_max = vdraw->draw_max; 83 PetscDraw *tdraw = vdraw->draw; 84 PetscDrawLG *drawlg = vdraw->drawlg; 85 PetscDrawAxis *drawaxis = vdraw->drawaxis; 86 87 vdraw->draw_max = 2*windownumber; 88 89 ierr = PetscMalloc3(vdraw->draw_max,PetscDraw,&vdraw->draw,vdraw->draw_max,PetscDrawLG,&vdraw->drawlg,vdraw->draw_max,PetscDrawAxis,&vdraw->drawaxis);CHKERRQ(ierr); 90 ierr = PetscMemzero(vdraw->draw,vdraw->draw_max*sizeof(PetscDraw));CHKERRQ(ierr); 91 ierr = PetscMemzero(vdraw->drawlg,vdraw->draw_max*sizeof(PetscDrawLG));CHKERRQ(ierr); 92 ierr = PetscMemzero(vdraw->drawaxis,vdraw->draw_max*sizeof(PetscDrawAxis));CHKERRQ(ierr); 93 94 ierr = PetscMemcpy(vdraw->draw,tdraw,draw_max*sizeof(PetscDraw));CHKERRQ(ierr); 95 ierr = PetscMemcpy(vdraw->drawlg,drawlg,draw_max*sizeof(PetscDrawLG));CHKERRQ(ierr); 96 ierr = PetscMemcpy(vdraw->drawaxis,drawaxis,draw_max*sizeof(PetscDrawAxis));CHKERRQ(ierr); 97 98 ierr = PetscFree3(tdraw,drawlg,drawaxis);CHKERRQ(ierr); 99 } 100 101 if (!vdraw->draw[windownumber]) { 102 if (!windownumber) title = vdraw->title; 103 else { 104 char tmp_str[128]; 105 ierr = PetscSNPrintf(tmp_str, 128, "%s:%d", vdraw->title,windownumber);CHKERRQ(ierr); 106 title = tmp_str; 107 } 108 ierr = PetscDrawCreate(((PetscObject)viewer)->comm,vdraw->display,title,PETSC_DECIDE,PETSC_DECIDE,vdraw->w,vdraw->h,&vdraw->draw[windownumber]);CHKERRQ(ierr); 109 ierr = PetscDrawSetFromOptions(vdraw->draw[windownumber]);CHKERRQ(ierr); 110 } 111 if (draw) *draw = vdraw->draw[windownumber]; 112 if (draw) PetscValidHeaderSpecific(*draw,PETSC_DRAW_CLASSID,-1); 113 PetscFunctionReturn(0); 114 } 115 116 #undef __FUNCT__ 117 #define __FUNCT__ "PetscViewerDrawBaseAdd" 118 /*@C 119 PetscViewerDrawBaseAdd - add to the base integer that is added to the windownumber passed to PetscViewerDrawGetDraw() 120 121 Not collective (but PetscDraw returned will be parallel object if PetscViewer is) 122 123 Input Parameters: 124 + viewer - the PetscViewer (created with PetscViewerDrawOpen()) 125 - windownumber - how much to add to the base 126 127 Level: developer 128 129 Concepts: drawing^accessing PetscDraw context from PetscViewer 130 Concepts: graphics 131 132 .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), PetscViewerDrawBaseSet() 133 @*/ 134 PetscErrorCode PetscViewerDrawBaseAdd(PetscViewer viewer,PetscInt windownumber) 135 { 136 PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data; 137 PetscErrorCode ierr; 138 PetscBool isdraw; 139 140 PetscFunctionBegin; 141 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 142 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 143 if (!isdraw) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer"); 144 if (windownumber + vdraw->draw_base < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Resulting base %D cannot be negative",windownumber+vdraw->draw_base); 145 vdraw->draw_base += windownumber; 146 PetscFunctionReturn(0); 147 } 148 149 #undef __FUNCT__ 150 #define __FUNCT__ "PetscViewerDrawBaseSet" 151 /*@C 152 PetscViewerDrawBaseSet - sets the base integer that is added to the windownumber passed to PetscViewerDrawGetDraw() 153 154 Not collective (but PetscDraw returned will be parallel object if PetscViewer is) 155 156 Input Parameters: 157 + viewer - the PetscViewer (created with PetscViewerDrawOpen()) 158 - windownumber - value to set the base 159 160 Level: developer 161 162 Concepts: drawing^accessing PetscDraw context from PetscViewer 163 Concepts: graphics 164 165 .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), PetscViewerDrawBaseAdd() 166 @*/ 167 PetscErrorCode PetscViewerDrawBaseSet(PetscViewer viewer,PetscInt windownumber) 168 { 169 PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data; 170 PetscErrorCode ierr; 171 PetscBool isdraw; 172 173 PetscFunctionBegin; 174 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 175 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 176 if (!isdraw) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer"); 177 if (windownumber < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Resulting base %D cannot be negative",windownumber); 178 vdraw->draw_base = windownumber; 179 PetscFunctionReturn(0); 180 } 181 182 #undef __FUNCT__ 183 #define __FUNCT__ "PetscViewerDrawGetDrawLG" 184 /*@C 185 PetscViewerDrawGetDrawLG - Returns PetscDrawLG object from PetscViewer object. 186 This PetscDrawLG object may then be used to perform graphics using 187 PetscDrawLGXXX() commands. 188 189 Not Collective (but PetscDrawLG object will be parallel if PetscViewer is) 190 191 Input Parameter: 192 + PetscViewer - the PetscViewer (created with PetscViewerDrawOpen()) 193 - windownumber - indicates which subwindow (usually 0) 194 195 Ouput Parameter: 196 . draw - the draw line graph object 197 198 Level: intermediate 199 200 Concepts: line graph^accessing context 201 202 .seealso: PetscViewerDrawGetDraw(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen() 203 @*/ 204 PetscErrorCode PetscViewerDrawGetDrawLG(PetscViewer viewer,PetscInt windownumber,PetscDrawLG *drawlg) 205 { 206 PetscErrorCode ierr; 207 PetscBool isdraw; 208 PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data; 209 210 PetscFunctionBegin; 211 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 212 PetscValidPointer(drawlg,3); 213 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 214 if (!isdraw) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer"); 215 if (windownumber < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Window number cannot be negative"); 216 217 if (windownumber+vdraw->draw_base >= vdraw->draw_max || !vdraw->draw[windownumber+vdraw->draw_base]) { 218 ierr = PetscViewerDrawGetDraw(viewer,windownumber,PETSC_NULL);CHKERRQ(ierr); 219 } 220 if (!vdraw->drawlg[windownumber+vdraw->draw_base]) { 221 ierr = PetscDrawLGCreate(vdraw->draw[windownumber+vdraw->draw_base],1,&vdraw->drawlg[windownumber+vdraw->draw_base]);CHKERRQ(ierr); 222 ierr = PetscLogObjectParent(viewer,vdraw->drawlg[windownumber+vdraw->draw_base]);CHKERRQ(ierr); 223 } 224 *drawlg = vdraw->drawlg[windownumber+vdraw->draw_base]; 225 PetscFunctionReturn(0); 226 } 227 228 #undef __FUNCT__ 229 #define __FUNCT__ "PetscViewerDrawGetDrawAxis" 230 /*@C 231 PetscViewerDrawGetDrawAxis - Returns PetscDrawAxis object from PetscViewer object. 232 This PetscDrawAxis object may then be used to perform graphics using 233 PetscDrawAxisXXX() commands. 234 235 Not Collective (but PetscDrawAxis object will be parallel if PetscViewer is) 236 237 Input Parameter: 238 + viewer - the PetscViewer (created with PetscViewerDrawOpen() 239 - windownumber - indicates which subwindow (usually 0) 240 241 Ouput Parameter: 242 . drawaxis - the draw axis object 243 244 Level: advanced 245 246 Concepts: line graph^accessing context 247 248 .seealso: PetscViewerDrawGetDraw(), PetscViewerDrawGetLG(), PetscViewerDrawOpen() 249 @*/ 250 PetscErrorCode PetscViewerDrawGetDrawAxis(PetscViewer viewer,PetscInt windownumber,PetscDrawAxis *drawaxis) 251 { 252 PetscErrorCode ierr; 253 PetscBool isdraw; 254 PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;; 255 256 PetscFunctionBegin; 257 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 258 PetscValidPointer(drawaxis,3); 259 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 260 if (!isdraw) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer"); 261 if (windownumber < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Window number cannot be negative"); 262 263 if (windownumber+vdraw->draw_base >= vdraw->draw_max || !vdraw->draw[windownumber+vdraw->draw_base]) { 264 ierr = PetscViewerDrawGetDraw(viewer,windownumber,PETSC_NULL);CHKERRQ(ierr); 265 } 266 if (!vdraw->drawaxis[windownumber+vdraw->draw_base]) { 267 ierr = PetscDrawAxisCreate(vdraw->draw[windownumber+vdraw->draw_base],&vdraw->drawaxis[windownumber+vdraw->draw_base]);CHKERRQ(ierr); 268 ierr = PetscLogObjectParent(viewer,vdraw->drawaxis[windownumber+vdraw->draw_base]);CHKERRQ(ierr); 269 } 270 *drawaxis = vdraw->drawaxis[windownumber+vdraw->draw_base]; 271 PetscFunctionReturn(0); 272 } 273 274 #undef __FUNCT__ 275 #define __FUNCT__ "PetscViewerDrawResize" 276 PetscErrorCode PetscViewerDrawResize(PetscViewer v,int w,int h) 277 { 278 PetscViewer_Draw *vdraw = (PetscViewer_Draw*)v->data; 279 280 PetscFunctionBegin; 281 vdraw->h = h; 282 vdraw->w = w; 283 PetscFunctionReturn(0); 284 } 285 286 #undef __FUNCT__ 287 #define __FUNCT__ "PetscViewerDrawSetInfo" 288 PetscErrorCode PetscViewerDrawSetInfo(PetscViewer v,const char display[],const char title[],int x,int y,int w,int h) 289 { 290 PetscErrorCode ierr; 291 PetscViewer_Draw *vdraw = (PetscViewer_Draw*)v->data; 292 293 PetscFunctionBegin; 294 vdraw->h = h; 295 vdraw->w = w; 296 ierr = PetscStrallocpy(display,&vdraw->display);CHKERRQ(ierr); 297 ierr = PetscStrallocpy(title,&vdraw->title);CHKERRQ(ierr); 298 PetscFunctionReturn(0); 299 } 300 301 #undef __FUNCT__ 302 #define __FUNCT__ "PetscViewerDrawOpen" 303 /*@C 304 PetscViewerDrawOpen - Opens a window for use as a PetscViewer. If you want to 305 do graphics in this window, you must call PetscViewerDrawGetDraw() and 306 perform the graphics on the PetscDraw object. 307 308 Collective on MPI_Comm 309 310 Input Parameters: 311 + comm - communicator that will share window 312 . display - the X display on which to open, or null for the local machine 313 . title - the title to put in the title bar, or null for no title 314 . x, y - the screen coordinates of the upper left corner of window, or use PETSC_DECIDE 315 - w, h - window width and height in pixels, or may use PETSC_DECIDE or PETSC_DRAW_FULL_SIZE, PETSC_DRAW_HALF_SIZE, 316 PETSC_DRAW_THIRD_SIZE, PETSC_DRAW_QUARTER_SIZE 317 318 Output Parameters: 319 . viewer - the PetscViewer 320 321 Format Options: 322 + PETSC_VIEWER_DRAW_BASIC - displays with basic format 323 - PETSC_VIEWER_DRAW_LG - displays using a line graph 324 325 Options Database Keys: 326 PetscViewerDrawOpen() calls PetscDrawCreate(), so see the manual page for 327 PetscDrawCreate() for runtime options, including 328 + -draw_type x or null 329 . -nox - Disables all x-windows output 330 . -display <name> - Specifies name of machine for the X display 331 . -geometry <x,y,w,h> - allows setting the window location and size 332 - -draw_pause <pause> - Sets time (in seconds) that the 333 program pauses after PetscDrawPause() has been called 334 (0 is default, -1 implies until user input). 335 336 Level: beginner 337 338 Note for Fortran Programmers: 339 Whenever indicating null character data in a Fortran code, 340 PETSC_NULL_CHARACTER must be employed; using PETSC_NULL is not 341 correct for character data! Thus, PETSC_NULL_CHARACTER can be 342 used for the display and title input parameters. 343 344 Concepts: graphics^opening PetscViewer 345 Concepts: drawing^opening PetscViewer 346 347 348 .seealso: PetscDrawCreate(), PetscViewerDestroy(), PetscViewerDrawGetDraw(), PetscViewerCreate(), PETSC_VIEWER_DRAW_, 349 PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF 350 @*/ 351 PetscErrorCode PetscViewerDrawOpen(MPI_Comm comm,const char display[],const char title[],int x,int y,int w,int h,PetscViewer *viewer) 352 { 353 PetscErrorCode ierr; 354 355 PetscFunctionBegin; 356 ierr = PetscViewerCreate(comm,viewer);CHKERRQ(ierr); 357 ierr = PetscViewerSetType(*viewer,PETSCVIEWERDRAW);CHKERRQ(ierr); 358 ierr = PetscViewerDrawSetInfo(*viewer,display,title,x,y,w,h);CHKERRQ(ierr); 359 PetscFunctionReturn(0); 360 } 361 362 #undef __FUNCT__ 363 #define __FUNCT__ "PetscViewerGetSingleton_Draw" 364 PetscErrorCode PetscViewerGetSingleton_Draw(PetscViewer viewer,PetscViewer *sviewer) 365 { 366 PetscErrorCode ierr; 367 PetscMPIInt rank; 368 PetscInt i; 369 PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data,*vsdraw; 370 371 PetscFunctionBegin; 372 if (vdraw->singleton_made) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Trying to get singleton without first restoring previous"); 373 374 /* only processor zero can use the PetscViewer draw singleton */ 375 ierr = MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);CHKERRQ(ierr); 376 if (!rank) { 377 ierr = PetscViewerCreate(PETSC_COMM_SELF,sviewer);CHKERRQ(ierr); 378 ierr = PetscViewerSetType(*sviewer,PETSCVIEWERDRAW);CHKERRQ(ierr); 379 vsdraw = (PetscViewer_Draw*)(*sviewer)->data; 380 for (i=0; i<vdraw->draw_max; i++) { 381 if (vdraw->draw[i]) { 382 ierr = PetscDrawGetSingleton(vdraw->draw[i],&vsdraw->draw[i]);CHKERRQ(ierr); 383 } 384 } 385 } 386 vdraw->singleton_made = PETSC_TRUE; 387 PetscFunctionReturn(0); 388 } 389 390 #undef __FUNCT__ 391 #define __FUNCT__ "PetscViewerRestoreSingleton_Draw" 392 PetscErrorCode PetscViewerRestoreSingleton_Draw(PetscViewer viewer,PetscViewer *sviewer) 393 { 394 PetscErrorCode ierr; 395 PetscMPIInt rank; 396 PetscInt i; 397 PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data,*vsdraw; 398 399 PetscFunctionBegin; 400 if (!vdraw->singleton_made) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Trying to restore a singleton that was not gotten"); 401 ierr = MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);CHKERRQ(ierr); 402 if (!rank) { 403 vsdraw = (PetscViewer_Draw*)(*sviewer)->data; 404 for (i=0; i<vdraw->draw_max; i++) { 405 if (vdraw->draw[i] && vsdraw->draw[i]) { 406 ierr = PetscDrawRestoreSingleton(vdraw->draw[i],&vsdraw->draw[i]);CHKERRQ(ierr); 407 } 408 } 409 ierr = PetscFree3(vsdraw->draw,vsdraw->drawlg,vsdraw->drawaxis);CHKERRQ(ierr); 410 ierr = PetscFree((*sviewer)->data);CHKERRQ(ierr); 411 ierr = PetscHeaderDestroy(sviewer);CHKERRQ(ierr); 412 } 413 vdraw->singleton_made = PETSC_FALSE; 414 PetscFunctionReturn(0); 415 } 416 417 #undef __FUNCT__ 418 #define __FUNCT__ "PetscViewerSetFromOptions_Draw" 419 PetscErrorCode PetscViewerSetFromOptions_Draw(PetscViewer v) 420 { 421 PetscErrorCode ierr; 422 PetscReal bounds[16]; 423 PetscInt nbounds = 16; 424 PetscBool flg; 425 426 PetscFunctionBegin; 427 ierr = PetscOptionsHead("Draw PetscViewer Options");CHKERRQ(ierr); 428 ierr = PetscOptionsRealArray("-draw_bounds","Bounds to put on plots axis","PetscViewerDrawSetBounds",bounds,&nbounds,&flg);CHKERRQ(ierr); 429 if (flg) { 430 ierr = PetscViewerDrawSetBounds(v,nbounds/2,bounds);CHKERRQ(ierr); 431 } 432 433 ierr = PetscOptionsTail();CHKERRQ(ierr); 434 PetscFunctionReturn(0); 435 } 436 437 EXTERN_C_BEGIN 438 #undef __FUNCT__ 439 #define __FUNCT__ "PetscViewerCreate_Draw" 440 PetscErrorCode PetscViewerCreate_Draw(PetscViewer viewer) 441 { 442 PetscInt i; 443 PetscErrorCode ierr; 444 PetscViewer_Draw *vdraw; 445 446 PetscFunctionBegin; 447 ierr = PetscNewLog(viewer,PetscViewer_Draw,&vdraw);CHKERRQ(ierr); 448 viewer->data = (void*)vdraw; 449 450 viewer->ops->flush = PetscViewerFlush_Draw; 451 viewer->ops->destroy = PetscViewerDestroy_Draw; 452 viewer->ops->setfromoptions = PetscViewerSetFromOptions_Draw; 453 viewer->ops->getsingleton = PetscViewerGetSingleton_Draw; 454 viewer->ops->restoresingleton = PetscViewerRestoreSingleton_Draw; 455 viewer->format = PETSC_VIEWER_NOFORMAT; 456 457 /* these are created on the fly if requested */ 458 vdraw->draw_max = 5; 459 vdraw->draw_base = 0; 460 vdraw->w = PETSC_DECIDE; 461 vdraw->h = PETSC_DECIDE; 462 463 ierr = PetscMalloc3(vdraw->draw_max,PetscDraw,&vdraw->draw,vdraw->draw_max,PetscDrawLG,&vdraw->drawlg,vdraw->draw_max,PetscDrawAxis,&vdraw->drawaxis);CHKERRQ(ierr); 464 ierr = PetscMemzero(vdraw->draw,vdraw->draw_max*sizeof(PetscDraw));CHKERRQ(ierr); 465 ierr = PetscMemzero(vdraw->drawlg,vdraw->draw_max*sizeof(PetscDrawLG));CHKERRQ(ierr); 466 ierr = PetscMemzero(vdraw->drawaxis,vdraw->draw_max*sizeof(PetscDrawAxis));CHKERRQ(ierr); 467 for (i=0; i<vdraw->draw_max; i++) { 468 vdraw->draw[i] = 0; 469 vdraw->drawlg[i] = 0; 470 vdraw->drawaxis[i] = 0; 471 } 472 vdraw->singleton_made = PETSC_FALSE; 473 PetscFunctionReturn(0); 474 } 475 EXTERN_C_END 476 477 #undef __FUNCT__ 478 #define __FUNCT__ "PetscViewerDrawClear" 479 /*@ 480 PetscViewerDrawClear - Clears a PetscDraw graphic associated with a PetscViewer. 481 482 Not Collective 483 484 Input Parameter: 485 . viewer - the PetscViewer 486 487 Level: intermediate 488 489 .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), 490 491 @*/ 492 PetscErrorCode PetscViewerDrawClear(PetscViewer viewer) 493 { 494 PetscErrorCode ierr; 495 PetscInt i; 496 PetscBool isdraw; 497 PetscViewer_Draw *vdraw; 498 499 PetscFunctionBegin; 500 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 501 if (isdraw) { 502 vdraw = (PetscViewer_Draw*)viewer->data; 503 for (i=0; i<vdraw->draw_max; i++) { 504 if (vdraw->draw[i]) {ierr = PetscDrawClear(vdraw->draw[i]);CHKERRQ(ierr);} 505 } 506 } 507 PetscFunctionReturn(0); 508 } 509 510 #undef __FUNCT__ 511 #define __FUNCT__ "PetscViewerDrawGetPause" 512 /*@ 513 PetscViewerDrawGetPause - Gets a pause for the first present draw 514 515 Not Collective 516 517 Input Parameter: 518 . viewer - the PetscViewer 519 520 Output Parameter: 521 . pause - the pause value 522 523 Level: intermediate 524 525 .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), 526 527 @*/ 528 PetscErrorCode PetscViewerDrawGetPause(PetscViewer viewer,PetscReal *pause) 529 { 530 PetscErrorCode ierr; 531 PetscInt i; 532 PetscBool isdraw; 533 PetscViewer_Draw *vdraw; 534 PetscDraw draw; 535 536 PetscFunctionBegin; 537 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 538 *pause = 0.0; 539 if (isdraw) { 540 vdraw = (PetscViewer_Draw*)viewer->data; 541 for (i=0; i<vdraw->draw_max; i++) { 542 if (vdraw->draw[i]) { 543 ierr = PetscDrawGetPause(vdraw->draw[i],pause);CHKERRQ(ierr); 544 PetscFunctionReturn(0); 545 } 546 } 547 /* none exist yet so create one and get its pause */ 548 ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 549 ierr = PetscDrawGetPause(vdraw->draw[0],pause);CHKERRQ(ierr); 550 } 551 PetscFunctionReturn(0); 552 } 553 554 #undef __FUNCT__ 555 #define __FUNCT__ "PetscViewerDrawSetPause" 556 /*@ 557 PetscViewerDrawSetPause - Sets a pause for each PetscDraw in the viewer 558 559 Not Collective 560 561 Input Parameters: 562 + viewer - the PetscViewer 563 - pause - the pause value 564 565 Level: intermediate 566 567 .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), 568 569 @*/ 570 PetscErrorCode PetscViewerDrawSetPause(PetscViewer viewer,PetscReal pause) 571 { 572 PetscErrorCode ierr; 573 PetscInt i; 574 PetscBool isdraw; 575 PetscViewer_Draw *vdraw; 576 577 PetscFunctionBegin; 578 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 579 if (isdraw) { 580 vdraw = (PetscViewer_Draw*)viewer->data; 581 for (i=0; i<vdraw->draw_max; i++) { 582 if (vdraw->draw[i]) {ierr = PetscDrawSetPause(vdraw->draw[i],pause);CHKERRQ(ierr);} 583 } 584 } 585 PetscFunctionReturn(0); 586 } 587 588 589 #undef __FUNCT__ 590 #define __FUNCT__ "PetscViewerDrawSetHold" 591 /*@ 592 PetscViewerDrawSetHold - Holds previous image when drawing new image 593 594 Not Collective 595 596 Input Parameters: 597 + viewer - the PetscViewer 598 - hold - indicates to hold or not 599 600 Level: intermediate 601 602 .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), 603 604 @*/ 605 PetscErrorCode PetscViewerDrawSetHold(PetscViewer viewer,PetscBool hold) 606 { 607 PetscErrorCode ierr; 608 PetscViewer_Draw *vdraw; 609 PetscBool isdraw; 610 611 PetscFunctionBegin; 612 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 613 if (isdraw) { 614 vdraw = (PetscViewer_Draw*)viewer->data; 615 vdraw->hold = hold; 616 } 617 PetscFunctionReturn(0); 618 } 619 620 #undef __FUNCT__ 621 #define __FUNCT__ "PetscViewerDrawGetHold" 622 /*@ 623 PetscViewerDrawGetHold - Holds previous image when drawing new image 624 625 Not Collective 626 627 Input Parameter: 628 . viewer - the PetscViewer 629 630 Output Parameter: 631 . hold - indicates to hold or not 632 633 Level: intermediate 634 635 .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), 636 637 @*/ 638 PetscErrorCode PetscViewerDrawGetHold(PetscViewer viewer,PetscBool *hold) 639 { 640 PetscErrorCode ierr; 641 PetscViewer_Draw *vdraw; 642 PetscBool isdraw; 643 644 PetscFunctionBegin; 645 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 646 if (isdraw) { 647 vdraw = (PetscViewer_Draw*)viewer->data; 648 *hold = vdraw->hold; 649 } 650 PetscFunctionReturn(0); 651 } 652 653 /* ---------------------------------------------------------------------*/ 654 /* 655 The variable Petsc_Viewer_Draw_keyval is used to indicate an MPI attribute that 656 is attached to a communicator, in this case the attribute is a PetscViewer. 657 */ 658 static PetscMPIInt Petsc_Viewer_Draw_keyval = MPI_KEYVAL_INVALID; 659 660 #undef __FUNCT__ 661 #define __FUNCT__ "PETSC_VIEWER_DRAW_" 662 /*@C 663 PETSC_VIEWER_DRAW_ - Creates a window PetscViewer shared by all processors 664 in a communicator. 665 666 Collective on MPI_Comm 667 668 Input Parameter: 669 . comm - the MPI communicator to share the window PetscViewer 670 671 Level: intermediate 672 673 Notes: 674 Unlike almost all other PETSc routines, PETSC_VIEWER_DRAW_ does not return 675 an error code. The window is usually used in the form 676 $ XXXView(XXX object,PETSC_VIEWER_DRAW_(comm)); 677 678 .seealso: PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF, PetscViewerDrawOpen(), 679 @*/ 680 PetscViewer PETSC_VIEWER_DRAW_(MPI_Comm comm) 681 { 682 PetscErrorCode ierr; 683 PetscMPIInt flag; 684 PetscViewer viewer; 685 MPI_Comm ncomm; 686 687 PetscFunctionBegin; 688 ierr = PetscCommDuplicate(comm,&ncomm,PETSC_NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 689 if (Petsc_Viewer_Draw_keyval == MPI_KEYVAL_INVALID) { 690 ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Draw_keyval,0); 691 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 692 } 693 ierr = MPI_Attr_get(ncomm,Petsc_Viewer_Draw_keyval,(void**)&viewer,&flag); 694 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 695 if (!flag) { /* PetscViewer not yet created */ 696 ierr = PetscViewerDrawOpen(ncomm,0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,&viewer); 697 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 698 ierr = PetscObjectRegisterDestroy((PetscObject)viewer); 699 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 700 ierr = MPI_Attr_put(ncomm,Petsc_Viewer_Draw_keyval,(void*)viewer); 701 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 702 } 703 ierr = PetscCommDestroy(&ncomm); 704 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 705 PetscFunctionReturn(viewer); 706 } 707 708 #undef __FUNCT__ 709 #define __FUNCT__ "PetscViewerDrawSetBounds" 710 /*@ 711 PetscViewerDrawSetBounds - sets the upper and lower bounds to be used in plotting 712 713 Collective on PetscViewer 714 715 Input Parameters: 716 + viewer - the PetscViewer (created with PetscViewerDrawOpen()) 717 . nbounds - number of plots that can be made with this viewer, for example the dof passed to DMDACreate() 718 - bounds - the actual bounds, the size of this is 2*nbounds, the values are stored in the order min F_0, max F_0, min F_1, max F_1, ..... 719 720 721 Options Database: 722 . -draw_bounds minF0,maxF0,minF1,maxF1 723 724 Level: intermediate 725 726 Notes: this determines the colors used in 2d contour plots generated with VecView() for DMDA in 2d. Any values in the vector below or above the 727 bounds are moved to the bound value before plotting. In this way the color index from color to physical value remains the same for all plots generated with 728 this viewer. Otherwise the color to physical value meaning changes with each new image if this is not set. 729 730 Concepts: drawing^accessing PetscDraw context from PetscViewer 731 Concepts: graphics 732 733 .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen() 734 @*/ 735 PetscErrorCode PetscViewerDrawSetBounds(PetscViewer viewer,PetscInt nbounds,const PetscReal *bounds) 736 { 737 PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data; 738 PetscErrorCode ierr; 739 740 741 PetscFunctionBegin; 742 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 743 vdraw->nbounds = nbounds; 744 745 ierr = PetscMalloc(2*nbounds*sizeof(PetscReal),&vdraw->bounds);CHKERRQ(ierr); 746 ierr = PetscMemcpy(vdraw->bounds,bounds,2*nbounds*sizeof(PetscReal));CHKERRQ(ierr); 747 PetscFunctionReturn(0); 748 } 749 750 #undef __FUNCT__ 751 #define __FUNCT__ "PetscViewerDrawGetBounds" 752 /*@C 753 PetscViewerDrawGetBounds - gets the upper and lower bounds to be used in plotting set with PetscViewerDrawSetBounds() 754 755 Collective on PetscViewer 756 757 Input Parameter: 758 . viewer - the PetscViewer (created with PetscViewerDrawOpen()) 759 760 Output Paramters: 761 + nbounds - number of plots that can be made with this viewer, for example the dof passed to DMDACreate() 762 - bounds - the actual bounds, the size of this is 2*nbounds, the values are stored in the order min F_0, max F_0, min F_1, max F_1, ..... 763 764 Level: intermediate 765 766 Concepts: drawing^accessing PetscDraw context from PetscViewer 767 Concepts: graphics 768 769 .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen(), PetscViewerDrawSetBounds() 770 @*/ 771 PetscErrorCode PetscViewerDrawGetBounds(PetscViewer viewer,PetscInt *nbounds,const PetscReal **bounds) 772 { 773 PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data; 774 775 PetscFunctionBegin; 776 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 777 *nbounds = vdraw->nbounds; 778 *bounds = vdraw->bounds; 779 PetscFunctionReturn(0); 780 } 781