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 ierr = PetscDrawLGSetFromOptions(vdraw->drawlg[windownumber+vdraw->draw_base]);CHKERRQ(ierr); 236 } 237 *drawlg = vdraw->drawlg[windownumber+vdraw->draw_base]; 238 PetscFunctionReturn(0); 239 } 240 241 #undef __FUNCT__ 242 #define __FUNCT__ "PetscViewerDrawGetDrawAxis" 243 /*@C 244 PetscViewerDrawGetDrawAxis - Returns PetscDrawAxis object from PetscViewer object. 245 This PetscDrawAxis object may then be used to perform graphics using 246 PetscDrawAxisXXX() commands. 247 248 Not Collective (but PetscDrawAxis object will be parallel if PetscViewer is) 249 250 Input Parameter: 251 + viewer - the PetscViewer (created with PetscViewerDrawOpen() 252 - windownumber - indicates which subwindow (usually 0) 253 254 Ouput Parameter: 255 . drawaxis - the draw axis object 256 257 Level: advanced 258 259 Concepts: line graph^accessing context 260 261 .seealso: PetscViewerDrawGetDraw(), PetscViewerDrawGetLG(), PetscViewerDrawOpen() 262 @*/ 263 PetscErrorCode PetscViewerDrawGetDrawAxis(PetscViewer viewer,PetscInt windownumber,PetscDrawAxis *drawaxis) 264 { 265 PetscErrorCode ierr; 266 PetscBool isdraw; 267 PetscViewer_Draw *vdraw; 268 269 PetscFunctionBegin; 270 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 271 PetscValidLogicalCollectiveInt(viewer,windownumber,2); 272 PetscValidPointer(drawaxis,3); 273 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 274 if (!isdraw) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer"); 275 if (windownumber < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Window number cannot be negative"); 276 vdraw = (PetscViewer_Draw*)viewer->data; 277 278 if (windownumber+vdraw->draw_base >= vdraw->draw_max || !vdraw->draw[windownumber+vdraw->draw_base]) { 279 ierr = PetscViewerDrawGetDraw(viewer,windownumber,NULL);CHKERRQ(ierr); 280 } 281 if (!vdraw->drawaxis[windownumber+vdraw->draw_base]) { 282 ierr = PetscDrawAxisCreate(vdraw->draw[windownumber+vdraw->draw_base],&vdraw->drawaxis[windownumber+vdraw->draw_base]);CHKERRQ(ierr); 283 ierr = PetscLogObjectParent((PetscObject)viewer,(PetscObject)vdraw->drawaxis[windownumber+vdraw->draw_base]);CHKERRQ(ierr); 284 } 285 *drawaxis = vdraw->drawaxis[windownumber+vdraw->draw_base]; 286 PetscFunctionReturn(0); 287 } 288 289 #undef __FUNCT__ 290 #define __FUNCT__ "PetscViewerDrawResize" 291 PetscErrorCode PetscViewerDrawResize(PetscViewer v,int w,int h) 292 { 293 PetscErrorCode ierr; 294 PetscViewer_Draw *vdraw; 295 PetscBool isdraw; 296 297 PetscFunctionBegin; 298 PetscValidHeaderSpecific(v,PETSC_VIEWER_CLASSID,1); 299 ierr = PetscObjectTypeCompare((PetscObject)v,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 300 if (!isdraw) PetscFunctionReturn(0); 301 vdraw = (PetscViewer_Draw*)v->data; 302 303 if (w >= 1) vdraw->w = w; 304 if (h >= 1) vdraw->h = h; 305 PetscFunctionReturn(0); 306 } 307 308 #undef __FUNCT__ 309 #define __FUNCT__ "PetscViewerDrawSetInfo" 310 PetscErrorCode PetscViewerDrawSetInfo(PetscViewer v,const char display[],const char title[],int x,int y,int w,int h) 311 { 312 PetscErrorCode ierr; 313 PetscViewer_Draw *vdraw; 314 PetscBool isdraw; 315 316 PetscFunctionBegin; 317 PetscValidHeaderSpecific(v,PETSC_VIEWER_CLASSID,1); 318 ierr = PetscObjectTypeCompare((PetscObject)v,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 319 if (!isdraw) PetscFunctionReturn(0); 320 vdraw = (PetscViewer_Draw*)v->data; 321 322 ierr = PetscStrallocpy(display,&vdraw->display);CHKERRQ(ierr); 323 ierr = PetscStrallocpy(title,&vdraw->title);CHKERRQ(ierr); 324 if (w >= 1) vdraw->w = w; 325 if (h >= 1) vdraw->h = h; 326 PetscFunctionReturn(0); 327 } 328 329 #undef __FUNCT__ 330 #define __FUNCT__ "PetscViewerDrawSetDrawType" 331 PetscErrorCode PetscViewerDrawSetDrawType(PetscViewer v,PetscDrawType drawtype) 332 { 333 PetscErrorCode ierr; 334 PetscViewer_Draw *vdraw; 335 PetscBool isdraw; 336 337 PetscFunctionBegin; 338 PetscValidHeaderSpecific(v,PETSC_VIEWER_CLASSID,1); 339 ierr = PetscObjectTypeCompare((PetscObject)v,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 340 if (!isdraw) PetscFunctionReturn(0); 341 vdraw = (PetscViewer_Draw*)v->data; 342 343 ierr = PetscFree(vdraw->drawtype);CHKERRQ(ierr); 344 ierr = PetscStrallocpy(drawtype,(char**)&vdraw->drawtype);CHKERRQ(ierr); 345 PetscFunctionReturn(0); 346 } 347 348 #undef __FUNCT__ 349 #define __FUNCT__ "PetscViewerDrawOpen" 350 /*@C 351 PetscViewerDrawOpen - Opens a window for use as a PetscViewer. If you want to 352 do graphics in this window, you must call PetscViewerDrawGetDraw() and 353 perform the graphics on the PetscDraw object. 354 355 Collective on MPI_Comm 356 357 Input Parameters: 358 + comm - communicator that will share window 359 . display - the X display on which to open, or null for the local machine 360 . title - the title to put in the title bar, or null for no title 361 . x, y - the screen coordinates of the upper left corner of window, or use PETSC_DECIDE 362 - w, h - window width and height in pixels, or may use PETSC_DECIDE or PETSC_DRAW_FULL_SIZE, PETSC_DRAW_HALF_SIZE, 363 PETSC_DRAW_THIRD_SIZE, PETSC_DRAW_QUARTER_SIZE 364 365 Output Parameters: 366 . viewer - the PetscViewer 367 368 Format Options: 369 + PETSC_VIEWER_DRAW_BASIC - displays with basic format 370 - PETSC_VIEWER_DRAW_LG - displays using a line graph 371 372 Options Database Keys: 373 PetscViewerDrawOpen() calls PetscDrawCreate(), so see the manual page for 374 PetscDrawCreate() for runtime options, including 375 + -draw_type x or null 376 . -nox - Disables all x-windows output 377 . -display <name> - Specifies name of machine for the X display 378 . -geometry <x,y,w,h> - allows setting the window location and size 379 - -draw_pause <pause> - Sets time (in seconds) that the 380 program pauses after PetscDrawPause() has been called 381 (0 is default, -1 implies until user input). 382 383 Level: beginner 384 385 Note for Fortran Programmers: 386 Whenever indicating null character data in a Fortran code, 387 NULL_CHARACTER must be employed; using NULL is not 388 correct for character data! Thus, NULL_CHARACTER can be 389 used for the display and title input parameters. 390 391 Concepts: graphics^opening PetscViewer 392 Concepts: drawing^opening PetscViewer 393 394 395 .seealso: PetscDrawCreate(), PetscViewerDestroy(), PetscViewerDrawGetDraw(), PetscViewerCreate(), PETSC_VIEWER_DRAW_, 396 PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF 397 @*/ 398 PetscErrorCode PetscViewerDrawOpen(MPI_Comm comm,const char display[],const char title[],int x,int y,int w,int h,PetscViewer *viewer) 399 { 400 PetscErrorCode ierr; 401 402 PetscFunctionBegin; 403 ierr = PetscViewerCreate(comm,viewer);CHKERRQ(ierr); 404 ierr = PetscViewerSetType(*viewer,PETSCVIEWERDRAW);CHKERRQ(ierr); 405 ierr = PetscViewerDrawSetInfo(*viewer,display,title,x,y,w,h);CHKERRQ(ierr); 406 PetscFunctionReturn(0); 407 } 408 409 #undef __FUNCT__ 410 #define __FUNCT__ "PetscViewerGetSubViewer_Draw" 411 PetscErrorCode PetscViewerGetSubViewer_Draw(PetscViewer viewer,MPI_Comm comm,PetscViewer *sviewer) 412 { 413 PetscErrorCode ierr; 414 PetscMPIInt rank; 415 PetscInt i; 416 PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data,*svdraw; 417 418 PetscFunctionBegin; 419 if (vdraw->singleton_made) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Trying to get SubViewer without first restoring previous"); 420 /* only processor zero can use the PetscViewer draw singleton */ 421 if (*sviewer) *sviewer = NULL; 422 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr); 423 if (!rank) { 424 ierr = PetscViewerCreate(PETSC_COMM_SELF,sviewer);CHKERRQ(ierr); 425 ierr = PetscViewerSetType(*sviewer,PETSCVIEWERDRAW);CHKERRQ(ierr); 426 svdraw = (PetscViewer_Draw*)(*sviewer)->data; 427 (*sviewer)->format = viewer->format; 428 for (i=0; i<vdraw->draw_max; i++) { /* XXX this is wrong if svdraw->draw_max (initially 5) < vdraw->draw_max */ 429 if (vdraw->draw[i]) {ierr = PetscDrawGetSingleton(vdraw->draw[i],&svdraw->draw[i]);CHKERRQ(ierr);} 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,*svdraw; 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 svdraw = (PetscViewer_Draw*)(*sviewer)->data; 450 for (i=0; i<vdraw->draw_max; i++) { 451 if (vdraw->draw[i] && svdraw->draw[i]) { 452 ierr = PetscDrawRestoreSingleton(vdraw->draw[i],&svdraw->draw[i]);CHKERRQ(ierr); 453 } 454 } 455 ierr = PetscFree3(svdraw->draw,svdraw->drawlg,svdraw->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