xref: /petsc/src/vec/vec/utils/vecglvis.c (revision 5becb6a3a7fe6fe66ca978502f4679a4b24b29fc) !
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 
8   PetscFunctionBeginUser;
9   PetscCall(PetscFree(info->fec_type));
10   PetscCall(PetscFree(info));
11   PetscFunctionReturn(0);
12 }
13 
14 /* the main function to visualize vectors using GLVis */
15 PetscErrorCode VecView_GLVis(Vec U,PetscViewer viewer)
16 {
17   PetscErrorCode         (*g2lfields)(PetscObject,PetscInt,PetscObject[],void*);
18   Vec                    *Ufield;
19   const char             **fec_type;
20   PetscViewerGLVisStatus sockstatus;
21   PetscViewerGLVisType   socktype;
22   void                   *userctx;
23   PetscInt               i,nfields,*spacedim;
24   PetscBool              pause = PETSC_FALSE;
25 
26   PetscFunctionBegin;
27   PetscCall(PetscViewerGLVisGetStatus_Private(viewer,&sockstatus));
28   if (sockstatus == PETSCVIEWERGLVIS_DISABLED) PetscFunctionReturn(0);
29   /* if the user did not customize the viewer through the API, we need extra data that can be attached to the Vec */
30   PetscCall(PetscViewerGLVisGetFields_Private(viewer,&nfields,NULL,NULL,NULL,NULL,NULL));
31   if (!nfields) {
32     PetscObject dm;
33 
34     PetscCall(PetscObjectQuery((PetscObject)U, "__PETSc_dm",&dm));
35     if (dm) {
36       PetscCall(PetscViewerGLVisSetDM_Private(viewer,dm));
37     } else SETERRQ(PetscObjectComm((PetscObject)U),PETSC_ERR_SUP,"You need to provide a DM or use PetscViewerGLVisSetFields()");
38   }
39   PetscCall(PetscViewerGLVisGetFields_Private(viewer,&nfields,&fec_type,&spacedim,&g2lfields,(PetscObject**)&Ufield,&userctx));
40   if (!nfields) PetscFunctionReturn(0);
41 
42   PetscCall(PetscViewerGLVisGetType_Private(viewer,&socktype));
43 
44   for (i=0;i<nfields;i++) {
45     PetscObject    fdm;
46     PetscContainer container;
47 
48     /* attach visualization info to the vector */
49     PetscCall(PetscObjectQuery((PetscObject)Ufield[i],"_glvis_info_container",(PetscObject*)&container));
50     if (!container) {
51       PetscViewerGLVisVecInfo info;
52 
53       PetscCall(PetscNew(&info));
54       PetscCall(PetscStrallocpy(fec_type[i],&info->fec_type));
55       PetscCall(PetscContainerCreate(PetscObjectComm((PetscObject)U),&container));
56       PetscCall(PetscContainerSetPointer(container,(void*)info));
57       PetscCall(PetscContainerSetUserDestroy(container,PetscViewerGLVisVecInfoDestroy_Private));
58       PetscCall(PetscObjectCompose((PetscObject)Ufield[i],"_glvis_info_container",(PetscObject)container));
59       PetscCall(PetscContainerDestroy(&container));
60     }
61     /* attach the mesh to the viz vectors */
62     PetscCall(PetscObjectQuery((PetscObject)Ufield[i], "__PETSc_dm",&fdm));
63     if (!fdm) {
64       PetscObject dm;
65 
66       PetscCall(PetscViewerGLVisGetDM_Private(viewer,&dm));
67       if (!dm) {
68         PetscCall(PetscObjectQuery((PetscObject)U, "__PETSc_dm",&dm));
69       }
70       PetscCheck(dm,PetscObjectComm((PetscObject)U),PETSC_ERR_SUP,"Mesh not present");
71       PetscCall(PetscObjectCompose((PetscObject)Ufield[i], "__PETSc_dm",dm));
72     }
73   }
74 
75   /* user-provided sampling */
76   if (g2lfields) {
77     PetscCall((*g2lfields)((PetscObject)U,nfields,(PetscObject*)Ufield,userctx));
78   } else {
79     PetscCheck(nfields <= 1,PetscObjectComm((PetscObject)U),PETSC_ERR_SUP,"Don't know how to sample %" PetscInt_FMT " fields",nfields);
80     PetscCall(VecCopy(U,Ufield[0]));
81   }
82 
83   /* TODO callback to user routine to disable/enable subdomains */
84   for (i=0; i<nfields; i++) {
85     PetscObject dm;
86     PetscViewer view;
87 
88     PetscCall(PetscObjectQuery((PetscObject)Ufield[i], "__PETSc_dm",&dm));
89     PetscCall(PetscViewerGLVisGetWindow_Private(viewer,i,&view));
90     if (!view) continue; /* socket window has been closed */
91     if (socktype == PETSC_VIEWER_GLVIS_SOCKET) {
92       PetscMPIInt size,rank;
93       const char *name;
94 
95       PetscCallMPI(MPI_Comm_size(PetscObjectComm(dm),&size));
96       PetscCallMPI(MPI_Comm_rank(PetscObjectComm(dm),&rank));
97       PetscCall(PetscObjectGetName((PetscObject)Ufield[i],&name));
98 
99       PetscCall(PetscGLVisCollectiveBegin(PetscObjectComm(dm),&view));
100       PetscCall(PetscViewerASCIIPrintf(view,"parallel %d %d\nsolution\n",size,rank));
101       PetscCall(PetscObjectView(dm,view));
102       PetscCall(VecView(Ufield[i],view));
103       PetscCall(PetscViewerGLVisInitWindow_Private(view,PETSC_FALSE,spacedim[i],name));
104       PetscCall(PetscGLVisCollectiveEnd(PetscObjectComm(dm),&view));
105       if (view) pause = PETSC_TRUE; /* at least one window is connected */
106     } else {
107       PetscCall(PetscObjectView(dm,view));
108       PetscCall(VecView(Ufield[i],view));
109     }
110     PetscCall(PetscViewerGLVisRestoreWindow_Private(viewer,i,&view));
111   }
112   if (pause) PetscCall(PetscViewerGLVisPause_Private(viewer));
113   PetscFunctionReturn(0);
114 }
115