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