Actual source code: viewreg.c


  2: #include <petsc/private/viewerimpl.h>
  3: #include <petsc/private/hashtable.h>
  4: #if defined(PETSC_HAVE_SAWS)
  5: #include <petscviewersaws.h>
  6: #endif

  8: PetscFunctionList PetscViewerList = NULL;

 10: PetscOptionsHelpPrinted PetscOptionsHelpPrintedSingleton = NULL;
 11: KHASH_SET_INIT_STR(HTPrinted)
 12: struct _n_PetscOptionsHelpPrinted {
 13:   khash_t(HTPrinted) *printed;
 14:   PetscSegBuffer      strings;
 15: };

 17: PetscErrorCode PetscOptionsHelpPrintedDestroy(PetscOptionsHelpPrinted *hp)
 18: {
 19:   PetscFunctionBegin;
 20:   if (!*hp) PetscFunctionReturn(PETSC_SUCCESS);
 21:   kh_destroy(HTPrinted, (*hp)->printed);
 22:   PetscCall(PetscSegBufferDestroy(&(*hp)->strings));
 23:   PetscCall(PetscFree(*hp));
 24:   PetscFunctionReturn(PETSC_SUCCESS);
 25: }

 27: /*@C
 28:       PetscOptionsHelpPrintedCreate - Creates an object used to manage tracking which help messages have
 29:          been printed so they will not be printed again.

 31:      Not Collective

 33:     Level: developer

 35: .seealso: `PetscOptionsHelpPrintedCheck()`, `PetscOptionsHelpPrintChecked()`
 36: @*/
 37: PetscErrorCode PetscOptionsHelpPrintedCreate(PetscOptionsHelpPrinted *hp)
 38: {
 39:   PetscFunctionBegin;
 40:   PetscCall(PetscNew(hp));
 41:   (*hp)->printed = kh_init(HTPrinted);
 42:   PetscCall(PetscSegBufferCreate(sizeof(char), 10000, &(*hp)->strings));
 43:   PetscFunctionReturn(PETSC_SUCCESS);
 44: }

 46: /*@C
 47:       PetscOptionsHelpPrintedCheck - Checks if a particular pre, name pair has previous been entered (meaning the help message was printed)

 49:      Not Collective

 51:     Input Parameters:
 52: +     hp - the object used to manage tracking what help messages have been printed
 53: .     pre - the prefix part of the string, many be `NULL`
 54: -     name - the string to look for (cannot be `NULL`)

 56:     Output Parameter:
 57: .     found - `PETSC_TRUE` if the string was already set

 59:     Level: intermediate

 61: .seealso: `PetscOptionsHelpPrintedCreate()`
 62: @*/
 63: PetscErrorCode PetscOptionsHelpPrintedCheck(PetscOptionsHelpPrinted hp, const char *pre, const char *name, PetscBool *found)
 64: {
 65:   size_t l1, l2;
 66: #if !defined(PETSC_HAVE_THREADSAFETY)
 67:   char *both;
 68:   int   newitem;
 69: #endif

 71:   PetscFunctionBegin;
 72:   PetscCall(PetscStrlen(pre, &l1));
 73:   PetscCall(PetscStrlen(name, &l2));
 74:   if (l1 + l2 == 0) {
 75:     *found = PETSC_FALSE;
 76:     PetscFunctionReturn(PETSC_SUCCESS);
 77:   }
 78: #if !defined(PETSC_HAVE_THREADSAFETY)
 79:   size_t lboth = l1 + l2 + 1;
 80:   PetscCall(PetscSegBufferGet(hp->strings, lboth, &both));
 81:   PetscCall(PetscStrncpy(both, pre, lboth));
 82:   PetscCall(PetscStrncpy(both + l1, name, l2 + 1));
 83:   kh_put(HTPrinted, hp->printed, both, &newitem);
 84:   if (!newitem) PetscCall(PetscSegBufferUnuse(hp->strings, lboth));
 85:   *found = newitem ? PETSC_FALSE : PETSC_TRUE;
 86: #else
 87:   *found = PETSC_FALSE;
 88: #endif
 89:   PetscFunctionReturn(PETSC_SUCCESS);
 90: }

 92: static PetscBool noviewer = PETSC_FALSE;
 93: static PetscBool noviewers[PETSCVIEWERGETVIEWEROFFPUSHESMAX];
 94: static PetscInt  inoviewers = 0;

 96: /*@
 97:   PetscOptionsPushGetViewerOff - sets if a `PetscOptionsGetViewer()` returns a viewer.

 99:   Logically Collective

101:   Input Parameter:
102: . flg - `PETSC_TRUE` to turn off viewer creation, `PETSC_FALSE` to turn it on.

104:   Level: developer

106:   Note:
107:     Calling XXXViewFromOptions in an inner loop can be very expensive.  This can appear, for example, when using
108:    many small subsolves.  Call this function to control viewer creation in `PetscOptionsGetViewer()`, thus removing the expensive XXXViewFromOptions calls.

110: .seealso: [](sec_viewers), `PetscOptionsGetViewer()`, `PetscOptionsPopGetViewerOff()`
111: @*/
112: PetscErrorCode PetscOptionsPushGetViewerOff(PetscBool flg)
113: {
114:   PetscFunctionBegin;
115:   PetscCheck(inoviewers < PETSCVIEWERGETVIEWEROFFPUSHESMAX, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many PetscOptionsPushGetViewerOff(), perhaps you forgot PetscOptionsPopGetViewerOff()?");

117:   noviewers[inoviewers++] = noviewer;
118:   noviewer                = flg;
119:   PetscFunctionReturn(PETSC_SUCCESS);
120: }

122: /*@
123:   PetscOptionsPopGetViewerOff - reset whether `PetscOptionsGetViewer()` returns a viewer.

125:   Logically Collective

127:   Level: developer

129:   Note:
130:     Calling XXXViewFromOptions in an inner loop can be very expensive.  This can appear, for example, when using
131:    many small subsolves.  Call this function to control viewer creation in `PetscOptionsGetViewer()`, thus removing the expensive XXXViewFromOptions calls.

133: .seealso: [](sec_viewers), `PetscOptionsGetViewer()`, `PetscOptionsPushGetViewerOff()`
134: @*/
135: PetscErrorCode PetscOptionsPopGetViewerOff(void)
136: {
137:   PetscFunctionBegin;
138:   PetscCheck(inoviewers, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many PetscOptionsPopGetViewerOff(), perhaps you forgot PetscOptionsPushGetViewerOff()?");
139:   noviewer = noviewers[--inoviewers];
140:   PetscFunctionReturn(PETSC_SUCCESS);
141: }

143: /*@
144:   PetscOptionsGetViewerOff - does `PetscOptionsGetViewer()` return a viewer?

146:   Logically Collective

148:   Output Parameter:
149: . flg - whether viewers are returned.

151:   Level: developer

153:   Note:
154:     Calling XXXViewFromOptions in an inner loop can be very expensive.  This can appear, for example, when using
155:    many small subsolves.

157: .seealso: [](sec_viewers), `PetscOptionsGetViewer()`, `PetscOptionsPushGetViewerOff()`, `PetscOptionsPopGetViewerOff()`
158: @*/
159: PetscErrorCode PetscOptionsGetViewerOff(PetscBool *flg)
160: {
161:   PetscFunctionBegin;
163:   *flg = noviewer;
164:   PetscFunctionReturn(PETSC_SUCCESS);
165: }

167: /*@C
168:    PetscOptionsGetViewer - Gets a viewer appropriate for the type indicated by the user

170:    Collective

172:    Input Parameters:
173: +  comm - the communicator to own the viewer
174: .  options - options database, use `NULL` for default global database
175: .  pre - the string to prepend to the name or `NULL`
176: -  name - the option one is seeking

178:    Output Parameters:
179: +  viewer - the viewer, pass `NULL` if not needed
180: .  format - the `PetscViewerFormat` requested by the user, pass `NULL` if not needed
181: -  set - `PETSC_TRUE` if found, else `PETSC_FALSE`

183:    Level: intermediate

185:    Notes:
186:     If no value is provided ascii:stdout is used
187: +       ascii[:[filename][:[format][:append]]]  -  defaults to stdout - format can be one of ascii_info, ascii_info_detail, or ascii_matlab,
188:                                                   for example ascii::ascii_info prints just the information about the object not all details
189:                                                   unless :append is given filename opens in write mode, overwriting what was already there
190: .       binary[:[filename][:[format][:append]]] -  defaults to the file binaryoutput
191: .       draw[:drawtype[:filename]]              -  for example, draw:tikz, draw:tikz:figure.tex  or draw:x
192: .       socket[:port]                           -  defaults to the standard output port
193: -       saws[:communicatorname]                 -   publishes object to the Scientific Application Webserver (SAWs)

195:    Use `PetscViewerDestroy()` after using the viewer, otherwise a memory leak will occur

197:    You can control whether calls to this function create a viewer (or return early with *set of `PETSC_FALSE`) with
198:    `PetscOptionsPushGetViewerOff()`.  This is useful if calling many small subsolves, in which case XXXViewFromOptions can take
199:    an appreciable fraction of the runtime.

201:    If PETSc is configured with `--with-viewfromoptions=0` this function always returns with *set of `PETSC_FALSE`

203: .seealso: [](sec_viewers), `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
204:           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
205:           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsBool()`,
206:           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
207:           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
208:           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
209:           `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsPushGetViewerOff()`, `PetscOptionsPopGetViewerOff()`,
210:           `PetscOptionsGetViewerOff()`
211: @*/
212: PetscErrorCode PetscOptionsGetViewer(MPI_Comm comm, PetscOptions options, const char pre[], const char name[], PetscViewer *viewer, PetscViewerFormat *format, PetscBool *set)
213: {
214:   const char *value;
215:   PetscBool   flag, hashelp;

217:   PetscFunctionBegin;

220:   if (viewer) *viewer = NULL;
221:   if (format) *format = PETSC_VIEWER_DEFAULT;
222:   if (set) *set = PETSC_FALSE;
223:   PetscCall(PetscOptionsGetViewerOff(&flag));
224:   if (flag) PetscFunctionReturn(PETSC_SUCCESS);

226:   PetscCall(PetscOptionsHasHelp(NULL, &hashelp));
227:   if (hashelp) {
228:     PetscBool found;

230:     if (!PetscOptionsHelpPrintedSingleton) PetscCall(PetscOptionsHelpPrintedCreate(&PetscOptionsHelpPrintedSingleton));
231:     PetscCall(PetscOptionsHelpPrintedCheck(PetscOptionsHelpPrintedSingleton, pre, name, &found));
232:     if (!found && viewer) {
233:       PetscCall((*PetscHelpPrintf)(comm, "----------------------------------------\nViewer (-%s%s) options:\n", pre ? pre : "", name + 1));
234:       PetscCall((*PetscHelpPrintf)(comm, "  -%s%s ascii[:[filename][:[format][:append]]]: %s (%s)\n", pre ? pre : "", name + 1, "Prints object to stdout or ASCII file", "PetscOptionsGetViewer"));
235:       PetscCall((*PetscHelpPrintf)(comm, "  -%s%s binary[:[filename][:[format][:append]]]: %s (%s)\n", pre ? pre : "", name + 1, "Saves object to a binary file", "PetscOptionsGetViewer"));
236:       PetscCall((*PetscHelpPrintf)(comm, "  -%s%s draw[:[drawtype][:filename|format]] %s (%s)\n", pre ? pre : "", name + 1, "Draws object", "PetscOptionsGetViewer"));
237:       PetscCall((*PetscHelpPrintf)(comm, "  -%s%s socket[:port]: %s (%s)\n", pre ? pre : "", name + 1, "Pushes object to a Unix socket", "PetscOptionsGetViewer"));
238:       PetscCall((*PetscHelpPrintf)(comm, "  -%s%s saws[:communicatorname]: %s (%s)\n", pre ? pre : "", name + 1, "Publishes object to SAWs", "PetscOptionsGetViewer"));
239:     }
240:   }

242:   if (format) *format = PETSC_VIEWER_DEFAULT;
243:   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
244:   if (flag) {
245:     if (set) *set = PETSC_TRUE;
246:     if (!value) {
247:       if (viewer) {
248:         PetscCall(PetscViewerASCIIGetStdout(comm, viewer));
249:         PetscCall(PetscObjectReference((PetscObject)*viewer));
250:       }
251:     } else {
252:       char       *loc0_vtype = NULL, *loc1_fname = NULL, *loc2_fmt = NULL, *loc3_fmode = NULL;
253:       PetscInt    cnt;
254:       const char *viewers[] = {PETSCVIEWERASCII, PETSCVIEWERBINARY, PETSCVIEWERDRAW, PETSCVIEWERSOCKET, PETSCVIEWERMATLAB, PETSCVIEWERSAWS, PETSCVIEWERVTK, PETSCVIEWERHDF5, PETSCVIEWERGLVIS, PETSCVIEWEREXODUSII, NULL};

256:       PetscCall(PetscStrallocpy(value, &loc0_vtype));
257:       PetscCall(PetscStrchr(loc0_vtype, ':', &loc1_fname));
258:       if (loc1_fname) {
259:         *loc1_fname++ = 0;
260:         PetscCall(PetscStrchr(loc1_fname, ':', &loc2_fmt));
261:       }
262:       if (loc2_fmt) {
263:         *loc2_fmt++ = 0;
264:         PetscCall(PetscStrchr(loc2_fmt, ':', &loc3_fmode));
265:       }
266:       if (loc3_fmode) *loc3_fmode++ = 0;
267:       PetscCall(PetscStrendswithwhich(*loc0_vtype ? loc0_vtype : "ascii", viewers, &cnt));
268:       PetscCheck(cnt <= (PetscInt)sizeof(viewers) - 1, comm, PETSC_ERR_ARG_OUTOFRANGE, "Unknown viewer type: %s", loc0_vtype);
269:       if (viewer) {
270:         if (!loc1_fname) {
271:           switch (cnt) {
272:           case 0:
273:             PetscCall(PetscViewerASCIIGetStdout(comm, viewer));
274:             break;
275:           case 1:
276:             if (!(*viewer = PETSC_VIEWER_BINARY_(comm))) PetscCall(PETSC_ERR_PLIB);
277:             break;
278:           case 2:
279:             if (!(*viewer = PETSC_VIEWER_DRAW_(comm))) PetscCall(PETSC_ERR_PLIB);
280:             break;
281: #if defined(PETSC_USE_SOCKET_VIEWER)
282:           case 3:
283:             if (!(*viewer = PETSC_VIEWER_SOCKET_(comm))) PetscCall(PETSC_ERR_PLIB);
284:             break;
285: #endif
286: #if defined(PETSC_HAVE_MATLAB)
287:           case 4:
288:             if (!(*viewer = PETSC_VIEWER_MATLAB_(comm))) PetscCall(PETSC_ERR_PLIB);
289:             break;
290: #endif
291: #if defined(PETSC_HAVE_SAWS)
292:           case 5:
293:             if (!(*viewer = PETSC_VIEWER_SAWS_(comm))) PetscCall(PETSC_ERR_PLIB);
294:             break;
295: #endif
296: #if defined(PETSC_HAVE_HDF5)
297:           case 7:
298:             if (!(*viewer = PETSC_VIEWER_HDF5_(comm))) PetscCall(PETSC_ERR_PLIB);
299:             break;
300: #endif
301:           case 8:
302:             if (!(*viewer = PETSC_VIEWER_GLVIS_(comm))) PetscCall(PETSC_ERR_PLIB);
303:             break;
304: #if defined(PETSC_HAVE_EXODUSII)
305:           case 9:
306:             if (!(*viewer = PETSC_VIEWER_EXODUSII_(comm))) PetscCall(PETSC_ERR_PLIB);
307:             break;
308: #endif
309:           default:
310:             SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Unsupported viewer %s", loc0_vtype);
311:           }
312:           PetscCall(PetscObjectReference((PetscObject)*viewer));
313:         } else {
314:           if (loc2_fmt && !*loc1_fname && (cnt == 0)) { /* ASCII format without file name */
315:             PetscCall(PetscViewerASCIIGetStdout(comm, viewer));
316:             PetscCall(PetscObjectReference((PetscObject)*viewer));
317:           } else {
318:             PetscFileMode fmode;
319:             PetscCall(PetscViewerCreate(comm, viewer));
320:             PetscCall(PetscViewerSetType(*viewer, *loc0_vtype ? loc0_vtype : "ascii"));
321:             fmode = FILE_MODE_WRITE;
322:             if (loc3_fmode && *loc3_fmode) { /* Has non-empty file mode ("write" or "append") */
323:               PetscCall(PetscEnumFind(PetscFileModes, loc3_fmode, (PetscEnum *)&fmode, &flag));
324:               PetscCheck(flag, comm, PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown file mode: %s", loc3_fmode);
325:             }
326:             if (loc2_fmt) {
327:               PetscBool tk, im;
328:               PetscCall(PetscStrcmp(loc1_fname, "tikz", &tk));
329:               PetscCall(PetscStrcmp(loc1_fname, "image", &im));
330:               if (tk || im) {
331:                 PetscCall(PetscViewerDrawSetInfo(*viewer, NULL, loc2_fmt, PETSC_DECIDE, PETSC_DECIDE, PETSC_DECIDE, PETSC_DECIDE));
332:                 *loc2_fmt = 0;
333:               }
334:             }
335:             PetscCall(PetscViewerFileSetMode(*viewer, flag ? fmode : FILE_MODE_WRITE));
336:             PetscCall(PetscViewerFileSetName(*viewer, loc1_fname));
337:             if (*loc1_fname) PetscCall(PetscViewerDrawSetDrawType(*viewer, loc1_fname));
338:             PetscCall(PetscViewerSetFromOptions(*viewer));
339:           }
340:         }
341:       }
342:       if (viewer) PetscCall(PetscViewerSetUp(*viewer));
343:       if (loc2_fmt && *loc2_fmt) {
344:         PetscViewerFormat tfmt;

346:         PetscCall(PetscEnumFind(PetscViewerFormats, loc2_fmt, (PetscEnum *)&tfmt, &flag));
347:         if (format) *format = tfmt;
348:         PetscCheck(flag, PETSC_COMM_SELF, PETSC_ERR_SUP, "Unknown viewer format %s", loc2_fmt);
349:       } else if (viewer && (cnt == 6) && format) { /* Get format from VTK viewer */
350:         PetscCall(PetscViewerGetFormat(*viewer, format));
351:       }
352:       PetscCall(PetscFree(loc0_vtype));
353:     }
354:   }
355:   PetscFunctionReturn(PETSC_SUCCESS);
356: }

358: /*@
359:    PetscViewerCreate - Creates a viewing context. A `PetscViewer` represents a file, a graphical window, a Unix socket or a variety of other ways of viewing a PETSc object

361:    Collective

363:    Input Parameter:
364: .  comm - MPI communicator

366:    Output Parameter:
367: .  inviewer - location to put the `PetscViewer` context

369:    Level: advanced

371: .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerType`
372: @*/
373: PetscErrorCode PetscViewerCreate(MPI_Comm comm, PetscViewer *inviewer)
374: {
375:   PetscViewer viewer;

377:   PetscFunctionBegin;
378:   *inviewer = NULL;
379:   PetscCall(PetscViewerInitializePackage());
380:   PetscCall(PetscHeaderCreate(viewer, PETSC_VIEWER_CLASSID, "PetscViewer", "PetscViewer", "Viewer", comm, PetscViewerDestroy, PetscViewerView));
381:   *inviewer    = viewer;
382:   viewer->data = NULL;
383:   PetscFunctionReturn(PETSC_SUCCESS);
384: }

386: /*@C
387:    PetscViewerSetType - Builds `PetscViewer` for a particular implementation.

389:    Collective

391:    Input Parameters:
392: +  viewer      - the `PetscViewer` context obtained with `PetscViewerCreate()`
393: -  type        - for example, `PETSCVIEWERASCII`

395:    Options Database Key:
396: .  -viewer_type  <type> - Sets the type; use -help for a list of available methods (for instance, ascii)

398:    Level: advanced

400:    Note:
401:    See `PetscViewerType` for possible values

403: .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerCreate()`, `PetscViewerGetType()`, `PetscViewerType`, `PetscViewerPushFormat()`
404: @*/
405: PetscErrorCode PetscViewerSetType(PetscViewer viewer, PetscViewerType type)
406: {
407:   PetscBool match;
408:   PetscErrorCode (*r)(PetscViewer);

410:   PetscFunctionBegin;
413:   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, type, &match));
414:   if (match) PetscFunctionReturn(PETSC_SUCCESS);

416:   /* cleanup any old type that may be there */
417:   PetscTryTypeMethod(viewer, destroy);
418:   viewer->ops->destroy = NULL;
419:   viewer->data         = NULL;

421:   PetscCall(PetscMemzero(viewer->ops, sizeof(struct _PetscViewerOps)));

423:   PetscCall(PetscFunctionListFind(PetscViewerList, type, &r));
424:   PetscCheck(r, PETSC_COMM_SELF, PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscViewer type given: %s", type);

426:   PetscCall(PetscObjectChangeTypeName((PetscObject)viewer, type));
427:   PetscCall((*r)(viewer));
428:   PetscFunctionReturn(PETSC_SUCCESS);
429: }

431: /*@C
432:    PetscViewerRegister - Adds a viewer to those available for use

434:    Not Collective

436:    Input Parameters:
437: +  sname - name of a new user-defined viewer
438: -  function - routine to create method context

440:    Level: developer

442:    Note:
443:    `PetscViewerRegister()` may be called multiple times to add several user-defined viewers.

445:    Sample usage:
446: .vb
447:    PetscViewerRegister("my_viewer_type",MyViewerCreate);
448: .ve

450:    Then, your solver can be chosen with the procedural interface via
451: $     PetscViewerSetType(viewer,"my_viewer_type")
452:    or at runtime via the option
453: $     -viewer_type my_viewer_type

455: .seealso: [](sec_viewers), `PetscViewerRegisterAll()`
456:  @*/
457: PetscErrorCode PetscViewerRegister(const char *sname, PetscErrorCode (*function)(PetscViewer))
458: {
459:   PetscFunctionBegin;
460:   PetscCall(PetscViewerInitializePackage());
461:   PetscCall(PetscFunctionListAdd(&PetscViewerList, sname, function));
462:   PetscFunctionReturn(PETSC_SUCCESS);
463: }

465: /*@C
466:    PetscViewerSetFromOptions - Sets various options for a viewer based on values in the options database.

468:    Collective

470:    Input Parameter:
471: .     viewer - the viewer context

473:    Level: intermediate

475:    Note:
476:     Must be called after `PetscViewerCreate()` before the `PetscViewer` is used.

478: .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerCreate()`, `PetscViewerSetType()`, `PetscViewerType`
479: @*/
480: PetscErrorCode PetscViewerSetFromOptions(PetscViewer viewer)
481: {
482:   char      vtype[256];
483:   PetscBool flg;

485:   PetscFunctionBegin;

488:   if (!PetscViewerList) PetscCall(PetscViewerRegisterAll());
489:   PetscObjectOptionsBegin((PetscObject)viewer);
490:   PetscCall(PetscOptionsFList("-viewer_type", "Type of PetscViewer", "None", PetscViewerList, (char *)(((PetscObject)viewer)->type_name ? ((PetscObject)viewer)->type_name : PETSCVIEWERASCII), vtype, 256, &flg));
491:   if (flg) PetscCall(PetscViewerSetType(viewer, vtype));
492:   /* type has not been set? */
493:   if (!((PetscObject)viewer)->type_name) PetscCall(PetscViewerSetType(viewer, PETSCVIEWERASCII));
494:   PetscTryTypeMethod(viewer, setfromoptions, PetscOptionsObject);

496:   /* process any options handlers added with PetscObjectAddOptionsHandler() */
497:   PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)viewer, PetscOptionsObject));
498:   PetscCall(PetscViewerViewFromOptions(viewer, NULL, "-viewer_view"));
499:   PetscOptionsEnd();
500:   PetscFunctionReturn(PETSC_SUCCESS);
501: }

