Actual source code: mathematica.c

  1: #define PETSC_DLL
  2: /* 
  3:         Written by Matt Knepley, knepley@cs.purdue.edu 7/23/97
  4:         Major overhall for interactivity               11/14/97
  5:         Reorganized                                    11/8/98
  6: */
 7:  #include ../src/sys/viewer/viewerimpl.h
 8:  #include private/pcimpl.h
 9:  #include ../src/mat/impls/aij/seq/aij.h
 10:  #include mathematica.h
 11: #include "petscfix.h"

 13: #if defined (PETSC_HAVE__SNPRINTF) && !defined(PETSC_HAVE_SNPRINTF)
 14: #define snprintf _snprintf
 15: #endif

 17: PetscViewer  PETSC_VIEWER_MATHEMATICA_WORLD_PRIVATE = PETSC_NULL;
 18: static void *mathematicaEnv                   = PETSC_NULL;

 22: /*@C
 23:   PetscViewerMathematicaDestroyPackage - This function destroys everything in the Petsc interface to Mathematica. It is
 24:   called from PetscFinalize().

 26:   Level: developer

 28: .keywords: Petsc, destroy, package, mathematica
 29: .seealso: PetscFinalize()
 30: @*/
 31: PetscErrorCode  PetscViewerMathematicaFinalizePackage(void)
 32: {
 34:   if (mathematicaEnv) MLDeinitialize((MLEnvironment) mathematicaEnv);
 35:   return(0);
 36: }

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

 45:   Input Parameter:
 46:   path - The dynamic library path, or PETSC_NULL

 48:   Level: developer

 50: .keywords: Petsc, initialize, package, PLAPACK
 51: .seealso: PetscInitializePackage(), PetscInitialize()
 52: @*/
 53: PetscErrorCode  PetscViewerMathematicaInitializePackage(const char path[])
 54: {
 55:   static PetscTruth initialized = PETSC_FALSE;

 58:   if (initialized) return(0);
 59:   initialized = PETSC_TRUE;
 60:   mathematicaEnv = (void*) MLInitialize(0);
 61:   PetscRegisterFinalize(PetscViewerMathematicaFinalizePackage);
 62:   return(0);
 63: }


 68: PetscErrorCode PetscViewerInitializeMathematicaWorld_Private()
 69: {

 73:   if (PETSC_VIEWER_MATHEMATICA_WORLD_PRIVATE) return(0);
 74:   PetscViewerMathematicaOpen(PETSC_COMM_WORLD, PETSC_DECIDE, PETSC_NULL, PETSC_NULL, &PETSC_VIEWER_MATHEMATICA_WORLD_PRIVATE);
 75:   return(0);
 76: }

 80: static PetscErrorCode PetscViewerDestroy_Mathematica(PetscViewer viewer)
 81: {
 82:   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica *) viewer->data;
 83:   PetscErrorCode          ierr;

 86:   MLClose(vmath->link);
 87:   PetscFree(vmath->linkname);
 88:   PetscFree(vmath->linkhost);
 89:   PetscFree(vmath);
 90:   return(0);
 91: }

 95: PetscErrorCode PetscViewerDestroyMathematica_Private(void)
 96: {

100:   if (PETSC_VIEWER_MATHEMATICA_WORLD_PRIVATE) {
101:     PetscViewerDestroy(PETSC_VIEWER_MATHEMATICA_WORLD_PRIVATE);
102:   }
103:   return(0);
104: }

108: PetscErrorCode PetscViewerMathematicaSetupConnection_Private(PetscViewer v)
109: {
110:   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica *) v->data;
111: #ifdef MATHEMATICA_3_0
112:   int                     argc = 6;
113:   char                    *argv[6];
114: #else
115:   int                     argc = 5;
116:   char                    *argv[5];
117: #endif
118:   char                    hostname[256];
119:   long                    lerr;
120:   PetscErrorCode          ierr;

123:   /* Link name */
124:   argv[0] = "-linkname";
125:   if (!vmath->linkname) {
126:     argv[1] = "math -mathlink";
127:   } else {
128:     argv[1] = vmath->linkname;
129:   }

