Merge lp:~alesster/siesta/trunk_new_xc into lp:siesta

Proposed by Aleksandr V. Terentjev
Status: Needs review
Proposed branch: lp:~alesster/siesta/trunk_new_xc
Merge into: lp:siesta
Diff against target: 3150 lines (+2957/-16)
7 files modified
Docs/siesta.tex (+17/-0)
Src/SiestaXC/ggaxc.f (+270/-5)
Src/SiestaXC/vdwxc.F90 (+136/-6)
Src/SiestaXC/vv_vdwxc.F90 (+2517/-0)
Src/atom.F (+13/-2)
Tests/Makefile (+3/-2)
version.info (+1/-1)
To merge this branch: bzr merge lp:~alesster/siesta/trunk_new_xc
Reviewer Review Type Date Requested Status
Siesta Maintainers Pending
Review via email: mp+372423@code.launchpad.net

Description of the change

There were realized 4 new functionals:
SG4, GGA functional, keyword for XC.authors in fdf: SG4, sg4
Ref. L. A. Constantin et al, Phys. Rev. B 93, 045126 (2016)

SG4+VV10m, VDW functional, keyword for XC.authors in fdf: SG4VV, sg4vv
Ref. A. V. Terentjev et al, Computation 6, 7 (2018)

PBE+VV10, VDW functional, keyword for XC.authors in fdf: PBEVV, pbevv, PBEvv, pbeVV
Ref. H. Peng and J. P. Perdew, Phys. Rev. B 95, 0811105 (2017)

PBEsol+VV10s, VDW functional, keyword for XC.authors in fdf: PVESVVS, pbesvvs, PBESVVs, PBESvvs
Ref. A. V. Terentjev et al, Phys. Rev. B 98, 214108 (2018)

IMPORTANT NOTES:
During the testing two test examples were crashed with version 781:
h2o_filteret_basis and si001-diags

With new version 782 all tests were finished successfully exepting h2o_filteret_basis and si001-diags.

Check has shown the differences bwtween tested and refrenced output files. But it also gives the differences for the previous version 781.

To post a comment you must log in.
Revision history for this message
Alberto Garcia (albertog) wrote :

Sorry about the delay in handling your merge request for new vdW options in SiestaXC.
The delay was motivated by two issues:

1. The Gitlab transition.
2. The development of a stand-alone library, ligGridXC, based on the code in SiestaXC.

LibGridXC is being developed at

    https://gitlab.com/siesta-project/libraries/libgridxc

and is "the future", in the sense that it will be required as a external library for Siesta very soon, once we merge in the next few weeks the PSML branch.

LibGridXC has the same functionality of SiestaXC, with some streamlining, and, in addition, offers an interface to LibXC. This interface is optional now, but very likely it will be made compulsory in the future.

As I understand it, your merge request:

* Adds a few more vdW flavors.
* Implements a new semilocal SG4 functional that is needed by some of the new vdW flavors.

I have no problem with the content of your merge request. I think it should definitely go into libGridXC, but I am not sure whether to integrate it also into the current code base (based on SiestaXC) which is "going away" soon.

In any case, I would request that you make new merge requests within Gitlab:

1. One for libgridXC.
2. (If you think it is worth it) Another one for the "master" branch of Siesta:

             https://gitlab.com/siesta-project/siesta

Note that, as part of the Gitlab transition, the Launchpad branch that you proposed for merging is now available in git form in:

             https://gitlab.com/siesta-project/siesta-legacy/alesster_trunk_new_xc

As a further comment, note that the SG4 functional is already provided by libXC. However, the current way in which the semilocal pieces of the vdW functionals is handled in ligGridXC needs to be checked for compatibility with libXC. It is not as easy as passing the appropriate LIBXC-XXXX string to ggaxc, since the functional object needs to be initialized in advance. So I would keep the explicit implementation of SG4 for now.

Unmerged revisions

782. By Aleksandr V. Terentjev

-------------- This line and the following will be ignored --------------

modified:
  Docs/siesta.tex
  Src/SiestaXC/ggaxc.f
  Src/SiestaXC/vdwxc.F90
  Src/SiestaXC/vv_vdwxc.F90
  Src/atom.F
  Tests/Makefile
  version.info
