1 #include <petsc/private/glvisviewerimpl.h>
2 #include <petsc/private/glvisvecimpl.h>
3
PetscViewerGLVisVecInfoDestroy_Private(PetscCtxRt ptr)4 static PetscErrorCode PetscViewerGLVisVecInfoDestroy_Private(PetscCtxRt ptr)
5 {
6 PetscViewerGLVisVecInfo info = (PetscViewerGLVisVecInfo) * (void **)ptr;
7
8 PetscFunctionBeginUser;
9 PetscCall(PetscFree(info->fec_type));
10 PetscCall(PetscFree(info));
11 PetscFunctionReturn(PETSC_SUCCESS);
12 }
13
14 /* the main function to visualize vectors using GLVis */
VecView_GLVis(Vec U,PetscViewer viewer)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 *ctx;
23 PetscInt i, nfields, *spacedim;
24 PetscBool pause = PETSC_FALSE;
25
26 PetscFunctionBegin;
27 PetscCall(PetscViewerGLVisGetStatus_Internal(viewer, &sockstatus));
28 if (sockstatus == PETSCVIEWERGLVIS_DISABLED) PetscFunctionReturn(PETSC_SUCCESS);
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_Internal(viewer, &nfields, NULL, NULL, NULL, NULL, NULL));
31 if (!nfields) {
32 PetscObject dm;
33
34 PetscCall(PetscObjectQuery((PetscObject)U, "__PETSc_dm", &dm));
35 PetscCheck(dm, PetscObjectComm((PetscObject)U), PETSC_ERR_SUP, "You need to provide a DM or use PetscViewerGLVisSetFields()");
36 PetscCall(PetscViewerGLVisSetDM_Internal(viewer, dm));
37 }
38 PetscCall(PetscViewerGLVisGetFields_Internal(viewer, &nfields, &fec_type, &spacedim, &g2lfields, (PetscObject **)&Ufield, &ctx));
39 if (!nfields) PetscFunctionReturn(PETSC_SUCCESS);
40
41 PetscCall(PetscViewerGLVisGetType_Internal(viewer, &socktype));
42
43 for (i = 0; i < nfields; i++) {
44 PetscObject fdm;
45 PetscContainer container;
46
47 /* attach visualization info to the vector */
48 PetscCall(PetscObjectQuery((PetscObject)Ufield[i], "_glvis_info_container", (PetscObject *)&container));
49 if (!container) {
50 PetscViewerGLVisVecInfo info;
51
52 PetscCall(PetscNew(&info));
53 PetscCall(PetscStrallocpy(fec_type[i], &info->fec_type));
54 PetscCall(PetscObjectContainerCompose((PetscObject)Ufield[i], "_glvis_info_container", info, PetscViewerGLVisVecInfoDestroy_Private));
55 }
56 /* attach the mesh to the viz vectors */
57 PetscCall(PetscObjectQuery((PetscObject)Ufield[i], "__PETSc_dm", &fdm));
58 if (!fdm) {
59 PetscObject dm;
60
61 PetscCall(PetscViewerGLVisGetDM_Internal(viewer, &dm));
62 if (!dm) PetscCall(PetscObjectQuery((PetscObject)U, "__PETSc_dm", &dm));
63 PetscCheck(dm, PetscObjectComm((PetscObject)U), PETSC_ERR_SUP, "Mesh not present");
64 PetscCall(PetscObjectCompose((PetscObject)Ufield[i], "__PETSc_dm", dm));
65 }
66 }
67
68 /* user-provided sampling */
69 if (g2lfields) {
70 PetscCall((*g2lfields)((PetscObject)U, nfields, (PetscObject *)Ufield, ctx));
71 } else {
72 PetscCheck(nfields <= 1, PetscObjectComm((PetscObject)U), PETSC_ERR_SUP, "Don't know how to sample %" PetscInt_FMT " fields", nfields);
73 PetscCall(VecCopy(U, Ufield[0]));
74 }
75
76 /* TODO callback to user routine to disable/enable subdomains */
77 for (i = 0; i < nfields; i++) {
78 PetscObject dm;
79 PetscViewer view;
80
81 PetscCall(PetscObjectQuery((PetscObject)Ufield[i], "__PETSc_dm", &dm));
82 PetscCall(PetscViewerGLVisGetWindow_Internal(viewer, i, &view));
83 if (!view) continue; /* socket window has been closed */
84 if (socktype == PETSC_VIEWER_GLVIS_SOCKET) {
85 PetscMPIInt size, rank;
86 const char *name;
87
88 PetscCallMPI(MPI_Comm_size(PetscObjectComm(dm), &size));
89 PetscCallMPI(MPI_Comm_rank(PetscObjectComm(dm), &rank));
90 PetscCall(PetscObjectGetName((PetscObject)Ufield[i], &name));
91
92 PetscCall(PetscGLVisCollectiveBegin(PetscObjectComm(dm), &view));
93 PetscCall(PetscViewerASCIIPrintf(view, "parallel %d %d\nsolution\n", size, rank));
94 PetscCall(PetscObjectView(dm, view));
95 PetscCall(VecView(Ufield[i], view));
96 PetscCall(PetscViewerGLVisInitWindow_Internal(view, PETSC_FALSE, spacedim[i], name));
97 PetscCall(PetscGLVisCollectiveEnd(PetscObjectComm(dm), &view));
98 if (view) pause = PETSC_TRUE; /* at least one window is connected */
99 } else {
100 PetscCall(PetscObjectView(dm, view));
101 PetscCall(VecView(Ufield[i], view));
102 }
103 PetscCall(PetscViewerGLVisRestoreWindow_Internal(viewer, i, &view));
104 }
105 if (pause) PetscCall(PetscViewerGLVisPause_Internal(viewer));
106 PetscFunctionReturn(PETSC_SUCCESS);
107 }
108