xref: /petsc/src/sys/classes/viewer/interface/view.c (revision bfcb38ea38335faa6e7f8d97f6bc6ce9aa2a1dd1)
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 = 0; 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    PetscViewerView - Visualizes a viewer object.
335 
336    Collective on PetscViewer
337 
338    Input Parameters:
339 +  v - the viewer
340 -  viewer - visualization context
341 
342   Notes:
343   The available visualization contexts include
344 +    PETSC_VIEWER_STDOUT_SELF - standard output (default)
345 .    PETSC_VIEWER_STDOUT_WORLD - synchronized standard
346         output where only the first processor opens
347         the file.  All other processors send their
348         data to the first processor to print.
349 -     PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure
350 
351    Level: beginner
352 
353 .seealso: PetscViewerPushFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(),
354           PetscViewerSocketOpen(), PetscViewerBinaryOpen(), PetscViewerLoad()
355 @*/
356 PetscErrorCode  PetscViewerView(PetscViewer v,PetscViewer viewer)
357 {
358   PetscErrorCode    ierr;
359   PetscBool         iascii;
360   PetscViewerFormat format;
361 #if defined(PETSC_HAVE_SAWS)
362   PetscBool         issaws;
363 #endif
364 
365   PetscFunctionBegin;
366   PetscValidHeaderSpecific(v,PETSC_VIEWER_CLASSID,1);
367   PetscValidType(v,1);
368   if (!viewer) {
369     ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)v),&viewer);CHKERRQ(ierr);
370   }
371   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
372   PetscCheckSameComm(v,1,viewer,2);
373 
374   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
375 #if defined(PETSC_HAVE_SAWS)
376   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);CHKERRQ(ierr);
377 #endif
378   if (iascii) {
379     ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
380     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)v,viewer);CHKERRQ(ierr);
381     if (format == PETSC_VIEWER_DEFAULT || format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
382       if (v->format) {
383         ierr = PetscViewerASCIIPrintf(viewer,"  Viewer format = %s\n",PetscViewerFormats[v->format]);CHKERRQ(ierr);
384       }
385       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
386       if (v->ops->view) {
387         ierr = (*v->ops->view)(v,viewer);CHKERRQ(ierr);
388       }
389       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
390     }
391 #if defined(PETSC_HAVE_SAWS)
392   } else if (issaws) {
393     if (!((PetscObject)v)->amsmem) {
394       ierr = PetscObjectViewSAWs((PetscObject)v,viewer);CHKERRQ(ierr);
395       if (v->ops->view) {
396         ierr = (*v->ops->view)(v,viewer);CHKERRQ(ierr);
397       }
398     }
399 #endif
400   }
401   PetscFunctionReturn(0);
402 }
403 
404 /*@C
405    PetscViewerRead - Reads data from a PetscViewer
406 
407    Collective on MPI_Comm
408 
409    Input Parameters:
410 +  viewer   - The viewer
411 .  data     - Location to write the data
412 .  num      - Number of items of data to read
413 -  datatype - Type of data to read
414 
415    Output Parameters:
416 .  count - number of items of data actually read, or NULL
417 
418    Notes:
419    If datatype is PETSC_STRING and num is negative, reads until a newline character is found,
420    until a maximum of (-num - 1) chars.
421 
422    Level: beginner
423 
424    Concepts: binary files, ascii files
425 
426 .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
427           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
428           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer
429 @*/
430 PetscErrorCode  PetscViewerRead(PetscViewer viewer, void *data, PetscInt num, PetscInt *count, PetscDataType dtype)
431 {
432   PetscErrorCode ierr;
433 
434   PetscFunctionBegin;
435   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
436   if (dtype == PETSC_STRING) {
437     PetscInt c, i = 0, cnt;
438     char *s = (char *)data;
439     if (num >= 0) {
440       for (c = 0; c < num; c++) {
441         /* Skip leading whitespaces */
442         do {ierr = (*viewer->ops->read)(viewer, &(s[i]), 1, &cnt, PETSC_CHAR);CHKERRQ(ierr); if (!cnt) break;}
443         while (s[i]=='\n' || s[i]=='\t' || s[i]==' ' || s[i]=='\0' || s[i]=='\v' || s[i]=='\f' || s[i]=='\r');
444         i++;
445         /* Read strings one char at a time */
446         do {ierr = (*viewer->ops->read)(viewer, &(s[i++]), 1, &cnt, PETSC_CHAR);CHKERRQ(ierr); if (!cnt) break;}
447         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');
448         /* Terminate final string */
449         if (c == num-1) s[i-1] = '\0';
450       }
451     } else {
452       /* Read until a \n is encountered (-num is the max size allowed) */
453       do {ierr = (*viewer->ops->read)(viewer, &(s[i++]), 1, &cnt, PETSC_CHAR);CHKERRQ(ierr); if (i == -num || !cnt) break;}
454       while (s[i-1]!='\n');
455       /* Terminate final string */
456       s[i-1] = '\0';
457       c      = i;
458     }
459     if (count) *count = c;
460     else if (c < num) SETERRQ2(PetscObjectComm((PetscObject) viewer), PETSC_ERR_FILE_READ, "Insufficient data, only read %D < %D strings", c, num);
461   } else {
462     ierr = (*viewer->ops->read)(viewer, data, num, count, dtype);CHKERRQ(ierr);
463   }
464   PetscFunctionReturn(0);
465 }
466 
467 /*@
468    PetscViewerReadable - Return a flag whether the viewer can be read from
469 
470    Not Collective
471 
472    Input Parameters:
473 .  viewer - the PetscViewer context
474 
475    Output Parameters:
476 .  flg - PETSC_TRUE if the viewer is readable, PETSC_FALSE otherwise
477 
478    Notes:
479    PETSC_TRUE means that viewer's PetscViewerType supports reading (this holds e.g. for PETSCVIEWERBINARY)
480    and viewer is in a mode allowing reading, i.e. PetscViewerFileGetMode()
481    returns one of FILE_MODE_READ, FILE_MODE_UPDATE, FILE_MODE_APPEND_UPDATE.
482 
483    Level: intermediate
484 
485 .seealso: PetscViewerWritable(), PetscViewerCheckReadable(), PetscViewerCreate(), PetscViewerFileSetMode(), PetscViewerFileSetType()
486 @*/
487 PetscErrorCode  PetscViewerReadable(PetscViewer viewer, PetscBool *flg)
488 {
489   PetscErrorCode    ierr;
490   PetscFileMode     mode;
491   PetscErrorCode    (*f)(PetscViewer,PetscFileMode*) = NULL;
492 
493   PetscFunctionBegin;
494   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
495   PetscValidIntPointer(flg,2);
496   ierr = PetscObjectQueryFunction((PetscObject)viewer, "PetscViewerFileGetMode_C", &f);CHKERRQ(ierr);
497   *flg = PETSC_FALSE;
498   if (!f) PetscFunctionReturn(0);
499   ierr = (*f)(viewer, &mode);CHKERRQ(ierr);
500   switch (mode) {
501     case FILE_MODE_READ:
502     case FILE_MODE_UPDATE:
503     case FILE_MODE_APPEND_UPDATE:
504       *flg = PETSC_TRUE;
505     default: break;
506   }
507   PetscFunctionReturn(0);
508 }
509 
510 /*@
511    PetscViewerWritable - Return a flag whether the viewer can be written to
512 
513    Not Collective
514 
515    Input Parameters:
516 .  viewer - the PetscViewer context
517 
518    Output Parameters:
519 .  flg - PETSC_TRUE if the viewer is writable, PETSC_FALSE otherwise
520 
521    Notes:
522    PETSC_TRUE means viewer is in a mode allowing writing, i.e. PetscViewerFileGetMode()
523    returns one of FILE_MODE_WRITE, FILE_MODE_APPEND, FILE_MODE_UPDATE, FILE_MODE_APPEND_UPDATE.
524 
525    Level: intermediate
526 
527 .seealso: PetscViewerReadable(), PetscViewerCheckWritable(), PetscViewerCreate(), PetscViewerFileSetMode(), PetscViewerFileSetType()
528 @*/
529 PetscErrorCode  PetscViewerWritable(PetscViewer viewer, PetscBool *flg)
530 {
531   PetscErrorCode    ierr;
532   PetscFileMode     mode;
533   PetscErrorCode    (*f)(PetscViewer,PetscFileMode*) = NULL;
534 
535   PetscFunctionBegin;
536   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
537   PetscValidIntPointer(flg,2);
538   ierr = PetscObjectQueryFunction((PetscObject)viewer, "PetscViewerFileGetMode_C", &f);CHKERRQ(ierr);
539   *flg = PETSC_TRUE;
540   if (!f) PetscFunctionReturn(0);
541   ierr = (*f)(viewer, &mode);CHKERRQ(ierr);
542   if (mode == FILE_MODE_READ) *flg = PETSC_FALSE;
543   PetscFunctionReturn(0);
544 }
545 
546 /*@
547    PetscViewerCheckReadable - Check whether the viewer can be read from
548 
549    Collective
550 
551    Input Parameters:
552 .  viewer - the PetscViewer context
553 
554    Level: intermediate
555 
556 .seealso: PetscViewerReadable(), PetscViewerCheckWritable(), PetscViewerCreate(), PetscViewerFileSetMode(), PetscViewerFileSetType()
557 @*/
558 PetscErrorCode  PetscViewerCheckReadable(PetscViewer viewer)
559 {
560   PetscBool         flg;
561   PetscErrorCode    ierr;
562 
563   PetscFunctionBegin;
564   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
565   ierr = PetscViewerReadable(viewer, &flg);CHKERRQ(ierr);
566   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)");
567   PetscFunctionReturn(0);
568 }
569 
570 /*@
571    PetscViewerCheckWritable - Check whether the viewer can be written to
572 
573    Collective
574 
575    Input Parameters:
576 .  viewer - the PetscViewer context
577 
578    Level: intermediate
579 
580 .seealso: PetscViewerWritable(), PetscViewerCheckReadable(), PetscViewerCreate(), PetscViewerFileSetMode(), PetscViewerFileSetType()
581 @*/
582 PetscErrorCode  PetscViewerCheckWritable(PetscViewer viewer)
583 {
584   PetscBool         flg;
585   PetscErrorCode    ierr;
586 
587   PetscFunctionBegin;
588   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
589   ierr = PetscViewerWritable(viewer, &flg);CHKERRQ(ierr);
590   if (!flg) SETERRQ(PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Viewer doesn't support writing, or is in FILE_MODE_READ mode");
591   PetscFunctionReturn(0);
592 }
593