Actual source code: drawv.c

  1: /*$Id: drawv.c,v 1.61 2001/04/22 17:22:00 buschelm Exp $*/

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

  5: int PetscViewerDestroy_Draw(PetscViewer v)
  6: {
  7:   int              ierr,i;
  8:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)v->data;

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

 26: int PetscViewerFlush_Draw(PetscViewer v)
 27: {
 28:   int              ierr,i;
 29:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)v->data;

 32:   for (i=0; i<vdraw->draw_max; i++) {
 33:     if (vdraw->draw[i]) {PetscDrawSynchronizedFlush(vdraw->draw[i]);}
 34:   }
 35:   return(0);
 36: }

 38: /*@C
 39:     PetscViewerDrawGetDraw - Returns PetscDraw object from PetscViewer object.
 40:     This PetscDraw object may then be used to perform graphics using 
 41:     PetscDrawXXX() commands.

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

 45:     Input Parameters:
 46: +  viewer - the PetscViewer (created with PetscViewerDrawOpen()
 47: -   windownumber - indicates which subwindow (usually 0)

 49:     Ouput Parameter:
 50: .   draw - the draw object

 52:     Level: intermediate

 54:    Concepts: drawing^accessing PetscDraw context from PetscViewer
 55:    Concepts: graphics

 57: .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen()
 58: @*/
 59: int PetscViewerDrawGetDraw(PetscViewer viewer,int windownumber,PetscDraw *draw)
 60: {
 61:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;
 62:   int              ierr;
 63:   PetscTruth       isdraw;
 64:   char             *title;

 69:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
 70:   if (!isdraw) {
 71:     SETERRQ(PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
 72:   }
 73:   if (windownumber < 0) {
 74:     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Window number cannot be negative");
 75:   }
 76:   if (windownumber >= vdraw->draw_max) {
 77:      /* allocate twice as many slots as needed */
 78:      int           draw_max = vdraw->draw_max;
 79:      PetscDraw     *tdraw = vdraw->draw;
 80:      PetscDrawLG   *drawlg = vdraw->drawlg;
 81:      PetscDrawAxis *drawaxis = vdraw->drawaxis;

 83:      vdraw->draw_max = 2*windownumber;
 84:      PetscMalloc(vdraw->draw_max*sizeof(PetscDraw),&vdraw->draw);
 85:      PetscMemzero(vdraw->draw,vdraw->draw_max*sizeof(PetscDraw));
 86:      PetscMalloc(vdraw->draw_max*sizeof(PetscDrawLG),&vdraw->drawlg);
 87:      PetscMemzero(vdraw->drawlg,vdraw->draw_max*sizeof(PetscDrawLG));
 88:      PetscMalloc(vdraw->draw_max*sizeof(PetscDrawAxis),&vdraw->drawaxis);
 89:      PetscMemzero(vdraw->drawaxis,vdraw->draw_max*sizeof(PetscDrawAxis));

 91:      PetscMemcpy(vdraw->draw,tdraw,draw_max*sizeof(PetscDraw));
 92:      PetscMemcpy(vdraw->drawlg,drawlg,draw_max*sizeof(PetscDrawLG));
 93:      PetscMemcpy(vdraw->drawaxis,drawaxis,draw_max*sizeof(PetscDrawAxis));

 95:      PetscFree(tdraw);
 96:      PetscFree(drawlg);
 97:      PetscFree(drawaxis);
 98:   }

100:   if (!vdraw->draw[windownumber]) {
101:     if (vdraw->draw[0]) {
102:       PetscDrawGetTitle(vdraw->draw[0],&title);
103:     } else title = 0;
104:     PetscDrawCreate(viewer->comm,vdraw->display,title,PETSC_DECIDE,PETSC_DECIDE,vdraw->w,vdraw->h,
105:                      &vdraw->draw[windownumber]);
106:     PetscDrawSetFromOptions(vdraw->draw[windownumber]);
107:   }
108:   *draw = vdraw->draw[windownumber];
109:   return(0);
110: }

112: /*@C
113:     PetscViewerDrawGetDrawLG - Returns PetscDrawLG object from PetscViewer object.
114:     This PetscDrawLG object may then be used to perform graphics using 
115:     PetscDrawLGXXX() commands.

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

119:     Input Parameter:
120: +   PetscViewer - the PetscViewer (created with PetscViewerDrawOpen())
121: -   windownumber - indicates which subwindow (usually 0)

123:     Ouput Parameter:
124: .   draw - the draw line graph object

126:     Level: intermediate

128:   Concepts: line graph^accessing context

130: .seealso: PetscViewerDrawGetDraw(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen()
131: @*/
132: int PetscViewerDrawGetDrawLG(PetscViewer viewer,int windownumber,PetscDrawLG *drawlg)
133: {
134:   int              ierr;
135:   PetscTruth       isdraw;
136:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;

141:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
142:   if (!isdraw) {
143:     SETERRQ(PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
144:   }
145:   if (windownumber < 0) {
146:     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Window number cannot be negative");
147:   }
148:   if (windownumber >= vdraw->draw_max || !vdraw->draw[windownumber]) {
149:     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"No window with that number created yet");
150:   }

152:   if (!vdraw->drawlg[windownumber]) {
153:     PetscDrawLGCreate(vdraw->draw[windownumber],1,&vdraw->drawlg[windownumber]);
154:     PetscLogObjectParent(viewer,vdraw->drawlg[windownumber]);
155:   }
156:   *drawlg = vdraw->drawlg[windownumber];
157:   return(0);
158: }

160: /*@C
161:     PetscViewerDrawGetDrawAxis - Returns PetscDrawAxis object from PetscViewer object.
162:     This PetscDrawAxis object may then be used to perform graphics using 
163:     PetscDrawAxisXXX() commands.

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

167:     Input Parameter:
168: +   viewer - the PetscViewer (created with PetscViewerDrawOpen()
169: -   windownumber - indicates which subwindow (usually 0)

171:     Ouput Parameter:
172: .   drawaxis - the draw axis object

174:     Level: advanced

176:   Concepts: line graph^accessing context

178: .seealso: PetscViewerDrawGetDraw(), PetscViewerDrawGetLG(), PetscViewerDrawOpen()
179: @*/
180: int PetscViewerDrawGetDrawAxis(PetscViewer viewer,int windownumber,PetscDrawAxis *drawaxis)
181: {
182:   int              ierr;
183:   PetscTruth       isdraw;
184:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;;

189:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
190:   if (!isdraw) {
191:     SETERRQ(PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
192:   }
193:   if (windownumber < 0) {
194:     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Window number cannot be negative");
195:   }
196:   if (windownumber >= vdraw->draw_max || !vdraw->draw[windownumber]) {
197:     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"No window with that number created yet");
198:   }

200:   if (!vdraw->drawaxis[windownumber]) {
201:     PetscDrawAxisCreate(vdraw->draw[windownumber],&vdraw->drawaxis[windownumber]);
202:     PetscLogObjectParent(viewer,vdraw->drawaxis[windownumber]);
203:   }
204:   *drawaxis = vdraw->drawaxis[windownumber];
205:   return(0);
206: }

208: int PetscViewerDrawSetInfo(PetscViewer v,const char display[],const char title[],int x,int y,int w,int h)
209: {
210:   int              ierr;
211:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)v->data;

214:   vdraw->h  = h;
215:   vdraw->w  = w;
216:   ierr      = PetscStrallocpy(display,&vdraw->display);
217:   ierr      = PetscDrawCreate(v->comm,display,title,x,y,w,h,&vdraw->draw[0]);
218:   ierr      = PetscDrawSetFromOptions(vdraw->draw[0]);
219:   PetscLogObjectParent(v,vdraw->draw[0]);
220:   return(0);
221: }

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

