LCOV - code coverage report
Current view: top level - src/xc - xc_exchange_gga.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:2fce0f8) Lines: 96 301 31.9 %
Date: 2024-12-21 06:28:57 Functions: 6 13 46.2 %

          Line data    Source code
       1             : !--------------------------------------------------------------------------------------------------!
       2             : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3             : !   Copyright 2000-2024 CP2K developers group <https://cp2k.org>                                   !
       4             : !                                                                                                  !
       5             : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6             : !--------------------------------------------------------------------------------------------------!
       7             : 
       8             : ! **************************************************************************************************
       9             : !> \brief Calculate several different exchange energy functionals
      10             : !>      with a GGA form
      11             : !> \par History
      12             : !>      JGH (26.02.2003) : OpenMP enabled
      13             : !>      fawzi (04.2004)  : adapted to the new xc interface
      14             : !> \author JGH (27.02.2002)
      15             : ! **************************************************************************************************
      16             : MODULE xc_exchange_gga
      17             : 
      18             :    USE cp_array_utils,                  ONLY: cp_3d_r_cp_type
      19             :    USE cp_log_handling,                 ONLY: cp_to_string
      20             :    USE kinds,                           ONLY: dp
      21             :    USE mathconstants,                   ONLY: pi
      22             :    USE xc_derivative_desc,              ONLY: deriv_norm_drho,&
      23             :                                               deriv_norm_drhoa,&
      24             :                                               deriv_norm_drhob,&
      25             :                                               deriv_rho,&
      26             :                                               deriv_rhoa,&
      27             :                                               deriv_rhob
      28             :    USE xc_derivative_set_types,         ONLY: xc_derivative_set_type,&
      29             :                                               xc_dset_get_derivative
      30             :    USE xc_derivative_types,             ONLY: xc_derivative_get,&
      31             :                                               xc_derivative_type
      32             :    USE xc_functionals_utilities,        ONLY: calc_wave_vector,&
      33             :                                               set_util
      34             :    USE xc_input_constants,              ONLY: xgga_b88,&
      35             :                                               xgga_ev93,&
      36             :                                               xgga_opt,&
      37             :                                               xgga_pbe,&
      38             :                                               xgga_pw86,&
      39             :                                               xgga_pw91,&
      40             :                                               xgga_revpbe
      41             :    USE xc_rho_cflags_types,             ONLY: xc_rho_cflags_type
      42             :    USE xc_rho_set_types,                ONLY: xc_rho_set_get,&
      43             :                                               xc_rho_set_type
      44             : #include "../base/base_uses.f90"
      45             : 
      46             :    IMPLICIT NONE
      47             : 
      48             :    PRIVATE
      49             : 
      50             :    PUBLIC :: xgga_info, xgga_eval
      51             : 
      52             :    REAL(KIND=dp), PARAMETER :: f13 = 1.0_dp/3.0_dp, &
      53             :                                f23 = 2.0_dp*f13, &
      54             :                                f43 = 4.0_dp*f13, &
      55             :                                f53 = 5.0_dp*f13
      56             : 
      57             :    REAL(KIND=dp) :: cx, flda, flsd, sfac, t13
      58             :    REAL(KIND=dp) :: fact, tact
      59             :    REAL(KIND=dp) :: eps_rho
      60             :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'xc_exchange_gga'
      61             : 
      62             : CONTAINS
      63             : 
      64             : ! **************************************************************************************************
      65             : !> \brief return various information on the xgga functionals
      66             : !> \param functional integer selecting the xgga functional, it should be one of
      67             : !>        the constants defined in this module: xgga_b88, xgga_pw86,...
      68             : !> \param lsd a logical that specifies if you are asking about the lsd or lda
      69             : !>        version of the functional
      70             : !> \param reference string with the reference of the actual functional
      71             : !> \param shortform string with the shortform of the functional name
      72             : !> \param needs the components needed by this functional are set to
      73             : !>        true (does not set the unneeded components to false)
      74             : !> \param max_deriv ...
      75             : !> \author fawzi
      76             : ! **************************************************************************************************
      77          28 :    SUBROUTINE xgga_info(functional, lsd, reference, shortform, needs, max_deriv)
      78             :       INTEGER, INTENT(in)                                :: functional
      79             :       LOGICAL, INTENT(in)                                :: lsd
      80             :       CHARACTER(LEN=*), INTENT(OUT), OPTIONAL            :: reference, shortform
      81             :       TYPE(xc_rho_cflags_type), INTENT(inout), OPTIONAL  :: needs
      82             :       INTEGER, INTENT(out), OPTIONAL                     :: max_deriv
      83             : 
      84          28 :       IF (PRESENT(reference)) THEN
      85           4 :          SELECT CASE (functional)
      86             :          CASE (xgga_b88)
      87           0 :             reference = "A. Becke, Phys. Rev. A 38, 3098 (1988)"
      88             :          CASE (xgga_pw86)
      89           0 :             reference = "J.P. Perdew and Y. Wang, Phys. Rev. B, 33, 8800 (1986)"
      90             :          CASE (xgga_pw91)
      91           0 :             reference = "J.P. Perdew et al., Phys. Rev. B, 46, 6671 (1992)"
      92             :          CASE (xgga_pbe)
      93           0 :             reference = "J.P. Perdew, K. Burke, M Ernzerhof, Phys. Rev. Lett, 77, 3865 (1996)"
      94             :          CASE (xgga_revpbe)
      95           0 :             reference = "Y. Zang et al., PRL, 80, 890 (1998) (Revised PBEX)"
      96             :          CASE (xgga_opt)
      97           0 :             reference = "Wee-Meng Hoe, A.J. Cohen, N.C. Handy, CPL, 341, 319 (2001)"
      98             :          CASE (xgga_ev93)
      99           4 :             reference = "E. Engel and S.H. Vosko, Phys. Rev. B, 47, 13164 (1993)"
     100             :          CASE default
     101           4 :             CPABORT("Invalid functional requested ("//cp_to_string(functional)//")")
     102             :          END SELECT
     103           4 :          IF (.NOT. lsd) THEN
     104           4 :             IF (LEN_TRIM(reference) + 6 < LEN(reference)) THEN
     105           4 :                reference(LEN_TRIM(reference):LEN_TRIM(reference) + 6) = ' {LDA}'
     106             :             END IF
     107             :          END IF
     108             :       END IF
     109          28 :       IF (PRESENT(shortform)) THEN
     110           4 :          SELECT CASE (functional)
     111             :          CASE (xgga_b88)
     112           0 :             shortform = "Becke 1988 Exchange Functional"
     113             :          CASE (xgga_pw86)
     114           0 :             shortform = "Perdew-Wang 1986 Functional (exchange energy)"
     115             :          CASE (xgga_pw91)
     116           0 :             shortform = "Perdew-Wang 1991 Functional (exchange energy)"
     117             :          CASE (xgga_pbe)
     118           0 :             shortform = "PBE exchange energy functional"
     119             :          CASE (xgga_revpbe)
     120           0 :             shortform = "Revised PBEX by Zang et al."
     121             :          CASE (xgga_opt)
     122           0 :             shortform = "OPTX exchange energy functional"
     123             :          CASE (xgga_ev93)
     124           4 :             shortform = "Engel-Vosko exchange energy from virial relation"
     125             :          CASE default
     126           4 :             CPABORT("Invalid functional requested ("//cp_to_string(functional)//")")
     127             :          END SELECT
     128           4 :          IF (.NOT. lsd) THEN
     129           4 :             IF (LEN_TRIM(shortform) + 6 < LEN(shortform)) THEN
     130           4 :                shortform(LEN_TRIM(shortform):LEN_TRIM(shortform) + 6) = ' {LDA}'
     131             :             END IF
     132             :          END IF
     133             :       END IF
     134          28 :       IF (PRESENT(needs)) THEN
     135          24 :          IF (lsd) THEN
     136           0 :             needs%rho_spin = .TRUE.
     137           0 :             needs%rho_spin_1_3 = .TRUE.
     138           0 :             needs%norm_drho_spin = .TRUE.
     139             :          ELSE
     140          24 :             needs%rho = .TRUE.
     141          24 :             needs%rho_1_3 = .TRUE.
     142          24 :             needs%norm_drho = .TRUE.
     143             :          END IF
     144             :       END IF
     145          28 :       IF (PRESENT(max_deriv)) max_deriv = 3
     146             : 
     147          28 :    END SUBROUTINE xgga_info
     148             : 
     149             : ! **************************************************************************************************
     150             : !> \brief evaluates different exchange gga
     151             : !> \param functional integer to select the functional that should be evaluated
     152             : !> \param lsd if the lsd version of the functional should be used
     153             : !> \param rho_set the density where you want to evaluate the functional
     154             : !> \param deriv_set place where to store the functional derivatives (they are
     155             : !>        added to the derivatives)
     156             : !> \param order ...
     157             : !> \author fawzi
     158             : ! **************************************************************************************************
     159           8 :    SUBROUTINE xgga_eval(functional, lsd, rho_set, deriv_set, order)
     160             :       INTEGER, INTENT(in)                                :: functional
     161             :       LOGICAL, INTENT(in)                                :: lsd
     162             :       TYPE(xc_rho_set_type), INTENT(IN)                  :: rho_set
     163             :       TYPE(xc_derivative_set_type), INTENT(IN)           :: deriv_set
     164             :       INTEGER, INTENT(in)                                :: order
     165             : 
     166             :       CHARACTER(len=*), PARAMETER                        :: routineN = 'xgga_eval'
     167             : 
     168             :       INTEGER                                            :: handle, ispin, m, npoints, nspin
     169             :       INTEGER, DIMENSION(2)                              :: norm_drho_spin_name, rho_spin_name
     170             :       INTEGER, DIMENSION(2, 3)                           :: bo
     171             :       REAL(KIND=dp)                                      :: drho_cutoff, rho_cutoff
     172           8 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: s
     173           8 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: fs
     174           8 :       REAL(KIND=dp), CONTIGUOUS, DIMENSION(:, :, :), POINTER :: e_0, e_ndrho, e_ndrho_ndrho, &
     175           8 :          e_ndrho_ndrho_ndrho, e_rho, e_rho_ndrho, e_rho_ndrho_ndrho, e_rho_rho, e_rho_rho_ndrho, &
     176           8 :          e_rho_rho_rho
     177          72 :       TYPE(cp_3d_r_cp_type), DIMENSION(2)                :: norm_drho, rho, rho_1_3
     178             :       TYPE(xc_derivative_type), POINTER                  :: deriv
     179             : 
     180           8 :       CALL timeset(routineN, handle)
     181           8 :       NULLIFY (e_0, e_ndrho, e_ndrho_ndrho, e_ndrho_ndrho_ndrho, e_rho_ndrho_ndrho, &
     182           8 :                e_rho_ndrho, e_rho_rho_ndrho, e_rho, e_rho_rho, e_rho_rho_rho)
     183          24 :       DO ispin = 1, 2
     184          24 :          NULLIFY (norm_drho(ispin)%array, rho(ispin)%array, rho_1_3(ispin)%array)
     185             :       END DO
     186             : 
     187           8 :       IF (lsd) THEN
     188             :          CALL xc_rho_set_get(rho_set, rhoa_1_3=rho_1_3(1)%array, &
     189             :                              rhob_1_3=rho_1_3(2)%array, rhoa=rho(1)%array, &
     190             :                              rhob=rho(2)%array, norm_drhoa=norm_drho(1)%array, &
     191             :                              norm_drhob=norm_drho(2)%array, rho_cutoff=rho_cutoff, &
     192           0 :                              drho_cutoff=drho_cutoff, local_bounds=bo)
     193           0 :          nspin = 2
     194           0 :          rho_spin_name = [deriv_rhoa, deriv_rhob]
     195           0 :          norm_drho_spin_name = [deriv_norm_drhoa, deriv_norm_drhob]
     196             :       ELSE
     197             :          CALL xc_rho_set_get(rho_set, rho=rho(1)%array, rho_1_3=rho_1_3(1)%array, &
     198             :                              norm_drho=norm_drho(1)%array, local_bounds=bo, rho_cutoff=rho_cutoff, &
     199           8 :                              drho_cutoff=drho_cutoff)
     200           8 :          nspin = 1
     201           8 :          rho_spin_name = [deriv_rho, deriv_rho]
     202           8 :          norm_drho_spin_name = [deriv_norm_drho, deriv_norm_drho]
     203             :       END IF
     204           8 :       npoints = (bo(2, 1) - bo(1, 1) + 1)*(bo(2, 2) - bo(1, 2) + 1)*(bo(2, 3) - bo(1, 3) + 1)
     205           8 :       m = ABS(order)
     206           8 :       CALL xgga_init(rho_cutoff)
     207             : 
     208          24 :       ALLOCATE (s(npoints))
     209          32 :       ALLOCATE (fs(npoints, m + 1))
     210             : 
     211          16 :       DO ispin = 1, nspin
     212           8 :          IF (lsd) THEN
     213           0 :             fact = flsd
     214           0 :             tact = 1.0_dp
     215           0 :             CALL calc_wave_vector("p", rho(ispin)%array, norm_drho(ispin)%array, s)
     216             :          ELSE
     217           8 :             fact = flda
     218           8 :             tact = t13
     219             :             CALL calc_wave_vector("u", rho(ispin)%array, &
     220           8 :                                   norm_drho(ispin)%array, s)
     221             :          END IF
     222             : 
     223           8 :          SELECT CASE (functional)
     224             :          CASE (xgga_b88)
     225           0 :             CALL efactor_b88(s, fs, m)
     226             :          CASE (xgga_pw86)
     227           0 :             CALL efactor_pw86(s, fs, m)
     228             :          CASE (xgga_pw91)
     229             : 
     230             :             !! omp: note this is handled slightly differently to the
     231             :             !! other cases to prevent sprawling scope declarations
     232             :             !! in efactor_pw91()
     233             : 
     234           0 : !$OMP           PARALLEL DEFAULT (NONE) SHARED(s, fs, m)
     235             :             CALL efactor_pw91(s, fs, m)
     236             : !$OMP           END PARALLEL
     237             : 
     238             :          CASE (xgga_pbe)
     239           0 :             tact = t13
     240           0 :             CALL efactor_pbex(s, fs, m, 1)
     241           0 :             IF (lsd) tact = 1.0_dp
     242             :          CASE (xgga_revpbe)
     243           0 :             tact = t13
     244           0 :             CALL efactor_pbex(s, fs, m, 2)
     245           0 :             IF (lsd) tact = 1.0_dp
     246             :          CASE (xgga_opt)
     247           0 :             CALL efactor_optx(s, fs, m)
     248             :          CASE (xgga_ev93)
     249           8 :             tact = t13
     250           8 :             CALL efactor_ev93(s, fs, m)
     251           8 :             IF (lsd) tact = 1.0_dp
     252             :          CASE DEFAULT
     253           8 :             CPABORT("Unsupported functional")
     254             :          END SELECT
     255             : 
     256           8 :          IF (order >= 0) THEN
     257             :             deriv => xc_dset_get_derivative(deriv_set, [INTEGER::], &
     258           8 :                                             allocate_deriv=.TRUE.)
     259           8 :             CALL xc_derivative_get(deriv, deriv_data=e_0)
     260             : 
     261             :             CALL x_p_0(rho(ispin)%array, rho_1_3(ispin)%array, fs, e_0, &
     262           8 :                        npoints)
     263             :          END IF
     264           8 :          IF (order >= 1 .OR. order == -1) THEN
     265             :             deriv => xc_dset_get_derivative(deriv_set, [rho_spin_name(ispin)], &
     266          16 :                                             allocate_deriv=.TRUE.)
     267           8 :             CALL xc_derivative_get(deriv, deriv_data=e_rho)
     268             :             deriv => xc_dset_get_derivative(deriv_set, [norm_drho_spin_name(ispin)], &
     269          16 :                                             allocate_deriv=.TRUE.)
     270           8 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrho)
     271             : 
     272             :             CALL x_p_1(rho(ispin)%array, &
     273           8 :                        rho_1_3(ispin)%array, s, fs, e_rho, e_ndrho, npoints)
     274             :          END IF
     275           8 :          IF (order >= 2 .OR. order == -2) THEN
     276             :             deriv => xc_dset_get_derivative(deriv_set, [rho_spin_name(ispin), &
     277           0 :                                                         rho_spin_name(ispin)], allocate_deriv=.TRUE.)
     278           0 :             CALL xc_derivative_get(deriv, deriv_data=e_rho_rho)
     279             :             deriv => xc_dset_get_derivative(deriv_set, [rho_spin_name(ispin), &
     280           0 :                                                         norm_drho_spin_name(ispin)], allocate_deriv=.TRUE.)
     281           0 :             CALL xc_derivative_get(deriv, deriv_data=e_rho_ndrho)
     282             :             deriv => xc_dset_get_derivative(deriv_set, [norm_drho_spin_name(ispin), &
     283           0 :                                                         norm_drho_spin_name(ispin)], allocate_deriv=.TRUE.)
     284           0 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrho_ndrho)
     285             : 
     286             :             CALL x_p_2(rho(ispin)%array, &
     287             :                        rho_1_3(ispin)%array, s, fs, e_rho_rho, e_rho_ndrho, &
     288           0 :                        e_ndrho_ndrho, npoints)
     289             :          END IF
     290           8 :          IF (order >= 3 .OR. order == -3) THEN
     291             :             deriv => xc_dset_get_derivative(deriv_set, [rho_spin_name(ispin), &
     292             :                                                         rho_spin_name(ispin), rho_spin_name(ispin)], &
     293           0 :                                             allocate_deriv=.TRUE.)
     294           0 :             CALL xc_derivative_get(deriv, deriv_data=e_rho_rho_rho)
     295             :             deriv => xc_dset_get_derivative(deriv_set, [rho_spin_name(ispin), &
     296             :                                                         rho_spin_name(ispin), norm_drho_spin_name(ispin)], &
     297           0 :                                             allocate_deriv=.TRUE.)
     298           0 :             CALL xc_derivative_get(deriv, deriv_data=e_rho_rho_ndrho)
     299             :             deriv => xc_dset_get_derivative(deriv_set, [rho_spin_name(ispin), &
     300             :                                                         norm_drho_spin_name(ispin), norm_drho_spin_name(ispin)], &
     301           0 :                                             allocate_deriv=.TRUE.)
     302           0 :             CALL xc_derivative_get(deriv, deriv_data=e_rho_ndrho_ndrho)
     303             :             deriv => xc_dset_get_derivative(deriv_set, [norm_drho_spin_name(ispin), &
     304             :                                                         norm_drho_spin_name(ispin), norm_drho_spin_name(ispin)], &
     305           0 :                                             allocate_deriv=.TRUE.)
     306           0 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrho_ndrho_ndrho)
     307             : 
     308             :             CALL x_p_3(rho(ispin)%array, &
     309             :                        rho_1_3(ispin)%array, s, fs, e_rho_rho_rho, &
     310             :                        e_rho_rho_ndrho, e_rho_ndrho_ndrho, e_ndrho_ndrho_ndrho, &
     311           0 :                        npoints)
     312             :          END IF
     313          16 :          IF (order > 3 .OR. order < -3) THEN
     314           0 :             CPABORT("derivatives bigger than 3 not implemented")
     315             :          END IF
     316             :       END DO
     317             : 
     318           8 :       DEALLOCATE (s)
     319           8 :       DEALLOCATE (fs)
     320             : 
     321           8 :       CALL timestop(handle)
     322          24 :    END SUBROUTINE xgga_eval
     323             : 
     324             : ! **************************************************************************************************
     325             : !> \brief ...
     326             : !> \param cutoff ...
     327             : ! **************************************************************************************************
     328           8 :    SUBROUTINE xgga_init(cutoff)
     329             : 
     330             :       REAL(KIND=dp), INTENT(IN)                          :: cutoff
     331             : 
     332           8 :       eps_rho = cutoff
     333           8 :       CALL set_util(cutoff)
     334             : 
     335           8 :       cx = -0.75_dp*(3.0_dp/pi)**f13
     336           8 :       t13 = 2.0_dp**f13
     337           8 :       flda = cx
     338           8 :       flsd = cx*t13
     339             : 
     340           8 :       sfac = 1.0_dp/(2.0_dp*(3.0_dp*pi*pi)**f13)
     341             : 
     342           8 :    END SUBROUTINE xgga_init
     343             : 
     344             : ! **************************************************************************************************
     345             : !> \brief ...
     346             : !> \param rho ...
     347             : !> \param r13 ...
     348             : !> \param fs ...
     349             : !> \param e_0 ...
     350             : !> \param npoints ...
     351             : ! **************************************************************************************************
     352           8 :    SUBROUTINE x_p_0(rho, r13, fs, e_0, npoints)
     353             : 
     354             :       REAL(KIND=dp), DIMENSION(*), INTENT(IN)            :: rho, r13
     355             :       REAL(KIND=dp), DIMENSION(:, :), INTENT(IN)         :: fs
     356             :       REAL(KIND=dp), DIMENSION(*), INTENT(INOUT)         :: e_0
     357             :       INTEGER, INTENT(in)                                :: npoints
     358             : 
     359             :       INTEGER                                            :: ip
     360             : 
     361             : !$OMP     PARALLEL DO DEFAULT (NONE) &
     362             : !$OMP                 SHARED (npoints, rho, eps_rho, fact, r13, fs, e_0) &
     363           8 : !$OMP                 PRIVATE(ip)
     364             : 
     365             :       DO ip = 1, npoints
     366             : 
     367             :          IF (rho(ip) > eps_rho) THEN
     368             :             e_0(ip) = e_0(ip) + fact*r13(ip)*rho(ip)*fs(ip, 1)
     369             :          END IF
     370             : 
     371             :       END DO
     372             : 
     373             : !$OMP     END PARALLEL DO
     374             : 
     375           8 :    END SUBROUTINE x_p_0
     376             : 
     377             : ! **************************************************************************************************
     378             : !> \brief ...
     379             : !> \param rho ...
     380             : !> \param r13 ...
     381             : !> \param s ...
     382             : !> \param fs ...
     383             : !> \param e_rho ...
     384             : !> \param e_ndrho ...
     385             : !> \param npoints ...
     386             : ! **************************************************************************************************
     387           8 :    SUBROUTINE x_p_1(rho, r13, s, fs, e_rho, e_ndrho, npoints)
     388             : 
     389             :       REAL(KIND=dp), DIMENSION(*), INTENT(IN)            :: rho, r13, s
     390             :       REAL(KIND=dp), DIMENSION(:, :), INTENT(IN)         :: fs
     391             :       REAL(KIND=dp), DIMENSION(*), INTENT(INOUT)         :: e_rho, e_ndrho
     392             :       INTEGER, INTENT(in)                                :: npoints
     393             : 
     394             :       INTEGER                                            :: ip
     395             :       REAL(KIND=dp)                                      :: a0, a1, sx, sy
     396             : 
     397             : !$OMP     PARALLEL DO DEFAULT(NONE) &
     398             : !$OMP                 SHARED(npoints, rho, eps_rho, fact, r13, tact, fs) &
     399             : !$OMP                 SHARED(e_rho, e_ndrho, sfac, s) &
     400           8 : !$OMP                 PRIVATE(ip,a0,a1,sx,sy)
     401             : 
     402             :       DO ip = 1, npoints
     403             : 
     404             :          IF (rho(ip) > eps_rho) THEN
     405             : 
     406             :             a0 = fact*r13(ip)*rho(ip)
     407             :             a1 = f43*fact*r13(ip)
     408             :             sx = -f43*s(ip)/rho(ip)
     409             :             sy = sfac*tact/(r13(ip)*rho(ip))
     410             :             e_rho(ip) = e_rho(ip) + a1*fs(ip, 1) + a0*fs(ip, 2)*sx
     411             :             e_ndrho(ip) = e_ndrho(ip) + a0*fs(ip, 2)*sy
     412             : 
     413             :          END IF
     414             : 
     415             :       END DO
     416             : 
     417             : !$OMP     END PARALLEL DO
     418             : 
     419           8 :    END SUBROUTINE x_p_1
     420             : 
     421             : ! **************************************************************************************************
     422             : !> \brief ...
     423             : !> \param rho ...
     424             : !> \param r13 ...
     425             : !> \param s ...
     426             : !> \param fs ...
     427             : !> \param e_rho_rho ...
     428             : !> \param e_rho_ndrho ...
     429             : !> \param e_ndrho_ndrho ...
     430             : !> \param npoints ...
     431             : ! **************************************************************************************************
     432           0 :    SUBROUTINE x_p_2(rho, r13, s, fs, e_rho_rho, e_rho_ndrho, &
     433             :                     e_ndrho_ndrho, npoints)
     434             : 
     435             :       REAL(KIND=dp), DIMENSION(*), INTENT(IN)            :: rho, r13, s
     436             :       REAL(KIND=dp), DIMENSION(:, :), INTENT(IN)         :: fs
     437             :       REAL(KIND=dp), DIMENSION(*), INTENT(INOUT)         :: e_rho_rho, e_rho_ndrho, e_ndrho_ndrho
     438             :       INTEGER, INTENT(in)                                :: npoints
     439             : 
     440             :       INTEGER                                            :: ip
     441             :       REAL(KIND=dp)                                      :: a0, a1, a2, sx, sxx, sxy, sy
     442             : 
     443             : !$OMP     PARALLEL DO DEFAULT(NONE) &
     444             : !$OMP                 SHARED(npoints, rho, eps_rho, r13, fact, e_rho_rho) &
     445             : !$OMP                 SHARED(e_rho_ndrho, e_ndrho_ndrho, fs, sfac, tact, s) &
     446           0 : !$OMP                 PRIVATE(ip,a0,a1,a2,sx,sy,sxx,sxy)
     447             : 
     448             :       DO ip = 1, npoints
     449             : 
     450             :          IF (rho(ip) > eps_rho) THEN
     451             : 
     452             :             a0 = fact*r13(ip)*rho(ip)
     453             :             a1 = f43*fact*r13(ip)
     454             :             a2 = f13*f43*fact/(r13(ip)*r13(ip))
     455             :             sx = -f43*s(ip)/rho(ip)
     456             :             sy = sfac*tact/(r13(ip)*rho(ip))
     457             :             sxx = 28.0_dp/9.0_dp*s(ip)/(rho(ip)*rho(ip))
     458             :             sxy = -f43*sfac*tact/(r13(ip)*rho(ip)*rho(ip))
     459             :             e_rho_rho(ip) = e_rho_rho(ip) + a2*fs(ip, 1) + 2.0_dp*a1*fs(ip, 2)*sx + &
     460             :                             a0*fs(ip, 3)*sx*sx + a0*fs(ip, 2)*sxx
     461             :             e_rho_ndrho(ip) = e_rho_ndrho(ip) &
     462             :                               + a1*fs(ip, 2)*sy + a0*fs(ip, 3)*sx*sy + a0*fs(ip, 2)*sxy
     463             :             e_ndrho_ndrho(ip) = e_ndrho_ndrho(ip) + a0*fs(ip, 3)*sy*sy
     464             : 
     465             :          END IF
     466             : 
     467             :       END DO
     468             : 
     469             : !$OMP     END PARALLEL DO
     470             : 
     471           0 :    END SUBROUTINE x_p_2
     472             : 
     473             : ! **************************************************************************************************
     474             : !> \brief ...
     475             : !> \param rho ...
     476             : !> \param r13 ...
     477             : !> \param s ...
     478             : !> \param fs ...
     479             : !> \param e_rho_rho_rho ...
     480             : !> \param e_rho_rho_ndrho ...
     481             : !> \param e_rho_ndrho_ndrho ...
     482             : !> \param e_ndrho_ndrho_ndrho ...
     483             : !> \param npoints ...
     484             : ! **************************************************************************************************
     485           0 :    SUBROUTINE x_p_3(rho, r13, s, fs, e_rho_rho_rho, e_rho_rho_ndrho, &
     486             :                     e_rho_ndrho_ndrho, e_ndrho_ndrho_ndrho, npoints)
     487             : 
     488             :       REAL(KIND=dp), DIMENSION(*), INTENT(IN)            :: rho, r13, s
     489             :       REAL(KIND=dp), DIMENSION(:, :), INTENT(IN)         :: fs
     490             :       REAL(KIND=dp), DIMENSION(*), INTENT(INOUT)         :: e_rho_rho_rho, e_rho_rho_ndrho, &
     491             :                                                             e_rho_ndrho_ndrho, e_ndrho_ndrho_ndrho
     492             :       INTEGER, INTENT(in)                                :: npoints
     493             : 
     494             :       INTEGER                                            :: ip
     495             :       REAL(KIND=dp)                                      :: a0, a1, a2, a3, sx, sxx, sxxx, sxxy, &
     496             :                                                             sxy, sy
     497             : 
     498             : !$OMP     PARALLEL DO DEFAULT (NONE) &
     499             : !$OMP                 SHARED(npoints, rho, eps_rho, r13, fact, fs) &
     500             : !$OMP                 SHARED(e_rho_rho_rho, e_rho_rho_ndrho) &
     501             : !$OMP                 SHARED(e_rho_ndrho_ndrho, e_ndrho_ndrho_ndrho) &
     502             : !$OMP                 SHARED(sfac, tact, s) &
     503           0 : !$OMP                 PRIVATE(ip,a0,a1,a2,a3,sx,sy,sxx,sxy,sxxx,sxxy)
     504             : 
     505             :       DO ip = 1, npoints
     506             : 
     507             :          IF (rho(ip) > eps_rho) THEN
     508             : 
     509             :             a0 = fact*r13(ip)*rho(ip)
     510             :             a1 = f43*fact*r13(ip)
     511             :             a2 = f13*f43*fact/(r13(ip)*r13(ip))
     512             :             a3 = -f23*f13*f43*fact/(r13(ip)*r13(ip)*rho(ip))
     513             :             sx = -f43*s(ip)/rho(ip)
     514             :             sy = sfac*tact/(r13(ip)*rho(ip))
     515             :             sxx = 28.0_dp/9.0_dp*s(ip)/(rho(ip)*rho(ip))
     516             :             sxy = -f43*sfac*tact/(r13(ip)*rho(ip)*rho(ip))
     517             :             sxxx = -280.0_dp/27.0_dp*s(ip)/(rho(ip)*rho(ip)*rho(ip))
     518             :             sxxy = 28.0_dp/9.0_dp*sfac*tact/(r13(ip)*rho(ip)*rho(ip)*rho(ip))
     519             :             e_rho_rho_rho(ip) = e_rho_rho_rho(ip) &
     520             :                                 + a3*fs(ip, 1) + 3.0_dp*a2*fs(ip, 2)*sx + &
     521             :                                 3.0_dp*a1*fs(ip, 3)*sx*sx + 3.0_dp*a1*fs(ip, 2)*sxx + &
     522             :                                 a0*fs(ip, 4)*sx*sx*sx + 3.0_dp*a0*fs(ip, 3)*sx*sxx + &
     523             :                                 a0*fs(ip, 2)*sxxx
     524             :             e_rho_rho_ndrho(ip) = e_rho_rho_ndrho(ip) &
     525             :                                   + a2*fs(ip, 2)*sy + 2.0_dp*a1*fs(ip, 3)*sx*sy + &
     526             :                                   2.0_dp*a1*fs(ip, 2)*sxy + a0*fs(ip, 4)*sx*sx*sy + &
     527             :                                   2.0_dp*a0*fs(ip, 3)*sx*sxy + a0*fs(ip, 3)*sxx*sy + &
     528             :                                   a0*fs(ip, 2)*sxxy
     529             :             e_rho_ndrho_ndrho(ip) = e_rho_ndrho_ndrho(ip) &
     530             :                                     + a1*fs(ip, 3)*sy*sy + a0*fs(ip, 4)*sx*sy*sy + &
     531             :                                     2.0_dp*a0*fs(ip, 3)*sxy*sy
     532             :             e_ndrho_ndrho_ndrho(ip) = e_ndrho_ndrho_ndrho(ip) &
     533             :                                       + a0*fs(ip, 4)*sy*sy*sy
     534             : 
     535             :          END IF
     536             : 
     537             :       END DO
     538             : 
     539             : !$OMP     END PARALLEL DO
     540             : 
     541           0 :    END SUBROUTINE x_p_3
     542             : 
     543             : ! Enhancement Factors
     544             : ! **************************************************************************************************
     545             : !> \brief ...
     546             : !> \param s ...
     547             : !> \param fs ...
     548             : !> \param m ...
     549             : ! **************************************************************************************************
     550           0 :    SUBROUTINE efactor_b88(s, fs, m)
     551             :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: s
     552             :       REAL(KIND=dp), DIMENSION(:, :), INTENT(INOUT)      :: fs
     553             :       INTEGER, INTENT(IN)                                :: m
     554             : 
     555             :       INTEGER                                            :: ip
     556             :       REAL(KIND=dp) :: as, asp, beta, bs, f0, p, q, sas, sbs, sbs3, t1, t10, t13, t15, t16, t19, &
     557             :          t2, t22, t24, t25, t32, t34, t36, t39, t4, t40, t41, t44, t48, t49, t5, t6, t65, t8, t87, &
     558             :          t9, x, ys
     559             : 
     560           0 :       beta = 0.0042_dp
     561           0 :       f0 = 1.0_dp/sfac
     562           0 :       p = -beta/flsd
     563           0 :       q = 6.0_dp*beta
     564             : 
     565             : !$OMP     PARALLEL DO DEFAULT(NONE) &
     566             : !$OMP                 SHARED(s,fs,m,beta,f0,p,q) &
     567             : !$OMP                 PRIVATE(ip,x,bs,sbs,as,sas,ys,asp,sbs3) &
     568             : !$OMP                 PRIVATE(t1,t2,t4,t5,t6,t8,t9,t10,t13,t15,t16,t19,t22) &
     569             : !$OMP                 PRIVATE(t24,t25,t32,t34) &
     570           0 : !$OMP                 PRIVATE(t36,t39,t40,t41,t44,t48,t49,t65,t87)
     571             : 
     572             :       DO ip = 1, SIZE(s)
     573             :          x = s(ip)*f0
     574             :          bs = beta*x
     575             :          sbs = SQRT(x*x + 1.0_dp)
     576             :          as = LOG(x + sbs)
     577             :          sas = x*as
     578             :          ys = 1.0_dp/(1.0_dp + q*sas)
     579             :          SELECT CASE (m)
     580             :          CASE (0)
     581             :             fs(ip, 1) = 1.0_dp + p*x*x*ys
     582             :          CASE (1)
     583             :             asp = as + x/sbs
     584             :             fs(ip, 1) = 1.0_dp + p*x*x*ys
     585             :             fs(ip, 2) = (2.0_dp*p*x*ys - p*q*x*x*asp*ys*ys)*f0
     586             :          CASE (2)
     587             :             asp = as + x/sbs
     588             :             sbs3 = 1.0_dp/(sbs*sbs*sbs)
     589             :             fs(ip, 1) = 1.0_dp + p*x*x*ys
     590             :             fs(ip, 2) = (2.0_dp*p*x*ys - p*q*x*x*asp*ys*ys)*f0
     591             :             fs(ip, 3) = -f0*f0*p*ys**3*sbs3*(q*x*x*x*x*(q*sas + 5.0_dp &
     592             :                                                         - 2.0_dp*q*sbs) + 2.0_dp*(x*x*(q*q*sas &
     593             :                                                                                        + 3.0_dp*q - sbs) - sbs))
     594             :          CASE (3)
     595             :             asp = as + x/sbs
     596             :             sbs3 = 1.0_dp/(sbs*sbs*sbs)
     597             :             fs(ip, 1) = 1.0_dp + p*x*x*ys
     598             :             fs(ip, 2) = (2.0_dp*p*x*ys - p*q*x*x*asp*ys*ys)*f0
     599             :             fs(ip, 3) = -f0*f0*p*ys**3*sbs3*(q*x*x*x*x*(q*sas + 5.0_dp &
     600             :                                                         - 2.0_dp*q*sbs) + 2.0_dp*(x*x*(q*q*sas &
     601             :                                                                                        + 3.0_dp*q - sbs) - sbs))
     602             :             t1 = q*x
     603             :             t2 = x**2
     604             :             t4 = SQRT(1 + t2)
     605             :             t5 = x + t4
     606             :             t6 = LOG(t5)
     607             :             t8 = 1 + t1*t6
     608             :             t9 = t8**2
     609             :             t10 = 1/t9
     610             :             t13 = 1/t4
     611             :             t15 = 1 + t13*x
     612             :             t16 = 1/t5
     613             :             t19 = q*t6 + t1*t15*t16
     614             :             t22 = p*x
     615             :             t24 = 1/t9/t8
     616             :             t25 = t19**2
     617             :             t32 = t4**2
     618             :             t34 = 1/t32/t4
     619             :             t36 = -t34*t2 + t13
     620             :             t39 = t15**2
     621             :             t40 = t5**2
     622             :             t41 = 1/t40
     623             :             t44 = 2*q*t15*t16 + t1*t36*t16 - t1*t39*t41
     624             :             t48 = p*t2
     625             :             t49 = t9**2
     626             :             t65 = t32**2
     627             :             t87 = -6*p*t10*t19 + 12*t22*t24*t25 - 6*t22*t10*t44 - 6*t48/t49*t25*t19 + &
     628             :                   6*t48*t24*t19*t44 - t48*t10*(3*q*t36*t16 - 3*q*t39*t41 + 3*t1*(1/t65/t4* &
     629             :                                                                          t2*x - t34*x)*t16 - 3*t1*t36*t41*t15 + 2*t1*t39*t15/t40/t5)
     630             : 
     631             :             fs(ip, 4) = t87
     632             :             fs(ip, 4) = f0*f0*f0*fs(ip, 4)
     633             : 
     634             :          CASE DEFAULT
     635             :             CPABORT("Illegal order")
     636             :          END SELECT
     637             :       END DO
     638             : 
     639             : !$OMP     END PARALLEL DO
     640             : 
     641           0 :    END SUBROUTINE efactor_b88
     642             : ! **************************************************************************************************
     643             : !> \brief ...
     644             : !> \param s ...
     645             : !> \param fs ...
     646             : !> \param m ...
     647             : ! **************************************************************************************************
     648           0 :    SUBROUTINE efactor_pw86(s, fs, m)
     649             :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: s
     650             :       REAL(KIND=dp), DIMENSION(:, :), INTENT(INOUT)      :: fs
     651             :       INTEGER, INTENT(IN)                                :: m
     652             : 
     653             :       INTEGER                                            :: ip
     654             :       REAL(KIND=dp)                                      :: f15, p0, p1, p15, s2, s4, s6, t1, t10, &
     655             :                                                             t12, t13, t14, t19, t2, t25, t3, t8, t9
     656             : 
     657           0 :       t1 = 1.296_dp
     658           0 :       t2 = 14.0_dp
     659           0 :       t3 = 0.2_dp
     660           0 :       f15 = 1.0_dp/15.0_dp
     661             : 
     662             : !$OMP     PARALLEL DO DEFAULT(NONE) &
     663             : !$OMP                 SHARED(s, fs, m, t1, t2, t3, f15) &
     664             : !$OMP                 PRIVATE(ip,s2,s4,s6,p0,p1,p15)&
     665           0 : !$OMP                 PRIVATE(t8, t9, t10, t12, t13, t14, t19, t25)
     666             : 
     667             :       DO ip = 1, SIZE(s)
     668             :          s2 = s(ip)*s(ip)
     669             :          s4 = s2*s2
     670             :          s6 = s2*s4
     671             :          SELECT CASE (m)
     672             :          CASE (0)
     673             :             p0 = 1.0_dp + t1*s2 + t2*s4 + t3*s6
     674             :             fs(ip, 1) = p0**f15
     675             :          CASE (1)
     676             :             p0 = 1.0_dp + t1*s2 + t2*s4 + t3*s6
     677             :             p1 = s(ip)*(2.0_dp*t1 + 4.0_dp*t2*s2 + 6.0_dp*t3*s4)
     678             :             p15 = p0**f15
     679             :             fs(ip, 1) = p15
     680             :             fs(ip, 2) = f15*p1*p15/p0
     681             :          CASE (2)
     682             :             p0 = 1.0_dp + t1*s2 + t2*s4 + t3*s6
     683             :             p1 = s(ip)*(2.0_dp*t1 + 4.0_dp*t2*s2 + 6.0_dp*t3*s4)
     684             :             p15 = p0**f15
     685             :             fs(ip, 1) = p15
     686             :             fs(ip, 2) = f15*p1*p15/p0
     687             :             t9 = p15**2; t10 = t9**2; t12 = t10**2; t13 = t12*t10*t9
     688             :             t25 = p1*p1
     689             :             fs(ip, 3) = -14.0_dp/225.0_dp/t13/p0*t25 + &
     690             :                         1.0_dp/t13*(2.0_dp*t1 + 12*t2*s2 + 30.0_dp*t3*s4)/15.0_dp
     691             :          CASE (3)
     692             :             p0 = 1.0_dp + t1*s2 + t2*s4 + t3*s6
     693             :             p1 = s(ip)*(2.0_dp*t1 + 4.0_dp*t2*s2 + 6.0_dp*t3*s4)
     694             :             p15 = p0**f15
     695             :             fs(ip, 1) = p15
     696             :             fs(ip, 2) = f15*p1*p15/p0
     697             :             t9 = p15**2; t10 = t9**2; t12 = t10**2; t13 = t12*t10*t9
     698             :             t25 = p1*p1
     699             :             fs(ip, 3) = -14.0_dp/225.0_dp/t13/p0*t25 + &
     700             :                         1.0_dp/t13*(2.0_dp*t1 + 12*t2*s2 + 30.0_dp*t3*s4)/15.0_dp
     701             :             t8 = p0**2; t9 = p0**f15; t14 = p0/t9; t19 = s2*s(ip)
     702             :             fs(ip, 4) = 406.0_dp/3375.0_dp/t14/t8*p1*p1*p1 - 14.0_dp/ &
     703             :                         75.0_dp/t14/p0*p1*(2*t1 + 12*t2*s2 + 30*t3*s4) + &
     704             :                         1/t14*(24*t2*s(ip) + 120*t3*t19)*f15
     705             :          CASE DEFAULT
     706             :             CPABORT("Illegal order")
     707             :          END SELECT
     708             :       END DO
     709             : 
     710             : !$OMP     END PARALLEL DO
     711             : 
     712           0 :    END SUBROUTINE efactor_pw86
     713             : ! **************************************************************************************************
     714             : !> \brief ...
     715             : !> \param s ...
     716             : !> \param fs ...
     717             : !> \param m ...
     718             : ! **************************************************************************************************
     719           8 :    SUBROUTINE efactor_ev93(s, fs, m)
     720             :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: s
     721             :       REAL(KIND=dp), DIMENSION(:, :), INTENT(INOUT)      :: fs
     722             :       INTEGER, INTENT(IN)                                :: m
     723             : 
     724             :       INTEGER                                            :: ip
     725             :       REAL(KIND=dp)                                      :: a1, a2, a3, b1, b2, b3, d0, d1, d2, d3, &
     726             :                                                             f0, f1, f2, n0, n1, n2, n3, s2, s4, &
     727             :                                                             s6, scale_s, ss
     728             : 
     729           8 :       a1 = 1.647127_dp
     730           8 :       a2 = 0.980118_dp
     731           8 :       a3 = 0.017399_dp
     732           8 :       b1 = 1.523671_dp
     733           8 :       b2 = 0.367229_dp
     734           8 :       b3 = 0.011282_dp
     735           8 :       scale_s = 1._dp/tact
     736             : 
     737             : !$OMP     PARALLEL DO DEFAULT(NONE) &
     738             : !$OMP                 SHARED(s, fs, m, a1, a2, a3, b1, b2, b3, scale_s) &
     739             : !$OMP                 PRIVATE(ip,ss,s2,s4,s6) &
     740           8 : !$OMP                 PRIVATE(n0,n1,n2,n3,d0,d1,d2,d3,f0,f1,f2)
     741             : 
     742             :       DO ip = 1, SIZE(s)
     743             : !     ss = s(ip)
     744             : !
     745             :          ss = scale_s*s(ip)
     746             :          s2 = ss*ss
     747             :          s4 = s2*s2
     748             :          s6 = s2*s4
     749             :          SELECT CASE (m)
     750             :          CASE (0)
     751             :             n0 = 1._dp + a1*s2 + a2*s4 + a3*s6
     752             :             d0 = 1._dp + b1*s2 + b2*s4 + b3*s6
     753             :             fs(ip, 1) = n0/d0
     754             :          CASE (1)
     755             :             n0 = 1._dp + a1*s2 + a2*s4 + a3*s6
     756             :             d0 = 1._dp + b1*s2 + b2*s4 + b3*s6
     757             :             n1 = ss*(2._dp*a1 + 4._dp*a2*s2 + 6._dp*a3*s4)
     758             :             d1 = ss*(2._dp*b1 + 4._dp*b2*s2 + 6._dp*b3*s4)
     759             :             f0 = n0/d0
     760             :             fs(ip, 1) = f0
     761             :             fs(ip, 2) = (n1 - f0*d1)/d0*scale_s
     762             :          CASE (2)
     763             :             n0 = 1._dp + a1*s2 + a2*s4 + a3*s6
     764             :             d0 = 1._dp + b1*s2 + b2*s4 + b3*s6
     765             :             n1 = ss*(2._dp*a1 + 4._dp*a2*s2 + 6._dp*a3*s4)
     766             :             d1 = ss*(2._dp*b1 + 4._dp*b2*s2 + 6._dp*b3*s4)
     767             :             n2 = 2._dp*a1 + 12._dp*a2*s2 + 30._dp*a3*s4
     768             :             d2 = 2._dp*b1 + 12._dp*b2*s2 + 30._dp*b3*s4
     769             :             f0 = n0/d0
     770             :             f1 = (n1 - f0*d1)/d0
     771             :             fs(ip, 1) = f0
     772             :             fs(ip, 2) = f1*scale_s
     773             :             fs(ip, 3) = (n2 - f0*d2 - 2._dp*f1*d1)/d0*scale_s*scale_s
     774             :          CASE (3)
     775             :             n0 = 1._dp + a1*s2 + a2*s4 + a3*s6
     776             :             d0 = 1._dp + b1*s2 + b2*s4 + b3*s6
     777             :             n1 = ss*(2._dp*a1 + 4._dp*a2*s2 + 6._dp*a3*s4)
     778             :             d1 = ss*(2._dp*b1 + 4._dp*b2*s2 + 6._dp*b3*s4)
     779             :             n2 = 2._dp*a1 + 12._dp*a2*s2 + 30._dp*a3*s4
     780             :             d2 = 2._dp*b1 + 12._dp*b2*s2 + 30._dp*b3*s4
     781             :             n3 = ss*(24._dp*a2 + 120._dp*a3*s2)
     782             :             d3 = ss*(24._dp*b2 + 120._dp*b3*s2)
     783             :             f0 = n0/d0
     784             :             f1 = (n1 - f0*d1)/d0
     785             :             f2 = (n2 - f0*d2 - 2._dp*f1*d1)/d0
     786             :             fs(ip, 1) = f0
     787             :             fs(ip, 2) = f1*scale_s
     788             :             fs(ip, 3) = f2*scale_s*scale_s
     789             :             fs(ip, 4) = (n3 - f0*d3 - 3._dp*f2*d1 - 3._dp*f1*d2)/d0*scale_s*scale_s*scale_s
     790             :          CASE DEFAULT
     791             :             CPABORT("Illegal order")
     792             :          END SELECT
     793             :       END DO
     794             : 
     795             : !$OMP     END PARALLEL DO
     796             : 
     797           8 :    END SUBROUTINE efactor_ev93
     798             : ! **************************************************************************************************
     799             : !> \brief ...
     800             : !> \param s ...
     801             : !> \param fs ...
     802             : !> \param m ...
     803             : ! **************************************************************************************************
     804           0 :    SUBROUTINE efactor_optx(s, fs, m)
     805             :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: s
     806             :       REAL(KIND=dp), DIMENSION(:, :), INTENT(OUT)        :: fs
     807             :       INTEGER, INTENT(IN)                                :: m
     808             : 
     809             :       REAL(KIND=dp), PARAMETER                           :: a1 = 1.05151_dp, a2 = 1.43169_dp, &
     810             :                                                             gamma_bo = 0.006_dp
     811             : 
     812             :       INTEGER                                            :: ip
     813             :       REAL(KIND=dp)                                      :: a, b, f0, x, y
     814             : 
     815           0 :       f0 = 1.0_dp/sfac
     816           0 :       b = -a2/flsd
     817             : 
     818             : !$OMP     PARALLEL DO DEFAULT(NONE) &
     819             : !$OMP                 SHARED(s, fs, m, f0, b) &
     820           0 : !$OMP                 PRIVATE(ip,x,A,y)
     821             : 
     822             :       DO ip = 1, SIZE(s)
     823             :          x = s(ip)*f0
     824             :          a = gamma_bo*x*x
     825             :          y = 1.0_dp/(1.0_dp + a)
     826             :          SELECT CASE (m)
     827             :          CASE (0)
     828             :             fs(ip, 1) = a1 + b*a*a*y*y
     829             :          CASE (1)
     830             :             fs(ip, 1) = a1 + b*a*a*y*y
     831             :             fs(ip, 2) = 4.0_dp*b*f0*a*gamma_bo*x*y*y*y
     832             :          CASE (2)
     833             :             fs(ip, 1) = a1 + b*a*a*y*y
     834             :             fs(ip, 2) = 4.0_dp*b*f0*a*gamma_bo*x*y*y*y
     835             :             fs(ip, 3) = -12.0_dp*b*f0*f0*gamma_bo*a*(a - 1.0_dp)*y*y*y*y
     836             :          CASE (3)
     837             :             fs(ip, 1) = a1 + b*a*a*y*y
     838             :             fs(ip, 2) = 4.0_dp*b*f0*a*gamma_bo*x*y*y*y
     839             :             fs(ip, 3) = -12.0_dp*b*f0*f0*gamma_bo*a*(a - 1.0_dp)*y*y*y*y
     840             :             fs(ip, 4) = 24.0_dp*b*f0*f0*f0*gamma_bo*gamma_bo*x* &
     841             :                         (1.0_dp - 5.0_dp*a + 2.0_dp*a*a)*y*y*y*y*y
     842             :          CASE DEFAULT
     843             :             CPABORT("Illegal order")
     844             :          END SELECT
     845             :       END DO
     846             : 
     847             : !$OMP     END PARALLEL DO
     848             : 
     849           0 :    END SUBROUTINE efactor_optx
     850             : 
     851             : ! **************************************************************************************************
     852             : !> \brief ...
     853             : !> \param s ...
     854             : !> \param fs ...
     855             : !> \param m ...
     856             : ! **************************************************************************************************
     857           0 :    SUBROUTINE efactor_pw91(s, fs, m)
     858             :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: s
     859             :       REAL(KIND=dp), DIMENSION(:, :), INTENT(OUT)        :: fs
     860             :       INTEGER, INTENT(IN)                                :: m
     861             : 
     862             :       INTEGER                                            :: ip
     863             :       REAL(dp) :: t1, t10, t101, t106, t109, t111, t113, t119, t12, t123, t124, t13, t14, t15, &
     864             :          t16, t17, t18, t19, t2, t20, t21, t22, t23, t25, t26, t27, t28, t29, t3, t30, t31, t33, &
     865             :          t35, t37, t38, t39, t4, t40, t44, t47, t48, t5, t50, t51, t53, t55, t56, t57, t58, t59, &
     866             :          t6, t60, t64, t65, t69, t7, t70, t71, t73, t77, t78, t8, t80, t82, t9, t90, t93, t94, &
     867             :          t96, t98
     868             :       REAL(KIND=dp)                                      :: a1, a2, a3, a4, a5, b, o, x
     869             : 
     870           0 :       o = 1.0_dp
     871           0 :       a1 = 0.19645_dp
     872           0 :       a2 = 0.2743_dp
     873           0 :       a3 = 0.1508_dp
     874           0 :       a4 = 100.0_dp
     875           0 :       b = 0.8145161_dp
     876           0 :       a5 = 0.004_dp
     877           0 :       IF (m >= 0) THEN
     878             : 
     879           0 : !$OMP       DO
     880             : 
     881             :          DO ip = 1, SIZE(s)
     882           0 :             x = s(ip)
     883           0 :             t3 = b**2
     884           0 :             t4 = x**2
     885           0 :             t7 = SQRT(o + t3*t4)
     886           0 :             t9 = LOG(b*x + t7)
     887           0 :             t10 = a1*x*t9
     888           0 :             t12 = EXP(-a4*t4)
     889           0 :             t17 = t4**2
     890           0 :             fs(ip, 1) = (o + t10 + (a2 - a3*t12)*t4)/(o + t10 + a5*t17)
     891             :          END DO
     892             : 
     893             : !$OMP       END DO
     894             : 
     895             :       END IF
     896           0 :       IF (m >= 1) THEN
     897             : 
     898           0 : !$OMP       DO
     899             : 
     900             :          DO ip = 1, SIZE(s)
     901           0 :             x = s(ip)
     902           0 :             t2 = b**2
     903           0 :             t3 = x**2
     904           0 :             t6 = SQRT(o + t2*t3)
     905           0 :             t7 = b*x + t6
     906           0 :             t8 = LOG(t7)
     907           0 :             t9 = a1*t8
     908           0 :             t10 = a1*x
     909           0 :             t17 = t10*(b + 1/t6*t2*x)/t7
     910           0 :             t19 = t3*x
     911           0 :             t21 = EXP(-a4*t3)
     912           0 :             t26 = a2 - a3*t21
     913           0 :             t30 = t10*t8
     914           0 :             t31 = t3**2
     915           0 :             t33 = o + t30 + a5*t31
     916           0 :             t38 = t33**2
     917             :             fs(ip, 2) = &
     918             :                (t9 + t17 + 2._dp*a3*a4*t19*t21 + 2._dp*t26*x)/ &
     919           0 :                t33 - (o + t30 + t26*t3)/t38*(t9 + t17 + 4._dp*a5*t19)
     920             :          END DO
     921             : 
     922             : !$OMP       END DO
     923             : 
     924             :       END IF
     925           0 :       IF (m >= 2) THEN
     926             : 
     927           0 : !$OMP       DO
     928             : 
     929             :          DO ip = 1, SIZE(s)
     930           0 :             x = s(ip)
     931           0 :             t1 = b**2
     932           0 :             t2 = x**2
     933           0 :             t5 = SQRT(o + t1*t2)
     934           0 :             t7 = o/t5*t1
     935           0 :             t9 = b + t7*x
     936           0 :             t12 = b*x + t5
     937           0 :             t13 = o/t12
     938           0 :             t15 = 2._dp*a1*t9*t13
     939           0 :             t16 = a1*x
     940           0 :             t17 = t5**2
     941           0 :             t20 = t1**2
     942           0 :             t25 = t16*(-o/t17/t5*t20*t2 + t7)*t13
     943           0 :             t26 = t9**2
     944           0 :             t27 = t12**2
     945           0 :             t30 = t16*t26/t27
     946           0 :             t31 = a3*a4
     947           0 :             t33 = EXP(-a4*t2)
     948           0 :             t37 = a4**2
     949           0 :             t39 = t2**2
     950           0 :             t44 = a3*t33
     951           0 :             t47 = LOG(t12)
     952           0 :             t48 = t16*t47
     953           0 :             t50 = o + t48 + a5*t39
     954           0 :             t53 = a1*t47
     955           0 :             t55 = t16*t9*t13
     956           0 :             t56 = t2*x
     957           0 :             t60 = a2 - t44
     958           0 :             t64 = t50**2
     959           0 :             t65 = o/t64
     960           0 :             t69 = t53 + t55 + 4._dp*a5*t56
     961           0 :             t73 = o + t48 + t60*t2
     962           0 :             t77 = t69**2
     963             :             fs(ip, 3) = &
     964             :                (t15 + t25 - t30 + 10._dp*t31*t2*t33 - 4._dp*a3*t37*t39*t33 + &
     965             :                 2._dp*a2 - 2._dp*t44)/t50 - 2._dp* &
     966             :                (t53 + t55 + 2._dp*t31*t56*t33 + 2._dp*t60*x)* &
     967           0 :                t65*t69 + 2._dp*t73/t64/t50*t77 - t73*t65*(t15 + t25 - t30 + 12._dp*a5*t2)
     968             :          END DO
     969             : 
     970             : !$OMP       END DO
     971             : 
     972             :       END IF
     973           0 :       IF (m >= 3) THEN
     974             : 
     975           0 : !$OMP       DO
     976             : 
     977             :          DO ip = 1, SIZE(s)
     978           0 :             x = s(ip)
     979           0 :             t1 = b**2
     980           0 :             t2 = x**2
     981           0 :             t5 = SQRT(0.1e1_dp + t1*t2)
     982           0 :             t6 = t5**2
     983           0 :             t9 = t1**2
     984           0 :             t10 = 1/t6/t5*t9
     985           0 :             t13 = 1/t5*t1
     986           0 :             t14 = -t10*t2 + t13
     987           0 :             t17 = b*x + t5
     988           0 :             t18 = 1/t17
     989           0 :             t20 = 3*a1*t14*t18
     990           0 :             t22 = b + t13*x
     991           0 :             t23 = t22**2
     992           0 :             t25 = t17**2
     993           0 :             t26 = 1/t25
     994           0 :             t28 = 3*a1*t23*t26
     995           0 :             t29 = a1*x
     996           0 :             t30 = t6**2
     997           0 :             t35 = t2*x
     998           0 :             t40 = 3*t29*(1/t30/t5*t1*t9*t35 - t10*x)*t18
     999           0 :             t44 = 3*t29*t14*t26*t22
    1000           0 :             t50 = 2*t29*t23*t22/t25/t17
    1001           0 :             t51 = a3*a4
    1002           0 :             t53 = EXP(-a4*t2)
    1003           0 :             t57 = a4**2
    1004           0 :             t58 = a3*t57
    1005           0 :             t59 = t35*t53
    1006           0 :             t64 = t2**2
    1007           0 :             t70 = LOG(t17)
    1008           0 :             t71 = t29*t70
    1009           0 :             t73 = 0.1e1_dp + t71 + a5*t64
    1010           0 :             t78 = 2*a1*t22*t18
    1011           0 :             t80 = t29*t14*t18
    1012           0 :             t82 = t29*t23*t26
    1013           0 :             t90 = a3*t53
    1014           0 :             t93 = t73**2
    1015           0 :             t94 = 1/t93
    1016           0 :             t96 = a1*t70
    1017           0 :             t98 = t29*t18*t22
    1018           0 :             t101 = t96 + t98 + 4*a5*t35
    1019           0 :             t106 = a2 - t90
    1020           0 :             t109 = t96 + t98 + 2*t51*t59 + 2*t106*x
    1021           0 :             t111 = 1/t93/t73
    1022           0 :             t113 = t101**2
    1023           0 :             t119 = t78 + t80 - t82 + 12*a5*t2
    1024           0 :             t123 = 0.1e1_dp + t71 + t106*t2
    1025           0 :             t124 = t93**2
    1026             :             fs(ip, 4) = &
    1027             :                (t20 - t28 + t40 - t44 + t50 + 24*t51*x*t53 - 36._dp*t58*t59 + 8._dp*a3*t57*a4*t64* &
    1028             :                 x*t53)/t73 - 3._dp*(t78 + t80 - t82 + 10._dp*t51*t2*t53 - &
    1029             :                                     4._dp*t58*t64*t53 + 2._dp*a2 - 2._dp*t90)*t94*t101 + &
    1030             :                6._dp*t109*t111*t113 - 3._dp*t109*t94*t119 - 6*t123/t124*t113*t101 + &
    1031           0 :                6._dp*t123*t111*t101*t119 - t123*t94*(t20 - t28 + t40 - t44 + t50 + 24._dp*a5*x)
    1032             :          END DO
    1033             : 
    1034             : !$OMP       END DO
    1035             : 
    1036             :       END IF
    1037             : 
    1038           0 :    END SUBROUTINE efactor_pw91
    1039             : 
    1040             : ! **************************************************************************************************
    1041             : !> \brief ...
    1042             : !> \param s ...
    1043             : !> \param fs ...
    1044             : !> \param m ...
    1045             : !> \param pset ...
    1046             : ! **************************************************************************************************
    1047           0 :    SUBROUTINE efactor_pbex(s, fs, m, pset)
    1048             :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: s
    1049             :       REAL(KIND=dp), DIMENSION(:, :), INTENT(OUT)        :: fs
    1050             :       INTEGER, INTENT(IN)                                :: m, pset
    1051             : 
    1052             :       REAL(KIND=dp), PARAMETER                           :: kappa1 = 0.804_dp, kappa2 = 1.245_dp, &
    1053             :                                                             mu = 0.2195149727645171_dp
    1054             : 
    1055             :       INTEGER                                            :: ip
    1056             :       REAL(KIND=dp)                                      :: f0, mk, x, x2, y
    1057             : 
    1058             :       IF (pset == 1) mk = mu/kappa1
    1059           0 :       IF (pset == 2) mk = mu/kappa2
    1060             : 
    1061           0 :       f0 = 1.0_dp/tact
    1062             : 
    1063             : !$OMP     PARALLEL DO DEFAULT(NONE) &
    1064             : !$OMP                 SHARED (s, fs, m, mk, f0) &
    1065           0 : !$OMP                 PRIVATE(ip,x,x2,y)
    1066             : 
    1067             :       DO ip = 1, SIZE(s)
    1068             :          x = s(ip)*f0
    1069             :          x2 = x*x
    1070             :          y = 1.0_dp/(1.0_dp + mk*x2)
    1071             :          SELECT CASE (m)
    1072             :          CASE (0)
    1073             :             fs(ip, 1) = 1.0_dp + mu*x2*y
    1074             :          CASE (1)
    1075             :             fs(ip, 1) = 1.0_dp + mu*x2*y
    1076             :             fs(ip, 2) = 2.0_dp*mu*x*y*y*f0
    1077             :          CASE (2)
    1078             :             fs(ip, 1) = 1.0_dp + mu*x2*y
    1079             :             fs(ip, 2) = 2.0_dp*mu*x*y*y*f0
    1080             :             fs(ip, 3) = -2.0_dp*mu*(3.0_dp*mk*x2 - 1.0_dp)*y*y*y*f0*f0
    1081             :          CASE (3)
    1082             :             fs(ip, 1) = 1.0_dp + mu*x2*y
    1083             :             fs(ip, 2) = 2.0_dp*mu*x*y*y*f0
    1084             :             fs(ip, 3) = -2.0_dp*mu*(3.0_dp*mk*x2 - 1.0_dp)*y*y*y*f0*f0
    1085             :             fs(ip, 4) = 24.0_dp*mu*mk*x*(mk*x2 - 1.0_dp)*y*y*y*y*f0*f0*f0
    1086             :          CASE DEFAULT
    1087             :             CPABORT("Illegal order")
    1088             :          END SELECT
    1089             :       END DO
    1090             : 
    1091             : !$OMP     END PARALLEL DO
    1092             : 
    1093           0 :    END SUBROUTINE efactor_pbex
    1094             : 
    1095             : END MODULE xc_exchange_gga
    1096             : 

Generated by: LCOV version 1.15