Actual source code: drawv.c

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

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

 13:   if (vdraw->singleton_made) {
 14:     SETERRQ(PETSC_ERR_ORDER,"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:   }

 22:   PetscFree(vdraw->drawaxis);
 23:   PetscFree(vdraw->drawlg);
 24:   PetscFree(vdraw->draw);
 25:   PetscFree(vdraw);
 26:   return(0);
 27: }

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

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

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

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

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

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

 60:     Level: intermediate

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

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

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

 91:      vdraw->draw_max = 2*windownumber;
 92:      PetscMalloc(vdraw->draw_max*sizeof(PetscDraw),&vdraw->draw);
 93:      PetscMemzero(vdraw->draw,vdraw->draw_max*sizeof(PetscDraw));
 94:      PetscMalloc(vdraw->draw_max*sizeof(PetscDrawLG),&vdraw->drawlg);
 95:      PetscMemzero(vdraw->drawlg,vdraw->draw_max*sizeof(PetscDrawLG));
 96:      PetscMalloc(vdraw->draw_max*sizeof(PetscDrawAxis),&vdraw->drawaxis);
 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:      PetscFree(tdraw);
104:      PetscFree(drawlg);
105:      PetscFree(drawaxis);
106:   }

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

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

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

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

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

136:     Level: intermediate

138:   Concepts: line graph^accessing context

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

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

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

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

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

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

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

186:     Level: advanced

188:   Concepts: line graph^accessing context

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

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

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

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

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

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

244:    Collective on MPI_Comm

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

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

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

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

271:    Level: beginner

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

279:   Concepts: graphics^opening PetscViewer
280:   Concepts: drawing^opening PetscViewer


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

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

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

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

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

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

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

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

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

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

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

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

401:     Not Collective

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

406:     Level: intermediate

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

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

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

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

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

442:      Collective on MPI_Comm

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

447:      Level: intermediate

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

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

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