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