QMCPACK
test_J1Spin.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) 2021 QMCPACK developers.
6 //
7 // File developed by: Shiv Upadhyay, shivnupadhyay@gmail.com, University of Pittsburgh
8 //
9 // File created by: Shiv Upadhyay, shivnupadhyay@gmail.com, University of Pittsburgh
10 //////////////////////////////////////////////////////////////////////////////////////
11 
12 #include "catch.hpp"
13 
20 
21 namespace qmcplusplus
22 {
26 
27 TEST_CASE("J1 spin evaluate derivatives Jastrow", "[wavefunction]")
28 {
30 
32  auto ions_uptr = std::make_unique<ParticleSet>(ptcl.getSimulationCell());
33  auto elec_uptr = std::make_unique<ParticleSet>(ptcl.getSimulationCell());
34  ParticleSet& ions_(*ions_uptr);
35  ParticleSet& elec_(*elec_uptr);
36 
37  ions_.setName("ion0");
38  ptcl.addParticleSet(std::move(ions_uptr));
39  ions_.create({1});
40  ions_.R[0] = {0.0, 0.0, 0.0};
41  SpeciesSet& ispecies = ions_.getSpeciesSet();
42  int HIdx = ispecies.addSpecies("H");
43  int ichargeIdx = ispecies.addAttribute("charge");
44  ispecies(ichargeIdx, HIdx) = 1.0;
45 
46  elec_.setName("e");
47  ptcl.addParticleSet(std::move(elec_uptr));
48  elec_.create({1, 1});
49  elec_.R[0] = {0.5, 0.5, 0.5};
50  elec_.R[1] = {-0.5, -0.5, -0.5};
51 
52  SpeciesSet& tspecies = elec_.getSpeciesSet();
53  int upIdx = tspecies.addSpecies("u");
54  int downIdx = tspecies.addSpecies("d");
55  int massIdx = tspecies.addAttribute("mass");
56  int chargeIdx = tspecies.addAttribute("charge");
57  tspecies(massIdx, upIdx) = 1.0;
58  tspecies(massIdx, downIdx) = 1.0;
59  tspecies(chargeIdx, upIdx) = -1.0;
60  tspecies(massIdx, downIdx) = -1.0;
61  // Necessary to set mass
62  elec_.resetGroups();
63 
64  ions_.update();
65  elec_.addTable(elec_);
66  elec_.addTable(ions_);
67  elec_.update();
68 
69  const char* jasxml = R"(<wavefunction name="psi0" target="e">
70 <jastrow name="J1" type="One-Body" function="Bspline" print="yes" source="ion0" spin="yes">
71  <correlation speciesA="H" speciesB="u" cusp="0.0" size="2" rcut="5.0">
72  <coefficients id="J1uH" type="Array"> 0.5 0.1 </coefficients>
73  </correlation>
74  <correlation speciesA="H" speciesB="d" cusp="0.0" size="2" rcut="5.0">
75  <coefficients id="J1dH" type="Array"> 0.5 0.1 </coefficients>
76  </correlation>
77 </jastrow>
78 </wavefunction>
79 )";
81  bool okay = doc.parseFromString(jasxml);
82  REQUIRE(okay);
83  xmlNodePtr jas1 = doc.getRoot();
84  WaveFunctionFactory wf_factory(elec_, ptcl.getPool(), c);
85  RuntimeOptions runtime_options;
86  auto twf_ptr = wf_factory.buildTWF(jas1, runtime_options);
87  auto& twf(*twf_ptr);
88  twf.setMassTerm(elec_);
89  auto& twf_component_list = twf.getOrbitals();
90  auto cloned_j1spin = twf_component_list[0]->makeClone(elec_);
91 
92  opt_variables_type active;
93  twf.checkInVariables(active);
94  active.removeInactive();
95  int nparam = active.size_of_active();
96  REQUIRE(nparam == 4);
97 
98  // check logs
99  //evaluateLog += into G + L so reset
100  elec_.G = 0.0;
101  elec_.L = 0.0;
102  LogValue log = twf_component_list[0]->evaluateLog(elec_, elec_.G, elec_.L);
103  LogValue expected_log{-0.568775, 0.0};
104  CHECK(log == LogComplexApprox(expected_log));
105  //evaluateLog += into G + L so reset
106  elec_.G = 0.0;
107  elec_.L = 0.0;
108  LogValue cloned_log = cloned_j1spin->evaluateLog(elec_, elec_.G, elec_.L);
109  CHECK(cloned_log == LogComplexApprox(expected_log));
110 
111  // check derivatives
112  twf.evaluateLog(elec_);
113  Vector<ValueType> dlogpsi(nparam);
114  Vector<ValueType> dhpsioverpsi(nparam);
115  Vector<ValueType> cloned_dlogpsi(nparam);
116  Vector<ValueType> cloned_dhpsioverpsi(nparam);
117 
118  twf_component_list[0]->evaluateDerivatives(elec_, active, dlogpsi, dhpsioverpsi);
119  cloned_j1spin->evaluateDerivatives(elec_, active, cloned_dlogpsi, cloned_dhpsioverpsi);
120  // Numbers not validated
121  std::vector<ValueType> expected_dlogpsi = {-0.46681472435, -0.5098025897, -0.46681472435, -0.5098025897};
122  std::vector<ValueType> expected_dhpsioverpsi = {-0.5798216548, 0.37977462695, -0.5798216548, 0.37977462695};
123  for (int i = 0; i < nparam; i++)
124  {
125  CHECK(dlogpsi[i] == ValueApprox(expected_dlogpsi[i]));
126  CHECK(cloned_dlogpsi[i] == ValueApprox(expected_dlogpsi[i]));
127  CHECK(dhpsioverpsi[i] == ValueApprox(expected_dhpsioverpsi[i]));
128  CHECK(cloned_dhpsioverpsi[i] == ValueApprox(expected_dhpsioverpsi[i]));
129  }
130 }
131 
132 TEST_CASE("J1 spin evaluate derivatives multiparticle Jastrow", "[wavefunction]")
133 {
135 
137  auto ions_uptr = std::make_unique<ParticleSet>(ptcl.getSimulationCell());
138  auto elec_uptr = std::make_unique<ParticleSet>(ptcl.getSimulationCell());
139  ParticleSet& ions_(*ions_uptr);
140  ParticleSet& elec_(*elec_uptr);
141 
142  ions_.setName("ion0");
143  ptcl.addParticleSet(std::move(ions_uptr));
144  ions_.create({2});
145  ions_.R[0] = {-1.0, 0.0, 0.0};
146  ions_.R[1] = {1.0, 0.0, 0.0};
147  SpeciesSet& ispecies = ions_.getSpeciesSet();
148  int BeIdx = ispecies.addSpecies("Be");
149  int ichargeIdx = ispecies.addAttribute("charge");
150  ispecies(ichargeIdx, BeIdx) = 4.0;
151 
152  elec_.setName("e");
153  ptcl.addParticleSet(std::move(elec_uptr));
154  elec_.create({4, 4, 1});
155  elec_.R[0] = {0.5, 0.5, 0.5};
156  elec_.R[1] = {-0.5, 0.5, 0.5};
157  elec_.R[2] = {0.5, -0.5, 0.5};
158  elec_.R[3] = {0.5, 0.5, -0.5};
159  elec_.R[4] = {-0.5, -0.5, 0.5};
160  elec_.R[5] = {0.5, -0.5, -0.5};
161  elec_.R[6] = {-0.5, 0.5, -0.5};
162  elec_.R[7] = {-0.5, -0.5, -0.5};
163  elec_.R[8] = {1.5, 1.5, 1.5};
164 
165  SpeciesSet& tspecies = elec_.getSpeciesSet();
166  int upIdx = tspecies.addSpecies("u");
167  int downIdx = tspecies.addSpecies("d");
168  int posIdx = tspecies.addSpecies("p");
169  int massIdx = tspecies.addAttribute("mass");
170  int chargeIdx = tspecies.addAttribute("charge");
171  tspecies(massIdx, upIdx) = 1.0;
172  tspecies(massIdx, downIdx) = 1.0;
173  tspecies(massIdx, posIdx) = 1.0;
174  tspecies(chargeIdx, upIdx) = -1.0;
175  tspecies(massIdx, downIdx) = -1.0;
176  tspecies(massIdx, posIdx) = 1.0;
177  // Necessary to set mass
178  elec_.resetGroups();
179 
180  ions_.update();
181  elec_.addTable(elec_);
182  elec_.addTable(ions_);
183  elec_.update();
184 
185  const char* jasxml = R"(<wavefunction name="psi0" target="e">
186 <jastrow name="J1" type="One-Body" function="Bspline" print="yes" source="ion0" spin="yes">
187  <correlation speciesA="Be" speciesB="u" cusp="0.0" size="2" rcut="5.0">
188  <coefficients id="J1uH" type="Array"> 0.5 0.1 </coefficients>
189  </correlation>
190  <correlation speciesA="Be" speciesB="d" cusp="0.0" size="2" rcut="5.0">
191  <coefficients id="J1dH" type="Array"> 0.5 0.1 </coefficients>
192  </correlation>
193  <correlation speciesA="Be" speciesB="p" cusp="0.0" size="2" rcut="5.0">
194  <coefficients id="J1pH" type="Array"> 0.5 0.1 </coefficients>
195  </correlation>
196 </jastrow>
197 </wavefunction>
198 )";
200  bool okay = doc.parseFromString(jasxml);
201  REQUIRE(okay);
202  xmlNodePtr jas1 = doc.getRoot();
203  WaveFunctionFactory wf_factory(elec_, ptcl.getPool(), c);
204  RuntimeOptions runtime_options;
205  auto twf_ptr = wf_factory.buildTWF(jas1, runtime_options);
206  auto& twf(*twf_ptr);
207  twf.setMassTerm(elec_);
208  auto& twf_component_list = twf.getOrbitals();
209  auto cloned_j1spin = twf_component_list[0]->makeClone(elec_);
210 
211  opt_variables_type active;
212  twf.checkInVariables(active);
213  active.removeInactive();
214  int nparam = active.size_of_active();
215  REQUIRE(nparam == 6);
216 
217  // check logs
218  //evaluateLog += into G + L so reset
219  elec_.G = 0.0;
220  elec_.L = 0.0;
221  LogValue log = twf_component_list[0]->evaluateLog(elec_, elec_.G, elec_.L);
222  LogValue expected_log{-3.58983, 0.0};
223  CHECK(log == LogComplexApprox(expected_log));
224  //evaluateLog += into G + L so reset
225  elec_.G = 0.0;
226  elec_.L = 0.0;
227  LogValue cloned_log = cloned_j1spin->evaluateLog(elec_, elec_.G, elec_.L);
228  CHECK(cloned_log == LogComplexApprox(expected_log));
229 
230  // check derivatives
231  twf.evaluateLog(elec_);
232  Vector<ValueType> dlogpsi(nparam);
233  Vector<ValueType> dhpsioverpsi(nparam);
234  Vector<ValueType> cloned_dlogpsi(nparam);
235  Vector<ValueType> cloned_dhpsioverpsi(nparam);
236 
237  twf_component_list[0]->evaluateDerivatives(elec_, active, dlogpsi, dhpsioverpsi);
238  cloned_j1spin->evaluateDerivatives(elec_, active, cloned_dlogpsi, cloned_dhpsioverpsi);
239  // Numbers not validated
240  std::vector<ValueType> expected_dlogpsi = {-2.544, -4.70578, -2.544, -4.70578, -0.055314, -0.770138};
241  std::vector<ValueType> expected_dhpsioverpsi = {-2.45001, 0.0794429, -2.45001, 0.0794429, 0.0462761, -0.330801};
242  for (int i = 0; i < nparam; i++)
243  {
244  CHECK(dlogpsi[i] == ValueApprox(expected_dlogpsi[i]));
245  CHECK(cloned_dlogpsi[i] == ValueApprox(expected_dlogpsi[i]));
246  CHECK(dhpsioverpsi[i] == ValueApprox(expected_dhpsioverpsi[i]));
247  CHECK(cloned_dhpsioverpsi[i] == ValueApprox(expected_dhpsioverpsi[i]));
248  }
249 }
250 } // namespace qmcplusplus
void setName(const std::string &aname)
Definition: ParticleSet.h:237
class that handles xmlDoc
Definition: Libxml2Doc.h:76
int addSpecies(const std::string &aname)
When a name species does not exist, add a new species.
Definition: SpeciesSet.cpp:33
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
QTBase::RealType RealType
Definition: Configuration.h:58
TEST_CASE("complex_helper", "[type_traits]")
void addParticleSet(std::unique_ptr< ParticleSet > &&p)
add a ParticleSet* to the pool with its ownership transferred ParticleSet built outside the ParticleS...
xmlNodePtr getRoot()
Definition: Libxml2Doc.h:88
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
Catch::Detail::LogComplexApprox LogComplexApprox
std::complex< QTFull::RealType > LogValue
Wrapping information on parallelism.
Definition: Communicate.h:68
int addTable(const ParticleSet &psrc, DTModes modes=DTModes::ALL_OFF)
add a distance table
Specialized paritlce class for atomistic simulations.
Definition: ParticleSet.h:55
QTBase::ValueType ValueType
Definition: Configuration.h:60
REQUIRE(std::filesystem::exists(filename))
Manage a collection of ParticleSet objects.
ParticleGradient G
gradients of the particles
Definition: ParticleSet.h:83
Factory class to build a many-body wavefunction.
class to handle a set of variables that can be modified during optimizations
Definition: VariableSet.h:49
ParticlePos R
Position.
Definition: ParticleSet.h:79
int size_of_active() const
return the number of active variables
Definition: VariableSet.h:78
SpeciesSet & getSpeciesSet()
retrun the SpeciesSet of this particle set
Definition: ParticleSet.h:231
void create(const std::vector< int > &agroup)
create grouped particles
MakeReturn< UnaryNode< FnLog, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t log(const Vector< T1, C1 > &l)
QMCTraits::RealType RealType
bool parseFromString(const std::string_view data)
Definition: Libxml2Doc.cpp:204
CHECK(log_values[0]==ComplexApprox(std::complex< double >{ 5.603777579195571, -6.1586603331188225 }))
LatticeGaussianProduct::ValueType ValueType
Declaration of a WaveFunctionFactory.
std::complex< double > LogValue
Custom container for set of attributes for a set of species.
Definition: SpeciesSet.h:33
const PoolType & getPool() const
get the Pool object
void removeInactive()
remove inactive variables and trim the internal data
const auto & getSimulationCell() const
get simulation cell
Declaration of ParticleSetPool.