xref: /petsc/src/sys/classes/viewer/impls/ascii/filev.c (revision c69effb2e05caa58810396c101d616d7ad9da0a7)
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 
113*c69effb2SJacob 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:
184811af0c4SBarry 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 
194d1f92df0SBarry Smith .seealso: [](sec_viewers), `PETSCVIEWERASCII`, `PetscViewerASCIIOpen()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerCreate()`, `PetscViewerASCIIPrintf()`,
195db781477SPatrick Sanan           `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 /*@
231811af0c4SBarry Smith     PetscViewerASCIISetTab - Causes `PetscViewer` to tab in a number of times
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 
241d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIIGetTab()`,
242db781477SPatrick Sanan           `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIOpen()`,
243db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`, `PetscViewerASCIIPushTab()`
2445c6c1daeSBarry Smith @*/
245d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIISetTab(PetscViewer viewer, PetscInt tabs)
246d71ae5a4SJacob Faibussowitsch {
2475c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
2485c6c1daeSBarry Smith   PetscBool          iascii;
2495c6c1daeSBarry Smith 
2505c6c1daeSBarry Smith   PetscFunctionBegin;
2515c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
2529566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
253a297a907SKarl Rupp   if (iascii) ascii->tab = tabs;
2543ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2555c6c1daeSBarry Smith }
2565c6c1daeSBarry Smith 
2575c6c1daeSBarry Smith /*@
258811af0c4SBarry Smith     PetscViewerASCIIGetTab - Return the number of tabs used by `PetscViewer`.
2595c6c1daeSBarry Smith 
260cf53795eSBarry Smith     Not Collective, meaningful on first processor only; No Fortran Support
2615c6c1daeSBarry Smith 
2625c6c1daeSBarry Smith     Input Parameters:
263811af0c4SBarry Smith .    viewer - obtained with `PetscViewerASCIIOpen()`
264a2b725a8SWilliam Gropp 
2655c6c1daeSBarry Smith     Output Parameters:
2665c6c1daeSBarry Smith .    tabs - number of tabs
2675c6c1daeSBarry Smith 
2685c6c1daeSBarry Smith     Level: developer
2695c6c1daeSBarry Smith 
270d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIISetTab()`,
271db781477SPatrick Sanan           `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIOpen()`,
272db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`, `PetscViewerASCIIPushTab()`
2735c6c1daeSBarry Smith @*/
274d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIIGetTab(PetscViewer viewer, PetscInt *tabs)
275d71ae5a4SJacob Faibussowitsch {
2765c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
2775c6c1daeSBarry Smith   PetscBool          iascii;
2785c6c1daeSBarry Smith 
2795c6c1daeSBarry Smith   PetscFunctionBegin;
2805c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
2819566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
282a297a907SKarl Rupp   if (iascii && tabs) *tabs = ascii->tab;
2833ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2845c6c1daeSBarry Smith }
2855c6c1daeSBarry Smith 
2865c6c1daeSBarry Smith /*@
2875c6c1daeSBarry Smith     PetscViewerASCIIAddTab - Add to the number of times an ASCII viewer tabs before printing
2885c6c1daeSBarry Smith 
289cf53795eSBarry Smith     Not Collective, but only first processor in set has any effect; No Fortran Support
2905c6c1daeSBarry Smith 
2915c6c1daeSBarry Smith     Input Parameters:
292811af0c4SBarry Smith +    viewer - obtained with `PetscViewerASCIIOpen()`
2935c6c1daeSBarry Smith -    tabs - number of tabs
2945c6c1daeSBarry Smith 
2955c6c1daeSBarry Smith     Level: developer
2965c6c1daeSBarry Smith 
297d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`,
298db781477SPatrick Sanan           `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIOpen()`,
299db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`, `PetscViewerASCIIPushTab()`
3005c6c1daeSBarry Smith @*/
301d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIIAddTab(PetscViewer viewer, PetscInt tabs)
302d71ae5a4SJacob Faibussowitsch {
3035c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
3045c6c1daeSBarry Smith   PetscBool          iascii;
3055c6c1daeSBarry Smith 
3065c6c1daeSBarry Smith   PetscFunctionBegin;
3075c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
3089566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
309a297a907SKarl Rupp   if (iascii) ascii->tab += tabs;
3103ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3115c6c1daeSBarry Smith }
3125c6c1daeSBarry Smith 
3135c6c1daeSBarry Smith /*@
3145c6c1daeSBarry Smith     PetscViewerASCIISubtractTab - Subtracts from the number of times an ASCII viewer tabs before printing
3155c6c1daeSBarry Smith 
316cf53795eSBarry Smith     Not Collective, but only first processor in set has any effect; No Fortran Support
3175c6c1daeSBarry Smith 
3185c6c1daeSBarry Smith     Input Parameters:
319811af0c4SBarry Smith +    viewer - obtained with `PetscViewerASCIIOpen()`
3205c6c1daeSBarry Smith -    tabs - number of tabs
3215c6c1daeSBarry Smith 
3225c6c1daeSBarry Smith     Level: developer
3235c6c1daeSBarry Smith 
324d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`,
325db781477SPatrick Sanan           `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIOpen()`,
326db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`, `PetscViewerASCIIPushTab()`
3275c6c1daeSBarry Smith @*/
328d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIISubtractTab(PetscViewer viewer, PetscInt tabs)
329d71ae5a4SJacob Faibussowitsch {
3305c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
3315c6c1daeSBarry Smith   PetscBool          iascii;
3325c6c1daeSBarry Smith 
3335c6c1daeSBarry Smith   PetscFunctionBegin;
3345c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
3359566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
336a297a907SKarl Rupp   if (iascii) ascii->tab -= tabs;
3373ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3385c6c1daeSBarry Smith }
3395c6c1daeSBarry Smith 
3405c6c1daeSBarry Smith /*@C
341811af0c4SBarry Smith     PetscViewerASCIIPushSynchronized - Allows calls to `PetscViewerASCIISynchronizedPrintf()` for this viewer
3425c6c1daeSBarry Smith 
343c3339decSBarry Smith     Collective
3445c6c1daeSBarry Smith 
3455c6c1daeSBarry Smith     Input Parameters:
346811af0c4SBarry Smith .    viewer - obtained with `PetscViewerASCIIOpen()`
3475c6c1daeSBarry Smith 
3485c6c1daeSBarry Smith     Level: intermediate
3495c6c1daeSBarry Smith 
350811af0c4SBarry Smith     Note:
351811af0c4SBarry Smith     See documentation of `PetscViewerASCIISynchronizedPrintf()` for more details how the synchronized output should be done properly.
3525c6c1daeSBarry Smith 
353d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerFlush()`, `PetscViewerASCIIPopSynchronized()`,
354db781477SPatrick Sanan           `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIIOpen()`,
355db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`
3565c6c1daeSBarry Smith @*/
357d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIIPushSynchronized(PetscViewer viewer)
358d71ae5a4SJacob Faibussowitsch {
3595c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
3605c6c1daeSBarry Smith   PetscBool          iascii;
3615c6c1daeSBarry Smith 
3625c6c1daeSBarry Smith   PetscFunctionBegin;
3635c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
36428b400f6SJacob Faibussowitsch   PetscCheck(!ascii->sviewer, PetscObjectComm((PetscObject)viewer), PETSC_ERR_ARG_WRONGSTATE, "Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
3659566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
3661575c14dSBarry Smith   if (iascii) ascii->allowsynchronized++;
3673ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3681575c14dSBarry Smith }
3691575c14dSBarry Smith 
3701575c14dSBarry Smith /*@C
371811af0c4SBarry Smith     PetscViewerASCIIPopSynchronized - Undoes most recent `PetscViewerASCIIPushSynchronized()` for this viewer
3721575c14dSBarry Smith 
373c3339decSBarry Smith     Collective
3741575c14dSBarry Smith 
3751575c14dSBarry Smith     Input Parameters:
376811af0c4SBarry Smith .    viewer - obtained with `PetscViewerASCIIOpen()`
3771575c14dSBarry Smith 
3781575c14dSBarry Smith     Level: intermediate
3791575c14dSBarry Smith 
380811af0c4SBarry Smith     Note:
381811af0c4SBarry Smith     See documentation of `PetscViewerASCIISynchronizedPrintf()` for more details how the synchronized output should be done properly.
3821575c14dSBarry Smith 
383d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscViewerASCIIPushSynchronized()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerFlush()`,
384db781477SPatrick Sanan           `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIIOpen()`,
385db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`
3861575c14dSBarry Smith @*/
387d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIIPopSynchronized(PetscViewer viewer)
388d71ae5a4SJacob Faibussowitsch {
3891575c14dSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
3901575c14dSBarry Smith   PetscBool          iascii;
3911575c14dSBarry Smith 
3921575c14dSBarry Smith   PetscFunctionBegin;
3931575c14dSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
39428b400f6SJacob Faibussowitsch   PetscCheck(!ascii->sviewer, PetscObjectComm((PetscObject)viewer), PETSC_ERR_ARG_WRONGSTATE, "Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
3959566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
3961575c14dSBarry Smith   if (iascii) {
3971575c14dSBarry Smith     ascii->allowsynchronized--;
39808401ef6SPierre Jolivet     PetscCheck(ascii->allowsynchronized >= 0, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Called more times than PetscViewerASCIIPushSynchronized()");
3991575c14dSBarry Smith   }
4003ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4015c6c1daeSBarry Smith }
4025c6c1daeSBarry Smith 
4031c297824SMatthew G. Knepley /*@C
404811af0c4SBarry Smith     PetscViewerASCIIPushTab - Adds one more tab to the amount that `PetscViewerASCIIPrintf()`
4055c6c1daeSBarry Smith      lines are tabbed.
4065c6c1daeSBarry Smith 
407cf53795eSBarry Smith     Not Collective, but only first processor in set has any effect; No Fortran Support
4085c6c1daeSBarry Smith 
4095c6c1daeSBarry Smith     Input Parameters:
410811af0c4SBarry Smith .    viewer - obtained with `PetscViewerASCIIOpen()`
4115c6c1daeSBarry Smith 
4125c6c1daeSBarry Smith     Level: developer
4135c6c1daeSBarry Smith 
414d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`,
415db781477SPatrick Sanan           `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIOpen()`,
416db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`
4175c6c1daeSBarry Smith @*/
418d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIIPushTab(PetscViewer viewer)
419d71ae5a4SJacob Faibussowitsch {
4205c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
4215c6c1daeSBarry Smith   PetscBool          iascii;
4225c6c1daeSBarry Smith 
4235c6c1daeSBarry Smith   PetscFunctionBegin;
4245c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
4259566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
426a297a907SKarl Rupp   if (iascii) ascii->tab++;
4273ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4285c6c1daeSBarry Smith }
4295c6c1daeSBarry Smith 
4301c297824SMatthew G. Knepley /*@C
431811af0c4SBarry Smith     PetscViewerASCIIPopTab - Removes one tab from the amount that `PetscViewerASCIIPrintf()` lines are tabbed that was provided by `PetscViewerASCIIPushTab()`
4325c6c1daeSBarry Smith 
433cf53795eSBarry Smith     Not Collective, but only first processor in set has any effect; No Fortran Support
4345c6c1daeSBarry Smith 
4355c6c1daeSBarry Smith     Input Parameters:
436811af0c4SBarry Smith .    viewer - obtained with `PetscViewerASCIIOpen()`
4375c6c1daeSBarry Smith 
4385c6c1daeSBarry Smith     Level: developer
4395c6c1daeSBarry Smith 
440d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`,
441db781477SPatrick Sanan           `PetscViewerASCIIPushTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIOpen()`,
442db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`
4435c6c1daeSBarry Smith @*/
444d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIIPopTab(PetscViewer viewer)
445d71ae5a4SJacob Faibussowitsch {
4465c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
4475c6c1daeSBarry Smith   PetscBool          iascii;
4485c6c1daeSBarry Smith 
4495c6c1daeSBarry Smith   PetscFunctionBegin;
4505c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
4519566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
4525c6c1daeSBarry Smith   if (iascii) {
45308401ef6SPierre Jolivet     PetscCheck(ascii->tab > 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "More tabs popped than pushed");
4545c6c1daeSBarry Smith     ascii->tab--;
4555c6c1daeSBarry Smith   }
4563ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4575c6c1daeSBarry Smith }
4585c6c1daeSBarry Smith 
4595c6c1daeSBarry Smith /*@
460811af0c4SBarry Smith     PetscViewerASCIIUseTabs - Turns on or off the use of tabs with the ASCII `PetscViewer`
4615c6c1daeSBarry Smith 
462cf53795eSBarry Smith     Not Collective, but only first processor in set has any effect; No Fortran Support
4635c6c1daeSBarry Smith 
4645c6c1daeSBarry Smith     Input Parameters:
465811af0c4SBarry Smith +    viewer - obtained with `PetscViewerASCIIOpen()`
466811af0c4SBarry Smith -    flg - `PETSC_TRUE` or `PETSC_FALSE`
4675c6c1daeSBarry Smith 
4685c6c1daeSBarry Smith     Level: developer
4695c6c1daeSBarry Smith 
470d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`,
471db781477SPatrick Sanan           `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIPushTab()`, `PetscViewerASCIIOpen()`,
472db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`
4735c6c1daeSBarry Smith @*/
474d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIIUseTabs(PetscViewer viewer, PetscBool flg)
475d71ae5a4SJacob Faibussowitsch {
4765c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
4775c6c1daeSBarry Smith   PetscBool          iascii;
4785c6c1daeSBarry Smith 
4795c6c1daeSBarry Smith   PetscFunctionBegin;
4805c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
4819566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
4825c6c1daeSBarry Smith   if (iascii) {
483a297a907SKarl Rupp     if (flg) ascii->tab = ascii->tab_store;
484a297a907SKarl Rupp     else {
4855c6c1daeSBarry Smith       ascii->tab_store = ascii->tab;
4865c6c1daeSBarry Smith       ascii->tab       = 0;
4875c6c1daeSBarry Smith     }
4885c6c1daeSBarry Smith   }
4893ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4905c6c1daeSBarry Smith }
4915c6c1daeSBarry Smith 
4925c6c1daeSBarry Smith /* ----------------------------------------------------------------------- */
4935c6c1daeSBarry Smith 
4945c6c1daeSBarry Smith /*@C
4955c6c1daeSBarry Smith     PetscViewerASCIIPrintf - Prints to a file, only from the first
4965c6c1daeSBarry Smith     processor in the PetscViewer
4975c6c1daeSBarry Smith 
4985c6c1daeSBarry Smith     Not Collective, but only first processor in set has any effect
4995c6c1daeSBarry Smith 
5005c6c1daeSBarry Smith     Input Parameters:
501811af0c4SBarry Smith +    viewer - obtained with `PetscViewerASCIIOpen()`
5025c6c1daeSBarry Smith -    format - the usual printf() format string
5035c6c1daeSBarry Smith 
5045c6c1daeSBarry Smith     Level: developer
5055c6c1daeSBarry Smith 
5065c6c1daeSBarry Smith     Fortran Note:
507811af0c4SBarry Smith     The call sequence is `PetscViewerASCIIPrintf`(PetscViewer, character(*), int ierr) from Fortran.
5085c6c1daeSBarry Smith     That is, you can only pass a single character string from Fortran.
5095c6c1daeSBarry Smith 
510d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIOpen()`,
511db781477SPatrick Sanan           `PetscViewerASCIIPushTab()`, `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`,
512db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`, `PetscViewerASCIIPushSynchronized()`
5135c6c1daeSBarry Smith @*/
514d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIIPrintf(PetscViewer viewer, const char format[], ...)
515d71ae5a4SJacob Faibussowitsch {
5165c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
5175c6c1daeSBarry Smith   PetscMPIInt        rank;
518dd2fa690SBarry Smith   PetscInt           tab, intab = ascii->tab;
5195c6c1daeSBarry Smith   FILE              *fd = ascii->fd;
5203f08860eSBarry Smith   PetscBool          iascii;
5215c6c1daeSBarry Smith 
5225c6c1daeSBarry Smith   PetscFunctionBegin;
5235c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
52428b400f6SJacob Faibussowitsch   PetscCheck(!ascii->sviewer, PetscObjectComm((PetscObject)viewer), PETSC_ERR_ARG_WRONGSTATE, "Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
5255c6c1daeSBarry Smith   PetscValidCharPointer(format, 2);
5269566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
52728b400f6SJacob Faibussowitsch   PetscCheck(iascii, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Not ASCII PetscViewer");
5289566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank));
5293ba16761SJacob Faibussowitsch   if (rank) PetscFunctionReturn(PETSC_SUCCESS);
5303f08860eSBarry Smith 
5313f08860eSBarry Smith   if (ascii->bviewer) { /* pass string up to parent viewer */
5323f08860eSBarry Smith     char   *string;
5333f08860eSBarry Smith     va_list Argp;
5343f08860eSBarry Smith     size_t  fullLength;
5353f08860eSBarry Smith 
5369566063dSJacob Faibussowitsch     PetscCall(PetscCalloc1(QUEUESTRINGSIZE, &string));
5373f08860eSBarry Smith     va_start(Argp, format);
5389566063dSJacob Faibussowitsch     PetscCall(PetscVSNPrintf(string, QUEUESTRINGSIZE, format, &fullLength, Argp));
5393f08860eSBarry Smith     va_end(Argp);
5409566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "%s", string));
5419566063dSJacob Faibussowitsch     PetscCall(PetscFree(string));
5423f08860eSBarry Smith   } else { /* write directly to file */
5435c6c1daeSBarry Smith     va_list Argp;
544559f443fSBarry Smith     /* flush my own messages that I may have queued up */
545559f443fSBarry Smith     PrintfQueue next = ascii->petsc_printfqueuebase, previous;
546559f443fSBarry Smith     PetscInt    i;
547559f443fSBarry Smith     for (i = 0; i < ascii->petsc_printfqueuelength; i++) {
5489566063dSJacob Faibussowitsch       PetscCall(PetscFPrintf(PETSC_COMM_SELF, fd, "%s", next->string));
549559f443fSBarry Smith       previous = next;
550559f443fSBarry Smith       next     = next->next;
5519566063dSJacob Faibussowitsch       PetscCall(PetscFree(previous->string));
5529566063dSJacob Faibussowitsch       PetscCall(PetscFree(previous));
553559f443fSBarry Smith     }
55402c9f0b5SLisandro Dalcin     ascii->petsc_printfqueue       = NULL;
555559f443fSBarry Smith     ascii->petsc_printfqueuelength = 0;
556dd2fa690SBarry Smith     tab                            = intab;
55748a46eb9SPierre Jolivet     while (tab--) PetscCall(PetscFPrintf(PETSC_COMM_SELF, fd, "  "));
5585c6c1daeSBarry Smith 
5595c6c1daeSBarry Smith     va_start(Argp, format);
5609566063dSJacob Faibussowitsch     PetscCall((*PetscVFPrintf)(fd, format, Argp));
561*c69effb2SJacob Faibussowitsch     PetscCall(PetscFFlush(fd));
5625c6c1daeSBarry Smith     if (petsc_history) {
5635c6c1daeSBarry Smith       va_start(Argp, format);
564dd2fa690SBarry Smith       tab = intab;
56548a46eb9SPierre Jolivet       while (tab--) PetscCall(PetscFPrintf(PETSC_COMM_SELF, petsc_history, "  "));
5669566063dSJacob Faibussowitsch       PetscCall((*PetscVFPrintf)(petsc_history, format, Argp));
567*c69effb2SJacob Faibussowitsch       PetscCall(PetscFFlush(petsc_history));
5685c6c1daeSBarry Smith     }
5695c6c1daeSBarry Smith     va_end(Argp);
5705c6c1daeSBarry Smith   }
5713ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5725c6c1daeSBarry Smith }
5735c6c1daeSBarry Smith 
5745c6c1daeSBarry Smith /*@C
575811af0c4SBarry Smith      PetscViewerFileSetName - Sets the name of the file the `PetscViewer` uses.
5765c6c1daeSBarry Smith 
577c3339decSBarry Smith     Collective
5785c6c1daeSBarry Smith 
5795c6c1daeSBarry Smith   Input Parameters:
580811af0c4SBarry Smith +  viewer - the PetscViewer; either `PETSCVIEWERASCII` or `PETSCVIEWERBINARY`
5815c6c1daeSBarry Smith -  name - the name of the file it should use
5825c6c1daeSBarry Smith 
5835c6c1daeSBarry Smith     Level: advanced
5845c6c1daeSBarry Smith 
585d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscViewerCreate()`, `PetscViewerSetType()`, `PetscViewerASCIIOpen()`, `PetscViewerBinaryOpen()`, `PetscViewerDestroy()`,
586db781477SPatrick Sanan           `PetscViewerASCIIGetPointer()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIISynchronizedPrintf()`
5875c6c1daeSBarry Smith @*/
588d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerFileSetName(PetscViewer viewer, const char name[])
589d71ae5a4SJacob Faibussowitsch {
590cc843e7aSLisandro Dalcin   char filename[PETSC_MAX_PATH_LEN];
5915c6c1daeSBarry Smith 
5925c6c1daeSBarry Smith   PetscFunctionBegin;
5935c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
5945c6c1daeSBarry Smith   PetscValidCharPointer(name, 2);
5959566063dSJacob Faibussowitsch   PetscCall(PetscStrreplace(PetscObjectComm((PetscObject)viewer), name, filename, sizeof(filename)));
596cac4c232SBarry Smith   PetscTryMethod(viewer, "PetscViewerFileSetName_C", (PetscViewer, const char[]), (viewer, filename));
5973ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5985c6c1daeSBarry Smith }
5995c6c1daeSBarry Smith 
6005c6c1daeSBarry Smith /*@C
601811af0c4SBarry Smith      PetscViewerFileGetName - Gets the name of the file the `PetscViewer` uses.
6025c6c1daeSBarry Smith 
6035c6c1daeSBarry Smith     Not Collective
6045c6c1daeSBarry Smith 
6055c6c1daeSBarry Smith   Input Parameter:
606811af0c4SBarry Smith .  viewer - the `PetscViewer`; either `PETSCVIEWERASCII` or `PETSCVIEWERBINARY`
6075c6c1daeSBarry Smith 
6085c6c1daeSBarry Smith   Output Parameter:
6095c6c1daeSBarry Smith .  name - the name of the file it is using
6105c6c1daeSBarry Smith 
6115c6c1daeSBarry Smith     Level: advanced
6125c6c1daeSBarry Smith 
613d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscViewerCreate()`, `PetscViewerSetType()`, `PetscViewerASCIIOpen()`, `PetscViewerBinaryOpen()`, `PetscViewerFileSetName()`
6145c6c1daeSBarry Smith @*/
615d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerFileGetName(PetscViewer viewer, const char **name)
616d71ae5a4SJacob Faibussowitsch {
6175c6c1daeSBarry Smith   PetscFunctionBegin;
6185c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
6196e05b1faSLisandro Dalcin   PetscValidPointer(name, 2);
620cac4c232SBarry Smith   PetscUseMethod(viewer, "PetscViewerFileGetName_C", (PetscViewer, const char **), (viewer, name));
6213ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6225c6c1daeSBarry Smith }
6235c6c1daeSBarry Smith 
624d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerFileGetName_ASCII(PetscViewer viewer, const char **name)
625d71ae5a4SJacob Faibussowitsch {
6265c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
6275c6c1daeSBarry Smith 
6285c6c1daeSBarry Smith   PetscFunctionBegin;
6295c6c1daeSBarry Smith   *name = vascii->filename;
6303ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6315c6c1daeSBarry Smith }
6325c6c1daeSBarry Smith 
633d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerFileSetName_ASCII(PetscViewer viewer, const char name[])
634d71ae5a4SJacob Faibussowitsch {
6355c6c1daeSBarry Smith   size_t             len;
636bbcf679cSJacob Faibussowitsch   char               fname[PETSC_MAX_PATH_LEN], *gz = NULL;
6375c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
6385c6c1daeSBarry Smith   PetscBool          isstderr, isstdout;
6395c6c1daeSBarry Smith   PetscMPIInt        rank;
6405c6c1daeSBarry Smith 
6415c6c1daeSBarry Smith   PetscFunctionBegin;
6429566063dSJacob Faibussowitsch   PetscCall(PetscViewerFileClose_ASCII(viewer));
6433ba16761SJacob Faibussowitsch   if (!name) PetscFunctionReturn(PETSC_SUCCESS);
6449566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(name, &vascii->filename));
6455c6c1daeSBarry Smith 
6465c6c1daeSBarry Smith   /* Is this file to be compressed */
6475c6c1daeSBarry Smith   vascii->storecompressed = PETSC_FALSE;
648a297a907SKarl Rupp 
6499566063dSJacob Faibussowitsch   PetscCall(PetscStrstr(vascii->filename, ".gz", &gz));
6505c6c1daeSBarry Smith   if (gz) {
6519566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(gz, &len));
6525c6c1daeSBarry Smith     if (len == 3) {
65308401ef6SPierre 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");
6545c6c1daeSBarry Smith       *gz                     = 0;
6555c6c1daeSBarry Smith       vascii->storecompressed = PETSC_TRUE;
6565c6c1daeSBarry Smith     }
6575c6c1daeSBarry Smith   }
6589566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank));
659dd400576SPatrick Sanan   if (rank == 0) {
6609566063dSJacob Faibussowitsch     PetscCall(PetscStrcmp(name, "stderr", &isstderr));
6619566063dSJacob Faibussowitsch     PetscCall(PetscStrcmp(name, "stdout", &isstdout));
6625c6c1daeSBarry Smith     /* empty filename means stdout */
6635c6c1daeSBarry Smith     if (name[0] == 0) isstdout = PETSC_TRUE;
6645c6c1daeSBarry Smith     if (isstderr) vascii->fd = PETSC_STDERR;
6655c6c1daeSBarry Smith     else if (isstdout) vascii->fd = PETSC_STDOUT;
6665c6c1daeSBarry Smith     else {
6679566063dSJacob Faibussowitsch       PetscCall(PetscFixFilename(name, fname));
6685c6c1daeSBarry Smith       switch (vascii->mode) {
669d71ae5a4SJacob Faibussowitsch       case FILE_MODE_READ:
670d71ae5a4SJacob Faibussowitsch         vascii->fd = fopen(fname, "r");
671d71ae5a4SJacob Faibussowitsch         break;
672d71ae5a4SJacob Faibussowitsch       case FILE_MODE_WRITE:
673d71ae5a4SJacob Faibussowitsch         vascii->fd = fopen(fname, "w");
674d71ae5a4SJacob Faibussowitsch         break;
675d71ae5a4SJacob Faibussowitsch       case FILE_MODE_APPEND:
676d71ae5a4SJacob Faibussowitsch         vascii->fd = fopen(fname, "a");
677d71ae5a4SJacob Faibussowitsch         break;
6785c6c1daeSBarry Smith       case FILE_MODE_UPDATE:
6795c6c1daeSBarry Smith         vascii->fd = fopen(fname, "r+");
680a297a907SKarl Rupp         if (!vascii->fd) vascii->fd = fopen(fname, "w+");
6815c6c1daeSBarry Smith         break;
6825c6c1daeSBarry Smith       case FILE_MODE_APPEND_UPDATE:
6835c6c1daeSBarry Smith         /* I really want a file which is opened at the end for updating,
6845c6c1daeSBarry Smith            not a+, which opens at the beginning, but makes writes at the end.
6855c6c1daeSBarry Smith         */
6865c6c1daeSBarry Smith         vascii->fd = fopen(fname, "r+");
687a297a907SKarl Rupp         if (!vascii->fd) vascii->fd = fopen(fname, "w+");
6883ba16761SJacob Faibussowitsch         else {
6893ba16761SJacob Faibussowitsch           int ret = fseek(vascii->fd, 0, SEEK_END);
6903ba16761SJacob Faibussowitsch           PetscCheck(!ret, PETSC_COMM_SELF, PETSC_ERR_LIB, "fseek() failed with error code %d", ret);
6913ba16761SJacob Faibussowitsch         }
6925c6c1daeSBarry Smith         break;
693d71ae5a4SJacob Faibussowitsch       default:
694d71ae5a4SJacob Faibussowitsch         SETERRQ(PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Unsupported file mode %s", PetscFileModes[vascii->mode]);
6955c6c1daeSBarry Smith       }
69628b400f6SJacob Faibussowitsch       PetscCheck(vascii->fd, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Cannot open PetscViewer file: %s", fname);
6975c6c1daeSBarry Smith     }
6985c6c1daeSBarry Smith   }
6995c6c1daeSBarry Smith #if defined(PETSC_USE_LOG)
7003ba16761SJacob Faibussowitsch   PetscCall(PetscLogObjectState((PetscObject)viewer, "File: %s", name));
7015c6c1daeSBarry Smith #endif
7023ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7035c6c1daeSBarry Smith }
7045c6c1daeSBarry Smith 
705d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerGetSubViewer_ASCII(PetscViewer viewer, MPI_Comm subcomm, PetscViewer *outviewer)
706d71ae5a4SJacob Faibussowitsch {
7075c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data, *ovascii;
7085c6c1daeSBarry Smith 
7095c6c1daeSBarry Smith   PetscFunctionBegin;
7109566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPushSynchronized(viewer));
71128b400f6SJacob Faibussowitsch   PetscCheck(!vascii->sviewer, PETSC_COMM_SELF, PETSC_ERR_ORDER, "SubViewer already obtained from PetscViewer and not restored");
712e5afcf28SBarry Smith   /*
7139530cbd7SBarry Smith      The following line is a bug; it does another PetscViewerASCIIPushSynchronized() on viewer, but if it is removed the code won't work
7149530cbd7SBarry 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
7159530cbd7SBarry Smith      (since the count never gets to zero) in some examples this displays information that otherwise would be lost
7169530cbd7SBarry Smith 
7179530cbd7SBarry Smith      This code also means another call to PetscViewerASCIIPopSynchronized() must be made after the PetscViewerRestoreSubViewer(), see, for example,
7189530cbd7SBarry Smith      PCView_GASM().
719e5afcf28SBarry Smith   */
7209566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPushSynchronized(viewer));
7219566063dSJacob Faibussowitsch   PetscCall(PetscViewerCreate(subcomm, outviewer));
7229566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetType(*outviewer, PETSCVIEWERASCII));
7239566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPushSynchronized(*outviewer));
7245c6c1daeSBarry Smith   ovascii            = (PetscViewer_ASCII *)(*outviewer)->data;
7255c6c1daeSBarry Smith   ovascii->fd        = vascii->fd;
7265c6c1daeSBarry Smith   ovascii->tab       = vascii->tab;
727ba5a0b41SBarry Smith   ovascii->closefile = PETSC_FALSE;
7285c6c1daeSBarry Smith 
7295c6c1daeSBarry Smith   vascii->sviewer                                      = *outviewer;
7305c6c1daeSBarry Smith   (*outviewer)->format                                 = viewer->format;
7315c6c1daeSBarry Smith   ((PetscViewer_ASCII *)((*outviewer)->data))->bviewer = viewer;
7323f08860eSBarry Smith   (*outviewer)->ops->destroy                           = PetscViewerDestroy_ASCII_SubViewer;
7333ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7345c6c1daeSBarry Smith }
7355c6c1daeSBarry Smith 
736d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerRestoreSubViewer_ASCII(PetscViewer viewer, MPI_Comm comm, PetscViewer *outviewer)
737d71ae5a4SJacob Faibussowitsch {
7385c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
7395c6c1daeSBarry Smith 
7405c6c1daeSBarry Smith   PetscFunctionBegin;
74128b400f6SJacob Faibussowitsch   PetscCheck(ascii->sviewer, PETSC_COMM_SELF, PETSC_ERR_ORDER, "SubViewer never obtained from PetscViewer");
74208401ef6SPierre Jolivet   PetscCheck(ascii->sviewer == *outviewer, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "This PetscViewer did not generate this SubViewer");
7435c6c1daeSBarry Smith 
7449566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPopSynchronized(*outviewer));
745e5afcf28SBarry Smith   ascii->sviewer             = NULL;
7465c6c1daeSBarry Smith   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
7479566063dSJacob Faibussowitsch   PetscCall(PetscViewerDestroy(outviewer));
7489566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPopSynchronized(viewer));
7493ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7505c6c1daeSBarry Smith }
7515c6c1daeSBarry Smith 
752d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerView_ASCII(PetscViewer v, PetscViewer viewer)
753d71ae5a4SJacob Faibussowitsch {
7542bf49c77SBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)v->data;
7552bf49c77SBarry Smith 
7562bf49c77SBarry Smith   PetscFunctionBegin;
75748a46eb9SPierre Jolivet   if (ascii->filename) PetscCall(PetscViewerASCIIPrintf(viewer, "Filename: %s\n", ascii->filename));
7583ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7592bf49c77SBarry Smith }
7602bf49c77SBarry Smith 
7618556b5ebSBarry Smith /*MC
7628556b5ebSBarry Smith    PETSCVIEWERASCII - A viewer that prints to stdout or an ASCII file
7638556b5ebSBarry Smith 
764811af0c4SBarry Smith   Level: beginner
765811af0c4SBarry Smith 
766d1f92df0SBarry Smith .seealso: [](sec_viewers), `PETSC_VIEWER_STDOUT_()`, `PETSC_VIEWER_STDOUT_SELF`, `PETSC_VIEWER_STDOUT_WORLD`, `PetscViewerCreate()`, `PetscViewerASCIIOpen()`,
767db781477SPatrick Sanan           `PetscViewerMatlabOpen()`, `VecView()`, `DMView()`, `PetscViewerMatlabPutArray()`, `PETSCVIEWERBINARY`, `PETSCVIEWERMATLAB`,
768db781477SPatrick Sanan           `PetscViewerFileSetName()`, `PetscViewerFileSetMode()`, `PetscViewerFormat`, `PetscViewerType`, `PetscViewerSetType()`
7698556b5ebSBarry Smith M*/
770d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscViewerCreate_ASCII(PetscViewer viewer)
771d71ae5a4SJacob Faibussowitsch {
7725c6c1daeSBarry Smith   PetscViewer_ASCII *vascii;
7735c6c1daeSBarry Smith 
7745c6c1daeSBarry Smith   PetscFunctionBegin;
7754dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&vascii));
7765c6c1daeSBarry Smith   viewer->data = (void *)vascii;
7775c6c1daeSBarry Smith 
7785c6c1daeSBarry Smith   viewer->ops->destroy          = PetscViewerDestroy_ASCII;
7795c6c1daeSBarry Smith   viewer->ops->flush            = PetscViewerFlush_ASCII;
780559f443fSBarry Smith   viewer->ops->getsubviewer     = PetscViewerGetSubViewer_ASCII;
781559f443fSBarry Smith   viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_ASCII;
7822bf49c77SBarry Smith   viewer->ops->view             = PetscViewerView_ASCII;
7831d641e7bSMichael Lange   viewer->ops->read             = PetscViewerASCIIRead;
7845c6c1daeSBarry Smith 
7855c6c1daeSBarry Smith   /* defaults to stdout unless set with PetscViewerFileSetName() */
7865c6c1daeSBarry Smith   vascii->fd        = PETSC_STDOUT;
7875c6c1daeSBarry Smith   vascii->mode      = FILE_MODE_WRITE;
78802c9f0b5SLisandro Dalcin   vascii->bviewer   = NULL;
78902c9f0b5SLisandro Dalcin   vascii->subviewer = NULL;
79002c9f0b5SLisandro Dalcin   vascii->sviewer   = NULL;
7915c6c1daeSBarry Smith   vascii->tab       = 0;
7925c6c1daeSBarry Smith   vascii->tab_store = 0;
79302c9f0b5SLisandro Dalcin   vascii->filename  = NULL;
7945c6c1daeSBarry Smith   vascii->closefile = PETSC_TRUE;
7955c6c1daeSBarry Smith 
7969566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileSetName_C", PetscViewerFileSetName_ASCII));
7979566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileGetName_C", PetscViewerFileGetName_ASCII));
7989566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileGetMode_C", PetscViewerFileGetMode_ASCII));
7999566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileSetMode_C", PetscViewerFileSetMode_ASCII));
8003ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
8015c6c1daeSBarry Smith }
8025c6c1daeSBarry Smith 
8035c6c1daeSBarry Smith /*@C
8045c6c1daeSBarry Smith     PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from
8055c6c1daeSBarry Smith     several processors.  Output of the first processor is followed by that of the
8065c6c1daeSBarry Smith     second, etc.
8075c6c1daeSBarry Smith 
808811af0c4SBarry Smith     Not Collective, must call collective `PetscViewerFlush()` to get the results out
8095c6c1daeSBarry Smith 
8105c6c1daeSBarry Smith     Input Parameters:
811811af0c4SBarry Smith +   viewer - the `PETSCVIEWERASCII` `PetscViewer`
8125c6c1daeSBarry Smith -   format - the usual printf() format string
8135c6c1daeSBarry Smith 
8145c6c1daeSBarry Smith     Level: intermediate
8155c6c1daeSBarry Smith 
81695452b02SPatrick Sanan     Notes:
817811af0c4SBarry Smith     You must have previously called `PetscViewerASCIIPushSynchronized()` to allow this routine to be called.
818e6abc3ddSVáclav Hapla     Then you can do multiple independent calls to this routine.
819811af0c4SBarry Smith 
820811af0c4SBarry Smith     The actual synchronized print is then done using `PetscViewerFlush()`.
821811af0c4SBarry Smith     `PetscViewerASCIIPopSynchronized()` should be then called if we are already done with the synchronized output
822e6abc3ddSVáclav Hapla     to conclude the "synchronized session".
823811af0c4SBarry Smith 
824e6abc3ddSVáclav Hapla     So the typical calling sequence looks like
825811af0c4SBarry Smith .vb
826811af0c4SBarry Smith     PetscViewerASCIIPushSynchronized(viewer);
827811af0c4SBarry Smith     PetscViewerASCIISynchronizedPrintf(viewer, ...);
828811af0c4SBarry Smith     PetscViewerASCIISynchronizedPrintf(viewer, ...);
829811af0c4SBarry Smith     ...
830811af0c4SBarry Smith     PetscViewerFlush(viewer);
831811af0c4SBarry Smith     PetscViewerASCIISynchronizedPrintf(viewer, ...);
832811af0c4SBarry Smith     PetscViewerASCIISynchronizedPrintf(viewer, ...);
833811af0c4SBarry Smith     ...
834811af0c4SBarry Smith     PetscViewerFlush(viewer);
835811af0c4SBarry Smith    PetscViewerASCIIPopSynchronized(viewer);
836811af0c4SBarry Smith .ve
8375c6c1daeSBarry Smith 
8385c6c1daeSBarry Smith     Fortran Note:
8395c6c1daeSBarry Smith       Can only print a single character* string
8405c6c1daeSBarry Smith 
841d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscViewerASCIIPushSynchronized()`, `PetscViewerFlush()`, `PetscViewerASCIIPopSynchronized()`,
842db781477SPatrick Sanan           `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIIOpen()`,
843db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`
8445c6c1daeSBarry Smith @*/
845d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIISynchronizedPrintf(PetscViewer viewer, const char format[], ...)
846d71ae5a4SJacob Faibussowitsch {
8475c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
8483f08860eSBarry Smith   PetscMPIInt        rank;
8495c6c1daeSBarry Smith   PetscInt           tab = vascii->tab;
8505c6c1daeSBarry Smith   MPI_Comm           comm;
8515c6c1daeSBarry Smith   FILE              *fp;
852559f443fSBarry Smith   PetscBool          iascii, hasbviewer = PETSC_FALSE;
8535c6c1daeSBarry Smith 
8545c6c1daeSBarry Smith   PetscFunctionBegin;
8555c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
8565c6c1daeSBarry Smith   PetscValidCharPointer(format, 2);
8579566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
85828b400f6SJacob Faibussowitsch   PetscCheck(iascii, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Not ASCII PetscViewer");
85928b400f6SJacob Faibussowitsch   PetscCheck(vascii->allowsynchronized, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "First call PetscViewerASCIIPushSynchronized() to allow this call");
8605c6c1daeSBarry Smith 
8619566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
8629566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
8635c6c1daeSBarry Smith 
864559f443fSBarry Smith   if (vascii->bviewer) {
865559f443fSBarry Smith     hasbviewer = PETSC_TRUE;
866dd400576SPatrick Sanan     if (rank == 0) {
867559f443fSBarry Smith       vascii = (PetscViewer_ASCII *)vascii->bviewer->data;
8689566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
8699566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Comm_rank(comm, &rank));
870559f443fSBarry Smith     }
871559f443fSBarry Smith   }
8723f08860eSBarry Smith 
873559f443fSBarry Smith   fp = vascii->fd;
874559f443fSBarry Smith 
875dd400576SPatrick Sanan   if (rank == 0 && !hasbviewer) { /* First processor prints immediately to fp */
8765c6c1daeSBarry Smith     va_list Argp;
877559f443fSBarry Smith     /* flush my own messages that I may have queued up */
878559f443fSBarry Smith     PrintfQueue next = vascii->petsc_printfqueuebase, previous;
879559f443fSBarry Smith     PetscInt    i;
880559f443fSBarry Smith     for (i = 0; i < vascii->petsc_printfqueuelength; i++) {
8819566063dSJacob Faibussowitsch       PetscCall(PetscFPrintf(comm, fp, "%s", next->string));
882559f443fSBarry Smith       previous = next;
883559f443fSBarry Smith       next     = next->next;
8849566063dSJacob Faibussowitsch       PetscCall(PetscFree(previous->string));
8859566063dSJacob Faibussowitsch       PetscCall(PetscFree(previous));
886559f443fSBarry Smith     }
88702c9f0b5SLisandro Dalcin     vascii->petsc_printfqueue       = NULL;
888559f443fSBarry Smith     vascii->petsc_printfqueuelength = 0;
8895c6c1daeSBarry Smith 
89048a46eb9SPierre Jolivet     while (tab--) PetscCall(PetscFPrintf(PETSC_COMM_SELF, fp, "  "));
8915c6c1daeSBarry Smith 
8925c6c1daeSBarry Smith     va_start(Argp, format);
8939566063dSJacob Faibussowitsch     PetscCall((*PetscVFPrintf)(fp, format, Argp));
894*c69effb2SJacob Faibussowitsch     PetscCall(PetscFFlush(fp));
8955c6c1daeSBarry Smith     if (petsc_history) {
8965c6c1daeSBarry Smith       va_start(Argp, format);
8979566063dSJacob Faibussowitsch       PetscCall((*PetscVFPrintf)(petsc_history, format, Argp));
898*c69effb2SJacob Faibussowitsch       PetscCall(PetscFFlush(petsc_history));
8995c6c1daeSBarry Smith     }
9005c6c1daeSBarry Smith     va_end(Argp);
901559f443fSBarry Smith   } else { /* other processors add to queue */
9025c6c1daeSBarry Smith     char       *string;
9035c6c1daeSBarry Smith     va_list     Argp;
9045c6c1daeSBarry Smith     size_t      fullLength;
9055c6c1daeSBarry Smith     PrintfQueue next;
9065c6c1daeSBarry Smith 
9079566063dSJacob Faibussowitsch     PetscCall(PetscNew(&next));
908559f443fSBarry Smith     if (vascii->petsc_printfqueue) {
909559f443fSBarry Smith       vascii->petsc_printfqueue->next = next;
910559f443fSBarry Smith       vascii->petsc_printfqueue       = next;
911a297a907SKarl Rupp     } else {
912559f443fSBarry Smith       vascii->petsc_printfqueuebase = vascii->petsc_printfqueue = next;
913a297a907SKarl Rupp     }
914559f443fSBarry Smith     vascii->petsc_printfqueuelength++;
9155c6c1daeSBarry Smith     next->size = QUEUESTRINGSIZE;
9169566063dSJacob Faibussowitsch     PetscCall(PetscCalloc1(next->size, &next->string));
9175c6c1daeSBarry Smith     string = next->string;
9185c6c1daeSBarry Smith     tab *= 2;
919ad540459SPierre Jolivet     while (tab--) *string++ = ' ';
9205c6c1daeSBarry Smith     va_start(Argp, format);
9219566063dSJacob Faibussowitsch     PetscCall(PetscVSNPrintf(string, next->size - 2 * vascii->tab, format, &fullLength, Argp));
9225c6c1daeSBarry Smith     va_end(Argp);
923cb500232SBarry Smith     if (fullLength > (size_t)(next->size - 2 * vascii->tab)) {
9249566063dSJacob Faibussowitsch       PetscCall(PetscFree(next->string));
92514416c0eSBarry Smith       next->size = fullLength + 2 * vascii->tab;
9269566063dSJacob Faibussowitsch       PetscCall(PetscCalloc1(next->size, &next->string));
92714416c0eSBarry Smith       string = next->string;
92814416c0eSBarry Smith       tab    = 2 * vascii->tab;
929ad540459SPierre Jolivet       while (tab--) *string++ = ' ';
93014416c0eSBarry Smith       va_start(Argp, format);
9319566063dSJacob Faibussowitsch       PetscCall(PetscVSNPrintf(string, next->size - 2 * vascii->tab, format, NULL, Argp));
93214416c0eSBarry Smith       va_end(Argp);
93314416c0eSBarry Smith     }
9345c6c1daeSBarry Smith   }
9353ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9365c6c1daeSBarry Smith }
9375c6c1daeSBarry Smith 
9382655f987SMichael Lange /*@C
939f8859db6SBarry Smith    PetscViewerASCIIRead - Reads from a ASCII file
9402655f987SMichael Lange 
941811af0c4SBarry Smith    Only process 0 in the `PetscViewer` may call this
9422655f987SMichael Lange 
9432655f987SMichael Lange    Input Parameters:
9442655f987SMichael Lange +  viewer - the ascii viewer
9452655f987SMichael Lange .  data - location to write the data
946060da220SMatthew G. Knepley .  num - number of items of data to read
9472655f987SMichael Lange -  datatype - type of data to read
9482655f987SMichael Lange 
949f8e4bde8SMatthew G. Knepley    Output Parameters:
950060da220SMatthew G. Knepley .  count - number of items of data actually read, or NULL
951f8e4bde8SMatthew G. Knepley 
9522655f987SMichael Lange    Level: beginner
9532655f987SMichael Lange 
954d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscViewerASCIIOpen()`, `PetscViewerPushFormat()`, `PetscViewerDestroy()`, `PetscViewerCreate()`, `PetscViewerFileSetMode()`, `PetscViewerFileSetName()`
955db781477SPatrick Sanan           `VecView()`, `MatView()`, `VecLoad()`, `MatLoad()`, `PetscViewerBinaryGetDescriptor()`,
956db781477SPatrick Sanan           `PetscViewerBinaryGetInfoPointer()`, `PetscFileMode`, `PetscViewer`, `PetscViewerBinaryRead()`
9572655f987SMichael Lange @*/
958d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIIRead(PetscViewer viewer, void *data, PetscInt num, PetscInt *count, PetscDataType dtype)
959d71ae5a4SJacob Faibussowitsch {
9602655f987SMichael Lange   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
9612655f987SMichael Lange   FILE              *fd     = vascii->fd;
9622655f987SMichael Lange   PetscInt           i;
9633b7fe8c3SMatthew G. Knepley   int                ret = 0;
964f8859db6SBarry Smith   PetscMPIInt        rank;
9652655f987SMichael Lange 
9662655f987SMichael Lange   PetscFunctionBegin;
9672655f987SMichael Lange   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
9689566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank));
969c5853193SPierre Jolivet   PetscCheck(rank == 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Can only be called from process 0 in the PetscViewer");
970060da220SMatthew G. Knepley   for (i = 0; i < num; i++) {
971f8e4bde8SMatthew G. Knepley     if (dtype == PETSC_CHAR) ret = fscanf(fd, "%c", &(((char *)data)[i]));
972f8e4bde8SMatthew G. Knepley     else if (dtype == PETSC_STRING) ret = fscanf(fd, "%s", &(((char *)data)[i]));
973a05e1a72SSatish Balay     else if (dtype == PETSC_INT) ret = fscanf(fd, "%" PetscInt_FMT, &(((PetscInt *)data)[i]));
974f8e4bde8SMatthew G. Knepley     else if (dtype == PETSC_ENUM) ret = fscanf(fd, "%d", &(((int *)data)[i]));
9759e3e4c22SLisandro Dalcin     else if (dtype == PETSC_INT64) ret = fscanf(fd, "%" PetscInt64_FMT, &(((PetscInt64 *)data)[i]));
976972064b6SLisandro Dalcin     else if (dtype == PETSC_LONG) ret = fscanf(fd, "%ld", &(((long *)data)[i]));
977f8e4bde8SMatthew G. Knepley     else if (dtype == PETSC_FLOAT) ret = fscanf(fd, "%f", &(((float *)data)[i]));
978f8e4bde8SMatthew G. Knepley     else if (dtype == PETSC_DOUBLE) ret = fscanf(fd, "%lg", &(((double *)data)[i]));
979a6e181c6SToby Isaac #if defined(PETSC_USE_REAL___FLOAT128)
980fba955ccSBarry Smith     else if (dtype == PETSC___FLOAT128) {
981fba955ccSBarry Smith       double tmp;
982fba955ccSBarry Smith       ret                     = fscanf(fd, "%lg", &tmp);
983a6e181c6SToby Isaac       ((__float128 *)data)[i] = tmp;
984a6e181c6SToby Isaac     }
985fba955ccSBarry Smith #endif
9869371c9d4SSatish Balay     else
9879371c9d4SSatish Balay       SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Data type %d not supported", (int)dtype);
98828b400f6SJacob Faibussowitsch     PetscCheck(ret, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Conversion error for data type %d", (int)dtype);
989f7d195e4SLawrence Mitchell     if (ret < 0) break; /* Proxy for EOF, need to check for it in configure */
9902655f987SMichael Lange   }
991060da220SMatthew G. Knepley   if (count) *count = i;
99208401ef6SPierre Jolivet   else PetscCheck(ret >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Insufficient data, read only %" PetscInt_FMT " < %" PetscInt_FMT " items", i, num);
9933ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9942655f987SMichael Lange }
995