1 #include <petsc/private/drawimpl.h> /*I "petscdraw.h" I*/
2 #include <petscviewer.h>
3
4 PetscClassId PETSC_DRAW_CLASSID;
5
6 static PetscBool PetscDrawPackageInitialized = PETSC_FALSE;
7 /*@C
8 PetscDrawFinalizePackage - This function destroys everything in the PETSc interface to the `PetscDraw` package. It is
9 called from `PetscFinalize()`.
10
11 Level: developer
12
13 .seealso: `PetscDraw`, `PetscFinalize()`
14 @*/
PetscDrawFinalizePackage(void)15 PetscErrorCode PetscDrawFinalizePackage(void)
16 {
17 PetscFunctionBegin;
18 PetscCall(PetscFunctionListDestroy(&PetscDrawList));
19 PetscDrawPackageInitialized = PETSC_FALSE;
20 PetscDrawRegisterAllCalled = PETSC_FALSE;
21 PetscFunctionReturn(PETSC_SUCCESS);
22 }
23
24 /*@C
25 PetscDrawInitializePackage - This function initializes everything in the `PetscDraw` package. It is called
26 from PetscDLLibraryRegister_petsc() when using dynamic libraries, and on the call to `PetscInitialize()`
27 when using shared or static libraries.
28
29 Level: developer
30
31 .seealso: `PetscDraw`, `PetscInitialize()`
32 @*/
PetscDrawInitializePackage(void)33 PetscErrorCode PetscDrawInitializePackage(void)
34 {
35 char logList[256];
36 PetscBool opt, pkg;
37
38 PetscFunctionBegin;
39 if (PetscDrawPackageInitialized) PetscFunctionReturn(PETSC_SUCCESS);
40 PetscDrawPackageInitialized = PETSC_TRUE;
41 /* Register Classes */
42 PetscCall(PetscClassIdRegister("Draw", &PETSC_DRAW_CLASSID));
43 PetscCall(PetscClassIdRegister("Draw Axis", &PETSC_DRAWAXIS_CLASSID));
44 PetscCall(PetscClassIdRegister("Line Graph", &PETSC_DRAWLG_CLASSID));
45 PetscCall(PetscClassIdRegister("Histogram", &PETSC_DRAWHG_CLASSID));
46 PetscCall(PetscClassIdRegister("Bar Graph", &PETSC_DRAWBAR_CLASSID));
47 PetscCall(PetscClassIdRegister("Scatter Plot", &PETSC_DRAWSP_CLASSID));
48 /* Register Constructors */
49 PetscCall(PetscDrawRegisterAll());
50 /* Process Info */
51 {
52 PetscClassId classids[6];
53
54 classids[0] = PETSC_DRAW_CLASSID;
55 classids[1] = PETSC_DRAWAXIS_CLASSID;
56 classids[2] = PETSC_DRAWLG_CLASSID;
57 classids[3] = PETSC_DRAWHG_CLASSID;
58 classids[4] = PETSC_DRAWBAR_CLASSID;
59 classids[5] = PETSC_DRAWSP_CLASSID;
60 PetscCall(PetscInfoProcessClass("draw", 6, classids));
61 }
62 /* Process summary exclusions */
63 PetscCall(PetscOptionsGetString(NULL, NULL, "-log_exclude", logList, sizeof(logList), &opt));
64 if (opt) {
65 PetscCall(PetscStrInList("draw", logList, ',', &pkg));
66 if (pkg) {
67 PetscCall(PetscLogEventExcludeClass(PETSC_DRAW_CLASSID));
68 PetscCall(PetscLogEventExcludeClass(PETSC_DRAWAXIS_CLASSID));
69 PetscCall(PetscLogEventExcludeClass(PETSC_DRAWLG_CLASSID));
70 PetscCall(PetscLogEventExcludeClass(PETSC_DRAWHG_CLASSID));
71 PetscCall(PetscLogEventExcludeClass(PETSC_DRAWBAR_CLASSID));
72 PetscCall(PetscLogEventExcludeClass(PETSC_DRAWSP_CLASSID));
73 }
74 }
75 /* Register package finalizer */
76 PetscCall(PetscRegisterFinalize(PetscDrawFinalizePackage));
77 PetscFunctionReturn(PETSC_SUCCESS);
78 }
79
80 /*@
81 PetscDrawResizeWindow - Allows one to resize a window from a program.
82
83 Collective
84
85 Input Parameters:
86 + draw - the window
87 . w - the new width of the window
88 - h - the new height of the window
89
90 Level: intermediate
91
92 .seealso: `PetscDraw`, `PetscDrawCheckResizedWindow()`
93 @*/
PetscDrawResizeWindow(PetscDraw draw,int w,int h)94 PetscErrorCode PetscDrawResizeWindow(PetscDraw draw, int w, int h)
95 {
96 PetscFunctionBegin;
97 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1);
98 PetscValidLogicalCollectiveInt(draw, w, 2);
99 PetscValidLogicalCollectiveInt(draw, h, 3);
100 PetscTryTypeMethod(draw, resizewindow, w, h);
101 PetscFunctionReturn(PETSC_SUCCESS);
102 }
103
104 /*@
105 PetscDrawGetWindowSize - Gets the size of the window.
106
107 Not Collective
108
109 Input Parameter:
110 . draw - the window
111
112 Output Parameters:
113 + w - the window width
114 - h - the window height
115
116 Level: intermediate
117
118 .seealso: `PetscDraw`, `PetscDrawResizeWindow()`, `PetscDrawCheckResizedWindow()`
119 @*/
PetscDrawGetWindowSize(PetscDraw draw,int * w,int * h)120 PetscErrorCode PetscDrawGetWindowSize(PetscDraw draw, int *w, int *h)
121 {
122 PetscFunctionBegin;
123 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1);
124 if (w) PetscAssertPointer(w, 2);
125 if (h) PetscAssertPointer(h, 3);
126 if (w) *w = draw->w;
127 if (h) *h = draw->h;
128 PetscFunctionReturn(PETSC_SUCCESS);
129 }
130
131 /*@
132 PetscDrawCheckResizedWindow - Checks if the user has resized the window.
133
134 Collective
135
136 Input Parameter:
137 . draw - the window
138
139 Level: advanced
140
141 .seealso: `PetscDraw`, `PetscDrawResizeWindow()`
142 @*/
PetscDrawCheckResizedWindow(PetscDraw draw)143 PetscErrorCode PetscDrawCheckResizedWindow(PetscDraw draw)
144 {
145 PetscFunctionBegin;
146 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1);
147 PetscTryTypeMethod(draw, checkresizedwindow);
148 PetscFunctionReturn(PETSC_SUCCESS);
149 }
150
151 /*@
152 PetscDrawGetTitle - Gets pointer to title of a `PetscDraw` context.
153
154 Not Collective
155
156 Input Parameter:
157 . draw - the graphics context
158
159 Output Parameter:
160 . title - the title
161
162 Level: intermediate
163
164 .seealso: `PetscDraw`, `PetscDrawSetTitle()`
165 @*/
PetscDrawGetTitle(PetscDraw draw,const char * title[])166 PetscErrorCode PetscDrawGetTitle(PetscDraw draw, const char *title[])
167 {
168 PetscFunctionBegin;
169 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1);
170 PetscAssertPointer(title, 2);
171 *title = draw->title;
172 PetscFunctionReturn(PETSC_SUCCESS);
173 }
174
175 /*@
176 PetscDrawSetTitle - Sets the title of a `PetscDraw` context.
177
178 Collective
179
180 Input Parameters:
181 + draw - the graphics context
182 - title - the title
183
184 Level: intermediate
185
186 Notes:
187 The title is positioned in the windowing system title bar for the window. Hence it will not be saved with -draw_save
188 in the image.
189
190 A copy of the string is made, so you may destroy the
191 title string after calling this routine.
192
193 You can use `PetscDrawAxisSetLabels()` to indicate a title within the window
194
195 .seealso: `PetscDraw`, `PetscDrawGetTitle()`, `PetscDrawAppendTitle()`
196 @*/
PetscDrawSetTitle(PetscDraw draw,const char title[])197 PetscErrorCode PetscDrawSetTitle(PetscDraw draw, const char title[])
198 {
199 PetscFunctionBegin;
200 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1);
201 PetscAssertPointer(title, 2);
202 PetscCall(PetscFree(draw->title));
203 PetscCall(PetscStrallocpy(title, &draw->title));
204 PetscTryTypeMethod(draw, settitle, draw->title);
205 PetscFunctionReturn(PETSC_SUCCESS);
206 }
207
208 /*@
209 PetscDrawAppendTitle - Appends to the title of a `PetscDraw` context.
210
211 Collective
212
213 Input Parameters:
214 + draw - the graphics context
215 - title - the title
216
217 Level: advanced
218
219 Note:
220 A copy of the string is made, so you may destroy the
221 title string after calling this routine.
222
223 .seealso: `PetscDraw`, `PetscDrawSetTitle()`, `PetscDrawGetTitle()`
224 @*/
PetscDrawAppendTitle(PetscDraw draw,const char title[])225 PetscErrorCode PetscDrawAppendTitle(PetscDraw draw, const char title[])
226 {
227 PetscFunctionBegin;
228 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1);
229 if (title) PetscAssertPointer(title, 2);
230 if (!title || !title[0]) PetscFunctionReturn(PETSC_SUCCESS);
231
232 if (draw->title) {
233 size_t len1, len2, new_len;
234 PetscCall(PetscStrlen(draw->title, &len1));
235 PetscCall(PetscStrlen(title, &len2));
236 new_len = len1 + len2 + 1;
237 PetscCall(PetscRealloc(new_len * sizeof(*draw->title), &draw->title));
238 PetscCall(PetscStrncpy(draw->title + len1, title, len2 + 1));
239 } else {
240 PetscCall(PetscStrallocpy(title, &draw->title));
241 }
242 PetscTryTypeMethod(draw, settitle, draw->title);
243 PetscFunctionReturn(PETSC_SUCCESS);
244 }
245
PetscDrawDestroy_Private(PetscDraw draw)246 static PetscErrorCode PetscDrawDestroy_Private(PetscDraw draw)
247 {
248 PetscFunctionBegin;
249 if (!draw->ops->save && !draw->ops->getimage) PetscFunctionReturn(PETSC_SUCCESS);
250 PetscCall(PetscDrawSaveMovie(draw));
251 if (draw->savefinalfilename) {
252 draw->savesinglefile = PETSC_TRUE;
253 PetscCall(PetscDrawSetSave(draw, draw->savefinalfilename));
254 PetscCall(PetscDrawSave(draw));
255 }
256 PetscCall(PetscBarrier((PetscObject)draw));
257 PetscFunctionReturn(PETSC_SUCCESS);
258 }
259
260 /*@
261 PetscDrawDestroy - Deletes a draw context.
262
263 Collective
264
265 Input Parameter:
266 . draw - the drawing context
267
268 Level: beginner
269
270 .seealso: `PetscDraw`, `PetscDrawCreate()`
271 @*/
PetscDrawDestroy(PetscDraw * draw)272 PetscErrorCode PetscDrawDestroy(PetscDraw *draw)
273 {
274 PetscFunctionBegin;
275 if (!*draw) PetscFunctionReturn(PETSC_SUCCESS);
276 PetscValidHeaderSpecific(*draw, PETSC_DRAW_CLASSID, 1);
277 if (--((PetscObject)*draw)->refct > 0) PetscFunctionReturn(PETSC_SUCCESS);
278
279 if ((*draw)->pause == -2) {
280 (*draw)->pause = -1;
281 PetscCall(PetscDrawPause(*draw));
282 }
283
284 /* if memory was published then destroy it */
285 PetscCall(PetscObjectSAWsViewOff((PetscObject)*draw));
286
287 PetscCall(PetscDrawDestroy_Private(*draw));
288
289 PetscTryTypeMethod(*draw, destroy);
290 PetscCall(PetscDrawDestroy(&(*draw)->popup));
291 PetscCall(PetscFree((*draw)->title));
292 PetscCall(PetscFree((*draw)->display));
293 PetscCall(PetscFree((*draw)->savefilename));
294 PetscCall(PetscFree((*draw)->saveimageext));
295 PetscCall(PetscFree((*draw)->savemovieext));
296 PetscCall(PetscFree((*draw)->savefinalfilename));
297 PetscCall(PetscHeaderDestroy(draw));
298 PetscFunctionReturn(PETSC_SUCCESS);
299 }
300
301 /*@
302 PetscDrawGetPopup - Creates a popup window associated with a `PetscDraw` window.
303
304 Collective
305
306 Input Parameter:
307 . draw - the original window
308
309 Output Parameter:
310 . popup - the new popup window
311
312 Level: advanced
313
314 .seealso: `PetscDraw`, `PetscDrawScalePopup()`, `PetscDrawCreate()`
315 @*/
PetscDrawGetPopup(PetscDraw draw,PetscDraw * popup)316 PetscErrorCode PetscDrawGetPopup(PetscDraw draw, PetscDraw *popup)
317 {
318 PetscFunctionBegin;
319 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1);
320 PetscAssertPointer(popup, 2);
321
322 if (draw->popup) *popup = draw->popup;
323 else if (draw->ops->getpopup) {
324 PetscUseTypeMethod(draw, getpopup, popup);
325 if (*popup) {
326 PetscCall(PetscObjectSetOptionsPrefix((PetscObject)*popup, "popup_"));
327 (*popup)->pause = 0.0;
328 PetscCall(PetscDrawSetFromOptions(*popup));
329 }
330 } else *popup = NULL;
331 PetscFunctionReturn(PETSC_SUCCESS);
332 }
333
334 /*@
335 PetscDrawSetDisplay - Sets the display where a `PetscDraw` object will be displayed
336
337 Input Parameters:
338 + draw - the drawing context
339 - display - the X windows display
340
341 Level: advanced
342
343 .seealso: `PetscDraw`, `PetscDrawOpenX()`, `PetscDrawCreate()`
344 @*/
PetscDrawSetDisplay(PetscDraw draw,const char display[])345 PetscErrorCode PetscDrawSetDisplay(PetscDraw draw, const char display[])
346 {
347 PetscFunctionBegin;
348 PetscCall(PetscFree(draw->display));
349 PetscCall(PetscStrallocpy(display, &draw->display));
350 PetscFunctionReturn(PETSC_SUCCESS);
351 }
352
353 /*@
354 PetscDrawSetDoubleBuffer - Sets a window to be double buffered.
355
356 Logically Collective
357
358 Input Parameter:
359 . draw - the drawing context
360
361 Level: intermediate
362
363 .seealso: `PetscDraw`, `PetscDrawOpenX()`, `PetscDrawCreate()`
364 @*/
PetscDrawSetDoubleBuffer(PetscDraw draw)365 PetscErrorCode PetscDrawSetDoubleBuffer(PetscDraw draw)
366 {
367 PetscFunctionBegin;
368 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1);
369 PetscTryTypeMethod(draw, setdoublebuffer);
370 PetscFunctionReturn(PETSC_SUCCESS);
371 }
372
373 /*@
374 PetscDrawGetSingleton - Gain access to a `PetscDraw` object as if it were owned
375 by the one process.
376
377 Collective
378
379 Input Parameter:
380 . draw - the original window
381
382 Output Parameter:
383 . sdraw - the singleton window
384
385 Level: advanced
386
387 .seealso: `PetscDraw`, `PetscDrawRestoreSingleton()`, `PetscViewerGetSingleton()`, `PetscViewerRestoreSingleton()`
388 @*/
PetscDrawGetSingleton(PetscDraw draw,PetscDraw * sdraw)389 PetscErrorCode PetscDrawGetSingleton(PetscDraw draw, PetscDraw *sdraw)
390 {
391 PetscMPIInt size;
392
393 PetscFunctionBegin;
394 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1);
395 PetscAssertPointer(sdraw, 2);
396
397 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)draw), &size));
398 if (size == 1) {
399 PetscCall(PetscObjectReference((PetscObject)draw));
400 *sdraw = draw;
401 } else PetscUseTypeMethod(draw, getsingleton, sdraw);
402 PetscFunctionReturn(PETSC_SUCCESS);
403 }
404
405 /*@
406 PetscDrawRestoreSingleton - Remove access to a `PetscDraw` object obtained with `PetscDrawGetSingleton()`
407 by the one process.
408
409 Collective
410
411 Input Parameters:
412 + draw - the original window
413 - sdraw - the singleton window
414
415 Level: advanced
416
417 .seealso: `PetscDraw`, `PetscDrawGetSingleton()`, `PetscViewerGetSingleton()`, `PetscViewerRestoreSingleton()`
418 @*/
PetscDrawRestoreSingleton(PetscDraw draw,PetscDraw * sdraw)419 PetscErrorCode PetscDrawRestoreSingleton(PetscDraw draw, PetscDraw *sdraw)
420 {
421 PetscMPIInt size;
422
423 PetscFunctionBegin;
424 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1);
425 PetscAssertPointer(sdraw, 2);
426 PetscValidHeaderSpecific(*sdraw, PETSC_DRAW_CLASSID, 2);
427
428 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)draw), &size));
429 if (size == 1) {
430 PetscCheck(draw == *sdraw, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Cannot restore singleton, it is not the parent draw");
431 PetscCall(PetscObjectDereference((PetscObject)draw));
432 *sdraw = NULL;
433 } else PetscUseTypeMethod(draw, restoresingleton, sdraw);
434 PetscFunctionReturn(PETSC_SUCCESS);
435 }
436
437 /*@
438 PetscDrawSetVisible - Sets if the drawing surface (the 'window') is visible on its display.
439
440 Input Parameters:
441 + draw - the drawing window
442 - visible - if the surface should be visible
443
444 Level: intermediate
445
446 .seealso: `PetscDraw`
447 @*/
PetscDrawSetVisible(PetscDraw draw,PetscBool visible)448 PetscErrorCode PetscDrawSetVisible(PetscDraw draw, PetscBool visible)
449 {
450 PetscFunctionBegin;
451 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1);
452 PetscTryTypeMethod(draw, setvisible, visible);
453 PetscFunctionReturn(PETSC_SUCCESS);
454 }
455