xref: /petsc/src/sys/classes/viewer/impls/draw/drawv.c (revision ce78bad369055609e946c9d2c25ea67a45873e27)
15c6c1daeSBarry Smith #include <../src/sys/classes/viewer/impls/draw/vdraw.h> /*I "petscdraw.h" I*/
2665c2dedSJed Brown #include <petscviewer.h>                                /*I "petscviewer.h" I*/
35c6c1daeSBarry Smith 
4d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscViewerDestroy_Draw(PetscViewer v)
5d71ae5a4SJacob Faibussowitsch {
65c6c1daeSBarry Smith   PetscInt          i;
75c6c1daeSBarry Smith   PetscViewer_Draw *vdraw = (PetscViewer_Draw *)v->data;
85c6c1daeSBarry Smith 
95c6c1daeSBarry Smith   PetscFunctionBegin;
1028b400f6SJacob Faibussowitsch   PetscCheck(!vdraw->singleton_made, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Destroying PetscViewer without first restoring singleton");
115c6c1daeSBarry Smith   for (i = 0; i < vdraw->draw_max; i++) {
129566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisDestroy(&vdraw->drawaxis[i]));
139566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGDestroy(&vdraw->drawlg[i]));
149566063dSJacob Faibussowitsch     PetscCall(PetscDrawDestroy(&vdraw->draw[i]));
155c6c1daeSBarry Smith   }
169566063dSJacob Faibussowitsch   PetscCall(PetscFree(vdraw->display));
179566063dSJacob Faibussowitsch   PetscCall(PetscFree(vdraw->title));
189566063dSJacob Faibussowitsch   PetscCall(PetscFree3(vdraw->draw, vdraw->drawlg, vdraw->drawaxis));
199566063dSJacob Faibussowitsch   PetscCall(PetscFree(vdraw->bounds));
209566063dSJacob Faibussowitsch   PetscCall(PetscFree(vdraw->drawtype));
219566063dSJacob Faibussowitsch   PetscCall(PetscFree(v->data));
223ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
235c6c1daeSBarry Smith }
245c6c1daeSBarry Smith 
25d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscViewerFlush_Draw(PetscViewer v)
26d71ae5a4SJacob Faibussowitsch {
275c6c1daeSBarry Smith   PetscInt          i;
285c6c1daeSBarry Smith   PetscViewer_Draw *vdraw = (PetscViewer_Draw *)v->data;
295c6c1daeSBarry Smith 
305c6c1daeSBarry Smith   PetscFunctionBegin;
315c6c1daeSBarry Smith   for (i = 0; i < vdraw->draw_max; i++) {
329566063dSJacob Faibussowitsch     if (vdraw->draw[i]) PetscCall(PetscDrawFlush(vdraw->draw[i]));
335c6c1daeSBarry Smith   }
343ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
355c6c1daeSBarry Smith }
365c6c1daeSBarry Smith 
375d83a8b1SBarry Smith /*@
38c410d8ccSBarry Smith   PetscViewerDrawBaseAdd - add to the base integer that is added to the `windownumber` passed to `PetscViewerDrawGetDraw()`
395c6c1daeSBarry Smith 
40c3339decSBarry Smith   Logically Collective
415c6c1daeSBarry Smith 
425c6c1daeSBarry Smith   Input Parameters:
43811af0c4SBarry Smith + viewer       - the `PetscViewer` (created with `PetscViewerDrawOpen()`)
445c6c1daeSBarry Smith - windownumber - how much to add to the base
455c6c1daeSBarry Smith 
465c6c1daeSBarry Smith   Level: developer
475c6c1daeSBarry Smith 
48811af0c4SBarry Smith   Note:
49811af0c4SBarry Smith   A `PETSCVIEWERDRAW` may have multiple `PetscDraw` subwindows, this increases the number of the subwindow that is returned with `PetscViewerDrawGetDraw()`
50811af0c4SBarry Smith 
51d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscViewerDrawGetLG()`, `PetscViewerDrawGetAxis()`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`, `PetscViewerDrawBaseSet()`
525c6c1daeSBarry Smith @*/
53d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerDrawBaseAdd(PetscViewer viewer, PetscInt windownumber)
54d71ae5a4SJacob Faibussowitsch {
55e5ab1681SLisandro Dalcin   PetscViewer_Draw *vdraw;
565c6c1daeSBarry Smith   PetscBool         isdraw;
575c6c1daeSBarry Smith 
585c6c1daeSBarry Smith   PetscFunctionBegin;
595c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
60e5ab1681SLisandro Dalcin   PetscValidLogicalCollectiveInt(viewer, windownumber, 2);
619566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
6228b400f6SJacob Faibussowitsch   PetscCheck(isdraw, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Must be draw type PetscViewer");
63e5ab1681SLisandro Dalcin   vdraw = (PetscViewer_Draw *)viewer->data;
64e5ab1681SLisandro Dalcin 
65cc73adaaSBarry Smith   PetscCheck(windownumber + vdraw->draw_base >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Resulting base %" PetscInt_FMT " cannot be negative", windownumber + vdraw->draw_base);
665c6c1daeSBarry Smith   vdraw->draw_base += windownumber;
673ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
685c6c1daeSBarry Smith }
695c6c1daeSBarry Smith 
705d83a8b1SBarry Smith /*@
71c410d8ccSBarry Smith   PetscViewerDrawBaseSet - sets the base integer that is added to the `windownumber` passed to `PetscViewerDrawGetDraw()`
725c6c1daeSBarry Smith 
73c3339decSBarry Smith   Logically Collective
745c6c1daeSBarry Smith 
755c6c1daeSBarry Smith   Input Parameters:
76811af0c4SBarry Smith + viewer       - the `PetscViewer` (created with `PetscViewerDrawOpen()`)
775c6c1daeSBarry Smith - windownumber - value to set the base
785c6c1daeSBarry Smith 
795c6c1daeSBarry Smith   Level: developer
805c6c1daeSBarry Smith 
81811af0c4SBarry Smith   Note:
82811af0c4SBarry Smith   A `PETSCVIEWERDRAW` may have multiple `PetscDraw` subwindows, this increases the number of the subwindow that is returned with `PetscViewerDrawGetDraw()`
83811af0c4SBarry Smith 
84d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscViewerDrawGetLG()`, `PetscViewerDrawGetAxis()`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`, `PetscViewerDrawBaseAdd()`
855c6c1daeSBarry Smith @*/
86d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerDrawBaseSet(PetscViewer viewer, PetscInt windownumber)
87d71ae5a4SJacob Faibussowitsch {
88e5ab1681SLisandro Dalcin   PetscViewer_Draw *vdraw;
895c6c1daeSBarry Smith   PetscBool         isdraw;
905c6c1daeSBarry Smith 
915c6c1daeSBarry Smith   PetscFunctionBegin;
925c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
93e5ab1681SLisandro Dalcin   PetscValidLogicalCollectiveInt(viewer, windownumber, 2);
949566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
9528b400f6SJacob Faibussowitsch   PetscCheck(isdraw, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Must be draw type PetscViewer");
96e5ab1681SLisandro Dalcin   vdraw = (PetscViewer_Draw *)viewer->data;
97e5ab1681SLisandro Dalcin 
9808401ef6SPierre Jolivet   PetscCheck(windownumber >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Resulting base %" PetscInt_FMT " cannot be negative", windownumber);
995c6c1daeSBarry Smith   vdraw->draw_base = windownumber;
1003ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1015c6c1daeSBarry Smith }
1025c6c1daeSBarry Smith 
103d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerDrawResize(PetscViewer v, int w, int h)
104d71ae5a4SJacob Faibussowitsch {
105e5ab1681SLisandro Dalcin   PetscViewer_Draw *vdraw;
106e5ab1681SLisandro Dalcin   PetscBool         isdraw;
1075c6c1daeSBarry Smith 
1085c6c1daeSBarry Smith   PetscFunctionBegin;
109e5ab1681SLisandro Dalcin   PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 1);
1109566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERDRAW, &isdraw));
1113ba16761SJacob Faibussowitsch   if (!isdraw) PetscFunctionReturn(PETSC_SUCCESS);
112e5ab1681SLisandro Dalcin   vdraw = (PetscViewer_Draw *)v->data;
113e5ab1681SLisandro Dalcin 
114e5ab1681SLisandro Dalcin   if (w >= 1) vdraw->w = w;
115e5ab1681SLisandro Dalcin   if (h >= 1) vdraw->h = h;
1163ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1175c6c1daeSBarry Smith }
1185c6c1daeSBarry Smith 
119d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerDrawSetInfo(PetscViewer v, const char display[], const char title[], int x, int y, int w, int h)
120d71ae5a4SJacob Faibussowitsch {
121e5ab1681SLisandro Dalcin   PetscViewer_Draw *vdraw;
122e5ab1681SLisandro Dalcin   PetscBool         isdraw;
1235c6c1daeSBarry Smith 
1245c6c1daeSBarry Smith   PetscFunctionBegin;
125e5ab1681SLisandro Dalcin   PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 1);
1269566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERDRAW, &isdraw));
1273ba16761SJacob Faibussowitsch   if (!isdraw) PetscFunctionReturn(PETSC_SUCCESS);
128e5ab1681SLisandro Dalcin   vdraw = (PetscViewer_Draw *)v->data;
129e5ab1681SLisandro Dalcin 
1309566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(display, &vdraw->display));
1319566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(title, &vdraw->title));
132e5ab1681SLisandro Dalcin   if (w >= 1) vdraw->w = w;
133e5ab1681SLisandro Dalcin   if (h >= 1) vdraw->h = h;
1343ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1355c6c1daeSBarry Smith }
1365c6c1daeSBarry Smith 
137d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerDrawSetTitle(PetscViewer v, const char title[])
138d71ae5a4SJacob Faibussowitsch {
139f55236e4SLisandro Dalcin   PetscViewer_Draw *vdraw;
140f55236e4SLisandro Dalcin   PetscBool         isdraw;
141f55236e4SLisandro Dalcin 
142f55236e4SLisandro Dalcin   PetscFunctionBegin;
143f55236e4SLisandro Dalcin   PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 1);
1449566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERDRAW, &isdraw));
1453ba16761SJacob Faibussowitsch   if (!isdraw) PetscFunctionReturn(PETSC_SUCCESS);
146f55236e4SLisandro Dalcin   vdraw = (PetscViewer_Draw *)v->data;
147f55236e4SLisandro Dalcin 
1489566063dSJacob Faibussowitsch   PetscCall(PetscFree(vdraw->title));
1499566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(title, &vdraw->title));
1503ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
151f55236e4SLisandro Dalcin }
152f55236e4SLisandro Dalcin 
153d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerDrawGetTitle(PetscViewer v, const char *title[])
154d71ae5a4SJacob Faibussowitsch {
155f55236e4SLisandro Dalcin   PetscViewer_Draw *vdraw;
156f55236e4SLisandro Dalcin   PetscBool         isdraw;
157f55236e4SLisandro Dalcin 
158f55236e4SLisandro Dalcin   PetscFunctionBegin;
159f55236e4SLisandro Dalcin   PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 1);
1609566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERDRAW, &isdraw));
16128b400f6SJacob Faibussowitsch   PetscCheck(isdraw, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Must be draw type PetscViewer");
162f55236e4SLisandro Dalcin   vdraw = (PetscViewer_Draw *)v->data;
163f55236e4SLisandro Dalcin 
164f55236e4SLisandro Dalcin   *title = vdraw->title;
1653ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
166f55236e4SLisandro Dalcin }
167f55236e4SLisandro Dalcin 
168cc4c1da9SBarry Smith /*@
16910450e9eSJacob Faibussowitsch   PetscViewerDrawOpen - Opens a `PetscDraw` window for use as a `PetscViewer` with type
17010450e9eSJacob Faibussowitsch   `PETSCVIEWERDRAW`.
1715c6c1daeSBarry Smith 
172d083f849SBarry Smith   Collective
1735c6c1daeSBarry Smith 
1745c6c1daeSBarry Smith   Input Parameters:
1755c6c1daeSBarry Smith + comm    - communicator that will share window
1763f423023SBarry Smith . display - the X display on which to open, or `NULL` for the local machine
1773f423023SBarry Smith . title   - the title to put in the title bar, or `NULL` for no title
178aaa8cc7dSPierre Jolivet . x       - horizontal screen coordinate of the upper left corner of window, or use `PETSC_DECIDE`
1792fe279fdSBarry Smith . y       - vertical screen coordinate of the upper left corner of window, or use `PETSC_DECIDE`
1802fe279fdSBarry Smith . 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`
1812fe279fdSBarry Smith - 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`
1825c6c1daeSBarry Smith 
183f899ff85SJose E. Roman   Output Parameter:
184811af0c4SBarry Smith . viewer - the `PetscViewer`
1855c6c1daeSBarry Smith 
1865c6c1daeSBarry Smith   Options Database Keys:
18710699b91SBarry Smith + -draw_type          - use x or null
1885c6c1daeSBarry Smith . -nox                - Disables all x-windows output
1895c6c1daeSBarry Smith . -display <name>     - Specifies name of machine for the X display
1905c6c1daeSBarry Smith . -geometry <x,y,w,h> - allows setting the window location and size
1915c6c1daeSBarry Smith - -draw_pause <pause> - Sets time (in seconds) that the
1925c6c1daeSBarry Smith      program pauses after PetscDrawPause() has been called
1935c6c1daeSBarry Smith      (0 is default, -1 implies until user input).
1945c6c1daeSBarry Smith 
1955c6c1daeSBarry Smith   Level: beginner
1965c6c1daeSBarry Smith 
19710450e9eSJacob Faibussowitsch   Notes:
19810450e9eSJacob Faibussowitsch   If you want to do graphics in this window, you must call `PetscViewerDrawGetDraw()` and
19910450e9eSJacob Faibussowitsch   perform the graphics on the `PetscDraw` object.
20010450e9eSJacob Faibussowitsch 
20110450e9eSJacob Faibussowitsch   Format options include\:
20210450e9eSJacob Faibussowitsch + `PETSC_VIEWER_DRAW_BASIC` - displays with basic format
20310450e9eSJacob Faibussowitsch - `PETSC_VIEWER_DRAW_LG`    - displays using a line graph
20410450e9eSJacob Faibussowitsch 
205aec76313SJacob Faibussowitsch   Fortran Notes:
2065c6c1daeSBarry Smith   Whenever indicating null character data in a Fortran code,
207811af0c4SBarry Smith   `PETSC_NULL_CHARACTER` must be employed; using NULL is not
208811af0c4SBarry Smith   correct for character data!  Thus, `PETSC_NULL_CHARACTER` can be
2095c6c1daeSBarry Smith   used for the display and title input parameters.
2105c6c1daeSBarry Smith 
211d1f92df0SBarry Smith .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscDrawCreate()`, `PetscViewerDestroy()`, `PetscViewerDrawGetDraw()`, `PetscViewerCreate()`, `PETSC_VIEWER_DRAW_`,
212db781477SPatrick Sanan           `PETSC_VIEWER_DRAW_WORLD`, `PETSC_VIEWER_DRAW_SELF`
2135c6c1daeSBarry Smith @*/
214d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerDrawOpen(MPI_Comm comm, const char display[], const char title[], int x, int y, int w, int h, PetscViewer *viewer)
215d71ae5a4SJacob Faibussowitsch {
2165c6c1daeSBarry Smith   PetscFunctionBegin;
2179566063dSJacob Faibussowitsch   PetscCall(PetscViewerCreate(comm, viewer));
2189566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetType(*viewer, PETSCVIEWERDRAW));
2199566063dSJacob Faibussowitsch   PetscCall(PetscViewerDrawSetInfo(*viewer, display, title, x, y, w, h));
2203ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2215c6c1daeSBarry Smith }
2225c6c1daeSBarry Smith 
223a9db196aSBarry Smith #include <petsc/private/drawimpl.h>
224a9db196aSBarry Smith 
22534e79e72SJacob Faibussowitsch static PetscErrorCode PetscViewerGetSubViewer_Draw(PetscViewer viewer, MPI_Comm comm, PetscViewer *sviewer)
226d71ae5a4SJacob Faibussowitsch {
2275c6c1daeSBarry Smith   PetscMPIInt       rank;
2285c6c1daeSBarry Smith   PetscInt          i;
229c6228bbaSLisandro Dalcin   PetscViewer_Draw *vdraw = (PetscViewer_Draw *)viewer->data, *svdraw;
2305c6c1daeSBarry Smith 
2315c6c1daeSBarry Smith   PetscFunctionBegin;
23228b400f6SJacob Faibussowitsch   PetscCheck(!vdraw->singleton_made, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Trying to get SubViewer without first restoring previous");
2335c6c1daeSBarry Smith   /* only processor zero can use the PetscViewer draw singleton */
2349566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank));
235dd400576SPatrick Sanan   if (rank == 0) {
236e5afcf28SBarry Smith     PetscMPIInt flg;
237a9db196aSBarry Smith     PetscDraw   draw, sdraw;
238e5afcf28SBarry Smith 
2399566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_compare(PETSC_COMM_SELF, comm, &flg));
240cc73adaaSBarry Smith     PetscCheck(flg == MPI_IDENT || flg == MPI_CONGRUENT, PETSC_COMM_SELF, PETSC_ERR_SUP, "PetscViewerGetSubViewer() for PETSCVIEWERDRAW requires a singleton MPI_Comm");
2419566063dSJacob Faibussowitsch     PetscCall(PetscViewerCreate(comm, sviewer));
2429566063dSJacob Faibussowitsch     PetscCall(PetscViewerSetType(*sviewer, PETSCVIEWERDRAW));
243c6228bbaSLisandro Dalcin     svdraw             = (PetscViewer_Draw *)(*sviewer)->data;
244c6228bbaSLisandro Dalcin     (*sviewer)->format = viewer->format;
245c6228bbaSLisandro Dalcin     for (i = 0; i < vdraw->draw_max; i++) { /* XXX this is wrong if svdraw->draw_max (initially 5) < vdraw->draw_max */
2469566063dSJacob Faibussowitsch       if (vdraw->draw[i]) PetscCall(PetscDrawGetSingleton(vdraw->draw[i], &svdraw->draw[i]));
2475c6c1daeSBarry Smith     }
2489566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw));
2499566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawGetDraw(*sviewer, 0, &sdraw));
250a9db196aSBarry Smith     if (draw->savefilename) {
2519566063dSJacob Faibussowitsch       PetscCall(PetscDrawSetSave(sdraw, draw->savefilename));
252a9db196aSBarry Smith       sdraw->savefilecount  = draw->savefilecount;
253a9db196aSBarry Smith       sdraw->savesinglefile = draw->savesinglefile;
254a9db196aSBarry Smith       sdraw->savemoviefps   = draw->savemoviefps;
255a9db196aSBarry Smith       sdraw->saveonclear    = draw->saveonclear;
256a9db196aSBarry Smith       sdraw->saveonflush    = draw->saveonflush;
257a9db196aSBarry Smith     }
2589566063dSJacob Faibussowitsch     if (draw->savefinalfilename) PetscCall(PetscDrawSetSaveFinalImage(sdraw, draw->savefinalfilename));
259a9db196aSBarry Smith   } else {
260a9db196aSBarry Smith     PetscDraw draw;
2619566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw));
2625c6c1daeSBarry Smith   }
2635c6c1daeSBarry Smith   vdraw->singleton_made = PETSC_TRUE;
2643ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2655c6c1daeSBarry Smith }
2665c6c1daeSBarry Smith 
26734e79e72SJacob Faibussowitsch static PetscErrorCode PetscViewerRestoreSubViewer_Draw(PetscViewer viewer, MPI_Comm comm, PetscViewer *sviewer)
268d71ae5a4SJacob Faibussowitsch {
2695c6c1daeSBarry Smith   PetscMPIInt       rank;
2705c6c1daeSBarry Smith   PetscInt          i;
271c6228bbaSLisandro Dalcin   PetscViewer_Draw *vdraw = (PetscViewer_Draw *)viewer->data, *svdraw;
2725c6c1daeSBarry Smith 
2735c6c1daeSBarry Smith   PetscFunctionBegin;
27428b400f6SJacob Faibussowitsch   PetscCheck(vdraw->singleton_made, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Trying to restore a singleton that was not gotten");
2759566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank));
276dd400576SPatrick Sanan   if (rank == 0) {
277a9db196aSBarry Smith     PetscDraw draw, sdraw;
278a9db196aSBarry Smith 
2799566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw));
2809566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawGetDraw(*sviewer, 0, &sdraw));
281a9db196aSBarry Smith     if (draw->savefilename) {
282a9db196aSBarry Smith       draw->savefilecount = sdraw->savefilecount;
2839566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Bcast(&draw->savefilecount, 1, MPIU_INT, 0, PetscObjectComm((PetscObject)draw)));
284a9db196aSBarry Smith     }
285c6228bbaSLisandro Dalcin     svdraw = (PetscViewer_Draw *)(*sviewer)->data;
2865c6c1daeSBarry Smith     for (i = 0; i < vdraw->draw_max; i++) {
28748a46eb9SPierre Jolivet       if (vdraw->draw[i] && svdraw->draw[i]) PetscCall(PetscDrawRestoreSingleton(vdraw->draw[i], &svdraw->draw[i]));
2885c6c1daeSBarry Smith     }
2899566063dSJacob Faibussowitsch     PetscCall(PetscFree3(svdraw->draw, svdraw->drawlg, svdraw->drawaxis));
2909566063dSJacob Faibussowitsch     PetscCall(PetscFree((*sviewer)->data));
2919566063dSJacob Faibussowitsch     PetscCall(PetscHeaderDestroy(sviewer));
292a9db196aSBarry Smith   } else {
293a9db196aSBarry Smith     PetscDraw draw;
294a9db196aSBarry Smith 
2959566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw));
29648a46eb9SPierre Jolivet     if (draw->savefilename) PetscCallMPI(MPI_Bcast(&draw->savefilecount, 1, MPIU_INT, 0, PetscObjectComm((PetscObject)draw)));
297a9db196aSBarry Smith   }
298a9db196aSBarry Smith 
2995c6c1daeSBarry Smith   vdraw->singleton_made = PETSC_FALSE;
3003ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3015c6c1daeSBarry Smith }
3025c6c1daeSBarry Smith 
303*ce78bad3SBarry Smith static PetscErrorCode PetscViewerSetFromOptions_Draw(PetscViewer v, PetscOptionItems PetscOptionsObject)
304d71ae5a4SJacob Faibussowitsch {
305e9457bf7SBarry Smith   PetscReal bounds[16];
306e9457bf7SBarry Smith   PetscInt  nbounds = 16;
307e9457bf7SBarry Smith   PetscBool flg;
308e9457bf7SBarry Smith 
309e9457bf7SBarry Smith   PetscFunctionBegin;
310d0609cedSBarry Smith   PetscOptionsHeadBegin(PetscOptionsObject, "Draw PetscViewer Options");
3119566063dSJacob Faibussowitsch   PetscCall(PetscOptionsRealArray("-draw_bounds", "Bounds to put on plots axis", "PetscViewerDrawSetBounds", bounds, &nbounds, &flg));
31248a46eb9SPierre Jolivet   if (flg) PetscCall(PetscViewerDrawSetBounds(v, nbounds / 2, bounds));
313d0609cedSBarry Smith   PetscOptionsHeadEnd();
3143ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
315e9457bf7SBarry Smith }
316e9457bf7SBarry Smith 
31734e79e72SJacob Faibussowitsch static PetscErrorCode PetscViewerView_Draw(PetscViewer viewer, PetscViewer v)
318d71ae5a4SJacob Faibussowitsch {
3190076e027SBarry Smith   PetscDraw         draw;
3200076e027SBarry Smith   PetscInt          i;
3210076e027SBarry Smith   PetscViewer_Draw *vdraw = (PetscViewer_Draw *)viewer->data;
322ccb5f961SBarry Smith   PetscBool         iascii;
3230076e027SBarry Smith 
3240076e027SBarry Smith   PetscFunctionBegin;
325ccb5f961SBarry Smith   PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERASCII, &iascii));
326ccb5f961SBarry Smith   if (iascii) PetscCall(PetscViewerASCIIPrintf(v, "Draw viewer is of type %s\n", vdraw->drawtype));
3270076e027SBarry Smith   /*  If the PetscViewer has just been created then no vdraw->draw yet
3280076e027SBarry Smith       exists so this will not actually call the viewer on any draws. */
3290076e027SBarry Smith   for (i = 0; i < vdraw->draw_base; i++) {
3300076e027SBarry Smith     if (vdraw->draw[i]) {
3319566063dSJacob Faibussowitsch       PetscCall(PetscViewerDrawGetDraw(viewer, i, &draw));
3329566063dSJacob Faibussowitsch       PetscCall(PetscDrawView(draw, v));
3330076e027SBarry Smith     }
3340076e027SBarry Smith   }
3353ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3360076e027SBarry Smith }
3370076e027SBarry Smith 
3388556b5ebSBarry Smith /*MC
3398556b5ebSBarry Smith    PETSCVIEWERDRAW - A viewer that generates graphics, either to the screen or a file
3408556b5ebSBarry Smith 
341811af0c4SBarry Smith   Level: beginner
342811af0c4SBarry Smith 
343d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`, `PETSC_VIEWER_DRAW_()`, `PETSC_VIEWER_DRAW_SELF`, `PETSC_VIEWER_DRAW_WORLD`,
344db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerASCIIOpen()`, `PetscViewerBinaryOpen()`, `PETSCVIEWERBINARY`,
345db781477SPatrick Sanan           `PetscViewerMatlabOpen()`, `VecView()`, `DMView()`, `PetscViewerMatlabPutArray()`, `PETSCVIEWERASCII`, `PETSCVIEWERMATLAB`,
346db781477SPatrick Sanan           `PetscViewerFileSetName()`, `PetscViewerFileSetMode()`, `PetscViewerFormat`, `PetscViewerType`, `PetscViewerSetType()`
3478556b5ebSBarry Smith M*/
348d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscViewerCreate_Draw(PetscViewer viewer)
349d71ae5a4SJacob Faibussowitsch {
3505c6c1daeSBarry Smith   PetscViewer_Draw *vdraw;
3515c6c1daeSBarry Smith 
3525c6c1daeSBarry Smith   PetscFunctionBegin;
3534dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&vdraw));
3545c6c1daeSBarry Smith   viewer->data = (void *)vdraw;
3555c6c1daeSBarry Smith 
3565c6c1daeSBarry Smith   viewer->ops->flush            = PetscViewerFlush_Draw;
3570076e027SBarry Smith   viewer->ops->view             = PetscViewerView_Draw;
3585c6c1daeSBarry Smith   viewer->ops->destroy          = PetscViewerDestroy_Draw;
359e9457bf7SBarry Smith   viewer->ops->setfromoptions   = PetscViewerSetFromOptions_Draw;
360559f443fSBarry Smith   viewer->ops->getsubviewer     = PetscViewerGetSubViewer_Draw;
361559f443fSBarry Smith   viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_Draw;
3625c6c1daeSBarry Smith 
3635c6c1daeSBarry Smith   /* these are created on the fly if requested */
3645c6c1daeSBarry Smith   vdraw->draw_max  = 5;
3655c6c1daeSBarry Smith   vdraw->draw_base = 0;
366ccad63c3SBarry Smith   vdraw->w         = PETSC_DECIDE;
367ccad63c3SBarry Smith   vdraw->h         = PETSC_DECIDE;
368a297a907SKarl Rupp 
3699566063dSJacob Faibussowitsch   PetscCall(PetscCalloc3(vdraw->draw_max, &vdraw->draw, vdraw->draw_max, &vdraw->drawlg, vdraw->draw_max, &vdraw->drawaxis));
3705c6c1daeSBarry Smith   vdraw->singleton_made = PETSC_FALSE;
3713ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3725c6c1daeSBarry Smith }
3735c6c1daeSBarry Smith 
3745c6c1daeSBarry Smith /*@
375811af0c4SBarry Smith   PetscViewerDrawClear - Clears a `PetscDraw` graphic associated with a `PetscViewer`.
3765c6c1daeSBarry Smith 
3775c6c1daeSBarry Smith   Not Collective
3785c6c1daeSBarry Smith 
3795c6c1daeSBarry Smith   Input Parameter:
380811af0c4SBarry Smith . viewer - the `PetscViewer`
3815c6c1daeSBarry Smith 
3825c6c1daeSBarry Smith   Level: intermediate
3835c6c1daeSBarry Smith 
384d1f92df0SBarry Smith .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`,
3855c6c1daeSBarry Smith @*/
386d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerDrawClear(PetscViewer viewer)
387d71ae5a4SJacob Faibussowitsch {
3885c6c1daeSBarry Smith   PetscViewer_Draw *vdraw;
389e5ab1681SLisandro Dalcin   PetscBool         isdraw;
390e5ab1681SLisandro Dalcin   PetscInt          i;
3915c6c1daeSBarry Smith 
3925c6c1daeSBarry Smith   PetscFunctionBegin;
393e5ab1681SLisandro Dalcin   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
3949566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
3953ba16761SJacob Faibussowitsch   if (!isdraw) PetscFunctionReturn(PETSC_SUCCESS);
3965c6c1daeSBarry Smith   vdraw = (PetscViewer_Draw *)viewer->data;
397e5ab1681SLisandro Dalcin 
3985c6c1daeSBarry Smith   for (i = 0; i < vdraw->draw_max; i++) {
3999566063dSJacob Faibussowitsch     if (vdraw->draw[i]) PetscCall(PetscDrawClear(vdraw->draw[i]));
4005c6c1daeSBarry Smith   }
4013ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4025c6c1daeSBarry Smith }
4035c6c1daeSBarry Smith 
4045c6c1daeSBarry Smith /*@
405811af0c4SBarry Smith   PetscViewerDrawGetPause - Gets the pause value (how long to pause before an image is changed)  in the `PETSCVIEWERDRAW` `PetscViewer`
4065c6c1daeSBarry Smith 
4075c6c1daeSBarry Smith   Not Collective
4085c6c1daeSBarry Smith 
4095c6c1daeSBarry Smith   Input Parameter:
410811af0c4SBarry Smith . viewer - the `PetscViewer`
4115c6c1daeSBarry Smith 
4125c6c1daeSBarry Smith   Output Parameter:
4135c6c1daeSBarry Smith . pause - the pause value
4145c6c1daeSBarry Smith 
4155c6c1daeSBarry Smith   Level: intermediate
4165c6c1daeSBarry Smith 
417d1f92df0SBarry Smith .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`,
4185c6c1daeSBarry Smith @*/
419d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerDrawGetPause(PetscViewer viewer, PetscReal *pause)
420d71ae5a4SJacob Faibussowitsch {
4215c6c1daeSBarry Smith   PetscViewer_Draw *vdraw;
422e5ab1681SLisandro Dalcin   PetscBool         isdraw;
423e5ab1681SLisandro Dalcin   PetscInt          i;
4245c6c1daeSBarry Smith   PetscDraw         draw;
4255c6c1daeSBarry Smith 
4265c6c1daeSBarry Smith   PetscFunctionBegin;
427e5ab1681SLisandro Dalcin   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
4289566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
4299371c9d4SSatish Balay   if (!isdraw) {
4309371c9d4SSatish Balay     *pause = 0.0;
4313ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
4329371c9d4SSatish Balay   }
4335c6c1daeSBarry Smith   vdraw = (PetscViewer_Draw *)viewer->data;
434e5ab1681SLisandro Dalcin 
4355c6c1daeSBarry Smith   for (i = 0; i < vdraw->draw_max; i++) {
4365c6c1daeSBarry Smith     if (vdraw->draw[i]) {
4379566063dSJacob Faibussowitsch       PetscCall(PetscDrawGetPause(vdraw->draw[i], pause));
4383ba16761SJacob Faibussowitsch       PetscFunctionReturn(PETSC_SUCCESS);
4395c6c1daeSBarry Smith     }
4405c6c1daeSBarry Smith   }
4415c6c1daeSBarry Smith   /* none exist yet so create one and get its pause */
4429566063dSJacob Faibussowitsch   PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw));
4439566063dSJacob Faibussowitsch   PetscCall(PetscDrawGetPause(draw, pause));
4443ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4455c6c1daeSBarry Smith }
4465c6c1daeSBarry Smith 
4475c6c1daeSBarry Smith /*@
448811af0c4SBarry Smith   PetscViewerDrawSetPause - Sets a pause for each `PetscDraw` in the `PETSCVIEWERDRAW` `PetscViewer`
4495c6c1daeSBarry Smith 
4505c6c1daeSBarry Smith   Not Collective
4515c6c1daeSBarry Smith 
4525c6c1daeSBarry Smith   Input Parameters:
453811af0c4SBarry Smith + viewer - the `PetscViewer`
4545c6c1daeSBarry Smith - pause  - the pause value
4555c6c1daeSBarry Smith 
4565c6c1daeSBarry Smith   Level: intermediate
4575c6c1daeSBarry Smith 
458d1f92df0SBarry Smith .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`,
4595c6c1daeSBarry Smith @*/
460d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerDrawSetPause(PetscViewer viewer, PetscReal pause)
461d71ae5a4SJacob Faibussowitsch {
462e5ab1681SLisandro Dalcin   PetscViewer_Draw *vdraw;
4635c6c1daeSBarry Smith   PetscBool         isdraw;
464e5ab1681SLisandro Dalcin   PetscInt          i;
4655c6c1daeSBarry Smith 
4665c6c1daeSBarry Smith   PetscFunctionBegin;
467e5ab1681SLisandro Dalcin   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
4689566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
4693ba16761SJacob Faibussowitsch   if (!isdraw) PetscFunctionReturn(PETSC_SUCCESS);
470e5ab1681SLisandro Dalcin   vdraw = (PetscViewer_Draw *)viewer->data;
471afe78b3cSBarry Smith 
472afe78b3cSBarry Smith   vdraw->pause = pause;
4735c6c1daeSBarry Smith   for (i = 0; i < vdraw->draw_max; i++) {
4749566063dSJacob Faibussowitsch     if (vdraw->draw[i]) PetscCall(PetscDrawSetPause(vdraw->draw[i], pause));
4755c6c1daeSBarry Smith   }
4763ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4775c6c1daeSBarry Smith }
4785c6c1daeSBarry Smith 
4795c6c1daeSBarry Smith /*@
480c410d8ccSBarry Smith   PetscViewerDrawSetHold - Holds previous image when drawing new image in a `PETSCVIEWERDRAW`
4815c6c1daeSBarry Smith 
4825c6c1daeSBarry Smith   Not Collective
4835c6c1daeSBarry Smith 
4845c6c1daeSBarry Smith   Input Parameters:
485811af0c4SBarry Smith + viewer - the `PetscViewer`
486811af0c4SBarry Smith - hold   - `PETSC_TRUE` indicates to hold the previous image
4875c6c1daeSBarry Smith 
4885c6c1daeSBarry Smith   Level: intermediate
4895c6c1daeSBarry Smith 
490d1f92df0SBarry Smith .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`,
4915c6c1daeSBarry Smith @*/
492d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerDrawSetHold(PetscViewer viewer, PetscBool hold)
493d71ae5a4SJacob Faibussowitsch {
4945c6c1daeSBarry Smith   PetscViewer_Draw *vdraw;
4955c6c1daeSBarry Smith   PetscBool         isdraw;
4965c6c1daeSBarry Smith 
4975c6c1daeSBarry Smith   PetscFunctionBegin;
498e5ab1681SLisandro Dalcin   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
4999566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
5003ba16761SJacob Faibussowitsch   if (!isdraw) PetscFunctionReturn(PETSC_SUCCESS);
5015c6c1daeSBarry Smith   vdraw = (PetscViewer_Draw *)viewer->data;
502e5ab1681SLisandro Dalcin 
5035c6c1daeSBarry Smith   vdraw->hold = hold;
5043ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5055c6c1daeSBarry Smith }
5065c6c1daeSBarry Smith 
5075c6c1daeSBarry Smith /*@
508811af0c4SBarry Smith   PetscViewerDrawGetHold - Checks if the `PETSCVIEWERDRAW` `PetscViewer` holds previous image when drawing new image
5095c6c1daeSBarry Smith 
5105c6c1daeSBarry Smith   Not Collective
5115c6c1daeSBarry Smith 
5125c6c1daeSBarry Smith   Input Parameter:
513811af0c4SBarry Smith . viewer - the `PetscViewer`
5145c6c1daeSBarry Smith 
5155c6c1daeSBarry Smith   Output Parameter:
5165c6c1daeSBarry Smith . hold - indicates to hold or not
5175c6c1daeSBarry Smith 
5185c6c1daeSBarry Smith   Level: intermediate
5195c6c1daeSBarry Smith 
520d1f92df0SBarry Smith .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`,
5215c6c1daeSBarry Smith @*/
522d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerDrawGetHold(PetscViewer viewer, PetscBool *hold)
523d71ae5a4SJacob Faibussowitsch {
5245c6c1daeSBarry Smith   PetscViewer_Draw *vdraw;
5255c6c1daeSBarry Smith   PetscBool         isdraw;
5265c6c1daeSBarry Smith 
5275c6c1daeSBarry Smith   PetscFunctionBegin;
528e5ab1681SLisandro Dalcin   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
5299566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
5309371c9d4SSatish Balay   if (!isdraw) {
5319371c9d4SSatish Balay     *hold = PETSC_FALSE;
5323ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
5339371c9d4SSatish Balay   }
5345c6c1daeSBarry Smith   vdraw = (PetscViewer_Draw *)viewer->data;
535e5ab1681SLisandro Dalcin 
5365c6c1daeSBarry Smith   *hold = vdraw->hold;
5373ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5385c6c1daeSBarry Smith }
5395c6c1daeSBarry Smith 
5405c6c1daeSBarry Smith /*
5415c6c1daeSBarry Smith     The variable Petsc_Viewer_Draw_keyval is used to indicate an MPI attribute that
5425c6c1daeSBarry Smith   is attached to a communicator, in this case the attribute is a PetscViewer.
5435c6c1daeSBarry Smith */
544d4c7638eSBarry Smith PetscMPIInt Petsc_Viewer_Draw_keyval = MPI_KEYVAL_INVALID;
5455c6c1daeSBarry Smith 
5465c6c1daeSBarry Smith /*@C
547811af0c4SBarry Smith    PETSC_VIEWER_DRAW_ - Creates a window `PETSCVIEWERDRAW` `PetscViewer` shared by all processors
548c410d8ccSBarry Smith                      in an MPI communicator.
5495c6c1daeSBarry Smith 
550d083f849SBarry Smith    Collective
5515c6c1daeSBarry Smith 
5525c6c1daeSBarry Smith    Input Parameter:
553811af0c4SBarry Smith .  comm - the MPI communicator to share the window `PetscViewer`
5545c6c1daeSBarry Smith 
5555c6c1daeSBarry Smith    Level: intermediate
5565c6c1daeSBarry Smith 
55734fa283eSBarry Smith    Notes:
55834fa283eSBarry Smith    This object is destroyed in `PetscFinalize()`, `PetscViewerDestroy()` should never be called on it
55934fa283eSBarry Smith 
560811af0c4SBarry Smith    Unlike almost all other PETSc routines, `PETSC_VIEWER_DRAW_()` does not return
5615c6c1daeSBarry Smith    an error code.  The window is usually used in the form
562*ce78bad3SBarry Smith .vb
563*ce78bad3SBarry Smith    XXXView(XXX object, PETSC_VIEWER_DRAW_(comm));
564*ce78bad3SBarry Smith .ve
5655c6c1daeSBarry Smith 
566d1f92df0SBarry Smith .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewer`, `PETSC_VIEWER_DRAW_WORLD`, `PETSC_VIEWER_DRAW_SELF`, `PetscViewerDrawOpen()`,
5675c6c1daeSBarry Smith @*/
568d71ae5a4SJacob Faibussowitsch PetscViewer PETSC_VIEWER_DRAW_(MPI_Comm comm)
569d71ae5a4SJacob Faibussowitsch {
570648c30bcSBarry Smith   PetscMPIInt flag;
5715c6c1daeSBarry Smith   PetscViewer viewer;
5725c6c1daeSBarry Smith   MPI_Comm    ncomm;
5735c6c1daeSBarry Smith 
5745c6c1daeSBarry Smith   PetscFunctionBegin;
575648c30bcSBarry Smith   PetscCallNull(PetscCommDuplicate(comm, &ncomm, NULL));
576648c30bcSBarry Smith   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)); }
577648c30bcSBarry Smith   PetscCallMPINull(MPI_Comm_get_attr(ncomm, Petsc_Viewer_Draw_keyval, (void **)&viewer, &flag));
5785c6c1daeSBarry Smith   if (!flag) { /* PetscViewer not yet created */
579648c30bcSBarry Smith     PetscCallNull(PetscViewerDrawOpen(ncomm, NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 300, 300, &viewer));
580648c30bcSBarry Smith     PetscCallNull(PetscObjectRegisterDestroy((PetscObject)viewer));
581648c30bcSBarry Smith     PetscCallMPINull(MPI_Comm_set_attr(ncomm, Petsc_Viewer_Draw_keyval, (void *)viewer));
5829371c9d4SSatish Balay   }
583648c30bcSBarry Smith   PetscCallNull(PetscCommDestroy(&ncomm));
5845c6c1daeSBarry Smith   PetscFunctionReturn(viewer);
5855c6c1daeSBarry Smith }
5865c6c1daeSBarry Smith 
5875c6c1daeSBarry Smith /*@
588c410d8ccSBarry Smith   PetscViewerDrawSetBounds - sets the upper and lower bounds to be used in plotting in a `PETSCVIEWERDRAW` `PetscViewer`
5895c6c1daeSBarry Smith 
590c3339decSBarry Smith   Collective
5915c6c1daeSBarry Smith 
5925c6c1daeSBarry Smith   Input Parameters:
593811af0c4SBarry Smith + viewer  - the Petsc`Viewer` (created with `PetscViewerDrawOpen()`)
594811af0c4SBarry Smith . nbounds - number of plots that can be made with this viewer, for example the dof passed to `DMDACreate()`
595c410d8ccSBarry Smith - 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, .....
5965c6c1daeSBarry Smith 
597811af0c4SBarry Smith   Options Database Key:
59810699b91SBarry Smith . -draw_bounds  minF0,maxF0,minF1,maxF1 - the lower left and upper right bounds
599e9457bf7SBarry Smith 
6005c6c1daeSBarry Smith   Level: intermediate
6015c6c1daeSBarry Smith 
602811af0c4SBarry Smith   Note:
603811af0c4SBarry Smith   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
604f3f0eb19SBarry Smith   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
605f3f0eb19SBarry Smith   this viewer. Otherwise the color to physical value meaning changes with each new image if this is not set.
606f3f0eb19SBarry Smith 
607d1f92df0SBarry Smith .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewerDrawGetLG()`, `PetscViewerDrawGetAxis()`, `PetscViewerDrawOpen()`
6085c6c1daeSBarry Smith @*/
609d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerDrawSetBounds(PetscViewer viewer, PetscInt nbounds, const PetscReal *bounds)
610d71ae5a4SJacob Faibussowitsch {
611e5ab1681SLisandro Dalcin   PetscViewer_Draw *vdraw;
612e5ab1681SLisandro Dalcin   PetscBool         isdraw;
6135c6c1daeSBarry Smith 
6145c6c1daeSBarry Smith   PetscFunctionBegin;
6155c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
6169566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
6173ba16761SJacob Faibussowitsch   if (!isdraw) PetscFunctionReturn(PETSC_SUCCESS);
618e5ab1681SLisandro Dalcin   vdraw = (PetscViewer_Draw *)viewer->data;
619a297a907SKarl Rupp 
620e5ab1681SLisandro Dalcin   vdraw->nbounds = nbounds;
6219566063dSJacob Faibussowitsch   PetscCall(PetscFree(vdraw->bounds));
6229566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(2 * nbounds, &vdraw->bounds));
6239566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(vdraw->bounds, bounds, 2 * nbounds));
6243ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6255c6c1daeSBarry Smith }
6265c6c1daeSBarry Smith 
6275c6c1daeSBarry Smith /*@C
628811af0c4SBarry Smith   PetscViewerDrawGetBounds - gets the upper and lower bounds to be used in plotting set with `PetscViewerDrawSetBounds()`
6295c6c1daeSBarry Smith 
630c3339decSBarry Smith   Collective
6315c6c1daeSBarry Smith 
6325c6c1daeSBarry Smith   Input Parameter:
633811af0c4SBarry Smith . viewer - the `PetscViewer` (created with `PetscViewerDrawOpen()`)
6345c6c1daeSBarry Smith 
635fd292e60Sprj-   Output Parameters:
636811af0c4SBarry Smith + nbounds - number of plots that can be made with this viewer, for example the dof passed to `DMDACreate()`
637c410d8ccSBarry Smith - 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, .....
6385c6c1daeSBarry Smith 
6395c6c1daeSBarry Smith   Level: intermediate
6405c6c1daeSBarry Smith 
641d1f92df0SBarry Smith .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewerDrawGetLG()`, `PetscViewerDrawGetAxis()`, `PetscViewerDrawOpen()`, `PetscViewerDrawSetBounds()`
6425c6c1daeSBarry Smith @*/
643cc4c1da9SBarry Smith PetscErrorCode PetscViewerDrawGetBounds(PetscViewer viewer, PetscInt *nbounds, const PetscReal *bounds[])
644d71ae5a4SJacob Faibussowitsch {
645e5ab1681SLisandro Dalcin   PetscViewer_Draw *vdraw;
646e5ab1681SLisandro Dalcin   PetscBool         isdraw;
6475c6c1daeSBarry Smith 
6485c6c1daeSBarry Smith   PetscFunctionBegin;
6495c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
6509566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
6519371c9d4SSatish Balay   if (!isdraw) {
6529371c9d4SSatish Balay     if (nbounds) *nbounds = 0;
6539371c9d4SSatish Balay     if (bounds) *bounds = NULL;
6543ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
6559371c9d4SSatish Balay   }
656e5ab1681SLisandro Dalcin   vdraw = (PetscViewer_Draw *)viewer->data;
657e5ab1681SLisandro Dalcin 
658e5ab1681SLisandro Dalcin   if (nbounds) *nbounds = vdraw->nbounds;
659e5ab1681SLisandro Dalcin   if (bounds) *bounds = vdraw->bounds;
6603ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6615c6c1daeSBarry Smith }
662*ce78bad3SBarry Smith 
663*ce78bad3SBarry Smith /*@C
664*ce78bad3SBarry Smith   PetscViewerMonitorLGSetUp - sets up a viewer to be used by line graph monitoring routines such as `KSPMonitorResidualDrawLG()`
665*ce78bad3SBarry Smith 
666*ce78bad3SBarry Smith   Collective
667*ce78bad3SBarry Smith 
668*ce78bad3SBarry Smith   Input Parameters:
669*ce78bad3SBarry Smith + viewer - the viewer in which to display the line graphs, it not a `PETSCVIEWERDRAW` it will set to that `PetscViewerType`
670*ce78bad3SBarry Smith . host   - the host to open the window on, 'NULL' indicates the local host
671*ce78bad3SBarry Smith . title  - the title at the top of the window
672*ce78bad3SBarry Smith . metric - the label above the graph
673*ce78bad3SBarry Smith . l      - the number of curves
674*ce78bad3SBarry Smith . names  - the names of each curve to be used in displaying the legend. May be 'NULL'
675*ce78bad3SBarry Smith . x      - horizontal screen coordinate of the upper left corner of window, or use `PETSC_DECIDE`
676*ce78bad3SBarry Smith . y      - vertical screen coordinate of the upper left corner of window, or use `PETSC_DECIDE`
677*ce78bad3SBarry Smith . 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`
678*ce78bad3SBarry Smith - 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`
679*ce78bad3SBarry Smith 
680*ce78bad3SBarry Smith   Level: developer
681*ce78bad3SBarry Smith 
682*ce78bad3SBarry Smith .seealso: `PetscViewer()`, `PETSCVIEWERDRAW`, `PetscViewerDrawGetDrawLG()`, `PetscViewerDrawOpen()`, `PetscViewerDrawSetInfo()`
683*ce78bad3SBarry Smith @*/
684*ce78bad3SBarry Smith 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
685*ce78bad3SBarry Smith {
686*ce78bad3SBarry Smith   PetscDrawAxis axis;
687*ce78bad3SBarry Smith   PetscDrawLG   lg;
688*ce78bad3SBarry Smith 
689*ce78bad3SBarry Smith   PetscFunctionBegin;
690*ce78bad3SBarry Smith   PetscCall(PetscViewerSetType(viewer, PETSCVIEWERDRAW));
691*ce78bad3SBarry Smith   PetscCall(PetscViewerDrawSetInfo(viewer, host, title, x, y, m, n));
692*ce78bad3SBarry Smith   PetscCall(PetscViewerDrawGetDrawLG(viewer, 0, &lg));
693*ce78bad3SBarry Smith   if (names) PetscCall(PetscDrawLGSetLegend(lg, names));
694*ce78bad3SBarry Smith   PetscCall(PetscDrawLGSetFromOptions(lg));
695*ce78bad3SBarry Smith   PetscCall(PetscDrawLGGetAxis(lg, &axis));
696*ce78bad3SBarry Smith   PetscCall(PetscDrawAxisSetLabels(axis, "Convergence", "Iteration", metric));
697*ce78bad3SBarry Smith   PetscFunctionReturn(PETSC_SUCCESS);
698*ce78bad3SBarry Smith }
699