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