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 Notes: 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: 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);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_SAWS_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 38 if (Petsc_Viewer_SAWs_keyval == MPI_KEYVAL_INVALID) { 39 ierr = MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,MPI_COMM_NULL_DELETE_FN,&Petsc_Viewer_SAWs_keyval,0); 40 if (ierr) {PetscError(ncomm,__LINE__,"PETSC_VIEWER_SAWS_",__FILE__,1,PETSC_ERROR_INITIAL," "); PetscFunctionReturn(NULL);} 41 } 42 ierr = MPI_Comm_get_attr(ncomm,Petsc_Viewer_SAWs_keyval,(void**)&viewer,&flag); 43 if (ierr) {PetscError(ncomm,__LINE__,"PETSC_VIEWER_SAWS_",__FILE__,1,PETSC_ERROR_INITIAL," "); PetscFunctionReturn(NULL);} 44 if (!flag) { /* PetscViewer not yet created */ 45 ierr = PetscViewerSAWsOpen(comm,&viewer); 46 if (ierr) {PetscError(ncomm,__LINE__,"PETSC_VIEWER_SAWS_",__FILE__,1,PETSC_ERROR_REPEAT," "); PetscFunctionReturn(NULL);} 47 ierr = PetscObjectRegisterDestroy((PetscObject)viewer); 48 if (ierr) {PetscError(ncomm,__LINE__,"PETSC_VIEWER_SAWS_",__FILE__,1,PETSC_ERROR_REPEAT," "); PetscFunctionReturn(NULL);} 49 ierr = MPI_Comm_set_attr(ncomm,Petsc_Viewer_SAWs_keyval,(void*)viewer); 50 if (ierr) {PetscError(ncomm,__LINE__,"PETSC_VIEWER_SAWS_",__FILE__,1,PETSC_ERROR_INITIAL," "); PetscFunctionReturn(NULL);} 51 } 52 ierr = PetscCommDestroy(&ncomm); 53 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_SAWS_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");PetscFunctionReturn(NULL);} 54 PetscFunctionReturn(viewer); 55 } 56 57 /* 58 If there is a PetscViewer associated with this communicator, it is destroyed. 59 */ 60 PetscErrorCode PetscViewer_SAWS_Destroy(MPI_Comm comm) 61 { 62 PetscMPIInt flag; 63 PetscViewer viewer; 64 65 PetscFunctionBegin; 66 if (Petsc_Viewer_SAWs_keyval == MPI_KEYVAL_INVALID) PetscFunctionReturn(0); 67 68 PetscCallMPI(MPI_Comm_get_attr(comm,Petsc_Viewer_SAWs_keyval,(void**)&viewer,&flag)); 69 if (flag) { 70 PetscCall(PetscViewerDestroy(&viewer)); 71 PetscCallMPI(MPI_Comm_delete_attr(comm,Petsc_Viewer_SAWs_keyval)); 72 } 73 PetscFunctionReturn(0); 74 } 75 76 static PetscErrorCode PetscViewerDestroy_SAWs(PetscViewer viewer) 77 { 78 PetscFunctionBegin; 79 /* 80 Make sure that we mark that the stack is no longer published 81 */ 82 if (PetscObjectComm((PetscObject)viewer) == PETSC_COMM_WORLD) PetscCall(PetscStackSAWsViewOff()); 83 PetscFunctionReturn(0); 84 } 85 86 PETSC_EXTERN PetscErrorCode PetscViewerCreate_SAWs(PetscViewer v) 87 { 88 PetscFunctionBegin; 89 v->ops->destroy = PetscViewerDestroy_SAWs; 90 PetscFunctionReturn(0); 91 } 92