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