xref: /petsc/src/sys/classes/draw/interface/dviewp.c (revision c5929fdf3082647d199855a5c1d0286204349b03)
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 = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
168   if (isnull) {*ports = NULL; PetscFunctionReturn(0);}
169 
170   ierr             = PetscNew(ports);CHKERRQ(ierr);
171   (*ports)->draw   = draw;
172   (*ports)->nports = nports;
173 
174   ierr = PetscObjectReference((PetscObject)draw);CHKERRQ(ierr);
175 
176   n = (PetscInt)(.1 + PetscSqrtReal((PetscReal)nports));
177   while (n*n < nports) n++;
178 
179   ierr = PetscMalloc1(n*n,&xl);CHKERRQ(ierr);(*ports)->xl = xl;
180   ierr = PetscMalloc1(n*n,&xr);CHKERRQ(ierr);(*ports)->xr = xr;
181   ierr = PetscMalloc1(n*n,&yl);CHKERRQ(ierr);(*ports)->yl = yl;
182   ierr = PetscMalloc1(n*n,&yr);CHKERRQ(ierr);(*ports)->yr = yr;
183 
184   h = 1.0/n;
185 
186   for (i=0; i<n*n; i++) {
187     xl[i] = (i % n)*h;
188     xr[i] = xl[i] + h;
189     yl[i] = (i/n)*h;
190     yr[i] = yl[i] + h;
191 
192     ierr = PetscDrawLine(draw,xl[i],yl[i],xl[i],yr[i],PETSC_DRAW_BLACK);CHKERRQ(ierr);
193     ierr = PetscDrawLine(draw,xl[i],yr[i],xr[i],yr[i],PETSC_DRAW_BLACK);CHKERRQ(ierr);
194     ierr = PetscDrawLine(draw,xr[i],yr[i],xr[i],yl[i],PETSC_DRAW_BLACK);CHKERRQ(ierr);
195     ierr = PetscDrawLine(draw,xr[i],yl[i],xl[i],yl[i],PETSC_DRAW_BLACK);CHKERRQ(ierr);
196 
197     xl[i] += .1*h;
198     xr[i] -= .1*h;
199     yl[i] += .1*h;
200     yr[i] -= .1*h;
201   }
202   /* save previous drawport of window */
203   ierr = PetscDrawGetViewPort(draw,&(*ports)->port_xl,&(*ports)->port_yl,&(*ports)->port_xr,&(*ports)->port_yr);CHKERRQ(ierr);
204   /* ierr = PetscDrawSynchronizedFlush(draw);CHKERRQ(ierr);*/  /* this causes flicker */
205   PetscFunctionReturn(0);
206 }
207 
208 #undef __FUNCT__
209 #define __FUNCT__ "PetscDrawViewPortsCreateRect"
210 /*@C
211    PetscDrawViewPortsCreateRect - Splits a window into smaller
212        view ports. Each processor shares all the viewports. The number
213        of views in the x- and y-directions is specified.
214 
215    Collective on PetscDraw
216 
217    Input Parameters:
218 +  draw - the drawing context
219 .  nx - the number of x divisions
220 -  ny - the number of y divisions
221 
222    Output Parameter:
223 .  ports - a PetscDrawViewPorts context (C structure)
224 
225    Level: advanced
226 
227    Concepts: drawing^in subset of window
228 
229 .seealso: PetscDrawSplitViewPort(), PetscDrawSetViewPort(), PetscDrawViewPortsSet(), PetscDrawViewPortsDestroy()
230 
231 @*/
232 PetscErrorCode  PetscDrawViewPortsCreateRect(PetscDraw draw,PetscInt nx,PetscInt ny,PetscDrawViewPorts **ports)
233 {
234   PetscReal      *xl, *xr, *yl, *yr, hx, hy;
235   PetscBool      isnull;
236   PetscInt       i, j, n;
237   PetscErrorCode ierr;
238 
239   PetscFunctionBegin;
240   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
241   if ((nx < 1) || (ny < 1)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Number of divisions must be positive: %d x %d", nx, ny);
242   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
243   if (isnull) {*ports = NULL; PetscFunctionReturn(0);}
244 
245   n    = nx*ny;
246   hx   = 1.0/nx;
247   hy   = 1.0/ny;
248   ierr = PetscNew(ports);CHKERRQ(ierr);
249 
250   (*ports)->draw   = draw;
251   (*ports)->nports = n;
252 
253   ierr = PetscObjectReference((PetscObject) draw);CHKERRQ(ierr);
254   ierr = PetscMalloc1(n, &xl);CHKERRQ(ierr);(*ports)->xl = xl;
255   ierr = PetscMalloc1(n, &xr);CHKERRQ(ierr);(*ports)->xr = xr;
256   ierr = PetscMalloc1(n, &yl);CHKERRQ(ierr);(*ports)->yl = yl;
257   ierr = PetscMalloc1(n, &yr);CHKERRQ(ierr);(*ports)->yr = yr;
258   for (i = 0; i < nx; i++) {
259     for (j = 0; j < ny; j++) {
260       PetscInt k = j*nx+i;
261 
262       xl[k] = i*hx;
263       xr[k] = xl[k] + hx;
264       yl[k] = j*hy;
265       yr[k] = yl[k] + hy;
266 
267       ierr = PetscDrawLine(draw,xl[k],yl[k],xl[k],yr[k],PETSC_DRAW_BLACK);CHKERRQ(ierr);
268       ierr = PetscDrawLine(draw,xl[k],yr[k],xr[k],yr[k],PETSC_DRAW_BLACK);CHKERRQ(ierr);
269       ierr = PetscDrawLine(draw,xr[k],yr[k],xr[k],yl[k],PETSC_DRAW_BLACK);CHKERRQ(ierr);
270       ierr = PetscDrawLine(draw,xr[k],yl[k],xl[k],yl[k],PETSC_DRAW_BLACK);CHKERRQ(ierr);
271 
272       xl[k] += .01*hx;
273       xr[k] -= .01*hx;
274       yl[k] += .01*hy;
275       yr[k] -= .01*hy;
276     }
277   }
278   ierr = PetscDrawGetViewPort(draw,&(*ports)->port_xl,&(*ports)->port_yl,&(*ports)->port_xr,&(*ports)->port_yr);CHKERRQ(ierr);
279   /* ierr = PetscDrawSynchronizedFlush(draw);CHKERRQ(ierr); */  /* this causes flicker */
280   PetscFunctionReturn(0);
281 }
282 
283 #undef __FUNCT__
284 #define __FUNCT__ "PetscDrawViewPortsDestroy"
285 /*@C
286    PetscDrawViewPortsDestroy - frees a PetscDrawViewPorts object
287 
288    Collective on PetscDraw inside PetscDrawViewPorts
289 
290    Input Parameter:
291 .  ports - the PetscDrawViewPorts object
292 
293    Level: advanced
294 
295 .seealso: PetscDrawSplitViewPort(), PetscDrawSetViewPort(), PetscDrawViewPortsSet(), PetscDrawViewPortsCreate()
296 
297 @*/
298 PetscErrorCode  PetscDrawViewPortsDestroy(PetscDrawViewPorts *ports)
299 {
300   PetscErrorCode ierr;
301 
302   PetscFunctionBegin;
303   if (!ports) PetscFunctionReturn(0);
304   /* reset Drawport of Window back to previous value */
305   ierr = PetscDrawSetViewPort(ports->draw,ports->port_xl,ports->port_yl,ports->port_xr,ports->port_yr);CHKERRQ(ierr);
306   ierr = PetscDrawDestroy(&ports->draw);CHKERRQ(ierr);
307   ierr = PetscFree(ports->xl);CHKERRQ(ierr);
308   ierr = PetscFree(ports->xr);CHKERRQ(ierr);
309   ierr = PetscFree(ports->yl);CHKERRQ(ierr);
310   ierr = PetscFree(ports->yr);CHKERRQ(ierr);
311   ierr = PetscFree(ports);CHKERRQ(ierr);
312   PetscFunctionReturn(0);
313 }
314 
315 #undef __FUNCT__
316 #define __FUNCT__ "PetscDrawViewPortsSet"
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    Concepts: drawing^in subset of window
329 
330 .seealso: PetscDrawSplitViewPort(), PetscDrawSetViewPort(), PetscDrawViewPortsDestroy(), PetscDrawViewPortsCreate()
331 
332 @*/
333 PetscErrorCode  PetscDrawViewPortsSet(PetscDrawViewPorts *ports,PetscInt port)
334 {
335   PetscErrorCode ierr;
336 
337   PetscFunctionBegin;
338   if (ports) {
339     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);
340     ierr = PetscDrawSetViewPort(ports->draw,ports->xl[port],ports->yl[port],ports->xr[port],ports->yr[port]);CHKERRQ(ierr);
341   }
342   PetscFunctionReturn(0);
343 }
344