228:    Collective on MPI_Comm

230:    Input Parameters:
231: +  comm - communicator that will share window
232: .  display - the X display on which to open, or null for the local machine
233: .  title - the title to put in the title bar, or null for no title
234: .  x, y - the screen coordinates of the upper left corner of window, or use PETSC_DECIDE
235: -  w, h - window width and height in pixels, or may use PETSC_DECIDE or PETSC_DRAW_FULL_SIZE, PETSC_DRAW_HALF_SIZE,
236:           PETSC_DRAW_THIRD_SIZE, PETSC_DRAW_QUARTER_SIZE

238:    Output Parameters:
239: . viewer - the PetscViewer

241:    Format Options:
242: +  PETSC_VIEWER_DRAW_BASIC - displays with basic format
243: -  PETSC_VIEWER_DRAW_LG    - displays using a line graph

245:    Options Database Keys:
246:    PetscViewerDrawOpen() calls PetscDrawCreate(), so see the manual page for
247:    PetscDrawCreate() for runtime options, including
248: +  -draw_type x or null
249: .  -nox - Disables all x-windows output
250: .  -display <name> - Specifies name of machine for the X display
251: -  -draw_pause <pause> - Sets time (in seconds) that the
252:      program pauses after PetscDrawPause() has been called
253:      (0 is default, -1 implies until user input).

