Metadata-Version: 2.1
Name: pyeonclient
Version: 0.3.3
Summary: Nanobind bindings to the eOn C++ client (Matter, Parameters, Potential, Jobs, NEB, RGPOT)
Keywords: eOn,AKMC,nanobind,Matter,metatomic,NEB,rgpot
Author-Email: Rohit Goswami <rgoswami@ieee.org>
License: BSD-3-Clause
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: BSD License
Classifier: Programming Language :: C++
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Programming Language :: Python :: Free Threading :: 2 - Beta
Classifier: Topic :: Scientific/Engineering
Classifier: Operating System :: POSIX :: Linux
Classifier: Operating System :: MacOS
Project-URL: Homepage, https://github.com/TheochemUI/eOn
Project-URL: Documentation, https://theochemuieon.readthedocs.io/
Project-URL: Repository, https://github.com/TheochemUI/eOn
Project-URL: Issues, https://github.com/TheochemUI/eOn/issues
Project-URL: Changelog, https://github.com/TheochemUI/eOn/blob/main/CHANGELOG.md
Requires-Python: >=3.12
Requires-Dist: numpy>=1.26.4
Requires-Dist: readcon>=0.8.0
Provides-Extra: ase
Requires-Dist: ase>=3.22; extra == "ase"
Provides-Extra: models
Requires-Dist: eon-schema>=0.2.1; extra == "models"
Provides-Extra: metatomic
Requires-Dist: torch>=2.7; extra == "metatomic"
Requires-Dist: rgpot>=2.4.1; extra == "metatomic"
Requires-Dist: metatensor>=0.1.0; extra == "metatomic"
Requires-Dist: metatensor-torch>=0.6.0; extra == "metatomic"
Requires-Dist: metatomic-torch>=0.1.0; extra == "metatomic"
Requires-Dist: vesin>=0.1.0; extra == "metatomic"
Provides-Extra: cookbook
Requires-Dist: pyeonclient[ase,metatomic,models]; extra == "cookbook"
Requires-Dist: rgpycrumbs>=0.1.0; extra == "cookbook"
Description-Content-Type: text/markdown

# pyeonclient

In-process eOn client for Python. First-class algorithm objects on **Matter**
(not a workdir wrapper).

| Class / function | Role |
|------------------|------|
| `Matter` | Geometry + PEF (ASE `Atoms` analogue) |
| `ImprovedDimer` / `Dimer` / `Lanczos` / `Davidson` | Min-mode |
| `MinModeSaddleSearch` | Single-ended saddle search |
| `NudgedElasticBand` | NEB band (`list[Matter]`) |
| `Hessian` / `get_prefactors` | Vibrational analysis / HTST |
| `make_job` + `Job.run` | Full `JobType` factory (workdir jobs) |

Docs: [Python API](https://eondocs.org/user_guide/pyeonclient.html)

## Install

```bash
pip install pyeonclient
pip install 'pyeonclient[ase]'           # Matter ↔ ASE geometry helpers
pip install 'pyeonclient[models]'        # optional Pydantic DimerSpec / NebSpec
# uv: uv pip install 'pyeonclient[models]'
# Core Dimer/NEB work without pydantic; C++ + light Python still enforce
# accelerant="gp" only with method="improved".
```

## Example (dimer → saddle)

```python
import numpy as np
import pyeonclient as pyec

params = pyec.Parameters()
params.potential = pyec.PotType.LJ
pot = pyec.make_potential(params.potential, params)
matter = pyec.Matter(pot, params)
# ... set positions / cell / numbers ...

matter.relax()
mode0 = np.random.default_rng(0).normal(size=matter.positions.shape)
dimer = pyec.ImprovedDimer(matter, params, pot)
dimer.compute(matter, mode0)

ss = pyec.MinModeSaddleSearch(
    matter, dimer.eigenvector, matter.potential_energy, params, pot
)
status = ss.run()
print(pyec.saddle_status_message(status), ss.eigenvalue)
```

## NEB

```python
path = [pyec.from_ase(img, pot, params) for img in images]
neb = pyec.NudgedElasticBand(path, params, pot)
neb.compute()
# Stamped ConFrames for plots (no neb.con write required):
frames = neb.path_frames()  # list[readcon.ConFrame]
path = list(neb.path_images())
```

## Min / saddle movies (in-memory)

```python
out, ok = matter.relax(retain_frames=True)  # default inplace=False returns working copy
movie = out.movie_frames()  # list[readcon.ConFrame]

ss = pyec.MinModeSaddleSearch(matter, mode, e0, params, pot)
ss.run_retain_frames()
climb = ss.climb_frames()
```

## Build

```bash
meson setup build -Dwith_pyeonclient=true
meson compile -C build
pytest tests/test_pyeonclient_eigenmode.py tests/test_pyeonclient_neb.py -v
```
