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