Actual source code: drawv.c

  1: #define PETSC_DLL

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

  7: PetscErrorCode PetscViewerDestroy_Draw(PetscViewer v)
  8: {
  9:   PetscErrorCode   ierr;
 10:   int              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->drawaxis);
 24:   PetscFree(vdraw->drawlg);
 25:   PetscFree(vdraw->draw);
 26:   PetscFree(vdraw);
 27:   return(0);
 28: }

 32: PetscErrorCode PetscViewerFlush_Draw(PetscViewer v)
 33: {
 34:   PetscErrorCode   ierr;
 35:   int              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 PETSC_DLLEXPORT PetscViewerDrawGetDraw(PetscViewer viewer,int 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:   if (windownumber >= vdraw->draw_max) {
 86:      /* allocate twice as many slots as needed */
 87:      int           draw_max = vdraw->draw_max;
 88:      PetscDraw     *tdraw = vdraw->draw;
 89:      PetscDrawLG   *drawlg = vdraw->drawlg;
 90:      PetscDrawAxis *drawaxis = vdraw->drawaxis;

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

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

104:      PetscFree(tdraw);
105:      PetscFree(drawlg);
106:      PetscFree(drawaxis);
107:   }

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

123: /*@C
124:     PetscViewerDrawGetDrawLG - Returns PetscDrawLG object from PetscViewer object.
125:     This PetscDrawLG object may then be used to perform graphics using 
126:     PetscDrawLGXXX() commands.

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

130:     Input Parameter:
131: +   PetscViewer - the PetscViewer (created with PetscViewerDrawOpen())
132: -   windownumber - indicates which subwindow (usually 0)

134:     Ouput Parameter:
135: .   draw - the draw line graph object

137:     Level: intermediate

139:   Concepts: line graph^accessing context

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

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

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

173: /*@C
174:     PetscViewerDrawGetDrawAxis - Returns PetscDrawAxis object from PetscViewer object.
175:     This PetscDrawAxis object may then be used to perform graphics using 
176:     PetscDrawAxisXXX() commands.

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

180:     Input Parameter:
181: +   viewer - the PetscViewer (created with PetscViewerDrawOpen()
182: -   windownumber - indicates which subwindow (usually 0)

184:     Ouput Parameter:
185: .   drawaxis - the draw axis object

187:     Level: advanced

189:   Concepts: line graph^accessing context

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

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

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

223: PetscErrorCode PETSC_DLLEXPORT PetscViewerDrawSetInfo(PetscViewer v,const char display[],const char title[],int x,int y,int w,int h)
224: {
225:   PetscErrorCode   ierr;
226:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)v->data;

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

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

245:    Collective on MPI_Comm

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

255:    Output Parameters:
256: . viewer - the PetscViewer

258:    Format Options:
259: +  PETSC_VIEWER_DRAW_BASIC - displays with basic format
260: -  PETSC_VIEWER_DRAW_LG    - displays using a line graph

262:    Options Database Keys:
263:    PetscViewerDrawOpen() calls PetscDrawCreate(), so see the manual page for
264:    PetscDrawCreate() for runtime options, including
265: +  -draw_type x or null
266: .  -nox - Disables all x-windows output
267: .  -display <name> - Specifies name of machine for the X display
268: .  -geometry <x,y,w,h> - allows setting the window location and size
269: -  -draw_pause <pause> - Sets time (in seconds) that the
270:      program pauses after PetscDrawPause() has been called
271:      (0 is default, -1 implies until user input).

273:    Level: beginner

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

281:   Concepts: graphics^opening PetscViewer
282:   Concepts: drawing^opening PetscViewer


285: .seealso: PetscDrawCreate(), PetscViewerDestroy(), PetscViewerDrawGetDraw(), PetscViewerCreate(), PETSC_VIEWER_DRAW_,
286:           PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF
287: @*/
288: PetscErrorCode PETSC_DLLEXPORT PetscViewerDrawOpen(MPI_Comm comm,const char display[],const char title[],int x,int y,int w,int h,PetscViewer *viewer)
289: {

293:   PetscViewerCreate(comm,viewer);
294:   PetscViewerSetType(*viewer,PETSC_VIEWER_DRAW);
295:   PetscViewerDrawSetInfo(*viewer,display,title,x,y,w,h);
296:   return(0);
297: }

301: PetscErrorCode PetscViewerGetSingleton_Draw(PetscViewer viewer,PetscViewer *sviewer)
302: {
303:   PetscErrorCode   ierr;
304:   PetscMPIInt      rank;
305:   int              i;
306:   PetscViewer_Draw *vdraw = (PetscViewer_Draw *)viewer->data,*vsdraw;

309:   if (vdraw->singleton_made) {
310:     SETERRQ(PETSC_ERR_ORDER,"Trying to get singleton without first restoring previous");
311:   }

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

331: PetscErrorCode PetscViewerRestoreSingleton_Draw(PetscViewer viewer,PetscViewer *sviewer)
332: {
333:   PetscErrorCode   ierr;
334:   PetscMPIInt      rank;
335:   int              i;
336:   PetscViewer_Draw *vdraw = (PetscViewer_Draw *)viewer->data,*vsdraw;

339:   if (!vdraw->singleton_made) {
340:     SETERRQ(PETSC_ERR_ORDER,"Trying to restore a singleton that was not gotten");
341:   }
342:   MPI_Comm_rank(viewer->comm,&rank);
343:   if (!rank) {
344:     vsdraw = (PetscViewer_Draw *)(*sviewer)->data;
345:     for (i=0; i<vdraw->draw_max; i++) {
346:       if (vdraw->draw[i] && vsdraw->draw[i]) {
347:          PetscDrawRestoreSingleton(vdraw->draw[i],&vsdraw->draw[i]);
348:       }
349:     }
350:     PetscFree(vsdraw->drawaxis);
351:     PetscFree(vsdraw->drawlg);
352:     PetscFree(vsdraw->draw);
353:     PetscFree((*sviewer)->data);
354:     PetscHeaderDestroy(*sviewer);
355:   }
356:   vdraw->singleton_made = PETSC_FALSE;
357:   return(0);
358: }

363: PetscErrorCode PETSC_DLLEXPORT PetscViewerCreate_Draw(PetscViewer viewer)
364: {
365:   int              i;
366:   PetscErrorCode   ierr;
367:   PetscViewer_Draw *vdraw;

370:   PetscNew(PetscViewer_Draw,&vdraw);
371:   viewer->data = (void*)vdraw;

373:   viewer->ops->flush            = PetscViewerFlush_Draw;
374:   viewer->ops->destroy          = PetscViewerDestroy_Draw;
375:   viewer->ops->getsingleton     = PetscViewerGetSingleton_Draw;
376:   viewer->ops->restoresingleton = PetscViewerRestoreSingleton_Draw;
377:   viewer->format                = PETSC_VIEWER_NOFORMAT;

379:   /* these are created on the fly if requested */
380:   vdraw->draw_max = 5;
381:   PetscMalloc(vdraw->draw_max*sizeof(PetscDraw),&vdraw->draw);
382:   PetscMemzero(vdraw->draw,vdraw->draw_max*sizeof(PetscDraw));
383:   PetscMalloc(vdraw->draw_max*sizeof(PetscDrawLG),&vdraw->drawlg);
384:   PetscMemzero(vdraw->drawlg,vdraw->draw_max*sizeof(PetscDrawLG));
385:   PetscMalloc(vdraw->draw_max*sizeof(PetscDrawAxis),&vdraw->drawaxis);
386:   PetscMemzero(vdraw->drawaxis,vdraw->draw_max*sizeof(PetscDrawAxis));
387:   for (i=0; i<vdraw->draw_max; i++) {
388:     vdraw->draw[i]     = 0;
389:     vdraw->drawlg[i]   = 0;
390:     vdraw->drawaxis[i] = 0;
391:   }
392:   vdraw->singleton_made = PETSC_FALSE;
393:   return(0);
394: }

399: /*@
400:     PetscViewerDrawClear - Clears a PetscDraw graphic associated with a PetscViewer.

402:     Not Collective

404:     Input Parameter:
405: .  viewer - the PetscViewer 

407:     Level: intermediate

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

411: @*/
412: PetscErrorCode PETSC_DLLEXPORT PetscViewerDrawClear(PetscViewer viewer)
413: {
414:   PetscErrorCode   ierr;
415:   int              i;
416:   PetscTruth       isdraw;
417:   PetscViewer_Draw *vdraw;

420:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
421:   if (isdraw) {
422:     vdraw = (PetscViewer_Draw*)viewer->data;
423:     for (i=0; i<vdraw->draw_max; i++) {
424:       if (vdraw->draw[i]) {PetscDrawClear(vdraw->draw[i]);}
425:     }
426:   }
427:   return(0);
428: }

430: /* ---------------------------------------------------------------------*/
431: /*
432:     The variable Petsc_Viewer_Draw_keyval is used to indicate an MPI attribute that
433:   is attached to a communicator, in this case the attribute is a PetscViewer.
434: */
435: static int Petsc_Viewer_Draw_keyval = MPI_KEYVAL_INVALID;

439: /*@C
440:     PETSC_VIEWER_DRAW_ - Creates a window PetscViewer shared by all processors 
441:                      in a communicator.

443:      Collective on MPI_Comm

445:      Input Parameter:
446: .    comm - the MPI communicator to share the window PetscViewer

448:      Level: intermediate

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

455: .seealso: PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF, PetscViewerDrawOpen(), 
456: @*/
457: PetscViewer PETSC_DLLEXPORT PETSC_VIEWER_DRAW_(MPI_Comm comm)
458: {
460:   int            flag;
461:   PetscViewer    viewer;

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