xref: /petsc/src/sys/classes/viewer/impls/ascii/filev.c (revision 4dfa11a44d5adf2389f1d3acbc8f3c1116dc6c3a)
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 
69371c9d4SSatish Balay static PetscErrorCode PetscViewerFileClose_ASCII(PetscViewer viewer) {
75c6c1daeSBarry Smith   PetscMPIInt        rank;
85c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
95c6c1daeSBarry Smith   int                err;
105c6c1daeSBarry Smith 
115c6c1daeSBarry Smith   PetscFunctionBegin;
1228b400f6SJacob Faibussowitsch   PetscCheck(!vascii->sviewer, PetscObjectComm((PetscObject)viewer), PETSC_ERR_ARG_WRONGSTATE, "Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
139566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank));
14dd400576SPatrick Sanan   if (rank == 0 && vascii->fd != stderr && vascii->fd != PETSC_STDOUT) {
155c6c1daeSBarry Smith     if (vascii->fd && vascii->closefile) {
165c6c1daeSBarry Smith       err = fclose(vascii->fd);
1728b400f6SJacob Faibussowitsch       PetscCheck(!err, PETSC_COMM_SELF, PETSC_ERR_SYS, "fclose() failed on file");
185c6c1daeSBarry Smith     }
195c6c1daeSBarry Smith     if (vascii->storecompressed) {
205c6c1daeSBarry Smith       char  par[PETSC_MAX_PATH_LEN], buf[PETSC_MAX_PATH_LEN];
215c6c1daeSBarry Smith       FILE *fp;
229566063dSJacob Faibussowitsch       PetscCall(PetscStrncpy(par, "gzip ", sizeof(par)));
239566063dSJacob Faibussowitsch       PetscCall(PetscStrlcat(par, vascii->filename, sizeof(par)));
245c6c1daeSBarry Smith #if defined(PETSC_HAVE_POPEN)
259566063dSJacob Faibussowitsch       PetscCall(PetscPOpen(PETSC_COMM_SELF, NULL, par, "r", &fp));
26cc73adaaSBarry Smith       PetscCheck(!fgets(buf, 1024, fp), PETSC_COMM_SELF, PETSC_ERR_LIB, "Error from compression command %s\n%s", par, buf);
279566063dSJacob Faibussowitsch       PetscCall(PetscPClose(PETSC_COMM_SELF, fp));
285c6c1daeSBarry Smith #else
295c6c1daeSBarry Smith       SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP_SYS, "Cannot run external programs on this machine");
305c6c1daeSBarry Smith #endif
315c6c1daeSBarry Smith     }
325c6c1daeSBarry Smith   }
339566063dSJacob Faibussowitsch   PetscCall(PetscFree(vascii->filename));
345c6c1daeSBarry Smith   PetscFunctionReturn(0);
355c6c1daeSBarry Smith }
365c6c1daeSBarry Smith 
375c6c1daeSBarry Smith /* ----------------------------------------------------------------------*/
389371c9d4SSatish Balay PetscErrorCode PetscViewerDestroy_ASCII(PetscViewer viewer) {
395c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
405c6c1daeSBarry Smith   PetscViewerLink   *vlink;
415c6c1daeSBarry Smith   PetscBool          flg;
425c6c1daeSBarry Smith 
435c6c1daeSBarry Smith   PetscFunctionBegin;
4428b400f6SJacob Faibussowitsch   PetscCheck(!vascii->sviewer, PetscObjectComm((PetscObject)viewer), PETSC_ERR_ARG_WRONGSTATE, "Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
459566063dSJacob Faibussowitsch   PetscCall(PetscViewerFileClose_ASCII(viewer));
469566063dSJacob Faibussowitsch   PetscCall(PetscFree(vascii));
475c6c1daeSBarry Smith 
485c6c1daeSBarry Smith   /* remove the viewer from the list in the MPI Communicator */
4948a46eb9SPierre 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));
505c6c1daeSBarry Smith 
519566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_get_attr(PetscObjectComm((PetscObject)viewer), Petsc_Viewer_keyval, (void **)&vlink, (PetscMPIInt *)&flg));
525c6c1daeSBarry Smith   if (flg) {
535c6c1daeSBarry Smith     if (vlink && vlink->viewer == viewer) {
54e5840a18SBarry Smith       if (vlink->next) {
559566063dSJacob Faibussowitsch         PetscCallMPI(MPI_Comm_set_attr(PetscObjectComm((PetscObject)viewer), Petsc_Viewer_keyval, vlink->next));
56e5840a18SBarry Smith       } else {
579566063dSJacob Faibussowitsch         PetscCallMPI(MPI_Comm_delete_attr(PetscObjectComm((PetscObject)viewer), Petsc_Viewer_keyval));
58e5840a18SBarry Smith       }
599566063dSJacob Faibussowitsch       PetscCall(PetscFree(vlink));
605c6c1daeSBarry Smith     } else {
615c6c1daeSBarry Smith       while (vlink && vlink->next) {
625c6c1daeSBarry Smith         if (vlink->next->viewer == viewer) {
635c6c1daeSBarry Smith           PetscViewerLink *nv = vlink->next;
645c6c1daeSBarry Smith           vlink->next         = vlink->next->next;
659566063dSJacob Faibussowitsch           PetscCall(PetscFree(nv));
665c6c1daeSBarry Smith         }
675c6c1daeSBarry Smith         vlink = vlink->next;
685c6c1daeSBarry Smith       }
695c6c1daeSBarry Smith     }
705c6c1daeSBarry Smith   }
71aa139df6SJed Brown 
72aa139df6SJed Brown   if (Petsc_Viewer_Stdout_keyval != MPI_KEYVAL_INVALID) {
73aa139df6SJed Brown     PetscViewer aviewer;
749566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_get_attr(PetscObjectComm((PetscObject)viewer), Petsc_Viewer_Stdout_keyval, (void **)&aviewer, (PetscMPIInt *)&flg));
7548a46eb9SPierre Jolivet     if (flg && aviewer == viewer) PetscCallMPI(MPI_Comm_delete_attr(PetscObjectComm((PetscObject)viewer), Petsc_Viewer_Stdout_keyval));
76aa139df6SJed Brown   }
77aa139df6SJed Brown   if (Petsc_Viewer_Stderr_keyval != MPI_KEYVAL_INVALID) {
78aa139df6SJed Brown     PetscViewer aviewer;
799566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_get_attr(PetscObjectComm((PetscObject)viewer), Petsc_Viewer_Stderr_keyval, (void **)&aviewer, (PetscMPIInt *)&flg));
8048a46eb9SPierre Jolivet     if (flg && aviewer == viewer) PetscCallMPI(MPI_Comm_delete_attr(PetscObjectComm((PetscObject)viewer), Petsc_Viewer_Stderr_keyval));
81aa139df6SJed Brown   }
822e956fe4SStefano Zampini   PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileSetName_C", NULL));
832e956fe4SStefano Zampini   PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileGetName_C", NULL));
842e956fe4SStefano Zampini   PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileGetMode_C", NULL));
852e956fe4SStefano Zampini   PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileSetMode_C", NULL));
865c6c1daeSBarry Smith   PetscFunctionReturn(0);
875c6c1daeSBarry Smith }
885c6c1daeSBarry Smith 
899371c9d4SSatish Balay PetscErrorCode PetscViewerDestroy_ASCII_SubViewer(PetscViewer viewer) {
905c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
915fd66863SKarl Rupp 
925c6c1daeSBarry Smith   PetscFunctionBegin;
939566063dSJacob Faibussowitsch   PetscCall(PetscViewerRestoreSubViewer(vascii->bviewer, 0, &viewer));
945c6c1daeSBarry Smith   PetscFunctionReturn(0);
955c6c1daeSBarry Smith }
965c6c1daeSBarry Smith 
979371c9d4SSatish Balay PetscErrorCode PetscViewerFlush_ASCII(PetscViewer viewer) {
985c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
995c6c1daeSBarry Smith   int                err;
100559f443fSBarry Smith   MPI_Comm           comm;
101559f443fSBarry Smith   PetscMPIInt        rank, size;
102559f443fSBarry Smith   FILE              *fd = vascii->fd;
1035c6c1daeSBarry Smith 
1045c6c1daeSBarry Smith   PetscFunctionBegin;
10528b400f6SJacob Faibussowitsch   PetscCheck(!vascii->sviewer, PetscObjectComm((PetscObject)viewer), PETSC_ERR_ARG_WRONGSTATE, "Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
1069566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
1079566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
1089566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(comm, &size));
109559f443fSBarry Smith 
110dd400576SPatrick Sanan   if (!vascii->bviewer && rank == 0 && (vascii->mode != FILE_MODE_READ)) {
1115c6c1daeSBarry Smith     err = fflush(vascii->fd);
11228b400f6SJacob Faibussowitsch     PetscCheck(!err, PETSC_COMM_SELF, PETSC_ERR_SYS, "fflush() call failed");
1135c6c1daeSBarry Smith   }
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   }
1755c6c1daeSBarry Smith   PetscFunctionReturn(0);
1765c6c1daeSBarry Smith }
1775c6c1daeSBarry Smith 
1785c6c1daeSBarry Smith /*@C
179811af0c4SBarry Smith     PetscViewerASCIIGetPointer - Extracts the file pointer from an ASCII `PetscViewer`.
1805c6c1daeSBarry Smith 
181f8859db6SBarry Smith     Not Collective, depending on the viewer the value may be meaningless except for process 0 of the viewer
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 
1945c6c1daeSBarry Smith     Fortran Note:
1955c6c1daeSBarry Smith     This routine is not supported in Fortran.
1965c6c1daeSBarry Smith 
197811af0c4SBarry Smith .seealso: `PETSCVIEWERASCII`, `PetscViewerASCIIOpen()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerCreate()`, `PetscViewerASCIIPrintf()`,
198db781477SPatrick Sanan           `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerFlush()`
1995c6c1daeSBarry Smith @*/
2009371c9d4SSatish Balay PetscErrorCode PetscViewerASCIIGetPointer(PetscViewer viewer, FILE **fd) {
2015c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
2025c6c1daeSBarry Smith 
2035c6c1daeSBarry Smith   PetscFunctionBegin;
2045c6c1daeSBarry Smith   *fd = vascii->fd;
2055c6c1daeSBarry Smith   PetscFunctionReturn(0);
2065c6c1daeSBarry Smith }
2075c6c1daeSBarry Smith 
2089371c9d4SSatish Balay PetscErrorCode PetscViewerFileGetMode_ASCII(PetscViewer viewer, PetscFileMode *mode) {
2095c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
2105c6c1daeSBarry Smith 
2115c6c1daeSBarry Smith   PetscFunctionBegin;
2125c6c1daeSBarry Smith   *mode = vascii->mode;
2135c6c1daeSBarry Smith   PetscFunctionReturn(0);
2145c6c1daeSBarry Smith }
2155c6c1daeSBarry Smith 
2169371c9d4SSatish Balay PetscErrorCode PetscViewerFileSetMode_ASCII(PetscViewer viewer, PetscFileMode mode) {
2175c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
2185c6c1daeSBarry Smith 
2195c6c1daeSBarry Smith   PetscFunctionBegin;
2205c6c1daeSBarry Smith   vascii->mode = mode;
2215c6c1daeSBarry Smith   PetscFunctionReturn(0);
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 
2335c6c1daeSBarry Smith     Not Collective, but only first processor in set has any effect
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 
2415c6c1daeSBarry Smith     Fortran Note:
2425c6c1daeSBarry Smith     This routine is not supported in Fortran.
2435c6c1daeSBarry Smith 
244db781477SPatrick Sanan .seealso: `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIIGetTab()`,
245db781477SPatrick Sanan           `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIOpen()`,
246db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`, `PetscViewerASCIIPushTab()`
2475c6c1daeSBarry Smith @*/
2489371c9d4SSatish Balay PetscErrorCode PetscViewerASCIISetTab(PetscViewer viewer, PetscInt tabs) {
2495c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
2505c6c1daeSBarry Smith   PetscBool          iascii;
2515c6c1daeSBarry Smith 
2525c6c1daeSBarry Smith   PetscFunctionBegin;
2535c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
2549566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
255a297a907SKarl Rupp   if (iascii) ascii->tab = tabs;
2565c6c1daeSBarry Smith   PetscFunctionReturn(0);
2575c6c1daeSBarry Smith }
2585c6c1daeSBarry Smith 
2595c6c1daeSBarry Smith /*@
260811af0c4SBarry Smith     PetscViewerASCIIGetTab - Return the number of tabs used by `PetscViewer`.
2615c6c1daeSBarry Smith 
2625c6c1daeSBarry Smith     Not Collective, meaningful on first processor only.
2635c6c1daeSBarry Smith 
2645c6c1daeSBarry Smith     Input Parameters:
265811af0c4SBarry Smith .    viewer - obtained with `PetscViewerASCIIOpen()`
266a2b725a8SWilliam Gropp 
2675c6c1daeSBarry Smith     Output Parameters:
2685c6c1daeSBarry Smith .    tabs - number of tabs
2695c6c1daeSBarry Smith 
2705c6c1daeSBarry Smith     Level: developer
2715c6c1daeSBarry Smith 
2725c6c1daeSBarry Smith     Fortran Note:
2735c6c1daeSBarry Smith     This routine is not supported in Fortran.
2745c6c1daeSBarry Smith 
275db781477SPatrick Sanan .seealso: `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIISetTab()`,
276db781477SPatrick Sanan           `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIOpen()`,
277db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`, `PetscViewerASCIIPushTab()`
2785c6c1daeSBarry Smith @*/
2799371c9d4SSatish Balay PetscErrorCode PetscViewerASCIIGetTab(PetscViewer viewer, PetscInt *tabs) {
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;
2875c6c1daeSBarry Smith   PetscFunctionReturn(0);
2885c6c1daeSBarry Smith }
2895c6c1daeSBarry Smith 
2905c6c1daeSBarry Smith /*@
2915c6c1daeSBarry Smith     PetscViewerASCIIAddTab - Add to the number of times an ASCII viewer tabs before printing
2925c6c1daeSBarry Smith 
2935c6c1daeSBarry Smith     Not Collective, but only first processor in set has any effect
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 
3015c6c1daeSBarry Smith     Fortran Note:
3025c6c1daeSBarry Smith     This routine is not supported in Fortran.
3035c6c1daeSBarry Smith 
304db781477SPatrick Sanan .seealso: `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`,
305db781477SPatrick Sanan           `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIOpen()`,
306db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`, `PetscViewerASCIIPushTab()`
3075c6c1daeSBarry Smith @*/
3089371c9d4SSatish Balay PetscErrorCode PetscViewerASCIIAddTab(PetscViewer viewer, PetscInt tabs) {
3095c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
3105c6c1daeSBarry Smith   PetscBool          iascii;
3115c6c1daeSBarry Smith 
3125c6c1daeSBarry Smith   PetscFunctionBegin;
3135c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
3149566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
315a297a907SKarl Rupp   if (iascii) ascii->tab += tabs;
3165c6c1daeSBarry Smith   PetscFunctionReturn(0);
3175c6c1daeSBarry Smith }
3185c6c1daeSBarry Smith 
3195c6c1daeSBarry Smith /*@
3205c6c1daeSBarry Smith     PetscViewerASCIISubtractTab - Subtracts from the number of times an ASCII viewer tabs before printing
3215c6c1daeSBarry Smith 
3225c6c1daeSBarry Smith     Not Collective, but only first processor in set has any effect
3235c6c1daeSBarry Smith 
3245c6c1daeSBarry Smith     Input Parameters:
325811af0c4SBarry Smith +    viewer - obtained with `PetscViewerASCIIOpen()`
3265c6c1daeSBarry Smith -    tabs - number of tabs
3275c6c1daeSBarry Smith 
3285c6c1daeSBarry Smith     Level: developer
3295c6c1daeSBarry Smith 
3305c6c1daeSBarry Smith     Fortran Note:
3315c6c1daeSBarry Smith     This routine is not supported in Fortran.
3325c6c1daeSBarry Smith 
333db781477SPatrick Sanan .seealso: `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`,
334db781477SPatrick Sanan           `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIOpen()`,
335db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`, `PetscViewerASCIIPushTab()`
3365c6c1daeSBarry Smith @*/
3379371c9d4SSatish Balay PetscErrorCode PetscViewerASCIISubtractTab(PetscViewer viewer, PetscInt tabs) {
3385c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
3395c6c1daeSBarry Smith   PetscBool          iascii;
3405c6c1daeSBarry Smith 
3415c6c1daeSBarry Smith   PetscFunctionBegin;
3425c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
3439566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
344a297a907SKarl Rupp   if (iascii) ascii->tab -= tabs;
3455c6c1daeSBarry Smith   PetscFunctionReturn(0);
3465c6c1daeSBarry Smith }
3475c6c1daeSBarry Smith 
3485c6c1daeSBarry Smith /*@C
349811af0c4SBarry Smith     PetscViewerASCIIPushSynchronized - Allows calls to `PetscViewerASCIISynchronizedPrintf()` for this viewer
3505c6c1daeSBarry Smith 
351811af0c4SBarry Smith     Collective on viewer
3525c6c1daeSBarry Smith 
3535c6c1daeSBarry Smith     Input Parameters:
354811af0c4SBarry Smith .    viewer - obtained with `PetscViewerASCIIOpen()`
3555c6c1daeSBarry Smith 
3565c6c1daeSBarry Smith     Level: intermediate
3575c6c1daeSBarry Smith 
358811af0c4SBarry Smith     Note:
359811af0c4SBarry Smith     See documentation of `PetscViewerASCIISynchronizedPrintf()` for more details how the synchronized output should be done properly.
3605c6c1daeSBarry Smith 
361db781477SPatrick Sanan .seealso: `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerFlush()`, `PetscViewerASCIIPopSynchronized()`,
362db781477SPatrick Sanan           `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIIOpen()`,
363db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`
3645c6c1daeSBarry Smith @*/
3659371c9d4SSatish Balay PetscErrorCode PetscViewerASCIIPushSynchronized(PetscViewer viewer) {
3665c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
3675c6c1daeSBarry Smith   PetscBool          iascii;
3685c6c1daeSBarry Smith 
3695c6c1daeSBarry Smith   PetscFunctionBegin;
3705c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
37128b400f6SJacob Faibussowitsch   PetscCheck(!ascii->sviewer, PetscObjectComm((PetscObject)viewer), PETSC_ERR_ARG_WRONGSTATE, "Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
3729566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
3731575c14dSBarry Smith   if (iascii) ascii->allowsynchronized++;
3741575c14dSBarry Smith   PetscFunctionReturn(0);
3751575c14dSBarry Smith }
3761575c14dSBarry Smith 
3771575c14dSBarry Smith /*@C
378811af0c4SBarry Smith     PetscViewerASCIIPopSynchronized - Undoes most recent `PetscViewerASCIIPushSynchronized()` for this viewer
3791575c14dSBarry Smith 
380811af0c4SBarry Smith     Collective on viewer
3811575c14dSBarry Smith 
3821575c14dSBarry Smith     Input Parameters:
383811af0c4SBarry Smith .    viewer - obtained with `PetscViewerASCIIOpen()`
3841575c14dSBarry Smith 
3851575c14dSBarry Smith     Level: intermediate
3861575c14dSBarry Smith 
387811af0c4SBarry Smith     Note:
388811af0c4SBarry Smith     See documentation of `PetscViewerASCIISynchronizedPrintf()` for more details how the synchronized output should be done properly.
3891575c14dSBarry Smith 
390db781477SPatrick Sanan .seealso: `PetscViewerASCIIPushSynchronized()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerFlush()`,
391db781477SPatrick Sanan           `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIIOpen()`,
392db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`
3931575c14dSBarry Smith @*/
3949371c9d4SSatish Balay PetscErrorCode PetscViewerASCIIPopSynchronized(PetscViewer viewer) {
3951575c14dSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
3961575c14dSBarry Smith   PetscBool          iascii;
3971575c14dSBarry Smith 
3981575c14dSBarry Smith   PetscFunctionBegin;
3991575c14dSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
40028b400f6SJacob Faibussowitsch   PetscCheck(!ascii->sviewer, PetscObjectComm((PetscObject)viewer), PETSC_ERR_ARG_WRONGSTATE, "Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
4019566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
4021575c14dSBarry Smith   if (iascii) {
4031575c14dSBarry Smith     ascii->allowsynchronized--;
40408401ef6SPierre Jolivet     PetscCheck(ascii->allowsynchronized >= 0, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Called more times than PetscViewerASCIIPushSynchronized()");
4051575c14dSBarry Smith   }
4065c6c1daeSBarry Smith   PetscFunctionReturn(0);
4075c6c1daeSBarry Smith }
4085c6c1daeSBarry Smith 
4091c297824SMatthew G. Knepley /*@C
410811af0c4SBarry Smith     PetscViewerASCIIPushTab - Adds one more tab to the amount that `PetscViewerASCIIPrintf()`
4115c6c1daeSBarry Smith      lines are tabbed.
4125c6c1daeSBarry Smith 
4135c6c1daeSBarry Smith     Not Collective, but only first processor in set has any effect
4145c6c1daeSBarry Smith 
4155c6c1daeSBarry Smith     Input Parameters:
416811af0c4SBarry Smith .    viewer - obtained with `PetscViewerASCIIOpen()`
4175c6c1daeSBarry Smith 
4185c6c1daeSBarry Smith     Level: developer
4195c6c1daeSBarry Smith 
4205c6c1daeSBarry Smith     Fortran Note:
4215c6c1daeSBarry Smith     This routine is not supported in Fortran.
4225c6c1daeSBarry Smith 
423db781477SPatrick Sanan .seealso: `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`,
424db781477SPatrick Sanan           `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIOpen()`,
425db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`
4265c6c1daeSBarry Smith @*/
4279371c9d4SSatish Balay PetscErrorCode PetscViewerASCIIPushTab(PetscViewer viewer) {
4285c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
4295c6c1daeSBarry Smith   PetscBool          iascii;
4305c6c1daeSBarry Smith 
4315c6c1daeSBarry Smith   PetscFunctionBegin;
4325c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
4339566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
434a297a907SKarl Rupp   if (iascii) ascii->tab++;
4355c6c1daeSBarry Smith   PetscFunctionReturn(0);
4365c6c1daeSBarry Smith }
4375c6c1daeSBarry Smith 
4381c297824SMatthew G. Knepley /*@C
439811af0c4SBarry Smith     PetscViewerASCIIPopTab - Removes one tab from the amount that `PetscViewerASCIIPrintf()` lines are tabbed that was provided by `PetscViewerASCIIPushTab()`
4405c6c1daeSBarry Smith 
4415c6c1daeSBarry Smith     Not Collective, but only first processor in set has any effect
4425c6c1daeSBarry Smith 
4435c6c1daeSBarry Smith     Input Parameters:
444811af0c4SBarry Smith .    viewer - obtained with `PetscViewerASCIIOpen()`
4455c6c1daeSBarry Smith 
4465c6c1daeSBarry Smith     Level: developer
4475c6c1daeSBarry Smith 
4485c6c1daeSBarry Smith     Fortran Note:
4495c6c1daeSBarry Smith     This routine is not supported in Fortran.
4505c6c1daeSBarry Smith 
451db781477SPatrick Sanan .seealso: `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`,
452db781477SPatrick Sanan           `PetscViewerASCIIPushTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIOpen()`,
453db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`
4545c6c1daeSBarry Smith @*/
4559371c9d4SSatish Balay PetscErrorCode PetscViewerASCIIPopTab(PetscViewer viewer) {
4565c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
4575c6c1daeSBarry Smith   PetscBool          iascii;
4585c6c1daeSBarry Smith 
4595c6c1daeSBarry Smith   PetscFunctionBegin;
4605c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
4619566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
4625c6c1daeSBarry Smith   if (iascii) {
46308401ef6SPierre Jolivet     PetscCheck(ascii->tab > 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "More tabs popped than pushed");
4645c6c1daeSBarry Smith     ascii->tab--;
4655c6c1daeSBarry Smith   }
4665c6c1daeSBarry Smith   PetscFunctionReturn(0);
4675c6c1daeSBarry Smith }
4685c6c1daeSBarry Smith 
4695c6c1daeSBarry Smith /*@
470811af0c4SBarry Smith     PetscViewerASCIIUseTabs - Turns on or off the use of tabs with the ASCII `PetscViewer`
4715c6c1daeSBarry Smith 
4725c6c1daeSBarry Smith     Not Collective, but only first processor in set has any effect
4735c6c1daeSBarry Smith 
4745c6c1daeSBarry Smith     Input Parameters:
475811af0c4SBarry Smith +    viewer - obtained with `PetscViewerASCIIOpen()`
476811af0c4SBarry Smith -    flg - `PETSC_TRUE` or `PETSC_FALSE`
4775c6c1daeSBarry Smith 
4785c6c1daeSBarry Smith     Level: developer
4795c6c1daeSBarry Smith 
4805c6c1daeSBarry Smith     Fortran Note:
4815c6c1daeSBarry Smith     This routine is not supported in Fortran.
4825c6c1daeSBarry Smith 
483db781477SPatrick Sanan .seealso: `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`,
484db781477SPatrick Sanan           `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIPushTab()`, `PetscViewerASCIIOpen()`,
485db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`
4865c6c1daeSBarry Smith @*/
4879371c9d4SSatish Balay PetscErrorCode PetscViewerASCIIUseTabs(PetscViewer viewer, PetscBool flg) {
4885c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
4895c6c1daeSBarry Smith   PetscBool          iascii;
4905c6c1daeSBarry Smith 
4915c6c1daeSBarry Smith   PetscFunctionBegin;
4925c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
4939566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
4945c6c1daeSBarry Smith   if (iascii) {
495a297a907SKarl Rupp     if (flg) ascii->tab = ascii->tab_store;
496a297a907SKarl Rupp     else {
4975c6c1daeSBarry Smith       ascii->tab_store = ascii->tab;
4985c6c1daeSBarry Smith       ascii->tab       = 0;
4995c6c1daeSBarry Smith     }
5005c6c1daeSBarry Smith   }
5015c6c1daeSBarry Smith   PetscFunctionReturn(0);
5025c6c1daeSBarry Smith }
5035c6c1daeSBarry Smith 
5045c6c1daeSBarry Smith /* ----------------------------------------------------------------------- */
5055c6c1daeSBarry Smith 
5065c6c1daeSBarry Smith /*@C
5075c6c1daeSBarry Smith     PetscViewerASCIIPrintf - Prints to a file, only from the first
5085c6c1daeSBarry Smith     processor in the PetscViewer
5095c6c1daeSBarry Smith 
5105c6c1daeSBarry Smith     Not Collective, but only first processor in set has any effect
5115c6c1daeSBarry Smith 
5125c6c1daeSBarry Smith     Input Parameters:
513811af0c4SBarry Smith +    viewer - obtained with `PetscViewerASCIIOpen()`
5145c6c1daeSBarry Smith -    format - the usual printf() format string
5155c6c1daeSBarry Smith 
5165c6c1daeSBarry Smith     Level: developer
5175c6c1daeSBarry Smith 
5185c6c1daeSBarry Smith     Fortran Note:
519811af0c4SBarry Smith     The call sequence is `PetscViewerASCIIPrintf`(PetscViewer, character(*), int ierr) from Fortran.
5205c6c1daeSBarry Smith     That is, you can only pass a single character string from Fortran.
5215c6c1daeSBarry Smith 
522db781477SPatrick Sanan .seealso: `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIOpen()`,
523db781477SPatrick Sanan           `PetscViewerASCIIPushTab()`, `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`,
524db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`, `PetscViewerASCIIPushSynchronized()`
5255c6c1daeSBarry Smith @*/
5269371c9d4SSatish Balay PetscErrorCode PetscViewerASCIIPrintf(PetscViewer viewer, const char format[], ...) {
5275c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
5285c6c1daeSBarry Smith   PetscMPIInt        rank;
529dd2fa690SBarry Smith   PetscInt           tab, intab = ascii->tab;
5305c6c1daeSBarry Smith   FILE              *fd = ascii->fd;
5313f08860eSBarry Smith   PetscBool          iascii;
5325c6c1daeSBarry Smith   int                err;
5335c6c1daeSBarry Smith 
5345c6c1daeSBarry Smith   PetscFunctionBegin;
5355c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
53628b400f6SJacob Faibussowitsch   PetscCheck(!ascii->sviewer, PetscObjectComm((PetscObject)viewer), PETSC_ERR_ARG_WRONGSTATE, "Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
5375c6c1daeSBarry Smith   PetscValidCharPointer(format, 2);
5389566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
53928b400f6SJacob Faibussowitsch   PetscCheck(iascii, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Not ASCII PetscViewer");
5409566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank));
541559f443fSBarry Smith   if (rank) PetscFunctionReturn(0);
5423f08860eSBarry Smith 
5433f08860eSBarry Smith   if (ascii->bviewer) { /* pass string up to parent viewer */
5443f08860eSBarry Smith     char   *string;
5453f08860eSBarry Smith     va_list Argp;
5463f08860eSBarry Smith     size_t  fullLength;
5473f08860eSBarry Smith 
5489566063dSJacob Faibussowitsch     PetscCall(PetscCalloc1(QUEUESTRINGSIZE, &string));
5493f08860eSBarry Smith     va_start(Argp, format);
5509566063dSJacob Faibussowitsch     PetscCall(PetscVSNPrintf(string, QUEUESTRINGSIZE, format, &fullLength, Argp));
5513f08860eSBarry Smith     va_end(Argp);
5529566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "%s", string));
5539566063dSJacob Faibussowitsch     PetscCall(PetscFree(string));
5543f08860eSBarry Smith   } else { /* write directly to file */
5555c6c1daeSBarry Smith     va_list     Argp;
556559f443fSBarry Smith     /* flush my own messages that I may have queued up */
557559f443fSBarry Smith     PrintfQueue next = ascii->petsc_printfqueuebase, previous;
558559f443fSBarry Smith     PetscInt    i;
559559f443fSBarry Smith     for (i = 0; i < ascii->petsc_printfqueuelength; i++) {
5609566063dSJacob Faibussowitsch       PetscCall(PetscFPrintf(PETSC_COMM_SELF, fd, "%s", next->string));
561559f443fSBarry Smith       previous = next;
562559f443fSBarry Smith       next     = next->next;
5639566063dSJacob Faibussowitsch       PetscCall(PetscFree(previous->string));
5649566063dSJacob Faibussowitsch       PetscCall(PetscFree(previous));
565559f443fSBarry Smith     }
56602c9f0b5SLisandro Dalcin     ascii->petsc_printfqueue       = NULL;
567559f443fSBarry Smith     ascii->petsc_printfqueuelength = 0;
568dd2fa690SBarry Smith     tab                            = intab;
56948a46eb9SPierre Jolivet     while (tab--) PetscCall(PetscFPrintf(PETSC_COMM_SELF, fd, "  "));
5705c6c1daeSBarry Smith 
5715c6c1daeSBarry Smith     va_start(Argp, format);
5729566063dSJacob Faibussowitsch     PetscCall((*PetscVFPrintf)(fd, format, Argp));
5735c6c1daeSBarry Smith     err = fflush(fd);
57428b400f6SJacob Faibussowitsch     PetscCheck(!err, PETSC_COMM_SELF, PETSC_ERR_SYS, "fflush() failed on file");
5755c6c1daeSBarry Smith     if (petsc_history) {
5765c6c1daeSBarry Smith       va_start(Argp, format);
577dd2fa690SBarry Smith       tab = intab;
57848a46eb9SPierre Jolivet       while (tab--) PetscCall(PetscFPrintf(PETSC_COMM_SELF, petsc_history, "  "));
5799566063dSJacob Faibussowitsch       PetscCall((*PetscVFPrintf)(petsc_history, format, Argp));
5805c6c1daeSBarry Smith       err = fflush(petsc_history);
58128b400f6SJacob Faibussowitsch       PetscCheck(!err, PETSC_COMM_SELF, PETSC_ERR_SYS, "fflush() failed on file");
5825c6c1daeSBarry Smith     }
5835c6c1daeSBarry Smith     va_end(Argp);
5845c6c1daeSBarry Smith   }
5855c6c1daeSBarry Smith   PetscFunctionReturn(0);
5865c6c1daeSBarry Smith }
5875c6c1daeSBarry Smith 
5885c6c1daeSBarry Smith /*@C
589811af0c4SBarry Smith      PetscViewerFileSetName - Sets the name of the file the `PetscViewer` uses.
5905c6c1daeSBarry Smith 
591811af0c4SBarry Smith     Collective on viewer
5925c6c1daeSBarry Smith 
5935c6c1daeSBarry Smith   Input Parameters:
594811af0c4SBarry Smith +  viewer - the PetscViewer; either `PETSCVIEWERASCII` or `PETSCVIEWERBINARY`
5955c6c1daeSBarry Smith -  name - the name of the file it should use
5965c6c1daeSBarry Smith 
5975c6c1daeSBarry Smith     Level: advanced
5985c6c1daeSBarry Smith 
599db781477SPatrick Sanan .seealso: `PetscViewerCreate()`, `PetscViewerSetType()`, `PetscViewerASCIIOpen()`, `PetscViewerBinaryOpen()`, `PetscViewerDestroy()`,
600db781477SPatrick Sanan           `PetscViewerASCIIGetPointer()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIISynchronizedPrintf()`
6015c6c1daeSBarry Smith @*/
6029371c9d4SSatish Balay PetscErrorCode PetscViewerFileSetName(PetscViewer viewer, const char name[]) {
603cc843e7aSLisandro Dalcin   char filename[PETSC_MAX_PATH_LEN];
6045c6c1daeSBarry Smith 
6055c6c1daeSBarry Smith   PetscFunctionBegin;
6065c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
6075c6c1daeSBarry Smith   PetscValidCharPointer(name, 2);
6089566063dSJacob Faibussowitsch   PetscCall(PetscStrreplace(PetscObjectComm((PetscObject)viewer), name, filename, sizeof(filename)));
609cac4c232SBarry Smith   PetscTryMethod(viewer, "PetscViewerFileSetName_C", (PetscViewer, const char[]), (viewer, filename));
6105c6c1daeSBarry Smith   PetscFunctionReturn(0);
6115c6c1daeSBarry Smith }
6125c6c1daeSBarry Smith 
6135c6c1daeSBarry Smith /*@C
614811af0c4SBarry Smith      PetscViewerFileGetName - Gets the name of the file the `PetscViewer` uses.
6155c6c1daeSBarry Smith 
6165c6c1daeSBarry Smith     Not Collective
6175c6c1daeSBarry Smith 
6185c6c1daeSBarry Smith   Input Parameter:
619811af0c4SBarry Smith .  viewer - the `PetscViewer`; either `PETSCVIEWERASCII` or `PETSCVIEWERBINARY`
6205c6c1daeSBarry Smith 
6215c6c1daeSBarry Smith   Output Parameter:
6225c6c1daeSBarry Smith .  name - the name of the file it is using
6235c6c1daeSBarry Smith 
6245c6c1daeSBarry Smith     Level: advanced
6255c6c1daeSBarry Smith 
626db781477SPatrick Sanan .seealso: `PetscViewerCreate()`, `PetscViewerSetType()`, `PetscViewerASCIIOpen()`, `PetscViewerBinaryOpen()`, `PetscViewerFileSetName()`
6275c6c1daeSBarry Smith @*/
6289371c9d4SSatish Balay PetscErrorCode PetscViewerFileGetName(PetscViewer viewer, const char **name) {
6295c6c1daeSBarry Smith   PetscFunctionBegin;
6305c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
6316e05b1faSLisandro Dalcin   PetscValidPointer(name, 2);
632cac4c232SBarry Smith   PetscUseMethod(viewer, "PetscViewerFileGetName_C", (PetscViewer, const char **), (viewer, name));
6335c6c1daeSBarry Smith   PetscFunctionReturn(0);
6345c6c1daeSBarry Smith }
6355c6c1daeSBarry Smith 
6369371c9d4SSatish Balay PetscErrorCode PetscViewerFileGetName_ASCII(PetscViewer viewer, const char **name) {
6375c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
6385c6c1daeSBarry Smith 
6395c6c1daeSBarry Smith   PetscFunctionBegin;
6405c6c1daeSBarry Smith   *name = vascii->filename;
6415c6c1daeSBarry Smith   PetscFunctionReturn(0);
6425c6c1daeSBarry Smith }
6435c6c1daeSBarry Smith 
6449371c9d4SSatish Balay PetscErrorCode PetscViewerFileSetName_ASCII(PetscViewer viewer, const char name[]) {
6455c6c1daeSBarry Smith   size_t             len;
6465c6c1daeSBarry Smith   char               fname[PETSC_MAX_PATH_LEN], *gz;
6475c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
6485c6c1daeSBarry Smith   PetscBool          isstderr, isstdout;
6495c6c1daeSBarry Smith   PetscMPIInt        rank;
6505c6c1daeSBarry Smith 
6515c6c1daeSBarry Smith   PetscFunctionBegin;
6529566063dSJacob Faibussowitsch   PetscCall(PetscViewerFileClose_ASCII(viewer));
6535c6c1daeSBarry Smith   if (!name) PetscFunctionReturn(0);
6549566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(name, &vascii->filename));
6555c6c1daeSBarry Smith 
6565c6c1daeSBarry Smith   /* Is this file to be compressed */
6575c6c1daeSBarry Smith   vascii->storecompressed = PETSC_FALSE;
658a297a907SKarl Rupp 
6599566063dSJacob Faibussowitsch   PetscCall(PetscStrstr(vascii->filename, ".gz", &gz));
6605c6c1daeSBarry Smith   if (gz) {
6619566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(gz, &len));
6625c6c1daeSBarry Smith     if (len == 3) {
66308401ef6SPierre 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");
6645c6c1daeSBarry Smith       *gz                     = 0;
6655c6c1daeSBarry Smith       vascii->storecompressed = PETSC_TRUE;
6665c6c1daeSBarry Smith     }
6675c6c1daeSBarry Smith   }
6689566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank));
669dd400576SPatrick Sanan   if (rank == 0) {
6709566063dSJacob Faibussowitsch     PetscCall(PetscStrcmp(name, "stderr", &isstderr));
6719566063dSJacob Faibussowitsch     PetscCall(PetscStrcmp(name, "stdout", &isstdout));
6725c6c1daeSBarry Smith     /* empty filename means stdout */
6735c6c1daeSBarry Smith     if (name[0] == 0) isstdout = PETSC_TRUE;
6745c6c1daeSBarry Smith     if (isstderr) vascii->fd = PETSC_STDERR;
6755c6c1daeSBarry Smith     else if (isstdout) vascii->fd = PETSC_STDOUT;
6765c6c1daeSBarry Smith     else {
6779566063dSJacob Faibussowitsch       PetscCall(PetscFixFilename(name, fname));
6785c6c1daeSBarry Smith       switch (vascii->mode) {
6799371c9d4SSatish Balay       case FILE_MODE_READ: vascii->fd = fopen(fname, "r"); break;
6809371c9d4SSatish Balay       case FILE_MODE_WRITE: vascii->fd = fopen(fname, "w"); break;
6819371c9d4SSatish Balay       case FILE_MODE_APPEND: vascii->fd = fopen(fname, "a"); break;
6825c6c1daeSBarry Smith       case FILE_MODE_UPDATE:
6835c6c1daeSBarry Smith         vascii->fd = fopen(fname, "r+");
684a297a907SKarl Rupp         if (!vascii->fd) vascii->fd = fopen(fname, "w+");
6855c6c1daeSBarry Smith         break;
6865c6c1daeSBarry Smith       case FILE_MODE_APPEND_UPDATE:
6875c6c1daeSBarry Smith         /* I really want a file which is opened at the end for updating,
6885c6c1daeSBarry Smith            not a+, which opens at the beginning, but makes writes at the end.
6895c6c1daeSBarry Smith         */
6905c6c1daeSBarry Smith         vascii->fd = fopen(fname, "r+");
691a297a907SKarl Rupp         if (!vascii->fd) vascii->fd = fopen(fname, "w+");
69248a46eb9SPierre Jolivet         else PetscCall(fseek(vascii->fd, 0, SEEK_END));
6935c6c1daeSBarry Smith         break;
6949371c9d4SSatish Balay       default: 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)
7005c6c1daeSBarry Smith   PetscLogObjectState((PetscObject)viewer, "File: %s", name);
7015c6c1daeSBarry Smith #endif
7025c6c1daeSBarry Smith   PetscFunctionReturn(0);
7035c6c1daeSBarry Smith }
7045c6c1daeSBarry Smith 
7059371c9d4SSatish Balay PetscErrorCode PetscViewerGetSubViewer_ASCII(PetscViewer viewer, MPI_Comm subcomm, PetscViewer *outviewer) {
7065c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data, *ovascii;
7075c6c1daeSBarry Smith 
7085c6c1daeSBarry Smith   PetscFunctionBegin;
7099566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPushSynchronized(viewer));
71028b400f6SJacob Faibussowitsch   PetscCheck(!vascii->sviewer, PETSC_COMM_SELF, PETSC_ERR_ORDER, "SubViewer already obtained from PetscViewer and not restored");
711e5afcf28SBarry Smith   /*
7129530cbd7SBarry Smith      The following line is a bug; it does another PetscViewerASCIIPushSynchronized() on viewer, but if it is removed the code won't work
7139530cbd7SBarry 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
7149530cbd7SBarry Smith      (since the count never gets to zero) in some examples this displays information that otherwise would be lost
7159530cbd7SBarry Smith 
7169530cbd7SBarry Smith      This code also means another call to PetscViewerASCIIPopSynchronized() must be made after the PetscViewerRestoreSubViewer(), see, for example,
7179530cbd7SBarry Smith      PCView_GASM().
718e5afcf28SBarry Smith   */
7199566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPushSynchronized(viewer));
7209566063dSJacob Faibussowitsch   PetscCall(PetscViewerCreate(subcomm, outviewer));
7219566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetType(*outviewer, PETSCVIEWERASCII));
7229566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPushSynchronized(*outviewer));
7235c6c1daeSBarry Smith   ovascii            = (PetscViewer_ASCII *)(*outviewer)->data;
7245c6c1daeSBarry Smith   ovascii->fd        = vascii->fd;
7255c6c1daeSBarry Smith   ovascii->tab       = vascii->tab;
726ba5a0b41SBarry Smith   ovascii->closefile = PETSC_FALSE;
7275c6c1daeSBarry Smith 
7285c6c1daeSBarry Smith   vascii->sviewer                                      = *outviewer;
7295c6c1daeSBarry Smith   (*outviewer)->format                                 = viewer->format;
7305c6c1daeSBarry Smith   ((PetscViewer_ASCII *)((*outviewer)->data))->bviewer = viewer;
7313f08860eSBarry Smith   (*outviewer)->ops->destroy                           = PetscViewerDestroy_ASCII_SubViewer;
7325c6c1daeSBarry Smith   PetscFunctionReturn(0);
7335c6c1daeSBarry Smith }
7345c6c1daeSBarry Smith 
7359371c9d4SSatish Balay PetscErrorCode PetscViewerRestoreSubViewer_ASCII(PetscViewer viewer, MPI_Comm comm, PetscViewer *outviewer) {
7365c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
7375c6c1daeSBarry Smith 
7385c6c1daeSBarry Smith   PetscFunctionBegin;
73928b400f6SJacob Faibussowitsch   PetscCheck(ascii->sviewer, PETSC_COMM_SELF, PETSC_ERR_ORDER, "SubViewer never obtained from PetscViewer");
74008401ef6SPierre Jolivet   PetscCheck(ascii->sviewer == *outviewer, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "This PetscViewer did not generate this SubViewer");
7415c6c1daeSBarry Smith 
7429566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPopSynchronized(*outviewer));
743e5afcf28SBarry Smith   ascii->sviewer             = NULL;
7445c6c1daeSBarry Smith   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
7459566063dSJacob Faibussowitsch   PetscCall(PetscViewerDestroy(outviewer));
7469566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPopSynchronized(viewer));
7475c6c1daeSBarry Smith   PetscFunctionReturn(0);
7485c6c1daeSBarry Smith }
7495c6c1daeSBarry Smith 
7509371c9d4SSatish Balay PetscErrorCode PetscViewerView_ASCII(PetscViewer v, PetscViewer viewer) {
7512bf49c77SBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)v->data;
7522bf49c77SBarry Smith 
7532bf49c77SBarry Smith   PetscFunctionBegin;
75448a46eb9SPierre Jolivet   if (ascii->filename) PetscCall(PetscViewerASCIIPrintf(viewer, "Filename: %s\n", ascii->filename));
7552bf49c77SBarry Smith   PetscFunctionReturn(0);
7562bf49c77SBarry Smith }
7572bf49c77SBarry Smith 
7588556b5ebSBarry Smith /*MC
7598556b5ebSBarry Smith    PETSCVIEWERASCII - A viewer that prints to stdout or an ASCII file
7608556b5ebSBarry Smith 
761811af0c4SBarry Smith   Level: beginner
762811af0c4SBarry Smith 
763c2e3fba1SPatrick Sanan .seealso: `PETSC_VIEWER_STDOUT_()`, `PETSC_VIEWER_STDOUT_SELF`, `PETSC_VIEWER_STDOUT_WORLD`, `PetscViewerCreate()`, `PetscViewerASCIIOpen()`,
764db781477SPatrick Sanan           `PetscViewerMatlabOpen()`, `VecView()`, `DMView()`, `PetscViewerMatlabPutArray()`, `PETSCVIEWERBINARY`, `PETSCVIEWERMATLAB`,
765db781477SPatrick Sanan           `PetscViewerFileSetName()`, `PetscViewerFileSetMode()`, `PetscViewerFormat`, `PetscViewerType`, `PetscViewerSetType()`
7668556b5ebSBarry Smith M*/
7679371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode PetscViewerCreate_ASCII(PetscViewer viewer) {
7685c6c1daeSBarry Smith   PetscViewer_ASCII *vascii;
7695c6c1daeSBarry Smith 
7705c6c1daeSBarry Smith   PetscFunctionBegin;
771*4dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&vascii));
7725c6c1daeSBarry Smith   viewer->data = (void *)vascii;
7735c6c1daeSBarry Smith 
7745c6c1daeSBarry Smith   viewer->ops->destroy          = PetscViewerDestroy_ASCII;
7755c6c1daeSBarry Smith   viewer->ops->flush            = PetscViewerFlush_ASCII;
776559f443fSBarry Smith   viewer->ops->getsubviewer     = PetscViewerGetSubViewer_ASCII;
777559f443fSBarry Smith   viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_ASCII;
7782bf49c77SBarry Smith   viewer->ops->view             = PetscViewerView_ASCII;
7791d641e7bSMichael Lange   viewer->ops->read             = PetscViewerASCIIRead;
7805c6c1daeSBarry Smith 
7815c6c1daeSBarry Smith   /* defaults to stdout unless set with PetscViewerFileSetName() */
7825c6c1daeSBarry Smith   vascii->fd        = PETSC_STDOUT;
7835c6c1daeSBarry Smith   vascii->mode      = FILE_MODE_WRITE;
78402c9f0b5SLisandro Dalcin   vascii->bviewer   = NULL;
78502c9f0b5SLisandro Dalcin   vascii->subviewer = NULL;
78602c9f0b5SLisandro Dalcin   vascii->sviewer   = NULL;
7875c6c1daeSBarry Smith   vascii->tab       = 0;
7885c6c1daeSBarry Smith   vascii->tab_store = 0;
78902c9f0b5SLisandro Dalcin   vascii->filename  = NULL;
7905c6c1daeSBarry Smith   vascii->closefile = PETSC_TRUE;
7915c6c1daeSBarry Smith 
7929566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileSetName_C", PetscViewerFileSetName_ASCII));
7939566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileGetName_C", PetscViewerFileGetName_ASCII));
7949566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileGetMode_C", PetscViewerFileGetMode_ASCII));
7959566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileSetMode_C", PetscViewerFileSetMode_ASCII));
7965c6c1daeSBarry Smith   PetscFunctionReturn(0);
7975c6c1daeSBarry Smith }
7985c6c1daeSBarry Smith 
7995c6c1daeSBarry Smith /*@C
8005c6c1daeSBarry Smith     PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from
8015c6c1daeSBarry Smith     several processors.  Output of the first processor is followed by that of the
8025c6c1daeSBarry Smith     second, etc.
8035c6c1daeSBarry Smith 
804811af0c4SBarry Smith     Not Collective, must call collective `PetscViewerFlush()` to get the results out
8055c6c1daeSBarry Smith 
8065c6c1daeSBarry Smith     Input Parameters:
807811af0c4SBarry Smith +   viewer - the `PETSCVIEWERASCII` `PetscViewer`
8085c6c1daeSBarry Smith -   format - the usual printf() format string
8095c6c1daeSBarry Smith 
8105c6c1daeSBarry Smith     Level: intermediate
8115c6c1daeSBarry Smith 
81295452b02SPatrick Sanan     Notes:
813811af0c4SBarry Smith     You must have previously called `PetscViewerASCIIPushSynchronized()` to allow this routine to be called.
814e6abc3ddSVáclav Hapla     Then you can do multiple independent calls to this routine.
815811af0c4SBarry Smith 
816811af0c4SBarry Smith     The actual synchronized print is then done using `PetscViewerFlush()`.
817811af0c4SBarry Smith     `PetscViewerASCIIPopSynchronized()` should be then called if we are already done with the synchronized output
818e6abc3ddSVáclav Hapla     to conclude the "synchronized session".
819811af0c4SBarry Smith 
820e6abc3ddSVáclav Hapla     So the typical calling sequence looks like
821811af0c4SBarry Smith .vb
822811af0c4SBarry Smith     PetscViewerASCIIPushSynchronized(viewer);
823811af0c4SBarry Smith     PetscViewerASCIISynchronizedPrintf(viewer, ...);
824811af0c4SBarry Smith     PetscViewerASCIISynchronizedPrintf(viewer, ...);
825811af0c4SBarry Smith     ...
826811af0c4SBarry Smith     PetscViewerFlush(viewer);
827811af0c4SBarry Smith     PetscViewerASCIISynchronizedPrintf(viewer, ...);
828811af0c4SBarry Smith     PetscViewerASCIISynchronizedPrintf(viewer, ...);
829811af0c4SBarry Smith     ...
830811af0c4SBarry Smith     PetscViewerFlush(viewer);
831811af0c4SBarry Smith    PetscViewerASCIIPopSynchronized(viewer);
832811af0c4SBarry Smith .ve
8335c6c1daeSBarry Smith 
8345c6c1daeSBarry Smith     Fortran Note:
8355c6c1daeSBarry Smith       Can only print a single character* string
8365c6c1daeSBarry Smith 
837db781477SPatrick Sanan .seealso: `PetscViewerASCIIPushSynchronized()`, `PetscViewerFlush()`, `PetscViewerASCIIPopSynchronized()`,
838db781477SPatrick Sanan           `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIIOpen()`,
839db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`
8405c6c1daeSBarry Smith @*/
8419371c9d4SSatish Balay PetscErrorCode PetscViewerASCIISynchronizedPrintf(PetscViewer viewer, const char format[], ...) {
8425c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
8433f08860eSBarry Smith   PetscMPIInt        rank;
8445c6c1daeSBarry Smith   PetscInt           tab = vascii->tab;
8455c6c1daeSBarry Smith   MPI_Comm           comm;
8465c6c1daeSBarry Smith   FILE              *fp;
847559f443fSBarry Smith   PetscBool          iascii, hasbviewer = PETSC_FALSE;
8485c6c1daeSBarry Smith   int                err;
8495c6c1daeSBarry Smith 
8505c6c1daeSBarry Smith   PetscFunctionBegin;
8515c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
8525c6c1daeSBarry Smith   PetscValidCharPointer(format, 2);
8539566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
85428b400f6SJacob Faibussowitsch   PetscCheck(iascii, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Not ASCII PetscViewer");
85528b400f6SJacob Faibussowitsch   PetscCheck(vascii->allowsynchronized, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "First call PetscViewerASCIIPushSynchronized() to allow this call");
8565c6c1daeSBarry Smith 
8579566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
8589566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
8595c6c1daeSBarry Smith 
860559f443fSBarry Smith   if (vascii->bviewer) {
861559f443fSBarry Smith     hasbviewer = PETSC_TRUE;
862dd400576SPatrick Sanan     if (rank == 0) {
863559f443fSBarry Smith       vascii = (PetscViewer_ASCII *)vascii->bviewer->data;
8649566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
8659566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Comm_rank(comm, &rank));
866559f443fSBarry Smith     }
867559f443fSBarry Smith   }
8683f08860eSBarry Smith 
869559f443fSBarry Smith   fp = vascii->fd;
870559f443fSBarry Smith 
871dd400576SPatrick Sanan   if (rank == 0 && !hasbviewer) { /* First processor prints immediately to fp */
8725c6c1daeSBarry Smith     va_list     Argp;
873559f443fSBarry Smith     /* flush my own messages that I may have queued up */
874559f443fSBarry Smith     PrintfQueue next = vascii->petsc_printfqueuebase, previous;
875559f443fSBarry Smith     PetscInt    i;
876559f443fSBarry Smith     for (i = 0; i < vascii->petsc_printfqueuelength; i++) {
8779566063dSJacob Faibussowitsch       PetscCall(PetscFPrintf(comm, fp, "%s", next->string));
878559f443fSBarry Smith       previous = next;
879559f443fSBarry Smith       next     = next->next;
8809566063dSJacob Faibussowitsch       PetscCall(PetscFree(previous->string));
8819566063dSJacob Faibussowitsch       PetscCall(PetscFree(previous));
882559f443fSBarry Smith     }
88302c9f0b5SLisandro Dalcin     vascii->petsc_printfqueue       = NULL;
884559f443fSBarry Smith     vascii->petsc_printfqueuelength = 0;
8855c6c1daeSBarry Smith 
88648a46eb9SPierre Jolivet     while (tab--) PetscCall(PetscFPrintf(PETSC_COMM_SELF, fp, "  "));
8875c6c1daeSBarry Smith 
8885c6c1daeSBarry Smith     va_start(Argp, format);
8899566063dSJacob Faibussowitsch     PetscCall((*PetscVFPrintf)(fp, format, Argp));
8905c6c1daeSBarry Smith     err = fflush(fp);
89128b400f6SJacob Faibussowitsch     PetscCheck(!err, PETSC_COMM_SELF, PETSC_ERR_SYS, "fflush() failed on file");
8925c6c1daeSBarry Smith     if (petsc_history) {
8935c6c1daeSBarry Smith       va_start(Argp, format);
8949566063dSJacob Faibussowitsch       PetscCall((*PetscVFPrintf)(petsc_history, format, Argp));
8955c6c1daeSBarry Smith       err = fflush(petsc_history);
89628b400f6SJacob Faibussowitsch       PetscCheck(!err, PETSC_COMM_SELF, PETSC_ERR_SYS, "fflush() failed on file");
8975c6c1daeSBarry Smith     }
8985c6c1daeSBarry Smith     va_end(Argp);
899559f443fSBarry Smith   } else { /* other processors add to queue */
9005c6c1daeSBarry Smith     char       *string;
9015c6c1daeSBarry Smith     va_list     Argp;
9025c6c1daeSBarry Smith     size_t      fullLength;
9035c6c1daeSBarry Smith     PrintfQueue next;
9045c6c1daeSBarry Smith 
9059566063dSJacob Faibussowitsch     PetscCall(PetscNew(&next));
906559f443fSBarry Smith     if (vascii->petsc_printfqueue) {
907559f443fSBarry Smith       vascii->petsc_printfqueue->next = next;
908559f443fSBarry Smith       vascii->petsc_printfqueue       = next;
909a297a907SKarl Rupp     } else {
910559f443fSBarry Smith       vascii->petsc_printfqueuebase = vascii->petsc_printfqueue = next;
911a297a907SKarl Rupp     }
912559f443fSBarry Smith     vascii->petsc_printfqueuelength++;
9135c6c1daeSBarry Smith     next->size = QUEUESTRINGSIZE;
9149566063dSJacob Faibussowitsch     PetscCall(PetscCalloc1(next->size, &next->string));
9155c6c1daeSBarry Smith     string = next->string;
9165c6c1daeSBarry Smith     tab *= 2;
917ad540459SPierre Jolivet     while (tab--) *string++ = ' ';
9185c6c1daeSBarry Smith     va_start(Argp, format);
9199566063dSJacob Faibussowitsch     PetscCall(PetscVSNPrintf(string, next->size - 2 * vascii->tab, format, &fullLength, Argp));
9205c6c1daeSBarry Smith     va_end(Argp);
921cb500232SBarry Smith     if (fullLength > (size_t)(next->size - 2 * vascii->tab)) {
9229566063dSJacob Faibussowitsch       PetscCall(PetscFree(next->string));
92314416c0eSBarry Smith       next->size = fullLength + 2 * vascii->tab;
9249566063dSJacob Faibussowitsch       PetscCall(PetscCalloc1(next->size, &next->string));
92514416c0eSBarry Smith       string = next->string;
92614416c0eSBarry Smith       tab    = 2 * vascii->tab;
927ad540459SPierre Jolivet       while (tab--) *string++ = ' ';
92814416c0eSBarry Smith       va_start(Argp, format);
9299566063dSJacob Faibussowitsch       PetscCall(PetscVSNPrintf(string, next->size - 2 * vascii->tab, format, NULL, Argp));
93014416c0eSBarry Smith       va_end(Argp);
93114416c0eSBarry Smith     }
9325c6c1daeSBarry Smith   }
9335c6c1daeSBarry Smith   PetscFunctionReturn(0);
9345c6c1daeSBarry Smith }
9355c6c1daeSBarry Smith 
9362655f987SMichael Lange /*@C
937f8859db6SBarry Smith    PetscViewerASCIIRead - Reads from a ASCII file
9382655f987SMichael Lange 
939811af0c4SBarry Smith    Only process 0 in the `PetscViewer` may call this
9402655f987SMichael Lange 
9412655f987SMichael Lange    Input Parameters:
9422655f987SMichael Lange +  viewer - the ascii viewer
9432655f987SMichael Lange .  data - location to write the data
944060da220SMatthew G. Knepley .  num - number of items of data to read
9452655f987SMichael Lange -  datatype - type of data to read
9462655f987SMichael Lange 
947f8e4bde8SMatthew G. Knepley    Output Parameters:
948060da220SMatthew G. Knepley .  count - number of items of data actually read, or NULL
949f8e4bde8SMatthew G. Knepley 
9502655f987SMichael Lange    Level: beginner
9512655f987SMichael Lange 
952db781477SPatrick Sanan .seealso: `PetscViewerASCIIOpen()`, `PetscViewerPushFormat()`, `PetscViewerDestroy()`, `PetscViewerCreate()`, `PetscViewerFileSetMode()`, `PetscViewerFileSetName()`
953db781477SPatrick Sanan           `VecView()`, `MatView()`, `VecLoad()`, `MatLoad()`, `PetscViewerBinaryGetDescriptor()`,
954db781477SPatrick Sanan           `PetscViewerBinaryGetInfoPointer()`, `PetscFileMode`, `PetscViewer`, `PetscViewerBinaryRead()`
9552655f987SMichael Lange @*/
9569371c9d4SSatish Balay PetscErrorCode PetscViewerASCIIRead(PetscViewer viewer, void *data, PetscInt num, PetscInt *count, PetscDataType dtype) {
9572655f987SMichael Lange   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
9582655f987SMichael Lange   FILE              *fd     = vascii->fd;
9592655f987SMichael Lange   PetscInt           i;
9603b7fe8c3SMatthew G. Knepley   int                ret = 0;
961f8859db6SBarry Smith   PetscMPIInt        rank;
9622655f987SMichael Lange 
9632655f987SMichael Lange   PetscFunctionBegin;
9642655f987SMichael Lange   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
9659566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank));
966c5853193SPierre Jolivet   PetscCheck(rank == 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Can only be called from process 0 in the PetscViewer");
967060da220SMatthew G. Knepley   for (i = 0; i < num; i++) {
968f8e4bde8SMatthew G. Knepley     if (dtype == PETSC_CHAR) ret = fscanf(fd, "%c", &(((char *)data)[i]));
969f8e4bde8SMatthew G. Knepley     else if (dtype == PETSC_STRING) ret = fscanf(fd, "%s", &(((char *)data)[i]));
970a05e1a72SSatish Balay     else if (dtype == PETSC_INT) ret = fscanf(fd, "%" PetscInt_FMT, &(((PetscInt *)data)[i]));
971f8e4bde8SMatthew G. Knepley     else if (dtype == PETSC_ENUM) ret = fscanf(fd, "%d", &(((int *)data)[i]));
9729e3e4c22SLisandro Dalcin     else if (dtype == PETSC_INT64) ret = fscanf(fd, "%" PetscInt64_FMT, &(((PetscInt64 *)data)[i]));
973972064b6SLisandro Dalcin     else if (dtype == PETSC_LONG) ret = fscanf(fd, "%ld", &(((long *)data)[i]));
974f8e4bde8SMatthew G. Knepley     else if (dtype == PETSC_FLOAT) ret = fscanf(fd, "%f", &(((float *)data)[i]));
975f8e4bde8SMatthew G. Knepley     else if (dtype == PETSC_DOUBLE) ret = fscanf(fd, "%lg", &(((double *)data)[i]));
976a6e181c6SToby Isaac #if defined(PETSC_USE_REAL___FLOAT128)
977fba955ccSBarry Smith     else if (dtype == PETSC___FLOAT128) {
978fba955ccSBarry Smith       double tmp;
979fba955ccSBarry Smith       ret                     = fscanf(fd, "%lg", &tmp);
980a6e181c6SToby Isaac       ((__float128 *)data)[i] = tmp;
981a6e181c6SToby Isaac     }
982fba955ccSBarry Smith #endif
9839371c9d4SSatish Balay     else
9849371c9d4SSatish Balay       SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Data type %d not supported", (int)dtype);
98528b400f6SJacob Faibussowitsch     PetscCheck(ret, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Conversion error for data type %d", (int)dtype);
986f7d195e4SLawrence Mitchell     if (ret < 0) break; /* Proxy for EOF, need to check for it in configure */
9872655f987SMichael Lange   }
988060da220SMatthew G. Knepley   if (count) *count = i;
98908401ef6SPierre Jolivet   else PetscCheck(ret >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Insufficient data, read only %" PetscInt_FMT " < %" PetscInt_FMT " items", i, num);
9902655f987SMichael Lange   PetscFunctionReturn(0);
9912655f987SMichael Lange }
992