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