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 #undef __FUNCT__ 13 #define __FUNCT__ "PETSC_VIEWER_SAWS_" 14 /*@C 15 PETSC_VIEWER_SAWS_ - Creates an SAWs PetscViewer shared by all processors in a communicator. 16 17 Collective on MPI_Comm 18 19 Input Parameters: 20 . comm - the MPI communicator to share the PetscViewer 21 22 Level: developer 23 24 Notes: 25 Unlike almost all other PETSc routines, PETSC_VIEWER_SAWS_() does not return 26 an error code. The resulting PetscViewer is usually used in the form 27 $ XXXView(XXX object,PETSC_VIEWER_SAWS_(comm)); 28 29 .seealso: PETSC_VIEWER_SAWS_WORLD, PETSC_VIEWER_SAWS_SELF 30 @*/ 31 PetscViewer PETSC_VIEWER_SAWS_(MPI_Comm comm) 32 { 33 PetscErrorCode ierr; 34 PetscMPIInt flag; 35 PetscViewer viewer; 36 MPI_Comm ncomm; 37 38 PetscFunctionBegin; 39 ierr = PetscCommDuplicate(comm,&ncomm,NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_SAWS_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 40 if (Petsc_Viewer_SAWs_keyval == MPI_KEYVAL_INVALID) { 41 ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_SAWs_keyval,0); 42 if (ierr) {PetscError(ncomm,__LINE__,"PETSC_VIEWER_SAWS_",__FILE__,1,PETSC_ERROR_INITIAL," "); viewer = NULL;} 43 } 44 ierr = MPI_Attr_get(ncomm,Petsc_Viewer_SAWs_keyval,(void**)&viewer,&flag); 45 if (ierr) {PetscError(ncomm,__LINE__,"PETSC_VIEWER_SAWS_",__FILE__,1,PETSC_ERROR_INITIAL," "); viewer = NULL;} 46 if (!flag) { /* PetscViewer not yet created */ 47 ierr = PetscViewerSAWsOpen(comm,&viewer); 48 if (ierr) {PetscError(ncomm,__LINE__,"PETSC_VIEWER_SAWS_",__FILE__,1,PETSC_ERROR_INITIAL," "); viewer = NULL;} 49 ierr = PetscObjectRegisterDestroy((PetscObject)viewer); 50 if (ierr) {PetscError(ncomm,__LINE__,"PETSC_VIEWER_SAWS_",__FILE__,1,PETSC_ERROR_INITIAL," "); viewer = NULL;} 51 ierr = MPI_Attr_put(ncomm,Petsc_Viewer_SAWs_keyval,(void*)viewer); 52 if (ierr) {PetscError(ncomm,__LINE__,"PETSC_VIEWER_SAWS_",__FILE__,1,PETSC_ERROR_INITIAL," "); viewer = NULL;} 53 } 54 ierr = PetscCommDestroy(&ncomm); 55 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_SAWS_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 56 PetscFunctionReturn(viewer); 57 } 58 59 /* 60 If there is a PetscViewer associated with this communicator, it is destroyed. 61 */ 62 #undef __FUNCT__ 63 #define __FUNCT__ "PetscViewer_SAWS_Destroy" 64 PetscErrorCode PetscViewer_SAWS_Destroy(MPI_Comm comm) 65 { 66 PetscErrorCode ierr; 67 PetscMPIInt flag; 68 PetscViewer viewer; 69 70 PetscFunctionBegin; 71 if (Petsc_Viewer_SAWs_keyval == MPI_KEYVAL_INVALID) PetscFunctionReturn(0); 72 73 ierr = MPI_Attr_get(comm,Petsc_Viewer_SAWs_keyval,(void**)&viewer,&flag);CHKERRQ(ierr); 74 if (flag) { 75 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 76 ierr = MPI_Attr_delete(comm,Petsc_Viewer_SAWs_keyval);CHKERRQ(ierr); 77 } 78 PetscFunctionReturn(0); 79 } 80 81 #undef __FUNCT__ 82 #define __FUNCT__ "PetscViewerDestroy_SAWs" 83 static PetscErrorCode PetscViewerDestroy_SAWs(PetscViewer viewer) 84 { 85 PetscErrorCode ierr; 86 87 PetscFunctionBegin; 88 /* 89 Make sure that we mark that the stack is no longer published 90 */ 91 if (PetscObjectComm((PetscObject)viewer) == PETSC_COMM_WORLD) { 92 ierr = PetscStackSAWsViewOff();CHKERRQ(ierr); 93 } 94 PetscFunctionReturn(0); 95 } 96 97 #undef __FUNCT__ 98 #define __FUNCT__ "PetscViewerCreate_SAWs" 99 PETSC_EXTERN PetscErrorCode PetscViewerCreate_SAWs(PetscViewer v) 100 { 101 PetscFunctionBegin; 102 v->ops->destroy = PetscViewerDestroy_SAWs; 103 PetscFunctionReturn(0); 104 } 105 106 107 108