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