xref: /petsc/src/sys/classes/viewer/interface/viewreg.c (revision 8540dad3b2fdd8ef545edc3be868c162ab2475da)
1 
2 #include <petsc/private/viewerimpl.h>  /*I "petscviewer.h" I*/
3 #if defined(PETSC_HAVE_SAWS)
4 #include <petscviewersaws.h>
5 #endif
6 
7 PetscFunctionList PetscViewerList = 0;
8 
9 #include "../src/sys/utils/hash.h"
10 
11 
12 PetscOptionsHelpPrinted PetscOptionsHelpPrintedSingleton = NULL;
13 KHASH_SET_INIT_STR(HTPrinted)
14 struct  _n_PetscOptionsHelpPrinted{
15   khash_t(HTPrinted) *printed;
16   PetscSegBuffer     strings;
17 };
18 
19 #undef __FUNCT__
20 #define __FUNCT__ "PetscOptionsHelpPrintedDestroy"
21 PetscErrorCode PetscOptionsHelpPrintedDestroy(PetscOptionsHelpPrinted *hp)
22 {
23   PetscErrorCode ierr;
24 
25   PetscFunctionBegin;
26   if (!*hp) PetscFunctionReturn(0);
27   kh_destroy(HTPrinted,(*hp)->printed);
28   ierr = PetscSegBufferDestroy(&(*hp)->strings);CHKERRQ(ierr);
29   ierr = PetscFree(*hp);CHKERRQ(ierr);
30   PetscFunctionReturn(0);
31 }
32 
33 #undef __FUNCT__
34 #define __FUNCT__ "PetscOptionsHelpPrintedCreate"
35 /*@C
36       PetscOptionsHelpPrintedCreate - Creates an object used to manage tracking which help messages have
37          been printed so they will not be printed again.
38 
39      Not collective
40 
41     Level: developer
42 
43 .seealso: PetscOptionsHelpPrintedCheck(), PetscOptionsHelpPrintChecked()
44 @*/
45 PetscErrorCode PetscOptionsHelpPrintedCreate(PetscOptionsHelpPrinted *hp)
46 {
47   PetscErrorCode             ierr;
48 
49   PetscFunctionBegin;
50   ierr = PetscNew(hp);CHKERRQ(ierr);
51   (*hp)->printed = kh_init(HTPrinted);
52   ierr = PetscSegBufferCreate(sizeof(char),10000,&(*hp)->strings);CHKERRQ(ierr);
53   PetscFunctionReturn(0);
54 }
55 
56 #undef __FUNCT__
57 #define __FUNCT__ "PetscOptionsHelpPrintedCheck"
58 /*@C
59       PetscOptionsHelpPrintedCheck - Checks if a particular pre, name pair has previous been entered (meaning the help message was printed)
60 
61      Not collective
62 
63     Input Parameters:
64 +     hp - the object used to manage tracking what help messages have been printed
65 .     pre - the prefix part of the string, many be NULL
66 -     name - the string to look for (cannot be NULL)
67 
68     Output Parameter:
69 .     found - PETSC_TRUE if the string was already set
70 
71     Level: intermediate
72 
73 
74 .seealso: PetscOptionsHelpPrintedCreate()
75 @*/
76 PetscErrorCode PetscOptionsHelpPrintedCheck(PetscOptionsHelpPrinted hp,const char *pre,const char* name,PetscBool *found)
77 {
78   size_t          l1,l2;
79 #if !defined(PETSC_HAVE_THREADSAFETY)
80   char            *both;
81   khint_t         newitem;
82 #endif
83   PetscErrorCode  ierr;
84 
85   PetscFunctionBegin;
86   ierr = PetscStrlen(pre,&l1);CHKERRQ(ierr);
87   ierr = PetscStrlen(name,&l2);CHKERRQ(ierr);
88   if (l1+l2 == 0) {
89     *found = PETSC_FALSE;
90     PetscFunctionReturn(0);
91   }
92 #if !defined(PETSC_HAVE_THREADSAFETY)
93   ierr = PetscSegBufferGet(hp->strings,l1+l2+1,&both);CHKERRQ(ierr);
94   ierr = PetscStrcpy(both,pre);CHKERRQ(ierr);
95   ierr = PetscStrcat(both,name);CHKERRQ(ierr);
96   kh_put(HTPrinted,hp->printed,both,&newitem);
97   if (!newitem) {
98     ierr = PetscSegBufferUnuse(hp->strings,l1+l2+1);CHKERRQ(ierr);
99   }
100   *found = newitem ? PETSC_FALSE : PETSC_TRUE;
101 #else
102   *found = PETSC_FALSE;
103 #endif
104   PetscFunctionReturn(0);
105 }
106 
107 static PetscBool noviewer = PETSC_FALSE;
108 static PetscBool noviewers[PETSCVIEWERGETVIEWEROFFPUSHESMAX];
109 static PetscInt  inoviewers = 0;
110 
111 #undef __FUNCT__
112 #define __FUNCT__ "PetscOptionsPushGetViewerOff"
113 /*@
114   PetscOptionsPushGetViewerOff - control whether PetscOptionsGetViewer returns a viewer.
115 
116   Logically Collective
117 
118   Input Parameter:
119 . flg - PETSC_TRUE to turn off viewer creation, PETSC_FALSE to turn it on.
120 
121   Level: developer
122 
123   Notes: Calling XXXViewFromOptions in an inner loop can be very expensive.  This can appear, for example, when using
124    many small subsolves.  Call this function to control viewer creation in PetscOptionsGetViewer, thus removing the expensive XXXViewFromOptions calls.
125 
126 .seealso: PetscOptionsGetViewer(), PetscOptionsPopGetViewerOff()
127 @*/
128 PetscErrorCode  PetscOptionsPushGetViewerOff(PetscBool flg)
129 {
130   PetscFunctionBegin;
131   if (inoviewers > PETSCVIEWERGETVIEWEROFFPUSHESMAX - 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many PetscOptionsPushGetViewerOff(), perhaps you forgot PetscOptionsPopGetViewerOff()?");
132 
133   noviewers[inoviewers++] = noviewer;
134   noviewer = flg;
135   PetscFunctionReturn(0);
136 }
137 
138 #undef __FUNCT__
139 #define __FUNCT__ "PetscOptionsPopGetViewerOff"
140 /*@
141   PetscOptionsPopGetViewerOff - reset whether PetscOptionsGetViewer returns a viewer.
142 
143   Logically Collective
144 
145   Level: developer
146 
147   Notes: Calling XXXViewFromOptions in an inner loop can be very expensive.  This can appear, for example, when using
148    many small subsolves.  Call this function to control viewer creation in PetscOptionsGetViewer, thus removing the expensive XXXViewFromOptions calls.
149 
150 .seealso: PetscOptionsGetViewer(), PetscOptionsPushGetViewerOff()
151 @*/
152 PetscErrorCode  PetscOptionsPopGetViewerOff()
153 {
154   PetscFunctionBegin;
155   if (!inoviewers) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many PetscOptionsPopGetViewerOff(), perhaps you forgot PetscOptionsPushGetViewerOff()?");
156   noviewer = noviewers[--inoviewers];
157   PetscFunctionReturn(0);
158 }
159 
160 #undef __FUNCT__
161 #define __FUNCT__ "PetscOptionsGetViewerOff"
162 /*@
163   PetscOptionsGetViewerOff - does PetscOptionsGetViewer return a viewer?
164 
165   Logically Collective
166 
167   Output Parameter:
168 . flg - whether viewers are returned.
169 
170   Level: developer
171 
172   Notes: Calling XXXViewFromOptions in an inner loop can be very expensive.  This can appear, for example, when using
173    many small subsolves.
174 
175 .seealso: PetscOptionsGetViewer(), PetscOptionsPushGetViewerOff(), PetscOptionsPopGetViewerOff()
176 @*/
177 PetscErrorCode  PetscOptionsGetViewerOff(PetscBool *flg)
178 {
179   PetscFunctionBegin;
180   PetscValidPointer(flg,0);
181   *flg = noviewer;
182   PetscFunctionReturn(0);
183 }
184 
185 #undef __FUNCT__
186 #define __FUNCT__ "PetscOptionsGetViewer"
187 /*@C
188    PetscOptionsGetViewer - Gets a viewer appropriate for the type indicated by the user
189 
190    Collective on MPI_Comm
191 
192    Input Parameters:
193 +  comm - the communicator to own the viewer
194 .  pre - the string to prepend to the name or NULL
195 -  name - the option one is seeking
196 
197    Output Parameter:
198 +  viewer - the viewer, pass NULL if not needed
199 .  format - the PetscViewerFormat requested by the user, pass NULL if not needed
200 -  set - PETSC_TRUE if found, else PETSC_FALSE
201 
202    Level: intermediate
203 
204    Notes: If no value is provided ascii:stdout is used
205 $       ascii[:[filename][:[format][:append]]]    defaults to stdout - format can be one of ascii_info, ascii_info_detail, or ascii_matlab,
206                                                   for example ascii::ascii_info prints just the information about the object not all details
207                                                   unless :append is given filename opens in write mode, overwriting what was already there
208 $       binary[:[filename][:[format][:append]]]   defaults to the file binaryoutput
209 $       draw[:drawtype[:filename]]                for example, draw:tikz, draw:tikz:figure.tex  or draw:x
210 $       socket[:port]                             defaults to the standard output port
211 $       saws[:communicatorname]                    publishes object to the Scientific Application Webserver (SAWs)
212 
213    Use PetscViewerDestroy() after using the viewer, otherwise a memory leak will occur
214 
215    You can control whether calls to this function create a viewer (or return early with *set of PETSC_FALSE) with
216    PetscOptionsPushGetViewerOff.  This is useful if calling many small subsolves, in which case XXXViewFromOptions can take
217    an appreciable fraction of the runtime.
218 
219    If PETSc is configured with --with-viewfromoptions=0 this function always returns with *set of PETSC_FALSE
220 
221 .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
222           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
223           PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
224           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
225           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
226           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
227           PetscOptionsFList(), PetscOptionsEList(), PetscOptionsPushGetViewerOff(), PetscOptionsPopGetViewerOff(),
228           PetscOptionsGetViewerOff()
229 @*/
230 PetscErrorCode  PetscOptionsGetViewer(MPI_Comm comm,const char pre[],const char name[],PetscViewer *viewer,PetscViewerFormat *format,PetscBool  *set)
231 {
232   char                           *value;
233   PetscErrorCode                 ierr;
234   PetscBool                      flag,hashelp;
235 
236   PetscFunctionBegin;
237   PetscValidCharPointer(name,3);
238 
239   if (set) *set = PETSC_FALSE;
240 #if defined(PETSC_SKIP_VIEWFROMOPTIONS)
241   PetscFunctionReturn(0);
242 #endif
243   ierr = PetscOptionsGetViewerOff(&flag);CHKERRQ(ierr);
244   if (flag) PetscFunctionReturn(0);
245 
246   ierr = PetscLogEventBegin(PetscOptions_GetViewer,0,0,0,0);CHKERRQ(ierr);
247   ierr = PetscOptionsHasName(NULL,NULL,"-help",&hashelp);CHKERRQ(ierr);
248   if (hashelp) {
249     PetscBool found;
250 
251     if (!PetscOptionsHelpPrintedSingleton) {
252       ierr = PetscOptionsHelpPrintedCreate(&PetscOptionsHelpPrintedSingleton);CHKERRQ(ierr);
253     }
254     ierr = PetscOptionsHelpPrintedCheck(PetscOptionsHelpPrintedSingleton,pre,name,&found);CHKERRQ(ierr);
255     if (!found) {
256       if (viewer) {
257         ierr = (*PetscHelpPrintf)(comm,"\n  -%s%s ascii[:[filename][:[format][:append]]]: %s (%s)\n",pre ? pre : "",name+1,"Prints object to stdout or ASCII file","PetscOptionsGetViewer");CHKERRQ(ierr);
258         ierr = (*PetscHelpPrintf)(comm,"    -%s%s binary[:[filename][:[format][:append]]]: %s (%s)\n",pre ? pre : "",name+1,"Saves object to a binary file","PetscOptionsGetViewer");CHKERRQ(ierr);
259         ierr = (*PetscHelpPrintf)(comm,"    -%s%s draw[:drawtype[:filename]] %s (%s)\n",pre ? pre : "",name+1,"Draws object","PetscOptionsGetViewer");CHKERRQ(ierr);
260         ierr = (*PetscHelpPrintf)(comm,"    -%s%s socket[:port]: %s (%s)\n",pre ? pre : "",name+1,"Pushes object to a Unix socket","PetscOptionsGetViewer");CHKERRQ(ierr);
261         ierr = (*PetscHelpPrintf)(comm,"    -%s%s saws[:communicatorname]: %s (%s)\n\n",pre ? pre : "",name+1,"Publishes object to SAWs","PetscOptionsGetViewer");CHKERRQ(ierr);
262       } else {
263         ierr = (*PetscHelpPrintf)(comm,"    -%s%s\n",pre ? pre : "",name+1);CHKERRQ(ierr);
264       }
265     }
266   }
267 
268   if (format) *format = PETSC_VIEWER_DEFAULT;
269   ierr = PetscOptionsFindPair_Private(NULL,pre,name,&value,&flag);CHKERRQ(ierr);
270   if (flag) {
271     if (set) *set = PETSC_TRUE;
272     if (!value) {
273       if (viewer) {
274         ierr = PetscViewerASCIIGetStdout(comm,viewer);CHKERRQ(ierr);
275         ierr = PetscObjectReference((PetscObject)*viewer);CHKERRQ(ierr);
276       }
277     } else {
278       char       *loc0_vtype,*loc1_fname,*loc2_fmt = NULL,*loc3_fmode = NULL;
279       PetscInt   cnt;
280       const char *viewers[] = {PETSCVIEWERASCII,PETSCVIEWERBINARY,PETSCVIEWERDRAW,PETSCVIEWERSOCKET,PETSCVIEWERMATLAB,PETSCVIEWERSAWS,PETSCVIEWERVTK,PETSCVIEWERHDF5,0};
281 
282       ierr = PetscStrallocpy(value,&loc0_vtype);CHKERRQ(ierr);
283       ierr = PetscStrchr(loc0_vtype,':',&loc1_fname);CHKERRQ(ierr);
284       if (loc1_fname) {
285         *loc1_fname++ = 0;
286         ierr = PetscStrchr(loc1_fname,':',&loc2_fmt);CHKERRQ(ierr);
287       }
288       if (loc2_fmt) {
289         *loc2_fmt++ = 0;
290         ierr = PetscStrchr(loc2_fmt,':',&loc3_fmode);CHKERRQ(ierr);
291       }
292       if (loc3_fmode) *loc3_fmode++ = 0;
293       ierr = PetscStrendswithwhich(*loc0_vtype ? loc0_vtype : "ascii",viewers,&cnt);CHKERRQ(ierr);
294       if (cnt > (PetscInt) sizeof(viewers)-1) SETERRQ1(comm,PETSC_ERR_ARG_OUTOFRANGE,"Unknown viewer type: %s",loc0_vtype);
295       if (viewer) {
296         if (!loc1_fname) {
297           switch (cnt) {
298           case 0:
299             ierr = PetscViewerASCIIGetStdout(comm,viewer);CHKERRQ(ierr);
300             break;
301           case 1:
302             if (!(*viewer = PETSC_VIEWER_BINARY_(comm))) CHKERRQ(PETSC_ERR_PLIB);
303             break;
304           case 2:
305             if (!(*viewer = PETSC_VIEWER_DRAW_(comm))) CHKERRQ(PETSC_ERR_PLIB);
306             break;
307 #if defined(PETSC_USE_SOCKET_VIEWER)
308           case 3:
309             if (!(*viewer = PETSC_VIEWER_SOCKET_(comm))) CHKERRQ(PETSC_ERR_PLIB);
310             break;
311 #endif
312 #if defined(PETSC_HAVE_MATLAB_ENGINE)
313           case 4:
314             if (!(*viewer = PETSC_VIEWER_MATLAB_(comm))) CHKERRQ(PETSC_ERR_PLIB);
315             break;
316 #endif
317 #if defined(PETSC_HAVE_SAWS)
318           case 5:
319             if (!(*viewer = PETSC_VIEWER_SAWS_(comm))) CHKERRQ(PETSC_ERR_PLIB);
320             break;
321 #endif
322 #if defined(PETSC_HAVE_HDF5)
323           case 7:
324             if (!(*viewer = PETSC_VIEWER_HDF5_(comm))) CHKERRQ(PETSC_ERR_PLIB);
325             break;
326 #endif
327           default: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unsupported viewer %s",loc0_vtype);
328           }
329           ierr = PetscObjectReference((PetscObject)*viewer);CHKERRQ(ierr);
330         } else {
331           if (loc2_fmt && !*loc1_fname && (cnt == 0)) { /* ASCII format without file name */
332             ierr = PetscViewerASCIIGetStdout(comm,viewer);CHKERRQ(ierr);
333             ierr = PetscObjectReference((PetscObject)*viewer);CHKERRQ(ierr);
334           } else {
335             PetscFileMode fmode;
336             ierr = PetscViewerCreate(comm,viewer);CHKERRQ(ierr);
337             ierr = PetscViewerSetType(*viewer,*loc0_vtype ? loc0_vtype : "ascii");CHKERRQ(ierr);
338             fmode = FILE_MODE_WRITE;
339             if (loc3_fmode && *loc3_fmode) { /* Has non-empty file mode ("write" or "append") */
340               ierr = PetscEnumFind(PetscFileModes,loc3_fmode,(PetscEnum*)&fmode,&flag);CHKERRQ(ierr);
341               if (!flag) SETERRQ1(comm,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown file mode: %s",loc3_fmode);
342             }
343             if (loc2_fmt) {
344               PetscBool tk;
345               ierr = PetscStrcmp(loc1_fname,"tikz",&tk);CHKERRQ(ierr);
346               if (tk) {
347                 ierr = PetscViewerDrawSetInfo(*viewer,NULL,loc2_fmt,0,0,0,0);CHKERRQ(ierr);
348                 *loc2_fmt = 0;
349               }
350             }
351             ierr = PetscViewerFileSetMode(*viewer,flag?fmode:FILE_MODE_WRITE);CHKERRQ(ierr);
352             ierr = PetscViewerFileSetName(*viewer,loc1_fname);CHKERRQ(ierr);
353             ierr = PetscViewerDrawSetDrawType(*viewer,loc1_fname);CHKERRQ(ierr);
354           }
355         }
356       }
357       if (viewer) {
358         ierr = PetscViewerSetUp(*viewer);CHKERRQ(ierr);
359       }
360       if (loc2_fmt && *loc2_fmt) {
361         ierr = PetscEnumFind(PetscViewerFormats,loc2_fmt,(PetscEnum*)format,&flag);CHKERRQ(ierr);
362         if (!flag) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unknown viewer format %s",loc2_fmt);CHKERRQ(ierr);
363       }
364       ierr = PetscFree(loc0_vtype);CHKERRQ(ierr);
365     }
366   }
367   ierr = PetscLogEventEnd(PetscOptions_GetViewer,0,0,0,0);CHKERRQ(ierr);
368   PetscFunctionReturn(0);
369 }
370 
371 #undef __FUNCT__
372 #define __FUNCT__ "PetscViewerCreate"
373 /*@
374    PetscViewerCreate - Creates a viewing context
375 
376    Collective on MPI_Comm
377 
378    Input Parameter:
379 .  comm - MPI communicator
380 
381    Output Parameter:
382 .  inviewer - location to put the PetscViewer context
383 
384    Level: advanced
385 
386    Concepts: graphics^creating PetscViewer
387    Concepts: file input/output^creating PetscViewer
388    Concepts: sockets^creating PetscViewer
389 
390 .seealso: PetscViewerDestroy(), PetscViewerSetType(), PetscViewerType
391 
392 @*/
393 PetscErrorCode  PetscViewerCreate(MPI_Comm comm,PetscViewer *inviewer)
394 {
395   PetscViewer    viewer;
396   PetscErrorCode ierr;
397 
398   PetscFunctionBegin;
399   *inviewer = 0;
400   ierr = PetscViewerInitializePackage();CHKERRQ(ierr);
401   ierr         = PetscHeaderCreate(viewer,PETSC_VIEWER_CLASSID,"PetscViewer","PetscViewer","Viewer",comm,PetscViewerDestroy,NULL);CHKERRQ(ierr);
402   *inviewer    = viewer;
403   viewer->data = 0;
404   PetscFunctionReturn(0);
405 }
406 
407 #undef __FUNCT__
408 #define __FUNCT__ "PetscViewerSetType"
409 /*@C
410    PetscViewerSetType - Builds PetscViewer for a particular implementation.
411 
412    Collective on PetscViewer
413 
414    Input Parameter:
415 +  viewer      - the PetscViewer context
416 -  type        - for example, PETSCVIEWERASCII
417 
418    Options Database Command:
419 .  -draw_type  <type> - Sets the type; use -help for a list
420     of available methods (for instance, ascii)
421 
422    Level: advanced
423 
424    Notes:
425    See "include/petscviewer.h" for available methods (for instance,
426    PETSCVIEWERSOCKET)
427 
428 .seealso: PetscViewerCreate(), PetscViewerGetType(), PetscViewerType, PetscViewerPushFormat()
429 @*/
430 PetscErrorCode  PetscViewerSetType(PetscViewer viewer,PetscViewerType type)
431 {
432   PetscErrorCode ierr,(*r)(PetscViewer);
433   PetscBool      match;
434 
435   PetscFunctionBegin;
436   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
437   PetscValidCharPointer(type,2);
438   ierr = PetscObjectTypeCompare((PetscObject)viewer,type,&match);CHKERRQ(ierr);
439   if (match) PetscFunctionReturn(0);
440 
441   /* cleanup any old type that may be there */
442   if (viewer->data) {
443     ierr         = (*viewer->ops->destroy)(viewer);CHKERRQ(ierr);
444 
445     viewer->ops->destroy = NULL;
446     viewer->data         = 0;
447   }
448   ierr = PetscMemzero(viewer->ops,sizeof(struct _PetscViewerOps));CHKERRQ(ierr);
449 
450   ierr =  PetscFunctionListFind(PetscViewerList,type,&r);CHKERRQ(ierr);
451   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown PetscViewer type given: %s",type);
452 
453   ierr = PetscObjectChangeTypeName((PetscObject)viewer,type);CHKERRQ(ierr);
454   ierr = (*r)(viewer);CHKERRQ(ierr);
455   PetscFunctionReturn(0);
456 }
457 
458 #undef __FUNCT__
459 #define __FUNCT__ "PetscViewerRegister"
460 /*@C
461    PetscViewerRegister - Adds a viewer
462 
463    Not Collective
464 
465    Input Parameters:
466 +  name_solver - name of a new user-defined viewer
467 -  routine_create - routine to create method context
468 
469    Level: developer
470    Notes:
471    PetscViewerRegister() may be called multiple times to add several user-defined viewers.
472 
473    Sample usage:
474 .vb
475    PetscViewerRegister("my_viewer_type",MyViewerCreate);
476 .ve
477 
478    Then, your solver can be chosen with the procedural interface via
479 $     PetscViewerSetType(viewer,"my_viewer_type")
480    or at runtime via the option
481 $     -viewer_type my_viewer_type
482 
483   Concepts: registering^Viewers
484 
485 .seealso: PetscViewerRegisterAll(), PetscViewerRegisterDestroy()
486  @*/
487 PetscErrorCode  PetscViewerRegister(const char *sname,PetscErrorCode (*function)(PetscViewer))
488 {
489   PetscErrorCode ierr;
490 
491   PetscFunctionBegin;
492   ierr = PetscFunctionListAdd(&PetscViewerList,sname,function);CHKERRQ(ierr);
493   PetscFunctionReturn(0);
494 }
495 
496 #undef __FUNCT__
497 #define __FUNCT__ "PetscViewerSetFromOptions"
498 /*@C
499    PetscViewerSetFromOptions - Sets the graphics type from the options database.
500       Defaults to a PETSc X windows graphics.
501 
502    Collective on PetscViewer
503 
504    Input Parameter:
505 .     PetscViewer - the graphics context
506 
507    Level: intermediate
508 
509    Notes:
510     Must be called after PetscViewerCreate() before the PetscViewer is used.
511 
512   Concepts: PetscViewer^setting options
513 
514 .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerType
515 
516 @*/
517 PetscErrorCode  PetscViewerSetFromOptions(PetscViewer viewer)
518 {
519   PetscErrorCode    ierr;
520   char              vtype[256];
521   PetscBool         flg;
522 
523   PetscFunctionBegin;
524   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
525 
526   if (!PetscViewerList) {
527     ierr = PetscViewerRegisterAll();CHKERRQ(ierr);
528   }
529   ierr = PetscObjectOptionsBegin((PetscObject)viewer);CHKERRQ(ierr);
530   ierr = PetscOptionsFList("-viewer_type","Type of PetscViewer","None",PetscViewerList,(char*)(((PetscObject)viewer)->type_name ? ((PetscObject)viewer)->type_name : PETSCVIEWERASCII),vtype,256,&flg);CHKERRQ(ierr);
531   if (flg) {
532     ierr = PetscViewerSetType(viewer,vtype);CHKERRQ(ierr);
533   }
534   /* type has not been set? */
535   if (!((PetscObject)viewer)->type_name) {
536     ierr = PetscViewerSetType(viewer,PETSCVIEWERASCII);CHKERRQ(ierr);
537   }
538   if (viewer->ops->setfromoptions) {
539     ierr = (*viewer->ops->setfromoptions)(PetscOptionsObject,viewer);CHKERRQ(ierr);
540   }
541 
542   /* process any options handlers added with PetscObjectAddOptionsHandler() */
543   ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)viewer);CHKERRQ(ierr);
544   ierr = PetscViewerViewFromOptions(viewer,NULL,"-viewer_view");CHKERRQ(ierr);
545   ierr = PetscOptionsEnd();CHKERRQ(ierr);
546   PetscFunctionReturn(0);
547 }
548 
549 #undef __FUNCT__
550 #define __FUNCT__ "PetscViewerFlowControlStart"
551 PetscErrorCode PetscViewerFlowControlStart(PetscViewer viewer,PetscInt *mcnt,PetscInt *cnt)
552 {
553   PetscErrorCode ierr;
554   PetscFunctionBegin;
555   ierr = PetscViewerBinaryGetFlowControl(viewer,mcnt);CHKERRQ(ierr);
556   ierr = PetscViewerBinaryGetFlowControl(viewer,cnt);CHKERRQ(ierr);
557   PetscFunctionReturn(0);
558 }
559 
560 #undef __FUNCT__
561 #define __FUNCT__ "PetscViewerFlowControlStepMaster"
562 PetscErrorCode PetscViewerFlowControlStepMaster(PetscViewer viewer,PetscInt i,PetscInt *mcnt,PetscInt cnt)
563 {
564   PetscErrorCode ierr;
565   MPI_Comm       comm;
566 
567   PetscFunctionBegin;
568   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
569   if (i >= *mcnt) {
570     *mcnt += cnt;
571     ierr = MPI_Bcast(mcnt,1,MPIU_INT,0,comm);CHKERRQ(ierr);
572   }
573   PetscFunctionReturn(0);
574 }
575 
576 #undef __FUNCT__
577 #define __FUNCT__ "PetscViewerFlowControlEndMaster"
578 PetscErrorCode PetscViewerFlowControlEndMaster(PetscViewer viewer,PetscInt *mcnt)
579 {
580   PetscErrorCode ierr;
581   MPI_Comm       comm;
582   PetscFunctionBegin;
583   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
584   *mcnt = 0;
585   ierr = MPI_Bcast(mcnt,1,MPIU_INT,0,comm);CHKERRQ(ierr);
586   PetscFunctionReturn(0);
587 }
588 
589 #undef __FUNCT__
590 #define __FUNCT__ "PetscViewerFlowControlStepWorker"
591 PetscErrorCode PetscViewerFlowControlStepWorker(PetscViewer viewer,PetscMPIInt rank,PetscInt *mcnt)
592 {
593   PetscErrorCode ierr;
594   MPI_Comm       comm;
595   PetscFunctionBegin;
596   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
597   while (PETSC_TRUE) {
598     if (rank < *mcnt) break;
599     ierr = MPI_Bcast(mcnt,1,MPIU_INT,0,comm);CHKERRQ(ierr);
600   }
601   PetscFunctionReturn(0);
602 }
603 
604 #undef __FUNCT__
605 #define __FUNCT__ "PetscViewerFlowControlEndWorker"
606 PetscErrorCode PetscViewerFlowControlEndWorker(PetscViewer viewer,PetscInt *mcnt)
607 {
608   PetscErrorCode ierr;
609   MPI_Comm       comm;
610   PetscFunctionBegin;
611   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
612   while (PETSC_TRUE) {
613     ierr = MPI_Bcast(mcnt,1,MPIU_INT,0,comm);CHKERRQ(ierr);
614     if (!*mcnt) break;
615   }
616   PetscFunctionReturn(0);
617 }
618