Date: 2013-07-02T14:38:09+00:00

Actual source code: mathematica.c
petsc-3.4.2 2013-07-02

      2: #include <petsc-private/viewerimpl.h>   /* "petscsys.h" */
      3: #include <petsc-private/pcimpl.h>
      4: #include <../src/mat/impls/aij/seq/aij.h>
      5: #include <mathematica.h>

      7: #if defined(PETSC_HAVE__SNPRINTF) && !defined(PETSC_HAVE_SNPRINTF)
      8: #define snprintf _snprintf
      9: #endif

     11: PetscViewer PETSC_VIEWER_MATHEMATICA_WORLD_PRIVATE = NULL;
     12: static void *mathematicaEnv                        = NULL;

     14: static PetscBool PetscViewerMathematicaPackageInitialized = PETSC_FALSE;
     17: /*@C
     18:   PetscViewerMathematicaFinalizePackage - This function destroys everything in the Petsc interface to Mathematica. It is
     19:   called from PetscFinalize().

     21:   Level: developer

     23: .keywords: Petsc, destroy, package, mathematica
     24: .seealso: PetscFinalize()
     25: @*/
     26: PetscErrorCode  PetscViewerMathematicaFinalizePackage(void)
     27: {
     29:   if (mathematicaEnv) MLDeinitialize((MLEnvironment) mathematicaEnv);
     30:   PetscViewerMathematicaPackageInitialized = PETSC_TRUE;
     31:   return(0);
     32: }

     36: /*@C
     37:   PetscViewerMathematicaInitializePackage - This function initializes everything in the Petsc interface to Mathematica. It is
     38:   called from PetscDLLibraryRegister() when using dynamic libraries, and on the call to PetscInitialize()
     39:   when using static libraries.

     41:   Level: developer

     43: .keywords: Petsc, initialize, package
     44: .seealso: PetscSysInitializePackage(), PetscInitialize()
     45: @*/
     46: PetscErrorCode  PetscViewerMathematicaInitializePackage(void)
     47: {
     48:   PetscError ierr;

     51:   if (PetscViewerMathematicaPackageInitialized) return(0);
     52:   PetscViewerMathematicaPackageInitialized = PETSC_TRUE;

     54:   mathematicaEnv = (void*) MLInitialize(0);

     56:   PetscRegisterFinalize(PetscViewerMathematicaFinalizePackage);
     57:   return(0);
     58: }

     63: PetscErrorCode PetscViewerInitializeMathematicaWorld_Private()
     64: {

     68:   if (PETSC_VIEWER_MATHEMATICA_WORLD_PRIVATE) return(0);
     69:   PetscViewerMathematicaOpen(PETSC_COMM_WORLD, PETSC_DECIDE, NULL, NULL, &PETSC_VIEWER_MATHEMATICA_WORLD_PRIVATE);
     70:   return(0);
     71: }

     75: static PetscErrorCode PetscViewerDestroy_Mathematica(PetscViewer viewer)
     76: {
     77:   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica*) viewer->data;
     78:   PetscErrorCode          ierr;

     81:   MLClose(vmath->link);
     82:   PetscFree(vmath->linkname);
     83:   PetscFree(vmath->linkhost);
     84:   PetscFree(vmath);
     85:   return(0);
     86: }

     90: PetscErrorCode PetscViewerDestroyMathematica_Private(void)
     91: {

     95:   if (PETSC_VIEWER_MATHEMATICA_WORLD_PRIVATE) {
     96:     PetscViewerDestroy(PETSC_VIEWER_MATHEMATICA_WORLD_PRIVATE);
     97:   }
     98:   return(0);
     99: }

    103: PetscErrorCode PetscViewerMathematicaSetupConnection_Private(PetscViewer v)
    104: {
    105:   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica*) v->data;
    106: #if defined(MATHEMATICA_3_0)
    107:   int                     argc = 6;
    108:   char                    *argv[6];
    109: #else
    110:   int                     argc = 5;
    111:   char                    *argv[5];
    112: #endif
    113:   char                    hostname[256];
    114:   long                    lerr;
    115:   PetscErrorCode          ierr;

    118:   /* Link name */
    119:   argv[0] = "-linkname";
    120:   if (!vmath->linkname) argv[1] = "math -mathlink";
    121:   else                  argv[1] = vmath->linkname;

    123:   /* Link host */
    124:   argv[2] = "-linkhost";
    125:   if (!vmath->linkhost) {
    126:     PetscGetHostName(hostname, 255);
    127:     argv[3] = hostname;
    128:   } else argv[3] = vmath->linkhost;

    130:   /* Link mode */
    131: #if defined(MATHEMATICA_3_0)
    132:   argv[4] = "-linkmode";
    133:   switch (vmath->linkmode) {
    134:   case MATHEMATICA_LINK_CREATE:
    135:     argv[5] = "Create";
    136:     break;
    137:   case MATHEMATICA_LINK_CONNECT:
    138:     argv[5] = "Connect";
    139:     break;
    140:   case MATHEMATICA_LINK_LAUNCH:
    141:     argv[5] = "Launch";
    142:     break;
    143:   }
    144: #else
    145:   switch (vmath->linkmode) {
    146:   case MATHEMATICA_LINK_CREATE:
    147:     argv[4] = "-linkcreate";
    148:     break;
    149:   case MATHEMATICA_LINK_CONNECT:
    150:     argv[4] = "-linkconnect";
    151:     break;
    152:   case MATHEMATICA_LINK_LAUNCH:
    153:     argv[4] = "-linklaunch";
    154:     break;
    155:   }
    156: #endif
    157:   vmath->link = MLOpenInEnv(mathematicaEnv, argc, argv, &lerr);
    158: #endif
    159:   return(0);
    160: }

    164: PETSC_EXTERN PetscErrorCode PetscViewerCreate_Mathematica(PetscViewer v)
    165: {
    166:   PetscViewer_Mathematica *vmath;
    167:   PetscErrorCode          ierr;

    170: #if !defined(PETSC_USE_DYNAMIC_LIBRARIES)
    171:   PetscViewerMathematicaInitializePackage();
    172: #endif

    174:   PetscNewLog(v,PetscViewer_Mathematica, &vmath);
    175:   v->data         = (void*) vmath;
    176:   v->ops->destroy = PetscViewerDestroy_Mathematica;
    177:   v->ops->flush   = 0;
    178:   PetscStrallocpy(PETSC_VIEWER_MATHEMATICA, &((PetscObject)v)->type_name);

    180:   vmath->linkname     = NULL;
    181:   vmath->linkhost     = NULL;
    182:   vmath->linkmode     = MATHEMATICA_LINK_CONNECT;
    183:   vmath->graphicsType = GRAPHICS_MOTIF;
    184:   vmath->plotType     = MATHEMATICA_TRIANGULATION_PLOT;
    185:   vmath->objName      = NULL;

    187:   PetscViewerMathematicaSetFromOptions(v);
    188:   PetscViewerMathematicaSetupConnection_Private(v);
    189:   return(0);
    190: }

    194: PetscErrorCode PetscViewerMathematicaParseLinkMode_Private(char *modename, LinkMode *mode)
    195: {
    196:   PetscBool      isCreate, isConnect, isLaunch;

    200:   PetscStrcasecmp(modename, "Create",  &isCreate);
    201:   PetscStrcasecmp(modename, "Connect", &isConnect);
    202:   PetscStrcasecmp(modename, "Launch",  &isLaunch);
    203:   if (isCreate)       *mode = MATHEMATICA_LINK_CREATE;
    204:   else if (isConnect) *mode = MATHEMATICA_LINK_CONNECT;
    205:   else if (isLaunch)  *mode = MATHEMATICA_LINK_LAUNCH;
    206:   else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Invalid Mathematica link mode: %s", modename);
    207:   return(0);
    208: }

    212: PetscErrorCode  PetscViewerMathematicaSetFromOptions(PetscViewer v)
    213: {
    214:   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica*) v->data;
    215:   char                    linkname[256];
    216:   char                    modename[256];
    217:   char                    hostname[256];
    218:   char                    type[256];
    219:   PetscInt                numPorts;
    220:   PetscInt                *ports;
    221:   PetscInt                numHosts;
    222:   int                     h;
    223:   char                    **hosts;
    224:   PetscMPIInt             size, rank;
    225:   PetscBool               opt;
    226:   PetscErrorCode          ierr;

    229:   MPI_Comm_size(PetscObjectComm((PetscObject)v), &size);
    230:   MPI_Comm_rank(PetscObjectComm((PetscObject)v), &rank);

    232:   /* Get link name */
    233:   PetscOptionsGetString("viewer_", "-math_linkname", linkname, 256, &opt);
    234:   if (opt) {
    235:     PetscViewerMathematicaSetLinkName(v, linkname);
    236:   }
    237:   /* Get link port */
    238:   numPorts = size;
    239:   PetscMalloc(size*sizeof(int), &ports);
    240:   PetscOptionsGetIntArray("viewer_", "-math_linkport", ports, &numPorts, &opt);
    241:   if (opt) {
    242:     if (numPorts > rank) snprintf(linkname, 255, "%6d", ports[rank]);
    243:     else                 snprintf(linkname, 255, "%6d", ports[0]);
    244:     PetscViewerMathematicaSetLinkName(v, linkname);
    245:   }
    246:   PetscFree(ports);
    247:   /* Get link host */
    248:   numHosts = size;
    249:   PetscMalloc(size*sizeof(char*), &hosts);
    250:   PetscOptionsGetStringArray("viewer_", "-math_linkhost", hosts, &numHosts, &opt);
    251:   if (opt) {
    252:     if (numHosts > rank) {
    253:       PetscStrncpy(hostname, hosts[rank], 255);
    254:     } else {
    255:       PetscStrncpy(hostname, hosts[0], 255);
    256:     }
    257:     PetscViewerMathematicaSetLinkHost(v, hostname);
    258:   }
    259:   for (h = 0; h < numHosts; h++) {
    260:     PetscFree(hosts[h]);
    261:   }
    262:   PetscFree(hosts);
    263:   /* Get link mode */
    264:   PetscOptionsGetString("viewer_", "-math_linkmode", modename, 256, &opt);
    265:   if (opt) {
    266:     LinkMode mode;

    268:     PetscViewerMathematicaParseLinkMode_Private(modename, &mode);
    269:     PetscViewerMathematicaSetLinkMode(v, mode);
    270:   }
    271:   /* Get graphics type */
    272:   PetscOptionsGetString("viewer_", "-math_graphics", type, 256, &opt);
    273:   if (opt) {
    274:     PetscBool isMotif, isPS, isPSFile;

    276:     PetscStrcasecmp(type, "Motif",  &isMotif);
    277:     PetscStrcasecmp(type, "PS",     &isPS);
    278:     PetscStrcasecmp(type, "PSFile", &isPSFile);
    279:     if (isMotif)       vmath->graphicsType = GRAPHICS_MOTIF;
    280:     else if (isPS)     vmath->graphicsType = GRAPHICS_PS_STDOUT;
    281:     else if (isPSFile) vmath->graphicsType = GRAPHICS_PS_FILE;
    282:   }
    283:   /* Get plot type */
    284:   PetscOptionsGetString("viewer_", "-math_type", type, 256, &opt);
    285:   if (opt) {
    286:     PetscBool isTri, isVecTri, isVec, isSurface;

    288:     PetscStrcasecmp(type, "Triangulation",       &isTri);
    289:     PetscStrcasecmp(type, "VectorTriangulation", &isVecTri);
    290:     PetscStrcasecmp(type, "Vector",              &isVec);
    291:     PetscStrcasecmp(type, "Surface",             &isSurface);
    292:     if (isTri)          vmath->plotType = MATHEMATICA_TRIANGULATION_PLOT;
    293:     else if (isVecTri)  vmath->plotType = MATHEMATICA_VECTOR_TRIANGULATION_PLOT;
    294:     else if (isVec)     vmath->plotType = MATHEMATICA_VECTOR_PLOT;
    295:     else if (isSurface) vmath->plotType = MATHEMATICA_SURFACE_PLOT;
    296:   }
    297:   return(0);
    298: }

    302: PetscErrorCode  PetscViewerMathematicaSetLinkName(PetscViewer v, const char *name)
    303: {
    304:   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica*) v->data;
    305:   PetscErrorCode          ierr;

    310:   PetscStrallocpy(name, &vmath->linkname);
    311:   return(0);
    312: }

    316: PetscErrorCode  PetscViewerMathematicaSetLinkPort(PetscViewer v, int port)
    317: {
    318:   char           name[16];

    322:   snprintf(name, 16, "%6d", port);
    323:   PetscViewerMathematicaSetLinkName(v, name);
    324:   return(0);
    325: }

    329: PetscErrorCode  PetscViewerMathematicaSetLinkHost(PetscViewer v, const char *host)
    330: {
    331:   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica*) v->data;
    332:   PetscErrorCode          ierr;

    337:   PetscStrallocpy(host, &vmath->linkhost);
    338:   return(0);
    339: }

    343: PetscErrorCode  PetscViewerMathematicaSetLinkMode(PetscViewer v, LinkMode mode)
    344: {
    345:   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica*) v->data;

    348:   vmath->linkmode = mode;
    349:   return(0);
    350: }

    352: /*----------------------------------------- Public Functions --------------------------------------------------------*/
    355: /*@C
    356:   PetscViewerMathematicaOpen - Communicates with Mathemtica using MathLink.

    358:   Collective on comm

    360:   Input Parameters:
    361: + comm    - The MPI communicator
    362: . port    - [optional] The port to connect on, or PETSC_DECIDE
    363: . machine - [optional] The machine to run Mathematica on, or NULL
    364: - mode    - [optional] The connection mode, or NULL

    366:   Output Parameter:
    367: . viewer  - The Mathematica viewer

    369:   Level: intermediate

    371:   Notes:
    372:   Most users should employ the following commands to access the
    373:   Mathematica viewers
    374: $
    375: $    PetscViewerMathematicaOpen(MPI_Comm comm, int port, char *machine, char *mode, PetscViewer &viewer)
    376: $    MatView(Mat matrix, PetscViewer viewer)
    377: $
    378: $                or
    379: $
    380: $    PetscViewerMathematicaOpen(MPI_Comm comm, int port, char *machine, char *mode, PetscViewer &viewer)
    381: $    VecView(Vec vector, PetscViewer viewer)

    383:    Options Database Keys:
    384: $    -viewer_math_linkhost <machine> - The host machine for the kernel
    385: $    -viewer_math_linkname <name>    - The full link name for the connection
    386: $    -viewer_math_linkport <port>    - The port for the connection
    387: $    -viewer_math_mode <mode>        - The mode, e.g. Launch, Connect
    388: $    -viewer_math_type <type>        - The plot type, e.g. Triangulation, Vector
    389: $    -viewer_math_graphics <output>  - The output type, e.g. Motif, PS, PSFile

    391: .keywords: PetscViewer, Mathematica, open

    393: .seealso: MatView(), VecView()
    394: @*/
    395: PetscErrorCode  PetscViewerMathematicaOpen(MPI_Comm comm, int port, const char machine[], const char mode[], PetscViewer *v)
    396: {

    400:   PetscViewerCreate(comm, v);
    401: #if 0
    402:   LinkMode linkmode;
    403:   PetscViewerMathematicaSetLinkPort(*v, port);
    404:   PetscViewerMathematicaSetLinkHost(*v, machine);
    405:   PetscViewerMathematicaParseLinkMode_Private(mode, &linkmode);
    406:   PetscViewerMathematicaSetLinkMode(*v, linkmode);
    407: #endif
    408:   PetscViewerSetType(*v, PETSC_VIEWER_MATHEMATICA);
    409:   return(0);
    410: }

    414: /*@C
    415:   PetscViewerMathematicaGetLink - Returns the link to Mathematica

    417:   Input Parameters:
    418: . viewer - The Mathematica viewer
    419: . link   - The link to Mathematica

    421:   Level: intermediate

    423: .keywords PetscViewer, Mathematica, link
    424: .seealso PetscViewerMathematicaOpen()
    425: @*/
    426: PetscErrorCode  PetscViewerMathematicaGetLink(PetscViewer viewer, MLINK *link)
    427: {
    428:   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica*) viewer->data;

    432:   *link = vmath->link;
    433:   return(0);
    434: }

    438: /*@C
    439:   PetscViewerMathematicaSkipPackets - Discard packets sent by Mathematica until a certain packet type is received

    441:   Input Parameters:
    442: . viewer - The Mathematica viewer
    443: . type   - The packet type to search for, e.g RETURNPKT

    445:   Level: advanced

    447: .keywords PetscViewer, Mathematica, packets
    448: .seealso PetscViewerMathematicaSetName(), PetscViewerMathematicaGetVector()
    449: @*/
    450: PetscErrorCode  PetscViewerMathematicaSkipPackets(PetscViewer viewer, int type)
    451: {
    452:   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica*) viewer->data;
    453:   MLINK                   link   = vmath->link; /* The link to Mathematica */
    454:   int                     pkt;                 /* The packet type */

    457:   while ((pkt = MLNextPacket(link)) && (pkt != type)) MLNewPacket(link);
    458:   if (!pkt) {
    459:     MLClearError(link);
    460:     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB, (char*) MLErrorMessage(link));
    461:   }
    462:   return(0);
    463: }

    467: /*@C
    468:   PetscViewerMathematicaGetName - Retrieve the default name for objects communicated to Mathematica

    470:   Input Parameter:
    471: . viewer - The Mathematica viewer

    473:   Output Parameter:
    474: . name   - The name for new objects created in Mathematica

    476:   Level: intermediate

    478: .keywords PetscViewer, Mathematica, name
    479: .seealso PetscViewerMathematicaSetName(), PetscViewerMathematicaClearName()
    480: @*/
    481: PetscErrorCode  PetscViewerMathematicaGetName(PetscViewer viewer, const char **name)
    482: {
    483:   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica*) viewer->data;

    488:   *name = vmath->objName;
    489:   return(0);
    490: }

    494: /*@C
    495:   PetscViewerMathematicaSetName - Override the default name for objects communicated to Mathematica

    497:   Input Parameters:
    498: . viewer - The Mathematica viewer
    499: . name   - The name for new objects created in Mathematica

    501:   Level: intermediate

    503: .keywords PetscViewer, Mathematica, name
    504: .seealso PetscViewerMathematicaSetName(), PetscViewerMathematicaClearName()
    505: @*/
    506: PetscErrorCode  PetscViewerMathematicaSetName(PetscViewer viewer, const char name[])
    507: {
    508:   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica*) viewer->data;

    513:   vmath->objName = name;
    514:   return(0);
    515: }

    519: /*@C
    520:   PetscViewerMathematicaClearName - Use the default name for objects communicated to Mathematica

    522:   Input Parameter:
    523: . viewer - The Mathematica viewer

    525:   Level: intermediate

    527: .keywords PetscViewer, Mathematica, name
    528: .seealso PetscViewerMathematicaGetName(), PetscViewerMathematicaSetName()
    529: @*/
    530: PetscErrorCode  PetscViewerMathematicaClearName(PetscViewer viewer)
    531: {
    532:   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica*) viewer->data;

    536:   vmath->objName = NULL;
    537:   return(0);
    538: }

    542: /*@C
    543:   PetscViewerMathematicaGetVector - Retrieve a vector from Mathematica

    545:   Input Parameter:
    546: . viewer - The Mathematica viewer

    548:   Output Parameter:
    549: . v      - The vector

    551:   Level: intermediate

    553: .keywords PetscViewer, Mathematica, vector
    554: .seealso VecView(), PetscViewerMathematicaPutVector()
    555: @*/
    556: PetscErrorCode  PetscViewerMathematicaGetVector(PetscViewer viewer, Vec v)
    557: {
    558:   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica*) viewer->data;
    559:   MLINK                   link;   /* The link to Mathematica */
    560:   char                    *name;
    561:   PetscScalar             *mArray,*array;
    562:   long                    mSize;
    563:   int                     n;
    564:   PetscErrorCode          ierr;

    570:   /* Determine the object name */
    571:   if (!vmath->objName) name = "vec";
    572:   else                 name = (char*) vmath->objName;

    574:   link = vmath->link;
    575:   VecGetLocalSize(v, &n);
    576:   VecGetArray(v, &array);
    577:   MLPutFunction(link, "EvaluatePacket", 1);
    578:   MLPutSymbol(link, name);
    579:   MLEndPacket(link);
    580:   PetscViewerMathematicaSkipPackets(viewer, RETURNPKT);
    581:   MLGetRealList(link, &mArray, &mSize);
    582:   if (n != mSize) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Incompatible vector sizes %d %d",n,mSize);
    583:   PetscMemcpy(array, mArray, mSize * sizeof(double));
    584:   MLDisownRealList(link, mArray, mSize);
    585:   VecRestoreArray(v, &array);
    586:   return(0);
    587: }

    591: /*@C
    592:   PetscViewerMathematicaPutVector - Send a vector to Mathematica

    594:   Input Parameters:
    595: + viewer - The Mathematica viewer
    596: - v      - The vector

    598:   Level: intermediate

    600: .keywords PetscViewer, Mathematica, vector
    601: .seealso VecView(), PetscViewerMathematicaGetVector()
    602: @*/
    603: PetscErrorCode  PetscViewerMathematicaPutVector(PetscViewer viewer, Vec v)
    604: {
    605:   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica*) viewer->data;
    606:   MLINK                   link   = vmath->link; /* The link to Mathematica */
    607:   char                    *name;
    608:   PetscScalar             *array;
    609:   int                     n;
    610:   PetscErrorCode          ierr;

    613:   /* Determine the object name */
    614:   if (!vmath->objName) name = "vec";
    615:   else                 name = (char*) vmath->objName;

    617:   VecGetLocalSize(v, &n);
    618:   VecGetArray(v, &array);

    620:   /* Send the Vector object */
    621:   MLPutFunction(link, "EvaluatePacket", 1);
    622:   MLPutFunction(link, "Set", 2);
    623:   MLPutSymbol(link, name);
    624:   MLPutRealList(link, array, n);
    625:   MLEndPacket(link);
    626:   /* Skip packets until ReturnPacket */
    627:   PetscViewerMathematicaSkipPackets(viewer, RETURNPKT);
    628:   /* Skip ReturnPacket */
    629:   MLNewPacket(link);

    631:   VecRestoreArray(v, &array);
    632:   return(0);
    633: }

    635: PetscErrorCode  PetscViewerMathematicaPutMatrix(PetscViewer viewer, int m, int n, PetscReal *a)
    636: {
    637:   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica*) viewer->data;
    638:   MLINK                   link   = vmath->link; /* The link to Mathematica */
    639:   char                    *name;
    640:   PetscErrorCode          ierr;

    643:   /* Determine the object name */
    644:   if (!vmath->objName) name = "mat";
    645:   else                 name = (char*) vmath->objName;

    647:   /* Send the dense matrix object */
    648:   MLPutFunction(link, "EvaluatePacket", 1);
    649:   MLPutFunction(link, "Set", 2);
    650:   MLPutSymbol(link, name);
    651:   MLPutFunction(link, "Transpose", 1);
    652:   MLPutFunction(link, "Partition", 2);
    653:   MLPutRealList(link, a, m*n);
    654:   MLPutInteger(link, m);
    655:   MLEndPacket(link);
    656:   /* Skip packets until ReturnPacket */
    657:   PetscViewerMathematicaSkipPackets(viewer, RETURNPKT);
    658:   /* Skip ReturnPacket */
    659:   MLNewPacket(link);
    660:   return(0);
    661: }

    663: PetscErrorCode  PetscViewerMathematicaPutCSRMatrix(PetscViewer viewer, int m, int n, int *i, int *j, PetscReal *a)
    664: {
    665:   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica*) viewer->data;
    666:   MLINK                   link   = vmath->link; /* The link to Mathematica */
    667:   const char              *symbol;
    668:   char                    *name;
    669:   PetscBool               match;
    670:   PetscErrorCode          ierr;

    673:   /* Determine the object name */
    674:   if (!vmath->objName) name = "mat";
    675:   else                 name = (char*) vmath->objName;

    677:   /* Make sure Mathematica recognizes sparse matrices */
    678:   MLPutFunction(link, "EvaluatePacket", 1);
    679:   MLPutFunction(link, "Needs", 1);
    680:   MLPutString(link, "LinearAlgebra`CSRMatrix`");
    681:   MLEndPacket(link);
    682:   /* Skip packets until ReturnPacket */
    683:   PetscViewerMathematicaSkipPackets(viewer, RETURNPKT);
    684:   /* Skip ReturnPacket */
    685:   MLNewPacket(link);

    687:   /* Send the CSRMatrix object */
    688:   MLPutFunction(link, "EvaluatePacket", 1);
    689:   MLPutFunction(link, "Set", 2);
    690:   MLPutSymbol(link, name);
    691:   MLPutFunction(link, "CSRMatrix", 5);
    692:   MLPutInteger(link, m);
    693:   MLPutInteger(link, n);
    694:   MLPutFunction(link, "Plus", 2);
    695:   MLPutIntegerList(link, i, m+1);
    696:   MLPutInteger(link, 1);
    697:   MLPutFunction(link, "Plus", 2);
    698:   MLPutIntegerList(link, j, i[m]);
    699:   MLPutInteger(link, 1);
    700:   MLPutRealList(link, a, i[m]);
    701:   MLEndPacket(link);
    702:   /* Skip packets until ReturnPacket */
    703:   PetscViewerMathematicaSkipPackets(viewer, RETURNPKT);
    704:   /* Skip ReturnPacket */
    705:   MLNewPacket(link);

    707:   /* Check that matrix is valid */
    708:   MLPutFunction(link, "EvaluatePacket", 1);
    709:   MLPutFunction(link, "ValidQ", 1);
    710:   MLPutSymbol(link, name);
    711:   MLEndPacket(link);
    712:   PetscViewerMathematicaSkipPackets(viewer, RETURNPKT);
    713:   MLGetSymbol(link, &symbol);
    714:   PetscStrcmp("True", (char*) symbol, &match);
    715:   if (!match) {
    716:     MLDisownSymbol(link, symbol);
    717:     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB, "Invalid CSR matrix in Mathematica");
    718:   }
    719:   MLDisownSymbol(link, symbol);
    720:   /* Skip ReturnPacket */
    721:   MLNewPacket(link);
    722:   return(0);
    723: }