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: }