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