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