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