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
1=== modified file 'Docs/siesta.tex'
2--- Docs/siesta.tex 2019-08-22 09:05:46 +0000
3+++ Docs/siesta.tex 2019-09-06 14:47:07 +0000
4@@ -3723,6 +3723,10 @@
5 implemented in \siesta)
6
7 \item%
8+ \fdf*{SG4}: GGA functional based on semiclassical atom theory of Lucian A. Constantin, Aleksandrs Terentjevs, Fabio Della Sala, Pietro Cortona and Eduardo Fabiano,
9+ Phys. Rev. B \textbf{93}, 045126 (2016).
10+
11+ \item%
12 \fdf*{DRSLL} (equivalent to \fdf*{DF1}): \xcidx{vdW-DF1}
13 \xcidx{DRSLL}%
14 van der Waals \xcidx{vdW} density functional (vdW-DF) \xcidx{vdW-DF}
15@@ -3757,6 +3761,19 @@
16 \fdf*{VV}: \xcidx{VV}%
17 vdW-DF functional of O. A. Vydrov and T. Van Voorhis,
18 J. Chem. Phys. \textbf{133}, 244103 (2010)
19+
20+ \item%
21+ \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).
22+
23+ \item%
24+ \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).
25+ SG4+VV10m is the modification of SG4+rVV10m functional for \siesta\ of Aleksandr V. Terentjev, Pietro Cortona, Lucian A. Constantin, José M. Pitarke
26+ Fabio Della Sala and Eduardo Fabiano, Computation \textbf{6}, 7 (2018).
27+
28+ \item%
29+ \fdf*{PBESVVS}: vdW-DF functional (PBEsol+VV10s) with PBEsol exchange and correlation functionals and with non-local correlation term of O. A. Vydrov and
30+ 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,
31+ Phys. Rev. B \textbf{98}, 214108 (2018).
32
33 \end{itemize}
34
35
36=== modified file 'Src/SiestaXC/ggaxc.f'
37--- Src/SiestaXC/ggaxc.f 2018-04-19 10:08:47 +0000
38+++ Src/SiestaXC/ggaxc.f 2019-09-06 14:47:07 +0000
39@@ -24,8 +24,9 @@
40 ! b88x, ! Becke, PRA 38, 3098 (1988) (exchange only)
41 ! b88kbmx, ! Klimes et al, JPCM 22, 022201 (2009) (exchange only)
42 ! c09x, ! Cooper, PRB 81, 161104 (2010) (exchange only)
43-! bhx ! Berland & Hyldgaard, PRB 89, 035412 (2014) (exchange only)
44-!
45+! bhx, ! Berland & Hyldgaard, PRB 89, 035412 (2014) (exchange only)
46+! sg4xc ! GGA Constantin et al, PRB, 93, 045126 (2016)
47+!
48 ! PUBLIC parameters, types, and variables available from this module:
49 ! none
50 !
51@@ -76,8 +77,9 @@
52 . b88x, ! Becke, PRA 38, 3098 (1988) (exchange only)
53 . b88kbmx, ! Klimes et al, JPCM 22, 022201 (2009) (exchange only)
54 . c09x, ! Cooper, PRB 81, 161104 (2010) (exchange only)
55- . bhx ! Berland & Hyldgaard, PRB 89, 035412 (2014) (exch. only)
56-
57+ . bhx, ! Berland & Hyldgaard, PRB 89, 035412 (2014) (exch. only)
58+ . sg4xc ! GGA Constantin et al, PRB, 93, 045126 (2016)
59+
60 PRIVATE ! Nothing is declared public beyond this point
61
62 CONTAINS
63@@ -255,6 +257,10 @@
64 CALL PBESOLXC( IREL, NS, DD, GDD,
65 . EPSX, EPSC, dEXdDD, dECdDD, dEXdGDD, dECdGDD )
66
67+ ELSEIF (AUTHOR.EQ.'SG4'.OR.AUTHOR.EQ.'sg4') THEN
68+ CALL SG4XC( IREL, NS, DD, GDD,
69+ . EPSX, EPSC, dEXdDD, dECdDD, dEXdGDD, dECdGDD )
70+
71 ELSEIF (AUTHOR.EQ.'AM05' .OR. AUTHOR.EQ.'am05') THEN
72 CALL AM05XC( IREL, NS, DD, GDD,
73 . EPSX, EPSC, dEXdDD, dECdDD, dEXdGDD, dECdGDD )
74@@ -2756,4 +2762,263 @@
75
76 END SUBROUTINE C09X
77
78- END MODULE m_ggaxc
79+! END MODULE m_ggaxc
80+
81+c
82+c the SG4 subroutine
83+c
84+
85+ SUBROUTINE SG4XC( IREL, nspin, Dens, GDens,
86+ . EX, EC, DEXDD, DECDD, DEXDGD, DECDGD )
87+
88+C *********************************************************************
89+C Implements GGA based on Semiclassical atom theory
90+C Ref: L.A.Constantin et al, PRB, 93, 045126 (2016)
91+C ******** INPUT ******************************************************
92+C INTEGER IREL : Relativistic-exchange switch (0=No, 1=Yes)
93+C INTEGER nspin : Number of spin polarizations (1 or 2)
94+C REAL*8 Dens(nspin) : Total electron density (if nspin=1) or
95+C spin electron density (if nspin=2)
96+C REAL*8 GDens(3,nspin) : Total or spin density gradient
97+C ******** OUTPUT *****************************************************
98+C REAL*8 EX : Exchange energy density
99+C REAL*8 EC : Correlation energy density
100+C REAL*8 DEXDD(nspin) : Partial derivative
101+C d(DensTot*Ex)/dDens(ispin),
102+C where DensTot = Sum_ispin( Dens(ispin) )
103+C For a constant density, this is the
104+C exchange potential
105+C REAL*8 DECDD(nspin) : Partial derivative
106+C d(DensTot*Ec)/dDens(ispin),
107+C where DensTot = Sum_ispin( Dens(ispin) )
108+C For a constant density, this is the
109+C correlation potential
110+C REAL*8 DEXDGD(3,nspin): Partial derivative
111+C d(DensTot*Ex)/d(GradDens(i,ispin))
112+C REAL*8 DECDGD(3,nspin): Partial derivative
113+C d(DensTot*Ec)/d(GradDens(i,ispin))
114+C ********* UNITS ****************************************************
115+C Lengths in Bohr
116+C Densities in electrons per Bohr**3
117+C Energies in Hartrees
118+C Gradient vectors in cartesian coordinates
119+C ********* ROUTINES CALLED ******************************************
120+C EXCHNG, PW92C
121+C ********************************************************************
122+
123+ use precision, only : dp
124+
125+ implicit none
126+ INTEGER IREL, nspin
127+ real(dp) Dens(nspin), DECDD(nspin), DECDGD(3,nspin),
128+ . DEXDD(nspin), DEXDGD(3,nspin), GDens(3,nspin)
129+
130+C Internal variables
131+ INTEGER
132+ . IS, IX
133+
134+ real(dp)
135+ . A, BETA, D(2), DADD, DECUDD, DENMIN,
136+ . DF1DD, DF2DD, DF3DD, DF4DD, DF1DGD, DF3DGD, DF4DGD,
137+ . DFCDD(2), DFCDGD(3,2), DFDD, DFDGD, DFXDD(2), DFXDGD(3,2),
138+ . DHDD, DHDGD, DKFDD, DKSDD, DPDD, DPDZ, DRSDD,
139+ . DS(2), DSDD, DSDGD, DT, DTDD, DTDGD, DZDD(2),
140+ . EC, ECUNIF, EX, EXUNIF,
141+ . F, F1, F2, F3, F4, FC, FX, FOUTHD,
142+ . GAMMA, GD(3,2), GDM(2), GDMIN, GDMS, GDMT, GDS, GDT(3),
143+ . H, HALF, KAPPA, KF, KFS, KS, MU, PHI, PI, RS, S,
144+ . T, THD, THRHLF, TWO, TWOTHD, VCUNIF(2), VXUNIF(2), ZETA,
145+c Lucian: new variables
146+ . beta0, sigma, alpha, amu1, amu2, ak1, ak2, term1, dbetadd,
147+ . dterm1dd, dbetadgd, dadgd, dterm1dgd, xx1, xx2, dxx1ds, dxx2ds,
148+ . dfds
149+
150+
151+C Lower bounds of density and its gradient to avoid divisions by zero
152+ PARAMETER ( DENMIN = 1.D-12 )
153+ PARAMETER ( GDMIN = 1.D-12 )
154+
155+C Fix some numerical parameters
156+ PARAMETER ( FOUTHD=4.D0/3.D0, HALF=0.5D0,
157+ . THD=1.D0/3.D0, THRHLF=1.5D0,
158+ . TWO=2.D0, TWOTHD=2.D0/3.D0 )
159+
160+C Fix some more numerical constants
161+c Lucian: constants for SG4 correlation and exchange
162+ PI = 4 * ATAN(1.D0)
163+ GAMMA = (1 - LOG(TWO)) / PI**2
164+ BETA0=0.07903051884257d0
165+ sigma=0.07d0
166+ alpha=0.8d0
167+c
168+ amu1=0.042d0
169+ amu2=0.218d0
170+ ak1=0.56028717948717954d0
171+ ak2=0.24371282051282048d0
172+C Translate density and its gradient to new variables
173+ IF (nspin .EQ. 1) THEN
174+ if(Dens(1).le.1.0d-12) Dens(1)=1.0d-12
175+ D(1) = HALF * Dens(1)
176+ D(2) = D(1)
177+ DT = MAX( DENMIN, Dens(1) )
178+ DO 10 IX = 1,3
179+ GD(IX,1) = HALF * GDens(IX,1)
180+ GD(IX,2) = GD(IX,1)
181+ GDT(IX) = GDens(IX,1)
182+ 10 CONTINUE
183+ ELSE
184+ if(Dens(1).le.1.0d-12) Dens(1)=1.0d-12
185+ if(Dens(2).le.1.0d-12) Dens(2)=1.0d-12
186+ D(1) = Dens(1)
187+ D(2) = Dens(2)
188+ DT = MAX( DENMIN, Dens(1)+Dens(2) )
189+ DO 20 IX = 1,3
190+ GD(IX,1) = GDens(IX,1)
191+ GD(IX,2) = GDens(IX,2)
192+ GDT(IX) = GDens(IX,1) + GDens(IX,2)
193+ 20 CONTINUE
194+ ENDIF
195+ GDM(1) = SQRT( GD(1,1)**2 + GD(2,1)**2 + GD(3,1)**2 )
196+ GDM(2) = SQRT( GD(1,2)**2 + GD(2,2)**2 + GD(3,2)**2 )
197+ GDMT = SQRT( GDT(1)**2 + GDT(2)**2 + GDT(3)**2 )
198+ GDMT = MAX( GDMIN, GDMT )
199+
200+C Find local correlation energy and potential
201+ CALL PW92C( 2, D, ECUNIF, VCUNIF )
202+
203+C Find total correlation energy
204+ RS = ( 3 / (4*PI*DT) )**THD
205+ KF = (3 * PI**2 * DT)**THD
206+ KS = SQRT( 4 * KF / PI )
207+ ZETA = ( D(1) - D(2) ) / DT
208+ ZETA = MAX( -1.D0+DENMIN, ZETA )
209+ ZETA = MIN( 1.D0-DENMIN, ZETA )
210+ PHI = HALF * ( (1+ZETA)**TWOTHD + (1-ZETA)**TWOTHD )
211+ T = GDMT / (2 * PHI * KS * DT)
212+c Define beta
213+ if(t.ge.100.d0)t=100.d0
214+ beta=beta0+sigma*t*(1.d0-dexp(-rs**2))
215+c
216+ F1 = ECUNIF / GAMMA / PHI**3
217+ F2 = EXP(-F1)
218+ A = BETA / GAMMA / (F2-1)
219+ F3 = T**2 + A * T**4
220+ F4 = BETA/GAMMA * F3 / (1 + A*F3)
221+c Define phi**(alpha*t**3) term
222+ term1 = phi ** ( alpha * t **3 )
223+ H = term1 * GAMMA * PHI**3 * LOG( 1 + F4 )
224+c
225+ FC = ECUNIF + H
226+
227+C Find correlation energy derivatives
228+ DRSDD = - (THD * RS / DT)
229+ DKFDD = THD * KF / DT
230+ DKSDD = HALF * KS * DKFDD / KF
231+ DZDD(1) = 1 / DT - ZETA / DT
232+ DZDD(2) = - (1 / DT) - ZETA / DT
233+ DPDZ = HALF * TWOTHD * ( 1/(1+ZETA)**THD - 1/(1-ZETA)**THD )
234+ DO 40 IS = 1,2
235+ DECUDD = ( VCUNIF(IS) - ECUNIF ) / DT
236+ DPDD = DPDZ * DZDD(IS)
237+ DTDD = (- T) * ( DPDD/PHI + DKSDD/KS + 1/DT )
238+c Derivative of beta
239+ dbetadd = sigma * DTDD * ( 1.d0 - dexp ( - rs ** 2 ) ) +
240+ . sigma * t * 2.d0 * rs * dexp ( - rs ** 2 ) * DRSDD
241+c
242+ DF1DD = F1 * ( DECUDD/ECUNIF - 3*DPDD/PHI )
243+ DF2DD = (- F2) * DF1DD
244+c Derivative of A
245+ DADD = (- A) * DF2DD / (F2-1) + dbetadd / GAMMA / (F2-1)
246+c
247+ DF3DD = (2*T + 4*A*T**3) * DTDD + DADD * T**4
248+ DF4DD = F4 * ( DF3DD/F3 - (DADD*F3+A*DF3DD)/(1+A*F3) )+
249+ . dbetadd/GAMMA * F3 / (1 + A*F3)
250+
251+c Derivative of term1
252+ dterm1dd = term1 * ( alpha * 3.d0 * t * t * dtdd * dlog(phi) +
253+ . alpha * t * t * t / phi * dpdd )
254+c
255+c Derivative of H
256+ DHDD= 3 * phi**2 * term1 * GAMMA * LOG( 1 + F4 ) * DPDD +
257+ . dterm1dd * GAMMA * PHI**3 * LOG( 1 + F4 ) +
258+ . term1 * GAMMA * PHI**3 * DF4DD / (1+F4)
259+c
260+ DFCDD(IS) = VCUNIF(IS) + H + DT * DHDD
261+ DO 30 IX = 1,3
262+ DTDGD = (T / GDMT) * GDT(IX) / GDMT
263+c Derivative of beta with respect to gradient
264+ dbetadgd = sigma * DTDGD * ( 1.d0 - dexp ( - rs**2 ) )
265+c Derivative of A with respect to gradient
266+ dadgd = dbetadgd / GAMMA / (F2-1)
267+c
268+ DF3DGD = DTDGD * ( 2 * T + 4 * A * T**3 ) +
269+ . dadgd * T**4
270+c
271+ DF4DGD = F4 * DF3DGD * ( 1/F3 - A/(1+A*F3) )+
272+ . dbetadgd /GAMMA * F3 / (1 + A*F3) -
273+ . BETA /GAMMA * F3 / (1 + A*F3)**2 * dadgd *f3
274+c
275+ dterm1dgd = term1 * alpha * 3.d0 * t * t * dtdgd * dlog(phi)
276+c
277+ DHDGD = term1 * GAMMA * PHI**3 * DF4DGD / (1+F4) +
278+ . dterm1dgd * GAMMA * PHI**3 * LOG( 1 + F4 )
279+c
280+ DFCDGD(IX,IS) = DT * DHDGD
281+ 30 CONTINUE
282+ 40 CONTINUE
283+
284+C Find exchange energy and potential
285+ FX = 0
286+ DO 60 IS = 1,2
287+ DS(IS) = MAX( DENMIN, 2 * D(IS) )
288+ GDMS = MAX( GDMIN, 2 * GDM(IS) )
289+ KFS = (3 * PI**2 * DS(IS))**THD
290+ S = GDMS / (2 * KFS * DS(IS))
291+c Exchange enhancement factor
292+ xx1=amu1*s*s/ak1
293+ xx2=amu2*s*s/ak2
294+ F=1+ak1+ak2-ak1/(1.d0+xx1+xx1**2+xx1**3+xx1**4)-
295+ . ak2/(1.d0+xx2)
296+c
297+c Note nspin=1 in call to exchng...
298+c
299+ CALL EXCHNG( IREL, 1, DS(IS), EXUNIF, VXUNIF(IS) )
300+ FX = FX + DS(IS) * EXUNIF * F
301+
302+ DKFDD = THD * KFS / DS(IS)
303+ DSDD = S * ( -(DKFDD/KFS) - 1/DS(IS) )
304+c Derivative of exchange enhancement factor
305+ dxx1ds=amu1*2.d0*s/ak1
306+ dxx2ds=amu2*2.d0*s/ak2
307+ dfds=ak1/(1.d0+xx1+xx1**2+xx1**3+xx1**4)**2 *
308+ . dxx1ds*(1.d0+2.d0*xx1+3.d0*xx1**2+4.d0*xx1**3) +
309+ . ak2/(1.d0+xx2)**2 * dxx2ds
310+ dfdd=dfds*dsdd
311+ DFXDD(IS) = VXUNIF(IS) * F + DS(IS) * EXUNIF * DFDD
312+
313+ DO 50 IX = 1,3
314+ GDS = 2 * GD(IX,IS)
315+ DSDGD = (S / GDMS) * GDS / GDMS
316+c
317+ DFDGD = dfds * DSDGD
318+c
319+ DFXDGD(IX,IS) = DS(IS) * EXUNIF * DFDGD
320+ 50 CONTINUE
321+ 60 CONTINUE
322+ FX = HALF * FX / DT
323+
324+C Set output arguments
325+ EX = FX
326+ EC = FC
327+ DO 90 IS = 1,nspin
328+ DEXDD(IS) = DFXDD(IS)
329+ DECDD(IS) = DFCDD(IS)
330+ DO 80 IX = 1,3
331+ DEXDGD(IX,IS) = DFXDGD(IX,IS)
332+ DECDGD(IX,IS) = DFCDGD(IX,IS)
333+ 80 CONTINUE
334+ 90 CONTINUE
335+
336+ END SUBROUTINE SG4XC
337+
338+ END MODULE m_ggaxc
339
340=== modified file 'Src/SiestaXC/vdwxc.F90'
341--- Src/SiestaXC/vdwxc.F90 2015-05-08 09:34:16 +0000
342+++ Src/SiestaXC/vdwxc.F90 2019-09-06 14:47:07 +0000
343@@ -257,12 +257,33 @@
344 use m_vv_vdwxc, only: vv_vdw_get_kmesh ! Size and values of (kf,kg) mesh
345 use m_vv_vdwxc, only: vv_vdw_phi ! Interpolates rho1*rho2*phi(k1,k2,k)
346 use m_vv_vdwxc, only: vv_vdw_set_kcut ! Sets the planewave cutoff kc
347-
348+!! New vdw
349+ use m_sg4vv_vdwxc, only: sg4vv_vdw_beta ! Parameter beta of VV2010 functional
350+ use m_sg4vv_vdwxc, only: sg4vv_vdw_theta ! Func. theta of VV2010 functional
351+ use m_sg4vv_vdwxc, only: sg4vv_vdw_get_kmesh ! Size and values of (kf,kg) mesh
352+ use m_sg4vv_vdwxc, only: sg4vv_vdw_phi ! Interpolates rho1*rho2*phi(k1,k2,k)
353+ use m_sg4vv_vdwxc, only: sg4vv_vdw_set_kcut ! Sets the planewave cutoff kc
354+
355+ use m_pbevv_vdwxc, only: pbevv_vdw_beta ! Parameter beta of VV2010 functional
356+ use m_pbevv_vdwxc, only: pbevv_vdw_theta ! Func. theta of VV2010 functional
357+ use m_pbevv_vdwxc, only: pbevv_vdw_get_kmesh ! Size and values of (kf,kg) mesh
358+ use m_pbevv_vdwxc, only: pbevv_vdw_phi ! Interpolates rho1*rho2*phi(k1,k2,k)
359+ use m_pbevv_vdwxc, only: pbevv_vdw_set_kcut ! Sets the planewave cutoff kc
360+
361+ use m_pbesvvs_vdwxc, only: pbesvvs_vdw_beta ! Parameter beta of VV2010 functional
362+ use m_pbesvvs_vdwxc, only: pbesvvs_vdw_theta ! Func. theta of VV2010 functional
363+ use m_pbesvvs_vdwxc, only: pbesvvs_vdw_get_kmesh ! Size and values of (kf,kg) mesh
364+ use m_pbesvvs_vdwxc, only: pbesvvs_vdw_phi ! Interpolates rho1*rho2*phi(k1,k2,k)
365+ use m_pbesvvs_vdwxc, only: pbesvvs_vdw_set_kcut ! Sets the planewave cutoff kc
366 ! Used module parameters
367 use precision, only: dp ! Real double precision type
368
369 #ifdef DEBUG_XC
370 use m_vv_vdwxc, only: vv_vdw_phiofr ! Interpolates rho1*rho2*phi(k1,k2,r)
371+!! New use of vdw_phiofr
372+ use m_sg4vv_vdwxc, only: sg4vv_vdw_phiofr
373+ use m_pbevv_vdwxc, only: pbevv_vdw_phiofr
374+ use m_pbesvvs_vdwxc, only: pbesvvs_vdw_phiofr
375 use debugXC, only: udebug ! File unit for debug output
376 ! use plot_module, only: plot
377 #endif /* DEBUG_XC */
378@@ -348,7 +369,7 @@
379 real(dp),parameter:: ytol = 1.e-15_dp ! Tol. for saturated q
380
381 ! Private module variables and arrays
382- character(len=5),save:: vdw_author='DRSLL' ! Functional 'flavour' name
383+ character(len=7),save:: vdw_author='PBESVVS' ! Functional 'flavour' name
384 real(dp),save:: dmesh(nd) ! Mesh points for phi(d1,d2) table
385 real(dp),save:: qmesh(mq) ! Mesh points for phi(q1,q2,r)
386 real(dp),save:: phi_table(0:3,0:3,nd,nd) ! Coefs. for bicubic interpolation
387@@ -748,8 +769,18 @@
388 ! Trap VV-version exception
389 #ifdef DEBUG_XC
390 if (vdw_author=='VV') then
391- call vv_vdw_phiofr( r, phi )
392- return
393+ call vv_vdw_phiofr( r, phi )
394+ return
395+!! New vdw_phiofr
396+ elseif (vdw_author=='SG4VV') then
397+ call sg4vv_vdw_phiofr( r, phi )
398+ return
399+ elseif (vdw_author=='PBEVV') then
400+ call pbevv_vdw_phiofr( r, phi )
401+ return
402+ elseif (vdw_author=='PBESVVS') then
403+ call pbesvvs_vdw_phiofr( r, phi )
404+ return
405 end if
406 #endif /* DEBUG_XC */
407
408@@ -1362,6 +1393,22 @@
409 dedrho = eps
410 dedgrho = 0
411 return
412+!! New vdw_beta
413+ elseif (vdw_author=='SG4VV') then
414+ eps = sg4vv_vdw_beta()
415+ dedrho = eps
416+ dedgrho = 0
417+ return
418+ elseif (vdw_author=='PBEVV') then
419+ eps = pbevv_vdw_beta()
420+ dedrho = eps
421+ dedgrho = 0
422+ return
423+ elseif (vdw_author=='PBESVVS') then
424+ eps = pbesvvs_vdw_beta()
425+ dedrho = eps
426+ dedgrho = 0
427+ return
428 end if
429
430 if (.not.initialized) then
431@@ -1424,11 +1471,30 @@
432
433 ! Trap VV-version exception
434 if (vdw_author=='VV') then
435- call vv_vdw_get_kmesh( nkf, nkg )
436+ call vv_vdw_get_kmesh( nkf, nkg )
437 n = nkf*nkg
438 if (present(q)) &
439 call die('vdw_get_qmesh: ERROR q-mesh not available for author=VV')
440 return
441+!! New vdw_get_kmesh
442+ elseif (vdw_author=='SG4VV') then
443+ call sg4vv_vdw_get_kmesh( nkf, nkg )
444+ n = nkf*nkg
445+ if (present(q)) &
446+ call die('vdw_get_qmesh: ERROR q-mesh not available for author=SG4VV')
447+ return
448+ elseif (vdw_author=='PBEVV') then
449+ call pbevv_vdw_get_kmesh( nkf, nkg )
450+ n = nkf*nkg
451+ if (present(q)) &
452+ call die('vdw_get_qmesh: ERROR q-mesh not available for author=PBEVV')
453+ return
454+ elseif (vdw_author=='PBESVVS') then
455+ call pbesvvs_vdw_get_kmesh( nkf, nkg )
456+ n = nkf*nkg
457+ if (present(q)) &
458+ call die('vdw_get_qmesh: ERROR q-mesh not available for author=PBESVVS')
459+ return
460 end if
461
462 if (.not.qmesh_set) call set_qmesh()
463@@ -1514,6 +1580,33 @@
464 dEXdD, dEdDaux, dEXdGD, dEdGDaux )
465 call GGAxc( 'PBE', iRel, nSpin, D, GD, epsAux, epsC, &
466 dEdDaux, dECdD, dEdGDaux, dECdGD )
467+!! New vdw functionals
468+ else if (vdw_author=='SG4VV' .or. vdw_author=='sg4vv') then
469+ ! A. V. Terentjev et al, Computation 6, 7 (2018)
470+ ! SG4 GGA for both exchange and correlation
471+ call GGAxc( 'SG4', iRel, nSpin, D, GD, epsX, epsAux, &
472+ dEXdD, dEdDaux, dEXdGD, dEdGDaux )
473+ call GGAxc( 'SG4', iRel, nSpin, D, GD, epsAux, epsC, &
474+ dEdDaux, dECdD, dEdGDaux, dECdGD )
475+
476+ else if (vdw_author=='PBEVV' .or. vdw_author=='pbevv' .or. &
477+ vdw_author=='PBEvv' .or. vdw_author=='pbeVV' ) then
478+ ! H. Peng and J. P. Perdew, Phys. Rev. B 95, 0811105 (2017)
479+ ! PBE GGA for both exchange and correlation
480+ call GGAxc( 'PBE', iRel, nSpin, D, GD, epsX, epsAux, &
481+ dEXdD, dEdDaux, dEXdGD, dEdGDaux )
482+ call GGAxc( 'PBE', iRel, nSpin, D, GD, epsAux, epsC, &
483+ dEdDaux, dECdD, dEdGDaux, dECdGD )
484+
485+ else if (vdw_author=='PBESVVS' .or. vdw_author=='pbesvvs' .or. &
486+ vdw_author=='PBESVVs' .or. vdw_author=='PBESvvs' ) then
487+ ! A. V. Terentjev et al, Phys. Rev. B 98, 214108 (2018)
488+ ! PBESOL GGA for both exchange and correlation
489+ call GGAxc( 'PBESOL', iRel, nSpin, D, GD, epsX, epsAux, &
490+ dEXdD, dEdDaux, dEXdGD, dEdGDaux )
491+ call GGAxc( 'PBESOL', iRel, nSpin, D, GD, epsAux, epsC, &
492+ dEdDaux, dECdD, dEdGDaux, dECdGD )
493+
494 else
495 stop 'vdw_exchng ERROR: unknown author'
496 end if
497@@ -1542,6 +1635,16 @@
498 if (vdw_author=='VV') then
499 call vv_vdw_phi( k, phi, dphidk )
500 return
501+!! New vdw_phi
502+ elseif (vdw_author=='SG4VV') then
503+ call sg4vv_vdw_phi( k, phi, dphidk )
504+ return
505+ elseif (vdw_author=='PBEVV') then
506+ call pbevv_vdw_phi( k, phi, dphidk )
507+ return
508+ elseif (vdw_author=='PBESVVS') then
509+ call pbesvvs_vdw_phi( k, phi, dphidk )
510+ return
511 end if
512
513 if (.not.kcut_set) stop 'vdw_phi: ERROR: kcut must be previously set'
514@@ -1605,6 +1708,13 @@
515 zab = -0.8491_dp
516 else if (author=='VV') then
517 ! Vydrov and Van Voorhis, JCP 133, 244103 (2010)
518+!! New vdw functionals
519+ else if (author=='SG4VV') then
520+ ! A. V. Terentjev et al, Computation 6, 7 (2018)
521+ else if (author=='PBEVV') then
522+ ! H. Peng and J. P. Perdew, Phys. Rev. B 95, 0811105 (2017)
523+ else if (author=='PBESVVS') then
524+ ! A. V. Terentjev et al, Phys. Rev. B 98, 214108 (2018)
525 else
526 stop 'vdw_set_author: ERROR: author not known'
527 end if
528@@ -1630,8 +1740,18 @@
529
530 ! Trap VV-version exception
531 if (vdw_author=='VV') then
532- call vv_vdw_set_kcut( kc )
533+ call vv_vdw_set_kcut( kc )
534 return
535+!! New vdw_set_kcut
536+ elseif (vdw_author=='SG4VV') then
537+ call sg4vv_vdw_set_kcut( kc )
538+ return
539+ elseif (vdw_author=='PBEVV') then
540+ call pbevv_vdw_set_kcut( kc )
541+ return
542+ elseif (vdw_author=='PBESVVS') then
543+ call pbesvvs_vdw_set_kcut( kc )
544+ return
545 end if
546
547 if (kc == kcut) return ! Work alredy done
548@@ -1780,6 +1900,16 @@
549 if (vdw_author=='VV') then
550 call vv_vdw_theta( nspin, rhos, grhos, theta, dtdrho, dtdgrho )
551 return
552+!! New vdw_theta
553+ elseif (vdw_author=='SG4VV') then
554+ call sg4vv_vdw_theta( nspin, rhos, grhos, theta, dtdrho, dtdgrho )
555+ return
556+ elseif (vdw_author=='PBEVV') then
557+ call pbevv_vdw_theta( nspin, rhos, grhos, theta, dtdrho, dtdgrho )
558+ return
559+ elseif (vdw_author=='PBESVVS') then
560+ call pbesvvs_vdw_theta( nspin, rhos, grhos, theta, dtdrho, dtdgrho )
561+ return
562 end if
563
564 ns = min(nspin,2)
565
566=== modified file 'Src/SiestaXC/vv_vdwxc.F90'
567--- Src/SiestaXC/vv_vdwxc.F90 2016-05-10 10:45:36 +0000
568+++ Src/SiestaXC/vv_vdwxc.F90 2019-09-06 14:47:07 +0000
569@@ -993,3 +993,2520 @@
570 end subroutine vv_vdw_theta
571
572 END MODULE m_vv_vdwxc
573+
574+!!!==================SG4VV====================
575+
576+MODULE m_sg4vv_vdwxc
577+
578+! Used module procedures
579+ use sys, only: die ! Termination routine
580+ use mesh1D, only: get_mesh ! Returns the mesh points
581+ use m_radfft, only: radfft ! Radial fast Fourier transform
582+ use alloc, only: re_alloc ! Re-allocation routine
583+ use mesh1D, only: set_mesh ! Sets a 1D mesh
584+ use interpolation,only: spline ! Sets spline interpolation
585+ use interpolation,only: splint ! Calculates spline interpolation
586+
587+! Used module parameters
588+ use precision, only: dp ! Real double precision type
589+
590+#ifdef DEBUG_XC
591+ use debugXC, only: udebug ! File unit for debug output
592+! use plot_module, only: plot
593+#endif /* DEBUG_XC */
594+
595+ implicit none
596+
597+! Called by m_vdwxc
598+PUBLIC :: &
599+ sg4vv_vdw_beta, &! Returns parameter beta of the VV2010 functional
600+ sg4vv_vdw_theta, &! Finds function theta_ik(rho,grad_rho)
601+ sg4vv_vdw_get_kmesh, &! Returns size and values of (kf,kg) mesh
602+ sg4vv_vdw_phi, &! Finds and interpolates rho1*rho2*phi(k1,k2,k)
603+ sg4vv_vdw_set_kcut ! Sets the planewave cutoff kc of the integration grid
604+
605+#ifdef DEBUG_XC
606+! Called by debugging test programs
607+PUBLIC :: &
608+ sg4vv_vdw_phi_val, &! Kernel phi(kf1,kf2,kg1,kg2,r12) with no interpolation
609+ sg4vv_vdw_phiofr ! Kernel phi(k1,k2,r) at tabulated k1,k2-mesh values
610+#endif /* DEBUG_XC */
611+
612+PRIVATE ! Nothing is declared public beyond this point
613+
614+!! Set parameters of the SG4+rVV10m functional
615+!! Ref. A. V. Terentjev et al, Computation 6, 7 (2018)
616+ real(dp),parameter:: vv_C = 0.0001
617+ real(dp),parameter:: vv_b = 12.0
618+!!
619+ real(dp),parameter:: vv_beta = 0.00497
620+
621+ ! Mesh parameters for table of phi(k1,k2,r) and its Fourier transform
622+ character(len=*),parameter:: kernelPrefactor='rho' ! Prefactor of the
623+ ! nonlocal kernel for interpolation
624+ ! ('kf'|'kf2'|'sqr_rho'|'rho')
625+ integer, parameter:: nr = 2048 ! Radial mesh points (power of 2)
626+ real(dp),parameter:: rcut = 100._dp ! Radial cutoff: r>rcut => phi=0
627+ real(dp),parameter:: rmin = 1.e-6_dp ! Min. radius as denominator
628+ integer, parameter:: nkf = 7 ! Number of Fermi wavevectors
629+ integer, parameter:: nkg = 5 ! Num. of grad(n)/n wavevectors
630+ integer, parameter:: nkfg = nkf*nkg ! Num. of (kf,kg) mesh points
631+ real(dp),parameter:: kfcut = 5.0_dp ! Max. Fermi wavevec.
632+ real(dp),parameter:: kgcut = 5.0_dp ! Max. grad(n)/n
633+ real(dp),parameter:: dkfmaxdkfmin = 20.0_dp ! Last/first kf mesh interval
634+ real(dp),parameter:: dkgmaxdkgmin = 2.0_dp ! Last/first kg mesh interval
635+ real(dp),parameter:: ktol = 1.e-12_dp ! 'out of range' tolerance
636+ real(dp),parameter:: amin = 1.e-12_dp ! tiny denominator to avoid /0
637+ real(dp),parameter:: rhoMin = 1.e-10_dp ! Min. density for nonzero Vxc
638+
639+ ! Parameters for cutoff function, used in radial Fourier transforms of phi
640+ integer, parameter:: ncut1 = 8 ! cutoff(x)=(1-x**ncut1)**ncut2
641+ integer, parameter:: ncut2 = 4
642+
643+ ! Parameters for saturate function, used to enforce that q<qcut
644+ integer, parameter:: nsat = 15 ! h(x,xc)=1/(1/x**nsat+1/xc**nsat)**(1/nsat)
645+ ! nsat=15 approximately corresponds to
646+ ! nsat=12 for eq.(5) of Roman-Soler PRL
647+
648+ ! Private module variables and arrays
649+ logical, save:: kcut_set=.false. ! Has kcut been set?
650+ logical, save:: kmesh_set=.false. ! Has (kf,kg) mesh been set?
651+ logical, save:: phi_table_set=.false. ! Has phi_table been set?
652+ integer, save:: nk ! Num. of radial mesh k-points
653+ real(dp),save:: dr ! r-mesh interval
654+ real(dp),save:: dk ! k-mesh interval
655+ real(dp),save:: kcut ! Planewave cutoff: k>kcut => phi=0
656+ real(dp),save:: kmax ! Max. k vector in Fourier transforms
657+ real(dp),save:: kfmesh(nkf) ! Mesh points for Fermi wavevector
658+ real(dp),save:: kgmesh(nkg) ! Mesh points for grad(n)/n
659+ real(dp),pointer,save:: &
660+ phir(:,:,:)=>null(), &! Table of phi(r)
661+ phik(:,:,:)=>null(), &! Table of phi(k)
662+ d2phidr2(:,:,:)=>null(),&! Table of d^2(phi)/dr^2
663+ d2phidk2(:,:,:)=>null() ! Table of d^2(phi)/dk^2
664+
665+CONTAINS
666+
667+! -----------------------------------------------------------------------------
668+
669+real(dp) function cutoff( x )
670+
671+! Defines a smooth cutoff function that falls from y(0)=1 to y(1)=0
672+
673+ implicit none
674+ real(dp),intent(in):: x
675+
676+ if (x<=0._dp) then
677+ cutoff = 1
678+ else if (x>=1._dp) then
679+ cutoff = 0
680+ else
681+ cutoff = (1-x**ncut1)**ncut2
682+ end if
683+
684+end function cutoff
685+
686+!-----------------------------------------------------------------------------
687+
688+subroutine iofk( kf, kg, ikf, ikg )
689+
690+! Finds indexes ikf and ikg such that kfmesh(ikf) <= kf < kfmesh(ikf+1)
691+! and kgmesh(ikg) <= kg < kgmesh(ikg+1) in logarithmic meshes of the form
692+! k(ik) = b*(exp((ik-1)*a)-1)
693+
694+ implicit none
695+ real(dp), intent(in) :: kf, kg
696+ integer, intent(out):: ikf, ikg
697+
698+ real(dp),save:: akf, akg, bkf, bkg
699+ logical, save:: first_call = .true.
700+ integer:: ik
701+
702+ ! Mesh data initializations
703+ if (first_call) then
704+ ! Find logarithmic-mesh a & b parameters: x(j)=x(1)+b*(exp(a*(j-1))-1)
705+ akf = log( (kfmesh(nkf)-kfmesh(nkf-1)) / (kfmesh(2)-kfmesh(1)) ) / (nkf-2)
706+ akg = log( (kgmesh(nkg)-kgmesh(nkg-1)) / (kgmesh(2)-kgmesh(1)) ) / (nkg-2)
707+ akf = max( akf, amin )
708+ akg = max( akg, amin )
709+ bkf = (kfmesh(nkf) - kfmesh(1)) / (exp(akf*(nkf-1)) - 1)
710+ bkg = (kgmesh(nkg) - kgmesh(1)) / (exp(akg*(nkg-1)) - 1)
711+ ! Check that meshes are indeed logarithmic
712+ do ik = 1,nkf
713+ if (abs(kfmesh(ik)-kfmesh(1)-bkf*(exp(akf*(ik-1))-1))>ktol) &
714+ call die('sg4vv_vdw_iofk ERROR: kfmesh not logarithmic')
715+ end do
716+ do ik = 1,nkg
717+ if (abs(kgmesh(ik)-kgmesh(1)-bkg*(exp(akg*(ik-1))-1))>ktol) &
718+ call die('sg4vv_vdw_iofk ERROR: kgmesh not logarithmic')
719+ end do
720+ first_call = .false.
721+ end if
722+
723+ ! Check that kf and kg are within interpolation range
724+ if (kf<kfmesh(1)-ktol .or. kf>kfmesh(nkf)+ktol .or. &
725+ kg<kgmesh(1)-ktol .or. kg>kgmesh(nkg)+ktol) then
726+ call die('sg4vv_vdw_iofk ERROR: (kf,kg) out of range')
727+ endif
728+
729+ ! Find interpolation mesh intervals
730+ ikf = 1 + int( log( 1 + (kf-kfmesh(1))/bkf ) / akf )
731+ ikg = 1 + int( log( 1 + (kg-kgmesh(1))/bkg ) / akg )
732+ ikf = max( 1, ikf )
733+ ikg = max( 1, ikg )
734+ ikf = min( nkf-1, ikf )
735+ ikg = min( nkg-1, ikg )
736+
737+end subroutine iofk
738+
739+! -----------------------------------------------------------------------------
740+
741+subroutine kofn( n, gn, kf, kg, dkfdn, dkgdn, dkfdgn, dkgdgn )
742+
743+! Finds Fermi and gradient wavevectors from density and gradient
744+
745+ implicit none
746+ real(dp), intent(in) :: n ! Electron density
747+ real(dp), intent(in) :: gn(3) ! Density gradient
748+ real(dp), intent(out):: kf ! Local Fermi wavevector
749+ real(dp), intent(out):: kg ! |grad(n)|/n
750+ real(dp), intent(out):: dkfdn ! dkf/dn
751+ real(dp), intent(out):: dkgdn ! dkg/dn
752+ real(dp), intent(out):: dkfdgn(3) ! dkf/dgn
753+ real(dp), intent(out):: dkgdgn(3) ! dkg/dgn
754+
755+ real(dp):: gn2, pi
756+
757+! Trap exception for zero density
758+ if (n <= 1.e-30_dp) then
759+ kf = 0
760+ kg = 0
761+ dkfdn = 0
762+ dkfdgn = 0
763+ dkgdn = 0
764+ dkgdgn = 0
765+ return
766+ end if
767+
768+! Find kf and kg
769+ pi = acos(-1._dp)
770+ kf = (3*pi**2*n)**(1._dp/3)
771+ gn2 = sum(gn**2)
772+ kg = sqrt(gn2)/n
773+
774+! Find derivatives
775+ dkfdn = kf/n/3
776+ dkfdgn = 0
777+ dkgdn = -kg/n
778+ dkgdgn = kg*gn/gn2
779+
780+end subroutine kofn
781+
782+!-----------------------------------------------------------------------------
783+
784+subroutine pofk( kf, kg, p, dpdkf, dpdkg )
785+
786+! Finds the values and derivatives, at (kf,kg), of the bicubic polynomials
787+! p_i(kf,kg) such that
788+! y(kf,kg) = Sum_i p_i(kf,kg) * y_i
789+! is the bicubic spline interpolation at (kf,kg) of (any) function y with
790+! values y_i at mesh points (kfmesh,kgmesh)_i
791+
792+ implicit none
793+ real(dp),intent(in) :: kf, kg ! point at which the polynomials are required
794+ real(dp),intent(out):: p(nkfg) ! polynomial values at (kf,kg)
795+ real(dp),intent(out):: dpdkf(nkfg) ! dp/dkf at (kf,kg)
796+ real(dp),intent(out):: dpdkg(nkfg) ! dp/dkg at (kf,kg)
797+
798+ integer :: ikf, ikg, ikfg, ikf0, ikg0
799+ real(dp):: a, b, dk, dkf0dkf, dkg0dkg, kf0, kg0
800+ real(dp):: pkf0(nkf), dpkfdkf0(nkf), pkg0(nkg), dpkgdkg0(nkg)
801+ logical, save :: first_call=.true.
802+ real(dp),save :: pkf(nkf,nkf), d2pkfdkf2(nkf,nkf)
803+ real(dp),save :: pkg(nkg,nkg), d2pkgdkg2(nkg,nkg)
804+
805+! Set up spline polynomial basis
806+ if (first_call) then
807+ do ikf = 1,nkf
808+ pkf(:,ikf) = 0 ! ikf'th polynomial pkf(:,ikf) is one at kfmesh(ikf)
809+ pkf(ikf,ikf) = 1 ! and zero at all other points
810+ call spline( kfmesh, pkf(:,ikf), nkf, 1.e30_dp, 1.e30_dp, &
811+ d2pkfdkf2(:,ikf) )
812+! call spline( kfmesh, pkf(:,ikf), nkf, 0._dp, 0._dp, d2pkfdkf2(:,ikf) )
813+ end do
814+ do ikg = 1,nkg
815+ pkg(:,ikg) = 0
816+ pkg(ikg,ikg) = 1
817+ call spline( kgmesh, pkg(:,ikg), nkg, 1.e30_dp, 1.e30_dp, &
818+ d2pkgdkg2(:,ikg) )
819+! call spline( kgmesh, pkg(:,ikg), nkg, 0._dp, 0._dp, d2pkgdkg2(:,ikg) )
820+ end do
821+
822+! DEBUG
823+ open(22,file='pkf.dat')
824+ do ikf = 1,nkf
825+ write(22,'(20e15.6)') kfmesh(ikf), pkf(:,ikf), d2pkfdkf2(:,ikf)
826+ end do
827+ close(22)
828+ open(22,file='pkg.dat')
829+ do ikg = 1,nkg
830+ write(22,'(20e15.6)') kgmesh(ikg), pkg(:,ikg), d2pkgdkg2(:,ikg)
831+ end do
832+ close(22)
833+! END DEBUG
834+
835+ first_call = .false.
836+ end if
837+
838+! 'Saturate' (kf,kg) values to bring them to interpolation range
839+ call saturate( kf, kfcut, kf0, dkf0dkf )
840+ call saturate( kg, kgcut, kg0, dkg0dkg )
841+
842+! Find interval of k mesh in which (kf0,kg0) point is included
843+ call iofk( kf0, kg0, ikf0, ikg0 )
844+
845+! Evaluate pkf polynomials of spline basis at kf0
846+! The splint code is in-lined here because it is a hot point
847+ dk = kfmesh(ikf0+1) - kfmesh(ikf0)
848+ a = (kfmesh(ikf0+1) - kf0) / dk ! dadkf0 = -1/dk
849+ b = (kf0 - kfmesh(ikf0)) / dk ! dbdkf0 = +1/dk
850+ do ikf = 1,nkf
851+ pkf0(ikf) = a*pkf(ikf0,ikf) + b*pkf(ikf0+1,ikf) &
852+ + ((a**3-a)*d2pkfdkf2(ikf0,ikf) + &
853+ (b**3-b)*d2pkfdkf2(ikf0+1,ikf)) * dk**2/6
854+ dpkfdkf0(ikf) = - (pkf(ikf0,ikf) - pkf(ikf0+1,ikf)) / dk &
855+ - ((3*a**2-1)*d2pkfdkf2(ikf0,ikf) - &
856+ (3*b**2-1)*d2pkfdkf2(ikf0+1,ikf)) * dk/6
857+ end do
858+
859+! Evaluate pkg polynomials of spline basis at kg0
860+ dk = kgmesh(ikg0+1) - kgmesh(ikg0)
861+ a = (kgmesh(ikg0+1) - kg0) / dk ! dadkg0 = -1/dk
862+ b = (kg0 - kgmesh(ikg0)) / dk ! dbdkg0 = +1/dk
863+ do ikg = 1,nkg
864+ pkg0(ikg) = a*pkg(ikg0,ikg) + b*pkg(ikg0+1,ikg) &
865+ + ((a**3-a)*d2pkgdkg2(ikg0,ikg) + &
866+ (b**3-b)*d2pkgdkg2(ikg0+1,ikg)) * dk**2/6
867+ dpkgdkg0(ikg) = - (pkg(ikg0,ikg) - pkg(ikg0+1,ikg)) / dk &
868+ - ((3*a**2-1)*d2pkgdkg2(ikg0,ikg) - &
869+ (3*b**2-1)*d2pkgdkg2(ikg0+1,ikg)) * dk/6
870+ end do
871+
872+! Evaluate pkf*pkg polynomials at (kf0,kg0)
873+ ikfg = 0
874+ do ikg = 1,nkg
875+ do ikf = 1,nkf
876+ ikfg = ikfg+1
877+ p(ikfg) = pkf0(ikf) * pkg0(ikg)
878+ dpdkf(ikfg) = dpkfdkf0(ikf)*dkf0dkf * pkg0(ikg)
879+ dpdkg(ikfg) = pkf0(ikf) * dpkgdkg0(ikg)*dkg0dkg
880+ end do
881+ end do
882+
883+end subroutine pofk
884+
885+!-----------------------------------------------------------------------------
886+
887+subroutine saturate( x, xc, y, dydx )
888+
889+ ! Defines a function y(x,xc) = 1/(1/x^nsat+1/xc^nsat)^(1/nsat), where nsat
890+ ! is an integer set in the module header. This function is approximately
891+ ! equal to x for x<xc and it saturates to xc when x->infinity
892+
893+ implicit none
894+ real(dp),intent(in) :: x ! Independent variable
895+ real(dp),intent(in) :: xc ! Saturation value
896+ real(dp),intent(out):: y ! Function value
897+ real(dp),intent(out):: dydx ! Derivative dy/dx
898+
899+ real(dp):: z
900+
901+ if (xc<=0._dp) then
902+ call die('sg4vv_vdwxc_saturate ERROR: xc<=0')
903+ else if (x<0._dp) then
904+ call die('sg4vv_vdwxc_saturate ERROR: x<0')
905+ else if (x==0._dp) then
906+ y = 0
907+ dydx = 1
908+ else
909+ z = 1/x**nsat + 1/xc**nsat
910+ y = 1/z**(1._dp/nsat)
911+ dydx = y/z/x**(nsat+1)
912+ end if
913+
914+end subroutine saturate
915+
916+!-----------------------------------------------------------------------------
917+
918+subroutine saturate_inverse( y, xc, x, dxdy )
919+
920+! Finds the inverse of the function defined in saturate subroutine:
921+! y=1/(1/x^n+1/xc^n)^(1/n) => x=1/(1/y^n-1/xc^n)^(1/n)
922+
923+ implicit none
924+ real(dp),intent(in) :: y ! Independent variable
925+ real(dp),intent(in) :: xc ! Saturation value
926+ real(dp),intent(out):: x ! Inverse function value
927+ real(dp),intent(out):: dxdy ! Derivative dx/dy
928+
929+ real(dp):: z
930+
931+ if (xc<=0._dp) then
932+ call die('sg4vv_vdwxc_saturate_inverse ERROR: xc<=0')
933+ else if (y<0._dp .or. y>=xc) then
934+ call die('sg4vv_vdwxc_saturate_inverse ERROR: y out of range')
935+ else if (y==0._dp) then
936+ x = 0
937+ dxdy = 1
938+ else
939+ z = 1/y**nsat - 1/xc**nsat
940+ x = 1/z**(1._dp/nsat)
941+ dxdy = x/z/y**(nsat+1)
942+ end if
943+
944+end subroutine saturate_inverse
945+
946+!-----------------------------------------------------------------------------
947+
948+subroutine set_kmesh()
949+
950+! Sets mesh of q values
951+
952+ implicit none
953+ integer :: mkf, mkg
954+
955+ if (.not.kmesh_set) then
956+ call set_mesh( nkf, xmax=kfcut, dxndx1=dkfmaxdkfmin )
957+ call get_mesh( nkf, mkf, kfmesh )
958+ call set_mesh( nkg, xmax=kgcut, dxndx1=dkgmaxdkgmin )
959+ call get_mesh( nkg, mkg, kgmesh )
960+ kmesh_set = .true.
961+#ifdef DEBUG_XC
962+ write(udebug,'(/,a,/,(10f8.4))') 'sg4vv_vdw_set_kmesh: kfmesh =', kfmesh
963+ write(udebug,'(/,a,/,(10f8.4))') 'sg4vv_vdw_set_kmesh: kgmesh =', kgmesh
964+#endif /* DEBUG_XC */
965+ end if
966+
967+end subroutine set_kmesh
968+
969+! -----------------------------------------------------------------------------
970+
971+subroutine set_phi_table()
972+
973+! Finds and stores in memory the interpolation table (mesh points and
974+! function values) for the kernel phi(k1,k2,k).
975+
976+ implicit none
977+ character(len=*),parameter:: myName = 'sg4vv_vdwxc/set_phi_table '
978+ integer :: ik, ikf1, ikf2, ikg1, ikg2, ik1, ik2, ir
979+ real(dp):: dkdk0, dphidk0, dphidkmax, dphidr0, dphidrmax, &
980+ k, kf1, kf2, kg1, kg2, pi, r(0:nr)
981+
982+! Check that table was not set yet
983+ if (phi_table_set) return
984+
985+! Check that kf, kg, r, and k meshes have been set
986+ if (.not.kmesh_set) call set_kmesh()
987+ if (.not.kcut_set) call die('sg4vv_vdw_set_phi_table ERROR: kcut not set')
988+ forall(ir=0:nr) r(ir) = ir*dr
989+ pi = acos(-1.0_dp)
990+
991+! Allocate arrays
992+ call re_alloc( phir, 0,nr, 1,nkfg, 1,nkfg, myName//'phir' )
993+ call re_alloc( phik, 0,nr, 1,nkfg, 1,nkfg, myName//'phik' )
994+ call re_alloc( d2phidr2, 0,nr, 1,nkfg, 1,nkfg, myName//'d2phidr2' )
995+ call re_alloc( d2phidk2, 0,nr, 1,nkfg, 1,nkfg, myName//'d2phidk2' )
996+
997+! Loop on (k1,k2) mesh points
998+ do ikg2 = 1,nkg ! loop on kg2
999+ do ikf2 = 1,nkf ! loop on kf2
1000+ ik2 = ikf2 + nkf*(ikg2-1) ! combined (ikf2,ikg2) index
1001+ do ikg1 = 1,nkg ! loop on kg1
1002+ do ikf1 = 1,nkf ! loop on kf1
1003+ ik1 = ikf1 + nkf*(ikg1-1) ! combined (ikf1,ikg1) index
1004+ if (ik1>ik2) cycle ! since we will symmetrize at the end
1005+
1006+ ! Saturated (kf,kg) values
1007+ kf1 = kfmesh(ikf1)
1008+ kf2 = kfmesh(ikf2)
1009+ kg1 = kgmesh(ikg1)
1010+ kg2 = kgmesh(ikg2)
1011+
1012+ ! Find original (unsaturated) kf anf kg values
1013+ ! call saturate_inverse( kfmesh(ikf1), kfcut, kf1, dkdk0 )
1014+ ! call saturate_inverse( kfmesh(ikf2), kfcut, kf2, dkdk0 )
1015+ ! call saturate_inverse( kgmesh(ikg1), kgcut, kg1, dkdk0 )
1016+ ! call saturate_inverse( kgmesh(ikg2), kgcut, kg2, dkdk0 )
1017+
1018+ ! Find kernel as a function of r12
1019+ do ir = 0,nr
1020+ phir(ir,ik1,ik2) = sg4vv_vdw_phi_val( kf1, kf2, kg1, kg2, r(ir) )
1021+ end do
1022+
1023+ ! Kill kernel smoothly at r=rcut
1024+ do ir = 0,nr
1025+ phir(ir,ik1,ik2) = phir(ir,ik1,ik2) * cutoff( r(ir)/rcut )
1026+ end do
1027+
1028+ ! Find kernel in reciprocal space
1029+ call radfft( 0, nr, rcut, phir(:,ik1,ik2), phik(:,ik1,ik2) )
1030+ phik(:,ik1,ik2) = phik(:,ik1,ik2) * (2*pi)**1.5_dp
1031+
1032+ ! Filter out above kcut
1033+ phik(nk:nr,ik1,ik2) = 0
1034+
1035+ ! Soft filter below kcut
1036+ do ik = 1,nk
1037+ k = ik * dk
1038+ phik(ik,ik1,ik2) = phik(ik,ik1,ik2) * cutoff(k/kcut)
1039+ end do
1040+
1041+ ! Find filtered kernel in real space
1042+ call radfft( 0, nr, kmax, phik(:,ik1,ik2), phir(:,ik1,ik2) )
1043+ phir(:,ik1,ik2) = phir(:,ik1,ik2) / (2*pi)**1.5_dp
1044+
1045+ ! Set up spline interpolation tables
1046+ dphidr0 = 0 ! since phi(k1,k2,r) is even in r
1047+ dphidk0 = 0 ! and therefore phi(k1,k2,k) is also even in k
1048+ dphidrmax = 0 ! since phi->0 for r->infty
1049+ dphidkmax = 0 ! and also when k->infty
1050+ call spline( dr, phir(:,ik1,ik2), nr+1, dphidr0, dphidrmax, &
1051+ d2phidr2(:,ik1,ik2) )
1052+ call spline( dk, phik(:,ik1,ik2), nk+1, dphidk0, dphidkmax, &
1053+ d2phidk2(:,ik1,ik2) )
1054+
1055+ ! Fill symmetric elements
1056+ phir(:,ik2,ik1) = phir(:,ik1,ik2)
1057+ phik(:,ik2,ik1) = phik(:,ik1,ik2)
1058+ d2phidr2(:,ik2,ik1) = d2phidr2(:,ik1,ik2)
1059+ d2phidk2(:,ik2,ik1) = d2phidk2(:,ik1,ik2)
1060+
1061+!#ifdef DEBUG_XC
1062+! if (.false. .and. ik1==ik2) then
1063+! print*, 'sg4vv_vdw_set_kcut: ik1,ik2=', ik1, ik2
1064+! call window( 0._dp, 5._dp, -1._dp, 4._dp, 0 )
1065+! call axes( 0._dp, 1._dp, 0._dp, 1._dp )
1066+! call plot( nr+1, r, phi, phir(:,ik1,ik2) )
1067+! call window( 0._dp, 10._dp, -0.05_dp, 0.15_dp, 0 )
1068+! call axes( 0._dp, 1._dp, 0._dp, 0.05_dp )
1069+! call plot( nr+1, r, r**2*phi, r**2*phir(:,ik1,ik2))
1070+! call show()
1071+! end if
1072+!#endif /* DEBUG_XC */
1073+
1074+ end do ! ikf1
1075+ end do ! ikg1
1076+ end do ! ikf2
1077+ end do ! ikg2
1078+
1079+!#ifdef DEBUG_XC
1080+! open(17,file='vv_phi.table')
1081+! write(17,'(3a6,2a12,/,(3i6,2f15.9))') &
1082+! 'ik1', 'ik2', 'ir', 'phi', 'd2phi/dk2', &
1083+!! (((ik1,ik2,ir,phir(ir,ik1,ik2),d2phidr2(ir,ik1,ik2), &
1084+! (((ik1,ik2,ir,phik(ir,ik1,ik2),d2phidk2(ir,ik1,ik2), &
1085+! ir=0,100),ik2=1,nkfg),ik1=1,nkfg)
1086+! close(17)
1087+!#endif /* DEBUG_XC */
1088+
1089+! Mark table as set
1090+ phi_table_set = .true.
1091+
1092+end subroutine set_phi_table
1093+
1094+! -----------------------------------------------------------------------------
1095+
1096+real(dp) function sg4vv_vdw_phi_val( kf1, kf2, kg1, kg2, r12 )
1097+
1098+! vdW energy kernel of Vydrov-vanVoorhis, eq.(2) of JCP 133, 244103 (2010)
1099+! This subroutine calculates the 'raw' kernel directly, without interpolarions
1100+! In practice, it returns n1*n2*phi(k1,k2,r12), which is smooth for kf->0
1101+! Input:
1102+! real(dp):: kf1, kf2 ! Fermi wavevectors at points 1 and 2
1103+! real(dp):: kg1, kg2 ! |grad(n)|/n at points 1 and 2
1104+! real(dp):: r12 ! distance between points 1 and 2
1105+
1106+! Arguments
1107+ implicit none
1108+ real(dp),intent(in) :: kf1, kf2, kg1, kg2, r12
1109+
1110+! Internal variables
1111+ real(dp):: g1, g2, kappa1, kappa2, kf1m, kf2m, n1, n2, &
1112+ phi, pi, w01, w02, wg1, wg2, wp1, wp2
1113+
1114+! Avoid dividing by zero when kf=0
1115+ kf1m = max(kf1,ktol)
1116+ kf2m = max(kf2,ktol)
1117+
1118+! Find kernel
1119+ pi = acos(-1.0_dp)
1120+ n1 = kf1m**3/(3*pi**2) ! electron density at point 1
1121+ n2 = kf2m**3/(3*pi**2) ! electron density at point 2
1122+ wp1 = sqrt(4*pi*n1) ! local plasma frequency at point 1
1123+ wp2 = sqrt(4*pi*n2) ! local plasma frequency at point 2
1124+ wg1 = sqrt(vv_C*kg1**4) ! local band gap at point 1
1125+ wg2 = sqrt(vv_C*kg2**4) ! local band gap at point 2
1126+ kappa1 = vv_b*kf1m**2/wp1 ! local VV kappa variable (eq.(9)) at point 1
1127+ kappa2 = vv_b*kf2m**2/wp2 ! kappa variable at point 2
1128+ w01 = sqrt(wg1**2+wp1**2/3) ! local w0 frequency (eq.(5)) at point 1
1129+ w02 = sqrt(wg2**2+wp2**2/3) ! local w0 frequency at point 2
1130+ g1 = w01*r12**2 + kappa1 ! local g variable (eq.(3)) at point 1
1131+ g2 = w02*r12**2 + kappa2 ! local g variable at point 2
1132+ phi = -1.5_dp/g1/g2/(g1+g2) ! VV kernel phi (eq.(2))
1133+
1134+ if (kernelPrefactor=='rho') then
1135+ ! Return whole integrand of eq.(1)
1136+ sg4vv_vdw_phi_val = n1*n2*phi
1137+ else if (kernelPrefactor=='kf') then
1138+ ! Return kf1*kf2*phi
1139+ sg4vv_vdw_phi_val = kf1*kf2*phi
1140+ else if (kernelPrefactor=='kf2') then
1141+ ! Return (kf1*kf2)**2*phi
1142+ sg4vv_vdw_phi_val = (kf1*kf2)**2*phi
1143+ else if (kernelPrefactor=='sqr_rho') then
1144+ ! Find and return sqrt(n1*n2)*phi
1145+ sg4vv_vdw_phi_val = sqrt(n1*n2)*phi
1146+ else
1147+ call die('sg4vv_vdw_phi_val ERROR: unknown kernelPrefactor')
1148+ end if
1149+
1150+end function sg4vv_vdw_phi_val
1151+
1152+! -----------------------------------------------------------------------------
1153+
1154+real(dp) function sg4vv_vdw_beta()
1155+
1156+! Returns parameter beta of VV functional
1157+
1158+ implicit none
1159+ sg4vv_vdw_beta = vv_beta
1160+
1161+end function sg4vv_vdw_beta
1162+
1163+!-----------------------------------------------------------------------------
1164+
1165+subroutine sg4vv_vdw_get_kmesh( mkf, mkg, kf, kg )
1166+
1167+! Returns size and values of (kf,kg) mesh
1168+
1169+ implicit none
1170+ integer, intent(out) :: mkf ! Number of kf mesh points
1171+ integer, intent(out) :: mkg ! Number of kg mesh points
1172+ real(dp),optional,intent(out) :: kf(:) ! Values of kf mesh points
1173+ real(dp),optional,intent(out) :: kg(:) ! Values of kg mesh points
1174+ integer:: nmax
1175+ if (.not.kmesh_set) call set_kmesh()
1176+ mkf = nkf
1177+ mkg = nkg
1178+ if (present(kf)) then
1179+ nmax = max( nkf, size(kf) )
1180+ kf(1:nmax) = kfmesh(1:nmax)
1181+ end if
1182+ if (present(kg)) then
1183+ nmax = max( nkg, size(kg) )
1184+ kg(1:nmax) = kgmesh(1:nmax)
1185+ end if
1186+end subroutine sg4vv_vdw_get_kmesh
1187+
1188+! -----------------------------------------------------------------------------
1189+
1190+subroutine sg4vv_vdw_phi( k, phi, dphidk )
1191+
1192+! Finds by interpolation phi(k1,k2,k) (Fourier transform of phi(k1,k2,r)),
1193+! with k1=(kf1,kg1), k2=(kf2,kg2) for all mesh values of kf (Fermi
1194+! wavevector) and kg (grad(n)/n). If the interpolation table does not exist,
1195+! it is calculated in the first call to sg4vv_vdw_phi. It requires a previous
1196+! call to sg4vv_vdw_set_kc to set k mesh.
1197+
1198+ implicit none
1199+ real(dp),intent(in) :: k ! Modulus of actual k vector
1200+ real(dp),intent(out):: phi(:,:) ! phi(k1,k2,k) at given k
1201+ ! for all k1,k2 in (kf,kg) mesh
1202+ real(dp),intent(out):: dphidk(:,:) ! dphi(k1,k2,k)/dk at given k
1203+
1204+ integer :: ik, ik1, ik2
1205+ real(dp):: a, a2, a3, b, b2, b3
1206+
1207+! Set interpolation table
1208+ if (.not.phi_table_set) call set_phi_table()
1209+
1210+! Check argument sizes
1211+ if (size(phi,1)<nkfg .or. size(phi,2)<nkfg) &
1212+ call die('sg4vv_vdw_phi: ERROR: size(phi) too small')
1213+
1214+! Find phi values at point k
1215+ if (k >= kcut) then
1216+ phi(:,:) = 0
1217+ dphidk(:,:) = 0
1218+ else
1219+ ! Expand interpolation inline since this is the hottest point in VdW
1220+ ik = int(k/dk)
1221+ a = ((ik+1)*dk-k)/dk
1222+ b = 1 - a
1223+ a2 = (3*a**2 -1) * dk / 6
1224+ b2 = (3*b**2 -1) * dk / 6
1225+ a3 = (a**3 - a) * dk**2 / 6
1226+ b3 = (b**3 - b) * dk**2 / 6
1227+ do ik2 = 1,nkfg
1228+ do ik1 = 1,ik2
1229+! call splint( dk, phik(:,ik1,ik2), d2phidk2(:,ik1,ik2), &
1230+! nk+1, k, phi(ik1,ik2), dphidk(ik1,ik2), pr )
1231+ phi(ik1,ik2) = a*phik(ik,ik1,ik2) + b*phik(ik+1,ik1,ik2) &
1232+ + a3*d2phidk2(ik,ik1,ik2) + b3*d2phidk2(ik+1,ik1,ik2)
1233+ dphidk(ik1,ik2) = (-phik(ik,ik1,ik2) &
1234+ +phik(ik+1,ik1,ik2) )/dk &
1235+ - a2*d2phidk2(ik,ik1,ik2) + b2*d2phidk2(ik+1,ik1,ik2)
1236+ phi(ik2,ik1) = phi(ik1,ik2)
1237+ dphidk(ik2,ik1) = dphidk(ik1,ik2)
1238+ end do
1239+ end do
1240+ end if
1241+
1242+end subroutine sg4vv_vdw_phi
1243+
1244+!-----------------------------------------------------------------------------
1245+
1246+subroutine sg4vv_vdw_phiofr( r, phi )
1247+
1248+! Finds phi(k1,k2,r) with k1=(kf1,kg1), k2=(kf2,kg2) for mesh values of
1249+! kf's (Fermi wavevectors) and kg's (grad(n)/n)
1250+
1251+ implicit none
1252+ real(dp),intent(in) :: r
1253+ real(dp),intent(out):: phi(:,:)
1254+
1255+ integer :: ikf1, ikf2, ikg1, ikg2, ik1, ik2
1256+ real(dp):: dphidr
1257+
1258+ if (size(phi,1)<nkfg .or. size(phi,2)<nkfg) &
1259+ stop 'vv_phiofr: ERROR: size(phi) too small'
1260+ if (.not.phi_table_set) call set_phi_table()
1261+
1262+ if (r >= rcut) then
1263+ phi(:,:) = 0
1264+ else
1265+ do ik2 = 1,nkfg
1266+ do ik1 = 1,ik2
1267+ call splint( dr, phir(:,ik1,ik2), d2phidr2(:,ik1,ik2), &
1268+ nr+1, r, phi(ik1,ik2), dphidr )
1269+ phi(ik2,ik1) = phi(ik1,ik2)
1270+ end do ! ik1
1271+ end do ! ik2
1272+ end if ! (r>=rcut)
1273+
1274+end subroutine sg4vv_vdw_phiofr
1275+
1276+!-----------------------------------------------------------------------------
1277+
1278+subroutine sg4vv_vdw_set_kcut( kc )
1279+
1280+! Sets the reciprocal planewave cutoff kc of the integration grid, and finds
1281+! the interpolation table to be used by vdw_phi to obtain the vdW kernel phi
1282+! at the reciprocal mesh wavevectors.
1283+
1284+ implicit none
1285+ real(dp),intent(in):: kc ! Planewave cutoff: k>kcut => phi=0
1286+
1287+ real(dp):: pi
1288+
1289+ ! Set kcut and radial mesh parameters, if not already set
1290+ if (.not. kc==kcut) then
1291+ kcut = kc
1292+ pi = acos(-1._dp)
1293+ dr = rcut / nr
1294+ dk = pi / rcut
1295+ kmax = pi / dr
1296+ nk = int(kcut/dk) + 1
1297+ if (nk>nr) stop 'sg4vv_vdw_set_kcut: ERROR: nk>nr'
1298+ kcut_set = .true.
1299+#ifdef DEBUG_XC
1300+ write(udebug,'(a,5f8.3)') 'sg4vv_vdw_set_kcut: kfcut,kgcut,rcut,kcut,kmax=', &
1301+ kfcut, kgcut, rcut, kc, kmax
1302+#endif /* DEBUG_XC */
1303+ end if
1304+
1305+ ! Set (kf,kg) mesh and phi table
1306+ call set_kmesh()
1307+ call set_phi_table()
1308+
1309+end subroutine sg4vv_vdw_set_kcut
1310+
1311+!-----------------------------------------------------------------------------
1312+
1313+subroutine sg4vv_vdw_theta( nspin, rhos, grhos, theta, dtdrho, dtdgrho )
1314+
1315+! Finds the value and derivatives of theta_i(rho,grad_rho) of eq.(8)
1316+! of Roman-Soler PRL 2009. In practice, theta_i=p_i rather than rho*p_i,
1317+! beacuse p_i is used here to expand rho1*rho2*phi rather than only phi.
1318+
1319+ implicit none
1320+ integer, intent(in) :: nspin ! Number of spin components
1321+ real(dp),intent(in) :: rhos(nspin) ! Electron spin density
1322+ real(dp),intent(in) :: grhos(3,nspin) ! Spin density gradient
1323+ real(dp),intent(out):: theta(nkfg) ! Exp. polynomials at (kf,kg)
1324+ real(dp),intent(out):: dtdrho(nkfg,nspin) ! dtheta(ik)/drhos
1325+ real(dp),intent(out):: dtdgrho(3,nkfg,nspin) ! dtheta(ik)/dgrhos(ix)
1326+
1327+ integer :: is, ix, ns
1328+ real(dp):: rho, grho(3), dpdkf(nkfg), dpdkg(nkfg), dkfdrho, dkfdgrho(3), &
1329+ dkgdrho, dkgdgrho(3), kf, kg, p(nkfg)
1330+
1331+ ! Sum spin components of electron density
1332+ ns = min(nspin,2) ! num. of diagonal spin components (if noncollinear)
1333+ rho = sum(rhos(1:ns)) ! local electron density
1334+ grho = sum(grhos(:,1:ns),dim=2) ! local density gradient
1335+
1336+ ! If density is between threshold, return zero
1337+ if (rho<rhoMin) then
1338+ theta = 0
1339+ dtdrho = 0
1340+ dtdgrho = 0
1341+ return
1342+ end if
1343+
1344+ ! Find local Fermi and gradient wavevectors, and their derivatives
1345+ call kofn( rho, grho, kf, kg, dkfdrho, dkgdrho, dkfdgrho, dkgdgrho )
1346+
1347+ ! Find expansion polynomials of integrand kernel of nonlocal vdW energy
1348+ call pofk( kf, kg, p, dpdkf, dpdkg )
1349+
1350+ ! Find theta functions and their derivatives with respect to rho and grho
1351+ if (kernelPrefactor=='rho') then
1352+ ! This is the right code if sg4vv_vdw_phi_val returns rho1*rho2*phi
1353+ theta(1:nkfg) = p(1:nkfg)
1354+ do is = 1,ns
1355+ dtdrho(1:nkfg,is) = dpdkf(1:nkfg)*dkfdrho + dpdkg(1:nkfg)*dkgdrho
1356+ do ix = 1,3
1357+ dtdgrho(ix,1:nkfg,is) = dpdkf(1:nkfg)*dkfdgrho(ix) &
1358+ + dpdkg(1:nkfg)*dkgdgrho(ix)
1359+ end do
1360+ end do
1361+ else if (kernelPrefactor=='kf') then
1362+ ! This is the right code if sg4vv_vdw_phi_val returns kf1*kf2*phi
1363+ kf = max(kf,ktol)
1364+ theta(1:nkfg) = p(1:nkfg)*rho/kf
1365+ do is = 1,ns
1366+ dtdrho(1:nkfg,is) = (dpdkf(1:nkfg)*dkfdrho &
1367+ +dpdkg(1:nkfg)*dkgdrho)*rho/kf &
1368+ + p(1:nkfg)*(1/kf-rho/kf**2*dkfdrho)
1369+ do ix = 1,3
1370+ dtdgrho(ix,1:nkfg,is) = (dpdkf(1:nkfg)*dkfdgrho(ix) &
1371+ +dpdkg(1:nkfg)*dkgdgrho(ix))*rho/kf
1372+ end do
1373+ end do
1374+ else if (kernelPrefactor=='kf2') then
1375+ ! This is the right code if sg4vv_vdw_phi_val returns (kf1*kf2)**2*phi
1376+ kf = max(kf,ktol)
1377+ theta(1:nkfg) = p(1:nkfg)*rho/kf**2
1378+ do is = 1,ns
1379+ dtdrho(1:nkfg,is) = (dpdkf(1:nkfg)*dkfdrho &
1380+ +dpdkg(1:nkfg)*dkgdrho)*rho/kf**2 &
1381+ + p(1:nkfg)*(1/kf**2-2*rho/kf**3*dkfdrho)
1382+ do ix = 1,3
1383+ dtdgrho(ix,1:nkfg,is) = (dpdkf(1:nkfg)*dkfdgrho(ix) &
1384+ +dpdkg(1:nkfg)*dkgdgrho(ix))*rho/kf**2
1385+ end do
1386+ end do
1387+ else if (kernelPrefactor=='sqr_rho') then
1388+ ! This is the right code if sg4vv_vdw_phi_val returns sqrt(rho1*rho2)*phi
1389+ rho = max(rho,1.e-12_dp) ! to avoid division by zero
1390+ theta(1:nkfg) = p(1:nkfg) * sqrt(rho)
1391+ do is = 1,ns
1392+ dtdrho(1:nkfg,is) = ( dpdkf(1:nkfg)*dkfdrho &
1393+ + dpdkg(1:nkfg)*dkgdrho ) * sqrt(rho) &
1394+ + p(1:nkfg) * 0.5/sqrt(rho)
1395+ do ix = 1,3
1396+ dtdgrho(ix,1:nkfg,is) = dpdkf(1:nkfg)*dkfdgrho(ix) * sqrt(rho) &
1397+ + dpdkg(1:nkfg)*dkgdgrho(ix) * sqrt(rho)
1398+ end do
1399+ end do
1400+ else
1401+ call die('sg4vv_vdw_theta ERROR: unknown kernelPrefactor')
1402+ end if ! (kernelPrefactor=='rho')
1403+
1404+end subroutine sg4vv_vdw_theta
1405+
1406+END MODULE m_sg4vv_vdwxc
1407+
1408+!!!=============== PBE+VV10 ========================
1409+
1410+MODULE m_pbevv_vdwxc
1411+
1412+! Used module procedures
1413+ use sys, only: die ! Termination routine
1414+ use mesh1D, only: get_mesh ! Returns the mesh points
1415+ use m_radfft, only: radfft ! Radial fast Fourier transform
1416+ use alloc, only: re_alloc ! Re-allocation routine
1417+ use mesh1D, only: set_mesh ! Sets a 1D mesh
1418+ use interpolation,only: spline ! Sets spline interpolation
1419+ use interpolation,only: splint ! Calculates spline interpolation
1420+
1421+! Used module parameters
1422+ use precision, only: dp ! Real double precision type
1423+
1424+#ifdef DEBUG_XC
1425+ use debugXC, only: udebug ! File unit for debug output
1426+! use plot_module, only: plot
1427+#endif /* DEBUG_XC */
1428+
1429+ implicit none
1430+
1431+! Called by m_vdwxc
1432+PUBLIC :: &
1433+ pbevv_vdw_beta, &! Returns parameter beta of the VV2010 functional
1434+ pbevv_vdw_theta, &! Finds function theta_ik(rho,grad_rho)
1435+ pbevv_vdw_get_kmesh, &! Returns size and values of (kf,kg) mesh
1436+ pbevv_vdw_phi, &! Finds and interpolates rho1*rho2*phi(k1,k2,k)
1437+ pbevv_vdw_set_kcut ! Sets the planewave cutoff kc of the integration grid
1438+
1439+#ifdef DEBUG_XC
1440+! Called by debugging test programs
1441+PUBLIC :: &
1442+ pbevv_vdw_phi_val, &! Kernel phi(kf1,kf2,kg1,kg2,r12) with no interpolation
1443+ pbevv_vdw_phiofr ! Kernel phi(k1,k2,r) at tabulated k1,k2-mesh values
1444+#endif /* DEBUG_XC */
1445+
1446+PRIVATE ! Nothing is declared public beyond this point
1447+
1448+ ! Set parameters of the PBE+rVV10,
1449+ ! Ref. H. Peng and J. P. Perdew, Phys. Rev. B 95, 0811105 (2017)
1450+ real(dp),parameter:: vv_C = 0.0093
1451+ real(dp),parameter:: vv_b = 10.0
1452+ real(dp),parameter:: vv_beta = 0.00497
1453+
1454+ ! Mesh parameters for table of phi(k1,k2,r) and its Fourier transform
1455+ character(len=*),parameter:: kernelPrefactor='rho' ! Prefactor of the
1456+ ! nonlocal kernel for interpolation
1457+ ! ('kf'|'kf2'|'sqr_rho'|'rho')
1458+ integer, parameter:: nr = 2048 ! Radial mesh points (power of 2)
1459+ real(dp),parameter:: rcut = 100._dp ! Radial cutoff: r>rcut => phi=0
1460+ real(dp),parameter:: rmin = 1.e-6_dp ! Min. radius as denominator
1461+ integer, parameter:: nkf = 7 ! Number of Fermi wavevectors
1462+ integer, parameter:: nkg = 5 ! Num. of grad(n)/n wavevectors
1463+ integer, parameter:: nkfg = nkf*nkg ! Num. of (kf,kg) mesh points
1464+ real(dp),parameter:: kfcut = 5.0_dp ! Max. Fermi wavevec.
1465+ real(dp),parameter:: kgcut = 5.0_dp ! Max. grad(n)/n
1466+ real(dp),parameter:: dkfmaxdkfmin = 20.0_dp ! Last/first kf mesh interval
1467+ real(dp),parameter:: dkgmaxdkgmin = 2.0_dp ! Last/first kg mesh interval
1468+ real(dp),parameter:: ktol = 1.e-12_dp ! 'out of range' tolerance
1469+ real(dp),parameter:: amin = 1.e-12_dp ! tiny denominator to avoid /0
1470+ real(dp),parameter:: rhoMin = 1.e-10_dp ! Min. density for nonzero Vxc
1471+
1472+ ! Parameters for cutoff function, used in radial Fourier transforms of phi
1473+ integer, parameter:: ncut1 = 8 ! cutoff(x)=(1-x**ncut1)**ncut2
1474+ integer, parameter:: ncut2 = 4
1475+
1476+ ! Parameters for saturate function, used to enforce that q<qcut
1477+ integer, parameter:: nsat = 15 ! h(x,xc)=1/(1/x**nsat+1/xc**nsat)**(1/nsat)
1478+ ! nsat=15 approximately corresponds to
1479+ ! nsat=12 for eq.(5) of Roman-Soler PRL
1480+
1481+ ! Private module variables and arrays
1482+ logical, save:: kcut_set=.false. ! Has kcut been set?
1483+ logical, save:: kmesh_set=.false. ! Has (kf,kg) mesh been set?
1484+ logical, save:: phi_table_set=.false. ! Has phi_table been set?
1485+ integer, save:: nk ! Num. of radial mesh k-points
1486+ real(dp),save:: dr ! r-mesh interval
1487+ real(dp),save:: dk ! k-mesh interval
1488+ real(dp),save:: kcut ! Planewave cutoff: k>kcut => phi=0
1489+ real(dp),save:: kmax ! Max. k vector in Fourier transforms
1490+ real(dp),save:: kfmesh(nkf) ! Mesh points for Fermi wavevector
1491+ real(dp),save:: kgmesh(nkg) ! Mesh points for grad(n)/n
1492+ real(dp),pointer,save:: &
1493+ phir(:,:,:)=>null(), &! Table of phi(r)
1494+ phik(:,:,:)=>null(), &! Table of phi(k)
1495+ d2phidr2(:,:,:)=>null(),&! Table of d^2(phi)/dr^2
1496+ d2phidk2(:,:,:)=>null() ! Table of d^2(phi)/dk^2
1497+
1498+CONTAINS
1499+
1500+! -----------------------------------------------------------------------------
1501+
1502+real(dp) function cutoff( x )
1503+
1504+! Defines a smooth cutoff function that falls from y(0)=1 to y(1)=0
1505+
1506+ implicit none
1507+ real(dp),intent(in):: x
1508+
1509+ if (x<=0._dp) then
1510+ cutoff = 1
1511+ else if (x>=1._dp) then
1512+ cutoff = 0
1513+ else
1514+ cutoff = (1-x**ncut1)**ncut2
1515+ end if
1516+
1517+end function cutoff
1518+
1519+!-----------------------------------------------------------------------------
1520+
1521+subroutine iofk( kf, kg, ikf, ikg )
1522+
1523+! Finds indexes ikf and ikg such that kfmesh(ikf) <= kf < kfmesh(ikf+1)
1524+! and kgmesh(ikg) <= kg < kgmesh(ikg+1) in logarithmic meshes of the form
1525+! k(ik) = b*(exp((ik-1)*a)-1)
1526+
1527+ implicit none
1528+ real(dp), intent(in) :: kf, kg
1529+ integer, intent(out):: ikf, ikg
1530+
1531+ real(dp),save:: akf, akg, bkf, bkg
1532+ logical, save:: first_call = .true.
1533+ integer:: ik
1534+
1535+ ! Mesh data initializations
1536+ if (first_call) then
1537+ ! Find logarithmic-mesh a & b parameters: x(j)=x(1)+b*(exp(a*(j-1))-1)
1538+ akf = log( (kfmesh(nkf)-kfmesh(nkf-1)) / (kfmesh(2)-kfmesh(1)) ) / (nkf-2)
1539+ akg = log( (kgmesh(nkg)-kgmesh(nkg-1)) / (kgmesh(2)-kgmesh(1)) ) / (nkg-2)
1540+ akf = max( akf, amin )
1541+ akg = max( akg, amin )
1542+ bkf = (kfmesh(nkf) - kfmesh(1)) / (exp(akf*(nkf-1)) - 1)
1543+ bkg = (kgmesh(nkg) - kgmesh(1)) / (exp(akg*(nkg-1)) - 1)
1544+ ! Check that meshes are indeed logarithmic
1545+ do ik = 1,nkf
1546+ if (abs(kfmesh(ik)-kfmesh(1)-bkf*(exp(akf*(ik-1))-1))>ktol) &
1547+ call die('pbevv_vdw_iofk ERROR: kfmesh not logarithmic')
1548+ end do
1549+ do ik = 1,nkg
1550+ if (abs(kgmesh(ik)-kgmesh(1)-bkg*(exp(akg*(ik-1))-1))>ktol) &
1551+ call die('pbevv_vdw_iofk ERROR: kgmesh not logarithmic')
1552+ end do
1553+ first_call = .false.
1554+ end if
1555+
1556+ ! Check that kf and kg are within interpolation range
1557+ if (kf<kfmesh(1)-ktol .or. kf>kfmesh(nkf)+ktol .or. &
1558+ kg<kgmesh(1)-ktol .or. kg>kgmesh(nkg)+ktol) then
1559+ call die('pbevv_vdw_iofk ERROR: (kf,kg) out of range')
1560+ endif
1561+
1562+ ! Find interpolation mesh intervals
1563+ ikf = 1 + int( log( 1 + (kf-kfmesh(1))/bkf ) / akf )
1564+ ikg = 1 + int( log( 1 + (kg-kgmesh(1))/bkg ) / akg )
1565+ ikf = max( 1, ikf )
1566+ ikg = max( 1, ikg )
1567+ ikf = min( nkf-1, ikf )
1568+ ikg = min( nkg-1, ikg )
1569+
1570+end subroutine iofk
1571+
1572+! -----------------------------------------------------------------------------
1573+
1574+subroutine kofn( n, gn, kf, kg, dkfdn, dkgdn, dkfdgn, dkgdgn )
1575+
1576+! Finds Fermi and gradient wavevectors from density and gradient
1577+
1578+ implicit none
1579+ real(dp), intent(in) :: n ! Electron density
1580+ real(dp), intent(in) :: gn(3) ! Density gradient
1581+ real(dp), intent(out):: kf ! Local Fermi wavevector
1582+ real(dp), intent(out):: kg ! |grad(n)|/n
1583+ real(dp), intent(out):: dkfdn ! dkf/dn
1584+ real(dp), intent(out):: dkgdn ! dkg/dn
1585+ real(dp), intent(out):: dkfdgn(3) ! dkf/dgn
1586+ real(dp), intent(out):: dkgdgn(3) ! dkg/dgn
1587+
1588+ real(dp):: gn2, pi
1589+
1590+! Trap exception for zero density
1591+ if (n <= 1.e-30_dp) then
1592+ kf = 0
1593+ kg = 0
1594+ dkfdn = 0
1595+ dkfdgn = 0
1596+ dkgdn = 0
1597+ dkgdgn = 0
1598+ return
1599+ end if
1600+
1601+! Find kf and kg
1602+ pi = acos(-1._dp)
1603+ kf = (3*pi**2*n)**(1._dp/3)
1604+ gn2 = sum(gn**2)
1605+ kg = sqrt(gn2)/n
1606+
1607+! Find derivatives
1608+ dkfdn = kf/n/3
1609+ dkfdgn = 0
1610+ dkgdn = -kg/n
1611+ dkgdgn = kg*gn/gn2
1612+
1613+end subroutine kofn
1614+
1615+!-----------------------------------------------------------------------------
1616+
1617+subroutine pofk( kf, kg, p, dpdkf, dpdkg )
1618+
1619+! Finds the values and derivatives, at (kf,kg), of the bicubic polynomials
1620+! p_i(kf,kg) such that
1621+! y(kf,kg) = Sum_i p_i(kf,kg) * y_i
1622+! is the bicubic spline interpolation at (kf,kg) of (any) function y with
1623+! values y_i at mesh points (kfmesh,kgmesh)_i
1624+
1625+ implicit none
1626+ real(dp),intent(in) :: kf, kg ! point at which the polynomials are required
1627+ real(dp),intent(out):: p(nkfg) ! polynomial values at (kf,kg)
1628+ real(dp),intent(out):: dpdkf(nkfg) ! dp/dkf at (kf,kg)
1629+ real(dp),intent(out):: dpdkg(nkfg) ! dp/dkg at (kf,kg)
1630+
1631+ integer :: ikf, ikg, ikfg, ikf0, ikg0
1632+ real(dp):: a, b, dk, dkf0dkf, dkg0dkg, kf0, kg0
1633+ real(dp):: pkf0(nkf), dpkfdkf0(nkf), pkg0(nkg), dpkgdkg0(nkg)
1634+ logical, save :: first_call=.true.
1635+ real(dp),save :: pkf(nkf,nkf), d2pkfdkf2(nkf,nkf)
1636+ real(dp),save :: pkg(nkg,nkg), d2pkgdkg2(nkg,nkg)
1637+
1638+! Set up spline polynomial basis
1639+ if (first_call) then
1640+ do ikf = 1,nkf
1641+ pkf(:,ikf) = 0 ! ikf'th polynomial pkf(:,ikf) is one at kfmesh(ikf)
1642+ pkf(ikf,ikf) = 1 ! and zero at all other points
1643+ call spline( kfmesh, pkf(:,ikf), nkf, 1.e30_dp, 1.e30_dp, &
1644+ d2pkfdkf2(:,ikf) )
1645+! call spline( kfmesh, pkf(:,ikf), nkf, 0._dp, 0._dp, d2pkfdkf2(:,ikf) )
1646+ end do
1647+ do ikg = 1,nkg
1648+ pkg(:,ikg) = 0
1649+ pkg(ikg,ikg) = 1
1650+ call spline( kgmesh, pkg(:,ikg), nkg, 1.e30_dp, 1.e30_dp, &
1651+ d2pkgdkg2(:,ikg) )
1652+! call spline( kgmesh, pkg(:,ikg), nkg, 0._dp, 0._dp, d2pkgdkg2(:,ikg) )
1653+ end do
1654+
1655+! DEBUG
1656+ open(22,file='pkf.dat')
1657+ do ikf = 1,nkf
1658+ write(22,'(20e15.6)') kfmesh(ikf), pkf(:,ikf), d2pkfdkf2(:,ikf)
1659+ end do
1660+ close(22)
1661+ open(22,file='pkg.dat')
1662+ do ikg = 1,nkg
1663+ write(22,'(20e15.6)') kgmesh(ikg), pkg(:,ikg), d2pkgdkg2(:,ikg)
1664+ end do
1665+ close(22)
1666+! END DEBUG
1667+
1668+ first_call = .false.
1669+ end if
1670+
1671+! 'Saturate' (kf,kg) values to bring them to interpolation range
1672+ call saturate( kf, kfcut, kf0, dkf0dkf )
1673+ call saturate( kg, kgcut, kg0, dkg0dkg )
1674+
1675+! Find interval of k mesh in which (kf0,kg0) point is included
1676+ call iofk( kf0, kg0, ikf0, ikg0 )
1677+
1678+! Evaluate pkf polynomials of spline basis at kf0
1679+! The splint code is in-lined here because it is a hot point
1680+ dk = kfmesh(ikf0+1) - kfmesh(ikf0)
1681+ a = (kfmesh(ikf0+1) - kf0) / dk ! dadkf0 = -1/dk
1682+ b = (kf0 - kfmesh(ikf0)) / dk ! dbdkf0 = +1/dk
1683+ do ikf = 1,nkf
1684+ pkf0(ikf) = a*pkf(ikf0,ikf) + b*pkf(ikf0+1,ikf) &
1685+ + ((a**3-a)*d2pkfdkf2(ikf0,ikf) + &
1686+ (b**3-b)*d2pkfdkf2(ikf0+1,ikf)) * dk**2/6
1687+ dpkfdkf0(ikf) = - (pkf(ikf0,ikf) - pkf(ikf0+1,ikf)) / dk &
1688+ - ((3*a**2-1)*d2pkfdkf2(ikf0,ikf) - &
1689+ (3*b**2-1)*d2pkfdkf2(ikf0+1,ikf)) * dk/6
1690+ end do
1691+
1692+! Evaluate pkg polynomials of spline basis at kg0
1693+ dk = kgmesh(ikg0+1) - kgmesh(ikg0)
1694+ a = (kgmesh(ikg0+1) - kg0) / dk ! dadkg0 = -1/dk
1695+ b = (kg0 - kgmesh(ikg0)) / dk ! dbdkg0 = +1/dk
1696+ do ikg = 1,nkg
1697+ pkg0(ikg) = a*pkg(ikg0,ikg) + b*pkg(ikg0+1,ikg) &
1698+ + ((a**3-a)*d2pkgdkg2(ikg0,ikg) + &
1699+ (b**3-b)*d2pkgdkg2(ikg0+1,ikg)) * dk**2/6
1700+ dpkgdkg0(ikg) = - (pkg(ikg0,ikg) - pkg(ikg0+1,ikg)) / dk &
1701+ - ((3*a**2-1)*d2pkgdkg2(ikg0,ikg) - &
1702+ (3*b**2-1)*d2pkgdkg2(ikg0+1,ikg)) * dk/6
1703+ end do
1704+
1705+! Evaluate pkf*pkg polynomials at (kf0,kg0)
1706+ ikfg = 0
1707+ do ikg = 1,nkg
1708+ do ikf = 1,nkf
1709+ ikfg = ikfg+1
1710+ p(ikfg) = pkf0(ikf) * pkg0(ikg)
1711+ dpdkf(ikfg) = dpkfdkf0(ikf)*dkf0dkf * pkg0(ikg)
1712+ dpdkg(ikfg) = pkf0(ikf) * dpkgdkg0(ikg)*dkg0dkg
1713+ end do
1714+ end do
1715+
1716+end subroutine pofk
1717+
1718+!-----------------------------------------------------------------------------
1719+
1720+subroutine saturate( x, xc, y, dydx )
1721+
1722+ ! Defines a function y(x,xc) = 1/(1/x^nsat+1/xc^nsat)^(1/nsat), where nsat
1723+ ! is an integer set in the module header. This function is approximately
1724+ ! equal to x for x<xc and it saturates to xc when x->infinity
1725+
1726+ implicit none
1727+ real(dp),intent(in) :: x ! Independent variable
1728+ real(dp),intent(in) :: xc ! Saturation value
1729+ real(dp),intent(out):: y ! Function value
1730+ real(dp),intent(out):: dydx ! Derivative dy/dx
1731+
1732+ real(dp):: z
1733+
1734+ if (xc<=0._dp) then
1735+ call die('pbevv_vdwxc_saturate ERROR: xc<=0')
1736+ else if (x<0._dp) then
1737+ call die('pbevv_vdwxc_saturate ERROR: x<0')
1738+ else if (x==0._dp) then
1739+ y = 0
1740+ dydx = 1
1741+ else
1742+ z = 1/x**nsat + 1/xc**nsat
1743+ y = 1/z**(1._dp/nsat)
1744+ dydx = y/z/x**(nsat+1)
1745+ end if
1746+
1747+end subroutine saturate
1748+
1749+!-----------------------------------------------------------------------------
1750+
1751+subroutine saturate_inverse( y, xc, x, dxdy )
1752+
1753+! Finds the inverse of the function defined in saturate subroutine:
1754+! y=1/(1/x^n+1/xc^n)^(1/n) => x=1/(1/y^n-1/xc^n)^(1/n)
1755+
1756+ implicit none
1757+ real(dp),intent(in) :: y ! Independent variable
1758+ real(dp),intent(in) :: xc ! Saturation value
1759+ real(dp),intent(out):: x ! Inverse function value
1760+ real(dp),intent(out):: dxdy ! Derivative dx/dy
1761+
1762+ real(dp):: z
1763+
1764+ if (xc<=0._dp) then
1765+ call die('pbevv_vdwxc_saturate_inverse ERROR: xc<=0')
1766+ else if (y<0._dp .or. y>=xc) then
1767+ call die('pbevv_vdwxc_saturate_inverse ERROR: y out of range')
1768+ else if (y==0._dp) then
1769+ x = 0
1770+ dxdy = 1
1771+ else
1772+ z = 1/y**nsat - 1/xc**nsat
1773+ x = 1/z**(1._dp/nsat)
1774+ dxdy = x/z/y**(nsat+1)
1775+ end if
1776+
1777+end subroutine saturate_inverse
1778+
1779+!-----------------------------------------------------------------------------
1780+
1781+subroutine set_kmesh()
1782+
1783+! Sets mesh of q values
1784+
1785+ implicit none
1786+ integer :: mkf, mkg
1787+
1788+ if (.not.kmesh_set) then
1789+ call set_mesh( nkf, xmax=kfcut, dxndx1=dkfmaxdkfmin )
1790+ call get_mesh( nkf, mkf, kfmesh )
1791+ call set_mesh( nkg, xmax=kgcut, dxndx1=dkgmaxdkgmin )
1792+ call get_mesh( nkg, mkg, kgmesh )
1793+ kmesh_set = .true.
1794+#ifdef DEBUG_XC
1795+ write(udebug,'(/,a,/,(10f8.4))') 'pbevv_vdw_set_kmesh: kfmesh =', kfmesh
1796+ write(udebug,'(/,a,/,(10f8.4))') 'pbevv_vdw_set_kmesh: kgmesh =', kgmesh
1797+#endif /* DEBUG_XC */
1798+ end if
1799+
1800+end subroutine set_kmesh
1801+
1802+! -----------------------------------------------------------------------------
1803+
1804+subroutine set_phi_table()
1805+
1806+! Finds and stores in memory the interpolation table (mesh points and
1807+! function values) for the kernel phi(k1,k2,k).
1808+
1809+ implicit none
1810+ character(len=*),parameter:: myName = 'pbevv_vdwxc/set_phi_table '
1811+ integer :: ik, ikf1, ikf2, ikg1, ikg2, ik1, ik2, ir
1812+ real(dp):: dkdk0, dphidk0, dphidkmax, dphidr0, dphidrmax, &
1813+ k, kf1, kf2, kg1, kg2, pi, r(0:nr)
1814+
1815+! Check that table was not set yet
1816+ if (phi_table_set) return
1817+
1818+! Check that kf, kg, r, and k meshes have been set
1819+ if (.not.kmesh_set) call set_kmesh()
1820+ if (.not.kcut_set) call die('pbevv_vdw_set_phi_table ERROR: kcut not set')
1821+ forall(ir=0:nr) r(ir) = ir*dr
1822+ pi = acos(-1.0_dp)
1823+
1824+! Allocate arrays
1825+ call re_alloc( phir, 0,nr, 1,nkfg, 1,nkfg, myName//'phir' )
1826+ call re_alloc( phik, 0,nr, 1,nkfg, 1,nkfg, myName//'phik' )
1827+ call re_alloc( d2phidr2, 0,nr, 1,nkfg, 1,nkfg, myName//'d2phidr2' )
1828+ call re_alloc( d2phidk2, 0,nr, 1,nkfg, 1,nkfg, myName//'d2phidk2' )
1829+
1830+! Loop on (k1,k2) mesh points
1831+ do ikg2 = 1,nkg ! loop on kg2
1832+ do ikf2 = 1,nkf ! loop on kf2
1833+ ik2 = ikf2 + nkf*(ikg2-1) ! combined (ikf2,ikg2) index
1834+ do ikg1 = 1,nkg ! loop on kg1
1835+ do ikf1 = 1,nkf ! loop on kf1
1836+ ik1 = ikf1 + nkf*(ikg1-1) ! combined (ikf1,ikg1) index
1837+ if (ik1>ik2) cycle ! since we will symmetrize at the end
1838+
1839+ ! Saturated (kf,kg) values
1840+ kf1 = kfmesh(ikf1)
1841+ kf2 = kfmesh(ikf2)
1842+ kg1 = kgmesh(ikg1)
1843+ kg2 = kgmesh(ikg2)
1844+
1845+ ! Find original (unsaturated) kf anf kg values
1846+ ! call saturate_inverse( kfmesh(ikf1), kfcut, kf1, dkdk0 )
1847+ ! call saturate_inverse( kfmesh(ikf2), kfcut, kf2, dkdk0 )
1848+ ! call saturate_inverse( kgmesh(ikg1), kgcut, kg1, dkdk0 )
1849+ ! call saturate_inverse( kgmesh(ikg2), kgcut, kg2, dkdk0 )
1850+
1851+ ! Find kernel as a function of r12
1852+ do ir = 0,nr
1853+ phir(ir,ik1,ik2) = pbevv_vdw_phi_val( kf1, kf2, kg1, kg2, r(ir) )
1854+ end do
1855+
1856+ ! Kill kernel smoothly at r=rcut
1857+ do ir = 0,nr
1858+ phir(ir,ik1,ik2) = phir(ir,ik1,ik2) * cutoff( r(ir)/rcut )
1859+ end do
1860+
1861+ ! Find kernel in reciprocal space
1862+ call radfft( 0, nr, rcut, phir(:,ik1,ik2), phik(:,ik1,ik2) )
1863+ phik(:,ik1,ik2) = phik(:,ik1,ik2) * (2*pi)**1.5_dp
1864+
1865+ ! Filter out above kcut
1866+ phik(nk:nr,ik1,ik2) = 0
1867+
1868+ ! Soft filter below kcut
1869+ do ik = 1,nk
1870+ k = ik * dk
1871+ phik(ik,ik1,ik2) = phik(ik,ik1,ik2) * cutoff(k/kcut)
1872+ end do
1873+
1874+ ! Find filtered kernel in real space
1875+ call radfft( 0, nr, kmax, phik(:,ik1,ik2), phir(:,ik1,ik2) )
1876+ phir(:,ik1,ik2) = phir(:,ik1,ik2) / (2*pi)**1.5_dp
1877+
1878+ ! Set up spline interpolation tables
1879+ dphidr0 = 0 ! since phi(k1,k2,r) is even in r
1880+ dphidk0 = 0 ! and therefore phi(k1,k2,k) is also even in k
1881+ dphidrmax = 0 ! since phi->0 for r->infty
1882+ dphidkmax = 0 ! and also when k->infty
1883+ call spline( dr, phir(:,ik1,ik2), nr+1, dphidr0, dphidrmax, &
1884+ d2phidr2(:,ik1,ik2) )
1885+ call spline( dk, phik(:,ik1,ik2), nk+1, dphidk0, dphidkmax, &
1886+ d2phidk2(:,ik1,ik2) )
1887+
1888+ ! Fill symmetric elements
1889+ phir(:,ik2,ik1) = phir(:,ik1,ik2)
1890+ phik(:,ik2,ik1) = phik(:,ik1,ik2)
1891+ d2phidr2(:,ik2,ik1) = d2phidr2(:,ik1,ik2)
1892+ d2phidk2(:,ik2,ik1) = d2phidk2(:,ik1,ik2)
1893+
1894+!#ifdef DEBUG_XC
1895+! if (.false. .and. ik1==ik2) then
1896+! print*, 'pbevv_vdw_set_kcut: ik1,ik2=', ik1, ik2
1897+! call window( 0._dp, 5._dp, -1._dp, 4._dp, 0 )
1898+! call axes( 0._dp, 1._dp, 0._dp, 1._dp )
1899+! call plot( nr+1, r, phi, phir(:,ik1,ik2) )
1900+! call window( 0._dp, 10._dp, -0.05_dp, 0.15_dp, 0 )
1901+! call axes( 0._dp, 1._dp, 0._dp, 0.05_dp )
1902+! call plot( nr+1, r, r**2*phi, r**2*phir(:,ik1,ik2))
1903+! call show()
1904+! end if
1905+!#endif /* DEBUG_XC */
1906+
1907+ end do ! ikf1
1908+ end do ! ikg1
1909+ end do ! ikf2
1910+ end do ! ikg2
1911+
1912+!#ifdef DEBUG_XC
1913+! open(17,file='vv_phi.table')
1914+! write(17,'(3a6,2a12,/,(3i6,2f15.9))') &
1915+! 'ik1', 'ik2', 'ir', 'phi', 'd2phi/dk2', &
1916+!! (((ik1,ik2,ir,phir(ir,ik1,ik2),d2phidr2(ir,ik1,ik2), &
1917+! (((ik1,ik2,ir,phik(ir,ik1,ik2),d2phidk2(ir,ik1,ik2), &
1918+! ir=0,100),ik2=1,nkfg),ik1=1,nkfg)
1919+! close(17)
1920+!#endif /* DEBUG_XC */
1921+
1922+! Mark table as set
1923+ phi_table_set = .true.
1924+
1925+end subroutine set_phi_table
1926+
1927+! -----------------------------------------------------------------------------
1928+
1929+real(dp) function pbevv_vdw_phi_val( kf1, kf2, kg1, kg2, r12 )
1930+
1931+! vdW energy kernel of Vydrov-vanVoorhis, eq.(2) of JCP 133, 244103 (2010)
1932+! This subroutine calculates the 'raw' kernel directly, without interpolarions
1933+! In practice, it returns n1*n2*phi(k1,k2,r12), which is smooth for kf->0
1934+! Input:
1935+! real(dp):: kf1, kf2 ! Fermi wavevectors at points 1 and 2
1936+! real(dp):: kg1, kg2 ! |grad(n)|/n at points 1 and 2
1937+! real(dp):: r12 ! distance between points 1 and 2
1938+
1939+! Arguments
1940+ implicit none
1941+ real(dp),intent(in) :: kf1, kf2, kg1, kg2, r12
1942+
1943+! Internal variables
1944+ real(dp):: g1, g2, kappa1, kappa2, kf1m, kf2m, n1, n2, &
1945+ phi, pi, w01, w02, wg1, wg2, wp1, wp2
1946+
1947+! Avoid dividing by zero when kf=0
1948+ kf1m = max(kf1,ktol)
1949+ kf2m = max(kf2,ktol)
1950+
1951+! Find kernel
1952+ pi = acos(-1.0_dp)
1953+ n1 = kf1m**3/(3*pi**2) ! electron density at point 1
1954+ n2 = kf2m**3/(3*pi**2) ! electron density at point 2
1955+ wp1 = sqrt(4*pi*n1) ! local plasma frequency at point 1
1956+ wp2 = sqrt(4*pi*n2) ! local plasma frequency at point 2
1957+ wg1 = sqrt(vv_C*kg1**4) ! local band gap at point 1
1958+ wg2 = sqrt(vv_C*kg2**4) ! local band gap at point 2
1959+ kappa1 = vv_b*kf1m**2/wp1 ! local VV kappa variable (eq.(9)) at point 1
1960+ kappa2 = vv_b*kf2m**2/wp2 ! kappa variable at point 2
1961+ w01 = sqrt(wg1**2+wp1**2/3) ! local w0 frequency (eq.(5)) at point 1
1962+ w02 = sqrt(wg2**2+wp2**2/3) ! local w0 frequency at point 2
1963+ g1 = w01*r12**2 + kappa1 ! local g variable (eq.(3)) at point 1
1964+ g2 = w02*r12**2 + kappa2 ! local g variable at point 2
1965+ phi = -1.5_dp/g1/g2/(g1+g2) ! VV kernel phi (eq.(2))
1966+
1967+ if (kernelPrefactor=='rho') then
1968+ ! Return whole integrand of eq.(1)
1969+ pbevv_vdw_phi_val = n1*n2*phi
1970+ else if (kernelPrefactor=='kf') then
1971+ ! Return kf1*kf2*phi
1972+ pbevv_vdw_phi_val = kf1*kf2*phi
1973+ else if (kernelPrefactor=='kf2') then
1974+ ! Return (kf1*kf2)**2*phi
1975+ pbevv_vdw_phi_val = (kf1*kf2)**2*phi
1976+ else if (kernelPrefactor=='sqr_rho') then
1977+ ! Find and return sqrt(n1*n2)*phi
1978+ pbevv_vdw_phi_val = sqrt(n1*n2)*phi
1979+ else
1980+ call die('pbevv_vdw_phi_val ERROR: unknown kernelPrefactor')
1981+ end if
1982+
1983+end function pbevv_vdw_phi_val
1984+
1985+! -----------------------------------------------------------------------------
1986+
1987+real(dp) function pbevv_vdw_beta()
1988+
1989+! Returns parameter beta of VV functional
1990+
1991+ implicit none
1992+ pbevv_vdw_beta = vv_beta
1993+
1994+end function pbevv_vdw_beta
1995+
1996+!-----------------------------------------------------------------------------
1997+
1998+subroutine pbevv_vdw_get_kmesh( mkf, mkg, kf, kg )
1999+
2000+! Returns size and values of (kf,kg) mesh
2001+
2002+ implicit none
2003+ integer, intent(out) :: mkf ! Number of kf mesh points
2004+ integer, intent(out) :: mkg ! Number of kg mesh points
2005+ real(dp),optional,intent(out) :: kf(:) ! Values of kf mesh points
2006+ real(dp),optional,intent(out) :: kg(:) ! Values of kg mesh points
2007+ integer:: nmax
2008+ if (.not.kmesh_set) call set_kmesh()
2009+ mkf = nkf
2010+ mkg = nkg
2011+ if (present(kf)) then
2012+ nmax = max( nkf, size(kf) )
2013+ kf(1:nmax) = kfmesh(1:nmax)
2014+ end if
2015+ if (present(kg)) then
2016+ nmax = max( nkg, size(kg) )
2017+ kg(1:nmax) = kgmesh(1:nmax)
2018+ end if
2019+end subroutine pbevv_vdw_get_kmesh
2020+
2021+! -----------------------------------------------------------------------------
2022+
2023+subroutine pbevv_vdw_phi( k, phi, dphidk )
2024+
2025+! Finds by interpolation phi(k1,k2,k) (Fourier transform of phi(k1,k2,r)),
2026+! with k1=(kf1,kg1), k2=(kf2,kg2) for all mesh values of kf (Fermi
2027+! wavevector) and kg (grad(n)/n). If the interpolation table does not exist,
2028+! it is calculated in the first call to pbevv_vdw_phi. It requires a previous
2029+! call to pbevv_vdw_set_kc to set k mesh.
2030+
2031+ implicit none
2032+ real(dp),intent(in) :: k ! Modulus of actual k vector
2033+ real(dp),intent(out):: phi(:,:) ! phi(k1,k2,k) at given k
2034+ ! for all k1,k2 in (kf,kg) mesh
2035+ real(dp),intent(out):: dphidk(:,:) ! dphi(k1,k2,k)/dk at given k
2036+
2037+ integer :: ik, ik1, ik2
2038+ real(dp):: a, a2, a3, b, b2, b3
2039+
2040+! Set interpolation table
2041+ if (.not.phi_table_set) call set_phi_table()
2042+
2043+! Check argument sizes
2044+ if (size(phi,1)<nkfg .or. size(phi,2)<nkfg) &
2045+ call die('pbevv_vdw_phi: ERROR: size(phi) too small')
2046+
2047+! Find phi values at point k
2048+ if (k >= kcut) then
2049+ phi(:,:) = 0
2050+ dphidk(:,:) = 0
2051+ else
2052+ ! Expand interpolation inline since this is the hottest point in VdW
2053+ ik = int(k/dk)
2054+ a = ((ik+1)*dk-k)/dk
2055+ b = 1 - a
2056+ a2 = (3*a**2 -1) * dk / 6
2057+ b2 = (3*b**2 -1) * dk / 6
2058+ a3 = (a**3 - a) * dk**2 / 6
2059+ b3 = (b**3 - b) * dk**2 / 6
2060+ do ik2 = 1,nkfg
2061+ do ik1 = 1,ik2
2062+! call splint( dk, phik(:,ik1,ik2), d2phidk2(:,ik1,ik2), &
2063+! nk+1, k, phi(ik1,ik2), dphidk(ik1,ik2), pr )
2064+ phi(ik1,ik2) = a*phik(ik,ik1,ik2) + b*phik(ik+1,ik1,ik2) &
2065+ + a3*d2phidk2(ik,ik1,ik2) + b3*d2phidk2(ik+1,ik1,ik2)
2066+ dphidk(ik1,ik2) = (-phik(ik,ik1,ik2) &
2067+ +phik(ik+1,ik1,ik2) )/dk &
2068+ - a2*d2phidk2(ik,ik1,ik2) + b2*d2phidk2(ik+1,ik1,ik2)
2069+ phi(ik2,ik1) = phi(ik1,ik2)
2070+ dphidk(ik2,ik1) = dphidk(ik1,ik2)
2071+ end do
2072+ end do
2073+ end if
2074+
2075+end subroutine pbevv_vdw_phi
2076+
2077+!-----------------------------------------------------------------------------
2078+
2079+subroutine pbevv_vdw_phiofr( r, phi )
2080+
2081+! Finds phi(k1,k2,r) with k1=(kf1,kg1), k2=(kf2,kg2) for mesh values of
2082+! kf's (Fermi wavevectors) and kg's (grad(n)/n)
2083+
2084+ implicit none
2085+ real(dp),intent(in) :: r
2086+ real(dp),intent(out):: phi(:,:)
2087+
2088+ integer :: ikf1, ikf2, ikg1, ikg2, ik1, ik2
2089+ real(dp):: dphidr
2090+
2091+ if (size(phi,1)<nkfg .or. size(phi,2)<nkfg) &
2092+ stop 'vv_phiofr: ERROR: size(phi) too small'
2093+ if (.not.phi_table_set) call set_phi_table()
2094+
2095+ if (r >= rcut) then
2096+ phi(:,:) = 0
2097+ else
2098+ do ik2 = 1,nkfg
2099+ do ik1 = 1,ik2
2100+ call splint( dr, phir(:,ik1,ik2), d2phidr2(:,ik1,ik2), &
2101+ nr+1, r, phi(ik1,ik2), dphidr )
2102+ phi(ik2,ik1) = phi(ik1,ik2)
2103+ end do ! ik1
2104+ end do ! ik2
2105+ end if ! (r>=rcut)
2106+
2107+end subroutine pbevv_vdw_phiofr
2108+
2109+!-----------------------------------------------------------------------------
2110+
2111+subroutine pbevv_vdw_set_kcut( kc )
2112+
2113+! Sets the reciprocal planewave cutoff kc of the integration grid, and finds
2114+! the interpolation table to be used by vdw_phi to obtain the vdW kernel phi
2115+! at the reciprocal mesh wavevectors.
2116+
2117+ implicit none
2118+ real(dp),intent(in):: kc ! Planewave cutoff: k>kcut => phi=0
2119+
2120+ real(dp):: pi
2121+
2122+ ! Set kcut and radial mesh parameters, if not already set
2123+ if (.not. kc==kcut) then
2124+ kcut = kc
2125+ pi = acos(-1._dp)
2126+ dr = rcut / nr
2127+ dk = pi / rcut
2128+ kmax = pi / dr
2129+ nk = int(kcut/dk) + 1
2130+ if (nk>nr) stop 'pbevv_vdw_set_kcut: ERROR: nk>nr'
2131+ kcut_set = .true.
2132+#ifdef DEBUG_XC
2133+ write(udebug,'(a,5f8.3)') 'pbevv_vdw_set_kcut: kfcut,kgcut,rcut,kcut,kmax=', &
2134+ kfcut, kgcut, rcut, kc, kmax
2135+#endif /* DEBUG_XC */
2136+ end if
2137+
2138+ ! Set (kf,kg) mesh and phi table
2139+ call set_kmesh()
2140+ call set_phi_table()
2141+
2142+end subroutine pbevv_vdw_set_kcut
2143+
2144+!-----------------------------------------------------------------------------
2145+
2146+subroutine pbevv_vdw_theta( nspin, rhos, grhos, theta, dtdrho, dtdgrho )
2147+
2148+! Finds the value and derivatives of theta_i(rho,grad_rho) of eq.(8)
2149+! of Roman-Soler PRL 2009. In practice, theta_i=p_i rather than rho*p_i,
2150+! beacuse p_i is used here to expand rho1*rho2*phi rather than only phi.
2151+
2152+ implicit none
2153+ integer, intent(in) :: nspin ! Number of spin components
2154+ real(dp),intent(in) :: rhos(nspin) ! Electron spin density
2155+ real(dp),intent(in) :: grhos(3,nspin) ! Spin density gradient
2156+ real(dp),intent(out):: theta(nkfg) ! Exp. polynomials at (kf,kg)
2157+ real(dp),intent(out):: dtdrho(nkfg,nspin) ! dtheta(ik)/drhos
2158+ real(dp),intent(out):: dtdgrho(3,nkfg,nspin) ! dtheta(ik)/dgrhos(ix)
2159+
2160+ integer :: is, ix, ns
2161+ real(dp):: rho, grho(3), dpdkf(nkfg), dpdkg(nkfg), dkfdrho, dkfdgrho(3), &
2162+ dkgdrho, dkgdgrho(3), kf, kg, p(nkfg)
2163+
2164+ ! Sum spin components of electron density
2165+ ns = min(nspin,2) ! num. of diagonal spin components (if noncollinear)
2166+ rho = sum(rhos(1:ns)) ! local electron density
2167+ grho = sum(grhos(:,1:ns),dim=2) ! local density gradient
2168+
2169+ ! If density is between threshold, return zero
2170+ if (rho<rhoMin) then
2171+ theta = 0
2172+ dtdrho = 0
2173+ dtdgrho = 0
2174+ return
2175+ end if
2176+
2177+ ! Find local Fermi and gradient wavevectors, and their derivatives
2178+ call kofn( rho, grho, kf, kg, dkfdrho, dkgdrho, dkfdgrho, dkgdgrho )
2179+
2180+ ! Find expansion polynomials of integrand kernel of nonlocal vdW energy
2181+ call pofk( kf, kg, p, dpdkf, dpdkg )
2182+
2183+ ! Find theta functions and their derivatives with respect to rho and grho
2184+ if (kernelPrefactor=='rho') then
2185+ ! This is the right code if pbevv_vdw_phi_val returns rho1*rho2*phi
2186+ theta(1:nkfg) = p(1:nkfg)
2187+ do is = 1,ns
2188+ dtdrho(1:nkfg,is) = dpdkf(1:nkfg)*dkfdrho + dpdkg(1:nkfg)*dkgdrho
2189+ do ix = 1,3
2190+ dtdgrho(ix,1:nkfg,is) = dpdkf(1:nkfg)*dkfdgrho(ix) &
2191+ + dpdkg(1:nkfg)*dkgdgrho(ix)
2192+ end do
2193+ end do
2194+ else if (kernelPrefactor=='kf') then
2195+ ! This is the right code if pbevv_vdw_phi_val returns kf1*kf2*phi
2196+ kf = max(kf,ktol)
2197+ theta(1:nkfg) = p(1:nkfg)*rho/kf
2198+ do is = 1,ns
2199+ dtdrho(1:nkfg,is) = (dpdkf(1:nkfg)*dkfdrho &
2200+ +dpdkg(1:nkfg)*dkgdrho)*rho/kf &
2201+ + p(1:nkfg)*(1/kf-rho/kf**2*dkfdrho)
2202+ do ix = 1,3
2203+ dtdgrho(ix,1:nkfg,is) = (dpdkf(1:nkfg)*dkfdgrho(ix) &
2204+ +dpdkg(1:nkfg)*dkgdgrho(ix))*rho/kf
2205+ end do
2206+ end do
2207+ else if (kernelPrefactor=='kf2') then
2208+ ! This is the right code if pbevv_vdw_phi_val returns (kf1*kf2)**2*phi
2209+ kf = max(kf,ktol)
2210+ theta(1:nkfg) = p(1:nkfg)*rho/kf**2
2211+ do is = 1,ns
2212+ dtdrho(1:nkfg,is) = (dpdkf(1:nkfg)*dkfdrho &
2213+ +dpdkg(1:nkfg)*dkgdrho)*rho/kf**2 &
2214+ + p(1:nkfg)*(1/kf**2-2*rho/kf**3*dkfdrho)
2215+ do ix = 1,3
2216+ dtdgrho(ix,1:nkfg,is) = (dpdkf(1:nkfg)*dkfdgrho(ix) &
2217+ +dpdkg(1:nkfg)*dkgdgrho(ix))*rho/kf**2
2218+ end do
2219+ end do
2220+ else if (kernelPrefactor=='sqr_rho') then
2221+ ! This is the right code if pbevv_vdw_phi_val returns sqrt(rho1*rho2)*phi
2222+ rho = max(rho,1.e-12_dp) ! to avoid division by zero
2223+ theta(1:nkfg) = p(1:nkfg) * sqrt(rho)
2224+ do is = 1,ns
2225+ dtdrho(1:nkfg,is) = ( dpdkf(1:nkfg)*dkfdrho &
2226+ + dpdkg(1:nkfg)*dkgdrho ) * sqrt(rho) &
2227+ + p(1:nkfg) * 0.5/sqrt(rho)
2228+ do ix = 1,3
2229+ dtdgrho(ix,1:nkfg,is) = dpdkf(1:nkfg)*dkfdgrho(ix) * sqrt(rho) &
2230+ + dpdkg(1:nkfg)*dkgdgrho(ix) * sqrt(rho)
2231+ end do
2232+ end do
2233+ else
2234+ call die('pbevv_vdw_theta ERROR: unknown kernelPrefactor')
2235+ end if ! (kernelPrefactor=='rho')
2236+
2237+end subroutine pbevv_vdw_theta
2238+
2239+END MODULE m_pbevv_vdwxc
2240+
2241+!!!=============== PBEsol+VV10s =========================
2242+
2243+MODULE m_pbesvvs_vdwxc
2244+
2245+! Used module procedures
2246+ use sys, only: die ! Termination routine
2247+ use mesh1D, only: get_mesh ! Returns the mesh points
2248+ use m_radfft, only: radfft ! Radial fast Fourier transform
2249+ use alloc, only: re_alloc ! Re-allocation routine
2250+ use mesh1D, only: set_mesh ! Sets a 1D mesh
2251+ use interpolation,only: spline ! Sets spline interpolation
2252+ use interpolation,only: splint ! Calculates spline interpolation
2253+
2254+! Used module parameters
2255+ use precision, only: dp ! Real double precision type
2256+
2257+#ifdef DEBUG_XC
2258+ use debugXC, only: udebug ! File unit for debug output
2259+! use plot_module, only: plot
2260+#endif /* DEBUG_XC */
2261+
2262+ implicit none
2263+
2264+! Called by m_vdwxc
2265+PUBLIC :: &
2266+ pbesvvs_vdw_beta, &! Returns parameter beta of the VV2010 functional
2267+ pbesvvs_vdw_theta, &! Finds function theta_ik(rho,grad_rho)
2268+ pbesvvs_vdw_get_kmesh, &! Returns size and values of (kf,kg) mesh
2269+ pbesvvs_vdw_phi, &! Finds and interpolates rho1*rho2*phi(k1,k2,k)
2270+ pbesvvs_vdw_set_kcut ! Sets the planewave cutoff kc of the integration grid
2271+
2272+#ifdef DEBUG_XC
2273+! Called by debugging test programs
2274+PUBLIC :: &
2275+ pbesvvs_vdw_phi_val, &! Kernel phi(kf1,kf2,kg1,kg2,r12) with no interpolation
2276+ pbesvvs_vdw_phiofr ! Kernel phi(k1,k2,r) at tabulated k1,k2-mesh values
2277+#endif /* DEBUG_XC */
2278+
2279+PRIVATE ! Nothing is declared public beyond this point
2280+
2281+ ! Set parameters of the PBEsol+rVV10s,
2282+ ! Ref. A. V. Terentjev et al, Phys. Rev. B 98, 214108 (2018)
2283+ real(dp),parameter:: vv_C = 0.0093
2284+ real(dp),parameter:: vv_b = 10.0
2285+ real(dp),parameter:: vv_beta = 0.00497
2286+
2287+ ! Mesh parameters for table of phi(k1,k2,r) and its Fourier transform
2288+ character(len=*),parameter:: kernelPrefactor='rho' ! Prefactor of the
2289+ ! nonlocal kernel for interpolation
2290+ ! ('kf'|'kf2'|'sqr_rho'|'rho')
2291+ integer, parameter:: nr = 2048 ! Radial mesh points (power of 2)
2292+ real(dp),parameter:: rcut = 100._dp ! Radial cutoff: r>rcut => phi=0
2293+ real(dp),parameter:: rmin = 1.e-6_dp ! Min. radius as denominator
2294+ integer, parameter:: nkf = 7 ! Number of Fermi wavevectors
2295+ integer, parameter:: nkg = 5 ! Num. of grad(n)/n wavevectors
2296+ integer, parameter:: nkfg = nkf*nkg ! Num. of (kf,kg) mesh points
2297+ real(dp),parameter:: kfcut = 5.0_dp ! Max. Fermi wavevec.
2298+ real(dp),parameter:: kgcut = 5.0_dp ! Max. grad(n)/n
2299+ real(dp),parameter:: dkfmaxdkfmin = 20.0_dp ! Last/first kf mesh interval
2300+ real(dp),parameter:: dkgmaxdkgmin = 2.0_dp ! Last/first kg mesh interval
2301+ real(dp),parameter:: ktol = 1.e-12_dp ! 'out of range' tolerance
2302+ real(dp),parameter:: amin = 1.e-12_dp ! tiny denominator to avoid /0
2303+ real(dp),parameter:: rhoMin = 1.e-10_dp ! Min. density for nonzero Vxc
2304+
2305+ ! Parameters for cutoff function, used in radial Fourier transforms of phi
2306+ integer, parameter:: ncut1 = 8 ! cutoff(x)=(1-x**ncut1)**ncut2
2307+ integer, parameter:: ncut2 = 4
2308+
2309+ ! Parameters for saturate function, used to enforce that q<qcut
2310+ integer, parameter:: nsat = 15 ! h(x,xc)=1/(1/x**nsat+1/xc**nsat)**(1/nsat)
2311+ ! nsat=15 approximately corresponds to
2312+ ! nsat=12 for eq.(5) of Roman-Soler PRL
2313+
2314+ ! Private module variables and arrays
2315+ logical, save:: kcut_set=.false. ! Has kcut been set?
2316+ logical, save:: kmesh_set=.false. ! Has (kf,kg) mesh been set?
2317+ logical, save:: phi_table_set=.false. ! Has phi_table been set?
2318+ integer, save:: nk ! Num. of radial mesh k-points
2319+ real(dp),save:: dr ! r-mesh interval
2320+ real(dp),save:: dk ! k-mesh interval
2321+ real(dp),save:: kcut ! Planewave cutoff: k>kcut => phi=0
2322+ real(dp),save:: kmax ! Max. k vector in Fourier transforms
2323+ real(dp),save:: kfmesh(nkf) ! Mesh points for Fermi wavevector
2324+ real(dp),save:: kgmesh(nkg) ! Mesh points for grad(n)/n
2325+ real(dp),pointer,save:: &
2326+ phir(:,:,:)=>null(), &! Table of phi(r)
2327+ phik(:,:,:)=>null(), &! Table of phi(k)
2328+ d2phidr2(:,:,:)=>null(),&! Table of d^2(phi)/dr^2
2329+ d2phidk2(:,:,:)=>null() ! Table of d^2(phi)/dk^2
2330+
2331+CONTAINS
2332+
2333+! -----------------------------------------------------------------------------
2334+
2335+real(dp) function cutoff( x )
2336+
2337+! Defines a smooth cutoff function that falls from y(0)=1 to y(1)=0
2338+
2339+ implicit none
2340+ real(dp),intent(in):: x
2341+
2342+ if (x<=0._dp) then
2343+ cutoff = 1
2344+ else if (x>=1._dp) then
2345+ cutoff = 0
2346+ else
2347+ cutoff = (1-x**ncut1)**ncut2
2348+ end if
2349+
2350+end function cutoff
2351+
2352+!-----------------------------------------------------------------------------
2353+
2354+subroutine iofk( kf, kg, ikf, ikg )
2355+
2356+! Finds indexes ikf and ikg such that kfmesh(ikf) <= kf < kfmesh(ikf+1)
2357+! and kgmesh(ikg) <= kg < kgmesh(ikg+1) in logarithmic meshes of the form
2358+! k(ik) = b*(exp((ik-1)*a)-1)
2359+
2360+ implicit none
2361+ real(dp), intent(in) :: kf, kg
2362+ integer, intent(out):: ikf, ikg
2363+
2364+ real(dp),save:: akf, akg, bkf, bkg
2365+ logical, save:: first_call = .true.
2366+ integer:: ik
2367+
2368+ ! Mesh data initializations
2369+ if (first_call) then
2370+ ! Find logarithmic-mesh a & b parameters: x(j)=x(1)+b*(exp(a*(j-1))-1)
2371+ akf = log( (kfmesh(nkf)-kfmesh(nkf-1)) / (kfmesh(2)-kfmesh(1)) ) / (nkf-2)
2372+ akg = log( (kgmesh(nkg)-kgmesh(nkg-1)) / (kgmesh(2)-kgmesh(1)) ) / (nkg-2)
2373+ akf = max( akf, amin )
2374+ akg = max( akg, amin )
2375+ bkf = (kfmesh(nkf) - kfmesh(1)) / (exp(akf*(nkf-1)) - 1)
2376+ bkg = (kgmesh(nkg) - kgmesh(1)) / (exp(akg*(nkg-1)) - 1)
2377+ ! Check that meshes are indeed logarithmic
2378+ do ik = 1,nkf
2379+ if (abs(kfmesh(ik)-kfmesh(1)-bkf*(exp(akf*(ik-1))-1))>ktol) &
2380+ call die('pbesvvs_vdw_iofk ERROR: kfmesh not logarithmic')
2381+ end do
2382+ do ik = 1,nkg
2383+ if (abs(kgmesh(ik)-kgmesh(1)-bkg*(exp(akg*(ik-1))-1))>ktol) &
2384+ call die('pbesvvs_vdw_iofk ERROR: kgmesh not logarithmic')
2385+ end do
2386+ first_call = .false.
2387+ end if
2388+
2389+ ! Check that kf and kg are within interpolation range
2390+ if (kf<kfmesh(1)-ktol .or. kf>kfmesh(nkf)+ktol .or. &
2391+ kg<kgmesh(1)-ktol .or. kg>kgmesh(nkg)+ktol) then
2392+ call die('pbesvvs_vdw_iofk ERROR: (kf,kg) out of range')
2393+ endif
2394+
2395+ ! Find interpolation mesh intervals
2396+ ikf = 1 + int( log( 1 + (kf-kfmesh(1))/bkf ) / akf )
2397+ ikg = 1 + int( log( 1 + (kg-kgmesh(1))/bkg ) / akg )
2398+ ikf = max( 1, ikf )
2399+ ikg = max( 1, ikg )
2400+ ikf = min( nkf-1, ikf )
2401+ ikg = min( nkg-1, ikg )
2402+
2403+end subroutine iofk
2404+
2405+! -----------------------------------------------------------------------------
2406+
2407+subroutine kofn( n, gn, kf, kg, dkfdn, dkgdn, dkfdgn, dkgdgn )
2408+
2409+! Finds Fermi and gradient wavevectors from density and gradient
2410+
2411+ implicit none
2412+ real(dp), intent(in) :: n ! Electron density
2413+ real(dp), intent(in) :: gn(3) ! Density gradient
2414+ real(dp), intent(out):: kf ! Local Fermi wavevector
2415+ real(dp), intent(out):: kg ! |grad(n)|/n
2416+ real(dp), intent(out):: dkfdn ! dkf/dn
2417+ real(dp), intent(out):: dkgdn ! dkg/dn
2418+ real(dp), intent(out):: dkfdgn(3) ! dkf/dgn
2419+ real(dp), intent(out):: dkgdgn(3) ! dkg/dgn
2420+
2421+ real(dp):: gn2, pi
2422+
2423+! Trap exception for zero density
2424+ if (n <= 1.e-30_dp) then
2425+ kf = 0
2426+ kg = 0
2427+ dkfdn = 0
2428+ dkfdgn = 0
2429+ dkgdn = 0
2430+ dkgdgn = 0
2431+ return
2432+ end if
2433+
2434+! Find kf and kg
2435+ pi = acos(-1._dp)
2436+ kf = (3*pi**2*n)**(1._dp/3)
2437+ gn2 = sum(gn**2)
2438+ kg = sqrt(gn2)/n
2439+
2440+! Find derivatives
2441+ dkfdn = kf/n/3
2442+ dkfdgn = 0
2443+ dkgdn = -kg/n
2444+ dkgdgn = kg*gn/gn2
2445+
2446+end subroutine kofn
2447+
2448+!-----------------------------------------------------------------------------
2449+
2450+subroutine pofk( kf, kg, p, dpdkf, dpdkg )
2451+
2452+! Finds the values and derivatives, at (kf,kg), of the bicubic polynomials
2453+! p_i(kf,kg) such that
2454+! y(kf,kg) = Sum_i p_i(kf,kg) * y_i
2455+! is the bicubic spline interpolation at (kf,kg) of (any) function y with
2456+! values y_i at mesh points (kfmesh,kgmesh)_i
2457+
2458+ implicit none
2459+ real(dp),intent(in) :: kf, kg ! point at which the polynomials are required
2460+ real(dp),intent(out):: p(nkfg) ! polynomial values at (kf,kg)
2461+ real(dp),intent(out):: dpdkf(nkfg) ! dp/dkf at (kf,kg)
2462+ real(dp),intent(out):: dpdkg(nkfg) ! dp/dkg at (kf,kg)
2463+
2464+ integer :: ikf, ikg, ikfg, ikf0, ikg0
2465+ real(dp):: a, b, dk, dkf0dkf, dkg0dkg, kf0, kg0
2466+ real(dp):: pkf0(nkf), dpkfdkf0(nkf), pkg0(nkg), dpkgdkg0(nkg)
2467+ logical, save :: first_call=.true.
2468+ real(dp),save :: pkf(nkf,nkf), d2pkfdkf2(nkf,nkf)
2469+ real(dp),save :: pkg(nkg,nkg), d2pkgdkg2(nkg,nkg)
2470+
2471+! Set up spline polynomial basis
2472+ if (first_call) then
2473+ do ikf = 1,nkf
2474+ pkf(:,ikf) = 0 ! ikf'th polynomial pkf(:,ikf) is one at kfmesh(ikf)
2475+ pkf(ikf,ikf) = 1 ! and zero at all other points
2476+ call spline( kfmesh, pkf(:,ikf), nkf, 1.e30_dp, 1.e30_dp, &
2477+ d2pkfdkf2(:,ikf) )
2478+! call spline( kfmesh, pkf(:,ikf), nkf, 0._dp, 0._dp, d2pkfdkf2(:,ikf) )
2479+ end do
2480+ do ikg = 1,nkg
2481+ pkg(:,ikg) = 0
2482+ pkg(ikg,ikg) = 1
2483+ call spline( kgmesh, pkg(:,ikg), nkg, 1.e30_dp, 1.e30_dp, &
2484+ d2pkgdkg2(:,ikg) )
2485+! call spline( kgmesh, pkg(:,ikg), nkg, 0._dp, 0._dp, d2pkgdkg2(:,ikg) )
2486+ end do
2487+
2488+! DEBUG
2489+ open(22,file='pkf.dat')
2490+ do ikf = 1,nkf
2491+ write(22,'(20e15.6)') kfmesh(ikf), pkf(:,ikf), d2pkfdkf2(:,ikf)
2492+ end do
2493+ close(22)
2494+ open(22,file='pkg.dat')
2495+ do ikg = 1,nkg
2496+ write(22,'(20e15.6)') kgmesh(ikg), pkg(:,ikg), d2pkgdkg2(:,ikg)
2497+ end do
2498+ close(22)
2499+! END DEBUG
2500+
2501+ first_call = .false.
2502+ end if
2503+
2504+! 'Saturate' (kf,kg) values to bring them to interpolation range
2505+ call saturate( kf, kfcut, kf0, dkf0dkf )
2506+ call saturate( kg, kgcut, kg0, dkg0dkg )
2507+
2508+! Find interval of k mesh in which (kf0,kg0) point is included
2509+ call iofk( kf0, kg0, ikf0, ikg0 )
2510+
2511+! Evaluate pkf polynomials of spline basis at kf0
2512+! The splint code is in-lined here because it is a hot point
2513+ dk = kfmesh(ikf0+1) - kfmesh(ikf0)
2514+ a = (kfmesh(ikf0+1) - kf0) / dk ! dadkf0 = -1/dk
2515+ b = (kf0 - kfmesh(ikf0)) / dk ! dbdkf0 = +1/dk
2516+ do ikf = 1,nkf
2517+ pkf0(ikf) = a*pkf(ikf0,ikf) + b*pkf(ikf0+1,ikf) &
2518+ + ((a**3-a)*d2pkfdkf2(ikf0,ikf) + &
2519+ (b**3-b)*d2pkfdkf2(ikf0+1,ikf)) * dk**2/6
2520+ dpkfdkf0(ikf) = - (pkf(ikf0,ikf) - pkf(ikf0+1,ikf)) / dk &
2521+ - ((3*a**2-1)*d2pkfdkf2(ikf0,ikf) - &
2522+ (3*b**2-1)*d2pkfdkf2(ikf0+1,ikf)) * dk/6
2523+ end do
2524+
2525+! Evaluate pkg polynomials of spline basis at kg0
2526+ dk = kgmesh(ikg0+1) - kgmesh(ikg0)
2527+ a = (kgmesh(ikg0+1) - kg0) / dk ! dadkg0 = -1/dk
2528+ b = (kg0 - kgmesh(ikg0)) / dk ! dbdkg0 = +1/dk
2529+ do ikg = 1,nkg
2530+ pkg0(ikg) = a*pkg(ikg0,ikg) + b*pkg(ikg0+1,ikg) &
2531+ + ((a**3-a)*d2pkgdkg2(ikg0,ikg) + &
2532+ (b**3-b)*d2pkgdkg2(ikg0+1,ikg)) * dk**2/6
2533+ dpkgdkg0(ikg) = - (pkg(ikg0,ikg) - pkg(ikg0+1,ikg)) / dk &
2534+ - ((3*a**2-1)*d2pkgdkg2(ikg0,ikg) - &
2535+ (3*b**2-1)*d2pkgdkg2(ikg0+1,ikg)) * dk/6
2536+ end do
2537+
2538+! Evaluate pkf*pkg polynomials at (kf0,kg0)
2539+ ikfg = 0
2540+ do ikg = 1,nkg
2541+ do ikf = 1,nkf
2542+ ikfg = ikfg+1
2543+ p(ikfg) = pkf0(ikf) * pkg0(ikg)
2544+ dpdkf(ikfg) = dpkfdkf0(ikf)*dkf0dkf * pkg0(ikg)
2545+ dpdkg(ikfg) = pkf0(ikf) * dpkgdkg0(ikg)*dkg0dkg
2546+ end do
2547+ end do
2548+
2549+end subroutine pofk
2550+
2551+!-----------------------------------------------------------------------------
2552+
2553+subroutine saturate( x, xc, y, dydx )
2554+
2555+ ! Defines a function y(x,xc) = 1/(1/x^nsat+1/xc^nsat)^(1/nsat), where nsat
2556+ ! is an integer set in the module header. This function is approximately
2557+ ! equal to x for x<xc and it saturates to xc when x->infinity
2558+
2559+ implicit none
2560+ real(dp),intent(in) :: x ! Independent variable
2561+ real(dp),intent(in) :: xc ! Saturation value
2562+ real(dp),intent(out):: y ! Function value
2563+ real(dp),intent(out):: dydx ! Derivative dy/dx
2564+
2565+ real(dp):: z
2566+
2567+ if (xc<=0._dp) then
2568+ call die('pbesvvs_vdwxc_saturate ERROR: xc<=0')
2569+ else if (x<0._dp) then
2570+ call die('pbesvvs_vdwxc_saturate ERROR: x<0')
2571+ else if (x==0._dp) then
2572+ y = 0
2573+ dydx = 1
2574+ else
2575+ z = 1/x**nsat + 1/xc**nsat
2576+ y = 1/z**(1._dp/nsat)
2577+ dydx = y/z/x**(nsat+1)
2578+ end if
2579+
2580+end subroutine saturate
2581+
2582+!-----------------------------------------------------------------------------
2583+
2584+subroutine saturate_inverse( y, xc, x, dxdy )
2585+
2586+! Finds the inverse of the function defined in saturate subroutine:
2587+! y=1/(1/x^n+1/xc^n)^(1/n) => x=1/(1/y^n-1/xc^n)^(1/n)
2588+
2589+ implicit none
2590+ real(dp),intent(in) :: y ! Independent variable
2591+ real(dp),intent(in) :: xc ! Saturation value
2592+ real(dp),intent(out):: x ! Inverse function value
2593+ real(dp),intent(out):: dxdy ! Derivative dx/dy
2594+
2595+ real(dp):: z
2596+
2597+ if (xc<=0._dp) then
2598+ call die('pbesvvs_vdwxc_saturate_inverse ERROR: xc<=0')
2599+ else if (y<0._dp .or. y>=xc) then
2600+ call die('pbesvvs_vdwxc_saturate_inverse ERROR: y out of range')
2601+ else if (y==0._dp) then
2602+ x = 0
2603+ dxdy = 1
2604+ else
2605+ z = 1/y**nsat - 1/xc**nsat
2606+ x = 1/z**(1._dp/nsat)
2607+ dxdy = x/z/y**(nsat+1)
2608+ end if
2609+
2610+end subroutine saturate_inverse
2611+
2612+!-----------------------------------------------------------------------------
2613+
2614+subroutine set_kmesh()
2615+
2616+! Sets mesh of q values
2617+
2618+ implicit none
2619+ integer :: mkf, mkg
2620+
2621+ if (.not.kmesh_set) then
2622+ call set_mesh( nkf, xmax=kfcut, dxndx1=dkfmaxdkfmin )
2623+ call get_mesh( nkf, mkf, kfmesh )
2624+ call set_mesh( nkg, xmax=kgcut, dxndx1=dkgmaxdkgmin )
2625+ call get_mesh( nkg, mkg, kgmesh )
2626+ kmesh_set = .true.
2627+#ifdef DEBUG_XC
2628+ write(udebug,'(/,a,/,(10f8.4))') 'pbesvvs_vdw_set_kmesh: kfmesh =', kfmesh
2629+ write(udebug,'(/,a,/,(10f8.4))') 'pbesvvs_vdw_set_kmesh: kgmesh =', kgmesh
2630+#endif /* DEBUG_XC */
2631+ end if
2632+
2633+end subroutine set_kmesh
2634+
2635+! -----------------------------------------------------------------------------
2636+
2637+subroutine set_phi_table()
2638+
2639+! Finds and stores in memory the interpolation table (mesh points and
2640+! function values) for the kernel phi(k1,k2,k).
2641+
2642+ implicit none
2643+ character(len=*),parameter:: myName = 'pbesvvs_vdwxc/set_phi_table '
2644+ integer :: ik, ikf1, ikf2, ikg1, ikg2, ik1, ik2, ir
2645+ real(dp):: dkdk0, dphidk0, dphidkmax, dphidr0, dphidrmax, &
2646+ k, kf1, kf2, kg1, kg2, pi, r(0:nr)
2647+
2648+! Check that table was not set yet
2649+ if (phi_table_set) return
2650+
2651+! Check that kf, kg, r, and k meshes have been set
2652+ if (.not.kmesh_set) call set_kmesh()
2653+ if (.not.kcut_set) call die('pbesvvs_vdw_set_phi_table ERROR: kcut not set')
2654+ forall(ir=0:nr) r(ir) = ir*dr
2655+ pi = acos(-1.0_dp)
2656+
2657+! Allocate arrays
2658+ call re_alloc( phir, 0,nr, 1,nkfg, 1,nkfg, myName//'phir' )
2659+ call re_alloc( phik, 0,nr, 1,nkfg, 1,nkfg, myName//'phik' )
2660+ call re_alloc( d2phidr2, 0,nr, 1,nkfg, 1,nkfg, myName//'d2phidr2' )
2661+ call re_alloc( d2phidk2, 0,nr, 1,nkfg, 1,nkfg, myName//'d2phidk2' )
2662+
2663+! Loop on (k1,k2) mesh points
2664+ do ikg2 = 1,nkg ! loop on kg2
2665+ do ikf2 = 1,nkf ! loop on kf2
2666+ ik2 = ikf2 + nkf*(ikg2-1) ! combined (ikf2,ikg2) index
2667+ do ikg1 = 1,nkg ! loop on kg1
2668+ do ikf1 = 1,nkf ! loop on kf1
2669+ ik1 = ikf1 + nkf*(ikg1-1) ! combined (ikf1,ikg1) index
2670+ if (ik1>ik2) cycle ! since we will symmetrize at the end
2671+
2672+ ! Saturated (kf,kg) values
2673+ kf1 = kfmesh(ikf1)
2674+ kf2 = kfmesh(ikf2)
2675+ kg1 = kgmesh(ikg1)
2676+ kg2 = kgmesh(ikg2)
2677+
2678+ ! Find original (unsaturated) kf anf kg values
2679+ ! call saturate_inverse( kfmesh(ikf1), kfcut, kf1, dkdk0 )
2680+ ! call saturate_inverse( kfmesh(ikf2), kfcut, kf2, dkdk0 )
2681+ ! call saturate_inverse( kgmesh(ikg1), kgcut, kg1, dkdk0 )
2682+ ! call saturate_inverse( kgmesh(ikg2), kgcut, kg2, dkdk0 )
2683+
2684+ ! Find kernel as a function of r12
2685+ do ir = 0,nr
2686+ phir(ir,ik1,ik2) = pbesvvs_vdw_phi_val( kf1, kf2, kg1, kg2, r(ir) )
2687+ end do
2688+
2689+ ! Kill kernel smoothly at r=rcut
2690+ do ir = 0,nr
2691+ phir(ir,ik1,ik2) = phir(ir,ik1,ik2) * cutoff( r(ir)/rcut )
2692+ end do
2693+
2694+ ! Find kernel in reciprocal space
2695+ call radfft( 0, nr, rcut, phir(:,ik1,ik2), phik(:,ik1,ik2) )
2696+ phik(:,ik1,ik2) = phik(:,ik1,ik2) * (2*pi)**1.5_dp
2697+
2698+ ! Filter out above kcut
2699+ phik(nk:nr,ik1,ik2) = 0
2700+
2701+ ! Soft filter below kcut
2702+ do ik = 1,nk
2703+ k = ik * dk
2704+ phik(ik,ik1,ik2) = phik(ik,ik1,ik2) * cutoff(k/kcut)
2705+ end do
2706+
2707+ ! Find filtered kernel in real space
2708+ call radfft( 0, nr, kmax, phik(:,ik1,ik2), phir(:,ik1,ik2) )
2709+ phir(:,ik1,ik2) = phir(:,ik1,ik2) / (2*pi)**1.5_dp
2710+
2711+ ! Set up spline interpolation tables
2712+ dphidr0 = 0 ! since phi(k1,k2,r) is even in r
2713+ dphidk0 = 0 ! and therefore phi(k1,k2,k) is also even in k
2714+ dphidrmax = 0 ! since phi->0 for r->infty
2715+ dphidkmax = 0 ! and also when k->infty
2716+ call spline( dr, phir(:,ik1,ik2), nr+1, dphidr0, dphidrmax, &
2717+ d2phidr2(:,ik1,ik2) )
2718+ call spline( dk, phik(:,ik1,ik2), nk+1, dphidk0, dphidkmax, &
2719+ d2phidk2(:,ik1,ik2) )
2720+
2721+ ! Fill symmetric elements
2722+ phir(:,ik2,ik1) = phir(:,ik1,ik2)
2723+ phik(:,ik2,ik1) = phik(:,ik1,ik2)
2724+ d2phidr2(:,ik2,ik1) = d2phidr2(:,ik1,ik2)
2725+ d2phidk2(:,ik2,ik1) = d2phidk2(:,ik1,ik2)
2726+
2727+!#ifdef DEBUG_XC
2728+! if (.false. .and. ik1==ik2) then
2729+! print*, 'pbesvvs_vdw_set_kcut: ik1,ik2=', ik1, ik2
2730+! call window( 0._dp, 5._dp, -1._dp, 4._dp, 0 )
2731+! call axes( 0._dp, 1._dp, 0._dp, 1._dp )
2732+! call plot( nr+1, r, phi, phir(:,ik1,ik2) )
2733+! call window( 0._dp, 10._dp, -0.05_dp, 0.15_dp, 0 )
2734+! call axes( 0._dp, 1._dp, 0._dp, 0.05_dp )
2735+! call plot( nr+1, r, r**2*phi, r**2*phir(:,ik1,ik2))
2736+! call show()
2737+! end if
2738+!#endif /* DEBUG_XC */
2739+
2740+ end do ! ikf1
2741+ end do ! ikg1
2742+ end do ! ikf2
2743+ end do ! ikg2
2744+
2745+!#ifdef DEBUG_XC
2746+! open(17,file='vv_phi.table')
2747+! write(17,'(3a6,2a12,/,(3i6,2f15.9))') &
2748+! 'ik1', 'ik2', 'ir', 'phi', 'd2phi/dk2', &
2749+!! (((ik1,ik2,ir,phir(ir,ik1,ik2),d2phidr2(ir,ik1,ik2), &
2750+! (((ik1,ik2,ir,phik(ir,ik1,ik2),d2phidk2(ir,ik1,ik2), &
2751+! ir=0,100),ik2=1,nkfg),ik1=1,nkfg)
2752+! close(17)
2753+!#endif /* DEBUG_XC */
2754+
2755+! Mark table as set
2756+ phi_table_set = .true.
2757+
2758+end subroutine set_phi_table
2759+
2760+! -----------------------------------------------------------------------------
2761+
2762+real(dp) function pbesvvs_vdw_phi_val( kf1, kf2, kg1, kg2, r12 )
2763+
2764+! vdW energy kernel of Vydrov-vanVoorhis, eq.(2) of JCP 133, 244103 (2010)
2765+! This subroutine calculates the 'raw' kernel directly, without interpolarions
2766+! In practice, it returns n1*n2*phi(k1,k2,r12), which is smooth for kf->0
2767+! Input:
2768+! real(dp):: kf1, kf2 ! Fermi wavevectors at points 1 and 2
2769+! real(dp):: kg1, kg2 ! |grad(n)|/n at points 1 and 2
2770+! real(dp):: r12 ! distance between points 1 and 2
2771+
2772+! Arguments
2773+ implicit none
2774+ real(dp),intent(in) :: kf1, kf2, kg1, kg2, r12
2775+
2776+! Internal variables
2777+ real(dp):: g1, g2, kappa1, kappa2, kf1m, kf2m, n1, n2, &
2778+ phi, pi, w01, w02, wg1, wg2, wp1, wp2, &
2779+ ss1, ss2, vv_C1, vv_C2, vv_Ct1, vv_Ct2
2780+
2781+!! New parameters of the PBEsol+rVV10s,
2782+!! Ref. A.V. Terentjev et al, Phys. Rev. B 98, 214108 (2018)
2783+ vv_C1 = 0.5_dp
2784+ vv_C2 = 300.0_dp
2785+
2786+! Avoid dividing by zero when kf=0
2787+ kf1m = max(kf1,ktol)
2788+ kf2m = max(kf2,ktol)
2789+
2790+! Find kernel
2791+ pi = acos(-1.0_dp)
2792+ n1 = kf1m**3/(3*pi**2) ! electron density at point 1
2793+ n2 = kf2m**3/(3*pi**2) ! electron density at point 2
2794+!! New formulas of the PBEsol+rVV10s,
2795+!! Ref. A.V. Terentjev et al, Phys. Rev. B 98, 214108 (2018)
2796+ ss1 = 0.1616204568582_dp*kg1/(n1**(1/3))
2797+ ss2 = 0.1616204568582_dp*kg2/(n2**(1/3))
2798+ vv_Ct1 = vv_C+vv_C1/(1.0_dp + vv_C2*(ss1-0.5_dp)**2)
2799+ vv_Ct2 = vv_C+vv_C1/(1.0_dp + vv_C2*(ss2-0.5_dp)**2)
2800+!!
2801+ wp1 = sqrt(4*pi*n1) ! local plasma frequency at point 1
2802+ wp2 = sqrt(4*pi*n2) ! local plasma frequency at point 2
2803+!!
2804+ wg1 = sqrt(vv_Ct1*kg1**4) ! local band gap at point 1
2805+ wg2 = sqrt(vv_Ct2*kg2**4) ! local band gap at point 2
2806+!!
2807+ kappa1 = vv_b*kf1m**2/wp1 ! local VV kappa variable (eq.(9)) at point 1
2808+ kappa2 = vv_b*kf2m**2/wp2 ! kappa variable at point 2
2809+ w01 = sqrt(wg1**2+wp1**2/3) ! local w0 frequency (eq.(5)) at point 1
2810+ w02 = sqrt(wg2**2+wp2**2/3) ! local w0 frequency at point 2
2811+ g1 = w01*r12**2 + kappa1 ! local g variable (eq.(3)) at point 1
2812+ g2 = w02*r12**2 + kappa2 ! local g variable at point 2
2813+ phi = -1.5_dp/g1/g2/(g1+g2) ! VV kernel phi (eq.(2))
2814+
2815+ if (kernelPrefactor=='rho') then
2816+ ! Return whole integrand of eq.(1)
2817+ pbesvvs_vdw_phi_val = n1*n2*phi
2818+ else if (kernelPrefactor=='kf') then
2819+ ! Return kf1*kf2*phi
2820+ pbesvvs_vdw_phi_val = kf1*kf2*phi
2821+ else if (kernelPrefactor=='kf2') then
2822+ ! Return (kf1*kf2)**2*phi
2823+ pbesvvs_vdw_phi_val = (kf1*kf2)**2*phi
2824+ else if (kernelPrefactor=='sqr_rho') then
2825+ ! Find and return sqrt(n1*n2)*phi
2826+ pbesvvs_vdw_phi_val = sqrt(n1*n2)*phi
2827+ else
2828+ call die('pbesvvs_vdw_phi_val ERROR: unknown kernelPrefactor')
2829+ end if
2830+
2831+end function pbesvvs_vdw_phi_val
2832+
2833+! -----------------------------------------------------------------------------
2834+
2835+real(dp) function pbesvvs_vdw_beta()
2836+
2837+! Returns parameter beta of VV functional
2838+
2839+ implicit none
2840+ pbesvvs_vdw_beta = vv_beta
2841+
2842+end function pbesvvs_vdw_beta
2843+
2844+!-----------------------------------------------------------------------------
2845+
2846+subroutine pbesvvs_vdw_get_kmesh( mkf, mkg, kf, kg )
2847+
2848+! Returns size and values of (kf,kg) mesh
2849+
2850+ implicit none
2851+ integer, intent(out) :: mkf ! Number of kf mesh points
2852+ integer, intent(out) :: mkg ! Number of kg mesh points
2853+ real(dp),optional,intent(out) :: kf(:) ! Values of kf mesh points
2854+ real(dp),optional,intent(out) :: kg(:) ! Values of kg mesh points
2855+ integer:: nmax
2856+ if (.not.kmesh_set) call set_kmesh()
2857+ mkf = nkf
2858+ mkg = nkg
2859+ if (present(kf)) then
2860+ nmax = max( nkf, size(kf) )
2861+ kf(1:nmax) = kfmesh(1:nmax)
2862+ end if
2863+ if (present(kg)) then
2864+ nmax = max( nkg, size(kg) )
2865+ kg(1:nmax) = kgmesh(1:nmax)
2866+ end if
2867+end subroutine pbesvvs_vdw_get_kmesh
2868+
2869+! -----------------------------------------------------------------------------
2870+
2871+subroutine pbesvvs_vdw_phi( k, phi, dphidk )
2872+
2873+! Finds by interpolation phi(k1,k2,k) (Fourier transform of phi(k1,k2,r)),
2874+! with k1=(kf1,kg1), k2=(kf2,kg2) for all mesh values of kf (Fermi
2875+! wavevector) and kg (grad(n)/n). If the interpolation table does not exist,
2876+! it is calculated in the first call to pbesvvs_vdw_phi. It requires a previous
2877+! call to pbesvvs_vdw_set_kc to set k mesh.
2878+
2879+ implicit none
2880+ real(dp),intent(in) :: k ! Modulus of actual k vector
2881+ real(dp),intent(out):: phi(:,:) ! phi(k1,k2,k) at given k
2882+ ! for all k1,k2 in (kf,kg) mesh
2883+ real(dp),intent(out):: dphidk(:,:) ! dphi(k1,k2,k)/dk at given k
2884+
2885+ integer :: ik, ik1, ik2
2886+ real(dp):: a, a2, a3, b, b2, b3
2887+
2888+! Set interpolation table
2889+ if (.not.phi_table_set) call set_phi_table()
2890+
2891+! Check argument sizes
2892+ if (size(phi,1)<nkfg .or. size(phi,2)<nkfg) &
2893+ call die('pbesvvs_vdw_phi: ERROR: size(phi) too small')
2894+
2895+! Find phi values at point k
2896+ if (k >= kcut) then
2897+ phi(:,:) = 0
2898+ dphidk(:,:) = 0
2899+ else
2900+ ! Expand interpolation inline since this is the hottest point in VdW
2901+ ik = int(k/dk)
2902+ a = ((ik+1)*dk-k)/dk
2903+ b = 1 - a
2904+ a2 = (3*a**2 -1) * dk / 6
2905+ b2 = (3*b**2 -1) * dk / 6
2906+ a3 = (a**3 - a) * dk**2 / 6
2907+ b3 = (b**3 - b) * dk**2 / 6
2908+ do ik2 = 1,nkfg
2909+ do ik1 = 1,ik2
2910+! call splint( dk, phik(:,ik1,ik2), d2phidk2(:,ik1,ik2), &
2911+! nk+1, k, phi(ik1,ik2), dphidk(ik1,ik2), pr )
2912+ phi(ik1,ik2) = a*phik(ik,ik1,ik2) + b*phik(ik+1,ik1,ik2) &
2913+ + a3*d2phidk2(ik,ik1,ik2) + b3*d2phidk2(ik+1,ik1,ik2)
2914+ dphidk(ik1,ik2) = (-phik(ik,ik1,ik2) &
2915+ +phik(ik+1,ik1,ik2) )/dk &
2916+ - a2*d2phidk2(ik,ik1,ik2) + b2*d2phidk2(ik+1,ik1,ik2)
2917+ phi(ik2,ik1) = phi(ik1,ik2)
2918+ dphidk(ik2,ik1) = dphidk(ik1,ik2)
2919+ end do
2920+ end do
2921+ end if
2922+
2923+end subroutine pbesvvs_vdw_phi
2924+
2925+!-----------------------------------------------------------------------------
2926+
2927+subroutine pbesvvs_vdw_phiofr( r, phi )
2928+
2929+! Finds phi(k1,k2,r) with k1=(kf1,kg1), k2=(kf2,kg2) for mesh values of
2930+! kf's (Fermi wavevectors) and kg's (grad(n)/n)
2931+
2932+ implicit none
2933+ real(dp),intent(in) :: r
2934+ real(dp),intent(out):: phi(:,:)
2935+
2936+ integer :: ikf1, ikf2, ikg1, ikg2, ik1, ik2
2937+ real(dp):: dphidr
2938+
2939+ if (size(phi,1)<nkfg .or. size(phi,2)<nkfg) &
2940+ stop 'vv_phiofr: ERROR: size(phi) too small'
2941+ if (.not.phi_table_set) call set_phi_table()
2942+
2943+ if (r >= rcut) then
2944+ phi(:,:) = 0
2945+ else
2946+ do ik2 = 1,nkfg
2947+ do ik1 = 1,ik2
2948+ call splint( dr, phir(:,ik1,ik2), d2phidr2(:,ik1,ik2), &
2949+ nr+1, r, phi(ik1,ik2), dphidr )
2950+ phi(ik2,ik1) = phi(ik1,ik2)
2951+ end do ! ik1
2952+ end do ! ik2
2953+ end if ! (r>=rcut)
2954+
2955+end subroutine pbesvvs_vdw_phiofr
2956+
2957+!-----------------------------------------------------------------------------
2958+
2959+subroutine pbesvvs_vdw_set_kcut( kc )
2960+
2961+! Sets the reciprocal planewave cutoff kc of the integration grid, and finds
2962+! the interpolation table to be used by vdw_phi to obtain the vdW kernel phi
2963+! at the reciprocal mesh wavevectors.
2964+
2965+ implicit none
2966+ real(dp),intent(in):: kc ! Planewave cutoff: k>kcut => phi=0
2967+
2968+ real(dp):: pi
2969+
2970+ ! Set kcut and radial mesh parameters, if not already set
2971+ if (.not. kc==kcut) then
2972+ kcut = kc
2973+ pi = acos(-1._dp)
2974+ dr = rcut / nr
2975+ dk = pi / rcut
2976+ kmax = pi / dr
2977+ nk = int(kcut/dk) + 1
2978+ if (nk>nr) stop 'pbesvvs_vdw_set_kcut: ERROR: nk>nr'
2979+ kcut_set = .true.
2980+#ifdef DEBUG_XC
2981+ write(udebug,'(a,5f8.3)') 'pbesvvs_vdw_set_kcut: kfcut,kgcut,rcut,kcut,kmax=', &
2982+ kfcut, kgcut, rcut, kc, kmax
2983+#endif /* DEBUG_XC */
2984+ end if
2985+
2986+ ! Set (kf,kg) mesh and phi table
2987+ call set_kmesh()
2988+ call set_phi_table()
2989+
2990+end subroutine pbesvvs_vdw_set_kcut
2991+
2992+!-----------------------------------------------------------------------------
2993+
2994+subroutine pbesvvs_vdw_theta( nspin, rhos, grhos, theta, dtdrho, dtdgrho )
2995+
2996+! Finds the value and derivatives of theta_i(rho,grad_rho) of eq.(8)
2997+! of Roman-Soler PRL 2009. In practice, theta_i=p_i rather than rho*p_i,
2998+! beacuse p_i is used here to expand rho1*rho2*phi rather than only phi.
2999+
3000+ implicit none
3001+ integer, intent(in) :: nspin ! Number of spin components
3002+ real(dp),intent(in) :: rhos(nspin) ! Electron spin density
3003+ real(dp),intent(in) :: grhos(3,nspin) ! Spin density gradient
3004+ real(dp),intent(out):: theta(nkfg) ! Exp. polynomials at (kf,kg)
3005+ real(dp),intent(out):: dtdrho(nkfg,nspin) ! dtheta(ik)/drhos
3006+ real(dp),intent(out):: dtdgrho(3,nkfg,nspin) ! dtheta(ik)/dgrhos(ix)
3007+
3008+ integer :: is, ix, ns
3009+ real(dp):: rho, grho(3), dpdkf(nkfg), dpdkg(nkfg), dkfdrho, dkfdgrho(3), &
3010+ dkgdrho, dkgdgrho(3), kf, kg, p(nkfg)
3011+
3012+ ! Sum spin components of electron density
3013+ ns = min(nspin,2) ! num. of diagonal spin components (if noncollinear)
3014+ rho = sum(rhos(1:ns)) ! local electron density
3015+ grho = sum(grhos(:,1:ns),dim=2) ! local density gradient
3016+
3017+ ! If density is between threshold, return zero
3018+ if (rho<rhoMin) then
3019+ theta = 0
3020+ dtdrho = 0
3021+ dtdgrho = 0
3022+ return
3023+ end if
3024+
3025+ ! Find local Fermi and gradient wavevectors, and their derivatives
3026+ call kofn( rho, grho, kf, kg, dkfdrho, dkgdrho, dkfdgrho, dkgdgrho )
3027+
3028+ ! Find expansion polynomials of integrand kernel of nonlocal vdW energy
3029+ call pofk( kf, kg, p, dpdkf, dpdkg )
3030+
3031+ ! Find theta functions and their derivatives with respect to rho and grho
3032+ if (kernelPrefactor=='rho') then
3033+ ! This is the right code if pbesvvs_vdw_phi_val returns rho1*rho2*phi
3034+ theta(1:nkfg) = p(1:nkfg)
3035+ do is = 1,ns
3036+ dtdrho(1:nkfg,is) = dpdkf(1:nkfg)*dkfdrho + dpdkg(1:nkfg)*dkgdrho
3037+ do ix = 1,3
3038+ dtdgrho(ix,1:nkfg,is) = dpdkf(1:nkfg)*dkfdgrho(ix) &
3039+ + dpdkg(1:nkfg)*dkgdgrho(ix)
3040+ end do
3041+ end do
3042+ else if (kernelPrefactor=='kf') then
3043+ ! This is the right code if pbesvvs_vdw_phi_val returns kf1*kf2*phi
3044+ kf = max(kf,ktol)
3045+ theta(1:nkfg) = p(1:nkfg)*rho/kf
3046+ do is = 1,ns
3047+ dtdrho(1:nkfg,is) = (dpdkf(1:nkfg)*dkfdrho &
3048+ +dpdkg(1:nkfg)*dkgdrho)*rho/kf &
3049+ + p(1:nkfg)*(1/kf-rho/kf**2*dkfdrho)
3050+ do ix = 1,3
3051+ dtdgrho(ix,1:nkfg,is) = (dpdkf(1:nkfg)*dkfdgrho(ix) &
3052+ +dpdkg(1:nkfg)*dkgdgrho(ix))*rho/kf
3053+ end do
3054+ end do
3055+ else if (kernelPrefactor=='kf2') then
3056+ ! This is the right code if pbesvvs_vdw_phi_val returns (kf1*kf2)**2*phi
3057+ kf = max(kf,ktol)
3058+ theta(1:nkfg) = p(1:nkfg)*rho/kf**2
3059+ do is = 1,ns
3060+ dtdrho(1:nkfg,is) = (dpdkf(1:nkfg)*dkfdrho &
3061+ +dpdkg(1:nkfg)*dkgdrho)*rho/kf**2 &
3062+ + p(1:nkfg)*(1/kf**2-2*rho/kf**3*dkfdrho)
3063+ do ix = 1,3
3064+ dtdgrho(ix,1:nkfg,is) = (dpdkf(1:nkfg)*dkfdgrho(ix) &
3065+ +dpdkg(1:nkfg)*dkgdgrho(ix))*rho/kf**2
3066+ end do
3067+ end do
3068+ else if (kernelPrefactor=='sqr_rho') then
3069+ ! This is the right code if pbesvvs_vdw_phi_val returns sqrt(rho1*rho2)*phi
3070+ rho = max(rho,1.e-12_dp) ! to avoid division by zero
3071+ theta(1:nkfg) = p(1:nkfg) * sqrt(rho)
3072+ do is = 1,ns
3073+ dtdrho(1:nkfg,is) = ( dpdkf(1:nkfg)*dkfdrho &
3074+ + dpdkg(1:nkfg)*dkgdrho ) * sqrt(rho) &
3075+ + p(1:nkfg) * 0.5/sqrt(rho)
3076+ do ix = 1,3
3077+ dtdgrho(ix,1:nkfg,is) = dpdkf(1:nkfg)*dkfdgrho(ix) * sqrt(rho) &
3078+ + dpdkg(1:nkfg)*dkgdgrho(ix) * sqrt(rho)
3079+ end do
3080+ end do
3081+ else
3082+ call die('pbesvvs_vdw_theta ERROR: unknown kernelPrefactor')
3083+ end if ! (kernelPrefactor=='rho')
3084+
3085+end subroutine pbesvvs_vdw_theta
3086+
3087+END MODULE m_pbesvvs_vdwxc
3088+
3089+
3090
3091=== modified file 'Src/atom.F'
3092--- Src/atom.F 2019-06-20 10:59:42 +0000
3093+++ Src/atom.F 2019-09-06 14:47:07 +0000
3094@@ -2038,6 +2038,8 @@
3095 if (icorr .eq. "wc") ps_string ="GGA WC"
3096 if (icorr .eq. "bl") ps_string ="GGA BLYP"
3097 if (icorr .eq. "ps") ps_string ="GGA PBEsol"
3098+!
3099+ if (icorr .eq. "sg") ps_string ="GGA SG4"
3100
3101 if (icorr .eq. "jo") ps_string ="GGA PBEJsJrLO"
3102 if (icorr .eq. "jh") ps_string ="GGA PBEJsJrHEG"
3103@@ -2131,8 +2133,17 @@
3104 . write(6,'(a,1x,2a)')
3105 . 'xc_check: WARNING: Pseudopotential generated with',
3106 . trim(ps_string), " functional"
3107-
3108-
3109+!
3110+ elseif((XCauth(nf).eq.'SG4').and.(XCfunc(nf).eq.'GGA'))
3111+ . then
3112+
3113+ write(6,'(a)')
3114+ . 'xc_check: GGA SG4'
3115+ if (icorr.ne.'sg'.and.nXCfunc.eq.1)
3116+ . write(6,'(a,1x,2a)')
3117+ . 'xc_check: WARNING: Pseudopotential generated with',
3118+ . trim(ps_string), " functional"
3119+
3120 elseif((XCauth(nf).eq.'PW91').and.(XCfunc(nf).eq.'GGA')) then
3121
3122 write(6,'(a)')
3123
3124=== modified file 'Tests/Makefile'
3125--- Tests/Makefile 2019-01-30 15:22:16 +0000
3126+++ Tests/Makefile 2019-09-06 14:47:07 +0000
3127@@ -42,13 +42,14 @@
3128
3129 label = work
3130
3131-tests = 32_h2o ag anneal-cont ar2_vdw batio3 benzene bessel bessel-rich \
3132+tests = 32_h2o ag ag_sg4 anneal-cont ar2_vdw batio3 benzene bessel bessel-rich \
3133 born born_spin carbon_nanoscroll ch4 chargeconf-h2o \
3134 constant_volume dipole_correction fe fe_broyden \
3135 fe_clust_noncollinear fe_clust_noncollinear-gga fe_cohp \
3136 fen fe_noncol_kp fire_benzene floating \
3137 force_2 force_constants gate_G_charge gate_G_hartree ge111 \
3138- ge_fatbands_so graphite_c6 graphite_c6_full graphite_vdw_df \
3139+ ge_fatbands_so graphite_c6 graphite_c6_full graphite_c6_sg4 graphite_vdw_df \
3140+ graphite_vdw_pbesvvs graphite_vdw_pbevv graphite_vdw_sg4vv \
3141 h2_bessel h2o h2o_2 h2o_am05 h2o_bands h2o_bands_nc \
3142 h2o_bands_polarized h2o_basis h2o_coop h2o_dipole h2o_dipole2 \
3143 h2o_dos h2o_filteret_basis h2o_findp_bug h2o_netcdf h2o_op_broyden \
3144
3145=== modified file 'version.info'
3146--- version.info 2019-09-04 13:09:45 +0000
3147+++ version.info 2019-09-06 14:47:07 +0000
3148@@ -1,1 +1,1 @@
3149-trunk-781
3150+trunk-782

Subscribers

People subscribed via source and target branches