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