xref: /petsc/src/sys/classes/draw/utils/lgc.c (revision e6e75211d226c622f451867f53ce5d558649ff4f)
1 
2 #include <../src/sys/classes/draw/utils/lgimpl.h>  /*I   "petscdraw.h"  I*/
3 #include <petscviewer.h>
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 @*/
25 PetscErrorCode  PetscDrawLGGetAxis(PetscDrawLG lg,PetscDrawAxis *axis)
26 {
27   PetscFunctionBegin;
28   if (lg && ((PetscObject)lg)->classid == PETSC_DRAW_CLASSID) {
29     *axis = 0;
30     PetscFunctionReturn(0);
31   }
32   PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1);
33   PetscValidPointer(axis,2);
34   *axis = lg->axis;
35   PetscFunctionReturn(0);
36 }
37 
38 #undef __FUNCT__
39 #define __FUNCT__ "PetscDrawLGGetDraw"
40 /*@
41    PetscDrawLGGetDraw - Gets the draw context associated with a line graph.
42 
43    Not Collective, if PetscDrawLG is parallel then PetscDraw is parallel
44 
45    Input Parameter:
46 .  lg - the line graph context
47 
48    Output Parameter:
49 .  draw - the draw context
50 
51    Level: intermediate
52 
53 @*/
54 PetscErrorCode  PetscDrawLGGetDraw(PetscDrawLG lg,PetscDraw *draw)
55 {
56   PetscFunctionBegin;
57   PetscValidHeader(lg,1);
58   PetscValidPointer(draw,2);
59   if (((PetscObject)lg)->classid == PETSC_DRAW_CLASSID) *draw = (PetscDraw)lg;
60   else {
61     PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1);
62     *draw = lg->win;
63   }
64   PetscFunctionReturn(0);
65 }
66 
67 
68 #undef __FUNCT__
69 #define __FUNCT__ "PetscDrawLGSPDraw"
70 /*@
71    PetscDrawLGSPDraw - Redraws a line graph.
72 
73    Not Collective,but ignored by all processors except processor 0 in PetscDrawLG
74 
75    Input Parameter:
76 .  lg - the line graph context
77 
78    Level: intermediate
79 
80 .seealso: PetscDrawLGDraw(), PetscDrawSPDraw()
81 
82    Developer Notes: This code cheats and uses the fact that the LG and SP structs are the same
83 
84 @*/
85 PetscErrorCode  PetscDrawLGSPDraw(PetscDrawLG lg,PetscDrawSP spin)
86 {
87   PetscDrawLG    sp = (PetscDrawLG)spin;
88   PetscReal      xmin,xmax,ymin,ymax;
89   PetscErrorCode ierr;
90   int            i,j,dim,nopts,rank;
91   PetscDraw      draw = lg->win;
92 
93   PetscFunctionBegin;
94   if (lg && ((PetscObject)lg)->classid == PETSC_DRAW_CLASSID) PetscFunctionReturn(0);
95   PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1);
96   PetscValidHeaderSpecific(sp,PETSC_DRAWSP_CLASSID,2);
97 
98   xmin = PetscMin(lg->xmin,sp->xmin);
99   ymin = PetscMin(lg->ymin,sp->ymin);
100   xmax = PetscMax(lg->xmax,sp->xmax);
101   ymax = PetscMax(lg->ymax,sp->ymax);
102 
103   ierr = PetscDrawClear(draw);CHKERRQ(ierr);
104   ierr = PetscDrawAxisSetLimits(lg->axis,xmin,xmax,ymin,ymax);CHKERRQ(ierr);
105   ierr = PetscDrawAxisDraw(lg->axis);CHKERRQ(ierr);
106 
107   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)lg),&rank);CHKERRQ(ierr);
108   if (!rank) {
109 
110     dim   = lg->dim;
111     nopts = lg->nopts;
112     for (i=0; i<dim; i++) {
113       for (j=1; j<nopts; j++) {
114         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);
115         if (lg->use_markers) {
116           ierr = PetscDrawMarker(draw,lg->x[j*dim+i],lg->y[j*dim+i],PETSC_DRAW_RED);CHKERRQ(ierr);
117         }
118       }
119     }
120 
121     dim   = sp->dim;
122     nopts = sp->nopts;
123     for (i=0; i<dim; i++) {
124       for (j=0; j<nopts; j++) {
125         ierr = PetscDrawMarker(draw,sp->x[j*dim+i],sp->y[j*dim+i],PETSC_DRAW_RED);CHKERRQ(ierr);
126       }
127     }
128   }
129   ierr = PetscDrawFlush(lg->win);CHKERRQ(ierr);
130   ierr = PetscDrawPause(lg->win);CHKERRQ(ierr);
131   PetscFunctionReturn(0);
132 }
133 
134 
135 #undef __FUNCT__
136 #define __FUNCT__ "PetscDrawLGCreate"
137 /*@
138     PetscDrawLGCreate - Creates a line graph data structure.
139 
140     Collective over PetscDraw
141 
142     Input Parameters:
143 +   draw - the window where the graph will be made.
144 -   dim - the number of curves which will be drawn
145 
146     Output Parameters:
147 .   outctx - the line graph context
148 
149     Level: intermediate
150 
151     Concepts: line graph^creating
152 
153 .seealso:  PetscDrawLGDestroy()
154 @*/
155 PetscErrorCode  PetscDrawLGCreate(PetscDraw draw,PetscInt dim,PetscDrawLG *outctx)
156 {
157   PetscErrorCode ierr;
158   PetscBool      isnull;
159   PetscObject    obj = (PetscObject)draw;
160   PetscDrawLG    lg;
161 
162   PetscFunctionBegin;
163   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
164   PetscValidPointer(outctx,2);
165   ierr = PetscObjectTypeCompare(obj,PETSC_DRAW_NULL,&isnull);CHKERRQ(ierr);
166   if (isnull) {
167     ierr = PetscDrawOpenNull(PetscObjectComm((PetscObject)obj),(PetscDraw*)outctx);CHKERRQ(ierr);
168     PetscFunctionReturn(0);
169   }
170   ierr = PetscHeaderCreate(lg,PETSC_DRAWLG_CLASSID,"PetscDrawLG","Line graph","Draw",PetscObjectComm((PetscObject)obj),PetscDrawLGDestroy,NULL);CHKERRQ(ierr);
171 
172   lg->view    = NULL;
173   lg->destroy = NULL;
174   lg->nopts   = 0;
175   lg->win     = draw;
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   *outctx = 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 over 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 @*/
212 PetscErrorCode  PetscDrawLGSetColors(PetscDrawLG lg,const int *colors)
213 {
214   PetscErrorCode ierr;
215 
216   PetscFunctionBegin;
217   if (lg && ((PetscObject)lg)->classid == PETSC_DRAW_CLASSID) PetscFunctionReturn(0);
218   PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1);
219   ierr = PetscFree(lg->colors);CHKERRQ(ierr);
220   ierr = PetscMalloc1(lg->dim,&lg->colors);CHKERRQ(ierr);
221   ierr = PetscMemcpy(lg->colors,colors,lg->dim*sizeof(int));CHKERRQ(ierr);
222   PetscFunctionReturn(0);
223 }
224 
225 #undef __FUNCT__
226 #undef __FUNCT__
227 #define __FUNCT__ "PetscDrawLGSetLegend"
228 /*@C
229    PetscDrawLGSetLegend - sets the names of each curve plotted
230 
231    Logically Collective over PetscDrawLG
232 
233    Input Parameter:
234 +  lg - the line graph context.
235 -  names - the names for each curve
236 
237    Level: intermediate
238 
239    Concepts: line graph^setting number of lines
240 
241 @*/
242 PetscErrorCode  PetscDrawLGSetLegend(PetscDrawLG lg,const char *const *names)
243 {
244   PetscErrorCode ierr;
245   PetscInt       i;
246 
247   PetscFunctionBegin;
248   if (lg && ((PetscObject)lg)->classid == PETSC_DRAW_CLASSID) PetscFunctionReturn(0);
249   PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1);
250 
251   if (lg->legend) {
252     for (i=0; i<lg->dim; i++) {
253       ierr = PetscFree(lg->legend[i]);CHKERRQ(ierr);
254     }
255     ierr = PetscFree(lg->legend);CHKERRQ(ierr);
256   }
257   if (names) {
258     ierr = PetscMalloc1(lg->dim,&lg->legend);CHKERRQ(ierr);
259     for (i=0; i<lg->dim; i++) {
260       ierr = PetscStrallocpy(names[i],&lg->legend[i]);CHKERRQ(ierr);
261     }
262   }
263   PetscFunctionReturn(0);
264 }
265 
266 #undef __FUNCT__
267 #define __FUNCT__ "PetscDrawLGGetDimension"
268 /*@
269    PetscDrawLGGetDimension - Change the number of lines that are to be drawn.
270 
271    Logically Collective over PetscDrawLG
272 
273    Input Parameter:
274 .  lg - the line graph context.
275 
276    Output Parameter:
277 .  dim - the number of curves.
278 
279    Level: intermediate
280 
281    Concepts: line graph^setting number of lines
282 
283 @*/
284 PetscErrorCode  PetscDrawLGGetDimension(PetscDrawLG lg,PetscInt *dim)
285 {
286   PetscFunctionBegin;
287   if (lg && ((PetscObject)lg)->classid == PETSC_DRAW_CLASSID) PetscFunctionReturn(0);
288   PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1);
289   *dim = lg->dim;
290   PetscFunctionReturn(0);
291 }
292 
293 #undef __FUNCT__
294 #define __FUNCT__ "PetscDrawLGSetDimension"
295 /*@
296    PetscDrawLGSetDimension - Change the number of lines that are to be drawn.
297 
298    Logically Collective over PetscDrawLG
299 
300    Input Parameter:
301 +  lg - the line graph context.
302 -  dim - the number of curves.
303 
304    Level: intermediate
305 
306    Concepts: line graph^setting number of lines
307 
308 @*/
309 PetscErrorCode  PetscDrawLGSetDimension(PetscDrawLG lg,PetscInt dim)
310 {
311   PetscErrorCode ierr;
312   PetscInt       i;
313 
314   PetscFunctionBegin;
315   if (lg && ((PetscObject)lg)->classid == PETSC_DRAW_CLASSID) PetscFunctionReturn(0);
316   PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1);
317   PetscValidLogicalCollectiveInt(lg,dim,2);
318   if (lg->dim == dim) PetscFunctionReturn(0);
319 
320   ierr = PetscFree2(lg->x,lg->y);CHKERRQ(ierr);
321   if (lg->legend) {
322     for (i=0; i<lg->dim; i++) {
323       ierr = PetscFree(lg->legend[i]);CHKERRQ(ierr);
324     }
325     ierr = PetscFree(lg->legend);CHKERRQ(ierr);
326   }
327   ierr    = PetscFree(lg->colors);CHKERRQ(ierr);
328   lg->dim = dim;
329   ierr    = PetscMalloc2(dim*CHUNCKSIZE,&lg->x,dim*CHUNCKSIZE,&lg->y);CHKERRQ(ierr);
330   ierr    = PetscLogObjectMemory((PetscObject)lg,2*dim*CHUNCKSIZE*sizeof(PetscReal));CHKERRQ(ierr);
331   lg->len = dim*CHUNCKSIZE;
332   PetscFunctionReturn(0);
333 }
334 
335 #undef __FUNCT__
336 #define __FUNCT__ "PetscDrawLGReset"
337 /*@
338    PetscDrawLGReset - Clears line graph to allow for reuse with new data.
339 
340    Logically Collective over PetscDrawLG
341 
342    Input Parameter:
343 .  lg - the line graph context.
344 
345    Level: intermediate
346 
347    Concepts: line graph^restarting
348 
349 @*/
350 PetscErrorCode  PetscDrawLGReset(PetscDrawLG lg)
351 {
352   PetscFunctionBegin;
353   if (lg && ((PetscObject)lg)->classid == PETSC_DRAW_CLASSID) PetscFunctionReturn(0);
354   PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1);
355   lg->xmin  = 1.e20;
356   lg->ymin  = 1.e20;
357   lg->xmax  = -1.e20;
358   lg->ymax  = -1.e20;
359   lg->loc   = 0;
360   lg->nopts = 0;
361   PetscFunctionReturn(0);
362 }
363 
364 #undef __FUNCT__
365 #define __FUNCT__ "PetscDrawLGDestroy"
366 /*@
367    PetscDrawLGDestroy - Frees all space taken up by line graph data structure.
368 
369    Collective over PetscDrawLG
370 
371    Input Parameter:
372 .  lg - the line graph context
373 
374    Level: intermediate
375 
376 .seealso:  PetscDrawLGCreate()
377 @*/
378 PetscErrorCode  PetscDrawLGDestroy(PetscDrawLG *lg)
379 {
380   PetscErrorCode ierr;
381   PetscInt       i;
382 
383   PetscFunctionBegin;
384   if (!*lg) PetscFunctionReturn(0);
385   if (((PetscObject)(*lg))->classid != PETSC_DRAW_CLASSID) PetscValidHeaderSpecific(*lg,PETSC_DRAWLG_CLASSID,1);
386 
387   if (--((PetscObject)(*lg))->refct > 0) {*lg = 0; PetscFunctionReturn(0);}
388   if (((PetscObject)(*lg))->classid == PETSC_DRAW_CLASSID) {
389     ierr = PetscObjectDestroy((PetscObject*)lg);CHKERRQ(ierr);
390     PetscFunctionReturn(0);
391   }
392   if ((*lg)->legend) {
393     for (i=0; i<(*lg)->dim; i++) {
394       ierr = PetscFree((*lg)->legend[i]);CHKERRQ(ierr);
395     }
396     ierr = PetscFree((*lg)->legend);CHKERRQ(ierr);
397   }
398   ierr = PetscFree((*lg)->colors);CHKERRQ(ierr);
399   ierr = PetscDrawAxisDestroy(&(*lg)->axis);CHKERRQ(ierr);
400   ierr = PetscFree2((*lg)->x,(*lg)->y);CHKERRQ(ierr);
401   ierr = PetscHeaderDestroy(lg);CHKERRQ(ierr);
402   PetscFunctionReturn(0);
403 }
404 #undef __FUNCT__
405 #define __FUNCT__ "PetscDrawLGSetUseMarkers"
406 /*@
407    PetscDrawLGSetUseMarkers - Causes LG to draw a marker for each data-point.
408 
409    Not Collective, but ignored by all processors except processor 0 in PetscDrawLG
410 
411    Input Parameters:
412 +  lg - the linegraph context
413 -  flg - should mark each data point
414 
415    Options Database:
416 .  -lg_use_markers  <true,false>
417 
418    Level: intermediate
419 
420    Concepts: line graph^showing points
421 
422 @*/
423 PetscErrorCode  PetscDrawLGSetUseMarkers(PetscDrawLG lg,PetscBool flg)
424 {
425   PetscFunctionBegin;
426   if (lg && ((PetscObject)lg)->classid == PETSC_DRAW_CLASSID) PetscFunctionReturn(0);
427 
428   lg->use_markers = flg;
429   PetscFunctionReturn(0);
430 }
431 
432 #if defined(PETSC_HAVE_SETJMP_H) && defined(PETSC_HAVE_X)
433 #include <X11/Xlib.h>
434 #include <X11/Xutil.h>
435 #include <setjmp.h>
436 static jmp_buf PetscXIOErrorJumpBuf;
437 static void PetscXIOHandler(Display *dpy)
438 {
439   longjmp(PetscXIOErrorJumpBuf, 1);
440 }
441 #endif
442 
443 #undef __FUNCT__
444 #define __FUNCT__ "PetscDrawLGDraw"
445 /*@
446    PetscDrawLGDraw - Redraws a line graph.
447 
448    Not Collective,but ignored by all processors except processor 0 in PetscDrawLG
449 
450    Input Parameter:
451 .  lg - the line graph context
452 
453    Level: intermediate
454 
455 .seealso: PetscDrawSPDraw(), PetscDrawLGSPDraw()
456 
457 @*/
458 PetscErrorCode  PetscDrawLGDraw(PetscDrawLG lg)
459 {
460   PetscReal      xmin=lg->xmin,xmax=lg->xmax,ymin=lg->ymin,ymax=lg->ymax;
461   PetscErrorCode ierr;
462   int            i,j,dim = lg->dim,nopts = lg->nopts,rank,cl;
463   PetscDraw      draw = lg->win;
464   PetscBool      isnull;
465 
466   PetscFunctionBegin;
467   if (lg && ((PetscObject)lg)->classid == PETSC_DRAW_CLASSID) PetscFunctionReturn(0);
468   PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1);
469   ierr = PetscDrawIsNull(lg->win,&isnull);CHKERRQ(ierr);
470   if (isnull) PetscFunctionReturn(0);
471 
472 #if defined(PETSC_HAVE_SETJMP_H) && defined(PETSC_HAVE_X)
473   if (!setjmp(PetscXIOErrorJumpBuf)) XSetIOErrorHandler((XIOErrorHandler)PetscXIOHandler);
474   else {
475     XSetIOErrorHandler(NULL);
476     ierr = PetscDrawSetType(draw,PETSC_DRAW_NULL);CHKERRQ(ierr);
477     PetscFunctionReturn(0);
478   }
479 #endif
480 
481   ierr = PetscDrawCheckResizedWindow(draw);CHKERRQ(ierr);
482   ierr = PetscDrawClear(draw);CHKERRQ(ierr);
483   ierr = PetscDrawAxisSetLimits(lg->axis,xmin,xmax,ymin,ymax);CHKERRQ(ierr);
484   ierr = PetscDrawAxisDraw(lg->axis);CHKERRQ(ierr);
485 
486   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)lg),&rank);CHKERRQ(ierr);
487   if (!rank) {
488     for (i=0; i<dim; i++) {
489       for (j=1; j<nopts; j++) {
490         if (lg->colors) cl = lg->colors[i];
491         else cl = PETSC_DRAW_BLACK+i;
492         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);
493         if (lg->use_markers) {
494           ierr = PetscDrawMarker(draw,lg->x[j*dim+i],lg->y[j*dim+i],cl);CHKERRQ(ierr);
495         }
496       }
497     }
498   }
499   if (!rank && lg->legend) {
500     PetscReal xl,yl,xr,yr,tw,th;
501     size_t    len,mlen = 0;
502     int       cl;
503     ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
504     ierr = PetscDrawStringGetSize(draw,&tw,&th);CHKERRQ(ierr);
505     for (i=0; i<dim; i++) {
506       ierr = PetscStrlen(lg->legend[i],&len);CHKERRQ(ierr);
507       mlen = PetscMax(mlen,len);
508     }
509     ierr = PetscDrawLine(draw,xr - (mlen + 8)*tw,yr - 3*th,xr - 2*tw,yr - 3*th,PETSC_DRAW_BLACK);CHKERRQ(ierr);
510     ierr = PetscDrawLine(draw,xr - (mlen + 8)*tw,yr - 3*th,xr - (mlen + 8)*tw,yr - (4+lg->dim)*th,PETSC_DRAW_BLACK);CHKERRQ(ierr);
511     for  (i=0; i<dim; i++) {
512       cl   = (lg->colors ? lg->colors[i] : i + 1);
513       ierr = PetscDrawLine(draw,xr - (mlen + 6.7)*tw,yr - (4 + i)*th,xr - (mlen + 3.2)*tw,yr - (4 + i)*th,cl);CHKERRQ(ierr);
514       ierr = PetscDrawString(draw,xr - (mlen + 3)*tw,yr - (4.5 + i)*th,PETSC_DRAW_BLACK,lg->legend[i]);CHKERRQ(ierr);
515     }
516     ierr = PetscDrawLine(draw,xr - 2*tw,yr - 3*th,xr - 2*tw,yr - (4+lg->dim)*th,PETSC_DRAW_BLACK);CHKERRQ(ierr);
517     ierr = PetscDrawLine(draw,xr - (mlen + 8)*tw,yr - (4+lg->dim)*th,xr - 2*tw,yr - (4+lg->dim)*th,PETSC_DRAW_BLACK);CHKERRQ(ierr);
518   }
519   if (!rank) {ierr = PetscDrawFlush(lg->win);CHKERRQ(ierr);}
520   ierr = PetscDrawPause(lg->win);CHKERRQ(ierr);
521 #if defined(PETSC_HAVE_SETJMP_H) && defined(PETSC_HAVE_X)
522   XSetIOErrorHandler(NULL);
523 #endif
524   PetscFunctionReturn(0);
525 }
526 
527 #undef __FUNCT__
528 #define __FUNCT__ "PetscDrawLGView"
529 /*@
530   PetscDrawLGView - Prints a line graph.
531 
532   Not collective
533 
534   Input Parameter:
535 . lg - the line graph context
536 
537   Level: beginner
538 
539 .keywords:  draw, line, graph
540 @*/
541 PetscErrorCode  PetscDrawLGView(PetscDrawLG lg,PetscViewer viewer)
542 {
543   PetscReal      xmin=lg->xmin, xmax=lg->xmax, ymin=lg->ymin, ymax=lg->ymax;
544   PetscInt       i, j, dim = lg->dim, nopts = lg->nopts;
545   PetscErrorCode ierr;
546 
547   PetscFunctionBegin;
548   if (lg && ((PetscObject)lg)->classid == PETSC_DRAW_CLASSID) PetscFunctionReturn(0);
549   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID,1);
550   if (nopts < 1)                  PetscFunctionReturn(0);
551   if (xmin > xmax || ymin > ymax) PetscFunctionReturn(0);
552 
553   if (!viewer){
554     ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)lg),&viewer);CHKERRQ(ierr);
555   }
556   ierr = PetscObjectPrintClassNamePrefixType((PetscObject)lg,viewer);CHKERRQ(ierr);
557   for (i = 0; i < dim; i++) {
558     ierr = PetscViewerASCIIPrintf(viewer, "Line %D>\n", i);CHKERRQ(ierr);
559     for (j = 0; j < nopts; j++) {
560       ierr = PetscViewerASCIIPrintf(viewer, "  X: %g Y: %g\n", (double)lg->x[j*dim+i], (double)lg->y[j*dim+i]);CHKERRQ(ierr);
561     }
562   }
563   PetscFunctionReturn(0);
564 }
565 
566 #undef __FUNCT__
567 #define __FUNCT__ "PetscDrawLGSetFromOptions"
568 /*@
569     PetscDrawLGSetFromOptions - Sets options related to the PetscDrawLG
570 
571     Collective over PetscDrawLG
572 
573     Options Database:
574 
575     Level: intermediate
576 
577     Concepts: line graph^creating
578 
579 .seealso:  PetscDrawLGDestroy(), PetscDrawLGCreate()
580 @*/
581 PetscErrorCode  PetscDrawLGSetFromOptions(PetscDrawLG lg)
582 {
583   PetscErrorCode ierr;
584   PetscBool      flg=PETSC_FALSE, set;
585 
586   PetscFunctionBegin;
587   ierr = PetscOptionsGetBool(NULL,"-lg_use_markers",&flg,&set);CHKERRQ(ierr);
588   if (set) {ierr = PetscDrawLGSetUseMarkers(lg,flg);CHKERRQ(ierr);}
589   PetscFunctionReturn(0);
590 }
591