255:    Level: beginner

257:    Note for Fortran Programmers:
258:    Whenever indicating null character data in a Fortran code,
259:    PETSC_NULL_CHARACTER must be employed; using PETSC_NULL is not
260:    correct for character data!  Thus, PETSC_NULL_CHARACTER can be
261:    used for the display and title input parameters.

263:   Concepts: graphics^opening PetscViewer
264:   Concepts: drawing^opening PetscViewer


267: .seealso: PetscDrawCreate(), PetscViewerDestroy(), PetscViewerDrawGetDraw(), PetscViewerCreate(), PETSC_VIEWER_DRAW_,
268:           PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF
269: @*/
270: int PetscViewerDrawOpen(MPI_Comm comm,const char display[],const char title[],int x,int y,int w,int h,PetscViewer *viewer)
271: {

275:   PetscViewerCreate(comm,viewer);
276:   PetscViewerSetType(*viewer,PETSC_VIEWER_DRAW);
277:   PetscViewerDrawSetInfo(*viewer,display,title,x,y,w,h);
278:   return(0);
279: }

281: int PetscViewerGetSingleton_Draw(PetscViewer viewer,PetscViewer *sviewer)
282: {
283:   int              ierr,rank,i;
284:   PetscViewer_Draw *vdraw = (PetscViewer_Draw *)viewer->data,*vsdraw;

287:   if (vdraw->singleton_made) {
288:     SETERRQ(1,"Trying to get singleton without first restoring previous");
289:   }

291:   /* only processor zero can use the PetscViewer draw singleton */
292:   MPI_Comm_rank(viewer->comm,&rank);
293:   if (!rank) {
294:     ierr   = PetscViewerCreate(PETSC_COMM_SELF,sviewer);
295:     ierr   = PetscViewerSetType(*sviewer,PETSC_VIEWER_DRAW);
296:     vsdraw = (PetscViewer_Draw *)(*sviewer)->data;
297:     for (i=0; i<vdraw->draw_max; i++) {
298:       if (vdraw->draw[i]) {
299:         PetscDrawGetSingleton(vdraw->draw[i],&vsdraw->draw[i]);
300:       }
301:     }
302:   }
303:   vdraw->singleton_made = PETSC_TRUE;
304:   return(0);
305: }

307: int PetscViewerRestoreSingleton_Draw(PetscViewer viewer,PetscViewer *sviewer)
308: {
309:   int              ierr,rank,i;
310:   PetscViewer_Draw *vdraw = (PetscViewer_Draw *)viewer->data,*vsdraw;

313:   if (!vdraw->singleton_made) {
314:     SETERRQ(1,"Trying to restore a singleton that was not gotten");
315:   }
316:   MPI_Comm_rank(viewer->comm,&rank);
317:   if (!rank) {
318:     vsdraw = (PetscViewer_Draw *)(*sviewer)->data;
319:     for (i=0; i<vdraw->draw_max; i++) {
320:       if (vdraw->draw[i] && vsdraw->draw[i]) {
321:          PetscDrawRestoreSingleton(vdraw->draw[i],&vsdraw->draw[i]);
322:       }
323:     }
324:     PetscFree(vsdraw->drawaxis);
325:     PetscFree(vsdraw->drawlg);
326:     PetscFree(vsdraw->draw);
327:     PetscFree((*sviewer)->data);
328:     PetscLogObjectDestroy((PetscObject)*sviewer);
329:     PetscHeaderDestroy((PetscObject)*sviewer);
330:   }
331:   vdraw->singleton_made = PETSC_FALSE;
332:   return(0);
333: }

