xref: /petsc/src/sys/classes/viewer/interface/viewreg.c (revision 20f4b53cbb5e9bd9ef12b76a8697d60d197cda17)
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*20f4b53cSBarry Smith      Not Collective
329de0f6ecSBarry Smith 
339de0f6ecSBarry Smith     Level: developer
349de0f6ecSBarry Smith 
35db781477SPatrick Sanan .seealso: `PetscOptionsHelpPrintedCheck()`, `PetscOptionsHelpPrintChecked()`
369de0f6ecSBarry Smith @*/
37d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsHelpPrintedCreate(PetscOptionsHelpPrinted *hp)
38d71ae5a4SJacob Faibussowitsch {
399de0f6ecSBarry Smith   PetscFunctionBegin;
409566063dSJacob Faibussowitsch   PetscCall(PetscNew(hp));
419de0f6ecSBarry Smith   (*hp)->printed = kh_init(HTPrinted);
429566063dSJacob Faibussowitsch   PetscCall(PetscSegBufferCreate(sizeof(char), 10000, &(*hp)->strings));
433ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
449de0f6ecSBarry Smith }
459de0f6ecSBarry Smith 
469de0f6ecSBarry Smith /*@C
479de0f6ecSBarry Smith       PetscOptionsHelpPrintedCheck - Checks if a particular pre, name pair has previous been entered (meaning the help message was printed)
489de0f6ecSBarry Smith 
49*20f4b53cSBarry Smith      Not Collective
509de0f6ecSBarry Smith 
519de0f6ecSBarry Smith     Input Parameters:
529de0f6ecSBarry Smith +     hp - the object used to manage tracking what help messages have been printed
533f423023SBarry Smith .     pre - the prefix part of the string, many be `NULL`
543f423023SBarry Smith -     name - the string to look for (cannot be `NULL`)
559de0f6ecSBarry Smith 
569de0f6ecSBarry Smith     Output Parameter:
573f423023SBarry Smith .     found - `PETSC_TRUE` if the string was already set
589de0f6ecSBarry Smith 
599de0f6ecSBarry Smith     Level: intermediate
609de0f6ecSBarry Smith 
61db781477SPatrick Sanan .seealso: `PetscOptionsHelpPrintedCreate()`
629de0f6ecSBarry Smith @*/
63d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsHelpPrintedCheck(PetscOptionsHelpPrinted hp, const char *pre, const char *name, PetscBool *found)
64d71ae5a4SJacob Faibussowitsch {
659de0f6ecSBarry Smith   size_t l1, l2;
66c1449d8eSBarry Smith #if !defined(PETSC_HAVE_THREADSAFETY)
679de0f6ecSBarry Smith   char *both;
68e8f14785SLisandro Dalcin   int   newitem;
69c1449d8eSBarry Smith #endif
709de0f6ecSBarry Smith 
719de0f6ecSBarry Smith   PetscFunctionBegin;
729566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(pre, &l1));
739566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(name, &l2));
749de0f6ecSBarry Smith   if (l1 + l2 == 0) {
759de0f6ecSBarry Smith     *found = PETSC_FALSE;
763ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
779de0f6ecSBarry Smith   }
78c1449d8eSBarry Smith #if !defined(PETSC_HAVE_THREADSAFETY)
79c6a7a370SJeremy L Thompson   size_t lboth = l1 + l2 + 1;
80c6a7a370SJeremy L Thompson   PetscCall(PetscSegBufferGet(hp->strings, lboth, &both));
81c6a7a370SJeremy L Thompson   PetscCall(PetscStrncpy(both, pre, lboth));
82c6a7a370SJeremy L Thompson   PetscCall(PetscStrncpy(both + l1, name, l2 + 1));
839de0f6ecSBarry Smith   kh_put(HTPrinted, hp->printed, both, &newitem);
84c6a7a370SJeremy L Thompson   if (!newitem) PetscCall(PetscSegBufferUnuse(hp->strings, lboth));
859de0f6ecSBarry Smith   *found = newitem ? PETSC_FALSE : PETSC_TRUE;
86c1449d8eSBarry Smith #else
87c1449d8eSBarry Smith   *found = PETSC_FALSE;
88c1449d8eSBarry Smith #endif
893ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9094d6a431SBarry Smith }
9194d6a431SBarry Smith 
92eb55bdffSLawrence Mitchell static PetscBool noviewer = PETSC_FALSE;
93eb55bdffSLawrence Mitchell static PetscBool noviewers[PETSCVIEWERGETVIEWEROFFPUSHESMAX];
94eb55bdffSLawrence Mitchell static PetscInt  inoviewers = 0;
95eb55bdffSLawrence Mitchell 
96eb55bdffSLawrence Mitchell /*@
97811af0c4SBarry Smith   PetscOptionsPushGetViewerOff - sets if a `PetscOptionsGetViewer()` returns a viewer.
98eb55bdffSLawrence Mitchell 
99eb55bdffSLawrence Mitchell   Logically Collective
100eb55bdffSLawrence Mitchell 
101eb55bdffSLawrence Mitchell   Input Parameter:
102811af0c4SBarry Smith . flg - `PETSC_TRUE` to turn off viewer creation, `PETSC_FALSE` to turn it on.
103eb55bdffSLawrence Mitchell 
104eb55bdffSLawrence Mitchell   Level: developer
105eb55bdffSLawrence Mitchell 
106811af0c4SBarry Smith   Note:
10795452b02SPatrick Sanan     Calling XXXViewFromOptions in an inner loop can be very expensive.  This can appear, for example, when using
108811af0c4SBarry Smith    many small subsolves.  Call this function to control viewer creation in `PetscOptionsGetViewer()`, thus removing the expensive XXXViewFromOptions calls.
109eb55bdffSLawrence Mitchell 
110d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscOptionsGetViewer()`, `PetscOptionsPopGetViewerOff()`
111eb55bdffSLawrence Mitchell @*/
112d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsPushGetViewerOff(PetscBool flg)
113d71ae5a4SJacob Faibussowitsch {
114eb55bdffSLawrence Mitchell   PetscFunctionBegin;
115cc73adaaSBarry Smith   PetscCheck(inoviewers < PETSCVIEWERGETVIEWEROFFPUSHESMAX, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many PetscOptionsPushGetViewerOff(), perhaps you forgot PetscOptionsPopGetViewerOff()?");
116eb55bdffSLawrence Mitchell 
117eb55bdffSLawrence Mitchell   noviewers[inoviewers++] = noviewer;
118eb55bdffSLawrence Mitchell   noviewer                = flg;
1193ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
120eb55bdffSLawrence Mitchell }
121eb55bdffSLawrence Mitchell 
122eb55bdffSLawrence Mitchell /*@
123811af0c4SBarry Smith   PetscOptionsPopGetViewerOff - reset whether `PetscOptionsGetViewer()` returns a viewer.
124eb55bdffSLawrence Mitchell 
125eb55bdffSLawrence Mitchell   Logically Collective
126eb55bdffSLawrence Mitchell 
127eb55bdffSLawrence Mitchell   Level: developer
128eb55bdffSLawrence Mitchell 
129811af0c4SBarry Smith   Note:
13095452b02SPatrick Sanan     Calling XXXViewFromOptions in an inner loop can be very expensive.  This can appear, for example, when using
131811af0c4SBarry Smith    many small subsolves.  Call this function to control viewer creation in `PetscOptionsGetViewer()`, thus removing the expensive XXXViewFromOptions calls.
132eb55bdffSLawrence Mitchell 
133d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscOptionsGetViewer()`, `PetscOptionsPushGetViewerOff()`
134eb55bdffSLawrence Mitchell @*/
135d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsPopGetViewerOff(void)
136d71ae5a4SJacob Faibussowitsch {
137eb55bdffSLawrence Mitchell   PetscFunctionBegin;
13828b400f6SJacob Faibussowitsch   PetscCheck(inoviewers, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many PetscOptionsPopGetViewerOff(), perhaps you forgot PetscOptionsPushGetViewerOff()?");
139eb55bdffSLawrence Mitchell   noviewer = noviewers[--inoviewers];
1403ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
141eb55bdffSLawrence Mitchell }
142eb55bdffSLawrence Mitchell 
143eb55bdffSLawrence Mitchell /*@
144811af0c4SBarry Smith   PetscOptionsGetViewerOff - does `PetscOptionsGetViewer()` return a viewer?
145eb55bdffSLawrence Mitchell 
146eb55bdffSLawrence Mitchell   Logically Collective
147eb55bdffSLawrence Mitchell 
148eb55bdffSLawrence Mitchell   Output Parameter:
149eb55bdffSLawrence Mitchell . flg - whether viewers are returned.
150eb55bdffSLawrence Mitchell 
151eb55bdffSLawrence Mitchell   Level: developer
152eb55bdffSLawrence Mitchell 
153811af0c4SBarry Smith   Note:
15495452b02SPatrick Sanan     Calling XXXViewFromOptions in an inner loop can be very expensive.  This can appear, for example, when using
155eb55bdffSLawrence Mitchell    many small subsolves.
156eb55bdffSLawrence Mitchell 
157d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscOptionsGetViewer()`, `PetscOptionsPushGetViewerOff()`, `PetscOptionsPopGetViewerOff()`
158eb55bdffSLawrence Mitchell @*/
159d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetViewerOff(PetscBool *flg)
160d71ae5a4SJacob Faibussowitsch {
161eb55bdffSLawrence Mitchell   PetscFunctionBegin;
162534a8f05SLisandro Dalcin   PetscValidBoolPointer(flg, 1);
163eb55bdffSLawrence Mitchell   *flg = noviewer;
1643ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
165eb55bdffSLawrence Mitchell }
166eb55bdffSLawrence Mitchell 
1672bf49c77SBarry Smith /*@C
1682bf49c77SBarry Smith    PetscOptionsGetViewer - Gets a viewer appropriate for the type indicated by the user
1692bf49c77SBarry Smith 
170d083f849SBarry Smith    Collective
1712bf49c77SBarry Smith 
1722bf49c77SBarry Smith    Input Parameters:
1732bf49c77SBarry Smith +  comm - the communicator to own the viewer
1743f423023SBarry Smith .  options - options database, use `NULL` for default global database
1753f423023SBarry Smith .  pre - the string to prepend to the name or `NULL`
1762bf49c77SBarry Smith -  name - the option one is seeking
1772bf49c77SBarry Smith 
178d8d19677SJose E. Roman    Output Parameters:
1793f423023SBarry Smith +  viewer - the viewer, pass `NULL` if not needed
1803f423023SBarry Smith .  format - the `PetscViewerFormat` requested by the user, pass `NULL` if not needed
181811af0c4SBarry Smith -  set - `PETSC_TRUE` if found, else `PETSC_FALSE`
1822bf49c77SBarry Smith 
1832bf49c77SBarry Smith    Level: intermediate
1842bf49c77SBarry Smith 
18595452b02SPatrick Sanan    Notes:
18695452b02SPatrick Sanan     If no value is provided ascii:stdout is used
187811af0c4SBarry Smith +       ascii[:[filename][:[format][:append]]]  -  defaults to stdout - format can be one of ascii_info, ascii_info_detail, or ascii_matlab,
188d1da0b69SBarry Smith                                                   for example ascii::ascii_info prints just the information about the object not all details
189d1da0b69SBarry Smith                                                   unless :append is given filename opens in write mode, overwriting what was already there
190811af0c4SBarry Smith .       binary[:[filename][:[format][:append]]] -  defaults to the file binaryoutput
191811af0c4SBarry Smith .       draw[:drawtype[:filename]]              -  for example, draw:tikz, draw:tikz:figure.tex  or draw:x
192811af0c4SBarry Smith .       socket[:port]                           -  defaults to the standard output port
193811af0c4SBarry Smith -       saws[:communicatorname]                 -   publishes object to the Scientific Application Webserver (SAWs)
1942bf49c77SBarry Smith 
195811af0c4SBarry Smith    Use `PetscViewerDestroy()` after using the viewer, otherwise a memory leak will occur
1962bf49c77SBarry Smith 
197811af0c4SBarry Smith    You can control whether calls to this function create a viewer (or return early with *set of `PETSC_FALSE`) with
198811af0c4SBarry Smith    `PetscOptionsPushGetViewerOff()`.  This is useful if calling many small subsolves, in which case XXXViewFromOptions can take
199eb55bdffSLawrence Mitchell    an appreciable fraction of the runtime.
200eb55bdffSLawrence Mitchell 
2013f423023SBarry Smith    If PETSc is configured with `--with-viewfromoptions=0` this function always returns with *set of `PETSC_FALSE`
20227b0f280SBarry Smith 
203d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
204db781477SPatrick Sanan           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
205db781477SPatrick Sanan           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsBool()`,
206db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
207c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
208db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
209db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsPushGetViewerOff()`, `PetscOptionsPopGetViewerOff()`,
210db781477SPatrick Sanan           `PetscOptionsGetViewerOff()`
2112bf49c77SBarry Smith @*/
212d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetViewer(MPI_Comm comm, PetscOptions options, const char pre[], const char name[], PetscViewer *viewer, PetscViewerFormat *format, PetscBool *set)
213d71ae5a4SJacob Faibussowitsch {
2142d747510SLisandro Dalcin   const char *value;
21520610d12SBarry Smith   PetscBool   flag, hashelp;
2162bf49c77SBarry Smith 
2172bf49c77SBarry Smith   PetscFunctionBegin;
218064a246eSJacob Faibussowitsch   PetscValidCharPointer(name, 4);
2192bf49c77SBarry Smith 
2206348e711SLisandro Dalcin   if (viewer) *viewer = NULL;
2216348e711SLisandro Dalcin   if (format) *format = PETSC_VIEWER_DEFAULT;
22227b0f280SBarry Smith   if (set) *set = PETSC_FALSE;
2239566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetViewerOff(&flag));
2243ba16761SJacob Faibussowitsch   if (flag) PetscFunctionReturn(PETSC_SUCCESS);
22527b0f280SBarry Smith 
2269566063dSJacob Faibussowitsch   PetscCall(PetscOptionsHasHelp(NULL, &hashelp));
22720610d12SBarry Smith   if (hashelp) {
2289de0f6ecSBarry Smith     PetscBool found;
2299af95d99SBarry Smith 
23048a46eb9SPierre Jolivet     if (!PetscOptionsHelpPrintedSingleton) PetscCall(PetscOptionsHelpPrintedCreate(&PetscOptionsHelpPrintedSingleton));
2319566063dSJacob Faibussowitsch     PetscCall(PetscOptionsHelpPrintedCheck(PetscOptionsHelpPrintedSingleton, pre, name, &found));
23256071f75SVaclav Hapla     if (!found && viewer) {
2339566063dSJacob Faibussowitsch       PetscCall((*PetscHelpPrintf)(comm, "----------------------------------------\nViewer (-%s%s) options:\n", pre ? pre : "", name + 1));
2349566063dSJacob 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"));
2359566063dSJacob Faibussowitsch       PetscCall((*PetscHelpPrintf)(comm, "  -%s%s binary[:[filename][:[format][:append]]]: %s (%s)\n", pre ? pre : "", name + 1, "Saves object to a binary file", "PetscOptionsGetViewer"));
2369566063dSJacob Faibussowitsch       PetscCall((*PetscHelpPrintf)(comm, "  -%s%s draw[:[drawtype][:filename|format]] %s (%s)\n", pre ? pre : "", name + 1, "Draws object", "PetscOptionsGetViewer"));
2379566063dSJacob Faibussowitsch       PetscCall((*PetscHelpPrintf)(comm, "  -%s%s socket[:port]: %s (%s)\n", pre ? pre : "", name + 1, "Pushes object to a Unix socket", "PetscOptionsGetViewer"));
2389566063dSJacob Faibussowitsch       PetscCall((*PetscHelpPrintf)(comm, "  -%s%s saws[:communicatorname]: %s (%s)\n", pre ? pre : "", name + 1, "Publishes object to SAWs", "PetscOptionsGetViewer"));
23994d6a431SBarry Smith     }
24020610d12SBarry Smith   }
241685405a1SBarry Smith 
242e3f3e4b6SBarry Smith   if (format) *format = PETSC_VIEWER_DEFAULT;
2439566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2442bf49c77SBarry Smith   if (flag) {
2452bf49c77SBarry Smith     if (set) *set = PETSC_TRUE;
2462bf49c77SBarry Smith     if (!value) {
247bb1d7374SBarry Smith       if (viewer) {
2489566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIGetStdout(comm, viewer));
2499566063dSJacob Faibussowitsch         PetscCall(PetscObjectReference((PetscObject)*viewer));
250bb1d7374SBarry Smith       }
2512bf49c77SBarry Smith     } else {
252bbcf679cSJacob Faibussowitsch       char       *loc0_vtype = NULL, *loc1_fname = NULL, *loc2_fmt = NULL, *loc3_fmode = NULL;
2532bf49c77SBarry Smith       PetscInt    cnt;
2541e50132fSMatthew G. Knepley       const char *viewers[] = {PETSCVIEWERASCII, PETSCVIEWERBINARY, PETSCVIEWERDRAW, PETSCVIEWERSOCKET, PETSCVIEWERMATLAB, PETSCVIEWERSAWS, PETSCVIEWERVTK, PETSCVIEWERHDF5, PETSCVIEWERGLVIS, PETSCVIEWEREXODUSII, NULL};
2552bf49c77SBarry Smith 
2569566063dSJacob Faibussowitsch       PetscCall(PetscStrallocpy(value, &loc0_vtype));
2579566063dSJacob Faibussowitsch       PetscCall(PetscStrchr(loc0_vtype, ':', &loc1_fname));
25835d27ee3SJed Brown       if (loc1_fname) {
25935d27ee3SJed Brown         *loc1_fname++ = 0;
2609566063dSJacob Faibussowitsch         PetscCall(PetscStrchr(loc1_fname, ':', &loc2_fmt));
26135d27ee3SJed Brown       }
26235d27ee3SJed Brown       if (loc2_fmt) {
26335d27ee3SJed Brown         *loc2_fmt++ = 0;
2649566063dSJacob Faibussowitsch         PetscCall(PetscStrchr(loc2_fmt, ':', &loc3_fmode));
26535d27ee3SJed Brown       }
26635d27ee3SJed Brown       if (loc3_fmode) *loc3_fmode++ = 0;
2679566063dSJacob Faibussowitsch       PetscCall(PetscStrendswithwhich(*loc0_vtype ? loc0_vtype : "ascii", viewers, &cnt));
26808401ef6SPierre Jolivet       PetscCheck(cnt <= (PetscInt)sizeof(viewers) - 1, comm, PETSC_ERR_ARG_OUTOFRANGE, "Unknown viewer type: %s", loc0_vtype);
269bb1d7374SBarry Smith       if (viewer) {
27035d27ee3SJed Brown         if (!loc1_fname) {
27143b63833SBarry Smith           switch (cnt) {
272d71ae5a4SJacob Faibussowitsch           case 0:
273d71ae5a4SJacob Faibussowitsch             PetscCall(PetscViewerASCIIGetStdout(comm, viewer));
274d71ae5a4SJacob Faibussowitsch             break;
27543b63833SBarry Smith           case 1:
2769566063dSJacob Faibussowitsch             if (!(*viewer = PETSC_VIEWER_BINARY_(comm))) PetscCall(PETSC_ERR_PLIB);
27743b63833SBarry Smith             break;
27843b63833SBarry Smith           case 2:
2799566063dSJacob Faibussowitsch             if (!(*viewer = PETSC_VIEWER_DRAW_(comm))) PetscCall(PETSC_ERR_PLIB);
28043b63833SBarry Smith             break;
281b58ca069SBarry Smith #if defined(PETSC_USE_SOCKET_VIEWER)
28243b63833SBarry Smith           case 3:
2839566063dSJacob Faibussowitsch             if (!(*viewer = PETSC_VIEWER_SOCKET_(comm))) PetscCall(PETSC_ERR_PLIB);
28443b63833SBarry Smith             break;
285b58ca069SBarry Smith #endif
286d1e78c4fSBarry Smith #if defined(PETSC_HAVE_MATLAB)
28743b63833SBarry Smith           case 4:
2889566063dSJacob Faibussowitsch             if (!(*viewer = PETSC_VIEWER_MATLAB_(comm))) PetscCall(PETSC_ERR_PLIB);
28943b63833SBarry Smith             break;
29043b63833SBarry Smith #endif
291e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS)
292bfb97211SBarry Smith           case 5:
2939566063dSJacob Faibussowitsch             if (!(*viewer = PETSC_VIEWER_SAWS_(comm))) PetscCall(PETSC_ERR_PLIB);
294bfb97211SBarry Smith             break;
295bfb97211SBarry Smith #endif
296a75e6a4aSMatthew G. Knepley #if defined(PETSC_HAVE_HDF5)
297a75e6a4aSMatthew G. Knepley           case 7:
2989566063dSJacob Faibussowitsch             if (!(*viewer = PETSC_VIEWER_HDF5_(comm))) PetscCall(PETSC_ERR_PLIB);
299a75e6a4aSMatthew G. Knepley             break;
300a75e6a4aSMatthew G. Knepley #endif
3018135c375SStefano Zampini           case 8:
3029566063dSJacob Faibussowitsch             if (!(*viewer = PETSC_VIEWER_GLVIS_(comm))) PetscCall(PETSC_ERR_PLIB);
3038135c375SStefano Zampini             break;
3041e50132fSMatthew G. Knepley #if defined(PETSC_HAVE_EXODUSII)
3051e50132fSMatthew G. Knepley           case 9:
3069566063dSJacob Faibussowitsch             if (!(*viewer = PETSC_VIEWER_EXODUSII_(comm))) PetscCall(PETSC_ERR_PLIB);
3071e50132fSMatthew G. Knepley             break;
3081e50132fSMatthew G. Knepley #endif
309d71ae5a4SJacob Faibussowitsch           default:
310d71ae5a4SJacob Faibussowitsch             SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Unsupported viewer %s", loc0_vtype);
3117f677774SBarry Smith           }
3129566063dSJacob Faibussowitsch           PetscCall(PetscObjectReference((PetscObject)*viewer));
3137f677774SBarry Smith         } else {
31435d27ee3SJed Brown           if (loc2_fmt && !*loc1_fname && (cnt == 0)) { /* ASCII format without file name */
3159566063dSJacob Faibussowitsch             PetscCall(PetscViewerASCIIGetStdout(comm, viewer));
3169566063dSJacob Faibussowitsch             PetscCall(PetscObjectReference((PetscObject)*viewer));
3177f677774SBarry Smith           } else {
3183550efbcSJed Brown             PetscFileMode fmode;
3199566063dSJacob Faibussowitsch             PetscCall(PetscViewerCreate(comm, viewer));
3209566063dSJacob Faibussowitsch             PetscCall(PetscViewerSetType(*viewer, *loc0_vtype ? loc0_vtype : "ascii"));
3213550efbcSJed Brown             fmode = FILE_MODE_WRITE;
3223550efbcSJed Brown             if (loc3_fmode && *loc3_fmode) { /* Has non-empty file mode ("write" or "append") */
3239566063dSJacob Faibussowitsch               PetscCall(PetscEnumFind(PetscFileModes, loc3_fmode, (PetscEnum *)&fmode, &flag));
32428b400f6SJacob Faibussowitsch               PetscCheck(flag, comm, PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown file mode: %s", loc3_fmode);
3257f677774SBarry Smith             }
326acd7d2deSBarry Smith             if (loc2_fmt) {
3270ecfd9fcSLisandro Dalcin               PetscBool tk, im;
3289566063dSJacob Faibussowitsch               PetscCall(PetscStrcmp(loc1_fname, "tikz", &tk));
3299566063dSJacob Faibussowitsch               PetscCall(PetscStrcmp(loc1_fname, "image", &im));
3300ecfd9fcSLisandro Dalcin               if (tk || im) {
3319566063dSJacob Faibussowitsch                 PetscCall(PetscViewerDrawSetInfo(*viewer, NULL, loc2_fmt, PETSC_DECIDE, PETSC_DECIDE, PETSC_DECIDE, PETSC_DECIDE));
332acd7d2deSBarry Smith                 *loc2_fmt = 0;
333acd7d2deSBarry Smith               }
334acd7d2deSBarry Smith             }
3359566063dSJacob Faibussowitsch             PetscCall(PetscViewerFileSetMode(*viewer, flag ? fmode : FILE_MODE_WRITE));
3369566063dSJacob Faibussowitsch             PetscCall(PetscViewerFileSetName(*viewer, loc1_fname));
3371baa6e33SBarry Smith             if (*loc1_fname) PetscCall(PetscViewerDrawSetDrawType(*viewer, loc1_fname));
3389566063dSJacob Faibussowitsch             PetscCall(PetscViewerSetFromOptions(*viewer));
33905315717SToby Isaac           }
340bb1d7374SBarry Smith         }
34152f76066SLisandro Dalcin       }
3421baa6e33SBarry Smith       if (viewer) PetscCall(PetscViewerSetUp(*viewer));
34335d27ee3SJed Brown       if (loc2_fmt && *loc2_fmt) {
344e156c29bSStefano Zampini         PetscViewerFormat tfmt;
345d6acdc46SStefano Zampini 
3469566063dSJacob Faibussowitsch         PetscCall(PetscEnumFind(PetscViewerFormats, loc2_fmt, (PetscEnum *)&tfmt, &flag));
347d6acdc46SStefano Zampini         if (format) *format = tfmt;
34828b400f6SJacob Faibussowitsch         PetscCheck(flag, PETSC_COMM_SELF, PETSC_ERR_SUP, "Unknown viewer format %s", loc2_fmt);
349d6acdc46SStefano Zampini       } else if (viewer && (cnt == 6) && format) { /* Get format from VTK viewer */
3509566063dSJacob Faibussowitsch         PetscCall(PetscViewerGetFormat(*viewer, format));
3517f677774SBarry Smith       }
3529566063dSJacob Faibussowitsch       PetscCall(PetscFree(loc0_vtype));
3532bf49c77SBarry Smith     }
3542bf49c77SBarry Smith   }
3553ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3562bf49c77SBarry Smith }
3572bf49c77SBarry Smith 
3585c6c1daeSBarry Smith /*@
359811af0c4SBarry Smith    PetscViewerCreate - Creates a viewing context. A `PetscViewer` represents a file, a graphical window, a Unix socket or a variety of other ways of viewing a PETSc object
3605c6c1daeSBarry Smith 
361d083f849SBarry Smith    Collective
3625c6c1daeSBarry Smith 
3635c6c1daeSBarry Smith    Input Parameter:
3645c6c1daeSBarry Smith .  comm - MPI communicator
3655c6c1daeSBarry Smith 
3665c6c1daeSBarry Smith    Output Parameter:
367811af0c4SBarry Smith .  inviewer - location to put the `PetscViewer` context
3685c6c1daeSBarry Smith 
3695c6c1daeSBarry Smith    Level: advanced
3705c6c1daeSBarry Smith 
371d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerType`
3725c6c1daeSBarry Smith @*/
373d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerCreate(MPI_Comm comm, PetscViewer *inviewer)
374d71ae5a4SJacob Faibussowitsch {
3755c6c1daeSBarry Smith   PetscViewer viewer;
3765c6c1daeSBarry Smith 
3775c6c1daeSBarry Smith   PetscFunctionBegin;
37802c9f0b5SLisandro Dalcin   *inviewer = NULL;
3799566063dSJacob Faibussowitsch   PetscCall(PetscViewerInitializePackage());
3809566063dSJacob Faibussowitsch   PetscCall(PetscHeaderCreate(viewer, PETSC_VIEWER_CLASSID, "PetscViewer", "PetscViewer", "Viewer", comm, PetscViewerDestroy, PetscViewerView));
3815c6c1daeSBarry Smith   *inviewer    = viewer;
38202c9f0b5SLisandro Dalcin   viewer->data = NULL;
3833ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3845c6c1daeSBarry Smith }
3855c6c1daeSBarry Smith 
3865c6c1daeSBarry Smith /*@C
387811af0c4SBarry Smith    PetscViewerSetType - Builds `PetscViewer` for a particular implementation.
3885c6c1daeSBarry Smith 
389c3339decSBarry Smith    Collective
3905c6c1daeSBarry Smith 
391d8d19677SJose E. Roman    Input Parameters:
392811af0c4SBarry Smith +  viewer      - the `PetscViewer` context obtained with `PetscViewerCreate()`
393811af0c4SBarry Smith -  type        - for example, `PETSCVIEWERASCII`
3945c6c1daeSBarry Smith 
3953c7db156SBarry Smith    Options Database Key:
3963c7db156SBarry Smith .  -viewer_type  <type> - Sets the type; use -help for a list of available methods (for instance, ascii)
3975c6c1daeSBarry Smith 
3985c6c1daeSBarry Smith    Level: advanced
3995c6c1daeSBarry Smith 
400811af0c4SBarry Smith    Note:
4013f423023SBarry Smith    See `PetscViewerType` for possible values
4025c6c1daeSBarry Smith 
403d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerCreate()`, `PetscViewerGetType()`, `PetscViewerType`, `PetscViewerPushFormat()`
4045c6c1daeSBarry Smith @*/
405d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerSetType(PetscViewer viewer, PetscViewerType type)
406d71ae5a4SJacob Faibussowitsch {
4075c6c1daeSBarry Smith   PetscBool match;
4085f80ce2aSJacob Faibussowitsch   PetscErrorCode (*r)(PetscViewer);
4095c6c1daeSBarry Smith 
4105c6c1daeSBarry Smith   PetscFunctionBegin;
4115c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
4125c6c1daeSBarry Smith   PetscValidCharPointer(type, 2);
4139566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, type, &match));
4143ba16761SJacob Faibussowitsch   if (match) PetscFunctionReturn(PETSC_SUCCESS);
4155c6c1daeSBarry Smith 
4165c6c1daeSBarry Smith   /* cleanup any old type that may be there */
417dbbe0bcdSBarry Smith   PetscTryTypeMethod(viewer, destroy);
4180298fd71SBarry Smith   viewer->ops->destroy = NULL;
41902c9f0b5SLisandro Dalcin   viewer->data         = NULL;
420dbbe0bcdSBarry Smith 
4219566063dSJacob Faibussowitsch   PetscCall(PetscMemzero(viewer->ops, sizeof(struct _PetscViewerOps)));
4225c6c1daeSBarry Smith 
4239566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListFind(PetscViewerList, type, &r));
42428b400f6SJacob Faibussowitsch   PetscCheck(r, PETSC_COMM_SELF, PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscViewer type given: %s", type);
4255c6c1daeSBarry Smith 
4269566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)viewer, type));
4279566063dSJacob Faibussowitsch   PetscCall((*r)(viewer));
4283ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4295c6c1daeSBarry Smith }
4305c6c1daeSBarry Smith 
4311c84c290SBarry Smith /*@C
432811af0c4SBarry Smith    PetscViewerRegister - Adds a viewer to those available for use
4331c84c290SBarry Smith 
4341c84c290SBarry Smith    Not Collective
4351c84c290SBarry Smith 
4361c84c290SBarry Smith    Input Parameters:
4371c84c290SBarry Smith +  name_solver - name of a new user-defined viewer
4381c84c290SBarry Smith -  routine_create - routine to create method context
4391c84c290SBarry Smith 
4401c84c290SBarry Smith    Level: developer
441811af0c4SBarry Smith 
442811af0c4SBarry Smith    Note:
443811af0c4SBarry Smith    `PetscViewerRegister()` may be called multiple times to add several user-defined viewers.
4441c84c290SBarry Smith 
4451c84c290SBarry Smith    Sample usage:
4461c84c290SBarry Smith .vb
447bdf89e91SBarry Smith    PetscViewerRegister("my_viewer_type",MyViewerCreate);
4481c84c290SBarry Smith .ve
4491c84c290SBarry Smith 
4501c84c290SBarry Smith    Then, your solver can be chosen with the procedural interface via
4511c84c290SBarry Smith $     PetscViewerSetType(viewer,"my_viewer_type")
4521c84c290SBarry Smith    or at runtime via the option
4531c84c290SBarry Smith $     -viewer_type my_viewer_type
4541c84c290SBarry Smith 
455d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscViewerRegisterAll()`
4561c84c290SBarry Smith  @*/
457d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerRegister(const char *sname, PetscErrorCode (*function)(PetscViewer))
458d71ae5a4SJacob Faibussowitsch {
4595c6c1daeSBarry Smith   PetscFunctionBegin;
4609566063dSJacob Faibussowitsch   PetscCall(PetscViewerInitializePackage());
4619566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListAdd(&PetscViewerList, sname, function));
4623ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4635c6c1daeSBarry Smith }
4645c6c1daeSBarry Smith 
4655c6c1daeSBarry Smith /*@C
4663f423023SBarry Smith    PetscViewerSetFromOptions - Sets various options for a viewer based on values in the options database.
4675c6c1daeSBarry Smith 
468c3339decSBarry Smith    Collective
4695c6c1daeSBarry Smith 
4705c6c1daeSBarry Smith    Input Parameter:
471811af0c4SBarry Smith .     viewer - the viewer context
4725c6c1daeSBarry Smith 
4735c6c1daeSBarry Smith    Level: intermediate
4745c6c1daeSBarry Smith 
475811af0c4SBarry Smith    Note:
4763f423023SBarry Smith     Must be called after `PetscViewerCreate()` before the `PetscViewer` is used.
4775c6c1daeSBarry Smith 
478d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerCreate()`, `PetscViewerSetType()`, `PetscViewerType`
4795c6c1daeSBarry Smith @*/
480d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerSetFromOptions(PetscViewer viewer)
481d71ae5a4SJacob Faibussowitsch {
4825c6c1daeSBarry Smith   char      vtype[256];
4835c6c1daeSBarry Smith   PetscBool flg;
4845c6c1daeSBarry Smith 
4855c6c1daeSBarry Smith   PetscFunctionBegin;
4865c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
4875c6c1daeSBarry Smith 
48848a46eb9SPierre Jolivet   if (!PetscViewerList) PetscCall(PetscViewerRegisterAll());
489d0609cedSBarry Smith   PetscObjectOptionsBegin((PetscObject)viewer);
4909566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFList("-viewer_type", "Type of PetscViewer", "None", PetscViewerList, (char *)(((PetscObject)viewer)->type_name ? ((PetscObject)viewer)->type_name : PETSCVIEWERASCII), vtype, 256, &flg));
4911baa6e33SBarry Smith   if (flg) PetscCall(PetscViewerSetType(viewer, vtype));
4925c6c1daeSBarry Smith   /* type has not been set? */
49348a46eb9SPierre Jolivet   if (!((PetscObject)viewer)->type_name) PetscCall(PetscViewerSetType(viewer, PETSCVIEWERASCII));
494dbbe0bcdSBarry Smith   PetscTryTypeMethod(viewer, setfromoptions, PetscOptionsObject);
4955c6c1daeSBarry Smith 
4965c6c1daeSBarry Smith   /* process any options handlers added with PetscObjectAddOptionsHandler() */
497dbbe0bcdSBarry Smith   PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)viewer, PetscOptionsObject));
4989566063dSJacob Faibussowitsch   PetscCall(PetscViewerViewFromOptions(viewer, NULL, "-viewer_view"));
499d0609cedSBarry Smith   PetscOptionsEnd();
5003ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5015c6c1daeSBarry Smith }
502816f7b76SBarry Smith 
503d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerFlowControlStart(PetscViewer viewer, PetscInt *mcnt, PetscInt *cnt)
504d71ae5a4SJacob Faibussowitsch {
505816f7b76SBarry Smith   PetscFunctionBegin;
5069566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryGetFlowControl(viewer, mcnt));
5079566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryGetFlowControl(viewer, cnt));
5083ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
509816f7b76SBarry Smith }
510816f7b76SBarry Smith 
511d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerFlowControlStepMain(PetscViewer viewer, PetscInt i, PetscInt *mcnt, PetscInt cnt)
512d71ae5a4SJacob Faibussowitsch {
513816f7b76SBarry Smith   MPI_Comm comm;
514816f7b76SBarry Smith 
515816f7b76SBarry Smith   PetscFunctionBegin;
5169566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
517816f7b76SBarry Smith   if (i >= *mcnt) {
518816f7b76SBarry Smith     *mcnt += cnt;
5199566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Bcast(mcnt, 1, MPIU_INT, 0, comm));
520816f7b76SBarry Smith   }
5213ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
522816f7b76SBarry Smith }
523816f7b76SBarry Smith 
524d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerFlowControlEndMain(PetscViewer viewer, PetscInt *mcnt)
525d71ae5a4SJacob Faibussowitsch {
526816f7b76SBarry Smith   MPI_Comm comm;
527816f7b76SBarry Smith   PetscFunctionBegin;
5289566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
529816f7b76SBarry Smith   *mcnt = 0;
5309566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Bcast(mcnt, 1, MPIU_INT, 0, comm));
5313ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
532816f7b76SBarry Smith }
533816f7b76SBarry Smith 
534d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerFlowControlStepWorker(PetscViewer viewer, PetscMPIInt rank, PetscInt *mcnt)
535d71ae5a4SJacob Faibussowitsch {
536816f7b76SBarry Smith   MPI_Comm comm;
537816f7b76SBarry Smith   PetscFunctionBegin;
5389566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
539816f7b76SBarry Smith   while (PETSC_TRUE) {
540816f7b76SBarry Smith     if (rank < *mcnt) break;
5419566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Bcast(mcnt, 1, MPIU_INT, 0, comm));
542816f7b76SBarry Smith   }
5433ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
544816f7b76SBarry Smith }
545816f7b76SBarry Smith 
546d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerFlowControlEndWorker(PetscViewer viewer, PetscInt *mcnt)
547d71ae5a4SJacob Faibussowitsch {
548816f7b76SBarry Smith   MPI_Comm comm;
549816f7b76SBarry Smith   PetscFunctionBegin;
5509566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
551816f7b76SBarry Smith   while (PETSC_TRUE) {
5529566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Bcast(mcnt, 1, MPIU_INT, 0, comm));
553816f7b76SBarry Smith     if (!*mcnt) break;
554816f7b76SBarry Smith   }
5553ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
556816f7b76SBarry Smith }
557