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(viewer,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(viewer,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 EXTERN_C_BEGIN 440 #undef __FUNCT__ 441 #define __FUNCT__ "PetscViewerCreate_Draw" 442 PetscErrorCode PetscViewerCreate_Draw(PetscViewer viewer) 443 { 444 PetscInt i; 445 PetscErrorCode ierr; 446 PetscViewer_Draw *vdraw; 447 448 PetscFunctionBegin; 449 ierr = PetscNewLog(viewer,PetscViewer_Draw,&vdraw);CHKERRQ(ierr); 450 viewer->data = (void*)vdraw; 451 452 viewer->ops->flush = PetscViewerFlush_Draw; 453 viewer->ops->destroy = PetscViewerDestroy_Draw; 454 viewer->ops->setfromoptions = PetscViewerSetFromOptions_Draw; 455 viewer->ops->getsingleton = PetscViewerGetSingleton_Draw; 456 viewer->ops->restoresingleton = PetscViewerRestoreSingleton_Draw; 457 viewer->format = PETSC_VIEWER_NOFORMAT; 458 459 /* these are created on the fly if requested */ 460 vdraw->draw_max = 5; 461 vdraw->draw_base = 0; 462 vdraw->w = PETSC_DECIDE; 463 vdraw->h = PETSC_DECIDE; 464 465 ierr = PetscMalloc3(vdraw->draw_max,PetscDraw,&vdraw->draw,vdraw->draw_max,PetscDrawLG,&vdraw->drawlg,vdraw->draw_max,PetscDrawAxis,&vdraw->drawaxis);CHKERRQ(ierr); 466 ierr = PetscMemzero(vdraw->draw,vdraw->draw_max*sizeof(PetscDraw));CHKERRQ(ierr); 467 ierr = PetscMemzero(vdraw->drawlg,vdraw->draw_max*sizeof(PetscDrawLG));CHKERRQ(ierr); 468 ierr = PetscMemzero(vdraw->drawaxis,vdraw->draw_max*sizeof(PetscDrawAxis));CHKERRQ(ierr); 469 for (i=0; i<vdraw->draw_max; i++) { 470 vdraw->draw[i] = 0; 471 vdraw->drawlg[i] = 0; 472 vdraw->drawaxis[i] = 0; 473 } 474 vdraw->singleton_made = PETSC_FALSE; 475 PetscFunctionReturn(0); 476 } 477 EXTERN_C_END 478 479 #undef __FUNCT__ 480 #define __FUNCT__ "PetscViewerDrawClear" 481 /*@ 482 PetscViewerDrawClear - Clears a PetscDraw graphic associated with a PetscViewer. 483 484 Not Collective 485 486 Input Parameter: 487 . viewer - the PetscViewer 488 489 Level: intermediate 490 491 .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), 492 493 @*/ 494 PetscErrorCode PetscViewerDrawClear(PetscViewer viewer) 495 { 496 PetscErrorCode ierr; 497 PetscInt i; 498 PetscBool isdraw; 499 PetscViewer_Draw *vdraw; 500 501 PetscFunctionBegin; 502 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 503 if (isdraw) { 504 vdraw = (PetscViewer_Draw*)viewer->data; 505 for (i=0; i<vdraw->draw_max; i++) { 506 if (vdraw->draw[i]) {ierr = PetscDrawClear(vdraw->draw[i]);CHKERRQ(ierr);} 507 } 508 } 509 PetscFunctionReturn(0); 510 } 511 512 #undef __FUNCT__ 513 #define __FUNCT__ "PetscViewerDrawGetPause" 514 /*@ 515 PetscViewerDrawGetPause - Gets a pause for the first present draw 516 517 Not Collective 518 519 Input Parameter: 520 . viewer - the PetscViewer 521 522 Output Parameter: 523 . pause - the pause value 524 525 Level: intermediate 526 527 .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), 528 529 @*/ 530 PetscErrorCode PetscViewerDrawGetPause(PetscViewer viewer,PetscReal *pause) 531 { 532 PetscErrorCode ierr; 533 PetscInt i; 534 PetscBool isdraw; 535 PetscViewer_Draw *vdraw; 536 PetscDraw draw; 537 538 PetscFunctionBegin; 539 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 540 *pause = 0.0; 541 if (isdraw) { 542 vdraw = (PetscViewer_Draw*)viewer->data; 543 for (i=0; i<vdraw->draw_max; i++) { 544 if (vdraw->draw[i]) { 545 ierr = PetscDrawGetPause(vdraw->draw[i],pause);CHKERRQ(ierr); 546 PetscFunctionReturn(0); 547 } 548 } 549 /* none exist yet so create one and get its pause */ 550 ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 551 ierr = PetscDrawGetPause(vdraw->draw[0],pause);CHKERRQ(ierr); 552 } 553 PetscFunctionReturn(0); 554 } 555 556 #undef __FUNCT__ 557 #define __FUNCT__ "PetscViewerDrawSetPause" 558 /*@ 559 PetscViewerDrawSetPause - Sets a pause for each PetscDraw in the viewer 560 561 Not Collective 562 563 Input Parameters: 564 + viewer - the PetscViewer 565 - pause - the pause value 566 567 Level: intermediate 568 569 .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), 570 571 @*/ 572 PetscErrorCode PetscViewerDrawSetPause(PetscViewer viewer,PetscReal pause) 573 { 574 PetscErrorCode ierr; 575 PetscInt i; 576 PetscBool isdraw; 577 578 PetscFunctionBegin; 579 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 580 if (isdraw) { 581 PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data; 582 583 vdraw->pause = pause; 584 for (i=0; i<vdraw->draw_max; i++) { 585 if (vdraw->draw[i]) {ierr = PetscDrawSetPause(vdraw->draw[i],pause);CHKERRQ(ierr);} 586 } 587 } 588 PetscFunctionReturn(0); 589 } 590 591 592 #undef __FUNCT__ 593 #define __FUNCT__ "PetscViewerDrawSetHold" 594 /*@ 595 PetscViewerDrawSetHold - Holds previous image when drawing new image 596 597 Not Collective 598 599 Input Parameters: 600 + viewer - the PetscViewer 601 - hold - indicates to hold or not 602 603 Level: intermediate 604 605 .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), 606 607 @*/ 608 PetscErrorCode PetscViewerDrawSetHold(PetscViewer viewer,PetscBool hold) 609 { 610 PetscErrorCode ierr; 611 PetscViewer_Draw *vdraw; 612 PetscBool isdraw; 613 614 PetscFunctionBegin; 615 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 616 if (isdraw) { 617 vdraw = (PetscViewer_Draw*)viewer->data; 618 vdraw->hold = hold; 619 } 620 PetscFunctionReturn(0); 621 } 622 623 #undef __FUNCT__ 624 #define __FUNCT__ "PetscViewerDrawGetHold" 625 /*@ 626 PetscViewerDrawGetHold - Holds previous image when drawing new image 627 628 Not Collective 629 630 Input Parameter: 631 . viewer - the PetscViewer 632 633 Output Parameter: 634 . hold - indicates to hold or not 635 636 Level: intermediate 637 638 .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), 639 640 @*/ 641 PetscErrorCode PetscViewerDrawGetHold(PetscViewer viewer,PetscBool *hold) 642 { 643 PetscErrorCode ierr; 644 PetscViewer_Draw *vdraw; 645 PetscBool isdraw; 646 647 PetscFunctionBegin; 648 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 649 if (isdraw) { 650 vdraw = (PetscViewer_Draw*)viewer->data; 651 *hold = vdraw->hold; 652 } 653 PetscFunctionReturn(0); 654 } 655 656 /* ---------------------------------------------------------------------*/ 657 /* 658 The variable Petsc_Viewer_Draw_keyval is used to indicate an MPI attribute that 659 is attached to a communicator, in this case the attribute is a PetscViewer. 660 */ 661 static PetscMPIInt Petsc_Viewer_Draw_keyval = MPI_KEYVAL_INVALID; 662 663 #undef __FUNCT__ 664 #define __FUNCT__ "PETSC_VIEWER_DRAW_" 665 /*@C 666 PETSC_VIEWER_DRAW_ - Creates a window PetscViewer shared by all processors 667 in a communicator. 668 669 Collective on MPI_Comm 670 671 Input Parameter: 672 . comm - the MPI communicator to share the window PetscViewer 673 674 Level: intermediate 675 676 Notes: 677 Unlike almost all other PETSc routines, PETSC_VIEWER_DRAW_ does not return 678 an error code. The window is usually used in the form 679 $ XXXView(XXX object,PETSC_VIEWER_DRAW_(comm)); 680 681 .seealso: PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF, PetscViewerDrawOpen(), 682 @*/ 683 PetscViewer PETSC_VIEWER_DRAW_(MPI_Comm comm) 684 { 685 PetscErrorCode ierr; 686 PetscMPIInt flag; 687 PetscViewer viewer; 688 MPI_Comm ncomm; 689 690 PetscFunctionBegin; 691 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);} 692 if (Petsc_Viewer_Draw_keyval == MPI_KEYVAL_INVALID) { 693 ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Draw_keyval,0); 694 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 695 } 696 ierr = MPI_Attr_get(ncomm,Petsc_Viewer_Draw_keyval,(void**)&viewer,&flag); 697 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 698 if (!flag) { /* PetscViewer not yet created */ 699 ierr = PetscViewerDrawOpen(ncomm,0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,&viewer); 700 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 701 ierr = PetscObjectRegisterDestroy((PetscObject)viewer); 702 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 703 ierr = MPI_Attr_put(ncomm,Petsc_Viewer_Draw_keyval,(void*)viewer); 704 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 705 } 706 ierr = PetscCommDestroy(&ncomm); 707 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 708 PetscFunctionReturn(viewer); 709 } 710 711 #undef __FUNCT__ 712 #define __FUNCT__ "PetscViewerDrawSetBounds" 713 /*@ 714 PetscViewerDrawSetBounds - sets the upper and lower bounds to be used in plotting 715 716 Collective on PetscViewer 717 718 Input Parameters: 719 + viewer - the PetscViewer (created with PetscViewerDrawOpen()) 720 . nbounds - number of plots that can be made with this viewer, for example the dof passed to DMDACreate() 721 - 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, ..... 722 723 724 Options Database: 725 . -draw_bounds minF0,maxF0,minF1,maxF1 726 727 Level: intermediate 728 729 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 730 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 731 this viewer. Otherwise the color to physical value meaning changes with each new image if this is not set. 732 733 Concepts: drawing^accessing PetscDraw context from PetscViewer 734 Concepts: graphics 735 736 .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen() 737 @*/ 738 PetscErrorCode PetscViewerDrawSetBounds(PetscViewer viewer,PetscInt nbounds,const PetscReal *bounds) 739 { 740 PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data; 741 PetscErrorCode ierr; 742 743 744 PetscFunctionBegin; 745 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 746 vdraw->nbounds = nbounds; 747 748 ierr = PetscMalloc(2*nbounds*sizeof(PetscReal),&vdraw->bounds);CHKERRQ(ierr); 749 ierr = PetscMemcpy(vdraw->bounds,bounds,2*nbounds*sizeof(PetscReal));CHKERRQ(ierr); 750 PetscFunctionReturn(0); 751 } 752 753 #undef __FUNCT__ 754 #define __FUNCT__ "PetscViewerDrawGetBounds" 755 /*@C 756 PetscViewerDrawGetBounds - gets the upper and lower bounds to be used in plotting set with PetscViewerDrawSetBounds() 757 758 Collective on PetscViewer 759 760 Input Parameter: 761 . viewer - the PetscViewer (created with PetscViewerDrawOpen()) 762 763 Output Paramters: 764 + nbounds - number of plots that can be made with this viewer, for example the dof passed to DMDACreate() 765 - 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, ..... 766 767 Level: intermediate 768 769 Concepts: drawing^accessing PetscDraw context from PetscViewer 770 Concepts: graphics 771 772 .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen(), PetscViewerDrawSetBounds() 773 @*/ 774 PetscErrorCode PetscViewerDrawGetBounds(PetscViewer viewer,PetscInt *nbounds,const PetscReal **bounds) 775 { 776 PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data; 777 778 PetscFunctionBegin; 779 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 780 *nbounds = vdraw->nbounds; 781 *bounds = vdraw->bounds; 782 PetscFunctionReturn(0); 783 } 784