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