xref: /petsc/src/sys/classes/draw/interface/dviewp.c (revision 4e278199b78715991f5c71ebbd945c1489263e6c)
1 
2 /*
3        Provides the calling sequences for all the basic PetscDraw routines.
4 */
5 #include <petsc/private/drawimpl.h>  /*I "petscdraw.h" I*/
6 
7 /*@
8    PetscDrawSetViewPort - Sets the portion of the window (page) to which draw
9    routines will write.
10 
11    Collective on PetscDraw
12 
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
18 
19    Level: advanced
20 
21 @*/
22 PetscErrorCode  PetscDrawSetViewPort(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr)
23 {
24   PetscErrorCode ierr;
25 
26   PetscFunctionBegin;
27   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
28   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);
29   draw->port_xl = xl; draw->port_yl = yl;
30   draw->port_xr = xr; draw->port_yr = yr;
31   if (draw->ops->setviewport) {
32     ierr = (*draw->ops->setviewport)(draw,xl,yl,xr,yr);CHKERRQ(ierr);
33   }
34   PetscFunctionReturn(0);
35 }
36 
37 /*@
38    PetscDrawGetViewPort - Gets the portion of the window (page) to which draw
39    routines will write.
40 
41    Collective on PetscDraw
42 
43    Input Parameter:
44 .  draw - the drawing context
45 
46    Output Parameter:
47 .  xl,yl,xr,yr - upper right and lower left corners of subwindow
48                  These numbers must always be between 0.0 and 1.0.
49                  Lower left corner is (0,0).
50 
51    Level: advanced
52 
53 @*/
54 PetscErrorCode  PetscDrawGetViewPort(PetscDraw draw,PetscReal *xl,PetscReal *yl,PetscReal *xr,PetscReal *yr)
55 {
56   PetscFunctionBegin;
57   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
58   PetscValidRealPointer(xl,2);
59   PetscValidRealPointer(yl,3);
60   PetscValidRealPointer(xr,4);
61   PetscValidRealPointer(yr,5);
62   *xl = draw->port_xl;
63   *yl = draw->port_yl;
64   *xr = draw->port_xr;
65   *yr = draw->port_yr;
66   PetscFunctionReturn(0);
67 }
68 
69 /*@
70    PetscDrawSplitViewPort - Splits a window shared by several processes into smaller
71    view ports. One for each process.
72 
73    Collective on PetscDraw
74 
75    Input Parameter:
76 .  draw - the drawing context
77 
78    Level: advanced
79 
80 .seealso: PetscDrawDivideViewPort(), PetscDrawSetViewPort()
81 
82 @*/
83 PetscErrorCode  PetscDrawSplitViewPort(PetscDraw draw)
84 {
85   PetscErrorCode ierr;
86   PetscMPIInt    rank,size;
87   PetscInt       n;
88   PetscBool      isnull;
89   PetscReal      xl,xr,yl,yr,h;
90 
91   PetscFunctionBegin;
92   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
93   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
94   if (isnull) PetscFunctionReturn(0);
95   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);CHKERRMPI(ierr);
96   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)draw),&size);CHKERRMPI(ierr);
97 
98   n = (PetscInt)(.1 + PetscSqrtReal((PetscReal)size));
99   while (n*n < size) n++;
100 
101   h  = 1.0/n;
102   xl = (rank % n)*h;
103   xr = xl + h;
104   yl = (rank / n)*h;
105   yr = yl + h;
106 
107   ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
108   ierr = PetscDrawLine(draw,xl,yl,xl,yr,PETSC_DRAW_BLACK);CHKERRQ(ierr);
109   ierr = PetscDrawLine(draw,xl,yr,xr,yr,PETSC_DRAW_BLACK);CHKERRQ(ierr);
110   ierr = PetscDrawLine(draw,xr,yr,xr,yl,PETSC_DRAW_BLACK);CHKERRQ(ierr);
111   ierr = PetscDrawLine(draw,xr,yl,xl,yl,PETSC_DRAW_BLACK);CHKERRQ(ierr);
112   ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
113   ierr = PetscDrawFlush(draw);CHKERRQ(ierr);
114 
115   draw->port_xl = xl + .05*h;
116   draw->port_xr = xr - .05*h;
117   draw->port_yl = yl + .05*h;
118   draw->port_yr = yr - .05*h;
119 
120   if (draw->ops->setviewport) {
121     ierr =  (*draw->ops->setviewport)(draw,xl,yl,xr,yr);CHKERRQ(ierr);
122   }
123   PetscFunctionReturn(0);
124 }
125 
126 /*@C
127    PetscDrawViewPortsCreate - Splits a window into smaller view ports. Each processor shares all the viewports.
128 
129    Collective on PetscDraw
130 
131    Input Parameters:
132 +  draw - the drawing context
133 -  nports - the number of ports
134 
135    Output Parameter:
136 .  ports - a PetscDrawViewPorts context (C structure)
137 
138    Options Database:
139 .  -draw_ports - display multiple fields in the same window with PetscDrawPorts instead of in separate windows
140 
141    Level: advanced
142 
143 .seealso: PetscDrawSplitViewPort(), PetscDrawSetViewPort(), PetscDrawViewPortsSet(), PetscDrawViewPortsDestroy()
144 
145 @*/
146 PetscErrorCode  PetscDrawViewPortsCreate(PetscDraw draw,PetscInt nports,PetscDrawViewPorts **newports)
147 {
148   PetscDrawViewPorts *ports;
149   PetscInt           i,n;
150   PetscBool          isnull;
151   PetscMPIInt        rank;
152   PetscReal          *xl,*xr,*yl,*yr,h;
153   PetscErrorCode     ierr;
154 
155   PetscFunctionBegin;
156   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
157   if (nports < 1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Number of divisions must be positive: %d", nports);
158   PetscValidPointer(newports,3);
159   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
160   if (isnull) {*newports = NULL; PetscFunctionReturn(0);}
161   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);CHKERRMPI(ierr);
162 
163   ierr = PetscNew(&ports);CHKERRQ(ierr); *newports = ports;
164   ports->draw = draw;
165   ports->nports = nports;
166   ierr = PetscObjectReference((PetscObject)draw);CHKERRQ(ierr);
167   /* save previous drawport of window */
168   ierr = PetscDrawGetViewPort(draw,&ports->port_xl,&ports->port_yl,&ports->port_xr,&ports->port_yr);CHKERRQ(ierr);
169 
170   n = (PetscInt)(.1 + PetscSqrtReal((PetscReal)nports));
171   while (n*n < nports) n++;
172   h = 1.0/n;
173 
174   ierr = PetscMalloc4(n*n,&xl,n*n,&xr,n*n,&yl,n*n,&yr);CHKERRQ(ierr);
175   ports->xl = xl;
176   ports->xr = xr;
177   ports->yl = yl;
178   ports->yr = yr;
179 
180   ierr = PetscDrawSetCoordinates(draw,0.0,0.0,1.0,1.0);CHKERRQ(ierr);
181   ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
182   for (i=0; i<n*n; i++) {
183     xl[i] = (i % n)*h;
184     xr[i] = xl[i] + h;
185     yl[i] = (i / n)*h;
186     yr[i] = yl[i] + h;
187 
188     if (!rank) {
189       ierr = PetscDrawLine(draw,xl[i],yl[i],xl[i],yr[i],PETSC_DRAW_BLACK);CHKERRQ(ierr);
190       ierr = PetscDrawLine(draw,xl[i],yr[i],xr[i],yr[i],PETSC_DRAW_BLACK);CHKERRQ(ierr);
191       ierr = PetscDrawLine(draw,xr[i],yr[i],xr[i],yl[i],PETSC_DRAW_BLACK);CHKERRQ(ierr);
192       ierr = PetscDrawLine(draw,xr[i],yl[i],xl[i],yl[i],PETSC_DRAW_BLACK);CHKERRQ(ierr);
193     }
194 
195     xl[i] += .05*h;
196     xr[i] -= .05*h;
197     yl[i] += .05*h;
198     yr[i] -= .05*h;
199   }
200   ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
201   ierr = PetscDrawFlush(draw);CHKERRQ(ierr);
202   PetscFunctionReturn(0);
203 }
204 
205 /*@C
206    PetscDrawViewPortsCreateRect - Splits a window into smaller
207        view ports. Each processor shares all the viewports. The number
208        of views in the x- and y-directions is specified.
209 
210    Collective on PetscDraw
211 
212    Input Parameters:
213 +  draw - the drawing context
214 .  nx - the number of x divisions
215 -  ny - the number of y divisions
216 
217    Output Parameter:
218 .  ports - a PetscDrawViewPorts context (C structure)
219 
220    Level: advanced
221 
222 .seealso: PetscDrawSplitViewPort(), PetscDrawSetViewPort(), PetscDrawViewPortsSet(), PetscDrawViewPortsDestroy()
223 
224 @*/
225 PetscErrorCode  PetscDrawViewPortsCreateRect(PetscDraw draw,PetscInt nx,PetscInt ny,PetscDrawViewPorts **newports)
226 {
227   PetscDrawViewPorts *ports;
228   PetscReal          *xl,*xr,*yl,*yr,hx,hy;
229   PetscInt           i,j,k,n;
230   PetscBool          isnull;
231   PetscMPIInt        rank;
232   PetscErrorCode     ierr;
233 
234   PetscFunctionBegin;
235   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
236   if ((nx < 1) || (ny < 1)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Number of divisions must be positive: %d x %d", nx, ny);
237   PetscValidPointer(newports,4);
238   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
239   if (isnull) {*newports = NULL; PetscFunctionReturn(0);}
240   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);CHKERRMPI(ierr);
241 
242   n  = nx*ny;
243   hx = 1.0/nx;
244   hy = 1.0/ny;
245   ierr = PetscNew(&ports);CHKERRQ(ierr); *newports = ports;
246   ports->draw = draw;
247   ports->nports = n;
248   ierr = PetscObjectReference((PetscObject) draw);CHKERRQ(ierr);
249   /* save previous drawport of window */
250   ierr = PetscDrawGetViewPort(draw,&ports->port_xl,&ports->port_yl,&ports->port_xr,&ports->port_yr);CHKERRQ(ierr);
251 
252   ierr = PetscMalloc4(n,&xl,n,&xr,n,&yl,n,&yr);CHKERRQ(ierr);
253   ports->xr = xr;
254   ports->xl = xl;
255   ports->yl = yl;
256   ports->yr = yr;
257 
258   ierr = PetscDrawSetCoordinates(draw,0.0,0.0,1.0,1.0);CHKERRQ(ierr);
259   ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
260   for (i = 0; i < nx; i++) {
261     for (j = 0; j < ny; j++) {
262       k = j*nx+i;
263 
264       xl[k] = i*hx;
265       xr[k] = xl[k] + hx;
266       yl[k] = j*hy;
267       yr[k] = yl[k] + hy;
268 
269       if (!rank) {
270         ierr = PetscDrawLine(draw,xl[k],yl[k],xl[k],yr[k],PETSC_DRAW_BLACK);CHKERRQ(ierr);
271         ierr = PetscDrawLine(draw,xl[k],yr[k],xr[k],yr[k],PETSC_DRAW_BLACK);CHKERRQ(ierr);
272         ierr = PetscDrawLine(draw,xr[k],yr[k],xr[k],yl[k],PETSC_DRAW_BLACK);CHKERRQ(ierr);
273         ierr = PetscDrawLine(draw,xr[k],yl[k],xl[k],yl[k],PETSC_DRAW_BLACK);CHKERRQ(ierr);
274       }
275 
276       xl[k] += .05*hx;
277       xr[k] -= .05*hx;
278       yl[k] += .05*hy;
279       yr[k] -= .05*hy;
280     }
281   }
282   ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
283   ierr = PetscDrawFlush(draw);CHKERRQ(ierr);
284   PetscFunctionReturn(0);
285 }
286 
287 /*@C
288    PetscDrawViewPortsDestroy - frees a PetscDrawViewPorts object
289 
290    Collective on PetscDraw inside PetscDrawViewPorts
291 
292    Input Parameter:
293 .  ports - the PetscDrawViewPorts object
294 
295    Level: advanced
296 
297 .seealso: PetscDrawSplitViewPort(), PetscDrawSetViewPort(), PetscDrawViewPortsSet(), PetscDrawViewPortsCreate()
298 
299 @*/
300 PetscErrorCode  PetscDrawViewPortsDestroy(PetscDrawViewPorts *ports)
301 {
302   PetscErrorCode ierr;
303 
304   PetscFunctionBegin;
305   if (!ports) PetscFunctionReturn(0);
306   PetscValidPointer(ports,1);
307   /* reset Drawport of Window back to previous value */
308   ierr = PetscDrawSetViewPort(ports->draw,ports->port_xl,ports->port_yl,ports->port_xr,ports->port_yr);CHKERRQ(ierr);
309   ierr = PetscDrawDestroy(&ports->draw);CHKERRQ(ierr);
310   ierr = PetscFree4(ports->xl,ports->xr,ports->yl,ports->yr);CHKERRQ(ierr);
311   ierr = PetscFree(ports);CHKERRQ(ierr);
312   PetscFunctionReturn(0);
313 }
314 
315 /*@C
316    PetscDrawViewPortsSet - sets a draw object to use a particular subport
317 
318    Logically Collective on PetscDraw inside PetscDrawViewPorts
319 
320    Input Parameter:
321 +  ports - the PetscDrawViewPorts object
322 -  port - the port number, from 0 to nports-1
323 
324    Level: advanced
325 
326 .seealso: PetscDrawSplitViewPort(), PetscDrawSetViewPort(), PetscDrawViewPortsDestroy(), PetscDrawViewPortsCreate()
327 
328 @*/
329 PetscErrorCode  PetscDrawViewPortsSet(PetscDrawViewPorts *ports,PetscInt port)
330 {
331   PetscErrorCode ierr;
332 
333   PetscFunctionBegin;
334   if (!ports) PetscFunctionReturn(0);
335   PetscValidPointer(ports,1);
336   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);
337   ierr = PetscDrawSetViewPort(ports->draw,ports->xl[port],ports->yl[port],ports->xr[port],ports->yr[port]);CHKERRQ(ierr);
338   PetscFunctionReturn(0);
339 }
340