1 2 #include <petsc/private/viewerimpl.h> /*I "petscviewer.h" I*/ 3 #include <petscdraw.h> 4 5 PetscClassId PETSC_VIEWER_CLASSID; 6 7 static PetscBool PetscViewerPackageInitialized = PETSC_FALSE; 8 /*@C 9 PetscViewerFinalizePackage - This function destroys any global objects created in the Petsc viewers. It is 10 called from `PetscFinalize()`. 11 12 Level: developer 13 14 .seealso: [](sec_viewers), `PetscFinalize()` 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), `PetscInitialize()` 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 Parameters: 82 . viewer - the `PetscViewer` to be destroyed. 83 84 Level: beginner 85 86 .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerSocketOpen()`, `PetscViewerASCIIOpen()`, `PetscViewerCreate()`, `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 so you can destroy the viewer object after this call 122 123 This is used as the context variable for many of the `TS`, `SNES`, and `KSP` monitor functions 124 125 .seealso: [](sec_viewers), `PetscViewerSocketOpen()`, `PetscViewerASCIIOpen()`, `PetscViewerCreate()`, `PetscViewerDrawOpen()`, `PetscViewerAndFormatDestroy()` 126 @*/ 127 PetscErrorCode PetscViewerAndFormatCreate(PetscViewer viewer, PetscViewerFormat format, PetscViewerAndFormat **vf) 128 { 129 PetscFunctionBegin; 130 PetscCall(PetscObjectReference((PetscObject)viewer)); 131 PetscCall(PetscNew(vf)); 132 (*vf)->viewer = viewer; 133 (*vf)->format = format; 134 (*vf)->lg = NULL; 135 (*vf)->data = NULL; 136 PetscFunctionReturn(PETSC_SUCCESS); 137 } 138 139 /*@C 140 PetscViewerAndFormatDestroy - Destroys a `PetscViewerAndFormat` struct. 141 142 Collective 143 144 Input Parameters: 145 . vf - the `PetscViewerAndFormat` to be destroyed. 146 147 Level: developer 148 149 .seealso: [](sec_viewers), `PetscViewerSocketOpen()`, `PetscViewerASCIIOpen()`, `PetscViewerCreate()`, `PetscViewerDrawOpen()`, `PetscViewerAndFormatCreate()` 150 @*/ 151 PetscErrorCode PetscViewerAndFormatDestroy(PetscViewerAndFormat **vf) 152 { 153 PetscFunctionBegin; 154 PetscCall(PetscViewerDestroy(&(*vf)->viewer)); 155 PetscCall(PetscDrawLGDestroy(&(*vf)->lg)); 156 PetscCall(PetscFree(*vf)); 157 PetscFunctionReturn(PETSC_SUCCESS); 158 } 159 160 /*@C 161 PetscViewerGetType - Returns the type of a `PetscViewer`. 162 163 Not Collective 164 165 Input Parameter: 166 . viewer - the `PetscViewer` 167 168 Output Parameter: 169 . type - `PetscViewerType` (see below) 170 171 Available Types Include: 172 + `PETSCVIEWERSOCKET` - Socket PetscViewer 173 . `PETSCVIEWERASCII` - ASCII PetscViewer 174 . `PETSCVIEWERBINARY` - binary file PetscViewer 175 . `PETSCVIEWERSTRING` - string PetscViewer 176 - `PETSCVIEWERDRAW` - drawing PetscViewer 177 178 Level: intermediate 179 180 Note: 181 See include/petscviewer.h for a complete list of `PetscViewer`s. 182 183 `PetscViewerType` is actually a string 184 185 .seealso: [](sec_viewers), `PetscViewerType`, `PetscViewer`, `PetscViewerCreate()`, `PetscViewerSetType()`, `PetscViewerType` 186 @*/ 187 PetscErrorCode PetscViewerGetType(PetscViewer viewer, PetscViewerType *type) 188 { 189 PetscFunctionBegin; 190 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 191 PetscValidPointer(type, 2); 192 *type = ((PetscObject)viewer)->type_name; 193 PetscFunctionReturn(PETSC_SUCCESS); 194 } 195 196 /*@C 197 PetscViewerSetOptionsPrefix - Sets the prefix used for searching for all 198 `PetscViewer` options in the database. 199 200 Logically Collective 201 202 Input Parameters: 203 + viewer - the `PetscViewer` context 204 - prefix - the prefix to prepend to all option names 205 206 Note: 207 A hyphen (-) must NOT be given at the beginning of the prefix name. 208 The first character of all runtime options is AUTOMATICALLY the hyphen. 209 210 Level: advanced 211 212 .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerSetFromOptions()` 213 @*/ 214 PetscErrorCode PetscViewerSetOptionsPrefix(PetscViewer viewer, const char prefix[]) 215 { 216 PetscFunctionBegin; 217 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 218 PetscCall(PetscObjectSetOptionsPrefix((PetscObject)viewer, prefix)); 219 PetscFunctionReturn(PETSC_SUCCESS); 220 } 221 222 /*@C 223 PetscViewerAppendOptionsPrefix - Appends to the prefix used for searching for all 224 `PetscViewer` options in the database. 225 226 Logically Collective 227 228 Input Parameters: 229 + viewer - the `PetscViewer` context 230 - prefix - the prefix to prepend to all option names 231 232 Level: advanced 233 234 Note: 235 A hyphen (-) must NOT be given at the beginning of the prefix name. 236 The first character of all runtime options is AUTOMATICALLY the hyphen. 237 238 .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerGetOptionsPrefix()` 239 @*/ 240 PetscErrorCode PetscViewerAppendOptionsPrefix(PetscViewer viewer, const char prefix[]) 241 { 242 PetscFunctionBegin; 243 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 244 PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)viewer, prefix)); 245 PetscFunctionReturn(PETSC_SUCCESS); 246 } 247 248 /*@C 249 PetscViewerGetOptionsPrefix - Sets the prefix used for searching for all 250 `PetscViewer` options in the database. 251 252 Not Collective 253 254 Input Parameter: 255 . viewer - the `PetscViewer` context 256 257 Output Parameter: 258 . prefix - pointer to the prefix string used 259 260 Level: advanced 261 262 Fortran Note: 263 The user should pass in a string 'prefix' of sufficient length to hold the prefix. 264 265 .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerAppendOptionsPrefix()` 266 @*/ 267 PetscErrorCode PetscViewerGetOptionsPrefix(PetscViewer viewer, const char *prefix[]) 268 { 269 PetscFunctionBegin; 270 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 271 PetscCall(PetscObjectGetOptionsPrefix((PetscObject)viewer, prefix)); 272 PetscFunctionReturn(PETSC_SUCCESS); 273 } 274 275 /*@ 276 PetscViewerSetUp - Sets up the internal viewer data structures for the later use. 277 278 Collective 279 280 Input Parameters: 281 . viewer - the `PetscViewer` context 282 283 Level: advanced 284 285 Note: 286 For basic use of the `PetscViewer` classes the user need not explicitly call 287 `PetscViewerSetUp()`, since these actions will happen automatically. 288 289 .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerCreate()`, `PetscViewerDestroy()` 290 @*/ 291 PetscErrorCode PetscViewerSetUp(PetscViewer viewer) 292 { 293 PetscFunctionBegin; 294 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 295 if (viewer->setupcalled) PetscFunctionReturn(PETSC_SUCCESS); 296 PetscTryTypeMethod(viewer, setup); 297 viewer->setupcalled = PETSC_TRUE; 298 PetscFunctionReturn(PETSC_SUCCESS); 299 } 300 301 /*@C 302 PetscViewerViewFromOptions - View from the viewer based on the options database values 303 304 Collective 305 306 Input Parameters: 307 + A - the `PetscViewer` context 308 . obj - Optional object that provides the prefix for the option names 309 - name - command line option 310 311 Level: intermediate 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 /*@C 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 384 . num - Number of items of data to read 385 - datatype - Type of data to read 386 387 Output Parameters: 388 . count - number of items of data actually read, or `NULL` 389 390 Level: beginner 391 392 Note: 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`, `PetscViewer` 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 PetscCall((*viewer->ops->read)(viewer, &(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 PetscCall((*viewer->ops->read)(viewer, &(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 PetscCall((*viewer->ops->read)(viewer, &(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 443 444 Not Collective 445 446 Input Parameters: 447 . viewer - the `PetscViewer` context 448 449 Output Parameters: 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 (this holds e.g. for `PETSCVIEWERBINARY`) 456 and 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 PetscValidBoolPointer(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 486 487 Not Collective 488 489 Input Parameters: 490 . viewer - the `PetscViewer` context 491 492 Output Parameters: 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 PetscValidBoolPointer(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 Parameters: 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 Parameters: 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