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