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," "); viewer = 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," "); viewer = 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_INITIAL," "); viewer = NULL;} 47 ierr = PetscObjectRegisterDestroy((PetscObject)viewer); 48 if (ierr) {PetscError(ncomm,__LINE__,"PETSC_VIEWER_SAWS_",__FILE__,1,PETSC_ERROR_INITIAL," "); viewer = 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," "); viewer = NULL;} 51 } 52 ierr = PetscCommDestroy(&ncomm); 53 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_SAWS_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 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 PetscErrorCode ierr; 63 PetscMPIInt flag; 64 PetscViewer viewer; 65 66 PetscFunctionBegin; 67 if (Petsc_Viewer_SAWs_keyval == MPI_KEYVAL_INVALID) PetscFunctionReturn(0); 68 69 ierr = MPI_Comm_get_attr(comm,Petsc_Viewer_SAWs_keyval,(void**)&viewer,&flag);CHKERRQ(ierr); 70 if (flag) { 71 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 72 ierr = MPI_Comm_delete_attr(comm,Petsc_Viewer_SAWs_keyval);CHKERRQ(ierr); 73 } 74 PetscFunctionReturn(0); 75 } 76 77 static PetscErrorCode PetscViewerDestroy_SAWs(PetscViewer viewer) 78 { 79 PetscErrorCode ierr; 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) { 86 ierr = PetscStackSAWsViewOff();CHKERRQ(ierr); 87 } 88 PetscFunctionReturn(0); 89 } 90 91 PETSC_EXTERN PetscErrorCode PetscViewerCreate_SAWs(PetscViewer v) 92 { 93 PetscFunctionBegin; 94 v->ops->destroy = PetscViewerDestroy_SAWs; 95 PetscFunctionReturn(0); 96 } 97 98 99 100