1 #include <petsc/private/glvisviewerimpl.h> 2 #include <petsc/private/glvisvecimpl.h> 3 4 static PetscErrorCode PetscViewerGLVisVecInfoDestroy_Private(void *ptr) 5 { 6 PetscViewerGLVisVecInfo info = (PetscViewerGLVisVecInfo)ptr; 7 PetscErrorCode ierr; 8 9 PetscFunctionBeginUser; 10 ierr = PetscFree(info->fec_type);CHKERRQ(ierr); 11 ierr = PetscFree(info);CHKERRQ(ierr); 12 PetscFunctionReturn(0); 13 } 14 15 #if defined(PETSC_HAVE_SETJMP_H) && !defined(PETSC_MISSING_SIGPIPE) 16 #include <setjmp.h> 17 #include <signal.h> 18 19 #if defined(PETSC_HAVE_WINDOWS_H) 20 #define DEV_NULL "NUL" 21 #else 22 #define DEV_NULL "/dev/null" 23 #endif 24 25 static jmp_buf PetscGLVisSigPipeJmpBuf; 26 27 static void PetscGLVisSigPipeHandler(PETSC_UNUSED int sig) 28 { 29 longjmp(PetscGLVisSigPipeJmpBuf,1); 30 } 31 #endif 32 33 /* the main function to visualize vectors using GLVis */ 34 PetscErrorCode VecView_GLVis(Vec U,PetscViewer viewer) 35 { 36 PetscErrorCode (*g2lfields)(PetscObject,PetscInt,PetscObject[],void*); 37 Vec *Ufield; 38 const char **fec_type; 39 PetscViewerGLVisStatus sockstatus; 40 PetscViewerGLVisType socktype; 41 void *userctx; 42 PetscInt i,nfields,*spacedim; 43 PetscErrorCode ierr; 44 45 PetscFunctionBegin; 46 ierr = PetscViewerGLVisGetStatus_Private(viewer,&sockstatus);CHKERRQ(ierr); 47 if (sockstatus == PETSCVIEWERGLVIS_DISABLED) PetscFunctionReturn(0); 48 /* if the user did not customize the viewer through the API, we need extra data that can be attached to the Vec */ 49 ierr = PetscViewerGLVisGetFields_Private(viewer,&nfields,NULL,NULL,NULL,NULL,NULL);CHKERRQ(ierr); 50 if (!nfields) { 51 PetscObject dm; 52 53 ierr = PetscObjectQuery((PetscObject)U, "__PETSc_dm",&dm);CHKERRQ(ierr); 54 if (dm) { 55 ierr = PetscViewerGLVisSetDM_Private(viewer,dm);CHKERRQ(ierr); 56 } else SETERRQ(PetscObjectComm((PetscObject)U),PETSC_ERR_SUP,"You need to provide a DM or use PetscViewerGLVisSetFields()"); 57 } 58 ierr = PetscViewerGLVisGetFields_Private(viewer,&nfields,&fec_type,&spacedim,&g2lfields,(PetscObject**)&Ufield,&userctx);CHKERRQ(ierr); 59 if (!nfields) PetscFunctionReturn(0); 60 61 ierr = PetscViewerGLVisGetType_Private(viewer,&socktype);CHKERRQ(ierr); 62 63 for (i=0;i<nfields;i++) { 64 PetscObject fdm; 65 PetscContainer container; 66 67 /* attach visualization info to the vector */ 68 ierr = PetscObjectQuery((PetscObject)Ufield[i],"_glvis_info_container",(PetscObject*)&container);CHKERRQ(ierr); 69 if (!container) { 70 PetscViewerGLVisVecInfo info; 71 72 ierr = PetscNew(&info);CHKERRQ(ierr); 73 ierr = PetscStrallocpy(fec_type[i],&info->fec_type);CHKERRQ(ierr); 74 ierr = PetscContainerCreate(PetscObjectComm((PetscObject)U),&container);CHKERRQ(ierr); 75 ierr = PetscContainerSetPointer(container,(void*)info);CHKERRQ(ierr); 76 ierr = PetscContainerSetUserDestroy(container,PetscViewerGLVisVecInfoDestroy_Private);CHKERRQ(ierr); 77 ierr = PetscObjectCompose((PetscObject)Ufield[i],"_glvis_info_container",(PetscObject)container);CHKERRQ(ierr); 78 ierr = PetscContainerDestroy(&container);CHKERRQ(ierr); 79 } 80 /* attach the mesh to the viz vectors */ 81 ierr = PetscObjectQuery((PetscObject)Ufield[i], "__PETSc_dm",&fdm);CHKERRQ(ierr); 82 if (!fdm) { 83 PetscObject dm; 84 85 ierr = PetscViewerGLVisGetDM_Private(viewer,&dm);CHKERRQ(ierr); 86 if (!dm) { 87 ierr = PetscObjectQuery((PetscObject)U, "__PETSc_dm",&dm);CHKERRQ(ierr); 88 } 89 if (!dm) SETERRQ(PetscObjectComm((PetscObject)U),PETSC_ERR_SUP,"Mesh not present"); 90 ierr = PetscObjectCompose((PetscObject)Ufield[i], "__PETSc_dm",dm);CHKERRQ(ierr); 91 } 92 } 93 94 /* user-provided sampling */ 95 if (g2lfields) { 96 ierr = (*g2lfields)((PetscObject)U,nfields,(PetscObject*)Ufield,userctx);CHKERRQ(ierr); 97 } else { 98 ierr = VecCopy(U,Ufield[0]);CHKERRQ(ierr); 99 } 100 101 /* TODO callback to user routine to disable/enable subdomains */ 102 for (i=0;i<nfields;i++) { 103 PetscObject dm; 104 PetscViewer view; 105 106 ierr = PetscObjectQuery((PetscObject)Ufield[i], "__PETSc_dm",&dm);CHKERRQ(ierr); 107 ierr = PetscViewerGLVisGetWindow_Private(viewer,i,&view);CHKERRQ(ierr); 108 if (!view) continue; /* socket window has been closed */ 109 if (socktype == PETSC_VIEWER_GLVIS_DUMP) { 110 ierr = PetscObjectView(dm,view);CHKERRQ(ierr); 111 ierr = VecView(Ufield[i],view);CHKERRQ(ierr); 112 } else { 113 /* It may happen that the user has closed the GLVis window */ 114 #if defined(PETSC_HAVE_SETJMP_H) && !defined(PETSC_MISSING_SIGPIPE) 115 void (*sighdl)(int) = signal(SIGPIPE,PetscGLVisSigPipeHandler); 116 if (!setjmp(PetscGLVisSigPipeJmpBuf)) { 117 #endif 118 PetscMPIInt size,rank; 119 const char *name; 120 121 ierr = MPI_Comm_size(PetscObjectComm(dm),&size);CHKERRQ(ierr); 122 ierr = MPI_Comm_rank(PetscObjectComm(dm),&rank);CHKERRQ(ierr); 123 ierr = PetscViewerASCIIPrintf(view,"parallel %D %D\nsolution\n",size,rank);CHKERRQ(ierr); 124 ierr = PetscObjectView(dm,view);CHKERRQ(ierr); 125 ierr = VecView(Ufield[i],view);CHKERRQ(ierr); 126 ierr = PetscObjectGetName((PetscObject)Ufield[i],&name);CHKERRQ(ierr); 127 ierr = PetscViewerGLVisInitWindow_Private(view,PETSC_FALSE,spacedim[i],name);CHKERRQ(ierr); 128 #if defined(PETSC_HAVE_SETJMP_H) && !defined(PETSC_MISSING_SIGPIPE) 129 } else { 130 FILE *sock,*null = fopen(DEV_NULL,"w"); 131 PetscInt readonly; 132 133 ierr = VecLockGet(Ufield[i],&readonly);CHKERRQ(ierr); 134 if (readonly) { 135 ierr = VecLockPop(Ufield[i]);CHKERRQ(ierr); 136 } 137 ierr = PetscViewerASCIIGetPointer(view,&sock);CHKERRQ(ierr); 138 ierr = PetscViewerASCIISetFILE(view,null);CHKERRQ(ierr); 139 ierr = PetscViewerDestroy(&view);CHKERRQ(ierr); 140 (void)fclose(sock); 141 } 142 (void)signal(SIGPIPE,sighdl); 143 #endif 144 } 145 ierr = PetscViewerGLVisRestoreWindow_Private(viewer,i,&view);CHKERRQ(ierr); 146 } 147 ierr = PetscViewerGLVisPause_Private(viewer);CHKERRQ(ierr); 148 PetscFunctionReturn(0); 149 } 150