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 an SAWs `PetscViewer` shared by all processors in a communicator. 14 15 Collective 16 17 Input Parameters: 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: `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 PetscError(PETSC_COMM_SELF, __LINE__, "PETSC_VIEWER_SAWS_", __FILE__, PETSC_ERR_PLIB, PETSC_ERROR_INITIAL, " "); 40 PetscFunctionReturn(0); 41 } 42 if (Petsc_Viewer_SAWs_keyval == MPI_KEYVAL_INVALID) { 43 ierr = MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN, MPI_COMM_NULL_DELETE_FN, &Petsc_Viewer_SAWs_keyval, 0); 44 if (ierr) { 45 PetscError(ncomm, __LINE__, "PETSC_VIEWER_SAWS_", __FILE__, 1, PETSC_ERROR_INITIAL, " "); 46 PetscFunctionReturn(NULL); 47 } 48 } 49 ierr = MPI_Comm_get_attr(ncomm, Petsc_Viewer_SAWs_keyval, (void **)&viewer, &flag); 50 if (ierr) { 51 PetscError(ncomm, __LINE__, "PETSC_VIEWER_SAWS_", __FILE__, 1, PETSC_ERROR_INITIAL, " "); 52 PetscFunctionReturn(NULL); 53 } 54 if (!flag) { /* PetscViewer not yet created */ 55 ierr = PetscViewerSAWsOpen(comm, &viewer); 56 if (ierr) { 57 PetscError(ncomm, __LINE__, "PETSC_VIEWER_SAWS_", __FILE__, 1, PETSC_ERROR_REPEAT, " "); 58 PetscFunctionReturn(NULL); 59 } 60 ierr = PetscObjectRegisterDestroy((PetscObject)viewer); 61 if (ierr) { 62 PetscError(ncomm, __LINE__, "PETSC_VIEWER_SAWS_", __FILE__, 1, PETSC_ERROR_REPEAT, " "); 63 PetscFunctionReturn(NULL); 64 } 65 ierr = MPI_Comm_set_attr(ncomm, Petsc_Viewer_SAWs_keyval, (void *)viewer); 66 if (ierr) { 67 PetscError(ncomm, __LINE__, "PETSC_VIEWER_SAWS_", __FILE__, 1, PETSC_ERROR_INITIAL, " "); 68 PetscFunctionReturn(NULL); 69 } 70 } 71 ierr = PetscCommDestroy(&ncomm); 72 if (ierr) { 73 PetscError(PETSC_COMM_SELF, __LINE__, "PETSC_VIEWER_SAWS_", __FILE__, PETSC_ERR_PLIB, PETSC_ERROR_REPEAT, " "); 74 PetscFunctionReturn(NULL); 75 } 76 PetscFunctionReturn(viewer); 77 } 78 79 /* 80 If there is a PetscViewer associated with this communicator, it is destroyed. 81 */ 82 PetscErrorCode PetscViewer_SAWS_Destroy(MPI_Comm comm) 83 { 84 PetscMPIInt flag; 85 PetscViewer viewer; 86 87 PetscFunctionBegin; 88 if (Petsc_Viewer_SAWs_keyval == MPI_KEYVAL_INVALID) PetscFunctionReturn(0); 89 90 PetscCallMPI(MPI_Comm_get_attr(comm, Petsc_Viewer_SAWs_keyval, (void **)&viewer, &flag)); 91 if (flag) { 92 PetscCall(PetscViewerDestroy(&viewer)); 93 PetscCallMPI(MPI_Comm_delete_attr(comm, Petsc_Viewer_SAWs_keyval)); 94 } 95 PetscFunctionReturn(0); 96 } 97 98 static PetscErrorCode PetscViewerDestroy_SAWs(PetscViewer viewer) 99 { 100 PetscFunctionBegin; 101 /* 102 Make sure that we mark that the stack is no longer published 103 */ 104 if (PetscObjectComm((PetscObject)viewer) == PETSC_COMM_WORLD) PetscCall(PetscStackSAWsViewOff()); 105 PetscFunctionReturn(0); 106 } 107 108 PETSC_EXTERN PetscErrorCode PetscViewerCreate_SAWs(PetscViewer v) 109 { 110 PetscFunctionBegin; 111 v->ops->destroy = PetscViewerDestroy_SAWs; 112 PetscFunctionReturn(0); 113 } 114