feat(py): accept m_eff, and export M_E - #9
Open
reneotten wants to merge 1 commit into
Open
Conversation
The Python wrapper's docstring said keyword arguments "match the Rust `DeviceParams` field names", but `m_eff` was hardcoded to `0.9 * M_E` in the binding, so `Device(m_eff=...)` raised TypeError. The README discusses `m_eff` as a tunable fitting parameter, so the documentation actively pointed at an argument that did not exist. Accept `m_eff` as an optional keyword. The default is unchanged. `m_eff` is an absolute mass in kilograms, and the natural way to write "0.9 electron masses" is `m_eff=0.9`, which would silently be ~10^30x too heavy. Export `M_E` so the intent can be spelled `m_eff=0.19 * negforge.M_E`, and reject values above 1e-25 kg with an error that shows the correct form. Non-finite and non-positive values are rejected too. Also documents an asymmetry found while testing this: `m_eff` only enters the NEGF hopping `t_hop = hbar^2/(2 m_eff a^2)`, so it changes the LDOS and the self-consistent charge but leaves `calc_current()` bit-for-bit unchanged -- the ballistic Landauer integral assumes unit transmission above the barrier and carries no mass prefactor. Pinned by a test so the behaviour is a stated property rather than a surprise.
There was a problem hiding this comment.
Pull request overview
This PR updates the Python bindings to fully support m_eff as a configurable Device parameter (instead of being hardcoded), and exposes the free-electron mass constant M_E so Python callers can specify effective masses safely in SI units.
Changes:
- Add optional
m_effkeyword argument to the PyO3Deviceconstructor, preserving the existing default. - Export
M_Eto Python and re-export it fromnegforgefor ergonomic usage (negforge.M_E). - Add a core Rust test that pins the intended behavior:
m_effscalest_hopbut does not affect the ballisticcalc_current()result.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| python/negforge/init.py | Re-exports M_E and documents correct m_eff units/usage and its modeled impact. |
| crates/negforge-py/src/lib.rs | Accepts m_eff=None, validates units/range, and exports M_E from the extension module. |
| crates/negforge-core/src/device.rs | Adds a regression test asserting m_eff affects hopping but not ballistic current. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
feat(py): accept m_eff, and export M_E
The Python wrapper's docstring said keyword arguments "match the Rust
DeviceParamsfield names", butm_effwas hardcoded to0.9 * M_Ein thebinding, so
Device(m_eff=...)raised TypeError. The README discussesm_effas a tunable fitting parameter, so the documentation activelypointed at an argument that did not exist.
Accept
m_effas an optional keyword. The default is unchanged.m_effis an absolute mass in kilograms, and the natural way to write "0.9electron masses" is
m_eff=0.9, which would silently be ~10^30x too heavy.Export
M_Eso the intent can be spelledm_eff=0.19 * negforge.M_E, andreject values above 1e-25 kg with an error that shows the correct form.
Non-finite and non-positive values are rejected too.
Also documents an asymmetry found while testing this:
m_effonly entersthe NEGF hopping
t_hop = hbar^2 / (2 m_eff a^2), so it changeslocal_density_of_states()and the self-consistent charge, but not
calc_current(): the ballisticLandauer integral in this model assumes unit transmission above the barrier
and carries no mass prefactor. Changing
m_effalone therefore leaves theballistic I-V untouched by construction. Pinned by a test so the behaviour
is a stated property rather than a surprise.