Actual source code: dtri.c
1: #include <petsc/private/drawimpl.h>
3: /*@
4: PetscDrawTriangle - draws a triangle onto a drawable.
6: Not Collective
8: Input Parameters:
9: + draw - the drawing context
10: . x1 - coordinate of the first vertex
11: . y_1 - coordinate of the first vertex
12: . x2 - coordinate of the second vertex
13: . y2 - coordinate of the second vertex
14: . x3 - coordinate of the third vertex
15: . y3 - coordinate of the third vertex
16: . c1 - color of the first vertex
17: . c2 - color of the second vertex
18: - c3 - color of the third vertext
20: Level: beginner
22: .seealso: `PetscDraw`, `PetscDrawLine()`, `PetscDrawRectangle()`, `PetscDrawEllipse()`, `PetscDrawMarker()`, `PetscDrawPoint()`, `PetscDrawArrow()`
23: @*/
24: PetscErrorCode PetscDrawTriangle(PetscDraw draw, PetscReal x1, PetscReal y_1, PetscReal x2, PetscReal y2, PetscReal x3, PetscReal y3, int c1, int c2, int c3)
25: {
26: PetscFunctionBegin;
28: PetscUseTypeMethod(draw, triangle, x1, y_1, x2, y2, x3, y3, c1, c2, c3);
29: PetscFunctionReturn(PETSC_SUCCESS);
30: }
32: /*@
33: PetscDrawScalePopup - draws a contour scale window.
35: Collective
37: Input Parameters:
38: + popup - the window (often a window obtained via `PetscDrawGetPopup()`
39: . min - minimum value being plotted
40: - max - maximum value being plotted
42: Level: intermediate
44: Note:
45: All processors that share the draw MUST call this routine
47: .seealso: `PetscDraw`, `PetscDrawGetPopup()`, `PetscDrawTensorContour()`
48: @*/
49: PetscErrorCode PetscDrawScalePopup(PetscDraw popup, PetscReal min, PetscReal max)
50: {
51: PetscBool isnull;
52: PetscReal xl = 0.0, yl = 0.0, xr = 1.0, yr = 1.0;
53: PetscMPIInt rank;
54: int i;
55: char string[32];
57: PetscFunctionBegin;
58: if (!popup) PetscFunctionReturn(PETSC_SUCCESS);
60: PetscCall(PetscDrawIsNull(popup, &isnull));
61: if (isnull) PetscFunctionReturn(PETSC_SUCCESS);
62: PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)popup), &rank));
64: PetscCall(PetscDrawCheckResizedWindow(popup));
65: PetscCall(PetscDrawClear(popup));
66: PetscCall(PetscDrawSetTitle(popup, "Contour Scale"));
67: PetscCall(PetscDrawSetCoordinates(popup, xl, yl, xr, yr));
68: PetscDrawCollectiveBegin(popup);
69: if (rank == 0) {
70: for (i = 0; i < 10; i++) {
71: int c = PetscDrawRealToColor((PetscReal)i / 9, 0, 1);
72: PetscCall(PetscDrawRectangle(popup, xl, yl, xr, yr, c, c, c, c));
73: yl += 0.1;
74: }
75: for (i = 0; i < 10; i++) {
76: PetscReal value = min + ((PetscReal)i) * (max - min) / 9;
77: /* look for a value that should be zero, but is not due to round-off */
78: if (PetscAbsReal(value) < 1.e-10 && max - min > 1.e-6) value = 0.0;
79: PetscCall(PetscSNPrintf(string, sizeof(string), "%18.16e", (double)value));
80: PetscCall(PetscDrawString(popup, 0.2, 0.02 + i / 10.0, PETSC_DRAW_BLACK, string));
81: }
82: }
83: PetscDrawCollectiveEnd(popup);
84: PetscCall(PetscDrawFlush(popup));
85: PetscCall(PetscDrawSave(popup));
86: PetscFunctionReturn(PETSC_SUCCESS);
87: }
89: typedef struct {
90: int m, n;
91: PetscReal *x, *y, min, max, *v;
92: PetscBool showgrid;
93: } ZoomCtx;
95: static PetscErrorCode PetscDrawTensorContour_Zoom(PetscDraw win, void *dctx)
96: {
97: int i;
98: ZoomCtx *ctx = (ZoomCtx *)dctx;
100: PetscFunctionBegin;
101: PetscCall(PetscDrawTensorContourPatch(win, ctx->m, ctx->n, ctx->x, ctx->y, ctx->min, ctx->max, ctx->v));
102: if (ctx->showgrid) {
103: for (i = 0; i < ctx->m; i++) PetscCall(PetscDrawLine(win, ctx->x[i], ctx->y[0], ctx->x[i], ctx->y[ctx->n - 1], PETSC_DRAW_BLACK));
104: for (i = 0; i < ctx->n; i++) PetscCall(PetscDrawLine(win, ctx->x[0], ctx->y[i], ctx->x[ctx->m - 1], ctx->y[i], PETSC_DRAW_BLACK));
105: }
106: PetscFunctionReturn(PETSC_SUCCESS);
107: }
109: /*@
110: PetscDrawTensorContour - draws a contour plot for a two-dimensional array
112: Collective, but `draw` must be sequential
114: Input Parameters:
115: + draw - the draw context
116: . m - the number of local mesh points in the x direction
117: . n - the number of local mesh points in the y direction
118: . xi - the locations of the global mesh points in the horizontal direction (optional, use `NULL` to indicate uniform spacing on [0,1])
119: . yi - the locations of the global mesh points in the vertical direction (optional, use `NULL` to indicate uniform spacing on [0,1])
120: - v - the values
122: Options Database Keys:
123: + -draw_x_shared_colormap - Indicates use of private colormap
124: - -draw_contour_grid - draws grid contour
126: Level: intermediate
128: .seealso: `PetscDraw`, `PetscDrawTensorContourPatch()`, `PetscDrawScalePopup()`
129: @*/
130: PetscErrorCode PetscDrawTensorContour(PetscDraw draw, int m, int n, const PetscReal xi[], const PetscReal yi[], PetscReal *v)
131: {
132: int N = m * n;
133: PetscBool isnull;
134: PetscDraw popup;
135: int xin = 1, yin = 1, i;
136: PetscMPIInt size;
137: PetscReal h;
138: ZoomCtx ctx;
140: PetscFunctionBegin;
142: PetscCall(PetscDrawIsNull(draw, &isnull));
143: if (isnull) PetscFunctionReturn(PETSC_SUCCESS);
144: PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)draw), &size));
145: PetscCheck(size <= 1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "May only be used with single processor PetscDraw");
146: PetscCheck(N > 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n %d and m %d must be positive", m, n);
148: ctx.v = v;
149: ctx.m = m;
150: ctx.n = n;
151: ctx.max = ctx.min = v[0];
152: for (i = 0; i < N; i++) {
153: if (ctx.max < ctx.v[i]) ctx.max = ctx.v[i];
154: if (ctx.min > ctx.v[i]) ctx.min = ctx.v[i];
155: }
156: if (ctx.max - ctx.min < 1.e-7) {
157: ctx.min -= 5.e-8;
158: ctx.max += 5.e-8;
159: }
161: /* PetscDraw the scale window */
162: PetscCall(PetscDrawGetPopup(draw, &popup));
163: PetscCall(PetscDrawScalePopup(popup, ctx.min, ctx.max));
165: ctx.showgrid = PETSC_FALSE;
166: PetscCall(PetscOptionsGetBool(((PetscObject)draw)->options, NULL, "-draw_contour_grid", &ctx.showgrid, NULL));
168: /* fill up x and y coordinates */
169: if (!xi) {
170: xin = 0;
171: PetscCall(PetscMalloc1(ctx.m, &ctx.x));
172: h = 1.0 / (ctx.m - 1);
173: ctx.x[0] = 0.0;
174: for (i = 1; i < ctx.m; i++) ctx.x[i] = ctx.x[i - 1] + h;
175: } else ctx.x = (PetscReal *)xi;
177: if (!yi) {
178: yin = 0;
179: PetscCall(PetscMalloc1(ctx.n, &ctx.y));
180: h = 1.0 / (ctx.n - 1);
181: ctx.y[0] = 0.0;
182: for (i = 1; i < ctx.n; i++) ctx.y[i] = ctx.y[i - 1] + h;
183: } else ctx.y = (PetscReal *)yi;
185: PetscCall(PetscDrawZoom(draw, PetscDrawTensorContour_Zoom, &ctx));
187: if (!xin) PetscCall(PetscFree(ctx.x));
188: if (!yin) PetscCall(PetscFree(ctx.y));
189: PetscFunctionReturn(PETSC_SUCCESS);
190: }
192: /*@
193: PetscDrawTensorContourPatch - draws a rectangular patch of a contour plot
194: for a two-dimensional array.
196: Not Collective
198: Input Parameters:
199: + draw - the draw context
200: . m - the number of local mesh points in the x direction
201: . n - the number of local mesh points in the y direction
202: . x - the horizontal locations of the local mesh points
203: . y - the vertical locations of the local mesh points
204: . min - the minimum value in the entire contour
205: . max - the maximum value in the entire contour
206: - v - the data
208: Options Database Key:
209: . -draw_x_shared_colormap - Activates private colormap
211: Level: advanced
213: Note:
214: This is a lower level support routine, usually the user will call
215: `PetscDrawTensorContour()`.
217: .seealso: `PetscDraw`, `PetscDrawTensorContour()`
218: @*/
219: PetscErrorCode PetscDrawTensorContourPatch(PetscDraw draw, int m, int n, PetscReal *x, PetscReal *y, PetscReal min, PetscReal max, PetscReal *v)
220: {
221: int c1, c2, c3, c4, i, j;
222: PetscReal x1, x2, x3, x4, y_1, y2, y3, y4;
224: PetscFunctionBegin;
226: /* PetscDraw the contour plot patch */
227: for (j = 0; j < n - 1; j++) {
228: for (i = 0; i < m - 1; i++) {
229: x1 = x[i];
230: y_1 = y[j];
231: c1 = PetscDrawRealToColor(v[i + j * m], min, max);
232: x2 = x[i + 1];
233: y2 = y_1;
234: c2 = PetscDrawRealToColor(v[i + j * m + 1], min, max);
235: x3 = x2;
236: y3 = y[j + 1];
237: c3 = PetscDrawRealToColor(v[i + j * m + 1 + m], min, max);
238: x4 = x1;
239: y4 = y3;
240: c4 = PetscDrawRealToColor(v[i + j * m + m], min, max);
242: PetscCall(PetscDrawTriangle(draw, x1, y_1, x2, y2, x3, y3, c1, c2, c3));
243: PetscCall(PetscDrawTriangle(draw, x1, y_1, x3, y3, x4, y4, c1, c3, c4));
244: }
245: }
246: PetscFunctionReturn(PETSC_SUCCESS);
247: }