How to use this library?#
This section contains a few self-contained examples on how to use D3.
Compute energy with rational damping#
This example shows how to compute the dispersion energy with the rational damping function.
energy.f90#
program test_simple_d3
use, intrinsic :: iso_fortran_env, only : r8 => real64
use mctc_env, only: error_type
use mctc_io, only: structure_type, new
use dftd3, only: d3_model, d3_param, rational_damping_param, get_rational_damping, &
& new_rational_damping, new_d3_model, get_dispersion, realspace_cutoff
implicit none
character(len=:), allocatable :: method
type(structure_type) :: mol
type(error_type), allocatable :: error
integer, allocatable :: num(:)
real(r8), allocatable :: xyz(:, :)
real(r8) :: energy
type(d3_model) :: disp
type(d3_param) :: inp
type(rational_damping_param) :: param
method = 'PBE0'
num = [6, 1, 1, 1, 1]
xyz = reshape([ & ! coordinates in Bohr
& 0.0000000_r8, -0.0000000_r8, 0.0000000_r8, &
& -1.1922080_r8, 1.1922080_r8, 1.1922080_r8, &
& 1.1922080_r8, -1.1922080_r8, 1.1922080_r8, &
& -1.1922080_r8, -1.1922080_r8, -1.1922080_r8, &
& 1.1922080_r8, 1.1922080_r8, -1.1922080_r8],&
& [3, size(num)])
call new(mol, num, xyz, charge=0.0_r8, uhf=0)
call get_rational_damping(inp, method, error, s9=1.0_r8)
if (allocated(error)) then
print '(2a)', "Error: ", error%message
return
end if
call new_rational_damping(param, inp)
call new_d3_model(disp, mol)
call get_dispersion(mol, disp, param, realspace_cutoff(), energy)
print '(3a, f13.10, a)', 'Dispersion energy for ', method, '-D3(BJ) is ', energy, ' Hartree'
end program test_simple_d3
energy.c#
#include <stdio.h>
#include <stdbool.h>
#include "dftd3.h"
int main(void)
{
dftd3_error error = dftd3_new_error();
dftd3_structure mol = NULL;
dftd3_model d3 = NULL;
dftd3_param param = NULL;
int nat = 5;
int num[5] = {6, 1, 1, 1, 1};
double xyz[15] = { // coordinates in Bohr
0.0000000, -0.0000000, 0.0000000,
-1.1922080, 1.1922080, 1.1922080,
1.1922080, -1.1922080, 1.1922080,
-1.1922080, -1.1922080, -1.1922080,
1.1922080, 1.1922080, -1.1922080};
mol = dftd3_new_structure(error, nat, num, xyz, NULL, NULL);
if (dftd3_check_error(error)) goto handle_error;
char method[5] = "PBE0";
param = dftd3_load_rational_damping(error, method, false);
if (dftd3_check_error(error)) goto handle_error;
d3 = dftd3_new_d3_model(error, mol);
if (dftd3_check_error(error)) goto handle_error;
double energy;
dftd3_get_dispersion(error, mol, d3, param, &energy, NULL, NULL);
if (dftd3_check_error(error)) goto handle_error;
printf("Dispersion energy for %s-D3(BJ) is %13.10lf Hartree\n", method, energy);
dftd3_delete(error);
dftd3_delete(mol);
dftd3_delete(d3);
dftd3_delete(param);
return 0;
handle_error:
char msg[512];
dftd3_get_error(error, msg, NULL);
printf("Error: %s\n", msg);
dftd3_delete(error);
dftd3_delete(mol);
dftd3_delete(d3);
dftd3_delete(param);
return 1;
}
energy.py#
import numpy as np
from dftd3.interface import RationalDampingParam, DispersionModel
num = np.array([6, 1, 1, 1, 1])
xyz = np.array( # coordinates in Bohr
[
[ 0.0000000, -0.0000000, 0.0000000],
[-1.1922080, 1.1922080, 1.1922080],
[ 1.1922080, -1.1922080, 1.1922080],
[-1.1922080, -1.1922080, -1.1922080],
[ 1.1922080, 1.1922080, -1.1922080],
]
)
method = "PBE0"
model = DispersionModel(num, xyz)
res = model.get_dispersion(RationalDampingParam(method=method), grad=False)
print(f"Dispersion energy for {method}-D3(BJ) is {res['energy']:13.10f} Hartree")
To test this example you can install the dependencies with
mamba create d3 simple-dftd3 fortran-compiler pkg-config
mamba activate d3
mamba create d3 simple-dftd3 c-compiler pkg-config
mamba activate d3
mamba create d3 dftd3-python
mamba activate d3
You can run the example code with
❯ $FC energy.f90 $(pkg-config s-dftd3 mctc-lib --cflags --libs) && ./a.out
Dispersion energy for PBE0-D3(BJ) is -0.0009218696 Hartree
❯ $CC energy.c $(pkg-config s-dftd3 mctc-lib --cflags --libs) && ./a.out
Dispersion energy for PBE0-D3(BJ) is -0.0009218696 Hartree
❯ python energy.py
Dispersion energy for PBE0-D3(BJ) is -0.0009218696 Hartree