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:  Mark Dewing, markdewing@gmail.com, University of Illinois at Urbana-Champaign
8 //
9 // File created by: Mark Dewing, markdewing@gmail.com, University of Illinois at Urbana-Champaign
10 //////////////////////////////////////////////////////////////////////////////////////
11 
12 
13 #include "catch.hpp"
14 
15 #include "Particle/ParticleSet.h"
16 #include "Particle/MCWalkerConfiguration.h"
17 #include "QMCDrivers/DriftOperators.h"
18 #include "QMCDrivers/GreenFunctionModifiers/DriftModifierUNR.h"
19 
20 namespace qmcplusplus
21 {
22 TEST_CASE("drift pbyp and node correction real", "[drivers][drift]")
23 {
24   Communicate* c;
25   c = OHMMS::Controller;
26 
27   MCWalkerConfiguration elec;
28 
29   elec.setName("elec");
30   std::vector<int> agroup(1);
31   agroup[0] = 1;
32   elec.create(agroup);
33 
34   ParticleSet::RealType tau  = 0.5;
35   ParticleSet::RealType mass = 0.85;
36   std::vector<ParticleSet::RealType> massinv(1, 1. / mass);
37   ParticleSet::ParticlePos_t drift(1);
38 
39   // check from -xtot/2 to xtot/2 in step size of dx i.e. np.arange(-xtot/2,xtot/2,dx)
40   double xtot  = 10.;
41   int nx       = 100;
42   double gradx = -xtot / 2.;
43   double dx    = xtot / nx;
44 
45   //app_log() << " begin printing" << std::endl;
46   for (int ix = 0; ix < nx; ix++)
47   {
48     elec.G[0][0] = gradx;
49     setScaledDriftPbyPandNodeCorr(tau, massinv, elec.G, drift);
50     double dval = drift[0][0];
51 
52     double scale_factor = (-1. + std::sqrt(1. + 2. * gradx * gradx * tau / mass)) / (gradx * gradx * tau / mass);
53     REQUIRE(dval == Approx(scale_factor * gradx * tau / mass));
54 
55     //app_log() << gradx << " " << dval << std::endl;
56     gradx += dx;
57   }
58   //app_log() << " end printing." << std::endl;
59 }
60 
61 #ifdef QMC_COMPLEX
62 TEST_CASE("drift pbyp and node correction complex", "[drivers][drift]")
63 { // basically copy and pasted from real test, except "myi"
64   Communicate* c;
65   c = OHMMS::Controller;
66 
67   MCWalkerConfiguration elec;
68 
69   elec.setName("elec");
70   std::vector<int> agroup(1);
71   agroup[0] = 1;
72   elec.create(agroup);
73 
74   ParticleSet::RealType tau  = 0.5;
75   ParticleSet::RealType mass = 0.85;
76   std::vector<ParticleSet::RealType> massinv(1, 1. / mass);
77   ParticleSet::ParticlePos_t drift(1);
78 
79   // check from -xtot/2 to xtot/2 in step size of dx i.e. np.arange(-xtot/2,xtot/2,dx)
80   double xtot  = 10.;
81   int nx       = 100;
82   double gradx = -xtot / 2.;
83   double dx    = xtot / nx;
84 
85   // imaginary component of wf gradient should NOT affect drift
86   std::complex<double> myi(0, 1.9);
87   for (int ix = 0; ix < nx; ix++)
88   {
89     elec.G[0][0] = gradx + myi;
90     setScaledDriftPbyPandNodeCorr(tau, massinv, elec.G, drift);
91     double dval = drift[0][0];
92 
93     double scale_factor = (-1. + std::sqrt(1. + 2. * gradx * gradx * tau / mass)) / (gradx * gradx * tau / mass);
94     REQUIRE(dval == Approx(scale_factor * gradx * tau / mass));
95 
96     gradx += dx;
97   }
98 }
99 #endif
100 
101 TEST_CASE("get scaled drift real", "[drivers][drift]")
102 {
103   Communicate* c;
104   c = OHMMS::Controller;
105 
106   MCWalkerConfiguration elec;
107 
108   elec.setName("elec");
109   std::vector<int> agroup(1);
110   agroup[0] = 1;
111   elec.create(agroup);
112 
113   ParticleSet::RealType tau  = 0.5;
114   ParticleSet::RealType mass = 0.85;
115   std::vector<ParticleSet::RealType> massinv(1, 1. / mass);
116   ParticleSet::PosType drift;
117 
118   // check from -xtot/2 to xtot/2 in step size of dx i.e. np.arange(-xtot/2,xtot/2,dx)
119   double xtot  = 10.;
120   int nx       = 100;
121   double gradx = -xtot / 2.;
122   double dx    = xtot / nx;
123 
124   DriftModifierUNR DM;
125   for (int ix = 0; ix < nx; ix++)
126   {
127     elec.G[0][0] = gradx;
128     DM.getDrift(tau / mass, elec.G[0], drift);
129     double dval = drift[0];
130 
131     double scale_factor = (-1. + std::sqrt(1. + 2. * gradx * gradx * tau / mass)) / (gradx * gradx * tau / mass);
132     REQUIRE(dval == Approx(scale_factor * gradx * tau / mass));
133 
134     gradx += dx;
135   }
136 }
137 
138 #ifdef QMC_COMPLEX
139 TEST_CASE("get scaled drift complex", "[drivers][drift]")
140 {
141   Communicate* c;
142   c = OHMMS::Controller;
143 
144   MCWalkerConfiguration elec;
145 
146   elec.setName("elec");
147   std::vector<int> agroup(1);
148   agroup[0] = 1;
149   elec.create(agroup);
150 
151   ParticleSet::RealType tau  = 0.5;
152   ParticleSet::RealType mass = 0.85;
153   std::vector<ParticleSet::RealType> massinv(1, 1. / mass);
154   ParticleSet::PosType drift;
155 
156   // check from -xtot/2 to xtot/2 in step size of dx i.e. np.arange(-xtot/2,xtot/2,dx)
157   double xtot  = 10.;
158   int nx       = 100;
159   double gradx = -xtot / 2.;
160   double dx    = xtot / nx;
161 
162   DriftModifierUNR DM;
163 
164   // imaginary component of wf gradient should NOT affect drift
165   std::complex<double> myi(0, 1.9);
166   for (int ix = 0; ix < nx; ix++)
167   {
168     elec.G[0][0] = gradx + myi;
169     DM.getDrift(tau / mass, elec.G[0], drift);
170     double dval = drift[0];
171 
172     double scale_factor = (-1. + std::sqrt(1. + 2. * gradx * gradx * tau / mass)) / (gradx * gradx * tau / mass);
173     REQUIRE(dval == Approx(scale_factor * gradx * tau / mass));
174 
175     gradx += dx;
176   }
177 }
178 #endif
179 
180 } // namespace qmcplusplus
181