xref: /petsc/src/sys/classes/viewer/impls/ascii/filev.c (revision eae3dc7d82c4e75c6efc83af6cf84b0783a1b49f)
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:
192811af0c4SBarry Smith     For the standard `PETSCVIEWERASCII` the value is valid only on process 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 
2675c6c1daeSBarry Smith     Input Parameters:
268811af0c4SBarry Smith .    viewer - obtained with `PetscViewerASCIIOpen()`
269a2b725a8SWilliam Gropp 
2705c6c1daeSBarry Smith     Output Parameters:
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 
3585c6c1daeSBarry Smith     Input Parameters:
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 
3881575c14dSBarry Smith     Input Parameters:
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 
420cf53795eSBarry Smith     Not Collective, but only first processor in set has any effect; No Fortran Support
4215c6c1daeSBarry Smith 
4225c6c1daeSBarry Smith     Input Parameters:
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 
447cf53795eSBarry Smith     Not Collective, but only first processor in set has any effect; No Fortran Support
4485c6c1daeSBarry Smith 
4495c6c1daeSBarry Smith     Input Parameters:
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 /*@
474811af0c4SBarry Smith     PetscViewerASCIIUseTabs - Turns on or off the use of tabs with the ASCII `PetscViewer`
4755c6c1daeSBarry Smith 
476cf53795eSBarry Smith     Not Collective, but only first processor in set 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 
5065c6c1daeSBarry Smith /* ----------------------------------------------------------------------- */
5075c6c1daeSBarry Smith 
5085c6c1daeSBarry Smith /*@C
5095c6c1daeSBarry Smith     PetscViewerASCIIPrintf - Prints to a file, only from the first
5103f423023SBarry Smith     processor in the `PetscViewer` of type `PETSCVIEWERASCII`
5115c6c1daeSBarry Smith 
5125c6c1daeSBarry Smith     Not Collective, but only first processor in set has any effect
5135c6c1daeSBarry Smith 
5145c6c1daeSBarry Smith     Input Parameters:
515811af0c4SBarry Smith +    viewer - obtained with `PetscViewerASCIIOpen()`
5165c6c1daeSBarry Smith -    format - the usual printf() format string
5175c6c1daeSBarry Smith 
5185c6c1daeSBarry Smith     Level: developer
5195c6c1daeSBarry Smith 
5205c6c1daeSBarry Smith     Fortran Note:
521811af0c4SBarry Smith     The call sequence is `PetscViewerASCIIPrintf`(PetscViewer, character(*), int ierr) from Fortran.
5225c6c1daeSBarry Smith     That is, you can only pass a single character string from Fortran.
5235c6c1daeSBarry Smith 
524d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIOpen()`,
525db781477SPatrick Sanan           `PetscViewerASCIIPushTab()`, `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`,
526db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`, `PetscViewerASCIIPushSynchronized()`
5275c6c1daeSBarry Smith @*/
528d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIIPrintf(PetscViewer viewer, const char format[], ...)
529d71ae5a4SJacob Faibussowitsch {
5305c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
5315c6c1daeSBarry Smith   PetscMPIInt        rank;
532dd2fa690SBarry Smith   PetscInt           tab, intab = ascii->tab;
5335c6c1daeSBarry Smith   FILE              *fd = ascii->fd;
5343f08860eSBarry Smith   PetscBool          iascii;
5355c6c1daeSBarry Smith 
5365c6c1daeSBarry Smith   PetscFunctionBegin;
5375c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
53828b400f6SJacob Faibussowitsch   PetscCheck(!ascii->sviewer, PetscObjectComm((PetscObject)viewer), PETSC_ERR_ARG_WRONGSTATE, "Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
5395c6c1daeSBarry Smith   PetscValidCharPointer(format, 2);
5409566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
54128b400f6SJacob Faibussowitsch   PetscCheck(iascii, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Not ASCII PetscViewer");
5429566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank));
5433ba16761SJacob Faibussowitsch   if (rank) PetscFunctionReturn(PETSC_SUCCESS);
5443f08860eSBarry Smith 
5453f08860eSBarry Smith   if (ascii->bviewer) { /* pass string up to parent viewer */
5463f08860eSBarry Smith     char   *string;
5473f08860eSBarry Smith     va_list Argp;
5483f08860eSBarry Smith     size_t  fullLength;
5493f08860eSBarry Smith 
5509566063dSJacob Faibussowitsch     PetscCall(PetscCalloc1(QUEUESTRINGSIZE, &string));
5513f08860eSBarry Smith     va_start(Argp, format);
5529566063dSJacob Faibussowitsch     PetscCall(PetscVSNPrintf(string, QUEUESTRINGSIZE, format, &fullLength, Argp));
5533f08860eSBarry Smith     va_end(Argp);
5549566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "%s", string));
5559566063dSJacob Faibussowitsch     PetscCall(PetscFree(string));
5563f08860eSBarry Smith   } else { /* write directly to file */
5575c6c1daeSBarry Smith     va_list Argp;
558559f443fSBarry Smith     /* flush my own messages that I may have queued up */
559559f443fSBarry Smith     PrintfQueue next = ascii->petsc_printfqueuebase, previous;
560559f443fSBarry Smith     PetscInt    i;
561559f443fSBarry Smith     for (i = 0; i < ascii->petsc_printfqueuelength; i++) {
5629566063dSJacob Faibussowitsch       PetscCall(PetscFPrintf(PETSC_COMM_SELF, fd, "%s", next->string));
563559f443fSBarry Smith       previous = next;
564559f443fSBarry Smith       next     = next->next;
5659566063dSJacob Faibussowitsch       PetscCall(PetscFree(previous->string));
5669566063dSJacob Faibussowitsch       PetscCall(PetscFree(previous));
567559f443fSBarry Smith     }
56802c9f0b5SLisandro Dalcin     ascii->petsc_printfqueue       = NULL;
569559f443fSBarry Smith     ascii->petsc_printfqueuelength = 0;
570dd2fa690SBarry Smith     tab                            = intab;
57148a46eb9SPierre Jolivet     while (tab--) PetscCall(PetscFPrintf(PETSC_COMM_SELF, fd, "  "));
5725c6c1daeSBarry Smith 
5735c6c1daeSBarry Smith     va_start(Argp, format);
5749566063dSJacob Faibussowitsch     PetscCall((*PetscVFPrintf)(fd, format, Argp));
575*eae3dc7dSJacob Faibussowitsch     va_end(Argp);
576c69effb2SJacob Faibussowitsch     PetscCall(PetscFFlush(fd));
5775c6c1daeSBarry Smith     if (petsc_history) {
578dd2fa690SBarry Smith       tab = intab;
57948a46eb9SPierre Jolivet       while (tab--) PetscCall(PetscFPrintf(PETSC_COMM_SELF, petsc_history, "  "));
580*eae3dc7dSJacob Faibussowitsch       va_start(Argp, format);
5819566063dSJacob Faibussowitsch       PetscCall((*PetscVFPrintf)(petsc_history, format, Argp));
582*eae3dc7dSJacob Faibussowitsch       va_end(Argp);
583c69effb2SJacob Faibussowitsch       PetscCall(PetscFFlush(petsc_history));
5845c6c1daeSBarry Smith     }
5855c6c1daeSBarry Smith   }
5863ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5875c6c1daeSBarry Smith }
5885c6c1daeSBarry Smith 
5895c6c1daeSBarry Smith /*@C
590811af0c4SBarry Smith      PetscViewerFileSetName - Sets the name of the file the `PetscViewer` uses.
5915c6c1daeSBarry Smith 
592c3339decSBarry Smith     Collective
5935c6c1daeSBarry Smith 
5945c6c1daeSBarry Smith   Input Parameters:
5953f423023SBarry Smith +  viewer - the `PetscViewer`; for example, of type `PETSCVIEWERASCII` or `PETSCVIEWERBINARY`
5965c6c1daeSBarry Smith -  name - the name of the file it should use
5975c6c1daeSBarry Smith 
5985c6c1daeSBarry Smith     Level: advanced
5995c6c1daeSBarry Smith 
600d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscViewerCreate()`, `PetscViewerSetType()`, `PetscViewerASCIIOpen()`, `PetscViewerBinaryOpen()`, `PetscViewerDestroy()`,
601db781477SPatrick Sanan           `PetscViewerASCIIGetPointer()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIISynchronizedPrintf()`
6025c6c1daeSBarry Smith @*/
603d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerFileSetName(PetscViewer viewer, const char name[])
604d71ae5a4SJacob Faibussowitsch {
605cc843e7aSLisandro Dalcin   char filename[PETSC_MAX_PATH_LEN];
6065c6c1daeSBarry Smith 
6075c6c1daeSBarry Smith   PetscFunctionBegin;
6085c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
6095c6c1daeSBarry Smith   PetscValidCharPointer(name, 2);
6109566063dSJacob Faibussowitsch   PetscCall(PetscStrreplace(PetscObjectComm((PetscObject)viewer), name, filename, sizeof(filename)));
611cac4c232SBarry Smith   PetscTryMethod(viewer, "PetscViewerFileSetName_C", (PetscViewer, const char[]), (viewer, filename));
6123ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6135c6c1daeSBarry Smith }
6145c6c1daeSBarry Smith 
6155c6c1daeSBarry Smith /*@C
616811af0c4SBarry Smith      PetscViewerFileGetName - Gets the name of the file the `PetscViewer` uses.
6175c6c1daeSBarry Smith 
6185c6c1daeSBarry Smith     Not Collective
6195c6c1daeSBarry Smith 
6205c6c1daeSBarry Smith   Input Parameter:
6213f423023SBarry Smith .  viewer - the `PetscViewer`
6225c6c1daeSBarry Smith 
6235c6c1daeSBarry Smith   Output Parameter:
6245c6c1daeSBarry Smith .  name - the name of the file it is using
6255c6c1daeSBarry Smith 
6265c6c1daeSBarry Smith     Level: advanced
6275c6c1daeSBarry Smith 
628d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscViewerCreate()`, `PetscViewerSetType()`, `PetscViewerASCIIOpen()`, `PetscViewerBinaryOpen()`, `PetscViewerFileSetName()`
6295c6c1daeSBarry Smith @*/
630d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerFileGetName(PetscViewer viewer, const char **name)
631d71ae5a4SJacob Faibussowitsch {
6325c6c1daeSBarry Smith   PetscFunctionBegin;
6335c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
6346e05b1faSLisandro Dalcin   PetscValidPointer(name, 2);
635cac4c232SBarry Smith   PetscUseMethod(viewer, "PetscViewerFileGetName_C", (PetscViewer, const char **), (viewer, name));
6363ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6375c6c1daeSBarry Smith }
6385c6c1daeSBarry Smith 
639d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerFileGetName_ASCII(PetscViewer viewer, const char **name)
640d71ae5a4SJacob Faibussowitsch {
6415c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
6425c6c1daeSBarry Smith 
6435c6c1daeSBarry Smith   PetscFunctionBegin;
6445c6c1daeSBarry Smith   *name = vascii->filename;
6453ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6465c6c1daeSBarry Smith }
6475c6c1daeSBarry Smith 
648d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerFileSetName_ASCII(PetscViewer viewer, const char name[])
649d71ae5a4SJacob Faibussowitsch {
6505c6c1daeSBarry Smith   size_t             len;
651bbcf679cSJacob Faibussowitsch   char               fname[PETSC_MAX_PATH_LEN], *gz = NULL;
6525c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
6535c6c1daeSBarry Smith   PetscBool          isstderr, isstdout;
6545c6c1daeSBarry Smith   PetscMPIInt        rank;
6555c6c1daeSBarry Smith 
6565c6c1daeSBarry Smith   PetscFunctionBegin;
6579566063dSJacob Faibussowitsch   PetscCall(PetscViewerFileClose_ASCII(viewer));
6583ba16761SJacob Faibussowitsch   if (!name) PetscFunctionReturn(PETSC_SUCCESS);
6599566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(name, &vascii->filename));
6605c6c1daeSBarry Smith 
6615c6c1daeSBarry Smith   /* Is this file to be compressed */
6625c6c1daeSBarry Smith   vascii->storecompressed = PETSC_FALSE;
663a297a907SKarl Rupp 
6649566063dSJacob Faibussowitsch   PetscCall(PetscStrstr(vascii->filename, ".gz", &gz));
6655c6c1daeSBarry Smith   if (gz) {
6669566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(gz, &len));
6675c6c1daeSBarry Smith     if (len == 3) {
66808401ef6SPierre 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");
6695c6c1daeSBarry Smith       *gz                     = 0;
6705c6c1daeSBarry Smith       vascii->storecompressed = PETSC_TRUE;
6715c6c1daeSBarry Smith     }
6725c6c1daeSBarry Smith   }
6739566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank));
674dd400576SPatrick Sanan   if (rank == 0) {
6759566063dSJacob Faibussowitsch     PetscCall(PetscStrcmp(name, "stderr", &isstderr));
6769566063dSJacob Faibussowitsch     PetscCall(PetscStrcmp(name, "stdout", &isstdout));
6775c6c1daeSBarry Smith     /* empty filename means stdout */
6785c6c1daeSBarry Smith     if (name[0] == 0) isstdout = PETSC_TRUE;
6795c6c1daeSBarry Smith     if (isstderr) vascii->fd = PETSC_STDERR;
6805c6c1daeSBarry Smith     else if (isstdout) vascii->fd = PETSC_STDOUT;
6815c6c1daeSBarry Smith     else {
6829566063dSJacob Faibussowitsch       PetscCall(PetscFixFilename(name, fname));
6835c6c1daeSBarry Smith       switch (vascii->mode) {
684d71ae5a4SJacob Faibussowitsch       case FILE_MODE_READ:
685d71ae5a4SJacob Faibussowitsch         vascii->fd = fopen(fname, "r");
686d71ae5a4SJacob Faibussowitsch         break;
687d71ae5a4SJacob Faibussowitsch       case FILE_MODE_WRITE:
688d71ae5a4SJacob Faibussowitsch         vascii->fd = fopen(fname, "w");
689d71ae5a4SJacob Faibussowitsch         break;
690d71ae5a4SJacob Faibussowitsch       case FILE_MODE_APPEND:
691d71ae5a4SJacob Faibussowitsch         vascii->fd = fopen(fname, "a");
692d71ae5a4SJacob Faibussowitsch         break;
6935c6c1daeSBarry Smith       case FILE_MODE_UPDATE:
6945c6c1daeSBarry Smith         vascii->fd = fopen(fname, "r+");
695a297a907SKarl Rupp         if (!vascii->fd) vascii->fd = fopen(fname, "w+");
6965c6c1daeSBarry Smith         break;
6975c6c1daeSBarry Smith       case FILE_MODE_APPEND_UPDATE:
6985c6c1daeSBarry Smith         /* I really want a file which is opened at the end for updating,
6995c6c1daeSBarry Smith            not a+, which opens at the beginning, but makes writes at the end.
7005c6c1daeSBarry Smith         */
7015c6c1daeSBarry Smith         vascii->fd = fopen(fname, "r+");
702a297a907SKarl Rupp         if (!vascii->fd) vascii->fd = fopen(fname, "w+");
7033ba16761SJacob Faibussowitsch         else {
7043ba16761SJacob Faibussowitsch           int ret = fseek(vascii->fd, 0, SEEK_END);
7053ba16761SJacob Faibussowitsch           PetscCheck(!ret, PETSC_COMM_SELF, PETSC_ERR_LIB, "fseek() failed with error code %d", ret);
7063ba16761SJacob Faibussowitsch         }
7075c6c1daeSBarry Smith         break;
708d71ae5a4SJacob Faibussowitsch       default:
709d71ae5a4SJacob Faibussowitsch         SETERRQ(PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Unsupported file mode %s", PetscFileModes[vascii->mode]);
7105c6c1daeSBarry Smith       }
71128b400f6SJacob Faibussowitsch       PetscCheck(vascii->fd, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Cannot open PetscViewer file: %s", fname);
7125c6c1daeSBarry Smith     }
7135c6c1daeSBarry Smith   }
7145c6c1daeSBarry Smith #if defined(PETSC_USE_LOG)
7153ba16761SJacob Faibussowitsch   PetscCall(PetscLogObjectState((PetscObject)viewer, "File: %s", name));
7165c6c1daeSBarry Smith #endif
7173ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7185c6c1daeSBarry Smith }
7195c6c1daeSBarry Smith 
720d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerGetSubViewer_ASCII(PetscViewer viewer, MPI_Comm subcomm, PetscViewer *outviewer)
721d71ae5a4SJacob Faibussowitsch {
7225c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data, *ovascii;
7235c6c1daeSBarry Smith 
7245c6c1daeSBarry Smith   PetscFunctionBegin;
7259566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPushSynchronized(viewer));
72628b400f6SJacob Faibussowitsch   PetscCheck(!vascii->sviewer, PETSC_COMM_SELF, PETSC_ERR_ORDER, "SubViewer already obtained from PetscViewer and not restored");
727e5afcf28SBarry Smith   /*
7289530cbd7SBarry Smith      The following line is a bug; it does another PetscViewerASCIIPushSynchronized() on viewer, but if it is removed the code won't work
7299530cbd7SBarry 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
7309530cbd7SBarry Smith      (since the count never gets to zero) in some examples this displays information that otherwise would be lost
7319530cbd7SBarry Smith 
7329530cbd7SBarry Smith      This code also means another call to PetscViewerASCIIPopSynchronized() must be made after the PetscViewerRestoreSubViewer(), see, for example,
7339530cbd7SBarry Smith      PCView_GASM().
734e5afcf28SBarry Smith   */
7359566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPushSynchronized(viewer));
7369566063dSJacob Faibussowitsch   PetscCall(PetscViewerCreate(subcomm, outviewer));
7379566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetType(*outviewer, PETSCVIEWERASCII));
7389566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPushSynchronized(*outviewer));
7395c6c1daeSBarry Smith   ovascii            = (PetscViewer_ASCII *)(*outviewer)->data;
7405c6c1daeSBarry Smith   ovascii->fd        = vascii->fd;
7415c6c1daeSBarry Smith   ovascii->tab       = vascii->tab;
742ba5a0b41SBarry Smith   ovascii->closefile = PETSC_FALSE;
7435c6c1daeSBarry Smith 
7445c6c1daeSBarry Smith   vascii->sviewer                                      = *outviewer;
7455c6c1daeSBarry Smith   (*outviewer)->format                                 = viewer->format;
7465c6c1daeSBarry Smith   ((PetscViewer_ASCII *)((*outviewer)->data))->bviewer = viewer;
7473f08860eSBarry Smith   (*outviewer)->ops->destroy                           = PetscViewerDestroy_ASCII_SubViewer;
7483ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7495c6c1daeSBarry Smith }
7505c6c1daeSBarry Smith 
751d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerRestoreSubViewer_ASCII(PetscViewer viewer, MPI_Comm comm, PetscViewer *outviewer)
752d71ae5a4SJacob Faibussowitsch {
7535c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
7545c6c1daeSBarry Smith 
7555c6c1daeSBarry Smith   PetscFunctionBegin;
75628b400f6SJacob Faibussowitsch   PetscCheck(ascii->sviewer, PETSC_COMM_SELF, PETSC_ERR_ORDER, "SubViewer never obtained from PetscViewer");
75708401ef6SPierre Jolivet   PetscCheck(ascii->sviewer == *outviewer, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "This PetscViewer did not generate this SubViewer");
7585c6c1daeSBarry Smith 
7599566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPopSynchronized(*outviewer));
760e5afcf28SBarry Smith   ascii->sviewer             = NULL;
7615c6c1daeSBarry Smith   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
7629566063dSJacob Faibussowitsch   PetscCall(PetscViewerDestroy(outviewer));
7639566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPopSynchronized(viewer));
7643ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7655c6c1daeSBarry Smith }
7665c6c1daeSBarry Smith 
767d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerView_ASCII(PetscViewer v, PetscViewer viewer)
768d71ae5a4SJacob Faibussowitsch {
7692bf49c77SBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)v->data;
7702bf49c77SBarry Smith 
7712bf49c77SBarry Smith   PetscFunctionBegin;
77248a46eb9SPierre Jolivet   if (ascii->filename) PetscCall(PetscViewerASCIIPrintf(viewer, "Filename: %s\n", ascii->filename));
7733ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7742bf49c77SBarry Smith }
7752bf49c77SBarry Smith 
7768556b5ebSBarry Smith /*MC
7778556b5ebSBarry Smith    PETSCVIEWERASCII - A viewer that prints to stdout or an ASCII file
7788556b5ebSBarry Smith 
779811af0c4SBarry Smith   Level: beginner
780811af0c4SBarry Smith 
781d1f92df0SBarry Smith .seealso: [](sec_viewers), `PETSC_VIEWER_STDOUT_()`, `PETSC_VIEWER_STDOUT_SELF`, `PETSC_VIEWER_STDOUT_WORLD`, `PetscViewerCreate()`, `PetscViewerASCIIOpen()`,
782db781477SPatrick Sanan           `PetscViewerMatlabOpen()`, `VecView()`, `DMView()`, `PetscViewerMatlabPutArray()`, `PETSCVIEWERBINARY`, `PETSCVIEWERMATLAB`,
783db781477SPatrick Sanan           `PetscViewerFileSetName()`, `PetscViewerFileSetMode()`, `PetscViewerFormat`, `PetscViewerType`, `PetscViewerSetType()`
7848556b5ebSBarry Smith M*/
785d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscViewerCreate_ASCII(PetscViewer viewer)
786d71ae5a4SJacob Faibussowitsch {
7875c6c1daeSBarry Smith   PetscViewer_ASCII *vascii;
7885c6c1daeSBarry Smith 
7895c6c1daeSBarry Smith   PetscFunctionBegin;
7904dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&vascii));
7915c6c1daeSBarry Smith   viewer->data = (void *)vascii;
7925c6c1daeSBarry Smith 
7935c6c1daeSBarry Smith   viewer->ops->destroy          = PetscViewerDestroy_ASCII;
7945c6c1daeSBarry Smith   viewer->ops->flush            = PetscViewerFlush_ASCII;
795559f443fSBarry Smith   viewer->ops->getsubviewer     = PetscViewerGetSubViewer_ASCII;
796559f443fSBarry Smith   viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_ASCII;
7972bf49c77SBarry Smith   viewer->ops->view             = PetscViewerView_ASCII;
7981d641e7bSMichael Lange   viewer->ops->read             = PetscViewerASCIIRead;
7995c6c1daeSBarry Smith 
8005c6c1daeSBarry Smith   /* defaults to stdout unless set with PetscViewerFileSetName() */
8015c6c1daeSBarry Smith   vascii->fd        = PETSC_STDOUT;
8025c6c1daeSBarry Smith   vascii->mode      = FILE_MODE_WRITE;
80302c9f0b5SLisandro Dalcin   vascii->bviewer   = NULL;
80402c9f0b5SLisandro Dalcin   vascii->subviewer = NULL;
80502c9f0b5SLisandro Dalcin   vascii->sviewer   = NULL;
8065c6c1daeSBarry Smith   vascii->tab       = 0;
8075c6c1daeSBarry Smith   vascii->tab_store = 0;
80802c9f0b5SLisandro Dalcin   vascii->filename  = NULL;
8095c6c1daeSBarry Smith   vascii->closefile = PETSC_TRUE;
8105c6c1daeSBarry Smith 
8119566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileSetName_C", PetscViewerFileSetName_ASCII));
8129566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileGetName_C", PetscViewerFileGetName_ASCII));
8139566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileGetMode_C", PetscViewerFileGetMode_ASCII));
8149566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileSetMode_C", PetscViewerFileSetMode_ASCII));
8153ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
8165c6c1daeSBarry Smith }
8175c6c1daeSBarry Smith 
8185c6c1daeSBarry Smith /*@C
8195c6c1daeSBarry Smith     PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from
8205c6c1daeSBarry Smith     several processors.  Output of the first processor is followed by that of the
8215c6c1daeSBarry Smith     second, etc.
8225c6c1daeSBarry Smith 
823811af0c4SBarry Smith     Not Collective, must call collective `PetscViewerFlush()` to get the results out
8245c6c1daeSBarry Smith 
8255c6c1daeSBarry Smith     Input Parameters:
826811af0c4SBarry Smith +   viewer - the `PETSCVIEWERASCII` `PetscViewer`
8275c6c1daeSBarry Smith -   format - the usual printf() format string
8285c6c1daeSBarry Smith 
8295c6c1daeSBarry Smith     Level: intermediate
8305c6c1daeSBarry Smith 
83195452b02SPatrick Sanan     Notes:
832811af0c4SBarry Smith     You must have previously called `PetscViewerASCIIPushSynchronized()` to allow this routine to be called.
833e6abc3ddSVáclav Hapla     Then you can do multiple independent calls to this routine.
834811af0c4SBarry Smith 
835811af0c4SBarry Smith     The actual synchronized print is then done using `PetscViewerFlush()`.
836811af0c4SBarry Smith     `PetscViewerASCIIPopSynchronized()` should be then called if we are already done with the synchronized output
837e6abc3ddSVáclav Hapla     to conclude the "synchronized session".
838811af0c4SBarry Smith 
839e6abc3ddSVáclav Hapla     So the typical calling sequence looks like
840811af0c4SBarry Smith .vb
841811af0c4SBarry Smith     PetscViewerASCIIPushSynchronized(viewer);
842811af0c4SBarry Smith     PetscViewerASCIISynchronizedPrintf(viewer, ...);
843811af0c4SBarry Smith     PetscViewerASCIISynchronizedPrintf(viewer, ...);
844811af0c4SBarry Smith     ...
845811af0c4SBarry Smith     PetscViewerFlush(viewer);
846811af0c4SBarry Smith     PetscViewerASCIISynchronizedPrintf(viewer, ...);
847811af0c4SBarry Smith     PetscViewerASCIISynchronizedPrintf(viewer, ...);
848811af0c4SBarry Smith     ...
849811af0c4SBarry Smith     PetscViewerFlush(viewer);
850811af0c4SBarry Smith    PetscViewerASCIIPopSynchronized(viewer);
851811af0c4SBarry Smith .ve
8525c6c1daeSBarry Smith 
8535c6c1daeSBarry Smith     Fortran Note:
8545c6c1daeSBarry Smith       Can only print a single character* string
8555c6c1daeSBarry Smith 
856d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscViewerASCIIPushSynchronized()`, `PetscViewerFlush()`, `PetscViewerASCIIPopSynchronized()`,
857db781477SPatrick Sanan           `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIIOpen()`,
858db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`
8595c6c1daeSBarry Smith @*/
860d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIISynchronizedPrintf(PetscViewer viewer, const char format[], ...)
861d71ae5a4SJacob Faibussowitsch {
8625c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
8633f08860eSBarry Smith   PetscMPIInt        rank;
8645c6c1daeSBarry Smith   PetscInt           tab = vascii->tab;
8655c6c1daeSBarry Smith   MPI_Comm           comm;
8665c6c1daeSBarry Smith   FILE              *fp;
867559f443fSBarry Smith   PetscBool          iascii, hasbviewer = PETSC_FALSE;
8685c6c1daeSBarry Smith 
8695c6c1daeSBarry Smith   PetscFunctionBegin;
8705c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
8715c6c1daeSBarry Smith   PetscValidCharPointer(format, 2);
8729566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
87328b400f6SJacob Faibussowitsch   PetscCheck(iascii, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Not ASCII PetscViewer");
87428b400f6SJacob Faibussowitsch   PetscCheck(vascii->allowsynchronized, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "First call PetscViewerASCIIPushSynchronized() to allow this call");
8755c6c1daeSBarry Smith 
8769566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
8779566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
8785c6c1daeSBarry Smith 
879559f443fSBarry Smith   if (vascii->bviewer) {
880559f443fSBarry Smith     hasbviewer = PETSC_TRUE;
881dd400576SPatrick Sanan     if (rank == 0) {
882559f443fSBarry Smith       vascii = (PetscViewer_ASCII *)vascii->bviewer->data;
8839566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
8849566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Comm_rank(comm, &rank));
885559f443fSBarry Smith     }
886559f443fSBarry Smith   }
8873f08860eSBarry Smith 
888559f443fSBarry Smith   fp = vascii->fd;
889559f443fSBarry Smith 
890dd400576SPatrick Sanan   if (rank == 0 && !hasbviewer) { /* First processor prints immediately to fp */
8915c6c1daeSBarry Smith     va_list Argp;
892559f443fSBarry Smith     /* flush my own messages that I may have queued up */
893559f443fSBarry Smith     PrintfQueue next = vascii->petsc_printfqueuebase, previous;
894559f443fSBarry Smith     PetscInt    i;
895559f443fSBarry Smith     for (i = 0; i < vascii->petsc_printfqueuelength; i++) {
8969566063dSJacob Faibussowitsch       PetscCall(PetscFPrintf(comm, fp, "%s", next->string));
897559f443fSBarry Smith       previous = next;
898559f443fSBarry Smith       next     = next->next;
8999566063dSJacob Faibussowitsch       PetscCall(PetscFree(previous->string));
9009566063dSJacob Faibussowitsch       PetscCall(PetscFree(previous));
901559f443fSBarry Smith     }
90202c9f0b5SLisandro Dalcin     vascii->petsc_printfqueue       = NULL;
903559f443fSBarry Smith     vascii->petsc_printfqueuelength = 0;
9045c6c1daeSBarry Smith 
90548a46eb9SPierre Jolivet     while (tab--) PetscCall(PetscFPrintf(PETSC_COMM_SELF, fp, "  "));
9065c6c1daeSBarry Smith 
9075c6c1daeSBarry Smith     va_start(Argp, format);
9089566063dSJacob Faibussowitsch     PetscCall((*PetscVFPrintf)(fp, format, Argp));
909*eae3dc7dSJacob Faibussowitsch     va_end(Argp);
910c69effb2SJacob Faibussowitsch     PetscCall(PetscFFlush(fp));
9115c6c1daeSBarry Smith     if (petsc_history) {
9125c6c1daeSBarry Smith       va_start(Argp, format);
9139566063dSJacob Faibussowitsch       PetscCall((*PetscVFPrintf)(petsc_history, format, Argp));
914*eae3dc7dSJacob Faibussowitsch       va_end(Argp);
915c69effb2SJacob Faibussowitsch       PetscCall(PetscFFlush(petsc_history));
9165c6c1daeSBarry Smith     }
9175c6c1daeSBarry Smith     va_end(Argp);
918559f443fSBarry Smith   } else { /* other processors add to queue */
9195c6c1daeSBarry Smith     char       *string;
9205c6c1daeSBarry Smith     va_list     Argp;
9215c6c1daeSBarry Smith     size_t      fullLength;
9225c6c1daeSBarry Smith     PrintfQueue next;
9235c6c1daeSBarry Smith 
9249566063dSJacob Faibussowitsch     PetscCall(PetscNew(&next));
925559f443fSBarry Smith     if (vascii->petsc_printfqueue) {
926559f443fSBarry Smith       vascii->petsc_printfqueue->next = next;
927559f443fSBarry Smith       vascii->petsc_printfqueue       = next;
928a297a907SKarl Rupp     } else {
929559f443fSBarry Smith       vascii->petsc_printfqueuebase = vascii->petsc_printfqueue = next;
930a297a907SKarl Rupp     }
931559f443fSBarry Smith     vascii->petsc_printfqueuelength++;
9325c6c1daeSBarry Smith     next->size = QUEUESTRINGSIZE;
9339566063dSJacob Faibussowitsch     PetscCall(PetscCalloc1(next->size, &next->string));
9345c6c1daeSBarry Smith     string = next->string;
9355c6c1daeSBarry Smith     tab *= 2;
936ad540459SPierre Jolivet     while (tab--) *string++ = ' ';
9375c6c1daeSBarry Smith     va_start(Argp, format);
9389566063dSJacob Faibussowitsch     PetscCall(PetscVSNPrintf(string, next->size - 2 * vascii->tab, format, &fullLength, Argp));
9395c6c1daeSBarry Smith     va_end(Argp);
940cb500232SBarry Smith     if (fullLength > (size_t)(next->size - 2 * vascii->tab)) {
9419566063dSJacob Faibussowitsch       PetscCall(PetscFree(next->string));
94214416c0eSBarry Smith       next->size = fullLength + 2 * vascii->tab;
9439566063dSJacob Faibussowitsch       PetscCall(PetscCalloc1(next->size, &next->string));
94414416c0eSBarry Smith       string = next->string;
94514416c0eSBarry Smith       tab    = 2 * vascii->tab;
946ad540459SPierre Jolivet       while (tab--) *string++ = ' ';
94714416c0eSBarry Smith       va_start(Argp, format);
9489566063dSJacob Faibussowitsch       PetscCall(PetscVSNPrintf(string, next->size - 2 * vascii->tab, format, NULL, Argp));
94914416c0eSBarry Smith       va_end(Argp);
95014416c0eSBarry Smith     }
9515c6c1daeSBarry Smith   }
9523ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9535c6c1daeSBarry Smith }
9545c6c1daeSBarry Smith 
9552655f987SMichael Lange /*@C
956f8859db6SBarry Smith    PetscViewerASCIIRead - Reads from a ASCII file
9572655f987SMichael Lange 
958811af0c4SBarry Smith    Only process 0 in the `PetscViewer` may call this
9592655f987SMichael Lange 
9602655f987SMichael Lange    Input Parameters:
9613f423023SBarry Smith +  viewer - the `PETSCVIEWERASCII` viewer
9622655f987SMichael Lange .  data - location to write the data
963060da220SMatthew G. Knepley .  num - number of items of data to read
9642655f987SMichael Lange -  datatype - type of data to read
9652655f987SMichael Lange 
966f8e4bde8SMatthew G. Knepley    Output Parameters:
9673f423023SBarry Smith .  count - number of items of data actually read, or `NULL`
968f8e4bde8SMatthew G. Knepley 
9692655f987SMichael Lange    Level: beginner
9702655f987SMichael Lange 
971d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscViewerASCIIOpen()`, `PetscViewerPushFormat()`, `PetscViewerDestroy()`, `PetscViewerCreate()`, `PetscViewerFileSetMode()`, `PetscViewerFileSetName()`
972db781477SPatrick Sanan           `VecView()`, `MatView()`, `VecLoad()`, `MatLoad()`, `PetscViewerBinaryGetDescriptor()`,
973db781477SPatrick Sanan           `PetscViewerBinaryGetInfoPointer()`, `PetscFileMode`, `PetscViewer`, `PetscViewerBinaryRead()`
9742655f987SMichael Lange @*/
975d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIIRead(PetscViewer viewer, void *data, PetscInt num, PetscInt *count, PetscDataType dtype)
976d71ae5a4SJacob Faibussowitsch {
9772655f987SMichael Lange   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
9782655f987SMichael Lange   FILE              *fd     = vascii->fd;
9792655f987SMichael Lange   PetscInt           i;
9803b7fe8c3SMatthew G. Knepley   int                ret = 0;
981f8859db6SBarry Smith   PetscMPIInt        rank;
9822655f987SMichael Lange 
9832655f987SMichael Lange   PetscFunctionBegin;
9842655f987SMichael Lange   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
9859566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank));
986c5853193SPierre Jolivet   PetscCheck(rank == 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Can only be called from process 0 in the PetscViewer");
987060da220SMatthew G. Knepley   for (i = 0; i < num; i++) {
988f8e4bde8SMatthew G. Knepley     if (dtype == PETSC_CHAR) ret = fscanf(fd, "%c", &(((char *)data)[i]));
989f8e4bde8SMatthew G. Knepley     else if (dtype == PETSC_STRING) ret = fscanf(fd, "%s", &(((char *)data)[i]));
990a05e1a72SSatish Balay     else if (dtype == PETSC_INT) ret = fscanf(fd, "%" PetscInt_FMT, &(((PetscInt *)data)[i]));
991f8e4bde8SMatthew G. Knepley     else if (dtype == PETSC_ENUM) ret = fscanf(fd, "%d", &(((int *)data)[i]));
9929e3e4c22SLisandro Dalcin     else if (dtype == PETSC_INT64) ret = fscanf(fd, "%" PetscInt64_FMT, &(((PetscInt64 *)data)[i]));
993972064b6SLisandro Dalcin     else if (dtype == PETSC_LONG) ret = fscanf(fd, "%ld", &(((long *)data)[i]));
994f8e4bde8SMatthew G. Knepley     else if (dtype == PETSC_FLOAT) ret = fscanf(fd, "%f", &(((float *)data)[i]));
995f8e4bde8SMatthew G. Knepley     else if (dtype == PETSC_DOUBLE) ret = fscanf(fd, "%lg", &(((double *)data)[i]));
996a6e181c6SToby Isaac #if defined(PETSC_USE_REAL___FLOAT128)
997fba955ccSBarry Smith     else if (dtype == PETSC___FLOAT128) {
998fba955ccSBarry Smith       double tmp;
999fba955ccSBarry Smith       ret                     = fscanf(fd, "%lg", &tmp);
1000a6e181c6SToby Isaac       ((__float128 *)data)[i] = tmp;
1001a6e181c6SToby Isaac     }
1002fba955ccSBarry Smith #endif
10039371c9d4SSatish Balay     else
10049371c9d4SSatish Balay       SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Data type %d not supported", (int)dtype);
100528b400f6SJacob Faibussowitsch     PetscCheck(ret, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Conversion error for data type %d", (int)dtype);
1006f7d195e4SLawrence Mitchell     if (ret < 0) break; /* Proxy for EOF, need to check for it in configure */
10072655f987SMichael Lange   }
1008060da220SMatthew G. Knepley   if (count) *count = i;
100908401ef6SPierre Jolivet   else PetscCheck(ret >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Insufficient data, read only %" PetscInt_FMT " < %" PetscInt_FMT " items", i, num);
10103ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10112655f987SMichael Lange }
1012