Actual source code: mathematica.c

  1: #define PETSC_DLL

 3:  #include private/viewerimpl.h
 4:  #include private/pcimpl.h
 5:  #include ../src/mat/impls/aij/seq/aij.h
 6:  #include mathematica.h

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

 12: PetscViewer  PETSC_VIEWER_MATHEMATICA_WORLD_PRIVATE = PETSC_NULL;
 13: static void *mathematicaEnv                   = PETSC_NULL;

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

 22:   Level: developer

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

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

 42:   Input Parameter:
 43:   path - The dynamic library path, or PETSC_NULL

 45:   Level: developer

 47: .keywords: Petsc, initialize, package, PLAPACK
 48: .seealso: PetscInitializePackage(), PetscInitialize()
 49: @*/
 50: PetscErrorCode  PetscViewerMathematicaInitializePackage(const char path[])
 51: {
 52:   PetscError ierr;

 55:   if (PetscViewerMathematicaPackageInitialized) return(0);
 56:   PetscViewerMathematicaPackageInitialized = PETSC_TRUE;
 57:   mathematicaEnv = (void*) MLInitialize(0);
 58:   PetscRegisterFinalize(PetscViewerMathematicaFinalizePackage);
 59:   return(0);
 60: }


 65: PetscErrorCode PetscViewerInitializeMathematicaWorld_Private()
 66: {

 70:   if (PETSC_VIEWER_MATHEMATICA_WORLD_PRIVATE) return(0);
 71:   PetscViewerMathematicaOpen(PETSC_COMM_WORLD, PETSC_DECIDE, PETSC_NULL, PETSC_NULL, &PETSC_VIEWER_MATHEMATICA_WORLD_PRIVATE);
 72:   return(0);
 73: }

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

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

 92: PetscErrorCode PetscViewerDestroyMathematica_Private(void)
 93: {

 97:   if (PETSC_VIEWER_MATHEMATICA_WORLD_PRIVATE) {
 98:     PetscViewerDestroy(PETSC_VIEWER_MATHEMATICA_WORLD_PRIVATE);
 99:   }
100:   return(0);
101: }

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

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

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

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

172: PetscErrorCode  PetscViewerCreate_Mathematica(PetscViewer v)
173: {
174:   PetscViewer_Mathematica *vmath;
175:   PetscErrorCode          ierr;

178: #ifndef PETSC_USE_DYNAMIC_LIBRARIES
179:   PetscViewerMathematicaInitializePackage(PETSC_NULL);
180: #endif

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

188:   vmath->linkname         = PETSC_NULL;
189:   vmath->linkhost         = PETSC_NULL;
190:   vmath->linkmode         = MATHEMATICA_LINK_CONNECT;
191:   vmath->graphicsType     = GRAPHICS_MOTIF;
192:   vmath->plotType         = MATHEMATICA_TRIANGULATION_PLOT;
193:   vmath->objName          = PETSC_NULL;

195:   PetscViewerMathematicaSetFromOptions(v);
196:   PetscViewerMathematicaSetupConnection_Private(v);
197:   return(0);
198: }

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

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

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

242:   MPI_Comm_size(((PetscObject)v)->comm, &size);
243:   MPI_Comm_rank(((PetscObject)v)->comm, &rank);

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

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

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

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

327: PetscErrorCode  PetscViewerMathematicaSetLinkName(PetscViewer v, const char *name) {
328:   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica *) v->data;
329:   PetscErrorCode          ierr;

334:   PetscStrallocpy(name, &vmath->linkname);
335:   return(0);
336: }

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

345:   snprintf(name, 16, "%6d", port);
346:   PetscViewerMathematicaSetLinkName(v, name);
347:   return(0);
348: }

352: PetscErrorCode  PetscViewerMathematicaSetLinkHost(PetscViewer v, const char *host) {
353:   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica *) v->data;
354:   PetscErrorCode          ierr;

359:   PetscStrallocpy(host, &vmath->linkhost);
360:   return(0);
361: }

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

369:   vmath->linkmode = mode;
370:   return(0);
371: }

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

379:   Collective on comm

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

387:   Output Parameter:
388: . viewer  - The Mathematica viewer

390:   Level: intermediate

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

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

412: .keywords: PetscViewer, Mathematica, open

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

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

435: /*@C
436:   PetscViewerMathematicaGetLink - Returns the link to Mathematica

438:   Input Parameters:
439: . viewer - The Mathematica viewer
440: . link   - The link to Mathematica

442:   Level: intermediate

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

453:   *link = vmath->link;
454:   return(0);
455: }

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

462:   Input Parameters:
463: . viewer - The Mathematica viewer
464: . type   - The packet type to search for, e.g RETURNPKT

466:   Level: advanced

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

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

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

492:   Input Parameter:
493: . viewer - The Mathematica viewer

495:   Output Parameter:
496: . name   - The name for new objects created in Mathematica

498:   Level: intermediate

500: .keywords PetscViewer, Mathematica, name
501: .seealso PetscViewerMathematicaSetName(), PetscViewerMathematicaClearName()
502: @*/
503: PetscErrorCode  PetscViewerMathematicaGetName(PetscViewer viewer, const char **name)
504: {
505:   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica *) viewer->data;

510:   *name = vmath->objName;
511:   return(0);
512: }

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

519:   Input Parameters:
520: . viewer - The Mathematica viewer
521: . name   - The name for new objects created in Mathematica

523:   Level: intermediate

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

535:   vmath->objName = name;
536:   return(0);
537: }

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

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

547:   Level: intermediate

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

558:   vmath->objName = PETSC_NULL;
559:   return(0);
560: }

564: /*@C
565:   PetscViewerMathematicaGetVector - Retrieve a vector from Mathematica

567:   Input Parameter:
568: . viewer - The Mathematica viewer

570:   Output Parameter:
571: . v      - The vector

573:   Level: intermediate

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


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

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

611:   return(0);
612: }

616: /*@C
617:   PetscViewerMathematicaPutVector - Send a vector to Mathematica

619:   Input Parameters:
620: + viewer - The Mathematica viewer
621: - v      - The vector

623:   Level: intermediate

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

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

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

658:   VecRestoreArray(v, &array);
659:   return(0);
660: }

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

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

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

691:   return(0);
692: }

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

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

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

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

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

757:   return(0);
758: }