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:   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->display);
 24:   PetscFree(vdraw->drawaxis);
 25:   PetscFree(vdraw->drawlg);
 26:   PetscFree(vdraw->draw);
 27:   PetscFree(vdraw);
 28:   return(0);
 29: }

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

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

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

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

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

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

 62:     Level: intermediate

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

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

 79:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
 80:   if (!isdraw) {
 81:     SETERRQ(PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
 82:   }
 83:   if (windownumber < 0) {
 84:     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Window number cannot be negative");
 85:   }
 86:   if (windownumber >= vdraw->draw_max) {
 87:      /* allocate twice as many slots as needed */
 88:      int           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:      PetscMalloc(vdraw->draw_max*sizeof(PetscDraw),&vdraw->draw);
 95:      PetscMemzero(vdraw->draw,vdraw->draw_max*sizeof(PetscDraw));
 96:      PetscMalloc(vdraw->draw_max*sizeof(PetscDrawLG),&vdraw->drawlg);
 97:      PetscMemzero(vdraw->drawlg,vdraw->draw_max*sizeof(PetscDrawLG));
 98:      PetscMalloc(vdraw->draw_max*sizeof(PetscDrawAxis),&vdraw->drawaxis);
 99:      PetscMemzero(vdraw->drawaxis,vdraw->draw_max*sizeof(PetscDrawAxis));

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

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

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

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

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

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

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

138:     Level: intermediate

140:   Concepts: line graph^accessing context

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

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

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

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

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

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

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

188:     Level: advanced

190:   Concepts: line graph^accessing context

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

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

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

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

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

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

246:    Collective on MPI_Comm

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

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

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

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

274:    Level: beginner

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

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


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

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

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

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

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

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

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

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

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

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

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

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

403:     Not Collective

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

408:     Level: intermediate

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

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

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

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

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

444:      Collective on MPI_Comm

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

449:      Level: intermediate

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

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

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