! This Source Code Form is subject to the terms of the Mozilla Public ! License, v. 2.0. If a copy of the MPL was not distributed with this ! file, You can obtain one at http://mozilla.org/MPL/2.0/. module mbd_damping !! Damping functions. use mbd_constants use mbd_defaults use mbd_gradients, only: grad_scalar_t, grad_request_t use mbd_utils, only: lower, exception_t implicit none private public :: damping_fermi, damping_sqrtfermi, op1minus_grad type, public :: damping_t !! Represents a damping function. character(len=20) :: version real(dp) :: beta = 0d0 real(dp) :: a = MBD_DAMPING_A real(dp) :: ts_d = TS_DAMPING_D real(dp) :: ts_sr = 0d0 real(dp) :: mayer_scaling = 1d0 real(dp), allocatable :: r_vdw(:) real(dp), allocatable :: sigma(:) real(dp), allocatable :: damping_custom(:, :) real(dp), allocatable :: potential_custom(:, :, :, :) contains procedure :: set_params_from_xc => damping_set_params_from_xc end type contains real(dp) function damping_fermi(r, s_vdw, d, df, grad) result(f) !! $$ !! \begin{gathered} !! f_{(ij)}=\frac1{1+\exp\big({-}a(\eta-1)\big)},\qquad !! \eta=\frac{R_{(ij)}}{S_{\text{vdW}(ij)}}\equiv !! \frac{R_{(ij)}}{\beta R_{\text{vdW}(ij)}} !! \\ \frac{\mathrm df}{\mathrm dR_c}= !! \frac a{2+2\cosh\big(a(\eta-1)\big)}\frac{\mathrm d\eta}{\mathrm dR_c},\qquad !! \frac{\mathrm d\eta}{\mathrm dR_c}= !! \frac{R_c}{RS_\text{vdW}}- !! \frac{R}{S_\text{vdW}^2}\frac{\mathrm dS_\text{vdW}}{\mathrm dR_c} !! \end{gathered} !! $$ real(dp), intent(in) :: r(3) real(dp), intent(in) :: s_vdw real(dp), intent(in) :: d type(grad_scalar_t), intent(out), optional :: df type(grad_request_t), intent(in), optional :: grad real(dp) :: pre, eta, r_1 r_1 = sqrt(sum(r**2)) eta = r_1 / s_vdw f = 1d0 / (1 + exp(-d * (eta - 1))) if (.not. present(grad)) return pre = d / (2 + 2 * cosh(d - d * eta)) if (grad%dcoords) df%dr = pre * r / (r_1 * s_vdw) if (grad%dr_vdw) df%dvdw = -pre * r_1 / s_vdw**2 end function real(dp) function damping_sqrtfermi(r, s_vdw, d) result(f) real(dp), intent(in) :: r(3) real(dp), intent(in) :: s_vdw real(dp), intent(in) :: d f = sqrt(damping_fermi(r, s_vdw, d)) end function subroutine op1minus_grad(f, df) real(dp), intent(inout) :: f type(grad_scalar_t), intent(inout) :: df f = 1 - f if (allocated(df%dr)) df%dr = -df%dr if (allocated(df%dvdw)) df%dvdw = -df%dvdw end subroutine type(exception_t) function damping_set_params_from_xc(this, xc, variant) result(exc) class(damping_t), intent(inout) :: this character(len=*), intent(in) :: xc character(len=*), intent(in) :: variant select case (lower(variant)) case ('ts') select case (lower(xc)) case ('pbe') this%ts_sr = 0.94d0 case ('pbe0') this%ts_sr = 0.96d0 case ('hse') this%ts_sr = 0.96d0 case ('blyp') this%ts_sr = 0.62d0 case ('b3lyp') this%ts_sr = 0.84d0 case ('revpbe') this%ts_sr = 0.60d0 case ('am05') this%ts_sr = 0.84d0 case default exc%code = MBD_EXC_DAMPING exc%msg = 'Damping parameter S_r of method TS unknown for '//trim(xc) end select case ('mbd-rsscs') select case (lower(xc)) case ('pbe') this%beta = 0.83d0 case ('pbe0') this%beta = 0.85d0 case ('hse') this%beta = 0.85d0 case default exc%code = MBD_EXC_DAMPING exc%msg = 'Damping parameter beta of method MBD@rsSCS unknown for '//trim(xc) end select case ('mbd-nl') select case (lower(xc)) case ('pbe') this%beta = 0.81d0 case ('pbe0') this%beta = 0.83d0 case ('hse') this%beta = 0.83d0 case default exc%code = MBD_EXC_DAMPING exc%msg = 'Damping parameter beta of method MBD-NL unknown for '//trim(xc) end select case ('mbd-ts') select case (lower(xc)) case ('pbe') this%beta = 0.81d0 case ('pbe0') this%beta = 0.83d0 case ('hse') this%beta = 0.83d0 case default exc%code = MBD_EXC_DAMPING exc%msg = 'Damping parameter beta of method MBD@TS unknown for '//trim(xc) end select case ('mbd-scs') select case (lower(xc)) case ('pbe') this%a = 2.56d0 case ('pbe0') this%a = 2.53d0 case ('hse') this%a = 2.53d0 case default exc%code = MBD_EXC_DAMPING exc%msg = 'Damping parameter a of method MBD@SCS unknown for '//trim(xc) end select case default exc%code = MBD_EXC_DAMPING exc%msg = 'Damping paramters of method '//trim(variant)//' unkonwn for '//trim(xc) end select end function end module