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