131:   /* Link host */
132:   argv[2] = "-linkhost";
133:   if (!vmath->linkhost) {
134:     PetscGetHostName(hostname, 255);
135:     argv[3] = hostname;
136:   } else {
137:     argv[3] = vmath->linkhost;
138:   }

140:   /* Link mode */
141: #ifdef MATHEMATICA_3_0
142:   argv[4] = "-linkmode";
143:   switch(vmath->linkmode) {
144:   case MATHEMATICA_LINK_CREATE:
145:     argv[5] = "Create";
146:     break;
147:   case MATHEMATICA_LINK_CONNECT:
148:     argv[5] = "Connect";
149:     break;
150:   case MATHEMATICA_LINK_LAUNCH:
151:     argv[5] = "Launch";
152:     break;
153:   }
154: #else
155:   switch(vmath->linkmode) {
156:   case MATHEMATICA_LINK_CREATE:
157:     argv[4] = "-linkcreate";
158:     break;
159:   case MATHEMATICA_LINK_CONNECT:
160:     argv[4] = "-linkconnect";
161:     break;
162:   case MATHEMATICA_LINK_LAUNCH:
163:     argv[4] = "-linklaunch";
164:     break;
165:   }
166: #endif
167:   vmath->link = MLOpenInEnv(mathematicaEnv, argc, argv, &lerr);
168: #endif
169:   return(0);
170: }

175: PetscErrorCode  PetscViewerCreate_Mathematica(PetscViewer v)
176: {
177:   PetscViewer_Mathematica *vmath;
178:   PetscErrorCode          ierr;

181: #ifndef PETSC_USE_DYNAMIC_LIBRARIES
182:   PetscViewerMathematicaInitializePackage(PETSC_NULL);
183: #endif

185:   PetscNewLog(v,PetscViewer_Mathematica, &vmath);
186:   v->data         = (void*) vmath;
187:   v->ops->destroy = PetscViewerDestroy_Mathematica;
188:   v->ops->flush   = 0;
189:   PetscStrallocpy(PETSC_VIEWER_MATHEMATICA, &((PetscObject)v)->type_name);

191:   vmath->linkname         = PETSC_NULL;
192:   vmath->linkhost         = PETSC_NULL;
193:   vmath->linkmode         = MATHEMATICA_LINK_CONNECT;
194:   vmath->graphicsType     = GRAPHICS_MOTIF;
195:   vmath->plotType         = MATHEMATICA_TRIANGULATION_PLOT;
196:   vmath->objName          = PETSC_NULL;

198:   PetscViewerMathematicaSetFromOptions(v);
199:   PetscViewerMathematicaSetupConnection_Private(v);
200:   return(0);
201: }

206: PetscErrorCode PetscViewerMathematicaParseLinkMode_Private(char *modename, LinkMode *mode) {
207:   PetscTruth     isCreate, isConnect, isLaunch;

211:   PetscStrcasecmp(modename, "Create",  &isCreate);
212:   PetscStrcasecmp(modename, "Connect", &isConnect);
213:   PetscStrcasecmp(modename, "Launch",  &isLaunch);
214:   if (isCreate) {
215:     *mode = MATHEMATICA_LINK_CREATE;
216:   } else if (isConnect) {
217:     *mode = MATHEMATICA_LINK_CONNECT;
218:   } else if (isLaunch) {
219:     *mode = MATHEMATICA_LINK_LAUNCH;
220:   } else {
221:     SETERRQ1(PETSC_ERR_ARG_WRONG, "Invalid Mathematica link mode: %s", modename);
222:   }
223:   return(0);
224: }

