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 // Jeremy McMinnis, jmcminis@gmail.com, University of Illinois at Urbana-Champaign
9 // Mark A. Berrill, berrillma@ornl.gov, Oak Ridge National Laboratory
10 //
11 // File created by: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
12 //////////////////////////////////////////////////////////////////////////////////////
13
14
15 #include "LPQHIBasis.h"
16 #include <cassert>
17
18 namespace qmcplusplus
19 {
20 using std::cos;
21 using std::sin;
set_NumKnots(int n)22 void LPQHIBasis::set_NumKnots(int n)
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
set_rc(mRealType rc)36 void LPQHIBasis::set_rc(mRealType rc)
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 //LPQHIBasis::RealType
48 //LPQHIBasis::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
hintr2(int n)79 LPQHIBasis::mRealType LPQHIBasis::hintr2(int n)
80 {
81 int j = n / 3;
82 int alpha = n - 3 * j;
83 mRealType deltap3 = delta * delta * delta;
84 mRealType min1toalpha = 1.0;
85 bool alphaeven = true;
86 //Constants above correct for alpha==0
87 if (alpha == 1)
88 {
89 min1toalpha = -1.0;
90 alphaeven = false;
91 }
92 mRealType sum = 0.0;
93 if (j == 0)
94 {
95 for (int i = 0; i <= 5; i++)
96 sum += S(alpha, i) / (i + 3);
97 sum *= deltap3;
98 }
99 else if (j == (NumKnots - 1))
100 {
101 mRealType prod1 = 1.0 / 3.0;
102 mRealType prod2 = -j;
103 mRealType prod3 = j * j;
104 for (int i = 0; i <= 5; i++)
105 {
106 sum += S(alpha, i) * (prod1 + prod2 + prod3);
107 prod1 *= (i + 3.0) / (i + 4.0);
108 prod2 *= (i + 2.0) / (i + 3.0);
109 prod3 *= (i + 1.0) / (i + 2.0);
110 }
111 sum *= deltap3 * min1toalpha;
112 }
113 else
114 // expression for 0<j<M
115 {
116 if (alphaeven)
117 {
118 mRealType prod1 = 1.0 / 3.0;
119 mRealType prod2 = j * j;
120 for (int i = 0; i <= 5; i++)
121 {
122 sum += S(alpha, i) * (prod1 + prod2);
123 prod1 *= (i + 3.0) / (i + 4.0); //Prepare for next cycle.
124 prod2 *= (i + 1.0) / (i + 2.0); //Prepare for next cycle.
125 }
126 sum *= 2. * deltap3;
127 }
128 else
129 {
130 for (int i = 0; i <= 5; i++)
131 sum += S(alpha, i) / (i + 2.0);
132 sum *= deltap3 * 4. * j;
133 }
134 }
135 return (sum);
136 }
137
138
c(int m,mRealType k)139 LPQHIBasis::mRealType LPQHIBasis::c(int m, mRealType k)
140 {
141 int i = m / 3;
142 int alpha = m - 3 * i;
143 mRealType sum = 0.0;
144 if (i == 0)
145 {
146 for (int n = 0; n <= 5; n++)
147 {
148 sum += S(alpha, n) * (Dplus(i, k, n));
149 }
150 }
151 else if (i == (NumKnots - 1))
152 {
153 for (int n = 0; n <= 5; n++)
154 {
155 mRealType sign = ((alpha + n) & 1) ? -1.0 : 1.0;
156 sum += S(alpha, n) * (Dminus(i, k, n) * sign);
157 }
158 }
159 else
160 {
161 for (int n = 0; n <= 5; n++)
162 {
163 mRealType sign = ((alpha + n) & 1) ? -1.0 : 1.0;
164 sum += S(alpha, n) * (Dplus(i, k, n) + Dminus(i, k, n) * sign);
165 }
166 }
167 return (sum);
168 }
169
170
Eplus(int i,mRealType k,int n)171 inline std::complex<LPQHIBasis::mRealType> LPQHIBasis::Eplus(int i, mRealType k, int n)
172 {
173 std::complex<mRealType> eye(0.0, 1.0);
174 if (n == 0)
175 {
176 std::complex<mRealType> e1(cos(k * delta) - 1.0, sin(k * delta));
177 std::complex<mRealType> e2(cos(k * delta * i), sin(k * delta * i));
178 return (-(eye / k) * e1 * e2);
179 }
180 else
181 {
182 std::complex<mRealType> t1, t2;
183 t1 = std::complex<mRealType>(cos(k * delta * (i + 1)), sin(k * delta * (i + 1)));
184 t2 = -(mRealType)n / delta * Eplus(i, k, n - 1);
185 ;
186 return (-(eye / k) * (t1 + t2));
187 }
188 }
189
190
Eminus(int i,mRealType k,int n)191 inline std::complex<LPQHIBasis::mRealType> LPQHIBasis::Eminus(int i, mRealType k, int n)
192 {
193 std::complex<mRealType> eye(0.0, 1.0);
194 if (n == 0)
195 {
196 std::complex<mRealType> e1(cos(k * delta) - 1.0, -sin(k * delta));
197 std::complex<mRealType> e2(cos(k * delta * i), sin(k * delta * i));
198 return (-(eye / k) * e1 * e2);
199 }
200 else
201 {
202 std::complex<mRealType> t1, t2;
203 mRealType sign = (n & 1) ? -1.0 : 1.0;
204 t1 = sign * std::complex<mRealType>(cos(k * delta * (i - 1)), sin(k * delta * (i - 1)));
205 t2 = -(mRealType)n / delta * Eminus(i, k, n - 1);
206 return (-(eye / k) * (t1 + t2));
207 }
208 }
209
210
Dplus(int i,mRealType k,int n)211 inline LPQHIBasis::mRealType LPQHIBasis::Dplus(int i, mRealType k, int n)
212 {
213 std::complex<mRealType> Z1 = Eplus(i, k, n + 1);
214 std::complex<mRealType> Z2 = Eplus(i, k, n);
215 return 4.0 * M_PI / (k * Lattice.Volume) * (delta * Z1.imag() + i * delta * Z2.imag());
216 }
217
218
Dminus(int i,mRealType k,int n)219 inline LPQHIBasis::mRealType LPQHIBasis::Dminus(int i, mRealType k, int n)
220 {
221 std::complex<mRealType> Z1 = Eminus(i, k, n + 1);
222 std::complex<mRealType> Z2 = Eminus(i, k, n);
223 return -4.0 * M_PI / (k * Lattice.Volume) * (delta * Z1.imag() + i * delta * Z2.imag());
224 }
225 } // namespace qmcplusplus
226