Actual source code: viewreg.c
1: #include <petsc/private/viewerimpl.h>
2: #include <petsc/private/hashtable.h>
3: #if defined(PETSC_HAVE_SAWS)
4: #include <petscviewersaws.h>
5: #endif
7: PetscFunctionList PetscViewerList = NULL;
9: PetscOptionsHelpPrinted PetscOptionsHelpPrintedSingleton = NULL;
10: KHASH_SET_INIT_STR(HTPrinted)
11: struct _n_PetscOptionsHelpPrinted {
12: khash_t(HTPrinted) *printed;
13: PetscSegBuffer strings;
14: };
16: PetscErrorCode PetscOptionsHelpPrintedDestroy(PetscOptionsHelpPrinted *hp)
17: {
18: PetscFunctionBegin;
19: if (!*hp) PetscFunctionReturn(PETSC_SUCCESS);
20: kh_destroy(HTPrinted, (*hp)->printed);
21: PetscCall(PetscSegBufferDestroy(&(*hp)->strings));
22: PetscCall(PetscFree(*hp));
23: PetscFunctionReturn(PETSC_SUCCESS);
24: }
26: /*@C
27: PetscOptionsHelpPrintedCreate - Creates an object used to manage tracking which help messages have
28: been printed so they will not be printed again.
30: Output Parameter:
31: . hp - the created object
33: Not Collective
35: Level: developer
37: .seealso: `PetscOptionsHelpPrintedCheck()`, `PetscOptionsHelpPrintChecked()`
38: @*/
39: PetscErrorCode PetscOptionsHelpPrintedCreate(PetscOptionsHelpPrinted *hp)
40: {
41: PetscFunctionBegin;
42: PetscCall(PetscNew(hp));
43: (*hp)->printed = kh_init(HTPrinted);
44: PetscCall(PetscSegBufferCreate(sizeof(char), 10000, &(*hp)->strings));
45: PetscFunctionReturn(PETSC_SUCCESS);
46: }
48: /*@C
49: PetscOptionsHelpPrintedCheck - Checks if a particular pre, name pair has previous been entered (meaning the help message was printed)
51: Not Collective
53: Input Parameters:
54: + hp - the object used to manage tracking what help messages have been printed
55: . pre - the prefix part of the string, many be `NULL`
56: - name - the string to look for (cannot be `NULL`)
58: Output Parameter:
59: . found - `PETSC_TRUE` if the string was already set
61: Level: intermediate
63: .seealso: `PetscOptionsHelpPrintedCreate()`
64: @*/
65: PetscErrorCode PetscOptionsHelpPrintedCheck(PetscOptionsHelpPrinted hp, const char *pre, const char *name, PetscBool *found)
66: {
67: size_t l1, l2;
68: #if !defined(PETSC_HAVE_THREADSAFETY)
69: char *both;
70: int newitem;
71: #endif
73: PetscFunctionBegin;
74: PetscCall(PetscStrlen(pre, &l1));
75: PetscCall(PetscStrlen(name, &l2));
76: if (l1 + l2 == 0) {
77: *found = PETSC_FALSE;
78: PetscFunctionReturn(PETSC_SUCCESS);
79: }
80: #if !defined(PETSC_HAVE_THREADSAFETY)
81: size_t lboth = l1 + l2 + 1;
82: PetscCall(PetscSegBufferGet(hp->strings, lboth, &both));
83: PetscCall(PetscStrncpy(both, pre, lboth));
84: PetscCall(PetscStrncpy(both + l1, name, l2 + 1));
85: kh_put(HTPrinted, hp->printed, both, &newitem);
86: if (!newitem) PetscCall(PetscSegBufferUnuse(hp->strings, lboth));
87: *found = newitem ? PETSC_FALSE : PETSC_TRUE;
88: #else
89: *found = PETSC_FALSE;
90: #endif
91: PetscFunctionReturn(PETSC_SUCCESS);
92: }
94: static PetscBool noviewer = PETSC_FALSE;
95: static PetscBool noviewers[PETSCVIEWERCREATEVIEWEROFFPUSHESMAX];
96: static PetscInt inoviewers = 0;
98: /*@
99: PetscOptionsPushCreateViewerOff - sets if a `PetscOptionsCreateViewer()`, `PetscOptionsViewer(), and `PetscOptionsCreateViewers()` returns viewers.
101: Logically Collective
103: Input Parameter:
104: . flg - `PETSC_TRUE` to turn off viewer creation, `PETSC_FALSE` to turn it on.
106: Level: developer
108: Note:
109: Calling `XXXViewFromOptions` in an inner loop can be expensive. This can appear, for example, when using
110: many small subsolves. Call this function to control viewer creation in `PetscOptionsCreateViewer()`, thus removing the expensive `XXXViewFromOptions` calls.
112: Developer Notes:
113: Instead of using this approach, the calls to `PetscOptionsCreateViewer()` can be moved into `XXXSetFromOptions()`
115: .seealso: [](sec_viewers), `PetscOptionsCreateViewer()`, `PetscOptionsPopCreateViewerOff()`
116: @*/
117: PetscErrorCode PetscOptionsPushCreateViewerOff(PetscBool flg)
118: {
119: PetscFunctionBegin;
120: PetscCheck(inoviewers < PETSCVIEWERCREATEVIEWEROFFPUSHESMAX, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many PetscOptionsPushCreateViewerOff(), perhaps you forgot PetscOptionsPopCreateViewerOff()?");
122: noviewers[inoviewers++] = noviewer;
123: noviewer = flg;
124: PetscFunctionReturn(PETSC_SUCCESS);
125: }
127: /*@
128: PetscOptionsPopCreateViewerOff - reset whether `PetscOptionsCreateViewer()` returns a viewer.
130: Logically Collective
132: Level: developer
134: Note:
135: See `PetscOptionsPushCreateViewerOff()`
137: .seealso: [](sec_viewers), `PetscOptionsCreateViewer()`, `PetscOptionsPushCreateViewerOff()`
138: @*/
139: PetscErrorCode PetscOptionsPopCreateViewerOff(void)
140: {
141: PetscFunctionBegin;
142: PetscCheck(inoviewers, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many PetscOptionsPopCreateViewerOff(), perhaps you forgot PetscOptionsPushCreateViewerOff()?");
143: noviewer = noviewers[--inoviewers];
144: PetscFunctionReturn(PETSC_SUCCESS);
145: }
147: /*@
148: PetscOptionsGetCreateViewerOff - do `PetscOptionsCreateViewer()`, `PetscOptionsViewer(), and `PetscOptionsCreateViewers()` return viewers
150: Logically Collective
152: Output Parameter:
153: . flg - whether viewers are returned.
155: Level: developer
157: .seealso: [](sec_viewers), `PetscOptionsCreateViewer()`, `PetscOptionsPushCreateViewerOff()`, `PetscOptionsPopCreateViewerOff()`
158: @*/
159: PetscErrorCode PetscOptionsGetCreateViewerOff(PetscBool *flg)
160: {
161: PetscFunctionBegin;
162: PetscAssertPointer(flg, 1);
163: *flg = noviewer;
164: PetscFunctionReturn(PETSC_SUCCESS);
165: }
167: static PetscErrorCode PetscOptionsCreateViewers_Single(MPI_Comm comm, const char value[], PetscViewer *viewer, PetscViewerFormat *format)
168: {
169: char *loc0_vtype = NULL, *loc1_fname = NULL, *loc2_fmt = NULL, *loc3_fmode = NULL;
170: PetscInt cnt;
171: size_t viewer_string_length;
172: const char *viewers[] = {PETSCVIEWERASCII, PETSCVIEWERBINARY, PETSCVIEWERDRAW, PETSCVIEWERSOCKET, PETSCVIEWERMATLAB, PETSCVIEWERSAWS, PETSCVIEWERVTK, PETSCVIEWERHDF5, PETSCVIEWERGLVIS, PETSCVIEWEREXODUSII, PETSCVIEWERPYTHON, PETSCVIEWERPYVISTA, NULL}; /* list should be automatically generated from PetscViewersList */
174: PetscFunctionBegin;
175: PetscCall(PetscStrlen(value, &viewer_string_length));
176: if (!viewer_string_length) {
177: if (format) *format = PETSC_VIEWER_DEFAULT;
178: if (viewer) {
179: PetscCall(PetscViewerASCIIGetStdout(comm, viewer));
180: PetscCall(PetscObjectReference((PetscObject)*viewer));
181: }
182: PetscFunctionReturn(PETSC_SUCCESS);
183: }
185: PetscCall(PetscStrallocpy(value, &loc0_vtype));
186: PetscCall(PetscStrchr(loc0_vtype, ':', &loc1_fname));
187: if (loc1_fname) {
188: PetscBool is_daos;
189: *loc1_fname++ = 0;
190: // When using DAOS, the filename will have the form "daos:/path/to/file.h5", so capture the rest of it.
191: PetscCall(PetscStrncmp(loc1_fname, "daos:", 5, &is_daos));
192: PetscCall(PetscStrchr(loc1_fname + (is_daos == PETSC_TRUE ? 5 : 0), ':', &loc2_fmt));
193: }
194: if (loc2_fmt) {
195: *loc2_fmt++ = 0;
196: PetscCall(PetscStrchr(loc2_fmt, ':', &loc3_fmode));
197: }
198: if (loc3_fmode) *loc3_fmode++ = 0;
199: PetscCall(PetscStrendswithwhich(*loc0_vtype ? loc0_vtype : "ascii", viewers, &cnt));
200: PetscCheck(cnt <= (PetscInt)sizeof(viewers) - 1, comm, PETSC_ERR_ARG_OUTOFRANGE, "Unknown viewer type: %s", loc0_vtype);
201: if (viewer) {
202: if (!loc1_fname) {
203: switch (cnt) {
204: case 0:
205: PetscCall(PetscViewerASCIIGetStdout(comm, viewer));
206: PetscCall(PetscObjectReference((PetscObject)*viewer));
207: break;
208: case 1:
209: if (!(*viewer = PETSC_VIEWER_BINARY_(comm))) PetscCall(PETSC_ERR_PLIB);
210: PetscCall(PetscObjectReference((PetscObject)*viewer));
211: break;
212: case 2:
213: if (!(*viewer = PETSC_VIEWER_DRAW_(comm))) PetscCall(PETSC_ERR_PLIB);
214: PetscCall(PetscObjectReference((PetscObject)*viewer));
215: break;
216: #if defined(PETSC_USE_SOCKET_VIEWER)
217: case 3:
218: if (!(*viewer = PETSC_VIEWER_SOCKET_(comm))) PetscCall(PETSC_ERR_PLIB);
219: PetscCall(PetscObjectReference((PetscObject)*viewer));
220: break;
221: #endif
222: #if defined(PETSC_HAVE_MATLAB)
223: case 4:
224: if (!(*viewer = PETSC_VIEWER_MATLAB_(comm))) PetscCall(PETSC_ERR_PLIB);
225: PetscCall(PetscObjectReference((PetscObject)*viewer));
226: break;
227: #endif
228: #if defined(PETSC_HAVE_SAWS)
229: case 5:
230: if (!(*viewer = PETSC_VIEWER_SAWS_(comm))) PetscCall(PETSC_ERR_PLIB);
231: PetscCall(PetscObjectReference((PetscObject)*viewer));
232: break;
233: #endif
234: #if defined(PETSC_HAVE_HDF5)
235: case 7:
236: if (!(*viewer = PETSC_VIEWER_HDF5_(comm))) PetscCall(PETSC_ERR_PLIB);
237: PetscCall(PetscObjectReference((PetscObject)*viewer));
238: break;
239: #endif
240: case 8:
241: if (!(*viewer = PETSC_VIEWER_GLVIS_(comm))) PetscCall(PETSC_ERR_PLIB);
242: PetscCall(PetscObjectReference((PetscObject)*viewer));
243: break;
244: #if defined(PETSC_HAVE_EXODUSII)
245: case 9:
246: if (!(*viewer = PETSC_VIEWER_EXODUSII_(comm))) PetscCall(PETSC_ERR_PLIB);
247: PetscCall(PetscObjectReference((PetscObject)*viewer));
248: break;
249: #endif
250: case 10:
251: if (!(*viewer = PETSC_VIEWER_PYTHON_(comm))) PetscCall(PETSC_ERR_PLIB);
252: PetscCall(PetscObjectReference((PetscObject)*viewer));
253: break;
254: case 11:
255: if (!(*viewer = PETSC_VIEWER_PYVISTA_(comm))) PetscCall(PETSC_ERR_PLIB);
256: PetscCall(PetscObjectReference((PetscObject)*viewer));
257: break;
258: default:
259: SETERRQ(comm, PETSC_ERR_SUP, "Unsupported viewer %s", loc0_vtype);
260: }
261: } else {
262: if (loc2_fmt && !*loc1_fname && (cnt == 0)) { /* ASCII format without file name */
263: PetscCall(PetscViewerASCIIGetStdout(comm, viewer));
264: PetscCall(PetscObjectReference((PetscObject)*viewer));
265: } else {
266: PetscFileMode fmode;
267: PetscBool flag = PETSC_FALSE;
269: PetscCall(PetscViewerCreate(comm, viewer));
270: PetscCall(PetscViewerSetType(*viewer, *loc0_vtype ? loc0_vtype : "ascii"));
271: fmode = FILE_MODE_WRITE;
272: if (loc3_fmode && *loc3_fmode) { /* Has non-empty file mode ("write" or "append") */
273: PetscCall(PetscEnumFind(PetscFileModes, loc3_fmode, (PetscEnum *)&fmode, &flag));
274: PetscCheck(flag, comm, PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown file mode: %s", loc3_fmode);
275: }
276: if (loc2_fmt) {
277: PetscBool tk, im;
278: PetscCall(PetscStrcmp(loc1_fname, "tikz", &tk));
279: PetscCall(PetscStrcmp(loc1_fname, "image", &im));
280: if (tk || im) {
281: PetscCall(PetscViewerDrawSetInfo(*viewer, NULL, loc2_fmt, PETSC_DECIDE, PETSC_DECIDE, PETSC_DECIDE, PETSC_DECIDE));
282: *loc2_fmt = 0;
283: }
284: }
285: PetscCall(PetscViewerFileSetMode(*viewer, flag ? fmode : FILE_MODE_WRITE));
286: PetscCall(PetscViewerFileSetName(*viewer, loc1_fname));
287: if (*loc1_fname) PetscCall(PetscViewerDrawSetDrawType(*viewer, loc1_fname));
288: PetscCall(PetscViewerSetFromOptions(*viewer));
289: }
290: }
291: }
292: if (viewer) PetscCall(PetscViewerSetUp(*viewer));
293: if (loc2_fmt && *loc2_fmt) {
294: PetscViewerFormat tfmt;
295: PetscBool flag;
297: PetscCall(PetscEnumFind(PetscViewerFormats, loc2_fmt, (PetscEnum *)&tfmt, &flag));
298: if (format) *format = tfmt;
299: PetscCheck(flag, comm, PETSC_ERR_SUP, "Unknown viewer format %s", loc2_fmt);
300: } else if (viewer && (cnt == 6) && format) { /* Get format from VTK viewer */
301: PetscCall(PetscViewerGetFormat(*viewer, format));
302: }
303: PetscCall(PetscFree(loc0_vtype));
304: PetscFunctionReturn(PETSC_SUCCESS);
305: }
307: static PetscErrorCode PetscOptionsCreateViewers_Internal(MPI_Comm comm, PetscOptions options, const char pre[], const char name[], PetscInt *n_max_p, PetscViewer viewer[], PetscViewerFormat format[], PetscBool *set, const char func_name[], PetscBool allow_multiple)
308: {
309: const char *value;
310: PetscBool flag, hashelp;
311: PetscInt n_max;
313: PetscFunctionBegin;
314: PetscAssertPointer(name, 4);
315: PetscAssertPointer(n_max_p, 5);
316: n_max = *n_max_p;
317: PetscCheck(n_max >= 0, comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid size %" PetscInt_FMT " of passed arrays", *n_max_p);
318: *n_max_p = 0;
320: if (set) *set = PETSC_FALSE;
321: PetscCall(PetscOptionsGetCreateViewerOff(&flag));
322: if (flag) PetscFunctionReturn(PETSC_SUCCESS);
324: PetscCall(PetscOptionsHasHelp(NULL, &hashelp));
325: if (hashelp) {
326: PetscBool found;
328: if (!PetscOptionsHelpPrintedSingleton) PetscCall(PetscOptionsHelpPrintedCreate(&PetscOptionsHelpPrintedSingleton));
329: PetscCall(PetscOptionsHelpPrintedCheck(PetscOptionsHelpPrintedSingleton, pre, name, &found));
330: if (!found && viewer) {
331: PetscCall((*PetscHelpPrintf)(comm, "----------------------------------------\nViewer (-%s%s) options:\n", pre ? pre : "", name + 1));
332: PetscCall((*PetscHelpPrintf)(comm, " -%s%s ascii[:[filename][:[format][:append]]]: %s (%s)\n", pre ? pre : "", name + 1, "Prints object to stdout or ASCII file", func_name));
333: PetscCall((*PetscHelpPrintf)(comm, " -%s%s binary[:[filename][:[format][:append]]]: %s (%s)\n", pre ? pre : "", name + 1, "Saves object to a binary file", func_name));
334: PetscCall((*PetscHelpPrintf)(comm, " -%s%s draw[:[drawtype][:filename|format]] %s (%s)\n", pre ? pre : "", name + 1, "Draws object", func_name));
335: PetscCall((*PetscHelpPrintf)(comm, " -%s%s socket[:port]: %s (%s)\n", pre ? pre : "", name + 1, "Pushes object to a Unix socket", func_name));
336: PetscCall((*PetscHelpPrintf)(comm, " -%s%s saws[:communicatorname]: %s (%s)\n", pre ? pre : "", name + 1, "Publishes object to SAWs", func_name));
337: if (allow_multiple) PetscCall((*PetscHelpPrintf)(comm, " -%s%s v1[,v2,...]: %s (%s)\n", pre ? pre : "", name + 1, "Multiple viewers", func_name));
338: }
339: }
341: PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
342: if (flag) {
343: if (set) *set = PETSC_TRUE;
344: if (!value) {
345: PetscCheck(n_max > 0, comm, PETSC_ERR_ARG_SIZ, "More viewers (1) than max available (0)");
346: if (format) *format = PETSC_VIEWER_DEFAULT;
347: if (viewer) {
348: PetscCall(PetscViewerASCIIGetStdout(comm, viewer));
349: PetscCall(PetscObjectReference((PetscObject)*viewer));
350: }
351: *n_max_p = 1;
352: } else {
353: char *loc0_viewer_string = NULL, *this_viewer_string = NULL;
354: size_t viewer_string_length;
356: PetscCall(PetscStrallocpy(value, &loc0_viewer_string));
357: PetscCall(PetscStrlen(loc0_viewer_string, &viewer_string_length));
358: this_viewer_string = loc0_viewer_string;
360: do {
361: PetscViewer *this_viewer;
362: PetscViewerFormat *this_viewer_format;
363: char *next_viewer_string = NULL;
364: char *comma_separator = NULL;
365: PetscInt n = *n_max_p;
367: PetscCheck(n < n_max, comm, PETSC_ERR_PLIB, "More viewers than max available (%" PetscInt_FMT ")", n_max);
369: PetscCall(PetscStrchr(this_viewer_string, ',', &comma_separator));
370: if (comma_separator) {
371: PetscCheck(allow_multiple, comm, PETSC_ERR_ARG_OUTOFRANGE, "Trying to pass multiple viewers to %s: only one allowed. Use PetscOptionsCreateViewers() instead", func_name);
372: *comma_separator = 0;
373: next_viewer_string = comma_separator + 1;
374: }
375: this_viewer = PetscSafePointerPlusOffset(viewer, n);
376: if (this_viewer) *this_viewer = NULL;
377: this_viewer_format = PetscSafePointerPlusOffset(format, n);
378: if (this_viewer_format) *this_viewer_format = PETSC_VIEWER_DEFAULT;
379: PetscCall(PetscOptionsCreateViewers_Single(comm, this_viewer_string, this_viewer, this_viewer_format));
380: this_viewer_string = next_viewer_string;
381: (*n_max_p)++;
382: } while (this_viewer_string);
383: PetscCall(PetscFree(loc0_viewer_string));
384: }
385: }
386: PetscFunctionReturn(PETSC_SUCCESS);
387: }
389: /*@C
390: PetscOptionsCreateViewer - Creates a viewer appropriate for the type indicated by the user
392: Collective
394: Input Parameters:
395: + comm - the communicator to own the viewer
396: . options - options database, use `NULL` for default global database
397: . pre - the string to prepend to the name or `NULL`
398: - name - the options database name that will be checked for
400: Output Parameters:
401: + viewer - the viewer, pass `NULL` if not needed
402: . format - the `PetscViewerFormat` requested by the user, pass `NULL` if not needed
403: - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
405: Level: intermediate
407: Notes:
408: The argument has the following form
409: .vb
410: type:filename:format:filemode
411: .ve
412: where all parts are optional, but you need to include the colon to access the next part. The mode argument must a valid `PetscFileMode`, i.e. read, write, append, update, or append_update. For example, to read from an HDF5 file, use
413: .vb
414: hdf5:sol.h5::read
415: .ve
417: If no value is provided ascii:stdout is used
418: + ascii[:[filename][:[format][:append]]] - defaults to stdout - format can be one of ascii_info, ascii_info_detail, or ascii_matlab,
419: for example ascii::ascii_info prints just the information about the object not all details
420: unless :append is given filename opens in write mode, overwriting what was already there
421: . binary[:[filename][:[format][:append]]] - defaults to the file binaryoutput
422: . draw[:drawtype[:filename]] - for example, draw:tikz, draw:tikz:figure.tex or draw:x
423: . socket[:port] - defaults to the standard output port
424: - saws[:communicatorname] - publishes object to the Scientific Application Webserver (SAWs)
426: You can control whether calls to this function create a viewer (or return early with *set of `PETSC_FALSE`) with
427: `PetscOptionsPushCreateViewerOff()`. This is useful if calling many small subsolves, in which case XXXViewFromOptions can take
428: an appreciable fraction of the runtime.
430: If PETSc is configured with `--with-viewfromoptions=0` this function always returns with *set of `PETSC_FALSE`
432: This routine is thread-safe for accessing predefined `PetscViewer`s like `PETSC_VIEWER_STDOUT_SELF` but not for accessing
433: files by name.
435: .seealso: [](sec_viewers), `PetscViewerDestroy()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
436: `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
437: `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`,
438: `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
439: `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
440: `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
441: `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsPushCreateViewerOff()`, `PetscOptionsPopCreateViewerOff()`,
442: `PetscOptionsCreateViewerOff()`
443: @*/
444: PetscErrorCode PetscOptionsCreateViewer(MPI_Comm comm, PetscOptions options, const char pre[], const char name[], PetscViewer *viewer, PetscViewerFormat *format, PetscBool *set)
445: {
446: PetscInt n_max = 1;
447: PetscBool set_internal;
449: PetscFunctionBegin;
450: if (viewer) *viewer = NULL;
451: if (format) *format = PETSC_VIEWER_DEFAULT;
452: PetscCall(PetscOptionsCreateViewers_Internal(comm, options, pre, name, &n_max, viewer, format, &set_internal, PETSC_FUNCTION_NAME, PETSC_FALSE));
453: if (set_internal) PetscAssert(n_max == 1, comm, PETSC_ERR_PLIB, "Unexpected: %" PetscInt_FMT " != 1 viewers set", n_max);
454: if (set) *set = set_internal;
455: PetscFunctionReturn(PETSC_SUCCESS);
456: }
458: /*@C
459: PetscOptionsCreateViewers - Create multiple viewers from a comma-separated list in the options database
461: Collective
463: Input Parameters:
464: + comm - the communicator to own the viewers
465: . options - options database, use `NULL` for default global database
466: . pre - the string to prepend to the name or `NULL`
467: . name - the options database name that will be checked for
468: - n_max - on input: the maximum number of viewers; on output: the number of viewers in the comma-separated list
470: Output Parameters:
471: + viewers - an array to hold at least `n_max` `PetscViewer`s, or `NULL` if not needed; on output: if not `NULL`, the
472: first `n_max` entries are initialized `PetscViewer`s
473: . formats - an array to hold at least `n_max` `PetscViewerFormat`s, or `NULL` if not needed; on output: if not
474: `NULL`, the first `n_max` entries are valid `PetscViewewFormat`s
475: - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
477: Level: intermediate
479: Note:
480: See `PetscOptionsCreateViewer()` for how the format strings for the viewers are interpreted.
482: Use `PetscViewerDestroy()` on each viewer, otherwise a memory leak will occur.
484: If PETSc is configured with `--with-viewfromoptions=0` this function always returns with `n_max` of 0 and `set` of `PETSC_FALSE`
486: .seealso: [](sec_viewers), `PetscOptionsCreateViewer()`
487: @*/
488: PetscErrorCode PetscOptionsCreateViewers(MPI_Comm comm, PetscOptions options, const char pre[], const char name[], PetscInt *n_max, PetscViewer viewers[], PetscViewerFormat formats[], PetscBool *set)
489: {
490: PetscFunctionBegin;
491: PetscCall(PetscOptionsCreateViewers_Internal(comm, options, pre, name, n_max, viewers, formats, set, PETSC_FUNCTION_NAME, PETSC_TRUE));
492: PetscFunctionReturn(PETSC_SUCCESS);
493: }
495: /*@
496: PetscViewerCreate - Creates a viewing context. A `PetscViewer` represents a file, a graphical window, a Unix socket or a variety of other ways
497: of viewing a PETSc object
499: Collective
501: Input Parameter:
502: . comm - MPI communicator
504: Output Parameter:
505: . inviewer - location to put the `PetscViewer` context
507: Level: advanced
509: .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerType`
510: @*/
511: PetscErrorCode PetscViewerCreate(MPI_Comm comm, PetscViewer *inviewer)
512: {
513: PetscViewer viewer;
515: PetscFunctionBegin;
516: PetscAssertPointer(inviewer, 2);
517: PetscCall(PetscViewerInitializePackage());
518: PetscCall(PetscHeaderCreate(viewer, PETSC_VIEWER_CLASSID, "PetscViewer", "PetscViewer", "Viewer", comm, PetscViewerDestroy, PetscViewerView));
519: *inviewer = viewer;
520: viewer->data = NULL;
521: PetscFunctionReturn(PETSC_SUCCESS);
522: }
524: /*@
525: PetscViewerSetType - Builds `PetscViewer` for a particular implementation.
527: Collective
529: Input Parameters:
530: + viewer - the `PetscViewer` context obtained with `PetscViewerCreate()`
531: - type - for example, `PETSCVIEWERASCII`
533: Options Database Key:
534: . -viewer_type <type> - Sets the type; use -help for a list of available methods (for instance, ascii)
536: Level: advanced
538: Note:
539: See `PetscViewerType` for possible values
541: .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerCreate()`, `PetscViewerGetType()`, `PetscViewerType`, `PetscViewerPushFormat()`
542: @*/
543: PetscErrorCode PetscViewerSetType(PetscViewer viewer, PetscViewerType type)
544: {
545: PetscBool match;
546: PetscErrorCode (*r)(PetscViewer);
548: PetscFunctionBegin;
550: PetscAssertPointer(type, 2);
551: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, type, &match));
552: if (match) PetscFunctionReturn(PETSC_SUCCESS);
554: /* cleanup any old type that may be there */
555: PetscTryTypeMethod(viewer, destroy);
556: viewer->ops->destroy = NULL;
557: viewer->data = NULL;
559: PetscCall(PetscMemzero(viewer->ops, sizeof(struct _PetscViewerOps)));
561: PetscCall(PetscFunctionListFind(PetscViewerList, type, &r));
562: PetscCheck(r, PetscObjectComm((PetscObject)viewer), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscViewer type given: %s", type);
564: PetscCall(PetscObjectChangeTypeName((PetscObject)viewer, type));
565: PetscCall((*r)(viewer));
566: PetscFunctionReturn(PETSC_SUCCESS);
567: }
569: /*@C
570: PetscViewerRegister - Adds a viewer to those available for use with `PetscViewerSetType()`
572: Not Collective, No Fortran Support
574: Input Parameters:
575: + sname - name of a new user-defined viewer
576: - function - routine to create method context
578: Level: developer
580: Note:
581: `PetscViewerRegister()` may be called multiple times to add several user-defined viewers.
583: Example Usage:
584: .vb
585: PetscViewerRegister("my_viewer_type", MyViewerCreate);
586: .ve
588: Then, your solver can be chosen with the procedural interface via
589: $ PetscViewerSetType(viewer, "my_viewer_type")
590: or at runtime via the option
591: $ -viewer_type my_viewer_type
593: .seealso: [](sec_viewers), `PetscViewerRegisterAll()`
594: @*/
595: PetscErrorCode PetscViewerRegister(const char *sname, PetscErrorCode (*function)(PetscViewer))
596: {
597: PetscFunctionBegin;
598: PetscCall(PetscViewerInitializePackage());
599: PetscCall(PetscFunctionListAdd(&PetscViewerList, sname, function));
600: PetscFunctionReturn(PETSC_SUCCESS);
601: }
603: /*@C
604: PetscViewerSetFromOptions - Sets various options for a viewer based on values in the options database.
606: Collective
608: Input Parameter:
609: . viewer - the viewer context
611: Level: intermediate
613: Note:
614: Must be called after `PetscViewerCreate()` but before the `PetscViewer` is used.
616: .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerCreate()`, `PetscViewerSetType()`, `PetscViewerType`
617: @*/
618: PetscErrorCode PetscViewerSetFromOptions(PetscViewer viewer)
619: {
620: char vtype[256];
621: PetscBool flg;
623: PetscFunctionBegin;
626: if (!PetscViewerList) PetscCall(PetscViewerRegisterAll());
627: PetscObjectOptionsBegin((PetscObject)viewer);
628: PetscCall(PetscOptionsFList("-viewer_type", "Type of PetscViewer", "None", PetscViewerList, (char *)(((PetscObject)viewer)->type_name ? ((PetscObject)viewer)->type_name : PETSCVIEWERASCII), vtype, 256, &flg));
629: if (flg) PetscCall(PetscViewerSetType(viewer, vtype));
630: /* type has not been set? */
631: if (!((PetscObject)viewer)->type_name) PetscCall(PetscViewerSetType(viewer, PETSCVIEWERASCII));
632: PetscTryTypeMethod(viewer, setfromoptions, PetscOptionsObject);
634: /* process any options handlers added with PetscObjectAddOptionsHandler() */
635: PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)viewer, PetscOptionsObject));
636: PetscCall(PetscViewerViewFromOptions(viewer, NULL, "-viewer_view"));
637: PetscOptionsEnd();
638: PetscFunctionReturn(PETSC_SUCCESS);
639: }
641: PetscErrorCode PetscViewerFlowControlStart(PetscViewer viewer, PetscInt *mcnt, PetscInt *cnt)
642: {
643: PetscFunctionBegin;
644: PetscCall(PetscViewerBinaryGetFlowControl(viewer, mcnt));
645: PetscCall(PetscViewerBinaryGetFlowControl(viewer, cnt));
646: PetscFunctionReturn(PETSC_SUCCESS);
647: }
649: PetscErrorCode PetscViewerFlowControlStepMain(PetscViewer viewer, PetscInt i, PetscInt *mcnt, PetscInt cnt)
650: {
651: MPI_Comm comm;
653: PetscFunctionBegin;
654: PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
655: if (i >= *mcnt) {
656: *mcnt += cnt;
657: PetscCallMPI(MPI_Bcast(mcnt, 1, MPIU_INT, 0, comm));
658: }
659: PetscFunctionReturn(PETSC_SUCCESS);
660: }
662: PetscErrorCode PetscViewerFlowControlEndMain(PetscViewer viewer, PetscInt *mcnt)
663: {
664: MPI_Comm comm;
666: PetscFunctionBegin;
667: PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
668: *mcnt = 0;
669: PetscCallMPI(MPI_Bcast(mcnt, 1, MPIU_INT, 0, comm));
670: PetscFunctionReturn(PETSC_SUCCESS);
671: }
673: PetscErrorCode PetscViewerFlowControlStepWorker(PetscViewer viewer, PetscMPIInt rank, PetscInt *mcnt)
674: {
675: MPI_Comm comm;
677: PetscFunctionBegin;
678: PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
679: while (PETSC_TRUE) {
680: if (rank < *mcnt) break;
681: PetscCallMPI(MPI_Bcast(mcnt, 1, MPIU_INT, 0, comm));
682: }
683: PetscFunctionReturn(PETSC_SUCCESS);
684: }
686: PetscErrorCode PetscViewerFlowControlEndWorker(PetscViewer viewer, PetscInt *mcnt)
687: {
688: MPI_Comm comm;
690: PetscFunctionBegin;
691: PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
692: while (PETSC_TRUE) {
693: PetscCallMPI(MPI_Bcast(mcnt, 1, MPIU_INT, 0, comm));
694: if (!*mcnt) break;
695: }
696: PetscFunctionReturn(PETSC_SUCCESS);
697: }