Actual source code: dviewp.c

petsc-3.10.5 2019-03-28
Report Typos and Errors

  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 on PetscDraw

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

 19:    Level: advanced

 21:    Concepts: drawing^in subset of window
 22:    Concepts: graphics^in subset of window

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

 31:   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",(double)xl,(double)yl,(double)xr,(double)yr);
 32:   draw->port_xl = xl; draw->port_yl = yl;
 33:   draw->port_xr = xr; draw->port_yr = yr;
 34:   if (draw->ops->setviewport) {
 35:     (*draw->ops->setviewport)(draw,xl,yl,xr,yr);
 36:   }
 37:   return(0);
 38: }

 40: /*@
 41:    PetscDrawGetViewPort - Gets the portion of the window (page) to which draw
 42:    routines will write.

 44:    Collective on PetscDraw

 46:    Input Parameter:
 47: .  draw - the drawing context

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

 54:    Level: advanced

 56:    Concepts: drawing^in subset of window
 57:    Concepts: graphics^in subset of window

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

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

 79:    Collective on PetscDraw

 81:    Input Parameter:
 82: .  draw - the drawing context

 84:    Level: advanced

 86:    Concepts: drawing^in subset of window

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

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

101:   PetscDrawIsNull(draw,&isnull);
102:   if (isnull) return(0);
103:   MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);
104:   MPI_Comm_size(PetscObjectComm((PetscObject)draw),&size);

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

109:   h  = 1.0/n;
110:   xl = (rank % n)*h;
111:   xr = xl + h;
112:   yl = (rank / n)*h;
113:   yr = yl + h;

115:   PetscDrawCollectiveBegin(draw);
116:   PetscDrawLine(draw,xl,yl,xl,yr,PETSC_DRAW_BLACK);
117:   PetscDrawLine(draw,xl,yr,xr,yr,PETSC_DRAW_BLACK);
118:   PetscDrawLine(draw,xr,yr,xr,yl,PETSC_DRAW_BLACK);
119:   PetscDrawLine(draw,xr,yl,xl,yl,PETSC_DRAW_BLACK);
120:   PetscDrawCollectiveEnd(draw);
121:   PetscDrawFlush(draw);

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

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

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

137:    Collective on PetscDraw

139:    Input Parameters:
140: +  draw - the drawing context
141: -  nports - the number of ports

143:    Output Parameter:
144: .  ports - a PetscDrawViewPorts context (C structure)

146:    Options Database:
147: .  -draw_ports - display multiple fields in the same window with PetscDrawPorts instead of in seperate windows

149:    Level: advanced

151:    Concepts: drawing^in subset of window

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

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

167:   if (nports < 1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Number of divisions must be positive: %d", nports);
169:   PetscDrawIsNull(draw,&isnull);
170:   if (isnull) {*newports = NULL; return(0);}
171:   MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);

173:   PetscNew(&ports); *newports = ports;
174:   ports->draw = draw;
175:   ports->nports = nports;
176:   PetscObjectReference((PetscObject)draw);
177:   /* save previous drawport of window */
178:   PetscDrawGetViewPort(draw,&ports->port_xl,&ports->port_yl,&ports->port_xr,&ports->port_yr);

180:   n = (PetscInt)(.1 + PetscSqrtReal((PetscReal)nports));
181:   while (n*n < nports) n++;
182:   h = 1.0/n;

184:   PetscMalloc4(n*n,&xl,n*n,&xr,n*n,&yl,n*n,&yr);
185:   ports->xl = xl;
186:   ports->xr = xr;
187:   ports->yl = yl;
188:   ports->yr = yr;

190:   PetscDrawSetCoordinates(draw,0.0,0.0,1.0,1.0);
191:   PetscDrawCollectiveBegin(draw);
192:   for (i=0; i<n*n; i++) {
193:     xl[i] = (i % n)*h;
194:     xr[i] = xl[i] + h;
195:     yl[i] = (i / n)*h;
196:     yr[i] = yl[i] + h;

198:     if (!rank) {
199:       PetscDrawLine(draw,xl[i],yl[i],xl[i],yr[i],PETSC_DRAW_BLACK);
200:       PetscDrawLine(draw,xl[i],yr[i],xr[i],yr[i],PETSC_DRAW_BLACK);
201:       PetscDrawLine(draw,xr[i],yr[i],xr[i],yl[i],PETSC_DRAW_BLACK);
202:       PetscDrawLine(draw,xr[i],yl[i],xl[i],yl[i],PETSC_DRAW_BLACK);
203:     }

205:     xl[i] += .05*h;
206:     xr[i] -= .05*h;
207:     yl[i] += .05*h;
208:     yr[i] -= .05*h;
209:   }
210:   PetscDrawCollectiveEnd(draw);
211:   PetscDrawFlush(draw);
212:   return(0);
213: }

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

