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