Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: docs

# Build the MkDocs site and publish it to GitHub Pages (gh-pages branch).
on:
push:
branches:
- main
paths:
- "docs/**"
- "mkdocs.yml"
- ".github/workflows/docs.yml"
workflow_dispatch:

permissions:
contents: write

jobs:
build-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"

- name: Cache pip
uses: actions/cache@v4
with:
path: ~/.cache/pip
key: docs-pip-${{ hashFiles('.github/workflows/docs.yml') }}

- name: Install documentation dependencies
run: |
python -m pip install --upgrade pip
pip install "mkdocs<2.0" "mkdocs-material>=9.5" "pymdown-extensions>=10.0"

- name: Build and deploy
run: mkdocs gh-deploy --force --clean
5 changes: 2 additions & 3 deletions .github/workflows/python-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,9 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade pip
#python -m pip install uv
#pip install numpy scipy jarvis-tools flake8 pytest matplotlib torch h5py ase spglib coverage
pip install flake8 pytest coverage
#if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
# runtime dependencies -- needed so pytest can import the package
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
pip install -e .
coverage run -m pytest
Expand Down
3 changes: 3 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
include README.md
include requirements.txt
recursive-include slakonet/data *.json
47 changes: 47 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,53 @@ dos_values = properties['dos_values_tensor']
dos_energies = properties['dos_energy_grid_tensor']
```

### ASE Calculator

`SlaKoNetCalculator` exposes SlaKoNet through the standard ASE
`Calculator` API. The trained model is **loaded once** and injected into
the calculator, then reused for every structure and every call (no
per-call reload). Energy, forces and stress use the usual ASE methods;
band structure and DOS are dedicated methods.

```python
from ase.build import bulk
from slakonet.optim import default_model
from slakonet.ase_calc import SlaKoNetCalculator

# load the trained model ONCE
model = default_model().float()

calc = SlaKoNetCalculator(model, kpoints=(3, 3, 3))

si = bulk("Si", "diamond", a=5.43)
si.calc = calc
si.get_potential_energy() # eV
si.get_forces() # eV/Ang, shape (N, 3)
si.get_stress() # eV/Ang^3, Voigt(6)

# band structure (-> PNG) and total DOS, same loaded model
bs = calc.band_structure(si, path="GXWKGL", npoints=120,
savefig="si_bands.png")
e, dos = calc.dos(si)
print(calc.get_bandgap(), calc.get_fermi_level())

