xref: /petsc/src/sys/classes/viewer/impls/mathematica/mathematica.c (revision cc4c1da905d89950b196b027190941013bd3e15a)
1af0996ceSBarry Smith #include <petsc/private/viewerimpl.h> /* "petscsys.h" */
2af0996ceSBarry Smith #include <petsc/private/pcimpl.h>
35c6c1daeSBarry Smith #include <../src/mat/impls/aij/seq/aij.h>
45c6c1daeSBarry Smith #include <mathematica.h>
55c6c1daeSBarry Smith 
65c6c1daeSBarry Smith #if defined(PETSC_HAVE__SNPRINTF) && !defined(PETSC_HAVE_SNPRINTF)
75c6c1daeSBarry Smith   #define snprintf _snprintf
85c6c1daeSBarry Smith #endif
95c6c1daeSBarry Smith 
100298fd71SBarry Smith PetscViewer  PETSC_VIEWER_MATHEMATICA_WORLD_PRIVATE = NULL;
110298fd71SBarry Smith static void *mathematicaEnv                         = NULL;
125c6c1daeSBarry Smith 
135c6c1daeSBarry Smith static PetscBool PetscViewerMathematicaPackageInitialized = PETSC_FALSE;
145c6c1daeSBarry Smith /*@C
155c6c1daeSBarry Smith   PetscViewerMathematicaFinalizePackage - This function destroys everything in the Petsc interface to Mathematica. It is
165c6c1daeSBarry Smith   called from PetscFinalize().
175c6c1daeSBarry Smith 
185c6c1daeSBarry Smith   Level: developer
195c6c1daeSBarry Smith 
20db781477SPatrick Sanan .seealso: `PetscFinalize()`
215c6c1daeSBarry Smith @*/
22d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerMathematicaFinalizePackage(void)
23d71ae5a4SJacob Faibussowitsch {
245c6c1daeSBarry Smith   PetscFunctionBegin;
255c6c1daeSBarry Smith   if (mathematicaEnv) MLDeinitialize((MLEnvironment)mathematicaEnv);
265c6c1daeSBarry Smith   PetscViewerMathematicaPackageInitialized = PETSC_TRUE;
273ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
285c6c1daeSBarry Smith }
295c6c1daeSBarry Smith 
305c6c1daeSBarry Smith /*@C
315c6c1daeSBarry Smith   PetscViewerMathematicaInitializePackage - This function initializes everything in the Petsc interface to Mathematica. It is
32811af0c4SBarry Smith   called from `PetscViewerInitializePackage()`.
335c6c1daeSBarry Smith 
345c6c1daeSBarry Smith   Level: developer
355c6c1daeSBarry Smith 
36db781477SPatrick Sanan .seealso: `PetscSysInitializePackage()`, `PetscInitialize()`
375c6c1daeSBarry Smith @*/
38d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerMathematicaInitializePackage(void)
39d71ae5a4SJacob Faibussowitsch {
405c6c1daeSBarry Smith   PetscError ierr;
415c6c1daeSBarry Smith 
425c6c1daeSBarry Smith   PetscFunctionBegin;
433ba16761SJacob Faibussowitsch   if (PetscViewerMathematicaPackageInitialized) PetscFunctionReturn(PETSC_SUCCESS);
445c6c1daeSBarry Smith   PetscViewerMathematicaPackageInitialized = PETSC_TRUE;
45a297a907SKarl Rupp 
465c6c1daeSBarry Smith   mathematicaEnv = (void *)MLInitialize(0);
47a297a907SKarl Rupp 
489566063dSJacob Faibussowitsch   PetscCall(PetscRegisterFinalize(PetscViewerMathematicaFinalizePackage));
493ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
505c6c1daeSBarry Smith }
515c6c1daeSBarry Smith 
5266976f2fSJacob Faibussowitsch static PetscErrorCode PetscViewerInitializeMathematicaWorld_Private()
53d71ae5a4SJacob Faibussowitsch {
545c6c1daeSBarry Smith   PetscFunctionBegin;
553ba16761SJacob Faibussowitsch   if (PETSC_VIEWER_MATHEMATICA_WORLD_PRIVATE) PetscFunctionReturn(PETSC_SUCCESS);
569566063dSJacob Faibussowitsch   PetscCall(PetscViewerMathematicaOpen(PETSC_COMM_WORLD, PETSC_DECIDE, NULL, NULL, &PETSC_VIEWER_MATHEMATICA_WORLD_PRIVATE));
573ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
585c6c1daeSBarry Smith }
595c6c1daeSBarry Smith 
60d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscViewerDestroy_Mathematica(PetscViewer viewer)
61d71ae5a4SJacob Faibussowitsch {
625c6c1daeSBarry Smith   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica *)viewer->data;
635c6c1daeSBarry Smith 
645c6c1daeSBarry Smith   PetscFunctionBegin;
655c6c1daeSBarry Smith   MLClose(vmath->link);
669566063dSJacob Faibussowitsch   PetscCall(PetscFree(vmath->linkname));
679566063dSJacob Faibussowitsch   PetscCall(PetscFree(vmath->linkhost));
689566063dSJacob Faibussowitsch   PetscCall(PetscFree(vmath));
693ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
705c6c1daeSBarry Smith }
715c6c1daeSBarry Smith 
7266976f2fSJacob Faibussowitsch static PetscErrorCode PetscViewerDestroyMathematica_Private(void)
73d71ae5a4SJacob Faibussowitsch {
745c6c1daeSBarry Smith   PetscFunctionBegin;
751baa6e33SBarry Smith   if (PETSC_VIEWER_MATHEMATICA_WORLD_PRIVATE) PetscCall(PetscViewerDestroy(PETSC_VIEWER_MATHEMATICA_WORLD_PRIVATE));
763ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
775c6c1daeSBarry Smith }
785c6c1daeSBarry Smith 
7966976f2fSJacob Faibussowitsch static PetscErrorCode PetscViewerMathematicaSetupConnection_Private(PetscViewer v)
80d71ae5a4SJacob Faibussowitsch {
815c6c1daeSBarry Smith   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica *)v->data;
82519f805aSKarl Rupp #if defined(MATHEMATICA_3_0)
835c6c1daeSBarry Smith   int   argc = 6;
845c6c1daeSBarry Smith   char *argv[6];
855c6c1daeSBarry Smith #else
865c6c1daeSBarry Smith   int   argc = 5;
875c6c1daeSBarry Smith   char *argv[5];
885c6c1daeSBarry Smith #endif
895c6c1daeSBarry Smith   char hostname[256];
905c6c1daeSBarry Smith   long lerr;
915c6c1daeSBarry Smith 
925c6c1daeSBarry Smith   PetscFunctionBegin;
935c6c1daeSBarry Smith   /* Link name */
945c6c1daeSBarry Smith   argv[0] = "-linkname";
95a297a907SKarl Rupp   if (!vmath->linkname) argv[1] = "math -mathlink";
96a297a907SKarl Rupp   else argv[1] = vmath->linkname;
975c6c1daeSBarry Smith 
985c6c1daeSBarry Smith   /* Link host */
995c6c1daeSBarry Smith   argv[2] = "-linkhost";
1005c6c1daeSBarry Smith   if (!vmath->linkhost) {
1019566063dSJacob Faibussowitsch     PetscCall(PetscGetHostName(hostname, sizeof(hostname)));
1025c6c1daeSBarry Smith     argv[3] = hostname;
103a297a907SKarl Rupp   } else argv[3] = vmath->linkhost;
1045c6c1daeSBarry Smith 
1055c6c1daeSBarry Smith     /* Link mode */
106519f805aSKarl Rupp #if defined(MATHEMATICA_3_0)
1075c6c1daeSBarry Smith   argv[4] = "-linkmode";
1085c6c1daeSBarry Smith   switch (vmath->linkmode) {
109d71ae5a4SJacob Faibussowitsch   case MATHEMATICA_LINK_CREATE:
110d71ae5a4SJacob Faibussowitsch     argv[5] = "Create";
111d71ae5a4SJacob Faibussowitsch     break;
112d71ae5a4SJacob Faibussowitsch   case MATHEMATICA_LINK_CONNECT:
113d71ae5a4SJacob Faibussowitsch     argv[5] = "Connect";
114d71ae5a4SJacob Faibussowitsch     break;
115d71ae5a4SJacob Faibussowitsch   case MATHEMATICA_LINK_LAUNCH:
116d71ae5a4SJacob Faibussowitsch     argv[5] = "Launch";
117d71ae5a4SJacob Faibussowitsch     break;
1185c6c1daeSBarry Smith   }
1195c6c1daeSBarry Smith #else
1205c6c1daeSBarry Smith   switch (vmath->linkmode) {
121d71ae5a4SJacob Faibussowitsch   case MATHEMATICA_LINK_CREATE:
122d71ae5a4SJacob Faibussowitsch     argv[4] = "-linkcreate";
123d71ae5a4SJacob Faibussowitsch     break;
124d71ae5a4SJacob Faibussowitsch   case MATHEMATICA_LINK_CONNECT:
125d71ae5a4SJacob Faibussowitsch     argv[4] = "-linkconnect";
126d71ae5a4SJacob Faibussowitsch     break;
127d71ae5a4SJacob Faibussowitsch   case MATHEMATICA_LINK_LAUNCH:
128d71ae5a4SJacob Faibussowitsch     argv[4] = "-linklaunch";
129d71ae5a4SJacob Faibussowitsch     break;
1305c6c1daeSBarry Smith   }
1315c6c1daeSBarry Smith #endif
1325c6c1daeSBarry Smith   vmath->link = MLOpenInEnv(mathematicaEnv, argc, argv, &lerr);
1335c6c1daeSBarry Smith #endif
1343ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1355c6c1daeSBarry Smith }
1365c6c1daeSBarry Smith 
137d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscViewerCreate_Mathematica(PetscViewer v)
138d71ae5a4SJacob Faibussowitsch {
1395c6c1daeSBarry Smith   PetscViewer_Mathematica *vmath;
1405c6c1daeSBarry Smith 
1415c6c1daeSBarry Smith   PetscFunctionBegin;
1429566063dSJacob Faibussowitsch   PetscCall(PetscViewerMathematicaInitializePackage());
1435c6c1daeSBarry Smith 
1444dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&vmath));
1455c6c1daeSBarry Smith   v->data         = (void *)vmath;
1465c6c1daeSBarry Smith   v->ops->destroy = PetscViewerDestroy_Mathematica;
1475c6c1daeSBarry Smith   v->ops->flush   = 0;
1489566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(PETSC_VIEWER_MATHEMATICA, &((PetscObject)v)->type_name));
1495c6c1daeSBarry Smith 
1500298fd71SBarry Smith   vmath->linkname     = NULL;
1510298fd71SBarry Smith   vmath->linkhost     = NULL;
1525c6c1daeSBarry Smith   vmath->linkmode     = MATHEMATICA_LINK_CONNECT;
1535c6c1daeSBarry Smith   vmath->graphicsType = GRAPHICS_MOTIF;
1545c6c1daeSBarry Smith   vmath->plotType     = MATHEMATICA_TRIANGULATION_PLOT;
1550298fd71SBarry Smith   vmath->objName      = NULL;
1565c6c1daeSBarry Smith 
1579566063dSJacob Faibussowitsch   PetscCall(PetscViewerMathematicaSetFromOptions(v));
1589566063dSJacob Faibussowitsch   PetscCall(PetscViewerMathematicaSetupConnection_Private(v));
1593ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1605c6c1daeSBarry Smith }
1615c6c1daeSBarry Smith 
162d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscViewerMathematicaParseLinkMode(char *modename, LinkMode *mode)
163d71ae5a4SJacob Faibussowitsch {
1645c6c1daeSBarry Smith   PetscBool isCreate, isConnect, isLaunch;
1655c6c1daeSBarry Smith 
1665c6c1daeSBarry Smith   PetscFunctionBegin;
1679566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(modename, "Create", &isCreate));
1689566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(modename, "Connect", &isConnect));
1699566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(modename, "Launch", &isLaunch));
170a297a907SKarl Rupp   if (isCreate) *mode = MATHEMATICA_LINK_CREATE;
171a297a907SKarl Rupp   else if (isConnect) *mode = MATHEMATICA_LINK_CONNECT;
172a297a907SKarl Rupp   else if (isLaunch) *mode = MATHEMATICA_LINK_LAUNCH;
17398921bdaSJacob Faibussowitsch   else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid Mathematica link mode: %s", modename);
1743ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1755c6c1daeSBarry Smith }
1765c6c1daeSBarry Smith 
177d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerMathematicaSetFromOptions(PetscViewer v)
178d71ae5a4SJacob Faibussowitsch {
1795c6c1daeSBarry Smith   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica *)v->data;
1805c6c1daeSBarry Smith   char                     linkname[256];
1815c6c1daeSBarry Smith   char                     modename[256];
1825c6c1daeSBarry Smith   char                     hostname[256];
1835c6c1daeSBarry Smith   char                     type[256];
1845c6c1daeSBarry Smith   PetscInt                 numPorts;
1855c6c1daeSBarry Smith   PetscInt                *ports;
1865c6c1daeSBarry Smith   PetscInt                 numHosts;
1875c6c1daeSBarry Smith   int                      h;
1885c6c1daeSBarry Smith   char                   **hosts;
1895c6c1daeSBarry Smith   PetscMPIInt              size, rank;
1905c6c1daeSBarry Smith   PetscBool                opt;
1915c6c1daeSBarry Smith 
1925c6c1daeSBarry Smith   PetscFunctionBegin;
1939566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)v), &size));
1949566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)v), &rank));
1955c6c1daeSBarry Smith 
1965c6c1daeSBarry Smith   /* Get link name */
1979566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetString("viewer_", "-math_linkname", linkname, sizeof(linkname), &opt));
1981baa6e33SBarry Smith   if (opt) PetscCall(PetscViewerMathematicaSetLinkName(v, linkname));
1995c6c1daeSBarry Smith   /* Get link port */
2005c6c1daeSBarry Smith   numPorts = size;
2019566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(size, &ports));
2029566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetIntArray("viewer_", "-math_linkport", ports, &numPorts, &opt));
2035c6c1daeSBarry Smith   if (opt) {
204589a23caSBarry Smith     if (numPorts > rank) snprintf(linkname, sizeof(linkname), "%6d", ports[rank]);
205589a23caSBarry Smith     else snprintf(linkname, sizeof(linkname), "%6d", ports[0]);
2069566063dSJacob Faibussowitsch     PetscCall(PetscViewerMathematicaSetLinkName(v, linkname));
2075c6c1daeSBarry Smith   }
2089566063dSJacob Faibussowitsch   PetscCall(PetscFree(ports));
2095c6c1daeSBarry Smith   /* Get link host */
2105c6c1daeSBarry Smith   numHosts = size;
2119566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(size, &hosts));
2129566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetStringArray("viewer_", "-math_linkhost", hosts, &numHosts, &opt));
2135c6c1daeSBarry Smith   if (opt) {
2145c6c1daeSBarry Smith     if (numHosts > rank) {
2159566063dSJacob Faibussowitsch       PetscCall(PetscStrncpy(hostname, hosts[rank], sizeof(hostname)));
2165c6c1daeSBarry Smith     } else {
2179566063dSJacob Faibussowitsch       PetscCall(PetscStrncpy(hostname, hosts[0], sizeof(hostname)));
2185c6c1daeSBarry Smith     }
2199566063dSJacob Faibussowitsch     PetscCall(PetscViewerMathematicaSetLinkHost(v, hostname));
2205c6c1daeSBarry Smith   }
22148a46eb9SPierre Jolivet   for (h = 0; h < numHosts; h++) PetscCall(PetscFree(hosts[h]));
2229566063dSJacob Faibussowitsch   PetscCall(PetscFree(hosts));
2235c6c1daeSBarry Smith   /* Get link mode */
2249566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetString("viewer_", "-math_linkmode", modename, sizeof(modename), &opt));
2255c6c1daeSBarry Smith   if (opt) {
2265c6c1daeSBarry Smith     LinkMode mode;
2275c6c1daeSBarry Smith 
2289566063dSJacob Faibussowitsch     PetscCall(PetscViewerMathematicaParseLinkMode(modename, &mode));
2299566063dSJacob Faibussowitsch     PetscCall(PetscViewerMathematicaSetLinkMode(v, mode));
2305c6c1daeSBarry Smith   }
2315c6c1daeSBarry Smith   /* Get graphics type */
2329566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetString("viewer_", "-math_graphics", type, sizeof(type), &opt));
2335c6c1daeSBarry Smith   if (opt) {
2345c6c1daeSBarry Smith     PetscBool isMotif, isPS, isPSFile;
2355c6c1daeSBarry Smith 
2369566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(type, "Motif", &isMotif));
2379566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(type, "PS", &isPS));
2389566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(type, "PSFile", &isPSFile));
239a297a907SKarl Rupp     if (isMotif) vmath->graphicsType = GRAPHICS_MOTIF;
240a297a907SKarl Rupp     else if (isPS) vmath->graphicsType = GRAPHICS_PS_STDOUT;
241a297a907SKarl Rupp     else if (isPSFile) vmath->graphicsType = GRAPHICS_PS_FILE;
2425c6c1daeSBarry Smith   }
2435c6c1daeSBarry Smith   /* Get plot type */
2449566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetString("viewer_", "-math_type", type, sizeof(type), &opt));
2455c6c1daeSBarry Smith   if (opt) {
2465c6c1daeSBarry Smith     PetscBool isTri, isVecTri, isVec, isSurface;
2475c6c1daeSBarry Smith 
2489566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(type, "Triangulation", &isTri));
2499566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(type, "VectorTriangulation", &isVecTri));
2509566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(type, "Vector", &isVec));
2519566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(type, "Surface", &isSurface));
252a297a907SKarl Rupp     if (isTri) vmath->plotType = MATHEMATICA_TRIANGULATION_PLOT;
253a297a907SKarl Rupp     else if (isVecTri) vmath->plotType = MATHEMATICA_VECTOR_TRIANGULATION_PLOT;
254a297a907SKarl Rupp     else if (isVec) vmath->plotType = MATHEMATICA_VECTOR_PLOT;
255a297a907SKarl Rupp     else if (isSurface) vmath->plotType = MATHEMATICA_SURFACE_PLOT;
2565c6c1daeSBarry Smith   }
2573ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2585c6c1daeSBarry Smith }
2595c6c1daeSBarry Smith 
260d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerMathematicaSetLinkName(PetscViewer v, const char *name)
261d71ae5a4SJacob Faibussowitsch {
2625c6c1daeSBarry Smith   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica *)v->data;
2635c6c1daeSBarry Smith 
2645c6c1daeSBarry Smith   PetscFunctionBegin;
2655c6c1daeSBarry Smith   PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 1);
2664f572ea9SToby Isaac   PetscAssertPointer(name, 2);
2679566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(name, &vmath->linkname));
2683ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2695c6c1daeSBarry Smith }
2705c6c1daeSBarry Smith 
271d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerMathematicaSetLinkPort(PetscViewer v, int port)
272d71ae5a4SJacob Faibussowitsch {
2735c6c1daeSBarry Smith   char name[16];
2745c6c1daeSBarry Smith 
2755c6c1daeSBarry Smith   PetscFunctionBegin;
2765c6c1daeSBarry Smith   snprintf(name, 16, "%6d", port);
2779566063dSJacob Faibussowitsch   PetscCall(PetscViewerMathematicaSetLinkName(v, name));
2783ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2795c6c1daeSBarry Smith }
2805c6c1daeSBarry Smith 
281d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerMathematicaSetLinkHost(PetscViewer v, const char *host)
282d71ae5a4SJacob Faibussowitsch {
2835c6c1daeSBarry Smith   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica *)v->data;
2845c6c1daeSBarry Smith 
2855c6c1daeSBarry Smith   PetscFunctionBegin;
2865c6c1daeSBarry Smith   PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 1);
2874f572ea9SToby Isaac   PetscAssertPointer(host, 2);
2889566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(host, &vmath->linkhost));
2893ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2905c6c1daeSBarry Smith }
2915c6c1daeSBarry Smith 
292d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerMathematicaSetLinkMode(PetscViewer v, LinkMode mode)
293d71ae5a4SJacob Faibussowitsch {
2945c6c1daeSBarry Smith   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica *)v->data;
2955c6c1daeSBarry Smith 
2965c6c1daeSBarry Smith   PetscFunctionBegin;
2975c6c1daeSBarry Smith   vmath->linkmode = mode;
2983ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2995c6c1daeSBarry Smith }
3005c6c1daeSBarry Smith 
3015c6c1daeSBarry Smith /*----------------------------------------- Public Functions --------------------------------------------------------*/
302*cc4c1da9SBarry Smith /*@
3035c6c1daeSBarry Smith   PetscViewerMathematicaOpen - Communicates with Mathemtica using MathLink.
3045c6c1daeSBarry Smith 
305d083f849SBarry Smith   Collective
3065c6c1daeSBarry Smith 
3075c6c1daeSBarry Smith   Input Parameters:
3085c6c1daeSBarry Smith + comm    - The MPI communicator
3095c6c1daeSBarry Smith . port    - [optional] The port to connect on, or PETSC_DECIDE
3100298fd71SBarry Smith . machine - [optional] The machine to run Mathematica on, or NULL
3110298fd71SBarry Smith - mode    - [optional] The connection mode, or NULL
3125c6c1daeSBarry Smith 
3135c6c1daeSBarry Smith   Output Parameter:
314aec76313SJacob Faibussowitsch . v - The Mathematica viewer
3155c6c1daeSBarry Smith 
3165c6c1daeSBarry Smith   Options Database Keys:
317e1bc860dSBarry Smith + -viewer_math_linkhost <machine> - The host machine for the kernel
318e1bc860dSBarry Smith . -viewer_math_linkname <name>    - The full link name for the connection
319e1bc860dSBarry Smith . -viewer_math_linkport <port>    - The port for the connection
320e1bc860dSBarry Smith . -viewer_math_mode <mode>        - The mode, e.g. Launch, Connect
321e1bc860dSBarry Smith . -viewer_math_type <type>        - The plot type, e.g. Triangulation, Vector
322e1bc860dSBarry Smith - -viewer_math_graphics <output>  - The output type, e.g. Motif, PS, PSFile
3235c6c1daeSBarry Smith 
324811af0c4SBarry Smith   Level: intermediate
325811af0c4SBarry Smith 
326811af0c4SBarry Smith   Note:
327811af0c4SBarry Smith   Most users should employ the following commands to access the
328811af0c4SBarry Smith   Mathematica viewers
329811af0c4SBarry Smith .vb
330811af0c4SBarry Smith     PetscViewerMathematicaOpen(MPI_Comm comm, int port, char *machine, char *mode, PetscViewer &viewer)
331811af0c4SBarry Smith     MatView(Mat matrix, PetscViewer viewer)
332811af0c4SBarry Smith 
333811af0c4SBarry Smith                 or
334811af0c4SBarry Smith 
335811af0c4SBarry Smith     PetscViewerMathematicaOpen(MPI_Comm comm, int port, char *machine, char *mode, PetscViewer &viewer)
336811af0c4SBarry Smith     VecView(Vec vector, PetscViewer viewer)
337811af0c4SBarry Smith .ve
338811af0c4SBarry Smith 
339811af0c4SBarry Smith .seealso: `PETSCVIEWERMATHEMATICA`, `MatView()`, `VecView()`
3405c6c1daeSBarry Smith @*/
341d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerMathematicaOpen(MPI_Comm comm, int port, const char machine[], const char mode[], PetscViewer *v)
342d71ae5a4SJacob Faibussowitsch {
3435c6c1daeSBarry Smith   PetscFunctionBegin;
3449566063dSJacob Faibussowitsch   PetscCall(PetscViewerCreate(comm, v));
3455c6c1daeSBarry Smith #if 0
3465c6c1daeSBarry Smith   LinkMode linkmode;
3479566063dSJacob Faibussowitsch   PetscCall(PetscViewerMathematicaSetLinkPort(*v, port));
3489566063dSJacob Faibussowitsch   PetscCall(PetscViewerMathematicaSetLinkHost(*v, machine));
3499566063dSJacob Faibussowitsch   PetscCall(PetscViewerMathematicaParseLinkMode(mode, &linkmode));
3509566063dSJacob Faibussowitsch   PetscCall(PetscViewerMathematicaSetLinkMode(*v, linkmode));
3515c6c1daeSBarry Smith #endif
3529566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetType(*v, PETSC_VIEWER_MATHEMATICA));
3533ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3545c6c1daeSBarry Smith }
3555c6c1daeSBarry Smith 
35666976f2fSJacob Faibussowitsch /*
357811af0c4SBarry Smith   PetscViewerMathematicaGetLink - Returns the link to Mathematica from a `PETSCVIEWERMATHEMATICA`
3585c6c1daeSBarry Smith 
3595c6c1daeSBarry Smith   Input Parameters:
360a2b725a8SWilliam Gropp + viewer - The Mathematica viewer
361a2b725a8SWilliam Gropp - link   - The link to Mathematica
3625c6c1daeSBarry Smith 
3635c6c1daeSBarry Smith   Level: intermediate
3645c6c1daeSBarry Smith 
365811af0c4SBarry Smith .seealso: `PETSCVIEWERMATHEMATICA`, `PetscViewerMathematicaOpen()`
36666976f2fSJacob Faibussowitsch */
36766976f2fSJacob Faibussowitsch static PetscErrorCode PetscViewerMathematicaGetLink(PetscViewer viewer, MLINK *link)
368d71ae5a4SJacob Faibussowitsch {
3695c6c1daeSBarry Smith   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica *)viewer->data;
3705c6c1daeSBarry Smith 
3715c6c1daeSBarry Smith   PetscFunctionBegin;
3725c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
3735c6c1daeSBarry Smith   *link = vmath->link;
3743ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3755c6c1daeSBarry Smith }
3765c6c1daeSBarry Smith 
3775c6c1daeSBarry Smith /*@C
3785c6c1daeSBarry Smith   PetscViewerMathematicaSkipPackets - Discard packets sent by Mathematica until a certain packet type is received
3795c6c1daeSBarry Smith 
3805c6c1daeSBarry Smith   Input Parameters:
381a2b725a8SWilliam Gropp + viewer - The Mathematica viewer
382a2b725a8SWilliam Gropp - type   - The packet type to search for, e.g RETURNPKT
3835c6c1daeSBarry Smith 
3845c6c1daeSBarry Smith   Level: advanced
3855c6c1daeSBarry Smith 
386811af0c4SBarry Smith .seealso: `PetscViewerMathematicaSetName()`, `PetscViewerMathematicaGetVector()`
3875c6c1daeSBarry Smith @*/
388d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerMathematicaSkipPackets(PetscViewer viewer, int type)
389d71ae5a4SJacob Faibussowitsch {
3905c6c1daeSBarry Smith   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica *)viewer->data;
3915c6c1daeSBarry Smith   MLINK                    link  = vmath->link; /* The link to Mathematica */
3925c6c1daeSBarry Smith   int                      pkt;                 /* The packet type */
3935c6c1daeSBarry Smith 
3945c6c1daeSBarry Smith   PetscFunctionBegin;
395a297a907SKarl Rupp   while ((pkt = MLNextPacket(link)) && (pkt != type)) MLNewPacket(link);
3965c6c1daeSBarry Smith   if (!pkt) {
3975c6c1daeSBarry Smith     MLClearError(link);
3985c6c1daeSBarry Smith     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, (char *)MLErrorMessage(link));
3995c6c1daeSBarry Smith   }
4003ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4015c6c1daeSBarry Smith }
4025c6c1daeSBarry Smith 
4035c6c1daeSBarry Smith /*@C
404811af0c4SBarry Smith   PetscViewerMathematicaGetName - Retrieve the default name for objects communicated to Mathematica via `PETSCVIEWERMATHEMATICA`
4055c6c1daeSBarry Smith 
4065c6c1daeSBarry Smith   Input Parameter:
4075c6c1daeSBarry Smith . viewer - The Mathematica viewer
4085c6c1daeSBarry Smith 
4095c6c1daeSBarry Smith   Output Parameter:
4105c6c1daeSBarry Smith . name - The name for new objects created in Mathematica
4115c6c1daeSBarry Smith 
4125c6c1daeSBarry Smith   Level: intermediate
4135c6c1daeSBarry Smith 
414811af0c4SBarry Smith .seealso: `PETSCVIEWERMATHEMATICA`, `PetscViewerMathematicaSetName()`, `PetscViewerMathematicaClearName()`
4155c6c1daeSBarry Smith @*/
416d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerMathematicaGetName(PetscViewer viewer, const char **name)
417d71ae5a4SJacob Faibussowitsch {
4185c6c1daeSBarry Smith   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica *)viewer->data;
4195c6c1daeSBarry Smith 
4205c6c1daeSBarry Smith   PetscFunctionBegin;
4215c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
4224f572ea9SToby Isaac   PetscAssertPointer(name, 2);
4235c6c1daeSBarry Smith   *name = vmath->objName;
4243ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4255c6c1daeSBarry Smith }
4265c6c1daeSBarry Smith 
4275c6c1daeSBarry Smith /*@C
428811af0c4SBarry Smith   PetscViewerMathematicaSetName - Override the default name for objects communicated to Mathematica via `PETSCVIEWERMATHEMATICA`
4295c6c1daeSBarry Smith 
4305c6c1daeSBarry Smith   Input Parameters:
431a2b725a8SWilliam Gropp + viewer - The Mathematica viewer
432a2b725a8SWilliam Gropp - name   - The name for new objects created in Mathematica
4335c6c1daeSBarry Smith 
4345c6c1daeSBarry Smith   Level: intermediate
4355c6c1daeSBarry Smith 
43642747ad1SJacob Faibussowitsch .seealso: `PETSCVIEWERMATHEMATICA`, `PetscViewerMathematicaClearName()`
4375c6c1daeSBarry Smith @*/
438d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerMathematicaSetName(PetscViewer viewer, const char name[])
439d71ae5a4SJacob Faibussowitsch {
4405c6c1daeSBarry Smith   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica *)viewer->data;
4415c6c1daeSBarry Smith 
4425c6c1daeSBarry Smith   PetscFunctionBegin;
4435c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
4444f572ea9SToby Isaac   PetscAssertPointer(name, 2);
4455c6c1daeSBarry Smith   vmath->objName = name;
4463ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4475c6c1daeSBarry Smith }
4485c6c1daeSBarry Smith 
449811af0c4SBarry Smith /*@
4505c6c1daeSBarry Smith   PetscViewerMathematicaClearName - Use the default name for objects communicated to Mathematica
4515c6c1daeSBarry Smith 
4525c6c1daeSBarry Smith   Input Parameter:
4535c6c1daeSBarry Smith . viewer - The Mathematica viewer
4545c6c1daeSBarry Smith 
4555c6c1daeSBarry Smith   Level: intermediate
4565c6c1daeSBarry Smith 
457811af0c4SBarry Smith .seealso: `PETSCVIEWERMATHEMATICA`, `PetscViewerMathematicaGetName()`, `PetscViewerMathematicaSetName()`
4585c6c1daeSBarry Smith @*/
459d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerMathematicaClearName(PetscViewer viewer)
460d71ae5a4SJacob Faibussowitsch {
4615c6c1daeSBarry Smith   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica *)viewer->data;
4625c6c1daeSBarry Smith 
4635c6c1daeSBarry Smith   PetscFunctionBegin;
4645c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
4650298fd71SBarry Smith   vmath->objName = NULL;
4663ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4675c6c1daeSBarry Smith }
4685c6c1daeSBarry Smith 
469811af0c4SBarry Smith /*@
470811af0c4SBarry Smith   PetscViewerMathematicaGetVector - Retrieve a vector from Mathematica via a `PETSCVIEWERMATHEMATICA`
4715c6c1daeSBarry Smith 
4725c6c1daeSBarry Smith   Input Parameter:
4735c6c1daeSBarry Smith . viewer - The Mathematica viewer
4745c6c1daeSBarry Smith 
4755c6c1daeSBarry Smith   Output Parameter:
4765c6c1daeSBarry Smith . v - The vector
4775c6c1daeSBarry Smith 
4785c6c1daeSBarry Smith   Level: intermediate
4795c6c1daeSBarry Smith 
480811af0c4SBarry Smith .seealso: `PETSCVIEWERMATHEMATICA`, `VecView()`, `PetscViewerMathematicaPutVector()`
4815c6c1daeSBarry Smith @*/
482d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerMathematicaGetVector(PetscViewer viewer, Vec v)
483d71ae5a4SJacob Faibussowitsch {
4845c6c1daeSBarry Smith   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica *)viewer->data;
4855c6c1daeSBarry Smith   MLINK                    link; /* The link to Mathematica */
4865c6c1daeSBarry Smith   char                    *name;
4875c6c1daeSBarry Smith   PetscScalar             *mArray, *array;
4885c6c1daeSBarry Smith   long                     mSize;
4895c6c1daeSBarry Smith   int                      n;
4905c6c1daeSBarry Smith 
4915c6c1daeSBarry Smith   PetscFunctionBegin;
4925c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
4935c6c1daeSBarry Smith   PetscValidHeaderSpecific(v, VEC_CLASSID, 2);
4945c6c1daeSBarry Smith 
4955c6c1daeSBarry Smith   /* Determine the object name */
496a297a907SKarl Rupp   if (!vmath->objName) name = "vec";
497a297a907SKarl Rupp   else name = (char *)vmath->objName;
4985c6c1daeSBarry Smith 
4995c6c1daeSBarry Smith   link = vmath->link;
5009566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(v, &n));
5019566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v, &array));
5025c6c1daeSBarry Smith   MLPutFunction(link, "EvaluatePacket", 1);
5035c6c1daeSBarry Smith   MLPutSymbol(link, name);
5045c6c1daeSBarry Smith   MLEndPacket(link);
5059566063dSJacob Faibussowitsch   PetscCall(PetscViewerMathematicaSkipPackets(viewer, RETURNPKT));
5065c6c1daeSBarry Smith   MLGetRealList(link, &mArray, &mSize);
50708401ef6SPierre Jolivet   PetscCheck(n == mSize, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Incompatible vector sizes %d %d", n, mSize);
5089566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(array, mArray, mSize));
5095c6c1daeSBarry Smith   MLDisownRealList(link, mArray, mSize);
5109566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v, &array));
5113ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5125c6c1daeSBarry Smith }
5135c6c1daeSBarry Smith 
514811af0c4SBarry Smith /*@
515811af0c4SBarry Smith   PetscViewerMathematicaPutVector - Send a vector to Mathematica via a `PETSCVIEWERMATHEMATICA` `PetscViewer`
5165c6c1daeSBarry Smith 
5175c6c1daeSBarry Smith   Input Parameters:
5185c6c1daeSBarry Smith + viewer - The Mathematica viewer
5195c6c1daeSBarry Smith - v      - The vector
5205c6c1daeSBarry Smith 
5215c6c1daeSBarry Smith   Level: intermediate
5225c6c1daeSBarry Smith 
523811af0c4SBarry Smith .seealso: `PETSCVIEWERMATHEMATICA`, `VecView()`, `PetscViewerMathematicaGetVector()`
5245c6c1daeSBarry Smith @*/
525d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerMathematicaPutVector(PetscViewer viewer, Vec v)
526d71ae5a4SJacob Faibussowitsch {
5275c6c1daeSBarry Smith   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica *)viewer->data;
5285c6c1daeSBarry Smith   MLINK                    link  = vmath->link; /* The link to Mathematica */
5295c6c1daeSBarry Smith   char                    *name;
5305c6c1daeSBarry Smith   PetscScalar             *array;
5315c6c1daeSBarry Smith   int                      n;
5325c6c1daeSBarry Smith 
5335c6c1daeSBarry Smith   PetscFunctionBegin;
5345c6c1daeSBarry Smith   /* Determine the object name */
535a297a907SKarl Rupp   if (!vmath->objName) name = "vec";
536a297a907SKarl Rupp   else name = (char *)vmath->objName;
537a297a907SKarl Rupp 
5389566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(v, &n));
5399566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v, &array));
5405c6c1daeSBarry Smith 
5415c6c1daeSBarry Smith   /* Send the Vector object */
5425c6c1daeSBarry Smith   MLPutFunction(link, "EvaluatePacket", 1);
5435c6c1daeSBarry Smith   MLPutFunction(link, "Set", 2);
5445c6c1daeSBarry Smith   MLPutSymbol(link, name);
5455c6c1daeSBarry Smith   MLPutRealList(link, array, n);
5465c6c1daeSBarry Smith   MLEndPacket(link);
5475c6c1daeSBarry Smith   /* Skip packets until ReturnPacket */
5489566063dSJacob Faibussowitsch   PetscCall(PetscViewerMathematicaSkipPackets(viewer, RETURNPKT));
5495c6c1daeSBarry Smith   /* Skip ReturnPacket */
5505c6c1daeSBarry Smith   MLNewPacket(link);
5515c6c1daeSBarry Smith 
5529566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v, &array));
5533ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5545c6c1daeSBarry Smith }
5555c6c1daeSBarry Smith 
556d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerMathematicaPutMatrix(PetscViewer viewer, int m, int n, PetscReal *a)
557d71ae5a4SJacob Faibussowitsch {
5585c6c1daeSBarry Smith   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica *)viewer->data;
5595c6c1daeSBarry Smith   MLINK                    link  = vmath->link; /* The link to Mathematica */
5605c6c1daeSBarry Smith   char                    *name;
5615c6c1daeSBarry Smith 
5625c6c1daeSBarry Smith   PetscFunctionBegin;
5635c6c1daeSBarry Smith   /* Determine the object name */
564a297a907SKarl Rupp   if (!vmath->objName) name = "mat";
565a297a907SKarl Rupp   else name = (char *)vmath->objName;
5665c6c1daeSBarry Smith 
5675c6c1daeSBarry Smith   /* Send the dense matrix object */
5685c6c1daeSBarry Smith   MLPutFunction(link, "EvaluatePacket", 1);
5695c6c1daeSBarry Smith   MLPutFunction(link, "Set", 2);
5705c6c1daeSBarry Smith   MLPutSymbol(link, name);
5715c6c1daeSBarry Smith   MLPutFunction(link, "Transpose", 1);
5725c6c1daeSBarry Smith   MLPutFunction(link, "Partition", 2);
5735c6c1daeSBarry Smith   MLPutRealList(link, a, m * n);
5745c6c1daeSBarry Smith   MLPutInteger(link, m);
5755c6c1daeSBarry Smith   MLEndPacket(link);
5765c6c1daeSBarry Smith   /* Skip packets until ReturnPacket */
5779566063dSJacob Faibussowitsch   PetscCall(PetscViewerMathematicaSkipPackets(viewer, RETURNPKT));
5785c6c1daeSBarry Smith   /* Skip ReturnPacket */
5795c6c1daeSBarry Smith   MLNewPacket(link);
5803ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5815c6c1daeSBarry Smith }
5825c6c1daeSBarry Smith 
583d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerMathematicaPutCSRMatrix(PetscViewer viewer, int m, int n, int *i, int *j, PetscReal *a)
584d71ae5a4SJacob Faibussowitsch {
5855c6c1daeSBarry Smith   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica *)viewer->data;
5865c6c1daeSBarry Smith   MLINK                    link  = vmath->link; /* The link to Mathematica */
5875c6c1daeSBarry Smith   const char              *symbol;
5885c6c1daeSBarry Smith   char                    *name;
5895c6c1daeSBarry Smith   PetscBool                match;
5905c6c1daeSBarry Smith 
5915c6c1daeSBarry Smith   PetscFunctionBegin;
5925c6c1daeSBarry Smith   /* Determine the object name */
593a297a907SKarl Rupp   if (!vmath->objName) name = "mat";
594a297a907SKarl Rupp   else name = (char *)vmath->objName;
5955c6c1daeSBarry Smith 
5965c6c1daeSBarry Smith   /* Make sure Mathematica recognizes sparse matrices */
5975c6c1daeSBarry Smith   MLPutFunction(link, "EvaluatePacket", 1);
5985c6c1daeSBarry Smith   MLPutFunction(link, "Needs", 1);
5995c6c1daeSBarry Smith   MLPutString(link, "LinearAlgebra`CSRMatrix`");
6005c6c1daeSBarry Smith   MLEndPacket(link);
6015c6c1daeSBarry Smith   /* Skip packets until ReturnPacket */
6029566063dSJacob Faibussowitsch   PetscCall(PetscViewerMathematicaSkipPackets(viewer, RETURNPKT));
6035c6c1daeSBarry Smith   /* Skip ReturnPacket */
6045c6c1daeSBarry Smith   MLNewPacket(link);
6055c6c1daeSBarry Smith 
6065c6c1daeSBarry Smith   /* Send the CSRMatrix object */
6075c6c1daeSBarry Smith   MLPutFunction(link, "EvaluatePacket", 1);
6085c6c1daeSBarry Smith   MLPutFunction(link, "Set", 2);
6095c6c1daeSBarry Smith   MLPutSymbol(link, name);
6105c6c1daeSBarry Smith   MLPutFunction(link, "CSRMatrix", 5);
6115c6c1daeSBarry Smith   MLPutInteger(link, m);
6125c6c1daeSBarry Smith   MLPutInteger(link, n);
6135c6c1daeSBarry Smith   MLPutFunction(link, "Plus", 2);
6145c6c1daeSBarry Smith   MLPutIntegerList(link, i, m + 1);
6155c6c1daeSBarry Smith   MLPutInteger(link, 1);
6165c6c1daeSBarry Smith   MLPutFunction(link, "Plus", 2);
6175c6c1daeSBarry Smith   MLPutIntegerList(link, j, i[m]);
6185c6c1daeSBarry Smith   MLPutInteger(link, 1);
6195c6c1daeSBarry Smith   MLPutRealList(link, a, i[m]);
6205c6c1daeSBarry Smith   MLEndPacket(link);
6215c6c1daeSBarry Smith   /* Skip packets until ReturnPacket */
6229566063dSJacob Faibussowitsch   PetscCall(PetscViewerMathematicaSkipPackets(viewer, RETURNPKT));
6235c6c1daeSBarry Smith   /* Skip ReturnPacket */
6245c6c1daeSBarry Smith   MLNewPacket(link);
6255c6c1daeSBarry Smith 
6265c6c1daeSBarry Smith   /* Check that matrix is valid */
6275c6c1daeSBarry Smith   MLPutFunction(link, "EvaluatePacket", 1);
6285c6c1daeSBarry Smith   MLPutFunction(link, "ValidQ", 1);
6295c6c1daeSBarry Smith   MLPutSymbol(link, name);
6305c6c1daeSBarry Smith   MLEndPacket(link);
6319566063dSJacob Faibussowitsch   PetscCall(PetscViewerMathematicaSkipPackets(viewer, RETURNPKT));
6325c6c1daeSBarry Smith   MLGetSymbol(link, &symbol);
6339566063dSJacob Faibussowitsch   PetscCall(PetscStrcmp("True", (char *)symbol, &match));
6345c6c1daeSBarry Smith   if (!match) {
6355c6c1daeSBarry Smith     MLDisownSymbol(link, symbol);
6365c6c1daeSBarry Smith     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Invalid CSR matrix in Mathematica");
6375c6c1daeSBarry Smith   }
6385c6c1daeSBarry Smith   MLDisownSymbol(link, symbol);
6395c6c1daeSBarry Smith   /* Skip ReturnPacket */
6405c6c1daeSBarry Smith   MLNewPacket(link);
6413ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6425c6c1daeSBarry Smith }
643