Expand description
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 Filaments
(discretize, or discretize_graded for a skin-depth-aware grid
graded toward the conductor surfaces); their resistances and partial
inductances
(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 Ports 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 gmres on
that operator instead of by dense LU. The dense MeshSystem remains
the default up to DENSE_PATH_MAX_FILAMENTS filaments, which is what
SolverChoice::Auto — the front end’s default — switches on.
§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);Re-exports§
pub use coupling::Coupling;pub use coupling::CouplingError;pub use coupling::TruncationWarning;pub use filament::discretize;pub use filament::discretize_graded;pub use filament::DiscretizeError;pub use filament::Filament;pub use geometry::Geometry;pub use geometry::GeometryError;pub use geometry::LocalBasis;pub use geometry::Node;pub use geometry::NodeId;pub use geometry::Segment;pub use geometry::SegmentDef;pub use geometry::SegmentError;pub use gmres::GmresOutcome;pub use gmres::GmresParams;pub use inductance::mutual_batch;pub use inductance::mutual_batch_detailed;pub use inductance::mutual_inductance;pub use inductance::partial_inductance_matrix;pub use inductance::partial_inductance_matrix_detailed;pub use inductance::partial_inductance_matrix_masked;pub use inductance::partial_inductance_matrix_masked_with;pub use inductance::self_inductance;pub use inductance::KernelError;pub use inductance::MutualBatch;pub use inductance::PairMask;pub use inductance::MU0;pub use iterative::IterativeParams;pub use iterative::IterativeSolution;pub use iterative::IterativeSystem;pub use mesh::MeshError;pub use mesh::MeshMatrix;pub use mesh::Port;pub use pfft::GridSpacing;pub use pfft::PfftError;pub use pfft::PfftOperator;pub use pfft::PfftParams;pub use pfft::PfftStats;pub use result::Counts;pub use result::Provenance;pub use result::SweepResult;pub use result::Timing;pub use solve::filament_resistance;pub use solve::skin_depth;pub use solve::solve;pub use solve::Discretization;pub use solve::Grading;pub use solve::MeshSystem;pub use solve::SkinDepthGrading;pub use solve::SolveError;pub use solve::Solver;pub use solve::SolverChoice;pub use solve::Subdivision;pub use solve::DENSE_PATH_MAX_FILAMENTS;
Modules§
- coupling
- Coupling truncation: naming groups of segments and declaring which pairs of groups are magnetically coupled, so that the mutual inductance of the rest is never computed.
- dense
- Dense LU solve for the mesh system.
- filament
- Filaments — the PEEC current elements — and the discretization of a
Segmentinto annw × nhbundle of them, uniform (discretize) or graded toward the conductor surfaces (discretize_graded). - geometry
- Conductor geometry: nodes, straight rectangular-cross-section segments,
and the validated
Geometrycontainer every later stage consumes. - gmres
- Restarted GMRES for matrix-free linear systems, real or complex.
- inductance
- Partial self and mutual inductances of rectangular filaments — the numerical core of the PEEC method.
- iterative
- Matrix-free port impedance extraction: GMRES on the precorrected-FFT operator.
- mesh
- Ports and the mesh (loop) basis of the filament circuit.
- pfft
- Matrix-free partial-inductance products by the precorrected FFT (pFFT) method.
- plane
- Ground planes: thick rectangular sheets discretized into a mesh of
bars, with rectangular holes and locally refined contact regions — the
FastHenry
Gfeature, on the same segment/kernel/mesh machinery everything else uses. - result
- The result of a frequency sweep, and its JSON form.
- solve
- Assembly of the PEEC mesh system and its solution for the port impedance
matrix
Z(ω).
Constants§
- VERSION
- Crate version, for CLI
--versionand JSON output provenance.