diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index 88fd15d..9e25396 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -11,13 +11,13 @@ jobs: fail-fast: false matrix: include: - - os: windows-latest + - os: windows-2022 python: 312 platform_id: win_amd64 - os: ubuntu-latest python: 312 platform_id: manylinux_x86_64 - - os: macos-latest + - os: macos-14 python: 312 macos_target: 14 platform_id: macosx_arm64 @@ -65,6 +65,12 @@ jobs: shell: msys2 {0} env: PYTHONIOENCODING: utf-8 + - uses: fortran-lang/setup-fortran@v1 + id: setup-fortran + if: runner.os != 'Windows' + with: + compiler: gcc + version: latest - uses: pypa/cibuildwheel@v3.1.1 if: runner.os != 'Windows' env: @@ -73,7 +79,7 @@ jobs: UV_INDEX: https://pypi.org/simple UV_DEFAULT_INDEX: https://pypi.org/simple CIBW_BEFORE_ALL_LINUX: "yum install -y openblas-devel" - CIBW_BEFORE_ALL_MACOS: "brew install openblas gfortran" + CIBW_BEFORE_ALL_MACOS: "brew install openblas" CIBW_BUILD: cp${{ matrix.python }}-${{ matrix.platform_id }} MACOSX_DEPLOYMENT_TARGET: ${{ matrix.macos_target }}.0 - run: ls -l wheelhouse/* diff --git a/.github/workflows/wheel.yml b/.github/workflows/wheel.yml index 52c0fed..93a38ef 100644 --- a/.github/workflows/wheel.yml +++ b/.github/workflows/wheel.yml @@ -17,29 +17,29 @@ jobs: matrix: include: # win-64 - - os: windows-latest + - os: windows python: 39 platform_id: win_amd64 - - os: windows-latest + - os: windows-2022 python: 310 platform_id: win_amd64 - - os: windows-latest + - os: windows-2022 python: 311 platform_id: win_amd64 - - os: windows-latest + - os: windows-2022 python: 312 platform_id: win_amd64 - - os: windows-latest + - os: windows-2022 python: 313 platform_id: win_amd64 - - os: windows-latest + - os: windows-2022 python: 313t platform_id: win_amd64 cibw_enable: cpython-freethreading - - os: windows-latest + - os: windows-2022 python: 314 platform_id: win_amd64 - - os: windows-latest + - os: windows-2022 python: 314t platform_id: win_amd64 cibw_enable: cpython-freethreading @@ -287,15 +287,21 @@ jobs: pipx run --python 3.13 delvewheel==1.10 repair dist/*.whl -vv if: runner.os == 'Windows' shell: msys2 {0} + - uses: fortran-lang/setup-fortran@v1 + id: setup-fortran + if: runner.os != 'Windows' + with: + compiler: gcc + version: latest - uses: pypa/cibuildwheel@v3.1.1 if: runner.os != 'Windows' env: CIBW_ARCHS: all CIBW_BUILD_VERBOSITY: 1 + CIBW_ENVIRONMENT_MACOS: FC=gfortran CIBW_ENABLE: ${{ matrix.cibw_enable }} CIBW_BEFORE_ALL_LINUX: "yum install -y openblas-devel" CIBW_BEFORE_ALL_MACOS: "brew install openblas gfortran" - CIBW_ENVIRONMENT_MACOS: CC=gcc-13 CXX=g++-13 FC=gfortran-13 CIBW_BUILD: cp${{ matrix.python }}-${{ matrix.platform_id }} CIBW_MANYLINUX_X86_64_IMAGE: ${{ matrix.manylinux_image }} MACOSX_DEPLOYMENT_TARGET: ${{ matrix.macos_target }}.0 @@ -369,6 +375,6 @@ jobs: conda config --set anaconda_upload yes export ANACONDA_API_TOKEN=${{ secrets.ANACONDA_TOKEN }} for file in conda-dist/*; do - anaconda upload $file + anaconda upload $file -c conda-forge done shell: micromamba-shell {0} diff --git a/AGENTS.md b/AGENTS.md deleted file mode 100644 index 50ddd2a..0000000 --- a/AGENTS.md +++ /dev/null @@ -1,84 +0,0 @@ -# PyGFNFF - -## Project Overview - -PyGFNFF is a Python library that provides the GFN-FF (Generic Force Field) method for computational chemistry calculations. It is based on F2PY (Fortran to Python interface) and integrates with the Atomic Simulation Environment (ASE). - -**Reference:** -- S.Spicher, S.Grimme. Robust Atomistic Modeling of Materials, Organometallic, and Biochemical Systems (2020), DOI: https://doi.org/10.1002/anie.202004239 -- Original Fortran implementation: https://github.com/pprcht/gfnff/ - -## Project Structure - -``` -PyGFNFF/ -├── pygfnff/ # Python package -│ ├── __init__.py # Exports GFNFF calculator and gfnff function -│ └── _pygfnff.py # Main implementation -├── fortran/ # Fortran source code -│ ├── gfnff_*.f90 # GFN-FF modules -│ ├── _pygfnfflib.f90 # F2PY interface -│ ├── CMakeLists.txt # Fortran build configuration -│ └── gbsa/ # GBSA solvation model -├── include/ # C header and parameter files -│ ├── gfnff_interface_c.h -│ └── param_*.fh # Parameter files for solvents -├── tests/ # Test suite -│ ├── test_co_by_ase.py -│ └── test_coffeine.py -├── CMakeLists.txt # Root CMake configuration -└── pyproject.toml # Python project configuration -``` - -## Key Components - -### Python Interface (`pygfnff/`) - -- **`GFNFF`**: ASE Calculator subclass for non-PBC systems -- **`gfnff()`**: Low-level function for single-point energy calculations - -### Fortran Backend (`fortran/`) - -- GFN-FF implementation derived from https://github.com/pprcht/gfnff (commit 0491df2) -- GBSA solvation model support (optional, enabled via CMake `WITH_GBSA`) -- F2PY bindings via `_pygfnfflib.f90` - -## Build System - -- **Build backend**: scikit-build-core -- **Fortran build**: CMake with Ninja generator -- **Required compilers**: GNU Fortran or Intel Fortran -- **Dependencies**: LAPACK, OpenBLAS, OpenMP (optional) - -## Development Commands - -```bash -# Install dependencies -uv sync - -# Run tests -pytest tests/ - -# Build wheel (requires fortran compiler) -pipx run --python 3.13 cibuildwheel==3.1.1 -``` - -## Usage Example - -```python -from ase import Atoms -from ase.build import molecule -from ase.optimize import BFGS -from pygfnff import GFNFF - -atoms = Atoms(molecule("CO"), calculator=GFNFF()) -opt = BFGS(atoms, logfile="-", trajectory=None) -opt.run(fmax=0.03, steps=50) -e = atoms.get_potential_energy() -``` - -## Configuration - -- `pyproject.toml`: Project metadata, dependencies, build settings -- `.python-version`: Python version specification -- `.github/workflows/`: CI/CD pipelines for pytest and wheel building diff --git a/README.md b/README.md index f387c48..98a7b26 100644 --- a/README.md +++ b/README.md @@ -3,10 +3,46 @@ [![Pypi version](https://img.shields.io/pypi/v/pygfnff)](https://pypi.org/project/pygfnff/) [![PyPI Downloads](https://static.pepy.tech/badge/pygfnff)](https://pepy.tech/projects/pygfnff) -This is a Python version for [GFN-FF](https://github.com/pprcht/gfnff) based on F2PY. +PyGFNFF is a Python library that provides the [GFN-FF](https://github.com/pprcht/gfnff) (Generic Force Field) method for computational chemistry calculations. It is based on F2PY (Fortran to Python interface) and integrates with the Atomic Simulation Environment (ASE). --- +## Project Structure + +``` +PyGFNFF/ +├── pygfnff/ # Python package +│ ├── __init__.py # Exports GFNFF calculator and gfnff function +│ └── _pygfnff.py # Main implementation +├── fortran/ # Fortran source code +│ ├── gfnff_*.f90 # GFN-FF modules +│ ├── _pygfnfflib.f90 # F2PY interface +│ ├── CMakeLists.txt # Fortran build configuration +│ └── gbsa/ # GBSA solvation model +├── include/ # C header and parameter files +│ ├── gfnff_interface_c.h +│ └── param_*.fh # Parameter files for solvents +├── tests/ # Test suite +│ ├── test_co_by_ase.py +│ └── test_coffeine.py +├── CMakeLists.txt # Root CMake configuration +└── pyproject.toml # Python project configuration +``` + +## Key Components + +### Python Interface (`pygfnff/`) + +- **`GFNFF`**: ASE Calculator subclass for non-PBC systems +- **`gfnff()`**: Low-level function for single-point energy calculations + +### Fortran Backend (`fortran/`) + +- GFN-FF implementation derived from https://github.com/pprcht/gfnff (commit 0491df2) +- GBSA solvation model support (optional, enabled via CMake `WITH_GBSA`) +- F2PY bindings via `_pygfnfflib.f90` + + ## Usage There is an `ase.Calculator` subclass termed `GFNFF` for non-PBC system. And a more low function called `gfnff` can be found in [the code](https://github.com/LiuGaoyong/PyGFNFF/blob/main/pygfnff/_pygfnff.py). diff --git a/pyproject.toml b/pyproject.toml index a831ba4..9602b7e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,7 +9,7 @@ build-backend = "scikit_build_core.build" [project] name = "pygfnff" -version = "v0.0.3" +version = "v0.0.4" description = "A Python Library for GFN-FF." readme = "README.md" authors = [{ name = "Liu Gaoyong", email = "liugaoyong_88@163.com" }] diff --git a/uv.lock b/uv.lock index 74bd414..560d9b0 100644 --- a/uv.lock +++ b/uv.lock @@ -1,5 +1,5 @@ version = 1 -revision = 1 +revision = 3 requires-python = ">=3.9" resolution-markers = [ "python_full_version >= '3.11'", @@ -904,7 +904,7 @@ wheels = [ [[package]] name = "pygfnff" -version = "0.0.3" +version = "0.0.4" source = { virtual = "." } dependencies = [ { name = "ase" },