QMCPACK
test_dmc_driver.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) 2018 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 
16 #include "Utilities/ProjectData.h"
18 #include "OhmmsData/Libxml2Doc.h"
19 #include "OhmmsPETE/OhmmsMatrix.h"
20 #include "Particle/ParticleSet.h"
31 #include "QMCDrivers/DMC/DMC.h"
32 
33 
34 #include <stdio.h>
35 #include <string>
36 
37 
38 using std::string;
39 
40 namespace qmcplusplus
41 {
42 TEST_CASE("DMC", "[drivers][dmc]")
43 {
44  ProjectData project_data;
46 
47  const SimulationCell simulation_cell;
48  ParticleSet ions(simulation_cell);
49  MCWalkerConfiguration elec(simulation_cell);
50 
51  ions.setName("ion");
52  ions.create({1});
53  ions.R[0] = {0.0, 0.0, 0.0};
54  elec.setName("elec");
55  std::vector<int> agroup(1);
56  agroup[0] = 2;
57  elec.create(agroup);
58  elec.R[0] = {1.0, 0.0, 0.0};
59  elec.R[1] = {0.0, 0.0, 1.0};
60  elec.createWalkers(1);
61 
62  SpeciesSet& tspecies = elec.getSpeciesSet();
63  int upIdx = tspecies.addSpecies("u");
64  int chargeIdx = tspecies.addAttribute("charge");
65  int massIdx = tspecies.addAttribute("mass");
66  tspecies(chargeIdx, upIdx) = -1;
67  tspecies(massIdx, upIdx) = 1.0;
68 
69  elec.addTable(ions);
70  elec.update();
71 
73 
74  TrialWaveFunction psi(project_data.getRuntimeOptions());
75  psi.addComponent(std::make_unique<ConstantOrbital>());
76  psi.registerData(elec, elec[0]->DataSet);
77  elec[0]->DataSet.allocate();
78 
81  for (std::unique_ptr<RNG>& rng : rngs)
82  rng = std::make_unique<FakeRandom<QMCTraits::FullPrecRealType>>();
83 
85  std::unique_ptr<BareKineticEnergy> p_bke = std::make_unique<BareKineticEnergy>(elec, psi);
86  h.addOperator(std::move(p_bke), "Kinetic");
87  h.addObservables(elec); // get double free error on 'h.Observables' w/o this
88 
89  elec.resetWalkerProperty(); // get memory corruption w/o this
90 
91  DMC dmc_omp(project_data, elec, psi, h, rngs, c, false);
92 
93  const char* dmc_input = R"(<qmc method="dmc" checkpoint="-1">
94  <parameter name="steps">1</parameter>
95  <parameter name="blocks">1</parameter>
96  <parameter name="timestep">0.1</parameter>
97  </qmc>
98  )";
100  bool okay = doc.parseFromString(dmc_input);
101  REQUIRE(okay);
102  xmlNodePtr root = doc.getRoot();
103 
104  dmc_omp.process(root); // need to call 'process' for QMCDriver, which in turn calls 'put'
105 
106  dmc_omp.run();
107 
108  // With the constant wavefunction, no moves should be rejected
109  double ar = dmc_omp.acceptRatio();
110  CHECK(ar == Approx(1.0));
111 
112  // Each electron moved sqrt(tau)*gaussian_rng()
113  // See Particle>Base/tests/test_random_seq.cpp for the gaussian random numbers
114  // Values from diffuse.py for moving one step
115 
116  CHECK(elec[0]->R[0][0] == Approx(0.627670258894097));
117  CHECK(elec.R[0][1] == Approx(0.0));
118  CHECK(elec.R[0][2] == Approx(-0.372329741105903));
119 
120  CHECK(elec.R[1][0] == Approx(0.0));
121  CHECK(elec.R[1][1] == Approx(-0.372329741105903));
122  CHECK(elec.R[1][2] == Approx(1.0));
123 }
124 
125 TEST_CASE("SODMC", "[drivers][dmc]")
126 {
127  ProjectData project_data;
129 
130  const SimulationCell simulation_cell;
131  ParticleSet ions(simulation_cell);
132  MCWalkerConfiguration elec(simulation_cell);
133 
134  ions.setName("ion");
135  ions.create({1});
136  ions.R[0] = {0.0, 0.0, 0.0};
137  elec.setName("elec");
138  std::vector<int> agroup(1);
139  agroup[0] = 1;
140  elec.create(agroup);
141  elec.R[0] = {1.0, 0.0, 0.0};
142  elec.spins[0] = 0.0;
143  elec.setSpinor(true);
144  elec.createWalkers(1);
145 
146  SpeciesSet& tspecies = elec.getSpeciesSet();
147  int upIdx = tspecies.addSpecies("u");
148  int chargeIdx = tspecies.addAttribute("charge");
149  int massIdx = tspecies.addAttribute("mass");
150  tspecies(chargeIdx, upIdx) = -1;
151  tspecies(massIdx, upIdx) = 1.0;
152 
153  elec.addTable(ions);
154  elec.update();
155 
157 
158  TrialWaveFunction psi(project_data.getRuntimeOptions());
159  psi.addComponent(std::make_unique<ConstantOrbital>());
160  psi.registerData(elec, elec[0]->DataSet);
161  elec[0]->DataSet.allocate();
162 
165  for (std::unique_ptr<RNG>& rng : rngs)
166  rng = std::make_unique<FakeRandom<QMCTraits::FullPrecRealType>>();
167 
168  QMCHamiltonian h;
169  std::unique_ptr<BareKineticEnergy> p_bke = std::make_unique<BareKineticEnergy>(elec, psi);
170  h.addOperator(std::move(p_bke), "Kinetic");
171  h.addObservables(elec); // get double free error on 'h.Observables' w/o this
172 
173  elec.resetWalkerProperty(); // get memory corruption w/o this
174 
175  DMC dmc_omp(project_data, elec, psi, h, rngs, c, false);
176 
177  const char* dmc_input = R"(<qmc method="dmc" checkpoint="-1">
178  <parameter name="steps">1</parameter>
179  <parameter name="blocks">1</parameter>
180  <parameter name="timestep">0.1</parameter>
181  <parameter name="SpinMass">0.25</parameter>
182  </qmc>
183  )";
185  bool okay = doc.parseFromString(dmc_input);
186  REQUIRE(okay);
187  xmlNodePtr root = doc.getRoot();
188 
189  dmc_omp.process(root); // need to call 'process' for QMCDriver, which in turn calls 'put'
190 
191  dmc_omp.run();
192 
193  // With the constant wavefunction, no moves should be rejected
194  double ar = dmc_omp.acceptRatio();
195  CHECK(ar == Approx(1.0));
196 
197  // Each electron moved sqrt(tau)*gaussian_rng()
198  // See Particle>Base/tests/test_random_seq.cpp for the gaussian random numbers
199  // Values from diffuse.py for moving one step
200 
201  CHECK(elec[0]->R[0][0] == Approx(0.627670258894097));
202  CHECK(elec.R[0][1] == Approx(0.0));
203  CHECK(elec.R[0][2] == Approx(-0.372329741105903));
204 
205  CHECK(elec.spins[0] == Approx(-0.74465948215809097));
206 }
207 } // namespace qmcplusplus
void setName(const std::string &aname)
Definition: ParticleSet.h:237
bool run() override
Definition: DMC.cpp:228
class that handles xmlDoc
Definition: Libxml2Doc.h:76
A set of walkers that are to be advanced by Metropolis Monte Carlo.
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
ParticleScalar spins
internal spin variables for dynamical spin calculations
Definition: ParticleSet.h:81
void addOperator(std::unique_ptr< OperatorBase > &&h, const std::string &aname, bool physical=true)
add an operator
class ProjectData
Definition: ProjectData.h:36
TEST_CASE("complex_helper", "[type_traits]")
xmlNodePtr getRoot()
Definition: Libxml2Doc.h:88
Collection of Local Energy Operators.
std::vector< std::unique_ptr< T > > UPtrVector
void update(bool skipSK=false)
update the internal data
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
const RuntimeOptions & getRuntimeOptions() const noexcept
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
omp_int_t omp_get_max_threads()
Definition: OpenMP.h:26
REQUIRE(std::filesystem::exists(filename))
Declaration of WaveFunctionPool.
ParticlePos R
Position.
Definition: ParticleSet.h:79
Manager class of scalar estimators.
SpeciesSet & getSpeciesSet()
retrun the SpeciesSet of this particle set
Definition: ParticleSet.h:231
void create(const std::vector< int > &agroup)
create grouped particles
Declaration of a TrialWaveFunction.
Declaration of HamiltonianPool.
Class to represent a many-body trial wave function.
bool parseFromString(const std::string_view data)
Definition: Libxml2Doc.cpp:204
CHECK(log_values[0]==ComplexApprox(std::complex< double >{ 5.603777579195571, -6.1586603331188225 }))
RealType acceptRatio() const
Declaration of WaveFunctionComponent.
Custom container for set of attributes for a set of species.
Definition: SpeciesSet.h:33
void setSpinor(bool is_spinor)
Definition: ParticleSet.h:257
void createWalkers(int numWalkers)
create numWalkers Walkers
Declare a global Random Number Generator.
Declaration of a MCWalkerConfiguration.
void process(xmlNodePtr cur) override
initialize with xmlNode
Definition: QMCDriver.cpp:172
Define OpenMP-able DMC Driver.
void addComponent(std::unique_ptr< WaveFunctionComponent > &&aterm)
add a WaveFunctionComponent
Declaration of ParticleSetPool.
DMC driver using OpenMP paragra.
Definition: DMC.h:30