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