Actual source code: mathematica.c

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

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

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

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

 26:   Input Parameter:
 27:   path - The dynamic library path, or PETSC_NULL

 29:   Level: developer

 31: .keywords: Petsc, initialize, package, PLAPACK
 32: .seealso: PetscInitializePackage(), PetscInitialize()
 33: @*/
 34: PetscErrorCode PetscViewerMathematicaInitializePackage(char *path)
 35: {
 36:   static PetscTruth initialized = PETSC_FALSE;

 39:   if (initialized) return(0);
 40:   initialized = PETSC_TRUE;
 41:   mathematicaEnv = (void*) MLInitialize(0);
 42:   return(0);
 43: }

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

 51:   Level: developer

 53: .keywords: Petsc, destroy, package, mathematica
 54: .seealso: PetscFinalize()
 55: @*/
 56: PetscErrorCode PetscViewerMathematicaFinalizePackage(void)
 57: {
 59:   if (mathematicaEnv) MLDeinitialize((MLEnvironment) mathematicaEnv);
 60:   return(0);
 61: }

 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:   if (vmath->linkname != PETSC_NULL) {
 85:     PetscFree(vmath->linkname);
 86:   }
 87:   if (vmath->linkhost != PETSC_NULL) {
 88:     PetscFree(vmath->linkhost);
 89:   }
 90:   PetscFree(vmath);
 91:   return(0);
 92: }

 96: PetscErrorCode PetscViewerDestroyMathematica_Private(void)
 97: {

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

380:   Collective on comm

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

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

391:   Level: intermediate

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

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

413: .keywords: PetscViewer, Mathematica, open

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

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

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

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

443:   Level: intermediate

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

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

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

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

467:   Level: advanced

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

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

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

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

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

499:   Level: intermediate

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

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

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

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

524:   Level: intermediate

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

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

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

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

548:   Level: intermediate

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

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

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

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

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

574:   Level: intermediate

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


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

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

612:   return(0);
613: }

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

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

624:   Level: intermediate

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

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

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

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

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

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

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

692:   return(0);
693: }

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

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

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

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

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

758:   return(0);
759: }