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 PetscTryTypeMethod(*viewer, destroy); 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)->data = NULL; 141 PetscFunctionReturn(PETSC_SUCCESS); 142 } 143 144 /*@C 145 PetscViewerAndFormatDestroy - Destroys a `PetscViewerAndFormat` struct created with `PetscViewerAndFormatCreate()` 146 147 Collective 148 149 Input Parameter: 150 . vf - the `PetscViewerAndFormat` to be destroyed. 151 152 Level: developer 153 154 .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerAndFormat`, `PetscViewerFormat`, `PetscViewerAndFormatCreate()`, `PetscViewerSocketOpen()`, 155 `PetscViewerASCIIOpen()`, `PetscViewerCreate()`, `PetscViewerDrawOpen()` 156 @*/ 157 PetscErrorCode PetscViewerAndFormatDestroy(PetscViewerAndFormat **vf) 158 { 159 PetscFunctionBegin; 160 PetscCall(PetscViewerDestroy(&(*vf)->viewer)); 161 if ((*vf)->data_destroy) PetscCall((*vf)->data_destroy(&(*vf)->data)); 162 PetscCall(PetscFree(*vf)); 163 PetscFunctionReturn(PETSC_SUCCESS); 164 } 165 166 /*@ 167 PetscViewerGetType - Returns the type of a `PetscViewer`. 168 169 Not Collective 170 171 Input Parameter: 172 . viewer - the `PetscViewer` 173 174 Output Parameter: 175 . type - `PetscViewerType` 176 177 Level: intermediate 178 179 Note: 180 `PetscViewerType` is actually a string 181 182 .seealso: [](sec_viewers), `PetscViewerType`, `PetscViewer`, `PetscViewerCreate()`, `PetscViewerSetType()` 183 @*/ 184 PetscErrorCode PetscViewerGetType(PetscViewer viewer, PetscViewerType *type) 185 { 186 PetscFunctionBegin; 187 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 188 PetscAssertPointer(type, 2); 189 *type = ((PetscObject)viewer)->type_name; 190 PetscFunctionReturn(PETSC_SUCCESS); 191 } 192 193 /*@ 194 PetscViewerSetOptionsPrefix - Sets the prefix used for searching for 195 `PetscViewer` options in the database during `PetscViewerSetFromOptions()`. 196 197 Logically Collective 198 199 Input Parameters: 200 + viewer - the `PetscViewer` context 201 - prefix - the prefix to prepend to all option names 202 203 Note: 204 A hyphen (-) must NOT be given at the beginning of the prefix name. 205 The first character of all runtime options is AUTOMATICALLY the hyphen. 206 207 Level: advanced 208 209 .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerSetFromOptions()`, `PetscViewerAppendOptionsPrefix()` 210 @*/ 211 PetscErrorCode PetscViewerSetOptionsPrefix(PetscViewer viewer, const char prefix[]) 212 { 213 PetscFunctionBegin; 214 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 215 PetscCall(PetscObjectSetOptionsPrefix((PetscObject)viewer, prefix)); 216 PetscFunctionReturn(PETSC_SUCCESS); 217 } 218 219 /*@ 220 PetscViewerAppendOptionsPrefix - Appends to the prefix used for searching for 221 `PetscViewer` options in the database during `PetscViewerSetFromOptions()`. 222 223 Logically Collective 224 225 Input Parameters: 226 + viewer - the `PetscViewer` context 227 - prefix - the prefix to prepend to all option names 228 229 Level: advanced 230 231 Note: 232 A hyphen (-) must NOT be given at the beginning of the prefix name. 233 The first character of all runtime options is AUTOMATICALLY the hyphen. 234 235 .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerGetOptionsPrefix()`, `PetscViewerSetOptionsPrefix()` 236 @*/ 237 PetscErrorCode PetscViewerAppendOptionsPrefix(PetscViewer viewer, const char prefix[]) 238 { 239 PetscFunctionBegin; 240 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 241 PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)viewer, prefix)); 242 PetscFunctionReturn(PETSC_SUCCESS); 243 } 244 245 /*@ 246 PetscViewerGetOptionsPrefix - Gets the prefix used for searching for 247 `PetscViewer` options in the database during `PetscViewerSetFromOptions()`. 248 249 Not Collective 250 251 Input Parameter: 252 . viewer - the `PetscViewer` context 253 254 Output Parameter: 255 . prefix - pointer to the prefix string used 256 257 Level: advanced 258 259 Fortran Notes: 260 The user should pass in a string 'prefix' of sufficient length to hold the prefix. 261 262 .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerAppendOptionsPrefix()`, `PetscViewerSetOptionsPrefix()` 263 @*/ 264 PetscErrorCode PetscViewerGetOptionsPrefix(PetscViewer viewer, const char *prefix[]) 265 { 266 PetscFunctionBegin; 267 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 268 PetscCall(PetscObjectGetOptionsPrefix((PetscObject)viewer, prefix)); 269 PetscFunctionReturn(PETSC_SUCCESS); 270 } 271 272 /*@ 273 PetscViewerSetUp - Sets up the internal viewer data structures for the later use. 274 275 Collective 276 277 Input Parameter: 278 . viewer - the `PetscViewer` context 279 280 Level: advanced 281 282 Note: 283 For basic use of the `PetscViewer` classes the user need not explicitly call 284 `PetscViewerSetUp()`, since these actions will happen automatically. 285 286 .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerCreate()`, `PetscViewerDestroy()` 287 @*/ 288 PetscErrorCode PetscViewerSetUp(PetscViewer viewer) 289 { 290 PetscFunctionBegin; 291 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 292 if (viewer->setupcalled) PetscFunctionReturn(PETSC_SUCCESS); 293 PetscTryTypeMethod(viewer, setup); 294 viewer->setupcalled = PETSC_TRUE; 295 PetscFunctionReturn(PETSC_SUCCESS); 296 } 297 298 /*@ 299 PetscViewerViewFromOptions - View from the viewer based on options in the options database 300 301 Collective 302 303 Input Parameters: 304 + A - the `PetscViewer` context 305 . obj - Optional object that provides the prefix for the option names 306 - name - command line option 307 308 Level: intermediate 309 310 Note: 311 See `PetscObjectViewFromOptions()` for details on the viewers and formats support via this interface 312 313 .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerView`, `PetscObjectViewFromOptions()`, `PetscViewerCreate()` 314 @*/ 315 PetscErrorCode PetscViewerViewFromOptions(PetscViewer A, PetscObject obj, const char name[]) 316 { 317 PetscFunctionBegin; 318 PetscValidHeaderSpecific(A, PETSC_VIEWER_CLASSID, 1); 319 PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name)); 320 PetscFunctionReturn(PETSC_SUCCESS); 321 } 322 323 /*@ 324 PetscViewerView - Visualizes a viewer object. 325 326 Collective 327 328 Input Parameters: 329 + v - the viewer to be viewed 330 - viewer - visualization context 331 332 Level: beginner 333 334 .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerPushFormat()`, `PetscViewerASCIIOpen()`, `PetscViewerDrawOpen()`, 335 `PetscViewerSocketOpen()`, `PetscViewerBinaryOpen()`, `PetscViewerLoad()` 336 @*/ 337 PetscErrorCode PetscViewerView(PetscViewer v, PetscViewer viewer) 338 { 339 PetscBool iascii; 340 PetscViewerFormat format; 341 #if defined(PETSC_HAVE_SAWS) 342 PetscBool issaws; 343 #endif 344 345 PetscFunctionBegin; 346 PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 1); 347 PetscValidType(v, 1); 348 if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)v), &viewer)); 349 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 350 PetscCheckSameComm(v, 1, viewer, 2); 351 352 PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 353 #if defined(PETSC_HAVE_SAWS) 354 PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSAWS, &issaws)); 355 #endif 356 if (iascii) { 357 PetscCall(PetscViewerGetFormat(viewer, &format)); 358 PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)v, viewer)); 359 if (format == PETSC_VIEWER_DEFAULT || format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 360 if (v->format) PetscCall(PetscViewerASCIIPrintf(viewer, " Viewer format = %s\n", PetscViewerFormats[v->format])); 361 PetscCall(PetscViewerASCIIPushTab(viewer)); 362 PetscTryTypeMethod(v, view, viewer); 363 PetscCall(PetscViewerASCIIPopTab(viewer)); 364 } 365 #if defined(PETSC_HAVE_SAWS) 366 } else if (issaws) { 367 if (!((PetscObject)v)->amsmem) { 368 PetscCall(PetscObjectViewSAWs((PetscObject)v, viewer)); 369 PetscTryTypeMethod(v, view, viewer); 370 } 371 #endif 372 } 373 PetscFunctionReturn(PETSC_SUCCESS); 374 } 375 376 /*@C 377 PetscViewerRead - Reads data from a `PetscViewer` 378 379 Collective 380 381 Input Parameters: 382 + viewer - The viewer 383 . data - Location to write the data, treated as an array of the type defined by `datatype` 384 . num - Number of items of data to read 385 - dtype - Type of data to read 386 387 Output Parameter: 388 . count - number of items of data actually read, or `NULL` 389 390 Level: beginner 391 392 Notes: 393 If datatype is `PETSC_STRING` and `num` is negative, reads until a newline character is found, 394 until a maximum of (-num - 1) chars. 395 396 Only certain viewers, such as `PETSCVIEWERBINARY` can be read from, see `PetscViewerReadable()` 397 398 .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerASCIIOpen()`, `PetscViewerPushFormat()`, `PetscViewerDestroy()`, 399 `PetscViewerReadable()`, `PetscViewerBinaryGetDescriptor()`, 400 `PetscViewerBinaryGetInfoPointer()`, `PetscFileMode` 401 @*/ 402 PetscErrorCode PetscViewerRead(PetscViewer viewer, void *data, PetscInt num, PetscInt *count, PetscDataType dtype) 403 { 404 PetscFunctionBegin; 405 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 406 if (dtype == PETSC_STRING) { 407 PetscInt c, i = 0, cnt; 408 char *s = (char *)data; 409 if (num >= 0) { 410 for (c = 0; c < num; c++) { 411 /* Skip leading whitespaces */ 412 do { 413 PetscUseTypeMethod(viewer, read, &s[i], 1, &cnt, PETSC_CHAR); 414 if (!cnt) break; 415 } while (s[i] == '\n' || s[i] == '\t' || s[i] == ' ' || s[i] == '\0' || s[i] == '\v' || s[i] == '\f' || s[i] == '\r'); 416 i++; 417 /* Read strings one char at a time */ 418 do { 419 PetscUseTypeMethod(viewer, read, &s[i++], 1, &cnt, PETSC_CHAR); 420 if (!cnt) break; 421 } 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'); 422 /* Terminate final string */ 423 if (c == num - 1) s[i - 1] = '\0'; 424 } 425 } else { 426 /* Read until a \n is encountered (-num is the max size allowed) */ 427 do { 428 PetscUseTypeMethod(viewer, read, &s[i++], 1, &cnt, PETSC_CHAR); 429 if (i == -num || !cnt) break; 430 } while (s[i - 1] != '\n'); 431 /* Terminate final string */ 432 s[i - 1] = '\0'; 433 c = i; 434 } 435 if (count) *count = c; 436 else PetscCheck(c >= num, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_READ, "Insufficient data, only read %" PetscInt_FMT " < %" PetscInt_FMT " strings", c, num); 437 } else PetscUseTypeMethod(viewer, read, data, num, count, dtype); 438 PetscFunctionReturn(PETSC_SUCCESS); 439 } 440 441 /*@ 442 PetscViewerReadable - Return a flag whether the viewer can be read from with `PetscViewerRead()` 443 444 Not Collective 445 446 Input Parameter: 447 . viewer - the `PetscViewer` context 448 449 Output Parameter: 450 . flg - `PETSC_TRUE` if the viewer is readable, `PETSC_FALSE` otherwise 451 452 Level: intermediate 453 454 Note: 455 `PETSC_TRUE` means that viewer's `PetscViewerType` supports reading, that is `PetscViewerRead()`, (this holds e.g. for `PETSCVIEWERBINARY`) 456 and the viewer is in a mode allowing reading, i.e. `PetscViewerFileGetMode()` 457 returns one of `FILE_MODE_READ`, `FILE_MODE_UPDATE`, `FILE_MODE_APPEND_UPDATE`. 458 459 .seealso: [](sec_viewers), `PetscViewerRead()`, `PetscViewer`, `PetscViewerWritable()`, `PetscViewerCheckReadable()`, `PetscViewerCreate()`, `PetscViewerFileSetMode()`, `PetscViewerFileSetType()` 460 @*/ 461 PetscErrorCode PetscViewerReadable(PetscViewer viewer, PetscBool *flg) 462 { 463 PetscFileMode mode; 464 PetscErrorCode (*f)(PetscViewer, PetscFileMode *) = NULL; 465 466 PetscFunctionBegin; 467 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 468 PetscAssertPointer(flg, 2); 469 PetscCall(PetscObjectQueryFunction((PetscObject)viewer, "PetscViewerFileGetMode_C", &f)); 470 *flg = PETSC_FALSE; 471 if (!f) PetscFunctionReturn(PETSC_SUCCESS); 472 PetscCall((*f)(viewer, &mode)); 473 switch (mode) { 474 case FILE_MODE_READ: 475 case FILE_MODE_UPDATE: 476 case FILE_MODE_APPEND_UPDATE: 477 *flg = PETSC_TRUE; 478 default: 479 break; 480 } 481 PetscFunctionReturn(PETSC_SUCCESS); 482 } 483 484 /*@ 485 PetscViewerWritable - Return a flag whether the viewer can be written to with `PetscViewerWrite()` 486 487 Not Collective 488 489 Input Parameter: 490 . viewer - the `PetscViewer` context 491 492 Output Parameter: 493 . flg - `PETSC_TRUE` if the viewer is writable, `PETSC_FALSE` otherwise 494 495 Level: intermediate 496 497 Note: 498 `PETSC_TRUE` means viewer is in a mode allowing writing, i.e. `PetscViewerFileGetMode()` 499 returns one of `FILE_MODE_WRITE`, `FILE_MODE_APPEND`, `FILE_MODE_UPDATE`, `FILE_MODE_APPEND_UPDATE`. 500 501 .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerReadable()`, `PetscViewerCheckWritable()`, `PetscViewerCreate()`, `PetscViewerFileSetMode()`, `PetscViewerFileSetType()` 502 @*/ 503 PetscErrorCode PetscViewerWritable(PetscViewer viewer, PetscBool *flg) 504 { 505 PetscFileMode mode; 506 PetscErrorCode (*f)(PetscViewer, PetscFileMode *) = NULL; 507 508 PetscFunctionBegin; 509 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 510 PetscAssertPointer(flg, 2); 511 PetscCall(PetscObjectQueryFunction((PetscObject)viewer, "PetscViewerFileGetMode_C", &f)); 512 *flg = PETSC_TRUE; 513 if (!f) PetscFunctionReturn(PETSC_SUCCESS); 514 PetscCall((*f)(viewer, &mode)); 515 if (mode == FILE_MODE_READ) *flg = PETSC_FALSE; 516 PetscFunctionReturn(PETSC_SUCCESS); 517 } 518 519 /*@ 520 PetscViewerCheckReadable - Check whether the viewer can be read from, generates an error if not 521 522 Collective 523 524 Input Parameter: 525 . viewer - the `PetscViewer` context 526 527 Level: intermediate 528 529 .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerReadable()`, `PetscViewerCheckWritable()`, `PetscViewerCreate()`, `PetscViewerFileSetMode()`, `PetscViewerFileSetType()` 530 @*/ 531 PetscErrorCode PetscViewerCheckReadable(PetscViewer viewer) 532 { 533 PetscBool flg; 534 535 PetscFunctionBegin; 536 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 537 PetscCall(PetscViewerReadable(viewer, &flg)); 538 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)"); 539 PetscFunctionReturn(PETSC_SUCCESS); 540 } 541 542 /*@ 543 PetscViewerCheckWritable - Check whether the viewer can be written to, generates an error if not 544 545 Collective 546 547 Input Parameter: 548 . viewer - the `PetscViewer` context 549 550 Level: intermediate 551 552 .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerWritable()`, `PetscViewerCheckReadable()`, `PetscViewerCreate()`, `PetscViewerFileSetMode()`, `PetscViewerFileSetType()` 553 @*/ 554 PetscErrorCode PetscViewerCheckWritable(PetscViewer viewer) 555 { 556 PetscBool flg; 557 558 PetscFunctionBegin; 559 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 560 PetscCall(PetscViewerWritable(viewer, &flg)); 561 PetscCheck(flg, PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Viewer doesn't support writing, or is in FILE_MODE_READ mode"); 562 PetscFunctionReturn(PETSC_SUCCESS); 563 } 564