xref: /petsc/src/sys/classes/viewer/impls/ascii/vcreatea.c (revision f4f49eeac7efa77fffa46b7ff95a3ed169f659ed)
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 
99c5ded49SBarry Smith /*@
10811af0c4SBarry Smith   PetscViewerASCIIGetStdout - Creates a `PETSCVIEWERASCII` `PetscViewer` shared by all processors
11811af0c4SBarry Smith   in a communicator. Error returning version of `PETSC_VIEWER_STDOUT_()`
125c6c1daeSBarry Smith 
13d083f849SBarry Smith   Collective
145c6c1daeSBarry Smith 
155c6c1daeSBarry Smith   Input Parameter:
16811af0c4SBarry Smith . comm - the MPI communicator to share the `PetscViewer`
175c6c1daeSBarry Smith 
1810450e9eSJacob Faibussowitsch   Output Parameter:
1910450e9eSJacob Faibussowitsch . viewer - the viewer
2010450e9eSJacob Faibussowitsch 
215c6c1daeSBarry Smith   Level: beginner
225c6c1daeSBarry Smith 
23811af0c4SBarry Smith   Note:
2434fa283eSBarry Smith   This object is destroyed in `PetscFinalize()`, `PetscViewerDestroy()` should never be called on it
2534fa283eSBarry Smith 
2634fa283eSBarry Smith   Developer Note:
273f423023SBarry Smith   This should be used in all PETSc source code instead of `PETSC_VIEWER_STDOUT_()` since it allows error checking
285c6c1daeSBarry Smith 
29d1f92df0SBarry Smith .seealso: [](sec_viewers), `PETSC_VIEWER_DRAW_()`, `PetscViewerASCIIOpen()`, `PETSC_VIEWER_STDERR_`, `PETSC_VIEWER_STDOUT_WORLD`,
30db781477SPatrick Sanan           `PETSC_VIEWER_STDOUT_SELF`
315c6c1daeSBarry Smith @*/
32d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIIGetStdout(MPI_Comm comm, PetscViewer *viewer)
33d71ae5a4SJacob Faibussowitsch {
34e2dcd6d3SBarry Smith   PetscBool flg;
35e2dcd6d3SBarry Smith   MPI_Comm  ncomm;
365c6c1daeSBarry Smith 
375c6c1daeSBarry Smith   PetscFunctionBegin;
389566063dSJacob Faibussowitsch   PetscCall(PetscSpinlockLock(&PetscViewerASCIISpinLockStdout));
399566063dSJacob Faibussowitsch   PetscCall(PetscCommDuplicate(comm, &ncomm, NULL));
4048a46eb9SPierre 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));
419566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_get_attr(ncomm, Petsc_Viewer_Stdout_keyval, (void **)viewer, (PetscMPIInt *)&flg));
42e2dcd6d3SBarry Smith   if (!flg) { /* PetscViewer not yet created */
439566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIOpen(ncomm, "stdout", viewer));
4434fa283eSBarry Smith     ((PetscObject)*viewer)->persistent = PETSC_TRUE;
459566063dSJacob Faibussowitsch     PetscCall(PetscObjectRegisterDestroy((PetscObject)*viewer));
469566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_set_attr(ncomm, Petsc_Viewer_Stdout_keyval, (void *)*viewer));
47e2dcd6d3SBarry Smith   }
489566063dSJacob Faibussowitsch   PetscCall(PetscCommDestroy(&ncomm));
499566063dSJacob Faibussowitsch   PetscCall(PetscSpinlockUnlock(&PetscViewerASCIISpinLockStdout));
503ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
515c6c1daeSBarry Smith }
525c6c1daeSBarry Smith 
535c6c1daeSBarry Smith /*@C
54c410d8ccSBarry Smith    PETSC_VIEWER_STDOUT_ - Creates a `PETSCVIEWERASCII` `PetscViewer` shared by all MPI processes
555c6c1daeSBarry Smith                     in a communicator.
565c6c1daeSBarry Smith 
57d083f849SBarry Smith    Collective
585c6c1daeSBarry Smith 
595c6c1daeSBarry Smith    Input Parameter:
60811af0c4SBarry Smith .  comm - the MPI communicator to share the `PetscViewer`
615c6c1daeSBarry Smith 
625c6c1daeSBarry Smith    Level: beginner
635c6c1daeSBarry Smith 
6434fa283eSBarry Smith    Notes:
6534fa283eSBarry Smith    This object is destroyed in `PetscFinalize()`, `PetscViewerDestroy()` should never be called on it
6634fa283eSBarry Smith 
675c6c1daeSBarry Smith    Unlike almost all other PETSc routines, this does not return
685c6c1daeSBarry Smith    an error code. Usually used in the form
695c6c1daeSBarry Smith $      XXXView(XXX object, PETSC_VIEWER_STDOUT_(comm));
705c6c1daeSBarry Smith 
71d1f92df0SBarry Smith .seealso: [](sec_viewers), `PETSC_VIEWER_DRAW_()`, `PetscViewerASCIIOpen()`, `PETSC_VIEWER_STDERR_`, `PETSC_VIEWER_STDOUT_WORLD`,
72db781477SPatrick Sanan           `PETSC_VIEWER_STDOUT_SELF`
735c6c1daeSBarry Smith @*/
74d71ae5a4SJacob Faibussowitsch PetscViewer PETSC_VIEWER_STDOUT_(MPI_Comm comm)
75d71ae5a4SJacob Faibussowitsch {
765c6c1daeSBarry Smith   PetscErrorCode ierr;
775c6c1daeSBarry Smith   PetscViewer    viewer;
785c6c1daeSBarry Smith 
795c6c1daeSBarry Smith   PetscFunctionBegin;
805c6c1daeSBarry Smith   ierr = PetscViewerASCIIGetStdout(comm, &viewer);
819371c9d4SSatish Balay   if (ierr) {
823ba16761SJacob Faibussowitsch     ierr = PetscError(PETSC_COMM_SELF, __LINE__, "PETSC_VIEWER_STDOUT_", __FILE__, PETSC_ERR_PLIB, PETSC_ERROR_INITIAL, " ");
839371c9d4SSatish Balay     PetscFunctionReturn(NULL);
849371c9d4SSatish Balay   }
855c6c1daeSBarry Smith   PetscFunctionReturn(viewer);
865c6c1daeSBarry Smith }
875c6c1daeSBarry Smith 
88e2dcd6d3SBarry Smith /*
89e2dcd6d3SBarry Smith     The variable Petsc_Viewer_Stderr_keyval is used to indicate an MPI attribute that
90e2dcd6d3SBarry Smith   is attached to a communicator, in this case the attribute is a PetscViewer.
91e2dcd6d3SBarry Smith */
92d4c7638eSBarry Smith PetscMPIInt Petsc_Viewer_Stderr_keyval = MPI_KEYVAL_INVALID;
93e2dcd6d3SBarry Smith 
949c5ded49SBarry Smith /*@
95c410d8ccSBarry Smith   PetscViewerASCIIGetStderr - Creates a `PETSCVIEWERASCII` `PetscViewer` shared by all MPI processes
96811af0c4SBarry Smith   in a communicator. Error returning version of `PETSC_VIEWER_STDERR_()`
975c6c1daeSBarry Smith 
98d083f849SBarry Smith   Collective
995c6c1daeSBarry Smith 
1005c6c1daeSBarry Smith   Input Parameter:
101811af0c4SBarry Smith . comm - the MPI communicator to share the `PetscViewer`
1025c6c1daeSBarry Smith 
10310450e9eSJacob Faibussowitsch   Output Parameter:
10410450e9eSJacob Faibussowitsch . viewer - the viewer
10510450e9eSJacob Faibussowitsch 
1065c6c1daeSBarry Smith   Level: beginner
1075c6c1daeSBarry Smith 
108811af0c4SBarry Smith   Note:
10934fa283eSBarry Smith   This object is destroyed in `PetscFinalize()`, `PetscViewerDestroy()` should never be called on it
11034fa283eSBarry Smith 
11134fa283eSBarry Smith   Developer Note:
1123f423023SBarry Smith   This should be used in all PETSc source code instead of `PETSC_VIEWER_STDERR_()` since it allows error checking
1135c6c1daeSBarry Smith 
114d1f92df0SBarry Smith .seealso: [](sec_viewers), `PETSC_VIEWER_DRAW_()`, `PetscViewerASCIIOpen()`, `PETSC_VIEWER_STDERR_`, `PETSC_VIEWER_STDERR_WORLD`,
115db781477SPatrick Sanan           `PETSC_VIEWER_STDERR_SELF`
1165c6c1daeSBarry Smith @*/
117d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIIGetStderr(MPI_Comm comm, PetscViewer *viewer)
118d71ae5a4SJacob Faibussowitsch {
119e2dcd6d3SBarry Smith   PetscBool flg;
120e2dcd6d3SBarry Smith   MPI_Comm  ncomm;
121e2dcd6d3SBarry Smith 
122e2dcd6d3SBarry Smith   PetscFunctionBegin;
1239566063dSJacob Faibussowitsch   PetscCall(PetscSpinlockLock(&PetscViewerASCIISpinLockStderr));
1249566063dSJacob Faibussowitsch   PetscCall(PetscCommDuplicate(comm, &ncomm, NULL));
12548a46eb9SPierre 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));
1269566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_get_attr(ncomm, Petsc_Viewer_Stderr_keyval, (void **)viewer, (PetscMPIInt *)&flg));
127e2dcd6d3SBarry Smith   if (!flg) { /* PetscViewer not yet created */
1289566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIOpen(ncomm, "stderr", viewer));
12934fa283eSBarry Smith     ((PetscObject)*viewer)->persistent = PETSC_TRUE;
1309566063dSJacob Faibussowitsch     PetscCall(PetscObjectRegisterDestroy((PetscObject)*viewer));
1319566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_set_attr(ncomm, Petsc_Viewer_Stderr_keyval, (void *)*viewer));
132e2dcd6d3SBarry Smith   }
1339566063dSJacob Faibussowitsch   PetscCall(PetscCommDestroy(&ncomm));
1349566063dSJacob Faibussowitsch   PetscCall(PetscSpinlockUnlock(&PetscViewerASCIISpinLockStderr));
1353ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1365c6c1daeSBarry Smith }
1375c6c1daeSBarry Smith 
1385c6c1daeSBarry Smith /*@C
139c410d8ccSBarry Smith    PETSC_VIEWER_STDERR_ - Creates a `PETSCVIEWERASCII` `PetscViewer` shared by all MPI processes
1405c6c1daeSBarry Smith                     in a communicator.
1415c6c1daeSBarry Smith 
142d083f849SBarry Smith    Collective
1435c6c1daeSBarry Smith 
1445c6c1daeSBarry Smith    Input Parameter:
145811af0c4SBarry Smith .  comm - the MPI communicator to share the `PetscViewer`
1465c6c1daeSBarry Smith 
1475c6c1daeSBarry Smith    Level: beginner
1485c6c1daeSBarry Smith 
1493f423023SBarry Smith    Notes:
15034fa283eSBarry Smith    This object is destroyed in `PetscFinalize()`, `PetscViewerDestroy()` should never be called on it
15134fa283eSBarry Smith 
1525c6c1daeSBarry Smith    Unlike almost all other PETSc routines, this does not return
1535c6c1daeSBarry Smith    an error code. Usually used in the form
1545c6c1daeSBarry Smith $      XXXView(XXX object, PETSC_VIEWER_STDERR_(comm));
1555c6c1daeSBarry Smith 
1563f423023SBarry Smith    `PetscViewerASCIIGetStderr()` is preferred  since it allows error checking
1573f423023SBarry Smith 
158d1f92df0SBarry Smith .seealso: [](sec_viewers), `PETSC_VIEWER_DRAW_`, `PetscViewerASCIIOpen()`, `PETSC_VIEWER_STDOUT_`, `PETSC_VIEWER_STDOUT_WORLD`,
159db781477SPatrick Sanan           `PETSC_VIEWER_STDOUT_SELF`, `PETSC_VIEWER_STDERR_WORLD`, `PETSC_VIEWER_STDERR_SELF`
1605c6c1daeSBarry Smith @*/
161d71ae5a4SJacob Faibussowitsch PetscViewer PETSC_VIEWER_STDERR_(MPI_Comm comm)
162d71ae5a4SJacob Faibussowitsch {
1635c6c1daeSBarry Smith   PetscErrorCode ierr;
1645c6c1daeSBarry Smith   PetscViewer    viewer;
1655c6c1daeSBarry Smith 
1665c6c1daeSBarry Smith   PetscFunctionBegin;
1675c6c1daeSBarry Smith   ierr = PetscViewerASCIIGetStderr(comm, &viewer);
1689371c9d4SSatish Balay   if (ierr) {
1693ba16761SJacob Faibussowitsch     ierr = PetscError(PETSC_COMM_SELF, __LINE__, "PETSC_VIEWER_STDERR_", __FILE__, PETSC_ERR_PLIB, PETSC_ERROR_INITIAL, " ");
1709371c9d4SSatish Balay     PetscFunctionReturn(NULL);
1719371c9d4SSatish Balay   }
1725c6c1daeSBarry Smith   PetscFunctionReturn(viewer);
1735c6c1daeSBarry Smith }
1745c6c1daeSBarry Smith 
1755c6c1daeSBarry Smith PetscMPIInt Petsc_Viewer_keyval = MPI_KEYVAL_INVALID;
1765c6c1daeSBarry Smith /*
1773f423023SBarry Smith    Called with MPI_Comm_free() is called on a communicator that has a viewer as an attribute. The viewer is not actually destroyed
1783f423023SBarry Smith    because that is managed by PetscObjectDestroyRegisterAll(). PetscViewerASCIIGetStdout() registers the viewer with PetscObjectDestroyRegister() to be destroyed when PetscFinalize() is called.
1795c6c1daeSBarry Smith 
1805c6c1daeSBarry Smith   This is called by MPI, not by users.
1815c6c1daeSBarry Smith 
1825c6c1daeSBarry Smith */
18334e79e72SJacob Faibussowitsch PetscMPIInt MPIAPI Petsc_DelViewer(MPI_Comm comm, PetscMPIInt keyval, void *attr_val, void *extra_state)
184d71ae5a4SJacob Faibussowitsch {
1855c6c1daeSBarry Smith   PetscFunctionBegin;
18634e79e72SJacob Faibussowitsch   (void)keyval;
18734e79e72SJacob Faibussowitsch   (void)attr_val;
18834e79e72SJacob Faibussowitsch   (void)extra_state;
18934e79e72SJacob Faibussowitsch   PetscCallMPI(PetscInfo(NULL, "Removing viewer data attribute in an MPI_Comm %" PETSC_INTPTR_T_FMT "\n", (PETSC_INTPTR_T)comm));
1905c6c1daeSBarry Smith   PetscFunctionReturn(MPI_SUCCESS);
1915c6c1daeSBarry Smith }
1925c6c1daeSBarry Smith 
1935c6c1daeSBarry Smith /*@C
194c410d8ccSBarry Smith   PetscViewerASCIIOpen - Opens an ASCII file for writing as a `PETSCVIEWERASCII` `PetscViewer`.
1955c6c1daeSBarry Smith 
196d083f849SBarry Smith   Collective
1975c6c1daeSBarry Smith 
1985c6c1daeSBarry Smith   Input Parameters:
1995c6c1daeSBarry Smith + comm - the communicator
2005c6c1daeSBarry Smith - name - the file name
2015c6c1daeSBarry Smith 
2025c6c1daeSBarry Smith   Output Parameter:
2033f423023SBarry Smith . lab - the `PetscViewer` to use with the specified file
2045c6c1daeSBarry Smith 
2055c6c1daeSBarry Smith   Level: beginner
2065c6c1daeSBarry Smith 
2075c6c1daeSBarry Smith   Notes:
208f8859db6SBarry Smith   To open a ASCII file as a viewer for reading one must use the sequence
209811af0c4SBarry Smith .vb
210811af0c4SBarry Smith    PetscViewerCreate(comm,&lab);
211811af0c4SBarry Smith    PetscViewerSetType(lab,PETSCVIEWERASCII);
212811af0c4SBarry Smith    PetscViewerFileSetMode(lab,FILE_MODE_READ);
213811af0c4SBarry Smith    PetscViewerFileSetName(lab,name);
214811af0c4SBarry Smith .ve
215f8859db6SBarry Smith 
216811af0c4SBarry Smith   This `PetscViewer` can be destroyed with `PetscViewerDestroy()`.
2175c6c1daeSBarry Smith 
2182ea3bc1cSBarry Smith   The MPI communicator used here must match that used by the object one is viewing. For example if the
219811af0c4SBarry Smith   Mat was created with a `PETSC_COMM_WORLD`, then the Viewer must be created with `PETSC_COMM_WORLD`
2205c6c1daeSBarry Smith 
221811af0c4SBarry Smith   As shown below, `PetscViewerASCIIOpen()` is useful in conjunction with
222811af0c4SBarry Smith   `MatView()` and `VecView()`
2235c6c1daeSBarry Smith .vb
2245c6c1daeSBarry Smith      PetscViewerASCIIOpen(PETSC_COMM_WORLD,"mat.output",&viewer);
2255c6c1daeSBarry Smith      MatView(matrix,viewer);
2265c6c1daeSBarry Smith .ve
2275c6c1daeSBarry Smith 
228d1f92df0SBarry Smith .seealso: [](sec_viewers), `MatView()`, `VecView()`, `PetscViewerDestroy()`, `PetscViewerBinaryOpen()`, `PetscViewerASCIIRead()`, `PETSCVIEWERASCII`
229db781477SPatrick Sanan           `PetscViewerASCIIGetPointer()`, `PetscViewerPushFormat()`, `PETSC_VIEWER_STDOUT_`, `PETSC_VIEWER_STDERR_`,
230db781477SPatrick Sanan           `PETSC_VIEWER_STDOUT_WORLD`, `PETSC_VIEWER_STDOUT_SELF`,
2315c6c1daeSBarry Smith @*/
232d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIIOpen(MPI_Comm comm, const char name[], PetscViewer *lab)
233d71ae5a4SJacob Faibussowitsch {
2345c6c1daeSBarry Smith   PetscViewerLink *vlink, *nv;
2355c6c1daeSBarry Smith   PetscBool        flg, eq;
2365c6c1daeSBarry Smith   size_t           len;
2375c6c1daeSBarry Smith 
2385c6c1daeSBarry Smith   PetscFunctionBegin;
2399566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(name, &len));
2405c6c1daeSBarry Smith   if (!len) {
2419566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIGetStdout(comm, lab));
2429566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)*lab));
2433ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
2445c6c1daeSBarry Smith   }
2459566063dSJacob Faibussowitsch   PetscCall(PetscSpinlockLock(&PetscViewerASCIISpinLockOpen));
24648a46eb9SPierre 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));
2472bf49c77SBarry Smith   /*
2482bf49c77SBarry Smith        It would be better to move this code to PetscFileSetName() but since it must return a preexiting communicator
2492bf49c77SBarry Smith      we cannot do that, since PetscFileSetName() takes a communicator that already exists.
2502bf49c77SBarry Smith 
2512bf49c77SBarry Smith       Plus if the original communicator that created the file has since been close this will not detect the old
2522bf49c77SBarry Smith       communictor and hence will overwrite the old data. It may be better to simply remove all this code
2532bf49c77SBarry Smith   */
2545c6c1daeSBarry Smith   /* make sure communicator is a PETSc communicator */
2559566063dSJacob Faibussowitsch   PetscCall(PetscCommDuplicate(comm, &comm, NULL));
2565c6c1daeSBarry Smith   /* has file already been opened into a viewer */
2579566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_get_attr(comm, Petsc_Viewer_keyval, (void **)&vlink, (PetscMPIInt *)&flg));
2585c6c1daeSBarry Smith   if (flg) {
2595c6c1daeSBarry Smith     while (vlink) {
260*f4f49eeaSPierre Jolivet       PetscCall(PetscStrcmp(name, ((PetscViewer_ASCII *)vlink->viewer->data)->filename, &eq));
2615c6c1daeSBarry Smith       if (eq) {
2629566063dSJacob Faibussowitsch         PetscCall(PetscObjectReference((PetscObject)vlink->viewer));
2635c6c1daeSBarry Smith         *lab = vlink->viewer;
2649566063dSJacob Faibussowitsch         PetscCall(PetscCommDestroy(&comm));
2659566063dSJacob Faibussowitsch         PetscCall(PetscSpinlockUnlock(&PetscViewerASCIISpinLockOpen));
2663ba16761SJacob Faibussowitsch         PetscFunctionReturn(PETSC_SUCCESS);
2675c6c1daeSBarry Smith       }
2685c6c1daeSBarry Smith       vlink = vlink->next;
2695c6c1daeSBarry Smith     }
2705c6c1daeSBarry Smith   }
2719566063dSJacob Faibussowitsch   PetscCall(PetscViewerCreate(comm, lab));
2729566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetType(*lab, PETSCVIEWERASCII));
2731baa6e33SBarry Smith   if (name) PetscCall(PetscViewerFileSetName(*lab, name));
2745c6c1daeSBarry Smith   /* save viewer into communicator if needed later */
2759566063dSJacob Faibussowitsch   PetscCall(PetscNew(&nv));
2765c6c1daeSBarry Smith   nv->viewer = *lab;
2775c6c1daeSBarry Smith   if (!flg) {
2789566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_set_attr(comm, Petsc_Viewer_keyval, nv));
2795c6c1daeSBarry Smith   } else {
2809566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_get_attr(comm, Petsc_Viewer_keyval, (void **)&vlink, (PetscMPIInt *)&flg));
2815c6c1daeSBarry Smith     if (vlink) {
2825c6c1daeSBarry Smith       while (vlink->next) vlink = vlink->next;
2835c6c1daeSBarry Smith       vlink->next = nv;
2845c6c1daeSBarry Smith     } else {
2859566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Comm_set_attr(comm, Petsc_Viewer_keyval, nv));
2865c6c1daeSBarry Smith     }
2875c6c1daeSBarry Smith   }
2889566063dSJacob Faibussowitsch   PetscCall(PetscCommDestroy(&comm));
2899566063dSJacob Faibussowitsch   PetscCall(PetscSpinlockUnlock(&PetscViewerASCIISpinLockOpen));
2903ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2915c6c1daeSBarry Smith }
2925c6c1daeSBarry Smith 
2935c6c1daeSBarry Smith /*@C
2943f423023SBarry Smith   PetscViewerASCIIOpenWithFILE - Given an open file creates an `PETSCVIEWERASCII` viewer that prints to it.
2955c6c1daeSBarry Smith 
296d083f849SBarry Smith   Collective
2975c6c1daeSBarry Smith 
2985c6c1daeSBarry Smith   Input Parameters:
2995c6c1daeSBarry Smith + comm - the communicator
30020f4b53cSBarry Smith - fd   - the `FILE` pointer
3015c6c1daeSBarry Smith 
3025c6c1daeSBarry Smith   Output Parameter:
303811af0c4SBarry Smith . lab - the `PetscViewer` to use with the specified file
3045c6c1daeSBarry Smith 
3055c6c1daeSBarry Smith   Level: beginner
3065c6c1daeSBarry Smith 
3075c6c1daeSBarry Smith   Notes:
308811af0c4SBarry Smith   This `PetscViewer` can be destroyed with `PetscViewerDestroy()`, but the fd will NOT be closed.
3095c6c1daeSBarry Smith 
310811af0c4SBarry Smith   If a multiprocessor communicator is used (such as `PETSC_COMM_WORLD`),
3115c6c1daeSBarry Smith   then only the first processor in the group uses the file.  All other
3125c6c1daeSBarry Smith   processors send their data to the first processor to print.
3135c6c1daeSBarry Smith 
314aec76313SJacob Faibussowitsch   Fortran Notes:
315e4096674SBarry Smith   Use `PetscViewerASCIIOpenWithFileUnit()`
316e4096674SBarry Smith 
317e4096674SBarry Smith .seealso: [](sec_viewers), `MatView()`, `VecView()`, `PetscViewerDestroy()`, `PetscViewerBinaryOpen()`, `PetscViewerASCIIOpenWithFileUnit()`,
318db781477SPatrick Sanan           `PetscViewerASCIIGetPointer()`, `PetscViewerPushFormat()`, `PETSC_VIEWER_STDOUT_`, `PETSC_VIEWER_STDERR_`,
319811af0c4SBarry Smith           `PETSC_VIEWER_STDOUT_WORLD`, `PETSC_VIEWER_STDOUT_SELF`, `PetscViewerASCIIOpen()`, `PetscViewerASCIISetFILE()`, `PETSCVIEWERASCII`
3205c6c1daeSBarry Smith @*/
321d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIIOpenWithFILE(MPI_Comm comm, FILE *fd, PetscViewer *lab)
322d71ae5a4SJacob Faibussowitsch {
3235c6c1daeSBarry Smith   PetscFunctionBegin;
3249566063dSJacob Faibussowitsch   PetscCall(PetscViewerCreate(comm, lab));
3259566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetType(*lab, PETSCVIEWERASCII));
3269566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIISetFILE(*lab, fd));
3273ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3285c6c1daeSBarry Smith }
3295c6c1daeSBarry Smith 
330811af0c4SBarry Smith /*@C
3313f423023SBarry Smith   PetscViewerASCIISetFILE - Given an open file sets the `PETSCVIEWERASCII` viewer to use the file for output
332811af0c4SBarry Smith 
33320f4b53cSBarry Smith   Not Collective
334811af0c4SBarry Smith 
335811af0c4SBarry Smith   Input Parameters:
336811af0c4SBarry Smith + viewer - the `PetscViewer` to use with the specified file
33720f4b53cSBarry Smith - fd     - the `FILE` pointer
338811af0c4SBarry Smith 
339811af0c4SBarry Smith   Level: beginner
340811af0c4SBarry Smith 
341811af0c4SBarry Smith   Notes:
342c410d8ccSBarry Smith   This `PetscViewer` can be destroyed with `PetscViewerDestroy()`, but the `fd` will NOT be closed.
343811af0c4SBarry Smith 
344811af0c4SBarry Smith   If a multiprocessor communicator is used (such as `PETSC_COMM_WORLD`),
345811af0c4SBarry Smith   then only the first processor in the group uses the file.  All other
346811af0c4SBarry Smith   processors send their data to the first processor to print.
347811af0c4SBarry Smith 
348aec76313SJacob Faibussowitsch   Fortran Notes:
349e4096674SBarry Smith   Use `PetscViewerASCIISetFileUnit()`
350e4096674SBarry Smith 
351e4096674SBarry Smith .seealso: `MatView()`, `VecView()`, `PetscViewerDestroy()`, `PetscViewerBinaryOpen()`, `PetscViewerASCIISetFileUnit()`,
352811af0c4SBarry Smith           `PetscViewerASCIIGetPointer()`, `PetscViewerPushFormat()`, `PETSC_VIEWER_STDOUT_`, `PETSC_VIEWER_STDERR_`,
353811af0c4SBarry Smith           `PETSC_VIEWER_STDOUT_WORLD`, `PETSC_VIEWER_STDOUT_SELF`, `PetscViewerASCIIOpen()`, `PetscViewerASCIIOpenWithFILE()`, `PETSCVIEWERASCII`
354811af0c4SBarry Smith @*/
355d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerASCIISetFILE(PetscViewer viewer, FILE *fd)
356d71ae5a4SJacob Faibussowitsch {
3575c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
3585c6c1daeSBarry Smith 
3595c6c1daeSBarry Smith   PetscFunctionBegin;
3605c6c1daeSBarry Smith   vascii->fd        = fd;
3615c6c1daeSBarry Smith   vascii->closefile = PETSC_FALSE;
3623ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3635c6c1daeSBarry Smith }
364