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 
PetscOptionsHelpPrintedDestroy(PetscOptionsHelpPrinted * hp)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 @*/
PetscOptionsHelpPrintedCreate(PetscOptionsHelpPrinted * hp)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 @*/
PetscOptionsHelpPrintedCheck(PetscOptionsHelpPrinted hp,const char * pre,const char * name,PetscBool * found)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 @*/
PetscOptionsPushGetViewerOff(PetscBool flg)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 @*/
PetscOptionsPopGetViewerOff(void)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 @*/
PetscOptionsGetViewerOff(PetscBool * flg)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 @*/
PetscOptionsGetViewer(MPI_Comm comm,PetscOptions options,const char pre[],const char name[],PetscViewer * viewer,PetscViewerFormat * format,PetscBool * set)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 && viewer) {
243       ierr = (*PetscHelpPrintf)(comm,"----------------------------------------\nViewer (-%s%s) options:\n",pre ? pre : "",name+1);CHKERRQ(ierr);
244       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);
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",pre ? pre : "",name+1,"Publishes object to SAWs","PetscOptionsGetViewer");CHKERRQ(ierr);
249     }
250   }
251 
252   if (format) *format = PETSC_VIEWER_DEFAULT;
253   ierr = PetscOptionsFindPair(options,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,PETSCVIEWEREXODUSII,NULL};
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 #if defined(PETSC_HAVE_EXODUSII)
315           case 9:
316             if (!(*viewer = PETSC_VIEWER_EXODUSII_(comm))) CHKERRQ(PETSC_ERR_PLIB);
317             break;
318 #endif
319           default: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unsupported viewer %s",loc0_vtype);
320           }
321           ierr = PetscObjectReference((PetscObject)*viewer);CHKERRQ(ierr);
322         } else {
323           if (loc2_fmt && !*loc1_fname && (cnt == 0)) { /* ASCII format without file name */
324             ierr = PetscViewerASCIIGetStdout(comm,viewer);CHKERRQ(ierr);
325             ierr = PetscObjectReference((PetscObject)*viewer);CHKERRQ(ierr);
326           } else {
327             PetscFileMode fmode;
328             ierr = PetscViewerCreate(comm,viewer);CHKERRQ(ierr);
329             ierr = PetscViewerSetType(*viewer,*loc0_vtype ? loc0_vtype : "ascii");CHKERRQ(ierr);
330             fmode = FILE_MODE_WRITE;
331             if (loc3_fmode && *loc3_fmode) { /* Has non-empty file mode ("write" or "append") */
332               ierr = PetscEnumFind(PetscFileModes,loc3_fmode,(PetscEnum*)&fmode,&flag);CHKERRQ(ierr);
333               if (!flag) SETERRQ1(comm,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown file mode: %s",loc3_fmode);
334             }
335             if (loc2_fmt) {
336               PetscBool tk,im;
337               ierr = PetscStrcmp(loc1_fname,"tikz",&tk);CHKERRQ(ierr);
338               ierr = PetscStrcmp(loc1_fname,"image",&im);CHKERRQ(ierr);
339               if (tk || im) {
340                 ierr = PetscViewerDrawSetInfo(*viewer,NULL,loc2_fmt,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr);
341                 *loc2_fmt = 0;
342               }
343             }
344             ierr = PetscViewerFileSetMode(*viewer,flag?fmode:FILE_MODE_WRITE);CHKERRQ(ierr);
345             ierr = PetscViewerFileSetName(*viewer,loc1_fname);CHKERRQ(ierr);
346             if (*loc1_fname) {
347               ierr = PetscViewerDrawSetDrawType(*viewer,loc1_fname);CHKERRQ(ierr);
348             }
349             ierr = PetscViewerSetFromOptions(*viewer);CHKERRQ(ierr);
350           }
351         }
352       }
353       if (viewer) {
354         ierr = PetscViewerSetUp(*viewer);CHKERRQ(ierr);
355       }
356       if (loc2_fmt && *loc2_fmt) {
357         PetscViewerFormat tfmt;
358 
359         ierr = PetscEnumFind(PetscViewerFormats,loc2_fmt,(PetscEnum*)&tfmt,&flag);CHKERRQ(ierr);
360         if (format) *format = tfmt;
361         if (!flag) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unknown viewer format %s",loc2_fmt);
362       } else if (viewer && (cnt == 6) && format) { /* Get format from VTK viewer */
363         ierr = PetscViewerGetFormat(*viewer,format);CHKERRQ(ierr);
364       }
365       ierr = PetscFree(loc0_vtype);CHKERRQ(ierr);
366     }
367   }
368   PetscFunctionReturn(0);
369 }
370 
371 /*@
372    PetscViewerCreate - Creates a viewing context
373 
374    Collective
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 .seealso: PetscViewerDestroy(), PetscViewerSetType(), PetscViewerType
385 
386 @*/
PetscViewerCreate(MPI_Comm comm,PetscViewer * inviewer)387 PetscErrorCode  PetscViewerCreate(MPI_Comm comm,PetscViewer *inviewer)
388 {
389   PetscViewer    viewer;
390   PetscErrorCode ierr;
391 
392   PetscFunctionBegin;
393   *inviewer = NULL;
394   ierr = PetscViewerInitializePackage();CHKERRQ(ierr);
395   ierr         = PetscHeaderCreate(viewer,PETSC_VIEWER_CLASSID,"PetscViewer","PetscViewer","Viewer",comm,PetscViewerDestroy,PetscViewerView);CHKERRQ(ierr);
396   *inviewer    = viewer;
397   viewer->data = NULL;
398   PetscFunctionReturn(0);
399 }
400 
401 /*@C
402    PetscViewerSetType - Builds PetscViewer for a particular implementation.
403 
404    Collective on PetscViewer
405 
406    Input Parameter:
407 +  viewer      - the PetscViewer context
408 -  type        - for example, PETSCVIEWERASCII
409 
410    Options Database Command:
411 .  -viewer_type  <type> - Sets the type; use -help for a list
412     of available methods (for instance, ascii)
413 
414    Level: advanced
415 
416    Notes:
417    See "include/petscviewer.h" for available methods (for instance,
418    PETSCVIEWERSOCKET)
419 
420 .seealso: PetscViewerCreate(), PetscViewerGetType(), PetscViewerType, PetscViewerPushFormat()
421 @*/
PetscViewerSetType(PetscViewer viewer,PetscViewerType type)422 PetscErrorCode  PetscViewerSetType(PetscViewer viewer,PetscViewerType type)
423 {
424   PetscErrorCode ierr,(*r)(PetscViewer);
425   PetscBool      match;
426 
427   PetscFunctionBegin;
428   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
429   PetscValidCharPointer(type,2);
430   ierr = PetscObjectTypeCompare((PetscObject)viewer,type,&match);CHKERRQ(ierr);
431   if (match) PetscFunctionReturn(0);
432 
433   /* cleanup any old type that may be there */
434   if (viewer->data) {
435     ierr         = (*viewer->ops->destroy)(viewer);CHKERRQ(ierr);
436 
437     viewer->ops->destroy = NULL;
438     viewer->data         = NULL;
439   }
440   ierr = PetscMemzero(viewer->ops,sizeof(struct _PetscViewerOps));CHKERRQ(ierr);
441 
442   ierr =  PetscFunctionListFind(PetscViewerList,type,&r);CHKERRQ(ierr);
443   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown PetscViewer type given: %s",type);
444 
445   ierr = PetscObjectChangeTypeName((PetscObject)viewer,type);CHKERRQ(ierr);
446   ierr = (*r)(viewer);CHKERRQ(ierr);
447   PetscFunctionReturn(0);
448 }
449 
450 /*@C
451    PetscViewerRegister - Adds a viewer
452 
453    Not Collective
454 
455    Input Parameters:
456 +  name_solver - name of a new user-defined viewer
457 -  routine_create - routine to create method context
458 
459    Level: developer
460    Notes:
461    PetscViewerRegister() may be called multiple times to add several user-defined viewers.
462 
463    Sample usage:
464 .vb
465    PetscViewerRegister("my_viewer_type",MyViewerCreate);
466 .ve
467 
468    Then, your solver can be chosen with the procedural interface via
469 $     PetscViewerSetType(viewer,"my_viewer_type")
470    or at runtime via the option
471 $     -viewer_type my_viewer_type
472 
473 .seealso: PetscViewerRegisterAll(), PetscViewerRegisterDestroy()
474  @*/
PetscViewerRegister(const char * sname,PetscErrorCode (* function)(PetscViewer))475 PetscErrorCode  PetscViewerRegister(const char *sname,PetscErrorCode (*function)(PetscViewer))
476 {
477   PetscErrorCode ierr;
478 
479   PetscFunctionBegin;
480   ierr = PetscViewerInitializePackage();CHKERRQ(ierr);
481   ierr = PetscFunctionListAdd(&PetscViewerList,sname,function);CHKERRQ(ierr);
482   PetscFunctionReturn(0);
483 }
484 
485 /*@C
486    PetscViewerSetFromOptions - Sets the graphics type from the options database.
487       Defaults to a PETSc X windows graphics.
488 
489    Collective on PetscViewer
490 
491    Input Parameter:
492 .     PetscViewer - the graphics context
493 
494    Level: intermediate
495 
496    Notes:
497     Must be called after PetscViewerCreate() before the PetscViewer is used.
498 
499 .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerType
500 
501 @*/
PetscViewerSetFromOptions(PetscViewer viewer)502 PetscErrorCode  PetscViewerSetFromOptions(PetscViewer viewer)
503 {
504   PetscErrorCode    ierr;
505   char              vtype[256];
506   PetscBool         flg;
507 
508   PetscFunctionBegin;
509   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
510 
511   if (!PetscViewerList) {
512     ierr = PetscViewerRegisterAll();CHKERRQ(ierr);
513   }
514   ierr = PetscObjectOptionsBegin((PetscObject)viewer);CHKERRQ(ierr);
515   ierr = PetscOptionsFList("-viewer_type","Type of PetscViewer","None",PetscViewerList,(char*)(((PetscObject)viewer)->type_name ? ((PetscObject)viewer)->type_name : PETSCVIEWERASCII),vtype,256,&flg);CHKERRQ(ierr);
516   if (flg) {
517     ierr = PetscViewerSetType(viewer,vtype);CHKERRQ(ierr);
518   }
519   /* type has not been set? */
520   if (!((PetscObject)viewer)->type_name) {
521     ierr = PetscViewerSetType(viewer,PETSCVIEWERASCII);CHKERRQ(ierr);
522   }
523   if (viewer->ops->setfromoptions) {
524     ierr = (*viewer->ops->setfromoptions)(PetscOptionsObject,viewer);CHKERRQ(ierr);
525   }
526 
527   /* process any options handlers added with PetscObjectAddOptionsHandler() */
528   ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)viewer);CHKERRQ(ierr);
529   ierr = PetscViewerViewFromOptions(viewer,NULL,"-viewer_view");CHKERRQ(ierr);
530   ierr = PetscOptionsEnd();CHKERRQ(ierr);
531   PetscFunctionReturn(0);
532 }
533 
PetscViewerFlowControlStart(PetscViewer viewer,PetscInt * mcnt,PetscInt * cnt)534 PetscErrorCode PetscViewerFlowControlStart(PetscViewer viewer,PetscInt *mcnt,PetscInt *cnt)
535 {
536   PetscErrorCode ierr;
537   PetscFunctionBegin;
538   ierr = PetscViewerBinaryGetFlowControl(viewer,mcnt);CHKERRQ(ierr);
539   ierr = PetscViewerBinaryGetFlowControl(viewer,cnt);CHKERRQ(ierr);
540   PetscFunctionReturn(0);
541 }
542 
PetscViewerFlowControlStepMaster(PetscViewer viewer,PetscInt i,PetscInt * mcnt,PetscInt cnt)543 PetscErrorCode PetscViewerFlowControlStepMaster(PetscViewer viewer,PetscInt i,PetscInt *mcnt,PetscInt cnt)
544 {
545   PetscErrorCode ierr;
546   MPI_Comm       comm;
547 
548   PetscFunctionBegin;
549   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
550   if (i >= *mcnt) {
551     *mcnt += cnt;
552     ierr = MPI_Bcast(mcnt,1,MPIU_INT,0,comm);CHKERRQ(ierr);
553   }
554   PetscFunctionReturn(0);
555 }
556 
PetscViewerFlowControlEndMaster(PetscViewer viewer,PetscInt * mcnt)557 PetscErrorCode PetscViewerFlowControlEndMaster(PetscViewer viewer,PetscInt *mcnt)
558 {
559   PetscErrorCode ierr;
560   MPI_Comm       comm;
561   PetscFunctionBegin;
562   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
563   *mcnt = 0;
564   ierr = MPI_Bcast(mcnt,1,MPIU_INT,0,comm);CHKERRQ(ierr);
565   PetscFunctionReturn(0);
566 }
567 
PetscViewerFlowControlStepWorker(PetscViewer viewer,PetscMPIInt rank,PetscInt * mcnt)568 PetscErrorCode PetscViewerFlowControlStepWorker(PetscViewer viewer,PetscMPIInt rank,PetscInt *mcnt)
569 {
570   PetscErrorCode ierr;
571   MPI_Comm       comm;
572   PetscFunctionBegin;
573   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
574   while (PETSC_TRUE) {
575     if (rank < *mcnt) break;
576     ierr = MPI_Bcast(mcnt,1,MPIU_INT,0,comm);CHKERRQ(ierr);
577   }
578   PetscFunctionReturn(0);
579 }
580 
PetscViewerFlowControlEndWorker(PetscViewer viewer,PetscInt * mcnt)581 PetscErrorCode PetscViewerFlowControlEndWorker(PetscViewer viewer,PetscInt *mcnt)
582 {
583   PetscErrorCode ierr;
584   MPI_Comm       comm;
585   PetscFunctionBegin;
586   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
587   while (PETSC_TRUE) {
588     ierr = MPI_Bcast(mcnt,1,MPIU_INT,0,comm);CHKERRQ(ierr);
589     if (!*mcnt) break;
590   }
591   PetscFunctionReturn(0);
592 }
593