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(PetscNewLog(v,&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++) { 223 PetscCall(PetscFree(hosts[h])); 224 } 225 PetscCall(PetscFree(hosts)); 226 /* Get link mode */ 227 PetscCall(PetscOptionsGetString("viewer_", "-math_linkmode", modename, sizeof(modename), &opt)); 228 if (opt) { 229 LinkMode mode; 230 231 PetscCall(PetscViewerMathematicaParseLinkMode(modename, &mode)); 232 PetscCall(PetscViewerMathematicaSetLinkMode(v, mode)); 233 } 234 /* Get graphics type */ 235 PetscCall(PetscOptionsGetString("viewer_", "-math_graphics", type, sizeof(type), &opt)); 236 if (opt) { 237 PetscBool isMotif, isPS, isPSFile; 238 239 PetscCall(PetscStrcasecmp(type, "Motif", &isMotif)); 240 PetscCall(PetscStrcasecmp(type, "PS", &isPS)); 241 PetscCall(PetscStrcasecmp(type, "PSFile", &isPSFile)); 242 if (isMotif) vmath->graphicsType = GRAPHICS_MOTIF; 243 else if (isPS) vmath->graphicsType = GRAPHICS_PS_STDOUT; 244 else if (isPSFile) vmath->graphicsType = GRAPHICS_PS_FILE; 245 } 246 /* Get plot type */ 247 PetscCall(PetscOptionsGetString("viewer_", "-math_type", type, sizeof(type), &opt)); 248 if (opt) { 249 PetscBool isTri, isVecTri, isVec, isSurface; 250 251 PetscCall(PetscStrcasecmp(type, "Triangulation", &isTri)); 252 PetscCall(PetscStrcasecmp(type, "VectorTriangulation", &isVecTri)); 253 PetscCall(PetscStrcasecmp(type, "Vector", &isVec)); 254 PetscCall(PetscStrcasecmp(type, "Surface", &isSurface)); 255 if (isTri) vmath->plotType = MATHEMATICA_TRIANGULATION_PLOT; 256 else if (isVecTri) vmath->plotType = MATHEMATICA_VECTOR_TRIANGULATION_PLOT; 257 else if (isVec) vmath->plotType = MATHEMATICA_VECTOR_PLOT; 258 else if (isSurface) vmath->plotType = MATHEMATICA_SURFACE_PLOT; 259 } 260 PetscFunctionReturn(0); 261 } 262 263 PetscErrorCode PetscViewerMathematicaSetLinkName(PetscViewer v, const char *name) 264 { 265 PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica*) v->data; 266 267 PetscFunctionBegin; 268 PetscValidHeaderSpecific(v,PETSC_VIEWER_CLASSID,1); 269 PetscValidCharPointer(name,2); 270 PetscCall(PetscStrallocpy(name, &vmath->linkname)); 271 PetscFunctionReturn(0); 272 } 273 274 PetscErrorCode PetscViewerMathematicaSetLinkPort(PetscViewer v, int port) 275 { 276 char name[16]; 277 278 PetscFunctionBegin; 279 snprintf(name, 16, "%6d", port); 280 PetscCall(PetscViewerMathematicaSetLinkName(v, name)); 281 PetscFunctionReturn(0); 282 } 283 284 PetscErrorCode PetscViewerMathematicaSetLinkHost(PetscViewer v, const char *host) 285 { 286 PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica*) v->data; 287 288 PetscFunctionBegin; 289 PetscValidHeaderSpecific(v,PETSC_VIEWER_CLASSID,1); 290 PetscValidCharPointer(host,2); 291 PetscCall(PetscStrallocpy(host, &vmath->linkhost)); 292 PetscFunctionReturn(0); 293 } 294 295 PetscErrorCode PetscViewerMathematicaSetLinkMode(PetscViewer v, LinkMode mode) 296 { 297 PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica*) v->data; 298 299 PetscFunctionBegin; 300 vmath->linkmode = mode; 301 PetscFunctionReturn(0); 302 } 303 304 /*----------------------------------------- Public Functions --------------------------------------------------------*/ 305 /*@C 306 PetscViewerMathematicaOpen - Communicates with Mathemtica using MathLink. 307 308 Collective 309 310 Input Parameters: 311 + comm - The MPI communicator 312 . port - [optional] The port to connect on, or PETSC_DECIDE 313 . machine - [optional] The machine to run Mathematica on, or NULL 314 - mode - [optional] The connection mode, or NULL 315 316 Output Parameter: 317 . viewer - The Mathematica viewer 318 319 Level: intermediate 320 321 Notes: 322 Most users should employ the following commands to access the 323 Mathematica viewers 324 $ 325 $ PetscViewerMathematicaOpen(MPI_Comm comm, int port, char *machine, char *mode, PetscViewer &viewer) 326 $ MatView(Mat matrix, PetscViewer viewer) 327 $ 328 $ or 329 $ 330 $ PetscViewerMathematicaOpen(MPI_Comm comm, int port, char *machine, char *mode, PetscViewer &viewer) 331 $ VecView(Vec vector, PetscViewer viewer) 332 333 Options Database Keys: 334 + -viewer_math_linkhost <machine> - The host machine for the kernel 335 . -viewer_math_linkname <name> - The full link name for the connection 336 . -viewer_math_linkport <port> - The port for the connection 337 . -viewer_math_mode <mode> - The mode, e.g. Launch, Connect 338 . -viewer_math_type <type> - The plot type, e.g. Triangulation, Vector 339 - -viewer_math_graphics <output> - The output type, e.g. Motif, PS, PSFile 340 341 .seealso: `MatView()`, `VecView()` 342 @*/ 343 PetscErrorCode PetscViewerMathematicaOpen(MPI_Comm comm, int port, const char machine[], const char mode[], PetscViewer *v) 344 { 345 PetscFunctionBegin; 346 PetscCall(PetscViewerCreate(comm, v)); 347 #if 0 348 LinkMode linkmode; 349 PetscCall(PetscViewerMathematicaSetLinkPort(*v, port)); 350 PetscCall(PetscViewerMathematicaSetLinkHost(*v, machine)); 351 PetscCall(PetscViewerMathematicaParseLinkMode(mode, &linkmode)); 352 PetscCall(PetscViewerMathematicaSetLinkMode(*v, linkmode)); 353 #endif 354 PetscCall(PetscViewerSetType(*v, PETSC_VIEWER_MATHEMATICA)); 355 PetscFunctionReturn(0); 356 } 357 358 /*@C 359 PetscViewerMathematicaGetLink - Returns the link to Mathematica 360 361 Input Parameters: 362 + viewer - The Mathematica viewer 363 - link - The link to Mathematica 364 365 Level: intermediate 366 367 .keywords PetscViewer, Mathematica, link 368 .seealso `PetscViewerMathematicaOpen()` 369 @*/ 370 PetscErrorCode PetscViewerMathematicaGetLink(PetscViewer viewer, MLINK *link) 371 { 372 PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica*) viewer->data; 373 374 PetscFunctionBegin; 375 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID,1); 376 *link = vmath->link; 377 PetscFunctionReturn(0); 378 } 379 380 /*@C 381 PetscViewerMathematicaSkipPackets - Discard packets sent by Mathematica until a certain packet type is received 382 383 Input Parameters: 384 + viewer - The Mathematica viewer 385 - type - The packet type to search for, e.g RETURNPKT 386 387 Level: advanced 388 389 .keywords PetscViewer, Mathematica, packets 390 .seealso `PetscViewerMathematicaSetName()`, `PetscViewerMathematicaGetVector()` 391 @*/ 392 PetscErrorCode PetscViewerMathematicaSkipPackets(PetscViewer viewer, int type) 393 { 394 PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica*) viewer->data; 395 MLINK link = vmath->link; /* The link to Mathematica */ 396 int pkt; /* The packet type */ 397 398 PetscFunctionBegin; 399 while ((pkt = MLNextPacket(link)) && (pkt != type)) MLNewPacket(link); 400 if (!pkt) { 401 MLClearError(link); 402 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB, (char*) MLErrorMessage(link)); 403 } 404 PetscFunctionReturn(0); 405 } 406 407 /*@C 408 PetscViewerMathematicaGetName - Retrieve the default name for objects communicated to Mathematica 409 410 Input Parameter: 411 . viewer - The Mathematica viewer 412 413 Output Parameter: 414 . name - The name for new objects created in Mathematica 415 416 Level: intermediate 417 418 .keywords PetscViewer, Mathematica, name 419 .seealso `PetscViewerMathematicaSetName()`, `PetscViewerMathematicaClearName()` 420 @*/ 421 PetscErrorCode PetscViewerMathematicaGetName(PetscViewer viewer, const char **name) 422 { 423 PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica*) viewer->data; 424 425 PetscFunctionBegin; 426 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID,1); 427 PetscValidPointer(name,2); 428 *name = vmath->objName; 429 PetscFunctionReturn(0); 430 } 431 432 /*@C 433 PetscViewerMathematicaSetName - Override the default name for objects communicated to Mathematica 434 435 Input Parameters: 436 + viewer - The Mathematica viewer 437 - name - The name for new objects created in Mathematica 438 439 Level: intermediate 440 441 .keywords PetscViewer, Mathematica, name 442 .seealso `PetscViewerMathematicaSetName()`, `PetscViewerMathematicaClearName()` 443 @*/ 444 PetscErrorCode PetscViewerMathematicaSetName(PetscViewer viewer, const char name[]) 445 { 446 PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica*) viewer->data; 447 448 PetscFunctionBegin; 449 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID,1); 450 PetscValidPointer(name,2); 451 vmath->objName = name; 452 PetscFunctionReturn(0); 453 } 454 455 /*@C 456 PetscViewerMathematicaClearName - Use the default name for objects communicated to Mathematica 457 458 Input Parameter: 459 . viewer - The Mathematica viewer 460 461 Level: intermediate 462 463 .keywords PetscViewer, Mathematica, name 464 .seealso `PetscViewerMathematicaGetName()`, `PetscViewerMathematicaSetName()` 465 @*/ 466 PetscErrorCode PetscViewerMathematicaClearName(PetscViewer viewer) 467 { 468 PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica*) viewer->data; 469 470 PetscFunctionBegin; 471 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID,1); 472 vmath->objName = NULL; 473 PetscFunctionReturn(0); 474 } 475 476 /*@C 477 PetscViewerMathematicaGetVector - Retrieve a vector from Mathematica 478 479 Input Parameter: 480 . viewer - The Mathematica viewer 481 482 Output Parameter: 483 . v - The vector 484 485 Level: intermediate 486 487 .keywords PetscViewer, Mathematica, vector 488 .seealso `VecView()`, `PetscViewerMathematicaPutVector()` 489 @*/ 490 PetscErrorCode PetscViewerMathematicaGetVector(PetscViewer viewer, Vec v) 491 { 492 PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica*) viewer->data; 493 MLINK link; /* The link to Mathematica */ 494 char *name; 495 PetscScalar *mArray,*array; 496 long mSize; 497 int n; 498 499 PetscFunctionBegin; 500 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID,1); 501 PetscValidHeaderSpecific(v, VEC_CLASSID,2); 502 503 /* Determine the object name */ 504 if (!vmath->objName) name = "vec"; 505 else name = (char*) vmath->objName; 506 507 link = vmath->link; 508 PetscCall(VecGetLocalSize(v, &n)); 509 PetscCall(VecGetArray(v, &array)); 510 MLPutFunction(link, "EvaluatePacket", 1); 511 MLPutSymbol(link, name); 512 MLEndPacket(link); 513 PetscCall(PetscViewerMathematicaSkipPackets(viewer, RETURNPKT)); 514 MLGetRealList(link, &mArray, &mSize); 515 PetscCheck(n == mSize,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Incompatible vector sizes %d %d",n,mSize); 516 PetscCall(PetscArraycpy(array, mArray, mSize)); 517 MLDisownRealList(link, mArray, mSize); 518 PetscCall(VecRestoreArray(v, &array)); 519 PetscFunctionReturn(0); 520 } 521 522 /*@C 523 PetscViewerMathematicaPutVector - Send a vector to Mathematica 524 525 Input Parameters: 526 + viewer - The Mathematica viewer 527 - v - The vector 528 529 Level: intermediate 530 531 .keywords PetscViewer, Mathematica, vector 532 .seealso `VecView()`, `PetscViewerMathematicaGetVector()` 533 @*/ 534 PetscErrorCode PetscViewerMathematicaPutVector(PetscViewer viewer, Vec v) 535 { 536 PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica*) viewer->data; 537 MLINK link = vmath->link; /* The link to Mathematica */ 538 char *name; 539 PetscScalar *array; 540 int n; 541 542 PetscFunctionBegin; 543 /* Determine the object name */ 544 if (!vmath->objName) name = "vec"; 545 else name = (char*) vmath->objName; 546 547 PetscCall(VecGetLocalSize(v, &n)); 548 PetscCall(VecGetArray(v, &array)); 549 550 /* Send the Vector object */ 551 MLPutFunction(link, "EvaluatePacket", 1); 552 MLPutFunction(link, "Set", 2); 553 MLPutSymbol(link, name); 554 MLPutRealList(link, array, n); 555 MLEndPacket(link); 556 /* Skip packets until ReturnPacket */ 557 PetscCall(PetscViewerMathematicaSkipPackets(viewer, RETURNPKT)); 558 /* Skip ReturnPacket */ 559 MLNewPacket(link); 560 561 PetscCall(VecRestoreArray(v, &array)); 562 PetscFunctionReturn(0); 563 } 564 565 PetscErrorCode PetscViewerMathematicaPutMatrix(PetscViewer viewer, int m, int n, PetscReal *a) 566 { 567 PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica*) viewer->data; 568 MLINK link = vmath->link; /* The link to Mathematica */ 569 char *name; 570 571 PetscFunctionBegin; 572 /* Determine the object name */ 573 if (!vmath->objName) name = "mat"; 574 else name = (char*) vmath->objName; 575 576 /* Send the dense matrix object */ 577 MLPutFunction(link, "EvaluatePacket", 1); 578 MLPutFunction(link, "Set", 2); 579 MLPutSymbol(link, name); 580 MLPutFunction(link, "Transpose", 1); 581 MLPutFunction(link, "Partition", 2); 582 MLPutRealList(link, a, m*n); 583 MLPutInteger(link, m); 584 MLEndPacket(link); 585 /* Skip packets until ReturnPacket */ 586 PetscCall(PetscViewerMathematicaSkipPackets(viewer, RETURNPKT)); 587 /* Skip ReturnPacket */ 588 MLNewPacket(link); 589 PetscFunctionReturn(0); 590 } 591 592 PetscErrorCode PetscViewerMathematicaPutCSRMatrix(PetscViewer viewer, int m, int n, int *i, int *j, PetscReal *a) 593 { 594 PetscViewer_Mathematica *vmath = (PetscViewer_Mathematica*) viewer->data; 595 MLINK link = vmath->link; /* The link to Mathematica */ 596 const char *symbol; 597 char *name; 598 PetscBool match; 599 600 PetscFunctionBegin; 601 /* Determine the object name */ 602 if (!vmath->objName) name = "mat"; 603 else name = (char*) vmath->objName; 604 605 /* Make sure Mathematica recognizes sparse matrices */ 606 MLPutFunction(link, "EvaluatePacket", 1); 607 MLPutFunction(link, "Needs", 1); 608 MLPutString(link, "LinearAlgebra`CSRMatrix`"); 609 MLEndPacket(link); 610 /* Skip packets until ReturnPacket */ 611 PetscCall(PetscViewerMathematicaSkipPackets(viewer, RETURNPKT)); 612 /* Skip ReturnPacket */ 613 MLNewPacket(link); 614 615 /* Send the CSRMatrix object */ 616 MLPutFunction(link, "EvaluatePacket", 1); 617 MLPutFunction(link, "Set", 2); 618 MLPutSymbol(link, name); 619 MLPutFunction(link, "CSRMatrix", 5); 620 MLPutInteger(link, m); 621 MLPutInteger(link, n); 622 MLPutFunction(link, "Plus", 2); 623 MLPutIntegerList(link, i, m+1); 624 MLPutInteger(link, 1); 625 MLPutFunction(link, "Plus", 2); 626 MLPutIntegerList(link, j, i[m]); 627 MLPutInteger(link, 1); 628 MLPutRealList(link, a, i[m]); 629 MLEndPacket(link); 630 /* Skip packets until ReturnPacket */ 631 PetscCall(PetscViewerMathematicaSkipPackets(viewer, RETURNPKT)); 632 /* Skip ReturnPacket */ 633 MLNewPacket(link); 634 635 /* Check that matrix is valid */ 636 MLPutFunction(link, "EvaluatePacket", 1); 637 MLPutFunction(link, "ValidQ", 1); 638 MLPutSymbol(link, name); 639 MLEndPacket(link); 640 PetscCall(PetscViewerMathematicaSkipPackets(viewer, RETURNPKT)); 641 MLGetSymbol(link, &symbol); 642 PetscCall(PetscStrcmp("True", (char*) symbol, &match)); 643 if (!match) { 644 MLDisownSymbol(link, symbol); 645 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB, "Invalid CSR matrix in Mathematica"); 646 } 647 MLDisownSymbol(link, symbol); 648 /* Skip ReturnPacket */ 649 MLNewPacket(link); 650 PetscFunctionReturn(0); 651 } 652