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