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