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