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