QMCPACK
test_example_he.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) 2019 Jeongnim Kim and QMCPACK developers.
6 //
7 // File developed by: Mark Dewing, mdewing@anl.gov, Argonne National Laboratory
8 //
9 // File created by: Mark Dewing, mdewing@anl.gov, Argonne National Laboratory
10 //////////////////////////////////////////////////////////////////////////////////////
11 
12 
13 #include "catch.hpp"
14 
15 #include "Configuration.h"
16 #include "Message/Communicate.h"
18 #include "OhmmsData/Libxml2Doc.h"
22 
23 namespace qmcplusplus
24 {
29 
30 TEST_CASE("ExampleHe", "[wavefunction]")
31 {
33 
34  const SimulationCell simulation_cell;
35 
36  auto elec_ptr = std::make_unique<ParticleSet>(simulation_cell);
37  auto& elec(*elec_ptr);
38 
39  std::vector<int> agroup(1);
40  int nelec = 2;
41  agroup[0] = nelec;
42  elec.setName("e");
43  elec.create(agroup);
44  elec.R[0] = {1.0, 2.0, 3.0};
45  elec.R[1] = {0.0, 1.1, 2.2};
46  SpeciesSet& tspecies = elec.getSpeciesSet();
47  int upIdx = tspecies.addSpecies("u");
48  int downIdx = tspecies.addSpecies("d");
49  int massIdx = tspecies.addAttribute("mass");
50  tspecies(massIdx, upIdx) = 1.0;
51  tspecies(massIdx, downIdx) = 1.0;
52 
53  auto ions_ptr = std::make_unique<ParticleSet>(simulation_cell);
54  auto& ions(*ions_ptr);
55 
56  ions.setName("ion0");
57  ions.create({1});
58  ions.R[0] = {0.0, 0.0, 0.0};
59  SpeciesSet& he_species = ions.getSpeciesSet();
60  int He_Idx = he_species.addSpecies("He");
61  int chargeIdx = he_species.addAttribute("charge");
62  tspecies(chargeIdx, He_Idx) = 2.0;
63  tspecies(massIdx, upIdx) = 1.0;
64 
65  WaveFunctionFactory::PSetMap particle_set_map;
66  particle_set_map.emplace(elec_ptr->getName(), std::move(elec_ptr));
67  particle_set_map.emplace(ions_ptr->getName(), std::move(ions_ptr));
68 
69  WaveFunctionFactory wff(elec, particle_set_map, c);
70 
71  const char* wavefunction_xml = R"(<wavefunction>
72  <example_he name="mine" source="ion0">
73  <var id="B" name="B">0.8</var>
74  </example_he>
75 </wavefunction>)";
77  bool okay = doc.parseFromString(wavefunction_xml);
78  REQUIRE(okay);
79 
80  xmlNodePtr root = doc.getRoot();
81  RuntimeOptions runtime_options;
82  auto twf_ptr = wff.buildTWF(root, runtime_options);
83 
84  REQUIRE(twf_ptr != nullptr);
85  REQUIRE(twf_ptr->size() == 1);
86 
87  auto& base_example_he = twf_ptr->getOrbitals()[0];
88  REQUIRE(base_example_he != nullptr);
89 
90  ExampleHeComponent* example_he = dynamic_cast<ExampleHeComponent*>(base_example_he.get());
91  REQUIRE(example_he != nullptr);
92 
93  ions.update();
94  elec.update();
95 
98  all_grad.resize(nelec);
99  all_lap.resize(nelec);
100 
101  // Set the base expectations for wavefunction value and derivatives
102  LogValue logpsi = example_he->evaluateLog(elec, all_grad, all_lap);
103 
104  // Comparisons are performed at a single set of electron coordinates. This should be expanded.
105 
106  // Compare with evalGrad
107 
108  ParticleSet::GradType grad0;
109  int iat = 0;
110  grad0 = example_he->evalGrad(elec, iat);
111 
112  CHECK(grad0[0] == ValueApprox(all_grad[0][0]));
113  CHECK(grad0[1] == ValueApprox(all_grad[0][1]));
114  CHECK(grad0[2] == ValueApprox(all_grad[0][2]));
115 
116  ParticleSet::GradType grad1;
117  iat = 1;
118  grad1 = example_he->evalGrad(elec, iat);
119 
120  CHECK(grad1[0] == ValueApprox(all_grad[1][0]));
121  CHECK(grad1[1] == ValueApprox(all_grad[1][1]));
122  CHECK(grad1[2] == ValueApprox(all_grad[1][2]));
123 
124 
125  // Compare ratio and ratioGrad with a zero displacement
126  ParticleSet::SingleParticlePos zero_displ(0.0, 0.0, 0.0);
127  iat = 0;
128  elec.makeMove(iat, zero_displ);
129 
130 
131  PsiValue ratio = example_he->ratio(elec, iat);
132  CHECK(std::real(ratio) == Approx(1.0));
133 
134  ratio = example_he->ratioGrad(elec, iat, grad0);
135 
136  CHECK(std::real(ratio) == Approx(1.0));
137 
138  CHECK(grad0[0] == ValueApprox(all_grad[0][0]));
139  CHECK(grad0[1] == ValueApprox(all_grad[0][1]));
140  CHECK(grad0[2] == ValueApprox(all_grad[0][2]));
141 
142  iat = 1;
143  elec.makeMove(iat, zero_displ);
144  ratio = example_he->ratio(elec, iat);
145  CHECK(std::real(ratio) == Approx(1.0));
146 
147 
148  ratio = example_he->ratioGrad(elec, iat, grad1);
149 
150  CHECK(std::real(ratio) == Approx(1.0));
151  CHECK(grad1[0] == ValueApprox(all_grad[1][0]));
152  CHECK(grad1[1] == ValueApprox(all_grad[1][1]));
153  CHECK(grad1[2] == ValueApprox(all_grad[1][2]));
154 
155  // Compare ratio and ratioGrad with a non-zero displacement
156  // Should compare more displacements
157  ParticleSet::SingleParticlePos oldpos = elec.R[0];
158  ParticleSet::SingleParticlePos displ(0.15, 0.10, 0.21);
159  elec.R[0] = oldpos + displ;
160  elec.update();
163  new_grad.resize(nelec);
164  new_lap.resize(nelec);
165 
166  // wavefunction value and derivatives at new position
167  LogValue new_logpsi = example_he->evaluateLog(elec, new_grad, new_lap);
168  elec.R[0] = oldpos;
169  elec.update();
170 
171  iat = 0;
172  elec.makeMove(iat, displ);
173 
174  ratio = example_he->ratio(elec, iat);
175  CHECK(ValueApprox(ratio) == LogToValue<PsiValue>::convert(new_logpsi - logpsi));
176 
177  ratio = example_he->ratioGrad(elec, iat, grad0);
178 
179  CHECK(ValueApprox(ratio) == LogToValue<PsiValue>::convert(new_logpsi - logpsi));
180 
181  CHECK(grad0[0] == ValueApprox(new_grad[0][0]));
182  CHECK(grad0[1] == ValueApprox(new_grad[0][1]));
183  CHECK(grad0[2] == ValueApprox(new_grad[0][2]));
184 
185  // Compare parameter derivatives
186 
187  const int nparam = 1;
188  optimize::VariableSet var_param;
189  example_he->checkInVariablesExclusive(var_param);
190  REQUIRE(var_param.size_of_active() == nparam);
191 
192  example_he->checkOutVariables(var_param);
193 
194  RealType old_B = example_he->B;
195  // Interval size for finite-difference approximation to parameter derivative
196  RealType h = 0.01;
197  RealType new_B = old_B + h;
198 
199  var_param["B"] = new_B;
200  example_he->resetParametersExclusive(var_param);
201  CHECK(example_he->B == Approx(new_B));
202 
203  ParticleSet::ParticleGradient grad_plus_h;
205  grad_plus_h.resize(nelec);
206  lap_plus_h.resize(nelec);
207 
208  LogValue logpsi_plus_h = example_he->evaluateLog(elec, grad_plus_h, lap_plus_h);
209 
210  //phase change is not allowed in finite difference
211  REQUIRE(std::imag(logpsi_plus_h) == std::imag(logpsi));
212 
213  // Finite difference derivative approximation
214  LogValue fd_logpsi = (logpsi_plus_h - logpsi) / LogValue(h);
215 
216  Vector<ValueType> dlogpsi(nparam);
217  Vector<ValueType> dhpsioverpsi(nparam);
218  example_he->evaluateDerivatives(elec, var_param, dlogpsi, dhpsioverpsi);
219 
220  CHECK(dlogpsi[0] == ValueApprox(std::real(fd_logpsi)).epsilon(h));
221 
222  ValueType eloc = -0.5 * (Sum(all_lap) + Dot(all_grad, all_grad));
223  ValueType eloc_h = -0.5 * (Sum(lap_plus_h) + Dot(grad_plus_h, grad_plus_h));
224 
225  ValueType fd_eloc = (eloc_h - eloc) / h;
226 
227  CHECK(dhpsioverpsi[0] == ValueApprox(fd_eloc).epsilon(h));
228 }
229 } // namespace qmcplusplus
void resize(size_type n, Type_t val=Type_t())
Resize the container.
Definition: OhmmsVector.h:166
LogValue evaluateLog(const ParticleSet &P, ParticleSet::ParticleGradient &G, ParticleSet::ParticleLaplacian &L) override
evaluate the value of the WaveFunctionComponent from scratch
T Sum(const ParticleAttrib< T > &pa)
Fixed-size array.
Definition: OhmmsTinyMeta.h:30
class that handles xmlDoc
Definition: Libxml2Doc.h:76
void checkInVariablesExclusive(OptVariablesType &active) override
check in variational parameters to the global list of parameters used by the optimizer.
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
QTBase::RealType RealType
Definition: Configuration.h:58
An example wavefunction component for a simple wavefunction for a helium atom.
TEST_CASE("complex_helper", "[type_traits]")
xmlNodePtr getRoot()
Definition: Libxml2Doc.h:88
evaluate psi based on log(psi)
GradType evalGrad(ParticleSet &P, int iat) override
return the current gradient for the iat-th particle
void evaluateDerivatives(ParticleSet &P, const OptVariablesType &optvars, Vector< ValueType > &dlogpsi, Vector< ValueType > &dhpsioverpsi) override
Compute the derivatives of both the log of the wavefunction and kinetic energy with respect to optimi...
Attaches a unit to a Vector for IO.
Communicate * Controller
Global Communicator for a process.
Definition: Communicate.cpp:35
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
T Dot(const ParticleAttrib< TinyVector< T, D >> &pa, const ParticleAttrib< TinyVector< T, D >> &pb)
std::complex< QTFull::RealType > LogValue
Wrapping information on parallelism.
Definition: Communicate.h:68
float imag(const float &c)
imaginary part of a scalar. Cannot be replaced by std::imag due to AFQMC specific needs...
PsiValue ratio(ParticleSet &P, int iat) override
evaluate the ratio of the new to old WaveFunctionComponent value
std::unique_ptr< TrialWaveFunction > buildTWF(xmlNodePtr cur, const RuntimeOptions &runtime_options)
read from xmlNode
QTBase::ValueType ValueType
Definition: Configuration.h:60
REQUIRE(std::filesystem::exists(filename))
void resetParametersExclusive(const OptVariablesType &active) override
reset the parameters during optimizations.
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
int size_of_active() const
return the number of active variables
Definition: VariableSet.h:78
QMCTraits::RealType RealType
std::map< std::string, const std::unique_ptr< ParticleSet > > PSetMap
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 }))
PsiValue ratioGrad(ParticleSet &P, int iat, GradType &grad_iat) override
evaluate the ratio of the new to old WaveFunctionComponent value and the new gradient ...
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
void checkOutVariables(const OptVariablesType &active) override
check out variational optimizable variables