QMCPACK
LPQHISRCoulombBasis.cpp
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: Raymond Clay III, j.k.rofling@gmail.com, Lawrence Livermore National Laboratory
8 // Mark A. Berrill, berrillma@ornl.gov, Oak Ridge National Laboratory
9 //
10 // File created by: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
11 //////////////////////////////////////////////////////////////////////////////////////
12 
13 
14 #include "LPQHISRCoulombBasis.h"
15 #include <cassert>
16 #include "CPU/math.hpp"
17 
18 namespace qmcplusplus
19 {
20 using std::cos;
21 using std::sin;
23 {
24  assert(n > 1);
25  NumKnots = n;
26  if (m_rc != 0.0)
27  {
28  delta = m_rc / (NumKnots - 1);
29  deltainv = 1.0 / delta;
30  }
31  //set the BasisSize to 3*NumKnots
32  BasisSize = 3 * NumKnots;
33 }
34 
35 
37 {
38  m_rc = rc;
39  if (NumKnots != 0)
40  {
41  delta = m_rc / (NumKnots - 1);
42  deltainv = 1.0 / delta;
43  }
44 }
45 
46 
47 //LPQHISRCoulombBasis::mRealType
48 //LPQHISRCoulombBasis::h(int n, mRealType r) {
49 // int i=n/3;
50 // int alpha = n-3*i;
51 // mRealType ra = delta*(i-1);
52 // mRealType rb = delta*i;
53 // mRealType rc = delta*(i+1);
54 // rc = std::min(m_rc, rc);
55 // if ((r > ra) && (r <= rb)) {
56 // mRealType sum = 0.0;
57 // mRealType prod = 1.0;
58 // for (int j=0; j<=5; j++) {
59 // sum += (S(alpha,j) * prod);
60 // prod *= ((rb - r) * deltainv);
61 // }
62 // for (int j=0; j<alpha; j++)
63 // sum *= -1.0;
64 // return (sum);
65 // }
66 // else if ((r > rb) && (r <= rc)) {
67 // mRealType sum = 0.0;
68 // mRealType prod = 1.0;
69 // for (int j=0; j<=5; j++) {
70 // sum += S(alpha,j) * prod;
71 // prod *= ((r-rb) * deltainv);
72 // }
73 // return sum;
74 // }
75 // return 0.0;
76 //}
77 
78 
80 {
81  int j = n / 3;
82  int alpha = n - 3 * j;
83  mRealType deltaa2 = std::pow(delta, alpha + 2.0);
84  int mysign = 1 - 2 * (alpha % 2);
85  mRealType sum = 0.0;
86 
87  for (int i = 0; i <= 5; i++)
88  {
89  if (j < NumKnots - 1)
90  sum += S(alpha, i) * deltaa2 * (1.0 / mRealType(i + 2) + mRealType(j) / mRealType(i + 1));
91  if (j > 0)
92  sum += mysign * S(alpha, i) * deltaa2 * (-1.0 / mRealType(i + 2) + mRealType(j) / mRealType(i + 1));
93  }
94 
95  return (sum);
96 }
97 
98 
100 {
101  int i = m / 3;
102  int alpha = m - 3 * i;
103  mRealType sum = 0.0;
104  if (i == 0)
105  {
106  for (int n = 0; n <= 5; n++)
107  {
108  sum += S(alpha, n) * (Dplus(i, k, n));
109  }
110  }
111  else if (i == (NumKnots - 1))
112  {
113  for (int n = 0; n <= 5; n++)
114  {
115  mRealType sign = ((alpha + n) & 1) ? -1.0 : 1.0;
116  sum += S(alpha, n) * (Dminus(i, k, n) * sign);
117  }
118  }
119  else
120  {
121  for (int n = 0; n <= 5; n++)
122  {
123  mRealType sign = ((alpha + n) & 1) ? -1.0 : 1.0;
124  sum += S(alpha, n) * (Dplus(i, k, n) + Dminus(i, k, n) * sign);
125  }
126  }
127  return std::pow(delta, alpha) * (sum);
128 }
129 
130 
131 inline std::complex<LPQHISRCoulombBasis::mRealType> LPQHISRCoulombBasis::Eplus(int i, mRealType k, int n) const
132 {
133  std::complex<mRealType> eye(0.0, 1.0);
134  if (n == 0)
135  {
136  std::complex<mRealType> e1(cos(k * delta) - 1.0, sin(k * delta));
137  std::complex<mRealType> e2(cos(k * delta * i), sin(k * delta * i));
138  return (-(eye / k) * e1 * e2);
139  }
140  else
141  {
142  std::complex<mRealType> t1, t2;
143  t1 = std::complex<mRealType>(cos(k * delta * (i + 1)), sin(k * delta * (i + 1)));
144  t2 = -(mRealType)n / delta * Eplus(i, k, n - 1);
145  ;
146  return (-(eye / k) * (t1 + t2));
147  }
148 }
149 
150 
151 inline std::complex<LPQHISRCoulombBasis::mRealType> LPQHISRCoulombBasis::Eminus(int i, mRealType k, int n) const
152 {
153  std::complex<mRealType> eye(0.0, 1.0);
154  if (n == 0)
155  {
156  std::complex<mRealType> e1(cos(k * delta) - 1.0, -sin(k * delta));
157  std::complex<mRealType> e2(cos(k * delta * i), sin(k * delta * i));
158  return (-(eye / k) * e1 * e2);
159  }
160  else
161  {
162  std::complex<mRealType> t1, t2;
163  mRealType sign = (n & 1) ? -1.0 : 1.0;
164  t1 = sign * std::complex<mRealType>(cos(k * delta * (i - 1)), sin(k * delta * (i - 1)));
165  t2 = -(mRealType)n / delta * Eminus(i, k, n - 1);
166  return (-(eye / k) * (t1 + t2));
167  }
168 }
169 
170 
172 {
173  std::complex<mRealType> Z1 = Eplus(i, k, n);
174  return 4.0 * M_PI / (k * Lattice.Volume) * (Z1.imag());
175 }
176 
177 
179 {
180  std::complex<mRealType> Z1 = Eminus(i, k, n);
181  return -4.0 * M_PI / (k * Lattice.Volume) * (Z1.imag());
182 }
183 
185 {
186  int i = m / 3;
187  int alpha = m - 3 * i;
188  mRealType sum = 0.0;
189  if (i == 0)
190  {
191  for (int n = 0; n <= 5; n++)
192  {
193  sum += S(alpha, n) * (Dplus_dG(i, k, n));
194  }
195  }
196  else if (i == (NumKnots - 1))
197  {
198  for (int n = 0; n <= 5; n++)
199  {
200  mRealType sign = ((alpha + n) & 1) ? -1.0 : 1.0;
201  sum += S(alpha, n) * (Dminus_dG(i, k, n) * sign);
202  }
203  }
204  else
205  {
206  for (int n = 0; n <= 5; n++)
207  {
208  mRealType sign = ((alpha + n) & 1) ? -1.0 : 1.0;
209  sum += S(alpha, n) * (Dplus_dG(i, k, n) + Dminus_dG(i, k, n) * sign);
210  }
211  }
212  return std::pow(delta, alpha) * (sum);
213 }
214 
215 inline std::complex<LPQHISRCoulombBasis::mRealType> LPQHISRCoulombBasis::Eplus_dG(int i, mRealType k, int n) const
216 {
217  std::complex<mRealType> eye(0.0, 1.0);
218  mRealType ri = i * delta;
219  mRealType kinv = 1 / mRealType(k);
220  std::complex<mRealType> eigd(cos(k * delta), sin(k * delta));
221  std::complex<mRealType> eigr(cos(k * ri), sin(k * ri));
222 
223  if (n == 0)
224  return Eplus(i, k, n) * (eye * ri - kinv) + delta * kinv * eigr * eigd;
225  else
226  return -kinv * Eplus(i, k, n) -
227  eye * kinv * (eye * (ri + delta) * eigd * eigr - (n / mRealType(delta)) * Eplus_dG(i, k, n - 1));
228 }
229 
230 inline std::complex<LPQHISRCoulombBasis::mRealType> LPQHISRCoulombBasis::Eminus_dG(int i, mRealType k, int n) const
231 {
232  std::complex<mRealType> eye(0.0, 1.0);
233  mRealType ri = i * delta;
234  mRealType kinv = 1.0 / mRealType(k);
235  std::complex<mRealType> eigd(cos(k * delta), -sin(k * delta));
236  std::complex<mRealType> eigr(cos(k * ri), sin(k * ri));
237 
238  if (n == 0)
239  {
240  std::complex<mRealType> eigd(cos(k * delta), -sin(k * delta));
241  std::complex<mRealType> eigr(cos(k * ri), sin(k * ri));
242  return Eminus(i, k, n) * (eye * ri - kinv) - delta * kinv * eigr * eigd;
243  }
244  else
245  return -kinv * Eminus(i, k, n) -
246  eye * kinv *
247  (mRealType(pow(-1.0, n)) * eye * (ri - delta) * eigd * eigr - (n / mRealType(delta)) * Eminus_dG(i, k, n - 1));
248 }
249 
250 
252 {
253  mRealType kinv = 1.0 / mRealType(k);
254  std::complex<mRealType> Z1 = Eplus_dG(i, k, n);
255 
256  return 4.0 * M_PI / (k * Lattice.Volume) * Z1.imag() - kinv * Dplus(i, k, n);
257 }
258 
259 
261 {
262  mRealType kinv = 1.0 / mRealType(k);
263  std::complex<mRealType> Z1 = Eminus_dG(i, k, n);
264  return -4.0 * M_PI / (k * Lattice.Volume) * Z1.imag() - kinv * Dminus(i, k, n);
265 }
266 
267 } // namespace qmcplusplus
a class that defines a supercell in D-dimensional Euclean space.
mRealType Dminus(int i, mRealType k, int n) const
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
std::complex< mRealType > Eminus(int i, mRealType k, int n) const
mRealType c(int n, mRealType k) const override
MakeReturn< UnaryNode< FnSin, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t sin(const Vector< T1, C1 > &l)
EwaldHandler3D::mRealType mRealType
mRealType Dplus_dG(int i, mRealType k, int n) const
mRealType dc_dk(int n, mRealType k) const override
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)
MakeReturn< UnaryNode< FnCos, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t cos(const Vector< T1, C1 > &l)
Scalar_t Volume
Physical properties of a supercell.
std::complex< mRealType > Eplus(int i, mRealType k, int n) const
void set_rc(mRealType rc) override
double sign(double x)
Definition: Standard.h:73
mRealType Dminus_dG(int i, mRealType k, int n) const
std::complex< mRealType > Eminus_dG(int i, mRealType k, int n) const
mRealType Dplus(int i, mRealType k, int n) const
mRealType m_rc
Real-space cutoff for short-range part.
Definition: LRBasis.h:40
DECLARE_COULOMB_TYPES int BasisSize
size of the basis elements
Definition: LRBasis.h:38
std::complex< mRealType > Eplus_dG(int i, mRealType k, int n) const
mRealType hintr2(int n) const override