228: PetscErrorCode  PetscViewerMathematicaSetFromOptions(PetscViewer v)
229: {
230:   PetscViewer_Mathematica  *vmath = (PetscViewer_Mathematica *) v->data;
231:   char                     linkname[256];
232:   char                     modename[256];
233:   char                     hostname[256];
234:   char                     type[256];
235:   PetscInt                 numPorts;
236:   PetscInt                 *ports;
237:   PetscInt                 numHosts;
238:   int                      h;
239:   char                     **hosts;
240:   PetscMPIInt              size, rank;
241:   PetscTruth               opt;
242:   PetscErrorCode           ierr;

245:   MPI_Comm_size(((PetscObject)v)->comm, &size);
246:   MPI_Comm_rank(((PetscObject)v)->comm, &rank);

248:   /* Get link name */
249:   PetscOptionsGetString("viewer_", "-math_linkname", linkname, 255, &opt);
250:   if (opt) {
251:     PetscViewerMathematicaSetLinkName(v, linkname);
252:   }
253:   /* Get link port */
254:   numPorts = size;
255:   PetscMalloc(size * sizeof(int), &ports);
256:   PetscOptionsGetIntArray("viewer_", "-math_linkport", ports, &numPorts, &opt);
257:   if (opt) {
258:     if (numPorts > rank) {
259:       snprintf(linkname, 255, "%6d", ports[rank]);
260:     } else {
261:       snprintf(linkname, 255, "%6d", ports[0]);
262:     }
263:     PetscViewerMathematicaSetLinkName(v, linkname);
264:   }
265:   PetscFree(ports);
266:   /* Get link host */
267:   numHosts = size;
268:   PetscMalloc(size * sizeof(char *), &hosts);
269:   PetscOptionsGetStringArray("viewer_", "-math_linkhost", hosts, &numHosts, &opt);
270:   if (opt) {
271:     if (numHosts > rank) {
272:       PetscStrncpy(hostname, hosts[rank], 255);
273:     } else {
274:       PetscStrncpy(hostname, hosts[0], 255);
275:     }
276:     PetscViewerMathematicaSetLinkHost(v, hostname);
277:   }
278:   for(h = 0; h < numHosts; h++) {
279:     PetscFree(hosts[h]);
280:   }
281:   PetscFree(hosts);
282:   /* Get link mode */
283:   PetscOptionsGetString("viewer_", "-math_linkmode", modename, 255, &opt);
284:   if (opt) {
285:     LinkMode mode;

287:     PetscViewerMathematicaParseLinkMode_Private(modename, &mode);
288:     PetscViewerMathematicaSetLinkMode(v, mode);
289:   }
290:   /* Get graphics type */
291:   PetscOptionsGetString("viewer_", "-math_graphics", type, 255, &opt);
292:   if (opt) {
293:     PetscTruth isMotif, isPS, isPSFile;

295:     PetscStrcasecmp(type, "Motif",  &isMotif);
296:     PetscStrcasecmp(type, "PS",     &isPS);
297:     PetscStrcasecmp(type, "PSFile", &isPSFile);
298:     if (isMotif) {
299:       vmath->graphicsType = GRAPHICS_MOTIF;
300:     } else if (isPS) {
301:       vmath->graphicsType = GRAPHICS_PS_STDOUT;
302:     } else if (isPSFile) {
303:       vmath->graphicsType = GRAPHICS_PS_FILE;
304:     }
305:   }
306:   /* Get plot type */
307:   PetscOptionsGetString("viewer_", "-math_type", type, 255, &opt);
308:   if (opt) {
309:     PetscTruth isTri, isVecTri, isVec, isSurface;

311:     PetscStrcasecmp(type, "Triangulation",       &isTri);
312:     PetscStrcasecmp(type, "VectorTriangulation", &isVecTri);
313:     PetscStrcasecmp(type, "Vector",              &isVec);
314:     PetscStrcasecmp(type, "Surface",             &isSurface);
315:     if (isTri) {
316:       vmath->plotType     = MATHEMATICA_TRIANGULATION_PLOT;
317:     } else if (isVecTri) {
318:       vmath->plotType     = MATHEMATICA_VECTOR_TRIANGULATION_PLOT;
319:     } else if (isVec) {
320:       vmath->plotType     = MATHEMATICA_VECTOR_PLOT;
321:     } else if (isSurface) {
322:       vmath->plotType     = MATHEMATICA_SURFACE_PLOT;
323:     }
324:   }
325:   return(0);
326: }

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

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

343: PetscErrorCode  PetscViewerMathematicaSetLinkPort(PetscViewer v, int port) {
344:   char           name[16];

348:   snprintf(name, 16, "%6d", port);
349:   PetscViewerMathematicaSetLinkName(v, name);
350:   return(0);
351: }