503: PetscErrorCode PetscViewerFlowControlStart(PetscViewer viewer, PetscInt *mcnt, PetscInt *cnt)
504: {
505:   PetscFunctionBegin;
506:   PetscCall(PetscViewerBinaryGetFlowControl(viewer, mcnt));
507:   PetscCall(PetscViewerBinaryGetFlowControl(viewer, cnt));
508:   PetscFunctionReturn(PETSC_SUCCESS);
509: }

511: PetscErrorCode PetscViewerFlowControlStepMain(PetscViewer viewer, PetscInt i, PetscInt *mcnt, PetscInt cnt)
512: {
513:   MPI_Comm comm;

515:   PetscFunctionBegin;
516:   PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
517:   if (i >= *mcnt) {
518:     *mcnt += cnt;
519:     PetscCallMPI(MPI_Bcast(mcnt, 1, MPIU_INT, 0, comm));
520:   }
521:   PetscFunctionReturn(PETSC_SUCCESS);
522: }

524: PetscErrorCode PetscViewerFlowControlEndMain(PetscViewer viewer, PetscInt *mcnt)
525: {
526:   MPI_Comm comm;
527:   PetscFunctionBegin;
528:   PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
529:   *mcnt = 0;
530:   PetscCallMPI(MPI_Bcast(mcnt, 1, MPIU_INT, 0, comm));
531:   PetscFunctionReturn(PETSC_SUCCESS);
532: }

534: PetscErrorCode PetscViewerFlowControlStepWorker(PetscViewer viewer, PetscMPIInt rank, PetscInt *mcnt)
535: {
536:   MPI_Comm comm;
537:   PetscFunctionBegin;
538:   PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
539:   while (PETSC_TRUE) {
540:     if (rank < *mcnt) break;
541:     PetscCallMPI(MPI_Bcast(mcnt, 1, MPIU_INT, 0, comm));
542:   }
543:   PetscFunctionReturn(PETSC_SUCCESS);
544: }

546: PetscErrorCode PetscViewerFlowControlEndWorker(PetscViewer viewer, PetscInt *mcnt)
547: {
548:   MPI_Comm comm;
549:   PetscFunctionBegin;
550:   PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
551:   while (PETSC_TRUE) {
552:     PetscCallMPI(MPI_Bcast(mcnt, 1, MPIU_INT, 0, comm));
553:     if (!*mcnt) break;
554:   }
555:   PetscFunctionReturn(PETSC_SUCCESS);
556: }