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