1 #include <petsc/private/viewerimpl.h> /*I "petscviewer.h" I*/
2 #include <petsc/private/hashtable.h>
3 #if defined(PETSC_HAVE_SAWS)
4 #include <petscviewersaws.h>
5 #endif
6
7 PetscFunctionList PetscViewerList = NULL;
8
9 PetscOptionsHelpPrinted PetscOptionsHelpPrintedSingleton = NULL;
10 KHASH_SET_INIT_STR(HTPrinted)
11 struct _n_PetscOptionsHelpPrinted {
12 khash_t(HTPrinted) *printed;
13 PetscSegBuffer strings;
14 };
15
PetscOptionsHelpPrintedDestroy(PetscOptionsHelpPrinted * hp)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 }
25
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.
29
30 Output Parameter:
31 . hp - the created object
32
33 Not Collective
34
35 Level: developer
36
37 .seealso: `PetscOptionsHelpPrintedCheck()`, `PetscOptionsHelpPrintChecked()`
38 @*/
PetscOptionsHelpPrintedCreate(PetscOptionsHelpPrinted * hp)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 }
47
48 /*@C
49 PetscOptionsHelpPrintedCheck - Checks if a particular pre, name pair has previous been entered (meaning the help message was printed)
50
51 Not Collective
52
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`)
57
58 Output Parameter:
59 . found - `PETSC_TRUE` if the string was already set
60
61 Level: intermediate
62
63 .seealso: `PetscOptionsHelpPrintedCreate()`
64 @*/
PetscOptionsHelpPrintedCheck(PetscOptionsHelpPrinted hp,const char * pre,const char * name,PetscBool * found)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
72
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 }
93
94 static PetscBool noviewer = PETSC_FALSE;
95 static PetscBool noviewers[PETSCVIEWERCREATEVIEWEROFFPUSHESMAX];
96 static PetscInt inoviewers = 0;
97
98 /*@
99 PetscOptionsPushCreateViewerOff - sets if `PetscOptionsCreateViewer()`, `PetscOptionsViewer()`, and `PetscOptionsCreateViewers()` return viewers.
100
101 Logically Collective
102
103 Input Parameter:
104 . flg - `PETSC_TRUE` to turn off viewer creation, `PETSC_FALSE` to turn it on.
105
106 Level: developer
107
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.
111
112 Developer Notes:
113 Instead of using this approach, the calls to `PetscOptionsCreateViewer()` can be moved into `XXXSetFromOptions()`
114
115 .seealso: [](sec_viewers), `PetscOptionsCreateViewer()`, `PetscOptionsPopCreateViewerOff()`
116 @*/
PetscOptionsPushCreateViewerOff(PetscBool flg)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()?");
121
122 noviewers[inoviewers++] = noviewer;
123 noviewer = flg;
124 PetscFunctionReturn(PETSC_SUCCESS);
125 }
126
127 /*@
128 PetscOptionsPopCreateViewerOff - reset whether `PetscOptionsCreateViewer()` returns a viewer.
129
130 Logically Collective
131
132 Level: developer
133
134 Note:
135 See `PetscOptionsPushCreateViewerOff()`
136
137 .seealso: [](sec_viewers), `PetscOptionsCreateViewer()`, `PetscOptionsPushCreateViewerOff()`
138 @*/
PetscOptionsPopCreateViewerOff(void)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 }
146
147 /*@
148 PetscOptionsGetCreateViewerOff - do `PetscOptionsCreateViewer()`, `PetscOptionsViewer()`, and `PetscOptionsCreateViewers()` return viewers
149
150 Logically Collective
151
152 Output Parameter:
153 . flg - whether viewers are returned.
154
155 Level: developer
156
157 .seealso: [](sec_viewers), `PetscOptionsCreateViewer()`, `PetscOptionsPushCreateViewerOff()`, `PetscOptionsPopCreateViewerOff()`
158 @*/
PetscOptionsGetCreateViewerOff(PetscBool * flg)159 PetscErrorCode PetscOptionsGetCreateViewerOff(PetscBool *flg)
160 {
161 PetscFunctionBegin;
162 PetscAssertPointer(flg, 1);
163 *flg = noviewer;
164 PetscFunctionReturn(PETSC_SUCCESS);
165 }
166
PetscOptionsCreateViewers_Single(MPI_Comm comm,const char value[],PetscViewer * viewer,PetscViewerFormat * format)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 */
173
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 }
184
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;
268
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;
296
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 }
306
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)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;
312
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;
319
320 if (set) *set = PETSC_FALSE;
321 PetscCall(PetscOptionsGetCreateViewerOff(&flag));
322 if (flag) PetscFunctionReturn(PETSC_SUCCESS);
323
324 PetscCall(PetscOptionsHasHelp(NULL, &hashelp));
325 if (hashelp) {
326 PetscBool found;
327
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 }
340
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;
355
356 PetscCall(PetscStrallocpy(value, &loc0_viewer_string));
357 PetscCall(PetscStrlen(loc0_viewer_string, &viewer_string_length));
358 this_viewer_string = loc0_viewer_string;
359
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;
366
367 PetscCheck(n < n_max, comm, PETSC_ERR_PLIB, "More viewers than max available (%" PetscInt_FMT ")", n_max);
368
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 }
388
389 /*@C
390 PetscOptionsCreateViewer - Creates a viewer appropriate for the type indicated by the user
391
392 Collective
393
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
399
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`
404
405 Level: intermediate
406
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
416
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)
425
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.
429
430 If PETSc is configured with `--with-viewfromoptions=0` this function always returns with *set of `PETSC_FALSE`
431
432 This routine is thread-safe for accessing predefined `PetscViewer`s like `PETSC_VIEWER_STDOUT_SELF` but not for accessing
433 files by name.
434
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 @*/
PetscOptionsCreateViewer(MPI_Comm comm,PetscOptions options,const char pre[],const char name[],PetscViewer * viewer,PetscViewerFormat * format,PetscBool * set)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;
448
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 }
457
458 /*@C
459 PetscOptionsCreateViewers - Create multiple viewers from a comma-separated list in the options database
460
461 Collective
462
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
469
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`
476
477 Level: intermediate
478
479 Note:
480 See `PetscOptionsCreateViewer()` for how the format strings for the viewers are interpreted.
481
482 Use `PetscViewerDestroy()` on each viewer, otherwise a memory leak will occur.
483
484 If PETSc is configured with `--with-viewfromoptions=0` this function always returns with `n_max` of 0 and `set` of `PETSC_FALSE`
485
486 .seealso: [](sec_viewers), `PetscOptionsCreateViewer()`
487 @*/
PetscOptionsCreateViewers(MPI_Comm comm,PetscOptions options,const char pre[],const char name[],PetscInt * n_max,PetscViewer viewers[],PetscViewerFormat formats[],PetscBool * set)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 }
494
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
498
499 Collective
500
501 Input Parameter:
502 . comm - MPI communicator
503
504 Output Parameter:
505 . inviewer - location to put the `PetscViewer` context
506
507 Level: advanced
508
509 .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerType`
510 @*/
PetscViewerCreate(MPI_Comm comm,PetscViewer * inviewer)511 PetscErrorCode PetscViewerCreate(MPI_Comm comm, PetscViewer *inviewer)
512 {
513 PetscViewer viewer;
514
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 }
523
524 /*@
525 PetscViewerSetType - Builds `PetscViewer` for a particular implementation.
526
527 Collective
528
529 Input Parameters:
530 + viewer - the `PetscViewer` context obtained with `PetscViewerCreate()`
531 - type - for example, `PETSCVIEWERASCII`
532
533 Options Database Key:
534 . -viewer_type <type> - Sets the type; use -help for a list of available methods (for instance, ascii)
535
536 Level: advanced
537
538 Note:
539 See `PetscViewerType` for possible values
540
541 .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerCreate()`, `PetscViewerGetType()`, `PetscViewerType`, `PetscViewerPushFormat()`
542 @*/
PetscViewerSetType(PetscViewer viewer,PetscViewerType type)543 PetscErrorCode PetscViewerSetType(PetscViewer viewer, PetscViewerType type)
544 {
545 PetscBool match;
546 PetscErrorCode (*r)(PetscViewer);
547
548 PetscFunctionBegin;
549 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
550 PetscAssertPointer(type, 2);
551 PetscCall(PetscObjectTypeCompare((PetscObject)viewer, type, &match));
552 if (match) PetscFunctionReturn(PETSC_SUCCESS);
553
554 /* cleanup any old type that may be there */
555 PetscTryTypeMethod(viewer, destroy);
556 viewer->ops->destroy = NULL;
557 viewer->data = NULL;
558
559 PetscCall(PetscMemzero(viewer->ops, sizeof(struct _PetscViewerOps)));
560
561 PetscCall(PetscFunctionListFind(PetscViewerList, type, &r));
562 PetscCheck(r, PetscObjectComm((PetscObject)viewer), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscViewer type given: %s", type);
563
564 PetscCall(PetscObjectChangeTypeName((PetscObject)viewer, type));
565 PetscCall((*r)(viewer));
566 PetscFunctionReturn(PETSC_SUCCESS);
567 }
568
569 /*@C
570 PetscViewerRegister - Adds a viewer to those available for use with `PetscViewerSetType()`
571
572 Not Collective, No Fortran Support
573
574 Input Parameters:
575 + sname - name of a new user-defined viewer
576 - function - routine to create method context
577
578 Level: developer
579
580 Note:
581 `PetscViewerRegister()` may be called multiple times to add several user-defined viewers.
582
583 Example Usage:
584 .vb
585 PetscViewerRegister("my_viewer_type", MyViewerCreate);
586 .ve
587
588 Then, your solver can be chosen with the procedural interface via
589 .vb
590 PetscViewerSetType(viewer, "my_viewer_type")
591 .ve
592 or at runtime via the option
593 .vb
594 -viewer_type my_viewer_type
595 .ve
596
597 .seealso: [](sec_viewers), `PetscViewerRegisterAll()`
598 @*/
PetscViewerRegister(const char * sname,PetscErrorCode (* function)(PetscViewer))599 PetscErrorCode PetscViewerRegister(const char *sname, PetscErrorCode (*function)(PetscViewer))
600 {
601 PetscFunctionBegin;
602 PetscCall(PetscViewerInitializePackage());
603 PetscCall(PetscFunctionListAdd(&PetscViewerList, sname, function));
604 PetscFunctionReturn(PETSC_SUCCESS);
605 }
606
607 /*@C
608 PetscViewerSetFromOptions - Sets various options for a viewer based on values in the options database.
609
610 Collective
611
612 Input Parameter:
613 . viewer - the viewer context
614
615 Level: intermediate
616
617 Note:
618 Must be called after `PetscViewerCreate()` but before the `PetscViewer` is used.
619
620 .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerCreate()`, `PetscViewerSetType()`, `PetscViewerType`
621 @*/
PetscViewerSetFromOptions(PetscViewer viewer)622 PetscErrorCode PetscViewerSetFromOptions(PetscViewer viewer)
623 {
624 char vtype[256];
625 PetscBool flg;
626
627 PetscFunctionBegin;
628 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
629
630 if (!PetscViewerList) PetscCall(PetscViewerRegisterAll());
631 PetscObjectOptionsBegin((PetscObject)viewer);
632 PetscCall(PetscOptionsFList("-viewer_type", "Type of PetscViewer", "None", PetscViewerList, (char *)(((PetscObject)viewer)->type_name ? ((PetscObject)viewer)->type_name : PETSCVIEWERASCII), vtype, 256, &flg));
633 if (flg) PetscCall(PetscViewerSetType(viewer, vtype));
634 /* type has not been set? */
635 if (!((PetscObject)viewer)->type_name) PetscCall(PetscViewerSetType(viewer, PETSCVIEWERASCII));
636 PetscTryTypeMethod(viewer, setfromoptions, PetscOptionsObject);
637
638 /* process any options handlers added with PetscObjectAddOptionsHandler() */
639 PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)viewer, PetscOptionsObject));
640 PetscCall(PetscViewerViewFromOptions(viewer, NULL, "-viewer_view"));
641 PetscOptionsEnd();
642 PetscFunctionReturn(PETSC_SUCCESS);
643 }
644
PetscViewerFlowControlStart(PetscViewer viewer,PetscInt * mcnt,PetscInt * cnt)645 PetscErrorCode PetscViewerFlowControlStart(PetscViewer viewer, PetscInt *mcnt, PetscInt *cnt)
646 {
647 PetscFunctionBegin;
648 PetscCall(PetscViewerBinaryGetFlowControl(viewer, mcnt));
649 PetscCall(PetscViewerBinaryGetFlowControl(viewer, cnt));
650 PetscFunctionReturn(PETSC_SUCCESS);
651 }
652
PetscViewerFlowControlStepMain(PetscViewer viewer,PetscInt i,PetscInt * mcnt,PetscInt cnt)653 PetscErrorCode PetscViewerFlowControlStepMain(PetscViewer viewer, PetscInt i, PetscInt *mcnt, PetscInt cnt)
654 {
655 MPI_Comm comm;
656
657 PetscFunctionBegin;
658 PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
659 if (i >= *mcnt) {
660 *mcnt += cnt;
661 PetscCallMPI(MPI_Bcast(mcnt, 1, MPIU_INT, 0, comm));
662 }
663 PetscFunctionReturn(PETSC_SUCCESS);
664 }
665
PetscViewerFlowControlEndMain(PetscViewer viewer,PetscInt * mcnt)666 PetscErrorCode PetscViewerFlowControlEndMain(PetscViewer viewer, PetscInt *mcnt)
667 {
668 MPI_Comm comm;
669
670 PetscFunctionBegin;
671 PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
672 *mcnt = 0;
673 PetscCallMPI(MPI_Bcast(mcnt, 1, MPIU_INT, 0, comm));
674 PetscFunctionReturn(PETSC_SUCCESS);
675 }
676
PetscViewerFlowControlStepWorker(PetscViewer viewer,PetscMPIInt rank,PetscInt * mcnt)677 PetscErrorCode PetscViewerFlowControlStepWorker(PetscViewer viewer, PetscMPIInt rank, PetscInt *mcnt)
678 {
679 MPI_Comm comm;
680
681 PetscFunctionBegin;
682 PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
683 while (PETSC_TRUE) {
684 if (rank < *mcnt) break;
685 PetscCallMPI(MPI_Bcast(mcnt, 1, MPIU_INT, 0, comm));
686 }
687 PetscFunctionReturn(PETSC_SUCCESS);
688 }
689
PetscViewerFlowControlEndWorker(PetscViewer viewer,PetscInt * mcnt)690 PetscErrorCode PetscViewerFlowControlEndWorker(PetscViewer viewer, PetscInt *mcnt)
691 {
692 MPI_Comm comm;
693
694 PetscFunctionBegin;
695 PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
696 while (PETSC_TRUE) {
697 PetscCallMPI(MPI_Bcast(mcnt, 1, MPIU_INT, 0, comm));
698 if (!*mcnt) break;
699 }
700 PetscFunctionReturn(PETSC_SUCCESS);
701 }
702