220:    Collective on PetscDraw

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

227:    Output Parameter:
228: .  ports - a PetscDrawViewPorts context (C structure)

230:    Level: advanced

232:    Concepts: drawing^in subset of window

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

236: @*/
237: PetscErrorCode  PetscDrawViewPortsCreateRect(PetscDraw draw,PetscInt nx,PetscInt ny,PetscDrawViewPorts **newports)
238: {
239:   PetscDrawViewPorts *ports;
240:   PetscReal          *xl,*xr,*yl,*yr,hx,hy;
241:   PetscInt           i,j,k,n;
242:   PetscBool          isnull;
243:   PetscMPIInt        rank;
244:   PetscErrorCode     ierr;

248:   if ((nx < 1) || (ny < 1)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Number of divisions must be positive: %d x %d", nx, ny);
250:   PetscDrawIsNull(draw,&isnull);
251:   if (isnull) {*newports = NULL; return(0);}
252:   MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);

254:   n  = nx*ny;
255:   hx = 1.0/nx;
256:   hy = 1.0/ny;
257:   PetscNew(&ports); *newports = ports;
258:   ports->draw = draw;
259:   ports->nports = n;
260:   PetscObjectReference((PetscObject) draw);
261:   /* save previous drawport of window */
262:   PetscDrawGetViewPort(draw,&ports->port_xl,&ports->port_yl,&ports->port_xr,&ports->port_yr);

264:   PetscMalloc4(n,&xl,n,&xr,n,&yl,n,&yr);
265:   ports->xr = xr;
266:   ports->xl = xl;
267:   ports->yl = yl;
268:   ports->yr = yr;

270:   PetscDrawSetCoordinates(draw,0.0,0.0,1.0,1.0);
271:   PetscDrawCollectiveBegin(draw);
272:   for (i = 0; i < nx; i++) {
273:     for (j = 0; j < ny; j++) {
274:       k = j*nx+i;

276:       xl[k] = i*hx;
277:       xr[k] = xl[k] + hx;
278:       yl[k] = j*hy;
279:       yr[k] = yl[k] + hy;

281:       if (!rank) {
282:         PetscDrawLine(draw,xl[k],yl[k],xl[k],yr[k],PETSC_DRAW_BLACK);
283:         PetscDrawLine(draw,xl[k],yr[k],xr[k],yr[k],PETSC_DRAW_BLACK);
284:         PetscDrawLine(draw,xr[k],yr[k],xr[k],yl[k],PETSC_DRAW_BLACK);
285:         PetscDrawLine(draw,xr[k],yl[k],xl[k],yl[k],PETSC_DRAW_BLACK);
286:       }

288:       xl[k] += .05*hx;
289:       xr[k] -= .05*hx;
290:       yl[k] += .05*hy;
291:       yr[k] -= .05*hy;
292:     }
293:   }
294:   PetscDrawCollectiveEnd(draw);
295:   PetscDrawFlush(draw);
296:   return(0);
297: }

299: /*@C
300:    PetscDrawViewPortsDestroy - frees a PetscDrawViewPorts object

302:    Collective on PetscDraw inside PetscDrawViewPorts

304:    Input Parameter:
305: .  ports - the PetscDrawViewPorts object

307:    Level: advanced

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

311: @*/
312: PetscErrorCode  PetscDrawViewPortsDestroy(PetscDrawViewPorts *ports)
313: {

317:   if (!ports) return(0);
319:   /* reset Drawport of Window back to previous value */
320:   PetscDrawSetViewPort(ports->draw,ports->port_xl,ports->port_yl,ports->port_xr,ports->port_yr);
321:   PetscDrawDestroy(&ports->draw);
322:   PetscFree4(ports->xl,ports->xr,ports->yl,ports->yr);
323:   PetscFree(ports);
324:   return(0);
325: }

327: /*@C
328:    PetscDrawViewPortsSet - sets a draw object to use a particular subport

330:    Logically Collective on PetscDraw inside PetscDrawViewPorts

332:    Input Parameter:
333: +  ports - the PetscDrawViewPorts object
334: -  port - the port number, from 0 to nports-1

336:    Level: advanced

338:    Concepts: drawing^in subset of window

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

342: @*/
343: PetscErrorCode  PetscDrawViewPortsSet(PetscDrawViewPorts *ports,PetscInt port)
344: {

348:   if (!ports) return(0);
350:   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-1);
351:   PetscDrawSetViewPort(ports->draw,ports->xl[port],ports->yl[port],ports->xr[port],ports->yr[port]);
352:   return(0);
353: }