15c6c1daeSBarry Smith 2665c2dedSJed Brown #include <../src/sys/classes/viewer/impls/ascii/asciiimpl.h> /*I "petscviewer.h" I*/ 35c6c1daeSBarry Smith 45c6c1daeSBarry Smith #define QUEUESTRINGSIZE 8192 55c6c1daeSBarry Smith 6d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscViewerFileClose_ASCII(PetscViewer viewer) 7d71ae5a4SJacob Faibussowitsch { 85c6c1daeSBarry Smith PetscMPIInt rank; 95c6c1daeSBarry Smith PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data; 105c6c1daeSBarry Smith int err; 115c6c1daeSBarry Smith 125c6c1daeSBarry Smith PetscFunctionBegin; 1328b400f6SJacob Faibussowitsch PetscCheck(!vascii->sviewer, PetscObjectComm((PetscObject)viewer), PETSC_ERR_ARG_WRONGSTATE, "Cannot call with outstanding call to PetscViewerRestoreSubViewer()"); 149566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank)); 15dd400576SPatrick Sanan if (rank == 0 && vascii->fd != stderr && vascii->fd != PETSC_STDOUT) { 165c6c1daeSBarry Smith if (vascii->fd && vascii->closefile) { 175c6c1daeSBarry Smith err = fclose(vascii->fd); 1828b400f6SJacob Faibussowitsch PetscCheck(!err, PETSC_COMM_SELF, PETSC_ERR_SYS, "fclose() failed on file"); 195c6c1daeSBarry Smith } 205c6c1daeSBarry Smith if (vascii->storecompressed) { 215c6c1daeSBarry Smith char par[PETSC_MAX_PATH_LEN], buf[PETSC_MAX_PATH_LEN]; 225c6c1daeSBarry Smith FILE *fp; 239566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(par, "gzip ", sizeof(par))); 249566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(par, vascii->filename, sizeof(par))); 255c6c1daeSBarry Smith #if defined(PETSC_HAVE_POPEN) 269566063dSJacob Faibussowitsch PetscCall(PetscPOpen(PETSC_COMM_SELF, NULL, par, "r", &fp)); 27cc73adaaSBarry Smith PetscCheck(!fgets(buf, 1024, fp), PETSC_COMM_SELF, PETSC_ERR_LIB, "Error from compression command %s\n%s", par, buf); 289566063dSJacob Faibussowitsch PetscCall(PetscPClose(PETSC_COMM_SELF, fp)); 295c6c1daeSBarry Smith #else 305c6c1daeSBarry Smith SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP_SYS, "Cannot run external programs on this machine"); 315c6c1daeSBarry Smith #endif 325c6c1daeSBarry Smith } 335c6c1daeSBarry Smith } 349566063dSJacob Faibussowitsch PetscCall(PetscFree(vascii->filename)); 353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 365c6c1daeSBarry Smith } 375c6c1daeSBarry Smith 385c6c1daeSBarry Smith /* ----------------------------------------------------------------------*/ 39d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerDestroy_ASCII(PetscViewer viewer) 40d71ae5a4SJacob Faibussowitsch { 415c6c1daeSBarry Smith PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data; 425c6c1daeSBarry Smith PetscViewerLink *vlink; 435c6c1daeSBarry Smith PetscBool flg; 445c6c1daeSBarry Smith 455c6c1daeSBarry Smith PetscFunctionBegin; 4628b400f6SJacob Faibussowitsch PetscCheck(!vascii->sviewer, PetscObjectComm((PetscObject)viewer), PETSC_ERR_ARG_WRONGSTATE, "Cannot call with outstanding call to PetscViewerRestoreSubViewer()"); 479566063dSJacob Faibussowitsch PetscCall(PetscViewerFileClose_ASCII(viewer)); 489566063dSJacob Faibussowitsch PetscCall(PetscFree(vascii)); 495c6c1daeSBarry Smith 505c6c1daeSBarry Smith /* remove the viewer from the list in the MPI Communicator */ 5148a46eb9SPierre Jolivet if (Petsc_Viewer_keyval == MPI_KEYVAL_INVALID) PetscCallMPI(MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN, Petsc_DelViewer, &Petsc_Viewer_keyval, (void *)0)); 525c6c1daeSBarry Smith 539566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_get_attr(PetscObjectComm((PetscObject)viewer), Petsc_Viewer_keyval, (void **)&vlink, (PetscMPIInt *)&flg)); 545c6c1daeSBarry Smith if (flg) { 555c6c1daeSBarry Smith if (vlink && vlink->viewer == viewer) { 56e5840a18SBarry Smith if (vlink->next) { 579566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_set_attr(PetscObjectComm((PetscObject)viewer), Petsc_Viewer_keyval, vlink->next)); 58e5840a18SBarry Smith } else { 599566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_delete_attr(PetscObjectComm((PetscObject)viewer), Petsc_Viewer_keyval)); 60e5840a18SBarry Smith } 619566063dSJacob Faibussowitsch PetscCall(PetscFree(vlink)); 625c6c1daeSBarry Smith } else { 635c6c1daeSBarry Smith while (vlink && vlink->next) { 645c6c1daeSBarry Smith if (vlink->next->viewer == viewer) { 655c6c1daeSBarry Smith PetscViewerLink *nv = vlink->next; 665c6c1daeSBarry Smith vlink->next = vlink->next->next; 679566063dSJacob Faibussowitsch PetscCall(PetscFree(nv)); 685c6c1daeSBarry Smith } 695c6c1daeSBarry Smith vlink = vlink->next; 705c6c1daeSBarry Smith } 715c6c1daeSBarry Smith } 725c6c1daeSBarry Smith } 73aa139df6SJed Brown 74aa139df6SJed Brown if (Petsc_Viewer_Stdout_keyval != MPI_KEYVAL_INVALID) { 75aa139df6SJed Brown PetscViewer aviewer; 769566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_get_attr(PetscObjectComm((PetscObject)viewer), Petsc_Viewer_Stdout_keyval, (void **)&aviewer, (PetscMPIInt *)&flg)); 7748a46eb9SPierre Jolivet if (flg && aviewer == viewer) PetscCallMPI(MPI_Comm_delete_attr(PetscObjectComm((PetscObject)viewer), Petsc_Viewer_Stdout_keyval)); 78aa139df6SJed Brown } 79aa139df6SJed Brown if (Petsc_Viewer_Stderr_keyval != MPI_KEYVAL_INVALID) { 80aa139df6SJed Brown PetscViewer aviewer; 819566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_get_attr(PetscObjectComm((PetscObject)viewer), Petsc_Viewer_Stderr_keyval, (void **)&aviewer, (PetscMPIInt *)&flg)); 8248a46eb9SPierre Jolivet if (flg && aviewer == viewer) PetscCallMPI(MPI_Comm_delete_attr(PetscObjectComm((PetscObject)viewer), Petsc_Viewer_Stderr_keyval)); 83aa139df6SJed Brown } 842e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileSetName_C", NULL)); 852e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileGetName_C", NULL)); 862e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileGetMode_C", NULL)); 872e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileSetMode_C", NULL)); 883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 895c6c1daeSBarry Smith } 905c6c1daeSBarry Smith 91d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerDestroy_ASCII_SubViewer(PetscViewer viewer) 92d71ae5a4SJacob Faibussowitsch { 935c6c1daeSBarry Smith PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data; 945fd66863SKarl Rupp 955c6c1daeSBarry Smith PetscFunctionBegin; 969566063dSJacob Faibussowitsch PetscCall(PetscViewerRestoreSubViewer(vascii->bviewer, 0, &viewer)); 973ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 985c6c1daeSBarry Smith } 995c6c1daeSBarry Smith 100d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerFlush_ASCII(PetscViewer viewer) 101d71ae5a4SJacob Faibussowitsch { 1025c6c1daeSBarry Smith PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data; 103559f443fSBarry Smith MPI_Comm comm; 104559f443fSBarry Smith PetscMPIInt rank, size; 105559f443fSBarry Smith FILE *fd = vascii->fd; 1065c6c1daeSBarry Smith 1075c6c1daeSBarry Smith PetscFunctionBegin; 10828b400f6SJacob Faibussowitsch PetscCheck(!vascii->sviewer, PetscObjectComm((PetscObject)viewer), PETSC_ERR_ARG_WRONGSTATE, "Cannot call with outstanding call to PetscViewerRestoreSubViewer()"); 1099566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm)); 1109566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 1119566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &size)); 112559f443fSBarry Smith 113c69effb2SJacob Faibussowitsch if (!vascii->bviewer && rank == 0 && (vascii->mode != FILE_MODE_READ)) PetscCall(PetscFFlush(vascii->fd)); 1145c6c1daeSBarry Smith 1155c6c1daeSBarry Smith if (vascii->allowsynchronized) { 116559f443fSBarry Smith PetscMPIInt tag, i, j, n = 0, dummy = 0; 117559f443fSBarry Smith char *message; 118559f443fSBarry Smith MPI_Status status; 119559f443fSBarry Smith 1209566063dSJacob Faibussowitsch PetscCall(PetscCommDuplicate(comm, &comm, &tag)); 121559f443fSBarry Smith 122559f443fSBarry Smith /* First processor waits for messages from all other processors */ 123dd400576SPatrick Sanan if (rank == 0) { 124559f443fSBarry Smith /* flush my own messages that I may have queued up */ 125559f443fSBarry Smith PrintfQueue next = vascii->petsc_printfqueuebase, previous; 126559f443fSBarry Smith for (i = 0; i < vascii->petsc_printfqueuelength; i++) { 127559f443fSBarry Smith if (!vascii->bviewer) { 1289566063dSJacob Faibussowitsch PetscCall(PetscFPrintf(comm, fd, "%s", next->string)); 129559f443fSBarry Smith } else { 1309566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISynchronizedPrintf(vascii->bviewer, "%s", next->string)); 131559f443fSBarry Smith } 132559f443fSBarry Smith previous = next; 133559f443fSBarry Smith next = next->next; 1349566063dSJacob Faibussowitsch PetscCall(PetscFree(previous->string)); 1359566063dSJacob Faibussowitsch PetscCall(PetscFree(previous)); 136559f443fSBarry Smith } 13702c9f0b5SLisandro Dalcin vascii->petsc_printfqueue = NULL; 138559f443fSBarry Smith vascii->petsc_printfqueuelength = 0; 139559f443fSBarry Smith for (i = 1; i < size; i++) { 140559f443fSBarry Smith /* to prevent a flood of messages to process zero, request each message separately */ 1419566063dSJacob Faibussowitsch PetscCallMPI(MPI_Send(&dummy, 1, MPI_INT, i, tag, comm)); 1429566063dSJacob Faibussowitsch PetscCallMPI(MPI_Recv(&n, 1, MPI_INT, i, tag, comm, &status)); 143559f443fSBarry Smith for (j = 0; j < n; j++) { 144559f443fSBarry Smith PetscMPIInt size = 0; 145559f443fSBarry Smith 1469566063dSJacob Faibussowitsch PetscCallMPI(MPI_Recv(&size, 1, MPI_INT, i, tag, comm, &status)); 1479566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size, &message)); 1489566063dSJacob Faibussowitsch PetscCallMPI(MPI_Recv(message, size, MPI_CHAR, i, tag, comm, &status)); 149559f443fSBarry Smith if (!vascii->bviewer) { 1509566063dSJacob Faibussowitsch PetscCall(PetscFPrintf(comm, fd, "%s", message)); 151559f443fSBarry Smith } else { 1529566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISynchronizedPrintf(vascii->bviewer, "%s", message)); 153559f443fSBarry Smith } 1549566063dSJacob Faibussowitsch PetscCall(PetscFree(message)); 155559f443fSBarry Smith } 156559f443fSBarry Smith } 157559f443fSBarry Smith } else { /* other processors send queue to processor 0 */ 158559f443fSBarry Smith PrintfQueue next = vascii->petsc_printfqueuebase, previous; 159559f443fSBarry Smith 1609566063dSJacob Faibussowitsch PetscCallMPI(MPI_Recv(&dummy, 1, MPI_INT, 0, tag, comm, &status)); 1619566063dSJacob Faibussowitsch PetscCallMPI(MPI_Send(&vascii->petsc_printfqueuelength, 1, MPI_INT, 0, tag, comm)); 162559f443fSBarry Smith for (i = 0; i < vascii->petsc_printfqueuelength; i++) { 1639566063dSJacob Faibussowitsch PetscCallMPI(MPI_Send(&next->size, 1, MPI_INT, 0, tag, comm)); 1649566063dSJacob Faibussowitsch PetscCallMPI(MPI_Send(next->string, next->size, MPI_CHAR, 0, tag, comm)); 165559f443fSBarry Smith previous = next; 166559f443fSBarry Smith next = next->next; 1679566063dSJacob Faibussowitsch PetscCall(PetscFree(previous->string)); 1689566063dSJacob Faibussowitsch PetscCall(PetscFree(previous)); 169559f443fSBarry Smith } 17002c9f0b5SLisandro Dalcin vascii->petsc_printfqueue = NULL; 171559f443fSBarry Smith vascii->petsc_printfqueuelength = 0; 172559f443fSBarry Smith } 1739566063dSJacob Faibussowitsch PetscCall(PetscCommDestroy(&comm)); 1745c6c1daeSBarry Smith } 1753ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1765c6c1daeSBarry Smith } 1775c6c1daeSBarry Smith 1785c6c1daeSBarry Smith /*@C 179811af0c4SBarry Smith PetscViewerASCIIGetPointer - Extracts the file pointer from an ASCII `PetscViewer`. 1805c6c1daeSBarry Smith 18135cb6cd3SPierre Jolivet Not Collective, depending on the viewer the value may be meaningless except for process 0 of the viewer; No Fortran Support 1825c6c1daeSBarry Smith 183f8859db6SBarry Smith Input Parameter: 1843f423023SBarry Smith . viewer - `PetscViewer` context, obtained from `PetscViewerASCIIOpen()` 185f8859db6SBarry Smith 186f8859db6SBarry Smith Output Parameter: 187f8859db6SBarry Smith . fd - file pointer 188f8859db6SBarry Smith 1895c6c1daeSBarry Smith Level: intermediate 1905c6c1daeSBarry Smith 191811af0c4SBarry Smith Note: 192c410d8ccSBarry Smith For the standard `PETSCVIEWERASCII` the value is valid only on MPI rank 0 of the viewer 193811af0c4SBarry Smith 1943f423023SBarry Smith .seealso: [](sec_viewers), `PETSCVIEWERASCII`, `PetscViewerASCIIOpen()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, 1953f423023SBarry Smith `PetscViewerCreate()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerFlush()` 1965c6c1daeSBarry Smith @*/ 197d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIIGetPointer(PetscViewer viewer, FILE **fd) 198d71ae5a4SJacob Faibussowitsch { 1995c6c1daeSBarry Smith PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data; 2005c6c1daeSBarry Smith 2015c6c1daeSBarry Smith PetscFunctionBegin; 2025c6c1daeSBarry Smith *fd = vascii->fd; 2033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2045c6c1daeSBarry Smith } 2055c6c1daeSBarry Smith 206d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerFileGetMode_ASCII(PetscViewer viewer, PetscFileMode *mode) 207d71ae5a4SJacob Faibussowitsch { 2085c6c1daeSBarry Smith PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data; 2095c6c1daeSBarry Smith 2105c6c1daeSBarry Smith PetscFunctionBegin; 2115c6c1daeSBarry Smith *mode = vascii->mode; 2123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2135c6c1daeSBarry Smith } 2145c6c1daeSBarry Smith 215d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerFileSetMode_ASCII(PetscViewer viewer, PetscFileMode mode) 216d71ae5a4SJacob Faibussowitsch { 2175c6c1daeSBarry Smith PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data; 2185c6c1daeSBarry Smith 2195c6c1daeSBarry Smith PetscFunctionBegin; 2205c6c1daeSBarry Smith vascii->mode = mode; 2213ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2225c6c1daeSBarry Smith } 2235c6c1daeSBarry Smith 2245c6c1daeSBarry Smith /* 2255c6c1daeSBarry Smith If petsc_history is on, then all Petsc*Printf() results are saved 2265c6c1daeSBarry Smith if the appropriate (usually .petschistory) file. 2275c6c1daeSBarry Smith */ 22895c0884eSLisandro Dalcin PETSC_INTERN FILE *petsc_history; 2295c6c1daeSBarry Smith 2305c6c1daeSBarry Smith /*@ 2313f423023SBarry Smith PetscViewerASCIISetTab - Causes `PetscViewer` to tab in a number of times before printing 2325c6c1daeSBarry Smith 233cf53795eSBarry Smith Not Collective, but only first processor in set has any effect; No Fortran Support 2345c6c1daeSBarry Smith 2355c6c1daeSBarry Smith Input Parameters: 236811af0c4SBarry Smith + viewer - obtained with `PetscViewerASCIIOpen()` 2375c6c1daeSBarry Smith - tabs - number of tabs 2385c6c1daeSBarry Smith 2395c6c1daeSBarry Smith Level: developer 2405c6c1daeSBarry Smith 2413f423023SBarry Smith Note: 2423f423023SBarry Smith `PetscViewerASCIIPushTab()` and `PetscViewerASCIIPopTab()` are the preferred usage 2433f423023SBarry Smith 2443f423023SBarry Smith .seealso: [](sec_viewers), `PETSCVIEWERASCII`, `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, 2453f423023SBarry Smith `PetscViewerASCIIGetTab()`, 246db781477SPatrick Sanan `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIOpen()`, 2473f423023SBarry Smith `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`, 2483f423023SBarry Smith `PetscViewerASCIIPushTab()` 2495c6c1daeSBarry Smith @*/ 250d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIISetTab(PetscViewer viewer, PetscInt tabs) 251d71ae5a4SJacob Faibussowitsch { 2525c6c1daeSBarry Smith PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data; 2535c6c1daeSBarry Smith PetscBool iascii; 2545c6c1daeSBarry Smith 2555c6c1daeSBarry Smith PetscFunctionBegin; 2565c6c1daeSBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 2579566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 258a297a907SKarl Rupp if (iascii) ascii->tab = tabs; 2593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2605c6c1daeSBarry Smith } 2615c6c1daeSBarry Smith 2625c6c1daeSBarry Smith /*@ 263811af0c4SBarry Smith PetscViewerASCIIGetTab - Return the number of tabs used by `PetscViewer`. 2645c6c1daeSBarry Smith 265cf53795eSBarry Smith Not Collective, meaningful on first processor only; No Fortran Support 2665c6c1daeSBarry Smith 26720f4b53cSBarry Smith Input Parameter: 268811af0c4SBarry Smith . viewer - obtained with `PetscViewerASCIIOpen()` 269a2b725a8SWilliam Gropp 27020f4b53cSBarry Smith Output Parameter: 2715c6c1daeSBarry Smith . tabs - number of tabs 2725c6c1daeSBarry Smith 2735c6c1daeSBarry Smith Level: developer 2745c6c1daeSBarry Smith 2753f423023SBarry Smith .seealso: [](sec_viewers), `PETSCVIEWERASCII`, `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, 2763f423023SBarry Smith `PetscViewerASCIISetTab()`, 277db781477SPatrick Sanan `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIOpen()`, 278db781477SPatrick Sanan `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`, `PetscViewerASCIIPushTab()` 2795c6c1daeSBarry Smith @*/ 280d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIIGetTab(PetscViewer viewer, PetscInt *tabs) 281d71ae5a4SJacob Faibussowitsch { 2825c6c1daeSBarry Smith PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data; 2835c6c1daeSBarry Smith PetscBool iascii; 2845c6c1daeSBarry Smith 2855c6c1daeSBarry Smith PetscFunctionBegin; 2865c6c1daeSBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 2879566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 288a297a907SKarl Rupp if (iascii && tabs) *tabs = ascii->tab; 2893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2905c6c1daeSBarry Smith } 2915c6c1daeSBarry Smith 2925c6c1daeSBarry Smith /*@ 2933f423023SBarry Smith PetscViewerASCIIAddTab - Add to the number of times a `PETSCVIEWERASCII` viewer tabs before printing 2945c6c1daeSBarry Smith 295cf53795eSBarry Smith Not Collective, but only first processor in set has any effect; No Fortran Support 2965c6c1daeSBarry Smith 2975c6c1daeSBarry Smith Input Parameters: 298811af0c4SBarry Smith + viewer - obtained with `PetscViewerASCIIOpen()` 2995c6c1daeSBarry Smith - tabs - number of tabs 3005c6c1daeSBarry Smith 3015c6c1daeSBarry Smith Level: developer 3025c6c1daeSBarry Smith 3033f423023SBarry Smith Note: 3043f423023SBarry Smith `PetscViewerASCIIPushTab()` and `PetscViewerASCIIPopTab()` are the preferred usage 3053f423023SBarry Smith 3063f423023SBarry Smith .seealso: [](sec_viewers), `PETSCVIEWERASCII`, `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, 307db781477SPatrick Sanan `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIOpen()`, 308db781477SPatrick Sanan `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`, `PetscViewerASCIIPushTab()` 3095c6c1daeSBarry Smith @*/ 310d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIIAddTab(PetscViewer viewer, PetscInt tabs) 311d71ae5a4SJacob Faibussowitsch { 3125c6c1daeSBarry Smith PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data; 3135c6c1daeSBarry Smith PetscBool iascii; 3145c6c1daeSBarry Smith 3155c6c1daeSBarry Smith PetscFunctionBegin; 3165c6c1daeSBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 3179566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 318a297a907SKarl Rupp if (iascii) ascii->tab += tabs; 3193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3205c6c1daeSBarry Smith } 3215c6c1daeSBarry Smith 3225c6c1daeSBarry Smith /*@ 3233f423023SBarry Smith PetscViewerASCIISubtractTab - Subtracts from the number of times a `PETSCVIEWERASCII` viewer tabs before printing 3245c6c1daeSBarry Smith 325cf53795eSBarry Smith Not Collective, but only first processor in set has any effect; No Fortran Support 3265c6c1daeSBarry Smith 3275c6c1daeSBarry Smith Input Parameters: 328811af0c4SBarry Smith + viewer - obtained with `PetscViewerASCIIOpen()` 3295c6c1daeSBarry Smith - tabs - number of tabs 3305c6c1daeSBarry Smith 3315c6c1daeSBarry Smith Level: developer 3325c6c1daeSBarry Smith 3333f423023SBarry Smith Note: 3343f423023SBarry Smith `PetscViewerASCIIPushTab()` and `PetscViewerASCIIPopTab()` are the preferred usage 3353f423023SBarry Smith 3363f423023SBarry Smith .seealso: [](sec_viewers), `PETSCVIEWERASCII`, `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, 337db781477SPatrick Sanan `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIOpen()`, 3383f423023SBarry Smith `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`, 3393f423023SBarry Smith `PetscViewerASCIIPushTab()` 3405c6c1daeSBarry Smith @*/ 341d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIISubtractTab(PetscViewer viewer, PetscInt tabs) 342d71ae5a4SJacob Faibussowitsch { 3435c6c1daeSBarry Smith PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data; 3445c6c1daeSBarry Smith PetscBool iascii; 3455c6c1daeSBarry Smith 3465c6c1daeSBarry Smith PetscFunctionBegin; 3475c6c1daeSBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 3489566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 349a297a907SKarl Rupp if (iascii) ascii->tab -= tabs; 3503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3515c6c1daeSBarry Smith } 3525c6c1daeSBarry Smith 3535c6c1daeSBarry Smith /*@C 354811af0c4SBarry Smith PetscViewerASCIIPushSynchronized - Allows calls to `PetscViewerASCIISynchronizedPrintf()` for this viewer 3555c6c1daeSBarry Smith 356c3339decSBarry Smith Collective 3575c6c1daeSBarry Smith 35820f4b53cSBarry Smith Input Parameter: 359811af0c4SBarry Smith . viewer - obtained with `PetscViewerASCIIOpen()` 3605c6c1daeSBarry Smith 3615c6c1daeSBarry Smith Level: intermediate 3625c6c1daeSBarry Smith 363811af0c4SBarry Smith Note: 364811af0c4SBarry Smith See documentation of `PetscViewerASCIISynchronizedPrintf()` for more details how the synchronized output should be done properly. 3655c6c1daeSBarry Smith 366d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerFlush()`, `PetscViewerASCIIPopSynchronized()`, 367db781477SPatrick Sanan `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIIOpen()`, 368db781477SPatrick Sanan `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()` 3695c6c1daeSBarry Smith @*/ 370d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIIPushSynchronized(PetscViewer viewer) 371d71ae5a4SJacob Faibussowitsch { 3725c6c1daeSBarry Smith PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data; 3735c6c1daeSBarry Smith PetscBool iascii; 3745c6c1daeSBarry Smith 3755c6c1daeSBarry Smith PetscFunctionBegin; 3765c6c1daeSBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 37728b400f6SJacob Faibussowitsch PetscCheck(!ascii->sviewer, PetscObjectComm((PetscObject)viewer), PETSC_ERR_ARG_WRONGSTATE, "Cannot call with outstanding call to PetscViewerRestoreSubViewer()"); 3789566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 3791575c14dSBarry Smith if (iascii) ascii->allowsynchronized++; 3803ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3811575c14dSBarry Smith } 3821575c14dSBarry Smith 3831575c14dSBarry Smith /*@C 384811af0c4SBarry Smith PetscViewerASCIIPopSynchronized - Undoes most recent `PetscViewerASCIIPushSynchronized()` for this viewer 3851575c14dSBarry Smith 386c3339decSBarry Smith Collective 3871575c14dSBarry Smith 38820f4b53cSBarry Smith Input Parameter: 389811af0c4SBarry Smith . viewer - obtained with `PetscViewerASCIIOpen()` 3901575c14dSBarry Smith 3911575c14dSBarry Smith Level: intermediate 3921575c14dSBarry Smith 393811af0c4SBarry Smith Note: 394811af0c4SBarry Smith See documentation of `PetscViewerASCIISynchronizedPrintf()` for more details how the synchronized output should be done properly. 3951575c14dSBarry Smith 396d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscViewerASCIIPushSynchronized()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerFlush()`, 397db781477SPatrick Sanan `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIIOpen()`, 398db781477SPatrick Sanan `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()` 3991575c14dSBarry Smith @*/ 400d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIIPopSynchronized(PetscViewer viewer) 401d71ae5a4SJacob Faibussowitsch { 4021575c14dSBarry Smith PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data; 4031575c14dSBarry Smith PetscBool iascii; 4041575c14dSBarry Smith 4051575c14dSBarry Smith PetscFunctionBegin; 4061575c14dSBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 40728b400f6SJacob Faibussowitsch PetscCheck(!ascii->sviewer, PetscObjectComm((PetscObject)viewer), PETSC_ERR_ARG_WRONGSTATE, "Cannot call with outstanding call to PetscViewerRestoreSubViewer()"); 4089566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 4091575c14dSBarry Smith if (iascii) { 4101575c14dSBarry Smith ascii->allowsynchronized--; 41108401ef6SPierre Jolivet PetscCheck(ascii->allowsynchronized >= 0, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Called more times than PetscViewerASCIIPushSynchronized()"); 4121575c14dSBarry Smith } 4133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4145c6c1daeSBarry Smith } 4155c6c1daeSBarry Smith 4161c297824SMatthew G. Knepley /*@C 417811af0c4SBarry Smith PetscViewerASCIIPushTab - Adds one more tab to the amount that `PetscViewerASCIIPrintf()` 4185c6c1daeSBarry Smith lines are tabbed. 4195c6c1daeSBarry Smith 420c410d8ccSBarry Smith Not Collective, but only first MPI rank in the viewer has any effect; No Fortran Support 4215c6c1daeSBarry Smith 42220f4b53cSBarry Smith Input Parameter: 423811af0c4SBarry Smith . viewer - obtained with `PetscViewerASCIIOpen()` 4245c6c1daeSBarry Smith 4255c6c1daeSBarry Smith Level: developer 4265c6c1daeSBarry Smith 427d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, 428db781477SPatrick Sanan `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIOpen()`, 429db781477SPatrick Sanan `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()` 4305c6c1daeSBarry Smith @*/ 431d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIIPushTab(PetscViewer viewer) 432d71ae5a4SJacob Faibussowitsch { 4335c6c1daeSBarry Smith PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data; 4345c6c1daeSBarry Smith PetscBool iascii; 4355c6c1daeSBarry Smith 4365c6c1daeSBarry Smith PetscFunctionBegin; 4375c6c1daeSBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 4389566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 439a297a907SKarl Rupp if (iascii) ascii->tab++; 4403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4415c6c1daeSBarry Smith } 4425c6c1daeSBarry Smith 4431c297824SMatthew G. Knepley /*@C 4443f423023SBarry Smith PetscViewerASCIIPopTab - Removes one tab from the amount that `PetscViewerASCIIPrintf()` lines are tabbed that was provided by 4453f423023SBarry Smith `PetscViewerASCIIPushTab()` 4465c6c1daeSBarry Smith 447c410d8ccSBarry Smith Not Collective, but only first MPI rank in the viewer has any effect; No Fortran Support 4485c6c1daeSBarry Smith 44920f4b53cSBarry Smith Input Parameter: 450811af0c4SBarry Smith . viewer - obtained with `PetscViewerASCIIOpen()` 4515c6c1daeSBarry Smith 4525c6c1daeSBarry Smith Level: developer 4535c6c1daeSBarry Smith 454d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, 455db781477SPatrick Sanan `PetscViewerASCIIPushTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIOpen()`, 456db781477SPatrick Sanan `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()` 4575c6c1daeSBarry Smith @*/ 458d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIIPopTab(PetscViewer viewer) 459d71ae5a4SJacob Faibussowitsch { 4605c6c1daeSBarry Smith PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data; 4615c6c1daeSBarry Smith PetscBool iascii; 4625c6c1daeSBarry Smith 4635c6c1daeSBarry Smith PetscFunctionBegin; 4645c6c1daeSBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 4659566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 4665c6c1daeSBarry Smith if (iascii) { 46708401ef6SPierre Jolivet PetscCheck(ascii->tab > 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "More tabs popped than pushed"); 4685c6c1daeSBarry Smith ascii->tab--; 4695c6c1daeSBarry Smith } 4703ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4715c6c1daeSBarry Smith } 4725c6c1daeSBarry Smith 4735c6c1daeSBarry Smith /*@ 474c410d8ccSBarry Smith PetscViewerASCIIUseTabs - Turns on or off the use of tabs with the `PETSCVIEWERASCII` `PetscViewer` 4755c6c1daeSBarry Smith 476c410d8ccSBarry Smith Not Collective, but only first MPI rank in the viewer has any effect; No Fortran Support 4775c6c1daeSBarry Smith 4785c6c1daeSBarry Smith Input Parameters: 479811af0c4SBarry Smith + viewer - obtained with `PetscViewerASCIIOpen()` 480811af0c4SBarry Smith - flg - `PETSC_TRUE` or `PETSC_FALSE` 4815c6c1daeSBarry Smith 4825c6c1daeSBarry Smith Level: developer 4835c6c1daeSBarry Smith 484d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, 485db781477SPatrick Sanan `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIPushTab()`, `PetscViewerASCIIOpen()`, 486db781477SPatrick Sanan `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()` 4875c6c1daeSBarry Smith @*/ 488d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIIUseTabs(PetscViewer viewer, PetscBool flg) 489d71ae5a4SJacob Faibussowitsch { 4905c6c1daeSBarry Smith PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data; 4915c6c1daeSBarry Smith PetscBool iascii; 4925c6c1daeSBarry Smith 4935c6c1daeSBarry Smith PetscFunctionBegin; 4945c6c1daeSBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 4959566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 4965c6c1daeSBarry Smith if (iascii) { 497a297a907SKarl Rupp if (flg) ascii->tab = ascii->tab_store; 498a297a907SKarl Rupp else { 4995c6c1daeSBarry Smith ascii->tab_store = ascii->tab; 5005c6c1daeSBarry Smith ascii->tab = 0; 5015c6c1daeSBarry Smith } 5025c6c1daeSBarry Smith } 5033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5045c6c1daeSBarry Smith } 5055c6c1daeSBarry Smith 506e4096674SBarry Smith #if defined(PETSC_USE_FORTRAN_BINDINGS) 507e4096674SBarry Smith 508e4096674SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS) 509e4096674SBarry Smith #define petscviewerasciiopenwithfileunit_ PETSCVIEWERASCIIOPENWITHFILEUNIT 510e4096674SBarry Smith #define petscviewerasciisetfilefileunit_ PETSCVIEWERASCIISETFILEUNIT 511e4096674SBarry Smith #define petscfortranprinttounit_ PETSCFORTRANPRINTTOUNIT 512e4096674SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE) 513e4096674SBarry Smith #define petscviewerasciiopenwithfileunit_ petscviewerasciiopenwithfileunit 514e4096674SBarry Smith #define petscviewerasciisetfileunit_ petscviewerasciisetfileunit 515e4096674SBarry Smith #define petscfortranprinttounit_ petscfortranprinttounit 516e4096674SBarry Smith #endif 517e4096674SBarry Smith 518e4096674SBarry Smith #if defined(__cplusplus) 519e4096674SBarry Smith extern "C" void petscfortranprinttounit_(PetscInt *, const char *, PetscErrorCode *, PETSC_FORTRAN_CHARLEN_T); 520e4096674SBarry Smith #else 521e4096674SBarry Smith extern void petscfortranprinttounit_(PetscInt *, const char *, PetscErrorCode *, PETSC_FORTRAN_CHARLEN_T); 522e4096674SBarry Smith #endif 523e4096674SBarry Smith 524e4096674SBarry Smith #define PETSCDEFAULTBUFFERSIZE 8 * 1024 525e4096674SBarry Smith 526e4096674SBarry Smith /*@M 527e4096674SBarry Smith PetscViewerASCIISetFileUnit - sets the `PETSCASCIIVIEWER` to write to a Fortan IO unit 528e4096674SBarry Smith 529*aec76313SJacob Faibussowitsch Fortran Notes: 530e4096674SBarry Smith void PetscViewerASCIISetFileUnit(PetscViewer lab, PetscInt unit, PetscErrorCode ierr) 531e4096674SBarry Smith 532e4096674SBarry Smith Input Parameters: 533e4096674SBarry Smith + lab - the viewer 534e4096674SBarry Smith - unit - the unit number 535e4096674SBarry Smith 536e4096674SBarry Smith Output Parameter: 537e4096674SBarry Smith . ierr - the error code 538e4096674SBarry Smith 539e4096674SBarry Smith Note: 540e4096674SBarry Smith `PetscViewerDestroy()` does not close the unit for this `PetscViewer` 541e4096674SBarry Smith 542*aec76313SJacob Faibussowitsch Fortran Notes: 543e4096674SBarry Smith Only for Fortran, use `PetscViewerASCIISetFILE()` for C 544e4096674SBarry Smith 545e4096674SBarry Smith .seealso: `PetscViewerASCIISetFILE()`, `PETSCVIEWERASCII`, `PetscViewerASCIIOpenWithFileUnit()` 546e4096674SBarry Smith @*/ 547e4096674SBarry Smith PETSC_EXTERN void petscviewerasciisetfileunit_(PetscViewer *lab, PetscInt *unit, PetscErrorCode *ierr) 548e4096674SBarry Smith { 549e4096674SBarry Smith PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)(*lab)->data; 550e4096674SBarry Smith 551e4096674SBarry Smith if (vascii->mode == FILE_MODE_READ) { 552e4096674SBarry Smith *ierr = PETSC_ERR_ARG_WRONGSTATE; 553e4096674SBarry Smith return; 554e4096674SBarry Smith } 555e4096674SBarry Smith vascii->fileunit = *unit; 556e4096674SBarry Smith } 557e4096674SBarry Smith 558e4096674SBarry Smith /*@M 559e4096674SBarry Smith PetscViewerASCIIOpenWithFileUnit - opens a `PETSCASCIIVIEWER` to write to a Fortan IO unit 560e4096674SBarry Smith 561*aec76313SJacob Faibussowitsch Fortran Notes: 562e4096674SBarry Smith void PetscViewerASCIIOpenWithFileUnit(MPI_Comm comm, PetscInt unit, PetscViewer viewer, PetscErrorCode ierr) 563e4096674SBarry Smith 564e4096674SBarry Smith Input Parameters: 565e4096674SBarry Smith + comm - the `MPI_Comm` to share the viewer 566e4096674SBarry Smith - unit - the unit number 567e4096674SBarry Smith 568e4096674SBarry Smith Output Parameters: 569e4096674SBarry Smith + lab - the viewer 570e4096674SBarry Smith - ierr - the error code 571e4096674SBarry Smith 572e4096674SBarry Smith Note: 573e4096674SBarry Smith `PetscViewerDestroy()` does not close the unit for this `PetscViewer` 574e4096674SBarry Smith 575*aec76313SJacob Faibussowitsch Fortran Notes: 576e4096674SBarry Smith Only for Fortran, use `PetscViewerASCIIOpenWithFILE()` for C 577e4096674SBarry Smith 578e4096674SBarry Smith .seealso: `PetscViewerASCIISetFileUnit()`, `PetscViewerASCIISetFILE()`, `PETSCVIEWERASCII`, `PetscViewerASCIIOpenWithFILE()` 579e4096674SBarry Smith @*/ 580e4096674SBarry Smith PETSC_EXTERN void petscviewerasciiopenwithfileunit_(MPI_Comm *comm, PetscInt *unit, PetscViewer *lab, PetscErrorCode *ierr) 581e4096674SBarry Smith { 582e4096674SBarry Smith *ierr = PetscViewerCreate(MPI_Comm_f2c(*(MPI_Fint *)&*comm), lab); 583e4096674SBarry Smith if (*ierr) return; 584e4096674SBarry Smith *ierr = PetscViewerSetType(*lab, PETSCVIEWERASCII); 585e4096674SBarry Smith if (*ierr) return; 586e4096674SBarry Smith *ierr = PetscViewerFileSetMode(*lab, FILE_MODE_WRITE); 587e4096674SBarry Smith if (*ierr) return; 588e4096674SBarry Smith petscviewerasciisetfileunit_(lab, unit, ierr); 589e4096674SBarry Smith } 590e4096674SBarry Smith 591e4096674SBarry Smith static PetscErrorCode PetscVFPrintfFortran(PetscInt unit, const char format[], va_list Argp) 592e4096674SBarry Smith { 593e4096674SBarry Smith PetscErrorCode ierr; 594e4096674SBarry Smith char str[PETSCDEFAULTBUFFERSIZE]; 595e4096674SBarry Smith size_t len; 596e4096674SBarry Smith 597e4096674SBarry Smith PetscFunctionBegin; 598e4096674SBarry Smith PetscCall(PetscVSNPrintf(str, sizeof(str), format, NULL, Argp)); 599e4096674SBarry Smith PetscCall(PetscStrlen(str, &len)); 600e4096674SBarry Smith petscfortranprinttounit_(&unit, str, &ierr, (int)len); 601e4096674SBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 602e4096674SBarry Smith } 603e4096674SBarry Smith 604e4096674SBarry Smith static PetscErrorCode PetscFPrintfFortran(PetscInt unit, const char str[]) 605e4096674SBarry Smith { 606e4096674SBarry Smith PetscErrorCode ierr; 607e4096674SBarry Smith size_t len; 608e4096674SBarry Smith 609e4096674SBarry Smith PetscFunctionBegin; 610e4096674SBarry Smith PetscCall(PetscStrlen(str, &len)); 611e4096674SBarry Smith petscfortranprinttounit_(&unit, str, &ierr, (int)len); 612e4096674SBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 613e4096674SBarry Smith } 614e4096674SBarry Smith 615e4096674SBarry Smith #else 616e4096674SBarry Smith 617e4096674SBarry Smith /* these will never be used; but are needed to link with */ 618e4096674SBarry Smith static PetscErrorCode PetscVFPrintfFortran(PetscInt unit, const char format[], va_list Argp) 619e4096674SBarry Smith { 620e4096674SBarry Smith PetscFunctionBegin; 621e4096674SBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 622e4096674SBarry Smith } 623e4096674SBarry Smith 624e4096674SBarry Smith static PetscErrorCode PetscFPrintfFortran(PetscInt unit, const char str[]) 625e4096674SBarry Smith { 626e4096674SBarry Smith PetscFunctionBegin; 627e4096674SBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 628e4096674SBarry Smith } 629e4096674SBarry Smith #endif 630e4096674SBarry Smith 6315c6c1daeSBarry Smith /*@C 6325c6c1daeSBarry Smith PetscViewerASCIIPrintf - Prints to a file, only from the first 6333f423023SBarry Smith processor in the `PetscViewer` of type `PETSCVIEWERASCII` 6345c6c1daeSBarry Smith 635c410d8ccSBarry Smith Not Collective, but only the first MPI rank in the viewer has any effect 6365c6c1daeSBarry Smith 6375c6c1daeSBarry Smith Input Parameters: 638811af0c4SBarry Smith + viewer - obtained with `PetscViewerASCIIOpen()` 6395c6c1daeSBarry Smith - format - the usual printf() format string 6405c6c1daeSBarry Smith 6415c6c1daeSBarry Smith Level: developer 6425c6c1daeSBarry Smith 643*aec76313SJacob Faibussowitsch Fortran Notes: 644c410d8ccSBarry Smith The call sequence is `PetscViewerASCIIPrintf`(`PetscViewer`, character(*), int ierr) from Fortran. 6455c6c1daeSBarry Smith That is, you can only pass a single character string from Fortran. 6465c6c1daeSBarry Smith 647d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIOpen()`, 648db781477SPatrick Sanan `PetscViewerASCIIPushTab()`, `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`, 649db781477SPatrick Sanan `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`, `PetscViewerASCIIPushSynchronized()` 6505c6c1daeSBarry Smith @*/ 651d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIIPrintf(PetscViewer viewer, const char format[], ...) 652d71ae5a4SJacob Faibussowitsch { 6535c6c1daeSBarry Smith PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data; 6545c6c1daeSBarry Smith PetscMPIInt rank; 655dd2fa690SBarry Smith PetscInt tab, intab = ascii->tab; 6565c6c1daeSBarry Smith FILE *fd = ascii->fd; 6573f08860eSBarry Smith PetscBool iascii; 6585c6c1daeSBarry Smith 6595c6c1daeSBarry Smith PetscFunctionBegin; 6605c6c1daeSBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 66128b400f6SJacob Faibussowitsch PetscCheck(!ascii->sviewer, PetscObjectComm((PetscObject)viewer), PETSC_ERR_ARG_WRONGSTATE, "Cannot call with outstanding call to PetscViewerRestoreSubViewer()"); 6625c6c1daeSBarry Smith PetscValidCharPointer(format, 2); 6639566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 66428b400f6SJacob Faibussowitsch PetscCheck(iascii, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Not ASCII PetscViewer"); 6659566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank)); 6663ba16761SJacob Faibussowitsch if (rank) PetscFunctionReturn(PETSC_SUCCESS); 6673f08860eSBarry Smith 6683f08860eSBarry Smith if (ascii->bviewer) { /* pass string up to parent viewer */ 6693f08860eSBarry Smith char *string; 6703f08860eSBarry Smith va_list Argp; 6713f08860eSBarry Smith size_t fullLength; 6723f08860eSBarry Smith 6739566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(QUEUESTRINGSIZE, &string)); 6743f08860eSBarry Smith va_start(Argp, format); 6759566063dSJacob Faibussowitsch PetscCall(PetscVSNPrintf(string, QUEUESTRINGSIZE, format, &fullLength, Argp)); 6763f08860eSBarry Smith va_end(Argp); 6779566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "%s", string)); 6789566063dSJacob Faibussowitsch PetscCall(PetscFree(string)); 6793f08860eSBarry Smith } else { /* write directly to file */ 6805c6c1daeSBarry Smith va_list Argp; 681559f443fSBarry Smith /* flush my own messages that I may have queued up */ 682559f443fSBarry Smith PrintfQueue next = ascii->petsc_printfqueuebase, previous; 683559f443fSBarry Smith PetscInt i; 684559f443fSBarry Smith for (i = 0; i < ascii->petsc_printfqueuelength; i++) { 685e4096674SBarry Smith if (!ascii->fileunit) PetscCall(PetscFPrintf(PETSC_COMM_SELF, fd, "%s", next->string)); 686e4096674SBarry Smith else PetscCall(PetscFPrintfFortran(ascii->fileunit, next->string)); 687559f443fSBarry Smith previous = next; 688559f443fSBarry Smith next = next->next; 6899566063dSJacob Faibussowitsch PetscCall(PetscFree(previous->string)); 6909566063dSJacob Faibussowitsch PetscCall(PetscFree(previous)); 691559f443fSBarry Smith } 69202c9f0b5SLisandro Dalcin ascii->petsc_printfqueue = NULL; 693559f443fSBarry Smith ascii->petsc_printfqueuelength = 0; 694dd2fa690SBarry Smith tab = intab; 695e4096674SBarry Smith while (tab--) { 696e4096674SBarry Smith if (!ascii->fileunit) PetscCall(PetscFPrintf(PETSC_COMM_SELF, fd, " ")); 697e4096674SBarry Smith else PetscCall(PetscFPrintfFortran(ascii->fileunit, " ")); 698e4096674SBarry Smith } 6995c6c1daeSBarry Smith 7005c6c1daeSBarry Smith va_start(Argp, format); 701e4096674SBarry Smith if (!ascii->fileunit) PetscCall((*PetscVFPrintf)(fd, format, Argp)); 702e4096674SBarry Smith else PetscCall(PetscVFPrintfFortran(ascii->fileunit, format, Argp)); 703eae3dc7dSJacob Faibussowitsch va_end(Argp); 704c69effb2SJacob Faibussowitsch PetscCall(PetscFFlush(fd)); 7055c6c1daeSBarry Smith } 7063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7075c6c1daeSBarry Smith } 7085c6c1daeSBarry Smith 7095c6c1daeSBarry Smith /*@C 710c410d8ccSBarry Smith PetscViewerFileSetName - Sets the name of the file the `PetscViewer` should use. 7115c6c1daeSBarry Smith 712c3339decSBarry Smith Collective 7135c6c1daeSBarry Smith 7145c6c1daeSBarry Smith Input Parameters: 7153f423023SBarry Smith + viewer - the `PetscViewer`; for example, of type `PETSCVIEWERASCII` or `PETSCVIEWERBINARY` 7165c6c1daeSBarry Smith - name - the name of the file it should use 7175c6c1daeSBarry Smith 7185c6c1daeSBarry Smith Level: advanced 7195c6c1daeSBarry Smith 720c410d8ccSBarry Smith Note: 721c410d8ccSBarry Smith This will have no effect on viewers that are not related to files 722c410d8ccSBarry Smith 723d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscViewerCreate()`, `PetscViewerSetType()`, `PetscViewerASCIIOpen()`, `PetscViewerBinaryOpen()`, `PetscViewerDestroy()`, 724db781477SPatrick Sanan `PetscViewerASCIIGetPointer()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIISynchronizedPrintf()` 7255c6c1daeSBarry Smith @*/ 726d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerFileSetName(PetscViewer viewer, const char name[]) 727d71ae5a4SJacob Faibussowitsch { 728cc843e7aSLisandro Dalcin char filename[PETSC_MAX_PATH_LEN]; 7295c6c1daeSBarry Smith 7305c6c1daeSBarry Smith PetscFunctionBegin; 7315c6c1daeSBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 7325c6c1daeSBarry Smith PetscValidCharPointer(name, 2); 7339566063dSJacob Faibussowitsch PetscCall(PetscStrreplace(PetscObjectComm((PetscObject)viewer), name, filename, sizeof(filename))); 734cac4c232SBarry Smith PetscTryMethod(viewer, "PetscViewerFileSetName_C", (PetscViewer, const char[]), (viewer, filename)); 7353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7365c6c1daeSBarry Smith } 7375c6c1daeSBarry Smith 7385c6c1daeSBarry Smith /*@C 739c410d8ccSBarry Smith PetscViewerFileGetName - Gets the name of the file the `PetscViewer` is using 7405c6c1daeSBarry Smith 7415c6c1daeSBarry Smith Not Collective 7425c6c1daeSBarry Smith 7435c6c1daeSBarry Smith Input Parameter: 7443f423023SBarry Smith . viewer - the `PetscViewer` 7455c6c1daeSBarry Smith 7465c6c1daeSBarry Smith Output Parameter: 7475c6c1daeSBarry Smith . name - the name of the file it is using 7485c6c1daeSBarry Smith 7495c6c1daeSBarry Smith Level: advanced 7505c6c1daeSBarry Smith 751c410d8ccSBarry Smith Note: 752c410d8ccSBarry Smith This will have no effect on viewers that are not related to files 753c410d8ccSBarry Smith 754d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscViewerCreate()`, `PetscViewerSetType()`, `PetscViewerASCIIOpen()`, `PetscViewerBinaryOpen()`, `PetscViewerFileSetName()` 7555c6c1daeSBarry Smith @*/ 756d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerFileGetName(PetscViewer viewer, const char **name) 757d71ae5a4SJacob Faibussowitsch { 7585c6c1daeSBarry Smith PetscFunctionBegin; 7595c6c1daeSBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 7606e05b1faSLisandro Dalcin PetscValidPointer(name, 2); 761cac4c232SBarry Smith PetscUseMethod(viewer, "PetscViewerFileGetName_C", (PetscViewer, const char **), (viewer, name)); 7623ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7635c6c1daeSBarry Smith } 7645c6c1daeSBarry Smith 765d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerFileGetName_ASCII(PetscViewer viewer, const char **name) 766d71ae5a4SJacob Faibussowitsch { 7675c6c1daeSBarry Smith PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data; 7685c6c1daeSBarry Smith 7695c6c1daeSBarry Smith PetscFunctionBegin; 7705c6c1daeSBarry Smith *name = vascii->filename; 7713ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7725c6c1daeSBarry Smith } 7735c6c1daeSBarry Smith 774bf31d2d3SBarry Smith #include <errno.h> 775d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerFileSetName_ASCII(PetscViewer viewer, const char name[]) 776d71ae5a4SJacob Faibussowitsch { 7775c6c1daeSBarry Smith size_t len; 778bbcf679cSJacob Faibussowitsch char fname[PETSC_MAX_PATH_LEN], *gz = NULL; 7795c6c1daeSBarry Smith PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data; 7805c6c1daeSBarry Smith PetscBool isstderr, isstdout; 7815c6c1daeSBarry Smith PetscMPIInt rank; 7825c6c1daeSBarry Smith 7835c6c1daeSBarry Smith PetscFunctionBegin; 7849566063dSJacob Faibussowitsch PetscCall(PetscViewerFileClose_ASCII(viewer)); 7853ba16761SJacob Faibussowitsch if (!name) PetscFunctionReturn(PETSC_SUCCESS); 7869566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(name, &vascii->filename)); 7875c6c1daeSBarry Smith 7885c6c1daeSBarry Smith /* Is this file to be compressed */ 7895c6c1daeSBarry Smith vascii->storecompressed = PETSC_FALSE; 790a297a907SKarl Rupp 7919566063dSJacob Faibussowitsch PetscCall(PetscStrstr(vascii->filename, ".gz", &gz)); 7925c6c1daeSBarry Smith if (gz) { 7939566063dSJacob Faibussowitsch PetscCall(PetscStrlen(gz, &len)); 7945c6c1daeSBarry Smith if (len == 3) { 79508401ef6SPierre Jolivet PetscCheck(vascii->mode == FILE_MODE_WRITE, PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Cannot open ASCII PetscViewer file that is compressed; uncompress it manually first"); 7965c6c1daeSBarry Smith *gz = 0; 7975c6c1daeSBarry Smith vascii->storecompressed = PETSC_TRUE; 7985c6c1daeSBarry Smith } 7995c6c1daeSBarry Smith } 8009566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank)); 801dd400576SPatrick Sanan if (rank == 0) { 8029566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, "stderr", &isstderr)); 8039566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, "stdout", &isstdout)); 8045c6c1daeSBarry Smith /* empty filename means stdout */ 8055c6c1daeSBarry Smith if (name[0] == 0) isstdout = PETSC_TRUE; 8065c6c1daeSBarry Smith if (isstderr) vascii->fd = PETSC_STDERR; 8075c6c1daeSBarry Smith else if (isstdout) vascii->fd = PETSC_STDOUT; 8085c6c1daeSBarry Smith else { 8099566063dSJacob Faibussowitsch PetscCall(PetscFixFilename(name, fname)); 8105c6c1daeSBarry Smith switch (vascii->mode) { 811d71ae5a4SJacob Faibussowitsch case FILE_MODE_READ: 812d71ae5a4SJacob Faibussowitsch vascii->fd = fopen(fname, "r"); 813d71ae5a4SJacob Faibussowitsch break; 814d71ae5a4SJacob Faibussowitsch case FILE_MODE_WRITE: 815d71ae5a4SJacob Faibussowitsch vascii->fd = fopen(fname, "w"); 816d71ae5a4SJacob Faibussowitsch break; 817d71ae5a4SJacob Faibussowitsch case FILE_MODE_APPEND: 818d71ae5a4SJacob Faibussowitsch vascii->fd = fopen(fname, "a"); 819d71ae5a4SJacob Faibussowitsch break; 8205c6c1daeSBarry Smith case FILE_MODE_UPDATE: 8215c6c1daeSBarry Smith vascii->fd = fopen(fname, "r+"); 822a297a907SKarl Rupp if (!vascii->fd) vascii->fd = fopen(fname, "w+"); 8235c6c1daeSBarry Smith break; 8245c6c1daeSBarry Smith case FILE_MODE_APPEND_UPDATE: 8255c6c1daeSBarry Smith /* I really want a file which is opened at the end for updating, 8265c6c1daeSBarry Smith not a+, which opens at the beginning, but makes writes at the end. 8275c6c1daeSBarry Smith */ 8285c6c1daeSBarry Smith vascii->fd = fopen(fname, "r+"); 829a297a907SKarl Rupp if (!vascii->fd) vascii->fd = fopen(fname, "w+"); 8303ba16761SJacob Faibussowitsch else { 8313ba16761SJacob Faibussowitsch int ret = fseek(vascii->fd, 0, SEEK_END); 8323ba16761SJacob Faibussowitsch PetscCheck(!ret, PETSC_COMM_SELF, PETSC_ERR_LIB, "fseek() failed with error code %d", ret); 8333ba16761SJacob Faibussowitsch } 8345c6c1daeSBarry Smith break; 835d71ae5a4SJacob Faibussowitsch default: 836d71ae5a4SJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Unsupported file mode %s", PetscFileModes[vascii->mode]); 8375c6c1daeSBarry Smith } 838bf31d2d3SBarry Smith PetscCheck(vascii->fd, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Cannot open PetscViewer file: %s due to \"%s\"", fname, strerror(errno)); 8395c6c1daeSBarry Smith } 8405c6c1daeSBarry Smith } 8415c6c1daeSBarry Smith #if defined(PETSC_USE_LOG) 8423ba16761SJacob Faibussowitsch PetscCall(PetscLogObjectState((PetscObject)viewer, "File: %s", name)); 8435c6c1daeSBarry Smith #endif 8443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8455c6c1daeSBarry Smith } 8465c6c1daeSBarry Smith 847d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerGetSubViewer_ASCII(PetscViewer viewer, MPI_Comm subcomm, PetscViewer *outviewer) 848d71ae5a4SJacob Faibussowitsch { 8495c6c1daeSBarry Smith PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data, *ovascii; 8505c6c1daeSBarry Smith 8515c6c1daeSBarry Smith PetscFunctionBegin; 8529566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushSynchronized(viewer)); 85328b400f6SJacob Faibussowitsch PetscCheck(!vascii->sviewer, PETSC_COMM_SELF, PETSC_ERR_ORDER, "SubViewer already obtained from PetscViewer and not restored"); 854e5afcf28SBarry Smith /* 8559530cbd7SBarry Smith The following line is a bug; it does another PetscViewerASCIIPushSynchronized() on viewer, but if it is removed the code won't work 8569530cbd7SBarry Smith because it relies on this behavior in other places. In particular this line causes the synchronized flush to occur when the viewer is destroyed 8579530cbd7SBarry Smith (since the count never gets to zero) in some examples this displays information that otherwise would be lost 8589530cbd7SBarry Smith 8599530cbd7SBarry Smith This code also means another call to PetscViewerASCIIPopSynchronized() must be made after the PetscViewerRestoreSubViewer(), see, for example, 8609530cbd7SBarry Smith PCView_GASM(). 861e5afcf28SBarry Smith */ 8629566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushSynchronized(viewer)); 8639566063dSJacob Faibussowitsch PetscCall(PetscViewerCreate(subcomm, outviewer)); 8649566063dSJacob Faibussowitsch PetscCall(PetscViewerSetType(*outviewer, PETSCVIEWERASCII)); 8659566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushSynchronized(*outviewer)); 8665c6c1daeSBarry Smith ovascii = (PetscViewer_ASCII *)(*outviewer)->data; 8675c6c1daeSBarry Smith ovascii->fd = vascii->fd; 8685c6c1daeSBarry Smith ovascii->tab = vascii->tab; 869ba5a0b41SBarry Smith ovascii->closefile = PETSC_FALSE; 8705c6c1daeSBarry Smith 8715c6c1daeSBarry Smith vascii->sviewer = *outviewer; 8725c6c1daeSBarry Smith (*outviewer)->format = viewer->format; 8735c6c1daeSBarry Smith ((PetscViewer_ASCII *)((*outviewer)->data))->bviewer = viewer; 8743f08860eSBarry Smith (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_SubViewer; 8753ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8765c6c1daeSBarry Smith } 8775c6c1daeSBarry Smith 878d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerRestoreSubViewer_ASCII(PetscViewer viewer, MPI_Comm comm, PetscViewer *outviewer) 879d71ae5a4SJacob Faibussowitsch { 8805c6c1daeSBarry Smith PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data; 8815c6c1daeSBarry Smith 8825c6c1daeSBarry Smith PetscFunctionBegin; 88328b400f6SJacob Faibussowitsch PetscCheck(ascii->sviewer, PETSC_COMM_SELF, PETSC_ERR_ORDER, "SubViewer never obtained from PetscViewer"); 88408401ef6SPierre Jolivet PetscCheck(ascii->sviewer == *outviewer, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "This PetscViewer did not generate this SubViewer"); 8855c6c1daeSBarry Smith 8869566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopSynchronized(*outviewer)); 887e5afcf28SBarry Smith ascii->sviewer = NULL; 8885c6c1daeSBarry Smith (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII; 8899566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(outviewer)); 8909566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopSynchronized(viewer)); 8913ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8925c6c1daeSBarry Smith } 8935c6c1daeSBarry Smith 894d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerView_ASCII(PetscViewer v, PetscViewer viewer) 895d71ae5a4SJacob Faibussowitsch { 8962bf49c77SBarry Smith PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)v->data; 8972bf49c77SBarry Smith 8982bf49c77SBarry Smith PetscFunctionBegin; 89948a46eb9SPierre Jolivet if (ascii->filename) PetscCall(PetscViewerASCIIPrintf(viewer, "Filename: %s\n", ascii->filename)); 9003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9012bf49c77SBarry Smith } 9022bf49c77SBarry Smith 9038556b5ebSBarry Smith /*MC 9048556b5ebSBarry Smith PETSCVIEWERASCII - A viewer that prints to stdout or an ASCII file 9058556b5ebSBarry Smith 906811af0c4SBarry Smith Level: beginner 907811af0c4SBarry Smith 908d1f92df0SBarry Smith .seealso: [](sec_viewers), `PETSC_VIEWER_STDOUT_()`, `PETSC_VIEWER_STDOUT_SELF`, `PETSC_VIEWER_STDOUT_WORLD`, `PetscViewerCreate()`, `PetscViewerASCIIOpen()`, 909db781477SPatrick Sanan `PetscViewerMatlabOpen()`, `VecView()`, `DMView()`, `PetscViewerMatlabPutArray()`, `PETSCVIEWERBINARY`, `PETSCVIEWERMATLAB`, 910db781477SPatrick Sanan `PetscViewerFileSetName()`, `PetscViewerFileSetMode()`, `PetscViewerFormat`, `PetscViewerType`, `PetscViewerSetType()` 9118556b5ebSBarry Smith M*/ 912d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscViewerCreate_ASCII(PetscViewer viewer) 913d71ae5a4SJacob Faibussowitsch { 9145c6c1daeSBarry Smith PetscViewer_ASCII *vascii; 9155c6c1daeSBarry Smith 9165c6c1daeSBarry Smith PetscFunctionBegin; 9174dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&vascii)); 9185c6c1daeSBarry Smith viewer->data = (void *)vascii; 9195c6c1daeSBarry Smith 9205c6c1daeSBarry Smith viewer->ops->destroy = PetscViewerDestroy_ASCII; 9215c6c1daeSBarry Smith viewer->ops->flush = PetscViewerFlush_ASCII; 922559f443fSBarry Smith viewer->ops->getsubviewer = PetscViewerGetSubViewer_ASCII; 923559f443fSBarry Smith viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_ASCII; 9242bf49c77SBarry Smith viewer->ops->view = PetscViewerView_ASCII; 9251d641e7bSMichael Lange viewer->ops->read = PetscViewerASCIIRead; 9265c6c1daeSBarry Smith 9275c6c1daeSBarry Smith /* defaults to stdout unless set with PetscViewerFileSetName() */ 9285c6c1daeSBarry Smith vascii->fd = PETSC_STDOUT; 9295c6c1daeSBarry Smith vascii->mode = FILE_MODE_WRITE; 93002c9f0b5SLisandro Dalcin vascii->bviewer = NULL; 93102c9f0b5SLisandro Dalcin vascii->subviewer = NULL; 93202c9f0b5SLisandro Dalcin vascii->sviewer = NULL; 9335c6c1daeSBarry Smith vascii->tab = 0; 9345c6c1daeSBarry Smith vascii->tab_store = 0; 93502c9f0b5SLisandro Dalcin vascii->filename = NULL; 9365c6c1daeSBarry Smith vascii->closefile = PETSC_TRUE; 9375c6c1daeSBarry Smith 9389566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileSetName_C", PetscViewerFileSetName_ASCII)); 9399566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileGetName_C", PetscViewerFileGetName_ASCII)); 9409566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileGetMode_C", PetscViewerFileGetMode_ASCII)); 9419566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileSetMode_C", PetscViewerFileSetMode_ASCII)); 9423ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9435c6c1daeSBarry Smith } 9445c6c1daeSBarry Smith 9455c6c1daeSBarry Smith /*@C 946c410d8ccSBarry Smith PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified `PETSCVIEWERASCII` file from 9475c6c1daeSBarry Smith several processors. Output of the first processor is followed by that of the 9485c6c1daeSBarry Smith second, etc. 9495c6c1daeSBarry Smith 950c410d8ccSBarry Smith Not Collective, must call collective `PetscViewerFlush()` to get the results flushed 9515c6c1daeSBarry Smith 9525c6c1daeSBarry Smith Input Parameters: 953811af0c4SBarry Smith + viewer - the `PETSCVIEWERASCII` `PetscViewer` 9545c6c1daeSBarry Smith - format - the usual printf() format string 9555c6c1daeSBarry Smith 9565c6c1daeSBarry Smith Level: intermediate 9575c6c1daeSBarry Smith 95895452b02SPatrick Sanan Notes: 959811af0c4SBarry Smith You must have previously called `PetscViewerASCIIPushSynchronized()` to allow this routine to be called. 960e6abc3ddSVáclav Hapla Then you can do multiple independent calls to this routine. 961811af0c4SBarry Smith 962811af0c4SBarry Smith The actual synchronized print is then done using `PetscViewerFlush()`. 963811af0c4SBarry Smith `PetscViewerASCIIPopSynchronized()` should be then called if we are already done with the synchronized output 964e6abc3ddSVáclav Hapla to conclude the "synchronized session". 965811af0c4SBarry Smith 966e6abc3ddSVáclav Hapla So the typical calling sequence looks like 967811af0c4SBarry Smith .vb 968811af0c4SBarry Smith PetscViewerASCIIPushSynchronized(viewer); 969811af0c4SBarry Smith PetscViewerASCIISynchronizedPrintf(viewer, ...); 970811af0c4SBarry Smith PetscViewerASCIISynchronizedPrintf(viewer, ...); 971811af0c4SBarry Smith ... 972811af0c4SBarry Smith PetscViewerFlush(viewer); 973811af0c4SBarry Smith PetscViewerASCIISynchronizedPrintf(viewer, ...); 974811af0c4SBarry Smith PetscViewerASCIISynchronizedPrintf(viewer, ...); 975811af0c4SBarry Smith ... 976811af0c4SBarry Smith PetscViewerFlush(viewer); 977811af0c4SBarry Smith PetscViewerASCIIPopSynchronized(viewer); 978811af0c4SBarry Smith .ve 9795c6c1daeSBarry Smith 980*aec76313SJacob Faibussowitsch Fortran Notes: 9815c6c1daeSBarry Smith Can only print a single character* string 9825c6c1daeSBarry Smith 983d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscViewerASCIIPushSynchronized()`, `PetscViewerFlush()`, `PetscViewerASCIIPopSynchronized()`, 984db781477SPatrick Sanan `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIIOpen()`, 985db781477SPatrick Sanan `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()` 9865c6c1daeSBarry Smith @*/ 987d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIISynchronizedPrintf(PetscViewer viewer, const char format[], ...) 988d71ae5a4SJacob Faibussowitsch { 9895c6c1daeSBarry Smith PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data; 9903f08860eSBarry Smith PetscMPIInt rank; 9915c6c1daeSBarry Smith PetscInt tab = vascii->tab; 9925c6c1daeSBarry Smith MPI_Comm comm; 9935c6c1daeSBarry Smith FILE *fp; 994559f443fSBarry Smith PetscBool iascii, hasbviewer = PETSC_FALSE; 9955c6c1daeSBarry Smith 9965c6c1daeSBarry Smith PetscFunctionBegin; 9975c6c1daeSBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 9985c6c1daeSBarry Smith PetscValidCharPointer(format, 2); 9999566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 100028b400f6SJacob Faibussowitsch PetscCheck(iascii, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Not ASCII PetscViewer"); 100128b400f6SJacob Faibussowitsch PetscCheck(vascii->allowsynchronized, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "First call PetscViewerASCIIPushSynchronized() to allow this call"); 10025c6c1daeSBarry Smith 10039566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm)); 10049566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 10055c6c1daeSBarry Smith 1006559f443fSBarry Smith if (vascii->bviewer) { 1007559f443fSBarry Smith hasbviewer = PETSC_TRUE; 1008dd400576SPatrick Sanan if (rank == 0) { 1009559f443fSBarry Smith vascii = (PetscViewer_ASCII *)vascii->bviewer->data; 10109566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm)); 10119566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 1012559f443fSBarry Smith } 1013559f443fSBarry Smith } 10143f08860eSBarry Smith 1015559f443fSBarry Smith fp = vascii->fd; 1016559f443fSBarry Smith 1017dd400576SPatrick Sanan if (rank == 0 && !hasbviewer) { /* First processor prints immediately to fp */ 10185c6c1daeSBarry Smith va_list Argp; 1019559f443fSBarry Smith /* flush my own messages that I may have queued up */ 1020559f443fSBarry Smith PrintfQueue next = vascii->petsc_printfqueuebase, previous; 1021559f443fSBarry Smith PetscInt i; 1022559f443fSBarry Smith for (i = 0; i < vascii->petsc_printfqueuelength; i++) { 10239566063dSJacob Faibussowitsch PetscCall(PetscFPrintf(comm, fp, "%s", next->string)); 1024559f443fSBarry Smith previous = next; 1025559f443fSBarry Smith next = next->next; 10269566063dSJacob Faibussowitsch PetscCall(PetscFree(previous->string)); 10279566063dSJacob Faibussowitsch PetscCall(PetscFree(previous)); 1028559f443fSBarry Smith } 102902c9f0b5SLisandro Dalcin vascii->petsc_printfqueue = NULL; 1030559f443fSBarry Smith vascii->petsc_printfqueuelength = 0; 10315c6c1daeSBarry Smith 103248a46eb9SPierre Jolivet while (tab--) PetscCall(PetscFPrintf(PETSC_COMM_SELF, fp, " ")); 10335c6c1daeSBarry Smith 10345c6c1daeSBarry Smith va_start(Argp, format); 10359566063dSJacob Faibussowitsch PetscCall((*PetscVFPrintf)(fp, format, Argp)); 1036eae3dc7dSJacob Faibussowitsch va_end(Argp); 1037c69effb2SJacob Faibussowitsch PetscCall(PetscFFlush(fp)); 10385c6c1daeSBarry Smith if (petsc_history) { 10395c6c1daeSBarry Smith va_start(Argp, format); 10409566063dSJacob Faibussowitsch PetscCall((*PetscVFPrintf)(petsc_history, format, Argp)); 1041eae3dc7dSJacob Faibussowitsch va_end(Argp); 1042c69effb2SJacob Faibussowitsch PetscCall(PetscFFlush(petsc_history)); 10435c6c1daeSBarry Smith } 10445c6c1daeSBarry Smith va_end(Argp); 1045559f443fSBarry Smith } else { /* other processors add to queue */ 10465c6c1daeSBarry Smith char *string; 10475c6c1daeSBarry Smith va_list Argp; 10485c6c1daeSBarry Smith size_t fullLength; 10495c6c1daeSBarry Smith PrintfQueue next; 10505c6c1daeSBarry Smith 10519566063dSJacob Faibussowitsch PetscCall(PetscNew(&next)); 1052559f443fSBarry Smith if (vascii->petsc_printfqueue) { 1053559f443fSBarry Smith vascii->petsc_printfqueue->next = next; 1054559f443fSBarry Smith vascii->petsc_printfqueue = next; 1055a297a907SKarl Rupp } else { 1056559f443fSBarry Smith vascii->petsc_printfqueuebase = vascii->petsc_printfqueue = next; 1057a297a907SKarl Rupp } 1058559f443fSBarry Smith vascii->petsc_printfqueuelength++; 10595c6c1daeSBarry Smith next->size = QUEUESTRINGSIZE; 10609566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(next->size, &next->string)); 10615c6c1daeSBarry Smith string = next->string; 10625c6c1daeSBarry Smith tab *= 2; 1063ad540459SPierre Jolivet while (tab--) *string++ = ' '; 10645c6c1daeSBarry Smith va_start(Argp, format); 10659566063dSJacob Faibussowitsch PetscCall(PetscVSNPrintf(string, next->size - 2 * vascii->tab, format, &fullLength, Argp)); 10665c6c1daeSBarry Smith va_end(Argp); 1067cb500232SBarry Smith if (fullLength > (size_t)(next->size - 2 * vascii->tab)) { 10689566063dSJacob Faibussowitsch PetscCall(PetscFree(next->string)); 106914416c0eSBarry Smith next->size = fullLength + 2 * vascii->tab; 10709566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(next->size, &next->string)); 107114416c0eSBarry Smith string = next->string; 107214416c0eSBarry Smith tab = 2 * vascii->tab; 1073ad540459SPierre Jolivet while (tab--) *string++ = ' '; 107414416c0eSBarry Smith va_start(Argp, format); 10759566063dSJacob Faibussowitsch PetscCall(PetscVSNPrintf(string, next->size - 2 * vascii->tab, format, NULL, Argp)); 107614416c0eSBarry Smith va_end(Argp); 107714416c0eSBarry Smith } 10785c6c1daeSBarry Smith } 10793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 10805c6c1daeSBarry Smith } 10815c6c1daeSBarry Smith 10822655f987SMichael Lange /*@C 1083c410d8ccSBarry Smith PetscViewerASCIIRead - Reads from a `PETSCVIEWERASCII` file 10842655f987SMichael Lange 1085c410d8ccSBarry Smith Only MPI rank 0 in the `PetscViewer` may call this 10862655f987SMichael Lange 10872655f987SMichael Lange Input Parameters: 10883f423023SBarry Smith + viewer - the `PETSCVIEWERASCII` viewer 1089c410d8ccSBarry Smith . data - location to write the data, treated as an array of type indicated by `datatype` 1090060da220SMatthew G. Knepley . num - number of items of data to read 1091*aec76313SJacob Faibussowitsch - dtype - type of data to read 10922655f987SMichael Lange 109320f4b53cSBarry Smith Output Parameter: 10943f423023SBarry Smith . count - number of items of data actually read, or `NULL` 1095f8e4bde8SMatthew G. Knepley 10962655f987SMichael Lange Level: beginner 10972655f987SMichael Lange 1098d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscViewerASCIIOpen()`, `PetscViewerPushFormat()`, `PetscViewerDestroy()`, `PetscViewerCreate()`, `PetscViewerFileSetMode()`, `PetscViewerFileSetName()` 1099db781477SPatrick Sanan `VecView()`, `MatView()`, `VecLoad()`, `MatLoad()`, `PetscViewerBinaryGetDescriptor()`, 1100db781477SPatrick Sanan `PetscViewerBinaryGetInfoPointer()`, `PetscFileMode`, `PetscViewer`, `PetscViewerBinaryRead()` 11012655f987SMichael Lange @*/ 1102d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIIRead(PetscViewer viewer, void *data, PetscInt num, PetscInt *count, PetscDataType dtype) 1103d71ae5a4SJacob Faibussowitsch { 11042655f987SMichael Lange PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data; 11052655f987SMichael Lange FILE *fd = vascii->fd; 11062655f987SMichael Lange PetscInt i; 11073b7fe8c3SMatthew G. Knepley int ret = 0; 1108f8859db6SBarry Smith PetscMPIInt rank; 11092655f987SMichael Lange 11102655f987SMichael Lange PetscFunctionBegin; 11112655f987SMichael Lange PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 11129566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank)); 1113c5853193SPierre Jolivet PetscCheck(rank == 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Can only be called from process 0 in the PetscViewer"); 1114060da220SMatthew G. Knepley for (i = 0; i < num; i++) { 1115f8e4bde8SMatthew G. Knepley if (dtype == PETSC_CHAR) ret = fscanf(fd, "%c", &(((char *)data)[i])); 1116f8e4bde8SMatthew G. Knepley else if (dtype == PETSC_STRING) ret = fscanf(fd, "%s", &(((char *)data)[i])); 1117a05e1a72SSatish Balay else if (dtype == PETSC_INT) ret = fscanf(fd, "%" PetscInt_FMT, &(((PetscInt *)data)[i])); 1118f8e4bde8SMatthew G. Knepley else if (dtype == PETSC_ENUM) ret = fscanf(fd, "%d", &(((int *)data)[i])); 11199e3e4c22SLisandro Dalcin else if (dtype == PETSC_INT64) ret = fscanf(fd, "%" PetscInt64_FMT, &(((PetscInt64 *)data)[i])); 1120972064b6SLisandro Dalcin else if (dtype == PETSC_LONG) ret = fscanf(fd, "%ld", &(((long *)data)[i])); 1121f8e4bde8SMatthew G. Knepley else if (dtype == PETSC_FLOAT) ret = fscanf(fd, "%f", &(((float *)data)[i])); 1122f8e4bde8SMatthew G. Knepley else if (dtype == PETSC_DOUBLE) ret = fscanf(fd, "%lg", &(((double *)data)[i])); 1123a6e181c6SToby Isaac #if defined(PETSC_USE_REAL___FLOAT128) 1124fba955ccSBarry Smith else if (dtype == PETSC___FLOAT128) { 1125fba955ccSBarry Smith double tmp; 1126fba955ccSBarry Smith ret = fscanf(fd, "%lg", &tmp); 1127a6e181c6SToby Isaac ((__float128 *)data)[i] = tmp; 1128a6e181c6SToby Isaac } 1129fba955ccSBarry Smith #endif 11309371c9d4SSatish Balay else 11319371c9d4SSatish Balay SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Data type %d not supported", (int)dtype); 113228b400f6SJacob Faibussowitsch PetscCheck(ret, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Conversion error for data type %d", (int)dtype); 1133f7d195e4SLawrence Mitchell if (ret < 0) break; /* Proxy for EOF, need to check for it in configure */ 11342655f987SMichael Lange } 1135060da220SMatthew G. Knepley if (count) *count = i; 113608401ef6SPierre Jolivet else PetscCheck(ret >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Insufficient data, read only %" PetscInt_FMT " < %" PetscInt_FMT " items", i, num); 11373ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 11382655f987SMichael Lange } 1139