xref: /petsc/src/sys/classes/viewer/impls/mathematica/mathematica.c (revision 48a46eb9bd028bec07ec0f396b1a3abb43f14558)
15c6c1daeSBarry Smith 
2af0996ceSBarry Smith #include <petsc/private/viewerimpl.h> /* "petscsys.h" */
3af0996ceSBarry Smith #include <petsc/private/pcimpl.h>
45c6c1daeSBarry Smith #include <../src/mat/impls/aij/seq/aij.h>
55c6c1daeSBarry Smith #include <mathematica.h>
65c6c1daeSBarry Smith 
75c6c1daeSBarry Smith #if defined(PETSC_HAVE__SNPRINTF) && !defined(PETSC_HAVE_SNPRINTF)
85c6c1daeSBarry Smith #define snprintf _snprintf
95c6c1daeSBarry Smith #endif
105c6c1daeSBarry Smith 
110298fd71SBarry Smith PetscViewer  PETSC_VIEWER_MATHEMATICA_WORLD_PRIVATE = NULL;
120298fd71SBarry Smith static void *mathematicaEnv                         = NULL;
135c6c1daeSBarry Smith 
145c6c1daeSBarry Smith static PetscBool PetscViewerMathematicaPackageInitialized = PETSC_FALSE;
155c6c1daeSBarry Smith /*@C
165c6c1daeSBarry Smith   PetscViewerMathematicaFinalizePackage - This function destroys everything in the Petsc interface to Mathematica. It is
175c6c1daeSBarry Smith   called from PetscFinalize().
185c6c1daeSBarry Smith 
195c6c1daeSBarry Smith   Level: developer
205c6c1daeSBarry Smith 
21db781477SPatrick Sanan .seealso: `PetscFinalize()`
225c6c1daeSBarry Smith @*/
239371c9d4SSatish Balay PetscErrorCode   PetscViewerMathematicaFinalizePackage(void) {
245c6c1daeSBarry Smith     PetscFunctionBegin;
255c6c1daeSBarry Smith     if (mathematicaEnv) MLDeinitialize((MLEnvironment)mathematicaEnv);
265c6c1daeSBarry Smith   PetscViewerMathematicaPackageInitialized = PETSC_TRUE;
275c6c1daeSBarry Smith     PetscFunctionReturn(0);
285c6c1daeSBarry Smith }
295c6c1daeSBarry Smith 
305c6c1daeSBarry Smith /*@C
315c6c1daeSBarry Smith   PetscViewerMathematicaInitializePackage - This function initializes everything in the Petsc interface to Mathematica. It is
328a690491SBarry Smith   called from PetscViewerInitializePackage().
335c6c1daeSBarry Smith 
345c6c1daeSBarry Smith   Level: developer
355c6c1daeSBarry Smith 
36db781477SPatrick Sanan .seealso: `PetscSysInitializePackage()`, `PetscInitialize()`
375c6c1daeSBarry Smith @*/
389371c9d4SSatish Balay PetscErrorCode PetscViewerMathematicaInitializePackage(void) {
395c6c1daeSBarry Smith   PetscError ierr;
405c6c1daeSBarry Smith 
415c6c1daeSBarry Smith   PetscFunctionBegin;
425c6c1daeSBarry Smith   if (PetscViewerMathematicaPackageInitialized) PetscFunctionReturn(0);
435c6c1daeSBarry Smith   PetscViewerMathematicaPackageInitialized = PETSC_TRUE;
44a297a907SKarl Rupp 
455c6c1daeSBarry Smith   mathematicaEnv = (void *)MLInitialize(0);
46a297a907SKarl Rupp 
479566063dSJacob Faibussowitsch   PetscCall(PetscRegisterFinalize(PetscViewerMathematicaFinalizePackage));
485c6c1daeSBarry Smith   PetscFunctionReturn(0);
495c6c1daeSBarry Smith }
505c6c1daeSBarry Smith 
519371c9d4SSatish Balay PetscErrorCode PetscViewerInitializeMathematicaWorld_Private() {
525c6c1daeSBarry Smith   PetscFunctionBegin;
535c6c1daeSBarry Smith   if (PETSC_VIEWER_MATHEMATICA_WORLD_PRIVATE) PetscFunctionReturn(0);
549566063dSJacob Faibussowitsch   PetscCall(PetscViewerMathematicaOpen(PETSC_COMM_WORLD, PETSC_DECIDE, NULL, NULL, &PETSC_VIEWER_MATHEMATICA_WORLD_PRIVATE));
555c6c1daeSBarry Smith   PetscFunctionReturn(0);
565c6c1daeSBarry Smith }
575c6c1daeSBarry Smith 
589371c9d4SSatish Balay static PetscErrorCode PetscViewerDestroy_Mathematica(PetscViewer viewer) {
595c6c1daeSBarry Smith   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica *)viewer->data;
605c6c1daeSBarry Smith 
615c6c1daeSBarry Smith   PetscFunctionBegin;
625c6c1daeSBarry Smith   MLClose(vmath->link);
639566063dSJacob Faibussowitsch   PetscCall(PetscFree(vmath->linkname));
649566063dSJacob Faibussowitsch   PetscCall(PetscFree(vmath->linkhost));
659566063dSJacob Faibussowitsch   PetscCall(PetscFree(vmath));
665c6c1daeSBarry Smith   PetscFunctionReturn(0);
675c6c1daeSBarry Smith }
685c6c1daeSBarry Smith 
699371c9d4SSatish Balay PetscErrorCode PetscViewerDestroyMathematica_Private(void) {
705c6c1daeSBarry Smith   PetscFunctionBegin;
711baa6e33SBarry Smith   if (PETSC_VIEWER_MATHEMATICA_WORLD_PRIVATE) PetscCall(PetscViewerDestroy(PETSC_VIEWER_MATHEMATICA_WORLD_PRIVATE));
725c6c1daeSBarry Smith   PetscFunctionReturn(0);
735c6c1daeSBarry Smith }
745c6c1daeSBarry Smith 
759371c9d4SSatish Balay PetscErrorCode PetscViewerMathematicaSetupConnection_Private(PetscViewer v) {
765c6c1daeSBarry Smith   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica *)v->data;
77519f805aSKarl Rupp #if defined(MATHEMATICA_3_0)
785c6c1daeSBarry Smith   int   argc = 6;
795c6c1daeSBarry Smith   char *argv[6];
805c6c1daeSBarry Smith #else
815c6c1daeSBarry Smith   int   argc = 5;
825c6c1daeSBarry Smith   char *argv[5];
835c6c1daeSBarry Smith #endif
845c6c1daeSBarry Smith   char hostname[256];
855c6c1daeSBarry Smith   long lerr;
865c6c1daeSBarry Smith 
875c6c1daeSBarry Smith   PetscFunctionBegin;
885c6c1daeSBarry Smith   /* Link name */
895c6c1daeSBarry Smith   argv[0] = "-linkname";
90a297a907SKarl Rupp   if (!vmath->linkname) argv[1] = "math -mathlink";
91a297a907SKarl Rupp   else argv[1] = vmath->linkname;
925c6c1daeSBarry Smith 
935c6c1daeSBarry Smith   /* Link host */
945c6c1daeSBarry Smith   argv[2] = "-linkhost";
955c6c1daeSBarry Smith   if (!vmath->linkhost) {
969566063dSJacob Faibussowitsch     PetscCall(PetscGetHostName(hostname, sizeof(hostname)));
975c6c1daeSBarry Smith     argv[3] = hostname;
98a297a907SKarl Rupp   } else argv[3] = vmath->linkhost;
995c6c1daeSBarry Smith 
1005c6c1daeSBarry Smith     /* Link mode */
101519f805aSKarl Rupp #if defined(MATHEMATICA_3_0)
1025c6c1daeSBarry Smith   argv[4] = "-linkmode";
1035c6c1daeSBarry Smith   switch (vmath->linkmode) {
1049371c9d4SSatish Balay   case MATHEMATICA_LINK_CREATE: argv[5] = "Create"; break;
1059371c9d4SSatish Balay   case MATHEMATICA_LINK_CONNECT: argv[5] = "Connect"; break;
1069371c9d4SSatish Balay   case MATHEMATICA_LINK_LAUNCH: argv[5] = "Launch"; break;
1075c6c1daeSBarry Smith   }
1085c6c1daeSBarry Smith #else
1095c6c1daeSBarry Smith   switch (vmath->linkmode) {
1109371c9d4SSatish Balay   case MATHEMATICA_LINK_CREATE: argv[4] = "-linkcreate"; break;
1119371c9d4SSatish Balay   case MATHEMATICA_LINK_CONNECT: argv[4] = "-linkconnect"; break;
1129371c9d4SSatish Balay   case MATHEMATICA_LINK_LAUNCH: argv[4] = "-linklaunch"; break;
1135c6c1daeSBarry Smith   }
1145c6c1daeSBarry Smith #endif
1155c6c1daeSBarry Smith   vmath->link = MLOpenInEnv(mathematicaEnv, argc, argv, &lerr);
1165c6c1daeSBarry Smith #endif
1175c6c1daeSBarry Smith   PetscFunctionReturn(0);
1185c6c1daeSBarry Smith }
1195c6c1daeSBarry Smith 
1209371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode PetscViewerCreate_Mathematica(PetscViewer v) {
1215c6c1daeSBarry Smith   PetscViewer_Mathematica *vmath;
1225c6c1daeSBarry Smith 
1235c6c1daeSBarry Smith   PetscFunctionBegin;
1249566063dSJacob Faibussowitsch   PetscCall(PetscViewerMathematicaInitializePackage());
1255c6c1daeSBarry Smith 
1269566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(v, &vmath));
1275c6c1daeSBarry Smith   v->data         = (void *)vmath;
1285c6c1daeSBarry Smith   v->ops->destroy = PetscViewerDestroy_Mathematica;
1295c6c1daeSBarry Smith   v->ops->flush   = 0;
1309566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(PETSC_VIEWER_MATHEMATICA, &((PetscObject)v)->type_name));
1315c6c1daeSBarry Smith 
1320298fd71SBarry Smith   vmath->linkname     = NULL;
1330298fd71SBarry Smith   vmath->linkhost     = NULL;
1345c6c1daeSBarry Smith   vmath->linkmode     = MATHEMATICA_LINK_CONNECT;
1355c6c1daeSBarry Smith   vmath->graphicsType = GRAPHICS_MOTIF;
1365c6c1daeSBarry Smith   vmath->plotType     = MATHEMATICA_TRIANGULATION_PLOT;
1370298fd71SBarry Smith   vmath->objName      = NULL;
1385c6c1daeSBarry Smith 
1399566063dSJacob Faibussowitsch   PetscCall(PetscViewerMathematicaSetFromOptions(v));
1409566063dSJacob Faibussowitsch   PetscCall(PetscViewerMathematicaSetupConnection_Private(v));
1415c6c1daeSBarry Smith   PetscFunctionReturn(0);
1425c6c1daeSBarry Smith }
1435c6c1daeSBarry Smith 
1449371c9d4SSatish Balay static PetscErrorCode PetscViewerMathematicaParseLinkMode(char *modename, LinkMode *mode) {
1455c6c1daeSBarry Smith   PetscBool isCreate, isConnect, isLaunch;
1465c6c1daeSBarry Smith 
1475c6c1daeSBarry Smith   PetscFunctionBegin;
1489566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(modename, "Create", &isCreate));
1499566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(modename, "Connect", &isConnect));
1509566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(modename, "Launch", &isLaunch));
151a297a907SKarl Rupp   if (isCreate) *mode = MATHEMATICA_LINK_CREATE;
152a297a907SKarl Rupp   else if (isConnect) *mode = MATHEMATICA_LINK_CONNECT;
153a297a907SKarl Rupp   else if (isLaunch) *mode = MATHEMATICA_LINK_LAUNCH;
15498921bdaSJacob Faibussowitsch   else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid Mathematica link mode: %s", modename);
1555c6c1daeSBarry Smith   PetscFunctionReturn(0);
1565c6c1daeSBarry Smith }
1575c6c1daeSBarry Smith 
1589371c9d4SSatish Balay PetscErrorCode PetscViewerMathematicaSetFromOptions(PetscViewer v) {
1595c6c1daeSBarry Smith   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica *)v->data;
1605c6c1daeSBarry Smith   char                     linkname[256];
1615c6c1daeSBarry Smith   char                     modename[256];
1625c6c1daeSBarry Smith   char                     hostname[256];
1635c6c1daeSBarry Smith   char                     type[256];
1645c6c1daeSBarry Smith   PetscInt                 numPorts;
1655c6c1daeSBarry Smith   PetscInt                *ports;
1665c6c1daeSBarry Smith   PetscInt                 numHosts;
1675c6c1daeSBarry Smith   int                      h;
1685c6c1daeSBarry Smith   char                   **hosts;
1695c6c1daeSBarry Smith   PetscMPIInt              size, rank;
1705c6c1daeSBarry Smith   PetscBool                opt;
1715c6c1daeSBarry Smith 
1725c6c1daeSBarry Smith   PetscFunctionBegin;
1739566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)v), &size));
1749566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)v), &rank));
1755c6c1daeSBarry Smith 
1765c6c1daeSBarry Smith   /* Get link name */
1779566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetString("viewer_", "-math_linkname", linkname, sizeof(linkname), &opt));
1781baa6e33SBarry Smith   if (opt) PetscCall(PetscViewerMathematicaSetLinkName(v, linkname));
1795c6c1daeSBarry Smith   /* Get link port */
1805c6c1daeSBarry Smith   numPorts = size;
1819566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(size, &ports));
1829566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetIntArray("viewer_", "-math_linkport", ports, &numPorts, &opt));
1835c6c1daeSBarry Smith   if (opt) {
184589a23caSBarry Smith     if (numPorts > rank) snprintf(linkname, sizeof(linkname), "%6d", ports[rank]);
185589a23caSBarry Smith     else snprintf(linkname, sizeof(linkname), "%6d", ports[0]);
1869566063dSJacob Faibussowitsch     PetscCall(PetscViewerMathematicaSetLinkName(v, linkname));
1875c6c1daeSBarry Smith   }
1889566063dSJacob Faibussowitsch   PetscCall(PetscFree(ports));
1895c6c1daeSBarry Smith   /* Get link host */
1905c6c1daeSBarry Smith   numHosts = size;
1919566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(size, &hosts));
1929566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetStringArray("viewer_", "-math_linkhost", hosts, &numHosts, &opt));
1935c6c1daeSBarry Smith   if (opt) {
1945c6c1daeSBarry Smith     if (numHosts > rank) {
1959566063dSJacob Faibussowitsch       PetscCall(PetscStrncpy(hostname, hosts[rank], sizeof(hostname)));
1965c6c1daeSBarry Smith     } else {
1979566063dSJacob Faibussowitsch       PetscCall(PetscStrncpy(hostname, hosts[0], sizeof(hostname)));
1985c6c1daeSBarry Smith     }
1999566063dSJacob Faibussowitsch     PetscCall(PetscViewerMathematicaSetLinkHost(v, hostname));
2005c6c1daeSBarry Smith   }
201*48a46eb9SPierre Jolivet   for (h = 0; h < numHosts; h++) PetscCall(PetscFree(hosts[h]));
2029566063dSJacob Faibussowitsch   PetscCall(PetscFree(hosts));
2035c6c1daeSBarry Smith   /* Get link mode */
2049566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetString("viewer_", "-math_linkmode", modename, sizeof(modename), &opt));
2055c6c1daeSBarry Smith   if (opt) {
2065c6c1daeSBarry Smith     LinkMode mode;
2075c6c1daeSBarry Smith 
2089566063dSJacob Faibussowitsch     PetscCall(PetscViewerMathematicaParseLinkMode(modename, &mode));
2099566063dSJacob Faibussowitsch     PetscCall(PetscViewerMathematicaSetLinkMode(v, mode));
2105c6c1daeSBarry Smith   }
2115c6c1daeSBarry Smith   /* Get graphics type */
2129566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetString("viewer_", "-math_graphics", type, sizeof(type), &opt));
2135c6c1daeSBarry Smith   if (opt) {
2145c6c1daeSBarry Smith     PetscBool isMotif, isPS, isPSFile;
2155c6c1daeSBarry Smith 
2169566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(type, "Motif", &isMotif));
2179566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(type, "PS", &isPS));
2189566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(type, "PSFile", &isPSFile));
219a297a907SKarl Rupp     if (isMotif) vmath->graphicsType = GRAPHICS_MOTIF;
220a297a907SKarl Rupp     else if (isPS) vmath->graphicsType = GRAPHICS_PS_STDOUT;
221a297a907SKarl Rupp     else if (isPSFile) vmath->graphicsType = GRAPHICS_PS_FILE;
2225c6c1daeSBarry Smith   }
2235c6c1daeSBarry Smith   /* Get plot type */
2249566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetString("viewer_", "-math_type", type, sizeof(type), &opt));
2255c6c1daeSBarry Smith   if (opt) {
2265c6c1daeSBarry Smith     PetscBool isTri, isVecTri, isVec, isSurface;
2275c6c1daeSBarry Smith 
2289566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(type, "Triangulation", &isTri));
2299566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(type, "VectorTriangulation", &isVecTri));
2309566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(type, "Vector", &isVec));
2319566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(type, "Surface", &isSurface));
232a297a907SKarl Rupp     if (isTri) vmath->plotType = MATHEMATICA_TRIANGULATION_PLOT;
233a297a907SKarl Rupp     else if (isVecTri) vmath->plotType = MATHEMATICA_VECTOR_TRIANGULATION_PLOT;
234a297a907SKarl Rupp     else if (isVec) vmath->plotType = MATHEMATICA_VECTOR_PLOT;
235a297a907SKarl Rupp     else if (isSurface) vmath->plotType = MATHEMATICA_SURFACE_PLOT;
2365c6c1daeSBarry Smith   }
2375c6c1daeSBarry Smith   PetscFunctionReturn(0);
2385c6c1daeSBarry Smith }
2395c6c1daeSBarry Smith 
2409371c9d4SSatish Balay PetscErrorCode PetscViewerMathematicaSetLinkName(PetscViewer v, const char *name) {
2415c6c1daeSBarry Smith   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica *)v->data;
2425c6c1daeSBarry Smith 
2435c6c1daeSBarry Smith   PetscFunctionBegin;
2445c6c1daeSBarry Smith   PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 1);
2455c6c1daeSBarry Smith   PetscValidCharPointer(name, 2);
2469566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(name, &vmath->linkname));
2475c6c1daeSBarry Smith   PetscFunctionReturn(0);
2485c6c1daeSBarry Smith }
2495c6c1daeSBarry Smith 
2509371c9d4SSatish Balay PetscErrorCode PetscViewerMathematicaSetLinkPort(PetscViewer v, int port) {
2515c6c1daeSBarry Smith   char name[16];
2525c6c1daeSBarry Smith 
2535c6c1daeSBarry Smith   PetscFunctionBegin;
2545c6c1daeSBarry Smith   snprintf(name, 16, "%6d", port);
2559566063dSJacob Faibussowitsch   PetscCall(PetscViewerMathematicaSetLinkName(v, name));
2565c6c1daeSBarry Smith   PetscFunctionReturn(0);
2575c6c1daeSBarry Smith }
2585c6c1daeSBarry Smith 
2599371c9d4SSatish Balay PetscErrorCode PetscViewerMathematicaSetLinkHost(PetscViewer v, const char *host) {
2605c6c1daeSBarry Smith   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica *)v->data;
2615c6c1daeSBarry Smith 
2625c6c1daeSBarry Smith   PetscFunctionBegin;
2635c6c1daeSBarry Smith   PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 1);
2645c6c1daeSBarry Smith   PetscValidCharPointer(host, 2);
2659566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(host, &vmath->linkhost));
2665c6c1daeSBarry Smith   PetscFunctionReturn(0);
2675c6c1daeSBarry Smith }
2685c6c1daeSBarry Smith 
2699371c9d4SSatish Balay PetscErrorCode PetscViewerMathematicaSetLinkMode(PetscViewer v, LinkMode mode) {
2705c6c1daeSBarry Smith   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica *)v->data;
2715c6c1daeSBarry Smith 
2725c6c1daeSBarry Smith   PetscFunctionBegin;
2735c6c1daeSBarry Smith   vmath->linkmode = mode;
2745c6c1daeSBarry Smith   PetscFunctionReturn(0);
2755c6c1daeSBarry Smith }
2765c6c1daeSBarry Smith 
2775c6c1daeSBarry Smith /*----------------------------------------- Public Functions --------------------------------------------------------*/
2785c6c1daeSBarry Smith /*@C
2795c6c1daeSBarry Smith   PetscViewerMathematicaOpen - Communicates with Mathemtica using MathLink.
2805c6c1daeSBarry Smith 
281d083f849SBarry Smith   Collective
2825c6c1daeSBarry Smith 
2835c6c1daeSBarry Smith   Input Parameters:
2845c6c1daeSBarry Smith + comm    - The MPI communicator
2855c6c1daeSBarry Smith . port    - [optional] The port to connect on, or PETSC_DECIDE
2860298fd71SBarry Smith . machine - [optional] The machine to run Mathematica on, or NULL
2870298fd71SBarry Smith - mode    - [optional] The connection mode, or NULL
2885c6c1daeSBarry Smith 
2895c6c1daeSBarry Smith   Output Parameter:
2905c6c1daeSBarry Smith . viewer  - The Mathematica viewer
2915c6c1daeSBarry Smith 
2925c6c1daeSBarry Smith   Level: intermediate
2935c6c1daeSBarry Smith 
2945c6c1daeSBarry Smith   Notes:
2955c6c1daeSBarry Smith   Most users should employ the following commands to access the
2965c6c1daeSBarry Smith   Mathematica viewers
2975c6c1daeSBarry Smith $
2985c6c1daeSBarry Smith $    PetscViewerMathematicaOpen(MPI_Comm comm, int port, char *machine, char *mode, PetscViewer &viewer)
2995c6c1daeSBarry Smith $    MatView(Mat matrix, PetscViewer viewer)
3005c6c1daeSBarry Smith $
3015c6c1daeSBarry Smith $                or
3025c6c1daeSBarry Smith $
3035c6c1daeSBarry Smith $    PetscViewerMathematicaOpen(MPI_Comm comm, int port, char *machine, char *mode, PetscViewer &viewer)
3045c6c1daeSBarry Smith $    VecView(Vec vector, PetscViewer viewer)
3055c6c1daeSBarry Smith 
3065c6c1daeSBarry Smith    Options Database Keys:
307e1bc860dSBarry Smith +    -viewer_math_linkhost <machine> - The host machine for the kernel
308e1bc860dSBarry Smith .    -viewer_math_linkname <name>    - The full link name for the connection
309e1bc860dSBarry Smith .    -viewer_math_linkport <port>    - The port for the connection
310e1bc860dSBarry Smith .    -viewer_math_mode <mode>        - The mode, e.g. Launch, Connect
311e1bc860dSBarry Smith .    -viewer_math_type <type>        - The plot type, e.g. Triangulation, Vector
312e1bc860dSBarry Smith -    -viewer_math_graphics <output>  - The output type, e.g. Motif, PS, PSFile
3135c6c1daeSBarry Smith 
314db781477SPatrick Sanan .seealso: `MatView()`, `VecView()`
3155c6c1daeSBarry Smith @*/
3169371c9d4SSatish Balay PetscErrorCode PetscViewerMathematicaOpen(MPI_Comm comm, int port, const char machine[], const char mode[], PetscViewer *v) {
3175c6c1daeSBarry Smith   PetscFunctionBegin;
3189566063dSJacob Faibussowitsch   PetscCall(PetscViewerCreate(comm, v));
3195c6c1daeSBarry Smith #if 0
3205c6c1daeSBarry Smith   LinkMode linkmode;
3219566063dSJacob Faibussowitsch   PetscCall(PetscViewerMathematicaSetLinkPort(*v, port));
3229566063dSJacob Faibussowitsch   PetscCall(PetscViewerMathematicaSetLinkHost(*v, machine));
3239566063dSJacob Faibussowitsch   PetscCall(PetscViewerMathematicaParseLinkMode(mode, &linkmode));
3249566063dSJacob Faibussowitsch   PetscCall(PetscViewerMathematicaSetLinkMode(*v, linkmode));
3255c6c1daeSBarry Smith #endif
3269566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetType(*v, PETSC_VIEWER_MATHEMATICA));
3275c6c1daeSBarry Smith   PetscFunctionReturn(0);
3285c6c1daeSBarry Smith }
3295c6c1daeSBarry Smith 
3305c6c1daeSBarry Smith /*@C
3315c6c1daeSBarry Smith   PetscViewerMathematicaGetLink - Returns the link to Mathematica
3325c6c1daeSBarry Smith 
3335c6c1daeSBarry Smith   Input Parameters:
334a2b725a8SWilliam Gropp + viewer - The Mathematica viewer
335a2b725a8SWilliam Gropp - link   - The link to Mathematica
3365c6c1daeSBarry Smith 
3375c6c1daeSBarry Smith   Level: intermediate
3385c6c1daeSBarry Smith 
3395c6c1daeSBarry Smith .keywords PetscViewer, Mathematica, link
340db781477SPatrick Sanan .seealso `PetscViewerMathematicaOpen()`
3415c6c1daeSBarry Smith @*/
3429371c9d4SSatish Balay PetscErrorCode PetscViewerMathematicaGetLink(PetscViewer viewer, MLINK *link) {
3435c6c1daeSBarry Smith   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica *)viewer->data;
3445c6c1daeSBarry Smith 
3455c6c1daeSBarry Smith   PetscFunctionBegin;
3465c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
3475c6c1daeSBarry Smith   *link = vmath->link;
3485c6c1daeSBarry Smith   PetscFunctionReturn(0);
3495c6c1daeSBarry Smith }
3505c6c1daeSBarry Smith 
3515c6c1daeSBarry Smith /*@C
3525c6c1daeSBarry Smith   PetscViewerMathematicaSkipPackets - Discard packets sent by Mathematica until a certain packet type is received
3535c6c1daeSBarry Smith 
3545c6c1daeSBarry Smith   Input Parameters:
355a2b725a8SWilliam Gropp + viewer - The Mathematica viewer
356a2b725a8SWilliam Gropp - type   - The packet type to search for, e.g RETURNPKT
3575c6c1daeSBarry Smith 
3585c6c1daeSBarry Smith   Level: advanced
3595c6c1daeSBarry Smith 
3605c6c1daeSBarry Smith .keywords PetscViewer, Mathematica, packets
361db781477SPatrick Sanan .seealso `PetscViewerMathematicaSetName()`, `PetscViewerMathematicaGetVector()`
3625c6c1daeSBarry Smith @*/
3639371c9d4SSatish Balay PetscErrorCode PetscViewerMathematicaSkipPackets(PetscViewer viewer, int type) {
3645c6c1daeSBarry Smith   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica *)viewer->data;
3655c6c1daeSBarry Smith   MLINK                    link  = vmath->link; /* The link to Mathematica */
3665c6c1daeSBarry Smith   int                      pkt;                 /* The packet type */
3675c6c1daeSBarry Smith 
3685c6c1daeSBarry Smith   PetscFunctionBegin;
369a297a907SKarl Rupp   while ((pkt = MLNextPacket(link)) && (pkt != type)) MLNewPacket(link);
3705c6c1daeSBarry Smith   if (!pkt) {
3715c6c1daeSBarry Smith     MLClearError(link);
3725c6c1daeSBarry Smith     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, (char *)MLErrorMessage(link));
3735c6c1daeSBarry Smith   }
3745c6c1daeSBarry Smith   PetscFunctionReturn(0);
3755c6c1daeSBarry Smith }
3765c6c1daeSBarry Smith 
3775c6c1daeSBarry Smith /*@C
3785c6c1daeSBarry Smith   PetscViewerMathematicaGetName - Retrieve the default name for objects communicated to Mathematica
3795c6c1daeSBarry Smith 
3805c6c1daeSBarry Smith   Input Parameter:
3815c6c1daeSBarry Smith . viewer - The Mathematica viewer
3825c6c1daeSBarry Smith 
3835c6c1daeSBarry Smith   Output Parameter:
3845c6c1daeSBarry Smith . name   - The name for new objects created in Mathematica
3855c6c1daeSBarry Smith 
3865c6c1daeSBarry Smith   Level: intermediate
3875c6c1daeSBarry Smith 
3885c6c1daeSBarry Smith .keywords PetscViewer, Mathematica, name
389db781477SPatrick Sanan .seealso `PetscViewerMathematicaSetName()`, `PetscViewerMathematicaClearName()`
3905c6c1daeSBarry Smith @*/
3919371c9d4SSatish Balay PetscErrorCode PetscViewerMathematicaGetName(PetscViewer viewer, const char **name) {
3925c6c1daeSBarry Smith   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica *)viewer->data;
3935c6c1daeSBarry Smith 
3945c6c1daeSBarry Smith   PetscFunctionBegin;
3955c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
3965c6c1daeSBarry Smith   PetscValidPointer(name, 2);
3975c6c1daeSBarry Smith   *name = vmath->objName;
3985c6c1daeSBarry Smith   PetscFunctionReturn(0);
3995c6c1daeSBarry Smith }
4005c6c1daeSBarry Smith 
4015c6c1daeSBarry Smith /*@C
4025c6c1daeSBarry Smith   PetscViewerMathematicaSetName - Override the default name for objects communicated to Mathematica
4035c6c1daeSBarry Smith 
4045c6c1daeSBarry Smith   Input Parameters:
405a2b725a8SWilliam Gropp + viewer - The Mathematica viewer
406a2b725a8SWilliam Gropp - name   - The name for new objects created in Mathematica
4075c6c1daeSBarry Smith 
4085c6c1daeSBarry Smith   Level: intermediate
4095c6c1daeSBarry Smith 
4105c6c1daeSBarry Smith .keywords PetscViewer, Mathematica, name
411db781477SPatrick Sanan .seealso `PetscViewerMathematicaSetName()`, `PetscViewerMathematicaClearName()`
4125c6c1daeSBarry Smith @*/
4139371c9d4SSatish Balay PetscErrorCode PetscViewerMathematicaSetName(PetscViewer viewer, const char name[]) {
4145c6c1daeSBarry Smith   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica *)viewer->data;
4155c6c1daeSBarry Smith 
4165c6c1daeSBarry Smith   PetscFunctionBegin;
4175c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
4185c6c1daeSBarry Smith   PetscValidPointer(name, 2);
4195c6c1daeSBarry Smith   vmath->objName = name;
4205c6c1daeSBarry Smith   PetscFunctionReturn(0);
4215c6c1daeSBarry Smith }
4225c6c1daeSBarry Smith 
4235c6c1daeSBarry Smith /*@C
4245c6c1daeSBarry Smith   PetscViewerMathematicaClearName - Use the default name for objects communicated to Mathematica
4255c6c1daeSBarry Smith 
4265c6c1daeSBarry Smith   Input Parameter:
4275c6c1daeSBarry Smith . viewer - The Mathematica viewer
4285c6c1daeSBarry Smith 
4295c6c1daeSBarry Smith   Level: intermediate
4305c6c1daeSBarry Smith 
4315c6c1daeSBarry Smith .keywords PetscViewer, Mathematica, name
432db781477SPatrick Sanan .seealso `PetscViewerMathematicaGetName()`, `PetscViewerMathematicaSetName()`
4335c6c1daeSBarry Smith @*/
4349371c9d4SSatish Balay PetscErrorCode PetscViewerMathematicaClearName(PetscViewer viewer) {
4355c6c1daeSBarry Smith   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica *)viewer->data;
4365c6c1daeSBarry Smith 
4375c6c1daeSBarry Smith   PetscFunctionBegin;
4385c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
4390298fd71SBarry Smith   vmath->objName = NULL;
4405c6c1daeSBarry Smith   PetscFunctionReturn(0);
4415c6c1daeSBarry Smith }
4425c6c1daeSBarry Smith 
4435c6c1daeSBarry Smith /*@C
4445c6c1daeSBarry Smith   PetscViewerMathematicaGetVector - Retrieve a vector from Mathematica
4455c6c1daeSBarry Smith 
4465c6c1daeSBarry Smith   Input Parameter:
4475c6c1daeSBarry Smith . viewer - The Mathematica viewer
4485c6c1daeSBarry Smith 
4495c6c1daeSBarry Smith   Output Parameter:
4505c6c1daeSBarry Smith . v      - The vector
4515c6c1daeSBarry Smith 
4525c6c1daeSBarry Smith   Level: intermediate
4535c6c1daeSBarry Smith 
4545c6c1daeSBarry Smith .keywords PetscViewer, Mathematica, vector
455db781477SPatrick Sanan .seealso `VecView()`, `PetscViewerMathematicaPutVector()`
4565c6c1daeSBarry Smith @*/
4579371c9d4SSatish Balay PetscErrorCode PetscViewerMathematicaGetVector(PetscViewer viewer, Vec v) {
4585c6c1daeSBarry Smith   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica *)viewer->data;
4595c6c1daeSBarry Smith   MLINK                    link; /* The link to Mathematica */
4605c6c1daeSBarry Smith   char                    *name;
4615c6c1daeSBarry Smith   PetscScalar             *mArray, *array;
4625c6c1daeSBarry Smith   long                     mSize;
4635c6c1daeSBarry Smith   int                      n;
4645c6c1daeSBarry Smith 
4655c6c1daeSBarry Smith   PetscFunctionBegin;
4665c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
4675c6c1daeSBarry Smith   PetscValidHeaderSpecific(v, VEC_CLASSID, 2);
4685c6c1daeSBarry Smith 
4695c6c1daeSBarry Smith   /* Determine the object name */
470a297a907SKarl Rupp   if (!vmath->objName) name = "vec";
471a297a907SKarl Rupp   else name = (char *)vmath->objName;
4725c6c1daeSBarry Smith 
4735c6c1daeSBarry Smith   link = vmath->link;
4749566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(v, &n));
4759566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v, &array));
4765c6c1daeSBarry Smith   MLPutFunction(link, "EvaluatePacket", 1);
4775c6c1daeSBarry Smith   MLPutSymbol(link, name);
4785c6c1daeSBarry Smith   MLEndPacket(link);
4799566063dSJacob Faibussowitsch   PetscCall(PetscViewerMathematicaSkipPackets(viewer, RETURNPKT));
4805c6c1daeSBarry Smith   MLGetRealList(link, &mArray, &mSize);
48108401ef6SPierre Jolivet   PetscCheck(n == mSize, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Incompatible vector sizes %d %d", n, mSize);
4829566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(array, mArray, mSize));
4835c6c1daeSBarry Smith   MLDisownRealList(link, mArray, mSize);
4849566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v, &array));
4855c6c1daeSBarry Smith   PetscFunctionReturn(0);
4865c6c1daeSBarry Smith }
4875c6c1daeSBarry Smith 
4885c6c1daeSBarry Smith /*@C
4895c6c1daeSBarry Smith   PetscViewerMathematicaPutVector - Send a vector to Mathematica
4905c6c1daeSBarry Smith 
4915c6c1daeSBarry Smith   Input Parameters:
4925c6c1daeSBarry Smith + viewer - The Mathematica viewer
4935c6c1daeSBarry Smith - v      - The vector
4945c6c1daeSBarry Smith 
4955c6c1daeSBarry Smith   Level: intermediate
4965c6c1daeSBarry Smith 
4975c6c1daeSBarry Smith .keywords PetscViewer, Mathematica, vector
498db781477SPatrick Sanan .seealso `VecView()`, `PetscViewerMathematicaGetVector()`
4995c6c1daeSBarry Smith @*/
5009371c9d4SSatish Balay PetscErrorCode PetscViewerMathematicaPutVector(PetscViewer viewer, Vec v) {
5015c6c1daeSBarry Smith   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica *)viewer->data;
5025c6c1daeSBarry Smith   MLINK                    link  = vmath->link; /* The link to Mathematica */
5035c6c1daeSBarry Smith   char                    *name;
5045c6c1daeSBarry Smith   PetscScalar             *array;
5055c6c1daeSBarry Smith   int                      n;
5065c6c1daeSBarry Smith 
5075c6c1daeSBarry Smith   PetscFunctionBegin;
5085c6c1daeSBarry Smith   /* Determine the object name */
509a297a907SKarl Rupp   if (!vmath->objName) name = "vec";
510a297a907SKarl Rupp   else name = (char *)vmath->objName;
511a297a907SKarl Rupp 
5129566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(v, &n));
5139566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v, &array));
5145c6c1daeSBarry Smith 
5155c6c1daeSBarry Smith   /* Send the Vector object */
5165c6c1daeSBarry Smith   MLPutFunction(link, "EvaluatePacket", 1);
5175c6c1daeSBarry Smith   MLPutFunction(link, "Set", 2);
5185c6c1daeSBarry Smith   MLPutSymbol(link, name);
5195c6c1daeSBarry Smith   MLPutRealList(link, array, n);
5205c6c1daeSBarry Smith   MLEndPacket(link);
5215c6c1daeSBarry Smith   /* Skip packets until ReturnPacket */
5229566063dSJacob Faibussowitsch   PetscCall(PetscViewerMathematicaSkipPackets(viewer, RETURNPKT));
5235c6c1daeSBarry Smith   /* Skip ReturnPacket */
5245c6c1daeSBarry Smith   MLNewPacket(link);
5255c6c1daeSBarry Smith 
5269566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v, &array));
5275c6c1daeSBarry Smith   PetscFunctionReturn(0);
5285c6c1daeSBarry Smith }
5295c6c1daeSBarry Smith 
5309371c9d4SSatish Balay PetscErrorCode PetscViewerMathematicaPutMatrix(PetscViewer viewer, int m, int n, PetscReal *a) {
5315c6c1daeSBarry Smith   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica *)viewer->data;
5325c6c1daeSBarry Smith   MLINK                    link  = vmath->link; /* The link to Mathematica */
5335c6c1daeSBarry Smith   char                    *name;
5345c6c1daeSBarry Smith 
5355c6c1daeSBarry Smith   PetscFunctionBegin;
5365c6c1daeSBarry Smith   /* Determine the object name */
537a297a907SKarl Rupp   if (!vmath->objName) name = "mat";
538a297a907SKarl Rupp   else name = (char *)vmath->objName;
5395c6c1daeSBarry Smith 
5405c6c1daeSBarry Smith   /* Send the dense matrix object */
5415c6c1daeSBarry Smith   MLPutFunction(link, "EvaluatePacket", 1);
5425c6c1daeSBarry Smith   MLPutFunction(link, "Set", 2);
5435c6c1daeSBarry Smith   MLPutSymbol(link, name);
5445c6c1daeSBarry Smith   MLPutFunction(link, "Transpose", 1);
5455c6c1daeSBarry Smith   MLPutFunction(link, "Partition", 2);
5465c6c1daeSBarry Smith   MLPutRealList(link, a, m * n);
5475c6c1daeSBarry Smith   MLPutInteger(link, m);
5485c6c1daeSBarry Smith   MLEndPacket(link);
5495c6c1daeSBarry Smith   /* Skip packets until ReturnPacket */
5509566063dSJacob Faibussowitsch   PetscCall(PetscViewerMathematicaSkipPackets(viewer, RETURNPKT));
5515c6c1daeSBarry Smith   /* Skip ReturnPacket */
5525c6c1daeSBarry Smith   MLNewPacket(link);
5535c6c1daeSBarry Smith   PetscFunctionReturn(0);
5545c6c1daeSBarry Smith }
5555c6c1daeSBarry Smith 
5569371c9d4SSatish Balay PetscErrorCode PetscViewerMathematicaPutCSRMatrix(PetscViewer viewer, int m, int n, int *i, int *j, PetscReal *a) {
5575c6c1daeSBarry Smith   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica *)viewer->data;
5585c6c1daeSBarry Smith   MLINK                    link  = vmath->link; /* The link to Mathematica */
5595c6c1daeSBarry Smith   const char              *symbol;
5605c6c1daeSBarry Smith   char                    *name;
5615c6c1daeSBarry Smith   PetscBool                match;
5625c6c1daeSBarry Smith 
5635c6c1daeSBarry Smith   PetscFunctionBegin;
5645c6c1daeSBarry Smith   /* Determine the object name */
565a297a907SKarl Rupp   if (!vmath->objName) name = "mat";
566a297a907SKarl Rupp   else name = (char *)vmath->objName;
5675c6c1daeSBarry Smith 
5685c6c1daeSBarry Smith   /* Make sure Mathematica recognizes sparse matrices */
5695c6c1daeSBarry Smith   MLPutFunction(link, "EvaluatePacket", 1);
5705c6c1daeSBarry Smith   MLPutFunction(link, "Needs", 1);
5715c6c1daeSBarry Smith   MLPutString(link, "LinearAlgebra`CSRMatrix`");
5725c6c1daeSBarry Smith   MLEndPacket(link);
5735c6c1daeSBarry Smith   /* Skip packets until ReturnPacket */
5749566063dSJacob Faibussowitsch   PetscCall(PetscViewerMathematicaSkipPackets(viewer, RETURNPKT));
5755c6c1daeSBarry Smith   /* Skip ReturnPacket */
5765c6c1daeSBarry Smith   MLNewPacket(link);
5775c6c1daeSBarry Smith 
5785c6c1daeSBarry Smith   /* Send the CSRMatrix object */
5795c6c1daeSBarry Smith   MLPutFunction(link, "EvaluatePacket", 1);
5805c6c1daeSBarry Smith   MLPutFunction(link, "Set", 2);
5815c6c1daeSBarry Smith   MLPutSymbol(link, name);
5825c6c1daeSBarry Smith   MLPutFunction(link, "CSRMatrix", 5);
5835c6c1daeSBarry Smith   MLPutInteger(link, m);
5845c6c1daeSBarry Smith   MLPutInteger(link, n);
5855c6c1daeSBarry Smith   MLPutFunction(link, "Plus", 2);
5865c6c1daeSBarry Smith   MLPutIntegerList(link, i, m + 1);
5875c6c1daeSBarry Smith   MLPutInteger(link, 1);
5885c6c1daeSBarry Smith   MLPutFunction(link, "Plus", 2);
5895c6c1daeSBarry Smith   MLPutIntegerList(link, j, i[m]);
5905c6c1daeSBarry Smith   MLPutInteger(link, 1);
5915c6c1daeSBarry Smith   MLPutRealList(link, a, i[m]);
5925c6c1daeSBarry Smith   MLEndPacket(link);
5935c6c1daeSBarry Smith   /* Skip packets until ReturnPacket */
5949566063dSJacob Faibussowitsch   PetscCall(PetscViewerMathematicaSkipPackets(viewer, RETURNPKT));
5955c6c1daeSBarry Smith   /* Skip ReturnPacket */
5965c6c1daeSBarry Smith   MLNewPacket(link);
5975c6c1daeSBarry Smith 
5985c6c1daeSBarry Smith   /* Check that matrix is valid */
5995c6c1daeSBarry Smith   MLPutFunction(link, "EvaluatePacket", 1);
6005c6c1daeSBarry Smith   MLPutFunction(link, "ValidQ", 1);
6015c6c1daeSBarry Smith   MLPutSymbol(link, name);
6025c6c1daeSBarry Smith   MLEndPacket(link);
6039566063dSJacob Faibussowitsch   PetscCall(PetscViewerMathematicaSkipPackets(viewer, RETURNPKT));
6045c6c1daeSBarry Smith   MLGetSymbol(link, &symbol);
6059566063dSJacob Faibussowitsch   PetscCall(PetscStrcmp("True", (char *)symbol, &match));
6065c6c1daeSBarry Smith   if (!match) {
6075c6c1daeSBarry Smith     MLDisownSymbol(link, symbol);
6085c6c1daeSBarry Smith     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Invalid CSR matrix in Mathematica");
6095c6c1daeSBarry Smith   }
6105c6c1daeSBarry Smith   MLDisownSymbol(link, symbol);
6115c6c1daeSBarry Smith   /* Skip ReturnPacket */
6125c6c1daeSBarry Smith   MLNewPacket(link);
6135c6c1daeSBarry Smith   PetscFunctionReturn(0);
6145c6c1daeSBarry Smith }
615