xref: /petsc/src/sys/classes/viewer/interface/viewreg.c (revision 09222b14142ceaf2171009ab1b8ed257feccc12b)
15c6c1daeSBarry Smith 
2af0996ceSBarry Smith #include <petsc/private/viewerimpl.h> /*I "petscviewer.h" I*/
3e8f14785SLisandro Dalcin #include <petsc/private/hashtable.h>
4e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS)
5e04113cfSBarry Smith   #include <petscviewersaws.h>
6bfb97211SBarry Smith #endif
75c6c1daeSBarry Smith 
802c9f0b5SLisandro Dalcin PetscFunctionList PetscViewerList = NULL;
95c6c1daeSBarry Smith 
109de0f6ecSBarry Smith PetscOptionsHelpPrinted PetscOptionsHelpPrintedSingleton = NULL;
119de0f6ecSBarry Smith KHASH_SET_INIT_STR(HTPrinted)
129de0f6ecSBarry Smith struct _n_PetscOptionsHelpPrinted {
139de0f6ecSBarry Smith   khash_t(HTPrinted) *printed;
149de0f6ecSBarry Smith   PetscSegBuffer      strings;
159de0f6ecSBarry Smith };
169de0f6ecSBarry Smith 
17d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsHelpPrintedDestroy(PetscOptionsHelpPrinted *hp)
18d71ae5a4SJacob Faibussowitsch {
199de0f6ecSBarry Smith   PetscFunctionBegin;
203ba16761SJacob Faibussowitsch   if (!*hp) PetscFunctionReturn(PETSC_SUCCESS);
219de0f6ecSBarry Smith   kh_destroy(HTPrinted, (*hp)->printed);
229566063dSJacob Faibussowitsch   PetscCall(PetscSegBufferDestroy(&(*hp)->strings));
239566063dSJacob Faibussowitsch   PetscCall(PetscFree(*hp));
243ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
259de0f6ecSBarry Smith }
269de0f6ecSBarry Smith 
279de0f6ecSBarry Smith /*@C
289de0f6ecSBarry Smith   PetscOptionsHelpPrintedCreate - Creates an object used to manage tracking which help messages have
299de0f6ecSBarry Smith   been printed so they will not be printed again.
309de0f6ecSBarry Smith 
3110450e9eSJacob Faibussowitsch   Output Parameter:
3210450e9eSJacob Faibussowitsch . hp - the created object
3310450e9eSJacob Faibussowitsch 
3420f4b53cSBarry Smith   Not Collective
359de0f6ecSBarry Smith 
369de0f6ecSBarry Smith   Level: developer
379de0f6ecSBarry Smith 
38db781477SPatrick Sanan .seealso: `PetscOptionsHelpPrintedCheck()`, `PetscOptionsHelpPrintChecked()`
399de0f6ecSBarry Smith @*/
40d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsHelpPrintedCreate(PetscOptionsHelpPrinted *hp)
41d71ae5a4SJacob Faibussowitsch {
429de0f6ecSBarry Smith   PetscFunctionBegin;
439566063dSJacob Faibussowitsch   PetscCall(PetscNew(hp));
449de0f6ecSBarry Smith   (*hp)->printed = kh_init(HTPrinted);
459566063dSJacob Faibussowitsch   PetscCall(PetscSegBufferCreate(sizeof(char), 10000, &(*hp)->strings));
463ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
479de0f6ecSBarry Smith }
489de0f6ecSBarry Smith 
499de0f6ecSBarry Smith /*@C
509de0f6ecSBarry Smith   PetscOptionsHelpPrintedCheck - Checks if a particular pre, name pair has previous been entered (meaning the help message was printed)
519de0f6ecSBarry Smith 
5220f4b53cSBarry Smith   Not Collective
539de0f6ecSBarry Smith 
549de0f6ecSBarry Smith   Input Parameters:
559de0f6ecSBarry Smith + hp   - the object used to manage tracking what help messages have been printed
563f423023SBarry Smith . pre  - the prefix part of the string, many be `NULL`
573f423023SBarry Smith - name - the string to look for (cannot be `NULL`)
589de0f6ecSBarry Smith 
599de0f6ecSBarry Smith   Output Parameter:
603f423023SBarry Smith . found - `PETSC_TRUE` if the string was already set
619de0f6ecSBarry Smith 
629de0f6ecSBarry Smith   Level: intermediate
639de0f6ecSBarry Smith 
64db781477SPatrick Sanan .seealso: `PetscOptionsHelpPrintedCreate()`
659de0f6ecSBarry Smith @*/
66d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsHelpPrintedCheck(PetscOptionsHelpPrinted hp, const char *pre, const char *name, PetscBool *found)
67d71ae5a4SJacob Faibussowitsch {
689de0f6ecSBarry Smith   size_t l1, l2;
69c1449d8eSBarry Smith #if !defined(PETSC_HAVE_THREADSAFETY)
709de0f6ecSBarry Smith   char *both;
71e8f14785SLisandro Dalcin   int   newitem;
72c1449d8eSBarry Smith #endif
739de0f6ecSBarry Smith 
749de0f6ecSBarry Smith   PetscFunctionBegin;
759566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(pre, &l1));
769566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(name, &l2));
779de0f6ecSBarry Smith   if (l1 + l2 == 0) {
789de0f6ecSBarry Smith     *found = PETSC_FALSE;
793ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
809de0f6ecSBarry Smith   }
81c1449d8eSBarry Smith #if !defined(PETSC_HAVE_THREADSAFETY)
82c6a7a370SJeremy L Thompson   size_t lboth = l1 + l2 + 1;
83c6a7a370SJeremy L Thompson   PetscCall(PetscSegBufferGet(hp->strings, lboth, &both));
84c6a7a370SJeremy L Thompson   PetscCall(PetscStrncpy(both, pre, lboth));
85c6a7a370SJeremy L Thompson   PetscCall(PetscStrncpy(both + l1, name, l2 + 1));
869de0f6ecSBarry Smith   kh_put(HTPrinted, hp->printed, both, &newitem);
87c6a7a370SJeremy L Thompson   if (!newitem) PetscCall(PetscSegBufferUnuse(hp->strings, lboth));
889de0f6ecSBarry Smith   *found = newitem ? PETSC_FALSE : PETSC_TRUE;
89c1449d8eSBarry Smith #else
90c1449d8eSBarry Smith   *found = PETSC_FALSE;
91c1449d8eSBarry Smith #endif
923ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9394d6a431SBarry Smith }
9494d6a431SBarry Smith 
95eb55bdffSLawrence Mitchell static PetscBool noviewer = PETSC_FALSE;
96eb55bdffSLawrence Mitchell static PetscBool noviewers[PETSCVIEWERGETVIEWEROFFPUSHESMAX];
97eb55bdffSLawrence Mitchell static PetscInt  inoviewers = 0;
98eb55bdffSLawrence Mitchell 
99eb55bdffSLawrence Mitchell /*@
100811af0c4SBarry Smith   PetscOptionsPushGetViewerOff - sets if a `PetscOptionsGetViewer()` returns a viewer.
101eb55bdffSLawrence Mitchell 
102eb55bdffSLawrence Mitchell   Logically Collective
103eb55bdffSLawrence Mitchell 
104eb55bdffSLawrence Mitchell   Input Parameter:
105811af0c4SBarry Smith . flg - `PETSC_TRUE` to turn off viewer creation, `PETSC_FALSE` to turn it on.
106eb55bdffSLawrence Mitchell 
107eb55bdffSLawrence Mitchell   Level: developer
108eb55bdffSLawrence Mitchell 
109811af0c4SBarry Smith   Note:
110c410d8ccSBarry Smith   Calling `XXXViewFromOptions` in an inner loop can be expensive.  This can appear, for example, when using
111c410d8ccSBarry Smith   many small subsolves.  Call this function to control viewer creation in `PetscOptionsGetViewer()`, thus removing the expensive `XXXViewFromOptions` calls.
112c410d8ccSBarry Smith 
11310450e9eSJacob Faibussowitsch   Developer Notes:
114c410d8ccSBarry Smith   Instead of using this approach, the calls to `PetscOptionsGetViewer()` can be moved into `XXXSetFromOptions()`
115eb55bdffSLawrence Mitchell 
116d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscOptionsGetViewer()`, `PetscOptionsPopGetViewerOff()`
117eb55bdffSLawrence Mitchell @*/
118d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsPushGetViewerOff(PetscBool flg)
119d71ae5a4SJacob Faibussowitsch {
120eb55bdffSLawrence Mitchell   PetscFunctionBegin;
121cc73adaaSBarry Smith   PetscCheck(inoviewers < PETSCVIEWERGETVIEWEROFFPUSHESMAX, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many PetscOptionsPushGetViewerOff(), perhaps you forgot PetscOptionsPopGetViewerOff()?");
122eb55bdffSLawrence Mitchell 
123eb55bdffSLawrence Mitchell   noviewers[inoviewers++] = noviewer;
124eb55bdffSLawrence Mitchell   noviewer                = flg;
1253ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
126eb55bdffSLawrence Mitchell }
127eb55bdffSLawrence Mitchell 
128eb55bdffSLawrence Mitchell /*@
129811af0c4SBarry Smith   PetscOptionsPopGetViewerOff - reset whether `PetscOptionsGetViewer()` returns a viewer.
130eb55bdffSLawrence Mitchell 
131eb55bdffSLawrence Mitchell   Logically Collective
132eb55bdffSLawrence Mitchell 
133eb55bdffSLawrence Mitchell   Level: developer
134eb55bdffSLawrence Mitchell 
135811af0c4SBarry Smith   Note:
136c410d8ccSBarry Smith   See `PetscOptionsPushGetViewerOff()`
137eb55bdffSLawrence Mitchell 
138d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscOptionsGetViewer()`, `PetscOptionsPushGetViewerOff()`
139eb55bdffSLawrence Mitchell @*/
140d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsPopGetViewerOff(void)
141d71ae5a4SJacob Faibussowitsch {
142eb55bdffSLawrence Mitchell   PetscFunctionBegin;
14328b400f6SJacob Faibussowitsch   PetscCheck(inoviewers, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many PetscOptionsPopGetViewerOff(), perhaps you forgot PetscOptionsPushGetViewerOff()?");
144eb55bdffSLawrence Mitchell   noviewer = noviewers[--inoviewers];
1453ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
146eb55bdffSLawrence Mitchell }
147eb55bdffSLawrence Mitchell 
148eb55bdffSLawrence Mitchell /*@
149811af0c4SBarry Smith   PetscOptionsGetViewerOff - does `PetscOptionsGetViewer()` return a viewer?
150eb55bdffSLawrence Mitchell 
151eb55bdffSLawrence Mitchell   Logically Collective
152eb55bdffSLawrence Mitchell 
153eb55bdffSLawrence Mitchell   Output Parameter:
154eb55bdffSLawrence Mitchell . flg - whether viewers are returned.
155eb55bdffSLawrence Mitchell 
156eb55bdffSLawrence Mitchell   Level: developer
157eb55bdffSLawrence Mitchell 
158811af0c4SBarry Smith   Note:
159c410d8ccSBarry Smith   See `PetscOptionsPushGetViewerOff()`
160eb55bdffSLawrence Mitchell 
161d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscOptionsGetViewer()`, `PetscOptionsPushGetViewerOff()`, `PetscOptionsPopGetViewerOff()`
162eb55bdffSLawrence Mitchell @*/
163d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetViewerOff(PetscBool *flg)
164d71ae5a4SJacob Faibussowitsch {
165eb55bdffSLawrence Mitchell   PetscFunctionBegin;
1664f572ea9SToby Isaac   PetscAssertPointer(flg, 1);
167eb55bdffSLawrence Mitchell   *flg = noviewer;
1683ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
169eb55bdffSLawrence Mitchell }
170eb55bdffSLawrence Mitchell 
171*09222b14SToby Isaac static PetscErrorCode PetscOptionsGetViewers_Single(MPI_Comm comm, const char value[], PetscViewer *viewer, PetscViewerFormat *format)
172d71ae5a4SJacob Faibussowitsch {
173*09222b14SToby Isaac   char       *loc0_vtype = NULL, *loc1_fname = NULL, *loc2_fmt = NULL, *loc3_fmode = NULL;
174*09222b14SToby Isaac   PetscInt    cnt;
175*09222b14SToby Isaac   size_t      viewer_string_length;
176*09222b14SToby Isaac   const char *viewers[] = {PETSCVIEWERASCII, PETSCVIEWERBINARY, PETSCVIEWERDRAW, PETSCVIEWERSOCKET, PETSCVIEWERMATLAB, PETSCVIEWERSAWS, PETSCVIEWERVTK, PETSCVIEWERHDF5, PETSCVIEWERGLVIS, PETSCVIEWEREXODUSII, NULL};
1772bf49c77SBarry Smith 
1782bf49c77SBarry Smith   PetscFunctionBegin;
179*09222b14SToby Isaac   PetscCall(PetscStrlen(value, &viewer_string_length));
180*09222b14SToby Isaac   if (!viewer_string_length) {
1816348e711SLisandro Dalcin     if (format) *format = PETSC_VIEWER_DEFAULT;
182bb1d7374SBarry Smith     if (viewer) {
1839566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIGetStdout(comm, viewer));
1849566063dSJacob Faibussowitsch       PetscCall(PetscObjectReference((PetscObject)*viewer));
185bb1d7374SBarry Smith     }
186*09222b14SToby Isaac     PetscFunctionReturn(PETSC_SUCCESS);
187*09222b14SToby Isaac   }
1882bf49c77SBarry Smith 
1899566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(value, &loc0_vtype));
1909566063dSJacob Faibussowitsch   PetscCall(PetscStrchr(loc0_vtype, ':', &loc1_fname));
19135d27ee3SJed Brown   if (loc1_fname) {
19235d27ee3SJed Brown     *loc1_fname++ = 0;
1939566063dSJacob Faibussowitsch     PetscCall(PetscStrchr(loc1_fname, ':', &loc2_fmt));
19435d27ee3SJed Brown   }
19535d27ee3SJed Brown   if (loc2_fmt) {
19635d27ee3SJed Brown     *loc2_fmt++ = 0;
1979566063dSJacob Faibussowitsch     PetscCall(PetscStrchr(loc2_fmt, ':', &loc3_fmode));
19835d27ee3SJed Brown   }
19935d27ee3SJed Brown   if (loc3_fmode) *loc3_fmode++ = 0;
2009566063dSJacob Faibussowitsch   PetscCall(PetscStrendswithwhich(*loc0_vtype ? loc0_vtype : "ascii", viewers, &cnt));
20108401ef6SPierre Jolivet   PetscCheck(cnt <= (PetscInt)sizeof(viewers) - 1, comm, PETSC_ERR_ARG_OUTOFRANGE, "Unknown viewer type: %s", loc0_vtype);
202bb1d7374SBarry Smith   if (viewer) {
20335d27ee3SJed Brown     if (!loc1_fname) {
20443b63833SBarry Smith       switch (cnt) {
205d71ae5a4SJacob Faibussowitsch       case 0:
206d71ae5a4SJacob Faibussowitsch         PetscCall(PetscViewerASCIIGetStdout(comm, viewer));
207d71ae5a4SJacob Faibussowitsch         break;
20843b63833SBarry Smith       case 1:
2099566063dSJacob Faibussowitsch         if (!(*viewer = PETSC_VIEWER_BINARY_(comm))) PetscCall(PETSC_ERR_PLIB);
21043b63833SBarry Smith         break;
21143b63833SBarry Smith       case 2:
2129566063dSJacob Faibussowitsch         if (!(*viewer = PETSC_VIEWER_DRAW_(comm))) PetscCall(PETSC_ERR_PLIB);
21343b63833SBarry Smith         break;
214b58ca069SBarry Smith #if defined(PETSC_USE_SOCKET_VIEWER)
21543b63833SBarry Smith       case 3:
2169566063dSJacob Faibussowitsch         if (!(*viewer = PETSC_VIEWER_SOCKET_(comm))) PetscCall(PETSC_ERR_PLIB);
21743b63833SBarry Smith         break;
218b58ca069SBarry Smith #endif
219d1e78c4fSBarry Smith #if defined(PETSC_HAVE_MATLAB)
22043b63833SBarry Smith       case 4:
2219566063dSJacob Faibussowitsch         if (!(*viewer = PETSC_VIEWER_MATLAB_(comm))) PetscCall(PETSC_ERR_PLIB);
22243b63833SBarry Smith         break;
22343b63833SBarry Smith #endif
224e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS)
225bfb97211SBarry Smith       case 5:
2269566063dSJacob Faibussowitsch         if (!(*viewer = PETSC_VIEWER_SAWS_(comm))) PetscCall(PETSC_ERR_PLIB);
227bfb97211SBarry Smith         break;
228bfb97211SBarry Smith #endif
229a75e6a4aSMatthew G. Knepley #if defined(PETSC_HAVE_HDF5)
230a75e6a4aSMatthew G. Knepley       case 7:
2319566063dSJacob Faibussowitsch         if (!(*viewer = PETSC_VIEWER_HDF5_(comm))) PetscCall(PETSC_ERR_PLIB);
232a75e6a4aSMatthew G. Knepley         break;
233a75e6a4aSMatthew G. Knepley #endif
2348135c375SStefano Zampini       case 8:
2359566063dSJacob Faibussowitsch         if (!(*viewer = PETSC_VIEWER_GLVIS_(comm))) PetscCall(PETSC_ERR_PLIB);
2368135c375SStefano Zampini         break;
2371e50132fSMatthew G. Knepley #if defined(PETSC_HAVE_EXODUSII)
2381e50132fSMatthew G. Knepley       case 9:
2399566063dSJacob Faibussowitsch         if (!(*viewer = PETSC_VIEWER_EXODUSII_(comm))) PetscCall(PETSC_ERR_PLIB);
2401e50132fSMatthew G. Knepley         break;
2411e50132fSMatthew G. Knepley #endif
242d71ae5a4SJacob Faibussowitsch       default:
243*09222b14SToby Isaac         SETERRQ(comm, PETSC_ERR_SUP, "Unsupported viewer %s", loc0_vtype);
2447f677774SBarry Smith       }
2459566063dSJacob Faibussowitsch       PetscCall(PetscObjectReference((PetscObject)*viewer));
2467f677774SBarry Smith     } else {
24735d27ee3SJed Brown       if (loc2_fmt && !*loc1_fname && (cnt == 0)) { /* ASCII format without file name */
2489566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIGetStdout(comm, viewer));
2499566063dSJacob Faibussowitsch         PetscCall(PetscObjectReference((PetscObject)*viewer));
2507f677774SBarry Smith       } else {
2513550efbcSJed Brown         PetscFileMode fmode;
252*09222b14SToby Isaac         PetscBool     flag = PETSC_FALSE;
253*09222b14SToby Isaac 
2549566063dSJacob Faibussowitsch         PetscCall(PetscViewerCreate(comm, viewer));
2559566063dSJacob Faibussowitsch         PetscCall(PetscViewerSetType(*viewer, *loc0_vtype ? loc0_vtype : "ascii"));
2563550efbcSJed Brown         fmode = FILE_MODE_WRITE;
2573550efbcSJed Brown         if (loc3_fmode && *loc3_fmode) { /* Has non-empty file mode ("write" or "append") */
2589566063dSJacob Faibussowitsch           PetscCall(PetscEnumFind(PetscFileModes, loc3_fmode, (PetscEnum *)&fmode, &flag));
25928b400f6SJacob Faibussowitsch           PetscCheck(flag, comm, PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown file mode: %s", loc3_fmode);
2607f677774SBarry Smith         }
261acd7d2deSBarry Smith         if (loc2_fmt) {
2620ecfd9fcSLisandro Dalcin           PetscBool tk, im;
2639566063dSJacob Faibussowitsch           PetscCall(PetscStrcmp(loc1_fname, "tikz", &tk));
2649566063dSJacob Faibussowitsch           PetscCall(PetscStrcmp(loc1_fname, "image", &im));
2650ecfd9fcSLisandro Dalcin           if (tk || im) {
2669566063dSJacob Faibussowitsch             PetscCall(PetscViewerDrawSetInfo(*viewer, NULL, loc2_fmt, PETSC_DECIDE, PETSC_DECIDE, PETSC_DECIDE, PETSC_DECIDE));
267acd7d2deSBarry Smith             *loc2_fmt = 0;
268acd7d2deSBarry Smith           }
269acd7d2deSBarry Smith         }
2709566063dSJacob Faibussowitsch         PetscCall(PetscViewerFileSetMode(*viewer, flag ? fmode : FILE_MODE_WRITE));
2719566063dSJacob Faibussowitsch         PetscCall(PetscViewerFileSetName(*viewer, loc1_fname));
2721baa6e33SBarry Smith         if (*loc1_fname) PetscCall(PetscViewerDrawSetDrawType(*viewer, loc1_fname));
2739566063dSJacob Faibussowitsch         PetscCall(PetscViewerSetFromOptions(*viewer));
27405315717SToby Isaac       }
275bb1d7374SBarry Smith     }
27652f76066SLisandro Dalcin   }
2771baa6e33SBarry Smith   if (viewer) PetscCall(PetscViewerSetUp(*viewer));
27835d27ee3SJed Brown   if (loc2_fmt && *loc2_fmt) {
279e156c29bSStefano Zampini     PetscViewerFormat tfmt;
280*09222b14SToby Isaac     PetscBool         flag;
281d6acdc46SStefano Zampini 
2829566063dSJacob Faibussowitsch     PetscCall(PetscEnumFind(PetscViewerFormats, loc2_fmt, (PetscEnum *)&tfmt, &flag));
283d6acdc46SStefano Zampini     if (format) *format = tfmt;
2846adde796SStefano Zampini     PetscCheck(flag, comm, PETSC_ERR_SUP, "Unknown viewer format %s", loc2_fmt);
285d6acdc46SStefano Zampini   } else if (viewer && (cnt == 6) && format) { /* Get format from VTK viewer */
2869566063dSJacob Faibussowitsch     PetscCall(PetscViewerGetFormat(*viewer, format));
2877f677774SBarry Smith   }
2889566063dSJacob Faibussowitsch   PetscCall(PetscFree(loc0_vtype));
289*09222b14SToby Isaac 
290*09222b14SToby Isaac   PetscFunctionReturn(PETSC_SUCCESS);
291*09222b14SToby Isaac }
292*09222b14SToby Isaac 
293*09222b14SToby Isaac static PetscErrorCode PetscOptionsGetViewers_Internal(MPI_Comm comm, PetscOptions options, const char pre[], const char name[], PetscInt *n_max_p, PetscViewer viewer[], PetscViewerFormat format[], PetscBool *set, const char func_name[], PetscBool allow_multiple)
294*09222b14SToby Isaac {
295*09222b14SToby Isaac   const char *value;
296*09222b14SToby Isaac   PetscBool   flag, hashelp;
297*09222b14SToby Isaac   PetscInt    n_max;
298*09222b14SToby Isaac 
299*09222b14SToby Isaac   PetscFunctionBegin;
300*09222b14SToby Isaac   PetscAssertPointer(name, 4);
301*09222b14SToby Isaac   PetscAssertPointer(n_max_p, 5);
302*09222b14SToby Isaac   n_max = *n_max_p;
303*09222b14SToby Isaac   PetscCheck(n_max >= 0, comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid size %" PetscInt_FMT " of passed arrays", *n_max_p);
304*09222b14SToby Isaac   *n_max_p = 0;
305*09222b14SToby Isaac 
306*09222b14SToby Isaac   if (set) *set = PETSC_FALSE;
307*09222b14SToby Isaac   PetscCall(PetscOptionsGetViewerOff(&flag));
308*09222b14SToby Isaac   if (flag) PetscFunctionReturn(PETSC_SUCCESS);
309*09222b14SToby Isaac 
310*09222b14SToby Isaac   PetscCall(PetscOptionsHasHelp(NULL, &hashelp));
311*09222b14SToby Isaac   if (hashelp) {
312*09222b14SToby Isaac     PetscBool found;
313*09222b14SToby Isaac 
314*09222b14SToby Isaac     if (!PetscOptionsHelpPrintedSingleton) PetscCall(PetscOptionsHelpPrintedCreate(&PetscOptionsHelpPrintedSingleton));
315*09222b14SToby Isaac     PetscCall(PetscOptionsHelpPrintedCheck(PetscOptionsHelpPrintedSingleton, pre, name, &found));
316*09222b14SToby Isaac     if (!found && viewer) {
317*09222b14SToby Isaac       PetscCall((*PetscHelpPrintf)(comm, "----------------------------------------\nViewer (-%s%s) options:\n", pre ? pre : "", name + 1));
318*09222b14SToby Isaac       PetscCall((*PetscHelpPrintf)(comm, "  -%s%s ascii[:[filename][:[format][:append]]]: %s (%s)\n", pre ? pre : "", name + 1, "Prints object to stdout or ASCII file", func_name));
319*09222b14SToby Isaac       PetscCall((*PetscHelpPrintf)(comm, "  -%s%s binary[:[filename][:[format][:append]]]: %s (%s)\n", pre ? pre : "", name + 1, "Saves object to a binary file", func_name));
320*09222b14SToby Isaac       PetscCall((*PetscHelpPrintf)(comm, "  -%s%s draw[:[drawtype][:filename|format]] %s (%s)\n", pre ? pre : "", name + 1, "Draws object", func_name));
321*09222b14SToby Isaac       PetscCall((*PetscHelpPrintf)(comm, "  -%s%s socket[:port]: %s (%s)\n", pre ? pre : "", name + 1, "Pushes object to a Unix socket", func_name));
322*09222b14SToby Isaac       PetscCall((*PetscHelpPrintf)(comm, "  -%s%s saws[:communicatorname]: %s (%s)\n", pre ? pre : "", name + 1, "Publishes object to SAWs", func_name));
323*09222b14SToby Isaac       if (allow_multiple) PetscCall((*PetscHelpPrintf)(comm, "  -%s%s v1[,v2,...]: %s (%s)\n", pre ? pre : "", name + 1, "Multiple viewers", func_name));
3242bf49c77SBarry Smith     }
3252bf49c77SBarry Smith   }
326*09222b14SToby Isaac 
327*09222b14SToby Isaac   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
328*09222b14SToby Isaac   if (flag) {
329*09222b14SToby Isaac     if (set) *set = PETSC_TRUE;
330*09222b14SToby Isaac     if (!value) {
331*09222b14SToby Isaac       PetscCheck(n_max > 0, comm, PETSC_ERR_ARG_SIZ, "More viewers (1) than max available (0)");
332*09222b14SToby Isaac       if (format) *format = PETSC_VIEWER_DEFAULT;
333*09222b14SToby Isaac       if (viewer) {
334*09222b14SToby Isaac         PetscCall(PetscViewerASCIIGetStdout(comm, viewer));
335*09222b14SToby Isaac         PetscCall(PetscObjectReference((PetscObject)*viewer));
336*09222b14SToby Isaac       }
337*09222b14SToby Isaac       *n_max_p = 1;
338*09222b14SToby Isaac     } else {
339*09222b14SToby Isaac       char  *loc0_viewer_string = NULL, *this_viewer_string = NULL;
340*09222b14SToby Isaac       size_t viewer_string_length;
341*09222b14SToby Isaac 
342*09222b14SToby Isaac       PetscCall(PetscStrallocpy(value, &loc0_viewer_string));
343*09222b14SToby Isaac       PetscCall(PetscStrlen(loc0_viewer_string, &viewer_string_length));
344*09222b14SToby Isaac       this_viewer_string = loc0_viewer_string;
345*09222b14SToby Isaac 
346*09222b14SToby Isaac       do {
347*09222b14SToby Isaac         PetscViewer       *this_viewer;
348*09222b14SToby Isaac         PetscViewerFormat *this_viewer_format;
349*09222b14SToby Isaac         char              *next_viewer_string = NULL;
350*09222b14SToby Isaac         char              *comma_separator    = NULL;
351*09222b14SToby Isaac         PetscInt           n                  = *n_max_p;
352*09222b14SToby Isaac 
353*09222b14SToby Isaac         PetscCheck(n < n_max, comm, PETSC_ERR_PLIB, "More viewers than max available (%d)", (int)n_max);
354*09222b14SToby Isaac 
355*09222b14SToby Isaac         PetscCall(PetscStrchr(this_viewer_string, ',', &comma_separator));
356*09222b14SToby Isaac         if (comma_separator) {
357*09222b14SToby Isaac           PetscCheck(allow_multiple, comm, PETSC_ERR_ARG_OUTOFRANGE, "Trying to pass multiple viewers to %s: only one allowed.  Use PetscOptionsGetViewers() instead", func_name);
358*09222b14SToby Isaac           *comma_separator   = 0;
359*09222b14SToby Isaac           next_viewer_string = comma_separator + 1;
360*09222b14SToby Isaac         }
361*09222b14SToby Isaac         this_viewer = viewer ? &viewer[n] : NULL;
362*09222b14SToby Isaac         if (this_viewer) *this_viewer = NULL;
363*09222b14SToby Isaac         this_viewer_format = format ? &format[n] : NULL;
364*09222b14SToby Isaac         if (this_viewer_format) *this_viewer_format = PETSC_VIEWER_DEFAULT;
365*09222b14SToby Isaac         PetscCall(PetscOptionsGetViewers_Single(comm, this_viewer_string, this_viewer, this_viewer_format));
366*09222b14SToby Isaac         this_viewer_string = next_viewer_string;
367*09222b14SToby Isaac         (*n_max_p)++;
368*09222b14SToby Isaac       } while (this_viewer_string);
369*09222b14SToby Isaac       PetscCall(PetscFree(loc0_viewer_string));
370*09222b14SToby Isaac     }
371*09222b14SToby Isaac   }
372*09222b14SToby Isaac   PetscFunctionReturn(PETSC_SUCCESS);
373*09222b14SToby Isaac }
374*09222b14SToby Isaac 
375*09222b14SToby Isaac /*@C
376*09222b14SToby Isaac   PetscOptionsGetViewer - Gets a viewer appropriate for the type indicated by the user
377*09222b14SToby Isaac 
378*09222b14SToby Isaac   Collective
379*09222b14SToby Isaac 
380*09222b14SToby Isaac   Input Parameters:
381*09222b14SToby Isaac + comm    - the communicator to own the viewer
382*09222b14SToby Isaac . options - options database, use `NULL` for default global database
383*09222b14SToby Isaac . pre     - the string to prepend to the name or `NULL`
384*09222b14SToby Isaac - name    - the option one is seeking
385*09222b14SToby Isaac 
386*09222b14SToby Isaac   Output Parameters:
387*09222b14SToby Isaac + viewer - the viewer, pass `NULL` if not needed
388*09222b14SToby Isaac . format - the `PetscViewerFormat` requested by the user, pass `NULL` if not needed
389*09222b14SToby Isaac - set    - `PETSC_TRUE` if found, else `PETSC_FALSE`
390*09222b14SToby Isaac 
391*09222b14SToby Isaac   Level: intermediate
392*09222b14SToby Isaac 
393*09222b14SToby Isaac   Notes:
394*09222b14SToby Isaac   If no value is provided ascii:stdout is used
395*09222b14SToby Isaac +       ascii[:[filename][:[format][:append]]]  -  defaults to stdout - format can be one of ascii_info, ascii_info_detail, or ascii_matlab,
396*09222b14SToby Isaac   for example ascii::ascii_info prints just the information about the object not all details
397*09222b14SToby Isaac   unless :append is given filename opens in write mode, overwriting what was already there
398*09222b14SToby Isaac .       binary[:[filename][:[format][:append]]] -  defaults to the file binaryoutput
399*09222b14SToby Isaac .       draw[:drawtype[:filename]]              -  for example, draw:tikz, draw:tikz:figure.tex  or draw:x
400*09222b14SToby Isaac .       socket[:port]                           -  defaults to the standard output port
401*09222b14SToby Isaac -       saws[:communicatorname]                 -   publishes object to the Scientific Application Webserver (SAWs)
402*09222b14SToby Isaac 
403*09222b14SToby Isaac   Use `PetscViewerDestroy()` after using the viewer, otherwise a memory leak will occur
404*09222b14SToby Isaac 
405*09222b14SToby Isaac   You can control whether calls to this function create a viewer (or return early with *set of `PETSC_FALSE`) with
406*09222b14SToby Isaac   `PetscOptionsPushGetViewerOff()`.  This is useful if calling many small subsolves, in which case XXXViewFromOptions can take
407*09222b14SToby Isaac   an appreciable fraction of the runtime.
408*09222b14SToby Isaac 
409*09222b14SToby Isaac   If PETSc is configured with `--with-viewfromoptions=0` this function always returns with *set of `PETSC_FALSE`
410*09222b14SToby Isaac 
411*09222b14SToby Isaac .seealso: [](sec_viewers), `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
412*09222b14SToby Isaac           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
413*09222b14SToby Isaac           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`,
414*09222b14SToby Isaac           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
415*09222b14SToby Isaac           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
416*09222b14SToby Isaac           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
417*09222b14SToby Isaac           `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsPushGetViewerOff()`, `PetscOptionsPopGetViewerOff()`,
418*09222b14SToby Isaac           `PetscOptionsGetViewerOff()`
419*09222b14SToby Isaac @*/
420*09222b14SToby Isaac PetscErrorCode PetscOptionsGetViewer(MPI_Comm comm, PetscOptions options, const char pre[], const char name[], PetscViewer *viewer, PetscViewerFormat *format, PetscBool *set)
421*09222b14SToby Isaac {
422*09222b14SToby Isaac   PetscInt  n_max = 1;
423*09222b14SToby Isaac   PetscBool set_internal;
424*09222b14SToby Isaac 
425*09222b14SToby Isaac   PetscFunctionBegin;
426*09222b14SToby Isaac   if (viewer) *viewer = NULL;
427*09222b14SToby Isaac   if (format) *format = PETSC_VIEWER_DEFAULT;
428*09222b14SToby Isaac   PetscCall(PetscOptionsGetViewers_Internal(comm, options, pre, name, &n_max, viewer, format, &set_internal, PETSC_FUNCTION_NAME, PETSC_FALSE));
429*09222b14SToby Isaac   if (set_internal) PetscAssert(n_max == 1, comm, PETSC_ERR_PLIB, "Unexpected: %d != 1 viewers set", (int)n_max);
430*09222b14SToby Isaac   if (set) *set = set_internal;
431*09222b14SToby Isaac   PetscFunctionReturn(PETSC_SUCCESS);
432*09222b14SToby Isaac }
433*09222b14SToby Isaac 
434*09222b14SToby Isaac /*@C
435*09222b14SToby Isaac    PetscOptionsGetViewers - Get multiple viewers from a comma-separated list in the options database
436*09222b14SToby Isaac 
437*09222b14SToby Isaac    Collective
438*09222b14SToby Isaac 
439*09222b14SToby Isaac    Input Parameters:
440*09222b14SToby Isaac +  comm    - the communicator to own the viewer
441*09222b14SToby Isaac .  options - options database, use `NULL` for default global database
442*09222b14SToby Isaac .  pre     - the string to prepend to the name or `NULL`
443*09222b14SToby Isaac .  name    - the option one is seeking
444*09222b14SToby Isaac -  n_max   - on input: the maximum number of viewers; on output: the number of viewers in the comma-separated list
445*09222b14SToby Isaac 
446*09222b14SToby Isaac    Output Parameters:
447*09222b14SToby Isaac +  viewers - an array to hold at least `n_max` `PetscViewer`s, or `NULL` if not needed; on output: if not `NULL`, the
448*09222b14SToby Isaac              first `n_max` entries are initialized `PetscViewer`s
449*09222b14SToby Isaac .  formats - an array to hold at least `n_max` `PetscViewerFormat`s, or `NULL` if not needed; on output: if not
450*09222b14SToby Isaac              `NULL`, the first `n_max` entries are valid `PetscViewewFormat`s
451*09222b14SToby Isaac -  set     - `PETSC_TRUE` if found, else `PETSC_FALSE`
452*09222b14SToby Isaac 
453*09222b14SToby Isaac    Level: intermediate
454*09222b14SToby Isaac 
455*09222b14SToby Isaac    Note:
456*09222b14SToby Isaac    See `PetscOptionsGetViewer()` for how the format strings for the viewers are interpreted.  Use `PetscViewerDestroy()` on each viewer, otherwise a memory leak will occur.
457*09222b14SToby Isaac 
458*09222b14SToby Isaac    If PETSc is configured with `--with-viewfromoptions=0` this function always returns with `n_max` of 0 and `set` of `PETSC_FALSE`
459*09222b14SToby Isaac 
460*09222b14SToby Isaac .seealso: [](sec_viewers), `PetscOptionsGetViewer()`
461*09222b14SToby Isaac @*/
462*09222b14SToby Isaac PetscErrorCode PetscOptionsGetViewers(MPI_Comm comm, PetscOptions options, const char pre[], const char name[], PetscInt *n_max, PetscViewer viewers[], PetscViewerFormat formats[], PetscBool *set)
463*09222b14SToby Isaac {
464*09222b14SToby Isaac   PetscFunctionBegin;
465*09222b14SToby Isaac   PetscCall(PetscOptionsGetViewers_Internal(comm, options, pre, name, n_max, viewers, formats, set, PETSC_FUNCTION_NAME, PETSC_TRUE));
4663ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4672bf49c77SBarry Smith }
4682bf49c77SBarry Smith 
4695c6c1daeSBarry Smith /*@
470c410d8ccSBarry Smith   PetscViewerCreate - Creates a viewing context. A `PetscViewer` represents a file, a graphical window, a Unix socket or a variety of other ways
471c410d8ccSBarry Smith   of viewing a PETSc object
4725c6c1daeSBarry Smith 
473d083f849SBarry Smith   Collective
4745c6c1daeSBarry Smith 
4755c6c1daeSBarry Smith   Input Parameter:
4765c6c1daeSBarry Smith . comm - MPI communicator
4775c6c1daeSBarry Smith 
4785c6c1daeSBarry Smith   Output Parameter:
479811af0c4SBarry Smith . inviewer - location to put the `PetscViewer` context
4805c6c1daeSBarry Smith 
4815c6c1daeSBarry Smith   Level: advanced
4825c6c1daeSBarry Smith 
483d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerType`
4845c6c1daeSBarry Smith @*/
485d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerCreate(MPI_Comm comm, PetscViewer *inviewer)
486d71ae5a4SJacob Faibussowitsch {
4875c6c1daeSBarry Smith   PetscViewer viewer;
4885c6c1daeSBarry Smith 
4895c6c1daeSBarry Smith   PetscFunctionBegin;
49002c9f0b5SLisandro Dalcin   *inviewer = NULL;
4919566063dSJacob Faibussowitsch   PetscCall(PetscViewerInitializePackage());
4929566063dSJacob Faibussowitsch   PetscCall(PetscHeaderCreate(viewer, PETSC_VIEWER_CLASSID, "PetscViewer", "PetscViewer", "Viewer", comm, PetscViewerDestroy, PetscViewerView));
4935c6c1daeSBarry Smith   *inviewer    = viewer;
49402c9f0b5SLisandro Dalcin   viewer->data = NULL;
4953ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4965c6c1daeSBarry Smith }
4975c6c1daeSBarry Smith 
4985c6c1daeSBarry Smith /*@C
499811af0c4SBarry Smith   PetscViewerSetType - Builds `PetscViewer` for a particular implementation.
5005c6c1daeSBarry Smith 
501c3339decSBarry Smith   Collective
5025c6c1daeSBarry Smith 
503d8d19677SJose E. Roman   Input Parameters:
504811af0c4SBarry Smith + viewer - the `PetscViewer` context obtained with `PetscViewerCreate()`
505811af0c4SBarry Smith - type   - for example, `PETSCVIEWERASCII`
5065c6c1daeSBarry Smith 
5073c7db156SBarry Smith   Options Database Key:
5083c7db156SBarry Smith . -viewer_type  <type> - Sets the type; use -help for a list of available methods (for instance, ascii)
5095c6c1daeSBarry Smith 
5105c6c1daeSBarry Smith   Level: advanced
5115c6c1daeSBarry Smith 
512811af0c4SBarry Smith   Note:
5133f423023SBarry Smith   See `PetscViewerType` for possible values
5145c6c1daeSBarry Smith 
515d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerCreate()`, `PetscViewerGetType()`, `PetscViewerType`, `PetscViewerPushFormat()`
5165c6c1daeSBarry Smith @*/
517d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerSetType(PetscViewer viewer, PetscViewerType type)
518d71ae5a4SJacob Faibussowitsch {
5195c6c1daeSBarry Smith   PetscBool match;
5205f80ce2aSJacob Faibussowitsch   PetscErrorCode (*r)(PetscViewer);
5215c6c1daeSBarry Smith 
5225c6c1daeSBarry Smith   PetscFunctionBegin;
5235c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
5244f572ea9SToby Isaac   PetscAssertPointer(type, 2);
5259566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, type, &match));
5263ba16761SJacob Faibussowitsch   if (match) PetscFunctionReturn(PETSC_SUCCESS);
5275c6c1daeSBarry Smith 
5285c6c1daeSBarry Smith   /* cleanup any old type that may be there */
529dbbe0bcdSBarry Smith   PetscTryTypeMethod(viewer, destroy);
5300298fd71SBarry Smith   viewer->ops->destroy = NULL;
53102c9f0b5SLisandro Dalcin   viewer->data         = NULL;
532dbbe0bcdSBarry Smith 
5339566063dSJacob Faibussowitsch   PetscCall(PetscMemzero(viewer->ops, sizeof(struct _PetscViewerOps)));
5345c6c1daeSBarry Smith 
5359566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListFind(PetscViewerList, type, &r));
5366adde796SStefano Zampini   PetscCheck(r, PetscObjectComm((PetscObject)viewer), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscViewer type given: %s", type);
5375c6c1daeSBarry Smith 
5389566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)viewer, type));
5399566063dSJacob Faibussowitsch   PetscCall((*r)(viewer));
5403ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5415c6c1daeSBarry Smith }
5425c6c1daeSBarry Smith 
5431c84c290SBarry Smith /*@C
544c410d8ccSBarry Smith   PetscViewerRegister - Adds a viewer to those available for use with `PetscViewerSetType()`
5451c84c290SBarry Smith 
5461c84c290SBarry Smith   Not Collective
5471c84c290SBarry Smith 
5481c84c290SBarry Smith   Input Parameters:
5492fe279fdSBarry Smith + sname    - name of a new user-defined viewer
5502fe279fdSBarry Smith - function - routine to create method context
5511c84c290SBarry Smith 
5521c84c290SBarry Smith   Level: developer
553811af0c4SBarry Smith 
554811af0c4SBarry Smith   Note:
555811af0c4SBarry Smith   `PetscViewerRegister()` may be called multiple times to add several user-defined viewers.
5561c84c290SBarry Smith 
557aec76313SJacob Faibussowitsch   Example Usage:
5581c84c290SBarry Smith .vb
559bdf89e91SBarry Smith    PetscViewerRegister("my_viewer_type", MyViewerCreate);
5601c84c290SBarry Smith .ve
5611c84c290SBarry Smith 
5621c84c290SBarry Smith   Then, your solver can be chosen with the procedural interface via
5631c84c290SBarry Smith $     PetscViewerSetType(viewer, "my_viewer_type")
5641c84c290SBarry Smith   or at runtime via the option
5651c84c290SBarry Smith $     -viewer_type my_viewer_type
5661c84c290SBarry Smith 
567d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscViewerRegisterAll()`
5681c84c290SBarry Smith  @*/
569d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerRegister(const char *sname, PetscErrorCode (*function)(PetscViewer))
570d71ae5a4SJacob Faibussowitsch {
5715c6c1daeSBarry Smith   PetscFunctionBegin;
5729566063dSJacob Faibussowitsch   PetscCall(PetscViewerInitializePackage());
5739566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListAdd(&PetscViewerList, sname, function));
5743ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5755c6c1daeSBarry Smith }
5765c6c1daeSBarry Smith 
5775c6c1daeSBarry Smith /*@C
5783f423023SBarry Smith   PetscViewerSetFromOptions - Sets various options for a viewer based on values in the options database.
5795c6c1daeSBarry Smith 
580c3339decSBarry Smith   Collective
5815c6c1daeSBarry Smith 
5825c6c1daeSBarry Smith   Input Parameter:
583811af0c4SBarry Smith . viewer - the viewer context
5845c6c1daeSBarry Smith 
5855c6c1daeSBarry Smith   Level: intermediate
5865c6c1daeSBarry Smith 
587811af0c4SBarry Smith   Note:
588c410d8ccSBarry Smith   Must be called after `PetscViewerCreate()` but before the `PetscViewer` is used.
5895c6c1daeSBarry Smith 
590d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerCreate()`, `PetscViewerSetType()`, `PetscViewerType`
5915c6c1daeSBarry Smith @*/
592d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerSetFromOptions(PetscViewer viewer)
593d71ae5a4SJacob Faibussowitsch {
5945c6c1daeSBarry Smith   char      vtype[256];
5955c6c1daeSBarry Smith   PetscBool flg;
5965c6c1daeSBarry Smith 
5975c6c1daeSBarry Smith   PetscFunctionBegin;
5985c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
5995c6c1daeSBarry Smith 
60048a46eb9SPierre Jolivet   if (!PetscViewerList) PetscCall(PetscViewerRegisterAll());
601d0609cedSBarry Smith   PetscObjectOptionsBegin((PetscObject)viewer);
6029566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFList("-viewer_type", "Type of PetscViewer", "None", PetscViewerList, (char *)(((PetscObject)viewer)->type_name ? ((PetscObject)viewer)->type_name : PETSCVIEWERASCII), vtype, 256, &flg));
6031baa6e33SBarry Smith   if (flg) PetscCall(PetscViewerSetType(viewer, vtype));
6045c6c1daeSBarry Smith   /* type has not been set? */
60548a46eb9SPierre Jolivet   if (!((PetscObject)viewer)->type_name) PetscCall(PetscViewerSetType(viewer, PETSCVIEWERASCII));
606dbbe0bcdSBarry Smith   PetscTryTypeMethod(viewer, setfromoptions, PetscOptionsObject);
6075c6c1daeSBarry Smith 
6085c6c1daeSBarry Smith   /* process any options handlers added with PetscObjectAddOptionsHandler() */
609dbbe0bcdSBarry Smith   PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)viewer, PetscOptionsObject));
6109566063dSJacob Faibussowitsch   PetscCall(PetscViewerViewFromOptions(viewer, NULL, "-viewer_view"));
611d0609cedSBarry Smith   PetscOptionsEnd();
6123ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6135c6c1daeSBarry Smith }
614816f7b76SBarry Smith 
615d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerFlowControlStart(PetscViewer viewer, PetscInt *mcnt, PetscInt *cnt)
616d71ae5a4SJacob Faibussowitsch {
617816f7b76SBarry Smith   PetscFunctionBegin;
6189566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryGetFlowControl(viewer, mcnt));
6199566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryGetFlowControl(viewer, cnt));
6203ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
621816f7b76SBarry Smith }
622816f7b76SBarry Smith 
623d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerFlowControlStepMain(PetscViewer viewer, PetscInt i, PetscInt *mcnt, PetscInt cnt)
624d71ae5a4SJacob Faibussowitsch {
625816f7b76SBarry Smith   MPI_Comm comm;
626816f7b76SBarry Smith 
627816f7b76SBarry Smith   PetscFunctionBegin;
6289566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
629816f7b76SBarry Smith   if (i >= *mcnt) {
630816f7b76SBarry Smith     *mcnt += cnt;
6319566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Bcast(mcnt, 1, MPIU_INT, 0, comm));
632816f7b76SBarry Smith   }
6333ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
634816f7b76SBarry Smith }
635816f7b76SBarry Smith 
636d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerFlowControlEndMain(PetscViewer viewer, PetscInt *mcnt)
637d71ae5a4SJacob Faibussowitsch {
638816f7b76SBarry Smith   MPI_Comm comm;
639816f7b76SBarry Smith   PetscFunctionBegin;
6409566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
641816f7b76SBarry Smith   *mcnt = 0;
6429566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Bcast(mcnt, 1, MPIU_INT, 0, comm));
6433ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
644816f7b76SBarry Smith }
645816f7b76SBarry Smith 
646d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerFlowControlStepWorker(PetscViewer viewer, PetscMPIInt rank, PetscInt *mcnt)
647d71ae5a4SJacob Faibussowitsch {
648816f7b76SBarry Smith   MPI_Comm comm;
649816f7b76SBarry Smith   PetscFunctionBegin;
6509566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
651816f7b76SBarry Smith   while (PETSC_TRUE) {
652816f7b76SBarry Smith     if (rank < *mcnt) break;
6539566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Bcast(mcnt, 1, MPIU_INT, 0, comm));
654816f7b76SBarry Smith   }
6553ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
656816f7b76SBarry Smith }
657816f7b76SBarry Smith 
658d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerFlowControlEndWorker(PetscViewer viewer, PetscInt *mcnt)
659d71ae5a4SJacob Faibussowitsch {
660816f7b76SBarry Smith   MPI_Comm comm;
661816f7b76SBarry Smith   PetscFunctionBegin;
6629566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
663816f7b76SBarry Smith   while (PETSC_TRUE) {
6649566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Bcast(mcnt, 1, MPIU_INT, 0, comm));
665816f7b76SBarry Smith     if (!*mcnt) break;
666816f7b76SBarry Smith   }
6673ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
668816f7b76SBarry Smith }
669