xref: /petsc/src/sys/classes/viewer/interface/viewreg.c (revision 3f42302340a499d375d5639ca05dacd894fd8c16)
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 
319de0f6ecSBarry 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 
499de0f6ecSBarry Smith      Not collective
509de0f6ecSBarry Smith 
519de0f6ecSBarry Smith     Input Parameters:
529de0f6ecSBarry Smith +     hp - the object used to manage tracking what help messages have been printed
53*3f423023SBarry Smith .     pre - the prefix part of the string, many be `NULL`
54*3f423023SBarry Smith -     name - the string to look for (cannot be `NULL`)
559de0f6ecSBarry Smith 
569de0f6ecSBarry Smith     Output Parameter:
57*3f423023SBarry 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)
799566063dSJacob Faibussowitsch   PetscCall(PetscSegBufferGet(hp->strings, l1 + l2 + 1, &both));
809566063dSJacob Faibussowitsch   PetscCall(PetscStrcpy(both, pre));
819566063dSJacob Faibussowitsch   PetscCall(PetscStrcat(both, name));
829de0f6ecSBarry Smith   kh_put(HTPrinted, hp->printed, both, &newitem);
8348a46eb9SPierre Jolivet   if (!newitem) PetscCall(PetscSegBufferUnuse(hp->strings, l1 + l2 + 1));
849de0f6ecSBarry Smith   *found = newitem ? PETSC_FALSE : PETSC_TRUE;
85c1449d8eSBarry Smith #else
86c1449d8eSBarry Smith   *found = PETSC_FALSE;
87c1449d8eSBarry Smith #endif
883ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
8994d6a431SBarry Smith }
9094d6a431SBarry Smith 
91eb55bdffSLawrence Mitchell static PetscBool noviewer = PETSC_FALSE;
92eb55bdffSLawrence Mitchell static PetscBool noviewers[PETSCVIEWERGETVIEWEROFFPUSHESMAX];
93eb55bdffSLawrence Mitchell static PetscInt  inoviewers = 0;
94eb55bdffSLawrence Mitchell 
95eb55bdffSLawrence Mitchell /*@
96811af0c4SBarry Smith   PetscOptionsPushGetViewerOff - sets if a `PetscOptionsGetViewer()` returns a viewer.
97eb55bdffSLawrence Mitchell 
98eb55bdffSLawrence Mitchell   Logically Collective
99eb55bdffSLawrence Mitchell 
100eb55bdffSLawrence Mitchell   Input Parameter:
101811af0c4SBarry Smith . flg - `PETSC_TRUE` to turn off viewer creation, `PETSC_FALSE` to turn it on.
102eb55bdffSLawrence Mitchell 
103eb55bdffSLawrence Mitchell   Level: developer
104eb55bdffSLawrence Mitchell 
105811af0c4SBarry Smith   Note:
10695452b02SPatrick Sanan     Calling XXXViewFromOptions in an inner loop can be very expensive.  This can appear, for example, when using
107811af0c4SBarry Smith    many small subsolves.  Call this function to control viewer creation in `PetscOptionsGetViewer()`, thus removing the expensive XXXViewFromOptions calls.
108eb55bdffSLawrence Mitchell 
109d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscOptionsGetViewer()`, `PetscOptionsPopGetViewerOff()`
110eb55bdffSLawrence Mitchell @*/
111d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsPushGetViewerOff(PetscBool flg)
112d71ae5a4SJacob Faibussowitsch {
113eb55bdffSLawrence Mitchell   PetscFunctionBegin;
114cc73adaaSBarry Smith   PetscCheck(inoviewers < PETSCVIEWERGETVIEWEROFFPUSHESMAX, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many PetscOptionsPushGetViewerOff(), perhaps you forgot PetscOptionsPopGetViewerOff()?");
115eb55bdffSLawrence Mitchell 
116eb55bdffSLawrence Mitchell   noviewers[inoviewers++] = noviewer;
117eb55bdffSLawrence Mitchell   noviewer                = flg;
1183ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
119eb55bdffSLawrence Mitchell }
120eb55bdffSLawrence Mitchell 
121eb55bdffSLawrence Mitchell /*@
122811af0c4SBarry Smith   PetscOptionsPopGetViewerOff - reset whether `PetscOptionsGetViewer()` returns a viewer.
123eb55bdffSLawrence Mitchell 
124eb55bdffSLawrence Mitchell   Logically Collective
125eb55bdffSLawrence Mitchell 
126eb55bdffSLawrence Mitchell   Level: developer
127eb55bdffSLawrence Mitchell 
128811af0c4SBarry Smith   Note:
12995452b02SPatrick Sanan     Calling XXXViewFromOptions in an inner loop can be very expensive.  This can appear, for example, when using
130811af0c4SBarry Smith    many small subsolves.  Call this function to control viewer creation in `PetscOptionsGetViewer()`, thus removing the expensive XXXViewFromOptions calls.
131eb55bdffSLawrence Mitchell 
132d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscOptionsGetViewer()`, `PetscOptionsPushGetViewerOff()`
133eb55bdffSLawrence Mitchell @*/
134d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsPopGetViewerOff(void)
135d71ae5a4SJacob Faibussowitsch {
136eb55bdffSLawrence Mitchell   PetscFunctionBegin;
13728b400f6SJacob Faibussowitsch   PetscCheck(inoviewers, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many PetscOptionsPopGetViewerOff(), perhaps you forgot PetscOptionsPushGetViewerOff()?");
138eb55bdffSLawrence Mitchell   noviewer = noviewers[--inoviewers];
1393ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
140eb55bdffSLawrence Mitchell }
141eb55bdffSLawrence Mitchell 
142eb55bdffSLawrence Mitchell /*@
143811af0c4SBarry Smith   PetscOptionsGetViewerOff - does `PetscOptionsGetViewer()` return a viewer?
144eb55bdffSLawrence Mitchell 
145eb55bdffSLawrence Mitchell   Logically Collective
146eb55bdffSLawrence Mitchell 
147eb55bdffSLawrence Mitchell   Output Parameter:
148eb55bdffSLawrence Mitchell . flg - whether viewers are returned.
149eb55bdffSLawrence Mitchell 
150eb55bdffSLawrence Mitchell   Level: developer
151eb55bdffSLawrence Mitchell 
152811af0c4SBarry Smith   Note:
15395452b02SPatrick Sanan     Calling XXXViewFromOptions in an inner loop can be very expensive.  This can appear, for example, when using
154eb55bdffSLawrence Mitchell    many small subsolves.
155eb55bdffSLawrence Mitchell 
156d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscOptionsGetViewer()`, `PetscOptionsPushGetViewerOff()`, `PetscOptionsPopGetViewerOff()`
157eb55bdffSLawrence Mitchell @*/
158d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetViewerOff(PetscBool *flg)
159d71ae5a4SJacob Faibussowitsch {
160eb55bdffSLawrence Mitchell   PetscFunctionBegin;
161534a8f05SLisandro Dalcin   PetscValidBoolPointer(flg, 1);
162eb55bdffSLawrence Mitchell   *flg = noviewer;
1633ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
164eb55bdffSLawrence Mitchell }
165eb55bdffSLawrence Mitchell 
1662bf49c77SBarry Smith /*@C
1672bf49c77SBarry Smith    PetscOptionsGetViewer - Gets a viewer appropriate for the type indicated by the user
1682bf49c77SBarry Smith 
169d083f849SBarry Smith    Collective
1702bf49c77SBarry Smith 
1712bf49c77SBarry Smith    Input Parameters:
1722bf49c77SBarry Smith +  comm - the communicator to own the viewer
173*3f423023SBarry Smith .  options - options database, use `NULL` for default global database
174*3f423023SBarry Smith .  pre - the string to prepend to the name or `NULL`
1752bf49c77SBarry Smith -  name - the option one is seeking
1762bf49c77SBarry Smith 
177d8d19677SJose E. Roman    Output Parameters:
178*3f423023SBarry Smith +  viewer - the viewer, pass `NULL` if not needed
179*3f423023SBarry Smith .  format - the `PetscViewerFormat` requested by the user, pass `NULL` if not needed
180811af0c4SBarry Smith -  set - `PETSC_TRUE` if found, else `PETSC_FALSE`
1812bf49c77SBarry Smith 
1822bf49c77SBarry Smith    Level: intermediate
1832bf49c77SBarry Smith 
18495452b02SPatrick Sanan    Notes:
18595452b02SPatrick Sanan     If no value is provided ascii:stdout is used
186811af0c4SBarry Smith +       ascii[:[filename][:[format][:append]]]  -  defaults to stdout - format can be one of ascii_info, ascii_info_detail, or ascii_matlab,
187d1da0b69SBarry Smith                                                   for example ascii::ascii_info prints just the information about the object not all details
188d1da0b69SBarry Smith                                                   unless :append is given filename opens in write mode, overwriting what was already there
189811af0c4SBarry Smith .       binary[:[filename][:[format][:append]]] -  defaults to the file binaryoutput
190811af0c4SBarry Smith .       draw[:drawtype[:filename]]              -  for example, draw:tikz, draw:tikz:figure.tex  or draw:x
191811af0c4SBarry Smith .       socket[:port]                           -  defaults to the standard output port
192811af0c4SBarry Smith -       saws[:communicatorname]                 -   publishes object to the Scientific Application Webserver (SAWs)
1932bf49c77SBarry Smith 
194811af0c4SBarry Smith    Use `PetscViewerDestroy()` after using the viewer, otherwise a memory leak will occur
1952bf49c77SBarry Smith 
196811af0c4SBarry Smith    You can control whether calls to this function create a viewer (or return early with *set of `PETSC_FALSE`) with
197811af0c4SBarry Smith    `PetscOptionsPushGetViewerOff()`.  This is useful if calling many small subsolves, in which case XXXViewFromOptions can take
198eb55bdffSLawrence Mitchell    an appreciable fraction of the runtime.
199eb55bdffSLawrence Mitchell 
200*3f423023SBarry Smith    If PETSc is configured with `--with-viewfromoptions=0` this function always returns with *set of `PETSC_FALSE`
20127b0f280SBarry Smith 
202d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
203db781477SPatrick Sanan           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
204db781477SPatrick Sanan           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsBool()`,
205db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
206c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
207db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
208db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsPushGetViewerOff()`, `PetscOptionsPopGetViewerOff()`,
209db781477SPatrick Sanan           `PetscOptionsGetViewerOff()`
2102bf49c77SBarry Smith @*/
211d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetViewer(MPI_Comm comm, PetscOptions options, const char pre[], const char name[], PetscViewer *viewer, PetscViewerFormat *format, PetscBool *set)
212d71ae5a4SJacob Faibussowitsch {
2132d747510SLisandro Dalcin   const char *value;
21420610d12SBarry Smith   PetscBool   flag, hashelp;
2152bf49c77SBarry Smith 
2162bf49c77SBarry Smith   PetscFunctionBegin;
217064a246eSJacob Faibussowitsch   PetscValidCharPointer(name, 4);
2182bf49c77SBarry Smith 
2196348e711SLisandro Dalcin   if (viewer) *viewer = NULL;
2206348e711SLisandro Dalcin   if (format) *format = PETSC_VIEWER_DEFAULT;
22127b0f280SBarry Smith   if (set) *set = PETSC_FALSE;
2229566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetViewerOff(&flag));
2233ba16761SJacob Faibussowitsch   if (flag) PetscFunctionReturn(PETSC_SUCCESS);
22427b0f280SBarry Smith 
2259566063dSJacob Faibussowitsch   PetscCall(PetscOptionsHasHelp(NULL, &hashelp));
22620610d12SBarry Smith   if (hashelp) {
2279de0f6ecSBarry Smith     PetscBool found;
2289af95d99SBarry Smith 
22948a46eb9SPierre Jolivet     if (!PetscOptionsHelpPrintedSingleton) PetscCall(PetscOptionsHelpPrintedCreate(&PetscOptionsHelpPrintedSingleton));
2309566063dSJacob Faibussowitsch     PetscCall(PetscOptionsHelpPrintedCheck(PetscOptionsHelpPrintedSingleton, pre, name, &found));
23156071f75SVaclav Hapla     if (!found && viewer) {
2329566063dSJacob Faibussowitsch       PetscCall((*PetscHelpPrintf)(comm, "----------------------------------------\nViewer (-%s%s) options:\n", pre ? pre : "", name + 1));
2339566063dSJacob 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"));
2349566063dSJacob Faibussowitsch       PetscCall((*PetscHelpPrintf)(comm, "  -%s%s binary[:[filename][:[format][:append]]]: %s (%s)\n", pre ? pre : "", name + 1, "Saves object to a binary file", "PetscOptionsGetViewer"));
2359566063dSJacob Faibussowitsch       PetscCall((*PetscHelpPrintf)(comm, "  -%s%s draw[:[drawtype][:filename|format]] %s (%s)\n", pre ? pre : "", name + 1, "Draws object", "PetscOptionsGetViewer"));
2369566063dSJacob Faibussowitsch       PetscCall((*PetscHelpPrintf)(comm, "  -%s%s socket[:port]: %s (%s)\n", pre ? pre : "", name + 1, "Pushes object to a Unix socket", "PetscOptionsGetViewer"));
2379566063dSJacob Faibussowitsch       PetscCall((*PetscHelpPrintf)(comm, "  -%s%s saws[:communicatorname]: %s (%s)\n", pre ? pre : "", name + 1, "Publishes object to SAWs", "PetscOptionsGetViewer"));
23894d6a431SBarry Smith     }
23920610d12SBarry Smith   }
240685405a1SBarry Smith 
241e3f3e4b6SBarry Smith   if (format) *format = PETSC_VIEWER_DEFAULT;
2429566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2432bf49c77SBarry Smith   if (flag) {
2442bf49c77SBarry Smith     if (set) *set = PETSC_TRUE;
2452bf49c77SBarry Smith     if (!value) {
246bb1d7374SBarry Smith       if (viewer) {
2479566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIGetStdout(comm, viewer));
2489566063dSJacob Faibussowitsch         PetscCall(PetscObjectReference((PetscObject)*viewer));
249bb1d7374SBarry Smith       }
2502bf49c77SBarry Smith     } else {
251bbcf679cSJacob Faibussowitsch       char       *loc0_vtype = NULL, *loc1_fname = NULL, *loc2_fmt = NULL, *loc3_fmode = NULL;
2522bf49c77SBarry Smith       PetscInt    cnt;
2531e50132fSMatthew G. Knepley       const char *viewers[] = {PETSCVIEWERASCII, PETSCVIEWERBINARY, PETSCVIEWERDRAW, PETSCVIEWERSOCKET, PETSCVIEWERMATLAB, PETSCVIEWERSAWS, PETSCVIEWERVTK, PETSCVIEWERHDF5, PETSCVIEWERGLVIS, PETSCVIEWEREXODUSII, NULL};
2542bf49c77SBarry Smith 
2559566063dSJacob Faibussowitsch       PetscCall(PetscStrallocpy(value, &loc0_vtype));
2569566063dSJacob Faibussowitsch       PetscCall(PetscStrchr(loc0_vtype, ':', &loc1_fname));
25735d27ee3SJed Brown       if (loc1_fname) {
25835d27ee3SJed Brown         *loc1_fname++ = 0;
2599566063dSJacob Faibussowitsch         PetscCall(PetscStrchr(loc1_fname, ':', &loc2_fmt));
26035d27ee3SJed Brown       }
26135d27ee3SJed Brown       if (loc2_fmt) {
26235d27ee3SJed Brown         *loc2_fmt++ = 0;
2639566063dSJacob Faibussowitsch         PetscCall(PetscStrchr(loc2_fmt, ':', &loc3_fmode));
26435d27ee3SJed Brown       }
26535d27ee3SJed Brown       if (loc3_fmode) *loc3_fmode++ = 0;
2669566063dSJacob Faibussowitsch       PetscCall(PetscStrendswithwhich(*loc0_vtype ? loc0_vtype : "ascii", viewers, &cnt));
26708401ef6SPierre Jolivet       PetscCheck(cnt <= (PetscInt)sizeof(viewers) - 1, comm, PETSC_ERR_ARG_OUTOFRANGE, "Unknown viewer type: %s", loc0_vtype);
268bb1d7374SBarry Smith       if (viewer) {
26935d27ee3SJed Brown         if (!loc1_fname) {
27043b63833SBarry Smith           switch (cnt) {
271d71ae5a4SJacob Faibussowitsch           case 0:
272d71ae5a4SJacob Faibussowitsch             PetscCall(PetscViewerASCIIGetStdout(comm, viewer));
273d71ae5a4SJacob Faibussowitsch             break;
27443b63833SBarry Smith           case 1:
2759566063dSJacob Faibussowitsch             if (!(*viewer = PETSC_VIEWER_BINARY_(comm))) PetscCall(PETSC_ERR_PLIB);
27643b63833SBarry Smith             break;
27743b63833SBarry Smith           case 2:
2789566063dSJacob Faibussowitsch             if (!(*viewer = PETSC_VIEWER_DRAW_(comm))) PetscCall(PETSC_ERR_PLIB);
27943b63833SBarry Smith             break;
280b58ca069SBarry Smith #if defined(PETSC_USE_SOCKET_VIEWER)
28143b63833SBarry Smith           case 3:
2829566063dSJacob Faibussowitsch             if (!(*viewer = PETSC_VIEWER_SOCKET_(comm))) PetscCall(PETSC_ERR_PLIB);
28343b63833SBarry Smith             break;
284b58ca069SBarry Smith #endif
285d1e78c4fSBarry Smith #if defined(PETSC_HAVE_MATLAB)
28643b63833SBarry Smith           case 4:
2879566063dSJacob Faibussowitsch             if (!(*viewer = PETSC_VIEWER_MATLAB_(comm))) PetscCall(PETSC_ERR_PLIB);
28843b63833SBarry Smith             break;
28943b63833SBarry Smith #endif
290e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS)
291bfb97211SBarry Smith           case 5:
2929566063dSJacob Faibussowitsch             if (!(*viewer = PETSC_VIEWER_SAWS_(comm))) PetscCall(PETSC_ERR_PLIB);
293bfb97211SBarry Smith             break;
294bfb97211SBarry Smith #endif
295a75e6a4aSMatthew G. Knepley #if defined(PETSC_HAVE_HDF5)
296a75e6a4aSMatthew G. Knepley           case 7:
2979566063dSJacob Faibussowitsch             if (!(*viewer = PETSC_VIEWER_HDF5_(comm))) PetscCall(PETSC_ERR_PLIB);
298a75e6a4aSMatthew G. Knepley             break;
299a75e6a4aSMatthew G. Knepley #endif
3008135c375SStefano Zampini           case 8:
3019566063dSJacob Faibussowitsch             if (!(*viewer = PETSC_VIEWER_GLVIS_(comm))) PetscCall(PETSC_ERR_PLIB);
3028135c375SStefano Zampini             break;
3031e50132fSMatthew G. Knepley #if defined(PETSC_HAVE_EXODUSII)
3041e50132fSMatthew G. Knepley           case 9:
3059566063dSJacob Faibussowitsch             if (!(*viewer = PETSC_VIEWER_EXODUSII_(comm))) PetscCall(PETSC_ERR_PLIB);
3061e50132fSMatthew G. Knepley             break;
3071e50132fSMatthew G. Knepley #endif
308d71ae5a4SJacob Faibussowitsch           default:
309d71ae5a4SJacob Faibussowitsch             SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Unsupported viewer %s", loc0_vtype);
3107f677774SBarry Smith           }
3119566063dSJacob Faibussowitsch           PetscCall(PetscObjectReference((PetscObject)*viewer));
3127f677774SBarry Smith         } else {
31335d27ee3SJed Brown           if (loc2_fmt && !*loc1_fname && (cnt == 0)) { /* ASCII format without file name */
3149566063dSJacob Faibussowitsch             PetscCall(PetscViewerASCIIGetStdout(comm, viewer));
3159566063dSJacob Faibussowitsch             PetscCall(PetscObjectReference((PetscObject)*viewer));
3167f677774SBarry Smith           } else {
3173550efbcSJed Brown             PetscFileMode fmode;
3189566063dSJacob Faibussowitsch             PetscCall(PetscViewerCreate(comm, viewer));
3199566063dSJacob Faibussowitsch             PetscCall(PetscViewerSetType(*viewer, *loc0_vtype ? loc0_vtype : "ascii"));
3203550efbcSJed Brown             fmode = FILE_MODE_WRITE;
3213550efbcSJed Brown             if (loc3_fmode && *loc3_fmode) { /* Has non-empty file mode ("write" or "append") */
3229566063dSJacob Faibussowitsch               PetscCall(PetscEnumFind(PetscFileModes, loc3_fmode, (PetscEnum *)&fmode, &flag));
32328b400f6SJacob Faibussowitsch               PetscCheck(flag, comm, PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown file mode: %s", loc3_fmode);
3247f677774SBarry Smith             }
325acd7d2deSBarry Smith             if (loc2_fmt) {
3260ecfd9fcSLisandro Dalcin               PetscBool tk, im;
3279566063dSJacob Faibussowitsch               PetscCall(PetscStrcmp(loc1_fname, "tikz", &tk));
3289566063dSJacob Faibussowitsch               PetscCall(PetscStrcmp(loc1_fname, "image", &im));
3290ecfd9fcSLisandro Dalcin               if (tk || im) {
3309566063dSJacob Faibussowitsch                 PetscCall(PetscViewerDrawSetInfo(*viewer, NULL, loc2_fmt, PETSC_DECIDE, PETSC_DECIDE, PETSC_DECIDE, PETSC_DECIDE));
331acd7d2deSBarry Smith                 *loc2_fmt = 0;
332acd7d2deSBarry Smith               }
333acd7d2deSBarry Smith             }
3349566063dSJacob Faibussowitsch             PetscCall(PetscViewerFileSetMode(*viewer, flag ? fmode : FILE_MODE_WRITE));
3359566063dSJacob Faibussowitsch             PetscCall(PetscViewerFileSetName(*viewer, loc1_fname));
3361baa6e33SBarry Smith             if (*loc1_fname) PetscCall(PetscViewerDrawSetDrawType(*viewer, loc1_fname));
3379566063dSJacob Faibussowitsch             PetscCall(PetscViewerSetFromOptions(*viewer));
33805315717SToby Isaac           }
339bb1d7374SBarry Smith         }
34052f76066SLisandro Dalcin       }
3411baa6e33SBarry Smith       if (viewer) PetscCall(PetscViewerSetUp(*viewer));
34235d27ee3SJed Brown       if (loc2_fmt && *loc2_fmt) {
343e156c29bSStefano Zampini         PetscViewerFormat tfmt;
344d6acdc46SStefano Zampini 
3459566063dSJacob Faibussowitsch         PetscCall(PetscEnumFind(PetscViewerFormats, loc2_fmt, (PetscEnum *)&tfmt, &flag));
346d6acdc46SStefano Zampini         if (format) *format = tfmt;
34728b400f6SJacob Faibussowitsch         PetscCheck(flag, PETSC_COMM_SELF, PETSC_ERR_SUP, "Unknown viewer format %s", loc2_fmt);
348d6acdc46SStefano Zampini       } else if (viewer && (cnt == 6) && format) { /* Get format from VTK viewer */
3499566063dSJacob Faibussowitsch         PetscCall(PetscViewerGetFormat(*viewer, format));
3507f677774SBarry Smith       }
3519566063dSJacob Faibussowitsch       PetscCall(PetscFree(loc0_vtype));
3522bf49c77SBarry Smith     }
3532bf49c77SBarry Smith   }
3543ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3552bf49c77SBarry Smith }
3562bf49c77SBarry Smith 
3575c6c1daeSBarry Smith /*@
358811af0c4SBarry 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
3595c6c1daeSBarry Smith 
360d083f849SBarry Smith    Collective
3615c6c1daeSBarry Smith 
3625c6c1daeSBarry Smith    Input Parameter:
3635c6c1daeSBarry Smith .  comm - MPI communicator
3645c6c1daeSBarry Smith 
3655c6c1daeSBarry Smith    Output Parameter:
366811af0c4SBarry Smith .  inviewer - location to put the `PetscViewer` context
3675c6c1daeSBarry Smith 
3685c6c1daeSBarry Smith    Level: advanced
3695c6c1daeSBarry Smith 
370d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerType`
3715c6c1daeSBarry Smith @*/
372d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerCreate(MPI_Comm comm, PetscViewer *inviewer)
373d71ae5a4SJacob Faibussowitsch {
3745c6c1daeSBarry Smith   PetscViewer viewer;
3755c6c1daeSBarry Smith 
3765c6c1daeSBarry Smith   PetscFunctionBegin;
37702c9f0b5SLisandro Dalcin   *inviewer = NULL;
3789566063dSJacob Faibussowitsch   PetscCall(PetscViewerInitializePackage());
3799566063dSJacob Faibussowitsch   PetscCall(PetscHeaderCreate(viewer, PETSC_VIEWER_CLASSID, "PetscViewer", "PetscViewer", "Viewer", comm, PetscViewerDestroy, PetscViewerView));
3805c6c1daeSBarry Smith   *inviewer    = viewer;
38102c9f0b5SLisandro Dalcin   viewer->data = NULL;
3823ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3835c6c1daeSBarry Smith }
3845c6c1daeSBarry Smith 
3855c6c1daeSBarry Smith /*@C
386811af0c4SBarry Smith    PetscViewerSetType - Builds `PetscViewer` for a particular implementation.
3875c6c1daeSBarry Smith 
388c3339decSBarry Smith    Collective
3895c6c1daeSBarry Smith 
390d8d19677SJose E. Roman    Input Parameters:
391811af0c4SBarry Smith +  viewer      - the `PetscViewer` context obtained with `PetscViewerCreate()`
392811af0c4SBarry Smith -  type        - for example, `PETSCVIEWERASCII`
3935c6c1daeSBarry Smith 
3943c7db156SBarry Smith    Options Database Key:
3953c7db156SBarry Smith .  -viewer_type  <type> - Sets the type; use -help for a list of available methods (for instance, ascii)
3965c6c1daeSBarry Smith 
3975c6c1daeSBarry Smith    Level: advanced
3985c6c1daeSBarry Smith 
399811af0c4SBarry Smith    Note:
400*3f423023SBarry Smith    See `PetscViewerType` for possible values
4015c6c1daeSBarry Smith 
402d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerCreate()`, `PetscViewerGetType()`, `PetscViewerType`, `PetscViewerPushFormat()`
4035c6c1daeSBarry Smith @*/
404d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerSetType(PetscViewer viewer, PetscViewerType type)
405d71ae5a4SJacob Faibussowitsch {
4065c6c1daeSBarry Smith   PetscBool match;
4075f80ce2aSJacob Faibussowitsch   PetscErrorCode (*r)(PetscViewer);
4085c6c1daeSBarry Smith 
4095c6c1daeSBarry Smith   PetscFunctionBegin;
4105c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
4115c6c1daeSBarry Smith   PetscValidCharPointer(type, 2);
4129566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, type, &match));
4133ba16761SJacob Faibussowitsch   if (match) PetscFunctionReturn(PETSC_SUCCESS);
4145c6c1daeSBarry Smith 
4155c6c1daeSBarry Smith   /* cleanup any old type that may be there */
416dbbe0bcdSBarry Smith   PetscTryTypeMethod(viewer, destroy);
4170298fd71SBarry Smith   viewer->ops->destroy = NULL;
41802c9f0b5SLisandro Dalcin   viewer->data         = NULL;
419dbbe0bcdSBarry Smith 
4209566063dSJacob Faibussowitsch   PetscCall(PetscMemzero(viewer->ops, sizeof(struct _PetscViewerOps)));
4215c6c1daeSBarry Smith 
4229566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListFind(PetscViewerList, type, &r));
42328b400f6SJacob Faibussowitsch   PetscCheck(r, PETSC_COMM_SELF, PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscViewer type given: %s", type);
4245c6c1daeSBarry Smith 
4259566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)viewer, type));
4269566063dSJacob Faibussowitsch   PetscCall((*r)(viewer));
4273ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4285c6c1daeSBarry Smith }
4295c6c1daeSBarry Smith 
4301c84c290SBarry Smith /*@C
431811af0c4SBarry Smith    PetscViewerRegister - Adds a viewer to those available for use
4321c84c290SBarry Smith 
4331c84c290SBarry Smith    Not Collective
4341c84c290SBarry Smith 
4351c84c290SBarry Smith    Input Parameters:
4361c84c290SBarry Smith +  name_solver - name of a new user-defined viewer
4371c84c290SBarry Smith -  routine_create - routine to create method context
4381c84c290SBarry Smith 
4391c84c290SBarry Smith    Level: developer
440811af0c4SBarry Smith 
441811af0c4SBarry Smith    Note:
442811af0c4SBarry Smith    `PetscViewerRegister()` may be called multiple times to add several user-defined viewers.
4431c84c290SBarry Smith 
4441c84c290SBarry Smith    Sample usage:
4451c84c290SBarry Smith .vb
446bdf89e91SBarry Smith    PetscViewerRegister("my_viewer_type",MyViewerCreate);
4471c84c290SBarry Smith .ve
4481c84c290SBarry Smith 
4491c84c290SBarry Smith    Then, your solver can be chosen with the procedural interface via
4501c84c290SBarry Smith $     PetscViewerSetType(viewer,"my_viewer_type")
4511c84c290SBarry Smith    or at runtime via the option
4521c84c290SBarry Smith $     -viewer_type my_viewer_type
4531c84c290SBarry Smith 
454d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscViewerRegisterAll()`
4551c84c290SBarry Smith  @*/
456d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerRegister(const char *sname, PetscErrorCode (*function)(PetscViewer))
457d71ae5a4SJacob Faibussowitsch {
4585c6c1daeSBarry Smith   PetscFunctionBegin;
4599566063dSJacob Faibussowitsch   PetscCall(PetscViewerInitializePackage());
4609566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListAdd(&PetscViewerList, sname, function));
4613ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4625c6c1daeSBarry Smith }
4635c6c1daeSBarry Smith 
4645c6c1daeSBarry Smith /*@C
465*3f423023SBarry Smith    PetscViewerSetFromOptions - Sets various options for a viewer based on values in the options database.
4665c6c1daeSBarry Smith 
467c3339decSBarry Smith    Collective
4685c6c1daeSBarry Smith 
4695c6c1daeSBarry Smith    Input Parameter:
470811af0c4SBarry Smith .     viewer - the viewer context
4715c6c1daeSBarry Smith 
4725c6c1daeSBarry Smith    Level: intermediate
4735c6c1daeSBarry Smith 
474811af0c4SBarry Smith    Note:
475*3f423023SBarry Smith     Must be called after `PetscViewerCreate()` before the `PetscViewer` is used.
4765c6c1daeSBarry Smith 
477d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerCreate()`, `PetscViewerSetType()`, `PetscViewerType`
4785c6c1daeSBarry Smith @*/
479d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerSetFromOptions(PetscViewer viewer)
480d71ae5a4SJacob Faibussowitsch {
4815c6c1daeSBarry Smith   char      vtype[256];
4825c6c1daeSBarry Smith   PetscBool flg;
4835c6c1daeSBarry Smith 
4845c6c1daeSBarry Smith   PetscFunctionBegin;
4855c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
4865c6c1daeSBarry Smith 
48748a46eb9SPierre Jolivet   if (!PetscViewerList) PetscCall(PetscViewerRegisterAll());
488d0609cedSBarry Smith   PetscObjectOptionsBegin((PetscObject)viewer);
4899566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFList("-viewer_type", "Type of PetscViewer", "None", PetscViewerList, (char *)(((PetscObject)viewer)->type_name ? ((PetscObject)viewer)->type_name : PETSCVIEWERASCII), vtype, 256, &flg));
4901baa6e33SBarry Smith   if (flg) PetscCall(PetscViewerSetType(viewer, vtype));
4915c6c1daeSBarry Smith   /* type has not been set? */
49248a46eb9SPierre Jolivet   if (!((PetscObject)viewer)->type_name) PetscCall(PetscViewerSetType(viewer, PETSCVIEWERASCII));
493dbbe0bcdSBarry Smith   PetscTryTypeMethod(viewer, setfromoptions, PetscOptionsObject);
4945c6c1daeSBarry Smith 
4955c6c1daeSBarry Smith   /* process any options handlers added with PetscObjectAddOptionsHandler() */
496dbbe0bcdSBarry Smith   PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)viewer, PetscOptionsObject));
4979566063dSJacob Faibussowitsch   PetscCall(PetscViewerViewFromOptions(viewer, NULL, "-viewer_view"));
498d0609cedSBarry Smith   PetscOptionsEnd();
4993ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5005c6c1daeSBarry Smith }
501816f7b76SBarry Smith 
502d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerFlowControlStart(PetscViewer viewer, PetscInt *mcnt, PetscInt *cnt)
503d71ae5a4SJacob Faibussowitsch {
504816f7b76SBarry Smith   PetscFunctionBegin;
5059566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryGetFlowControl(viewer, mcnt));
5069566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryGetFlowControl(viewer, cnt));
5073ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
508816f7b76SBarry Smith }
509816f7b76SBarry Smith 
510d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerFlowControlStepMain(PetscViewer viewer, PetscInt i, PetscInt *mcnt, PetscInt cnt)
511d71ae5a4SJacob Faibussowitsch {
512816f7b76SBarry Smith   MPI_Comm comm;
513816f7b76SBarry Smith 
514816f7b76SBarry Smith   PetscFunctionBegin;
5159566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
516816f7b76SBarry Smith   if (i >= *mcnt) {
517816f7b76SBarry Smith     *mcnt += cnt;
5189566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Bcast(mcnt, 1, MPIU_INT, 0, comm));
519816f7b76SBarry Smith   }
5203ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
521816f7b76SBarry Smith }
522816f7b76SBarry Smith 
523d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerFlowControlEndMain(PetscViewer viewer, PetscInt *mcnt)
524d71ae5a4SJacob Faibussowitsch {
525816f7b76SBarry Smith   MPI_Comm comm;
526816f7b76SBarry Smith   PetscFunctionBegin;
5279566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
528816f7b76SBarry Smith   *mcnt = 0;
5299566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Bcast(mcnt, 1, MPIU_INT, 0, comm));
5303ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
531816f7b76SBarry Smith }
532816f7b76SBarry Smith 
533d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerFlowControlStepWorker(PetscViewer viewer, PetscMPIInt rank, PetscInt *mcnt)
534d71ae5a4SJacob Faibussowitsch {
535816f7b76SBarry Smith   MPI_Comm comm;
536816f7b76SBarry Smith   PetscFunctionBegin;
5379566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
538816f7b76SBarry Smith   while (PETSC_TRUE) {
539816f7b76SBarry Smith     if (rank < *mcnt) break;
5409566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Bcast(mcnt, 1, MPIU_INT, 0, comm));
541816f7b76SBarry Smith   }
5423ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
543816f7b76SBarry Smith }
544816f7b76SBarry Smith 
545d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerFlowControlEndWorker(PetscViewer viewer, PetscInt *mcnt)
546d71ae5a4SJacob Faibussowitsch {
547816f7b76SBarry Smith   MPI_Comm comm;
548816f7b76SBarry Smith   PetscFunctionBegin;
5499566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
550816f7b76SBarry Smith   while (PETSC_TRUE) {
5519566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Bcast(mcnt, 1, MPIU_INT, 0, comm));
552816f7b76SBarry Smith     if (!*mcnt) break;
553816f7b76SBarry Smith   }
5543ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
555816f7b76SBarry Smith }
556