xref: /petsc/src/sys/classes/viewer/interface/viewreg.c (revision 10450e9e44b354a0a3da7bbd573407bdf051df10)
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 
31*10450e9eSJacob Faibussowitsch   Output Parameter:
32*10450e9eSJacob Faibussowitsch . hp - the created object
33*10450e9eSJacob 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 
113*10450e9eSJacob 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;
166534a8f05SLisandro Dalcin   PetscValidBoolPointer(flg, 1);
167eb55bdffSLawrence Mitchell   *flg = noviewer;
1683ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
169eb55bdffSLawrence Mitchell }
170eb55bdffSLawrence Mitchell 
1712bf49c77SBarry Smith /*@C
1722bf49c77SBarry Smith   PetscOptionsGetViewer - Gets a viewer appropriate for the type indicated by the user
1732bf49c77SBarry Smith 
174d083f849SBarry Smith   Collective
1752bf49c77SBarry Smith 
1762bf49c77SBarry Smith   Input Parameters:
1772bf49c77SBarry Smith + comm    - the communicator to own the viewer
1783f423023SBarry Smith . options - options database, use `NULL` for default global database
1793f423023SBarry Smith . pre     - the string to prepend to the name or `NULL`
1802bf49c77SBarry Smith - name    - the option one is seeking
1812bf49c77SBarry Smith 
182d8d19677SJose E. Roman   Output Parameters:
1833f423023SBarry Smith + viewer - the viewer, pass `NULL` if not needed
1843f423023SBarry Smith . format - the `PetscViewerFormat` requested by the user, pass `NULL` if not needed
185811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, else `PETSC_FALSE`
1862bf49c77SBarry Smith 
1872bf49c77SBarry Smith   Level: intermediate
1882bf49c77SBarry Smith 
18995452b02SPatrick Sanan   Notes:
19095452b02SPatrick Sanan   If no value is provided ascii:stdout is used
191811af0c4SBarry Smith +       ascii[:[filename][:[format][:append]]]  -  defaults to stdout - format can be one of ascii_info, ascii_info_detail, or ascii_matlab,
192d1da0b69SBarry Smith   for example ascii::ascii_info prints just the information about the object not all details
193d1da0b69SBarry Smith   unless :append is given filename opens in write mode, overwriting what was already there
194811af0c4SBarry Smith .       binary[:[filename][:[format][:append]]] -  defaults to the file binaryoutput
195811af0c4SBarry Smith .       draw[:drawtype[:filename]]              -  for example, draw:tikz, draw:tikz:figure.tex  or draw:x
196811af0c4SBarry Smith .       socket[:port]                           -  defaults to the standard output port
197811af0c4SBarry Smith -       saws[:communicatorname]                 -   publishes object to the Scientific Application Webserver (SAWs)
1982bf49c77SBarry Smith 
199811af0c4SBarry Smith   Use `PetscViewerDestroy()` after using the viewer, otherwise a memory leak will occur
2002bf49c77SBarry Smith 
201811af0c4SBarry Smith   You can control whether calls to this function create a viewer (or return early with *set of `PETSC_FALSE`) with
202811af0c4SBarry Smith   `PetscOptionsPushGetViewerOff()`.  This is useful if calling many small subsolves, in which case XXXViewFromOptions can take
203eb55bdffSLawrence Mitchell   an appreciable fraction of the runtime.
204eb55bdffSLawrence Mitchell 
2053f423023SBarry Smith   If PETSc is configured with `--with-viewfromoptions=0` this function always returns with *set of `PETSC_FALSE`
20627b0f280SBarry Smith 
207d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
208db781477SPatrick Sanan           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
209aec76313SJacob Faibussowitsch           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`,
210db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
211c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
212db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
213db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsPushGetViewerOff()`, `PetscOptionsPopGetViewerOff()`,
214db781477SPatrick Sanan           `PetscOptionsGetViewerOff()`
2152bf49c77SBarry Smith @*/
216d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetViewer(MPI_Comm comm, PetscOptions options, const char pre[], const char name[], PetscViewer *viewer, PetscViewerFormat *format, PetscBool *set)
217d71ae5a4SJacob Faibussowitsch {
2182d747510SLisandro Dalcin   const char *value;
21920610d12SBarry Smith   PetscBool   flag, hashelp;
2202bf49c77SBarry Smith 
2212bf49c77SBarry Smith   PetscFunctionBegin;
222064a246eSJacob Faibussowitsch   PetscValidCharPointer(name, 4);
2232bf49c77SBarry Smith 
2246348e711SLisandro Dalcin   if (viewer) *viewer = NULL;
2256348e711SLisandro Dalcin   if (format) *format = PETSC_VIEWER_DEFAULT;
22627b0f280SBarry Smith   if (set) *set = PETSC_FALSE;
2279566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetViewerOff(&flag));
2283ba16761SJacob Faibussowitsch   if (flag) PetscFunctionReturn(PETSC_SUCCESS);
22927b0f280SBarry Smith 
2309566063dSJacob Faibussowitsch   PetscCall(PetscOptionsHasHelp(NULL, &hashelp));
23120610d12SBarry Smith   if (hashelp) {
2329de0f6ecSBarry Smith     PetscBool found;
2339af95d99SBarry Smith 
23448a46eb9SPierre Jolivet     if (!PetscOptionsHelpPrintedSingleton) PetscCall(PetscOptionsHelpPrintedCreate(&PetscOptionsHelpPrintedSingleton));
2359566063dSJacob Faibussowitsch     PetscCall(PetscOptionsHelpPrintedCheck(PetscOptionsHelpPrintedSingleton, pre, name, &found));
23656071f75SVaclav Hapla     if (!found && viewer) {
2379566063dSJacob Faibussowitsch       PetscCall((*PetscHelpPrintf)(comm, "----------------------------------------\nViewer (-%s%s) options:\n", pre ? pre : "", name + 1));
2389566063dSJacob Faibussowitsch       PetscCall((*PetscHelpPrintf)(comm, "  -%s%s ascii[:[filename][:[format][:append]]]: %s (%s)\n", pre ? pre : "", name + 1, "Prints object to stdout or ASCII file", "PetscOptionsGetViewer"));
2399566063dSJacob Faibussowitsch       PetscCall((*PetscHelpPrintf)(comm, "  -%s%s binary[:[filename][:[format][:append]]]: %s (%s)\n", pre ? pre : "", name + 1, "Saves object to a binary file", "PetscOptionsGetViewer"));
2409566063dSJacob Faibussowitsch       PetscCall((*PetscHelpPrintf)(comm, "  -%s%s draw[:[drawtype][:filename|format]] %s (%s)\n", pre ? pre : "", name + 1, "Draws object", "PetscOptionsGetViewer"));
2419566063dSJacob Faibussowitsch       PetscCall((*PetscHelpPrintf)(comm, "  -%s%s socket[:port]: %s (%s)\n", pre ? pre : "", name + 1, "Pushes object to a Unix socket", "PetscOptionsGetViewer"));
2429566063dSJacob Faibussowitsch       PetscCall((*PetscHelpPrintf)(comm, "  -%s%s saws[:communicatorname]: %s (%s)\n", pre ? pre : "", name + 1, "Publishes object to SAWs", "PetscOptionsGetViewer"));
24394d6a431SBarry Smith     }
24420610d12SBarry Smith   }
245685405a1SBarry Smith 
246e3f3e4b6SBarry Smith   if (format) *format = PETSC_VIEWER_DEFAULT;
2479566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2482bf49c77SBarry Smith   if (flag) {
2492bf49c77SBarry Smith     if (set) *set = PETSC_TRUE;
2502bf49c77SBarry Smith     if (!value) {
251bb1d7374SBarry Smith       if (viewer) {
2529566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIGetStdout(comm, viewer));
2539566063dSJacob Faibussowitsch         PetscCall(PetscObjectReference((PetscObject)*viewer));
254bb1d7374SBarry Smith       }
2552bf49c77SBarry Smith     } else {
256bbcf679cSJacob Faibussowitsch       char       *loc0_vtype = NULL, *loc1_fname = NULL, *loc2_fmt = NULL, *loc3_fmode = NULL;
2572bf49c77SBarry Smith       PetscInt    cnt;
2581e50132fSMatthew G. Knepley       const char *viewers[] = {PETSCVIEWERASCII, PETSCVIEWERBINARY, PETSCVIEWERDRAW, PETSCVIEWERSOCKET, PETSCVIEWERMATLAB, PETSCVIEWERSAWS, PETSCVIEWERVTK, PETSCVIEWERHDF5, PETSCVIEWERGLVIS, PETSCVIEWEREXODUSII, NULL};
2592bf49c77SBarry Smith 
2609566063dSJacob Faibussowitsch       PetscCall(PetscStrallocpy(value, &loc0_vtype));
2619566063dSJacob Faibussowitsch       PetscCall(PetscStrchr(loc0_vtype, ':', &loc1_fname));
26235d27ee3SJed Brown       if (loc1_fname) {
26335d27ee3SJed Brown         *loc1_fname++ = 0;
2649566063dSJacob Faibussowitsch         PetscCall(PetscStrchr(loc1_fname, ':', &loc2_fmt));
26535d27ee3SJed Brown       }
26635d27ee3SJed Brown       if (loc2_fmt) {
26735d27ee3SJed Brown         *loc2_fmt++ = 0;
2689566063dSJacob Faibussowitsch         PetscCall(PetscStrchr(loc2_fmt, ':', &loc3_fmode));
26935d27ee3SJed Brown       }
27035d27ee3SJed Brown       if (loc3_fmode) *loc3_fmode++ = 0;
2719566063dSJacob Faibussowitsch       PetscCall(PetscStrendswithwhich(*loc0_vtype ? loc0_vtype : "ascii", viewers, &cnt));
27208401ef6SPierre Jolivet       PetscCheck(cnt <= (PetscInt)sizeof(viewers) - 1, comm, PETSC_ERR_ARG_OUTOFRANGE, "Unknown viewer type: %s", loc0_vtype);
273bb1d7374SBarry Smith       if (viewer) {
27435d27ee3SJed Brown         if (!loc1_fname) {
27543b63833SBarry Smith           switch (cnt) {
276d71ae5a4SJacob Faibussowitsch           case 0:
277d71ae5a4SJacob Faibussowitsch             PetscCall(PetscViewerASCIIGetStdout(comm, viewer));
278d71ae5a4SJacob Faibussowitsch             break;
27943b63833SBarry Smith           case 1:
2809566063dSJacob Faibussowitsch             if (!(*viewer = PETSC_VIEWER_BINARY_(comm))) PetscCall(PETSC_ERR_PLIB);
28143b63833SBarry Smith             break;
28243b63833SBarry Smith           case 2:
2839566063dSJacob Faibussowitsch             if (!(*viewer = PETSC_VIEWER_DRAW_(comm))) PetscCall(PETSC_ERR_PLIB);
28443b63833SBarry Smith             break;
285b58ca069SBarry Smith #if defined(PETSC_USE_SOCKET_VIEWER)
28643b63833SBarry Smith           case 3:
2879566063dSJacob Faibussowitsch             if (!(*viewer = PETSC_VIEWER_SOCKET_(comm))) PetscCall(PETSC_ERR_PLIB);
28843b63833SBarry Smith             break;
289b58ca069SBarry Smith #endif
290d1e78c4fSBarry Smith #if defined(PETSC_HAVE_MATLAB)
29143b63833SBarry Smith           case 4:
2929566063dSJacob Faibussowitsch             if (!(*viewer = PETSC_VIEWER_MATLAB_(comm))) PetscCall(PETSC_ERR_PLIB);
29343b63833SBarry Smith             break;
29443b63833SBarry Smith #endif
295e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS)
296bfb97211SBarry Smith           case 5:
2979566063dSJacob Faibussowitsch             if (!(*viewer = PETSC_VIEWER_SAWS_(comm))) PetscCall(PETSC_ERR_PLIB);
298bfb97211SBarry Smith             break;
299bfb97211SBarry Smith #endif
300a75e6a4aSMatthew G. Knepley #if defined(PETSC_HAVE_HDF5)
301a75e6a4aSMatthew G. Knepley           case 7:
3029566063dSJacob Faibussowitsch             if (!(*viewer = PETSC_VIEWER_HDF5_(comm))) PetscCall(PETSC_ERR_PLIB);
303a75e6a4aSMatthew G. Knepley             break;
304a75e6a4aSMatthew G. Knepley #endif
3058135c375SStefano Zampini           case 8:
3069566063dSJacob Faibussowitsch             if (!(*viewer = PETSC_VIEWER_GLVIS_(comm))) PetscCall(PETSC_ERR_PLIB);
3078135c375SStefano Zampini             break;
3081e50132fSMatthew G. Knepley #if defined(PETSC_HAVE_EXODUSII)
3091e50132fSMatthew G. Knepley           case 9:
3109566063dSJacob Faibussowitsch             if (!(*viewer = PETSC_VIEWER_EXODUSII_(comm))) PetscCall(PETSC_ERR_PLIB);
3111e50132fSMatthew G. Knepley             break;
3121e50132fSMatthew G. Knepley #endif
313d71ae5a4SJacob Faibussowitsch           default:
314d71ae5a4SJacob Faibussowitsch             SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Unsupported viewer %s", loc0_vtype);
3157f677774SBarry Smith           }
3169566063dSJacob Faibussowitsch           PetscCall(PetscObjectReference((PetscObject)*viewer));
3177f677774SBarry Smith         } else {
31835d27ee3SJed Brown           if (loc2_fmt && !*loc1_fname && (cnt == 0)) { /* ASCII format without file name */
3199566063dSJacob Faibussowitsch             PetscCall(PetscViewerASCIIGetStdout(comm, viewer));
3209566063dSJacob Faibussowitsch             PetscCall(PetscObjectReference((PetscObject)*viewer));
3217f677774SBarry Smith           } else {
3223550efbcSJed Brown             PetscFileMode fmode;
3239566063dSJacob Faibussowitsch             PetscCall(PetscViewerCreate(comm, viewer));
3249566063dSJacob Faibussowitsch             PetscCall(PetscViewerSetType(*viewer, *loc0_vtype ? loc0_vtype : "ascii"));
3253550efbcSJed Brown             fmode = FILE_MODE_WRITE;
3263550efbcSJed Brown             if (loc3_fmode && *loc3_fmode) { /* Has non-empty file mode ("write" or "append") */
3279566063dSJacob Faibussowitsch               PetscCall(PetscEnumFind(PetscFileModes, loc3_fmode, (PetscEnum *)&fmode, &flag));
32828b400f6SJacob Faibussowitsch               PetscCheck(flag, comm, PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown file mode: %s", loc3_fmode);
3297f677774SBarry Smith             }
330acd7d2deSBarry Smith             if (loc2_fmt) {
3310ecfd9fcSLisandro Dalcin               PetscBool tk, im;
3329566063dSJacob Faibussowitsch               PetscCall(PetscStrcmp(loc1_fname, "tikz", &tk));
3339566063dSJacob Faibussowitsch               PetscCall(PetscStrcmp(loc1_fname, "image", &im));
3340ecfd9fcSLisandro Dalcin               if (tk || im) {
3359566063dSJacob Faibussowitsch                 PetscCall(PetscViewerDrawSetInfo(*viewer, NULL, loc2_fmt, PETSC_DECIDE, PETSC_DECIDE, PETSC_DECIDE, PETSC_DECIDE));
336acd7d2deSBarry Smith                 *loc2_fmt = 0;
337acd7d2deSBarry Smith               }
338acd7d2deSBarry Smith             }
3399566063dSJacob Faibussowitsch             PetscCall(PetscViewerFileSetMode(*viewer, flag ? fmode : FILE_MODE_WRITE));
3409566063dSJacob Faibussowitsch             PetscCall(PetscViewerFileSetName(*viewer, loc1_fname));
3411baa6e33SBarry Smith             if (*loc1_fname) PetscCall(PetscViewerDrawSetDrawType(*viewer, loc1_fname));
3429566063dSJacob Faibussowitsch             PetscCall(PetscViewerSetFromOptions(*viewer));
34305315717SToby Isaac           }
344bb1d7374SBarry Smith         }
34552f76066SLisandro Dalcin       }
3461baa6e33SBarry Smith       if (viewer) PetscCall(PetscViewerSetUp(*viewer));
34735d27ee3SJed Brown       if (loc2_fmt && *loc2_fmt) {
348e156c29bSStefano Zampini         PetscViewerFormat tfmt;
349d6acdc46SStefano Zampini 
3509566063dSJacob Faibussowitsch         PetscCall(PetscEnumFind(PetscViewerFormats, loc2_fmt, (PetscEnum *)&tfmt, &flag));
351d6acdc46SStefano Zampini         if (format) *format = tfmt;
3526adde796SStefano Zampini         PetscCheck(flag, comm, PETSC_ERR_SUP, "Unknown viewer format %s", loc2_fmt);
353d6acdc46SStefano Zampini       } else if (viewer && (cnt == 6) && format) { /* Get format from VTK viewer */
3549566063dSJacob Faibussowitsch         PetscCall(PetscViewerGetFormat(*viewer, format));
3557f677774SBarry Smith       }
3569566063dSJacob Faibussowitsch       PetscCall(PetscFree(loc0_vtype));
3572bf49c77SBarry Smith     }
3582bf49c77SBarry Smith   }
3593ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3602bf49c77SBarry Smith }
3612bf49c77SBarry Smith 
3625c6c1daeSBarry Smith /*@
363c410d8ccSBarry Smith   PetscViewerCreate - Creates a viewing context. A `PetscViewer` represents a file, a graphical window, a Unix socket or a variety of other ways
364c410d8ccSBarry Smith   of viewing a PETSc object
3655c6c1daeSBarry Smith 
366d083f849SBarry Smith   Collective
3675c6c1daeSBarry Smith 
3685c6c1daeSBarry Smith   Input Parameter:
3695c6c1daeSBarry Smith . comm - MPI communicator
3705c6c1daeSBarry Smith 
3715c6c1daeSBarry Smith   Output Parameter:
372811af0c4SBarry Smith . inviewer - location to put the `PetscViewer` context
3735c6c1daeSBarry Smith 
3745c6c1daeSBarry Smith   Level: advanced
3755c6c1daeSBarry Smith 
376d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerType`
3775c6c1daeSBarry Smith @*/
378d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerCreate(MPI_Comm comm, PetscViewer *inviewer)
379d71ae5a4SJacob Faibussowitsch {
3805c6c1daeSBarry Smith   PetscViewer viewer;
3815c6c1daeSBarry Smith 
3825c6c1daeSBarry Smith   PetscFunctionBegin;
38302c9f0b5SLisandro Dalcin   *inviewer = NULL;
3849566063dSJacob Faibussowitsch   PetscCall(PetscViewerInitializePackage());
3859566063dSJacob Faibussowitsch   PetscCall(PetscHeaderCreate(viewer, PETSC_VIEWER_CLASSID, "PetscViewer", "PetscViewer", "Viewer", comm, PetscViewerDestroy, PetscViewerView));
3865c6c1daeSBarry Smith   *inviewer    = viewer;
38702c9f0b5SLisandro Dalcin   viewer->data = NULL;
3883ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3895c6c1daeSBarry Smith }
3905c6c1daeSBarry Smith 
3915c6c1daeSBarry Smith /*@C
392811af0c4SBarry Smith   PetscViewerSetType - Builds `PetscViewer` for a particular implementation.
3935c6c1daeSBarry Smith 
394c3339decSBarry Smith   Collective
3955c6c1daeSBarry Smith 
396d8d19677SJose E. Roman   Input Parameters:
397811af0c4SBarry Smith + viewer - the `PetscViewer` context obtained with `PetscViewerCreate()`
398811af0c4SBarry Smith - type   - for example, `PETSCVIEWERASCII`
3995c6c1daeSBarry Smith 
4003c7db156SBarry Smith   Options Database Key:
4013c7db156SBarry Smith . -viewer_type  <type> - Sets the type; use -help for a list of available methods (for instance, ascii)
4025c6c1daeSBarry Smith 
4035c6c1daeSBarry Smith   Level: advanced
4045c6c1daeSBarry Smith 
405811af0c4SBarry Smith   Note:
4063f423023SBarry Smith   See `PetscViewerType` for possible values
4075c6c1daeSBarry Smith 
408d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerCreate()`, `PetscViewerGetType()`, `PetscViewerType`, `PetscViewerPushFormat()`
4095c6c1daeSBarry Smith @*/
410d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerSetType(PetscViewer viewer, PetscViewerType type)
411d71ae5a4SJacob Faibussowitsch {
4125c6c1daeSBarry Smith   PetscBool match;
4135f80ce2aSJacob Faibussowitsch   PetscErrorCode (*r)(PetscViewer);
4145c6c1daeSBarry Smith 
4155c6c1daeSBarry Smith   PetscFunctionBegin;
4165c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
4175c6c1daeSBarry Smith   PetscValidCharPointer(type, 2);
4189566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, type, &match));
4193ba16761SJacob Faibussowitsch   if (match) PetscFunctionReturn(PETSC_SUCCESS);
4205c6c1daeSBarry Smith 
4215c6c1daeSBarry Smith   /* cleanup any old type that may be there */
422dbbe0bcdSBarry Smith   PetscTryTypeMethod(viewer, destroy);
4230298fd71SBarry Smith   viewer->ops->destroy = NULL;
42402c9f0b5SLisandro Dalcin   viewer->data         = NULL;
425dbbe0bcdSBarry Smith 
4269566063dSJacob Faibussowitsch   PetscCall(PetscMemzero(viewer->ops, sizeof(struct _PetscViewerOps)));
4275c6c1daeSBarry Smith 
4289566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListFind(PetscViewerList, type, &r));
4296adde796SStefano Zampini   PetscCheck(r, PetscObjectComm((PetscObject)viewer), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscViewer type given: %s", type);
4305c6c1daeSBarry Smith 
4319566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)viewer, type));
4329566063dSJacob Faibussowitsch   PetscCall((*r)(viewer));
4333ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4345c6c1daeSBarry Smith }
4355c6c1daeSBarry Smith 
4361c84c290SBarry Smith /*@C
437c410d8ccSBarry Smith   PetscViewerRegister - Adds a viewer to those available for use with `PetscViewerSetType()`
4381c84c290SBarry Smith 
4391c84c290SBarry Smith   Not Collective
4401c84c290SBarry Smith 
4411c84c290SBarry Smith   Input Parameters:
4422fe279fdSBarry Smith + sname    - name of a new user-defined viewer
4432fe279fdSBarry Smith - function - routine to create method context
4441c84c290SBarry Smith 
4451c84c290SBarry Smith   Level: developer
446811af0c4SBarry Smith 
447811af0c4SBarry Smith   Note:
448811af0c4SBarry Smith   `PetscViewerRegister()` may be called multiple times to add several user-defined viewers.
4491c84c290SBarry Smith 
450aec76313SJacob Faibussowitsch   Example Usage:
4511c84c290SBarry Smith .vb
452bdf89e91SBarry Smith    PetscViewerRegister("my_viewer_type", MyViewerCreate);
4531c84c290SBarry Smith .ve
4541c84c290SBarry Smith 
4551c84c290SBarry Smith   Then, your solver can be chosen with the procedural interface via
4561c84c290SBarry Smith $     PetscViewerSetType(viewer, "my_viewer_type")
4571c84c290SBarry Smith   or at runtime via the option
4581c84c290SBarry Smith $     -viewer_type my_viewer_type
4591c84c290SBarry Smith 
460d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscViewerRegisterAll()`
4611c84c290SBarry Smith  @*/
462d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerRegister(const char *sname, PetscErrorCode (*function)(PetscViewer))
463d71ae5a4SJacob Faibussowitsch {
4645c6c1daeSBarry Smith   PetscFunctionBegin;
4659566063dSJacob Faibussowitsch   PetscCall(PetscViewerInitializePackage());
4669566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListAdd(&PetscViewerList, sname, function));
4673ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4685c6c1daeSBarry Smith }
4695c6c1daeSBarry Smith 
4705c6c1daeSBarry Smith /*@C
4713f423023SBarry Smith   PetscViewerSetFromOptions - Sets various options for a viewer based on values in the options database.
4725c6c1daeSBarry Smith 
473c3339decSBarry Smith   Collective
4745c6c1daeSBarry Smith 
4755c6c1daeSBarry Smith   Input Parameter:
476811af0c4SBarry Smith . viewer - the viewer context
4775c6c1daeSBarry Smith 
4785c6c1daeSBarry Smith   Level: intermediate
4795c6c1daeSBarry Smith 
480811af0c4SBarry Smith   Note:
481c410d8ccSBarry Smith   Must be called after `PetscViewerCreate()` but before the `PetscViewer` is used.
4825c6c1daeSBarry Smith 
483d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerCreate()`, `PetscViewerSetType()`, `PetscViewerType`
4845c6c1daeSBarry Smith @*/
485d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerSetFromOptions(PetscViewer viewer)
486d71ae5a4SJacob Faibussowitsch {
4875c6c1daeSBarry Smith   char      vtype[256];
4885c6c1daeSBarry Smith   PetscBool flg;
4895c6c1daeSBarry Smith 
4905c6c1daeSBarry Smith   PetscFunctionBegin;
4915c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
4925c6c1daeSBarry Smith 
49348a46eb9SPierre Jolivet   if (!PetscViewerList) PetscCall(PetscViewerRegisterAll());
494d0609cedSBarry Smith   PetscObjectOptionsBegin((PetscObject)viewer);
4959566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFList("-viewer_type", "Type of PetscViewer", "None", PetscViewerList, (char *)(((PetscObject)viewer)->type_name ? ((PetscObject)viewer)->type_name : PETSCVIEWERASCII), vtype, 256, &flg));
4961baa6e33SBarry Smith   if (flg) PetscCall(PetscViewerSetType(viewer, vtype));
4975c6c1daeSBarry Smith   /* type has not been set? */
49848a46eb9SPierre Jolivet   if (!((PetscObject)viewer)->type_name) PetscCall(PetscViewerSetType(viewer, PETSCVIEWERASCII));
499dbbe0bcdSBarry Smith   PetscTryTypeMethod(viewer, setfromoptions, PetscOptionsObject);
5005c6c1daeSBarry Smith 
5015c6c1daeSBarry Smith   /* process any options handlers added with PetscObjectAddOptionsHandler() */
502dbbe0bcdSBarry Smith   PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)viewer, PetscOptionsObject));
5039566063dSJacob Faibussowitsch   PetscCall(PetscViewerViewFromOptions(viewer, NULL, "-viewer_view"));
504d0609cedSBarry Smith   PetscOptionsEnd();
5053ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5065c6c1daeSBarry Smith }
507816f7b76SBarry Smith 
508d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerFlowControlStart(PetscViewer viewer, PetscInt *mcnt, PetscInt *cnt)
509d71ae5a4SJacob Faibussowitsch {
510816f7b76SBarry Smith   PetscFunctionBegin;
5119566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryGetFlowControl(viewer, mcnt));
5129566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryGetFlowControl(viewer, cnt));
5133ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
514816f7b76SBarry Smith }
515816f7b76SBarry Smith 
516d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerFlowControlStepMain(PetscViewer viewer, PetscInt i, PetscInt *mcnt, PetscInt cnt)
517d71ae5a4SJacob Faibussowitsch {
518816f7b76SBarry Smith   MPI_Comm comm;
519816f7b76SBarry Smith 
520816f7b76SBarry Smith   PetscFunctionBegin;
5219566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
522816f7b76SBarry Smith   if (i >= *mcnt) {
523816f7b76SBarry Smith     *mcnt += cnt;
5249566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Bcast(mcnt, 1, MPIU_INT, 0, comm));
525816f7b76SBarry Smith   }
5263ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
527816f7b76SBarry Smith }
528816f7b76SBarry Smith 
529d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerFlowControlEndMain(PetscViewer viewer, PetscInt *mcnt)
530d71ae5a4SJacob Faibussowitsch {
531816f7b76SBarry Smith   MPI_Comm comm;
532816f7b76SBarry Smith   PetscFunctionBegin;
5339566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
534816f7b76SBarry Smith   *mcnt = 0;
5359566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Bcast(mcnt, 1, MPIU_INT, 0, comm));
5363ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
537816f7b76SBarry Smith }
538816f7b76SBarry Smith 
539d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerFlowControlStepWorker(PetscViewer viewer, PetscMPIInt rank, PetscInt *mcnt)
540d71ae5a4SJacob Faibussowitsch {
541816f7b76SBarry Smith   MPI_Comm comm;
542816f7b76SBarry Smith   PetscFunctionBegin;
5439566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
544816f7b76SBarry Smith   while (PETSC_TRUE) {
545816f7b76SBarry Smith     if (rank < *mcnt) break;
5469566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Bcast(mcnt, 1, MPIU_INT, 0, comm));
547816f7b76SBarry Smith   }
5483ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
549816f7b76SBarry Smith }
550816f7b76SBarry Smith 
551d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerFlowControlEndWorker(PetscViewer viewer, PetscInt *mcnt)
552d71ae5a4SJacob Faibussowitsch {
553816f7b76SBarry Smith   MPI_Comm comm;
554816f7b76SBarry Smith   PetscFunctionBegin;
5559566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
556816f7b76SBarry Smith   while (PETSC_TRUE) {
5579566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Bcast(mcnt, 1, MPIU_INT, 0, comm));
558816f7b76SBarry Smith     if (!*mcnt) break;
559816f7b76SBarry Smith   }
5603ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
561816f7b76SBarry Smith }
562