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: }