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