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