1 /* Ergo, version 3.8, a program for linear scaling electronic structure
2 * calculations.
3 * Copyright (C) 2019 Elias Rudberg, Emanuel H. Rubensson, Pawel Salek,
4 * and Anastasia Kruchinina.
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 *
19 * Primary academic reference:
20 * Ergo: An open-source program for linear-scaling electronic structure
21 * calculations,
22 * Elias Rudberg, Emanuel H. Rubensson, Pawel Salek, and Anastasia
23 * Kruchinina,
24 * SoftwareX 7, 107 (2018),
25 * <http://dx.doi.org/10.1016/j.softx.2018.03.005>
26 *
27 * For further information about Ergo, see <http://www.ergoscf.org>.
28 */
29
30 /* -*-mode:c; c-style:bsd; c-basic-offset:4;indent-tabs-mode:nil; -*- */
31 /** @file fun-vwn.c
32 implementation of VWN functional and its derivatives.
33 (c), Pawel Salek, pawsa@theochem.kth.se, sep 2001, nov 2002
34 */
35
36 #include <math.h>
37 #include <stddef.h>
38 #include <stdlib.h>
39
40 #define __CVERSION__
41
42 #include "functionals.h"
43
44 /* INTERFACE PART */
vwn_isgga(void)45 static int vwn_isgga(void) { return 0; }
46 static int vwn_read(const char* conf_line);
47 static real vwn3_energy(const FunDensProp* dp);
48 static void vwn3_first(FunFirstFuncDrv *ds, real factor, const FunDensProp* dp);
49 static void vwn3_second(FunSecondFuncDrv *ds, real factor, const FunDensProp* dp);
50 static void vwn3_third(FunThirdFuncDrv *ds, real factor, const FunDensProp* dp);
51 static real vwn_energy(const FunDensProp* dp);
52 static void vwn_first(FunFirstFuncDrv *ds, real factor, const FunDensProp* dp);
53 static void vwn_second(FunSecondFuncDrv *ds, real factor, const FunDensProp* dp);
54 static void vwn_third(FunThirdFuncDrv *ds, real factor, const FunDensProp* dp);
55 static void vwn_fourth(FunFourthFuncDrv *ds, real factor,
56 const FunDensProp* dp);
57 static real vwni_energy(const FunDensProp* dp);
58 static void vwni_first(FunFirstFuncDrv *ds, real factor, const FunDensProp* dp);
59 static void vwni_second(FunSecondFuncDrv *ds, real factor, const FunDensProp* dp);
60 static void vwni_third(FunThirdFuncDrv *ds, real factor, const FunDensProp* dp);
61 static real vwn3i_energy(const FunDensProp* dp);
62 static void vwn3i_first(FunFirstFuncDrv *ds, real factor, const FunDensProp* dp);
63 static void vwn3i_second(FunSecondFuncDrv *ds, real factor, const FunDensProp* dp);
64 static void vwn3i_third(FunThirdFuncDrv *ds, real factor, const FunDensProp* dp);
65
66 /* VWN3 is a Gaussian version of the VWN functional based on suboptimal
67 * set of parameters */
68 Functional VWN3Functional = {
69 "VWN3", /* name */
70 vwn_isgga, /* gga-corrected */
71 vwn_read, /* no extra input expected, just set the common block */
72 NULL,
73 vwn3_energy,
74 vwn3_first,
75 vwn3_second,
76 vwn3_third
77 };
78
79 Functional VWN5Functional = {
80 "VWN5", /* name */
81 vwn_isgga, /* gga-corrected */
82 vwn_read, /* no extra input expected, just set the common block */
83 NULL,
84 vwn_energy,
85 vwn_first,
86 vwn_second,
87 vwn_third,
88 vwn_fourth
89 };
90
91 /* VWN is used for backward compatibility only */
92 Functional VWNFunctional = {
93 "VWN", /* name */
94 vwn_isgga, /* gga-corrected */
95 vwn_read, /* no extra input expected, just set the common block */
96 NULL,
97 vwn_energy,
98 vwn_first,
99 vwn_second,
100 vwn_third,
101 vwn_fourth
102 };
103
104 /* VWNIFunctional is a variant of VWN5 functional with another spin
105 polarization dependence:
106
107 F(r,zeta) = (E_p + f(zeta)*(E_f - E_p))*rho
108
109 */
110 Functional VWNIFunctional = {
111 "VWNI", /* name */
112 vwn_isgga, /* gga-corrected */
113 vwn_read, /* no extra input expected, just set the common block */
114 NULL,
115 vwni_energy,
116 vwni_first,
117 vwni_second,
118 vwni_third
119 };
120
121 /* VWN3IFunctional is a variant of VWN3 functional with another spin
122 polarization dependence:
123
124 F(r,zeta) = (E_p + f(zeta)*(E_f - E_p))*rho
125
126 */
127 Functional VWN3IFunctional = {
128 "VWN3I", /* name */
129 vwn_isgga, /* gga-corrected */
130 vwn_read, /* no extra input expected, just set the common block */
131 NULL,
132 vwn3i_energy,
133 vwn3i_first,
134 vwn3i_second,
135 vwn3i_third
136 };
137
138
139 /* IMPLEMENTATION PART */
140 #define VWN_ZERO 1e-35
141
142 static int
vwn_read(const char * conf_line)143 vwn_read(const char* conf_line)
144 {
145 fun_set_hf_weight(0);
146 return 1;
147 }
148
149 /* vwn_params contains two sets of parameters for paramagnetic and
150 ferromagnetic cases. See Table 5 in VWN paper.
151 */
152
153
154 static const struct vwn_params {
155 real X0, A, B, C;
156 } vwn_paramagnetic = { -0.1049800, 0.0621814, 3.72744, 12.9352 },
157 vwn_ferromagnetic = { -0.3250000, 0.0310907, 7.06042, 18.0578 },
158 vwn_interp = { -0.0047584,-0.0337737, 1.13107, 13.0045 },
159 vwn3_paramagnetic = { -0.4092860, 0.0621814, 13.0720, 42.7198 },
160 vwn3_ferromagnetic= { -0.7432940, 0.0310907, 20.1231, 101.578 };
161
162
163 static const real SPINPOLF = 1.92366105093154; /* 1/(2(2^(1/3)-1)) */
164 static const real THREEFTHRD2 = 0.584822305543806;/* hm? 4.5/(4*SPINPOLF) */
165 static const real FOURTHREE = 1.333333333333333;
166
167 /* vwn_en_pot:
168 returns "order" numbers in enpot array
169 enpot[0]: energy of given type p E = rho F - THIS IS AN EXCEPTION!
170 DO NOT BLAME IT ON ME.
171 enpot[1]: E'=enpot[0] + rho*F'
172 enpot[2]: E''
173 enpot[3]: E'''
174 */
175 static void
vwn_en_pot(real * enpot,real rho,int order,const struct vwn_params * p)176 vwn_en_pot(real* enpot, real rho, int order, const struct vwn_params* p)
177 {
178 const real
179 AI = p->A,
180 BI = p->B,
181 CI = p->C,
182 X0I = p->X0;
183 const real
184 Q = SQRT(4*CI - BI*BI),
185 XF0I = X0I*X0I + BI*X0I + CI,
186 YF0I = Q/(BI + 2*X0I),
187 DCRS = POW(3.0/(4*M_PI),1.0/6.0),
188 B = X0I/XF0I,
189 C = XF0I*YF0I,
190 ACON = B*BI - 1.0,
191 BCON = 2*ACON + 2.0,
192 CCON = 2*BI*(1.0/Q - X0I/C);
193
194 real rho13 = POW(rho,1.0/3.0);
195 real x = DCRS/SQRT(rho13);
196 real xrho = -DCRS*POW(rho,-7.0/6.0)/6.0;
197 real xxrho = +DCRS*POW(rho,-13.0/6.0)*7.0/36.0;
198 real xf = x*x + BI*x+CI;
199 real xfx = 2*x + BI;
200 real yf = Q/xfx;
201 real e1, ex1, exx1, exxx1;
202 real xf_p2, xf_p3, xf_p4, xfx_p2, xfx_p4;
203 real xrho_p2, xrho_p3, xrho_p4, xxrho_p2, xxxrho, xxxxrho;
204 real Q_p2, exxxx1;
205 real x_p4;
206
207 e1 = 2*LOG(x)
208 + ACON*LOG(xf)
209 - BCON*LOG(x - X0I)
210 + CCON*ATAN(yf);
211 enpot[0] = 0.5*AI*e1;
212 if(order<1) return;
213
214 ex1 = 2.0/x
215 + ACON*xfx/xf
216 - BCON/(x - X0I)
217 - CCON*(2*yf/xfx)/(1.0 + yf*yf);
218 enpot[1] = 0.5*AI*(e1 + rho*ex1*xrho);
219 if(order<2) return;
220
221 exx1= -2.0/(x*x)
222 + ACON*(2.0/xf - xfx*xfx/(xf*xf))
223 + BCON/((x - X0I)*(x - X0I))
224 + CCON*8*Q*xfx/((Q*Q + xfx*xfx)*(Q*Q + xfx*xfx));
225 enpot[2] = 0.5*AI*xrho*(2*ex1 + rho*exx1*xrho - ex1*7.0/6.0);
226 if(order<3) return;
227
228 exxx1= 4.0/(x*x*x)
229 + ACON*(2.0*xfx/(xf*xf))*(xfx*xfx/xf-3.0)
230 - BCON*2.0/POW(x - X0I,3.0)
231 + CCON*16.0*Q*(Q*Q-3.0*xfx*xfx)/POW(Q*Q + xfx*xfx,3.0);
232 enpot[3] = 0.5*AI*xxrho*(2*ex1 + rho*exx1*xrho - 7.0/6.0*ex1)
233 + 0.5*AI*xrho*(2*exx1*xrho
234 +exx1*xrho + rho*(exxx1*xrho*xrho+exx1*xxrho)
235 -7.0/6.0*exx1*xrho);
236
237 if(order<4) return;
238 x_p4 = POW(x,4.0);
239 xf_p2 = xf*xf;
240 xf_p3 = xf_p2*xf;
241 xf_p4 = xf_p2*xf_p2;
242 xfx_p2 = xfx*xfx;
243 xfx_p4 = xfx_p2*xfx_p2;
244 xrho_p2 = xrho*xrho;
245 xrho_p3 = xrho_p2*xrho;
246 xrho_p4 = xrho_p2*xrho_p2;
247 xxrho_p2 = xxrho*xxrho;
248 xxxrho = (-91.0/216.0)*DCRS/POW(rho,19.0/6.0);
249 xxxxrho = (1729.0/1296.0)*DCRS/POW(rho,25.0/6.0);
250 Q_p2 = Q*Q;
251
252 exxxx1 = 6*((-2*ACON)/xf_p2 + (4*xfx_p2*ACON)/xf_p3 -
253 (xfx_p4*ACON)/xf_p4 + (64*xfx*CCON*(xfx - Q)*Q*(xfx + Q))/
254 POW((xfx_p2 + Q_p2),4.0) - 2/x_p4 + BCON/POW((x - X0I),4.0));
255
256 enpot[4] = 0.5*AI*(4*exxx1*xrho_p3 + exxxx1*rho*xrho_p4 +
257 6*exxx1*rho*xrho_p2*xxrho +
258 3*exx1*rho*xxrho_p2 +
259 4*exx1*xrho*(3*xxrho + rho*xxxrho) +
260 ex1*(4*xxxrho + rho*xxxxrho));
261 /* for fourth derivatives we need also
262 first derivative of enpot[0] with respect to rho.
263 It is stored in enpot[5] (what a mess!) */
264 enpot[5] = 0.5*AI*ex1*xrho;
265
266 }
267
268 static real
par_energy(const FunDensProp * dp,const struct vwn_params * para,const struct vwn_params * ferro)269 par_energy(const FunDensProp* dp, const struct vwn_params* para,
270 const struct vwn_params* ferro)
271 {
272 real ep_p[2], ep_f[2], ep_i[2], zeta, zeta4, f_zeta, delta;
273 real rhoa = dp->rhoa, rhob = dp->rhob, rho;
274
275 if(rhoa<VWN_ZERO) rhoa = VWN_ZERO;
276 if(rhob<VWN_ZERO) rhob = VWN_ZERO;
277 rho = rhoa + rhob;
278 vwn_en_pot(ep_p, rho, 0, para);
279
280 if(FABS(dp->rhoa-dp->rhob)<VWN_ZERO) return ep_p[0]*rho;
281 vwn_en_pot(ep_f, rho, 0, ferro);
282 vwn_en_pot(ep_i, rho, 0, &vwn_interp);
283
284 zeta = (dp->rhoa-dp->rhob)/rho;
285 zeta4 = POW(zeta,4.0);
286 f_zeta = SPINPOLF*(POW(1+zeta,FOURTHREE)+POW(1-zeta,FOURTHREE)-2.0);
287 delta = f_zeta*((ep_f[0]-ep_p[0])*zeta4 + ep_i[0]*(1-zeta4)*THREEFTHRD2);
288
289 return (ep_p[0]+ delta)*rho;
290 }
291
292 static void
par_first(FunFirstFuncDrv * ds,real factor,const FunDensProp * dp,const struct vwn_params * para,const struct vwn_params * ferro)293 par_first(FunFirstFuncDrv *ds, real factor, const FunDensProp* dp,
294 const struct vwn_params* para, const struct vwn_params* ferro)
295 {
296 real zeta, zeta3,zeta4, f_zeta, f_zet1, e_f,acp, dacp, vcfp, g_f;
297 real delta, ep_p[2], ep_f[2], ep_i[2];
298 real rhoa = dp->rhoa, rhob = dp->rhob, rho;
299
300 if(rhoa<VWN_ZERO) rhoa = VWN_ZERO;
301 if(rhob<VWN_ZERO) rhob = VWN_ZERO;
302 rho = rhoa + rhob;
303 vwn_en_pot(ep_p, rho, 1, para);
304
305 ds->df1000 += ep_p[1]*factor;
306 ds->df0100 += ep_p[1]*factor;
307
308 if(FABS(dp->rhoa-dp->rhob)<VWN_ZERO) return;
309
310 /* contribution from spin-polarized case; first order */
311 zeta = (dp->rhoa-dp->rhob)/rho;
312 zeta3 = POW(zeta,3.0);
313 zeta4 = zeta3*zeta;
314 f_zeta = SPINPOLF*(POW(1+zeta,FOURTHREE)+POW(1-zeta,FOURTHREE)-2.0);
315 f_zet1 = SPINPOLF*4.0/3.0*(POW(1+zeta,1.0/3.0)-POW(1-zeta,1.0/3.0));
316 vwn_en_pot(ep_f, rho, 1, ferro);
317 e_f = ep_f[0] - ep_p[0];
318 g_f = ep_f[1] - ep_p[1];
319 vwn_en_pot(ep_i, rho, 1, &vwn_interp);
320 acp = ep_i[0]*THREEFTHRD2;
321 dacp = ep_i[1]*THREEFTHRD2;
322
323 vcfp = f_zeta*(g_f*zeta4 + dacp*(1-zeta4));
324 delta= (f_zet1*(e_f*zeta4 + acp*(1-zeta4)) +
325 4*f_zeta*(e_f - acp)*zeta3);
326
327 /* the final section: begin */
328 ds->df1000 += (vcfp + delta*(1-zeta))*factor;
329 ds->df0100 += (vcfp - delta*(1+zeta))*factor;
330 /* the final section: end */
331 }
332
333 /* vwn_second:
334 CAUTION: may raise zeros to a negative power!
335 */
336 static void
par_second(FunSecondFuncDrv * ds,real factor,const FunDensProp * dp,const struct vwn_params * para,const struct vwn_params * ferro)337 par_second(FunSecondFuncDrv *ds, real factor, const FunDensProp* dp,
338 const struct vwn_params* para, const struct vwn_params* ferro)
339 {
340 real zeta, zeta2, zeta3,zeta4, f_zeta, f_zet1, f_zet2, vcfp;
341 real delta, ep_p[3], ep_f[3], ep_i[3];
342 real vcfp1, ef0, ef1, ef2, ei0, ei1, ei2, bterm, cterm, dterm;
343 real spA, spB;
344 real rhoa = dp->rhoa, rhob = dp->rhob, rho = dp->rhoa + dp->rhob;
345 real rho2 = rho*rho;
346 real dAA, dAB, dBB;
347
348 vwn_en_pot(ep_p, rho, 2, para);
349
350 ds->df1000 += ep_p[1]*factor;
351 ds->df0100 += ep_p[1]*factor;
352 ds->df2000 += ep_p[2]*factor;
353 ds->df0200 += ep_p[2]*factor;
354 ds->df1100 += ep_p[2]*factor;
355
356 /* if(0&&dp->rhoa==dp->rhob) return; */
357 /* contribution from spin-polarized case; second order */
358 zeta = (dp->rhoa-dp->rhob)/rho;
359 zeta2 = zeta*zeta;
360 zeta3 = zeta2*zeta;
361 zeta4 = zeta3*zeta;
362 f_zeta = SPINPOLF*(POW(1+zeta,FOURTHREE)+POW(1-zeta,FOURTHREE)-2.0);
363 f_zet1 = SPINPOLF*4.0/3.0*(POW(1+zeta,1.0/3.0)-POW(1-zeta,1.0/3.0));
364 /* CAUTION: may raise 0 to negative power! */
365 f_zet2 = SPINPOLF*4.0/9.0*(POW(1+zeta,-2.0/3.0)+POW(1-zeta,-2.0/3.0));
366 vwn_en_pot(ep_f, rho, 2, ferro);
367 ef0 = ep_f[0] - ep_p[0];
368 ef1 = ep_f[1] - ep_p[1];
369 ef2 = ep_f[2] - ep_p[2];
370 vwn_en_pot(ep_i, rho, 2, &vwn_interp);
371 ei0 = ep_i[0]*THREEFTHRD2;
372 ei1 = ep_i[1]*THREEFTHRD2;
373 ei2 = ep_i[2]*THREEFTHRD2;
374
375 bterm = ef1*zeta4 + ei1*(1-zeta4);
376 vcfp = f_zeta*bterm;
377 delta = (f_zet1*(ef0*zeta4 + ei0*(1-zeta4))
378 + 4*f_zeta*(ef0 - ei0)*zeta3);
379
380 spA = 2*rhob/rho2; /* = 2(1-zeta)/rho */
381 spB =-2*rhoa/rho2; /* = -2(1+zeta)/rho */
382 /* contribution from spin-polarized case; second order */
383 /* spin independent part of vcfp */
384 vcfp1 = f_zeta*(ef2*zeta4 + ei2*(1-zeta4));
385 /* spin dependent part of vcfp */
386 cterm = 4*f_zeta*(ef1-ei1)*zeta3 + bterm*f_zet1 - delta;
387
388 /* spin dependent part of delta */
389 dterm = (f_zet2*(ef0*zeta4+ei0*(1-zeta4))
390 +8*f_zet1*(ef0-ei0)*zeta3
391 +12*f_zeta*(ef0-ei0)*zeta2)*rho;
392
393 dAA = dterm*spA*spA;
394 dAB = dterm*spA*spB;
395 dBB = dterm*spB*spB;
396
397 /* the final section: begin */
398 ds->df1000 += (vcfp + delta*(1-zeta))*factor;
399 ds->df0100 += (vcfp - delta*(1+zeta))*factor;
400
401 ds->df2000 += (vcfp1+ cterm*(spA+spA) + dAA)*factor;
402 ds->df1100 += (vcfp1+ cterm*(spA+spB) + dAB)*factor;
403 ds->df0200 += (vcfp1+ cterm*(spB+spB) + dBB)*factor;
404 /* the final section: end */
405 }
406
407 /* third not tested for open-shell! */
408 static void
par_third(FunThirdFuncDrv * ds,real factor,const FunDensProp * dp,const struct vwn_params * para,const struct vwn_params * ferro)409 par_third(FunThirdFuncDrv *ds, real factor, const FunDensProp* dp,
410 const struct vwn_params* para, const struct vwn_params* ferro)
411 {
412 real zeta, zeta2, zeta3,zeta4, f_zeta, f_zet1, f_zet2, f_zet3, vcfp;
413 real delta, ep_p[4], ep_f[4], ep_i[4];
414 real vcfp1, vcfp2, ef0, ef1, ef2, ef3, ei0, ei1, ei2, ei3;
415 real bterm, cterm, dterm, eterm, ctrm1, ctrm2, dtrm1, dtrm2;
416 real ef2bi, ei2bi;
417 real spA, spB, spAA, spAB, spBB;
418 real rhoa = dp->rhoa, rhob = dp->rhob, rho, rho2, rho3;
419
420 if(rhoa<VWN_ZERO) rhoa = VWN_ZERO;
421 if(rhob<VWN_ZERO) rhob = VWN_ZERO;
422 rho = rhoa + rhob;
423 rho2 = rho*rho; rho3 = rho2*rho;
424
425 vwn_en_pot(ep_p, rho, 3, para);
426
427 ds->df1000 += ep_p[1]*factor;
428 ds->df0100 += ep_p[1]*factor;
429 ds->df2000 += ep_p[2]*factor;
430 ds->df0200 += ep_p[2]*factor;
431 ds->df1100 += ep_p[2]*factor;
432
433 ds->df3000 += ep_p[3]*factor;
434 ds->df2100 += ep_p[3]*factor;
435 ds->df1200 += ep_p[3]*factor;
436 ds->df0300 += ep_p[3]*factor;
437
438 /* if(0&&dp->rhoa==dp->rhob) return; */
439 /* contribution from spin-polarized case; second order */
440 zeta = (dp->rhoa-dp->rhob)/rho;
441 zeta2 = zeta*zeta;
442 zeta3 = zeta2*zeta;
443 zeta4 = zeta3*zeta;
444 f_zeta = SPINPOLF* (POW(1+zeta,FOURTHREE)+POW(1-zeta,FOURTHREE)-2.0);
445 f_zet1 = SPINPOLF*4.0/3.0 *(POW(1+zeta, 1.0/3.0)-POW(1-zeta, 1.0/3.0));
446 f_zet2 = SPINPOLF*4.0/9.0 *(POW(1+zeta,-2.0/3.0)+POW(1-zeta,-2.0/3.0));
447 f_zet3 =-SPINPOLF*8.0/27.0*(POW(1+zeta,-5.0/3.0)-POW(1-zeta,-5.0/3.0));
448
449 vwn_en_pot(ep_f, rho, 3, ferro);
450 ef0 = ep_f[0] - ep_p[0];
451 ef1 = ep_f[1] - ep_p[1];
452 ef2 = ep_f[2] - ep_p[2];
453 ef3 = ep_f[3] - ep_p[3];
454 vwn_en_pot(ep_i, rho, 3,&vwn_interp);
455 ei0 = ep_i[0]*THREEFTHRD2;
456 ei1 = ep_i[1]*THREEFTHRD2;
457 ei2 = ep_i[2]*THREEFTHRD2;
458 ei3 = ep_i[3]*THREEFTHRD2;
459
460 bterm = ef1*zeta4 + ei1*(1-zeta4);
461 vcfp = f_zeta*bterm;
462 delta = (f_zet1*(ef0*zeta4 + ei0*(1-zeta4))
463 + 4*f_zeta*(ef0 - ei0)*zeta3);
464
465 spA = 2*rhob/rho2; /* = 2(1-zeta)/rho */
466 spB =-2*rhoa/rho2; /* = -2(1+zeta)/rho */
467 spAA = -4*rhob/rho3;
468 spAB = 2*(rho-2*rhob)/rho3;
469 spBB = 4*rhoa/rho3;
470 /* contribution from spin-polarized case; second order */
471 /* spin independent part of vcfp */
472 vcfp1 = f_zeta*(ef2*zeta4 + ei2*(1-zeta4));
473 /* spin dependent part of vcfp */
474 cterm = 4*f_zeta*(ef1-ei1)*zeta3 + bterm*f_zet1 - delta;
475
476 /* spin dependent part of delta */
477 dterm = (f_zet2*(ef0*zeta4+ei0*(1-zeta4))
478 +8*f_zet1*(ef0-ei0)*zeta3
479 +12*f_zeta*(ef0-ei0)*zeta2)*rho;
480
481 /* third order terms */
482 vcfp2 = f_zeta*(ef3*zeta4+ei3*(1-zeta4));
483 eterm = f_zet1*(ef2*zeta4 + ei2*(1-zeta4)) + f_zeta*(ef2-ei2)*4*zeta3;
484 ef2bi = ef2-(ef1-ef0)/rho;
485 ei2bi = ei2-(ei1-ei0)/rho;
486 ctrm1 = 4*f_zeta*(ef2bi-ei2bi)*zeta3 +f_zet1*(ef2bi*zeta4+ei2bi*(1-zeta4));
487
488 ctrm2 = (ef1-ei1-ef0+ei0)*(8*f_zet1*zeta3+12*f_zeta*zeta2)
489 +f_zet2*(bterm-(ef0*zeta4 + ei0*(1-zeta4)));
490
491 dtrm1 = f_zet2*((ef1-ef0)*zeta4+(ei1-ei0)*(1-zeta4))
492 +(8*f_zet1*zeta3+12*f_zeta*zeta2)*(ef1-ei1-ef0+ei0)
493 +dterm/rho;
494 dtrm2 = ((12*f_zet2*zeta3 + 36*f_zet1*zeta2 + 24*f_zeta*zeta)*(ef0-ei0)+
495 f_zet3*(ef0*zeta4+ei0*(1-zeta4)))*rho;
496
497 /* the final section: begin */
498 ds->df1000 += (vcfp + delta*(1-zeta))*factor;
499 ds->df0100 += (vcfp - delta*(1+zeta))*factor;
500
501 ds->df2000 += (vcfp1+ cterm*(spA+spA) + dterm*spA*spA)*factor;
502 ds->df1100 += (vcfp1+ cterm*(spA+spB) + dterm*spA*spB)*factor;
503 ds->df0200 += (vcfp1+ cterm*(spB+spB) + dterm*spB*spB)*factor;
504 ds->df3000 += (vcfp2+ eterm*spA +
505 ctrm1*(spA+spA)+ ctrm2*spA*(spA+spA) + cterm*(spAA+spAA) +
506 dtrm1*(spA*spA)+ dtrm2*spA*spA*spA + dterm*(2*spAA*spA)
507 )*factor;
508 ds->df2100 += (vcfp2+ eterm*spB +
509 ctrm1*(spA+spA)+ ctrm2*spB*(spA+spA) + cterm*(spAB+spAB) +
510 dtrm1*(spA*spA)+ dtrm2*spA*spA*spB + dterm*(2*spAB*spA)
511 )*factor;
512 ds->df1200 += (vcfp2+ eterm*spA +
513 ctrm1*(spB+spB)+ ctrm2*spA*(spB+spB) + cterm*(spAB+spAB) +
514 dtrm1*(spB*spB)+ dtrm2*spB*spB*spA + dterm*(2*spAB*spB)
515 )*factor;
516 ds->df0300 += (vcfp2+ eterm*spB +
517 ctrm1*(spB+spB)+ ctrm2*spB*(spB+spB) + cterm*(spBB+spBB) +
518 dtrm1*(spB*spB)+ dtrm2*spB*spB*spB + dterm*(2*spBB*spB)
519 )*factor;
520 /* the final section: end */
521 }
522
523 /* The dispatch part of the functional implementation */
524 static real
vwn3_energy(const FunDensProp * dp)525 vwn3_energy(const FunDensProp* dp)
526 {
527 return par_energy(dp, &vwn3_paramagnetic, &vwn3_ferromagnetic);
528 }
529
530 static void
vwn3_first(FunFirstFuncDrv * ds,real factor,const FunDensProp * dp)531 vwn3_first(FunFirstFuncDrv *ds, real factor, const FunDensProp* dp)
532 {
533 par_first(ds, factor, dp, &vwn3_paramagnetic, &vwn3_ferromagnetic);
534 }
535
536 static void
vwn3_second(FunSecondFuncDrv * ds,real factor,const FunDensProp * dp)537 vwn3_second(FunSecondFuncDrv *ds, real factor, const FunDensProp* dp)
538 {
539 par_second(ds, factor, dp, &vwn3_paramagnetic, &vwn3_ferromagnetic);
540 }
541
542 static void
vwn3_third(FunThirdFuncDrv * ds,real factor,const FunDensProp * dp)543 vwn3_third(FunThirdFuncDrv *ds, real factor, const FunDensProp* dp)
544 {
545 par_third(ds, factor, dp, &vwn3_paramagnetic, &vwn3_ferromagnetic);
546 }
547
548
549 static real
vwn_energy(const FunDensProp * dp)550 vwn_energy(const FunDensProp* dp)
551 {
552 return par_energy(dp, &vwn_paramagnetic, &vwn_ferromagnetic);
553 }
554
555 static void
vwn_first(FunFirstFuncDrv * ds,real factor,const FunDensProp * dp)556 vwn_first(FunFirstFuncDrv *ds, real factor, const FunDensProp* dp)
557 {
558 par_first(ds, factor, dp, &vwn_paramagnetic, &vwn_ferromagnetic);
559 }
560
561 static void
vwn_second(FunSecondFuncDrv * ds,real factor,const FunDensProp * dp)562 vwn_second(FunSecondFuncDrv *ds, real factor, const FunDensProp* dp)
563 {
564 par_second(ds, factor, dp, &vwn_paramagnetic, &vwn_ferromagnetic);
565 }
566
567 static void
vwn_third(FunThirdFuncDrv * ds,real factor,const FunDensProp * dp)568 vwn_third(FunThirdFuncDrv *ds, real factor, const FunDensProp* dp)
569 {
570 par_third(ds, factor, dp, &vwn_paramagnetic, &vwn_ferromagnetic);
571 }
572
573 static void
vwn_fourth(FunFourthFuncDrv * ds,real factor,const FunDensProp * dp)574 vwn_fourth(FunFourthFuncDrv *ds, real factor, const FunDensProp* dp)
575 {
576 real zeta, zeta2, zeta3,zeta4, f_zeta, f_zet1, f_zet2, f_zet3, vcfp;
577 real delta, ep_p[6], ep_f[6], ep_i[6], d_ef0, d_ei0;
578 real vcfp1, vcfp2, ef0, ef1, ef2, ef3, ei0, ei1, ei2, ei3;
579 real bterm, cterm, dterm, eterm, ctrm1, ctrm2, dtrm1, dtrm2;
580 real ef2bi, ei2bi;
581 real spA, spB, spAA, spAB, spBB;
582 real rhoa = dp->rhoa, rhob = dp->rhob, rho = dp->rhoa + dp->rhob;
583 real rho2 = rho*rho;
584 real rho3 = rho2*rho;
585 real rho4 = rho2*rho2;
586 real f_zet4;
587 real ef4, ei4;
588 real spAAA, spBBB, spAAB, spABB;
589 real d_ef2bi, d_ei2bi, d_bterm_indep, d_bterm_dep, d_delta_indep,
590 d_delta_dep, d_vcfp2_indep, d_vcfp2_dep, d_eterm_indep,
591 d_eterm_dep, d_ctrm1_indep, d_ctrm1_dep, d_ctrm2_indep,
592 d_ctrm2_dep, d_cterm_indep, d_cterm_dep, d_dterm_indep,
593 d_dterm_dep, d_dtrm1_indep, d_dtrm1_dep, d_dtrm2_indep,
594 d_dtrm2_dep;
595
596 vwn_en_pot(ep_p, rho, 4, &vwn_paramagnetic);
597
598 ds->df1000 += ep_p[1]*factor;
599 ds->df0100 += ep_p[1]*factor;
600
601 ds->df2000 += ep_p[2]*factor;
602 ds->df0200 += ep_p[2]*factor;
603 ds->df1100 += ep_p[2]*factor;
604
605 ds->df3000 += ep_p[3]*factor;
606 ds->df2100 += ep_p[3]*factor;
607 ds->df1200 += ep_p[3]*factor;
608 ds->df0300 += ep_p[3]*factor;
609
610 ds->df4000 += ep_p[4]*factor;
611 ds->df3100 += ep_p[4]*factor;
612 ds->df2200 += ep_p[4]*factor;
613 ds->df1300 += ep_p[4]*factor;
614 ds->df0400 += ep_p[4]*factor;
615
616 /* if(dp->rhoa==dp->rhob) return; */
617 /* contribution from spin-polarized case; second order */
618 zeta = (dp->rhoa-dp->rhob)/rho;
619 zeta2 = zeta*zeta;
620 zeta3 = zeta2*zeta;
621 zeta4 = zeta3*zeta;
622 f_zeta = SPINPOLF* (POW(1+zeta,FOURTHREE)+POW(1-zeta,FOURTHREE)-2.0);
623 f_zet1 = SPINPOLF*4.0/3.0 *(POW(1+zeta, 1.0/3.0)-POW(1-zeta, 1.0/3.0));
624 f_zet2 = SPINPOLF*4.0/9.0 *(POW(1+zeta,-2.0/3.0)+POW(1-zeta,-2.0/3.0));
625 f_zet3 =-SPINPOLF*8.0/27.0*(POW(1+zeta,-5.0/3.0)-POW(1-zeta,-5.0/3.0));
626 f_zet4 = SPINPOLF*(40.0/81.0)*(POW(1-zeta,-8.0/3.0)+POW(1+zeta,-8.0/3.0));
627
628 vwn_en_pot(ep_f, rho, 4,&vwn_ferromagnetic);
629 ef0 = ep_f[0] - ep_p[0];
630 ef1 = ep_f[1] - ep_p[1];
631 ef2 = ep_f[2] - ep_p[2];
632 ef3 = ep_f[3] - ep_p[3];
633 ef4 = ep_f[4] - ep_p[4];
634 d_ef0 = ep_f[5] - ep_p[5];
635 vwn_en_pot(ep_i, rho, 4,&vwn_interp);
636 ei0 = ep_i[0]*THREEFTHRD2;
637 ei1 = ep_i[1]*THREEFTHRD2;
638 ei2 = ep_i[2]*THREEFTHRD2;
639 ei3 = ep_i[3]*THREEFTHRD2;
640 ei4 = ep_i[4]*THREEFTHRD2;
641 d_ei0 = ep_i[5]*THREEFTHRD2;
642
643
644 bterm = ef1*zeta4 + ei1*(1-zeta4);
645 vcfp = f_zeta*bterm;
646 delta = (f_zet1*(ef0*zeta4 + ei0*(1-zeta4))
647 + 4*f_zeta*(ef0 - ei0)*zeta3);
648
649 spA = 2*rhob/rho2; /* = 2(1-zeta)/rho */
650 spB =-2*rhoa/rho2; /* = -2(1+zeta)/rho */
651 spAA = -4*rhob/rho3;
652 spAB = 2*(rho-2*rhob)/rho3;
653 spBB = 4*rhoa/rho3;
654 spAAA = 12*rhob/rho4;
655 spAAB = -4*(rhoa - 2* rhob)/rho4;
656 spABB = (-8*rhoa + 4*rhob)/rho4;
657 spBBB = -12*rhoa/rho4;
658
659
660 /* contribution from spin-polarized case; second order */
661 /* spin independent part of vcfp */
662 vcfp1 = f_zeta*(ef2*zeta4 + ei2*(1-zeta4));
663 /* spin dependent part of vcfp */
664 cterm = 4*f_zeta*(ef1-ei1)*zeta3 + bterm*f_zet1 - delta;
665
666 /* spin dependent part of delta */
667 dterm = (f_zet2*(ef0*zeta4+ei0*(1-zeta4))
668 +8*f_zet1*(ef0-ei0)*zeta3
669 +12*f_zeta*(ef0-ei0)*zeta2)*rho;
670
671 /* third order terms */
672 vcfp2 = f_zeta*(ef3*zeta4+ei3*(1-zeta4));
673
674 eterm = f_zet1*(ef2*zeta4 + ei2*(1-zeta4)) + f_zeta*(ef2-ei2)*4*zeta3;
675
676 ef2bi = ef2-(ef1-ef0)/rho;
677 ei2bi = ei2-(ei1-ei0)/rho;
678 ctrm1 = 4*f_zeta*(ef2bi-ei2bi)*zeta3 +f_zet1*(ef2bi*zeta4+ei2bi*(1-zeta4));
679
680 ctrm2 = (ef1-ei1-ef0+ei0)*(8*f_zet1*zeta3+12*f_zeta*zeta2)
681 +f_zet2*(bterm-(ef0*zeta4 + ei0*(1-zeta4)));
682
683 dtrm1 = f_zet2*((ef1-ef0)*zeta4+(ei1-ei0)*(1-zeta4))
684 +(8*f_zet1*zeta3+12*f_zeta*zeta2)*(ef1-ei1-ef0+ei0)
685 +dterm/rho;
686 dtrm2 = ((12*f_zet2*zeta3 + 36*f_zet1*zeta2 + 24*f_zeta*zeta)*(ef0-ei0)+
687 f_zet3*(ef0*zeta4+ei0*(1-zeta4)))*rho;
688
689 /* the final section: begin */
690 ds->df1000 += (vcfp + delta*(1-zeta))*factor;
691 ds->df0100 += (vcfp - delta*(1+zeta))*factor;
692
693 ds->df2000 += (vcfp1+ cterm*(spA+spA) + dterm*spA*spA)*factor;
694 ds->df1100 += (vcfp1+ cterm*(spA+spB) + dterm*spA*spB)*factor;
695 ds->df0200 += (vcfp1+ cterm*(spB+spB) + dterm*spB*spB)*factor;
696
697 ds->df3000 += (vcfp2+ eterm*spA +
698 ctrm1*(spA+spA)+ ctrm2*spA*(spA+spA) + cterm*(spAA+spAA) +
699 dtrm1*(spA*spA)+ dtrm2*spA*spA*spA + dterm*(2*spAA*spA)
700 )*factor;
701 ds->df2100 += (vcfp2+ eterm*spB +
702 ctrm1*(spA+spA)+ ctrm2*spB*(spA+spA) + cterm*(spAB+spAB) +
703 dtrm1*(spA*spA)+ dtrm2*spA*spA*spB + dterm*(2*spAB*spA)
704 )*factor;
705 ds->df1200 += (vcfp2+ eterm*spA +
706 ctrm1*(spB+spB)+ ctrm2*spA*(spB+spB) + cterm*(spAB+spAB) +
707 dtrm1*(spB*spB)+ dtrm2*spB*spB*spA + dterm*(2*spAB*spB)
708 )*factor;
709 ds->df0300 += (vcfp2+ eterm*spB +
710 ctrm1*(spB+spB)+ ctrm2*spB*(spB+spB) + cterm*(spBB+spBB) +
711 dtrm1*(spB*spB)+ dtrm2*spB*spB*spB + dterm*(2*spBB*spB)
712 )*factor;
713
714 d_ef2bi = ef3 + (-ef0 + ef1)/rho2 - (-d_ef0 + ef2)/rho;
715 d_ei2bi = ei3 + (-ei0 + ei1)/rho2 - (-d_ei0 + ei2)/rho;
716
717
718 d_bterm_indep = ei2*(1 - zeta4) + ef2*zeta4;
719 d_bterm_dep = (4*ef1*zeta3 - 4*ei1*zeta3);
720
721
722 d_delta_indep = 4*(d_ef0 - d_ei0)*f_zeta*zeta3 +
723 d_ei0*f_zet1*(1 - zeta4) + d_ef0*f_zet1*zeta4;
724
725 d_delta_dep = (12*(ef0 - ei0)*f_zeta*zeta2 + 4*ef0*f_zet1*zeta3 +
726 4*(ef0 - ei0)*f_zet1*zeta3 - 4*ei0*f_zet1*zeta3 +
727 f_zet2*(ei0*(1 - zeta4) + ef0*zeta4));
728
729 d_vcfp2_indep = ei4*f_zeta*(1 - zeta4) + ef4*f_zeta*zeta4;
730
731 d_vcfp2_dep = (4*ef3*f_zeta*zeta3 - 4*ei3*f_zeta*zeta3 +
732 f_zet1*(ei3*(1 - zeta4) + ef3*zeta4));
733
734
735 d_eterm_indep = 4*(ef3 - ei3)*f_zeta*zeta3 + ei3*f_zet1*(1 - zeta4) +
736 ef3*f_zet1*zeta4;
737
738 d_eterm_dep = (12*(ef2 - ei2)*f_zeta*zeta2 +
739 4*ef2*f_zet1*zeta3 + 4*(ef2 - ei2)*f_zet1*zeta3 -
740 4*ei2*f_zet1*zeta3 + f_zet2*(ei2*(1 - zeta4) +
741 ef2*zeta4));
742
743
744 d_ctrm1_indep = 4*(d_ef2bi - d_ei2bi)*f_zeta*zeta3 +
745 d_ei2bi*f_zet1*(1 - zeta4) + d_ef2bi*f_zet1*zeta4;
746
747 d_ctrm1_dep = (12*(ef2bi - ei2bi)*f_zeta*zeta2 +
748 4*ef2bi*f_zet1*zeta3 + 4*(ef2bi - ei2bi)*f_zet1*zeta3 -
749 4*ei2bi*f_zet1*zeta3 + f_zet2*(ei2bi*(1 - zeta4) +
750 ef2bi*zeta4));
751
752
753 d_ctrm2_indep = d_bterm_indep*f_zet2 + (-d_ef0 + d_ei0 + ef2 - ei2)*
754 (12*f_zeta*zeta2 + 8*f_zet1*zeta3) +
755 d_ei0*f_zet2*(-1 + zeta4) - d_ef0*f_zet2*zeta4;
756
757 d_ctrm2_dep = d_bterm_dep*f_zet2 +
758 (4*(-ef0 + ei0)*f_zet2*zeta3 -
759 4*(ef0 - ef1 - ei0 + ei1)*(6*f_zeta*zeta +
760 9*f_zet1*zeta2 + 2*f_zet2*zeta3) +
761 f_zet3*(bterm + ei0*(-1 + zeta4) - ef0*zeta4));
762
763
764 d_cterm_indep = -d_delta_indep + d_bterm_indep*f_zet1 +
765 4*(ef2 - ei2)*f_zeta*zeta3;
766
767 d_cterm_dep = -d_delta_dep + d_bterm_dep*f_zet1 +
768 (bterm*f_zet2 + 12*(ef1 - ei1)*f_zeta*
769 zeta2 + 4*(ef1 - ei1)*f_zet1*zeta3);
770
771
772 d_dterm_indep = 12*(ef0 - ei0)*f_zeta*zeta2 + 12*d_ef0*f_zeta*rho*
773 zeta2 + 8*(ef0 - ei0)*f_zet1*zeta3 +
774 8*d_ef0*f_zet1*rho*zeta3 + d_ef0*f_zet2*rho*zeta4 +
775 f_zet2*(ei0 + ef0*zeta4 - ei0*zeta4) +
776 d_ei0*rho*(f_zet2 - 12*f_zeta*zeta2 - 8*f_zet1*zeta3 -
777 f_zet2*zeta4);
778
779 d_dterm_dep = (24*ef0*f_zeta*rho*zeta +
780 36*ef0*f_zet1*rho*zeta2 + 12*ef0*f_zet2*rho*zeta3 -
781 ei0*rho*(12*(2*f_zeta*zeta + 3*f_zet1*zeta2 +
782 f_zet2*zeta3) + f_zet3*(-1 + zeta4)) +
783 ef0*f_zet3*rho*zeta4);
784
785
786 d_dtrm1_indep = -(d_ei0*f_zet2) + ei2*f_zet2 +
787 (-d_ef0 + d_ei0 + ef2 - ei2)*(12*f_zeta*zeta2 +
788 8*f_zet1*zeta3) - d_ef0*f_zet2*zeta4 +
789 (d_ei0 + ef2 - ei2)*f_zet2*zeta4 -
790 dterm/rho2 + d_dterm_indep/rho;
791
792 d_dtrm1_dep = (4*(-ef0 + ef1 + ei0 - ei1)*f_zet2*zeta3 -
793 4*(ef0 - ef1 - ei0 + ei1)*(6*f_zeta*zeta +
794 9*f_zet1*zeta2 + 2*f_zet2*zeta3)
795 +
796 f_zet3*(ei1 + ei0*(-1 + zeta4) - (ef0 - ef1 + ei1)*zeta4))
797 + d_dterm_dep/rho;
798
799
800 d_dtrm2_indep = d_ei0*f_zet3*rho + 12*(ef0 - ei0)*
801 (2*f_zeta*zeta + 3*f_zet1*zeta2 + f_zet2*zeta3) +
802 12*(d_ef0 - d_ei0)*rho*(2*f_zeta*zeta + 3*f_zet1*zeta2 +
803 f_zet2*zeta3) + d_ef0*f_zet3*rho*zeta4 -
804 d_ei0*f_zet3*rho*zeta4 + f_zet3*(ei0 + ef0*zeta4 -
805 ei0*zeta4);
806
807 d_dtrm2_dep = (4*(ef0 - ei0)*f_zet3*rho*zeta3 +
808 12*(ef0 - ei0)*rho*(2*f_zeta + 8*f_zet1*zeta +
809 6*f_zet2*zeta2 + f_zet3*zeta3)
810 + f_zet4*rho*(ei0 + ef0*zeta4 - ei0*zeta4));
811
812 ds->df4000 += ( d_vcfp2_indep + 2*d_ctrm1_indep*spA + d_eterm_indep*spA +
813 d_vcfp2_dep*spA + 2*d_ctrm1_dep*spA*spA +
814 2*d_ctrm2_indep*spA*spA + d_dtrm1_indep*spA*spA +
815 d_eterm_dep*spA*spA + 2*d_ctrm2_dep*spA*spA*spA +
816 d_dtrm1_dep*spA*spA*spA + d_dtrm2_indep*spA*spA*spA +
817 d_dtrm2_dep*spA*spA*spA*spA + 2*d_cterm_indep*spAA +
818 2*d_cterm_dep*spA*spAA + 2*d_dterm_indep*spA*spAA +
819 2*d_dterm_dep*spA*spA*spAA + 2*spAAA*cterm +
820 2*spAA*ctrm1 + 4*spA*spAA*ctrm2 +
821 2*spAA*spAA*dterm + 2*spA*spAAA*dterm +
822 2*spA*spAA*dtrm1 + 3*spA*spA*spAA*dtrm2 +
823 spAA*eterm
824 )*factor;
825
826 ds->df3100 += ( d_vcfp2_indep + 2*d_ctrm1_indep*spA + d_eterm_indep*spA +
827 2*d_ctrm2_indep*spA*spA + d_dtrm1_indep*spA*spA +
828 d_dtrm2_indep*spA*spA*spA + 2*d_cterm_indep*spAA +
829 2*d_dterm_indep*spA*spAA + d_vcfp2_dep*spB +
830 2*d_ctrm1_dep*spA*spB + d_eterm_dep*spA*spB +
831 2*d_ctrm2_dep*spA*spA*spB + d_dtrm1_dep*spA*spA*spB +
832 d_dtrm2_dep*spA*spA*spA*spB + 2*d_cterm_dep*spAA*spB +
833 2*d_dterm_dep*spA*spAA*spB + 2*spAAB*cterm +
834 2*spAB*ctrm1 + 4*spA*spAB*ctrm2 +
835 2*spA*spAAB*dterm + 2*spAA*spAB*dterm +
836 2*spA*spAB*dtrm1 + 3*spA*spA*spAB*dtrm2 +
837 spAB*eterm
838 )*factor;
839
840 ds->df2200 += (d_vcfp2_indep + 2*d_ctrm1_indep*spA +
841 d_dtrm1_indep*spA*spA + 2*d_cterm_indep*spAB +
842 2*d_dterm_indep*spA*spAB + d_eterm_indep*spB +
843 d_vcfp2_dep*spB + 2*d_ctrm1_dep*spA*spB +
844 2*d_ctrm2_indep*spA*spB + d_dtrm1_dep*spA*spA*spB +
845 d_dtrm2_indep*spA*spA*spB + 2*d_cterm_dep*spAB*spB +
846 2*d_dterm_dep*spA*spAB*spB + d_eterm_dep*spB*spB +
847 2*d_ctrm2_dep*spA*spB*spB + d_dtrm2_dep*spA*spA*spB*spB +
848 2*spABB*cterm + 2*spAB*ctrm1 +
849 2*spAB*spB*ctrm2 + 2*spA*spBB*ctrm2 +
850 2*spAB*spAB*dterm + 2*spA*spABB*dterm +
851 2*spA*spAB*dtrm1 + 2*spA*spAB*spB*dtrm2 +
852 spA*spA*spBB*dtrm2 + spBB*eterm
853 )*factor;
854
855 ds->df1300 += ( d_vcfp2_indep + 2*d_ctrm1_indep*spB + d_eterm_indep*spB +
856 2*d_ctrm2_indep*spB*spB + d_dtrm1_indep*spB*spB +
857 d_dtrm2_indep*spB*spB*spB + 2*d_cterm_indep*spBB +
858 2*d_dterm_indep*spB*spBB + d_vcfp2_dep*spA +
859 2*d_ctrm1_dep*spB*spA + d_eterm_dep*spB*spA +
860 2*d_ctrm2_dep*spB*spB*spA + d_dtrm1_dep*spB*spB*spA +
861 d_dtrm2_dep*spB*spB*spB*spA + 2*d_cterm_dep*spBB*spA +
862 2*d_dterm_dep*spB*spBB*spA + 2*spABB*cterm +
863 2*spAB*ctrm1 + 4*spB*spAB*ctrm2 +
864 2*spB*spABB*dterm + 2*spBB*spAB*dterm +
865 2*spB*spAB*dtrm1 + 3*spB*spB*spAB*dtrm2 +
866 spAB*eterm
867 )*factor;
868
869 ds->df0400 += ( d_vcfp2_indep + 2*d_ctrm1_indep*spB + d_eterm_indep*spB +
870 d_vcfp2_dep*spB + 2*d_ctrm1_dep*spB*spB +
871 2*d_ctrm2_indep*spB*spB + d_dtrm1_indep*spB*spB +
872 d_eterm_dep*spB*spB + 2*d_ctrm2_dep*spB*spB*spB +
873 d_dtrm1_dep*spB*spB*spB + d_dtrm2_indep*spB*spB*spB +
874 d_dtrm2_dep*spB*spB*spB*spB + 2*d_cterm_indep*spBB +
875 2*d_cterm_dep*spB*spBB + 2*d_dterm_indep*spB*spBB +
876 2*d_dterm_dep*spB*spB*spBB + 2*spBBB*cterm +
877 2*spBB*ctrm1 + 4*spB*spBB*ctrm2 +
878 2*spBB*spBB*dterm + 2*spB*spBBB*dterm +
879 2*spB*spBB*dtrm1 + 3*spB*spB*spBB*dtrm2 +
880 spBB*eterm
881 )*factor;
882
883
884 /* the final section: end */
885 }
886
887
888 /* Other spin interpolation scheme */
889 static real
spni_energy(const FunDensProp * dp,const struct vwn_params * para,const struct vwn_params * ferro)890 spni_energy(const FunDensProp* dp, const struct vwn_params* para,
891 const struct vwn_params* ferro)
892 {
893 real ep_p[2], ep_f[2], ep_i[2], zeta, f_zeta, delta;
894 real rhoa = dp->rhoa, rhob = dp->rhob, rho;
895
896 if(rhoa<VWN_ZERO) rhoa = 1e-40;
897 if(rhob<VWN_ZERO) rhob = 1e-40;
898 rho = rhoa + rhob;
899 vwn_en_pot(ep_p, rho, 0, para);
900
901 if( FABS(dp->rhoa - dp->rhob)<VWN_ZERO) return ep_p[0]*rho;
902 vwn_en_pot(ep_f, rho, 0, ferro);
903 vwn_en_pot(ep_i, rho, 0, &vwn_interp);
904
905 zeta = (dp->rhoa-dp->rhob)/rho;
906 f_zeta = SPINPOLF*(POW(1+zeta,FOURTHREE)+POW(1-zeta,FOURTHREE)-2.0);
907 delta = f_zeta*(ep_f[0]-ep_p[0]);
908
909 return (ep_p[0]+ delta)*rho;
910 }
911
912 static void
spni_first(FunFirstFuncDrv * ds,real factor,const FunDensProp * dp,const struct vwn_params * para,const struct vwn_params * ferro)913 spni_first(FunFirstFuncDrv *ds, real factor, const FunDensProp* dp,
914 const struct vwn_params* para, const struct vwn_params* ferro)
915 {
916 real zeta, f_zeta, f_zet1, vcfp;
917 real delta, ep_p[2], ep_f[2];
918 real rhoa = dp->rhoa, rhob = dp->rhob, rho;
919
920 if(rhoa<VWN_ZERO) rhoa = 1e-40;
921 if(rhob<VWN_ZERO) rhob = 1e-40;
922 rho = rhoa + rhob;
923 vwn_en_pot(ep_p, rho, 1, para);
924
925 ds->df1000 += ep_p[1]*factor;
926 ds->df0100 += ep_p[1]*factor;
927
928 /* if(dp->rhoa==dp->rhob) return; */
929
930 /* contribution from spin-polarized case; first order */
931 zeta = (dp->rhoa-dp->rhob)/rho;
932 f_zeta = SPINPOLF*(POW(1+zeta,FOURTHREE)+POW(1-zeta,FOURTHREE)-2.0);
933 f_zet1 = SPINPOLF*4.0/3.0*(POW(1+zeta,1.0/3.0)-POW(1-zeta,1.0/3.0));
934 vwn_en_pot(ep_f, rho, 1, ferro);
935
936 vcfp = f_zeta*(ep_f[1] - ep_p[1]);
937 delta= f_zet1*(ep_f[0] - ep_p[0]);
938
939 /* the final section: begin */
940 ds->df1000 += (vcfp + delta*(1-zeta))*factor;
941 ds->df0100 += (vcfp - delta*(1+zeta))*factor;
942 /* the final section: end */
943 }
944
945 static void
spni_second(FunSecondFuncDrv * ds,real factor,const FunDensProp * dp,const struct vwn_params * para,const struct vwn_params * ferro)946 spni_second(FunSecondFuncDrv *ds, real factor, const FunDensProp* dp,
947 const struct vwn_params* para, const struct vwn_params* ferro)
948 {
949 real zeta, f_zeta, f_zet1, f_zet2, vcfp;
950 real delta, ep_p[3], ep_f[3];
951 real rhoa = dp->rhoa, rhob = dp->rhob, rho = dp->rhoa + dp->rhob;
952 real rho2 = rho*rho;
953 real vcf2, fac2, vap2, ef0, ef1, ef2;
954 real zA, zB, zAAr, zABr, zBBr;
955
956 vwn_en_pot(ep_p, rho, 2, para);
957
958 ds->df1000 += ep_p[1]*factor;
959 ds->df0100 += ep_p[1]*factor;
960 ds->df2000 += ep_p[2]*factor;
961 ds->df1100 += ep_p[2]*factor;
962 ds->df0200 += ep_p[2]*factor;
963
964 /* if( fabs(rhoa - rhob)<VWN_ZERO) return; */
965 /* contribution from spin-polarized case; first order */
966 zeta = (rhoa - rhob)/rho;
967 f_zeta = SPINPOLF*(POW(1+zeta,FOURTHREE)+POW(1-zeta,FOURTHREE)-2.0);
968 f_zet1 = SPINPOLF*4.0/3.0*(POW(1+zeta, 1.0/3.0)-POW(1-zeta, 1.0/3.0));
969 f_zet2 = SPINPOLF*4.0/9.0*(POW(1+zeta,-2.0/3.0)+POW(1-zeta,-2.0/3.0));
970 vwn_en_pot(ep_f, rho, 2, ferro);
971
972 ef0 = ep_f[0] - ep_p[0];
973 ef1 = ep_f[1] - ep_p[1];
974 ef2 = ep_f[2] - ep_p[2];
975 vcfp = f_zeta*ef1;
976 delta= f_zet1*ef0;
977
978 vcf2 = f_zeta*ef2;
979 vap2 = f_zet1*ef1;
980 fac2 = f_zet2*ef0*rho;
981 zA = 2*rhob/rho2;
982 zB = -2*rhoa/rho2;
983 zAAr = -4*rhob/rho2;
984 zABr = 2*zeta/rho;
985 zBBr = 4*rhoa/rho2;
986
987 /* the final section: begin */
988 ds->df1000 += (vcfp + delta*rho*zA)*factor;
989 ds->df0100 += (vcfp - delta*(1+zeta))*factor;
990
991 ds->df2000 += (vcf2 + vap2*(zA+zA) + fac2*zA*zA + delta*zAAr)*factor;
992 ds->df1100 += (vcf2 + vap2*(zA+zB) +fac2*zA*zB + delta*zABr)*factor;
993 ds->df0200 += (vcf2 + vap2*(zB+zB) + fac2*zB*zB + delta*zBBr)*factor;
994 /* the final section: end */
995 }
996
997 static real
vwni_energy(const FunDensProp * dp)998 vwni_energy(const FunDensProp* dp)
999 {
1000 return spni_energy(dp, &vwn_paramagnetic, &vwn_ferromagnetic);
1001 }
1002
1003 static void
vwni_first(FunFirstFuncDrv * ds,real factor,const FunDensProp * dp)1004 vwni_first(FunFirstFuncDrv *ds, real factor, const FunDensProp* dp)
1005 {
1006 spni_first(ds, factor, dp, &vwn_paramagnetic, &vwn_ferromagnetic);
1007 }
1008
1009 static void
vwni_second(FunSecondFuncDrv * ds,real factor,const FunDensProp * dp)1010 vwni_second(FunSecondFuncDrv *ds, real factor, const FunDensProp* dp)
1011 {
1012 spni_second(ds, factor, dp, &vwn_paramagnetic, &vwn_ferromagnetic);
1013 }
1014
1015 static void
vwni_third(FunThirdFuncDrv * ds,real factor,const FunDensProp * dp)1016 vwni_third(FunThirdFuncDrv *ds, real factor, const FunDensProp* dp)
1017 {
1018 fun_printf("vwni_third not implemented."); exit(1);
1019 }
1020
1021 static real
vwn3i_energy(const FunDensProp * dp)1022 vwn3i_energy(const FunDensProp* dp)
1023 {
1024 return spni_energy(dp, &vwn3_paramagnetic, &vwn3_ferromagnetic);
1025 }
1026
1027 static void
vwn3i_first(FunFirstFuncDrv * ds,real factor,const FunDensProp * dp)1028 vwn3i_first(FunFirstFuncDrv *ds, real factor, const FunDensProp* dp)
1029 {
1030 spni_first(ds, factor, dp, &vwn3_paramagnetic, &vwn3_ferromagnetic);
1031 }
1032
1033 static void
vwn3i_second(FunSecondFuncDrv * ds,real factor,const FunDensProp * dp)1034 vwn3i_second(FunSecondFuncDrv *ds, real factor, const FunDensProp* dp)
1035 {
1036 spni_second(ds, factor, dp, &vwn3_paramagnetic, &vwn3_ferromagnetic);
1037 }
1038
1039 static void
vwn3i_third(FunThirdFuncDrv * ds,real factor,const FunDensProp * dp)1040 vwn3i_third(FunThirdFuncDrv *ds, real factor, const FunDensProp* dp)
1041 {
1042 fun_printf("vwni_third not implemented."); exit(1);
1043 }
1044