Actual source code: dviewp.c
petsc-3.11.4 2019-09-28
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: }