xref: /petsc/src/sys/classes/viewer/impls/ascii/vcreatea.c (revision feaf08ea36ffe4fb16da05e2fed575fa424e5b40)
1f5860696SSatish Balay #include <../src/sys/classes/viewer/impls/ascii/asciiimpl.h> /*I     "petscviewer.h"   I*/
25c6c1daeSBarry Smith 
3e2dcd6d3SBarry Smith /*
4e2dcd6d3SBarry Smith     The variable Petsc_Viewer_Stdout_keyval is used to indicate an MPI attribute that
5e2dcd6d3SBarry Smith   is attached to a communicator, in this case the attribute is a PetscViewer.
6e2dcd6d3SBarry Smith */
7d4c7638eSBarry Smith PetscMPIInt Petsc_Viewer_Stdout_keyval = MPI_KEYVAL_INVALID;
8e2dcd6d3SBarry Smith 
95c6c1daeSBarry Smith /*@C
10c410d8ccSBarry Smith    PETSC_VIEWER_STDOUT_ - Creates a `PETSCVIEWERASCII` `PetscViewer` shared by all MPI processes
115c6c1daeSBarry Smith                     in a communicator.
125c6c1daeSBarry Smith 
13d083f849SBarry Smith    Collective
145c6c1daeSBarry Smith 
155c6c1daeSBarry Smith    Input Parameter:
16811af0c4SBarry Smith .  comm - the MPI communicator to share the `PetscViewer`
175c6c1daeSBarry Smith 
185c6c1daeSBarry Smith    Level: beginner
195c6c1daeSBarry Smith 
2034fa283eSBarry Smith    Notes:
2134fa283eSBarry Smith    This object is destroyed in `PetscFinalize()`, `PetscViewerDestroy()` should never be called on it
2234fa283eSBarry Smith 
235c6c1daeSBarry Smith    Unlike almost all other PETSc routines, this does not return
245c6c1daeSBarry Smith    an error code. Usually used in the form
255c6c1daeSBarry Smith $      XXXView(XXX object, PETSC_VIEWER_STDOUT_(comm));
265c6c1daeSBarry Smith 
27d1f92df0SBarry Smith .seealso: [](sec_viewers), `PETSC_VIEWER_DRAW_()`, `PetscViewerASCIIOpen()`, `PETSC_VIEWER_STDERR_`, `PETSC_VIEWER_STDOUT_WORLD`,
28648c30bcSBarry Smith           `PETSC_VIEWER_STDOUT_SELF`, `PetscViewerASCIIGetStdout()`, `PetscViewerASCIIGetStderr()`
295c6c1daeSBarry Smith @*/
30d71ae5a4SJacob Faibussowitsch PetscViewer PETSC_VIEWER_STDOUT_(MPI_Comm comm)
31d71ae5a4SJacob Faibussowitsch {
325c6c1daeSBarry Smith   PetscViewer viewer;
335c6c1daeSBarry Smith 
345c6c1daeSBarry Smith   PetscFunctionBegin;
35648c30bcSBarry Smith   PetscCallNull(PetscViewerASCIIGetStdout(comm, &viewer));
365c6c1daeSBarry Smith   PetscFunctionReturn(viewer);
375c6c1daeSBarry Smith }
385c6c1daeSBarry Smith 
39e2dcd6d3SBarry Smith /*
40e2dcd6d3SBarry Smith     The variable Petsc_Viewer_Stderr_keyval is used to indicate an MPI attribute that
41e2dcd6d3SBarry Smith   is attached to a communicator, in this case the attribute is a PetscViewer.
42e2dcd6d3SBarry Smith */
43d4c7638eSBarry Smith PetscMPIInt Petsc_Viewer_Stderr_keyval = MPI_KEYVAL_INVALID;
44e2dcd6d3SBarry Smith 
459c5ded49SBarry Smith /*@
46c410d8ccSBarry Smith   PetscViewerASCIIGetStderr - Creates a `PETSCVIEWERASCII` `PetscViewer` shared by all MPI processes
47648c30bcSBarry Smith   in a communicator that prints to `stderr`. Error returning version of `PETSC_VIEWER_STDERR_()`
485c6c1daeSBarry Smith 
49d083f849SBarry Smith   Collective
505c6c1daeSBarry Smith 
515c6c1daeSBarry Smith   Input Parameter:
52811af0c4SBarry Smith . comm - the MPI communicator to share the `PetscViewer`
535c6c1daeSBarry Smith 
5410450e9eSJacob Faibussowitsch   Output Parameter:
5510450e9eSJacob Faibussowitsch . viewer - the viewer
5610450e9eSJacob Faibussowitsch 
575c6c1daeSBarry Smith   Level: beginner
585c6c1daeSBarry Smith 
59811af0c4SBarry Smith   Note:
60648c30bcSBarry Smith   Use `PetscViewerDestroy()` to destroy it
6134fa283eSBarry Smith 
6234fa283eSBarry Smith   Developer Note:
633f423023SBarry Smith   This should be used in all PETSc source code instead of `PETSC_VIEWER_STDERR_()` since it allows error checking
645c6c1daeSBarry Smith 
65648c30bcSBarry Smith .seealso: [](sec_viewers), `PetscViewerASCIIGetStdout()`, `PETSC_VIEWER_DRAW_()`, `PetscViewerASCIIOpen()`, `PETSC_VIEWER_STDERR_`, `PETSC_VIEWER_STDERR_WORLD`,
66db781477SPatrick Sanan           `PETSC_VIEWER_STDERR_SELF`
675c6c1daeSBarry Smith @*/
68d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIIGetStderr(MPI_Comm comm, PetscViewer *viewer)
69d71ae5a4SJacob Faibussowitsch {
70e2dcd6d3SBarry Smith   PetscBool flg;
71e2dcd6d3SBarry Smith   MPI_Comm  ncomm;
72e2dcd6d3SBarry Smith 
73e2dcd6d3SBarry Smith   PetscFunctionBegin;
749566063dSJacob Faibussowitsch   PetscCall(PetscSpinlockLock(&PetscViewerASCIISpinLockStderr));
759566063dSJacob Faibussowitsch   PetscCall(PetscCommDuplicate(comm, &ncomm, NULL));
7648a46eb9SPierre 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));
779566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_get_attr(ncomm, Petsc_Viewer_Stderr_keyval, (void **)viewer, (PetscMPIInt *)&flg));
78e2dcd6d3SBarry Smith   if (!flg) { /* PetscViewer not yet created */
79648c30bcSBarry Smith     PetscCall(PetscViewerCreate(ncomm, viewer));
80648c30bcSBarry Smith     PetscCall(PetscViewerSetType(*viewer, PETSCVIEWERASCII));
81648c30bcSBarry Smith     PetscCall(PetscViewerFileSetName(*viewer, "stderr"));
829566063dSJacob Faibussowitsch     PetscCall(PetscObjectRegisterDestroy((PetscObject)*viewer));
839566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_set_attr(ncomm, Petsc_Viewer_Stderr_keyval, (void *)*viewer));
84e2dcd6d3SBarry Smith   }
859566063dSJacob Faibussowitsch   PetscCall(PetscCommDestroy(&ncomm));
869566063dSJacob Faibussowitsch   PetscCall(PetscSpinlockUnlock(&PetscViewerASCIISpinLockStderr));
873ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
885c6c1daeSBarry Smith }
895c6c1daeSBarry Smith 
905c6c1daeSBarry Smith /*@C
91c410d8ccSBarry Smith    PETSC_VIEWER_STDERR_ - Creates a `PETSCVIEWERASCII` `PetscViewer` shared by all MPI processes
925c6c1daeSBarry Smith                     in a communicator.
935c6c1daeSBarry Smith 
94d083f849SBarry Smith    Collective
955c6c1daeSBarry Smith 
965c6c1daeSBarry Smith    Input Parameter:
97811af0c4SBarry Smith .  comm - the MPI communicator to share the `PetscViewer`
985c6c1daeSBarry Smith 
995c6c1daeSBarry Smith    Level: beginner
1005c6c1daeSBarry Smith 
1013f423023SBarry Smith    Notes:
10234fa283eSBarry Smith    This object is destroyed in `PetscFinalize()`, `PetscViewerDestroy()` should never be called on it
10334fa283eSBarry Smith 
1045c6c1daeSBarry Smith    Unlike almost all other PETSc routines, this does not return
1055c6c1daeSBarry Smith    an error code. Usually used in the form
1065c6c1daeSBarry Smith $      XXXView(XXX object, PETSC_VIEWER_STDERR_(comm));
1075c6c1daeSBarry Smith 
1083f423023SBarry Smith    `PetscViewerASCIIGetStderr()` is preferred  since it allows error checking
1093f423023SBarry Smith 
110d1f92df0SBarry Smith .seealso: [](sec_viewers), `PETSC_VIEWER_DRAW_`, `PetscViewerASCIIOpen()`, `PETSC_VIEWER_STDOUT_`, `PETSC_VIEWER_STDOUT_WORLD`,
111db781477SPatrick Sanan           `PETSC_VIEWER_STDOUT_SELF`, `PETSC_VIEWER_STDERR_WORLD`, `PETSC_VIEWER_STDERR_SELF`
1125c6c1daeSBarry Smith @*/
113d71ae5a4SJacob Faibussowitsch PetscViewer PETSC_VIEWER_STDERR_(MPI_Comm comm)
114d71ae5a4SJacob Faibussowitsch {
1155c6c1daeSBarry Smith   PetscViewer viewer;
1165c6c1daeSBarry Smith 
1175c6c1daeSBarry Smith   PetscFunctionBegin;
118648c30bcSBarry Smith   PetscCallNull(PetscViewerASCIIGetStderr(comm, &viewer));
1195c6c1daeSBarry Smith   PetscFunctionReturn(viewer);
1205c6c1daeSBarry Smith }
1215c6c1daeSBarry Smith 
1225c6c1daeSBarry Smith PetscMPIInt Petsc_Viewer_keyval = MPI_KEYVAL_INVALID;
1235c6c1daeSBarry Smith /*
1243f423023SBarry Smith    Called with MPI_Comm_free() is called on a communicator that has a viewer as an attribute. The viewer is not actually destroyed
1253f423023SBarry Smith    because that is managed by PetscObjectDestroyRegisterAll(). PetscViewerASCIIGetStdout() registers the viewer with PetscObjectDestroyRegister() to be destroyed when PetscFinalize() is called.
1265c6c1daeSBarry Smith 
1275c6c1daeSBarry Smith   This is called by MPI, not by users.
1285c6c1daeSBarry Smith 
1295c6c1daeSBarry Smith */
13034e79e72SJacob Faibussowitsch PetscMPIInt MPIAPI Petsc_DelViewer(MPI_Comm comm, PetscMPIInt keyval, void *attr_val, void *extra_state)
131d71ae5a4SJacob Faibussowitsch {
1325c6c1daeSBarry Smith   PetscFunctionBegin;
13334e79e72SJacob Faibussowitsch   (void)keyval;
13434e79e72SJacob Faibussowitsch   (void)attr_val;
13534e79e72SJacob Faibussowitsch   (void)extra_state;
1367c5b2466SBarry Smith   PetscCallReturnMPI(PetscInfo(NULL, "Removing viewer data attribute in an MPI_Comm %" PETSC_INTPTR_T_FMT "\n", (PETSC_INTPTR_T)comm));
1375c6c1daeSBarry Smith   PetscFunctionReturn(MPI_SUCCESS);
1385c6c1daeSBarry Smith }
1395c6c1daeSBarry Smith 
140cc4c1da9SBarry Smith /*@
141c410d8ccSBarry Smith   PetscViewerASCIIOpen - Opens an ASCII file for writing as a `PETSCVIEWERASCII` `PetscViewer`.
1425c6c1daeSBarry Smith 
143d083f849SBarry Smith   Collective
1445c6c1daeSBarry Smith 
1455c6c1daeSBarry Smith   Input Parameters:
1465c6c1daeSBarry Smith + comm - the communicator
1475c6c1daeSBarry Smith - name - the file name
1485c6c1daeSBarry Smith 
1495c6c1daeSBarry Smith   Output Parameter:
150377f809aSBarry Smith . viewer - the `PetscViewer` to use with the specified file
1515c6c1daeSBarry Smith 
1525c6c1daeSBarry Smith   Level: beginner
1535c6c1daeSBarry Smith 
1545c6c1daeSBarry Smith   Notes:
155648c30bcSBarry Smith   This routine only opens files for writing. To open a ASCII file as a `PetscViewer` for reading use the sequence
156811af0c4SBarry Smith .vb
157377f809aSBarry Smith    PetscViewerCreate(comm,&viewer);
158377f809aSBarry Smith    PetscViewerSetType(viewer,PETSCVIEWERASCII);
159377f809aSBarry Smith    PetscViewerFileSetMode(viewer,FILE_MODE_READ);
160377f809aSBarry Smith    PetscViewerFileSetName(viewer,name);
161811af0c4SBarry Smith .ve
162f8859db6SBarry Smith 
163811af0c4SBarry Smith   This `PetscViewer` can be destroyed with `PetscViewerDestroy()`.
1645c6c1daeSBarry Smith 
165648c30bcSBarry Smith   The MPI communicator used here must match that used by the object viewed. For example if the
166648c30bcSBarry Smith   Mat was created with a `PETSC_COMM_WORLD`, then `viewer` must be created with `PETSC_COMM_WORLD`
1675c6c1daeSBarry Smith 
168811af0c4SBarry Smith   As shown below, `PetscViewerASCIIOpen()` is useful in conjunction with
169811af0c4SBarry Smith   `MatView()` and `VecView()`
1705c6c1daeSBarry Smith .vb
1715c6c1daeSBarry Smith      PetscViewerASCIIOpen(PETSC_COMM_WORLD,"mat.output",&viewer);
1725c6c1daeSBarry Smith      MatView(matrix,viewer);
1735c6c1daeSBarry Smith .ve
1745c6c1daeSBarry Smith 
175648c30bcSBarry Smith   Developer Note:
176648c30bcSBarry Smith   When called with `NULL`, `stdout`, or `stderr` this does not return the same communicator as `PetscViewerASCIIGetStdout()` or `PetscViewerASCIIGetStderr()`
177648c30bcSBarry Smith   but that is ok.
178648c30bcSBarry Smith 
179d1f92df0SBarry Smith .seealso: [](sec_viewers), `MatView()`, `VecView()`, `PetscViewerDestroy()`, `PetscViewerBinaryOpen()`, `PetscViewerASCIIRead()`, `PETSCVIEWERASCII`
180db781477SPatrick Sanan           `PetscViewerASCIIGetPointer()`, `PetscViewerPushFormat()`, `PETSC_VIEWER_STDOUT_`, `PETSC_VIEWER_STDERR_`,
181648c30bcSBarry Smith           `PETSC_VIEWER_STDOUT_WORLD`, `PETSC_VIEWER_STDOUT_SELF`, `PetscViewerASCIIGetStdout()`, `PetscViewerASCIIGetStderr()`
1825c6c1daeSBarry Smith @*/
183377f809aSBarry Smith PetscErrorCode PetscViewerASCIIOpen(MPI_Comm comm, const char name[], PetscViewer *viewer)
184d71ae5a4SJacob Faibussowitsch {
1855c6c1daeSBarry Smith   PetscViewerLink *vlink, *nv;
1865c6c1daeSBarry Smith   PetscBool        flg, eq;
1875c6c1daeSBarry Smith   size_t           len;
1885c6c1daeSBarry Smith 
1895c6c1daeSBarry Smith   PetscFunctionBegin;
190377f809aSBarry Smith   PetscAssertPointer(viewer, 3);
1919566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(name, &len));
192648c30bcSBarry Smith   if (!len) name = "stdout";
1939566063dSJacob Faibussowitsch   PetscCall(PetscSpinlockLock(&PetscViewerASCIISpinLockOpen));
194c8025a54SPierre Jolivet   if (Petsc_Viewer_keyval == MPI_KEYVAL_INVALID) PetscCallMPI(MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN, Petsc_DelViewer, &Petsc_Viewer_keyval, NULL));
1952bf49c77SBarry Smith   /*
1962bf49c77SBarry Smith        It would be better to move this code to PetscFileSetName() but since it must return a preexiting communicator
1972bf49c77SBarry Smith      we cannot do that, since PetscFileSetName() takes a communicator that already exists.
1982bf49c77SBarry Smith 
1992bf49c77SBarry Smith       Plus if the original communicator that created the file has since been close this will not detect the old
2002bf49c77SBarry Smith       communictor and hence will overwrite the old data. It may be better to simply remove all this code
2012bf49c77SBarry Smith   */
2025c6c1daeSBarry Smith   /* make sure communicator is a PETSc communicator */
2039566063dSJacob Faibussowitsch   PetscCall(PetscCommDuplicate(comm, &comm, NULL));
2045c6c1daeSBarry Smith   /* has file already been opened into a viewer */
2059566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_get_attr(comm, Petsc_Viewer_keyval, (void **)&vlink, (PetscMPIInt *)&flg));
2065c6c1daeSBarry Smith   if (flg) {
2075c6c1daeSBarry Smith     while (vlink) {
208f4f49eeaSPierre Jolivet       PetscCall(PetscStrcmp(name, ((PetscViewer_ASCII *)vlink->viewer->data)->filename, &eq));
2095c6c1daeSBarry Smith       if (eq) {
2109566063dSJacob Faibussowitsch         PetscCall(PetscObjectReference((PetscObject)vlink->viewer));
211377f809aSBarry Smith         *viewer = vlink->viewer;
2129566063dSJacob Faibussowitsch         PetscCall(PetscCommDestroy(&comm));
2139566063dSJacob Faibussowitsch         PetscCall(PetscSpinlockUnlock(&PetscViewerASCIISpinLockOpen));
2143ba16761SJacob Faibussowitsch         PetscFunctionReturn(PETSC_SUCCESS);
2155c6c1daeSBarry Smith       }
2165c6c1daeSBarry Smith       vlink = vlink->next;
2175c6c1daeSBarry Smith     }
2185c6c1daeSBarry Smith   }
219377f809aSBarry Smith   PetscCall(PetscViewerCreate(comm, viewer));
220377f809aSBarry Smith   PetscCall(PetscViewerSetType(*viewer, PETSCVIEWERASCII));
221648c30bcSBarry Smith   PetscCall(PetscViewerFileSetName(*viewer, name));
2225c6c1daeSBarry Smith   /* save viewer into communicator if needed later */
2239566063dSJacob Faibussowitsch   PetscCall(PetscNew(&nv));
224377f809aSBarry Smith   nv->viewer = *viewer;
2255c6c1daeSBarry Smith   if (!flg) {
2269566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_set_attr(comm, Petsc_Viewer_keyval, nv));
2275c6c1daeSBarry Smith   } else {
2289566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_get_attr(comm, Petsc_Viewer_keyval, (void **)&vlink, (PetscMPIInt *)&flg));
2295c6c1daeSBarry Smith     if (vlink) {
2305c6c1daeSBarry Smith       while (vlink->next) vlink = vlink->next;
2315c6c1daeSBarry Smith       vlink->next = nv;
2325c6c1daeSBarry Smith     } else {
2339566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Comm_set_attr(comm, Petsc_Viewer_keyval, nv));
2345c6c1daeSBarry Smith     }
2355c6c1daeSBarry Smith   }
2369566063dSJacob Faibussowitsch   PetscCall(PetscCommDestroy(&comm));
2379566063dSJacob Faibussowitsch   PetscCall(PetscSpinlockUnlock(&PetscViewerASCIISpinLockOpen));
2383ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2395c6c1daeSBarry Smith }
2405c6c1daeSBarry Smith 
2415c6c1daeSBarry Smith /*@C
2423f423023SBarry Smith   PetscViewerASCIIOpenWithFILE - Given an open file creates an `PETSCVIEWERASCII` viewer that prints to it.
2435c6c1daeSBarry Smith 
244d083f849SBarry Smith   Collective
2455c6c1daeSBarry Smith 
2465c6c1daeSBarry Smith   Input Parameters:
2475c6c1daeSBarry Smith + comm - the communicator
24820f4b53cSBarry Smith - fd   - the `FILE` pointer
2495c6c1daeSBarry Smith 
2505c6c1daeSBarry Smith   Output Parameter:
251377f809aSBarry Smith . viewer - the `PetscViewer` to use with the specified file
2525c6c1daeSBarry Smith 
2535c6c1daeSBarry Smith   Level: beginner
2545c6c1daeSBarry Smith 
2555c6c1daeSBarry Smith   Notes:
256811af0c4SBarry Smith   This `PetscViewer` can be destroyed with `PetscViewerDestroy()`, but the fd will NOT be closed.
2575c6c1daeSBarry Smith 
258811af0c4SBarry Smith   If a multiprocessor communicator is used (such as `PETSC_COMM_WORLD`),
2595c6c1daeSBarry Smith   then only the first processor in the group uses the file.  All other
2605c6c1daeSBarry Smith   processors send their data to the first processor to print.
2615c6c1daeSBarry Smith 
262aec76313SJacob Faibussowitsch   Fortran Notes:
263e4096674SBarry Smith   Use `PetscViewerASCIIOpenWithFileUnit()`
264e4096674SBarry Smith 
265e4096674SBarry Smith .seealso: [](sec_viewers), `MatView()`, `VecView()`, `PetscViewerDestroy()`, `PetscViewerBinaryOpen()`, `PetscViewerASCIIOpenWithFileUnit()`,
266db781477SPatrick Sanan           `PetscViewerASCIIGetPointer()`, `PetscViewerPushFormat()`, `PETSC_VIEWER_STDOUT_`, `PETSC_VIEWER_STDERR_`,
267811af0c4SBarry Smith           `PETSC_VIEWER_STDOUT_WORLD`, `PETSC_VIEWER_STDOUT_SELF`, `PetscViewerASCIIOpen()`, `PetscViewerASCIISetFILE()`, `PETSCVIEWERASCII`
2685c6c1daeSBarry Smith @*/
269377f809aSBarry Smith PetscErrorCode PetscViewerASCIIOpenWithFILE(MPI_Comm comm, FILE *fd, PetscViewer *viewer)
270d71ae5a4SJacob Faibussowitsch {
2715c6c1daeSBarry Smith   PetscFunctionBegin;
272377f809aSBarry Smith   PetscCall(PetscViewerCreate(comm, viewer));
273377f809aSBarry Smith   PetscCall(PetscViewerSetType(*viewer, PETSCVIEWERASCII));
274377f809aSBarry Smith   PetscCall(PetscViewerASCIISetFILE(*viewer, fd));
2753ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2765c6c1daeSBarry Smith }
2775c6c1daeSBarry Smith 
278811af0c4SBarry Smith /*@C
2793f423023SBarry Smith   PetscViewerASCIISetFILE - Given an open file sets the `PETSCVIEWERASCII` viewer to use the file for output
280811af0c4SBarry Smith 
28120f4b53cSBarry Smith   Not Collective
282811af0c4SBarry Smith 
283811af0c4SBarry Smith   Input Parameters:
284811af0c4SBarry Smith + viewer - the `PetscViewer` to use with the specified file
28520f4b53cSBarry Smith - fd     - the `FILE` pointer
286811af0c4SBarry Smith 
287811af0c4SBarry Smith   Level: beginner
288811af0c4SBarry Smith 
289811af0c4SBarry Smith   Notes:
290c410d8ccSBarry Smith   This `PetscViewer` can be destroyed with `PetscViewerDestroy()`, but the `fd` will NOT be closed.
291811af0c4SBarry Smith 
292811af0c4SBarry Smith   If a multiprocessor communicator is used (such as `PETSC_COMM_WORLD`),
293811af0c4SBarry Smith   then only the first processor in the group uses the file.  All other
294811af0c4SBarry Smith   processors send their data to the first processor to print.
295811af0c4SBarry Smith 
296*feaf08eaSBarry Smith   Fortran Note:
297e4096674SBarry Smith   Use `PetscViewerASCIISetFileUnit()`
298e4096674SBarry Smith 
299e4096674SBarry Smith .seealso: `MatView()`, `VecView()`, `PetscViewerDestroy()`, `PetscViewerBinaryOpen()`, `PetscViewerASCIISetFileUnit()`,
300811af0c4SBarry Smith           `PetscViewerASCIIGetPointer()`, `PetscViewerPushFormat()`, `PETSC_VIEWER_STDOUT_`, `PETSC_VIEWER_STDERR_`,
301811af0c4SBarry Smith           `PETSC_VIEWER_STDOUT_WORLD`, `PETSC_VIEWER_STDOUT_SELF`, `PetscViewerASCIIOpen()`, `PetscViewerASCIIOpenWithFILE()`, `PETSCVIEWERASCII`
302811af0c4SBarry Smith @*/
303d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIISetFILE(PetscViewer viewer, FILE *fd)
304d71ae5a4SJacob Faibussowitsch {
3055c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
3065c6c1daeSBarry Smith 
3075c6c1daeSBarry Smith   PetscFunctionBegin;
3085c6c1daeSBarry Smith   vascii->fd        = fd;
3095c6c1daeSBarry Smith   vascii->closefile = PETSC_FALSE;
3103ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3115c6c1daeSBarry Smith }
312