xref: /petsc/src/sys/classes/viewer/impls/draw/drawv.c (revision 4dfa11a44d5adf2389f1d3acbc8f3c1116dc6c3a)
15c6c1daeSBarry Smith 
25c6c1daeSBarry Smith #include <../src/sys/classes/viewer/impls/draw/vdraw.h> /*I "petscdraw.h" I*/
3665c2dedSJed Brown #include <petscviewer.h>                                /*I "petscviewer.h" I*/
45c6c1daeSBarry Smith 
59371c9d4SSatish Balay static PetscErrorCode PetscViewerDestroy_Draw(PetscViewer v) {
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));
225c6c1daeSBarry Smith   PetscFunctionReturn(0);
235c6c1daeSBarry Smith }
245c6c1daeSBarry Smith 
259371c9d4SSatish Balay static PetscErrorCode PetscViewerFlush_Draw(PetscViewer v) {
265c6c1daeSBarry Smith   PetscInt          i;
275c6c1daeSBarry Smith   PetscViewer_Draw *vdraw = (PetscViewer_Draw *)v->data;
285c6c1daeSBarry Smith 
295c6c1daeSBarry Smith   PetscFunctionBegin;
305c6c1daeSBarry Smith   for (i = 0; i < vdraw->draw_max; i++) {
319566063dSJacob Faibussowitsch     if (vdraw->draw[i]) PetscCall(PetscDrawFlush(vdraw->draw[i]));
325c6c1daeSBarry Smith   }
335c6c1daeSBarry Smith   PetscFunctionReturn(0);
345c6c1daeSBarry Smith }
355c6c1daeSBarry Smith 
365c6c1daeSBarry Smith /*@C
37811af0c4SBarry Smith     PetscViewerDrawGetDraw - Returns `PetscDraw` object from `PetscViewer` object.
38811af0c4SBarry Smith     This `PetscDraw` object may then be used to perform graphics using
39811af0c4SBarry Smith     `PetscDraw` commands.
405c6c1daeSBarry Smith 
41811af0c4SBarry Smith     Collective on viewer
425c6c1daeSBarry Smith 
435c6c1daeSBarry Smith     Input Parameters:
44811af0c4SBarry Smith +   viewer - the `PetscViewer` (created with `PetscViewerDrawOpen()` of type `PETSCVIEWERDRAW`)
455c6c1daeSBarry Smith -   windownumber - indicates which subwindow (usually 0)
465c6c1daeSBarry Smith 
4701d2d390SJose E. Roman     Output Parameter:
485c6c1daeSBarry Smith .   draw - the draw object
495c6c1daeSBarry Smith 
505c6c1daeSBarry Smith     Level: intermediate
515c6c1daeSBarry Smith 
52811af0c4SBarry Smith .seealso: `PETSCVIEWERDRAW`, `PetscViewerDrawGetLG()`, `PetscViewerDrawGetAxis()`, `PetscViewerDrawOpen()`
535c6c1daeSBarry Smith @*/
549371c9d4SSatish Balay PetscErrorCode PetscViewerDrawGetDraw(PetscViewer viewer, PetscInt windownumber, PetscDraw *draw) {
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);
615c6c1daeSBarry Smith   if (draw) PetscValidPointer(draw, 3);
629566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
6328b400f6SJacob Faibussowitsch   PetscCheck(isdraw, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Must be draw type PetscViewer");
6408401ef6SPierre Jolivet   PetscCheck(windownumber >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Window number cannot be negative");
65e5ab1681SLisandro Dalcin   vdraw = (PetscViewer_Draw *)viewer->data;
66e5ab1681SLisandro Dalcin 
675c6c1daeSBarry Smith   windownumber += vdraw->draw_base;
685c6c1daeSBarry Smith   if (windownumber >= vdraw->draw_max) {
695c6c1daeSBarry Smith     /* allocate twice as many slots as needed */
705c6c1daeSBarry Smith     PetscInt       draw_max = vdraw->draw_max;
715c6c1daeSBarry Smith     PetscDraw     *tdraw    = vdraw->draw;
725c6c1daeSBarry Smith     PetscDrawLG   *drawlg   = vdraw->drawlg;
735c6c1daeSBarry Smith     PetscDrawAxis *drawaxis = vdraw->drawaxis;
745c6c1daeSBarry Smith 
755c6c1daeSBarry Smith     vdraw->draw_max = 2 * windownumber;
76a297a907SKarl Rupp 
779566063dSJacob Faibussowitsch     PetscCall(PetscCalloc3(vdraw->draw_max, &vdraw->draw, vdraw->draw_max, &vdraw->drawlg, vdraw->draw_max, &vdraw->drawaxis));
789566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(vdraw->draw, tdraw, draw_max));
799566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(vdraw->drawlg, drawlg, draw_max));
809566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(vdraw->drawaxis, drawaxis, draw_max));
819566063dSJacob Faibussowitsch     PetscCall(PetscFree3(tdraw, drawlg, drawaxis));
825c6c1daeSBarry Smith   }
835c6c1daeSBarry Smith 
845c6c1daeSBarry Smith   if (!vdraw->draw[windownumber]) {
85e5ab1681SLisandro Dalcin     char *title = vdraw->title, tmp_str[128];
8610f3a0f4SLisandro Dalcin     if (windownumber) {
879566063dSJacob Faibussowitsch       PetscCall(PetscSNPrintf(tmp_str, sizeof(tmp_str), "%s:%" PetscInt_FMT, vdraw->title ? vdraw->title : "", windownumber));
885c6c1daeSBarry Smith       title = tmp_str;
895c6c1daeSBarry Smith     }
909566063dSJacob Faibussowitsch     PetscCall(PetscDrawCreate(PetscObjectComm((PetscObject)viewer), vdraw->display, title, PETSC_DECIDE, PETSC_DECIDE, vdraw->w, vdraw->h, &vdraw->draw[windownumber]));
9148a46eb9SPierre Jolivet     if (vdraw->drawtype) PetscCall(PetscDrawSetType(vdraw->draw[windownumber], vdraw->drawtype));
929566063dSJacob Faibussowitsch     PetscCall(PetscDrawSetPause(vdraw->draw[windownumber], vdraw->pause));
939566063dSJacob Faibussowitsch     PetscCall(PetscDrawSetOptionsPrefix(vdraw->draw[windownumber], ((PetscObject)viewer)->prefix));
949566063dSJacob Faibussowitsch     PetscCall(PetscDrawSetFromOptions(vdraw->draw[windownumber]));
955c6c1daeSBarry Smith   }
965c6c1daeSBarry Smith   if (draw) *draw = vdraw->draw[windownumber];
97064a246eSJacob Faibussowitsch   if (draw) PetscValidHeaderSpecific(*draw, PETSC_DRAW_CLASSID, 3);
985c6c1daeSBarry Smith   PetscFunctionReturn(0);
995c6c1daeSBarry Smith }
1005c6c1daeSBarry Smith 
1015c6c1daeSBarry Smith /*@C
102811af0c4SBarry Smith     PetscViewerDrawBaseAdd - add to the base integer that is added to the windownumber passed to `PetscViewerDrawGetDraw()`
1035c6c1daeSBarry Smith 
104811af0c4SBarry Smith     Logically Collective on viewer
1055c6c1daeSBarry Smith 
1065c6c1daeSBarry Smith     Input Parameters:
107811af0c4SBarry Smith +  viewer - the `PetscViewer` (created with `PetscViewerDrawOpen()`)
1085c6c1daeSBarry Smith -   windownumber - how much to add to the base
1095c6c1daeSBarry Smith 
1105c6c1daeSBarry Smith     Level: developer
1115c6c1daeSBarry Smith 
112811af0c4SBarry Smith     Note:
113811af0c4SBarry Smith     A `PETSCVIEWERDRAW` may have multiple `PetscDraw` subwindows, this increases the number of the subwindow that is returned with `PetscViewerDrawGetDraw()`
114811af0c4SBarry Smith 
115db781477SPatrick Sanan .seealso: `PetscViewerDrawGetLG()`, `PetscViewerDrawGetAxis()`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`, `PetscViewerDrawBaseSet()`
1165c6c1daeSBarry Smith @*/
1179371c9d4SSatish Balay PetscErrorCode PetscViewerDrawBaseAdd(PetscViewer viewer, PetscInt windownumber) {
118e5ab1681SLisandro Dalcin   PetscViewer_Draw *vdraw;
1195c6c1daeSBarry Smith   PetscBool         isdraw;
1205c6c1daeSBarry Smith 
1215c6c1daeSBarry Smith   PetscFunctionBegin;
1225c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
123e5ab1681SLisandro Dalcin   PetscValidLogicalCollectiveInt(viewer, windownumber, 2);
1249566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
12528b400f6SJacob Faibussowitsch   PetscCheck(isdraw, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Must be draw type PetscViewer");
126e5ab1681SLisandro Dalcin   vdraw = (PetscViewer_Draw *)viewer->data;
127e5ab1681SLisandro Dalcin 
128cc73adaaSBarry 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);
1295c6c1daeSBarry Smith   vdraw->draw_base += windownumber;
1305c6c1daeSBarry Smith   PetscFunctionReturn(0);
1315c6c1daeSBarry Smith }
1325c6c1daeSBarry Smith 
1335c6c1daeSBarry Smith /*@C
134811af0c4SBarry Smith     PetscViewerDrawBaseSet - sets the base integer that is added to the windownumber passed to `PetscViewerDrawGetDraw()`
1355c6c1daeSBarry Smith 
136811af0c4SBarry Smith     Logically Collective on viewer
1375c6c1daeSBarry Smith 
1385c6c1daeSBarry Smith     Input Parameters:
139811af0c4SBarry Smith +   viewer - the `PetscViewer` (created with `PetscViewerDrawOpen()`)
1405c6c1daeSBarry Smith -   windownumber - value to set the base
1415c6c1daeSBarry Smith 
1425c6c1daeSBarry Smith     Level: developer
1435c6c1daeSBarry Smith 
144811af0c4SBarry Smith     Note:
145811af0c4SBarry Smith     A `PETSCVIEWERDRAW` may have multiple `PetscDraw` subwindows, this increases the number of the subwindow that is returned with `PetscViewerDrawGetDraw()`
146811af0c4SBarry Smith 
147db781477SPatrick Sanan .seealso: `PetscViewerDrawGetLG()`, `PetscViewerDrawGetAxis()`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`, `PetscViewerDrawBaseAdd()`
1485c6c1daeSBarry Smith @*/
1499371c9d4SSatish Balay PetscErrorCode PetscViewerDrawBaseSet(PetscViewer viewer, PetscInt windownumber) {
150e5ab1681SLisandro Dalcin   PetscViewer_Draw *vdraw;
1515c6c1daeSBarry Smith   PetscBool         isdraw;
1525c6c1daeSBarry Smith 
1535c6c1daeSBarry Smith   PetscFunctionBegin;
1545c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
155e5ab1681SLisandro Dalcin   PetscValidLogicalCollectiveInt(viewer, windownumber, 2);
1569566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
15728b400f6SJacob Faibussowitsch   PetscCheck(isdraw, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Must be draw type PetscViewer");
158e5ab1681SLisandro Dalcin   vdraw = (PetscViewer_Draw *)viewer->data;
159e5ab1681SLisandro Dalcin 
16008401ef6SPierre Jolivet   PetscCheck(windownumber >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Resulting base %" PetscInt_FMT " cannot be negative", windownumber);
1615c6c1daeSBarry Smith   vdraw->draw_base = windownumber;
1625c6c1daeSBarry Smith   PetscFunctionReturn(0);
1635c6c1daeSBarry Smith }
1645c6c1daeSBarry Smith 
1655c6c1daeSBarry Smith /*@C
166811af0c4SBarry Smith     PetscViewerDrawGetDrawLG - Returns a `PetscDrawLG` object from `PetscViewer` object of type `PETSCVIEWERDRAW`.
167811af0c4SBarry Smith     This `PetscDrawLG` object may then be used to perform graphics using `PetscDrawLG` commands.
1685c6c1daeSBarry Smith 
169811af0c4SBarry Smith     Collective on viewer
1705c6c1daeSBarry Smith 
171d8d19677SJose E. Roman     Input Parameters:
172811af0c4SBarry Smith +   PetscViewer - the `PetscViewer` (created with `PetscViewerDrawOpen()`)
1735c6c1daeSBarry Smith -   windownumber - indicates which subwindow (usually 0)
1745c6c1daeSBarry Smith 
17501d2d390SJose E. Roman     Output Parameter:
1765c6c1daeSBarry Smith .   draw - the draw line graph object
1775c6c1daeSBarry Smith 
1785c6c1daeSBarry Smith     Level: intermediate
1795c6c1daeSBarry Smith 
180811af0c4SBarry Smith     Note:
181811af0c4SBarry Smith     A `PETSCVIEWERDRAW` may have multiple `PetscDraw` subwindows
182811af0c4SBarry Smith 
183811af0c4SBarry Smith .seealso: `PetscDrawLG`, `PetscViewerDrawGetDraw()`, `PetscViewerDrawGetAxis()`, `PetscViewerDrawOpen()`
1845c6c1daeSBarry Smith @*/
1859371c9d4SSatish Balay PetscErrorCode PetscViewerDrawGetDrawLG(PetscViewer viewer, PetscInt windownumber, PetscDrawLG *drawlg) {
1865c6c1daeSBarry Smith   PetscBool         isdraw;
187e5ab1681SLisandro Dalcin   PetscViewer_Draw *vdraw;
1885c6c1daeSBarry Smith 
1895c6c1daeSBarry Smith   PetscFunctionBegin;
1905c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
191e5ab1681SLisandro Dalcin   PetscValidLogicalCollectiveInt(viewer, windownumber, 2);
1925c6c1daeSBarry Smith   PetscValidPointer(drawlg, 3);
1939566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
19428b400f6SJacob Faibussowitsch   PetscCheck(isdraw, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Must be draw type PetscViewer");
19508401ef6SPierre Jolivet   PetscCheck(windownumber >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Window number cannot be negative");
196e5ab1681SLisandro Dalcin   vdraw = (PetscViewer_Draw *)viewer->data;
1975c6c1daeSBarry Smith 
19848a46eb9SPierre Jolivet   if (windownumber + vdraw->draw_base >= vdraw->draw_max || !vdraw->draw[windownumber + vdraw->draw_base]) PetscCall(PetscViewerDrawGetDraw(viewer, windownumber, NULL));
1995c6c1daeSBarry Smith   if (!vdraw->drawlg[windownumber + vdraw->draw_base]) {
2009566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGCreate(vdraw->draw[windownumber + vdraw->draw_base], 1, &vdraw->drawlg[windownumber + vdraw->draw_base]));
2019566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSetFromOptions(vdraw->drawlg[windownumber + vdraw->draw_base]));
2025c6c1daeSBarry Smith   }
2035c6c1daeSBarry Smith   *drawlg = vdraw->drawlg[windownumber + vdraw->draw_base];
2045c6c1daeSBarry Smith   PetscFunctionReturn(0);
2055c6c1daeSBarry Smith }
2065c6c1daeSBarry Smith 
2075c6c1daeSBarry Smith /*@C
208811af0c4SBarry Smith     PetscViewerDrawGetDrawAxis - Returns a `PetscDrawAxis` object from a `PetscViewer` object of type `PETSCVIEWERDRAW`.
209811af0c4SBarry Smith     This `PetscDrawAxis` object may then be used to perform graphics using `PetscDrawAxis` commands.
2105c6c1daeSBarry Smith 
211811af0c4SBarry Smith     Collective on viewer
2125c6c1daeSBarry Smith 
213d8d19677SJose E. Roman     Input Parameters:
214811af0c4SBarry Smith +   viewer - the `PetscViewer` (created with `PetscViewerDrawOpen()`)
2155c6c1daeSBarry Smith -   windownumber - indicates which subwindow (usually 0)
2165c6c1daeSBarry Smith 
21701d2d390SJose E. Roman     Output Parameter:
2185c6c1daeSBarry Smith .   drawaxis - the draw axis object
2195c6c1daeSBarry Smith 
2205c6c1daeSBarry Smith     Level: advanced
2215c6c1daeSBarry Smith 
222811af0c4SBarry Smith     Note:
223811af0c4SBarry Smith     A `PETSCVIEWERDRAW` may have multiple `PetscDraw` subwindows
224811af0c4SBarry Smith 
225db781477SPatrick Sanan .seealso: `PetscViewerDrawGetDraw()`, `PetscViewerDrawGetLG()`, `PetscViewerDrawOpen()`
2265c6c1daeSBarry Smith @*/
2279371c9d4SSatish Balay PetscErrorCode PetscViewerDrawGetDrawAxis(PetscViewer viewer, PetscInt windownumber, PetscDrawAxis *drawaxis) {
2285c6c1daeSBarry Smith   PetscBool         isdraw;
229e5ab1681SLisandro Dalcin   PetscViewer_Draw *vdraw;
2305c6c1daeSBarry Smith 
2315c6c1daeSBarry Smith   PetscFunctionBegin;
2325c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
233e5ab1681SLisandro Dalcin   PetscValidLogicalCollectiveInt(viewer, windownumber, 2);
2345c6c1daeSBarry Smith   PetscValidPointer(drawaxis, 3);
2359566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
23628b400f6SJacob Faibussowitsch   PetscCheck(isdraw, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Must be draw type PetscViewer");
23708401ef6SPierre Jolivet   PetscCheck(windownumber >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Window number cannot be negative");
238e5ab1681SLisandro Dalcin   vdraw = (PetscViewer_Draw *)viewer->data;
2395c6c1daeSBarry Smith 
24048a46eb9SPierre Jolivet   if (windownumber + vdraw->draw_base >= vdraw->draw_max || !vdraw->draw[windownumber + vdraw->draw_base]) PetscCall(PetscViewerDrawGetDraw(viewer, windownumber, NULL));
241*4dfa11a4SJacob Faibussowitsch   if (!vdraw->drawaxis[windownumber + vdraw->draw_base]) PetscCall(PetscDrawAxisCreate(vdraw->draw[windownumber + vdraw->draw_base], &vdraw->drawaxis[windownumber + vdraw->draw_base]));
2425c6c1daeSBarry Smith   *drawaxis = vdraw->drawaxis[windownumber + vdraw->draw_base];
2435c6c1daeSBarry Smith   PetscFunctionReturn(0);
2445c6c1daeSBarry Smith }
2455c6c1daeSBarry Smith 
2469371c9d4SSatish Balay PetscErrorCode PetscViewerDrawResize(PetscViewer v, int w, int h) {
247e5ab1681SLisandro Dalcin   PetscViewer_Draw *vdraw;
248e5ab1681SLisandro Dalcin   PetscBool         isdraw;
2495c6c1daeSBarry Smith 
2505c6c1daeSBarry Smith   PetscFunctionBegin;
251e5ab1681SLisandro Dalcin   PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 1);
2529566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERDRAW, &isdraw));
253e5ab1681SLisandro Dalcin   if (!isdraw) PetscFunctionReturn(0);
254e5ab1681SLisandro Dalcin   vdraw = (PetscViewer_Draw *)v->data;
255e5ab1681SLisandro Dalcin 
256e5ab1681SLisandro Dalcin   if (w >= 1) vdraw->w = w;
257e5ab1681SLisandro Dalcin   if (h >= 1) vdraw->h = h;
2585c6c1daeSBarry Smith   PetscFunctionReturn(0);
2595c6c1daeSBarry Smith }
2605c6c1daeSBarry Smith 
2619371c9d4SSatish Balay PetscErrorCode PetscViewerDrawSetInfo(PetscViewer v, const char display[], const char title[], int x, int y, int w, int h) {
262e5ab1681SLisandro Dalcin   PetscViewer_Draw *vdraw;
263e5ab1681SLisandro Dalcin   PetscBool         isdraw;
2645c6c1daeSBarry Smith 
2655c6c1daeSBarry Smith   PetscFunctionBegin;
266e5ab1681SLisandro Dalcin   PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 1);
2679566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERDRAW, &isdraw));
268e5ab1681SLisandro Dalcin   if (!isdraw) PetscFunctionReturn(0);
269e5ab1681SLisandro Dalcin   vdraw = (PetscViewer_Draw *)v->data;
270e5ab1681SLisandro Dalcin 
2719566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(display, &vdraw->display));
2729566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(title, &vdraw->title));
273e5ab1681SLisandro Dalcin   if (w >= 1) vdraw->w = w;
274e5ab1681SLisandro Dalcin   if (h >= 1) vdraw->h = h;
2755c6c1daeSBarry Smith   PetscFunctionReturn(0);
2765c6c1daeSBarry Smith }
2775c6c1daeSBarry Smith 
2789371c9d4SSatish Balay PetscErrorCode PetscViewerDrawSetDrawType(PetscViewer v, PetscDrawType drawtype) {
279e5ab1681SLisandro Dalcin   PetscViewer_Draw *vdraw;
280e5ab1681SLisandro Dalcin   PetscBool         isdraw;
281d1da0b69SBarry Smith 
282d1da0b69SBarry Smith   PetscFunctionBegin;
283e5ab1681SLisandro Dalcin   PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 1);
2849566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERDRAW, &isdraw));
285e5ab1681SLisandro Dalcin   if (!isdraw) PetscFunctionReturn(0);
286e5ab1681SLisandro Dalcin   vdraw = (PetscViewer_Draw *)v->data;
287e5ab1681SLisandro Dalcin 
2889566063dSJacob Faibussowitsch   PetscCall(PetscFree(vdraw->drawtype));
2899566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(drawtype, (char **)&vdraw->drawtype));
290d1da0b69SBarry Smith   PetscFunctionReturn(0);
291d1da0b69SBarry Smith }
292d1da0b69SBarry Smith 
2939371c9d4SSatish Balay PetscErrorCode PetscViewerDrawGetDrawType(PetscViewer v, PetscDrawType *drawtype) {
2941f49e1f7SLisandro Dalcin   PetscViewer_Draw *vdraw;
2951f49e1f7SLisandro Dalcin   PetscBool         isdraw;
2961f49e1f7SLisandro Dalcin 
2971f49e1f7SLisandro Dalcin   PetscFunctionBegin;
2981f49e1f7SLisandro Dalcin   PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 1);
2999566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERDRAW, &isdraw));
30028b400f6SJacob Faibussowitsch   PetscCheck(isdraw, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Must be draw type PetscViewer");
3011f49e1f7SLisandro Dalcin   vdraw = (PetscViewer_Draw *)v->data;
3021f49e1f7SLisandro Dalcin 
3031f49e1f7SLisandro Dalcin   *drawtype = vdraw->drawtype;
3041f49e1f7SLisandro Dalcin   PetscFunctionReturn(0);
3051f49e1f7SLisandro Dalcin }
3061f49e1f7SLisandro Dalcin 
3079371c9d4SSatish Balay PetscErrorCode PetscViewerDrawSetTitle(PetscViewer v, const char title[]) {
308f55236e4SLisandro Dalcin   PetscViewer_Draw *vdraw;
309f55236e4SLisandro Dalcin   PetscBool         isdraw;
310f55236e4SLisandro Dalcin 
311f55236e4SLisandro Dalcin   PetscFunctionBegin;
312f55236e4SLisandro Dalcin   PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 1);
3139566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERDRAW, &isdraw));
314f55236e4SLisandro Dalcin   if (!isdraw) PetscFunctionReturn(0);
315f55236e4SLisandro Dalcin   vdraw = (PetscViewer_Draw *)v->data;
316f55236e4SLisandro Dalcin 
3179566063dSJacob Faibussowitsch   PetscCall(PetscFree(vdraw->title));
3189566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(title, &vdraw->title));
319f55236e4SLisandro Dalcin   PetscFunctionReturn(0);
320f55236e4SLisandro Dalcin }
321f55236e4SLisandro Dalcin 
3229371c9d4SSatish Balay PetscErrorCode PetscViewerDrawGetTitle(PetscViewer v, const char *title[]) {
323f55236e4SLisandro Dalcin   PetscViewer_Draw *vdraw;
324f55236e4SLisandro Dalcin   PetscBool         isdraw;
325f55236e4SLisandro Dalcin 
326f55236e4SLisandro Dalcin   PetscFunctionBegin;
327f55236e4SLisandro Dalcin   PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 1);
3289566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERDRAW, &isdraw));
32928b400f6SJacob Faibussowitsch   PetscCheck(isdraw, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Must be draw type PetscViewer");
330f55236e4SLisandro Dalcin   vdraw = (PetscViewer_Draw *)v->data;
331f55236e4SLisandro Dalcin 
332f55236e4SLisandro Dalcin   *title = vdraw->title;
333f55236e4SLisandro Dalcin   PetscFunctionReturn(0);
334f55236e4SLisandro Dalcin }
335f55236e4SLisandro Dalcin 
3365c6c1daeSBarry Smith /*@C
337811af0c4SBarry Smith    PetscViewerDrawOpen - Opens a `PetscDraw` window for use as a `PetscViewer` with type `PETSCVIEWERDRAW`. If you want to
338811af0c4SBarry Smith    do graphics in this window, you must call `PetscViewerDrawGetDraw()` and
339811af0c4SBarry Smith    perform the graphics on the `PetscDraw` object.
3405c6c1daeSBarry Smith 
341d083f849SBarry Smith    Collective
3425c6c1daeSBarry Smith 
3435c6c1daeSBarry Smith    Input Parameters:
3445c6c1daeSBarry Smith +  comm - communicator that will share window
3455c6c1daeSBarry Smith .  display - the X display on which to open, or null for the local machine
3465c6c1daeSBarry Smith .  title - the title to put in the title bar, or null for no title
347811af0c4SBarry Smith .  x, y - the screen coordinates of the upper left corner of window, or use `PETSC_DECIDE`
348811af0c4SBarry Smith -  w, h - window width and height in pixels, or may use `PETSC_DECIDE` or `PETSC_DRAW_FULL_SIZE`, `PETSC_DRAW_HALF_SIZE`,
349811af0c4SBarry Smith           `PETSC_DRAW_THIRD_SIZE`, `PETSC_DRAW_QUARTER_SIZE`
3505c6c1daeSBarry Smith 
351f899ff85SJose E. Roman    Output Parameter:
352811af0c4SBarry Smith . viewer - the `PetscViewer`
3535c6c1daeSBarry Smith 
3545c6c1daeSBarry Smith    Format Options:
355811af0c4SBarry Smith +  `PETSC_VIEWER_DRAW_BASIC` - displays with basic format
356811af0c4SBarry Smith -  `PETSC_VIEWER_DRAW_LG`    - displays using a line graph
3575c6c1daeSBarry Smith 
3585c6c1daeSBarry Smith    Options Database Keys:
35910699b91SBarry Smith +  -draw_type - use x or null
3605c6c1daeSBarry Smith .  -nox - Disables all x-windows output
3615c6c1daeSBarry Smith .  -display <name> - Specifies name of machine for the X display
3625c6c1daeSBarry Smith .  -geometry <x,y,w,h> - allows setting the window location and size
3635c6c1daeSBarry Smith -  -draw_pause <pause> - Sets time (in seconds) that the
3645c6c1daeSBarry Smith      program pauses after PetscDrawPause() has been called
3655c6c1daeSBarry Smith      (0 is default, -1 implies until user input).
3665c6c1daeSBarry Smith 
3675c6c1daeSBarry Smith    Level: beginner
3685c6c1daeSBarry Smith 
3695c6c1daeSBarry Smith    Note for Fortran Programmers:
3705c6c1daeSBarry Smith    Whenever indicating null character data in a Fortran code,
371811af0c4SBarry Smith    `PETSC_NULL_CHARACTER` must be employed; using NULL is not
372811af0c4SBarry Smith    correct for character data!  Thus, `PETSC_NULL_CHARACTER` can be
3735c6c1daeSBarry Smith    used for the display and title input parameters.
3745c6c1daeSBarry Smith 
375811af0c4SBarry Smith .seealso: `PETSCVIEWERDRAW`, `PetscDrawCreate()`, `PetscViewerDestroy()`, `PetscViewerDrawGetDraw()`, `PetscViewerCreate()`, `PETSC_VIEWER_DRAW_`,
376db781477SPatrick Sanan           `PETSC_VIEWER_DRAW_WORLD`, `PETSC_VIEWER_DRAW_SELF`
3775c6c1daeSBarry Smith @*/
3789371c9d4SSatish Balay PetscErrorCode PetscViewerDrawOpen(MPI_Comm comm, const char display[], const char title[], int x, int y, int w, int h, PetscViewer *viewer) {
3795c6c1daeSBarry Smith   PetscFunctionBegin;
3809566063dSJacob Faibussowitsch   PetscCall(PetscViewerCreate(comm, viewer));
3819566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetType(*viewer, PETSCVIEWERDRAW));
3829566063dSJacob Faibussowitsch   PetscCall(PetscViewerDrawSetInfo(*viewer, display, title, x, y, w, h));
3835c6c1daeSBarry Smith   PetscFunctionReturn(0);
3845c6c1daeSBarry Smith }
3855c6c1daeSBarry Smith 
386a9db196aSBarry Smith #include <petsc/private/drawimpl.h>
387a9db196aSBarry Smith 
3889371c9d4SSatish Balay PetscErrorCode PetscViewerGetSubViewer_Draw(PetscViewer viewer, MPI_Comm comm, PetscViewer *sviewer) {
3895c6c1daeSBarry Smith   PetscMPIInt       rank;
3905c6c1daeSBarry Smith   PetscInt          i;
391c6228bbaSLisandro Dalcin   PetscViewer_Draw *vdraw = (PetscViewer_Draw *)viewer->data, *svdraw;
3925c6c1daeSBarry Smith 
3935c6c1daeSBarry Smith   PetscFunctionBegin;
39428b400f6SJacob Faibussowitsch   PetscCheck(!vdraw->singleton_made, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Trying to get SubViewer without first restoring previous");
3955c6c1daeSBarry Smith   /* only processor zero can use the PetscViewer draw singleton */
396fefe69c3SStefano Zampini   if (sviewer) *sviewer = NULL;
3979566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank));
398dd400576SPatrick Sanan   if (rank == 0) {
399e5afcf28SBarry Smith     PetscMPIInt flg;
400a9db196aSBarry Smith     PetscDraw   draw, sdraw;
401e5afcf28SBarry Smith 
4029566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_compare(PETSC_COMM_SELF, comm, &flg));
403cc73adaaSBarry Smith     PetscCheck(flg == MPI_IDENT || flg == MPI_CONGRUENT, PETSC_COMM_SELF, PETSC_ERR_SUP, "PetscViewerGetSubViewer() for PETSCVIEWERDRAW requires a singleton MPI_Comm");
4049566063dSJacob Faibussowitsch     PetscCall(PetscViewerCreate(comm, sviewer));
4059566063dSJacob Faibussowitsch     PetscCall(PetscViewerSetType(*sviewer, PETSCVIEWERDRAW));
406c6228bbaSLisandro Dalcin     svdraw             = (PetscViewer_Draw *)(*sviewer)->data;
407c6228bbaSLisandro Dalcin     (*sviewer)->format = viewer->format;
408c6228bbaSLisandro Dalcin     for (i = 0; i < vdraw->draw_max; i++) { /* XXX this is wrong if svdraw->draw_max (initially 5) < vdraw->draw_max */
4099566063dSJacob Faibussowitsch       if (vdraw->draw[i]) PetscCall(PetscDrawGetSingleton(vdraw->draw[i], &svdraw->draw[i]));
4105c6c1daeSBarry Smith     }
4119566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw));
4129566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawGetDraw(*sviewer, 0, &sdraw));
413a9db196aSBarry Smith     if (draw->savefilename) {
4149566063dSJacob Faibussowitsch       PetscCall(PetscDrawSetSave(sdraw, draw->savefilename));
415a9db196aSBarry Smith       sdraw->savefilecount  = draw->savefilecount;
416a9db196aSBarry Smith       sdraw->savesinglefile = draw->savesinglefile;
417a9db196aSBarry Smith       sdraw->savemoviefps   = draw->savemoviefps;
418a9db196aSBarry Smith       sdraw->saveonclear    = draw->saveonclear;
419a9db196aSBarry Smith       sdraw->saveonflush    = draw->saveonflush;
420a9db196aSBarry Smith     }
4219566063dSJacob Faibussowitsch     if (draw->savefinalfilename) PetscCall(PetscDrawSetSaveFinalImage(sdraw, draw->savefinalfilename));
422a9db196aSBarry Smith   } else {
423a9db196aSBarry Smith     PetscDraw draw;
4249566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw));
4255c6c1daeSBarry Smith   }
4265c6c1daeSBarry Smith   vdraw->singleton_made = PETSC_TRUE;
4275c6c1daeSBarry Smith   PetscFunctionReturn(0);
4285c6c1daeSBarry Smith }
4295c6c1daeSBarry Smith 
4309371c9d4SSatish Balay PetscErrorCode PetscViewerRestoreSubViewer_Draw(PetscViewer viewer, MPI_Comm comm, PetscViewer *sviewer) {
4315c6c1daeSBarry Smith   PetscMPIInt       rank;
4325c6c1daeSBarry Smith   PetscInt          i;
433c6228bbaSLisandro Dalcin   PetscViewer_Draw *vdraw = (PetscViewer_Draw *)viewer->data, *svdraw;
4345c6c1daeSBarry Smith 
4355c6c1daeSBarry Smith   PetscFunctionBegin;
43628b400f6SJacob Faibussowitsch   PetscCheck(vdraw->singleton_made, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Trying to restore a singleton that was not gotten");
4379566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank));
438dd400576SPatrick Sanan   if (rank == 0) {
439a9db196aSBarry Smith     PetscDraw draw, sdraw;
440a9db196aSBarry Smith 
4419566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw));
4429566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawGetDraw(*sviewer, 0, &sdraw));
443a9db196aSBarry Smith     if (draw->savefilename) {
444a9db196aSBarry Smith       draw->savefilecount = sdraw->savefilecount;
4459566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Bcast(&draw->savefilecount, 1, MPIU_INT, 0, PetscObjectComm((PetscObject)draw)));
446a9db196aSBarry Smith     }
447c6228bbaSLisandro Dalcin     svdraw = (PetscViewer_Draw *)(*sviewer)->data;
4485c6c1daeSBarry Smith     for (i = 0; i < vdraw->draw_max; i++) {
44948a46eb9SPierre Jolivet       if (vdraw->draw[i] && svdraw->draw[i]) PetscCall(PetscDrawRestoreSingleton(vdraw->draw[i], &svdraw->draw[i]));
4505c6c1daeSBarry Smith     }
4519566063dSJacob Faibussowitsch     PetscCall(PetscFree3(svdraw->draw, svdraw->drawlg, svdraw->drawaxis));
4529566063dSJacob Faibussowitsch     PetscCall(PetscFree((*sviewer)->data));
4539566063dSJacob Faibussowitsch     PetscCall(PetscHeaderDestroy(sviewer));
454a9db196aSBarry Smith   } else {
455a9db196aSBarry Smith     PetscDraw draw;
456a9db196aSBarry Smith 
4579566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw));
45848a46eb9SPierre Jolivet     if (draw->savefilename) PetscCallMPI(MPI_Bcast(&draw->savefilecount, 1, MPIU_INT, 0, PetscObjectComm((PetscObject)draw)));
459a9db196aSBarry Smith   }
460a9db196aSBarry Smith 
4615c6c1daeSBarry Smith   vdraw->singleton_made = PETSC_FALSE;
4625c6c1daeSBarry Smith   PetscFunctionReturn(0);
4635c6c1daeSBarry Smith }
4645c6c1daeSBarry Smith 
4659371c9d4SSatish Balay PetscErrorCode PetscViewerSetFromOptions_Draw(PetscViewer v, PetscOptionItems *PetscOptionsObject) {
466e9457bf7SBarry Smith   PetscReal bounds[16];
467e9457bf7SBarry Smith   PetscInt  nbounds = 16;
468e9457bf7SBarry Smith   PetscBool flg;
469e9457bf7SBarry Smith 
470e9457bf7SBarry Smith   PetscFunctionBegin;
471d0609cedSBarry Smith   PetscOptionsHeadBegin(PetscOptionsObject, "Draw PetscViewer Options");
4729566063dSJacob Faibussowitsch   PetscCall(PetscOptionsRealArray("-draw_bounds", "Bounds to put on plots axis", "PetscViewerDrawSetBounds", bounds, &nbounds, &flg));
47348a46eb9SPierre Jolivet   if (flg) PetscCall(PetscViewerDrawSetBounds(v, nbounds / 2, bounds));
474d0609cedSBarry Smith   PetscOptionsHeadEnd();
475e9457bf7SBarry Smith   PetscFunctionReturn(0);
476e9457bf7SBarry Smith }
477e9457bf7SBarry Smith 
4789371c9d4SSatish Balay PetscErrorCode PetscViewerView_Draw(PetscViewer viewer, PetscViewer v) {
4790076e027SBarry Smith   PetscDraw         draw;
4800076e027SBarry Smith   PetscInt          i;
4810076e027SBarry Smith   PetscViewer_Draw *vdraw = (PetscViewer_Draw *)viewer->data;
4820076e027SBarry Smith 
4830076e027SBarry Smith   PetscFunctionBegin;
4840076e027SBarry Smith   /*  If the PetscViewer has just been created then no vdraw->draw yet
4850076e027SBarry Smith       exists so this will not actually call the viewer on any draws. */
4860076e027SBarry Smith   for (i = 0; i < vdraw->draw_base; i++) {
4870076e027SBarry Smith     if (vdraw->draw[i]) {
4889566063dSJacob Faibussowitsch       PetscCall(PetscViewerDrawGetDraw(viewer, i, &draw));
4899566063dSJacob Faibussowitsch       PetscCall(PetscDrawView(draw, v));
4900076e027SBarry Smith     }
4910076e027SBarry Smith   }
4920076e027SBarry Smith   PetscFunctionReturn(0);
4930076e027SBarry Smith }
4940076e027SBarry Smith 
4958556b5ebSBarry Smith /*MC
4968556b5ebSBarry Smith    PETSCVIEWERDRAW - A viewer that generates graphics, either to the screen or a file
4978556b5ebSBarry Smith 
498811af0c4SBarry Smith   Level: beginner
499811af0c4SBarry Smith 
500c2e3fba1SPatrick Sanan .seealso: `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`, `PETSC_VIEWER_DRAW_()`, `PETSC_VIEWER_DRAW_SELF`, `PETSC_VIEWER_DRAW_WORLD`,
501db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerASCIIOpen()`, `PetscViewerBinaryOpen()`, `PETSCVIEWERBINARY`,
502db781477SPatrick Sanan           `PetscViewerMatlabOpen()`, `VecView()`, `DMView()`, `PetscViewerMatlabPutArray()`, `PETSCVIEWERASCII`, `PETSCVIEWERMATLAB`,
503db781477SPatrick Sanan           `PetscViewerFileSetName()`, `PetscViewerFileSetMode()`, `PetscViewerFormat`, `PetscViewerType`, `PetscViewerSetType()`
5048556b5ebSBarry Smith M*/
5059371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode PetscViewerCreate_Draw(PetscViewer viewer) {
5065c6c1daeSBarry Smith   PetscViewer_Draw *vdraw;
5075c6c1daeSBarry Smith 
5085c6c1daeSBarry Smith   PetscFunctionBegin;
509*4dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&vdraw));
5105c6c1daeSBarry Smith   viewer->data = (void *)vdraw;
5115c6c1daeSBarry Smith 
5125c6c1daeSBarry Smith   viewer->ops->flush            = PetscViewerFlush_Draw;
5130076e027SBarry Smith   viewer->ops->view             = PetscViewerView_Draw;
5145c6c1daeSBarry Smith   viewer->ops->destroy          = PetscViewerDestroy_Draw;
515e9457bf7SBarry Smith   viewer->ops->setfromoptions   = PetscViewerSetFromOptions_Draw;
516559f443fSBarry Smith   viewer->ops->getsubviewer     = PetscViewerGetSubViewer_Draw;
517559f443fSBarry Smith   viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_Draw;
5185c6c1daeSBarry Smith 
5195c6c1daeSBarry Smith   /* these are created on the fly if requested */
5205c6c1daeSBarry Smith   vdraw->draw_max  = 5;
5215c6c1daeSBarry Smith   vdraw->draw_base = 0;
522ccad63c3SBarry Smith   vdraw->w         = PETSC_DECIDE;
523ccad63c3SBarry Smith   vdraw->h         = PETSC_DECIDE;
524a297a907SKarl Rupp 
5259566063dSJacob Faibussowitsch   PetscCall(PetscCalloc3(vdraw->draw_max, &vdraw->draw, vdraw->draw_max, &vdraw->drawlg, vdraw->draw_max, &vdraw->drawaxis));
5265c6c1daeSBarry Smith   vdraw->singleton_made = PETSC_FALSE;
5275c6c1daeSBarry Smith   PetscFunctionReturn(0);
5285c6c1daeSBarry Smith }
5295c6c1daeSBarry Smith 
5305c6c1daeSBarry Smith /*@
531811af0c4SBarry Smith     PetscViewerDrawClear - Clears a `PetscDraw` graphic associated with a `PetscViewer`.
5325c6c1daeSBarry Smith 
5335c6c1daeSBarry Smith     Not Collective
5345c6c1daeSBarry Smith 
5355c6c1daeSBarry Smith     Input Parameter:
536811af0c4SBarry Smith .  viewer - the `PetscViewer`
5375c6c1daeSBarry Smith 
5385c6c1daeSBarry Smith     Level: intermediate
5395c6c1daeSBarry Smith 
540811af0c4SBarry Smith .seealso: `PETSCVIEWERDRAW`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`,
5415c6c1daeSBarry Smith @*/
5429371c9d4SSatish Balay PetscErrorCode PetscViewerDrawClear(PetscViewer viewer) {
5435c6c1daeSBarry Smith   PetscViewer_Draw *vdraw;
544e5ab1681SLisandro Dalcin   PetscBool         isdraw;
545e5ab1681SLisandro Dalcin   PetscInt          i;
5465c6c1daeSBarry Smith 
5475c6c1daeSBarry Smith   PetscFunctionBegin;
548e5ab1681SLisandro Dalcin   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
5499566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
550e5ab1681SLisandro Dalcin   if (!isdraw) PetscFunctionReturn(0);
5515c6c1daeSBarry Smith   vdraw = (PetscViewer_Draw *)viewer->data;
552e5ab1681SLisandro Dalcin 
5535c6c1daeSBarry Smith   for (i = 0; i < vdraw->draw_max; i++) {
5549566063dSJacob Faibussowitsch     if (vdraw->draw[i]) PetscCall(PetscDrawClear(vdraw->draw[i]));
5555c6c1daeSBarry Smith   }
5565c6c1daeSBarry Smith   PetscFunctionReturn(0);
5575c6c1daeSBarry Smith }
5585c6c1daeSBarry Smith 
5595c6c1daeSBarry Smith /*@
560811af0c4SBarry Smith     PetscViewerDrawGetPause - Gets the pause value (how long to pause before an image is changed)  in the `PETSCVIEWERDRAW` `PetscViewer`
5615c6c1daeSBarry Smith 
5625c6c1daeSBarry Smith     Not Collective
5635c6c1daeSBarry Smith 
5645c6c1daeSBarry Smith     Input Parameter:
565811af0c4SBarry Smith .  viewer - the `PetscViewer`
5665c6c1daeSBarry Smith 
5675c6c1daeSBarry Smith     Output Parameter:
5685c6c1daeSBarry Smith .  pause - the pause value
5695c6c1daeSBarry Smith 
5705c6c1daeSBarry Smith     Level: intermediate
5715c6c1daeSBarry Smith 
572811af0c4SBarry Smith .seealso: `PETSCVIEWERDRAW`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`,
5735c6c1daeSBarry Smith @*/
5749371c9d4SSatish Balay PetscErrorCode PetscViewerDrawGetPause(PetscViewer viewer, PetscReal *pause) {
5755c6c1daeSBarry Smith   PetscViewer_Draw *vdraw;
576e5ab1681SLisandro Dalcin   PetscBool         isdraw;
577e5ab1681SLisandro Dalcin   PetscInt          i;
5785c6c1daeSBarry Smith   PetscDraw         draw;
5795c6c1daeSBarry Smith 
5805c6c1daeSBarry Smith   PetscFunctionBegin;
581e5ab1681SLisandro Dalcin   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
5829566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
5839371c9d4SSatish Balay   if (!isdraw) {
5849371c9d4SSatish Balay     *pause = 0.0;
5859371c9d4SSatish Balay     PetscFunctionReturn(0);
5869371c9d4SSatish Balay   }
5875c6c1daeSBarry Smith   vdraw = (PetscViewer_Draw *)viewer->data;
588e5ab1681SLisandro Dalcin 
5895c6c1daeSBarry Smith   for (i = 0; i < vdraw->draw_max; i++) {
5905c6c1daeSBarry Smith     if (vdraw->draw[i]) {
5919566063dSJacob Faibussowitsch       PetscCall(PetscDrawGetPause(vdraw->draw[i], pause));
5925c6c1daeSBarry Smith       PetscFunctionReturn(0);
5935c6c1daeSBarry Smith     }
5945c6c1daeSBarry Smith   }
5955c6c1daeSBarry Smith   /* none exist yet so create one and get its pause */
5969566063dSJacob Faibussowitsch   PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw));
5979566063dSJacob Faibussowitsch   PetscCall(PetscDrawGetPause(draw, pause));
5985c6c1daeSBarry Smith   PetscFunctionReturn(0);
5995c6c1daeSBarry Smith }
6005c6c1daeSBarry Smith 
6015c6c1daeSBarry Smith /*@
602811af0c4SBarry Smith     PetscViewerDrawSetPause - Sets a pause for each `PetscDraw` in the `PETSCVIEWERDRAW` `PetscViewer`
6035c6c1daeSBarry Smith 
6045c6c1daeSBarry Smith     Not Collective
6055c6c1daeSBarry Smith 
6065c6c1daeSBarry Smith     Input Parameters:
607811af0c4SBarry Smith +  viewer - the `PetscViewer`
6085c6c1daeSBarry Smith -  pause - the pause value
6095c6c1daeSBarry Smith 
6105c6c1daeSBarry Smith     Level: intermediate
6115c6c1daeSBarry Smith 
612811af0c4SBarry Smith .seealso: `PETSCVIEWERDRAW`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`,
6135c6c1daeSBarry Smith @*/
6149371c9d4SSatish Balay PetscErrorCode PetscViewerDrawSetPause(PetscViewer viewer, PetscReal pause) {
615e5ab1681SLisandro Dalcin   PetscViewer_Draw *vdraw;
6165c6c1daeSBarry Smith   PetscBool         isdraw;
617e5ab1681SLisandro Dalcin   PetscInt          i;
6185c6c1daeSBarry Smith 
6195c6c1daeSBarry Smith   PetscFunctionBegin;
620e5ab1681SLisandro Dalcin   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
6219566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
622e5ab1681SLisandro Dalcin   if (!isdraw) PetscFunctionReturn(0);
623e5ab1681SLisandro Dalcin   vdraw = (PetscViewer_Draw *)viewer->data;
624afe78b3cSBarry Smith 
625afe78b3cSBarry Smith   vdraw->pause = pause;
6265c6c1daeSBarry Smith   for (i = 0; i < vdraw->draw_max; i++) {
6279566063dSJacob Faibussowitsch     if (vdraw->draw[i]) PetscCall(PetscDrawSetPause(vdraw->draw[i], pause));
6285c6c1daeSBarry Smith   }
6295c6c1daeSBarry Smith   PetscFunctionReturn(0);
6305c6c1daeSBarry Smith }
6315c6c1daeSBarry Smith 
6325c6c1daeSBarry Smith /*@
6335c6c1daeSBarry Smith     PetscViewerDrawSetHold - Holds previous image when drawing new image
6345c6c1daeSBarry Smith 
6355c6c1daeSBarry Smith     Not Collective
6365c6c1daeSBarry Smith 
6375c6c1daeSBarry Smith     Input Parameters:
638811af0c4SBarry Smith +  viewer - the `PetscViewer`
639811af0c4SBarry Smith -  hold - `PETSC_TRUE` indicates to hold the previous image
6405c6c1daeSBarry Smith 
6415c6c1daeSBarry Smith     Level: intermediate
6425c6c1daeSBarry Smith 
643811af0c4SBarry Smith .seealso: `PETSCVIEWERDRAW`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`,
6445c6c1daeSBarry Smith @*/
6459371c9d4SSatish Balay PetscErrorCode PetscViewerDrawSetHold(PetscViewer viewer, PetscBool hold) {
6465c6c1daeSBarry Smith   PetscViewer_Draw *vdraw;
6475c6c1daeSBarry Smith   PetscBool         isdraw;
6485c6c1daeSBarry Smith 
6495c6c1daeSBarry Smith   PetscFunctionBegin;
650e5ab1681SLisandro Dalcin   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
6519566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
652e5ab1681SLisandro Dalcin   if (!isdraw) PetscFunctionReturn(0);
6535c6c1daeSBarry Smith   vdraw = (PetscViewer_Draw *)viewer->data;
654e5ab1681SLisandro Dalcin 
6555c6c1daeSBarry Smith   vdraw->hold = hold;
6565c6c1daeSBarry Smith   PetscFunctionReturn(0);
6575c6c1daeSBarry Smith }
6585c6c1daeSBarry Smith 
6595c6c1daeSBarry Smith /*@
660811af0c4SBarry Smith     PetscViewerDrawGetHold - Checks if the `PETSCVIEWERDRAW` `PetscViewer` holds previous image when drawing new image
6615c6c1daeSBarry Smith 
6625c6c1daeSBarry Smith     Not Collective
6635c6c1daeSBarry Smith 
6645c6c1daeSBarry Smith     Input Parameter:
665811af0c4SBarry Smith .  viewer - the `PetscViewer`
6665c6c1daeSBarry Smith 
6675c6c1daeSBarry Smith     Output Parameter:
6685c6c1daeSBarry Smith .  hold - indicates to hold or not
6695c6c1daeSBarry Smith 
6705c6c1daeSBarry Smith     Level: intermediate
6715c6c1daeSBarry Smith 
672811af0c4SBarry Smith .seealso: `PETSCVIEWERDRAW`, `PetscViewerDrawOpen()`, `PetscViewerDrawGetDraw()`,
6735c6c1daeSBarry Smith @*/
6749371c9d4SSatish Balay PetscErrorCode PetscViewerDrawGetHold(PetscViewer viewer, PetscBool *hold) {
6755c6c1daeSBarry Smith   PetscViewer_Draw *vdraw;
6765c6c1daeSBarry Smith   PetscBool         isdraw;
6775c6c1daeSBarry Smith 
6785c6c1daeSBarry Smith   PetscFunctionBegin;
679e5ab1681SLisandro Dalcin   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
6809566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
6819371c9d4SSatish Balay   if (!isdraw) {
6829371c9d4SSatish Balay     *hold = PETSC_FALSE;
6839371c9d4SSatish Balay     PetscFunctionReturn(0);
6849371c9d4SSatish Balay   }
6855c6c1daeSBarry Smith   vdraw = (PetscViewer_Draw *)viewer->data;
686e5ab1681SLisandro Dalcin 
6875c6c1daeSBarry Smith   *hold = vdraw->hold;
6885c6c1daeSBarry Smith   PetscFunctionReturn(0);
6895c6c1daeSBarry Smith }
6905c6c1daeSBarry Smith 
6915c6c1daeSBarry Smith /* ---------------------------------------------------------------------*/
6925c6c1daeSBarry Smith /*
6935c6c1daeSBarry Smith     The variable Petsc_Viewer_Draw_keyval is used to indicate an MPI attribute that
6945c6c1daeSBarry Smith   is attached to a communicator, in this case the attribute is a PetscViewer.
6955c6c1daeSBarry Smith */
696d4c7638eSBarry Smith PetscMPIInt Petsc_Viewer_Draw_keyval = MPI_KEYVAL_INVALID;
6975c6c1daeSBarry Smith 
6985c6c1daeSBarry Smith /*@C
699811af0c4SBarry Smith     PETSC_VIEWER_DRAW_ - Creates a window `PETSCVIEWERDRAW` `PetscViewer` shared by all processors
7005c6c1daeSBarry Smith                      in a communicator.
7015c6c1daeSBarry Smith 
702d083f849SBarry Smith      Collective
7035c6c1daeSBarry Smith 
7045c6c1daeSBarry Smith      Input Parameter:
705811af0c4SBarry Smith .    comm - the MPI communicator to share the window `PetscViewer`
7065c6c1daeSBarry Smith 
7075c6c1daeSBarry Smith      Level: intermediate
7085c6c1daeSBarry Smith 
709811af0c4SBarry Smith      Note:
710811af0c4SBarry Smith      Unlike almost all other PETSc routines, `PETSC_VIEWER_DRAW_()` does not return
7115c6c1daeSBarry Smith      an error code.  The window is usually used in the form
7125c6c1daeSBarry Smith $       XXXView(XXX object,PETSC_VIEWER_DRAW_(comm));
7135c6c1daeSBarry Smith 
714811af0c4SBarry Smith .seealso: `PETSCVIEWERDRAW`, `PetscViewer`, `PETSC_VIEWER_DRAW_WORLD`, `PETSC_VIEWER_DRAW_SELF`, `PetscViewerDrawOpen()`,
7155c6c1daeSBarry Smith @*/
7169371c9d4SSatish Balay PetscViewer PETSC_VIEWER_DRAW_(MPI_Comm comm) {
7175c6c1daeSBarry Smith   PetscErrorCode ierr;
7185c6c1daeSBarry Smith   PetscMPIInt    flag;
7195c6c1daeSBarry Smith   PetscViewer    viewer;
7205c6c1daeSBarry Smith   MPI_Comm       ncomm;
7215c6c1daeSBarry Smith 
7225c6c1daeSBarry Smith   PetscFunctionBegin;
7239371c9d4SSatish Balay   ierr = PetscCommDuplicate(comm, &ncomm, NULL);
7249371c9d4SSatish Balay   if (ierr) {
7259371c9d4SSatish Balay     PetscError(PETSC_COMM_SELF, __LINE__, "PETSC_VIEWER_DRAW_", __FILE__, PETSC_ERR_PLIB, PETSC_ERROR_INITIAL, " ");
7269371c9d4SSatish Balay     PetscFunctionReturn(NULL);
7279371c9d4SSatish Balay   }
7285c6c1daeSBarry Smith   if (Petsc_Viewer_Draw_keyval == MPI_KEYVAL_INVALID) {
72902c9f0b5SLisandro Dalcin     ierr = MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN, MPI_COMM_NULL_DELETE_FN, &Petsc_Viewer_Draw_keyval, NULL);
7309371c9d4SSatish Balay     if (ierr) {
7319371c9d4SSatish Balay       PetscError(PETSC_COMM_SELF, __LINE__, "PETSC_VIEWER_DRAW_", __FILE__, PETSC_ERR_PLIB, PETSC_ERROR_INITIAL, " ");
7329371c9d4SSatish Balay       PetscFunctionReturn(NULL);
7339371c9d4SSatish Balay     }
7345c6c1daeSBarry Smith   }
73547435625SJed Brown   ierr = MPI_Comm_get_attr(ncomm, Petsc_Viewer_Draw_keyval, (void **)&viewer, &flag);
7369371c9d4SSatish Balay   if (ierr) {
7379371c9d4SSatish Balay     PetscError(PETSC_COMM_SELF, __LINE__, "PETSC_VIEWER_DRAW_", __FILE__, PETSC_ERR_PLIB, PETSC_ERROR_INITIAL, " ");
7389371c9d4SSatish Balay     PetscFunctionReturn(NULL);
7399371c9d4SSatish Balay   }
7405c6c1daeSBarry Smith   if (!flag) { /* PetscViewer not yet created */
74102c9f0b5SLisandro Dalcin     ierr = PetscViewerDrawOpen(ncomm, NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 300, 300, &viewer);
7429371c9d4SSatish Balay     if (ierr) {
7439371c9d4SSatish Balay       PetscError(PETSC_COMM_SELF, __LINE__, "PETSC_VIEWER_DRAW_", __FILE__, PETSC_ERR_PLIB, PETSC_ERROR_REPEAT, " ");
7449371c9d4SSatish Balay       PetscFunctionReturn(NULL);
7459371c9d4SSatish Balay     }
7465c6c1daeSBarry Smith     ierr = PetscObjectRegisterDestroy((PetscObject)viewer);
7479371c9d4SSatish Balay     if (ierr) {
7489371c9d4SSatish Balay       PetscError(PETSC_COMM_SELF, __LINE__, "PETSC_VIEWER_DRAW_", __FILE__, PETSC_ERR_PLIB, PETSC_ERROR_REPEAT, " ");
7499371c9d4SSatish Balay       PetscFunctionReturn(NULL);
7509371c9d4SSatish Balay     }
75147435625SJed Brown     ierr = MPI_Comm_set_attr(ncomm, Petsc_Viewer_Draw_keyval, (void *)viewer);
7529371c9d4SSatish Balay     if (ierr) {
7539371c9d4SSatish Balay       PetscError(PETSC_COMM_SELF, __LINE__, "PETSC_VIEWER_DRAW_", __FILE__, PETSC_ERR_PLIB, PETSC_ERROR_INITIAL, " ");
7549371c9d4SSatish Balay       PetscFunctionReturn(NULL);
7559371c9d4SSatish Balay     }
7565c6c1daeSBarry Smith   }
7575c6c1daeSBarry Smith   ierr = PetscCommDestroy(&ncomm);
7589371c9d4SSatish Balay   if (ierr) {
7599371c9d4SSatish Balay     PetscError(PETSC_COMM_SELF, __LINE__, "PETSC_VIEWER_DRAW_", __FILE__, PETSC_ERR_PLIB, PETSC_ERROR_REPEAT, " ");
7609371c9d4SSatish Balay     PetscFunctionReturn(NULL);
7619371c9d4SSatish Balay   }
7625c6c1daeSBarry Smith   PetscFunctionReturn(viewer);
7635c6c1daeSBarry Smith }
7645c6c1daeSBarry Smith 
7655c6c1daeSBarry Smith /*@
7665c6c1daeSBarry Smith     PetscViewerDrawSetBounds - sets the upper and lower bounds to be used in plotting
7675c6c1daeSBarry Smith 
768811af0c4SBarry Smith     Collective on viewer
7695c6c1daeSBarry Smith 
7705c6c1daeSBarry Smith     Input Parameters:
771811af0c4SBarry Smith +   viewer - the Petsc`Viewer` (created with `PetscViewerDrawOpen()`)
772811af0c4SBarry Smith .   nbounds - number of plots that can be made with this viewer, for example the dof passed to `DMDACreate()`
7735c6c1daeSBarry 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, .....
7745c6c1daeSBarry Smith 
775811af0c4SBarry Smith     Options Database Key:
77610699b91SBarry Smith .   -draw_bounds  minF0,maxF0,minF1,maxF1 - the lower left and upper right bounds
777e9457bf7SBarry Smith 
7785c6c1daeSBarry Smith     Level: intermediate
7795c6c1daeSBarry Smith 
780811af0c4SBarry Smith     Note:
781811af0c4SBarry 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
782f3f0eb19SBarry 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
783f3f0eb19SBarry Smith       this viewer. Otherwise the color to physical value meaning changes with each new image if this is not set.
784f3f0eb19SBarry Smith 
785811af0c4SBarry Smith .seealso: `PETSCVIEWERDRAW`, `PetscViewerDrawGetLG()`, `PetscViewerDrawGetAxis()`, `PetscViewerDrawOpen()`
7865c6c1daeSBarry Smith @*/
7879371c9d4SSatish Balay PetscErrorCode PetscViewerDrawSetBounds(PetscViewer viewer, PetscInt nbounds, const PetscReal *bounds) {
788e5ab1681SLisandro Dalcin   PetscViewer_Draw *vdraw;
789e5ab1681SLisandro Dalcin   PetscBool         isdraw;
7905c6c1daeSBarry Smith 
7915c6c1daeSBarry Smith   PetscFunctionBegin;
7925c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
7939566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
794e5ab1681SLisandro Dalcin   if (!isdraw) PetscFunctionReturn(0);
795e5ab1681SLisandro Dalcin   vdraw = (PetscViewer_Draw *)viewer->data;
796a297a907SKarl Rupp 
797e5ab1681SLisandro Dalcin   vdraw->nbounds = nbounds;
7989566063dSJacob Faibussowitsch   PetscCall(PetscFree(vdraw->bounds));
7999566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(2 * nbounds, &vdraw->bounds));
8009566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(vdraw->bounds, bounds, 2 * nbounds));
8015c6c1daeSBarry Smith   PetscFunctionReturn(0);
8025c6c1daeSBarry Smith }
8035c6c1daeSBarry Smith 
8045c6c1daeSBarry Smith /*@C
805811af0c4SBarry Smith     PetscViewerDrawGetBounds - gets the upper and lower bounds to be used in plotting set with `PetscViewerDrawSetBounds()`
8065c6c1daeSBarry Smith 
807811af0c4SBarry Smith     Collective on viewer
8085c6c1daeSBarry Smith 
8095c6c1daeSBarry Smith     Input Parameter:
810811af0c4SBarry Smith .   viewer - the `PetscViewer` (created with `PetscViewerDrawOpen()`)
8115c6c1daeSBarry Smith 
812fd292e60Sprj-     Output Parameters:
813811af0c4SBarry Smith +   nbounds - number of plots that can be made with this viewer, for example the dof passed to `DMDACreate()`
8145c6c1daeSBarry 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, .....
8155c6c1daeSBarry Smith 
8165c6c1daeSBarry Smith     Level: intermediate
8175c6c1daeSBarry Smith 
818811af0c4SBarry Smith .seealso: `PETSCVIEWERDRAW`, `PetscViewerDrawGetLG()`, `PetscViewerDrawGetAxis()`, `PetscViewerDrawOpen()`, `PetscViewerDrawSetBounds()`
8195c6c1daeSBarry Smith @*/
8209371c9d4SSatish Balay PetscErrorCode PetscViewerDrawGetBounds(PetscViewer viewer, PetscInt *nbounds, const PetscReal **bounds) {
821e5ab1681SLisandro Dalcin   PetscViewer_Draw *vdraw;
822e5ab1681SLisandro Dalcin   PetscBool         isdraw;
8235c6c1daeSBarry Smith 
8245c6c1daeSBarry Smith   PetscFunctionBegin;
8255c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
8269566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
8279371c9d4SSatish Balay   if (!isdraw) {
8289371c9d4SSatish Balay     if (nbounds) *nbounds = 0;
8299371c9d4SSatish Balay     if (bounds) *bounds = NULL;
8309371c9d4SSatish Balay     PetscFunctionReturn(0);
8319371c9d4SSatish Balay   }
832e5ab1681SLisandro Dalcin   vdraw = (PetscViewer_Draw *)viewer->data;
833e5ab1681SLisandro Dalcin 
834e5ab1681SLisandro Dalcin   if (nbounds) *nbounds = vdraw->nbounds;
835e5ab1681SLisandro Dalcin   if (bounds) *bounds = vdraw->bounds;
8365c6c1daeSBarry Smith   PetscFunctionReturn(0);
8375c6c1daeSBarry Smith }
838