Actual source code: dtri.c
2: #include <petsc/private/drawimpl.h>
4: /*@
5: PetscDrawTriangle - draws a triangle onto a drawable.
7: Not Collective
9: Input Parameters:
10: + draw - the drawing context
11: . x1 - coordinate of the first vertex
12: . y1 - coordinate of the first vertex
13: . x2 - coordinate of the second vertex
14: . y2 - coordinate of the second vertex
15: . x3 - coordinate of the third vertex
16: . y3 - coordinate of the third vertex
17: . c1 - color of the first vertex
18: . c2 - color of the second vertex
19: - c3 - color of the third vertext
21: Level: beginner
23: .seealso: `PetscDraw`, `PetscDrawLine()`, `PetscDrawRectangle()`, `PetscDrawEllipse()`, `PetscDrawMarker()`, `PetscDrawPoint()`, `PetscDrawArrow()`
24: @*/
25: PetscErrorCode PetscDrawTriangle(PetscDraw draw, PetscReal x1, PetscReal y_1, PetscReal x2, PetscReal y2, PetscReal x3, PetscReal y3, int c1, int c2, int c3)
26: {
27: PetscFunctionBegin;
29: PetscUseTypeMethod(draw, triangle, x1, y_1, x2, y2, x3, y3, c1, c2, c3);
30: PetscFunctionReturn(PETSC_SUCCESS);
31: }
33: /*@
34: PetscDrawScalePopup - draws a contour scale window.
36: Collective
38: Input Parameters:
39: + popup - the window (often a window obtained via `PetscDrawGetPopup()`
40: . min - minimum value being plotted
41: - max - maximum value being plotted
43: Level: intermediate
45: Note:
46: All processors that share the draw MUST call this routine
48: .seealso: `PetscDraw`, `PetscDrawGetPopup()`, `PetscDrawTensorContour()`
49: @*/
50: PetscErrorCode PetscDrawScalePopup(PetscDraw popup, PetscReal min, PetscReal max)
51: {
52: PetscBool isnull;
53: PetscReal xl = 0.0, yl = 0.0, xr = 1.0, yr = 1.0;
54: PetscMPIInt rank;
55: int i;
56: char string[32];
58: PetscFunctionBegin;
59: if (!popup) PetscFunctionReturn(PETSC_SUCCESS);
61: PetscCall(PetscDrawIsNull(popup, &isnull));
62: if (isnull) PetscFunctionReturn(PETSC_SUCCESS);
63: PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)popup), &rank));
65: PetscCall(PetscDrawCheckResizedWindow(popup));
66: PetscCall(PetscDrawClear(popup));
67: PetscCall(PetscDrawSetTitle(popup, "Contour Scale"));
68: PetscCall(PetscDrawSetCoordinates(popup, xl, yl, xr, yr));
69: PetscDrawCollectiveBegin(popup);
70: if (rank == 0) {
71: for (i = 0; i < 10; i++) {
72: int c = PetscDrawRealToColor((PetscReal)i / 9, 0, 1);
73: PetscCall(PetscDrawRectangle(popup, xl, yl, xr, yr, c, c, c, c));
74: yl += 0.1;
75: }
76: for (i = 0; i < 10; i++) {
77: PetscReal value = min + i * (max - min) / 9;
78: /* look for a value that should be zero, but is not due to round-off */
79: if (PetscAbsReal(value) < 1.e-10 && max - min > 1.e-6) value = 0.0;
80: PetscCall(PetscSNPrintf(string, sizeof(string), "%18.16e", (double)value));
81: PetscCall(PetscDrawString(popup, 0.2, 0.02 + i / 10.0, PETSC_DRAW_BLACK, string));
82: }
83: }
84: PetscDrawCollectiveEnd(popup);
85: PetscCall(PetscDrawFlush(popup));
86: PetscCall(PetscDrawSave(popup));
87: PetscFunctionReturn(PETSC_SUCCESS);
88: }
90: typedef struct {
91: int m, n;
92: PetscReal *x, *y, min, max, *v;
93: PetscBool showgrid;
94: } ZoomCtx;
96: static PetscErrorCode PetscDrawTensorContour_Zoom(PetscDraw win, void *dctx)
97: {
98: int i;
99: ZoomCtx *ctx = (ZoomCtx *)dctx;
101: PetscFunctionBegin;
102: PetscCall(PetscDrawTensorContourPatch(win, ctx->m, ctx->n, ctx->x, ctx->y, ctx->min, ctx->max, ctx->v));
103: if (ctx->showgrid) {
104: 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));
105: 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));
106: }
107: PetscFunctionReturn(PETSC_SUCCESS);
108: }
110: /*@C
111: PetscDrawTensorContour - draws a contour plot for a two-dimensional array
113: Collective on draw, but draw must be sequential
115: Input Parameters:
116: + draw - the draw context
117: . m,n - the global number of mesh points in the x and y directions
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,n - the number of local mesh points in the x and y direction
201: . x - the horizontal locations of the local mesh points
202: . y - the vertical locations of the local mesh points
203: . min - the minimum value in the entire contour
204: . max - the maximum value in the entire contour
205: - v - the data
207: Options Database Key:
208: . -draw_x_shared_colormap - Activates private colormap
210: Level: advanced
212: Note:
213: This is a lower level support routine, usually the user will call
214: `PetscDrawTensorContour()`.
216: .seealso: `PetscDraw`, `PetscDrawTensorContour()`
217: @*/
218: PetscErrorCode PetscDrawTensorContourPatch(PetscDraw draw, int m, int n, PetscReal *x, PetscReal *y, PetscReal min, PetscReal max, PetscReal *v)
219: {
220: int c1, c2, c3, c4, i, j;
221: PetscReal x1, x2, x3, x4, y_1, y2, y3, y4;
223: PetscFunctionBegin;
225: /* PetscDraw the contour plot patch */
226: for (j = 0; j < n - 1; j++) {
227: for (i = 0; i < m - 1; i++) {
228: x1 = x[i];
229: y_1 = y[j];
230: c1 = PetscDrawRealToColor(v[i + j * m], min, max);
231: x2 = x[i + 1];
232: y2 = y_1;
233: c2 = PetscDrawRealToColor(v[i + j * m + 1], min, max);
234: x3 = x2;
235: y3 = y[j + 1];
236: c3 = PetscDrawRealToColor(v[i + j * m + 1 + m], min, max);
237: x4 = x1;
238: y4 = y3;
239: c4 = PetscDrawRealToColor(v[i + j * m + m], min, max);
241: PetscCall(PetscDrawTriangle(draw, x1, y_1, x2, y2, x3, y3, c1, c2, c3));
242: PetscCall(PetscDrawTriangle(draw, x1, y_1, x3, y3, x4, y4, c1, c3, c4));
243: }
244: }
245: PetscFunctionReturn(PETSC_SUCCESS);
246: }