1# -------------------------------------------------------------------- 2 3class MatType(object): 4 """Matrix type. 5 6 See Also 7 -------- 8 petsc.MatType 9 10 """ 11 SAME = S_(MATSAME) 12 MAIJ = S_(MATMAIJ) 13 SEQMAIJ = S_(MATSEQMAIJ) 14 MPIMAIJ = S_(MATMPIMAIJ) 15 KAIJ = S_(MATKAIJ) 16 SEQKAIJ = S_(MATSEQKAIJ) 17 MPIKAIJ = S_(MATMPIKAIJ) 18 IS = S_(MATIS) 19 AIJ = S_(MATAIJ) 20 SEQAIJ = S_(MATSEQAIJ) 21 MPIAIJ = S_(MATMPIAIJ) 22 AIJCRL = S_(MATAIJCRL) 23 SEQAIJCRL = S_(MATSEQAIJCRL) 24 MPIAIJCRL = S_(MATMPIAIJCRL) 25 AIJCUSPARSE = S_(MATAIJCUSPARSE) 26 SEQAIJCUSPARSE = S_(MATSEQAIJCUSPARSE) 27 MPIAIJCUSPARSE = S_(MATMPIAIJCUSPARSE) 28 AIJVIENNACL = S_(MATAIJVIENNACL) 29 SEQAIJVIENNACL = S_(MATSEQAIJVIENNACL) 30 MPIAIJVIENNACL = S_(MATMPIAIJVIENNACL) 31 AIJPERM = S_(MATAIJPERM) 32 SEQAIJPERM = S_(MATSEQAIJPERM) 33 MPIAIJPERM = S_(MATMPIAIJPERM) 34 AIJSELL = S_(MATAIJSELL) 35 SEQAIJSELL = S_(MATSEQAIJSELL) 36 MPIAIJSELL = S_(MATMPIAIJSELL) 37 AIJMKL = S_(MATAIJMKL) 38 SEQAIJMKL = S_(MATSEQAIJMKL) 39 MPIAIJMKL = S_(MATMPIAIJMKL) 40 BAIJMKL = S_(MATBAIJMKL) 41 SEQBAIJMKL = S_(MATSEQBAIJMKL) 42 MPIBAIJMKL = S_(MATMPIBAIJMKL) 43 SHELL = S_(MATSHELL) 44 DENSE = S_(MATDENSE) 45 DENSECUDA = S_(MATDENSECUDA) 46 DENSEHIP = S_(MATDENSEHIP) 47 SEQDENSE = S_(MATSEQDENSE) 48 SEQDENSECUDA = S_(MATSEQDENSECUDA) 49 SEQDENSEHIP = S_(MATSEQDENSEHIP) 50 MPIDENSE = S_(MATMPIDENSE) 51 MPIDENSECUDA = S_(MATMPIDENSECUDA) 52 MPIDENSEHIP = S_(MATMPIDENSEHIP) 53 ELEMENTAL = S_(MATELEMENTAL) 54 BAIJ = S_(MATBAIJ) 55 SEQBAIJ = S_(MATSEQBAIJ) 56 MPIBAIJ = S_(MATMPIBAIJ) 57 MPIADJ = S_(MATMPIADJ) 58 SBAIJ = S_(MATSBAIJ) 59 SEQSBAIJ = S_(MATSEQSBAIJ) 60 MPISBAIJ = S_(MATMPISBAIJ) 61 MFFD = S_(MATMFFD) 62 NORMAL = S_(MATNORMAL) 63 NORMALHERMITIAN = S_(MATNORMALHERMITIAN) 64 LRC = S_(MATLRC) 65 SCATTER = S_(MATSCATTER) 66 BLOCKMAT = S_(MATBLOCKMAT) 67 COMPOSITE = S_(MATCOMPOSITE) 68 FFT = S_(MATFFT) 69 FFTW = S_(MATFFTW) 70 SEQCUFFT = S_(MATSEQCUFFT) 71 TRANSPOSE = S_(MATTRANSPOSEVIRTUAL) 72 HERMITIANTRANSPOSE = S_(MATHERMITIANTRANSPOSEVIRTUAL) 73 SCHURCOMPLEMENT = S_(MATSCHURCOMPLEMENT) 74 PYTHON = S_(MATPYTHON) 75 HYPRE = S_(MATHYPRE) 76 HYPRESTRUCT = S_(MATHYPRESTRUCT) 77 HYPRESSTRUCT = S_(MATHYPRESSTRUCT) 78 SUBMATRIX = S_(MATSUBMATRIX) 79 LOCALREF = S_(MATLOCALREF) 80 NEST = S_(MATNEST) 81 PREALLOCATOR = S_(MATPREALLOCATOR) 82 SELL = S_(MATSELL) 83 SEQSELL = S_(MATSEQSELL) 84 MPISELL = S_(MATMPISELL) 85 DUMMY = S_(MATDUMMY) 86 LMVM = S_(MATLMVM) 87 LMVMDFP = S_(MATLMVMDFP) 88 LMVMDDFP = S_(MATLMVMDDFP) 89 LMVMBFGS = S_(MATLMVMBFGS) 90 LMVMDBFGS = S_(MATLMVMDBFGS) 91 LMVMDQN = S_(MATLMVMDQN) 92 LMVMSR1 = S_(MATLMVMSR1) 93 LMVMBROYDEN = S_(MATLMVMBROYDEN) 94 LMVMBADBROYDEN = S_(MATLMVMBADBROYDEN) 95 LMVMSYMBROYDEN = S_(MATLMVMSYMBROYDEN) 96 LMVMSYMBADBROYDEN = S_(MATLMVMSYMBADBROYDEN) 97 LMVMDIAGBBROYDEN = S_(MATLMVMDIAGBROYDEN) 98 CONSTANTDIAGONAL = S_(MATCONSTANTDIAGONAL) 99 DIAGONAL = S_(MATDIAGONAL) 100 H2OPUS = S_(MATH2OPUS) 101 102 103class MatOption(object): 104 """Matrix option. 105 106 See Also 107 -------- 108 petsc.MatOption 109 110 """ 111 OPTION_MIN = MAT_OPTION_MIN 112 UNUSED_NONZERO_LOCATION_ERR = MAT_UNUSED_NONZERO_LOCATION_ERR 113 ROW_ORIENTED = MAT_ROW_ORIENTED 114 SYMMETRIC = MAT_SYMMETRIC 115 STRUCTURALLY_SYMMETRIC = MAT_STRUCTURALLY_SYMMETRIC 116 FORCE_DIAGONAL_ENTRIES = MAT_FORCE_DIAGONAL_ENTRIES 117 IGNORE_OFF_PROC_ENTRIES = MAT_IGNORE_OFF_PROC_ENTRIES 118 USE_HASH_TABLE = MAT_USE_HASH_TABLE 119 KEEP_NONZERO_PATTERN = MAT_KEEP_NONZERO_PATTERN 120 IGNORE_ZERO_ENTRIES = MAT_IGNORE_ZERO_ENTRIES 121 USE_INODES = MAT_USE_INODES 122 HERMITIAN = MAT_HERMITIAN 123 SYMMETRY_ETERNAL = MAT_SYMMETRY_ETERNAL 124 NEW_NONZERO_LOCATION_ERR = MAT_NEW_NONZERO_LOCATION_ERR 125 IGNORE_LOWER_TRIANGULAR = MAT_IGNORE_LOWER_TRIANGULAR 126 ERROR_LOWER_TRIANGULAR = MAT_ERROR_LOWER_TRIANGULAR 127 GETROW_UPPERTRIANGULAR = MAT_GETROW_UPPERTRIANGULAR 128 SPD = MAT_SPD 129 NO_OFF_PROC_ZERO_ROWS = MAT_NO_OFF_PROC_ZERO_ROWS 130 NO_OFF_PROC_ENTRIES = MAT_NO_OFF_PROC_ENTRIES 131 NEW_NONZERO_LOCATIONS = MAT_NEW_NONZERO_LOCATIONS 132 NEW_NONZERO_ALLOCATION_ERR = MAT_NEW_NONZERO_ALLOCATION_ERR 133 SUBSET_OFF_PROC_ENTRIES = MAT_SUBSET_OFF_PROC_ENTRIES 134 SUBMAT_SINGLEIS = MAT_SUBMAT_SINGLEIS 135 STRUCTURE_ONLY = MAT_STRUCTURE_ONLY 136 SORTED_FULL = MAT_SORTED_FULL 137 OPTION_MAX = MAT_OPTION_MAX 138 139 140class MatAssemblyType(object): 141 """Matrix assembly type. 142 143 See Also 144 -------- 145 petsc.MatAssemblyType 146 147 """ 148 # native 149 FINAL_ASSEMBLY = MAT_FINAL_ASSEMBLY 150 FLUSH_ASSEMBLY = MAT_FLUSH_ASSEMBLY 151 # aliases 152 FINAL = FINAL_ASSEMBLY 153 FLUSH = FLUSH_ASSEMBLY 154 155 156class MatInfoType(object): 157 """Matrix info type.""" 158 LOCAL = MAT_LOCAL 159 GLOBAL_MAX = MAT_GLOBAL_MAX 160 GLOBAL_SUM = MAT_GLOBAL_SUM 161 162 163class MatStructure(object): 164 """Matrix modification structure. 165 166 See Also 167 -------- 168 petsc.MatStructure 169 170 """ 171 # native 172 SAME_NONZERO_PATTERN = MAT_SAME_NONZERO_PATTERN 173 DIFFERENT_NONZERO_PATTERN = MAT_DIFFERENT_NONZERO_PATTERN 174 SUBSET_NONZERO_PATTERN = MAT_SUBSET_NONZERO_PATTERN 175 UNKNOWN_NONZERO_PATTERN = MAT_UNKNOWN_NONZERO_PATTERN 176 # aliases 177 SAME = SAME_NZ = SAME_NONZERO_PATTERN 178 SUBSET = SUBSET_NZ = SUBSET_NONZERO_PATTERN 179 DIFFERENT = DIFFERENT_NZ = DIFFERENT_NONZERO_PATTERN 180 UNKNOWN = UNKNOWN_NZ = UNKNOWN_NONZERO_PATTERN 181 182 183class MatDuplicateOption(object): 184 """Matrix duplicate option. 185 186 See Also 187 -------- 188 petsc.MatDuplicateOption 189 190 """ 191 DO_NOT_COPY_VALUES = MAT_DO_NOT_COPY_VALUES 192 COPY_VALUES = MAT_COPY_VALUES 193 SHARE_NONZERO_PATTERN = MAT_SHARE_NONZERO_PATTERN 194 195 196class MatOrderingType(object): 197 """Factored matrix ordering type. 198 199 See Also 200 -------- 201 petsc.MatOrderingType 202 203 """ 204 NATURAL = S_(MATORDERINGNATURAL) 205 ND = S_(MATORDERINGND) 206 OWD = S_(MATORDERING1WD) 207 RCM = S_(MATORDERINGRCM) 208 QMD = S_(MATORDERINGQMD) 209 ROWLENGTH = S_(MATORDERINGROWLENGTH) 210 WBM = S_(MATORDERINGWBM) 211 SPECTRAL = S_(MATORDERINGSPECTRAL) 212 AMD = S_(MATORDERINGAMD) 213 METISND = S_(MATORDERINGMETISND) 214 215 216class MatSolverType(object): 217 """Factored matrix solver type. 218 219 See Also 220 -------- 221 petsc.MatSolverType 222 223 """ 224 SUPERLU = S_(MATSOLVERSUPERLU) 225 SUPERLU_DIST = S_(MATSOLVERSUPERLU_DIST) 226 STRUMPACK = S_(MATSOLVERSTRUMPACK) 227 UMFPACK = S_(MATSOLVERUMFPACK) 228 CHOLMOD = S_(MATSOLVERCHOLMOD) 229 KLU = S_(MATSOLVERKLU) 230 ELEMENTAL = S_(MATSOLVERELEMENTAL) 231 SCALAPACK = S_(MATSOLVERSCALAPACK) 232 ESSL = S_(MATSOLVERESSL) 233 LUSOL = S_(MATSOLVERLUSOL) 234 MUMPS = S_(MATSOLVERMUMPS) 235 MKL_PARDISO = S_(MATSOLVERMKL_PARDISO) 236 MKL_CPARDISO = S_(MATSOLVERMKL_CPARDISO) 237 PASTIX = S_(MATSOLVERPASTIX) 238 MATLAB = S_(MATSOLVERMATLAB) 239 PETSC = S_(MATSOLVERPETSC) 240 BAS = S_(MATSOLVERBAS) 241 CUSPARSE = S_(MATSOLVERCUSPARSE) 242 CUDA = S_(MATSOLVERCUDA) 243 SPQR = S_(MATSOLVERSPQR) 244 245 246class MatFactorShiftType(object): 247 """Factored matrix shift type. 248 249 See Also 250 -------- 251 petsc.MatFactorShiftType 252 253 """ 254 # native 255 NONE = MAT_SHIFT_NONE 256 NONZERO = MAT_SHIFT_NONZERO 257 POSITIVE_DEFINITE = MAT_SHIFT_POSITIVE_DEFINITE 258 INBLOCKS = MAT_SHIFT_INBLOCKS 259 # aliases 260 NZ = MAT_SHIFT_NONZERO 261 PD = MAT_SHIFT_POSITIVE_DEFINITE 262 263 264class MatSORType(object): 265 """Matrix SOR type. 266 267 See Also 268 -------- 269 petsc.MatSORType 270 271 """ 272 FORWARD_SWEEP = SOR_FORWARD_SWEEP 273 BACKWARD_SWEEP = SOR_BACKWARD_SWEEP 274 SYMMETRY_SWEEP = SOR_SYMMETRIC_SWEEP 275 LOCAL_FORWARD_SWEEP = SOR_LOCAL_FORWARD_SWEEP 276 LOCAL_BACKWARD_SWEEP = SOR_LOCAL_BACKWARD_SWEEP 277 LOCAL_SYMMETRIC_SWEEP = SOR_LOCAL_SYMMETRIC_SWEEP 278 ZERO_INITIAL_GUESS = SOR_ZERO_INITIAL_GUESS 279 EISENSTAT = SOR_EISENSTAT 280 APPLY_UPPER = SOR_APPLY_UPPER 281 APPLY_LOWER = SOR_APPLY_LOWER 282 283 284@cython.internal 285cdef class MatStencil: 286 """Associate structured grid coordinates with matrix indices. 287 288 See Also 289 -------- 290 petsc.MatStencil 291 292 """ 293 294 cdef PetscMatStencil stencil 295 296 property i: 297 "First logical grid coordinate." 298 def __get__(self) -> int: 299 return toInt(self.stencil.i) 300 301 def __set__(self, value: int) -> None: 302 self.stencil.i = asInt(value) 303 304 property j: 305 "Second logical grid coordinate." 306 def __get__(self) -> int: 307 return toInt(self.stencil.j) 308 309 def __set__(self, value: int) -> None: 310 self.stencil.j = asInt(value) 311 312 property k: 313 "Third logical grid coordinate." 314 def __get__(self) -> int: 315 return toInt(self.stencil.k) 316 317 def __set__(self, value: int) -> None: 318 self.stencil.k = asInt(value) 319 320 property c: 321 "Field component." 322 def __get__(self) -> int: 323 return toInt(self.stencil.c) 324 325 def __set__(self, value: int) -> None: 326 self.stencil.c = asInt(value) 327 328 property index: 329 "Logical grid coordinates ``(i, j, k)``." 330 def __get__(self) -> tuple[int, int, int]: 331 cdef PetscMatStencil *s = &self.stencil 332 return toInt(s.i), toInt(s.j), toInt(s.k) 333 334 def __set__(self, value: Sequence[int]) -> None: 335 cdef PetscMatStencil *s = &self.stencil 336 s.i = s.j = s.k = 0 337 asDims(value, &s.i, &s.j, &s.k) 338 339 property field: 340 "Field component." 341 def __get__(self) -> int: 342 cdef PetscMatStencil *s = &self.stencil 343 return toInt(s.c) 344 345 def __set__(self, value: int) -> None: 346 cdef PetscMatStencil *s = &self.stencil 347 s.c = asInt(value) 348 349# -------------------------------------------------------------------- 350 351cdef class Mat(Object): 352 """Matrix object. 353 354 Mat is described in the `PETSc manual <petsc:manual/mat>`. 355 356 See Also 357 -------- 358 petsc.Mat 359 360 """ 361 362 Type = MatType 363 Option = MatOption 364 AssemblyType = MatAssemblyType 365 InfoType = MatInfoType 366 Structure = MatStructure 367 DuplicateOption = MatDuplicateOption 368 OrderingType = MatOrderingType 369 SolverType = MatSolverType 370 FactorShiftType = MatFactorShiftType 371 SORType = MatSORType 372 # 373 374 def __cinit__(self): 375 self.obj = <PetscObject*> &self.mat 376 self.mat = NULL 377 378 # unary operations 379 380 def __pos__(self): 381 return mat_pos(self) 382 383 def __neg__(self): 384 return mat_neg(self) 385 386 # inplace binary operations 387 388 def __iadd__(self, other): 389 return mat_iadd(self, other) 390 391 def __isub__(self, other): 392 return mat_isub(self, other) 393 394 def __imul__(self, other): 395 return mat_imul(self, other) 396 397 def __idiv__(self, other): 398 return mat_idiv(self, other) 399 400 def __itruediv__(self, other): 401 return mat_idiv(self, other) 402 403 # binary operations 404 405 def __add__(self, other): 406 return mat_add(self, other) 407 408 def __radd__(self, other): 409 return mat_radd(self, other) 410 411 def __sub__(self, other): 412 return mat_sub(self, other) 413 414 def __rsub__(self, other): 415 return mat_rsub(self, other) 416 417 def __mul__(self, other): 418 return mat_mul(self, other) 419 420 def __rmul__(self, other): 421 return mat_rmul(self, other) 422 423 def __div__(self, other): 424 return mat_div(self, other) 425 426 def __rdiv__(self, other): 427 return mat_rdiv(self, other) 428 429 def __truediv__(self, other): 430 return mat_div(self, other) 431 432 def __rtruediv__(self, other): 433 return mat_rdiv(self, other) 434 435 def __matmul__(self, other): 436 return mat_matmul(self, other) 437 438 # 439 440 def __getitem__(self, ij): 441 return mat_getitem(self, ij) 442 443 def __setitem__(self, ij, v): 444 mat_setitem(self, ij, v) 445 446 def __call__(self, x, y=None): 447 if y is None: 448 y = self.createVecLeft() 449 self.mult(x, y) 450 return y 451 # 452 453 def view(self, Viewer viewer=None) -> None: 454 """View the matrix. 455 456 Collective. 457 458 Parameters 459 ---------- 460 viewer 461 A `Viewer` instance or `None` for the default viewer. 462 463 Notes 464 ----- 465 Viewers with type `Viewer.Type.ASCII` are only recommended for small 466 matrices on small numbers of processes. Larger matrices should use a 467 binary format like `Viewer.Type.BINARY`. 468 469 See Also 470 -------- 471 load, Viewer, petsc.MatView 472 473 """ 474 cdef PetscViewer vwr = NULL 475 if viewer is not None: vwr = viewer.vwr 476 CHKERR(MatView(self.mat, vwr)) 477 478 def destroy(self) -> Self: 479 """Destroy the matrix. 480 481 Collective. 482 483 See Also 484 -------- 485 create, petsc.MatDestroy 486 487 """ 488 CHKERR(MatDestroy(&self.mat)) 489 return self 490 491 def create(self, comm: Comm | None = None) -> Self: 492 """Create the matrix. 493 494 Collective. 495 496 Once created, the user should call `setType` or 497 `setFromOptions` before using the matrix. Alternatively, specific 498 creation routines such as `createAIJ` or 499 `createBAIJ` can be used. 500 501 Parameters 502 ---------- 503 comm 504 MPI communicator, defaults to `Sys.getDefaultComm`. 505 506 See Also 507 -------- 508 destroy, petsc.MatCreate 509 510 """ 511 cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) 512 cdef PetscMat newmat = NULL 513 CHKERR(MatCreate(ccomm, &newmat)) 514 CHKERR(PetscCLEAR(self.obj)); self.mat = newmat 515 return self 516 517 def setType(self, mat_type: Type | str) -> None: 518 """Set the matrix type. 519 520 Collective. 521 522 Parameters 523 ---------- 524 mat_type 525 The matrix type. 526 527 See Also 528 -------- 529 create, getType, petsc.MatSetType 530 531 """ 532 cdef PetscMatType cval = NULL 533 mat_type = str2bytes(mat_type, &cval) 534 CHKERR(MatSetType(self.mat, cval)) 535 536 def setSizes( 537 self, 538 size: MatSizeSpec, 539 bsize: MatBlockSizeSpec | None = None) -> None: 540 """Set the local, global and block sizes. 541 542 Collective. 543 544 Parameters 545 ---------- 546 size 547 Matrix size. 548 bsize 549 Matrix block size. If `None`, a block size of ``1`` is set. 550 551 Examples 552 -------- 553 Create a `Mat` with ``n`` rows and columns and the same local and 554 global sizes. 555 556 >>> mat = PETSc.Mat().create() 557 >>> mat.setFromOptions() 558 >>> mat.setSizes(n) 559 560 Create a `Mat` with ``nr`` rows, ``nc`` columns and the same local and 561 global sizes. 562 563 >>> mat = PETSc.Mat().create() 564 >>> mat.setFromOptions() 565 >>> mat.setSizes([nr, nc]) 566 567 Create a `Mat` with ``nrl`` local rows, ``nrg`` global rows, ``ncl`` 568 local columns and ``ncg`` global columns. 569 570 >>> mat = PETSc.Mat().create() 571 >>> mat.setFromOptions() 572 >>> mat.setSizes([[nrl, nrg], [ncl, ncg]]) 573 574 See Also 575 -------- 576 setBlockSize, setBlockSizes, petsc.MatSetSizes, petsc.MatSetBlockSize 577 petsc.MatSetBlockSizes 578 579 """ 580 cdef PetscInt rbs = 0, cbs = 0, m = 0, n = 0, M = 0, N = 0 581 Mat_Sizes(size, bsize, &rbs, &cbs, &m, &n, &M, &N) 582 CHKERR(MatSetSizes(self.mat, m, n, M, N)) 583 if rbs != PETSC_DECIDE: 584 if cbs != PETSC_DECIDE: 585 CHKERR(MatSetBlockSizes(self.mat, rbs, cbs)) 586 else: 587 CHKERR(MatSetBlockSize(self.mat, rbs)) 588 589 def setBlockSize(self, bsize: int) -> None: 590 """Set the matrix block size (same for rows and columns). 591 592 Logically collective. 593 594 Parameters 595 ---------- 596 bsize 597 Block size. 598 599 See Also 600 -------- 601 setBlockSizes, setSizes, petsc.MatSetBlockSize 602 603 """ 604 cdef PetscInt bs = asInt(bsize) 605 CHKERR(MatSetBlockSize(self.mat, bs)) 606 607 def setBlockSizes(self, row_bsize: int, col_bsize: int) -> None: 608 """Set the row and column block sizes. 609 610 Logically collective. 611 612 Parameters 613 ---------- 614 row_bsize 615 Row block size. 616 col_bsize 617 Column block size. 618 619 See Also 620 -------- 621 setBlockSize, setSizes, petsc.MatSetBlockSizes 622 623 """ 624 cdef PetscInt rbs = asInt(row_bsize) 625 cdef PetscInt cbs = asInt(col_bsize) 626 CHKERR(MatSetBlockSizes(self.mat, rbs, cbs)) 627 628 def setVariableBlockSizes(self, blocks: Sequence[int]) -> None: 629 """Set diagonal point-blocks of the matrix. 630 631 Not collective. 632 633 See Also 634 -------- 635 setBlockSize, petsc.MatSetVariableBlockSizes 636 637 """ 638 cdef PetscInt nb=0, *b=NULL 639 iarray_i(blocks, &nb, &b) 640 CHKERR(MatSetVariableBlockSizes(self.mat, nb, b)) 641 642 def setVecType(self, vec_type: Vec.Type | str) -> None: 643 """Set the vector type. 644 645 Collective. 646 647 Parameters 648 ---------- 649 vec_type 650 Vector type used when creating vectors with `createVecs`. 651 652 See Also 653 -------- 654 getVecType, petsc.MatSetVecType 655 656 """ 657 cdef PetscVecType cval = NULL 658 vec_type = str2bytes(vec_type, &cval) 659 CHKERR(MatSetVecType(self.mat, cval)) 660 661 def getVecType(self) -> str: 662 """Return the vector type used by the matrix. 663 664 Not collective. 665 666 See Also 667 -------- 668 setVecType, petsc.MatGetVecType 669 670 """ 671 cdef PetscVecType cval = NULL 672 CHKERR(MatGetVecType(self.mat, &cval)) 673 return bytes2str(cval) 674 675 def setNestVecType(self, vec_type: Vec.Type | str) -> None: 676 """Set the vector type for a `Type.NEST` matrix. 677 678 Collective. 679 680 Parameters 681 ---------- 682 vec_type 683 Vector type used when creating vectors with `createVecs`. 684 685 See Also 686 -------- 687 getVecType, petsc.MatNestSetVecType 688 689 """ 690 cdef PetscVecType cval = NULL 691 vec_type = str2bytes(vec_type, &cval) 692 CHKERR(MatNestSetVecType(self.mat, cval)) 693 694 # 695 696 def createAIJ( 697 self, 698 size: MatSizeSpec, 699 bsize: MatBlockSizeSpec | None = None, 700 nnz: NNZSpec | None = None, 701 csr: CSRIndicesSpec | None = None, 702 comm: Comm | None = None) -> Self: 703 """Create a sparse `Type.AIJ` matrix, optionally preallocating. 704 705 Collective. 706 707 To preallocate the matrix the user can either pass ``nnz`` or ``csr`` 708 describing the sparsity. If neither is set then preallocation will not 709 occur. Consult the `PETSc manual <petsc:sec_matsparse>` for 710 more information. 711 712 Parameters 713 ---------- 714 size 715 Matrix size. 716 bsize 717 Matrix block size. If `None`, a block size of ``1`` is set. 718 nnz 719 Optional non-zeros preallocation pattern. 720 csr 721 Optional compressed sparse row layout information. 722 If provided, it takes precedence on ``nnz``. 723 comm 724 MPI communicator, defaults to `Sys.getDefaultComm`. 725 726 See Also 727 -------- 728 setSizes, createBAIJ, petsc.MATAIJ, petsc.MATSEQAIJ, petsc.MATMPIAIJ 729 petsc.MatCreateAIJ, petsc.MatSeqAIJSetPreallocation 730 petsc.MatSeqAIJSetPreallocationCSR 731 732 """ 733 # create matrix 734 cdef PetscMat newmat = NULL 735 Mat_Create(MATAIJ, comm, size, bsize, &newmat) 736 CHKERR(PetscCLEAR(self.obj)); self.mat = newmat 737 # preallocate matrix 738 Mat_AllocAIJ(self.mat, nnz, csr) 739 return self 740 741 def createBAIJ( 742 self, 743 size: MatSizeSpec, 744 bsize: MatBlockSizeSpec, 745 nnz: NNZSpec | None = None, 746 csr: CSRIndicesSpec | None = None, 747 comm: Comm | None = None) -> Self: 748 """Create a sparse blocked `Type.BAIJ` matrix, optionally preallocating. 749 750 Collective. 751 752 To preallocate the matrix the user can either pass ``nnz`` or ``csr`` 753 describing the sparsity. If neither is set then preallocation will not 754 occur. Consult the `PETSc manual <petsc:sec_matsparse>` for 755 more information. 756 757 Parameters 758 ---------- 759 size 760 Matrix size. 761 bsize 762 Matrix block size. 763 nnz 764 Optional non-zeros preallocation pattern for block rows. 765 csr 766 Optional block-compressed sparse row layout information. 767 If provided, it takes precedence on ``nnz``. 768 comm 769 MPI communicator, defaults to `Sys.getDefaultComm`. 770 771 See Also 772 -------- 773 setSizes, createAIJ, petsc.MATBAIJ, petsc.MATSEQBAIJ 774 petsc.MATMPIBAIJ, petsc.MatCreateBAIJ 775 776 """ 777 # create matrix 778 cdef PetscMat newmat = NULL 779 Mat_Create(MATBAIJ, comm, size, bsize, &newmat) 780 CHKERR(PetscCLEAR(self.obj)); self.mat = newmat 781 # preallocate matrix 782 Mat_AllocAIJ(self.mat, nnz, csr) 783 return self 784 785 def createSBAIJ( 786 self, 787 size: MatSizeSpec, 788 bsize: MatBlockSizeSpec, 789 nnz: NNZSpec | None = None, 790 csr: CSRIndicesSpec | None = None, 791 comm: Comm | None = None) -> Self: 792 """Create a sparse `Type.SBAIJ` matrix in symmetric block format. 793 794 Collective. 795 796 To preallocate the matrix the user can either pass ``nnz`` or ``csr`` 797 describing the sparsity. If neither is set then preallocation will not 798 occur. Consult the `PETSc manual <petsc:sec_matsparse>` for 799 more information. 800 801 Parameters 802 ---------- 803 size 804 Matrix size. 805 bsize 806 Matrix block size. 807 nnz 808 Optional upper-triangular (including diagonal) 809 non-zeros preallocation pattern for block rows. 810 csr 811 Optional block-compressed sparse row layout information. 812 If provided, it takes precedence on ``nnz``. 813 comm 814 MPI communicator, defaults to `Sys.getDefaultComm`. 815 816 See Also 817 -------- 818 createAIJ, createBAIJ, petsc.MatCreateSBAIJ 819 820 """ 821 # create matrix 822 cdef PetscMat newmat = NULL 823 Mat_Create(MATSBAIJ, comm, size, bsize, &newmat) 824 CHKERR(PetscCLEAR(self.obj)); self.mat = newmat 825 # preallocate matrix 826 Mat_AllocAIJ(self.mat, nnz, csr) 827 return self 828 829 def createAIJCRL( 830 self, 831 size: MatSizeSpec, 832 bsize: MatBlockSizeSpec | None = None, 833 nnz: NNZSpec | None = None, 834 csr: CSRIndicesSpec | None = None, 835 comm: Comm | None = None) -> Self: 836 """Create a sparse `Type.AIJCRL` matrix. 837 838 Collective. 839 840 This is similar to `Type.AIJ` matrices but stores some additional 841 information that improves vectorization for the matrix-vector product. 842 843 To preallocate the matrix the user can either pass ``nnz`` or ``csr`` 844 describing the sparsity. If neither is set then preallocation will not 845 occur. Consult the `PETSc manual <petsc:sec_matsparse>` for 846 more information. 847 848 Parameters 849 ---------- 850 size 851 Matrix size. 852 bsize 853 Matrix block size. If `None`, a block size of ``1`` is set. 854 nnz 855 Optional non-zeros preallocation pattern. 856 csr 857 Optional compressed sparse row layout information. 858 If provided, it takes precedence on ``nnz``. 859 comm 860 MPI communicator, defaults to `Sys.getDefaultComm`. 861 862 See Also 863 -------- 864 createAIJ, createBAIJ, petsc.MatCreateSeqAIJCRL 865 petsc.MatCreateMPIAIJCRL 866 867 """ 868 # create matrix 869 cdef PetscMat newmat = NULL 870 Mat_Create(MATAIJCRL, comm, size, bsize, &newmat) 871 CHKERR(PetscCLEAR(self.obj)); self.mat = newmat 872 # preallocate matrix 873 Mat_AllocAIJ(self.mat, nnz, csr) 874 return self 875 876 def setPreallocationNNZ(self, nnz: NNZSpec) -> Self: 877 """Preallocate memory for the matrix with a non-zero pattern. 878 879 Collective. 880 881 Correct preallocation can result in a dramatic reduction in matrix 882 assembly time. 883 884 Parameters 885 ---------- 886 nnz 887 The number of non-zeros per row for the local portion of the matrix, 888 or a 2-tuple for the on-process and off-process part of the matrix. 889 890 See Also 891 -------- 892 setPreallocationCSR, createAIJ, petsc.MatSeqAIJSetPreallocation 893 petsc.MatMPIAIJSetPreallocation 894 895 """ 896 cdef PetscBool done = PETSC_FALSE 897 CHKERR(MatIsPreallocated(self.mat, &done)) 898 # if done: raise Error(PETSC_ERR_ORDER) 899 Mat_AllocAIJ_NNZ(self.mat, nnz) 900 return self 901 902 def setPreallocationCOO(self, coo_i: Sequence[int], coo_j: Sequence[int]) -> Self: 903 """Set preallocation using coordinate format with global indices. 904 905 Collective. 906 907 Parameters 908 ---------- 909 coo_i 910 Row indices in COO format. 911 coo_j 912 Column indices in COO format. 913 914 See Also 915 -------- 916 setValuesCOO, setPreallocationNNZ, setPreallocationCSR 917 petsc.MatSetPreallocationCOO 918 919 """ 920 cdef PetscInt ncoo_i = 0, ncoo_j = 0 921 cdef PetscInt *ccoo_i = NULL, *ccoo_j = NULL 922 cdef PetscCount ncoo = 0 923 924 coo_i = iarray_i(coo_i, &ncoo_i, &ccoo_i) 925 coo_j = iarray_i(coo_j, &ncoo_j, &ccoo_j) 926 927 if ncoo_i != ncoo_j: 928 raise ValueError("coo_i and coo_j must have the same length") 929 930 ncoo = <PetscCount> ncoo_i 931 CHKERR(MatSetPreallocationCOO(self.mat, ncoo, ccoo_i, ccoo_j)) 932 return self 933 934 def setPreallocationCOOLocal(self, coo_i: Sequence[int], coo_j: Sequence[int]) -> Self: 935 """Set preallocation using coordinate format with local indices. 936 937 Collective. 938 939 Parameters 940 ---------- 941 coo_i 942 Row indices in COO format. 943 coo_j 944 Column indices in COO format. 945 946 See Also 947 -------- 948 setPreallocationCOO, setValuesCOO, setLGMap 949 petsc.MatSetPreallocationCOOLocal, petsc.MatSetPreallocationCOOLocal 950 951 """ 952 cdef PetscInt ncoo_i = 0, ncoo_j = 0 953 cdef PetscInt *ccoo_i = NULL, *ccoo_j = NULL 954 cdef PetscCount ncoo = 0 955 956 coo_i = iarray_i(coo_i, &ncoo_i, &ccoo_i) 957 coo_j = iarray_i(coo_j, &ncoo_j, &ccoo_j) 958 959 if ncoo_i != ncoo_j: 960 raise ValueError("coo_i and coo_j must have the same length") 961 962 ncoo = <PetscCount> ncoo_i 963 CHKERR(MatSetPreallocationCOOLocal(self.mat, ncoo, ccoo_i, ccoo_j)) 964 return self 965 966 def setPreallocationCSR(self, csr: CSRIndicesSpec) -> Self: 967 """Preallocate memory for the matrix with a CSR layout. 968 969 Collective. 970 971 Correct preallocation can result in a dramatic reduction in matrix 972 assembly time. 973 974 Parameters 975 ---------- 976 csr 977 Local matrix data in compressed sparse row layout format. 978 979 Notes 980 ----- 981 Must use the block-compressed form with `Type.BAIJ` and `Type.SBAIJ`. 982 983 See Also 984 -------- 985 setPreallocationNNZ, createAIJ, createBAIJ, createSBAIJ 986 petsc.MatSeqAIJSetPreallocationCSR 987 petsc.MatMPIAIJSetPreallocationCSR 988 petsc.MatSeqBAIJSetPreallocationCSR 989 petsc.MatMPIBAIJSetPreallocationCSR 990 petsc.MatSeqSBAIJSetPreallocationCSR 991 petsc.MatMPISBAIJSetPreallocationCSR 992 993 """ 994 cdef PetscBool done = PETSC_FALSE 995 CHKERR(MatIsPreallocated(self.mat, &done)) 996 # if done: raise Error(PETSC_ERR_ORDER) 997 Mat_AllocAIJ_CSR(self.mat, csr) 998 return self 999 1000 def preallocatorPreallocate(self, Mat A, fill: bool = True) -> None: 1001 """Preallocate memory for a matrix using a preallocator matrix. 1002 1003 Collective. 1004 1005 The current matrix (``self``) must be of type `Type.PREALLOCATOR`. 1006 1007 Parameters 1008 ---------- 1009 A 1010 The matrix to be preallocated. 1011 fill 1012 Flag indicating whether or not to insert zeros into 1013 the newly allocated matrix, defaults to `True`. 1014 1015 See Also 1016 -------- 1017 petsc.MatPreallocatorPreallocate 1018 1019 """ 1020 cdef PetscBool cfill = asBool(fill) 1021 CHKERR(MatPreallocatorPreallocate(self.mat, cfill, A.mat)) 1022 1023 def createAIJWithArrays( 1024 self, 1025 size: MatSizeSpec, 1026 csr: CSRSpec | tuple[CSRSpec, CSRSpec], 1027 bsize: MatBlockSizeSpec | None = None, 1028 comm: Comm | None = None) -> Self: 1029 """Create a sparse `Type.AIJ` matrix with data in CSR format. 1030 1031 Collective. 1032 1033 Parameters 1034 ---------- 1035 size 1036 Matrix size. 1037 csr 1038 Local matrix data in compressed sparse row format. 1039 bsize 1040 Matrix block size. If `None`, a block size of ``1`` is set. 1041 comm 1042 MPI communicator, defaults to `Sys.getDefaultComm`. 1043 1044 Notes 1045 ----- 1046 For `Type.SEQAIJ` matrices, the ``csr`` data is not copied. 1047 For `Type.MPIAIJ` matrices, the ``csr`` data is not copied only 1048 in the case it represents on-process and off-process information. 1049 1050 See Also 1051 -------- 1052 createAIJ, petsc.MatCreateSeqAIJWithArrays 1053 petsc.MatCreateMPIAIJWithArrays, petsc.MatCreateMPIAIJWithSplitArrays 1054 1055 """ 1056 # communicator 1057 cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) 1058 # sizes and block sizes 1059 cdef PetscInt rbs = 0, cbs = 0, m = 0, n = 0, M = 0, N = 0 1060 Mat_Sizes(size, bsize, &rbs, &cbs, &m, &n, &M, &N) 1061 if rbs == PETSC_DECIDE: rbs = 1 1062 if cbs == PETSC_DECIDE: cbs = rbs 1063 Sys_Layout(ccomm, rbs, &m, &M) 1064 Sys_Layout(ccomm, cbs, &n, &N) 1065 # unpack CSR argument 1066 cdef object pi, pj, pv, poi, poj, pov 1067 try: 1068 (pi, pj, pv), (poi, poj, pov) = csr 1069 except (TypeError, ValueError): 1070 pi, pj, pv = csr 1071 poi = poj = pov = None 1072 # rows, cols, and values 1073 cdef PetscInt ni=0, noi=0, *i=NULL, *oi=NULL 1074 cdef PetscInt nj=0, noj=0, *j=NULL, *oj=NULL 1075 pi = iarray_i(pi, &ni, &i) # Row pointers (diagonal) 1076 pj = iarray_i(pj, &nj, &j) # Column indices (diagonal) 1077 if ni != m+1: raise ValueError( 1078 "A matrix with %d rows requires a row pointer of length %d (given: %d)" % 1079 (toInt(m), toInt(m+1), toInt(ni))) 1080 if poi is not None and poj is not None: 1081 poi = iarray_i(poi, &noi, &oi) # Row pointers (off-diagonal) 1082 poj = iarray_i(poj, &noj, &oj) # Column indices (off-diagonal) 1083 cdef PetscInt nv=0, nov=0 1084 cdef PetscScalar *v=NULL, *ov=NULL 1085 pv = iarray_s(pv, &nv, &v) # Non-zero values (diagonal) 1086 if nj != nv: raise ValueError( 1087 "Given %d column indices but %d non-zero values" % 1088 (toInt(nj), toInt(nv))) 1089 if pov is not None: 1090 pov = iarray_s(pov, &nov, &ov) # Non-zero values (off-diagonal) 1091 # create matrix 1092 cdef PetscMat newmat = NULL 1093 if comm_size(ccomm) == 1: 1094 CHKERR(MatCreateSeqAIJWithArrays( 1095 ccomm, m, n, i, j, v, &newmat)) 1096 csr = (pi, pj, pv) 1097 else: 1098 # if off-diagonal components are provided then SplitArrays can be 1099 # used (and not cause a copy). 1100 if oi != NULL and oj != NULL and ov != NULL: 1101 CHKERR(MatCreateMPIAIJWithSplitArrays( 1102 ccomm, m, n, M, N, i, j, v, oi, oj, ov, &newmat)) 1103 csr = ((pi, pj, pv), (poi, poj, pov)) 1104 else: 1105 CHKERR(MatCreateMPIAIJWithArrays( 1106 ccomm, m, n, M, N, i, j, v, &newmat)) 1107 csr = None 1108 CHKERR(PetscCLEAR(self.obj)); self.mat = newmat 1109 self.set_attr('__csr__', csr) 1110 return self 1111 1112 # 1113 1114 def createDense( 1115 self, 1116 size: MatSizeSpec, 1117 bsize: MatBlockSizeSpec | None = None, 1118 array: Sequence[Scalar] | None = None, 1119 comm: Comm | None = None) -> Self: 1120 """Create a `Type.DENSE` matrix. 1121 1122 Collective. 1123 1124 Parameters 1125 ---------- 1126 size 1127 Matrix size. 1128 bsize 1129 Matrix block size. If `None`, a block size of ``1`` is set. 1130 array 1131 Optional matrix data. If `None`, memory is internally allocated. 1132 comm 1133 MPI communicator, defaults to `Sys.getDefaultComm`. 1134 1135 See Also 1136 -------- 1137 createDenseCUDA, petsc.MATDENSE, petsc.MatCreateDense 1138 1139 """ 1140 # create matrix 1141 cdef PetscMat newmat = NULL 1142 Mat_Create(MATDENSE, comm, size, bsize, &newmat) 1143 CHKERR(PetscCLEAR(self.obj)); self.mat = newmat 1144 # preallocate matrix 1145 if array is not None: 1146 array = Mat_AllocDense(self.mat, array) 1147 self.set_attr('__array__', array) 1148 return self 1149 1150 def createDenseCUDA( 1151 self, 1152 size: MatSizeSpec, 1153 bsize: MatBlockSizeSpec | None = None, 1154 array: Sequence[Scalar] | None = None, 1155 cudahandle: int | None = None, 1156 comm: Comm | None = None) -> Self: 1157 """Create a `Type.DENSECUDA` matrix with optional host and device data. 1158 1159 Collective. 1160 1161 Parameters 1162 ---------- 1163 size 1164 Matrix size. 1165 bsize 1166 Matrix block size. If `None`, a block size of ``1`` is set. 1167 array 1168 Host data. Will be lazily allocated if `None`. 1169 cudahandle 1170 Address of the array on the GPU. Will be lazily allocated if 1171 `None`. If ``cudahandle`` is provided, ``array`` will be 1172 ignored. 1173 comm 1174 MPI communicator, defaults to `Sys.getDefaultComm`. 1175 1176 See Also 1177 -------- 1178 createDense, petsc.MatCreateDenseCUDA 1179 1180 """ 1181 # create matrix 1182 cdef PetscMat newmat = NULL 1183 # communicator 1184 cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) 1185 # sizes and block sizes 1186 cdef PetscInt rbs = 0, cbs = 0, m = 0, n = 0, M = 0, N = 0 1187 1188 # FIXME handle the case of array not None? 1189 if cudahandle is not None: 1190 Mat_Sizes(size, None, &rbs, &cbs, &m, &n, &M, &N) 1191 if rbs == PETSC_DECIDE: rbs = 1 1192 if cbs == PETSC_DECIDE: cbs = rbs 1193 Sys_Layout(ccomm, rbs, &m, &M) 1194 Sys_Layout(ccomm, cbs, &n, &N) 1195 # create matrix and set sizes 1196 CHKERR(MatCreateDenseCUDA(ccomm, m, n, M, N, <PetscScalar*>(<Py_uintptr_t>cudahandle), &newmat)) 1197 # Does block size make sense for MATDENSE? 1198 CHKERR(MatSetBlockSizes(newmat, rbs, cbs)) 1199 else: 1200 Mat_Create(MATDENSECUDA, comm, size, bsize, &newmat) 1201 if array is not None: 1202 array = Mat_AllocDense(self.mat, array) 1203 self.set_attr('__array__', array) 1204 CHKERR(PetscCLEAR(self.obj)); self.mat = newmat 1205 return self 1206 1207 def setPreallocationDense(self, array: Sequence[Scalar]) -> Self: 1208 """Set the array used for storing matrix elements for a dense matrix. 1209 1210 Collective. 1211 1212 Parameters 1213 ---------- 1214 array 1215 Array that will be used to store matrix data. 1216 1217 See Also 1218 -------- 1219 petsc.MatSeqDenseSetPreallocation, petsc.MatMPIDenseSetPreallocation 1220 1221 """ 1222 cdef PetscBool done = PETSC_FALSE 1223 CHKERR(MatIsPreallocated(self.mat, &done)) 1224 # if done: raise Error(PETSC_ERR_ORDER) 1225 array = Mat_AllocDense(self.mat, array) 1226 self.set_attr('__array__', array) 1227 return self 1228 1229 # 1230 1231 def createScatter(self, Scatter scatter, comm: Comm | None = None) -> Self: 1232 """Create a `Type.SCATTER` matrix from a vector scatter. 1233 1234 Collective. 1235 1236 Parameters 1237 ---------- 1238 scatter 1239 Vector scatter. 1240 comm 1241 MPI communicator, defaults to `Sys.getDefaultComm`. 1242 1243 See Also 1244 -------- 1245 petsc.MATSCATTER, petsc.MatCreateScatter 1246 1247 """ 1248 if comm is None: comm = scatter.getComm() 1249 cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) 1250 cdef PetscMat newmat = NULL 1251 CHKERR(MatCreateScatter(ccomm, scatter.sct, &newmat)) 1252 CHKERR(PetscCLEAR(self.obj)); self.mat = newmat 1253 return self 1254 1255 def createNormal(self, Mat mat) -> Self: 1256 """Create a `Type.NORMAL` matrix representing AᵀA. 1257 1258 Collective. 1259 1260 Parameters 1261 ---------- 1262 mat 1263 The (possibly rectangular) matrix A. 1264 1265 Notes 1266 ----- 1267 The product AᵀA is never actually formed. Instead A and Aᵀ are used 1268 during `mult` and various other matrix operations. 1269 1270 See Also 1271 -------- 1272 petsc.MATNORMAL, petsc.MatCreateNormal 1273 1274 """ 1275 cdef PetscMat newmat = NULL 1276 CHKERR(MatCreateNormal(mat.mat, &newmat)) 1277 CHKERR(PetscCLEAR(self.obj)); self.mat = newmat 1278 return self 1279 1280 def createTranspose(self, Mat mat) -> Self: 1281 """Create a `Type.TRANSPOSE` matrix that behaves like Aᵀ. 1282 1283 Collective. 1284 1285 Parameters 1286 ---------- 1287 mat 1288 Matrix A to represent the transpose of. 1289 1290 Notes 1291 ----- 1292 The transpose is never actually formed. Instead `multTranspose` is 1293 called whenever the matrix-vector product is computed. 1294 1295 See Also 1296 -------- 1297 createNormal, petsc.MatCreateTranspose 1298 1299 """ 1300 cdef PetscMat newmat = NULL 1301 CHKERR(MatCreateTranspose(mat.mat, &newmat)) 1302 CHKERR(PetscCLEAR(self.obj)); self.mat = newmat 1303 return self 1304 1305 def getTransposeMat(self) -> Mat: 1306 """Return the internal matrix of a `Type.TRANSPOSE` matrix. 1307 1308 Not collective. 1309 1310 Parameters 1311 ---------- 1312 mat 1313 Matrix A of type `Type.TRANSPOSE`. 1314 1315 See Also 1316 -------- 1317 petsc.MatTransposeGetMat 1318 1319 """ 1320 cdef Mat mat = type(self)() 1321 CHKERR(MatTransposeGetMat(self.mat, &mat.mat)) 1322 CHKERR(PetscINCREF(mat.obj)) 1323 return mat 1324 1325 def createNormalHermitian(self, Mat mat) -> Self: 1326 """Create a `Type.NORMALHERMITIAN` matrix representing (A*)ᵀA. 1327 1328 Collective. 1329 1330 Parameters 1331 ---------- 1332 mat 1333 The (possibly rectangular) matrix A. 1334 1335 Notes 1336 ----- 1337 The product (A*)ᵀA is never actually formed. 1338 1339 See Also 1340 -------- 1341 createHermitianTranspose, petsc.MATNORMAL, petsc.MATNORMALHERMITIAN 1342 petsc.MatCreateNormalHermitian 1343 1344 """ 1345 cdef PetscMat newmat = NULL 1346 CHKERR(MatCreateNormalHermitian(mat.mat, &newmat)) 1347 CHKERR(PetscCLEAR(self.obj)); self.mat = newmat 1348 return self 1349 1350 def createHermitianTranspose(self, Mat mat) -> Self: 1351 """Create a `Type.HERMITIANTRANSPOSE` matrix that behaves like (A*)ᵀ. 1352 1353 Collective. 1354 1355 Parameters 1356 ---------- 1357 mat 1358 Matrix A to represent the Hermitian transpose of. 1359 1360 Notes 1361 ----- 1362 The Hermitian transpose is never actually formed. 1363 1364 See Also 1365 -------- 1366 createNormal, createNormalHermitian 1367 petsc.MATHERMITIANTRANSPOSEVIRTUAL, petsc.MatCreateHermitianTranspose 1368 1369 """ 1370 cdef PetscMat newmat = NULL 1371 CHKERR(MatCreateHermitianTranspose(mat.mat, &newmat)) 1372 CHKERR(PetscCLEAR(self.obj)); self.mat = newmat 1373 return self 1374 1375 def createLRC( 1376 self, 1377 Mat A or None: Mat | None, 1378 Mat U, 1379 Vec c or None: Vec | None, 1380 Mat V or None: Mat | None) -> Self: 1381 """Create a low-rank correction `Type.LRC` matrix representing A + UCVᵀ. 1382 1383 Collective. 1384 1385 Parameters 1386 ---------- 1387 A 1388 Sparse matrix, can be `None`. 1389 U 1390 Dense rectangular matrix. 1391 c 1392 Vector containing the diagonal of ``C``, can be `None`. 1393 V 1394 Dense rectangular matrix, can be set to ``U`` or 'None'. 1395 1396 Notes 1397 ----- 1398 The matrix A + UCVᵀ is never actually formed. 1399 1400 C is a diagonal matrix (represented as a vector) of order k, where k 1401 is the number of columns of both ``U`` and ``V``. 1402 1403 If A is `None` then the new object behaves like a low-rank matrix UCVᵀ. 1404 1405 Use the same matrix for ``V`` and ``U`` (or ``V=None``) for a symmetric 1406 low-rank correction, A + UCUᵀ. 1407 1408 If ``c`` is `None` then the low-rank correction is just U*Vᵀ. If a 1409 sequential ``c`` vector is used for a parallel matrix, PETSc assumes 1410 that the values of the vector are consistently set across processors. 1411 1412 See Also 1413 -------- 1414 petsc.MATLRC, petsc.MatCreateLRC 1415 1416 """ 1417 cdef PetscMat Amat = NULL 1418 cdef PetscMat Umat = U.mat 1419 cdef PetscVec cvec = NULL 1420 cdef PetscMat Vmat = NULL 1421 cdef PetscMat newmat = NULL 1422 if A is not None: Amat = A.mat 1423 if c is not None: cvec = c.vec 1424 if V is not None: Vmat = V.mat 1425 CHKERR(MatCreateLRC(Amat, Umat, cvec, Vmat, &newmat)) 1426 CHKERR(PetscCLEAR(self.obj)); self.mat = newmat 1427 return self 1428 1429 def createSubMatrixVirtual(self, Mat A, IS isrow, IS iscol=None) -> Self: 1430 """Create a `Type.SUBMATRIX` matrix that acts as a submatrix. 1431 1432 Collective. 1433 1434 Parameters 1435 ---------- 1436 A 1437 Matrix to extract submatrix from. 1438 isrow 1439 Rows present in the submatrix. 1440 iscol 1441 Columns present in the submatrix, defaults to ``isrow``. 1442 1443 See Also 1444 -------- 1445 petsc.MatCreateSubMatrixVirtual 1446 1447 """ 1448 if iscol is None: iscol = isrow 1449 cdef PetscMat newmat = NULL 1450 CHKERR(MatCreateSubMatrixVirtual(A.mat, isrow.iset, iscol.iset, &newmat)) 1451 CHKERR(PetscCLEAR(self.obj)); self.mat = newmat 1452 return self 1453 1454 def createNest( 1455 self, 1456 mats: Sequence[Sequence[Mat]], 1457 isrows: Sequence[IS] | None = None, 1458 iscols: Sequence[IS] | None = None, 1459 comm: Comm | None = None) -> Self: 1460 """Create a `Type.NEST` matrix containing multiple submatrices. 1461 1462 Collective. 1463 1464 Parameters 1465 ---------- 1466 mats 1467 Iterable of matrix block rows with size ``len(isrows)``. 1468 Each matrix block row must be of size ``len(iscols)``. 1469 Empty submatrices can be set with `None`. 1470 isrows 1471 Index set for each nested row block, defaults to contiguous 1472 ordering. 1473 iscols 1474 Index set for each nested column block, defaults to contiguous 1475 ordering. 1476 comm 1477 MPI communicator, defaults to `Sys.getDefaultComm`. 1478 1479 See Also 1480 -------- 1481 petsc.MatCreateNest, petsc.MATNEST 1482 1483 """ 1484 cdef object mat 1485 mats = [list(mat) for mat in mats] 1486 if isrows: 1487 isrows = list(isrows) 1488 assert len(isrows) == len(mats) 1489 else: 1490 isrows = None 1491 if iscols: 1492 iscols = list(iscols) 1493 assert len(iscols) == len(mats[0]) 1494 else: 1495 iscols = None 1496 cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) 1497 cdef Py_ssize_t i, mr = len(mats) 1498 cdef Py_ssize_t j, mc = len(mats[0]) 1499 cdef PetscInt nr = <PetscInt>mr 1500 cdef PetscInt nc = <PetscInt>mc 1501 cdef PetscMat *cmats = NULL 1502 cdef PetscIS *cisrows = NULL 1503 cdef PetscIS *ciscols = NULL 1504 cdef object unused1, unused2, unused3 1505 unused1 = oarray_p(empty_p(nr*nc), NULL, <void**>&cmats) 1506 for i from 0 <= i < mr: 1507 for j from 0 <= j < mc: 1508 mat = mats[i][j] 1509 cmats[i*mc+j] = (<Mat?>mat).mat if mat is not None else NULL 1510 if isrows is not None: 1511 unused2 = oarray_p(empty_p(nr), NULL, <void**>&cisrows) 1512 for i from 0 <= i < mr: cisrows[i] = (<IS?>isrows[i]).iset 1513 if iscols is not None: 1514 unused3 = oarray_p(empty_p(nc), NULL, <void**>&ciscols) 1515 for j from 0 <= j < mc: ciscols[j] = (<IS?>iscols[j]).iset 1516 cdef PetscMat newmat = NULL 1517 CHKERR(MatCreateNest(ccomm, nr, cisrows, nc, ciscols, cmats, &newmat)) 1518 CHKERR(PetscCLEAR(self.obj)); self.mat = newmat 1519 return self 1520 1521 def createH2OpusFromMat( 1522 self, 1523 Mat A, 1524 coordinates: Sequence[Scalar] | None = None, 1525 dist: bool | None = None, 1526 eta: float | None = None, 1527 leafsize: int | None = None, 1528 maxrank: int | None = None, 1529 bs: int | None = None, 1530 rtol: float | None = None) -> Self: 1531 """Create a hierarchical `Type.H2OPUS` matrix sampling from a provided operator. 1532 1533 Collective. 1534 1535 Parameters 1536 ---------- 1537 A 1538 Matrix to be sampled. 1539 coordinates 1540 Coordinates of the points. 1541 dist 1542 Whether or not coordinates are distributed, defaults to `False`. 1543 eta 1544 Admissibility condition tolerance, defaults to `DECIDE`. 1545 leafsize 1546 Leaf size in cluster tree, defaults to `DECIDE`. 1547 maxrank 1548 Maximum rank permitted, defaults to `DECIDE`. 1549 bs 1550 Maximum number of samples to take concurrently, defaults to 1551 `DECIDE`. 1552 rtol 1553 Relative tolerance for construction, defaults to `DECIDE`. 1554 1555 Notes 1556 ----- 1557 See `petsc.MatCreateH2OpusFromMat` for the appropriate database 1558 options. 1559 1560 See Also 1561 -------- 1562 petsc_options, petsc.MatCreateH2OpusFromMat 1563 1564 """ 1565 cdef PetscInt cdim = 1 1566 cdef PetscReal *coords = NULL 1567 cdef PetscBool cdist = PETSC_FALSE 1568 cdef PetscReal peta = PETSC_DECIDE 1569 cdef PetscInt lsize = PETSC_DECIDE 1570 cdef PetscInt maxr = PETSC_DECIDE 1571 cdef PetscInt pbs = PETSC_DECIDE 1572 cdef PetscReal tol = PETSC_DECIDE 1573 cdef ndarray xyz 1574 cdef PetscInt nvtx 1575 cdef PetscInt rl = 0, cl = 0 1576 if dist is not None: cdist = asBool(dist) 1577 if eta is not None: peta = asReal(eta) 1578 if leafsize is not None: lsize = asInt(leafsize) 1579 if maxrank is not None: maxr = asInt(maxrank) 1580 if bs is not None: pbs = asInt(bs) 1581 if rtol is not None: tol = asReal(rtol) 1582 1583 if coordinates is not None: 1584 xyz = iarray(coordinates, NPY_PETSC_REAL) 1585 if PyArray_ISFORTRAN(xyz): xyz = PyArray_Copy(xyz) 1586 if PyArray_NDIM(xyz) != 2: raise ValueError( 1587 ("coordinates must have two dimensions: " 1588 "coordinates.ndim=%d") % (PyArray_NDIM(xyz))) 1589 nvtx = <PetscInt> PyArray_DIM(xyz, 0) 1590 CHKERR(MatGetLocalSize(A.mat, &rl, &cl)) 1591 if cl != rl: raise ValueError("Not for rectangular matrices") 1592 if nvtx < rl: raise ValueError( 1593 ("coordinates size must be at least %d" % rl)) 1594 cdim = <PetscInt> PyArray_DIM(xyz, 1) 1595 coords = <PetscReal*> PyArray_DATA(xyz) 1596 1597 cdef PetscMat newmat = NULL 1598 CHKERR(MatCreateH2OpusFromMat(A.mat, cdim, coords, cdist, peta, lsize, maxr, pbs, tol, &newmat)) 1599 CHKERR(PetscCLEAR(self.obj)); self.mat = newmat 1600 return self 1601 1602 def createIS( 1603 self, 1604 size: MatSizeSpec, 1605 bsize: MatBlockSizeSpec | None = None, 1606 LGMap lgmapr = None, 1607 LGMap lgmapc = None, 1608 comm: Comm | None = None) -> Self: 1609 """Create a `Type.IS` matrix representing globally unassembled operators. 1610 1611 Collective. 1612 1613 Parameters 1614 ---------- 1615 size 1616 Matrix size. 1617 bsize 1618 Matrix block size. If `None`, a block size of ``1`` is set. 1619 lgmapr 1620 Optional local-to-global mapping for the rows. 1621 If `None`, the local row space matches the global row space. 1622 lgmapc 1623 Optional local-to-global mapping for the columns. 1624 If `None`, the local column space matches the global column space. 1625 comm 1626 MPI communicator, defaults to `Sys.getDefaultComm`. 1627 1628 See Also 1629 -------- 1630 petsc.MATIS 1631 1632 """ 1633 # communicator and sizes 1634 if comm is None and lgmapr is not None: comm = lgmapr.getComm() 1635 if comm is None and lgmapc is not None: comm = lgmapc.getComm() 1636 cdef PetscLGMap lgmr = NULL 1637 cdef PetscLGMap lgmc = NULL 1638 cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) 1639 cdef PetscInt rbs = 0, cbs = 0, m = 0, n = 0, M = 0, N = 0 1640 Mat_Sizes(size, bsize, &rbs, &cbs, &m, &n, &M, &N) 1641 Sys_Layout(ccomm, rbs, &m, &M) 1642 Sys_Layout(ccomm, cbs, &n, &N) 1643 # create matrix 1644 cdef PetscMat newmat = NULL 1645 cdef PetscInt bs = 1 1646 if rbs == cbs: bs = rbs 1647 if lgmapr is not None: 1648 lgmr = lgmapr.lgm 1649 if lgmapc is not None: 1650 lgmc = lgmapc.lgm 1651 CHKERR(MatCreateIS(ccomm, bs, m, n, M, N, lgmr, lgmc, &newmat)) 1652 CHKERR(PetscCLEAR(self.obj)); self.mat = newmat 1653 return self 1654 1655 def createConstantDiagonal( 1656 self, 1657 size: MatSizeSpec, 1658 diag: float, 1659 comm: Comm | None = None) -> Self: 1660 """Create a diagonal matrix of type `Type.CONSTANTDIAGONAL`. 1661 1662 Collective. 1663 1664 Parameters 1665 ---------- 1666 size 1667 Matrix size. 1668 diag 1669 The diagonal value. 1670 comm 1671 MPI communicator, defaults to `Sys.getDefaultComm`. 1672 1673 See Also 1674 -------- 1675 createDiagonal 1676 1677 """ 1678 cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) 1679 cdef PetscInt rbs = 0, cbs = 0, m = 0, n = 0, M = 0, N = 0 1680 Mat_Sizes(size, None, &rbs, &cbs, &m, &n, &M, &N) 1681 Sys_Layout(ccomm, rbs, &m, &M) 1682 Sys_Layout(ccomm, cbs, &n, &N) 1683 cdef PetscMat newmat = NULL 1684 CHKERR(MatCreateConstantDiagonal(ccomm, m, n, M, N, diag, &newmat)) 1685 CHKERR(PetscCLEAR(self.obj)); self.mat = newmat 1686 return self 1687 1688 def createDiagonal( 1689 self, 1690 Vec diag) -> Self: 1691 """Create a diagonal matrix of type `Type.DIAGONAL`. 1692 1693 Collective. 1694 1695 Parameters 1696 ---------- 1697 diag 1698 The vector holding diagonal values. 1699 1700 See Also 1701 -------- 1702 createConstantDiagonal 1703 1704 """ 1705 cdef PetscVec dvec = diag.vec 1706 cdef PetscMat newmat = NULL 1707 CHKERR(MatCreateDiagonal(dvec, &newmat)) 1708 CHKERR(PetscCLEAR(self.obj)); self.mat = newmat 1709 return self 1710 1711 def createPython(self, size: MatSizeSpec, context: Any = None, comm: Comm | None = None) -> Self: 1712 """Create a `Type.PYTHON` matrix. 1713 1714 Collective. 1715 1716 Parameters 1717 ---------- 1718 size 1719 Matrix size. 1720 context 1721 An instance of the Python class implementing the required methods. 1722 comm 1723 MPI communicator, defaults to `Sys.getDefaultComm`. 1724 1725 See Also 1726 -------- 1727 petsc_python_mat, setType, setPythonContext, Type.PYTHON 1728 1729 """ 1730 # communicator and sizes 1731 cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) 1732 cdef PetscInt rbs = 0, cbs = 0, m = 0, n = 0, M = 0, N = 0 1733 Mat_Sizes(size, None, &rbs, &cbs, &m, &n, &M, &N) 1734 Sys_Layout(ccomm, rbs, &m, &M) 1735 Sys_Layout(ccomm, cbs, &n, &N) 1736 # create matrix 1737 # FIXME: propagate block sizes? 1738 cdef PetscMat newmat = NULL 1739 CHKERR(MatCreate(ccomm, &newmat)) 1740 CHKERR(PetscCLEAR(self.obj)); self.mat = newmat 1741 CHKERR(MatSetSizes(self.mat, m, n, M, N)) 1742 CHKERR(MatSetType(self.mat, MATPYTHON)) 1743 CHKERR(MatPythonSetContext(self.mat, <void*>context)) 1744 if context: 1745 CHKERR(MatSetUp(self.mat)) 1746 return self 1747 1748 def setPythonContext(self, context: Any) -> None: 1749 """Set the instance of the class implementing the required Python methods. 1750 1751 Logically collective. 1752 1753 Notes 1754 ----- 1755 In order to use the matrix, `Mat.setUp` must be called after having set 1756 the context. Pass `None` to reset the matrix to its initial state. 1757 1758 See Also 1759 -------- 1760 petsc_python_mat, getPythonContext, setPythonType 1761 1762 """ 1763 CHKERR(MatPythonSetContext(self.mat, <void*>context)) 1764 1765 def getPythonContext(self) -> Any: 1766 """Return the instance of the class implementing the required Python methods. 1767 1768 Not collective. 1769 1770 See Also 1771 -------- 1772 petsc_python_mat, setPythonContext 1773 1774 """ 1775 cdef void *context = NULL 1776 CHKERR(MatPythonGetContext(self.mat, &context)) 1777 if context == NULL: return None 1778 else: return <object> context 1779 1780 def setPythonType(self, py_type: str) -> None: 1781 """Set the fully qualified Python name of the class to be used. 1782 1783 Collective. 1784 1785 Notes 1786 ----- 1787 In order to use the matrix, `Mat.setUp` must be called after having set 1788 the type. 1789 1790 See Also 1791 -------- 1792 petsc_python_mat, setPythonContext, getPythonType 1793 petsc.MatPythonSetType 1794 1795 """ 1796 cdef const char *cval = NULL 1797 py_type = str2bytes(py_type, &cval) 1798 CHKERR(MatPythonSetType(self.mat, cval)) 1799 1800 def getPythonType(self) -> str: 1801 """Return the fully qualified Python name of the class used by the matrix. 1802 1803 Not collective. 1804 1805 See Also 1806 -------- 1807 petsc_python_mat, setPythonContext, setPythonType 1808 petsc.MatPythonGetType 1809 1810 """ 1811 cdef const char *cval = NULL 1812 CHKERR(MatPythonGetType(self.mat, &cval)) 1813 return bytes2str(cval) 1814 1815 # 1816 1817 def setOptionsPrefix(self, prefix: str | None = None) -> None: 1818 """Set the prefix used for searching for options in the database. 1819 1820 Logically collective. 1821 1822 See Also 1823 -------- 1824 petsc_options, getOptionsPrefix, petsc.MatSetOptionsPrefix 1825 1826 """ 1827 cdef const char *cval = NULL 1828 prefix = str2bytes(prefix, &cval) 1829 CHKERR(MatSetOptionsPrefix(self.mat, cval)) 1830 1831 def getOptionsPrefix(self) -> str: 1832 """Return the prefix used for searching for options in the database. 1833 1834 Not collective. 1835 1836 See Also 1837 -------- 1838 petsc_options, setOptionsPrefix, petsc.MatGetOptionsPrefix 1839 1840 """ 1841 cdef const char *cval = NULL 1842 CHKERR(MatGetOptionsPrefix(self.mat, &cval)) 1843 return bytes2str(cval) 1844 1845 def appendOptionsPrefix(self, prefix: str | None = None) -> None: 1846 """Append to the prefix used for searching for options in the database. 1847 1848 Logically collective. 1849 1850 See Also 1851 -------- 1852 petsc_options, setOptionsPrefix, petsc.MatAppendOptionsPrefix 1853 1854 """ 1855 cdef const char *cval = NULL 1856 prefix = str2bytes(prefix, &cval) 1857 CHKERR(MatAppendOptionsPrefix(self.mat, cval)) 1858 1859 def setFromOptions(self) -> None: 1860 """Configure the matrix from the options database. 1861 1862 Collective. 1863 1864 See Also 1865 -------- 1866 petsc_options, petsc.MatSetFromOptions 1867 1868 """ 1869 CHKERR(MatSetFromOptions(self.mat)) 1870 1871 def setUp(self) -> Self: 1872 """Set up the internal data structures for using the matrix. 1873 1874 Collective. 1875 1876 See Also 1877 -------- 1878 petsc.MatSetUp 1879 1880 """ 1881 CHKERR(MatSetUp(self.mat)) 1882 return self 1883 1884 def setOption(self, option: Option, flag: bool) -> None: 1885 """Set option. 1886 1887 Collective. 1888 1889 See Also 1890 -------- 1891 getOption, petsc.MatSetOption 1892 1893 """ 1894 CHKERR(MatSetOption(self.mat, option, flag)) 1895 1896 def getOption(self, option: Option) -> bool: 1897 """Return the option value. 1898 1899 Not collective. 1900 1901 See Also 1902 -------- 1903 setOption, petsc.MatGetOption 1904 1905 """ 1906 cdef PetscBool flag = PETSC_FALSE 1907 CHKERR(MatGetOption(self.mat, option, &flag)) 1908 return toBool(flag) 1909 1910 def getType(self) -> str: 1911 """Return the type of the matrix. 1912 1913 Not collective. 1914 1915 See Also 1916 -------- 1917 setType, Type, petsc.MatGetType 1918 1919 """ 1920 cdef PetscMatType cval = NULL 1921 CHKERR(MatGetType(self.mat, &cval)) 1922 return bytes2str(cval) 1923 1924 def getSize(self) -> tuple[int, int]: 1925 """Return the global number of rows and columns. 1926 1927 Not collective. 1928 1929 See Also 1930 -------- 1931 getLocalSize, getSizes, petsc.MatGetSize 1932 1933 """ 1934 cdef PetscInt M = 0, N = 0 1935 CHKERR(MatGetSize(self.mat, &M, &N)) 1936 return (toInt(M), toInt(N)) 1937 1938 def getLocalSize(self) -> tuple[int, int]: 1939 """Return the local number of rows and columns. 1940 1941 Not collective. 1942 1943 See Also 1944 -------- 1945 getSize, petsc.MatGetLocalSize 1946 1947 """ 1948 cdef PetscInt m = 0, n = 0 1949 CHKERR(MatGetLocalSize(self.mat, &m, &n)) 1950 return (toInt(m), toInt(n)) 1951 1952 def getSizes(self) -> tuple[LayoutSizeSpec, LayoutSizeSpec]: 1953 """Return the tuple of matrix layouts. 1954 1955 Not collective. 1956 1957 See Also 1958 -------- 1959 getLocalSize, getSize 1960 1961 """ 1962 cdef PetscInt m = 0, n = 0 1963 cdef PetscInt M = 0, N = 0 1964 CHKERR(MatGetLocalSize(self.mat, &m, &n)) 1965 CHKERR(MatGetSize(self.mat, &M, &N)) 1966 return ((toInt(m), toInt(M)), (toInt(n), toInt(N))) 1967 1968 def getBlockSize(self) -> int: 1969 """Return the matrix block size. 1970 1971 Not collective. 1972 1973 See Also 1974 -------- 1975 getBlockSize, petsc.MatGetBlockSize 1976 1977 """ 1978 cdef PetscInt bs = 0 1979 CHKERR(MatGetBlockSize(self.mat, &bs)) 1980 return toInt(bs) 1981 1982 def getBlockSizes(self) -> tuple[int, int]: 1983 """Return the row and column block sizes. 1984 1985 Not collective. 1986 1987 See Also 1988 -------- 1989 getBlockSize, petsc.MatGetBlockSizes 1990 1991 """ 1992 cdef PetscInt rbs = 0, cbs = 0 1993 CHKERR(MatGetBlockSizes(self.mat, &rbs, &cbs)) 1994 return (toInt(rbs), toInt(cbs)) 1995 1996 def getOwnershipRange(self) -> tuple[int, int]: 1997 """Return the locally owned range of rows. 1998 1999 Not collective. 2000 2001 See Also 2002 -------- 2003 getOwnershipRanges, getOwnershipRangeColumn, petsc.MatGetOwnershipRange 2004 2005 """ 2006 cdef PetscInt ival1 = 0, ival2 = 0 2007 CHKERR(MatGetOwnershipRange(self.mat, &ival1, &ival2)) 2008 return (toInt(ival1), toInt(ival2)) 2009 2010 def getOwnershipRanges(self) -> ArrayInt: 2011 """Return the range of rows owned by each process. 2012 2013 Not collective. 2014 2015 The returned array is the result of exclusive scan of the local sizes. 2016 2017 See Also 2018 -------- 2019 getOwnershipRange, petsc.MatGetOwnershipRanges 2020 2021 """ 2022 cdef const PetscInt *rowrng = NULL 2023 CHKERR(MatGetOwnershipRanges(self.mat, &rowrng)) 2024 cdef MPI_Comm comm = MPI_COMM_NULL 2025 CHKERR(PetscObjectGetComm(<PetscObject>self.mat, &comm)) 2026 cdef int size = -1 2027 CHKERR(<PetscErrorCode>MPI_Comm_size(comm, &size)) 2028 return array_i(size+1, rowrng) 2029 2030 def getOwnershipRangeColumn(self) -> tuple[int, int]: 2031 """Return the locally owned range of columns. 2032 2033 Not collective. 2034 2035 See Also 2036 -------- 2037 getOwnershipRangesColumn, getOwnershipRange 2038 petsc.MatGetOwnershipRangeColumn 2039 2040 """ 2041 cdef PetscInt ival1 = 0, ival2 = 0 2042 CHKERR(MatGetOwnershipRangeColumn(self.mat, &ival1, &ival2)) 2043 return (toInt(ival1), toInt(ival2)) 2044 2045 def getOwnershipRangesColumn(self) -> ArrayInt: 2046 """Return the range of columns owned by each process. 2047 2048 Not collective. 2049 2050 See Also 2051 -------- 2052 getOwnershipRangeColumn, petsc.MatGetOwnershipRangesColumn 2053 2054 """ 2055 cdef const PetscInt *colrng = NULL 2056 CHKERR(MatGetOwnershipRangesColumn(self.mat, &colrng)) 2057 cdef MPI_Comm comm = MPI_COMM_NULL 2058 CHKERR(PetscObjectGetComm(<PetscObject>self.mat, &comm)) 2059 cdef int size = -1 2060 CHKERR(<PetscErrorCode>MPI_Comm_size(comm, &size)) 2061 return array_i(size+1, colrng) 2062 2063 def getOwnershipIS(self) -> tuple[IS, IS]: 2064 """Return the ranges of rows and columns owned by each process as index sets. 2065 2066 Not collective. 2067 2068 See Also 2069 -------- 2070 getOwnershipRanges, getOwnershipRangesColumn, petsc.MatGetOwnershipIS 2071 2072 """ 2073 cdef IS rows = IS() 2074 cdef IS cols = IS() 2075 CHKERR(MatGetOwnershipIS(self.mat, &rows.iset, &cols.iset)) 2076 return (rows, cols) 2077 2078 def getInfo(self, info: InfoType | None = None) -> dict[str, float]: 2079 """Return summary information. 2080 2081 Collective. 2082 2083 Parameters 2084 ---------- 2085 info 2086 If `None`, it uses `InfoType.GLOBAL_SUM`. 2087 2088 See Also 2089 -------- 2090 petsc.MatInfo, petsc.MatGetInfo 2091 2092 """ 2093 cdef PetscMatInfoType itype = infotype(info) 2094 cdef PetscMatInfo cinfo 2095 CHKERR(MatGetInfo(self.mat, itype, &cinfo)) 2096 return cinfo 2097 2098 def duplicate(self, copy: DuplicateOption | bool = False) -> Mat: 2099 """Return a clone of the matrix. 2100 2101 Collective. 2102 2103 Parameters 2104 ---------- 2105 copy 2106 If `True`, it also copies the values. 2107 2108 See Also 2109 -------- 2110 petsc.MatDuplicate 2111 2112 """ 2113 cdef PetscMatDuplicateOption flag = matduplicateoption(copy) 2114 cdef Mat mat = type(self)() 2115 CHKERR(MatDuplicate(self.mat, flag, &mat.mat)) 2116 return mat 2117 2118 def copy(self, Mat result=None, structure: Structure | None = None) -> Mat: 2119 """Return a copy of the matrix. 2120 2121 Collective. 2122 2123 Parameters 2124 ---------- 2125 result 2126 Optional return matrix. If `None`, it is internally created. 2127 structure 2128 The copy structure. Only relevant if ``result`` is not `None`. 2129 2130 See Also 2131 -------- 2132 petsc.MatCopy, petsc.MatDuplicate 2133 2134 """ 2135 cdef PetscMatDuplicateOption copy = MAT_COPY_VALUES 2136 cdef PetscMatStructure mstr = matstructure(structure) 2137 if result is None: 2138 result = type(self)() 2139 if result.mat == NULL: 2140 CHKERR(MatDuplicate(self.mat, copy, &result.mat)) 2141 else: 2142 CHKERR(MatCopy(self.mat, result.mat, mstr)) 2143 return result 2144 2145 def load(self, Viewer viewer) -> Self: 2146 """Load a matrix. 2147 2148 Collective. 2149 2150 See Also 2151 -------- 2152 petsc.MatLoad 2153 2154 """ 2155 cdef MPI_Comm comm = MPI_COMM_NULL 2156 cdef PetscObject obj = <PetscObject>(viewer.vwr) 2157 if self.mat == NULL: 2158 CHKERR(PetscObjectGetComm(obj, &comm)) 2159 CHKERR(MatCreate(comm, &self.mat)) 2160 CHKERR(MatLoad(self.mat, viewer.vwr)) 2161 return self 2162 2163 def convert(self, mat_type: Type | str | None = None, Mat out=None) -> Mat: 2164 """Convert the matrix type. 2165 2166 Collective. 2167 2168 Parameters 2169 ---------- 2170 mat_type 2171 The type of the new matrix. If `None` uses `Type.SAME`. 2172 out 2173 Optional return matrix. If `None`, inplace conversion is performed. 2174 Otherwise, the matrix is reused. 2175 2176 See Also 2177 -------- 2178 petsc.MatConvert 2179 2180 """ 2181 cdef PetscMatType mtype = MATSAME 2182 cdef PetscMatReuse reuse = MAT_INITIAL_MATRIX 2183 mat_type = str2bytes(mat_type, &mtype) 2184 if mtype == NULL: mtype = MATSAME 2185 if out is None: out = self 2186 if out.mat == self.mat: 2187 reuse = MAT_INPLACE_MATRIX 2188 elif out.mat == NULL: 2189 reuse = MAT_INITIAL_MATRIX 2190 else: 2191 reuse = MAT_REUSE_MATRIX 2192 CHKERR(MatConvert(self.mat, mtype, reuse, &out.mat)) 2193 return out 2194 2195 def transpose(self, Mat out=None) -> Mat: 2196 """Return the transposed matrix. 2197 2198 Collective. 2199 2200 Parameters 2201 ---------- 2202 out 2203 Optional return matrix. If `None`, inplace transposition is performed. 2204 Otherwise, the matrix is reused. 2205 2206 See Also 2207 -------- 2208 petsc.MatTranspose 2209 2210 """ 2211 cdef PetscMatReuse reuse = MAT_INITIAL_MATRIX 2212 if out is None: out = self 2213 if out.mat == self.mat: 2214 reuse = MAT_INPLACE_MATRIX 2215 elif out.mat == NULL: 2216 reuse = MAT_INITIAL_MATRIX 2217 else: 2218 reuse = MAT_REUSE_MATRIX 2219 CHKERR(MatTranspose(self.mat, reuse, &out.mat)) 2220 return out 2221 2222 def setTransposePrecursor(self, Mat out) -> None: 2223 """Set transpose precursor. 2224 2225 Logically collective. 2226 2227 See Also 2228 -------- 2229 petsc.MatTransposeSetPrecursor 2230 2231 """ 2232 CHKERR(MatTransposeSetPrecursor(self.mat, out.mat)) 2233 2234 def hermitianTranspose(self, Mat out=None) -> Mat: 2235 """Return the transposed Hermitian matrix. 2236 2237 Collective. 2238 2239 Parameters 2240 ---------- 2241 out 2242 Optional return matrix. If `None`, inplace transposition is performed. 2243 Otherwise, the matrix is reused. 2244 2245 See Also 2246 -------- 2247 petsc.MatHermitianTranspose 2248 2249 """ 2250 cdef PetscMatReuse reuse = MAT_INITIAL_MATRIX 2251 if out is None: out = self 2252 if out.mat == self.mat: 2253 reuse = MAT_INPLACE_MATRIX 2254 elif out.mat == NULL: 2255 reuse = MAT_INITIAL_MATRIX 2256 else: 2257 reuse = MAT_REUSE_MATRIX 2258 CHKERR(MatHermitianTranspose(self.mat, reuse, &out.mat)) 2259 return out 2260 2261 def realPart(self, Mat out=None) -> Mat: 2262 """Return the real part of the matrix. 2263 2264 Collective. 2265 2266 Parameters 2267 ---------- 2268 out 2269 Optional return matrix. If `None`, the operation is performed in-place. 2270 Otherwise, the operation is performed on ``out``. 2271 2272 See Also 2273 -------- 2274 imagPart, conjugate, petsc.MatRealPart 2275 2276 """ 2277 if out is None: 2278 out = self 2279 elif out.mat == NULL: 2280 CHKERR(MatDuplicate(self.mat, MAT_COPY_VALUES, &out.mat)) 2281 CHKERR(MatRealPart(out.mat)) 2282 return out 2283 2284 def imagPart(self, Mat out=None) -> Mat: 2285 """Return the imaginary part of the matrix. 2286 2287 Collective. 2288 2289 Parameters 2290 ---------- 2291 out 2292 Optional return matrix. If `None`, the operation is performed in-place. 2293 Otherwise, the operation is performed on ``out``. 2294 2295 See Also 2296 -------- 2297 realPart, conjugate, petsc.MatImaginaryPart 2298 2299 """ 2300 if out is None: 2301 out = self 2302 elif out.mat == NULL: 2303 CHKERR(MatDuplicate(self.mat, MAT_COPY_VALUES, &out.mat)) 2304 CHKERR(MatImaginaryPart(out.mat)) 2305 return out 2306 2307 def conjugate(self, Mat out=None) -> Mat: 2308 """Return the conjugate matrix. 2309 2310 Collective. 2311 2312 Parameters 2313 ---------- 2314 out 2315 Optional return matrix. If `None`, the operation is performed in-place. 2316 Otherwise, the operation is performed on ``out``. 2317 2318 See Also 2319 -------- 2320 realPart, imagPart, petsc.MatConjugate 2321 2322 """ 2323 if out is None: 2324 out = self 2325 elif out.mat == NULL: 2326 CHKERR(MatDuplicate(self.mat, MAT_COPY_VALUES, &out.mat)) 2327 CHKERR(MatConjugate(out.mat)) 2328 return out 2329 2330 def permute(self, IS row, IS col) -> Mat: 2331 """Return the permuted matrix. 2332 2333 Collective. 2334 2335 Parameters 2336 ---------- 2337 row 2338 Row permutation. 2339 col 2340 Column permutation. 2341 2342 See Also 2343 -------- 2344 petsc.MatPermute 2345 2346 """ 2347 cdef Mat mat = Mat() 2348 CHKERR(MatPermute(self.mat, row.iset, col.iset, &mat.mat)) 2349 return mat 2350 2351 def equal(self, Mat mat) -> bool: 2352 """Return the result of matrix comparison. 2353 2354 Collective. 2355 2356 See Also 2357 -------- 2358 petsc.MatEqual 2359 2360 """ 2361 cdef PetscBool flag = PETSC_FALSE 2362 CHKERR(MatEqual(self.mat, mat.mat, &flag)) 2363 return toBool(flag) 2364 2365 def isTranspose(self, Mat mat=None, tol: float = 0) -> bool: 2366 """Return the result of matrix comparison with transposition. 2367 2368 Collective. 2369 2370 Parameters 2371 ---------- 2372 mat 2373 Matrix to compare against. Uses ``self`` if `None`. 2374 tol 2375 Tolerance for comparison. 2376 2377 See Also 2378 -------- 2379 petsc.MatIsTranspose 2380 2381 """ 2382 if mat is None: mat = self 2383 cdef PetscReal rval = asReal(tol) 2384 cdef PetscBool flag = PETSC_FALSE 2385 CHKERR(MatIsTranspose(self.mat, mat.mat, rval, &flag)) 2386 return toBool(flag) 2387 2388 def isSymmetric(self, tol: float = 0) -> bool: 2389 """Return the boolean indicating if the matrix is symmetric. 2390 2391 Collective. 2392 2393 Parameters 2394 ---------- 2395 tol 2396 Tolerance for comparison. 2397 2398 See Also 2399 -------- 2400 petsc.MatIsSymmetric 2401 2402 """ 2403 cdef PetscReal rval = asReal(tol) 2404 cdef PetscBool flag = PETSC_FALSE 2405 CHKERR(MatIsSymmetric(self.mat, rval, &flag)) 2406 return toBool(flag) 2407 2408 def isSymmetricKnown(self) -> tuple[bool, bool]: 2409 """Return the 2-tuple indicating if the matrix is known to be symmetric. 2410 2411 Not collective. 2412 2413 See Also 2414 -------- 2415 petsc.MatIsSymmetricKnown 2416 2417 """ 2418 cdef PetscBool flag1 = PETSC_FALSE 2419 cdef PetscBool flag2 = PETSC_FALSE 2420 CHKERR(MatIsSymmetricKnown(self.mat, &flag1, &flag2)) 2421 return (toBool(flag1), toBool(flag2)) 2422 2423 def isHermitian(self, tol: float = 0) -> bool: 2424 """Return the boolean indicating if the matrix is Hermitian. 2425 2426 Collective. 2427 2428 Parameters 2429 ---------- 2430 tol 2431 Tolerance for comparison. 2432 2433 See Also 2434 -------- 2435 petsc.MatIsHermitian 2436 2437 """ 2438 cdef PetscReal rval = asReal(tol) 2439 cdef PetscBool flag = PETSC_FALSE 2440 CHKERR(MatIsHermitian(self.mat, rval, &flag)) 2441 return toBool(flag) 2442 2443 def isHermitianKnown(self) -> tuple[bool, bool]: 2444 """Return the 2-tuple indicating if the matrix is known to be Hermitian. 2445 2446 Not collective. 2447 2448 See Also 2449 -------- 2450 petsc.MatIsHermitianKnown 2451 2452 """ 2453 cdef PetscBool flag1 = PETSC_FALSE 2454 cdef PetscBool flag2 = PETSC_FALSE 2455 CHKERR(MatIsHermitianKnown(self.mat, &flag1, &flag2)) 2456 return (toBool(flag1), toBool(flag2)) 2457 2458 def isStructurallySymmetric(self) -> bool: 2459 """Return the boolean indicating if the matrix is structurally symmetric. 2460 2461 Not collective. 2462 2463 See Also 2464 -------- 2465 petsc.MatIsStructurallySymmetric 2466 2467 """ 2468 cdef PetscBool flag = PETSC_FALSE 2469 CHKERR(MatIsStructurallySymmetric(self.mat, &flag)) 2470 return toBool(flag) 2471 2472 def isLinear(self, n: int = 1) -> bool: 2473 """Return whether the Mat is a linear operator. 2474 2475 Collective. 2476 2477 Parameters 2478 ---------- 2479 n 2480 Number of random vectors to be tested. 2481 2482 See Also 2483 -------- 2484 petsc.MatIsLinear 2485 2486 """ 2487 cdef PetscBool flag = PETSC_FALSE 2488 CHKERR(MatIsLinear(self.mat, n, &flag)) 2489 return toBool(flag) 2490 2491 def zeroEntries(self) -> None: 2492 """Zero the entries of the matrix. 2493 2494 Collective. 2495 2496 See Also 2497 -------- 2498 petsc.MatZeroEntries 2499 2500 """ 2501 CHKERR(MatZeroEntries(self.mat)) 2502 2503 def getValue(self, row, col) -> Scalar: 2504 """Return the value in the (row, col) position. 2505 2506 Not collective. 2507 2508 See Also 2509 -------- 2510 petsc.MatGetValues 2511 2512 """ 2513 cdef PetscInt ival1 = asInt(row) 2514 cdef PetscInt ival2 = asInt(col) 2515 cdef PetscScalar sval = 0 2516 CHKERR(MatGetValues(self.mat, 1, &ival1, 1, &ival2, &sval)) 2517 return toScalar(sval) 2518 2519 def getValues(self, rows: Sequence[int], cols: Sequence[int], values: ArrayScalar | None = None) -> ArrayScalar: 2520 """Return the values in the ``zip(rows, cols)`` positions. 2521 2522 Not collective. 2523 2524 Parameters 2525 ---------- 2526 rows 2527 Row indices. 2528 cols 2529 Column indices. 2530 values 2531 Optional array where to store the values. 2532 2533 See Also 2534 -------- 2535 petsc.MatGetValues 2536 2537 """ 2538 return matgetvalues(self.mat, rows, cols, values) 2539 2540 def getValuesCSR(self) -> tuple[ArrayInt, ArrayInt, ArrayScalar]: 2541 """Return the CSR representation of the local part of the matrix. 2542 2543 Not collective. 2544 2545 See Also 2546 -------- 2547 petsc.MatGetRow 2548 2549 """ 2550 # row ownership 2551 cdef PetscInt rstart=0, rend=0, nrows=0 2552 CHKERR(MatGetOwnershipRange(self.mat, &rstart, &rend)) 2553 nrows = rend - rstart 2554 # first pass: row pointer array 2555 cdef PetscInt *AI = NULL 2556 cdef ndarray ai = oarray_i(empty_i(nrows+1), NULL, &AI) 2557 cdef PetscInt irow=0, ncols=0 2558 AI[0] = 0 2559 for irow from 0 <= irow < nrows: 2560 CHKERR(MatGetRow(self.mat, irow+rstart, &ncols, NULL, NULL)) 2561 AI[irow+1] = AI[irow] + ncols 2562 CHKERR(MatRestoreRow(self.mat, irow+rstart, &ncols, NULL, NULL)) 2563 # second pass: column indices and values 2564 cdef PetscInt *AJ = NULL 2565 cdef ndarray aj = oarray_i(empty_i(AI[nrows]), NULL, &AJ) 2566 cdef PetscScalar *AV = NULL 2567 cdef ndarray av = oarray_s(empty_s(AI[nrows]), NULL, &AV) 2568 cdef const PetscInt *cols = NULL 2569 cdef const PetscScalar *vals = NULL 2570 for irow from 0 <= irow < nrows: 2571 CHKERR(MatGetRow(self.mat, irow+rstart, &ncols, &cols, &vals)) 2572 CHKERR(PetscMemcpy(AJ+AI[irow], cols, <size_t>ncols*sizeof(PetscInt))) 2573 CHKERR(PetscMemcpy(AV+AI[irow], vals, <size_t>ncols*sizeof(PetscScalar))) 2574 CHKERR(MatRestoreRow(self.mat, irow+rstart, &ncols, &cols, &vals)) 2575 # 2576 return (ai, aj, av) 2577 2578 def getRow(self, row: int) -> tuple[ArrayInt, ArrayScalar]: 2579 """Return the column indices and values for the requested row. 2580 2581 Not collective. 2582 2583 See Also 2584 -------- 2585 petsc.MatGetRow 2586 2587 """ 2588 cdef PetscInt irow = asInt(row) 2589 cdef PetscInt ncols = 0 2590 cdef const PetscInt *icols=NULL 2591 cdef const PetscScalar *svals=NULL 2592 CHKERR(MatGetRow(self.mat, irow, &ncols, &icols, &svals)) 2593 cdef object cols = array_i(ncols, icols) 2594 cdef object vals = array_s(ncols, svals) 2595 CHKERR(MatRestoreRow(self.mat, irow, &ncols, &icols, &svals)) 2596 return (cols, vals) 2597 2598 def getRowIJ(self, symmetric: bool = False, compressed: bool = False) -> tuple[ArrayInt, ArrayInt]: 2599 """Return the CSR representation of the local sparsity pattern. 2600 2601 Collective. 2602 2603 Parameters 2604 ---------- 2605 symmetric 2606 If `True`, return the symmetrized graph. 2607 compressed 2608 If `True`, return the compressed graph. 2609 2610 See Also 2611 -------- 2612 petsc.MatGetRowIJ 2613 2614 """ 2615 cdef PetscInt shift=0 2616 cdef PetscBool symm=symmetric 2617 cdef PetscBool bcmp=compressed 2618 cdef PetscInt n=0 2619 cdef const PetscInt *ia=NULL 2620 cdef const PetscInt *ja=NULL 2621 cdef PetscBool done=PETSC_FALSE 2622 CHKERR(MatGetRowIJ(self.mat, shift, symm, bcmp, &n, &ia, &ja, &done)) 2623 cdef object ai=None, aj=None 2624 if done != PETSC_FALSE: ai = array_i(n+1, ia) 2625 if done != PETSC_FALSE: aj = array_i(ia[n], ja) 2626 CHKERR(MatRestoreRowIJ(self.mat, shift, symm, bcmp, &n, &ia, &ja, &done)) 2627 return (ai, aj) 2628 2629 def getColumnIJ(self, symmetric: bool = False, compressed: bool = False) -> tuple[ArrayInt, ArrayInt]: 2630 """Return the CSC representation of the local sparsity pattern. 2631 2632 Collective. 2633 2634 Parameters 2635 ---------- 2636 symmetric 2637 If `True`, return the symmetrized graph. 2638 compressed 2639 If `True`, return the compressed graph. 2640 2641 See Also 2642 -------- 2643 petsc.MatGetRowIJ 2644 2645 """ 2646 cdef PetscInt shift=0 2647 cdef PetscBool symm=symmetric, bcmp=compressed 2648 cdef PetscInt n=0 2649 cdef const PetscInt *ia=NULL 2650 cdef const PetscInt *ja=NULL 2651 cdef PetscBool done=PETSC_FALSE 2652 CHKERR(MatGetColumnIJ(self.mat, shift, symm, bcmp, &n, &ia, &ja, &done)) 2653 cdef object ai=None, aj=None 2654 if done != PETSC_FALSE: ai = array_i(n+1, ia) 2655 if done != PETSC_FALSE: aj = array_i(ia[n], ja) 2656 CHKERR(MatRestoreColumnIJ(self.mat, shift, symm, bcmp, &n, &ia, &ja, &done)) 2657 return (ai, aj) 2658 2659 def setValue( 2660 self, 2661 row: int, 2662 col: int, 2663 value: Scalar, 2664 addv: InsertModeSpec = None) -> None: 2665 """Set a value to the ``(row, col)`` entry of the matrix. 2666 2667 Not collective. 2668 2669 Parameters 2670 ---------- 2671 row 2672 Row index. 2673 col 2674 Column index. 2675 value 2676 The scalar value. 2677 addv 2678 Insertion mode. 2679 2680 See Also 2681 -------- 2682 petsc.MatSetValues 2683 2684 """ 2685 cdef PetscInt ival1 = asInt(row) 2686 cdef PetscInt ival2 = asInt(col) 2687 cdef PetscScalar sval = asScalar(value) 2688 cdef PetscInsertMode caddv = insertmode(addv) 2689 CHKERR(MatSetValues(self.mat, 1, &ival1, 1, &ival2, &sval, caddv)) 2690 2691 def setValues( 2692 self, 2693 rows: Sequence[int], 2694 cols: Sequence[int], 2695 values: Sequence[Scalar], 2696 addv: InsertModeSpec = None) -> None: 2697 """Set values to the rows ⊗ cols entries of the matrix. 2698 2699 Not collective. 2700 2701 Parameters 2702 ---------- 2703 rows 2704 Row indices. 2705 cols 2706 Column indices. 2707 values 2708 The scalar values. A sequence of length at least ``len(rows) * len(cols)``. 2709 addv 2710 Insertion mode. 2711 2712 See Also 2713 -------- 2714 petsc.MatSetValues 2715 2716 """ 2717 matsetvalues(self.mat, rows, cols, values, addv, 0, 0) 2718 2719 def setValuesRCV(self, R, C, V, addv=None) -> None: 2720 """Undocumented.""" 2721 matsetvalues_rcv(self.mat, R, C, V, addv, 0, 0) 2722 2723 def setValuesIJV( 2724 self, 2725 I: Sequence[int], 2726 J: Sequence[int], 2727 V: Sequence[Scalar], 2728 addv: InsertModeSpec = None, 2729 rowmap: Sequence[int] | None = None) -> None: 2730 """Set a subset of values stored in CSR format. 2731 2732 Not collective. 2733 2734 Parameters 2735 ---------- 2736 I 2737 Row pointers. 2738 J 2739 Column indices. 2740 V 2741 The scalar values. 2742 addv 2743 Insertion mode. 2744 rowmap 2745 Optional iterable indicating which row to insert. 2746 2747 See Also 2748 -------- 2749 petsc.MatSetValues 2750 2751 """ 2752 matsetvalues_ijv(self.mat, I, J, V, addv, rowmap, 0, 0) 2753 2754 def setValuesCOO( 2755 self, 2756 coo_v: Sequence[Scalar], 2757 addv: InsertModeSpec = None) -> None: 2758 """Set values after preallocation with coordinate format. 2759 2760 Collective. 2761 2762 Parameters 2763 ---------- 2764 coo_v 2765 The matrix values. 2766 addv 2767 Insertion mode. 2768 2769 See Also 2770 -------- 2771 setPreallocationCOO, petsc.MatSetValuesCOO 2772 """ 2773 matsetvalues_coo(self.mat, coo_v, addv) 2774 2775 def setValuesCSR( 2776 self, 2777 I: Sequence[int], 2778 J: Sequence[int], 2779 V: Sequence[Scalar], 2780 addv: InsertModeSpec = None) -> None: 2781 """Set values stored in CSR format. 2782 2783 Not collective. 2784 2785 Parameters 2786 ---------- 2787 I 2788 Row pointers. 2789 J 2790 Column indices. 2791 V 2792 The scalar values. 2793 addv 2794 Insertion mode. 2795 2796 See Also 2797 -------- 2798 petsc.MatSetValues 2799 2800 """ 2801 matsetvalues_csr(self.mat, I, J, V, addv, 0, 0) 2802 2803 def setValuesBlocked( 2804 self, 2805 rows: Sequence[int], 2806 cols: Sequence[int], 2807 values: Sequence[Scalar], 2808 addv: InsertModeSpec = None) -> None: 2809 """Set values to the rows ⊗ col block entries of the matrix. 2810 2811 Not collective. 2812 2813 Parameters 2814 ---------- 2815 rows 2816 Block row indices. 2817 cols 2818 Block column indices. 2819 values 2820 The scalar values. A sequence of length at least 2821 ``len(rows) * len(cols) * bs * bs``, 2822 where ``bs`` is the block size of the matrix. 2823 addv 2824 Insertion mode. 2825 2826 See Also 2827 -------- 2828 petsc.MatSetValuesBlocked 2829 2830 """ 2831 matsetvalues(self.mat, rows, cols, values, addv, 1, 0) 2832 2833 def setValuesBlockedRCV(self, R, C, V, addv=None) -> None: 2834 """Undocumented.""" 2835 matsetvalues_rcv(self.mat, R, C, V, addv, 1, 0) 2836 2837 def setValuesBlockedIJV( 2838 self, 2839 I: Sequence[int], 2840 J: Sequence[int], 2841 V: Sequence[Scalar], 2842 addv: InsertModeSpec = None, 2843 rowmap: Sequence[int] | None = None) -> None: 2844 """Set a subset of values stored in block CSR format. 2845 2846 Not collective. 2847 2848 Parameters 2849 ---------- 2850 I 2851 Block row pointers. 2852 J 2853 Block column indices. 2854 V 2855 The scalar values. 2856 addv 2857 Insertion mode. 2858 rowmap 2859 Optional iterable indicating which block row to insert. 2860 2861 See Also 2862 -------- 2863 petsc.MatSetValuesBlocked 2864 2865 """ 2866 matsetvalues_ijv(self.mat, I, J, V, addv, rowmap, 1, 0) 2867 2868 def setValuesBlockedCSR( 2869 self, 2870 I: Sequence[int], 2871 J: Sequence[int], 2872 V: Sequence[Scalar], 2873 addv: InsertModeSpec = None) -> None: 2874 """Set values stored in block CSR format. 2875 2876 Not collective. 2877 2878 Parameters 2879 ---------- 2880 I 2881 Block row pointers. 2882 J 2883 Block column indices. 2884 V 2885 The scalar values. 2886 addv 2887 Insertion mode. 2888 2889 See Also 2890 -------- 2891 petsc.MatSetValuesBlocked 2892 2893 """ 2894 matsetvalues_csr(self.mat, I, J, V, addv, 1, 0) 2895 2896 def setLGMap(self, LGMap rmap, LGMap cmap=None) -> None: 2897 """Set the local-to-global mappings. 2898 2899 Collective. 2900 2901 Parameters 2902 ---------- 2903 rmap 2904 Row mapping. 2905 cmap 2906 Column mapping. If `None`, ``cmap = rmap``. 2907 2908 See Also 2909 -------- 2910 getLGMap, petsc.MatSetLocalToGlobalMapping 2911 2912 """ 2913 if cmap is None: cmap = rmap 2914 CHKERR(MatSetLocalToGlobalMapping(self.mat, rmap.lgm, cmap.lgm)) 2915 2916 def getLGMap(self) -> tuple[LGMap, LGMap]: 2917 """Return the local-to-global mappings. 2918 2919 Not collective. 2920 2921 See Also 2922 -------- 2923 setLGMap, petsc.MatGetLocalToGlobalMapping 2924 2925 """ 2926 cdef LGMap cmap = LGMap() 2927 cdef LGMap rmap = LGMap() 2928 CHKERR(MatGetLocalToGlobalMapping(self.mat, &rmap.lgm, &cmap.lgm)) 2929 CHKERR(PetscINCREF(cmap.obj)) 2930 CHKERR(PetscINCREF(rmap.obj)) 2931 return (rmap, cmap) 2932 2933 def setValueLocal( 2934 self, 2935 row: int, 2936 col: int, 2937 value: Scalar, 2938 addv: InsertModeSpec = None) -> None: 2939 """Set a value to the ``(row, col)`` entry of the matrix in local ordering. 2940 2941 Not collective. 2942 2943 Parameters 2944 ---------- 2945 row 2946 Local row index. 2947 col 2948 Local column index. 2949 value 2950 The scalar value. 2951 addv 2952 Insertion mode. 2953 2954 See Also 2955 -------- 2956 petsc.MatSetValuesLocal 2957 2958 """ 2959 cdef PetscInt ival1 = asInt(row) 2960 cdef PetscInt ival2 = asInt(col) 2961 cdef PetscScalar sval = asScalar(value) 2962 cdef PetscInsertMode caddv = insertmode(addv) 2963 CHKERR(MatSetValuesLocal( 2964 self.mat, 1, &ival1, 1, &ival2, &sval, caddv)) 2965 2966 def setValuesLocal( 2967 self, 2968 rows: Sequence[int], 2969 cols: Sequence[int], 2970 values: Sequence[Scalar], 2971 addv: InsertModeSpec = None) -> None: 2972 """Set values to the rows ⊗ col entries of the matrix in local ordering. 2973 2974 Not collective. 2975 2976 Parameters 2977 ---------- 2978 rows 2979 Local row indices. 2980 cols 2981 Local column indices. 2982 values 2983 The scalar values. A sequence of length at least ``len(rows) * len(cols)``. 2984 addv 2985 Insertion mode. 2986 2987 See Also 2988 -------- 2989 petsc.MatSetValuesLocal 2990 2991 """ 2992 matsetvalues(self.mat, rows, cols, values, addv, 0, 1) 2993 2994 def setValuesLocalRCV(self, R, C, V, addv=None) -> None: 2995 """Undocumented.""" 2996 matsetvalues_rcv(self.mat, R, C, V, addv, 0, 1) 2997 2998 def setValuesLocalIJV( 2999 self, 3000 I: Sequence[int], 3001 J: Sequence[int], 3002 V: Sequence[Scalar], 3003 addv: InsertModeSpec = None, 3004 rowmap: Sequence[int] | None = None) -> None: 3005 """Set a subset of values stored in CSR format. 3006 3007 Not collective. 3008 3009 Parameters 3010 ---------- 3011 I 3012 Row pointers. 3013 J 3014 Local column indices. 3015 V 3016 The scalar values. 3017 addv 3018 Insertion mode. 3019 rowmap 3020 Optional iterable indicating which row to insert. 3021 3022 See Also 3023 -------- 3024 petsc.MatSetValuesLocal 3025 3026 """ 3027 matsetvalues_ijv(self.mat, I, J, V, addv, rowmap, 0, 1) 3028 3029 def setValuesLocalCSR( 3030 self, 3031 I: Sequence[int], 3032 J: Sequence[int], 3033 V: Sequence[Scalar], 3034 addv: InsertModeSpec = None) -> None: 3035 """Set values stored in CSR format. 3036 3037 Not collective. 3038 3039 Parameters 3040 ---------- 3041 I 3042 Row pointers. 3043 J 3044 Local column indices. 3045 V 3046 The scalar values. 3047 addv 3048 Insertion mode. 3049 3050 See Also 3051 -------- 3052 petsc.MatSetValuesLocal 3053 3054 """ 3055 matsetvalues_csr(self.mat, I, J, V, addv, 0, 1) 3056 3057 def setValuesBlockedLocal( 3058 self, 3059 rows: Sequence[int], 3060 cols: Sequence[int], 3061 values: Sequence[Scalar], 3062 addv: InsertModeSpec = None) -> None: 3063 """Set values to the rows ⊗ col block entries of the matrix in local ordering. 3064 3065 Not collective. 3066 3067 Parameters 3068 ---------- 3069 rows 3070 Local block row indices. 3071 cols 3072 Local block column indices. 3073 values 3074 The scalar values. A sequence of length at least 3075 ``len(rows) * len(cols) * bs * bs``, 3076 where ``bs`` is the block size of the matrix. 3077 addv 3078 Insertion mode. 3079 3080 See Also 3081 -------- 3082 petsc.MatSetValuesBlockedLocal 3083 3084 """ 3085 matsetvalues(self.mat, rows, cols, values, addv, 1, 1) 3086 3087 def setValuesBlockedLocalRCV(self, R, C, V, addv=None) -> None: 3088 """Undocumented.""" 3089 matsetvalues_rcv(self.mat, R, C, V, addv, 1, 1) 3090 3091 def setValuesBlockedLocalIJV( 3092 self, 3093 I: Sequence[int], 3094 J: Sequence[int], 3095 V: Sequence[Scalar], 3096 addv: InsertModeSpec = None, 3097 rowmap: Sequence[int] | None = None) -> None: 3098 """Set a subset of values stored in block CSR format. 3099 3100 Not collective. 3101 3102 Parameters 3103 ---------- 3104 I 3105 Block row pointers. 3106 J 3107 Local block column indices. 3108 V 3109 The scalar values. 3110 addv 3111 Insertion mode. 3112 rowmap 3113 Optional iterable indicating which block row to insert. 3114 3115 See Also 3116 -------- 3117 petsc.MatSetValuesBlockedLocal 3118 3119 """ 3120 matsetvalues_ijv(self.mat, I, J, V, addv, rowmap, 1, 1) 3121 3122 def setValuesBlockedLocalCSR( 3123 self, 3124 I: Sequence[int], 3125 J: Sequence[int], 3126 V: Sequence[Scalar], 3127 addv: InsertModeSpec = None) -> None: 3128 """Set values stored in block CSR format. 3129 3130 Not collective. 3131 3132 Parameters 3133 ---------- 3134 I 3135 Block row pointers. 3136 J 3137 Local block column indices. 3138 V 3139 The scalar values. 3140 addv 3141 Insertion mode. 3142 3143 See Also 3144 -------- 3145 petsc.MatSetValuesBlockedLocal 3146 3147 """ 3148 matsetvalues_csr(self.mat, I, J, V, addv, 1, 1) 3149 3150 # 3151 3152 Stencil = MatStencil 3153 3154 def setStencil(self, dims: DimsSpec, starts: DimsSpec | None = None, dof: int = 1) -> None: 3155 """Set matrix stencil. 3156 3157 Not collective. 3158 3159 See Also 3160 -------- 3161 petsc.MatSetStencil 3162 3163 """ 3164 cdef PetscInt ndim, ndof 3165 cdef PetscInt cdims[3], cstarts[3] 3166 cdims[0] = cdims[1] = cdims[2] = 1 3167 cstarts[0] = cstarts[1] = cstarts[2] = 0 3168 ndim = asDims(dims, &cdims[0], &cdims[1], &cdims[2]) 3169 ndof = asInt(dof) 3170 if starts is not None: 3171 asDims(dims, &cstarts[0], &cstarts[1], &cstarts[2]) 3172 CHKERR(MatSetStencil(self.mat, ndim, cdims, cstarts, ndof)) 3173 3174 def setValueStencil( 3175 self, 3176 MatStencil row: Stencil, 3177 MatStencil col: Stencil, 3178 value: Sequence[Scalar], 3179 addv: InsertModeSpec = None) -> None: 3180 """Set a value to row and col stencil. 3181 3182 Not collective. 3183 3184 Parameters 3185 ---------- 3186 row 3187 Row stencil. 3188 col 3189 Column stencil. 3190 value 3191 The scalar values. 3192 addv 3193 Insertion mode. 3194 3195 See Also 3196 -------- 3197 petsc.MatSetValuesStencil 3198 3199 """ 3200 cdef MatStencil r = row, c = col 3201 cdef PetscInsertMode im = insertmode(addv) 3202 matsetvaluestencil(self.mat, r, c, value, im, 0) 3203 3204 def setValueStagStencil(self, row, col, value, addv=None) -> None: 3205 """Not implemented.""" 3206 raise NotImplementedError 3207 3208 def setValueBlockedStencil( 3209 self, 3210 row: Stencil, 3211 col: Stencil, 3212 value: Sequence[Scalar], 3213 addv: InsertModeSpec = None) -> None: 3214 """Set a block of values to row and col stencil. 3215 3216 Not collective. 3217 3218 Parameters 3219 ---------- 3220 row 3221 Row stencil. 3222 col 3223 Column stencil. 3224 value 3225 The scalar values. 3226 addv 3227 Insertion mode. 3228 3229 See Also 3230 -------- 3231 petsc.MatSetValuesBlockedStencil 3232 3233 """ 3234 cdef MatStencil r = row, c = col 3235 cdef PetscInsertMode im = insertmode(addv) 3236 matsetvaluestencil(self.mat, r, c, value, im, 1) 3237 3238 def setValueBlockedStagStencil(self, row, col, value, addv=None) -> None: 3239 """Not implemented.""" 3240 raise NotImplementedError 3241 3242 def zeroRows(self, rows: IS | Sequence[int], diag: Scalar = 1.0, Vec x=None, Vec b=None) -> None: 3243 """Zero selected rows of the matrix. 3244 3245 Collective. 3246 3247 Parameters 3248 ---------- 3249 rows 3250 Row indices to be zeroed. 3251 diag 3252 Scalar value to be inserted into the diagonal. 3253 x 3254 Optional solution vector to be modified for zeroed rows. 3255 b 3256 Optional right-hand side vector to be modified. 3257 It will be adjusted with provided solution entries. 3258 3259 See Also 3260 -------- 3261 zeroRowsLocal, petsc.MatZeroRows, petsc.MatZeroRowsIS 3262 3263 """ 3264 cdef PetscInt ni=0, *i=NULL 3265 cdef PetscScalar sval = asScalar(diag) 3266 cdef PetscVec xvec=NULL, bvec=NULL 3267 if x is not None: xvec = x.vec 3268 if b is not None: bvec = b.vec 3269 if isinstance(rows, IS): 3270 CHKERR(MatZeroRowsIS(self.mat, (<IS>rows).iset, sval, xvec, bvec)) 3271 else: 3272 rows = iarray_i(rows, &ni, &i) 3273 CHKERR(MatZeroRows(self.mat, ni, i, sval, xvec, bvec)) 3274 3275 def zeroRowsLocal(self, rows: IS | Sequence[int], diag: Scalar = 1.0, Vec x=None, Vec b=None) -> None: 3276 """Zero selected rows of the matrix in local ordering. 3277 3278 Collective. 3279 3280 Parameters 3281 ---------- 3282 rows 3283 Local row indices to be zeroed. 3284 diag 3285 Scalar value to be inserted into the diagonal. 3286 x 3287 Optional solution vector to be modified for zeroed rows. 3288 b 3289 Optional right-hand side vector to be modified. 3290 It will be adjusted with provided solution entries. 3291 3292 See Also 3293 -------- 3294 zeroRows, petsc.MatZeroRowsLocal, petsc.MatZeroRowsLocalIS 3295 3296 """ 3297 cdef PetscInt ni=0, *i=NULL 3298 cdef PetscScalar sval = asScalar(diag) 3299 cdef PetscVec xvec=NULL, bvec=NULL 3300 if x is not None: xvec = x.vec 3301 if b is not None: bvec = b.vec 3302 if isinstance(rows, IS): 3303 CHKERR(MatZeroRowsLocalIS(self.mat, (<IS>rows).iset, sval, xvec, bvec)) 3304 else: 3305 rows = iarray_i(rows, &ni, &i) 3306 CHKERR(MatZeroRowsLocal(self.mat, ni, i, sval, xvec, bvec)) 3307 3308 def zeroRowsColumns(self, rows: IS | Sequence[int], diag: Scalar = 1.0, Vec x=None, Vec b=None) -> None: 3309 """Zero selected rows and columns of the matrix. 3310 3311 Collective. 3312 3313 Parameters 3314 ---------- 3315 rows 3316 Row/column indices to be zeroed. 3317 diag 3318 Scalar value to be inserted into the diagonal. 3319 x 3320 Optional solution vector to be modified for zeroed rows. 3321 b 3322 Optional right-hand side vector to be modified. 3323 It will be adjusted with provided solution entries. 3324 3325 See Also 3326 -------- 3327 zeroRowsColumnsLocal, zeroRows, petsc.MatZeroRowsColumns 3328 petsc.MatZeroRowsColumnsIS 3329 3330 """ 3331 cdef PetscInt ni=0, *i=NULL 3332 cdef PetscScalar sval = asScalar(diag) 3333 cdef PetscVec xvec=NULL, bvec=NULL 3334 if x is not None: xvec = x.vec 3335 if b is not None: bvec = b.vec 3336 if isinstance(rows, IS): 3337 CHKERR(MatZeroRowsColumnsIS(self.mat, (<IS>rows).iset, sval, xvec, bvec)) 3338 else: 3339 rows = iarray_i(rows, &ni, &i) 3340 CHKERR(MatZeroRowsColumns(self.mat, ni, i, sval, xvec, bvec)) 3341 3342 def zeroRowsColumnsLocal(self, rows: IS | Sequence[int], diag: Scalar = 1.0, Vec x=None, Vec b=None) -> None: 3343 """Zero selected rows and columns of the matrix in local ordering. 3344 3345 Collective. 3346 3347 Parameters 3348 ---------- 3349 rows 3350 Local row/column indices to be zeroed. 3351 diag 3352 Scalar value to be inserted into the diagonal. 3353 x 3354 Optional solution vector to be modified for zeroed rows. 3355 b 3356 Optional right-hand side vector to be modified. 3357 It will be adjusted with provided solution entries. 3358 3359 See Also 3360 -------- 3361 zeroRowsLocal, zeroRowsColumns, petsc.MatZeroRowsColumnsLocal 3362 petsc.MatZeroRowsColumnsLocalIS 3363 3364 """ 3365 cdef PetscInt ni=0, *i=NULL 3366 cdef PetscScalar sval = asScalar(diag) 3367 cdef PetscVec xvec=NULL, bvec=NULL 3368 if x is not None: xvec = x.vec 3369 if b is not None: bvec = b.vec 3370 if isinstance(rows, IS): 3371 CHKERR(MatZeroRowsColumnsLocalIS(self.mat, (<IS>rows).iset, sval, xvec, bvec)) 3372 else: 3373 rows = iarray_i(rows, &ni, &i) 3374 CHKERR(MatZeroRowsColumnsLocal(self.mat, ni, i, sval, xvec, bvec)) 3375 3376 def zeroRowsColumnsStencil(self, rows: Sequence[Stencil], diag: Scalar = 1.0, Vec x=None, Vec b=None) -> None: 3377 """Zero selected rows and columns of the matrix. 3378 3379 Collective. 3380 3381 Parameters 3382 ---------- 3383 rows 3384 Iterable of stencil rows and columns. 3385 diag 3386 Scalar value to be inserted into the diagonal. 3387 x 3388 Optional solution vector to be modified for zeroed rows. 3389 b 3390 Optional right-hand side vector to be modified. 3391 It will be adjusted with provided solution entries. 3392 3393 See Also 3394 -------- 3395 zeroRowsLocal, zeroRowsColumns, petsc.MatZeroRowsColumnsStencil 3396 3397 """ 3398 cdef PetscScalar sval = asScalar(diag) 3399 cdef PetscInt nrows = asInt(len(rows)) 3400 cdef PetscMatStencil *crows = NULL 3401 CHKERR(PetscMalloc(<size_t>(nrows+1)*sizeof(PetscMatStencil), &crows)) 3402 for i in range(nrows): 3403 crows[i] = (<MatStencil?>rows[i]).stencil 3404 cdef PetscVec xvec = NULL, bvec = NULL 3405 if x is not None: xvec = x.vec 3406 if b is not None: bvec = b.vec 3407 CHKERR(MatZeroRowsColumnsStencil(self.mat, nrows, crows, sval, xvec, bvec)) 3408 CHKERR(PetscFree(crows)) 3409 3410 def storeValues(self) -> None: 3411 """Stash a copy of the matrix values. 3412 3413 Collective. 3414 3415 See Also 3416 -------- 3417 retrieveValues, petsc.MatStoreValues 3418 3419 """ 3420 CHKERR(MatStoreValues(self.mat)) 3421 3422 def retrieveValues(self) -> None: 3423 """Retrieve a copy of the matrix values previously stored with `storeValues`. 3424 3425 Collective. 3426 3427 See Also 3428 -------- 3429 storeValues, petsc.MatRetrieveValues 3430 3431 """ 3432 CHKERR(MatRetrieveValues(self.mat)) 3433 3434 def assemblyBegin(self, assembly: MatAssemblySpec = None) -> None: 3435 """Begin an assembling stage of the matrix. 3436 3437 Collective. 3438 3439 Parameters 3440 ---------- 3441 assembly 3442 The assembly type. 3443 3444 See Also 3445 -------- 3446 assemblyEnd, assemble, petsc.MatAssemblyBegin 3447 3448 """ 3449 cdef PetscMatAssemblyType flag = assemblytype(assembly) 3450 CHKERR(MatAssemblyBegin(self.mat, flag)) 3451 3452 def assemblyEnd(self, assembly: MatAssemblySpec = None) -> None: 3453 """Complete an assembling stage of the matrix initiated with `assemblyBegin`. 3454 3455 Collective. 3456 3457 Parameters 3458 ---------- 3459 assembly 3460 The assembly type. 3461 3462 See Also 3463 -------- 3464 assemblyBegin, assemble, petsc.MatAssemblyEnd 3465 3466 """ 3467 cdef PetscMatAssemblyType flag = assemblytype(assembly) 3468 CHKERR(MatAssemblyEnd(self.mat, flag)) 3469 3470 def assemble(self, assembly: MatAssemblySpec = None) -> None: 3471 """Assemble the matrix. 3472 3473 Collective. 3474 3475 Parameters 3476 ---------- 3477 assembly 3478 The assembly type. 3479 3480 See Also 3481 -------- 3482 assemblyBegin, assemblyEnd 3483 3484 """ 3485 cdef PetscMatAssemblyType flag = assemblytype(assembly) 3486 CHKERR(MatAssemblyBegin(self.mat, flag)) 3487 CHKERR(MatAssemblyEnd(self.mat, flag)) 3488 3489 def isAssembled(self) -> bool: 3490 """The boolean flag indicating if the matrix is assembled. 3491 3492 Not collective. 3493 3494 See Also 3495 -------- 3496 assemble, petsc.MatAssembled 3497 3498 """ 3499 cdef PetscBool flag = PETSC_FALSE 3500 CHKERR(MatAssembled(self.mat, &flag)) 3501 return toBool(flag) 3502 3503 def findZeroRows(self) -> IS: 3504 """Return the index set of empty rows. 3505 3506 Collective. 3507 3508 See Also 3509 -------- 3510 petsc.MatFindZeroRows 3511 3512 """ 3513 cdef IS zerorows = IS() 3514 CHKERR(MatFindZeroRows(self.mat, &zerorows.iset)) 3515 return zerorows 3516 3517 def createVecs( 3518 self, 3519 side: Literal['r', 'R', 'right', 'Right', 'RIGHT', 'l', 'L', 'left', 'Left', 'LEFT'] | None = None) -> Vec | tuple[Vec, Vec]: 3520 """Return vectors that can be used in matrix vector products. 3521 3522 Collective. 3523 3524 Parameters 3525 ---------- 3526 side 3527 If `None` returns a 2-tuple of vectors ``(right, left)``. 3528 Otherwise it just returns a left or right vector. 3529 3530 Notes 3531 ----- 3532 ``right`` is a vector that the matrix can be multiplied against. 3533 ``left`` is a vector that the matrix-vector product can be stored in. 3534 3535 See Also 3536 -------- 3537 createVecLeft, createVecRight, petsc.MatCreateVecs 3538 3539 """ 3540 cdef Vec vecr, vecl 3541 if side is None: 3542 vecr = Vec(); vecl = Vec() 3543 CHKERR(MatCreateVecs(self.mat, &vecr.vec, &vecl.vec)) 3544 return (vecr, vecl) 3545 elif side in ('r', 'R', 'right', 'Right', 'RIGHT'): 3546 vecr = Vec() 3547 CHKERR(MatCreateVecs(self.mat, &vecr.vec, NULL)) 3548 return vecr 3549 elif side in ('l', 'L', 'left', 'Left', 'LEFT'): 3550 vecl = Vec() 3551 CHKERR(MatCreateVecs(self.mat, NULL, &vecl.vec)) 3552 return vecl 3553 else: 3554 raise ValueError("side '%r' not understood" % side) 3555 3556 def createVecRight(self) -> Vec: 3557 """Return a right vector, a vector that the matrix can be multiplied against. 3558 3559 Collective. 3560 3561 See Also 3562 -------- 3563 createVecs, createVecLeft, petsc.MatCreateVecs 3564 3565 """ 3566 cdef Vec vecr = Vec() 3567 CHKERR(MatCreateVecs(self.mat, &vecr.vec, NULL)) 3568 return vecr 3569 3570 def createVecLeft(self) -> Vec: 3571 """Return a left vector, a vector that the matrix vector product can be stored in. 3572 3573 Collective. 3574 3575 See Also 3576 -------- 3577 createVecs, createVecRight, petsc.MatCreateVecs 3578 3579 """ 3580 cdef Vec vecl = Vec() 3581 CHKERR(MatCreateVecs(self.mat, NULL, &vecl.vec)) 3582 return vecl 3583 3584 getVecs = createVecs 3585 getVecRight = createVecRight 3586 getVecLeft = createVecLeft 3587 3588 # 3589 3590 def getColumnVector(self, column: int, Vec result=None) -> Vec: 3591 """Return the columnᵗʰ column vector of the matrix. 3592 3593 Collective. 3594 3595 Parameters 3596 ---------- 3597 column 3598 Column index. 3599 result 3600 Optional vector to store the result. 3601 3602 See Also 3603 -------- 3604 petsc.MatGetColumnVector 3605 3606 """ 3607 cdef PetscInt ival = asInt(column) 3608 if result is None: 3609 result = Vec() 3610 if result.vec == NULL: 3611 CHKERR(MatCreateVecs(self.mat, NULL, &result.vec)) 3612 CHKERR(MatGetColumnVector(self.mat, result.vec, ival)) 3613 return result 3614 3615 def getRedundantMatrix(self, nsubcomm: int, subcomm: Comm | None = None, Mat out=None) -> Mat: 3616 """Return redundant matrices on subcommunicators. 3617 3618 Collective. 3619 3620 Parameters 3621 ---------- 3622 nsubcomm 3623 The number of subcommunicators. 3624 subcomm 3625 Communicator split or `None` for the null communicator. 3626 out 3627 Optional resultant matrix. 3628 When `None`, a new matrix is created, and ``MAT_INITIAL_MATRIX`` is used. 3629 When not `None`, the matrix is reused with ``MAT_REUSE_MATRIX``. 3630 3631 See Also 3632 -------- 3633 petsc.MatCreateRedundantMatrix 3634 3635 """ 3636 cdef PetscInt _nsubcomm = asInt(nsubcomm) 3637 cdef MPI_Comm _subcomm = MPI_COMM_NULL 3638 if subcomm: _subcomm = def_Comm(subcomm, PETSC_COMM_DEFAULT) 3639 cdef PetscMatReuse reuse = MAT_INITIAL_MATRIX 3640 if out is None: out = Mat() 3641 if out.mat != NULL: reuse = MAT_REUSE_MATRIX 3642 CHKERR(MatCreateRedundantMatrix(self.mat, _nsubcomm, _subcomm, reuse, &out.mat)) 3643 return out 3644 3645 def getDiagonal(self, Vec result=None) -> Vec: 3646 """Return the diagonal of the matrix. 3647 3648 Collective. 3649 3650 Parameters 3651 ---------- 3652 result 3653 Optional vector to store the result. 3654 3655 See Also 3656 -------- 3657 setDiagonal, petsc.MatGetDiagonal 3658 3659 """ 3660 if result is None: 3661 result = Vec() 3662 if result.vec == NULL: 3663 CHKERR(MatCreateVecs(self.mat, NULL, &result.vec)) 3664 CHKERR(MatGetDiagonal(self.mat, result.vec)) 3665 return result 3666 3667 def getRowSum(self, Vec result=None) -> Vec: 3668 """Return the row-sum vector. 3669 3670 Collective. 3671 3672 Parameters 3673 ---------- 3674 result 3675 Optional vector to store the result. 3676 3677 See Also 3678 -------- 3679 petsc.MatGetRowSum 3680 3681 """ 3682 if result is None: 3683 result = Vec() 3684 if result.vec == NULL: 3685 CHKERR(MatCreateVecs(self.mat, NULL, &result.vec)) 3686 CHKERR(MatGetRowSum(self.mat, result.vec)) 3687 return result 3688 3689 def setDiagonal(self, Vec diag, addv: InsertModeSpec = None) -> None: 3690 """Set the diagonal values of the matrix. 3691 3692 Collective. 3693 3694 Parameters 3695 ---------- 3696 diag 3697 Vector storing diagonal values. 3698 addv 3699 Insertion mode. 3700 3701 See Also 3702 -------- 3703 getDiagonal, petsc.MatDiagonalSet 3704 3705 """ 3706 cdef PetscInsertMode caddv = insertmode(addv) 3707 CHKERR(MatDiagonalSet(self.mat, diag.vec, caddv)) 3708 3709 def diagonalScale(self, Vec L=None, Vec R=None) -> None: 3710 """Perform left and/or right diagonal scaling of the matrix. 3711 3712 Collective. 3713 3714 Parameters 3715 ---------- 3716 L 3717 Optional left scaling vector. 3718 R 3719 Optional right scaling vector. 3720 3721 See Also 3722 -------- 3723 petsc.MatDiagonalScale 3724 3725 """ 3726 cdef PetscVec vecl=NULL, vecr=NULL 3727 if L is not None: vecl = L.vec 3728 if R is not None: vecr = R.vec 3729 CHKERR(MatDiagonalScale(self.mat, vecl, vecr)) 3730 3731 def invertBlockDiagonal(self) -> ArrayScalar: 3732 """Return the inverse of the block-diagonal entries. 3733 3734 Collective. 3735 3736 See Also 3737 -------- 3738 petsc.MatInvertBlockDiagonal 3739 3740 """ 3741 cdef PetscInt bs = 0, m = 0 3742 cdef const PetscScalar *cibdiag = NULL 3743 CHKERR(MatGetBlockSize(self.mat, &bs)) 3744 CHKERR(MatGetLocalSize(self.mat, &m, NULL)) 3745 CHKERR(MatInvertBlockDiagonal(self.mat, &cibdiag)) 3746 cdef ndarray ibdiag = array_s(m*bs, cibdiag) 3747 ibdiag.shape = (toInt(m//bs), toInt(bs), toInt(bs)) 3748 return ibdiag.transpose(0, 2, 1) 3749 3750 # null space 3751 3752 def setNullSpace(self, NullSpace nsp) -> None: 3753 """Set the nullspace. 3754 3755 Collective. 3756 3757 See Also 3758 -------- 3759 getNullSpace, petsc.MatSetNullSpace 3760 3761 """ 3762 CHKERR(MatSetNullSpace(self.mat, nsp.nsp)) 3763 3764 def getNullSpace(self) -> NullSpace: 3765 """Return the nullspace. 3766 3767 Not collective. 3768 3769 See Also 3770 -------- 3771 setNullSpace, petsc.MatGetNullSpace 3772 3773 """ 3774 cdef NullSpace nsp = NullSpace() 3775 CHKERR(MatGetNullSpace(self.mat, &nsp.nsp)) 3776 CHKERR(PetscINCREF(nsp.obj)) 3777 return nsp 3778 3779 def setTransposeNullSpace(self, NullSpace nsp) -> None: 3780 """Set the transpose nullspace. 3781 3782 Collective. 3783 3784 See Also 3785 -------- 3786 setNullSpace, getTransposeNullSpace, petsc.MatSetTransposeNullSpace 3787 3788 """ 3789 CHKERR(MatSetTransposeNullSpace(self.mat, nsp.nsp)) 3790 3791 def getTransposeNullSpace(self) -> NullSpace: 3792 """Return the transpose nullspace. 3793 3794 Not collective. 3795 3796 See Also 3797 -------- 3798 getNullSpace, setTransposeNullSpace, petsc.MatGetTransposeNullSpace 3799 3800 """ 3801 cdef NullSpace nsp = NullSpace() 3802 CHKERR(MatGetTransposeNullSpace(self.mat, &nsp.nsp)) 3803 CHKERR(PetscINCREF(nsp.obj)) 3804 return nsp 3805 3806 def setNearNullSpace(self, NullSpace nsp) -> None: 3807 """Set the near-nullspace. 3808 3809 Collective. 3810 3811 See Also 3812 -------- 3813 setNullSpace, getNearNullSpace, petsc.MatSetNearNullSpace 3814 3815 """ 3816 CHKERR(MatSetNearNullSpace(self.mat, nsp.nsp)) 3817 3818 def getNearNullSpace(self) -> NullSpace: 3819 """Return the near-nullspace. 3820 3821 Not collective. 3822 3823 See Also 3824 -------- 3825 getNullSpace, setNearNullSpace, petsc.MatSetNearNullSpace 3826 3827 """ 3828 cdef NullSpace nsp = NullSpace() 3829 CHKERR(MatGetNearNullSpace(self.mat, &nsp.nsp)) 3830 CHKERR(PetscINCREF(nsp.obj)) 3831 return nsp 3832 3833 # matrix-vector product 3834 3835 def mult(self, Vec x, Vec y) -> None: 3836 """Perform the matrix vector product y = A @ x. 3837 3838 Collective. 3839 3840 Parameters 3841 ---------- 3842 x 3843 The input vector. 3844 y 3845 The output vector. 3846 3847 See Also 3848 -------- 3849 petsc.MatMult 3850 3851 """ 3852 CHKERR(MatMult(self.mat, x.vec, y.vec)) 3853 3854 def multAdd(self, Vec x, Vec v, Vec y) -> None: 3855 """Perform the matrix vector product with addition y = A @ x + v. 3856 3857 Collective. 3858 3859 Parameters 3860 ---------- 3861 x 3862 The input vector for the matrix-vector product. 3863 v 3864 The input vector to be added to. 3865 y 3866 The output vector. 3867 3868 See Also 3869 -------- 3870 petsc.MatMultAdd 3871 3872 """ 3873 CHKERR(MatMultAdd(self.mat, x.vec, v.vec, y.vec)) 3874 3875 def multTranspose(self, Vec x, Vec y) -> None: 3876 """Perform the transposed matrix vector product y = A^T @ x. 3877 3878 Collective. 3879 3880 Parameters 3881 ---------- 3882 x 3883 The input vector. 3884 y 3885 The output vector. 3886 3887 See Also 3888 -------- 3889 petsc.MatMultTranspose 3890 3891 """ 3892 CHKERR(MatMultTranspose(self.mat, x.vec, y.vec)) 3893 3894 def multTransposeAdd(self, Vec x, Vec v, Vec y) -> None: 3895 """Perform the transposed matrix vector product with addition y = A^T @ x + v. 3896 3897 Collective. 3898 3899 Parameters 3900 ---------- 3901 x 3902 The input vector for the transposed matrix-vector product. 3903 v 3904 The input vector to be added to. 3905 y 3906 The output vector. 3907 3908 See Also 3909 -------- 3910 petsc.MatMultTransposeAdd 3911 3912 """ 3913 CHKERR(MatMultTransposeAdd(self.mat, x.vec, v.vec, y.vec)) 3914 3915 def multHermitian(self, Vec x, Vec y) -> None: 3916 """Perform the Hermitian matrix vector product y = A^H @ x. 3917 3918 Collective. 3919 3920 Parameters 3921 ---------- 3922 x 3923 The input vector for the Hermitian matrix-vector product. 3924 y 3925 The output vector. 3926 3927 See Also 3928 -------- 3929 petsc.MatMultHermitianTranspose 3930 3931 """ 3932 CHKERR(MatMultHermitian(self.mat, x.vec, y.vec)) 3933 3934 def multHermitianAdd(self, Vec x, Vec v, Vec y) -> None: 3935 """Perform the Hermitian matrix vector product with addition y = A^H @ x + v. 3936 3937 Collective. 3938 3939 Parameters 3940 ---------- 3941 x 3942 The input vector for the Hermitian matrix-vector product. 3943 v 3944 The input vector to be added to. 3945 y 3946 The output vector. 3947 3948 See Also 3949 -------- 3950 petsc.MatMultHermitianTransposeAdd 3951 3952 """ 3953 CHKERR(MatMultHermitianAdd(self.mat, x.vec, v.vec, y.vec)) 3954 3955 # SOR 3956 3957 def SOR( 3958 self, 3959 Vec b, 3960 Vec x, 3961 omega: float = 1.0, 3962 sortype: SORType | None = None, 3963 shift: float = 0.0, 3964 its: int = 1, 3965 lits: int = 1) -> None: 3966 """Compute relaxation (SOR, Gauss-Seidel) sweeps. 3967 3968 Neighborwise collective. 3969 3970 See Also 3971 -------- 3972 petsc.MatSOR 3973 3974 """ 3975 cdef PetscReal comega = asReal(omega) 3976 cdef PetscMatSORType csortype = SOR_LOCAL_SYMMETRIC_SWEEP 3977 if sortype is not None: 3978 csortype = <PetscMatSORType> asInt(sortype) 3979 cdef PetscReal cshift = asReal(shift) 3980 cdef PetscInt cits = asInt(its) 3981 cdef PetscInt clits = asInt(lits) 3982 CHKERR(MatSOR(self.mat, b.vec, comega, csortype, cshift, cits, clits, x.vec)) 3983 3984 # 3985 3986 def getDiagonalBlock(self) -> Mat: 3987 """Return the part of the matrix associated with the on-process coupling. 3988 3989 Not collective. 3990 3991 See Also 3992 -------- 3993 petsc.MatGetDiagonalBlock 3994 3995 """ 3996 cdef Mat submat = Mat() 3997 CHKERR(MatGetDiagonalBlock(self.mat, &submat.mat)) 3998 CHKERR(PetscINCREF(submat.obj)) 3999 return submat 4000 4001 def increaseOverlap(self, IS iset, overlap: int = 1) -> None: 4002 """Increase the overlap of a index set. 4003 4004 Collective. 4005 4006 See Also 4007 -------- 4008 petsc.MatIncreaseOverlap 4009 4010 """ 4011 cdef PetscInt ival = asInt(overlap) 4012 CHKERR(MatIncreaseOverlap(self.mat, 1, &iset.iset, ival)) 4013 4014 def createSubMatrix(self, IS isrow, IS iscol=None, Mat submat=None) -> Mat: 4015 """Return a submatrix. 4016 4017 Collective. 4018 4019 Parameters 4020 ---------- 4021 isrow 4022 Row index set. 4023 iscol 4024 Column index set. If `None`, ``iscol = isrow``. 4025 submat 4026 Optional resultant matrix. 4027 When `None`, a new matrix is created, and ``MAT_INITIAL_MATRIX`` is used. 4028 When not `None`, the matrix is reused with ``MAT_REUSE_MATRIX``. 4029 4030 See Also 4031 -------- 4032 petsc.MatCreateSubMatrix 4033 4034 """ 4035 cdef PetscMatReuse reuse = MAT_INITIAL_MATRIX 4036 cdef PetscIS ciscol = NULL 4037 if iscol is not None: ciscol = iscol.iset 4038 if submat is None: submat = Mat() 4039 if submat.mat != NULL: reuse = MAT_REUSE_MATRIX 4040 CHKERR(MatCreateSubMatrix(self.mat, isrow.iset, ciscol, 4041 reuse, &submat.mat)) 4042 return submat 4043 4044 def createSubMatrices( 4045 self, 4046 isrows: IS | Sequence[IS], 4047 iscols: IS | Sequence[IS] | None = None, 4048 submats: Mat | Sequence[Mat] | None = None) -> Sequence[Mat]: 4049 """Return several sequential submatrices. 4050 4051 Collective. 4052 4053 Parameters 4054 ---------- 4055 isrows 4056 Row index sets. 4057 iscols 4058 Column index sets. If `None`, ``iscols = isrows``. 4059 submats 4060 Optional resultant matrices. 4061 When `None`, new matrices are created, and ``MAT_INITIAL_MATRIX`` is used. 4062 When not `None`, the matrices are reused with ``MAT_REUSE_MATRIX``. 4063 4064 See Also 4065 -------- 4066 petsc.MatCreateSubMatrices 4067 4068 """ 4069 if iscols is None: iscols = isrows 4070 isrows = [isrows] if isinstance(isrows, IS) else list(isrows) 4071 iscols = [iscols] if isinstance(iscols, IS) else list(iscols) 4072 assert len(isrows) == len(iscols) 4073 cdef Py_ssize_t i, n = len(isrows) 4074 cdef PetscMatReuse reuse = MAT_INITIAL_MATRIX 4075 cdef PetscIS *cisrows = NULL 4076 cdef PetscIS *ciscols = NULL 4077 cdef PetscMat *cmats = NULL 4078 cdef Mat mat 4079 cdef object unused1 = oarray_p(empty_p(<PetscInt>n), NULL, <void**>&cisrows) 4080 for i from 0 <= i < n: cisrows[i] = (<IS?>isrows[i]).iset 4081 cdef object unused2 = oarray_p(empty_p(<PetscInt>n), NULL, <void**>&ciscols) 4082 for i from 0 <= i < n: ciscols[i] = (<IS?>iscols[i]).iset 4083 if submats is not None: 4084 reuse = MAT_REUSE_MATRIX 4085 submats = list(submats) 4086 assert len(submats) == len(isrows) 4087 CHKERR(PetscMalloc(<size_t>(n+1)*sizeof(PetscMat), &cmats)) 4088 for i from 0 <= i < n: cmats[i] = (<Mat?>submats[i]).mat 4089 CHKERR(MatCreateSubMatrices(self.mat, <PetscInt>n, cisrows, ciscols, reuse, &cmats)) 4090 for i from 0 <= i < n: CHKERR(PetscINCREF(<PetscObject*>&cmats[i])) 4091 if reuse == MAT_INITIAL_MATRIX: 4092 submats = [None] * n 4093 for i from 0 <= i < n: 4094 submats[i] = mat = Mat() 4095 mat.mat = cmats[i] 4096 CHKERR(MatDestroyMatrices(<PetscInt>n, &cmats)) 4097 return submats 4098 4099 # 4100 4101 def createSchurComplement(self, Mat A00, Mat Ap00, Mat A01, Mat A10, Mat A11=None) -> Self: 4102 """Create a `Type.SCHURCOMPLEMENT` matrix. 4103 4104 Collective. 4105 4106 Parameters 4107 ---------- 4108 A00 4109 the upper-left block of the original matrix A = [A00 A01; A10 A11]. 4110 Ap00 4111 used to construct the preconditioner used in ksp(A00,Ap00) to 4112 approximate the action of A00^{-1}. 4113 A01 4114 the upper-right block of the original matrix A = [A00 A01; A10 A11]. 4115 A10 4116 the lower-left block of the original matrix A = [A00 A01; A10 A11]. 4117 A11 4118 Optional lower-right block of the original matrix 4119 A = [A00 A01; A10 A11]. 4120 4121 See Also 4122 -------- 4123 petsc.MatCreateSchurComplement 4124 4125 """ 4126 cdef PetscMat newmat = NULL, A11_mat = NULL 4127 if A11 is not None: 4128 A11_mat = A11.mat 4129 CHKERR(MatCreateSchurComplement(A00.mat, Ap00.mat, A01.mat, A10.mat, A11_mat, &newmat)) 4130 CHKERR(PetscCLEAR(self.obj)); self.mat = newmat 4131 return self 4132 4133 # 4134 4135 def getSchurComplementSubMatrices(self) -> tuple[Mat, Mat, Mat, Mat, Mat]: 4136 """Return Schur complement sub-matrices. 4137 4138 Collective. 4139 4140 See Also 4141 -------- 4142 petsc.MatSchurComplementGetSubMatrices 4143 4144 """ 4145 cdef Mat A00 = Mat(), Ap00 = Mat(), A01 = Mat(), A10 = Mat(), A11 = Mat() 4146 CHKERR(MatSchurComplementGetSubMatrices(self.mat, &A00.mat, &Ap00.mat, &A01.mat, &A10.mat, &A11.mat)) 4147 CHKERR(PetscINCREF(A00.obj)) 4148 CHKERR(PetscINCREF(Ap00.obj)) 4149 CHKERR(PetscINCREF(A01.obj)) 4150 CHKERR(PetscINCREF(A10.obj)) 4151 CHKERR(PetscINCREF(A11.obj)) 4152 return A00, Ap00, A01, A10, A11 4153 4154 # 4155 4156 def getLocalSubMatrix(self, IS isrow, IS iscol, Mat submat=None) -> Mat: 4157 """Return a reference to a submatrix specified in local numbering. 4158 4159 Collective. 4160 4161 Parameters 4162 ---------- 4163 isrow 4164 Row index set. 4165 iscol 4166 Column index set. 4167 submat 4168 Optional resultant matrix. 4169 When `None`, a new matrix is created. 4170 When not `None`, the matrix is first destroyed and then recreated. 4171 4172 See Also 4173 -------- 4174 restoreLocalSubMatrix, petsc.MatGetLocalSubMatrix 4175 4176 """ 4177 if submat is None: submat = Mat() 4178 else: CHKERR(MatDestroy(&submat.mat)) 4179 CHKERR(MatGetLocalSubMatrix(self.mat, isrow.iset, iscol.iset, &submat.mat)) 4180 return submat 4181 4182 def restoreLocalSubMatrix(self, IS isrow, IS iscol, Mat submat) -> None: 4183 """Restore a reference to a submatrix obtained with `getLocalSubMatrix`. 4184 4185 Collective. 4186 4187 Parameters 4188 ---------- 4189 isrow 4190 Row index set. 4191 iscol 4192 Column index set. 4193 submat 4194 The submatrix. 4195 4196 See Also 4197 -------- 4198 getLocalSubMatrix, petsc.MatRestoreLocalSubMatrix 4199 4200 """ 4201 CHKERR(MatRestoreLocalSubMatrix(self.mat, isrow.iset, iscol.iset, &submat.mat)) 4202 4203 # 4204 4205 def norm( 4206 self, 4207 norm_type: NormTypeSpec = None) -> float | tuple[float, float]: 4208 """Compute the requested matrix norm. 4209 4210 Collective. 4211 4212 A 2-tuple is returned if `NormType.NORM_1_AND_2` is specified. 4213 4214 See Also 4215 -------- 4216 petsc.MatNorm, petsc.NormType 4217 4218 """ 4219 cdef PetscNormType norm_1_2 = PETSC_NORM_1_AND_2 4220 cdef PetscNormType ntype = PETSC_NORM_FROBENIUS 4221 if norm_type is not None: ntype = norm_type 4222 cdef PetscReal rval[2] 4223 CHKERR(MatNorm(self.mat, ntype, rval)) 4224 if ntype != norm_1_2: return toReal(rval[0]) 4225 else: return (toReal(rval[0]), toReal(rval[1])) 4226 4227 def scale(self, alpha: Scalar) -> None: 4228 """Scale the matrix. 4229 4230 Collective. 4231 4232 See Also 4233 -------- 4234 petsc.MatScale 4235 4236 """ 4237 cdef PetscScalar sval = asScalar(alpha) 4238 CHKERR(MatScale(self.mat, sval)) 4239 4240 def shift(self, alpha: Scalar) -> None: 4241 """Shift the matrix. 4242 4243 Collective. 4244 4245 See Also 4246 -------- 4247 petsc.MatShift 4248 4249 """ 4250 cdef PetscScalar sval = asScalar(alpha) 4251 CHKERR(MatShift(self.mat, sval)) 4252 4253 def chop(self, tol: float) -> None: 4254 """Set entries smallest of tol (in absolute values) to zero. 4255 4256 Collective. 4257 4258 See Also 4259 -------- 4260 petsc.MatFilter 4261 4262 """ 4263 cdef PetscReal rval = asReal(tol) 4264 CHKERR(MatFilter(self.mat, rval, PETSC_FALSE, PETSC_FALSE)) 4265 4266 def setRandom(self, Random random=None) -> None: 4267 """Set random values in the matrix. 4268 4269 Collective. 4270 4271 Parameters 4272 ---------- 4273 random 4274 The random number generator object or `None` for the default. 4275 4276 See Also 4277 -------- 4278 petsc.MatSetRandom 4279 4280 """ 4281 cdef PetscRandom rnd = NULL 4282 if random is not None: rnd = random.rnd 4283 CHKERR(MatSetRandom(self.mat, rnd)) 4284 4285 def axpy(self, alpha: Scalar, Mat X, structure: Structure | None = None) -> None: 4286 """Perform the matrix summation ``self`` + = ɑ·X. 4287 4288 Collective. 4289 4290 Parameters 4291 ---------- 4292 alpha 4293 The scalar. 4294 X 4295 The matrix to be added. 4296 structure 4297 The structure of the operation. 4298 4299 See Also 4300 -------- 4301 petsc.MatAXPY 4302 4303 """ 4304 cdef PetscScalar sval = asScalar(alpha) 4305 cdef PetscMatStructure flag = matstructure(structure) 4306 CHKERR(MatAXPY(self.mat, sval, X.mat, flag)) 4307 4308 def aypx(self, alpha: Scalar, Mat X, structure: Structure | None = None) -> None: 4309 """Perform the matrix summation ``self`` = ɑ·``self`` + X. 4310 4311 Collective. 4312 4313 Parameters 4314 ---------- 4315 alpha 4316 The scalar. 4317 X 4318 The matrix to be added. 4319 structure 4320 The structure of the operation. 4321 4322 See Also 4323 -------- 4324 petsc.MatAYPX 4325 4326 """ 4327 cdef PetscScalar sval = asScalar(alpha) 4328 cdef PetscMatStructure flag = matstructure(structure) 4329 CHKERR(MatAYPX(self.mat, sval, X.mat, flag)) 4330 4331 # matrix-matrix product 4332 4333 def matMult( 4334 self, 4335 Mat mat, 4336 Mat result=None, 4337 fill: float | None = None) -> Mat: 4338 """Perform matrix-matrix multiplication C=AB. 4339 4340 Neighborwise collective. 4341 4342 Parameters 4343 ---------- 4344 mat 4345 The right hand matrix B. 4346 result 4347 The optional resultant matrix C. When `None`, a new matrix 4348 is created, and ``MAT_INITIAL_MATRIX`` is used. When C is 4349 not `None`, the matrix is reused with ``MAT_REUSE_MATRIX``. 4350 fill 4351 Expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use 4352 `None` if you do not have a good estimate. If the 4353 result is a dense matrix this is irrelevant. 4354 4355 Returns 4356 ------- 4357 result : Mat 4358 The resultant product matrix C. 4359 4360 Notes 4361 ----- 4362 To determine the correct fill value, run with -info and search 4363 for the string "Fill ratio" to see the value actually needed. 4364 4365 See Also 4366 -------- 4367 petsc.MatMatMult, petsc.MatReuse 4368 4369 """ 4370 cdef PetscMatReuse reuse = MAT_INITIAL_MATRIX 4371 cdef PetscReal rval = 2 4372 if result is None: 4373 result = Mat() 4374 elif result.mat != NULL: 4375 reuse = MAT_REUSE_MATRIX 4376 if fill is not None: rval = asReal(fill) 4377 CHKERR(MatMatMult(self.mat, mat.mat, reuse, rval, &result.mat)) 4378 return result 4379 4380 def matTransposeMult( 4381 self, 4382 Mat mat, 4383 Mat result=None, 4384 fill: float | None = None) -> Mat: 4385 """Perform matrix-matrix multiplication C=ABᵀ. 4386 4387 Neighborwise collective. 4388 4389 Parameters 4390 ---------- 4391 mat 4392 The right hand matrix B. 4393 result 4394 The optional resultant matrix C. When `None`, a new matrix 4395 is created, and ``MAT_INITIAL_MATRIX`` is used. When C is 4396 not `None`, the matrix is reused with ``MAT_REUSE_MATRIX``. 4397 fill 4398 Expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use 4399 `None` if you do not have a good estimate. If the 4400 result is a dense matrix this is irrelevant. 4401 4402 Returns 4403 ------- 4404 result : Mat 4405 The resultant product matrix C. 4406 4407 Notes 4408 ----- 4409 To determine the correct fill value, run with -info and search 4410 for the string "Fill ratio" to see the value actually needed. 4411 4412 See Also 4413 -------- 4414 petsc.MatMatTransposeMult, petsc.MatReuse 4415 4416 """ 4417 cdef PetscMatReuse reuse = MAT_INITIAL_MATRIX 4418 cdef PetscReal rval = 2 4419 if result is None: 4420 result = Mat() 4421 elif result.mat != NULL: 4422 reuse = MAT_REUSE_MATRIX 4423 if fill is not None: rval = asReal(fill) 4424 CHKERR(MatMatTransposeMult(self.mat, mat.mat, reuse, rval, &result.mat)) 4425 return result 4426 4427 def transposeMatMult( 4428 self, 4429 Mat mat, 4430 Mat result=None, 4431 fill: float | None = None) -> Mat: 4432 """Perform matrix-matrix multiplication C=AᵀB. 4433 4434 Neighborwise collective. 4435 4436 Parameters 4437 ---------- 4438 mat 4439 The right hand matrix B. 4440 result 4441 The optional resultant matrix C. When `None`, a new matrix 4442 is created, and ``MAT_INITIAL_MATRIX`` is used. When C is 4443 not `None`, the matrix is reused with ``MAT_REUSE_MATRIX``. 4444 fill 4445 Expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use 4446 `None` if you do not have a good estimate. If the 4447 result is a dense matrix this is irrelevant. 4448 4449 Returns 4450 ------- 4451 result : Mat 4452 The resultant product matrix C. 4453 4454 Notes 4455 ----- 4456 To determine the correct fill value, run with -info and search 4457 for the string "Fill ratio" to see the value actually needed. 4458 4459 See Also 4460 -------- 4461 petsc.MatTransposeMatMult, petsc.MatReuse 4462 4463 """ 4464 cdef PetscMatReuse reuse = MAT_INITIAL_MATRIX 4465 cdef PetscReal rval = 2 4466 if result is None: 4467 result = Mat() 4468 elif result.mat != NULL: 4469 reuse = MAT_REUSE_MATRIX 4470 if fill is not None: rval = asReal(fill) 4471 CHKERR(MatTransposeMatMult(self.mat, mat.mat, reuse, rval, &result.mat)) 4472 return result 4473 4474 def ptap( 4475 self, 4476 Mat P, 4477 Mat result=None, 4478 fill: float | None = None) -> Mat: 4479 """Creates the matrix product C = PᵀAP. 4480 4481 Neighborwise collective. 4482 4483 Parameters 4484 ---------- 4485 P 4486 The matrix P. 4487 result 4488 The optional resultant matrix C. When `None`, a new matrix 4489 is created, and ``MAT_INITIAL_MATRIX`` is used. When C is 4490 not `None`, the matrix is reused with ``MAT_REUSE_MATRIX``. 4491 fill 4492 Expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use 4493 `None` if you do not have a good estimate. If the 4494 result is a dense matrix this is irrelevant. 4495 4496 Returns 4497 ------- 4498 result : Mat 4499 The resultant product matrix C. 4500 4501 Notes 4502 ----- 4503 To determine the correct fill value, run with -info and search 4504 for the string "Fill ratio" to see the value actually needed. 4505 4506 An alternative approach to this function is to use 4507 `petsc.MatProductCreate` and set the desired options before the 4508 computation is done. 4509 4510 See Also 4511 -------- 4512 petsc.MatPtAP, petsc.MatReuse 4513 4514 """ 4515 cdef PetscMatReuse reuse = MAT_INITIAL_MATRIX 4516 cdef PetscReal cfill = PETSC_DEFAULT 4517 if result is None: 4518 result = Mat() 4519 elif result.mat != NULL: 4520 reuse = MAT_REUSE_MATRIX 4521 if fill is not None: cfill = asReal(fill) 4522 CHKERR(MatPtAP(self.mat, P.mat, reuse, cfill, &result.mat)) 4523 return result 4524 4525 def rart( 4526 self, 4527 Mat R, 4528 Mat result=None, 4529 fill: float | None = None) -> Mat: 4530 """Create the matrix product C = RARᵀ. 4531 4532 Neighborwise collective. 4533 4534 Parameters 4535 ---------- 4536 R 4537 The projection matrix. 4538 result 4539 The optional resultant matrix C. When `None`, a new matrix 4540 is created, and ``MAT_INITIAL_MATRIX`` is used. When C is 4541 not `None`, the matrix is reused with ``MAT_REUSE_MATRIX``. 4542 fill 4543 Expected fill as ratio of nnz(C)/nnz(A), use `None` if 4544 you do not have a good estimate. If the result is a dense 4545 matrix this is irrelevant. 4546 4547 Returns 4548 ------- 4549 result : Mat 4550 The resultant product matrix C. 4551 4552 Notes 4553 ----- 4554 To determine the correct fill value, run with -info and search 4555 for the string "Fill ratio" to see the value actually needed. 4556 4557 See Also 4558 -------- 4559 petsc.MatRARt, petsc.MatReuse 4560 4561 """ 4562 cdef PetscMatReuse reuse = MAT_INITIAL_MATRIX 4563 cdef PetscReal cfill = PETSC_DEFAULT 4564 if result is None: 4565 result = Mat() 4566 elif result.mat != NULL: 4567 reuse = MAT_REUSE_MATRIX 4568 if fill is not None: cfill = asReal(fill) 4569 CHKERR(MatRARt(self.mat, R.mat, reuse, cfill, &result.mat)) 4570 return result 4571 4572 def matMatMult( 4573 self, 4574 Mat B, 4575 Mat C, 4576 Mat result=None, 4577 fill: float | None = None) -> Mat: 4578 """Perform matrix-matrix-matrix multiplication D=ABC. 4579 4580 Neighborwise collective. 4581 4582 Parameters 4583 ---------- 4584 B 4585 The middle matrix B. 4586 C 4587 The right hand matrix C. 4588 result 4589 The optional resultant matrix D. When `None`, a new matrix 4590 is created, and ``MAT_INITIAL_MATRIX`` is used. When D is 4591 not `None`, the matrix is reused with ``MAT_REUSE_MATRIX``. 4592 fill 4593 Expected fill as ratio of nnz(C)/nnz(A), use `None` if 4594 you do not have a good estimate. If the result is a dense 4595 matrix this is irrelevant. 4596 4597 Returns 4598 ------- 4599 result : Mat 4600 The resultant product matrix D. 4601 4602 See Also 4603 -------- 4604 petsc.MatMatMatMult, petsc.MatReuse 4605 4606 """ 4607 cdef PetscMatReuse reuse = MAT_INITIAL_MATRIX 4608 cdef PetscReal cfill = PETSC_DEFAULT 4609 if result is None: 4610 result = Mat() 4611 elif result.mat != NULL: 4612 reuse = MAT_REUSE_MATRIX 4613 if fill is not None: cfill = asReal(fill) 4614 CHKERR(MatMatMatMult(self.mat, B.mat, C.mat, reuse, cfill, &result.mat)) 4615 return result 4616 4617 def kron( 4618 self, 4619 Mat mat, 4620 Mat result=None) -> Mat: 4621 """Compute C, the Kronecker product of A and B. 4622 4623 Collective. 4624 4625 Parameters 4626 ---------- 4627 mat 4628 The right hand matrix B. 4629 result 4630 The optional resultant matrix. When `None`, a new matrix 4631 is created, and ``MAT_INITIAL_MATRIX`` is used. When it is 4632 not `None`, the matrix is reused with ``MAT_REUSE_MATRIX``. 4633 4634 Returns 4635 ------- 4636 result : Mat 4637 The resultant matrix C, the Kronecker product of A and B. 4638 4639 See Also 4640 -------- 4641 petsc.MatSeqAIJKron, petsc.MatReuse 4642 4643 """ 4644 cdef PetscMatReuse reuse = MAT_INITIAL_MATRIX 4645 if result is None: 4646 result = Mat() 4647 elif result.mat != NULL: 4648 reuse = MAT_REUSE_MATRIX 4649 CHKERR(MatSeqAIJKron(self.mat, mat.mat, reuse, &result.mat)) 4650 return result 4651 4652 def bindToCPU(self, flg: bool) -> None: 4653 """Mark a matrix to temporarily stay on the CPU. 4654 4655 Collective. 4656 4657 Once marked, perform computations on the CPU. 4658 4659 Parameters 4660 ---------- 4661 flg 4662 Bind to the CPU if `True`. 4663 4664 See Also 4665 -------- 4666 petsc.MatBindToCPU 4667 4668 """ 4669 cdef PetscBool bindFlg = asBool(flg) 4670 CHKERR(MatBindToCPU(self.mat, bindFlg)) 4671 4672 def boundToCPU(self) -> bool: 4673 """Query if a matrix is bound to the CPU. 4674 4675 Not collective. 4676 4677 See Also 4678 -------- 4679 petsc.MatBoundToCPU 4680 4681 """ 4682 cdef PetscBool flg = PETSC_TRUE 4683 CHKERR(MatBoundToCPU(self.mat, &flg)) 4684 return toBool(flg) 4685 4686 # XXX factorization 4687 4688 def getOrdering(self, ord_type: OrderingType) -> tuple[IS, IS]: 4689 """Return a reordering for a matrix to improve a LU factorization. 4690 4691 Collective. 4692 4693 Parameters 4694 ---------- 4695 ord_type 4696 The type of reordering. 4697 4698 Returns 4699 ------- 4700 rp : IS 4701 The row permutation indices. 4702 cp : IS 4703 The column permutation indices. 4704 4705 See Also 4706 -------- 4707 petsc.MatGetOrdering 4708 4709 """ 4710 cdef PetscMatOrderingType cval = NULL 4711 ord_type = str2bytes(ord_type, &cval) 4712 cdef IS rp = IS(), cp = IS() 4713 CHKERR(MatGetOrdering(self.mat, cval, &rp.iset, &cp.iset)) 4714 return (rp, cp) 4715 4716 def reorderForNonzeroDiagonal( 4717 self, 4718 IS isrow, 4719 IS iscol, 4720 atol: float = 0) -> None: 4721 """Change a matrix ordering to remove zeros from the diagonal. 4722 4723 Collective. 4724 4725 Parameters 4726 ---------- 4727 isrow 4728 The row reordering. 4729 iscol 4730 The column reordering. 4731 atol 4732 The absolute tolerance. Values along the diagonal whose absolute value 4733 are smaller than this tolerance are moved off the diagonal. 4734 4735 See Also 4736 -------- 4737 getOrdering, petsc.MatReorderForNonzeroDiagonal 4738 4739 """ 4740 cdef PetscReal rval = asReal(atol) 4741 cdef PetscIS rp = isrow.iset, cp = iscol.iset 4742 CHKERR(MatReorderForNonzeroDiagonal(self.mat, rval, rp, cp)) 4743 4744 def factorLU( 4745 self, 4746 IS isrow, 4747 IS iscol, 4748 options: dict[str, Any] | None = None) -> None: 4749 """Perform an in-place LU factorization. 4750 4751 Collective. 4752 4753 Parameters 4754 ---------- 4755 isrow 4756 The row permutation. 4757 iscol 4758 The column permutation. 4759 options 4760 An optional dictionary of options for the factorization. These include 4761 ``fill``, the expected fill as a ratio of the original fill and 4762 ``dtcol``, the pivot tolerance where ``0`` indicates no pivot and ``1`` 4763 indicates full column pivoting. 4764 4765 See Also 4766 -------- 4767 petsc.MatLUFactor 4768 4769 """ 4770 cdef PetscMatFactorInfo info 4771 matfactorinfo(PETSC_FALSE, PETSC_FALSE, options, &info) 4772 CHKERR(MatLUFactor(self.mat, isrow.iset, iscol.iset, &info)) 4773 4774 def factorSymbolicLU(self, Mat mat, IS isrow, IS iscol, options=None) -> None: 4775 """Not implemented.""" 4776 raise NotImplementedError 4777 4778 def factorNumericLU(self, Mat mat, options=None) -> None: 4779 """Not implemented.""" 4780 raise NotImplementedError 4781 4782 def factorILU( 4783 self, 4784 IS isrow, 4785 IS iscol, 4786 options: dict[str, Any] | None = None) -> None: 4787 """Perform an in-place ILU factorization. 4788 4789 Collective. 4790 4791 Parameters 4792 ---------- 4793 isrow 4794 The row permutation. 4795 iscol 4796 The column permutation. 4797 options 4798 An optional dictionary of options for the factorization. These include 4799 ``levels``, the number of levels of fill, ``fill``, the expected fill 4800 as a ratio of the original fill, and ``dtcol``, the pivot tolerance 4801 where ``0`` indicates no pivot and ``1`` indicates full column pivoting. 4802 4803 See Also 4804 -------- 4805 petsc.MatILUFactor 4806 4807 """ 4808 cdef PetscMatFactorInfo info 4809 matfactorinfo(PETSC_TRUE, PETSC_FALSE, options, &info) 4810 CHKERR(MatILUFactor(self.mat, isrow.iset, iscol.iset, &info)) 4811 4812 def factorSymbolicILU(self, IS isrow, IS iscol, options=None) -> None: 4813 """Not implemented.""" 4814 raise NotImplementedError 4815 4816 def factorCholesky( 4817 self, 4818 IS isperm, 4819 options: dict[str, Any] | None = None) -> None: 4820 """Perform an in-place Cholesky factorization. 4821 4822 Collective. 4823 4824 Parameters 4825 ---------- 4826 isperm 4827 The row and column permutations. 4828 options 4829 An optional dictionary of options for the factorization. These include 4830 ``fill``, the expected fill as a ratio of the original fill. 4831 4832 See Also 4833 -------- 4834 factorLU, petsc.MatCholeskyFactor 4835 4836 """ 4837 cdef PetscMatFactorInfo info 4838 matfactorinfo(PETSC_FALSE, PETSC_TRUE, options, &info) 4839 CHKERR(MatCholeskyFactor(self.mat, isperm.iset, &info)) 4840 4841 def factorSymbolicCholesky(self, IS isperm, options=None) -> None: 4842 """Not implemented.""" 4843 raise NotImplementedError 4844 4845 def factorNumericCholesky(self, Mat mat, options=None) -> None: 4846 """Not implemented.""" 4847 raise NotImplementedError 4848 4849 def factorICC( 4850 self, 4851 IS isperm, 4852 options: dict[str, Any] | None = None) -> None: 4853 """Perform an in-place an incomplete Cholesky factorization. 4854 4855 Collective. 4856 4857 Parameters 4858 ---------- 4859 isperm 4860 The row and column permutations 4861 options 4862 An optional dictionary of options for the factorization. These include 4863 ``fill``, the expected fill as a ratio of the original fill. 4864 4865 See Also 4866 -------- 4867 factorILU, petsc.MatICCFactor 4868 4869 """ 4870 cdef PetscMatFactorInfo info 4871 matfactorinfo(PETSC_TRUE, PETSC_TRUE, options, &info) 4872 CHKERR(MatICCFactor(self.mat, isperm.iset, &info)) 4873 4874 def factorSymbolicICC(self, IS isperm, options=None) -> None: 4875 """Not implemented.""" 4876 raise NotImplementedError 4877 4878 def getInertia(self) -> tuple[int, int, int]: 4879 """Return the inertia from a factored matrix. 4880 4881 Collective. 4882 4883 The matrix must have been factored by calling `factorCholesky`. 4884 4885 Returns 4886 ------- 4887 n : int 4888 The number of negative eigenvalues. 4889 z : int 4890 The number of zero eigenvalues. 4891 p : int 4892 The number of positive eigenvalues. 4893 4894 See Also 4895 -------- 4896 petsc.MatGetInertia 4897 4898 """ 4899 cdef PetscInt ival1 = 0, ival2 = 0, ival3 = 0 4900 CHKERR(MatGetInertia(self.mat, &ival1, &ival2, &ival3)) 4901 return (toInt(ival1), toInt(ival2), toInt(ival3)) 4902 4903 def setUnfactored(self) -> None: 4904 """Set a factored matrix to be treated as unfactored. 4905 4906 Logically collective. 4907 4908 See Also 4909 -------- 4910 petsc.MatSetUnfactored 4911 4912 """ 4913 CHKERR(MatSetUnfactored(self.mat)) 4914 4915 # IS 4916 4917 def setISAllowRepeated(self, allow: bool = True) -> None: 4918 """Allow repeated entries in the local to global map. 4919 4920 Logically collective. 4921 4922 Parameters 4923 ---------- 4924 allow 4925 When `True`, local dofs are allowed to map to the same global dof. 4926 4927 See Also 4928 -------- 4929 getISAllowRepeated, petsc.MatISSetAllowRepeated 4930 4931 """ 4932 cdef PetscBool callow = asBool(allow) 4933 CHKERR(MatISSetAllowRepeated(self.mat, callow)) 4934 4935 def getISAllowRepeated(self) -> bool: 4936 """Get the flag for repeated entries in the local to global map. 4937 4938 Not collective. 4939 4940 See Also 4941 -------- 4942 setISAllowRepeated, petsc.MatISGetAllowRepeated 4943 4944 """ 4945 cdef PetscBool callow = PETSC_FALSE 4946 CHKERR(MatISGetAllowRepeated(self.mat, &callow)) 4947 return asBool(callow) 4948 4949 def fixISLocalEmpty(self, fix: bool = True) -> None: 4950 """Compress out zero local rows from the local matrices. 4951 4952 Collective. 4953 4954 Parameters 4955 ---------- 4956 fix 4957 When `True`, new local matrices and local to global maps are generated 4958 during the final assembly process. 4959 4960 See Also 4961 -------- 4962 petsc.MatISFixLocalEmpty 4963 4964 """ 4965 cdef PetscBool cfix = asBool(fix) 4966 CHKERR(MatISFixLocalEmpty(self.mat, cfix)) 4967 4968 def getISLocalMat(self) -> Mat: 4969 """Return the local matrix stored inside a `Type.IS` matrix. 4970 4971 Not collective. 4972 4973 See Also 4974 -------- 4975 petsc.MatISGetLocalMat 4976 4977 """ 4978 cdef Mat local = Mat() 4979 CHKERR(MatISGetLocalMat(self.mat, &local.mat)) 4980 CHKERR(PetscINCREF(local.obj)) 4981 return local 4982 4983 def restoreISLocalMat(self, Mat local not None) -> None: 4984 """Restore the local matrix obtained with `getISLocalMat`. 4985 4986 Not collective. 4987 4988 Parameters 4989 ---------- 4990 local 4991 The local matrix. 4992 4993 See Also 4994 -------- 4995 petsc.MatISRestoreLocalMat 4996 4997 """ 4998 CHKERR(MatISRestoreLocalMat(self.mat, &local.mat)) 4999 5000 def setISLocalMat(self, Mat local not None) -> None: 5001 """Set the local matrix stored inside a `Type.IS`. 5002 5003 Not collective. 5004 5005 Parameters 5006 ---------- 5007 local 5008 The local matrix. 5009 5010 See Also 5011 -------- 5012 petsc.MatISSetLocalMat 5013 5014 """ 5015 CHKERR(MatISSetLocalMat(self.mat, local.mat)) 5016 5017 def setISPreallocation( 5018 self, 5019 nnz: Sequence[int], 5020 onnz: Sequence[int]) -> Self: 5021 """Preallocate memory for a `Type.IS` parallel matrix. 5022 5023 Collective. 5024 5025 Parameters 5026 ---------- 5027 nnz 5028 The sequence whose length corresponds to the number of local rows 5029 and values which represent the number of nonzeros in the various 5030 rows of the *diagonal* of the local submatrix. 5031 onnz: 5032 The sequence whose length corresponds to the number of local rows 5033 and values which represent the number of nonzeros in the various 5034 rows of the *off-diagonal* of the local submatrix. 5035 5036 See Also 5037 -------- 5038 petsc.MatISSetPreallocation 5039 5040 """ 5041 cdef PetscInt *cnnz = NULL 5042 cdef PetscInt *connz = NULL 5043 nnz = iarray_i(nnz, NULL, &cnnz) 5044 onnz = iarray_i(onnz, NULL, &connz) 5045 CHKERR(MatISSetPreallocation(self.mat, 0, cnnz, 0, connz)) 5046 return self 5047 5048 # LRC 5049 5050 def getLRCMats(self) -> tuple[Mat, Mat, Vec, Mat]: 5051 """Return the constituents of a `Type.LRC` matrix. 5052 5053 Not collective. 5054 5055 Returns 5056 ------- 5057 A : Mat 5058 The ``A`` matrix. 5059 U : Mat 5060 The first dense rectangular matrix. 5061 c : Vec 5062 The sequential vector containing the diagonal of ``C``. 5063 V : Mat 5064 The second dense rectangular matrix. 5065 5066 See Also 5067 -------- 5068 petsc.MatLRCGetMats 5069 5070 """ 5071 cdef Mat A = Mat() 5072 cdef Mat U = Mat() 5073 cdef Vec c = Vec() 5074 cdef Mat V = Mat() 5075 CHKERR(MatLRCGetMats(self.mat, &A.mat, &U.mat, &c.vec, &V.mat)) 5076 CHKERR(PetscINCREF(A.obj)) 5077 CHKERR(PetscINCREF(U.obj)) 5078 CHKERR(PetscINCREF(c.obj)) 5079 CHKERR(PetscINCREF(V.obj)) 5080 return (A, U, c, V) 5081 5082 def setLRCMats(self, Mat A, Mat U, Vec c=None, Mat V=None) -> None: 5083 """Set the constituents of a `Type.LRC` matrix. 5084 5085 Logically collective. 5086 5087 Parameters 5088 ---------- 5089 A : Mat 5090 The ``A`` matrix, or `None` to omit ``A``. 5091 U : Mat 5092 The first dense rectangular matrix. 5093 c : Vec 5094 The sequential vector containing the diagonal of ``C``, 5095 or `None` for all ones. 5096 V : Mat 5097 The second dense rectangular matrix, or `None` for a copy of ``U``. 5098 5099 See Also 5100 -------- 5101 petsc.MatLRCSetMats 5102 5103 """ 5104 cdef PetscMat Amat = A.mat if A is not None else <PetscMat>NULL 5105 cdef PetscVec cvec = c.vec if c is not None else <PetscVec>NULL 5106 cdef PetscMat Vmat = V.mat if V is not None else <PetscMat>NULL 5107 CHKERR(MatLRCSetMats(self.mat, Amat, U.mat, cvec, Vmat)) 5108 5109 # H2Opus 5110 5111 def H2OpusOrthogonalize(self) -> Self: 5112 """Orthogonalize the basis tree of a hierarchical matrix. 5113 5114 Collective. 5115 5116 See Also 5117 -------- 5118 petsc.MatH2OpusOrthogonalize 5119 5120 """ 5121 CHKERR(MatH2OpusOrthogonalize(self.mat)) 5122 return self 5123 5124 def H2OpusCompress(self, tol: float) -> Self: 5125 """Compress a hierarchical matrix. 5126 5127 Collective. 5128 5129 Parameters 5130 ---------- 5131 tol 5132 The absolute truncation threshold. 5133 5134 See Also 5135 -------- 5136 petsc.MatH2OpusCompress 5137 5138 """ 5139 cdef PetscReal _tol = asReal(tol) 5140 CHKERR(MatH2OpusCompress(self.mat, _tol)) 5141 return self 5142 5143 def H2OpusLowRankUpdate(self, Mat U, Mat V=None, s: float = 1.0) -> Self: 5144 """Perform a low-rank update of the form ``self`` += sUVᵀ. 5145 5146 Collective. 5147 5148 Parameters 5149 ---------- 5150 U 5151 The dense low-rank update matrix. 5152 V 5153 The dense low-rank update matrix. If `None`, ``V = U``. 5154 s 5155 The scaling factor. 5156 5157 See Also 5158 -------- 5159 petsc.MatH2OpusLowRankUpdate 5160 5161 """ 5162 cdef PetscScalar _s = asScalar(s) 5163 cdef PetscMat vmat = NULL 5164 if V is not None: 5165 vmat = V.mat 5166 CHKERR(MatH2OpusLowRankUpdate(self.mat, U.mat, vmat, _s)) 5167 return self 5168 5169 # LMVM 5170 5171 def getLMVMJ0(self) -> Mat: 5172 """Get the initial Jacobian of the LMVM matrix. 5173 5174 Not collective. 5175 5176 See Also 5177 -------- 5178 setLMVMJ0, petsc.MatLMVMGetJ0 5179 """ 5180 cdef Mat M = Mat() 5181 CHKERR(MatLMVMGetJ0(self.mat, &M.mat)) 5182 CHKERR(PetscINCREF(M.obj)) 5183 return M 5184 5185 def setLMVMJ0(self, Mat J0) -> None: 5186 """Set the initial Jacobian of the LMVM matrix. 5187 5188 Logically collective. 5189 5190 Parameters 5191 ---------- 5192 J0: 5193 The initial Jacobian matrix. 5194 5195 See Also 5196 -------- 5197 getLMVMJ0, petsc.MatLMVMSetJ0 5198 """ 5199 cdef PetscMat ctype = J0.mat 5200 CHKERR(MatLMVMSetJ0(self.mat, ctype)) 5201 5202 def getLMVMJ0KSP(self) -> Mat: 5203 """Get the KSP of the LMVM matrix. 5204 5205 Not collective. 5206 5207 See Also 5208 -------- 5209 setLMVMJ0KSP, petsc.MatLMVMGetJ0KSP 5210 """ 5211 cdef KSP ksp = KSP() 5212 CHKERR(MatLMVMGetJ0KSP(self.mat, &ksp.ksp)) 5213 CHKERR(PetscINCREF(ksp.obj)) 5214 return ksp 5215 5216 def setLMVMJ0KSP(self, KSP ksp) -> None: 5217 """Set the KSP of the LMVM matrix. 5218 5219 Logically collective. 5220 5221 Parameters 5222 ---------- 5223 ksp: 5224 The KSP. 5225 5226 See Also 5227 -------- 5228 getLMVMJ0KSP, petsc.MatLMVMSetJ0KSP 5229 """ 5230 cdef PetscKSP ctype = ksp.ksp 5231 CHKERR(MatLMVMSetJ0KSP(self.mat, ctype)) 5232 5233 def allocateLMVM(self, Vec x, Vec f) -> None: 5234 """Allocate all necessary common memory LMVM matrix. 5235 5236 Logically collective. 5237 5238 Parameters 5239 ---------- 5240 x: 5241 Solution vector. 5242 f: 5243 Function vector. 5244 5245 See Also 5246 -------- 5247 petsc.MatLMVMAllocate 5248 """ 5249 cdef PetscVec xvec = x.vec 5250 cdef PetscVec fvec = f.vec 5251 CHKERR(MatLMVMAllocate(self.mat, xvec, fvec)) 5252 5253 def updateLMVM(self, Vec x, Vec f) -> None: 5254 """Adds (X-Xprev) and (F-Fprev) updates to LMVM matrix. 5255 5256 Logically collective. 5257 5258 Parameters 5259 ---------- 5260 x: 5261 Solution vector. 5262 f: 5263 Function vector. 5264 5265 See Also 5266 -------- 5267 petsc.MatLMVMUpdate 5268 """ 5269 cdef PetscVec xvec = x.vec 5270 cdef PetscVec fvec = f.vec 5271 CHKERR(MatLMVMUpdate(self.mat, xvec, fvec)) 5272 5273 def resetLMVM(self, destructive: bool = False) -> None: 5274 """Flushes all of the accumulated updates out of the LMVM matrix. 5275 5276 Logically collective. 5277 5278 Parameters 5279 ---------- 5280 destructive: 5281 Flag for enabling destruction of data structures. 5282 5283 See Also 5284 -------- 5285 petsc.MatLMVMReset 5286 """ 5287 cdef PetscBool cdestructive = asBool(destructive) 5288 CHKERR(MatLMVMReset(self.mat, cdestructive)) 5289 5290 # MUMPS 5291 5292 def setMumpsIcntl(self, icntl: int, ival: int) -> None: 5293 """Set a MUMPS parameter, ``ICNTL[icntl] = ival``. 5294 5295 Logically collective. 5296 5297 Parameters 5298 ---------- 5299 icntl 5300 The index of the MUMPS parameter array. 5301 ival 5302 The value to set. 5303 5304 See Also 5305 -------- 5306 petsc_options, petsc.MatMumpsSetIcntl 5307 5308 """ 5309 cdef PetscInt _icntl = asInt(icntl) 5310 cdef PetscInt _ival = asInt(ival) 5311 CHKERR(MatMumpsSetIcntl(self.mat, _icntl, _ival)) 5312 5313 def getMumpsIcntl(self, icntl: int) -> int: 5314 """Return the MUMPS parameter, ``ICNTL[icntl]``. 5315 5316 Logically collective. 5317 5318 See Also 5319 -------- 5320 petsc_options, petsc.MatMumpsGetIcntl 5321 5322 """ 5323 cdef PetscInt _icntl = asInt(icntl) 5324 cdef PetscInt ival = 0 5325 CHKERR(MatMumpsGetIcntl(self.mat, _icntl, &ival)) 5326 return toInt(ival) 5327 5328 def setMumpsCntl(self, icntl: int, val: float) -> None: 5329 """Set a MUMPS parameter, ``CNTL[icntl] = val``. 5330 5331 Logically collective. 5332 5333 Parameters 5334 ---------- 5335 icntl 5336 The index of the MUMPS parameter array. 5337 val 5338 The value to set. 5339 5340 See Also 5341 -------- 5342 petsc_options, petsc.MatMumpsSetCntl 5343 5344 """ 5345 cdef PetscInt _icntl = asInt(icntl) 5346 cdef PetscReal _val = asReal(val) 5347 CHKERR(MatMumpsSetCntl(self.mat, _icntl, _val)) 5348 5349 def getMumpsCntl(self, icntl: int) -> float: 5350 """Return the MUMPS parameter, ``CNTL[icntl]``. 5351 5352 Logically collective. 5353 5354 See Also 5355 -------- 5356 petsc_options, petsc.MatMumpsGetCntl 5357 5358 """ 5359 cdef PetscInt _icntl = asInt(icntl) 5360 cdef PetscReal val = 0 5361 CHKERR(MatMumpsGetCntl(self.mat, _icntl, &val)) 5362 return toReal(val) 5363 5364 def getMumpsInfo(self, icntl: int) -> int: 5365 """Return the MUMPS parameter, ``INFO[icntl]``. 5366 5367 Logically collective. 5368 5369 Parameters 5370 ---------- 5371 icntl 5372 The index of the MUMPS INFO array. 5373 5374 See Also 5375 -------- 5376 petsc.MatMumpsGetInfo 5377 5378 """ 5379 cdef PetscInt _icntl = asInt(icntl) 5380 cdef PetscInt ival = 0 5381 CHKERR(MatMumpsGetInfo(self.mat, _icntl, &ival)) 5382 return toInt(ival) 5383 5384 def getMumpsInfog(self, icntl: int) -> int: 5385 """Return the MUMPS parameter, ``INFOG[icntl]``. 5386 5387 Logically collective. 5388 5389 Parameters 5390 ---------- 5391 icntl 5392 The index of the MUMPS INFOG array. 5393 5394 See Also 5395 -------- 5396 petsc.MatMumpsGetInfog 5397 5398 """ 5399 cdef PetscInt _icntl = asInt(icntl) 5400 cdef PetscInt ival = 0 5401 CHKERR(MatMumpsGetInfog(self.mat, _icntl, &ival)) 5402 return toInt(ival) 5403 5404 def getMumpsRinfo(self, icntl: int) -> float: 5405 """Return the MUMPS parameter, ``RINFO[icntl]``. 5406 5407 Logically collective. 5408 5409 Parameters 5410 ---------- 5411 icntl 5412 The index of the MUMPS RINFO array. 5413 5414 See Also 5415 -------- 5416 petsc.MatMumpsGetRinfo 5417 5418 """ 5419 cdef PetscInt _icntl = asInt(icntl) 5420 cdef PetscReal val = 0 5421 CHKERR(MatMumpsGetRinfo(self.mat, _icntl, &val)) 5422 return toReal(val) 5423 5424 def getMumpsRinfog(self, icntl: int) -> float: 5425 """Return the MUMPS parameter, ``RINFOG[icntl]``. 5426 5427 Logically collective. 5428 5429 Parameters 5430 ---------- 5431 icntl 5432 The index of the MUMPS RINFOG array. 5433 5434 See Also 5435 -------- 5436 petsc.MatMumpsGetRinfog 5437 5438 """ 5439 cdef PetscInt _icntl = asInt(icntl) 5440 cdef PetscReal val = 0 5441 CHKERR(MatMumpsGetRinfog(self.mat, _icntl, &val)) 5442 return toReal(val) 5443 5444 # solve 5445 5446 def solveForward(self, Vec b, Vec x) -> None: 5447 """Solve Lx = b, given a factored matrix A = LU. 5448 5449 Neighborwise collective. 5450 5451 Parameters 5452 ---------- 5453 b 5454 The right-hand side vector. 5455 x 5456 The output solution vector. 5457 5458 See Also 5459 -------- 5460 petsc.MatForwardSolve 5461 5462 """ 5463 CHKERR(MatForwardSolve(self.mat, b.vec, x.vec)) 5464 5465 def solveBackward(self, Vec b, Vec x) -> None: 5466 """Solve Ux=b, given a factored matrix A=LU. 5467 5468 Neighborwise collective. 5469 5470 Parameters 5471 ---------- 5472 b 5473 The right-hand side vector. 5474 x 5475 The output solution vector. 5476 5477 See Also 5478 -------- 5479 petsc.MatBackwardSolve 5480 5481 """ 5482 CHKERR(MatBackwardSolve(self.mat, b.vec, x.vec)) 5483 5484 def solve(self, Vec b, Vec x) -> None: 5485 """Solve Ax=b, given a factored matrix. 5486 5487 Neighborwise collective. 5488 5489 The vectors ``b`` and ``x`` cannot be the same. 5490 Most users should employ the `KSP` interface for linear solvers instead 5491 of working directly with matrix algebra routines. 5492 5493 Parameters 5494 ---------- 5495 b 5496 The right-hand side vector. 5497 x 5498 The output solution vector, must be different than ``b``. 5499 5500 See Also 5501 -------- 5502 KSP.create, solveTranspose, petsc.MatSolve 5503 5504 """ 5505 CHKERR(MatSolve(self.mat, b.vec, x.vec)) 5506 5507 def solveTranspose(self, Vec b, Vec x) -> None: 5508 """Solve Aᵀx=b, given a factored matrix. 5509 5510 Neighborwise collective. 5511 5512 The vectors ``b`` and ``x`` cannot be the same. 5513 5514 Parameters 5515 ---------- 5516 b 5517 The right-hand side vector. 5518 x 5519 The output solution vector, must be different than ``b``. 5520 5521 See Also 5522 -------- 5523 KSP.create, petsc.MatSolve, petsc.MatSolveTranspose 5524 5525 """ 5526 CHKERR(MatSolveTranspose(self.mat, b.vec, x.vec)) 5527 5528 def solveAdd(self, Vec b, Vec y, Vec x) -> None: 5529 """Solve x=y+A⁻¹b, given a factored matrix. 5530 5531 Neighborwise collective. 5532 5533 The vectors ``b`` and ``x`` cannot be the same. 5534 5535 Parameters 5536 ---------- 5537 b 5538 The right-hand side vector. 5539 y 5540 The vector to be added 5541 x 5542 The output solution vector, must be different than ``b``. 5543 5544 See Also 5545 -------- 5546 KSP.create, petsc.MatSolve, petsc.MatSolveAdd 5547 5548 """ 5549 CHKERR(MatSolveAdd(self.mat, b.vec, y.vec, x.vec)) 5550 5551 def solveTransposeAdd(self, Vec b, Vec y, Vec x) -> None: 5552 """Solve x=y+A⁻ᵀb, given a factored matrix. 5553 5554 Neighborwise collective. 5555 5556 The vectors ``b`` and ``x`` cannot be the same. 5557 5558 Parameters 5559 ---------- 5560 b 5561 The right-hand side vector. 5562 y 5563 The vector to be added 5564 x 5565 The output solution vector, must be different than ``b``. 5566 5567 See Also 5568 -------- 5569 KSP.create, petsc.MatSolve, petsc.MatSolveTransposeAdd 5570 5571 """ 5572 CHKERR(MatSolveTransposeAdd(self.mat, b.vec, y.vec, x.vec)) 5573 5574 def matSolve(self, Mat B, Mat X) -> None: 5575 """Solve AX=B, given a factored matrix A. 5576 5577 Neighborwise collective. 5578 5579 Parameters 5580 ---------- 5581 B 5582 The right-hand side matrix of type `Type.DENSE`. Can be of type 5583 `Type.AIJ` if using MUMPS. 5584 X 5585 The output solution matrix, must be different than ``B``. 5586 5587 See Also 5588 -------- 5589 KSP.create, petsc.MatMatSolve 5590 5591 """ 5592 CHKERR(MatMatSolve(self.mat, B.mat, X.mat)) 5593 5594 # dense matrices 5595 5596 def setDenseLDA(self, lda: int) -> None: 5597 """Set the leading dimension of the array used by the dense matrix. 5598 5599 Not collective. 5600 5601 Parameters 5602 ---------- 5603 lda 5604 The leading dimension. 5605 5606 See Also 5607 -------- 5608 petsc.MatDenseSetLDA 5609 5610 """ 5611 cdef PetscInt _ilda = asInt(lda) 5612 CHKERR(MatDenseSetLDA(self.mat, _ilda)) 5613 5614 def getDenseLDA(self) -> int: 5615 """Return the leading dimension of the array used by the dense matrix. 5616 5617 Not collective. 5618 5619 See Also 5620 -------- 5621 petsc.MatDenseGetLDA 5622 5623 """ 5624 cdef PetscInt lda=0 5625 CHKERR(MatDenseGetLDA(self.mat, &lda)) 5626 return toInt(lda) 5627 5628 def getDenseArray(self, readonly: bool = False) -> ArrayScalar: 5629 """Return the array where the data is stored. 5630 5631 Not collective. 5632 5633 Parameters 5634 ---------- 5635 readonly 5636 Enable to obtain a read only array. 5637 5638 See Also 5639 -------- 5640 petsc.MatDenseGetArrayRead, petsc.MatDenseGetArray 5641 5642 """ 5643 cdef PetscInt m=0, N=0, lda=0 5644 cdef PetscScalar *data = NULL 5645 CHKERR(MatGetLocalSize(self.mat, &m, NULL)) 5646 CHKERR(MatGetSize(self.mat, NULL, &N)) 5647 CHKERR(MatDenseGetLDA(self.mat, &lda)) 5648 if readonly: 5649 CHKERR(MatDenseGetArrayRead(self.mat, <const PetscScalar**>&data)) 5650 else: 5651 CHKERR(MatDenseGetArray(self.mat, &data)) 5652 cdef int typenum = NPY_PETSC_SCALAR 5653 cdef int itemsize = <int>sizeof(PetscScalar) 5654 cdef int flags = NPY_ARRAY_FARRAY_RO if readonly else NPY_ARRAY_FARRAY 5655 cdef npy_intp dims[2], strides[2] 5656 dims[0] = <npy_intp>m; strides[0] = <npy_intp>sizeof(PetscScalar) 5657 dims[1] = <npy_intp>N; strides[1] = <npy_intp>(lda*sizeof(PetscScalar)) 5658 cdef ndarray array = PyArray_New(<PyTypeObject*>ndarray, 2, 5659 dims, typenum, strides, 5660 data, itemsize, flags, NULL) 5661 Py_INCREF(<PyObject*>self) 5662 PyArray_SetBaseObject(array, self) 5663 if readonly: 5664 CHKERR(MatDenseRestoreArrayRead(self.mat, <const PetscScalar**>&data)) 5665 else: 5666 CHKERR(MatDenseRestoreArray(self.mat, &data)) 5667 return array 5668 5669 def getDenseLocalMatrix(self) -> Mat: 5670 """Return the local part of the dense matrix. 5671 5672 Not collective. 5673 5674 See Also 5675 -------- 5676 petsc.MatDenseGetLocalMatrix 5677 5678 """ 5679 cdef Mat mat = type(self)() 5680 CHKERR(MatDenseGetLocalMatrix(self.mat, &mat.mat)) 5681 CHKERR(PetscINCREF(mat.obj)) 5682 return mat 5683 5684 def getDenseSubMatrix(self, 5685 rbegin: int = DECIDE, 5686 rend: int = DECIDE, 5687 cbegin: int = DECIDE, 5688 cend: int = DECIDE) -> Mat: 5689 """Get access to a submatrix of a `Type.DENSE` matrix. 5690 5691 Collective. 5692 5693 Parameters 5694 ---------- 5695 rbegin 5696 the first global row index. 5697 rend 5698 the global row index past the last one. 5699 cbegin 5700 the first global column index. 5701 cend 5702 the global column index past the last one. 5703 5704 See Also 5705 -------- 5706 restoreDenseSubMatrix, petsc.MatDenseGetSubMatrix 5707 5708 """ 5709 cdef Mat mat = type(self)() 5710 cdef PetscInt crbegin = asInt(rbegin) 5711 cdef PetscInt crend = asInt(rend) 5712 cdef PetscInt ccbegin = asInt(cbegin) 5713 cdef PetscInt ccend = asInt(cend) 5714 CHKERR(MatDenseGetSubMatrix(self.mat, crbegin, crend, ccbegin, ccend, &mat.mat)) 5715 CHKERR(PetscINCREF(mat.obj)) 5716 return mat 5717 5718 def restoreDenseSubMatrix(self, Mat mat) -> None: 5719 """Restore access to a submatrix of a `Type.DENSE` matrix. 5720 5721 Collective. 5722 5723 Parameters 5724 ---------- 5725 mat 5726 the matrix obtained from `getDenseSubMatrix`. 5727 5728 See Also 5729 -------- 5730 getDenseSubMatrix, petsc.MatDenseRestoreSubMatrix 5731 5732 """ 5733 cdef PetscMat v = mat.mat 5734 CHKERR(MatDenseRestoreSubMatrix(self.mat, &v)) 5735 CHKERR(PetscCLEAR(mat.obj)) 5736 5737 def getDenseColumnVec(self, i: int, mode: AccessModeSpec = 'rw') -> Vec: 5738 """Return the iᵗʰ column vector of the dense matrix. 5739 5740 Collective. 5741 5742 Parameters 5743 ---------- 5744 i 5745 The column index to access. 5746 mode 5747 The access type of the vector to be returned. 5748 5749 See Also 5750 -------- 5751 restoreDenseColumnVec, petsc.MatDenseGetColumnVec 5752 petsc.MatDenseGetColumnVecRead, petsc.MatDenseGetColumnVecWrite 5753 5754 """ 5755 if mode is None: mode = 'rw' 5756 if mode not in ['rw', 'r', 'w']: 5757 raise ValueError("Invalid mode: expected 'rw', 'r', or 'w'") 5758 cdef Vec v = Vec() 5759 cdef PetscInt _i = asInt(i) 5760 if mode == 'rw': 5761 CHKERR(MatDenseGetColumnVec(self.mat, _i, &v.vec)) 5762 elif mode == 'r': 5763 CHKERR(MatDenseGetColumnVecRead(self.mat, _i, &v.vec)) 5764 else: 5765 CHKERR(MatDenseGetColumnVecWrite(self.mat, _i, &v.vec)) 5766 CHKERR(PetscINCREF(v.obj)) 5767 return v 5768 5769 def restoreDenseColumnVec(self, i: int, mode: AccessModeSpec = 'rw', Vec V=None) -> None: 5770 """Restore the iᵗʰ column vector of the dense matrix. 5771 5772 Collective. 5773 5774 Parameters 5775 ---------- 5776 i 5777 The column index to be restored. 5778 mode 5779 The access type of the vector to be restored. 5780 V 5781 The vector obtained from calling `getDenseColumnVec`. 5782 5783 See Also 5784 -------- 5785 getDenseColumnVec, petsc.MatDenseRestoreColumnVec 5786 petsc.MatDenseRestoreColumnVecRead, petsc.MatDenseRestoreColumnVecWrite 5787 5788 """ 5789 cdef PetscVec v = NULL 5790 if V is not None: 5791 v = V.vec 5792 cdef PetscInt _i = asInt(i) 5793 if mode == 'rw': 5794 CHKERR(MatDenseRestoreColumnVec(self.mat, _i, &v)) 5795 elif mode == 'r': 5796 CHKERR(MatDenseRestoreColumnVecRead(self.mat, _i, &v)) 5797 else: 5798 CHKERR(MatDenseRestoreColumnVecWrite(self.mat, _i, &v)) 5799 if V is not None: 5800 CHKERR(PetscCLEAR(V.obj)) 5801 5802 # Nest 5803 5804 def getNestSize(self) -> tuple[int, int]: 5805 """Return the number of rows and columns of the matrix. 5806 5807 Not collective. 5808 5809 See Also 5810 -------- 5811 petsc.MatNestGetSize 5812 5813 """ 5814 cdef PetscInt nrows = 0, ncols = 0 5815 CHKERR(MatNestGetSize(self.mat, &nrows, &ncols)) 5816 return toInt(nrows), toInt(ncols) 5817 5818 def getNestISs(self) -> tuple[list[IS], list[IS]]: 5819 """Return the index sets representing the row and column spaces. 5820 5821 Not collective. 5822 5823 See Also 5824 -------- 5825 petsc.MatNestGetISs 5826 5827 """ 5828 cdef PetscInt nrows = 0, ncols = 0 5829 cdef PetscIS *cisrows = NULL 5830 cdef PetscIS *ciscols = NULL 5831 CHKERR(MatNestGetSize(self.mat, &nrows, &ncols)) 5832 cdef object unusedr = oarray_p(empty_p(nrows), NULL, <void**>&cisrows) 5833 cdef object unusedc = oarray_p(empty_p(ncols), NULL, <void**>&ciscols) 5834 CHKERR(MatNestGetISs(self.mat, cisrows, ciscols)) 5835 isetsrows = [ref_IS(cisrows[i]) for i from 0 <= i < nrows] 5836 isetscols = [ref_IS(ciscols[i]) for i from 0 <= i < ncols] 5837 return isetsrows, isetscols 5838 5839 def getNestLocalISs(self) -> tuple[list[IS], list[IS]]: 5840 """Return the local index sets representing the row and column spaces. 5841 5842 Not collective. 5843 5844 See Also 5845 -------- 5846 petsc.MatNestGetLocalISs 5847 5848 """ 5849 cdef PetscInt nrows = 0, ncols = 0 5850 cdef PetscIS *cisrows = NULL 5851 cdef PetscIS *ciscols = NULL 5852 CHKERR(MatNestGetSize(self.mat, &nrows, &ncols)) 5853 cdef object unusedr = oarray_p(empty_p(nrows), NULL, <void**>&cisrows) 5854 cdef object unusedc = oarray_p(empty_p(ncols), NULL, <void**>&ciscols) 5855 CHKERR(MatNestGetLocalISs(self.mat, cisrows, ciscols)) 5856 isetsrows = [ref_IS(cisrows[i]) for i from 0 <= i < nrows] 5857 isetscols = [ref_IS(ciscols[i]) for i from 0 <= i < ncols] 5858 return isetsrows, isetscols 5859 5860 def getNestSubMatrix(self, i: int, j: int) -> Mat: 5861 """Return a single submatrix. 5862 5863 Not collective. 5864 5865 Parameters 5866 ---------- 5867 i 5868 The first index of the matrix within the nesting. 5869 j 5870 The second index of the matrix within the nesting. 5871 5872 See Also 5873 -------- 5874 petsc.MatNestGetSubMat 5875 5876 """ 5877 cdef Mat submat = Mat() 5878 cdef PetscInt idxm = asInt(i) 5879 cdef PetscInt jdxm = asInt(j) 5880 CHKERR(MatNestGetSubMat(self.mat, idxm, jdxm, &submat.mat)) 5881 CHKERR(PetscINCREF(submat.obj)) 5882 return submat 5883 5884 # DM 5885 5886 def getDM(self) -> DM: 5887 """Return the DM defining the data layout of the matrix. 5888 5889 Not collective. 5890 5891 See Also 5892 -------- 5893 petsc.MatGetDM 5894 5895 """ 5896 cdef PetscDM newdm = NULL 5897 CHKERR(MatGetDM(self.mat, &newdm)) 5898 cdef DM dm = subtype_DM(newdm)() 5899 dm.dm = newdm 5900 CHKERR(PetscINCREF(dm.obj)) 5901 return dm 5902 5903 def setDM(self, DM dm) -> None: 5904 """Set the DM defining the data layout of the matrix. 5905 5906 Not collective. 5907 5908 Parameters 5909 ---------- 5910 dm 5911 The `DM`. 5912 5913 See Also 5914 -------- 5915 petsc.MatSetDM 5916 5917 """ 5918 CHKERR(MatSetDM(self.mat, dm.dm)) 5919 5920 # backward compatibility 5921 5922 PtAP = ptap 5923 5924 # 5925 5926 property sizes: 5927 """Matrix local and global sizes.""" 5928 def __get__(self) -> tuple[tuple[int, int], tuple[int, int]]: 5929 return self.getSizes() 5930 5931 def __set__(self, value): 5932 self.setSizes(value) 5933 5934 property size: 5935 """Matrix global size.""" 5936 def __get__(self) -> tuple[int, int]: 5937 return self.getSize() 5938 5939 property local_size: 5940 """Matrix local size.""" 5941 def __get__(self) -> int: 5942 return self.getLocalSize() 5943 5944 property block_size: 5945 """Matrix block size.""" 5946 def __get__(self) -> int: 5947 return self.getBlockSize() 5948 5949 property block_sizes: 5950 """Matrix row and column block sizes.""" 5951 def __get__(self) -> tuple[int, int]: 5952 return self.getBlockSizes() 5953 5954 property owner_range: 5955 """Matrix local row range.""" 5956 def __get__(self) -> tuple[int, int]: 5957 return self.getOwnershipRange() 5958 5959 property owner_ranges: 5960 """Matrix row ranges.""" 5961 def __get__(self) -> ArrayInt: 5962 return self.getOwnershipRanges() 5963 5964 # 5965 5966 property assembled: 5967 """The boolean flag indicating if the matrix is assembled.""" 5968 def __get__(self) -> bool: 5969 return self.isAssembled() 5970 property symmetric: 5971 """The boolean flag indicating if the matrix is symmetric.""" 5972 def __get__(self) -> bool: 5973 return self.isSymmetric() 5974 property hermitian: 5975 """The boolean flag indicating if the matrix is Hermitian.""" 5976 def __get__(self) -> bool: 5977 return self.isHermitian() 5978 property structsymm: 5979 """The boolean flag indicating if the matrix is structurally symmetric.""" 5980 def __get__(self) -> bool: 5981 return self.isStructurallySymmetric() 5982 5983 # TODO Stream 5984 def __dlpack__(self, stream=-1): 5985 return self.toDLPack('rw') 5986 5987 def __dlpack_device__(self): 5988 (dltype, devId, _, _, _) = mat_get_dlpack_ctx(self) 5989 return (dltype, devId) 5990 5991 def toDLPack(self, mode: AccessModeSpec = 'rw') -> Any: 5992 """Return a DLPack `PyCapsule` wrapping the vector data.""" 5993 if mode is None: mode = 'rw' 5994 if mode is None: mode = 'rw' 5995 if mode not in ['rw', 'r', 'w']: 5996 raise ValueError("Invalid mode: expected 'rw', 'r', or 'w'") 5997 5998 cdef int64_t ndim = 0 5999 (device_type, device_id, ndim, shape, strides) = mat_get_dlpack_ctx(self) 6000 hostmem = (device_type == kDLCPU) 6001 6002 cdef DLManagedTensor* dlm_tensor = <DLManagedTensor*>malloc(sizeof(DLManagedTensor)) 6003 cdef DLTensor* dl_tensor = &dlm_tensor.dl_tensor 6004 cdef PetscScalar *a = NULL 6005 cdef int64_t* shape_strides = NULL 6006 dl_tensor.byte_offset = 0 6007 6008 # DLPack does not currently play well with our get/restore model 6009 # Call restore right-away and hope that the consumer will do the right thing 6010 # and not modify memory requested with read access 6011 # By restoring now, we guarantee the sanity of the ObjectState 6012 if mode == 'w': 6013 if hostmem: 6014 CHKERR(MatDenseGetArrayWrite(self.mat, <PetscScalar**>&a)) 6015 CHKERR(MatDenseRestoreArrayWrite(self.mat, NULL)) 6016 else: 6017 CHKERR(MatDenseGetArrayWriteAndMemType(self.mat, <PetscScalar**>&a, NULL)) 6018 CHKERR(MatDenseRestoreArrayWriteAndMemType(self.mat, NULL)) 6019 elif mode == 'r': 6020 if hostmem: 6021 CHKERR(MatDenseGetArrayRead(self.mat, <const PetscScalar**>&a)) 6022 CHKERR(MatDenseRestoreArrayRead(self.mat, NULL)) 6023 else: 6024 CHKERR(MatDenseGetArrayReadAndMemType(self.mat, <const PetscScalar**>&a, NULL)) 6025 CHKERR(MatDenseRestoreArrayReadAndMemType(self.mat, NULL)) 6026 else: 6027 if hostmem: 6028 CHKERR(MatDenseGetArray(self.mat, <PetscScalar**>&a)) 6029 CHKERR(MatDenseRestoreArray(self.mat, NULL)) 6030 else: 6031 CHKERR(MatDenseGetArrayAndMemType(self.mat, <PetscScalar**>&a, NULL)) 6032 CHKERR(MatDenseRestoreArrayAndMemType(self.mat, NULL)) 6033 dl_tensor.data = <void *>a 6034 6035 cdef DLContext* ctx = &dl_tensor.ctx 6036 ctx.device_type = device_type 6037 ctx.device_id = device_id 6038 shape_strides = <int64_t*>malloc(sizeof(int64_t)*2*ndim) 6039 for i in range(ndim): 6040 shape_strides[i] = shape[i] 6041 for i in range(ndim): 6042 shape_strides[i+ndim] = strides[i] 6043 dl_tensor.ndim = <int>ndim 6044 dl_tensor.shape = shape_strides 6045 dl_tensor.strides = shape_strides + ndim 6046 6047 cdef DLDataType* dtype = &dl_tensor.dtype 6048 dtype.code = <uint8_t>DLDataTypeCode.kDLFloat 6049 if sizeof(PetscScalar) == 8: 6050 dtype.bits = <uint8_t>64 6051 elif sizeof(PetscScalar) == 4: 6052 dtype.bits = <uint8_t>32 6053 else: 6054 raise ValueError('Unsupported PetscScalar type') 6055 dtype.lanes = <uint16_t>1 6056 dlm_tensor.manager_ctx = <void *>self.mat 6057 CHKERR(PetscObjectReference(<PetscObject>self.mat)) 6058 dlm_tensor.manager_deleter = manager_deleter 6059 dlm_tensor.del_obj = <dlpack_manager_del_obj>PetscDEALLOC 6060 return PyCapsule_New(dlm_tensor, 'dltensor', pycapsule_deleter) 6061 6062# -------------------------------------------------------------------- 6063 6064cdef class NullSpace(Object): 6065 """Nullspace object. 6066 6067 See Also 6068 -------- 6069 petsc.MatNullSpace 6070 6071 """ 6072 # 6073 6074 def __cinit__(self): 6075 self.obj = <PetscObject*> &self.nsp 6076 self.nsp = NULL 6077 6078 def __call__(self, vec): 6079 self.remove(vec) 6080 6081 # 6082 6083 def view(self, Viewer viewer=None) -> None: 6084 """View the null space. 6085 6086 Collective. 6087 6088 Parameters 6089 ---------- 6090 viewer 6091 A `Viewer` instance or `None` for the default viewer. 6092 6093 See Also 6094 -------- 6095 Viewer, petsc.MatNullSpaceView 6096 6097 """ 6098 cdef PetscViewer vwr = NULL 6099 if viewer is not None: vwr = viewer.vwr 6100 CHKERR(MatNullSpaceView(self.nsp, vwr)) 6101 6102 def destroy(self) -> Self: 6103 """Destroy the null space. 6104 6105 Collective. 6106 6107 See Also 6108 -------- 6109 create, petsc.MatNullSpaceDestroy 6110 6111 """ 6112 CHKERR(MatNullSpaceDestroy(&self.nsp)) 6113 return self 6114 6115 def create( 6116 self, 6117 constant: bool = False, 6118 vectors: Sequence[Vec] = (), 6119 comm=None) -> Self: 6120 """Create the null space. 6121 6122 Collective. 6123 6124 Parameters 6125 ---------- 6126 constant 6127 A flag to indicate the null space contains the constant vector. 6128 vectors 6129 The sequence of vectors that span the null space. 6130 comm 6131 MPI communicator, defaults to `Sys.getDefaultComm`. 6132 6133 See Also 6134 -------- 6135 destroy, petsc.MatNullSpaceCreate 6136 6137 """ 6138 cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) 6139 cdef PetscBool has_const = PETSC_FALSE 6140 if constant: has_const = PETSC_TRUE 6141 cdef PetscInt i = 0, nv = <PetscInt>len(vectors) 6142 cdef PetscVec *v = NULL 6143 cdef object unused2 = oarray_p(empty_p(nv), NULL, <void**>&v) 6144 for i from 0 <= i < nv: 6145 v[i] = (<Vec?>(vectors[<Py_ssize_t>i])).vec 6146 cdef PetscNullSpace newnsp = NULL 6147 CHKERR(MatNullSpaceCreate(ccomm, has_const, nv, v, &newnsp)) 6148 CHKERR(PetscCLEAR(self.obj)); self.nsp = newnsp 6149 return self 6150 6151 def createRigidBody(self, Vec coords) -> Self: 6152 """Create rigid body modes from coordinates. 6153 6154 Collective. 6155 6156 Parameters 6157 ---------- 6158 coords 6159 The block coordinates of each node. 6160 Requires the block size to have been set. 6161 6162 See Also 6163 -------- 6164 petsc.MatNullSpaceCreateRigidBody 6165 6166 """ 6167 cdef PetscNullSpace newnsp = NULL 6168 CHKERR(MatNullSpaceCreateRigidBody(coords.vec, &newnsp)) 6169 CHKERR(PetscCLEAR(self.obj)); self.nsp = newnsp 6170 return self 6171 6172 def setFunction( 6173 self, 6174 function: MatNullFunction, 6175 args: tuple[Any, ...] | None = None, 6176 kargs: dict[str, Any] | None = None) -> None: 6177 """Set the callback to remove the nullspace. 6178 6179 Logically collective. 6180 6181 Parameters 6182 ---------- 6183 function 6184 The callback. 6185 args 6186 Positional arguments for the callback. 6187 kargs 6188 Keyword arguments for the callback. 6189 6190 See Also 6191 -------- 6192 getFunction, petsc.MatNullSpaceSetFunction 6193 6194 """ 6195 if function is not None: 6196 CHKERR(MatNullSpaceSetFunction( 6197 self.nsp, NullSpace_Function, NULL)) 6198 if args is None: args = () 6199 if kargs is None: kargs = {} 6200 self.set_attr('__function__', (function, args, kargs)) 6201 else: 6202 CHKERR(MatNullSpaceSetFunction(self.nsp, NULL, NULL)) 6203 self.set_attr('__function__', None) 6204 # 6205 6206 def hasConstant(self) -> bool: 6207 """Return whether the null space contains the constant. 6208 6209 Not collective. 6210 6211 See Also 6212 -------- 6213 petsc.MatNullSpaceGetVecs 6214 6215 """ 6216 cdef PetscBool flag = PETSC_FALSE 6217 CHKERR(MatNullSpaceGetVecs(self.nsp, &flag, NULL, NULL)) 6218 return toBool(flag) 6219 6220 def getVecs(self) -> list[Vec]: 6221 """Return the vectors defining the null space. 6222 6223 Not collective. 6224 6225 See Also 6226 -------- 6227 petsc.MatNullSpaceGetVecs 6228 6229 """ 6230 cdef PetscInt i = 0, nv = 0 6231 cdef const PetscVec *v = NULL 6232 CHKERR(MatNullSpaceGetVecs(self.nsp, NULL, &nv, &v)) 6233 cdef Vec vec = None 6234 cdef list vectors = [] 6235 for i from 0 <= i < nv: 6236 vec = Vec() 6237 vec.vec = v[i] 6238 CHKERR(PetscINCREF(vec.obj)) 6239 vectors.append(vec) 6240 return vectors 6241 6242 def getFunction(self) -> MatNullFunction: 6243 """Return the callback to remove the nullspace. 6244 6245 Not collective. 6246 6247 See Also 6248 -------- 6249 setFunction 6250 6251 """ 6252 return self.get_attr('__function__') 6253 6254 # 6255 6256 def remove(self, Vec vec) -> None: 6257 """Remove all components of a null space from a vector. 6258 6259 Collective. 6260 6261 Parameters 6262 ---------- 6263 vec 6264 The vector from which the null space is removed. 6265 6266 See Also 6267 -------- 6268 petsc.MatNullSpaceRemove 6269 6270 """ 6271 CHKERR(MatNullSpaceRemove(self.nsp, vec.vec)) 6272 6273 def test(self, Mat mat) -> bool: 6274 """Return if the claimed null space is valid for a matrix. 6275 6276 Collective. 6277 6278 Parameters 6279 ---------- 6280 mat 6281 The matrix to check. 6282 6283 See Also 6284 -------- 6285 petsc.MatNullSpaceTest 6286 6287 """ 6288 cdef PetscBool flag = PETSC_FALSE 6289 CHKERR(MatNullSpaceTest(self.nsp, mat.mat, &flag)) 6290 return toBool(flag) 6291 6292# -------------------------------------------------------------------- 6293 6294del MatType 6295del MatOption 6296del MatAssemblyType 6297del MatInfoType 6298del MatStructure 6299del MatDuplicateOption 6300del MatOrderingType 6301del MatSolverType 6302del MatFactorShiftType 6303del MatSORType 6304 6305# -------------------------------------------------------------------- 6306