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