Actual source code: dviewp.c

petsc-3.4.4 2014-03-13
  2: /*
  3:        Provides the calling sequences for all the basic PetscDraw routines.
  4: */
  5: #include <petsc-private/drawimpl.h>  /*I "petscdraw.h" I*/

  9: /*@
 10:    PetscDrawSetViewPort - Sets the portion of the window (page) to which draw
 11:    routines will write.

 13:    Collective on PetscDraw

 15:    Input Parameters:
 16: +  xl,yl,xr,yr - upper right and lower left corners of subwindow
 17:                  These numbers must always be between 0.0 and 1.0.
 18:                  Lower left corner is (0,0).
 19: -  draw - the drawing context

 21:    Level: advanced

 23:    Concepts: drawing^in subset of window
 24:    Concepts: graphics^in subset of window

 26: @*/
 27: PetscErrorCode  PetscDrawSetViewPort(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr)
 28: {

 33:   if (xl < 0.0 || xr > 1.0 || yl < 0.0 || yr > 1.0 || xr <= xl || yr <= yl) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"ViewPort values must be >= 0 and <= 1: Instead %G %G %G %G",xl,yl,xr,yr);
 34:   draw->port_xl = xl; draw->port_yl = yl;
 35:   draw->port_xr = xr; draw->port_yr = yr;
 36:   if (draw->ops->setviewport) {
 37:     (*draw->ops->setviewport)(draw,xl,yl,xr,yr);
 38:   }
 39:   return(0);
 40: }

 44: /*@
 45:    PetscDrawGetViewPort - Gets the portion of the window (page) to which draw
 46:    routines will write.

 48:    Collective on PetscDraw

 50:    Input Parameter:
 51: .  draw - the drawing context

 53:    Output Parameter:
 54: .  xl,yl,xr,yr - upper right and lower left corners of subwindow
 55:                  These numbers must always be between 0.0 and 1.0.
 56:                  Lower left corner is (0,0).

 58:    Level: advanced

 60:    Concepts: drawing^in subset of window
 61:    Concepts: graphics^in subset of window

 63: @*/
 64: PetscErrorCode  PetscDrawGetViewPort(PetscDraw draw,PetscReal *xl,PetscReal *yl,PetscReal *xr,PetscReal *yr)
 65: {
 68:   *xl = draw->port_xl;
 69:   *yl = draw->port_yl;
 70:   *xr = draw->port_xr;
 71:   *yr = draw->port_yr;
 72:   return(0);
 73: }

 77: /*@
 78:    PetscDrawSplitViewPort - Splits a window shared by several processes into smaller
 79:    view ports. One for each process.

 81:    Collective on PetscDraw

 83:    Input Parameter:
 84: .  draw - the drawing context

 86:    Level: advanced

 88:    Concepts: drawing^in subset of window

 90: .seealso: PetscDrawDivideViewPort(), PetscDrawSetViewPort()

 92: @*/
 93: PetscErrorCode  PetscDrawSplitViewPort(PetscDraw draw)
 94: {
 96:   PetscMPIInt    rank,size;
 97:   PetscInt       n;
 98:   PetscBool      isnull;
 99:   PetscReal      xl,xr,yl,yr,h;

103:   PetscObjectTypeCompare((PetscObject)draw,PETSC_DRAW_NULL,&isnull);
104:   if (isnull) return(0);

106:   MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);
107:   MPI_Comm_size(PetscObjectComm((PetscObject)draw),&size);

109:   n = (PetscInt)(.1 + PetscSqrtReal((PetscReal)size));
110:   while (n*n < size) n++;

112:   h  = 1.0/n;
113:   xl = (rank % n)*h;
114:   xr = xl + h;
115:   yl = (rank/n)*h;
116:   yr = yl + h;

118:   PetscDrawLine(draw,xl,yl,xl,yr,PETSC_DRAW_BLACK);
119:   PetscDrawLine(draw,xl,yr,xr,yr,PETSC_DRAW_BLACK);
120:   PetscDrawLine(draw,xr,yr,xr,yl,PETSC_DRAW_BLACK);
121:   PetscDrawLine(draw,xr,yl,xl,yl,PETSC_DRAW_BLACK);
122:   PetscDrawSynchronizedFlush(draw);

