xref: /petsc/src/sys/classes/draw/interface/dviewp.c (revision e611a964e9853b74d61a56642fe9d06a6e51780f)
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   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);CHKERRQ(ierr);
110   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)draw),&size);CHKERRQ(ierr);
111 
112   n = (PetscInt)(.1 + PetscSqrtReal((PetscReal)size));
113   while (n*n < size) n++;
114 
115   h  = 1.0/n;
116   xl = (rank % n)*h;
117   xr = xl + h;
118   yl = (rank / n)*h;
119   yr = yl + h;
120 
121   ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
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 = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
127   ierr = PetscDrawFlush(draw);CHKERRQ(ierr);
128 
129   draw->port_xl = xl + .05*h;
130   draw->port_xr = xr - .05*h;
131   draw->port_yl = yl + .05*h;
132   draw->port_yr = yr - .05*h;
133 
134   if (draw->ops->setviewport) {
135     ierr =  (*draw->ops->setviewport)(draw,xl,yl,xr,yr);CHKERRQ(ierr);
136   }
137   PetscFunctionReturn(0);
138 }
139 
140 #undef __FUNCT__
141 #define __FUNCT__ "PetscDrawViewPortsCreate"
142 /*@C
143    PetscDrawViewPortsCreate - Splits a window into smaller
144        view ports. Each processor shares all the viewports.
145 
146    Collective on PetscDraw
147 
148    Input Parameters:
149 +  draw - the drawing context
150 -  nports - the number of ports
151 
152    Output Parameter:
153 .  ports - a PetscDrawViewPorts context (C structure)
154 
155    Level: advanced
156 
157    Concepts: drawing^in subset of window
158 
159 .seealso: PetscDrawSplitViewPort(), PetscDrawSetViewPort(), PetscDrawViewPortsSet(), PetscDrawViewPortsDestroy()
160 
161 @*/
162 PetscErrorCode  PetscDrawViewPortsCreate(PetscDraw draw,PetscInt nports,PetscDrawViewPorts **newports)
163 {
164   PetscDrawViewPorts *ports;
165   PetscInt           i,n;
166   PetscBool          isnull;
167   PetscMPIInt        rank;
168   PetscReal          *xl,*xr,*yl,*yr,h;
169   PetscErrorCode     ierr;
170 
171   PetscFunctionBegin;
172   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
173   if (nports < 1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Number of divisions must be positive: %d", nports);
174   PetscValidPointer(newports,3);
175   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
176   if (isnull) {*newports = NULL; PetscFunctionReturn(0);}
177   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);CHKERRQ(ierr);
178 
179   ierr = PetscNew(&ports);CHKERRQ(ierr); *newports = ports;
180   ports->draw = draw;
181   ports->nports = nports;
182   ierr = PetscObjectReference((PetscObject)draw);CHKERRQ(ierr);
183   /* save previous drawport of window */
184   ierr = PetscDrawGetViewPort(draw,&ports->port_xl,&ports->port_yl,&ports->port_xr,&ports->port_yr);CHKERRQ(ierr);
185 
186   n = (PetscInt)(.1 + PetscSqrtReal((PetscReal)nports));
187   while (n*n < nports) n++;
188   h = 1.0/n;
189 
190   ierr = PetscMalloc1(n*n,&xl);CHKERRQ(ierr); ports->xl = xl;
191   ierr = PetscMalloc1(n*n,&xr);CHKERRQ(ierr); ports->xr = xr;
192   ierr = PetscMalloc1(n*n,&yl);CHKERRQ(ierr); ports->yl = yl;
193   ierr = PetscMalloc1(n*n,&yr);CHKERRQ(ierr); ports->yr = yr;
194 
195   ierr = PetscDrawSetCoordinates(draw,0.0,0.0,1.0,1.0);CHKERRQ(ierr);
196   ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
197   for (i=0; i<n*n; i++) {
198     xl[i] = (i % n)*h;
199     xr[i] = xl[i] + h;
200     yl[i] = (i / n)*h;
201     yr[i] = yl[i] + h;
202 
203     if (!rank) {
204       ierr = PetscDrawLine(draw,xl[i],yl[i],xl[i],yr[i],PETSC_DRAW_BLACK);CHKERRQ(ierr);
205       ierr = PetscDrawLine(draw,xl[i],yr[i],xr[i],yr[i],PETSC_DRAW_BLACK);CHKERRQ(ierr);
206       ierr = PetscDrawLine(draw,xr[i],yr[i],xr[i],yl[i],PETSC_DRAW_BLACK);CHKERRQ(ierr);
207       ierr = PetscDrawLine(draw,xr[i],yl[i],xl[i],yl[i],PETSC_DRAW_BLACK);CHKERRQ(ierr);
208     }
209 
210     xl[i] += .05*h;
211     xr[i] -= .05*h;
212     yl[i] += .05*h;
213     yr[i] -= .05*h;
214   }
215   ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
216   ierr = PetscDrawFlush(draw);CHKERRQ(ierr);
217   PetscFunctionReturn(0);
218 }
219 
220 #undef __FUNCT__
221 #define __FUNCT__ "PetscDrawViewPortsCreateRect"
222 /*@C
223    PetscDrawViewPortsCreateRect - Splits a window into smaller
224        view ports. Each processor shares all the viewports. The number
225        of views in the x- and y-directions is specified.
226 
227    Collective on PetscDraw
228 
229    Input Parameters:
230 +  draw - the drawing context
231 .  nx - the number of x divisions
232 -  ny - the number of y divisions
233 
234    Output Parameter:
235 .  ports - a PetscDrawViewPorts context (C structure)
236 
237    Level: advanced
238 
239    Concepts: drawing^in subset of window
240 
241 .seealso: PetscDrawSplitViewPort(), PetscDrawSetViewPort(), PetscDrawViewPortsSet(), PetscDrawViewPortsDestroy()
242 
243 @*/
244 PetscErrorCode  PetscDrawViewPortsCreateRect(PetscDraw draw,PetscInt nx,PetscInt ny,PetscDrawViewPorts **newports)
245 {
246   PetscDrawViewPorts *ports;
247   PetscReal          *xl,*xr,*yl,*yr,hx,hy;
248   PetscInt           i,j,k,n;
249   PetscBool          isnull;
250   PetscMPIInt        rank;
251   PetscErrorCode     ierr;
252 
253   PetscFunctionBegin;
254   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
255   if ((nx < 1) || (ny < 1)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Number of divisions must be positive: %d x %d", nx, ny);
256   PetscValidPointer(newports,3);
257   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
258   if (isnull) {*newports = NULL; PetscFunctionReturn(0);}
259   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);CHKERRQ(ierr);
260 
261   n  = nx*ny;
262   hx = 1.0/nx;
263   hy = 1.0/ny;
264   ierr = PetscNew(&ports);CHKERRQ(ierr); *newports = ports;
265   ports->draw = draw;
266   ports->nports = n;
267   ierr = PetscObjectReference((PetscObject) draw);CHKERRQ(ierr);
268   /* save previous drawport of window */
269   ierr = PetscDrawGetViewPort(draw,&ports->port_xl,&ports->port_yl,&ports->port_xr,&ports->port_yr);CHKERRQ(ierr);
270 
271   ierr = PetscMalloc1(n,&xl);CHKERRQ(ierr); ports->xl = xl;
272   ierr = PetscMalloc1(n,&xr);CHKERRQ(ierr); ports->xr = xr;
273   ierr = PetscMalloc1(n,&yl);CHKERRQ(ierr); ports->yl = yl;
274   ierr = PetscMalloc1(n,&yr);CHKERRQ(ierr); ports->yr = yr;
275 
276   ierr = PetscDrawSetCoordinates(draw,0.0,0.0,1.0,1.0);CHKERRQ(ierr);
277   ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
278   for (i = 0; i < nx; i++) {
279     for (j = 0; j < ny; j++) {
280       k = j*nx+i;
281 
282       xl[k] = i*hx;
283       xr[k] = xl[k] + hx;
284       yl[k] = j*hy;
285       yr[k] = yl[k] + hy;
286 
287       if (!rank) {
288         ierr = PetscDrawLine(draw,xl[k],yl[k],xl[k],yr[k],PETSC_DRAW_BLACK);CHKERRQ(ierr);
289         ierr = PetscDrawLine(draw,xl[k],yr[k],xr[k],yr[k],PETSC_DRAW_BLACK);CHKERRQ(ierr);
290         ierr = PetscDrawLine(draw,xr[k],yr[k],xr[k],yl[k],PETSC_DRAW_BLACK);CHKERRQ(ierr);
291         ierr = PetscDrawLine(draw,xr[k],yl[k],xl[k],yl[k],PETSC_DRAW_BLACK);CHKERRQ(ierr);
292       }
293 
294       xl[k] += .05*hx;
295       xr[k] -= .05*hx;
296       yl[k] += .05*hy;
297       yr[k] -= .05*hy;
298     }
299   }
300   ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
301   ierr = PetscDrawFlush(draw);CHKERRQ(ierr);
302   PetscFunctionReturn(0);
303 }
304 
305 #undef __FUNCT__
306 #define __FUNCT__ "PetscDrawViewPortsDestroy"
307 /*@C
308    PetscDrawViewPortsDestroy - frees a PetscDrawViewPorts object
309 
310    Collective on PetscDraw inside PetscDrawViewPorts
311 
312    Input Parameter:
313 .  ports - the PetscDrawViewPorts object
314 
315    Level: advanced
316 
317 .seealso: PetscDrawSplitViewPort(), PetscDrawSetViewPort(), PetscDrawViewPortsSet(), PetscDrawViewPortsCreate()
318 
319 @*/
320 PetscErrorCode  PetscDrawViewPortsDestroy(PetscDrawViewPorts *ports)
321 {
322   PetscErrorCode ierr;
323 
324   PetscFunctionBegin;
325   if (!ports) PetscFunctionReturn(0);
326   PetscValidPointer(ports,1);
327   /* reset Drawport of Window back to previous value */
328   ierr = PetscDrawSetViewPort(ports->draw,ports->port_xl,ports->port_yl,ports->port_xr,ports->port_yr);CHKERRQ(ierr);
329   ierr = PetscDrawDestroy(&ports->draw);CHKERRQ(ierr);
330   ierr = PetscFree(ports->xl);CHKERRQ(ierr);
331   ierr = PetscFree(ports->xr);CHKERRQ(ierr);
332   ierr = PetscFree(ports->yl);CHKERRQ(ierr);
333   ierr = PetscFree(ports->yr);CHKERRQ(ierr);
334   ierr = PetscFree(ports);CHKERRQ(ierr);
335   PetscFunctionReturn(0);
336 }
337 
338 #undef __FUNCT__
339 #define __FUNCT__ "PetscDrawViewPortsSet"
340 /*@C
341    PetscDrawViewPortsSet - sets a draw object to use a particular subport
342 
343    Logically Collective on PetscDraw inside PetscDrawViewPorts
344 
345    Input Parameter:
346 +  ports - the PetscDrawViewPorts object
347 -  port - the port number, from 0 to nports-1
348 
349    Level: advanced
350 
351    Concepts: drawing^in subset of window
352 
353 .seealso: PetscDrawSplitViewPort(), PetscDrawSetViewPort(), PetscDrawViewPortsDestroy(), PetscDrawViewPortsCreate()
354 
355 @*/
356 PetscErrorCode  PetscDrawViewPortsSet(PetscDrawViewPorts *ports,PetscInt port)
357 {
358   PetscErrorCode ierr;
359 
360   PetscFunctionBegin;
361   if (!ports) PetscFunctionReturn(0);
362   PetscValidPointer(ports,1);
363   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);
364   ierr = PetscDrawSetViewPort(ports->draw,ports->xl[port],ports->yl[port],ports->xr[port],ports->yr[port]);CHKERRQ(ierr);
365   PetscFunctionReturn(0);
366 }
367