1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
//! fasterhenry — clean-room PEEC (partial-element equivalent circuit)
//! resistance and inductance extraction for 3-D conductor geometries.
//!
//! This crate implements the published method (Ruehli's PEEC; Kamon, Tsuk &
//! White, *FASTHENRY: a multipole-accelerated 3-D inductance extraction
//! program*, IEEE T-MTT 1994; Grover/Rosa closed forms for filament partial
//! inductances) from the literature. It contains no code derived from MIT's
//! FastHenry/FastCap, whose license permits only internal, noncommercial use
//! and forbids redistribution. See CONTRIBUTING.md before adding anything.
//!
//! # Pipeline
//!
//! A [`Geometry`] of nodes and segments is cut into [`Filament`]s
//! ([`discretize`], or [`discretize_graded`] for a skin-depth-aware grid
//! graded toward the conductor surfaces); their resistances and partial
//! inductances
//! ([`mod@inductance`]) form the branch impedance `R + jωL`; a loop basis
//! ([`mesh`]) turns that into the mesh system, which [`solve()`] reduces to
//! the impedance matrix `Z(ω)` seen at user-defined [`Port`]s over a list of
//! frequencies, returned as a JSON-serializable [`SweepResult`].
//!
//! [`coupling`] is the optional sparsity lever on that pipeline: name groups
//! of segments, declare which pairs of them are coupled, and the mutual
//! inductance of the rest is never computed. The default couples everything.
//!
//! [`pfft`] is the scaling lever: a matrix-free [`PfftOperator`] that
//! evaluates `L·x` by the precorrected FFT method, in near-linear time and
//! memory, without assembling `L`. [`IterativeSystem`] builds on it: the
//! same port impedance matrix as [`MeshSystem`], solved by [`mod@gmres`] on
//! that operator instead of by dense LU. The dense [`MeshSystem`] remains
//! the default.
//!
//! # Example
//!
//! A 1 mm copper bar, 100 µm × 20 µm in cross-section, with a port across
//! its ends, swept from DC to 1 GHz. All quantities are SI.
//!
//! ```
//! use fasterhenry::{solve, Discretization, Geometry, Node, Port, SegmentDef, Subdivision};
//!
//! let sigma_cu = 5.8e7; // S/m
//! let mut geometry = Geometry::new();
//! let a = geometry.add_node(Node::new(0.0, 0.0, 0.0))?;
//! let b = geometry.add_node(Node::new(1e-3, 0.0, 0.0))?;
//! geometry.add_segment(SegmentDef::new(a, b, 100e-6, 20e-6, sigma_cu))?;
//!
//! let ports = [Port::new(a, b)];
//! // A 5 × 3 filament grid across the cross-section resolves skin effect.
//! let discretization = Discretization::Uniform(Subdivision::new(5, 3));
//! let result = solve(&geometry, &ports, &discretization, &[0.0, 1e6, 1e9])?;
//!
//! // At DC the resistance is l / (σ·A).
//! let r_dc = result.resistance(0)[(0, 0)];
//! assert!((r_dc - 1e-3 / (sigma_cu * 100e-6 * 20e-6)).abs() < 1e-9);
//! // Skin effect raises R at 1 GHz; the partial self-inductance is ~1 nH.
//! assert!(result.resistance(2)[(0, 0)] > r_dc);
//! let l_1mhz = result.inductance(1).expect("defined at f > 0")[(0, 0)];
//! assert!(l_1mhz > 0.5e-9 && l_1mhz < 1.5e-9);
//! # Ok::<(), Box<dyn std::error::Error>>(())
//! ```
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
/// Crate version, for CLI `--version` and JSON output provenance.
pub const VERSION: &str = env!;