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