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 #undef __FUNCT__ 505 #define __FUNCT__ "PetscViewerCreate_Draw" 506 PETSC_EXTERN PetscErrorCode PetscViewerCreate_Draw(PetscViewer viewer) 507 { 508 PetscErrorCode ierr; 509 PetscViewer_Draw *vdraw; 510 511 PetscFunctionBegin; 512 ierr = PetscNewLog(viewer,&vdraw);CHKERRQ(ierr); 513 viewer->data = (void*)vdraw; 514 515 viewer->ops->flush = PetscViewerFlush_Draw; 516 viewer->ops->view = PetscViewerView_Draw; 517 viewer->ops->destroy = PetscViewerDestroy_Draw; 518 viewer->ops->setfromoptions = PetscViewerSetFromOptions_Draw; 519 viewer->ops->getsubviewer = PetscViewerGetSubViewer_Draw; 520 viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_Draw; 521 522 /* these are created on the fly if requested */ 523 vdraw->draw_max = 5; 524 vdraw->draw_base = 0; 525 vdraw->w = PETSC_DECIDE; 526 vdraw->h = PETSC_DECIDE; 527 528 ierr = PetscCalloc3(vdraw->draw_max,&vdraw->draw,vdraw->draw_max,&vdraw->drawlg,vdraw->draw_max,&vdraw->drawaxis);CHKERRQ(ierr); 529 vdraw->singleton_made = PETSC_FALSE; 530 PetscFunctionReturn(0); 531 } 532 533 #undef __FUNCT__ 534 #define __FUNCT__ "PetscViewerDrawClear" 535 /*@ 536 PetscViewerDrawClear - Clears a PetscDraw graphic associated with a PetscViewer. 537 538 Not Collective 539 540 Input Parameter: 541 . viewer - the PetscViewer 542 543 Level: intermediate 544 545 .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), 546 547 @*/ 548 PetscErrorCode PetscViewerDrawClear(PetscViewer viewer) 549 { 550 PetscErrorCode ierr; 551 PetscViewer_Draw *vdraw; 552 PetscBool isdraw; 553 PetscInt i; 554 555 PetscFunctionBegin; 556 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 557 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 558 if (!isdraw) PetscFunctionReturn(0); 559 vdraw = (PetscViewer_Draw*)viewer->data; 560 561 for (i=0; i<vdraw->draw_max; i++) { 562 if (vdraw->draw[i]) {ierr = PetscDrawClear(vdraw->draw[i]);CHKERRQ(ierr);} 563 } 564 PetscFunctionReturn(0); 565 } 566 567 #undef __FUNCT__ 568 #define __FUNCT__ "PetscViewerDrawGetPause" 569 /*@ 570 PetscViewerDrawGetPause - Gets a pause for the first present draw 571 572 Not Collective 573 574 Input Parameter: 575 . viewer - the PetscViewer 576 577 Output Parameter: 578 . pause - the pause value 579 580 Level: intermediate 581 582 .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), 583 584 @*/ 585 PetscErrorCode PetscViewerDrawGetPause(PetscViewer viewer,PetscReal *pause) 586 { 587 PetscErrorCode ierr; 588 PetscViewer_Draw *vdraw; 589 PetscBool isdraw; 590 PetscInt i; 591 PetscDraw draw; 592 593 PetscFunctionBegin; 594 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 595 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 596 if (!isdraw) {*pause = 0.0; PetscFunctionReturn(0);} 597 vdraw = (PetscViewer_Draw*)viewer->data; 598 599 for (i=0; i<vdraw->draw_max; i++) { 600 if (vdraw->draw[i]) { 601 ierr = PetscDrawGetPause(vdraw->draw[i],pause);CHKERRQ(ierr); 602 PetscFunctionReturn(0); 603 } 604 } 605 /* none exist yet so create one and get its pause */ 606 ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 607 ierr = PetscDrawGetPause(draw,pause);CHKERRQ(ierr); 608 PetscFunctionReturn(0); 609 } 610 611 #undef __FUNCT__ 612 #define __FUNCT__ "PetscViewerDrawSetPause" 613 /*@ 614 PetscViewerDrawSetPause - Sets a pause for each PetscDraw in the viewer 615 616 Not Collective 617 618 Input Parameters: 619 + viewer - the PetscViewer 620 - pause - the pause value 621 622 Level: intermediate 623 624 .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), 625 626 @*/ 627 PetscErrorCode PetscViewerDrawSetPause(PetscViewer viewer,PetscReal pause) 628 { 629 PetscErrorCode ierr; 630 PetscViewer_Draw *vdraw; 631 PetscBool isdraw; 632 PetscInt i; 633 634 PetscFunctionBegin; 635 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 636 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 637 if (!isdraw) PetscFunctionReturn(0); 638 vdraw = (PetscViewer_Draw*)viewer->data; 639 640 vdraw->pause = pause; 641 for (i=0; i<vdraw->draw_max; i++) { 642 if (vdraw->draw[i]) {ierr = PetscDrawSetPause(vdraw->draw[i],pause);CHKERRQ(ierr);} 643 } 644 PetscFunctionReturn(0); 645 } 646 647 648 #undef __FUNCT__ 649 #define __FUNCT__ "PetscViewerDrawSetHold" 650 /*@ 651 PetscViewerDrawSetHold - Holds previous image when drawing new image 652 653 Not Collective 654 655 Input Parameters: 656 + viewer - the PetscViewer 657 - hold - indicates to hold or not 658 659 Level: intermediate 660 661 .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), 662 663 @*/ 664 PetscErrorCode PetscViewerDrawSetHold(PetscViewer viewer,PetscBool hold) 665 { 666 PetscErrorCode ierr; 667 PetscViewer_Draw *vdraw; 668 PetscBool isdraw; 669 670 PetscFunctionBegin; 671 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 672 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 673 if (!isdraw) PetscFunctionReturn(0); 674 vdraw = (PetscViewer_Draw*)viewer->data; 675 676 vdraw->hold = hold; 677 PetscFunctionReturn(0); 678 } 679 680 #undef __FUNCT__ 681 #define __FUNCT__ "PetscViewerDrawGetHold" 682 /*@ 683 PetscViewerDrawGetHold - Checks if holds previous image when drawing new image 684 685 Not Collective 686 687 Input Parameter: 688 . viewer - the PetscViewer 689 690 Output Parameter: 691 . hold - indicates to hold or not 692 693 Level: intermediate 694 695 .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), 696 697 @*/ 698 PetscErrorCode PetscViewerDrawGetHold(PetscViewer viewer,PetscBool *hold) 699 { 700 PetscErrorCode ierr; 701 PetscViewer_Draw *vdraw; 702 PetscBool isdraw; 703 704 PetscFunctionBegin; 705 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 706 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 707 if (!isdraw) {*hold = PETSC_FALSE; PetscFunctionReturn(0);} 708 vdraw = (PetscViewer_Draw*)viewer->data; 709 710 *hold = vdraw->hold; 711 PetscFunctionReturn(0); 712 } 713 714 /* ---------------------------------------------------------------------*/ 715 /* 716 The variable Petsc_Viewer_Draw_keyval is used to indicate an MPI attribute that 717 is attached to a communicator, in this case the attribute is a PetscViewer. 718 */ 719 static PetscMPIInt Petsc_Viewer_Draw_keyval = MPI_KEYVAL_INVALID; 720 721 #undef __FUNCT__ 722 #define __FUNCT__ "PETSC_VIEWER_DRAW_" 723 /*@C 724 PETSC_VIEWER_DRAW_ - Creates a window PetscViewer shared by all processors 725 in a communicator. 726 727 Collective on MPI_Comm 728 729 Input Parameter: 730 . comm - the MPI communicator to share the window PetscViewer 731 732 Level: intermediate 733 734 Notes: 735 Unlike almost all other PETSc routines, PETSC_VIEWER_DRAW_ does not return 736 an error code. The window is usually used in the form 737 $ XXXView(XXX object,PETSC_VIEWER_DRAW_(comm)); 738 739 .seealso: PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF, PetscViewerDrawOpen(), 740 @*/ 741 PetscViewer PETSC_VIEWER_DRAW_(MPI_Comm comm) 742 { 743 PetscErrorCode ierr; 744 PetscMPIInt flag; 745 PetscViewer viewer; 746 MPI_Comm ncomm; 747 748 PetscFunctionBegin; 749 ierr = PetscCommDuplicate(comm,&ncomm,NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 750 if (Petsc_Viewer_Draw_keyval == MPI_KEYVAL_INVALID) { 751 ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Draw_keyval,0); 752 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 753 } 754 ierr = MPI_Attr_get(ncomm,Petsc_Viewer_Draw_keyval,(void**)&viewer,&flag); 755 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 756 if (!flag) { /* PetscViewer not yet created */ 757 ierr = PetscViewerDrawOpen(ncomm,0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,&viewer); 758 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 759 ierr = PetscObjectRegisterDestroy((PetscObject)viewer); 760 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 761 ierr = MPI_Attr_put(ncomm,Petsc_Viewer_Draw_keyval,(void*)viewer); 762 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 763 } 764 ierr = PetscCommDestroy(&ncomm); 765 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 766 PetscFunctionReturn(viewer); 767 } 768 769 #undef __FUNCT__ 770 #define __FUNCT__ "PetscViewerDrawSetBounds" 771 /*@ 772 PetscViewerDrawSetBounds - sets the upper and lower bounds to be used in plotting 773 774 Collective on PetscViewer 775 776 Input Parameters: 777 + viewer - the PetscViewer (created with PetscViewerDrawOpen()) 778 . nbounds - number of plots that can be made with this viewer, for example the dof passed to DMDACreate() 779 - 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, ..... 780 781 782 Options Database: 783 . -draw_bounds minF0,maxF0,minF1,maxF1 784 785 Level: intermediate 786 787 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 788 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 789 this viewer. Otherwise the color to physical value meaning changes with each new image if this is not set. 790 791 Concepts: drawing^accessing PetscDraw context from PetscViewer 792 Concepts: graphics 793 794 .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen() 795 @*/ 796 PetscErrorCode PetscViewerDrawSetBounds(PetscViewer viewer,PetscInt nbounds,const PetscReal *bounds) 797 { 798 PetscViewer_Draw *vdraw; 799 PetscBool isdraw; 800 PetscErrorCode ierr; 801 802 803 PetscFunctionBegin; 804 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 805 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 806 if (!isdraw) PetscFunctionReturn(0); 807 vdraw = (PetscViewer_Draw*)viewer->data; 808 809 vdraw->nbounds = nbounds; 810 ierr = PetscFree(vdraw->bounds);CHKERRQ(ierr); 811 ierr = PetscMalloc1(2*nbounds,&vdraw->bounds);CHKERRQ(ierr); 812 ierr = PetscMemcpy(vdraw->bounds,bounds,2*nbounds*sizeof(PetscReal));CHKERRQ(ierr); 813 PetscFunctionReturn(0); 814 } 815 816 #undef __FUNCT__ 817 #define __FUNCT__ "PetscViewerDrawGetBounds" 818 /*@C 819 PetscViewerDrawGetBounds - gets the upper and lower bounds to be used in plotting set with PetscViewerDrawSetBounds() 820 821 Collective on PetscViewer 822 823 Input Parameter: 824 . viewer - the PetscViewer (created with PetscViewerDrawOpen()) 825 826 Output Paramters: 827 + nbounds - number of plots that can be made with this viewer, for example the dof passed to DMDACreate() 828 - 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, ..... 829 830 Level: intermediate 831 832 Concepts: drawing^accessing PetscDraw context from PetscViewer 833 Concepts: graphics 834 835 .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen(), PetscViewerDrawSetBounds() 836 @*/ 837 PetscErrorCode PetscViewerDrawGetBounds(PetscViewer viewer,PetscInt *nbounds,const PetscReal **bounds) 838 { 839 PetscViewer_Draw *vdraw; 840 PetscBool isdraw; 841 PetscErrorCode ierr; 842 843 PetscFunctionBegin; 844 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 845 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 846 if (!isdraw) {if (nbounds) *nbounds = 0; if (bounds) *bounds = NULL; PetscFunctionReturn(0);} 847 vdraw = (PetscViewer_Draw*)viewer->data; 848 849 if (nbounds) *nbounds = vdraw->nbounds; 850 if (bounds) *bounds = vdraw->bounds; 851 PetscFunctionReturn(0); 852 } 853