Actual source code: drawv.c

  1: #define PETSC_DLL

 3:  #include ../src/sys/viewer/impls/draw/vdraw.h

  7: PetscErrorCode PetscViewerDestroy_Draw(PetscViewer v)
  8: {
  9:   PetscErrorCode   ierr;
 10:   PetscInt         i;
 11:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)v->data;

 14:   if (vdraw->singleton_made) {
 15:     SETERRQ(PETSC_ERR_ORDER,"Destroying PetscViewer without first restoring singleton");
 16:   }
 17:   for (i=0; i<vdraw->draw_max; i++) {
 18:     if (vdraw->drawaxis[i]) {PetscDrawAxisDestroy(vdraw->drawaxis[i]);}
 19:     if (vdraw->drawlg[i])   {PetscDrawLGDestroy(vdraw->drawlg[i]);}
 20:     if (vdraw->draw[i])     {PetscDrawDestroy(vdraw->draw[i]);}
 21:   }

 23:   PetscFree(vdraw->display);
 24:   PetscFree(vdraw->title);
 25:   PetscFree3(vdraw->draw,vdraw->drawlg,vdraw->drawaxis);
 26:   PetscFree(vdraw);
 27:   return(0);
 28: }

 32: PetscErrorCode PetscViewerFlush_Draw(PetscViewer v)
 33: {
 34:   PetscErrorCode   ierr;
 35:   PetscInt         i;
 36:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)v->data;

 39:   for (i=0; i<vdraw->draw_max; i++) {
 40:     if (vdraw->draw[i]) {PetscDrawSynchronizedFlush(vdraw->draw[i]);}
 41:   }
 42:   return(0);
 43: }

 47: /*@C
 48:     PetscViewerDrawGetDraw - Returns PetscDraw object from PetscViewer object.
 49:     This PetscDraw object may then be used to perform graphics using 
 50:     PetscDrawXXX() commands.

 52:     Not collective (but PetscDraw returned will be parallel object if PetscViewer is)

 54:     Input Parameters:
 55: +  viewer - the PetscViewer (created with PetscViewerDrawOpen())
 56: -   windownumber - indicates which subwindow (usually 0)

 58:     Ouput Parameter:
 59: .   draw - the draw object

 61:     Level: intermediate

 63:    Concepts: drawing^accessing PetscDraw context from PetscViewer
 64:    Concepts: graphics

 66: .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen()
 67: @*/
 68: PetscErrorCode  PetscViewerDrawGetDraw(PetscViewer viewer,PetscInt  windownumber,PetscDraw *draw)
 69: {
 70:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;
 71:   PetscErrorCode   ierr;
 72:   PetscTruth       isdraw;
 73:   char             *title;

 78:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
 79:   if (!isdraw) {
 80:     SETERRQ(PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
 81:   }
 82:   if (windownumber < 0) {
 83:     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Window number cannot be negative");
 84:   }
 85:   windownumber += vdraw->draw_base;
 86:   if (windownumber >= vdraw->draw_max) {
 87:      /* allocate twice as many slots as needed */
 88:      PetscInt      draw_max = vdraw->draw_max;
 89:      PetscDraw     *tdraw = vdraw->draw;
 90:      PetscDrawLG   *drawlg = vdraw->drawlg;
 91:      PetscDrawAxis *drawaxis = vdraw->drawaxis;

 93:      vdraw->draw_max = 2*windownumber;
 94:      PetscMalloc3(vdraw->draw_max,PetscDraw,&vdraw->draw,vdraw->draw_max,PetscDrawLG,&vdraw->drawlg,vdraw->draw_max,PetscDrawAxis,&vdraw->drawaxis);
 95:      PetscMemzero(vdraw->draw,vdraw->draw_max*sizeof(PetscDraw));
 96:      PetscMemzero(vdraw->drawlg,vdraw->draw_max*sizeof(PetscDrawLG));
 97:      PetscMemzero(vdraw->drawaxis,vdraw->draw_max*sizeof(PetscDrawAxis));

 99:      PetscMemcpy(vdraw->draw,tdraw,draw_max*sizeof(PetscDraw));
100:      PetscMemcpy(vdraw->drawlg,drawlg,draw_max*sizeof(PetscDrawLG));
101:      PetscMemcpy(vdraw->drawaxis,drawaxis,draw_max*sizeof(PetscDrawAxis));

103:      PetscFree3(tdraw,drawlg,drawaxis);
104:   }

106:   if (!vdraw->draw[windownumber]) {
107:     if (!windownumber) {
108:       title = vdraw->title;
109:     } else {
110:       char tmp_str[128];
111:       PetscSNPrintf(tmp_str, 128, "%s:%d", vdraw->title,windownumber);
112:       title = tmp_str;
113:     }
114:     PetscDrawCreate(((PetscObject)viewer)->comm,vdraw->display,title,PETSC_DECIDE,PETSC_DECIDE,vdraw->w,vdraw->h,&vdraw->draw[windownumber]);
115:     PetscDrawSetFromOptions(vdraw->draw[windownumber]);
116:   }
117:   if (draw) *draw = vdraw->draw[windownumber];
118:   return(0);
119: }

123: /*@C
124:     PetscViewerDrawBaseAdd - add to the base integer that is added to the windownumber passed to PetscViewerDrawGetDraw()

126:     Not collective (but PetscDraw returned will be parallel object if PetscViewer is)

128:     Input Parameters:
129: +  viewer - the PetscViewer (created with PetscViewerDrawOpen())
130: -   windownumber - how much to add to the base

132:     Level: developer

134:    Concepts: drawing^accessing PetscDraw context from PetscViewer
135:    Concepts: graphics

137: .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), PetscViewerDrawBaseSet()
138: @*/
139: PetscErrorCode  PetscViewerDrawBaseAdd(PetscViewer viewer,PetscInt  windownumber)
140: {
141:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;
142:   PetscErrorCode   ierr;
143:   PetscTruth       isdraw;

147:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
148:   if (!isdraw) {
149:     SETERRQ(PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
150:   }
151:   if (windownumber + vdraw->draw_base < 0) {
152:     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Resulting base %D cannot be negative",windownumber+vdraw->draw_base);
153:   }
154:   vdraw->draw_base += windownumber;
155:   return(0);
156: }

160: /*@C
161:     PetscViewerDrawBaseSet - sets the base integer that is added to the windownumber passed to PetscViewerDrawGetDraw()

163:     Not collective (but PetscDraw returned will be parallel object if PetscViewer is)

165:     Input Parameters:
166: +  viewer - the PetscViewer (created with PetscViewerDrawOpen())
167: -   windownumber - value to set the base

169:     Level: developer

171:    Concepts: drawing^accessing PetscDraw context from PetscViewer
172:    Concepts: graphics

174: .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), PetscViewerDrawBaseAdd()
175: @*/
176: PetscErrorCode  PetscViewerDrawBaseSet(PetscViewer viewer,PetscInt  windownumber)
177: {
178:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;
179:   PetscErrorCode   ierr;
180:   PetscTruth       isdraw;

184:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
185:   if (!isdraw) {
186:     SETERRQ(PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
187:   }
188:   if (windownumber < 0) {
189:     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Resulting base %D cannot be negative",windownumber);
190:   }
191:   vdraw->draw_base = windownumber;
192:   return(0);
193: }

197: /*@C
198:     PetscViewerDrawGetDrawLG - Returns PetscDrawLG object from PetscViewer object.
199:     This PetscDrawLG object may then be used to perform graphics using 
200:     PetscDrawLGXXX() commands.

202:     Not Collective (but PetscDrawLG object will be parallel if PetscViewer is)

204:     Input Parameter:
205: +   PetscViewer - the PetscViewer (created with PetscViewerDrawOpen())
206: -   windownumber - indicates which subwindow (usually 0)

208:     Ouput Parameter:
209: .   draw - the draw line graph object

211:     Level: intermediate

213:   Concepts: line graph^accessing context

215: .seealso: PetscViewerDrawGetDraw(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen()
216: @*/
217: PetscErrorCode  PetscViewerDrawGetDrawLG(PetscViewer viewer,PetscInt  windownumber,PetscDrawLG *drawlg)
218: {
219:   PetscErrorCode   ierr;
220:   PetscTruth       isdraw;
221:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;

226:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
227:   if (!isdraw) {
228:     SETERRQ(PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
229:   }
230:   if (windownumber < 0) {
231:     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Window number cannot be negative");
232:   }

234:   if (windownumber+vdraw->draw_base >= vdraw->draw_max || !vdraw->draw[windownumber+vdraw->draw_base]) {
235:     PetscViewerDrawGetDraw(viewer,windownumber,PETSC_NULL);
236:   }
237:   if (!vdraw->drawlg[windownumber+vdraw->draw_base]) {
238:     PetscDrawLGCreate(vdraw->draw[windownumber+vdraw->draw_base],1,&vdraw->drawlg[windownumber+vdraw->draw_base]);
239:     PetscLogObjectParent(viewer,vdraw->drawlg[windownumber+vdraw->draw_base]);
240:   }
241:   *drawlg = vdraw->drawlg[windownumber+vdraw->draw_base];
242:   return(0);
243: }

247: /*@C
248:     PetscViewerDrawGetDrawAxis - Returns PetscDrawAxis object from PetscViewer object.
249:     This PetscDrawAxis object may then be used to perform graphics using 
250:     PetscDrawAxisXXX() commands.

252:     Not Collective (but PetscDrawAxis object will be parallel if PetscViewer is)

254:     Input Parameter:
255: +   viewer - the PetscViewer (created with PetscViewerDrawOpen()
256: -   windownumber - indicates which subwindow (usually 0)

258:     Ouput Parameter:
259: .   drawaxis - the draw axis object

261:     Level: advanced

263:   Concepts: line graph^accessing context

265: .seealso: PetscViewerDrawGetDraw(), PetscViewerDrawGetLG(), PetscViewerDrawOpen()
266: @*/
267: PetscErrorCode  PetscViewerDrawGetDrawAxis(PetscViewer viewer,PetscInt  windownumber,PetscDrawAxis *drawaxis)
268: {
269:   PetscErrorCode   ierr;
270:   PetscTruth       isdraw;
271:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;;

276:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
277:   if (!isdraw) {
278:     SETERRQ(PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
279:   }
280:   if (windownumber < 0) {
281:     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Window number cannot be negative");
282:   }

284:   if (windownumber+vdraw->draw_base >= vdraw->draw_max || !vdraw->draw[windownumber+vdraw->draw_base]) {
285:     PetscViewerDrawGetDraw(viewer,windownumber,PETSC_NULL);
286:   }
287:   if (!vdraw->drawaxis[windownumber+vdraw->draw_base]) {
288:     PetscDrawAxisCreate(vdraw->draw[windownumber+vdraw->draw_base],&vdraw->drawaxis[windownumber+vdraw->draw_base]);
289:     PetscLogObjectParent(viewer,vdraw->drawaxis[windownumber+vdraw->draw_base]);
290:   }
291:   *drawaxis = vdraw->drawaxis[windownumber+vdraw->draw_base];
292:   return(0);
293: }

297: PetscErrorCode  PetscViewerDrawSetInfo(PetscViewer v,const char display[],const char title[],int x,int y,int w,int h)
298: {
299:   PetscErrorCode   ierr;
300:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)v->data;

303:   vdraw->h  = h;
304:   vdraw->w  = w;
305:   PetscStrallocpy(display,&vdraw->display);
306:   PetscStrallocpy(title,&vdraw->title);
307:   return(0);
308: }

312: /*@C
313:    PetscViewerDrawOpen - Opens an X window for use as a PetscViewer. If you want to 
314:    do graphics in this window, you must call PetscViewerDrawGetDraw() and
315:    perform the graphics on the PetscDraw object.

317:    Collective on MPI_Comm

319:    Input Parameters:
320: +  comm - communicator that will share window
321: .  display - the X display on which to open, or null for the local machine
322: .  title - the title to put in the title bar, or null for no title
323: .  x, y - the screen coordinates of the upper left corner of window, or use PETSC_DECIDE
324: -  w, h - window width and height in pixels, or may use PETSC_DECIDE or PETSC_DRAW_FULL_SIZE, PETSC_DRAW_HALF_SIZE,
325:           PETSC_DRAW_THIRD_SIZE, PETSC_DRAW_QUARTER_SIZE

327:    Output Parameters:
328: . viewer - the PetscViewer

330:    Format Options:
331: +  PETSC_VIEWER_DRAW_BASIC - displays with basic format
332: -  PETSC_VIEWER_DRAW_LG    - displays using a line graph

334:    Options Database Keys:
335:    PetscViewerDrawOpen() calls PetscDrawCreate(), so see the manual page for
336:    PetscDrawCreate() for runtime options, including
337: +  -draw_type x or null
338: .  -nox - Disables all x-windows output
339: .  -display <name> - Specifies name of machine for the X display
340: .  -geometry <x,y,w,h> - allows setting the window location and size
341: -  -draw_pause <pause> - Sets time (in seconds) that the
342:      program pauses after PetscDrawPause() has been called
343:      (0 is default, -1 implies until user input).

345:    Level: beginner

347:    Note for Fortran Programmers:
348:    Whenever indicating null character data in a Fortran code,
349:    PETSC_NULL_CHARACTER must be employed; using PETSC_NULL is not
350:    correct for character data!  Thus, PETSC_NULL_CHARACTER can be
351:    used for the display and title input parameters.

353:   Concepts: graphics^opening PetscViewer
354:   Concepts: drawing^opening PetscViewer


357: .seealso: PetscDrawCreate(), PetscViewerDestroy(), PetscViewerDrawGetDraw(), PetscViewerCreate(), PETSC_VIEWER_DRAW_,
358:           PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF
359: @*/
360: PetscErrorCode  PetscViewerDrawOpen(MPI_Comm comm,const char display[],const char title[],int x,int y,int w,int h,PetscViewer *viewer)
361: {

365:   PetscViewerCreate(comm,viewer);
366:   PetscViewerSetType(*viewer,PETSC_VIEWER_DRAW);
367:   PetscViewerDrawSetInfo(*viewer,display,title,x,y,w,h);
368:   return(0);
369: }

373: PetscErrorCode PetscViewerGetSingleton_Draw(PetscViewer viewer,PetscViewer *sviewer)
374: {
375:   PetscErrorCode   ierr;
376:   PetscMPIInt      rank;
377:   PetscInt         i;
378:   PetscViewer_Draw *vdraw = (PetscViewer_Draw *)viewer->data,*vsdraw;

381:   if (vdraw->singleton_made) {
382:     SETERRQ(PETSC_ERR_ORDER,"Trying to get singleton without first restoring previous");
383:   }

385:   /* only processor zero can use the PetscViewer draw singleton */
386:   MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
387:   if (!rank) {
388:     PetscViewerCreate(PETSC_COMM_SELF,sviewer);
389:     PetscViewerSetType(*sviewer,PETSC_VIEWER_DRAW);
390:     vsdraw = (PetscViewer_Draw *)(*sviewer)->data;
391:     for (i=0; i<vdraw->draw_max; i++) {
392:       if (vdraw->draw[i]) {
393:         PetscDrawGetSingleton(vdraw->draw[i],&vsdraw->draw[i]);
394:       }
395:     }
396:   }
397:   vdraw->singleton_made = PETSC_TRUE;
398:   return(0);
399: }

403: PetscErrorCode PetscViewerRestoreSingleton_Draw(PetscViewer viewer,PetscViewer *sviewer)
404: {
405:   PetscErrorCode   ierr;
406:   PetscMPIInt      rank;
407:   PetscInt         i;
408:   PetscViewer_Draw *vdraw = (PetscViewer_Draw *)viewer->data,*vsdraw;

411:   if (!vdraw->singleton_made) {
412:     SETERRQ(PETSC_ERR_ORDER,"Trying to restore a singleton that was not gotten");
413:   }
414:   MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
415:   if (!rank) {
416:     vsdraw = (PetscViewer_Draw *)(*sviewer)->data;
417:     for (i=0; i<vdraw->draw_max; i++) {
418:       if (vdraw->draw[i] && vsdraw->draw[i]) {
419:          PetscDrawRestoreSingleton(vdraw->draw[i],&vsdraw->draw[i]);
420:       }
421:     }
422:     PetscFree3(vsdraw->draw,vsdraw->drawlg,vsdraw->drawaxis);
423:     PetscFree((*sviewer)->data);
424:     PetscHeaderDestroy(*sviewer);
425:   }
426:   vdraw->singleton_made = PETSC_FALSE;
427:   return(0);
428: }

433: PetscErrorCode  PetscViewerCreate_Draw(PetscViewer viewer)
434: {
435:   PetscInt         i;
436:   PetscErrorCode   ierr;
437:   PetscViewer_Draw *vdraw;

440:   PetscNewLog(viewer,PetscViewer_Draw,&vdraw);
441:   viewer->data = (void*)vdraw;

443:   viewer->ops->flush            = PetscViewerFlush_Draw;
444:   viewer->ops->destroy          = PetscViewerDestroy_Draw;
445:   viewer->ops->getsingleton     = PetscViewerGetSingleton_Draw;
446:   viewer->ops->restoresingleton = PetscViewerRestoreSingleton_Draw;
447:   viewer->format                = PETSC_VIEWER_NOFORMAT;

449:   /* these are created on the fly if requested */
450:   vdraw->draw_max  = 5;
451:   vdraw->draw_base = 0;
452:   PetscMalloc3(vdraw->draw_max,PetscDraw,&vdraw->draw,vdraw->draw_max,PetscDrawLG,&vdraw->drawlg,vdraw->draw_max,PetscDrawAxis,&vdraw->drawaxis);
453:   PetscMemzero(vdraw->draw,vdraw->draw_max*sizeof(PetscDraw));
454:   PetscMemzero(vdraw->drawlg,vdraw->draw_max*sizeof(PetscDrawLG));
455:   PetscMemzero(vdraw->drawaxis,vdraw->draw_max*sizeof(PetscDrawAxis));
456:   for (i=0; i<vdraw->draw_max; i++) {
457:     vdraw->draw[i]     = 0;
458:     vdraw->drawlg[i]   = 0;
459:     vdraw->drawaxis[i] = 0;
460:   }
461:   vdraw->singleton_made = PETSC_FALSE;
462:   return(0);
463: }

468: /*@
469:     PetscViewerDrawClear - Clears a PetscDraw graphic associated with a PetscViewer.

471:     Not Collective

473:     Input Parameter:
474: .  viewer - the PetscViewer 

476:     Level: intermediate

478: .seealso: PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), 

480: @*/
481: PetscErrorCode  PetscViewerDrawClear(PetscViewer viewer)
482: {
483:   PetscErrorCode   ierr;
484:   PetscInt         i;
485:   PetscTruth       isdraw;
486:   PetscViewer_Draw *vdraw;

489:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
490:   if (isdraw) {
491:     vdraw = (PetscViewer_Draw*)viewer->data;
492:     for (i=0; i<vdraw->draw_max; i++) {
493:       if (vdraw->draw[i]) {PetscDrawClear(vdraw->draw[i]);}
494:     }
495:   }
496:   return(0);
497: }

499: /* ---------------------------------------------------------------------*/
500: /*
501:     The variable Petsc_Viewer_Draw_keyval is used to indicate an MPI attribute that
502:   is attached to a communicator, in this case the attribute is a PetscViewer.
503: */
504: static PetscMPIInt Petsc_Viewer_Draw_keyval = MPI_KEYVAL_INVALID;

508: /*@C
509:     PETSC_VIEWER_DRAW_ - Creates a window PetscViewer shared by all processors 
510:                      in a communicator.

512:      Collective on MPI_Comm

514:      Input Parameter:
515: .    comm - the MPI communicator to share the window PetscViewer

517:      Level: intermediate

519:      Notes:
520:      Unlike almost all other PETSc routines, PETSC_VIEWER_DRAW_ does not return 
521:      an error code.  The window is usually used in the form
522: $       XXXView(XXX object,PETSC_VIEWER_DRAW_(comm));

524: .seealso: PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF, PetscViewerDrawOpen(), 
525: @*/
526: PetscViewer  PETSC_VIEWER_DRAW_(MPI_Comm comm)
527: {
529:   PetscMPIInt    flag;
530:   PetscViewer    viewer;

533:   if (Petsc_Viewer_Draw_keyval == MPI_KEYVAL_INVALID) {
534:     MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Draw_keyval,0);
535:     if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,1,1," ");return(0);}
536:   }
537:   MPI_Attr_get(comm,Petsc_Viewer_Draw_keyval,(void **)&viewer,&flag);
538:   if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,1,1," ");return(0);}
539:   if (!flag) { /* PetscViewer not yet created */
540:     PetscViewerDrawOpen(comm,0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,&viewer);
541:     if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,1,1," ");return(0);}
542:     PetscObjectRegisterDestroy((PetscObject)viewer);
543:     if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,1,1," ");return(0);}
544:     MPI_Attr_put(comm,Petsc_Viewer_Draw_keyval,(void*)viewer);
545:     if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,1,1," ");return(0);}
546:   }
547:   PetscFunctionReturn(viewer);
548: }