xref: /petsc/src/sys/classes/viewer/impls/ascii/vcreatea.c (revision 34fa283e3f79c4e6ee06127db834b156ca11f1ea)
15c6c1daeSBarry Smith 
2f5860696SSatish Balay #include <../src/sys/classes/viewer/impls/ascii/asciiimpl.h> /*I     "petscviewer.h"   I*/
35c6c1daeSBarry Smith 
4e2dcd6d3SBarry Smith /*
5e2dcd6d3SBarry Smith     The variable Petsc_Viewer_Stdout_keyval is used to indicate an MPI attribute that
6e2dcd6d3SBarry Smith   is attached to a communicator, in this case the attribute is a PetscViewer.
7e2dcd6d3SBarry Smith */
8d4c7638eSBarry Smith PetscMPIInt Petsc_Viewer_Stdout_keyval = MPI_KEYVAL_INVALID;
9e2dcd6d3SBarry Smith 
109c5ded49SBarry Smith /*@
11811af0c4SBarry Smith   PetscViewerASCIIGetStdout - Creates a `PETSCVIEWERASCII` `PetscViewer` shared by all processors
12811af0c4SBarry Smith   in a communicator. Error returning version of `PETSC_VIEWER_STDOUT_()`
135c6c1daeSBarry Smith 
14d083f849SBarry Smith   Collective
155c6c1daeSBarry Smith 
165c6c1daeSBarry Smith   Input Parameter:
17811af0c4SBarry Smith . comm - the MPI communicator to share the `PetscViewer`
185c6c1daeSBarry Smith 
1910450e9eSJacob Faibussowitsch   Output Parameter:
2010450e9eSJacob Faibussowitsch . viewer - the viewer
2110450e9eSJacob Faibussowitsch 
225c6c1daeSBarry Smith   Level: beginner
235c6c1daeSBarry Smith 
24811af0c4SBarry Smith   Note:
25*34fa283eSBarry Smith   This object is destroyed in `PetscFinalize()`, `PetscViewerDestroy()` should never be called on it
26*34fa283eSBarry Smith 
27*34fa283eSBarry Smith   Developer Note:
283f423023SBarry Smith   This should be used in all PETSc source code instead of `PETSC_VIEWER_STDOUT_()` since it allows error checking
295c6c1daeSBarry Smith 
30d1f92df0SBarry Smith .seealso: [](sec_viewers), `PETSC_VIEWER_DRAW_()`, `PetscViewerASCIIOpen()`, `PETSC_VIEWER_STDERR_`, `PETSC_VIEWER_STDOUT_WORLD`,
31db781477SPatrick Sanan           `PETSC_VIEWER_STDOUT_SELF`
325c6c1daeSBarry Smith @*/
33d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIIGetStdout(MPI_Comm comm, PetscViewer *viewer)
34d71ae5a4SJacob Faibussowitsch {
35e2dcd6d3SBarry Smith   PetscBool flg;
36e2dcd6d3SBarry Smith   MPI_Comm  ncomm;
375c6c1daeSBarry Smith 
385c6c1daeSBarry Smith   PetscFunctionBegin;
399566063dSJacob Faibussowitsch   PetscCall(PetscSpinlockLock(&PetscViewerASCIISpinLockStdout));
409566063dSJacob Faibussowitsch   PetscCall(PetscCommDuplicate(comm, &ncomm, NULL));
4148a46eb9SPierre Jolivet   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));
429566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_get_attr(ncomm, Petsc_Viewer_Stdout_keyval, (void **)viewer, (PetscMPIInt *)&flg));
43e2dcd6d3SBarry Smith   if (!flg) { /* PetscViewer not yet created */
449566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIOpen(ncomm, "stdout", viewer));
45*34fa283eSBarry Smith     ((PetscObject)*viewer)->persistent = PETSC_TRUE;
469566063dSJacob Faibussowitsch     PetscCall(PetscObjectRegisterDestroy((PetscObject)*viewer));
479566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_set_attr(ncomm, Petsc_Viewer_Stdout_keyval, (void *)*viewer));
48e2dcd6d3SBarry Smith   }
499566063dSJacob Faibussowitsch   PetscCall(PetscCommDestroy(&ncomm));
509566063dSJacob Faibussowitsch   PetscCall(PetscSpinlockUnlock(&PetscViewerASCIISpinLockStdout));
513ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
525c6c1daeSBarry Smith }
535c6c1daeSBarry Smith 
545c6c1daeSBarry Smith /*@C
55c410d8ccSBarry Smith    PETSC_VIEWER_STDOUT_ - Creates a `PETSCVIEWERASCII` `PetscViewer` shared by all MPI processes
565c6c1daeSBarry Smith                     in a communicator.
575c6c1daeSBarry Smith 
58d083f849SBarry Smith    Collective
595c6c1daeSBarry Smith 
605c6c1daeSBarry Smith    Input Parameter:
61811af0c4SBarry Smith .  comm - the MPI communicator to share the `PetscViewer`
625c6c1daeSBarry Smith 
635c6c1daeSBarry Smith    Level: beginner
645c6c1daeSBarry Smith 
65*34fa283eSBarry Smith    Notes:
66*34fa283eSBarry Smith    This object is destroyed in `PetscFinalize()`, `PetscViewerDestroy()` should never be called on it
67*34fa283eSBarry Smith 
685c6c1daeSBarry Smith    Unlike almost all other PETSc routines, this does not return
695c6c1daeSBarry Smith    an error code. Usually used in the form
705c6c1daeSBarry Smith $      XXXView(XXX object, PETSC_VIEWER_STDOUT_(comm));
715c6c1daeSBarry Smith 
72d1f92df0SBarry Smith .seealso: [](sec_viewers), `PETSC_VIEWER_DRAW_()`, `PetscViewerASCIIOpen()`, `PETSC_VIEWER_STDERR_`, `PETSC_VIEWER_STDOUT_WORLD`,
73db781477SPatrick Sanan           `PETSC_VIEWER_STDOUT_SELF`
745c6c1daeSBarry Smith @*/
75d71ae5a4SJacob Faibussowitsch PetscViewer PETSC_VIEWER_STDOUT_(MPI_Comm comm)
76d71ae5a4SJacob Faibussowitsch {
775c6c1daeSBarry Smith   PetscErrorCode ierr;
785c6c1daeSBarry Smith   PetscViewer    viewer;
795c6c1daeSBarry Smith 
805c6c1daeSBarry Smith   PetscFunctionBegin;
815c6c1daeSBarry Smith   ierr = PetscViewerASCIIGetStdout(comm, &viewer);
829371c9d4SSatish Balay   if (ierr) {
833ba16761SJacob Faibussowitsch     ierr = PetscError(PETSC_COMM_SELF, __LINE__, "PETSC_VIEWER_STDOUT_", __FILE__, PETSC_ERR_PLIB, PETSC_ERROR_INITIAL, " ");
849371c9d4SSatish Balay     PetscFunctionReturn(NULL);
859371c9d4SSatish Balay   }
865c6c1daeSBarry Smith   PetscFunctionReturn(viewer);
875c6c1daeSBarry Smith }
885c6c1daeSBarry Smith 
89e2dcd6d3SBarry Smith /*
90e2dcd6d3SBarry Smith     The variable Petsc_Viewer_Stderr_keyval is used to indicate an MPI attribute that
91e2dcd6d3SBarry Smith   is attached to a communicator, in this case the attribute is a PetscViewer.
92e2dcd6d3SBarry Smith */
93d4c7638eSBarry Smith PetscMPIInt Petsc_Viewer_Stderr_keyval = MPI_KEYVAL_INVALID;
94e2dcd6d3SBarry Smith 
959c5ded49SBarry Smith /*@
96c410d8ccSBarry Smith   PetscViewerASCIIGetStderr - Creates a `PETSCVIEWERASCII` `PetscViewer` shared by all MPI processes
97811af0c4SBarry Smith   in a communicator. Error returning version of `PETSC_VIEWER_STDERR_()`
985c6c1daeSBarry Smith 
99d083f849SBarry Smith   Collective
1005c6c1daeSBarry Smith 
1015c6c1daeSBarry Smith   Input Parameter:
102811af0c4SBarry Smith . comm - the MPI communicator to share the `PetscViewer`
1035c6c1daeSBarry Smith 
10410450e9eSJacob Faibussowitsch   Output Parameter:
10510450e9eSJacob Faibussowitsch . viewer - the viewer
10610450e9eSJacob Faibussowitsch 
1075c6c1daeSBarry Smith   Level: beginner
1085c6c1daeSBarry Smith 
109811af0c4SBarry Smith   Note:
110*34fa283eSBarry Smith   This object is destroyed in `PetscFinalize()`, `PetscViewerDestroy()` should never be called on it
111*34fa283eSBarry Smith 
112*34fa283eSBarry Smith   Developer Note:
1133f423023SBarry Smith   This should be used in all PETSc source code instead of `PETSC_VIEWER_STDERR_()` since it allows error checking
1145c6c1daeSBarry Smith 
115d1f92df0SBarry Smith .seealso: [](sec_viewers), `PETSC_VIEWER_DRAW_()`, `PetscViewerASCIIOpen()`, `PETSC_VIEWER_STDERR_`, `PETSC_VIEWER_STDERR_WORLD`,
116db781477SPatrick Sanan           `PETSC_VIEWER_STDERR_SELF`
1175c6c1daeSBarry Smith @*/
118d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIIGetStderr(MPI_Comm comm, PetscViewer *viewer)
119d71ae5a4SJacob Faibussowitsch {
120e2dcd6d3SBarry Smith   PetscBool flg;
121e2dcd6d3SBarry Smith   MPI_Comm  ncomm;
122e2dcd6d3SBarry Smith 
123e2dcd6d3SBarry Smith   PetscFunctionBegin;
1249566063dSJacob Faibussowitsch   PetscCall(PetscSpinlockLock(&PetscViewerASCIISpinLockStderr));
1259566063dSJacob Faibussowitsch   PetscCall(PetscCommDuplicate(comm, &ncomm, NULL));
12648a46eb9SPierre Jolivet   if (Petsc_Viewer_Stderr_keyval == MPI_KEYVAL_INVALID) PetscCallMPI(MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN, MPI_COMM_NULL_DELETE_FN, &Petsc_Viewer_Stderr_keyval, NULL));
1279566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_get_attr(ncomm, Petsc_Viewer_Stderr_keyval, (void **)viewer, (PetscMPIInt *)&flg));
128e2dcd6d3SBarry Smith   if (!flg) { /* PetscViewer not yet created */
1299566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIOpen(ncomm, "stderr", viewer));
130*34fa283eSBarry Smith     ((PetscObject)*viewer)->persistent = PETSC_TRUE;
1319566063dSJacob Faibussowitsch     PetscCall(PetscObjectRegisterDestroy((PetscObject)*viewer));
1329566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_set_attr(ncomm, Petsc_Viewer_Stderr_keyval, (void *)*viewer));
133e2dcd6d3SBarry Smith   }
1349566063dSJacob Faibussowitsch   PetscCall(PetscCommDestroy(&ncomm));
1359566063dSJacob Faibussowitsch   PetscCall(PetscSpinlockUnlock(&PetscViewerASCIISpinLockStderr));
1363ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1375c6c1daeSBarry Smith }
1385c6c1daeSBarry Smith 
1395c6c1daeSBarry Smith /*@C
140c410d8ccSBarry Smith    PETSC_VIEWER_STDERR_ - Creates a `PETSCVIEWERASCII` `PetscViewer` shared by all MPI processes
1415c6c1daeSBarry Smith                     in a communicator.
1425c6c1daeSBarry Smith 
143d083f849SBarry Smith    Collective
1445c6c1daeSBarry Smith 
1455c6c1daeSBarry Smith    Input Parameter:
146811af0c4SBarry Smith .  comm - the MPI communicator to share the `PetscViewer`
1475c6c1daeSBarry Smith 
1485c6c1daeSBarry Smith    Level: beginner
1495c6c1daeSBarry Smith 
1503f423023SBarry Smith    Notes:
151*34fa283eSBarry Smith    This object is destroyed in `PetscFinalize()`, `PetscViewerDestroy()` should never be called on it
152*34fa283eSBarry Smith 
1535c6c1daeSBarry Smith    Unlike almost all other PETSc routines, this does not return
1545c6c1daeSBarry Smith    an error code. Usually used in the form
1555c6c1daeSBarry Smith $      XXXView(XXX object, PETSC_VIEWER_STDERR_(comm));
1565c6c1daeSBarry Smith 
1573f423023SBarry Smith    `PetscViewerASCIIGetStderr()` is preferred  since it allows error checking
1583f423023SBarry Smith 
159d1f92df0SBarry Smith .seealso: [](sec_viewers), `PETSC_VIEWER_DRAW_`, `PetscViewerASCIIOpen()`, `PETSC_VIEWER_STDOUT_`, `PETSC_VIEWER_STDOUT_WORLD`,
160db781477SPatrick Sanan           `PETSC_VIEWER_STDOUT_SELF`, `PETSC_VIEWER_STDERR_WORLD`, `PETSC_VIEWER_STDERR_SELF`
1615c6c1daeSBarry Smith @*/
162d71ae5a4SJacob Faibussowitsch PetscViewer PETSC_VIEWER_STDERR_(MPI_Comm comm)
163d71ae5a4SJacob Faibussowitsch {
1645c6c1daeSBarry Smith   PetscErrorCode ierr;
1655c6c1daeSBarry Smith   PetscViewer    viewer;
1665c6c1daeSBarry Smith 
1675c6c1daeSBarry Smith   PetscFunctionBegin;
1685c6c1daeSBarry Smith   ierr = PetscViewerASCIIGetStderr(comm, &viewer);
1699371c9d4SSatish Balay   if (ierr) {
1703ba16761SJacob Faibussowitsch     ierr = PetscError(PETSC_COMM_SELF, __LINE__, "PETSC_VIEWER_STDERR_", __FILE__, PETSC_ERR_PLIB, PETSC_ERROR_INITIAL, " ");
1719371c9d4SSatish Balay     PetscFunctionReturn(NULL);
1729371c9d4SSatish Balay   }
1735c6c1daeSBarry Smith   PetscFunctionReturn(viewer);
1745c6c1daeSBarry Smith }
1755c6c1daeSBarry Smith 
1765c6c1daeSBarry Smith PetscMPIInt Petsc_Viewer_keyval = MPI_KEYVAL_INVALID;
1775c6c1daeSBarry Smith /*
1783f423023SBarry Smith    Called with MPI_Comm_free() is called on a communicator that has a viewer as an attribute. The viewer is not actually destroyed
1793f423023SBarry Smith    because that is managed by PetscObjectDestroyRegisterAll(). PetscViewerASCIIGetStdout() registers the viewer with PetscObjectDestroyRegister() to be destroyed when PetscFinalize() is called.
1805c6c1daeSBarry Smith 
1815c6c1daeSBarry Smith   This is called by MPI, not by users.
1825c6c1daeSBarry Smith 
1835c6c1daeSBarry Smith */
184d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscMPIInt MPIAPI Petsc_DelViewer(MPI_Comm comm, PetscMPIInt keyval, void *attr_val, void *extra_state)
185d71ae5a4SJacob Faibussowitsch {
1865c6c1daeSBarry Smith   PetscFunctionBegin;
1879566063dSJacob Faibussowitsch   PetscCallMPI(PetscInfo(NULL, "Removing viewer data attribute in an MPI_Comm %ld\n", (long)comm));
1885c6c1daeSBarry Smith   PetscFunctionReturn(MPI_SUCCESS);
1895c6c1daeSBarry Smith }
1905c6c1daeSBarry Smith 
1915c6c1daeSBarry Smith /*@C
192c410d8ccSBarry Smith   PetscViewerASCIIOpen - Opens an ASCII file for writing as a `PETSCVIEWERASCII` `PetscViewer`.
1935c6c1daeSBarry Smith 
194d083f849SBarry Smith   Collective
1955c6c1daeSBarry Smith 
1965c6c1daeSBarry Smith   Input Parameters:
1975c6c1daeSBarry Smith + comm - the communicator
1985c6c1daeSBarry Smith - name - the file name
1995c6c1daeSBarry Smith 
2005c6c1daeSBarry Smith   Output Parameter:
2013f423023SBarry Smith . lab - the `PetscViewer` to use with the specified file
2025c6c1daeSBarry Smith 
2035c6c1daeSBarry Smith   Level: beginner
2045c6c1daeSBarry Smith 
2055c6c1daeSBarry Smith   Notes:
206f8859db6SBarry Smith   To open a ASCII file as a viewer for reading one must use the sequence
207811af0c4SBarry Smith .vb
208811af0c4SBarry Smith    PetscViewerCreate(comm,&lab);
209811af0c4SBarry Smith    PetscViewerSetType(lab,PETSCVIEWERASCII);
210811af0c4SBarry Smith    PetscViewerFileSetMode(lab,FILE_MODE_READ);
211811af0c4SBarry Smith    PetscViewerFileSetName(lab,name);
212811af0c4SBarry Smith .ve
213f8859db6SBarry Smith 
214811af0c4SBarry Smith   This `PetscViewer` can be destroyed with `PetscViewerDestroy()`.
2155c6c1daeSBarry Smith 
2162ea3bc1cSBarry Smith   The MPI communicator used here must match that used by the object one is viewing. For example if the
217811af0c4SBarry Smith   Mat was created with a `PETSC_COMM_WORLD`, then the Viewer must be created with `PETSC_COMM_WORLD`
2185c6c1daeSBarry Smith 
219811af0c4SBarry Smith   As shown below, `PetscViewerASCIIOpen()` is useful in conjunction with
220811af0c4SBarry Smith   `MatView()` and `VecView()`
2215c6c1daeSBarry Smith .vb
2225c6c1daeSBarry Smith      PetscViewerASCIIOpen(PETSC_COMM_WORLD,"mat.output",&viewer);
2235c6c1daeSBarry Smith      MatView(matrix,viewer);
2245c6c1daeSBarry Smith .ve
2255c6c1daeSBarry Smith 
226d1f92df0SBarry Smith .seealso: [](sec_viewers), `MatView()`, `VecView()`, `PetscViewerDestroy()`, `PetscViewerBinaryOpen()`, `PetscViewerASCIIRead()`, `PETSCVIEWERASCII`
227db781477SPatrick Sanan           `PetscViewerASCIIGetPointer()`, `PetscViewerPushFormat()`, `PETSC_VIEWER_STDOUT_`, `PETSC_VIEWER_STDERR_`,
228db781477SPatrick Sanan           `PETSC_VIEWER_STDOUT_WORLD`, `PETSC_VIEWER_STDOUT_SELF`,
2295c6c1daeSBarry Smith @*/
230d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIIOpen(MPI_Comm comm, const char name[], PetscViewer *lab)
231d71ae5a4SJacob Faibussowitsch {
2325c6c1daeSBarry Smith   PetscViewerLink *vlink, *nv;
2335c6c1daeSBarry Smith   PetscBool        flg, eq;
2345c6c1daeSBarry Smith   size_t           len;
2355c6c1daeSBarry Smith 
2365c6c1daeSBarry Smith   PetscFunctionBegin;
2379566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(name, &len));
2385c6c1daeSBarry Smith   if (!len) {
2399566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIGetStdout(comm, lab));
2409566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)*lab));
2413ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
2425c6c1daeSBarry Smith   }
2439566063dSJacob Faibussowitsch   PetscCall(PetscSpinlockLock(&PetscViewerASCIISpinLockOpen));
24448a46eb9SPierre 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));
2452bf49c77SBarry Smith   /*
2462bf49c77SBarry Smith        It would be better to move this code to PetscFileSetName() but since it must return a preexiting communicator
2472bf49c77SBarry Smith      we cannot do that, since PetscFileSetName() takes a communicator that already exists.
2482bf49c77SBarry Smith 
2492bf49c77SBarry Smith       Plus if the original communicator that created the file has since been close this will not detect the old
2502bf49c77SBarry Smith       communictor and hence will overwrite the old data. It may be better to simply remove all this code
2512bf49c77SBarry Smith   */
2525c6c1daeSBarry Smith   /* make sure communicator is a PETSc communicator */
2539566063dSJacob Faibussowitsch   PetscCall(PetscCommDuplicate(comm, &comm, NULL));
2545c6c1daeSBarry Smith   /* has file already been opened into a viewer */
2559566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_get_attr(comm, Petsc_Viewer_keyval, (void **)&vlink, (PetscMPIInt *)&flg));
2565c6c1daeSBarry Smith   if (flg) {
2575c6c1daeSBarry Smith     while (vlink) {
2589566063dSJacob Faibussowitsch       PetscCall(PetscStrcmp(name, ((PetscViewer_ASCII *)(vlink->viewer->data))->filename, &eq));
2595c6c1daeSBarry Smith       if (eq) {
2609566063dSJacob Faibussowitsch         PetscCall(PetscObjectReference((PetscObject)vlink->viewer));
2615c6c1daeSBarry Smith         *lab = vlink->viewer;
2629566063dSJacob Faibussowitsch         PetscCall(PetscCommDestroy(&comm));
2639566063dSJacob Faibussowitsch         PetscCall(PetscSpinlockUnlock(&PetscViewerASCIISpinLockOpen));
2643ba16761SJacob Faibussowitsch         PetscFunctionReturn(PETSC_SUCCESS);
2655c6c1daeSBarry Smith       }
2665c6c1daeSBarry Smith       vlink = vlink->next;
2675c6c1daeSBarry Smith     }
2685c6c1daeSBarry Smith   }
2699566063dSJacob Faibussowitsch   PetscCall(PetscViewerCreate(comm, lab));
2709566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetType(*lab, PETSCVIEWERASCII));
2711baa6e33SBarry Smith   if (name) PetscCall(PetscViewerFileSetName(*lab, name));
2725c6c1daeSBarry Smith   /* save viewer into communicator if needed later */
2739566063dSJacob Faibussowitsch   PetscCall(PetscNew(&nv));
2745c6c1daeSBarry Smith   nv->viewer = *lab;
2755c6c1daeSBarry Smith   if (!flg) {
2769566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_set_attr(comm, Petsc_Viewer_keyval, nv));
2775c6c1daeSBarry Smith   } else {
2789566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_get_attr(comm, Petsc_Viewer_keyval, (void **)&vlink, (PetscMPIInt *)&flg));
2795c6c1daeSBarry Smith     if (vlink) {
2805c6c1daeSBarry Smith       while (vlink->next) vlink = vlink->next;
2815c6c1daeSBarry Smith       vlink->next = nv;
2825c6c1daeSBarry Smith     } else {
2839566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Comm_set_attr(comm, Petsc_Viewer_keyval, nv));
2845c6c1daeSBarry Smith     }
2855c6c1daeSBarry Smith   }
2869566063dSJacob Faibussowitsch   PetscCall(PetscCommDestroy(&comm));
2879566063dSJacob Faibussowitsch   PetscCall(PetscSpinlockUnlock(&PetscViewerASCIISpinLockOpen));
2883ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2895c6c1daeSBarry Smith }
2905c6c1daeSBarry Smith 
2915c6c1daeSBarry Smith /*@C
2923f423023SBarry Smith   PetscViewerASCIIOpenWithFILE - Given an open file creates an `PETSCVIEWERASCII` viewer that prints to it.
2935c6c1daeSBarry Smith 
294d083f849SBarry Smith   Collective
2955c6c1daeSBarry Smith 
2965c6c1daeSBarry Smith   Input Parameters:
2975c6c1daeSBarry Smith + comm - the communicator
29820f4b53cSBarry Smith - fd   - the `FILE` pointer
2995c6c1daeSBarry Smith 
3005c6c1daeSBarry Smith   Output Parameter:
301811af0c4SBarry Smith . lab - the `PetscViewer` to use with the specified file
3025c6c1daeSBarry Smith 
3035c6c1daeSBarry Smith   Level: beginner
3045c6c1daeSBarry Smith 
3055c6c1daeSBarry Smith   Notes:
306811af0c4SBarry Smith   This `PetscViewer` can be destroyed with `PetscViewerDestroy()`, but the fd will NOT be closed.
3075c6c1daeSBarry Smith 
308811af0c4SBarry Smith   If a multiprocessor communicator is used (such as `PETSC_COMM_WORLD`),
3095c6c1daeSBarry Smith   then only the first processor in the group uses the file.  All other
3105c6c1daeSBarry Smith   processors send their data to the first processor to print.
3115c6c1daeSBarry Smith 
312aec76313SJacob Faibussowitsch   Fortran Notes:
313e4096674SBarry Smith   Use `PetscViewerASCIIOpenWithFileUnit()`
314e4096674SBarry Smith 
315e4096674SBarry Smith .seealso: [](sec_viewers), `MatView()`, `VecView()`, `PetscViewerDestroy()`, `PetscViewerBinaryOpen()`, `PetscViewerASCIIOpenWithFileUnit()`,
316db781477SPatrick Sanan           `PetscViewerASCIIGetPointer()`, `PetscViewerPushFormat()`, `PETSC_VIEWER_STDOUT_`, `PETSC_VIEWER_STDERR_`,
317811af0c4SBarry Smith           `PETSC_VIEWER_STDOUT_WORLD`, `PETSC_VIEWER_STDOUT_SELF`, `PetscViewerASCIIOpen()`, `PetscViewerASCIISetFILE()`, `PETSCVIEWERASCII`
3185c6c1daeSBarry Smith @*/
319d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIIOpenWithFILE(MPI_Comm comm, FILE *fd, PetscViewer *lab)
320d71ae5a4SJacob Faibussowitsch {
3215c6c1daeSBarry Smith   PetscFunctionBegin;
3229566063dSJacob Faibussowitsch   PetscCall(PetscViewerCreate(comm, lab));
3239566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetType(*lab, PETSCVIEWERASCII));
3249566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIISetFILE(*lab, fd));
3253ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3265c6c1daeSBarry Smith }
3275c6c1daeSBarry Smith 
328811af0c4SBarry Smith /*@C
3293f423023SBarry Smith   PetscViewerASCIISetFILE - Given an open file sets the `PETSCVIEWERASCII` viewer to use the file for output
330811af0c4SBarry Smith 
33120f4b53cSBarry Smith   Not Collective
332811af0c4SBarry Smith 
333811af0c4SBarry Smith   Input Parameters:
334811af0c4SBarry Smith + viewer - the `PetscViewer` to use with the specified file
33520f4b53cSBarry Smith - fd     - the `FILE` pointer
336811af0c4SBarry Smith 
337811af0c4SBarry Smith   Level: beginner
338811af0c4SBarry Smith 
339811af0c4SBarry Smith   Notes:
340c410d8ccSBarry Smith   This `PetscViewer` can be destroyed with `PetscViewerDestroy()`, but the `fd` will NOT be closed.
341811af0c4SBarry Smith 
342811af0c4SBarry Smith   If a multiprocessor communicator is used (such as `PETSC_COMM_WORLD`),
343811af0c4SBarry Smith   then only the first processor in the group uses the file.  All other
344811af0c4SBarry Smith   processors send their data to the first processor to print.
345811af0c4SBarry Smith 
346aec76313SJacob Faibussowitsch   Fortran Notes:
347e4096674SBarry Smith   Use `PetscViewerASCIISetFileUnit()`
348e4096674SBarry Smith 
349e4096674SBarry Smith .seealso: `MatView()`, `VecView()`, `PetscViewerDestroy()`, `PetscViewerBinaryOpen()`, `PetscViewerASCIISetFileUnit()`,
350811af0c4SBarry Smith           `PetscViewerASCIIGetPointer()`, `PetscViewerPushFormat()`, `PETSC_VIEWER_STDOUT_`, `PETSC_VIEWER_STDERR_`,
351811af0c4SBarry Smith           `PETSC_VIEWER_STDOUT_WORLD`, `PETSC_VIEWER_STDOUT_SELF`, `PetscViewerASCIIOpen()`, `PetscViewerASCIIOpenWithFILE()`, `PETSCVIEWERASCII`
352811af0c4SBarry Smith @*/
353d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIISetFILE(PetscViewer viewer, FILE *fd)
354d71ae5a4SJacob Faibussowitsch {
3555c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
3565c6c1daeSBarry Smith 
3575c6c1daeSBarry Smith   PetscFunctionBegin;
3585c6c1daeSBarry Smith   vascii->fd        = fd;
3595c6c1daeSBarry Smith   vascii->closefile = PETSC_FALSE;
3603ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3615c6c1daeSBarry Smith }
362