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