xref: /petsc/src/sys/classes/draw/interface/dtri.c (revision 48a46eb9bd028bec07ec0f396b1a3abb43f14558)
15c6c1daeSBarry Smith 
25c6c1daeSBarry Smith /*
35c6c1daeSBarry Smith        Provides the calling sequences for all the basic PetscDraw routines.
45c6c1daeSBarry Smith */
5af0996ceSBarry Smith #include <petsc/private/drawimpl.h> /*I "petscdraw.h" I*/
65c6c1daeSBarry Smith 
75c6c1daeSBarry Smith /*@
85c6c1daeSBarry Smith    PetscDrawTriangle - PetscDraws a triangle  onto a drawable.
95c6c1daeSBarry Smith 
105c6c1daeSBarry Smith    Not Collective
115c6c1daeSBarry Smith 
125c6c1daeSBarry Smith    Input Parameters:
135c6c1daeSBarry Smith +  draw - the drawing context
145c6c1daeSBarry Smith .  x1,y1,x2,y2,x3,y3 - the coordinates of the vertices
155c6c1daeSBarry Smith -  c1,c2,c3 - the colors of the three vertices in the same order as the xi,yi
165c6c1daeSBarry Smith 
175c6c1daeSBarry Smith    Level: beginner
185c6c1daeSBarry Smith 
19db781477SPatrick Sanan .seealso: `PetscDrawLine()`, `PetscDrawRectangle()`, `PetscDrawEllipse()`, `PetscDrawMarker()`, `PetscDrawPoint()`, `PetscDrawArrow()`
205c6c1daeSBarry Smith @*/
219371c9d4SSatish Balay PetscErrorCode PetscDrawTriangle(PetscDraw draw, PetscReal x1, PetscReal y_1, PetscReal x2, PetscReal y2, PetscReal x3, PetscReal y3, int c1, int c2, int c3) {
225c6c1daeSBarry Smith   PetscFunctionBegin;
235c6c1daeSBarry Smith   PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1);
24dbbe0bcdSBarry Smith   PetscUseTypeMethod(draw, triangle, x1, y_1, x2, y2, x3, y3, c1, c2, c3);
255c6c1daeSBarry Smith   PetscFunctionReturn(0);
265c6c1daeSBarry Smith }
275c6c1daeSBarry Smith 
285c6c1daeSBarry Smith /*@
29ba1e01c4SBarry Smith    PetscDrawScalePopup - draws a contour scale window.
305c6c1daeSBarry Smith 
315c6c1daeSBarry Smith    Collective on PetscDraw
325c6c1daeSBarry Smith 
335c6c1daeSBarry Smith    Input Parameters:
345c6c1daeSBarry Smith +  popup - the window (often a window obtained via PetscDrawGetPopup()
355c6c1daeSBarry Smith .  min - minimum value being plotted
365c6c1daeSBarry Smith -  max - maximum value being plotted
375c6c1daeSBarry Smith 
385c6c1daeSBarry Smith    Level: intermediate
395c6c1daeSBarry Smith 
4095452b02SPatrick Sanan    Notes:
4195452b02SPatrick Sanan     All processors that share the draw MUST call this routine
425c6c1daeSBarry Smith 
43db781477SPatrick Sanan .seealso: `PetscDrawGetPopup()`, `PetscDrawTensorContour()`
44ba1e01c4SBarry Smith 
455c6c1daeSBarry Smith @*/
469371c9d4SSatish Balay PetscErrorCode PetscDrawScalePopup(PetscDraw popup, PetscReal min, PetscReal max) {
475b399a63SLisandro Dalcin   PetscBool   isnull;
4848db01dbSLisandro Dalcin   PetscReal   xl = 0.0, yl = 0.0, xr = 1.0, yr = 1.0;
49e118a51fSLisandro Dalcin   PetscMPIInt rank;
50b05fc000SLisandro Dalcin   int         i;
515c6c1daeSBarry Smith   char        string[32];
525c6c1daeSBarry Smith 
535c6c1daeSBarry Smith   PetscFunctionBegin;
5445f3bb6eSLisandro Dalcin   if (!popup) PetscFunctionReturn(0);
555b399a63SLisandro Dalcin   PetscValidHeaderSpecific(popup, PETSC_DRAW_CLASSID, 1);
569566063dSJacob Faibussowitsch   PetscCall(PetscDrawIsNull(popup, &isnull));
575b399a63SLisandro Dalcin   if (isnull) PetscFunctionReturn(0);
589566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)popup), &rank));
595b399a63SLisandro Dalcin 
609566063dSJacob Faibussowitsch   PetscCall(PetscDrawCheckResizedWindow(popup));
619566063dSJacob Faibussowitsch   PetscCall(PetscDrawClear(popup));
629566063dSJacob Faibussowitsch   PetscCall(PetscDrawSetTitle(popup, "Contour Scale"));
639566063dSJacob Faibussowitsch   PetscCall(PetscDrawSetCoordinates(popup, xl, yl, xr, yr));
64d0609cedSBarry Smith   PetscDrawCollectiveBegin(popup);
65dd400576SPatrick Sanan   if (rank == 0) {
665c6c1daeSBarry Smith     for (i = 0; i < 10; i++) {
67b05fc000SLisandro Dalcin       int c = PetscDrawRealToColor((PetscReal)i / 9, 0, 1);
689566063dSJacob Faibussowitsch       PetscCall(PetscDrawRectangle(popup, xl, yl, xr, yr, c, c, c, c));
6948db01dbSLisandro Dalcin       yl += 0.1;
705c6c1daeSBarry Smith     }
715c6c1daeSBarry Smith     for (i = 0; i < 10; i++) {
7248db01dbSLisandro Dalcin       PetscReal value = min + i * (max - min) / 9;
735c6c1daeSBarry Smith       /* look for a value that should be zero, but is not due to round-off */
745c6c1daeSBarry Smith       if (PetscAbsReal(value) < 1.e-10 && max - min > 1.e-6) value = 0.0;
759566063dSJacob Faibussowitsch       PetscCall(PetscSNPrintf(string, sizeof(string), "%18.16e", (double)value));
769566063dSJacob Faibussowitsch       PetscCall(PetscDrawString(popup, 0.2, 0.02 + i / 10.0, PETSC_DRAW_BLACK, string));
775c6c1daeSBarry Smith     }
78e118a51fSLisandro Dalcin   }
79d0609cedSBarry Smith   PetscDrawCollectiveEnd(popup);
809566063dSJacob Faibussowitsch   PetscCall(PetscDrawFlush(popup));
819566063dSJacob Faibussowitsch   PetscCall(PetscDrawSave(popup));
825c6c1daeSBarry Smith   PetscFunctionReturn(0);
835c6c1daeSBarry Smith }
845c6c1daeSBarry Smith 
855c6c1daeSBarry Smith typedef struct {
865c6c1daeSBarry Smith   int        m, n;
875c6c1daeSBarry Smith   PetscReal *x, *y, min, max, *v;
885c6c1daeSBarry Smith   PetscBool  showgrid;
895c6c1daeSBarry Smith } ZoomCtx;
905c6c1daeSBarry Smith 
919371c9d4SSatish Balay static PetscErrorCode PetscDrawTensorContour_Zoom(PetscDraw win, void *dctx) {
925c6c1daeSBarry Smith   int      i;
935c6c1daeSBarry Smith   ZoomCtx *ctx = (ZoomCtx *)dctx;
945c6c1daeSBarry Smith 
955c6c1daeSBarry Smith   PetscFunctionBegin;
969566063dSJacob Faibussowitsch   PetscCall(PetscDrawTensorContourPatch(win, ctx->m, ctx->n, ctx->x, ctx->y, ctx->min, ctx->max, ctx->v));
975c6c1daeSBarry Smith   if (ctx->showgrid) {
98*48a46eb9SPierre Jolivet     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));
99*48a46eb9SPierre Jolivet     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));
1005c6c1daeSBarry Smith   }
1015c6c1daeSBarry Smith   PetscFunctionReturn(0);
1025c6c1daeSBarry Smith }
1035c6c1daeSBarry Smith 
1045c6c1daeSBarry Smith /*@C
1055c6c1daeSBarry Smith    PetscDrawTensorContour - PetscDraws a contour plot for a two-dimensional array
1065c6c1daeSBarry Smith    that is stored as a PETSc vector.
1075c6c1daeSBarry Smith 
1085c6c1daeSBarry Smith    Collective on PetscDraw, but PetscDraw must be sequential
1095c6c1daeSBarry Smith 
1105c6c1daeSBarry Smith    Input Parameters:
1118f69470aSLisandro Dalcin +   draw  - the draw context
1125c6c1daeSBarry Smith .   m,n   - the global number of mesh points in the x and y directions
1130298fd71SBarry Smith .   xi,yi - the locations of the global mesh points (optional, use NULL
1145c6c1daeSBarry Smith             to indicate uniform spacing on [0,1])
1155c6c1daeSBarry Smith -   V     - the values
1165c6c1daeSBarry Smith 
1175c6c1daeSBarry Smith    Options Database Keys:
1185c6c1daeSBarry Smith +  -draw_x_shared_colormap - Indicates use of private colormap
1195c6c1daeSBarry Smith -  -draw_contour_grid - PetscDraws grid contour
1205c6c1daeSBarry Smith 
1215c6c1daeSBarry Smith    Level: intermediate
1225c6c1daeSBarry Smith 
123db781477SPatrick Sanan .seealso: `PetscDrawTensorContourPatch()`, `PetscDrawScalePopup()`
1245c6c1daeSBarry Smith 
1255c6c1daeSBarry Smith @*/
1269371c9d4SSatish Balay PetscErrorCode PetscDrawTensorContour(PetscDraw draw, int m, int n, const PetscReal xi[], const PetscReal yi[], PetscReal *v) {
1275c6c1daeSBarry Smith   int         N = m * n;
1285c6c1daeSBarry Smith   PetscBool   isnull;
1295c6c1daeSBarry Smith   PetscDraw   popup;
1305c6c1daeSBarry Smith   int         xin = 1, yin = 1, i;
1315c6c1daeSBarry Smith   PetscMPIInt size;
1325c6c1daeSBarry Smith   PetscReal   h;
1335c6c1daeSBarry Smith   ZoomCtx     ctx;
1345c6c1daeSBarry Smith 
1355c6c1daeSBarry Smith   PetscFunctionBegin;
1368f69470aSLisandro Dalcin   PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1);
1379566063dSJacob Faibussowitsch   PetscCall(PetscDrawIsNull(draw, &isnull));
138e118a51fSLisandro Dalcin   if (isnull) PetscFunctionReturn(0);
1399566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)draw), &size));
14008401ef6SPierre Jolivet   PetscCheck(size <= 1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "May only be used with single processor PetscDraw");
14108401ef6SPierre Jolivet   PetscCheck(N > 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n %d and m %d must be positive", m, n);
1425c6c1daeSBarry Smith 
1435c6c1daeSBarry Smith   ctx.v   = v;
1445c6c1daeSBarry Smith   ctx.m   = m;
1455c6c1daeSBarry Smith   ctx.n   = n;
1465c6c1daeSBarry Smith   ctx.max = ctx.min = v[0];
1475c6c1daeSBarry Smith   for (i = 0; i < N; i++) {
1485c6c1daeSBarry Smith     if (ctx.max < ctx.v[i]) ctx.max = ctx.v[i];
1495c6c1daeSBarry Smith     if (ctx.min > ctx.v[i]) ctx.min = ctx.v[i];
1505c6c1daeSBarry Smith   }
1519371c9d4SSatish Balay   if (ctx.max - ctx.min < 1.e-7) {
1529371c9d4SSatish Balay     ctx.min -= 5.e-8;
1539371c9d4SSatish Balay     ctx.max += 5.e-8;
1549371c9d4SSatish Balay   }
1555c6c1daeSBarry Smith 
1565c6c1daeSBarry Smith   /* PetscDraw the scale window */
1579566063dSJacob Faibussowitsch   PetscCall(PetscDrawGetPopup(draw, &popup));
1589566063dSJacob Faibussowitsch   PetscCall(PetscDrawScalePopup(popup, ctx.min, ctx.max));
1595c6c1daeSBarry Smith 
1605c6c1daeSBarry Smith   ctx.showgrid = PETSC_FALSE;
1619566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(((PetscObject)draw)->options, NULL, "-draw_contour_grid", &ctx.showgrid, NULL));
1625c6c1daeSBarry Smith 
1635c6c1daeSBarry Smith   /* fill up x and y coordinates */
1645c6c1daeSBarry Smith   if (!xi) {
1655c6c1daeSBarry Smith     xin = 0;
1669566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(ctx.m, &ctx.x));
1675c6c1daeSBarry Smith     h        = 1.0 / (ctx.m - 1);
1685c6c1daeSBarry Smith     ctx.x[0] = 0.0;
1695c6c1daeSBarry Smith     for (i = 1; i < ctx.m; i++) ctx.x[i] = ctx.x[i - 1] + h;
170a297a907SKarl Rupp   } else ctx.x = (PetscReal *)xi;
171a297a907SKarl Rupp 
1725c6c1daeSBarry Smith   if (!yi) {
1735c6c1daeSBarry Smith     yin = 0;
1749566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(ctx.n, &ctx.y));
1755c6c1daeSBarry Smith     h        = 1.0 / (ctx.n - 1);
1765c6c1daeSBarry Smith     ctx.y[0] = 0.0;
1775c6c1daeSBarry Smith     for (i = 1; i < ctx.n; i++) ctx.y[i] = ctx.y[i - 1] + h;
178a297a907SKarl Rupp   } else ctx.y = (PetscReal *)yi;
1795c6c1daeSBarry Smith 
1809566063dSJacob Faibussowitsch   PetscCall(PetscDrawZoom(draw, PetscDrawTensorContour_Zoom, &ctx));
1815c6c1daeSBarry Smith 
1829566063dSJacob Faibussowitsch   if (!xin) PetscCall(PetscFree(ctx.x));
1839566063dSJacob Faibussowitsch   if (!yin) PetscCall(PetscFree(ctx.y));
1845c6c1daeSBarry Smith   PetscFunctionReturn(0);
1855c6c1daeSBarry Smith }
1865c6c1daeSBarry Smith 
1875c6c1daeSBarry Smith /*@
1885c6c1daeSBarry Smith    PetscDrawTensorContourPatch - PetscDraws a rectangular patch of a contour plot
1895c6c1daeSBarry Smith    for a two-dimensional array.
1905c6c1daeSBarry Smith 
1915c6c1daeSBarry Smith    Not Collective
1925c6c1daeSBarry Smith 
1935c6c1daeSBarry Smith    Input Parameters:
194b05fc000SLisandro Dalcin +  draw - the draw context
1955c6c1daeSBarry Smith .  m,n - the number of local mesh points in the x and y direction
1965c6c1daeSBarry Smith .  x,y - the locations of the local mesh points
197b05fc000SLisandro Dalcin .  min,max - the minimum and maximum value in the entire contour
1985c6c1daeSBarry Smith -  v - the data
1995c6c1daeSBarry Smith 
2005c6c1daeSBarry Smith    Options Database Keys:
2015c6c1daeSBarry Smith .  -draw_x_shared_colormap - Activates private colormap
2025c6c1daeSBarry Smith 
2035c6c1daeSBarry Smith    Level: advanced
2045c6c1daeSBarry Smith 
2055c6c1daeSBarry Smith    Note:
2065c6c1daeSBarry Smith    This is a lower level support routine, usually the user will call
2075c6c1daeSBarry Smith    PetscDrawTensorContour().
2085c6c1daeSBarry Smith 
209db781477SPatrick Sanan .seealso: `PetscDrawTensorContour()`
2105c6c1daeSBarry Smith 
2115c6c1daeSBarry Smith @*/
2129371c9d4SSatish Balay PetscErrorCode PetscDrawTensorContourPatch(PetscDraw draw, int m, int n, PetscReal *x, PetscReal *y, PetscReal min, PetscReal max, PetscReal *v) {
2135c6c1daeSBarry Smith   int       c1, c2, c3, c4, i, j;
214b05fc000SLisandro Dalcin   PetscReal x1, x2, x3, x4, y_1, y2, y3, y4;
2155c6c1daeSBarry Smith 
2165c6c1daeSBarry Smith   PetscFunctionBegin;
2178f69470aSLisandro Dalcin   PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1);
2185c6c1daeSBarry Smith   /* PetscDraw the contour plot patch */
2195c6c1daeSBarry Smith   for (j = 0; j < n - 1; j++) {
2205c6c1daeSBarry Smith     for (i = 0; i < m - 1; i++) {
2219371c9d4SSatish Balay       x1  = x[i];
2229371c9d4SSatish Balay       y_1 = y[j];
2239371c9d4SSatish Balay       c1  = PetscDrawRealToColor(v[i + j * m], min, max);
2249371c9d4SSatish Balay       x2  = x[i + 1];
2259371c9d4SSatish Balay       y2  = y_1;
2269371c9d4SSatish Balay       c2  = PetscDrawRealToColor(v[i + j * m + 1], min, max);
2279371c9d4SSatish Balay       x3  = x2;
2289371c9d4SSatish Balay       y3  = y[j + 1];
2299371c9d4SSatish Balay       c3  = PetscDrawRealToColor(v[i + j * m + 1 + m], min, max);
2309371c9d4SSatish Balay       x4  = x1;
2319371c9d4SSatish Balay       y4  = y3;
2329371c9d4SSatish Balay       c4  = PetscDrawRealToColor(v[i + j * m + m], min, max);
233a297a907SKarl Rupp 
2349566063dSJacob Faibussowitsch       PetscCall(PetscDrawTriangle(draw, x1, y_1, x2, y2, x3, y3, c1, c2, c3));
2359566063dSJacob Faibussowitsch       PetscCall(PetscDrawTriangle(draw, x1, y_1, x3, y3, x4, y4, c1, c3, c4));
2365c6c1daeSBarry Smith     }
2375c6c1daeSBarry Smith   }
2385c6c1daeSBarry Smith   PetscFunctionReturn(0);
2395c6c1daeSBarry Smith }
240