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 @*/ 30 PetscViewer PETSC_VIEWER_SAWS_(MPI_Comm comm) 31 { 32 PetscErrorCode ierr; 33 PetscMPIInt flag; 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, &flag); 41 if (ierr) { 42 ierr = PetscError(ncomm, __LINE__, "PETSC_VIEWER_SAWS_", __FILE__, PETSC_ERR_MPI, PETSC_ERROR_INITIAL, " "); 43 PetscFunctionReturn(NULL); 44 } 45 if (!flag) { /* 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 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 68 PETSC_EXTERN PetscErrorCode PetscViewerCreate_SAWs(PetscViewer v) 69 { 70 PetscFunctionBegin; 71 v->ops->destroy = PetscViewerDestroy_SAWs; 72 PetscFunctionReturn(PETSC_SUCCESS); 73 } 74