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