Skip to main content

Crate fasterhenry

Crate fasterhenry 

Source
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 Segment into an nw × nh bundle of them, uniform (discretize) or graded toward the conductor surfaces (discretize_graded).
geometry
Conductor geometry: nodes, straight rectangular-cross-section segments, and the validated Geometry container 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 G feature, 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 --version and JSON output provenance.