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