1 #include <../src/sys/classes/viewer/impls/draw/vdraw.h> /*I "petscdraw.h" I*/
2 #include <petscviewer.h> /*I "petscviewer.h" I*/
3
PetscViewerDestroy_Draw(PetscViewer v)4 static PetscErrorCode PetscViewerDestroy_Draw(PetscViewer v)
5 {
6 PetscInt i;
7 PetscViewer_Draw *vdraw = (PetscViewer_Draw *)v->data;
8
9 PetscFunctionBegin;
10 PetscCheck(!vdraw->singleton_made, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Destroying PetscViewer without first restoring singleton");
11 for (i = 0; i < vdraw->draw_max; i++) {
12 PetscCall(PetscDrawAxisDestroy(&vdraw->drawaxis[i]));
13 PetscCall(PetscDrawLGDestroy(&vdraw->drawlg[i]));
14 PetscCall(PetscDrawDestroy(&vdraw->draw[i]));
15 }
16 PetscCall(PetscFree(vdraw->display));
17 PetscCall(PetscFree(vdraw->title));
18 PetscCall(PetscFree3(vdraw->draw, vdraw->drawlg, vdraw->drawaxis));
19 PetscCall(PetscFree(vdraw->bounds));
20 PetscCall(PetscFree(vdraw->drawtype));
21 PetscCall(PetscFree(v->data));
22 PetscFunctionReturn(PETSC_SUCCESS);
23 }
24
PetscViewerFlush_Draw(PetscViewer v)25 static PetscErrorCode PetscViewerFlush_Draw(PetscViewer v)
26 {
27 PetscInt i;
28 PetscViewer_Draw *vdraw = (PetscViewer_Draw *)v->data;
29
30 PetscFunctionBegin;
31 for (i = 0; i < vdraw->draw_max; i++) {
32 if (vdraw->draw[i]) PetscCall(PetscDrawFlush(vdraw->draw[i]));
33 }
34 PetscFunctionReturn(PETSC_SUCCESS);
35 }
36
37 /*@
38 PetscViewerDrawBaseAdd - add to the base integer that is added to the `windownumber` passed to `PetscViewerDrawGetDraw()`
39
40 Logically Collective
41
42 Input Parameters:
43 + viewer - the `PetscViewer` (created with `PetscViewerDrawOpen()`)
44 - windownumber - how much to add to the base
45
46 Level: developer
47
48 Note:
49 A `PETSCVIEWERDRAW` may have multiple `PetscDraw` subwindows, this increases the number of the subwindow that is returned with `PetscViewerDrawGetDraw()`
50
51 .seealso: [](sec_viewers), `PetscViewerDrawGetLG()`, `PetscViewerDrawGetAxis()`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`, `PetscViewerDrawBaseSet()`
52 @*/
PetscViewerDrawBaseAdd(PetscViewer viewer,PetscInt windownumber)53 PetscErrorCode PetscViewerDrawBaseAdd(PetscViewer viewer, PetscInt windownumber)
54 {
55 PetscViewer_Draw *vdraw;
56 PetscBool isdraw;
57
58 PetscFunctionBegin;
59 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
60 PetscValidLogicalCollectiveInt(viewer, windownumber, 2);
61 PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
62 PetscCheck(isdraw, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Must be draw type PetscViewer");
63 vdraw = (PetscViewer_Draw *)viewer->data;
64
65 PetscCheck(windownumber + vdraw->draw_base >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Resulting base %" PetscInt_FMT " cannot be negative", windownumber + vdraw->draw_base);
66 vdraw->draw_base += windownumber;
67 PetscFunctionReturn(PETSC_SUCCESS);
68 }
69
70 /*@
71 PetscViewerDrawBaseSet - sets the base integer that is added to the `windownumber` passed to `PetscViewerDrawGetDraw()`
72
73 Logically Collective
74
75 Input Parameters:
76 + viewer - the `PetscViewer` (created with `PetscViewerDrawOpen()`)
77 - windownumber - value to set the base
78
79 Level: developer
80
81 Note:
82 A `PETSCVIEWERDRAW` may have multiple `PetscDraw` subwindows, this increases the number of the subwindow that is returned with `PetscViewerDrawGetDraw()`
83
84 .seealso: [](sec_viewers), `PetscViewerDrawGetLG()`, `PetscViewerDrawGetAxis()`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`, `PetscViewerDrawBaseAdd()`
85 @*/
PetscViewerDrawBaseSet(PetscViewer viewer,PetscInt windownumber)86 PetscErrorCode PetscViewerDrawBaseSet(PetscViewer viewer, PetscInt windownumber)
87 {
88 PetscViewer_Draw *vdraw;
89 PetscBool isdraw;
90
91 PetscFunctionBegin;
92 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
93 PetscValidLogicalCollectiveInt(viewer, windownumber, 2);
94 PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
95 PetscCheck(isdraw, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Must be draw type PetscViewer");
96 vdraw = (PetscViewer_Draw *)viewer->data;
97
98 PetscCheck(windownumber >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Resulting base %" PetscInt_FMT " cannot be negative", windownumber);
99 vdraw->draw_base = windownumber;
100 PetscFunctionReturn(PETSC_SUCCESS);
101 }
102
PetscViewerDrawResize(PetscViewer v,int w,int h)103 PetscErrorCode PetscViewerDrawResize(PetscViewer v, int w, int h)
104 {
105 PetscViewer_Draw *vdraw;
106 PetscBool isdraw;
107
108 PetscFunctionBegin;
109 PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 1);
110 PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERDRAW, &isdraw));
111 if (!isdraw) PetscFunctionReturn(PETSC_SUCCESS);
112 vdraw = (PetscViewer_Draw *)v->data;
113
114 if (w >= 1) vdraw->w = w;
115 if (h >= 1) vdraw->h = h;
116 PetscFunctionReturn(PETSC_SUCCESS);
117 }
118
PetscViewerDrawSetInfo(PetscViewer v,const char display[],const char title[],int x,int y,int w,int h)119 PetscErrorCode PetscViewerDrawSetInfo(PetscViewer v, const char display[], const char title[], int x, int y, int w, int h)
120 {
121 PetscViewer_Draw *vdraw;
122 PetscBool isdraw;
123
124 PetscFunctionBegin;
125 PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 1);
126 PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERDRAW, &isdraw));
127 if (!isdraw) PetscFunctionReturn(PETSC_SUCCESS);
128 vdraw = (PetscViewer_Draw *)v->data;
129
130 PetscCall(PetscStrallocpy(display, &vdraw->display));
131 PetscCall(PetscStrallocpy(title, &vdraw->title));
132 if (w >= 1) vdraw->w = w;
133 if (h >= 1) vdraw->h = h;
134 PetscFunctionReturn(PETSC_SUCCESS);
135 }
136
PetscViewerDrawSetTitle(PetscViewer v,const char title[])137 PetscErrorCode PetscViewerDrawSetTitle(PetscViewer v, const char title[])
138 {
139 PetscViewer_Draw *vdraw;
140 PetscBool isdraw;
141
142 PetscFunctionBegin;
143 PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 1);
144 PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERDRAW, &isdraw));
145 if (!isdraw) PetscFunctionReturn(PETSC_SUCCESS);
146 vdraw = (PetscViewer_Draw *)v->data;
147
148 PetscCall(PetscFree(vdraw->title));
149 PetscCall(PetscStrallocpy(title, &vdraw->title));
150 PetscFunctionReturn(PETSC_SUCCESS);
151 }
152
PetscViewerDrawGetTitle(PetscViewer v,const char * title[])153 PetscErrorCode PetscViewerDrawGetTitle(PetscViewer v, const char *title[])
154 {
155 PetscViewer_Draw *vdraw;
156 PetscBool isdraw;
157
158 PetscFunctionBegin;
159 PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 1);
160 PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERDRAW, &isdraw));
161 PetscCheck(isdraw, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Must be draw type PetscViewer");
162 vdraw = (PetscViewer_Draw *)v->data;
163
164 *title = vdraw->title;
165 PetscFunctionReturn(PETSC_SUCCESS);
166 }
167
168 /*@
169 PetscViewerDrawOpen - Opens a `PetscDraw` window for use as a `PetscViewer` with type
170 `PETSCVIEWERDRAW`.
171
172 Collective
173
174 Input Parameters:
175 + comm - communicator that will share window
176 . display - the X display on which to open, or `NULL` for the local machine
177 . title - the title to put in the title bar, or `NULL` for no title
178 . x - horizontal screen coordinate of the upper left corner of window, or use `PETSC_DECIDE`
179 . y - vertical screen coordinate of the upper left corner of window, or use `PETSC_DECIDE`
180 . w - window width in pixels, or may use `PETSC_DECIDE` or `PETSC_DRAW_FULL_SIZE`, `PETSC_DRAW_HALF_SIZE`,`PETSC_DRAW_THIRD_SIZE`, `PETSC_DRAW_QUARTER_SIZE`
181 - h - window height in pixels, or may use `PETSC_DECIDE` or `PETSC_DRAW_FULL_SIZE`, `PETSC_DRAW_HALF_SIZE`,`PETSC_DRAW_THIRD_SIZE`, `PETSC_DRAW_QUARTER_SIZE`
182
183 Output Parameter:
184 . viewer - the `PetscViewer`
185
186 Options Database Keys:
187 + -draw_type - use x or null
188 . -nox - Disables all x-windows output
189 . -display <name> - Specifies name of machine for the X display
190 . -geometry <x,y,w,h> - allows setting the window location and size
191 - -draw_pause <pause> - Sets time (in seconds) that the
192 program pauses after `PetscDrawPause()` has been called
193 (0 is default, -1 implies until user input).
194
195 Level: beginner
196
197 Notes:
198 If you want to do graphics in this window, you must call `PetscViewerDrawGetDraw()` and
199 perform the graphics on the `PetscDraw` object.
200
201 Format options include\:
202 + `PETSC_VIEWER_DRAW_BASIC` - displays with basic format
203 - `PETSC_VIEWER_DRAW_LG` - displays using a line graph
204
205 Fortran Note:
206 Whenever indicating null character data in a Fortran code,
207 `PETSC_NULL_CHARACTER` must be employed. Thus, `PETSC_NULL_CHARACTER` can be
208 used for the `display` and `title` input parameters.
209
210 .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscDrawCreate()`, `PetscViewerDestroy()`, `PetscViewerDrawGetDraw()`, `PetscViewerCreate()`, `PETSC_VIEWER_DRAW_`,
211 `PETSC_VIEWER_DRAW_WORLD`, `PETSC_VIEWER_DRAW_SELF`
212 @*/
PetscViewerDrawOpen(MPI_Comm comm,const char display[],const char title[],int x,int y,int w,int h,PetscViewer * viewer)213 PetscErrorCode PetscViewerDrawOpen(MPI_Comm comm, const char display[], const char title[], int x, int y, int w, int h, PetscViewer *viewer)
214 {
215 PetscFunctionBegin;
216 PetscCall(PetscViewerCreate(comm, viewer));
217 PetscCall(PetscViewerSetType(*viewer, PETSCVIEWERDRAW));
218 PetscCall(PetscViewerDrawSetInfo(*viewer, display, title, x, y, w, h));
219 PetscFunctionReturn(PETSC_SUCCESS);
220 }
221
222 #include <petsc/private/drawimpl.h>
223
PetscViewerGetSubViewer_Draw(PetscViewer viewer,MPI_Comm comm,PetscViewer * sviewer)224 static PetscErrorCode PetscViewerGetSubViewer_Draw(PetscViewer viewer, MPI_Comm comm, PetscViewer *sviewer)
225 {
226 PetscMPIInt rank;
227 PetscInt i;
228 PetscViewer_Draw *vdraw = (PetscViewer_Draw *)viewer->data, *svdraw;
229
230 PetscFunctionBegin;
231 PetscCheck(!vdraw->singleton_made, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Trying to get SubViewer without first restoring previous");
232 /* only processor zero can use the PetscViewer draw singleton */
233 PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank));
234 if (rank == 0) {
235 PetscMPIInt flg;
236 PetscDraw draw, sdraw;
237
238 PetscCallMPI(MPI_Comm_compare(PETSC_COMM_SELF, comm, &flg));
239 PetscCheck(flg == MPI_IDENT || flg == MPI_CONGRUENT, PETSC_COMM_SELF, PETSC_ERR_SUP, "PetscViewerGetSubViewer() for PETSCVIEWERDRAW requires a singleton MPI_Comm");
240 PetscCall(PetscViewerCreate(comm, sviewer));
241 PetscCall(PetscViewerSetType(*sviewer, PETSCVIEWERDRAW));
242 svdraw = (PetscViewer_Draw *)(*sviewer)->data;
243 (*sviewer)->format = viewer->format;
244 for (i = 0; i < vdraw->draw_max; i++) { /* XXX this is wrong if svdraw->draw_max (initially 5) < vdraw->draw_max */
245 if (vdraw->draw[i]) PetscCall(PetscDrawGetSingleton(vdraw->draw[i], &svdraw->draw[i]));
246 }
247 PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw));
248 PetscCall(PetscViewerDrawGetDraw(*sviewer, 0, &sdraw));
249 if (draw->savefilename) {
250 PetscCall(PetscDrawSetSave(sdraw, draw->savefilename));
251 sdraw->savefilecount = draw->savefilecount;
252 sdraw->savesinglefile = draw->savesinglefile;
253 sdraw->savemoviefps = draw->savemoviefps;
254 sdraw->saveonclear = draw->saveonclear;
255 sdraw->saveonflush = draw->saveonflush;
256 }
257 if (draw->savefinalfilename) PetscCall(PetscDrawSetSaveFinalImage(sdraw, draw->savefinalfilename));
258 } else {
259 PetscDraw draw;
260 PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw));
261 }
262 vdraw->singleton_made = PETSC_TRUE;
263 PetscFunctionReturn(PETSC_SUCCESS);
264 }
265
PetscViewerRestoreSubViewer_Draw(PetscViewer viewer,MPI_Comm comm,PetscViewer * sviewer)266 static PetscErrorCode PetscViewerRestoreSubViewer_Draw(PetscViewer viewer, MPI_Comm comm, PetscViewer *sviewer)
267 {
268 PetscMPIInt rank;
269 PetscInt i;
270 PetscViewer_Draw *vdraw = (PetscViewer_Draw *)viewer->data, *svdraw;
271
272 PetscFunctionBegin;
273 PetscCheck(vdraw->singleton_made, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Trying to restore a singleton that was not gotten");
274 PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank));
275 if (rank == 0) {
276 PetscDraw draw, sdraw;
277
278 PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw));
279 PetscCall(PetscViewerDrawGetDraw(*sviewer, 0, &sdraw));
280 if (draw->savefilename) {
281 draw->savefilecount = sdraw->savefilecount;
282 PetscCallMPI(MPI_Bcast(&draw->savefilecount, 1, MPIU_INT, 0, PetscObjectComm((PetscObject)draw)));
283 }
284 svdraw = (PetscViewer_Draw *)(*sviewer)->data;
285 for (i = 0; i < vdraw->draw_max; i++) {
286 if (vdraw->draw[i] && svdraw->draw[i]) PetscCall(PetscDrawRestoreSingleton(vdraw->draw[i], &svdraw->draw[i]));
287 }
288 PetscCall(PetscFree3(svdraw->draw, svdraw->drawlg, svdraw->drawaxis));
289 PetscCall(PetscFree((*sviewer)->data));
290 PetscCall(PetscHeaderDestroy(sviewer));
291 } else {
292 PetscDraw draw;
293
294 PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw));
295 if (draw->savefilename) PetscCallMPI(MPI_Bcast(&draw->savefilecount, 1, MPIU_INT, 0, PetscObjectComm((PetscObject)draw)));
296 }
297
298 vdraw->singleton_made = PETSC_FALSE;
299 PetscFunctionReturn(PETSC_SUCCESS);
300 }
301
PetscViewerSetFromOptions_Draw(PetscViewer v,PetscOptionItems PetscOptionsObject)302 static PetscErrorCode PetscViewerSetFromOptions_Draw(PetscViewer v, PetscOptionItems PetscOptionsObject)
303 {
304 PetscReal bounds[16];
305 PetscInt nbounds = 16;
306 PetscBool flg;
307
308 PetscFunctionBegin;
309 PetscOptionsHeadBegin(PetscOptionsObject, "Draw PetscViewer Options");
310 PetscCall(PetscOptionsRealArray("-draw_bounds", "Bounds to put on plots axis", "PetscViewerDrawSetBounds", bounds, &nbounds, &flg));
311 if (flg) PetscCall(PetscViewerDrawSetBounds(v, nbounds / 2, bounds));
312 PetscOptionsHeadEnd();
313 PetscFunctionReturn(PETSC_SUCCESS);
314 }
315
PetscViewerView_Draw(PetscViewer viewer,PetscViewer v)316 static PetscErrorCode PetscViewerView_Draw(PetscViewer viewer, PetscViewer v)
317 {
318 PetscDraw draw;
319 PetscInt i;
320 PetscViewer_Draw *vdraw = (PetscViewer_Draw *)viewer->data;
321 PetscBool isascii;
322
323 PetscFunctionBegin;
324 PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERASCII, &isascii));
325 if (isascii) PetscCall(PetscViewerASCIIPrintf(v, "Draw viewer is of type %s\n", vdraw->drawtype));
326 /* If the PetscViewer has just been created then no vdraw->draw yet
327 exists so this will not actually call the viewer on any draws. */
328 for (i = 0; i < vdraw->draw_base; i++) {
329 if (vdraw->draw[i]) {
330 PetscCall(PetscViewerDrawGetDraw(viewer, i, &draw));
331 PetscCall(PetscDrawView(draw, v));
332 }
333 }
334 PetscFunctionReturn(PETSC_SUCCESS);
335 }
336
337 /*MC
338 PETSCVIEWERDRAW - A viewer that generates graphics, either to the screen or a file
339
340 Level: beginner
341
342 .seealso: [](sec_viewers), `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`, `PETSC_VIEWER_DRAW_()`, `PETSC_VIEWER_DRAW_SELF`, `PETSC_VIEWER_DRAW_WORLD`,
343 `PetscViewerCreate()`, `PetscViewerASCIIOpen()`, `PetscViewerBinaryOpen()`, `PETSCVIEWERBINARY`,
344 `PetscViewerMatlabOpen()`, `VecView()`, `DMView()`, `PetscViewerMatlabPutArray()`, `PETSCVIEWERASCII`, `PETSCVIEWERMATLAB`,
345 `PetscViewerFileSetName()`, `PetscViewerFileSetMode()`, `PetscViewerFormat`, `PetscViewerType`, `PetscViewerSetType()`
346 M*/
PetscViewerCreate_Draw(PetscViewer viewer)347 PETSC_EXTERN PetscErrorCode PetscViewerCreate_Draw(PetscViewer viewer)
348 {
349 PetscViewer_Draw *vdraw;
350
351 PetscFunctionBegin;
352 PetscCall(PetscNew(&vdraw));
353 viewer->data = (void *)vdraw;
354
355 viewer->ops->flush = PetscViewerFlush_Draw;
356 viewer->ops->view = PetscViewerView_Draw;
357 viewer->ops->destroy = PetscViewerDestroy_Draw;
358 viewer->ops->setfromoptions = PetscViewerSetFromOptions_Draw;
359 viewer->ops->getsubviewer = PetscViewerGetSubViewer_Draw;
360 viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_Draw;
361
362 /* these are created on the fly if requested */
363 vdraw->draw_max = 5;
364 vdraw->draw_base = 0;
365 vdraw->w = PETSC_DECIDE;
366 vdraw->h = PETSC_DECIDE;
367
368 PetscCall(PetscCalloc3(vdraw->draw_max, &vdraw->draw, vdraw->draw_max, &vdraw->drawlg, vdraw->draw_max, &vdraw->drawaxis));
369 vdraw->singleton_made = PETSC_FALSE;
370 PetscFunctionReturn(PETSC_SUCCESS);
371 }
372
373 /*@
374 PetscViewerDrawClear - Clears a `PetscDraw` graphic associated with a `PetscViewer`.
375
376 Not Collective
377
378 Input Parameter:
379 . viewer - the `PetscViewer`
380
381 Level: intermediate
382
383 .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`,
384 @*/
PetscViewerDrawClear(PetscViewer viewer)385 PetscErrorCode PetscViewerDrawClear(PetscViewer viewer)
386 {
387 PetscViewer_Draw *vdraw;
388 PetscBool isdraw;
389 PetscInt i;
390
391 PetscFunctionBegin;
392 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
393 PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
394 if (!isdraw) PetscFunctionReturn(PETSC_SUCCESS);
395 vdraw = (PetscViewer_Draw *)viewer->data;
396
397 for (i = 0; i < vdraw->draw_max; i++) {
398 if (vdraw->draw[i]) PetscCall(PetscDrawClear(vdraw->draw[i]));
399 }
400 PetscFunctionReturn(PETSC_SUCCESS);
401 }
402
403 /*@
404 PetscViewerDrawGetPause - Gets the pause value (how long to pause before an image is changed) in the `PETSCVIEWERDRAW` `PetscViewer`
405
406 Not Collective
407
408 Input Parameter:
409 . viewer - the `PetscViewer`
410
411 Output Parameter:
412 . pause - the pause value
413
414 Level: intermediate
415
416 .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`,
417 @*/
PetscViewerDrawGetPause(PetscViewer viewer,PetscReal * pause)418 PetscErrorCode PetscViewerDrawGetPause(PetscViewer viewer, PetscReal *pause)
419 {
420 PetscViewer_Draw *vdraw;
421 PetscBool isdraw;
422 PetscInt i;
423 PetscDraw draw;
424
425 PetscFunctionBegin;
426 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
427 PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
428 if (!isdraw) {
429 *pause = 0.0;
430 PetscFunctionReturn(PETSC_SUCCESS);
431 }
432 vdraw = (PetscViewer_Draw *)viewer->data;
433
434 for (i = 0; i < vdraw->draw_max; i++) {
435 if (vdraw->draw[i]) {
436 PetscCall(PetscDrawGetPause(vdraw->draw[i], pause));
437 PetscFunctionReturn(PETSC_SUCCESS);
438 }
439 }
440 /* none exist yet so create one and get its pause */
441 PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw));
442 PetscCall(PetscDrawGetPause(draw, pause));
443 PetscFunctionReturn(PETSC_SUCCESS);
444 }
445
446 /*@
447 PetscViewerDrawSetPause - Sets a pause for each `PetscDraw` in the `PETSCVIEWERDRAW` `PetscViewer`
448
449 Not Collective
450
451 Input Parameters:
452 + viewer - the `PetscViewer`
453 - pause - the pause value
454
455 Level: intermediate
456
457 .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`,
458 @*/
PetscViewerDrawSetPause(PetscViewer viewer,PetscReal pause)459 PetscErrorCode PetscViewerDrawSetPause(PetscViewer viewer, PetscReal pause)
460 {
461 PetscViewer_Draw *vdraw;
462 PetscBool isdraw;
463 PetscInt i;
464
465 PetscFunctionBegin;
466 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
467 PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
468 if (!isdraw) PetscFunctionReturn(PETSC_SUCCESS);
469 vdraw = (PetscViewer_Draw *)viewer->data;
470
471 vdraw->pause = pause;
472 for (i = 0; i < vdraw->draw_max; i++) {
473 if (vdraw->draw[i]) PetscCall(PetscDrawSetPause(vdraw->draw[i], pause));
474 }
475 PetscFunctionReturn(PETSC_SUCCESS);
476 }
477
478 /*@
479 PetscViewerDrawSetHold - Holds previous image when drawing new image in a `PETSCVIEWERDRAW`
480
481 Not Collective
482
483 Input Parameters:
484 + viewer - the `PetscViewer`
485 - hold - `PETSC_TRUE` indicates to hold the previous image
486
487 Level: intermediate
488
489 .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`,
490 @*/
PetscViewerDrawSetHold(PetscViewer viewer,PetscBool hold)491 PetscErrorCode PetscViewerDrawSetHold(PetscViewer viewer, PetscBool hold)
492 {
493 PetscViewer_Draw *vdraw;
494 PetscBool isdraw;
495
496 PetscFunctionBegin;
497 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
498 PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
499 if (!isdraw) PetscFunctionReturn(PETSC_SUCCESS);
500 vdraw = (PetscViewer_Draw *)viewer->data;
501
502 vdraw->hold = hold;
503 PetscFunctionReturn(PETSC_SUCCESS);
504 }
505
506 /*@
507 PetscViewerDrawGetHold - Checks if the `PETSCVIEWERDRAW` `PetscViewer` holds previous image when drawing new image
508
509 Not Collective
510
511 Input Parameter:
512 . viewer - the `PetscViewer`
513
514 Output Parameter:
515 . hold - indicates to hold or not
516
517 Level: intermediate
518
519 .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`,
520 @*/
PetscViewerDrawGetHold(PetscViewer viewer,PetscBool * hold)521 PetscErrorCode PetscViewerDrawGetHold(PetscViewer viewer, PetscBool *hold)
522 {
523 PetscViewer_Draw *vdraw;
524 PetscBool isdraw;
525
526 PetscFunctionBegin;
527 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
528 PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
529 if (!isdraw) {
530 *hold = PETSC_FALSE;
531 PetscFunctionReturn(PETSC_SUCCESS);
532 }
533 vdraw = (PetscViewer_Draw *)viewer->data;
534
535 *hold = vdraw->hold;
536 PetscFunctionReturn(PETSC_SUCCESS);
537 }
538
539 /*
540 The variable Petsc_Viewer_Draw_keyval is used to indicate an MPI attribute that
541 is attached to a communicator, in this case the attribute is a PetscViewer.
542 */
543 PetscMPIInt Petsc_Viewer_Draw_keyval = MPI_KEYVAL_INVALID;
544
545 /*@C
546 PETSC_VIEWER_DRAW_ - Creates a window `PETSCVIEWERDRAW` `PetscViewer` shared by all processors
547 in an MPI communicator.
548
549 Collective
550
551 Input Parameter:
552 . comm - the MPI communicator to share the window `PetscViewer`
553
554 Level: intermediate
555
556 Notes:
557 This object is destroyed in `PetscFinalize()`, `PetscViewerDestroy()` should never be called on it
558
559 Unlike almost all other PETSc routines, `PETSC_VIEWER_DRAW_()` does not return
560 an error code. The window is usually used in the form
561 .vb
562 XXXView(XXX object, PETSC_VIEWER_DRAW_(comm));
563 .ve
564
565 .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewer`, `PETSC_VIEWER_DRAW_WORLD`, `PETSC_VIEWER_DRAW_SELF`, `PetscViewerDrawOpen()`,
566 @*/
PETSC_VIEWER_DRAW_(MPI_Comm comm)567 PetscViewer PETSC_VIEWER_DRAW_(MPI_Comm comm)
568 {
569 PetscMPIInt iflg;
570 PetscViewer viewer;
571 MPI_Comm ncomm;
572
573 PetscFunctionBegin;
574 PetscCallNull(PetscCommDuplicate(comm, &ncomm, NULL));
575 if (Petsc_Viewer_Draw_keyval == MPI_KEYVAL_INVALID) PetscCallMPINull(MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN, MPI_COMM_NULL_DELETE_FN, &Petsc_Viewer_Draw_keyval, NULL));
576 PetscCallMPINull(MPI_Comm_get_attr(ncomm, Petsc_Viewer_Draw_keyval, (void **)&viewer, &iflg));
577 if (!iflg) { /* PetscViewer not yet created */
578 PetscCallNull(PetscViewerDrawOpen(ncomm, NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 300, 300, &viewer));
579 PetscCallNull(PetscObjectRegisterDestroy((PetscObject)viewer));
580 PetscCallMPINull(MPI_Comm_set_attr(ncomm, Petsc_Viewer_Draw_keyval, (void *)viewer));
581 }
582 PetscCallNull(PetscCommDestroy(&ncomm));
583 PetscFunctionReturn(viewer);
584 }
585
586 /*@
587 PetscViewerDrawSetBounds - sets the upper and lower bounds to be used in plotting in a `PETSCVIEWERDRAW` `PetscViewer`
588
589 Collective
590
591 Input Parameters:
592 + viewer - the `PetscViewer` (created with `PetscViewerDrawOpen()`)
593 . nbounds - number of plots that can be made with this viewer, for example the dof passed to `DMDACreate()`
594 - bounds - the actual bounds, the size of this is 2*`nbounds`, the values are stored in the order min F_0, max F_0, min F_1, max F_1, .....
595
596 Options Database Key:
597 . -draw_bounds minF0,maxF0,minF1,maxF1 - the lower left and upper right bounds
598
599 Level: intermediate
600
601 Note:
602 this determines the colors used in 2d contour plots generated with VecView() for `DMDA` in 2d. Any values in the vector below or above the
603 bounds are moved to the bound value before plotting. In this way the color index from color to physical value remains the same for all plots generated with
604 this viewer. Otherwise the color to physical value meaning changes with each new image if this is not set.
605
606 .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewerDrawGetLG()`, `PetscViewerDrawGetAxis()`, `PetscViewerDrawOpen()`
607 @*/
PetscViewerDrawSetBounds(PetscViewer viewer,PetscInt nbounds,const PetscReal * bounds)608 PetscErrorCode PetscViewerDrawSetBounds(PetscViewer viewer, PetscInt nbounds, const PetscReal *bounds)
609 {
610 PetscViewer_Draw *vdraw;
611 PetscBool isdraw;
612
613 PetscFunctionBegin;
614 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
615 PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
616 if (!isdraw) PetscFunctionReturn(PETSC_SUCCESS);
617 vdraw = (PetscViewer_Draw *)viewer->data;
618
619 vdraw->nbounds = nbounds;
620 PetscCall(PetscFree(vdraw->bounds));
621 PetscCall(PetscMalloc1(2 * nbounds, &vdraw->bounds));
622 PetscCall(PetscArraycpy(vdraw->bounds, bounds, 2 * nbounds));
623 PetscFunctionReturn(PETSC_SUCCESS);
624 }
625
626 /*@C
627 PetscViewerDrawGetBounds - gets the upper and lower bounds to be used in plotting set with `PetscViewerDrawSetBounds()`
628
629 Collective
630
631 Input Parameter:
632 . viewer - the `PetscViewer` (created with `PetscViewerDrawOpen()`)
633
634 Output Parameters:
635 + nbounds - number of plots that can be made with this viewer, for example the dof passed to `DMDACreate()`
636 - bounds - the actual bounds, the size of this is 2*`nbounds`, the values are stored in the order min F_0, max F_0, min F_1, max F_1, .....
637
638 Level: intermediate
639
640 .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewerDrawGetLG()`, `PetscViewerDrawGetAxis()`, `PetscViewerDrawOpen()`, `PetscViewerDrawSetBounds()`
641 @*/
PetscViewerDrawGetBounds(PetscViewer viewer,PetscInt * nbounds,const PetscReal * bounds[])642 PetscErrorCode PetscViewerDrawGetBounds(PetscViewer viewer, PetscInt *nbounds, const PetscReal *bounds[])
643 {
644 PetscViewer_Draw *vdraw;
645 PetscBool isdraw;
646
647 PetscFunctionBegin;
648 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
649 PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
650 if (!isdraw) {
651 if (nbounds) *nbounds = 0;
652 if (bounds) *bounds = NULL;
653 PetscFunctionReturn(PETSC_SUCCESS);
654 }
655 vdraw = (PetscViewer_Draw *)viewer->data;
656
657 if (nbounds) *nbounds = vdraw->nbounds;
658 if (bounds) *bounds = vdraw->bounds;
659 PetscFunctionReturn(PETSC_SUCCESS);
660 }
661
662 /*@C
663 PetscViewerMonitorLGSetUp - sets up a viewer to be used by line graph monitoring routines such as `KSPMonitorResidualDrawLG()`
664
665 Collective
666
667 Input Parameters:
668 + viewer - the viewer in which to display the line graphs, it not a `PETSCVIEWERDRAW` it will set to that `PetscViewerType`
669 . host - the host to open the window on, 'NULL' indicates the local host
670 . title - the title at the top of the window
671 . metric - the label above the graph
672 . l - the number of curves
673 . names - the names of each curve to be used in displaying the legend. May be 'NULL'
674 . x - horizontal screen coordinate of the upper left corner of window, or use `PETSC_DECIDE`
675 . y - vertical screen coordinate of the upper left corner of window, or use `PETSC_DECIDE`
676 . m - window width in pixels, or may use `PETSC_DECIDE` or `PETSC_DRAW_FULL_SIZE`, `PETSC_DRAW_HALF_SIZE`,`PETSC_DRAW_THIRD_SIZE`, `PETSC_DRAW_QUARTER_SIZE`
677 - n - window height in pixels, or may use `PETSC_DECIDE` or `PETSC_DRAW_FULL_SIZE`, `PETSC_DRAW_HALF_SIZE`,`PETSC_DRAW_THIRD_SIZE`, `PETSC_DRAW_QUARTER_SIZE`
678
679 Level: developer
680
681 .seealso: `PetscViewer()`, `PETSCVIEWERDRAW`, `PetscViewerDrawGetDrawLG()`, `PetscViewerDrawOpen()`, `PetscViewerDrawSetInfo()`
682 @*/
PetscViewerMonitorLGSetUp(PetscViewer viewer,const char host[],const char title[],const char metric[],PetscInt l,const char * names[],int x,int y,int m,int n)683 PetscErrorCode PetscViewerMonitorLGSetUp(PetscViewer viewer, const char host[], const char title[], const char metric[], PetscInt l, const char *names[], int x, int y, int m, int n) PeNS
684 {
685 PetscDrawAxis axis;
686 PetscDrawLG lg;
687
688 PetscFunctionBegin;
689 PetscCall(PetscViewerSetType(viewer, PETSCVIEWERDRAW));
690 PetscCall(PetscViewerDrawSetInfo(viewer, host, title, x, y, m, n));
691 PetscCall(PetscViewerDrawGetDrawLG(viewer, 0, &lg));
692 if (names) PetscCall(PetscDrawLGSetLegend(lg, names));
693 PetscCall(PetscDrawLGSetFromOptions(lg));
694 PetscCall(PetscDrawLGGetAxis(lg, &axis));
695 PetscCall(PetscDrawAxisSetLabels(axis, "Convergence", "Iteration", metric));
696 PetscFunctionReturn(PETSC_SUCCESS);
697 }
698