Actual source code: dviewp.c
petsc-3.7.7 2017-09-25
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",(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: }
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: {
72: *xl = draw->port_xl;
73: *yl = draw->port_yl;
74: *xr = draw->port_xr;
75: *yr = draw->port_yr;
76: return(0);
77: }
81: /*@
82: PetscDrawSplitViewPort - Splits a window shared by several processes into smaller
83: view ports. One for each process.
85: Collective on PetscDraw
87: Input Parameter:
88: . draw - the drawing context
90: Level: advanced
92: Concepts: drawing^in subset of window
94: .seealso: PetscDrawDivideViewPort(), PetscDrawSetViewPort()
96: @*/
97: PetscErrorCode PetscDrawSplitViewPort(PetscDraw draw)
98: {
100: PetscMPIInt rank,size;
101: PetscInt n;
102: PetscBool isnull;
103: PetscReal xl,xr,yl,yr,h;
107: PetscDrawIsNull(draw,&isnull);
108: if (isnull) return(0);
109: MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);
110: MPI_Comm_size(PetscObjectComm((PetscObject)draw),&size);
112: n = (PetscInt)(.1 + PetscSqrtReal((PetscReal)size));
113: while (n*n < size) n++;
115: h = 1.0/n;
116: xl = (rank % n)*h;
117: xr = xl + h;
118: yl = (rank / n)*h;
119: yr = yl + h;
121: PetscDrawCollectiveBegin(draw);
122: PetscDrawLine(draw,xl,yl,xl,yr,PETSC_DRAW_BLACK);
123: PetscDrawLine(draw,xl,yr,xr,yr,PETSC_DRAW_BLACK);
124: PetscDrawLine(draw,xr,yr,xr,yl,PETSC_DRAW_BLACK);
125: PetscDrawLine(draw,xr,yl,xl,yl,PETSC_DRAW_BLACK);
126: PetscDrawCollectiveEnd(draw);
127: PetscDrawFlush(draw);
129: draw->port_xl = xl + .05*h;
130: draw->port_xr = xr - .05*h;
131: draw->port_yl = yl + .05*h;
132: draw->port_yr = yr - .05*h;
134: if (draw->ops->setviewport) {
135: (*draw->ops->setviewport)(draw,xl,yl,xr,yr);
136: }
137: return(0);
138: }
142: /*@C
143: PetscDrawViewPortsCreate - Splits a window into smaller
144: view ports. Each processor shares all the viewports.
146: Collective on PetscDraw
148: Input Parameters:
149: + draw - the drawing context
150: - nports - the number of ports
152: Output Parameter:
153: . ports - a PetscDrawViewPorts context (C structure)
155: Level: advanced
157: Concepts: drawing^in subset of window
159: .seealso: PetscDrawSplitViewPort(), PetscDrawSetViewPort(), PetscDrawViewPortsSet(), PetscDrawViewPortsDestroy()
161: @*/
162: PetscErrorCode PetscDrawViewPortsCreate(PetscDraw draw,PetscInt nports,PetscDrawViewPorts **newports)
163: {
164: PetscDrawViewPorts *ports;
165: PetscInt i,n;
166: PetscBool isnull;
167: PetscMPIInt rank;
168: PetscReal *xl,*xr,*yl,*yr,h;
169: PetscErrorCode ierr;
173: if (nports < 1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Number of divisions must be positive: %d", nports);
175: PetscDrawIsNull(draw,&isnull);
176: if (isnull) {*newports = NULL; return(0);}
177: MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);
179: PetscNew(&ports); *newports = ports;
180: ports->draw = draw;
181: ports->nports = nports;
182: PetscObjectReference((PetscObject)draw);
183: /* save previous drawport of window */
184: PetscDrawGetViewPort(draw,&ports->port_xl,&ports->port_yl,&ports->port_xr,&ports->port_yr);
186: n = (PetscInt)(.1 + PetscSqrtReal((PetscReal)nports));
187: while (n*n < nports) n++;
188: h = 1.0/n;
190: PetscMalloc1(n*n,&xl); ports->xl = xl;
191: PetscMalloc1(n*n,&xr); ports->xr = xr;
192: PetscMalloc1(n*n,&yl); ports->yl = yl;
193: PetscMalloc1(n*n,&yr); ports->yr = yr;
195: PetscDrawSetCoordinates(draw,0.0,0.0,1.0,1.0);
196: PetscDrawCollectiveBegin(draw);
197: for (i=0; i<n*n; i++) {
198: xl[i] = (i % n)*h;
199: xr[i] = xl[i] + h;
200: yl[i] = (i / n)*h;
201: yr[i] = yl[i] + h;
203: if (!rank) {
204: PetscDrawLine(draw,xl[i],yl[i],xl[i],yr[i],PETSC_DRAW_BLACK);
205: PetscDrawLine(draw,xl[i],yr[i],xr[i],yr[i],PETSC_DRAW_BLACK);
206: PetscDrawLine(draw,xr[i],yr[i],xr[i],yl[i],PETSC_DRAW_BLACK);
207: PetscDrawLine(draw,xr[i],yl[i],xl[i],yl[i],PETSC_DRAW_BLACK);
208: }
210: xl[i] += .05*h;
211: xr[i] -= .05*h;
212: yl[i] += .05*h;
213: yr[i] -= .05*h;
214: }
215: PetscDrawCollectiveEnd(draw);
216: PetscDrawFlush(draw);
217: return(0);
218: }
222: /*@C
223: PetscDrawViewPortsCreateRect - Splits a window into smaller
224: view ports. Each processor shares all the viewports. The number
225: of views in the x- and y-directions is specified.
227: Collective on PetscDraw
229: Input Parameters:
230: + draw - the drawing context
231: . nx - the number of x divisions
232: - ny - the number of y divisions
234: Output Parameter:
235: . ports - a PetscDrawViewPorts context (C structure)
237: Level: advanced
239: Concepts: drawing^in subset of window
241: .seealso: PetscDrawSplitViewPort(), PetscDrawSetViewPort(), PetscDrawViewPortsSet(), PetscDrawViewPortsDestroy()
243: @*/
244: PetscErrorCode PetscDrawViewPortsCreateRect(PetscDraw draw,PetscInt nx,PetscInt ny,PetscDrawViewPorts **newports)
245: {
246: PetscDrawViewPorts *ports;
247: PetscReal *xl,*xr,*yl,*yr,hx,hy;
248: PetscInt i,j,k,n;
249: PetscBool isnull;
250: PetscMPIInt rank;
251: PetscErrorCode ierr;
255: if ((nx < 1) || (ny < 1)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Number of divisions must be positive: %d x %d", nx, ny);
257: PetscDrawIsNull(draw,&isnull);
258: if (isnull) {*newports = NULL; return(0);}
259: MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);
261: n = nx*ny;
262: hx = 1.0/nx;
263: hy = 1.0/ny;
264: PetscNew(&ports); *newports = ports;
265: ports->draw = draw;
266: ports->nports = n;
267: PetscObjectReference((PetscObject) draw);
268: /* save previous drawport of window */
269: PetscDrawGetViewPort(draw,&ports->port_xl,&ports->port_yl,&ports->port_xr,&ports->port_yr);
271: PetscMalloc1(n,&xl); ports->xl = xl;
272: PetscMalloc1(n,&xr); ports->xr = xr;
273: PetscMalloc1(n,&yl); ports->yl = yl;
274: PetscMalloc1(n,&yr); ports->yr = yr;
276: PetscDrawSetCoordinates(draw,0.0,0.0,1.0,1.0);
277: PetscDrawCollectiveBegin(draw);
278: for (i = 0; i < nx; i++) {
279: for (j = 0; j < ny; j++) {
280: k = j*nx+i;
282: xl[k] = i*hx;
283: xr[k] = xl[k] + hx;
284: yl[k] = j*hy;
285: yr[k] = yl[k] + hy;
287: if (!rank) {
288: PetscDrawLine(draw,xl[k],yl[k],xl[k],yr[k],PETSC_DRAW_BLACK);
289: PetscDrawLine(draw,xl[k],yr[k],xr[k],yr[k],PETSC_DRAW_BLACK);
290: PetscDrawLine(draw,xr[k],yr[k],xr[k],yl[k],PETSC_DRAW_BLACK);
291: PetscDrawLine(draw,xr[k],yl[k],xl[k],yl[k],PETSC_DRAW_BLACK);
292: }
294: xl[k] += .05*hx;
295: xr[k] -= .05*hx;
296: yl[k] += .05*hy;
297: yr[k] -= .05*hy;
298: }
299: }
300: PetscDrawCollectiveEnd(draw);
301: PetscDrawFlush(draw);
302: return(0);
303: }
307: /*@C
308: PetscDrawViewPortsDestroy - frees a PetscDrawViewPorts object
310: Collective on PetscDraw inside PetscDrawViewPorts
312: Input Parameter:
313: . ports - the PetscDrawViewPorts object
315: Level: advanced
317: .seealso: PetscDrawSplitViewPort(), PetscDrawSetViewPort(), PetscDrawViewPortsSet(), PetscDrawViewPortsCreate()
319: @*/
320: PetscErrorCode PetscDrawViewPortsDestroy(PetscDrawViewPorts *ports)
321: {
325: if (!ports) return(0);
327: /* reset Drawport of Window back to previous value */
328: PetscDrawSetViewPort(ports->draw,ports->port_xl,ports->port_yl,ports->port_xr,ports->port_yr);
329: PetscDrawDestroy(&ports->draw);
330: PetscFree(ports->xl);
331: PetscFree(ports->xr);
332: PetscFree(ports->yl);
333: PetscFree(ports->yr);
334: PetscFree(ports);
335: return(0);
336: }
340: /*@C
341: PetscDrawViewPortsSet - sets a draw object to use a particular subport
343: Logically Collective on PetscDraw inside PetscDrawViewPorts
345: Input Parameter:
346: + ports - the PetscDrawViewPorts object
347: - port - the port number, from 0 to nports-1
349: Level: advanced
351: Concepts: drawing^in subset of window
353: .seealso: PetscDrawSplitViewPort(), PetscDrawSetViewPort(), PetscDrawViewPortsDestroy(), PetscDrawViewPortsCreate()
355: @*/
356: PetscErrorCode PetscDrawViewPortsSet(PetscDrawViewPorts *ports,PetscInt port)
357: {
361: if (!ports) return(0);
363: 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);
364: PetscDrawSetViewPort(ports->draw,ports->xl[port],ports->yl[port],ports->xr[port],ports->yr[port]);
365: return(0);
366: }