124:   draw->port_xl = xl + .1*h;
125:   draw->port_xr = xr - .1*h;
126:   draw->port_yl = yl + .1*h;
127:   draw->port_yr = yr - .1*h;

129:   if (draw->ops->setviewport) {
130:      (*draw->ops->setviewport)(draw,xl,yl,xr,yr);
131:   }
132:   return(0);
133: }

137: /*@C
138:    PetscDrawViewPortsCreate - Splits a window into smaller
139:        view ports. Each processor shares all the viewports.

141:    Collective on PetscDraw

143:    Input Parameters:
144: +  draw - the drawing context
145: -  nports - the number of ports

147:    Output Parameter:
148: .  ports - a PetscDrawViewPorts context (C structure)

150:    Level: advanced

152:    Concepts: drawing^in subset of window

154: .seealso: PetscDrawSplitViewPort(), PetscDrawSetViewPort(), PetscDrawViewPortsSet(), PetscDrawViewPortsDestroy()

156: @*/
157: PetscErrorCode  PetscDrawViewPortsCreate(PetscDraw draw,PetscInt nports,PetscDrawViewPorts **ports)
158: {
159:   PetscInt       i,n;
161:   PetscBool      isnull;
162:   PetscReal      *xl,*xr,*yl,*yr,h;

167:   PetscObjectTypeCompare((PetscObject)draw,PETSC_DRAW_NULL,&isnull);
168:   if (isnull) {
169:     *ports = NULL;
170:     return(0);
171:   }

173:   PetscNew(PetscDrawViewPorts,ports);
174:   (*ports)->draw   = draw;
175:   (*ports)->nports = nports;

177:   PetscObjectReference((PetscObject)draw);

179:   n = (PetscInt)(.1 + PetscSqrtReal((PetscReal)nports));
180:   while (n*n < nports) n++;

182:   PetscMalloc(n*n*sizeof(PetscReal),&xl);(*ports)->xl = xl;
183:   PetscMalloc(n*n*sizeof(PetscReal),&xr);(*ports)->xr = xr;
184:   PetscMalloc(n*n*sizeof(PetscReal),&yl);(*ports)->yl = yl;
185:   PetscMalloc(n*n*sizeof(PetscReal),&yr);(*ports)->yr = yr;

187:   h = 1.0/n;

189:   for (i=0; i<n*n; i++) {
190:     xl[i] = (i % n)*h;
191:     xr[i] = xl[i] + h;
192:     yl[i] = (i/n)*h;
193:     yr[i] = yl[i] + h;

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);

200:     xl[i] += .1*h;
201:     xr[i] -= .1*h;
202:     yl[i] += .1*h;
203:     yr[i] -= .1*h;
204:   }
205:   /* save previous drawport of window */
206:   PetscDrawGetViewPort(draw,&(*ports)->port_xl,&(*ports)->port_yl,&(*ports)->port_xr,&(*ports)->port_yr);
207:   /* PetscDrawSynchronizedFlush(draw);*/  /* this causes flicker */
208:   return(0);
209: }

