assembly ¤
Assembly functions for the transient circuit solver.
Provides functions for evaluating the residual vectors and effective Jacobian of the discretised circuit equations at each Newton iteration. Functions are provided in two variants:
-
Full assembly (:func:
assemble_system_real, :func:assemble_system_complex) — evaluates both the residual and the forward-mode Jacobian viajax.jacfwd. Used once per timestep to assemble and factor the frozen Jacobian in :class:~circulax.solver.FactorizedTransientSolver. -
Residual only (:func:
assemble_residual_only_real, :func:assemble_residual_only_complex) — evaluates only the primal residual, with no Jacobian computation. Used inside the Newton loop where the Jacobian has already been factored and only needs to be applied.
Each pair has a real and a complex variant. The complex variant operates on state vectors in unrolled block format — real parts concatenated with imaginary parts — allowing complex circuit analyses to reuse real-valued sparse linear algebra kernels.
Functions:
| Name | Description |
|---|---|
assemble_gc_complex | Return separate complex G and C COO value arrays at the linearisation point. |
assemble_gc_complex_2n | Return four-block G and C COO value arrays for the 2N×2N real-block system. |
assemble_gc_real | Return separate G and C COO value arrays at the linearisation point. |
assemble_residual_only_complex | Assemble the residual vectors for an unrolled complex system, without computing the Jacobian. |
assemble_residual_only_real | Assemble the residual vectors for a real system, without computing the Jacobian. |
assemble_system_complex | Assemble the residual vectors and effective Jacobian values for an unrolled complex system. |
assemble_system_real | Assemble the residual vectors and effective Jacobian values for a real system. |
assemble_gc_complex ¤
Return separate complex G and C COO value arrays at the linearisation point.
Complex counterpart of :func:assemble_gc_real. The input state vector is in unrolled block format (real parts followed by imaginary parts, shape (2 * num_vars,)). Returns complex128 COO value arrays aligned with the N-sized (not 2N) index arrays from _build_index_arrays(..., is_complex=False), suitable for building an N x N complex admittance matrix in the AC sweep.
The complex Jacobian is recovered from the four real Jacobian blocks via the Wirtinger formula::
J_complex = (1 / 2)(J_RR + J_II) + (j / 2)(J_IR - J_RI)
For holomorphic functions this simplifies to J_RR + j * J_IR; for real-valued functions it reduces to J_RR + 0j.
Source code in circulax/solvers/assembly.py
assemble_gc_complex_2n ¤
Return four-block G and C COO value arrays for the 2N×2N real-block system.
Unlike :func:assemble_gc_complex which collapses the four Jacobian blocks into N×N complex matrices via the Wirtinger formula, this function keeps the blocks separate — returning [RR, RI, IR, II] for both G and C. This is required for circuits containing non-holomorphic operations (e.g. jnp.real()) where the Wirtinger N×N system does not fully capture the conjugate field response.
Returns:
| Type | Description |
|---|---|
list[Array] |
|
list[Array] |
|
tuple[list[Array], list[Array]] | the N-sized index arrays from |
Source code in circulax/solvers/assembly.py
618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 | |
assemble_gc_real ¤
Return separate G and C COO value arrays at the linearisation point.
Mirrors :func:assemble_system_real but returns df/dy (conductance) and dq/dy (capacitance) separately instead of combining them as G + C/dt. Frequency-domain groups contribute zero-filled blocks so that the returned arrays align with the static COO index arrays produced by _build_index_arrays (which includes all groups).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
y_guess | Array | Linearisation point (DC operating point), shape | required |
component_groups | dict | Compiled component groups from :func: | required |
Returns:
| Type | Description |
|---|---|
Array | A two-tuple |
Array | have the same length as the concatenated |
tuple[Array, Array] | index arrays from |
Source code in circulax/solvers/assembly.py
assemble_residual_only_complex ¤
assemble_residual_only_complex(
y_guess: Array,
component_groups: dict,
t1: float,
dt: float,
hist_t: Array | None = None,
hist_y: Array | None = None,
delay_hist: dict[str, Array] | None = None,
) -> tuple[Array, Array]
Assemble the residual vectors for an unrolled complex system, without computing the Jacobian.
The complex counterpart of :func:assemble_residual_only_real. The state vector is expected in unrolled block format (real parts followed by imaginary parts) matching the layout used by :func:assemble_system_complex.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
y_guess | Array | Unrolled state vector of shape | required |
component_groups | dict | Compiled component groups returned by :func: | required |
t1 | float | Time at which the system is being evaluated. | required |
dt | float | Present for signature symmetry with :func: | required |
hist_t | Array | None | Accepted-step sample times for delayed reads, or | None |
hist_y | Array | None | Accepted-step state samples for delayed reads, or | None |
delay_hist | dict[str, Array] | None | Per-group periodic delayed samples supplied by HB, or | None |
Returns:
| Type | Description |
|---|---|
Array | A two-tuple |
Array |
|
Source code in circulax/solvers/assembly.py
937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 | |
assemble_residual_only_real ¤
assemble_residual_only_real(
y_guess: Array,
component_groups: dict,
t1: float,
dt: float,
hist_t: Array | None = None,
hist_y: Array | None = None,
delay_hist: dict[str, Array] | None = None,
) -> tuple[Array, Array]
Assemble the residual vectors for a real system, without computing the Jacobian.
Cheaper than :func:assemble_system_real as it performs only primal evaluations. Used inside the frozen-Jacobian Newton loop where the Jacobian has already been factored and only the residual needs to be recomputed at each iteration.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
y_guess | Array | Current state vector of shape | required |
component_groups | dict | Compiled component groups returned by :func: | required |
t1 | float | Time at which the system is being evaluated. | required |
dt | float | Present for signature symmetry with :func: | required |
hist_t | Array | None | Accepted-step sample times for delayed reads, or | None |
hist_y | Array | None | Accepted-step state samples for delayed reads, or | None |
delay_hist | dict[str, Array] | None | Per-group periodic delayed samples supplied by HB, or | None |
Returns:
| Type | Description |
|---|---|
Array | A two-tuple |
Array |
|
Source code in circulax/solvers/assembly.py
assemble_system_complex ¤
assemble_system_complex(
y_guess: Array,
component_groups: dict,
t1: float,
dt: float,
source_scale: float = 1.0,
alpha: float = 1.0,
hist_t: Array | None = None,
hist_y: Array | None = None,
) -> tuple[Array, Array, Array]
Assemble the residual vectors and effective Jacobian values for an unrolled complex system.
The complex state vector is stored in unrolled (block) format: the first half of y_guess holds the real parts of all node voltages/states, the second half holds the imaginary parts. This avoids JAX's limited support for complex-valued sparse linear solvers by keeping all arithmetic real.
The Jacobian is split into four real blocks — RR, RI, IR, II — representing the partial derivatives of the real and imaginary residual components with respect to the real and imaginary state components respectively. The blocks are concatenated in RR→RI→IR→II order to match the sparsity index layout produced during compilation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
y_guess | Array | Unrolled state vector of shape | required |
component_groups | dict | Compiled component groups returned by :func: | required |
t1 | float | Time at which the system is being evaluated. | required |
dt | float | Timestep duration, used to scale the reactive Jacobian blocks. | required |
source_scale | float | Multiplicative scale applied to source amplitudes (components whose | 1.0 |
alpha | float | Jacobian scaling factor for the reactive blocks. Use | 1.0 |
Returns:
| Type | Description |
|---|---|
Array | A three-tuple |
Array |
|
Array |
|
tuple[Array, Array, Array] |
|
Source code in circulax/solvers/assembly.py
782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 | |
assemble_system_real ¤
assemble_system_real(
y_guess: Array,
component_groups: dict,
t1: float,
dt: float,
source_scale: float = 1.0,
alpha: float = 1.0,
hist_t: Array | None = None,
hist_y: Array | None = None,
) -> tuple[Array, Array, Array]
Assemble the residual vectors and effective Jacobian values for a real system.
For each component group, evaluates the physics at t1 and computes the forward-mode Jacobian via jax.jacfwd. The effective Jacobian combines the resistive and reactive contributions as J_eff = df/dy + (alpha/dt) * dq/dy, where alpha=1 recovers Backward Euler and alpha=3/2 (uniform step) gives BDF2.
Components are processed in sorted key order to ensure a deterministic non-zero layout in the sparse Jacobian, which is required for the factorisation step.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
y_guess | Array | Current state vector of shape | required |
component_groups | dict | Compiled component groups returned by :func: | required |
t1 | float | Time at which the system is being evaluated. | required |
dt | float | Timestep duration, used to scale the reactive Jacobian block. | required |
source_scale | float | Multiplicative scale applied to source amplitudes (components whose | 1.0 |
alpha | float | Jacobian scaling factor for the reactive block. Use | 1.0 |
Returns:
| Type | Description |
|---|---|
Array | A three-tuple |
Array |
|
Array |
|
tuple[Array, Array, Array] |
|
Source code in circulax/solvers/assembly.py
371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 | |