Actual source code: dviewp.c
2: /*
3: Provides the calling sequences for all the basic PetscDraw routines.
4: */
5: #include <petsc/private/drawimpl.h>
7: /*@
8: PetscDrawSetViewPort - Sets the portion of the window (page) to which draw
9: routines will write.
11: Collective
13: Input Parameters:
14: + xl - the horizontal coordinate of the lower left corner of the subwindow.
15: . yl - the vertical coordinate of the lower left corner of the subwindow.
16: . xr - the horizontal coordinate of the upper right corner of the subwindow.
17: . yr - the vertical coordinate of the upper right corner of the subwindow.
18: - draw - the drawing context
20: Notes:
21: These numbers must always be between 0.0 and 1.0.
23: Lower left corner is (0,0).
25: Level: advanced
27: .seealso: `PetscDrawGetViewPort(), ``PetscDraw`, `PetscDrawSplitViewPort()`, `PetscDrawViewPortsCreate()`
28: @*/
29: PetscErrorCode PetscDrawSetViewPort(PetscDraw draw, PetscReal xl, PetscReal yl, PetscReal xr, PetscReal yr)
30: {
33: draw->port_xl = xl;
34: draw->port_yl = yl;
35: draw->port_xr = xr;
36: draw->port_yr = yr;
37: PetscTryTypeMethod(draw, setviewport, xl, yl, xr, yr);
38: return 0;
39: }
41: /*@
42: PetscDrawGetViewPort - Gets the portion of the window (page) to which draw
43: routines will write.
45: Collective
47: Input Parameter:
48: . draw - the drawing context
50: Output Parameters:
51: + xl - the horizontal coordinate of the lower left corner of the subwindow.
52: . yl - the vertical coordinate of the lower left corner of the subwindow.
53: . xr - the horizontal coordinate of the upper right corner of the subwindow.
54: - yr - the vertical coordinate of the upper right corner of the subwindow.
56: Notes:
57: These numbers must always be between 0.0 and 1.0.
59: Lower left corner is (0,0).
61: Level: advanced
63: .seealso: `PetscDraw`, `PetscDrawSplitViewPort()`, `PetscDrawSetViewPort()`
64: @*/
65: PetscErrorCode PetscDrawGetViewPort(PetscDraw draw, PetscReal *xl, PetscReal *yl, PetscReal *xr, PetscReal *yr)
66: {
72: *xl = draw->port_xl;
73: *yl = draw->port_yl;
74: *xr = draw->port_xr;
75: *yr = draw->port_yr;
76: return 0;
77: }
79: /*@
80: PetscDrawSplitViewPort - Splits a window shared by several processes into smaller
81: view ports. One for each process.
83: Collective
85: Input Parameter:
86: . draw - the drawing context
88: Level: advanced
90: .seealso: `PetscDrawDivideViewPort()`, `PetscDrawSetViewPort()`
91: @*/
92: PetscErrorCode PetscDrawSplitViewPort(PetscDraw draw)
93: {
94: PetscMPIInt rank, size;
95: PetscInt n;
96: PetscBool isnull;
97: PetscReal xl, xr, yl, yr, h;
100: PetscDrawIsNull(draw, &isnull);
101: if (isnull) return 0;
102: MPI_Comm_rank(PetscObjectComm((PetscObject)draw), &rank);
103: MPI_Comm_size(PetscObjectComm((PetscObject)draw), &size);
105: n = (PetscInt)(.1 + PetscSqrtReal((PetscReal)size));
106: while (n * n < size) n++;
108: h = 1.0 / n;
109: xl = (rank % n) * h;
110: xr = xl + h;
111: yl = (rank / n) * h;
112: yr = yl + h;
114: PetscDrawCollectiveBegin(draw);
115: PetscDrawLine(draw, xl, yl, xl, yr, PETSC_DRAW_BLACK);
116: PetscDrawLine(draw, xl, yr, xr, yr, PETSC_DRAW_BLACK);
117: PetscDrawLine(draw, xr, yr, xr, yl, PETSC_DRAW_BLACK);
118: PetscDrawLine(draw, xr, yl, xl, yl, PETSC_DRAW_BLACK);
119: PetscDrawCollectiveEnd(draw);
120: PetscDrawFlush(draw);
122: draw->port_xl = xl + .05 * h;
123: draw->port_xr = xr - .05 * h;
124: draw->port_yl = yl + .05 * h;
125: draw->port_yr = yr - .05 * h;
127: PetscTryTypeMethod(draw, setviewport, xl, yl, xr, yr);
128: return 0;
129: }
131: /*@C
132: PetscDrawViewPortsCreate - Splits a window into smaller view ports. Each processor shares all the viewports.
134: Collective
136: Input Parameters:
137: + draw - the drawing context
138: - nports - the number of ports
140: Output Parameter:
141: . ports - a `PetscDrawViewPorts` context (C structure)
143: Options Database Key:
144: . -draw_ports - display multiple fields in the same window with PetscDrawPorts() instead of in separate windows
146: Level: advanced
148: .seealso: `PetscDrawSplitViewPort()`, `PetscDrawSetViewPort()`, `PetscDrawViewPortsSet()`, `PetscDrawViewPortsDestroy()`
149: @*/
150: PetscErrorCode PetscDrawViewPortsCreate(PetscDraw draw, PetscInt nports, PetscDrawViewPorts **newports)
151: {
152: PetscDrawViewPorts *ports;
153: PetscInt i, n;
154: PetscBool isnull;
155: PetscMPIInt rank;
156: PetscReal *xl, *xr, *yl, *yr, h;
161: PetscDrawIsNull(draw, &isnull);
162: if (isnull) {
163: *newports = NULL;
164: return 0;
165: }
166: MPI_Comm_rank(PetscObjectComm((PetscObject)draw), &rank);
168: PetscNew(&ports);
169: *newports = ports;
170: ports->draw = draw;
171: ports->nports = nports;
172: PetscObjectReference((PetscObject)draw);
173: /* save previous drawport of window */
174: PetscDrawGetViewPort(draw, &ports->port_xl, &ports->port_yl, &ports->port_xr, &ports->port_yr);
176: n = (PetscInt)(.1 + PetscSqrtReal((PetscReal)nports));
177: while (n * n < nports) n++;
178: h = 1.0 / n;
180: PetscMalloc4(n * n, &xl, n * n, &xr, n * n, &yl, n * n, &yr);
181: ports->xl = xl;
182: ports->xr = xr;
183: ports->yl = yl;
184: ports->yr = yr;
186: PetscDrawSetCoordinates(draw, 0.0, 0.0, 1.0, 1.0);
187: PetscDrawCollectiveBegin(draw);
188: for (i = 0; i < n * n; i++) {
189: xl[i] = (i % n) * h;
190: xr[i] = xl[i] + h;
191: yl[i] = (i / n) * h;
192: yr[i] = yl[i] + h;
194: if (rank == 0) {
195: PetscDrawLine(draw, xl[i], yl[i], xl[i], yr[i], PETSC_DRAW_BLACK);
196: PetscDrawLine(draw, xl[i], yr[i], xr[i], yr[i], PETSC_DRAW_BLACK);
197: PetscDrawLine(draw, xr[i], yr[i], xr[i], yl[i], PETSC_DRAW_BLACK);
198: PetscDrawLine(draw, xr[i], yl[i], xl[i], yl[i], PETSC_DRAW_BLACK);
199: }
201: xl[i] += .05 * h;
202: xr[i] -= .05 * h;
203: yl[i] += .05 * h;
204: yr[i] -= .05 * h;
205: }
206: PetscDrawCollectiveEnd(draw);
207: PetscDrawFlush(draw);
208: return 0;
209: }
211: /*@C
212: PetscDrawViewPortsCreateRect - Splits a window into smaller
213: view ports. Each processor shares all the viewports. The number
214: of views in the x- and y-directions is specified.
216: Collective
218: Input Parameters:
219: + draw - the drawing context
220: . nx - the number of x divisions
221: - ny - the number of y divisions
223: Output Parameter:
224: . ports - a `PetscDrawViewPorts` context (C structure)
226: Level: advanced
228: .seealso: `PetscDrawSplitViewPort()`, `PetscDrawSetViewPort()`, `PetscDrawViewPortsSet()`, `PetscDrawViewPortsDestroy()`, `PetscDrawViewPorts`
229: @*/
230: PetscErrorCode PetscDrawViewPortsCreateRect(PetscDraw draw, PetscInt nx, PetscInt ny, PetscDrawViewPorts **newports)
231: {
232: PetscDrawViewPorts *ports;
233: PetscReal *xl, *xr, *yl, *yr, hx, hy;
234: PetscInt i, j, k, n;
235: PetscBool isnull;
236: PetscMPIInt rank;
241: PetscDrawIsNull(draw, &isnull);
242: if (isnull) {
243: *newports = NULL;
244: return 0;
245: }
246: MPI_Comm_rank(PetscObjectComm((PetscObject)draw), &rank);
248: n = nx * ny;
249: hx = 1.0 / nx;
250: hy = 1.0 / ny;
251: PetscNew(&ports);
252: *newports = ports;
253: ports->draw = draw;
254: ports->nports = n;
255: PetscObjectReference((PetscObject)draw);
256: /* save previous drawport of window */
257: PetscDrawGetViewPort(draw, &ports->port_xl, &ports->port_yl, &ports->port_xr, &ports->port_yr);
259: PetscMalloc4(n, &xl, n, &xr, n, &yl, n, &yr);
260: ports->xr = xr;
261: ports->xl = xl;
262: ports->yl = yl;
263: ports->yr = yr;
265: PetscDrawSetCoordinates(draw, 0.0, 0.0, 1.0, 1.0);
266: PetscDrawCollectiveBegin(draw);
267: for (i = 0; i < nx; i++) {
268: for (j = 0; j < ny; j++) {
269: k = j * nx + i;
271: xl[k] = i * hx;
272: xr[k] = xl[k] + hx;
273: yl[k] = j * hy;
274: yr[k] = yl[k] + hy;
276: if (rank == 0) {
277: PetscDrawLine(draw, xl[k], yl[k], xl[k], yr[k], PETSC_DRAW_BLACK);
278: PetscDrawLine(draw, xl[k], yr[k], xr[k], yr[k], PETSC_DRAW_BLACK);
279: PetscDrawLine(draw, xr[k], yr[k], xr[k], yl[k], PETSC_DRAW_BLACK);
280: PetscDrawLine(draw, xr[k], yl[k], xl[k], yl[k], PETSC_DRAW_BLACK);
281: }
283: xl[k] += .05 * hx;
284: xr[k] -= .05 * hx;
285: yl[k] += .05 * hy;
286: yr[k] -= .05 * hy;
287: }
288: }
289: PetscDrawCollectiveEnd(draw);
290: PetscDrawFlush(draw);
291: return 0;
292: }
294: /*@C
295: PetscDrawViewPortsDestroy - frees a `PetscDrawViewPorts` object
297: Collective on the PetscDraw inside ports
299: Input Parameter:
300: . ports - the `PetscDrawViewPorts` object
302: Level: advanced
304: .seealso: `PetscDrawViewPorts`, `PetscDrawSplitViewPort()`, `PetscDrawSetViewPort()`, `PetscDrawViewPortsSet()`, `PetscDrawViewPortsCreate()`
305: @*/
306: PetscErrorCode PetscDrawViewPortsDestroy(PetscDrawViewPorts *ports)
307: {
308: if (!ports) return 0;
310: /* reset Drawport of Window back to previous value */
311: PetscDrawSetViewPort(ports->draw, ports->port_xl, ports->port_yl, ports->port_xr, ports->port_yr);
312: PetscDrawDestroy(&ports->draw);
313: PetscFree4(ports->xl, ports->xr, ports->yl, ports->yr);
314: PetscFree(ports);
315: return 0;
316: }
318: /*@C
319: PetscDrawViewPortsSet - sets a draw object to use a particular subport
321: Logically Collective on the `PetscDraw` inside ports
323: Input Parameters:
324: + ports - the `PetscDrawViewPorts` object
325: - port - the port number, from 0 to nports-1
327: Level: advanced
329: .seealso: `PetscDrawViewPorts`, `PetscDrawSplitViewPort()`, `PetscDrawSetViewPort()`, `PetscDrawViewPortsDestroy()`, `PetscDrawViewPortsCreate()`
330: @*/
331: PetscErrorCode PetscDrawViewPortsSet(PetscDrawViewPorts *ports, PetscInt port)
332: {
333: if (!ports) return 0;
336: PetscDrawSetViewPort(ports->draw, ports->xl[port], ports->yl[port], ports->xr[port], ports->yr[port]);
337: return 0;
338: }