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