355: PetscErrorCode  PetscViewerMathematicaSetLinkHost(PetscViewer v, const char *host) {
356:   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica *) v->data;
357:   PetscErrorCode          ierr;

362:   PetscStrallocpy(host, &vmath->linkhost);
363:   return(0);
364: }

368: PetscErrorCode  PetscViewerMathematicaSetLinkMode(PetscViewer v, LinkMode mode) {
369:   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica *) v->data;

372:   vmath->linkmode = mode;
373:   return(0);
374: }

376: /*----------------------------------------- Public Functions --------------------------------------------------------*/
379: /*@C
380:   PetscViewerMathematicaOpen - Communicates with Mathemtica using MathLink.

382:   Collective on comm

384:   Input Parameters:
385: + comm    - The MPI communicator
386: . port    - [optional] The port to connect on, or PETSC_DECIDE
387: . machine - [optional] The machine to run Mathematica on, or PETSC_NULL
388: - mode    - [optional] The connection mode, or PETSC_NULL

390:   Output Parameter:
391: . viewer  - The Mathematica viewer

393:   Level: intermediate

395:   Notes:
396:   Most users should employ the following commands to access the 
397:   Mathematica viewers
398: $
399: $    PetscViewerMathematicaOpen(MPI_Comm comm, int port, char *machine, char *mode, PetscViewer &viewer)
400: $    MatView(Mat matrix, PetscViewer viewer)
401: $
402: $                or
403: $
404: $    PetscViewerMathematicaOpen(MPI_Comm comm, int port, char *machine, char *mode, PetscViewer &viewer)
405: $    VecView(Vec vector, PetscViewer viewer)

407:    Options Database Keys:
408: $    -viewer_math_linkhost <machine> - The host machine for the kernel
409: $    -viewer_math_linkname <name>    - The full link name for the connection
410: $    -viewer_math_linkport <port>    - The port for the connection
411: $    -viewer_math_mode <mode>        - The mode, e.g. Launch, Connect
412: $    -viewer_math_type <type>        - The plot type, e.g. Triangulation, Vector
413: $    -viewer_math_graphics <output>  - The output type, e.g. Motif, PS, PSFile

415: .keywords: PetscViewer, Mathematica, open

417: .seealso: MatView(), VecView()
418: @*/
419: PetscErrorCode  PetscViewerMathematicaOpen(MPI_Comm comm, int port, const char machine[], const char mode[], PetscViewer *v)
420: {

424:   PetscViewerCreate(comm, v);
425: #if 0
426:   LinkMode linkmode;
427:   PetscViewerMathematicaSetLinkPort(*v, port);
428:   PetscViewerMathematicaSetLinkHost(*v, machine);
429:   PetscViewerMathematicaParseLinkMode_Private(mode, &linkmode);
430:   PetscViewerMathematicaSetLinkMode(*v, linkmode);
431: #endif
432:   PetscViewerSetType(*v, PETSC_VIEWER_MATHEMATICA);
433:   return(0);
434: }

438: /*@C
439:   PetscViewerMathematicaGetLink - Returns the link to Mathematica

441:   Input Parameters:
442: . viewer - The Mathematica viewer
443: . link   - The link to Mathematica

445:   Level: intermediate

447: .keywords PetscViewer, Mathematica, link
448: .seealso PetscViewerMathematicaOpen()
449: @*/
450: PetscErrorCode  PetscViewerMathematicaGetLink(PetscViewer viewer, MLINK *link)
451: {
452:   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica *) viewer->data;

456:   *link = vmath->link;
457:   return(0);
458: }

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

465:   Input Parameters:
466: . viewer - The Mathematica viewer
467: . type   - The packet type to search for, e.g RETURNPKT

469:   Level: advanced

471: .keywords PetscViewer, Mathematica, packets
472: .seealso PetscViewerMathematicaSetName(), PetscViewerMathematicaGetVector()
473: @*/
474: PetscErrorCode  PetscViewerMathematicaSkipPackets(PetscViewer viewer, int type)
475: {
476:   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica *) viewer->data;
477:   MLINK                   link  = vmath->link; /* The link to Mathematica */
478:   int                     pkt;                 /* The packet type */

