xref: /petsc/src/sys/classes/viewer/impls/mathematica/mathematica.c (revision feff33ee0b5b037fa8f9f294dede656a2f85cc47)
1 
2 #include <petsc/private/viewerimpl.h>   /* "petscsys.h" */
3 #include <petsc/private/pcimpl.h>
4 #include <../src/mat/impls/aij/seq/aij.h>
5 #include <mathematica.h>
6 
7 #if defined(PETSC_HAVE__SNPRINTF) && !defined(PETSC_HAVE_SNPRINTF)
8 #define snprintf _snprintf
9 #endif
10 
11 PetscViewer PETSC_VIEWER_MATHEMATICA_WORLD_PRIVATE = NULL;
12 static void *mathematicaEnv                        = NULL;
13 
14 static PetscBool PetscViewerMathematicaPackageInitialized = PETSC_FALSE;
15 /*@C
16   PetscViewerMathematicaFinalizePackage - This function destroys everything in the Petsc interface to Mathematica. It is
17   called from PetscFinalize().
18 
19   Level: developer
20 
21 .keywords: Petsc, destroy, package, mathematica
22 .seealso: PetscFinalize()
23 @*/
24 PetscErrorCode  PetscViewerMathematicaFinalizePackage(void)
25 {
26   PetscFunctionBegin;
27   if (mathematicaEnv) MLDeinitialize((MLEnvironment) mathematicaEnv);
28   PetscViewerMathematicaPackageInitialized = PETSC_TRUE;
29   PetscFunctionReturn(0);
30 }
31 
32 /*@C
33   PetscViewerMathematicaInitializePackage - This function initializes everything in the Petsc interface to Mathematica. It is
34   called from PetscDLLibraryRegister() when using dynamic libraries, and on the call to PetscInitialize()
35   when using static libraries.
36 
37   Level: developer
38 
39 .keywords: Petsc, initialize, package
40 .seealso: PetscSysInitializePackage(), PetscInitialize()
41 @*/
42 PetscErrorCode  PetscViewerMathematicaInitializePackage(void)
43 {
44   PetscError ierr;
45 
46   PetscFunctionBegin;
47   if (PetscViewerMathematicaPackageInitialized) PetscFunctionReturn(0);
48   PetscViewerMathematicaPackageInitialized = PETSC_TRUE;
49 
50   mathematicaEnv = (void*) MLInitialize(0);
51 
52   ierr = PetscRegisterFinalize(PetscViewerMathematicaFinalizePackage);CHKERRQ(ierr);
53   PetscFunctionReturn(0);
54 }
55 
56 
57 PetscErrorCode PetscViewerInitializeMathematicaWorld_Private()
58 {
59   PetscErrorCode ierr;
60 
61   PetscFunctionBegin;
62   if (PETSC_VIEWER_MATHEMATICA_WORLD_PRIVATE) PetscFunctionReturn(0);
63   ierr = PetscViewerMathematicaOpen(PETSC_COMM_WORLD, PETSC_DECIDE, NULL, NULL, &PETSC_VIEWER_MATHEMATICA_WORLD_PRIVATE);CHKERRQ(ierr);
64   PetscFunctionReturn(0);
65 }
66 
67 static PetscErrorCode PetscViewerDestroy_Mathematica(PetscViewer viewer)
68 {
69   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica*) viewer->data;
70   PetscErrorCode          ierr;
71 
72   PetscFunctionBegin;
73   MLClose(vmath->link);
74   ierr = PetscFree(vmath->linkname);CHKERRQ(ierr);
75   ierr = PetscFree(vmath->linkhost);CHKERRQ(ierr);
76   ierr = PetscFree(vmath);CHKERRQ(ierr);
77   PetscFunctionReturn(0);
78 }
79 
80 PetscErrorCode PetscViewerDestroyMathematica_Private(void)
81 {
82   PetscErrorCode ierr;
83 
84   PetscFunctionBegin;
85   if (PETSC_VIEWER_MATHEMATICA_WORLD_PRIVATE) {
86     ierr = PetscViewerDestroy(PETSC_VIEWER_MATHEMATICA_WORLD_PRIVATE);CHKERRQ(ierr);
87   }
88   PetscFunctionReturn(0);
89 }
90 
91 PetscErrorCode PetscViewerMathematicaSetupConnection_Private(PetscViewer v)
92 {
93   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica*) v->data;
94 #if defined(MATHEMATICA_3_0)
95   int                     argc = 6;
96   char                    *argv[6];
97 #else
98   int                     argc = 5;
99   char                    *argv[5];
100 #endif
101   char                    hostname[256];
102   long                    lerr;
103   PetscErrorCode          ierr;
104 
105   PetscFunctionBegin;
106   /* Link name */
107   argv[0] = "-linkname";
108   if (!vmath->linkname) argv[1] = "math -mathlink";
109   else                  argv[1] = vmath->linkname;
110 
111   /* Link host */
112   argv[2] = "-linkhost";
113   if (!vmath->linkhost) {
114     ierr    = PetscGetHostName(hostname, 255);CHKERRQ(ierr);
115     argv[3] = hostname;
116   } else argv[3] = vmath->linkhost;
117 
118   /* Link mode */
119 #if defined(MATHEMATICA_3_0)
120   argv[4] = "-linkmode";
121   switch (vmath->linkmode) {
122   case MATHEMATICA_LINK_CREATE:
123     argv[5] = "Create";
124     break;
125   case MATHEMATICA_LINK_CONNECT:
126     argv[5] = "Connect";
127     break;
128   case MATHEMATICA_LINK_LAUNCH:
129     argv[5] = "Launch";
130     break;
131   }
132 #else
133   switch (vmath->linkmode) {
134   case MATHEMATICA_LINK_CREATE:
135     argv[4] = "-linkcreate";
136     break;
137   case MATHEMATICA_LINK_CONNECT:
138     argv[4] = "-linkconnect";
139     break;
140   case MATHEMATICA_LINK_LAUNCH:
141     argv[4] = "-linklaunch";
142     break;
143   }
144 #endif
145   vmath->link = MLOpenInEnv(mathematicaEnv, argc, argv, &lerr);
146 #endif
147   PetscFunctionReturn(0);
148 }
149 
150 PETSC_EXTERN PetscErrorCode PetscViewerCreate_Mathematica(PetscViewer v)
151 {
152   PetscViewer_Mathematica *vmath;
153   PetscErrorCode          ierr;
154 
155   PetscFunctionBegin;
156   ierr = PetscViewerMathematicaInitializePackage();CHKERRQ(ierr);
157 
158   ierr            = PetscNewLog(v,&vmath);CHKERRQ(ierr);
159   v->data         = (void*) vmath;
160   v->ops->destroy = PetscViewerDestroy_Mathematica;
161   v->ops->flush   = 0;
162   ierr            = PetscStrallocpy(PETSC_VIEWER_MATHEMATICA, &((PetscObject)v)->type_name);CHKERRQ(ierr);
163 
164   vmath->linkname     = NULL;
165   vmath->linkhost     = NULL;
166   vmath->linkmode     = MATHEMATICA_LINK_CONNECT;
167   vmath->graphicsType = GRAPHICS_MOTIF;
168   vmath->plotType     = MATHEMATICA_TRIANGULATION_PLOT;
169   vmath->objName      = NULL;
170 
171   ierr = PetscViewerMathematicaSetFromOptions(v);CHKERRQ(ierr);
172   ierr = PetscViewerMathematicaSetupConnection_Private(v);CHKERRQ(ierr);
173   PetscFunctionReturn(0);
174 }
175 
176 PetscErrorCode PetscViewerMathematicaParseLinkMode_Private(char *modename, LinkMode *mode)
177 {
178   PetscBool      isCreate, isConnect, isLaunch;
179   PetscErrorCode ierr;
180 
181   PetscFunctionBegin;
182   ierr = PetscStrcasecmp(modename, "Create",  &isCreate);CHKERRQ(ierr);
183   ierr = PetscStrcasecmp(modename, "Connect", &isConnect);CHKERRQ(ierr);
184   ierr = PetscStrcasecmp(modename, "Launch",  &isLaunch);CHKERRQ(ierr);
185   if (isCreate)       *mode = MATHEMATICA_LINK_CREATE;
186   else if (isConnect) *mode = MATHEMATICA_LINK_CONNECT;
187   else if (isLaunch)  *mode = MATHEMATICA_LINK_LAUNCH;
188   else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Invalid Mathematica link mode: %s", modename);
189   PetscFunctionReturn(0);
190 }
191 
192 PetscErrorCode  PetscViewerMathematicaSetFromOptions(PetscViewer v)
193 {
194   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica*) v->data;
195   char                    linkname[256];
196   char                    modename[256];
197   char                    hostname[256];
198   char                    type[256];
199   PetscInt                numPorts;
200   PetscInt                *ports;
201   PetscInt                numHosts;
202   int                     h;
203   char                    **hosts;
204   PetscMPIInt             size, rank;
205   PetscBool               opt;
206   PetscErrorCode          ierr;
207 
208   PetscFunctionBegin;
209   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)v), &size);CHKERRQ(ierr);
210   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)v), &rank);CHKERRQ(ierr);
211 
212   /* Get link name */
213   ierr = PetscOptionsGetString("viewer_", "-math_linkname", linkname, 256, &opt);CHKERRQ(ierr);
214   if (opt) {
215     ierr = PetscViewerMathematicaSetLinkName(v, linkname);CHKERRQ(ierr);
216   }
217   /* Get link port */
218   numPorts = size;
219   ierr     = PetscMalloc1(size, &ports);CHKERRQ(ierr);
220   ierr     = PetscOptionsGetIntArray("viewer_", "-math_linkport", ports, &numPorts, &opt);CHKERRQ(ierr);
221   if (opt) {
222     if (numPorts > rank) snprintf(linkname, 255, "%6d", ports[rank]);
223     else                 snprintf(linkname, 255, "%6d", ports[0]);
224     ierr = PetscViewerMathematicaSetLinkName(v, linkname);CHKERRQ(ierr);
225   }
226   ierr = PetscFree(ports);CHKERRQ(ierr);
227   /* Get link host */
228   numHosts = size;
229   ierr     = PetscMalloc1(size, &hosts);CHKERRQ(ierr);
230   ierr     = PetscOptionsGetStringArray("viewer_", "-math_linkhost", hosts, &numHosts, &opt);CHKERRQ(ierr);
231   if (opt) {
232     if (numHosts > rank) {
233       ierr = PetscStrncpy(hostname, hosts[rank], 255);CHKERRQ(ierr);
234     } else {
235       ierr = PetscStrncpy(hostname, hosts[0], 255);CHKERRQ(ierr);
236     }
237     ierr = PetscViewerMathematicaSetLinkHost(v, hostname);CHKERRQ(ierr);
238   }
239   for (h = 0; h < numHosts; h++) {
240     ierr = PetscFree(hosts[h]);CHKERRQ(ierr);
241   }
242   ierr = PetscFree(hosts);CHKERRQ(ierr);
243   /* Get link mode */
244   ierr = PetscOptionsGetString("viewer_", "-math_linkmode", modename, 256, &opt);CHKERRQ(ierr);
245   if (opt) {
246     LinkMode mode;
247 
248     ierr = PetscViewerMathematicaParseLinkMode_Private(modename, &mode);CHKERRQ(ierr);
249     ierr = PetscViewerMathematicaSetLinkMode(v, mode);CHKERRQ(ierr);
250   }
251   /* Get graphics type */
252   ierr = PetscOptionsGetString("viewer_", "-math_graphics", type, 256, &opt);CHKERRQ(ierr);
253   if (opt) {
254     PetscBool isMotif, isPS, isPSFile;
255 
256     ierr = PetscStrcasecmp(type, "Motif",  &isMotif);CHKERRQ(ierr);
257     ierr = PetscStrcasecmp(type, "PS",     &isPS);CHKERRQ(ierr);
258     ierr = PetscStrcasecmp(type, "PSFile", &isPSFile);CHKERRQ(ierr);
259     if (isMotif)       vmath->graphicsType = GRAPHICS_MOTIF;
260     else if (isPS)     vmath->graphicsType = GRAPHICS_PS_STDOUT;
261     else if (isPSFile) vmath->graphicsType = GRAPHICS_PS_FILE;
262   }
263   /* Get plot type */
264   ierr = PetscOptionsGetString("viewer_", "-math_type", type, 256, &opt);CHKERRQ(ierr);
265   if (opt) {
266     PetscBool isTri, isVecTri, isVec, isSurface;
267 
268     ierr = PetscStrcasecmp(type, "Triangulation",       &isTri);CHKERRQ(ierr);
269     ierr = PetscStrcasecmp(type, "VectorTriangulation", &isVecTri);CHKERRQ(ierr);
270     ierr = PetscStrcasecmp(type, "Vector",              &isVec);CHKERRQ(ierr);
271     ierr = PetscStrcasecmp(type, "Surface",             &isSurface);CHKERRQ(ierr);
272     if (isTri)          vmath->plotType = MATHEMATICA_TRIANGULATION_PLOT;
273     else if (isVecTri)  vmath->plotType = MATHEMATICA_VECTOR_TRIANGULATION_PLOT;
274     else if (isVec)     vmath->plotType = MATHEMATICA_VECTOR_PLOT;
275     else if (isSurface) vmath->plotType = MATHEMATICA_SURFACE_PLOT;
276   }
277   PetscFunctionReturn(0);
278 }
279 
280 PetscErrorCode  PetscViewerMathematicaSetLinkName(PetscViewer v, const char *name)
281 {
282   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica*) v->data;
283   PetscErrorCode          ierr;
284 
285   PetscFunctionBegin;
286   PetscValidHeaderSpecific(v,PETSC_VIEWER_CLASSID,1);
287   PetscValidCharPointer(name,2);
288   ierr = PetscStrallocpy(name, &vmath->linkname);CHKERRQ(ierr);
289   PetscFunctionReturn(0);
290 }
291 
292 PetscErrorCode  PetscViewerMathematicaSetLinkPort(PetscViewer v, int port)
293 {
294   char           name[16];
295   PetscErrorCode ierr;
296 
297   PetscFunctionBegin;
298   snprintf(name, 16, "%6d", port);
299   ierr = PetscViewerMathematicaSetLinkName(v, name);CHKERRQ(ierr);
300   PetscFunctionReturn(0);
301 }
302 
303 PetscErrorCode  PetscViewerMathematicaSetLinkHost(PetscViewer v, const char *host)
304 {
305   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica*) v->data;
306   PetscErrorCode          ierr;
307 
308   PetscFunctionBegin;
309   PetscValidHeaderSpecific(v,PETSC_VIEWER_CLASSID,1);
310   PetscValidCharPointer(host,2);
311   ierr = PetscStrallocpy(host, &vmath->linkhost);CHKERRQ(ierr);
312   PetscFunctionReturn(0);
313 }
314 
315 PetscErrorCode  PetscViewerMathematicaSetLinkMode(PetscViewer v, LinkMode mode)
316 {
317   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica*) v->data;
318 
319   PetscFunctionBegin;
320   vmath->linkmode = mode;
321   PetscFunctionReturn(0);
322 }
323 
324 /*----------------------------------------- Public Functions --------------------------------------------------------*/
325 /*@C
326   PetscViewerMathematicaOpen - Communicates with Mathemtica using MathLink.
327 
328   Collective on comm
329 
330   Input Parameters:
331 + comm    - The MPI communicator
332 . port    - [optional] The port to connect on, or PETSC_DECIDE
333 . machine - [optional] The machine to run Mathematica on, or NULL
334 - mode    - [optional] The connection mode, or NULL
335 
336   Output Parameter:
337 . viewer  - The Mathematica viewer
338 
339   Level: intermediate
340 
341   Notes:
342   Most users should employ the following commands to access the
343   Mathematica viewers
344 $
345 $    PetscViewerMathematicaOpen(MPI_Comm comm, int port, char *machine, char *mode, PetscViewer &viewer)
346 $    MatView(Mat matrix, PetscViewer viewer)
347 $
348 $                or
349 $
350 $    PetscViewerMathematicaOpen(MPI_Comm comm, int port, char *machine, char *mode, PetscViewer &viewer)
351 $    VecView(Vec vector, PetscViewer viewer)
352 
353    Options Database Keys:
354 +    -viewer_math_linkhost <machine> - The host machine for the kernel
355 .    -viewer_math_linkname <name>    - The full link name for the connection
356 .    -viewer_math_linkport <port>    - The port for the connection
357 .    -viewer_math_mode <mode>        - The mode, e.g. Launch, Connect
358 .    -viewer_math_type <type>        - The plot type, e.g. Triangulation, Vector
359 -    -viewer_math_graphics <output>  - The output type, e.g. Motif, PS, PSFile
360 
361 .keywords: PetscViewer, Mathematica, open
362 
363 .seealso: MatView(), VecView()
364 @*/
365 PetscErrorCode  PetscViewerMathematicaOpen(MPI_Comm comm, int port, const char machine[], const char mode[], PetscViewer *v)
366 {
367   PetscErrorCode ierr;
368 
369   PetscFunctionBegin;
370   ierr = PetscViewerCreate(comm, v);CHKERRQ(ierr);
371 #if 0
372   LinkMode linkmode;
373   ierr = PetscViewerMathematicaSetLinkPort(*v, port);CHKERRQ(ierr);
374   ierr = PetscViewerMathematicaSetLinkHost(*v, machine);CHKERRQ(ierr);
375   ierr = PetscViewerMathematicaParseLinkMode_Private(mode, &linkmode);CHKERRQ(ierr);
376   ierr = PetscViewerMathematicaSetLinkMode(*v, linkmode);CHKERRQ(ierr);
377 #endif
378   ierr = PetscViewerSetType(*v, PETSC_VIEWER_MATHEMATICA);CHKERRQ(ierr);
379   PetscFunctionReturn(0);
380 }
381 
382 /*@C
383   PetscViewerMathematicaGetLink - Returns the link to Mathematica
384 
385   Input Parameters:
386 . viewer - The Mathematica viewer
387 . link   - The link to Mathematica
388 
389   Level: intermediate
390 
391 .keywords PetscViewer, Mathematica, link
392 .seealso PetscViewerMathematicaOpen()
393 @*/
394 PetscErrorCode  PetscViewerMathematicaGetLink(PetscViewer viewer, MLINK *link)
395 {
396   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica*) viewer->data;
397 
398   PetscFunctionBegin;
399   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID,1);
400   *link = vmath->link;
401   PetscFunctionReturn(0);
402 }
403 
404 /*@C
405   PetscViewerMathematicaSkipPackets - Discard packets sent by Mathematica until a certain packet type is received
406 
407   Input Parameters:
408 . viewer - The Mathematica viewer
409 . type   - The packet type to search for, e.g RETURNPKT
410 
411   Level: advanced
412 
413 .keywords PetscViewer, Mathematica, packets
414 .seealso PetscViewerMathematicaSetName(), PetscViewerMathematicaGetVector()
415 @*/
416 PetscErrorCode  PetscViewerMathematicaSkipPackets(PetscViewer viewer, int type)
417 {
418   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica*) viewer->data;
419   MLINK                   link   = vmath->link; /* The link to Mathematica */
420   int                     pkt;                 /* The packet type */
421 
422   PetscFunctionBegin;
423   while ((pkt = MLNextPacket(link)) && (pkt != type)) MLNewPacket(link);
424   if (!pkt) {
425     MLClearError(link);
426     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB, (char*) MLErrorMessage(link));
427   }
428   PetscFunctionReturn(0);
429 }
430 
431 /*@C
432   PetscViewerMathematicaGetName - Retrieve the default name for objects communicated to Mathematica
433 
434   Input Parameter:
435 . viewer - The Mathematica viewer
436 
437   Output Parameter:
438 . name   - The name for new objects created in Mathematica
439 
440   Level: intermediate
441 
442 .keywords PetscViewer, Mathematica, name
443 .seealso PetscViewerMathematicaSetName(), PetscViewerMathematicaClearName()
444 @*/
445 PetscErrorCode  PetscViewerMathematicaGetName(PetscViewer viewer, const char **name)
446 {
447   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica*) viewer->data;
448 
449   PetscFunctionBegin;
450   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID,1);
451   PetscValidPointer(name,2);
452   *name = vmath->objName;
453   PetscFunctionReturn(0);
454 }
455 
456 /*@C
457   PetscViewerMathematicaSetName - Override the default name for objects communicated to Mathematica
458 
459   Input Parameters:
460 . viewer - The Mathematica viewer
461 . name   - The name for new objects created in Mathematica
462 
463   Level: intermediate
464 
465 .keywords PetscViewer, Mathematica, name
466 .seealso PetscViewerMathematicaSetName(), PetscViewerMathematicaClearName()
467 @*/
468 PetscErrorCode  PetscViewerMathematicaSetName(PetscViewer viewer, const char name[])
469 {
470   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica*) viewer->data;
471 
472   PetscFunctionBegin;
473   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID,1);
474   PetscValidPointer(name,2);
475   vmath->objName = name;
476   PetscFunctionReturn(0);
477 }
478 
479 /*@C
480   PetscViewerMathematicaClearName - Use the default name for objects communicated to Mathematica
481 
482   Input Parameter:
483 . viewer - The Mathematica viewer
484 
485   Level: intermediate
486 
487 .keywords PetscViewer, Mathematica, name
488 .seealso PetscViewerMathematicaGetName(), PetscViewerMathematicaSetName()
489 @*/
490 PetscErrorCode  PetscViewerMathematicaClearName(PetscViewer viewer)
491 {
492   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica*) viewer->data;
493 
494   PetscFunctionBegin;
495   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID,1);
496   vmath->objName = NULL;
497   PetscFunctionReturn(0);
498 }
499 
500 /*@C
501   PetscViewerMathematicaGetVector - Retrieve a vector from Mathematica
502 
503   Input Parameter:
504 . viewer - The Mathematica viewer
505 
506   Output Parameter:
507 . v      - The vector
508 
509   Level: intermediate
510 
511 .keywords PetscViewer, Mathematica, vector
512 .seealso VecView(), PetscViewerMathematicaPutVector()
513 @*/
514 PetscErrorCode  PetscViewerMathematicaGetVector(PetscViewer viewer, Vec v)
515 {
516   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica*) viewer->data;
517   MLINK                   link;   /* The link to Mathematica */
518   char                    *name;
519   PetscScalar             *mArray,*array;
520   long                    mSize;
521   int                     n;
522   PetscErrorCode          ierr;
523 
524   PetscFunctionBegin;
525   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID,1);
526   PetscValidHeaderSpecific(v,      VEC_CLASSID,2);
527 
528   /* Determine the object name */
529   if (!vmath->objName) name = "vec";
530   else                 name = (char*) vmath->objName;
531 
532   link = vmath->link;
533   ierr = VecGetLocalSize(v, &n);CHKERRQ(ierr);
534   ierr = VecGetArray(v, &array);CHKERRQ(ierr);
535   MLPutFunction(link, "EvaluatePacket", 1);
536   MLPutSymbol(link, name);
537   MLEndPacket(link);
538   ierr = PetscViewerMathematicaSkipPackets(viewer, RETURNPKT);CHKERRQ(ierr);
539   MLGetRealList(link, &mArray, &mSize);
540   if (n != mSize) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Incompatible vector sizes %d %d",n,mSize);
541   ierr = PetscMemcpy(array, mArray, mSize * sizeof(double));CHKERRQ(ierr);
542   MLDisownRealList(link, mArray, mSize);
543   ierr = VecRestoreArray(v, &array);CHKERRQ(ierr);
544   PetscFunctionReturn(0);
545 }
546 
547 /*@C
548   PetscViewerMathematicaPutVector - Send a vector to Mathematica
549 
550   Input Parameters:
551 + viewer - The Mathematica viewer
552 - v      - The vector
553 
554   Level: intermediate
555 
556 .keywords PetscViewer, Mathematica, vector
557 .seealso VecView(), PetscViewerMathematicaGetVector()
558 @*/
559 PetscErrorCode  PetscViewerMathematicaPutVector(PetscViewer viewer, Vec v)
560 {
561   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica*) viewer->data;
562   MLINK                   link   = vmath->link; /* The link to Mathematica */
563   char                    *name;
564   PetscScalar             *array;
565   int                     n;
566   PetscErrorCode          ierr;
567 
568   PetscFunctionBegin;
569   /* Determine the object name */
570   if (!vmath->objName) name = "vec";
571   else                 name = (char*) vmath->objName;
572 
573   ierr = VecGetLocalSize(v, &n);CHKERRQ(ierr);
574   ierr = VecGetArray(v, &array);CHKERRQ(ierr);
575 
576   /* Send the Vector object */
577   MLPutFunction(link, "EvaluatePacket", 1);
578   MLPutFunction(link, "Set", 2);
579   MLPutSymbol(link, name);
580   MLPutRealList(link, array, n);
581   MLEndPacket(link);
582   /* Skip packets until ReturnPacket */
583   ierr = PetscViewerMathematicaSkipPackets(viewer, RETURNPKT);CHKERRQ(ierr);
584   /* Skip ReturnPacket */
585   MLNewPacket(link);
586 
587   ierr = VecRestoreArray(v, &array);CHKERRQ(ierr);
588   PetscFunctionReturn(0);
589 }
590 
591 PetscErrorCode  PetscViewerMathematicaPutMatrix(PetscViewer viewer, int m, int n, PetscReal *a)
592 {
593   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica*) viewer->data;
594   MLINK                   link   = vmath->link; /* The link to Mathematica */
595   char                    *name;
596   PetscErrorCode          ierr;
597 
598   PetscFunctionBegin;
599   /* Determine the object name */
600   if (!vmath->objName) name = "mat";
601   else                 name = (char*) vmath->objName;
602 
603   /* Send the dense matrix object */
604   MLPutFunction(link, "EvaluatePacket", 1);
605   MLPutFunction(link, "Set", 2);
606   MLPutSymbol(link, name);
607   MLPutFunction(link, "Transpose", 1);
608   MLPutFunction(link, "Partition", 2);
609   MLPutRealList(link, a, m*n);
610   MLPutInteger(link, m);
611   MLEndPacket(link);
612   /* Skip packets until ReturnPacket */
613   ierr = PetscViewerMathematicaSkipPackets(viewer, RETURNPKT);CHKERRQ(ierr);
614   /* Skip ReturnPacket */
615   MLNewPacket(link);
616   PetscFunctionReturn(0);
617 }
618 
619 PetscErrorCode  PetscViewerMathematicaPutCSRMatrix(PetscViewer viewer, int m, int n, int *i, int *j, PetscReal *a)
620 {
621   PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica*) viewer->data;
622   MLINK                   link   = vmath->link; /* The link to Mathematica */
623   const char              *symbol;
624   char                    *name;
625   PetscBool               match;
626   PetscErrorCode          ierr;
627 
628   PetscFunctionBegin;
629   /* Determine the object name */
630   if (!vmath->objName) name = "mat";
631   else                 name = (char*) vmath->objName;
632 
633   /* Make sure Mathematica recognizes sparse matrices */
634   MLPutFunction(link, "EvaluatePacket", 1);
635   MLPutFunction(link, "Needs", 1);
636   MLPutString(link, "LinearAlgebra`CSRMatrix`");
637   MLEndPacket(link);
638   /* Skip packets until ReturnPacket */
639   ierr = PetscViewerMathematicaSkipPackets(viewer, RETURNPKT);CHKERRQ(ierr);
640   /* Skip ReturnPacket */
641   MLNewPacket(link);
642 
643   /* Send the CSRMatrix object */
644   MLPutFunction(link, "EvaluatePacket", 1);
645   MLPutFunction(link, "Set", 2);
646   MLPutSymbol(link, name);
647   MLPutFunction(link, "CSRMatrix", 5);
648   MLPutInteger(link, m);
649   MLPutInteger(link, n);
650   MLPutFunction(link, "Plus", 2);
651   MLPutIntegerList(link, i, m+1);
652   MLPutInteger(link, 1);
653   MLPutFunction(link, "Plus", 2);
654   MLPutIntegerList(link, j, i[m]);
655   MLPutInteger(link, 1);
656   MLPutRealList(link, a, i[m]);
657   MLEndPacket(link);
658   /* Skip packets until ReturnPacket */
659   ierr = PetscViewerMathematicaSkipPackets(viewer, RETURNPKT);CHKERRQ(ierr);
660   /* Skip ReturnPacket */
661   MLNewPacket(link);
662 
663   /* Check that matrix is valid */
664   MLPutFunction(link, "EvaluatePacket", 1);
665   MLPutFunction(link, "ValidQ", 1);
666   MLPutSymbol(link, name);
667   MLEndPacket(link);
668   ierr = PetscViewerMathematicaSkipPackets(viewer, RETURNPKT);CHKERRQ(ierr);
669   MLGetSymbol(link, &symbol);
670   ierr = PetscStrcmp("True", (char*) symbol, &match);CHKERRQ(ierr);
671   if (!match) {
672     MLDisownSymbol(link, symbol);
673     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB, "Invalid CSR matrix in Mathematica");
674   }
675   MLDisownSymbol(link, symbol);
676   /* Skip ReturnPacket */
677   MLNewPacket(link);
678   PetscFunctionReturn(0);
679 }
680 
681