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;
2173365f8bSLisandro Dalcin PetscInt windowsizes[2];
228135c375SStefano Zampini char **fec_type; /* type of elements to be used for visualization, see FiniteElementCollection::Name() */
238135c375SStefano Zampini PetscErrorCode (*g2lfield)(PetscObject, PetscInt, PetscObject[], void *); /* global to local operation for generating dofs to be visualized */
244cac2994SStefano Zampini PetscInt *spacedim; /* geometrical space dimension (just used to initialize the scene) */
258135c375SStefano Zampini PetscObject *Ufield; /* work vectors for visualization */
268135c375SStefano Zampini PetscInt snapid; /* snapshot id, use PetscViewerGLVisSetSnapId to change this value*/
272a8381b2SBarry Smith void *ctx; /* User context, used by g2lfield */
282a8381b2SBarry Smith PetscCtxDestroyFn *destroyctx; /* destroy routine for ctx */
2977eacf09SStefano Zampini char *fmt; /* format string for FP values */
308135c375SStefano Zampini };
318135c375SStefano Zampini typedef struct _n_PetscViewerGLVis *PetscViewerGLVis;
328135c375SStefano Zampini
338135c375SStefano Zampini /*@
34811af0c4SBarry Smith PetscViewerGLVisSetPrecision - Set the number of digits for floating point values to be displayed
3577eacf09SStefano Zampini
3677eacf09SStefano Zampini Not Collective
3777eacf09SStefano Zampini
3877eacf09SStefano Zampini Input Parameters:
39811af0c4SBarry Smith + viewer - the `PetscViewer` of type `PETSCVIEWERGLVIS`
4077eacf09SStefano Zampini - prec - the number of digits required
4177eacf09SStefano Zampini
4277eacf09SStefano Zampini Level: beginner
4377eacf09SStefano Zampini
44d1f92df0SBarry Smith .seealso: [](sec_viewers), `PETSCVIEWERGLVIS`, `PetscViewerGLVisOpen()`, `PetscViewerGLVisSetFields()`, `PetscViewerCreate()`, `PetscViewerSetType()`
4577eacf09SStefano Zampini @*/
PetscViewerGLVisSetPrecision(PetscViewer viewer,PetscInt prec)46d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerGLVisSetPrecision(PetscViewer viewer, PetscInt prec)
47d71ae5a4SJacob Faibussowitsch {
4877eacf09SStefano Zampini PetscFunctionBegin;
4977eacf09SStefano Zampini PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
50cac4c232SBarry Smith PetscTryMethod(viewer, "PetscViewerGLVisSetPrecision_C", (PetscViewer, PetscInt), (viewer, prec));
513ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
5277eacf09SStefano Zampini }
5377eacf09SStefano Zampini
PetscViewerGLVisSetPrecision_GLVis(PetscViewer viewer,PetscInt prec)54d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscViewerGLVisSetPrecision_GLVis(PetscViewer viewer, PetscInt prec)
55d71ae5a4SJacob Faibussowitsch {
5677eacf09SStefano Zampini PetscViewerGLVis socket = (PetscViewerGLVis)viewer->data;
5777eacf09SStefano Zampini
5877eacf09SStefano Zampini PetscFunctionBegin;
599566063dSJacob Faibussowitsch PetscCall(PetscFree(socket->fmt));
6077eacf09SStefano Zampini if (prec > 0) {
619566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(16, &socket->fmt));
629566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(socket->fmt, 16, " %%.%" PetscInt_FMT "e", prec));
6377eacf09SStefano Zampini } else {
649566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(" %g", &socket->fmt));
6577eacf09SStefano Zampini }
663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
6777eacf09SStefano Zampini }
6877eacf09SStefano Zampini
6977eacf09SStefano Zampini /*@
70811af0c4SBarry Smith PetscViewerGLVisSetSnapId - Set the snapshot id. Only relevant when the `PetscViewerGLVisType` is `PETSC_VIEWER_GLVIS_DUMP`
718135c375SStefano Zampini
72c3339decSBarry Smith Logically Collective
738135c375SStefano Zampini
748135c375SStefano Zampini Input Parameters:
75811af0c4SBarry Smith + viewer - the `PetscViewer` of type `PETSCVIEWERGLVIS`
768135c375SStefano Zampini - id - the current snapshot id in a time-dependent simulation
778135c375SStefano Zampini
788135c375SStefano Zampini Level: beginner
798135c375SStefano Zampini
80d1f92df0SBarry Smith .seealso: [](sec_viewers), `PETSCVIEWERGLVIS`, `PetscViewerGLVisOpen()`, `PetscViewerGLVisSetFields()`, `PetscViewerCreate()`, `PetscViewerSetType()`
818135c375SStefano Zampini @*/
PetscViewerGLVisSetSnapId(PetscViewer viewer,PetscInt id)82d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerGLVisSetSnapId(PetscViewer viewer, PetscInt id)
83d71ae5a4SJacob Faibussowitsch {
848135c375SStefano Zampini PetscFunctionBegin;
858135c375SStefano Zampini PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
868135c375SStefano Zampini PetscValidLogicalCollectiveInt(viewer, id, 2);
87cac4c232SBarry Smith PetscTryMethod(viewer, "PetscViewerGLVisSetSnapId_C", (PetscViewer, PetscInt), (viewer, id));
883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
898135c375SStefano Zampini }
908135c375SStefano Zampini
PetscViewerGLVisSetSnapId_GLVis(PetscViewer viewer,PetscInt id)91d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscViewerGLVisSetSnapId_GLVis(PetscViewer viewer, PetscInt id)
92d71ae5a4SJacob Faibussowitsch {
938135c375SStefano Zampini PetscViewerGLVis socket = (PetscViewerGLVis)viewer->data;
948135c375SStefano Zampini
958135c375SStefano Zampini PetscFunctionBegin;
9677eacf09SStefano Zampini socket->snapid = id;
973ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
988135c375SStefano Zampini }
998135c375SStefano Zampini
1004cac2994SStefano Zampini /*@C
1014cac2994SStefano Zampini PetscViewerGLVisSetFields - Sets the required information to visualize different fields from a vector.
1028135c375SStefano Zampini
103c3339decSBarry Smith Logically Collective
1048135c375SStefano Zampini
1058135c375SStefano Zampini Input Parameters:
106811af0c4SBarry Smith + viewer - the `PetscViewer` of type `PETSCVIEWERGLVIS`
1078135c375SStefano Zampini . nf - number of fields to be visualized
1088135c375SStefano Zampini . fec_type - the type of finite element to be used to visualize the data (see FiniteElementCollection::Name() in MFEM)
1094cac2994SStefano Zampini . dim - array of space dimension for field vectors (used to initialize the scene)
110aec76313SJacob Faibussowitsch . g2l - User routine to compute the local field vectors to be visualized; PetscObject is used in place of Vec on the prototype
1114cac2994SStefano Zampini . Vfield - array of work vectors, one for each field
1128135c375SStefano Zampini . ctx - User context to store the relevant data to apply g2lfields
1132a8381b2SBarry Smith - destroyctx - Destroy function for ctx
1148135c375SStefano Zampini
1153f423023SBarry Smith Level: intermediate
1163f423023SBarry Smith
11795452b02SPatrick Sanan Notes:
1183f423023SBarry Smith `g2lfields` is called on the vector V to be visualized in order to extract the relevant dofs to be put in `Vfield`, as
1198135c375SStefano Zampini .vb
1204cac2994SStefano Zampini g2lfields((PetscObject)V,nfields,(PetscObject*)Vfield[],ctx).
1218135c375SStefano Zampini .ve
122811af0c4SBarry Smith
1233f423023SBarry Smith For vector spaces, the block size of `Vfield`[i] represents the vector dimension.
1243f423023SBarry Smith The names of the `Vfield` vectors will be displayed in the window title.
1258135c375SStefano Zampini
126d1f92df0SBarry Smith .seealso: [](sec_viewers), `PETSCVIEWERGLVIS`, `PetscViewerGLVisOpen()`, `PetscViewerCreate()`, `PetscViewerSetType()`, `PetscObjectSetName()`
1274cac2994SStefano Zampini @*/
PetscViewerGLVisSetFields(PetscViewer viewer,PetscInt nf,const char * fec_type[],PetscInt dim[],PetscErrorCode (* g2l)(PetscObject,PetscInt,PetscObject[],void *),PetscObject Vfield[],PetscCtx ctx,PetscCtxDestroyFn * destroyctx)1282a8381b2SBarry Smith PetscErrorCode PetscViewerGLVisSetFields(PetscViewer viewer, PetscInt nf, const char *fec_type[], PetscInt dim[], PetscErrorCode (*g2l)(PetscObject, PetscInt, PetscObject[], void *), PetscObject Vfield[], PetscCtx ctx, PetscCtxDestroyFn *destroyctx)
129d71ae5a4SJacob Faibussowitsch {
1308135c375SStefano Zampini PetscFunctionBegin;
1318135c375SStefano Zampini PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
1328135c375SStefano Zampini PetscValidLogicalCollectiveInt(viewer, nf, 2);
13328b400f6SJacob Faibussowitsch PetscCheck(fec_type, PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "You need to provide the FiniteElementCollection names for the fields");
1344f572ea9SToby Isaac PetscAssertPointer(fec_type, 3);
1354f572ea9SToby Isaac PetscAssertPointer(dim, 4);
1364f572ea9SToby Isaac PetscAssertPointer(Vfield, 6);
137e6aa7a3bSBarry Smith PetscTryMethod(viewer, "PetscViewerGLVisSetFields_C", (PetscViewer, PetscInt, const char *[], PetscInt[], PetscErrorCode (*)(PetscObject, PetscInt, PetscObject[], void *), PetscObject[], void *, PetscCtxDestroyFn *), (viewer, nf, fec_type, dim, g2l, Vfield, ctx, destroyctx));
1383ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1398135c375SStefano Zampini }
1408135c375SStefano Zampini
PetscViewerGLVisSetFields_GLVis(PetscViewer viewer,PetscInt nfields,const char * fec_type[],PetscInt dim[],PetscErrorCode (* g2l)(PetscObject,PetscInt,PetscObject[],void *),PetscObject Vfield[],PetscCtx ctx,PetscCtxDestroyFn * destroyctx)1412a8381b2SBarry Smith static PetscErrorCode PetscViewerGLVisSetFields_GLVis(PetscViewer viewer, PetscInt nfields, const char *fec_type[], PetscInt dim[], PetscErrorCode (*g2l)(PetscObject, PetscInt, PetscObject[], void *), PetscObject Vfield[], PetscCtx ctx, PetscCtxDestroyFn *destroyctx)
142d71ae5a4SJacob Faibussowitsch {
1438135c375SStefano Zampini PetscViewerGLVis socket = (PetscViewerGLVis)viewer->data;
1448135c375SStefano Zampini PetscInt i;
1458135c375SStefano Zampini
1468135c375SStefano Zampini PetscFunctionBegin;
147cc73adaaSBarry Smith PetscCheck(!socket->nwindow || socket->nwindow == nfields, PetscObjectComm((PetscObject)viewer), PETSC_ERR_USER, "Cannot set number of fields %" PetscInt_FMT " with number of windows %" PetscInt_FMT, nfields, socket->nwindow);
1488135c375SStefano Zampini if (!socket->nwindow) {
1498135c375SStefano Zampini socket->nwindow = nfields;
1508135c375SStefano Zampini
1519566063dSJacob Faibussowitsch PetscCall(PetscCalloc5(nfields, &socket->window, nfields, &socket->windowtitle, nfields, &socket->fec_type, nfields, &socket->spacedim, nfields, &socket->Ufield));
1528135c375SStefano Zampini for (i = 0; i < nfields; i++) {
1534cac2994SStefano Zampini const char *name;
1548135c375SStefano Zampini
1559566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName(Vfield[i], &name));
1569566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(name, &socket->windowtitle[i]));
1579566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(fec_type[i], &socket->fec_type[i]));
1589566063dSJacob Faibussowitsch PetscCall(PetscObjectReference(Vfield[i]));
1594cac2994SStefano Zampini socket->Ufield[i] = Vfield[i];
1604cac2994SStefano Zampini socket->spacedim[i] = dim[i];
1618135c375SStefano Zampini }
1628135c375SStefano Zampini }
1638135c375SStefano Zampini /* number of fields are not allowed to vary */
16408401ef6SPierre Jolivet PetscCheck(nfields == socket->nwindow, PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Cannot visualize %" PetscInt_FMT " fields using %" PetscInt_FMT " socket windows", nfields, socket->nwindow);
1658135c375SStefano Zampini socket->g2lfield = g2l;
1662a8381b2SBarry Smith if (socket->destroyctx && socket->ctx) PetscCall((*socket->destroyctx)(&socket->ctx));
1672a8381b2SBarry Smith socket->ctx = ctx;
1688135c375SStefano Zampini socket->destroyctx = destroyctx;
1693ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1708135c375SStefano Zampini }
1718135c375SStefano Zampini
PetscViewerGLVisInfoDestroy_Private(PetscCtxRt ptr)1722a8381b2SBarry Smith static PetscErrorCode PetscViewerGLVisInfoDestroy_Private(PetscCtxRt ptr)
173d71ae5a4SJacob Faibussowitsch {
1742a8381b2SBarry Smith PetscViewerGLVisInfo info = (PetscViewerGLVisInfo) * (void **)ptr;
1758135c375SStefano Zampini
176c0bc9656SStefano Zampini PetscFunctionBegin;
1779566063dSJacob Faibussowitsch PetscCall(PetscFree(info->fmt));
1789566063dSJacob Faibussowitsch PetscCall(PetscFree(info));
1793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1808135c375SStefano Zampini }
1818135c375SStefano Zampini
1828135c375SStefano Zampini /* we can decide to prevent specific processes from using the viewer */
PetscViewerGLVisAttachInfo_Private(PetscViewer viewer,PetscViewer window)183d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscViewerGLVisAttachInfo_Private(PetscViewer viewer, PetscViewer window)
184d71ae5a4SJacob Faibussowitsch {
1858135c375SStefano Zampini PetscViewerGLVis socket = (PetscViewerGLVis)viewer->data;
1868135c375SStefano Zampini PetscContainer container;
1878135c375SStefano Zampini PetscViewerGLVisInfo info;
1888135c375SStefano Zampini
189c0bc9656SStefano Zampini PetscFunctionBegin;
1909566063dSJacob Faibussowitsch PetscCall(PetscObjectQuery((PetscObject)window, "_glvis_info_container", (PetscObject *)&container));
19177eacf09SStefano Zampini if (!container) {
1929566063dSJacob Faibussowitsch PetscCall(PetscNew(&info));
1938135c375SStefano Zampini info->enabled = PETSC_TRUE;
1948135c375SStefano Zampini info->init = PETSC_FALSE;
19573365f8bSLisandro Dalcin info->size[0] = socket->windowsizes[0];
19673365f8bSLisandro Dalcin info->size[1] = socket->windowsizes[1];
1978135c375SStefano Zampini info->pause = socket->pause;
19803e76207SPierre Jolivet PetscCall(PetscObjectContainerCompose((PetscObject)window, "_glvis_info_container", info, PetscViewerGLVisInfoDestroy_Private));
19977eacf09SStefano Zampini } else {
2002a8381b2SBarry Smith PetscCall(PetscContainerGetPointer(container, &info));
20177eacf09SStefano Zampini }
2029566063dSJacob Faibussowitsch PetscCall(PetscFree(info->fmt));
2039566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(socket->fmt, &info->fmt));
2043ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
2058135c375SStefano Zampini }
2068135c375SStefano Zampini
PetscViewerGLVisGetNewWindow_Private(PetscViewer viewer,PetscViewer * view)207d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscViewerGLVisGetNewWindow_Private(PetscViewer viewer, PetscViewer *view)
208d71ae5a4SJacob Faibussowitsch {
2098135c375SStefano Zampini PetscViewerGLVis socket = (PetscViewerGLVis)viewer->data;
2108135c375SStefano Zampini PetscViewer window = NULL;
2118135c375SStefano Zampini PetscBool ldis, dis;
2128135c375SStefano Zampini
2138135c375SStefano Zampini PetscFunctionBegin;
2142da53a5bSBarry Smith PetscCall(PetscViewerASCIISocketOpen(PETSC_COMM_SELF, socket->name, socket->port, &window));
215da81f932SPierre Jolivet /* if we could not establish a connection, we disable the socket viewer on all MPI ranks */
2162da53a5bSBarry Smith ldis = !viewer ? PETSC_TRUE : PETSC_FALSE;
2175440e5dcSBarry Smith PetscCallMPI(MPIU_Allreduce(&ldis, &dis, 1, MPI_C_BOOL, MPI_LOR, PetscObjectComm((PetscObject)viewer)));
2188135c375SStefano Zampini if (dis) {
2198135c375SStefano Zampini socket->status = PETSCVIEWERGLVIS_DISABLED;
2209566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&window));
2218135c375SStefano Zampini }
2228135c375SStefano Zampini *view = window;
2233ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
2248135c375SStefano Zampini }
2258135c375SStefano Zampini
PetscViewerGLVisPause_Internal(PetscViewer viewer)22634e79e72SJacob Faibussowitsch PetscErrorCode PetscViewerGLVisPause_Internal(PetscViewer viewer)
227d71ae5a4SJacob Faibussowitsch {
2288135c375SStefano Zampini PetscViewerGLVis socket = (PetscViewerGLVis)viewer->data;
2298135c375SStefano Zampini
2308135c375SStefano Zampini PetscFunctionBegin;
23148a46eb9SPierre Jolivet if (socket->type == PETSC_VIEWER_GLVIS_SOCKET && socket->pause > 0) PetscCall(PetscSleep(socket->pause));
2323ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
2338135c375SStefano Zampini }
2348135c375SStefano Zampini
2358135c375SStefano Zampini /* DM specific support */
PetscViewerGLVisSetDM_Internal(PetscViewer viewer,PetscObject dm)23634e79e72SJacob Faibussowitsch PetscErrorCode PetscViewerGLVisSetDM_Internal(PetscViewer viewer, PetscObject dm)
237d71ae5a4SJacob Faibussowitsch {
2388135c375SStefano Zampini PetscViewerGLVis socket = (PetscViewerGLVis)viewer->data;
2398135c375SStefano Zampini
2408135c375SStefano Zampini PetscFunctionBegin;
241cc73adaaSBarry Smith PetscCheck(!socket->dm || socket->dm == dm, PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Cannot change DM associated with the GLVis viewer");
2428135c375SStefano Zampini if (!socket->dm) {
2438135c375SStefano Zampini PetscErrorCode (*setupwithdm)(PetscObject, PetscViewer) = NULL;
2448135c375SStefano Zampini
2459566063dSJacob Faibussowitsch PetscCall(PetscObjectQueryFunction(dm, "DMSetUpGLVisViewer_C", &setupwithdm));
246966bd95aSPierre Jolivet PetscCheck(setupwithdm, PetscObjectComm(dm), PETSC_ERR_SUP, "No support for DM type %s", dm->type_name);
2479566063dSJacob Faibussowitsch PetscCall((*setupwithdm)(dm, viewer));
2489566063dSJacob Faibussowitsch PetscCall(PetscObjectReference(dm));
2498135c375SStefano Zampini socket->dm = dm;
2508135c375SStefano Zampini }
2513ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
2528135c375SStefano Zampini }
2538135c375SStefano Zampini
PetscViewerGLVisGetDMWindow_Internal(PetscViewer viewer,PetscViewer * view)25434e79e72SJacob Faibussowitsch PetscErrorCode PetscViewerGLVisGetDMWindow_Internal(PetscViewer viewer, PetscViewer *view)
255d71ae5a4SJacob Faibussowitsch {
2568135c375SStefano Zampini PetscViewerGLVis socket = (PetscViewerGLVis)viewer->data;
2578135c375SStefano Zampini
2588135c375SStefano Zampini PetscFunctionBegin;
2594f572ea9SToby Isaac PetscAssertPointer(view, 2);
2608135c375SStefano Zampini if (!socket->meshwindow) {
2618135c375SStefano Zampini if (socket->type == PETSC_VIEWER_GLVIS_SOCKET) {
2629566063dSJacob Faibussowitsch PetscCall(PetscViewerGLVisGetNewWindow_Private(viewer, &socket->meshwindow));
2638135c375SStefano Zampini } else {
26404b79de6SStefano Zampini size_t len;
26504b79de6SStefano Zampini PetscBool isstdout;
26604b79de6SStefano Zampini
2679566063dSJacob Faibussowitsch PetscCall(PetscStrlen(socket->name, &len));
2689566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(socket->name, "stdout", &isstdout));
26904b79de6SStefano Zampini if (!socket->name || !len || isstdout) {
2709566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIOpen(PETSC_COMM_SELF, "stdout", &socket->meshwindow));
27104b79de6SStefano Zampini } else {
2728135c375SStefano Zampini PetscMPIInt rank;
2738135c375SStefano Zampini char filename[PETSC_MAX_PATH_LEN];
2749566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank));
2759566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(filename, PETSC_MAX_PATH_LEN, "%s-mesh.%06d", socket->name, rank));
2769566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIOpen(PETSC_COMM_SELF, filename, &socket->meshwindow));
2778135c375SStefano Zampini }
27804b79de6SStefano Zampini }
2791baa6e33SBarry Smith if (socket->meshwindow) PetscCall(PetscViewerPushFormat(socket->meshwindow, PETSC_VIEWER_ASCII_GLVIS));
2808135c375SStefano Zampini }
2811baa6e33SBarry Smith if (socket->meshwindow) PetscCall(PetscViewerGLVisAttachInfo_Private(viewer, socket->meshwindow));
2828135c375SStefano Zampini *view = socket->meshwindow;
2833ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
2848135c375SStefano Zampini }
2858135c375SStefano Zampini
PetscViewerGLVisRestoreDMWindow_Internal(PetscViewer viewer,PetscViewer * view)28634e79e72SJacob Faibussowitsch PetscErrorCode PetscViewerGLVisRestoreDMWindow_Internal(PetscViewer viewer, PetscViewer *view)
287d71ae5a4SJacob Faibussowitsch {
2880286d493SLisandro Dalcin PetscViewerGLVis socket = (PetscViewerGLVis)viewer->data;
2890286d493SLisandro Dalcin
2900286d493SLisandro Dalcin PetscFunctionBegin;
2914f572ea9SToby Isaac PetscAssertPointer(view, 2);
292cc73adaaSBarry Smith PetscCheck(!*view || *view == socket->meshwindow, PetscObjectComm((PetscObject)viewer), PETSC_ERR_USER, "Viewer was not obtained from PetscViewerGLVisGetDMWindow()");
2930286d493SLisandro Dalcin if (*view) {
2949566063dSJacob Faibussowitsch PetscCall(PetscViewerFlush(*view));
2959566063dSJacob Faibussowitsch PetscCall(PetscBarrier((PetscObject)viewer));
2960286d493SLisandro Dalcin }
2970286d493SLisandro Dalcin if (socket->type == PETSC_VIEWER_GLVIS_DUMP) { /* destroy the viewer, as it is associated with a single time step */
2989566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&socket->meshwindow));
2990286d493SLisandro Dalcin } else if (!*view) { /* something went wrong (SIGPIPE) so we just zero the private pointer */
3000286d493SLisandro Dalcin socket->meshwindow = NULL;
3010286d493SLisandro Dalcin }
3020286d493SLisandro Dalcin *view = NULL;
3033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
3040286d493SLisandro Dalcin }
3050286d493SLisandro Dalcin
PetscViewerGLVisGetType_Internal(PetscViewer viewer,PetscViewerGLVisType * type)30634e79e72SJacob Faibussowitsch PetscErrorCode PetscViewerGLVisGetType_Internal(PetscViewer viewer, PetscViewerGLVisType *type)
307d71ae5a4SJacob Faibussowitsch {
3088135c375SStefano Zampini PetscViewerGLVis socket = (PetscViewerGLVis)viewer->data;
3098135c375SStefano Zampini
3108135c375SStefano Zampini PetscFunctionBegin;
3114f572ea9SToby Isaac PetscAssertPointer(type, 2);
3128135c375SStefano Zampini *type = socket->type;
3133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
3148135c375SStefano Zampini }
3158135c375SStefano Zampini
3168135c375SStefano 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 */
PetscViewerGLVisGetStatus_Internal(PetscViewer viewer,PetscViewerGLVisStatus * sockstatus)31734e79e72SJacob Faibussowitsch PetscErrorCode PetscViewerGLVisGetStatus_Internal(PetscViewer viewer, PetscViewerGLVisStatus *sockstatus)
318d71ae5a4SJacob Faibussowitsch {
3198135c375SStefano Zampini PetscViewerGLVis socket = (PetscViewerGLVis)viewer->data;
3208135c375SStefano Zampini
3218135c375SStefano Zampini PetscFunctionBegin;
3224f572ea9SToby Isaac PetscAssertPointer(sockstatus, 2);
3238135c375SStefano Zampini if (socket->type == PETSC_VIEWER_GLVIS_DUMP) {
3248135c375SStefano Zampini socket->status = PETSCVIEWERGLVIS_DISCONNECTED;
3258135c375SStefano Zampini } else if (socket->status == PETSCVIEWERGLVIS_DISCONNECTED && socket->nwindow) {
3268135c375SStefano Zampini PetscInt i;
3278135c375SStefano Zampini PetscBool lconn, conn;
3288135c375SStefano Zampini
3298135c375SStefano Zampini for (i = 0, lconn = PETSC_TRUE; i < socket->nwindow; i++)
3309371c9d4SSatish Balay if (!socket->window[i]) lconn = PETSC_FALSE;
3318135c375SStefano Zampini
3325440e5dcSBarry Smith PetscCallMPI(MPIU_Allreduce(&lconn, &conn, 1, MPI_C_BOOL, MPI_LAND, PetscObjectComm((PetscObject)viewer)));
3338135c375SStefano Zampini if (conn) socket->status = PETSCVIEWERGLVIS_CONNECTED;
3348135c375SStefano Zampini }
3358135c375SStefano Zampini *sockstatus = socket->status;
3363ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
3378135c375SStefano Zampini }
3388135c375SStefano Zampini
PetscViewerGLVisGetDM_Internal(PetscViewer viewer,PetscObject * dm)33934e79e72SJacob Faibussowitsch PetscErrorCode PetscViewerGLVisGetDM_Internal(PetscViewer viewer, PetscObject *dm)
340d71ae5a4SJacob Faibussowitsch {
3418135c375SStefano Zampini PetscViewerGLVis socket = (PetscViewerGLVis)viewer->data;
3428135c375SStefano Zampini
3438135c375SStefano Zampini PetscFunctionBegin;
3448135c375SStefano Zampini *dm = socket->dm;
3453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
3468135c375SStefano Zampini }
3478135c375SStefano Zampini
PetscViewerGLVisGetFields_Internal(PetscViewer viewer,PetscInt * nfield,const char ** fec[],PetscInt * spacedim[],PetscErrorCode (** g2lfield)(PetscObject,PetscInt,PetscObject[],void *),PetscObject * Ufield[],void ** ctx)3482a8381b2SBarry Smith PetscErrorCode PetscViewerGLVisGetFields_Internal(PetscViewer viewer, PetscInt *nfield, const char **fec[], PetscInt *spacedim[], PetscErrorCode (**g2lfield)(PetscObject, PetscInt, PetscObject[], void *), PetscObject *Ufield[], void **ctx)
349d71ae5a4SJacob Faibussowitsch {
3508135c375SStefano Zampini PetscViewerGLVis socket = (PetscViewerGLVis)viewer->data;
3518135c375SStefano Zampini
3528135c375SStefano Zampini PetscFunctionBegin;
3538135c375SStefano Zampini if (nfield) *nfield = socket->nwindow;
3548135c375SStefano Zampini if (fec) *fec = (const char **)socket->fec_type;
3554cac2994SStefano Zampini if (spacedim) *spacedim = socket->spacedim;
3568135c375SStefano Zampini if (g2lfield) *g2lfield = socket->g2lfield;
3578135c375SStefano Zampini if (Ufield) *Ufield = socket->Ufield;
3582a8381b2SBarry Smith if (ctx) *ctx = socket->ctx;
3593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
3608135c375SStefano Zampini }
3618135c375SStefano Zampini
3628135c375SStefano Zampini /* accessor routines for the viewer windows:
3638135c375SStefano Zampini PETSC_VIEWER_GLVIS_DUMP : it returns a new viewer every time
3648135c375SStefano Zampini PETSC_VIEWER_GLVIS_SOCKET : it returns the socket, and creates it if not yet done.
3658135c375SStefano Zampini */
PetscViewerGLVisGetWindow_Internal(PetscViewer viewer,PetscInt wid,PetscViewer * view)36634e79e72SJacob Faibussowitsch PetscErrorCode PetscViewerGLVisGetWindow_Internal(PetscViewer viewer, PetscInt wid, PetscViewer *view)
367d71ae5a4SJacob Faibussowitsch {
3688135c375SStefano Zampini PetscViewerGLVis socket = (PetscViewerGLVis)viewer->data;
3698135c375SStefano Zampini PetscViewerGLVisStatus status;
3708135c375SStefano Zampini
3718135c375SStefano Zampini PetscFunctionBegin;
3728135c375SStefano Zampini PetscValidLogicalCollectiveInt(viewer, wid, 2);
3734f572ea9SToby Isaac PetscAssertPointer(view, 3);
3742c71b3e2SJacob Faibussowitsch PetscCheck(wid >= 0 && (wid <= socket->nwindow - 1), PetscObjectComm((PetscObject)viewer), PETSC_ERR_USER, "Cannot get window id %" PetscInt_FMT ": allowed range [0,%" PetscInt_FMT ")", wid, socket->nwindow - 1);
3758135c375SStefano Zampini status = socket->status;
3762c71b3e2SJacob Faibussowitsch if (socket->type == PETSC_VIEWER_GLVIS_DUMP) PetscCheck(!socket->window[wid], PETSC_COMM_SELF, PETSC_ERR_USER, "Window %" PetscInt_FMT " is already in use", wid);
3778135c375SStefano Zampini switch (status) {
3788135c375SStefano Zampini case PETSCVIEWERGLVIS_DISCONNECTED:
3792c71b3e2SJacob Faibussowitsch PetscCheck(!socket->window[wid], PETSC_COMM_SELF, PETSC_ERR_USER, "This should not happen");
380f7d195e4SLawrence Mitchell if (socket->type == PETSC_VIEWER_GLVIS_DUMP) {
38104b79de6SStefano Zampini size_t len;
38204b79de6SStefano Zampini PetscBool isstdout;
38304b79de6SStefano Zampini
3849566063dSJacob Faibussowitsch PetscCall(PetscStrlen(socket->name, &len));
3859566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(socket->name, "stdout", &isstdout));
38604b79de6SStefano Zampini if (!socket->name || !len || isstdout) {
3879566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIOpen(PETSC_COMM_SELF, "stdout", &socket->window[wid]));
38804b79de6SStefano Zampini } else {
3898135c375SStefano Zampini PetscMPIInt rank;
3908135c375SStefano Zampini char filename[PETSC_MAX_PATH_LEN];
3918135c375SStefano Zampini
3929566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank));
3939566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(filename, PETSC_MAX_PATH_LEN, "%s-%s-%" PetscInt_FMT ".%06d", socket->name, socket->windowtitle[wid], socket->snapid, rank));
3949566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIOpen(PETSC_COMM_SELF, filename, &socket->window[wid]));
39504b79de6SStefano Zampini }
3968135c375SStefano Zampini } else {
3979566063dSJacob Faibussowitsch PetscCall(PetscViewerGLVisGetNewWindow_Private(viewer, &socket->window[wid]));
3988135c375SStefano Zampini }
39948a46eb9SPierre Jolivet if (socket->window[wid]) PetscCall(PetscViewerPushFormat(socket->window[wid], PETSC_VIEWER_ASCII_GLVIS));
4008135c375SStefano Zampini *view = socket->window[wid];
4018135c375SStefano Zampini break;
402d71ae5a4SJacob Faibussowitsch case PETSCVIEWERGLVIS_CONNECTED:
403d71ae5a4SJacob Faibussowitsch *view = socket->window[wid];
404d71ae5a4SJacob Faibussowitsch break;
405d71ae5a4SJacob Faibussowitsch case PETSCVIEWERGLVIS_DISABLED:
406d71ae5a4SJacob Faibussowitsch *view = NULL;
407d71ae5a4SJacob Faibussowitsch break;
408d71ae5a4SJacob Faibussowitsch default:
409d71ae5a4SJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Unhandled socket status %d", (int)status);
4108135c375SStefano Zampini }
4111baa6e33SBarry Smith if (*view) PetscCall(PetscViewerGLVisAttachInfo_Private(viewer, *view));
4123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
4138135c375SStefano Zampini }
4148135c375SStefano Zampini
4158135c375SStefano Zampini /* Restore the window viewer
4168135c375SStefano Zampini PETSC_VIEWER_GLVIS_DUMP : destroys the temporary created ASCII viewer used for dumping
4178135c375SStefano Zampini PETSC_VIEWER_GLVIS_SOCKET: - if the returned window viewer is not NULL, just zeros the pointer.
4188135c375SStefano Zampini - it the returned window viewer is NULL, assumes something went wrong
4198135c375SStefano Zampini with the socket (i.e. SIGPIPE when a user closes the popup window)
4208135c375SStefano Zampini and that the caller already handled it (see VecView_GLVis).
4218135c375SStefano Zampini */
PetscViewerGLVisRestoreWindow_Internal(PetscViewer viewer,PetscInt wid,PetscViewer * view)42234e79e72SJacob Faibussowitsch PetscErrorCode PetscViewerGLVisRestoreWindow_Internal(PetscViewer viewer, PetscInt wid, PetscViewer *view)
423d71ae5a4SJacob Faibussowitsch {
4248135c375SStefano Zampini PetscViewerGLVis socket = (PetscViewerGLVis)viewer->data;
4258135c375SStefano Zampini
4268135c375SStefano Zampini PetscFunctionBegin;
42763bd7f81SStefano Zampini PetscValidHeaderSpecificType(viewer, PETSC_VIEWER_CLASSID, 1, PETSCVIEWERGLVIS);
4288135c375SStefano Zampini PetscValidLogicalCollectiveInt(viewer, wid, 2);
4294f572ea9SToby Isaac PetscAssertPointer(view, 3);
430cc73adaaSBarry Smith PetscCheck(wid >= 0 && wid < socket->nwindow, PetscObjectComm((PetscObject)viewer), PETSC_ERR_USER, "Cannot restore window id %" PetscInt_FMT ": allowed range [0,%" PetscInt_FMT ")", wid, socket->nwindow);
431cc73adaaSBarry Smith PetscCheck(!*view || *view == socket->window[wid], PetscObjectComm((PetscObject)viewer), PETSC_ERR_USER, "Viewer was not obtained from PetscViewerGLVisGetWindow()");
4328135c375SStefano Zampini if (*view) {
4339566063dSJacob Faibussowitsch PetscCall(PetscViewerFlush(*view));
4349566063dSJacob Faibussowitsch PetscCall(PetscBarrier((PetscObject)viewer));
4358135c375SStefano Zampini }
4368135c375SStefano Zampini if (socket->type == PETSC_VIEWER_GLVIS_DUMP) { /* destroy the viewer, as it is associated with a single time step */
4379566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&socket->window[wid]));
4388135c375SStefano Zampini } else if (!*view) { /* something went wrong (SIGPIPE) so we just zero the private pointer */
4398135c375SStefano Zampini socket->window[wid] = NULL;
4408135c375SStefano Zampini }
4418135c375SStefano Zampini *view = NULL;
4423ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
4438135c375SStefano Zampini }
4448135c375SStefano Zampini
4458135c375SStefano Zampini /* default window appearance in the PETSC_VIEWER_GLVIS_SOCKET case */
PetscViewerGLVisInitWindow_Internal(PetscViewer viewer,PetscBool mesh,PetscInt dim,const char * name)44634e79e72SJacob Faibussowitsch PetscErrorCode PetscViewerGLVisInitWindow_Internal(PetscViewer viewer, PetscBool mesh, PetscInt dim, const char *name)
447d71ae5a4SJacob Faibussowitsch {
4488135c375SStefano Zampini PetscViewerGLVisInfo info;
4498135c375SStefano Zampini PetscContainer container;
4508135c375SStefano Zampini
4518135c375SStefano Zampini PetscFunctionBegin;
4529566063dSJacob Faibussowitsch PetscCall(PetscObjectQuery((PetscObject)viewer, "_glvis_info_container", (PetscObject *)&container));
45328b400f6SJacob Faibussowitsch PetscCheck(container, PETSC_COMM_SELF, PETSC_ERR_USER, "Viewer was not obtained from PetscGLVisViewerGetNewWindow_Private");
4542a8381b2SBarry Smith PetscCall(PetscContainerGetPointer(container, &info));
4553ba16761SJacob Faibussowitsch if (info->init) PetscFunctionReturn(PETSC_SUCCESS);
456fe28a402SLisandro Dalcin
457fe28a402SLisandro Dalcin /* Configure window */
45848a46eb9SPierre Jolivet if (info->size[0] > 0) PetscCall(PetscViewerASCIIPrintf(viewer, "window_size %" PetscInt_FMT " %" PetscInt_FMT "\n", info->size[0], info->size[1]));
45948a46eb9SPierre Jolivet if (name) PetscCall(PetscViewerASCIIPrintf(viewer, "window_title '%s'\n", name));
460fe28a402SLisandro Dalcin
461fe28a402SLisandro Dalcin /* Configure default view */
4628135c375SStefano Zampini if (mesh) {
4638135c375SStefano Zampini switch (dim) {
4648135c375SStefano Zampini case 1:
4659566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "keys m\n")); /* show mesh */
4668135c375SStefano Zampini break;
4678135c375SStefano Zampini case 2:
4689566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "keys m\n")); /* show mesh */
4698135c375SStefano Zampini break;
470d71ae5a4SJacob Faibussowitsch case 3: /* TODO: decide default view in 3D */
471d71ae5a4SJacob Faibussowitsch break;
4728135c375SStefano Zampini }
4738135c375SStefano Zampini } else {
4749566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "keys cm\n")); /* show colorbar and mesh */
4758135c375SStefano Zampini switch (dim) {
4768135c375SStefano Zampini case 1:
4779566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "keys RRjl\n")); /* set to 1D (side view), turn off perspective and light */
4788135c375SStefano Zampini break;
4798135c375SStefano Zampini case 2:
4809566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "keys Rjl\n")); /* set to 2D (top view), turn off perspective and light */
4818135c375SStefano Zampini break;
482d71ae5a4SJacob Faibussowitsch case 3:
483d71ae5a4SJacob Faibussowitsch break;
4848135c375SStefano Zampini }
4859566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "autoscale value\n")); /* update value-range; keep mesh-extents fixed */
48673365f8bSLisandro Dalcin }
487fe28a402SLisandro Dalcin
488fe28a402SLisandro Dalcin { /* Additional keys and commands */
489fe28a402SLisandro Dalcin char keys[256] = "", cmds[2 * PETSC_MAX_PATH_LEN] = "";
490fe28a402SLisandro Dalcin PetscOptions opt = ((PetscObject)viewer)->options;
491fe28a402SLisandro Dalcin const char *pre = ((PetscObject)viewer)->prefix;
492fe28a402SLisandro Dalcin
4939566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetString(opt, pre, "-glvis_keys", keys, sizeof(keys), NULL));
4949566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetString(opt, pre, "-glvis_exec", cmds, sizeof(cmds), NULL));
4959566063dSJacob Faibussowitsch if (keys[0]) PetscCall(PetscViewerASCIIPrintf(viewer, "keys %s\n", keys));
4969566063dSJacob Faibussowitsch if (cmds[0]) PetscCall(PetscViewerASCIIPrintf(viewer, "%s\n", cmds));
4978135c375SStefano Zampini }
498fe28a402SLisandro Dalcin
499fe28a402SLisandro Dalcin /* Pause visualization */
50048a46eb9SPierre Jolivet if (!mesh && info->pause == -1) PetscCall(PetscViewerASCIIPrintf(viewer, "autopause 1\n"));
50148a46eb9SPierre Jolivet if (!mesh && info->pause == 0) PetscCall(PetscViewerASCIIPrintf(viewer, "pause\n"));
502fe28a402SLisandro Dalcin
5038135c375SStefano Zampini info->init = PETSC_TRUE;
5043ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
5058135c375SStefano Zampini }
5068135c375SStefano Zampini
PetscViewerDestroy_GLVis(PetscViewer viewer)507d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscViewerDestroy_GLVis(PetscViewer viewer)
508d71ae5a4SJacob Faibussowitsch {
5098135c375SStefano Zampini PetscViewerGLVis socket = (PetscViewerGLVis)viewer->data;
5108135c375SStefano Zampini PetscInt i;
5118135c375SStefano Zampini
5128135c375SStefano Zampini PetscFunctionBegin;
5138135c375SStefano Zampini for (i = 0; i < socket->nwindow; i++) {
5149566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&socket->window[i]));
5159566063dSJacob Faibussowitsch PetscCall(PetscFree(socket->windowtitle[i]));
5169566063dSJacob Faibussowitsch PetscCall(PetscFree(socket->fec_type[i]));
5179566063dSJacob Faibussowitsch PetscCall(PetscObjectDestroy(&socket->Ufield[i]));
5188135c375SStefano Zampini }
5199566063dSJacob Faibussowitsch PetscCall(PetscFree(socket->name));
5209566063dSJacob Faibussowitsch PetscCall(PetscFree5(socket->window, socket->windowtitle, socket->fec_type, socket->spacedim, socket->Ufield));
5219566063dSJacob Faibussowitsch PetscCall(PetscFree(socket->fmt));
5229566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&socket->meshwindow));
5239566063dSJacob Faibussowitsch PetscCall(PetscObjectDestroy(&socket->dm));
5242a8381b2SBarry Smith if (socket->destroyctx && socket->ctx) PetscCall((*socket->destroyctx)(&socket->ctx));
5258135c375SStefano Zampini
5269566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerGLVisSetPrecision_C", NULL));
5279566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerGLVisSetSnapId_C", NULL));
5289566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerGLVisSetFields_C", NULL));
5299566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileSetName_C", NULL));
5309566063dSJacob Faibussowitsch PetscCall(PetscFree(socket));
5318135c375SStefano Zampini viewer->data = NULL;
5323ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
5338135c375SStefano Zampini }
5348135c375SStefano Zampini
PetscViewerSetFromOptions_GLVis(PetscViewer v,PetscOptionItems PetscOptionsObject)535ce78bad3SBarry Smith static PetscErrorCode PetscViewerSetFromOptions_GLVis(PetscViewer v, PetscOptionItems PetscOptionsObject)
536d71ae5a4SJacob Faibussowitsch {
5378135c375SStefano Zampini PetscViewerGLVis socket = (PetscViewerGLVis)v->data;
53873365f8bSLisandro Dalcin PetscInt nsizes = 2, prec = PETSC_DECIDE;
53973365f8bSLisandro Dalcin PetscBool set;
5408135c375SStefano Zampini
5418135c375SStefano Zampini PetscFunctionBegin;
542d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "GLVis PetscViewer Options");
5439566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-glvis_precision", "Number of digits for floating point values", "PetscViewerGLVisSetPrecision", prec, &prec, &set));
5449566063dSJacob Faibussowitsch if (set) PetscCall(PetscViewerGLVisSetPrecision(v, prec));
5459566063dSJacob Faibussowitsch PetscCall(PetscOptionsIntArray("-glvis_size", "Window sizes", NULL, socket->windowsizes, &nsizes, &set));
54673365f8bSLisandro Dalcin if (set && (nsizes == 1 || socket->windowsizes[1] < 0)) socket->windowsizes[1] = socket->windowsizes[0];
5479566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-glvis_pause", "-1 to pause after each visualization, otherwise sleeps for given seconds", NULL, socket->pause, &socket->pause, NULL));
548bcee047aSJacob Faibussowitsch PetscCall(PetscOptionsName("-glvis_keys", "Additional keys to configure visualization", NULL, &set));
549bcee047aSJacob Faibussowitsch PetscCall(PetscOptionsName("-glvis_exec", "Additional commands to configure visualization", NULL, &set));
550d0609cedSBarry Smith PetscOptionsHeadEnd();
5513ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
5528135c375SStefano Zampini }
5538135c375SStefano Zampini
PetscViewerFileSetName_GLVis(PetscViewer viewer,const char name[])554d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscViewerFileSetName_GLVis(PetscViewer viewer, const char name[])
555d71ae5a4SJacob Faibussowitsch {
556bbcf679cSJacob Faibussowitsch char *sport = NULL;
5578135c375SStefano Zampini PetscViewerGLVis socket = (PetscViewerGLVis)viewer->data;
5588135c375SStefano Zampini
5598135c375SStefano Zampini PetscFunctionBegin;
5608135c375SStefano Zampini socket->type = PETSC_VIEWER_GLVIS_DUMP;
5618135c375SStefano Zampini /* we accept localhost^port */
5629566063dSJacob Faibussowitsch PetscCall(PetscFree(socket->name));
5639566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(name, &socket->name));
5649566063dSJacob Faibussowitsch PetscCall(PetscStrchr(socket->name, '^', &sport));
5658135c375SStefano Zampini if (sport) {
5668135c375SStefano Zampini PetscInt port = 19916;
5678135c375SStefano Zampini size_t len;
5685f80ce2aSJacob Faibussowitsch PetscErrorCode ierr;
5698135c375SStefano Zampini
5708135c375SStefano Zampini *sport++ = 0;
5719566063dSJacob Faibussowitsch PetscCall(PetscStrlen(sport, &len));
5725f80ce2aSJacob Faibussowitsch ierr = PetscOptionsStringToInt(sport, &port);
5735f80ce2aSJacob Faibussowitsch if (PetscUnlikely(ierr)) {
5748135c375SStefano Zampini socket->port = 19916;
5755f80ce2aSJacob Faibussowitsch } else {
5765f80ce2aSJacob Faibussowitsch socket->port = (port != PETSC_DECIDE && port != PETSC_DEFAULT) ? port : 19916;
5778135c375SStefano Zampini }
5788135c375SStefano Zampini socket->type = PETSC_VIEWER_GLVIS_SOCKET;
5798135c375SStefano Zampini }
5803ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
5818135c375SStefano Zampini }
5828135c375SStefano Zampini
583cc4c1da9SBarry Smith /*@
584811af0c4SBarry Smith PetscViewerGLVisOpen - Opens a `PETSCVIEWERGLVIS` `PetscViewer`
5858135c375SStefano Zampini
586d1f92df0SBarry Smith Collective; No Fortran Support
5878135c375SStefano Zampini
5888135c375SStefano Zampini Input Parameters:
5898135c375SStefano Zampini + comm - the MPI communicator
590811af0c4SBarry Smith . type - the viewer type: `PETSC_VIEWER_GLVIS_SOCKET` for real-time visualization or `PETSC_VIEWER_GLVIS_DUMP` for dumping to a file
5918135c375SStefano Zampini . name - either the hostname where the GLVis server is running or the base filename for dumping the data for subsequent visualizations
592811af0c4SBarry Smith - port - socket port where the GLVis server is listening. Not referenced when type is `PETSC_VIEWER_GLVIS_DUMP`
5938135c375SStefano Zampini
5942fe279fdSBarry Smith Output Parameter:
5952fe279fdSBarry Smith . viewer - the `PetscViewer` object
5968135c375SStefano Zampini
59773365f8bSLisandro Dalcin Options Database Keys:
598fe28a402SLisandro Dalcin + -glvis_precision <precision> - Sets number of digits for floating point values
599fe28a402SLisandro Dalcin . -glvis_size <width,height> - Sets the window size (in pixels)
60073365f8bSLisandro Dalcin . -glvis_pause <pause> - Sets time (in seconds) that the program pauses after each visualization
601fe28a402SLisandro Dalcin (0 is default, -1 implies every visualization)
602fe28a402SLisandro Dalcin . -glvis_keys - Additional keys to configure visualization
603fe28a402SLisandro Dalcin - -glvis_exec - Additional commands to configure visualization
60473365f8bSLisandro Dalcin
6058135c375SStefano Zampini Level: beginner
6068135c375SStefano Zampini
607d1f92df0SBarry Smith .seealso: [](sec_viewers), `PETSCVIEWERGLVIS`, `PetscViewerCreate()`, `PetscViewerSetType()`, `PetscViewerGLVisType`
60873365f8bSLisandro Dalcin @*/
PetscViewerGLVisOpen(MPI_Comm comm,PetscViewerGLVisType type,const char name[],PetscInt port,PetscViewer * viewer)609d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerGLVisOpen(MPI_Comm comm, PetscViewerGLVisType type, const char name[], PetscInt port, PetscViewer *viewer)
610d71ae5a4SJacob Faibussowitsch {
6118135c375SStefano Zampini PetscViewerGLVis socket;
6128135c375SStefano Zampini
6138135c375SStefano Zampini PetscFunctionBegin;
6149566063dSJacob Faibussowitsch PetscCall(PetscViewerCreate(comm, viewer));
6159566063dSJacob Faibussowitsch PetscCall(PetscViewerSetType(*viewer, PETSCVIEWERGLVIS));
6168135c375SStefano Zampini
6178135c375SStefano Zampini socket = (PetscViewerGLVis)((*viewer)->data);
618a7bda6aaSStefano Zampini socket->type = type;
619a7bda6aaSStefano Zampini if (type == PETSC_VIEWER_GLVIS_DUMP || name) {
6209566063dSJacob Faibussowitsch PetscCall(PetscFree(socket->name));
6219566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(name, &socket->name));
622a7bda6aaSStefano Zampini }
623a7bda6aaSStefano Zampini socket->port = (!port || port == PETSC_DETERMINE || port == PETSC_DECIDE) ? 19916 : port;
6248135c375SStefano Zampini
6259566063dSJacob Faibussowitsch PetscCall(PetscViewerSetFromOptions(*viewer));
6263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
6278135c375SStefano Zampini }
6288135c375SStefano Zampini
629d1f92df0SBarry Smith /*@C
630811af0c4SBarry Smith PETSC_VIEWER_GLVIS_ - Creates a `PETSCVIEWERGLVIS` `PetscViewer` shared by all processors in a communicator.
6318135c375SStefano Zampini
632d1f92df0SBarry Smith Collective; No Fortran Support
6338135c375SStefano Zampini
6348135c375SStefano Zampini Input Parameter:
635811af0c4SBarry Smith . comm - the MPI communicator to share the `PETSCVIEWERGLVIS` `PetscViewer`
6368135c375SStefano Zampini
6378135c375SStefano Zampini Environmental variables:
638d1f92df0SBarry Smith + `PETSC_VIEWER_GLVIS_FILENAME` - output filename (if specified dump to disk, and takes precedence on `PETSC_VIEWER_GLVIS_HOSTNAME`)
639d1f92df0SBarry Smith . `PETSC_VIEWER_GLVIS_HOSTNAME` - machine where the GLVis server is listening (defaults to localhost)
640d1f92df0SBarry Smith - `PETSC_VIEWER_GLVIS_PORT` - port opened by the GLVis server (defaults to 19916)
641d1f92df0SBarry Smith
642d1f92df0SBarry Smith Level: intermediate
6438135c375SStefano Zampini
644811af0c4SBarry Smith Note:
645811af0c4SBarry Smith Unlike almost all other PETSc routines, `PETSC_VIEWER_GLVIS_()` does not return
646811af0c4SBarry Smith an error code. It is usually used in the form
647648c30bcSBarry Smith .vb
648648c30bcSBarry Smith XXXView(XXX object, PETSC_VIEWER_GLVIS_(comm));
649648c30bcSBarry Smith .ve
650648c30bcSBarry Smith
651648c30bcSBarry Smith Developer Note:
652648c30bcSBarry Smith How come this viewer is not stashed as an attribute in the MPI communicator?
6538135c375SStefano Zampini
654d1f92df0SBarry Smith .seealso: [](sec_viewers), `PETSCVIEWERGLVIS`, `PetscViewer`, `PetscViewerGLVISOpen()`, `PetscViewerGLVisType`, `PetscViewerCreate()`, `PetscViewerDestroy()`
655d1f92df0SBarry Smith @*/
PETSC_VIEWER_GLVIS_(MPI_Comm comm)656d71ae5a4SJacob Faibussowitsch PetscViewer PETSC_VIEWER_GLVIS_(MPI_Comm comm)
657d71ae5a4SJacob Faibussowitsch {
6588135c375SStefano Zampini PetscBool flg;
6598135c375SStefano Zampini PetscViewer viewer;
6608135c375SStefano Zampini PetscViewerGLVisType type;
6618135c375SStefano Zampini char fname[PETSC_MAX_PATH_LEN], sport[16];
6628135c375SStefano Zampini PetscInt port = 19916; /* default for GLVis */
6638135c375SStefano Zampini
6648135c375SStefano Zampini PetscFunctionBegin;
665648c30bcSBarry Smith PetscCallNull(PetscOptionsGetenv(comm, "PETSC_VIEWER_GLVIS_FILENAME", fname, PETSC_MAX_PATH_LEN, &flg));
6668135c375SStefano Zampini if (!flg) {
6678135c375SStefano Zampini type = PETSC_VIEWER_GLVIS_SOCKET;
668648c30bcSBarry Smith PetscCallNull(PetscOptionsGetenv(comm, "PETSC_VIEWER_GLVIS_HOSTNAME", fname, PETSC_MAX_PATH_LEN, &flg));
6693a7d0413SPierre Jolivet if (!flg) PetscCallNull(PetscStrncpy(fname, "localhost", sizeof(fname)));
670648c30bcSBarry Smith PetscCallNull(PetscOptionsGetenv(comm, "PETSC_VIEWER_GLVIS_PORT", sport, 16, &flg));
6713a7d0413SPierre Jolivet if (flg) PetscCallNull(PetscOptionsStringToInt(sport, &port));
6728135c375SStefano Zampini } else {
6738135c375SStefano Zampini type = PETSC_VIEWER_GLVIS_DUMP;
6748135c375SStefano Zampini }
675648c30bcSBarry Smith PetscCallNull(PetscViewerGLVisOpen(comm, type, fname, port, &viewer));
676648c30bcSBarry Smith PetscCallNull(PetscObjectRegisterDestroy((PetscObject)viewer));
6778135c375SStefano Zampini PetscFunctionReturn(viewer);
6788135c375SStefano Zampini }
6798135c375SStefano Zampini
PetscViewerCreate_GLVis(PetscViewer viewer)680d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscViewerCreate_GLVis(PetscViewer viewer)
681d71ae5a4SJacob Faibussowitsch {
6828135c375SStefano Zampini PetscViewerGLVis socket;
6838135c375SStefano Zampini
6848135c375SStefano Zampini PetscFunctionBegin;
6854dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&socket));
6868135c375SStefano Zampini
6878135c375SStefano Zampini /* defaults to socket viewer */
6889566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy("localhost", &socket->name));
6898135c375SStefano Zampini socket->port = 19916; /* GLVis default listening port */
6908135c375SStefano Zampini socket->type = PETSC_VIEWER_GLVIS_SOCKET;
6918135c375SStefano Zampini socket->pause = 0; /* just pause the first time */
6928135c375SStefano Zampini
69373365f8bSLisandro Dalcin socket->windowsizes[0] = 600;
69473365f8bSLisandro Dalcin socket->windowsizes[1] = 600;
69573365f8bSLisandro Dalcin
69677eacf09SStefano Zampini /* defaults to full precision */
6979566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(" %g", &socket->fmt));
69877eacf09SStefano Zampini
6998135c375SStefano Zampini viewer->data = (void *)socket;
7008135c375SStefano Zampini viewer->ops->destroy = PetscViewerDestroy_GLVis;
7018135c375SStefano Zampini viewer->ops->setfromoptions = PetscViewerSetFromOptions_GLVis;
7028135c375SStefano Zampini
7039566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerGLVisSetPrecision_C", PetscViewerGLVisSetPrecision_GLVis));
7049566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerGLVisSetSnapId_C", PetscViewerGLVisSetSnapId_GLVis));
7059566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerGLVisSetFields_C", PetscViewerGLVisSetFields_GLVis));
7069566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileSetName_C", PetscViewerFileSetName_GLVis));
7073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
7088135c375SStefano Zampini }
7098135c375SStefano Zampini
7108135c375SStefano Zampini /* this is a private implementation of a SOCKET with ASCII data format
7118135c375SStefano Zampini GLVis does not currently handle binary socket streams */
7128135c375SStefano Zampini #if defined(PETSC_HAVE_UNISTD_H)
7138135c375SStefano Zampini #include <unistd.h>
7148135c375SStefano Zampini #endif
7158135c375SStefano Zampini
716*beceaeb6SBarry Smith #if !defined(PETSC_HAVE_WINDOWS_H)
7178135c375SStefano Zampini static PetscErrorCode (*PetscViewerDestroy_ASCII)(PetscViewer);
7188135c375SStefano Zampini
PetscViewerDestroy_ASCII_Socket(PetscViewer viewer)719d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscViewerDestroy_ASCII_Socket(PetscViewer viewer)
720d71ae5a4SJacob Faibussowitsch {
7218135c375SStefano Zampini FILE *stream;
722d0609cedSBarry Smith
7238135c375SStefano Zampini PetscFunctionBegin;
7249566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIGetPointer(viewer, &stream));
7258135c375SStefano Zampini if (stream) {
72640fde1d9SLisandro Dalcin int retv = fclose(stream);
72740fde1d9SLisandro Dalcin PetscCheck(!retv, PETSC_COMM_SELF, PETSC_ERR_SYS, "fclose() failed on stream");
7288135c375SStefano Zampini }
7299566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy_ASCII(viewer));
7303ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
7318135c375SStefano Zampini }
73227e89126SStefano Zampini #endif
73311a4995dSStefano Zampini
7342da53a5bSBarry Smith /*
7352da53a5bSBarry Smith This attempts to return a NULL viewer if it is unable to open a socket connection.
7362da53a5bSBarry Smith
7372da53a5bSBarry Smith The code below involving PetscUnlikely(ierr) is illegal in PETSc, one can NEVER attempt to recover once an error is initiated in PETSc.
7382da53a5bSBarry Smith
7392da53a5bSBarry Smith The correct approach is to refactor PetscOpenSocket() to not initiate an error under certain failure conditions but instead either return a special value
7402da53a5bSBarry Smith of fd to indicate it was impossible to open the socket, or add another return argument to it indicating the socket was not opened.
7412da53a5bSBarry Smith */
PetscViewerASCIISocketOpen(MPI_Comm comm,const char * hostname,PetscInt port,PetscViewer * viewer)742d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscViewerASCIISocketOpen(MPI_Comm comm, const char *hostname, PetscInt port, PetscViewer *viewer)
743d71ae5a4SJacob Faibussowitsch {
744150de0cbSStefano Zampini #if defined(PETSC_HAVE_WINDOWS_H)
74527e89126SStefano Zampini PetscFunctionBegin;
74627e89126SStefano Zampini SETERRQ(comm, PETSC_ERR_SUP, "Not implemented for Windows");
74727e89126SStefano Zampini #else
7488135c375SStefano Zampini FILE *stream = NULL;
749178bdba8SJose E. Roman int fd = 0;
7508135c375SStefano Zampini PetscErrorCode ierr;
751835f2295SStefano Zampini PetscMPIInt iport;
7528135c375SStefano Zampini
7538135c375SStefano Zampini PetscFunctionBegin;
7544f572ea9SToby Isaac PetscAssertPointer(hostname, 2);
7554f572ea9SToby Isaac PetscAssertPointer(viewer, 4);
756835f2295SStefano Zampini PetscCall(PetscMPIIntCast(port, &iport));
757c891a504SStefano Zampini #if defined(PETSC_USE_SOCKET_VIEWER)
758835f2295SStefano Zampini ierr = PetscOpenSocket(hostname, iport, &fd);
759c891a504SStefano Zampini #else
760c891a504SStefano Zampini SETERRQ(comm, PETSC_ERR_SUP, "Missing Socket viewer");
761c891a504SStefano Zampini #endif
7622da53a5bSBarry Smith /*
7632da53a5bSBarry Smith The following code is illegal in PETSc, one can NEVER attempt to recover once an error is initiated in PETSc.
7642da53a5bSBarry Smith The correct approach is to refactor PetscOpenSocket() to not initiate an error under certain conditions but instead either return a special value
7652da53a5bSBarry Smith of fd to indicate it was impossible to open the socket, or add another return argument to it indicating the socket was not opened.
7662da53a5bSBarry Smith */
7673ca90d2dSJacob Faibussowitsch if (PetscUnlikely(ierr)) {
7689d3446b2SPierre Jolivet PetscCall(PetscInfo(NULL, "Cannot connect to socket on %s:%" PetscInt_FMT ". Socket visualization is disabled\n", hostname, port));
7698135c375SStefano Zampini *viewer = NULL;
7703ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
7718135c375SStefano Zampini } else {
7729d3446b2SPierre Jolivet PetscCall(PetscInfo(NULL, "Successfully connect to socket on %s:%" PetscInt_FMT ". Socket visualization is enabled\n", hostname, port));
7738135c375SStefano Zampini }
7748135c375SStefano Zampini stream = fdopen(fd, "w"); /* Not possible on Windows */
77528b400f6SJacob Faibussowitsch PetscCheck(stream, PETSC_COMM_SELF, PETSC_ERR_SYS, "Cannot open stream from socket %s:%" PetscInt_FMT, hostname, port);
7769566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIOpenWithFILE(PETSC_COMM_SELF, stream, viewer));
7778135c375SStefano Zampini PetscViewerDestroy_ASCII = (*viewer)->ops->destroy;
7788135c375SStefano Zampini (*viewer)->ops->destroy = PetscViewerDestroy_ASCII_Socket;
77927e89126SStefano Zampini #endif
7803ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
7818135c375SStefano Zampini }
7820286d493SLisandro Dalcin
7830286d493SLisandro Dalcin #if !defined(PETSC_MISSING_SIGPIPE)
7840286d493SLisandro Dalcin
7850286d493SLisandro Dalcin #include <signal.h>
7860286d493SLisandro Dalcin
7870286d493SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H)
7880286d493SLisandro Dalcin #define PETSC_DEVNULL "NUL"
7890286d493SLisandro Dalcin #else
7900286d493SLisandro Dalcin #define PETSC_DEVNULL "/dev/null"
7910286d493SLisandro Dalcin #endif
7920286d493SLisandro Dalcin
7930286d493SLisandro Dalcin static volatile PetscBool PetscGLVisBrokenPipe = PETSC_FALSE;
7940286d493SLisandro Dalcin
7950286d493SLisandro Dalcin static void (*PetscGLVisSigHandler_save)(int) = NULL;
7960286d493SLisandro Dalcin
PetscGLVisSigHandler_SIGPIPE(PETSC_UNUSED int sig)797d71ae5a4SJacob Faibussowitsch static void PetscGLVisSigHandler_SIGPIPE(PETSC_UNUSED int sig)
798d71ae5a4SJacob Faibussowitsch {
7990286d493SLisandro Dalcin PetscGLVisBrokenPipe = PETSC_TRUE;
8000286d493SLisandro Dalcin #if !defined(PETSC_MISSING_SIG_IGN)
8010286d493SLisandro Dalcin signal(SIGPIPE, SIG_IGN);
8020286d493SLisandro Dalcin #endif
8030286d493SLisandro Dalcin }
8040286d493SLisandro Dalcin
PetscGLVisCollectiveBegin(PETSC_UNUSED MPI_Comm comm,PETSC_UNUSED PetscViewer * win)805d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscGLVisCollectiveBegin(PETSC_UNUSED MPI_Comm comm, PETSC_UNUSED PetscViewer *win)
806d71ae5a4SJacob Faibussowitsch {
8070286d493SLisandro Dalcin PetscFunctionBegin;
80828b400f6SJacob Faibussowitsch PetscCheck(!PetscGLVisSigHandler_save, comm, PETSC_ERR_PLIB, "Nested call to %s()", PETSC_FUNCTION_NAME);
8090286d493SLisandro Dalcin PetscGLVisBrokenPipe = PETSC_FALSE;
8100286d493SLisandro Dalcin PetscGLVisSigHandler_save = signal(SIGPIPE, PetscGLVisSigHandler_SIGPIPE);
8113ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
8120286d493SLisandro Dalcin }
8130286d493SLisandro Dalcin
PetscGLVisCollectiveEnd(MPI_Comm comm,PetscViewer * win)814d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscGLVisCollectiveEnd(MPI_Comm comm, PetscViewer *win)
815d71ae5a4SJacob Faibussowitsch {
8160286d493SLisandro Dalcin PetscBool flag, brokenpipe;
8170286d493SLisandro Dalcin
8180286d493SLisandro Dalcin PetscFunctionBegin;
8190286d493SLisandro Dalcin flag = PetscGLVisBrokenPipe;
8205440e5dcSBarry Smith PetscCallMPI(MPIU_Allreduce(&flag, &brokenpipe, 1, MPI_C_BOOL, MPI_LOR, comm));
8210286d493SLisandro Dalcin if (brokenpipe) {
8220286d493SLisandro Dalcin FILE *sock, *null = fopen(PETSC_DEVNULL, "w");
8239566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIGetPointer(*win, &sock));
8249566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetFILE(*win, null));
8259566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(win));
8260286d493SLisandro Dalcin if (sock) (void)fclose(sock);
8270286d493SLisandro Dalcin }
8280286d493SLisandro Dalcin (void)signal(SIGPIPE, PetscGLVisSigHandler_save);
8290286d493SLisandro Dalcin PetscGLVisSigHandler_save = NULL;
8300286d493SLisandro Dalcin PetscGLVisBrokenPipe = PETSC_FALSE;
8313ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
8320286d493SLisandro Dalcin }
8330286d493SLisandro Dalcin
8340286d493SLisandro Dalcin #else
8350286d493SLisandro Dalcin
PetscGLVisCollectiveBegin(PETSC_UNUSED MPI_Comm comm,PETSC_UNUSED PetscViewer * win)836d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscGLVisCollectiveBegin(PETSC_UNUSED MPI_Comm comm, PETSC_UNUSED PetscViewer *win)
837d71ae5a4SJacob Faibussowitsch {
8380286d493SLisandro Dalcin PetscFunctionBegin;
8393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
8400286d493SLisandro Dalcin }
8410286d493SLisandro Dalcin
PetscGLVisCollectiveEnd(PETSC_UNUSED MPI_Comm comm,PETSC_UNUSED PetscViewer * win)842d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscGLVisCollectiveEnd(PETSC_UNUSED MPI_Comm comm, PETSC_UNUSED PetscViewer *win)
843d71ae5a4SJacob Faibussowitsch {
8440286d493SLisandro Dalcin PetscFunctionBegin;
8453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
8460286d493SLisandro Dalcin }
8470286d493SLisandro Dalcin
8480286d493SLisandro Dalcin #endif
849