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