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