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: #undef __FUNCT__  
  7: int PetscViewerDestroy_Draw(PetscViewer v)
  8: {
  9:   int              ierr,i;
 10:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)v->data;

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

 28: #undef __FUNCT__  
 30: int PetscViewerFlush_Draw(PetscViewer v)
 31: {
 32:   int              ierr,i;
 33:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)v->data;

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

 42: #undef __FUNCT__  
 44: /*@C
 45:     PetscViewerDrawGetDraw - Returns PetscDraw object from PetscViewer object.
 46:     This PetscDraw object may then be used to perform graphics using 
 47:     PetscDrawXXX() commands.

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

 51:     Input Parameters:
 52: +  viewer - the PetscViewer (created with PetscViewerDrawOpen()
 53: -   windownumber - indicates which subwindow (usually 0)

 55:     Ouput Parameter:
 56: .   draw - the draw object

 58:     Level: intermediate

 60:    Concepts: drawing^accessing PetscDraw context from PetscViewer
 61:    Concepts: graphics

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

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

 89:      vdraw->draw_max = 2*windownumber;
 90:      PetscMalloc(vdraw->draw_max*sizeof(PetscDraw),&vdraw->draw);
 91:      PetscMemzero(vdraw->draw,vdraw->draw_max*sizeof(PetscDraw));
 92:      PetscMalloc(vdraw->draw_max*sizeof(PetscDrawLG),&vdraw->drawlg);
 93:      PetscMemzero(vdraw->drawlg,vdraw->draw_max*sizeof(PetscDrawLG));
 94:      PetscMalloc(vdraw->draw_max*sizeof(PetscDrawAxis),&vdraw->drawaxis);
 95:      PetscMemzero(vdraw->drawaxis,vdraw->draw_max*sizeof(PetscDrawAxis));

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

101:      PetscFree(tdraw);
102:      PetscFree(drawlg);
103:      PetscFree(drawaxis);
104:   }

106:   if (!vdraw->draw[windownumber]) {
107:     if (vdraw->draw[0]) {
108:       PetscDrawGetTitle(vdraw->draw[0],&title);
109:     } else title = 0;
110:     PetscDrawCreate(viewer->comm,vdraw->display,title,PETSC_DECIDE,PETSC_DECIDE,vdraw->w,vdraw->h,
111:                      &vdraw->draw[windownumber]);
112:     PetscDrawSetFromOptions(vdraw->draw[windownumber]);
113:   }
114:   *draw = vdraw->draw[windownumber];
115:   return(0);
116: }

118: #undef __FUNCT__  
120: /*@C
121:     PetscViewerDrawGetDrawLG - Returns PetscDrawLG object from PetscViewer object.
122:     This PetscDrawLG object may then be used to perform graphics using 
123:     PetscDrawLGXXX() commands.

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

127:     Input Parameter:
128: +   PetscViewer - the PetscViewer (created with PetscViewerDrawOpen())
129: -   windownumber - indicates which subwindow (usually 0)

131:     Ouput Parameter:
132: .   draw - the draw line graph object

134:     Level: intermediate

136:   Concepts: line graph^accessing context

138: .seealso: PetscViewerDrawGetDraw(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen()
139: @*/
140: int PetscViewerDrawGetDrawLG(PetscViewer viewer,int windownumber,PetscDrawLG *drawlg)
141: {
142:   int              ierr;
143:   PetscTruth       isdraw;
144:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;

149:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
150:   if (!isdraw) {
151:     SETERRQ(PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
152:   }
153:   if (windownumber < 0) {
154:     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Window number cannot be negative");
155:   }
156:   if (windownumber >= vdraw->draw_max || !vdraw->draw[windownumber]) {
157:     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"No window with that number created yet");
158:   }

160:   if (!vdraw->drawlg[windownumber]) {
161:     PetscDrawLGCreate(vdraw->draw[windownumber],1,&vdraw->drawlg[windownumber]);
162:     PetscLogObjectParent(viewer,vdraw->drawlg[windownumber]);
163:   }
164:   *drawlg = vdraw->drawlg[windownumber];
165:   return(0);
166: }

168: #undef __FUNCT__  
170: /*@C
171:     PetscViewerDrawGetDrawAxis - Returns PetscDrawAxis object from PetscViewer object.
172:     This PetscDrawAxis object may then be used to perform graphics using 
173:     PetscDrawAxisXXX() commands.

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

177:     Input Parameter:
178: +   viewer - the PetscViewer (created with PetscViewerDrawOpen()
179: -   windownumber - indicates which subwindow (usually 0)

181:     Ouput Parameter:
182: .   drawaxis - the draw axis object

184:     Level: advanced

186:   Concepts: line graph^accessing context

188: .seealso: PetscViewerDrawGetDraw(), PetscViewerDrawGetLG(), PetscViewerDrawOpen()
189: @*/
190: int PetscViewerDrawGetDrawAxis(PetscViewer viewer,int windownumber,PetscDrawAxis *drawaxis)
191: {
192:   int              ierr;
193:   PetscTruth       isdraw;
194:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;;

199:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
200:   if (!isdraw) {
201:     SETERRQ(PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
202:   }
203:   if (windownumber < 0) {
204:     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Window number cannot be negative");
205:   }
206:   if (windownumber >= vdraw->draw_max || !vdraw->draw[windownumber]) {
207:     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"No window with that number created yet");
208:   }

210:   if (!vdraw->drawaxis[windownumber]) {
211:     PetscDrawAxisCreate(vdraw->draw[windownumber],&vdraw->drawaxis[windownumber]);
212:     PetscLogObjectParent(viewer,vdraw->drawaxis[windownumber]);
213:   }
214:   *drawaxis = vdraw->drawaxis[windownumber];
215:   return(0);
216: }

218: #undef __FUNCT__  
220: int PetscViewerDrawSetInfo(PetscViewer v,const char display[],const char title[],int x,int y,int w,int h)
221: {
222:   int              ierr;
223:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)v->data;

226:   vdraw->h  = h;
227:   vdraw->w  = w;
228:   ierr      = PetscStrallocpy(display,&vdraw->display);
229:   ierr      = PetscDrawCreate(v->comm,display,title,x,y,w,h,&vdraw->draw[0]);
230:   ierr      = PetscDrawSetFromOptions(vdraw->draw[0]);
231:   PetscLogObjectParent(v,vdraw->draw[0]);
232:   return(0);
233: }

235: #undef __FUNCT__  
237: /*@C
238:    PetscViewerDrawOpen - Opens an X window for use as a PetscViewer. If you want to 
239:    do graphics in this window, you must call PetscViewerDrawGetDraw() and
240:    perform the graphics on the PetscDraw object.

242:    Collective on MPI_Comm

244:    Input Parameters:
245: +  comm - communicator that will share window
246: .  display - the X display on which to open, or null for the local machine
247: .  title - the title to put in the title bar, or null for no title
248: .  x, y - the screen coordinates of the upper left corner of window, or use PETSC_DECIDE
249: -  w, h - window width and height in pixels, or may use PETSC_DECIDE or PETSC_DRAW_FULL_SIZE, PETSC_DRAW_HALF_SIZE,
250:           PETSC_DRAW_THIRD_SIZE, PETSC_DRAW_QUARTER_SIZE

252:    Output Parameters:
253: . viewer - the PetscViewer

255:    Format Options:
256: +  PETSC_VIEWER_DRAW_BASIC - displays with basic format
257: -  PETSC_VIEWER_DRAW_LG    - displays using a line graph

259:    Options Database Keys:
260:    PetscViewerDrawOpen() calls PetscDrawCreate(), so see the manual page for
261:    PetscDrawCreate() for runtime options, including
262: +  -draw_type x or null
263: .  -nox - Disables all x-windows output
264: .  -display <name> - Specifies name of machine for the X display
265: -  -draw_pause <pause> - Sets time (in seconds) that the
266:      program pauses after PetscDrawPause() has been called
267:      (0 is default, -1 implies until user input).

269:    Level: beginner

271:    Note for Fortran Programmers:
272:    Whenever indicating null character data in a Fortran code,
273:    PETSC_NULL_CHARACTER must be employed; using PETSC_NULL is not
274:    correct for character data!  Thus, PETSC_NULL_CHARACTER can be
275:    used for the display and title input parameters.

277:   Concepts: graphics^opening PetscViewer
278:   Concepts: drawing^opening PetscViewer


281: .seealso: PetscDrawCreate(), PetscViewerDestroy(), PetscViewerDrawGetDraw(), PetscViewerCreate(), PETSC_VIEWER_DRAW_,
282:           PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF
283: @*/
284: int PetscViewerDrawOpen(MPI_Comm comm,const char display[],const char title[],int x,int y,int w,int h,PetscViewer *viewer)
285: {

289:   PetscViewerCreate(comm,viewer);
290:   PetscViewerSetType(*viewer,PETSC_VIEWER_DRAW);
291:   PetscViewerDrawSetInfo(*viewer,display,title,x,y,w,h);
292:   return(0);
293: }