335: EXTERN_C_BEGIN
336: int PetscViewerCreate_Draw(PetscViewer viewer)
337: {
338:   int              i,ierr;
339:   PetscViewer_Draw *vdraw;

342:   ierr         = PetscNew(PetscViewer_Draw,&vdraw);
343:   viewer->data = (void*)vdraw;

345:   viewer->ops->flush            = PetscViewerFlush_Draw;
346:   viewer->ops->destroy          = PetscViewerDestroy_Draw;
347:   viewer->ops->getsingleton     = PetscViewerGetSingleton_Draw;
348:   viewer->ops->restoresingleton = PetscViewerRestoreSingleton_Draw;
349:   viewer->format                = PETSC_VIEWER_NOFORMAT;

351:   /* these are created on the fly if requested */
352:   vdraw->draw_max = 5;
353:   PetscMalloc(vdraw->draw_max*sizeof(PetscDraw),&vdraw->draw);
354:   PetscMemzero(vdraw->draw,vdraw->draw_max*sizeof(PetscDraw));
355:   PetscMalloc(vdraw->draw_max*sizeof(PetscDrawLG),&vdraw->drawlg);
356:   PetscMemzero(vdraw->drawlg,vdraw->draw_max*sizeof(PetscDrawLG));
357:   PetscMalloc(vdraw->draw_max*sizeof(PetscDrawAxis),&vdraw->drawaxis);
358:   PetscMemzero(vdraw->drawaxis,vdraw->draw_max*sizeof(PetscDrawAxis));
359:   for (i=0; i<vdraw->draw_max; i++) {
360:     vdraw->draw[i]     = 0;
361:     vdraw->drawlg[i]   = 0;
362:     vdraw->drawaxis[i] = 0;
363:   }
364:   vdraw->singleton_made = PETSC_FALSE;
365:   return(0);
366: }
367: EXTERN_C_END

369: /*@
370:     PetscViewerDrawClear - Clears a PetscDraw graphic associated with a PetscViewer.

372:     Not Collective

374:     Input Parameter:
375: .  viewer - the PetscViewer 

377:     Level: intermediate

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

381: @*/
382: int PetscViewerDrawClear(PetscViewer viewer)
383: {
384:   int              ierr,i;
385:   PetscTruth       isdraw;
386:   PetscViewer_Draw *vdraw;

389:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
390:   if (isdraw) {
391:     vdraw = (PetscViewer_Draw*)viewer->data;
392:     for (i=0; i<vdraw->draw_max; i++) {
393:       if (vdraw->draw[i]) {PetscDrawClear(vdraw->draw[i]);}
394:     }
395:   }
396:   return(0);
397: }

399: /* ---------------------------------------------------------------------*/
400: /*
401:     The variable Petsc_Viewer_Draw_keyval is used to indicate an MPI attribute that
402:   is attached to a communicator, in this case the attribute is a PetscViewer.
403: */
404: static int Petsc_Viewer_Draw_keyval = MPI_KEYVAL_INVALID;

406: /*@C
407:     PETSC_VIEWER_DRAW_ - Creates a window PetscViewer shared by all processors 
408:                      in a communicator.

410:      Collective on MPI_Comm

412:      Input Parameter:
413: .    comm - the MPI communicator to share the window PetscViewer

415:      Level: intermediate

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

422: .seealso: PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF, PetscViewerDrawOpen(), 
423: @*/
424: PetscViewer PETSC_VIEWER_DRAW_(MPI_Comm comm)
425: {
426:   int         ierr,flag;
427:   PetscViewer viewer;

430:   if (Petsc_Viewer_Draw_keyval == MPI_KEYVAL_INVALID) {
431:     MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Draw_keyval,0);
432:     if (ierr) {PetscError(__LINE__,"VIEWER_DRAW_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
433:   }
434:   MPI_Attr_get(comm,Petsc_Viewer_Draw_keyval,(void **)&viewer,&flag);
435:   if (ierr) {PetscError(__LINE__,"VIEWER_DRAW_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
436:   if (!flag) { /* PetscViewer not yet created */
437:     PetscViewerDrawOpen(comm,0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,&viewer);
438:     if (ierr) {PetscError(__LINE__,"VIEWER_DRAW_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
439:     PetscObjectRegisterDestroy((PetscObject)viewer);
440:     if (ierr) {PetscError(__LINE__,"VIEWER_STDOUT_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
441:     MPI_Attr_put(comm,Petsc_Viewer_Draw_keyval,(void*)viewer);
442:     if (ierr) {PetscError(__LINE__,"VIEWER_DRAW_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
443:   }
444:   PetscFunctionReturn(viewer);
445: }