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