utility_w0gauss Function

public function utility_w0gauss(x, n)

Uses

  • proc~~utility_w0gauss~~UsesGraph proc~utility_w0gauss utility_w0gauss module~w90_constants w90_constants proc~utility_w0gauss->module~w90_constants module~w90_io w90_io proc~utility_w0gauss->module~w90_io module~w90_io->module~w90_constants

the derivative of utility_wgauss: an approximation to the delta function

(n>=0) : derivative of the corresponding Methfessel-Paxton utility_wgauss

(n=-1 ): derivative of cold smearing: 1/sqrt(pi)exp(-(x-1/sqrt(2))2)(2-sqrt(2)*x)

(n=-99): derivative of Fermi-Dirac function: 0.5/(1.0+cosh(x))

Arguments

Type IntentOptional AttributesName
real(kind=dp) :: x
integer :: n

Return Value real(kind=dp)


Called by

proc~~utility_w0gauss~~CalledByGraph proc~utility_w0gauss utility_w0gauss proc~dos_get_k dos_get_k proc~dos_get_k->proc~utility_w0gauss proc~gyrotropic_get_k_list gyrotropic_get_k_list proc~gyrotropic_get_k_list->proc~utility_w0gauss proc~tdf_kpt TDF_kpt proc~tdf_kpt->proc~utility_w0gauss proc~berry_get_kubo_k berry_get_kubo_k proc~berry_get_kubo_k->proc~utility_w0gauss proc~calctdfanddos calcTDFandDOS proc~calctdfanddos->proc~dos_get_k proc~calctdfanddos->proc~tdf_kpt proc~dos_main dos_main proc~dos_main->proc~dos_get_k proc~gyrotropic_main gyrotropic_main proc~gyrotropic_main->proc~gyrotropic_get_k_list proc~berry_main berry_main proc~berry_main->proc~berry_get_kubo_k proc~boltzwann_main boltzwann_main proc~boltzwann_main->proc~calctdfanddos

Contents

Source Code


Source Code

  function utility_w0gauss(x, n)
    !-----------------------------------------------------------------------
    !
    !! the derivative of utility_wgauss:  an approximation to the delta function
    !!
    !! (n>=0) : derivative of the corresponding Methfessel-Paxton utility_wgauss
    !!
    !! (n=-1 ): derivative of cold smearing:
    !!              1/sqrt(pi)*exp(-(x-1/sqrt(2))**2)*(2-sqrt(2)*x)
    !!
    !! (n=-99): derivative of Fermi-Dirac function: 0.5/(1.0+cosh(x))
    !
    use w90_constants, only: dp, pi
    use w90_io, only: io_error
    implicit none
    real(kind=dp) :: utility_w0gauss, x
    !! output: the value of the function
    !! input: the point where to compute the function

    integer :: n
    !! input: the order of the smearing function
    !
    !    here the local variables
    !
    real(kind=dp) :: a, arg, hp, hd, sqrtpm1
    ! the coefficients a_n
    ! the argument of the exponential
    ! the hermite function
    ! the hermite function

    integer :: i, ni
    ! counter on n values
    ! counter on 2n values

    ! Fermi-Dirac smearing

    sqrtpm1 = 1.0_dp/sqrt(pi)

    if (n .eq. -99) then
      if (abs(x) .le. 36.0) then
        utility_w0gauss = 1.00_dp/(2.00_dp + exp(-x) + exp(+x))
        ! in order to avoid problems for large values of x in the e
      else
        utility_w0gauss = 0.0_dp
      endif
      return

    endif
    ! cold smearing  (Marzari-Vanderbilt)
    if (n .eq. -1) then
      arg = min(200.0_dp, (x - 1.00_dp/sqrt(2.00_dp))**2)
      utility_w0gauss = sqrtpm1*exp(-arg)*(2.00_dp - sqrt(2.00_dp)*x)
      return

    endif

    if (n .gt. 10 .or. n .lt. 0) &
      call io_error('utility_w0gauss higher order smearing is untested and unstable')

    ! Methfessel-Paxton
    arg = min(200.0_dp, x**2)
    utility_w0gauss = exp(-arg)*sqrtpm1
    if (n .eq. 0) return
    hd = 0.00_dp
    hp = exp(-arg)
    ni = 0
    a = sqrtpm1
    do i = 1, n
      hd = 2.00_dp*x*hp - 2.00_dp*DBLE(ni)*hd
      ni = ni + 1
      a = -a/(DBLE(i)*4.00_dp)
      hp = 2.00_dp*x*hd - 2.00_dp*DBLE(ni)*hp
      ni = ni + 1
      utility_w0gauss = utility_w0gauss + a*hp
    enddo
    return
  end function utility_w0gauss