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