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