295: #undef __FUNCT__  
297: int PetscViewerGetSingleton_Draw(PetscViewer viewer,PetscViewer *sviewer)
298: {
299:   int              ierr,rank,i;
300:   PetscViewer_Draw *vdraw = (PetscViewer_Draw *)viewer->data,*vsdraw;

303:   if (vdraw->singleton_made) {
304:     SETERRQ(1,"Trying to get singleton without first restoring previous");
305:   }

307:   /* only processor zero can use the PetscViewer draw singleton */
308:   MPI_Comm_rank(viewer->comm,&rank);
309:   if (!rank) {
310:     ierr   = PetscViewerCreate(PETSC_COMM_SELF,sviewer);
311:     ierr   = PetscViewerSetType(*sviewer,PETSC_VIEWER_DRAW);
312:     vsdraw = (PetscViewer_Draw *)(*sviewer)->data;
313:     for (i=0; i<vdraw->draw_max; i++) {
314:       if (vdraw->draw[i]) {
315:         PetscDrawGetSingleton(vdraw->draw[i],&vsdraw->draw[i]);
316:       }
317:     }
318:   }
319:   vdraw->singleton_made = PETSC_TRUE;
320:   return(0);
321: }

323: #undef __FUNCT__  
325: int PetscViewerRestoreSingleton_Draw(PetscViewer viewer,PetscViewer *sviewer)
326: {
327:   int              ierr,rank,i;
328:   PetscViewer_Draw *vdraw = (PetscViewer_Draw *)viewer->data,*vsdraw;

331:   if (!vdraw->singleton_made) {
332:     SETERRQ(1,"Trying to restore a singleton that was not gotten");
333:   }
334:   MPI_Comm_rank(viewer->comm,&rank);
335:   if (!rank) {
336:     vsdraw = (PetscViewer_Draw *)(*sviewer)->data;
337:     for (i=0; i<vdraw->draw_max; i++) {
338:       if (vdraw->draw[i] && vsdraw->draw[i]) {
339:          PetscDrawRestoreSingleton(vdraw->draw[i],&vsdraw->draw[i]);
340:       }
341:     }
342:     PetscFree(vsdraw->drawaxis);
343:     PetscFree(vsdraw->drawlg);
344:     PetscFree(vsdraw->draw);
345:     PetscFree((*sviewer)->data);
346:     PetscLogObjectDestroy((PetscObject)*sviewer);
347:     PetscHeaderDestroy((PetscObject)*sviewer);
348:   }
349:   vdraw->singleton_made = PETSC_FALSE;
350:   return(0);
351: }

