Metadata-Version: 2.4
Name: anne-dft
Version: 0.1.0rc8
Summary: ANNE - a student-first GPU-DFT SCF engine (pre-release)
Project-URL: Homepage, https://github.com/bjarkejessen/anne-dft
Project-URL: Repository, https://github.com/bjarkejessen/anne-dft
Project-URL: Issues, https://github.com/bjarkejessen/anne-dft/issues
License-Expression: MIT
License-File: LICENSE
Requires-Python: >=3.11
Requires-Dist: ase>=3.22
Requires-Dist: cupy-cuda13x
Requires-Dist: numpy>=1.26
Requires-Dist: scipy>=1.11
Requires-Dist: sisl>=0.16.4
Requires-Dist: threadpoolctl
Provides-Extra: facade
Requires-Dist: ase>=3.22; extra == 'facade'
Requires-Dist: sisl>=0.16.4; extra == 'facade'
Provides-Extra: gpu
Requires-Dist: cupy-cuda13x; extra == 'gpu'
Provides-Extra: sisl
Requires-Dist: sisl>=0.16.4; extra == 'sisl'
Description-Content-Type: text/markdown

# ANNE — GPU density-functional theory that fits on your desk

A single-GPU LCAO-DFT engine, compatible with SIESTA,
[sisl](https://github.com/zerothi/sisl) and
[ASE](https://wiki.fysik.dtu.dk/ase/): SIESTA-comparable **absolute
total energies**, **analytic forces**, and **NEGF quantum transport** —
on one consumer graphics card.

![NEGF transmission vs a 96-core EPYC 9474F node](docs/wiki/fig_landing_moneyshot.png)

*NEGF transmission over a ladder of Cr–O–graphene edge-contact devices —
wall time, peak memory, and speedup vs a full dual-socket EPYC 9474F node
(96 cores) running TBtrans (fp64, its measured-optimum `mpirun -np 64`).
GPU arms are being fully remeasured on the shipped engine (2026-07-27);
curves appear here as each measurement completes — the figure is the
live dashboard. Past W8 the EPYC survives only in out-of-core mode
(open markers, RAM traded to disk). fp32 engine vs its fp64 reference:
0.029% mean on T(E).*

![SCF scaling vs the same EPYC 9474F node](docs/wiki/fig_landing_scf.png)

*The SCF loop against the same dual-socket EPYC 9474F node (2 sockets ×
48 physical cores, SMT off, verified from SLURM; SIESTA at its
measured-optimal `mpirun -np 64`). Protocol: steady-state cost per SCF
iteration — the one-off setup is excluded because it is not even
reproducible (18.4 s cold vs 1.9 s warm kernel cache), and iteration 1
is excluded on the GPU where it runs 2.7–6.3% hot; validated against a
50-iteration reference to ≤1% with identical peak VRAM. Points are means
over independent repeats (n up to 78) with ±1 std bars.*

*Measured 2026-07-28: **magnetic Cr with +U and k-points — 18.1× on the
RTX 5090** (588 atoms, 82.3 s/iteration vs 1,494 s) **and 23× on an
H200** (896 atoms, 183 s vs 4,218 s). Γ-point graphene is the harder
case for us at 4.2–5.4× above 2,000 orbitals (4.2–9.1× including small
sizes, where a fixed per-iteration overhead floor dominates both codes).
Reach on one 32 GB consumer card: 1,152-atom graphene and 588-atom
magnetic Cr; on an H200, 2,592-atom graphene and 1,024-atom Cr — sizes
the CPU reference cannot reach in a comparable time budget.*

*On memory, with both codes on the matched protocol SIESTA's peak sits
**above** both GPU curves at every size measured (e.g. 39.0 vs 26.9 GiB
at 1,152-atom graphene; 43.9 vs 26.2 GiB at 588-atom Cr). An earlier
version of this caption claimed the opposite for graphene; that came
from an unequal-iteration metric — SIESTA converged in 7 iterations with
an unfilled mixer history while ANNE ran 50 — and is corrected here.
Caveat still stated against ourselves: SIESTA is shown at its
speed-optimal rank count, and its per-rank memory scales with ranks, so
a fewer-rank run would use less.*

## Install

```bash
pip install anne-dft[facade]        # PyPI release pending
pip install cupy-cuda13x            # any CuPy CUDA wheel works...
pip install "cuda-toolkit[all]"     # ...this guarantees a modern cuSOLVER
```

From source: `git clone https://github.com/bjarkejessen/anne-dft && pip install -e "anne-dft[facade]"`.
You need an NVIDIA GPU. ANNE **requires a modern cuSOLVER** (the
generic/X eigensolver API): measured on the same RTX 5090, the legacy
path is 1.2–2.2× slower, uses more VRAM, and hits a hard ~23k-orbital
API ceiling — so the engine refuses it at runtime (explicit control:
`MINI_XSYGVD=0`). If your CuPy build carries an older cuSOLVER, ANNE
automatically picks up the modern one from the `cuda-toolkit` wheels
(verified: same converged energy to 0.1 meV on an RTX 5090, old-CuPy
env + wheel fallback vs a native CUDA-13 env).

## 60 seconds of ANNE

```python
import ase.build
import anne

# --- SCF + absolute total energy (zero setup: a battery-certified
#     PBE/DZP basis for H B C N O F Cl Cr Ni ships inside the wheel)
atoms = ase.build.molecule("H2O", vacuum=6.0)
res = anne.scf(atoms)
print(res.energy)        # eV, SIESTA-E_KS-comparable
res.plot()               # SCF convergence figure
# in a notebook, `res` renders as a card with a convergence sparkline

# --- structure relaxation (ASE optimizers under the hood)
rel = anne.relax(atoms, fmax=0.04)
print(rel.summary())     # h2o: 2 BFGS steps -> O-H 0.969 A on an RTX 5090

# --- or plug ANNE into ANY existing ASE workflow (MD, NEB, phonons...)
from ase.md.langevin import Langevin
from ase import units
atoms.calc = anne.ANNE()   # forces are production-certified; the
                           # calculator's energies are a logging proxy
                           # (use anne.scf for absolute energies)
dyn = Langevin(atoms, 0.5 * units.fs, temperature_K=300, friction=0.02)
dyn.run(100)               # ~0.1 s per SCF step for H2O on an RTX 5090
```

## Quantum transport (NEGF)

Point `anne.transmission` at a device directory containing the three
Hamiltonians a TBtrans-style calculation uses (`DEVICE.TSHS` +
`METAL.TSHS`/`GR.TSHS` electrode files, e.g. from a TranSiesta run):

```python
tr = anne.transmission("path/to/device")   # fp32+Löwdin production engine
print(tr.T_E0)                             # transmission at E_F
print(tr.resistance(T=300))                # thermal Landauer resistance, Ohm
tr.plot()                                  # T(E) curve
```

This is the engine behind the benchmark figure above. Fair-comparison
notes ship with every number: cross-code T(E) vs TBtrans agrees to 1.16%
mean, attributed to the electrode-broadening (η) convention at the
transmission dip — while the fp32 engine matches its own fp64 reference
to 0.029% mean.

## Check it yourself

```python
rep = anne.validate("path/to/any/finished/siesta/run")
print(rep)               # graded PASS/FAIL with measured thresholds
```

`anne.validate` reruns any SIESTA calculation directory (geometry, basis
and k-grid are read from it) and grades the comparison against the
project's 49-case validation battery thresholds.

## How accurate? (measured, not promised)

| Quantity | Agreement with SIESTA 5.4.2 | Evidence |
|---|---|---|
| Absolute total energy | non-magnetic median **1.95 meV/atom** (31 cases, max 8.2) | [`docs/wiki/Total-Energy.md`](docs/wiki/Total-Energy.md) |
| Hamiltonian matrix elements | **0.06 meV/element** median (49/49 systems, gauge-fitted) | H-parity battery |
| Forces | non-magnetic median **19.5 meV/Å** | force battery, [`docs/wiki/Total-Energy.md`](docs/wiki/Total-Energy.md) |
| Transmission T(E) | **0.029%** mean vs fp64 reference (engine-internal) | [`docs/wiki/Transport.md`](docs/wiki/Transport.md) |

Every figure in the docs carries its provenance (data file, hardware,
precision, config) in the caption; the standing rule is that solid lines
are measured runs, never formulas.

## Two import names, one rule of thumb

- **`anne`** — the interface for humans. Four verbs
  (`scf`, `relax`, `transmission`, `validate`) plus the `anne.ANNE()`
  ASE calculator. Evidence-cited defaults, guiding error messages,
  notebook-native results. **Start here.**
- **`annedft`** — the typed engine surface underneath (`run_scf`,
  `Problem`, `SCFConfig`, memory profiles, transport internals) for
  scripting the engine precisely. Reach for it when a verb's escape
  hatch (`anne.lowlevel`) tells you to.

## Documentation

Full docs (physics chapters, convergence recipes for magnetic systems,
hardware notes, the freeze policy and every benchmark) live in
[`docs/`](docs/) — Read the Docs hosting pending.

## License

MIT (see `LICENSE`).
