xref: /petsc/src/sys/classes/viewer/interface/view.c (revision 884d422fa8a734f01f4cddac68ca9e4d00f53602)
1 #include <petsc/private/viewerimpl.h> /*I "petscviewer.h" I*/
2 #include <petscdraw.h>
3 
4 PetscClassId PETSC_VIEWER_CLASSID;
5 
6 static PetscBool PetscViewerPackageInitialized = PETSC_FALSE;
7 
8 /*@C
9   PetscViewerFinalizePackage - This function destroys any global objects created in PETSc viewers. It is
10   called from `PetscFinalize()`.
11 
12   Level: developer
13 
14 .seealso: [](sec_viewers), `PetscViewer`, `PetscFinalize()`, `PetscViewerInitializePackage()`
15 @*/
16 PetscErrorCode PetscViewerFinalizePackage(void)
17 {
18   PetscFunctionBegin;
19   if (Petsc_Viewer_keyval != MPI_KEYVAL_INVALID) PetscCallMPI(MPI_Comm_free_keyval(&Petsc_Viewer_keyval));
20   if (Petsc_Viewer_Stdout_keyval != MPI_KEYVAL_INVALID) PetscCallMPI(MPI_Comm_free_keyval(&Petsc_Viewer_Stdout_keyval));
21   if (Petsc_Viewer_Stderr_keyval != MPI_KEYVAL_INVALID) PetscCallMPI(MPI_Comm_free_keyval(&Petsc_Viewer_Stderr_keyval));
22   if (Petsc_Viewer_Binary_keyval != MPI_KEYVAL_INVALID) PetscCallMPI(MPI_Comm_free_keyval(&Petsc_Viewer_Binary_keyval));
23   if (Petsc_Viewer_Draw_keyval != MPI_KEYVAL_INVALID) PetscCallMPI(MPI_Comm_free_keyval(&Petsc_Viewer_Draw_keyval));
24 #if defined(PETSC_HAVE_HDF5)
25   if (Petsc_Viewer_HDF5_keyval != MPI_KEYVAL_INVALID) PetscCallMPI(MPI_Comm_free_keyval(&Petsc_Viewer_HDF5_keyval));
26 #endif
27 #if defined(PETSC_USE_SOCKETVIEWER)
28   if (Petsc_Viewer_Socket_keyval != MPI_KEYVAL_INVALID) PetscCallMPI(MPI_Comm_free_keyval(&Petsc_Viewer_Socket_keyval));
29 #endif
30   PetscCall(PetscFunctionListDestroy(&PetscViewerList));
31   PetscViewerPackageInitialized = PETSC_FALSE;
32   PetscViewerRegisterAllCalled  = PETSC_FALSE;
33   PetscFunctionReturn(PETSC_SUCCESS);
34 }
35 
36 /*@C
37   PetscViewerInitializePackage - This function initializes everything in the `PetscViewer` package.
38 
39   Level: developer
40 
41 .seealso: [](sec_viewers), `PetscViewer`, `PetscInitialize()`, `PetscViewerFinalizePackage()`
42 @*/
43 PetscErrorCode PetscViewerInitializePackage(void)
44 {
45   char      logList[256];
46   PetscBool opt, pkg;
47 
48   PetscFunctionBegin;
49   if (PetscViewerPackageInitialized) PetscFunctionReturn(PETSC_SUCCESS);
50   PetscViewerPackageInitialized = PETSC_TRUE;
51   /* Register Classes */
52   PetscCall(PetscClassIdRegister("Viewer", &PETSC_VIEWER_CLASSID));
53   /* Register Constructors */
54   PetscCall(PetscViewerRegisterAll());
55   /* Process Info */
56   {
57     PetscClassId classids[1];
58 
59     classids[0] = PETSC_VIEWER_CLASSID;
60     PetscCall(PetscInfoProcessClass("viewer", 1, classids));
61   }
62   /* Process summary exclusions */
63   PetscCall(PetscOptionsGetString(NULL, NULL, "-log_exclude", logList, sizeof(logList), &opt));
64   if (opt) {
65     PetscCall(PetscStrInList("viewer", logList, ',', &pkg));
66     if (pkg) PetscCall(PetscLogEventExcludeClass(PETSC_VIEWER_CLASSID));
67   }
68 #if defined(PETSC_HAVE_MATHEMATICA)
69   PetscCall(PetscViewerMathematicaInitializePackage());
70 #endif
71   /* Register package finalizer */
72   PetscCall(PetscRegisterFinalize(PetscViewerFinalizePackage));
73   PetscFunctionReturn(PETSC_SUCCESS);
74 }
75 
76 /*@
77   PetscViewerDestroy - Destroys a `PetscViewer`.
78 
79   Collective
80 
81   Input Parameter:
82 . viewer - the `PetscViewer` to be destroyed.
83 
84   Level: beginner
85 
86 .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerCreate()`, `PetscViewerSocketOpen()`, `PetscViewerASCIIOpen()`, `PetscViewerDrawOpen()`
87 @*/
88 PetscErrorCode PetscViewerDestroy(PetscViewer *viewer)
89 {
90   PetscFunctionBegin;
91   if (!*viewer) PetscFunctionReturn(PETSC_SUCCESS);
92   PetscValidHeaderSpecific(*viewer, PETSC_VIEWER_CLASSID, 1);
93 
94   PetscCall(PetscViewerFlush(*viewer));
95   if (--((PetscObject)(*viewer))->refct > 0) {
96     *viewer = NULL;
97     PetscFunctionReturn(PETSC_SUCCESS);
98   }
99 
100   PetscCall(PetscObjectSAWsViewOff((PetscObject)*viewer));
101   if ((*viewer)->ops->destroy) PetscCall((*(*viewer)->ops->destroy)(*viewer));
102   PetscCall(PetscHeaderDestroy(viewer));
103   PetscFunctionReturn(PETSC_SUCCESS);
104 }
105 
106 /*@C
107   PetscViewerAndFormatCreate - Creates a `PetscViewerAndFormat` struct.
108 
109   Collective
110 
111   Input Parameters:
112 + viewer - the viewer
113 - format - the format
114 
115   Output Parameter:
116 . vf - viewer and format object
117 
118   Level: developer
119 
120   Notes:
121   This increases the reference count of the viewer.
122 
123   Use `PetscViewerAndFormatDestroy()` to free the struct
124 
125   This is used as the context variable for many of the `TS`, `SNES`, and `KSP` monitor functions
126 
127   This construct exists because it allows one to keep track of the use of a `PetscViewerFormat` without requiring the
128   format in the viewer to be permanently changed.
129 
130 .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerAndFormat`, `PetscViewerFormat`, `PetscViewerSocketOpen()`, `PetscViewerASCIIOpen()`, `PetscViewerCreate()`,
131           `PetscViewerDrawOpen()`, `PetscViewerAndFormatDestroy()`
132 @*/
133 PetscErrorCode PetscViewerAndFormatCreate(PetscViewer viewer, PetscViewerFormat format, PetscViewerAndFormat **vf)
134 {
135   PetscFunctionBegin;
136   if (!((PetscObject)viewer)->persistent) PetscCall(PetscObjectReference((PetscObject)viewer));
137   PetscCall(PetscNew(vf));
138   (*vf)->viewer = viewer;
139   (*vf)->format = format;
140   (*vf)->lg     = NULL;
141   (*vf)->data   = NULL;
142   PetscFunctionReturn(PETSC_SUCCESS);
143 }
144 
145 /*@C
146   PetscViewerAndFormatDestroy - Destroys a `PetscViewerAndFormat` struct created with `PetscViewerAndFormatCreate()`
147 
148   Collective
149 
150   Input Parameter:
151 . vf - the `PetscViewerAndFormat` to be destroyed.
152 
153   Level: developer
154 
155 .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerAndFormat`, `PetscViewerFormat`, `PetscViewerAndFormatCreate()`, `PetscViewerSocketOpen()`,
156           `PetscViewerASCIIOpen()`, `PetscViewerCreate()`, `PetscViewerDrawOpen()`
157 @*/
158 PetscErrorCode PetscViewerAndFormatDestroy(PetscViewerAndFormat **vf)
159 {
160   PetscFunctionBegin;
161   if (!((PetscObject)((*vf)->viewer))->persistent) PetscCall(PetscViewerDestroy(&(*vf)->viewer));
162   PetscCall(PetscDrawLGDestroy(&(*vf)->lg));
163   PetscCall(PetscFree(*vf));
164   PetscFunctionReturn(PETSC_SUCCESS);
165 }
166 
167 /*@C
168   PetscViewerGetType - Returns the type of a `PetscViewer`.
169 
170   Not Collective
171 
172   Input Parameter:
173 . viewer - the `PetscViewer`
174 
175   Output Parameter:
176 . type - `PetscViewerType`
177 
178   Level: intermediate
179 
180   Note:
181   `PetscViewerType` is actually a string
182 
183 .seealso: [](sec_viewers), `PetscViewerType`, `PetscViewer`, `PetscViewerCreate()`, `PetscViewerSetType()`
184 @*/
185 PetscErrorCode PetscViewerGetType(PetscViewer viewer, PetscViewerType *type)
186 {
187   PetscFunctionBegin;
188   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
189   PetscAssertPointer(type, 2);
190   *type = ((PetscObject)viewer)->type_name;
191   PetscFunctionReturn(PETSC_SUCCESS);
192 }
193 
194 /*@C
195   PetscViewerSetOptionsPrefix - Sets the prefix used for searching for
196   `PetscViewer` options in the database during `PetscViewerSetFromOptions()`.
197 
198   Logically Collective
199 
200   Input Parameters:
201 + viewer - the `PetscViewer` context
202 - prefix - the prefix to prepend to all option names
203 
204   Note:
205   A hyphen (-) must NOT be given at the beginning of the prefix name.
206   The first character of all runtime options is AUTOMATICALLY the hyphen.
207 
208   Level: advanced
209 
210 .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerSetFromOptions()`, `PetscViewerAppendOptionsPrefix()`
211 @*/
212 PetscErrorCode PetscViewerSetOptionsPrefix(PetscViewer viewer, const char prefix[])
213 {
214   PetscFunctionBegin;
215   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
216   PetscCall(PetscObjectSetOptionsPrefix((PetscObject)viewer, prefix));
217   PetscFunctionReturn(PETSC_SUCCESS);
218 }
219 
220 /*@C
221   PetscViewerAppendOptionsPrefix - Appends to the prefix used for searching for
222   `PetscViewer` options in the database during `PetscViewerSetFromOptions()`.
223 
224   Logically Collective
225 
226   Input Parameters:
227 + viewer - the `PetscViewer` context
228 - prefix - the prefix to prepend to all option names
229 
230   Level: advanced
231 
232   Note:
233   A hyphen (-) must NOT be given at the beginning of the prefix name.
234   The first character of all runtime options is AUTOMATICALLY the hyphen.
235 
236 .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerGetOptionsPrefix()`, `PetscViewerSetOptionsPrefix()`
237 @*/
238 PetscErrorCode PetscViewerAppendOptionsPrefix(PetscViewer viewer, const char prefix[])
239 {
240   PetscFunctionBegin;
241   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
242   PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)viewer, prefix));
243   PetscFunctionReturn(PETSC_SUCCESS);
244 }
245 
246 /*@C
247   PetscViewerGetOptionsPrefix - Gets the prefix used for searching for
248   `PetscViewer` options in the database during `PetscViewerSetFromOptions()`.
249 
250   Not Collective
251 
252   Input Parameter:
253 . viewer - the `PetscViewer` context
254 
255   Output Parameter:
256 . prefix - pointer to the prefix string used
257 
258   Level: advanced
259 
260   Fortran Notes:
261   The user should pass in a string 'prefix' of sufficient length to hold the prefix.
262 
263 .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerAppendOptionsPrefix()`, `PetscViewerSetOptionsPrefix()`
264 @*/
265 PetscErrorCode PetscViewerGetOptionsPrefix(PetscViewer viewer, const char *prefix[])
266 {
267   PetscFunctionBegin;
268   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
269   PetscCall(PetscObjectGetOptionsPrefix((PetscObject)viewer, prefix));
270   PetscFunctionReturn(PETSC_SUCCESS);
271 }
272 
273 /*@
274   PetscViewerSetUp - Sets up the internal viewer data structures for the later use.
275 
276   Collective
277 
278   Input Parameter:
279 . viewer - the `PetscViewer` context
280 
281   Level: advanced
282 
283   Note:
284   For basic use of the `PetscViewer` classes the user need not explicitly call
285   `PetscViewerSetUp()`, since these actions will happen automatically.
286 
287 .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerCreate()`, `PetscViewerDestroy()`
288 @*/
289 PetscErrorCode PetscViewerSetUp(PetscViewer viewer)
290 {
291   PetscFunctionBegin;
292   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
293   if (viewer->setupcalled) PetscFunctionReturn(PETSC_SUCCESS);
294   PetscTryTypeMethod(viewer, setup);
295   viewer->setupcalled = PETSC_TRUE;
296   PetscFunctionReturn(PETSC_SUCCESS);
297 }
298 
299 /*@C
300   PetscViewerViewFromOptions - View from the viewer based on options in the options database
301 
302   Collective
303 
304   Input Parameters:
305 + A    - the `PetscViewer` context
306 . obj  - Optional object that provides the prefix for the option names
307 - name - command line option
308 
309   Level: intermediate
310 
311   Note:
312   See `PetscObjectViewFromOptions()` for details on the viewers and formats support via this interface
313 
314 .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerView`, `PetscObjectViewFromOptions()`, `PetscViewerCreate()`
315 @*/
316 PetscErrorCode PetscViewerViewFromOptions(PetscViewer A, PetscObject obj, const char name[])
317 {
318   PetscFunctionBegin;
319   PetscValidHeaderSpecific(A, PETSC_VIEWER_CLASSID, 1);
320   PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name));
321   PetscFunctionReturn(PETSC_SUCCESS);
322 }
323 
324 /*@C
325   PetscViewerView - Visualizes a viewer object.
326 
327   Collective
328 
329   Input Parameters:
330 + v      - the viewer to be viewed
331 - viewer - visualization context
332 
333   Level: beginner
334 
335 .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerPushFormat()`, `PetscViewerASCIIOpen()`, `PetscViewerDrawOpen()`,
336           `PetscViewerSocketOpen()`, `PetscViewerBinaryOpen()`, `PetscViewerLoad()`
337 @*/
338 PetscErrorCode PetscViewerView(PetscViewer v, PetscViewer viewer)
339 {
340   PetscBool         iascii;
341   PetscViewerFormat format;
342 #if defined(PETSC_HAVE_SAWS)
343   PetscBool issaws;
344 #endif
345 
346   PetscFunctionBegin;
347   PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 1);
348   PetscValidType(v, 1);
349   if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)v), &viewer));
350   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
351   PetscCheckSameComm(v, 1, viewer, 2);
352 
353   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
354 #if defined(PETSC_HAVE_SAWS)
355   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSAWS, &issaws));
356 #endif
357   if (iascii) {
358     PetscCall(PetscViewerGetFormat(viewer, &format));
359     PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)v, viewer));
360     if (format == PETSC_VIEWER_DEFAULT || format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
361       if (v->format) PetscCall(PetscViewerASCIIPrintf(viewer, "  Viewer format = %s\n", PetscViewerFormats[v->format]));
362       PetscCall(PetscViewerASCIIPushTab(viewer));
363       PetscTryTypeMethod(v, view, viewer);
364       PetscCall(PetscViewerASCIIPopTab(viewer));
365     }
366 #if defined(PETSC_HAVE_SAWS)
367   } else if (issaws) {
368     if (!((PetscObject)v)->amsmem) {
369       PetscCall(PetscObjectViewSAWs((PetscObject)v, viewer));
370       PetscTryTypeMethod(v, view, viewer);
371     }
372 #endif
373   }
374   PetscFunctionReturn(PETSC_SUCCESS);
375 }
376 
377 /*@C
378   PetscViewerRead - Reads data from a `PetscViewer`
379 
380   Collective
381 
382   Input Parameters:
383 + viewer - The viewer
384 . data   - Location to write the data, treated as an array of the type defined by `datatype`
385 . num    - Number of items of data to read
386 - dtype  - Type of data to read
387 
388   Output Parameter:
389 . count - number of items of data actually read, or `NULL`
390 
391   Level: beginner
392 
393   Notes:
394   If datatype is `PETSC_STRING` and `num` is negative, reads until a newline character is found,
395   until a maximum of (-num - 1) chars.
396 
397   Only certain viewers, such as `PETSCVIEWERBINARY` can be read from, see `PetscViewerReadable()`
398 
399 .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerASCIIOpen()`, `PetscViewerPushFormat()`, `PetscViewerDestroy()`,
400           `PetscViewerReadable()`, `PetscViewerBinaryGetDescriptor()`,
401           `PetscViewerBinaryGetInfoPointer()`, `PetscFileMode`
402 @*/
403 PetscErrorCode PetscViewerRead(PetscViewer viewer, void *data, PetscInt num, PetscInt *count, PetscDataType dtype)
404 {
405   PetscFunctionBegin;
406   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
407   if (dtype == PETSC_STRING) {
408     PetscInt c, i = 0, cnt;
409     char    *s = (char *)data;
410     if (num >= 0) {
411       for (c = 0; c < num; c++) {
412         /* Skip leading whitespaces */
413         do {
414           PetscCall((*viewer->ops->read)(viewer, &(s[i]), 1, &cnt, PETSC_CHAR));
415           if (!cnt) break;
416         } while (s[i] == '\n' || s[i] == '\t' || s[i] == ' ' || s[i] == '\0' || s[i] == '\v' || s[i] == '\f' || s[i] == '\r');
417         i++;
418         /* Read strings one char at a time */
419         do {
420           PetscCall((*viewer->ops->read)(viewer, &(s[i++]), 1, &cnt, PETSC_CHAR));
421           if (!cnt) break;
422         } while (s[i - 1] != '\n' && s[i - 1] != '\t' && s[i - 1] != ' ' && s[i - 1] != '\0' && s[i - 1] != '\v' && s[i - 1] != '\f' && s[i - 1] != '\r');
423         /* Terminate final string */
424         if (c == num - 1) s[i - 1] = '\0';
425       }
426     } else {
427       /* Read until a \n is encountered (-num is the max size allowed) */
428       do {
429         PetscCall((*viewer->ops->read)(viewer, &(s[i++]), 1, &cnt, PETSC_CHAR));
430         if (i == -num || !cnt) break;
431       } while (s[i - 1] != '\n');
432       /* Terminate final string */
433       s[i - 1] = '\0';
434       c        = i;
435     }
436     if (count) *count = c;
437     else PetscCheck(c >= num, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_READ, "Insufficient data, only read %" PetscInt_FMT " < %" PetscInt_FMT " strings", c, num);
438   } else PetscUseTypeMethod(viewer, read, data, num, count, dtype);
439   PetscFunctionReturn(PETSC_SUCCESS);
440 }
441 
442 /*@
443   PetscViewerReadable - Return a flag whether the viewer can be read from with `PetscViewerRead()`
444 
445   Not Collective
446 
447   Input Parameter:
448 . viewer - the `PetscViewer` context
449 
450   Output Parameter:
451 . flg - `PETSC_TRUE` if the viewer is readable, `PETSC_FALSE` otherwise
452 
453   Level: intermediate
454 
455   Note:
456   `PETSC_TRUE` means that viewer's `PetscViewerType` supports reading, that is `PetscViewerRead()`, (this holds e.g. for `PETSCVIEWERBINARY`)
457   and the viewer is in a mode allowing reading, i.e. `PetscViewerFileGetMode()`
458   returns one of `FILE_MODE_READ`, `FILE_MODE_UPDATE`, `FILE_MODE_APPEND_UPDATE`.
459 
460 .seealso: [](sec_viewers), `PetscViewerRead()`, `PetscViewer`, `PetscViewerWritable()`, `PetscViewerCheckReadable()`, `PetscViewerCreate()`, `PetscViewerFileSetMode()`, `PetscViewerFileSetType()`
461 @*/
462 PetscErrorCode PetscViewerReadable(PetscViewer viewer, PetscBool *flg)
463 {
464   PetscFileMode mode;
465   PetscErrorCode (*f)(PetscViewer, PetscFileMode *) = NULL;
466 
467   PetscFunctionBegin;
468   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
469   PetscAssertPointer(flg, 2);
470   PetscCall(PetscObjectQueryFunction((PetscObject)viewer, "PetscViewerFileGetMode_C", &f));
471   *flg = PETSC_FALSE;
472   if (!f) PetscFunctionReturn(PETSC_SUCCESS);
473   PetscCall((*f)(viewer, &mode));
474   switch (mode) {
475   case FILE_MODE_READ:
476   case FILE_MODE_UPDATE:
477   case FILE_MODE_APPEND_UPDATE:
478     *flg = PETSC_TRUE;
479   default:
480     break;
481   }
482   PetscFunctionReturn(PETSC_SUCCESS);
483 }
484 
485 /*@
486   PetscViewerWritable - Return a flag whether the viewer can be written to with `PetscViewerWrite()`
487 
488   Not Collective
489 
490   Input Parameter:
491 . viewer - the `PetscViewer` context
492 
493   Output Parameter:
494 . flg - `PETSC_TRUE` if the viewer is writable, `PETSC_FALSE` otherwise
495 
496   Level: intermediate
497 
498   Note:
499   `PETSC_TRUE` means viewer is in a mode allowing writing, i.e. `PetscViewerFileGetMode()`
500   returns one of `FILE_MODE_WRITE`, `FILE_MODE_APPEND`, `FILE_MODE_UPDATE`, `FILE_MODE_APPEND_UPDATE`.
501 
502 .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerReadable()`, `PetscViewerCheckWritable()`, `PetscViewerCreate()`, `PetscViewerFileSetMode()`, `PetscViewerFileSetType()`
503 @*/
504 PetscErrorCode PetscViewerWritable(PetscViewer viewer, PetscBool *flg)
505 {
506   PetscFileMode mode;
507   PetscErrorCode (*f)(PetscViewer, PetscFileMode *) = NULL;
508 
509   PetscFunctionBegin;
510   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
511   PetscAssertPointer(flg, 2);
512   PetscCall(PetscObjectQueryFunction((PetscObject)viewer, "PetscViewerFileGetMode_C", &f));
513   *flg = PETSC_TRUE;
514   if (!f) PetscFunctionReturn(PETSC_SUCCESS);
515   PetscCall((*f)(viewer, &mode));
516   if (mode == FILE_MODE_READ) *flg = PETSC_FALSE;
517   PetscFunctionReturn(PETSC_SUCCESS);
518 }
519 
520 /*@
521   PetscViewerCheckReadable - Check whether the viewer can be read from, generates an error if not
522 
523   Collective
524 
525   Input Parameter:
526 . viewer - the `PetscViewer` context
527 
528   Level: intermediate
529 
530 .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerReadable()`, `PetscViewerCheckWritable()`, `PetscViewerCreate()`, `PetscViewerFileSetMode()`, `PetscViewerFileSetType()`
531 @*/
532 PetscErrorCode PetscViewerCheckReadable(PetscViewer viewer)
533 {
534   PetscBool flg;
535 
536   PetscFunctionBegin;
537   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
538   PetscCall(PetscViewerReadable(viewer, &flg));
539   PetscCheck(flg, PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Viewer doesn't support reading, or is not in reading mode (FILE_MODE_READ, FILE_MODE_UPDATE, FILE_MODE_APPEND_UPDATE)");
540   PetscFunctionReturn(PETSC_SUCCESS);
541 }
542 
543 /*@
544   PetscViewerCheckWritable - Check whether the viewer can be written to, generates an error if not
545 
546   Collective
547 
548   Input Parameter:
549 . viewer - the `PetscViewer` context
550 
551   Level: intermediate
552 
553 .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerWritable()`, `PetscViewerCheckReadable()`, `PetscViewerCreate()`, `PetscViewerFileSetMode()`, `PetscViewerFileSetType()`
554 @*/
555 PetscErrorCode PetscViewerCheckWritable(PetscViewer viewer)
556 {
557   PetscBool flg;
558 
559   PetscFunctionBegin;
560   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
561   PetscCall(PetscViewerWritable(viewer, &flg));
562   PetscCheck(flg, PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Viewer doesn't support writing, or is in FILE_MODE_READ mode");
563   PetscFunctionReturn(PETSC_SUCCESS);
564 }
565