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