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 + -draw_type - use x or null 390 . -nox - Disables all x-windows output 391 . -display <name> - Specifies name of machine for the X display 392 . -geometry <x,y,w,h> - allows setting the window location and size 393 - -draw_pause <pause> - Sets time (in seconds) that the 394 program pauses after PetscDrawPause() has been called 395 (0 is default, -1 implies until user input). 396 397 Level: beginner 398 399 Notes: 400 PetscViewerDrawOpen() calls PetscDrawCreate(), so see the manual pages for PetscDrawCreate() 401 402 Note for Fortran Programmers: 403 Whenever indicating null character data in a Fortran code, 404 PETSC_NULL_CHARACTER must be employed; using NULL is not 405 correct for character data! Thus, PETSC_NULL_CHARACTER can be 406 used for the display and title input parameters. 407 408 409 410 .seealso: PetscDrawCreate(), PetscViewerDestroy(), PetscViewerDrawGetDraw(), PetscViewerCreate(), PETSC_VIEWER_DRAW_, 411 PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF 412 @*/ 413 PetscErrorCode PetscViewerDrawOpen(MPI_Comm comm,const char display[],const char title[],int x,int y,int w,int h,PetscViewer *viewer) 414 { 415 PetscErrorCode ierr; 416 417 PetscFunctionBegin; 418 ierr = PetscViewerCreate(comm,viewer);CHKERRQ(ierr); 419 ierr = PetscViewerSetType(*viewer,PETSCVIEWERDRAW);CHKERRQ(ierr); 420 ierr = PetscViewerDrawSetInfo(*viewer,display,title,x,y,w,h);CHKERRQ(ierr); 421 PetscFunctionReturn(0); 422 } 423 424 #include <petsc/private/drawimpl.h> 425 426 PetscErrorCode PetscViewerGetSubViewer_Draw(PetscViewer viewer,MPI_Comm comm,PetscViewer *sviewer) 427 { 428 PetscErrorCode ierr; 429 PetscMPIInt rank; 430 PetscInt i; 431 PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data,*svdraw; 432 433 PetscFunctionBegin; 434 if (vdraw->singleton_made) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Trying to get SubViewer without first restoring previous"); 435 /* only processor zero can use the PetscViewer draw singleton */ 436 if (sviewer) *sviewer = NULL; 437 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRMPI(ierr); 438 if (!rank) { 439 PetscMPIInt flg; 440 PetscDraw draw,sdraw; 441 442 ierr = MPI_Comm_compare(PETSC_COMM_SELF,comm,&flg);CHKERRMPI(ierr); 443 if (flg != MPI_IDENT && flg != MPI_CONGRUENT) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"PetscViewerGetSubViewer() for PETSCVIEWERDRAW requires a singleton MPI_Comm"); 444 ierr = PetscViewerCreate(comm,sviewer);CHKERRQ(ierr); 445 ierr = PetscViewerSetType(*sviewer,PETSCVIEWERDRAW);CHKERRQ(ierr); 446 svdraw = (PetscViewer_Draw*)(*sviewer)->data; 447 (*sviewer)->format = viewer->format; 448 for (i=0; i<vdraw->draw_max; i++) { /* XXX this is wrong if svdraw->draw_max (initially 5) < vdraw->draw_max */ 449 if (vdraw->draw[i]) {ierr = PetscDrawGetSingleton(vdraw->draw[i],&svdraw->draw[i]);CHKERRQ(ierr);} 450 } 451 ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 452 ierr = PetscViewerDrawGetDraw(*sviewer,0,&sdraw);CHKERRQ(ierr); 453 if (draw->savefilename) { 454 ierr = PetscDrawSetSave(sdraw,draw->savefilename);CHKERRQ(ierr); 455 sdraw->savefilecount = draw->savefilecount; 456 sdraw->savesinglefile = draw->savesinglefile; 457 sdraw->savemoviefps = draw->savemoviefps; 458 sdraw->saveonclear = draw->saveonclear; 459 sdraw->saveonflush = draw->saveonflush; 460 } 461 if (draw->savefinalfilename) {ierr = PetscDrawSetSaveFinalImage(sdraw,draw->savefinalfilename);CHKERRQ(ierr);} 462 } else { 463 PetscDraw draw; 464 ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 465 } 466 vdraw->singleton_made = PETSC_TRUE; 467 PetscFunctionReturn(0); 468 } 469 470 PetscErrorCode PetscViewerRestoreSubViewer_Draw(PetscViewer viewer,MPI_Comm comm,PetscViewer *sviewer) 471 { 472 PetscErrorCode ierr; 473 PetscMPIInt rank; 474 PetscInt i; 475 PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data,*svdraw; 476 477 PetscFunctionBegin; 478 if (!vdraw->singleton_made) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Trying to restore a singleton that was not gotten"); 479 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRMPI(ierr); 480 if (!rank) { 481 PetscDraw draw,sdraw; 482 483 ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 484 ierr = PetscViewerDrawGetDraw(*sviewer,0,&sdraw);CHKERRQ(ierr); 485 if (draw->savefilename) { 486 draw->savefilecount = sdraw->savefilecount; 487 ierr = MPI_Bcast(&draw->savefilecount,1,MPIU_INT,0,PetscObjectComm((PetscObject)draw));CHKERRMPI(ierr); 488 } 489 svdraw = (PetscViewer_Draw*)(*sviewer)->data; 490 for (i=0; i<vdraw->draw_max; i++) { 491 if (vdraw->draw[i] && svdraw->draw[i]) { 492 ierr = PetscDrawRestoreSingleton(vdraw->draw[i],&svdraw->draw[i]);CHKERRQ(ierr); 493 } 494 } 495 ierr = PetscFree3(svdraw->draw,svdraw->drawlg,svdraw->drawaxis);CHKERRQ(ierr); 496 ierr = PetscFree((*sviewer)->data);CHKERRQ(ierr); 497 ierr = PetscHeaderDestroy(sviewer);CHKERRQ(ierr); 498 } else { 499 PetscDraw draw; 500 501 ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 502 if (draw->savefilename) { 503 ierr = MPI_Bcast(&draw->savefilecount,1,MPIU_INT,0,PetscObjectComm((PetscObject)draw));CHKERRMPI(ierr); 504 } 505 } 506 507 vdraw->singleton_made = PETSC_FALSE; 508 PetscFunctionReturn(0); 509 } 510 511 PetscErrorCode PetscViewerSetFromOptions_Draw(PetscOptionItems *PetscOptionsObject,PetscViewer v) 512 { 513 PetscErrorCode ierr; 514 PetscReal bounds[16]; 515 PetscInt nbounds = 16; 516 PetscBool flg; 517 518 PetscFunctionBegin; 519 ierr = PetscOptionsHead(PetscOptionsObject,"Draw PetscViewer Options");CHKERRQ(ierr); 520 ierr = PetscOptionsRealArray("-draw_bounds","Bounds to put on plots axis","PetscViewerDrawSetBounds",bounds,&nbounds,&flg);CHKERRQ(ierr); 521 if (flg) { 522 ierr = PetscViewerDrawSetBounds(v,nbounds/2,bounds);CHKERRQ(ierr); 523 } 524 ierr = PetscOptionsTail();CHKERRQ(ierr); 525 PetscFunctionReturn(0); 526 } 527 528 PetscErrorCode PetscViewerView_Draw(PetscViewer viewer,PetscViewer v) 529 { 530 PetscErrorCode ierr; 531 PetscDraw draw; 532 PetscInt i; 533 PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data; 534 535 PetscFunctionBegin; 536 /* If the PetscViewer has just been created then no vdraw->draw yet 537 exists so this will not actually call the viewer on any draws. */ 538 for (i=0; i<vdraw->draw_base; i++) { 539 if (vdraw->draw[i]) { 540 ierr = PetscViewerDrawGetDraw(viewer,i,&draw);CHKERRQ(ierr); 541 ierr = PetscDrawView(draw,v);CHKERRQ(ierr); 542 } 543 } 544 PetscFunctionReturn(0); 545 } 546 547 /*MC 548 PETSCVIEWERDRAW - A viewer that generates graphics, either to the screen or a file 549 550 551 .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), PETSC_VIEWER_DRAW_(),PETSC_VIEWER_DRAW_SELF, PETSC_VIEWER_DRAW_WORLD, 552 PetscViewerCreate(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PETSCVIEWERBINARY, 553 PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERASCII, PETSCVIEWERMATLAB, 554 PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType() 555 556 Level: beginner 557 558 M*/ 559 PETSC_EXTERN PetscErrorCode PetscViewerCreate_Draw(PetscViewer viewer) 560 { 561 PetscErrorCode ierr; 562 PetscViewer_Draw *vdraw; 563 564 PetscFunctionBegin; 565 ierr = PetscNewLog(viewer,&vdraw);CHKERRQ(ierr); 566 viewer->data = (void*)vdraw; 567 568 viewer->ops->flush = PetscViewerFlush_Draw; 569 viewer->ops->view = PetscViewerView_Draw; 570 viewer->ops->destroy = PetscViewerDestroy_Draw; 571 viewer->ops->setfromoptions = PetscViewerSetFromOptions_Draw; 572 viewer->ops->getsubviewer = PetscViewerGetSubViewer_Draw; 573 viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_Draw; 574 575 /* these are created on the fly if requested */ 576 vdraw->draw_max = 5; 577 vdraw->draw_base = 0; 578 vdraw->w = PETSC_DECIDE; 579 vdraw->h = PETSC_DECIDE; 580 581 ierr = PetscCalloc3(vdraw->draw_max,&vdraw->draw,vdraw->draw_max,&vdraw->drawlg,vdraw->draw_max,&vdraw->drawaxis);CHKERRQ(ierr); 582 vdraw->singleton_made = PETSC_FALSE; 583 PetscFunctionReturn(0); 584 } 585 586 /*@ 587 PetscViewerDrawClear - Clears a PetscDraw graphic associated with a PetscViewer. 588 589 Not Collective 590 591 Input Parameter: 592 . viewer - the PetscViewer 593 594 Level: intermediate 595 596 .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), 597 598 @*/ 599 PetscErrorCode PetscViewerDrawClear(PetscViewer viewer) 600 { 601 PetscErrorCode ierr; 602 PetscViewer_Draw *vdraw; 603 PetscBool isdraw; 604 PetscInt i; 605 606 PetscFunctionBegin; 607 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 608 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 609 if (!isdraw) PetscFunctionReturn(0); 610 vdraw = (PetscViewer_Draw*)viewer->data; 611 612 for (i=0; i<vdraw->draw_max; i++) { 613 if (vdraw->draw[i]) {ierr = PetscDrawClear(vdraw->draw[i]);CHKERRQ(ierr);} 614 } 615 PetscFunctionReturn(0); 616 } 617 618 /*@ 619 PetscViewerDrawGetPause - Gets a pause for the first present draw 620 621 Not Collective 622 623 Input Parameter: 624 . viewer - the PetscViewer 625 626 Output Parameter: 627 . pause - the pause value 628 629 Level: intermediate 630 631 .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), 632 633 @*/ 634 PetscErrorCode PetscViewerDrawGetPause(PetscViewer viewer,PetscReal *pause) 635 { 636 PetscErrorCode ierr; 637 PetscViewer_Draw *vdraw; 638 PetscBool isdraw; 639 PetscInt i; 640 PetscDraw draw; 641 642 PetscFunctionBegin; 643 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 644 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 645 if (!isdraw) {*pause = 0.0; PetscFunctionReturn(0);} 646 vdraw = (PetscViewer_Draw*)viewer->data; 647 648 for (i=0; i<vdraw->draw_max; i++) { 649 if (vdraw->draw[i]) { 650 ierr = PetscDrawGetPause(vdraw->draw[i],pause);CHKERRQ(ierr); 651 PetscFunctionReturn(0); 652 } 653 } 654 /* none exist yet so create one and get its pause */ 655 ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 656 ierr = PetscDrawGetPause(draw,pause);CHKERRQ(ierr); 657 PetscFunctionReturn(0); 658 } 659 660 /*@ 661 PetscViewerDrawSetPause - Sets a pause for each PetscDraw in the viewer 662 663 Not Collective 664 665 Input Parameters: 666 + viewer - the PetscViewer 667 - pause - the pause value 668 669 Level: intermediate 670 671 .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), 672 673 @*/ 674 PetscErrorCode PetscViewerDrawSetPause(PetscViewer viewer,PetscReal pause) 675 { 676 PetscErrorCode ierr; 677 PetscViewer_Draw *vdraw; 678 PetscBool isdraw; 679 PetscInt i; 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->pause = pause; 688 for (i=0; i<vdraw->draw_max; i++) { 689 if (vdraw->draw[i]) {ierr = PetscDrawSetPause(vdraw->draw[i],pause);CHKERRQ(ierr);} 690 } 691 PetscFunctionReturn(0); 692 } 693 694 695 /*@ 696 PetscViewerDrawSetHold - Holds previous image when drawing new image 697 698 Not Collective 699 700 Input Parameters: 701 + viewer - the PetscViewer 702 - hold - indicates to hold or not 703 704 Level: intermediate 705 706 .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), 707 708 @*/ 709 PetscErrorCode PetscViewerDrawSetHold(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) PetscFunctionReturn(0); 719 vdraw = (PetscViewer_Draw*)viewer->data; 720 721 vdraw->hold = hold; 722 PetscFunctionReturn(0); 723 } 724 725 /*@ 726 PetscViewerDrawGetHold - Checks if holds previous image when drawing new image 727 728 Not Collective 729 730 Input Parameter: 731 . viewer - the PetscViewer 732 733 Output Parameter: 734 . hold - indicates to hold or not 735 736 Level: intermediate 737 738 .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), 739 740 @*/ 741 PetscErrorCode PetscViewerDrawGetHold(PetscViewer viewer,PetscBool *hold) 742 { 743 PetscErrorCode ierr; 744 PetscViewer_Draw *vdraw; 745 PetscBool isdraw; 746 747 PetscFunctionBegin; 748 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 749 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 750 if (!isdraw) {*hold = PETSC_FALSE; PetscFunctionReturn(0);} 751 vdraw = (PetscViewer_Draw*)viewer->data; 752 753 *hold = vdraw->hold; 754 PetscFunctionReturn(0); 755 } 756 757 /* ---------------------------------------------------------------------*/ 758 /* 759 The variable Petsc_Viewer_Draw_keyval is used to indicate an MPI attribute that 760 is attached to a communicator, in this case the attribute is a PetscViewer. 761 */ 762 PetscMPIInt Petsc_Viewer_Draw_keyval = MPI_KEYVAL_INVALID; 763 764 /*@C 765 PETSC_VIEWER_DRAW_ - Creates a window PetscViewer shared by all processors 766 in a communicator. 767 768 Collective 769 770 Input Parameter: 771 . comm - the MPI communicator to share the window PetscViewer 772 773 Level: intermediate 774 775 Notes: 776 Unlike almost all other PETSc routines, PETSC_VIEWER_DRAW_ does not return 777 an error code. The window is usually used in the form 778 $ XXXView(XXX object,PETSC_VIEWER_DRAW_(comm)); 779 780 .seealso: PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF, PetscViewerDrawOpen(), 781 @*/ 782 PetscViewer PETSC_VIEWER_DRAW_(MPI_Comm comm) 783 { 784 PetscErrorCode ierr; 785 PetscMPIInt flag; 786 PetscViewer viewer; 787 MPI_Comm ncomm; 788 789 PetscFunctionBegin; 790 ierr = PetscCommDuplicate(comm,&ncomm,NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);} 791 if (Petsc_Viewer_Draw_keyval == MPI_KEYVAL_INVALID) { 792 ierr = MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,MPI_COMM_NULL_DELETE_FN,&Petsc_Viewer_Draw_keyval,NULL); 793 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);} 794 } 795 ierr = MPI_Comm_get_attr(ncomm,Petsc_Viewer_Draw_keyval,(void**)&viewer,&flag); 796 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);} 797 if (!flag) { /* PetscViewer not yet created */ 798 ierr = PetscViewerDrawOpen(ncomm,NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,300,300,&viewer); 799 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");PetscFunctionReturn(NULL);} 800 ierr = PetscObjectRegisterDestroy((PetscObject)viewer); 801 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");PetscFunctionReturn(NULL);} 802 ierr = MPI_Comm_set_attr(ncomm,Petsc_Viewer_Draw_keyval,(void*)viewer); 803 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);} 804 } 805 ierr = PetscCommDestroy(&ncomm); 806 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");PetscFunctionReturn(NULL);} 807 PetscFunctionReturn(viewer); 808 } 809 810 /*@ 811 PetscViewerDrawSetBounds - sets the upper and lower bounds to be used in plotting 812 813 Collective on PetscViewer 814 815 Input Parameters: 816 + viewer - the PetscViewer (created with PetscViewerDrawOpen()) 817 . nbounds - number of plots that can be made with this viewer, for example the dof passed to DMDACreate() 818 - 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, ..... 819 820 821 Options Database: 822 . -draw_bounds minF0,maxF0,minF1,maxF1 - the lower left and upper right bounds 823 824 Level: intermediate 825 826 Notes: 827 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 828 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 829 this viewer. Otherwise the color to physical value meaning changes with each new image if this is not set. 830 831 832 .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen() 833 @*/ 834 PetscErrorCode PetscViewerDrawSetBounds(PetscViewer viewer,PetscInt nbounds,const PetscReal *bounds) 835 { 836 PetscViewer_Draw *vdraw; 837 PetscBool isdraw; 838 PetscErrorCode ierr; 839 840 841 PetscFunctionBegin; 842 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 843 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 844 if (!isdraw) PetscFunctionReturn(0); 845 vdraw = (PetscViewer_Draw*)viewer->data; 846 847 vdraw->nbounds = nbounds; 848 ierr = PetscFree(vdraw->bounds);CHKERRQ(ierr); 849 ierr = PetscMalloc1(2*nbounds,&vdraw->bounds);CHKERRQ(ierr); 850 ierr = PetscArraycpy(vdraw->bounds,bounds,2*nbounds);CHKERRQ(ierr); 851 PetscFunctionReturn(0); 852 } 853 854 /*@C 855 PetscViewerDrawGetBounds - gets the upper and lower bounds to be used in plotting set with PetscViewerDrawSetBounds() 856 857 Collective on PetscViewer 858 859 Input Parameter: 860 . viewer - the PetscViewer (created with PetscViewerDrawOpen()) 861 862 Output Parameters: 863 + nbounds - number of plots that can be made with this viewer, for example the dof passed to DMDACreate() 864 - 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, ..... 865 866 Level: intermediate 867 868 869 .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen(), PetscViewerDrawSetBounds() 870 @*/ 871 PetscErrorCode PetscViewerDrawGetBounds(PetscViewer viewer,PetscInt *nbounds,const PetscReal **bounds) 872 { 873 PetscViewer_Draw *vdraw; 874 PetscBool isdraw; 875 PetscErrorCode ierr; 876 877 PetscFunctionBegin; 878 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 879 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 880 if (!isdraw) {if (nbounds) *nbounds = 0; if (bounds) *bounds = NULL; PetscFunctionReturn(0);} 881 vdraw = (PetscViewer_Draw*)viewer->data; 882 883 if (nbounds) *nbounds = vdraw->nbounds; 884 if (bounds) *bounds = vdraw->bounds; 885 PetscFunctionReturn(0); 886 } 887