QMCPACK
test_MomentumDistribution.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: Jaron T. Krogel, krogeljt@ornl.gov, Oak Ridge National Lab
8 //
9 // File created by: Jaron T. Krogel, krogeljt@ornl.gov, Oak Ridge National Lab
10 //////////////////////////////////////////////////////////////////////////////////////
11 
12 
13 #include "catch.hpp"
14 
15 #include "MomentumDistribution.h"
18 #include "EstimatorTesting.h"
19 #include "ParticleSet.h"
20 #include "TrialWaveFunction.h"
21 #include "OhmmsData/Libxml2Doc.h"
25 #include "Utilities/StdRandom.h"
27 #include "Utilities/ProjectData.h"
28 
29 #include <stdio.h>
30 #include <sstream>
31 
32 
33 namespace qmcplusplus
34 {
37 
38 namespace testing
39 {
40 /** class to preserve access control in MomentumDistribution
41  */
43 {
44 public:
46  {
47  MomentumDistribution md2(md);
48 
49  CHECK(md2.twist[0] == Approx(md.twist[0]));
50  CHECK(md2.twist[1] == Approx(md.twist[1]));
51  CHECK(md2.twist[2] == Approx(md.twist[2]));
52  CHECK(md2.kPoints.size() == md.kPoints.size());
53  CHECK(md.data_ != md2.data_);
54 
57  }
58 };
59 } // namespace testing
60 
61 TEST_CASE("MomentumDistribution::MomentumDistribution", "[estimators]")
62 {
63  // clang-format: off
64  const char* xml = R"(
65 <estimator type="MomentumDistribution" name="nofk" samples="5" kmax="3"/>
66 )";
67  // clang-format: on
68 
69  // Read xml into input object
71  bool okay = doc.parseFromString(xml);
72  if (!okay)
73  throw std::runtime_error("cannot parse MomentumDistributionInput section");
74  xmlNodePtr node = doc.getRoot();
76 
77  // Instantiate other dependencies (internal QMCPACK objects)
82 
84  auto wavefunction_pool =
86  auto& pset = *(particle_pool.getParticleSet("e"));
88 
89  // Build from input
90  MomentumDistribution md(std::move(mdi), pset.getTotalNum(), pset.getTwist(), pset.getLattice(), dl);
91 
92  CHECK(md.twist[0] == Approx(0.0));
93  CHECK(md.twist[1] == Approx(0.0));
94  CHECK(md.twist[2] == Approx(0.0));
95  CHECK(md.kPoints.size() == 27);
96 
97  // make sure there is something in mds data
98  using namespace testing;
99  OEBAccessor oeba(md);
100  oeba[0] = 1.0;
101 
103  mdt.testCopyConstructor(md);
104 }
105 
106 
107 TEST_CASE("MomentumDistribution::accumulate", "[estimators]")
108 {
110 
111  // clang-format: off
112  const char* xml = R"(
113 <estimator type="MomentumDistribution" name="nofk" samples="5" kmax="3"/>
114 )";
115  // clang-format: on
116 
117  // Read xml into input object
119  bool okay = doc.parseFromString(xml);
120  if (!okay)
121  throw std::runtime_error("cannot parse MomentumDistributionInput section");
122  xmlNodePtr node = doc.getRoot();
124 
125  // Instantiate other dependencies (internal QMCPACK objects)
128  Communicate* comm;
132  auto wavefunction_pool =
134  auto& pset = *(particle_pool.getParticleSet("e"));
136 
137  // Setup particleset
138  pset.R = ParticleSet::ParticlePos{{1.751870349, 4.381521229, 2.865202269}, {3.244515371, 4.382273176, 4.21105285},
139  {3.000459944, 3.329603408, 4.265030556}, {3.748660329, 3.63420622, 5.393637791},
140  {3.033228526, 3.391869137, 4.654413566}, {3.114198787, 2.654334594, 5.231075822},
141  {3.657151589, 4.883870516, 4.201243939}, {2.97317591, 4.245644974, 4.284564732}};
142 
143  // Build from input
144  MomentumDistribution md(std::move(mdi), pset.getTotalNum(), pset.getTwist(), pset.getLattice(), dl);
145 
146  // Test accumulate
147 
148  // Setup walker, particleset, wavefunction ref vectors
149  // Make clones
150  std::vector<MCPWalker> walkers;
151  int nwalkers = 4;
152  for (int iw = 0; iw < nwalkers; ++iw)
153  walkers.emplace_back(8);
154 
155  std::vector<ParticleSet> psets;
156  for (int iw = 0; iw < nwalkers; ++iw)
157  psets.emplace_back(pset);
158 
159  auto& trial_wavefunction = *(wavefunction_pool.getPrimary());
160  std::vector<UPtr<TrialWaveFunction>> wfns(nwalkers);
161  for (int iw = 0; iw < nwalkers; ++iw)
162  wfns[iw] = trial_wavefunction.makeClone(psets[iw]);
163 
164  // Initialize walker, pset, wfn
165  for (int iw = 0; iw < nwalkers; ++iw)
166  {
167  auto& walker = walkers[iw];
168  auto& pset = psets[iw];
169  pset.update(true);
170  pset.donePbyP();
171  wfns[iw]->evaluateLog(pset);
172  pset.saveWalker(walker);
173  }
174 
175  // Create ref vectors
176  std::vector<QMCHamiltonian> hams;
177 
178  auto ref_walkers = makeRefVector<MCPWalker>(walkers);
179  auto ref_psets = makeRefVector<ParticleSet>(psets);
180  auto ref_wfns = convertUPtrToRefVector(wfns);
181  auto ref_hams = makeRefVector<QMCHamiltonian>(hams);
182 
183  // Setup RNG
185 
186  // Perform accumulate
187  md.accumulate(ref_walkers, ref_psets, ref_wfns, ref_hams, rng);
188 
189  // Check data
190  std::vector<RealType>& data = md.get_data();
191 
192  using Data = MomentumDistribution::Data;
193  Data ref_data;
194 
195  ref_data = {3.92261216, -5.752141485, 4.78276286, 8.307662762, -5.130834919, 0.08942598353, 0.9716326509,
196  21.82310933, -9.177741101, -0.2024849597, -2.520417488, -9.470020717, -9.4969045, 3.866360129,
197  -9.4969045, -9.470020717, -2.520417488, -0.2024849597, -9.177741101, 21.82310933, 0.9716326509,
198  0.08942598353, -5.130834919, 8.307662762, 4.78276286, -5.752141485, 3.92261216};
199 
200  //std::cout<<"\n\n\nn(k) data:\n{";
201  //for(int i=0;i<data.size();++i)
202  // std::cout<<data[i]<<", ";
203  //std::cout<<"}\n\n\n";
204 
205  for (size_t id = 0; id < ref_data.size(); ++id)
206  {
207 #ifdef MIXED_PRECISION
208  CHECK(data[id] == Approx(ref_data[id]).epsilon(2.e-05));
209 #else
210  // default Catch2 epsilon std::numeric_limits<float>::epsilon()*100
211  // set value for x86_64
212  CHECK(data[id] == Approx(ref_data[id]).epsilon(1.192092896e-05));
213 #endif
214  }
215 
217 }
218 
219 TEST_CASE("MomentumDistribution::spawnCrowdClone", "[estimators]")
220 {
221  // clang-format: off
222  const char* xml = R"(
223 <estimator type="MomentumDistribution" name="nofk" samples="5" kmax="3"/>
224 )";
225  // clang-format: on
226 
227  // Read xml into input object
229  bool okay = doc.parseFromString(xml);
230  if (!okay)
231  throw std::runtime_error("cannot parse MomentumDistributionInput section");
232  xmlNodePtr node = doc.getRoot();
234 
235  // Instantiate other dependencies (internal QMCPACK objects)
238  Communicate* comm;
240 
242  auto wavefunction_pool =
244  auto& pset = *(particle_pool.getParticleSet("e"));
246 
247  // Build from input
248  MomentumDistribution md(std::move(mdi), pset.getTotalNum(), pset.getTwist(), pset.getLattice(), dl);
249 
250  auto clone = md.spawnCrowdClone();
251  REQUIRE(clone != nullptr);
252  REQUIRE(clone.get() != &md);
253  REQUIRE(dynamic_cast<decltype(&md)>(clone.get()) != nullptr);
254 
255  // This check can be removed once a rank locality memory scheme is implemented
256  // for MomentumDistribution. Then checks relevant to that should be added.
258  dl = DataLocality::rank;
259  MomentumDistribution fail_md(std::move(fail_mdi), pset.getTotalNum(), pset.getTwist(), pset.getLattice(), dl);
260  CHECK_THROWS_AS(clone = fail_md.spawnCrowdClone(), std::runtime_error);
261 }
262 
263 } // namespace qmcplusplus
class that handles xmlDoc
Definition: Libxml2Doc.h:76
void pause()
Pause the summary and log streams.
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
QTBase::RealType RealType
Definition: Configuration.h:58
if(!okay) throw std xmlNodePtr node
class ProjectData
Definition: ProjectData.h:36
static ParticleSetPool make_diamondC_1x1x1(Communicate *c)
TEST_CASE("complex_helper", "[type_traits]")
static WaveFunctionPool make_diamondC_1x1x1(const RuntimeOptions &runtime_options, Communicate *comm, ParticleSetPool &particle_pool)
xmlNodePtr getRoot()
Definition: Libxml2Doc.h:88
Class that collects momentum distribution of electrons.
class to preserve access control in MomentumDistribution
ProjectData test_project("test", ProjectData::DriverVersion::BATCH)
const char walkers[]
Definition: HDFVersion.h:36
Attaches a unit to a Vector for IO.
Communicate * Controller
Global Communicator for a process.
Definition: Communicate.cpp:35
static RefVector< T > convertUPtrToRefVector(const UPtrVector< T > &ptr_list)
convert a vector of std::unique_ptrs<T> to a refvector<T>
const RuntimeOptions & getRuntimeOptions() const noexcept
OutputManagerClass outputManager(Verbosity::HIGH)
QMCTraits::PosType PosType
Wrapping information on parallelism.
Definition: Communicate.h:68
DataLocality get_data_locality() const
CrystalLattice< OHMMS_PRECISION, OHMMS_DIM > lattice
void resume()
Resume the summary and log streams.
REQUIRE(std::filesystem::exists(filename))
A minimally functional wrapper for the since c++11 <random>
QTBase::PosType PosType
Definition: Configuration.h:61
Declaration of a TrialWaveFunction.
std::vector< QMCT::RealType > Data
QMCTraits::RealType RealType
std::vector< PosType > kPoints
list of k-points in Cartesian Coordinates
void testCopyConstructor(const MomentumDistribution &md)
bool parseFromString(const std::string_view data)
Definition: Libxml2Doc.cpp:204
CHECK(log_values[0]==ComplexApprox(std::complex< double >{ 5.603777579195571, -6.1586603331188225 }))
DataLocality
data locality with respect to walker buffer
Definition: DataLocality.h:19
OEBAccessor oeba(sdn)
break encapsulation of data_ by OperatorEstBase only for testing!
A container class to represent a walker.
Definition: Walker.h:49
Native representation for Momentum Distribution Estimators inputs.
Walker< QMCTraits, PtclOnLatticeTraits > MCPWalker