1 #include <petsc/private/viewerimpl.h> /*I "petscviewer.h" I*/ 2 #include <petscdraw.h> 3 4 PetscClassId PETSC_VIEWER_CLASSID; 5 6 static PetscBool PetscViewerPackageInitialized = PETSC_FALSE; 7 8 /*@C 9 PetscViewerFinalizePackage - This function destroys any global objects created in PETSc viewers. It is 10 called from `PetscFinalize()`. 11 12 Level: developer 13 14 .seealso: [](sec_viewers), `PetscViewer`, `PetscFinalize()`, `PetscViewerInitializePackage()` 15 @*/ 16 PetscErrorCode PetscViewerFinalizePackage(void) 17 { 18 PetscFunctionBegin; 19 if (Petsc_Viewer_keyval != MPI_KEYVAL_INVALID) PetscCallMPI(MPI_Comm_free_keyval(&Petsc_Viewer_keyval)); 20 if (Petsc_Viewer_Stdout_keyval != MPI_KEYVAL_INVALID) PetscCallMPI(MPI_Comm_free_keyval(&Petsc_Viewer_Stdout_keyval)); 21 if (Petsc_Viewer_Stderr_keyval != MPI_KEYVAL_INVALID) PetscCallMPI(MPI_Comm_free_keyval(&Petsc_Viewer_Stderr_keyval)); 22 if (Petsc_Viewer_Binary_keyval != MPI_KEYVAL_INVALID) PetscCallMPI(MPI_Comm_free_keyval(&Petsc_Viewer_Binary_keyval)); 23 if (Petsc_Viewer_Draw_keyval != MPI_KEYVAL_INVALID) PetscCallMPI(MPI_Comm_free_keyval(&Petsc_Viewer_Draw_keyval)); 24 #if defined(PETSC_HAVE_HDF5) 25 if (Petsc_Viewer_HDF5_keyval != MPI_KEYVAL_INVALID) PetscCallMPI(MPI_Comm_free_keyval(&Petsc_Viewer_HDF5_keyval)); 26 #endif 27 #if defined(PETSC_USE_SOCKETVIEWER) 28 if (Petsc_Viewer_Socket_keyval != MPI_KEYVAL_INVALID) PetscCallMPI(MPI_Comm_free_keyval(&Petsc_Viewer_Socket_keyval)); 29 #endif 30 PetscCall(PetscFunctionListDestroy(&PetscViewerList)); 31 PetscViewerPackageInitialized = PETSC_FALSE; 32 PetscViewerRegisterAllCalled = PETSC_FALSE; 33 PetscFunctionReturn(PETSC_SUCCESS); 34 } 35 36 /*@C 37 PetscViewerInitializePackage - This function initializes everything in the `PetscViewer` package. 38 39 Level: developer 40 41 .seealso: [](sec_viewers), `PetscViewer`, `PetscInitialize()`, `PetscViewerFinalizePackage()` 42 @*/ 43 PetscErrorCode PetscViewerInitializePackage(void) 44 { 45 char logList[256]; 46 PetscBool opt, pkg; 47 48 PetscFunctionBegin; 49 if (PetscViewerPackageInitialized) PetscFunctionReturn(PETSC_SUCCESS); 50 PetscViewerPackageInitialized = PETSC_TRUE; 51 /* Register Classes */ 52 PetscCall(PetscClassIdRegister("Viewer", &PETSC_VIEWER_CLASSID)); 53 /* Register Constructors */ 54 PetscCall(PetscViewerRegisterAll()); 55 /* Process Info */ 56 { 57 PetscClassId classids[1]; 58 59 classids[0] = PETSC_VIEWER_CLASSID; 60 PetscCall(PetscInfoProcessClass("viewer", 1, classids)); 61 } 62 /* Process summary exclusions */ 63 PetscCall(PetscOptionsGetString(NULL, NULL, "-log_exclude", logList, sizeof(logList), &opt)); 64 if (opt) { 65 PetscCall(PetscStrInList("viewer", logList, ',', &pkg)); 66 if (pkg) PetscCall(PetscLogEventExcludeClass(PETSC_VIEWER_CLASSID)); 67 } 68 #if defined(PETSC_HAVE_MATHEMATICA) 69 PetscCall(PetscViewerMathematicaInitializePackage()); 70 #endif 71 /* Register package finalizer */ 72 PetscCall(PetscRegisterFinalize(PetscViewerFinalizePackage)); 73 PetscFunctionReturn(PETSC_SUCCESS); 74 } 75 76 /*@ 77 PetscViewerDestroy - Destroys a `PetscViewer`. 78 79 Collective 80 81 Input Parameter: 82 . viewer - the `PetscViewer` to be destroyed. 83 84 Level: beginner 85 86 .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerCreate()`, `PetscViewerSocketOpen()`, `PetscViewerASCIIOpen()`, `PetscViewerDrawOpen()` 87 @*/ 88 PetscErrorCode PetscViewerDestroy(PetscViewer *viewer) 89 { 90 PetscFunctionBegin; 91 if (!*viewer) PetscFunctionReturn(PETSC_SUCCESS); 92 PetscValidHeaderSpecific(*viewer, PETSC_VIEWER_CLASSID, 1); 93 94 PetscCall(PetscViewerFlush(*viewer)); 95 if (--((PetscObject)(*viewer))->refct > 0) { 96 *viewer = NULL; 97 PetscFunctionReturn(PETSC_SUCCESS); 98 } 99 100 PetscCall(PetscObjectSAWsViewOff((PetscObject)*viewer)); 101 if ((*viewer)->ops->destroy) PetscCall((*(*viewer)->ops->destroy)(*viewer)); 102 PetscCall(PetscHeaderDestroy(viewer)); 103 PetscFunctionReturn(PETSC_SUCCESS); 104 } 105 106 /*@C 107 PetscViewerAndFormatCreate - Creates a `PetscViewerAndFormat` struct. 108 109 Collective 110 111 Input Parameters: 112 + viewer - the viewer 113 - format - the format 114 115 Output Parameter: 116 . vf - viewer and format object 117 118 Level: developer 119 120 Notes: 121 This increases the reference count of the viewer. 122 123 Use `PetscViewerAndFormatDestroy()` to free the struct 124 125 This is used as the context variable for many of the `TS`, `SNES`, and `KSP` monitor functions 126 127 This construct exists because it allows one to keep track of the use of a `PetscViewerFormat` without requiring the 128 format in the viewer to be permanently changed. 129 130 .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerAndFormat`, `PetscViewerFormat`, `PetscViewerSocketOpen()`, `PetscViewerASCIIOpen()`, `PetscViewerCreate()`, 131 `PetscViewerDrawOpen()`, `PetscViewerAndFormatDestroy()` 132 @*/ 133 PetscErrorCode PetscViewerAndFormatCreate(PetscViewer viewer, PetscViewerFormat format, PetscViewerAndFormat **vf) 134 { 135 PetscFunctionBegin; 136 PetscCall(PetscObjectReference((PetscObject)viewer)); 137 PetscCall(PetscNew(vf)); 138 (*vf)->viewer = viewer; 139 (*vf)->format = format; 140 (*vf)->lg = NULL; 141 (*vf)->data = NULL; 142 PetscFunctionReturn(PETSC_SUCCESS); 143 } 144 145 /*@C 146 PetscViewerAndFormatDestroy - Destroys a `PetscViewerAndFormat` struct created with `PetscViewerAndFormatCreate()` 147 148 Collective 149 150 Input Parameter: 151 . vf - the `PetscViewerAndFormat` to be destroyed. 152 153 Level: developer 154 155 .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerAndFormat`, `PetscViewerFormat`, `PetscViewerAndFormatCreate()`, `PetscViewerSocketOpen()`, 156 `PetscViewerASCIIOpen()`, `PetscViewerCreate()`, `PetscViewerDrawOpen()` 157 @*/ 158 PetscErrorCode PetscViewerAndFormatDestroy(PetscViewerAndFormat **vf) 159 { 160 PetscFunctionBegin; 161 PetscCall(PetscViewerDestroy(&(*vf)->viewer)); 162 PetscCall(PetscDrawLGDestroy(&(*vf)->lg)); 163 PetscCall(PetscFree(*vf)); 164 PetscFunctionReturn(PETSC_SUCCESS); 165 } 166 167 /*@C 168 PetscViewerGetType - Returns the type of a `PetscViewer`. 169 170 Not Collective 171 172 Input Parameter: 173 . viewer - the `PetscViewer` 174 175 Output Parameter: 176 . type - `PetscViewerType` 177 178 Level: intermediate 179 180 Note: 181 `PetscViewerType` is actually a string 182 183 .seealso: [](sec_viewers), `PetscViewerType`, `PetscViewer`, `PetscViewerCreate()`, `PetscViewerSetType()` 184 @*/ 185 PetscErrorCode PetscViewerGetType(PetscViewer viewer, PetscViewerType *type) 186 { 187 PetscFunctionBegin; 188 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 189 PetscAssertPointer(type, 2); 190 *type = ((PetscObject)viewer)->type_name; 191 PetscFunctionReturn(PETSC_SUCCESS); 192 } 193 194 /*@C 195 PetscViewerSetOptionsPrefix - Sets the prefix used for searching for 196 `PetscViewer` options in the database during `PetscViewerSetFromOptions()`. 197 198 Logically Collective 199 200 Input Parameters: 201 + viewer - the `PetscViewer` context 202 - prefix - the prefix to prepend to all option names 203 204 Note: 205 A hyphen (-) must NOT be given at the beginning of the prefix name. 206 The first character of all runtime options is AUTOMATICALLY the hyphen. 207 208 Level: advanced 209 210 .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerSetFromOptions()`, `PetscViewerAppendOptionsPrefix()` 211 @*/ 212 PetscErrorCode PetscViewerSetOptionsPrefix(PetscViewer viewer, const char prefix[]) 213 { 214 PetscFunctionBegin; 215 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 216 PetscCall(PetscObjectSetOptionsPrefix((PetscObject)viewer, prefix)); 217 PetscFunctionReturn(PETSC_SUCCESS); 218 } 219 220 /*@C 221 PetscViewerAppendOptionsPrefix - Appends to the prefix used for searching for 222 `PetscViewer` options in the database during `PetscViewerSetFromOptions()`. 223 224 Logically Collective 225 226 Input Parameters: 227 + viewer - the `PetscViewer` context 228 - prefix - the prefix to prepend to all option names 229 230 Level: advanced 231 232 Note: 233 A hyphen (-) must NOT be given at the beginning of the prefix name. 234 The first character of all runtime options is AUTOMATICALLY the hyphen. 235 236 .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerGetOptionsPrefix()`, `PetscViewerSetOptionsPrefix()` 237 @*/ 238 PetscErrorCode PetscViewerAppendOptionsPrefix(PetscViewer viewer, const char prefix[]) 239 { 240 PetscFunctionBegin; 241 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 242 PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)viewer, prefix)); 243 PetscFunctionReturn(PETSC_SUCCESS); 244 } 245 246 /*@C 247 PetscViewerGetOptionsPrefix - Gets the prefix used for searching for 248 `PetscViewer` options in the database during `PetscViewerSetFromOptions()`. 249 250 Not Collective 251 252 Input Parameter: 253 . viewer - the `PetscViewer` context 254 255 Output Parameter: 256 . prefix - pointer to the prefix string used 257 258 Level: advanced 259 260 Fortran Notes: 261 The user should pass in a string 'prefix' of sufficient length to hold the prefix. 262 263 .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerAppendOptionsPrefix()`, `PetscViewerSetOptionsPrefix()` 264 @*/ 265 PetscErrorCode PetscViewerGetOptionsPrefix(PetscViewer viewer, const char *prefix[]) 266 { 267 PetscFunctionBegin; 268 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 269 PetscCall(PetscObjectGetOptionsPrefix((PetscObject)viewer, prefix)); 270 PetscFunctionReturn(PETSC_SUCCESS); 271 } 272 273 /*@ 274 PetscViewerSetUp - Sets up the internal viewer data structures for the later use. 275 276 Collective 277 278 Input Parameter: 279 . viewer - the `PetscViewer` context 280 281 Level: advanced 282 283 Note: 284 For basic use of the `PetscViewer` classes the user need not explicitly call 285 `PetscViewerSetUp()`, since these actions will happen automatically. 286 287 .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerCreate()`, `PetscViewerDestroy()` 288 @*/ 289 PetscErrorCode PetscViewerSetUp(PetscViewer viewer) 290 { 291 PetscFunctionBegin; 292 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 293 if (viewer->setupcalled) PetscFunctionReturn(PETSC_SUCCESS); 294 PetscTryTypeMethod(viewer, setup); 295 viewer->setupcalled = PETSC_TRUE; 296 PetscFunctionReturn(PETSC_SUCCESS); 297 } 298 299 /*@C 300 PetscViewerViewFromOptions - View from the viewer based on options in the options database 301 302 Collective 303 304 Input Parameters: 305 + A - the `PetscViewer` context 306 . obj - Optional object that provides the prefix for the option names 307 - name - command line option 308 309 Level: intermediate 310 311 Note: 312 See `PetscObjectViewFromOptions()` for details on the viewers and formats support via this interface 313 314 .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerView`, `PetscObjectViewFromOptions()`, `PetscViewerCreate()` 315 @*/ 316 PetscErrorCode PetscViewerViewFromOptions(PetscViewer A, PetscObject obj, const char name[]) 317 { 318 PetscFunctionBegin; 319 PetscValidHeaderSpecific(A, PETSC_VIEWER_CLASSID, 1); 320 PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name)); 321 PetscFunctionReturn(PETSC_SUCCESS); 322 } 323 324 /*@C 325 PetscViewerView - Visualizes a viewer object. 326 327 Collective 328 329 Input Parameters: 330 + v - the viewer to be viewed 331 - viewer - visualization context 332 333 Level: beginner 334 335 .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerPushFormat()`, `PetscViewerASCIIOpen()`, `PetscViewerDrawOpen()`, 336 `PetscViewerSocketOpen()`, `PetscViewerBinaryOpen()`, `PetscViewerLoad()` 337 @*/ 338 PetscErrorCode PetscViewerView(PetscViewer v, PetscViewer viewer) 339 { 340 PetscBool iascii; 341 PetscViewerFormat format; 342 #if defined(PETSC_HAVE_SAWS) 343 PetscBool issaws; 344 #endif 345 346 PetscFunctionBegin; 347 PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 1); 348 PetscValidType(v, 1); 349 if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)v), &viewer)); 350 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 351 PetscCheckSameComm(v, 1, viewer, 2); 352 353 PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 354 #if defined(PETSC_HAVE_SAWS) 355 PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSAWS, &issaws)); 356 #endif 357 if (iascii) { 358 PetscCall(PetscViewerGetFormat(viewer, &format)); 359 PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)v, viewer)); 360 if (format == PETSC_VIEWER_DEFAULT || format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 361 if (v->format) PetscCall(PetscViewerASCIIPrintf(viewer, " Viewer format = %s\n", PetscViewerFormats[v->format])); 362 PetscCall(PetscViewerASCIIPushTab(viewer)); 363 PetscTryTypeMethod(v, view, viewer); 364 PetscCall(PetscViewerASCIIPopTab(viewer)); 365 } 366 #if defined(PETSC_HAVE_SAWS) 367 } else if (issaws) { 368 if (!((PetscObject)v)->amsmem) { 369 PetscCall(PetscObjectViewSAWs((PetscObject)v, viewer)); 370 PetscTryTypeMethod(v, view, viewer); 371 } 372 #endif 373 } 374 PetscFunctionReturn(PETSC_SUCCESS); 375 } 376 377 /*@C 378 PetscViewerRead - Reads data from a `PetscViewer` 379 380 Collective 381 382 Input Parameters: 383 + viewer - The viewer 384 . data - Location to write the data, treated as an array of the type defined by `datatype` 385 . num - Number of items of data to read 386 - dtype - Type of data to read 387 388 Output Parameter: 389 . count - number of items of data actually read, or `NULL` 390 391 Level: beginner 392 393 Notes: 394 If datatype is `PETSC_STRING` and `num` is negative, reads until a newline character is found, 395 until a maximum of (-num - 1) chars. 396 397 Only certain viewers, such as `PETSCVIEWERBINARY` can be read from, see `PetscViewerReadable()` 398 399 .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerASCIIOpen()`, `PetscViewerPushFormat()`, `PetscViewerDestroy()`, 400 `PetscViewerReadable()`, `PetscViewerBinaryGetDescriptor()`, 401 `PetscViewerBinaryGetInfoPointer()`, `PetscFileMode` 402 @*/ 403 PetscErrorCode PetscViewerRead(PetscViewer viewer, void *data, PetscInt num, PetscInt *count, PetscDataType dtype) 404 { 405 PetscFunctionBegin; 406 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 407 if (dtype == PETSC_STRING) { 408 PetscInt c, i = 0, cnt; 409 char *s = (char *)data; 410 if (num >= 0) { 411 for (c = 0; c < num; c++) { 412 /* Skip leading whitespaces */ 413 do { 414 PetscCall((*viewer->ops->read)(viewer, &(s[i]), 1, &cnt, PETSC_CHAR)); 415 if (!cnt) break; 416 } while (s[i] == '\n' || s[i] == '\t' || s[i] == ' ' || s[i] == '\0' || s[i] == '\v' || s[i] == '\f' || s[i] == '\r'); 417 i++; 418 /* Read strings one char at a time */ 419 do { 420 PetscCall((*viewer->ops->read)(viewer, &(s[i++]), 1, &cnt, PETSC_CHAR)); 421 if (!cnt) break; 422 } while (s[i - 1] != '\n' && s[i - 1] != '\t' && s[i - 1] != ' ' && s[i - 1] != '\0' && s[i - 1] != '\v' && s[i - 1] != '\f' && s[i - 1] != '\r'); 423 /* Terminate final string */ 424 if (c == num - 1) s[i - 1] = '\0'; 425 } 426 } else { 427 /* Read until a \n is encountered (-num is the max size allowed) */ 428 do { 429 PetscCall((*viewer->ops->read)(viewer, &(s[i++]), 1, &cnt, PETSC_CHAR)); 430 if (i == -num || !cnt) break; 431 } while (s[i - 1] != '\n'); 432 /* Terminate final string */ 433 s[i - 1] = '\0'; 434 c = i; 435 } 436 if (count) *count = c; 437 else PetscCheck(c >= num, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_READ, "Insufficient data, only read %" PetscInt_FMT " < %" PetscInt_FMT " strings", c, num); 438 } else PetscUseTypeMethod(viewer, read, data, num, count, dtype); 439 PetscFunctionReturn(PETSC_SUCCESS); 440 } 441 442 /*@ 443 PetscViewerReadable - Return a flag whether the viewer can be read from with `PetscViewerRead()` 444 445 Not Collective 446 447 Input Parameter: 448 . viewer - the `PetscViewer` context 449 450 Output Parameter: 451 . flg - `PETSC_TRUE` if the viewer is readable, `PETSC_FALSE` otherwise 452 453 Level: intermediate 454 455 Note: 456 `PETSC_TRUE` means that viewer's `PetscViewerType` supports reading, that is `PetscViewerRead()`, (this holds e.g. for `PETSCVIEWERBINARY`) 457 and the viewer is in a mode allowing reading, i.e. `PetscViewerFileGetMode()` 458 returns one of `FILE_MODE_READ`, `FILE_MODE_UPDATE`, `FILE_MODE_APPEND_UPDATE`. 459 460 .seealso: [](sec_viewers), `PetscViewerRead()`, `PetscViewer`, `PetscViewerWritable()`, `PetscViewerCheckReadable()`, `PetscViewerCreate()`, `PetscViewerFileSetMode()`, `PetscViewerFileSetType()` 461 @*/ 462 PetscErrorCode PetscViewerReadable(PetscViewer viewer, PetscBool *flg) 463 { 464 PetscFileMode mode; 465 PetscErrorCode (*f)(PetscViewer, PetscFileMode *) = NULL; 466 467 PetscFunctionBegin; 468 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 469 PetscAssertPointer(flg, 2); 470 PetscCall(PetscObjectQueryFunction((PetscObject)viewer, "PetscViewerFileGetMode_C", &f)); 471 *flg = PETSC_FALSE; 472 if (!f) PetscFunctionReturn(PETSC_SUCCESS); 473 PetscCall((*f)(viewer, &mode)); 474 switch (mode) { 475 case FILE_MODE_READ: 476 case FILE_MODE_UPDATE: 477 case FILE_MODE_APPEND_UPDATE: 478 *flg = PETSC_TRUE; 479 default: 480 break; 481 } 482 PetscFunctionReturn(PETSC_SUCCESS); 483 } 484 485 /*@ 486 PetscViewerWritable - Return a flag whether the viewer can be written to with `PetscViewerWrite()` 487 488 Not Collective 489 490 Input Parameter: 491 . viewer - the `PetscViewer` context 492 493 Output Parameter: 494 . flg - `PETSC_TRUE` if the viewer is writable, `PETSC_FALSE` otherwise 495 496 Level: intermediate 497 498 Note: 499 `PETSC_TRUE` means viewer is in a mode allowing writing, i.e. `PetscViewerFileGetMode()` 500 returns one of `FILE_MODE_WRITE`, `FILE_MODE_APPEND`, `FILE_MODE_UPDATE`, `FILE_MODE_APPEND_UPDATE`. 501 502 .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerReadable()`, `PetscViewerCheckWritable()`, `PetscViewerCreate()`, `PetscViewerFileSetMode()`, `PetscViewerFileSetType()` 503 @*/ 504 PetscErrorCode PetscViewerWritable(PetscViewer viewer, PetscBool *flg) 505 { 506 PetscFileMode mode; 507 PetscErrorCode (*f)(PetscViewer, PetscFileMode *) = NULL; 508 509 PetscFunctionBegin; 510 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 511 PetscAssertPointer(flg, 2); 512 PetscCall(PetscObjectQueryFunction((PetscObject)viewer, "PetscViewerFileGetMode_C", &f)); 513 *flg = PETSC_TRUE; 514 if (!f) PetscFunctionReturn(PETSC_SUCCESS); 515 PetscCall((*f)(viewer, &mode)); 516 if (mode == FILE_MODE_READ) *flg = PETSC_FALSE; 517 PetscFunctionReturn(PETSC_SUCCESS); 518 } 519 520 /*@ 521 PetscViewerCheckReadable - Check whether the viewer can be read from, generates an error if not 522 523 Collective 524 525 Input Parameter: 526 . viewer - the `PetscViewer` context 527 528 Level: intermediate 529 530 .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerReadable()`, `PetscViewerCheckWritable()`, `PetscViewerCreate()`, `PetscViewerFileSetMode()`, `PetscViewerFileSetType()` 531 @*/ 532 PetscErrorCode PetscViewerCheckReadable(PetscViewer viewer) 533 { 534 PetscBool flg; 535 536 PetscFunctionBegin; 537 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 538 PetscCall(PetscViewerReadable(viewer, &flg)); 539 PetscCheck(flg, PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Viewer doesn't support reading, or is not in reading mode (FILE_MODE_READ, FILE_MODE_UPDATE, FILE_MODE_APPEND_UPDATE)"); 540 PetscFunctionReturn(PETSC_SUCCESS); 541 } 542 543 /*@ 544 PetscViewerCheckWritable - Check whether the viewer can be written to, generates an error if not 545 546 Collective 547 548 Input Parameter: 549 . viewer - the `PetscViewer` context 550 551 Level: intermediate 552 553 .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerWritable()`, `PetscViewerCheckReadable()`, `PetscViewerCreate()`, `PetscViewerFileSetMode()`, `PetscViewerFileSetType()` 554 @*/ 555 PetscErrorCode PetscViewerCheckWritable(PetscViewer viewer) 556 { 557 PetscBool flg; 558 559 PetscFunctionBegin; 560 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 561 PetscCall(PetscViewerWritable(viewer, &flg)); 562 PetscCheck(flg, PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Viewer doesn't support writing, or is in FILE_MODE_READ mode"); 563 PetscFunctionReturn(PETSC_SUCCESS); 564 } 565