1*8135c375SStefano Zampini #include <petsc/private/viewerimpl.h> /*I "petscviewer.h" I*/ 2*8135c375SStefano Zampini #include <petsc/private/petscimpl.h> /*I "petscsys.h" I*/ 3*8135c375SStefano Zampini #include <petsc/private/glvisviewerimpl.h> 4*8135c375SStefano Zampini 5*8135c375SStefano Zampini /* we may eventually make this function public */ 6*8135c375SStefano Zampini static PetscErrorCode PetscViewerASCIISocketOpen(MPI_Comm,const char*,PetscInt,PetscViewer*); 7*8135c375SStefano Zampini 8*8135c375SStefano Zampini struct _n_PetscViewerGLVis { 9*8135c375SStefano Zampini PetscViewerGLVisStatus status; 10*8135c375SStefano Zampini PetscViewerGLVisType type; /* either PETSC_VIEWER_GLVIS_DUMP or PETSC_VIEWER_GLVIS_SOCKET */ 11*8135c375SStefano Zampini char *name; /* prefix for filename, or hostname, depending on the type */ 12*8135c375SStefano Zampini PetscInt port; /* used just for the socket case */ 13*8135c375SStefano Zampini PetscReal pause; /* if positive, calls PetscSleep(pause) after each VecView_GLVis call */ 14*8135c375SStefano Zampini PetscViewer meshwindow; /* used just by the ASCII dumping */ 15*8135c375SStefano Zampini PetscObject dm; /* DM as passed by PetscViewerGLVisSetDM_Private(): should contain discretization info */ 16*8135c375SStefano Zampini PetscInt nwindow; /* number of windows/fields to be visualized */ 17*8135c375SStefano Zampini PetscViewer *window; 18*8135c375SStefano Zampini char **windowtitle; 19*8135c375SStefano Zampini char **fec_type; /* type of elements to be used for visualization, see FiniteElementCollection::Name() */ 20*8135c375SStefano Zampini PetscErrorCode (*g2lfield)(PetscObject,PetscInt,PetscObject[],void*); /* global to local operation for generating dofs to be visualized */ 21*8135c375SStefano Zampini PetscInt *locandbs; /* local and block sizes for work vectors */ 22*8135c375SStefano Zampini PetscObject *Ufield; /* work vectors for visualization */ 23*8135c375SStefano Zampini PetscInt snapid; /* snapshot id, use PetscViewerGLVisSetSnapId to change this value*/ 24*8135c375SStefano Zampini void *userctx; /* User context, used by g2lfield */ 25*8135c375SStefano Zampini PetscErrorCode (*destroyctx)(void*); /* destroy routine for userctx */ 26*8135c375SStefano Zampini }; 27*8135c375SStefano Zampini typedef struct _n_PetscViewerGLVis *PetscViewerGLVis; 28*8135c375SStefano Zampini 29*8135c375SStefano Zampini /*@ 30*8135c375SStefano Zampini PetscViewerGLVisSetSnapId - Set the snapshot id. Only relevant when the viewer is of type PETSC_VIEWER_GLVIS_DUMP 31*8135c375SStefano Zampini 32*8135c375SStefano Zampini Logically Collective on PetscViewer 33*8135c375SStefano Zampini 34*8135c375SStefano Zampini Input Parameters: 35*8135c375SStefano Zampini + viewer - the PetscViewer 36*8135c375SStefano Zampini - id - the current snapshot id in a time-dependent simulation 37*8135c375SStefano Zampini 38*8135c375SStefano Zampini Level: beginner 39*8135c375SStefano Zampini 40*8135c375SStefano Zampini .seealso: PetscViewerGLVisOpen(), PetscViewerCreate(), PetscViewerSetType() 41*8135c375SStefano Zampini @*/ 42*8135c375SStefano Zampini PetscErrorCode PetscViewerGLVisSetSnapId(PetscViewer viewer, PetscInt id) 43*8135c375SStefano Zampini { 44*8135c375SStefano Zampini PetscErrorCode ierr; 45*8135c375SStefano Zampini 46*8135c375SStefano Zampini PetscFunctionBegin; 47*8135c375SStefano Zampini PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 48*8135c375SStefano Zampini PetscValidLogicalCollectiveInt(viewer,id,2); 49*8135c375SStefano Zampini ierr = PetscTryMethod(viewer,"PetscViewerGLVisSetSnapId_C",(PetscViewer,PetscInt),(viewer,id));CHKERRQ(ierr); 50*8135c375SStefano Zampini PetscFunctionReturn(0); 51*8135c375SStefano Zampini } 52*8135c375SStefano Zampini 53*8135c375SStefano Zampini static PetscErrorCode PetscViewerGLVisSetSnapId_GLVis(PetscViewer viewer, PetscInt id) 54*8135c375SStefano Zampini { 55*8135c375SStefano Zampini PetscViewerGLVis socket = (PetscViewerGLVis)viewer->data; 56*8135c375SStefano Zampini 57*8135c375SStefano Zampini PetscFunctionBegin; 58*8135c375SStefano Zampini socket->snapid = id;; 59*8135c375SStefano Zampini PetscFunctionReturn(0); 60*8135c375SStefano Zampini } 61*8135c375SStefano Zampini 62*8135c375SStefano Zampini /* 63*8135c375SStefano Zampini PetscViewerGLVisSetFields - Sets the required information to visualize different fields from within a vector. 64*8135c375SStefano Zampini 65*8135c375SStefano Zampini Logically Collective on PetscViewer 66*8135c375SStefano Zampini 67*8135c375SStefano Zampini Input Parameters: 68*8135c375SStefano Zampini + viewer - the PetscViewer 69*8135c375SStefano Zampini . nf - number of fields to be visualized 70*8135c375SStefano Zampini . namefield - optional name for each field 71*8135c375SStefano Zampini . fec_type - the type of finite element to be used to visualize the data (see FiniteElementCollection::Name() in MFEM) 72*8135c375SStefano Zampini . nlocal - array of local sizes for field vectors (can be NULL if nf == 1) 73*8135c375SStefano Zampini . bs - array of block sizes for field vectors (can be NULL if nf == 1) 74*8135c375SStefano Zampini . g2lfields - User routine to compute the local field vectors to be visualized; PetscObject is used in place of Vec on the prototype 75*8135c375SStefano Zampini . ctx - User context to store the relevant data to apply g2lfields 76*8135c375SStefano Zampini - destroyctx - Destroy function for userctx 77*8135c375SStefano Zampini 78*8135c375SStefano Zampini Notes: g2lfields is called on the Vec V to be visualized, in order to extract the relevant dofs to be put in Vfield[], as 79*8135c375SStefano Zampini .vb 80*8135c375SStefano Zampini g2lfields((PetscObject)V,nfields,(PetscObject*)Vfield[],ctx). Misses Fortran binding 81*8135c375SStefano Zampini .ve 82*8135c375SStefano Zampini 83*8135c375SStefano Zampini Level: intermediate 84*8135c375SStefano Zampini 85*8135c375SStefano Zampini .seealso: PetscViewerGLVisOpen(), PetscViewerCreate(), PetscViewerSetType() 86*8135c375SStefano Zampini */ 87*8135c375SStefano Zampini PetscErrorCode PetscViewerGLVisSetFields(PetscViewer viewer, PetscInt nf, const char* namefield[], const char* fec_type[], PetscInt nlocal[], PetscInt bs[], PetscErrorCode(*g2l)(PetscObject,PetscInt,PetscObject[],void*), void* ctx, PetscErrorCode(*destroyctx)(void*)) 88*8135c375SStefano Zampini { 89*8135c375SStefano Zampini PetscErrorCode ierr; 90*8135c375SStefano Zampini 91*8135c375SStefano Zampini PetscFunctionBegin; 92*8135c375SStefano Zampini PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 93*8135c375SStefano Zampini PetscValidLogicalCollectiveInt(viewer,nf,2); 94*8135c375SStefano Zampini if (namefield) PetscValidPointer(namefield,3); 95*8135c375SStefano Zampini if (!fec_type) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"You need to provide the FiniteElementCollection names for the fields"); 96*8135c375SStefano Zampini PetscValidPointer(fec_type,4); 97*8135c375SStefano Zampini if (nf > 1) { 98*8135c375SStefano Zampini PetscValidPointer(nlocal,5); 99*8135c375SStefano Zampini PetscValidPointer(bs,6); 100*8135c375SStefano Zampini } 101*8135c375SStefano Zampini ierr = PetscTryMethod(viewer,"PetscViewerGLVisSetFields_C",(PetscViewer,PetscInt,const char*[],const char*[],PetscInt[],PetscInt[],PetscErrorCode(*)(PetscObject,PetscInt,PetscObject[],void*),void*,PetscErrorCode(*)(void*)),(viewer,nf,namefield,fec_type,nlocal,bs,g2l,ctx,destroyctx));CHKERRQ(ierr); 102*8135c375SStefano Zampini PetscFunctionReturn(0); 103*8135c375SStefano Zampini } 104*8135c375SStefano Zampini 105*8135c375SStefano Zampini static PetscErrorCode PetscViewerGLVisSetFields_GLVis(PetscViewer viewer, PetscInt nfields, const char* namefield[], const char* fec_type[], PetscInt nlocal[], PetscInt bs[], PetscErrorCode(*g2l)(PetscObject,PetscInt,PetscObject[],void*),void* ctx, PetscErrorCode(*destroyctx)(void*)) 106*8135c375SStefano Zampini { 107*8135c375SStefano Zampini PetscViewerGLVis socket = (PetscViewerGLVis)viewer->data; 108*8135c375SStefano Zampini PetscInt i; 109*8135c375SStefano Zampini PetscErrorCode ierr; 110*8135c375SStefano Zampini 111*8135c375SStefano Zampini PetscFunctionBegin; 112*8135c375SStefano 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); 113*8135c375SStefano Zampini if (!socket->nwindow) { 114*8135c375SStefano Zampini socket->nwindow = nfields; 115*8135c375SStefano Zampini 116*8135c375SStefano Zampini ierr = PetscCalloc5(nfields,&socket->window,nfields,&socket->windowtitle,nfields,&socket->fec_type,2*nfields,&socket->locandbs,nfields,&socket->Ufield);CHKERRQ(ierr); 117*8135c375SStefano Zampini for (i=0;i<nfields;i++) { 118*8135c375SStefano Zampini if (!namefield || !namefield[i]) { 119*8135c375SStefano Zampini char name[16]; 120*8135c375SStefano Zampini 121*8135c375SStefano Zampini ierr = PetscSNPrintf(name,16,"Field%d",i);CHKERRQ(ierr); 122*8135c375SStefano Zampini ierr = PetscStrallocpy(name,&socket->windowtitle[i]);CHKERRQ(ierr); 123*8135c375SStefano Zampini } else { 124*8135c375SStefano Zampini ierr = PetscStrallocpy(namefield[i],&socket->windowtitle[i]);CHKERRQ(ierr); 125*8135c375SStefano Zampini } 126*8135c375SStefano Zampini ierr = PetscStrallocpy(fec_type[i],&socket->fec_type[i]);CHKERRQ(ierr); 127*8135c375SStefano Zampini socket->locandbs[2*i ] = nlocal[i]; 128*8135c375SStefano Zampini socket->locandbs[2*i+1] = bs[i]; 129*8135c375SStefano Zampini } 130*8135c375SStefano Zampini } 131*8135c375SStefano Zampini /* number of fields are not allowed to vary */ 132*8135c375SStefano Zampini if (nfields != socket->nwindow) SETERRQ2(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Cannot visualize %D fields using %D socket windows",nfields,socket->nwindow); 133*8135c375SStefano Zampini socket->g2lfield = g2l; 134*8135c375SStefano Zampini if (socket->destroyctx && socket->userctx) { ierr = (*socket->destroyctx)(socket->userctx);CHKERRQ(ierr); } 135*8135c375SStefano Zampini socket->userctx = ctx; 136*8135c375SStefano Zampini socket->destroyctx = destroyctx; 137*8135c375SStefano Zampini PetscFunctionReturn(0); 138*8135c375SStefano Zampini } 139*8135c375SStefano Zampini 140*8135c375SStefano Zampini static PetscErrorCode PetscViewerGLVisInfoDestroy_Private(void *ptr) 141*8135c375SStefano Zampini { 142*8135c375SStefano Zampini PetscViewerGLVisInfo info = (PetscViewerGLVisInfo)ptr; 143*8135c375SStefano Zampini PetscErrorCode ierr; 144*8135c375SStefano Zampini 145*8135c375SStefano Zampini PetscFunctionBeginUser; 146*8135c375SStefano Zampini ierr = PetscFree(info);CHKERRQ(ierr); 147*8135c375SStefano Zampini PetscFunctionReturn(0); 148*8135c375SStefano Zampini } 149*8135c375SStefano Zampini 150*8135c375SStefano Zampini /* we can decide to prevent specific processes from using the viewer */ 151*8135c375SStefano Zampini static PetscErrorCode PetscViewerGLVisAttachInfo_Private(PetscViewer viewer, PetscViewer window) 152*8135c375SStefano Zampini { 153*8135c375SStefano Zampini PetscViewerGLVis socket = (PetscViewerGLVis)viewer->data; 154*8135c375SStefano Zampini PetscErrorCode ierr; 155*8135c375SStefano Zampini PetscContainer container; 156*8135c375SStefano Zampini PetscViewerGLVisInfo info; 157*8135c375SStefano Zampini 158*8135c375SStefano Zampini PetscFunctionBeginUser; 159*8135c375SStefano Zampini ierr = PetscNew(&info);CHKERRQ(ierr); 160*8135c375SStefano Zampini info->enabled = PETSC_TRUE; 161*8135c375SStefano Zampini info->init = PETSC_FALSE; 162*8135c375SStefano Zampini info->pause = socket->pause; 163*8135c375SStefano Zampini ierr = PetscContainerCreate(PetscObjectComm((PetscObject)window),&container);CHKERRQ(ierr); 164*8135c375SStefano Zampini ierr = PetscContainerSetPointer(container,(void*)info);CHKERRQ(ierr); 165*8135c375SStefano Zampini ierr = PetscContainerSetUserDestroy(container,PetscViewerGLVisInfoDestroy_Private);CHKERRQ(ierr); 166*8135c375SStefano Zampini ierr = PetscObjectCompose((PetscObject)window,"_glvis_info_container",(PetscObject)container);CHKERRQ(ierr); 167*8135c375SStefano Zampini ierr = PetscContainerDestroy(&container);CHKERRQ(ierr); 168*8135c375SStefano Zampini PetscFunctionReturn(0); 169*8135c375SStefano Zampini } 170*8135c375SStefano Zampini 171*8135c375SStefano Zampini static PetscErrorCode PetscViewerGLVisGetNewWindow_Private(PetscViewer viewer,PetscViewer *view) 172*8135c375SStefano Zampini { 173*8135c375SStefano Zampini PetscViewerGLVis socket = (PetscViewerGLVis)viewer->data; 174*8135c375SStefano Zampini PetscViewer window = NULL; 175*8135c375SStefano Zampini PetscBool ldis,dis; 176*8135c375SStefano Zampini PetscErrorCode ierr; 177*8135c375SStefano Zampini 178*8135c375SStefano Zampini PetscFunctionBegin; 179*8135c375SStefano Zampini ierr = PetscViewerASCIISocketOpen(PETSC_COMM_SELF,socket->name,socket->port,&window); 180*8135c375SStefano Zampini /* if we could not estabilish a connection the first time, 181*8135c375SStefano Zampini we disable the socket viewer */ 182*8135c375SStefano Zampini ldis = ierr ? PETSC_TRUE : PETSC_FALSE; 183*8135c375SStefano Zampini ierr = MPI_Allreduce(&ldis,&dis,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)viewer));CHKERRQ(ierr); 184*8135c375SStefano Zampini if (dis) { 185*8135c375SStefano Zampini socket->status = PETSCVIEWERGLVIS_DISABLED; 186*8135c375SStefano Zampini ierr = PetscViewerDestroy(&window);CHKERRQ(ierr); 187*8135c375SStefano Zampini } 188*8135c375SStefano Zampini *view = window; 189*8135c375SStefano Zampini PetscFunctionReturn(0); 190*8135c375SStefano Zampini } 191*8135c375SStefano Zampini 192*8135c375SStefano Zampini PetscErrorCode PetscViewerGLVisPause_Private(PetscViewer viewer) 193*8135c375SStefano Zampini { 194*8135c375SStefano Zampini PetscViewerGLVis socket = (PetscViewerGLVis)viewer->data; 195*8135c375SStefano Zampini PetscErrorCode ierr; 196*8135c375SStefano Zampini 197*8135c375SStefano Zampini PetscFunctionBegin; 198*8135c375SStefano Zampini if (socket->pause > 0) { 199*8135c375SStefano Zampini ierr = PetscSleep(socket->pause);CHKERRQ(ierr); 200*8135c375SStefano Zampini } 201*8135c375SStefano Zampini PetscFunctionReturn(0); 202*8135c375SStefano Zampini } 203*8135c375SStefano Zampini 204*8135c375SStefano Zampini /* DM specific support */ 205*8135c375SStefano Zampini PetscErrorCode PetscViewerGLVisSetDM_Private(PetscViewer viewer, PetscObject dm) 206*8135c375SStefano Zampini { 207*8135c375SStefano Zampini PetscErrorCode ierr; 208*8135c375SStefano Zampini PetscViewerGLVis socket = (PetscViewerGLVis)viewer->data; 209*8135c375SStefano Zampini 210*8135c375SStefano Zampini PetscFunctionBegin; 211*8135c375SStefano Zampini if (socket->dm && socket->dm != dm) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Cannot change DM associated with the GLVis viewer"); 212*8135c375SStefano Zampini if (!socket->dm) { 213*8135c375SStefano Zampini PetscErrorCode (*setupwithdm)(PetscObject,PetscViewer) = NULL; 214*8135c375SStefano Zampini 215*8135c375SStefano Zampini ierr = PetscObjectQueryFunction(dm,"DMSetUpGLVisViewer_C",&setupwithdm);CHKERRQ(ierr); 216*8135c375SStefano Zampini if (setupwithdm) { 217*8135c375SStefano Zampini ierr = (*setupwithdm)(dm,viewer);CHKERRQ(ierr); 218*8135c375SStefano Zampini } else SETERRQ1(PetscObjectComm(dm),PETSC_ERR_SUP,"No support for DM type %s",dm->type_name); 219*8135c375SStefano Zampini ierr = PetscObjectReference(dm);CHKERRQ(ierr); 220*8135c375SStefano Zampini socket->dm = dm; 221*8135c375SStefano Zampini } 222*8135c375SStefano Zampini PetscFunctionReturn(0); 223*8135c375SStefano Zampini } 224*8135c375SStefano Zampini 225*8135c375SStefano Zampini PetscErrorCode PetscViewerGLVisGetDMWindow_Private(PetscViewer viewer,PetscViewer* view) 226*8135c375SStefano Zampini { 227*8135c375SStefano Zampini PetscViewerGLVis socket = (PetscViewerGLVis)viewer->data; 228*8135c375SStefano Zampini PetscErrorCode ierr; 229*8135c375SStefano Zampini 230*8135c375SStefano Zampini PetscFunctionBegin; 231*8135c375SStefano Zampini if (!socket->meshwindow) { 232*8135c375SStefano Zampini if (socket->type == PETSC_VIEWER_GLVIS_SOCKET) { 233*8135c375SStefano Zampini ierr = PetscViewerGLVisGetNewWindow_Private(viewer,&socket->meshwindow);CHKERRQ(ierr); 234*8135c375SStefano Zampini } else { 235*8135c375SStefano Zampini PetscMPIInt rank; 236*8135c375SStefano Zampini char filename[PETSC_MAX_PATH_LEN]; 237*8135c375SStefano Zampini 238*8135c375SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr); 239*8135c375SStefano Zampini ierr = PetscSNPrintf(filename,PETSC_MAX_PATH_LEN,"%s-mesh.%06d",socket->name,rank);CHKERRQ(ierr); 240*8135c375SStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,filename,&socket->meshwindow);CHKERRQ(ierr); 241*8135c375SStefano Zampini } 242*8135c375SStefano Zampini if (socket->meshwindow) { 243*8135c375SStefano Zampini ierr = PetscViewerGLVisAttachInfo_Private(viewer,socket->meshwindow);CHKERRQ(ierr); 244*8135c375SStefano Zampini ierr = PetscViewerPushFormat(socket->meshwindow,PETSC_VIEWER_ASCII_GLVIS);CHKERRQ(ierr); 245*8135c375SStefano Zampini } 246*8135c375SStefano Zampini } 247*8135c375SStefano Zampini *view = socket->meshwindow; 248*8135c375SStefano Zampini PetscFunctionReturn(0); 249*8135c375SStefano Zampini } 250*8135c375SStefano Zampini 251*8135c375SStefano Zampini PetscErrorCode PetscViewerGLVisGetType_Private(PetscViewer viewer,PetscViewerGLVisType *type) 252*8135c375SStefano Zampini { 253*8135c375SStefano Zampini PetscViewerGLVis socket = (PetscViewerGLVis)viewer->data; 254*8135c375SStefano Zampini 255*8135c375SStefano Zampini PetscFunctionBegin; 256*8135c375SStefano Zampini PetscValidPointer(type,2); 257*8135c375SStefano Zampini *type = socket->type; 258*8135c375SStefano Zampini PetscFunctionReturn(0); 259*8135c375SStefano Zampini } 260*8135c375SStefano Zampini 261*8135c375SStefano 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 */ 262*8135c375SStefano Zampini PetscErrorCode PetscViewerGLVisGetStatus_Private(PetscViewer viewer, PetscViewerGLVisStatus *sockstatus) 263*8135c375SStefano Zampini { 264*8135c375SStefano Zampini PetscViewerGLVis socket = (PetscViewerGLVis)viewer->data; 265*8135c375SStefano Zampini 266*8135c375SStefano Zampini PetscFunctionBegin; 267*8135c375SStefano Zampini PetscValidPointer(sockstatus,2); 268*8135c375SStefano Zampini if (socket->type == PETSC_VIEWER_GLVIS_DUMP) { 269*8135c375SStefano Zampini socket->status = PETSCVIEWERGLVIS_DISCONNECTED; 270*8135c375SStefano Zampini } else if (socket->status == PETSCVIEWERGLVIS_DISCONNECTED && socket->nwindow) { 271*8135c375SStefano Zampini PetscInt i; 272*8135c375SStefano Zampini PetscBool lconn,conn; 273*8135c375SStefano Zampini PetscErrorCode ierr; 274*8135c375SStefano Zampini 275*8135c375SStefano Zampini for (i=0,lconn=PETSC_TRUE;i<socket->nwindow;i++) 276*8135c375SStefano Zampini if (!socket->window[i]) 277*8135c375SStefano Zampini lconn = PETSC_FALSE; 278*8135c375SStefano Zampini 279*8135c375SStefano Zampini ierr = MPI_Allreduce(&lconn,&conn,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)viewer));CHKERRQ(ierr); 280*8135c375SStefano Zampini if (conn) socket->status = PETSCVIEWERGLVIS_CONNECTED; 281*8135c375SStefano Zampini } 282*8135c375SStefano Zampini *sockstatus = socket->status; 283*8135c375SStefano Zampini PetscFunctionReturn(0); 284*8135c375SStefano Zampini } 285*8135c375SStefano Zampini 286*8135c375SStefano Zampini PetscErrorCode PetscViewerGLVisGetDM_Private(PetscViewer viewer, PetscObject* dm) 287*8135c375SStefano Zampini { 288*8135c375SStefano Zampini PetscViewerGLVis socket = (PetscViewerGLVis)viewer->data; 289*8135c375SStefano Zampini 290*8135c375SStefano Zampini PetscFunctionBegin; 291*8135c375SStefano Zampini *dm = socket->dm; 292*8135c375SStefano Zampini PetscFunctionReturn(0); 293*8135c375SStefano Zampini } 294*8135c375SStefano Zampini 295*8135c375SStefano Zampini PetscErrorCode PetscViewerGLVisGetFields_Private(PetscViewer viewer, PetscInt* nfield, const char** names[], const char **fec[], PetscInt *locandbs[], PetscErrorCode(**g2lfield)(PetscObject,PetscInt,PetscObject[],void*), PetscObject *Ufield[], void **userctx) 296*8135c375SStefano Zampini { 297*8135c375SStefano Zampini PetscViewerGLVis socket = (PetscViewerGLVis)viewer->data; 298*8135c375SStefano Zampini 299*8135c375SStefano Zampini PetscFunctionBegin; 300*8135c375SStefano Zampini if (nfield) *nfield = socket->nwindow; 301*8135c375SStefano Zampini if (names) *names = (const char**)socket->windowtitle; 302*8135c375SStefano Zampini if (fec) *fec = (const char**)socket->fec_type; 303*8135c375SStefano Zampini if (locandbs) *locandbs = socket->locandbs; 304*8135c375SStefano Zampini if (g2lfield) *g2lfield = socket->g2lfield; 305*8135c375SStefano Zampini if (Ufield) *Ufield = socket->Ufield; 306*8135c375SStefano Zampini if (userctx) *userctx = socket->userctx; 307*8135c375SStefano Zampini PetscFunctionReturn(0); 308*8135c375SStefano Zampini } 309*8135c375SStefano Zampini 310*8135c375SStefano Zampini /* accessor routines for the viewer windows: 311*8135c375SStefano Zampini PETSC_VIEWER_GLVIS_DUMP : it returns a new viewer every time 312*8135c375SStefano Zampini PETSC_VIEWER_GLVIS_SOCKET : it returns the socket, and creates it if not yet done. 313*8135c375SStefano Zampini */ 314*8135c375SStefano Zampini PetscErrorCode PetscViewerGLVisGetWindow_Private(PetscViewer viewer,PetscInt wid,PetscViewer* view) 315*8135c375SStefano Zampini { 316*8135c375SStefano Zampini PetscViewerGLVis socket = (PetscViewerGLVis)viewer->data; 317*8135c375SStefano Zampini PetscViewerGLVisStatus status; 318*8135c375SStefano Zampini PetscErrorCode ierr; 319*8135c375SStefano Zampini 320*8135c375SStefano Zampini PetscFunctionBegin; 321*8135c375SStefano Zampini PetscValidLogicalCollectiveInt(viewer,wid,2); 322*8135c375SStefano Zampini PetscValidPointer(view,3); 323*8135c375SStefano 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); 324*8135c375SStefano Zampini status = socket->status; 325*8135c375SStefano 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); 326*8135c375SStefano Zampini switch (status) { 327*8135c375SStefano Zampini case PETSCVIEWERGLVIS_DISCONNECTED: 328*8135c375SStefano Zampini if (socket->window[wid]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"This should not happen"); 329*8135c375SStefano Zampini if (socket->type == PETSC_VIEWER_GLVIS_DUMP) { 330*8135c375SStefano Zampini PetscMPIInt rank; 331*8135c375SStefano Zampini char filename[PETSC_MAX_PATH_LEN]; 332*8135c375SStefano Zampini 333*8135c375SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr); 334*8135c375SStefano Zampini ierr = PetscSNPrintf(filename,PETSC_MAX_PATH_LEN,"%s-%s-%d.%06d",socket->name,socket->windowtitle[wid],socket->snapid,rank);CHKERRQ(ierr); 335*8135c375SStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,filename,&socket->window[wid]);CHKERRQ(ierr); 336*8135c375SStefano Zampini } else { 337*8135c375SStefano Zampini ierr = PetscViewerGLVisGetNewWindow_Private(viewer,&socket->window[wid]);CHKERRQ(ierr); 338*8135c375SStefano Zampini } 339*8135c375SStefano Zampini if (socket->window[wid]) { 340*8135c375SStefano Zampini ierr = PetscViewerGLVisAttachInfo_Private(viewer,socket->window[wid]);CHKERRQ(ierr); 341*8135c375SStefano Zampini ierr = PetscViewerPushFormat(socket->window[wid],PETSC_VIEWER_ASCII_GLVIS);CHKERRQ(ierr); 342*8135c375SStefano Zampini } 343*8135c375SStefano Zampini *view = socket->window[wid]; 344*8135c375SStefano Zampini break; 345*8135c375SStefano Zampini case PETSCVIEWERGLVIS_CONNECTED: 346*8135c375SStefano Zampini *view = socket->window[wid]; 347*8135c375SStefano Zampini break; 348*8135c375SStefano Zampini case PETSCVIEWERGLVIS_DISABLED: 349*8135c375SStefano Zampini *view = NULL; 350*8135c375SStefano Zampini break; 351*8135c375SStefano Zampini default: 352*8135c375SStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Unhandled socket status %d\n",(int)status); 353*8135c375SStefano Zampini break; 354*8135c375SStefano Zampini } 355*8135c375SStefano Zampini PetscFunctionReturn(0); 356*8135c375SStefano Zampini } 357*8135c375SStefano Zampini 358*8135c375SStefano Zampini /* Restore the window viewer 359*8135c375SStefano Zampini PETSC_VIEWER_GLVIS_DUMP : destroys the temporary created ASCII viewer used for dumping 360*8135c375SStefano Zampini PETSC_VIEWER_GLVIS_SOCKET: - if the returned window viewer is not NULL, just zeros the pointer. 361*8135c375SStefano Zampini - it the returned window viewer is NULL, assumes something went wrong 362*8135c375SStefano Zampini with the socket (i.e. SIGPIPE when a user closes the popup window) 363*8135c375SStefano Zampini and that the caller already handled it (see VecView_GLVis). 364*8135c375SStefano Zampini */ 365*8135c375SStefano Zampini PetscErrorCode PetscViewerGLVisRestoreWindow_Private(PetscViewer viewer,PetscInt wid, PetscViewer* view) 366*8135c375SStefano Zampini { 367*8135c375SStefano Zampini PetscViewerGLVis socket = (PetscViewerGLVis)viewer->data; 368*8135c375SStefano Zampini PetscErrorCode ierr; 369*8135c375SStefano Zampini 370*8135c375SStefano Zampini PetscFunctionBegin; 371*8135c375SStefano Zampini PetscValidLogicalCollectiveInt(viewer,wid,2); 372*8135c375SStefano Zampini PetscValidPointer(view,3); 373*8135c375SStefano 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); 374*8135c375SStefano Zampini if (*view && *view != socket->window[wid]) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_USER,"Viewer was not obtained from PetscViewerGLVisGetWindow"); 375*8135c375SStefano Zampini if (*view) { 376*8135c375SStefano Zampini ierr = PetscViewerFlush(*view);CHKERRQ(ierr); 377*8135c375SStefano Zampini ierr = PetscBarrier((PetscObject)viewer);CHKERRQ(ierr); 378*8135c375SStefano Zampini } 379*8135c375SStefano Zampini if (socket->type == PETSC_VIEWER_GLVIS_DUMP) { /* destroy the viewer, as it is associated with a single time step */ 380*8135c375SStefano Zampini ierr = PetscViewerDestroy(&socket->window[wid]);CHKERRQ(ierr); 381*8135c375SStefano Zampini } else if (!*view) { /* something went wrong (SIGPIPE) so we just zero the private pointer */ 382*8135c375SStefano Zampini socket->window[wid] = NULL; 383*8135c375SStefano Zampini } 384*8135c375SStefano Zampini *view = NULL; 385*8135c375SStefano Zampini PetscFunctionReturn(0); 386*8135c375SStefano Zampini } 387*8135c375SStefano Zampini 388*8135c375SStefano Zampini /* default window appearance in the PETSC_VIEWER_GLVIS_SOCKET case */ 389*8135c375SStefano Zampini PetscErrorCode PetscViewerGLVisInitWindow_Private(PetscViewer viewer, PetscBool mesh, PetscInt dim, const char *name) 390*8135c375SStefano Zampini { 391*8135c375SStefano Zampini PetscErrorCode ierr; 392*8135c375SStefano Zampini PetscViewerGLVisInfo info; 393*8135c375SStefano Zampini PetscContainer container; 394*8135c375SStefano Zampini 395*8135c375SStefano Zampini PetscFunctionBegin; 396*8135c375SStefano Zampini ierr = PetscObjectQuery((PetscObject)viewer,"_glvis_info_container",(PetscObject*)&container);CHKERRQ(ierr); 397*8135c375SStefano Zampini if (!container) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Viewer was not obtained from PetscGLVisViewerGetNewWindow_Private"); 398*8135c375SStefano Zampini ierr = PetscContainerGetPointer(container,(void**)&info);CHKERRQ(ierr); 399*8135c375SStefano Zampini if (info->init) { 400*8135c375SStefano Zampini if (info->pause < 0) { 401*8135c375SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"pause\n");CHKERRQ(ierr); /* pause */ 402*8135c375SStefano Zampini } 403*8135c375SStefano Zampini PetscFunctionReturn(0); 404*8135c375SStefano Zampini } 405*8135c375SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"window_size 800 800\n");CHKERRQ(ierr); 406*8135c375SStefano Zampini if (name) { 407*8135c375SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"window_title '%s'\n",name);CHKERRQ(ierr); 408*8135c375SStefano Zampini } 409*8135c375SStefano Zampini if (mesh) { 410*8135c375SStefano Zampini switch (dim) { 411*8135c375SStefano Zampini case 1: 412*8135c375SStefano Zampini break; 413*8135c375SStefano Zampini case 2: 414*8135c375SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"keys cmeeppppp\n");CHKERRQ(ierr); /* show colorbar, mesh and ranks */ 415*8135c375SStefano Zampini break; 416*8135c375SStefano Zampini case 3: /* TODO: decide default view in 3D */ 417*8135c375SStefano Zampini break; 418*8135c375SStefano Zampini } 419*8135c375SStefano Zampini } else { 420*8135c375SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"keys cm\n");CHKERRQ(ierr); /* show colorbar and mesh */ 421*8135c375SStefano Zampini switch (dim) { 422*8135c375SStefano Zampini case 1: 423*8135c375SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"keys RRj\n");CHKERRQ(ierr); /* set to 1D (side view) and turn off perspective */ 424*8135c375SStefano Zampini break; 425*8135c375SStefano Zampini case 2: 426*8135c375SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"keys Rjl\n");CHKERRQ(ierr); /* set to 2D (top view), turn off perspective and light */ 427*8135c375SStefano Zampini break; 428*8135c375SStefano Zampini case 3: 429*8135c375SStefano Zampini break; 430*8135c375SStefano Zampini } 431*8135c375SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"autoscale value\n");CHKERRQ(ierr); /* update value-range; keep mesh-extents fixed */ 432*8135c375SStefano Zampini if (info->pause == 0) { 433*8135c375SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"pause\n");CHKERRQ(ierr); /* pause */ 434*8135c375SStefano Zampini } 435*8135c375SStefano Zampini } 436*8135c375SStefano Zampini info->init = PETSC_TRUE; 437*8135c375SStefano Zampini PetscFunctionReturn(0); 438*8135c375SStefano Zampini } 439*8135c375SStefano Zampini 440*8135c375SStefano Zampini static PetscErrorCode PetscViewerDestroy_GLVis(PetscViewer viewer) 441*8135c375SStefano Zampini { 442*8135c375SStefano Zampini PetscViewerGLVis socket = (PetscViewerGLVis)viewer->data; 443*8135c375SStefano Zampini PetscInt i; 444*8135c375SStefano Zampini PetscErrorCode ierr; 445*8135c375SStefano Zampini 446*8135c375SStefano Zampini PetscFunctionBegin; 447*8135c375SStefano Zampini for (i=0;i<socket->nwindow;i++) { 448*8135c375SStefano Zampini ierr = PetscViewerDestroy(&socket->window[i]);CHKERRQ(ierr); 449*8135c375SStefano Zampini ierr = PetscFree(socket->windowtitle[i]);CHKERRQ(ierr); 450*8135c375SStefano Zampini ierr = PetscFree(socket->fec_type[i]);CHKERRQ(ierr); 451*8135c375SStefano Zampini ierr = PetscObjectDestroy(&socket->Ufield[i]);CHKERRQ(ierr); 452*8135c375SStefano Zampini } 453*8135c375SStefano Zampini ierr = PetscFree(socket->name);CHKERRQ(ierr); 454*8135c375SStefano Zampini ierr = PetscFree5(socket->window,socket->windowtitle,socket->fec_type,socket->locandbs,socket->Ufield);CHKERRQ(ierr); 455*8135c375SStefano Zampini ierr = PetscViewerDestroy(&socket->meshwindow);CHKERRQ(ierr); 456*8135c375SStefano Zampini ierr = PetscObjectDestroy(&socket->dm);CHKERRQ(ierr); 457*8135c375SStefano Zampini if (socket->destroyctx && socket->userctx) { ierr = (*socket->destroyctx)(socket->userctx);CHKERRQ(ierr); } 458*8135c375SStefano Zampini 459*8135c375SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerGLVisSetSnapId_C",NULL);CHKERRQ(ierr); 460*8135c375SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerGLVisSetFields_C",NULL);CHKERRQ(ierr); 461*8135c375SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetName_C",NULL);CHKERRQ(ierr); 462*8135c375SStefano Zampini ierr = PetscFree(socket);CHKERRQ(ierr); 463*8135c375SStefano Zampini viewer->data = NULL; 464*8135c375SStefano Zampini PetscFunctionReturn(0); 465*8135c375SStefano Zampini } 466*8135c375SStefano Zampini 467*8135c375SStefano Zampini static PetscErrorCode PetscViewerSetFromOptions_GLVis(PetscOptionItems *PetscOptionsObject,PetscViewer v) 468*8135c375SStefano Zampini { 469*8135c375SStefano Zampini PetscErrorCode ierr; 470*8135c375SStefano Zampini PetscViewerGLVis socket = (PetscViewerGLVis)v->data; 471*8135c375SStefano Zampini 472*8135c375SStefano Zampini PetscFunctionBegin; 473*8135c375SStefano Zampini ierr = PetscOptionsHead(PetscOptionsObject,"GLVis PetscViewer Options");CHKERRQ(ierr); 474*8135c375SStefano 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); 475*8135c375SStefano Zampini ierr = PetscOptionsTail();CHKERRQ(ierr); 476*8135c375SStefano Zampini PetscFunctionReturn(0); 477*8135c375SStefano Zampini } 478*8135c375SStefano Zampini 479*8135c375SStefano Zampini static PetscErrorCode PetscViewerSetFileName_GLVis(PetscViewer viewer, const char name[]) 480*8135c375SStefano Zampini { 481*8135c375SStefano Zampini char *sport; 482*8135c375SStefano Zampini PetscViewerGLVis socket = (PetscViewerGLVis)viewer->data; 483*8135c375SStefano Zampini PetscErrorCode ierr; 484*8135c375SStefano Zampini 485*8135c375SStefano Zampini PetscFunctionBegin; 486*8135c375SStefano Zampini socket->type = PETSC_VIEWER_GLVIS_DUMP; 487*8135c375SStefano Zampini /* we accept localhost^port */ 488*8135c375SStefano Zampini ierr = PetscFree(socket->name);CHKERRQ(ierr); 489*8135c375SStefano Zampini ierr = PetscStrallocpy(name,&socket->name);CHKERRQ(ierr); 490*8135c375SStefano Zampini ierr = PetscStrchr(socket->name,'^',&sport);CHKERRQ(ierr); 491*8135c375SStefano Zampini if (sport) { 492*8135c375SStefano Zampini PetscInt port = 19916; 493*8135c375SStefano Zampini size_t len; 494*8135c375SStefano Zampini 495*8135c375SStefano Zampini *sport++ = 0; 496*8135c375SStefano Zampini ierr = PetscStrlen(sport,&len);CHKERRQ(ierr); 497*8135c375SStefano Zampini if (len) ierr = PetscOptionsStringToInt(sport,&port); 498*8135c375SStefano Zampini if (!ierr) { 499*8135c375SStefano Zampini socket->port = (port != PETSC_DECIDE && port != PETSC_DEFAULT) ? port : 19916; 500*8135c375SStefano Zampini } else { 501*8135c375SStefano Zampini socket->port = 19916; 502*8135c375SStefano Zampini } 503*8135c375SStefano Zampini socket->type = PETSC_VIEWER_GLVIS_SOCKET; 504*8135c375SStefano Zampini } 505*8135c375SStefano Zampini PetscFunctionReturn(0); 506*8135c375SStefano Zampini } 507*8135c375SStefano Zampini 508*8135c375SStefano Zampini /* 509*8135c375SStefano Zampini PetscViewerGLVisOpen - Opens a GLVis type viewer 510*8135c375SStefano Zampini 511*8135c375SStefano Zampini Collective on comm 512*8135c375SStefano Zampini 513*8135c375SStefano Zampini Input Parameters: 514*8135c375SStefano Zampini + comm - the MPI communicator 515*8135c375SStefano Zampini . type - the viewer type: PETSC_VIEWER_GLVIS_SOCKET for real-time visualization or PETSC_VIEWER_GLVIS_DUMP for dumping to disk 516*8135c375SStefano Zampini . name - either the hostname where the GLVis server is running or the base filename for dumping the data for subsequent visualizations 517*8135c375SStefano Zampini - port - socket port where the GLVis server is listening. Not referenced when type is PETSC_VIEWER_GLVIS_DUMP 518*8135c375SStefano Zampini 519*8135c375SStefano Zampini Output Parameters: 520*8135c375SStefano Zampini - viewer - the PetscViewer object 521*8135c375SStefano Zampini 522*8135c375SStefano Zampini Notes: misses Fortran binding 523*8135c375SStefano Zampini 524*8135c375SStefano Zampini Level: beginner 525*8135c375SStefano Zampini 526*8135c375SStefano Zampini .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerGLVisType 527*8135c375SStefano Zampini */ 528*8135c375SStefano Zampini PETSC_EXTERN PetscErrorCode PetscViewerGLVisOpen(MPI_Comm comm, PetscViewerGLVisType type, const char* name, PetscInt port, PetscViewer* viewer) 529*8135c375SStefano Zampini { 530*8135c375SStefano Zampini PetscViewerGLVis socket; 531*8135c375SStefano Zampini PetscErrorCode ierr; 532*8135c375SStefano Zampini 533*8135c375SStefano Zampini PetscFunctionBegin; 534*8135c375SStefano Zampini ierr = PetscViewerCreate(comm,viewer);CHKERRQ(ierr); 535*8135c375SStefano Zampini ierr = PetscViewerSetType(*viewer,PETSCVIEWERGLVIS);CHKERRQ(ierr); 536*8135c375SStefano Zampini 537*8135c375SStefano Zampini socket = (PetscViewerGLVis)((*viewer)->data); 538*8135c375SStefano Zampini ierr = PetscFree(socket->name); 539*8135c375SStefano Zampini ierr = PetscStrallocpy(name,&socket->name);CHKERRQ(ierr); 540*8135c375SStefano Zampini socket->type = type; 541*8135c375SStefano Zampini socket->port = port; 542*8135c375SStefano Zampini 543*8135c375SStefano Zampini ierr = PetscViewerSetFromOptions(*viewer);CHKERRQ(ierr); 544*8135c375SStefano Zampini PetscFunctionReturn(0); 545*8135c375SStefano Zampini } 546*8135c375SStefano Zampini 547*8135c375SStefano Zampini /* 548*8135c375SStefano Zampini PETSC_VIEWER_GLVIS_ - Creates an GLVIS PetscViewer shared by all processors in a communicator. 549*8135c375SStefano Zampini 550*8135c375SStefano Zampini Collective on MPI_Comm 551*8135c375SStefano Zampini 552*8135c375SStefano Zampini Input Parameter: 553*8135c375SStefano Zampini . comm - the MPI communicator to share the GLVIS PetscViewer 554*8135c375SStefano Zampini 555*8135c375SStefano Zampini Level: intermediate 556*8135c375SStefano Zampini 557*8135c375SStefano Zampini Notes: misses Fortran bindings 558*8135c375SStefano Zampini 559*8135c375SStefano Zampini Environmental variables: 560*8135c375SStefano Zampini + PETSC_VIEWER_GLVIS_FILENAME : output filename (if specified dump to disk, and takes precedence on PETSC_VIEWER_GLVIS_HOSTNAME) 561*8135c375SStefano Zampini . PETSC_VIEWER_GLVIS_HOSTNAME : machine where the GLVis server is listening (defaults to localhost) 562*8135c375SStefano Zampini - PETSC_VIEWER_GLVIS_PORT : port opened by the GLVis server (defaults to 19916) 563*8135c375SStefano Zampini 564*8135c375SStefano Zampini Notes: 565*8135c375SStefano Zampini Unlike almost all other PETSc routines, PETSC_VIEWER_GLVIS_ does not return 566*8135c375SStefano Zampini an error code. The GLVIS PetscViewer is usually used in the form 567*8135c375SStefano Zampini $ XXXView(XXX object, PETSC_VIEWER_GLVIS_(comm)); 568*8135c375SStefano Zampini 569*8135c375SStefano Zampini .seealso: PetscViewerGLVISOpen(), PetscViewerGLVisType, PetscViewerCreate(), PetscViewerDestroy() 570*8135c375SStefano Zampini */ 571*8135c375SStefano Zampini PETSC_EXTERN PetscViewer PETSC_VIEWER_GLVIS_(MPI_Comm comm) 572*8135c375SStefano Zampini { 573*8135c375SStefano Zampini PetscErrorCode ierr; 574*8135c375SStefano Zampini PetscBool flg; 575*8135c375SStefano Zampini PetscViewer viewer; 576*8135c375SStefano Zampini PetscViewerGLVisType type; 577*8135c375SStefano Zampini char fname[PETSC_MAX_PATH_LEN],sport[16]; 578*8135c375SStefano Zampini PetscInt port = 19916; /* default for GLVis */ 579*8135c375SStefano Zampini 580*8135c375SStefano Zampini PetscFunctionBegin; 581*8135c375SStefano Zampini ierr = PetscOptionsGetenv(comm,"PETSC_VIEWER_GLVIS_FILENAME",fname,PETSC_MAX_PATH_LEN,&flg); 582*8135c375SStefano Zampini if (!flg) { 583*8135c375SStefano Zampini type = PETSC_VIEWER_GLVIS_SOCKET; 584*8135c375SStefano Zampini ierr = PetscOptionsGetenv(comm,"PETSC_VIEWER_GLVIS_HOSTNAME",fname,PETSC_MAX_PATH_LEN,&flg); 585*8135c375SStefano Zampini if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_GLVIS_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 586*8135c375SStefano Zampini if (!flg) { 587*8135c375SStefano Zampini ierr = PetscStrcpy(fname,"localhost"); 588*8135c375SStefano Zampini if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_GLVIS_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 589*8135c375SStefano Zampini } 590*8135c375SStefano Zampini ierr = PetscOptionsGetenv(comm,"PETSC_VIEWER_GLVIS_PORT",sport,16,&flg); 591*8135c375SStefano Zampini if (flg) { 592*8135c375SStefano Zampini ierr = PetscOptionsStringToInt(sport,&port); 593*8135c375SStefano Zampini if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_GLVIS_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 594*8135c375SStefano Zampini } 595*8135c375SStefano Zampini } else { 596*8135c375SStefano Zampini type = PETSC_VIEWER_GLVIS_DUMP; 597*8135c375SStefano Zampini } 598*8135c375SStefano Zampini ierr = PetscViewerGLVisOpen(comm,type,fname,port,&viewer); 599*8135c375SStefano Zampini if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_GLVIS_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 600*8135c375SStefano Zampini ierr = PetscObjectRegisterDestroy((PetscObject)viewer); 601*8135c375SStefano Zampini if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_GLVIS_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 602*8135c375SStefano Zampini if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_GLVIS_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 603*8135c375SStefano Zampini PetscFunctionReturn(viewer); 604*8135c375SStefano Zampini } 605*8135c375SStefano Zampini 606*8135c375SStefano Zampini PETSC_EXTERN PetscErrorCode PetscViewerCreate_GLVis(PetscViewer viewer) 607*8135c375SStefano Zampini { 608*8135c375SStefano Zampini PetscViewerGLVis socket; 609*8135c375SStefano Zampini PetscErrorCode ierr; 610*8135c375SStefano Zampini 611*8135c375SStefano Zampini PetscFunctionBegin; 612*8135c375SStefano Zampini ierr = PetscNewLog(viewer,&socket);CHKERRQ(ierr); 613*8135c375SStefano Zampini 614*8135c375SStefano Zampini /* defaults to socket viewer */ 615*8135c375SStefano Zampini ierr = PetscStrallocpy("localhost",&socket->name);CHKERRQ(ierr); 616*8135c375SStefano Zampini socket->port = 19916; /* GLVis default listening port */ 617*8135c375SStefano Zampini socket->type = PETSC_VIEWER_GLVIS_SOCKET; 618*8135c375SStefano Zampini socket->pause = 0; /* just pause the first time */ 619*8135c375SStefano Zampini 620*8135c375SStefano Zampini viewer->data = (void*)socket; 621*8135c375SStefano Zampini viewer->ops->destroy = PetscViewerDestroy_GLVis; 622*8135c375SStefano Zampini viewer->ops->setfromoptions = PetscViewerSetFromOptions_GLVis; 623*8135c375SStefano Zampini 624*8135c375SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerGLVisSetSnapId_C",PetscViewerGLVisSetSnapId_GLVis);CHKERRQ(ierr); 625*8135c375SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerGLVisSetFields_C",PetscViewerGLVisSetFields_GLVis);CHKERRQ(ierr); 626*8135c375SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetName_C",PetscViewerSetFileName_GLVis);CHKERRQ(ierr); 627*8135c375SStefano Zampini PetscFunctionReturn(0); 628*8135c375SStefano Zampini } 629*8135c375SStefano Zampini 630*8135c375SStefano Zampini /* this is a private implementation of a SOCKET with ASCII data format 631*8135c375SStefano Zampini GLVis does not currently handle binary socket streams */ 632*8135c375SStefano Zampini #include <petsc/private/viewerimpl.h> 633*8135c375SStefano Zampini 634*8135c375SStefano Zampini #if defined(PETSC_HAVE_UNISTD_H) 635*8135c375SStefano Zampini #include <unistd.h> 636*8135c375SStefano Zampini #endif 637*8135c375SStefano Zampini 638*8135c375SStefano Zampini static PetscErrorCode (*PetscViewerDestroy_ASCII)(PetscViewer); 639*8135c375SStefano Zampini 640*8135c375SStefano Zampini static PetscErrorCode PetscViewerDestroy_ASCII_Socket(PetscViewer viewer) 641*8135c375SStefano Zampini { 642*8135c375SStefano Zampini FILE *stream; 643*8135c375SStefano Zampini PetscErrorCode ierr = 0; 644*8135c375SStefano Zampini PetscFunctionBegin; 645*8135c375SStefano Zampini ierr = PetscViewerASCIIGetPointer(viewer,&stream);CHKERRQ(ierr); 646*8135c375SStefano Zampini if (stream) { 647*8135c375SStefano Zampini ierr = fclose(stream); 648*8135c375SStefano Zampini if (ierr) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on stream"); 649*8135c375SStefano Zampini } 650*8135c375SStefano Zampini ierr = PetscViewerDestroy_ASCII(viewer);CHKERRQ(ierr); 651*8135c375SStefano Zampini PetscFunctionReturn(0); 652*8135c375SStefano Zampini } 653*8135c375SStefano Zampini 654*8135c375SStefano Zampini static PetscErrorCode PetscViewerASCIISocketOpen(MPI_Comm comm,const char* hostname,PetscInt port,PetscViewer* viewer) 655*8135c375SStefano Zampini { 656*8135c375SStefano Zampini FILE *stream = NULL; 657*8135c375SStefano Zampini int fd; 658*8135c375SStefano Zampini PetscErrorCode ierr; 659*8135c375SStefano Zampini 660*8135c375SStefano Zampini PetscFunctionBegin; 661*8135c375SStefano Zampini PetscValidPointer(hostname,2); 662*8135c375SStefano Zampini PetscValidPointer(viewer,4); 663*8135c375SStefano Zampini ierr = PetscOpenSocket(hostname,port,&fd); 664*8135c375SStefano Zampini if (ierr) { 665*8135c375SStefano Zampini PetscInt sierr = ierr; 666*8135c375SStefano Zampini char err[1024]; 667*8135c375SStefano Zampini 668*8135c375SStefano Zampini ierr = PetscSNPrintf(err,1024,"Cannot connect to socket on %s:%D. Socket visualization is disabled\n",hostname,port);CHKERRQ(ierr); 669*8135c375SStefano Zampini ierr = PetscInfo(NULL,err);CHKERRQ(ierr); 670*8135c375SStefano Zampini *viewer = NULL; 671*8135c375SStefano Zampini PetscFunctionReturn(sierr); 672*8135c375SStefano Zampini } else { 673*8135c375SStefano Zampini char msg[1024]; 674*8135c375SStefano Zampini 675*8135c375SStefano Zampini ierr = PetscSNPrintf(msg,1024,"Successfully connect to socket on %s:%D. Socket visualization is enabled\n",hostname,port);CHKERRQ(ierr); 676*8135c375SStefano Zampini ierr = PetscInfo(NULL,msg);CHKERRQ(ierr); 677*8135c375SStefano Zampini } 678*8135c375SStefano Zampini stream = fdopen(fd,"w"); /* Not possible on Windows */ 679*8135c375SStefano Zampini if (!stream) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SYS,"Cannot open stream from socket %s:%d",hostname,port); 680*8135c375SStefano Zampini ierr = PetscViewerASCIIOpenWithFILE(PETSC_COMM_SELF,stream,viewer);CHKERRQ(ierr); 681*8135c375SStefano Zampini PetscViewerDestroy_ASCII = (*viewer)->ops->destroy; 682*8135c375SStefano Zampini (*viewer)->ops->destroy = PetscViewerDestroy_ASCII_Socket; 683*8135c375SStefano Zampini PetscFunctionReturn(0); 684*8135c375SStefano Zampini } 685