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:   PetscInt         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:   PetscFree3(vdraw->draw,vdraw->drawlg,vdraw->drawaxis);
 25:   PetscFree(vdraw);
 26:   return(0);
 27: }

 31: PetscErrorCode PetscViewerFlush_Draw(PetscViewer v)
 32: {
 33:   PetscErrorCode   ierr;
 34:   PetscInt         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,PetscInt  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:   windownumber += vdraw->draw_base;
 85:   if (windownumber >= vdraw->draw_max) {
 86:      /* allocate twice as many slots as needed */
 87:      PetscInt      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:      PetscMalloc3(vdraw->draw_max,PetscDraw,&vdraw->draw,vdraw->draw_max,PetscDrawLG,&vdraw->drawlg,vdraw->draw_max,PetscDrawAxis,&vdraw->drawaxis);
 94:      PetscMemzero(vdraw->draw,vdraw->draw_max*sizeof(PetscDraw));
 95:      PetscMemzero(vdraw->drawlg,vdraw->draw_max*sizeof(PetscDrawLG));
 96:      PetscMemzero(vdraw->drawaxis,vdraw->draw_max*sizeof(PetscDrawAxis));

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

102:      PetscFree3(tdraw,drawlg,drawaxis);
103:   }

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

118: /*@C
119:     PetscViewerDrawBaseAdd - add to the base integer that is added to the windownumber passed to PetscViewerDrawGetDraw()

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

123:     Input Parameters:
124: +  viewer - the PetscViewer (created with PetscViewerDrawOpen())
125: -   windownumber - how much to add to the base

127:     Level: developer

129:    Concepts: drawing^accessing PetscDraw context from PetscViewer
130:    Concepts: graphics

132: .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), PetscViewerDrawBaseSet()
133: @*/
134: PetscErrorCode  PetscViewerDrawBaseAdd(PetscViewer viewer,PetscInt  windownumber)
135: {
136:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;
137:   PetscErrorCode   ierr;
138:   PetscTruth       isdraw;

142:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
143:   if (!isdraw) {
144:     SETERRQ(PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
145:   }
146:   if (windownumber + vdraw->draw_base < 0) {
147:     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Resulting base %D cannot be negative",windownumber+vdraw->draw_base);
148:   }
149:   vdraw->draw_base += windownumber;
150:   return(0);
151: }

155: /*@C
156:     PetscViewerDrawBaseSet - sets the base integer that is added to the windownumber passed to PetscViewerDrawGetDraw()

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

160:     Input Parameters:
161: +  viewer - the PetscViewer (created with PetscViewerDrawOpen())
162: -   windownumber - value to set the base

164:     Level: developer

166:    Concepts: drawing^accessing PetscDraw context from PetscViewer
167:    Concepts: graphics

169: .seealso: PetscViewerDrawGetLG(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen(), PetscViewerDrawGetDraw(), PetscViewerDrawBaseAdd()
170: @*/
171: PetscErrorCode  PetscViewerDrawBaseSet(PetscViewer viewer,PetscInt  windownumber)
172: {
173:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;
174:   PetscErrorCode   ierr;
175:   PetscTruth       isdraw;

179:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
180:   if (!isdraw) {
181:     SETERRQ(PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
182:   }
183:   if (windownumber < 0) {
184:     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Resulting base %D cannot be negative",windownumber);
185:   }
186:   vdraw->draw_base = windownumber;
187:   return(0);
188: }

192: /*@C
193:     PetscViewerDrawGetDrawLG - Returns PetscDrawLG object from PetscViewer object.
194:     This PetscDrawLG object may then be used to perform graphics using 
195:     PetscDrawLGXXX() commands.

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

199:     Input Parameter:
200: +   PetscViewer - the PetscViewer (created with PetscViewerDrawOpen())
201: -   windownumber - indicates which subwindow (usually 0)

203:     Ouput Parameter:
204: .   draw - the draw line graph object

206:     Level: intermediate

208:   Concepts: line graph^accessing context

210: .seealso: PetscViewerDrawGetDraw(), PetscViewerDrawGetAxis(), PetscViewerDrawOpen()
211: @*/
212: PetscErrorCode  PetscViewerDrawGetDrawLG(PetscViewer viewer,PetscInt  windownumber,PetscDrawLG *drawlg)
213: {
214:   PetscErrorCode   ierr;
215:   PetscTruth       isdraw;
216:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;

221:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
222:   if (!isdraw) {
223:     SETERRQ(PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
224:   }
225:   if (windownumber < 0) {
226:     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Window number cannot be negative");
227:   }

229:   if (windownumber+vdraw->draw_base >= vdraw->draw_max || !vdraw->draw[windownumber+vdraw->draw_base]) {
230:     PetscViewerDrawGetDraw(viewer,windownumber,PETSC_NULL);
231:   }
232:   if (!vdraw->drawlg[windownumber+vdraw->draw_base]) {
233:     PetscDrawLGCreate(vdraw->draw[windownumber+vdraw->draw_base],1,&vdraw->drawlg[windownumber+vdraw->draw_base]);
234:     PetscLogObjectParent(viewer,vdraw->drawlg[windownumber+vdraw->draw_base]);
235:   }
236:   *drawlg = vdraw->drawlg[windownumber+vdraw->draw_base];
237:   return(0);
238: }

242: /*@C
243:     PetscViewerDrawGetDrawAxis - Returns PetscDrawAxis object from PetscViewer object.
244:     This PetscDrawAxis object may then be used to perform graphics using 
245:     PetscDrawAxisXXX() commands.

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

249:     Input Parameter:
250: +   viewer - the PetscViewer (created with PetscViewerDrawOpen()
251: -   windownumber - indicates which subwindow (usually 0)

253:     Ouput Parameter:
254: .   drawaxis - the draw axis object

256:     Level: advanced

258:   Concepts: line graph^accessing context

260: .seealso: PetscViewerDrawGetDraw(), PetscViewerDrawGetLG(), PetscViewerDrawOpen()
261: @*/
262: PetscErrorCode  PetscViewerDrawGetDrawAxis(PetscViewer viewer,PetscInt  windownumber,PetscDrawAxis *drawaxis)
263: {
264:   PetscErrorCode   ierr;
265:   PetscTruth       isdraw;
266:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)viewer->data;;

271:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
272:   if (!isdraw) {
273:     SETERRQ(PETSC_ERR_ARG_WRONG,"Must be draw type PetscViewer");
274:   }
275:   if (windownumber < 0) {
276:     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Window number cannot be negative");
277:   }

279:   if (windownumber+vdraw->draw_base >= vdraw->draw_max || !vdraw->draw[windownumber+vdraw->draw_base]) {
280:     PetscViewerDrawGetDraw(viewer,windownumber,PETSC_NULL);
281:   }
282:   if (!vdraw->drawaxis[windownumber+vdraw->draw_base]) {
283:     PetscDrawAxisCreate(vdraw->draw[windownumber+vdraw->draw_base],&vdraw->drawaxis[windownumber+vdraw->draw_base]);
284:     PetscLogObjectParent(viewer,vdraw->drawaxis[windownumber+vdraw->draw_base]);
285:   }
286:   *drawaxis = vdraw->drawaxis[windownumber+vdraw->draw_base];
287:   return(0);
288: }

292: PetscErrorCode  PetscViewerDrawSetInfo(PetscViewer v,const char display[],const char title[],int x,int y,int w,int h)
293: {
294:   PetscErrorCode   ierr;
295:   PetscViewer_Draw *vdraw = (PetscViewer_Draw*)v->data;

298:   vdraw->h  = h;
299:   vdraw->w  = w;
300:   PetscStrallocpy(display,&vdraw->display);
301:   /*  PetscDrawCreate(v->comm,display,title,x,y,w,h,&vdraw->draw[0]);
302:       PetscDrawSetFromOptions(vdraw->draw[0]);*/
303:   return(0);
304: }

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

313:    Collective on MPI_Comm

315:    Input Parameters:
316: +  comm - communicator that will share window
317: .  display - the X display on which to open, or null for the local machine
318: .  title - the title to put in the title bar, or null for no title
319: .  x, y - the screen coordinates of the upper left corner of window, or use PETSC_DECIDE
320: -  w, h - window width and height in pixels, or may use PETSC_DECIDE or PETSC_DRAW_FULL_SIZE, PETSC_DRAW_HALF_SIZE,
321:           PETSC_DRAW_THIRD_SIZE, PETSC_DRAW_QUARTER_SIZE

323:    Output Parameters:
324: . viewer - the PetscViewer

326:    Format Options:
327: +  PETSC_VIEWER_DRAW_BASIC - displays with basic format
328: -  PETSC_VIEWER_DRAW_LG    - displays using a line graph

330:    Options Database Keys:
331:    PetscViewerDrawOpen() calls PetscDrawCreate(), so see the manual page for
332:    PetscDrawCreate() for runtime options, including
333: +  -draw_type x or null
334: .  -nox - Disables all x-windows output
335: .  -display <name> - Specifies name of machine for the X display
336: .  -geometry <x,y,w,h> - allows setting the window location and size
337: -  -draw_pause <pause> - Sets time (in seconds) that the
338:      program pauses after PetscDrawPause() has been called
339:      (0 is default, -1 implies until user input).

341:    Level: beginner

343:    Note for Fortran Programmers:
344:    Whenever indicating null character data in a Fortran code,
345:    PETSC_NULL_CHARACTER must be employed; using PETSC_NULL is not
346:    correct for character data!  Thus, PETSC_NULL_CHARACTER can be
347:    used for the display and title input parameters.

349:   Concepts: graphics^opening PetscViewer
350:   Concepts: drawing^opening PetscViewer


353: .seealso: PetscDrawCreate(), PetscViewerDestroy(), PetscViewerDrawGetDraw(), PetscViewerCreate(), PETSC_VIEWER_DRAW_,
354:           PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF
355: @*/
356: PetscErrorCode  PetscViewerDrawOpen(MPI_Comm comm,const char display[],const char title[],int x,int y,int w,int h,PetscViewer *viewer)
357: {

361:   PetscViewerCreate(comm,viewer);
362:   PetscViewerSetType(*viewer,PETSC_VIEWER_DRAW);
363:   PetscViewerDrawSetInfo(*viewer,display,title,x,y,w,h);
364:   return(0);
365: }

369: PetscErrorCode PetscViewerGetSingleton_Draw(PetscViewer viewer,PetscViewer *sviewer)
370: {
371:   PetscErrorCode   ierr;
372:   PetscMPIInt      rank;
373:   PetscInt         i;
374:   PetscViewer_Draw *vdraw = (PetscViewer_Draw *)viewer->data,*vsdraw;

377:   if (vdraw->singleton_made) {
378:     SETERRQ(PETSC_ERR_ORDER,"Trying to get singleton without first restoring previous");
379:   }

381:   /* only processor zero can use the PetscViewer draw singleton */
382:   MPI_Comm_rank(viewer->comm,&rank);
383:   if (!rank) {
384:     PetscViewerCreate(PETSC_COMM_SELF,sviewer);
385:     PetscViewerSetType(*sviewer,PETSC_VIEWER_DRAW);
386:     vsdraw = (PetscViewer_Draw *)(*sviewer)->data;
387:     for (i=0; i<vdraw->draw_max; i++) {
388:       if (vdraw->draw[i]) {
389:         PetscDrawGetSingleton(vdraw->draw[i],&vsdraw->draw[i]);
390:       }
391:     }
392:   }
393:   vdraw->singleton_made = PETSC_TRUE;
394:   return(0);
395: }

399: PetscErrorCode PetscViewerRestoreSingleton_Draw(PetscViewer viewer,PetscViewer *sviewer)
400: {
401:   PetscErrorCode   ierr;
402:   PetscMPIInt      rank;
403:   PetscInt         i;
404:   PetscViewer_Draw *vdraw = (PetscViewer_Draw *)viewer->data,*vsdraw;

407:   if (!vdraw->singleton_made) {
408:     SETERRQ(PETSC_ERR_ORDER,"Trying to restore a singleton that was not gotten");
409:   }
410:   MPI_Comm_rank(viewer->comm,&rank);
411:   if (!rank) {
412:     vsdraw = (PetscViewer_Draw *)(*sviewer)->data;
413:     for (i=0; i<vdraw->draw_max; i++) {
414:       if (vdraw->draw[i] && vsdraw->draw[i]) {
415:          PetscDrawRestoreSingleton(vdraw->draw[i],&vsdraw->draw[i]);
416:       }
417:     }
418:     PetscFree3(vsdraw->draw,vsdraw->drawlg,vsdraw->drawaxis);
419:     PetscFree((*sviewer)->data);
420:     PetscHeaderDestroy(*sviewer);
421:   }
422:   vdraw->singleton_made = PETSC_FALSE;
423:   return(0);
424: }

429: PetscErrorCode  PetscViewerCreate_Draw(PetscViewer viewer)
430: {
431:   PetscInt         i;
432:   PetscErrorCode   ierr;
433:   PetscViewer_Draw *vdraw;

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

439:   viewer->ops->flush            = PetscViewerFlush_Draw;
440:   viewer->ops->destroy          = PetscViewerDestroy_Draw;
441:   viewer->ops->getsingleton     = PetscViewerGetSingleton_Draw;
442:   viewer->ops->restoresingleton = PetscViewerRestoreSingleton_Draw;
443:   viewer->format                = PETSC_VIEWER_NOFORMAT;

445:   /* these are created on the fly if requested */
446:   vdraw->draw_max  = 5;
447:   vdraw->draw_base = 0;
448:   PetscMalloc3(vdraw->draw_max,PetscDraw,&vdraw->draw,vdraw->draw_max,PetscDrawLG,&vdraw->drawlg,vdraw->draw_max,PetscDrawAxis,&vdraw->drawaxis);
449:   PetscMemzero(vdraw->draw,vdraw->draw_max*sizeof(PetscDraw));
450:   PetscMemzero(vdraw->drawlg,vdraw->draw_max*sizeof(PetscDrawLG));
451:   PetscMemzero(vdraw->drawaxis,vdraw->draw_max*sizeof(PetscDrawAxis));
452:   for (i=0; i<vdraw->draw_max; i++) {
453:     vdraw->draw[i]     = 0;
454:     vdraw->drawlg[i]   = 0;
455:     vdraw->drawaxis[i] = 0;
456:   }
457:   vdraw->singleton_made = PETSC_FALSE;
458:   return(0);
459: }

464: /*@
465:     PetscViewerDrawClear - Clears a PetscDraw graphic associated with a PetscViewer.

467:     Not Collective

469:     Input Parameter:
470: .  viewer - the PetscViewer 

472:     Level: intermediate

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

476: @*/
477: PetscErrorCode  PetscViewerDrawClear(PetscViewer viewer)
478: {
479:   PetscErrorCode   ierr;
480:   PetscInt         i;
481:   PetscTruth       isdraw;
482:   PetscViewer_Draw *vdraw;

485:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
486:   if (isdraw) {
487:     vdraw = (PetscViewer_Draw*)viewer->data;
488:     for (i=0; i<vdraw->draw_max; i++) {
489:       if (vdraw->draw[i]) {PetscDrawClear(vdraw->draw[i]);}
490:     }
491:   }
492:   return(0);
493: }

495: /* ---------------------------------------------------------------------*/
496: /*
497:     The variable Petsc_Viewer_Draw_keyval is used to indicate an MPI attribute that
498:   is attached to a communicator, in this case the attribute is a PetscViewer.
499: */
500: static PetscMPIInt Petsc_Viewer_Draw_keyval = MPI_KEYVAL_INVALID;

504: /*@C
505:     PETSC_VIEWER_DRAW_ - Creates a window PetscViewer shared by all processors 
506:                      in a communicator.

508:      Collective on MPI_Comm

510:      Input Parameter:
511: .    comm - the MPI communicator to share the window PetscViewer

513:      Level: intermediate

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

520: .seealso: PETSC_VIEWER_DRAW_WORLD, PETSC_VIEWER_DRAW_SELF, PetscViewerDrawOpen(), 
521: @*/
522: PetscViewer  PETSC_VIEWER_DRAW_(MPI_Comm comm)
523: {
525:   PetscMPIInt    flag;
526:   PetscViewer    viewer;

529:   if (Petsc_Viewer_Draw_keyval == MPI_KEYVAL_INVALID) {
530:     MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Draw_keyval,0);
531:     if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,1,1," ");return(0);}
532:   }
533:   MPI_Attr_get(comm,Petsc_Viewer_Draw_keyval,(void **)&viewer,&flag);
534:   if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,1,1," ");return(0);}
535:   if (!flag) { /* PetscViewer not yet created */
536:     PetscViewerDrawOpen(comm,0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,&viewer);
537:     if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,1,1," ");return(0);}
538:     PetscObjectRegisterDestroy((PetscObject)viewer);
539:     if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,1,1," ");return(0);}
540:     MPI_Attr_put(comm,Petsc_Viewer_Draw_keyval,(void*)viewer);
541:     if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_DRAW_",__FILE__,__SDIR__,1,1," ");return(0);}
542:   }
543:   PetscFunctionReturn(viewer);
544: }