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