MADNESS  version 0.9
DFcode/xcfunctional.h
Go to the documentation of this file.
1 #ifndef MOLDFT_XCMOLDFT_H
2 #define MOLDFT_XCMOLDFT_H
3 
5 
9 
10 #include <madness/tensor/tensor.h>
11 #include <vector>
12 #include <algorithm>
13 #include <utility>
14 #include <madness/mra/key.h>
15 
16 #ifdef MADNESS_HAS_LIBXC
17 #include <xc.h>
18 #endif
19 
23 
24  void operator()(const madness::Key<3> & key, madness::Tensor<double>& t) const
25  {
26  int x_rks_s__(const double *r__, double *f, double * dfdra);
27  int c_rks_vwn5__(const double *r__, double *f, double * dfdra);
28  double* rho = t.ptr();
29  for (int i=0; i<t.size(); i++) {
30  double r = std::max(rho[i],1e-12);
31  double q, dq1, dq2;
32  x_rks_s__(&r, &q, &dq1);
33  c_rks_vwn5__(&r, &q, &dq2);
34  rho[i] = dq1 + dq2;
35  }
36  }
37 };
38 
39 #ifdef MADNESS_HAS_MADXC
40 //#error
41 struct xc_func_type {
42  int number; /* indentifier number */
43  bool nspin; /* XC_UNPOLARIZED or XC_POLARIZED */
44  int kind; /* XC_EXCHANGE, XC_CORRELATION, or XC_EXCHANGE_CORRELATION */
45  std::string name; /* name of the functional, e.g. "PBE" */
46  int family; /* type of the functional, e.g. XC_FAMILY_GGA */
47  double coef; /* coefficient */
48 };
49 #endif
50 
52 class XCfunctional {
53 protected:
55  double hf_coeff;
56 #if defined(MADNESS_HAS_MADXC) ||defined( MADNESS_HAS_LIBXC)
57  std::vector< std::pair<xc_func_type*,double> > funcs;
58  int nderiv;
59 #endif
60 
61 #ifdef MADNESS_HAS_LIBXC
62  void make_libxc_args(const std::vector< madness::Tensor<double> >& t,
63  madness::Tensor<double>& rho,
64  madness::Tensor<double>& sigma,
65  madness::Tensor<double>& delrho) const;
66 #endif
67 
68 #ifdef MADNESS_HAS_MADXC
69  void make_xc_args(const std::vector< madness::Tensor<double> >& t,
70  std::vector< madness::Tensor<double> >& rho,
71  std::vector< madness::Tensor<double> >& sigma,
72  std::vector< madness::Tensor<double> >& delrho) const;
73 #endif
74 
76 
90  static void polyn(const double x, double& p, double& dpdx) {
91  // All of the static const stuff is evaluated at compile time
92 
93  static const double xmin = 1e-10; // <<<< MINIMUM VALUE OF DENSITY
94  static const double xmax = 1e-8; // <<<< DENSITY SMOOTHLY MODIFIED BELOW THIS VALUE
95 
96  static const double xmax2 = xmax*xmax;
97  static const double xmax3 = xmax2*xmax;
98  static const double xmin2 = xmin*xmin;
99  static const double xmin3 = xmin2*xmin;
100  static const double r = 1.0/((xmax-xmin)*(-xmin3+(3.0*xmin2+(-3.0*xmin+xmax)*xmax)*xmax));
101  static const double a0 = xmax3*xmin*(xmax-4.0*xmin)*r;
102  static const double a = xmin2*(xmin2+(-4.0*xmin+18.0*xmax)*xmax)*r;
103  static const double b = -6.0*xmin*xmax*(3.0*xmax+2.0*xmin)*r;
104  static const double c = (4.0*xmin2+(20.0*xmin+6.0*xmax)*xmax)*r;
105  static const double d = -(8.0*xmax+7.0*xmin)*r;
106  static const double e = 3.0*r;
107 
108  if (x > xmax) {
109  p = x;
110  dpdx = 1.0;
111  }
112  else if (x < xmin) {
113  p = xmin;
114  dpdx = 0.0;
115  }
116  else {
117  p = a0+(a+(b+(c+(d+e*x)*x)*x)*x)*x;
118  dpdx = a+(2.0*b+(3.0*c+(4.0*d+5.0*e*x)*x)*x)*x;
119  }
120  }
121 
122  static double munge(double rho) {
123  double p, dpdx;
124  polyn(rho, p, dpdx);
125  return p;
126  }
127 
128  static void munge2(double& rho, double& sigma) {
129  // rho(x) --> p(rho(x))
130  // d/dx p(rho(x)) --> dp/drho * drho/dx
131  if (sigma < 0.0) sigma = 0.0;
132  double p, dpdx;
133  polyn(rho, p, dpdx);
134  rho = p;
135  sigma *= dpdx*dpdx;
136  }
137  static void munge_der(double& rhoa, double& sigma, double& drx, double& dry, double& drz) {
138  // rho(x) --> p(rho(x))
139  // d/dx p(rho(x)) --> dp/drho * drho/dx
140  if (sigma < 0.0) sigma = 0.0;
141  double p, dpdx;
142  polyn(rhoa, p, dpdx);
143  rhoa = p;
144  sigma *= dpdx*dpdx;
145  drx *=dpdx;
146  dry *=dpdx;
147  drz *=dpdx;
148  }
149  static void munge5(double& rhoa, double& rhob, double& saa, double& sab, double& sbb) {
150  // rho(x) --> p(rho(x))
151  // d/dx p(rho(x)) --> dp/drho * drho/dx
152  if (saa < 0.0) saa = 0.0;
153  if (sab < 0.0) sab = 0.0;
154  if (sbb < 0.0) sbb = 0.0;
155  double pa, pb, dpadx, dpbdx;
156  polyn(rhoa, pa, dpadx);
157  polyn(rhob, pb, dpbdx);
158  rhoa = pa;
159  rhob = pb;
160  saa *= dpadx*dpadx;
161  sab *= dpadx*dpbdx;
162  sbb *= dpbdx*dpbdx;
163  }
164  static void munge5_der(double& rhoa, double& rhob, double& saa, double& sab, double& sbb,
165  double& drax, double& dray, double& draz,
166  double& drbx, double& drby, double& drbz) {
167  // rho(x) --> p(rho(x))
168  // d/dx p(rho(x)) --> dp/drho * drho/dx
169  if (saa < 0.0) saa = 0.0;
170  if (sab < 0.0) sab = 0.0;
171  if (sbb < 0.0) sbb = 0.0;
172  double pa, pb, dpadx, dpbdx;
173  polyn(rhoa, pa, dpadx);
174  polyn(rhob, pb, dpbdx);
175  rhoa = pa;
176  rhob = pb;
177  saa *= dpadx*dpadx;
178  sab *= dpadx*dpbdx;
179  sbb *= dpbdx*dpbdx;
180 
181  drax *=dpadx;
182  dray *=dpadx;
183  draz *=dpadx;
184 
185  drbx *=dpbdx;
186  drby *=dpbdx;
187  drbz *=dpbdx;
188  }
189 
190 public:
192  XCfunctional();
193 
195 
198  void initialize(const std::string& input_line, bool polarized);
199 
201  ~XCfunctional();
202 
204  bool is_lda() const;
205 
207  bool is_gga() const;
208 
210  bool is_meta() const;
211 
213  bool is_dft() const;
214 
216  bool is_spin_polarized() const
217  {
218  return spin_polarized;
219  }
220 
222  bool has_fxc() const;
223 
225  bool has_kxc() const;
226 
228  double hf_exchange_coefficient() const
229  {
230  return hf_coeff;
231  }
232 
234 
252  madness::Tensor<double> exc(const std::vector< madness::Tensor<double> >& t , const int ispin) const;
253 
255 
298  madness::Tensor<double> vxc(const std::vector< madness::Tensor<double> >& t, const int ispin, const int what) const;
299 
301  void plot() const {
302  long npt = 1001;
303  double lo=1e-6, hi=1e+1, s=std::pow(hi/lo, 1.0/(npt-1));
304 
305  madness::Tensor<double> rho(npt);
306  for (int i=0; i<npt; i++) {
307  rho[i] = lo;
308  lo *= s;
309  }
310  std::vector< madness::Tensor<double> > t;
311  t.push_back(rho);
312  if (is_spin_polarized()) t.push_back(rho);
313  madness::Tensor<double> f = exc(t,0); //pending UGHHHHH
314  madness::Tensor<double> va = vxc(t,0,0);
315  madness::Tensor<double> vb = vxc(t,0,1);
316  for (long i=0; i<npt; i++) {
317  printf("%.3e %.3e %.3e %.3e\n", rho[i], f[i], va[i], vb[i]);
318  }
319  }
320 };
321 
324  const XCfunctional* xc;
325  const int ispin;
326 
327  xc_functional(const XCfunctional& xc, int ispin)
328  : xc(&xc), ispin(ispin)
329  {}
330 
331  madness::Tensor<double> operator()(const madness::Key<3> & key, const std::vector< madness::Tensor<double> >& t) const
332  {
333  MADNESS_ASSERT(xc);
334  return xc->exc(t,ispin);
335  }
336 };
337 
339 struct xc_potential {
340  const XCfunctional* xc;
341  const int what;
342  const int ispin;
343 
344  xc_potential(const XCfunctional& xc, int ispin,int what)
345  : xc(&xc), what(what), ispin(ispin)
346  {}
347 
348  madness::Tensor<double> operator()(const madness::Key<3> & key, const std::vector< madness::Tensor<double> >& t) const
349  {
350  MADNESS_ASSERT(xc);
351  madness::Tensor<double> r = xc->vxc(t, ispin, what);
352  return r;
353  }
354 };
355 
356 #endif
const XCfunctional * xc
Definition: DFcode/xcfunctional.h:324
const int ispin
Definition: DFcode/xcfunctional.h:325
int x_rks_s__(const double *r__, double *f, double *dfdra)
Definition: chem/lda.cc:58
madness::Tensor< double > exc(const std::vector< madness::Tensor< double > > &t, const int ispin) const
Computes the energy functional at given points.
Definition: DFcode/xcfunctional_ldaonly.cc:61
Class to compute the energy functional.
Definition: DFcode/xcfunctional.h:323
bool is_spin_polarized() const
Returns true if the functional is spin_polarized.
Definition: DFcode/xcfunctional.h:216
static double munge(double rho)
Definition: DFcode/xcfunctional.h:122
const int ispin
Definition: DFcode/xcfunctional.h:342
static void munge2(double &rho, double &sigma)
Definition: DFcode/xcfunctional.h:128
const double sigma
Definition: dielectric.cc:187
Class to compute terms of the potential.
Definition: DFcode/xcfunctional.h:339
bool is_gga() const
Returns true if the potential is gga (needs first derivatives)
Definition: DFcode/xcfunctional_ldaonly.cc:39
::std::string string
Definition: gtest-port.h:872
xc_potential(const XCfunctional &xc, int ispin, int what)
Definition: DFcode/xcfunctional.h:344
Simplified interface to XC functionals.
Definition: DFcode/xcfunctional.h:52
NDIM & f
Definition: mra.h:2179
static void munge5_der(double &rhoa, double &rhob, double &saa, double &sab, double &sbb, double &drax, double &dray, double &draz, double &drbx, double &drby, double &drbz)
Definition: DFcode/xcfunctional.h:164
bool has_fxc() const
Returns true if the second derivative of the functional is available (not yet supported) ...
Definition: DFcode/xcfunctional_ldaonly.cc:51
bool is_meta() const
Returns true if the potential is meta gga (needs second derivatives ... not yet supported) ...
Definition: DFcode/xcfunctional_ldaonly.cc:43
XCfunctional()
Default constructor is required.
Definition: DFcode/xcfunctional_ldaonly.cc:14
Defines and implements most of Tensor.
madness::Tensor< double > vxc(const std::vector< madness::Tensor< double > > &t, const int ispin, const int what) const
Computes components of the potential (derivative of the energy functional) at np points.
Definition: DFcode/xcfunctional_ldaonly.cc:93
bool has_kxc() const
Returns true if the third derivative of the functional is available (not yet supported) ...
Definition: DFcode/xcfunctional_ldaonly.cc:56
#define max(a, b)
Definition: lda.h:53
madness::Tensor< double > operator()(const madness::Key< 3 > &key, const std::vector< madness::Tensor< double > > &t) const
Definition: DFcode/xcfunctional.h:348
void operator()(const madness::Key< 3 > &key, madness::Tensor< double > &t) const
Definition: DFcode/xcfunctional.h:24
bool spin_polarized
True if the functional is spin polarized.
Definition: DFcode/xcfunctional.h:54
FLOAT a(int j, FLOAT z)
Definition: y1.cc:86
double hf_exchange_coefficient() const
Returns the value of the hf exact exchange coefficient.
Definition: DFcode/xcfunctional.h:228
static void polyn(const double x, double &p, double &dpdx)
Smoothly switches between constant (xxmax)
Definition: DFcode/xcfunctional.h:90
static void munge_der(double &rhoa, double &sigma, double &drx, double &dry, double &drz)
Definition: DFcode/xcfunctional.h:137
~XCfunctional()
Destructor.
Definition: DFcode/xcfunctional_ldaonly.cc:32
bool is_lda() const
Returns true if the potential is lda.
Definition: DFcode/xcfunctional_ldaonly.cc:35
void initialize(const std::string &input_line, bool polarized)
Initialize the object from the user input data.
Definition: DFcode/xcfunctional_ldaonly.cc:16
int c_rks_vwn5__(const double *r__, double *f, double *dfdra)
Definition: chem/lda.cc:116
void plot() const
Crude function to plot the energy and potential functionals.
Definition: DFcode/xcfunctional.h:301
bool is_dft() const
Returns true if there is a DFT functional (false probably means Hatree-Fock exchange only) ...
Definition: DFcode/xcfunctional_ldaonly.cc:47
Compute the spin-restricted LDA potential using unaryop (only for the initial guess) ...
Definition: DFcode/xcfunctional.h:21
double hf_coeff
Factor multiplying HF exchange (+1.0 gives HF)
Definition: DFcode/xcfunctional.h:55
const int what
Definition: DFcode/xcfunctional.h:341
xc_functional(const XCfunctional &xc, int ispin)
Definition: DFcode/xcfunctional.h:327
xc_lda_potential()
Definition: DFcode/xcfunctional.h:22
madness::Tensor< double > operator()(const madness::Key< 3 > &key, const std::vector< madness::Tensor< double > > &t) const
Definition: DFcode/xcfunctional.h:331
Multidimension Key for MRA tree and associated iterators.
const double c
Definition: gfit.cc:200
FLOAT b(int j, FLOAT z)
Definition: y1.cc:79
Key is the index for a node of the 2^NDIM-tree.
Definition: key.h:69
static void munge5(double &rhoa, double &rhob, double &saa, double &sab, double &sbb)
Definition: DFcode/xcfunctional.h:149
const XCfunctional * xc
Definition: DFcode/xcfunctional.h:340