diff --git a/.github/workflows/conda.yml b/.github/workflows/conda.yml deleted file mode 100644 index 6e642b8..0000000 --- a/.github/workflows/conda.yml +++ /dev/null @@ -1,48 +0,0 @@ -name: Conda - -on: - workflow_dispatch: - push: - branches: - - master - pull_request: - -jobs: - build: - strategy: - fail-fast: false - matrix: - platform: [ubuntu-latest, windows-latest, macos-latest] - python-version: ["3.8", "3.10"] - - runs-on: ${{ matrix.platform }} - - # The setup-miniconda action needs this to activate miniconda - defaults: - run: - shell: "bash -l {0}" - - steps: - - uses: actions/checkout@v3 - with: - submodules: true - - - name: Get conda - uses: conda-incubator/setup-miniconda@v2.2.0 - with: - python-version: ${{ matrix.python-version }} - channels: conda-forge - channel-priority: strict - - # Currently conda-build requires the dead package "toml" but doesn't declare it - - name: Prepare - run: conda install conda-build conda-verify pytest toml - - - name: Build - run: conda build conda.recipe - - - name: Install - run: conda install -c ${CONDA_PREFIX}/conda-bld/ cmake_example - - - name: Test - run: python -m pytest diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml deleted file mode 100644 index c792242..0000000 --- a/.github/workflows/format.yml +++ /dev/null @@ -1,22 +0,0 @@ -# This is a format job. Pre-commit has a first-party GitHub action, so we use -# that: https://github.com/pre-commit/action - -name: Format - -on: - workflow_dispatch: - pull_request: - push: - branches: - - master - -jobs: - pre-commit: - name: Format - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 - with: - python-version: "3.x" - - uses: pre-commit/action@v3.0.0 diff --git a/.github/workflows/pip.yml b/.github/workflows/pip.yml index 5e8a046..f9da1c2 100644 --- a/.github/workflows/pip.yml +++ b/.github/workflows/pip.yml @@ -12,25 +12,48 @@ jobs: strategy: fail-fast: false matrix: - platform: [windows-latest, macos-latest, ubuntu-latest] - python-version: ["3.8", "3.11"] + python-version: ["3.10", "3.12"] - runs-on: ${{ matrix.platform }} + runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: submodules: true - - uses: actions/setup-python@v4 + - uses: conda-incubator/setup-miniconda@v3 with: + activate-environment: ci + auto-activate-base: false + environment-file: environment.yml python-version: ${{ matrix.python-version }} - - name: Add requirements + - name: Add Python requirements + shell: bash -el {0} run: python -m pip install --upgrade wheel setuptools - - name: Build and install + - name: Build with CMake + shell: bash -el {0} + run: | + mkdir -p build + cd build + cmake -DCMAKE_BUILD_TYPE=Release .. + make -j$(nproc) + + - name: Install Python package + shell: bash -el {0} run: pip install --verbose .[test] + - name: Add dftd4 binary to PATH + shell: bash -el {0} + run: echo "${{ github.workspace }}/build/dftd4/app" >> $GITHUB_PATH + + - name: Verify dftd4 binary + shell: bash -el {0} + run: | + which dftd4 + dftd4 --version || true + - name: Test + shell: bash -el {0} run: python -m pytest diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml deleted file mode 100644 index 7299cb6..0000000 --- a/.github/workflows/wheels.yml +++ /dev/null @@ -1,79 +0,0 @@ -name: Wheels - -on: - workflow_dispatch: - pull_request: - push: - branches: - - master - release: - types: - - published - -jobs: - build_sdist: - name: Build SDist - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - with: - submodules: true - - - name: Build SDist - run: pipx run build --sdist - - - name: Check metadata - run: pipx run twine check dist/* - - - uses: actions/upload-artifact@v3 - with: - path: dist/*.tar.gz - - - build_wheels: - name: Wheels on ${{ matrix.os }} - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - os: [ubuntu-latest, windows-latest, macos-latest] - - steps: - - uses: actions/checkout@v3 - with: - submodules: true - - - uses: pypa/cibuildwheel@v2.14 - env: - CIBW_ARCHS_MACOS: auto universal2 - CIBW_PRERELEASE_PYTHONS: "1" - - - name: Verify clean directory - run: git diff --exit-code - shell: bash - - - name: Upload wheels - uses: actions/upload-artifact@v3 - with: - path: wheelhouse/*.whl - - - upload_all: - name: Upload if release - needs: [build_wheels, build_sdist] - runs-on: ubuntu-latest - if: github.event_name == 'release' && github.event.action == 'published' - - steps: - - uses: actions/setup-python@v4 - with: - python-version: "3.x" - - - uses: actions/download-artifact@v3 - with: - name: artifact - path: dist - - - uses: pypa/gh-action-pypi-publish@release/v1 - with: - password: ${{ secrets.pypi_password }} diff --git a/.gitmodules b/.gitmodules index f207c3b..5645cc9 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,4 +4,4 @@ branch = master [submodule "dftd4"] path = dftd4 - url = git@github.com:Awallace3/dftd4.git + url = https://github.com/Awallace3/dftd4.git diff --git a/dftd4 b/dftd4 index 8ced737..ac6aa3b 160000 --- a/dftd4 +++ b/dftd4 @@ -1 +1 @@ -Subproject commit 8ced73763a835934b5994309a261fe688bf26f4d +Subproject commit ac6aa3b18b8ca2c3b2860710c009a6b9803853a3 diff --git a/environment.yml b/environment.yml new file mode 100644 index 0000000..ba82920 --- /dev/null +++ b/environment.yml @@ -0,0 +1,23 @@ +name: disp +channels: + - conda-forge + - nodefaults +dependencies: + # build + - c-compiler + - cmake + - cxx-compiler + - ninja + - eigen + - libblas=*=*mkl + - libboost-headers + - llvm-openmp + - numpy + - pip + - python + - fortran-compiler + - zlib + - setuptools + - pytest + - pytest-xdist + - qcelemental diff --git a/setup.py b/setup.py index 56bd7fc..e231f8b 100644 --- a/setup.py +++ b/setup.py @@ -262,7 +262,7 @@ def run(self): }, zip_safe=False, extras_require={ - "test": ["pytest>=6.0"], + "test": ["pytest>=6.0", "numpy", "qcelemental"], }, python_requires=">=3.8", classifiers=[ diff --git a/src/binder.cpp b/src/binder.cpp index 7bf7b26..efa6ef1 100644 --- a/src/binder.cpp +++ b/src/binder.cpp @@ -109,6 +109,15 @@ PYBIND11_MODULE(dispersion, m) { py::arg("pos"), py::arg("carts"), py::arg("C6s"), py::arg("C8s"), py::arg("C10s"), py::arg("RCs"), py::arg("params")); + m_d.def("disp_2B_XDM_inter", &disp::disp_2B_XDM_inter, R"pbdoc( + calculate intermolecular XDM dispersion energy using dimer-level C6s, C8s, + C10s, RCs matrices with monA/monB indices to restrict summation to + intermolecular atom pairs only. params = [a1, a2] + )pbdoc", + py::arg("pos"), py::arg("carts"), py::arg("C6s"), py::arg("C8s"), + py::arg("C10s"), py::arg("RCs"), py::arg("monAs"), py::arg("monBs"), + py::arg("params")); + m_d.def("disp_2B_dimer", &disp::disp_2B_dimer, R"pbdoc( calculate 2-body -D4 dispersion energy from positions, cartesians, C6s, and params for a dimer broken into two monomers with C6s and C8s diff --git a/src/disp.cpp b/src/disp.cpp index 6138542..8f1b907 100644 --- a/src/disp.cpp +++ b/src/disp.cpp @@ -167,6 +167,45 @@ double disp_2B_XDM_scaled(Ref pos, py::EigenDRef carts, return energy; }; +double disp_2B_XDM_inter(Ref pos, py::EigenDRef carts, + py::EigenDRef C6s, py::EigenDRef C8s, + py::EigenDRef C10s, py::EigenDRef RCs, + Ref monAs, Ref monBs, + Ref params) { + // Intermolecular XDM dispersion: only sum over pairs (i in monAs, j in monBs) + // Uses dimer-level C6s, C8s, C10s, RCs matrices indexed by dimer atom indices + // params[0] = a1, params[1] = a2 + double energy = 0; + double dis; + int A, B, i, j; + double a1, a2, de; + double ang_to_bohr = 1.8897261245650624; + a1 = params[0]; + a2 = params[1] * ang_to_bohr; +#pragma omp parallel for shared(C6s, C8s, C10s, RCs, carts, a1, a2, pos, monAs, \ + monBs) private(A, B, i, j, dis, de) \ + reduction(+ : energy) + for (A = 0; A < monAs.size(); A++) { + i = monAs[A]; + for (B = 0; B < monBs.size(); B++) { + j = monBs[B]; + double dx = carts(i, 0) - carts(j, 0); + double dy = carts(i, 1) - carts(j, 1); + double dz = carts(i, 2) - carts(j, 2); + double d2 = dx * dx + dy * dy + dz * dz; + double d6 = d2 * d2 * d2; + double d8 = d6 * d2; + double d10 = d8 * d2; + dis = a1 * RCs(i, j) + a2; + + de = -C6s(i, j) / (d6 + pow(dis, 6)) - C8s(i, j) / (d8 + pow(dis, 8)) - + C10s(i, j) / (d10 + pow(dis, 10)); + energy += de; + } + }; + return energy; +}; + double disp_2B_dimer(Ref pos, py::EigenDRef carts, py::EigenDRef C6s, Ref pA, py::EigenDRef cA, py::EigenDRef C6s_A, @@ -1312,7 +1351,6 @@ double disp_ATM_CHG_trimer_nambe(Ref pos, r3 = r2 * r1; r5 = r3 * r2; fdmp = 1.0 / (1.0 + 6.0 * pow(r0 / r1, alph / 3.0)); - printf("fdmp: %f\n", fdmp); ang = (0.375 * (dis_ij + dis_jk - dis_ik) * (dis_ij - dis_jk + dis_ik) * (-dis_ij + dis_jk + dis_ik) / r5 + 1.0 / r3); @@ -1386,7 +1424,6 @@ double disp_ATM_TT_trimer_nambe(Ref pos, (-dis_ij + dis_jk + dis_ik) / r5 + 1.0 / r3); fdmp = f6_ij * f6_ik * f6_jk; - printf("fdmp: %f\n", fdmp); energy -= 6 * (ang * fdmp * c9 * triple / 6.0); }; }; diff --git a/src/disp.hpp b/src/disp.hpp index 63c2569..1167e05 100644 --- a/src/disp.hpp +++ b/src/disp.hpp @@ -36,6 +36,12 @@ double disp_2B_XDM_scaled(Ref pos, py::EigenDRef carts, py::EigenDRef C10s, py::EigenDRef RCs, Ref params); +double disp_2B_XDM_inter(Ref pos, py::EigenDRef carts, + py::EigenDRef C6s, py::EigenDRef C8s, + py::EigenDRef C10s, py::EigenDRef RCs, + Ref monAs, Ref monBs, + Ref params); + double disp_2B_dimer(Ref pos, py::EigenDRef carts, py::EigenDRef C6s, Ref pA, py::EigenDRef cA, py::EigenDRef C6s_A, diff --git a/tests/test_basic.py b/tests/test_basic.py index f37854c..ba9b0b9 100644 --- a/tests/test_basic.py +++ b/tests/test_basic.py @@ -34,7 +34,7 @@ def test_disp_ATM_CHG_trimer_nambe(): } geom = np.hstack((data["symbols"].reshape(-1, 1), data["geometry"])) qcel_trimer = qcel.models.Molecule.from_data(geom, frags=data["frags"]) - print(qcel_trimer) + # print(qcel_trimer) C6s, C8s, C6s_ATM = pydispersion.qcel_mol_acquire_c6s(qcel_trimer) # Same parameters as Yi in # https://pubs.aip.org/aip/jcp/article/158/9/094110/2881313/Assessment-of-three-body-dispersion-models-against @@ -46,7 +46,7 @@ def test_disp_ATM_CHG_trimer_nambe(): "s9": 1.0, }, ) - print(f"nambe_ATM: {nambe_ATM}") + # print(f"nambe_ATM: {nambe_ATM}") return @@ -81,7 +81,7 @@ def test_disp_ATM_TT_trimer_nambe(): } geom = np.hstack((data["symbols"].reshape(-1, 1), data["geometry"])) qcel_trimer = qcel.models.Molecule.from_data(geom, frags=data["frags"]) - print(qcel_trimer) + # print(qcel_trimer) C6s, C8s, C6s_ATM = pydispersion.qcel_mol_acquire_c6s(qcel_trimer) # Same parameters as Yi in # https://pubs.aip.org/aip/jcp/article/158/9/094110/2881313/Assessment-of-three-body-dispersion-models-against @@ -93,7 +93,7 @@ def test_disp_ATM_TT_trimer_nambe(): "s9": 1.0, }, ) - print(f"nambe_ATM: {nambe_ATM}") + # print(f"nambe_ATM: {nambe_ATM}") return if __name__ == "__main__":