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 on PetscDraw
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.
22: Lower left corner is (0,0).
24: Level: advanced
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",(double)xl,(double)yl,(double)xr,(double)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: }
42: /*@
43: PetscDrawGetViewPort - Gets the portion of the window (page) to which draw
44: routines will write.
46: Collective on PetscDraw
48: Input Parameter:
49: . draw - the drawing context
51: Output Parameters:
52: + xl - the horizontal coordinate of the lower left corner of the subwindow.
53: . yl - the vertical coordinate of the lower left corner of the subwindow.
54: . xr - the horizontal coordinate of the upper right corner of the subwindow.
55: - yr - the vertical coordinate of the upper right corner of the subwindow.
57: Notes:
58: These numbers must always be between 0.0 and 1.0.
59: Lower left corner is (0,0).
61: Level: advanced
63: @*/
64: PetscErrorCode PetscDrawGetViewPort(PetscDraw draw,PetscReal *xl,PetscReal *yl,PetscReal *xr,PetscReal *yr)
65: {
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 on PetscDraw
85: Input Parameter:
86: . draw - the drawing context
88: Level: advanced
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: PetscDrawIsNull(draw,&isnull);
104: if (isnull) return(0);
105: MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);
106: MPI_Comm_size(PetscObjectComm((PetscObject)draw),&size);
108: n = (PetscInt)(.1 + PetscSqrtReal((PetscReal)size));
109: while (n*n < size) n++;
111: h = 1.0/n;
112: xl = (rank % n)*h;
113: xr = xl + h;
114: yl = (rank / n)*h;
115: yr = yl + h;
117: PetscDrawCollectiveBegin(draw);
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: PetscDrawCollectiveEnd(draw);
123: PetscDrawFlush(draw);
125: draw->port_xl = xl + .05*h;
126: draw->port_xr = xr - .05*h;
127: draw->port_yl = yl + .05*h;
128: draw->port_yr = yr - .05*h;
130: if (draw->ops->setviewport) {
131: (*draw->ops->setviewport)(draw,xl,yl,xr,yr);
132: }
133: return(0);
134: }
136: /*@C
137: PetscDrawViewPortsCreate - Splits a window into smaller view ports. Each processor shares all the viewports.
139: Collective on PetscDraw
141: Input Parameters:
142: + draw - the drawing context
143: - nports - the number of ports
145: Output Parameter:
146: . ports - a PetscDrawViewPorts context (C structure)
148: Options Database:
149: . -draw_ports - display multiple fields in the same window with PetscDrawPorts() instead of in separate windows
151: Level: advanced
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 == 0) {
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: .seealso: PetscDrawSplitViewPort(), PetscDrawSetViewPort(), PetscDrawViewPortsSet(), PetscDrawViewPortsDestroy()
234: @*/
235: PetscErrorCode PetscDrawViewPortsCreateRect(PetscDraw draw,PetscInt nx,PetscInt ny,PetscDrawViewPorts **newports)
236: {
237: PetscDrawViewPorts *ports;
238: PetscReal *xl,*xr,*yl,*yr,hx,hy;
239: PetscInt i,j,k,n;
240: PetscBool isnull;
241: PetscMPIInt rank;
242: PetscErrorCode ierr;
246: if ((nx < 1) || (ny < 1)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Number of divisions must be positive: %d x %d", nx, ny);
248: PetscDrawIsNull(draw,&isnull);
249: if (isnull) {*newports = NULL; return(0);}
250: MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);
252: n = nx*ny;
253: hx = 1.0/nx;
254: hy = 1.0/ny;
255: PetscNew(&ports); *newports = ports;
256: ports->draw = draw;
257: ports->nports = n;
258: PetscObjectReference((PetscObject) draw);
259: /* save previous drawport of window */
260: PetscDrawGetViewPort(draw,&ports->port_xl,&ports->port_yl,&ports->port_xr,&ports->port_yr);
262: PetscMalloc4(n,&xl,n,&xr,n,&yl,n,&yr);
263: ports->xr = xr;
264: ports->xl = xl;
265: ports->yl = yl;
266: ports->yr = yr;
268: PetscDrawSetCoordinates(draw,0.0,0.0,1.0,1.0);
269: PetscDrawCollectiveBegin(draw);
270: for (i = 0; i < nx; i++) {
271: for (j = 0; j < ny; j++) {
272: k = j*nx+i;
274: xl[k] = i*hx;
275: xr[k] = xl[k] + hx;
276: yl[k] = j*hy;
277: yr[k] = yl[k] + hy;
279: if (rank == 0) {
280: PetscDrawLine(draw,xl[k],yl[k],xl[k],yr[k],PETSC_DRAW_BLACK);
281: PetscDrawLine(draw,xl[k],yr[k],xr[k],yr[k],PETSC_DRAW_BLACK);
282: PetscDrawLine(draw,xr[k],yr[k],xr[k],yl[k],PETSC_DRAW_BLACK);
283: PetscDrawLine(draw,xr[k],yl[k],xl[k],yl[k],PETSC_DRAW_BLACK);
284: }
286: xl[k] += .05*hx;
287: xr[k] -= .05*hx;
288: yl[k] += .05*hy;
289: yr[k] -= .05*hy;
290: }
291: }
292: PetscDrawCollectiveEnd(draw);
293: PetscDrawFlush(draw);
294: return(0);
295: }
297: /*@C
298: PetscDrawViewPortsDestroy - frees a PetscDrawViewPorts object
300: Collective on PetscDraw inside PetscDrawViewPorts
302: Input Parameter:
303: . ports - the PetscDrawViewPorts object
305: Level: advanced
307: .seealso: PetscDrawSplitViewPort(), PetscDrawSetViewPort(), PetscDrawViewPortsSet(), PetscDrawViewPortsCreate()
309: @*/
310: PetscErrorCode PetscDrawViewPortsDestroy(PetscDrawViewPorts *ports)
311: {
315: if (!ports) return(0);
317: /* reset Drawport of Window back to previous value */
318: PetscDrawSetViewPort(ports->draw,ports->port_xl,ports->port_yl,ports->port_xr,ports->port_yr);
319: PetscDrawDestroy(&ports->draw);
320: PetscFree4(ports->xl,ports->xr,ports->yl,ports->yr);
321: PetscFree(ports);
322: return(0);
323: }
325: /*@C
326: PetscDrawViewPortsSet - sets a draw object to use a particular subport
328: Logically Collective on PetscDraw inside PetscDrawViewPorts
330: Input Parameters:
331: + ports - the PetscDrawViewPorts object
332: - port - the port number, from 0 to nports-1
334: Level: advanced
336: .seealso: PetscDrawSplitViewPort(), PetscDrawSetViewPort(), PetscDrawViewPortsDestroy(), PetscDrawViewPortsCreate()
338: @*/
339: PetscErrorCode PetscDrawViewPortsSet(PetscDrawViewPorts *ports,PetscInt port)
340: {
344: if (!ports) return(0);
346: 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);
347: PetscDrawSetViewPort(ports->draw,ports->xl[port],ports->yl[port],ports->xr[port],ports->yr[port]);
348: return(0);
349: }