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