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 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. 109 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()?"); 116 117 noviewers[inoviewers++] = noviewer; 118 noviewer = flg; 119 PetscFunctionReturn(PETSC_SUCCESS); 120 } 121 122 /*@ 123 PetscOptionsPopGetViewerOff - reset whether `PetscOptionsGetViewer()` returns a viewer. 124 125 Logically Collective 126 127 Level: developer 128 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. 132 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 } 142 143 /*@ 144 PetscOptionsGetViewerOff - does `PetscOptionsGetViewer()` return a viewer? 145 146 Logically Collective 147 148 Output Parameter: 149 . flg - whether viewers are returned. 150 151 Level: developer 152 153 Note: 154 Calling XXXViewFromOptions in an inner loop can be very expensive. This can appear, for example, when using 155 many small subsolves. 156 157 .seealso: [](sec_viewers), `PetscOptionsGetViewer()`, `PetscOptionsPushGetViewerOff()`, `PetscOptionsPopGetViewerOff()` 158 @*/ 159 PetscErrorCode PetscOptionsGetViewerOff(PetscBool *flg) 160 { 161 PetscFunctionBegin; 162 PetscValidBoolPointer(flg, 1); 163 *flg = noviewer; 164 PetscFunctionReturn(PETSC_SUCCESS); 165 } 166 167 /*@C 168 PetscOptionsGetViewer - Gets a viewer appropriate for the type indicated by the user 169 170 Collective 171 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 177 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` 182 183 Level: intermediate 184 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) 194 195 Use `PetscViewerDestroy()` after using the viewer, otherwise a memory leak will occur 196 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. 200 201 If PETSc is configured with `--with-viewfromoptions=0` this function always returns with *set of `PETSC_FALSE` 202 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; 216 217 PetscFunctionBegin; 218 PetscValidCharPointer(name, 4); 219 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); 225 226 PetscCall(PetscOptionsHasHelp(NULL, &hashelp)); 227 if (hashelp) { 228 PetscBool found; 229 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 } 241 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}; 255 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; 345 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 } 357 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 360 361 Collective 362 363 Input Parameter: 364 . comm - MPI communicator 365 366 Output Parameter: 367 . inviewer - location to put the `PetscViewer` context 368 369 Level: advanced 370 371 .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerType` 372 @*/ 373 PetscErrorCode PetscViewerCreate(MPI_Comm comm, PetscViewer *inviewer) 374 { 375 PetscViewer viewer; 376 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 } 385 386 /*@C 387 PetscViewerSetType - Builds `PetscViewer` for a particular implementation. 388 389 Collective 390 391 Input Parameters: 392 + viewer - the `PetscViewer` context obtained with `PetscViewerCreate()` 393 - type - for example, `PETSCVIEWERASCII` 394 395 Options Database Key: 396 . -viewer_type <type> - Sets the type; use -help for a list of available methods (for instance, ascii) 397 398 Level: advanced 399 400 Note: 401 See `PetscViewerType` for possible values 402 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); 409 410 PetscFunctionBegin; 411 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 412 PetscValidCharPointer(type, 2); 413 PetscCall(PetscObjectTypeCompare((PetscObject)viewer, type, &match)); 414 if (match) PetscFunctionReturn(PETSC_SUCCESS); 415 416 /* cleanup any old type that may be there */ 417 PetscTryTypeMethod(viewer, destroy); 418 viewer->ops->destroy = NULL; 419 viewer->data = NULL; 420 421 PetscCall(PetscMemzero(viewer->ops, sizeof(struct _PetscViewerOps))); 422 423 PetscCall(PetscFunctionListFind(PetscViewerList, type, &r)); 424 PetscCheck(r, PETSC_COMM_SELF, PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscViewer type given: %s", type); 425 426 PetscCall(PetscObjectChangeTypeName((PetscObject)viewer, type)); 427 PetscCall((*r)(viewer)); 428 PetscFunctionReturn(PETSC_SUCCESS); 429 } 430 431 /*@C 432 PetscViewerRegister - Adds a viewer to those available for use 433 434 Not Collective 435 436 Input Parameters: 437 + name_solver - name of a new user-defined viewer 438 - routine_create - routine to create method context 439 440 Level: developer 441 442 Note: 443 `PetscViewerRegister()` may be called multiple times to add several user-defined viewers. 444 445 Sample usage: 446 .vb 447 PetscViewerRegister("my_viewer_type",MyViewerCreate); 448 .ve 449 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 454 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 } 464 465 /*@C 466 PetscViewerSetFromOptions - Sets various options for a viewer based on values in the options database. 467 468 Collective 469 470 Input Parameter: 471 . viewer - the viewer context 472 473 Level: intermediate 474 475 Note: 476 Must be called after `PetscViewerCreate()` before the `PetscViewer` is used. 477 478 .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerCreate()`, `PetscViewerSetType()`, `PetscViewerType` 479 @*/ 480 PetscErrorCode PetscViewerSetFromOptions(PetscViewer viewer) 481 { 482 char vtype[256]; 483 PetscBool flg; 484 485 PetscFunctionBegin; 486 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 487 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); 495 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 } 502 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 } 510 511 PetscErrorCode PetscViewerFlowControlStepMain(PetscViewer viewer, PetscInt i, PetscInt *mcnt, PetscInt cnt) 512 { 513 MPI_Comm comm; 514 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 } 523 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 } 533 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 } 545 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 } 557