213: /*@C
214:    PetscDrawViewPortsCreateRect - Splits a window into smaller
215:        view ports. Each processor shares all the viewports. The number
216:        of views in the x- and y-directions is specified.

218:    Collective on PetscDraw

220:    Input Parameters:
221: +  draw - the drawing context
222: .  nx - the number of x divisions
223: -  ny - the number of y divisions

225:    Output Parameter:
226: .  ports - a PetscDrawViewPorts context (C structure)

228:    Level: advanced

230:    Concepts: drawing^in subset of window

232: .seealso: PetscDrawSplitViewPort(), PetscDrawSetViewPort(), PetscDrawViewPortsSet(), PetscDrawViewPortsDestroy()

234: @*/
235: PetscErrorCode  PetscDrawViewPortsCreateRect(PetscDraw draw,PetscInt nx,PetscInt ny,PetscDrawViewPorts **ports)
236: {
237:   PetscReal      *xl, *xr, *yl, *yr, hx, hy;
238:   PetscBool      isnull;
239:   PetscInt       i, j, n;

244:   if ((nx < 1) || (ny < 1)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Number of divisions must be positive: %d x %d", nx, ny);
245:   PetscObjectTypeCompare((PetscObject) draw, PETSC_DRAW_NULL, &isnull);
246:   if (isnull) {
247:     *ports = NULL;
248:     return(0);
249:   }
250:   n    = nx*ny;
251:   hx   = 1.0/nx;
252:   hy   = 1.0/ny;
253:   PetscNew(PetscDrawViewPorts, ports);

255:   (*ports)->draw   = draw;
256:   (*ports)->nports = n;

258:   PetscObjectReference((PetscObject) draw);
259:   PetscMalloc(n*sizeof(PetscReal), &xl);(*ports)->xl = xl;
260:   PetscMalloc(n*sizeof(PetscReal), &xr);(*ports)->xr = xr;
261:   PetscMalloc(n*sizeof(PetscReal), &yl);(*ports)->yl = yl;
262:   PetscMalloc(n*sizeof(PetscReal), &yr);(*ports)->yr = yr;
263:   for (i = 0; i < nx; i++) {
264:     for (j = 0; j < ny; j++) {
265:       PetscInt k = j*nx+i;

267:       xl[k] = i*hx;
268:       xr[k] = xl[k] + hx;
269:       yl[k] = j*hy;
270:       yr[k] = yl[k] + hy;

272:       PetscDrawLine(draw,xl[k],yl[k],xl[k],yr[k],PETSC_DRAW_BLACK);
273:       PetscDrawLine(draw,xl[k],yr[k],xr[k],yr[k],PETSC_DRAW_BLACK);
274:       PetscDrawLine(draw,xr[k],yr[k],xr[k],yl[k],PETSC_DRAW_BLACK);
275:       PetscDrawLine(draw,xr[k],yl[k],xl[k],yl[k],PETSC_DRAW_BLACK);

277:       xl[k] += .01*hx;
278:       xr[k] -= .01*hx;
279:       yl[k] += .01*hy;
280:       yr[k] -= .01*hy;
281:     }
282:   }
283:   PetscDrawGetViewPort(draw,&(*ports)->port_xl,&(*ports)->port_yl,&(*ports)->port_xr,&(*ports)->port_yr);
284:   /* PetscDrawSynchronizedFlush(draw); */  /* this causes flicker */
285:   return(0);
286: }

290: /*@C
291:    PetscDrawViewPortsDestroy - frees a PetscDrawViewPorts object

293:    Collective on PetscDraw inside PetscDrawViewPorts

295:    Input Parameter:
296: .  ports - the PetscDrawViewPorts object

298:    Level: advanced

300: .seealso: PetscDrawSplitViewPort(), PetscDrawSetViewPort(), PetscDrawViewPortsSet(), PetscDrawViewPortsCreate()

302: @*/
303: PetscErrorCode  PetscDrawViewPortsDestroy(PetscDrawViewPorts *ports)
304: {

308:   if (!ports) return(0);
309:   /* reset Drawport of Window back to previous value */
310:   PetscDrawSetViewPort(ports->draw,ports->port_xl,ports->port_yl,ports->port_xr,ports->port_yr);
311:   PetscDrawDestroy(&ports->draw);
312:   PetscFree(ports->xl);
313:   PetscFree(ports->xr);
314:   PetscFree(ports->yl);
315:   PetscFree(ports->yr);
316:   PetscFree(ports);
317:   return(0);
318: }

322: /*@C
323:    PetscDrawViewPortsSet - sets a draw object to use a particular subport

325:    Logically Collective on PetscDraw inside PetscDrawViewPorts

327:    Input Parameter:
328: +  ports - the PetscDrawViewPorts object
329: -  port - the port number, from 0 to nports-1

331:    Level: advanced

333:    Concepts: drawing^in subset of window

335: .seealso: PetscDrawSplitViewPort(), PetscDrawSetViewPort(), PetscDrawViewPortsDestroy(), PetscDrawViewPortsCreate()

337: @*/
338: PetscErrorCode  PetscDrawViewPortsSet(PetscDrawViewPorts *ports,PetscInt port)
339: {

343:   if (ports) {
344:     if (port < 0 || port > ports->nports-1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Port is out of range requested %d from 0 to %d\n",port,ports->nports);
345:     PetscDrawSetViewPort(ports->draw,ports->xl[port],ports->yl[port],ports->xr[port],ports->yr[port]);
346:   }
347:   return(0);
348: }