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