xref: /petsc/src/sys/classes/viewer/impls/ams/ams.c (revision 51b144c619aff302b570817d6f78637b8418d403)
1 #include <petsc/private/viewerimpl.h>
2 #include <petscviewersaws.h>
3 #include <petscsys.h>
4 
5 /*
6     The variable Petsc_Viewer_SAWs_keyval is used to indicate an MPI attribute that
7   is attached to a communicator, in this case the attribute is a PetscViewer.
8 */
9 static PetscMPIInt Petsc_Viewer_SAWs_keyval = MPI_KEYVAL_INVALID;
10 
11 /*@C
12      PETSC_VIEWER_SAWS_ - Creates a SAWs `PetscViewer` shared by all MPI processes in a communicator.
13 
14      Collective
15 
16      Input Parameter:
17 .    comm - the MPI communicator to share the `PetscViewer`
18 
19      Level: developer
20 
21      Note:
22      Unlike almost all other PETSc routines, `PETSC_VIEWER_SAWS_()` does not return
23      an error code.  The resulting `PetscViewer` is usually used in the form
24 .vb
25      XXXView(XXX object, PETSC_VIEWER_SAWS_(comm));
26 .ve
27 
28 .seealso: [](sec_viewers), `PetscViewer`, `PETSC_VIEWER_SAWS_WORLD`, `PETSC_VIEWER_SAWS_SELF`
29 @*/
PETSC_VIEWER_SAWS_(MPI_Comm comm)30 PetscViewer PETSC_VIEWER_SAWS_(MPI_Comm comm)
31 {
32   PetscErrorCode ierr;
33   PetscMPIInt    iflg;
34   PetscViewer    viewer;
35   MPI_Comm       ncomm;
36 
37   PetscFunctionBegin;
38   PetscCallNull(PetscCommDuplicate(comm, &ncomm, NULL));
39   if (Petsc_Viewer_SAWs_keyval == MPI_KEYVAL_INVALID) PetscCallMPINull(MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN, MPI_COMM_NULL_DELETE_FN, &Petsc_Viewer_SAWs_keyval, 0));
40   ierr = (PetscErrorCode)MPI_Comm_get_attr(ncomm, Petsc_Viewer_SAWs_keyval, (void **)&viewer, &iflg);
41   if (ierr) {
42     ierr = PetscError(ncomm, __LINE__, "PETSC_VIEWER_SAWS_", __FILE__, PETSC_ERR_MPI, PETSC_ERROR_INITIAL, " ");
43     PetscFunctionReturn(NULL);
44   }
45   if (!iflg) { /* PetscViewer not yet created */
46     PetscCallNull(PetscViewerSAWsOpen(comm, &viewer));
47     PetscCallNull(PetscObjectRegisterDestroy((PetscObject)viewer));
48     ierr = (PetscErrorCode)MPI_Comm_set_attr(ncomm, Petsc_Viewer_SAWs_keyval, (void *)viewer);
49     if (ierr) {
50       ierr = PetscError(ncomm, __LINE__, "PETSC_VIEWER_SAWS_", __FILE__, PETSC_ERR_MPI, PETSC_ERROR_INITIAL, " ");
51       PetscFunctionReturn(NULL);
52     }
53   }
54   PetscCallNull(PetscCommDestroy(&ncomm));
55   PetscFunctionReturn(viewer);
56 }
57 
PetscViewerDestroy_SAWs(PetscViewer viewer)58 static PetscErrorCode PetscViewerDestroy_SAWs(PetscViewer viewer)
59 {
60   PetscFunctionBegin;
61   /*
62      Make sure that we mark that the stack is no longer published
63   */
64   if (PetscObjectComm((PetscObject)viewer) == PETSC_COMM_WORLD) PetscCall(PetscStackSAWsViewOff());
65   PetscFunctionReturn(PETSC_SUCCESS);
66 }
67 
PetscViewerCreate_SAWs(PetscViewer v)68 PETSC_EXTERN PetscErrorCode PetscViewerCreate_SAWs(PetscViewer v)
69 {
70   PetscFunctionBegin;
71   v->ops->destroy = PetscViewerDestroy_SAWs;
72   PetscFunctionReturn(PETSC_SUCCESS);
73 }
74