481:   while((pkt = MLNextPacket(link)) && (pkt != type))
482:     MLNewPacket(link);
483:   if (!pkt) {
484:     MLClearError(link);
485:     SETERRQ(PETSC_ERR_LIB, (char *) MLErrorMessage(link));
486:   }
487:   return(0);
488: }

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

495:   Input Parameter:
496: . viewer - The Mathematica viewer

498:   Output Parameter:
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  PetscViewerMathematicaGetName(PetscViewer viewer, const char **name)
507: {
508:   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica *) viewer->data;

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

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

522:   Input Parameters:
523: . viewer - The Mathematica viewer
524: . name   - The name for new objects created in Mathematica

526:   Level: intermediate

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

538:   vmath->objName = name;
539:   return(0);
540: }

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

547:   Input Parameter:
548: . viewer - The Mathematica viewer

550:   Level: intermediate

552: .keywords PetscViewer, Mathematica, name
553: .seealso PetscViewerMathematicaGetName(), PetscViewerMathematicaSetName()
554: @*/
555: PetscErrorCode  PetscViewerMathematicaClearName(PetscViewer viewer)
556: {
557:   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica *) viewer->data;

561:   vmath->objName = PETSC_NULL;
562:   return(0);
563: }

567: /*@C
568:   PetscViewerMathematicaGetVector - Retrieve a vector from Mathematica

570:   Input Parameter:
571: . viewer - The Mathematica viewer

573:   Output Parameter:
574: . v      - The vector

576:   Level: intermediate

578: .keywords PetscViewer, Mathematica, vector
579: .seealso VecView(), PetscViewerMathematicaPutVector()
580: @*/
581: PetscErrorCode  PetscViewerMathematicaGetVector(PetscViewer viewer, Vec v) {
582:   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica *) viewer->data;
583:   MLINK                   link;   /* The link to Mathematica */
584:   char                    *name;
585:   PetscScalar             *mArray,*array;
586:   long                    mSize;
587:   int                     n;
588:   PetscErrorCode          ierr;


594:   /* Determine the object name */
595:   if (!vmath->objName) {
596:     name = "vec";
597:   } else {
598:     name = (char *) vmath->objName;
599:   }

601:   link = vmath->link;
602:   VecGetLocalSize(v, &n);
603:   VecGetArray(v, &array);
604:   MLPutFunction(link, "EvaluatePacket", 1);
605:     MLPutSymbol(link, name);
606:   MLEndPacket(link);
607:   PetscViewerMathematicaSkipPackets(viewer, RETURNPKT);
608:   MLGetRealList(link, &mArray, &mSize);
609:   if (n != mSize) SETERRQ2(PETSC_ERR_ARG_WRONG, "Incompatible vector sizes %d %d",n,mSize);
610:   PetscMemcpy(array, mArray, mSize * sizeof(double));
611:   MLDisownRealList(link, mArray, mSize);
612:   VecRestoreArray(v, &array);

614:   return(0);
615: }

619: /*@C
620:   PetscViewerMathematicaPutVector - Send a vector to Mathematica

622:   Input Parameters:
623: + viewer - The Mathematica viewer
624: - v      - The vector

626:   Level: intermediate

628: .keywords PetscViewer, Mathematica, vector
629: .seealso VecView(), PetscViewerMathematicaGetVector()
630: @*/
631: PetscErrorCode  PetscViewerMathematicaPutVector(PetscViewer viewer, Vec v)
632: {
633:   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica *) viewer->data;
634:   MLINK                   link  = vmath->link; /* The link to Mathematica */
635:   char                    *name;
636:   PetscScalar             *array;
637:   int                     n;
638:   PetscErrorCode          ierr;

641:   /* Determine the object name */
642:   if (!vmath->objName) {
643:     name = "vec";
644:   } else {
645:     name = (char *) vmath->objName;
646:   }
647:   VecGetLocalSize(v, &n);
648:   VecGetArray(v, &array);

650:   /* Send the Vector object */
651:   MLPutFunction(link, "EvaluatePacket", 1);
652:     MLPutFunction(link, "Set", 2);
653:       MLPutSymbol(link, name);
654:       MLPutRealList(link, array, n);
655:   MLEndPacket(link);
656:   /* Skip packets until ReturnPacket */
657:   PetscViewerMathematicaSkipPackets(viewer, RETURNPKT);
658:   /* Skip ReturnPacket */
659:   MLNewPacket(link);

