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