xref: /petsc/src/vec/vec/utils/vecglvis.c (revision d4c7638e66bfbab42594e49bfd8787d3c0f17499)
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