LCOV - code coverage report
Current view: top level - src/xc - xc_cs1.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:2fce0f8) Lines: 62 141 44.0 %
Date: 2024-12-21 06:28:57 Functions: 5 11 45.5 %

          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 the CS1 Functional (Handy s improved LYP functional)
      10             : !> \par History
      11             : !>      JGH (26.02.2003) : OpenMP enabled
      12             : !>      fawzi (04.2004)  : adapted to the new xc interface
      13             : !> \author JGH (16.03.2002)
      14             : ! **************************************************************************************************
      15             : MODULE xc_cs1
      16             : 
      17             :    USE kinds,                           ONLY: dp
      18             :    USE xc_derivative_desc,              ONLY: deriv_norm_drho,&
      19             :                                               deriv_norm_drhoa,&
      20             :                                               deriv_norm_drhob,&
      21             :                                               deriv_rho,&
      22             :                                               deriv_rhoa,&
      23             :                                               deriv_rhob
      24             :    USE xc_derivative_set_types,         ONLY: xc_derivative_set_type,&
      25             :                                               xc_dset_get_derivative
      26             :    USE xc_derivative_types,             ONLY: xc_derivative_get,&
      27             :                                               xc_derivative_type
      28             :    USE xc_functionals_utilities,        ONLY: set_util
      29             :    USE xc_rho_cflags_types,             ONLY: xc_rho_cflags_type
      30             :    USE xc_rho_set_types,                ONLY: xc_rho_set_get,&
      31             :                                               xc_rho_set_type
      32             : #include "../base/base_uses.f90"
      33             : 
      34             :    IMPLICIT NONE
      35             : 
      36             :    PRIVATE
      37             : 
      38             :    REAL(KIND=dp), PARAMETER :: f13 = 1.0_dp/3.0_dp, &
      39             :                                f23 = 2.0_dp*f13, &
      40             :                                f43 = 4.0_dp*f13, &
      41             :                                f53 = 5.0_dp*f13
      42             : 
      43             :    PUBLIC :: cs1_lda_info, cs1_lda_eval, cs1_lsd_info, cs1_lsd_eval
      44             : 
      45             :    REAL(KIND=dp) :: eps_rho
      46             :    LOGICAL :: debug_flag
      47             :    REAL(KIND=dp) :: fsig
      48             : 
      49             :    REAL(KIND=dp), PARAMETER :: a = 0.04918_dp, &
      50             :                                b = 0.132_dp, &
      51             :                                c = 0.2533_dp, &
      52             :                                d = 0.349_dp
      53             : 
      54             :    REAL(KIND=dp), PARAMETER :: c1 = 0.018897_dp, &
      55             :                                c2 = -0.155240_dp, &
      56             :                                c3 = 0.159068_dp, &
      57             :                                c4 = -0.007953_dp
      58             : 
      59             :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'xc_cs1'
      60             : 
      61             : CONTAINS
      62             : 
      63             : ! **************************************************************************************************
      64             : !> \brief return various information on the functional
      65             : !> \param reference string with the reference of the actual functional
      66             : !> \param shortform string with the shortform of the functional name
      67             : !> \param needs the components needed by this functional are set to
      68             : !>        true (does not set the unneeded components to false)
      69             : !> \param max_deriv ...
      70             : ! **************************************************************************************************
      71          33 :    SUBROUTINE cs1_lda_info(reference, shortform, needs, max_deriv)
      72             :       CHARACTER(LEN=*), INTENT(OUT), OPTIONAL            :: reference, shortform
      73             :       TYPE(xc_rho_cflags_type), INTENT(inout), OPTIONAL  :: needs
      74             :       INTEGER, INTENT(out), OPTIONAL                     :: max_deriv
      75             : 
      76          33 :       IF (PRESENT(reference)) THEN
      77           1 :          reference = "N.C. Handy and A.J. Cohen, J. Chem. Phys., 116, 5411 (2002) {LDA version}"
      78             :       END IF
      79          33 :       IF (PRESENT(shortform)) THEN
      80           1 :          shortform = "CS1: Handy improved LYP correlation energy functional {LDA}"
      81             :       END IF
      82          33 :       IF (PRESENT(needs)) THEN
      83          32 :          needs%rho = .TRUE.
      84          32 :          needs%rho_1_3 = .TRUE.
      85          32 :          needs%norm_drho = .TRUE.
      86             :       END IF
      87          33 :       IF (PRESENT(max_deriv)) max_deriv = 3
      88             : 
      89          33 :    END SUBROUTINE cs1_lda_info
      90             : 
      91             : ! **************************************************************************************************
      92             : !> \brief return various information on the functional
      93             : !> \param reference string with the reference of the actual functional
      94             : !> \param shortform string with the shortform of the functional name
      95             : !> \param needs the components needed by this functional are set to
      96             : !>        true (does not set the unneeded components to false)
      97             : !> \param max_deriv ...
      98             : ! **************************************************************************************************
      99           0 :    SUBROUTINE cs1_lsd_info(reference, shortform, needs, max_deriv)
     100             :       CHARACTER(LEN=*), INTENT(OUT), OPTIONAL            :: reference, shortform
     101             :       TYPE(xc_rho_cflags_type), INTENT(inout), OPTIONAL  :: needs
     102             :       INTEGER, INTENT(out), OPTIONAL                     :: max_deriv
     103             : 
     104           0 :       IF (PRESENT(reference)) THEN
     105           0 :          reference = "N.C. Handy and A.J. Cohen, J. Chem. Phys., 116, 5411 (2002)"
     106             :       END IF
     107           0 :       IF (PRESENT(shortform)) THEN
     108           0 :          shortform = "CS1: Handy improved LYP correlation energy functional"
     109             :       END IF
     110           0 :       IF (PRESENT(needs)) THEN
     111           0 :          needs%rho_spin = .TRUE.
     112           0 :          needs%rho_spin_1_3 = .TRUE.
     113           0 :          needs%norm_drho_spin = .TRUE.
     114             :       END IF
     115           0 :       IF (PRESENT(max_deriv)) max_deriv = 1
     116             : 
     117           0 :    END SUBROUTINE cs1_lsd_info
     118             : 
     119             : ! **************************************************************************************************
     120             : !> \brief ...
     121             : !> \param cutoff ...
     122             : !> \param debug ...
     123             : ! **************************************************************************************************
     124          32 :    SUBROUTINE cs1_init(cutoff, debug)
     125             : 
     126             :       REAL(KIND=dp), INTENT(IN)                          :: cutoff
     127             :       LOGICAL, INTENT(IN), OPTIONAL                      :: debug
     128             : 
     129          32 :       eps_rho = cutoff
     130          32 :       CALL set_util(cutoff)
     131             : 
     132          32 :       IF (PRESENT(debug)) THEN
     133           0 :          debug_flag = debug
     134             :       ELSE
     135          32 :          debug_flag = .FALSE.
     136             :       END IF
     137             : 
     138          32 :       fsig = 2.0_dp**f13
     139             : 
     140          32 :    END SUBROUTINE cs1_init
     141             : 
     142             : ! **************************************************************************************************
     143             : !> \brief ...
     144             : !> \param rho_set ...
     145             : !> \param deriv_set ...
     146             : !> \param order ...
     147             : ! **************************************************************************************************
     148          64 :    SUBROUTINE cs1_lda_eval(rho_set, deriv_set, order)
     149             :       TYPE(xc_rho_set_type), INTENT(IN)                  :: rho_set
     150             :       TYPE(xc_derivative_set_type), INTENT(IN)           :: deriv_set
     151             :       INTEGER, INTENT(in)                                :: order
     152             : 
     153             :       CHARACTER(len=*), PARAMETER                        :: routineN = 'cs1_lda_eval'
     154             : 
     155             :       INTEGER                                            :: handle, m, npoints
     156             :       INTEGER, DIMENSION(2, 3)                           :: bo
     157             :       REAL(KIND=dp)                                      :: epsilon_rho
     158          32 :       REAL(KIND=dp), CONTIGUOUS, DIMENSION(:, :, :), POINTER :: e_0, e_ndrho, e_ndrho_ndrho, &
     159          32 :          e_ndrho_ndrho_ndrho, e_rho, e_rho_ndrho, e_rho_ndrho_ndrho, e_rho_rho, e_rho_rho_ndrho, &
     160          32 :          e_rho_rho_rho, grho, rho, rho13
     161             :       TYPE(xc_derivative_type), POINTER                  :: deriv
     162             : 
     163          32 :       CALL timeset(routineN, handle)
     164          32 :       NULLIFY (rho, rho13, grho, e_0, e_rho, e_ndrho, &
     165          32 :                e_rho_rho, e_rho_ndrho, e_ndrho_ndrho, &
     166          32 :                e_rho_rho_rho, e_rho_rho_ndrho, e_rho_ndrho_ndrho, &
     167          32 :                e_ndrho_ndrho_ndrho)
     168             : 
     169             :       CALL xc_rho_set_get(rho_set, rho_1_3=rho13, rho=rho, &
     170          32 :                           norm_drho=grho, local_bounds=bo, rho_cutoff=epsilon_rho)
     171          32 :       npoints = (bo(2, 1) - bo(1, 1) + 1)*(bo(2, 2) - bo(1, 2) + 1)*(bo(2, 3) - bo(1, 3) + 1)
     172          32 :       m = ABS(order)
     173          32 :       CALL cs1_init(epsilon_rho)
     174             : 
     175          32 :       IF (order >= 0) THEN
     176             :          deriv => xc_dset_get_derivative(deriv_set, [INTEGER::], &
     177          32 :                                          allocate_deriv=.TRUE.)
     178          32 :          CALL xc_derivative_get(deriv, deriv_data=e_0)
     179             : 
     180          32 :          CALL cs1_u_0(rho, grho, rho13, e_0, npoints)
     181             :       END IF
     182          32 :       IF (order >= 1 .OR. order == -1) THEN
     183             :          deriv => xc_dset_get_derivative(deriv_set, [deriv_rho], &
     184          32 :                                          allocate_deriv=.TRUE.)
     185          32 :          CALL xc_derivative_get(deriv, deriv_data=e_rho)
     186             :          deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drho], &
     187          32 :                                          allocate_deriv=.TRUE.)
     188          32 :          CALL xc_derivative_get(deriv, deriv_data=e_ndrho)
     189             : 
     190             :          CALL cs1_u_1(rho, grho, rho13, e_rho, e_ndrho, &
     191          32 :                       npoints)
     192             :       END IF
     193          32 :       IF (order >= 2 .OR. order == -2) THEN
     194             :          deriv => xc_dset_get_derivative(deriv_set, [deriv_rho, deriv_rho], &
     195           0 :                                          allocate_deriv=.TRUE.)
     196           0 :          CALL xc_derivative_get(deriv, deriv_data=e_rho_rho)
     197             :          deriv => xc_dset_get_derivative(deriv_set, [deriv_rho, deriv_norm_drho], &
     198           0 :                                          allocate_deriv=.TRUE.)
     199           0 :          CALL xc_derivative_get(deriv, deriv_data=e_rho_ndrho)
     200             :          deriv => xc_dset_get_derivative(deriv_set, &
     201           0 :                                          [deriv_norm_drho, deriv_norm_drho], allocate_deriv=.TRUE.)
     202           0 :          CALL xc_derivative_get(deriv, deriv_data=e_ndrho_ndrho)
     203             : 
     204             :          CALL cs1_u_2(rho, grho, rho13, e_rho_rho, e_rho_ndrho, &
     205           0 :                       e_ndrho_ndrho, npoints)
     206             :       END IF
     207          32 :       IF (order >= 3 .OR. order == -3) THEN
     208             :          deriv => xc_dset_get_derivative(deriv_set, [deriv_rho, deriv_rho, deriv_rho], &
     209           0 :                                          allocate_deriv=.TRUE.)
     210           0 :          CALL xc_derivative_get(deriv, deriv_data=e_rho_rho_rho)
     211             :          deriv => xc_dset_get_derivative(deriv_set, &
     212           0 :                                          [deriv_rho, deriv_rho, deriv_norm_drho], allocate_deriv=.TRUE.)
     213           0 :          CALL xc_derivative_get(deriv, deriv_data=e_rho_rho_ndrho)
     214             :          deriv => xc_dset_get_derivative(deriv_set, &
     215           0 :                                          [deriv_rho, deriv_norm_drho, deriv_norm_drho], allocate_deriv=.TRUE.)
     216           0 :          CALL xc_derivative_get(deriv, deriv_data=e_rho_ndrho_ndrho)
     217             :          deriv => xc_dset_get_derivative(deriv_set, &
     218           0 :                                          [deriv_norm_drho, deriv_norm_drho, deriv_norm_drho], allocate_deriv=.TRUE.)
     219           0 :          CALL xc_derivative_get(deriv, deriv_data=e_ndrho_ndrho_ndrho)
     220             : 
     221             :          CALL cs1_u_3(rho, grho, rho13, e_rho_rho_rho, e_rho_rho_ndrho, &
     222           0 :                       e_rho_ndrho_ndrho, e_ndrho_ndrho_ndrho, npoints)
     223             :       END IF
     224          32 :       IF (order > 3 .OR. order < -3) THEN
     225           0 :          CPABORT("derivatives bigger than 3 not implemented")
     226             :       END IF
     227             : 
     228          32 :       CALL timestop(handle)
     229          32 :    END SUBROUTINE cs1_lda_eval
     230             : 
     231             : ! **************************************************************************************************
     232             : !> \brief ...
     233             : !> \param rho_set ...
     234             : !> \param deriv_set ...
     235             : !> \param order ...
     236             : ! **************************************************************************************************
     237           0 :    SUBROUTINE cs1_lsd_eval(rho_set, deriv_set, order)
     238             :       TYPE(xc_rho_set_type), INTENT(IN)                  :: rho_set
     239             :       TYPE(xc_derivative_set_type), INTENT(IN)           :: deriv_set
     240             :       INTEGER, INTENT(in)                                :: order
     241             : 
     242             :       CHARACTER(len=*), PARAMETER                        :: routineN = 'cs1_lsd_eval'
     243             : 
     244             :       INTEGER                                            :: handle, npoints
     245             :       INTEGER, DIMENSION(2, 3)                           :: bo
     246             :       REAL(KIND=dp)                                      :: epsilon_rho
     247             :       REAL(KIND=dp), CONTIGUOUS, DIMENSION(:, :, :), &
     248           0 :          POINTER                                         :: e_0, e_ndrhoa, e_ndrhob, e_rhoa, e_rhob, &
     249           0 :                                                             norm_drhoa, norm_drhob, rhoa, &
     250           0 :                                                             rhoa_1_3, rhob, rhob_1_3
     251             :       TYPE(xc_derivative_type), POINTER                  :: deriv
     252             : 
     253           0 :       CALL timeset(routineN, handle)
     254             : 
     255             :       CALL xc_rho_set_get(rho_set, rhoa=rhoa, rhob=rhob, &
     256             :                           rhoa_1_3=rhoa_1_3, rhob_1_3=rhob_1_3, &
     257             :                           norm_drhoa=norm_drhoa, norm_drhob=norm_drhob, &
     258           0 :                           local_bounds=bo, rho_cutoff=epsilon_rho)
     259           0 :       npoints = (bo(2, 1) - bo(1, 1) + 1)*(bo(2, 2) - bo(1, 2) + 1)*(bo(2, 3) - bo(1, 3) + 1)
     260           0 :       CALL cs1_init(epsilon_rho)
     261             : 
     262           0 :       IF (order >= 0) THEN
     263             :          deriv => xc_dset_get_derivative(deriv_set, [INTEGER::], &
     264           0 :                                          allocate_deriv=.TRUE.)
     265           0 :          CALL xc_derivative_get(deriv, deriv_data=e_0)
     266             : 
     267             :          CALL cs1_ss_0(rhoa, rhob, norm_drhoa, norm_drhob, &
     268           0 :                        rhoa_1_3, rhob_1_3, e_0, npoints)
     269             :       END IF
     270           0 :       IF (order >= 1 .OR. order == -1) THEN
     271             :          deriv => xc_dset_get_derivative(deriv_set, [deriv_rhoa], &
     272           0 :                                          allocate_deriv=.TRUE.)
     273           0 :          CALL xc_derivative_get(deriv, deriv_data=e_rhoa)
     274             :          deriv => xc_dset_get_derivative(deriv_set, [deriv_rhob], &
     275           0 :                                          allocate_deriv=.TRUE.)
     276           0 :          CALL xc_derivative_get(deriv, deriv_data=e_rhob)
     277             :          deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa], &
     278           0 :                                          allocate_deriv=.TRUE.)
     279           0 :          CALL xc_derivative_get(deriv, deriv_data=e_ndrhoa)
     280             :          deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drhob], &
     281           0 :                                          allocate_deriv=.TRUE.)
     282           0 :          CALL xc_derivative_get(deriv, deriv_data=e_ndrhob)
     283             : 
     284             :          CALL cs1_ss_1(rhoa, rhob, norm_drhoa, norm_drhob, &
     285             :                        rhoa_1_3, rhob_1_3, e_rhoa, e_rhob, e_ndrhoa, e_ndrhob, &
     286           0 :                        npoints)
     287             :       END IF
     288           0 :       IF (order > 1 .OR. order < 1) THEN
     289           0 :          CPABORT("derivatives bigger than 3 not implemented")
     290             :       END IF
     291           0 :       CALL timestop(handle)
     292           0 :    END SUBROUTINE cs1_lsd_eval
     293             : 
     294             : ! **************************************************************************************************
     295             : !> \brief ...
     296             : !> \param rho ...
     297             : !> \param grho ...
     298             : !> \param r13 ...
     299             : !> \param e_0 ...
     300             : !> \param npoints ...
     301             : ! **************************************************************************************************
     302          32 :    SUBROUTINE cs1_u_0(rho, grho, r13, e_0, npoints)
     303             : 
     304             :       REAL(KIND=dp), DIMENSION(*), INTENT(IN)            :: rho, grho, r13
     305             :       REAL(KIND=dp), DIMENSION(*), INTENT(INOUT)         :: e_0
     306             :       INTEGER, INTENT(in)                                :: npoints
     307             : 
     308             :       INTEGER                                            :: ip
     309             :       REAL(KIND=dp)                                      :: c2p, c3p, c4p, cp, dpv, F1, F2, F3, F4, &
     310             :                                                             g, oc, ocp, od, odp, r, r3, x
     311             : 
     312          32 :       dpv = fsig*d
     313          32 :       cp = c*fsig*fsig
     314          32 :       c2p = c2*fsig**4
     315          32 :       c3p = -c3*0.25_dp
     316          32 :       c4p = -c4*0.25_dp
     317             : 
     318             : !$OMP     PARALLEL DO DEFAULT(NONE) &
     319             : !$OMP                 SHARED(npoints,rho,eps_rho,e_0,dpv,cp,c2p,c3p,c4p,r13,grho) &
     320          32 : !$OMP                 PRIVATE(ip,r,r3,g,x,odp,ocp,od,oc,f1,f2,f3,f4)
     321             : 
     322             :       DO ip = 1, npoints
     323             : 
     324             :          IF (rho(ip) > eps_rho) THEN
     325             :             r = rho(ip)
     326             :             r3 = r13(ip)
     327             :             g = grho(ip)
     328             :             x = g/(r*r3)
     329             :             odp = 1.0_dp/(r3 + dpv)
     330             :             ocp = 1.0_dp/(r*r*r3*r3 + cp*g*g)
     331             :             od = 1.0_dp/(r3 + d)
     332             :             oc = 1.0_dp/(r*r*r3*r3 + c*g*g)
     333             :             F1 = c1*r*r3*odp
     334             :             F2 = c2p*g**4*r3*r*odp*ocp*ocp
     335             :             F3 = c3p*r*r3*od
     336             :             F4 = c4p*g**4*r3*r*od*oc*oc
     337             :             e_0(ip) = e_0(ip) + F1 + F2 + F3 + F4
     338             :          END IF
     339             : 
     340             :       END DO
     341             : 
     342             : !$OMP     END PARALLEL DO
     343             : 
     344          32 :    END SUBROUTINE cs1_u_0
     345             : 
     346             : ! **************************************************************************************************
     347             : !> \brief ...
     348             : !> \param rho ...
     349             : !> \param grho ...
     350             : !> \param r13 ...
     351             : !> \param e_rho ...
     352             : !> \param e_ndrho ...
     353             : !> \param npoints ...
     354             : ! **************************************************************************************************
     355          32 :    SUBROUTINE cs1_u_1(rho, grho, r13, e_rho, e_ndrho, npoints)
     356             : 
     357             :       REAL(KIND=dp), DIMENSION(*), INTENT(IN)            :: rho, grho, r13
     358             :       REAL(KIND=dp), DIMENSION(*), INTENT(INOUT)         :: e_rho, e_ndrho
     359             :       INTEGER, INTENT(in)                                :: npoints
     360             : 
     361             :       INTEGER                                            :: ip
     362             :       REAL(KIND=dp)                                      :: c2p, c3p, c4p, cp, dF1, dF3, dgF2, dgF4, &
     363             :                                                             dpv, drF2, drF4, g, oc, ocp, od, odp, &
     364             :                                                             r, r3
     365             : 
     366          32 :       dpv = fsig*d
     367          32 :       cp = c*fsig*fsig
     368          32 :       c2p = c2*fsig**4
     369          32 :       c3p = -c3*0.25_dp
     370          32 :       c4p = -c4*0.25_dp
     371             : 
     372             : !$OMP     PARALLEL DO DEFAULT(NONE) &
     373             : !$OMP                 SHARED(npoints, rho, eps_rho, r13, grho, e_rho) &
     374             : !$OMP                 SHARED(e_ndrho, dpv, cp, c2p, c3p, c4p) &
     375             : !$OMP                 PRIVATE(ip, r, r3, g, odp, ocp, od, oc, df1) &
     376          32 : !$OMP                 PRIVATE(drf2, dgf2, df3, drf4, dgf4)
     377             : 
     378             :       DO ip = 1, npoints
     379             : 
     380             :          IF (rho(ip) > eps_rho) THEN
     381             :             r = rho(ip)
     382             :             r3 = r13(ip)
     383             :             g = grho(ip)
     384             :             odp = 1.0_dp/(r3 + dpv)
     385             :             ocp = 1.0_dp/(r*r*r3*r3 + cp*g*g)
     386             :             od = 1.0_dp/(r3 + d)
     387             :             oc = 1.0_dp/(r*r*r3*r3 + c*g*g)
     388             :             dF1 = c1*f13*r3*(3*r3 + 4*dpv)*odp*odp
     389             :             drF2 = -f13*c2p*g**4*r3*(13*r**3 - 3*r3*cp*g*g + 12*r*r*r3*r3*dpv - &
     390             :                                      4*dpv*cp*g*g)*odp**2*ocp**3
     391             :             dgF2 = 4*c2p*g**3*r**4*odp*ocp**3
     392             :             dF3 = f13*r3*c3p*(3*r3 + 4*d)*od*od
     393             :             drF4 = -f13*c4p*g**4*r3*(13*r**3 - 3*r3*c*g*g + 12*r*r*r3*r3*d - &
     394             :                                      4*d*c*g*g)*od**2*oc**3
     395             :             dgF4 = 4*c4p*g**3*r**4*od*oc**3
     396             :             e_rho(ip) = e_rho(ip) + dF1 + drF2 + dF3 + drF4
     397             :             e_ndrho(ip) = e_ndrho(ip) + dgF2 + dgF4
     398             :          END IF
     399             : 
     400             :       END DO
     401             : 
     402             : !$OMP     END PARALLEL DO
     403             : 
     404          32 :    END SUBROUTINE cs1_u_1
     405             : 
     406             : ! **************************************************************************************************
     407             : !> \brief ...
     408             : !> \param rho ...
     409             : !> \param grho ...
     410             : !> \param r13 ...
     411             : !> \param e_rho_rho ...
     412             : !> \param e_rho_ndrho ...
     413             : !> \param e_ndrho_ndrho ...
     414             : !> \param npoints ...
     415             : ! **************************************************************************************************
     416           0 :    SUBROUTINE cs1_u_2(rho, grho, r13, e_rho_rho, e_rho_ndrho, e_ndrho_ndrho, &
     417             :                       npoints)
     418             : 
     419             :       REAL(KIND=dp), DIMENSION(*), INTENT(IN)            :: rho, grho, r13
     420             :       REAL(KIND=dp), DIMENSION(*), INTENT(INOUT)         :: e_rho_rho, e_rho_ndrho, e_ndrho_ndrho
     421             :       INTEGER, INTENT(in)                                :: npoints
     422             : 
     423             :       INTEGER                                            :: ip
     424             :       REAL(KIND=dp)                                      :: c2p, c3p, c4p, cp, d2F1, d2F3, d2gF2, &
     425             :                                                             d2gF4, d2rF2, d2rF4, dpv, drgF2, &
     426             :                                                             drgF4, g, oc, ocp, od, odp, r, r3
     427             : 
     428           0 :       dpv = fsig*d
     429           0 :       cp = c*fsig*fsig
     430           0 :       c2p = c2*fsig**4
     431           0 :       c3p = -c3*0.25_dp
     432           0 :       c4p = -c4*0.25_dp
     433             : 
     434             : !$OMP     PARALLEL DO DEFAULT(NONE) &
     435             : !$OMP                 SHARED(npoints, rho, eps_rho, r13, grho, e_rho_rho) &
     436             : !$OMP                 SHARED(e_rho_ndrho, e_ndrho_ndrho, dpv, cp, c2p, c3p, c4p) &
     437             : !$OMP                 PRIVATE(ip,r,r3,g,odp,ocp,od,oc,d2f1,d2rf2,drgf2,d2f3) &
     438           0 : !$OMP                 PRIVATE(d2rf4,drgf4,d2gf2,d2gf4)
     439             : 
     440             :       DO ip = 1, npoints
     441             : 
     442             :          IF (rho(ip) > eps_rho) THEN
     443             :             r = rho(ip)
     444             :             r3 = r13(ip)
     445             :             g = grho(ip)
     446             :             odp = 1.0_dp/(r3 + dpv)
     447             :             ocp = 1.0_dp/(r*r*r3*r3 + cp*g*g)
     448             :             od = 1.0_dp/(r3 + d)
     449             :             oc = 1.0_dp/(r*r*r3*r3 + c*g*g)
     450             :             d2F1 = c1*f23*f13*dpv*r3/r*(r3 + 2*dpv)*odp**3
     451             :             d2rF2 = c2p*f13*f23*g**4*r3/r*(193*dpv*r**5*r3*r3 + 90*dpv*dpv*r**5*r3 &
     452             :                                            - 88*g*g*cp*r**3*r3 - 100*dpv*dpv*cp*g*g*r*r*r3*r3 &
     453             :                                            + 2*dpv*dpv*cp*cp*g**4 - 190*g*g*r**3*cp*dpv + g**4*r3*cp*cp*dpv &
     454             :                                            + 104*r**6)*odp**3*ocp**4
     455             :             drgF2 = c2p*f43*g**3*r*r*r3*(-13*r**3*r3*r3 + 11*cp*r*g*g - 12*dpv*r**3*r3 &
     456             :                                          + 12*r3*r3*dpv*cp*g*g)*odp*odp*ocp**4
     457             :             d2gF2 = -12*c2p*g*g*r**4*(cp*g*g - r*r*r3*r3)*odp*ocp**4
     458             :             d2F3 = f13*f23*c3p*d*r3/r*(r3 + 2*d)*od**3
     459             :             d2rF4 = c4p*f13*f23*g**4*r3/r*(193*d*r**5*r3*r3 + 90*d*d*r**5*r3 &
     460             :                                            - 88*g*g*c*r**3*r3 - 100*d*d*c*g*g*r*r*r3*r3 &
     461             :                                            + 2*d*d*c*c*g**4 - 190*g*g*r**3*c*d + g**4*r3*c*c*d &
     462             :                                            + 104*r**6)*od**3*oc**4
     463             :             drgF4 = c4p*f43*g**3*r*r*r3*(-13*r**3*r3*r3 + 11*c*r*g*g - 12*d*r**3*r3 &
     464             :                                          + 12*r3*r3*d*c*g*g)*od*od*oc**4
     465             :             d2gF4 = -12*c4p*g*g*r**4*(c*g*g - r*r*r3*r3)*od*oc**4
     466             :             e_rho_rho(ip) = e_rho_rho(ip) + d2F1 + d2rF2 + d2F3 + d2rF4
     467             :             e_rho_ndrho(ip) = e_rho_ndrho(ip) + drgF2 + drgF4
     468             :             e_ndrho_ndrho(ip) = e_ndrho_ndrho(ip) + d2gF2 + d2gF4
     469             :          END IF
     470             : 
     471             :       END DO
     472             : 
     473             : !$OMP     END PARALLEL DO
     474             : 
     475           0 :    END SUBROUTINE cs1_u_2
     476             : 
     477             : ! **************************************************************************************************
     478             : !> \brief ...
     479             : !> \param rho ...
     480             : !> \param grho ...
     481             : !> \param r13 ...
     482             : !> \param e_rho_rho_rho ...
     483             : !> \param e_rho_rho_ndrho ...
     484             : !> \param e_rho_ndrho_ndrho ...
     485             : !> \param e_ndrho_ndrho_ndrho ...
     486             : !> \param npoints ...
     487             : ! **************************************************************************************************
     488           0 :    SUBROUTINE cs1_u_3(rho, grho, r13, e_rho_rho_rho, e_rho_rho_ndrho, &
     489             :                       e_rho_ndrho_ndrho, e_ndrho_ndrho_ndrho, npoints)
     490             : 
     491             :       REAL(KIND=dp), DIMENSION(*), INTENT(IN)            :: rho, grho, r13
     492             :       REAL(KIND=dp), DIMENSION(*), INTENT(INOUT)         :: e_rho_rho_rho, e_rho_rho_ndrho, &
     493             :                                                             e_rho_ndrho_ndrho, e_ndrho_ndrho_ndrho
     494             :       INTEGER, INTENT(in)                                :: npoints
     495             : 
     496             :       INTEGER                                            :: ip
     497             :       REAL(KIND=dp) :: c2p, c3p, c4p, cp, d2rgF2, d2rgF4, d3F1, d3F3, d3gF2, d3gF4, d3rF2, d3rF4, &
     498             :          dpv, dr2gF2, dr2gF4, g, oc, ocp, od, odp, r, r3, t1, t10, t11, t13, t15, t16, t17, t19, &
     499             :          t2, t22, t23, t26, t29, t3, t32, t33, t37, t4, t44, t45, t50, t51, t52, t58, t6, t61, t7, &
     500             :          t74, t76, t77, t8, t80, t81, t82, t9
     501             : 
     502           0 :       dpv = fsig*d
     503           0 :       cp = c*fsig*fsig
     504           0 :       c2p = c2*fsig**4
     505           0 :       c3p = -c3*0.25_dp
     506           0 :       c4p = -c4*0.25_dp
     507             : 
     508             : !$OMP     PARALLEL DO DEFAULT(NONE) &
     509             : !$OMP                 SHARED(npoints, rho, eps_rho, r13, grho, e_rho_rho_rho) &
     510             : !$OMP                 SHARED(e_rho_rho_ndrho, e_rho_ndrho_ndrho) &
     511             : !$OMP                 SHARED(e_ndrho_ndrho_ndrho, dpv, cp, c2p, c3p, c4p) &
     512             : !$OMP                 PRIVATE(ip,r,r3,g,odp,ocp,od,oc,d3f1,d3rF2,d2rgF2) &
     513             : !$OMP                 PRIVATE(dr2gF2,d3gF2,d3F3,d3rF4,d2rgF4,dr2gF4,d3gF4) &
     514             : !$OMP                 PRIVATE(t1, t2, t3, t4, t6, t7, t8, t9, t10, t11, t13) &
     515             : !$OMP                 PRIVATE(t15, t16, t17, t19, t22, t23, t26, t29, t32) &
     516             : !$OMP                 PRIVATE(t33, t37, t44, t45, t50, t51, t52, t58, t61) &
     517           0 : !$OMP                 PRIVATE(t74, t76, t77, t80, t81, t82)
     518             : 
     519             :       DO ip = 1, npoints
     520             : 
     521             :          IF (rho(ip) > eps_rho) THEN
     522             :             r = rho(ip)
     523             :             r3 = r13(ip)
     524             :             g = grho(ip)
     525             :             odp = 1.0_dp/(r3 + dpv)
     526             :             ocp = 1.0_dp/(r*r*r3*r3 + cp*g*g)
     527             :             od = 1.0_dp/(r3 + d)
     528             :             oc = 1.0_dp/(r*r*r3*r3 + c*g*g)
     529             :             d3F1 = -c1*f23*f13*f13*dpv*r3/(r*r)*(11*dpv*r3 + 4*dpv*dpv + 4*r/r3)*odp**4
     530             :             t1 = g**2; t2 = t1**2; t3 = r3; t4 = t3**2; t8 = dpv**2; t9 = t8*dpv
     531             :             t10 = cp**2; t11 = t10*cp; t13 = t2*t1; t16 = r**2; t17 = t4*t16
     532             :             t19 = t10*t2; t22 = t16**2; t23 = t22**2; t32 = t22*t16; t37 = t16*r
     533             :             t58 = t22*r; t61 = cp*t1
     534             :             t74 = 4*t9*t11*t13 + 668*t17*t9*t19 + 5524*t4*t23*dpv + 5171*t3*t23*t8 + &
     535             :                   1620*t23*t9 - 3728*t3*t32*cp*t1 + 440*t4*t37*t10*t2 + 1500*t2*t3*t37*dpv*t10 &
     536             :                   + 4*t13*t4*dpv*t11 + 1737*t37*t8*t19 + 11*t3*t8*t11*t13 - 3860*t3*t58*t9*t61 + &
     537             :                   1976*t23*r - 11535*t4*t58*t8*t61 - 11412*t1*t32*cp*dpv
     538             :             t76 = (t3 + dpv)**2; t77 = t76**2; t80 = t17 + t61; t81 = t80**2; t82 = t81**2
     539             :             d3rF2 = -f23*f13*f13*c2p*t2/t4/r*t74/t77/t82/t80
     540             :             t4 = t3*r; t6 = r**2; t7 = t6**2; t8 = t7*t6; t9 = dpv**2; t15 = t1**2
     541             :             t17 = cp**2; t23 = t3**2; t26 = t6*r; t29 = cp*t1; t33 = t17*t15; t44 = t3 + dpv
     542             :             t45 = t44**2; t50 = t23*t6 + t29; t51 = t50**2; t52 = t51**2
     543             :             d2rgF2 = c2p*f23*f43*t1*g*t4*(90*t8*t9 + 193*t3*t8*dpv + 44*t15*t4*t17 - 236*t1 &
     544             :                                           *t7*cp + 104*t23*t8 - 240*t3*t26*t9*t29 + 54*t23*t9*t33 - 478*t23*t26*dpv*t29 &
     545             :                                           + 97*r*dpv*t33)/t45/t44/t52/t50
     546             :             dr2gF2 = -4*c2p*g*g*r*r*r3*(-40*r**3*r3*dpv*cp*g*g + 12*r3*r3*dpv*cp*cp*g**4 &
     547             :                                         + 13*r**6*r3 - 40*r**3*r3*r3*cp*g*g + 11*r*cp*cp*g**4 + 12*r**6*dpv) &
     548             :                      *odp*odp*ocp**5
     549             :             d3gF2 = c2p*24*g*r**3*r3*(r**6 - 5*cp*g*g*r**3*r3 + 2*cp*cp*g**4*r3*r3)*odp*ocp**5
     550             :             d3F3 = -f23*f13*f13*c3p*d*r3/(r*r)*(11*d*r3 + 4*d*d + 4*r3*r3)*od**4
     551             :             t1 = g**2; t2 = t1**2; t3 = r3; t4 = t3**2; t8 = d**2; t9 = t8*d
     552             :             t10 = c**2; t11 = t10*c; t13 = t2*t1; t16 = r**2; t17 = t4*t16
     553             :             t19 = t10*t2; t22 = t16**2; t23 = t22**2; t32 = t22*t16; t37 = t16*r
     554             :             t58 = t22*r; t61 = c*t1
     555             :             t74 = 4*t9*t11*t13 + 668*t17*t9*t19 + 5524*t4*t23*d + 5171*t3*t23*t8 + &
     556             :                   1620*t23*t9 - 3728*t3*t32*c*t1 + 440*t4*t37*t10*t2 + 1500*t2*t3*t37*d*t10 &
     557             :                   + 4*t13*t4*d*t11 + 1737*t37*t8*t19 + 11*t3*t8*t11*t13 - 3860*t3*t58*t9*t61 + &
     558             :                   1976*t23*r - 11535*t4*t58*t8*t61 - 11412*t1*t32*c*d
     559             :             t76 = (t3 + d)**2; t77 = t76**2; t80 = t17 + t61; t81 = t80**2; t82 = t81**2
     560             :             d3rF4 = -f23*f13*f13*c4p*t2/t4/r*t74/t77/t82/t80
     561             :             t4 = t3*r; t6 = r**2; t7 = t6**2; t8 = t7*t6; t9 = d**2; t15 = t1**2
     562             :             t17 = c**2; t23 = t3**2; t26 = t6*r; t29 = c*t1; t33 = t17*t15; t44 = t3 + d
     563             :             t45 = t44**2; t50 = t23*t6 + t29; t51 = t50**2; t52 = t51**2
     564             :             d2rgF4 = c4p*f23*f43*t1*g*t4*(90*t8*t9 + 193*t3*t8*d + 44*t15*t4*t17 - 236*t1 &
     565             :                                           *t7*c + 104*t23*t8 - 240*t3*t26*t9*t29 + 54*t23*t9*t33 - 478*t23*t26*d*t29 &
     566             :                                           + 97*r*d*t33)/t45/t44/t52/t50
     567             :             dr2gF4 = -4*c4p*g*g*r*r*r3*(-40*r**3*r3*d*c*g*g + 12*r3*r3*d*c*c*g**4 &
     568             :                                         + 13*r**6*r3 - 40*r**3*r3*r3*c*g*g + 11*r*c*c*g**4 + 12*r**6*d) &
     569             :                      *od*od*oc**5
     570             :             d3gF4 = c4p*24*g*r**3*r3*(r**6 - 5*c*g*g*r**3*r3 + 2*c*c*g**4*r3*r3)*od*oc**5
     571             :             e_rho_rho_rho(ip) = e_rho_rho_rho(ip) + d3F1 + d3rF2 + d3F3 + d3rF4
     572             :             e_rho_rho_ndrho(ip) = e_rho_rho_ndrho(ip) + d2rgF2 + d2rgF4
     573             :             e_rho_ndrho_ndrho(ip) = e_rho_ndrho_ndrho(ip) + dr2gF2 + dr2gF4
     574             :             e_ndrho_ndrho_ndrho(ip) = e_ndrho_ndrho_ndrho(ip) + d3gF2 + d3gF4
     575             :          END IF
     576             : 
     577             :       END DO
     578             : 
     579             : !$OMP     END PARALLEL DO
     580             : 
     581           0 :    END SUBROUTINE cs1_u_3
     582             : 
     583             : ! **************************************************************************************************
     584             : !> \brief ...
     585             : !> \param rhoa ...
     586             : !> \param rhob ...
     587             : !> \param grhoa ...
     588             : !> \param grhob ...
     589             : !> \param r13a ...
     590             : !> \param r13b ...
     591             : !> \param e_0 ...
     592             : !> \param npoints ...
     593             : ! **************************************************************************************************
     594           0 :    SUBROUTINE cs1_ss_0(rhoa, rhob, grhoa, grhob, r13a, r13b, e_0, &
     595             :                        npoints)
     596             : 
     597             :       REAL(KIND=dp), DIMENSION(*), INTENT(IN)            :: rhoa, rhob, grhoa, grhob, r13a, r13b
     598             :       REAL(KIND=dp), DIMENSION(*), INTENT(INOUT)         :: e_0
     599             :       INTEGER, INTENT(in)                                :: npoints
     600             : 
     601             :       INTEGER                                            :: ip
     602             :       REAL(KIND=dp)                                      :: F1a, F1b, F2a, F2b, ga, gb, oca, ocb, &
     603             :                                                             oda, odb, r3a, r3b, ra, rb, xa, xb
     604             : 
     605             : !FM IF ( .NOT. debug_flag ) CPABORT("Routine not tested")
     606             : 
     607           0 :       CPWARN("not tested!")
     608             : 
     609             : !$OMP     PARALLEL DO DEFAULT(NONE) &
     610             : !$OMP                 SHARED(npoints, rhoa, eps_rho, r13a, grhoa, rhob) &
     611             : !$OMP                 SHARED(r13b, grhob, e_0) &
     612             : !$OMP                 PRIVATE(ip, f1a, f2a, ra, r3a, ga, xa, oda, oca) &
     613           0 : !$OMP                 PRIVATE(    f1b, f2b, rb, r3b, gb, xb, odb, ocb)
     614             : 
     615             :       DO ip = 1, npoints
     616             : 
     617             :          IF (rhoa(ip) < eps_rho) THEN
     618             :             F1a = 0.0_dp
     619             :             F2a = 0.0_dp
     620             :          ELSE
     621             :             ra = rhoa(ip)
     622             :             r3a = r13a(ip)
     623             :             ga = grhoa(ip)
     624             :             xa = ga/(ra*r3a)
     625             :             oda = 1.0_dp/(r3a + d)
     626             :             oca = 1.0_dp/(ra*ra*r3a*r3a + c*ga*ga)
     627             :             F1a = c1*ra*r3a*oda
     628             :             F2a = c2*ga**4*r3a*ra*oda*oca*oca
     629             :          END IF
     630             :          IF (rhob(ip) < eps_rho) THEN
     631             :             F1b = 0.0_dp
     632             :             F2b = 0.0_dp
     633             :          ELSE
     634             :             rb = rhob(ip)
     635             :             r3b = r13b(ip)
     636             :             gb = grhob(ip)
     637             :             xb = gb/(rb*r3b)
     638             :             odb = 1.0_dp/(r3b + d)
     639             :             ocb = 1.0_dp/(rb*rb*r3b*r3b + c*gb*gb)
     640             :             F1b = c1*rb*r3b*odb
     641             :             F2b = c2*gb**4*r3b*rb*odb*ocb*ocb
     642             :          END IF
     643             : 
     644             :          e_0(ip) = e_0(ip) + F1a + F1b + F2a + F2b
     645             : 
     646             :       END DO
     647             : 
     648             : !$OMP     END PARALLEL DO
     649             : 
     650           0 :    END SUBROUTINE cs1_ss_0
     651             : 
     652             : ! **************************************************************************************************
     653             : !> \brief ...
     654             : !> \param rhoa ...
     655             : !> \param rhob ...
     656             : !> \param grhoa ...
     657             : !> \param grhob ...
     658             : !> \param r13a ...
     659             : !> \param r13b ...
     660             : !> \param e_rhoa ...
     661             : !> \param e_rhob ...
     662             : !> \param e_ndrhoa ...
     663             : !> \param e_ndrhob ...
     664             : !> \param npoints ...
     665             : ! **************************************************************************************************
     666           0 :    SUBROUTINE cs1_ss_1(rhoa, rhob, grhoa, grhob, r13a, r13b, e_rhoa, &
     667             :                        e_rhob, e_ndrhoa, e_ndrhob, npoints)
     668             : 
     669             :       REAL(KIND=dp), DIMENSION(*), INTENT(IN)            :: rhoa, rhob, grhoa, grhob, r13a, r13b
     670             :       REAL(KIND=dp), DIMENSION(*), INTENT(INOUT)         :: e_rhoa, e_rhob, e_ndrhoa, e_ndrhob
     671             :       INTEGER, INTENT(in)                                :: npoints
     672             : 
     673             :       INTEGER                                            :: ip
     674             :       REAL(KIND=dp)                                      :: dF1a, dF1b, dgF2a, dgF2b, drF2a, drF2b, &
     675             :                                                             ga, gb, oca, ocb, oda, odb, r3a, r3b, &
     676             :                                                             ra, rb
     677             : 
     678           0 :       CPWARN("not tested!")
     679             : 
     680             : !$OMP     PARALLEL DO DEFAULT(NONE) &
     681             : !$OMP                 SHARED(npoints, rhoa, eps_rho, r13a, grhoa, rhob) &
     682             : !$OMP                 SHARED(grhob, e_rhoa, e_ndrhoa, e_rhob, e_ndrhob,r13b) &
     683             : !$OMP                 PRIVATE(ip, df1a, drf2a, dgf2a, ra, r3a, ga, oda, oca) &
     684           0 : !$OMP                 PRIVATE(    df1b, drf2b, dgf2b, rb, r3b, gb, odb, ocb)
     685             : 
     686             :       DO ip = 1, npoints
     687             : 
     688             :          IF (rhoa(ip) < eps_rho) THEN
     689             :             dF1a = 0.0_dp
     690             :             drF2a = 0.0_dp
     691             :             dgF2a = 0.0_dp
     692             :          ELSE
     693             :             ra = rhoa(ip)
     694             :             r3a = r13a(ip)
     695             :             ga = grhoa(ip)
     696             :             oda = 1.0_dp/(r3a + d)
     697             :             oca = 1.0_dp/(ra*ra*r3a*r3a + c*ga*ga)
     698             :             dF1a = c1*f13*r3a*(3*r3a + 4*d)*oda*oda
     699             : 
     700             :             drF2a = -f13*c2*ga**4*r3a*(13*ra**3 - 3*r3a*c*ga*ga + 12*ra*ra*r3a*r3a*d - &
     701             :                                        4*d*c*ga*ga)*oda**2*oca**3
     702             : 
     703             :             dgF2a = 4*c2*ga**3*ra**4*oda*oca**3
     704             : 
     705             :          END IF
     706             :          IF (rhob(ip) < eps_rho) THEN
     707             :             dF1b = 0.0_dp
     708             :             drF2b = 0.0_dp
     709             :             dgF2b = 0.0_dp
     710             :          ELSE
     711             :             rb = rhob(ip)
     712             :             r3b = r13b(ip)
     713             :             gb = grhob(ip)
     714             :             odb = 1.0_dp/(r3b + d)
     715             :             ocb = 1.0_dp/(rb*rb*r3b*r3b + c*gb*gb)
     716             :             dF1b = c1*f13*r3b*(3*r3b + 4*d)*odb*odb
     717             : 
     718             :             drF2b = -f13*c2*gb**4*r3b*(13*rb**3 - 3*r3b*c*gb*gb + 12*rb*rb*r3b*r3b*d - &
     719             :                                        4*d*c*gb*gb)*odb**2*ocb**3
     720             : 
     721             :             dgF2b = 4*c2*gb**3*rb**4*odb*ocb**3
     722             : 
     723             :          END IF
     724             : 
     725             :          e_rhoa(ip) = e_rhoa(ip) + dF1a + drF2a
     726             :          e_ndrhoa(ip) = e_ndrhoa(ip) + dgF2a
     727             :          e_rhob(ip) = e_rhob(ip) + dF1b + drF2b
     728             :          e_ndrhob(ip) = e_ndrhob(ip) + dgF2b
     729             : 
     730             :       END DO
     731             : 
     732             : !$OMP     END PARALLEL DO
     733             : 
     734           0 :    END SUBROUTINE cs1_ss_1
     735             : 
     736             : END MODULE xc_cs1
     737             : 

Generated by: LCOV version 1.15