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