xref: /petsc/src/sys/classes/viewer/impls/ascii/filev.c (revision 3ba1676111f5c958fe6c2729b46ca4d523958bb3)
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));
35*3ba16761SJacob 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));
88*3ba16761SJacob 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));
97*3ba16761SJacob 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;
1035c6c1daeSBarry Smith   int                err;
104559f443fSBarry Smith   MPI_Comm           comm;
105559f443fSBarry Smith   PetscMPIInt        rank, size;
106559f443fSBarry Smith   FILE              *fd = vascii->fd;
1075c6c1daeSBarry Smith 
1085c6c1daeSBarry Smith   PetscFunctionBegin;
10928b400f6SJacob Faibussowitsch   PetscCheck(!vascii->sviewer, PetscObjectComm((PetscObject)viewer), PETSC_ERR_ARG_WRONGSTATE, "Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
1109566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
1119566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
1129566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(comm, &size));
113559f443fSBarry Smith 
114dd400576SPatrick Sanan   if (!vascii->bviewer && rank == 0 && (vascii->mode != FILE_MODE_READ)) {
1155c6c1daeSBarry Smith     err = fflush(vascii->fd);
11628b400f6SJacob Faibussowitsch     PetscCheck(!err, PETSC_COMM_SELF, PETSC_ERR_SYS, "fflush() call failed");
1175c6c1daeSBarry Smith   }
1185c6c1daeSBarry Smith 
1195c6c1daeSBarry Smith   if (vascii->allowsynchronized) {
120559f443fSBarry Smith     PetscMPIInt tag, i, j, n = 0, dummy = 0;
121559f443fSBarry Smith     char       *message;
122559f443fSBarry Smith     MPI_Status  status;
123559f443fSBarry Smith 
1249566063dSJacob Faibussowitsch     PetscCall(PetscCommDuplicate(comm, &comm, &tag));
125559f443fSBarry Smith 
126559f443fSBarry Smith     /* First processor waits for messages from all other processors */
127dd400576SPatrick Sanan     if (rank == 0) {
128559f443fSBarry Smith       /* flush my own messages that I may have queued up */
129559f443fSBarry Smith       PrintfQueue next = vascii->petsc_printfqueuebase, previous;
130559f443fSBarry Smith       for (i = 0; i < vascii->petsc_printfqueuelength; i++) {
131559f443fSBarry Smith         if (!vascii->bviewer) {
1329566063dSJacob Faibussowitsch           PetscCall(PetscFPrintf(comm, fd, "%s", next->string));
133559f443fSBarry Smith         } else {
1349566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIISynchronizedPrintf(vascii->bviewer, "%s", next->string));
135559f443fSBarry Smith         }
136559f443fSBarry Smith         previous = next;
137559f443fSBarry Smith         next     = next->next;
1389566063dSJacob Faibussowitsch         PetscCall(PetscFree(previous->string));
1399566063dSJacob Faibussowitsch         PetscCall(PetscFree(previous));
140559f443fSBarry Smith       }
14102c9f0b5SLisandro Dalcin       vascii->petsc_printfqueue       = NULL;
142559f443fSBarry Smith       vascii->petsc_printfqueuelength = 0;
143559f443fSBarry Smith       for (i = 1; i < size; i++) {
144559f443fSBarry Smith         /* to prevent a flood of messages to process zero, request each message separately */
1459566063dSJacob Faibussowitsch         PetscCallMPI(MPI_Send(&dummy, 1, MPI_INT, i, tag, comm));
1469566063dSJacob Faibussowitsch         PetscCallMPI(MPI_Recv(&n, 1, MPI_INT, i, tag, comm, &status));
147559f443fSBarry Smith         for (j = 0; j < n; j++) {
148559f443fSBarry Smith           PetscMPIInt size = 0;
149559f443fSBarry Smith 
1509566063dSJacob Faibussowitsch           PetscCallMPI(MPI_Recv(&size, 1, MPI_INT, i, tag, comm, &status));
1519566063dSJacob Faibussowitsch           PetscCall(PetscMalloc1(size, &message));
1529566063dSJacob Faibussowitsch           PetscCallMPI(MPI_Recv(message, size, MPI_CHAR, i, tag, comm, &status));
153559f443fSBarry Smith           if (!vascii->bviewer) {
1549566063dSJacob Faibussowitsch             PetscCall(PetscFPrintf(comm, fd, "%s", message));
155559f443fSBarry Smith           } else {
1569566063dSJacob Faibussowitsch             PetscCall(PetscViewerASCIISynchronizedPrintf(vascii->bviewer, "%s", message));
157559f443fSBarry Smith           }
1589566063dSJacob Faibussowitsch           PetscCall(PetscFree(message));
159559f443fSBarry Smith         }
160559f443fSBarry Smith       }
161559f443fSBarry Smith     } else { /* other processors send queue to processor 0 */
162559f443fSBarry Smith       PrintfQueue next = vascii->petsc_printfqueuebase, previous;
163559f443fSBarry Smith 
1649566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Recv(&dummy, 1, MPI_INT, 0, tag, comm, &status));
1659566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Send(&vascii->petsc_printfqueuelength, 1, MPI_INT, 0, tag, comm));
166559f443fSBarry Smith       for (i = 0; i < vascii->petsc_printfqueuelength; i++) {
1679566063dSJacob Faibussowitsch         PetscCallMPI(MPI_Send(&next->size, 1, MPI_INT, 0, tag, comm));
1689566063dSJacob Faibussowitsch         PetscCallMPI(MPI_Send(next->string, next->size, MPI_CHAR, 0, tag, comm));
169559f443fSBarry Smith         previous = next;
170559f443fSBarry Smith         next     = next->next;
1719566063dSJacob Faibussowitsch         PetscCall(PetscFree(previous->string));
1729566063dSJacob Faibussowitsch         PetscCall(PetscFree(previous));
173559f443fSBarry Smith       }
17402c9f0b5SLisandro Dalcin       vascii->petsc_printfqueue       = NULL;
175559f443fSBarry Smith       vascii->petsc_printfqueuelength = 0;
176559f443fSBarry Smith     }
1779566063dSJacob Faibussowitsch     PetscCall(PetscCommDestroy(&comm));
1785c6c1daeSBarry Smith   }
179*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1805c6c1daeSBarry Smith }
1815c6c1daeSBarry Smith 
1825c6c1daeSBarry Smith /*@C
183811af0c4SBarry Smith     PetscViewerASCIIGetPointer - Extracts the file pointer from an ASCII `PetscViewer`.
1845c6c1daeSBarry Smith 
18535cb6cd3SPierre Jolivet     Not Collective, depending on the viewer the value may be meaningless except for process 0 of the viewer; No Fortran Support
1865c6c1daeSBarry Smith 
187f8859db6SBarry Smith     Input Parameter:
188811af0c4SBarry Smith .    viewer - PetscViewer context, obtained from `PetscViewerASCIIOpen()`
189f8859db6SBarry Smith 
190f8859db6SBarry Smith     Output Parameter:
191f8859db6SBarry Smith .    fd - file pointer
192f8859db6SBarry Smith 
1935c6c1daeSBarry Smith     Level: intermediate
1945c6c1daeSBarry Smith 
195811af0c4SBarry Smith     Note:
196811af0c4SBarry Smith     For the standard `PETSCVIEWERASCII` the value is valid only on process 0 of the viewer
197811af0c4SBarry Smith 
198d1f92df0SBarry Smith .seealso: [](sec_viewers), `PETSCVIEWERASCII`, `PetscViewerASCIIOpen()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerCreate()`, `PetscViewerASCIIPrintf()`,
199db781477SPatrick Sanan           `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerFlush()`
2005c6c1daeSBarry Smith @*/
201d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIIGetPointer(PetscViewer viewer, FILE **fd)
202d71ae5a4SJacob Faibussowitsch {
2035c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
2045c6c1daeSBarry Smith 
2055c6c1daeSBarry Smith   PetscFunctionBegin;
2065c6c1daeSBarry Smith   *fd = vascii->fd;
207*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2085c6c1daeSBarry Smith }
2095c6c1daeSBarry Smith 
210d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerFileGetMode_ASCII(PetscViewer viewer, PetscFileMode *mode)
211d71ae5a4SJacob Faibussowitsch {
2125c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
2135c6c1daeSBarry Smith 
2145c6c1daeSBarry Smith   PetscFunctionBegin;
2155c6c1daeSBarry Smith   *mode = vascii->mode;
216*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2175c6c1daeSBarry Smith }
2185c6c1daeSBarry Smith 
219d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerFileSetMode_ASCII(PetscViewer viewer, PetscFileMode mode)
220d71ae5a4SJacob Faibussowitsch {
2215c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
2225c6c1daeSBarry Smith 
2235c6c1daeSBarry Smith   PetscFunctionBegin;
2245c6c1daeSBarry Smith   vascii->mode = mode;
225*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2265c6c1daeSBarry Smith }
2275c6c1daeSBarry Smith 
2285c6c1daeSBarry Smith /*
2295c6c1daeSBarry Smith    If petsc_history is on, then all Petsc*Printf() results are saved
2305c6c1daeSBarry Smith    if the appropriate (usually .petschistory) file.
2315c6c1daeSBarry Smith */
23295c0884eSLisandro Dalcin PETSC_INTERN FILE *petsc_history;
2335c6c1daeSBarry Smith 
2345c6c1daeSBarry Smith /*@
235811af0c4SBarry Smith     PetscViewerASCIISetTab - Causes `PetscViewer` to tab in a number of times
2365c6c1daeSBarry Smith 
237cf53795eSBarry Smith     Not Collective, but only first processor in set has any effect; No Fortran Support
2385c6c1daeSBarry Smith 
2395c6c1daeSBarry Smith     Input Parameters:
240811af0c4SBarry Smith +    viewer - obtained with `PetscViewerASCIIOpen()`
2415c6c1daeSBarry Smith -    tabs - number of tabs
2425c6c1daeSBarry Smith 
2435c6c1daeSBarry Smith     Level: developer
2445c6c1daeSBarry Smith 
245d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIIGetTab()`,
246db781477SPatrick Sanan           `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIOpen()`,
247db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`, `PetscViewerASCIIPushTab()`
2485c6c1daeSBarry Smith @*/
249d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIISetTab(PetscViewer viewer, PetscInt tabs)
250d71ae5a4SJacob Faibussowitsch {
2515c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
2525c6c1daeSBarry Smith   PetscBool          iascii;
2535c6c1daeSBarry Smith 
2545c6c1daeSBarry Smith   PetscFunctionBegin;
2555c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
2569566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
257a297a907SKarl Rupp   if (iascii) ascii->tab = tabs;
258*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2595c6c1daeSBarry Smith }
2605c6c1daeSBarry Smith 
2615c6c1daeSBarry Smith /*@
262811af0c4SBarry Smith     PetscViewerASCIIGetTab - Return the number of tabs used by `PetscViewer`.
2635c6c1daeSBarry Smith 
264cf53795eSBarry Smith     Not Collective, meaningful on first processor only; No Fortran Support
2655c6c1daeSBarry Smith 
2665c6c1daeSBarry Smith     Input Parameters:
267811af0c4SBarry Smith .    viewer - obtained with `PetscViewerASCIIOpen()`
268a2b725a8SWilliam Gropp 
2695c6c1daeSBarry Smith     Output Parameters:
2705c6c1daeSBarry Smith .    tabs - number of tabs
2715c6c1daeSBarry Smith 
2725c6c1daeSBarry Smith     Level: developer
2735c6c1daeSBarry Smith 
274d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIISetTab()`,
275db781477SPatrick Sanan           `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIOpen()`,
276db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`, `PetscViewerASCIIPushTab()`
2775c6c1daeSBarry Smith @*/
278d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIIGetTab(PetscViewer viewer, PetscInt *tabs)
279d71ae5a4SJacob Faibussowitsch {
2805c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
2815c6c1daeSBarry Smith   PetscBool          iascii;
2825c6c1daeSBarry Smith 
2835c6c1daeSBarry Smith   PetscFunctionBegin;
2845c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
2859566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
286a297a907SKarl Rupp   if (iascii && tabs) *tabs = ascii->tab;
287*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2885c6c1daeSBarry Smith }
2895c6c1daeSBarry Smith 
2905c6c1daeSBarry Smith /*@
2915c6c1daeSBarry Smith     PetscViewerASCIIAddTab - Add to the number of times an ASCII viewer tabs before printing
2925c6c1daeSBarry Smith 
293cf53795eSBarry Smith     Not Collective, but only first processor in set has any effect; No Fortran Support
2945c6c1daeSBarry Smith 
2955c6c1daeSBarry Smith     Input Parameters:
296811af0c4SBarry Smith +    viewer - obtained with `PetscViewerASCIIOpen()`
2975c6c1daeSBarry Smith -    tabs - number of tabs
2985c6c1daeSBarry Smith 
2995c6c1daeSBarry Smith     Level: developer
3005c6c1daeSBarry Smith 
301d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`,
302db781477SPatrick Sanan           `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIOpen()`,
303db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`, `PetscViewerASCIIPushTab()`
3045c6c1daeSBarry Smith @*/
305d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIIAddTab(PetscViewer viewer, PetscInt tabs)
306d71ae5a4SJacob Faibussowitsch {
3075c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
3085c6c1daeSBarry Smith   PetscBool          iascii;
3095c6c1daeSBarry Smith 
3105c6c1daeSBarry Smith   PetscFunctionBegin;
3115c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
3129566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
313a297a907SKarl Rupp   if (iascii) ascii->tab += tabs;
314*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3155c6c1daeSBarry Smith }
3165c6c1daeSBarry Smith 
3175c6c1daeSBarry Smith /*@
3185c6c1daeSBarry Smith     PetscViewerASCIISubtractTab - Subtracts from the number of times an ASCII viewer tabs before printing
3195c6c1daeSBarry Smith 
320cf53795eSBarry Smith     Not Collective, but only first processor in set has any effect; No Fortran Support
3215c6c1daeSBarry Smith 
3225c6c1daeSBarry Smith     Input Parameters:
323811af0c4SBarry Smith +    viewer - obtained with `PetscViewerASCIIOpen()`
3245c6c1daeSBarry Smith -    tabs - number of tabs
3255c6c1daeSBarry Smith 
3265c6c1daeSBarry Smith     Level: developer
3275c6c1daeSBarry Smith 
328d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`,
329db781477SPatrick Sanan           `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIOpen()`,
330db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`, `PetscViewerASCIIPushTab()`
3315c6c1daeSBarry Smith @*/
332d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIISubtractTab(PetscViewer viewer, PetscInt tabs)
333d71ae5a4SJacob Faibussowitsch {
3345c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
3355c6c1daeSBarry Smith   PetscBool          iascii;
3365c6c1daeSBarry Smith 
3375c6c1daeSBarry Smith   PetscFunctionBegin;
3385c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
3399566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
340a297a907SKarl Rupp   if (iascii) ascii->tab -= tabs;
341*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3425c6c1daeSBarry Smith }
3435c6c1daeSBarry Smith 
3445c6c1daeSBarry Smith /*@C
345811af0c4SBarry Smith     PetscViewerASCIIPushSynchronized - Allows calls to `PetscViewerASCIISynchronizedPrintf()` for this viewer
3465c6c1daeSBarry Smith 
347c3339decSBarry Smith     Collective
3485c6c1daeSBarry Smith 
3495c6c1daeSBarry Smith     Input Parameters:
350811af0c4SBarry Smith .    viewer - obtained with `PetscViewerASCIIOpen()`
3515c6c1daeSBarry Smith 
3525c6c1daeSBarry Smith     Level: intermediate
3535c6c1daeSBarry Smith 
354811af0c4SBarry Smith     Note:
355811af0c4SBarry Smith     See documentation of `PetscViewerASCIISynchronizedPrintf()` for more details how the synchronized output should be done properly.
3565c6c1daeSBarry Smith 
357d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerFlush()`, `PetscViewerASCIIPopSynchronized()`,
358db781477SPatrick Sanan           `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIIOpen()`,
359db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`
3605c6c1daeSBarry Smith @*/
361d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIIPushSynchronized(PetscViewer viewer)
362d71ae5a4SJacob Faibussowitsch {
3635c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
3645c6c1daeSBarry Smith   PetscBool          iascii;
3655c6c1daeSBarry Smith 
3665c6c1daeSBarry Smith   PetscFunctionBegin;
3675c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
36828b400f6SJacob Faibussowitsch   PetscCheck(!ascii->sviewer, PetscObjectComm((PetscObject)viewer), PETSC_ERR_ARG_WRONGSTATE, "Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
3699566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
3701575c14dSBarry Smith   if (iascii) ascii->allowsynchronized++;
371*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3721575c14dSBarry Smith }
3731575c14dSBarry Smith 
3741575c14dSBarry Smith /*@C
375811af0c4SBarry Smith     PetscViewerASCIIPopSynchronized - Undoes most recent `PetscViewerASCIIPushSynchronized()` for this viewer
3761575c14dSBarry Smith 
377c3339decSBarry Smith     Collective
3781575c14dSBarry Smith 
3791575c14dSBarry Smith     Input Parameters:
380811af0c4SBarry Smith .    viewer - obtained with `PetscViewerASCIIOpen()`
3811575c14dSBarry Smith 
3821575c14dSBarry Smith     Level: intermediate
3831575c14dSBarry Smith 
384811af0c4SBarry Smith     Note:
385811af0c4SBarry Smith     See documentation of `PetscViewerASCIISynchronizedPrintf()` for more details how the synchronized output should be done properly.
3861575c14dSBarry Smith 
387d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscViewerASCIIPushSynchronized()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerFlush()`,
388db781477SPatrick Sanan           `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIIOpen()`,
389db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`
3901575c14dSBarry Smith @*/
391d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIIPopSynchronized(PetscViewer viewer)
392d71ae5a4SJacob Faibussowitsch {
3931575c14dSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
3941575c14dSBarry Smith   PetscBool          iascii;
3951575c14dSBarry Smith 
3961575c14dSBarry Smith   PetscFunctionBegin;
3971575c14dSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
39828b400f6SJacob Faibussowitsch   PetscCheck(!ascii->sviewer, PetscObjectComm((PetscObject)viewer), PETSC_ERR_ARG_WRONGSTATE, "Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
3999566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
4001575c14dSBarry Smith   if (iascii) {
4011575c14dSBarry Smith     ascii->allowsynchronized--;
40208401ef6SPierre Jolivet     PetscCheck(ascii->allowsynchronized >= 0, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Called more times than PetscViewerASCIIPushSynchronized()");
4031575c14dSBarry Smith   }
404*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4055c6c1daeSBarry Smith }
4065c6c1daeSBarry Smith 
4071c297824SMatthew G. Knepley /*@C
408811af0c4SBarry Smith     PetscViewerASCIIPushTab - Adds one more tab to the amount that `PetscViewerASCIIPrintf()`
4095c6c1daeSBarry Smith      lines are tabbed.
4105c6c1daeSBarry Smith 
411cf53795eSBarry Smith     Not Collective, but only first processor in set has any effect; No Fortran Support
4125c6c1daeSBarry Smith 
4135c6c1daeSBarry Smith     Input Parameters:
414811af0c4SBarry Smith .    viewer - obtained with `PetscViewerASCIIOpen()`
4155c6c1daeSBarry Smith 
4165c6c1daeSBarry Smith     Level: developer
4175c6c1daeSBarry Smith 
418d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`,
419db781477SPatrick Sanan           `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIOpen()`,
420db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`
4215c6c1daeSBarry Smith @*/
422d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIIPushTab(PetscViewer viewer)
423d71ae5a4SJacob Faibussowitsch {
4245c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
4255c6c1daeSBarry Smith   PetscBool          iascii;
4265c6c1daeSBarry Smith 
4275c6c1daeSBarry Smith   PetscFunctionBegin;
4285c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
4299566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
430a297a907SKarl Rupp   if (iascii) ascii->tab++;
431*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4325c6c1daeSBarry Smith }
4335c6c1daeSBarry Smith 
4341c297824SMatthew G. Knepley /*@C
435811af0c4SBarry Smith     PetscViewerASCIIPopTab - Removes one tab from the amount that `PetscViewerASCIIPrintf()` lines are tabbed that was provided by `PetscViewerASCIIPushTab()`
4365c6c1daeSBarry Smith 
437cf53795eSBarry Smith     Not Collective, but only first processor in set has any effect; No Fortran Support
4385c6c1daeSBarry Smith 
4395c6c1daeSBarry Smith     Input Parameters:
440811af0c4SBarry Smith .    viewer - obtained with `PetscViewerASCIIOpen()`
4415c6c1daeSBarry Smith 
4425c6c1daeSBarry Smith     Level: developer
4435c6c1daeSBarry Smith 
444d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`,
445db781477SPatrick Sanan           `PetscViewerASCIIPushTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIOpen()`,
446db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`
4475c6c1daeSBarry Smith @*/
448d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIIPopTab(PetscViewer viewer)
449d71ae5a4SJacob Faibussowitsch {
4505c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
4515c6c1daeSBarry Smith   PetscBool          iascii;
4525c6c1daeSBarry Smith 
4535c6c1daeSBarry Smith   PetscFunctionBegin;
4545c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
4559566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
4565c6c1daeSBarry Smith   if (iascii) {
45708401ef6SPierre Jolivet     PetscCheck(ascii->tab > 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "More tabs popped than pushed");
4585c6c1daeSBarry Smith     ascii->tab--;
4595c6c1daeSBarry Smith   }
460*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4615c6c1daeSBarry Smith }
4625c6c1daeSBarry Smith 
4635c6c1daeSBarry Smith /*@
464811af0c4SBarry Smith     PetscViewerASCIIUseTabs - Turns on or off the use of tabs with the ASCII `PetscViewer`
4655c6c1daeSBarry Smith 
466cf53795eSBarry Smith     Not Collective, but only first processor in set has any effect; No Fortran Support
4675c6c1daeSBarry Smith 
4685c6c1daeSBarry Smith     Input Parameters:
469811af0c4SBarry Smith +    viewer - obtained with `PetscViewerASCIIOpen()`
470811af0c4SBarry Smith -    flg - `PETSC_TRUE` or `PETSC_FALSE`
4715c6c1daeSBarry Smith 
4725c6c1daeSBarry Smith     Level: developer
4735c6c1daeSBarry Smith 
474d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`,
475db781477SPatrick Sanan           `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIPushTab()`, `PetscViewerASCIIOpen()`,
476db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`
4775c6c1daeSBarry Smith @*/
478d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIIUseTabs(PetscViewer viewer, PetscBool flg)
479d71ae5a4SJacob Faibussowitsch {
4805c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
4815c6c1daeSBarry Smith   PetscBool          iascii;
4825c6c1daeSBarry Smith 
4835c6c1daeSBarry Smith   PetscFunctionBegin;
4845c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
4859566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
4865c6c1daeSBarry Smith   if (iascii) {
487a297a907SKarl Rupp     if (flg) ascii->tab = ascii->tab_store;
488a297a907SKarl Rupp     else {
4895c6c1daeSBarry Smith       ascii->tab_store = ascii->tab;
4905c6c1daeSBarry Smith       ascii->tab       = 0;
4915c6c1daeSBarry Smith     }
4925c6c1daeSBarry Smith   }
493*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4945c6c1daeSBarry Smith }
4955c6c1daeSBarry Smith 
4965c6c1daeSBarry Smith /* ----------------------------------------------------------------------- */
4975c6c1daeSBarry Smith 
4985c6c1daeSBarry Smith /*@C
4995c6c1daeSBarry Smith     PetscViewerASCIIPrintf - Prints to a file, only from the first
5005c6c1daeSBarry Smith     processor in the PetscViewer
5015c6c1daeSBarry Smith 
5025c6c1daeSBarry Smith     Not Collective, but only first processor in set has any effect
5035c6c1daeSBarry Smith 
5045c6c1daeSBarry Smith     Input Parameters:
505811af0c4SBarry Smith +    viewer - obtained with `PetscViewerASCIIOpen()`
5065c6c1daeSBarry Smith -    format - the usual printf() format string
5075c6c1daeSBarry Smith 
5085c6c1daeSBarry Smith     Level: developer
5095c6c1daeSBarry Smith 
5105c6c1daeSBarry Smith     Fortran Note:
511811af0c4SBarry Smith     The call sequence is `PetscViewerASCIIPrintf`(PetscViewer, character(*), int ierr) from Fortran.
5125c6c1daeSBarry Smith     That is, you can only pass a single character string from Fortran.
5135c6c1daeSBarry Smith 
514d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIOpen()`,
515db781477SPatrick Sanan           `PetscViewerASCIIPushTab()`, `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`,
516db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`, `PetscViewerASCIIPushSynchronized()`
5175c6c1daeSBarry Smith @*/
518d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIIPrintf(PetscViewer viewer, const char format[], ...)
519d71ae5a4SJacob Faibussowitsch {
5205c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
5215c6c1daeSBarry Smith   PetscMPIInt        rank;
522dd2fa690SBarry Smith   PetscInt           tab, intab = ascii->tab;
5235c6c1daeSBarry Smith   FILE              *fd = ascii->fd;
5243f08860eSBarry Smith   PetscBool          iascii;
5255c6c1daeSBarry Smith   int                err;
5265c6c1daeSBarry Smith 
5275c6c1daeSBarry Smith   PetscFunctionBegin;
5285c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
52928b400f6SJacob Faibussowitsch   PetscCheck(!ascii->sviewer, PetscObjectComm((PetscObject)viewer), PETSC_ERR_ARG_WRONGSTATE, "Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
5305c6c1daeSBarry Smith   PetscValidCharPointer(format, 2);
5319566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
53228b400f6SJacob Faibussowitsch   PetscCheck(iascii, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Not ASCII PetscViewer");
5339566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank));
534*3ba16761SJacob Faibussowitsch   if (rank) PetscFunctionReturn(PETSC_SUCCESS);
5353f08860eSBarry Smith 
5363f08860eSBarry Smith   if (ascii->bviewer) { /* pass string up to parent viewer */
5373f08860eSBarry Smith     char   *string;
5383f08860eSBarry Smith     va_list Argp;
5393f08860eSBarry Smith     size_t  fullLength;
5403f08860eSBarry Smith 
5419566063dSJacob Faibussowitsch     PetscCall(PetscCalloc1(QUEUESTRINGSIZE, &string));
5423f08860eSBarry Smith     va_start(Argp, format);
5439566063dSJacob Faibussowitsch     PetscCall(PetscVSNPrintf(string, QUEUESTRINGSIZE, format, &fullLength, Argp));
5443f08860eSBarry Smith     va_end(Argp);
5459566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "%s", string));
5469566063dSJacob Faibussowitsch     PetscCall(PetscFree(string));
5473f08860eSBarry Smith   } else { /* write directly to file */
5485c6c1daeSBarry Smith     va_list Argp;
549559f443fSBarry Smith     /* flush my own messages that I may have queued up */
550559f443fSBarry Smith     PrintfQueue next = ascii->petsc_printfqueuebase, previous;
551559f443fSBarry Smith     PetscInt    i;
552559f443fSBarry Smith     for (i = 0; i < ascii->petsc_printfqueuelength; i++) {
5539566063dSJacob Faibussowitsch       PetscCall(PetscFPrintf(PETSC_COMM_SELF, fd, "%s", next->string));
554559f443fSBarry Smith       previous = next;
555559f443fSBarry Smith       next     = next->next;
5569566063dSJacob Faibussowitsch       PetscCall(PetscFree(previous->string));
5579566063dSJacob Faibussowitsch       PetscCall(PetscFree(previous));
558559f443fSBarry Smith     }
55902c9f0b5SLisandro Dalcin     ascii->petsc_printfqueue       = NULL;
560559f443fSBarry Smith     ascii->petsc_printfqueuelength = 0;
561dd2fa690SBarry Smith     tab                            = intab;
56248a46eb9SPierre Jolivet     while (tab--) PetscCall(PetscFPrintf(PETSC_COMM_SELF, fd, "  "));
5635c6c1daeSBarry Smith 
5645c6c1daeSBarry Smith     va_start(Argp, format);
5659566063dSJacob Faibussowitsch     PetscCall((*PetscVFPrintf)(fd, format, Argp));
5665c6c1daeSBarry Smith     err = fflush(fd);
56728b400f6SJacob Faibussowitsch     PetscCheck(!err, PETSC_COMM_SELF, PETSC_ERR_SYS, "fflush() failed on file");
5685c6c1daeSBarry Smith     if (petsc_history) {
5695c6c1daeSBarry Smith       va_start(Argp, format);
570dd2fa690SBarry Smith       tab = intab;
57148a46eb9SPierre Jolivet       while (tab--) PetscCall(PetscFPrintf(PETSC_COMM_SELF, petsc_history, "  "));
5729566063dSJacob Faibussowitsch       PetscCall((*PetscVFPrintf)(petsc_history, format, Argp));
5735c6c1daeSBarry Smith       err = fflush(petsc_history);
57428b400f6SJacob Faibussowitsch       PetscCheck(!err, PETSC_COMM_SELF, PETSC_ERR_SYS, "fflush() failed on file");
5755c6c1daeSBarry Smith     }
5765c6c1daeSBarry Smith     va_end(Argp);
5775c6c1daeSBarry Smith   }
578*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5795c6c1daeSBarry Smith }
5805c6c1daeSBarry Smith 
5815c6c1daeSBarry Smith /*@C
582811af0c4SBarry Smith      PetscViewerFileSetName - Sets the name of the file the `PetscViewer` uses.
5835c6c1daeSBarry Smith 
584c3339decSBarry Smith     Collective
5855c6c1daeSBarry Smith 
5865c6c1daeSBarry Smith   Input Parameters:
587811af0c4SBarry Smith +  viewer - the PetscViewer; either `PETSCVIEWERASCII` or `PETSCVIEWERBINARY`
5885c6c1daeSBarry Smith -  name - the name of the file it should use
5895c6c1daeSBarry Smith 
5905c6c1daeSBarry Smith     Level: advanced
5915c6c1daeSBarry Smith 
592d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscViewerCreate()`, `PetscViewerSetType()`, `PetscViewerASCIIOpen()`, `PetscViewerBinaryOpen()`, `PetscViewerDestroy()`,
593db781477SPatrick Sanan           `PetscViewerASCIIGetPointer()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIISynchronizedPrintf()`
5945c6c1daeSBarry Smith @*/
595d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerFileSetName(PetscViewer viewer, const char name[])
596d71ae5a4SJacob Faibussowitsch {
597cc843e7aSLisandro Dalcin   char filename[PETSC_MAX_PATH_LEN];
5985c6c1daeSBarry Smith 
5995c6c1daeSBarry Smith   PetscFunctionBegin;
6005c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
6015c6c1daeSBarry Smith   PetscValidCharPointer(name, 2);
6029566063dSJacob Faibussowitsch   PetscCall(PetscStrreplace(PetscObjectComm((PetscObject)viewer), name, filename, sizeof(filename)));
603cac4c232SBarry Smith   PetscTryMethod(viewer, "PetscViewerFileSetName_C", (PetscViewer, const char[]), (viewer, filename));
604*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6055c6c1daeSBarry Smith }
6065c6c1daeSBarry Smith 
6075c6c1daeSBarry Smith /*@C
608811af0c4SBarry Smith      PetscViewerFileGetName - Gets the name of the file the `PetscViewer` uses.
6095c6c1daeSBarry Smith 
6105c6c1daeSBarry Smith     Not Collective
6115c6c1daeSBarry Smith 
6125c6c1daeSBarry Smith   Input Parameter:
613811af0c4SBarry Smith .  viewer - the `PetscViewer`; either `PETSCVIEWERASCII` or `PETSCVIEWERBINARY`
6145c6c1daeSBarry Smith 
6155c6c1daeSBarry Smith   Output Parameter:
6165c6c1daeSBarry Smith .  name - the name of the file it is using
6175c6c1daeSBarry Smith 
6185c6c1daeSBarry Smith     Level: advanced
6195c6c1daeSBarry Smith 
620d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscViewerCreate()`, `PetscViewerSetType()`, `PetscViewerASCIIOpen()`, `PetscViewerBinaryOpen()`, `PetscViewerFileSetName()`
6215c6c1daeSBarry Smith @*/
622d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerFileGetName(PetscViewer viewer, const char **name)
623d71ae5a4SJacob Faibussowitsch {
6245c6c1daeSBarry Smith   PetscFunctionBegin;
6255c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
6266e05b1faSLisandro Dalcin   PetscValidPointer(name, 2);
627cac4c232SBarry Smith   PetscUseMethod(viewer, "PetscViewerFileGetName_C", (PetscViewer, const char **), (viewer, name));
628*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6295c6c1daeSBarry Smith }
6305c6c1daeSBarry Smith 
631d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerFileGetName_ASCII(PetscViewer viewer, const char **name)
632d71ae5a4SJacob Faibussowitsch {
6335c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
6345c6c1daeSBarry Smith 
6355c6c1daeSBarry Smith   PetscFunctionBegin;
6365c6c1daeSBarry Smith   *name = vascii->filename;
637*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6385c6c1daeSBarry Smith }
6395c6c1daeSBarry Smith 
640d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerFileSetName_ASCII(PetscViewer viewer, const char name[])
641d71ae5a4SJacob Faibussowitsch {
6425c6c1daeSBarry Smith   size_t             len;
6435c6c1daeSBarry Smith   char               fname[PETSC_MAX_PATH_LEN], *gz;
6445c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
6455c6c1daeSBarry Smith   PetscBool          isstderr, isstdout;
6465c6c1daeSBarry Smith   PetscMPIInt        rank;
6475c6c1daeSBarry Smith 
6485c6c1daeSBarry Smith   PetscFunctionBegin;
6499566063dSJacob Faibussowitsch   PetscCall(PetscViewerFileClose_ASCII(viewer));
650*3ba16761SJacob Faibussowitsch   if (!name) PetscFunctionReturn(PETSC_SUCCESS);
6519566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(name, &vascii->filename));
6525c6c1daeSBarry Smith 
6535c6c1daeSBarry Smith   /* Is this file to be compressed */
6545c6c1daeSBarry Smith   vascii->storecompressed = PETSC_FALSE;
655a297a907SKarl Rupp 
6569566063dSJacob Faibussowitsch   PetscCall(PetscStrstr(vascii->filename, ".gz", &gz));
6575c6c1daeSBarry Smith   if (gz) {
6589566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(gz, &len));
6595c6c1daeSBarry Smith     if (len == 3) {
66008401ef6SPierre 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");
6615c6c1daeSBarry Smith       *gz                     = 0;
6625c6c1daeSBarry Smith       vascii->storecompressed = PETSC_TRUE;
6635c6c1daeSBarry Smith     }
6645c6c1daeSBarry Smith   }
6659566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank));
666dd400576SPatrick Sanan   if (rank == 0) {
6679566063dSJacob Faibussowitsch     PetscCall(PetscStrcmp(name, "stderr", &isstderr));
6689566063dSJacob Faibussowitsch     PetscCall(PetscStrcmp(name, "stdout", &isstdout));
6695c6c1daeSBarry Smith     /* empty filename means stdout */
6705c6c1daeSBarry Smith     if (name[0] == 0) isstdout = PETSC_TRUE;
6715c6c1daeSBarry Smith     if (isstderr) vascii->fd = PETSC_STDERR;
6725c6c1daeSBarry Smith     else if (isstdout) vascii->fd = PETSC_STDOUT;
6735c6c1daeSBarry Smith     else {
6749566063dSJacob Faibussowitsch       PetscCall(PetscFixFilename(name, fname));
6755c6c1daeSBarry Smith       switch (vascii->mode) {
676d71ae5a4SJacob Faibussowitsch       case FILE_MODE_READ:
677d71ae5a4SJacob Faibussowitsch         vascii->fd = fopen(fname, "r");
678d71ae5a4SJacob Faibussowitsch         break;
679d71ae5a4SJacob Faibussowitsch       case FILE_MODE_WRITE:
680d71ae5a4SJacob Faibussowitsch         vascii->fd = fopen(fname, "w");
681d71ae5a4SJacob Faibussowitsch         break;
682d71ae5a4SJacob Faibussowitsch       case FILE_MODE_APPEND:
683d71ae5a4SJacob Faibussowitsch         vascii->fd = fopen(fname, "a");
684d71ae5a4SJacob Faibussowitsch         break;
6855c6c1daeSBarry Smith       case FILE_MODE_UPDATE:
6865c6c1daeSBarry Smith         vascii->fd = fopen(fname, "r+");
687a297a907SKarl Rupp         if (!vascii->fd) vascii->fd = fopen(fname, "w+");
6885c6c1daeSBarry Smith         break;
6895c6c1daeSBarry Smith       case FILE_MODE_APPEND_UPDATE:
6905c6c1daeSBarry Smith         /* I really want a file which is opened at the end for updating,
6915c6c1daeSBarry Smith            not a+, which opens at the beginning, but makes writes at the end.
6925c6c1daeSBarry Smith         */
6935c6c1daeSBarry Smith         vascii->fd = fopen(fname, "r+");
694a297a907SKarl Rupp         if (!vascii->fd) vascii->fd = fopen(fname, "w+");
695*3ba16761SJacob Faibussowitsch         else {
696*3ba16761SJacob Faibussowitsch           int ret = fseek(vascii->fd, 0, SEEK_END);
697*3ba16761SJacob Faibussowitsch           PetscCheck(!ret, PETSC_COMM_SELF, PETSC_ERR_LIB, "fseek() failed with error code %d", ret);
698*3ba16761SJacob Faibussowitsch         }
6995c6c1daeSBarry Smith         break;
700d71ae5a4SJacob Faibussowitsch       default:
701d71ae5a4SJacob Faibussowitsch         SETERRQ(PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Unsupported file mode %s", PetscFileModes[vascii->mode]);
7025c6c1daeSBarry Smith       }
70328b400f6SJacob Faibussowitsch       PetscCheck(vascii->fd, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Cannot open PetscViewer file: %s", fname);
7045c6c1daeSBarry Smith     }
7055c6c1daeSBarry Smith   }
7065c6c1daeSBarry Smith #if defined(PETSC_USE_LOG)
707*3ba16761SJacob Faibussowitsch   PetscCall(PetscLogObjectState((PetscObject)viewer, "File: %s", name));
7085c6c1daeSBarry Smith #endif
709*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7105c6c1daeSBarry Smith }
7115c6c1daeSBarry Smith 
712d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerGetSubViewer_ASCII(PetscViewer viewer, MPI_Comm subcomm, PetscViewer *outviewer)
713d71ae5a4SJacob Faibussowitsch {
7145c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data, *ovascii;
7155c6c1daeSBarry Smith 
7165c6c1daeSBarry Smith   PetscFunctionBegin;
7179566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPushSynchronized(viewer));
71828b400f6SJacob Faibussowitsch   PetscCheck(!vascii->sviewer, PETSC_COMM_SELF, PETSC_ERR_ORDER, "SubViewer already obtained from PetscViewer and not restored");
719e5afcf28SBarry Smith   /*
7209530cbd7SBarry Smith      The following line is a bug; it does another PetscViewerASCIIPushSynchronized() on viewer, but if it is removed the code won't work
7219530cbd7SBarry 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
7229530cbd7SBarry Smith      (since the count never gets to zero) in some examples this displays information that otherwise would be lost
7239530cbd7SBarry Smith 
7249530cbd7SBarry Smith      This code also means another call to PetscViewerASCIIPopSynchronized() must be made after the PetscViewerRestoreSubViewer(), see, for example,
7259530cbd7SBarry Smith      PCView_GASM().
726e5afcf28SBarry Smith   */
7279566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPushSynchronized(viewer));
7289566063dSJacob Faibussowitsch   PetscCall(PetscViewerCreate(subcomm, outviewer));
7299566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetType(*outviewer, PETSCVIEWERASCII));
7309566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPushSynchronized(*outviewer));
7315c6c1daeSBarry Smith   ovascii            = (PetscViewer_ASCII *)(*outviewer)->data;
7325c6c1daeSBarry Smith   ovascii->fd        = vascii->fd;
7335c6c1daeSBarry Smith   ovascii->tab       = vascii->tab;
734ba5a0b41SBarry Smith   ovascii->closefile = PETSC_FALSE;
7355c6c1daeSBarry Smith 
7365c6c1daeSBarry Smith   vascii->sviewer                                      = *outviewer;
7375c6c1daeSBarry Smith   (*outviewer)->format                                 = viewer->format;
7385c6c1daeSBarry Smith   ((PetscViewer_ASCII *)((*outviewer)->data))->bviewer = viewer;
7393f08860eSBarry Smith   (*outviewer)->ops->destroy                           = PetscViewerDestroy_ASCII_SubViewer;
740*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7415c6c1daeSBarry Smith }
7425c6c1daeSBarry Smith 
743d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerRestoreSubViewer_ASCII(PetscViewer viewer, MPI_Comm comm, PetscViewer *outviewer)
744d71ae5a4SJacob Faibussowitsch {
7455c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
7465c6c1daeSBarry Smith 
7475c6c1daeSBarry Smith   PetscFunctionBegin;
74828b400f6SJacob Faibussowitsch   PetscCheck(ascii->sviewer, PETSC_COMM_SELF, PETSC_ERR_ORDER, "SubViewer never obtained from PetscViewer");
74908401ef6SPierre Jolivet   PetscCheck(ascii->sviewer == *outviewer, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "This PetscViewer did not generate this SubViewer");
7505c6c1daeSBarry Smith 
7519566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPopSynchronized(*outviewer));
752e5afcf28SBarry Smith   ascii->sviewer             = NULL;
7535c6c1daeSBarry Smith   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
7549566063dSJacob Faibussowitsch   PetscCall(PetscViewerDestroy(outviewer));
7559566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPopSynchronized(viewer));
756*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7575c6c1daeSBarry Smith }
7585c6c1daeSBarry Smith 
759d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerView_ASCII(PetscViewer v, PetscViewer viewer)
760d71ae5a4SJacob Faibussowitsch {
7612bf49c77SBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)v->data;
7622bf49c77SBarry Smith 
7632bf49c77SBarry Smith   PetscFunctionBegin;
76448a46eb9SPierre Jolivet   if (ascii->filename) PetscCall(PetscViewerASCIIPrintf(viewer, "Filename: %s\n", ascii->filename));
765*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7662bf49c77SBarry Smith }
7672bf49c77SBarry Smith 
7688556b5ebSBarry Smith /*MC
7698556b5ebSBarry Smith    PETSCVIEWERASCII - A viewer that prints to stdout or an ASCII file
7708556b5ebSBarry Smith 
771811af0c4SBarry Smith   Level: beginner
772811af0c4SBarry Smith 
773d1f92df0SBarry Smith .seealso: [](sec_viewers), `PETSC_VIEWER_STDOUT_()`, `PETSC_VIEWER_STDOUT_SELF`, `PETSC_VIEWER_STDOUT_WORLD`, `PetscViewerCreate()`, `PetscViewerASCIIOpen()`,
774db781477SPatrick Sanan           `PetscViewerMatlabOpen()`, `VecView()`, `DMView()`, `PetscViewerMatlabPutArray()`, `PETSCVIEWERBINARY`, `PETSCVIEWERMATLAB`,
775db781477SPatrick Sanan           `PetscViewerFileSetName()`, `PetscViewerFileSetMode()`, `PetscViewerFormat`, `PetscViewerType`, `PetscViewerSetType()`
7768556b5ebSBarry Smith M*/
777d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscViewerCreate_ASCII(PetscViewer viewer)
778d71ae5a4SJacob Faibussowitsch {
7795c6c1daeSBarry Smith   PetscViewer_ASCII *vascii;
7805c6c1daeSBarry Smith 
7815c6c1daeSBarry Smith   PetscFunctionBegin;
7824dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&vascii));
7835c6c1daeSBarry Smith   viewer->data = (void *)vascii;
7845c6c1daeSBarry Smith 
7855c6c1daeSBarry Smith   viewer->ops->destroy          = PetscViewerDestroy_ASCII;
7865c6c1daeSBarry Smith   viewer->ops->flush            = PetscViewerFlush_ASCII;
787559f443fSBarry Smith   viewer->ops->getsubviewer     = PetscViewerGetSubViewer_ASCII;
788559f443fSBarry Smith   viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_ASCII;
7892bf49c77SBarry Smith   viewer->ops->view             = PetscViewerView_ASCII;
7901d641e7bSMichael Lange   viewer->ops->read             = PetscViewerASCIIRead;
7915c6c1daeSBarry Smith 
7925c6c1daeSBarry Smith   /* defaults to stdout unless set with PetscViewerFileSetName() */
7935c6c1daeSBarry Smith   vascii->fd        = PETSC_STDOUT;
7945c6c1daeSBarry Smith   vascii->mode      = FILE_MODE_WRITE;
79502c9f0b5SLisandro Dalcin   vascii->bviewer   = NULL;
79602c9f0b5SLisandro Dalcin   vascii->subviewer = NULL;
79702c9f0b5SLisandro Dalcin   vascii->sviewer   = NULL;
7985c6c1daeSBarry Smith   vascii->tab       = 0;
7995c6c1daeSBarry Smith   vascii->tab_store = 0;
80002c9f0b5SLisandro Dalcin   vascii->filename  = NULL;
8015c6c1daeSBarry Smith   vascii->closefile = PETSC_TRUE;
8025c6c1daeSBarry Smith 
8039566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileSetName_C", PetscViewerFileSetName_ASCII));
8049566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileGetName_C", PetscViewerFileGetName_ASCII));
8059566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileGetMode_C", PetscViewerFileGetMode_ASCII));
8069566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileSetMode_C", PetscViewerFileSetMode_ASCII));
807*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
8085c6c1daeSBarry Smith }
8095c6c1daeSBarry Smith 
8105c6c1daeSBarry Smith /*@C
8115c6c1daeSBarry Smith     PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from
8125c6c1daeSBarry Smith     several processors.  Output of the first processor is followed by that of the
8135c6c1daeSBarry Smith     second, etc.
8145c6c1daeSBarry Smith 
815811af0c4SBarry Smith     Not Collective, must call collective `PetscViewerFlush()` to get the results out
8165c6c1daeSBarry Smith 
8175c6c1daeSBarry Smith     Input Parameters:
818811af0c4SBarry Smith +   viewer - the `PETSCVIEWERASCII` `PetscViewer`
8195c6c1daeSBarry Smith -   format - the usual printf() format string
8205c6c1daeSBarry Smith 
8215c6c1daeSBarry Smith     Level: intermediate
8225c6c1daeSBarry Smith 
82395452b02SPatrick Sanan     Notes:
824811af0c4SBarry Smith     You must have previously called `PetscViewerASCIIPushSynchronized()` to allow this routine to be called.
825e6abc3ddSVáclav Hapla     Then you can do multiple independent calls to this routine.
826811af0c4SBarry Smith 
827811af0c4SBarry Smith     The actual synchronized print is then done using `PetscViewerFlush()`.
828811af0c4SBarry Smith     `PetscViewerASCIIPopSynchronized()` should be then called if we are already done with the synchronized output
829e6abc3ddSVáclav Hapla     to conclude the "synchronized session".
830811af0c4SBarry Smith 
831e6abc3ddSVáclav Hapla     So the typical calling sequence looks like
832811af0c4SBarry Smith .vb
833811af0c4SBarry Smith     PetscViewerASCIIPushSynchronized(viewer);
834811af0c4SBarry Smith     PetscViewerASCIISynchronizedPrintf(viewer, ...);
835811af0c4SBarry Smith     PetscViewerASCIISynchronizedPrintf(viewer, ...);
836811af0c4SBarry Smith     ...
837811af0c4SBarry Smith     PetscViewerFlush(viewer);
838811af0c4SBarry Smith     PetscViewerASCIISynchronizedPrintf(viewer, ...);
839811af0c4SBarry Smith     PetscViewerASCIISynchronizedPrintf(viewer, ...);
840811af0c4SBarry Smith     ...
841811af0c4SBarry Smith     PetscViewerFlush(viewer);
842811af0c4SBarry Smith    PetscViewerASCIIPopSynchronized(viewer);
843811af0c4SBarry Smith .ve
8445c6c1daeSBarry Smith 
8455c6c1daeSBarry Smith     Fortran Note:
8465c6c1daeSBarry Smith       Can only print a single character* string
8475c6c1daeSBarry Smith 
848d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscViewerASCIIPushSynchronized()`, `PetscViewerFlush()`, `PetscViewerASCIIPopSynchronized()`,
849db781477SPatrick Sanan           `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIIOpen()`,
850db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`
8515c6c1daeSBarry Smith @*/
852d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIISynchronizedPrintf(PetscViewer viewer, const char format[], ...)
853d71ae5a4SJacob Faibussowitsch {
8545c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
8553f08860eSBarry Smith   PetscMPIInt        rank;
8565c6c1daeSBarry Smith   PetscInt           tab = vascii->tab;
8575c6c1daeSBarry Smith   MPI_Comm           comm;
8585c6c1daeSBarry Smith   FILE              *fp;
859559f443fSBarry Smith   PetscBool          iascii, hasbviewer = PETSC_FALSE;
8605c6c1daeSBarry Smith   int                err;
8615c6c1daeSBarry Smith 
8625c6c1daeSBarry Smith   PetscFunctionBegin;
8635c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
8645c6c1daeSBarry Smith   PetscValidCharPointer(format, 2);
8659566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
86628b400f6SJacob Faibussowitsch   PetscCheck(iascii, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Not ASCII PetscViewer");
86728b400f6SJacob Faibussowitsch   PetscCheck(vascii->allowsynchronized, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "First call PetscViewerASCIIPushSynchronized() to allow this call");
8685c6c1daeSBarry Smith 
8699566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
8709566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
8715c6c1daeSBarry Smith 
872559f443fSBarry Smith   if (vascii->bviewer) {
873559f443fSBarry Smith     hasbviewer = PETSC_TRUE;
874dd400576SPatrick Sanan     if (rank == 0) {
875559f443fSBarry Smith       vascii = (PetscViewer_ASCII *)vascii->bviewer->data;
8769566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
8779566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Comm_rank(comm, &rank));
878559f443fSBarry Smith     }
879559f443fSBarry Smith   }
8803f08860eSBarry Smith 
881559f443fSBarry Smith   fp = vascii->fd;
882559f443fSBarry Smith 
883dd400576SPatrick Sanan   if (rank == 0 && !hasbviewer) { /* First processor prints immediately to fp */
8845c6c1daeSBarry Smith     va_list Argp;
885559f443fSBarry Smith     /* flush my own messages that I may have queued up */
886559f443fSBarry Smith     PrintfQueue next = vascii->petsc_printfqueuebase, previous;
887559f443fSBarry Smith     PetscInt    i;
888559f443fSBarry Smith     for (i = 0; i < vascii->petsc_printfqueuelength; i++) {
8899566063dSJacob Faibussowitsch       PetscCall(PetscFPrintf(comm, fp, "%s", next->string));
890559f443fSBarry Smith       previous = next;
891559f443fSBarry Smith       next     = next->next;
8929566063dSJacob Faibussowitsch       PetscCall(PetscFree(previous->string));
8939566063dSJacob Faibussowitsch       PetscCall(PetscFree(previous));
894559f443fSBarry Smith     }
89502c9f0b5SLisandro Dalcin     vascii->petsc_printfqueue       = NULL;
896559f443fSBarry Smith     vascii->petsc_printfqueuelength = 0;
8975c6c1daeSBarry Smith 
89848a46eb9SPierre Jolivet     while (tab--) PetscCall(PetscFPrintf(PETSC_COMM_SELF, fp, "  "));
8995c6c1daeSBarry Smith 
9005c6c1daeSBarry Smith     va_start(Argp, format);
9019566063dSJacob Faibussowitsch     PetscCall((*PetscVFPrintf)(fp, format, Argp));
9025c6c1daeSBarry Smith     err = fflush(fp);
90328b400f6SJacob Faibussowitsch     PetscCheck(!err, PETSC_COMM_SELF, PETSC_ERR_SYS, "fflush() failed on file");
9045c6c1daeSBarry Smith     if (petsc_history) {
9055c6c1daeSBarry Smith       va_start(Argp, format);
9069566063dSJacob Faibussowitsch       PetscCall((*PetscVFPrintf)(petsc_history, format, Argp));
9075c6c1daeSBarry Smith       err = fflush(petsc_history);
90828b400f6SJacob Faibussowitsch       PetscCheck(!err, PETSC_COMM_SELF, PETSC_ERR_SYS, "fflush() failed on file");
9095c6c1daeSBarry Smith     }
9105c6c1daeSBarry Smith     va_end(Argp);
911559f443fSBarry Smith   } else { /* other processors add to queue */
9125c6c1daeSBarry Smith     char       *string;
9135c6c1daeSBarry Smith     va_list     Argp;
9145c6c1daeSBarry Smith     size_t      fullLength;
9155c6c1daeSBarry Smith     PrintfQueue next;
9165c6c1daeSBarry Smith 
9179566063dSJacob Faibussowitsch     PetscCall(PetscNew(&next));
918559f443fSBarry Smith     if (vascii->petsc_printfqueue) {
919559f443fSBarry Smith       vascii->petsc_printfqueue->next = next;
920559f443fSBarry Smith       vascii->petsc_printfqueue       = next;
921a297a907SKarl Rupp     } else {
922559f443fSBarry Smith       vascii->petsc_printfqueuebase = vascii->petsc_printfqueue = next;
923a297a907SKarl Rupp     }
924559f443fSBarry Smith     vascii->petsc_printfqueuelength++;
9255c6c1daeSBarry Smith     next->size = QUEUESTRINGSIZE;
9269566063dSJacob Faibussowitsch     PetscCall(PetscCalloc1(next->size, &next->string));
9275c6c1daeSBarry Smith     string = next->string;
9285c6c1daeSBarry Smith     tab *= 2;
929ad540459SPierre Jolivet     while (tab--) *string++ = ' ';
9305c6c1daeSBarry Smith     va_start(Argp, format);
9319566063dSJacob Faibussowitsch     PetscCall(PetscVSNPrintf(string, next->size - 2 * vascii->tab, format, &fullLength, Argp));
9325c6c1daeSBarry Smith     va_end(Argp);
933cb500232SBarry Smith     if (fullLength > (size_t)(next->size - 2 * vascii->tab)) {
9349566063dSJacob Faibussowitsch       PetscCall(PetscFree(next->string));
93514416c0eSBarry Smith       next->size = fullLength + 2 * vascii->tab;
9369566063dSJacob Faibussowitsch       PetscCall(PetscCalloc1(next->size, &next->string));
93714416c0eSBarry Smith       string = next->string;
93814416c0eSBarry Smith       tab    = 2 * vascii->tab;
939ad540459SPierre Jolivet       while (tab--) *string++ = ' ';
94014416c0eSBarry Smith       va_start(Argp, format);
9419566063dSJacob Faibussowitsch       PetscCall(PetscVSNPrintf(string, next->size - 2 * vascii->tab, format, NULL, Argp));
94214416c0eSBarry Smith       va_end(Argp);
94314416c0eSBarry Smith     }
9445c6c1daeSBarry Smith   }
945*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9465c6c1daeSBarry Smith }
9475c6c1daeSBarry Smith 
9482655f987SMichael Lange /*@C
949f8859db6SBarry Smith    PetscViewerASCIIRead - Reads from a ASCII file
9502655f987SMichael Lange 
951811af0c4SBarry Smith    Only process 0 in the `PetscViewer` may call this
9522655f987SMichael Lange 
9532655f987SMichael Lange    Input Parameters:
9542655f987SMichael Lange +  viewer - the ascii viewer
9552655f987SMichael Lange .  data - location to write the data
956060da220SMatthew G. Knepley .  num - number of items of data to read
9572655f987SMichael Lange -  datatype - type of data to read
9582655f987SMichael Lange 
959f8e4bde8SMatthew G. Knepley    Output Parameters:
960060da220SMatthew G. Knepley .  count - number of items of data actually read, or NULL
961f8e4bde8SMatthew G. Knepley 
9622655f987SMichael Lange    Level: beginner
9632655f987SMichael Lange 
964d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscViewerASCIIOpen()`, `PetscViewerPushFormat()`, `PetscViewerDestroy()`, `PetscViewerCreate()`, `PetscViewerFileSetMode()`, `PetscViewerFileSetName()`
965db781477SPatrick Sanan           `VecView()`, `MatView()`, `VecLoad()`, `MatLoad()`, `PetscViewerBinaryGetDescriptor()`,
966db781477SPatrick Sanan           `PetscViewerBinaryGetInfoPointer()`, `PetscFileMode`, `PetscViewer`, `PetscViewerBinaryRead()`
9672655f987SMichael Lange @*/
968d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIIRead(PetscViewer viewer, void *data, PetscInt num, PetscInt *count, PetscDataType dtype)
969d71ae5a4SJacob Faibussowitsch {
9702655f987SMichael Lange   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
9712655f987SMichael Lange   FILE              *fd     = vascii->fd;
9722655f987SMichael Lange   PetscInt           i;
9733b7fe8c3SMatthew G. Knepley   int                ret = 0;
974f8859db6SBarry Smith   PetscMPIInt        rank;
9752655f987SMichael Lange 
9762655f987SMichael Lange   PetscFunctionBegin;
9772655f987SMichael Lange   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
9789566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank));
979c5853193SPierre Jolivet   PetscCheck(rank == 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Can only be called from process 0 in the PetscViewer");
980060da220SMatthew G. Knepley   for (i = 0; i < num; i++) {
981f8e4bde8SMatthew G. Knepley     if (dtype == PETSC_CHAR) ret = fscanf(fd, "%c", &(((char *)data)[i]));
982f8e4bde8SMatthew G. Knepley     else if (dtype == PETSC_STRING) ret = fscanf(fd, "%s", &(((char *)data)[i]));
983a05e1a72SSatish Balay     else if (dtype == PETSC_INT) ret = fscanf(fd, "%" PetscInt_FMT, &(((PetscInt *)data)[i]));
984f8e4bde8SMatthew G. Knepley     else if (dtype == PETSC_ENUM) ret = fscanf(fd, "%d", &(((int *)data)[i]));
9859e3e4c22SLisandro Dalcin     else if (dtype == PETSC_INT64) ret = fscanf(fd, "%" PetscInt64_FMT, &(((PetscInt64 *)data)[i]));
986972064b6SLisandro Dalcin     else if (dtype == PETSC_LONG) ret = fscanf(fd, "%ld", &(((long *)data)[i]));
987f8e4bde8SMatthew G. Knepley     else if (dtype == PETSC_FLOAT) ret = fscanf(fd, "%f", &(((float *)data)[i]));
988f8e4bde8SMatthew G. Knepley     else if (dtype == PETSC_DOUBLE) ret = fscanf(fd, "%lg", &(((double *)data)[i]));
989a6e181c6SToby Isaac #if defined(PETSC_USE_REAL___FLOAT128)
990fba955ccSBarry Smith     else if (dtype == PETSC___FLOAT128) {
991fba955ccSBarry Smith       double tmp;
992fba955ccSBarry Smith       ret                     = fscanf(fd, "%lg", &tmp);
993a6e181c6SToby Isaac       ((__float128 *)data)[i] = tmp;
994a6e181c6SToby Isaac     }
995fba955ccSBarry Smith #endif
9969371c9d4SSatish Balay     else
9979371c9d4SSatish Balay       SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Data type %d not supported", (int)dtype);
99828b400f6SJacob Faibussowitsch     PetscCheck(ret, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Conversion error for data type %d", (int)dtype);
999f7d195e4SLawrence Mitchell     if (ret < 0) break; /* Proxy for EOF, need to check for it in configure */
10002655f987SMichael Lange   }
1001060da220SMatthew G. Knepley   if (count) *count = i;
100208401ef6SPierre Jolivet   else PetscCheck(ret >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Insufficient data, read only %" PetscInt_FMT " < %" PetscInt_FMT " items", i, num);
1003*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10042655f987SMichael Lange }
1005