Support explicit spin; default to the minimum-spin ground state - #63
Merged
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #63 +/- ##
==========================================
+ Coverage 96.16% 96.17% +0.01%
==========================================
Files 22 22
Lines 1303 1308 +5
==========================================
+ Hits 1253 1258 +5
Misses 50 50
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
galjos
force-pushed
the
add-explicit-spin
branch
2 times, most recently
from
July 1, 2026 09:53
51f49d4 to
8b85fde
Compare
Electronic entropy (q_elec = 2S+1) took its spin from charge parity, which is wrong for open-shell species. Replace it with default_spin(atoms, charge): the minimum-spin ground state from the electron-count parity - even -> singlet (~99% of even-electron molecules), odd -> doublet (essentially always the radical ground state). This reliably auto-handles closed-shell molecules and simple radicals; even-electron high-spin ground states (triplet O2) are set with the explicit, validated spin argument added to System and threaded through run_thermo, dftbplus_thermo and screen (optional manifest 'spin' column).
galjos
added a commit
that referenced
this pull request
Jul 2, 2026
Follow-up to #63. #63 made the user spin drive the electronic-degeneracy *entropy*; this makes it drive the DFTB+ *calculation*, so open-shell species are treated consistently (open-shell energy **and** the matching multiplicity), with **no extra input**. ## Behaviour (charge is the only per-molecule input) `dftbplus_thermo` resolves the spin — the electron-count guess when not given (even→singlet, odd→doublet) — and: - **S > 0 → colinear spin-polarised** DFTB+: `SpinPolarisation = Colinear { UnpairedElectrons = round(2S) }` + the 3ob `SpinConstants` for the atoms present, injected into `Geoopt`/`Hessian`. - **S = 0 → restricted** closed-shell calculation, byte-for-byte unchanged (the default methodology). So a **radical (odd electrons) is auto-detected and run spin-polarised** — e.g. an anthraquinone radical anion (charge −1) just works. The same S drives the calculation and the entropy, so they stay consistent. Only even-electron **triplets** (O₂) need an explicit `spin=1`. ## Spin constants `SPIN_CONSTANTS` is the **3ob-3-1 PBE** set — the compact single-shell form (HOMO `W`, `ShellResolvedSpin = No`) matching this tool’s atom-resolved 3ob SCC. Cross-verified across three independent sources (3ob Elstner list ↔ QUASINANO2015 arXiv:1605.01360 ↔ DFTB+ manual/mio/Köhler). Covers H, C, N, O, F, P, S, Cl; elements without an authoritative constant (Br, I, metals) raise a clear error rather than a guessed number. The constants are parameters tied to the SK set/functional — see the code comment. ## Tests (offline; the slako files are absent here) - `_spin_kwargs`: restricted for S∈(None,0) and fractional S; colinear block for a doublet; error for an untabulated element. - `dftbplus_thermo` (mocked pipeline): an OH radical auto-spin-polarises (`UnpairedElectrons=1`, S passed to the analysis as 0.5); closed-shell water stays restricted; explicit O₂ `spin=1` → `UnpairedElectrons=2`. 178 passed, 5 skipped; pylint 8.88. ## Caveat This is a methodology change gated behind an open-shell spin (restricted stays the default). I could not validate the *energies* here — the 3ob slako files are gone from this machine — so the wiring and constants are verified but the numbers should be confirmed with a real spin-polarised run (restored slako). The S d-shell constant is contested upstream, but only s/p are used for organic sulfur.
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.
Closes #61.
Electronic entropy (
q_elec = 2S+1,S_elec = R ln q) took its spin fromspin(charge)— charge parity — which is wrong for open-shell species.Change
default_spin(atoms, charge): the minimum-spin ground state from the electron-count parity —even → singlet(S=0),odd → doublet(S=0.5). Even electron count is a singlet ~99% of the time, and an odd count is essentially always a doublet, so this auto-handles closed-shell molecules and simple radicals (e.g. every 1-electron-reduced redox species) correctly.spinargument toSystem, threaded throughrun_thermo,dftbplus_thermo, andscreen(optionalspinmanifest column) for the cases the guess cannot know: even-electron high-spin ground states (triplet O2 →spin=1, →S_elec = R ln 3).Tests
default_spinelectron-count parametrized (water/O2/hydroxide → 0; methyl radical → 0.5); explicit-spin override; negative-spin rejection.spin=1) →S_elec = R ln 3.spincolumn →ScreeningJob.spin;screenpasses it todftbplus_thermo.172 passed; pylint 8.86.
Follow-up (separate PR, once this lands): opt-in spin-polarised DFTB+ so a declared/guessed open-shell spin also drives the calculation (verified 3ob spin constants ready). Closes out the thermochemistry audit (#59 rotational, #62 imaginary modes, #61 spin).