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