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