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