Actual source code: vecglvis.c

  1: #include <petsc/private/glvisviewerimpl.h>
  2: #include <petsc/private/glvisvecimpl.h>

  4: static PetscErrorCode PetscViewerGLVisVecInfoDestroy_Private(void *ptr)
  5: {
  6:   PetscViewerGLVisVecInfo info = (PetscViewerGLVisVecInfo)ptr;

  8:   PetscFunctionBeginUser;
  9:   PetscCall(PetscFree(info->fec_type));
 10:   PetscCall(PetscFree(info));
 11:   PetscFunctionReturn(PETSC_SUCCESS);
 12: }

 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;

 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;

 34:     PetscCall(PetscObjectQuery((PetscObject)U, "__PETSc_dm", &dm));
 35:     if (dm) {
 36:       PetscCall(PetscViewerGLVisSetDM_Internal(viewer, dm));
 37:     } else SETERRQ(PetscObjectComm((PetscObject)U), PETSC_ERR_SUP, "You need to provide a DM or use PetscViewerGLVisSetFields()");
 38:   }
 39:   PetscCall(PetscViewerGLVisGetFields_Internal(viewer, &nfields, &fec_type, &spacedim, &g2lfields, (PetscObject **)&Ufield, &userctx));
 40:   if (!nfields) PetscFunctionReturn(PETSC_SUCCESS);

 42:   PetscCall(PetscViewerGLVisGetType_Internal(viewer, &socktype));

 44:   for (i = 0; i < nfields; i++) {
 45:     PetscObject    fdm;
 46:     PetscContainer container;

 48:     /* attach visualization info to the vector */
 49:     PetscCall(PetscObjectQuery((PetscObject)Ufield[i], "_glvis_info_container", (PetscObject *)&container));
 50:     if (!container) {
 51:       PetscViewerGLVisVecInfo info;

 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;

 66:       PetscCall(PetscViewerGLVisGetDM_Internal(viewer, &dm));
 67:       if (!dm) PetscCall(PetscObjectQuery((PetscObject)U, "__PETSc_dm", &dm));
 68:       PetscCheck(dm, PetscObjectComm((PetscObject)U), PETSC_ERR_SUP, "Mesh not present");
 69:       PetscCall(PetscObjectCompose((PetscObject)Ufield[i], "__PETSc_dm", dm));
 70:     }
 71:   }

 73:   /* user-provided sampling */
 74:   if (g2lfields) {
 75:     PetscCall((*g2lfields)((PetscObject)U, nfields, (PetscObject *)Ufield, userctx));
 76:   } else {
 77:     PetscCheck(nfields <= 1, PetscObjectComm((PetscObject)U), PETSC_ERR_SUP, "Don't know how to sample %" PetscInt_FMT " fields", nfields);
 78:     PetscCall(VecCopy(U, Ufield[0]));
 79:   }

 81:   /* TODO callback to user routine to disable/enable subdomains */
 82:   for (i = 0; i < nfields; i++) {
 83:     PetscObject dm;
 84:     PetscViewer view;

 86:     PetscCall(PetscObjectQuery((PetscObject)Ufield[i], "__PETSc_dm", &dm));
 87:     PetscCall(PetscViewerGLVisGetWindow_Internal(viewer, i, &view));
 88:     if (!view) continue; /* socket window has been closed */
 89:     if (socktype == PETSC_VIEWER_GLVIS_SOCKET) {
 90:       PetscMPIInt size, rank;
 91:       const char *name;

 93:       PetscCallMPI(MPI_Comm_size(PetscObjectComm(dm), &size));
 94:       PetscCallMPI(MPI_Comm_rank(PetscObjectComm(dm), &rank));
 95:       PetscCall(PetscObjectGetName((PetscObject)Ufield[i], &name));

 97:       PetscCall(PetscGLVisCollectiveBegin(PetscObjectComm(dm), &view));
 98:       PetscCall(PetscViewerASCIIPrintf(view, "parallel %d %d\nsolution\n", size, rank));
 99:       PetscCall(PetscObjectView(dm, view));
100:       PetscCall(VecView(Ufield[i], view));
101:       PetscCall(PetscViewerGLVisInitWindow_Internal(view, PETSC_FALSE, spacedim[i], name));
102:       PetscCall(PetscGLVisCollectiveEnd(PetscObjectComm(dm), &view));
103:       if (view) pause = PETSC_TRUE; /* at least one window is connected */
104:     } else {
105:       PetscCall(PetscObjectView(dm, view));
106:       PetscCall(VecView(Ufield[i], view));
107:     }
108:     PetscCall(PetscViewerGLVisRestoreWindow_Internal(viewer, i, &view));
109:   }
110:   if (pause) PetscCall(PetscViewerGLVisPause_Internal(viewer));
111:   PetscFunctionReturn(PETSC_SUCCESS);
112: }