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