QMCPACK
test_J2_bspline.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: 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 "OhmmsData/Libxml2Doc.h"
16 #include "OhmmsPETE/OhmmsMatrix.h"
17 #include "Particle/ParticleSet.h"
23 
24 #include <cstdio>
25 #include <string>
26 
27 
28 // Uncomment to print information and values from the underlying functor
29 //#define PRINT_SPLINE_DATA
30 
31 using std::string;
32 
33 namespace qmcplusplus
34 {
37 
38 TEST_CASE("BSpline builder Jastrow J2", "[wavefunction]")
39 {
41 
42  const SimulationCell simulation_cell;
43  ParticleSet ions_(simulation_cell);
44  ParticleSet elec_(simulation_cell);
45 
46  ions_.setName("ion");
47  ions_.create({1});
48  ions_.R[0] = {2.0, 0.0, 0.0};
49  elec_.setName("elec");
50  elec_.create({1, 1});
51  elec_.R[0] = {1.00, 0.0, 0.0};
52  elec_.R[1] = {0.0, 0.0, 0.0};
53  SpeciesSet& tspecies = elec_.getSpeciesSet();
54  int upIdx = tspecies.addSpecies("u");
55  int downIdx = tspecies.addSpecies("d");
56  int chargeIdx = tspecies.addAttribute("charge");
57  tspecies(chargeIdx, upIdx) = -1;
58  tspecies(chargeIdx, downIdx) = -1;
59  elec_.resetGroups();
60 
61  const char* particles = R"(<tmp>
62 <jastrow name="J2" type="Two-Body" function="Bspline" print="yes" gpu="no">
63  <correlation rcut="10" size="10" speciesA="u" speciesB="d">
64  <coefficients id="ud" type="Array"> 0.02904699284 -0.1004179 -0.1752703883 -0.2232576505 -0.2728029201 -0.3253286875 -0.3624525145 -0.3958223107 -0.4268582166 -0.4394531176</coefficients>
65  </correlation>
66 </jastrow>
67 </tmp>
68 )";
70  bool okay = doc.parseFromString(particles);
71  REQUIRE(okay);
72 
73  xmlNodePtr root = doc.getRoot();
74 
75  xmlNodePtr jas1 = xmlFirstElementChild(root);
76 
77  RadialJastrowBuilder jastrow(c, elec_);
78 
80  auto j2_uptr = jastrow.buildComponent(jas1);
81  J2Type* j2 = dynamic_cast<J2Type*>(j2_uptr.get());
82  REQUIRE(j2);
83 
84  // update all distance tables
85  elec_.update();
86 
87  double logpsi_real = std::real(j2->evaluateLog(elec_, elec_.G, elec_.L));
88  CHECK(logpsi_real == Approx(0.1012632641)); // note: number not validated
89 
90  double KE = -0.5 * (Dot(elec_.G, elec_.G) + Sum(elec_.L));
91  CHECK(KE == Approx(-0.1616624771)); // note: number not validated
92 
93  UniqueOptObjRefs opt_obj_refs;
94  j2->extractOptimizableObjectRefs(opt_obj_refs);
95  REQUIRE(opt_obj_refs.size() == 1);
96 
97  opt_variables_type optvars;
100 
101  for (OptimizableObject& obj : opt_obj_refs)
102  obj.checkInVariablesExclusive(optvars);
103  optvars.resetIndex();
104  const int NumOptimizables(optvars.size());
105  j2->checkOutVariables(optvars);
106  dlogpsi.resize(NumOptimizables);
107  dhpsioverpsi.resize(NumOptimizables);
108  j2->evaluateDerivatives(elec_, optvars, dlogpsi, dhpsioverpsi);
109 
110  app_log() << std::endl << "reporting dlogpsi and dhpsioverpsi" << std::scientific << std::endl;
111  for (int iparam = 0; iparam < NumOptimizables; iparam++)
112  app_log() << "param=" << iparam << " : " << dlogpsi[iparam] << " " << dhpsioverpsi[iparam] << std::endl;
113  app_log() << std::endl;
114 
115  CHECK(std::real(dlogpsi[2]) == Approx(-0.2211666667));
116  CHECK(std::real(dhpsioverpsi[3]) == Approx(0.1331717179));
117 
118 
119  // now test evaluateHessian
120  WaveFunctionComponent::HessVector grad_grad_psi;
121  grad_grad_psi.resize(elec_.getTotalNum());
122  grad_grad_psi = 0.0;
123 
124  app_log() << "eval hess" << std::endl;
125  j2->evaluateHessian(elec_, grad_grad_psi);
126  std::vector<double> hess_values = {
127  -0.0627236, 0, 0, 0, 0.10652, 0, 0, 0, 0.10652, -0.0627236, 0, 0, 0, 0.10652, 0, 0, 0, 0.10652,
128  };
129 
130  int m = 0;
131  for (int n = 0; n < elec_.getTotalNum(); n++)
132  for (int i = 0; i < OHMMS_DIM; i++)
133  for (int j = 0; j < OHMMS_DIM; j++, m++)
134  {
135  CHECK(std::real(grad_grad_psi[n](i, j)) == Approx(hess_values[m]));
136  }
137 
138 
139  struct JValues
140  {
141  double r;
142  double u;
143  double du;
144  double ddu;
145  };
146 
147  // Cut and paste from output of gen_bspline_jastrow.py
148  const int N = 20;
149  JValues Vals[N] = {{0.00, 0.1374071801, -0.5, 0.7866949593},
150  {0.60, -0.04952403966, -0.1706645865, 0.3110897524},
151  {1.20, -0.121361995, -0.09471371432, 0.055337302},
152  {1.80, -0.1695590431, -0.06815900213, 0.0331784053},
153  {2.40, -0.2058414025, -0.05505192964, 0.01049597156},
154  {3.00, -0.2382237097, -0.05422744821, -0.002401552969},
155  {3.60, -0.2712606182, -0.05600918024, -0.003537553803},
156  {4.20, -0.3047843679, -0.05428535477, 0.0101841028},
157  {4.80, -0.3347515004, -0.04506573714, 0.01469003611},
158  {5.40, -0.3597048574, -0.03904232165, 0.005388015505},
159  {6.00, -0.3823503292, -0.03657502025, 0.003511355265},
160  {6.60, -0.4036800017, -0.03415678101, 0.007891305516},
161  {7.20, -0.4219818468, -0.02556305518, 0.02075444724},
162  {7.80, -0.4192355508, 0.06799438701, 0.3266190181},
163  {8.40, -0.3019238309, 0.32586994, 0.2880861726},
164  {9.00, -0.09726352421, 0.2851358014, -0.4238666348},
165  {9.60, -0.006239062395, 0.04679296796, -0.2339648398},
166  {10.20, 0, 0, 0},
167  {10.80, 0, 0, 0},
168  {11.40, 0, 0, 0}};
169 
170 
171  BsplineFunctor<RealType>* bf = j2->getPairFunctions()[0];
172 
173  for (int i = 0; i < N; i++)
174  {
175  RealType dv = 0.0;
176  RealType ddv = 0.0;
177  RealType val = bf->evaluate(Vals[i].r, dv, ddv);
178  CHECK(Vals[i].u == Approx(val));
179  CHECK(Vals[i].du == Approx(dv));
180  CHECK(Vals[i].ddu == Approx(ddv));
181  }
182 
183 #ifdef PRINT_SPLINE_DATA
184  // write out values of the Bspline functor
185  //BsplineFunctor<double> *bf = j2->F[0];
186  printf("NumParams = %d\n", bf->NumParams);
187  printf("CuspValue = %g\n", bf->CuspValue);
188  printf("DeltaR = %g\n", bf->DeltaR);
189  printf("SplineCoeffs size = %d\n", bf->SplineCoefs.size());
190  for (int j = 0; j < bf->SplineCoefs.size(); j++)
191  {
192  printf("%d %g\n", j, bf->SplineCoefs[j]);
193  }
194  printf("\n");
195 
196  for (int i = 0; i < 20; i++)
197  {
198  double r = 0.6 * i;
199  elec_.R[0][0] = r;
200  elec_.update();
201  double logpsi_real = std::real(j2->evaluateLog(elec_, elec_.G, elec_.L));
202  //double alt_val = bf->evaluate(r);
203  double dv = 0.0;
204  double ddv = 0.0;
205  double alt_val = bf->evaluate(r, dv, ddv);
206  printf("%g %g %g %g %g\n", r, logpsi_real, alt_val, dv, ddv);
207  }
208 #endif
209 
211  using PosType = QMCTraits::PosType;
212 
213  // set virtutal particle position
214  PosType newpos(0.3, 0.2, 0.5);
215 
216  elec_.makeVirtualMoves(newpos);
217  std::vector<ValueType> ratios(elec_.getTotalNum());
218  j2->evaluateRatiosAlltoOne(elec_, ratios);
219 
220  CHECK(std::real(ratios[0]) == Approx(0.9522052017));
221  CHECK(std::real(ratios[1]) == Approx(0.9871985577));
222 
223  elec_.makeMove(0, newpos - elec_.R[0]);
224  PsiValue ratio_0 = j2->ratio(elec_, 0);
225  elec_.rejectMove(0);
226 
227  CHECK(std::real(ratio_0) == Approx(0.9522052017));
228 
229  VirtualParticleSet VP(elec_, 2);
230  std::vector<PosType> newpos2(2);
231  std::vector<ValueType> ratios2(2);
232  newpos2[0] = newpos - elec_.R[1];
233  newpos2[1] = PosType(0.2, 0.5, 0.3) - elec_.R[1];
234  VP.makeMoves(elec_, 1, newpos2);
235  j2->evaluateRatios(VP, ratios2);
236 
237  CHECK(std::real(ratios2[0]) == Approx(0.9871985577));
238  CHECK(std::real(ratios2[1]) == Approx(0.9989268241));
239 
240  //test acceptMove
241  elec_.makeMove(1, newpos - elec_.R[1]);
242  PsiValue ratio_1 = j2->ratio(elec_, 1);
243  j2->acceptMove(elec_, 1);
244  elec_.acceptMove(1);
245 
246  CHECK(std::real(ratio_1) == Approx(0.9871985577));
247  CHECK(std::real(j2->get_log_value()) == Approx(0.0883791773));
248 }
249 } // namespace qmcplusplus
void resize(size_type n, Type_t val=Type_t())
Resize the container.
Definition: OhmmsVector.h:166
void setName(const std::string &aname)
Definition: ParticleSet.h:237
T Sum(const ParticleAttrib< T > &pa)
class that handles xmlDoc
Definition: Libxml2Doc.h:76
WaveFunctionComponent::PsiValue PsiValue
Definition: SlaterDet.cpp:25
int addSpecies(const std::string &aname)
When a name species does not exist, add a new species.
Definition: SpeciesSet.cpp:33
QMCTraits::RealType real
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
BsplineFunctor class for the Jastrows REAL is the real type used by offload target, it is the correct type for the mw data pointers and is also used to coerce/implicitly convert the Real type inherited OptimizableFunctorBase into that buffer if offload is off this happens too but is just an implementation quirk.
QTBase::RealType RealType
Definition: Configuration.h:58
size_t getTotalNum() const
Definition: ParticleSet.h:493
std::ostream & app_log()
Definition: OutputManager.h:65
TEST_CASE("complex_helper", "[type_traits]")
std::unique_ptr< WaveFunctionComponent > buildComponent(xmlNodePtr cur) override
process a xml node at cur
A ParticleSet that handles virtual moves of a selected particle of a given physical ParticleSet Virtu...
void makeMoves(const ParticleSet &refp, int jel, const std::vector< PosType > &deltaV, bool sphere=false, int iat=-1)
move virtual particles to new postions and update distance tables
xmlNodePtr getRoot()
Definition: Libxml2Doc.h:88
JastrowBuilder using an analytic 1d functor Should be able to eventually handle all one and two body ...
void update(bool skipSK=false)
update the internal data
Communicate * Controller
Global Communicator for a process.
Definition: Communicate.cpp:35
ParticleLaplacian L
laplacians of the particles
Definition: ParticleSet.h:85
int addAttribute(const std::string &aname)
for a new attribute, allocate the data, !More often used to get the index of a species ...
Definition: SpeciesSet.cpp:45
#define OHMMS_DIM
Definition: config.h:64
T Dot(const ParticleAttrib< TinyVector< T, D >> &pa, const ParticleAttrib< TinyVector< T, D >> &pb)
Wrapping information on parallelism.
Definition: Communicate.h:68
Specialized paritlce class for atomistic simulations.
Definition: ParticleSet.h:55
QTBase::ValueType ValueType
Definition: Configuration.h:60
REQUIRE(std::filesystem::exists(filename))
void rejectMove(Index_t iat)
reject a proposed move in regular mode
ParticleGradient G
gradients of the particles
Definition: ParticleSet.h:83
class to handle a set of variables that can be modified during optimizations
Definition: VariableSet.h:49
ParticlePos R
Position.
Definition: ParticleSet.h:79
QTBase::PosType PosType
Definition: Configuration.h:61
Specialization for two-body Jastrow function using multiple functors.
SpeciesSet & getSpeciesSet()
retrun the SpeciesSet of this particle set
Definition: ParticleSet.h:231
void create(const std::vector< int > &agroup)
create grouped particles
QMCTraits::RealType RealType
void makeMove(Index_t iat, const SingleParticlePos &displ, bool maybe_accept=true)
move the iat-th particle to active_pos_
bool parseFromString(const std::string_view data)
Definition: Libxml2Doc.cpp:204
Declaraton of ParticleAttrib<T>
CHECK(log_values[0]==ComplexApprox(std::complex< double >{ 5.603777579195571, -6.1586603331188225 }))
TinyVector< double, 3 > PosType
OrbitalSetTraits< ValueType >::HessVector HessVector
LatticeGaussianProduct::ValueType ValueType
Declaration of WaveFunctionComponent.
Custom container for set of attributes for a set of species.
Definition: SpeciesSet.h:33
Real evaluate(Real r) const
void acceptMove(Index_t iat)
accept the move and update the particle attribute by the proposed move in regular mode ...
void makeVirtualMoves(const SingleParticlePos &newpos)
Handles virtual moves for all the particles to a single newpos.