├── .codecov.yml ├── .gitattributes ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── dco.yml └── workflows │ ├── codeql.yml │ ├── docs.yml │ ├── fortran-build.yml │ └── wheel.yml ├── .gitignore ├── .gitmodules ├── .readthedocs.yaml ├── CITATION.bib ├── CMakeLists.txt ├── COPYING ├── COPYING.LESSER ├── README.md ├── app ├── 01-ammonia.tmol ├── 01-energy-d4s.json ├── 01-energy.json ├── 02-gradient-d4s.json ├── 02-gradient.json ├── 02-nitralin.mol ├── 03-lenalidomid.gen ├── 03-properties.json ├── 04-caffeine.xyz ├── 04-pair-analysis.json ├── 05-r2scan3c.json ├── 06-r2scan3c-mod.json ├── CMakeLists.txt ├── argument.f90 ├── cli.f90 ├── driver.f90 ├── help.f90 ├── main.f90 ├── meson.build └── tester.py ├── assets ├── aur │ └── README.md ├── ci │ ├── build-env.yaml │ ├── python-env.yaml │ ├── setup-intel.sh │ └── wheel-req.txt ├── dftd4.wrap └── parameters.toml ├── config ├── CMakeLists.txt ├── cmake │ ├── Findcustom-blas.cmake │ ├── Findmctc-lib.cmake │ ├── Findmstore.cmake │ ├── Findmulticharge.cmake │ └── dftd4-utils.cmake ├── install-mod.py ├── meson.build ├── template.cmake └── template.pc ├── doc ├── _static │ ├── dftd4.svg │ └── references.bib ├── conf.py ├── index.rst ├── recipe │ ├── index.rst │ ├── installation.rst │ └── vasp.rst ├── reference │ ├── ase.rst │ ├── c.rst │ ├── fortran.rst │ ├── index.rst │ ├── pyscf.rst │ ├── python.rst │ └── qcschema.rst └── requirements.txt ├── ford.md ├── fpm.toml ├── include └── dftd4.h ├── man └── dftd4.1.adoc ├── meson.build ├── meson_options.txt ├── python ├── .gitignore ├── COPYING ├── COPYING.LESSER ├── README.rst ├── dftd4 │ ├── __init__.py │ ├── ase.py │ ├── data.py │ ├── interface.py │ ├── library.py │ ├── meson.build │ ├── parameters.py │ ├── pyscf.py │ ├── qcschema.py │ ├── references.json │ ├── test_ase.py │ ├── test_interface.py │ ├── test_library.py │ ├── test_parameters.py │ ├── test_pyscf.py │ └── test_qcschema.py ├── ffibuilder.py ├── include │ └── _dftd4.h ├── meson.build ├── meson_options.txt └── pyproject.toml ├── src ├── CMakeLists.txt ├── dftd4.f90 ├── dftd4 │ ├── CMakeLists.txt │ ├── api.f90 │ ├── blas.F90 │ ├── charge.f90 │ ├── compat.f90 │ ├── cutoff.f90 │ ├── damping.f90 │ ├── damping │ │ ├── CMakeLists.txt │ │ ├── atm.f90 │ │ ├── meson.build │ │ └── rational.f90 │ ├── data.f90 │ ├── data │ │ ├── CMakeLists.txt │ │ ├── covrad.f90 │ │ ├── en.f90 │ │ ├── hardness.f90 │ │ ├── meson.build │ │ ├── r4r2.f90 │ │ ├── wfpair.f90 │ │ └── zeff.f90 │ ├── disp.f90 │ ├── meson.build │ ├── model.f90 │ ├── model │ │ ├── CMakeLists.txt │ │ ├── d4.f90 │ │ ├── d4s.f90 │ │ ├── meson.build │ │ ├── type.f90 │ │ └── utils.f90 │ ├── ncoord.f90 │ ├── numdiff.f90 │ ├── output.f90 │ ├── param.f90 │ ├── reference.f90 │ ├── reference.inc │ ├── utils.f90 │ └── version.f90 └── meson.build ├── subprojects ├── .gitignore ├── mctc-lib.wrap ├── mstore.wrap └── multicharge.wrap └── test ├── CMakeLists.txt ├── api ├── CMakeLists.txt ├── example.c └── meson.build ├── meson.build └── unit ├── CMakeLists.txt ├── main.f90 ├── meson.build ├── test_dftd4.f90 ├── test_model.f90 ├── test_pairwise.f90 ├── test_param.f90 └── test_periodic.f90 /.codecov.yml: -------------------------------------------------------------------------------- 1 | fixes: 2 | - "/home/runner/work/dftd4/dftd4::" 3 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | 3 | # Fortran include files 4 | *.inc linguist-language=Fortran 5 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behaviour: 15 | 16 | 1. happens with input (include input files) 17 | 2. start `dftd4` with (all the options here) 18 | 3. output showing the error 19 | 20 | Please provide all input and output file such that we confirm your report. 21 | 22 | **Expected behaviour** 23 | A clear and concise description of what you expected to happen. 24 | 25 | **Additional context** 26 | Add any other context about the problem here. 27 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/dco.yml: -------------------------------------------------------------------------------- 1 | require: 2 | members: false 3 | -------------------------------------------------------------------------------- /.github/workflows/codeql.yml: -------------------------------------------------------------------------------- 1 | name: "CodeQL" 2 | 3 | on: 4 | push: 5 | branches: ["main"] 6 | pull_request: 7 | branches: ["main"] 8 | schedule: 9 | - cron: "6 8 * * 2" 10 | 11 | jobs: 12 | analyze: 13 | name: Analyze 14 | runs-on: ubuntu-latest 15 | permissions: 16 | actions: read 17 | contents: read 18 | security-events: write 19 | 20 | strategy: 21 | fail-fast: false 22 | matrix: 23 | language: [python] 24 | 25 | steps: 26 | - name: Checkout 27 | uses: actions/checkout@v4 28 | with: 29 | persist-credentials: false 30 | 31 | - name: Initialize CodeQL 32 | uses: github/codeql-action/init@v2 33 | with: 34 | languages: ${{ matrix.language }} 35 | queries: +security-and-quality 36 | 37 | - name: Autobuild 38 | uses: github/codeql-action/autobuild@v2 39 | 40 | - name: Perform CodeQL Analysis 41 | uses: github/codeql-action/analyze@v2 42 | with: 43 | category: "/language:${{ matrix.language }}" 44 | -------------------------------------------------------------------------------- /.github/workflows/docs.yml: -------------------------------------------------------------------------------- 1 | name: docs 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | pull_request: 9 | 10 | workflow_dispatch: 11 | 12 | jobs: 13 | build-and-deploy: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - id: deploy-on-push 17 | run: echo "result=$DEPLOY_BRANCH" >> $GITHUB_OUTPUT 18 | env: 19 | DEPLOY_BRANCH: ${{ secrets.DEPLOY_BRANCH && contains(github.ref, secrets.DEPLOY_BRANCH) && '1' || '0' }} 20 | 21 | - name: Set DEPLOY_BRANCH 22 | id: set-deploy-branch 23 | run: echo "DEPLOY_BRANCH=$DEPLOY_BRANCH" >> $GITHUB_ENV 24 | env: 25 | DEPLOY_BRANCH: ${{ secrets.DEPLOY_BRANCH && contains(github.ref, secrets.DEPLOY_BRANCH) && '1' || '0' }} 26 | 27 | - name: Validate DEPLOY_BRANCH 28 | run: | 29 | if [[ "$DEPLOY_BRANCH" != "1" && "$DEPLOY_BRANCH" != "0" ]]; then 30 | echo "Invalid DEPLOY_BRANCH value: $DEPLOY_BRANCH" 31 | exit 1 32 | fi 33 | env: 34 | DEPLOY_BRANCH: ${{ env.DEPLOY_BRANCH }} 35 | 36 | - name: Checkout code 37 | uses: actions/checkout@v4 38 | with: 39 | persist-credentials: false 40 | 41 | - name: Set up Python 42 | uses: actions/setup-python@v4 43 | with: 44 | python-version: "3.x" 45 | 46 | - name: Install dependencies 47 | run: pip install ford 48 | 49 | - name: Build Documentation 50 | run: ford ford.md 51 | 52 | - name: Deploy to GitHub Pages 53 | uses: JamesIves/github-pages-deploy-action@4.1.6 54 | if: ${{ github.event_name == 'push' && steps.deploy-on-push.outputs.result != '0' }} 55 | with: 56 | branch: gh-pages 57 | folder: _docs 58 | single-commit: true 59 | git-config-email: 49320512+dftd4@users.noreply.github.com 60 | git-config-name: DFT-D4 61 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | 34 | # Build directories 35 | /build*/ 36 | /install*/ 37 | /_*/ 38 | 39 | # Python files 40 | __pycache__ 41 | .idea/ 42 | 43 | # Project-specific files 44 | .EDISP 45 | dftd4.txt 46 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "assets/aur/dftd4"] 2 | path = assets/aur/dftd4 3 | url = https://aur.archlinux.org/dftd4.git 4 | [submodule "assets/aur/dftd4-git"] 5 | path = assets/aur/dftd4-git 6 | url = https://aur.archlinux.org/dftd4-git.git 7 | -------------------------------------------------------------------------------- /.readthedocs.yaml: -------------------------------------------------------------------------------- 1 | # .readthedocs.yaml 2 | # Read the Docs configuration file 3 | # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details 4 | 5 | # Required 6 | version: 2 7 | 8 | # Set the version of Python and other tools you might need 9 | build: 10 | os: ubuntu-22.04 11 | tools: 12 | python: "3.11" 13 | 14 | # Build documentation in the docs/ directory with Sphinx 15 | sphinx: 16 | configuration: doc/conf.py 17 | 18 | # We recommend specifying your dependencies to enable reproducible builds: 19 | # https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html 20 | python: 21 | install: 22 | - requirements: doc/requirements.txt 23 | 24 | -------------------------------------------------------------------------------- /CITATION.bib: -------------------------------------------------------------------------------- 1 | @article{dftd4-1, 2 | author = {Eike Caldeweyher and Christoph Bannwarth and Stefan Grimme}, 3 | journal = {J. Chem. Phys.}, 4 | title = {Extension of the D3 dispersion coefficient model}, 5 | year = {2017}, 6 | month = {7}, 7 | number = {3}, 8 | pages = {034112}, 9 | volume = {147}, 10 | doi = {10.1063/1.4993215}, 11 | publisher = {{AIP} Publishing} 12 | } 13 | 14 | @article{dftd4-2, 15 | author = {Eike Caldeweyher and Sebastian Ehlert and Andreas Hansen and Hagen Neugebauer and Sebastian Spicher and Christoph Bannwarth and Stefan Grimme}, 16 | journal = {J. Chem. Phys.}, 17 | title = {A generally applicable atomic-charge dependent London dispersion correction}, 18 | year = {2019}, 19 | month = {4}, 20 | number = {15}, 21 | pages = {154122}, 22 | volume = {150}, 23 | doi = {10.1063/1.5090222}, 24 | publisher = {{AIP} Publishing} 25 | } 26 | 27 | @article{dftd4-periodic, 28 | author = {Eike Caldeweyher and Jan-Michael Mewes and Sebastian Ehlert and Stefan Grimme}, 29 | journal = {Phys. Chem. Chem. Phys.}, 30 | title = {Extension and evaluation of the D4 London-dispersion model for periodic systems}, 31 | year = {2020}, 32 | number = {16}, 33 | pages = {8499--8512}, 34 | volume = {22}, 35 | doi = {10.1039/d0cp00502a}, 36 | publisher = {Royal Society of Chemistry ({RSC})} 37 | } 38 | 39 | @article{dftd4-rsh, 40 | author = {Friede, Marvin and Ehlert, Sebastian and Grimme, Stefan and Mewes, Jan-Michael}, 41 | title = {Do Optimally Tuned Range-Separated Hybrid Functionals Require a Reparametrization of the Dispersion Correction? It Depends}, 42 | journal = {Journal of Chemical Theory and Computation}, 43 | volume = {19}, 44 | number = {22}, 45 | pages = {8097-8107}, 46 | year = {2023}, 47 | doi = {10.1021/acs.jctc.3c00717}, 48 | note = {PMID: 37955590}, 49 | url = {https://doi.org/10.1021/acs.jctc.3c00717} 50 | } 51 | 52 | @article{dftd4-actinides, 53 | author = {Wittmann, Lukas and Gordiy, Igor and Friede, Marvin and Helmich-Paris, Benjamin and Grimme, Stefan and Hansen, Andreas and Bursch, Markus}, 54 | title = {Extension of the D3 and D4 London dispersion corrections to the full actinides series}, 55 | journal = {Phys. Chem. Chem. Phys.}, 56 | year = {2024}, 57 | volume = {26}, 58 | issue = {32}, 59 | pages = {21379-21394}, 60 | publisher = {The Royal Society of Chemistry}, 61 | doi = {10.1039/D4CP01514B}, 62 | url = {http://dx.doi.org/10.1039/D4CP01514B}, 63 | } 64 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # This file is part of dftd4. 2 | # SPDX-Identifier: LGPL-3.0-or-later 3 | # 4 | # dftd4 is free software: you can redistribute it and/or modify it under 5 | # the terms of the Lesser GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # dftd4 is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # Lesser GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the Lesser GNU General Public License 15 | # along with dftd4. If not, see . 16 | 17 | cmake_minimum_required(VERSION 3.14) 18 | 19 | project( 20 | "dftd4" 21 | LANGUAGES "Fortran" 22 | VERSION "3.7.0" 23 | DESCRIPTION "Generally Applicable Atomic-Charge Dependent London Dispersion Correction" 24 | ) 25 | 26 | # Follow GNU conventions for installing directories 27 | include(GNUInstallDirs) 28 | 29 | # General configuration information 30 | add_subdirectory("config") 31 | 32 | if(NOT TARGET "OpenMP::OpenMP_Fortran" AND WITH_OpenMP) 33 | find_package("OpenMP" REQUIRED) 34 | endif() 35 | 36 | if(WITH_ILP64 AND BLAS_LIBRARIES) 37 | message(STATUS "Using LAPACK/BLAS ILP64 interface") 38 | elseif(WITH_ILP64) 39 | message(FATAL_ERROR "ILP64 support needs BLAS_LIBRARIES") 40 | endif() 41 | 42 | if(NOT TARGET "BLAS::BLAS") 43 | find_package("custom-blas" REQUIRED) 44 | endif() 45 | 46 | # Collect subprojects 47 | if(NOT TARGET "mctc-lib::mctc-lib") 48 | find_package("mctc-lib") 49 | endif() 50 | if(NOT TARGET "mstore::mstore") 51 | find_package("mstore") 52 | endif() 53 | if(NOT TARGET "multicharge::multicharge") 54 | find_package("multicharge") 55 | endif() 56 | set( 57 | lib-deps 58 | "mctc-lib::mctc-lib" 59 | "multicharge::multicharge" 60 | ) 61 | 62 | # Collect source of the project 63 | set(srcs) 64 | add_subdirectory("src") 65 | 66 | # DFT-D4 library target 67 | add_library( 68 | "${PROJECT_NAME}-lib" 69 | "${srcs}" 70 | ) 71 | set_target_properties( 72 | "${PROJECT_NAME}-lib" 73 | PROPERTIES 74 | POSITION_INDEPENDENT_CODE TRUE 75 | OUTPUT_NAME "${PROJECT_NAME}" 76 | VERSION "${PROJECT_VERSION}" 77 | SOVERSION "${PROJECT_VERSION_MAJOR}" 78 | Fortran_MODULE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/include" 79 | ) 80 | target_link_libraries( 81 | "${PROJECT_NAME}-lib" 82 | PUBLIC 83 | "${lib-deps}" 84 | "$<$:OpenMP::OpenMP_Fortran>" 85 | ) 86 | target_include_directories( 87 | "${PROJECT_NAME}-lib" 88 | PUBLIC 89 | $ 90 | $ 91 | $ 92 | $ 93 | ) 94 | target_include_directories( 95 | "${PROJECT_NAME}-lib" 96 | PRIVATE 97 | ${CMAKE_CURRENT_SOURCE_DIR}/src/dftd4 98 | ) 99 | 100 | if(WITH_ILP64) 101 | target_compile_definitions( 102 | "${PROJECT_NAME}-lib" 103 | PUBLIC -DIK=i8) 104 | else() 105 | target_compile_definitions( 106 | "${PROJECT_NAME}-lib" 107 | PUBLIC -DIK=i4) 108 | endif() 109 | 110 | # Add example application 111 | add_subdirectory("app") 112 | 113 | # Export targets for other projects 114 | add_library("${PROJECT_NAME}" INTERFACE) 115 | target_link_libraries("${PROJECT_NAME}" INTERFACE "${PROJECT_NAME}-lib") 116 | install( 117 | TARGETS 118 | "${PROJECT_NAME}" 119 | "${PROJECT_NAME}-lib" 120 | EXPORT 121 | "${PROJECT_NAME}-targets" 122 | LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" 123 | ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" 124 | ) 125 | install( 126 | EXPORT 127 | "${PROJECT_NAME}-targets" 128 | NAMESPACE 129 | "${PROJECT_NAME}::" 130 | DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}" 131 | ) 132 | install( 133 | DIRECTORY 134 | "${CMAKE_CURRENT_BINARY_DIR}/include/" 135 | DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${module-dir}" 136 | ) 137 | if(WITH_API) 138 | enable_language("C") 139 | install( 140 | DIRECTORY 141 | "${CMAKE_CURRENT_SOURCE_DIR}/include/" 142 | DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" 143 | ) 144 | endif() 145 | # Package license files 146 | install( 147 | FILES 148 | "COPYING" 149 | "COPYING.LESSER" 150 | DESTINATION "${CMAKE_INSTALL_DATADIR}/licenses/${PROJECT_NAME}" 151 | ) 152 | 153 | # add the testsuite 154 | enable_testing() 155 | add_subdirectory("test") 156 | -------------------------------------------------------------------------------- /app/01-ammonia.tmol: -------------------------------------------------------------------------------- 1 | $coord 2 | 1.97420621099560E+00 1.97415497783241E+00 1.97424596974304E+00 N 3 | 6.82182427659395E+00 2.87346383480995E+00 7.72099517560089E+00 N 4 | 7.72104957181201E+00 6.82177051521773E+00 2.87336561318016E+00 N 5 | 2.87343220660781E+00 7.72108897828386E+00 6.82187093171878E+00 N 6 | 3.51863272100286E+00 2.63865333484548E+00 1.00652979981286E+00 H 7 | 2.63877594964754E+00 1.00647313885594E+00 3.51882748086447E+00 H 8 | 1.00639728563189E+00 3.51850454450845E+00 2.63869202592387E+00 H 9 | 8.36624975982697E+00 2.20896711017229E+00 8.68870955681018E+00 H 10 | 7.48639684558259E+00 3.84114715917956E+00 6.17640982573725E+00 H 11 | 5.85401675167715E+00 1.32911569888797E+00 7.05654606696031E+00 H 12 | 7.05646299938990E+00 5.85409590282274E+00 1.32879923864813E+00 H 13 | 8.68882633853582E+00 8.36611541129785E+00 2.20894120662207E+00 H 14 | 3.84121223226912E+00 6.17673669892998E+00 7.48629723649480E+00 H 15 | 1.32897854262127E+00 7.05658604099926E+00 5.85414031368096E+00 H 16 | 2.20884896069885E+00 8.68875820985799E+00 8.36643568423387E+00 H 17 | 6.17659142004652E+00 7.48627051643848E+00 3.84109594690835E+00 H 18 | $periodic 3 19 | $lattice 20 | 9.69523775911749 0.00000000000000 0.00000000000000 21 | 0.00000000000000 9.69523775911749 0.00000000000000 22 | 0.00000000000000 0.00000000000000 9.69523775911749 23 | $end 24 | -------------------------------------------------------------------------------- /app/01-energy-d4s.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "3.7.0", 3 | "energy": -2.6607170022857E-02 4 | } 5 | -------------------------------------------------------------------------------- /app/01-energy.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "3.1.0", 3 | "energy": -2.5957956130179434E-02 4 | } 5 | -------------------------------------------------------------------------------- /app/02-gradient-d4s.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "3.7.0", 3 | "energy": -1.1715899737148880E-02, 4 | "virial": [ 5 | 3.7851713933501705E-03, 6 | -8.1288172988859856E-04, 7 | 7.1872985559556118E-04, 8 | -8.1288172988859856E-04, 9 | 7.6271285791837395E-03, 10 | 4.9673613055807478E-04, 11 | 7.1872985559556129E-04, 12 | 4.9673613055807478E-04, 13 | 2.5557679250609640E-03 14 | ], 15 | "gradient": [ 16 | 5.0708719950501157E-06, 17 | 6.9790285785804521E-05, 18 | 7.4582379483635716E-05, 19 | 2.6758658553916956E-05, 20 | 6.8291798400885105E-05, 21 | 3.6759881358822335E-05, 22 | -1.5529094867403934E-05, 23 | 5.2360740334214594E-05, 24 | 5.3431230234034356E-05, 25 | -6.3119373387228183E-06, 26 | 3.1214699061503701E-05, 27 | 6.0937861068977001E-08, 28 | -5.7029639195333330E-06, 29 | 5.3610332896693898E-05, 30 | -4.9070935939292271E-05, 31 | -5.2189205334807051E-05, 32 | 5.3597739527035802E-05, 33 | -3.6345247975372378E-05, 34 | -3.2193863984979353E-05, 35 | 6.3050940822830315E-05, 36 | -7.4406219121144236E-05, 37 | -6.8199471199151069E-07, 38 | 2.4800444411536608E-06, 39 | 4.1668314838319672E-06, 40 | 4.7935669175707516E-05, 41 | -8.9185800761939102E-06, 42 | 4.4187557288377929E-06, 43 | 5.2979151308826060E-05, 44 | -5.1533875231268932E-05, 45 | 3.0711593412684880E-06, 46 | 1.4066680634948404E-05, 47 | -7.1035881518115326E-05, 48 | 3.3680744313132799E-06, 49 | -2.9389221372569086E-05, 50 | -6.8022388147806817E-05, 51 | 4.4063865455187328E-06, 52 | -4.1298549426047041E-05, 53 | -2.6538614213660617E-05, 54 | 5.7133966647469458E-06, 55 | -7.6446781370116375E-05, 56 | -1.7953651272498908E-05, 57 | 4.4407660447327063E-06, 58 | -8.0016860146350468E-05, 59 | -1.0581016208387845E-05, 60 | -2.7811899542245357E-05, 61 | -8.3546830039757863E-05, 62 | -1.6669008630562762E-05, 63 | 3.4432465592290238E-05, 64 | 2.3812380214019830E-05, 65 | -1.1684002908194005E-04, 66 | -1.6459621246456614E-05, 67 | 4.1901825929315152E-05, 68 | -5.5298626809437875E-05, 69 | 1.6125411888942118E-05, 70 | -1.8448502525466406E-05, 71 | -6.7274096432440124E-05, 72 | 1.3721139232111884E-05, 73 | 1.3714912277191165E-05, 74 | -6.0356444056628161E-05, 75 | -4.6329314505097146E-05, 76 | 7.7284864829571523E-05, 77 | 1.2708386125635737E-05, 78 | 4.6889168799917932E-07, 79 | 7.7237713501119115E-05, 80 | 1.7633592416565384E-05, 81 | 2.9688298304026077E-05, 82 | 8.4330592553775904E-05, 83 | 1.9663861619767448E-05, 84 | -3.2546049197661539E-05, 85 | -1.5120796151620731E-06, 86 | 1.0964990459210503E-05, 87 | 1.6021176317327828E-05, 88 | 1.0244388622063988E-05, 89 | 1.5134766002302252E-05, 90 | 2.0937787525761237E-05, 91 | 2.2011557406793824E-06, 92 | 2.3771471231183852E-05, 93 | 1.4791426291776318E-05, 94 | 1.9308809652847292E-06, 95 | 1.7332053458200055E-05, 96 | 1.7554027601555432E-05, 97 | 5.2017185849279400E-06, 98 | 1.6376459441194721E-05, 99 | 2.5857740812920871E-05, 100 | 9.5638420207772876E-07, 101 | 1.9530360103273072E-05, 102 | 7.4996334135244906E-06, 103 | 4.0630634209782417E-06, 104 | 8.0380387900326991E-06, 105 | 1.1826601794699065E-05, 106 | -8.2949178580240949E-06, 107 | 1.9146007324269666E-05, 108 | -7.5163575675225402E-06, 109 | -5.6109526891496664E-06, 110 | 7.4617872093392460E-06, 111 | -1.1492761254151282E-05, 112 | -9.0155187684656316E-06, 113 | 1.5741311365132330E-05, 114 | -1.7038284364516450E-05, 115 | -1.0872704967761594E-05, 116 | 1.3044294136487020E-05, 117 | -2.5790540671218004E-05, 118 | -2.8910685042547403E-06, 119 | 1.0985821515427485E-05, 120 | -1.6151938115027560E-05, 121 | -1.5229358339843181E-05, 122 | 1.0057621859720810E-05, 123 | -2.0771530621925347E-05, 124 | -1.1275265521351752E-05, 125 | 2.1436075701735326E-05, 126 | -1.4883288846923001E-05, 127 | 1.6460619722856689E-05, 128 | -1.0054436061838848E-05, 129 | 3.4858502718417217E-06, 130 | -1.1626784643225676E-05, 131 | -1.5629047576246960E-05, 132 | 3.5432729610590167E-06, 133 | 1.4505266325490599E-06, 134 | -6.9822951171518358E-06, 135 | -2.3029130827042162E-06, 136 | 7.6975944868542779E-06, 137 | -2.4480308489769973E-05, 138 | -5.6013584732218666E-06, 139 | 2.7848025932698499E-06, 140 | -2.5255181105650209E-05, 141 | -5.8552623491669292E-06 142 | ] 143 | } 144 | -------------------------------------------------------------------------------- /app/02-gradient.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "3.3.0", 3 | "energy": -1.1421068789694594E-02, 4 | "virial": [ 5 | 3.9165844609481372E-03, 6 | -7.9452543509793438E-04, 7 | 6.9571621273873275E-04, 8 | -7.9452543509793438E-04, 9 | 7.6720235247154499E-03, 10 | 4.7258510383686280E-04, 11 | 6.9571621273873307E-04, 12 | 4.7258510383686286E-04, 13 | 2.5948327118213372E-03 14 | ], 15 | "gradient": [ 16 | 5.4890876662500404E-06, 17 | 6.8905447786721675E-05, 18 | 7.2070052216048711E-05, 19 | 2.4930036834654630E-05, 20 | 6.7691563869255622E-05, 21 | 3.7700304546722816E-05, 22 | -1.4736600330367409E-05, 23 | 5.0856743815743789E-05, 24 | 5.1948469231735727E-05, 25 | -5.5630982195334975E-06, 26 | 2.7077022548787302E-05, 27 | 1.1709853718737010E-06, 28 | -5.4814452910103522E-06, 29 | 5.3354783358967081E-05, 30 | -5.0070001798715887E-05, 31 | -4.9371096057827503E-05, 32 | 5.3330637775583457E-05, 33 | -3.7238211656043093E-05, 34 | -3.2284809238574274E-05, 35 | 6.2055690601076177E-05, 36 | -7.2108620957980058E-05, 37 | -4.1493549933772412E-07, 38 | 1.0024803637166390E-06, 39 | 3.9850371883602319E-06, 40 | 5.0263498623665967E-05, 41 | -5.7893968688582054E-06, 42 | 4.3331181892400405E-06, 43 | 5.3979055291651126E-05, 44 | -4.7773948970397663E-05, 45 | 3.1020708488967720E-06, 46 | 1.4604165095962337E-05, 47 | -7.3704581645870666E-05, 48 | 3.2346766778437407E-06, 49 | -3.1735101843859748E-05, 50 | -6.4930828441567628E-05, 51 | 4.1568648266084882E-06, 52 | -4.4626268000078234E-05, 53 | -2.4542178129193826E-05, 54 | 5.2506564945890160E-06, 55 | -7.6487130949860982E-05, 56 | -1.6273015392162471E-05, 57 | 4.2102408044513196E-06, 58 | -8.0258430668872150E-05, 59 | -1.0419789403281010E-05, 60 | -2.7616987921682619E-05, 61 | -8.3718748527148007E-05, 62 | -1.6304508895742425E-05, 63 | 3.4174692867340408E-05, 64 | 2.4646593925862231E-05, 65 | -1.2128510361428890E-04, 66 | -1.5088755066311223E-05, 67 | 4.1513543795545927E-05, 68 | -5.5411950851423208E-05, 69 | 1.6366786924308155E-05, 70 | -1.8068887400930693E-05, 71 | -6.7233490324471832E-05, 72 | 1.3994731164539333E-05, 73 | 1.3038492575966103E-05, 74 | -5.7422367782667507E-05, 75 | -4.2009783716832734E-05, 76 | 7.6696835194624261E-05, 77 | 1.4286519179096965E-05, 78 | 5.0744157440020394E-07, 79 | 7.7380082160131638E-05, 80 | 1.7910888807345770E-05, 81 | 2.9525024593277162E-05, 82 | 8.4355670164167515E-05, 83 | 2.0039168588545728E-05, 84 | -3.2256599392487342E-05, 85 | 1.7760437187949364E-06, 86 | 1.4228919740082824E-05, 87 | 1.5791879994539008E-05, 88 | 5.0870776199930455E-06, 89 | 1.6779295096973123E-05, 90 | 2.0145601807769059E-05, 91 | 2.4459264358300038E-06, 92 | 1.9853909168675361E-05, 93 | 1.8271233453996398E-05, 94 | 8.3473761417685160E-06, 95 | 1.4040430107318220E-05, 96 | 1.6856636982711487E-05, 97 | 4.3462163463875292E-06, 98 | 2.0762925579628358E-05, 99 | 1.9138732443456433E-05, 100 | 1.6813259188241949E-06, 101 | 1.3629025280761206E-05, 102 | 1.3562010458450053E-05, 103 | -4.0645123376143335E-06, 104 | 1.1079770250857681E-05, 105 | 1.1536039162510016E-05, 106 | -6.7875253142938221E-06, 107 | 1.3858942633934986E-05, 108 | -1.2618273345569068E-05, 109 | -3.0887889184618994E-07, 110 | 1.2268776646226627E-05, 111 | -1.0984668301780144E-05, 112 | -1.3464852213635042E-05, 113 | 1.0139611173339474E-05, 114 | -1.6400450261450187E-05, 115 | -1.1910867065565125E-05, 116 | 1.7401733540289815E-05, 117 | -1.8988409045489166E-05, 118 | -7.2393400154619687E-06, 119 | 1.2703200821320033E-05, 120 | -1.5867164458465020E-05, 121 | -1.1133116040912580E-05, 122 | 1.3608536544769586E-05, 123 | -1.9996218133792218E-05, 124 | -1.0012689191157743E-05, 125 | 1.7782390248075313E-05, 126 | -1.8313133503013981E-05, 127 | 1.9049198201123272E-05, 128 | -1.0782724451800688E-05, 129 | 3.2796204108245434E-06, 130 | -1.3716049776340627E-05, 131 | -1.7287765338953561E-05, 132 | 3.1325053647752957E-06, 133 | 2.2289479399864011E-06, 134 | -1.0821119997796881E-05, 135 | -2.6618400426742859E-06, 136 | 3.4139406975064590E-06, 137 | -2.2685692457103688E-05, 138 | -7.6301645893656925E-06, 139 | 6.1112685255318218E-06, 140 | -2.1979950961512834E-05, 141 | -7.5961314076154966E-06 142 | ] 143 | } 144 | -------------------------------------------------------------------------------- /app/02-nitralin.mol: -------------------------------------------------------------------------------- 1 | 2 | 03092123493D 3 | 4 | 42 0 0 0 0 999 V2000 5 | 3.4480 3.6060 -0.0290 C 0 0 0 0 0 0 0 0 0 0 0 0 6 | 3.6340 2.8450 -1.3340 C 0 0 0 0 0 0 0 0 0 0 0 0 7 | 2.6190 1.7220 -1.5110 C 0 0 0 0 0 0 0 0 0 0 0 0 8 | 2.8010 1.0090 -2.7450 N 0 0 0 0 0 0 0 0 0 0 0 0 9 | 2.7100 1.7480 -4.0090 C 0 0 0 0 0 0 0 0 0 0 0 0 10 | 1.3460 2.3800 -4.1790 C 0 0 0 0 0 0 0 0 0 0 0 0 11 | 1.2060 3.1580 -5.4800 C 0 0 0 0 0 0 0 0 0 0 0 0 12 | 3.0770 -0.3690 -2.7670 C 0 0 0 0 0 0 0 0 0 0 0 0 13 | 4.3970 -0.8170 -2.7380 C 0 0 0 0 0 0 0 0 0 0 0 0 14 | 4.6710 -2.1850 -2.7600 C 0 0 0 0 0 0 0 0 0 0 0 0 15 | 3.6230 -3.1050 -2.8090 C 0 0 0 0 0 0 0 0 0 0 0 0 16 | 2.3020 -2.6570 -2.8380 C 0 0 0 0 0 0 0 0 0 0 0 0 17 | 2.0290 -1.2890 -2.8160 C 0 0 0 0 0 0 0 0 0 0 0 0 18 | 0.6710 -0.8620 -2.8470 N 0 0 0 0 0 0 0 0 0 0 0 0 19 | 0.1270 -0.6570 -3.9570 O 0 0 0 0 0 0 0 0 0 0 0 0 20 | 0.0630 -0.7040 -1.7630 O 0 0 0 0 0 0 0 0 0 0 0 0 21 | 3.9660 -4.8170 -2.8330 S 0 0 0 0 0 0 0 0 0 0 0 0 22 | 5.2710 -5.0220 -2.2210 O 0 0 0 0 0 0 0 0 0 0 0 0 23 | 2.8070 -5.5370 -2.3230 O 0 0 0 0 0 0 0 0 0 0 0 0 24 | 4.1040 -5.2150 -4.5610 C 0 0 0 0 0 0 0 0 0 0 0 0 25 | 5.4870 0.0970 -2.6860 N 0 0 0 0 0 0 0 0 0 0 0 0 26 | 5.9180 0.4620 -1.5670 O 0 0 0 0 0 0 0 0 0 0 0 0 27 | 5.9810 0.5100 -3.7610 O 0 0 0 0 0 0 0 0 0 0 0 0 28 | 4.1910 4.4040 0.0690 H 0 0 0 0 0 0 0 0 0 0 0 0 29 | 2.4540 4.0630 0.0020 H 0 0 0 0 0 0 0 0 0 0 0 0 30 | 3.5380 2.9420 0.8370 H 0 0 0 0 0 0 0 0 0 0 0 0 31 | 4.6430 2.4150 -1.3480 H 0 0 0 0 0 0 0 0 0 0 0 0 32 | 3.5690 3.5470 -2.1730 H 0 0 0 0 0 0 0 0 0 0 0 0 33 | 2.7220 0.9930 -0.7020 H 0 0 0 0 0 0 0 0 0 0 0 0 34 | 1.5940 2.1070 -1.4950 H 0 0 0 0 0 0 0 0 0 0 0 0 35 | 2.9060 1.0160 -4.7870 H 0 0 0 0 0 0 0 0 0 0 0 0 36 | 3.5110 2.4800 -3.9930 H 0 0 0 0 0 0 0 0 0 0 0 0 37 | 0.6010 1.5760 -4.1700 H 0 0 0 0 0 0 0 0 0 0 0 0 38 | 1.1190 3.0430 -3.3360 H 0 0 0 0 0 0 0 0 0 0 0 0 39 | 0.2080 3.6000 -5.5660 H 0 0 0 0 0 0 0 0 0 0 0 0 40 | 1.9390 3.9700 -5.5130 H 0 0 0 0 0 0 0 0 0 0 0 0 41 | 1.3760 2.5160 -6.3490 H 0 0 0 0 0 0 0 0 0 0 0 0 42 | 5.6990 -2.5390 -2.7380 H 0 0 0 0 0 0 0 0 0 0 0 0 43 | 1.4880 -3.3770 -2.8760 H 0 0 0 0 0 0 0 0 0 0 0 0 44 | 4.3180 -6.2760 -4.6330 H 0 0 0 0 0 0 0 0 0 0 0 0 45 | 3.1550 -4.9690 -5.0270 H 0 0 0 0 0 0 0 0 0 0 0 0 46 | 4.9130 -4.6180 -4.9680 H 0 0 0 0 0 0 0 0 0 0 0 0 47 | M END 48 | -------------------------------------------------------------------------------- /app/03-lenalidomid.gen: -------------------------------------------------------------------------------- 1 | 32 C 2 | O C N H 3 | 1 1 2.41991533900000E-01 2.20613779220000E+00 6.34791358700000E-01 4 | 2 2 -3.49920360500000E-01 1.14596821520000E+00 5.82644903500000E-01 5 | 3 3 1.07348430400000E-01 -1.27083519800000E-01 9.09970651200000E-01 6 | 4 2 1.51332303510000E+00 -4.70968533500000E-01 1.20770274880000E+00 7 | 5 2 1.99794023650000E+00 -1.44062429610000E+00 1.50324711900000E-01 8 | 6 1 1.55958567300000E+00 -2.56792043250000E+00 1.39556834600000E-01 9 | 7 3 2.92221040700000E+00 -1.00242939330000E+00 -7.81712554500000E-01 10 | 8 2 3.42413235130000E+00 2.81471551000000E-01 -9.07938231900000E-01 11 | 9 1 4.26073059370000E+00 5.62969663000000E-01 -1.73543837550000E+00 12 | 10 2 2.89300488820000E+00 1.33089460830000E+00 1.85039862000000E-02 13 | 11 2 2.43865274530000E+00 7.51467349600000E-01 1.36697077990000E+00 14 | 12 4 3.31736529160000E+00 4.79400130100000E-01 1.96285207130000E+00 15 | 13 4 1.90370583360000E+00 1.52121653630000E+00 1.93792558420000E+00 16 | 14 4 2.04792625940000E+00 1.82860251540000E+00 -4.69207606600000E-01 17 | 15 4 3.66430494730000E+00 2.09700854520000E+00 1.55116665300000E-01 18 | 16 4 3.25571920950000E+00 -1.68484267770000E+00 -1.44511940040000E+00 19 | 17 4 1.48155968250000E+00 -1.02818912240000E+00 2.15588140220000E+00 20 | 18 2 -8.98164396800000E-01 -1.17077063440000E+00 6.61285275500000E-01 21 | 19 2 -2.06567289130000E+00 -3.97037536200000E-01 1.37864781800000E-01 22 | 20 2 -3.32294808650000E+00 -8.36794798900000E-01 -2.88231306700000E-01 23 | 21 2 -4.22928125590000E+00 1.36920254900000E-01 -7.24055910400000E-01 24 | 22 2 -3.89546340270000E+00 1.47709714760000E+00 -7.40076522600000E-01 25 | 23 2 -2.64925981870000E+00 1.90165913270000E+00 -3.24065283800000E-01 26 | 24 2 -1.74002055450000E+00 9.55564529500000E-01 1.16700697600000E-01 27 | 25 4 -2.36927344180000E+00 2.94062727740000E+00 -3.37111624000000E-01 28 | 26 4 -4.61502764070000E+00 2.20148412380000E+00 -1.08411588860000E+00 29 | 27 4 -5.20360901060000E+00 -1.79568311200000E-01 -1.05128767420000E+00 30 | 28 3 -3.65067577220000E+00 -2.18305471950000E+00 -2.80498353200000E-01 31 | 29 4 -2.94221170750000E+00 -2.89521080640000E+00 -1.82925100800000E-01 32 | 30 4 -4.45879490940000E+00 -2.53022619770000E+00 -7.75658030400000E-01 33 | 31 4 -1.13779082160000E+00 -1.69612281550000E+00 1.58996349950000E+00 34 | 32 4 -5.13511826800000E-01 -1.88680920520000E+00 -7.13070833000000E-02 35 | -------------------------------------------------------------------------------- /app/04-caffeine.xyz: -------------------------------------------------------------------------------- 1 | 24 2 | 3 | C -3.2668063145 -1.0612383311 0.0019792586 4 | N -2.2766003898 -0.0195172936 -0.0013208218 5 | C -0.9134590858 -0.2019878522 0.0036747135 6 | C -0.3724701006 1.0762202467 0.0017569102 7 | N -1.3526586265 2.0066755645 -0.0051933750 8 | C -2.4700895686 1.3111433173 -0.0065911261 9 | H -3.4434528448 1.7598589152 -0.0115392456 10 | N 0.9701620055 1.2833365802 -0.0008793828 11 | C 1.8257144377 0.2028321683 -0.0007168653 12 | O 3.0278876281 0.3474912012 -0.0051812078 13 | N 1.2515027114 -1.0636950051 -0.0008922263 14 | C -0.1065018202 -1.3842039491 0.0029991689 15 | O -0.5015980556 -2.5366534217 0.0044099955 16 | C 2.2018357820 -2.1638123093 -0.0037185988 17 | H 1.6323675079 -3.0900622488 0.0097444448 18 | H 2.8244315108 -2.1119787186 -0.8964193499 19 | H 2.8450781508 -2.0977859157 0.8731480371 20 | C 1.5216365707 2.6211569486 0.0093869454 21 | H 0.7306184352 3.3088549484 -0.2771144995 22 | H 1.8886888508 2.8714188674 1.0060887389 23 | H 2.3551115434 2.6687817985 -0.6902763920 24 | H -2.7510404767 -2.0202634640 -0.0176576390 25 | H -3.9109098848 -0.9753935259 -0.8744768432 26 | H -3.8816811438 -0.9984445054 0.9013764258 27 | -------------------------------------------------------------------------------- /app/05-r2scan3c.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "3.6.0", 3 | "energy": -9.8497530849906E-03 4 | } 5 | -------------------------------------------------------------------------------- /app/06-r2scan3c-mod.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "3.6.0", 3 | "energy": -7.4859260608873E-03 4 | } 5 | -------------------------------------------------------------------------------- /app/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # This file is part of dftd4. 2 | # SPDX-Identifier: LGPL-3.0-or-later 3 | # 4 | # dftd4 is free software: you can redistribute it and/or modify it under 5 | # the terms of the GNU Lesser General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # dftd4 is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU Lesser General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU Lesser General Public License 15 | # along with dftd4. If not, see . 16 | 17 | add_executable( 18 | "${PROJECT_NAME}-exe" 19 | "main.f90" 20 | "argument.f90" 21 | "cli.f90" 22 | "driver.f90" 23 | "help.f90" 24 | ) 25 | set_target_properties( 26 | "${PROJECT_NAME}-exe" 27 | PROPERTIES 28 | OUTPUT_NAME "${PROJECT_NAME}" 29 | ) 30 | target_link_libraries( 31 | "${PROJECT_NAME}-exe" 32 | PRIVATE 33 | "${PROJECT_NAME}-lib" 34 | ) 35 | 36 | install( 37 | TARGETS 38 | "${PROJECT_NAME}-exe" 39 | DESTINATION 40 | "${CMAKE_INSTALL_BINDIR}" 41 | ) 42 | -------------------------------------------------------------------------------- /app/main.f90: -------------------------------------------------------------------------------- 1 | ! This file is part of dftd4. 2 | ! SPDX-Identifier: LGPL-3.0-or-later 3 | ! 4 | ! dftd4 is free software: you can redistribute it and/or modify it under 5 | ! the terms of the Lesser GNU General Public License as published by 6 | ! the Free Software Foundation, either version 3 of the License, or 7 | ! (at your option) any later version. 8 | ! 9 | ! dftd4 is distributed in the hope that it will be useful, 10 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | ! Lesser GNU General Public License for more details. 13 | ! 14 | ! You should have received a copy of the Lesser GNU General Public License 15 | ! along with dftd4. If not, see . 16 | 17 | !> Entry point for the command line interface of dftd4 18 | program driver 19 | use, intrinsic :: iso_fortran_env, only : error_unit 20 | use mctc_env, only : error_type 21 | use dftd4_cli, only : cli_config, get_arguments 22 | use dftd4_driver, only : main 23 | implicit none 24 | !> Configuration data deteriming the driver behaviour 25 | class(cli_config), allocatable :: config 26 | !> Error handling 27 | type(error_type), allocatable :: error 28 | 29 | call get_arguments(config, error) 30 | if (allocated(error)) then 31 | write(error_unit, '("[Error]:", 1x, a)') error%message 32 | error stop 33 | end if 34 | 35 | call main(config, error) 36 | if (allocated(error)) then 37 | write(error_unit, '("[Error]:", 1x, a)') error%message 38 | error stop 39 | end if 40 | 41 | end program driver 42 | -------------------------------------------------------------------------------- /app/meson.build: -------------------------------------------------------------------------------- 1 | # This file is part of dftd4. 2 | # SPDX-Identifier: LGPL-3.0-or-later 3 | # 4 | # dftd4 is free software: you can redistribute it and/or modify it under 5 | # the terms of the Lesser GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # dftd4 is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # Lesser GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the Lesser GNU General Public License 15 | # along with dftd4. If not, see . 16 | 17 | dftd4_exe = executable( 18 | meson.project_name(), 19 | sources: files( 20 | 'main.f90', 21 | 'argument.f90', 22 | 'cli.f90', 23 | 'driver.f90', 24 | 'help.f90', 25 | ), 26 | dependencies: dftd4_dep, 27 | install: install, 28 | link_language: 'fortran', 29 | ) 30 | 31 | test('app-version', dftd4_exe, args: '--version') 32 | test('app-help', dftd4_exe, args: '--help') 33 | test('app-help-run', dftd4_exe, args: ['run', '--help']) 34 | test('app-help-param', dftd4_exe, args: ['param', '--help']) 35 | test('app-param-list', dftd4_exe, args: ['param', '--list']) 36 | test('app-license', dftd4_exe, args: '--license') 37 | test('app-citation', dftd4_exe, args: '--citation') 38 | test('app-noargs', dftd4_exe, should_fail: true) 39 | 40 | app_tester = find_program(files('tester.py')) 41 | 42 | test( 43 | 'app-energy', 44 | app_tester, 45 | args: [ 46 | dftd4_exe, 47 | files('01-energy.json'), 48 | files('01-ammonia.tmol'), 49 | '--noedisp', 50 | '--func', 'tpssh' 51 | ], 52 | ) 53 | test( 54 | 'app-energy-d4s', 55 | app_tester, 56 | args: [ 57 | dftd4_exe, 58 | files('01-energy-d4s.json'), 59 | files('01-ammonia.tmol'), 60 | '--noedisp', 61 | '--func', 'tpssh', 62 | '--model', 'D4S' 63 | ], 64 | ) 65 | test( 66 | 'app-gradient', 67 | app_tester, 68 | args: [ 69 | dftd4_exe, 70 | files('02-gradient.json'), 71 | '--noedisp', 72 | '--func', 'scan', 73 | '--grad', 74 | '--', 75 | files('02-nitralin.mol'), 76 | ], 77 | ) 78 | test( 79 | 'app-gradient-d4s', 80 | app_tester, 81 | args: [ 82 | dftd4_exe, 83 | files('02-gradient-d4s.json'), 84 | '--noedisp', 85 | '--func', 'scan', 86 | '--model', 'D4S', 87 | '--grad', 88 | '--', 89 | files('02-nitralin.mol'), 90 | ], 91 | ) 92 | test( 93 | 'app-properties', 94 | app_tester, 95 | args: [ 96 | dftd4_exe, 97 | files('03-properties.json'), 98 | files('03-lenalidomid.gen'), 99 | ], 100 | ) 101 | test( 102 | 'app-pair-analysis', 103 | app_tester, 104 | args: [ 105 | dftd4_exe, 106 | files('04-pair-analysis.json'), 107 | files('04-caffeine.xyz'), 108 | '--noedisp', 109 | '--pair-resolved', 110 | '--func', 'b3lyp', 111 | ], 112 | ) 113 | 114 | # r2SCAN-3c modifies s9, ga, gc, hence, requiring additional tests: 115 | # - selection via functional name 116 | # - check if s9, ga, gc can still be modified when name is given 117 | # - full manual specification via command line 118 | test( 119 | 'app-r2scan3c', 120 | app_tester, 121 | args: [ 122 | dftd4_exe, 123 | files('05-r2scan3c.json'), 124 | files('04-caffeine.xyz'), 125 | '--noedisp', 126 | '--func', 'r2scan-3c', 127 | ], 128 | ) 129 | test( 130 | 'app-r2scan3c-mod', 131 | app_tester, 132 | args: [ 133 | dftd4_exe, 134 | files('06-r2scan3c-mod.json'), 135 | files('04-caffeine.xyz'), 136 | '--noedisp', 137 | '--func', 'r2scan-3c', 138 | '--zeta', '4.0', '5.0', 139 | '--mbdscale', '1.0', 140 | ], 141 | ) 142 | test( 143 | 'app-r2scan3c-cli', 144 | app_tester, 145 | args: [ 146 | dftd4_exe, 147 | files('05-r2scan3c.json'), 148 | files('04-caffeine.xyz'), 149 | '--noedisp', 150 | '--param', '1.0', '0.0', '0.42', '5.65', 151 | '--mbdscale', '2.0', 152 | '--zeta', '2.0', '1.0', 153 | ], 154 | ) 155 | -------------------------------------------------------------------------------- /app/tester.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | """ 3 | Minimal Python wrapper for testing the dftd4 command line interface. 4 | 5 | The wrapper will assume a specific order in the arguments rather than 6 | providing a generic command line interface by itself since it is 7 | supposed to be used by meson for testing purposes only. 8 | """ 9 | 10 | try: 11 | import subprocess, sys, json, os, pytest 12 | except ImportError: 13 | exit(77) 14 | 15 | if len(sys.argv) < 4: 16 | raise RuntimeError("Requires at least four arguments") 17 | 18 | thr = 1.0e-9 19 | prog = sys.argv[1] 20 | outp = sys.argv[2] 21 | args = sys.argv[3:] 22 | 23 | stat = subprocess.call( 24 | [prog, "--json", os.path.basename(outp)] + args, 25 | shell=False, 26 | stdin=None, 27 | stderr=subprocess.STDOUT, 28 | ) 29 | if stat != 0: 30 | raise RuntimeError("Calculation failed") 31 | 32 | with open(outp) as f: 33 | ref = json.load(f) 34 | del ref["version"] 35 | 36 | with open(os.path.basename(outp)) as f: 37 | res = json.load(f) 38 | 39 | for key in ref: 40 | if key not in res: 41 | raise RuntimeError("Missing '" + key + "' entry in results") 42 | assert pytest.approx(res[key], abs=thr) == ref[key] 43 | -------------------------------------------------------------------------------- /assets/aur/README.md: -------------------------------------------------------------------------------- 1 | # DFT-D4 on the Arch User Repository (AUR) 2 | 3 | [![AUR stable](https://img.shields.io/aur/version/dftd4?label=dftd4)](https://aur.archlinux.org/packages/dftd4/) 4 | [![AUR git](https://img.shields.io/aur/version/dftd4-git?label=dftd4-git)](https://aur.archlinux.org/packages/dftd4-git/) 5 | 6 | This program is available for Arch Linux via the [AUR](https://aur.archlinux.org). 7 | The necessary `PKGBUILD` files are provided here as git submodules linking 8 | to the AUR. 9 | 10 | Detailed information for packaging for the AUR can be found in the Arch Linux Wiki. 11 | -------------------------------------------------------------------------------- /assets/ci/build-env.yaml: -------------------------------------------------------------------------------- 1 | name: devel 2 | channels: 3 | - conda-forge 4 | dependencies: 5 | - meson !=1.8.0 6 | - fpm 7 | - cmake 8 | - ninja 9 | - gcovr 10 | - liblapack 11 | - pkg-config 12 | -------------------------------------------------------------------------------- /assets/ci/python-env.yaml: -------------------------------------------------------------------------------- 1 | name: python 2 | channels: 3 | - conda-forge 4 | dependencies: 5 | - python 6 | - pip 7 | - python-build 8 | - pkgconfig 9 | - pyscf 10 | - pytest 11 | - pytest-cov 12 | - coverage 13 | - cffi 14 | - numpy 15 | - ase 16 | - qcelemental 17 | - matplotlib-base 18 | - meson !=1.8.0 19 | -------------------------------------------------------------------------------- /assets/ci/setup-intel.sh: -------------------------------------------------------------------------------- 1 | set -ex 2 | if [ $(uname) = Darwin ]; then 3 | OUT=webimage-base.dmg 4 | URL=https://registrationcenter-download.intel.com/akdlm/irc_nas/17969/m_BaseKit_p_2021.3.0.3043.dmg 5 | COMPONENTS=intel.oneapi.mac.mkl.devel 6 | curl --output $OUT --url "$URL" --retry 5 --retry-delay 5 7 | hdiutil attach $OUT 8 | if [ -z "$COMPONENTS" ]; then 9 | sudo /Volumes/"$(basename "$URL" .dmg)"/bootstrapper.app/Contents/MacOS/bootstrapper -s --action install --eula=accept --continue-with-optional-error=yes --log-dir=. 10 | installer_exit_code=$? 11 | else 12 | sudo /Volumes/"$(basename "$URL" .dmg)"/bootstrapper.app/Contents/MacOS/bootstrapper -s --action install --components="$COMPONENTS" --eula=accept --continue-with-optional-error=yes --log-dir=. 13 | installer_exit_code=$? 14 | fi 15 | hdiutil detach /Volumes/"$(basename "$URL" .dmg)" -quiet 16 | 17 | URL=https://registrationcenter-download.intel.com/akdlm/irc_nas/17890/m_HPCKit_p_2021.3.0.3226_offline.dmg 18 | COMPONENTS=all 19 | curl --output $OUT --url "$URL" --retry 5 --retry-delay 5 20 | hdiutil attach $OUT 21 | if [ -z "$COMPONENTS" ]; then 22 | sudo /Volumes/"$(basename "$URL" .dmg)"/bootstrapper.app/Contents/MacOS/bootstrapper -s --action install --eula=accept --continue-with-optional-error=yes --log-dir=. 23 | installer_exit_code=$? 24 | else 25 | sudo /Volumes/"$(basename "$URL" .dmg)"/bootstrapper.app/Contents/MacOS/bootstrapper -s --action install --components="$COMPONENTS" --eula=accept --continue-with-optional-error=yes --log-dir=. 26 | installer_exit_code=$? 27 | fi 28 | hdiutil detach /Volumes/"$(basename "$URL" .dmg)" -quiet 29 | exit $installer_exit_code 30 | else 31 | KEY=GPG-PUB-KEY-INTEL-SW-PRODUCTS-2023.PUB 32 | wget https://apt.repos.intel.com/intel-gpg-keys/$KEY 33 | sudo apt-key add $KEY 34 | rm $KEY 35 | echo "deb https://apt.repos.intel.com/oneapi all main" | sudo tee /etc/apt/sources.list.d/oneAPI.list 36 | sudo apt-get update 37 | sudo apt-get install \ 38 | intel-oneapi-compiler-fortran-2021.2.0 \ 39 | intel-oneapi-compiler-dpcpp-cpp-and-cpp-classic-2021.2.0 \ 40 | intel-oneapi-mkl-devel-2021.2.0 41 | fi 42 | -------------------------------------------------------------------------------- /assets/ci/wheel-req.txt: -------------------------------------------------------------------------------- 1 | git 2 | python 3 | pip 4 | python-build 5 | pkgconfig 6 | patchelf 7 | cffi 8 | numpy 9 | ase 10 | qcelemental 11 | matplotlib-base 12 | liblapack 13 | meson!=1.8.0 14 | setuptools 15 | unzip 16 | wheel 17 | -------------------------------------------------------------------------------- /assets/dftd4.wrap: -------------------------------------------------------------------------------- 1 | [wrap-git] 2 | directory = dftd4 3 | url = https://github.com/dftd4/dftd4.git 4 | revision = head 5 | -------------------------------------------------------------------------------- /config/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # This file is part of dftd4. 2 | # SPDX-Identifier: LGPL-3.0-or-later 3 | # 4 | # dftd4 is free software: you can redistribute it and/or modify it under 5 | # the terms of the Lesser GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # dftd4 is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # Lesser GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the Lesser GNU General Public License 15 | # along with dftd4. If not, see . 16 | 17 | option(BUILD_SHARED_LIBS "Whether the libraries built should be shared" FALSE) 18 | 19 | option(WITH_API "Enable support for C API via iso_c_binding module" TRUE) 20 | option(WITH_OpenMP "Enable support for shared memory parallelisation with OpenMP" TRUE) 21 | option(WITH_ILP64 "Enable support for ILP64 BLAS/LAPACK calls" FALSE) 22 | option(WITH_API_V2 "Enable the compatibility layer for the dftd4 2.5.x API" FALSE) 23 | if(NOT DEFINED "${PROJECT_NAME}-dependeny-method") 24 | set( 25 | "${PROJECT_NAME}-dependency-method" 26 | "subproject" "cmake" "pkgconf" "fetch" 27 | ) 28 | endif() 29 | 30 | set( 31 | "${PROJECT_NAME}-module-dir" 32 | "${PROJECT_NAME}/${CMAKE_Fortran_COMPILER_ID}-${CMAKE_Fortran_COMPILER_VERSION}" 33 | CACHE STRING 34 | "Subdirectory to install generated module files to" 35 | ) 36 | set( 37 | module-dir 38 | "${${PROJECT_NAME}-module-dir}" 39 | ) 40 | set(module-dir "${module-dir}" PARENT_SCOPE) 41 | 42 | # Compiler-specific configurations 43 | if( 44 | "${CMAKE_Fortran_COMPILER_ID}" STREQUAL "PGI" 45 | OR "${CMAKE_Fortran_COMPILER_ID}" STREQUAL "NVHPC" 46 | OR "${CMAKE_Fortran_COMPILER_ID}" STREQUAL "Flang" 47 | ) 48 | set( 49 | CMAKE_Fortran_FLAGS 50 | "${CMAKE_Fortran_FLAGS} -Mbackslash -Mallocatable=03" 51 | PARENT_SCOPE 52 | ) 53 | endif() 54 | 55 | # Set build type as CMake does not provide defaults 56 | if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) 57 | set( 58 | CMAKE_BUILD_TYPE "RelWithDebInfo" 59 | CACHE STRING "Build type to be used." 60 | FORCE 61 | ) 62 | message( 63 | STATUS 64 | "Setting build type to '${CMAKE_BUILD_TYPE}' as none was specified." 65 | ) 66 | endif() 67 | 68 | list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") 69 | set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH}" PARENT_SCOPE) 70 | install( 71 | DIRECTORY 72 | "${CMAKE_CURRENT_SOURCE_DIR}/cmake/" 73 | DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}" 74 | ) 75 | 76 | include(CMakePackageConfigHelpers) 77 | configure_package_config_file( 78 | "${CMAKE_CURRENT_SOURCE_DIR}/template.cmake" 79 | "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake" 80 | INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}" 81 | ) 82 | write_basic_package_version_file( 83 | "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake" 84 | VERSION "${PROJECT_VERSION}" 85 | COMPATIBILITY SameMinorVersion 86 | ) 87 | install( 88 | FILES 89 | "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake" 90 | "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake" 91 | DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}" 92 | ) 93 | 94 | configure_file( 95 | "${CMAKE_CURRENT_SOURCE_DIR}/template.pc" 96 | "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc" 97 | @ONLY 98 | ) 99 | install( 100 | FILES 101 | "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc" 102 | DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig" 103 | ) 104 | -------------------------------------------------------------------------------- /config/cmake/Findcustom-blas.cmake: -------------------------------------------------------------------------------- 1 | # This file is part of dftd4. 2 | # SPDX-Identifier: LGPL-3.0-or-later 3 | # 4 | # dftd4 is free software: you can redistribute it and/or modify it under 5 | # the terms of the GNU Lesser General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # dftd4 is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU Lesser General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU Lesser General Public License 15 | # along with dftd4. If not, see . 16 | 17 | if(NOT BLAS_FOUND) 18 | if("${BLA_VENDOR}" MATCHES "^Intel" OR DEFINED ENV{MKLROOT}) 19 | # C must be enabled to use MKL 20 | # https://cmake.org/cmake/help/v3.14/module/FindBLAS.html#result-variables 21 | enable_language("C") 22 | endif() 23 | find_package("BLAS" REQUIRED) 24 | if(NOT TARGET "BLAS::BLAS") 25 | add_library("BLAS::BLAS" INTERFACE IMPORTED) 26 | target_link_libraries("BLAS::BLAS" INTERFACE "${BLAS_LIBRARIES}") 27 | endif() 28 | endif() 29 | -------------------------------------------------------------------------------- /config/cmake/Findmctc-lib.cmake: -------------------------------------------------------------------------------- 1 | # This file is part of dftd4. 2 | # SPDX-Identifier: LGPL-3.0-or-later 3 | # 4 | # dftd4 is free software: you can redistribute it and/or modify it under 5 | # the terms of the GNU Lesser General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # dftd4 is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU Lesser General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU Lesser General Public License 15 | # along with dftd4. If not, see . 16 | 17 | set(_lib "mctc-lib") 18 | set(_pkg "MCTCLIB") 19 | set(_url "https://github.com/grimme-lab/mctc-lib") 20 | set(_rev "v0.4.1") 21 | 22 | if(NOT DEFINED "${_pkg}_FIND_METHOD") 23 | if(DEFINED "${PROJECT_NAME}-dependency-method") 24 | set("${_pkg}_FIND_METHOD" "${${PROJECT_NAME}-dependency-method}") 25 | else() 26 | set("${_pkg}_FIND_METHOD" "cmake" "pkgconf" "subproject" "fetch") 27 | endif() 28 | set("_${_pkg}_FIND_METHOD") 29 | endif() 30 | 31 | include("${CMAKE_CURRENT_LIST_DIR}/dftd4-utils.cmake") 32 | 33 | dftd4_find_package("${_lib}" "${${_pkg}_FIND_METHOD}" "${_url}" "${_rev}") 34 | 35 | if(DEFINED "_${_pkg}_FIND_METHOD") 36 | unset("${_pkg}_FIND_METHOD") 37 | unset("_${_pkg}_FIND_METHOD") 38 | endif() 39 | unset(_lib) 40 | unset(_pkg) 41 | unset(_url) 42 | unset(_rev) 43 | -------------------------------------------------------------------------------- /config/cmake/Findmstore.cmake: -------------------------------------------------------------------------------- 1 | # This file is part of dftd4. 2 | # SPDX-Identifier: LGPL-3.0-or-later 3 | # 4 | # dftd4 is free software: you can redistribute it and/or modify it under 5 | # the terms of the GNU Lesser General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # dftd4 is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU Lesser General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU Lesser General Public License 15 | # along with dftd4. If not, see . 16 | 17 | set(_lib "mstore") 18 | set(_pkg "MSTORE") 19 | set(_url "https://github.com/grimme-lab/mstore") 20 | set(_rev "v0.3.0") 21 | 22 | if(NOT DEFINED "${_pkg}_FIND_METHOD") 23 | if(DEFINED "${PROJECT_NAME}-dependency-method") 24 | set("${_pkg}_FIND_METHOD" "${${PROJECT_NAME}-dependency-method}") 25 | else() 26 | set("${_pkg}_FIND_METHOD" "cmake" "pkgconf" "subproject" "fetch") 27 | endif() 28 | set("_${_pkg}_FIND_METHOD") 29 | endif() 30 | 31 | include("${CMAKE_CURRENT_LIST_DIR}/dftd4-utils.cmake") 32 | 33 | dftd4_find_package("${_lib}" "${${_pkg}_FIND_METHOD}" "${_url}" "${_rev}") 34 | 35 | if(DEFINED "_${_pkg}_FIND_METHOD") 36 | unset("${_pkg}_FIND_METHOD") 37 | unset("_${_pkg}_FIND_METHOD") 38 | endif() 39 | unset(_lib) 40 | unset(_pkg) 41 | unset(_url) 42 | unset(_rev) 43 | -------------------------------------------------------------------------------- /config/cmake/Findmulticharge.cmake: -------------------------------------------------------------------------------- 1 | # This file is part of dftd4. 2 | # SPDX-Identifier: LGPL-3.0-or-later 3 | # 4 | # dftd4 is free software: you can redistribute it and/or modify it under 5 | # the terms of the GNU Lesser General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # dftd4 is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU Lesser General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU Lesser General Public License 15 | # along with dftd4. If not, see . 16 | 17 | set(_lib "multicharge") 18 | set(_pkg "MULTICHARGE") 19 | set(_url "https://github.com/grimme-lab/multicharge") 20 | set(_rev "v0.4.0") 21 | 22 | if(NOT DEFINED "${_pkg}_FIND_METHOD") 23 | if(DEFINED "${PROJECT_NAME}-dependency-method") 24 | set("${_pkg}_FIND_METHOD" "${${PROJECT_NAME}-dependency-method}") 25 | else() 26 | set("${_pkg}_FIND_METHOD" "cmake" "pkgconf" "subproject" "fetch") 27 | endif() 28 | set("_${_pkg}_FIND_METHOD") 29 | endif() 30 | 31 | include("${CMAKE_CURRENT_LIST_DIR}/dftd4-utils.cmake") 32 | 33 | dftd4_find_package("${_lib}" "${${_pkg}_FIND_METHOD}" "${_url}" "${_rev}") 34 | 35 | if(DEFINED "_${_pkg}_FIND_METHOD") 36 | unset("${_pkg}_FIND_METHOD") 37 | unset("_${_pkg}_FIND_METHOD") 38 | endif() 39 | unset(_lib) 40 | unset(_pkg) 41 | unset(_url) 42 | unset(_rev) 43 | -------------------------------------------------------------------------------- /config/cmake/dftd4-utils.cmake: -------------------------------------------------------------------------------- 1 | # This file is part of dftd4. 2 | # SPDX-Identifier: LGPL-3.0-or-later 3 | # 4 | # dftd4 is free software: you can redistribute it and/or modify it under 5 | # the terms of the GNU Lesser General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # dftd4 is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU Lesser General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU Lesser General Public License 15 | # along with dftd4. If not, see . 16 | 17 | # Handling of subproject dependencies 18 | macro( 19 | "dftd4_find_package" 20 | package 21 | methods 22 | url 23 | revision 24 | ) 25 | string(TOLOWER "${package}" _pkg_lc) 26 | string(TOUPPER "${package}" _pkg_uc) 27 | 28 | foreach(method in ITEMS ${methods}) 29 | 30 | if(TARGET "${package}::${package}") 31 | break() 32 | endif() 33 | 34 | if("${method}" STREQUAL "cmake") 35 | message(STATUS "${package}: Find installed package") 36 | find_package("${package}" CONFIG) 37 | if("${package}_FOUND") 38 | message(STATUS "${package}: Found installed package") 39 | break() 40 | endif() 41 | endif() 42 | 43 | if("${method}" STREQUAL "pkgconf") 44 | find_package(PkgConfig QUIET) 45 | pkg_check_modules("${_pkg_uc}" QUIET "${package}") 46 | if("${_pkg_uc}_FOUND") 47 | message(STATUS "Found ${package} via pkg-config") 48 | 49 | add_library("${package}::${package}" INTERFACE IMPORTED) 50 | target_link_libraries( 51 | "${package}::${package}" 52 | INTERFACE 53 | "${${_pkg_uc}_LINK_LIBRARIES}" 54 | ) 55 | target_include_directories( 56 | "${package}::${package}" 57 | INTERFACE 58 | "${${_pkg_uc}_INCLUDE_DIRS}" 59 | ) 60 | break() 61 | endif() 62 | endif() 63 | 64 | if("${method}" STREQUAL "subproject") 65 | set("${_pkg_uc}_SOURCE_DIR" "${PROJECT_SOURCE_DIR}/subprojects/${package}") 66 | set("${_pkg_uc}_BINARY_DIR" "${PROJECT_BINARY_DIR}/subprojects/${package}") 67 | if(EXISTS "${${_pkg_uc}_SOURCE_DIR}/CMakeLists.txt") 68 | message(STATUS "Include ${package} from subprojects") 69 | add_subdirectory( 70 | "${${_pkg_uc}_SOURCE_DIR}" 71 | "${${_pkg_uc}_BINARY_DIR}" 72 | ) 73 | 74 | add_library("${package}::${package}" INTERFACE IMPORTED) 75 | target_link_libraries("${package}::${package}" INTERFACE "${package}") 76 | 77 | # We need the module directory in the subproject before we finish the configure stage 78 | if(NOT EXISTS "${${_pkg_uc}_BINARY_DIR}/include") 79 | file(MAKE_DIRECTORY "${${_pkg_uc}_BINARY_DIR}/include") 80 | endif() 81 | 82 | break() 83 | endif() 84 | endif() 85 | 86 | if("${method}" STREQUAL "fetch") 87 | message(STATUS "Retrieving ${package} revision ${revision} from ${url}") 88 | include(FetchContent) 89 | FetchContent_Declare( 90 | "${_pkg_lc}" 91 | GIT_REPOSITORY "${url}" 92 | GIT_TAG "${revision}" 93 | ) 94 | FetchContent_MakeAvailable("${_pkg_lc}") 95 | 96 | add_library("${package}::${package}" INTERFACE IMPORTED) 97 | target_link_libraries("${package}::${package}" INTERFACE "${package}") 98 | 99 | # We need the module directory in the subproject before we finish the configure stage 100 | FetchContent_GetProperties("${_pkg_lc}" BINARY_DIR "${_pkg_uc}_BINARY_DIR") 101 | if(NOT EXISTS "${${_pkg_uc}_BINARY_DIR}/include") 102 | file(MAKE_DIRECTORY "${${_pkg_uc}_BINARY_DIR}/include") 103 | endif() 104 | 105 | break() 106 | endif() 107 | 108 | endforeach() 109 | 110 | unset(_pkg_lc) 111 | unset(_pkg_uc) 112 | 113 | if(NOT TARGET "${package}::${package}") 114 | message(FATAL_ERROR "Could not find dependency ${package}") 115 | endif() 116 | 117 | endmacro() 118 | -------------------------------------------------------------------------------- /config/install-mod.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # This file is part of dftd4. 3 | # SPDX-Identifier: LGPL-3.0-or-later 4 | # 5 | # dftd4 is free software: you can redistribute it and/or modify it under 6 | # the terms of the Lesser GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # dftd4 is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # Lesser GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the Lesser GNU General Public License 16 | # along with dftd4. If not, see . 17 | 18 | from os import environ, listdir, makedirs 19 | from os.path import join, isdir, exists 20 | from sys import argv 21 | from shutil import copy 22 | 23 | build_dir = environ["MESON_BUILD_ROOT"] 24 | if "MESON_INSTALL_DESTDIR_PREFIX" in environ: 25 | install_dir = environ["MESON_INSTALL_DESTDIR_PREFIX"] 26 | else: 27 | install_dir = environ["MESON_INSTALL_PREFIX"] 28 | 29 | include_dir = argv[1] if len(argv) > 1 else "include" 30 | module_dir = join(install_dir, include_dir) 31 | 32 | modules = [] 33 | for d in listdir(build_dir): 34 | bd = join(build_dir, d) 35 | if isdir(bd): 36 | for f in listdir(bd): 37 | if f.endswith(".mod"): 38 | modules.append(join(bd, f)) 39 | 40 | if not exists(module_dir): 41 | makedirs(module_dir) 42 | 43 | for mod in modules: 44 | print("Installing", mod, "to", module_dir) 45 | copy(mod, module_dir) 46 | -------------------------------------------------------------------------------- /config/meson.build: -------------------------------------------------------------------------------- 1 | # This file is part of dftd4. 2 | # SPDX-Identifier: LGPL-3.0-or-later 3 | # 4 | # dftd4 is free software: you can redistribute it and/or modify it under 5 | # the terms of the Lesser GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # dftd4 is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # Lesser GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the Lesser GNU General Public License 15 | # along with dftd4. If not, see . 16 | 17 | os = host_machine.system() 18 | fc = meson.get_compiler('fortran') 19 | cc = fc 20 | if has_cc 21 | cc = meson.get_compiler('c') 22 | endif 23 | fc_id = fc.get_id() 24 | 25 | # Treat Intel LLVM compiler as standard Intel compiler for compatibility 26 | if fc_id == 'intel-llvm' 27 | fc_id = 'intel' 28 | endif 29 | if fc_id == 'gcc' 30 | add_project_arguments( 31 | '-ffree-line-length-none', 32 | '-fbacktrace', 33 | language: 'fortran', 34 | ) 35 | elif fc_id == 'intel' 36 | add_project_arguments( 37 | '-traceback', 38 | language: 'fortran', 39 | ) 40 | elif fc_id == 'intel-cl' 41 | add_project_arguments( 42 | '-fpp', 43 | language: 'fortran', 44 | ) 45 | elif fc_id == 'pgi' or fc_id == 'nvidia_hpc' 46 | add_project_arguments( 47 | '-Mbackslash', 48 | '-Mallocatable=03', 49 | '-traceback', 50 | language: 'fortran', 51 | ) 52 | elif fc_id == 'flang' 53 | add_project_arguments( 54 | '-Mbackslash', 55 | '-Mallocatable=03', 56 | language: 'fortran', 57 | ) 58 | endif 59 | 60 | if get_option('openmp') 61 | omp_dep = dependency('openmp') 62 | lib_deps += omp_dep 63 | endif 64 | 65 | lapack_vendor = get_option('lapack') 66 | if lapack_vendor == 'auto' 67 | if fc_id == 'intel' 68 | lapack_vendor = 'mkl' 69 | endif 70 | endif 71 | 72 | if get_option('ilp64') 73 | ilp64 = true 74 | add_project_arguments('-DIK=i8', language:'fortran') 75 | else 76 | add_project_arguments('-DIK=i4', language:'fortran') 77 | ilp64 = false 78 | endif 79 | 80 | if lapack_vendor == 'mkl' 81 | mkl_dep = [] 82 | if fc_id == 'intel' 83 | mkl_dep += cc.find_library(ilp64 ? 'mkl_intel_ilp64' : 'mkl_intel_lp64') 84 | if get_option('openmp') 85 | mkl_dep += cc.find_library('mkl_intel_thread') 86 | endif 87 | elif fc_id == 'gcc' 88 | mkl_dep += cc.find_library(ilp64 ? 'mkl_gf_ilp64' : 'mkl_gf_lp64') 89 | if get_option('openmp') 90 | mkl_dep += cc.find_library('mkl_gnu_thread') 91 | endif 92 | else 93 | error('MKL not supported for this compiler') 94 | endif 95 | if not get_option('openmp') 96 | mkl_dep += cc.find_library('mkl_tbb_thread') 97 | endif 98 | mkl_dep += cc.find_library('mkl_core') 99 | lib_deps += mkl_dep 100 | 101 | elif lapack_vendor == 'mkl-rt' 102 | mkl_dep = cc.find_library('mkl_rt') 103 | lib_deps += mkl_dep 104 | 105 | elif lapack_vendor == 'openblas' 106 | openblas_dep = dependency( ilp64 ? 'openblas64' : 'openblas', required: false) 107 | if not openblas_dep.found() 108 | openblas_dep = cc.find_library( ilp64 ? 'openblas64' : 'openblas') 109 | endif 110 | lib_deps += openblas_dep 111 | if not fc.links('external dsytrs; call dsytrs(); end', dependencies: openblas_dep) 112 | lapack_dep = dependency(ilp64 ? 'lapack64' : 'lapack', required: false) 113 | if not lapack_dep.found() 114 | lapack_dep = cc.find_library(ilp64 ? 'lapack64' : 'lapack') 115 | endif 116 | lib_deps += lapack_dep 117 | endif 118 | 119 | elif lapack_vendor == 'custom' 120 | custom_deps = [] 121 | libs = get_option('custom_libraries') 122 | if libs[0].startswith('-L') 123 | foreach lib: libs 124 | if lib != libs[0] 125 | custom_deps += cc.find_library(lib, dirs: libs[0].substring(2)) 126 | endif 127 | endforeach 128 | else 129 | foreach lib: libs 130 | custom_deps += cc.find_library(lib) 131 | endforeach 132 | endif 133 | if (not fc.links('external dsytrs; call dsytrs(); end', dependencies: (get_option('openmp') ? [custom_deps, omp_dep] : [custom_deps]))) 134 | error('Custom LAPACK libraries do not link') 135 | elif (not fc.links('external dsytrs; call dgemm(); end', dependencies: (get_option('openmp') ? [custom_deps, omp_dep] : [custom_deps]))) 136 | error('Custom BLAS libraries do not link') 137 | endif 138 | lib_deps += custom_deps 139 | 140 | else 141 | lapack_dep = dependency(ilp64 ? 'lapack64' : 'lapack', required: false) 142 | if not lapack_dep.found() 143 | lapack_dep = cc.find_library(ilp64 ? 'lapack64' : 'lapack') 144 | endif 145 | lib_deps += lapack_dep 146 | blas_dep = cc.find_library(ilp64 ? 'blas64' : 'blas', required: false) 147 | if not blas_dep.found() 148 | blas_dep = cc.find_library(ilp64 ? 'blas64' : 'blas') 149 | endif 150 | lib_deps += blas_dep 151 | endif 152 | 153 | # Create the tool chain library as subproject 154 | mctc_dep = dependency( 155 | 'mctc-lib', 156 | version: '>=0.4.1', 157 | fallback: ['mctc-lib', 'mctc_dep'], 158 | default_options: ['default_library=static'], 159 | ) 160 | lib_deps += mctc_dep 161 | 162 | # Create the electrostatic library as subproject 163 | multicharge_dep = dependency( 164 | 'multicharge', 165 | version: '>=0.4.0', 166 | fallback: ['multicharge', 'multicharge_dep'], 167 | default_options: ['default_library=static'], 168 | ) 169 | lib_deps += multicharge_dep 170 | -------------------------------------------------------------------------------- /config/template.cmake: -------------------------------------------------------------------------------- 1 | @PACKAGE_INIT@ 2 | 3 | set("@PROJECT_NAME@_WITH_API" @WITH_API@) 4 | set("@PROJECT_NAME@_WITH_API_V2" @WITH_API_V2@) 5 | set("@PROJECT_NAME@_WITH_OpenMP" @WITH_OpenMP@) 6 | set( 7 | "@PROJECT_NAME@_INCLUDE_DIRS" 8 | "@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_INCLUDEDIR@" 9 | "@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_INCLUDEDIR@/@module-dir@" 10 | ) 11 | list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}") 12 | 13 | if(NOT TARGET "@PROJECT_NAME@::@PROJECT_NAME@") 14 | include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@-targets.cmake") 15 | 16 | include(CMakeFindDependencyMacro) 17 | 18 | if(NOT TARGET "OpenMP::OpenMP_Fortran" AND "@PROJECT_NAME@_WITH_OpenMP") 19 | find_dependency("OpenMP") 20 | endif() 21 | 22 | if(NOT TARGET "BLAS::BLAS") 23 | find_dependency("BLAS") 24 | endif() 25 | 26 | if(NOT TARGET "mctc-lib::mctc-lib") 27 | find_dependency("mctc-lib") 28 | endif() 29 | 30 | if(NOT TARGET "multicharge::multicharge") 31 | find_dependency("multicharge") 32 | endif() 33 | endif() 34 | -------------------------------------------------------------------------------- /config/template.pc: -------------------------------------------------------------------------------- 1 | prefix=@CMAKE_INSTALL_PREFIX@ 2 | libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@ 3 | includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@ 4 | 5 | Name: @PROJECT_NAME@ 6 | Description: @PROJECT_DESCRIPTION@ 7 | Version: @PROJECT_VERSION@ 8 | Libs: -L${libdir} -l@PROJECT_NAME@ 9 | Cflags: -I${includedir} -I${includedir}/@module-dir@ 10 | -------------------------------------------------------------------------------- /doc/_static/references.bib: -------------------------------------------------------------------------------- 1 | @article{caldeweyher2020, 2 | title={Extension and evaluation of the {D4} {L}ondon-dispersion model for periodic systems}, 3 | author={Caldeweyher, Eike and Mewes, Jan-Michael and Ehlert, Sebastian and Grimme, Stefan}, 4 | journal={Phys{.} Chem{.} Chem{.} Phys{.}}, 5 | volume={22}, 6 | number={16}, 7 | pages={8499--8512}, 8 | year={2020}, 9 | doi={10.1039/D0CP00502A}, 10 | publisher={Royal Society of Chemistry} 11 | } 12 | 13 | @article{caldeweyher2019, 14 | title={A generally applicable atomic-charge dependent {L}ondon dispersion correction}, 15 | author={Caldeweyher, Eike and Ehlert, Sebastian and Hansen, Andreas and Neugebauer, Hagen and Spicher, Sebastian and Bannwarth, Christoph and Grimme, Stefan}, 16 | journal={J{.} Chem{.} Phys{.}}, 17 | volume={150}, 18 | number={15}, 19 | pages={154122}, 20 | year={2019}, 21 | doi={10.1063/1.5090222}, 22 | publisher={AIP Publishing LLC} 23 | } 24 | 25 | @article{caldeweyher2017, 26 | title={Extension of the {D3} dispersion coefficient model}, 27 | author={Caldeweyher, Eike and Bannwarth, Christoph and Grimme, Stefan}, 28 | journal={J{.} Chem{.} Phys{.}}, 29 | volume={147}, 30 | number={3}, 31 | pages={034112}, 32 | year={2017}, 33 | doi={10.1063/1.4993215}, 34 | publisher={AIP Publishing LLC} 35 | } 36 | 37 | @article{tkachenko2024, 38 | title={Smooth Dispersion Is Physically Appropriate: Assessing and Amending the D4 Dispersion Model}, 39 | author={Tkachenko, Nikolay V. and Dittmer, Linus Bjarne and Tomann, Rebecca and Head-Gordon, Martin}, 40 | journal={J{.} Phys{.} Chem{.} Lett{.}}, 41 | volume={15}, 42 | number={42}, 43 | pages={10629-10637}, 44 | year={2024}, 45 | doi={10.1021/acs.jpclett.4c02653}, 46 | publisher={ACS Publications} 47 | } 48 | -------------------------------------------------------------------------------- /doc/conf.py: -------------------------------------------------------------------------------- 1 | 2 | import sys, os.path as op 3 | 4 | sys.path.insert(0, op.join(op.dirname(__file__), "..", "python")) 5 | 6 | import dftd4 7 | 8 | 9 | project = "DFT-D4" 10 | author = "Grimme group" 11 | copyright = f"2017–2024 {author}" 12 | 13 | extensions = [ 14 | "sphinx_copybutton", 15 | "sphinx_design", 16 | "sphinx.ext.autosummary", 17 | "sphinx.ext.autodoc", 18 | "sphinx.ext.intersphinx", 19 | "sphinx.ext.viewcode", 20 | "sphinx.ext.napoleon", 21 | ] 22 | 23 | html_theme = "sphinx_book_theme" 24 | html_title = project 25 | html_logo = "_static/dftd4.svg" 26 | html_favicon = html_logo 27 | 28 | html_theme_options = { 29 | "repository_url": "https://github.com/dftd4/dftd4", 30 | "repository_branch": "main", 31 | "use_repository_button": True, 32 | "use_edit_page_button": True, 33 | "use_download_button": False, 34 | "path_to_docs": "doc", 35 | "show_navbar_depth": 3, 36 | "logo_only": False, 37 | } 38 | 39 | html_sidebars = {} 40 | 41 | html_css_files = [ 42 | "css/custom.css", 43 | ] 44 | html_static_path = ["_static"] 45 | templates_path = ["_templates"] 46 | 47 | autodoc_typehints = "none" 48 | autodoc_mock_imports = ["dftd4.library", "numpy", "ase", "qcelemental", "pyscf"] 49 | autosummary_generate = True 50 | napoleon_google_docstring = False 51 | napoleon_use_param = False 52 | napoleon_use_ivar = True 53 | 54 | master_doc = "index" 55 | -------------------------------------------------------------------------------- /doc/index.rst: -------------------------------------------------------------------------------- 1 | DFT-D4 dispersion correction 2 | ============================ 3 | 4 | .. image:: https://img.shields.io/github/license/dftd4/dftd4 5 | :target: https://github.com/dftd4/dftd4/blob/master/COPYING.LESSER 6 | :alt: License 7 | 8 | .. image:: https://img.shields.io/github/v/release/dftd4/dftd4 9 | :target: https://github.com/dftd4/dftd4/releases/latest 10 | :alt: Version 11 | 12 | .. image:: https://github.com/dftd4/dftd4/workflows/CI/badge.svg 13 | :target: https://github.com/dftd4/dftd4/actions 14 | :alt: CI 15 | 16 | .. image:: https://readthedocs.org/projects/dftd4/badge/?version=latest 17 | :target: https://dftd4.readthedocs.io/en/latest/?badge=latest 18 | :alt: Documentation 19 | 20 | .. image:: https://github.com/dftd4/dftd4/workflows/docs/badge.svg 21 | :target: https://dftd4.github.io/dftd4/ 22 | :alt: API docs 23 | 24 | .. image:: https://codecov.io/gh/dftd4/dftd4/branch/main/graph/badge.svg?token=IFtEF1Hwqj 25 | :target: https://codecov.io/gh/dftd4/dftd4 26 | :alt: Coverage 27 | 28 | This pages describe the usage and functionality of `dftd4`_ library. 29 | The *dftd4* project provides an implementation of the generally applicable, charge dependent London-dispersion correction, termed DFT-D4. 30 | 31 | .. _dftd4: https://github.com/dftd4/dftd4 32 | 33 | References 34 | ---------- 35 | 36 | - Eike Caldeweyher, Christoph Bannwarth and Stefan Grimme, 37 | *J. Chem. Phys.*, **2017**, 147, 034112. 38 | DOI: `10.1063/1.4993215 `__ 39 | 40 | - Eike Caldeweyher, Sebastian Ehlert, Andreas Hansen, Hagen Neugebauer, Sebastian Spicher, Christoph Bannwarth and Stefan Grimme, 41 | *J. Chem. Phys.*, **2019**, 150, 154122. 42 | DOI: `10.1063/1.5090222 `__ 43 | chemrxiv: `10.26434/chemrxiv.7430216 `__ 44 | 45 | - Eike Caldeweyher, Jan-Michael Mewes, Sebastian Ehlert and Stefan Grimme, 46 | *Phys. Chem. Chem. Phys.*, **2020**, 22, 8499-8512. 47 | DOI: `10.1039/D0CP00502A `__ 48 | chemrxiv: `10.26434/chemrxiv.10299428 `__ 49 | 50 | - Marvin Friede, Sebastian Ehlert, Stefan Grimme and Jan-Michael Mewes, 51 | *J. Chem. Theory Comput.*, **2023**, 19 (22), 8097-8107. 52 | DOI: `10.1021/acs.jctc.3c00717 <10.1021/acs.jctc.3c00717>`__ 53 | 54 | - Lukas Wittmann, Igor Gordiy, Marvin Friede, Benjamin Helmich-Paris, Stefan Grimme, Andreas Hansen and Markus Bursch, 55 | *Phys. Chem. Chem. Phys.*, **2024**, 26, 21379-21394. 56 | DOI: `10.1039/D4CP01514B <10.1039/D4CP01514B>`__ 57 | 58 | - Nikolay V. Tkachenko, Linus B. Dittmer, Rebecca Tomann and Martin Head-Gordon, 59 | *J. Phys. Chem. Lett.*, **2024**, 15, 42, 10629–10637. 60 | DOI: `10.1021/acs.jpclett.4c02653 `__ 61 | chemrxiv: `10.26434/chemrxiv-2024-31x2z `__ 62 | 63 | 64 | Citations can also be viewed via `dftd4 --citation` or in the `BibTeX file `__. 65 | 66 | 67 | .. toctree:: 68 | 69 | Recipes 70 | References 71 | -------------------------------------------------------------------------------- /doc/recipe/index.rst: -------------------------------------------------------------------------------- 1 | Recipes 2 | ======= 3 | 4 | This section deals with solving specific task with DFT-D4 by providing step by step recipes. 5 | 6 | 7 | .. toctree:: 8 | 9 | installation 10 | vasp 11 | -------------------------------------------------------------------------------- /doc/recipe/installation.rst: -------------------------------------------------------------------------------- 1 | .. _installation: 2 | 3 | Installing DFT-D4 4 | ================= 5 | 6 | This guide will walk you through installing the latest version of DFT-D4. 7 | 8 | 9 | :fab:`apple` :fab:`linux` :fab:`windows` Installing from conda-forge 10 | -------------------------------------------------------------------- 11 | 12 | .. image:: https://img.shields.io/conda/vn/conda-forge/dftd4 13 | :alt: Conda 14 | :target: https://github.com/conda-forge/dftd4-feedstock 15 | 16 | .. image:: https://img.shields.io/conda/pn/conda-forge/dftd4 17 | :alt: Conda 18 | :target: https://github.com/conda-forge/dftd4-feedstock 19 | 20 | 21 | This project is packaged for the *conda* package manager and available on the *conda-forge* channel. 22 | To install the *conda* package manager we recommend the `miniforge `_ installer. 23 | If the *conda-forge* channel is not yet enabled, add it to your channels with 24 | 25 | .. code-block:: bash 26 | 27 | conda config --add channels conda-forge 28 | conda config --set channel_priority strict 29 | 30 | Once the *conda-forge* channel has been enabled, DFT-D4 can be installed with *conda*: 31 | 32 | .. code-block:: shell 33 | 34 | conda install dftd4 35 | 36 | or with *mamba*: 37 | 38 | .. code-block:: shell 39 | 40 | mamba install dftd4 41 | 42 | It is possible to list all of the versions of DFT-D4 available on your platform with *conda*: 43 | 44 | .. code-block:: shell 45 | 46 | conda search dftd4 --channel conda-forge 47 | 48 | or with *mamba*: 49 | 50 | .. code-block:: shell 51 | 52 | mamba search dftd4 --channel conda-forge 53 | 54 | Alternatively, *mamba repoquery* may provide more information: 55 | 56 | .. code-block:: shell 57 | 58 | # Search all versions available on your platform: 59 | mamba repoquery search dftd4 --channel conda-forge 60 | 61 | # List packages depending on `dftd4`: 62 | mamba repoquery whoneeds dftd4 --channel conda-forge 63 | 64 | # List dependencies of `dftd4`: 65 | mamba repoquery depends dftd4 --channel conda-forge 66 | 67 | 68 | :fab:`freebsd` FreeBSD ports 69 | ---------------------------- 70 | 71 | .. image:: https://repology.org/badge/version-for-repo/freebsd/dftd4.svg 72 | :alt: FreeBSD 73 | :target: https://www.freshports.org/science/dftd4/ 74 | 75 | A port for FreeBSD is available 76 | 77 | .. code-block:: bash 78 | 79 | pkg install science/dftd4 80 | 81 | In case no package is available build the port using 82 | 83 | .. code-block:: bash 84 | 85 | cd /usr/ports/science/dftd4 86 | make install clean 87 | 88 | For more information see the `dftd4 port details `_. 89 | 90 | 91 | Building from source 92 | -------------------- 93 | 94 | To build this project from the source code in this repository you need to have 95 | 96 | - a Fortran compiler supporting Fortran 2008 97 | - One of the supported build systems 98 | 99 | - `meson `_ version 0.55 or newer 100 | - `CMake `_ version 3.9 or newer 101 | 102 | First, get the source by cloning the repository 103 | 104 | .. code-block:: bash 105 | 106 | git clone https://github.com/dftd4/dftd4 107 | cd dftd4 108 | 109 | 110 | Using Meson 111 | ^^^^^^^^^^^ 112 | 113 | To build this project with meson a build-system backend is required, *i.e.* `ninja `_ version 1.7 or newer. 114 | Setup a build with 115 | 116 | .. code-block:: bash 117 | 118 | meson setup _build --prefix=/path/to/installation 119 | 120 | You can select the Fortran compiler by the ``FC`` environment variable. 121 | To compile the project run 122 | 123 | .. code-block:: bash 124 | 125 | meson compile -C _build 126 | 127 | DFT-D4 comes with a comprehensive test suite. 128 | Run the tests with 129 | 130 | .. code-block:: bash 131 | 132 | meson test -C _build --print-errorlogs 133 | 134 | Finally, you can install DFT-D4 with 135 | 136 | .. code-block:: bash 137 | 138 | meson install -C _build 139 | 140 | 141 | Using CMake 142 | ^^^^^^^^^^^ 143 | 144 | While meson is the preferred way to build this project it also offers CMake support. 145 | Configure the CMake build with 146 | 147 | .. code-block:: bash 148 | 149 | cmake -B_build -GNinja -DCMAKE_INSTALL_PREFIX=/path/to/installation 150 | 151 | Similar to meson the compiler can be selected with the ``FC`` environment variable. 152 | You can build the project using 153 | 154 | .. code-block:: bash 155 | 156 | cmake --build _build 157 | 158 | DFT-D4 comes with a comprehensive test suite. 159 | Run the tests with 160 | 161 | .. code-block:: bash 162 | 163 | ctest --test-dir _build --output-on-failure 164 | 165 | Finally, you can install DFT-D4 with 166 | 167 | .. code-block:: bash 168 | 169 | cmake --install _build 170 | -------------------------------------------------------------------------------- /doc/recipe/vasp.rst: -------------------------------------------------------------------------------- 1 | Using DFT-D4 in Vasp 2 | ==================== 3 | 4 | To use the D4 dispersion correction in Vasp you need to a compile the ``dftd4`` package using the same Fortran compiler as used for Vasp and enable the API compatibility needed for linking the Vasp-side interface for ``dftd4``. 5 | Checkout the instructions for installing ``dftd4`` at :ref:`installation`. 6 | To use ``dftd4`` in Vasp the compatibility layer for the 2.5.x API has to be enable with ``-Dapi_v2=true`` (meson) or ``-DWITH_API_V2=ON`` (CMake). 7 | 8 | .. important:: 9 | 10 | It is important to build ``dftd4`` with the same Fortran compiler you build Vasp with. 11 | 12 | After you completed the installation of ``dftd4``, make sure it is findable by ``pkg-config``, you can check by running: 13 | 14 | .. code-block:: text 15 | 16 | pkg-config --modversion dftd4 17 | 18 | 19 | If your ``dftd4`` installation is not findable, you have to update your environment variables. 20 | One option is to provide a module file for your ``dftd4`` installation. 21 | The example module file below can be placed in your ``MODULEPATH`` to provide access to an installation in ``~/opt/dftd4/3.7.0``. 22 | Retry the above comment after loading the ``dftd4`` module and adjust the module file until ``pkg-config`` finds your installation. 23 | 24 | .. code-block:: lua 25 | 26 | -- dftd4/3.7.0.lua 27 | local name = "dftd4" 28 | local version = "3.7.0" 29 | local prefix = pathJoin(os.getenv("HOME"), "opt", name, version) 30 | local libdir = "lib" -- or lib64 31 | 32 | whatis("Name : " .. name) 33 | whatis("Version : " .. version) 34 | whatis("Description : Generally applicable charge dependent London dispersion correction") 35 | whatis("URL : https://github.com/dftd4/dftd4") 36 | 37 | prepend_path("PATH", pathJoin(prefix, "bin")) 38 | prepend_path("MANPATH", pathJoin(prefix, "share", "man")) 39 | prepend_path("CPATH", pathJoin(prefix, "include")) 40 | prepend_path("LIBRARY_PATH", pathJoin(prefix, libdir)) 41 | prepend_path("LD_LIBRARY_PATH", pathJoin(prefix, libdir)) 42 | prepend_path("PKG_CONFIG_PATH", pathJoin(prefix, libdir, "pkgconfig")) 43 | 44 | 45 | To enable support for D4 in Vasp add the following lines to the Makefile: 46 | 47 | .. code-block:: make 48 | 49 | CPP_OPTIONS += -DDFTD4 50 | LLIBS += $(shell pkg-config --libs dftd4) 51 | INCS += $(shell pkg-config --cflags dftd4) 52 | 53 | Depending on how you built DFT-D4, DFT-D4's dependencies not might be properly recognized during the VASP build. Try to explicitly add them to the link line. 54 | 55 | .. code-block:: make 56 | 57 | CPP_OPTIONS += -DDFTD4 58 | LLIBS += $(shell pkg-config --libs dftd4) -lmulticharge -lmctc-lib -lmstore 59 | INCS += $(shell pkg-config --cflags dftd4) 60 | ``` 61 | 62 | If you still run into issues, check out `VASP-related issues `_ on the ``dftd4`` issue tracker. 63 | -------------------------------------------------------------------------------- /doc/reference/ase.rst: -------------------------------------------------------------------------------- 1 | .. automodule:: dftd4.ase 2 | :members: 3 | -------------------------------------------------------------------------------- /doc/reference/fortran.rst: -------------------------------------------------------------------------------- 1 | Fortran API 2 | =========== 3 | 4 | The *dftd4* library seamlessly integrates with other Fortran projects via module interfaces, 5 | 6 | .. note:: 7 | 8 | Generally, all quantities used in the library are stored in `atomic units `_. 9 | 10 | .. toctree:: 11 | :hidden: 12 | 13 | Full Reference 14 | 15 | 16 | Handling of geometries and structure 17 | ------------------------------------ 18 | 19 | The basic infrastructure to handle molecular and periodic structures is provided by the `modular computation tool chain library `_. 20 | The library provides a structure type which is used to represent all geometry related informations in *dftd4*. 21 | A structure type can be constructed from arrays or read from a file. 22 | 23 | The constructor is provided with the generic interface ``new`` and takes an array of atomic numbers (``integer``) or element symbols (``character(len=*)``) as well as the cartesian coordinates in Bohr. 24 | Additionally, the molecular charge and the number of unpaired electrons can be provided the ``charge`` and ``uhf`` keyword, respectively. 25 | To create a periodic structure the lattice parameters can be passed as 3 by 3 matrix with the ``lattice`` keyword. 26 | 27 | An example for using the constructor is given here 28 | 29 | .. code-block:: fortran 30 | 31 | subroutine example 32 | use mctc_env, only : wp 33 | use mctc_io, only : structure_type, new 34 | implicit none 35 | type(structure_type) :: mol 36 | real(wp), allocatable :: xyz(:, :) 37 | integer, allocatable :: num(:) 38 | 39 | num = [6, 1, 1, 1, 1] 40 | xyz = reshape([ & 41 | & 0.00000000000000_wp, -0.00000000000000_wp, 0.00000000000000_wp, & 42 | & -1.19220800552211_wp, 1.19220800552211_wp, 1.19220800552211_wp, & 43 | & 1.19220800552211_wp, -1.19220800552211_wp, 1.19220800552211_wp, & 44 | & -1.19220800552211_wp, -1.19220800552211_wp, -1.19220800552211_wp, & 45 | & 1.19220800552211_wp, 1.19220800552211_wp, -1.19220800552211_wp],& 46 | & [3, size(num)]) 47 | 48 | call new(mol, num, xyz, charge=0.0_wp, uhf=0) 49 | 50 | ! ... 51 | end subroutine example 52 | 53 | 54 | To interact with common input file formats for structures the ``read_structure`` procedure is available. 55 | The file type is inferred from the name of the file automatically or if a file type hint is provided directly from the enumerator of available file types. 56 | The ``read_structure`` routine can also use an already opened unit, but in this case the file type hint is mandatory to select the correct format to read from. 57 | 58 | .. code-block:: fortran 59 | 60 | subroutine example 61 | use mctc_env, only : error_type 62 | use mctc_io, only : structure_type, read_structure, file_type 63 | implicit none 64 | type(structure_type) :: mol 65 | type(error_type), allocatable :: error 66 | character(len=:), allocatable :: input 67 | 68 | input = "struc.xyz" 69 | 70 | call read_structure(mol, input, error, file_type%xyz) 71 | if (allocated(error)) then 72 | print '(a)', error%message 73 | stop 1 74 | end if 75 | 76 | ! ... 77 | end subroutine example 78 | 79 | 80 | The structure type as well as the error type contain only allocatable members and can therefore be used without requiring explicit deconstruction. 81 | 82 | Certain members of the structure type should be considered immutable, like the number of atoms (``nat``), the identifiers for unique atoms (``id``) and the boundary conditions (``periodic``). 83 | To change those specific structure parameters the structure type and all dependent objects should be reconstructed to ensure a consistent setup. 84 | Other properties, like the geometry (``xyz``), molecular charge (``charge``), number of unpaired electrons (``uhf``) and lattice parameters (``lattice``) can be changed without requiring to reconstruct dependent objects like calculators or restart data. 85 | 86 | 87 | Error handling 88 | -------------- 89 | 90 | The basic error handler is an allocatable derived type, available from ``mctc_env`` as ``error_type``, which signals an error by its allocation status. 91 | 92 | .. code-block:: fortran 93 | 94 | use mctc_env, only : error_type, fatal_error 95 | implicit none 96 | type(error_type), allocatable :: error 97 | 98 | call always_ok(error) 99 | if (allocated(error)) then 100 | print '(a)', "Unexpected failure:", error%message 101 | end if 102 | 103 | call always_failed(error) 104 | if (allocated(error)) then 105 | print '(a)', "Error:", error%message 106 | end if 107 | 108 | contains 109 | subroutine always_ok(error) 110 | type(error_type), allocatable, intent(out) :: error 111 | end subroutine always_ok 112 | 113 | subroutine always_failed(error) 114 | type(error_type), allocatable, intent(out) :: error 115 | 116 | call fatal_error(error, "Message associated with this error") 117 | end subroutine always_failed 118 | end 119 | 120 | An unhandled error might get dropped by the next procedure call. 121 | -------------------------------------------------------------------------------- /doc/reference/index.rst: -------------------------------------------------------------------------------- 1 | .. _api: 2 | 3 | API documentation 4 | ================= 5 | 6 | DFT-D4 aims to provide first class API support Fortran, C and Python. 7 | Other programming languages should try to interface via one of those three APIs. 8 | To provide first class API support for a new language the interface specification should be available from the meson build files. 9 | 10 | .. toctree:: 11 | 12 | fortran 13 | c 14 | python 15 | -------------------------------------------------------------------------------- /doc/reference/pyscf.rst: -------------------------------------------------------------------------------- 1 | .. automodule:: dftd4.pyscf 2 | :members: 3 | -------------------------------------------------------------------------------- /doc/reference/python.rst: -------------------------------------------------------------------------------- 1 | .. _python: 2 | 3 | Python API 4 | ========== 5 | 6 | .. automodule:: dftd4 7 | 8 | 9 | .. toctree:: 10 | 11 | ase 12 | qcschema 13 | pyscf 14 | 15 | 16 | Library interface 17 | ----------------- 18 | 19 | .. automodule:: dftd4.interface 20 | 21 | 22 | Structure 23 | ~~~~~~~~~ 24 | 25 | .. autoclass:: Structure 26 | :members: 27 | 28 | 29 | DispersionModel 30 | ~~~~~~~~~~~~~~~ 31 | 32 | .. autoclass:: DispersionModel 33 | :members: 34 | 35 | 36 | DampingParam 37 | ~~~~~~~~~~~~ 38 | 39 | .. autoclass:: DampingParam 40 | :members: 41 | -------------------------------------------------------------------------------- /doc/reference/qcschema.rst: -------------------------------------------------------------------------------- 1 | .. automodule:: dftd4.qcschema 2 | :members: 3 | -------------------------------------------------------------------------------- /doc/requirements.txt: -------------------------------------------------------------------------------- 1 | cffi 2 | numpy 3 | sphinx_book_theme 4 | sphinx_copybutton 5 | sphinx_design 6 | -------------------------------------------------------------------------------- /ford.md: -------------------------------------------------------------------------------- 1 | --- 2 | project: DFT-D4 3 | symmary: Generally Applicable Atomic-Charge Dependent London Dispersion Correction 4 | author: Grimme group Bonn 5 | src_dir: ./src 6 | include: ./include 7 | output_dir: ./_docs 8 | exclude_dir: ./test 9 | project_github: https://github.com/dftd4/dftd4 10 | github: https://github.com/dftd4 11 | website: https://mctc.uni-bonn.de/software/dftd4 12 | docmark: < 13 | predocmark: > 14 | display: public 15 | protected 16 | private 17 | source: true 18 | graph: true 19 | sort: alpha 20 | print_creation_date: true 21 | creation_date: %Y-%m-%d %H:%M %z 22 | extra_mods: iso_fortran_env:https://gcc.gnu.org/onlinedocs/gfortran/ISO_005fFORTRAN_005fENV.html 23 | multicharge:https://github.com/grimme-lab/multicharge 24 | mctc_io:https://grimme-lab.github.io/mctc-lib/module/mctc_io.html 25 | mctc_env:https://grimme-lab.github.io/mctc-lib/module/mctc_env.html 26 | md_extensions: markdown.extensions.toc 27 | markdown.extensions.smarty 28 | --- 29 | 30 | {!README.md!} 31 | -------------------------------------------------------------------------------- /fpm.toml: -------------------------------------------------------------------------------- 1 | name = "dftd4" 2 | version = "3.7.0" 3 | license = "LGPL-3.0-or-later" 4 | maintainer = ["@awvwgk"] 5 | author = ["Eike Caldeweyher", "Sebastian Ehlert", "Stefan Grimme"] 6 | description = "Generally Applicable Atomic-Charge Dependent London Dispersion Correction" 7 | keywords = ["quantum-chemistry", "dispersion-correction"] 8 | copyright = "Copyright 2017-2021 E. Caldeweyher, S. Ehlert, S. Grimme" 9 | 10 | [build] 11 | link = ["lapack", "blas"] 12 | auto-tests = false 13 | 14 | [dependencies] 15 | mctc-lib.git = "https://github.com/grimme-lab/mctc-lib.git" 16 | mctc-lib.tag = "v0.4.1" 17 | multicharge.git = "https://github.com/grimme-lab/multicharge.git" 18 | multicharge.tag = "v0.4.0" 19 | 20 | [dev-dependencies] 21 | mstore.git = "https://github.com/grimme-lab/mstore.git" 22 | mstore.tag = "v0.3.0" 23 | 24 | [[test]] 25 | name = "tester" 26 | source-dir = "test/unit" 27 | -------------------------------------------------------------------------------- /man/dftd4.1.adoc: -------------------------------------------------------------------------------- 1 | = dftd4(1) 2 | :doctype: manpage 3 | 4 | == Name 5 | dftd4 - Generally Applicable Atomic-Charge Dependent London Dispersion Correction. 6 | 7 | == Synopsis 8 | *dftd4* [run|param] [_options_] _input_ 9 | 10 | 11 | == Description 12 | 13 | Takes an geometry input to calculate the D4(S) dispersion correction. 14 | Periodic calculations are performed automatically for periodic input formats. 15 | Reads .CHRG file (if present) from the same directory as the input. 16 | Specify the functional to select the correct parameters. 17 | 18 | 19 | == Commands 20 | 21 | *run*:: 22 | Evaluate dispersion correction on the provided input structure. 23 | Periodic calculations are performed automatically for periodic inputs 24 | If no command is specified run is selected by default. 25 | 26 | *param*:: 27 | Inspect damping parameters. 28 | 29 | 30 | == Options: run 31 | 32 | *-c, --charge* _integer_:: 33 | Set charge to molecule, 34 | overrides charge in .CHRG file 35 | 36 | *-f, --func* _functional_:: 37 | Dispersion correction for specified density functional method 38 | 39 | *--param* _s6_ _s8_ _a1_ _a2_:: 40 | use this damping parameters for energy calculation 41 | 42 | *--mbdscale* _s9_:: 43 | scale the many-body dispersion energy (default=1.0) 44 | 45 | *--zeta* _real_ _real_:: 46 | Adjust charge scaling height and charge scaling steepness 47 | (default: 3.0 and 2.0) 48 | 49 | *--wfactor* _real_:: 50 | Adjust weighting factor for the Gaussian interpolation (only D4) 51 | (default: 6.0) 52 | 53 | *-m, --model* _string_:: 54 | use either standard D4 (default) or the smoothed D4S model 55 | 56 | *-g, --grad* [_file_]:: 57 | prints analytical gradient to file, 58 | write results to file (default: dftd4.txt), 59 | attempts to add to Turbomole gradient and gradlatt files 60 | 61 | *--json* [_file_]:: 62 | Serialize all results as JSON (dftd4.json) 63 | 64 | *--noedisp*:: 65 | Do not write dispersion energy in `.EDISP` file 66 | 67 | *--property*:: 68 | Print atomic properties and molecular C6-coefficient 69 | 70 | *--pair-resolved*:: 71 | Calculate pairwise representation of dispersion energy 72 | 73 | *--version*:: 74 | Prints version number and citation 75 | 76 | *--citation*:: 77 | Prints references for DFT-D4 method 78 | 79 | *--license*:: 80 | Prints licensing information 81 | 82 | *-v, --verbose*:: 83 | Show more, can be used multiple times 84 | 85 | *-s, --silent*:: 86 | Show less, use twice to supress all output 87 | 88 | *-h, --help*:: 89 | Show this message 90 | 91 | 92 | == Options: param 93 | 94 | *--list, --funcs, -l*:: 95 | List all available functionals (keywords for *-f, --func*) 96 | -------------------------------------------------------------------------------- /meson.build: -------------------------------------------------------------------------------- 1 | # This file is part of dftd4. 2 | # SPDX-Identifier: LGPL-3.0-or-later 3 | # 4 | # dftd4 is free software: you can redistribute it and/or modify it under 5 | # the terms of the Lesser GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # dftd4 is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # Lesser GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the Lesser GNU General Public License 15 | # along with dftd4. If not, see . 16 | 17 | project( 18 | 'dftd4', 19 | 'fortran', 20 | version: '3.7.0', 21 | license: 'LGPL-3.0-or-later', 22 | meson_version: '>=0.55,!=1.8.0', 23 | default_options: [ 24 | 'buildtype=debugoptimized', 25 | 'default_library=both', 26 | 'c_std=c11', 27 | ], 28 | ) 29 | install = not (meson.is_subproject() and get_option('default_library') == 'static') 30 | has_cc = add_languages('c', required: get_option('api') or get_option('python'), native: false) 31 | 32 | # General configuration information 33 | inc_dirs = [] 34 | lib_deps = [] 35 | subdir('config') 36 | 37 | # Collect source of the project 38 | srcs = [] 39 | subdir('src') 40 | 41 | # Library target 42 | dftd4_lib = library( 43 | meson.project_name(), 44 | sources: srcs, 45 | version: meson.project_version(), 46 | dependencies: lib_deps, 47 | include_directories: inc_dirs, 48 | install: install, 49 | ) 50 | 51 | # Export dependency for other projects and test suite 52 | dftd4_inc = [dftd4_lib.private_dir_include(), include_directories('include')] 53 | dftd4_dep = declare_dependency( 54 | link_with: dftd4_lib, 55 | include_directories: dftd4_inc, 56 | dependencies: lib_deps, 57 | variables: {'includedir': meson.current_source_dir() / 'include'}, 58 | ) 59 | 60 | # Add applications 61 | subdir('app') 62 | 63 | # Package the license files 64 | dftd4_lic = files( 65 | 'COPYING', 66 | 'COPYING.LESSER', 67 | ) 68 | 69 | dftd4_header = files( 70 | 'include/dftd4.h', 71 | ) 72 | 73 | if install 74 | # Distribute the license files in share/licenses/ 75 | install_data( 76 | dftd4_lic, 77 | install_dir: get_option('datadir')/'licenses'/meson.project_name() 78 | ) 79 | 80 | if get_option('api') 81 | install_headers( 82 | dftd4_header, 83 | ) 84 | endif 85 | 86 | module_id = meson.project_name() / fc_id + '-' + fc.version() 87 | meson.add_install_script( 88 | find_program(files('config'/'install-mod.py')), 89 | get_option('includedir') / module_id, 90 | ) 91 | 92 | pkg = import('pkgconfig') 93 | pkg.generate( 94 | dftd4_lib, 95 | name: 'dftd4', 96 | description: 'Generally Applicable Atomic-Charge Dependent London Dispersion Correction', 97 | version: meson.project_version(), 98 | subdirs: ['', module_id], 99 | ) 100 | 101 | asciidoc = find_program('asciidoctor', required: false) 102 | if asciidoc.found() 103 | install_man( 104 | configure_file( 105 | command: [asciidoc, '-b', 'manpage', '@INPUT@', '-o', '@OUTPUT@'], 106 | input: files('man/dftd4.1.adoc'), 107 | output: '@BASENAME@', 108 | ) 109 | ) 110 | endif 111 | 112 | install_data( 113 | files('assets'/'parameters.toml'), 114 | install_dir: get_option('datadir')/meson.project_name(), 115 | ) 116 | endif 117 | 118 | # add the testsuite 119 | subdir('test') 120 | 121 | if get_option('python') 122 | subdir('python'/'dftd4') 123 | endif 124 | -------------------------------------------------------------------------------- /meson_options.txt: -------------------------------------------------------------------------------- 1 | # This file is part of dftd4. 2 | # SPDX-Identifier: LGPL-3.0-or-later 3 | # 4 | # dftd4 is free software: you can redistribute it and/or modify it under 5 | # the terms of the Lesser GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # dftd4 is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # Lesser GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the Lesser GNU General Public License 15 | # along with dftd4. If not, see . 16 | 17 | option( 18 | 'lapack', 19 | type: 'combo', 20 | value: 'auto', 21 | yield: true, 22 | choices: ['auto', 'mkl', 'mkl-rt', 'openblas', 'netlib', 'custom'], 23 | description : 'linear algebra backend', 24 | ) 25 | 26 | option( 27 | 'custom_libraries', 28 | type: 'array', 29 | value: [], 30 | yield: true, 31 | description: 'libraries to load for custom linear algebra backend', 32 | ) 33 | 34 | option( 35 | 'openmp', 36 | type: 'boolean', 37 | value: true, 38 | yield: true, 39 | description: 'use OpenMP parallelisation', 40 | ) 41 | 42 | option( 43 | 'api', 44 | type: 'boolean', 45 | value: true, 46 | description: 'Build C API using iso_c_binding module', 47 | ) 48 | 49 | option( 50 | 'python', 51 | type: 'boolean', 52 | value: false, 53 | description: 'Build Python extension module', 54 | ) 55 | 56 | option( 57 | 'python_version', 58 | type: 'string', 59 | value: 'python3', 60 | description: 'Python version to link against.', 61 | ) 62 | 63 | option( 64 | 'api_v2', 65 | type: 'boolean', 66 | value: false, 67 | description: 'Enable the compatibility layer for the dftd4 2.5.x API', 68 | ) 69 | 70 | option( 71 | 'ilp64', 72 | type: 'boolean', 73 | value: false, 74 | yield: true, 75 | description: 'Enable BLAS/LAPACK ilp64 support', 76 | ) 77 | -------------------------------------------------------------------------------- /python/.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | 34 | # Byte-compiled / optimized / DLL files 35 | __pycache__/ 36 | *.py[cod] 37 | *$py.class 38 | 39 | # Distribution / packaging 40 | .Python 41 | build/ 42 | develop-eggs/ 43 | dist/ 44 | downloads/ 45 | eggs/ 46 | .eggs/ 47 | lib/ 48 | lib64/ 49 | parts/ 50 | sdist/ 51 | var/ 52 | wheels/ 53 | share/python-wheels/ 54 | *.egg-info/ 55 | .installed.cfg 56 | *.egg 57 | MANIFEST 58 | 59 | # PyInstaller 60 | # Usually these files are written by a python script from a template 61 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 62 | *.manifest 63 | *.spec 64 | 65 | # Installer logs 66 | pip-log.txt 67 | pip-delete-this-directory.txt 68 | 69 | # Unit test / coverage reports 70 | htmlcov/ 71 | .tox/ 72 | .nox/ 73 | .coverage 74 | .coverage.* 75 | .cache 76 | nosetests.xml 77 | coverage.xml 78 | *.cover 79 | *.py,cover 80 | .hypothesis/ 81 | .pytest_cache/ 82 | cover/ 83 | 84 | # Translations 85 | *.mo 86 | *.pot 87 | 88 | # Django stuff: 89 | *.log 90 | local_settings.py 91 | db.sqlite3 92 | db.sqlite3-journal 93 | 94 | # Flask stuff: 95 | instance/ 96 | .webassets-cache 97 | 98 | # Scrapy stuff: 99 | .scrapy 100 | 101 | # Sphinx documentation 102 | docs/_build/ 103 | 104 | # PyBuilder 105 | .pybuilder/ 106 | target/ 107 | 108 | # Jupyter Notebook 109 | .ipynb_checkpoints 110 | 111 | # IPython 112 | profile_default/ 113 | ipython_config.py 114 | 115 | # pyenv 116 | # For a library or package, you might want to ignore these files since the code is 117 | # intended to run in multiple environments; otherwise, check them in: 118 | # .python-version 119 | 120 | # pipenv 121 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 122 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 123 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 124 | # install all needed dependencies. 125 | #Pipfile.lock 126 | 127 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 128 | __pypackages__/ 129 | 130 | # Celery stuff 131 | celerybeat-schedule 132 | celerybeat.pid 133 | 134 | # SageMath parsed files 135 | *.sage.py 136 | 137 | # Environments 138 | .env 139 | .venv 140 | env/ 141 | venv/ 142 | ENV/ 143 | env.bak/ 144 | venv.bak/ 145 | 146 | # Spyder project settings 147 | .spyderproject 148 | .spyproject 149 | 150 | # Rope project settings 151 | .ropeproject 152 | 153 | # mkdocs documentation 154 | /site 155 | 156 | # mypy 157 | .mypy_cache/ 158 | .dmypy.json 159 | dmypy.json 160 | 161 | # Pyre type checker 162 | .pyre/ 163 | 164 | # pytype static type analyzer 165 | .pytype/ 166 | 167 | # Cython debug symbols 168 | cython_debug/ 169 | 170 | # Directories 171 | /build*/ 172 | /_*/ 173 | -------------------------------------------------------------------------------- /python/dftd4/__init__.py: -------------------------------------------------------------------------------- 1 | # This file is part of dftd4. 2 | # SPDX-Identifier: LGPL-3.0-or-later 3 | # 4 | # dftd4 is free software: you can redistribute it and/or modify it under 5 | # the terms of the Lesser GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # dftd4 is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # Lesser GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the Lesser GNU General Public License 15 | # along with dftd4. If not, see . 16 | """Python API of the dftd4 program package""" 17 | 18 | # make sure we have a CFFI available 19 | import cffi 20 | 21 | __version__ = "3.7.0" 22 | -------------------------------------------------------------------------------- /python/dftd4/library.py: -------------------------------------------------------------------------------- 1 | # This file is part of dftd4. 2 | # SPDX-Identifier: LGPL-3.0-or-later 3 | # 4 | # dftd4 is free software: you can redistribute it and/or modify it under 5 | # the terms of the Lesser GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # dftd4 is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # Lesser GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the Lesser GNU General Public License 15 | # along with dftd4. If not, see . 16 | """Thin wrapper around the CFFI extension module. 17 | 18 | This module mainly acts as a guard for importing the libdftd4 extension and 19 | also provides some FFI based wappers for memory handling. 20 | 21 | To check for API compatibility use the provided wrapper around the API version 22 | getter. 23 | 24 | Example 25 | ------- 26 | >>> from dftd4.library import get_api_version 27 | >>> get_api_version() 28 | '3.7.0' 29 | """ 30 | 31 | import functools 32 | 33 | try: 34 | from ._libdftd4 import ffi, lib 35 | except ImportError: 36 | raise ImportError("dftd4 C extension unimportable, cannot use C-API") 37 | 38 | 39 | def get_api_version() -> str: 40 | """Return the current API version from dftd4. 41 | For easy usage in C the API version is provided as 42 | 43 | 10000 * major + 100 * minor + patch 44 | 45 | For Python we want something that looks like a semantic version again. 46 | """ 47 | api_version = lib.dftd4_get_version() 48 | return "{}.{}.{}".format( 49 | api_version // 10000, 50 | api_version % 10000 // 100, 51 | api_version % 100, 52 | ) 53 | 54 | 55 | def _delete_error(error) -> None: 56 | """Delete a dftd4 error handler object""" 57 | ptr = ffi.new("dftd4_error *") 58 | ptr[0] = error 59 | lib.dftd4_delete_error(ptr) 60 | 61 | 62 | def new_error(): 63 | """Create new dftd4 error handler object""" 64 | return ffi.gc(lib.dftd4_new_error(), _delete_error) 65 | 66 | 67 | def error_check(func): 68 | """Handle errors for library functions that require an error handle""" 69 | 70 | @functools.wraps(func) 71 | def handle_error(*args, **kwargs): 72 | """Run function and than compare context""" 73 | _err = new_error() 74 | value = func(_err, *args, **kwargs) 75 | if lib.dftd4_check_error(_err): 76 | _message = ffi.new("char[]", 512) 77 | lib.dftd4_get_error(_err, _message, ffi.NULL) 78 | raise RuntimeError(ffi.string(_message).decode()) 79 | return value 80 | 81 | return handle_error 82 | 83 | 84 | def _delete_structure(mol) -> None: 85 | """Delete molecular structure data""" 86 | ptr = ffi.new("dftd4_structure *") 87 | ptr[0] = mol 88 | lib.dftd4_delete_structure(ptr) 89 | 90 | 91 | def new_structure(natoms, numbers, positions, charge, lattice, periodic): 92 | """Create new molecular structure data""" 93 | return ffi.gc( 94 | error_check(lib.dftd4_new_structure)( 95 | natoms, 96 | numbers, 97 | positions, 98 | charge, 99 | lattice, 100 | periodic, 101 | ), 102 | _delete_structure, 103 | ) 104 | 105 | 106 | def _delete_model(error) -> None: 107 | """Delete a dftd4 dispersion model object""" 108 | ptr = ffi.new("dftd4_model *") 109 | ptr[0] = error 110 | lib.dftd4_delete_model(ptr) 111 | 112 | 113 | def new_d4_model(mol): 114 | """Create new dftd4 D4 dispersion model object""" 115 | return ffi.gc(error_check(lib.dftd4_new_d4_model)(mol), _delete_model) 116 | 117 | 118 | def new_d4s_model(mol): 119 | """Create new dftd4 D4S dispersion model object""" 120 | return ffi.gc(error_check(lib.dftd4_new_d4s_model)(mol), _delete_model) 121 | 122 | 123 | def custom_d4_model(mol, ga, gc, wf): 124 | """Create new dftd4 D4 dispersion model object""" 125 | return ffi.gc( 126 | error_check(lib.dftd4_custom_d4_model)(mol, ga, gc, wf), _delete_model 127 | ) 128 | 129 | 130 | def custom_d4s_model(mol, ga, gc): 131 | """Create new dftd4 D4S dispersion model object""" 132 | return ffi.gc( 133 | error_check(lib.dftd4_custom_d4s_model)(mol, ga, gc), _delete_model 134 | ) 135 | 136 | 137 | def _delete_param(error) -> None: 138 | """Delete a dftd4 damping parameter object""" 139 | ptr = ffi.new("dftd4_param *") 140 | ptr[0] = error 141 | lib.dftd4_delete_param(ptr) 142 | 143 | 144 | def new_rational_damping(s6, s8, s9, a1, a2, alp): 145 | """Create new dftd4 damping parameter object""" 146 | return ffi.gc( 147 | error_check(lib.dftd4_new_rational_damping)(s6, s8, s9, a1, a2, alp), 148 | _delete_param, 149 | ) 150 | 151 | 152 | def load_rational_damping(method, mbd): 153 | """Create new dftd4 damping parameter object by loading it from the database""" 154 | return ffi.gc( 155 | error_check(lib.dftd4_load_rational_damping)(method, mbd), 156 | _delete_param, 157 | ) 158 | 159 | 160 | update_structure = error_check(lib.dftd4_update_structure) 161 | get_dispersion = error_check(lib.dftd4_get_dispersion) 162 | get_pairwise_dispersion = error_check(lib.dftd4_get_pairwise_dispersion) 163 | get_properties = error_check(lib.dftd4_get_properties) 164 | 165 | 166 | def _ref(ctype, value): 167 | """Create a reference to a value""" 168 | if value is None: 169 | return ffi.NULL 170 | ref = ffi.new(ctype + "*") 171 | ref[0] = value 172 | return ref 173 | -------------------------------------------------------------------------------- /python/dftd4/meson.build: -------------------------------------------------------------------------------- 1 | # This file is part of dftd4. 2 | # SPDX-Identifier: LGPL-3.0-or-later 3 | # 4 | # dftd4 is free software: you can redistribute it and/or modify it under 5 | # the terms of the Lesser GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # dftd4 is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # Lesser GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the Lesser GNU General Public License 15 | # along with dftd4. If not, see . 16 | 17 | cc = meson.get_compiler('c') 18 | 19 | pymod = import('python') 20 | python = pymod.find_installation( 21 | get_option('python_version'), 22 | modules: [ 23 | 'cffi', 24 | 'setuptools', 25 | ], 26 | ) 27 | python_dep = python.dependency(required: true) 28 | 29 | # Python's CFFI is horrible in working with preprocessor statements, 30 | # therefore, we have to preprocess the header before passing it to the ffibuilder 31 | dftd4_pp = configure_file( 32 | command: [ 33 | cc, 34 | '-I@0@'.format( 35 | dftd4_dep.get_variable( 36 | pkgconfig: 'includedir', 37 | cmake: 'dftd4_INCLUDE_DIRS', 38 | internal: 'includedir', 39 | ).split().get(0) 40 | ), 41 | '-DDFTD4_CFFI', 42 | '-E', 43 | '@INPUT@', 44 | ], 45 | input: dftd4_header, 46 | output: '_libdftd4.h', 47 | capture: true, 48 | ) 49 | 50 | # This is the actual out-of-line API processing of the ffibuilder 51 | dftd4_cffi_srcs = configure_file( 52 | command: [python, files('..'/'ffibuilder.py'), '@INPUT@', '@BASENAME@'], 53 | input: dftd4_pp, 54 | output: '@BASENAME@.c', 55 | ) 56 | 57 | # Actual generation of the Python extension, since the shared_module does not work 58 | # well with dependency objects, we will trick it by linking a whole static lib 59 | dftd4_pyext = python.extension_module( 60 | '_libdftd4', 61 | link_whole: static_library( 62 | '_libdftd4', 63 | dftd4_cffi_srcs, 64 | dependencies: [dftd4_dep, python_dep], 65 | ), 66 | dependencies: [dftd4_dep, python_dep], 67 | install: install, 68 | subdir: 'dftd4', 69 | ) 70 | 71 | pysrcs = files( 72 | '__init__.py', 73 | 'ase.py', 74 | 'data.py', 75 | 'interface.py', 76 | 'library.py', 77 | 'parameters.py', 78 | 'pyscf.py', 79 | 'qcschema.py', 80 | 'references.json', 81 | 'test_ase.py', 82 | 'test_interface.py', 83 | 'test_library.py', 84 | 'test_parameters.py', 85 | 'test_pyscf.py', 86 | 'test_qcschema.py', 87 | ) 88 | fs = import('fs') 89 | if fs.exists('parameters.toml') 90 | pysrcs += files('parameters.toml') 91 | endif 92 | 93 | if install 94 | python.install_sources( 95 | pysrcs, 96 | subdir: 'dftd4', 97 | pure: false, 98 | ) 99 | endif 100 | 101 | -------------------------------------------------------------------------------- /python/dftd4/parameters.py: -------------------------------------------------------------------------------- 1 | # This file is part of dftd4. 2 | # SPDX-Identifier: LGPL-3.0-or-later 3 | # 4 | # dftd4 is free software: you can redistribute it and/or modify it under 5 | # the terms of the Lesser GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # dftd4 is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # Lesser GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the Lesser GNU General Public License 15 | # along with dftd4. If not, see . 16 | 17 | from os.path import dirname, exists, join 18 | from typing import Optional 19 | 20 | # We prefer tomli and tomlkit here, because they are 1.0.0 compliant, while toml is not yet 21 | try: 22 | import tomli as toml_impl 23 | except ModuleNotFoundError: 24 | try: 25 | import tomlkit as toml_impl 26 | except ModuleNotFoundError: 27 | try: 28 | import toml as toml_impl 29 | except ModuleNotFoundError: 30 | raise ModuleNotFoundError( 31 | "No TOML parser implementation found, install tomli, tomlkit or toml" 32 | ) 33 | 34 | _data_base = None 35 | 36 | 37 | def load_data_base(name: str) -> dict: 38 | """Load damping parameter database""" 39 | 40 | with open(name) as fh: 41 | return toml_impl.loads(fh.read()) 42 | 43 | 44 | def get_data_file_name(base_name: str = "parameters.toml") -> str: 45 | """The data base file is usually shipped with the dftd4 installation in 46 | $PREFIX/share/dftd4, which we access from $PREFIX/lib/pythonX.Y/site-packages/dftd4. 47 | 48 | If we don't find the parameter file there we might be standalone and ship 49 | our own data base file in the same directory as this source file. 50 | """ 51 | 52 | data_file = join( 53 | dirname(__file__), "..", "..", "..", "..", "share", "dftd4", base_name 54 | ) 55 | if not exists(data_file): 56 | # for Windows install layout 57 | data_file = join( 58 | dirname(__file__), "..", "..", "..", "Library", "share", "dftd4", base_name 59 | ) 60 | if not exists(data_file): 61 | data_file = join(dirname(__file__), base_name) 62 | 63 | return data_file 64 | 65 | 66 | def _get_params(entry: dict, base: dict, defaults: list, keep_meta=False) -> dict: 67 | """Retrive the parameters from the data base, make sure the default 68 | values are applied correctly in the process. In case we have multiple 69 | defaults search for the first of the list defined for this method.""" 70 | 71 | for default in defaults: 72 | try: 73 | params = base[default].copy() 74 | params.update(**entry[default]) 75 | if not keep_meta: 76 | for key in ("mbd", "damping", "doi"): 77 | if key in params: del params[key] 78 | return params 79 | except KeyError: 80 | continue 81 | 82 | raise KeyError("No entry for " + method + " in parameter data base") 83 | 84 | 85 | def get_damping_param( 86 | method: str, 87 | defaults: Optional[list] = None, 88 | data_file: Optional[str] = None, 89 | keep_meta=False, 90 | ) -> dict: 91 | """Obtain damping parameters from a data base file.""" 92 | global _data_base 93 | 94 | if _data_base is None: 95 | 96 | if data_file is None: 97 | data_file = get_data_file_name() 98 | 99 | _data_base = load_data_base(data_file) 100 | 101 | if "default" not in _data_base or "parameter" not in _data_base: 102 | raise KeyError("No default correct scheme provided") 103 | 104 | if defaults is None: 105 | defaults = _data_base["default"]["d4"] 106 | 107 | _base = _data_base["default"]["parameter"]["d4"] 108 | _entry = _data_base["parameter"][method.lower()]["d4"] 109 | 110 | return _get_params(_entry, _base, defaults, keep_meta) 111 | 112 | 113 | def get_all_damping_params( 114 | defaults: Optional[list] = None, data_file: Optional[str] = None, keep_meta=False 115 | ) -> dict: 116 | """Provide dictionary with all damping parameters available from parameter file""" 117 | global _data_base 118 | 119 | if _data_base is None: 120 | 121 | if data_file is None: 122 | data_file = get_data_file_name() 123 | 124 | _data_base = load_data_base(data_file) 125 | 126 | try: 127 | if defaults is None: 128 | defaults = _data_base["default"]["d4"] 129 | _base = _data_base["default"]["parameter"]["d4"] 130 | _parameters = _data_base["parameter"] 131 | except KeyError: 132 | return {} 133 | 134 | definitions = {} 135 | 136 | for method in _parameters: 137 | try: 138 | _entry = _parameters[method]["d4"] 139 | params = _get_params(_entry, _base, defaults, keep_meta) 140 | definitions[method] = params 141 | except KeyError: 142 | continue 143 | 144 | return definitions 145 | -------------------------------------------------------------------------------- /python/dftd4/test_ase.py: -------------------------------------------------------------------------------- 1 | # This file is part of dftd4. 2 | # SPDX-Identifier: LGPL-3.0-or-later 3 | # 4 | # dftd4 is free software: you can redistribute it and/or modify it under 5 | # the terms of the Lesser GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # dftd4 is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # Lesser GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the Lesser GNU General Public License 15 | # along with dftd4. If not, see . 16 | 17 | import numpy as np 18 | from ase.build import molecule 19 | from ase.calculators.emt import EMT 20 | from dftd4.ase import DFTD4 21 | from pytest import approx 22 | 23 | 24 | def test_ase_scand4() -> None: 25 | thr = 1.0e-6 26 | 27 | forces = np.array( 28 | [ 29 | [-7.90552684e-21, -1.15811595e-19, -2.80061133e-05], 30 | [+4.61502216e-20, +4.26735028e-04, +4.94269127e-04], 31 | [+2.28682834e-19, -4.26735028e-04, +4.94269127e-04], 32 | [+1.39725405e-20, -9.71924142e-20, -7.95205193e-04], 33 | [-1.08042249e-04, -8.23929519e-05, +2.31098749e-05], 34 | [+1.08042249e-04, -8.23929519e-05, +2.31098749e-05], 35 | [+1.08042249e-04, +8.23929519e-05, +2.31098749e-05], 36 | [-1.08042249e-04, +8.23929519e-05, +2.31098749e-05], 37 | [+1.07391220e-20, -4.98420762e-05, -1.28883224e-04], 38 | [+5.97028977e-21, +4.98420762e-05, -1.28883224e-04], 39 | ] 40 | ) 41 | 42 | atoms = molecule("methylenecyclopropane") 43 | atoms.calc = DFTD4(method="SCAN") 44 | 45 | assert approx(atoms.get_potential_energy(), abs=thr) == -0.021665446836610567 46 | assert approx(atoms.get_forces(), abs=thr) == forces 47 | 48 | atoms.calc = DFTD4(method="SCAN").add_calculator(EMT()) 49 | assert approx(atoms.get_potential_energy(), abs=thr) == 3.6624398683434225 50 | 51 | if hasattr(atoms.calc, "calcs"): 52 | calcs = atoms.calc.calcs 53 | else: 54 | calcs = atoms.calc.mixer.calcs 55 | 56 | energies = [calc.get_potential_energy() for calc in calcs] 57 | assert approx(energies, abs=thr) == [-0.021665446836610563, 3.684105315180033] 58 | 59 | 60 | def test_ase_pbed4s() -> None: 61 | thr = 1.0e-6 62 | 63 | forces = np.array( 64 | [ 65 | [-1.05900228e-18, -1.47186433e-03, -2.08505399e-03], 66 | [-8.94454333e-19, 1.47186433e-03, -2.08505399e-03], 67 | [-2.48990627e-03, -1.06729670e-18, 2.15375860e-03], 68 | [ 2.48990627e-03, -1.91047493e-19, 2.15375860e-03], 69 | [-4.33024525e-22, -2.06112648e-03, -6.95481292e-05], 70 | [ 2.47579260e-21, -2.26182709e-03, -5.56758674e-04], 71 | [ 3.90654502e-20, 2.06112648e-03, -6.95481292e-05], 72 | [ 4.57489295e-20, 2.26182709e-03, -5.56758674e-04], 73 | [-1.57814347e-03, 6.44754156e-19, 5.57602199e-04], 74 | [ 1.57814347e-03, 5.62735538e-19, 5.57602199e-04], 75 | ] 76 | ) 77 | 78 | atoms = molecule("bicyclobutane") 79 | atoms.calc = DFTD4(method="PBE", model="d4s") 80 | 81 | assert approx(atoms.get_potential_energy(), abs=thr) == -0.16377494406788423 82 | assert approx(atoms.get_forces(), abs=thr) == forces 83 | 84 | atoms.calc = DFTD4(method="PBE", model="d4s").add_calculator(EMT()) 85 | assert approx(atoms.get_potential_energy(), abs=thr) == 3.364290912363593 86 | 87 | if hasattr(atoms.calc, "calcs"): 88 | calcs = atoms.calc.calcs 89 | else: 90 | calcs = atoms.calc.mixer.calcs 91 | 92 | energies = [calc.get_potential_energy() for calc in calcs] 93 | assert approx(energies, abs=thr) == [-0.16377494406788423, 3.5280658564314775] 94 | 95 | 96 | def test_ase_tpssd4() -> None: 97 | thr = 1.0e-6 98 | 99 | forces = np.array( 100 | [ 101 | [-8.27697238e-04, -1.74116189e-02, +9.50315402e-05], 102 | [-3.00615825e-04, +3.51410800e-04, -3.12339518e-03], 103 | [-9.55691674e-04, -4.05325537e-03, +7.33934018e-05], 104 | [+2.70525425e-04, -1.91784287e-03, -6.13796425e-04], 105 | [+1.56444473e-02, +5.71643192e-03, +6.29706049e-04], 106 | [-1.43399413e-02, +7.36397630e-03, +7.87584027e-04], 107 | [+4.41551907e-03, +4.04705396e-04, +1.42098826e-03], 108 | [-4.17670039e-03, +1.57923335e-03, +1.60488604e-03], 109 | [+4.66065256e-03, +7.97764912e-05, -3.60249901e-05], 110 | [-4.95386767e-03, +1.38115911e-03, -1.63079386e-05], 111 | [+5.36717422e-03, +2.78165913e-03, -4.68647341e-04], 112 | [-4.80380448e-03, +3.72436466e-03, -3.53417437e-04], 113 | ] 114 | ) 115 | 116 | atoms = molecule("C2H6CHOH") 117 | atoms.calc = DFTD4(method="TPSS") 118 | 119 | assert approx(atoms.get_potential_energy(), abs=thr) == -0.24206732765720423 120 | assert approx(atoms.get_forces(), abs=thr) == forces 121 | 122 | atoms.calc = DFTD4(method="TPSS").add_calculator(EMT()) 123 | assert approx(atoms.get_potential_energy(), abs=thr) == 4.864016486351274 124 | 125 | if hasattr(atoms.calc, 'calcs'): 126 | calcs = atoms.calc.calcs 127 | else: 128 | calcs = atoms.calc.mixer.calcs 129 | 130 | energies = [calc.get_potential_energy() for calc in calcs] 131 | assert approx(energies, abs=thr) == [-0.24206732765720396, 5.106083814008478] 132 | -------------------------------------------------------------------------------- /python/dftd4/test_library.py: -------------------------------------------------------------------------------- 1 | # This file is part of dftd4. 2 | # SPDX-Identifier: LGPL-3.0-or-later 3 | # 4 | # dftd4 is free software: you can redistribute it and/or modify it under 5 | # the terms of the Lesser GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # dftd4 is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # Lesser GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the Lesser GNU General Public License 15 | # along with dftd4. If not, see . 16 | 17 | 18 | from dftd4.library import get_api_version 19 | from pkg_resources import parse_version 20 | 21 | from dftd4 import __version__ 22 | 23 | 24 | def test_api_version() -> None: 25 | """Ensure that the API version is compatible.""" 26 | 27 | assert parse_version(get_api_version()) == parse_version(__version__) 28 | -------------------------------------------------------------------------------- /python/dftd4/test_parameters.py: -------------------------------------------------------------------------------- 1 | # This file is part of dftd4. 2 | # SPDX-Identifier: LGPL-3.0-or-later 3 | # 4 | # dftd4 is free software: you can redistribute it and/or modify it under 5 | # the terms of the Lesser GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # dftd4 is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # Lesser GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the Lesser GNU General Public License 15 | # along with dftd4. If not, see . 16 | 17 | 18 | from dftd4.parameters import get_all_damping_params, get_damping_param 19 | from pytest import approx 20 | 21 | 22 | def get_data_file_name() -> str: 23 | """Make sure we can still test without installing""" 24 | from os.path import dirname, exists, join 25 | 26 | from dftd4.parameters import get_data_file_name as _get_data_file_name 27 | 28 | data_file = join(dirname(__file__), "..", "..", "assets", "parameters.toml") 29 | return data_file if exists(data_file) else _get_data_file_name() 30 | 31 | 32 | def test_get_b3lyp() -> None: 33 | expected = { 34 | "s6": 1.0, 35 | "s9": 1.0, 36 | "alp": 16.0, 37 | "s8": 2.02929367, 38 | "a1": 0.40868035, 39 | "a2": 4.53807137, 40 | } 41 | actual = get_damping_param("b3lyp", data_file=get_data_file_name()) 42 | 43 | for key in expected.keys(): 44 | assert approx(actual[key]) == expected[key] 45 | 46 | 47 | def test_get_b2plyp() -> None: 48 | expected = { 49 | "s6": 0.64, 50 | "s9": 1.0, 51 | "alp": 16.0, 52 | "s8": 1.16888646, 53 | "a1": 0.44154604, 54 | "a2": 4.73114642, 55 | } 56 | actual = get_damping_param("b2plyp", data_file=get_data_file_name()) 57 | 58 | for key in expected.keys(): 59 | assert approx(actual[key]) == expected[key] 60 | 61 | 62 | def test_get_pw6b95() -> None: 63 | expected = { 64 | "s6": 1.0, 65 | "s9": 1.0, 66 | "alp": 16.0, 67 | "s8": -0.31629935, 68 | "a1": 0.03999357, 69 | "a2": 5.83690254, 70 | } 71 | actual = get_damping_param( 72 | "pw6b95", data_file=get_data_file_name(), defaults=["bj-eeq-two", "bj-eeq-mbd"] 73 | ) 74 | 75 | for key in expected.keys(): 76 | assert approx(actual[key]) == expected[key] 77 | 78 | 79 | def test_all_parameters() -> None: 80 | params = get_all_damping_params() 81 | 82 | assert "b3lyp" in params 83 | assert "b2plyp" in params 84 | assert "pw6b95" in params 85 | -------------------------------------------------------------------------------- /python/ffibuilder.py: -------------------------------------------------------------------------------- 1 | # This file is part of dftd4. 2 | # SPDX-Identifier: LGPL-3.0-or-later 3 | # 4 | # dftd4 is free software: you can redistribute it and/or modify it under 5 | # the terms of the Lesser GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # dftd4 is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # Lesser GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the Lesser GNU General Public License 15 | # along with dftd4. If not, see . 16 | """ 17 | FFI builder module for dftd4 for usage from meson and from setup.py. 18 | 19 | Since meson has the full knowledge about the build, it will handle 20 | the generation of the C definitions in the meson.build file rather 21 | than in the FFI builder. This allows to correctly keep track of 22 | dependencies and updates in the build process. 23 | 24 | For setup.py we have to do the preprocessing ourselves here, this 25 | requires us to use the C compiler to preprocess the header file 26 | of dftd4 because the CFFI C parser cannot handle certain C 27 | preprocessor constructs. Also, we cannot rely on an external build 28 | system fixing dependencies for us and therefore have to find those 29 | ourselves using pkg-config. 30 | """ 31 | 32 | import os 33 | import cffi 34 | 35 | library = "dftd4" 36 | include_header = '#include "' + library + '.h"' 37 | prefix_var = library.upper() + "_PREFIX" 38 | if prefix_var not in os.environ: 39 | prefix_var = "CONDA_PREFIX" 40 | 41 | if __name__ == "__main__": 42 | import sys 43 | 44 | kwargs = dict(libraries=[library]) 45 | 46 | header_file = sys.argv[1] 47 | module_name = sys.argv[2] 48 | 49 | with open(header_file) as f: 50 | cdefs = f.read() 51 | else: 52 | import subprocess 53 | 54 | try: 55 | import pkgconfig 56 | 57 | if not pkgconfig.exists(library): 58 | raise ModuleNotFoundError("Unable to find pkg-config package 'dftd4'") 59 | if pkgconfig.installed(library, "< 3.0"): 60 | raise Exception( 61 | "Installed 'dftd4' version is too old, 3.0 or newer is required" 62 | ) 63 | 64 | kwargs = pkgconfig.parse(library) 65 | cflags = pkgconfig.cflags(library).split() 66 | 67 | except ModuleNotFoundError: 68 | kwargs = dict(libraries=[library]) 69 | cflags = [] 70 | if prefix_var in os.environ: 71 | prefix = os.environ[prefix_var] 72 | kwargs.update( 73 | include_dirs=[os.path.join(prefix, "include")], 74 | library_dirs=[os.path.join(prefix, "lib")], 75 | runtime_library_dirs=[os.path.join(prefix, "lib")], 76 | ) 77 | cflags.append("-I" + os.path.join(prefix, "include")) 78 | 79 | cc = os.environ["CC"] if "CC" in os.environ else "cc" 80 | 81 | module_name = library + "._lib" + library 82 | 83 | p = subprocess.Popen( 84 | [cc, *cflags, "-E", "-"], 85 | stdin=subprocess.PIPE, 86 | stdout=subprocess.PIPE, 87 | stderr=subprocess.PIPE, 88 | ) 89 | out, err = p.communicate(include_header.encode()) 90 | 91 | cdefs = out.decode() 92 | 93 | ffibuilder = cffi.FFI() 94 | ffibuilder.set_source(module_name, include_header, **kwargs) 95 | ffibuilder.cdef(cdefs) 96 | 97 | if __name__ == "__main__": 98 | ffibuilder.distutils_extension(".") 99 | -------------------------------------------------------------------------------- /python/include/_dftd4.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "dftd4.h" 4 | -------------------------------------------------------------------------------- /python/meson.build: -------------------------------------------------------------------------------- 1 | # This file is part of dftd4. 2 | # SPDX-Identifier: LGPL-3.0-or-later 3 | # 4 | # dftd4 is free software: you can redistribute it and/or modify it under 5 | # the terms of the Lesser GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # dftd4 is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # Lesser GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the Lesser GNU General Public License 15 | # along with dftd4. If not, see . 16 | 17 | # Standalone build for Python-API of DFT-D4, requires a dftd4 library 18 | # in the PKG_CONFIG_PATH environment variable to work. 19 | project( 20 | 'dftd4', 21 | 'c', 22 | version: '3.7.0', 23 | license: 'LGPL-3.0-or-later', 24 | meson_version: '>=0.55,!=1.8.0', 25 | default_options: [ 26 | 'buildtype=debugoptimized', 27 | ], 28 | ) 29 | install = true 30 | 31 | dftd4_dep = dependency( 32 | 'dftd4', 33 | version: '>=@0@'.format(meson.project_version()), 34 | fallback: ['dftd4', 'dftd4_dep'], 35 | default_options: [ 36 | 'default_library=static', 37 | 'api=true', 38 | 'python=false', 39 | ], 40 | ) 41 | dftd4_header = files('include'/'_dftd4.h') 42 | 43 | subdir('dftd4') 44 | -------------------------------------------------------------------------------- /python/meson_options.txt: -------------------------------------------------------------------------------- 1 | # This file is part of dftd4. 2 | # SPDX-Identifier: LGPL-3.0-or-later 3 | # 4 | # dftd4 is free software: you can redistribute it and/or modify it under 5 | # the terms of the Lesser GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # dftd4 is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # Lesser GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the Lesser GNU General Public License 15 | # along with dftd4. If not, see . 16 | 17 | option( 18 | 'python_version', 19 | type: 'string', 20 | value: 'python3', 21 | description: 'Python version to link against.', 22 | ) 23 | -------------------------------------------------------------------------------- /python/pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = [ 3 | "meson-python", 4 | "cffi", 5 | "setuptools", 6 | "meson!=1.8.0", 7 | ] 8 | build-backend = "mesonpy" 9 | 10 | [project] 11 | name = "dftd4" 12 | version = "3.7.0" 13 | description = "Python API of the DFT-D4 project" 14 | readme = "README.rst" 15 | license.text = "LGPL-3.0-or-later" 16 | urls.repository = "https://github.com/dftd4/dftd4" 17 | classifiers = [ 18 | "Intended Audience :: Science/Research", 19 | "Programming Language :: Fortran", 20 | "Programming Language :: Python :: 3", 21 | "Programming Language :: Python :: 3.7", 22 | "Programming Language :: Python :: 3.8", 23 | "Programming Language :: Python :: 3.9", 24 | "Programming Language :: Python :: 3.10", 25 | "Programming Language :: Python :: 3.11", 26 | "Programming Language :: Python :: 3.12", 27 | "Programming Language :: Python :: 3.13", 28 | "Topic :: Scientific/Engineering :: Chemistry", 29 | "Topic :: Scientific/Engineering :: Physics", 30 | ] 31 | requires-python = ">=3.7" 32 | dependencies = [ 33 | "cffi", 34 | "numpy", 35 | ] 36 | optional-dependencies.ase = [ 37 | "ase<3.23; python_version < '3.8'", 38 | "ase; python_version >= '3.8'", 39 | ] 40 | optional-dependencies.qcschema = ["qcelemental"] 41 | optional-dependencies.pyscf = ["pyscf"] 42 | optional-dependencies.test = [ 43 | "pytest", 44 | "pytest-cov", 45 | ] 46 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # This file is part of dftd4. 2 | # SPDX-Identifier: LGPL-3.0-or-later 3 | # 4 | # dftd4 is free software: you can redistribute it and/or modify it under 5 | # the terms of the GNU Lesser General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # dftd4 is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU Lesser General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU Lesser General Public License 15 | # along with dftd4. If not, see . 16 | 17 | add_subdirectory("dftd4") 18 | 19 | set(dir "${CMAKE_CURRENT_SOURCE_DIR}") 20 | 21 | list( 22 | APPEND srcs 23 | "${dir}/dftd4.f90" 24 | ) 25 | 26 | set(srcs "${srcs}" PARENT_SCOPE) 27 | -------------------------------------------------------------------------------- /src/dftd4.f90: -------------------------------------------------------------------------------- 1 | ! This file is part of dftd4. 2 | ! SPDX-Identifier: LGPL-3.0-or-later 3 | ! 4 | ! dftd4 is free software: you can redistribute it and/or modify it under 5 | ! the terms of the Lesser GNU General Public License as published by 6 | ! the Free Software Foundation, either version 3 of the License, or 7 | ! (at your option) any later version. 8 | ! 9 | ! dftd4 is distributed in the hope that it will be useful, 10 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | ! Lesser GNU General Public License for more details. 13 | ! 14 | ! You should have received a copy of the Lesser GNU General Public License 15 | ! along with dftd4. If not, see . 16 | 17 | module dftd4 18 | use mctc_io, only : structure_type, new 19 | use dftd4_cutoff, only : realspace_cutoff, get_lattice_points 20 | use dftd4_disp, only : get_dispersion, get_properties, get_pairwise_dispersion 21 | use dftd4_ncoord, only : get_coordination_number 22 | use dftd4_numdiff, only : get_dispersion_hessian 23 | use dftd4_damping, only : damping_param 24 | use dftd4_damping_rational, only : rational_damping_param 25 | use dftd4_model, only : dispersion_model 26 | use dftd4_model_d4, only : d4_model, new_d4_model 27 | use dftd4_model_d4s, only : d4s_model, new_d4s_model 28 | use dftd4_param, only : get_rational_damping 29 | use dftd4_version, only : get_dftd4_version 30 | implicit none 31 | public 32 | 33 | end module dftd4 34 | -------------------------------------------------------------------------------- /src/dftd4/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # This file is part of dftd4. 2 | # SPDX-Identifier: LGPL-3.0-or-later 3 | # 4 | # dftd4 is free software: you can redistribute it and/or modify it under 5 | # the terms of the GNU Lesser General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # dftd4 is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU Lesser General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU Lesser General Public License 15 | # along with dftd4. If not, see . 16 | 17 | add_subdirectory("damping") 18 | add_subdirectory("data") 19 | add_subdirectory("model") 20 | 21 | set(dir "${CMAKE_CURRENT_SOURCE_DIR}") 22 | 23 | list( 24 | APPEND srcs 25 | "${dir}/blas.F90" 26 | "${dir}/charge.f90" 27 | "${dir}/cutoff.f90" 28 | "${dir}/damping.f90" 29 | "${dir}/data.f90" 30 | "${dir}/disp.f90" 31 | "${dir}/model.f90" 32 | "${dir}/ncoord.f90" 33 | "${dir}/numdiff.f90" 34 | "${dir}/output.f90" 35 | "${dir}/param.f90" 36 | "${dir}/reference.f90" 37 | "${dir}/utils.f90" 38 | "${dir}/version.f90" 39 | ) 40 | if(WITH_API) 41 | list(APPEND srcs "${dir}/api.f90") 42 | endif() 43 | if(WITH_API_V2) 44 | list(APPEND srcs "${dir}/compat.f90") 45 | endif() 46 | 47 | set(srcs "${srcs}" PARENT_SCOPE) 48 | -------------------------------------------------------------------------------- /src/dftd4/charge.f90: -------------------------------------------------------------------------------- 1 | ! This file is part of dftd4. 2 | ! SPDX-Identifier: LGPL-3.0-or-later 3 | ! 4 | ! dftd4 is free software: you can redistribute it and/or modify it under 5 | ! the terms of the Lesser GNU General Public License as published by 6 | ! the Free Software Foundation, either version 3 of the License, or 7 | ! (at your option) any later version. 8 | ! 9 | ! dftd4 is distributed in the hope that it will be useful, 10 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | ! Lesser GNU General Public License for more details. 13 | ! 14 | ! You should have received a copy of the Lesser GNU General Public License 15 | ! along with dftd4. If not, see . 16 | 17 | !> Interface to the charge model 18 | module dftd4_charge 19 | use, intrinsic :: iso_fortran_env, only : error_unit 20 | use mctc_env, only : error_type, wp 21 | use mctc_io, only : structure_type 22 | use multicharge, only : mchrg_model_type, new_eeq2019_model 23 | implicit none 24 | private 25 | 26 | public :: get_charges 27 | 28 | 29 | contains 30 | 31 | 32 | !> Obtain charges from electronegativity equilibration model 33 | subroutine get_charges(mol, qvec, dqdr, dqdL) 34 | !DEC$ ATTRIBUTES DLLEXPORT :: get_charges 35 | 36 | !> Molecular structure data 37 | type(structure_type), intent(in) :: mol 38 | 39 | !> Atomic partial charges 40 | real(wp), intent(out), contiguous :: qvec(:) 41 | 42 | !> Derivative of the partial charges w.r.t. the Cartesian coordinates 43 | real(wp), intent(out), contiguous, optional :: dqdr(:, :, :) 44 | 45 | !> Derivative of the partial charges w.r.t. strain deformations 46 | real(wp), intent(out), contiguous, optional :: dqdL(:, :, :) 47 | 48 | logical :: grad 49 | type(mchrg_model_type) :: model 50 | type(error_type), allocatable :: error 51 | real(wp), parameter :: cn_max = 8.0_wp, cutoff = 25.0_wp 52 | real(wp), allocatable :: cn(:), dcndr(:, :, :), dcndL(:, :, :) 53 | real(wp), allocatable :: rcov(:), trans(:, :) 54 | 55 | grad = present(dqdr) .and. present(dqdL) 56 | 57 | call new_eeq2019_model(mol, model, error) 58 | if(allocated(error)) then 59 | write(error_unit, '("[Error]:", 1x, a)') error%message 60 | error stop 61 | end if 62 | 63 | allocate(cn(mol%nat)) 64 | if (grad) then 65 | allocate(dcndr(3, mol%nat, mol%nat), dcndL(3, 3, mol%nat)) 66 | end if 67 | 68 | call model%ncoord%get_cn(mol, cn, dcndr, dcndL) 69 | 70 | call model%solve(mol, error, cn, dcndr, dcndL, qvec=qvec, dqdr=dqdr, dqdL=dqdL) 71 | if(allocated(error)) then 72 | write(error_unit, '("[Error]:", 1x, a)') error%message 73 | error stop 74 | end if 75 | 76 | end subroutine get_charges 77 | 78 | 79 | end module dftd4_charge 80 | -------------------------------------------------------------------------------- /src/dftd4/cutoff.f90: -------------------------------------------------------------------------------- 1 | ! This file is part of dftd4. 2 | ! SPDX-Identifier: LGPL-3.0-or-later 3 | ! 4 | ! dftd4 is free software: you can redistribute it and/or modify it under 5 | ! the terms of the Lesser GNU General Public License as published by 6 | ! the Free Software Foundation, either version 3 of the License, or 7 | ! (at your option) any later version. 8 | ! 9 | ! dftd4 is distributed in the hope that it will be useful, 10 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | ! Lesser GNU General Public License for more details. 13 | ! 14 | ! You should have received a copy of the Lesser GNU General Public License 15 | ! along with dftd4. If not, see . 16 | 17 | !> Realspace cutoff and lattice point generator utilities 18 | module dftd4_cutoff 19 | use mctc_env, only : wp 20 | implicit none 21 | private 22 | 23 | public :: realspace_cutoff, get_lattice_points 24 | 25 | 26 | !> Coordination number cutoff 27 | real(wp), parameter :: cn_default = 30.0_wp 28 | 29 | !> Two-body interaction cutoff 30 | real(wp), parameter :: disp2_default = 60.0_wp 31 | 32 | !> Three-body interaction cutoff 33 | real(wp), parameter :: disp3_default = 40.0_wp 34 | 35 | 36 | !> Collection of real space cutoffs 37 | type :: realspace_cutoff 38 | sequence 39 | 40 | !> Coordination number cutoff 41 | real(wp) :: cn = cn_default 42 | 43 | !> Two-body interaction cutoff 44 | real(wp) :: disp2 = disp2_default 45 | 46 | !> Three-body interaction cutoff 47 | real(wp) :: disp3 = disp3_default 48 | 49 | end type realspace_cutoff 50 | 51 | 52 | interface get_lattice_points 53 | module procedure :: get_lattice_points_cutoff 54 | module procedure :: get_lattice_points_rep_3d 55 | end interface get_lattice_points 56 | 57 | 58 | contains 59 | 60 | 61 | !> Generate lattice points from repeatitions 62 | subroutine get_lattice_points_rep_3d(lat, rep, origin, trans) 63 | 64 | !> Lattice vectors 65 | real(wp), intent(in) :: lat(:, :) 66 | 67 | !> Repeatitions of lattice points to generate 68 | integer, intent(in) :: rep(:) 69 | 70 | !> Include the origin in the generated lattice points 71 | logical, intent(in) :: origin 72 | 73 | !> Generated lattice points 74 | real(wp), allocatable, intent(out) :: trans(:, :) 75 | 76 | integer :: itr, ix, iy, iz, jx, jy, jz 77 | 78 | itr = 0 79 | if (origin) then 80 | allocate(trans(3, product(2*rep+1))) 81 | do ix = 0, rep(1) 82 | do iy = 0, rep(2) 83 | do iz = 0, rep(3) 84 | do jx = 1, merge(-1, 1, ix > 0), -2 85 | do jy = 1, merge(-1, 1, iy > 0), -2 86 | do jz = 1, merge(-1, 1, iz > 0), -2 87 | itr = itr + 1 88 | trans(:, itr) = lat(:, 1)*ix*jx & 89 | & + lat(:, 2)*iy*jy + lat(:, 3)*iz*jz 90 | end do 91 | end do 92 | end do 93 | end do 94 | end do 95 | end do 96 | else 97 | allocate(trans(3, product(2*rep+1)-1)) 98 | do ix = 0, rep(1) 99 | do iy = 0, rep(2) 100 | do iz = 0, rep(3) 101 | if (ix == 0 .and. iy == 0 .and. iz == 0) cycle 102 | do jx = 1, merge(-1, 1, ix > 0), -2 103 | do jy = 1, merge(-1, 1, iy > 0), -2 104 | do jz = 1, merge(-1, 1, iz > 0), -2 105 | itr = itr + 1 106 | trans(:, itr) = lat(:, 1)*ix*jx & 107 | & + lat(:, 2)*iy*jy + lat(:, 3)*iz*jz 108 | end do 109 | end do 110 | end do 111 | end do 112 | end do 113 | end do 114 | end if 115 | 116 | end subroutine get_lattice_points_rep_3d 117 | 118 | 119 | !> Create lattice points within a given cutoff 120 | subroutine get_lattice_points_cutoff(periodic, lat, rthr, trans) 121 | !DEC$ ATTRIBUTES DLLEXPORT :: get_lattice_points_cutoff 122 | 123 | !> Periodic dimensions 124 | logical, intent(in) :: periodic(:) 125 | 126 | !> Real space cutoff 127 | real(wp), intent(in) :: rthr 128 | 129 | !> Lattice parameters 130 | real(wp), intent(in) :: lat(:, :) 131 | 132 | !> Generated lattice points 133 | real(wp), allocatable, intent(out) :: trans(:, :) 134 | 135 | integer :: rep(3) 136 | 137 | if (.not.any(periodic)) then 138 | allocate(trans(3, 1)) 139 | trans(:, :) = 0.0_wp 140 | else 141 | call get_translations(lat, rthr, rep) 142 | call get_lattice_points(lat, rep, .true., trans) 143 | end if 144 | 145 | end subroutine get_lattice_points_cutoff 146 | 147 | 148 | !> Generate a supercell based on a realspace cutoff, this subroutine 149 | !> doesn't know anything about the convergence behaviour of the 150 | !> associated property. 151 | pure subroutine get_translations(lat, rthr, rep) 152 | real(wp), intent(in) :: rthr 153 | real(wp), intent(in) :: lat(3, 3) 154 | integer, intent(out) :: rep(3) 155 | real(wp) :: normx(3), normy(3), normz(3) 156 | real(wp) :: cos10, cos21, cos32 157 | 158 | ! find normal to the plane... 159 | call crossproduct(lat(:, 2), lat(:, 3), normx) 160 | call crossproduct(lat(:, 3), lat(:, 1), normy) 161 | call crossproduct(lat(:, 1), lat(:, 2), normz) 162 | ! ...normalize it... 163 | normx = normx/norm2(normx) 164 | normy = normy/norm2(normy) 165 | normz = normz/norm2(normz) 166 | ! cos angles between normals and lattice vectors 167 | cos10 = sum(normx*lat(:, 1)) 168 | cos21 = sum(normy*lat(:, 2)) 169 | cos32 = sum(normz*lat(:, 3)) 170 | rep(1) = ceiling(abs(rthr/cos10)) 171 | rep(2) = ceiling(abs(rthr/cos21)) 172 | rep(3) = ceiling(abs(rthr/cos32)) 173 | 174 | contains 175 | 176 | pure subroutine crossproduct(a, b, c) 177 | real(wp), intent(in) :: a(3) 178 | real(wp), intent(in) :: b(3) 179 | real(wp), intent(out) :: c(3) 180 | c(1)=a(2)*b(3)-b(2)*a(3) 181 | c(2)=a(3)*b(1)-b(3)*a(1) 182 | c(3)=a(1)*b(2)-b(1)*a(2) 183 | end subroutine crossproduct 184 | 185 | end subroutine get_translations 186 | 187 | 188 | end module dftd4_cutoff 189 | -------------------------------------------------------------------------------- /src/dftd4/damping.f90: -------------------------------------------------------------------------------- 1 | ! This file is part of dftd4. 2 | ! SPDX-Identifier: LGPL-3.0-or-later 3 | ! 4 | ! dftd4 is free software: you can redistribute it and/or modify it under 5 | ! the terms of the Lesser GNU General Public License as published by 6 | ! the Free Software Foundation, either version 3 of the License, or 7 | ! (at your option) any later version. 8 | ! 9 | ! dftd4 is distributed in the hope that it will be useful, 10 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | ! Lesser GNU General Public License for more details. 13 | ! 14 | ! You should have received a copy of the Lesser GNU General Public License 15 | ! along with dftd4. If not, see . 16 | 17 | !> Generic interface to define damping functions for the DFT-D4 model 18 | module dftd4_damping 19 | use mctc_env, only : wp 20 | use mctc_io, only : structure_type 21 | implicit none 22 | 23 | public :: damping_param, dispersion_interface 24 | 25 | 26 | type, abstract :: damping_param 27 | contains 28 | procedure(dispersion_interface), deferred :: get_dispersion2 29 | procedure(dispersion_interface), deferred :: get_dispersion3 30 | procedure(pairwise_dispersion_interface), deferred :: get_pairwise_dispersion2 31 | procedure(pairwise_dispersion_interface), deferred :: get_pairwise_dispersion3 32 | end type damping_param 33 | 34 | 35 | abstract interface 36 | !> Evaluation of the dispersion energy expression 37 | subroutine dispersion_interface(self, mol, trans, cutoff, r4r2, & 38 | & c6, dc6dcn, dc6dq, energy, dEdcn, dEdq, gradient, sigma) 39 | import :: structure_type, damping_param, wp 40 | 41 | !> Damping parameters 42 | class(damping_param), intent(in) :: self 43 | 44 | !> Molecular structure data 45 | class(structure_type), intent(in) :: mol 46 | 47 | !> Lattice points 48 | real(wp), intent(in) :: trans(:, :) 49 | 50 | !> Real space cutoff 51 | real(wp), intent(in) :: cutoff 52 | 53 | !> Expectation values for r4 over r2 operator 54 | real(wp), intent(in) :: r4r2(:) 55 | 56 | !> C6 coefficients for all atom pairs. 57 | real(wp), intent(in) :: c6(:, :) 58 | 59 | !> Derivative of the C6 w.r.t. the coordination number 60 | real(wp), intent(in), optional :: dc6dcn(:, :) 61 | 62 | !> Derivative of the C6 w.r.t. the partial charges 63 | real(wp), intent(in), optional :: dc6dq(:, :) 64 | 65 | !> Dispersion energy 66 | real(wp), intent(inout) :: energy(:) 67 | 68 | !> Derivative of the energy w.r.t. the coordination number 69 | real(wp), intent(inout), optional :: dEdcn(:) 70 | 71 | !> Derivative of the energy w.r.t. the partial charges 72 | real(wp), intent(inout), optional :: dEdq(:) 73 | 74 | !> Dispersion gradient 75 | real(wp), intent(inout), optional :: gradient(:, :) 76 | 77 | !> Dispersion virial 78 | real(wp), intent(inout), optional :: sigma(:, :) 79 | end subroutine dispersion_interface 80 | 81 | !> Evaluation of the pairwise representation of the dispersion energy 82 | subroutine pairwise_dispersion_interface(self, mol, trans, cutoff, r4r2, c6, energy) 83 | import :: structure_type, damping_param, wp 84 | 85 | !> Damping parameters 86 | class(damping_param), intent(in) :: self 87 | 88 | !> Molecular structure data 89 | class(structure_type), intent(in) :: mol 90 | 91 | !> Lattice points 92 | real(wp), intent(in) :: trans(:, :) 93 | 94 | !> Real space cutoff 95 | real(wp), intent(in) :: cutoff 96 | 97 | !> Expectation values for r4 over r2 operator 98 | real(wp), intent(in) :: r4r2(:) 99 | 100 | !> C6 coefficients for all atom pairs. 101 | real(wp), intent(in) :: c6(:, :) 102 | 103 | !> Pairwise representation of the dispersion energy 104 | real(wp), intent(inout) :: energy(:, :) 105 | end subroutine pairwise_dispersion_interface 106 | end interface 107 | 108 | 109 | end module dftd4_damping 110 | -------------------------------------------------------------------------------- /src/dftd4/damping/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # This file is part of dftd4. 2 | # SPDX-Identifier: LGPL-3.0-or-later 3 | # 4 | # dftd4 is free software: you can redistribute it and/or modify it under 5 | # the terms of the GNU Lesser General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # dftd4 is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU Lesser General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU Lesser General Public License 15 | # along with dftd4. If not, see . 16 | 17 | set(dir "${CMAKE_CURRENT_SOURCE_DIR}") 18 | 19 | list( 20 | APPEND srcs 21 | "${dir}/atm.f90" 22 | "${dir}/rational.f90" 23 | ) 24 | 25 | set(srcs "${srcs}" PARENT_SCOPE) 26 | -------------------------------------------------------------------------------- /src/dftd4/damping/meson.build: -------------------------------------------------------------------------------- 1 | # This file is part of dftd4. 2 | # SPDX-Identifier: LGPL-3.0-or-later 3 | # 4 | # dftd4 is free software: you can redistribute it and/or modify it under 5 | # the terms of the Lesser GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # dftd4 is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # Lesser GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the Lesser GNU General Public License 15 | # along with dftd4. If not, see . 16 | 17 | srcs += files( 18 | 'atm.f90', 19 | 'rational.f90', 20 | ) 21 | -------------------------------------------------------------------------------- /src/dftd4/data.f90: -------------------------------------------------------------------------------- 1 | ! This file is part of dftd4. 2 | ! SPDX-Identifier: LGPL-3.0-or-later 3 | ! 4 | ! dftd4 is free software: you can redistribute it and/or modify it under 5 | ! the terms of the Lesser GNU General Public License as published by 6 | ! the Free Software Foundation, either version 3 of the License, or 7 | ! (at your option) any later version. 8 | ! 9 | ! dftd4 is distributed in the hope that it will be useful, 10 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | ! Lesser GNU General Public License for more details. 13 | ! 14 | ! You should have received a copy of the Lesser GNU General Public License 15 | ! along with dftd4. If not, see . 16 | 17 | !> Element specific data needed for the DFT-D4 model 18 | module dftd4_data 19 | use dftd4_data_covrad, only : get_covalent_rad 20 | use dftd4_data_en, only : get_electronegativity 21 | use dftd4_data_hardness, only : get_hardness 22 | use dftd4_data_r4r2, only : get_r4r2_val 23 | use dftd4_data_wfpair, only : get_wfpair_val 24 | use dftd4_data_zeff, only : get_effective_charge 25 | implicit none 26 | public 27 | 28 | end module dftd4_data 29 | -------------------------------------------------------------------------------- /src/dftd4/data/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # This file is part of dftd4. 2 | # SPDX-Identifier: LGPL-3.0-or-later 3 | # 4 | # dftd4 is free software: you can redistribute it and/or modify it under 5 | # the terms of the GNU Lesser General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # dftd4 is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU Lesser General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU Lesser General Public License 15 | # along with dftd4. If not, see . 16 | 17 | set(dir "${CMAKE_CURRENT_SOURCE_DIR}") 18 | 19 | list( 20 | APPEND srcs 21 | "${dir}/covrad.f90" 22 | "${dir}/en.f90" 23 | "${dir}/hardness.f90" 24 | "${dir}/r4r2.f90" 25 | "${dir}/wfpair.f90" 26 | "${dir}/zeff.f90" 27 | ) 28 | 29 | set(srcs "${srcs}" PARENT_SCOPE) 30 | -------------------------------------------------------------------------------- /src/dftd4/data/covrad.f90: -------------------------------------------------------------------------------- 1 | ! This file is part of dftd4. 2 | ! SPDX-Identifier: LGPL-3.0-or-later 3 | ! 4 | ! dftd4 is free software: you can redistribute it and/or modify it under 5 | ! the terms of the Lesser GNU General Public License as published by 6 | ! the Free Software Foundation, either version 3 of the License, or 7 | ! (at your option) any later version. 8 | ! 9 | ! dftd4 is distributed in the hope that it will be useful, 10 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | ! Lesser GNU General Public License for more details. 13 | ! 14 | ! You should have received a copy of the Lesser GNU General Public License 15 | ! along with dftd4. If not, see . 16 | 17 | module dftd4_data_covrad 18 | use mctc_env, only : wp 19 | use mctc_io_convert, only : aatoau 20 | use mctc_io_symbols, only : to_number 21 | implicit none 22 | private 23 | 24 | public :: get_covalent_rad 25 | 26 | 27 | !> Covalent radii for DFT-D3 coordination number 28 | interface get_covalent_rad 29 | module procedure :: get_covalent_rad_num 30 | module procedure :: get_covalent_rad_sym 31 | end interface get_covalent_rad 32 | 33 | 34 | integer, parameter :: max_elem = 118 35 | 36 | !> Covalent radii (taken from Pyykko and Atsumi, Chem. Eur. J. 15, 2009, 37 | ! 188-197), values for metals decreased by 10 % 38 | real(wp), parameter :: covalent_rad_2009(max_elem) = aatoau * [ & 39 | & 0.32_wp,0.46_wp, & ! H,He 40 | & 1.20_wp,0.94_wp,0.77_wp,0.75_wp,0.71_wp,0.63_wp,0.64_wp,0.67_wp, & ! Li-Ne 41 | & 1.40_wp,1.25_wp,1.13_wp,1.04_wp,1.10_wp,1.02_wp,0.99_wp,0.96_wp, & ! Na-Ar 42 | & 1.76_wp,1.54_wp, & ! K,Ca 43 | & 1.33_wp,1.22_wp,1.21_wp,1.10_wp,1.07_wp, & ! Sc- 44 | & 1.04_wp,1.00_wp,0.99_wp,1.01_wp,1.09_wp, & ! -Zn 45 | & 1.12_wp,1.09_wp,1.15_wp,1.10_wp,1.14_wp,1.17_wp, & ! Ga-Kr 46 | & 1.89_wp,1.67_wp, & ! Rb,Sr 47 | & 1.47_wp,1.39_wp,1.32_wp,1.24_wp,1.15_wp, & ! Y- 48 | & 1.13_wp,1.13_wp,1.08_wp,1.15_wp,1.23_wp, & ! -Cd 49 | & 1.28_wp,1.26_wp,1.26_wp,1.23_wp,1.32_wp,1.31_wp, & ! In-Xe 50 | & 2.09_wp,1.76_wp, & ! Cs,Ba 51 | & 1.62_wp,1.47_wp,1.58_wp,1.57_wp,1.56_wp,1.55_wp,1.51_wp, & ! La-Eu 52 | & 1.52_wp,1.51_wp,1.50_wp,1.49_wp,1.49_wp,1.48_wp,1.53_wp, & ! Gd-Yb 53 | & 1.46_wp,1.37_wp,1.31_wp,1.23_wp,1.18_wp, & ! Lu- 54 | & 1.16_wp,1.11_wp,1.12_wp,1.13_wp,1.32_wp, & ! -Hg 55 | & 1.30_wp,1.30_wp,1.36_wp,1.31_wp,1.38_wp,1.42_wp, & ! Tl-Rn 56 | & 2.01_wp,1.81_wp, & ! Fr,Ra 57 | & 1.67_wp,1.58_wp,1.52_wp,1.53_wp,1.54_wp,1.55_wp,1.49_wp, & ! Ac-Am 58 | & 1.49_wp,1.51_wp,1.51_wp,1.48_wp,1.50_wp,1.56_wp,1.58_wp, & ! Cm-No 59 | & 1.45_wp,1.41_wp,1.34_wp,1.29_wp,1.27_wp, & ! Lr- 60 | & 1.21_wp,1.16_wp,1.15_wp,1.09_wp,1.22_wp, & ! -Cn 61 | & 1.36_wp,1.43_wp,1.46_wp,1.58_wp,1.48_wp,1.57_wp ] ! Nh-Og 62 | 63 | !> D3 covalent radii used to construct the coordination number 64 | real(wp), parameter :: covalent_rad_d3(max_elem) = & 65 | & 4.0_wp / 3.0_wp * covalent_rad_2009 66 | 67 | contains 68 | 69 | 70 | !> Get covalent radius for a given element symbol 71 | elemental function get_covalent_rad_sym(sym) result(rad) 72 | !DEC$ ATTRIBUTES DLLEXPORT :: get_covalent_rad_sym 73 | 74 | !> Element symbol 75 | character(len=*), intent(in) :: sym 76 | 77 | !> Covalent radius 78 | real(wp) :: rad 79 | 80 | rad = get_covalent_rad(to_number(sym)) 81 | 82 | end function get_covalent_rad_sym 83 | 84 | 85 | !> Get covalent radius for a given atomic number 86 | elemental function get_covalent_rad_num(num) result(rad) 87 | !DEC$ ATTRIBUTES DLLEXPORT :: get_covalent_rad_num 88 | 89 | !> Atomic number 90 | integer, intent(in) :: num 91 | 92 | !> Covalent radius 93 | real(wp) :: rad 94 | 95 | if (num > 0 .and. num <= size(covalent_rad_d3)) then 96 | rad = covalent_rad_d3(num) 97 | else 98 | rad = 0.0_wp 99 | end if 100 | 101 | end function get_covalent_rad_num 102 | 103 | 104 | end module dftd4_data_covrad 105 | -------------------------------------------------------------------------------- /src/dftd4/data/en.f90: -------------------------------------------------------------------------------- 1 | ! This file is part of dftd4. 2 | ! SPDX-Identifier: LGPL-3.0-or-later 3 | ! 4 | ! dftd4 is free software: you can redistribute it and/or modify it under 5 | ! the terms of the GNU Lesser General Public License as published by 6 | ! the Free Software Foundation, either version 3 of the License, or 7 | ! (at your option) any later version. 8 | ! 9 | ! dftd4 is distributed in the hope that it will be useful, 10 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | ! GNU Lesser General Public License for more details. 13 | ! 14 | ! You should have received a copy of the GNU Lesser General Public License 15 | ! along with dftd4. If not, see . 16 | 17 | module dftd4_data_en 18 | use mctc_env, only : wp 19 | use mctc_io_symbols, only : to_number 20 | implicit none 21 | private 22 | 23 | public :: get_electronegativity 24 | 25 | 26 | interface get_electronegativity 27 | module procedure :: get_electronegativity_num 28 | module procedure :: get_electronegativity_sym 29 | end interface get_electronegativity 30 | 31 | 32 | integer, parameter :: max_elem = 118 33 | 34 | !> Pauling electronegativities, used for the covalent coordination number. 35 | real(wp), parameter :: pauling_en(max_elem) = [ & 36 | & 2.20_wp,3.00_wp, & ! H,He 37 | & 0.98_wp,1.57_wp,2.04_wp,2.55_wp,3.04_wp,3.44_wp,3.98_wp,4.50_wp, & ! Li-Ne 38 | & 0.93_wp,1.31_wp,1.61_wp,1.90_wp,2.19_wp,2.58_wp,3.16_wp,3.50_wp, & ! Na-Ar 39 | & 0.82_wp,1.00_wp, & ! K,Ca 40 | & 1.36_wp,1.54_wp,1.63_wp,1.66_wp,1.55_wp, & ! Sc- 41 | & 1.83_wp,1.88_wp,1.91_wp,1.90_wp,1.65_wp, & ! -Zn 42 | & 1.81_wp,2.01_wp,2.18_wp,2.55_wp,2.96_wp,3.00_wp, & ! Ga-Kr 43 | & 0.82_wp,0.95_wp, & ! Rb,Sr 44 | & 1.22_wp,1.33_wp,1.60_wp,2.16_wp,1.90_wp, & ! Y- 45 | & 2.20_wp,2.28_wp,2.20_wp,1.93_wp,1.69_wp, & ! -Cd 46 | & 1.78_wp,1.96_wp,2.05_wp,2.10_wp,2.66_wp,2.60_wp, & ! In-Xe 47 | & 0.79_wp,0.89_wp, & ! Cs,Ba 48 | & 1.10_wp,1.12_wp,1.13_wp,1.14_wp,1.15_wp,1.17_wp,1.18_wp, & ! La-Eu 49 | & 1.20_wp,1.21_wp,1.22_wp,1.23_wp,1.24_wp,1.25_wp,1.26_wp, & ! Gd-Yb 50 | & 1.27_wp,1.30_wp,1.50_wp,2.36_wp,1.90_wp, & ! Lu- 51 | & 2.20_wp,2.20_wp,2.28_wp,2.54_wp,2.00_wp, & ! -Hg 52 | & 1.62_wp,2.33_wp,2.02_wp,2.00_wp,2.20_wp,2.20_wp, & ! Tl-Rn 53 | 54 | & 0.79_wp,0.90_wp, & ! Fr,Ra 55 | & 1.10_wp,1.30_wp,1.50_wp,1.38_wp,1.36_wp,1.28_wp,1.30_wp, & ! Ac-Am 56 | & 1.30_wp,1.30_wp,1.30_wp,1.30_wp,1.30_wp,1.30_wp,1.30_wp, & ! Cm-No 57 | & 1.30_wp, & ! Lr 58 | ! only dummies below 59 | & 1.50_wp,1.50_wp,1.50_wp,1.50_wp, & ! Rf-Bh 60 | & 1.50_wp,1.50_wp,1.50_wp,1.50_wp,1.50_wp, & ! Hs-Cn 61 | & 1.50_wp,1.50_wp,1.50_wp,1.50_wp,1.50_wp,1.50_wp ] ! Nh-Og 62 | 63 | contains 64 | 65 | 66 | !> Get electronegativity for a given element symbol 67 | elemental function get_electronegativity_sym(sym) result(en) 68 | !DEC$ ATTRIBUTES DLLEXPORT :: get_electronegativity_sym 69 | 70 | !> Element symbol 71 | character(len=*), intent(in) :: sym 72 | 73 | !> Electronegativity 74 | real(wp) :: en 75 | 76 | en = get_electronegativity(to_number(sym)) 77 | 78 | end function get_electronegativity_sym 79 | 80 | 81 | !> Get electronegativity for a given atomic number 82 | elemental function get_electronegativity_num(num) result(en) 83 | !DEC$ ATTRIBUTES DLLEXPORT :: get_electronegativity_num 84 | 85 | !> Atomic number 86 | integer, intent(in) :: num 87 | 88 | !> Electronegativity 89 | real(wp) :: en 90 | 91 | if (num > 0 .and. num <= size(pauling_en)) then 92 | en = pauling_en(num) 93 | else 94 | en = 0.0_wp 95 | end if 96 | 97 | end function get_electronegativity_num 98 | 99 | 100 | end module dftd4_data_en 101 | -------------------------------------------------------------------------------- /src/dftd4/data/hardness.f90: -------------------------------------------------------------------------------- 1 | ! This file is part of dftd4. 2 | ! SPDX-Identifier: LGPL-3.0-or-later 3 | ! 4 | ! dftd4 is free software: you can redistribute it and/or modify it under 5 | ! the terms of the GNU Lesser General Public License as published by 6 | ! the Free Software Foundation, either version 3 of the License, or 7 | ! (at your option) any later version. 8 | ! 9 | ! dftd4 is distributed in the hope that it will be useful, 10 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | ! GNU Lesser General Public License for more details. 13 | ! 14 | ! You should have received a copy of the GNU Lesser General Public License 15 | ! along with dftd4. If not, see . 16 | 17 | module dftd4_data_hardness 18 | use mctc_env, only : wp 19 | use mctc_io_symbols, only : to_number 20 | implicit none 21 | private 22 | 23 | public :: get_hardness 24 | 25 | 26 | interface get_hardness 27 | module procedure :: get_hardness_num 28 | module procedure :: get_hardness_sym 29 | end interface get_hardness 30 | 31 | 32 | integer, parameter :: max_elem = 118 33 | 34 | !> Element-specific chemical hardnesses for the charge scaling function used 35 | !> to extrapolate the C6 coefficients in DFT-D4. 36 | real(wp), parameter :: chemical_hardness(max_elem) = [ & 37 | & 0.47259288_wp, 0.92203391_wp, 0.17452888_wp, 0.25700733_wp, 0.33949086_wp, & 38 | & 0.42195412_wp, 0.50438193_wp, 0.58691863_wp, 0.66931351_wp, 0.75191607_wp, & 39 | & 0.17964105_wp, 0.22157276_wp, 0.26348578_wp, 0.30539645_wp, 0.34734014_wp, & 40 | & 0.38924725_wp, 0.43115670_wp, 0.47308269_wp, 0.17105469_wp, 0.20276244_wp, & 41 | & 0.21007322_wp, 0.21739647_wp, 0.22471039_wp, 0.23201501_wp, 0.23933969_wp, & 42 | & 0.24665638_wp, 0.25398255_wp, 0.26128863_wp, 0.26859476_wp, 0.27592565_wp, & 43 | & 0.30762999_wp, 0.33931580_wp, 0.37235985_wp, 0.40273549_wp, 0.43445776_wp, & 44 | & 0.46611708_wp, 0.15585079_wp, 0.18649324_wp, 0.19356210_wp, 0.20063311_wp, & 45 | & 0.20770522_wp, 0.21477254_wp, 0.22184614_wp, 0.22891872_wp, 0.23598621_wp, & 46 | & 0.24305612_wp, 0.25013018_wp, 0.25719937_wp, 0.28784780_wp, 0.31848673_wp, & 47 | & 0.34912431_wp, 0.37976593_wp, 0.41040808_wp, 0.44105777_wp, 0.05019332_wp, & 48 | & 0.06762570_wp, 0.08504445_wp, 0.10247736_wp, 0.11991105_wp, 0.13732772_wp, & 49 | & 0.15476297_wp, 0.17218265_wp, 0.18961288_wp, 0.20704760_wp, 0.22446752_wp, & 50 | & 0.24189645_wp, 0.25932503_wp, 0.27676094_wp, 0.29418231_wp, 0.31159587_wp, & 51 | & 0.32902274_wp, 0.34592298_wp, 0.36388048_wp, 0.38130586_wp, 0.39877476_wp, & 52 | & 0.41614298_wp, 0.43364510_wp, 0.45104014_wp, 0.46848986_wp, 0.48584550_wp, & 53 | & 0.12526730_wp, 0.14268677_wp, 0.16011615_wp, 0.17755889_wp, 0.19497557_wp, & ! Tl-At 54 | & 0.21240778_wp, 0.07263525_wp, 0.09422158_wp, 0.09920295_wp, 0.10418621_wp, & ! Rn-Th 55 | & 0.14235633_wp, 0.16394294_wp, 0.18551941_wp, 0.22370139_wp, 0.25110000_wp, & ! Pa-Am 56 | & 0.25030000_wp, 0.28840000_wp, 0.31000000_wp, 0.33160000_wp, 0.35320000_wp, & ! Cm-Fm 57 | & 0.36820000_wp, 0.39630000_wp, 0.40140000_wp, 0.00000000_wp, 0.00000000_wp, & ! Md-Db 58 | & 0.00000000_wp, 0.00000000_wp, 0.00000000_wp, 0.00000000_wp, 0.00000000_wp, & ! Sg-Ds 59 | & 0.00000000_wp, 0.00000000_wp, 0.00000000_wp, 0.00000000_wp, 0.00000000_wp, & ! Rg-Mc 60 | & 0.00000000_wp, 0.00000000_wp, 0.00000000_wp] ! Lv,Ts,Og 61 | 62 | contains 63 | 64 | 65 | !> Get chemical hardness for a given element symbol 66 | elemental function get_hardness_sym(sym) result(eta) 67 | 68 | !> Element symbol 69 | character(len=*), intent(in) :: sym 70 | 71 | !> Chemical hardness 72 | real(wp) :: eta 73 | 74 | eta = get_hardness(to_number(sym)) 75 | 76 | end function get_hardness_sym 77 | 78 | 79 | !> Get chemical hardness for a given atomic number 80 | elemental function get_hardness_num(num) result(eta) 81 | 82 | !> Atomic number 83 | integer, intent(in) :: num 84 | 85 | !> Chemical hardness 86 | real(wp) :: eta 87 | 88 | if (num > 0 .and. num <= size(chemical_hardness)) then 89 | eta = chemical_hardness(num) 90 | else 91 | eta = 0.0_wp 92 | end if 93 | 94 | end function get_hardness_num 95 | 96 | 97 | end module dftd4_data_hardness 98 | -------------------------------------------------------------------------------- /src/dftd4/data/meson.build: -------------------------------------------------------------------------------- 1 | # This file is part of dftd4. 2 | # SPDX-Identifier: LGPL-3.0-or-later 3 | # 4 | # dftd4 is free software: you can redistribute it and/or modify it under 5 | # the terms of the Lesser GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # dftd4 is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # Lesser GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the Lesser GNU General Public License 15 | # along with dftd4. If not, see . 16 | 17 | srcs += files( 18 | 'covrad.f90', 19 | 'en.f90', 20 | 'hardness.f90', 21 | 'r4r2.f90', 22 | 'wfpair.f90', 23 | 'zeff.f90', 24 | ) 25 | -------------------------------------------------------------------------------- /src/dftd4/data/r4r2.f90: -------------------------------------------------------------------------------- 1 | ! This file is part of dftd4. 2 | ! SPDX-Identifier: LGPL-3.0-or-later 3 | ! 4 | ! dftd4 is free software: you can redistribute it and/or modify it under 5 | ! the terms of the Lesser GNU General Public License as published by 6 | ! the Free Software Foundation, either version 3 of the License, or 7 | ! (at your option) any later version. 8 | ! 9 | ! dftd4 is distributed in the hope that it will be useful, 10 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | ! Lesser GNU General Public License for more details. 13 | ! 14 | ! You should have received a copy of the Lesser GNU General Public License 15 | ! along with dftd4. If not, see . 16 | 17 | module dftd4_data_r4r2 18 | use mctc_env, only : wp 19 | use mctc_io_convert, only : aatoau 20 | use mctc_io_symbols, only : to_number 21 | implicit none 22 | private 23 | 24 | public :: get_r4r2_val 25 | 26 | 27 | !> Get r4/r2 expectation value 28 | interface get_r4r2_val 29 | module procedure :: get_r4r2_val_num 30 | module procedure :: get_r4r2_val_sym 31 | end interface get_r4r2_val 32 | 33 | 34 | integer, parameter :: max_elem = 118 35 | 36 | ! PBE0/def2-QZVP atomic values calculated by S. Grimme in Gaussian (2010) 37 | ! rare gases recalculated by J. Mewes with PBE0/aug-cc-pVQZ in Dirac (2018) 38 | ! He: 3.4698 -> 3.5544, Ne: 3.1036 -> 3.7943, Ar: 5.6004 -> 5.6638, 39 | ! Kr: 6.1971 -> 6.2312, Xe: 7.5152 -> 8.8367 40 | ! not replaced but recalculated (PBE0/cc-pVQZ) were 41 | ! H: 8.0589 ->10.9359, Li:29.0974 ->39.7226, Be:14.8517 ->17.7460 42 | ! also new super heavies Cn,Nh,Fl,Lv,Og 43 | ! Am-Rg calculated at 4c-PBE/Dyall-AE4Z (Dirac 2022) 44 | real(wp), parameter :: r4_over_r2(max_elem) = [ & 45 | & 8.0589_wp, 3.4698_wp, & ! H,He 46 | & 29.0974_wp,14.8517_wp,11.8799_wp, 7.8715_wp, 5.5588_wp, 4.7566_wp, 3.8025_wp, 3.1036_wp, & ! Li-Ne 47 | & 26.1552_wp,17.2304_wp,17.7210_wp,12.7442_wp, 9.5361_wp, 8.1652_wp, 6.7463_wp, 5.6004_wp, & ! Na-Ar 48 | & 29.2012_wp,22.3934_wp, & ! K,Ca 49 | & 19.0598_wp,16.8590_wp,15.4023_wp,12.5589_wp,13.4788_wp, & ! Sc- 50 | & 12.2309_wp,11.2809_wp,10.5569_wp,10.1428_wp, 9.4907_wp, & ! -Zn 51 | & 13.4606_wp,10.8544_wp, 8.9386_wp, 8.1350_wp, 7.1251_wp, 6.1971_wp, & ! Ga-Kr 52 | & 30.0162_wp,24.4103_wp, & ! Rb,Sr 53 | & 20.3537_wp,17.4780_wp,13.5528_wp,11.8451_wp,11.0355_wp, & ! Y- 54 | & 10.1997_wp, 9.5414_wp, 9.0061_wp, 8.6417_wp, 8.9975_wp, & ! -Cd 55 | & 14.0834_wp,11.8333_wp,10.0179_wp, 9.3844_wp, 8.4110_wp, 7.5152_wp, & ! In-Xe 56 | & 32.7622_wp,27.5708_wp, & ! Cs,Ba 57 | & 23.1671_wp,21.6003_wp,20.9615_wp,20.4562_wp,20.1010_wp,19.7475_wp,19.4828_wp, & ! La-Eu 58 | & 15.6013_wp,19.2362_wp,17.4717_wp,17.8321_wp,17.4237_wp,17.1954_wp,17.1631_wp, & ! Gd-Yb 59 | & 14.5716_wp,15.8758_wp,13.8989_wp,12.4834_wp,11.4421_wp, & ! Lu- 60 | & 10.2671_wp, 8.3549_wp, 7.8496_wp, 7.3278_wp, 7.4820_wp, & ! -Hg 61 | & 13.5124_wp,11.6554_wp,10.0959_wp, 9.7340_wp, 8.8584_wp, 8.0125_wp, & ! Tl-Rn 62 | & 29.8135_wp,26.3157_wp, & ! Fr,Ra 63 | & 19.1885_wp,15.8542_wp,16.1305_wp,15.6161_wp,15.1226_wp,16.1576_wp,14.6510_wp, & ! Ac-Am 64 | & 14.7178_wp,13.9108_wp,13.5623_wp,13.2326_wp,12.9189_wp,12.6133_wp,12.3142_wp, & ! Cm-No 65 | & 14.8326_wp,12.3771_wp,10.6378_wp, 9.3638_wp, 8.2297_wp, & ! Lr- 66 | & 7.5667_wp, 6.9456_wp, 6.3946_wp, 5.9159_wp, 5.4929_wp, & ! -Cn 67 | & 6.7286_wp, 6.5144_wp,10.9169_wp,10.3600_wp, 9.4723_wp, 8.6641_wp ] ! Nh-Og 68 | 69 | integer :: idum 70 | real(wp), parameter :: sqrt_z_r4_over_r2(max_elem) = & 71 | & sqrt(0.5_wp*(r4_over_r2*[(sqrt(real(idum,wp)),idum=1,max_elem)])) 72 | 73 | 74 | contains 75 | 76 | 77 | !> Get r4/r2 expectation value for a given element symbol 78 | elemental function get_r4r2_val_sym(sym) result(rad) 79 | 80 | !> Element symbol 81 | character(len=*), intent(in) :: sym 82 | 83 | !> r4/r2 expectation value 84 | real(wp) :: rad 85 | 86 | rad = get_r4r2_val(to_number(sym)) 87 | 88 | end function get_r4r2_val_sym 89 | 90 | 91 | !> Get r4/r2 expectation value for a given atomic number 92 | elemental function get_r4r2_val_num(num) result(rad) 93 | 94 | !> Atomic number 95 | integer, intent(in) :: num 96 | 97 | !> r4/r2 expectation value 98 | real(wp) :: rad 99 | 100 | if (num > 0 .and. num <= size(sqrt_z_r4_over_r2)) then 101 | rad = sqrt_z_r4_over_r2(num) 102 | else 103 | rad = 0.0_wp 104 | end if 105 | 106 | end function get_r4r2_val_num 107 | 108 | 109 | end module dftd4_data_r4r2 110 | -------------------------------------------------------------------------------- /src/dftd4/data/zeff.f90: -------------------------------------------------------------------------------- 1 | ! This file is part of dftd4. 2 | ! SPDX-Identifier: LGPL-3.0-or-later 3 | ! 4 | ! dftd4 is free software: you can redistribute it and/or modify it under 5 | ! the terms of the GNU Lesser General Public License as published by 6 | ! the Free Software Foundation, either version 3 of the License, or 7 | ! (at your option) any later version. 8 | ! 9 | ! dftd4 is distributed in the hope that it will be useful, 10 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | ! GNU Lesser General Public License for more details. 13 | ! 14 | ! You should have received a copy of the GNU Lesser General Public License 15 | ! along with dftd4. If not, see . 16 | 17 | module dftd4_data_zeff 18 | use mctc_env, only : wp 19 | use mctc_io_symbols, only : to_number 20 | implicit none 21 | private 22 | 23 | public :: get_effective_charge 24 | 25 | 26 | interface get_effective_charge 27 | module procedure :: get_effective_charge_num 28 | module procedure :: get_effective_charge_sym 29 | end interface get_effective_charge 30 | 31 | 32 | integer, parameter :: max_elem = 118 33 | 34 | 35 | !> Effective nuclear charges from the def2-ECPs used for calculating the reference 36 | !> polarizibilities for DFT-D4. 37 | real(wp), parameter :: effective_nuclear_charge(max_elem) = [ & 38 | & 1, 2, & ! H-He 39 | & 3, 4, 5, 6, 7, 8, 9,10, & ! Li-Ne 40 | & 11,12, 13,14,15,16,17,18, & ! Na-Ar 41 | & 19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36, & ! K-Kr 42 | & 9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26, & ! Rb-Xe 43 | & 9,10,11,30,31,32,33,34,35,36,37,38,39,40,41,42,43, & ! Cs-Lu 44 | & 12,13,14,15,16,17,18,19,20,21,22,23,24,25,26, & ! Hf-Rn 45 | ! just copy & paste from above 46 | & 9,10,11,30,31,32,33,34,35,36,37,38,39,40,41,42,43, & ! Fr-Lr 47 | & 12,13,14,15,16,17,18,19,20,21,22,23,24,25,26] ! Rf-Og 48 | 49 | contains 50 | 51 | 52 | !> Get effective nuclear charge for a given element symbol 53 | elemental function get_effective_charge_sym(sym) result(zeff) 54 | 55 | !> Element symbol 56 | character(len=*), intent(in) :: sym 57 | 58 | !> Effective nuclear charge 59 | real(wp) :: zeff 60 | 61 | zeff = get_effective_charge(to_number(sym)) 62 | 63 | end function get_effective_charge_sym 64 | 65 | 66 | !> Get effective nuclear charge for a given atomic number 67 | elemental function get_effective_charge_num(num) result(zeff) 68 | 69 | !> Atomic number 70 | integer, intent(in) :: num 71 | 72 | !> Effective nuclear charge 73 | real(wp) :: zeff 74 | 75 | if (num > 0 .and. num <= size(effective_nuclear_charge)) then 76 | zeff = effective_nuclear_charge(num) 77 | else 78 | zeff = 0.0_wp 79 | end if 80 | 81 | end function get_effective_charge_num 82 | 83 | 84 | end module dftd4_data_zeff 85 | -------------------------------------------------------------------------------- /src/dftd4/meson.build: -------------------------------------------------------------------------------- 1 | # This file is part of dftd4. 2 | # SPDX-Identifier: LGPL-3.0-or-later 3 | # 4 | # dftd4 is free software: you can redistribute it and/or modify it under 5 | # the terms of the Lesser GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # dftd4 is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # Lesser GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the Lesser GNU General Public License 15 | # along with dftd4. If not, see . 16 | 17 | subdir('damping') 18 | subdir('data') 19 | subdir('model') 20 | 21 | srcs += files( 22 | 'blas.F90', 23 | 'charge.f90', 24 | 'cutoff.f90', 25 | 'damping.f90', 26 | 'data.f90', 27 | 'disp.f90', 28 | 'model.f90', 29 | 'ncoord.f90', 30 | 'numdiff.f90', 31 | 'output.f90', 32 | 'param.f90', 33 | 'reference.f90', 34 | 'utils.f90', 35 | 'version.f90', 36 | ) 37 | if get_option('api') or get_option('python') 38 | srcs += files('api.f90') 39 | endif 40 | if get_option('api_v2') 41 | srcs += files('compat.f90') 42 | endif 43 | -------------------------------------------------------------------------------- /src/dftd4/model.f90: -------------------------------------------------------------------------------- 1 | ! This file is part of dftd4. 2 | ! SPDX-Identifier: LGPL-3.0-or-later 3 | ! 4 | ! dftd4 is free software: you can redistribute it and/or modify it under 5 | ! the terms of the Lesser GNU General Public License as published by 6 | ! the Free Software Foundation, either version 3 of the License, or 7 | ! (at your option) any later version. 8 | ! 9 | ! dftd4 is distributed in the hope that it will be useful, 10 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | ! Lesser GNU General Public License for more details. 13 | ! 14 | ! You should have received a copy of the Lesser GNU General Public License 15 | ! along with dftd4. If not, see . 16 | 17 | !> Re-export of all dispersion models 18 | module dftd4_model 19 | use dftd4_model_type, only : dispersion_model, d4_ref 20 | use dftd4_model_d4, only : d4_model, new_d4_model 21 | use dftd4_model_d4s, only : d4s_model, new_d4s_model 22 | implicit none 23 | private 24 | 25 | public :: dispersion_model, d4_ref 26 | public :: d4_model, new_d4_model 27 | public :: d4s_model, new_d4s_model 28 | 29 | end module dftd4_model 30 | -------------------------------------------------------------------------------- /src/dftd4/model/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # This file is part of dftd4. 2 | # SPDX-Identifier: LGPL-3.0-or-later 3 | # 4 | # dftd4 is free software: you can redistribute it and/or modify it under 5 | # the terms of the GNU Lesser General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # dftd4 is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU Lesser General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU Lesser General Public License 15 | # along with dftd4. If not, see . 16 | 17 | set(dir "${CMAKE_CURRENT_SOURCE_DIR}") 18 | 19 | list( 20 | APPEND srcs 21 | "${dir}/d4.f90" 22 | "${dir}/d4s.f90" 23 | "${dir}/type.f90" 24 | "${dir}/utils.f90" 25 | ) 26 | 27 | set(srcs "${srcs}" PARENT_SCOPE) 28 | -------------------------------------------------------------------------------- /src/dftd4/model/meson.build: -------------------------------------------------------------------------------- 1 | # This file is part of dftd4. 2 | # SPDX-Identifier: LGPL-3.0-or-later 3 | # 4 | # dftd4 is free software: you can redistribute it and/or modify it under 5 | # the terms of the Lesser GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # dftd4 is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # Lesser GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the Lesser GNU General Public License 15 | # along with dftd4. If not, see . 16 | 17 | srcs += files( 18 | 'd4.f90', 19 | 'd4s.f90', 20 | 'type.f90', 21 | 'utils.f90', 22 | ) 23 | -------------------------------------------------------------------------------- /src/dftd4/model/utils.f90: -------------------------------------------------------------------------------- 1 | ! This file is part of dftd4. 2 | ! SPDX-Identifier: LGPL-3.0-or-later 3 | ! 4 | ! dftd4 is free software: you can redistribute it and/or modify it under 5 | ! the terms of the Lesser GNU General Public License as published by 6 | ! the Free Software Foundation, either version 3 of the License, or 7 | ! (at your option) any later version. 8 | ! 9 | ! dftd4 is distributed in the hope that it will be useful, 10 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | ! Lesser GNU General Public License for more details. 13 | ! 14 | ! You should have received a copy of the Lesser GNU General Public License 15 | ! along with dftd4. If not, see . 16 | 17 | !> Utility functions for the dispersion models 18 | module dftd4_model_utils 19 | use ieee_arithmetic, only : ieee_is_nan 20 | use mctc_env, only : wp 21 | implicit none 22 | 23 | public :: is_exceptional, weight_cn, zeta, dzeta, trapzd 24 | 25 | contains 26 | 27 | 28 | !> Check whether we are dealing with an exceptional value, NaN or Inf 29 | elemental function is_exceptional(val) 30 | real(wp), intent(in) :: val 31 | logical :: is_exceptional 32 | is_exceptional = ieee_is_nan(val) .or. abs(val) > huge(val) 33 | end function is_exceptional 34 | 35 | 36 | elemental function weight_cn(wf,cn,cnref) result(cngw) 37 | real(wp),intent(in) :: wf, cn, cnref 38 | real(wp) :: cngw 39 | intrinsic :: exp 40 | cngw = exp ( -wf * ( cn - cnref )**2 ) 41 | end function weight_cn 42 | 43 | !> charge scaling function 44 | elemental function zeta(a, c, qref, qmod) 45 | real(wp), intent(in) :: a 46 | real(wp), intent(in) :: c 47 | real(wp), intent(in) :: qref 48 | real(wp), intent(in) :: qmod 49 | real(wp) :: zeta 50 | 51 | intrinsic :: exp 52 | 53 | if (qmod < 0.0_wp) then 54 | zeta = exp( a ) 55 | else 56 | zeta = exp( a * ( 1.0_wp - exp( c * ( 1.0_wp - qref/qmod ) ) ) ) 57 | endif 58 | 59 | end function zeta 60 | 61 | !> derivative of charge scaling function w.r.t. charge 62 | elemental function dzeta(a, c, qref, qmod) 63 | real(wp), intent(in) :: a 64 | real(wp), intent(in) :: c 65 | real(wp), intent(in) :: qref 66 | real(wp), intent(in) :: qmod 67 | real(wp) :: dzeta 68 | 69 | intrinsic :: exp 70 | 71 | if (qmod < 0.0_wp) then 72 | dzeta = 0.0_wp 73 | else 74 | dzeta = - a * c * exp( c * ( 1.0_wp - qref/qmod ) ) & 75 | & * zeta(a,c,qref,qmod) * qref / ( qmod**2 ) 76 | endif 77 | 78 | end function dzeta 79 | 80 | !> numerical Casimir--Polder integration 81 | pure function trapzd(pol) 82 | real(wp), intent(in) :: pol(23) 83 | real(wp) :: trapzd 84 | 85 | real(wp), parameter :: freq(23) = [ & 86 | & 0.000001_wp, 0.050000_wp, 0.100000_wp, & 87 | & 0.200000_wp, 0.300000_wp, 0.400000_wp, & 88 | & 0.500000_wp, 0.600000_wp, 0.700000_wp, & 89 | & 0.800000_wp, 0.900000_wp, 1.000000_wp, & 90 | & 1.200000_wp, 1.400000_wp, 1.600000_wp, & 91 | & 1.800000_wp, 2.000000_wp, 2.500000_wp, & 92 | & 3.000000_wp, 4.000000_wp, 5.000000_wp, & 93 | & 7.500000_wp, 10.00000_wp] 94 | real(wp), parameter :: weights(23) = 0.5_wp * [ & 95 | & ( freq (2) - freq (1) ), & 96 | & ( freq (2) - freq (1) ) + ( freq (3) - freq (2) ), & 97 | & ( freq (3) - freq (2) ) + ( freq (4) - freq (3) ), & 98 | & ( freq (4) - freq (3) ) + ( freq (5) - freq (4) ), & 99 | & ( freq (5) - freq (4) ) + ( freq (6) - freq (5) ), & 100 | & ( freq (6) - freq (5) ) + ( freq (7) - freq (6) ), & 101 | & ( freq (7) - freq (6) ) + ( freq (8) - freq (7) ), & 102 | & ( freq (8) - freq (7) ) + ( freq (9) - freq (8) ), & 103 | & ( freq (9) - freq (8) ) + ( freq(10) - freq (9) ), & 104 | & ( freq(10) - freq (9) ) + ( freq(11) - freq(10) ), & 105 | & ( freq(11) - freq(10) ) + ( freq(12) - freq(11) ), & 106 | & ( freq(12) - freq(11) ) + ( freq(13) - freq(12) ), & 107 | & ( freq(13) - freq(12) ) + ( freq(14) - freq(13) ), & 108 | & ( freq(14) - freq(13) ) + ( freq(15) - freq(14) ), & 109 | & ( freq(15) - freq(14) ) + ( freq(16) - freq(15) ), & 110 | & ( freq(16) - freq(15) ) + ( freq(17) - freq(16) ), & 111 | & ( freq(17) - freq(16) ) + ( freq(18) - freq(17) ), & 112 | & ( freq(18) - freq(17) ) + ( freq(19) - freq(18) ), & 113 | & ( freq(19) - freq(18) ) + ( freq(20) - freq(19) ), & 114 | & ( freq(20) - freq(19) ) + ( freq(21) - freq(20) ), & 115 | & ( freq(21) - freq(20) ) + ( freq(22) - freq(21) ), & 116 | & ( freq(22) - freq(21) ) + ( freq(23) - freq(22) ), & 117 | & ( freq(23) - freq(22) ) ] 118 | 119 | trapzd = sum(pol*weights) 120 | 121 | end function trapzd 122 | 123 | 124 | end module dftd4_model_utils 125 | -------------------------------------------------------------------------------- /src/dftd4/ncoord.f90: -------------------------------------------------------------------------------- 1 | ! This file is part of dftd4. 2 | ! SPDX-Identifier: LGPL-3.0-or-later 3 | ! 4 | ! dftd4 is free software: you can redistribute it and/or modify it under 5 | ! the terms of the Lesser GNU General Public License as published by 6 | ! the Free Software Foundation, either version 3 of the License, or 7 | ! (at your option) any later version. 8 | ! 9 | ! dftd4 is distributed in the hope that it will be useful, 10 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | ! Lesser GNU General Public License for more details. 13 | ! 14 | ! You should have received a copy of the Lesser GNU General Public License 15 | ! along with dftd4. If not, see . 16 | 17 | module dftd4_ncoord 18 | use, intrinsic :: iso_fortran_env, only : error_unit 19 | use mctc_env, only : error_type, wp 20 | use mctc_io, only : structure_type 21 | use mctc_ncoord, only : ncoord_type, new_ncoord, cn_count 22 | implicit none 23 | private 24 | 25 | public :: get_coordination_number, add_coordination_number_derivs 26 | 27 | 28 | !> Steepness of counting function 29 | real(wp), parameter :: default_kcn = 7.5_wp 30 | 31 | 32 | contains 33 | 34 | 35 | !> Geometric fractional coordination number, supports error function counting. 36 | subroutine get_coordination_number(mol, trans, cutoff, rcov, en, cn, dcndr, dcndL) 37 | !DEC$ ATTRIBUTES DLLEXPORT :: get_coordination_number 38 | 39 | !> Molecular structure data 40 | type(structure_type), intent(in) :: mol 41 | 42 | !> Lattice points 43 | real(wp), intent(in) :: trans(:, :) 44 | 45 | !> Real space cutoff 46 | real(wp), intent(in) :: cutoff 47 | 48 | !> Covalent radius 49 | real(wp), intent(in) :: rcov(:) 50 | 51 | !> Electronegativity 52 | real(wp), intent(in) :: en(:) 53 | 54 | !> Error function coordination number. 55 | real(wp), intent(out) :: cn(:) 56 | 57 | !> Derivative of the CN with respect to the Cartesian coordinates. 58 | real(wp), intent(out), optional :: dcndr(:, :, :) 59 | 60 | !> Derivative of the CN with respect to strain deformations. 61 | real(wp), intent(out), optional :: dcndL(:, :, :) 62 | 63 | class(ncoord_type), allocatable :: ncoord 64 | type(error_type), allocatable :: error 65 | 66 | call new_ncoord(ncoord, mol, cn_count%dftd4, & 67 | & kcn=default_kcn, cutoff=cutoff, rcov=rcov, en=en, error=error) 68 | if(allocated(error)) then 69 | write(error_unit, '("[Error]:", 1x, a)') error%message 70 | error stop 71 | end if 72 | 73 | call ncoord%get_coordination_number(mol, trans, cn, dcndr, dcndL) 74 | 75 | end subroutine get_coordination_number 76 | 77 | 78 | subroutine add_coordination_number_derivs(mol, trans, cutoff, rcov, en, dEdcn, gradient, sigma) 79 | 80 | !> Molecular structure data 81 | type(structure_type), intent(in) :: mol 82 | 83 | !> Lattice points 84 | real(wp), intent(in) :: trans(:, :) 85 | 86 | !> Real space cutoff 87 | real(wp), intent(in) :: cutoff 88 | 89 | !> Covalent radius 90 | real(wp), intent(in) :: rcov(:) 91 | 92 | !> Electronegativity 93 | real(wp), intent(in) :: en(:) 94 | 95 | !> Derivative of expression with respect to the coordination number 96 | real(wp), intent(in) :: dEdcn(:) 97 | 98 | !> Derivative of the CN with respect to the Cartesian coordinates 99 | real(wp), intent(inout) :: gradient(:, :) 100 | 101 | !> Derivative of the CN with respect to strain deformations 102 | real(wp), intent(inout) :: sigma(:, :) 103 | 104 | 105 | class(ncoord_type), allocatable :: ncoord 106 | type(error_type), allocatable :: error 107 | 108 | call new_ncoord(ncoord, mol, cn_count%dftd4, & 109 | & kcn=default_kcn, cutoff=cutoff, rcov=rcov, en=en, error=error) 110 | if(allocated(error)) then 111 | write(error_unit, '("[Error]:", 1x, a)') error%message 112 | error stop 113 | end if 114 | 115 | call ncoord%add_coordination_number_derivs(mol, trans, dEdcn, gradient, sigma) 116 | 117 | end subroutine add_coordination_number_derivs 118 | 119 | 120 | end module dftd4_ncoord -------------------------------------------------------------------------------- /src/dftd4/numdiff.f90: -------------------------------------------------------------------------------- 1 | ! This file is part of dftd4. 2 | ! SPDX-Identifier: LGPL-3.0-or-later 3 | ! 4 | ! dftd4 is free software: you can redistribute it and/or modify it under 5 | ! the terms of the Lesser GNU General Public License as published by 6 | ! the Free Software Foundation, either version 3 of the License, or 7 | ! (at your option) any later version. 8 | ! 9 | ! dftd4 is distributed in the hope that it will be useful, 10 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | ! Lesser GNU General Public License for more details. 13 | ! 14 | ! You should have received a copy of the Lesser GNU General Public License 15 | ! along with dftd4. If not, see . 16 | 17 | !> Numerical differentation of DFT-D4 model 18 | module dftd4_numdiff 19 | use dftd4_cutoff, only : realspace_cutoff 20 | use dftd4_damping, only : damping_param 21 | use dftd4_disp, only : get_dispersion 22 | use dftd4_model, only : dispersion_model 23 | use mctc_env, only : wp 24 | use mctc_io, only : structure_type 25 | implicit none 26 | private 27 | 28 | public :: get_dispersion_hessian 29 | 30 | 31 | contains 32 | 33 | 34 | !> Evaluate hessian matrix by numerical differention 35 | subroutine get_dispersion_hessian(mol, disp, param, cutoff, hessian) 36 | !DEC$ ATTRIBUTES DLLEXPORT :: get_dispersion_hessian 37 | 38 | !> Molecular structure data 39 | class(structure_type), intent(in) :: mol 40 | 41 | !> Dispersion model 42 | class(dispersion_model), intent(in) :: disp 43 | 44 | !> Damping parameters 45 | class(damping_param), intent(in) :: param 46 | 47 | !> Realspace cutoffs 48 | type(realspace_cutoff), intent(in) :: cutoff 49 | 50 | !> Dispersion hessian 51 | real(wp), intent(out) :: hessian(:, :, :, :) 52 | 53 | integer :: iat, ix 54 | real(wp), parameter :: step = 1.0e-4_wp 55 | type(structure_type) :: displ 56 | real(wp) :: el, er 57 | real(wp), allocatable :: gl(:, :), gr(:, :), sl(:, :), sr(:, :) 58 | 59 | hessian(:, :, :, :) = 0.0_wp 60 | !$omp parallel default(none) & 61 | !$omp private(iat, ix, displ, er, el, gr, gl, sr, sl) & 62 | !$omp shared(mol, disp, param, cutoff, hessian) 63 | displ = mol 64 | allocate(gl(3, mol%nat), gr(3, mol%nat), sl(3, 3), sr(3, 3)) 65 | !$omp do schedule(dynamic) collapse(2) 66 | do iat = 1, mol%nat 67 | do ix = 1, 3 68 | displ%xyz(ix, iat) = mol%xyz(ix, iat) + step 69 | call get_dispersion(displ, disp, param, cutoff, el, gl, sl) 70 | 71 | displ%xyz(ix, iat) = mol%xyz(ix, iat) - step 72 | call get_dispersion(displ, disp, param, cutoff, er, gr, sr) 73 | 74 | displ%xyz(ix, iat) = mol%xyz(ix, iat) 75 | hessian(:, :, ix, iat) = (gl - gr) / (2 * step) 76 | end do 77 | end do 78 | !$omp end parallel 79 | end subroutine get_dispersion_hessian 80 | 81 | end module dftd4_numdiff 82 | -------------------------------------------------------------------------------- /src/dftd4/utils.f90: -------------------------------------------------------------------------------- 1 | ! This file is part of dftd4. 2 | ! SPDX-Identifier: LGPL-3.0-or-later 3 | ! 4 | ! dftd4 is free software: you can redistribute it and/or modify it under 5 | ! the terms of the Lesser GNU General Public License as published by 6 | ! the Free Software Foundation, either version 3 of the License, or 7 | ! (at your option) any later version. 8 | ! 9 | ! dftd4 is distributed in the hope that it will be useful, 10 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | ! Lesser GNU General Public License for more details. 13 | ! 14 | ! You should have received a copy of the Lesser GNU General Public License 15 | ! along with dftd4. If not, see . 16 | 17 | module dftd4_utils 18 | use mctc_env, only : wp 19 | use mctc_io_math, only : matinv_3x3 20 | implicit none 21 | 22 | public :: lowercase, wrap_to_central_cell 23 | 24 | 25 | contains 26 | 27 | 28 | subroutine wrap_to_central_cell(xyz, lattice, periodic) 29 | !DEC$ ATTRIBUTES DLLEXPORT :: wrap_to_central_cell 30 | real(wp), intent(inout) :: xyz(:, :) 31 | real(wp), intent(in) :: lattice(:, :) 32 | logical, intent(in) :: periodic(:) 33 | real(wp) :: invlat(3, 3), vec(3) 34 | integer :: iat, idir 35 | 36 | if (.not.any(periodic)) return 37 | 38 | invlat = matinv_3x3(lattice) 39 | do iat = 1, size(xyz, 2) 40 | vec(:) = matmul(invlat, xyz(:, iat)) 41 | vec(:) = shift_back_abc(vec) 42 | xyz(:, iat) = matmul(lattice, vec) 43 | end do 44 | 45 | end subroutine wrap_to_central_cell 46 | 47 | 48 | elemental function shift_back_abc(in) result(out) 49 | !> fractional coordinate in (-∞,+∞) 50 | real(wp),intent(in) :: in 51 | !> fractional coordinate in [0,1) 52 | real(wp) :: out 53 | real(wp),parameter :: p_pbc_eps = 1.0e-14_wp 54 | out = in 55 | if(in < (0.0_wp - p_pbc_eps)) & 56 | out = in + real(ceiling(-in),wp) 57 | if(in > (1.0_wp + p_pbc_eps)) & 58 | out = in - real(floor ( in),wp) 59 | if (abs(in - 1.0_wp) < p_pbc_eps) & 60 | out = in - 1.0_wp 61 | end function shift_back_abc 62 | 63 | 64 | !> Convert string to lower case 65 | pure function lowercase(str) result(lcstr) 66 | character(len=*), intent(in) :: str 67 | character(len=len_trim(str)) :: lcstr 68 | integer :: ilen, ioffset, iquote, i, iav, iqc 69 | 70 | ilen=len_trim(str) 71 | ioffset=iachar('A')-iachar('a') 72 | iquote=0 73 | lcstr=str 74 | do i=1, ilen 75 | iav=iachar(str(i:i)) 76 | if(iquote==0 .and. (iav==34 .or.iav==39)) then 77 | iquote=1 78 | iqc=iav 79 | cycle 80 | endif 81 | if(iquote==1 .and. iav==iqc) then 82 | iquote=0 83 | cycle 84 | endif 85 | if (iquote==1) cycle 86 | if(iav >= iachar('A') .and. iav <= iachar('Z')) then 87 | lcstr(i:i)=achar(iav-ioffset) 88 | else 89 | lcstr(i:i)=str(i:i) 90 | endif 91 | enddo 92 | 93 | end function lowercase 94 | 95 | 96 | end module dftd4_utils 97 | -------------------------------------------------------------------------------- /src/dftd4/version.f90: -------------------------------------------------------------------------------- 1 | ! This file is part of dftd4. 2 | ! SPDX-Identifier: LGPL-3.0-or-later 3 | ! 4 | ! dftd4 is free software: you can redistribute it and/or modify it under 5 | ! the terms of the Lesser GNU General Public License as published by 6 | ! the Free Software Foundation, either version 3 of the License, or 7 | ! (at your option) any later version. 8 | ! 9 | ! dftd4 is distributed in the hope that it will be useful, 10 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | ! Lesser GNU General Public License for more details. 13 | ! 14 | ! You should have received a copy of the Lesser GNU General Public License 15 | ! along with dftd4. If not, see . 16 | 17 | !> Versioning information on this library. 18 | module dftd4_version 19 | implicit none 20 | private 21 | 22 | public :: dftd4_version_string, dftd4_version_compact 23 | public :: get_dftd4_version 24 | 25 | 26 | !> String representation of the dftd4 version 27 | character(len=*), parameter :: dftd4_version_string = "3.7.0" 28 | 29 | !> Numeric representation of the dftd4 version 30 | integer, parameter :: dftd4_version_compact(3) = [3, 7, 0] 31 | 32 | 33 | contains 34 | 35 | 36 | !> Getter function to retrieve dftd4 version 37 | subroutine get_dftd4_version(major, minor, patch, string) 38 | !DEC$ ATTRIBUTES DLLEXPORT :: get_dftd4_version 39 | 40 | !> Major version number of the dftd4 version 41 | integer, intent(out), optional :: major 42 | 43 | !> Minor version number of the dftd4 version 44 | integer, intent(out), optional :: minor 45 | 46 | !> Patch version number of the dftd4 version 47 | integer, intent(out), optional :: patch 48 | 49 | !> String representation of the dftd4 version 50 | character(len=:), allocatable, intent(out), optional :: string 51 | 52 | if (present(major)) then 53 | major = dftd4_version_compact(1) 54 | end if 55 | if (present(minor)) then 56 | minor = dftd4_version_compact(2) 57 | end if 58 | if (present(patch)) then 59 | patch = dftd4_version_compact(3) 60 | end if 61 | if (present(string)) then 62 | string = dftd4_version_string 63 | end if 64 | 65 | end subroutine get_dftd4_version 66 | 67 | 68 | end module dftd4_version 69 | -------------------------------------------------------------------------------- /src/meson.build: -------------------------------------------------------------------------------- 1 | # This file is part of dftd4. 2 | # SPDX-Identifier: LGPL-3.0-or-later 3 | # 4 | # dftd4 is free software: you can redistribute it and/or modify it under 5 | # the terms of the Lesser GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # dftd4 is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # Lesser GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the Lesser GNU General Public License 15 | # along with dftd4. If not, see . 16 | 17 | subdir('dftd4') 18 | 19 | srcs += files( 20 | 'dftd4.f90', 21 | ) 22 | -------------------------------------------------------------------------------- /subprojects/.gitignore: -------------------------------------------------------------------------------- 1 | /*/ 2 | json-fortran*.wrap 3 | -------------------------------------------------------------------------------- /subprojects/mctc-lib.wrap: -------------------------------------------------------------------------------- 1 | [wrap-git] 2 | directory = mctc-lib 3 | url = https://github.com/grimme-lab/mctc-lib 4 | revision = v0.4.1 5 | -------------------------------------------------------------------------------- /subprojects/mstore.wrap: -------------------------------------------------------------------------------- 1 | [wrap-git] 2 | directory = mstore 3 | url = https://github.com/grimme-lab/mstore 4 | revision = v0.3.0 5 | -------------------------------------------------------------------------------- /subprojects/multicharge.wrap: -------------------------------------------------------------------------------- 1 | [wrap-git] 2 | directory = multicharge 3 | url = https://github.com/grimme-lab/multicharge 4 | revision = v0.4.0 5 | -------------------------------------------------------------------------------- /test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # This file is part of dftd4. 2 | # SPDX-Identifier: LGPL-3.0-or-later 3 | # 4 | # dftd4 is free software: you can redistribute it and/or modify it under 5 | # the terms of the GNU Lesser General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # dftd4 is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU Lesser General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU Lesser General Public License 15 | # along with dftd4. If not, see . 16 | 17 | if(WITH_API) 18 | add_subdirectory("api") 19 | endif() 20 | add_subdirectory("unit") 21 | -------------------------------------------------------------------------------- /test/api/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # This file is part of dftd4. 2 | # SPDX-Identifier: LGPL-3.0-or-later 3 | # 4 | # dftd4 is free software: you can redistribute it and/or modify it under 5 | # the terms of the GNU Lesser General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # dftd4 is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU Lesser General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU Lesser General Public License 15 | # along with dftd4. If not, see . 16 | 17 | add_executable( 18 | "${PROJECT_NAME}-api-tester" 19 | "example.c" 20 | ) 21 | target_include_directories( 22 | "${PROJECT_NAME}-api-tester" 23 | PRIVATE 24 | "${PROJECT_SOURCE_DIR}/include" 25 | ) 26 | target_link_libraries( 27 | "${PROJECT_NAME}-api-tester" 28 | PRIVATE 29 | "${PROJECT_NAME}-lib" 30 | ) 31 | add_test(NAME "api" COMMAND "${PROJECT_NAME}-api-tester") 32 | -------------------------------------------------------------------------------- /test/api/meson.build: -------------------------------------------------------------------------------- 1 | # This file is part of dftd4. 2 | # SPDX-Identifier: LGPL-3.0-or-later 3 | # 4 | # dftd4 is free software: you can redistribute it and/or modify it under 5 | # the terms of the Lesser GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # dftd4 is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # Lesser GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the Lesser GNU General Public License 15 | # along with dftd4. If not, see . 16 | 17 | test( 18 | 'api-test', 19 | executable( 20 | 'api-tester', 21 | sources: files('example.c'), 22 | dependencies: dftd4_dep, 23 | ), 24 | ) 25 | 26 | -------------------------------------------------------------------------------- /test/meson.build: -------------------------------------------------------------------------------- 1 | # This file is part of dftd4. 2 | # SPDX-Identifier: LGPL-3.0-or-later 3 | # 4 | # dftd4 is free software: you can redistribute it and/or modify it under 5 | # the terms of the Lesser GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # dftd4 is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # Lesser GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the Lesser GNU General Public License 15 | # along with dftd4. If not, see . 16 | 17 | if get_option('api') 18 | subdir('api') 19 | endif 20 | 21 | subdir('unit') 22 | -------------------------------------------------------------------------------- /test/unit/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # This file is part of dftd4. 2 | # SPDX-Identifier: LGPL-3.0-or-later 3 | # 4 | # dftd4 is free software: you can redistribute it and/or modify it under 5 | # the terms of the GNU Lesser General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # dftd4 is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU Lesser General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU Lesser General Public License 15 | # along with dftd4. If not, see . 16 | 17 | # Unit testing 18 | set( 19 | tests 20 | "model" 21 | "dftd4" 22 | "pairwise" 23 | "param" 24 | "periodic" 25 | ) 26 | set( 27 | test-srcs 28 | "main.f90" 29 | ) 30 | foreach(t IN LISTS tests) 31 | string(MAKE_C_IDENTIFIER ${t} t) 32 | list(APPEND test-srcs "test_${t}.f90") 33 | endforeach() 34 | 35 | add_executable( 36 | "${PROJECT_NAME}-tester" 37 | "${test-srcs}" 38 | ) 39 | target_link_libraries( 40 | "${PROJECT_NAME}-tester" 41 | PRIVATE 42 | "${PROJECT_NAME}-lib" 43 | "mstore::mstore" 44 | ) 45 | 46 | foreach(t IN LISTS tests) 47 | add_test("${t}" "${PROJECT_NAME}-tester" "${t}") 48 | endforeach() 49 | -------------------------------------------------------------------------------- /test/unit/main.f90: -------------------------------------------------------------------------------- 1 | ! This file is part of dftd4. 2 | ! SPDX-Identifier: LGPL-3.0-or-later 3 | ! 4 | ! dftd4 is free software: you can redistribute it and/or modify it under 5 | ! the terms of the Lesser GNU General Public License as published by 6 | ! the Free Software Foundation, either version 3 of the License, or 7 | ! (at your option) any later version. 8 | ! 9 | ! dftd4 is distributed in the hope that it will be useful, 10 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | ! Lesser GNU General Public License for more details. 13 | ! 14 | ! You should have received a copy of the Lesser GNU General Public License 15 | ! along with dftd4. If not, see . 16 | 17 | !> Driver for unit testing 18 | program tester 19 | use, intrinsic :: iso_fortran_env, only : error_unit 20 | use mctc_env, only : get_argument 21 | use mctc_env_testing, only : run_testsuite, new_testsuite, testsuite_type, & 22 | & select_suite, run_selected 23 | use test_dftd4, only : collect_dftd4 24 | use test_model, only : collect_model 25 | use test_pairwise, only : collect_pairwise 26 | use test_param, only : collect_param 27 | use test_periodic, only : collect_periodic 28 | implicit none 29 | integer :: stat, is 30 | character(len=:), allocatable :: suite_name, test_name 31 | type(testsuite_type), allocatable :: testsuites(:) 32 | character(len=*), parameter :: fmt = '("#", *(1x, a))' 33 | 34 | stat = 0 35 | 36 | testsuites = [ & 37 | & new_testsuite("model", collect_model), & 38 | & new_testsuite("dftd4", collect_dftd4), & 39 | & new_testsuite("param", collect_param), & 40 | & new_testsuite("periodic", collect_periodic), & 41 | & new_testsuite("pairwise", collect_pairwise) & 42 | & ] 43 | 44 | call get_argument(1, suite_name) 45 | call get_argument(2, test_name) 46 | 47 | if (allocated(suite_name)) then 48 | is = select_suite(testsuites, suite_name) 49 | if (is > 0 .and. is <= size(testsuites)) then 50 | if (allocated(test_name)) then 51 | write(error_unit, fmt) "Suite:", testsuites(is)%name 52 | call run_selected(testsuites(is)%collect, test_name, error_unit, stat) 53 | if (stat < 0) then 54 | error stop 1 55 | end if 56 | else 57 | write(error_unit, fmt) "Testing:", testsuites(is)%name 58 | call run_testsuite(testsuites(is)%collect, error_unit, stat) 59 | end if 60 | else 61 | write(error_unit, fmt) "Available testsuites" 62 | do is = 1, size(testsuites) 63 | write(error_unit, fmt) "-", testsuites(is)%name 64 | end do 65 | error stop 1 66 | end if 67 | else 68 | do is = 1, size(testsuites) 69 | write(error_unit, fmt) "Testing:", testsuites(is)%name 70 | call run_testsuite(testsuites(is)%collect, error_unit, stat) 71 | end do 72 | end if 73 | 74 | if (stat > 0) then 75 | write(error_unit, '(i0, 1x, a)') stat, "test(s) failed!" 76 | error stop 1 77 | end if 78 | 79 | 80 | end program tester 81 | -------------------------------------------------------------------------------- /test/unit/meson.build: -------------------------------------------------------------------------------- 1 | # This file is part of dftd4. 2 | # SPDX-Identifier: LGPL-3.0-or-later 3 | # 4 | # dftd4 is free software: you can redistribute it and/or modify it under 5 | # the terms of the Lesser GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # dftd4 is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # Lesser GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the Lesser GNU General Public License 15 | # along with dftd4. If not, see . 16 | 17 | # Create mstore as subproject for testing 18 | mstore_dep = dependency( 19 | 'mstore', 20 | version: '>=0.3.0', 21 | fallback: ['mstore', 'mstore_dep'], 22 | default_options: ['default_library=static'], 23 | required: not meson.is_subproject(), 24 | ) 25 | # If we do not find mstore and are a subproject, we just skip testing 26 | if not mstore_dep.found() 27 | subdir_done() 28 | endif 29 | 30 | tests = [ 31 | 'model', 32 | 'dftd4', 33 | 'pairwise', 34 | 'param', 35 | 'periodic', 36 | ] 37 | 38 | test_srcs = files( 39 | 'main.f90', 40 | ) 41 | foreach t : tests 42 | test_srcs += files('test_@0@.f90'.format(t.underscorify())) 43 | endforeach 44 | 45 | tester = executable( 46 | 'tester', 47 | sources: test_srcs, 48 | dependencies: [dftd4_dep, mstore_dep], 49 | link_language: 'fortran', 50 | ) 51 | 52 | foreach t : tests 53 | test(t, tester, args: t) 54 | endforeach 55 | -------------------------------------------------------------------------------- /test/unit/test_pairwise.f90: -------------------------------------------------------------------------------- 1 | ! This file is part of dftd4. 2 | ! SPDX-Identifier: LGPL-3.0-or-later 3 | ! 4 | ! dftd4 is free software: you can redistribute it and/or modify it under 5 | ! the terms of the Lesser GNU General Public License as published by 6 | ! the Free Software Foundation, either version 3 of the License, or 7 | ! (at your option) any later version. 8 | ! 9 | ! dftd4 is distributed in the hope that it will be useful, 10 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | ! Lesser GNU General Public License for more details. 13 | ! 14 | ! You should have received a copy of the Lesser GNU General Public License 15 | ! along with dftd4. If not, see . 16 | 17 | module test_pairwise 18 | use mctc_env, only : wp 19 | use mctc_env_testing, only : new_unittest, unittest_type, error_type, check, & 20 | & test_failed 21 | use mctc_io, only : structure_type 22 | use mstore, only : get_structure 23 | use dftd4 24 | implicit none 25 | private 26 | 27 | public :: collect_pairwise 28 | 29 | real(wp), parameter :: thr = 100*epsilon(1.0_wp) 30 | real(wp), parameter :: thr2 = sqrt(epsilon(1.0_wp)) 31 | 32 | type(realspace_cutoff), parameter :: cutoff = & 33 | & realspace_cutoff(cn=30_wp, disp2=60.0_wp, disp3=15.0_wp) 34 | 35 | 36 | contains 37 | 38 | 39 | !> Collect all exported unit tests 40 | subroutine collect_pairwise(testsuite) 41 | 42 | !> Collection of tests 43 | type(unittest_type), allocatable, intent(out) :: testsuite(:) 44 | 45 | testsuite = [ & 46 | & new_unittest("PBE-D4", test_pbed4_mb01), & 47 | & new_unittest("PBE-D4S", test_pbed4s_mb01), & 48 | & new_unittest("B97-D4", test_b97d4_mb02), & 49 | & new_unittest("B97-D4S", test_b97d4s_mb02), & 50 | & new_unittest("TPSS-D4", test_tpssd4_ammonia), & 51 | & new_unittest("TPSS-D4S", test_tpssd4s_ammonia) & 52 | & ] 53 | 54 | end subroutine collect_pairwise 55 | 56 | 57 | subroutine test_dftd4_pairwise(error, mol, d4, param) 58 | 59 | !> Error handling 60 | type(error_type), allocatable, intent(out) :: error 61 | 62 | !> Molecular structure data 63 | type(structure_type), intent(in) :: mol 64 | 65 | !> Dispersion model 66 | class(dispersion_model), intent(in) :: d4 67 | 68 | !> Damping parameters 69 | class(damping_param), intent(in) :: param 70 | 71 | real(wp) :: energy 72 | real(wp), allocatable :: energy2(:, :), energy3(:, :) 73 | 74 | allocate(energy2(mol%nat, mol%nat), energy3(mol%nat, mol%nat)) 75 | 76 | call get_dispersion(mol, d4, param, cutoff, energy) 77 | call get_pairwise_dispersion(mol, d4, param, cutoff, energy2, energy3) 78 | 79 | call check(error, energy, sum(energy2) + sum(energy3), thr=thr) 80 | if (allocated(error)) then 81 | print*,energy, sum(energy2) + sum(energy3) 82 | end if 83 | 84 | end subroutine test_dftd4_pairwise 85 | 86 | 87 | subroutine test_pbed4_mb01(error) 88 | 89 | !> Error handling 90 | type(error_type), allocatable, intent(out) :: error 91 | 92 | type(structure_type) :: mol 93 | type(d4_model) :: d4 94 | type(rational_damping_param) :: param = rational_damping_param(& 95 | & s6 = 1.0_wp, s9 = 0.0_wp, alp = 16.0_wp, & 96 | & s8 = 0.95948085_wp, a1 = 0.38574991_wp, a2 = 4.80688534_wp) 97 | 98 | call get_structure(mol, "MB16-43", "01") 99 | call new_d4_model(d4, mol) 100 | call test_dftd4_pairwise(error, mol, d4, param) 101 | 102 | end subroutine test_pbed4_mb01 103 | 104 | subroutine test_pbed4s_mb01(error) 105 | 106 | !> Error handling 107 | type(error_type), allocatable, intent(out) :: error 108 | 109 | type(structure_type) :: mol 110 | type(d4s_model) :: d4s 111 | type(rational_damping_param) :: param = rational_damping_param(& 112 | & s6 = 1.0_wp, s9 = 0.0_wp, alp = 16.0_wp, & 113 | & s8 = 0.95948085_wp, a1 = 0.38574991_wp, a2 = 4.80688534_wp) 114 | 115 | call get_structure(mol, "MB16-43", "01") 116 | call new_d4s_model(d4s, mol) 117 | call test_dftd4_pairwise(error, mol, d4s, param) 118 | 119 | end subroutine test_pbed4s_mb01 120 | 121 | 122 | subroutine test_b97d4_mb02(error) 123 | 124 | !> Error handling 125 | type(error_type), allocatable, intent(out) :: error 126 | 127 | type(structure_type) :: mol 128 | type(d4_model) :: d4 129 | type(rational_damping_param) :: param = rational_damping_param(& 130 | & s6 = 1.0_wp, s9 = 1.0_wp, alp = 16.0_wp, & 131 | & s8 = 1.69460052_wp, a1 = 0.28904684_wp, a2 = 4.13407323_wp) 132 | 133 | call get_structure(mol, "MB16-43", "02") 134 | call new_d4_model(d4, mol) 135 | call test_dftd4_pairwise(error, mol, d4, param) 136 | 137 | end subroutine test_b97d4_mb02 138 | 139 | subroutine test_b97d4s_mb02(error) 140 | 141 | !> Error handling 142 | type(error_type), allocatable, intent(out) :: error 143 | 144 | type(structure_type) :: mol 145 | type(d4s_model) :: d4s 146 | type(rational_damping_param) :: param = rational_damping_param(& 147 | & s6 = 1.0_wp, s9 = 1.0_wp, alp = 16.0_wp, & 148 | & s8 = 1.69460052_wp, a1 = 0.28904684_wp, a2 = 4.13407323_wp) 149 | 150 | call get_structure(mol, "MB16-43", "02") 151 | call new_d4s_model(d4s, mol) 152 | call test_dftd4_pairwise(error, mol, d4s, param) 153 | 154 | end subroutine test_b97d4s_mb02 155 | 156 | 157 | subroutine test_tpssd4_ammonia(error) 158 | 159 | !> Error handling 160 | type(error_type), allocatable, intent(out) :: error 161 | 162 | type(structure_type) :: mol 163 | type(d4_model) :: d4 164 | type(rational_damping_param) :: param = rational_damping_param(& 165 | & s6 = 1.0_wp, s9 = 1.0_wp, alp = 16.0_wp, & 166 | & s8 = 1.76596355_wp, a1 = 0.42822303_wp, a2 = 4.54257102_wp ) 167 | 168 | call get_structure(mol, "X23", "ammonia") 169 | call new_d4_model(d4, mol) 170 | call test_dftd4_pairwise(error, mol, d4, param) 171 | 172 | end subroutine test_tpssd4_ammonia 173 | 174 | subroutine test_tpssd4s_ammonia(error) 175 | 176 | !> Error handling 177 | type(error_type), allocatable, intent(out) :: error 178 | 179 | type(structure_type) :: mol 180 | type(d4s_model) :: d4s 181 | type(rational_damping_param) :: param = rational_damping_param(& 182 | & s6 = 1.0_wp, s9 = 1.0_wp, alp = 16.0_wp, & 183 | & s8 = 1.76596355_wp, a1 = 0.42822303_wp, a2 = 4.54257102_wp ) 184 | 185 | call get_structure(mol, "X23", "ammonia") 186 | call new_d4s_model(d4s, mol) 187 | call test_dftd4_pairwise(error, mol, d4s, param) 188 | 189 | end subroutine test_tpssd4s_ammonia 190 | 191 | 192 | end module test_pairwise 193 | --------------------------------------------------------------------------------