QMCPACK
test_2d_jastrow.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) 2022 Jeongnim Kim and QMCPACK developers.
6 //
7 // File developed by: Yubo "Paul" Yang, yubo.paul.yang@gmail.com, CCQ @ Flatiron
8 //
9 // File created by: Yubo "Paul" Yang, yubo.paul.yang@gmail.com, CCQ @ Flatiron
10 //////////////////////////////////////////////////////////////////////////////////////
11 
12 
13 #include "catch.hpp"
14 
15 #include "OhmmsData/Libxml2Doc.h"
16 #include "ParticleIO/XMLParticleIO.h" // XMLParticleParser
19 
20 using std::imag;
21 using std::real;
22 
23 namespace qmcplusplus
24 {
27 using ValueType = QMCTraits::ValueType; // for real and mixed precision
29 
30 TEST_CASE("Jastrow 2D", "[wavefunction]")
31 {
34  xmlNodePtr root, node;
35  bool okay;
36 
37  // Step 1: create Jastrow
38  // TwoBodyJastrow<BsplineFunctor<RealType>> j2;
39  // RadialJastrowBuilder jastrow(Communicator, ParticleSet);
40  // ParticleSet( SimulationCell( CrystalLattice ) )
42  lattice.BoxBConds = true;
43  lattice.R.diagonal(70.89815403622065);
44  lattice.ndim = 2;
45  lattice.reset();
46  const SimulationCell cell(lattice);
47  ParticleSet elec(cell);
48  // read ParticleSet from xml text
49  const char* particle_text = R"(<tmp>
50  <particleset name="e" random="no">
51  <group name="u" size="2">
52  <parameter name="charge"> -1 </parameter>
53  <attrib name="position" datatype="posArray" condition="0">
54 54.66209032978565 2.018663420381362 0.0
55 23.566489035927912 3.443259712257945 0.0
56 </attrib>
57  </group>
58  <group name="d" size="2">
59  <parameter name="charge"> -1 </parameter>
60  <attrib name="position" datatype="posArray" condition="0">
61 67.26206197993817 30.29582561496142 0.0
62 37.00657847142635 1.4508035033146867 0.0
63 </attrib>
64  </group>
65  </particleset>
66  </tmp>)";
67  okay = doc.parseFromString(particle_text);
68  REQUIRE(okay);
69  root = doc.getRoot();
70  node = xmlFirstElementChild(root);
71  XMLParticleParser parse_electrons(elec);
72  parse_electrons.readXML(node);
73  int itab;
74  elec.addTable(elec);
75  elec.update(); // update distance tables
76  const int nelec = elec.getTotalNum();
77  // read Jastrow component from xml text
78  const char* jastrow_text = R"(<tmp>
79  <jastrow name="J2" type="Two-Body" function="Bspline">
80  <correlation speciesA="u" speciesB="u" size="8">
81  <coefficients id="uu" type="Array" optimize="yes">4.868951397 3.154235815 1.719776072 0.9676536301 0.6044866223 0.3368526364 0.1566214572 0.06031539785</coefficients>
82  </correlation>
83  <correlation speciesA="u" speciesB="d" size="8">
84  <coefficients id="ud" type="Array" optimize="yes">6.991319036 3.93760887 2.077967513 1.115208829 0.6946729632 0.3826149045 0.1705411558 0.06155742938</coefficients>
85  </correlation>
86  </jastrow>
87 </tmp>)";
88  okay = doc.parseFromString(jastrow_text);
89  REQUIRE(okay);
90  root = doc.getRoot();
91  node = xmlFirstElementChild(root);
92  RadialJastrowBuilder jastrow(c, elec);
94  auto j2_uptr = jastrow.buildComponent(node);
95  J2Type* j2 = dynamic_cast<J2Type*>(j2_uptr.get());
96  REQUIRE(j2);
97 
98  // Step 2: test Jastrow vglh
99  double logpsi = real(j2->evaluateLog(elec, elec.G, elec.L));
100  CHECK(real(logpsi) == Approx(-1.51908));
101  CHECK(real(elec.G[0][0]) == Approx(0.08490220791));
102  CHECK(real(elec.G[0][1]) == Approx(-0.006958062051));
103  CHECK(real(elec.G[1][0]) == Approx(-0.1325957095));
104  CHECK(real(elec.G[1][1]) == Approx(0.01872445072));
105  CHECK(real(elec.G[2][0]) == Approx(0.004059085343));
106  CHECK(real(elec.G[2][1]) == Approx(0.009109497845));
107  CHECK(real(elec.G[3][0]) == Approx(0.04363441629));
108  CHECK(real(elec.G[3][1]) == Approx(-0.02087588652));
109  for (int i = 0; i < nelec; i++)
110  {
111  for (int l = 0; l < OHMMS_DIM; l++)
112  CHECK(imag(elec.G[i][l]) == Approx(0));
113  CHECK(real(elec.G[i][2]) == Approx(0)); // ndim=2
114  }
115  const std::vector<RealType> lap_values = {-0.00916449, -0.0166369, -0.00351783, -0.0153977};
116  for (int m = 0; m < nelec; m++)
117  CHECK(real(elec.L[m]) == Approx(lap_values[m]));
118 
119  WaveFunctionComponent::HessVector grad_grad_psi;
120  grad_grad_psi.resize(nelec);
121  grad_grad_psi = 0.0;
122 
123  CHECK_THROWS(j2->evaluateHessian(elec, grad_grad_psi));
124  //std::vector<double> hess_values = {
125  // -0.0108098, -0.00172466, 0,
126  // -0.00172466, 0.00164531, 0,
127  // 0, 0, 0.00513802,
128  // -0.0254307, 0.00476379, 0,
129  // 0.00476379, 0.00879376, 0,
130  // 0, 0, 0.00948111,
131  // -0.000367339, -0.00154737, 0,
132  // -0.00154737, -0.00315049, 0,
133  // 0, 0, 0.00032215,
134  // -0.0284186, 0.00421815, 0,
135  // 0.00421815, 0.0130209, 0,
136  // 0, 0, 0.0137115
137  //}; // why do the zz components have non-zero values?
138 
139  //int m = 0;
140  //for (int n = 0; n < nelec; n++)
141  // for (int i = 0; i < OHMMS_DIM; i++)
142  // for (int j = 0; j < OHMMS_DIM; j++, m++)
143  // CHECK(real(grad_grad_psi[n](i, j)) == Approx(hess_values[m]));
144 
145  // Step 3: test Jastrow ratio for pbyp move
146  PosType newpos(0.3, 0.2, 0.5);
147 
148  elec.makeVirtualMoves(newpos);
149  std::vector<ValueType> ratios(nelec);
150  j2->evaluateRatiosAlltoOne(elec, ratios);
151  std::vector<double> ratio_values = {1.46023, 1.46559, 0.444258, 1.90226};
152  for (int i = 0; i < ratios.size(); i++)
153  CHECK(real(ratios[i]) == Approx(ratio_values[i]));
154 
155  for (int i = 0; i < nelec; i++)
156  {
157  elec.makeMove(i, newpos - elec.R[i]);
158  PsiValue rat1 = j2->ratio(elec, i);
159  CHECK(real(rat1) == Approx(ratio_values[i]));
160  elec.rejectMove(i);
161  }
162 
163  // Step 4: test Jastrow parameter derivatives
164  UniqueOptObjRefs opt_obj_refs;
165  j2->extractOptimizableObjectRefs(opt_obj_refs);
166  REQUIRE(opt_obj_refs.size() == 2);
167 
168  opt_variables_type optvars;
169  Vector<ValueType> dlogpsi;
170  Vector<ValueType> dhpsioverpsi;
171 
172  for (OptimizableObject& obj : opt_obj_refs)
173  obj.checkInVariablesExclusive(optvars);
174  optvars.resetIndex();
175  const int NumOptimizables(optvars.size());
176  j2->checkOutVariables(optvars);
177  dlogpsi.resize(NumOptimizables);
178  dhpsioverpsi.resize(NumOptimizables);
179  j2->evaluateDerivatives(elec, optvars, dlogpsi, dhpsioverpsi);
180  app_log() << std::endl << "reporting dlogpsi and dhpsioverpsi" << std::scientific << std::endl;
181  for (int iparam = 0; iparam < NumOptimizables; iparam++)
182  app_log() << "param=" << iparam << " : " << dlogpsi[iparam] << " " << dhpsioverpsi[iparam] << std::endl;
183  app_log() << std::endl;
184  const std::vector<RealType> dlogpsi_values = {0, 0, 0, 0, 0, 0, -1.521258e-04, -2.194165e-01, 0, 0, -2.779981e-02, -5.327999e-01, -9.356640e-01, -4.847466e-01, -1.945081e-02, -2.453297e-01};
185  const std::vector<RealType> dhpsi_values = {0, 0, 0, 0, 0, 0, 5.953288e-03, 8.618836e-03, 0, 0, 2.572195e-02, -5.048126e-02, -3.139861e-02, 2.197638e-02, 4.319522e-02, 3.512834e-02};
186  for (int iparam = 0; iparam < NumOptimizables; iparam++)
187  {
188  CHECK(real(dlogpsi[iparam]) == Approx(dlogpsi_values[iparam]));
189  CHECK(real(dhpsioverpsi[iparam]) == Approx(dhpsi_values[iparam]));
190  }
191 }
192 } // namespace qmcplusplus
void resize(size_type n, Type_t val=Type_t())
Resize the container.
Definition: OhmmsVector.h:166
a class that defines a supercell in D-dimensional Euclean space.
class that handles xmlDoc
Definition: Libxml2Doc.h:76
WaveFunctionComponent::PsiValue PsiValue
Definition: SlaterDet.cpp:25
QMCTraits::RealType real
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
QTBase::RealType RealType
Definition: Configuration.h:58
if(!okay) throw std xmlNodePtr node
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
xmlNodePtr getRoot()
Definition: Libxml2Doc.h:88
JastrowBuilder using an analytic 1d functor Should be able to eventually handle all one and two body ...
float real(const float &c)
real part of a scalar. Cannot be replaced by std::real due to AFQMC specific needs.
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
#define OHMMS_DIM
Definition: config.h:64
QMCTraits::PosType PosType
Wrapping information on parallelism.
Definition: Communicate.h:68
CrystalLattice< OHMMS_PRECISION, OHMMS_DIM > lattice
int addTable(const ParticleSet &psrc, DTModes modes=DTModes::ALL_OFF)
add a distance table
Specialized paritlce class for atomistic simulations.
Definition: ParticleSet.h:55
float imag(const float &c)
imaginary part of a scalar. Cannot be replaced by std::imag due to AFQMC specific needs...
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
bool readXML(xmlNodePtr cur)
process xmlnode <particleset/> which contains everything about the particle set to initialize ...
ParticlePos R
Position.
Definition: ParticleSet.h:79
QTBase::PosType PosType
Definition: Configuration.h:61
Specialization for two-body Jastrow function using multiple functors.
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
CHECK(log_values[0]==ComplexApprox(std::complex< double >{ 5.603777579195571, -6.1586603331188225 }))
OrbitalSetTraits< ValueType >::HessVector HessVector
LatticeGaussianProduct::ValueType ValueType
void makeVirtualMoves(const SingleParticlePos &newpos)
Handles virtual moves for all the particles to a single newpos.