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