1 2 #include <../src/sys/classes/viewer/impls/ascii/asciiimpl.h> /*I "petscviewer.h" I*/ 3 4 #define QUEUESTRINGSIZE 8192 5 6 static PetscErrorCode PetscViewerFileClose_ASCII(PetscViewer viewer) 7 { 8 PetscMPIInt rank; 9 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data; 10 int err; 11 12 PetscFunctionBegin; 13 PetscCheck(!vascii->sviewer,PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()"); 14 PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank)); 15 if (rank == 0 && vascii->fd != stderr && vascii->fd != PETSC_STDOUT) { 16 if (vascii->fd && vascii->closefile) { 17 err = fclose(vascii->fd); 18 PetscCheck(!err,PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file"); 19 } 20 if (vascii->storecompressed) { 21 char par[PETSC_MAX_PATH_LEN],buf[PETSC_MAX_PATH_LEN]; 22 FILE *fp; 23 PetscCall(PetscStrncpy(par,"gzip ",sizeof(par))); 24 PetscCall(PetscStrlcat(par,vascii->filename,sizeof(par))); 25 #if defined(PETSC_HAVE_POPEN) 26 PetscCall(PetscPOpen(PETSC_COMM_SELF,NULL,par,"r",&fp)); 27 PetscCheck(!fgets(buf,1024,fp),PETSC_COMM_SELF,PETSC_ERR_LIB,"Error from compression command %s\n%s",par,buf); 28 PetscCall(PetscPClose(PETSC_COMM_SELF,fp)); 29 #else 30 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine"); 31 #endif 32 } 33 } 34 PetscCall(PetscFree(vascii->filename)); 35 PetscFunctionReturn(0); 36 } 37 38 /* ----------------------------------------------------------------------*/ 39 PetscErrorCode PetscViewerDestroy_ASCII(PetscViewer viewer) 40 { 41 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data; 42 PetscViewerLink *vlink; 43 PetscBool flg; 44 45 PetscFunctionBegin; 46 PetscCheck(!vascii->sviewer,PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()"); 47 PetscCall(PetscViewerFileClose_ASCII(viewer)); 48 PetscCall(PetscFree(vascii)); 49 50 /* remove the viewer from the list in the MPI Communicator */ 51 if (Petsc_Viewer_keyval == MPI_KEYVAL_INVALID) { 52 PetscCallMPI(MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,Petsc_DelViewer,&Petsc_Viewer_keyval,(void*)0)); 53 } 54 55 PetscCallMPI(MPI_Comm_get_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg)); 56 if (flg) { 57 if (vlink && vlink->viewer == viewer) { 58 if (vlink->next) { 59 PetscCallMPI(MPI_Comm_set_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval,vlink->next)); 60 } else { 61 PetscCallMPI(MPI_Comm_delete_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval)); 62 } 63 PetscCall(PetscFree(vlink)); 64 } else { 65 while (vlink && vlink->next) { 66 if (vlink->next->viewer == viewer) { 67 PetscViewerLink *nv = vlink->next; 68 vlink->next = vlink->next->next; 69 PetscCall(PetscFree(nv)); 70 } 71 vlink = vlink->next; 72 } 73 } 74 } 75 76 if (Petsc_Viewer_Stdout_keyval != MPI_KEYVAL_INVALID) { 77 PetscViewer aviewer; 78 PetscCallMPI(MPI_Comm_get_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stdout_keyval,(void**)&aviewer,(PetscMPIInt*)&flg)); 79 if (flg && aviewer == viewer) { 80 PetscCallMPI(MPI_Comm_delete_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stdout_keyval)); 81 } 82 } 83 if (Petsc_Viewer_Stderr_keyval != MPI_KEYVAL_INVALID) { 84 PetscViewer aviewer; 85 PetscCallMPI(MPI_Comm_get_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stderr_keyval,(void**)&aviewer,(PetscMPIInt*)&flg)); 86 if (flg && aviewer == viewer) { 87 PetscCallMPI(MPI_Comm_delete_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stderr_keyval)); 88 } 89 } 90 PetscFunctionReturn(0); 91 } 92 93 PetscErrorCode PetscViewerDestroy_ASCII_SubViewer(PetscViewer viewer) 94 { 95 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data; 96 97 PetscFunctionBegin; 98 PetscCall(PetscViewerRestoreSubViewer(vascii->bviewer,0,&viewer)); 99 PetscFunctionReturn(0); 100 } 101 102 PetscErrorCode PetscViewerFlush_ASCII(PetscViewer viewer) 103 { 104 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data; 105 int err; 106 MPI_Comm comm; 107 PetscMPIInt rank,size; 108 FILE *fd = vascii->fd; 109 110 PetscFunctionBegin; 111 PetscCheck(!vascii->sviewer,PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()"); 112 PetscCall(PetscObjectGetComm((PetscObject)viewer,&comm)); 113 PetscCallMPI(MPI_Comm_rank(comm,&rank)); 114 PetscCallMPI(MPI_Comm_size(comm,&size)); 115 116 if (!vascii->bviewer && rank == 0 && (vascii->mode != FILE_MODE_READ)) { 117 err = fflush(vascii->fd); 118 PetscCheck(!err,PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() call failed"); 119 } 120 121 if (vascii->allowsynchronized) { 122 PetscMPIInt tag,i,j,n = 0,dummy = 0; 123 char *message; 124 MPI_Status status; 125 126 PetscCall(PetscCommDuplicate(comm,&comm,&tag)); 127 128 /* First processor waits for messages from all other processors */ 129 if (rank == 0) { 130 /* flush my own messages that I may have queued up */ 131 PrintfQueue next = vascii->petsc_printfqueuebase,previous; 132 for (i=0; i<vascii->petsc_printfqueuelength; i++) { 133 if (!vascii->bviewer) { 134 PetscCall(PetscFPrintf(comm,fd,"%s",next->string)); 135 } else { 136 PetscCall(PetscViewerASCIISynchronizedPrintf(vascii->bviewer,"%s",next->string)); 137 } 138 previous = next; 139 next = next->next; 140 PetscCall(PetscFree(previous->string)); 141 PetscCall(PetscFree(previous)); 142 } 143 vascii->petsc_printfqueue = NULL; 144 vascii->petsc_printfqueuelength = 0; 145 for (i=1; i<size; i++) { 146 /* to prevent a flood of messages to process zero, request each message separately */ 147 PetscCallMPI(MPI_Send(&dummy,1,MPI_INT,i,tag,comm)); 148 PetscCallMPI(MPI_Recv(&n,1,MPI_INT,i,tag,comm,&status)); 149 for (j=0; j<n; j++) { 150 PetscMPIInt size = 0; 151 152 PetscCallMPI(MPI_Recv(&size,1,MPI_INT,i,tag,comm,&status)); 153 PetscCall(PetscMalloc1(size, &message)); 154 PetscCallMPI(MPI_Recv(message,size,MPI_CHAR,i,tag,comm,&status)); 155 if (!vascii->bviewer) { 156 PetscCall(PetscFPrintf(comm,fd,"%s",message)); 157 } else { 158 PetscCall(PetscViewerASCIISynchronizedPrintf(vascii->bviewer,"%s",message)); 159 } 160 PetscCall(PetscFree(message)); 161 } 162 } 163 } else { /* other processors send queue to processor 0 */ 164 PrintfQueue next = vascii->petsc_printfqueuebase,previous; 165 166 PetscCallMPI(MPI_Recv(&dummy,1,MPI_INT,0,tag,comm,&status)); 167 PetscCallMPI(MPI_Send(&vascii->petsc_printfqueuelength,1,MPI_INT,0,tag,comm)); 168 for (i=0; i<vascii->petsc_printfqueuelength; i++) { 169 PetscCallMPI(MPI_Send(&next->size,1,MPI_INT,0,tag,comm)); 170 PetscCallMPI(MPI_Send(next->string,next->size,MPI_CHAR,0,tag,comm)); 171 previous = next; 172 next = next->next; 173 PetscCall(PetscFree(previous->string)); 174 PetscCall(PetscFree(previous)); 175 } 176 vascii->petsc_printfqueue = NULL; 177 vascii->petsc_printfqueuelength = 0; 178 } 179 PetscCall(PetscCommDestroy(&comm)); 180 } 181 PetscFunctionReturn(0); 182 } 183 184 /*@C 185 PetscViewerASCIIGetPointer - Extracts the file pointer from an ASCII PetscViewer. 186 187 Not Collective, depending on the viewer the value may be meaningless except for process 0 of the viewer 188 189 Input Parameter: 190 . viewer - PetscViewer context, obtained from PetscViewerASCIIOpen() 191 192 Output Parameter: 193 . fd - file pointer 194 195 Notes: for the standard PETSCVIEWERASCII the value is valid only on process 0 of the viewer 196 197 Level: intermediate 198 199 Fortran Note: 200 This routine is not supported in Fortran. 201 202 .seealso: `PetscViewerASCIIOpen()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerCreate()`, `PetscViewerASCIIPrintf()`, 203 `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerFlush()` 204 @*/ 205 PetscErrorCode PetscViewerASCIIGetPointer(PetscViewer viewer,FILE **fd) 206 { 207 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data; 208 209 PetscFunctionBegin; 210 *fd = vascii->fd; 211 PetscFunctionReturn(0); 212 } 213 214 PetscErrorCode PetscViewerFileGetMode_ASCII(PetscViewer viewer, PetscFileMode *mode) 215 { 216 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data; 217 218 PetscFunctionBegin; 219 *mode = vascii->mode; 220 PetscFunctionReturn(0); 221 } 222 223 PetscErrorCode PetscViewerFileSetMode_ASCII(PetscViewer viewer, PetscFileMode mode) 224 { 225 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data; 226 227 PetscFunctionBegin; 228 vascii->mode = mode; 229 PetscFunctionReturn(0); 230 } 231 232 /* 233 If petsc_history is on, then all Petsc*Printf() results are saved 234 if the appropriate (usually .petschistory) file. 235 */ 236 PETSC_INTERN FILE *petsc_history; 237 238 /*@ 239 PetscViewerASCIISetTab - Causes PetscViewer to tab in a number of times 240 241 Not Collective, but only first processor in set has any effect 242 243 Input Parameters: 244 + viewer - obtained with PetscViewerASCIIOpen() 245 - tabs - number of tabs 246 247 Level: developer 248 249 Fortran Note: 250 This routine is not supported in Fortran. 251 252 .seealso: `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIIGetTab()`, 253 `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIOpen()`, 254 `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`, `PetscViewerASCIIPushTab()` 255 @*/ 256 PetscErrorCode PetscViewerASCIISetTab(PetscViewer viewer,PetscInt tabs) 257 { 258 PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data; 259 PetscBool iascii; 260 261 PetscFunctionBegin; 262 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 263 PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii)); 264 if (iascii) ascii->tab = tabs; 265 PetscFunctionReturn(0); 266 } 267 268 /*@ 269 PetscViewerASCIIGetTab - Return the number of tabs used by PetscViewer. 270 271 Not Collective, meaningful on first processor only. 272 273 Input Parameters: 274 . viewer - obtained with PetscViewerASCIIOpen() 275 276 Output Parameters: 277 . tabs - number of tabs 278 279 Level: developer 280 281 Fortran Note: 282 This routine is not supported in Fortran. 283 284 .seealso: `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIISetTab()`, 285 `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIOpen()`, 286 `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`, `PetscViewerASCIIPushTab()` 287 @*/ 288 PetscErrorCode PetscViewerASCIIGetTab(PetscViewer viewer,PetscInt *tabs) 289 { 290 PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data; 291 PetscBool iascii; 292 293 PetscFunctionBegin; 294 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 295 PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii)); 296 if (iascii && tabs) *tabs = ascii->tab; 297 PetscFunctionReturn(0); 298 } 299 300 /*@ 301 PetscViewerASCIIAddTab - Add to the number of times an ASCII viewer tabs before printing 302 303 Not Collective, but only first processor in set has any effect 304 305 Input Parameters: 306 + viewer - obtained with PetscViewerASCIIOpen() 307 - tabs - number of tabs 308 309 Level: developer 310 311 Fortran Note: 312 This routine is not supported in Fortran. 313 314 .seealso: `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, 315 `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIOpen()`, 316 `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`, `PetscViewerASCIIPushTab()` 317 @*/ 318 PetscErrorCode PetscViewerASCIIAddTab(PetscViewer viewer,PetscInt tabs) 319 { 320 PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data; 321 PetscBool iascii; 322 323 PetscFunctionBegin; 324 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 325 PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii)); 326 if (iascii) ascii->tab += tabs; 327 PetscFunctionReturn(0); 328 } 329 330 /*@ 331 PetscViewerASCIISubtractTab - Subtracts from the number of times an ASCII viewer tabs before printing 332 333 Not Collective, but only first processor in set has any effect 334 335 Input Parameters: 336 + viewer - obtained with PetscViewerASCIIOpen() 337 - tabs - number of tabs 338 339 Level: developer 340 341 Fortran Note: 342 This routine is not supported in Fortran. 343 344 .seealso: `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, 345 `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIOpen()`, 346 `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`, `PetscViewerASCIIPushTab()` 347 @*/ 348 PetscErrorCode PetscViewerASCIISubtractTab(PetscViewer viewer,PetscInt tabs) 349 { 350 PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data; 351 PetscBool iascii; 352 353 PetscFunctionBegin; 354 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 355 PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii)); 356 if (iascii) ascii->tab -= tabs; 357 PetscFunctionReturn(0); 358 } 359 360 /*@C 361 PetscViewerASCIIPushSynchronized - Allows calls to PetscViewerASCIISynchronizedPrintf() for this viewer 362 363 Collective on PetscViewer 364 365 Input Parameters: 366 . viewer - obtained with PetscViewerASCIIOpen() 367 368 Level: intermediate 369 370 Notes: 371 See documentation of PetscViewerASCIISynchronizedPrintf() for more details how the synchronized output should be done properly. 372 373 .seealso: `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerFlush()`, `PetscViewerASCIIPopSynchronized()`, 374 `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIIOpen()`, 375 `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()` 376 @*/ 377 PetscErrorCode PetscViewerASCIIPushSynchronized(PetscViewer viewer) 378 { 379 PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data; 380 PetscBool iascii; 381 382 PetscFunctionBegin; 383 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 384 PetscCheck(!ascii->sviewer,PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()"); 385 PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii)); 386 if (iascii) ascii->allowsynchronized++; 387 PetscFunctionReturn(0); 388 } 389 390 /*@C 391 PetscViewerASCIIPopSynchronized - Undoes most recent PetscViewerASCIIPushSynchronized() for this viewer 392 393 Collective on PetscViewer 394 395 Input Parameters: 396 . viewer - obtained with PetscViewerASCIIOpen() 397 398 Level: intermediate 399 400 Notes: 401 See documentation of PetscViewerASCIISynchronizedPrintf() for more details how the synchronized output should be done properly. 402 403 .seealso: `PetscViewerASCIIPushSynchronized()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerFlush()`, 404 `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIIOpen()`, 405 `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()` 406 @*/ 407 PetscErrorCode PetscViewerASCIIPopSynchronized(PetscViewer viewer) 408 { 409 PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data; 410 PetscBool iascii; 411 412 PetscFunctionBegin; 413 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 414 PetscCheck(!ascii->sviewer,PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()"); 415 PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii)); 416 if (iascii) { 417 ascii->allowsynchronized--; 418 PetscCheck(ascii->allowsynchronized >= 0,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called more times than PetscViewerASCIIPushSynchronized()"); 419 } 420 PetscFunctionReturn(0); 421 } 422 423 /*@C 424 PetscViewerASCIIPushTab - Adds one more tab to the amount that PetscViewerASCIIPrintf() 425 lines are tabbed. 426 427 Not Collective, but only first processor in set has any effect 428 429 Input Parameters: 430 . viewer - obtained with PetscViewerASCIIOpen() 431 432 Level: developer 433 434 Fortran Note: 435 This routine is not supported in Fortran. 436 437 .seealso: `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, 438 `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIOpen()`, 439 `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()` 440 @*/ 441 PetscErrorCode PetscViewerASCIIPushTab(PetscViewer viewer) 442 { 443 PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data; 444 PetscBool iascii; 445 446 PetscFunctionBegin; 447 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 448 PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii)); 449 if (iascii) ascii->tab++; 450 PetscFunctionReturn(0); 451 } 452 453 /*@C 454 PetscViewerASCIIPopTab - Removes one tab from the amount that PetscViewerASCIIPrintf() 455 lines are tabbed. 456 457 Not Collective, but only first processor in set has any effect 458 459 Input Parameters: 460 . viewer - obtained with PetscViewerASCIIOpen() 461 462 Level: developer 463 464 Fortran Note: 465 This routine is not supported in Fortran. 466 467 .seealso: `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, 468 `PetscViewerASCIIPushTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIOpen()`, 469 `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()` 470 @*/ 471 PetscErrorCode PetscViewerASCIIPopTab(PetscViewer viewer) 472 { 473 PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data; 474 PetscBool iascii; 475 476 PetscFunctionBegin; 477 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 478 PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii)); 479 if (iascii) { 480 PetscCheck(ascii->tab > 0,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"More tabs popped than pushed"); 481 ascii->tab--; 482 } 483 PetscFunctionReturn(0); 484 } 485 486 /*@ 487 PetscViewerASCIIUseTabs - Turns on or off the use of tabs with the ASCII PetscViewer 488 489 Not Collective, but only first processor in set has any effect 490 491 Input Parameters: 492 + viewer - obtained with PetscViewerASCIIOpen() 493 - flg - PETSC_TRUE or PETSC_FALSE 494 495 Level: developer 496 497 Fortran Note: 498 This routine is not supported in Fortran. 499 500 .seealso: `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, 501 `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIPushTab()`, `PetscViewerASCIIOpen()`, 502 `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()` 503 @*/ 504 PetscErrorCode PetscViewerASCIIUseTabs(PetscViewer viewer,PetscBool flg) 505 { 506 PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data; 507 PetscBool iascii; 508 509 PetscFunctionBegin; 510 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 511 PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii)); 512 if (iascii) { 513 if (flg) ascii->tab = ascii->tab_store; 514 else { 515 ascii->tab_store = ascii->tab; 516 ascii->tab = 0; 517 } 518 } 519 PetscFunctionReturn(0); 520 } 521 522 /* ----------------------------------------------------------------------- */ 523 524 /*@C 525 PetscViewerASCIIPrintf - Prints to a file, only from the first 526 processor in the PetscViewer 527 528 Not Collective, but only first processor in set has any effect 529 530 Input Parameters: 531 + viewer - obtained with PetscViewerASCIIOpen() 532 - format - the usual printf() format string 533 534 Level: developer 535 536 Fortran Note: 537 The call sequence is PetscViewerASCIIPrintf(PetscViewer, character(*), int ierr) from Fortran. 538 That is, you can only pass a single character string from Fortran. 539 540 .seealso: `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIOpen()`, 541 `PetscViewerASCIIPushTab()`, `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`, 542 `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`, `PetscViewerASCIIPushSynchronized()` 543 @*/ 544 PetscErrorCode PetscViewerASCIIPrintf(PetscViewer viewer,const char format[],...) 545 { 546 PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data; 547 PetscMPIInt rank; 548 PetscInt tab,intab = ascii->tab; 549 FILE *fd = ascii->fd; 550 PetscBool iascii; 551 int err; 552 553 PetscFunctionBegin; 554 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 555 PetscCheck(!ascii->sviewer,PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()"); 556 PetscValidCharPointer(format,2); 557 PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii)); 558 PetscCheck(iascii,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer"); 559 PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank)); 560 if (rank) PetscFunctionReturn(0); 561 562 if (ascii->bviewer) { /* pass string up to parent viewer */ 563 char *string; 564 va_list Argp; 565 size_t fullLength; 566 567 PetscCall(PetscCalloc1(QUEUESTRINGSIZE, &string)); 568 va_start(Argp,format); 569 PetscCall(PetscVSNPrintf(string,QUEUESTRINGSIZE,format,&fullLength,Argp)); 570 va_end(Argp); 571 PetscCall(PetscViewerASCIISynchronizedPrintf(viewer,"%s",string)); 572 PetscCall(PetscFree(string)); 573 } else { /* write directly to file */ 574 va_list Argp; 575 /* flush my own messages that I may have queued up */ 576 PrintfQueue next = ascii->petsc_printfqueuebase,previous; 577 PetscInt i; 578 for (i=0; i<ascii->petsc_printfqueuelength; i++) { 579 PetscCall(PetscFPrintf(PETSC_COMM_SELF,fd,"%s",next->string)); 580 previous = next; 581 next = next->next; 582 PetscCall(PetscFree(previous->string)); 583 PetscCall(PetscFree(previous)); 584 } 585 ascii->petsc_printfqueue = NULL; 586 ascii->petsc_printfqueuelength = 0; 587 tab = intab; 588 while (tab--) { 589 PetscCall(PetscFPrintf(PETSC_COMM_SELF,fd," ")); 590 } 591 592 va_start(Argp,format); 593 PetscCall((*PetscVFPrintf)(fd,format,Argp)); 594 err = fflush(fd); 595 PetscCheck(!err,PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file"); 596 if (petsc_history) { 597 va_start(Argp,format); 598 tab = intab; 599 while (tab--) { 600 PetscCall(PetscFPrintf(PETSC_COMM_SELF,petsc_history," ")); 601 } 602 PetscCall((*PetscVFPrintf)(petsc_history,format,Argp)); 603 err = fflush(petsc_history); 604 PetscCheck(!err,PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file"); 605 } 606 va_end(Argp); 607 } 608 PetscFunctionReturn(0); 609 } 610 611 /*@C 612 PetscViewerFileSetName - Sets the name of the file the PetscViewer uses. 613 614 Collective on PetscViewer 615 616 Input Parameters: 617 + viewer - the PetscViewer; either ASCII or binary 618 - name - the name of the file it should use 619 620 Level: advanced 621 622 .seealso: `PetscViewerCreate()`, `PetscViewerSetType()`, `PetscViewerASCIIOpen()`, `PetscViewerBinaryOpen()`, `PetscViewerDestroy()`, 623 `PetscViewerASCIIGetPointer()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIISynchronizedPrintf()` 624 625 @*/ 626 PetscErrorCode PetscViewerFileSetName(PetscViewer viewer,const char name[]) 627 { 628 char filename[PETSC_MAX_PATH_LEN]; 629 630 PetscFunctionBegin; 631 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 632 PetscValidCharPointer(name,2); 633 PetscCall(PetscStrreplace(PetscObjectComm((PetscObject)viewer),name,filename,sizeof(filename))); 634 PetscTryMethod(viewer,"PetscViewerFileSetName_C",(PetscViewer,const char[]),(viewer,filename)); 635 PetscFunctionReturn(0); 636 } 637 638 /*@C 639 PetscViewerFileGetName - Gets the name of the file the PetscViewer uses. 640 641 Not Collective 642 643 Input Parameter: 644 . viewer - the PetscViewer; either ASCII or binary 645 646 Output Parameter: 647 . name - the name of the file it is using 648 649 Level: advanced 650 651 .seealso: `PetscViewerCreate()`, `PetscViewerSetType()`, `PetscViewerASCIIOpen()`, `PetscViewerBinaryOpen()`, `PetscViewerFileSetName()` 652 653 @*/ 654 PetscErrorCode PetscViewerFileGetName(PetscViewer viewer,const char **name) 655 { 656 PetscFunctionBegin; 657 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 658 PetscValidPointer(name,2); 659 PetscUseMethod(viewer,"PetscViewerFileGetName_C",(PetscViewer,const char**),(viewer,name)); 660 PetscFunctionReturn(0); 661 } 662 663 PetscErrorCode PetscViewerFileGetName_ASCII(PetscViewer viewer,const char **name) 664 { 665 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data; 666 667 PetscFunctionBegin; 668 *name = vascii->filename; 669 PetscFunctionReturn(0); 670 } 671 672 PetscErrorCode PetscViewerFileSetName_ASCII(PetscViewer viewer,const char name[]) 673 { 674 size_t len; 675 char fname[PETSC_MAX_PATH_LEN],*gz; 676 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data; 677 PetscBool isstderr,isstdout; 678 PetscMPIInt rank; 679 680 PetscFunctionBegin; 681 PetscCall(PetscViewerFileClose_ASCII(viewer)); 682 if (!name) PetscFunctionReturn(0); 683 PetscCall(PetscStrallocpy(name,&vascii->filename)); 684 685 /* Is this file to be compressed */ 686 vascii->storecompressed = PETSC_FALSE; 687 688 PetscCall(PetscStrstr(vascii->filename,".gz",&gz)); 689 if (gz) { 690 PetscCall(PetscStrlen(gz,&len)); 691 if (len == 3) { 692 PetscCheck(vascii->mode == FILE_MODE_WRITE,PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Cannot open ASCII PetscViewer file that is compressed; uncompress it manually first"); 693 *gz = 0; 694 vascii->storecompressed = PETSC_TRUE; 695 } 696 } 697 PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank)); 698 if (rank == 0) { 699 PetscCall(PetscStrcmp(name,"stderr",&isstderr)); 700 PetscCall(PetscStrcmp(name,"stdout",&isstdout)); 701 /* empty filename means stdout */ 702 if (name[0] == 0) isstdout = PETSC_TRUE; 703 if (isstderr) vascii->fd = PETSC_STDERR; 704 else if (isstdout) vascii->fd = PETSC_STDOUT; 705 else { 706 707 PetscCall(PetscFixFilename(name,fname)); 708 switch (vascii->mode) { 709 case FILE_MODE_READ: 710 vascii->fd = fopen(fname,"r"); 711 break; 712 case FILE_MODE_WRITE: 713 vascii->fd = fopen(fname,"w"); 714 break; 715 case FILE_MODE_APPEND: 716 vascii->fd = fopen(fname,"a"); 717 break; 718 case FILE_MODE_UPDATE: 719 vascii->fd = fopen(fname,"r+"); 720 if (!vascii->fd) vascii->fd = fopen(fname,"w+"); 721 break; 722 case FILE_MODE_APPEND_UPDATE: 723 /* I really want a file which is opened at the end for updating, 724 not a+, which opens at the beginning, but makes writes at the end. 725 */ 726 vascii->fd = fopen(fname,"r+"); 727 if (!vascii->fd) vascii->fd = fopen(fname,"w+"); 728 else { 729 PetscCall(fseek(vascii->fd, 0, SEEK_END)); 730 } 731 break; 732 default: 733 SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Unsupported file mode %s",PetscFileModes[vascii->mode]); 734 } 735 PetscCheck(vascii->fd,PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open PetscViewer file: %s",fname); 736 } 737 } 738 #if defined(PETSC_USE_LOG) 739 PetscLogObjectState((PetscObject)viewer,"File: %s",name); 740 #endif 741 PetscFunctionReturn(0); 742 } 743 744 PetscErrorCode PetscViewerGetSubViewer_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer) 745 { 746 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data,*ovascii; 747 748 PetscFunctionBegin; 749 PetscCall(PetscViewerASCIIPushSynchronized(viewer)); 750 PetscCheck(!vascii->sviewer,PETSC_COMM_SELF,PETSC_ERR_ORDER,"SubViewer already obtained from PetscViewer and not restored"); 751 /* 752 The following line is a bug; it does another PetscViewerASCIIPushSynchronized() on viewer, but if it is removed the code won't work 753 because it relies on this behavior in other places. In particular this line causes the synchronized flush to occur when the viewer is destroyed 754 (since the count never gets to zero) in some examples this displays information that otherwise would be lost 755 756 This code also means another call to PetscViewerASCIIPopSynchronized() must be made after the PetscViewerRestoreSubViewer(), see, for example, 757 PCView_GASM(). 758 */ 759 PetscCall(PetscViewerASCIIPushSynchronized(viewer)); 760 PetscCall(PetscViewerCreate(subcomm,outviewer)); 761 PetscCall(PetscViewerSetType(*outviewer,PETSCVIEWERASCII)); 762 PetscCall(PetscViewerASCIIPushSynchronized(*outviewer)); 763 ovascii = (PetscViewer_ASCII*)(*outviewer)->data; 764 ovascii->fd = vascii->fd; 765 ovascii->tab = vascii->tab; 766 ovascii->closefile = PETSC_FALSE; 767 768 vascii->sviewer = *outviewer; 769 (*outviewer)->format = viewer->format; 770 ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer; 771 (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_SubViewer; 772 PetscFunctionReturn(0); 773 } 774 775 PetscErrorCode PetscViewerRestoreSubViewer_ASCII(PetscViewer viewer,MPI_Comm comm,PetscViewer *outviewer) 776 { 777 PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data; 778 779 PetscFunctionBegin; 780 PetscCheck(ascii->sviewer,PETSC_COMM_SELF,PETSC_ERR_ORDER,"SubViewer never obtained from PetscViewer"); 781 PetscCheck(ascii->sviewer == *outviewer,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"This PetscViewer did not generate this SubViewer"); 782 783 PetscCall(PetscViewerASCIIPopSynchronized(*outviewer)); 784 ascii->sviewer = NULL; 785 (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII; 786 PetscCall(PetscViewerDestroy(outviewer)); 787 PetscCall(PetscViewerASCIIPopSynchronized(viewer)); 788 PetscFunctionReturn(0); 789 } 790 791 PetscErrorCode PetscViewerView_ASCII(PetscViewer v,PetscViewer viewer) 792 { 793 PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)v->data; 794 795 PetscFunctionBegin; 796 if (ascii->filename) { 797 PetscCall(PetscViewerASCIIPrintf(viewer,"Filename: %s\n",ascii->filename)); 798 } 799 PetscFunctionReturn(0); 800 } 801 802 /*MC 803 PETSCVIEWERASCII - A viewer that prints to stdout or an ASCII file 804 805 .seealso: `PETSC_VIEWER_STDOUT_()`, `PETSC_VIEWER_STDOUT_SELF`, `PETSC_VIEWER_STDOUT_WORLD`, `PetscViewerCreate()`, `PetscViewerASCIIOpen()`, 806 `PetscViewerMatlabOpen()`, `VecView()`, `DMView()`, `PetscViewerMatlabPutArray()`, `PETSCVIEWERBINARY`, `PETSCVIEWERMATLAB`, 807 `PetscViewerFileSetName()`, `PetscViewerFileSetMode()`, `PetscViewerFormat`, `PetscViewerType`, `PetscViewerSetType()` 808 809 Level: beginner 810 811 M*/ 812 PETSC_EXTERN PetscErrorCode PetscViewerCreate_ASCII(PetscViewer viewer) 813 { 814 PetscViewer_ASCII *vascii; 815 816 PetscFunctionBegin; 817 PetscCall(PetscNewLog(viewer,&vascii)); 818 viewer->data = (void*)vascii; 819 820 viewer->ops->destroy = PetscViewerDestroy_ASCII; 821 viewer->ops->flush = PetscViewerFlush_ASCII; 822 viewer->ops->getsubviewer = PetscViewerGetSubViewer_ASCII; 823 viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_ASCII; 824 viewer->ops->view = PetscViewerView_ASCII; 825 viewer->ops->read = PetscViewerASCIIRead; 826 827 /* defaults to stdout unless set with PetscViewerFileSetName() */ 828 vascii->fd = PETSC_STDOUT; 829 vascii->mode = FILE_MODE_WRITE; 830 vascii->bviewer = NULL; 831 vascii->subviewer = NULL; 832 vascii->sviewer = NULL; 833 vascii->tab = 0; 834 vascii->tab_store = 0; 835 vascii->filename = NULL; 836 vascii->closefile = PETSC_TRUE; 837 838 PetscCall(PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetName_C",PetscViewerFileSetName_ASCII)); 839 PetscCall(PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetName_C",PetscViewerFileGetName_ASCII)); 840 PetscCall(PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_ASCII)); 841 PetscCall(PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_ASCII)); 842 PetscFunctionReturn(0); 843 } 844 845 /*@C 846 PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from 847 several processors. Output of the first processor is followed by that of the 848 second, etc. 849 850 Not Collective, must call collective PetscViewerFlush() to get the results out 851 852 Input Parameters: 853 + viewer - the ASCII PetscViewer 854 - format - the usual printf() format string 855 856 Level: intermediate 857 858 Notes: 859 You must have previously called PetscViewerASCIIPushSynchronized() to allow this routine to be called. 860 Then you can do multiple independent calls to this routine. 861 The actual synchronized print is then done using PetscViewerFlush(). 862 PetscViewerASCIIPopSynchronized() should be then called if we are already done with the synchronized output 863 to conclude the "synchronized session". 864 So the typical calling sequence looks like 865 $ PetscViewerASCIIPushSynchronized(viewer); 866 $ PetscViewerASCIISynchronizedPrintf(viewer, ...); 867 $ PetscViewerASCIISynchronizedPrintf(viewer, ...); 868 $ ... 869 $ PetscViewerFlush(viewer); 870 $ PetscViewerASCIISynchronizedPrintf(viewer, ...); 871 $ PetscViewerASCIISynchronizedPrintf(viewer, ...); 872 $ ... 873 $ PetscViewerFlush(viewer); 874 $ PetscViewerASCIIPopSynchronized(viewer); 875 876 Fortran Note: 877 Can only print a single character* string 878 879 .seealso: `PetscViewerASCIIPushSynchronized()`, `PetscViewerFlush()`, `PetscViewerASCIIPopSynchronized()`, 880 `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIIOpen()`, 881 `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()` 882 @*/ 883 PetscErrorCode PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...) 884 { 885 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data; 886 PetscMPIInt rank; 887 PetscInt tab = vascii->tab; 888 MPI_Comm comm; 889 FILE *fp; 890 PetscBool iascii,hasbviewer = PETSC_FALSE; 891 int err; 892 893 PetscFunctionBegin; 894 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 895 PetscValidCharPointer(format,2); 896 PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii)); 897 PetscCheck(iascii,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer"); 898 PetscCheck(vascii->allowsynchronized,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"First call PetscViewerASCIIPushSynchronized() to allow this call"); 899 900 PetscCall(PetscObjectGetComm((PetscObject)viewer,&comm)); 901 PetscCallMPI(MPI_Comm_rank(comm,&rank)); 902 903 if (vascii->bviewer) { 904 hasbviewer = PETSC_TRUE; 905 if (rank == 0) { 906 vascii = (PetscViewer_ASCII*)vascii->bviewer->data; 907 PetscCall(PetscObjectGetComm((PetscObject)viewer,&comm)); 908 PetscCallMPI(MPI_Comm_rank(comm,&rank)); 909 } 910 } 911 912 fp = vascii->fd; 913 914 if (rank == 0 && !hasbviewer) { /* First processor prints immediately to fp */ 915 va_list Argp; 916 /* flush my own messages that I may have queued up */ 917 PrintfQueue next = vascii->petsc_printfqueuebase,previous; 918 PetscInt i; 919 for (i=0; i<vascii->petsc_printfqueuelength; i++) { 920 PetscCall(PetscFPrintf(comm,fp,"%s",next->string)); 921 previous = next; 922 next = next->next; 923 PetscCall(PetscFree(previous->string)); 924 PetscCall(PetscFree(previous)); 925 } 926 vascii->petsc_printfqueue = NULL; 927 vascii->petsc_printfqueuelength = 0; 928 929 while (tab--) { 930 PetscCall(PetscFPrintf(PETSC_COMM_SELF,fp," ")); 931 } 932 933 va_start(Argp,format); 934 PetscCall((*PetscVFPrintf)(fp,format,Argp)); 935 err = fflush(fp); 936 PetscCheck(!err,PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file"); 937 if (petsc_history) { 938 va_start(Argp,format); 939 PetscCall((*PetscVFPrintf)(petsc_history,format,Argp)); 940 err = fflush(petsc_history); 941 PetscCheck(!err,PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file"); 942 } 943 va_end(Argp); 944 } else { /* other processors add to queue */ 945 char *string; 946 va_list Argp; 947 size_t fullLength; 948 PrintfQueue next; 949 950 PetscCall(PetscNew(&next)); 951 if (vascii->petsc_printfqueue) { 952 vascii->petsc_printfqueue->next = next; 953 vascii->petsc_printfqueue = next; 954 } else { 955 vascii->petsc_printfqueuebase = vascii->petsc_printfqueue = next; 956 } 957 vascii->petsc_printfqueuelength++; 958 next->size = QUEUESTRINGSIZE; 959 PetscCall(PetscCalloc1(next->size, &next->string)); 960 string = next->string; 961 tab *= 2; 962 while (tab--) { 963 *string++ = ' '; 964 } 965 va_start(Argp,format); 966 PetscCall(PetscVSNPrintf(string,next->size-2*vascii->tab,format,&fullLength,Argp)); 967 va_end(Argp); 968 if (fullLength > (size_t) (next->size-2*vascii->tab)) { 969 PetscCall(PetscFree(next->string)); 970 next->size = fullLength + 2*vascii->tab; 971 PetscCall(PetscCalloc1(next->size, &next->string)); 972 string = next->string; 973 tab = 2*vascii->tab; 974 while (tab--) { 975 *string++ = ' '; 976 } 977 va_start(Argp,format); 978 PetscCall(PetscVSNPrintf(string,next->size-2*vascii->tab,format,NULL,Argp)); 979 va_end(Argp); 980 } 981 } 982 PetscFunctionReturn(0); 983 } 984 985 /*@C 986 PetscViewerASCIIRead - Reads from a ASCII file 987 988 Only process 0 in the PetscViewer may call this 989 990 Input Parameters: 991 + viewer - the ascii viewer 992 . data - location to write the data 993 . num - number of items of data to read 994 - datatype - type of data to read 995 996 Output Parameters: 997 . count - number of items of data actually read, or NULL 998 999 Level: beginner 1000 1001 .seealso: `PetscViewerASCIIOpen()`, `PetscViewerPushFormat()`, `PetscViewerDestroy()`, `PetscViewerCreate()`, `PetscViewerFileSetMode()`, `PetscViewerFileSetName()` 1002 `VecView()`, `MatView()`, `VecLoad()`, `MatLoad()`, `PetscViewerBinaryGetDescriptor()`, 1003 `PetscViewerBinaryGetInfoPointer()`, `PetscFileMode`, `PetscViewer`, `PetscViewerBinaryRead()` 1004 @*/ 1005 PetscErrorCode PetscViewerASCIIRead(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype) 1006 { 1007 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data; 1008 FILE *fd = vascii->fd; 1009 PetscInt i; 1010 int ret = 0; 1011 PetscMPIInt rank; 1012 1013 PetscFunctionBegin; 1014 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 1015 PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank)); 1016 PetscCheck(rank == 0,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Can only be called from process 0 in the PetscViewer"); 1017 for (i=0; i<num; i++) { 1018 if (dtype == PETSC_CHAR) ret = fscanf(fd, "%c", &(((char*)data)[i])); 1019 else if (dtype == PETSC_STRING) ret = fscanf(fd, "%s", &(((char*)data)[i])); 1020 else if (dtype == PETSC_INT) ret = fscanf(fd, "%" PetscInt_FMT, &(((PetscInt*)data)[i])); 1021 else if (dtype == PETSC_ENUM) ret = fscanf(fd, "%d", &(((int*)data)[i])); 1022 else if (dtype == PETSC_INT64) ret = fscanf(fd, "%" PetscInt64_FMT, &(((PetscInt64*)data)[i])); 1023 else if (dtype == PETSC_LONG) ret = fscanf(fd, "%ld", &(((long*)data)[i])); 1024 else if (dtype == PETSC_FLOAT) ret = fscanf(fd, "%f", &(((float*)data)[i])); 1025 else if (dtype == PETSC_DOUBLE) ret = fscanf(fd, "%lg", &(((double*)data)[i])); 1026 #if defined(PETSC_USE_REAL___FLOAT128) 1027 else if (dtype == PETSC___FLOAT128) { 1028 double tmp; 1029 ret = fscanf(fd, "%lg", &tmp); 1030 ((__float128*)data)[i] = tmp; 1031 } 1032 #endif 1033 else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Data type %d not supported", (int) dtype); 1034 PetscCheck(ret,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Conversion error for data type %d", (int) dtype); 1035 else if (ret < 0) break; /* Proxy for EOF, need to check for it in configure */ 1036 } 1037 if (count) *count = i; 1038 else PetscCheck(ret >= 0,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Insufficient data, read only %" PetscInt_FMT " < %" PetscInt_FMT " items", i, num); 1039 PetscFunctionReturn(0); 1040 } 1041