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