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