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 PetscObject dm; 37 PetscErrorCode (*g2lfields)(PetscObject,PetscInt,PetscObject[],void*); 38 Vec *Ufield; 39 const char **fec_type,**name; 40 PetscViewerGLVisStatus sockstatus; 41 PetscViewerGLVisType socktype; 42 void *userctx; 43 PetscInt i,nfields,*locandbs; 44 PetscErrorCode ierr; 45 46 PetscFunctionBegin; 47 ierr = PetscViewerGLVisGetStatus_Private(viewer,&sockstatus);CHKERRQ(ierr); 48 if (sockstatus == PETSCVIEWERGLVIS_DISABLED) PetscFunctionReturn(0); 49 /* if the user did not customize the viewer through the API, we need extra data that can be attached to the Vec */ 50 ierr = PetscViewerGLVisGetFields_Private(viewer,&nfields,NULL,NULL,NULL,NULL,NULL,NULL);CHKERRQ(ierr); 51 if (!nfields) { 52 ierr = PetscObjectQuery((PetscObject)U, "__PETSc_dm",&dm);CHKERRQ(ierr); 53 if (dm) { 54 ierr = PetscViewerGLVisSetDM_Private(viewer,dm);CHKERRQ(ierr); 55 } else SETERRQ(PetscObjectComm((PetscObject)U),PETSC_ERR_SUP,"You need to provide a DM or use PetscViewerGLVisSetFields()"); 56 } 57 ierr = PetscViewerGLVisGetFields_Private(viewer,&nfields,&name,&fec_type,&locandbs,&g2lfields,(PetscObject**)&Ufield,&userctx);CHKERRQ(ierr); 58 ierr = PetscViewerGLVisGetType_Private(viewer,&socktype);CHKERRQ(ierr); 59 ierr = PetscViewerGLVisGetDM_Private(viewer,&dm);CHKERRQ(ierr); 60 if (!dm) { 61 ierr = PetscObjectQuery((PetscObject)U, "__PETSc_dm",&dm);CHKERRQ(ierr); 62 } 63 if (!dm) SETERRQ(PetscObjectComm((PetscObject)U),PETSC_ERR_SUP,"Mesh not present"); 64 65 if (!Ufield[0]) { 66 for (i=0;i<nfields;i++) { 67 PetscViewerGLVisVecInfo info; 68 PetscContainer container; 69 70 ierr = VecCreateMPI(PetscObjectComm((PetscObject)U),locandbs[3*i],PETSC_DECIDE,&Ufield[i]);CHKERRQ(ierr); 71 ierr = PetscObjectSetName((PetscObject)Ufield[i],name[i]);CHKERRQ(ierr); 72 ierr = VecSetBlockSize(Ufield[i],locandbs[3*i+1]);CHKERRQ(ierr); 73 74 /* attach visualization info to the vector */ 75 ierr = PetscNew(&info);CHKERRQ(ierr); 76 ierr = PetscStrallocpy(fec_type[i],&info->fec_type);CHKERRQ(ierr); 77 ierr = PetscContainerCreate(PetscObjectComm((PetscObject)U),&container);CHKERRQ(ierr); 78 ierr = PetscContainerSetPointer(container,(void*)info);CHKERRQ(ierr); 79 ierr = PetscContainerSetUserDestroy(container,PetscViewerGLVisVecInfoDestroy_Private);CHKERRQ(ierr); 80 ierr = PetscObjectCompose((PetscObject)Ufield[i],"_glvis_info_container",(PetscObject)container);CHKERRQ(ierr); 81 ierr = PetscContainerDestroy(&container);CHKERRQ(ierr); 82 83 /* attach the mesh to the viz vectors */ 84 ierr = PetscObjectCompose((PetscObject)Ufield[i], "__PETSc_dm",dm);CHKERRQ(ierr); 85 } 86 } 87 88 /* user-provided sampling */ 89 if (g2lfields) { 90 ierr = (*g2lfields)((PetscObject)U,nfields,(PetscObject*)Ufield,userctx);CHKERRQ(ierr); 91 } else { 92 ierr = VecCopy(U,Ufield[0]);CHKERRQ(ierr); 93 } 94 95 /* TODO callback to user routine to disable/enable subdomains */ 96 for (i=0;i<nfields;i++) { 97 PetscViewer view; 98 99 ierr = PetscObjectQuery((PetscObject)Ufield[i], "__PETSc_dm",&dm);CHKERRQ(ierr); 100 ierr = PetscViewerGLVisGetWindow_Private(viewer,i,&view);CHKERRQ(ierr); 101 if (!view) continue; /* socket window has been closed */ 102 if (socktype == PETSC_VIEWER_GLVIS_DUMP) { 103 ierr = PetscObjectView(dm,view);CHKERRQ(ierr); 104 ierr = VecView(Ufield[i],view);CHKERRQ(ierr); 105 } else { 106 /* It may happen that the user has closed the GLVis window */ 107 #if defined(PETSC_HAVE_SETJMP_H) && !defined(PETSC_MISSING_SIGPIPE) 108 void (*sighdl)(int) = signal(SIGPIPE,PetscGLVisSigPipeHandler); 109 if (!setjmp(PetscGLVisSigPipeJmpBuf)) { 110 #endif 111 PetscMPIInt size,rank; 112 113 ierr = MPI_Comm_size(PetscObjectComm(dm),&size);CHKERRQ(ierr); 114 ierr = MPI_Comm_rank(PetscObjectComm(dm),&rank);CHKERRQ(ierr); 115 ierr = PetscViewerASCIIPrintf(view,"parallel %D %D\nsolution\n",size,rank);CHKERRQ(ierr); 116 ierr = PetscObjectView(dm,view);CHKERRQ(ierr); 117 ierr = VecView(Ufield[i],view);CHKERRQ(ierr); 118 ierr = PetscViewerGLVisInitWindow_Private(view,PETSC_FALSE,locandbs[3*i+2],name[i]);CHKERRQ(ierr); 119 #if defined(PETSC_HAVE_SETJMP_H) && !defined(PETSC_MISSING_SIGPIPE) 120 } else { 121 FILE *sock,*null = fopen(DEV_NULL,"w"); 122 PetscInt readonly; 123 124 ierr = VecLockGet(Ufield[i],&readonly);CHKERRQ(ierr); 125 if (readonly) { 126 ierr = VecLockPop(Ufield[i]);CHKERRQ(ierr); 127 } 128 ierr = PetscViewerASCIIGetPointer(view,&sock);CHKERRQ(ierr); 129 ierr = PetscViewerASCIISetFILE(view,null);CHKERRQ(ierr); 130 ierr = PetscViewerDestroy(&view);CHKERRQ(ierr); 131 (void)fclose(sock); 132 } 133 (void)signal(SIGPIPE,sighdl); 134 #endif 135 } 136 ierr = PetscViewerGLVisRestoreWindow_Private(viewer,i,&view);CHKERRQ(ierr); 137 } 138 ierr = PetscViewerGLVisPause_Private(viewer);CHKERRQ(ierr); 139 PetscFunctionReturn(0); 140 } 141