Actual source code: dviewp.c
petsc-3.14.6 2021-03-30
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
22: @*/
23: PetscErrorCode PetscDrawSetViewPort(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr)
24: {
29: 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);
30: draw->port_xl = xl; draw->port_yl = yl;
31: draw->port_xr = xr; draw->port_yr = yr;
32: if (draw->ops->setviewport) {
33: (*draw->ops->setviewport)(draw,xl,yl,xr,yr);
34: }
35: return(0);
36: }
38: /*@
39: PetscDrawGetViewPort - Gets the portion of the window (page) to which draw
40: routines will write.
42: Collective on PetscDraw
44: Input Parameter:
45: . draw - the drawing context
47: Output Parameter:
48: . xl,yl,xr,yr - upper right and lower left corners of subwindow
49: These numbers must always be between 0.0 and 1.0.
50: Lower left corner is (0,0).
52: Level: advanced
55: @*/
56: PetscErrorCode PetscDrawGetViewPort(PetscDraw draw,PetscReal *xl,PetscReal *yl,PetscReal *xr,PetscReal *yr)
57: {
64: *xl = draw->port_xl;
65: *yl = draw->port_yl;
66: *xr = draw->port_xr;
67: *yr = draw->port_yr;
68: return(0);
69: }
71: /*@
72: PetscDrawSplitViewPort - Splits a window shared by several processes into smaller
73: view ports. One for each process.
75: Collective on PetscDraw
77: Input Parameter:
78: . draw - the drawing context
80: Level: advanced
82: .seealso: PetscDrawDivideViewPort(), PetscDrawSetViewPort()
84: @*/
85: PetscErrorCode PetscDrawSplitViewPort(PetscDraw draw)
86: {
88: PetscMPIInt rank,size;
89: PetscInt n;
90: PetscBool isnull;
91: PetscReal xl,xr,yl,yr,h;
95: PetscDrawIsNull(draw,&isnull);
96: if (isnull) return(0);
97: MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);
98: MPI_Comm_size(PetscObjectComm((PetscObject)draw),&size);
100: n = (PetscInt)(.1 + PetscSqrtReal((PetscReal)size));
101: while (n*n < size) n++;
103: h = 1.0/n;
104: xl = (rank % n)*h;
105: xr = xl + h;
106: yl = (rank / n)*h;
107: yr = yl + h;
109: PetscDrawCollectiveBegin(draw);
110: PetscDrawLine(draw,xl,yl,xl,yr,PETSC_DRAW_BLACK);
111: PetscDrawLine(draw,xl,yr,xr,yr,PETSC_DRAW_BLACK);
112: PetscDrawLine(draw,xr,yr,xr,yl,PETSC_DRAW_BLACK);
113: PetscDrawLine(draw,xr,yl,xl,yl,PETSC_DRAW_BLACK);
114: PetscDrawCollectiveEnd(draw);
115: PetscDrawFlush(draw);
117: draw->port_xl = xl + .05*h;
118: draw->port_xr = xr - .05*h;
119: draw->port_yl = yl + .05*h;
120: draw->port_yr = yr - .05*h;
122: if (draw->ops->setviewport) {
123: (*draw->ops->setviewport)(draw,xl,yl,xr,yr);
124: }
125: return(0);
126: }
128: /*@C
129: PetscDrawViewPortsCreate - Splits a window into smaller view ports. Each processor shares all the viewports.
131: Collective on PetscDraw
133: Input Parameters:
134: + draw - the drawing context
135: - nports - the number of ports
137: Output Parameter:
138: . ports - a PetscDrawViewPorts context (C structure)
140: Options Database:
141: . -draw_ports - display multiple fields in the same window with PetscDrawPorts instead of in separate windows
143: Level: advanced
145: .seealso: PetscDrawSplitViewPort(), PetscDrawSetViewPort(), PetscDrawViewPortsSet(), PetscDrawViewPortsDestroy()
147: @*/
148: PetscErrorCode PetscDrawViewPortsCreate(PetscDraw draw,PetscInt nports,PetscDrawViewPorts **newports)
149: {
150: PetscDrawViewPorts *ports;
151: PetscInt i,n;
152: PetscBool isnull;
153: PetscMPIInt rank;
154: PetscReal *xl,*xr,*yl,*yr,h;
155: PetscErrorCode ierr;
159: if (nports < 1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Number of divisions must be positive: %d", nports);
161: PetscDrawIsNull(draw,&isnull);
162: if (isnull) {*newports = NULL; return(0);}
163: MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);
165: PetscNew(&ports); *newports = ports;
166: ports->draw = draw;
167: ports->nports = nports;
168: PetscObjectReference((PetscObject)draw);
169: /* save previous drawport of window */
170: PetscDrawGetViewPort(draw,&ports->port_xl,&ports->port_yl,&ports->port_xr,&ports->port_yr);
172: n = (PetscInt)(.1 + PetscSqrtReal((PetscReal)nports));
173: while (n*n < nports) n++;
174: h = 1.0/n;
176: PetscMalloc4(n*n,&xl,n*n,&xr,n*n,&yl,n*n,&yr);
177: ports->xl = xl;
178: ports->xr = xr;
179: ports->yl = yl;
180: ports->yr = yr;
182: PetscDrawSetCoordinates(draw,0.0,0.0,1.0,1.0);
183: PetscDrawCollectiveBegin(draw);
184: for (i=0; i<n*n; i++) {
185: xl[i] = (i % n)*h;
186: xr[i] = xl[i] + h;
187: yl[i] = (i / n)*h;
188: yr[i] = yl[i] + h;
190: if (!rank) {
191: PetscDrawLine(draw,xl[i],yl[i],xl[i],yr[i],PETSC_DRAW_BLACK);
192: PetscDrawLine(draw,xl[i],yr[i],xr[i],yr[i],PETSC_DRAW_BLACK);
193: PetscDrawLine(draw,xr[i],yr[i],xr[i],yl[i],PETSC_DRAW_BLACK);
194: PetscDrawLine(draw,xr[i],yl[i],xl[i],yl[i],PETSC_DRAW_BLACK);
195: }
197: xl[i] += .05*h;
198: xr[i] -= .05*h;
199: yl[i] += .05*h;
200: yr[i] -= .05*h;
201: }
202: PetscDrawCollectiveEnd(draw);
203: PetscDrawFlush(draw);
204: return(0);
205: }
207: /*@C
208: PetscDrawViewPortsCreateRect - Splits a window into smaller
209: view ports. Each processor shares all the viewports. The number
210: of views in the x- and y-directions is specified.
212: Collective on PetscDraw
214: Input Parameters:
215: + draw - the drawing context
216: . nx - the number of x divisions
217: - ny - the number of y divisions
219: Output Parameter:
220: . ports - a PetscDrawViewPorts context (C structure)
222: Level: advanced
224: .seealso: PetscDrawSplitViewPort(), PetscDrawSetViewPort(), PetscDrawViewPortsSet(), PetscDrawViewPortsDestroy()
226: @*/
227: PetscErrorCode PetscDrawViewPortsCreateRect(PetscDraw draw,PetscInt nx,PetscInt ny,PetscDrawViewPorts **newports)
228: {
229: PetscDrawViewPorts *ports;
230: PetscReal *xl,*xr,*yl,*yr,hx,hy;
231: PetscInt i,j,k,n;
232: PetscBool isnull;
233: PetscMPIInt rank;
234: PetscErrorCode ierr;
238: if ((nx < 1) || (ny < 1)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Number of divisions must be positive: %d x %d", nx, ny);
240: PetscDrawIsNull(draw,&isnull);
241: if (isnull) {*newports = NULL; return(0);}
242: MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);
244: n = nx*ny;
245: hx = 1.0/nx;
246: hy = 1.0/ny;
247: PetscNew(&ports); *newports = ports;
248: ports->draw = draw;
249: ports->nports = n;
250: PetscObjectReference((PetscObject) draw);
251: /* save previous drawport of window */
252: PetscDrawGetViewPort(draw,&ports->port_xl,&ports->port_yl,&ports->port_xr,&ports->port_yr);
254: PetscMalloc4(n,&xl,n,&xr,n,&yl,n,&yr);
255: ports->xr = xr;
256: ports->xl = xl;
257: ports->yl = yl;
258: ports->yr = yr;
260: PetscDrawSetCoordinates(draw,0.0,0.0,1.0,1.0);
261: PetscDrawCollectiveBegin(draw);
262: for (i = 0; i < nx; i++) {
263: for (j = 0; j < ny; j++) {
264: k = j*nx+i;
266: xl[k] = i*hx;
267: xr[k] = xl[k] + hx;
268: yl[k] = j*hy;
269: yr[k] = yl[k] + hy;
271: if (!rank) {
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);
276: }
278: xl[k] += .05*hx;
279: xr[k] -= .05*hx;
280: yl[k] += .05*hy;
281: yr[k] -= .05*hy;
282: }
283: }
284: PetscDrawCollectiveEnd(draw);
285: PetscDrawFlush(draw);
286: return(0);
287: }
289: /*@C
290: PetscDrawViewPortsDestroy - frees a PetscDrawViewPorts object
292: Collective on PetscDraw inside PetscDrawViewPorts
294: Input Parameter:
295: . ports - the PetscDrawViewPorts object
297: Level: advanced
299: .seealso: PetscDrawSplitViewPort(), PetscDrawSetViewPort(), PetscDrawViewPortsSet(), PetscDrawViewPortsCreate()
301: @*/
302: PetscErrorCode PetscDrawViewPortsDestroy(PetscDrawViewPorts *ports)
303: {
307: 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: PetscFree4(ports->xl,ports->xr,ports->yl,ports->yr);
313: PetscFree(ports);
314: return(0);
315: }
317: /*@C
318: PetscDrawViewPortsSet - sets a draw object to use a particular subport
320: Logically Collective on PetscDraw inside PetscDrawViewPorts
322: Input Parameter:
323: + ports - the PetscDrawViewPorts object
324: - port - the port number, from 0 to nports-1
326: Level: advanced
328: .seealso: PetscDrawSplitViewPort(), PetscDrawSetViewPort(), PetscDrawViewPortsDestroy(), PetscDrawViewPortsCreate()
330: @*/
331: PetscErrorCode PetscDrawViewPortsSet(PetscDrawViewPorts *ports,PetscInt port)
332: {
336: if (!ports) return(0);
338: 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);
339: PetscDrawSetViewPort(ports->draw,ports->xl[port],ports->yl[port],ports->xr[port],ports->yr[port]);
340: return(0);
341: }