10039db0dSBarry Smith #define PETSC_DESIRE_FEATURE_TEST_MACROS /* for fdopen() */ 2347361c3SStefano Zampini 38135c375SStefano Zampini #include <petsc/private/viewerimpl.h> /*I "petscviewer.h" I*/ 48135c375SStefano Zampini #include <petsc/private/petscimpl.h> /*I "petscsys.h" I*/ 58135c375SStefano Zampini #include <petsc/private/glvisviewerimpl.h> 68135c375SStefano Zampini 78135c375SStefano Zampini /* we may eventually make this function public */ 88135c375SStefano Zampini static PetscErrorCode PetscViewerASCIISocketOpen(MPI_Comm,const char*,PetscInt,PetscViewer*); 98135c375SStefano Zampini 108135c375SStefano Zampini struct _n_PetscViewerGLVis { 118135c375SStefano Zampini PetscViewerGLVisStatus status; 128135c375SStefano Zampini PetscViewerGLVisType type; /* either PETSC_VIEWER_GLVIS_DUMP or PETSC_VIEWER_GLVIS_SOCKET */ 138135c375SStefano Zampini char *name; /* prefix for filename, or hostname, depending on the type */ 148135c375SStefano Zampini PetscInt port; /* used just for the socket case */ 158135c375SStefano Zampini PetscReal pause; /* if positive, calls PetscSleep(pause) after each VecView_GLVis call */ 168135c375SStefano Zampini PetscViewer meshwindow; /* used just by the ASCII dumping */ 178135c375SStefano Zampini PetscObject dm; /* DM as passed by PetscViewerGLVisSetDM_Private(): should contain discretization info */ 188135c375SStefano Zampini PetscInt nwindow; /* number of windows/fields to be visualized */ 198135c375SStefano Zampini PetscViewer *window; 208135c375SStefano Zampini char **windowtitle; 218135c375SStefano Zampini char **fec_type; /* type of elements to be used for visualization, see FiniteElementCollection::Name() */ 228135c375SStefano Zampini PetscErrorCode (*g2lfield)(PetscObject,PetscInt,PetscObject[],void*); /* global to local operation for generating dofs to be visualized */ 234cac2994SStefano Zampini PetscInt *spacedim; /* geometrical space dimension (just used to initialize the scene) */ 248135c375SStefano Zampini PetscObject *Ufield; /* work vectors for visualization */ 258135c375SStefano Zampini PetscInt snapid; /* snapshot id, use PetscViewerGLVisSetSnapId to change this value*/ 268135c375SStefano Zampini void *userctx; /* User context, used by g2lfield */ 278135c375SStefano Zampini PetscErrorCode (*destroyctx)(void*); /* destroy routine for userctx */ 2877eacf09SStefano Zampini char* fmt; /* format string for FP values */ 298135c375SStefano Zampini }; 308135c375SStefano Zampini typedef struct _n_PetscViewerGLVis *PetscViewerGLVis; 318135c375SStefano Zampini 328135c375SStefano Zampini /*@ 3377eacf09SStefano Zampini PetscViewerGLVisSetPrecision - Set the number of digits for floating point values 3477eacf09SStefano Zampini 3577eacf09SStefano Zampini Not Collective 3677eacf09SStefano Zampini 3777eacf09SStefano Zampini Input Parameters: 3877eacf09SStefano Zampini + viewer - the PetscViewer 3977eacf09SStefano Zampini - prec - the number of digits required 4077eacf09SStefano Zampini 4177eacf09SStefano Zampini Level: beginner 4277eacf09SStefano Zampini 4377eacf09SStefano Zampini .seealso: PetscViewerGLVisOpen(), PetscViewerGLVisSetFields(), PetscViewerCreate(), PetscViewerSetType() 4477eacf09SStefano Zampini @*/ 4577eacf09SStefano Zampini PetscErrorCode PetscViewerGLVisSetPrecision(PetscViewer viewer, PetscInt prec) 4677eacf09SStefano Zampini { 4777eacf09SStefano Zampini PetscErrorCode ierr; 4877eacf09SStefano Zampini 4977eacf09SStefano Zampini PetscFunctionBegin; 5077eacf09SStefano Zampini PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 5177eacf09SStefano Zampini ierr = PetscTryMethod(viewer,"PetscViewerGLVisSetPrecision_C",(PetscViewer,PetscInt),(viewer,prec));CHKERRQ(ierr); 5277eacf09SStefano Zampini PetscFunctionReturn(0); 5377eacf09SStefano Zampini } 5477eacf09SStefano Zampini 5577eacf09SStefano Zampini static PetscErrorCode PetscViewerGLVisSetPrecision_GLVis(PetscViewer viewer, PetscInt prec) 5677eacf09SStefano Zampini { 5777eacf09SStefano Zampini PetscErrorCode ierr; 5877eacf09SStefano Zampini PetscViewerGLVis socket = (PetscViewerGLVis)viewer->data; 5977eacf09SStefano Zampini 6077eacf09SStefano Zampini PetscFunctionBegin; 6177eacf09SStefano Zampini ierr = PetscFree(socket->fmt);CHKERRQ(ierr); 6277eacf09SStefano Zampini if (prec > 0) { 6377eacf09SStefano Zampini ierr = PetscMalloc1(16,&socket->fmt);CHKERRQ(ierr); 6477eacf09SStefano Zampini ierr = PetscSNPrintf(socket->fmt,16," %%.%De",prec);CHKERRQ(ierr); 6577eacf09SStefano Zampini } else { 6677eacf09SStefano Zampini ierr = PetscStrallocpy(" %g",&socket->fmt);CHKERRQ(ierr); 6777eacf09SStefano Zampini } 6877eacf09SStefano Zampini PetscFunctionReturn(0); 6977eacf09SStefano Zampini } 7077eacf09SStefano Zampini 7177eacf09SStefano Zampini /*@ 728135c375SStefano Zampini PetscViewerGLVisSetSnapId - Set the snapshot id. Only relevant when the viewer is of type PETSC_VIEWER_GLVIS_DUMP 738135c375SStefano Zampini 748135c375SStefano Zampini Logically Collective on PetscViewer 758135c375SStefano Zampini 768135c375SStefano Zampini Input Parameters: 778135c375SStefano Zampini + viewer - the PetscViewer 788135c375SStefano Zampini - id - the current snapshot id in a time-dependent simulation 798135c375SStefano Zampini 808135c375SStefano Zampini Level: beginner 818135c375SStefano Zampini 8277eacf09SStefano Zampini .seealso: PetscViewerGLVisOpen(), PetscViewerGLVisSetFields(), PetscViewerCreate(), PetscViewerSetType() 838135c375SStefano Zampini @*/ 848135c375SStefano Zampini PetscErrorCode PetscViewerGLVisSetSnapId(PetscViewer viewer, PetscInt id) 858135c375SStefano Zampini { 868135c375SStefano Zampini PetscErrorCode ierr; 878135c375SStefano Zampini 888135c375SStefano Zampini PetscFunctionBegin; 898135c375SStefano Zampini PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 908135c375SStefano Zampini PetscValidLogicalCollectiveInt(viewer,id,2); 918135c375SStefano Zampini ierr = PetscTryMethod(viewer,"PetscViewerGLVisSetSnapId_C",(PetscViewer,PetscInt),(viewer,id));CHKERRQ(ierr); 928135c375SStefano Zampini PetscFunctionReturn(0); 938135c375SStefano Zampini } 948135c375SStefano Zampini 958135c375SStefano Zampini static PetscErrorCode PetscViewerGLVisSetSnapId_GLVis(PetscViewer viewer, PetscInt id) 968135c375SStefano Zampini { 978135c375SStefano Zampini PetscViewerGLVis socket = (PetscViewerGLVis)viewer->data; 988135c375SStefano Zampini 998135c375SStefano Zampini PetscFunctionBegin; 10077eacf09SStefano Zampini socket->snapid = id; 1018135c375SStefano Zampini PetscFunctionReturn(0); 1028135c375SStefano Zampini } 1038135c375SStefano Zampini 1044cac2994SStefano Zampini /*@C 1054cac2994SStefano Zampini PetscViewerGLVisSetFields - Sets the required information to visualize different fields from a vector. 1068135c375SStefano Zampini 1078135c375SStefano Zampini Logically Collective on PetscViewer 1088135c375SStefano Zampini 1098135c375SStefano Zampini Input Parameters: 1108135c375SStefano Zampini + viewer - the PetscViewer 1118135c375SStefano Zampini . nf - number of fields to be visualized 1128135c375SStefano Zampini . fec_type - the type of finite element to be used to visualize the data (see FiniteElementCollection::Name() in MFEM) 1134cac2994SStefano Zampini . dim - array of space dimension for field vectors (used to initialize the scene) 1148135c375SStefano Zampini . g2lfields - User routine to compute the local field vectors to be visualized; PetscObject is used in place of Vec on the prototype 1154cac2994SStefano Zampini . Vfield - array of work vectors, one for each field 1168135c375SStefano Zampini . ctx - User context to store the relevant data to apply g2lfields 1178135c375SStefano Zampini - destroyctx - Destroy function for userctx 1188135c375SStefano Zampini 1194cac2994SStefano Zampini Notes: g2lfields is called on the vector V to be visualized in order to extract the relevant dofs to be put in Vfield[], as 1208135c375SStefano Zampini .vb 1214cac2994SStefano Zampini g2lfields((PetscObject)V,nfields,(PetscObject*)Vfield[],ctx). 1228135c375SStefano Zampini .ve 1234cac2994SStefano Zampini For vector spaces, the block size of Vfield[i] represents the vector dimension. It misses the Fortran bindings. 1244cac2994SStefano Zampini PETSc will take ownership of the work vectors. 1254cac2994SStefano Zampini The names of the Vfield vectors will be displayed in the window title. 1268135c375SStefano Zampini 1278135c375SStefano Zampini Level: intermediate 1288135c375SStefano Zampini 1294cac2994SStefano Zampini .seealso: PetscViewerGLVisOpen(), PetscViewerCreate(), PetscViewerSetType(), PetscObjectSetName() 1304cac2994SStefano Zampini @*/ 1314cac2994SStefano Zampini PetscErrorCode PetscViewerGLVisSetFields(PetscViewer viewer, PetscInt nf, const char* fec_type[], PetscInt dim[], PetscErrorCode(*g2l)(PetscObject,PetscInt,PetscObject[],void*), PetscObject Vfield[], void* ctx, PetscErrorCode(*destroyctx)(void*)) 1328135c375SStefano Zampini { 1338135c375SStefano Zampini PetscErrorCode ierr; 1348135c375SStefano Zampini 1358135c375SStefano Zampini PetscFunctionBegin; 1368135c375SStefano Zampini PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 1378135c375SStefano Zampini PetscValidLogicalCollectiveInt(viewer,nf,2); 1388135c375SStefano Zampini if (!fec_type) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"You need to provide the FiniteElementCollection names for the fields"); 1394cac2994SStefano Zampini PetscValidPointer(fec_type,3); 1404cac2994SStefano Zampini PetscValidPointer(dim,4); 1414cac2994SStefano Zampini PetscValidPointer(Vfield,6); 1424cac2994SStefano Zampini ierr = PetscTryMethod(viewer,"PetscViewerGLVisSetFields_C",(PetscViewer,PetscInt,const char*[],PetscInt[],PetscErrorCode(*)(PetscObject,PetscInt,PetscObject[],void*),PetscObject[],void*,PetscErrorCode(*)(void*)),(viewer,nf,fec_type,dim,g2l,Vfield,ctx,destroyctx));CHKERRQ(ierr); 1438135c375SStefano Zampini PetscFunctionReturn(0); 1448135c375SStefano Zampini } 1458135c375SStefano Zampini 1464cac2994SStefano Zampini static PetscErrorCode PetscViewerGLVisSetFields_GLVis(PetscViewer viewer, PetscInt nfields, const char* fec_type[], PetscInt dim[], PetscErrorCode(*g2l)(PetscObject,PetscInt,PetscObject[],void*), PetscObject Vfield[], void* ctx, PetscErrorCode(*destroyctx)(void*)) 1478135c375SStefano Zampini { 1488135c375SStefano Zampini PetscViewerGLVis socket = (PetscViewerGLVis)viewer->data; 1498135c375SStefano Zampini PetscInt i; 1508135c375SStefano Zampini PetscErrorCode ierr; 1518135c375SStefano Zampini 1528135c375SStefano Zampini PetscFunctionBegin; 1538135c375SStefano Zampini if (socket->nwindow && socket->nwindow != nfields) SETERRQ2(PetscObjectComm((PetscObject)viewer),PETSC_ERR_USER,"Cannot set number of fields %D with number of windows %D",nfields,socket->nwindow); 1548135c375SStefano Zampini if (!socket->nwindow) { 1558135c375SStefano Zampini socket->nwindow = nfields; 1568135c375SStefano Zampini 1574cac2994SStefano Zampini ierr = PetscCalloc5(nfields,&socket->window,nfields,&socket->windowtitle,nfields,&socket->fec_type,nfields,&socket->spacedim,nfields,&socket->Ufield);CHKERRQ(ierr); 1588135c375SStefano Zampini for (i=0;i<nfields;i++) { 1594cac2994SStefano Zampini const char *name; 1608135c375SStefano Zampini 1614cac2994SStefano Zampini ierr = PetscObjectGetName(Vfield[i],&name);CHKERRQ(ierr); 1628135c375SStefano Zampini ierr = PetscStrallocpy(name,&socket->windowtitle[i]);CHKERRQ(ierr); 1638135c375SStefano Zampini ierr = PetscStrallocpy(fec_type[i],&socket->fec_type[i]);CHKERRQ(ierr); 1644cac2994SStefano Zampini ierr = PetscObjectReference(Vfield[i]);CHKERRQ(ierr); 1654cac2994SStefano Zampini socket->Ufield[i] = Vfield[i]; 1664cac2994SStefano Zampini socket->spacedim[i] = dim[i]; 1678135c375SStefano Zampini } 1688135c375SStefano Zampini } 1698135c375SStefano Zampini /* number of fields are not allowed to vary */ 1708135c375SStefano Zampini if (nfields != socket->nwindow) SETERRQ2(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Cannot visualize %D fields using %D socket windows",nfields,socket->nwindow); 1718135c375SStefano Zampini socket->g2lfield = g2l; 1728135c375SStefano Zampini if (socket->destroyctx && socket->userctx) { ierr = (*socket->destroyctx)(socket->userctx);CHKERRQ(ierr); } 1738135c375SStefano Zampini socket->userctx = ctx; 1748135c375SStefano Zampini socket->destroyctx = destroyctx; 1758135c375SStefano Zampini PetscFunctionReturn(0); 1768135c375SStefano Zampini } 1778135c375SStefano Zampini 1788135c375SStefano Zampini static PetscErrorCode PetscViewerGLVisInfoDestroy_Private(void *ptr) 1798135c375SStefano Zampini { 1808135c375SStefano Zampini PetscViewerGLVisInfo info = (PetscViewerGLVisInfo)ptr; 1818135c375SStefano Zampini PetscErrorCode ierr; 1828135c375SStefano Zampini 183c0bc9656SStefano Zampini PetscFunctionBegin; 18477eacf09SStefano Zampini ierr = PetscFree(info->fmt);CHKERRQ(ierr); 1858135c375SStefano Zampini ierr = PetscFree(info);CHKERRQ(ierr); 1868135c375SStefano Zampini PetscFunctionReturn(0); 1878135c375SStefano Zampini } 1888135c375SStefano Zampini 1898135c375SStefano Zampini /* we can decide to prevent specific processes from using the viewer */ 1908135c375SStefano Zampini static PetscErrorCode PetscViewerGLVisAttachInfo_Private(PetscViewer viewer, PetscViewer window) 1918135c375SStefano Zampini { 1928135c375SStefano Zampini PetscViewerGLVis socket = (PetscViewerGLVis)viewer->data; 1938135c375SStefano Zampini PetscErrorCode ierr; 1948135c375SStefano Zampini PetscContainer container; 1958135c375SStefano Zampini PetscViewerGLVisInfo info; 1968135c375SStefano Zampini 197c0bc9656SStefano Zampini PetscFunctionBegin; 19877eacf09SStefano Zampini ierr = PetscObjectQuery((PetscObject)window,"_glvis_info_container",(PetscObject*)&container);CHKERRQ(ierr); 19977eacf09SStefano Zampini if (!container) { 2008135c375SStefano Zampini ierr = PetscNew(&info);CHKERRQ(ierr); 2018135c375SStefano Zampini info->enabled = PETSC_TRUE; 2028135c375SStefano Zampini info->init = PETSC_FALSE; 2038135c375SStefano Zampini info->pause = socket->pause; 2048135c375SStefano Zampini ierr = PetscContainerCreate(PetscObjectComm((PetscObject)window),&container);CHKERRQ(ierr); 2058135c375SStefano Zampini ierr = PetscContainerSetPointer(container,(void*)info);CHKERRQ(ierr); 2068135c375SStefano Zampini ierr = PetscContainerSetUserDestroy(container,PetscViewerGLVisInfoDestroy_Private);CHKERRQ(ierr); 2078135c375SStefano Zampini ierr = PetscObjectCompose((PetscObject)window,"_glvis_info_container",(PetscObject)container);CHKERRQ(ierr); 2088135c375SStefano Zampini ierr = PetscContainerDestroy(&container);CHKERRQ(ierr); 20977eacf09SStefano Zampini } else { 21077eacf09SStefano Zampini ierr = PetscContainerGetPointer(container,(void**)&info);CHKERRQ(ierr); 21177eacf09SStefano Zampini } 21277eacf09SStefano Zampini ierr = PetscFree(info->fmt);CHKERRQ(ierr); 21377eacf09SStefano Zampini ierr = PetscStrallocpy(socket->fmt,&info->fmt);CHKERRQ(ierr); 2148135c375SStefano Zampini PetscFunctionReturn(0); 2158135c375SStefano Zampini } 2168135c375SStefano Zampini 2178135c375SStefano Zampini static PetscErrorCode PetscViewerGLVisGetNewWindow_Private(PetscViewer viewer,PetscViewer *view) 2188135c375SStefano Zampini { 2198135c375SStefano Zampini PetscViewerGLVis socket = (PetscViewerGLVis)viewer->data; 2208135c375SStefano Zampini PetscViewer window = NULL; 2218135c375SStefano Zampini PetscBool ldis,dis; 2228135c375SStefano Zampini PetscErrorCode ierr; 2238135c375SStefano Zampini 2248135c375SStefano Zampini PetscFunctionBegin; 2258135c375SStefano Zampini ierr = PetscViewerASCIISocketOpen(PETSC_COMM_SELF,socket->name,socket->port,&window); 2268135c375SStefano Zampini /* if we could not estabilish a connection the first time, 2278135c375SStefano Zampini we disable the socket viewer */ 2288135c375SStefano Zampini ldis = ierr ? PETSC_TRUE : PETSC_FALSE; 2298135c375SStefano Zampini ierr = MPI_Allreduce(&ldis,&dis,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)viewer));CHKERRQ(ierr); 2308135c375SStefano Zampini if (dis) { 2318135c375SStefano Zampini socket->status = PETSCVIEWERGLVIS_DISABLED; 2328135c375SStefano Zampini ierr = PetscViewerDestroy(&window);CHKERRQ(ierr); 2338135c375SStefano Zampini } 2348135c375SStefano Zampini *view = window; 2358135c375SStefano Zampini PetscFunctionReturn(0); 2368135c375SStefano Zampini } 2378135c375SStefano Zampini 2388135c375SStefano Zampini PetscErrorCode PetscViewerGLVisPause_Private(PetscViewer viewer) 2398135c375SStefano Zampini { 2408135c375SStefano Zampini PetscViewerGLVis socket = (PetscViewerGLVis)viewer->data; 2418135c375SStefano Zampini PetscErrorCode ierr; 2428135c375SStefano Zampini 2438135c375SStefano Zampini PetscFunctionBegin; 2448135c375SStefano Zampini if (socket->pause > 0) { 2458135c375SStefano Zampini ierr = PetscSleep(socket->pause);CHKERRQ(ierr); 2468135c375SStefano Zampini } 2478135c375SStefano Zampini PetscFunctionReturn(0); 2488135c375SStefano Zampini } 2498135c375SStefano Zampini 2508135c375SStefano Zampini /* DM specific support */ 2518135c375SStefano Zampini PetscErrorCode PetscViewerGLVisSetDM_Private(PetscViewer viewer, PetscObject dm) 2528135c375SStefano Zampini { 2538135c375SStefano Zampini PetscErrorCode ierr; 2548135c375SStefano Zampini PetscViewerGLVis socket = (PetscViewerGLVis)viewer->data; 2558135c375SStefano Zampini 2568135c375SStefano Zampini PetscFunctionBegin; 2578135c375SStefano Zampini if (socket->dm && socket->dm != dm) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Cannot change DM associated with the GLVis viewer"); 2588135c375SStefano Zampini if (!socket->dm) { 2598135c375SStefano Zampini PetscErrorCode (*setupwithdm)(PetscObject,PetscViewer) = NULL; 2608135c375SStefano Zampini 2618135c375SStefano Zampini ierr = PetscObjectQueryFunction(dm,"DMSetUpGLVisViewer_C",&setupwithdm);CHKERRQ(ierr); 2628135c375SStefano Zampini if (setupwithdm) { 2638135c375SStefano Zampini ierr = (*setupwithdm)(dm,viewer);CHKERRQ(ierr); 2648135c375SStefano Zampini } else SETERRQ1(PetscObjectComm(dm),PETSC_ERR_SUP,"No support for DM type %s",dm->type_name); 2658135c375SStefano Zampini ierr = PetscObjectReference(dm);CHKERRQ(ierr); 2668135c375SStefano Zampini socket->dm = dm; 2678135c375SStefano Zampini } 2688135c375SStefano Zampini PetscFunctionReturn(0); 2698135c375SStefano Zampini } 2708135c375SStefano Zampini 2718135c375SStefano Zampini PetscErrorCode PetscViewerGLVisGetDMWindow_Private(PetscViewer viewer,PetscViewer* view) 2728135c375SStefano Zampini { 2738135c375SStefano Zampini PetscViewerGLVis socket = (PetscViewerGLVis)viewer->data; 2748135c375SStefano Zampini PetscErrorCode ierr; 2758135c375SStefano Zampini 2768135c375SStefano Zampini PetscFunctionBegin; 2778135c375SStefano Zampini if (!socket->meshwindow) { 2788135c375SStefano Zampini if (socket->type == PETSC_VIEWER_GLVIS_SOCKET) { 2798135c375SStefano Zampini ierr = PetscViewerGLVisGetNewWindow_Private(viewer,&socket->meshwindow);CHKERRQ(ierr); 2808135c375SStefano Zampini } else { 28104b79de6SStefano Zampini size_t len; 28204b79de6SStefano Zampini PetscBool isstdout; 28304b79de6SStefano Zampini 28404b79de6SStefano Zampini ierr = PetscStrlen(socket->name,&len);CHKERRQ(ierr); 28504b79de6SStefano Zampini ierr = PetscStrcmp(socket->name,"stdout",&isstdout);CHKERRQ(ierr); 28604b79de6SStefano Zampini if (!socket->name || !len || isstdout) { 2873f877d7dSStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,"stdout",&socket->meshwindow);CHKERRQ(ierr); 28804b79de6SStefano Zampini } else { 2898135c375SStefano Zampini PetscMPIInt rank; 2908135c375SStefano Zampini char filename[PETSC_MAX_PATH_LEN]; 2918135c375SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr); 2928135c375SStefano Zampini ierr = PetscSNPrintf(filename,PETSC_MAX_PATH_LEN,"%s-mesh.%06d",socket->name,rank);CHKERRQ(ierr); 2938135c375SStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,filename,&socket->meshwindow);CHKERRQ(ierr); 2948135c375SStefano Zampini } 29504b79de6SStefano Zampini } 2968135c375SStefano Zampini if (socket->meshwindow) { 2978135c375SStefano Zampini ierr = PetscViewerPushFormat(socket->meshwindow,PETSC_VIEWER_ASCII_GLVIS);CHKERRQ(ierr); 2988135c375SStefano Zampini } 2998135c375SStefano Zampini } 30077eacf09SStefano Zampini if (socket->meshwindow) { 30177eacf09SStefano Zampini ierr = PetscViewerGLVisAttachInfo_Private(viewer,socket->meshwindow);CHKERRQ(ierr); 30277eacf09SStefano Zampini } 3038135c375SStefano Zampini *view = socket->meshwindow; 3048135c375SStefano Zampini PetscFunctionReturn(0); 3058135c375SStefano Zampini } 3068135c375SStefano Zampini 3078135c375SStefano Zampini PetscErrorCode PetscViewerGLVisGetType_Private(PetscViewer viewer,PetscViewerGLVisType *type) 3088135c375SStefano Zampini { 3098135c375SStefano Zampini PetscViewerGLVis socket = (PetscViewerGLVis)viewer->data; 3108135c375SStefano Zampini 3118135c375SStefano Zampini PetscFunctionBegin; 3128135c375SStefano Zampini PetscValidPointer(type,2); 3138135c375SStefano Zampini *type = socket->type; 3148135c375SStefano Zampini PetscFunctionReturn(0); 3158135c375SStefano Zampini } 3168135c375SStefano Zampini 3178135c375SStefano Zampini /* This function is only relevant in the SOCKET_GLIVS case. The status is computed the first time it is requested, as GLVis currently has issues when connecting the first time through the socket */ 3188135c375SStefano Zampini PetscErrorCode PetscViewerGLVisGetStatus_Private(PetscViewer viewer, PetscViewerGLVisStatus *sockstatus) 3198135c375SStefano Zampini { 3208135c375SStefano Zampini PetscViewerGLVis socket = (PetscViewerGLVis)viewer->data; 3218135c375SStefano Zampini 3228135c375SStefano Zampini PetscFunctionBegin; 3238135c375SStefano Zampini PetscValidPointer(sockstatus,2); 3248135c375SStefano Zampini if (socket->type == PETSC_VIEWER_GLVIS_DUMP) { 3258135c375SStefano Zampini socket->status = PETSCVIEWERGLVIS_DISCONNECTED; 3268135c375SStefano Zampini } else if (socket->status == PETSCVIEWERGLVIS_DISCONNECTED && socket->nwindow) { 3278135c375SStefano Zampini PetscInt i; 3288135c375SStefano Zampini PetscBool lconn,conn; 3298135c375SStefano Zampini PetscErrorCode ierr; 3308135c375SStefano Zampini 3318135c375SStefano Zampini for (i=0,lconn=PETSC_TRUE;i<socket->nwindow;i++) 3328135c375SStefano Zampini if (!socket->window[i]) 3338135c375SStefano Zampini lconn = PETSC_FALSE; 3348135c375SStefano Zampini 3358135c375SStefano Zampini ierr = MPI_Allreduce(&lconn,&conn,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)viewer));CHKERRQ(ierr); 3368135c375SStefano Zampini if (conn) socket->status = PETSCVIEWERGLVIS_CONNECTED; 3378135c375SStefano Zampini } 3388135c375SStefano Zampini *sockstatus = socket->status; 3398135c375SStefano Zampini PetscFunctionReturn(0); 3408135c375SStefano Zampini } 3418135c375SStefano Zampini 3428135c375SStefano Zampini PetscErrorCode PetscViewerGLVisGetDM_Private(PetscViewer viewer, PetscObject* dm) 3438135c375SStefano Zampini { 3448135c375SStefano Zampini PetscViewerGLVis socket = (PetscViewerGLVis)viewer->data; 3458135c375SStefano Zampini 3468135c375SStefano Zampini PetscFunctionBegin; 3478135c375SStefano Zampini *dm = socket->dm; 3488135c375SStefano Zampini PetscFunctionReturn(0); 3498135c375SStefano Zampini } 3508135c375SStefano Zampini 3514cac2994SStefano Zampini PetscErrorCode PetscViewerGLVisGetFields_Private(PetscViewer viewer, PetscInt* nfield, const char **fec[], PetscInt *spacedim[], PetscErrorCode(**g2lfield)(PetscObject,PetscInt,PetscObject[],void*), PetscObject *Ufield[], void **userctx) 3528135c375SStefano Zampini { 3538135c375SStefano Zampini PetscViewerGLVis socket = (PetscViewerGLVis)viewer->data; 3548135c375SStefano Zampini 3558135c375SStefano Zampini PetscFunctionBegin; 3568135c375SStefano Zampini if (nfield) *nfield = socket->nwindow; 3578135c375SStefano Zampini if (fec) *fec = (const char**)socket->fec_type; 3584cac2994SStefano Zampini if (spacedim) *spacedim = socket->spacedim; 3598135c375SStefano Zampini if (g2lfield) *g2lfield = socket->g2lfield; 3608135c375SStefano Zampini if (Ufield) *Ufield = socket->Ufield; 3618135c375SStefano Zampini if (userctx) *userctx = socket->userctx; 3628135c375SStefano Zampini PetscFunctionReturn(0); 3638135c375SStefano Zampini } 3648135c375SStefano Zampini 3658135c375SStefano Zampini /* accessor routines for the viewer windows: 3668135c375SStefano Zampini PETSC_VIEWER_GLVIS_DUMP : it returns a new viewer every time 3678135c375SStefano Zampini PETSC_VIEWER_GLVIS_SOCKET : it returns the socket, and creates it if not yet done. 3688135c375SStefano Zampini */ 3698135c375SStefano Zampini PetscErrorCode PetscViewerGLVisGetWindow_Private(PetscViewer viewer,PetscInt wid,PetscViewer* view) 3708135c375SStefano Zampini { 3718135c375SStefano Zampini PetscViewerGLVis socket = (PetscViewerGLVis)viewer->data; 3728135c375SStefano Zampini PetscViewerGLVisStatus status; 3738135c375SStefano Zampini PetscErrorCode ierr; 3748135c375SStefano Zampini 3758135c375SStefano Zampini PetscFunctionBegin; 3768135c375SStefano Zampini PetscValidLogicalCollectiveInt(viewer,wid,2); 3778135c375SStefano Zampini PetscValidPointer(view,3); 3788135c375SStefano Zampini if (wid < 0 || wid > socket->nwindow-1) SETERRQ2(PetscObjectComm((PetscObject)viewer),PETSC_ERR_USER,"Cannot get window id %D: allowed range [0,%D)",wid,socket->nwindow-1); 3798135c375SStefano Zampini status = socket->status; 3808135c375SStefano Zampini if (socket->type == PETSC_VIEWER_GLVIS_DUMP && socket->window[wid]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Window %D is already in use",wid); 3818135c375SStefano Zampini switch (status) { 3828135c375SStefano Zampini case PETSCVIEWERGLVIS_DISCONNECTED: 3838135c375SStefano Zampini if (socket->window[wid]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"This should not happen"); 3848135c375SStefano Zampini if (socket->type == PETSC_VIEWER_GLVIS_DUMP) { 38504b79de6SStefano Zampini size_t len; 38604b79de6SStefano Zampini PetscBool isstdout; 38704b79de6SStefano Zampini 38804b79de6SStefano Zampini ierr = PetscStrlen(socket->name,&len);CHKERRQ(ierr); 38904b79de6SStefano Zampini ierr = PetscStrcmp(socket->name,"stdout",&isstdout);CHKERRQ(ierr); 39004b79de6SStefano Zampini if (!socket->name || !len || isstdout) { 3913f877d7dSStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,"stdout",&socket->window[wid]);CHKERRQ(ierr); 39204b79de6SStefano Zampini } else { 3938135c375SStefano Zampini PetscMPIInt rank; 3948135c375SStefano Zampini char filename[PETSC_MAX_PATH_LEN]; 3958135c375SStefano Zampini 3968135c375SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr); 3978135c375SStefano Zampini ierr = PetscSNPrintf(filename,PETSC_MAX_PATH_LEN,"%s-%s-%d.%06d",socket->name,socket->windowtitle[wid],socket->snapid,rank);CHKERRQ(ierr); 3988135c375SStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,filename,&socket->window[wid]);CHKERRQ(ierr); 39904b79de6SStefano Zampini } 4008135c375SStefano Zampini } else { 4018135c375SStefano Zampini ierr = PetscViewerGLVisGetNewWindow_Private(viewer,&socket->window[wid]);CHKERRQ(ierr); 4028135c375SStefano Zampini } 4038135c375SStefano Zampini if (socket->window[wid]) { 4048135c375SStefano Zampini ierr = PetscViewerPushFormat(socket->window[wid],PETSC_VIEWER_ASCII_GLVIS);CHKERRQ(ierr); 4058135c375SStefano Zampini } 4068135c375SStefano Zampini *view = socket->window[wid]; 4078135c375SStefano Zampini break; 4088135c375SStefano Zampini case PETSCVIEWERGLVIS_CONNECTED: 4098135c375SStefano Zampini *view = socket->window[wid]; 4108135c375SStefano Zampini break; 4118135c375SStefano Zampini case PETSCVIEWERGLVIS_DISABLED: 4128135c375SStefano Zampini *view = NULL; 4138135c375SStefano Zampini break; 4148135c375SStefano Zampini default: 4158135c375SStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Unhandled socket status %d\n",(int)status); 4168135c375SStefano Zampini break; 4178135c375SStefano Zampini } 41877eacf09SStefano Zampini if (*view) { 41977eacf09SStefano Zampini ierr = PetscViewerGLVisAttachInfo_Private(viewer,*view);CHKERRQ(ierr); 42077eacf09SStefano Zampini } 4218135c375SStefano Zampini PetscFunctionReturn(0); 4228135c375SStefano Zampini } 4238135c375SStefano Zampini 4248135c375SStefano Zampini /* Restore the window viewer 4258135c375SStefano Zampini PETSC_VIEWER_GLVIS_DUMP : destroys the temporary created ASCII viewer used for dumping 4268135c375SStefano Zampini PETSC_VIEWER_GLVIS_SOCKET: - if the returned window viewer is not NULL, just zeros the pointer. 4278135c375SStefano Zampini - it the returned window viewer is NULL, assumes something went wrong 4288135c375SStefano Zampini with the socket (i.e. SIGPIPE when a user closes the popup window) 4298135c375SStefano Zampini and that the caller already handled it (see VecView_GLVis). 4308135c375SStefano Zampini */ 4318135c375SStefano Zampini PetscErrorCode PetscViewerGLVisRestoreWindow_Private(PetscViewer viewer,PetscInt wid, PetscViewer* view) 4328135c375SStefano Zampini { 4338135c375SStefano Zampini PetscViewerGLVis socket = (PetscViewerGLVis)viewer->data; 4348135c375SStefano Zampini PetscErrorCode ierr; 4358135c375SStefano Zampini 4368135c375SStefano Zampini PetscFunctionBegin; 4378135c375SStefano Zampini PetscValidLogicalCollectiveInt(viewer,wid,2); 4388135c375SStefano Zampini PetscValidPointer(view,3); 4398135c375SStefano Zampini if (wid < 0 || wid > socket->nwindow-1) SETERRQ2(PetscObjectComm((PetscObject)viewer),PETSC_ERR_USER,"Cannot restore window id %D: allowed range [0,%D)",wid,socket->nwindow); 4408135c375SStefano Zampini if (*view && *view != socket->window[wid]) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_USER,"Viewer was not obtained from PetscViewerGLVisGetWindow"); 4418135c375SStefano Zampini if (*view) { 4428135c375SStefano Zampini ierr = PetscViewerFlush(*view);CHKERRQ(ierr); 4438135c375SStefano Zampini ierr = PetscBarrier((PetscObject)viewer);CHKERRQ(ierr); 4448135c375SStefano Zampini } 4458135c375SStefano Zampini if (socket->type == PETSC_VIEWER_GLVIS_DUMP) { /* destroy the viewer, as it is associated with a single time step */ 4468135c375SStefano Zampini ierr = PetscViewerDestroy(&socket->window[wid]);CHKERRQ(ierr); 4478135c375SStefano Zampini } else if (!*view) { /* something went wrong (SIGPIPE) so we just zero the private pointer */ 4488135c375SStefano Zampini socket->window[wid] = NULL; 4498135c375SStefano Zampini } 4508135c375SStefano Zampini *view = NULL; 4518135c375SStefano Zampini PetscFunctionReturn(0); 4528135c375SStefano Zampini } 4538135c375SStefano Zampini 4548135c375SStefano Zampini /* default window appearance in the PETSC_VIEWER_GLVIS_SOCKET case */ 4558135c375SStefano Zampini PetscErrorCode PetscViewerGLVisInitWindow_Private(PetscViewer viewer, PetscBool mesh, PetscInt dim, const char *name) 4568135c375SStefano Zampini { 4578135c375SStefano Zampini PetscErrorCode ierr; 4588135c375SStefano Zampini PetscViewerGLVisInfo info; 4598135c375SStefano Zampini PetscContainer container; 4608135c375SStefano Zampini 4618135c375SStefano Zampini PetscFunctionBegin; 4628135c375SStefano Zampini ierr = PetscObjectQuery((PetscObject)viewer,"_glvis_info_container",(PetscObject*)&container);CHKERRQ(ierr); 4638135c375SStefano Zampini if (!container) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Viewer was not obtained from PetscGLVisViewerGetNewWindow_Private"); 4648135c375SStefano Zampini ierr = PetscContainerGetPointer(container,(void**)&info);CHKERRQ(ierr); 4658135c375SStefano Zampini if (info->init) { 4668135c375SStefano Zampini if (info->pause < 0) { 4678135c375SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"pause\n");CHKERRQ(ierr); /* pause */ 4688135c375SStefano Zampini } 4698135c375SStefano Zampini PetscFunctionReturn(0); 4708135c375SStefano Zampini } 4718135c375SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"window_size 800 800\n");CHKERRQ(ierr); 4728135c375SStefano Zampini if (name) { 4738135c375SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"window_title '%s'\n",name);CHKERRQ(ierr); 4748135c375SStefano Zampini } 4758135c375SStefano Zampini if (mesh) { 4768135c375SStefano Zampini switch (dim) { 4778135c375SStefano Zampini case 1: 4788135c375SStefano Zampini break; 4798135c375SStefano Zampini case 2: 4808135c375SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"keys cmeeppppp\n");CHKERRQ(ierr); /* show colorbar, mesh and ranks */ 4818135c375SStefano Zampini break; 4828135c375SStefano Zampini case 3: /* TODO: decide default view in 3D */ 4838135c375SStefano Zampini break; 4848135c375SStefano Zampini } 4858135c375SStefano Zampini } else { 4868135c375SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"keys cm\n");CHKERRQ(ierr); /* show colorbar and mesh */ 4878135c375SStefano Zampini switch (dim) { 4888135c375SStefano Zampini case 1: 4898135c375SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"keys RRj\n");CHKERRQ(ierr); /* set to 1D (side view) and turn off perspective */ 4908135c375SStefano Zampini break; 4918135c375SStefano Zampini case 2: 4928135c375SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"keys Rjl\n");CHKERRQ(ierr); /* set to 2D (top view), turn off perspective and light */ 4938135c375SStefano Zampini break; 4948135c375SStefano Zampini case 3: 4958135c375SStefano Zampini break; 4968135c375SStefano Zampini } 4978135c375SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"autoscale value\n");CHKERRQ(ierr); /* update value-range; keep mesh-extents fixed */ 4988135c375SStefano Zampini if (info->pause == 0) { 4998135c375SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"pause\n");CHKERRQ(ierr); /* pause */ 5008135c375SStefano Zampini } 5018135c375SStefano Zampini } 5028135c375SStefano Zampini info->init = PETSC_TRUE; 5038135c375SStefano Zampini PetscFunctionReturn(0); 5048135c375SStefano Zampini } 5058135c375SStefano Zampini 5068135c375SStefano Zampini static PetscErrorCode PetscViewerDestroy_GLVis(PetscViewer viewer) 5078135c375SStefano Zampini { 5088135c375SStefano Zampini PetscViewerGLVis socket = (PetscViewerGLVis)viewer->data; 5098135c375SStefano Zampini PetscInt i; 5108135c375SStefano Zampini PetscErrorCode ierr; 5118135c375SStefano Zampini 5128135c375SStefano Zampini PetscFunctionBegin; 5138135c375SStefano Zampini for (i=0;i<socket->nwindow;i++) { 5148135c375SStefano Zampini ierr = PetscViewerDestroy(&socket->window[i]);CHKERRQ(ierr); 5158135c375SStefano Zampini ierr = PetscFree(socket->windowtitle[i]);CHKERRQ(ierr); 5168135c375SStefano Zampini ierr = PetscFree(socket->fec_type[i]);CHKERRQ(ierr); 5178135c375SStefano Zampini ierr = PetscObjectDestroy(&socket->Ufield[i]);CHKERRQ(ierr); 5188135c375SStefano Zampini } 5198135c375SStefano Zampini ierr = PetscFree(socket->name);CHKERRQ(ierr); 5204cac2994SStefano Zampini ierr = PetscFree5(socket->window,socket->windowtitle,socket->fec_type,socket->spacedim,socket->Ufield);CHKERRQ(ierr); 52177eacf09SStefano Zampini ierr = PetscFree(socket->fmt);CHKERRQ(ierr); 5228135c375SStefano Zampini ierr = PetscViewerDestroy(&socket->meshwindow);CHKERRQ(ierr); 5238135c375SStefano Zampini ierr = PetscObjectDestroy(&socket->dm);CHKERRQ(ierr); 5248135c375SStefano Zampini if (socket->destroyctx && socket->userctx) { ierr = (*socket->destroyctx)(socket->userctx);CHKERRQ(ierr); } 5258135c375SStefano Zampini 52677eacf09SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerGLVisSetPrecision_C",NULL);CHKERRQ(ierr); 5278135c375SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerGLVisSetSnapId_C",NULL);CHKERRQ(ierr); 5288135c375SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerGLVisSetFields_C",NULL);CHKERRQ(ierr); 5298135c375SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetName_C",NULL);CHKERRQ(ierr); 5308135c375SStefano Zampini ierr = PetscFree(socket);CHKERRQ(ierr); 5318135c375SStefano Zampini viewer->data = NULL; 5328135c375SStefano Zampini PetscFunctionReturn(0); 5338135c375SStefano Zampini } 5348135c375SStefano Zampini 5358135c375SStefano Zampini static PetscErrorCode PetscViewerSetFromOptions_GLVis(PetscOptionItems *PetscOptionsObject,PetscViewer v) 5368135c375SStefano Zampini { 5378135c375SStefano Zampini PetscErrorCode ierr; 5388135c375SStefano Zampini PetscViewerGLVis socket = (PetscViewerGLVis)v->data; 5398135c375SStefano Zampini 5408135c375SStefano Zampini PetscFunctionBegin; 5418135c375SStefano Zampini ierr = PetscOptionsHead(PetscOptionsObject,"GLVis PetscViewer Options");CHKERRQ(ierr); 5428135c375SStefano Zampini ierr = PetscOptionsReal("-viewer_glvis_pause","-1 to pause after each visualization, otherwise sleeps for given seconds",NULL,socket->pause,&socket->pause,NULL);CHKERRQ(ierr); 5438135c375SStefano Zampini ierr = PetscOptionsTail();CHKERRQ(ierr); 5448135c375SStefano Zampini PetscFunctionReturn(0); 5458135c375SStefano Zampini } 5468135c375SStefano Zampini 5478135c375SStefano Zampini static PetscErrorCode PetscViewerSetFileName_GLVis(PetscViewer viewer, const char name[]) 5488135c375SStefano Zampini { 5498135c375SStefano Zampini char *sport; 5508135c375SStefano Zampini PetscViewerGLVis socket = (PetscViewerGLVis)viewer->data; 5518135c375SStefano Zampini PetscErrorCode ierr; 5528135c375SStefano Zampini 5538135c375SStefano Zampini PetscFunctionBegin; 5548135c375SStefano Zampini socket->type = PETSC_VIEWER_GLVIS_DUMP; 5558135c375SStefano Zampini /* we accept localhost^port */ 5568135c375SStefano Zampini ierr = PetscFree(socket->name);CHKERRQ(ierr); 5578135c375SStefano Zampini ierr = PetscStrallocpy(name,&socket->name);CHKERRQ(ierr); 5588135c375SStefano Zampini ierr = PetscStrchr(socket->name,'^',&sport);CHKERRQ(ierr); 5598135c375SStefano Zampini if (sport) { 5608135c375SStefano Zampini PetscInt port = 19916; 5618135c375SStefano Zampini size_t len; 5628135c375SStefano Zampini 5638135c375SStefano Zampini *sport++ = 0; 5648135c375SStefano Zampini ierr = PetscStrlen(sport,&len);CHKERRQ(ierr); 5658135c375SStefano Zampini if (len) ierr = PetscOptionsStringToInt(sport,&port); 5668135c375SStefano Zampini if (!ierr) { 5678135c375SStefano Zampini socket->port = (port != PETSC_DECIDE && port != PETSC_DEFAULT) ? port : 19916; 5688135c375SStefano Zampini } else { 5698135c375SStefano Zampini socket->port = 19916; 5708135c375SStefano Zampini } 5718135c375SStefano Zampini socket->type = PETSC_VIEWER_GLVIS_SOCKET; 5728135c375SStefano Zampini } 5738135c375SStefano Zampini PetscFunctionReturn(0); 5748135c375SStefano Zampini } 5758135c375SStefano Zampini 5768135c375SStefano Zampini /* 5778135c375SStefano Zampini PetscViewerGLVisOpen - Opens a GLVis type viewer 5788135c375SStefano Zampini 5798135c375SStefano Zampini Collective on comm 5808135c375SStefano Zampini 5818135c375SStefano Zampini Input Parameters: 5828135c375SStefano Zampini + comm - the MPI communicator 5838135c375SStefano Zampini . type - the viewer type: PETSC_VIEWER_GLVIS_SOCKET for real-time visualization or PETSC_VIEWER_GLVIS_DUMP for dumping to disk 5848135c375SStefano Zampini . name - either the hostname where the GLVis server is running or the base filename for dumping the data for subsequent visualizations 5858135c375SStefano Zampini - port - socket port where the GLVis server is listening. Not referenced when type is PETSC_VIEWER_GLVIS_DUMP 5868135c375SStefano Zampini 5878135c375SStefano Zampini Output Parameters: 5888135c375SStefano Zampini - viewer - the PetscViewer object 5898135c375SStefano Zampini 5908135c375SStefano Zampini Notes: misses Fortran binding 5918135c375SStefano Zampini 5928135c375SStefano Zampini Level: beginner 5938135c375SStefano Zampini 5948135c375SStefano Zampini .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerGLVisType 5958135c375SStefano Zampini */ 5968135c375SStefano Zampini PETSC_EXTERN PetscErrorCode PetscViewerGLVisOpen(MPI_Comm comm, PetscViewerGLVisType type, const char* name, PetscInt port, PetscViewer* viewer) 5978135c375SStefano Zampini { 5988135c375SStefano Zampini PetscViewerGLVis socket; 5998135c375SStefano Zampini PetscErrorCode ierr; 6008135c375SStefano Zampini 6018135c375SStefano Zampini PetscFunctionBegin; 6028135c375SStefano Zampini ierr = PetscViewerCreate(comm,viewer);CHKERRQ(ierr); 6038135c375SStefano Zampini ierr = PetscViewerSetType(*viewer,PETSCVIEWERGLVIS);CHKERRQ(ierr); 6048135c375SStefano Zampini 6058135c375SStefano Zampini socket = (PetscViewerGLVis)((*viewer)->data); 606*a7bda6aaSStefano Zampini socket->type = type; 607*a7bda6aaSStefano Zampini if (type == PETSC_VIEWER_GLVIS_DUMP || name) { 60851f51421SSatish Balay ierr = PetscFree(socket->name);CHKERRQ(ierr); 6098135c375SStefano Zampini ierr = PetscStrallocpy(name,&socket->name);CHKERRQ(ierr); 610*a7bda6aaSStefano Zampini } 611*a7bda6aaSStefano Zampini socket->port = (!port || port == PETSC_DETERMINE || port == PETSC_DECIDE) ? 19916 : port; 6128135c375SStefano Zampini 6138135c375SStefano Zampini ierr = PetscViewerSetFromOptions(*viewer);CHKERRQ(ierr); 6148135c375SStefano Zampini PetscFunctionReturn(0); 6158135c375SStefano Zampini } 6168135c375SStefano Zampini 6178135c375SStefano Zampini /* 6188135c375SStefano Zampini PETSC_VIEWER_GLVIS_ - Creates an GLVIS PetscViewer shared by all processors in a communicator. 6198135c375SStefano Zampini 6208135c375SStefano Zampini Collective on MPI_Comm 6218135c375SStefano Zampini 6228135c375SStefano Zampini Input Parameter: 6238135c375SStefano Zampini . comm - the MPI communicator to share the GLVIS PetscViewer 6248135c375SStefano Zampini 6258135c375SStefano Zampini Level: intermediate 6268135c375SStefano Zampini 6278135c375SStefano Zampini Notes: misses Fortran bindings 6288135c375SStefano Zampini 6298135c375SStefano Zampini Environmental variables: 6308135c375SStefano Zampini + PETSC_VIEWER_GLVIS_FILENAME : output filename (if specified dump to disk, and takes precedence on PETSC_VIEWER_GLVIS_HOSTNAME) 6318135c375SStefano Zampini . PETSC_VIEWER_GLVIS_HOSTNAME : machine where the GLVis server is listening (defaults to localhost) 6328135c375SStefano Zampini - PETSC_VIEWER_GLVIS_PORT : port opened by the GLVis server (defaults to 19916) 6338135c375SStefano Zampini 6348135c375SStefano Zampini Notes: 6358135c375SStefano Zampini Unlike almost all other PETSc routines, PETSC_VIEWER_GLVIS_ does not return 6368135c375SStefano Zampini an error code. The GLVIS PetscViewer is usually used in the form 6378135c375SStefano Zampini $ XXXView(XXX object, PETSC_VIEWER_GLVIS_(comm)); 6388135c375SStefano Zampini 6398135c375SStefano Zampini .seealso: PetscViewerGLVISOpen(), PetscViewerGLVisType, PetscViewerCreate(), PetscViewerDestroy() 6408135c375SStefano Zampini */ 6418135c375SStefano Zampini PETSC_EXTERN PetscViewer PETSC_VIEWER_GLVIS_(MPI_Comm comm) 6428135c375SStefano Zampini { 6438135c375SStefano Zampini PetscErrorCode ierr; 6448135c375SStefano Zampini PetscBool flg; 6458135c375SStefano Zampini PetscViewer viewer; 6468135c375SStefano Zampini PetscViewerGLVisType type; 6478135c375SStefano Zampini char fname[PETSC_MAX_PATH_LEN],sport[16]; 6488135c375SStefano Zampini PetscInt port = 19916; /* default for GLVis */ 6498135c375SStefano Zampini 6508135c375SStefano Zampini PetscFunctionBegin; 6519d7c699cSSatish Balay ierr = PetscOptionsGetenv(comm,"PETSC_VIEWER_GLVIS_FILENAME",fname,PETSC_MAX_PATH_LEN,&flg); 6529d7c699cSSatish Balay if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_GLVIS_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 6538135c375SStefano Zampini if (!flg) { 6548135c375SStefano Zampini type = PETSC_VIEWER_GLVIS_SOCKET; 6558135c375SStefano Zampini ierr = PetscOptionsGetenv(comm,"PETSC_VIEWER_GLVIS_HOSTNAME",fname,PETSC_MAX_PATH_LEN,&flg); 6568135c375SStefano Zampini if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_GLVIS_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 6578135c375SStefano Zampini if (!flg) { 6588135c375SStefano Zampini ierr = PetscStrcpy(fname,"localhost"); 6598135c375SStefano Zampini if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_GLVIS_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 6608135c375SStefano Zampini } 6619d7c699cSSatish Balay ierr = PetscOptionsGetenv(comm,"PETSC_VIEWER_GLVIS_PORT",sport,16,&flg); 6629d7c699cSSatish Balay if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_GLVIS_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 6638135c375SStefano Zampini if (flg) { 6648135c375SStefano Zampini ierr = PetscOptionsStringToInt(sport,&port); 6658135c375SStefano Zampini if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_GLVIS_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 6668135c375SStefano Zampini } 6678135c375SStefano Zampini } else { 6688135c375SStefano Zampini type = PETSC_VIEWER_GLVIS_DUMP; 6698135c375SStefano Zampini } 6708135c375SStefano Zampini ierr = PetscViewerGLVisOpen(comm,type,fname,port,&viewer); 6718135c375SStefano Zampini if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_GLVIS_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 6728135c375SStefano Zampini ierr = PetscObjectRegisterDestroy((PetscObject)viewer); 6738135c375SStefano Zampini if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_GLVIS_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 6748135c375SStefano Zampini PetscFunctionReturn(viewer); 6758135c375SStefano Zampini } 6768135c375SStefano Zampini 6778135c375SStefano Zampini PETSC_EXTERN PetscErrorCode PetscViewerCreate_GLVis(PetscViewer viewer) 6788135c375SStefano Zampini { 6798135c375SStefano Zampini PetscViewerGLVis socket; 6808135c375SStefano Zampini PetscErrorCode ierr; 6818135c375SStefano Zampini 6828135c375SStefano Zampini PetscFunctionBegin; 6838135c375SStefano Zampini ierr = PetscNewLog(viewer,&socket);CHKERRQ(ierr); 6848135c375SStefano Zampini 6858135c375SStefano Zampini /* defaults to socket viewer */ 6868135c375SStefano Zampini ierr = PetscStrallocpy("localhost",&socket->name);CHKERRQ(ierr); 6878135c375SStefano Zampini socket->port = 19916; /* GLVis default listening port */ 6888135c375SStefano Zampini socket->type = PETSC_VIEWER_GLVIS_SOCKET; 6898135c375SStefano Zampini socket->pause = 0; /* just pause the first time */ 6908135c375SStefano Zampini 69177eacf09SStefano Zampini /* defaults to full precision */ 69277eacf09SStefano Zampini ierr = PetscStrallocpy(" %g",&socket->fmt);CHKERRQ(ierr); 69377eacf09SStefano Zampini 6948135c375SStefano Zampini viewer->data = (void*)socket; 6958135c375SStefano Zampini viewer->ops->destroy = PetscViewerDestroy_GLVis; 6968135c375SStefano Zampini viewer->ops->setfromoptions = PetscViewerSetFromOptions_GLVis; 6978135c375SStefano Zampini 69877eacf09SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerGLVisSetPrecision_C",PetscViewerGLVisSetPrecision_GLVis);CHKERRQ(ierr); 6998135c375SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerGLVisSetSnapId_C",PetscViewerGLVisSetSnapId_GLVis);CHKERRQ(ierr); 7008135c375SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerGLVisSetFields_C",PetscViewerGLVisSetFields_GLVis);CHKERRQ(ierr); 7018135c375SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetName_C",PetscViewerSetFileName_GLVis);CHKERRQ(ierr); 7028135c375SStefano Zampini PetscFunctionReturn(0); 7038135c375SStefano Zampini } 7048135c375SStefano Zampini 7058135c375SStefano Zampini /* this is a private implementation of a SOCKET with ASCII data format 7068135c375SStefano Zampini GLVis does not currently handle binary socket streams */ 7078135c375SStefano Zampini #if defined(PETSC_HAVE_UNISTD_H) 7088135c375SStefano Zampini #include <unistd.h> 7098135c375SStefano Zampini #endif 7108135c375SStefano Zampini 711150de0cbSStefano Zampini #if !defined(PETSC_HAVE_WINDOWS_H) 7128135c375SStefano Zampini static PetscErrorCode (*PetscViewerDestroy_ASCII)(PetscViewer); 7138135c375SStefano Zampini 7148135c375SStefano Zampini static PetscErrorCode PetscViewerDestroy_ASCII_Socket(PetscViewer viewer) 7158135c375SStefano Zampini { 7168135c375SStefano Zampini FILE *stream; 7178135c375SStefano Zampini PetscErrorCode ierr = 0; 7188135c375SStefano Zampini PetscFunctionBegin; 7198135c375SStefano Zampini ierr = PetscViewerASCIIGetPointer(viewer,&stream);CHKERRQ(ierr); 7208135c375SStefano Zampini if (stream) { 7218135c375SStefano Zampini ierr = fclose(stream); 7228135c375SStefano Zampini if (ierr) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on stream"); 7238135c375SStefano Zampini } 7248135c375SStefano Zampini ierr = PetscViewerDestroy_ASCII(viewer);CHKERRQ(ierr); 7258135c375SStefano Zampini PetscFunctionReturn(0); 7268135c375SStefano Zampini } 72727e89126SStefano Zampini #endif 72811a4995dSStefano Zampini 7298135c375SStefano Zampini static PetscErrorCode PetscViewerASCIISocketOpen(MPI_Comm comm,const char* hostname,PetscInt port,PetscViewer* viewer) 7308135c375SStefano Zampini { 731150de0cbSStefano Zampini #if defined(PETSC_HAVE_WINDOWS_H) 73227e89126SStefano Zampini PetscFunctionBegin; 73327e89126SStefano Zampini SETERRQ(comm,PETSC_ERR_SUP,"Not implemented for Windows"); 73427e89126SStefano Zampini #else 7358135c375SStefano Zampini FILE *stream = NULL; 7368135c375SStefano Zampini int fd; 7378135c375SStefano Zampini PetscErrorCode ierr; 7388135c375SStefano Zampini 7398135c375SStefano Zampini PetscFunctionBegin; 7408135c375SStefano Zampini PetscValidPointer(hostname,2); 7418135c375SStefano Zampini PetscValidPointer(viewer,4); 742c891a504SStefano Zampini #if defined(PETSC_USE_SOCKET_VIEWER) 7438135c375SStefano Zampini ierr = PetscOpenSocket(hostname,port,&fd); 744c891a504SStefano Zampini #else 745c891a504SStefano Zampini SETERRQ(comm,PETSC_ERR_SUP,"Missing Socket viewer"); 746c891a504SStefano Zampini #endif 7478135c375SStefano Zampini if (ierr) { 7488135c375SStefano Zampini PetscInt sierr = ierr; 7498135c375SStefano Zampini char err[1024]; 7508135c375SStefano Zampini 7518135c375SStefano Zampini ierr = PetscSNPrintf(err,1024,"Cannot connect to socket on %s:%D. Socket visualization is disabled\n",hostname,port);CHKERRQ(ierr); 7528135c375SStefano Zampini ierr = PetscInfo(NULL,err);CHKERRQ(ierr); 7538135c375SStefano Zampini *viewer = NULL; 7548135c375SStefano Zampini PetscFunctionReturn(sierr); 7558135c375SStefano Zampini } else { 7568135c375SStefano Zampini char msg[1024]; 7578135c375SStefano Zampini 7588135c375SStefano Zampini ierr = PetscSNPrintf(msg,1024,"Successfully connect to socket on %s:%D. Socket visualization is enabled\n",hostname,port);CHKERRQ(ierr); 7598135c375SStefano Zampini ierr = PetscInfo(NULL,msg);CHKERRQ(ierr); 7608135c375SStefano Zampini } 7618135c375SStefano Zampini stream = fdopen(fd,"w"); /* Not possible on Windows */ 7628135c375SStefano Zampini if (!stream) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SYS,"Cannot open stream from socket %s:%d",hostname,port); 7638135c375SStefano Zampini ierr = PetscViewerASCIIOpenWithFILE(PETSC_COMM_SELF,stream,viewer);CHKERRQ(ierr); 7648135c375SStefano Zampini PetscViewerDestroy_ASCII = (*viewer)->ops->destroy; 7658135c375SStefano Zampini (*viewer)->ops->destroy = PetscViewerDestroy_ASCII_Socket; 76627e89126SStefano Zampini #endif 7678135c375SStefano Zampini PetscFunctionReturn(0); 7688135c375SStefano Zampini } 769