subroutine d4_calculation(io, env, options, mol_, param_, res)
integer, intent(in) :: io
type(mctc_logger), intent(inout) :: env
type(dftd_options), intent(in) :: options
type(molecule), intent(in) :: mol_
type(dftd_parameter), intent(in) :: param_
type(dftd_results), intent(out) :: res
type(structure_type) :: mol
type(d4_model) :: d4
type(rational_damping_param) :: param
real(wp), allocatable :: energy, gradient(:, :), sigma(:, :)
call new(mol, mol_%at, mol_%xyz, lattice=mol_%lattice)
call new_d4_model(d4, mol, ga=options%g_a, gc=options%g_c, wf=options%wf)
param = rational_damping_param(&
& s6=param_%s6, &
& s8=param_%s8, &
& s9=param_%s9, &
& a1=param_%a1, &
& a2=param_%a2, &
& alp=param_%alp)
allocate(energy, gradient(3, mol%nat), sigma(3, 3))
call get_dispersion(mol, d4, param, realspace_cutoff(), energy, gradient, sigma)
call move_alloc(energy, res%energy)
call move_alloc(gradient, res%gradient)
res%lattice_gradient = matmul(sigma, transpose(matinv_3x3(mol%lattice)))
end subroutine d4_calculation