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