1# -------------------------------------------------------------------- 2 3cdef class Section(Object): 4 """Mapping from integers in a range to unstructured set of integers.""" 5 6 def __cinit__(self): 7 self.obj = <PetscObject*> &self.sec 8 self.sec = NULL 9 10 def view(self, Viewer viewer=None) -> None: 11 """View the section. 12 13 Collective. 14 15 Parameters 16 ---------- 17 viewer 18 A `Viewer` to display the section. 19 20 See Also 21 -------- 22 petsc.PetscSectionView 23 24 """ 25 cdef PetscViewer vwr = NULL 26 if viewer is not None: vwr = viewer.vwr 27 CHKERR(PetscSectionView(self.sec, vwr)) 28 29 def destroy(self) -> Self: 30 """Destroy a section. 31 32 Not collective. 33 34 See Also 35 -------- 36 petsc.PetscSectionDestroy 37 38 """ 39 CHKERR(PetscSectionDestroy(&self.sec)) 40 return self 41 42 def create(self, comm: Comm | None = None) -> Self: 43 """Allocate a section and set the map contents to the default. 44 45 Collective. 46 47 Typical calling sequence: 48 - `create` 49 - `setNumFields` 50 - `setChart` 51 - `setDof` 52 - `setUp` 53 - `getOffset` 54 - `destroy` 55 56 The `Section` object and methods are intended to be used in the PETSc 57 Vec and Mat implementations. The indices returned by the `Section` are 58 appropriate for the kind of `Vec` it is associated with. For example, 59 if the vector being indexed is a local vector, we call the section a 60 local section. If the section indexes a global vector, we call it a 61 global section. For parallel vectors, like global vectors, we use 62 negative indices to indicate DOFs owned by other processes. 63 64 Parameters 65 ---------- 66 comm 67 MPI communicator, defaults to `Sys.getDefaultComm`. 68 69 See Also 70 -------- 71 petsc.PetscSectionCreate 72 73 """ 74 cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) 75 cdef PetscSection newsec = NULL 76 CHKERR(PetscSectionCreate(ccomm, &newsec)) 77 CHKERR(PetscCLEAR(self.obj)); self.sec = newsec 78 return self 79 80 def clone(self) -> Section: 81 """Return a copy of the section. 82 83 Collective. 84 85 The copy is shallow, if possible. 86 87 See Also 88 -------- 89 petsc.PetscSectionClone 90 91 """ 92 cdef Section sec = <Section>type(self)() 93 CHKERR(PetscSectionClone(self.sec, &sec.sec)) 94 return sec 95 96 def setUp(self) -> None: 97 """Calculate offsets. 98 99 Not collective. 100 101 Offsets are based on the number of degrees of freedom for each point. 102 103 See Also 104 -------- 105 petsc.PetscSectionSetUp 106 107 """ 108 CHKERR(PetscSectionSetUp(self.sec)) 109 110 def reset(self) -> None: 111 """Free all section data. 112 113 Not collective. 114 115 See Also 116 -------- 117 petsc.PetscSectionReset 118 119 """ 120 CHKERR(PetscSectionReset(self.sec)) 121 122 def getNumFields(self) -> int: 123 """Return the number of fields in a section. 124 125 Not collective. 126 127 Returns ``0`` if no fields were defined. 128 129 See Also 130 -------- 131 setNumFields, petsc.PetscSectionGetNumFields 132 133 """ 134 cdef PetscInt numFields = 0 135 CHKERR(PetscSectionGetNumFields(self.sec, &numFields)) 136 return toInt(numFields) 137 138 def setNumFields(self, numFields: int) -> None: 139 """Set the number of fields in a section. 140 141 Not collective. 142 143 Parameters 144 ---------- 145 numFields 146 The number of fields. 147 148 See Also 149 -------- 150 getNumFields, petsc.PetscSectionSetNumFields 151 152 """ 153 cdef PetscInt cnumFields = asInt(numFields) 154 CHKERR(PetscSectionSetNumFields(self.sec, cnumFields)) 155 156 def getFieldName(self, field: int) -> str: 157 """Return the name of a field in the section. 158 159 Not collective. 160 161 Parameters 162 ---------- 163 field 164 The field number. 165 166 See Also 167 -------- 168 setFieldName, petsc.PetscSectionGetFieldName 169 170 """ 171 cdef PetscInt cfield = asInt(field) 172 cdef const char *fieldName = NULL 173 CHKERR(PetscSectionGetFieldName(self.sec, cfield, &fieldName)) 174 return bytes2str(fieldName) 175 176 def setFieldName(self, field: int, fieldName: str) -> None: 177 """Set the name of a field in the section. 178 179 Not collective. 180 181 Parameters 182 ---------- 183 field 184 The field number. 185 fieldName 186 The field name. 187 188 See Also 189 -------- 190 getFieldName, petsc.PetscSectionSetFieldName 191 192 """ 193 cdef PetscInt cfield = asInt(field) 194 cdef const char *cname = NULL 195 fieldName = str2bytes(fieldName, &cname) 196 CHKERR(PetscSectionSetFieldName(self.sec, cfield, cname)) 197 198 def getFieldComponents(self, field: int) -> int: 199 """Return the number of field components for the given field. 200 201 Not collective. 202 203 Parameters 204 ---------- 205 field 206 The field number. 207 208 See Also 209 -------- 210 setFieldComponents, petsc.PetscSectionGetFieldComponents 211 212 """ 213 cdef PetscInt cfield = asInt(field), cnumComp = 0 214 CHKERR(PetscSectionGetFieldComponents(self.sec, cfield, &cnumComp)) 215 return toInt(cnumComp) 216 217 def setFieldComponents(self, field: int, numComp: int) -> None: 218 """Set the number of field components for the given field. 219 220 Not collective. 221 222 Parameters 223 ---------- 224 field 225 The field number. 226 numComp 227 The number of field components. 228 229 See Also 230 -------- 231 getFieldComponents, petsc.PetscSectionSetFieldComponents 232 233 """ 234 cdef PetscInt cfield = asInt(field) 235 cdef PetscInt cnumComp = asInt(numComp) 236 CHKERR(PetscSectionSetFieldComponents(self.sec, cfield, cnumComp)) 237 238 def getChart(self) -> tuple[int, int]: 239 """Return the range in which points (indices) lie for this section. 240 241 Not collective. 242 243 The range is [pStart, pEnd), i.e., from the first point to one past the 244 last point. 245 246 See Also 247 -------- 248 petsc.PetscSectionGetChart 249 250 """ 251 cdef PetscInt pStart = 0, pEnd = 0 252 CHKERR(PetscSectionGetChart(self.sec, &pStart, &pEnd)) 253 return toInt(pStart), toInt(pEnd) 254 255 def setChart(self, pStart: int, pEnd: int) -> None: 256 """Set the range in which points (indices) lie for this section. 257 258 Not collective. 259 260 The range is [pStart, pEnd), i.e., from the first point to one past the 261 last point. 262 263 Parameters 264 ---------- 265 pStart 266 The first point. 267 pEnd 268 One past the last point. 269 270 See Also 271 -------- 272 petsc.PetscSectionSetChart 273 274 """ 275 cdef PetscInt cStart = asInt(pStart) 276 cdef PetscInt cEnd = asInt(pEnd) 277 CHKERR(PetscSectionSetChart(self.sec, cStart, cEnd)) 278 279 def getPermutation(self) -> IS: 280 """Return the permutation that was set with `setPermutation`. 281 282 Not collective. 283 284 See Also 285 -------- 286 setPermutation, petsc.PetscSectionGetPermutation 287 288 """ 289 cdef IS perm = IS() 290 CHKERR(PetscSectionGetPermutation(self.sec, &perm.iset)) 291 CHKERR(PetscINCREF(perm.obj)) 292 return perm 293 294 def setPermutation(self, IS perm) -> None: 295 """Set the permutation for [0, pEnd - pStart). 296 297 Not collective. 298 299 Parameters 300 ---------- 301 perm 302 The permutation of points. 303 304 See Also 305 -------- 306 getPermutation, petsc.PetscSectionSetPermutation 307 308 """ 309 CHKERR(PetscSectionSetPermutation(self.sec, perm.iset)) 310 311 def getDof(self, point: int) -> int: 312 """Return the number of degrees of freedom for a given point. 313 314 Not collective. 315 316 In a global section, this value will be negative for points not owned 317 by this process. 318 319 Parameters 320 ---------- 321 point 322 The point. 323 324 See Also 325 -------- 326 setDof, addDof, petsc.PetscSectionGetDof 327 328 """ 329 cdef PetscInt cpoint = asInt(point), cnumDof = 0 330 CHKERR(PetscSectionGetDof(self.sec, cpoint, &cnumDof)) 331 return toInt(cnumDof) 332 333 def setDof(self, point: int, numDof: int) -> None: 334 """Set the number of degrees of freedom associated with a given point. 335 336 Not collective. 337 338 Parameters 339 ---------- 340 point 341 The point. 342 numDof 343 The number of DOFs. 344 345 See Also 346 -------- 347 getDof, addDof, petsc.PetscSectionSetDof 348 349 """ 350 cdef PetscInt cpoint = asInt(point) 351 cdef PetscInt cnumDof = asInt(numDof) 352 CHKERR(PetscSectionSetDof(self.sec, cpoint, cnumDof)) 353 354 def addDof(self, point: int, numDof: int) -> None: 355 """Add ``numDof`` degrees of freedom associated with a given point. 356 357 Not collective. 358 359 Parameters 360 ---------- 361 point 362 The point. 363 numDof 364 The number of additional DOFs. 365 366 See Also 367 -------- 368 setDof, getDof, petsc.PetscSectionAddDof 369 370 """ 371 cdef PetscInt cpoint = asInt(point) 372 cdef PetscInt cnumDof = asInt(numDof) 373 CHKERR(PetscSectionAddDof(self.sec, cpoint, cnumDof)) 374 375 def getFieldDof(self, point: int, field: int) -> int: 376 """Return the number of DOFs associated with a field on a given point. 377 378 Not collective. 379 380 Parameters 381 ---------- 382 point 383 The point. 384 field 385 The field. 386 387 See Also 388 -------- 389 setFieldDof, petsc.PetscSectionGetFieldDof 390 391 """ 392 cdef PetscInt cpoint = asInt(point), cnumDof = 0 393 cdef PetscInt cfield = asInt(field) 394 CHKERR(PetscSectionGetFieldDof(self.sec, cpoint, cfield, &cnumDof)) 395 return toInt(cnumDof) 396 397 def setFieldDof(self, point: int, field: int, numDof: int) -> None: 398 """Set the number of DOFs associated with a field on a given point. 399 400 Not collective. 401 402 Parameters 403 ---------- 404 point 405 The point. 406 field 407 The field. 408 numDof 409 The number of DOFs. 410 411 See Also 412 -------- 413 getFieldDof, addFieldDof, petsc.PetscSectionSetFieldDof 414 415 """ 416 cdef PetscInt cpoint = asInt(point) 417 cdef PetscInt cfield = asInt(field) 418 cdef PetscInt cnumDof = asInt(numDof) 419 CHKERR(PetscSectionSetFieldDof(self.sec, cpoint, cfield, cnumDof)) 420 421 def addFieldDof(self, point: int, field: int, numDof: int) -> None: 422 """Add ``numDof`` DOFs associated with a field on a given point. 423 424 Not collective. 425 426 Parameters 427 ---------- 428 point 429 The point. 430 field 431 The field. 432 numDof 433 The number of additional DOFs. 434 435 See Also 436 -------- 437 setFieldDof, getFieldDof, petsc.PetscSectionAddFieldDof 438 439 """ 440 cdef PetscInt cpoint = asInt(point) 441 cdef PetscInt cfield = asInt(field) 442 cdef PetscInt cnumDof = asInt(numDof) 443 CHKERR(PetscSectionAddFieldDof(self.sec, cpoint, cfield, cnumDof)) 444 445 def getConstraintDof(self, point: int) -> int: 446 """Return the number of constrained DOFs associated with a given point. 447 448 Not collective. 449 450 Parameters 451 ---------- 452 point 453 The point. 454 455 See Also 456 -------- 457 setConstraintDof, petsc.PetscSectionGetConstraintDof 458 459 """ 460 cdef PetscInt cpoint = asInt(point), cnumDof = 0 461 CHKERR(PetscSectionGetConstraintDof(self.sec, cpoint, &cnumDof)) 462 return toInt(cnumDof) 463 464 def setConstraintDof(self, point: int, numDof: int) -> None: 465 """Set the number of constrained DOFs associated with a given point. 466 467 Not collective. 468 469 Parameters 470 ---------- 471 point 472 The point. 473 numDof 474 The number of DOFs which are fixed by constraints. 475 476 See Also 477 -------- 478 getConstraintDof, addConstraintDof, petsc.PetscSectionSetConstraintDof 479 480 """ 481 cdef PetscInt cpoint = asInt(point) 482 cdef PetscInt cnumDof = asInt(numDof) 483 CHKERR(PetscSectionSetConstraintDof(self.sec, cpoint, cnumDof)) 484 485 def addConstraintDof(self, point: int, numDof: int) -> None: 486 """Increment the number of constrained DOFs for a given point. 487 488 Not collective. 489 490 Parameters 491 ---------- 492 point 493 The point. 494 numDof 495 The number of additional DOFs which are fixed by constraints. 496 497 See Also 498 -------- 499 setConstraintDof, getConstraintDof, petsc.PetscSectionAddConstraintDof 500 501 """ 502 cdef PetscInt cpoint = asInt(point) 503 cdef PetscInt cnumDof = asInt(numDof) 504 CHKERR(PetscSectionAddConstraintDof(self.sec, cpoint, cnumDof)) 505 506 def getFieldConstraintDof(self, point: int, field: int) -> int: 507 """Return the number of constrained DOFs for a given field on a point. 508 509 Not collective. 510 511 Parameters 512 ---------- 513 point 514 The point. 515 field 516 The field. 517 518 See Also 519 -------- 520 setFieldConstraintDof, petsc.PetscSectionGetFieldConstraintDof 521 522 """ 523 cdef PetscInt cpoint = asInt(point), cnumDof = 0 524 cdef PetscInt cfield = asInt(field) 525 CHKERR(PetscSectionGetFieldConstraintDof(self.sec, cpoint, cfield, &cnumDof)) 526 return toInt(cnumDof) 527 528 def setFieldConstraintDof( 529 self, 530 point: int, 531 field: int, 532 numDof: int) -> None: 533 """Set the number of constrained DOFs for a given field on a point. 534 535 Not collective. 536 537 Parameters 538 ---------- 539 point 540 The point. 541 field 542 The field. 543 numDof 544 The number of DOFs which are fixed by constraints. 545 546 See Also 547 -------- 548 getFieldConstraintDof, addFieldConstraintDof 549 petsc.PetscSectionSetFieldConstraintDof 550 551 """ 552 cdef PetscInt cpoint = asInt(point) 553 cdef PetscInt cfield = asInt(field) 554 cdef PetscInt cnumDof = asInt(numDof) 555 CHKERR(PetscSectionSetFieldConstraintDof(self.sec, cpoint, cfield, cnumDof)) 556 557 def addFieldConstraintDof( 558 self, 559 point: int, 560 field: int, 561 numDof: int) -> None: 562 """Add ``numDof`` constrained DOFs for a given field on a point. 563 564 Not collective. 565 566 Parameters 567 ---------- 568 point 569 The point. 570 field 571 The field. 572 numDof 573 The number of additional DOFs which are fixed by constraints. 574 575 See Also 576 -------- 577 setFieldConstraintDof, getFieldConstraintDof 578 petsc.PetscSectionAddFieldConstraintDof 579 580 """ 581 cdef PetscInt cpoint = asInt(point) 582 cdef PetscInt cfield = asInt(field) 583 cdef PetscInt cnumDof = asInt(numDof) 584 CHKERR(PetscSectionAddFieldConstraintDof(self.sec, cpoint, cfield, cnumDof)) 585 586 def getConstraintIndices(self, point: int) -> ArrayInt: 587 """Return the point DOFs numbers which are constrained for a given point. 588 589 Not collective. 590 591 The range is in [0, DOFs). 592 593 Parameters 594 ---------- 595 point 596 The point. 597 598 See Also 599 -------- 600 setConstraintIndices, petsc.PetscSectionGetConstraintIndices 601 602 """ 603 cdef PetscInt cpoint = asInt(point) 604 cdef PetscInt nindex = 0 605 cdef const PetscInt *indices = NULL 606 CHKERR(PetscSectionGetConstraintDof(self.sec, cpoint, &nindex)) 607 CHKERR(PetscSectionGetConstraintIndices(self.sec, cpoint, &indices)) 608 return array_i(nindex, indices) 609 610 def setConstraintIndices(self, point: int, indices: Sequence[int]) -> None: 611 """Set the point DOFs numbers, in [0, DOFs), which are constrained. 612 613 Not collective. 614 615 Parameters 616 ---------- 617 point 618 The point. 619 indices 620 The constrained DOFs. 621 622 See Also 623 -------- 624 getConstraintIndices, petsc.PetscSectionSetConstraintIndices 625 626 """ 627 cdef PetscInt cpoint = asInt(point) 628 cdef PetscInt nindex = 0 629 cdef PetscInt *cindices = NULL 630 indices = iarray_i(indices, &nindex, &cindices) 631 CHKERR(PetscSectionSetConstraintDof(self.sec, cpoint, nindex)) 632 CHKERR(PetscSectionSetConstraintIndices(self.sec, cpoint, cindices)) 633 634 def getFieldConstraintIndices(self, point: int, field: int) -> ArrayInt: 635 """Return the field DOFs numbers, in [0, DOFs), which are constrained. 636 637 Not collective. 638 639 The constrained DOFs are sorted in ascending order. 640 641 Parameters 642 ---------- 643 field 644 The field number. 645 point 646 The point. 647 648 See Also 649 -------- 650 setFieldConstraintIndices, petsc.PetscSectionGetFieldConstraintIndices 651 652 """ 653 cdef PetscInt cpoint = asInt(point) 654 cdef PetscInt cfield = asInt(field) 655 cdef PetscInt nindex = 0 656 cdef const PetscInt *indices = NULL 657 CHKERR(PetscSectionGetFieldConstraintDof(self.sec, cpoint, cfield, &nindex)) 658 CHKERR(PetscSectionGetFieldConstraintIndices(self.sec, cpoint, cfield, &indices)) 659 return array_i(nindex, indices) 660 661 def setFieldConstraintIndices( 662 self, 663 point: int, 664 field: int, 665 indices: Sequence[int]) -> None: 666 """Set the field DOFs numbers, in [0, DOFs), which are constrained. 667 668 Not collective. 669 670 Parameters 671 ---------- 672 point 673 The point. 674 field 675 The field number. 676 indices 677 The constrained DOFs. 678 679 See Also 680 -------- 681 getFieldConstraintIndices, petsc.PetscSectionSetFieldConstraintIndices 682 683 """ 684 cdef PetscInt cpoint = asInt(point) 685 cdef PetscInt cfield = asInt(field) 686 cdef PetscInt nindex = 0 687 cdef PetscInt *cindices = NULL 688 indices = iarray_i(indices, &nindex, &cindices) 689 CHKERR(PetscSectionSetFieldConstraintDof(self.sec, cpoint, cfield, nindex)) 690 CHKERR(PetscSectionSetFieldConstraintIndices(self.sec, cpoint, cfield, cindices)) 691 692 def getMaxDof(self) -> int: 693 """Return the maximum number of DOFs for any point in the section. 694 695 Not collective. 696 697 See Also 698 -------- 699 petsc.PetscSectionGetMaxDof 700 701 """ 702 cdef PetscInt maxDof = 0 703 CHKERR(PetscSectionGetMaxDof(self.sec, &maxDof)) 704 return toInt(maxDof) 705 706 def getStorageSize(self) -> int: 707 """Return the size capable of holding all the DOFs defined in a section. 708 709 Not collective. 710 711 See Also 712 -------- 713 getConstrainedStorageSize, petsc.PetscSectionGetStorageSize 714 715 """ 716 cdef PetscInt size = 0 717 CHKERR(PetscSectionGetStorageSize(self.sec, &size)) 718 return toInt(size) 719 720 def getConstrainedStorageSize(self) -> int: 721 """Return the size capable of holding all unconstrained DOFs in a section. 722 723 Not collective. 724 725 See Also 726 -------- 727 getStorageSize, petsc.PetscSectionGetConstrainedStorageSize 728 729 """ 730 cdef PetscInt size = 0 731 CHKERR(PetscSectionGetConstrainedStorageSize(self.sec, &size)) 732 return toInt(size) 733 734 def getOffset(self, point: int) -> int: 735 """Return the offset for the DOFs associated with the given point. 736 737 Not collective. 738 739 In a global section, this offset will be negative for points not owned 740 by this process. 741 742 Parameters 743 ---------- 744 point 745 The point. 746 747 See Also 748 -------- 749 setOffset, petsc.PetscSectionGetOffset 750 751 """ 752 cdef PetscInt cpoint = asInt(point), offset = 0 753 CHKERR(PetscSectionGetOffset(self.sec, cpoint, &offset)) 754 return toInt(offset) 755 756 def setOffset(self, point: int, offset: int) -> None: 757 """Set the offset for the DOFs associated with the given point. 758 759 Not collective. 760 761 The user usually does not call this function, but uses `setUp`. 762 763 Parameters 764 ---------- 765 point 766 The point. 767 offset 768 The offset. 769 770 See Also 771 -------- 772 getOffset, petsc.PetscSectionSetOffset 773 774 """ 775 cdef PetscInt cpoint = asInt(point) 776 cdef PetscInt coffset = asInt(offset) 777 CHKERR(PetscSectionSetOffset(self.sec, cpoint, coffset)) 778 779 def getFieldOffset(self, point: int, field: int) -> int: 780 """Return the offset for the field DOFs on the given point. 781 782 Not collective. 783 784 In a global section, this offset will be negative for points not owned 785 by this process. 786 787 Parameters 788 ---------- 789 point 790 The point. 791 field 792 The field. 793 794 See Also 795 -------- 796 setFieldOffset, petsc.PetscSectionGetFieldOffset 797 798 """ 799 cdef PetscInt cpoint = asInt(point) 800 cdef PetscInt cfield = asInt(field) 801 cdef PetscInt offset = 0 802 CHKERR(PetscSectionGetFieldOffset(self.sec, cpoint, cfield, &offset)) 803 return toInt(offset) 804 805 def setFieldOffset(self, point: int, field: int, offset: int) -> None: 806 """Set the offset for the DOFs on the given field at a point. 807 808 Not collective. 809 810 The user usually does not call this function, but uses `setUp`. 811 812 Parameters 813 ---------- 814 point 815 The point. 816 field 817 The field. 818 offset 819 The offset. 820 821 See Also 822 -------- 823 getFieldOffset, petsc.PetscSectionSetFieldOffset 824 825 """ 826 cdef PetscInt cpoint = asInt(point) 827 cdef PetscInt cfield = asInt(field) 828 cdef PetscInt coffset = asInt(offset) 829 CHKERR(PetscSectionSetFieldOffset(self.sec, cpoint, cfield, coffset)) 830 831 def getOffsetRange(self) -> tuple[int, int]: 832 """Return the full range of offsets, [start, end), for a section. 833 834 Not collective. 835 836 See Also 837 -------- 838 petsc.PetscSectionGetOffsetRange 839 840 """ 841 cdef PetscInt oStart = 0, oEnd = 0 842 CHKERR(PetscSectionGetOffsetRange(self.sec, &oStart, &oEnd)) 843 return toInt(oStart), toInt(oEnd) 844 845 # FIXME: Hardcoded PETSC_FALSE parameters 846 def createGlobalSection(self, SF sf) -> Section: 847 """Create a section describing the global field layout. 848 849 Collective. 850 851 The section describes the global field layout using the local section 852 and an `SF` describing the section point overlap. 853 854 If we have a set of local sections defining the layout of a set of 855 local vectors, and also an `SF` to determine which section points are 856 shared and the ownership, we can calculate a global section defining 857 the parallel data layout, and the associated global vector. 858 859 This gives negative sizes and offsets to points not owned by this 860 process. 861 862 ``includeConstraints`` and ``localOffsets`` parameters of the C API 863 are always set to `False`. 864 865 Parameters 866 ---------- 867 sf 868 The `SF` describing the parallel layout of the section points 869 (leaves are unowned local points). 870 871 See Also 872 -------- 873 petsc.PetscSectionCreateGlobalSection 874 875 """ 876 cdef Section gsec = Section() 877 CHKERR(PetscSectionCreateGlobalSection(self.sec, sf.sf, PETSC_TRUE, PETSC_FALSE, PETSC_FALSE, &gsec.sec)) 878 return gsec 879