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