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->drawtype);CHKERRQ(ierr); 26 ierr = PetscFree(vdraw);CHKERRQ(ierr); 27 PetscFunctionReturn(0); 28 } 29 30 #undef __FUNCT__ 31 #define __FUNCT__ "PetscViewerFlush_Draw" 32 PetscErrorCode PetscViewerFlush_Draw(PetscViewer v) 33 { 34 PetscErrorCode ierr; 35 PetscInt i; 36 PetscViewer_Draw *vdraw = (PetscViewer_Draw*)v->data; 37 38 PetscFunctionBegin; 39 for (i=0; i<vdraw->draw_max; i++) { 40 if (vdraw->draw[i]) {ierr = PetscDrawSynchronizedFlush(vdraw->draw[i]);CHKERRQ(ierr);} 41 } 42 PetscFunctionReturn(0); 43 } 44 45 #undef __FUNCT__ 46 #define __FUNCT__ "PetscViewerDrawGetDraw" 47 /*@C 48 PetscViewerDrawGetDraw - Returns PetscDraw object from PetscViewer object. 49 This PetscDraw object may then be used to perform graphics using 50 PetscDrawXXX() commands. 51 52 Not collective (but PetscDraw returned will be parallel object if PetscViewer is) 53 54 Input Parameters: 55 + viewer - the PetscViewer (created with PetscViewerDrawOpen()) 56 - windownumber - indicates which subwindow (usually 0) 57 58 Ouput Parameter: 59 . draw - the draw object 60 61 Level: intermediate 62 63 Concepts: drawing^accessing PetscDraw context from PetscViewer 64 Concepts: graphics 65 66 .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen() 67 @*/ 68 PetscErrorCode PetscViewerDrawGetDraw(PetscViewer viewer,PetscInt windownumber,PetscDraw *draw) 69 { 70 PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data; 71 PetscErrorCode ierr; 72 PetscBool isdraw; 73 char *title = vdraw->title; 74 75 PetscFunctionBegin; 76 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 77 if (draw) PetscValidPointer(draw,3); 78 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 79 if (!isdraw) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer"); 80 if (windownumber < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Window number cannot be negative"); 81 windownumber += vdraw->draw_base; 82 if (windownumber >= vdraw->draw_max) { 83 /* allocate twice as many slots as needed */ 84 PetscInt draw_max = vdraw->draw_max; 85 PetscDraw *tdraw = vdraw->draw; 86 PetscDrawLG *drawlg = vdraw->drawlg; 87 PetscDrawAxis *drawaxis = vdraw->drawaxis; 88 89 vdraw->draw_max = 2*windownumber; 90 91 ierr = PetscCalloc3(vdraw->draw_max,&vdraw->draw,vdraw->draw_max,&vdraw->drawlg,vdraw->draw_max,&vdraw->drawaxis);CHKERRQ(ierr); 92 93 ierr = PetscMemcpy(vdraw->draw,tdraw,draw_max*sizeof(PetscDraw));CHKERRQ(ierr); 94 ierr = PetscMemcpy(vdraw->drawlg,drawlg,draw_max*sizeof(PetscDrawLG));CHKERRQ(ierr); 95 ierr = PetscMemcpy(vdraw->drawaxis,drawaxis,draw_max*sizeof(PetscDrawAxis));CHKERRQ(ierr); 96 97 ierr = PetscFree3(tdraw,drawlg,drawaxis);CHKERRQ(ierr); 98 } 99 100 if (!vdraw->draw[windownumber]) { 101 char tmp_str[128]; 102 if (windownumber) { 103 ierr = PetscSNPrintf(tmp_str,sizeof(tmp_str),"%s:%d",vdraw->title?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 if (vdraw->drawtype) { 108 ierr = PetscDrawSetType(vdraw->draw[windownumber],vdraw->drawtype);CHKERRQ(ierr); 109 } 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__ "PetscViewerDrawSetDrawType" 305 PetscErrorCode PetscViewerDrawSetDrawType(PetscViewer v,PetscDrawType drawtype) 306 { 307 PetscErrorCode ierr; 308 PetscViewer_Draw *vdraw = (PetscViewer_Draw*)v->data; 309 PetscBool flg; 310 311 PetscFunctionBegin; 312 ierr = PetscObjectTypeCompare((PetscObject)v,PETSCVIEWERDRAW,&flg);CHKERRQ(ierr); 313 if (flg) { 314 ierr = PetscFree(vdraw->drawtype);CHKERRQ(ierr); 315 ierr = PetscStrallocpy(drawtype,(char**)&vdraw->drawtype);CHKERRQ(ierr); 316 } 317 PetscFunctionReturn(0); 318 } 319 320 #undef __FUNCT__ 321 #define __FUNCT__ "PetscViewerDrawOpen" 322 /*@C 323 PetscViewerDrawOpen - Opens a window for use as a PetscViewer. If you want to 324 do graphics in this window, you must call PetscViewerDrawGetDraw() and 325 perform the graphics on the PetscDraw object. 326 327 Collective on MPI_Comm 328 329 Input Parameters: 330 + comm - communicator that will share window 331 . display - the X display on which to open, or null for the local machine 332 . title - the title to put in the title bar, or null for no title 333 . x, y - the screen coordinates of the upper left corner of window, or use PETSC_DECIDE 334 - w, h - window width and height in pixels, or may use PETSC_DECIDE or PETSC_DRAW_FULL_SIZE, PETSC_DRAW_HALF_SIZE, 335 PETSC_DRAW_THIRD_SIZE, PETSC_DRAW_QUARTER_SIZE 336 337 Output Parameters: 338 . viewer - the PetscViewer 339 340 Format Options: 341 + PETSC_VIEWER_DRAW_BASIC - displays with basic format 342 - PETSC_VIEWER_DRAW_LG - displays using a line graph 343 344 Options Database Keys: 345 PetscViewerDrawOpen() calls PetscDrawCreate(), so see the manual page for 346 PetscDrawCreate() for runtime options, including 347 + -draw_type x or null 348 . -nox - Disables all x-windows output 349 . -display <name> - Specifies name of machine for the X display 350 . -geometry <x,y,w,h> - allows setting the window location and size 351 - -draw_pause <pause> - Sets time (in seconds) that the 352 program pauses after PetscDrawPause() has been called 353 (0 is default, -1 implies until user input). 354 355 Level: beginner 356 357 Note for Fortran Programmers: 358 Whenever indicating null character data in a Fortran code, 359 NULL_CHARACTER must be employed; using NULL is not 360 correct for character data! Thus, NULL_CHARACTER can be 361 used for the display and title input parameters. 362 363 Concepts: graphics^opening PetscViewer 364 Concepts: drawing^opening PetscViewer 365 366 367 .seealso: PetscDrawCreate(), PetscViewerDestroy(), PetscViewerDrawGetDraw(), PetscViewerCreate(), PETSC_VIEWER_DRAW_, 368 PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF 369 @*/ 370 PetscErrorCode PetscViewerDrawOpen(MPI_Comm comm,const char display[],const char title[],int x,int y,int w,int h,PetscViewer *viewer) 371 { 372 PetscErrorCode ierr; 373 374 PetscFunctionBegin; 375 ierr = PetscViewerCreate(comm,viewer);CHKERRQ(ierr); 376 ierr = PetscViewerSetType(*viewer,PETSCVIEWERDRAW);CHKERRQ(ierr); 377 ierr = PetscViewerDrawSetInfo(*viewer,display,title,x,y,w,h);CHKERRQ(ierr); 378 PetscFunctionReturn(0); 379 } 380 381 #undef __FUNCT__ 382 #define __FUNCT__ "PetscViewerGetSubViewer_Draw" 383 PetscErrorCode PetscViewerGetSubViewer_Draw(PetscViewer viewer,MPI_Comm comm,PetscViewer *sviewer) 384 { 385 PetscErrorCode ierr; 386 PetscMPIInt rank; 387 PetscInt i; 388 PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data,*vsdraw; 389 390 PetscFunctionBegin; 391 if (vdraw->singleton_made) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Trying to get SubViewer without first restoring previous"); 392 393 /* only processor zero can use the PetscViewer draw singleton */ 394 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr); 395 if (!rank) { 396 ierr = PetscViewerCreate(PETSC_COMM_SELF,sviewer);CHKERRQ(ierr); 397 ierr = PetscViewerSetType(*sviewer,PETSCVIEWERDRAW);CHKERRQ(ierr); 398 vsdraw = (PetscViewer_Draw*)(*sviewer)->data; 399 for (i=0; i<vdraw->draw_max; i++) { 400 if (vdraw->draw[i]) { 401 ierr = PetscDrawGetSingleton(vdraw->draw[i],&vsdraw->draw[i]);CHKERRQ(ierr); 402 } 403 } 404 } 405 vdraw->singleton_made = PETSC_TRUE; 406 PetscFunctionReturn(0); 407 } 408 409 #undef __FUNCT__ 410 #define __FUNCT__ "PetscViewerRestoreSubViewer_Draw" 411 PetscErrorCode PetscViewerRestoreSubViewer_Draw(PetscViewer viewer,MPI_Comm comm,PetscViewer *sviewer) 412 { 413 PetscErrorCode ierr; 414 PetscMPIInt rank; 415 PetscInt i; 416 PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data,*vsdraw; 417 418 PetscFunctionBegin; 419 if (!vdraw->singleton_made) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Trying to restore a singleton that was not gotten"); 420 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr); 421 if (!rank) { 422 vsdraw = (PetscViewer_Draw*)(*sviewer)->data; 423 for (i=0; i<vdraw->draw_max; i++) { 424 if (vdraw->draw[i] && vsdraw->draw[i]) { 425 ierr = PetscDrawRestoreSingleton(vdraw->draw[i],&vsdraw->draw[i]);CHKERRQ(ierr); 426 } 427 } 428 ierr = PetscFree3(vsdraw->draw,vsdraw->drawlg,vsdraw->drawaxis);CHKERRQ(ierr); 429 ierr = PetscFree((*sviewer)->data);CHKERRQ(ierr); 430 ierr = PetscHeaderDestroy(sviewer);CHKERRQ(ierr); 431 } 432 vdraw->singleton_made = PETSC_FALSE; 433 PetscFunctionReturn(0); 434 } 435 436 #undef __FUNCT__ 437 #define __FUNCT__ "PetscViewerSetFromOptions_Draw" 438 PetscErrorCode PetscViewerSetFromOptions_Draw(PetscOptionItems *PetscOptionsObject,PetscViewer v) 439 { 440 PetscErrorCode ierr; 441 PetscReal bounds[16]; 442 PetscInt nbounds = 16; 443 PetscBool flg; 444 445 PetscFunctionBegin; 446 ierr = PetscOptionsHead(PetscOptionsObject,"Draw PetscViewer Options");CHKERRQ(ierr); 447 ierr = PetscOptionsRealArray("-draw_bounds","Bounds to put on plots axis","PetscViewerDrawSetBounds",bounds,&nbounds,&flg);CHKERRQ(ierr); 448 if (flg) { 449 ierr = PetscViewerDrawSetBounds(v,nbounds/2,bounds);CHKERRQ(ierr); 450 } 451 452 ierr = PetscOptionsTail();CHKERRQ(ierr); 453 PetscFunctionReturn(0); 454 } 455 456 #undef __FUNCT__ 457 #define __FUNCT__ "PetscViewerView_Draw" 458 PetscErrorCode PetscViewerView_Draw(PetscViewer viewer,PetscViewer v) 459 { 460 PetscErrorCode ierr; 461 PetscDraw draw; 462 PetscInt i; 463 PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data; 464 465 PetscFunctionBegin; 466 /* If the PetscViewer has just been created then no vdraw->draw yet 467 exists so this will not actually call the viewer on any draws. */ 468 for (i=0; i<vdraw->draw_base; i++) { 469 if (vdraw->draw[i]) { 470 ierr = PetscViewerDrawGetDraw(viewer,i,&draw);CHKERRQ(ierr); 471 ierr = PetscDrawView(draw,v);CHKERRQ(ierr); 472 } 473 } 474 PetscFunctionReturn(0); 475 } 476 477 #undef __FUNCT__ 478 #define __FUNCT__ "PetscViewerCreate_Draw" 479 PETSC_EXTERN PetscErrorCode PetscViewerCreate_Draw(PetscViewer viewer) 480 { 481 PetscErrorCode ierr; 482 PetscViewer_Draw *vdraw; 483 484 PetscFunctionBegin; 485 ierr = PetscNewLog(viewer,&vdraw);CHKERRQ(ierr); 486 viewer->data = (void*)vdraw; 487 488 viewer->ops->flush = PetscViewerFlush_Draw; 489 viewer->ops->view = PetscViewerView_Draw; 490 viewer->ops->destroy = PetscViewerDestroy_Draw; 491 viewer->ops->setfromoptions = PetscViewerSetFromOptions_Draw; 492 viewer->ops->getsubviewer = PetscViewerGetSubViewer_Draw; 493 viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_Draw; 494 495 /* these are created on the fly if requested */ 496 vdraw->draw_max = 5; 497 vdraw->draw_base = 0; 498 vdraw->w = PETSC_DECIDE; 499 vdraw->h = PETSC_DECIDE; 500 501 ierr = PetscCalloc3(vdraw->draw_max,&vdraw->draw,vdraw->draw_max,&vdraw->drawlg,vdraw->draw_max,&vdraw->drawaxis);CHKERRQ(ierr); 502 vdraw->singleton_made = PETSC_FALSE; 503 PetscFunctionReturn(0); 504 } 505 506 #undef __FUNCT__ 507 #define __FUNCT__ "PetscViewerDrawClear" 508 /*@ 509 PetscViewerDrawClear - Clears a PetscDraw graphic associated with a PetscViewer. 510 511 Not Collective 512 513 Input Parameter: 514 . viewer - the PetscViewer 515 516 Level: intermediate 517 518 .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), 519 520 @*/ 521 PetscErrorCode PetscViewerDrawClear(PetscViewer viewer) 522 { 523 PetscErrorCode ierr; 524 PetscInt i; 525 PetscBool isdraw; 526 PetscViewer_Draw *vdraw; 527 528 PetscFunctionBegin; 529 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 530 if (isdraw) { 531 vdraw = (PetscViewer_Draw*)viewer->data; 532 for (i=0; i<vdraw->draw_max; i++) { 533 if (vdraw->draw[i]) {ierr = PetscDrawClear(vdraw->draw[i]);CHKERRQ(ierr);} 534 } 535 } 536 PetscFunctionReturn(0); 537 } 538 539 #undef __FUNCT__ 540 #define __FUNCT__ "PetscViewerDrawGetPause" 541 /*@ 542 PetscViewerDrawGetPause - Gets a pause for the first present draw 543 544 Not Collective 545 546 Input Parameter: 547 . viewer - the PetscViewer 548 549 Output Parameter: 550 . pause - the pause value 551 552 Level: intermediate 553 554 .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), 555 556 @*/ 557 PetscErrorCode PetscViewerDrawGetPause(PetscViewer viewer,PetscReal *pause) 558 { 559 PetscErrorCode ierr; 560 PetscInt i; 561 PetscBool isdraw; 562 PetscViewer_Draw *vdraw; 563 PetscDraw draw; 564 565 PetscFunctionBegin; 566 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 567 *pause = 0.0; 568 if (isdraw) { 569 vdraw = (PetscViewer_Draw*)viewer->data; 570 for (i=0; i<vdraw->draw_max; i++) { 571 if (vdraw->draw[i]) { 572 ierr = PetscDrawGetPause(vdraw->draw[i],pause);CHKERRQ(ierr); 573 PetscFunctionReturn(0); 574 } 575 } 576 /* none exist yet so create one and get its pause */ 577 ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 578 ierr = PetscDrawGetPause(vdraw->draw[0],pause);CHKERRQ(ierr); 579 } 580 PetscFunctionReturn(0); 581 } 582 583 #undef __FUNCT__ 584 #define __FUNCT__ "PetscViewerDrawSetPause" 585 /*@ 586 PetscViewerDrawSetPause - Sets a pause for each PetscDraw in the viewer 587 588 Not Collective 589 590 Input Parameters: 591 + viewer - the PetscViewer 592 - pause - the pause value 593 594 Level: intermediate 595 596 .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), 597 598 @*/ 599 PetscErrorCode PetscViewerDrawSetPause(PetscViewer viewer,PetscReal pause) 600 { 601 PetscErrorCode ierr; 602 PetscInt i; 603 PetscBool isdraw; 604 605 PetscFunctionBegin; 606 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 607 if (isdraw) { 608 PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data; 609 610 vdraw->pause = pause; 611 for (i=0; i<vdraw->draw_max; i++) { 612 if (vdraw->draw[i]) {ierr = PetscDrawSetPause(vdraw->draw[i],pause);CHKERRQ(ierr);} 613 } 614 } 615 PetscFunctionReturn(0); 616 } 617 618 619 #undef __FUNCT__ 620 #define __FUNCT__ "PetscViewerDrawSetHold" 621 /*@ 622 PetscViewerDrawSetHold - Holds previous image when drawing new image 623 624 Not Collective 625 626 Input Parameters: 627 + viewer - the PetscViewer 628 - hold - indicates to hold or not 629 630 Level: intermediate 631 632 .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), 633 634 @*/ 635 PetscErrorCode PetscViewerDrawSetHold(PetscViewer viewer,PetscBool hold) 636 { 637 PetscErrorCode ierr; 638 PetscViewer_Draw *vdraw; 639 PetscBool isdraw; 640 641 PetscFunctionBegin; 642 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 643 if (isdraw) { 644 vdraw = (PetscViewer_Draw*)viewer->data; 645 vdraw->hold = hold; 646 } 647 PetscFunctionReturn(0); 648 } 649 650 #undef __FUNCT__ 651 #define __FUNCT__ "PetscViewerDrawGetHold" 652 /*@ 653 PetscViewerDrawGetHold - Checks if holds previous image when drawing new image 654 655 Not Collective 656 657 Input Parameter: 658 . viewer - the PetscViewer 659 660 Output Parameter: 661 . hold - indicates to hold or not 662 663 Level: intermediate 664 665 .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), 666 667 @*/ 668 PetscErrorCode PetscViewerDrawGetHold(PetscViewer viewer,PetscBool *hold) 669 { 670 PetscErrorCode ierr; 671 PetscViewer_Draw *vdraw; 672 PetscBool isdraw; 673 674 PetscFunctionBegin; 675 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 676 if (isdraw) { 677 vdraw = (PetscViewer_Draw*)viewer->data; 678 *hold = vdraw->hold; 679 } 680 PetscFunctionReturn(0); 681 } 682 683 /* ---------------------------------------------------------------------*/ 684 /* 685 The variable Petsc_Viewer_Draw_keyval is used to indicate an MPI attribute that 686 is attached to a communicator, in this case the attribute is a PetscViewer. 687 */ 688 static PetscMPIInt Petsc_Viewer_Draw_keyval = MPI_KEYVAL_INVALID; 689 690 #undef __FUNCT__ 691 #define __FUNCT__ "PETSC_VIEWER_DRAW_" 692 /*@C 693 PETSC_VIEWER_DRAW_ - Creates a window PetscViewer shared by all processors 694 in a communicator. 695 696 Collective on MPI_Comm 697 698 Input Parameter: 699 . comm - the MPI communicator to share the window PetscViewer 700 701 Level: intermediate 702 703 Notes: 704 Unlike almost all other PETSc routines, PETSC_VIEWER_DRAW_ does not return 705 an error code. The window is usually used in the form 706 $ XXXView(XXX object,PETSC_VIEWER_DRAW_(comm)); 707 708 .seealso: PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF, PetscViewerDrawOpen(), 709 @*/ 710 PetscViewer PETSC_VIEWER_DRAW_(MPI_Comm comm) 711 { 712 PetscErrorCode ierr; 713 PetscMPIInt flag; 714 PetscViewer viewer; 715 MPI_Comm ncomm; 716 717 PetscFunctionBegin; 718 ierr = PetscCommDuplicate(comm,&ncomm,NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 719 if (Petsc_Viewer_Draw_keyval == MPI_KEYVAL_INVALID) { 720 ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Draw_keyval,0); 721 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 722 } 723 ierr = MPI_Attr_get(ncomm,Petsc_Viewer_Draw_keyval,(void**)&viewer,&flag); 724 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 725 if (!flag) { /* PetscViewer not yet created */ 726 ierr = PetscViewerDrawOpen(ncomm,0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,&viewer); 727 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 728 ierr = PetscObjectRegisterDestroy((PetscObject)viewer); 729 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 730 ierr = MPI_Attr_put(ncomm,Petsc_Viewer_Draw_keyval,(void*)viewer); 731 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 732 } 733 ierr = PetscCommDestroy(&ncomm); 734 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 735 PetscFunctionReturn(viewer); 736 } 737 738 #undef __FUNCT__ 739 #define __FUNCT__ "PetscViewerDrawSetBounds" 740 /*@ 741 PetscViewerDrawSetBounds - sets the upper and lower bounds to be used in plotting 742 743 Collective on PetscViewer 744 745 Input Parameters: 746 + viewer - the PetscViewer (created with PetscViewerDrawOpen()) 747 . nbounds - number of plots that can be made with this viewer, for example the dof passed to DMDACreate() 748 - 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, ..... 749 750 751 Options Database: 752 . -draw_bounds minF0,maxF0,minF1,maxF1 753 754 Level: intermediate 755 756 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 757 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 758 this viewer. Otherwise the color to physical value meaning changes with each new image if this is not set. 759 760 Concepts: drawing^accessing PetscDraw context from PetscViewer 761 Concepts: graphics 762 763 .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen() 764 @*/ 765 PetscErrorCode PetscViewerDrawSetBounds(PetscViewer viewer,PetscInt nbounds,const PetscReal *bounds) 766 { 767 PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data; 768 PetscErrorCode ierr; 769 770 771 PetscFunctionBegin; 772 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 773 vdraw->nbounds = nbounds; 774 775 ierr = PetscMalloc1(2*nbounds,&vdraw->bounds);CHKERRQ(ierr); 776 ierr = PetscMemcpy(vdraw->bounds,bounds,2*nbounds*sizeof(PetscReal));CHKERRQ(ierr); 777 PetscFunctionReturn(0); 778 } 779 780 #undef __FUNCT__ 781 #define __FUNCT__ "PetscViewerDrawGetBounds" 782 /*@C 783 PetscViewerDrawGetBounds - gets the upper and lower bounds to be used in plotting set with PetscViewerDrawSetBounds() 784 785 Collective on PetscViewer 786 787 Input Parameter: 788 . viewer - the PetscViewer (created with PetscViewerDrawOpen()) 789 790 Output Paramters: 791 + nbounds - number of plots that can be made with this viewer, for example the dof passed to DMDACreate() 792 - 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, ..... 793 794 Level: intermediate 795 796 Concepts: drawing^accessing PetscDraw context from PetscViewer 797 Concepts: graphics 798 799 .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen(), PetscViewerDrawSetBounds() 800 @*/ 801 PetscErrorCode PetscViewerDrawGetBounds(PetscViewer viewer,PetscInt *nbounds,const PetscReal **bounds) 802 { 803 PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data; 804 805 PetscFunctionBegin; 806 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 807 *nbounds = vdraw->nbounds; 808 *bounds = vdraw->bounds; 809 PetscFunctionReturn(0); 810 } 811