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 /*@
8 PetscDrawSetViewPort - Sets the portion of the window (page) to which draw
9 routines will write.
10
11 Collective on PetscDraw
12
13 Input Parameters:
14 + xl,yl,xr,yr - upper right and lower left corners of subwindow
15 These numbers must always be between 0.0 and 1.0.
16 Lower left corner is (0,0).
17 - draw - the drawing context
18
19 Level: advanced
20
21
22 @*/
PetscDrawSetViewPort(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr)23 PetscErrorCode PetscDrawSetViewPort(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr)
24 {
25 PetscErrorCode ierr;
26
27 PetscFunctionBegin;
28 PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
29 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);
30 draw->port_xl = xl; draw->port_yl = yl;
31 draw->port_xr = xr; draw->port_yr = yr;
32 if (draw->ops->setviewport) {
33 ierr = (*draw->ops->setviewport)(draw,xl,yl,xr,yr);CHKERRQ(ierr);
34 }
35 PetscFunctionReturn(0);
36 }
37
38 /*@
39 PetscDrawGetViewPort - Gets the portion of the window (page) to which draw
40 routines will write.
41
42 Collective on PetscDraw
43
44 Input Parameter:
45 . draw - the drawing context
46
47 Output Parameter:
48 . xl,yl,xr,yr - upper right and lower left corners of subwindow
49 These numbers must always be between 0.0 and 1.0.
50 Lower left corner is (0,0).
51
52 Level: advanced
53
54
55 @*/
PetscDrawGetViewPort(PetscDraw draw,PetscReal * xl,PetscReal * yl,PetscReal * xr,PetscReal * yr)56 PetscErrorCode PetscDrawGetViewPort(PetscDraw draw,PetscReal *xl,PetscReal *yl,PetscReal *xr,PetscReal *yr)
57 {
58 PetscFunctionBegin;
59 PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
60 PetscValidRealPointer(xl,2);
61 PetscValidRealPointer(yl,3);
62 PetscValidRealPointer(xr,4);
63 PetscValidRealPointer(yr,5);
64 *xl = draw->port_xl;
65 *yl = draw->port_yl;
66 *xr = draw->port_xr;
67 *yr = draw->port_yr;
68 PetscFunctionReturn(0);
69 }
70
71 /*@
72 PetscDrawSplitViewPort - Splits a window shared by several processes into smaller
73 view ports. One for each process.
74
75 Collective on PetscDraw
76
77 Input Parameter:
78 . draw - the drawing context
79
80 Level: advanced
81
82 .seealso: PetscDrawDivideViewPort(), PetscDrawSetViewPort()
83
84 @*/
PetscDrawSplitViewPort(PetscDraw draw)85 PetscErrorCode PetscDrawSplitViewPort(PetscDraw draw)
86 {
87 PetscErrorCode ierr;
88 PetscMPIInt rank,size;
89 PetscInt n;
90 PetscBool isnull;
91 PetscReal xl,xr,yl,yr,h;
92
93 PetscFunctionBegin;
94 PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
95 ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
96 if (isnull) PetscFunctionReturn(0);
97 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);CHKERRQ(ierr);
98 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)draw),&size);CHKERRQ(ierr);
99
100 n = (PetscInt)(.1 + PetscSqrtReal((PetscReal)size));
101 while (n*n < size) n++;
102
103 h = 1.0/n;
104 xl = (rank % n)*h;
105 xr = xl + h;
106 yl = (rank / n)*h;
107 yr = yl + h;
108
109 ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
110 ierr = PetscDrawLine(draw,xl,yl,xl,yr,PETSC_DRAW_BLACK);CHKERRQ(ierr);
111 ierr = PetscDrawLine(draw,xl,yr,xr,yr,PETSC_DRAW_BLACK);CHKERRQ(ierr);
112 ierr = PetscDrawLine(draw,xr,yr,xr,yl,PETSC_DRAW_BLACK);CHKERRQ(ierr);
113 ierr = PetscDrawLine(draw,xr,yl,xl,yl,PETSC_DRAW_BLACK);CHKERRQ(ierr);
114 ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
115 ierr = PetscDrawFlush(draw);CHKERRQ(ierr);
116
117 draw->port_xl = xl + .05*h;
118 draw->port_xr = xr - .05*h;
119 draw->port_yl = yl + .05*h;
120 draw->port_yr = yr - .05*h;
121
122 if (draw->ops->setviewport) {
123 ierr = (*draw->ops->setviewport)(draw,xl,yl,xr,yr);CHKERRQ(ierr);
124 }
125 PetscFunctionReturn(0);
126 }
127
128 /*@C
129 PetscDrawViewPortsCreate - Splits a window into smaller view ports. Each processor shares all the viewports.
130
131 Collective on PetscDraw
132
133 Input Parameters:
134 + draw - the drawing context
135 - nports - the number of ports
136
137 Output Parameter:
138 . ports - a PetscDrawViewPorts context (C structure)
139
140 Options Database:
141 . -draw_ports - display multiple fields in the same window with PetscDrawPorts instead of in separate windows
142
143 Level: advanced
144
145 .seealso: PetscDrawSplitViewPort(), PetscDrawSetViewPort(), PetscDrawViewPortsSet(), PetscDrawViewPortsDestroy()
146
147 @*/
PetscDrawViewPortsCreate(PetscDraw draw,PetscInt nports,PetscDrawViewPorts ** newports)148 PetscErrorCode PetscDrawViewPortsCreate(PetscDraw draw,PetscInt nports,PetscDrawViewPorts **newports)
149 {
150 PetscDrawViewPorts *ports;
151 PetscInt i,n;
152 PetscBool isnull;
153 PetscMPIInt rank;
154 PetscReal *xl,*xr,*yl,*yr,h;
155 PetscErrorCode ierr;
156
157 PetscFunctionBegin;
158 PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
159 if (nports < 1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Number of divisions must be positive: %d", nports);
160 PetscValidPointer(newports,3);
161 ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
162 if (isnull) {*newports = NULL; PetscFunctionReturn(0);}
163 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);CHKERRQ(ierr);
164
165 ierr = PetscNew(&ports);CHKERRQ(ierr); *newports = ports;
166 ports->draw = draw;
167 ports->nports = nports;
168 ierr = PetscObjectReference((PetscObject)draw);CHKERRQ(ierr);
169 /* save previous drawport of window */
170 ierr = PetscDrawGetViewPort(draw,&ports->port_xl,&ports->port_yl,&ports->port_xr,&ports->port_yr);CHKERRQ(ierr);
171
172 n = (PetscInt)(.1 + PetscSqrtReal((PetscReal)nports));
173 while (n*n < nports) n++;
174 h = 1.0/n;
175
176 ierr = PetscMalloc4(n*n,&xl,n*n,&xr,n*n,&yl,n*n,&yr);CHKERRQ(ierr);
177 ports->xl = xl;
178 ports->xr = xr;
179 ports->yl = yl;
180 ports->yr = yr;
181
182 ierr = PetscDrawSetCoordinates(draw,0.0,0.0,1.0,1.0);CHKERRQ(ierr);
183 ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
184 for (i=0; i<n*n; i++) {
185 xl[i] = (i % n)*h;
186 xr[i] = xl[i] + h;
187 yl[i] = (i / n)*h;
188 yr[i] = yl[i] + h;
189
190 if (!rank) {
191 ierr = PetscDrawLine(draw,xl[i],yl[i],xl[i],yr[i],PETSC_DRAW_BLACK);CHKERRQ(ierr);
192 ierr = PetscDrawLine(draw,xl[i],yr[i],xr[i],yr[i],PETSC_DRAW_BLACK);CHKERRQ(ierr);
193 ierr = PetscDrawLine(draw,xr[i],yr[i],xr[i],yl[i],PETSC_DRAW_BLACK);CHKERRQ(ierr);
194 ierr = PetscDrawLine(draw,xr[i],yl[i],xl[i],yl[i],PETSC_DRAW_BLACK);CHKERRQ(ierr);
195 }
196
197 xl[i] += .05*h;
198 xr[i] -= .05*h;
199 yl[i] += .05*h;
200 yr[i] -= .05*h;
201 }
202 ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
203 ierr = PetscDrawFlush(draw);CHKERRQ(ierr);
204 PetscFunctionReturn(0);
205 }
206
207 /*@C
208 PetscDrawViewPortsCreateRect - Splits a window into smaller
209 view ports. Each processor shares all the viewports. The number
210 of views in the x- and y-directions is specified.
211
212 Collective on PetscDraw
213
214 Input Parameters:
215 + draw - the drawing context
216 . nx - the number of x divisions
217 - ny - the number of y divisions
218
219 Output Parameter:
220 . ports - a PetscDrawViewPorts context (C structure)
221
222 Level: advanced
223
224 .seealso: PetscDrawSplitViewPort(), PetscDrawSetViewPort(), PetscDrawViewPortsSet(), PetscDrawViewPortsDestroy()
225
226 @*/
PetscDrawViewPortsCreateRect(PetscDraw draw,PetscInt nx,PetscInt ny,PetscDrawViewPorts ** newports)227 PetscErrorCode PetscDrawViewPortsCreateRect(PetscDraw draw,PetscInt nx,PetscInt ny,PetscDrawViewPorts **newports)
228 {
229 PetscDrawViewPorts *ports;
230 PetscReal *xl,*xr,*yl,*yr,hx,hy;
231 PetscInt i,j,k,n;
232 PetscBool isnull;
233 PetscMPIInt rank;
234 PetscErrorCode ierr;
235
236 PetscFunctionBegin;
237 PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
238 if ((nx < 1) || (ny < 1)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Number of divisions must be positive: %d x %d", nx, ny);
239 PetscValidPointer(newports,3);
240 ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
241 if (isnull) {*newports = NULL; PetscFunctionReturn(0);}
242 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);CHKERRQ(ierr);
243
244 n = nx*ny;
245 hx = 1.0/nx;
246 hy = 1.0/ny;
247 ierr = PetscNew(&ports);CHKERRQ(ierr); *newports = ports;
248 ports->draw = draw;
249 ports->nports = n;
250 ierr = PetscObjectReference((PetscObject) draw);CHKERRQ(ierr);
251 /* save previous drawport of window */
252 ierr = PetscDrawGetViewPort(draw,&ports->port_xl,&ports->port_yl,&ports->port_xr,&ports->port_yr);CHKERRQ(ierr);
253
254 ierr = PetscMalloc4(n,&xl,n,&xr,n,&yl,n,&yr);CHKERRQ(ierr);
255 ports->xr = xr;
256 ports->xl = xl;
257 ports->yl = yl;
258 ports->yr = yr;
259
260 ierr = PetscDrawSetCoordinates(draw,0.0,0.0,1.0,1.0);CHKERRQ(ierr);
261 ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
262 for (i = 0; i < nx; i++) {
263 for (j = 0; j < ny; j++) {
264 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 if (!rank) {
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
278 xl[k] += .05*hx;
279 xr[k] -= .05*hx;
280 yl[k] += .05*hy;
281 yr[k] -= .05*hy;
282 }
283 }
284 ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
285 ierr = PetscDrawFlush(draw);CHKERRQ(ierr);
286 PetscFunctionReturn(0);
287 }
288
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 @*/
PetscDrawViewPortsDestroy(PetscDrawViewPorts * ports)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 = PetscFree4(ports->xl,ports->xr,ports->yl,ports->yr);CHKERRQ(ierr);
313 ierr = PetscFree(ports);CHKERRQ(ierr);
314 PetscFunctionReturn(0);
315 }
316
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 .seealso: PetscDrawSplitViewPort(), PetscDrawSetViewPort(), PetscDrawViewPortsDestroy(), PetscDrawViewPortsCreate()
329
330 @*/
PetscDrawViewPortsSet(PetscDrawViewPorts * ports,PetscInt port)331 PetscErrorCode PetscDrawViewPortsSet(PetscDrawViewPorts *ports,PetscInt port)
332 {
333 PetscErrorCode ierr;
334
335 PetscFunctionBegin;
336 if (!ports) PetscFunctionReturn(0);
337 PetscValidPointer(ports,1);
338 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);
339 ierr = PetscDrawSetViewPort(ports->draw,ports->xl[port],ports->yl[port],ports->xr[port],ports->yr[port]);CHKERRQ(ierr);
340 PetscFunctionReturn(0);
341 }
342