xref: /petsc/src/sys/classes/viewer/impls/ascii/filev.c (revision 0b8bdde92eb4bc9ed9cee42fe7fcadba66103007)
1665c2dedSJed Brown #include <../src/sys/classes/viewer/impls/ascii/asciiimpl.h> /*I "petscviewer.h" I*/
25c6c1daeSBarry Smith 
35c6c1daeSBarry Smith #define QUEUESTRINGSIZE 8192
45c6c1daeSBarry Smith 
PetscViewerFileClose_ASCII(PetscViewer viewer)5d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscViewerFileClose_ASCII(PetscViewer viewer)
6d71ae5a4SJacob Faibussowitsch {
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));
2600045ab3SPierre Jolivet       PetscCheck(!fgets(buf, 1024, fp), PETSC_COMM_SELF, PETSC_ERR_LIB, "Error from compression command %s %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));
343ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
355c6c1daeSBarry Smith }
365c6c1daeSBarry Smith 
PetscViewerDestroy_ASCII(PetscViewer viewer)3734e79e72SJacob Faibussowitsch static PetscErrorCode PetscViewerDestroy_ASCII(PetscViewer viewer)
38d71ae5a4SJacob Faibussowitsch {
395c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
405c6c1daeSBarry Smith   PetscViewerLink   *vlink;
41b8b5be36SMartin Diehl   PetscMPIInt        iflg;
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 */
49c8025a54SPierre Jolivet   if (Petsc_Viewer_keyval == MPI_KEYVAL_INVALID) PetscCallMPI(MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN, Petsc_DelViewer, &Petsc_Viewer_keyval, NULL));
505c6c1daeSBarry Smith 
51b8b5be36SMartin Diehl   PetscCallMPI(MPI_Comm_get_attr(PetscObjectComm((PetscObject)viewer), Petsc_Viewer_keyval, (void **)&vlink, &iflg));
52b8b5be36SMartin Diehl   if (iflg) {
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;
74b8b5be36SMartin Diehl     PetscCallMPI(MPI_Comm_get_attr(PetscObjectComm((PetscObject)viewer), Petsc_Viewer_Stdout_keyval, (void **)&aviewer, &iflg));
75b8b5be36SMartin Diehl     if (iflg && 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;
79b8b5be36SMartin Diehl     PetscCallMPI(MPI_Comm_get_attr(PetscObjectComm((PetscObject)viewer), Petsc_Viewer_Stderr_keyval, (void **)&aviewer, &iflg));
80b8b5be36SMartin Diehl     if (iflg && 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));
863ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
875c6c1daeSBarry Smith }
885c6c1daeSBarry Smith 
PetscViewerDestroy_ASCII_SubViewer(PetscViewer viewer)8934e79e72SJacob Faibussowitsch static PetscErrorCode PetscViewerDestroy_ASCII_SubViewer(PetscViewer viewer)
90d71ae5a4SJacob Faibussowitsch {
915c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
925fd66863SKarl Rupp 
935c6c1daeSBarry Smith   PetscFunctionBegin;
949566063dSJacob Faibussowitsch   PetscCall(PetscViewerRestoreSubViewer(vascii->bviewer, 0, &viewer));
953ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
965c6c1daeSBarry Smith }
975c6c1daeSBarry Smith 
985c6c1daeSBarry Smith /*@C
99811af0c4SBarry Smith   PetscViewerASCIIGetPointer - Extracts the file pointer from an ASCII `PetscViewer`.
1005c6c1daeSBarry Smith 
10135cb6cd3SPierre Jolivet   Not Collective, depending on the viewer the value may be meaningless except for process 0 of the viewer; No Fortran Support
1025c6c1daeSBarry Smith 
103f8859db6SBarry Smith   Input Parameter:
1043f423023SBarry Smith . viewer - `PetscViewer` context, obtained from `PetscViewerASCIIOpen()`
105f8859db6SBarry Smith 
106f8859db6SBarry Smith   Output Parameter:
107f8859db6SBarry Smith . fd - file pointer
108f8859db6SBarry Smith 
1095c6c1daeSBarry Smith   Level: intermediate
1105c6c1daeSBarry Smith 
111811af0c4SBarry Smith   Note:
112c410d8ccSBarry Smith   For the standard `PETSCVIEWERASCII` the value is valid only on MPI rank 0 of the viewer
113811af0c4SBarry Smith 
1143f423023SBarry Smith .seealso: [](sec_viewers), `PETSCVIEWERASCII`, `PetscViewerASCIIOpen()`, `PetscViewerDestroy()`, `PetscViewerSetType()`,
1153f423023SBarry Smith           `PetscViewerCreate()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerFlush()`
1165c6c1daeSBarry Smith @*/
PetscViewerASCIIGetPointer(PetscViewer viewer,FILE ** fd)117d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIIGetPointer(PetscViewer viewer, FILE **fd)
118d71ae5a4SJacob Faibussowitsch {
1195c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
1205c6c1daeSBarry Smith 
1215c6c1daeSBarry Smith   PetscFunctionBegin;
122c621c6acSBarry Smith   PetscCheck(!vascii->fileunit, PetscObjectComm((PetscObject)viewer), PETSC_ERR_ARG_WRONGSTATE, "Cannot request file pointer for viewers that use Fortran files");
1235c6c1daeSBarry Smith   *fd = vascii->fd;
1243ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1255c6c1daeSBarry Smith }
1265c6c1daeSBarry Smith 
PetscViewerFileGetMode_ASCII(PetscViewer viewer,PetscFileMode * mode)12734e79e72SJacob Faibussowitsch static PetscErrorCode PetscViewerFileGetMode_ASCII(PetscViewer viewer, PetscFileMode *mode)
128d71ae5a4SJacob Faibussowitsch {
1295c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
1305c6c1daeSBarry Smith 
1315c6c1daeSBarry Smith   PetscFunctionBegin;
1325c6c1daeSBarry Smith   *mode = vascii->mode;
1333ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1345c6c1daeSBarry Smith }
1355c6c1daeSBarry Smith 
PetscViewerFileSetMode_ASCII(PetscViewer viewer,PetscFileMode mode)13634e79e72SJacob Faibussowitsch static PetscErrorCode PetscViewerFileSetMode_ASCII(PetscViewer viewer, PetscFileMode mode)
137d71ae5a4SJacob Faibussowitsch {
1385c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
1395c6c1daeSBarry Smith 
1405c6c1daeSBarry Smith   PetscFunctionBegin;
1415c6c1daeSBarry Smith   vascii->mode = mode;
1423ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1435c6c1daeSBarry Smith }
1445c6c1daeSBarry Smith 
1455c6c1daeSBarry Smith /*
1465c6c1daeSBarry Smith    If petsc_history is on, then all Petsc*Printf() results are saved
1475c6c1daeSBarry Smith    if the appropriate (usually .petschistory) file.
1485c6c1daeSBarry Smith */
14995c0884eSLisandro Dalcin PETSC_INTERN FILE *petsc_history;
1505c6c1daeSBarry Smith 
1515c6c1daeSBarry Smith /*@
1523f423023SBarry Smith   PetscViewerASCIISetTab - Causes `PetscViewer` to tab in a number of times before printing
1535c6c1daeSBarry Smith 
154cf53795eSBarry Smith   Not Collective, but only first processor in set has any effect; No Fortran Support
1555c6c1daeSBarry Smith 
1565c6c1daeSBarry Smith   Input Parameters:
157811af0c4SBarry Smith + viewer - obtained with `PetscViewerASCIIOpen()`
1585c6c1daeSBarry Smith - tabs   - number of tabs
1595c6c1daeSBarry Smith 
1605c6c1daeSBarry Smith   Level: developer
1615c6c1daeSBarry Smith 
1623f423023SBarry Smith   Note:
1633f423023SBarry Smith   `PetscViewerASCIIPushTab()` and `PetscViewerASCIIPopTab()` are the preferred usage
1643f423023SBarry Smith 
1653f423023SBarry Smith .seealso: [](sec_viewers), `PETSCVIEWERASCII`, `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`,
1663f423023SBarry Smith           `PetscViewerASCIIGetTab()`,
167db781477SPatrick Sanan           `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIOpen()`,
1683f423023SBarry Smith           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`,
1693f423023SBarry Smith           `PetscViewerASCIIPushTab()`
1705c6c1daeSBarry Smith @*/
PetscViewerASCIISetTab(PetscViewer viewer,PetscInt tabs)171d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIISetTab(PetscViewer viewer, PetscInt tabs)
172d71ae5a4SJacob Faibussowitsch {
1735c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
1749f196a02SMartin Diehl   PetscBool          isascii;
1755c6c1daeSBarry Smith 
1765c6c1daeSBarry Smith   PetscFunctionBegin;
1775c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
1789f196a02SMartin Diehl   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
1799f196a02SMartin Diehl   if (isascii) ascii->tab = tabs;
1803ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1815c6c1daeSBarry Smith }
1825c6c1daeSBarry Smith 
1835c6c1daeSBarry Smith /*@
184811af0c4SBarry Smith   PetscViewerASCIIGetTab - Return the number of tabs used by `PetscViewer`.
1855c6c1daeSBarry Smith 
186cf53795eSBarry Smith   Not Collective, meaningful on first processor only; No Fortran Support
1875c6c1daeSBarry Smith 
18820f4b53cSBarry Smith   Input Parameter:
189811af0c4SBarry Smith . viewer - obtained with `PetscViewerASCIIOpen()`
190a2b725a8SWilliam Gropp 
19120f4b53cSBarry Smith   Output Parameter:
1925c6c1daeSBarry Smith . tabs - number of tabs
1935c6c1daeSBarry Smith 
1945c6c1daeSBarry Smith   Level: developer
1955c6c1daeSBarry Smith 
1963f423023SBarry Smith .seealso: [](sec_viewers), `PETSCVIEWERASCII`, `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`,
1973f423023SBarry Smith           `PetscViewerASCIISetTab()`,
198db781477SPatrick Sanan           `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIOpen()`,
199db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`, `PetscViewerASCIIPushTab()`
2005c6c1daeSBarry Smith @*/
PetscViewerASCIIGetTab(PetscViewer viewer,PetscInt * tabs)201d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIIGetTab(PetscViewer viewer, PetscInt *tabs)
202d71ae5a4SJacob Faibussowitsch {
2035c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
2049f196a02SMartin Diehl   PetscBool          isascii;
2055c6c1daeSBarry Smith 
2065c6c1daeSBarry Smith   PetscFunctionBegin;
2075c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
2089f196a02SMartin Diehl   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
2099f196a02SMartin Diehl   if (isascii && tabs) *tabs = ascii->tab;
2103ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2115c6c1daeSBarry Smith }
2125c6c1daeSBarry Smith 
2135c6c1daeSBarry Smith /*@
2143f423023SBarry Smith   PetscViewerASCIIAddTab - Add to the number of times a `PETSCVIEWERASCII` viewer tabs before printing
2155c6c1daeSBarry Smith 
216cf53795eSBarry Smith   Not Collective, but only first processor in set has any effect; No Fortran Support
2175c6c1daeSBarry Smith 
2185c6c1daeSBarry Smith   Input Parameters:
219811af0c4SBarry Smith + viewer - obtained with `PetscViewerASCIIOpen()`
2205c6c1daeSBarry Smith - tabs   - number of tabs
2215c6c1daeSBarry Smith 
2225c6c1daeSBarry Smith   Level: developer
2235c6c1daeSBarry Smith 
2243f423023SBarry Smith   Note:
2253f423023SBarry Smith   `PetscViewerASCIIPushTab()` and `PetscViewerASCIIPopTab()` are the preferred usage
2263f423023SBarry Smith 
2273f423023SBarry Smith .seealso: [](sec_viewers), `PETSCVIEWERASCII`, `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`,
228db781477SPatrick Sanan           `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIOpen()`,
229db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`, `PetscViewerASCIIPushTab()`
2305c6c1daeSBarry Smith @*/
PetscViewerASCIIAddTab(PetscViewer viewer,PetscInt tabs)231d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIIAddTab(PetscViewer viewer, PetscInt tabs)
232d71ae5a4SJacob Faibussowitsch {
2335c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
2349f196a02SMartin Diehl   PetscBool          isascii;
2355c6c1daeSBarry Smith 
2365c6c1daeSBarry Smith   PetscFunctionBegin;
2375c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
2389f196a02SMartin Diehl   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
2399f196a02SMartin Diehl   if (isascii) ascii->tab += tabs;
2403ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2415c6c1daeSBarry Smith }
2425c6c1daeSBarry Smith 
2435c6c1daeSBarry Smith /*@
2443f423023SBarry Smith   PetscViewerASCIISubtractTab - Subtracts from the number of times a `PETSCVIEWERASCII` viewer tabs before printing
2455c6c1daeSBarry Smith 
246cf53795eSBarry Smith   Not Collective, but only first processor in set has any effect; No Fortran Support
2475c6c1daeSBarry Smith 
2485c6c1daeSBarry Smith   Input Parameters:
249811af0c4SBarry Smith + viewer - obtained with `PetscViewerASCIIOpen()`
2505c6c1daeSBarry Smith - tabs   - number of tabs
2515c6c1daeSBarry Smith 
2525c6c1daeSBarry Smith   Level: developer
2535c6c1daeSBarry Smith 
2543f423023SBarry Smith   Note:
2553f423023SBarry Smith   `PetscViewerASCIIPushTab()` and `PetscViewerASCIIPopTab()` are the preferred usage
2563f423023SBarry Smith 
2573f423023SBarry Smith .seealso: [](sec_viewers), `PETSCVIEWERASCII`, `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`,
258db781477SPatrick Sanan           `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIOpen()`,
2593f423023SBarry Smith           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`,
2603f423023SBarry Smith           `PetscViewerASCIIPushTab()`
2615c6c1daeSBarry Smith @*/
PetscViewerASCIISubtractTab(PetscViewer viewer,PetscInt tabs)262d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIISubtractTab(PetscViewer viewer, PetscInt tabs)
263d71ae5a4SJacob Faibussowitsch {
2645c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
2659f196a02SMartin Diehl   PetscBool          isascii;
2665c6c1daeSBarry Smith 
2675c6c1daeSBarry Smith   PetscFunctionBegin;
2685c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
2699f196a02SMartin Diehl   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
2709f196a02SMartin Diehl   if (isascii) ascii->tab -= tabs;
2713ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2725c6c1daeSBarry Smith }
2735c6c1daeSBarry Smith 
2745d83a8b1SBarry Smith /*@
275811af0c4SBarry Smith   PetscViewerASCIIPushSynchronized - Allows calls to `PetscViewerASCIISynchronizedPrintf()` for this viewer
2765c6c1daeSBarry Smith 
277c3339decSBarry Smith   Collective
2785c6c1daeSBarry Smith 
27920f4b53cSBarry Smith   Input Parameter:
280811af0c4SBarry Smith . viewer - obtained with `PetscViewerASCIIOpen()`
2815c6c1daeSBarry Smith 
2825c6c1daeSBarry Smith   Level: intermediate
2835c6c1daeSBarry Smith 
284811af0c4SBarry Smith   Note:
285811af0c4SBarry Smith   See documentation of `PetscViewerASCIISynchronizedPrintf()` for more details how the synchronized output should be done properly.
2865c6c1daeSBarry Smith 
287d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerFlush()`, `PetscViewerASCIIPopSynchronized()`,
288db781477SPatrick Sanan           `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIIOpen()`,
289db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`
2905c6c1daeSBarry Smith @*/
PetscViewerASCIIPushSynchronized(PetscViewer viewer)291d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIIPushSynchronized(PetscViewer viewer)
292d71ae5a4SJacob Faibussowitsch {
2935c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
2949f196a02SMartin Diehl   PetscBool          isascii;
2955c6c1daeSBarry Smith 
2965c6c1daeSBarry Smith   PetscFunctionBegin;
2975c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
29828b400f6SJacob Faibussowitsch   PetscCheck(!ascii->sviewer, PetscObjectComm((PetscObject)viewer), PETSC_ERR_ARG_WRONGSTATE, "Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
2999f196a02SMartin Diehl   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
3009f196a02SMartin Diehl   if (isascii) ascii->allowsynchronized++;
3013ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3021575c14dSBarry Smith }
3031575c14dSBarry Smith 
3045d83a8b1SBarry Smith /*@
305811af0c4SBarry Smith   PetscViewerASCIIPopSynchronized - Undoes most recent `PetscViewerASCIIPushSynchronized()` for this viewer
3061575c14dSBarry Smith 
307c3339decSBarry Smith   Collective
3081575c14dSBarry Smith 
30920f4b53cSBarry Smith   Input Parameter:
310811af0c4SBarry Smith . viewer - obtained with `PetscViewerASCIIOpen()`
3111575c14dSBarry Smith 
3121575c14dSBarry Smith   Level: intermediate
3131575c14dSBarry Smith 
314811af0c4SBarry Smith   Note:
315811af0c4SBarry Smith   See documentation of `PetscViewerASCIISynchronizedPrintf()` for more details how the synchronized output should be done properly.
3161575c14dSBarry Smith 
317d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscViewerASCIIPushSynchronized()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerFlush()`,
318db781477SPatrick Sanan           `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIIOpen()`,
319db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`
3201575c14dSBarry Smith @*/
PetscViewerASCIIPopSynchronized(PetscViewer viewer)321d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIIPopSynchronized(PetscViewer viewer)
322d71ae5a4SJacob Faibussowitsch {
3231575c14dSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
3249f196a02SMartin Diehl   PetscBool          isascii;
3251575c14dSBarry Smith 
3261575c14dSBarry Smith   PetscFunctionBegin;
3271575c14dSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
32828b400f6SJacob Faibussowitsch   PetscCheck(!ascii->sviewer, PetscObjectComm((PetscObject)viewer), PETSC_ERR_ARG_WRONGSTATE, "Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
3299f196a02SMartin Diehl   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
3309f196a02SMartin Diehl   if (isascii) {
3311575c14dSBarry Smith     ascii->allowsynchronized--;
33208401ef6SPierre Jolivet     PetscCheck(ascii->allowsynchronized >= 0, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Called more times than PetscViewerASCIIPushSynchronized()");
3331575c14dSBarry Smith   }
3343ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3355c6c1daeSBarry Smith }
3365c6c1daeSBarry Smith 
3375d83a8b1SBarry Smith /*@
338811af0c4SBarry Smith   PetscViewerASCIIPushTab - Adds one more tab to the amount that `PetscViewerASCIIPrintf()`
3395c6c1daeSBarry Smith   lines are tabbed.
3405c6c1daeSBarry Smith 
341c410d8ccSBarry Smith   Not Collective, but only first MPI rank in the viewer has any effect; No Fortran Support
3425c6c1daeSBarry Smith 
34320f4b53cSBarry Smith   Input Parameter:
344811af0c4SBarry Smith . viewer - obtained with `PetscViewerASCIIOpen()`
3455c6c1daeSBarry Smith 
3465c6c1daeSBarry Smith   Level: developer
3475c6c1daeSBarry Smith 
348d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`,
349db781477SPatrick Sanan           `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIOpen()`,
350db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`
3515c6c1daeSBarry Smith @*/
PetscViewerASCIIPushTab(PetscViewer viewer)352d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIIPushTab(PetscViewer viewer)
353d71ae5a4SJacob Faibussowitsch {
3545c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
3559f196a02SMartin Diehl   PetscBool          isascii;
3565c6c1daeSBarry Smith 
3575c6c1daeSBarry Smith   PetscFunctionBegin;
3585c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
3599f196a02SMartin Diehl   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
3609f196a02SMartin Diehl   if (isascii) ascii->tab++;
3613ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3625c6c1daeSBarry Smith }
3635c6c1daeSBarry Smith 
3645d83a8b1SBarry Smith /*@
3653f423023SBarry Smith   PetscViewerASCIIPopTab - Removes one tab from the amount that `PetscViewerASCIIPrintf()` lines are tabbed that was provided by
3663f423023SBarry Smith   `PetscViewerASCIIPushTab()`
3675c6c1daeSBarry Smith 
368c410d8ccSBarry Smith   Not Collective, but only first MPI rank in the viewer has any effect; No Fortran Support
3695c6c1daeSBarry Smith 
37020f4b53cSBarry Smith   Input Parameter:
371811af0c4SBarry Smith . viewer - obtained with `PetscViewerASCIIOpen()`
3725c6c1daeSBarry Smith 
3735c6c1daeSBarry Smith   Level: developer
3745c6c1daeSBarry Smith 
375d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`,
376db781477SPatrick Sanan           `PetscViewerASCIIPushTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIOpen()`,
377db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`
3785c6c1daeSBarry Smith @*/
PetscViewerASCIIPopTab(PetscViewer viewer)379d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIIPopTab(PetscViewer viewer)
380d71ae5a4SJacob Faibussowitsch {
3815c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
3829f196a02SMartin Diehl   PetscBool          isascii;
3835c6c1daeSBarry Smith 
3845c6c1daeSBarry Smith   PetscFunctionBegin;
3855c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
3869f196a02SMartin Diehl   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
3879f196a02SMartin Diehl   if (isascii) {
38808401ef6SPierre Jolivet     PetscCheck(ascii->tab > 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "More tabs popped than pushed");
3895c6c1daeSBarry Smith     ascii->tab--;
3905c6c1daeSBarry Smith   }
3913ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3925c6c1daeSBarry Smith }
3935c6c1daeSBarry Smith 
3945c6c1daeSBarry Smith /*@
395c410d8ccSBarry Smith   PetscViewerASCIIUseTabs - Turns on or off the use of tabs with the `PETSCVIEWERASCII` `PetscViewer`
3965c6c1daeSBarry Smith 
397c410d8ccSBarry Smith   Not Collective, but only first MPI rank in the viewer has any effect; No Fortran Support
3985c6c1daeSBarry Smith 
3995c6c1daeSBarry Smith   Input Parameters:
400811af0c4SBarry Smith + viewer - obtained with `PetscViewerASCIIOpen()`
401811af0c4SBarry Smith - flg    - `PETSC_TRUE` or `PETSC_FALSE`
4025c6c1daeSBarry Smith 
4035c6c1daeSBarry Smith   Level: developer
4045c6c1daeSBarry Smith 
405d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`,
406db781477SPatrick Sanan           `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIPushTab()`, `PetscViewerASCIIOpen()`,
407db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`
4085c6c1daeSBarry Smith @*/
PetscViewerASCIIUseTabs(PetscViewer viewer,PetscBool flg)409d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIIUseTabs(PetscViewer viewer, PetscBool flg)
410d71ae5a4SJacob Faibussowitsch {
4115c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
4129f196a02SMartin Diehl   PetscBool          isascii;
4135c6c1daeSBarry Smith 
4145c6c1daeSBarry Smith   PetscFunctionBegin;
4155c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
4169f196a02SMartin Diehl   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
4179f196a02SMartin Diehl   if (isascii) {
418a297a907SKarl Rupp     if (flg) ascii->tab = ascii->tab_store;
419a297a907SKarl Rupp     else {
4205c6c1daeSBarry Smith       ascii->tab_store = ascii->tab;
4215c6c1daeSBarry Smith       ascii->tab       = 0;
4225c6c1daeSBarry Smith     }
4235c6c1daeSBarry Smith   }
4243ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4255c6c1daeSBarry Smith }
4265c6c1daeSBarry Smith 
427e4096674SBarry Smith #if defined(PETSC_USE_FORTRAN_BINDINGS)
428e4096674SBarry Smith 
429e4096674SBarry Smith   #if defined(PETSC_HAVE_FORTRAN_CAPS)
430e4096674SBarry Smith     #define petscviewerasciiopenwithfileunit_  PETSCVIEWERASCIIOPENWITHFILEUNIT
43157b1f488SBarry Smith     #define petscviewerasciisetfileunit_       PETSCVIEWERASCIISETFILEUNIT
4329f0612e4SBarry Smith     #define petscviewerasciistdoutsetfileunit_ PETSCVIEWERASCIISTDOUTSETFILEUNIT
4339f0612e4SBarry Smith     #define petscfortranprinttofileunit_       PETSCFORTRANPRINTTOFILEUNIT
434e4096674SBarry Smith   #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE)
435e4096674SBarry Smith     #define petscviewerasciiopenwithfileunit_  petscviewerasciiopenwithfileunit
436e4096674SBarry Smith     #define petscviewerasciisetfileunit_       petscviewerasciisetfileunit
4379f0612e4SBarry Smith     #define petscviewerasciistdoutsetfileunit_ petscviewerasciistdoutsetfileunit
4389f0612e4SBarry Smith     #define petscfortranprinttofileunit_       petscfortranprinttofileunit
439e4096674SBarry Smith   #endif
440e4096674SBarry Smith 
441e4096674SBarry Smith   #if defined(__cplusplus)
4429f0612e4SBarry Smith extern "C" void petscfortranprinttofileunit_(int *, const char *, PetscErrorCode *, PETSC_FORTRAN_CHARLEN_T);
443e4096674SBarry Smith   #else
4449f0612e4SBarry Smith extern void petscfortranprinttofileunit_(int *, const char *, PetscErrorCode *, PETSC_FORTRAN_CHARLEN_T);
445e4096674SBarry Smith   #endif
446e4096674SBarry Smith 
447e4096674SBarry Smith   #define PETSCDEFAULTBUFFERSIZE 8 * 1024
448e4096674SBarry Smith 
4499f0612e4SBarry Smith static int PETSC_VIEWER_ASCII_STDOUT_fileunit = 0;
45057b1f488SBarry Smith 
45157b1f488SBarry Smith // PetscClangLinter pragma disable: -fdoc-synopsis-macro-explicit-synopsis-valid-header
45257b1f488SBarry Smith /*MC
4539f0612e4SBarry Smith   PetscViewerASCIIStdoutSetFileUnit - sets `PETSC_VIEWER_STDOUT_()` to write to a Fortran IO unit
45457b1f488SBarry Smith 
45557b1f488SBarry Smith   Synopsis:
45657b1f488SBarry Smith   #include <petscviewer.h>
4579f0612e4SBarry Smith   void PetscViewerASCIIStdoutSetFileUnit(PetscInt unit, PetscErrorCode ierr)
45857b1f488SBarry Smith 
45957b1f488SBarry Smith   Input Parameter:
46057b1f488SBarry Smith . unit - the unit number
46157b1f488SBarry Smith 
46257b1f488SBarry Smith   Output Parameter:
46357b1f488SBarry Smith . ierr - the error code
46457b1f488SBarry Smith 
46557b1f488SBarry Smith   Level: intermediate
46657b1f488SBarry Smith 
46757b1f488SBarry Smith   Notes:
4689f0612e4SBarry Smith   Can be called before `PetscInitialize()`
4699f0612e4SBarry Smith 
4709f0612e4SBarry Smith   Immediately changes the output for all `PETSC_VIEWER_STDOUT_()` viewers
47157b1f488SBarry Smith 
4721d031f67SBarry Smith   This may not work currently with some viewers that (improperly) use the `fd` directly instead of `PetscViewerASCIIPrintf()`
47357b1f488SBarry Smith 
47457b1f488SBarry Smith   With this option, for example, `-log_options` results will be saved to the Fortran file
47557b1f488SBarry Smith 
4761d031f67SBarry Smith   Any process may call this but only the unit passed on the first process is used
47757b1f488SBarry Smith 
47857b1f488SBarry Smith   Fortran Note:
47957b1f488SBarry Smith   Only for Fortran
48057b1f488SBarry Smith 
48157b1f488SBarry Smith   Developer Note:
4829f0612e4SBarry Smith   `PetscViewerASCIIWORLDSetFilename()` and `PetscViewerASCIIWORLDSetFILE()` could be added
48357b1f488SBarry Smith 
4849f0612e4SBarry Smith .seealso: `PetscViewerASCIISetFILE()`, `PETSCVIEWERASCII`, `PetscViewerASCIIOpenWithFileUnit()`, `PetscViewerASCIIStdoutSetFileUnit()`,
4859f0612e4SBarry Smith           `PETSC_VIEWER_STDOUT_()`, `PetscViewerASCIIGetStdout()`
48657b1f488SBarry Smith M*/
petscviewerasciistdoutsetfileunit_(int * unit,PetscErrorCode * ierr)4879f0612e4SBarry Smith PETSC_EXTERN void petscviewerasciistdoutsetfileunit_(int *unit, PetscErrorCode *ierr)
48857b1f488SBarry Smith {
4899f0612e4SBarry Smith   #if defined(PETSC_USE_FORTRAN_BINDINGS)
4909f0612e4SBarry Smith   PETSC_VIEWER_ASCII_STDOUT_fileunit = *unit;
4919f0612e4SBarry Smith   #endif
49257b1f488SBarry Smith }
49357b1f488SBarry Smith 
4946dd63270SBarry Smith   #include <petsc/private/ftnimpl.h>
49557b1f488SBarry Smith 
49610450e9eSJacob Faibussowitsch // PetscClangLinter pragma disable: -fdoc-synopsis-macro-explicit-synopsis-valid-header
497489d2c6aSPierre Jolivet /*MC
4989f0612e4SBarry Smith   PetscViewerASCIISetFileUnit - sets the `PETSCVIEWERASCII` `PetscViewer` to write to a Fortran IO unit
499e4096674SBarry Smith 
50010450e9eSJacob Faibussowitsch   Synopsis:
50110450e9eSJacob Faibussowitsch   #include <petscviewer.h>
5020da4d79bSMartin Diehl   void PetscViewerASCIISetFileUnit(PetscViewer viewer, PetscInt unit, PetscErrorCode ierr)
503e4096674SBarry Smith 
504e4096674SBarry Smith   Input Parameters:
5050da4d79bSMartin Diehl + viewer - the viewer
506e4096674SBarry Smith - unit   - the unit number
507e4096674SBarry Smith 
508e4096674SBarry Smith   Output Parameter:
509e4096674SBarry Smith . ierr - the error code
510e4096674SBarry Smith 
51110450e9eSJacob Faibussowitsch   Level: intermediate
51210450e9eSJacob Faibussowitsch 
513e4096674SBarry Smith   Note:
514e4096674SBarry Smith   `PetscViewerDestroy()` does not close the unit for this `PetscViewer`
515e4096674SBarry Smith 
516aec76313SJacob Faibussowitsch   Fortran Notes:
517e4096674SBarry Smith   Only for Fortran, use  `PetscViewerASCIISetFILE()` for C
518e4096674SBarry Smith 
5199f0612e4SBarry Smith .seealso: `PetscViewerASCIISetFILE()`, `PETSCVIEWERASCII`, `PetscViewerASCIIOpenWithFileUnit()`, `PetscViewerASCIIStdoutSetFileUnit()`
520489d2c6aSPierre Jolivet M*/
petscviewerasciisetfileunit_(PetscViewer * viewer,int * unit,PetscErrorCode * ierr)5210da4d79bSMartin Diehl PETSC_EXTERN void petscviewerasciisetfileunit_(PetscViewer *viewer, int *unit, PetscErrorCode *ierr)
522e4096674SBarry Smith {
52357b1f488SBarry Smith   PetscViewer_ASCII *vascii;
52457b1f488SBarry Smith   PetscViewer        v;
525e4096674SBarry Smith 
5260da4d79bSMartin Diehl   PetscPatchDefaultViewers_Fortran(viewer, v);
52757b1f488SBarry Smith   vascii = (PetscViewer_ASCII *)v->data;
528e4096674SBarry Smith   if (vascii->mode == FILE_MODE_READ) {
529e4096674SBarry Smith     *ierr = PETSC_ERR_ARG_WRONGSTATE;
530e4096674SBarry Smith     return;
531e4096674SBarry Smith   }
532e4096674SBarry Smith   vascii->fileunit = *unit;
533e4096674SBarry Smith }
534e4096674SBarry Smith 
53510450e9eSJacob Faibussowitsch // PetscClangLinter pragma disable: -fdoc-synopsis-macro-explicit-synopsis-valid-header
536489d2c6aSPierre Jolivet /*MC
537baca6076SPierre Jolivet   PetscViewerASCIIOpenWithFileUnit - opens a `PETSCVIEWERASCII` to write to a Fortran IO unit
538e4096674SBarry Smith 
53910450e9eSJacob Faibussowitsch   Synopsis:
54010450e9eSJacob Faibussowitsch   #include <petscviewer.h>
5419f0612e4SBarry Smith   void PetscViewerASCIIOpenWithFileUnit((MPI_Fint comm, integer unit, PetscViewer viewer, PetscErrorCode ierr)
542e4096674SBarry Smith 
543e4096674SBarry Smith   Input Parameters:
544e4096674SBarry Smith + comm - the `MPI_Comm` to share the viewer
545e4096674SBarry Smith - unit - the unit number
546e4096674SBarry Smith 
547e4096674SBarry Smith   Output Parameters:
5480da4d79bSMartin Diehl + viewer - the viewer
549e4096674SBarry Smith - ierr   - the error code
550e4096674SBarry Smith 
55110450e9eSJacob Faibussowitsch   Level: intermediate
55210450e9eSJacob Faibussowitsch 
553e4096674SBarry Smith   Note:
554e4096674SBarry Smith   `PetscViewerDestroy()` does not close the unit for this `PetscViewer`
555e4096674SBarry Smith 
556aec76313SJacob Faibussowitsch   Fortran Notes:
557e4096674SBarry Smith   Only for Fortran, use  `PetscViewerASCIIOpenWithFILE()` for C
558e4096674SBarry Smith 
559e4096674SBarry Smith .seealso: `PetscViewerASCIISetFileUnit()`, `PetscViewerASCIISetFILE()`, `PETSCVIEWERASCII`, `PetscViewerASCIIOpenWithFILE()`
560489d2c6aSPierre Jolivet M*/
petscviewerasciiopenwithfileunit_(MPI_Fint * comm,int * unit,PetscViewer * viewer,PetscErrorCode * ierr)5610da4d79bSMartin Diehl PETSC_EXTERN void petscviewerasciiopenwithfileunit_(MPI_Fint *comm, int *unit, PetscViewer *viewer, PetscErrorCode *ierr)
562e4096674SBarry Smith {
5630da4d79bSMartin Diehl   *ierr = PetscViewerCreate(MPI_Comm_f2c(*(MPI_Fint *)&*comm), viewer);
564e4096674SBarry Smith   if (*ierr) return;
5650da4d79bSMartin Diehl   *ierr = PetscViewerSetType(*viewer, PETSCVIEWERASCII);
566e4096674SBarry Smith   if (*ierr) return;
5670da4d79bSMartin Diehl   *ierr = PetscViewerFileSetMode(*viewer, FILE_MODE_WRITE);
568e4096674SBarry Smith   if (*ierr) return;
5690da4d79bSMartin Diehl   petscviewerasciisetfileunit_(viewer, unit, ierr);
570e4096674SBarry Smith }
571e4096674SBarry Smith 
PetscVFPrintfFortran(int unit,const char format[],va_list Argp)5729f0612e4SBarry Smith static PetscErrorCode PetscVFPrintfFortran(int unit, const char format[], va_list Argp)
573e4096674SBarry Smith {
574e4096674SBarry Smith   PetscErrorCode ierr;
575e4096674SBarry Smith   char           str[PETSCDEFAULTBUFFERSIZE];
576e4096674SBarry Smith   size_t         len;
577e4096674SBarry Smith 
578e4096674SBarry Smith   PetscFunctionBegin;
579e4096674SBarry Smith   PetscCall(PetscVSNPrintf(str, sizeof(str), format, NULL, Argp));
580e4096674SBarry Smith   PetscCall(PetscStrlen(str, &len));
5819f0612e4SBarry Smith   petscfortranprinttofileunit_(&unit, str, &ierr, (int)len);
582e4096674SBarry Smith   PetscFunctionReturn(PETSC_SUCCESS);
583e4096674SBarry Smith }
584e4096674SBarry Smith 
PetscFPrintfFortran(int unit,const char str[])5859f0612e4SBarry Smith static PetscErrorCode PetscFPrintfFortran(int unit, const char str[])
586e4096674SBarry Smith {
587e4096674SBarry Smith   PetscErrorCode ierr;
588e4096674SBarry Smith   size_t         len;
589e4096674SBarry Smith 
590e4096674SBarry Smith   PetscFunctionBegin;
591e4096674SBarry Smith   PetscCall(PetscStrlen(str, &len));
5929f0612e4SBarry Smith   petscfortranprinttofileunit_(&unit, str, &ierr, (int)len);
593e4096674SBarry Smith   PetscFunctionReturn(PETSC_SUCCESS);
594e4096674SBarry Smith }
595e4096674SBarry Smith 
596e4096674SBarry Smith #else
597e4096674SBarry Smith 
598e4096674SBarry Smith /* these will never be used; but are needed to link with */
PetscVFPrintfFortran(int unit,const char format[],va_list Argp)5999f0612e4SBarry Smith static PetscErrorCode PetscVFPrintfFortran(int unit, const char format[], va_list Argp)
600e4096674SBarry Smith {
601e4096674SBarry Smith   PetscFunctionBegin;
602e4096674SBarry Smith   PetscFunctionReturn(PETSC_SUCCESS);
603e4096674SBarry Smith }
604e4096674SBarry Smith 
PetscFPrintfFortran(int unit,const char str[])6059f0612e4SBarry Smith static PetscErrorCode PetscFPrintfFortran(int unit, const char str[])
606e4096674SBarry Smith {
607e4096674SBarry Smith   PetscFunctionBegin;
608e4096674SBarry Smith   PetscFunctionReturn(PETSC_SUCCESS);
609e4096674SBarry Smith }
610e4096674SBarry Smith #endif
611e4096674SBarry Smith 
61257b1f488SBarry Smith /*@
6131d031f67SBarry Smith   PetscViewerASCIIGetStdout - Creates a `PETSCVIEWERASCII` `PetscViewer` shared by all processes
614648c30bcSBarry Smith   in a communicator that prints to `stdout`. Error returning version of `PETSC_VIEWER_STDOUT_()`
61557b1f488SBarry Smith 
61657b1f488SBarry Smith   Collective
61757b1f488SBarry Smith 
61857b1f488SBarry Smith   Input Parameter:
61957b1f488SBarry Smith . comm - the MPI communicator to share the `PetscViewer`
62057b1f488SBarry Smith 
62157b1f488SBarry Smith   Output Parameter:
62257b1f488SBarry Smith . viewer - the viewer
62357b1f488SBarry Smith 
62457b1f488SBarry Smith   Level: beginner
62557b1f488SBarry Smith 
62657b1f488SBarry Smith   Note:
627648c30bcSBarry Smith   Use `PetscViewerDestroy()` to destroy it
62857b1f488SBarry Smith 
62957b1f488SBarry Smith   Developer Note:
63057b1f488SBarry Smith   This should be used in all PETSc source code instead of `PETSC_VIEWER_STDOUT_()` since it allows error checking
63157b1f488SBarry Smith 
632648c30bcSBarry Smith .seealso: [](sec_viewers), `PetscViewerASCIIGetStderr()`, `PETSC_VIEWER_DRAW_()`, `PetscViewerASCIIOpen()`, `PETSC_VIEWER_STDERR_`, `PETSC_VIEWER_STDOUT_WORLD`,
63357b1f488SBarry Smith           `PETSC_VIEWER_STDOUT_SELF`
63457b1f488SBarry Smith @*/
PetscViewerASCIIGetStdout(MPI_Comm comm,PetscViewer * viewer)63557b1f488SBarry Smith PetscErrorCode PetscViewerASCIIGetStdout(MPI_Comm comm, PetscViewer *viewer)
63657b1f488SBarry Smith {
637b8b5be36SMartin Diehl   PetscMPIInt iflg;
63857b1f488SBarry Smith   MPI_Comm    ncomm;
63957b1f488SBarry Smith 
64057b1f488SBarry Smith   PetscFunctionBegin;
641377f809aSBarry Smith   PetscAssertPointer(viewer, 2);
64257b1f488SBarry Smith   PetscCall(PetscSpinlockLock(&PetscViewerASCIISpinLockStdout));
64357b1f488SBarry Smith   PetscCall(PetscCommDuplicate(comm, &ncomm, NULL));
64457b1f488SBarry Smith   if (Petsc_Viewer_Stdout_keyval == MPI_KEYVAL_INVALID) PetscCallMPI(MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN, MPI_COMM_NULL_DELETE_FN, &Petsc_Viewer_Stdout_keyval, NULL));
645b8b5be36SMartin Diehl   PetscCallMPI(MPI_Comm_get_attr(ncomm, Petsc_Viewer_Stdout_keyval, (void **)viewer, &iflg));
646b8b5be36SMartin Diehl   if (!iflg) { /* PetscViewer not yet created */
64757b1f488SBarry Smith #if defined(PETSC_USE_FORTRAN_BINDINGS)
6489f0612e4SBarry Smith     PetscCallMPI(MPI_Bcast(&PETSC_VIEWER_ASCII_STDOUT_fileunit, 1, MPI_INT, 0, comm));
6499f0612e4SBarry Smith     if (PETSC_VIEWER_ASCII_STDOUT_fileunit) {
65057b1f488SBarry Smith       PetscErrorCode ierr;
6519f0612e4SBarry Smith       MPI_Fint       fcomm = MPI_Comm_c2f(ncomm);
65257b1f488SBarry Smith 
6539f0612e4SBarry Smith       petscviewerasciiopenwithfileunit_(&fcomm, &PETSC_VIEWER_ASCII_STDOUT_fileunit, viewer, &ierr);
65457b1f488SBarry Smith     } else
65557b1f488SBarry Smith #endif
656648c30bcSBarry Smith     {
6575e9aba71SBarry Smith       PetscViewerFormat format;
6585e9aba71SBarry Smith       PetscBool         set;
6595e9aba71SBarry Smith 
660648c30bcSBarry Smith       PetscCall(PetscViewerCreate(ncomm, viewer));
661648c30bcSBarry Smith       PetscCall(PetscViewerSetType(*viewer, PETSCVIEWERASCII));
6625e9aba71SBarry Smith       PetscCall(PetscOptionsGetEnum(NULL, NULL, "-petsc_viewer_stdout_format", PetscViewerFormats, (PetscEnum *)&format, &set));
6635e9aba71SBarry Smith       if (set) PetscCall(PetscViewerPushFormat(*viewer, format));
664648c30bcSBarry Smith       PetscCall(PetscViewerFileSetName(*viewer, "stdout"));
665648c30bcSBarry Smith     }
66657b1f488SBarry Smith     PetscCall(PetscObjectRegisterDestroy((PetscObject)*viewer));
66757b1f488SBarry Smith     PetscCallMPI(MPI_Comm_set_attr(ncomm, Petsc_Viewer_Stdout_keyval, (void *)*viewer));
66857b1f488SBarry Smith   }
66957b1f488SBarry Smith   PetscCall(PetscCommDestroy(&ncomm));
67057b1f488SBarry Smith   PetscCall(PetscSpinlockUnlock(&PetscViewerASCIISpinLockStdout));
6719f0612e4SBarry Smith #if defined(PETSC_USE_FORTRAN_BINDINGS)
6729f0612e4SBarry Smith   ((PetscViewer_ASCII *)(*viewer)->data)->fileunit = PETSC_VIEWER_ASCII_STDOUT_fileunit;
6739f0612e4SBarry Smith #endif
67457b1f488SBarry Smith   PetscFunctionReturn(PETSC_SUCCESS);
67557b1f488SBarry Smith }
67657b1f488SBarry Smith 
6775c6c1daeSBarry Smith /*@C
6785c6c1daeSBarry Smith   PetscViewerASCIIPrintf - Prints to a file, only from the first
6793f423023SBarry Smith   processor in the `PetscViewer` of type `PETSCVIEWERASCII`
6805c6c1daeSBarry Smith 
681c410d8ccSBarry Smith   Not Collective, but only the first MPI rank in the viewer has any effect
6825c6c1daeSBarry Smith 
6835c6c1daeSBarry Smith   Input Parameters:
684811af0c4SBarry Smith + viewer - obtained with `PetscViewerASCIIOpen()`
6855c6c1daeSBarry Smith - format - the usual printf() format string
6865c6c1daeSBarry Smith 
6875c6c1daeSBarry Smith   Level: developer
6885c6c1daeSBarry Smith 
689*3f7bdce8SBarry Smith   Fortran Note:
690*3f7bdce8SBarry Smith   The call sequence is `PetscViewerASCIIPrintf`(`PetscViewer`, character(*), int ierr).
6915c6c1daeSBarry Smith   That is, you can only pass a single character string from Fortran.
6925c6c1daeSBarry Smith 
693d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIOpen()`,
694db781477SPatrick Sanan           `PetscViewerASCIIPushTab()`, `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`,
695db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`, `PetscViewerASCIIPushSynchronized()`
6965c6c1daeSBarry Smith @*/
PetscViewerASCIIPrintf(PetscViewer viewer,const char format[],...)697d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIIPrintf(PetscViewer viewer, const char format[], ...)
698d71ae5a4SJacob Faibussowitsch {
6995c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
7005c6c1daeSBarry Smith   PetscMPIInt        rank;
701fe8fb074SBarry Smith   PetscInt           tab = 0, intab = ascii->tab;
7025c6c1daeSBarry Smith   FILE              *fd = ascii->fd;
7039f196a02SMartin Diehl   PetscBool          isascii;
7045c6c1daeSBarry Smith 
7055c6c1daeSBarry Smith   PetscFunctionBegin;
7065c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
70728b400f6SJacob Faibussowitsch   PetscCheck(!ascii->sviewer, PetscObjectComm((PetscObject)viewer), PETSC_ERR_ARG_WRONGSTATE, "Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
7084f572ea9SToby Isaac   PetscAssertPointer(format, 2);
7099f196a02SMartin Diehl   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
7109f196a02SMartin Diehl   PetscCheck(isascii, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Not ASCII PetscViewer");
7119566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank));
7123ba16761SJacob Faibussowitsch   if (rank) PetscFunctionReturn(PETSC_SUCCESS);
7133f08860eSBarry Smith 
7143f08860eSBarry Smith   if (ascii->bviewer) { /* pass string up to parent viewer */
7153f08860eSBarry Smith     char   *string;
7163f08860eSBarry Smith     va_list Argp;
7173f08860eSBarry Smith     size_t  fullLength;
7183f08860eSBarry Smith 
7199566063dSJacob Faibussowitsch     PetscCall(PetscCalloc1(QUEUESTRINGSIZE, &string));
720ac530a7eSPierre Jolivet     for (; tab < ascii->tab; tab++) string[2 * tab] = string[2 * tab + 1] = ' ';
7213f08860eSBarry Smith     va_start(Argp, format);
722fe8fb074SBarry Smith     PetscCall(PetscVSNPrintf(string + 2 * intab, QUEUESTRINGSIZE - 2 * intab, format, &fullLength, Argp));
7233f08860eSBarry Smith     va_end(Argp);
724fe8fb074SBarry Smith     PetscCall(PetscViewerASCIISynchronizedPrintf(ascii->bviewer, "%s", string));
7259566063dSJacob Faibussowitsch     PetscCall(PetscFree(string));
7263f08860eSBarry Smith   } else { /* write directly to file */
7275c6c1daeSBarry Smith     va_list Argp;
728fe8fb074SBarry Smith 
729dd2fa690SBarry Smith     tab = intab;
730e4096674SBarry Smith     while (tab--) {
731e4096674SBarry Smith       if (!ascii->fileunit) PetscCall(PetscFPrintf(PETSC_COMM_SELF, fd, "  "));
732e4096674SBarry Smith       else PetscCall(PetscFPrintfFortran(ascii->fileunit, "   "));
733e4096674SBarry Smith     }
7345c6c1daeSBarry Smith 
7355c6c1daeSBarry Smith     va_start(Argp, format);
736e4096674SBarry Smith     if (!ascii->fileunit) PetscCall((*PetscVFPrintf)(fd, format, Argp));
737e4096674SBarry Smith     else PetscCall(PetscVFPrintfFortran(ascii->fileunit, format, Argp));
738eae3dc7dSJacob Faibussowitsch     va_end(Argp);
739c69effb2SJacob Faibussowitsch     PetscCall(PetscFFlush(fd));
7405c6c1daeSBarry Smith   }
7413ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7425c6c1daeSBarry Smith }
7435c6c1daeSBarry Smith 
7445d83a8b1SBarry Smith /*@
745c410d8ccSBarry Smith   PetscViewerFileSetName - Sets the name of the file the `PetscViewer` should use.
7465c6c1daeSBarry Smith 
747c3339decSBarry Smith   Collective
7485c6c1daeSBarry Smith 
7495c6c1daeSBarry Smith   Input Parameters:
7503f423023SBarry Smith + viewer - the `PetscViewer`; for example, of type `PETSCVIEWERASCII` or `PETSCVIEWERBINARY`
7515c6c1daeSBarry Smith - name   - the name of the file it should use
7525c6c1daeSBarry Smith 
7535c6c1daeSBarry Smith   Level: advanced
7545c6c1daeSBarry Smith 
755c410d8ccSBarry Smith   Note:
756c410d8ccSBarry Smith   This will have no effect on viewers that are not related to files
757c410d8ccSBarry Smith 
758d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscViewerCreate()`, `PetscViewerSetType()`, `PetscViewerASCIIOpen()`, `PetscViewerBinaryOpen()`, `PetscViewerDestroy()`,
759db781477SPatrick Sanan           `PetscViewerASCIIGetPointer()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIISynchronizedPrintf()`
7605c6c1daeSBarry Smith @*/
PetscViewerFileSetName(PetscViewer viewer,const char name[])761d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerFileSetName(PetscViewer viewer, const char name[])
762d71ae5a4SJacob Faibussowitsch {
763cc843e7aSLisandro Dalcin   char filename[PETSC_MAX_PATH_LEN];
7645c6c1daeSBarry Smith 
7655c6c1daeSBarry Smith   PetscFunctionBegin;
7665c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
7674f572ea9SToby Isaac   PetscAssertPointer(name, 2);
7689566063dSJacob Faibussowitsch   PetscCall(PetscStrreplace(PetscObjectComm((PetscObject)viewer), name, filename, sizeof(filename)));
769cac4c232SBarry Smith   PetscTryMethod(viewer, "PetscViewerFileSetName_C", (PetscViewer, const char[]), (viewer, filename));
7703ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7715c6c1daeSBarry Smith }
7725c6c1daeSBarry Smith 
7735c6c1daeSBarry Smith /*@C
774c410d8ccSBarry Smith   PetscViewerFileGetName - Gets the name of the file the `PetscViewer` is using
7755c6c1daeSBarry Smith 
7765c6c1daeSBarry Smith   Not Collective
7775c6c1daeSBarry Smith 
7785c6c1daeSBarry Smith   Input Parameter:
7793f423023SBarry Smith . viewer - the `PetscViewer`
7805c6c1daeSBarry Smith 
7815c6c1daeSBarry Smith   Output Parameter:
7825c6c1daeSBarry Smith . name - the name of the file it is using
7835c6c1daeSBarry Smith 
7845c6c1daeSBarry Smith   Level: advanced
7855c6c1daeSBarry Smith 
786c410d8ccSBarry Smith   Note:
787c410d8ccSBarry Smith   This will have no effect on viewers that are not related to files
788c410d8ccSBarry Smith 
789d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscViewerCreate()`, `PetscViewerSetType()`, `PetscViewerASCIIOpen()`, `PetscViewerBinaryOpen()`, `PetscViewerFileSetName()`
7905c6c1daeSBarry Smith @*/
PetscViewerFileGetName(PetscViewer viewer,const char * name[])7915d83a8b1SBarry Smith PetscErrorCode PetscViewerFileGetName(PetscViewer viewer, const char *name[])
792d71ae5a4SJacob Faibussowitsch {
7935c6c1daeSBarry Smith   PetscFunctionBegin;
7945c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
7954f572ea9SToby Isaac   PetscAssertPointer(name, 2);
796cac4c232SBarry Smith   PetscUseMethod(viewer, "PetscViewerFileGetName_C", (PetscViewer, const char **), (viewer, name));
7973ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7985c6c1daeSBarry Smith }
7995c6c1daeSBarry Smith 
PetscViewerFileGetName_ASCII(PetscViewer viewer,const char ** name)80034e79e72SJacob Faibussowitsch static PetscErrorCode PetscViewerFileGetName_ASCII(PetscViewer viewer, const char **name)
801d71ae5a4SJacob Faibussowitsch {
8025c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
8035c6c1daeSBarry Smith 
8045c6c1daeSBarry Smith   PetscFunctionBegin;
8055c6c1daeSBarry Smith   *name = vascii->filename;
8063ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
8075c6c1daeSBarry Smith }
8085c6c1daeSBarry Smith 
809bf31d2d3SBarry Smith #include <errno.h>
PetscViewerFileSetName_ASCII(PetscViewer viewer,const char name[])81034e79e72SJacob Faibussowitsch static PetscErrorCode PetscViewerFileSetName_ASCII(PetscViewer viewer, const char name[])
811d71ae5a4SJacob Faibussowitsch {
8125c6c1daeSBarry Smith   size_t             len;
813bbcf679cSJacob Faibussowitsch   char               fname[PETSC_MAX_PATH_LEN], *gz = NULL;
8145c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
8155c6c1daeSBarry Smith   PetscBool          isstderr, isstdout;
8165c6c1daeSBarry Smith   PetscMPIInt        rank;
8175c6c1daeSBarry Smith 
8185c6c1daeSBarry Smith   PetscFunctionBegin;
8199566063dSJacob Faibussowitsch   PetscCall(PetscViewerFileClose_ASCII(viewer));
8203ba16761SJacob Faibussowitsch   if (!name) PetscFunctionReturn(PETSC_SUCCESS);
8219566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(name, &vascii->filename));
8225c6c1daeSBarry Smith 
8235c6c1daeSBarry Smith   /* Is this file to be compressed */
8245c6c1daeSBarry Smith   vascii->storecompressed = PETSC_FALSE;
825a297a907SKarl Rupp 
8269566063dSJacob Faibussowitsch   PetscCall(PetscStrstr(vascii->filename, ".gz", &gz));
8275c6c1daeSBarry Smith   if (gz) {
8289566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(gz, &len));
8295c6c1daeSBarry Smith     if (len == 3) {
83008401ef6SPierre 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");
8315c6c1daeSBarry Smith       *gz                     = 0;
8325c6c1daeSBarry Smith       vascii->storecompressed = PETSC_TRUE;
8335c6c1daeSBarry Smith     }
8345c6c1daeSBarry Smith   }
8359566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank));
836dd400576SPatrick Sanan   if (rank == 0) {
8379566063dSJacob Faibussowitsch     PetscCall(PetscStrcmp(name, "stderr", &isstderr));
8389566063dSJacob Faibussowitsch     PetscCall(PetscStrcmp(name, "stdout", &isstdout));
8395c6c1daeSBarry Smith     /* empty filename means stdout */
8405c6c1daeSBarry Smith     if (name[0] == 0) isstdout = PETSC_TRUE;
8415c6c1daeSBarry Smith     if (isstderr) vascii->fd = PETSC_STDERR;
8425c6c1daeSBarry Smith     else if (isstdout) vascii->fd = PETSC_STDOUT;
8435c6c1daeSBarry Smith     else {
8449566063dSJacob Faibussowitsch       PetscCall(PetscFixFilename(name, fname));
8455c6c1daeSBarry Smith       switch (vascii->mode) {
846d71ae5a4SJacob Faibussowitsch       case FILE_MODE_READ:
847d71ae5a4SJacob Faibussowitsch         vascii->fd = fopen(fname, "r");
848d71ae5a4SJacob Faibussowitsch         break;
849d71ae5a4SJacob Faibussowitsch       case FILE_MODE_WRITE:
850d71ae5a4SJacob Faibussowitsch         vascii->fd = fopen(fname, "w");
851d71ae5a4SJacob Faibussowitsch         break;
852d71ae5a4SJacob Faibussowitsch       case FILE_MODE_APPEND:
853d71ae5a4SJacob Faibussowitsch         vascii->fd = fopen(fname, "a");
854d71ae5a4SJacob Faibussowitsch         break;
8555c6c1daeSBarry Smith       case FILE_MODE_UPDATE:
8565c6c1daeSBarry Smith         vascii->fd = fopen(fname, "r+");
857a297a907SKarl Rupp         if (!vascii->fd) vascii->fd = fopen(fname, "w+");
8585c6c1daeSBarry Smith         break;
8595c6c1daeSBarry Smith       case FILE_MODE_APPEND_UPDATE:
8605c6c1daeSBarry Smith         /* I really want a file which is opened at the end for updating,
8615c6c1daeSBarry Smith            not a+, which opens at the beginning, but makes writes at the end.
8625c6c1daeSBarry Smith         */
8635c6c1daeSBarry Smith         vascii->fd = fopen(fname, "r+");
864a297a907SKarl Rupp         if (!vascii->fd) vascii->fd = fopen(fname, "w+");
8653ba16761SJacob Faibussowitsch         else {
8663ba16761SJacob Faibussowitsch           int ret = fseek(vascii->fd, 0, SEEK_END);
8673ba16761SJacob Faibussowitsch           PetscCheck(!ret, PETSC_COMM_SELF, PETSC_ERR_LIB, "fseek() failed with error code %d", ret);
8683ba16761SJacob Faibussowitsch         }
8695c6c1daeSBarry Smith         break;
870d71ae5a4SJacob Faibussowitsch       default:
871d71ae5a4SJacob Faibussowitsch         SETERRQ(PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Unsupported file mode %s", PetscFileModes[vascii->mode]);
8725c6c1daeSBarry Smith       }
873bf31d2d3SBarry Smith       PetscCheck(vascii->fd, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Cannot open PetscViewer file: %s due to \"%s\"", fname, strerror(errno));
8745c6c1daeSBarry Smith     }
8755c6c1daeSBarry Smith   }
8763ba16761SJacob Faibussowitsch   PetscCall(PetscLogObjectState((PetscObject)viewer, "File: %s", name));
8773ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
8785c6c1daeSBarry Smith }
8795c6c1daeSBarry Smith 
PetscViewerGetSubViewer_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer * outviewer)88034e79e72SJacob Faibussowitsch static PetscErrorCode PetscViewerGetSubViewer_ASCII(PetscViewer viewer, MPI_Comm subcomm, PetscViewer *outviewer)
881d71ae5a4SJacob Faibussowitsch {
8825c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data, *ovascii;
8835c6c1daeSBarry Smith 
8845c6c1daeSBarry Smith   PetscFunctionBegin;
88528b400f6SJacob Faibussowitsch   PetscCheck(!vascii->sviewer, PETSC_COMM_SELF, PETSC_ERR_ORDER, "SubViewer already obtained from PetscViewer and not restored");
886fe8fb074SBarry Smith   PetscCall(PetscViewerASCIIPushSynchronized(viewer));
887e5afcf28SBarry Smith   /*
8889530cbd7SBarry Smith      The following line is a bug; it does another PetscViewerASCIIPushSynchronized() on viewer, but if it is removed the code won't work
8899530cbd7SBarry 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
8909530cbd7SBarry Smith      (since the count never gets to zero) in some examples this displays information that otherwise would be lost
8919530cbd7SBarry Smith 
8929530cbd7SBarry Smith      This code also means another call to PetscViewerASCIIPopSynchronized() must be made after the PetscViewerRestoreSubViewer(), see, for example,
8939530cbd7SBarry Smith      PCView_GASM().
894e5afcf28SBarry Smith   */
8959566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPushSynchronized(viewer));
896b4025f61SBarry Smith   PetscCall(PetscViewerFlush(viewer));
8979566063dSJacob Faibussowitsch   PetscCall(PetscViewerCreate(subcomm, outviewer));
8989566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetType(*outviewer, PETSCVIEWERASCII));
8999566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPushSynchronized(*outviewer));
9005c6c1daeSBarry Smith   ovascii            = (PetscViewer_ASCII *)(*outviewer)->data;
9015c6c1daeSBarry Smith   ovascii->fd        = vascii->fd;
9029f0612e4SBarry Smith   ovascii->fileunit  = vascii->fileunit;
903ba5a0b41SBarry Smith   ovascii->closefile = PETSC_FALSE;
9045c6c1daeSBarry Smith 
9055c6c1daeSBarry Smith   vascii->sviewer                                      = *outviewer;
9065c6c1daeSBarry Smith   (*outviewer)->format                                 = viewer->format;
9075c6c1daeSBarry Smith   ((PetscViewer_ASCII *)((*outviewer)->data))->bviewer = viewer;
9083f08860eSBarry Smith   (*outviewer)->ops->destroy                           = PetscViewerDestroy_ASCII_SubViewer;
9093ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9105c6c1daeSBarry Smith }
9115c6c1daeSBarry Smith 
PetscViewerRestoreSubViewer_ASCII(PetscViewer viewer,MPI_Comm comm,PetscViewer * outviewer)91234e79e72SJacob Faibussowitsch static PetscErrorCode PetscViewerRestoreSubViewer_ASCII(PetscViewer viewer, MPI_Comm comm, PetscViewer *outviewer)
913d71ae5a4SJacob Faibussowitsch {
9145c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
9155c6c1daeSBarry Smith 
9165c6c1daeSBarry Smith   PetscFunctionBegin;
91728b400f6SJacob Faibussowitsch   PetscCheck(ascii->sviewer, PETSC_COMM_SELF, PETSC_ERR_ORDER, "SubViewer never obtained from PetscViewer");
91808401ef6SPierre Jolivet   PetscCheck(ascii->sviewer == *outviewer, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "This PetscViewer did not generate this SubViewer");
9195c6c1daeSBarry Smith 
9209566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPopSynchronized(*outviewer));
921e5afcf28SBarry Smith   ascii->sviewer             = NULL;
9225c6c1daeSBarry Smith   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
9239566063dSJacob Faibussowitsch   PetscCall(PetscViewerDestroy(outviewer));
924fe8fb074SBarry Smith   PetscCall(PetscViewerFlush(viewer));
9259566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPopSynchronized(viewer));
9263ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9275c6c1daeSBarry Smith }
9285c6c1daeSBarry Smith 
PetscViewerView_ASCII(PetscViewer v,PetscViewer viewer)92934e79e72SJacob Faibussowitsch static PetscErrorCode PetscViewerView_ASCII(PetscViewer v, PetscViewer viewer)
930d71ae5a4SJacob Faibussowitsch {
9312bf49c77SBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)v->data;
9322bf49c77SBarry Smith 
9332bf49c77SBarry Smith   PetscFunctionBegin;
9349f0612e4SBarry Smith   if (ascii->fileunit) PetscCall(PetscViewerASCIIPrintf(viewer, "Fortran FILE UNIT: %d\n", ascii->fileunit));
93557b1f488SBarry Smith   else if (ascii->filename) PetscCall(PetscViewerASCIIPrintf(viewer, "Filename: %s\n", ascii->filename));
9363ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9372bf49c77SBarry Smith }
9382bf49c77SBarry Smith 
PetscViewerFlush_ASCII(PetscViewer viewer)9399f0612e4SBarry Smith static PetscErrorCode PetscViewerFlush_ASCII(PetscViewer viewer)
9409f0612e4SBarry Smith {
9419f0612e4SBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
9429f0612e4SBarry Smith   MPI_Comm           comm;
9439f0612e4SBarry Smith   PetscMPIInt        rank, size;
9449f0612e4SBarry Smith   FILE              *fd = vascii->fd;
9459f0612e4SBarry Smith 
9469f0612e4SBarry Smith   PetscFunctionBegin;
9479f0612e4SBarry Smith   PetscCheck(!vascii->sviewer, PetscObjectComm((PetscObject)viewer), PETSC_ERR_ARG_WRONGSTATE, "Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
9489f0612e4SBarry Smith   PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
9499f0612e4SBarry Smith   PetscCallMPI(MPI_Comm_rank(comm, &rank));
9509f0612e4SBarry Smith   PetscCallMPI(MPI_Comm_size(comm, &size));
9519f0612e4SBarry Smith 
9529f0612e4SBarry Smith   if (!vascii->bviewer && rank == 0 && (vascii->mode != FILE_MODE_READ)) PetscCall(PetscFFlush(vascii->fd));
9539f0612e4SBarry Smith 
9549f0612e4SBarry Smith   if (vascii->allowsynchronized) {
9559f0612e4SBarry Smith     PetscMPIInt tag, i, j, n = 0, dummy = 0;
9569f0612e4SBarry Smith     char       *message;
9579f0612e4SBarry Smith     MPI_Status  status;
9589f0612e4SBarry Smith 
9599f0612e4SBarry Smith     PetscCall(PetscCommDuplicate(comm, &comm, &tag));
9609f0612e4SBarry Smith 
9619f0612e4SBarry Smith     /* First processor waits for messages from all other processors */
9629f0612e4SBarry Smith     if (rank == 0) {
9639f0612e4SBarry Smith       /* flush my own messages that I may have queued up */
9649f0612e4SBarry Smith       PrintfQueue next = vascii->petsc_printfqueuebase, previous;
9659f0612e4SBarry Smith       for (i = 0; i < vascii->petsc_printfqueuelength; i++) {
9669f0612e4SBarry Smith         if (!vascii->bviewer) {
9679f0612e4SBarry Smith           if (!vascii->fileunit) PetscCall(PetscFPrintf(comm, fd, "%s", next->string));
9689f0612e4SBarry Smith           else PetscCall(PetscFPrintfFortran(vascii->fileunit, next->string));
9699f0612e4SBarry Smith         } else {
9709f0612e4SBarry Smith           PetscCall(PetscViewerASCIISynchronizedPrintf(vascii->bviewer, "%s", next->string));
9719f0612e4SBarry Smith         }
9729f0612e4SBarry Smith         previous = next;
9739f0612e4SBarry Smith         next     = next->next;
9749f0612e4SBarry Smith         PetscCall(PetscFree(previous->string));
9759f0612e4SBarry Smith         PetscCall(PetscFree(previous));
9769f0612e4SBarry Smith       }
9779f0612e4SBarry Smith       vascii->petsc_printfqueue       = NULL;
9789f0612e4SBarry Smith       vascii->petsc_printfqueuelength = 0;
9799f0612e4SBarry Smith       for (i = 1; i < size; i++) {
9809f0612e4SBarry Smith         /* to prevent a flood of messages to process zero, request each message separately */
9819f0612e4SBarry Smith         PetscCallMPI(MPI_Send(&dummy, 1, MPI_INT, i, tag, comm));
9829f0612e4SBarry Smith         PetscCallMPI(MPI_Recv(&n, 1, MPI_INT, i, tag, comm, &status));
9839f0612e4SBarry Smith         for (j = 0; j < n; j++) {
9846497c311SBarry Smith           size_t size;
9859f0612e4SBarry Smith 
9866497c311SBarry Smith           PetscCallMPI(MPI_Recv(&size, 1, MPIU_SIZE_T, i, tag, comm, &status));
9879f0612e4SBarry Smith           PetscCall(PetscMalloc1(size, &message));
9886497c311SBarry Smith           PetscCallMPI(MPI_Recv(message, (PetscMPIInt)size, MPI_CHAR, i, tag, comm, &status));
9899f0612e4SBarry Smith           if (!vascii->bviewer) {
9909f0612e4SBarry Smith             if (!vascii->fileunit) PetscCall(PetscFPrintf(comm, fd, "%s", message));
9919f0612e4SBarry Smith             else PetscCall(PetscFPrintfFortran(vascii->fileunit, message));
9929f0612e4SBarry Smith           } else {
9939f0612e4SBarry Smith             PetscCall(PetscViewerASCIISynchronizedPrintf(vascii->bviewer, "%s", message));
9949f0612e4SBarry Smith           }
9959f0612e4SBarry Smith           PetscCall(PetscFree(message));
9969f0612e4SBarry Smith         }
9979f0612e4SBarry Smith       }
9989f0612e4SBarry Smith     } else { /* other processors send queue to processor 0 */
9999f0612e4SBarry Smith       PrintfQueue next = vascii->petsc_printfqueuebase, previous;
10009f0612e4SBarry Smith 
10019f0612e4SBarry Smith       PetscCallMPI(MPI_Recv(&dummy, 1, MPI_INT, 0, tag, comm, &status));
10029f0612e4SBarry Smith       PetscCallMPI(MPI_Send(&vascii->petsc_printfqueuelength, 1, MPI_INT, 0, tag, comm));
10039f0612e4SBarry Smith       for (i = 0; i < vascii->petsc_printfqueuelength; i++) {
10046497c311SBarry Smith         PetscCallMPI(MPI_Send(&next->size, 1, MPIU_SIZE_T, 0, tag, comm));
10056497c311SBarry Smith         PetscCallMPI(MPI_Send(next->string, (PetscMPIInt)next->size, MPI_CHAR, 0, tag, comm));
10069f0612e4SBarry Smith         previous = next;
10079f0612e4SBarry Smith         next     = next->next;
10089f0612e4SBarry Smith         PetscCall(PetscFree(previous->string));
10099f0612e4SBarry Smith         PetscCall(PetscFree(previous));
10109f0612e4SBarry Smith       }
10119f0612e4SBarry Smith       vascii->petsc_printfqueue       = NULL;
10129f0612e4SBarry Smith       vascii->petsc_printfqueuelength = 0;
10139f0612e4SBarry Smith     }
10149f0612e4SBarry Smith     PetscCall(PetscCommDestroy(&comm));
10159f0612e4SBarry Smith   }
10169f0612e4SBarry Smith   PetscFunctionReturn(PETSC_SUCCESS);
10179f0612e4SBarry Smith }
10189f0612e4SBarry Smith 
10198556b5ebSBarry Smith /*MC
1020648c30bcSBarry Smith    PETSCVIEWERASCII - A viewer that prints to `stdout`, `stderr`, or an ASCII file
10218556b5ebSBarry Smith 
1022811af0c4SBarry Smith   Level: beginner
1023811af0c4SBarry Smith 
1024d1f92df0SBarry Smith .seealso: [](sec_viewers), `PETSC_VIEWER_STDOUT_()`, `PETSC_VIEWER_STDOUT_SELF`, `PETSC_VIEWER_STDOUT_WORLD`, `PetscViewerCreate()`, `PetscViewerASCIIOpen()`,
1025db781477SPatrick Sanan           `PetscViewerMatlabOpen()`, `VecView()`, `DMView()`, `PetscViewerMatlabPutArray()`, `PETSCVIEWERBINARY`, `PETSCVIEWERMATLAB`,
1026db781477SPatrick Sanan           `PetscViewerFileSetName()`, `PetscViewerFileSetMode()`, `PetscViewerFormat`, `PetscViewerType`, `PetscViewerSetType()`
10278556b5ebSBarry Smith M*/
PetscViewerCreate_ASCII(PetscViewer viewer)1028d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscViewerCreate_ASCII(PetscViewer viewer)
1029d71ae5a4SJacob Faibussowitsch {
10305c6c1daeSBarry Smith   PetscViewer_ASCII *vascii;
10315c6c1daeSBarry Smith 
10325c6c1daeSBarry Smith   PetscFunctionBegin;
10334dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&vascii));
10345c6c1daeSBarry Smith   viewer->data = (void *)vascii;
10355c6c1daeSBarry Smith 
10365c6c1daeSBarry Smith   viewer->ops->destroy          = PetscViewerDestroy_ASCII;
10375c6c1daeSBarry Smith   viewer->ops->flush            = PetscViewerFlush_ASCII;
1038559f443fSBarry Smith   viewer->ops->getsubviewer     = PetscViewerGetSubViewer_ASCII;
1039559f443fSBarry Smith   viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_ASCII;
10402bf49c77SBarry Smith   viewer->ops->view             = PetscViewerView_ASCII;
10411d641e7bSMichael Lange   viewer->ops->read             = PetscViewerASCIIRead;
10425c6c1daeSBarry Smith 
10435c6c1daeSBarry Smith   /* defaults to stdout unless set with PetscViewerFileSetName() */
10445c6c1daeSBarry Smith   vascii->fd        = PETSC_STDOUT;
10455c6c1daeSBarry Smith   vascii->mode      = FILE_MODE_WRITE;
104602c9f0b5SLisandro Dalcin   vascii->bviewer   = NULL;
104702c9f0b5SLisandro Dalcin   vascii->subviewer = NULL;
104802c9f0b5SLisandro Dalcin   vascii->sviewer   = NULL;
10495c6c1daeSBarry Smith   vascii->tab       = 0;
10505c6c1daeSBarry Smith   vascii->tab_store = 0;
105102c9f0b5SLisandro Dalcin   vascii->filename  = NULL;
10525c6c1daeSBarry Smith   vascii->closefile = PETSC_TRUE;
10535c6c1daeSBarry Smith 
10549566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileSetName_C", PetscViewerFileSetName_ASCII));
10559566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileGetName_C", PetscViewerFileGetName_ASCII));
10569566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileGetMode_C", PetscViewerFileGetMode_ASCII));
10579566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileSetMode_C", PetscViewerFileSetMode_ASCII));
10583ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10595c6c1daeSBarry Smith }
10605c6c1daeSBarry Smith 
10615c6c1daeSBarry Smith /*@C
1062c410d8ccSBarry Smith   PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified `PETSCVIEWERASCII` file from
10635c6c1daeSBarry Smith   several processors.  Output of the first processor is followed by that of the
10645c6c1daeSBarry Smith   second, etc.
10655c6c1daeSBarry Smith 
1066c410d8ccSBarry Smith   Not Collective, must call collective `PetscViewerFlush()` to get the results flushed
10675c6c1daeSBarry Smith 
10685c6c1daeSBarry Smith   Input Parameters:
1069811af0c4SBarry Smith + viewer - the `PETSCVIEWERASCII` `PetscViewer`
10705c6c1daeSBarry Smith - format - the usual printf() format string
10715c6c1daeSBarry Smith 
10725c6c1daeSBarry Smith   Level: intermediate
10735c6c1daeSBarry Smith 
107495452b02SPatrick Sanan   Notes:
1075811af0c4SBarry Smith   You must have previously called `PetscViewerASCIIPushSynchronized()` to allow this routine to be called.
1076e6abc3ddSVáclav Hapla   Then you can do multiple independent calls to this routine.
1077811af0c4SBarry Smith 
1078811af0c4SBarry Smith   The actual synchronized print is then done using `PetscViewerFlush()`.
1079811af0c4SBarry Smith   `PetscViewerASCIIPopSynchronized()` should be then called if we are already done with the synchronized output
1080e6abc3ddSVáclav Hapla   to conclude the "synchronized session".
1081811af0c4SBarry Smith 
1082e6abc3ddSVáclav Hapla   So the typical calling sequence looks like
1083811af0c4SBarry Smith .vb
1084811af0c4SBarry Smith     PetscViewerASCIIPushSynchronized(viewer);
1085811af0c4SBarry Smith     PetscViewerASCIISynchronizedPrintf(viewer, ...);
1086811af0c4SBarry Smith     PetscViewerASCIISynchronizedPrintf(viewer, ...);
1087811af0c4SBarry Smith     ...
1088811af0c4SBarry Smith     PetscViewerFlush(viewer);
1089811af0c4SBarry Smith     PetscViewerASCIISynchronizedPrintf(viewer, ...);
1090811af0c4SBarry Smith     PetscViewerASCIISynchronizedPrintf(viewer, ...);
1091811af0c4SBarry Smith     ...
1092811af0c4SBarry Smith     PetscViewerFlush(viewer);
1093811af0c4SBarry Smith     PetscViewerASCIIPopSynchronized(viewer);
1094811af0c4SBarry Smith .ve
10955c6c1daeSBarry Smith 
1096*3f7bdce8SBarry Smith   Fortran Note:
1097*3f7bdce8SBarry Smith   The call sequence is `PetscViewerASCIISynchronizedPrintf`(`PetscViewer`, `character(*)`, `PetscErrorCode` ierr)
1098*3f7bdce8SBarry Smith   That is, you can only pass a single character string from Fortran.
10995c6c1daeSBarry Smith 
1100d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscViewerASCIIPushSynchronized()`, `PetscViewerFlush()`, `PetscViewerASCIIPopSynchronized()`,
1101db781477SPatrick Sanan           `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIIOpen()`,
1102db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`
11035c6c1daeSBarry Smith @*/
PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...)1104d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIISynchronizedPrintf(PetscViewer viewer, const char format[], ...)
1105d71ae5a4SJacob Faibussowitsch {
11065c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
11073f08860eSBarry Smith   PetscMPIInt        rank;
1108fe8fb074SBarry Smith   PetscInt           tab = 0;
11095c6c1daeSBarry Smith   MPI_Comm           comm;
11109f196a02SMartin Diehl   PetscBool          isascii;
11115c6c1daeSBarry Smith 
11125c6c1daeSBarry Smith   PetscFunctionBegin;
11135c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
11144f572ea9SToby Isaac   PetscAssertPointer(format, 2);
11159f196a02SMartin Diehl   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
11169f196a02SMartin Diehl   PetscCheck(isascii, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Not ASCII PetscViewer");
111728b400f6SJacob Faibussowitsch   PetscCheck(vascii->allowsynchronized, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "First call PetscViewerASCIIPushSynchronized() to allow this call");
11185c6c1daeSBarry Smith 
11199566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
11209566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
11215c6c1daeSBarry Smith 
1122559f443fSBarry Smith   if (vascii->bviewer) {
1123fe8fb074SBarry Smith     char   *string;
11245c6c1daeSBarry Smith     va_list Argp;
1125fe8fb074SBarry Smith     size_t  fullLength;
11265c6c1daeSBarry Smith 
1127fe8fb074SBarry Smith     PetscCall(PetscCalloc1(QUEUESTRINGSIZE, &string));
1128ac530a7eSPierre Jolivet     for (; tab < vascii->tab; tab++) string[2 * tab] = string[2 * tab + 1] = ' ';
1129fe8fb074SBarry Smith     va_start(Argp, format);
1130fe8fb074SBarry Smith     PetscCall(PetscVSNPrintf(string + 2 * tab, QUEUESTRINGSIZE - 2 * tab, format, &fullLength, Argp));
1131fe8fb074SBarry Smith     va_end(Argp);
1132fe8fb074SBarry Smith     PetscCall(PetscViewerASCIISynchronizedPrintf(vascii->bviewer, "%s", string));
1133fe8fb074SBarry Smith     PetscCall(PetscFree(string));
1134fe8fb074SBarry Smith   } else if (rank == 0) { /* First processor prints immediately to fp */
1135fe8fb074SBarry Smith     va_list Argp;
1136fe8fb074SBarry Smith     FILE   *fp = vascii->fd;
1137fe8fb074SBarry Smith 
1138fe8fb074SBarry Smith     tab = vascii->tab;
11399f0612e4SBarry Smith     while (tab--) {
11409f0612e4SBarry Smith       if (!vascii->fileunit) PetscCall(PetscFPrintf(PETSC_COMM_SELF, fp, "  "));
11419f0612e4SBarry Smith       else PetscCall(PetscFPrintfFortran(vascii->fileunit, "   "));
11429f0612e4SBarry Smith     }
11435c6c1daeSBarry Smith 
11445c6c1daeSBarry Smith     va_start(Argp, format);
11459f0612e4SBarry Smith     if (!vascii->fileunit) PetscCall((*PetscVFPrintf)(fp, format, Argp));
11469f0612e4SBarry Smith     else PetscCall(PetscVFPrintfFortran(vascii->fileunit, format, Argp));
1147eae3dc7dSJacob Faibussowitsch     va_end(Argp);
1148c69effb2SJacob Faibussowitsch     PetscCall(PetscFFlush(fp));
11495c6c1daeSBarry Smith     if (petsc_history) {
11505c6c1daeSBarry Smith       va_start(Argp, format);
11519566063dSJacob Faibussowitsch       PetscCall((*PetscVFPrintf)(petsc_history, format, Argp));
1152eae3dc7dSJacob Faibussowitsch       va_end(Argp);
1153c69effb2SJacob Faibussowitsch       PetscCall(PetscFFlush(petsc_history));
11545c6c1daeSBarry Smith     }
1155559f443fSBarry Smith   } else { /* other processors add to queue */
11565c6c1daeSBarry Smith     char       *string;
11575c6c1daeSBarry Smith     va_list     Argp;
11585c6c1daeSBarry Smith     size_t      fullLength;
11595c6c1daeSBarry Smith     PrintfQueue next;
11605c6c1daeSBarry Smith 
11619566063dSJacob Faibussowitsch     PetscCall(PetscNew(&next));
1162559f443fSBarry Smith     if (vascii->petsc_printfqueue) {
1163559f443fSBarry Smith       vascii->petsc_printfqueue->next = next;
1164559f443fSBarry Smith       vascii->petsc_printfqueue       = next;
1165a297a907SKarl Rupp     } else {
1166559f443fSBarry Smith       vascii->petsc_printfqueuebase = vascii->petsc_printfqueue = next;
1167a297a907SKarl Rupp     }
1168559f443fSBarry Smith     vascii->petsc_printfqueuelength++;
11695c6c1daeSBarry Smith     next->size = QUEUESTRINGSIZE;
11709566063dSJacob Faibussowitsch     PetscCall(PetscCalloc1(next->size, &next->string));
11715c6c1daeSBarry Smith     string = next->string;
1172f15bb73eSStefano Zampini 
1173f15bb73eSStefano Zampini     tab = vascii->tab;
11745c6c1daeSBarry Smith     tab *= 2;
1175ad540459SPierre Jolivet     while (tab--) *string++ = ' ';
11765c6c1daeSBarry Smith     va_start(Argp, format);
11779566063dSJacob Faibussowitsch     PetscCall(PetscVSNPrintf(string, next->size - 2 * vascii->tab, format, &fullLength, Argp));
11785c6c1daeSBarry Smith     va_end(Argp);
1179835f2295SStefano Zampini     if (fullLength > next->size - 2 * vascii->tab) {
11809566063dSJacob Faibussowitsch       PetscCall(PetscFree(next->string));
118114416c0eSBarry Smith       next->size = fullLength + 2 * vascii->tab;
11829566063dSJacob Faibussowitsch       PetscCall(PetscCalloc1(next->size, &next->string));
118314416c0eSBarry Smith       string = next->string;
118414416c0eSBarry Smith       tab    = 2 * vascii->tab;
1185ad540459SPierre Jolivet       while (tab--) *string++ = ' ';
118614416c0eSBarry Smith       va_start(Argp, format);
11879566063dSJacob Faibussowitsch       PetscCall(PetscVSNPrintf(string, next->size - 2 * vascii->tab, format, NULL, Argp));
118814416c0eSBarry Smith       va_end(Argp);
118914416c0eSBarry Smith     }
11905c6c1daeSBarry Smith   }
11913ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
11925c6c1daeSBarry Smith }
11935c6c1daeSBarry Smith 
11942655f987SMichael Lange /*@C
1195c410d8ccSBarry Smith   PetscViewerASCIIRead - Reads from a `PETSCVIEWERASCII` file
11962655f987SMichael Lange 
1197c410d8ccSBarry Smith   Only MPI rank 0 in the `PetscViewer` may call this
11982655f987SMichael Lange 
11992655f987SMichael Lange   Input Parameters:
12003f423023SBarry Smith + viewer - the `PETSCVIEWERASCII` viewer
1201c410d8ccSBarry Smith . data   - location to write the data, treated as an array of type indicated by `datatype`
1202060da220SMatthew G. Knepley . num    - number of items of data to read
1203aec76313SJacob Faibussowitsch - dtype  - type of data to read
12042655f987SMichael Lange 
120520f4b53cSBarry Smith   Output Parameter:
12063f423023SBarry Smith . count - number of items of data actually read, or `NULL`
1207f8e4bde8SMatthew G. Knepley 
12082655f987SMichael Lange   Level: beginner
12092655f987SMichael Lange 
1210d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscViewerASCIIOpen()`, `PetscViewerPushFormat()`, `PetscViewerDestroy()`, `PetscViewerCreate()`, `PetscViewerFileSetMode()`, `PetscViewerFileSetName()`
1211db781477SPatrick Sanan           `VecView()`, `MatView()`, `VecLoad()`, `MatLoad()`, `PetscViewerBinaryGetDescriptor()`,
1212db781477SPatrick Sanan           `PetscViewerBinaryGetInfoPointer()`, `PetscFileMode`, `PetscViewer`, `PetscViewerBinaryRead()`
12132655f987SMichael Lange @*/
PetscViewerASCIIRead(PetscViewer viewer,void * data,PetscInt num,PetscInt * count,PetscDataType dtype)1214d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIIRead(PetscViewer viewer, void *data, PetscInt num, PetscInt *count, PetscDataType dtype)
1215d71ae5a4SJacob Faibussowitsch {
12162655f987SMichael Lange   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
12172655f987SMichael Lange   FILE              *fd     = vascii->fd;
12182655f987SMichael Lange   PetscInt           i;
12193b7fe8c3SMatthew G. Knepley   int                ret = 0;
1220f8859db6SBarry Smith   PetscMPIInt        rank;
12212655f987SMichael Lange 
12222655f987SMichael Lange   PetscFunctionBegin;
12232655f987SMichael Lange   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
12249566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank));
1225c5853193SPierre Jolivet   PetscCheck(rank == 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Can only be called from process 0 in the PetscViewer");
1226060da220SMatthew G. Knepley   for (i = 0; i < num; i++) {
1227f8e4bde8SMatthew G. Knepley     if (dtype == PETSC_CHAR) ret = fscanf(fd, "%c", &(((char *)data)[i]));
1228f8e4bde8SMatthew G. Knepley     else if (dtype == PETSC_STRING) ret = fscanf(fd, "%s", &(((char *)data)[i]));
1229a05e1a72SSatish Balay     else if (dtype == PETSC_INT) ret = fscanf(fd, "%" PetscInt_FMT, &(((PetscInt *)data)[i]));
1230f8e4bde8SMatthew G. Knepley     else if (dtype == PETSC_ENUM) ret = fscanf(fd, "%d", &(((int *)data)[i]));
12319e3e4c22SLisandro Dalcin     else if (dtype == PETSC_INT64) ret = fscanf(fd, "%" PetscInt64_FMT, &(((PetscInt64 *)data)[i]));
1232972064b6SLisandro Dalcin     else if (dtype == PETSC_LONG) ret = fscanf(fd, "%ld", &(((long *)data)[i]));
12336497c311SBarry Smith     else if (dtype == PETSC_COUNT) ret = fscanf(fd, "%" PetscCount_FMT, &(((PetscCount *)data)[i]));
1234f8e4bde8SMatthew G. Knepley     else if (dtype == PETSC_FLOAT) ret = fscanf(fd, "%f", &(((float *)data)[i]));
1235f8e4bde8SMatthew G. Knepley     else if (dtype == PETSC_DOUBLE) ret = fscanf(fd, "%lg", &(((double *)data)[i]));
1236a6e181c6SToby Isaac #if defined(PETSC_USE_REAL___FLOAT128)
1237fba955ccSBarry Smith     else if (dtype == PETSC___FLOAT128) {
1238fba955ccSBarry Smith       double tmp;
1239fba955ccSBarry Smith       ret                     = fscanf(fd, "%lg", &tmp);
1240a6e181c6SToby Isaac       ((__float128 *)data)[i] = tmp;
1241a6e181c6SToby Isaac     }
1242fba955ccSBarry Smith #endif
12439371c9d4SSatish Balay     else
12449371c9d4SSatish Balay       SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Data type %d not supported", (int)dtype);
124528b400f6SJacob Faibussowitsch     PetscCheck(ret, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Conversion error for data type %d", (int)dtype);
1246f7d195e4SLawrence Mitchell     if (ret < 0) break; /* Proxy for EOF, need to check for it in configure */
12472655f987SMichael Lange   }
1248060da220SMatthew G. Knepley   if (count) *count = i;
124908401ef6SPierre Jolivet   else PetscCheck(ret >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Insufficient data, read only %" PetscInt_FMT " < %" PetscInt_FMT " items", i, num);
12503ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
12512655f987SMichael Lange }
1252