QMCPACK
LRBreakupUtilities.h
Go to the documentation of this file.
1 //////////////////////////////////////////////////////////////////////////////////////
2 // This file is distributed under the University of Illinois/NCSA Open Source License.
3 // See LICENSE file in top directory for details.
4 //
5 // Copyright (c) 2016 Jeongnim Kim and QMCPACK developers.
6 //
7 // File developed by: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
8 // Miguel Morales, moralessilva2@llnl.gov, Lawrence Livermore National Laboratory
9 // Jeremy McMinnis, jmcminis@gmail.com, University of Illinois at Urbana-Champaign
10 // Mark A. Berrill, berrillma@ornl.gov, Oak Ridge National Laboratory
11 //
12 // File created by: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
13 //////////////////////////////////////////////////////////////////////////////////////
14 
15 
16 /** @file
17  * @brief Define a LRHandler with two template parameters
18  */
19 #ifndef QMCPLUSPLUS_LONGRANGEJASTROW_BREAKUPUTILITY_H
20 #define QMCPLUSPLUS_LONGRANGEJASTROW_BREAKUPUTILITY_H
21 
22 #include "OptimizableFunctorBase.h"
23 
24 namespace qmcplusplus
25 {
26 /** RPABreakUp
27  *
28  * A Func for LRHandlerTemp. Four member functions have to be provided
29  *
30  * - reset(T volume) : reset the normalization factor
31  * - operator() (T r, T rinv) const : return a value of the original function e.g., 1.0/r
32  * - Fk(T k, T rc)
33  * - Xk(T k, T rc)
34  *
35  */
36 template<class T = double>
38 {
39  T Rs;
40  T SqrtRs;
43  inline YukawaBreakup() {}
44 
45  void reset(ParticleSet& ref)
46  {
47  NormFactor = 4.0 * M_PI / ref.getLattice().Volume;
48  T Density = ref.getTotalNum() / ref.getLattice().Volume;
49  Rs = std::pow(3.0 / (4.0 * M_PI * Density), 1.0 / 3.0);
50  SqrtRs = std::sqrt(Rs);
51  OneOverSqrtRs = 1.0 / SqrtRs;
52  }
53 
54  void reset(ParticleSet& ref, T rs)
55  {
56  NormFactor = 4.0 * M_PI / ref.getLattice().Volume;
57  //NormFactor*=(rs*rs*rs)/(Rs*Rs*Rs);
58  Rs = rs;
59  SqrtRs = std::sqrt(Rs);
60  OneOverSqrtRs = 1.0 / SqrtRs;
61  }
62 
63 
64  inline T operator()(T r, T rinv) const
65  {
66  if (r < std::numeric_limits<T>::epsilon())
67  return SqrtRs - 0.5 * r;
68  else
69  return Rs * rinv * (1.0 - std::exp(-r * OneOverSqrtRs));
70  //if (r > 1e-10) return Rs*rinv*(1.0 - std::exp(-r*OneOverSqrtRs));
71  //return 1.0 / OneOverSqrtRs - 0.5 * r;
72  }
73 
74  inline T df(T r) const
75  {
76  if (r < std::numeric_limits<T>::epsilon())
77  return -0.5 + r * OneOverSqrtRs / 3.0;
78  else
79  {
80  T rinv = 1.0 / r;
81  T exponential = std::exp(-r * OneOverSqrtRs);
82  return -Rs * rinv * rinv * (1.0 - exponential) + exponential * rinv * SqrtRs;
83  }
84  }
85 
86  inline T Fk(T k, T rc) const { return -Xk(k, rc); }
87 
88  inline T Xk(T k, T rc) const
89  {
90  T coskr = std::cos(k * rc);
91  T sinkr = std::sin(k * rc);
92  T oneOverK = 1.0 / k;
93  return -NormFactor * Rs *
94  (coskr * oneOverK * oneOverK -
95  std::exp(-rc * OneOverSqrtRs) * (coskr - OneOverSqrtRs * sinkr * oneOverK) / (k * k + 1.0 / Rs));
96  }
97 
98  inline T integrate_r2(T rc) const { return 0.0; }
99 
100  /** return RPA value at |k|
101  * @param kk |k|^2
102  */
103  inline T Uk(T kk) const { return NormFactor * Rs / kk; }
104 
105  /** return d u(k)/d rs
106  *
107  * Implement a correct one
108  */
109  inline T derivUk(T kk) const { return NormFactor / kk; }
110 };
111 
112 template<class T = double>
114 {
115  T Rs;
116  T Kf;
119  inline DerivRPABreakup() {}
120 
121  void reset(ParticleSet& ref)
122  {
123  // NormFactor= 4.0*M_PI/ref.getLattice().Volume;
124  // NormFactor=4.0*M_PI/ref.getTotalNum();
125  NormFactor = 1.0 / ref.getTotalNum();
126  Density = ref.getTotalNum() / ref.getLattice().Volume;
127  Rs = std::pow(3.0 / (4.0 * M_PI * Density), 1.0 / 3.0);
128  //unpolarized K_f
129  Kf = std::pow(2.25 * M_PI, 1.0 / 3.0) / Rs;
130  }
131 
132  void reset(ParticleSet& ref, T rs)
133  {
134  // NormFactor=4.0*M_PI/ref.getLattice().Volume;
135  NormFactor = 1.0 / ref.getTotalNum();
136  // NormFactor=4.0*M_PI/ref.getTotalNum();
137  Density = ref.getTotalNum() / ref.getLattice().Volume;
138  Rs = rs;
139  //unpolarized
140  Kf = std::pow(2.25 * M_PI, 1.0 / 3.0) / Rs;
141  }
142 
143 
144  inline T operator()(T r, T rinv) const { return 0.0; }
145 
146  inline T df(T r) const { return 0.0; }
147 
148  inline T Fk(T k, T rc) const { return -Xk(k, rc); }
149 
150  inline T Xk(T k, T rc) const
151  {
152  T y = 0.5 * k / Kf;
153  T Sy;
154  if (y >= 1.0)
155  {
156  Sy = 1.0;
157  }
158  else
159  {
160  Sy = 1.5 * y - 0.5 * y * y * y;
161  };
162  //multiply by NORM?
163  return NormFactor * 3.0 /
164  ((k * k * k * k * Rs * Rs * Rs * Rs *
165  (std::pow(1.0 / (Sy * Sy) + 12.0 / (k * k * k * k * Rs * Rs * Rs), 0.5))));
166  }
167 
168  inline T integrate_r2(T rc) const { return 0.0; }
169  /** return RPA value at |k|
170  * @param kk |k|^2
171  */
172  inline T Uk(T kk) const { return NormFactor * Rs / kk; }
173 
174  /** return d u(k)/d rs
175  *
176  * Implement a correct one
177  */
178  inline T derivUk(T kk) const { return 0.0; }
179 };
180 
181 
182 template<class T = double>
184 {
185  T Rs;
186  T Kf;
189  inline RPABreakup() {}
190 
191  void reset(ParticleSet& ref)
192  {
193  // NormFactor= 4.0*M_PI/ref.getLattice().Volume;
194  // NormFactor=4.0*M_PI/ref.getTotalNum();
195  NormFactor = 1.0 / ref.getTotalNum();
196  Density = ref.getTotalNum() / ref.getLattice().Volume;
197  Rs = std::pow(3.0 / (4.0 * M_PI * Density), 1.0 / 3.0);
198  //unpolarized K_f
199  Kf = std::pow(2.25 * M_PI, 1.0 / 3.0) / Rs;
200  }
201 
202  void reset(ParticleSet& ref, T rs)
203  {
204  // NormFactor=4.0*M_PI/ref.getLattice().Volume;
205  NormFactor = 1.0 / ref.getTotalNum();
206  // NormFactor=4.0*M_PI/ref.getTotalNum();
207  Density = ref.getTotalNum() / ref.getLattice().Volume;
208  Rs = rs;
209  //unpolarized
210  Kf = std::pow(2.25 * M_PI, 1.0 / 3.0) / Rs;
211  }
212 
213 
214  inline T operator()(T r, T rinv) const { return 0.0; }
215 
216  inline T df(T r) const { return 0.0; }
217 
218  inline T Fk(T k, T rc) const { return -Xk(k, rc); }
219 
220  inline T Xk(T k, T rc) const
221  {
222  T y = 0.5 * k / Kf;
223  T Sy;
224  if (y >= 1.0)
225  {
226  Sy = 1.0;
227  }
228  else
229  {
230  Sy = 1.5 * y - 0.5 * y * y * y;
231  };
232  //multiply by NORM?
233  return NormFactor * (0.5 * (-1.0 / Sy + std::pow(1.0 / (Sy * Sy) + 12.0 / (k * k * k * k * Rs * Rs * Rs), 0.5)));
234  }
235 
236  inline T integrate_r2(T rc) const { return 0.0; }
237 
238  /** return RPA value at |k|
239  * @param kk |k|^2
240  */
241  inline T Uk(T kk) const { return NormFactor * Rs / kk; }
242 
243  /** return d u(k)/d rs
244  *
245  * Implement a correct one
246  */
247  inline T derivUk(T kk) const { return 0.0; }
248 };
249 
250 
251 template<class T = double>
253 {
254  T Rc;
255  T Rs;
262  T n2;
263 
264  inline DerivYukawaBreakup() {}
265 
266  void reset(ParticleSet& ref)
267  {
268  NormFactor = 4.0 * M_PI / ref.getLattice().Volume;
269  T Density = ref.getTotalNum() / ref.getLattice().Volume;
270  n2 = ref.getTotalNum();
271  Rs = std::pow(3.0 / (4.0 * M_PI * Density), 1.0 / 3.0);
272  SqrtRs = std::sqrt(Rs);
273  OneOverSqrtRs = 1.0 / SqrtRs;
275  OneOverRs = 1.0 / Rs;
276  DerivSecondTaylorTerm = (1.0 / 12.0) * OneOverSqrtRs3;
277  Rc = ref.getLattice().LR_rc;
278  }
279 
280  void reset(ParticleSet& ref, T rs)
281  {
282  Rs = rs;
283  NormFactor = 4.0 * M_PI / ref.getLattice().Volume;
284  n2 = ref.getTotalNum();
285  SqrtRs = std::sqrt(Rs);
286  OneOverSqrtRs = 1.0 / SqrtRs;
288  OneOverRs = 1.0 / Rs;
289  DerivSecondTaylorTerm = (1.0 / 12.0) * OneOverSqrtRs3;
290  }
291 
292  /** need the df(r)/d(rs) */
293  inline T operator()(T r, T rinv) const
294  {
295  if (r < std::numeric_limits<T>::epsilon())
296  return 0.5 * OneOverSqrtRs * (1.0 - r * OneOverSqrtRs);
297  else
298  {
299  return 0.5 * OneOverSqrtRs * std::exp(-r * OneOverSqrtRs);
300  }
301  }
302 
303  /** need d(df(r)/d(rs))/dr */
304  inline T df(T r) const
305  {
306  if (r < std::numeric_limits<T>::epsilon())
307  return -0.5 * OneOverRs * (1.0 - r * OneOverSqrtRs);
308  else
309  {
310  return -0.5 * OneOverRs * std::exp(-r * OneOverSqrtRs);
311  }
312  }
313 
314  inline T integrate_r2(T rc) const { return 0.0; }
315 
316  inline T Fk(T k, T rc) const { return -Xk(k, rc); }
317 
318  /** integral from kc to infinity */
319  inline T Xk(T k, T rc) const
320  {
321  T Rc = rc;
322  T coskr = std::cos(k * Rc);
323  T sinkr = std::sin(k * Rc);
324  T oneOverK = 1.0 / k;
325  T Val = (-0.5 * NormFactor * OneOverSqrtRs * oneOverK) *
326  (1.0 / ((1.0 + k * k * Rs) * (1.0 + k * k * Rs)) * std::exp(-rc * OneOverSqrtRs) * SqrtRs *
327  (k * SqrtRs * (rc + 2.0 * SqrtRs + k * k * rc * Rs) * coskr +
328  (rc + k * k * rc * Rs + SqrtRs * (1.0 - k * k * Rs)) * sinkr));
329  return Val;
330  }
331 };
332 
333 template<class T = double>
335 {
336  T Rs;
337  T Kf;
340  inline EPRPABreakup() {}
341 
342  void reset(ParticleSet& ref)
343  {
344  NormFactor = 1.0 / ref.getTotalNum();
345  Density = ref.getTotalNum() / ref.getLattice().Volume;
346  Rs = std::pow(3.0 / (4.0 * M_PI * Density), 1.0 / 3.0);
347  //unpolarized K_f
348  Kf = std::pow(2.25 * M_PI, 1.0 / 3.0) / Rs;
349  }
350 
351  void reset(ParticleSet& ref, T rs)
352  {
353  // NormFactor=4.0*M_PI/ref.getLattice().Volume;
354  NormFactor = 1.0 / ref.getTotalNum();
355  // NormFactor=4.0*M_PI/ref.getTotalNum();
356  Density = ref.getTotalNum() / ref.getLattice().Volume;
357  Rs = rs;
358  //unpolarized
359  Kf = std::pow(2.25 * M_PI, 1.0 / 3.0) / Rs;
360  }
361 
362 
363  inline T operator()(T r, T rinv) const { return 0.0; }
364 
365  inline T df(T r) const { return 0.0; }
366 
367  inline T Fk(T k, T rc) const { return -Xk(k, rc); }
368 
369  inline T Xk(T k, T rc) const
370  {
371  T y = 0.5 * k / Kf;
372  T Sy;
373  if (y >= 1.0)
374  {
375  Sy = 1.0;
376  }
377  else
378  {
379  Sy = 1.5 * y - 0.5 * y * y * y;
380  };
381  T val = 12.0 / (k * k * k * k * Rs * Rs * Rs);
382  return -0.5 * NormFactor * val * std::pow(1.0 / (Sy * Sy) + val, -0.5);
383  }
384 
385  inline T integrate_r2(T rc) const { return 0.0; }
386 
387  /** return RPA value at |k|
388  * @param kk |k|^2
389  */
390  inline T Uk(T kk) const { return NormFactor * Rs / kk; }
391 
392  /** return d u(k)/d rs
393  *
394  * Implement a correct one
395  */
396  inline T derivUk(T kk) const { return 0.0; }
397 };
398 
399 template<class T = double>
401 {
402  T Rs;
403  T Kf;
406  inline derivEPRPABreakup() {}
407 
408  void reset(ParticleSet& ref)
409  {
410  NormFactor = 1.0 / ref.getTotalNum();
411  Density = ref.getTotalNum() / ref.getLattice().Volume;
412  Rs = std::pow(3.0 / (4.0 * M_PI * Density), 1.0 / 3.0);
413  //unpolarized K_f
414  Kf = std::pow(2.25 * M_PI, 1.0 / 3.0) / Rs;
415  }
416 
417  void reset(ParticleSet& ref, T rs)
418  {
419  // NormFactor=4.0*M_PI/ref.getLattice().Volume;
420  NormFactor = 1.0 / ref.getTotalNum();
421  // NormFactor=4.0*M_PI/ref.getTotalNum();
422  Density = ref.getTotalNum() / ref.getLattice().Volume;
423  Rs = rs;
424  //unpolarized
425  Kf = std::pow(2.25 * M_PI, 1.0 / 3.0) / Rs;
426  }
427 
428 
429  inline T operator()(T r, T rinv) const { return 0.0; }
430 
431  inline T df(T r) const { return 0.0; }
432 
433  inline T Fk(T k, T rc) const { return -Xk(k, rc); }
434 
435  inline T Xk(T k, T rc) const
436  {
437  T y = 0.5 * k / Kf;
438  T Sy;
439  if (y >= 1.0)
440  {
441  Sy = 1.0;
442  }
443  else
444  {
445  Sy = 1.5 * y - 0.5 * y * y * y;
446  };
447  T val = 12.0 / (k * k * k * k * Rs * Rs * Rs);
448  T uk = val * std::pow(1.0 / (Sy * Sy) + val, -0.5);
449  return -0.5 * NormFactor * (uk / Rs) * (1.0 - 0.5 * val / (1.0 / (Sy * Sy) + val));
450  }
451  inline T integrate_r2(T rc) const { return 0.0; }
452 
453  /** return RPA value at |k|
454  * @param kk |k|^2
455  */
456  inline T Uk(T kk) const { return NormFactor * Rs / kk; }
457 
458  /** return d u(k)/d rs
459  *
460  * Implement a correct one
461  */
462  inline T derivUk(T kk) const { return 0.0; }
463 };
464 
465 template<typename T>
467 {
469 
470  explicit ShortRangePartAdapter(HandlerType* inhandler) : Uconst(0), myHandler(inhandler) {}
471 
472  OptimizableFunctorBase* makeClone() const override { return new ShortRangePartAdapter<T>(*this); }
473 
474  inline void reset() override {}
475  inline void setRmax(real_type rm) { Uconst = myHandler->evaluate(rm, 1.0 / rm); }
476  inline real_type evaluate(real_type r) { return f(r); }
477  inline real_type f(real_type r) override { return myHandler->evaluate(r, 1.0 / r) - Uconst; }
478  inline real_type df(real_type r) override { return myHandler->srDf(r, 1.0 / r); }
480  void checkOutVariables(const opt_variables_type& active) override {}
481  void resetParametersExclusive(const opt_variables_type& optVariables) override {}
482  bool put(xmlNodePtr cur) override { return true; }
485 };
486 
487 
488 template<class T = double>
490 {
491  T Rs;
492  T kf;
493  T kfm[2];
496  T hbs2m;
497  int nelec;
498  int nspin;
499  int nppss[2];
500  inline RPABFeeBreakup() {}
501 
502  // assumes 3D here, fix
503  void reset(ParticleSet& ref)
504  {
505  volume = ref.getLattice().Volume;
506  nspin = ref.groups();
507  for (int i = 0; i < nspin; ++i)
508  nppss[i] = ref.last(i) - ref.first(i);
509  Density = ref.getTotalNum() / ref.getLattice().Volume;
510  Rs = std::pow(3.0 / (4.0 * M_PI * Density), 1.0 / 3.0);
511  nelec = ref.getTotalNum();
512  hbs2m = 0.5;
513  kf = 0.0;
514  kfm[0] = kfm[1] = 0.0;
515  for (int i = 0; i < nspin; i++)
516  {
517  T a3 = 3.0 * volume / (4.0 * M_PI * nppss[i]);
518  kfm[i] = std::pow(9.0 * M_PI / (2.0 * a3), 1.0 / OHMMS_DIM);
519  kf += kfm[i] * nppss[i] / ref.getTotalNum();
520  }
521  }
522 
523  // assumes 3D here, fix
524  void reset(ParticleSet& ref, T rs)
525  {
526  Density = ref.getTotalNum() / ref.getLattice().Volume;
527  volume = ref.getLattice().Volume;
528  nspin = ref.groups();
529  for (int i = 0; i < nspin; ++i)
530  nppss[i] = ref.last(i) - ref.first(i);
531  Rs = rs;
532  nelec = ref.getTotalNum();
533  hbs2m = 0.5;
534  kf = 0.0;
535  kfm[0] = kfm[1] = 0.0;
536  for (int i = 0; i < nspin; i++)
537  {
538  T a3 = 3.0 * volume / (4.0 * M_PI * nppss[i]);
539  kfm[i] = std::pow(9.0 * M_PI / (2.0 * a3), 1.0 / OHMMS_DIM);
540  kf += kfm[i] * nppss[i] / ref.getTotalNum();
541  }
542  }
543 
544 
545  inline T operator()(T r, T rinv) const { return 0.0; }
546 
547  inline T df(T r) const { return 0.0; }
548 
549  inline T Fk(T k, T rc) const { return -Xk(k, rc); }
550 
551  inline T Xk(T k, T rc) const
552  {
553  T u = urpa(k) * volume / nelec;
554  T eq = k * k * hbs2m;
555  T vlr = u * u * 2.0 * Density * eq;
556  T vq = (2.0 * M_PI * (OHMMS_DIM - 1.0)) / (std::pow(k, OHMMS_DIM - 1.0));
557  T veff = vq - vlr;
558  T op2 = Density * 2.0 * vq * eq;
559 #if OHMMS_DIM == 3
560  // T op2kf=Density*2.0*(2.0*M_PI*(OHMMS_DIM-1.0))*hbs2m;
561  T op = (op2 + 1.2 * (kfm[0] * kfm[0] + kfm[1] * kfm[1]) * eq * hbs2m + eq * eq);
562 #elif OHMMS_DIM == 2
563  // T op2kf=Density*2.0*(2.0*M_PI*(OHMMS_DIM-1.0))*std::pow(kf,3.0-OHMMS_DIM)*hbs2m;
564  T op = (op2 + 1.5 * (kfm[0] * kfm[0] + kfm[1] * kfm[1]) * hbs2m * eq + eq * eq);
565 #endif
566  op = std::sqrt(op);
567  T denom = 1.0 / veff - Dlindhard(k, -eq);
568  T dp = -Dlindhardp(k, -eq);
569  T s0 = 0.0, ss = 0.0;
570  for (int i = 0; i < nspin; i++)
571  {
572  if (nppss[i] > 0)
573  {
574  T y = 0.5 * k / kfm[i];
575  if (y < 1.0)
576  {
577 #if OHMMS_DIM == 3
578  ss = 0.5 * y * (3.0 - y * y);
579 #elif OHMMS_DIM == 2
580  ss = (2.0 / M_PI) * (std::asin(y) + y * std::sqrt(1.0 - y * y));
581 #endif
582  }
583  else
584  {
585  ss = 1.0;
586  }
587  s0 += nppss[i] * ss / nelec;
588  }
589  }
590  T yq = s0 * s0 / (4.0 * k * k) * (1.0 / (eq * denom) + dp / (denom * denom)) +
591  2.0 * hbs2m * vlr / (op * (std::sqrt(op2) + eq));
592  return yq / volume;
593  }
594 
595  inline T integrate_r2(T rc) const { return 0.0; }
596 
597  /** return RPA value at |k|
598  * @param kk |k|^2
599  */
600  inline T Uk(T kk) const { return 0.0; }
601 
602  /** return d u(k)/d rs
603  *
604  * Implement a correct one
605  */
606  inline T derivUk(T kk) const { return 0.0; }
607 
608  T urpa(T q) const
609  {
610  T a = 0.0, vkbare;
611  if (q > 0.0)
612  {
613  vkbare = 4.0 * M_PI / (q * q);
614  a = 2.0 * Density * vkbare / (hbs2m * q * q);
615  }
616  return -0.5 + 0.5 * std::sqrt(1.0 + a);
617  }
618 
619  // mmorales: taken from bopimc (originally by M Holzmann)
620  T Dlindhard(T q, T w) const
621  {
622  T xd1, xd2, small = 0.00000001, xdummy, rq1, rq2;
623  T res = 0.0;
624  for (int i = 0; i < nspin; i++)
625  {
626  if (kfm[i] > 0.0)
627  {
628  T xq = q / kfm[i];
629  if (xq < small)
630  xq = small;
631  T om = w / (kfm[i] * kfm[i] * hbs2m * 2.0);
632  xd1 = om / xq - xq / 2.0;
633  xd2 = om / xq + xq / 2.0;
634  if (std::abs(xd1 - 1.0) <= small)
635  {
636  if (xd1 >= 1.0)
637  xd1 = 1.0 + small;
638  else
639  xd1 = 1.0 - small;
640  }
641  else if (std::abs(xd2 - 1.0) <= small)
642  {
643  if (xd2 >= 1.0)
644  xd2 = 1.0 + small;
645  else
646  xd2 = 1.0 - small;
647  }
648 #if OHMMS_DIM == 3
649  rq1 = std::log(std::abs(1.0 + xd1) / std::abs(1.0 - xd1));
650  rq2 = std::log(std::abs(1.0 + xd2) / std::abs(1.0 - xd2));
651  xdummy = -1.0 + 0.5 * (1.0 - xd1 * xd1) / xq * rq1 - 0.50 * (1.0 - xd2 * xd2) / xq * rq2;
652  xdummy *= kfm[i] / (8.0 * M_PI * M_PI * hbs2m);
653 #elif OHMMS_DIM == 2
654  T sd1, sd2;
655  if (std::abs(xd1) < small)
656  sd1 = 0.0;
657  else
658  sd1 = xd1 / std::abs(xd1);
659  if (std::abs(xd2) < small)
660  sd2 = 0.0;
661  else
662  sd2 = xd2 / std::abs(xd2);
663  if (xd1 * xd1 - 1.0 > 1.0)
664  rq1 = std::sqrt(xd1 * xd1 - 1.0) * sd1;
665  else
666  rq1 = 0.0;
667  if (xd2 * xd2 - 1.0 > 1.0)
668  rq2 = std::sqrt(xd2 * xd2 - 1.0) * sd2;
669  else
670  rq2 = 0.0;
671  xdummy = -(xq + rq1 - rq2) / (4.0 * M_PI * xq * hbs2m);
672 #endif
673  res += xdummy;
674  }
675  }
676  return res;
677  }
678 
679  // mmorales: taken from bopimc (originally by M Holzmann)
680  T Dlindhardp(T q, T w) const
681  {
682  T xd1, xd2, small = 0.00000001, xdummy, rq1, rq2;
683  T res = 0.0;
684  for (int i = 0; i < nspin; i++)
685  {
686  if (kfm[i] > 0.0)
687  {
688  T xq = q / kfm[i];
689  if (xq < small)
690  xq = small;
691  T om = w / (kfm[i] * kfm[i] * hbs2m * 2.0);
692  xd1 = om / xq - xq / 2.0;
693  xd2 = om / xq + xq / 2.0;
694  if (std::abs(xd1 - 1.0) <= small)
695  {
696  if (xd1 >= 1.0)
697  xd1 = 1.0 + small;
698  else
699  xd1 = 1.0 - small;
700  }
701  else if (std::abs(xd2 - 1.0) <= small)
702  {
703  if (xd2 >= 1.0)
704  xd2 = 1.0 + small;
705  else
706  xd2 = 1.0 - small;
707  }
708 #if OHMMS_DIM == 3
709  rq1 = std::log(std::abs(1.0 + xd1) / std::abs(1.0 - xd1));
710  rq2 = std::log(std::abs(1.0 + xd2) / std::abs(1.0 - xd2));
711  xdummy = -xd1 / (xq * kfm[i] * kfm[i] * 2.0 * hbs2m) * rq1 + xd2 / (xq * kfm[i] * kfm[i] * 2.0 * hbs2m) * rq2;
712  xdummy *= kfm[i] / (8.0 * M_PI * M_PI * hbs2m * xq);
713 #elif OHMMS_DIM == 2
714  T sd1, sd2;
715  if (std::abs(xd1) < small)
716  sd1 = 0.0;
717  else
718  sd1 = xd1 / std::abs(xd1);
719  if (std::abs(xd2) < small)
720  sd2 = 0.0;
721  else
722  sd2 = xd2 / std::abs(xd2);
723  if (xd1 * xd1 - 1.0 > 1.0)
724  rq1 = sd1 * xd1 / std::sqrt(xd1 * xd1 - 1.0);
725  else
726  rq1 = 0.0;
727  if (xd2 * xd2 - 1.0 > 1.0)
728  rq2 = sd2 * xd2 / std::sqrt(xd2 * xd2 - 1.0);
729  else
730  rq2 = 0.0;
731  xdummy = -(rq1 - rq2) / (8.0 * M_PI * (xq * kfm[i] * hbs2m) * (xq * kfm[i] * hbs2m));
732 #endif
733  res += xdummy;
734  }
735  }
736  return res;
737  }
738 };
739 
740 } // namespace qmcplusplus
741 #endif
T Xk(T k, T rc) const
integral from kc to infinity
void reset(ParticleSet &ref)
T Uk(T kk) const
return RPA value at |k|
T derivUk(T kk) const
return d u(k)/d rs
void reset() override
reset function
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
void checkInVariablesExclusive(opt_variables_type &active) override
check in variational parameters to the global list of parameters used by the optimizer.
MakeReturn< UnaryNode< FnFabs, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t abs(const Vector< T1, C1 > &l)
size_t getTotalNum() const
Definition: ParticleSet.h:493
real_type df(real_type r) override
evaluate the first derivative
MakeReturn< UnaryNode< FnSin, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t sin(const Vector< T1, C1 > &l)
void checkOutVariables(const opt_variables_type &active) override
check out variational optimizable variables
T Uk(T kk) const
return RPA value at |k|
void reset(ParticleSet &ref)
T operator()(T r, T rinv) const
int first(int igroup) const
return the first index of a group i
Definition: ParticleSet.h:514
T df(T r) const
need d(df(r)/d(rs))/dr
Define a base class for one-dimensional functions with optimizable variables.
mRealType evaluate(const std::vector< int > &kshell, const pRealType *restrict rk1_r, const pRealType *restrict rk1_i, const pRealType *restrict rk2_r, const pRealType *restrict rk2_i) const
evaluate
Definition: LRHandlerBase.h:93
#define OHMMS_DIM
Definition: config.h:64
T operator()(T r, T rinv) const
void reset(ParticleSet &ref, T rs)
int groups() const
return the number of groups
Definition: ParticleSet.h:511
MakeReturn< BinaryNode< FnPow, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t, typename CreateLeaf< Vector< T2, C2 > >::Leaf_t > >::Expression_t pow(const Vector< T1, C1 > &l, const Vector< T2, C2 > &r)
T Uk(T kk) const
return RPA value at |k|
Specialized paritlce class for atomistic simulations.
Definition: ParticleSet.h:55
T operator()(T r, T rinv) const
MakeReturn< UnaryNode< FnCos, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t cos(const Vector< T1, C1 > &l)
void reset(ParticleSet &ref, T rs)
T Uk(T kk) const
return RPA value at |k|
T derivUk(T kk) const
return d u(k)/d rs
T operator()(T r, T rinv) const
class to handle a set of variables that can be modified during optimizations
Definition: VariableSet.h:49
int last(int igroup) const
return the last index of a group i
Definition: ParticleSet.h:517
MakeReturn< UnaryNode< FnExp, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t exp(const Vector< T1, C1 > &l)
void reset(ParticleSet &ref, T rs)
bool put(xmlNodePtr cur) override
process xmlnode and registers variables to optimize
T derivUk(T kk) const
return d u(k)/d rs
T operator()(T r, T rinv) const
need the df(r)/d(rs)
T operator()(T r, T rinv) const
Base class for any functor with optimizable parameters.
void reset(ParticleSet &ref, T rs)
MakeReturn< UnaryNode< FnLog, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t log(const Vector< T1, C1 > &l)
MakeReturn< UnaryNode< FnSqrt, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t sqrt(const Vector< T1, C1 > &l)
T derivUk(T kk) const
return d u(k)/d rs
void reset(ParticleSet &ref, T rs)
void reset(ParticleSet &ref, T rs)
void reset(ParticleSet &ref)
const auto & getLattice() const
Definition: ParticleSet.h:251
T derivUk(T kk) const
return d u(k)/d rs
base class for LRHandlerTemp<FUNC,BASIS> and DummyLRHanlder<typename Func>
Definition: LRHandlerBase.h:30
OptimizableFunctorBase * makeClone() const override
create a clone of this object
void reset(ParticleSet &ref, T rs)
T Uk(T kk) const
return RPA value at |k|
void reset(ParticleSet &ref)
optimize::VariableSet::real_type real_type
typedef for real values
virtual mRealType srDf(mRealType r, mRealType rinv) const =0
void resetParametersExclusive(const opt_variables_type &optVariables) override
reset the parameters during optimizations.
void reset(ParticleSet &ref)
real_type f(real_type r) override
evaluate the value at r
T derivUk(T kk) const
return d u(k)/d rs
T Uk(T kk) const
return RPA value at |k|
MakeReturn< UnaryNode< FnArcSin, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t asin(const Vector< T1, C1 > &l)
ShortRangePartAdapter(HandlerType *inhandler)