├── .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 | [](https://aur.archlinux.org/packages/dftd4/)
4 | [](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 |
--------------------------------------------------------------------------------