xref: /petsc/src/sys/classes/viewer/impls/ascii/vcreatea.c (revision b44f4de476a10dd52a698c0f9a8f47d015bd1e19)
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
25*b44f4de4SBarry Smith .vb
26*b44f4de4SBarry Smith   XXXView(XXX object, PETSC_VIEWER_STDOUT_(comm));
27*b44f4de4SBarry Smith .ve
285c6c1daeSBarry Smith 
29d1f92df0SBarry Smith .seealso: [](sec_viewers), `PETSC_VIEWER_DRAW_()`, `PetscViewerASCIIOpen()`, `PETSC_VIEWER_STDERR_`, `PETSC_VIEWER_STDOUT_WORLD`,
30648c30bcSBarry Smith           `PETSC_VIEWER_STDOUT_SELF`, `PetscViewerASCIIGetStdout()`, `PetscViewerASCIIGetStderr()`
315c6c1daeSBarry Smith @*/
32d71ae5a4SJacob Faibussowitsch PetscViewer PETSC_VIEWER_STDOUT_(MPI_Comm comm)
33d71ae5a4SJacob Faibussowitsch {
345c6c1daeSBarry Smith   PetscViewer viewer;
355c6c1daeSBarry Smith 
365c6c1daeSBarry Smith   PetscFunctionBegin;
37648c30bcSBarry Smith   PetscCallNull(PetscViewerASCIIGetStdout(comm, &viewer));
385c6c1daeSBarry Smith   PetscFunctionReturn(viewer);
395c6c1daeSBarry Smith }
405c6c1daeSBarry Smith 
41e2dcd6d3SBarry Smith /*
42e2dcd6d3SBarry Smith     The variable Petsc_Viewer_Stderr_keyval is used to indicate an MPI attribute that
43e2dcd6d3SBarry Smith   is attached to a communicator, in this case the attribute is a PetscViewer.
44e2dcd6d3SBarry Smith */
45d4c7638eSBarry Smith PetscMPIInt Petsc_Viewer_Stderr_keyval = MPI_KEYVAL_INVALID;
46e2dcd6d3SBarry Smith 
479c5ded49SBarry Smith /*@
48c410d8ccSBarry Smith   PetscViewerASCIIGetStderr - Creates a `PETSCVIEWERASCII` `PetscViewer` shared by all MPI processes
49648c30bcSBarry Smith   in a communicator that prints to `stderr`. Error returning version of `PETSC_VIEWER_STDERR_()`
505c6c1daeSBarry Smith 
51d083f849SBarry Smith   Collective
525c6c1daeSBarry Smith 
535c6c1daeSBarry Smith   Input Parameter:
54811af0c4SBarry Smith . comm - the MPI communicator to share the `PetscViewer`
555c6c1daeSBarry Smith 
5610450e9eSJacob Faibussowitsch   Output Parameter:
5710450e9eSJacob Faibussowitsch . viewer - the viewer
5810450e9eSJacob Faibussowitsch 
595c6c1daeSBarry Smith   Level: beginner
605c6c1daeSBarry Smith 
61811af0c4SBarry Smith   Note:
62648c30bcSBarry Smith   Use `PetscViewerDestroy()` to destroy it
6334fa283eSBarry Smith 
6434fa283eSBarry Smith   Developer Note:
653f423023SBarry Smith   This should be used in all PETSc source code instead of `PETSC_VIEWER_STDERR_()` since it allows error checking
665c6c1daeSBarry Smith 
67648c30bcSBarry Smith .seealso: [](sec_viewers), `PetscViewerASCIIGetStdout()`, `PETSC_VIEWER_DRAW_()`, `PetscViewerASCIIOpen()`, `PETSC_VIEWER_STDERR_`, `PETSC_VIEWER_STDERR_WORLD`,
68db781477SPatrick Sanan           `PETSC_VIEWER_STDERR_SELF`
695c6c1daeSBarry Smith @*/
70d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIIGetStderr(MPI_Comm comm, PetscViewer *viewer)
71d71ae5a4SJacob Faibussowitsch {
72e2dcd6d3SBarry Smith   PetscBool flg;
73e2dcd6d3SBarry Smith   MPI_Comm  ncomm;
74e2dcd6d3SBarry Smith 
75e2dcd6d3SBarry Smith   PetscFunctionBegin;
769566063dSJacob Faibussowitsch   PetscCall(PetscSpinlockLock(&PetscViewerASCIISpinLockStderr));
779566063dSJacob Faibussowitsch   PetscCall(PetscCommDuplicate(comm, &ncomm, NULL));
7848a46eb9SPierre 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));
799566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_get_attr(ncomm, Petsc_Viewer_Stderr_keyval, (void **)viewer, (PetscMPIInt *)&flg));
80e2dcd6d3SBarry Smith   if (!flg) { /* PetscViewer not yet created */
81648c30bcSBarry Smith     PetscCall(PetscViewerCreate(ncomm, viewer));
82648c30bcSBarry Smith     PetscCall(PetscViewerSetType(*viewer, PETSCVIEWERASCII));
83648c30bcSBarry Smith     PetscCall(PetscViewerFileSetName(*viewer, "stderr"));
849566063dSJacob Faibussowitsch     PetscCall(PetscObjectRegisterDestroy((PetscObject)*viewer));
859566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_set_attr(ncomm, Petsc_Viewer_Stderr_keyval, (void *)*viewer));
86e2dcd6d3SBarry Smith   }
879566063dSJacob Faibussowitsch   PetscCall(PetscCommDestroy(&ncomm));
889566063dSJacob Faibussowitsch   PetscCall(PetscSpinlockUnlock(&PetscViewerASCIISpinLockStderr));
893ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
905c6c1daeSBarry Smith }
915c6c1daeSBarry Smith 
925c6c1daeSBarry Smith /*@C
93c410d8ccSBarry Smith    PETSC_VIEWER_STDERR_ - Creates a `PETSCVIEWERASCII` `PetscViewer` shared by all MPI processes
945c6c1daeSBarry Smith                     in a communicator.
955c6c1daeSBarry Smith 
96d083f849SBarry Smith    Collective
975c6c1daeSBarry Smith 
985c6c1daeSBarry Smith    Input Parameter:
99811af0c4SBarry Smith .  comm - the MPI communicator to share the `PetscViewer`
1005c6c1daeSBarry Smith 
1015c6c1daeSBarry Smith    Level: beginner
1025c6c1daeSBarry Smith 
1033f423023SBarry Smith    Notes:
10434fa283eSBarry Smith    This object is destroyed in `PetscFinalize()`, `PetscViewerDestroy()` should never be called on it
10534fa283eSBarry Smith 
1065c6c1daeSBarry Smith    Unlike almost all other PETSc routines, this does not return
1075c6c1daeSBarry Smith    an error code. Usually used in the form
1085c6c1daeSBarry Smith $      XXXView(XXX object, PETSC_VIEWER_STDERR_(comm));
1095c6c1daeSBarry Smith 
1103f423023SBarry Smith    `PetscViewerASCIIGetStderr()` is preferred  since it allows error checking
1113f423023SBarry Smith 
112d1f92df0SBarry Smith .seealso: [](sec_viewers), `PETSC_VIEWER_DRAW_`, `PetscViewerASCIIOpen()`, `PETSC_VIEWER_STDOUT_`, `PETSC_VIEWER_STDOUT_WORLD`,
113db781477SPatrick Sanan           `PETSC_VIEWER_STDOUT_SELF`, `PETSC_VIEWER_STDERR_WORLD`, `PETSC_VIEWER_STDERR_SELF`
1145c6c1daeSBarry Smith @*/
115d71ae5a4SJacob Faibussowitsch PetscViewer PETSC_VIEWER_STDERR_(MPI_Comm comm)
116d71ae5a4SJacob Faibussowitsch {
1175c6c1daeSBarry Smith   PetscViewer viewer;
1185c6c1daeSBarry Smith 
1195c6c1daeSBarry Smith   PetscFunctionBegin;
120648c30bcSBarry Smith   PetscCallNull(PetscViewerASCIIGetStderr(comm, &viewer));
1215c6c1daeSBarry Smith   PetscFunctionReturn(viewer);
1225c6c1daeSBarry Smith }
1235c6c1daeSBarry Smith 
1245c6c1daeSBarry Smith PetscMPIInt Petsc_Viewer_keyval = MPI_KEYVAL_INVALID;
1255c6c1daeSBarry Smith /*
1263f423023SBarry Smith    Called with MPI_Comm_free() is called on a communicator that has a viewer as an attribute. The viewer is not actually destroyed
1273f423023SBarry Smith    because that is managed by PetscObjectDestroyRegisterAll(). PetscViewerASCIIGetStdout() registers the viewer with PetscObjectDestroyRegister() to be destroyed when PetscFinalize() is called.
1285c6c1daeSBarry Smith 
1295c6c1daeSBarry Smith   This is called by MPI, not by users.
1305c6c1daeSBarry Smith 
1315c6c1daeSBarry Smith */
13234e79e72SJacob Faibussowitsch PetscMPIInt MPIAPI Petsc_DelViewer(MPI_Comm comm, PetscMPIInt keyval, void *attr_val, void *extra_state)
133d71ae5a4SJacob Faibussowitsch {
1345c6c1daeSBarry Smith   PetscFunctionBegin;
13534e79e72SJacob Faibussowitsch   (void)keyval;
13634e79e72SJacob Faibussowitsch   (void)attr_val;
13734e79e72SJacob Faibussowitsch   (void)extra_state;
1387c5b2466SBarry Smith   PetscCallReturnMPI(PetscInfo(NULL, "Removing viewer data attribute in an MPI_Comm %" PETSC_INTPTR_T_FMT "\n", (PETSC_INTPTR_T)comm));
1395c6c1daeSBarry Smith   PetscFunctionReturn(MPI_SUCCESS);
1405c6c1daeSBarry Smith }
1415c6c1daeSBarry Smith 
142cc4c1da9SBarry Smith /*@
143c410d8ccSBarry Smith   PetscViewerASCIIOpen - Opens an ASCII file for writing as a `PETSCVIEWERASCII` `PetscViewer`.
1445c6c1daeSBarry Smith 
145d083f849SBarry Smith   Collective
1465c6c1daeSBarry Smith 
1475c6c1daeSBarry Smith   Input Parameters:
1485c6c1daeSBarry Smith + comm - the communicator
1495c6c1daeSBarry Smith - name - the file name
1505c6c1daeSBarry Smith 
1515c6c1daeSBarry Smith   Output Parameter:
152377f809aSBarry Smith . viewer - the `PetscViewer` to use with the specified file
1535c6c1daeSBarry Smith 
1545c6c1daeSBarry Smith   Level: beginner
1555c6c1daeSBarry Smith 
1565c6c1daeSBarry Smith   Notes:
157648c30bcSBarry Smith   This routine only opens files for writing. To open a ASCII file as a `PetscViewer` for reading use the sequence
158811af0c4SBarry Smith .vb
159377f809aSBarry Smith    PetscViewerCreate(comm,&viewer);
160377f809aSBarry Smith    PetscViewerSetType(viewer,PETSCVIEWERASCII);
161377f809aSBarry Smith    PetscViewerFileSetMode(viewer,FILE_MODE_READ);
162377f809aSBarry Smith    PetscViewerFileSetName(viewer,name);
163811af0c4SBarry Smith .ve
164f8859db6SBarry Smith 
165811af0c4SBarry Smith   This `PetscViewer` can be destroyed with `PetscViewerDestroy()`.
1665c6c1daeSBarry Smith 
167648c30bcSBarry Smith   The MPI communicator used here must match that used by the object viewed. For example if the
168648c30bcSBarry Smith   Mat was created with a `PETSC_COMM_WORLD`, then `viewer` must be created with `PETSC_COMM_WORLD`
1695c6c1daeSBarry Smith 
170811af0c4SBarry Smith   As shown below, `PetscViewerASCIIOpen()` is useful in conjunction with
171811af0c4SBarry Smith   `MatView()` and `VecView()`
1725c6c1daeSBarry Smith .vb
1735c6c1daeSBarry Smith      PetscViewerASCIIOpen(PETSC_COMM_WORLD,"mat.output",&viewer);
1745c6c1daeSBarry Smith      MatView(matrix,viewer);
1755c6c1daeSBarry Smith .ve
1765c6c1daeSBarry Smith 
177648c30bcSBarry Smith   Developer Note:
178648c30bcSBarry Smith   When called with `NULL`, `stdout`, or `stderr` this does not return the same communicator as `PetscViewerASCIIGetStdout()` or `PetscViewerASCIIGetStderr()`
179648c30bcSBarry Smith   but that is ok.
180648c30bcSBarry Smith 
181d1f92df0SBarry Smith .seealso: [](sec_viewers), `MatView()`, `VecView()`, `PetscViewerDestroy()`, `PetscViewerBinaryOpen()`, `PetscViewerASCIIRead()`, `PETSCVIEWERASCII`
182db781477SPatrick Sanan           `PetscViewerASCIIGetPointer()`, `PetscViewerPushFormat()`, `PETSC_VIEWER_STDOUT_`, `PETSC_VIEWER_STDERR_`,
183648c30bcSBarry Smith           `PETSC_VIEWER_STDOUT_WORLD`, `PETSC_VIEWER_STDOUT_SELF`, `PetscViewerASCIIGetStdout()`, `PetscViewerASCIIGetStderr()`
1845c6c1daeSBarry Smith @*/
185377f809aSBarry Smith PetscErrorCode PetscViewerASCIIOpen(MPI_Comm comm, const char name[], PetscViewer *viewer)
186d71ae5a4SJacob Faibussowitsch {
1875c6c1daeSBarry Smith   PetscViewerLink *vlink, *nv;
1885c6c1daeSBarry Smith   PetscBool        flg, eq;
1895c6c1daeSBarry Smith   size_t           len;
1905c6c1daeSBarry Smith 
1915c6c1daeSBarry Smith   PetscFunctionBegin;
192377f809aSBarry Smith   PetscAssertPointer(viewer, 3);
1939566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(name, &len));
194648c30bcSBarry Smith   if (!len) name = "stdout";
1959566063dSJacob Faibussowitsch   PetscCall(PetscSpinlockLock(&PetscViewerASCIISpinLockOpen));
196c8025a54SPierre Jolivet   if (Petsc_Viewer_keyval == MPI_KEYVAL_INVALID) PetscCallMPI(MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN, Petsc_DelViewer, &Petsc_Viewer_keyval, NULL));
1972bf49c77SBarry Smith   /*
1982bf49c77SBarry Smith        It would be better to move this code to PetscFileSetName() but since it must return a preexiting communicator
1992bf49c77SBarry Smith      we cannot do that, since PetscFileSetName() takes a communicator that already exists.
2002bf49c77SBarry Smith 
2012bf49c77SBarry Smith       Plus if the original communicator that created the file has since been close this will not detect the old
2022bf49c77SBarry Smith       communictor and hence will overwrite the old data. It may be better to simply remove all this code
2032bf49c77SBarry Smith   */
2045c6c1daeSBarry Smith   /* make sure communicator is a PETSc communicator */
2059566063dSJacob Faibussowitsch   PetscCall(PetscCommDuplicate(comm, &comm, NULL));
2065c6c1daeSBarry Smith   /* has file already been opened into a viewer */
2079566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_get_attr(comm, Petsc_Viewer_keyval, (void **)&vlink, (PetscMPIInt *)&flg));
2085c6c1daeSBarry Smith   if (flg) {
2095c6c1daeSBarry Smith     while (vlink) {
210f4f49eeaSPierre Jolivet       PetscCall(PetscStrcmp(name, ((PetscViewer_ASCII *)vlink->viewer->data)->filename, &eq));
2115c6c1daeSBarry Smith       if (eq) {
2129566063dSJacob Faibussowitsch         PetscCall(PetscObjectReference((PetscObject)vlink->viewer));
213377f809aSBarry Smith         *viewer = vlink->viewer;
2149566063dSJacob Faibussowitsch         PetscCall(PetscCommDestroy(&comm));
2159566063dSJacob Faibussowitsch         PetscCall(PetscSpinlockUnlock(&PetscViewerASCIISpinLockOpen));
2163ba16761SJacob Faibussowitsch         PetscFunctionReturn(PETSC_SUCCESS);
2175c6c1daeSBarry Smith       }
2185c6c1daeSBarry Smith       vlink = vlink->next;
2195c6c1daeSBarry Smith     }
2205c6c1daeSBarry Smith   }
221377f809aSBarry Smith   PetscCall(PetscViewerCreate(comm, viewer));
222377f809aSBarry Smith   PetscCall(PetscViewerSetType(*viewer, PETSCVIEWERASCII));
223648c30bcSBarry Smith   PetscCall(PetscViewerFileSetName(*viewer, name));
2245c6c1daeSBarry Smith   /* save viewer into communicator if needed later */
2259566063dSJacob Faibussowitsch   PetscCall(PetscNew(&nv));
226377f809aSBarry Smith   nv->viewer = *viewer;
2275c6c1daeSBarry Smith   if (!flg) {
2289566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_set_attr(comm, Petsc_Viewer_keyval, nv));
2295c6c1daeSBarry Smith   } else {
2309566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_get_attr(comm, Petsc_Viewer_keyval, (void **)&vlink, (PetscMPIInt *)&flg));
2315c6c1daeSBarry Smith     if (vlink) {
2325c6c1daeSBarry Smith       while (vlink->next) vlink = vlink->next;
2335c6c1daeSBarry Smith       vlink->next = nv;
2345c6c1daeSBarry Smith     } else {
2359566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Comm_set_attr(comm, Petsc_Viewer_keyval, nv));
2365c6c1daeSBarry Smith     }
2375c6c1daeSBarry Smith   }
2389566063dSJacob Faibussowitsch   PetscCall(PetscCommDestroy(&comm));
2399566063dSJacob Faibussowitsch   PetscCall(PetscSpinlockUnlock(&PetscViewerASCIISpinLockOpen));
2403ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2415c6c1daeSBarry Smith }
2425c6c1daeSBarry Smith 
2435c6c1daeSBarry Smith /*@C
2443f423023SBarry Smith   PetscViewerASCIIOpenWithFILE - Given an open file creates an `PETSCVIEWERASCII` viewer that prints to it.
2455c6c1daeSBarry Smith 
246d083f849SBarry Smith   Collective
2475c6c1daeSBarry Smith 
2485c6c1daeSBarry Smith   Input Parameters:
2495c6c1daeSBarry Smith + comm - the communicator
25020f4b53cSBarry Smith - fd   - the `FILE` pointer
2515c6c1daeSBarry Smith 
2525c6c1daeSBarry Smith   Output Parameter:
253377f809aSBarry Smith . viewer - the `PetscViewer` to use with the specified file
2545c6c1daeSBarry Smith 
2555c6c1daeSBarry Smith   Level: beginner
2565c6c1daeSBarry Smith 
2575c6c1daeSBarry Smith   Notes:
258811af0c4SBarry Smith   This `PetscViewer` can be destroyed with `PetscViewerDestroy()`, but the fd will NOT be closed.
2595c6c1daeSBarry Smith 
260811af0c4SBarry Smith   If a multiprocessor communicator is used (such as `PETSC_COMM_WORLD`),
2615c6c1daeSBarry Smith   then only the first processor in the group uses the file.  All other
2625c6c1daeSBarry Smith   processors send their data to the first processor to print.
2635c6c1daeSBarry Smith 
264aec76313SJacob Faibussowitsch   Fortran Notes:
265e4096674SBarry Smith   Use `PetscViewerASCIIOpenWithFileUnit()`
266e4096674SBarry Smith 
267e4096674SBarry Smith .seealso: [](sec_viewers), `MatView()`, `VecView()`, `PetscViewerDestroy()`, `PetscViewerBinaryOpen()`, `PetscViewerASCIIOpenWithFileUnit()`,
268db781477SPatrick Sanan           `PetscViewerASCIIGetPointer()`, `PetscViewerPushFormat()`, `PETSC_VIEWER_STDOUT_`, `PETSC_VIEWER_STDERR_`,
269811af0c4SBarry Smith           `PETSC_VIEWER_STDOUT_WORLD`, `PETSC_VIEWER_STDOUT_SELF`, `PetscViewerASCIIOpen()`, `PetscViewerASCIISetFILE()`, `PETSCVIEWERASCII`
2705c6c1daeSBarry Smith @*/
271377f809aSBarry Smith PetscErrorCode PetscViewerASCIIOpenWithFILE(MPI_Comm comm, FILE *fd, PetscViewer *viewer)
272d71ae5a4SJacob Faibussowitsch {
2735c6c1daeSBarry Smith   PetscFunctionBegin;
274377f809aSBarry Smith   PetscCall(PetscViewerCreate(comm, viewer));
275377f809aSBarry Smith   PetscCall(PetscViewerSetType(*viewer, PETSCVIEWERASCII));
276377f809aSBarry Smith   PetscCall(PetscViewerASCIISetFILE(*viewer, fd));
2773ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2785c6c1daeSBarry Smith }
2795c6c1daeSBarry Smith 
280811af0c4SBarry Smith /*@C
2813f423023SBarry Smith   PetscViewerASCIISetFILE - Given an open file sets the `PETSCVIEWERASCII` viewer to use the file for output
282811af0c4SBarry Smith 
28320f4b53cSBarry Smith   Not Collective
284811af0c4SBarry Smith 
285811af0c4SBarry Smith   Input Parameters:
286811af0c4SBarry Smith + viewer - the `PetscViewer` to use with the specified file
28720f4b53cSBarry Smith - fd     - the `FILE` pointer
288811af0c4SBarry Smith 
289811af0c4SBarry Smith   Level: beginner
290811af0c4SBarry Smith 
291811af0c4SBarry Smith   Notes:
292c410d8ccSBarry Smith   This `PetscViewer` can be destroyed with `PetscViewerDestroy()`, but the `fd` will NOT be closed.
293811af0c4SBarry Smith 
294811af0c4SBarry Smith   If a multiprocessor communicator is used (such as `PETSC_COMM_WORLD`),
295811af0c4SBarry Smith   then only the first processor in the group uses the file.  All other
296811af0c4SBarry Smith   processors send their data to the first processor to print.
297811af0c4SBarry Smith 
298feaf08eaSBarry Smith   Fortran Note:
299e4096674SBarry Smith   Use `PetscViewerASCIISetFileUnit()`
300e4096674SBarry Smith 
301e4096674SBarry Smith .seealso: `MatView()`, `VecView()`, `PetscViewerDestroy()`, `PetscViewerBinaryOpen()`, `PetscViewerASCIISetFileUnit()`,
302811af0c4SBarry Smith           `PetscViewerASCIIGetPointer()`, `PetscViewerPushFormat()`, `PETSC_VIEWER_STDOUT_`, `PETSC_VIEWER_STDERR_`,
303811af0c4SBarry Smith           `PETSC_VIEWER_STDOUT_WORLD`, `PETSC_VIEWER_STDOUT_SELF`, `PetscViewerASCIIOpen()`, `PetscViewerASCIIOpenWithFILE()`, `PETSCVIEWERASCII`
304811af0c4SBarry Smith @*/
305d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIISetFILE(PetscViewer viewer, FILE *fd)
306d71ae5a4SJacob Faibussowitsch {
3075c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
3085c6c1daeSBarry Smith 
3095c6c1daeSBarry Smith   PetscFunctionBegin;
3105c6c1daeSBarry Smith   vascii->fd        = fd;
3115c6c1daeSBarry Smith   vascii->closefile = PETSC_FALSE;
3123ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3135c6c1daeSBarry Smith }
314