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