Skip to content

N-conductor Maxwell matrices, Wheeler losses, roughness and causal materials - #38

Open
RFingAdam wants to merge 22 commits into
mainfrom
feature/mtl-nconductor
Open

RFingAdam wants to merge 22 commits into
mainfrom
feature/mtl-nconductor

Conversation

@RFingAdam

Copy link
Copy Markdown
Owner

Adds what fieldforge's interconnect extraction needs from lineforge, as a library:

  • Usermap.from_labels with integer conductor_ids (-1 non-conductor, 0 reference, 1..N signals, -2 floating) and a vectorised colour mapping.
  • DSParams (Djordjevic-Sarkar) and RoughnessSpec (Hammerstad, Groisse, Huray cannonball) on MaterialRecord, with er_complex(f) and JSON pack I/O.
  • solvers/mtl.py: solve_maxwell (N+1 Laplace solves) and rlgc_matrices (Maxwell C, L_ext = mu0 eps0 inv(C0), G from the dielectric energy shares).
  • solvers/wheeler.py: solve_wheeler_resistance, the Wheeler incremental-inductance rule with roughness, giving the full R matrix.
  • solvers/faraday.solve_impedance_matrix: N right-hand-side PEEC with one LU and a SolverBudgetExceeded guard.
  • touchstone.to_touchstone_nport: Touchstone 1 via scikit-rf and native Touchstone 2 with [Reference] and [Mixed-Mode Order].

Also fixes a long-standing bug in solvers/diff_modes.py: a spurious pixel_width**2 factor and per-drive normalisation made Z_odd 2/px^2 too large and Z_even 0.5/px^2 too small. Any externally saved bitmap differential-mode numbers from before this change are invalid; see the CHANGELOG entry.

All existing tests unchanged; the five tests/test_cli.py failures and the 17 mypy errors pre-date this branch.

solve_maxwell runs one Laplace solve per signal conductor (that conductor
at 1 V, every other fixed conductor at 0 V, floats via float_groups) plus
the same set in vacuum, and stores the energy matrices partitioned by
material code. rlgc_matrices turns those into C, G and L_ext at any
frequency via MaterialRecord.er_complex.

Also fixes two normalization bugs in diff_modes that the N = 2 cross-check
exposed: the mode capacitance was multiplied by pixel_width^2 (the pixel
factors already cancel, as in cgp._energy_integral) and the odd/even drives
were normalized by the differential drive voltage instead of per line, so
z_odd was really Z_diff and z_even really Z_common. Both solvers now agree
to 1e-11 on the same geometry.
… document conventions

solve_maxwell now reports two previously silent conventions through
MaxwellResult.warnings: conductor-material pixels with no conductor_ids
entry are driven at 0 V (unlabelled_conductor_pixels), and the AMG Laplace
path has no floating-conductor support, so a map with floats solved through
AMG loses the equipotential constraint (float_groups_ignored_by_amg). Both
are documented in the docstring, and the er field is now built by one helper
for the nominal and the f_ref_hz branch.

Also corrects the diff_modes module docstring to the post-fix meaning of its
outputs (per-line odd/even impedances, Z_diff = 2 Z_odd, Z_common = Z_even/2),
scopes the n_lines normalization comment to the two symmetric drives, and
restores a zero-drive guard.
CHANGELOG.md: record every capability tasks 1-7 added (Usermap.from_labels,
DSParams/RoughnessSpec/er_complex, solvers/roughness.py, solve_maxwell,
rlgc_matrices, solve_wheeler_resistance, solve_impedance_matrix,
SolverBudgetExceeded, to_touchstone_nport) and the diff_modes fix, with the
exact old scale factors (z_odd off by 2/px**2, z_even off by 0.5/px**2) so
anyone with numbers saved from the old bitmap differential path knows to
re-run them.

docs/theory/faraday_solver.md: add a short N-conductor extraction workflow
section walking through labels, solve_maxwell, rlgc_matrices,
solve_wheeler_resistance, roughness, solve_impedance_matrix and
to_touchstone_nport in order.
- add a Touchstone version-2 two-port round-trip test (P=2, [Two-Port Data
  Order] 12_21) and a comment on the header line noting the nominal z_ref
  is for legacy readers, per-port values live in [Reference].
- add an absolute-magnitude cross-check: diff_modes.solve_modes' z_odd
  against sqrt((L11-L12)/(C11-C12)) from solve_maxwell + rlgc_matrices, the
  check the old internal-identity-only tests could not have caught.
- document that MaterialRecord.resistivity_ohm_cm is in practice
  micro-ohm-centimetres and gets multiplied by 1e-8 for ohm-metres; the
  field keeps its name to avoid breaking the on-disk MoreColors.txt format.
- move _CANNONBALL_HEIGHT/_CANNONBALL_RATIO into materials/database.py and
  import them from there in solvers/roughness.py instead of duplicating
  them: RoughnessSpec's validator can't call solvers.roughness directly
  without a cycle, since that module already imports RoughnessSpec.
- add the from_labels validation tests and the float-role RGB test that
  were missing, closing the last gaps in that code's coverage.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant