xref: /petsc/src/sys/classes/draw/interface/dviewp.c (revision e0877f539457ad1ce8178bc0750eac5ffa490a67)
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   PetscValidRealPointer(xl,2);
69   PetscValidRealPointer(yl,3);
70   PetscValidRealPointer(xr,4);
71   PetscValidRealPointer(yr,5);
72   *xl = draw->port_xl;
73   *yl = draw->port_yl;
74   *xr = draw->port_xr;
75   *yr = draw->port_yr;
76   PetscFunctionReturn(0);
77 }
78 
79 #undef __FUNCT__
80 #define __FUNCT__ "PetscDrawSplitViewPort"
81 /*@
82    PetscDrawSplitViewPort - Splits a window shared by several processes into smaller
83    view ports. One for each process.
84 
85    Collective on PetscDraw
86 
87    Input Parameter:
88 .  draw - the drawing context
89 
90    Level: advanced
91 
92    Concepts: drawing^in subset of window
93 
94 .seealso: PetscDrawDivideViewPort(), PetscDrawSetViewPort()
95 
96 @*/
97 PetscErrorCode  PetscDrawSplitViewPort(PetscDraw draw)
98 {
99   PetscErrorCode ierr;
100   PetscMPIInt    rank,size;
101   PetscInt       n;
102   PetscBool      isnull;
103   PetscReal      xl,xr,yl,yr,h;
104 
105   PetscFunctionBegin;
106   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
107   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
108   if (isnull) PetscFunctionReturn(0);
109 
110   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);CHKERRQ(ierr);
111   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)draw),&size);CHKERRQ(ierr);
112 
113   n = (PetscInt)(.1 + PetscSqrtReal((PetscReal)size));
114   while (n*n < size) n++;
115 
116   h  = 1.0/n;
117   xl = (rank % n)*h;
118   xr = xl + h;
119   yl = (rank/n)*h;
120   yr = yl + h;
121 
122   ierr = PetscDrawLine(draw,xl,yl,xl,yr,PETSC_DRAW_BLACK);CHKERRQ(ierr);
123   ierr = PetscDrawLine(draw,xl,yr,xr,yr,PETSC_DRAW_BLACK);CHKERRQ(ierr);
124   ierr = PetscDrawLine(draw,xr,yr,xr,yl,PETSC_DRAW_BLACK);CHKERRQ(ierr);
125   ierr = PetscDrawLine(draw,xr,yl,xl,yl,PETSC_DRAW_BLACK);CHKERRQ(ierr);
126   ierr = PetscDrawSynchronizedFlush(draw);CHKERRQ(ierr);
127 
128   draw->port_xl = xl + .1*h;
129   draw->port_xr = xr - .1*h;
130   draw->port_yl = yl + .1*h;
131   draw->port_yr = yr - .1*h;
132 
133   if (draw->ops->setviewport) {
134     ierr =  (*draw->ops->setviewport)(draw,xl,yl,xr,yr);CHKERRQ(ierr);
135   }
136   PetscFunctionReturn(0);
137 }
138 
139 #undef __FUNCT__
140 #define __FUNCT__ "PetscDrawViewPortsCreate"
141 /*@C
142    PetscDrawViewPortsCreate - Splits a window into smaller
143        view ports. Each processor shares all the viewports.
144 
145    Collective on PetscDraw
146 
147    Input Parameters:
148 +  draw - the drawing context
149 -  nports - the number of ports
150 
151    Output Parameter:
152 .  ports - a PetscDrawViewPorts context (C structure)
153 
154    Level: advanced
155 
156    Concepts: drawing^in subset of window
157 
158 .seealso: PetscDrawSplitViewPort(), PetscDrawSetViewPort(), PetscDrawViewPortsSet(), PetscDrawViewPortsDestroy()
159 
160 @*/
161 PetscErrorCode  PetscDrawViewPortsCreate(PetscDraw draw,PetscInt nports,PetscDrawViewPorts **ports)
162 {
163   PetscInt       i,n;
164   PetscErrorCode ierr;
165   PetscBool      isnull;
166   PetscReal      *xl,*xr,*yl,*yr,h;
167 
168   PetscFunctionBegin;
169   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
170   PetscValidPointer(ports,3);
171   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
172   if (isnull) {*ports = NULL; PetscFunctionReturn(0);}
173 
174   ierr             = PetscNew(ports);CHKERRQ(ierr);
175   (*ports)->draw   = draw;
176   (*ports)->nports = nports;
177 
178   ierr = PetscObjectReference((PetscObject)draw);CHKERRQ(ierr);
179 
180   n = (PetscInt)(.1 + PetscSqrtReal((PetscReal)nports));
181   while (n*n < nports) n++;
182 
183   ierr = PetscMalloc1(n*n,&xl);CHKERRQ(ierr);(*ports)->xl = xl;
184   ierr = PetscMalloc1(n*n,&xr);CHKERRQ(ierr);(*ports)->xr = xr;
185   ierr = PetscMalloc1(n*n,&yl);CHKERRQ(ierr);(*ports)->yl = yl;
186   ierr = PetscMalloc1(n*n,&yr);CHKERRQ(ierr);(*ports)->yr = yr;
187 
188   h = 1.0/n;
189 
190   for (i=0; i<n*n; i++) {
191     xl[i] = (i % n)*h;
192     xr[i] = xl[i] + h;
193     yl[i] = (i/n)*h;
194     yr[i] = yl[i] + h;
195 
196     ierr = PetscDrawLine(draw,xl[i],yl[i],xl[i],yr[i],PETSC_DRAW_BLACK);CHKERRQ(ierr);
197     ierr = PetscDrawLine(draw,xl[i],yr[i],xr[i],yr[i],PETSC_DRAW_BLACK);CHKERRQ(ierr);
198     ierr = PetscDrawLine(draw,xr[i],yr[i],xr[i],yl[i],PETSC_DRAW_BLACK);CHKERRQ(ierr);
199     ierr = PetscDrawLine(draw,xr[i],yl[i],xl[i],yl[i],PETSC_DRAW_BLACK);CHKERRQ(ierr);
200 
201     xl[i] += .1*h;
202     xr[i] -= .1*h;
203     yl[i] += .1*h;
204     yr[i] -= .1*h;
205   }
206   /* save previous drawport of window */
207   ierr = PetscDrawGetViewPort(draw,&(*ports)->port_xl,&(*ports)->port_yl,&(*ports)->port_xr,&(*ports)->port_yr);CHKERRQ(ierr);
208   /* ierr = PetscDrawSynchronizedFlush(draw);CHKERRQ(ierr);*/  /* this causes flicker */
209   PetscFunctionReturn(0);
210 }
211 
212 #undef __FUNCT__
213 #define __FUNCT__ "PetscDrawViewPortsCreateRect"
214 /*@C
215    PetscDrawViewPortsCreateRect - Splits a window into smaller
216        view ports. Each processor shares all the viewports. The number
217        of views in the x- and y-directions is specified.
218 
219    Collective on PetscDraw
220 
221    Input Parameters:
222 +  draw - the drawing context
223 .  nx - the number of x divisions
224 -  ny - the number of y divisions
225 
226    Output Parameter:
227 .  ports - a PetscDrawViewPorts context (C structure)
228 
229    Level: advanced
230 
231    Concepts: drawing^in subset of window
232 
233 .seealso: PetscDrawSplitViewPort(), PetscDrawSetViewPort(), PetscDrawViewPortsSet(), PetscDrawViewPortsDestroy()
234 
235 @*/
236 PetscErrorCode  PetscDrawViewPortsCreateRect(PetscDraw draw,PetscInt nx,PetscInt ny,PetscDrawViewPorts **ports)
237 {
238   PetscReal      *xl, *xr, *yl, *yr, hx, hy;
239   PetscBool      isnull;
240   PetscInt       i, j, n;
241   PetscErrorCode ierr;
242 
243   PetscFunctionBegin;
244   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
245   if ((nx < 1) || (ny < 1)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Number of divisions must be positive: %d x %d", nx, ny);
246   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
247   if (isnull) {*ports = NULL; PetscFunctionReturn(0);}
248 
249   n    = nx*ny;
250   hx   = 1.0/nx;
251   hy   = 1.0/ny;
252   ierr = PetscNew(ports);CHKERRQ(ierr);
253 
254   (*ports)->draw   = draw;
255   (*ports)->nports = n;
256 
257   ierr = PetscObjectReference((PetscObject) draw);CHKERRQ(ierr);
258   ierr = PetscMalloc1(n, &xl);CHKERRQ(ierr);(*ports)->xl = xl;
259   ierr = PetscMalloc1(n, &xr);CHKERRQ(ierr);(*ports)->xr = xr;
260   ierr = PetscMalloc1(n, &yl);CHKERRQ(ierr);(*ports)->yl = yl;
261   ierr = PetscMalloc1(n, &yr);CHKERRQ(ierr);(*ports)->yr = yr;
262   for (i = 0; i < nx; i++) {
263     for (j = 0; j < ny; j++) {
264       PetscInt 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       ierr = PetscDrawLine(draw,xl[k],yl[k],xl[k],yr[k],PETSC_DRAW_BLACK);CHKERRQ(ierr);
272       ierr = PetscDrawLine(draw,xl[k],yr[k],xr[k],yr[k],PETSC_DRAW_BLACK);CHKERRQ(ierr);
273       ierr = PetscDrawLine(draw,xr[k],yr[k],xr[k],yl[k],PETSC_DRAW_BLACK);CHKERRQ(ierr);
274       ierr = PetscDrawLine(draw,xr[k],yl[k],xl[k],yl[k],PETSC_DRAW_BLACK);CHKERRQ(ierr);
275 
276       xl[k] += .01*hx;
277       xr[k] -= .01*hx;
278       yl[k] += .01*hy;
279       yr[k] -= .01*hy;
280     }
281   }
282   ierr = PetscDrawGetViewPort(draw,&(*ports)->port_xl,&(*ports)->port_yl,&(*ports)->port_xr,&(*ports)->port_yr);CHKERRQ(ierr);
283   /* ierr = PetscDrawSynchronizedFlush(draw);CHKERRQ(ierr); */  /* this causes flicker */
284   PetscFunctionReturn(0);
285 }
286 
287 #undef __FUNCT__
288 #define __FUNCT__ "PetscDrawViewPortsDestroy"
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 @*/
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 = 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) PetscFunctionReturn(0);
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   PetscFunctionReturn(0);
347 }
348