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: #if defined(__GNUC__) && !defined(__clang__)
33: #pragma GCC diagnostic push
34: #pragma GCC diagnostic ignored "-Wclobbered"
35: #endif
36: /*@
37: PetscDrawScalePopup - draws a contour scale window.
39: Collective
41: Input Parameters:
42: + popup - the window (often a window obtained via `PetscDrawGetPopup()`
43: . min - minimum value being plotted
44: - max - maximum value being plotted
46: Level: intermediate
48: Note:
49: All processors that share the draw MUST call this routine
51: .seealso: `PetscDraw`, `PetscDrawGetPopup()`, `PetscDrawTensorContour()`
52: @*/
53: PetscErrorCode PetscDrawScalePopup(PetscDraw popup, PetscReal min, PetscReal max)
54: {
55: PetscBool isnull;
56: PetscReal xl = 0.0, yl = 0.0, xr = 1.0, yr = 1.0;
57: PetscMPIInt rank;
58: int i;
59: char string[32];
61: PetscFunctionBegin;
62: if (!popup) PetscFunctionReturn(PETSC_SUCCESS);
64: PetscCall(PetscDrawIsNull(popup, &isnull));
65: if (isnull) PetscFunctionReturn(PETSC_SUCCESS);
66: PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)popup), &rank));
68: PetscCall(PetscDrawCheckResizedWindow(popup));
69: PetscCall(PetscDrawClear(popup));
70: PetscCall(PetscDrawSetTitle(popup, "Contour Scale"));
71: PetscCall(PetscDrawSetCoordinates(popup, xl, yl, xr, yr));
72: PetscDrawCollectiveBegin(popup);
73: if (rank == 0) {
74: for (i = 0; i < 10; i++) {
75: int c = PetscDrawRealToColor((PetscReal)i / 9, 0, 1);
76: PetscCall(PetscDrawRectangle(popup, xl, yl, xr, yr, c, c, c, c));
77: yl += 0.1;
78: }
79: for (i = 0; i < 10; i++) {
80: PetscReal value = min + ((PetscReal)i) * (max - min) / 9;
81: /* look for a value that should be zero, but is not due to round-off */
82: if (PetscAbsReal(value) < 1.e-10 && max - min > 1.e-6) value = 0.0;
83: PetscCall(PetscSNPrintf(string, sizeof(string), "%18.16e", (double)value));
84: PetscCall(PetscDrawString(popup, 0.2, 0.02 + i / 10.0, PETSC_DRAW_BLACK, string));
85: }
86: }
87: PetscDrawCollectiveEnd(popup);
88: PetscCall(PetscDrawFlush(popup));
89: PetscCall(PetscDrawSave(popup));
90: PetscFunctionReturn(PETSC_SUCCESS);
91: }
92: #if defined(__GNUC__) && !defined(__clang__)
93: #pragma GCC diagnostic pop
94: #endif
96: typedef struct {
97: int m, n;
98: PetscReal *x, *y, min, max, *v;
99: PetscBool showgrid;
100: } ZoomCtx;
102: static PetscErrorCode PetscDrawTensorContour_Zoom(PetscDraw win, void *dctx)
103: {
104: int i;
105: ZoomCtx *ctx = (ZoomCtx *)dctx;
107: PetscFunctionBegin;
108: PetscCall(PetscDrawTensorContourPatch(win, ctx->m, ctx->n, ctx->x, ctx->y, ctx->min, ctx->max, ctx->v));
109: if (ctx->showgrid) {
110: 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));
111: 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));
112: }
113: PetscFunctionReturn(PETSC_SUCCESS);
114: }
116: /*@
117: PetscDrawTensorContour - draws a contour plot for a two-dimensional array
119: Collective, but `draw` must be sequential
121: Input Parameters:
122: + draw - the draw context
123: . m - the number of local mesh points in the x direction
124: . n - the number of local mesh points in the y direction
125: . xi - the locations of the global mesh points in the horizontal direction (optional, use `NULL` to indicate uniform spacing on [0,1])
126: . yi - the locations of the global mesh points in the vertical direction (optional, use `NULL` to indicate uniform spacing on [0,1])
127: - v - the values
129: Options Database Keys:
130: + -draw_x_shared_colormap - Indicates use of private colormap
131: - -draw_contour_grid - draws grid contour
133: Level: intermediate
135: .seealso: `PetscDraw`, `PetscDrawTensorContourPatch()`, `PetscDrawScalePopup()`
136: @*/
137: PetscErrorCode PetscDrawTensorContour(PetscDraw draw, int m, int n, const PetscReal xi[], const PetscReal yi[], PetscReal v[])
138: {
139: int N = m * n;
140: PetscBool isnull;
141: PetscDraw popup;
142: int xin = 1, yin = 1, i;
143: PetscMPIInt size;
144: PetscReal h;
145: ZoomCtx ctx;
147: PetscFunctionBegin;
149: PetscCall(PetscDrawIsNull(draw, &isnull));
150: if (isnull) PetscFunctionReturn(PETSC_SUCCESS);
151: PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)draw), &size));
152: PetscCheck(size <= 1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "May only be used with single processor PetscDraw");
153: PetscCheck(N > 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n %d and m %d must be positive", m, n);
155: ctx.v = v;
156: ctx.m = m;
157: ctx.n = n;
158: ctx.max = ctx.min = v[0];
159: for (i = 0; i < N; i++) {
160: if (ctx.max < ctx.v[i]) ctx.max = ctx.v[i];
161: if (ctx.min > ctx.v[i]) ctx.min = ctx.v[i];
162: }
163: if (ctx.max - ctx.min < 1.e-7) {
164: ctx.min -= 5.e-8;
165: ctx.max += 5.e-8;
166: }
168: /* PetscDraw the scale window */
169: PetscCall(PetscDrawGetPopup(draw, &popup));
170: PetscCall(PetscDrawScalePopup(popup, ctx.min, ctx.max));
172: ctx.showgrid = PETSC_FALSE;
173: PetscCall(PetscOptionsGetBool(((PetscObject)draw)->options, NULL, "-draw_contour_grid", &ctx.showgrid, NULL));
175: /* fill up x and y coordinates */
176: if (!xi) {
177: xin = 0;
178: PetscCall(PetscMalloc1(ctx.m, &ctx.x));
179: h = 1.0 / (ctx.m - 1);
180: ctx.x[0] = 0.0;
181: for (i = 1; i < ctx.m; i++) ctx.x[i] = ctx.x[i - 1] + h;
182: } else ctx.x = (PetscReal *)xi;
184: if (!yi) {
185: yin = 0;
186: PetscCall(PetscMalloc1(ctx.n, &ctx.y));
187: h = 1.0 / (ctx.n - 1);
188: ctx.y[0] = 0.0;
189: for (i = 1; i < ctx.n; i++) ctx.y[i] = ctx.y[i - 1] + h;
190: } else ctx.y = (PetscReal *)yi;
192: PetscCall(PetscDrawZoom(draw, PetscDrawTensorContour_Zoom, &ctx));
194: if (!xin) PetscCall(PetscFree(ctx.x));
195: if (!yin) PetscCall(PetscFree(ctx.y));
196: PetscFunctionReturn(PETSC_SUCCESS);
197: }
199: /*@
200: PetscDrawTensorContourPatch - draws a rectangular patch of a contour plot
201: for a two-dimensional array.
203: Not Collective
205: Input Parameters:
206: + draw - the draw context
207: . m - the number of local mesh points in the x direction
208: . n - the number of local mesh points in the y direction
209: . x - the horizontal locations of the local mesh points
210: . y - the vertical locations of the local mesh points
211: . min - the minimum value in the entire contour
212: . max - the maximum value in the entire contour
213: - v - the data
215: Options Database Key:
216: . -draw_x_shared_colormap - Activates private colormap
218: Level: advanced
220: Note:
221: This is a lower level support routine, usually the user will call
222: `PetscDrawTensorContour()`.
224: .seealso: `PetscDraw`, `PetscDrawTensorContour()`
225: @*/
226: PetscErrorCode PetscDrawTensorContourPatch(PetscDraw draw, int m, int n, PetscReal *x, PetscReal *y, PetscReal min, PetscReal max, PetscReal *v)
227: {
228: int c1, c2, c3, c4, i, j;
229: PetscReal x1, x2, x3, x4, y_1, y2, y3, y4;
231: PetscFunctionBegin;
233: /* PetscDraw the contour plot patch */
234: for (j = 0; j < n - 1; j++) {
235: for (i = 0; i < m - 1; i++) {
236: x1 = x[i];
237: y_1 = y[j];
238: c1 = PetscDrawRealToColor(v[i + j * m], min, max);
239: x2 = x[i + 1];
240: y2 = y_1;
241: c2 = PetscDrawRealToColor(v[i + j * m + 1], min, max);
242: x3 = x2;
243: y3 = y[j + 1];
244: c3 = PetscDrawRealToColor(v[i + j * m + 1 + m], min, max);
245: x4 = x1;
246: y4 = y3;
247: c4 = PetscDrawRealToColor(v[i + j * m + m], min, max);
249: PetscCall(PetscDrawTriangle(draw, x1, y_1, x2, y2, x3, y3, c1, c2, c3));
250: PetscCall(PetscDrawTriangle(draw, x1, y_1, x3, y3, x4, y4, c1, c3, c4));
251: }
252: }
253: PetscFunctionReturn(PETSC_SUCCESS);
254: }