xref: /petsc/src/sys/classes/viewer/interface/viewreg.c (revision eb55bdffca50d68374504080e1f317d0c4a47ce0)
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 = PetscOptionsHasName(NULL,NULL,"-help",&hashelp);CHKERRQ(ierr);
247   if (hashelp) {
248     PetscBool found;
249 
250     if (!PetscOptionsHelpPrintedSingleton) {
251       ierr = PetscOptionsHelpPrintedCreate(&PetscOptionsHelpPrintedSingleton);CHKERRQ(ierr);
252     }
253     ierr = PetscOptionsHelpPrintedCheck(PetscOptionsHelpPrintedSingleton,pre,name,&found);CHKERRQ(ierr);
254     if (!found) {
255       if (viewer) {
256         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);
257         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);
258         ierr = (*PetscHelpPrintf)(comm,"    -%s%s draw[:drawtype[:filename]] %s (%s)\n",pre ? pre : "",name+1,"Draws object","PetscOptionsGetViewer");CHKERRQ(ierr);
259         ierr = (*PetscHelpPrintf)(comm,"    -%s%s socket[:port]: %s (%s)\n",pre ? pre : "",name+1,"Pushes object to a Unix socket","PetscOptionsGetViewer");CHKERRQ(ierr);
260         ierr = (*PetscHelpPrintf)(comm,"    -%s%s saws[:communicatorname]: %s (%s)\n\n",pre ? pre : "",name+1,"Publishes object to SAWs","PetscOptionsGetViewer");CHKERRQ(ierr);
261       } else {
262         ierr = (*PetscHelpPrintf)(comm,"    -%s%s\n",pre ? pre : "",name+1);CHKERRQ(ierr);
263       }
264     }
265   }
266 
267   if (format) *format = PETSC_VIEWER_DEFAULT;
268   ierr = PetscOptionsFindPair_Private(NULL,pre,name,&value,&flag);CHKERRQ(ierr);
269   if (flag) {
270     if (set) *set = PETSC_TRUE;
271     if (!value) {
272       if (viewer) {
273         ierr = PetscViewerASCIIGetStdout(comm,viewer);CHKERRQ(ierr);
274         ierr = PetscObjectReference((PetscObject)*viewer);CHKERRQ(ierr);
275       }
276     } else {
277       char       *loc0_vtype,*loc1_fname,*loc2_fmt = NULL,*loc3_fmode = NULL;
278       PetscInt   cnt;
279       const char *viewers[] = {PETSCVIEWERASCII,PETSCVIEWERBINARY,PETSCVIEWERDRAW,PETSCVIEWERSOCKET,PETSCVIEWERMATLAB,PETSCVIEWERSAWS,PETSCVIEWERVTK,PETSCVIEWERHDF5,0};
280 
281       ierr = PetscStrallocpy(value,&loc0_vtype);CHKERRQ(ierr);
282       ierr = PetscStrchr(loc0_vtype,':',&loc1_fname);CHKERRQ(ierr);
283       if (loc1_fname) {
284         *loc1_fname++ = 0;
285         ierr = PetscStrchr(loc1_fname,':',&loc2_fmt);CHKERRQ(ierr);
286       }
287       if (loc2_fmt) {
288         *loc2_fmt++ = 0;
289         ierr = PetscStrchr(loc2_fmt,':',&loc3_fmode);CHKERRQ(ierr);
290       }
291       if (loc3_fmode) *loc3_fmode++ = 0;
292       ierr = PetscStrendswithwhich(*loc0_vtype ? loc0_vtype : "ascii",viewers,&cnt);CHKERRQ(ierr);
293       if (cnt > (PetscInt) sizeof(viewers)-1) SETERRQ1(comm,PETSC_ERR_ARG_OUTOFRANGE,"Unknown viewer type: %s",loc0_vtype);
294       if (viewer) {
295         if (!loc1_fname) {
296           switch (cnt) {
297           case 0:
298             ierr = PetscViewerASCIIGetStdout(comm,viewer);CHKERRQ(ierr);
299             break;
300           case 1:
301             if (!(*viewer = PETSC_VIEWER_BINARY_(comm))) CHKERRQ(PETSC_ERR_PLIB);
302             break;
303           case 2:
304             if (!(*viewer = PETSC_VIEWER_DRAW_(comm))) CHKERRQ(PETSC_ERR_PLIB);
305             break;
306 #if defined(PETSC_USE_SOCKET_VIEWER)
307           case 3:
308             if (!(*viewer = PETSC_VIEWER_SOCKET_(comm))) CHKERRQ(PETSC_ERR_PLIB);
309             break;
310 #endif
311 #if defined(PETSC_HAVE_MATLAB_ENGINE)
312           case 4:
313             if (!(*viewer = PETSC_VIEWER_MATLAB_(comm))) CHKERRQ(PETSC_ERR_PLIB);
314             break;
315 #endif
316 #if defined(PETSC_HAVE_SAWS)
317           case 5:
318             if (!(*viewer = PETSC_VIEWER_SAWS_(comm))) CHKERRQ(PETSC_ERR_PLIB);
319             break;
320 #endif
321 #if defined(PETSC_HAVE_HDF5)
322           case 7:
323             if (!(*viewer = PETSC_VIEWER_HDF5_(comm))) CHKERRQ(PETSC_ERR_PLIB);
324             break;
325 #endif
326           default: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unsupported viewer %s",loc0_vtype);
327           }
328           ierr = PetscObjectReference((PetscObject)*viewer);CHKERRQ(ierr);
329         } else {
330           if (loc2_fmt && !*loc1_fname && (cnt == 0)) { /* ASCII format without file name */
331             ierr = PetscViewerASCIIGetStdout(comm,viewer);CHKERRQ(ierr);
332             ierr = PetscObjectReference((PetscObject)*viewer);CHKERRQ(ierr);
333           } else {
334             PetscFileMode fmode;
335             ierr = PetscViewerCreate(comm,viewer);CHKERRQ(ierr);
336             ierr = PetscViewerSetType(*viewer,*loc0_vtype ? loc0_vtype : "ascii");CHKERRQ(ierr);
337             fmode = FILE_MODE_WRITE;
338             if (loc3_fmode && *loc3_fmode) { /* Has non-empty file mode ("write" or "append") */
339               ierr = PetscEnumFind(PetscFileModes,loc3_fmode,(PetscEnum*)&fmode,&flag);CHKERRQ(ierr);
340               if (!flag) SETERRQ1(comm,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown file mode: %s",loc3_fmode);
341             }
342             if (loc2_fmt) {
343               PetscBool tk;
344               ierr = PetscStrcmp(loc1_fname,"tikz",&tk);CHKERRQ(ierr);
345               if (tk) {
346                 ierr = PetscViewerDrawSetInfo(*viewer,NULL,loc2_fmt,0,0,0,0);CHKERRQ(ierr);
347                 *loc2_fmt = 0;
348               }
349             }
350             ierr = PetscViewerFileSetMode(*viewer,flag?fmode:FILE_MODE_WRITE);CHKERRQ(ierr);
351             ierr = PetscViewerFileSetName(*viewer,loc1_fname);CHKERRQ(ierr);
352             ierr = PetscViewerDrawSetDrawType(*viewer,loc1_fname);CHKERRQ(ierr);
353           }
354         }
355       }
356       if (viewer) {
357         ierr = PetscViewerSetUp(*viewer);CHKERRQ(ierr);
358       }
359       if (loc2_fmt && *loc2_fmt) {
360         ierr = PetscEnumFind(PetscViewerFormats,loc2_fmt,(PetscEnum*)format,&flag);CHKERRQ(ierr);
361         if (!flag) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unknown viewer format %s",loc2_fmt);CHKERRQ(ierr);
362       }
363       ierr = PetscFree(loc0_vtype);CHKERRQ(ierr);
364     }
365   }
366   PetscFunctionReturn(0);
367 }
368 
369 #undef __FUNCT__
370 #define __FUNCT__ "PetscViewerCreate"
371 /*@
372    PetscViewerCreate - Creates a viewing context
373 
374    Collective on MPI_Comm
375 
376    Input Parameter:
377 .  comm - MPI communicator
378 
379    Output Parameter:
380 .  inviewer - location to put the PetscViewer context
381 
382    Level: advanced
383 
384    Concepts: graphics^creating PetscViewer
385    Concepts: file input/output^creating PetscViewer
386    Concepts: sockets^creating PetscViewer
387 
388 .seealso: PetscViewerDestroy(), PetscViewerSetType(), PetscViewerType
389 
390 @*/
391 PetscErrorCode  PetscViewerCreate(MPI_Comm comm,PetscViewer *inviewer)
392 {
393   PetscViewer    viewer;
394   PetscErrorCode ierr;
395 
396   PetscFunctionBegin;
397   *inviewer = 0;
398   ierr = PetscViewerInitializePackage();CHKERRQ(ierr);
399   ierr         = PetscHeaderCreate(viewer,PETSC_VIEWER_CLASSID,"PetscViewer","PetscViewer","Viewer",comm,PetscViewerDestroy,NULL);CHKERRQ(ierr);
400   *inviewer    = viewer;
401   viewer->data = 0;
402   PetscFunctionReturn(0);
403 }
404 
405 #undef __FUNCT__
406 #define __FUNCT__ "PetscViewerSetType"
407 /*@C
408    PetscViewerSetType - Builds PetscViewer for a particular implementation.
409 
410    Collective on PetscViewer
411 
412    Input Parameter:
413 +  viewer      - the PetscViewer context
414 -  type        - for example, PETSCVIEWERASCII
415 
416    Options Database Command:
417 .  -draw_type  <type> - Sets the type; use -help for a list
418     of available methods (for instance, ascii)
419 
420    Level: advanced
421 
422    Notes:
423    See "include/petscviewer.h" for available methods (for instance,
424    PETSCVIEWERSOCKET)
425 
426 .seealso: PetscViewerCreate(), PetscViewerGetType(), PetscViewerType, PetscViewerPushFormat()
427 @*/
428 PetscErrorCode  PetscViewerSetType(PetscViewer viewer,PetscViewerType type)
429 {
430   PetscErrorCode ierr,(*r)(PetscViewer);
431   PetscBool      match;
432 
433   PetscFunctionBegin;
434   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
435   PetscValidCharPointer(type,2);
436   ierr = PetscObjectTypeCompare((PetscObject)viewer,type,&match);CHKERRQ(ierr);
437   if (match) PetscFunctionReturn(0);
438 
439   /* cleanup any old type that may be there */
440   if (viewer->data) {
441     ierr         = (*viewer->ops->destroy)(viewer);CHKERRQ(ierr);
442 
443     viewer->ops->destroy = NULL;
444     viewer->data         = 0;
445   }
446   ierr = PetscMemzero(viewer->ops,sizeof(struct _PetscViewerOps));CHKERRQ(ierr);
447 
448   ierr =  PetscFunctionListFind(PetscViewerList,type,&r);CHKERRQ(ierr);
449   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown PetscViewer type given: %s",type);
450 
451   ierr = PetscObjectChangeTypeName((PetscObject)viewer,type);CHKERRQ(ierr);
452   ierr = (*r)(viewer);CHKERRQ(ierr);
453   PetscFunctionReturn(0);
454 }
455 
456 #undef __FUNCT__
457 #define __FUNCT__ "PetscViewerRegister"
458 /*@C
459    PetscViewerRegister - Adds a viewer
460 
461    Not Collective
462 
463    Input Parameters:
464 +  name_solver - name of a new user-defined viewer
465 -  routine_create - routine to create method context
466 
467    Level: developer
468    Notes:
469    PetscViewerRegister() may be called multiple times to add several user-defined viewers.
470 
471    Sample usage:
472 .vb
473    PetscViewerRegister("my_viewer_type",MyViewerCreate);
474 .ve
475 
476    Then, your solver can be chosen with the procedural interface via
477 $     PetscViewerSetType(viewer,"my_viewer_type")
478    or at runtime via the option
479 $     -viewer_type my_viewer_type
480 
481   Concepts: registering^Viewers
482 
483 .seealso: PetscViewerRegisterAll(), PetscViewerRegisterDestroy()
484  @*/
485 PetscErrorCode  PetscViewerRegister(const char *sname,PetscErrorCode (*function)(PetscViewer))
486 {
487   PetscErrorCode ierr;
488 
489   PetscFunctionBegin;
490   ierr = PetscFunctionListAdd(&PetscViewerList,sname,function);CHKERRQ(ierr);
491   PetscFunctionReturn(0);
492 }
493 
494 #undef __FUNCT__
495 #define __FUNCT__ "PetscViewerSetFromOptions"
496 /*@C
497    PetscViewerSetFromOptions - Sets the graphics type from the options database.
498       Defaults to a PETSc X windows graphics.
499 
500    Collective on PetscViewer
501 
502    Input Parameter:
503 .     PetscViewer - the graphics context
504 
505    Level: intermediate
506 
507    Notes:
508     Must be called after PetscViewerCreate() before the PetscViewer is used.
509 
510   Concepts: PetscViewer^setting options
511 
512 .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerType
513 
514 @*/
515 PetscErrorCode  PetscViewerSetFromOptions(PetscViewer viewer)
516 {
517   PetscErrorCode    ierr;
518   char              vtype[256];
519   PetscBool         flg;
520 
521   PetscFunctionBegin;
522   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
523 
524   if (!PetscViewerList) {
525     ierr = PetscViewerRegisterAll();CHKERRQ(ierr);
526   }
527   ierr = PetscObjectOptionsBegin((PetscObject)viewer);CHKERRQ(ierr);
528   ierr = PetscOptionsFList("-viewer_type","Type of PetscViewer","None",PetscViewerList,(char*)(((PetscObject)viewer)->type_name ? ((PetscObject)viewer)->type_name : PETSCVIEWERASCII),vtype,256,&flg);CHKERRQ(ierr);
529   if (flg) {
530     ierr = PetscViewerSetType(viewer,vtype);CHKERRQ(ierr);
531   }
532   /* type has not been set? */
533   if (!((PetscObject)viewer)->type_name) {
534     ierr = PetscViewerSetType(viewer,PETSCVIEWERASCII);CHKERRQ(ierr);
535   }
536   if (viewer->ops->setfromoptions) {
537     ierr = (*viewer->ops->setfromoptions)(PetscOptionsObject,viewer);CHKERRQ(ierr);
538   }
539 
540   /* process any options handlers added with PetscObjectAddOptionsHandler() */
541   ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)viewer);CHKERRQ(ierr);
542   ierr = PetscViewerViewFromOptions(viewer,NULL,"-viewer_view");CHKERRQ(ierr);
543   ierr = PetscOptionsEnd();CHKERRQ(ierr);
544   PetscFunctionReturn(0);
545 }
546 
547 #undef __FUNCT__
548 #define __FUNCT__ "PetscViewerFlowControlStart"
549 PetscErrorCode PetscViewerFlowControlStart(PetscViewer viewer,PetscInt *mcnt,PetscInt *cnt)
550 {
551   PetscErrorCode ierr;
552   PetscFunctionBegin;
553   ierr = PetscViewerBinaryGetFlowControl(viewer,mcnt);CHKERRQ(ierr);
554   ierr = PetscViewerBinaryGetFlowControl(viewer,cnt);CHKERRQ(ierr);
555   PetscFunctionReturn(0);
556 }
557 
558 #undef __FUNCT__
559 #define __FUNCT__ "PetscViewerFlowControlStepMaster"
560 PetscErrorCode PetscViewerFlowControlStepMaster(PetscViewer viewer,PetscInt i,PetscInt *mcnt,PetscInt cnt)
561 {
562   PetscErrorCode ierr;
563   MPI_Comm       comm;
564 
565   PetscFunctionBegin;
566   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
567   if (i >= *mcnt) {
568     *mcnt += cnt;
569     ierr = MPI_Bcast(mcnt,1,MPIU_INT,0,comm);CHKERRQ(ierr);
570   }
571   PetscFunctionReturn(0);
572 }
573 
574 #undef __FUNCT__
575 #define __FUNCT__ "PetscViewerFlowControlEndMaster"
576 PetscErrorCode PetscViewerFlowControlEndMaster(PetscViewer viewer,PetscInt *mcnt)
577 {
578   PetscErrorCode ierr;
579   MPI_Comm       comm;
580   PetscFunctionBegin;
581   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
582   *mcnt = 0;
583   ierr = MPI_Bcast(mcnt,1,MPIU_INT,0,comm);CHKERRQ(ierr);
584   PetscFunctionReturn(0);
585 }
586 
587 #undef __FUNCT__
588 #define __FUNCT__ "PetscViewerFlowControlStepWorker"
589 PetscErrorCode PetscViewerFlowControlStepWorker(PetscViewer viewer,PetscMPIInt rank,PetscInt *mcnt)
590 {
591   PetscErrorCode ierr;
592   MPI_Comm       comm;
593   PetscFunctionBegin;
594   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
595   while (PETSC_TRUE) {
596     if (rank < *mcnt) break;
597     ierr = MPI_Bcast(mcnt,1,MPIU_INT,0,comm);CHKERRQ(ierr);
598   }
599   PetscFunctionReturn(0);
600 }
601 
602 #undef __FUNCT__
603 #define __FUNCT__ "PetscViewerFlowControlEndWorker"
604 PetscErrorCode PetscViewerFlowControlEndWorker(PetscViewer viewer,PetscInt *mcnt)
605 {
606   PetscErrorCode ierr;
607   MPI_Comm       comm;
608   PetscFunctionBegin;
609   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
610   while (PETSC_TRUE) {
611     ierr = MPI_Bcast(mcnt,1,MPIU_INT,0,comm);CHKERRQ(ierr);
612     if (!*mcnt) break;
613   }
614   PetscFunctionReturn(0);
615 }
616