# reuse on another structure with NO model reload
ge = bulk("Ge", "diamond", a=5.66); ge.calc = calc
ge.get_potential_energy()
```

Toggles (constructor keywords): `compute_forces`, `compute_stress`,
`use_scc`, `include_dos`, `kpoints`, `cutoff`, `kT`, `alpha`, `beta`,
`device`. Setting `compute_forces=False` gives a fast energy-only path
for high-throughput screening.

Notes: forces are scaled by `beta` (default `0.1`); pass `beta=1.0` for
physically correct forces. Stress is converted to ASE units
(eV/Ang^3, Voigt) but should be validated against a numerical-strain
reference before use in cell relaxation. A full runnable demo is in
`slakonet/examples/slakonet_calculator_example.py`. See also the ASE docs
page *Calculators -> SlaKoNet*.

## Supported Materials

- **Elements**: Z = 1-65
Expand Down
98 changes: 98 additions & 0 deletions docs/api-reference.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# API reference

The most useful public entry points. For the full source, see the
[GitHub repository](https://github.com/atomgptlab/slakonet).

## `slakonet.optim`

### `default_model()`

```python
from slakonet.optim import default_model
model = default_model()
```

Loads (and caches on first use) the trained SlaKoNet model covering 65
elements. Call once; reuse the returned object everywhere. Often used as
`default_model().float()`.

### `default_mu(full=False)`

```python
from slakonet.optim import default_mu
mu = default_mu() # {element: chemical potential, eV}
meta = default_mu(full=True) # full record incl. calibration metadata
```

Returns the per-element chemical potentials bundled with SlaKoNet, used
for formation energies. See [Formation energies](guide/formation-energy.md).

## `slakonet.ase_calc`

### `SlaKoNetCalculator`

```python
from slakonet.ase_calc import SlaKoNetCalculator
calc = SlaKoNetCalculator(model, kpoints=(3, 3, 3))
```

A standard ASE `Calculator`. Constructor options are documented in the
[ASE calculator guide](guide/ase-calculator.md).

**Standard ASE properties**

| Call | Returns |
| --- | --- |
| `atoms.get_potential_energy()` | total energy, eV |
| `atoms.get_forces()` | forces, eV/Å, shape `(N, 3)` |
| `atoms.get_stress()` | stress, eV/ų, Voigt 6-vector |

**SlaKoNet-specific methods**

| Method | Returns |
| --- | --- |
| `calc.get_bandgap()` | band gap (eV), from the MP grid |
| `calc.get_fermi_level()` | Fermi level (eV) |
| `calc.band_structure(atoms, path=None, npoints=80, savefig=None)` | dict with `energies`, `kpts`, `labels`, `path`, `gap`, `vbm`, `cbm` |
| `calc.dos(atoms, energy_range=(-10, 10), num_points=3000, sigma=0.1)` | `(energies, dos)` arrays, Fermi-referenced |

### `SlaKoNetConfig`

```python
from slakonet.ase_calc import SlaKoNetConfig
cfg = SlaKoNetConfig(kpoints=[4, 4, 4], use_scc=True)
calc = SlaKoNetCalculator(model, config=cfg)
```

A declarative configuration object (pydantic). Accepts the same fields
as the calculator constructor; also constructible from a `dict` or a
JSON file. Explicit keyword arguments to `SlaKoNetCalculator` override
the config.

## `slakonet.predict_slakonet`

### `plot_band_dos_atoms(...)`

```python
from slakonet.predict_slakonet import plot_band_dos_atoms
plot_band_dos_atoms(atoms=atoms, model=model,
filename="bands_dos.png")
```

Convenience function: computes and plots a combined band-structure +
DOS figure for a structure.

## Quick map of the package

| Module | Purpose |
| --- | --- |
| `slakonet.optim` | model loading (`default_model`), chemical potentials (`default_mu`) |
| `slakonet.ase_calc` | the ASE `SlaKoNetCalculator` and `SlaKoNetConfig` |
| `slakonet.predict_slakonet` | band-structure / DOS prediction helpers |
| `slakonet.main` | core driver (`SimpleDftb`, shell-dict helpers) |
| `slakonet.slaterkoster` | Slater-Koster Hamiltonian / overlap construction |
| `slakonet.atoms`, `slakonet.basis` | geometry and basis-set containers |

!!! tip
For day-to-day use you only need `slakonet.optim` and
`slakonet.ase_calc` — the rest is internal machinery.
66 changes: 66 additions & 0 deletions docs/contributing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Contributing

Contributions are welcome — bug reports, fixes, new examples,
documentation improvements, and feature work.

## Ways to help

- **Report bugs** — open a [GitHub issue](https://github.com/atomgptlab/slakonet/issues)
with a minimal reproducer.
- **Improve the docs** — every page has an edit link (top right); fixes
and clarifications are appreciated.
- **Add examples** — a clear, self-contained script for a new use case
is one of the most useful contributions.
- **Submit code** — bug fixes and features via pull request.

## Development setup

```bash
git clone https://github.com/atomgptlab/slakonet.git
cd slakonet
conda create --name slakonet-dev python=3.10 -y
conda activate slakonet-dev
pip install -e .
```

## Building the documentation locally

The docs are built with [MkDocs](https://www.mkdocs.org/) and the
[Material](https://squidfunk.github.io/mkdocs-material/) theme:

```bash
pip install mkdocs-material
mkdocs serve
```

Then open <http://127.0.0.1:8000>. The site rebuilds live as you edit
files under `docs/`.

## Pull request guidelines

- Keep changes focused — one logical change per PR.
- Match the surrounding code style.
- Add or update an example or doc page when you add a feature.
- Make sure existing examples still run.
- Describe *why* the change is needed in the PR description.

## Reporting bugs effectively

A good bug report includes:

1. What you ran (a minimal code snippet).
2. What you expected.
3. What happened (full error / traceback).
4. Your environment — OS, Python, PyTorch and SlaKoNet versions, CPU/GPU.

## Code of conduct

Please be respectful and constructive in all project spaces. Assume good
intent and help newcomers.

## Questions

For usage questions, open a
[GitHub issue](https://github.com/atomgptlab/slakonet/issues) — chances
are someone else has the same question, and the answer then helps them
too.
87 changes: 87 additions & 0 deletions docs/examples.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# Examples & Colab

The fastest way to try SlaKoNet — **no installation required** — is the
interactive Colab notebook. Worked example scripts that ship with the
repository are listed further down.

## :material-rocket-launch: Run it in Google Colab

[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/knc6/jarvis-tools-notebooks/blob/master/jarvis-tools-notebooks/slakonet_example.ipynb)

| Notebook | Open | What it covers |
| --- | --- | --- |
| **SlaKoNet — getting started** | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/knc6/jarvis-tools-notebooks/blob/master/jarvis-tools-notebooks/slakonet_example.ipynb) | Loading the model, computing a band structure and DOS, extracting the band gap — entirely in the browser. |

!!! tip "First cell"
The notebook installs SlaKoNet with `pip install slakonet` and then
downloads the trained model on first use. Give the first cell a
minute.

## Example scripts in the repository

The [`slakonet/examples/`](https://github.com/atomgptlab/slakonet/tree/main/slakonet/examples)
directory contains runnable, self-contained scripts. Highlights:

### Using the model

| Script | What it does |
| --- | --- |
| `slakonet_calculator_example.py` | End-to-end `SlaKoNetCalculator` demo — energy, forces, stress, band structure, DOS; reuses one loaded model across structures. |
| `chipstb_bandgaps.py` | High-throughput band-gap benchmark over a JARVIS-DFT material set; compares two k-sampling schemes and computes formation energies. |
| `mgb2_fermi_bands.py` | MgB₂ worked example: band structure + DOS, 3D band structure, and 2D / 3D Fermi surfaces. |
| `predict_bands_from_poscar.py` | Predict a band structure directly from a POSCAR file. |

### Validation & correctness

| Script | What it does |
| --- | --- |
| `check_autograd_forces.py` | Verifies forces match a finite-difference of the energy. |
| `check_stress.py` | Verifies stress against numerical strain. |

To run any of them:

```bash
git clone https://github.com/atomgptlab/slakonet.git
cd slakonet/slakonet/examples
python slakonet_calculator_example.py
```

A full annotated index lives in
[`slakonet/examples/README.md`](https://github.com/atomgptlab/slakonet/blob/main/slakonet/examples/README.md).

## Minimal copy-paste examples

### Band gap of a single material

```python
from ase.build import bulk
from slakonet.optim import default_model
from slakonet.ase_calc import SlaKoNetCalculator

calc = SlaKoNetCalculator(default_model().float())
si = bulk("Si", "diamond", a=5.43); si.calc = calc
print("Si gap:", calc.get_bandgap(), "eV")
```

### Band structure to a PNG

```python
calc.band_structure(si, path="GXWKGL", npoints=20,
savefig="si_bands.png")
```

### Screen many materials with one loop

```python
model = default_model().float()
calc = SlaKoNetCalculator(model, kpoints=(3, 3, 3),
compute_forces=False) # fast path

for atoms in my_structures: # any iterable of ASE Atoms
atoms.calc = calc
atoms.get_potential_energy()
print(atoms.get_chemical_formula(), calc.get_bandgap())
```

See [Band-gap screening](guide/bandgap-screening.md) for a complete,
benchmarked screening tutorial.
Loading
Loading