xref: /petsc/src/sys/classes/viewer/impls/ascii/filev.c (revision 48a46eb9bd028bec07ec0f396b1a3abb43f14558)
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 */
49*48a46eb9SPierre 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));
75*48a46eb9SPierre 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));
80*48a46eb9SPierre 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
1795c6c1daeSBarry 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:
184f8859db6SBarry Smith .    viewer - PetscViewer context, obtained from PetscViewerASCIIOpen()
185f8859db6SBarry Smith 
186f8859db6SBarry Smith     Output Parameter:
187f8859db6SBarry Smith .    fd - file pointer
188f8859db6SBarry Smith 
189f8859db6SBarry Smith     Notes: for the standard PETSCVIEWERASCII the value is valid only on process 0 of the viewer
1905c6c1daeSBarry Smith 
1915c6c1daeSBarry Smith     Level: intermediate
1925c6c1daeSBarry Smith 
1935c6c1daeSBarry Smith     Fortran Note:
1945c6c1daeSBarry Smith     This routine is not supported in Fortran.
1955c6c1daeSBarry Smith 
196db781477SPatrick Sanan .seealso: `PetscViewerASCIIOpen()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerCreate()`, `PetscViewerASCIIPrintf()`,
197db781477SPatrick Sanan           `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerFlush()`
1985c6c1daeSBarry Smith @*/
1999371c9d4SSatish Balay PetscErrorCode PetscViewerASCIIGetPointer(PetscViewer viewer, FILE **fd) {
2005c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
2015c6c1daeSBarry Smith 
2025c6c1daeSBarry Smith   PetscFunctionBegin;
2035c6c1daeSBarry Smith   *fd = vascii->fd;
2045c6c1daeSBarry Smith   PetscFunctionReturn(0);
2055c6c1daeSBarry Smith }
2065c6c1daeSBarry Smith 
2079371c9d4SSatish Balay PetscErrorCode PetscViewerFileGetMode_ASCII(PetscViewer viewer, PetscFileMode *mode) {
2085c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
2095c6c1daeSBarry Smith 
2105c6c1daeSBarry Smith   PetscFunctionBegin;
2115c6c1daeSBarry Smith   *mode = vascii->mode;
2125c6c1daeSBarry Smith   PetscFunctionReturn(0);
2135c6c1daeSBarry Smith }
2145c6c1daeSBarry Smith 
2159371c9d4SSatish Balay PetscErrorCode PetscViewerFileSetMode_ASCII(PetscViewer viewer, PetscFileMode mode) {
2165c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
2175c6c1daeSBarry Smith 
2185c6c1daeSBarry Smith   PetscFunctionBegin;
2195c6c1daeSBarry Smith   vascii->mode = mode;
2205c6c1daeSBarry Smith   PetscFunctionReturn(0);
2215c6c1daeSBarry Smith }
2225c6c1daeSBarry Smith 
2235c6c1daeSBarry Smith /*
2245c6c1daeSBarry Smith    If petsc_history is on, then all Petsc*Printf() results are saved
2255c6c1daeSBarry Smith    if the appropriate (usually .petschistory) file.
2265c6c1daeSBarry Smith */
22795c0884eSLisandro Dalcin PETSC_INTERN FILE *petsc_history;
2285c6c1daeSBarry Smith 
2295c6c1daeSBarry Smith /*@
2305c6c1daeSBarry Smith     PetscViewerASCIISetTab - Causes PetscViewer to tab in a number of times
2315c6c1daeSBarry Smith 
2325c6c1daeSBarry Smith     Not Collective, but only first processor in set has any effect
2335c6c1daeSBarry Smith 
2345c6c1daeSBarry Smith     Input Parameters:
2351575c14dSBarry Smith +    viewer - obtained with PetscViewerASCIIOpen()
2365c6c1daeSBarry Smith -    tabs - number of tabs
2375c6c1daeSBarry Smith 
2385c6c1daeSBarry Smith     Level: developer
2395c6c1daeSBarry Smith 
2405c6c1daeSBarry Smith     Fortran Note:
2415c6c1daeSBarry Smith     This routine is not supported in Fortran.
2425c6c1daeSBarry Smith 
243db781477SPatrick Sanan .seealso: `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIIGetTab()`,
244db781477SPatrick Sanan           `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIOpen()`,
245db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`, `PetscViewerASCIIPushTab()`
2465c6c1daeSBarry Smith @*/
2479371c9d4SSatish Balay PetscErrorCode PetscViewerASCIISetTab(PetscViewer viewer, PetscInt tabs) {
2485c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
2495c6c1daeSBarry Smith   PetscBool          iascii;
2505c6c1daeSBarry Smith 
2515c6c1daeSBarry Smith   PetscFunctionBegin;
2525c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
2539566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
254a297a907SKarl Rupp   if (iascii) ascii->tab = tabs;
2555c6c1daeSBarry Smith   PetscFunctionReturn(0);
2565c6c1daeSBarry Smith }
2575c6c1daeSBarry Smith 
2585c6c1daeSBarry Smith /*@
2595c6c1daeSBarry Smith     PetscViewerASCIIGetTab - Return the number of tabs used by PetscViewer.
2605c6c1daeSBarry Smith 
2615c6c1daeSBarry Smith     Not Collective, meaningful on first processor only.
2625c6c1daeSBarry Smith 
2635c6c1daeSBarry Smith     Input Parameters:
2641575c14dSBarry Smith .    viewer - obtained with PetscViewerASCIIOpen()
265a2b725a8SWilliam Gropp 
2665c6c1daeSBarry Smith     Output Parameters:
2675c6c1daeSBarry Smith .    tabs - number of tabs
2685c6c1daeSBarry Smith 
2695c6c1daeSBarry Smith     Level: developer
2705c6c1daeSBarry Smith 
2715c6c1daeSBarry Smith     Fortran Note:
2725c6c1daeSBarry Smith     This routine is not supported in Fortran.
2735c6c1daeSBarry Smith 
274db781477SPatrick Sanan .seealso: `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIISetTab()`,
275db781477SPatrick Sanan           `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIOpen()`,
276db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`, `PetscViewerASCIIPushTab()`
2775c6c1daeSBarry Smith @*/
2789371c9d4SSatish Balay PetscErrorCode PetscViewerASCIIGetTab(PetscViewer viewer, PetscInt *tabs) {
2795c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
2805c6c1daeSBarry Smith   PetscBool          iascii;
2815c6c1daeSBarry Smith 
2825c6c1daeSBarry Smith   PetscFunctionBegin;
2835c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
2849566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
285a297a907SKarl Rupp   if (iascii && tabs) *tabs = ascii->tab;
2865c6c1daeSBarry Smith   PetscFunctionReturn(0);
2875c6c1daeSBarry Smith }
2885c6c1daeSBarry Smith 
2895c6c1daeSBarry Smith /*@
2905c6c1daeSBarry Smith     PetscViewerASCIIAddTab - Add to the number of times an ASCII viewer tabs before printing
2915c6c1daeSBarry Smith 
2925c6c1daeSBarry Smith     Not Collective, but only first processor in set has any effect
2935c6c1daeSBarry Smith 
2945c6c1daeSBarry Smith     Input Parameters:
2951575c14dSBarry Smith +    viewer - obtained with PetscViewerASCIIOpen()
2965c6c1daeSBarry Smith -    tabs - number of tabs
2975c6c1daeSBarry Smith 
2985c6c1daeSBarry Smith     Level: developer
2995c6c1daeSBarry Smith 
3005c6c1daeSBarry Smith     Fortran Note:
3015c6c1daeSBarry Smith     This routine is not supported in Fortran.
3025c6c1daeSBarry Smith 
303db781477SPatrick Sanan .seealso: `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`,
304db781477SPatrick Sanan           `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIOpen()`,
305db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`, `PetscViewerASCIIPushTab()`
3065c6c1daeSBarry Smith @*/
3079371c9d4SSatish Balay PetscErrorCode PetscViewerASCIIAddTab(PetscViewer viewer, PetscInt tabs) {
3085c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
3095c6c1daeSBarry Smith   PetscBool          iascii;
3105c6c1daeSBarry Smith 
3115c6c1daeSBarry Smith   PetscFunctionBegin;
3125c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
3139566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
314a297a907SKarl Rupp   if (iascii) ascii->tab += tabs;
3155c6c1daeSBarry Smith   PetscFunctionReturn(0);
3165c6c1daeSBarry Smith }
3175c6c1daeSBarry Smith 
3185c6c1daeSBarry Smith /*@
3195c6c1daeSBarry Smith     PetscViewerASCIISubtractTab - Subtracts from the number of times an ASCII viewer tabs before printing
3205c6c1daeSBarry Smith 
3215c6c1daeSBarry Smith     Not Collective, but only first processor in set has any effect
3225c6c1daeSBarry Smith 
3235c6c1daeSBarry Smith     Input Parameters:
3241575c14dSBarry Smith +    viewer - obtained with PetscViewerASCIIOpen()
3255c6c1daeSBarry Smith -    tabs - number of tabs
3265c6c1daeSBarry Smith 
3275c6c1daeSBarry Smith     Level: developer
3285c6c1daeSBarry Smith 
3295c6c1daeSBarry Smith     Fortran Note:
3305c6c1daeSBarry Smith     This routine is not supported in Fortran.
3315c6c1daeSBarry Smith 
332db781477SPatrick Sanan .seealso: `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`,
333db781477SPatrick Sanan           `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIOpen()`,
334db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`, `PetscViewerASCIIPushTab()`
3355c6c1daeSBarry Smith @*/
3369371c9d4SSatish Balay PetscErrorCode PetscViewerASCIISubtractTab(PetscViewer viewer, PetscInt tabs) {
3375c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
3385c6c1daeSBarry Smith   PetscBool          iascii;
3395c6c1daeSBarry Smith 
3405c6c1daeSBarry Smith   PetscFunctionBegin;
3415c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
3429566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
343a297a907SKarl Rupp   if (iascii) ascii->tab -= tabs;
3445c6c1daeSBarry Smith   PetscFunctionReturn(0);
3455c6c1daeSBarry Smith }
3465c6c1daeSBarry Smith 
3475c6c1daeSBarry Smith /*@C
3481575c14dSBarry Smith     PetscViewerASCIIPushSynchronized - Allows calls to PetscViewerASCIISynchronizedPrintf() for this viewer
3495c6c1daeSBarry Smith 
3505c6c1daeSBarry Smith     Collective on PetscViewer
3515c6c1daeSBarry Smith 
3525c6c1daeSBarry Smith     Input Parameters:
3531575c14dSBarry Smith .    viewer - obtained with PetscViewerASCIIOpen()
3545c6c1daeSBarry Smith 
3555c6c1daeSBarry Smith     Level: intermediate
3565c6c1daeSBarry Smith 
357e6abc3ddSVáclav Hapla     Notes:
358e6abc3ddSVáclav Hapla     See documentation of PetscViewerASCIISynchronizedPrintf() for more details how the synchronized output should be done properly.
3595c6c1daeSBarry Smith 
360db781477SPatrick Sanan .seealso: `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerFlush()`, `PetscViewerASCIIPopSynchronized()`,
361db781477SPatrick Sanan           `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIIOpen()`,
362db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`
3635c6c1daeSBarry Smith @*/
3649371c9d4SSatish Balay PetscErrorCode PetscViewerASCIIPushSynchronized(PetscViewer viewer) {
3655c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
3665c6c1daeSBarry Smith   PetscBool          iascii;
3675c6c1daeSBarry Smith 
3685c6c1daeSBarry Smith   PetscFunctionBegin;
3695c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
37028b400f6SJacob Faibussowitsch   PetscCheck(!ascii->sviewer, PetscObjectComm((PetscObject)viewer), PETSC_ERR_ARG_WRONGSTATE, "Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
3719566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
3721575c14dSBarry Smith   if (iascii) ascii->allowsynchronized++;
3731575c14dSBarry Smith   PetscFunctionReturn(0);
3741575c14dSBarry Smith }
3751575c14dSBarry Smith 
3761575c14dSBarry Smith /*@C
3771575c14dSBarry Smith     PetscViewerASCIIPopSynchronized - Undoes most recent PetscViewerASCIIPushSynchronized() for this viewer
3781575c14dSBarry Smith 
3791575c14dSBarry Smith     Collective on PetscViewer
3801575c14dSBarry Smith 
3811575c14dSBarry Smith     Input Parameters:
3821575c14dSBarry Smith .    viewer - obtained with PetscViewerASCIIOpen()
3831575c14dSBarry Smith 
3841575c14dSBarry Smith     Level: intermediate
3851575c14dSBarry Smith 
386e6abc3ddSVáclav Hapla     Notes:
387e6abc3ddSVáclav Hapla     See documentation of PetscViewerASCIISynchronizedPrintf() for more details how the synchronized output should be done properly.
3881575c14dSBarry Smith 
389db781477SPatrick Sanan .seealso: `PetscViewerASCIIPushSynchronized()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerFlush()`,
390db781477SPatrick Sanan           `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIIOpen()`,
391db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`
3921575c14dSBarry Smith @*/
3939371c9d4SSatish Balay PetscErrorCode PetscViewerASCIIPopSynchronized(PetscViewer viewer) {
3941575c14dSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
3951575c14dSBarry Smith   PetscBool          iascii;
3961575c14dSBarry Smith 
3971575c14dSBarry Smith   PetscFunctionBegin;
3981575c14dSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
39928b400f6SJacob Faibussowitsch   PetscCheck(!ascii->sviewer, PetscObjectComm((PetscObject)viewer), PETSC_ERR_ARG_WRONGSTATE, "Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
4009566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
4011575c14dSBarry Smith   if (iascii) {
4021575c14dSBarry Smith     ascii->allowsynchronized--;
40308401ef6SPierre Jolivet     PetscCheck(ascii->allowsynchronized >= 0, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Called more times than PetscViewerASCIIPushSynchronized()");
4041575c14dSBarry Smith   }
4055c6c1daeSBarry Smith   PetscFunctionReturn(0);
4065c6c1daeSBarry Smith }
4075c6c1daeSBarry Smith 
4081c297824SMatthew G. Knepley /*@C
4095c6c1daeSBarry Smith     PetscViewerASCIIPushTab - Adds one more tab to the amount that PetscViewerASCIIPrintf()
4105c6c1daeSBarry Smith      lines are tabbed.
4115c6c1daeSBarry Smith 
4125c6c1daeSBarry Smith     Not Collective, but only first processor in set has any effect
4135c6c1daeSBarry Smith 
4145c6c1daeSBarry Smith     Input Parameters:
4151575c14dSBarry Smith .    viewer - obtained with PetscViewerASCIIOpen()
4165c6c1daeSBarry Smith 
4175c6c1daeSBarry Smith     Level: developer
4185c6c1daeSBarry Smith 
4195c6c1daeSBarry Smith     Fortran Note:
4205c6c1daeSBarry Smith     This routine is not supported in Fortran.
4215c6c1daeSBarry Smith 
422db781477SPatrick Sanan .seealso: `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`,
423db781477SPatrick Sanan           `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIOpen()`,
424db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`
4255c6c1daeSBarry Smith @*/
4269371c9d4SSatish Balay PetscErrorCode PetscViewerASCIIPushTab(PetscViewer viewer) {
4275c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
4285c6c1daeSBarry Smith   PetscBool          iascii;
4295c6c1daeSBarry Smith 
4305c6c1daeSBarry Smith   PetscFunctionBegin;
4315c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
4329566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
433a297a907SKarl Rupp   if (iascii) ascii->tab++;
4345c6c1daeSBarry Smith   PetscFunctionReturn(0);
4355c6c1daeSBarry Smith }
4365c6c1daeSBarry Smith 
4371c297824SMatthew G. Knepley /*@C
4385c6c1daeSBarry Smith     PetscViewerASCIIPopTab - Removes one tab from the amount that PetscViewerASCIIPrintf()
4395c6c1daeSBarry Smith      lines are tabbed.
4405c6c1daeSBarry Smith 
4415c6c1daeSBarry Smith     Not Collective, but only first processor in set has any effect
4425c6c1daeSBarry Smith 
4435c6c1daeSBarry Smith     Input Parameters:
4441575c14dSBarry 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 /*@
4705c6c1daeSBarry 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:
4751575c14dSBarry Smith +    viewer - obtained with PetscViewerASCIIOpen()
4765c6c1daeSBarry 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:
5131575c14dSBarry 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:
5195c6c1daeSBarry 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;
569*48a46eb9SPierre 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;
578*48a46eb9SPierre 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
5895c6c1daeSBarry Smith      PetscViewerFileSetName - Sets the name of the file the PetscViewer uses.
5905c6c1daeSBarry Smith 
5915c6c1daeSBarry Smith     Collective on PetscViewer
5925c6c1daeSBarry Smith 
5935c6c1daeSBarry Smith   Input Parameters:
5945c6c1daeSBarry Smith +  viewer - the PetscViewer; either ASCII or binary
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 
6025c6c1daeSBarry Smith @*/
6039371c9d4SSatish Balay PetscErrorCode PetscViewerFileSetName(PetscViewer viewer, const char name[]) {
604cc843e7aSLisandro Dalcin   char filename[PETSC_MAX_PATH_LEN];
6055c6c1daeSBarry Smith 
6065c6c1daeSBarry Smith   PetscFunctionBegin;
6075c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
6085c6c1daeSBarry Smith   PetscValidCharPointer(name, 2);
6099566063dSJacob Faibussowitsch   PetscCall(PetscStrreplace(PetscObjectComm((PetscObject)viewer), name, filename, sizeof(filename)));
610cac4c232SBarry Smith   PetscTryMethod(viewer, "PetscViewerFileSetName_C", (PetscViewer, const char[]), (viewer, filename));
6115c6c1daeSBarry Smith   PetscFunctionReturn(0);
6125c6c1daeSBarry Smith }
6135c6c1daeSBarry Smith 
6145c6c1daeSBarry Smith /*@C
6155c6c1daeSBarry Smith      PetscViewerFileGetName - Gets the name of the file the PetscViewer uses.
6165c6c1daeSBarry Smith 
6175c6c1daeSBarry Smith     Not Collective
6185c6c1daeSBarry Smith 
6195c6c1daeSBarry Smith   Input Parameter:
6205c6c1daeSBarry Smith .  viewer - the PetscViewer; either ASCII or binary
6215c6c1daeSBarry Smith 
6225c6c1daeSBarry Smith   Output Parameter:
6235c6c1daeSBarry Smith .  name - the name of the file it is using
6245c6c1daeSBarry Smith 
6255c6c1daeSBarry Smith     Level: advanced
6265c6c1daeSBarry Smith 
627db781477SPatrick Sanan .seealso: `PetscViewerCreate()`, `PetscViewerSetType()`, `PetscViewerASCIIOpen()`, `PetscViewerBinaryOpen()`, `PetscViewerFileSetName()`
6285c6c1daeSBarry Smith 
6295c6c1daeSBarry Smith @*/
6309371c9d4SSatish Balay PetscErrorCode PetscViewerFileGetName(PetscViewer viewer, const char **name) {
6315c6c1daeSBarry Smith   PetscFunctionBegin;
6325c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
6336e05b1faSLisandro Dalcin   PetscValidPointer(name, 2);
634cac4c232SBarry Smith   PetscUseMethod(viewer, "PetscViewerFileGetName_C", (PetscViewer, const char **), (viewer, name));
6355c6c1daeSBarry Smith   PetscFunctionReturn(0);
6365c6c1daeSBarry Smith }
6375c6c1daeSBarry Smith 
6389371c9d4SSatish Balay PetscErrorCode PetscViewerFileGetName_ASCII(PetscViewer viewer, const char **name) {
6395c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
6405c6c1daeSBarry Smith 
6415c6c1daeSBarry Smith   PetscFunctionBegin;
6425c6c1daeSBarry Smith   *name = vascii->filename;
6435c6c1daeSBarry Smith   PetscFunctionReturn(0);
6445c6c1daeSBarry Smith }
6455c6c1daeSBarry Smith 
6469371c9d4SSatish Balay PetscErrorCode PetscViewerFileSetName_ASCII(PetscViewer viewer, const char name[]) {
6475c6c1daeSBarry Smith   size_t             len;
6485c6c1daeSBarry Smith   char               fname[PETSC_MAX_PATH_LEN], *gz;
6495c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
6505c6c1daeSBarry Smith   PetscBool          isstderr, isstdout;
6515c6c1daeSBarry Smith   PetscMPIInt        rank;
6525c6c1daeSBarry Smith 
6535c6c1daeSBarry Smith   PetscFunctionBegin;
6549566063dSJacob Faibussowitsch   PetscCall(PetscViewerFileClose_ASCII(viewer));
6555c6c1daeSBarry Smith   if (!name) PetscFunctionReturn(0);
6569566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(name, &vascii->filename));
6575c6c1daeSBarry Smith 
6585c6c1daeSBarry Smith   /* Is this file to be compressed */
6595c6c1daeSBarry Smith   vascii->storecompressed = PETSC_FALSE;
660a297a907SKarl Rupp 
6619566063dSJacob Faibussowitsch   PetscCall(PetscStrstr(vascii->filename, ".gz", &gz));
6625c6c1daeSBarry Smith   if (gz) {
6639566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(gz, &len));
6645c6c1daeSBarry Smith     if (len == 3) {
66508401ef6SPierre 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");
6665c6c1daeSBarry Smith       *gz                     = 0;
6675c6c1daeSBarry Smith       vascii->storecompressed = PETSC_TRUE;
6685c6c1daeSBarry Smith     }
6695c6c1daeSBarry Smith   }
6709566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank));
671dd400576SPatrick Sanan   if (rank == 0) {
6729566063dSJacob Faibussowitsch     PetscCall(PetscStrcmp(name, "stderr", &isstderr));
6739566063dSJacob Faibussowitsch     PetscCall(PetscStrcmp(name, "stdout", &isstdout));
6745c6c1daeSBarry Smith     /* empty filename means stdout */
6755c6c1daeSBarry Smith     if (name[0] == 0) isstdout = PETSC_TRUE;
6765c6c1daeSBarry Smith     if (isstderr) vascii->fd = PETSC_STDERR;
6775c6c1daeSBarry Smith     else if (isstdout) vascii->fd = PETSC_STDOUT;
6785c6c1daeSBarry Smith     else {
6799566063dSJacob Faibussowitsch       PetscCall(PetscFixFilename(name, fname));
6805c6c1daeSBarry Smith       switch (vascii->mode) {
6819371c9d4SSatish Balay       case FILE_MODE_READ: vascii->fd = fopen(fname, "r"); break;
6829371c9d4SSatish Balay       case FILE_MODE_WRITE: vascii->fd = fopen(fname, "w"); break;
6839371c9d4SSatish Balay       case FILE_MODE_APPEND: vascii->fd = fopen(fname, "a"); break;
6845c6c1daeSBarry Smith       case FILE_MODE_UPDATE:
6855c6c1daeSBarry Smith         vascii->fd = fopen(fname, "r+");
686a297a907SKarl Rupp         if (!vascii->fd) vascii->fd = fopen(fname, "w+");
6875c6c1daeSBarry Smith         break;
6885c6c1daeSBarry Smith       case FILE_MODE_APPEND_UPDATE:
6895c6c1daeSBarry Smith         /* I really want a file which is opened at the end for updating,
6905c6c1daeSBarry Smith            not a+, which opens at the beginning, but makes writes at the end.
6915c6c1daeSBarry Smith         */
6925c6c1daeSBarry Smith         vascii->fd = fopen(fname, "r+");
693a297a907SKarl Rupp         if (!vascii->fd) vascii->fd = fopen(fname, "w+");
694*48a46eb9SPierre Jolivet         else PetscCall(fseek(vascii->fd, 0, SEEK_END));
6955c6c1daeSBarry Smith         break;
6969371c9d4SSatish Balay       default: SETERRQ(PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Unsupported file mode %s", PetscFileModes[vascii->mode]);
6975c6c1daeSBarry Smith       }
69828b400f6SJacob Faibussowitsch       PetscCheck(vascii->fd, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Cannot open PetscViewer file: %s", fname);
6995c6c1daeSBarry Smith     }
7005c6c1daeSBarry Smith   }
7015c6c1daeSBarry Smith #if defined(PETSC_USE_LOG)
7025c6c1daeSBarry Smith   PetscLogObjectState((PetscObject)viewer, "File: %s", name);
7035c6c1daeSBarry Smith #endif
7045c6c1daeSBarry Smith   PetscFunctionReturn(0);
7055c6c1daeSBarry Smith }
7065c6c1daeSBarry Smith 
7079371c9d4SSatish Balay PetscErrorCode PetscViewerGetSubViewer_ASCII(PetscViewer viewer, MPI_Comm subcomm, PetscViewer *outviewer) {
7085c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data, *ovascii;
7095c6c1daeSBarry Smith 
7105c6c1daeSBarry Smith   PetscFunctionBegin;
7119566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPushSynchronized(viewer));
71228b400f6SJacob Faibussowitsch   PetscCheck(!vascii->sviewer, PETSC_COMM_SELF, PETSC_ERR_ORDER, "SubViewer already obtained from PetscViewer and not restored");
713e5afcf28SBarry Smith   /*
7149530cbd7SBarry Smith      The following line is a bug; it does another PetscViewerASCIIPushSynchronized() on viewer, but if it is removed the code won't work
7159530cbd7SBarry 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
7169530cbd7SBarry Smith      (since the count never gets to zero) in some examples this displays information that otherwise would be lost
7179530cbd7SBarry Smith 
7189530cbd7SBarry Smith      This code also means another call to PetscViewerASCIIPopSynchronized() must be made after the PetscViewerRestoreSubViewer(), see, for example,
7199530cbd7SBarry Smith      PCView_GASM().
720e5afcf28SBarry Smith   */
7219566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPushSynchronized(viewer));
7229566063dSJacob Faibussowitsch   PetscCall(PetscViewerCreate(subcomm, outviewer));
7239566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetType(*outviewer, PETSCVIEWERASCII));
7249566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPushSynchronized(*outviewer));
7255c6c1daeSBarry Smith   ovascii            = (PetscViewer_ASCII *)(*outviewer)->data;
7265c6c1daeSBarry Smith   ovascii->fd        = vascii->fd;
7275c6c1daeSBarry Smith   ovascii->tab       = vascii->tab;
728ba5a0b41SBarry Smith   ovascii->closefile = PETSC_FALSE;
7295c6c1daeSBarry Smith 
7305c6c1daeSBarry Smith   vascii->sviewer                                      = *outviewer;
7315c6c1daeSBarry Smith   (*outviewer)->format                                 = viewer->format;
7325c6c1daeSBarry Smith   ((PetscViewer_ASCII *)((*outviewer)->data))->bviewer = viewer;
7333f08860eSBarry Smith   (*outviewer)->ops->destroy                           = PetscViewerDestroy_ASCII_SubViewer;
7345c6c1daeSBarry Smith   PetscFunctionReturn(0);
7355c6c1daeSBarry Smith }
7365c6c1daeSBarry Smith 
7379371c9d4SSatish Balay PetscErrorCode PetscViewerRestoreSubViewer_ASCII(PetscViewer viewer, MPI_Comm comm, PetscViewer *outviewer) {
7385c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
7395c6c1daeSBarry Smith 
7405c6c1daeSBarry Smith   PetscFunctionBegin;
74128b400f6SJacob Faibussowitsch   PetscCheck(ascii->sviewer, PETSC_COMM_SELF, PETSC_ERR_ORDER, "SubViewer never obtained from PetscViewer");
74208401ef6SPierre Jolivet   PetscCheck(ascii->sviewer == *outviewer, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "This PetscViewer did not generate this SubViewer");
7435c6c1daeSBarry Smith 
7449566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPopSynchronized(*outviewer));
745e5afcf28SBarry Smith   ascii->sviewer             = NULL;
7465c6c1daeSBarry Smith   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
7479566063dSJacob Faibussowitsch   PetscCall(PetscViewerDestroy(outviewer));
7489566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPopSynchronized(viewer));
7495c6c1daeSBarry Smith   PetscFunctionReturn(0);
7505c6c1daeSBarry Smith }
7515c6c1daeSBarry Smith 
7529371c9d4SSatish Balay PetscErrorCode PetscViewerView_ASCII(PetscViewer v, PetscViewer viewer) {
7532bf49c77SBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)v->data;
7542bf49c77SBarry Smith 
7552bf49c77SBarry Smith   PetscFunctionBegin;
756*48a46eb9SPierre Jolivet   if (ascii->filename) PetscCall(PetscViewerASCIIPrintf(viewer, "Filename: %s\n", ascii->filename));
7572bf49c77SBarry Smith   PetscFunctionReturn(0);
7582bf49c77SBarry Smith }
7592bf49c77SBarry Smith 
7608556b5ebSBarry Smith /*MC
7618556b5ebSBarry Smith    PETSCVIEWERASCII - A viewer that prints to stdout or an ASCII file
7628556b5ebSBarry 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 
7671b266c99SBarry Smith   Level: beginner
7681b266c99SBarry Smith 
7698556b5ebSBarry Smith M*/
7709371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode PetscViewerCreate_ASCII(PetscViewer viewer) {
7715c6c1daeSBarry Smith   PetscViewer_ASCII *vascii;
7725c6c1daeSBarry Smith 
7735c6c1daeSBarry Smith   PetscFunctionBegin;
7749566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(viewer, &vascii));
7755c6c1daeSBarry Smith   viewer->data = (void *)vascii;
7765c6c1daeSBarry Smith 
7775c6c1daeSBarry Smith   viewer->ops->destroy          = PetscViewerDestroy_ASCII;
7785c6c1daeSBarry Smith   viewer->ops->flush            = PetscViewerFlush_ASCII;
779559f443fSBarry Smith   viewer->ops->getsubviewer     = PetscViewerGetSubViewer_ASCII;
780559f443fSBarry Smith   viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_ASCII;
7812bf49c77SBarry Smith   viewer->ops->view             = PetscViewerView_ASCII;
7821d641e7bSMichael Lange   viewer->ops->read             = PetscViewerASCIIRead;
7835c6c1daeSBarry Smith 
7845c6c1daeSBarry Smith   /* defaults to stdout unless set with PetscViewerFileSetName() */
7855c6c1daeSBarry Smith   vascii->fd        = PETSC_STDOUT;
7865c6c1daeSBarry Smith   vascii->mode      = FILE_MODE_WRITE;
78702c9f0b5SLisandro Dalcin   vascii->bviewer   = NULL;
78802c9f0b5SLisandro Dalcin   vascii->subviewer = NULL;
78902c9f0b5SLisandro Dalcin   vascii->sviewer   = NULL;
7905c6c1daeSBarry Smith   vascii->tab       = 0;
7915c6c1daeSBarry Smith   vascii->tab_store = 0;
79202c9f0b5SLisandro Dalcin   vascii->filename  = NULL;
7935c6c1daeSBarry Smith   vascii->closefile = PETSC_TRUE;
7945c6c1daeSBarry Smith 
7959566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileSetName_C", PetscViewerFileSetName_ASCII));
7969566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileGetName_C", PetscViewerFileGetName_ASCII));
7979566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileGetMode_C", PetscViewerFileGetMode_ASCII));
7989566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileSetMode_C", PetscViewerFileSetMode_ASCII));
7995c6c1daeSBarry Smith   PetscFunctionReturn(0);
8005c6c1daeSBarry Smith }
8015c6c1daeSBarry Smith 
8025c6c1daeSBarry Smith /*@C
8035c6c1daeSBarry Smith     PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from
8045c6c1daeSBarry Smith     several processors.  Output of the first processor is followed by that of the
8055c6c1daeSBarry Smith     second, etc.
8065c6c1daeSBarry Smith 
8075c6c1daeSBarry Smith     Not Collective, must call collective PetscViewerFlush() to get the results out
8085c6c1daeSBarry Smith 
8095c6c1daeSBarry Smith     Input Parameters:
8105c6c1daeSBarry Smith +   viewer - the ASCII PetscViewer
8115c6c1daeSBarry Smith -   format - the usual printf() format string
8125c6c1daeSBarry Smith 
8135c6c1daeSBarry Smith     Level: intermediate
8145c6c1daeSBarry Smith 
81595452b02SPatrick Sanan     Notes:
816e6abc3ddSVáclav Hapla     You must have previously called PetscViewerASCIIPushSynchronized() to allow this routine to be called.
817e6abc3ddSVáclav Hapla     Then you can do multiple independent calls to this routine.
818e6abc3ddSVáclav Hapla     The actual synchronized print is then done using PetscViewerFlush().
819e6abc3ddSVáclav Hapla     PetscViewerASCIIPopSynchronized() should be then called if we are already done with the synchronized output
820e6abc3ddSVáclav Hapla     to conclude the "synchronized session".
821e6abc3ddSVáclav Hapla     So the typical calling sequence looks like
822e6abc3ddSVáclav Hapla $ PetscViewerASCIIPushSynchronized(viewer);
823e6abc3ddSVáclav Hapla $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
824e6abc3ddSVáclav Hapla $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
825e6abc3ddSVáclav Hapla $ ...
826e6abc3ddSVáclav Hapla $ PetscViewerFlush(viewer);
827e6abc3ddSVáclav Hapla $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
828e6abc3ddSVáclav Hapla $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
829e6abc3ddSVáclav Hapla $ ...
830e6abc3ddSVáclav Hapla $ PetscViewerFlush(viewer);
831e6abc3ddSVáclav Hapla $ PetscViewerASCIIPopSynchronized(viewer);
8325c6c1daeSBarry Smith 
8335c6c1daeSBarry Smith     Fortran Note:
8345c6c1daeSBarry Smith       Can only print a single character* string
8355c6c1daeSBarry Smith 
836db781477SPatrick Sanan .seealso: `PetscViewerASCIIPushSynchronized()`, `PetscViewerFlush()`, `PetscViewerASCIIPopSynchronized()`,
837db781477SPatrick Sanan           `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIIOpen()`,
838db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`
8395c6c1daeSBarry Smith @*/
8409371c9d4SSatish Balay PetscErrorCode PetscViewerASCIISynchronizedPrintf(PetscViewer viewer, const char format[], ...) {
8415c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
8423f08860eSBarry Smith   PetscMPIInt        rank;
8435c6c1daeSBarry Smith   PetscInt           tab = vascii->tab;
8445c6c1daeSBarry Smith   MPI_Comm           comm;
8455c6c1daeSBarry Smith   FILE              *fp;
846559f443fSBarry Smith   PetscBool          iascii, hasbviewer = PETSC_FALSE;
8475c6c1daeSBarry Smith   int                err;
8485c6c1daeSBarry Smith 
8495c6c1daeSBarry Smith   PetscFunctionBegin;
8505c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
8515c6c1daeSBarry Smith   PetscValidCharPointer(format, 2);
8529566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
85328b400f6SJacob Faibussowitsch   PetscCheck(iascii, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Not ASCII PetscViewer");
85428b400f6SJacob Faibussowitsch   PetscCheck(vascii->allowsynchronized, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "First call PetscViewerASCIIPushSynchronized() to allow this call");
8555c6c1daeSBarry Smith 
8569566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
8579566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
8585c6c1daeSBarry Smith 
859559f443fSBarry Smith   if (vascii->bviewer) {
860559f443fSBarry Smith     hasbviewer = PETSC_TRUE;
861dd400576SPatrick Sanan     if (rank == 0) {
862559f443fSBarry Smith       vascii = (PetscViewer_ASCII *)vascii->bviewer->data;
8639566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
8649566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Comm_rank(comm, &rank));
865559f443fSBarry Smith     }
866559f443fSBarry Smith   }
8673f08860eSBarry Smith 
868559f443fSBarry Smith   fp = vascii->fd;
869559f443fSBarry Smith 
870dd400576SPatrick Sanan   if (rank == 0 && !hasbviewer) { /* First processor prints immediately to fp */
8715c6c1daeSBarry Smith     va_list     Argp;
872559f443fSBarry Smith     /* flush my own messages that I may have queued up */
873559f443fSBarry Smith     PrintfQueue next = vascii->petsc_printfqueuebase, previous;
874559f443fSBarry Smith     PetscInt    i;
875559f443fSBarry Smith     for (i = 0; i < vascii->petsc_printfqueuelength; i++) {
8769566063dSJacob Faibussowitsch       PetscCall(PetscFPrintf(comm, fp, "%s", next->string));
877559f443fSBarry Smith       previous = next;
878559f443fSBarry Smith       next     = next->next;
8799566063dSJacob Faibussowitsch       PetscCall(PetscFree(previous->string));
8809566063dSJacob Faibussowitsch       PetscCall(PetscFree(previous));
881559f443fSBarry Smith     }
88202c9f0b5SLisandro Dalcin     vascii->petsc_printfqueue       = NULL;
883559f443fSBarry Smith     vascii->petsc_printfqueuelength = 0;
8845c6c1daeSBarry Smith 
885*48a46eb9SPierre Jolivet     while (tab--) PetscCall(PetscFPrintf(PETSC_COMM_SELF, fp, "  "));
8865c6c1daeSBarry Smith 
8875c6c1daeSBarry Smith     va_start(Argp, format);
8889566063dSJacob Faibussowitsch     PetscCall((*PetscVFPrintf)(fp, format, Argp));
8895c6c1daeSBarry Smith     err = fflush(fp);
89028b400f6SJacob Faibussowitsch     PetscCheck(!err, PETSC_COMM_SELF, PETSC_ERR_SYS, "fflush() failed on file");
8915c6c1daeSBarry Smith     if (petsc_history) {
8925c6c1daeSBarry Smith       va_start(Argp, format);
8939566063dSJacob Faibussowitsch       PetscCall((*PetscVFPrintf)(petsc_history, format, Argp));
8945c6c1daeSBarry Smith       err = fflush(petsc_history);
89528b400f6SJacob Faibussowitsch       PetscCheck(!err, PETSC_COMM_SELF, PETSC_ERR_SYS, "fflush() failed on file");
8965c6c1daeSBarry Smith     }
8975c6c1daeSBarry Smith     va_end(Argp);
898559f443fSBarry Smith   } else { /* other processors add to queue */
8995c6c1daeSBarry Smith     char       *string;
9005c6c1daeSBarry Smith     va_list     Argp;
9015c6c1daeSBarry Smith     size_t      fullLength;
9025c6c1daeSBarry Smith     PrintfQueue next;
9035c6c1daeSBarry Smith 
9049566063dSJacob Faibussowitsch     PetscCall(PetscNew(&next));
905559f443fSBarry Smith     if (vascii->petsc_printfqueue) {
906559f443fSBarry Smith       vascii->petsc_printfqueue->next = next;
907559f443fSBarry Smith       vascii->petsc_printfqueue       = next;
908a297a907SKarl Rupp     } else {
909559f443fSBarry Smith       vascii->petsc_printfqueuebase = vascii->petsc_printfqueue = next;
910a297a907SKarl Rupp     }
911559f443fSBarry Smith     vascii->petsc_printfqueuelength++;
9125c6c1daeSBarry Smith     next->size = QUEUESTRINGSIZE;
9139566063dSJacob Faibussowitsch     PetscCall(PetscCalloc1(next->size, &next->string));
9145c6c1daeSBarry Smith     string = next->string;
9155c6c1daeSBarry Smith     tab *= 2;
9169371c9d4SSatish Balay     while (tab--) { *string++ = ' '; }
9175c6c1daeSBarry Smith     va_start(Argp, format);
9189566063dSJacob Faibussowitsch     PetscCall(PetscVSNPrintf(string, next->size - 2 * vascii->tab, format, &fullLength, Argp));
9195c6c1daeSBarry Smith     va_end(Argp);
920cb500232SBarry Smith     if (fullLength > (size_t)(next->size - 2 * vascii->tab)) {
9219566063dSJacob Faibussowitsch       PetscCall(PetscFree(next->string));
92214416c0eSBarry Smith       next->size = fullLength + 2 * vascii->tab;
9239566063dSJacob Faibussowitsch       PetscCall(PetscCalloc1(next->size, &next->string));
92414416c0eSBarry Smith       string = next->string;
92514416c0eSBarry Smith       tab    = 2 * vascii->tab;
9269371c9d4SSatish Balay       while (tab--) { *string++ = ' '; }
92714416c0eSBarry Smith       va_start(Argp, format);
9289566063dSJacob Faibussowitsch       PetscCall(PetscVSNPrintf(string, next->size - 2 * vascii->tab, format, NULL, Argp));
92914416c0eSBarry Smith       va_end(Argp);
93014416c0eSBarry Smith     }
9315c6c1daeSBarry Smith   }
9325c6c1daeSBarry Smith   PetscFunctionReturn(0);
9335c6c1daeSBarry Smith }
9345c6c1daeSBarry Smith 
9352655f987SMichael Lange /*@C
936f8859db6SBarry Smith    PetscViewerASCIIRead - Reads from a ASCII file
9372655f987SMichael Lange 
938f8859db6SBarry Smith    Only process 0 in the PetscViewer may call this
9392655f987SMichael Lange 
9402655f987SMichael Lange    Input Parameters:
9412655f987SMichael Lange +  viewer - the ascii viewer
9422655f987SMichael Lange .  data - location to write the data
943060da220SMatthew G. Knepley .  num - number of items of data to read
9442655f987SMichael Lange -  datatype - type of data to read
9452655f987SMichael Lange 
946f8e4bde8SMatthew G. Knepley    Output Parameters:
947060da220SMatthew G. Knepley .  count - number of items of data actually read, or NULL
948f8e4bde8SMatthew G. Knepley 
9492655f987SMichael Lange    Level: beginner
9502655f987SMichael Lange 
951db781477SPatrick Sanan .seealso: `PetscViewerASCIIOpen()`, `PetscViewerPushFormat()`, `PetscViewerDestroy()`, `PetscViewerCreate()`, `PetscViewerFileSetMode()`, `PetscViewerFileSetName()`
952db781477SPatrick Sanan           `VecView()`, `MatView()`, `VecLoad()`, `MatLoad()`, `PetscViewerBinaryGetDescriptor()`,
953db781477SPatrick Sanan           `PetscViewerBinaryGetInfoPointer()`, `PetscFileMode`, `PetscViewer`, `PetscViewerBinaryRead()`
9542655f987SMichael Lange @*/
9559371c9d4SSatish Balay PetscErrorCode PetscViewerASCIIRead(PetscViewer viewer, void *data, PetscInt num, PetscInt *count, PetscDataType dtype) {
9562655f987SMichael Lange   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
9572655f987SMichael Lange   FILE              *fd     = vascii->fd;
9582655f987SMichael Lange   PetscInt           i;
9593b7fe8c3SMatthew G. Knepley   int                ret = 0;
960f8859db6SBarry Smith   PetscMPIInt        rank;
9612655f987SMichael Lange 
9622655f987SMichael Lange   PetscFunctionBegin;
9632655f987SMichael Lange   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
9649566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank));
965c5853193SPierre Jolivet   PetscCheck(rank == 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Can only be called from process 0 in the PetscViewer");
966060da220SMatthew G. Knepley   for (i = 0; i < num; i++) {
967f8e4bde8SMatthew G. Knepley     if (dtype == PETSC_CHAR) ret = fscanf(fd, "%c", &(((char *)data)[i]));
968f8e4bde8SMatthew G. Knepley     else if (dtype == PETSC_STRING) ret = fscanf(fd, "%s", &(((char *)data)[i]));
969a05e1a72SSatish Balay     else if (dtype == PETSC_INT) ret = fscanf(fd, "%" PetscInt_FMT, &(((PetscInt *)data)[i]));
970f8e4bde8SMatthew G. Knepley     else if (dtype == PETSC_ENUM) ret = fscanf(fd, "%d", &(((int *)data)[i]));
9719e3e4c22SLisandro Dalcin     else if (dtype == PETSC_INT64) ret = fscanf(fd, "%" PetscInt64_FMT, &(((PetscInt64 *)data)[i]));
972972064b6SLisandro Dalcin     else if (dtype == PETSC_LONG) ret = fscanf(fd, "%ld", &(((long *)data)[i]));
973f8e4bde8SMatthew G. Knepley     else if (dtype == PETSC_FLOAT) ret = fscanf(fd, "%f", &(((float *)data)[i]));
974f8e4bde8SMatthew G. Knepley     else if (dtype == PETSC_DOUBLE) ret = fscanf(fd, "%lg", &(((double *)data)[i]));
975a6e181c6SToby Isaac #if defined(PETSC_USE_REAL___FLOAT128)
976fba955ccSBarry Smith     else if (dtype == PETSC___FLOAT128) {
977fba955ccSBarry Smith       double tmp;
978fba955ccSBarry Smith       ret                     = fscanf(fd, "%lg", &tmp);
979a6e181c6SToby Isaac       ((__float128 *)data)[i] = tmp;
980a6e181c6SToby Isaac     }
981fba955ccSBarry Smith #endif
9829371c9d4SSatish Balay     else
9839371c9d4SSatish Balay       SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Data type %d not supported", (int)dtype);
98428b400f6SJacob Faibussowitsch     PetscCheck(ret, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Conversion error for data type %d", (int)dtype);
985f7d195e4SLawrence Mitchell     if (ret < 0) break; /* Proxy for EOF, need to check for it in configure */
9862655f987SMichael Lange   }
987060da220SMatthew G. Knepley   if (count) *count = i;
98808401ef6SPierre Jolivet   else PetscCheck(ret >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Insufficient data, read only %" PetscInt_FMT " < %" PetscInt_FMT " items", i, num);
9892655f987SMichael Lange   PetscFunctionReturn(0);
9902655f987SMichael Lange }
991