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