661:   VecRestoreArray(v, &array);
662:   return(0);
663: }

665: PetscErrorCode  PetscViewerMathematicaPutMatrix(PetscViewer viewer, int m, int n, PetscReal *a)
666: {
667:   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica *) viewer->data;
668:   MLINK                   link  = vmath->link; /* The link to Mathematica */
669:   char                    *name;
670:   PetscErrorCode          ierr;

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

680:   /* Send the dense matrix object */
681:   MLPutFunction(link, "EvaluatePacket", 1);
682:     MLPutFunction(link, "Set", 2);
683:       MLPutSymbol(link, name);
684:       MLPutFunction(link, "Transpose", 1);
685:         MLPutFunction(link, "Partition", 2);
686:           MLPutRealList(link, a, m*n);
687:           MLPutInteger(link, m);
688:   MLEndPacket(link);
689:   /* Skip packets until ReturnPacket */
690:   PetscViewerMathematicaSkipPackets(viewer, RETURNPKT);
691:   /* Skip ReturnPacket */
692:   MLNewPacket(link);

694:   return(0);
695: }

697: PetscErrorCode  PetscViewerMathematicaPutCSRMatrix(PetscViewer viewer, int m, int n, int *i, int *j, PetscReal *a)
698: {
699:   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica *) viewer->data;
700:   MLINK                   link  = vmath->link; /* The link to Mathematica */
701:   const char              *symbol;
702:   char                    *name;
703:   PetscTruth              match;
704:   PetscErrorCode          ierr;

707:   /* Determine the object name */
708:   if (!vmath->objName) {
709:     name = "mat";
710:   } else {
711:     name = (char *) vmath->objName;
712:   }

714:   /* Make sure Mathematica recognizes sparse matrices */
715:   MLPutFunction(link, "EvaluatePacket", 1);
716:     MLPutFunction(link, "Needs", 1);
717:       MLPutString(link, "LinearAlgebra`CSRMatrix`");
718:   MLEndPacket(link);
719:   /* Skip packets until ReturnPacket */
720:   PetscViewerMathematicaSkipPackets(viewer, RETURNPKT);
721:   /* Skip ReturnPacket */
722:   MLNewPacket(link);

724:   /* Send the CSRMatrix object */
725:   MLPutFunction(link, "EvaluatePacket", 1);
726:     MLPutFunction(link, "Set", 2);
727:       MLPutSymbol(link, name);
728:       MLPutFunction(link, "CSRMatrix", 5);
729:         MLPutInteger(link, m);
730:         MLPutInteger(link, n);
731:         MLPutFunction(link, "Plus", 2);
732:           MLPutIntegerList(link, i, m+1);
733:           MLPutInteger(link, 1);
734:         MLPutFunction(link, "Plus", 2);
735:           MLPutIntegerList(link, j, i[m]);
736:           MLPutInteger(link, 1);
737:         MLPutRealList(link, a, i[m]);
738:   MLEndPacket(link);
739:   /* Skip packets until ReturnPacket */
740:   PetscViewerMathematicaSkipPackets(viewer, RETURNPKT);
741:   /* Skip ReturnPacket */
742:   MLNewPacket(link);

744:   /* Check that matrix is valid */
745:   MLPutFunction(link, "EvaluatePacket", 1);
746:     MLPutFunction(link, "ValidQ", 1);
747:       MLPutSymbol(link, name);
748:   MLEndPacket(link);
749:   PetscViewerMathematicaSkipPackets(viewer, RETURNPKT);
750:   MLGetSymbol(link, &symbol);
751:   PetscStrcmp("True", (char *) symbol, &match);
752:   if (!match) {
753:     MLDisownSymbol(link, symbol);
754:     SETERRQ(PETSC_ERR_PLIB, "Invalid CSR matrix in Mathematica");
755:   }
756:   MLDisownSymbol(link, symbol);
757:   /* Skip ReturnPacket */
758:   MLNewPacket(link);

760:   return(0);
761: }