1 
2 #include <petscviewer.h>
3 #include <../src/sys/classes/draw/utils/lgimpl.h>  /*I   "petscdraw.h"  I*/
4 PetscClassId PETSC_DRAWLG_CLASSID = 0;
5 
6 /*@
7    PetscDrawLGGetAxis - Gets the axis context associated with a line graph.
8    This is useful if one wants to change some axis property, such as
9    labels, color, etc. The axis context should not be destroyed by the
10    application code.
11 
12    Not Collective, if PetscDrawLG is parallel then PetscDrawAxis is parallel
13 
14    Input Parameter:
15 .  lg - the line graph context
16 
17    Output Parameter:
18 .  axis - the axis context
19 
20    Level: advanced
21 
22 .seealso: PetscDrawLGCreate(), PetscDrawAxis
23 
24 @*/
PetscDrawLGGetAxis(PetscDrawLG lg,PetscDrawAxis * axis)25 PetscErrorCode  PetscDrawLGGetAxis(PetscDrawLG lg,PetscDrawAxis *axis)
26 {
27   PetscFunctionBegin;
28   PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1);
29   PetscValidPointer(axis,2);
30   *axis = lg->axis;
31   PetscFunctionReturn(0);
32 }
33 
34 /*@
35    PetscDrawLGGetDraw - Gets the draw context associated with a line graph.
36 
37    Not Collective, if PetscDrawLG is parallel then PetscDraw is parallel
38 
39    Input Parameter:
40 .  lg - the line graph context
41 
42    Output Parameter:
43 .  draw - the draw context
44 
45    Level: intermediate
46 
47 .seealso: PetscDrawLGCreate(), PetscDraw
48 @*/
PetscDrawLGGetDraw(PetscDrawLG lg,PetscDraw * draw)49 PetscErrorCode  PetscDrawLGGetDraw(PetscDrawLG lg,PetscDraw *draw)
50 {
51   PetscFunctionBegin;
52   PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1);
53   PetscValidPointer(draw,2);
54   *draw = lg->win;
55   PetscFunctionReturn(0);
56 }
57 
58 
59 /*@
60    PetscDrawLGSPDraw - Redraws a line graph.
61 
62    Collective on PetscDrawLG
63 
64    Input Parameter:
65 .  lg - the line graph context
66 
67    Level: intermediate
68 
69 .seealso: PetscDrawLGDraw(), PetscDrawSPDraw()
70 
71    Developer Notes:
72     This code cheats and uses the fact that the LG and SP structs are the same
73 
74 @*/
PetscDrawLGSPDraw(PetscDrawLG lg,PetscDrawSP spin)75 PetscErrorCode  PetscDrawLGSPDraw(PetscDrawLG lg,PetscDrawSP spin)
76 {
77   PetscDrawLG    sp = (PetscDrawLG)spin;
78   PetscReal      xmin,xmax,ymin,ymax;
79   PetscErrorCode ierr;
80   PetscBool      isnull;
81   PetscMPIInt    rank;
82   PetscDraw      draw;
83 
84   PetscFunctionBegin;
85   PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1);
86   PetscValidHeaderSpecific(sp,PETSC_DRAWSP_CLASSID,2);
87   ierr = PetscDrawIsNull(lg->win,&isnull);CHKERRQ(ierr);
88   if (isnull) PetscFunctionReturn(0);
89   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)lg),&rank);CHKERRQ(ierr);
90 
91   draw = lg->win;
92   ierr = PetscDrawCheckResizedWindow(draw);CHKERRQ(ierr);
93   ierr = PetscDrawClear(draw);CHKERRQ(ierr);
94 
95   xmin = PetscMin(lg->xmin,sp->xmin); ymin = PetscMin(lg->ymin,sp->ymin);
96   xmax = PetscMax(lg->xmax,sp->xmax); ymax = PetscMax(lg->ymax,sp->ymax);
97   ierr = PetscDrawAxisSetLimits(lg->axis,xmin,xmax,ymin,ymax);CHKERRQ(ierr);
98   ierr = PetscDrawAxisDraw(lg->axis);CHKERRQ(ierr);
99 
100   ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
101   if (!rank) {
102     int i,j,dim,nopts;
103     dim   = lg->dim;
104     nopts = lg->nopts;
105     for (i=0; i<dim; i++) {
106       for (j=1; j<nopts; j++) {
107         ierr = PetscDrawLine(draw,lg->x[(j-1)*dim+i],lg->y[(j-1)*dim+i],lg->x[j*dim+i],lg->y[j*dim+i],PETSC_DRAW_BLACK+i);CHKERRQ(ierr);
108         if (lg->use_markers) {
109           ierr = PetscDrawMarker(draw,lg->x[j*dim+i],lg->y[j*dim+i],PETSC_DRAW_RED);CHKERRQ(ierr);
110         }
111       }
112     }
113     dim   = sp->dim;
114     nopts = sp->nopts;
115     for (i=0; i<dim; i++) {
116       for (j=0; j<nopts; j++) {
117         ierr = PetscDrawMarker(draw,sp->x[j*dim+i],sp->y[j*dim+i],PETSC_DRAW_RED);CHKERRQ(ierr);
118       }
119     }
120   }
121   ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
122 
123   ierr = PetscDrawFlush(draw);CHKERRQ(ierr);
124   ierr = PetscDrawPause(draw);CHKERRQ(ierr);
125   PetscFunctionReturn(0);
126 }
127 
128 
129 /*@
130     PetscDrawLGCreate - Creates a line graph data structure.
131 
132     Collective on PetscDraw
133 
134     Input Parameters:
135 +   draw - the window where the graph will be made.
136 -   dim - the number of curves which will be drawn
137 
138     Output Parameters:
139 .   outlg - the line graph context
140 
141     Level: intermediate
142 
143     Notes:
144     The MPI communicator that owns the PetscDraw owns this PetscDrawLG, but the calls to set options and add points are ignored on all processes except the
145            zeroth MPI process in the communicator. All MPI processes in the communicator must call PetscDrawLGDraw() to display the updated graph.
146 
147 .seealso:  PetscDrawLGDestroy(), PetscDrawLGAddPoint(), PetscDrawLGAddCommonPoint(), PetscDrawLGAddPoints(), PetscDrawLGDraw(), PetscDrawLGSave(),
148            PetscDrawLGView(), PetscDrawLGReset(), PetscDrawLGSetDimension(), PetscDrawLGGetDimension(), PetscDrawLGSetLegend(), PetscDrawLGGetAxis(),
149            PetscDrawLGGetDraw(), PetscDrawLGSetUseMarkers(), PetscDrawLGSetLimits(), PetscDrawLGSetColors(), PetscDrawLGSetOptionsPrefix(), PetscDrawLGSetFromOptions()
150 @*/
PetscDrawLGCreate(PetscDraw draw,PetscInt dim,PetscDrawLG * outlg)151 PetscErrorCode  PetscDrawLGCreate(PetscDraw draw,PetscInt dim,PetscDrawLG *outlg)
152 {
153   PetscDrawLG    lg;
154   PetscErrorCode ierr;
155 
156   PetscFunctionBegin;
157   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
158   PetscValidLogicalCollectiveInt(draw,dim,2);
159   PetscValidPointer(outlg,3);
160 
161   ierr = PetscHeaderCreate(lg,PETSC_DRAWLG_CLASSID,"DrawLG","Line Graph","Draw",PetscObjectComm((PetscObject)draw),PetscDrawLGDestroy,NULL);CHKERRQ(ierr);
162   ierr = PetscLogObjectParent((PetscObject)draw,(PetscObject)lg);CHKERRQ(ierr);
163   ierr = PetscDrawLGSetOptionsPrefix(lg,((PetscObject)draw)->prefix);CHKERRQ(ierr);
164 
165   ierr = PetscObjectReference((PetscObject)draw);CHKERRQ(ierr);
166   lg->win = draw;
167 
168   lg->view    = NULL;
169   lg->destroy = NULL;
170   lg->nopts   = 0;
171   lg->dim     = dim;
172   lg->xmin    = 1.e20;
173   lg->ymin    = 1.e20;
174   lg->xmax    = -1.e20;
175   lg->ymax    = -1.e20;
176 
177   ierr = PetscMalloc2(dim*CHUNCKSIZE,&lg->x,dim*CHUNCKSIZE,&lg->y);CHKERRQ(ierr);
178   ierr = PetscLogObjectMemory((PetscObject)lg,2*dim*CHUNCKSIZE*sizeof(PetscReal));CHKERRQ(ierr);
179 
180   lg->len         = dim*CHUNCKSIZE;
181   lg->loc         = 0;
182   lg->use_markers = PETSC_FALSE;
183 
184   ierr = PetscDrawAxisCreate(draw,&lg->axis);CHKERRQ(ierr);
185   ierr = PetscLogObjectParent((PetscObject)lg,(PetscObject)lg->axis);CHKERRQ(ierr);
186 
187   *outlg = lg;
188   PetscFunctionReturn(0);
189 }
190 
191 /*@
192    PetscDrawLGSetColors - Sets the color of each line graph drawn
193 
194    Logically Collective on PetscDrawLG
195 
196    Input Parameter:
197 +  lg - the line graph context.
198 -  colors - the colors
199 
200    Level: intermediate
201 
202 .seealso: PetscDrawLGCreate()
203 
204 @*/
PetscDrawLGSetColors(PetscDrawLG lg,const int colors[])205 PetscErrorCode  PetscDrawLGSetColors(PetscDrawLG lg,const int colors[])
206 {
207   PetscErrorCode ierr;
208 
209   PetscFunctionBegin;
210   PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1);
211   if (lg->dim) PetscValidIntPointer(colors,2);
212 
213   ierr = PetscFree(lg->colors);CHKERRQ(ierr);
214   ierr = PetscMalloc1(lg->dim,&lg->colors);CHKERRQ(ierr);
215   ierr = PetscArraycpy(lg->colors,colors,lg->dim);CHKERRQ(ierr);
216   PetscFunctionReturn(0);
217 }
218 
219 /*@C
220    PetscDrawLGSetLegend - sets the names of each curve plotted
221 
222    Logically Collective on PetscDrawLG
223 
224    Input Parameter:
225 +  lg - the line graph context.
226 -  names - the names for each curve
227 
228    Level: intermediate
229 
230    Notes:
231     Call PetscDrawLGGetAxis() and then change properties of the PetscDrawAxis for detailed control of the plot
232 
233 .seealso: PetscDrawLGGetAxis(), PetscDrawAxis, PetscDrawAxisSetColors(), PetscDrawAxisSetLabels(), PetscDrawAxisSetHoldLimits()
234 
235 @*/
PetscDrawLGSetLegend(PetscDrawLG lg,const char * const * names)236 PetscErrorCode  PetscDrawLGSetLegend(PetscDrawLG lg,const char *const *names)
237 {
238   PetscErrorCode ierr;
239   PetscInt       i;
240 
241   PetscFunctionBegin;
242   PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1);
243   if (names) PetscValidPointer(names,2);
244 
245   if (lg->legend) {
246     for (i=0; i<lg->dim; i++) {
247       ierr = PetscFree(lg->legend[i]);CHKERRQ(ierr);
248     }
249     ierr = PetscFree(lg->legend);CHKERRQ(ierr);
250   }
251   if (names) {
252     ierr = PetscMalloc1(lg->dim,&lg->legend);CHKERRQ(ierr);
253     for (i=0; i<lg->dim; i++) {
254       ierr = PetscStrallocpy(names[i],&lg->legend[i]);CHKERRQ(ierr);
255     }
256   }
257   PetscFunctionReturn(0);
258 }
259 
260 /*@
261    PetscDrawLGGetDimension - Change the number of lines that are to be drawn.
262 
263    Not Collective
264 
265    Input Parameter:
266 .  lg - the line graph context.
267 
268    Output Parameter:
269 .  dim - the number of curves.
270 
271    Level: intermediate
272 
273 .seealso: PetscDrawLGCreate(), PetscDrawLGSetDimension()
274 
275 @*/
PetscDrawLGGetDimension(PetscDrawLG lg,PetscInt * dim)276 PetscErrorCode  PetscDrawLGGetDimension(PetscDrawLG lg,PetscInt *dim)
277 {
278   PetscFunctionBegin;
279   PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1);
280   PetscValidIntPointer(dim,2);
281   *dim = lg->dim;
282   PetscFunctionReturn(0);
283 }
284 
285 /*@
286    PetscDrawLGSetDimension - Change the number of lines that are to be drawn.
287 
288    Logically Collective on PetscDrawLG
289 
290    Input Parameter:
291 +  lg - the line graph context.
292 -  dim - the number of curves.
293 
294    Level: intermediate
295 
296 .seealso: PetscDrawLGCreate(), PetscDrawLGGetDimension()
297 @*/
PetscDrawLGSetDimension(PetscDrawLG lg,PetscInt dim)298 PetscErrorCode  PetscDrawLGSetDimension(PetscDrawLG lg,PetscInt dim)
299 {
300   PetscErrorCode ierr;
301   PetscInt       i;
302 
303   PetscFunctionBegin;
304   PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1);
305   PetscValidLogicalCollectiveInt(lg,dim,2);
306   if (lg->dim == dim) PetscFunctionReturn(0);
307 
308   ierr = PetscFree2(lg->x,lg->y);CHKERRQ(ierr);
309   if (lg->legend) {
310     for (i=0; i<lg->dim; i++) {
311       ierr = PetscFree(lg->legend[i]);CHKERRQ(ierr);
312     }
313     ierr = PetscFree(lg->legend);CHKERRQ(ierr);
314   }
315   ierr    = PetscFree(lg->colors);CHKERRQ(ierr);
316   lg->dim = dim;
317   ierr    = PetscMalloc2(dim*CHUNCKSIZE,&lg->x,dim*CHUNCKSIZE,&lg->y);CHKERRQ(ierr);
318   ierr    = PetscLogObjectMemory((PetscObject)lg,2*dim*CHUNCKSIZE*sizeof(PetscReal));CHKERRQ(ierr);
319   lg->len = dim*CHUNCKSIZE;
320   PetscFunctionReturn(0);
321 }
322 
323 
324 /*@
325    PetscDrawLGSetLimits - Sets the axis limits for a line graph. If more
326    points are added after this call, the limits will be adjusted to
327    include those additional points.
328 
329    Logically Collective on PetscDrawLG
330 
331    Input Parameters:
332 +  xlg - the line graph context
333 -  x_min,x_max,y_min,y_max - the limits
334 
335    Level: intermediate
336 
337 .seealso: PetscDrawLGCreate()
338 
339 @*/
PetscDrawLGSetLimits(PetscDrawLG lg,PetscReal x_min,PetscReal x_max,PetscReal y_min,PetscReal y_max)340 PetscErrorCode  PetscDrawLGSetLimits(PetscDrawLG lg,PetscReal x_min,PetscReal x_max,PetscReal y_min,PetscReal y_max)
341 {
342   PetscFunctionBegin;
343   PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1);
344 
345   (lg)->xmin = x_min;
346   (lg)->xmax = x_max;
347   (lg)->ymin = y_min;
348   (lg)->ymax = y_max;
349   PetscFunctionReturn(0);
350 }
351 
352 /*@
353    PetscDrawLGReset - Clears line graph to allow for reuse with new data.
354 
355    Logically Collective on PetscDrawLG
356 
357    Input Parameter:
358 .  lg - the line graph context.
359 
360    Level: intermediate
361 
362 .seealso: PetscDrawLGCreate()
363 
364 @*/
PetscDrawLGReset(PetscDrawLG lg)365 PetscErrorCode  PetscDrawLGReset(PetscDrawLG lg)
366 {
367   PetscFunctionBegin;
368   PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1);
369   lg->xmin  = 1.e20;
370   lg->ymin  = 1.e20;
371   lg->xmax  = -1.e20;
372   lg->ymax  = -1.e20;
373   lg->loc   = 0;
374   lg->nopts = 0;
375   PetscFunctionReturn(0);
376 }
377 
378 /*@
379    PetscDrawLGDestroy - Frees all space taken up by line graph data structure.
380 
381    Collective on PetscDrawLG
382 
383    Input Parameter:
384 .  lg - the line graph context
385 
386    Level: intermediate
387 
388 .seealso:  PetscDrawLGCreate()
389 @*/
PetscDrawLGDestroy(PetscDrawLG * lg)390 PetscErrorCode  PetscDrawLGDestroy(PetscDrawLG *lg)
391 {
392   PetscErrorCode ierr;
393   PetscInt       i;
394 
395   PetscFunctionBegin;
396   if (!*lg) PetscFunctionReturn(0);
397   PetscValidHeaderSpecific(*lg,PETSC_DRAWLG_CLASSID,1);
398   if (--((PetscObject)(*lg))->refct > 0) {*lg = NULL; PetscFunctionReturn(0);}
399 
400   if ((*lg)->legend) {
401     for (i=0; i<(*lg)->dim; i++) {
402       ierr = PetscFree((*lg)->legend[i]);CHKERRQ(ierr);
403     }
404     ierr = PetscFree((*lg)->legend);CHKERRQ(ierr);
405   }
406   ierr = PetscFree((*lg)->colors);CHKERRQ(ierr);
407   ierr = PetscFree2((*lg)->x,(*lg)->y);CHKERRQ(ierr);
408   ierr = PetscDrawAxisDestroy(&(*lg)->axis);CHKERRQ(ierr);
409   ierr = PetscDrawDestroy(&(*lg)->win);CHKERRQ(ierr);
410   ierr = PetscHeaderDestroy(lg);CHKERRQ(ierr);
411   PetscFunctionReturn(0);
412 }
413 /*@
414    PetscDrawLGSetUseMarkers - Causes LG to draw a marker for each data-point.
415 
416    Logically Collective on PetscDrawLG
417 
418    Input Parameters:
419 +  lg - the linegraph context
420 -  flg - should mark each data point
421 
422    Options Database:
423 .  -lg_use_markers  <true,false>
424 
425    Level: intermediate
426 
427 .seealso: PetscDrawLGCreate()
428 
429 @*/
PetscDrawLGSetUseMarkers(PetscDrawLG lg,PetscBool flg)430 PetscErrorCode  PetscDrawLGSetUseMarkers(PetscDrawLG lg,PetscBool flg)
431 {
432   PetscFunctionBegin;
433   PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1);
434   PetscValidLogicalCollectiveBool(lg,flg,2);
435   lg->use_markers = flg;
436   PetscFunctionReturn(0);
437 }
438 
439 /*@
440    PetscDrawLGDraw - Redraws a line graph.
441 
442    Collective on PetscDrawLG
443 
444    Input Parameter:
445 .  lg - the line graph context
446 
447    Level: intermediate
448 
449 .seealso: PetscDrawSPDraw(), PetscDrawLGSPDraw(), PetscDrawLGReset()
450 
451 @*/
PetscDrawLGDraw(PetscDrawLG lg)452 PetscErrorCode  PetscDrawLGDraw(PetscDrawLG lg)
453 {
454   PetscReal      xmin,xmax,ymin,ymax;
455   PetscErrorCode ierr;
456   PetscMPIInt    rank;
457   PetscDraw      draw;
458   PetscBool      isnull;
459 
460   PetscFunctionBegin;
461   PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1);
462   ierr = PetscDrawIsNull(lg->win,&isnull);CHKERRQ(ierr);
463   if (isnull) PetscFunctionReturn(0);
464   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)lg),&rank);CHKERRQ(ierr);
465 
466   draw = lg->win;
467   ierr = PetscDrawCheckResizedWindow(draw);CHKERRQ(ierr);
468   ierr = PetscDrawClear(draw);CHKERRQ(ierr);
469 
470   xmin = lg->xmin; xmax = lg->xmax; ymin = lg->ymin; ymax = lg->ymax;
471   ierr = PetscDrawAxisSetLimits(lg->axis,xmin,xmax,ymin,ymax);CHKERRQ(ierr);
472   ierr = PetscDrawAxisDraw(lg->axis);CHKERRQ(ierr);
473 
474   ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
475   if (!rank) {
476     int i,j,dim=lg->dim,nopts=lg->nopts,cl;
477     for (i=0; i<dim; i++) {
478       for (j=1; j<nopts; j++) {
479         cl   = lg->colors ? lg->colors[i] : ((PETSC_DRAW_BLACK + i) % PETSC_DRAW_MAXCOLOR);
480         ierr = PetscDrawLine(draw,lg->x[(j-1)*dim+i],lg->y[(j-1)*dim+i],lg->x[j*dim+i],lg->y[j*dim+i],cl);CHKERRQ(ierr);
481         if (lg->use_markers) {ierr = PetscDrawMarker(draw,lg->x[j*dim+i],lg->y[j*dim+i],cl);CHKERRQ(ierr);}
482       }
483     }
484   }
485   if (!rank && lg->legend) {
486     int       i,dim=lg->dim,cl;
487     PetscReal xl,yl,xr,yr,tw,th;
488     size_t    slen,len=0;
489     ierr = PetscDrawAxisGetLimits(lg->axis,&xl,&xr,&yl,&yr);CHKERRQ(ierr);
490     ierr = PetscDrawStringGetSize(draw,&tw,&th);CHKERRQ(ierr);
491     for (i=0; i<dim; i++) {
492       ierr = PetscStrlen(lg->legend[i],&slen);CHKERRQ(ierr);
493       len = PetscMax(len,slen);
494     }
495     xr = xr - 1.5*tw; xl = xr - (len + 7)*tw;
496     yr = yr - 1.0*th; yl = yr - (dim + 1)*th;
497     ierr = PetscDrawLine(draw,xl,yl,xr,yl,PETSC_DRAW_BLACK);CHKERRQ(ierr);
498     ierr = PetscDrawLine(draw,xr,yl,xr,yr,PETSC_DRAW_BLACK);CHKERRQ(ierr);
499     ierr = PetscDrawLine(draw,xr,yr,xl,yr,PETSC_DRAW_BLACK);CHKERRQ(ierr);
500     ierr = PetscDrawLine(draw,xl,yr,xl,yl,PETSC_DRAW_BLACK);CHKERRQ(ierr);
501     for  (i=0; i<dim; i++) {
502       cl   = lg->colors ? lg->colors[i] : (PETSC_DRAW_BLACK + i);
503       ierr = PetscDrawLine(draw,xl + 1*tw,yr - (i + 1)*th,xl + 5*tw,yr - (i + 1)*th,cl);CHKERRQ(ierr);
504       ierr = PetscDrawString(draw,xl + 6*tw,yr - (i + 1.5)*th,PETSC_DRAW_BLACK,lg->legend[i]);CHKERRQ(ierr);
505     }
506   }
507   ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
508 
509   ierr = PetscDrawFlush(draw);CHKERRQ(ierr);
510   ierr = PetscDrawPause(draw);CHKERRQ(ierr);
511   PetscFunctionReturn(0);
512 }
513 
514 /*@
515   PetscDrawLGSave - Saves a drawn image
516 
517   Collective on PetscDrawLG
518 
519   Input Parameter:
520 . lg - The line graph context
521 
522   Level: intermediate
523 
524 .seealso:  PetscDrawLGCreate(), PetscDrawLGGetDraw(), PetscDrawSetSave(), PetscDrawSave()
525 @*/
PetscDrawLGSave(PetscDrawLG lg)526 PetscErrorCode  PetscDrawLGSave(PetscDrawLG lg)
527 {
528   PetscErrorCode ierr;
529 
530   PetscFunctionBegin;
531   PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1);
532   ierr = PetscDrawSave(lg->win);CHKERRQ(ierr);
533   PetscFunctionReturn(0);
534 }
535 
536 /*@
537   PetscDrawLGView - Prints a line graph.
538 
539   Collective on PetscDrawLG
540 
541   Input Parameter:
542 . lg - the line graph context
543 
544   Level: beginner
545 
546 .seealso: PetscDrawLGCreate()
547 
548 @*/
PetscDrawLGView(PetscDrawLG lg,PetscViewer viewer)549 PetscErrorCode  PetscDrawLGView(PetscDrawLG lg,PetscViewer viewer)
550 {
551   PetscReal      xmin=lg->xmin, xmax=lg->xmax, ymin=lg->ymin, ymax=lg->ymax;
552   PetscInt       i, j, dim = lg->dim, nopts = lg->nopts;
553   PetscErrorCode ierr;
554 
555   PetscFunctionBegin;
556   PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1);
557 
558   if (nopts < 1)                  PetscFunctionReturn(0);
559   if (xmin > xmax || ymin > ymax) PetscFunctionReturn(0);
560 
561   if (!viewer){
562     ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)lg),&viewer);CHKERRQ(ierr);
563   }
564   ierr = PetscObjectPrintClassNamePrefixType((PetscObject)lg,viewer);CHKERRQ(ierr);
565   for (i = 0; i < dim; i++) {
566     ierr = PetscViewerASCIIPrintf(viewer, "Line %D>\n", i);CHKERRQ(ierr);
567     for (j = 0; j < nopts; j++) {
568       ierr = PetscViewerASCIIPrintf(viewer, "  X: %g Y: %g\n", (double)lg->x[j*dim+i], (double)lg->y[j*dim+i]);CHKERRQ(ierr);
569     }
570   }
571   PetscFunctionReturn(0);
572 }
573 
574 /*@C
575    PetscDrawLGSetOptionsPrefix - Sets the prefix used for searching for all
576    PetscDrawLG options in the database.
577 
578    Logically Collective on PetscDrawLG
579 
580    Input Parameter:
581 +  lg - the line graph context
582 -  prefix - the prefix to prepend to all option names
583 
584    Level: advanced
585 
586 .seealso: PetscDrawLGSetFromOptions(), PetscDrawLGCreate()
587 @*/
PetscDrawLGSetOptionsPrefix(PetscDrawLG lg,const char prefix[])588 PetscErrorCode  PetscDrawLGSetOptionsPrefix(PetscDrawLG lg,const char prefix[])
589 {
590   PetscErrorCode ierr;
591 
592   PetscFunctionBegin;
593   PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1);
594   ierr = PetscObjectSetOptionsPrefix((PetscObject)lg,prefix);CHKERRQ(ierr);
595   PetscFunctionReturn(0);
596 }
597 
598 /*@
599     PetscDrawLGSetFromOptions - Sets options related to the PetscDrawLG
600 
601     Collective on PetscDrawLG
602 
603     Options Database:
604 
605     Level: intermediate
606 
607 .seealso:  PetscDrawLGDestroy(), PetscDrawLGCreate()
608 @*/
PetscDrawLGSetFromOptions(PetscDrawLG lg)609 PetscErrorCode  PetscDrawLGSetFromOptions(PetscDrawLG lg)
610 {
611   PetscErrorCode      ierr;
612   PetscBool           usemarkers,set;
613   PetscDrawMarkerType markertype;
614 
615   PetscFunctionBegin;
616   PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1);
617 
618   ierr = PetscDrawGetMarkerType(lg->win,&markertype);CHKERRQ(ierr);
619   ierr = PetscOptionsGetEnum(((PetscObject)lg)->options,((PetscObject)lg)->prefix,"-lg_marker_type",PetscDrawMarkerTypes,(PetscEnum*)&markertype,&set);CHKERRQ(ierr);
620   if (set) {
621     ierr = PetscDrawLGSetUseMarkers(lg,PETSC_TRUE);CHKERRQ(ierr);
622     ierr = PetscDrawSetMarkerType(lg->win,markertype);CHKERRQ(ierr);
623   }
624   usemarkers = lg->use_markers;
625   ierr = PetscOptionsGetBool(((PetscObject)lg)->options,((PetscObject)lg)->prefix,"-lg_use_markers",&usemarkers,&set);CHKERRQ(ierr);
626   if (set) {ierr = PetscDrawLGSetUseMarkers(lg,usemarkers);CHKERRQ(ierr);}
627   PetscFunctionReturn(0);
628 }
629