353: EXTERN_C_BEGIN
354: #undef __FUNCT__  
356: int PetscViewerCreate_Draw(PetscViewer viewer)
357: {
358:   int              i,ierr;
359:   PetscViewer_Draw *vdraw;

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

365:   viewer->ops->flush            = PetscViewerFlush_Draw;
366:   viewer->ops->destroy          = PetscViewerDestroy_Draw;
367:   viewer->ops->getsingleton     = PetscViewerGetSingleton_Draw;
368:   viewer->ops->restoresingleton = PetscViewerRestoreSingleton_Draw;
369:   viewer->format                = PETSC_VIEWER_NOFORMAT;

371:   /* these are created on the fly if requested */
372:   vdraw->draw_max = 5;
373:   PetscMalloc(vdraw->draw_max*sizeof(PetscDraw),&vdraw->draw);
374:   PetscMemzero(vdraw->draw,vdraw->draw_max*sizeof(PetscDraw));
375:   PetscMalloc(vdraw->draw_max*sizeof(PetscDrawLG),&vdraw->drawlg);
376:   PetscMemzero(vdraw->drawlg,vdraw->draw_max*sizeof(PetscDrawLG));
377:   PetscMalloc(vdraw->draw_max*sizeof(PetscDrawAxis),&vdraw->drawaxis);
378:   PetscMemzero(vdraw->drawaxis,vdraw->draw_max*sizeof(PetscDrawAxis));
379:   for (i=0; i<vdraw->draw_max; i++) {
380:     vdraw->draw[i]     = 0;
381:     vdraw->drawlg[i]   = 0;
382:     vdraw->drawaxis[i] = 0;
383:   }
384:   vdraw->singleton_made = PETSC_FALSE;
385:   return(0);
386: }
387: EXTERN_C_END

389: #undef __FUNCT__  
391: /*@
392:     PetscViewerDrawClear - Clears a PetscDraw graphic associated with a PetscViewer.

394:     Not Collective

396:     Input Parameter:
397: .  viewer - the PetscViewer 

399:     Level: intermediate

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

403: @*/
404: int PetscViewerDrawClear(PetscViewer viewer)
405: {
406:   int              ierr,i;
407:   PetscTruth       isdraw;
408:   PetscViewer_Draw *vdraw;

411:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
412:   if (isdraw) {
413:     vdraw = (PetscViewer_Draw*)viewer->data;
414:     for (i=0; i<vdraw->draw_max; i++) {
415:       if (vdraw->draw[i]) {PetscDrawClear(vdraw->draw[i]);}
416:     }
417:   }
418:   return(0);
419: }

421: /* ---------------------------------------------------------------------*/
422: /*
423:     The variable Petsc_Viewer_Draw_keyval is used to indicate an MPI attribute that
424:   is attached to a communicator, in this case the attribute is a PetscViewer.
425: */
426: static int Petsc_Viewer_Draw_keyval = MPI_KEYVAL_INVALID;

428: /*MC
429:   PETSC_VIEWER_DRAW_WORLD  - same as PETSC_VIEWER_DRAW_(PETSC_COMM_WORLD)

431:   Level: intermediate
432: M*/

434: /*MC
435:   PETSC_VIEWER_DRAW_SELF  - same as PETSC_VIEWER_DRAW_(PETSC_COMM_SELF)

437:   Level: intermediate
438: M*/

440: #undef __FUNCT__  
442: /*@C
443:     PETSC_VIEWER_DRAW_ - Creates a window PetscViewer shared by all processors 
444:                      in a communicator.

446:      Collective on MPI_Comm

448:      Input Parameter:
449: .    comm - the MPI communicator to share the window PetscViewer

451:      Level: intermediate

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

458: .seealso: PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF, PetscViewerDrawOpen(), 
459: @*/
460: PetscViewer PETSC_VIEWER_DRAW_(MPI_Comm comm)
461: {
462:   int         ierr,flag;
463:   PetscViewer viewer;

466:   if (Petsc_Viewer_Draw_keyval == MPI_KEYVAL_INVALID) {
467:     MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Draw_keyval,0);
468:     if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
469:   }
470:   MPI_Attr_get(comm,Petsc_Viewer_Draw_keyval,(void **)&viewer,&flag);
471:   if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
472:   if (!flag) { /* PetscViewer not yet created */
473:     PetscViewerDrawOpen(comm,0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,&viewer);
474:     if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
475:     PetscObjectRegisterDestroy((PetscObject)viewer);
476:     if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_STDOUT_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
477:     MPI_Attr_put(comm,Petsc_Viewer_Draw_keyval,(void*)viewer);
478:     if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
479:   }
480:   PetscFunctionReturn(viewer);
481: }