unknown:
  Docs/branch-changes/NOTES.trunk_new_xc
  Tests/ag_sg4/
  Tests/graphite_c6_sg4/
  Tests/graphite_vdw_pbesvvs/
  Tests/graphite_vdw_pbevv/
  Tests/graphite_vdw_sg4vv/
  Tests/Reference/ag_sg4.out
  Tests/Reference/graphite_c6_sg4.out
  Tests/Reference/graphite_vdw_pbesvvs.out
  Tests/Reference/graphite_vdw_pbevv.out
  Tests/Reference/graphite_vdw_sg4vv.out

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'Docs/siesta.tex'
--- Docs/siesta.tex 2019-08-22 09:05:46 +0000
+++ Docs/siesta.tex 2019-09-06 14:47:07 +0000
@@ -3723,6 +3723,10 @@
3723 implemented in \siesta)3723 implemented in \siesta)
37243724
3725 \item%3725 \item%
3726 \fdf*{SG4}: GGA functional based on semiclassical atom theory of Lucian A. Constantin, Aleksandrs Terentjevs, Fabio Della Sala, Pietro Cortona and Eduardo Fabiano,
3727 Phys. Rev. B \textbf{93}, 045126 (2016).
3728
3729 \item%
3726 \fdf*{DRSLL} (equivalent to \fdf*{DF1}): \xcidx{vdW-DF1}3730 \fdf*{DRSLL} (equivalent to \fdf*{DF1}): \xcidx{vdW-DF1}
3727 \xcidx{DRSLL}%3731 \xcidx{DRSLL}%
3728 van der Waals \xcidx{vdW} density functional (vdW-DF) \xcidx{vdW-DF}3732 van der Waals \xcidx{vdW} density functional (vdW-DF) \xcidx{vdW-DF}
@@ -3757,6 +3761,19 @@
3757 \fdf*{VV}: \xcidx{VV}%3761 \fdf*{VV}: \xcidx{VV}%
3758 vdW-DF functional of O. A. Vydrov and T. Van Voorhis, 3762 vdW-DF functional of O. A. Vydrov and T. Van Voorhis,
3759 J. Chem. Phys. \textbf{133}, 244103 (2010)3763 J. Chem. Phys. \textbf{133}, 244103 (2010)
3764
3765 \item%
3766 \fdf*{PBEVV}: vdW-DF functional (PBE+VV10L) with PBE exchange and correlation functionals and with non-local correlation term of O. A. Vydrov and T. Van Voorhis (VV). PBE+VV10L is the modification of PBE+rVV10L for \siesta\ of H. Peng and J. P. Perdew, Phys. Rev. B \textbf{95}, 0811105 (2017).
3767
3768 \item%
3769 \fdf*{SG4VV}: vdW-DF functional (SG4+VV10m) with SG4 exchange and correlation functionals and with non-local correlation term of O. A. Vydrov and T. Van Voorhis (VV).
3770 SG4+VV10m is the modification of SG4+rVV10m functional for \siesta\ of Aleksandr V. Terentjev, Pietro Cortona, Lucian A. Constantin, José M. Pitarke
3771 Fabio Della Sala and Eduardo Fabiano, Computation \textbf{6}, 7 (2018).
3772
3773 \item%
3774 \fdf*{PBESVVS}: vdW-DF functional (PBEsol+VV10s) with PBEsol exchange and correlation functionals and with non-local correlation term of O. A. Vydrov and
3775 T. Van Voorhis (VV). PBEsol+VV10s is the modification of PBEsol+rVV10s functional for \siesta\ of Aleksandr V. Terentjev, Lucian A. Constantin and J. M. Pitarke,
3776 Phys. Rev. B \textbf{98}, 214108 (2018).
3760 3777
3761 \end{itemize}3778 \end{itemize}
37623779
37633780
=== modified file 'Src/SiestaXC/ggaxc.f'
--- Src/SiestaXC/ggaxc.f 2018-04-19 10:08:47 +0000
+++ Src/SiestaXC/ggaxc.f 2019-09-06 14:47:07 +0000
@@ -24,8 +24,9 @@
24! b88x, ! Becke, PRA 38, 3098 (1988) (exchange only)24! b88x, ! Becke, PRA 38, 3098 (1988) (exchange only)
25! b88kbmx, ! Klimes et al, JPCM 22, 022201 (2009) (exchange only)25! b88kbmx, ! Klimes et al, JPCM 22, 022201 (2009) (exchange only)
26! c09x, ! Cooper, PRB 81, 161104 (2010) (exchange only)26! c09x, ! Cooper, PRB 81, 161104 (2010) (exchange only)
27! bhx ! Berland & Hyldgaard, PRB 89, 035412 (2014) (exchange only)27! bhx, ! Berland & Hyldgaard, PRB 89, 035412 (2014) (exchange only)
28!28! sg4xc ! GGA Constantin et al, PRB, 93, 045126 (2016)
29!
29! PUBLIC parameters, types, and variables available from this module:30! PUBLIC parameters, types, and variables available from this module:
30! none31! none
31!32!
@@ -76,8 +77,9 @@
76 . b88x, ! Becke, PRA 38, 3098 (1988) (exchange only)77 . b88x, ! Becke, PRA 38, 3098 (1988) (exchange only)
77 . b88kbmx, ! Klimes et al, JPCM 22, 022201 (2009) (exchange only)78 . b88kbmx, ! Klimes et al, JPCM 22, 022201 (2009) (exchange only)
78 . c09x, ! Cooper, PRB 81, 161104 (2010) (exchange only)79 . c09x, ! Cooper, PRB 81, 161104 (2010) (exchange only)
79 . bhx ! Berland & Hyldgaard, PRB 89, 035412 (2014) (exch. only)80 . bhx, ! Berland & Hyldgaard, PRB 89, 035412 (2014) (exch. only)
8081 . sg4xc ! GGA Constantin et al, PRB, 93, 045126 (2016)
82
81 PRIVATE ! Nothing is declared public beyond this point83 PRIVATE ! Nothing is declared public beyond this point
8284
83 CONTAINS85 CONTAINS
@@ -255,6 +257,10 @@
255 CALL PBESOLXC( IREL, NS, DD, GDD,257 CALL PBESOLXC( IREL, NS, DD, GDD,
256 . EPSX, EPSC, dEXdDD, dECdDD, dEXdGDD, dECdGDD )258 . EPSX, EPSC, dEXdDD, dECdDD, dEXdGDD, dECdGDD )
257259
260 ELSEIF (AUTHOR.EQ.'SG4'.OR.AUTHOR.EQ.'sg4') THEN
261 CALL SG4XC( IREL, NS, DD, GDD,
262 . EPSX, EPSC, dEXdDD, dECdDD, dEXdGDD, dECdGDD )
263
258 ELSEIF (AUTHOR.EQ.'AM05' .OR. AUTHOR.EQ.'am05') THEN264 ELSEIF (AUTHOR.EQ.'AM05' .OR. AUTHOR.EQ.'am05') THEN
259 CALL AM05XC( IREL, NS, DD, GDD,265 CALL AM05XC( IREL, NS, DD, GDD,
260 . EPSX, EPSC, dEXdDD, dECdDD, dEXdGDD, dECdGDD )266 . EPSX, EPSC, dEXdDD, dECdDD, dEXdGDD, dECdGDD )
@@ -2756,4 +2762,263 @@
27562762
2757 END SUBROUTINE C09X2763 END SUBROUTINE C09X
27582764
2759 END MODULE m_ggaxc2765! END MODULE m_ggaxc
2766
2767c
2768c the SG4 subroutine
2769c
2770
2771 SUBROUTINE SG4XC( IREL, nspin, Dens, GDens,
2772 . EX, EC, DEXDD, DECDD, DEXDGD, DECDGD )
2773
2774C *********************************************************************
2775C Implements GGA based on Semiclassical atom theory
2776C Ref: L.A.Constantin et al, PRB, 93, 045126 (2016)
2777C ******** INPUT ******************************************************
2778C INTEGER IREL : Relativistic-exchange switch (0=No, 1=Yes)
2779C INTEGER nspin : Number of spin polarizations (1 or 2)
2780C REAL*8 Dens(nspin) : Total electron density (if nspin=1) or
2781C spin electron density (if nspin=2)
2782C REAL*8 GDens(3,nspin) : Total or spin density gradient
2783C ******** OUTPUT *****************************************************
2784C REAL*8 EX : Exchange energy density
2785C REAL*8 EC : Correlation energy density
2786C REAL*8 DEXDD(nspin) : Partial derivative
2787C d(DensTot*Ex)/dDens(ispin),
2788C where DensTot = Sum_ispin( Dens(ispin) )
2789C For a constant density, this is the
2790C exchange potential
2791C REAL*8 DECDD(nspin) : Partial derivative
2792C d(DensTot*Ec)/dDens(ispin),
2793C where DensTot = Sum_ispin( Dens(ispin) )
2794C For a constant density, this is the
2795C correlation potential
2796C REAL*8 DEXDGD(3,nspin): Partial derivative
2797C d(DensTot*Ex)/d(GradDens(i,ispin))
2798C REAL*8 DECDGD(3,nspin): Partial derivative
2799C d(DensTot*Ec)/d(GradDens(i,ispin))
2800C ********* UNITS ****************************************************
2801C Lengths in Bohr
2802C Densities in electrons per Bohr**3
2803C Energies in Hartrees
2804C Gradient vectors in cartesian coordinates
2805C ********* ROUTINES CALLED ******************************************
2806C EXCHNG, PW92C
2807C ********************************************************************
2808
2809 use precision, only : dp
2810
2811 implicit none
2812 INTEGER IREL, nspin
2813 real(dp) Dens(nspin), DECDD(nspin), DECDGD(3,nspin),
2814 . DEXDD(nspin), DEXDGD(3,nspin), GDens(3,nspin)
2815
2816C Internal variables
2817 INTEGER
2818 . IS, IX
2819
2820 real(dp)
2821 . A, BETA, D(2), DADD, DECUDD, DENMIN,
2822 . DF1DD, DF2DD, DF3DD, DF4DD, DF1DGD, DF3DGD, DF4DGD,
2823 . DFCDD(2), DFCDGD(3,2), DFDD, DFDGD, DFXDD(2), DFXDGD(3,2),
2824 . DHDD, DHDGD, DKFDD, DKSDD, DPDD, DPDZ, DRSDD,
2825 . DS(2), DSDD, DSDGD, DT, DTDD, DTDGD, DZDD(2),
2826 . EC, ECUNIF, EX, EXUNIF,
2827 . F, F1, F2, F3, F4, FC, FX, FOUTHD,
2828 . GAMMA, GD(3,2), GDM(2), GDMIN, GDMS, GDMT, GDS, GDT(3),
2829 . H, HALF, KAPPA, KF, KFS, KS, MU, PHI, PI, RS, S,
2830 . T, THD, THRHLF, TWO, TWOTHD, VCUNIF(2), VXUNIF(2), ZETA,
2831c Lucian: new variables
2832 . beta0, sigma, alpha, amu1, amu2, ak1, ak2, term1, dbetadd,
2833 . dterm1dd, dbetadgd, dadgd, dterm1dgd, xx1, xx2, dxx1ds, dxx2ds,
2834 . dfds
2835
2836
2837C Lower bounds of density and its gradient to avoid divisions by zero
2838 PARAMETER ( DENMIN = 1.D-12 )
2839 PARAMETER ( GDMIN = 1.D-12 )
2840
2841C Fix some numerical parameters
2842 PARAMETER ( FOUTHD=4.D0/3.D0, HALF=0.5D0,
2843 . THD=1.D0/3.D0, THRHLF=1.5D0,
2844 . TWO=2.D0, TWOTHD=2.D0/3.D0 )
2845
2846C Fix some more numerical constants
2847c Lucian: constants for SG4 correlation and exchange
2848 PI = 4 * ATAN(1.D0)
2849 GAMMA = (1 - LOG(TWO)) / PI**2
2850 BETA0=0.07903051884257d0
2851 sigma=0.07d0
2852 alpha=0.8d0
2853c
2854 amu1=0.042d0
2855 amu2=0.218d0
2856 ak1=0.56028717948717954d0
2857 ak2=0.24371282051282048d0
2858C Translate density and its gradient to new variables
2859 IF (nspin .EQ. 1) THEN
2860 if(Dens(1).le.1.0d-12) Dens(1)=1.0d-12
2861 D(1) = HALF * Dens(1)
2862 D(2) = D(1)
2863 DT = MAX( DENMIN, Dens(1) )
2864 DO 10 IX = 1,3
2865 GD(IX,1) = HALF * GDens(IX,1)
2866 GD(IX,2) = GD(IX,1)
2867 GDT(IX) = GDens(IX,1)
2868 10 CONTINUE
2869 ELSE
2870 if(Dens(1).le.1.0d-12) Dens(1)=1.0d-12
2871 if(Dens(2).le.1.0d-12) Dens(2)=1.0d-12
2872 D(1) = Dens(1)
2873 D(2) = Dens(2)
2874 DT = MAX( DENMIN, Dens(1)+Dens(2) )
2875 DO 20 IX = 1,3
2876 GD(IX,1) = GDens(IX,1)
2877 GD(IX,2) = GDens(IX,2)
2878 GDT(IX) = GDens(IX,1) + GDens(IX,2)
2879 20 CONTINUE
2880 ENDIF
2881 GDM(1) = SQRT( GD(1,1)**2 + GD(2,1)**2 + GD(3,1)**2 )
2882 GDM(2) = SQRT( GD(1,2)**2 + GD(2,2)**2 + GD(3,2)**2 )
2883 GDMT = SQRT( GDT(1)**2 + GDT(2)**2 + GDT(3)**2 )
2884 GDMT = MAX( GDMIN, GDMT )
2885
2886C Find local correlation energy and potential
2887 CALL PW92C( 2, D, ECUNIF, VCUNIF )
2888
2889C Find total correlation energy
2890 RS = ( 3 / (4*PI*DT) )**THD
2891 KF = (3 * PI**2 * DT)**THD
2892 KS = SQRT( 4 * KF / PI )
2893 ZETA = ( D(1) - D(2) ) / DT
2894 ZETA = MAX( -1.D0+DENMIN, ZETA )
2895 ZETA = MIN( 1.D0-DENMIN, ZETA )
2896 PHI = HALF * ( (1+ZETA)**TWOTHD + (1-ZETA)**TWOTHD )
2897 T = GDMT / (2 * PHI * KS * DT)
2898c Define beta
2899 if(t.ge.100.d0)t=100.d0
2900 beta=beta0+sigma*t*(1.d0-dexp(-rs**2))
2901c
2902 F1 = ECUNIF / GAMMA / PHI**3
2903 F2 = EXP(-F1)
2904 A = BETA / GAMMA / (F2-1)
2905 F3 = T**2 + A * T**4
2906 F4 = BETA/GAMMA * F3 / (1 + A*F3)
2907c Define phi**(alpha*t**3) term
2908 term1 = phi ** ( alpha * t **3 )
2909 H = term1 * GAMMA * PHI**3 * LOG( 1 + F4 )
2910c
2911 FC = ECUNIF + H
2912
2913C Find correlation energy derivatives
2914 DRSDD = - (THD * RS / DT)
2915 DKFDD = THD * KF / DT
2916 DKSDD = HALF * KS * DKFDD / KF
2917 DZDD(1) = 1 / DT - ZETA / DT
2918 DZDD(2) = - (1 / DT) - ZETA / DT
2919 DPDZ = HALF * TWOTHD * ( 1/(1+ZETA)**THD - 1/(1-ZETA)**THD )
2920 DO 40 IS = 1,2
2921 DECUDD = ( VCUNIF(IS) - ECUNIF ) / DT
2922 DPDD = DPDZ * DZDD(IS)
2923 DTDD = (- T) * ( DPDD/PHI + DKSDD/KS + 1/DT )
2924c Derivative of beta
2925 dbetadd = sigma * DTDD * ( 1.d0 - dexp ( - rs ** 2 ) ) +
2926 . sigma * t * 2.d0 * rs * dexp ( - rs ** 2 ) * DRSDD
2927c
2928 DF1DD = F1 * ( DECUDD/ECUNIF - 3*DPDD/PHI )
2929 DF2DD = (- F2) * DF1DD
2930c Derivative of A
2931 DADD = (- A) * DF2DD / (F2-1) + dbetadd / GAMMA / (F2-1)
2932c
2933 DF3DD = (2*T + 4*A*T**3) * DTDD + DADD * T**4
2934 DF4DD = F4 * ( DF3DD/F3 - (DADD*F3+A*DF3DD)/(1+A*F3) )+
2935 . dbetadd/GAMMA * F3 / (1 + A*F3)
2936
2937c Derivative of term1
2938 dterm1dd = term1 * ( alpha * 3.d0 * t * t * dtdd * dlog(phi) +
2939 . alpha * t * t * t / phi * dpdd )
2940c
2941c Derivative of H
2942 DHDD= 3 * phi**2 * term1 * GAMMA * LOG( 1 + F4 ) * DPDD +
2943 . dterm1dd * GAMMA * PHI**3 * LOG( 1 + F4 ) +
2944 . term1 * GAMMA * PHI**3 * DF4DD / (1+F4)
2945c
2946 DFCDD(IS) = VCUNIF(IS) + H + DT * DHDD
2947 DO 30 IX = 1,3
2948 DTDGD = (T / GDMT) * GDT(IX) / GDMT
2949c Derivative of beta with respect to gradient
2950 dbetadgd = sigma * DTDGD * ( 1.d0 - dexp ( - rs**2 ) )
2951c Derivative of A with respect to gradient
2952 dadgd = dbetadgd / GAMMA / (F2-1)
2953c
2954 DF3DGD = DTDGD * ( 2 * T + 4 * A * T**3 ) +
2955 . dadgd * T**4
2956c
2957 DF4DGD = F4 * DF3DGD * ( 1/F3 - A/(1+A*F3) )+
2958 . dbetadgd /GAMMA * F3 / (1 + A*F3) -
2959 . BETA /GAMMA * F3 / (1 + A*F3)**2 * dadgd *f3
2960c
2961 dterm1dgd = term1 * alpha * 3.d0 * t * t * dtdgd * dlog(phi)
2962c
2963 DHDGD = term1 * GAMMA * PHI**3 * DF4DGD / (1+F4) +
2964 . dterm1dgd * GAMMA * PHI**3 * LOG( 1 + F4 )
2965c
2966 DFCDGD(IX,IS) = DT * DHDGD
2967 30 CONTINUE
2968 40 CONTINUE
2969
2970C Find exchange energy and potential
2971 FX = 0
2972 DO 60 IS = 1,2
2973 DS(IS) = MAX( DENMIN, 2 * D(IS) )
2974 GDMS = MAX( GDMIN, 2 * GDM(IS) )
2975 KFS = (3 * PI**2 * DS(IS))**THD
2976 S = GDMS / (2 * KFS * DS(IS))
2977c Exchange enhancement factor
2978 xx1=amu1*s*s/ak1
2979 xx2=amu2*s*s/ak2
2980 F=1+ak1+ak2-ak1/(1.d0+xx1+xx1**2+xx1**3+xx1**4)-
2981 . ak2/(1.d0+xx2)
2982c
2983c Note nspin=1 in call to exchng...
2984c
2985 CALL EXCHNG( IREL, 1, DS(IS), EXUNIF, VXUNIF(IS) )
2986 FX = FX + DS(IS) * EXUNIF * F
2987
2988 DKFDD = THD * KFS / DS(IS)
2989 DSDD = S * ( -(DKFDD/KFS) - 1/DS(IS) )
2990c Derivative of exchange enhancement factor
2991 dxx1ds=amu1*2.d0*s/ak1
2992 dxx2ds=amu2*2.d0*s/ak2
2993 dfds=ak1/(1.d0+xx1+xx1**2+xx1**3+xx1**4)**2 *
2994 . dxx1ds*(1.d0+2.d0*xx1+3.d0*xx1**2+4.d0*xx1**3) +
2995 . ak2/(1.d0+xx2)**2 * dxx2ds
2996 dfdd=dfds*dsdd
2997 DFXDD(IS) = VXUNIF(IS) * F + DS(IS) * EXUNIF * DFDD
2998
2999 DO 50 IX = 1,3
3000 GDS = 2 * GD(IX,IS)
3001 DSDGD = (S / GDMS) * GDS / GDMS
3002c
3003 DFDGD = dfds * DSDGD
3004c
3005 DFXDGD(IX,IS) = DS(IS) * EXUNIF * DFDGD
3006 50 CONTINUE
3007 60 CONTINUE
3008 FX = HALF * FX / DT
3009
3010C Set output arguments
3011 EX = FX
3012 EC = FC
3013 DO 90 IS = 1,nspin
3014 DEXDD(IS) = DFXDD(IS)
3015 DECDD(IS) = DFCDD(IS)
3016 DO 80 IX = 1,3
3017 DEXDGD(IX,IS) = DFXDGD(IX,IS)
3018 DECDGD(IX,IS) = DFCDGD(IX,IS)
3019 80 CONTINUE
3020 90 CONTINUE
3021
3022 END SUBROUTINE SG4XC
3023
3024 END MODULE m_ggaxc
27603025
=== modified file 'Src/SiestaXC/vdwxc.F90'
--- Src/SiestaXC/vdwxc.F90 2015-05-08 09:34:16 +0000
+++ Src/SiestaXC/vdwxc.F90 2019-09-06 14:47:07 +0000
@@ -257,12 +257,33 @@
257 use m_vv_vdwxc, only: vv_vdw_get_kmesh ! Size and values of (kf,kg) mesh257 use m_vv_vdwxc, only: vv_vdw_get_kmesh ! Size and values of (kf,kg) mesh
258 use m_vv_vdwxc, only: vv_vdw_phi ! Interpolates rho1*rho2*phi(k1,k2,k)258 use m_vv_vdwxc, only: vv_vdw_phi ! Interpolates rho1*rho2*phi(k1,k2,k)
259 use m_vv_vdwxc, only: vv_vdw_set_kcut ! Sets the planewave cutoff kc259 use m_vv_vdwxc, only: vv_vdw_set_kcut ! Sets the planewave cutoff kc
260260!! New vdw
261 use m_sg4vv_vdwxc, only: sg4vv_vdw_beta ! Parameter beta of VV2010 functional
262 use m_sg4vv_vdwxc, only: sg4vv_vdw_theta ! Func. theta of VV2010 functional
263 use m_sg4vv_vdwxc, only: sg4vv_vdw_get_kmesh ! Size and values of (kf,kg) mesh
264 use m_sg4vv_vdwxc, only: sg4vv_vdw_phi ! Interpolates rho1*rho2*phi(k1,k2,k)
265 use m_sg4vv_vdwxc, only: sg4vv_vdw_set_kcut ! Sets the planewave cutoff kc
266
267 use m_pbevv_vdwxc, only: pbevv_vdw_beta ! Parameter beta of VV2010 functional
268 use m_pbevv_vdwxc, only: pbevv_vdw_theta ! Func. theta of VV2010 functional
269 use m_pbevv_vdwxc, only: pbevv_vdw_get_kmesh ! Size and values of (kf,kg) mesh
270 use m_pbevv_vdwxc, only: pbevv_vdw_phi ! Interpolates rho1*rho2*phi(k1,k2,k)
271 use m_pbevv_vdwxc, only: pbevv_vdw_set_kcut ! Sets the planewave cutoff kc
272
273 use m_pbesvvs_vdwxc, only: pbesvvs_vdw_beta ! Parameter beta of VV2010 functional
274 use m_pbesvvs_vdwxc, only: pbesvvs_vdw_theta ! Func. theta of VV2010 functional
275 use m_pbesvvs_vdwxc, only: pbesvvs_vdw_get_kmesh ! Size and values of (kf,kg) mesh
276 use m_pbesvvs_vdwxc, only: pbesvvs_vdw_phi ! Interpolates rho1*rho2*phi(k1,k2,k)
277 use m_pbesvvs_vdwxc, only: pbesvvs_vdw_set_kcut ! Sets the planewave cutoff kc
261! Used module parameters278! Used module parameters
262 use precision, only: dp ! Real double precision type279 use precision, only: dp ! Real double precision type
263280
264#ifdef DEBUG_XC281#ifdef DEBUG_XC
265 use m_vv_vdwxc, only: vv_vdw_phiofr ! Interpolates rho1*rho2*phi(k1,k2,r)282 use m_vv_vdwxc, only: vv_vdw_phiofr ! Interpolates rho1*rho2*phi(k1,k2,r)
283!! New use of vdw_phiofr
284 use m_sg4vv_vdwxc, only: sg4vv_vdw_phiofr
285 use m_pbevv_vdwxc, only: pbevv_vdw_phiofr
286 use m_pbesvvs_vdwxc, only: pbesvvs_vdw_phiofr
266 use debugXC, only: udebug ! File unit for debug output287 use debugXC, only: udebug ! File unit for debug output
267! use plot_module, only: plot288! use plot_module, only: plot
268#endif /* DEBUG_XC */289#endif /* DEBUG_XC */
@@ -348,7 +369,7 @@
348 real(dp),parameter:: ytol = 1.e-15_dp ! Tol. for saturated q369 real(dp),parameter:: ytol = 1.e-15_dp ! Tol. for saturated q
349370
350 ! Private module variables and arrays371 ! Private module variables and arrays
351 character(len=5),save:: vdw_author='DRSLL' ! Functional 'flavour' name372 character(len=7),save:: vdw_author='PBESVVS' ! Functional 'flavour' name
352 real(dp),save:: dmesh(nd) ! Mesh points for phi(d1,d2) table373 real(dp),save:: dmesh(nd) ! Mesh points for phi(d1,d2) table
353 real(dp),save:: qmesh(mq) ! Mesh points for phi(q1,q2,r)374 real(dp),save:: qmesh(mq) ! Mesh points for phi(q1,q2,r)
354 real(dp),save:: phi_table(0:3,0:3,nd,nd) ! Coefs. for bicubic interpolation375 real(dp),save:: phi_table(0:3,0:3,nd,nd) ! Coefs. for bicubic interpolation
@@ -748,8 +769,18 @@
748 ! Trap VV-version exception769 ! Trap VV-version exception
749#ifdef DEBUG_XC770#ifdef DEBUG_XC
750 if (vdw_author=='VV') then771 if (vdw_author=='VV') then
751 call vv_vdw_phiofr( r, phi )772 call vv_vdw_phiofr( r, phi )
752 return773 return
774!! New vdw_phiofr
775 elseif (vdw_author=='SG4VV') then
776 call sg4vv_vdw_phiofr( r, phi )
777 return
778 elseif (vdw_author=='PBEVV') then
779 call pbevv_vdw_phiofr( r, phi )
780 return
781 elseif (vdw_author=='PBESVVS') then
782 call pbesvvs_vdw_phiofr( r, phi )
783 return
753 end if784 end if
754#endif /* DEBUG_XC */785#endif /* DEBUG_XC */
755786
@@ -1362,6 +1393,22 @@
1362 dedrho = eps1393 dedrho = eps
1363 dedgrho = 01394 dedgrho = 0
1364 return1395 return
1396!! New vdw_beta
1397 elseif (vdw_author=='SG4VV') then
1398 eps = sg4vv_vdw_beta()
1399 dedrho = eps
1400 dedgrho = 0
1401 return
1402 elseif (vdw_author=='PBEVV') then
1403 eps = pbevv_vdw_beta()
1404 dedrho = eps
1405 dedgrho = 0
1406 return
1407 elseif (vdw_author=='PBESVVS') then
1408 eps = pbesvvs_vdw_beta()
1409 dedrho = eps
1410 dedgrho = 0
1411 return
1365 end if1412 end if
13661413
1367 if (.not.initialized) then1414 if (.not.initialized) then
@@ -1424,11 +1471,30 @@
14241471
1425 ! Trap VV-version exception1472 ! Trap VV-version exception
1426 if (vdw_author=='VV') then1473 if (vdw_author=='VV') then
1427 call vv_vdw_get_kmesh( nkf, nkg )1474 call vv_vdw_get_kmesh( nkf, nkg )
1428 n = nkf*nkg1475 n = nkf*nkg
1429 if (present(q)) &1476 if (present(q)) &
1430 call die('vdw_get_qmesh: ERROR q-mesh not available for author=VV')1477 call die('vdw_get_qmesh: ERROR q-mesh not available for author=VV')
1431 return1478 return
1479!! New vdw_get_kmesh
1480 elseif (vdw_author=='SG4VV') then
1481 call sg4vv_vdw_get_kmesh( nkf, nkg )
1482 n = nkf*nkg
1483 if (present(q)) &
1484 call die('vdw_get_qmesh: ERROR q-mesh not available for author=SG4VV')
1485 return
1486 elseif (vdw_author=='PBEVV') then
1487 call pbevv_vdw_get_kmesh( nkf, nkg )
1488 n = nkf*nkg
1489 if (present(q)) &
1490 call die('vdw_get_qmesh: ERROR q-mesh not available for author=PBEVV')
1491 return
1492 elseif (vdw_author=='PBESVVS') then
1493 call pbesvvs_vdw_get_kmesh( nkf, nkg )
1494 n = nkf*nkg
1495 if (present(q)) &
1496 call die('vdw_get_qmesh: ERROR q-mesh not available for author=PBESVVS')
1497 return
1432 end if1498 end if
14331499
1434 if (.not.qmesh_set) call set_qmesh()1500 if (.not.qmesh_set) call set_qmesh()
@@ -1514,6 +1580,33 @@
1514 dEXdD, dEdDaux, dEXdGD, dEdGDaux )1580 dEXdD, dEdDaux, dEXdGD, dEdGDaux )
1515 call GGAxc( 'PBE', iRel, nSpin, D, GD, epsAux, epsC, &1581 call GGAxc( 'PBE', iRel, nSpin, D, GD, epsAux, epsC, &
1516 dEdDaux, dECdD, dEdGDaux, dECdGD )1582 dEdDaux, dECdD, dEdGDaux, dECdGD )
1583!! New vdw functionals
1584 else if (vdw_author=='SG4VV' .or. vdw_author=='sg4vv') then
1585 ! A. V. Terentjev et al, Computation 6, 7 (2018)
1586 ! SG4 GGA for both exchange and correlation
1587 call GGAxc( 'SG4', iRel, nSpin, D, GD, epsX, epsAux, &
1588 dEXdD, dEdDaux, dEXdGD, dEdGDaux )
1589 call GGAxc( 'SG4', iRel, nSpin, D, GD, epsAux, epsC, &
1590 dEdDaux, dECdD, dEdGDaux, dECdGD )
1591
1592 else if (vdw_author=='PBEVV' .or. vdw_author=='pbevv' .or. &
1593 vdw_author=='PBEvv' .or. vdw_author=='pbeVV' ) then
1594 ! H. Peng and J. P. Perdew, Phys. Rev. B 95, 0811105 (2017)
1595 ! PBE GGA for both exchange and correlation
1596 call GGAxc( 'PBE', iRel, nSpin, D, GD, epsX, epsAux, &
1597 dEXdD, dEdDaux, dEXdGD, dEdGDaux )
1598 call GGAxc( 'PBE', iRel, nSpin, D, GD, epsAux, epsC, &
1599 dEdDaux, dECdD, dEdGDaux, dECdGD )
1600
1601 else if (vdw_author=='PBESVVS' .or. vdw_author=='pbesvvs' .or. &
1602 vdw_author=='PBESVVs' .or. vdw_author=='PBESvvs' ) then
1603 ! A. V. Terentjev et al, Phys. Rev. B 98, 214108 (2018)
1604 ! PBESOL GGA for both exchange and correlation
1605 call GGAxc( 'PBESOL', iRel, nSpin, D, GD, epsX, epsAux, &
1606 dEXdD, dEdDaux, dEXdGD, dEdGDaux )
1607 call GGAxc( 'PBESOL', iRel, nSpin, D, GD, epsAux, epsC, &
1608 dEdDaux, dECdD, dEdGDaux, dECdGD )
1609
1517 else1610 else
1518 stop 'vdw_exchng ERROR: unknown author'1611 stop 'vdw_exchng ERROR: unknown author'
1519 end if1612 end if
@@ -1542,6 +1635,16 @@
1542 if (vdw_author=='VV') then1635 if (vdw_author=='VV') then
1543 call vv_vdw_phi( k, phi, dphidk )1636 call vv_vdw_phi( k, phi, dphidk )
1544 return1637 return
1638!! New vdw_phi
1639 elseif (vdw_author=='SG4VV') then
1640 call sg4vv_vdw_phi( k, phi, dphidk )
1641 return
1642 elseif (vdw_author=='PBEVV') then
1643 call pbevv_vdw_phi( k, phi, dphidk )
1644 return
1645 elseif (vdw_author=='PBESVVS') then
1646 call pbesvvs_vdw_phi( k, phi, dphidk )
1647 return
1545 end if1648 end if
15461649
1547 if (.not.kcut_set) stop 'vdw_phi: ERROR: kcut must be previously set'1650 if (.not.kcut_set) stop 'vdw_phi: ERROR: kcut must be previously set'
@@ -1605,6 +1708,13 @@
1605 zab = -0.8491_dp1708 zab = -0.8491_dp
1606 else if (author=='VV') then1709 else if (author=='VV') then
1607 ! Vydrov and Van Voorhis, JCP 133, 244103 (2010)1710 ! Vydrov and Van Voorhis, JCP 133, 244103 (2010)
1711!! New vdw functionals
1712 else if (author=='SG4VV') then
1713 ! A. V. Terentjev et al, Computation 6, 7 (2018)
1714 else if (author=='PBEVV') then
1715 ! H. Peng and J. P. Perdew, Phys. Rev. B 95, 0811105 (2017)
1716 else if (author=='PBESVVS') then
1717 ! A. V. Terentjev et al, Phys. Rev. B 98, 214108 (2018)
1608 else1718 else
1609 stop 'vdw_set_author: ERROR: author not known'1719 stop 'vdw_set_author: ERROR: author not known'
1610 end if1720 end if
@@ -1630,8 +1740,18 @@
16301740
1631 ! Trap VV-version exception1741 ! Trap VV-version exception
1632 if (vdw_author=='VV') then1742 if (vdw_author=='VV') then
1633 call vv_vdw_set_kcut( kc )1743 call vv_vdw_set_kcut( kc )
1634 return1744 return
1745!! New vdw_set_kcut
1746 elseif (vdw_author=='SG4VV') then
1747 call sg4vv_vdw_set_kcut( kc )
1748 return
1749 elseif (vdw_author=='PBEVV') then
1750 call pbevv_vdw_set_kcut( kc )
1751 return
1752 elseif (vdw_author=='PBESVVS') then
1753 call pbesvvs_vdw_set_kcut( kc )
1754 return
1635 end if1755 end if
16361756
1637 if (kc == kcut) return ! Work alredy done1757 if (kc == kcut) return ! Work alredy done
@@ -1780,6 +1900,16 @@
1780 if (vdw_author=='VV') then1900 if (vdw_author=='VV') then
1781 call vv_vdw_theta( nspin, rhos, grhos, theta, dtdrho, dtdgrho )1901 call vv_vdw_theta( nspin, rhos, grhos, theta, dtdrho, dtdgrho )
1782 return1902 return
1903!! New vdw_theta
1904 elseif (vdw_author=='SG4VV') then
1905 call sg4vv_vdw_theta( nspin, rhos, grhos, theta, dtdrho, dtdgrho )
1906 return
1907 elseif (vdw_author=='PBEVV') then
1908 call pbevv_vdw_theta( nspin, rhos, grhos, theta, dtdrho, dtdgrho )
1909 return
1910 elseif (vdw_author=='PBESVVS') then
1911 call pbesvvs_vdw_theta( nspin, rhos, grhos, theta, dtdrho, dtdgrho )
1912 return
1783 end if1913 end if
17841914
1785 ns = min(nspin,2)1915 ns = min(nspin,2)
17861916
=== modified file 'Src/SiestaXC/vv_vdwxc.F90'
--- Src/SiestaXC/vv_vdwxc.F90 2016-05-10 10:45:36 +0000
+++ Src/SiestaXC/vv_vdwxc.F90 2019-09-06 14:47:07 +0000
@@ -993,3 +993,2520 @@
993end subroutine vv_vdw_theta993end subroutine vv_vdw_theta
994994
995END MODULE m_vv_vdwxc995END MODULE m_vv_vdwxc
996
997!!!==================SG4VV====================
998
999MODULE m_sg4vv_vdwxc
1000
1001! Used module procedures
1002 use sys, only: die ! Termination routine
1003 use mesh1D, only: get_mesh ! Returns the mesh points
1004 use m_radfft, only: radfft ! Radial fast Fourier transform
1005 use alloc, only: re_alloc ! Re-allocation routine
1006 use mesh1D, only: set_mesh ! Sets a 1D mesh
1007 use interpolation,only: spline ! Sets spline interpolation
1008 use interpolation,only: splint ! Calculates spline interpolation
1009
1010! Used module parameters
1011 use precision, only: dp ! Real double precision type
1012
1013#ifdef DEBUG_XC
1014 use debugXC, only: udebug ! File unit for debug output
1015! use plot_module, only: plot
1016#endif /* DEBUG_XC */
1017
1018 implicit none
1019
1020! Called by m_vdwxc
1021PUBLIC :: &
1022 sg4vv_vdw_beta, &! Returns parameter beta of the VV2010 functional
1023 sg4vv_vdw_theta, &! Finds function theta_ik(rho,grad_rho)
1024 sg4vv_vdw_get_kmesh, &! Returns size and values of (kf,kg) mesh
1025 sg4vv_vdw_phi, &! Finds and interpolates rho1*rho2*phi(k1,k2,k)
1026 sg4vv_vdw_set_kcut ! Sets the planewave cutoff kc of the integration grid
1027
1028#ifdef DEBUG_XC
1029! Called by debugging test programs
1030PUBLIC :: &
1031 sg4vv_vdw_phi_val, &! Kernel phi(kf1,kf2,kg1,kg2,r12) with no interpolation
1032 sg4vv_vdw_phiofr ! Kernel phi(k1,k2,r) at tabulated k1,k2-mesh values
1033#endif /* DEBUG_XC */
1034
1035PRIVATE ! Nothing is declared public beyond this point
1036
1037!! Set parameters of the SG4+rVV10m functional
1038!! Ref. A. V. Terentjev et al, Computation 6, 7 (2018)
1039 real(dp),parameter:: vv_C = 0.0001
1040 real(dp),parameter:: vv_b = 12.0
1041!!
1042 real(dp),parameter:: vv_beta = 0.00497
1043
1044 ! Mesh parameters for table of phi(k1,k2,r) and its Fourier transform
1045 character(len=*),parameter:: kernelPrefactor='rho' ! Prefactor of the
1046 ! nonlocal kernel for interpolation
1047 ! ('kf'|'kf2'|'sqr_rho'|'rho')
1048 integer, parameter:: nr = 2048 ! Radial mesh points (power of 2)
1049 real(dp),parameter:: rcut = 100._dp ! Radial cutoff: r>rcut => phi=0
1050 real(dp),parameter:: rmin = 1.e-6_dp ! Min. radius as denominator
1051 integer, parameter:: nkf = 7 ! Number of Fermi wavevectors
1052 integer, parameter:: nkg = 5 ! Num. of grad(n)/n wavevectors
1053 integer, parameter:: nkfg = nkf*nkg ! Num. of (kf,kg) mesh points
1054 real(dp),parameter:: kfcut = 5.0_dp ! Max. Fermi wavevec.
1055 real(dp),parameter:: kgcut = 5.0_dp ! Max. grad(n)/n
1056 real(dp),parameter:: dkfmaxdkfmin = 20.0_dp ! Last/first kf mesh interval
1057 real(dp),parameter:: dkgmaxdkgmin = 2.0_dp ! Last/first kg mesh interval
1058 real(dp),parameter:: ktol = 1.e-12_dp ! 'out of range' tolerance
1059 real(dp),parameter:: amin = 1.e-12_dp ! tiny denominator to avoid /0
1060 real(dp),parameter:: rhoMin = 1.e-10_dp ! Min. density for nonzero Vxc
1061
1062 ! Parameters for cutoff function, used in radial Fourier transforms of phi
1063 integer, parameter:: ncut1 = 8 ! cutoff(x)=(1-x**ncut1)**ncut2
1064 integer, parameter:: ncut2 = 4
1065
1066 ! Parameters for saturate function, used to enforce that q<qcut
1067 integer, parameter:: nsat = 15 ! h(x,xc)=1/(1/x**nsat+1/xc**nsat)**(1/nsat)
1068 ! nsat=15 approximately corresponds to
1069 ! nsat=12 for eq.(5) of Roman-Soler PRL
1070
1071 ! Private module variables and arrays
1072 logical, save:: kcut_set=.false. ! Has kcut been set?
1073 logical, save:: kmesh_set=.false. ! Has (kf,kg) mesh been set?
1074 logical, save:: phi_table_set=.false. ! Has phi_table been set?
1075 integer, save:: nk ! Num. of radial mesh k-points
1076 real(dp),save:: dr ! r-mesh interval
1077 real(dp),save:: dk ! k-mesh interval
1078 real(dp),save:: kcut ! Planewave cutoff: k>kcut => phi=0
1079 real(dp),save:: kmax ! Max. k vector in Fourier transforms
1080 real(dp),save:: kfmesh(nkf) ! Mesh points for Fermi wavevector
1081 real(dp),save:: kgmesh(nkg) ! Mesh points for grad(n)/n
1082 real(dp),pointer,save:: &
1083 phir(:,:,:)=>null(), &! Table of phi(r)
1084 phik(:,:,:)=>null(), &! Table of phi(k)
1085 d2phidr2(:,:,:)=>null(),&! Table of d^2(phi)/dr^2
1086 d2phidk2(:,:,:)=>null() ! Table of d^2(phi)/dk^2
1087
1088CONTAINS
1089
1090! -----------------------------------------------------------------------------
1091
1092real(dp) function cutoff( x )
1093
1094! Defines a smooth cutoff function that falls from y(0)=1 to y(1)=0
1095
1096 implicit none
1097 real(dp),intent(in):: x
1098
1099 if (x<=0._dp) then
1100 cutoff = 1
1101 else if (x>=1._dp) then
1102 cutoff = 0
1103 else
1104 cutoff = (1-x**ncut1)**ncut2
1105 end if
1106
1107end function cutoff
1108
1109!-----------------------------------------------------------------------------
1110
1111subroutine iofk( kf, kg, ikf, ikg )
1112
1113! Finds indexes ikf and ikg such that kfmesh(ikf) <= kf < kfmesh(ikf+1)
1114! and kgmesh(ikg) <= kg < kgmesh(ikg+1) in logarithmic meshes of the form
1115! k(ik) = b*(exp((ik-1)*a)-1)
1116
1117 implicit none
1118 real(dp), intent(in) :: kf, kg
1119 integer, intent(out):: ikf, ikg
1120
1121 real(dp),save:: akf, akg, bkf, bkg
1122 logical, save:: first_call = .true.
1123 integer:: ik
1124
1125 ! Mesh data initializations
1126 if (first_call) then
1127 ! Find logarithmic-mesh a & b parameters: x(j)=x(1)+b*(exp(a*(j-1))-1)
1128 akf = log( (kfmesh(nkf)-kfmesh(nkf-1)) / (kfmesh(2)-kfmesh(1)) ) / (nkf-2)
1129 akg = log( (kgmesh(nkg)-kgmesh(nkg-1)) / (kgmesh(2)-kgmesh(1)) ) / (nkg-2)
1130 akf = max( akf, amin )
1131 akg = max( akg, amin )
1132 bkf = (kfmesh(nkf) - kfmesh(1)) / (exp(akf*(nkf-1)) - 1)
1133 bkg = (kgmesh(nkg) - kgmesh(1)) / (exp(akg*(nkg-1)) - 1)
1134 ! Check that meshes are indeed logarithmic
1135 do ik = 1,nkf
1136 if (abs(kfmesh(ik)-kfmesh(1)-bkf*(exp(akf*(ik-1))-1))>ktol) &
1137 call die('sg4vv_vdw_iofk ERROR: kfmesh not logarithmic')
1138 end do
1139 do ik = 1,nkg
1140 if (abs(kgmesh(ik)-kgmesh(1)-bkg*(exp(akg*(ik-1))-1))>ktol) &
1141 call die('sg4vv_vdw_iofk ERROR: kgmesh not logarithmic')
1142 end do
1143 first_call = .false.
1144 end if
1145
1146 ! Check that kf and kg are within interpolation range
1147 if (kf<kfmesh(1)-ktol .or. kf>kfmesh(nkf)+ktol .or. &
1148 kg<kgmesh(1)-ktol .or. kg>kgmesh(nkg)+ktol) then
1149 call die('sg4vv_vdw_iofk ERROR: (kf,kg) out of range')
1150 endif
1151
1152 ! Find interpolation mesh intervals
1153 ikf = 1 + int( log( 1 + (kf-kfmesh(1))/bkf ) / akf )
1154 ikg = 1 + int( log( 1 + (kg-kgmesh(1))/bkg ) / akg )
1155 ikf = max( 1, ikf )
1156 ikg = max( 1, ikg )
1157 ikf = min( nkf-1, ikf )
1158 ikg = min( nkg-1, ikg )
1159
1160end subroutine iofk
1161
1162! -----------------------------------------------------------------------------
1163
1164subroutine kofn( n, gn, kf, kg, dkfdn, dkgdn, dkfdgn, dkgdgn )
1165
1166! Finds Fermi and gradient wavevectors from density and gradient
1167
1168 implicit none
1169 real(dp), intent(in) :: n ! Electron density
1170 real(dp), intent(in) :: gn(3) ! Density gradient
1171 real(dp), intent(out):: kf ! Local Fermi wavevector
1172 real(dp), intent(out):: kg ! |grad(n)|/n
1173 real(dp), intent(out):: dkfdn ! dkf/dn
1174 real(dp), intent(out):: dkgdn ! dkg/dn
1175 real(dp), intent(out):: dkfdgn(3) ! dkf/dgn
1176 real(dp), intent(out):: dkgdgn(3) ! dkg/dgn
1177
1178 real(dp):: gn2, pi
1179
1180! Trap exception for zero density
1181 if (n <= 1.e-30_dp) then
1182 kf = 0
1183 kg = 0
1184 dkfdn = 0
1185 dkfdgn = 0
1186 dkgdn = 0
1187 dkgdgn = 0
1188 return
1189 end if
1190
1191! Find kf and kg
1192 pi = acos(-1._dp)
1193 kf = (3*pi**2*n)**(1._dp/3)
1194 gn2 = sum(gn**2)
1195 kg = sqrt(gn2)/n
1196
1197! Find derivatives
1198 dkfdn = kf/n/3
1199 dkfdgn = 0
1200 dkgdn = -kg/n
1201 dkgdgn = kg*gn/gn2
1202
1203end subroutine kofn
1204
1205!-----------------------------------------------------------------------------
1206
1207subroutine pofk( kf, kg, p, dpdkf, dpdkg )
1208
1209! Finds the values and derivatives, at (kf,kg), of the bicubic polynomials
1210! p_i(kf,kg) such that
1211! y(kf,kg) = Sum_i p_i(kf,kg) * y_i
1212! is the bicubic spline interpolation at (kf,kg) of (any) function y with
1213! values y_i at mesh points (kfmesh,kgmesh)_i
1214
1215 implicit none
1216 real(dp),intent(in) :: kf, kg ! point at which the polynomials are required
1217 real(dp),intent(out):: p(nkfg) ! polynomial values at (kf,kg)
1218 real(dp),intent(out):: dpdkf(nkfg) ! dp/dkf at (kf,kg)
1219 real(dp),intent(out):: dpdkg(nkfg) ! dp/dkg at (kf,kg)
1220
1221 integer :: ikf, ikg, ikfg, ikf0, ikg0
1222 real(dp):: a, b, dk, dkf0dkf, dkg0dkg, kf0, kg0
1223 real(dp):: pkf0(nkf), dpkfdkf0(nkf), pkg0(nkg), dpkgdkg0(nkg)
1224 logical, save :: first_call=.true.
1225 real(dp),save :: pkf(nkf,nkf), d2pkfdkf2(nkf,nkf)
1226 real(dp),save :: pkg(nkg,nkg), d2pkgdkg2(nkg,nkg)
1227
1228! Set up spline polynomial basis
1229 if (first_call) then
1230 do ikf = 1,nkf
1231 pkf(:,ikf) = 0 ! ikf'th polynomial pkf(:,ikf) is one at kfmesh(ikf)
1232 pkf(ikf,ikf) = 1 ! and zero at all other points
1233 call spline( kfmesh, pkf(:,ikf), nkf, 1.e30_dp, 1.e30_dp, &
1234 d2pkfdkf2(:,ikf) )
1235! call spline( kfmesh, pkf(:,ikf), nkf, 0._dp, 0._dp, d2pkfdkf2(:,ikf) )
1236 end do
1237 do ikg = 1,nkg
1238 pkg(:,ikg) = 0
1239 pkg(ikg,ikg) = 1
1240 call spline( kgmesh, pkg(:,ikg), nkg, 1.e30_dp, 1.e30_dp, &
1241 d2pkgdkg2(:,ikg) )
1242! call spline( kgmesh, pkg(:,ikg), nkg, 0._dp, 0._dp, d2pkgdkg2(:,ikg) )
1243 end do
1244
1245! DEBUG
1246 open(22,file='pkf.dat')
1247 do ikf = 1,nkf
1248 write(22,'(20e15.6)') kfmesh(ikf), pkf(:,ikf), d2pkfdkf2(:,ikf)
1249 end do
1250 close(22)
1251 open(22,file='pkg.dat')
1252 do ikg = 1,nkg
1253 write(22,'(20e15.6)') kgmesh(ikg), pkg(:,ikg), d2pkgdkg2(:,ikg)
1254 end do
1255 close(22)
1256! END DEBUG
1257
1258 first_call = .false.
1259 end if
1260
1261! 'Saturate' (kf,kg) values to bring them to interpolation range
1262 call saturate( kf, kfcut, kf0, dkf0dkf )
1263 call saturate( kg, kgcut, kg0, dkg0dkg )
1264
1265! Find interval of k mesh in which (kf0,kg0) point is included
1266 call iofk( kf0, kg0, ikf0, ikg0 )
1267
1268! Evaluate pkf polynomials of spline basis at kf0
1269! The splint code is in-lined here because it is a hot point
1270 dk = kfmesh(ikf0+1) - kfmesh(ikf0)
1271 a = (kfmesh(ikf0+1) - kf0) / dk ! dadkf0 = -1/dk
1272 b = (kf0 - kfmesh(ikf0)) / dk ! dbdkf0 = +1/dk
1273 do ikf = 1,nkf
1274 pkf0(ikf) = a*pkf(ikf0,ikf) + b*pkf(ikf0+1,ikf) &
1275 + ((a**3-a)*d2pkfdkf2(ikf0,ikf) + &
1276 (b**3-b)*d2pkfdkf2(ikf0+1,ikf)) * dk**2/6
1277 dpkfdkf0(ikf) = - (pkf(ikf0,ikf) - pkf(ikf0+1,ikf)) / dk &
1278 - ((3*a**2-1)*d2pkfdkf2(ikf0,ikf) - &
1279 (3*b**2-1)*d2pkfdkf2(ikf0+1,ikf)) * dk/6
1280 end do
1281
1282! Evaluate pkg polynomials of spline basis at kg0
1283 dk = kgmesh(ikg0+1) - kgmesh(ikg0)
1284 a = (kgmesh(ikg0+1) - kg0) / dk ! dadkg0 = -1/dk
1285 b = (kg0 - kgmesh(ikg0)) / dk ! dbdkg0 = +1/dk
1286 do ikg = 1,nkg
1287 pkg0(ikg) = a*pkg(ikg0,ikg) + b*pkg(ikg0+1,ikg) &
1288 + ((a**3-a)*d2pkgdkg2(ikg0,ikg) + &
1289 (b**3-b)*d2pkgdkg2(ikg0+1,ikg)) * dk**2/6
1290 dpkgdkg0(ikg) = - (pkg(ikg0,ikg) - pkg(ikg0+1,ikg)) / dk &
1291 - ((3*a**2-1)*d2pkgdkg2(ikg0,ikg) - &
1292 (3*b**2-1)*d2pkgdkg2(ikg0+1,ikg)) * dk/6
1293 end do
1294
1295! Evaluate pkf*pkg polynomials at (kf0,kg0)
1296 ikfg = 0
1297 do ikg = 1,nkg
1298 do ikf = 1,nkf
1299 ikfg = ikfg+1
1300 p(ikfg) = pkf0(ikf) * pkg0(ikg)
1301 dpdkf(ikfg) = dpkfdkf0(ikf)*dkf0dkf * pkg0(ikg)
1302 dpdkg(ikfg) = pkf0(ikf) * dpkgdkg0(ikg)*dkg0dkg
1303 end do
1304 end do
1305
1306end subroutine pofk
1307
1308!-----------------------------------------------------------------------------
1309
1310subroutine saturate( x, xc, y, dydx )
1311
1312 ! Defines a function y(x,xc) = 1/(1/x^nsat+1/xc^nsat)^(1/nsat), where nsat
1313 ! is an integer set in the module header. This function is approximately
1314 ! equal to x for x<xc and it saturates to xc when x->infinity
1315
1316 implicit none
1317 real(dp),intent(in) :: x ! Independent variable
1318 real(dp),intent(in) :: xc ! Saturation value
1319 real(dp),intent(out):: y ! Function value
1320 real(dp),intent(out):: dydx ! Derivative dy/dx
1321
1322 real(dp):: z
1323
1324 if (xc<=0._dp) then
1325 call die('sg4vv_vdwxc_saturate ERROR: xc<=0')
1326 else if (x<0._dp) then
1327 call die('sg4vv_vdwxc_saturate ERROR: x<0')
1328 else if (x==0._dp) then
1329 y = 0
1330 dydx = 1
1331 else
1332 z = 1/x**nsat + 1/xc**nsat
1333 y = 1/z**(1._dp/nsat)
1334 dydx = y/z/x**(nsat+1)
1335 end if
1336
1337end subroutine saturate
1338
1339!-----------------------------------------------------------------------------
1340
1341subroutine saturate_inverse( y, xc, x, dxdy )
1342
1343! Finds the inverse of the function defined in saturate subroutine:
1344! y=1/(1/x^n+1/xc^n)^(1/n) => x=1/(1/y^n-1/xc^n)^(1/n)
1345
1346 implicit none
1347 real(dp),intent(in) :: y ! Independent variable
1348 real(dp),intent(in) :: xc ! Saturation value
1349 real(dp),intent(out):: x ! Inverse function value
1350 real(dp),intent(out):: dxdy ! Derivative dx/dy
1351
1352 real(dp):: z
1353
1354 if (xc<=0._dp) then
1355 call die('sg4vv_vdwxc_saturate_inverse ERROR: xc<=0')
1356 else if (y<0._dp .or. y>=xc) then
1357 call die('sg4vv_vdwxc_saturate_inverse ERROR: y out of range')
1358 else if (y==0._dp) then
1359 x = 0
1360 dxdy = 1
1361 else
1362 z = 1/y**nsat - 1/xc**nsat
1363 x = 1/z**(1._dp/nsat)
1364 dxdy = x/z/y**(nsat+1)
1365 end if
1366
1367end subroutine saturate_inverse
1368
1369!-----------------------------------------------------------------------------
1370
1371subroutine set_kmesh()
1372
1373! Sets mesh of q values
1374
1375 implicit none
1376 integer :: mkf, mkg
1377
1378 if (.not.kmesh_set) then
1379 call set_mesh( nkf, xmax=kfcut, dxndx1=dkfmaxdkfmin )
1380 call get_mesh( nkf, mkf, kfmesh )
1381 call set_mesh( nkg, xmax=kgcut, dxndx1=dkgmaxdkgmin )
1382 call get_mesh( nkg, mkg, kgmesh )
1383 kmesh_set = .true.
1384#ifdef DEBUG_XC
1385 write(udebug,'(/,a,/,(10f8.4))') 'sg4vv_vdw_set_kmesh: kfmesh =', kfmesh
1386 write(udebug,'(/,a,/,(10f8.4))') 'sg4vv_vdw_set_kmesh: kgmesh =', kgmesh
1387#endif /* DEBUG_XC */
1388 end if
1389
1390end subroutine set_kmesh
1391
1392! -----------------------------------------------------------------------------
1393
1394subroutine set_phi_table()
1395
1396! Finds and stores in memory the interpolation table (mesh points and
1397! function values) for the kernel phi(k1,k2,k).
1398
1399 implicit none
1400 character(len=*),parameter:: myName = 'sg4vv_vdwxc/set_phi_table '
1401 integer :: ik, ikf1, ikf2, ikg1, ikg2, ik1, ik2, ir
1402 real(dp):: dkdk0, dphidk0, dphidkmax, dphidr0, dphidrmax, &
1403 k, kf1, kf2, kg1, kg2, pi, r(0:nr)
1404
1405! Check that table was not set yet
1406 if (phi_table_set) return
1407
1408! Check that kf, kg, r, and k meshes have been set
1409 if (.not.kmesh_set) call set_kmesh()
1410 if (.not.kcut_set) call die('sg4vv_vdw_set_phi_table ERROR: kcut not set')
1411 forall(ir=0:nr) r(ir) = ir*dr
1412 pi = acos(-1.0_dp)
1413
1414! Allocate arrays
1415 call re_alloc( phir, 0,nr, 1,nkfg, 1,nkfg, myName//'phir' )
1416 call re_alloc( phik, 0,nr, 1,nkfg, 1,nkfg, myName//'phik' )
1417 call re_alloc( d2phidr2, 0,nr, 1,nkfg, 1,nkfg, myName//'d2phidr2' )
1418 call re_alloc( d2phidk2, 0,nr, 1,nkfg, 1,nkfg, myName//'d2phidk2' )
1419
1420! Loop on (k1,k2) mesh points
1421 do ikg2 = 1,nkg ! loop on kg2
1422 do ikf2 = 1,nkf ! loop on kf2
1423 ik2 = ikf2 + nkf*(ikg2-1) ! combined (ikf2,ikg2) index
1424 do ikg1 = 1,nkg ! loop on kg1
1425 do ikf1 = 1,nkf ! loop on kf1
1426 ik1 = ikf1 + nkf*(ikg1-1) ! combined (ikf1,ikg1) index
1427 if (ik1>ik2) cycle ! since we will symmetrize at the end
1428
1429 ! Saturated (kf,kg) values
1430 kf1 = kfmesh(ikf1)
1431 kf2 = kfmesh(ikf2)
1432 kg1 = kgmesh(ikg1)
1433 kg2 = kgmesh(ikg2)
1434
1435 ! Find original (unsaturated) kf anf kg values
1436 ! call saturate_inverse( kfmesh(ikf1), kfcut, kf1, dkdk0 )
1437 ! call saturate_inverse( kfmesh(ikf2), kfcut, kf2, dkdk0 )
1438 ! call saturate_inverse( kgmesh(ikg1), kgcut, kg1, dkdk0 )
1439 ! call saturate_inverse( kgmesh(ikg2), kgcut, kg2, dkdk0 )
1440
1441 ! Find kernel as a function of r12
1442 do ir = 0,nr
1443 phir(ir,ik1,ik2) = sg4vv_vdw_phi_val( kf1, kf2, kg1, kg2, r(ir) )
1444 end do
1445
1446 ! Kill kernel smoothly at r=rcut
1447 do ir = 0,nr
1448 phir(ir,ik1,ik2) = phir(ir,ik1,ik2) * cutoff( r(ir)/rcut )
1449 end do
1450
1451 ! Find kernel in reciprocal space
1452 call radfft( 0, nr, rcut, phir(:,ik1,ik2), phik(:,ik1,ik2) )
1453 phik(:,ik1,ik2) = phik(:,ik1,ik2) * (2*pi)**1.5_dp
1454
1455 ! Filter out above kcut
1456 phik(nk:nr,ik1,ik2) = 0
1457
1458 ! Soft filter below kcut
1459 do ik = 1,nk
1460 k = ik * dk
1461 phik(ik,ik1,ik2) = phik(ik,ik1,ik2) * cutoff(k/kcut)
1462 end do
1463
1464 ! Find filtered kernel in real space
1465 call radfft( 0, nr, kmax, phik(:,ik1,ik2), phir(:,ik1,ik2) )
1466 phir(:,ik1,ik2) = phir(:,ik1,ik2) / (2*pi)**1.5_dp
1467
1468 ! Set up spline interpolation tables
1469 dphidr0 = 0 ! since phi(k1,k2,r) is even in r
1470 dphidk0 = 0 ! and therefore phi(k1,k2,k) is also even in k
1471 dphidrmax = 0 ! since phi->0 for r->infty
1472 dphidkmax = 0 ! and also when k->infty
1473 call spline( dr, phir(:,ik1,ik2), nr+1, dphidr0, dphidrmax, &
1474 d2phidr2(:,ik1,ik2) )
1475 call spline( dk, phik(:,ik1,ik2), nk+1, dphidk0, dphidkmax, &
1476 d2phidk2(:,ik1,ik2) )
1477
1478 ! Fill symmetric elements
1479 phir(:,ik2,ik1) = phir(:,ik1,ik2)
1480 phik(:,ik2,ik1) = phik(:,ik1,ik2)
1481 d2phidr2(:,ik2,ik1) = d2phidr2(:,ik1,ik2)
1482 d2phidk2(:,ik2,ik1) = d2phidk2(:,ik1,ik2)
1483
1484!#ifdef DEBUG_XC
1485! if (.false. .and. ik1==ik2) then
1486! print*, 'sg4vv_vdw_set_kcut: ik1,ik2=', ik1, ik2
1487! call window( 0._dp, 5._dp, -1._dp, 4._dp, 0 )
1488! call axes( 0._dp, 1._dp, 0._dp, 1._dp )
1489! call plot( nr+1, r, phi, phir(:,ik1,ik2) )
1490! call window( 0._dp, 10._dp, -0.05_dp, 0.15_dp, 0 )
1491! call axes( 0._dp, 1._dp, 0._dp, 0.05_dp )
1492! call plot( nr+1, r, r**2*phi, r**2*phir(:,ik1,ik2))
1493! call show()
1494! end if
1495!#endif /* DEBUG_XC */
1496
1497 end do ! ikf1
1498 end do ! ikg1
1499 end do ! ikf2
1500 end do ! ikg2
1501
1502!#ifdef DEBUG_XC
1503! open(17,file='vv_phi.table')
1504! write(17,'(3a6,2a12,/,(3i6,2f15.9))') &
1505! 'ik1', 'ik2', 'ir', 'phi', 'd2phi/dk2', &
1506!! (((ik1,ik2,ir,phir(ir,ik1,ik2),d2phidr2(ir,ik1,ik2), &
1507! (((ik1,ik2,ir,phik(ir,ik1,ik2),d2phidk2(ir,ik1,ik2), &
1508! ir=0,100),ik2=1,nkfg),ik1=1,nkfg)
1509! close(17)
1510!#endif /* DEBUG_XC */
1511
1512! Mark table as set
1513 phi_table_set = .true.
1514
1515end subroutine set_phi_table
1516
1517! -----------------------------------------------------------------------------
1518
1519real(dp) function sg4vv_vdw_phi_val( kf1, kf2, kg1, kg2, r12 )
1520
1521! vdW energy kernel of Vydrov-vanVoorhis, eq.(2) of JCP 133, 244103 (2010)
1522! This subroutine calculates the 'raw' kernel directly, without interpolarions
1523! In practice, it returns n1*n2*phi(k1,k2,r12), which is smooth for kf->0
1524! Input:
1525! real(dp):: kf1, kf2 ! Fermi wavevectors at points 1 and 2
1526! real(dp):: kg1, kg2 ! |grad(n)|/n at points 1 and 2
1527! real(dp):: r12 ! distance between points 1 and 2
1528
1529! Arguments
1530 implicit none
1531 real(dp),intent(in) :: kf1, kf2, kg1, kg2, r12
1532
1533! Internal variables
1534 real(dp):: g1, g2, kappa1, kappa2, kf1m, kf2m, n1, n2, &
1535 phi, pi, w01, w02, wg1, wg2, wp1, wp2
1536
1537! Avoid dividing by zero when kf=0
1538 kf1m = max(kf1,ktol)
1539 kf2m = max(kf2,ktol)
1540
1541! Find kernel
1542 pi = acos(-1.0_dp)
1543 n1 = kf1m**3/(3*pi**2) ! electron density at point 1
1544 n2 = kf2m**3/(3*pi**2) ! electron density at point 2
1545 wp1 = sqrt(4*pi*n1) ! local plasma frequency at point 1
1546 wp2 = sqrt(4*pi*n2) ! local plasma frequency at point 2
1547 wg1 = sqrt(vv_C*kg1**4) ! local band gap at point 1
1548 wg2 = sqrt(vv_C*kg2**4) ! local band gap at point 2
1549 kappa1 = vv_b*kf1m**2/wp1 ! local VV kappa variable (eq.(9)) at point 1
1550 kappa2 = vv_b*kf2m**2/wp2 ! kappa variable at point 2
1551 w01 = sqrt(wg1**2+wp1**2/3) ! local w0 frequency (eq.(5)) at point 1
1552 w02 = sqrt(wg2**2+wp2**2/3) ! local w0 frequency at point 2
1553 g1 = w01*r12**2 + kappa1 ! local g variable (eq.(3)) at point 1
1554 g2 = w02*r12**2 + kappa2 ! local g variable at point 2
1555 phi = -1.5_dp/g1/g2/(g1+g2) ! VV kernel phi (eq.(2))
1556
1557 if (kernelPrefactor=='rho') then
1558 ! Return whole integrand of eq.(1)
1559 sg4vv_vdw_phi_val = n1*n2*phi
1560 else if (kernelPrefactor=='kf') then
1561 ! Return kf1*kf2*phi
1562 sg4vv_vdw_phi_val = kf1*kf2*phi
1563 else if (kernelPrefactor=='kf2') then
1564 ! Return (kf1*kf2)**2*phi
1565 sg4vv_vdw_phi_val = (kf1*kf2)**2*phi
1566 else if (kernelPrefactor=='sqr_rho') then
1567 ! Find and return sqrt(n1*n2)*phi
1568 sg4vv_vdw_phi_val = sqrt(n1*n2)*phi
1569 else
1570 call die('sg4vv_vdw_phi_val ERROR: unknown kernelPrefactor')
1571 end if
1572
1573end function sg4vv_vdw_phi_val
1574
1575! -----------------------------------------------------------------------------
1576
1577real(dp) function sg4vv_vdw_beta()
1578
1579! Returns parameter beta of VV functional
1580
1581 implicit none
1582 sg4vv_vdw_beta = vv_beta
1583
1584end function sg4vv_vdw_beta
1585
1586!-----------------------------------------------------------------------------
1587
1588subroutine sg4vv_vdw_get_kmesh( mkf, mkg, kf, kg )
1589
1590! Returns size and values of (kf,kg) mesh
1591
1592 implicit none
1593 integer, intent(out) :: mkf ! Number of kf mesh points
1594 integer, intent(out) :: mkg ! Number of kg mesh points
1595 real(dp),optional,intent(out) :: kf(:) ! Values of kf mesh points
1596 real(dp),optional,intent(out) :: kg(:) ! Values of kg mesh points
1597 integer:: nmax
1598 if (.not.kmesh_set) call set_kmesh()
1599 mkf = nkf
1600 mkg = nkg
1601 if (present(kf)) then
1602 nmax = max( nkf, size(kf) )
1603 kf(1:nmax) = kfmesh(1:nmax)
1604 end if
1605 if (present(kg)) then
1606 nmax = max( nkg, size(kg) )
1607 kg(1:nmax) = kgmesh(1:nmax)
1608 end if
1609end subroutine sg4vv_vdw_get_kmesh
1610
1611! -----------------------------------------------------------------------------
1612
1613subroutine sg4vv_vdw_phi( k, phi, dphidk )
1614
1615! Finds by interpolation phi(k1,k2,k) (Fourier transform of phi(k1,k2,r)),
1616! with k1=(kf1,kg1), k2=(kf2,kg2) for all mesh values of kf (Fermi
1617! wavevector) and kg (grad(n)/n). If the interpolation table does not exist,
1618! it is calculated in the first call to sg4vv_vdw_phi. It requires a previous
1619! call to sg4vv_vdw_set_kc to set k mesh.
1620
1621 implicit none
1622 real(dp),intent(in) :: k ! Modulus of actual k vector
1623 real(dp),intent(out):: phi(:,:) ! phi(k1,k2,k) at given k
1624 ! for all k1,k2 in (kf,kg) mesh
1625 real(dp),intent(out):: dphidk(:,:) ! dphi(k1,k2,k)/dk at given k
1626
1627 integer :: ik, ik1, ik2
1628 real(dp):: a, a2, a3, b, b2, b3
1629
1630! Set interpolation table
1631 if (.not.phi_table_set) call set_phi_table()
1632
1633! Check argument sizes
1634 if (size(phi,1)<nkfg .or. size(phi,2)<nkfg) &
1635 call die('sg4vv_vdw_phi: ERROR: size(phi) too small')
1636
1637! Find phi values at point k
1638 if (k >= kcut) then
1639 phi(:,:) = 0
1640 dphidk(:,:) = 0
1641 else
1642 ! Expand interpolation inline since this is the hottest point in VdW
1643 ik = int(k/dk)
1644 a = ((ik+1)*dk-k)/dk
1645 b = 1 - a
1646 a2 = (3*a**2 -1) * dk / 6
1647 b2 = (3*b**2 -1) * dk / 6
1648 a3 = (a**3 - a) * dk**2 / 6
1649 b3 = (b**3 - b) * dk**2 / 6
1650 do ik2 = 1,nkfg
1651 do ik1 = 1,ik2
1652! call splint( dk, phik(:,ik1,ik2), d2phidk2(:,ik1,ik2), &
1653! nk+1, k, phi(ik1,ik2), dphidk(ik1,ik2), pr )
1654 phi(ik1,ik2) = a*phik(ik,ik1,ik2) + b*phik(ik+1,ik1,ik2) &
1655 + a3*d2phidk2(ik,ik1,ik2) + b3*d2phidk2(ik+1,ik1,ik2)
1656 dphidk(ik1,ik2) = (-phik(ik,ik1,ik2) &
1657 +phik(ik+1,ik1,ik2) )/dk &
1658 - a2*d2phidk2(ik,ik1,ik2) + b2*d2phidk2(ik+1,ik1,ik2)
1659 phi(ik2,ik1) = phi(ik1,ik2)
1660 dphidk(ik2,ik1) = dphidk(ik1,ik2)
1661 end do
1662 end do
1663 end if
1664
1665end subroutine sg4vv_vdw_phi
1666
1667!-----------------------------------------------------------------------------
1668
1669subroutine sg4vv_vdw_phiofr( r, phi )
1670
1671! Finds phi(k1,k2,r) with k1=(kf1,kg1), k2=(kf2,kg2) for mesh values of
1672! kf's (Fermi wavevectors) and kg's (grad(n)/n)
1673
1674 implicit none
1675 real(dp),intent(in) :: r
1676 real(dp),intent(out):: phi(:,:)
1677
1678 integer :: ikf1, ikf2, ikg1, ikg2, ik1, ik2
1679 real(dp):: dphidr
1680
1681 if (size(phi,1)<nkfg .or. size(phi,2)<nkfg) &
1682 stop 'vv_phiofr: ERROR: size(phi) too small'
1683 if (.not.phi_table_set) call set_phi_table()
1684
1685 if (r >= rcut) then
1686 phi(:,:) = 0
1687 else
1688 do ik2 = 1,nkfg
1689 do ik1 = 1,ik2
1690 call splint( dr, phir(:,ik1,ik2), d2phidr2(:,ik1,ik2), &
1691 nr+1, r, phi(ik1,ik2), dphidr )
1692 phi(ik2,ik1) = phi(ik1,ik2)
1693 end do ! ik1
1694 end do ! ik2
1695 end if ! (r>=rcut)
1696
1697end subroutine sg4vv_vdw_phiofr
1698
1699!-----------------------------------------------------------------------------
1700
1701subroutine sg4vv_vdw_set_kcut( kc )
1702
1703! Sets the reciprocal planewave cutoff kc of the integration grid, and finds
1704! the interpolation table to be used by vdw_phi to obtain the vdW kernel phi
1705! at the reciprocal mesh wavevectors.
1706
1707 implicit none
1708 real(dp),intent(in):: kc ! Planewave cutoff: k>kcut => phi=0
1709
1710 real(dp):: pi
1711
1712 ! Set kcut and radial mesh parameters, if not already set
1713 if (.not. kc==kcut) then
1714 kcut = kc
1715 pi = acos(-1._dp)
1716 dr = rcut / nr
1717 dk = pi / rcut
1718 kmax = pi / dr
1719 nk = int(kcut/dk) + 1
1720 if (nk>nr) stop 'sg4vv_vdw_set_kcut: ERROR: nk>nr'
1721 kcut_set = .true.
1722#ifdef DEBUG_XC
1723 write(udebug,'(a,5f8.3)') 'sg4vv_vdw_set_kcut: kfcut,kgcut,rcut,kcut,kmax=', &
1724 kfcut, kgcut, rcut, kc, kmax
1725#endif /* DEBUG_XC */
1726 end if
1727
1728 ! Set (kf,kg) mesh and phi table
1729 call set_kmesh()
1730 call set_phi_table()
1731
1732end subroutine sg4vv_vdw_set_kcut
1733
1734!-----------------------------------------------------------------------------
1735
1736subroutine sg4vv_vdw_theta( nspin, rhos, grhos, theta, dtdrho, dtdgrho )
1737
1738! Finds the value and derivatives of theta_i(rho,grad_rho) of eq.(8)
1739! of Roman-Soler PRL 2009. In practice, theta_i=p_i rather than rho*p_i,
1740! beacuse p_i is used here to expand rho1*rho2*phi rather than only phi.
1741
1742 implicit none
1743 integer, intent(in) :: nspin ! Number of spin components
1744 real(dp),intent(in) :: rhos(nspin) ! Electron spin density
1745 real(dp),intent(in) :: grhos(3,nspin) ! Spin density gradient
1746 real(dp),intent(out):: theta(nkfg) ! Exp. polynomials at (kf,kg)
1747 real(dp),intent(out):: dtdrho(nkfg,nspin) ! dtheta(ik)/drhos
1748 real(dp),intent(out):: dtdgrho(3,nkfg,nspin) ! dtheta(ik)/dgrhos(ix)
1749
1750 integer :: is, ix, ns
1751 real(dp):: rho, grho(3), dpdkf(nkfg), dpdkg(nkfg), dkfdrho, dkfdgrho(3), &
1752 dkgdrho, dkgdgrho(3), kf, kg, p(nkfg)
1753
1754 ! Sum spin components of electron density
1755 ns = min(nspin,2) ! num. of diagonal spin components (if noncollinear)
1756 rho = sum(rhos(1:ns)) ! local electron density
1757 grho = sum(grhos(:,1:ns),dim=2) ! local density gradient
1758
1759 ! If density is between threshold, return zero
1760 if (rho<rhoMin) then
1761 theta = 0
1762 dtdrho = 0
1763 dtdgrho = 0
1764 return
1765 end if
1766
1767 ! Find local Fermi and gradient wavevectors, and their derivatives
1768 call kofn( rho, grho, kf, kg, dkfdrho, dkgdrho, dkfdgrho, dkgdgrho )
1769
1770 ! Find expansion polynomials of integrand kernel of nonlocal vdW energy
1771 call pofk( kf, kg, p, dpdkf, dpdkg )
1772
1773 ! Find theta functions and their derivatives with respect to rho and grho
1774 if (kernelPrefactor=='rho') then
1775 ! This is the right code if sg4vv_vdw_phi_val returns rho1*rho2*phi
1776 theta(1:nkfg) = p(1:nkfg)
1777 do is = 1,ns
1778 dtdrho(1:nkfg,is) = dpdkf(1:nkfg)*dkfdrho + dpdkg(1:nkfg)*dkgdrho
1779 do ix = 1,3
1780 dtdgrho(ix,1:nkfg,is) = dpdkf(1:nkfg)*dkfdgrho(ix) &
1781 + dpdkg(1:nkfg)*dkgdgrho(ix)
1782 end do
1783 end do
1784 else if (kernelPrefactor=='kf') then
1785 ! This is the right code if sg4vv_vdw_phi_val returns kf1*kf2*phi
1786 kf = max(kf,ktol)
1787 theta(1:nkfg) = p(1:nkfg)*rho/kf
1788 do is = 1,ns
1789 dtdrho(1:nkfg,is) = (dpdkf(1:nkfg)*dkfdrho &
1790 +dpdkg(1:nkfg)*dkgdrho)*rho/kf &
1791 + p(1:nkfg)*(1/kf-rho/kf**2*dkfdrho)
1792 do ix = 1,3
1793 dtdgrho(ix,1:nkfg,is) = (dpdkf(1:nkfg)*dkfdgrho(ix) &
1794 +dpdkg(1:nkfg)*dkgdgrho(ix))*rho/kf
1795 end do
1796 end do
1797 else if (kernelPrefactor=='kf2') then
1798 ! This is the right code if sg4vv_vdw_phi_val returns (kf1*kf2)**2*phi
1799 kf = max(kf,ktol)
1800 theta(1:nkfg) = p(1:nkfg)*rho/kf**2
1801 do is = 1,ns
1802 dtdrho(1:nkfg,is) = (dpdkf(1:nkfg)*dkfdrho &
1803 +dpdkg(1:nkfg)*dkgdrho)*rho/kf**2 &
1804 + p(1:nkfg)*(1/kf**2-2*rho/kf**3*dkfdrho)
1805 do ix = 1,3
1806 dtdgrho(ix,1:nkfg,is) = (dpdkf(1:nkfg)*dkfdgrho(ix) &
1807 +dpdkg(1:nkfg)*dkgdgrho(ix))*rho/kf**2
1808 end do
1809 end do
1810 else if (kernelPrefactor=='sqr_rho') then
1811 ! This is the right code if sg4vv_vdw_phi_val returns sqrt(rho1*rho2)*phi
1812 rho = max(rho,1.e-12_dp) ! to avoid division by zero
1813 theta(1:nkfg) = p(1:nkfg) * sqrt(rho)
1814 do is = 1,ns
1815 dtdrho(1:nkfg,is) = ( dpdkf(1:nkfg)*dkfdrho &
1816 + dpdkg(1:nkfg)*dkgdrho ) * sqrt(rho) &
1817 + p(1:nkfg) * 0.5/sqrt(rho)
1818 do ix = 1,3
1819 dtdgrho(ix,1:nkfg,is) = dpdkf(1:nkfg)*dkfdgrho(ix) * sqrt(rho) &
1820 + dpdkg(1:nkfg)*dkgdgrho(ix) * sqrt(rho)
1821 end do
1822 end do
1823 else
1824 call die('sg4vv_vdw_theta ERROR: unknown kernelPrefactor')
1825 end if ! (kernelPrefactor=='rho')
1826
1827end subroutine sg4vv_vdw_theta
1828
1829END MODULE m_sg4vv_vdwxc
1830
1831!!!=============== PBE+VV10 ========================
1832
1833MODULE m_pbevv_vdwxc
1834
1835! Used module procedures
1836 use sys, only: die ! Termination routine
1837 use mesh1D, only: get_mesh ! Returns the mesh points
1838 use m_radfft, only: radfft ! Radial fast Fourier transform
1839 use alloc, only: re_alloc ! Re-allocation routine
1840 use mesh1D, only: set_mesh ! Sets a 1D mesh
1841 use interpolation,only: spline ! Sets spline interpolation
1842 use interpolation,only: splint ! Calculates spline interpolation
1843
1844! Used module parameters
1845 use precision, only: dp ! Real double precision type
1846
1847#ifdef DEBUG_XC
1848 use debugXC, only: udebug ! File unit for debug output
1849! use plot_module, only: plot
1850#endif /* DEBUG_XC */
1851
1852 implicit none
1853
1854! Called by m_vdwxc
1855PUBLIC :: &
1856 pbevv_vdw_beta, &! Returns parameter beta of the VV2010 functional
1857 pbevv_vdw_theta, &! Finds function theta_ik(rho,grad_rho)
1858 pbevv_vdw_get_kmesh, &! Returns size and values of (kf,kg) mesh
1859 pbevv_vdw_phi, &! Finds and interpolates rho1*rho2*phi(k1,k2,k)
1860 pbevv_vdw_set_kcut ! Sets the planewave cutoff kc of the integration grid
1861
1862#ifdef DEBUG_XC
1863! Called by debugging test programs
1864PUBLIC :: &
1865 pbevv_vdw_phi_val, &! Kernel phi(kf1,kf2,kg1,kg2,r12) with no interpolation
1866 pbevv_vdw_phiofr ! Kernel phi(k1,k2,r) at tabulated k1,k2-mesh values
1867#endif /* DEBUG_XC */
1868
1869PRIVATE ! Nothing is declared public beyond this point
1870
1871 ! Set parameters of the PBE+rVV10,
1872 ! Ref. H. Peng and J. P. Perdew, Phys. Rev. B 95, 0811105 (2017)
1873 real(dp),parameter:: vv_C = 0.0093
1874 real(dp),parameter:: vv_b = 10.0
1875 real(dp),parameter:: vv_beta = 0.00497
1876
1877 ! Mesh parameters for table of phi(k1,k2,r) and its Fourier transform
1878 character(len=*),parameter:: kernelPrefactor='rho' ! Prefactor of the
1879 ! nonlocal kernel for interpolation
1880 ! ('kf'|'kf2'|'sqr_rho'|'rho')
1881 integer, parameter:: nr = 2048 ! Radial mesh points (power of 2)
1882 real(dp),parameter:: rcut = 100._dp ! Radial cutoff: r>rcut => phi=0
1883 real(dp),parameter:: rmin = 1.e-6_dp ! Min. radius as denominator
1884 integer, parameter:: nkf = 7 ! Number of Fermi wavevectors
1885 integer, parameter:: nkg = 5 ! Num. of grad(n)/n wavevectors
1886 integer, parameter:: nkfg = nkf*nkg ! Num. of (kf,kg) mesh points
1887 real(dp),parameter:: kfcut = 5.0_dp ! Max. Fermi wavevec.
1888 real(dp),parameter:: kgcut = 5.0_dp ! Max. grad(n)/n
1889 real(dp),parameter:: dkfmaxdkfmin = 20.0_dp ! Last/first kf mesh interval
1890 real(dp),parameter:: dkgmaxdkgmin = 2.0_dp ! Last/first kg mesh interval
1891 real(dp),parameter:: ktol = 1.e-12_dp ! 'out of range' tolerance
1892 real(dp),parameter:: amin = 1.e-12_dp ! tiny denominator to avoid /0
1893 real(dp),parameter:: rhoMin = 1.e-10_dp ! Min. density for nonzero Vxc
1894
1895 ! Parameters for cutoff function, used in radial Fourier transforms of phi
1896 integer, parameter:: ncut1 = 8 ! cutoff(x)=(1-x**ncut1)**ncut2
1897 integer, parameter:: ncut2 = 4
1898
1899 ! Parameters for saturate function, used to enforce that q<qcut
1900 integer, parameter:: nsat = 15 ! h(x,xc)=1/(1/x**nsat+1/xc**nsat)**(1/nsat)
1901 ! nsat=15 approximately corresponds to
1902 ! nsat=12 for eq.(5) of Roman-Soler PRL
1903
1904 ! Private module variables and arrays
1905 logical, save:: kcut_set=.false. ! Has kcut been set?
1906 logical, save:: kmesh_set=.false. ! Has (kf,kg) mesh been set?
1907 logical, save:: phi_table_set=.false. ! Has phi_table been set?
1908 integer, save:: nk ! Num. of radial mesh k-points
1909 real(dp),save:: dr ! r-mesh interval
1910 real(dp),save:: dk ! k-mesh interval
1911 real(dp),save:: kcut ! Planewave cutoff: k>kcut => phi=0
1912 real(dp),save:: kmax ! Max. k vector in Fourier transforms
1913 real(dp),save:: kfmesh(nkf) ! Mesh points for Fermi wavevector
1914 real(dp),save:: kgmesh(nkg) ! Mesh points for grad(n)/n
1915 real(dp),pointer,save:: &
1916 phir(:,:,:)=>null(), &! Table of phi(r)
1917 phik(:,:,:)=>null(), &! Table of phi(k)
1918 d2phidr2(:,:,:)=>null(),&! Table of d^2(phi)/dr^2
1919 d2phidk2(:,:,:)=>null() ! Table of d^2(phi)/dk^2
1920
1921CONTAINS
1922
1923! -----------------------------------------------------------------------------
1924
1925real(dp) function cutoff( x )
1926
1927! Defines a smooth cutoff function that falls from y(0)=1 to y(1)=0
1928
1929 implicit none
1930 real(dp),intent(in):: x
1931
1932 if (x<=0._dp) then
1933 cutoff = 1
1934 else if (x>=1._dp) then
1935 cutoff = 0
1936 else
1937 cutoff = (1-x**ncut1)**ncut2
1938 end if
1939
1940end function cutoff
1941
1942!-----------------------------------------------------------------------------
1943
1944subroutine iofk( kf, kg, ikf, ikg )
1945
1946! Finds indexes ikf and ikg such that kfmesh(ikf) <= kf < kfmesh(ikf+1)
1947! and kgmesh(ikg) <= kg < kgmesh(ikg+1) in logarithmic meshes of the form
1948! k(ik) = b*(exp((ik-1)*a)-1)
1949
1950 implicit none
1951 real(dp), intent(in) :: kf, kg
1952 integer, intent(out):: ikf, ikg
1953
1954 real(dp),save:: akf, akg, bkf, bkg
1955 logical, save:: first_call = .true.
1956 integer:: ik
1957
1958 ! Mesh data initializations
1959 if (first_call) then
1960 ! Find logarithmic-mesh a & b parameters: x(j)=x(1)+b*(exp(a*(j-1))-1)
1961 akf = log( (kfmesh(nkf)-kfmesh(nkf-1)) / (kfmesh(2)-kfmesh(1)) ) / (nkf-2)
1962 akg = log( (kgmesh(nkg)-kgmesh(nkg-1)) / (kgmesh(2)-kgmesh(1)) ) / (nkg-2)
1963 akf = max( akf, amin )
1964 akg = max( akg, amin )
1965 bkf = (kfmesh(nkf) - kfmesh(1)) / (exp(akf*(nkf-1)) - 1)
1966 bkg = (kgmesh(nkg) - kgmesh(1)) / (exp(akg*(nkg-1)) - 1)
1967 ! Check that meshes are indeed logarithmic
1968 do ik = 1,nkf
1969 if (abs(kfmesh(ik)-kfmesh(1)-bkf*(exp(akf*(ik-1))-1))>ktol) &
1970 call die('pbevv_vdw_iofk ERROR: kfmesh not logarithmic')
1971 end do
1972 do ik = 1,nkg
1973 if (abs(kgmesh(ik)-kgmesh(1)-bkg*(exp(akg*(ik-1))-1))>ktol) &
1974 call die('pbevv_vdw_iofk ERROR: kgmesh not logarithmic')
1975 end do
1976 first_call = .false.
1977 end if
1978
1979 ! Check that kf and kg are within interpolation range
1980 if (kf<kfmesh(1)-ktol .or. kf>kfmesh(nkf)+ktol .or. &
1981 kg<kgmesh(1)-ktol .or. kg>kgmesh(nkg)+ktol) then
1982 call die('pbevv_vdw_iofk ERROR: (kf,kg) out of range')
1983 endif
1984
1985 ! Find interpolation mesh intervals
1986 ikf = 1 + int( log( 1 + (kf-kfmesh(1))/bkf ) / akf )
1987 ikg = 1 + int( log( 1 + (kg-kgmesh(1))/bkg ) / akg )
1988 ikf = max( 1, ikf )
1989 ikg = max( 1, ikg )
1990 ikf = min( nkf-1, ikf )
1991 ikg = min( nkg-1, ikg )
1992
1993end subroutine iofk
1994
1995! -----------------------------------------------------------------------------
1996
1997subroutine kofn( n, gn, kf, kg, dkfdn, dkgdn, dkfdgn, dkgdgn )
1998
1999! Finds Fermi and gradient wavevectors from density and gradient
2000
2001 implicit none
2002 real(dp), intent(in) :: n ! Electron density
2003 real(dp), intent(in) :: gn(3) ! Density gradient
2004 real(dp), intent(out):: kf ! Local Fermi wavevector
2005 real(dp), intent(out):: kg ! |grad(n)|/n
2006 real(dp), intent(out):: dkfdn ! dkf/dn
2007 real(dp), intent(out):: dkgdn ! dkg/dn
2008 real(dp), intent(out):: dkfdgn(3) ! dkf/dgn
2009 real(dp), intent(out):: dkgdgn(3) ! dkg/dgn
2010
2011 real(dp):: gn2, pi
2012
2013! Trap exception for zero density
2014 if (n <= 1.e-30_dp) then
2015 kf = 0
2016 kg = 0
2017 dkfdn = 0
2018 dkfdgn = 0
2019 dkgdn = 0
2020 dkgdgn = 0
2021 return
2022 end if
2023
2024! Find kf and kg
2025 pi = acos(-1._dp)
2026 kf = (3*pi**2*n)**(1._dp/3)
2027 gn2 = sum(gn**2)
2028 kg = sqrt(gn2)/n
2029
2030! Find derivatives
2031 dkfdn = kf/n/3
2032 dkfdgn = 0
2033 dkgdn = -kg/n
2034 dkgdgn = kg*gn/gn2
2035
2036end subroutine kofn
2037
2038!-----------------------------------------------------------------------------
2039
2040subroutine pofk( kf, kg, p, dpdkf, dpdkg )
2041
2042! Finds the values and derivatives, at (kf,kg), of the bicubic polynomials
2043! p_i(kf,kg) such that
2044! y(kf,kg) = Sum_i p_i(kf,kg) * y_i
2045! is the bicubic spline interpolation at (kf,kg) of (any) function y with
2046! values y_i at mesh points (kfmesh,kgmesh)_i
2047
2048 implicit none
2049 real(dp),intent(in) :: kf, kg ! point at which the polynomials are required
2050 real(dp),intent(out):: p(nkfg) ! polynomial values at (kf,kg)
2051 real(dp),intent(out):: dpdkf(nkfg) ! dp/dkf at (kf,kg)
2052 real(dp),intent(out):: dpdkg(nkfg) ! dp/dkg at (kf,kg)
2053
2054 integer :: ikf, ikg, ikfg, ikf0, ikg0
2055 real(dp):: a, b, dk, dkf0dkf, dkg0dkg, kf0, kg0
2056 real(dp):: pkf0(nkf), dpkfdkf0(nkf), pkg0(nkg), dpkgdkg0(nkg)
2057 logical, save :: first_call=.true.
2058 real(dp),save :: pkf(nkf,nkf), d2pkfdkf2(nkf,nkf)
2059 real(dp),save :: pkg(nkg,nkg), d2pkgdkg2(nkg,nkg)
2060
2061! Set up spline polynomial basis
2062 if (first_call) then
2063 do ikf = 1,nkf
2064 pkf(:,ikf) = 0 ! ikf'th polynomial pkf(:,ikf) is one at kfmesh(ikf)
2065 pkf(ikf,ikf) = 1 ! and zero at all other points
2066 call spline( kfmesh, pkf(:,ikf), nkf, 1.e30_dp, 1.e30_dp, &
2067 d2pkfdkf2(:,ikf) )
2068! call spline( kfmesh, pkf(:,ikf), nkf, 0._dp, 0._dp, d2pkfdkf2(:,ikf) )
2069 end do
2070 do ikg = 1,nkg
2071 pkg(:,ikg) = 0
2072 pkg(ikg,ikg) = 1
2073 call spline( kgmesh, pkg(:,ikg), nkg, 1.e30_dp, 1.e30_dp, &
2074 d2pkgdkg2(:,ikg) )
2075! call spline( kgmesh, pkg(:,ikg), nkg, 0._dp, 0._dp, d2pkgdkg2(:,ikg) )
2076 end do
2077
2078! DEBUG
2079 open(22,file='pkf.dat')
2080 do ikf = 1,nkf
2081 write(22,'(20e15.6)') kfmesh(ikf), pkf(:,ikf), d2pkfdkf2(:,ikf)
2082 end do
2083 close(22)
2084 open(22,file='pkg.dat')
2085 do ikg = 1,nkg
2086 write(22,'(20e15.6)') kgmesh(ikg), pkg(:,ikg), d2pkgdkg2(:,ikg)
2087 end do
2088 close(22)
2089! END DEBUG
2090
2091 first_call = .false.
2092 end if
2093
2094! 'Saturate' (kf,kg) values to bring them to interpolation range
2095 call saturate( kf, kfcut, kf0, dkf0dkf )
2096 call saturate( kg, kgcut, kg0, dkg0dkg )
2097
2098! Find interval of k mesh in which (kf0,kg0) point is included
2099 call iofk( kf0, kg0, ikf0, ikg0 )
2100
2101! Evaluate pkf polynomials of spline basis at kf0
2102! The splint code is in-lined here because it is a hot point
2103 dk = kfmesh(ikf0+1) - kfmesh(ikf0)
2104 a = (kfmesh(ikf0+1) - kf0) / dk ! dadkf0 = -1/dk
2105 b = (kf0 - kfmesh(ikf0)) / dk ! dbdkf0 = +1/dk
2106 do ikf = 1,nkf
2107 pkf0(ikf) = a*pkf(ikf0,ikf) + b*pkf(ikf0+1,ikf) &
2108 + ((a**3-a)*d2pkfdkf2(ikf0,ikf) + &
2109 (b**3-b)*d2pkfdkf2(ikf0+1,ikf)) * dk**2/6
2110 dpkfdkf0(ikf) = - (pkf(ikf0,ikf) - pkf(ikf0+1,ikf)) / dk &
2111 - ((3*a**2-1)*d2pkfdkf2(ikf0,ikf) - &
2112 (3*b**2-1)*d2pkfdkf2(ikf0+1,ikf)) * dk/6
2113 end do
2114
2115! Evaluate pkg polynomials of spline basis at kg0
2116 dk = kgmesh(ikg0+1) - kgmesh(ikg0)
2117 a = (kgmesh(ikg0+1) - kg0) / dk ! dadkg0 = -1/dk
2118 b = (kg0 - kgmesh(ikg0)) / dk ! dbdkg0 = +1/dk
2119 do ikg = 1,nkg
2120 pkg0(ikg) = a*pkg(ikg0,ikg) + b*pkg(ikg0+1,ikg) &
2121 + ((a**3-a)*d2pkgdkg2(ikg0,ikg) + &
2122 (b**3-b)*d2pkgdkg2(ikg0+1,ikg)) * dk**2/6
2123 dpkgdkg0(ikg) = - (pkg(ikg0,ikg) - pkg(ikg0+1,ikg)) / dk &
2124 - ((3*a**2-1)*d2pkgdkg2(ikg0,ikg) - &
2125 (3*b**2-1)*d2pkgdkg2(ikg0+1,ikg)) * dk/6
2126 end do
2127
2128! Evaluate pkf*pkg polynomials at (kf0,kg0)
2129 ikfg = 0
2130 do ikg = 1,nkg
2131 do ikf = 1,nkf
2132 ikfg = ikfg+1
2133 p(ikfg) = pkf0(ikf) * pkg0(ikg)
2134 dpdkf(ikfg) = dpkfdkf0(ikf)*dkf0dkf * pkg0(ikg)
2135 dpdkg(ikfg) = pkf0(ikf) * dpkgdkg0(ikg)*dkg0dkg
2136 end do
2137 end do
2138
2139end subroutine pofk
2140
2141!-----------------------------------------------------------------------------
2142
2143subroutine saturate( x, xc, y, dydx )
2144
2145 ! Defines a function y(x,xc) = 1/(1/x^nsat+1/xc^nsat)^(1/nsat), where nsat
2146 ! is an integer set in the module header. This function is approximately
2147 ! equal to x for x<xc and it saturates to xc when x->infinity
2148
2149 implicit none
2150 real(dp),intent(in) :: x ! Independent variable
2151 real(dp),intent(in) :: xc ! Saturation value
2152 real(dp),intent(out):: y ! Function value
2153 real(dp),intent(out):: dydx ! Derivative dy/dx
2154
2155 real(dp):: z
2156
2157 if (xc<=0._dp) then
2158 call die('pbevv_vdwxc_saturate ERROR: xc<=0')
2159 else if (x<0._dp) then
2160 call die('pbevv_vdwxc_saturate ERROR: x<0')
2161 else if (x==0._dp) then
2162 y = 0
2163 dydx = 1
2164 else
2165 z = 1/x**nsat + 1/xc**nsat
2166 y = 1/z**(1._dp/nsat)
2167 dydx = y/z/x**(nsat+1)
2168 end if
2169
2170end subroutine saturate
2171
2172!-----------------------------------------------------------------------------
2173
2174subroutine saturate_inverse( y, xc, x, dxdy )
2175
2176! Finds the inverse of the function defined in saturate subroutine:
2177! y=1/(1/x^n+1/xc^n)^(1/n) => x=1/(1/y^n-1/xc^n)^(1/n)
2178
2179 implicit none
2180 real(dp),intent(in) :: y ! Independent variable
2181 real(dp),intent(in) :: xc ! Saturation value
2182 real(dp),intent(out):: x ! Inverse function value
2183 real(dp),intent(out):: dxdy ! Derivative dx/dy
2184
2185 real(dp):: z
2186
2187 if (xc<=0._dp) then
2188 call die('pbevv_vdwxc_saturate_inverse ERROR: xc<=0')
2189 else if (y<0._dp .or. y>=xc) then
2190 call die('pbevv_vdwxc_saturate_inverse ERROR: y out of range')
2191 else if (y==0._dp) then
2192 x = 0
2193 dxdy = 1
2194 else
2195 z = 1/y**nsat - 1/xc**nsat
2196 x = 1/z**(1._dp/nsat)
2197 dxdy = x/z/y**(nsat+1)
2198 end if
2199
2200end subroutine saturate_inverse
2201
2202!-----------------------------------------------------------------------------
2203
2204subroutine set_kmesh()
2205
2206! Sets mesh of q values
2207
2208 implicit none
2209 integer :: mkf, mkg
2210
2211 if (.not.kmesh_set) then
2212 call set_mesh( nkf, xmax=kfcut, dxndx1=dkfmaxdkfmin )
2213 call get_mesh( nkf, mkf, kfmesh )
2214 call set_mesh( nkg, xmax=kgcut, dxndx1=dkgmaxdkgmin )
2215 call get_mesh( nkg, mkg, kgmesh )
2216 kmesh_set = .true.
2217#ifdef DEBUG_XC
2218 write(udebug,'(/,a,/,(10f8.4))') 'pbevv_vdw_set_kmesh: kfmesh =', kfmesh
2219 write(udebug,'(/,a,/,(10f8.4))') 'pbevv_vdw_set_kmesh: kgmesh =', kgmesh
2220#endif /* DEBUG_XC */
2221 end if
2222
2223end subroutine set_kmesh
2224
2225! -----------------------------------------------------------------------------
2226
2227subroutine set_phi_table()
2228
2229! Finds and stores in memory the interpolation table (mesh points and
2230! function values) for the kernel phi(k1,k2,k).
2231
2232 implicit none
2233 character(len=*),parameter:: myName = 'pbevv_vdwxc/set_phi_table '
2234 integer :: ik, ikf1, ikf2, ikg1, ikg2, ik1, ik2, ir
2235 real(dp):: dkdk0, dphidk0, dphidkmax, dphidr0, dphidrmax, &
2236 k, kf1, kf2, kg1, kg2, pi, r(0:nr)
2237
2238! Check that table was not set yet
2239 if (phi_table_set) return
2240
2241! Check that kf, kg, r, and k meshes have been set
2242 if (.not.kmesh_set) call set_kmesh()
2243 if (.not.kcut_set) call die('pbevv_vdw_set_phi_table ERROR: kcut not set')
2244 forall(ir=0:nr) r(ir) = ir*dr
2245 pi = acos(-1.0_dp)
2246
2247! Allocate arrays
2248 call re_alloc( phir, 0,nr, 1,nkfg, 1,nkfg, myName//'phir' )
2249 call re_alloc( phik, 0,nr, 1,nkfg, 1,nkfg, myName//'phik' )
2250 call re_alloc( d2phidr2, 0,nr, 1,nkfg, 1,nkfg, myName//'d2phidr2' )
2251 call re_alloc( d2phidk2, 0,nr, 1,nkfg, 1,nkfg, myName//'d2phidk2' )
2252
2253! Loop on (k1,k2) mesh points
2254 do ikg2 = 1,nkg ! loop on kg2
2255 do ikf2 = 1,nkf ! loop on kf2
2256 ik2 = ikf2 + nkf*(ikg2-1) ! combined (ikf2,ikg2) index
2257 do ikg1 = 1,nkg ! loop on kg1
2258 do ikf1 = 1,nkf ! loop on kf1
2259 ik1 = ikf1 + nkf*(ikg1-1) ! combined (ikf1,ikg1) index
2260 if (ik1>ik2) cycle ! since we will symmetrize at the end
2261
2262 ! Saturated (kf,kg) values
2263 kf1 = kfmesh(ikf1)
2264 kf2 = kfmesh(ikf2)
2265 kg1 = kgmesh(ikg1)
2266 kg2 = kgmesh(ikg2)
2267
2268 ! Find original (unsaturated) kf anf kg values
2269 ! call saturate_inverse( kfmesh(ikf1), kfcut, kf1, dkdk0 )
2270 ! call saturate_inverse( kfmesh(ikf2), kfcut, kf2, dkdk0 )
2271 ! call saturate_inverse( kgmesh(ikg1), kgcut, kg1, dkdk0 )
2272 ! call saturate_inverse( kgmesh(ikg2), kgcut, kg2, dkdk0 )
2273
2274 ! Find kernel as a function of r12
2275 do ir = 0,nr
2276 phir(ir,ik1,ik2) = pbevv_vdw_phi_val( kf1, kf2, kg1, kg2, r(ir) )
2277 end do
2278
2279 ! Kill kernel smoothly at r=rcut
2280 do ir = 0,nr
2281 phir(ir,ik1,ik2) = phir(ir,ik1,ik2) * cutoff( r(ir)/rcut )
2282 end do
2283
2284 ! Find kernel in reciprocal space
2285 call radfft( 0, nr, rcut, phir(:,ik1,ik2), phik(:,ik1,ik2) )
2286 phik(:,ik1,ik2) = phik(:,ik1,ik2) * (2*pi)**1.5_dp
2287
2288 ! Filter out above kcut
2289 phik(nk:nr,ik1,ik2) = 0
2290
2291 ! Soft filter below kcut
2292 do ik = 1,nk
2293 k = ik * dk
2294 phik(ik,ik1,ik2) = phik(ik,ik1,ik2) * cutoff(k/kcut)
2295 end do
2296
2297 ! Find filtered kernel in real space
2298 call radfft( 0, nr, kmax, phik(:,ik1,ik2), phir(:,ik1,ik2) )
2299 phir(:,ik1,ik2) = phir(:,ik1,ik2) / (2*pi)**1.5_dp
2300
2301 ! Set up spline interpolation tables
2302 dphidr0 = 0 ! since phi(k1,k2,r) is even in r
2303 dphidk0 = 0 ! and therefore phi(k1,k2,k) is also even in k
2304 dphidrmax = 0 ! since phi->0 for r->infty
2305 dphidkmax = 0 ! and also when k->infty
2306 call spline( dr, phir(:,ik1,ik2), nr+1, dphidr0, dphidrmax, &
2307 d2phidr2(:,ik1,ik2) )
2308 call spline( dk, phik(:,ik1,ik2), nk+1, dphidk0, dphidkmax, &
2309 d2phidk2(:,ik1,ik2) )
2310
2311 ! Fill symmetric elements
2312 phir(:,ik2,ik1) = phir(:,ik1,ik2)
2313 phik(:,ik2,ik1) = phik(:,ik1,ik2)
2314 d2phidr2(:,ik2,ik1) = d2phidr2(:,ik1,ik2)
2315 d2phidk2(:,ik2,ik1) = d2phidk2(:,ik1,ik2)
2316
2317!#ifdef DEBUG_XC
2318! if (.false. .and. ik1==ik2) then
2319! print*, 'pbevv_vdw_set_kcut: ik1,ik2=', ik1, ik2
2320! call window( 0._dp, 5._dp, -1._dp, 4._dp, 0 )
2321! call axes( 0._dp, 1._dp, 0._dp, 1._dp )
2322! call plot( nr+1, r, phi, phir(:,ik1,ik2) )
2323! call window( 0._dp, 10._dp, -0.05_dp, 0.15_dp, 0 )
2324! call axes( 0._dp, 1._dp, 0._dp, 0.05_dp )
2325! call plot( nr+1, r, r**2*phi, r**2*phir(:,ik1,ik2))
2326! call show()
2327! end if
2328!#endif /* DEBUG_XC */
2329
2330 end do ! ikf1
2331 end do ! ikg1
2332 end do ! ikf2
2333 end do ! ikg2
2334
2335!#ifdef DEBUG_XC
2336! open(17,file='vv_phi.table')
2337! write(17,'(3a6,2a12,/,(3i6,2f15.9))') &
2338! 'ik1', 'ik2', 'ir', 'phi', 'd2phi/dk2', &
2339!! (((ik1,ik2,ir,phir(ir,ik1,ik2),d2phidr2(ir,ik1,ik2), &
2340! (((ik1,ik2,ir,phik(ir,ik1,ik2),d2phidk2(ir,ik1,ik2), &
2341! ir=0,100),ik2=1,nkfg),ik1=1,nkfg)
2342! close(17)
2343!#endif /* DEBUG_XC */
2344
2345! Mark table as set
2346 phi_table_set = .true.
2347
2348end subroutine set_phi_table
2349
2350! -----------------------------------------------------------------------------
2351
2352real(dp) function pbevv_vdw_phi_val( kf1, kf2, kg1, kg2, r12 )
2353
2354! vdW energy kernel of Vydrov-vanVoorhis, eq.(2) of JCP 133, 244103 (2010)
2355! This subroutine calculates the 'raw' kernel directly, without interpolarions
2356! In practice, it returns n1*n2*phi(k1,k2,r12), which is smooth for kf->0
2357! Input:
2358! real(dp):: kf1, kf2 ! Fermi wavevectors at points 1 and 2
2359! real(dp):: kg1, kg2 ! |grad(n)|/n at points 1 and 2
2360! real(dp):: r12 ! distance between points 1 and 2
2361
2362! Arguments
2363 implicit none
2364 real(dp),intent(in) :: kf1, kf2, kg1, kg2, r12
2365
2366! Internal variables
2367 real(dp):: g1, g2, kappa1, kappa2, kf1m, kf2m, n1, n2, &
2368 phi, pi, w01, w02, wg1, wg2, wp1, wp2
2369
2370! Avoid dividing by zero when kf=0
2371 kf1m = max(kf1,ktol)
2372 kf2m = max(kf2,ktol)
2373
2374! Find kernel
2375 pi = acos(-1.0_dp)
2376 n1 = kf1m**3/(3*pi**2) ! electron density at point 1
2377 n2 = kf2m**3/(3*pi**2) ! electron density at point 2
2378 wp1 = sqrt(4*pi*n1) ! local plasma frequency at point 1
2379 wp2 = sqrt(4*pi*n2) ! local plasma frequency at point 2
2380 wg1 = sqrt(vv_C*kg1**4) ! local band gap at point 1
2381 wg2 = sqrt(vv_C*kg2**4) ! local band gap at point 2
2382 kappa1 = vv_b*kf1m**2/wp1 ! local VV kappa variable (eq.(9)) at point 1
2383 kappa2 = vv_b*kf2m**2/wp2 ! kappa variable at point 2
2384 w01 = sqrt(wg1**2+wp1**2/3) ! local w0 frequency (eq.(5)) at point 1
2385 w02 = sqrt(wg2**2+wp2**2/3) ! local w0 frequency at point 2
2386 g1 = w01*r12**2 + kappa1 ! local g variable (eq.(3)) at point 1
2387 g2 = w02*r12**2 + kappa2 ! local g variable at point 2
2388 phi = -1.5_dp/g1/g2/(g1+g2) ! VV kernel phi (eq.(2))
2389
2390 if (kernelPrefactor=='rho') then
2391 ! Return whole integrand of eq.(1)
2392 pbevv_vdw_phi_val = n1*n2*phi
2393 else if (kernelPrefactor=='kf') then
2394 ! Return kf1*kf2*phi
2395 pbevv_vdw_phi_val = kf1*kf2*phi
2396 else if (kernelPrefactor=='kf2') then
2397 ! Return (kf1*kf2)**2*phi
2398 pbevv_vdw_phi_val = (kf1*kf2)**2*phi
2399 else if (kernelPrefactor=='sqr_rho') then
2400 ! Find and return sqrt(n1*n2)*phi
2401 pbevv_vdw_phi_val = sqrt(n1*n2)*phi
2402 else
2403 call die('pbevv_vdw_phi_val ERROR: unknown kernelPrefactor')
2404 end if
2405
2406end function pbevv_vdw_phi_val
2407
2408! -----------------------------------------------------------------------------
2409
2410real(dp) function pbevv_vdw_beta()
2411
2412! Returns parameter beta of VV functional
2413
2414 implicit none
2415 pbevv_vdw_beta = vv_beta
2416
2417end function pbevv_vdw_beta
2418
2419!-----------------------------------------------------------------------------
2420
2421subroutine pbevv_vdw_get_kmesh( mkf, mkg, kf, kg )
2422
2423! Returns size and values of (kf,kg) mesh
2424
2425 implicit none
2426 integer, intent(out) :: mkf ! Number of kf mesh points
2427 integer, intent(out) :: mkg ! Number of kg mesh points
2428 real(dp),optional,intent(out) :: kf(:) ! Values of kf mesh points
2429 real(dp),optional,intent(out) :: kg(:) ! Values of kg mesh points
2430 integer:: nmax
2431 if (.not.kmesh_set) call set_kmesh()
2432 mkf = nkf
2433 mkg = nkg
2434 if (present(kf)) then
2435 nmax = max( nkf, size(kf) )
2436 kf(1:nmax) = kfmesh(1:nmax)
2437 end if
2438 if (present(kg)) then
2439 nmax = max( nkg, size(kg) )
2440 kg(1:nmax) = kgmesh(1:nmax)
2441 end if
2442end subroutine pbevv_vdw_get_kmesh
2443
2444! -----------------------------------------------------------------------------
2445
2446subroutine pbevv_vdw_phi( k, phi, dphidk )
2447
2448! Finds by interpolation phi(k1,k2,k) (Fourier transform of phi(k1,k2,r)),
2449! with k1=(kf1,kg1), k2=(kf2,kg2) for all mesh values of kf (Fermi
2450! wavevector) and kg (grad(n)/n). If the interpolation table does not exist,
2451! it is calculated in the first call to pbevv_vdw_phi. It requires a previous
2452! call to pbevv_vdw_set_kc to set k mesh.
2453
2454 implicit none
2455 real(dp),intent(in) :: k ! Modulus of actual k vector
2456 real(dp),intent(out):: phi(:,:) ! phi(k1,k2,k) at given k
2457 ! for all k1,k2 in (kf,kg) mesh
2458 real(dp),intent(out):: dphidk(:,:) ! dphi(k1,k2,k)/dk at given k
2459
2460 integer :: ik, ik1, ik2
2461 real(dp):: a, a2, a3, b, b2, b3
2462
2463! Set interpolation table
2464 if (.not.phi_table_set) call set_phi_table()
2465
2466! Check argument sizes
2467 if (size(phi,1)<nkfg .or. size(phi,2)<nkfg) &
2468 call die('pbevv_vdw_phi: ERROR: size(phi) too small')
2469
2470! Find phi values at point k
2471 if (k >= kcut) then
2472 phi(:,:) = 0
2473 dphidk(:,:) = 0
2474 else
2475 ! Expand interpolation inline since this is the hottest point in VdW
2476 ik = int(k/dk)
2477 a = ((ik+1)*dk-k)/dk
2478 b = 1 - a
2479 a2 = (3*a**2 -1) * dk / 6
2480 b2 = (3*b**2 -1) * dk / 6
2481 a3 = (a**3 - a) * dk**2 / 6
2482 b3 = (b**3 - b) * dk**2 / 6
2483 do ik2 = 1,nkfg
2484 do ik1 = 1,ik2
2485! call splint( dk, phik(:,ik1,ik2), d2phidk2(:,ik1,ik2), &
2486! nk+1, k, phi(ik1,ik2), dphidk(ik1,ik2), pr )
2487 phi(ik1,ik2) = a*phik(ik,ik1,ik2) + b*phik(ik+1,ik1,ik2) &
2488 + a3*d2phidk2(ik,ik1,ik2) + b3*d2phidk2(ik+1,ik1,ik2)
2489 dphidk(ik1,ik2) = (-phik(ik,ik1,ik2) &
2490 +phik(ik+1,ik1,ik2) )/dk &
2491 - a2*d2phidk2(ik,ik1,ik2) + b2*d2phidk2(ik+1,ik1,ik2)
2492 phi(ik2,ik1) = phi(ik1,ik2)
2493 dphidk(ik2,ik1) = dphidk(ik1,ik2)
2494 end do
2495 end do
2496 end if
2497
2498end subroutine pbevv_vdw_phi
2499
2500!-----------------------------------------------------------------------------
2501
2502subroutine pbevv_vdw_phiofr( r, phi )
2503
2504! Finds phi(k1,k2,r) with k1=(kf1,kg1), k2=(kf2,kg2) for mesh values of
2505! kf's (Fermi wavevectors) and kg's (grad(n)/n)
2506
2507 implicit none
2508 real(dp),intent(in) :: r
2509 real(dp),intent(out):: phi(:,:)
2510
2511 integer :: ikf1, ikf2, ikg1, ikg2, ik1, ik2
2512 real(dp):: dphidr
2513
2514 if (size(phi,1)<nkfg .or. size(phi,2)<nkfg) &
2515 stop 'vv_phiofr: ERROR: size(phi) too small'
2516 if (.not.phi_table_set) call set_phi_table()
2517
2518 if (r >= rcut) then
2519 phi(:,:) = 0
2520 else
2521 do ik2 = 1,nkfg
2522 do ik1 = 1,ik2
2523 call splint( dr, phir(:,ik1,ik2), d2phidr2(:,ik1,ik2), &
2524 nr+1, r, phi(ik1,ik2), dphidr )
2525 phi(ik2,ik1) = phi(ik1,ik2)
2526 end do ! ik1
2527 end do ! ik2
2528 end if ! (r>=rcut)
2529
2530end subroutine pbevv_vdw_phiofr
2531
2532!-----------------------------------------------------------------------------
2533
2534subroutine pbevv_vdw_set_kcut( kc )
2535
2536! Sets the reciprocal planewave cutoff kc of the integration grid, and finds
2537! the interpolation table to be used by vdw_phi to obtain the vdW kernel phi
2538! at the reciprocal mesh wavevectors.
2539
2540 implicit none
2541 real(dp),intent(in):: kc ! Planewave cutoff: k>kcut => phi=0
2542
2543 real(dp):: pi
2544
2545 ! Set kcut and radial mesh parameters, if not already set
2546 if (.not. kc==kcut) then
2547 kcut = kc
2548 pi = acos(-1._dp)
2549 dr = rcut / nr
2550 dk = pi / rcut
2551 kmax = pi / dr
2552 nk = int(kcut/dk) + 1
2553 if (nk>nr) stop 'pbevv_vdw_set_kcut: ERROR: nk>nr'
2554 kcut_set = .true.
2555#ifdef DEBUG_XC
2556 write(udebug,'(a,5f8.3)') 'pbevv_vdw_set_kcut: kfcut,kgcut,rcut,kcut,kmax=', &
2557 kfcut, kgcut, rcut, kc, kmax
2558#endif /* DEBUG_XC */
2559 end if
2560
2561 ! Set (kf,kg) mesh and phi table
2562 call set_kmesh()
2563 call set_phi_table()
2564
2565end subroutine pbevv_vdw_set_kcut
2566
2567!-----------------------------------------------------------------------------
2568
2569subroutine pbevv_vdw_theta( nspin, rhos, grhos, theta, dtdrho, dtdgrho )
2570
2571! Finds the value and derivatives of theta_i(rho,grad_rho) of eq.(8)
2572! of Roman-Soler PRL 2009. In practice, theta_i=p_i rather than rho*p_i,
2573! beacuse p_i is used here to expand rho1*rho2*phi rather than only phi.
2574
2575 implicit none
2576 integer, intent(in) :: nspin ! Number of spin components
2577 real(dp),intent(in) :: rhos(nspin) ! Electron spin density
2578 real(dp),intent(in) :: grhos(3,nspin) ! Spin density gradient
2579 real(dp),intent(out):: theta(nkfg) ! Exp. polynomials at (kf,kg)
2580 real(dp),intent(out):: dtdrho(nkfg,nspin) ! dtheta(ik)/drhos
2581 real(dp),intent(out):: dtdgrho(3,nkfg,nspin) ! dtheta(ik)/dgrhos(ix)
2582
2583 integer :: is, ix, ns
2584 real(dp):: rho, grho(3), dpdkf(nkfg), dpdkg(nkfg), dkfdrho, dkfdgrho(3), &
2585 dkgdrho, dkgdgrho(3), kf, kg, p(nkfg)
2586
2587 ! Sum spin components of electron density
2588 ns = min(nspin,2) ! num. of diagonal spin components (if noncollinear)
2589 rho = sum(rhos(1:ns)) ! local electron density
2590 grho = sum(grhos(:,1:ns),dim=2) ! local density gradient
2591
2592 ! If density is between threshold, return zero
2593 if (rho<rhoMin) then
2594 theta = 0
2595 dtdrho = 0
2596 dtdgrho = 0
2597 return
2598 end if
2599
2600 ! Find local Fermi and gradient wavevectors, and their derivatives
2601 call kofn( rho, grho, kf, kg, dkfdrho, dkgdrho, dkfdgrho, dkgdgrho )
2602
2603 ! Find expansion polynomials of integrand kernel of nonlocal vdW energy
2604 call pofk( kf, kg, p, dpdkf, dpdkg )
2605
2606 ! Find theta functions and their derivatives with respect to rho and grho
2607 if (kernelPrefactor=='rho') then
2608 ! This is the right code if pbevv_vdw_phi_val returns rho1*rho2*phi
2609 theta(1:nkfg) = p(1:nkfg)
2610 do is = 1,ns
2611 dtdrho(1:nkfg,is) = dpdkf(1:nkfg)*dkfdrho + dpdkg(1:nkfg)*dkgdrho
2612 do ix = 1,3
2613 dtdgrho(ix,1:nkfg,is) = dpdkf(1:nkfg)*dkfdgrho(ix) &
2614 + dpdkg(1:nkfg)*dkgdgrho(ix)
2615 end do
2616 end do
2617 else if (kernelPrefactor=='kf') then
2618 ! This is the right code if pbevv_vdw_phi_val returns kf1*kf2*phi
2619 kf = max(kf,ktol)
2620 theta(1:nkfg) = p(1:nkfg)*rho/kf
2621 do is = 1,ns
2622 dtdrho(1:nkfg,is) = (dpdkf(1:nkfg)*dkfdrho &
2623 +dpdkg(1:nkfg)*dkgdrho)*rho/kf &
2624 + p(1:nkfg)*(1/kf-rho/kf**2*dkfdrho)
2625 do ix = 1,3
2626 dtdgrho(ix,1:nkfg,is) = (dpdkf(1:nkfg)*dkfdgrho(ix) &
2627 +dpdkg(1:nkfg)*dkgdgrho(ix))*rho/kf
2628 end do
2629 end do
2630 else if (kernelPrefactor=='kf2') then
2631 ! This is the right code if pbevv_vdw_phi_val returns (kf1*kf2)**2*phi
2632 kf = max(kf,ktol)
2633 theta(1:nkfg) = p(1:nkfg)*rho/kf**2
2634 do is = 1,ns
2635 dtdrho(1:nkfg,is) = (dpdkf(1:nkfg)*dkfdrho &
2636 +dpdkg(1:nkfg)*dkgdrho)*rho/kf**2 &
2637 + p(1:nkfg)*(1/kf**2-2*rho/kf**3*dkfdrho)
2638 do ix = 1,3
2639 dtdgrho(ix,1:nkfg,is) = (dpdkf(1:nkfg)*dkfdgrho(ix) &
2640 +dpdkg(1:nkfg)*dkgdgrho(ix))*rho/kf**2
2641 end do
2642 end do
2643 else if (kernelPrefactor=='sqr_rho') then
2644 ! This is the right code if pbevv_vdw_phi_val returns sqrt(rho1*rho2)*phi
2645 rho = max(rho,1.e-12_dp) ! to avoid division by zero
2646 theta(1:nkfg) = p(1:nkfg) * sqrt(rho)
2647 do is = 1,ns
2648 dtdrho(1:nkfg,is) = ( dpdkf(1:nkfg)*dkfdrho &
2649 + dpdkg(1:nkfg)*dkgdrho ) * sqrt(rho) &
2650 + p(1:nkfg) * 0.5/sqrt(rho)
2651 do ix = 1,3
2652 dtdgrho(ix,1:nkfg,is) = dpdkf(1:nkfg)*dkfdgrho(ix) * sqrt(rho) &
2653 + dpdkg(1:nkfg)*dkgdgrho(ix) * sqrt(rho)
2654 end do
2655 end do
2656 else
2657 call die('pbevv_vdw_theta ERROR: unknown kernelPrefactor')
2658 end if ! (kernelPrefactor=='rho')
2659
2660end subroutine pbevv_vdw_theta
2661
2662END MODULE m_pbevv_vdwxc
2663
2664!!!=============== PBEsol+VV10s =========================
2665
2666MODULE m_pbesvvs_vdwxc
2667
2668! Used module procedures
2669 use sys, only: die ! Termination routine
2670 use mesh1D, only: get_mesh ! Returns the mesh points
2671 use m_radfft, only: radfft ! Radial fast Fourier transform
2672 use alloc, only: re_alloc ! Re-allocation routine
2673 use mesh1D, only: set_mesh ! Sets a 1D mesh
2674 use interpolation,only: spline ! Sets spline interpolation
2675 use interpolation,only: splint ! Calculates spline interpolation
2676
2677! Used module parameters
2678 use precision, only: dp ! Real double precision type
2679
2680#ifdef DEBUG_XC
2681 use debugXC, only: udebug ! File unit for debug output
2682! use plot_module, only: plot
2683#endif /* DEBUG_XC */
2684
2685 implicit none
2686
2687! Called by m_vdwxc
2688PUBLIC :: &
2689 pbesvvs_vdw_beta, &! Returns parameter beta of the VV2010 functional
2690 pbesvvs_vdw_theta, &! Finds function theta_ik(rho,grad_rho)
2691 pbesvvs_vdw_get_kmesh, &! Returns size and values of (kf,kg) mesh
2692 pbesvvs_vdw_phi, &! Finds and interpolates rho1*rho2*phi(k1,k2,k)
2693 pbesvvs_vdw_set_kcut ! Sets the planewave cutoff kc of the integration grid
2694
2695#ifdef DEBUG_XC
2696! Called by debugging test programs
2697PUBLIC :: &
2698 pbesvvs_vdw_phi_val, &! Kernel phi(kf1,kf2,kg1,kg2,r12) with no interpolation
2699 pbesvvs_vdw_phiofr ! Kernel phi(k1,k2,r) at tabulated k1,k2-mesh values
2700#endif /* DEBUG_XC */
2701
2702PRIVATE ! Nothing is declared public beyond this point
2703
2704 ! Set parameters of the PBEsol+rVV10s,
2705 ! Ref. A. V. Terentjev et al, Phys. Rev. B 98, 214108 (2018)
2706 real(dp),parameter:: vv_C = 0.0093
2707 real(dp),parameter:: vv_b = 10.0
2708 real(dp),parameter:: vv_beta = 0.00497
2709
2710 ! Mesh parameters for table of phi(k1,k2,r) and its Fourier transform
2711 character(len=*),parameter:: kernelPrefactor='rho' ! Prefactor of the
2712 ! nonlocal kernel for interpolation
2713 ! ('kf'|'kf2'|'sqr_rho'|'rho')
2714 integer, parameter:: nr = 2048 ! Radial mesh points (power of 2)
2715 real(dp),parameter:: rcut = 100._dp ! Radial cutoff: r>rcut => phi=0
2716 real(dp),parameter:: rmin = 1.e-6_dp ! Min. radius as denominator
2717 integer, parameter:: nkf = 7 ! Number of Fermi wavevectors
2718 integer, parameter:: nkg = 5 ! Num. of grad(n)/n wavevectors
2719 integer, parameter:: nkfg = nkf*nkg ! Num. of (kf,kg) mesh points
2720 real(dp),parameter:: kfcut = 5.0_dp ! Max. Fermi wavevec.
2721 real(dp),parameter:: kgcut = 5.0_dp ! Max. grad(n)/n
2722 real(dp),parameter:: dkfmaxdkfmin = 20.0_dp ! Last/first kf mesh interval
2723 real(dp),parameter:: dkgmaxdkgmin = 2.0_dp ! Last/first kg mesh interval
2724 real(dp),parameter:: ktol = 1.e-12_dp ! 'out of range' tolerance
2725 real(dp),parameter:: amin = 1.e-12_dp ! tiny denominator to avoid /0
2726 real(dp),parameter:: rhoMin = 1.e-10_dp ! Min. density for nonzero Vxc
2727
2728 ! Parameters for cutoff function, used in radial Fourier transforms of phi
2729 integer, parameter:: ncut1 = 8 ! cutoff(x)=(1-x**ncut1)**ncut2
2730 integer, parameter:: ncut2 = 4
2731
2732 ! Parameters for saturate function, used to enforce that q<qcut
2733 integer, parameter:: nsat = 15 ! h(x,xc)=1/(1/x**nsat+1/xc**nsat)**(1/nsat)
2734 ! nsat=15 approximately corresponds to
2735 ! nsat=12 for eq.(5) of Roman-Soler PRL
2736
2737 ! Private module variables and arrays
2738 logical, save:: kcut_set=.false. ! Has kcut been set?
2739 logical, save:: kmesh_set=.false. ! Has (kf,kg) mesh been set?
2740 logical, save:: phi_table_set=.false. ! Has phi_table been set?
2741 integer, save:: nk ! Num. of radial mesh k-points
2742 real(dp),save:: dr ! r-mesh interval
2743 real(dp),save:: dk ! k-mesh interval
2744 real(dp),save:: kcut ! Planewave cutoff: k>kcut => phi=0
2745 real(dp),save:: kmax ! Max. k vector in Fourier transforms
2746 real(dp),save:: kfmesh(nkf) ! Mesh points for Fermi wavevector
2747 real(dp),save:: kgmesh(nkg) ! Mesh points for grad(n)/n
2748 real(dp),pointer,save:: &
2749 phir(:,:,:)=>null(), &! Table of phi(r)
2750 phik(:,:,:)=>null(), &! Table of phi(k)
2751 d2phidr2(:,:,:)=>null(),&! Table of d^2(phi)/dr^2
2752 d2phidk2(:,:,:)=>null() ! Table of d^2(phi)/dk^2
2753
2754CONTAINS
2755
2756! -----------------------------------------------------------------------------
2757
2758real(dp) function cutoff( x )
2759
2760! Defines a smooth cutoff function that falls from y(0)=1 to y(1)=0
2761
2762 implicit none
2763 real(dp),intent(in):: x
2764
2765 if (x<=0._dp) then
2766 cutoff = 1
2767 else if (x>=1._dp) then
2768 cutoff = 0
2769 else
2770 cutoff = (1-x**ncut1)**ncut2
2771 end if
2772
2773end function cutoff
2774
2775!-----------------------------------------------------------------------------
2776
2777subroutine iofk( kf, kg, ikf, ikg )
2778
2779! Finds indexes ikf and ikg such that kfmesh(ikf) <= kf < kfmesh(ikf+1)
2780! and kgmesh(ikg) <= kg < kgmesh(ikg+1) in logarithmic meshes of the form
2781! k(ik) = b*(exp((ik-1)*a)-1)
2782
2783 implicit none
2784 real(dp), intent(in) :: kf, kg
2785 integer, intent(out):: ikf, ikg
2786
2787 real(dp),save:: akf, akg, bkf, bkg
2788 logical, save:: first_call = .true.
2789 integer:: ik
2790
2791 ! Mesh data initializations
2792 if (first_call) then
2793 ! Find logarithmic-mesh a & b parameters: x(j)=x(1)+b*(exp(a*(j-1))-1)
2794 akf = log( (kfmesh(nkf)-kfmesh(nkf-1)) / (kfmesh(2)-kfmesh(1)) ) / (nkf-2)
2795 akg = log( (kgmesh(nkg)-kgmesh(nkg-1)) / (kgmesh(2)-kgmesh(1)) ) / (nkg-2)
2796 akf = max( akf, amin )
2797 akg = max( akg, amin )
2798 bkf = (kfmesh(nkf) - kfmesh(1)) / (exp(akf*(nkf-1)) - 1)
2799 bkg = (kgmesh(nkg) - kgmesh(1)) / (exp(akg*(nkg-1)) - 1)
2800 ! Check that meshes are indeed logarithmic
2801 do ik = 1,nkf
2802 if (abs(kfmesh(ik)-kfmesh(1)-bkf*(exp(akf*(ik-1))-1))>ktol) &
2803 call die('pbesvvs_vdw_iofk ERROR: kfmesh not logarithmic')
2804 end do
2805 do ik = 1,nkg
2806 if (abs(kgmesh(ik)-kgmesh(1)-bkg*(exp(akg*(ik-1))-1))>ktol) &
2807 call die('pbesvvs_vdw_iofk ERROR: kgmesh not logarithmic')
2808 end do
2809 first_call = .false.
2810 end if
2811
2812 ! Check that kf and kg are within interpolation range
2813 if (kf<kfmesh(1)-ktol .or. kf>kfmesh(nkf)+ktol .or. &
2814 kg<kgmesh(1)-ktol .or. kg>kgmesh(nkg)+ktol) then
2815 call die('pbesvvs_vdw_iofk ERROR: (kf,kg) out of range')
2816 endif
2817
2818 ! Find interpolation mesh intervals
2819 ikf = 1 + int( log( 1 + (kf-kfmesh(1))/bkf ) / akf )
2820 ikg = 1 + int( log( 1 + (kg-kgmesh(1))/bkg ) / akg )
2821 ikf = max( 1, ikf )
2822 ikg = max( 1, ikg )
2823 ikf = min( nkf-1, ikf )
2824 ikg = min( nkg-1, ikg )
2825
2826end subroutine iofk
2827
2828! -----------------------------------------------------------------------------
2829
2830subroutine kofn( n, gn, kf, kg, dkfdn, dkgdn, dkfdgn, dkgdgn )
2831
2832! Finds Fermi and gradient wavevectors from density and gradient
2833
2834 implicit none
2835 real(dp), intent(in) :: n ! Electron density
2836 real(dp), intent(in) :: gn(3) ! Density gradient
2837 real(dp), intent(out):: kf ! Local Fermi wavevector
2838 real(dp), intent(out):: kg ! |grad(n)|/n
2839 real(dp), intent(out):: dkfdn ! dkf/dn
2840 real(dp), intent(out):: dkgdn ! dkg/dn
2841 real(dp), intent(out):: dkfdgn(3) ! dkf/dgn
2842 real(dp), intent(out):: dkgdgn(3) ! dkg/dgn
2843
2844 real(dp):: gn2, pi
2845
2846! Trap exception for zero density
2847 if (n <= 1.e-30_dp) then
2848 kf = 0
2849 kg = 0
2850 dkfdn = 0
2851 dkfdgn = 0
2852 dkgdn = 0
2853 dkgdgn = 0
2854 return
2855 end if
2856
2857! Find kf and kg
2858 pi = acos(-1._dp)
2859 kf = (3*pi**2*n)**(1._dp/3)
2860 gn2 = sum(gn**2)
2861 kg = sqrt(gn2)/n
2862
2863! Find derivatives
2864 dkfdn = kf/n/3
2865 dkfdgn = 0
2866 dkgdn = -kg/n
2867 dkgdgn = kg*gn/gn2
2868
2869end subroutine kofn
2870
2871!-----------------------------------------------------------------------------
2872
2873subroutine pofk( kf, kg, p, dpdkf, dpdkg )
2874
2875! Finds the values and derivatives, at (kf,kg), of the bicubic polynomials
2876! p_i(kf,kg) such that
2877! y(kf,kg) = Sum_i p_i(kf,kg) * y_i
2878! is the bicubic spline interpolation at (kf,kg) of (any) function y with
2879! values y_i at mesh points (kfmesh,kgmesh)_i
2880
2881 implicit none
2882 real(dp),intent(in) :: kf, kg ! point at which the polynomials are required
2883 real(dp),intent(out):: p(nkfg) ! polynomial values at (kf,kg)
2884 real(dp),intent(out):: dpdkf(nkfg) ! dp/dkf at (kf,kg)
2885 real(dp),intent(out):: dpdkg(nkfg) ! dp/dkg at (kf,kg)
2886
2887 integer :: ikf, ikg, ikfg, ikf0, ikg0
2888 real(dp):: a, b, dk, dkf0dkf, dkg0dkg, kf0, kg0
2889 real(dp):: pkf0(nkf), dpkfdkf0(nkf), pkg0(nkg), dpkgdkg0(nkg)
2890 logical, save :: first_call=.true.
2891 real(dp),save :: pkf(nkf,nkf), d2pkfdkf2(nkf,nkf)
2892 real(dp),save :: pkg(nkg,nkg), d2pkgdkg2(nkg,nkg)
2893
2894! Set up spline polynomial basis
2895 if (first_call) then
2896 do ikf = 1,nkf
2897 pkf(:,ikf) = 0 ! ikf'th polynomial pkf(:,ikf) is one at kfmesh(ikf)
2898 pkf(ikf,ikf) = 1 ! and zero at all other points
2899 call spline( kfmesh, pkf(:,ikf), nkf, 1.e30_dp, 1.e30_dp, &
2900 d2pkfdkf2(:,ikf) )
2901! call spline( kfmesh, pkf(:,ikf), nkf, 0._dp, 0._dp, d2pkfdkf2(:,ikf) )
2902 end do
2903 do ikg = 1,nkg
2904 pkg(:,ikg) = 0
2905 pkg(ikg,ikg) = 1
2906 call spline( kgmesh, pkg(:,ikg), nkg, 1.e30_dp, 1.e30_dp, &
2907 d2pkgdkg2(:,ikg) )
2908! call spline( kgmesh, pkg(:,ikg), nkg, 0._dp, 0._dp, d2pkgdkg2(:,ikg) )
2909 end do
2910
2911! DEBUG
2912 open(22,file='pkf.dat')
2913 do ikf = 1,nkf
2914 write(22,'(20e15.6)') kfmesh(ikf), pkf(:,ikf), d2pkfdkf2(:,ikf)
2915 end do
2916 close(22)
2917 open(22,file='pkg.dat')
2918 do ikg = 1,nkg
2919 write(22,'(20e15.6)') kgmesh(ikg), pkg(:,ikg), d2pkgdkg2(:,ikg)
2920 end do
2921 close(22)
2922! END DEBUG
2923
2924 first_call = .false.
2925 end if
2926
2927! 'Saturate' (kf,kg) values to bring them to interpolation range
2928 call saturate( kf, kfcut, kf0, dkf0dkf )
2929 call saturate( kg, kgcut, kg0, dkg0dkg )
2930
2931! Find interval of k mesh in which (kf0,kg0) point is included
2932 call iofk( kf0, kg0, ikf0, ikg0 )
2933
2934! Evaluate pkf polynomials of spline basis at kf0
2935! The splint code is in-lined here because it is a hot point
2936 dk = kfmesh(ikf0+1) - kfmesh(ikf0)
2937 a = (kfmesh(ikf0+1) - kf0) / dk ! dadkf0 = -1/dk
2938 b = (kf0 - kfmesh(ikf0)) / dk ! dbdkf0 = +1/dk
2939 do ikf = 1,nkf
2940 pkf0(ikf) = a*pkf(ikf0,ikf) + b*pkf(ikf0+1,ikf) &
2941 + ((a**3-a)*d2pkfdkf2(ikf0,ikf) + &
2942 (b**3-b)*d2pkfdkf2(ikf0+1,ikf)) * dk**2/6
2943 dpkfdkf0(ikf) = - (pkf(ikf0,ikf) - pkf(ikf0+1,ikf)) / dk &
2944 - ((3*a**2-1)*d2pkfdkf2(ikf0,ikf) - &
2945 (3*b**2-1)*d2pkfdkf2(ikf0+1,ikf)) * dk/6
2946 end do
2947
2948! Evaluate pkg polynomials of spline basis at kg0
2949 dk = kgmesh(ikg0+1) - kgmesh(ikg0)
2950 a = (kgmesh(ikg0+1) - kg0) / dk ! dadkg0 = -1/dk
2951 b = (kg0 - kgmesh(ikg0)) / dk ! dbdkg0 = +1/dk
2952 do ikg = 1,nkg
2953 pkg0(ikg) = a*pkg(ikg0,ikg) + b*pkg(ikg0+1,ikg) &
2954 + ((a**3-a)*d2pkgdkg2(ikg0,ikg) + &
2955 (b**3-b)*d2pkgdkg2(ikg0+1,ikg)) * dk**2/6
2956 dpkgdkg0(ikg) = - (pkg(ikg0,ikg) - pkg(ikg0+1,ikg)) / dk &
2957 - ((3*a**2-1)*d2pkgdkg2(ikg0,ikg) - &
2958 (3*b**2-1)*d2pkgdkg2(ikg0+1,ikg)) * dk/6
2959 end do
2960
2961! Evaluate pkf*pkg polynomials at (kf0,kg0)
2962 ikfg = 0
2963 do ikg = 1,nkg
2964 do ikf = 1,nkf
2965 ikfg = ikfg+1
2966 p(ikfg) = pkf0(ikf) * pkg0(ikg)
2967 dpdkf(ikfg) = dpkfdkf0(ikf)*dkf0dkf * pkg0(ikg)
2968 dpdkg(ikfg) = pkf0(ikf) * dpkgdkg0(ikg)*dkg0dkg
2969 end do
2970 end do
2971
2972end subroutine pofk
2973
2974!-----------------------------------------------------------------------------
2975
2976subroutine saturate( x, xc, y, dydx )
2977
2978 ! Defines a function y(x,xc) = 1/(1/x^nsat+1/xc^nsat)^(1/nsat), where nsat
2979 ! is an integer set in the module header. This function is approximately
2980 ! equal to x for x<xc and it saturates to xc when x->infinity
2981
2982 implicit none
2983 real(dp),intent(in) :: x ! Independent variable
2984 real(dp),intent(in) :: xc ! Saturation value
2985 real(dp),intent(out):: y ! Function value
2986 real(dp),intent(out):: dydx ! Derivative dy/dx
2987
2988 real(dp):: z
2989
2990 if (xc<=0._dp) then
2991 call die('pbesvvs_vdwxc_saturate ERROR: xc<=0')
2992 else if (x<0._dp) then
2993 call die('pbesvvs_vdwxc_saturate ERROR: x<0')
2994 else if (x==0._dp) then
2995 y = 0
2996 dydx = 1
2997 else
2998 z = 1/x**nsat + 1/xc**nsat
2999 y = 1/z**(1._dp/nsat)
3000 dydx = y/z/x**(nsat+1)
3001 end if
3002
3003end subroutine saturate
3004
3005!-----------------------------------------------------------------------------
3006
3007subroutine saturate_inverse( y, xc, x, dxdy )
3008
3009! Finds the inverse of the function defined in saturate subroutine:
3010! y=1/(1/x^n+1/xc^n)^(1/n) => x=1/(1/y^n-1/xc^n)^(1/n)
3011
3012 implicit none
3013 real(dp),intent(in) :: y ! Independent variable
3014 real(dp),intent(in) :: xc ! Saturation value
3015 real(dp),intent(out):: x ! Inverse function value
3016 real(dp),intent(out):: dxdy ! Derivative dx/dy
3017
3018 real(dp):: z
3019
3020 if (xc<=0._dp) then
3021 call die('pbesvvs_vdwxc_saturate_inverse ERROR: xc<=0')
3022 else if (y<0._dp .or. y>=xc) then
3023 call die('pbesvvs_vdwxc_saturate_inverse ERROR: y out of range')
3024 else if (y==0._dp) then
3025 x = 0
3026 dxdy = 1
3027 else
3028 z = 1/y**nsat - 1/xc**nsat
3029 x = 1/z**(1._dp/nsat)
3030 dxdy = x/z/y**(nsat+1)
3031 end if
3032
3033end subroutine saturate_inverse
3034
3035!-----------------------------------------------------------------------------
3036
3037subroutine set_kmesh()
3038
3039! Sets mesh of q values
3040
3041 implicit none
3042 integer :: mkf, mkg
3043
3044 if (.not.kmesh_set) then
3045 call set_mesh( nkf, xmax=kfcut, dxndx1=dkfmaxdkfmin )
3046 call get_mesh( nkf, mkf, kfmesh )
3047 call set_mesh( nkg, xmax=kgcut, dxndx1=dkgmaxdkgmin )
3048 call get_mesh( nkg, mkg, kgmesh )
3049 kmesh_set = .true.
3050#ifdef DEBUG_XC
3051 write(udebug,'(/,a,/,(10f8.4))') 'pbesvvs_vdw_set_kmesh: kfmesh =', kfmesh
3052 write(udebug,'(/,a,/,(10f8.4))') 'pbesvvs_vdw_set_kmesh: kgmesh =', kgmesh
3053#endif /* DEBUG_XC */
3054 end if
3055
3056end subroutine set_kmesh
3057
3058! -----------------------------------------------------------------------------
3059
3060subroutine set_phi_table()
3061
3062! Finds and stores in memory the interpolation table (mesh points and
3063! function values) for the kernel phi(k1,k2,k).
3064
3065 implicit none
3066 character(len=*),parameter:: myName = 'pbesvvs_vdwxc/set_phi_table '
3067 integer :: ik, ikf1, ikf2, ikg1, ikg2, ik1, ik2, ir
3068 real(dp):: dkdk0, dphidk0, dphidkmax, dphidr0, dphidrmax, &
3069 k, kf1, kf2, kg1, kg2, pi, r(0:nr)
3070
3071! Check that table was not set yet
3072 if (phi_table_set) return
3073
3074! Check that kf, kg, r, and k meshes have been set
3075 if (.not.kmesh_set) call set_kmesh()
3076 if (.not.kcut_set) call die('pbesvvs_vdw_set_phi_table ERROR: kcut not set')
3077 forall(ir=0:nr) r(ir) = ir*dr
3078 pi = acos(-1.0_dp)
3079
3080! Allocate arrays
3081 call re_alloc( phir, 0,nr, 1,nkfg, 1,nkfg, myName//'phir' )
3082 call re_alloc( phik, 0,nr, 1,nkfg, 1,nkfg, myName//'phik' )
3083 call re_alloc( d2phidr2, 0,nr, 1,nkfg, 1,nkfg, myName//'d2phidr2' )
3084 call re_alloc( d2phidk2, 0,nr, 1,nkfg, 1,nkfg, myName//'d2phidk2' )
3085
3086! Loop on (k1,k2) mesh points
3087 do ikg2 = 1,nkg ! loop on kg2
3088 do ikf2 = 1,nkf ! loop on kf2
3089 ik2 = ikf2 + nkf*(ikg2-1) ! combined (ikf2,ikg2) index
3090 do ikg1 = 1,nkg ! loop on kg1
3091 do ikf1 = 1,nkf ! loop on kf1
3092 ik1 = ikf1 + nkf*(ikg1-1) ! combined (ikf1,ikg1) index
3093 if (ik1>ik2) cycle ! since we will symmetrize at the end
3094
3095 ! Saturated (kf,kg) values
3096 kf1 = kfmesh(ikf1)
3097 kf2 = kfmesh(ikf2)
3098 kg1 = kgmesh(ikg1)
3099 kg2 = kgmesh(ikg2)
3100
3101 ! Find original (unsaturated) kf anf kg values
3102 ! call saturate_inverse( kfmesh(ikf1), kfcut, kf1, dkdk0 )
3103 ! call saturate_inverse( kfmesh(ikf2), kfcut, kf2, dkdk0 )
3104 ! call saturate_inverse( kgmesh(ikg1), kgcut, kg1, dkdk0 )
3105 ! call saturate_inverse( kgmesh(ikg2), kgcut, kg2, dkdk0 )
3106
3107 ! Find kernel as a function of r12
3108 do ir = 0,nr
3109 phir(ir,ik1,ik2) = pbesvvs_vdw_phi_val( kf1, kf2, kg1, kg2, r(ir) )
3110 end do
3111
3112 ! Kill kernel smoothly at r=rcut
3113 do ir = 0,nr
3114 phir(ir,ik1,ik2) = phir(ir,ik1,ik2) * cutoff( r(ir)/rcut )
3115 end do
3116
3117 ! Find kernel in reciprocal space
3118 call radfft( 0, nr, rcut, phir(:,ik1,ik2), phik(:,ik1,ik2) )
3119 phik(:,ik1,ik2) = phik(:,ik1,ik2) * (2*pi)**1.5_dp
3120
3121 ! Filter out above kcut
3122 phik(nk:nr,ik1,ik2) = 0
3123
3124 ! Soft filter below kcut
3125 do ik = 1,nk
3126 k = ik * dk
3127 phik(ik,ik1,ik2) = phik(ik,ik1,ik2) * cutoff(k/kcut)
3128 end do
3129
3130 ! Find filtered kernel in real space
3131 call radfft( 0, nr, kmax, phik(:,ik1,ik2), phir(:,ik1,ik2) )
3132 phir(:,ik1,ik2) = phir(:,ik1,ik2) / (2*pi)**1.5_dp
3133
3134 ! Set up spline interpolation tables
3135 dphidr0 = 0 ! since phi(k1,k2,r) is even in r
3136 dphidk0 = 0 ! and therefore phi(k1,k2,k) is also even in k
3137 dphidrmax = 0 ! since phi->0 for r->infty
3138 dphidkmax = 0 ! and also when k->infty
3139 call spline( dr, phir(:,ik1,ik2), nr+1, dphidr0, dphidrmax, &
3140 d2phidr2(:,ik1,ik2) )
3141 call spline( dk, phik(:,ik1,ik2), nk+1, dphidk0, dphidkmax, &
3142 d2phidk2(:,ik1,ik2) )
3143
3144 ! Fill symmetric elements
3145 phir(:,ik2,ik1) = phir(:,ik1,ik2)
3146 phik(:,ik2,ik1) = phik(:,ik1,ik2)
3147 d2phidr2(:,ik2,ik1) = d2phidr2(:,ik1,ik2)
3148 d2phidk2(:,ik2,ik1) = d2phidk2(:,ik1,ik2)
3149
3150!#ifdef DEBUG_XC
3151! if (.false. .and. ik1==ik2) then
3152! print*, 'pbesvvs_vdw_set_kcut: ik1,ik2=', ik1, ik2
3153! call window( 0._dp, 5._dp, -1._dp, 4._dp, 0 )
3154! call axes( 0._dp, 1._dp, 0._dp, 1._dp )
3155! call plot( nr+1, r, phi, phir(:,ik1,ik2) )
3156! call window( 0._dp, 10._dp, -0.05_dp, 0.15_dp, 0 )
3157! call axes( 0._dp, 1._dp, 0._dp, 0.05_dp )
3158! call plot( nr+1, r, r**2*phi, r**2*phir(:,ik1,ik2))
3159! call show()
3160! end if
3161!#endif /* DEBUG_XC */
3162
3163 end do ! ikf1
3164 end do ! ikg1
3165 end do ! ikf2
3166 end do ! ikg2
3167
3168!#ifdef DEBUG_XC
3169! open(17,file='vv_phi.table')
3170! write(17,'(3a6,2a12,/,(3i6,2f15.9))') &
3171! 'ik1', 'ik2', 'ir', 'phi', 'd2phi/dk2', &
3172!! (((ik1,ik2,ir,phir(ir,ik1,ik2),d2phidr2(ir,ik1,ik2), &
3173! (((ik1,ik2,ir,phik(ir,ik1,ik2),d2phidk2(ir,ik1,ik2), &
3174! ir=0,100),ik2=1,nkfg),ik1=1,nkfg)
3175! close(17)
3176!#endif /* DEBUG_XC */
3177
3178! Mark table as set
3179 phi_table_set = .true.
3180
3181end subroutine set_phi_table
3182
3183! -----------------------------------------------------------------------------
3184
3185real(dp) function pbesvvs_vdw_phi_val( kf1, kf2, kg1, kg2, r12 )
3186
3187! vdW energy kernel of Vydrov-vanVoorhis, eq.(2) of JCP 133, 244103 (2010)
3188! This subroutine calculates the 'raw' kernel directly, without interpolarions
3189! In practice, it returns n1*n2*phi(k1,k2,r12), which is smooth for kf->0
3190! Input:
3191! real(dp):: kf1, kf2 ! Fermi wavevectors at points 1 and 2
3192! real(dp):: kg1, kg2 ! |grad(n)|/n at points 1 and 2
3193! real(dp):: r12 ! distance between points 1 and 2
3194
3195! Arguments
3196 implicit none
3197 real(dp),intent(in) :: kf1, kf2, kg1, kg2, r12
3198
3199! Internal variables
3200 real(dp):: g1, g2, kappa1, kappa2, kf1m, kf2m, n1, n2, &
3201 phi, pi, w01, w02, wg1, wg2, wp1, wp2, &
3202 ss1, ss2, vv_C1, vv_C2, vv_Ct1, vv_Ct2
3203
3204!! New parameters of the PBEsol+rVV10s,
3205!! Ref. A.V. Terentjev et al, Phys. Rev. B 98, 214108 (2018)
3206 vv_C1 = 0.5_dp
3207 vv_C2 = 300.0_dp
3208
3209! Avoid dividing by zero when kf=0
3210 kf1m = max(kf1,ktol)
3211 kf2m = max(kf2,ktol)
3212
3213! Find kernel
3214 pi = acos(-1.0_dp)
3215 n1 = kf1m**3/(3*pi**2) ! electron density at point 1
3216 n2 = kf2m**3/(3*pi**2) ! electron density at point 2
3217!! New formulas of the PBEsol+rVV10s,
3218!! Ref. A.V. Terentjev et al, Phys. Rev. B 98, 214108 (2018)
3219 ss1 = 0.1616204568582_dp*kg1/(n1**(1/3))
3220 ss2 = 0.1616204568582_dp*kg2/(n2**(1/3))
3221 vv_Ct1 = vv_C+vv_C1/(1.0_dp + vv_C2*(ss1-0.5_dp)**2)
3222 vv_Ct2 = vv_C+vv_C1/(1.0_dp + vv_C2*(ss2-0.5_dp)**2)
3223!!
3224 wp1 = sqrt(4*pi*n1) ! local plasma frequency at point 1
3225 wp2 = sqrt(4*pi*n2) ! local plasma frequency at point 2
3226!!
3227 wg1 = sqrt(vv_Ct1*kg1**4) ! local band gap at point 1
3228 wg2 = sqrt(vv_Ct2*kg2**4) ! local band gap at point 2
3229!!
3230 kappa1 = vv_b*kf1m**2/wp1 ! local VV kappa variable (eq.(9)) at point 1
3231 kappa2 = vv_b*kf2m**2/wp2 ! kappa variable at point 2
3232 w01 = sqrt(wg1**2+wp1**2/3) ! local w0 frequency (eq.(5)) at point 1
3233 w02 = sqrt(wg2**2+wp2**2/3) ! local w0 frequency at point 2
3234 g1 = w01*r12**2 + kappa1 ! local g variable (eq.(3)) at point 1
3235 g2 = w02*r12**2 + kappa2 ! local g variable at point 2
3236 phi = -1.5_dp/g1/g2/(g1+g2) ! VV kernel phi (eq.(2))
3237
3238 if (kernelPrefactor=='rho') then
3239 ! Return whole integrand of eq.(1)
3240 pbesvvs_vdw_phi_val = n1*n2*phi
3241 else if (kernelPrefactor=='kf') then
3242 ! Return kf1*kf2*phi
3243 pbesvvs_vdw_phi_val = kf1*kf2*phi
3244 else if (kernelPrefactor=='kf2') then
3245 ! Return (kf1*kf2)**2*phi
3246 pbesvvs_vdw_phi_val = (kf1*kf2)**2*phi
3247 else if (kernelPrefactor=='sqr_rho') then
3248 ! Find and return sqrt(n1*n2)*phi
3249 pbesvvs_vdw_phi_val = sqrt(n1*n2)*phi
3250 else
3251 call die('pbesvvs_vdw_phi_val ERROR: unknown kernelPrefactor')
3252 end if
3253
3254end function pbesvvs_vdw_phi_val
3255
3256! -----------------------------------------------------------------------------
3257
3258real(dp) function pbesvvs_vdw_beta()
3259
3260! Returns parameter beta of VV functional
3261
3262 implicit none
3263 pbesvvs_vdw_beta = vv_beta
3264
3265end function pbesvvs_vdw_beta
3266
3267!-----------------------------------------------------------------------------
3268
3269subroutine pbesvvs_vdw_get_kmesh( mkf, mkg, kf, kg )
3270
3271! Returns size and values of (kf,kg) mesh
3272
3273 implicit none
3274 integer, intent(out) :: mkf ! Number of kf mesh points
3275 integer, intent(out) :: mkg ! Number of kg mesh points
3276 real(dp),optional,intent(out) :: kf(:) ! Values of kf mesh points
3277 real(dp),optional,intent(out) :: kg(:) ! Values of kg mesh points
3278 integer:: nmax
3279 if (.not.kmesh_set) call set_kmesh()
3280 mkf = nkf
3281 mkg = nkg
3282 if (present(kf)) then
3283 nmax = max( nkf, size(kf) )
3284 kf(1:nmax) = kfmesh(1:nmax)
3285 end if
3286 if (present(kg)) then
3287 nmax = max( nkg, size(kg) )
3288 kg(1:nmax) = kgmesh(1:nmax)
3289 end if
3290end subroutine pbesvvs_vdw_get_kmesh
3291
3292! -----------------------------------------------------------------------------
3293
3294subroutine pbesvvs_vdw_phi( k, phi, dphidk )
3295
3296! Finds by interpolation phi(k1,k2,k) (Fourier transform of phi(k1,k2,r)),
3297! with k1=(kf1,kg1), k2=(kf2,kg2) for all mesh values of kf (Fermi
3298! wavevector) and kg (grad(n)/n). If the interpolation table does not exist,
3299! it is calculated in the first call to pbesvvs_vdw_phi. It requires a previous
3300! call to pbesvvs_vdw_set_kc to set k mesh.
3301
3302 implicit none
3303 real(dp),intent(in) :: k ! Modulus of actual k vector
3304 real(dp),intent(out):: phi(:,:) ! phi(k1,k2,k) at given k
3305 ! for all k1,k2 in (kf,kg) mesh
3306 real(dp),intent(out):: dphidk(:,:) ! dphi(k1,k2,k)/dk at given k
3307
3308 integer :: ik, ik1, ik2
3309 real(dp):: a, a2, a3, b, b2, b3
3310
3311! Set interpolation table
3312 if (.not.phi_table_set) call set_phi_table()
3313
3314! Check argument sizes
3315 if (size(phi,1)<nkfg .or. size(phi,2)<nkfg) &
3316 call die('pbesvvs_vdw_phi: ERROR: size(phi) too small')
3317
3318! Find phi values at point k
3319 if (k >= kcut) then
3320 phi(:,:) = 0
3321 dphidk(:,:) = 0
3322 else
3323 ! Expand interpolation inline since this is the hottest point in VdW
3324 ik = int(k/dk)
3325 a = ((ik+1)*dk-k)/dk
3326 b = 1 - a
3327 a2 = (3*a**2 -1) * dk / 6
3328 b2 = (3*b**2 -1) * dk / 6
3329 a3 = (a**3 - a) * dk**2 / 6
3330 b3 = (b**3 - b) * dk**2 / 6
3331 do ik2 = 1,nkfg
3332 do ik1 = 1,ik2
3333! call splint( dk, phik(:,ik1,ik2), d2phidk2(:,ik1,ik2), &
3334! nk+1, k, phi(ik1,ik2), dphidk(ik1,ik2), pr )
3335 phi(ik1,ik2) = a*phik(ik,ik1,ik2) + b*phik(ik+1,ik1,ik2) &
3336 + a3*d2phidk2(ik,ik1,ik2) + b3*d2phidk2(ik+1,ik1,ik2)
3337 dphidk(ik1,ik2) = (-phik(ik,ik1,ik2) &
3338 +phik(ik+1,ik1,ik2) )/dk &
3339 - a2*d2phidk2(ik,ik1,ik2) + b2*d2phidk2(ik+1,ik1,ik2)
3340 phi(ik2,ik1) = phi(ik1,ik2)
3341 dphidk(ik2,ik1) = dphidk(ik1,ik2)
3342 end do
3343 end do
3344 end if
3345
3346end subroutine pbesvvs_vdw_phi
3347
3348!-----------------------------------------------------------------------------
3349
3350subroutine pbesvvs_vdw_phiofr( r, phi )
3351
3352! Finds phi(k1,k2,r) with k1=(kf1,kg1), k2=(kf2,kg2) for mesh values of
3353! kf's (Fermi wavevectors) and kg's (grad(n)/n)
3354
3355 implicit none
3356 real(dp),intent(in) :: r
3357 real(dp),intent(out):: phi(:,:)
3358
3359 integer :: ikf1, ikf2, ikg1, ikg2, ik1, ik2
3360 real(dp):: dphidr
3361
3362 if (size(phi,1)<nkfg .or. size(phi,2)<nkfg) &
3363 stop 'vv_phiofr: ERROR: size(phi) too small'
3364 if (.not.phi_table_set) call set_phi_table()
3365
3366 if (r >= rcut) then
3367 phi(:,:) = 0
3368 else
3369 do ik2 = 1,nkfg
3370 do ik1 = 1,ik2
3371 call splint( dr, phir(:,ik1,ik2), d2phidr2(:,ik1,ik2), &
3372 nr+1, r, phi(ik1,ik2), dphidr )
3373 phi(ik2,ik1) = phi(ik1,ik2)
3374 end do ! ik1
3375 end do ! ik2
3376 end if ! (r>=rcut)
3377
3378end subroutine pbesvvs_vdw_phiofr
3379
3380!-----------------------------------------------------------------------------
3381
3382subroutine pbesvvs_vdw_set_kcut( kc )
3383
3384! Sets the reciprocal planewave cutoff kc of the integration grid, and finds
3385! the interpolation table to be used by vdw_phi to obtain the vdW kernel phi
3386! at the reciprocal mesh wavevectors.
3387
3388 implicit none
3389 real(dp),intent(in):: kc ! Planewave cutoff: k>kcut => phi=0
3390
3391 real(dp):: pi
3392
3393 ! Set kcut and radial mesh parameters, if not already set
3394 if (.not. kc==kcut) then
3395 kcut = kc
3396 pi = acos(-1._dp)
3397 dr = rcut / nr
3398 dk = pi / rcut
3399 kmax = pi / dr
3400 nk = int(kcut/dk) + 1
3401 if (nk>nr) stop 'pbesvvs_vdw_set_kcut: ERROR: nk>nr'
3402 kcut_set = .true.
3403#ifdef DEBUG_XC
3404 write(udebug,'(a,5f8.3)') 'pbesvvs_vdw_set_kcut: kfcut,kgcut,rcut,kcut,kmax=', &
3405 kfcut, kgcut, rcut, kc, kmax
3406#endif /* DEBUG_XC */
3407 end if
3408
3409 ! Set (kf,kg) mesh and phi table
3410 call set_kmesh()
3411 call set_phi_table()
3412
3413end subroutine pbesvvs_vdw_set_kcut
3414
3415!-----------------------------------------------------------------------------
3416
3417subroutine pbesvvs_vdw_theta( nspin, rhos, grhos, theta, dtdrho, dtdgrho )
3418
3419! Finds the value and derivatives of theta_i(rho,grad_rho) of eq.(8)
3420! of Roman-Soler PRL 2009. In practice, theta_i=p_i rather than rho*p_i,
3421! beacuse p_i is used here to expand rho1*rho2*phi rather than only phi.
3422
3423 implicit none
3424 integer, intent(in) :: nspin ! Number of spin components
3425 real(dp),intent(in) :: rhos(nspin) ! Electron spin density
3426 real(dp),intent(in) :: grhos(3,nspin) ! Spin density gradient
3427 real(dp),intent(out):: theta(nkfg) ! Exp. polynomials at (kf,kg)
3428 real(dp),intent(out):: dtdrho(nkfg,nspin) ! dtheta(ik)/drhos
3429 real(dp),intent(out):: dtdgrho(3,nkfg,nspin) ! dtheta(ik)/dgrhos(ix)
3430
3431 integer :: is, ix, ns
3432 real(dp):: rho, grho(3), dpdkf(nkfg), dpdkg(nkfg), dkfdrho, dkfdgrho(3), &
3433 dkgdrho, dkgdgrho(3), kf, kg, p(nkfg)
3434
3435 ! Sum spin components of electron density
3436 ns = min(nspin,2) ! num. of diagonal spin components (if noncollinear)
3437 rho = sum(rhos(1:ns)) ! local electron density
3438 grho = sum(grhos(:,1:ns),dim=2) ! local density gradient
3439
3440 ! If density is between threshold, return zero
3441 if (rho<rhoMin) then
3442 theta = 0
3443 dtdrho = 0
3444 dtdgrho = 0
3445 return
3446 end if
3447
3448 ! Find local Fermi and gradient wavevectors, and their derivatives
3449 call kofn( rho, grho, kf, kg, dkfdrho, dkgdrho, dkfdgrho, dkgdgrho )
3450
3451 ! Find expansion polynomials of integrand kernel of nonlocal vdW energy
3452 call pofk( kf, kg, p, dpdkf, dpdkg )
3453
3454 ! Find theta functions and their derivatives with respect to rho and grho
3455 if (kernelPrefactor=='rho') then
3456 ! This is the right code if pbesvvs_vdw_phi_val returns rho1*rho2*phi
3457 theta(1:nkfg) = p(1:nkfg)
3458 do is = 1,ns
3459 dtdrho(1:nkfg,is) = dpdkf(1:nkfg)*dkfdrho + dpdkg(1:nkfg)*dkgdrho
3460 do ix = 1,3
3461 dtdgrho(ix,1:nkfg,is) = dpdkf(1:nkfg)*dkfdgrho(ix) &
3462 + dpdkg(1:nkfg)*dkgdgrho(ix)
3463 end do
3464 end do
3465 else if (kernelPrefactor=='kf') then
3466 ! This is the right code if pbesvvs_vdw_phi_val returns kf1*kf2*phi
3467 kf = max(kf,ktol)
3468 theta(1:nkfg) = p(1:nkfg)*rho/kf
3469 do is = 1,ns
3470 dtdrho(1:nkfg,is) = (dpdkf(1:nkfg)*dkfdrho &
3471 +dpdkg(1:nkfg)*dkgdrho)*rho/kf &
3472 + p(1:nkfg)*(1/kf-rho/kf**2*dkfdrho)
3473 do ix = 1,3
3474 dtdgrho(ix,1:nkfg,is) = (dpdkf(1:nkfg)*dkfdgrho(ix) &
3475 +dpdkg(1:nkfg)*dkgdgrho(ix))*rho/kf
3476 end do
3477 end do
3478 else if (kernelPrefactor=='kf2') then
3479 ! This is the right code if pbesvvs_vdw_phi_val returns (kf1*kf2)**2*phi
3480 kf = max(kf,ktol)
3481 theta(1:nkfg) = p(1:nkfg)*rho/kf**2
3482 do is = 1,ns
3483 dtdrho(1:nkfg,is) = (dpdkf(1:nkfg)*dkfdrho &
3484 +dpdkg(1:nkfg)*dkgdrho)*rho/kf**2 &
3485 + p(1:nkfg)*(1/kf**2-2*rho/kf**3*dkfdrho)
3486 do ix = 1,3
3487 dtdgrho(ix,1:nkfg,is) = (dpdkf(1:nkfg)*dkfdgrho(ix) &
3488 +dpdkg(1:nkfg)*dkgdgrho(ix))*rho/kf**2
3489 end do
3490 end do
3491 else if (kernelPrefactor=='sqr_rho') then
3492 ! This is the right code if pbesvvs_vdw_phi_val returns sqrt(rho1*rho2)*phi
3493 rho = max(rho,1.e-12_dp) ! to avoid division by zero
3494 theta(1:nkfg) = p(1:nkfg) * sqrt(rho)
3495 do is = 1,ns
3496 dtdrho(1:nkfg,is) = ( dpdkf(1:nkfg)*dkfdrho &
3497 + dpdkg(1:nkfg)*dkgdrho ) * sqrt(rho) &
3498 + p(1:nkfg) * 0.5/sqrt(rho)
3499 do ix = 1,3
3500 dtdgrho(ix,1:nkfg,is) = dpdkf(1:nkfg)*dkfdgrho(ix) * sqrt(rho) &
3501 + dpdkg(1:nkfg)*dkgdgrho(ix) * sqrt(rho)
3502 end do
3503 end do
3504 else
3505 call die('pbesvvs_vdw_theta ERROR: unknown kernelPrefactor')
3506 end if ! (kernelPrefactor=='rho')
3507
3508end subroutine pbesvvs_vdw_theta
3509
3510END MODULE m_pbesvvs_vdwxc
3511
3512
9963513
=== modified file 'Src/atom.F'
--- Src/atom.F 2019-06-20 10:59:42 +0000
+++ Src/atom.F 2019-09-06 14:47:07 +0000
@@ -2038,6 +2038,8 @@
2038 if (icorr .eq. "wc") ps_string ="GGA WC"2038 if (icorr .eq. "wc") ps_string ="GGA WC"
2039 if (icorr .eq. "bl") ps_string ="GGA BLYP"2039 if (icorr .eq. "bl") ps_string ="GGA BLYP"
2040 if (icorr .eq. "ps") ps_string ="GGA PBEsol"2040 if (icorr .eq. "ps") ps_string ="GGA PBEsol"
2041!
2042 if (icorr .eq. "sg") ps_string ="GGA SG4"
20412043
2042 if (icorr .eq. "jo") ps_string ="GGA PBEJsJrLO"2044 if (icorr .eq. "jo") ps_string ="GGA PBEJsJrLO"
2043 if (icorr .eq. "jh") ps_string ="GGA PBEJsJrHEG"2045 if (icorr .eq. "jh") ps_string ="GGA PBEJsJrHEG"
@@ -2131,8 +2133,17 @@
2131 . write(6,'(a,1x,2a)')2133 . write(6,'(a,1x,2a)')
2132 . 'xc_check: WARNING: Pseudopotential generated with',2134 . 'xc_check: WARNING: Pseudopotential generated with',
2133 . trim(ps_string), " functional"2135 . trim(ps_string), " functional"
21342136!
21352137 elseif((XCauth(nf).eq.'SG4').and.(XCfunc(nf).eq.'GGA'))
2138 . then
2139
2140 write(6,'(a)')
2141 . 'xc_check: GGA SG4'
2142 if (icorr.ne.'sg'.and.nXCfunc.eq.1)
2143 . write(6,'(a,1x,2a)')
2144 . 'xc_check: WARNING: Pseudopotential generated with',
2145 . trim(ps_string), " functional"
2146
2136 elseif((XCauth(nf).eq.'PW91').and.(XCfunc(nf).eq.'GGA')) then2147 elseif((XCauth(nf).eq.'PW91').and.(XCfunc(nf).eq.'GGA')) then
21372148
2138 write(6,'(a)')2149 write(6,'(a)')
21392150
=== modified file 'Tests/Makefile'
--- Tests/Makefile 2019-01-30 15:22:16 +0000
+++ Tests/Makefile 2019-09-06 14:47:07 +0000
@@ -42,13 +42,14 @@
4242
43label = work43label = work
4444
45tests = 32_h2o ag anneal-cont ar2_vdw batio3 benzene bessel bessel-rich \45tests = 32_h2o ag ag_sg4 anneal-cont ar2_vdw batio3 benzene bessel bessel-rich \
46 born born_spin carbon_nanoscroll ch4 chargeconf-h2o \46 born born_spin carbon_nanoscroll ch4 chargeconf-h2o \
47 constant_volume dipole_correction fe fe_broyden \47 constant_volume dipole_correction fe fe_broyden \
48 fe_clust_noncollinear fe_clust_noncollinear-gga fe_cohp \48 fe_clust_noncollinear fe_clust_noncollinear-gga fe_cohp \
49 fen fe_noncol_kp fire_benzene floating \49 fen fe_noncol_kp fire_benzene floating \
50 force_2 force_constants gate_G_charge gate_G_hartree ge111 \50 force_2 force_constants gate_G_charge gate_G_hartree ge111 \
51 ge_fatbands_so graphite_c6 graphite_c6_full graphite_vdw_df \51 ge_fatbands_so graphite_c6 graphite_c6_full graphite_c6_sg4 graphite_vdw_df \
52 graphite_vdw_pbesvvs graphite_vdw_pbevv graphite_vdw_sg4vv \
52 h2_bessel h2o h2o_2 h2o_am05 h2o_bands h2o_bands_nc \53 h2_bessel h2o h2o_2 h2o_am05 h2o_bands h2o_bands_nc \
53 h2o_bands_polarized h2o_basis h2o_coop h2o_dipole h2o_dipole2 \54 h2o_bands_polarized h2o_basis h2o_coop h2o_dipole h2o_dipole2 \
54 h2o_dos h2o_filteret_basis h2o_findp_bug h2o_netcdf h2o_op_broyden \55 h2o_dos h2o_filteret_basis h2o_findp_bug h2o_netcdf h2o_op_broyden \
5556
=== modified file 'version.info'
--- version.info 2019-09-04 13:09:45 +0000
+++ version.info 2019-09-06 14:47:07 +0000
@@ -1,1 +1,1 @@
1trunk-7811trunk-782

Subscribers

People subscribed via source and target branches