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