QMCPACK
test_SpinDensityNew.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) 2024 QMCPACK developers.
6 //
7 // File developed by: Peter Doak, doakpw@ornl.gov, Oak Ridge National Lab
8 //
9 // File created by: Peter Doak, doakpw@ornl.gov, Oak Ridge National Lab
10 //////////////////////////////////////////////////////////////////////////////////////
11 
12 
13 #include "catch.hpp"
14 
15 #include "SpinDensityInput.h"
16 #include "ValidSpinDensityInput.h"
17 #include "SpinDensityNew.h"
18 #include "RandomForTest.h"
19 #include "ParticleSet.h"
20 #include "TrialWaveFunction.h"
21 #include "EstimatorTesting.h"
22 
23 #include "OhmmsData/Libxml2Doc.h"
24 
25 #include <stdio.h>
26 #include <sstream>
27 
28 namespace qmcplusplus
29 {
30 
31 using QMCT = QMCTraits;
32 
33 namespace testing
34 {
35 /** class to preserve access control in MomentumDistribution
36  */
38 {
39 public:
41  {
42  SpinDensityNew sdn2(sdn);
43 
45  CHECK(sdn.data_ != sdn2.data_);
46  }
47 };
48 } // namespace testing
49 
50 
52 {
53  const SimulationCell simulation_cell;
54  for (int iops = 0; iops < ncrowds; ++iops)
55  {
56  std::vector<OperatorEstBase::MCPWalker> walkers;
57  int nwalkers = 4;
58  for (int iw = 0; iw < nwalkers; ++iw)
59  walkers.emplace_back(2);
60 
61  std::vector<ParticleSet> psets;
62 
63  crowd_sdns.emplace_back(sdn.spawnCrowdClone());
64  SpinDensityNew& crowd_sdn = dynamic_cast<SpinDensityNew&>(*(crowd_sdns.back()));
65 
66  for (int iw = 0; iw < nwalkers; ++iw)
67  {
68  psets.emplace_back(simulation_cell);
69  ParticleSet& pset = psets.back();
70  pset.create({2});
71  pset.R[0] = ParticleSet::PosType(0.00000000, 0.00000000, 0.00000000);
72  pset.R[1] = ParticleSet::PosType(0.68658058, 0.68658058, 0.68658058);
73  }
74 
75  std::vector<TrialWaveFunction> wfns;
76  std::vector<QMCHamiltonian> hams;
77 
78  auto ref_walkers = makeRefVector<OperatorEstBase::MCPWalker>(walkers);
79  auto ref_psets = makeRefVector<ParticleSet>(psets);
80  auto ref_wfns = makeRefVector<TrialWaveFunction>(wfns);
81  auto ref_hams = makeRefVector<QMCHamiltonian>(hams);
82 
84 
85  crowd_sdn.accumulate(ref_walkers, ref_psets, ref_wfns, ref_hams, rng);
86  }
87 }
88 
90 {
91  const SimulationCell simulation_cell;
92  for (auto& uptr_crowd_sdn : crowd_sdns)
93  {
94  std::vector<OperatorEstBase::MCPWalker> walkers;
95  int nwalkers = 4;
96  for (int iw = 0; iw < nwalkers; ++iw)
97  walkers.emplace_back(2);
98 
99  std::vector<ParticleSet> psets;
100 
101  SpinDensityNew& crowd_sdn = dynamic_cast<SpinDensityNew&>(*(uptr_crowd_sdn));
102 
103  std::vector<QMCT::RealType> rng_reals(nwalkers * QMCT::DIM * 2);
104  rft.fillVecRng(rng_reals);
105  auto it_rng_reals = rng_reals.begin();
106  for (int iw = 0; iw < nwalkers; ++iw)
107  {
108  psets.emplace_back(simulation_cell);
109  ParticleSet& pset = psets.back();
110  pset.create({2});
111  pset.R[0] = ParticleSet::PosType(*it_rng_reals++, *it_rng_reals++, *it_rng_reals++);
112  pset.R[1] = ParticleSet::PosType(*it_rng_reals++, *it_rng_reals++, *it_rng_reals++);
113  }
114 
115  std::vector<TrialWaveFunction> wfns;
116  std::vector<QMCHamiltonian> hams;
117  auto ref_walkers = makeRefVector<OperatorEstBase::MCPWalker>(walkers);
118  auto ref_psets = makeRefVector<ParticleSet>(psets);
119  auto ref_wfns = makeRefVector<TrialWaveFunction>(wfns);
120  auto ref_hams = makeRefVector<QMCHamiltonian>(hams);
121 
123 
124  crowd_sdn.accumulate(ref_walkers, ref_psets, ref_wfns, ref_hams, rng);
125  }
126 }
127 
128 TEST_CASE("SpinDensityNew::SpinDensityNew(SPInput, SpeciesSet)", "[estimators]")
129 {
133  REQUIRE(okay);
134  xmlNodePtr node = doc.getRoot();
137  int ispecies = species_set.addSpecies("C");
138  int iattribute = species_set.addAttribute("membersize");
141  SpinDensityNew(std::move(sdi), species_set);
143 }
144 
145 TEST_CASE("SpinDensityNew::SpinDensityNew(SPInput, Lattice, SpeciesSet)", "[estimators]")
146 {
148  using input = testing::ValidSpinDensityInput;
150  REQUIRE(okay);
151  xmlNodePtr node = doc.getRoot();
152  SpinDensityInput sdi(node);
153  SpeciesSet species_set;
154  int ispecies = species_set.addSpecies("C");
155  int iattribute = species_set.addAttribute("membersize");
158  SpinDensityNew sdn(std::move(sdi), lattice, species_set);
159  // make sure there is something in obdm's data
160  using namespace testing;
161  OEBAccessor oeba(sdn);
162  oeba[0] = 1.0;
165 }
166 
167 TEST_CASE("SpinDensityNew::spawnCrowdClone()", "[estimators]")
168 {
170  using input = testing::ValidSpinDensityInput;
172  REQUIRE(okay);
173  xmlNodePtr node = doc.getRoot();
174  SpinDensityInput sdi(node);
175  SpeciesSet species_set;
176  int ispecies = species_set.addSpecies("C");
177  int iattribute = species_set.addAttribute("membersize");
181  auto clone = original.spawnCrowdClone();
182  REQUIRE(clone != nullptr);
183  REQUIRE(clone.get() != &original);
184  REQUIRE(dynamic_cast<decltype(&original)>(clone.get()) != nullptr);
185 }
186 
187 TEST_CASE("SpinDensityNew::accumulate", "[estimators]")
188 {
190  using QMCT = QMCTraits;
191 
195  REQUIRE(okay);
196  xmlNodePtr node = doc.getRoot();
199  int ispecies = species_set.addSpecies("u");
200  ispecies = species_set.addSpecies("d");
201  CHECK(ispecies == 1);
202  int iattribute = species_set.addAttribute("membersize");
203  species_set(iattribute, 0) = 1;
204  species_set(iattribute, 1) = 1;
205 
206  SpinDensityNew sdn(std::move(sdi), species_set);
207  std::vector<MCPWalker> walkers;
208  int nwalkers = 4;
209  for (int iw = 0; iw < nwalkers; ++iw)
210  walkers.emplace_back(2);
211 
212  std::vector<ParticleSet> psets;
213 
214  const SimulationCell simulation_cell;
215  for (int iw = 0; iw < nwalkers; ++iw)
216  {
217  psets.emplace_back(simulation_cell);
218  ParticleSet& pset = psets.back();
219  pset.create({2});
220  pset.R[0] = ParticleSet::PosType(0.00000000, 0.00000000, 0.00000000);
221  pset.R[1] = ParticleSet::PosType(1.68658058, 1.68658058, 1.68658058);
222  }
223 
224  std::vector<TrialWaveFunction> wfns;
225  std::vector<QMCHamiltonian> hams;
226 
227  auto ref_walkers = makeRefVector<MCPWalker>(walkers);
228  auto ref_psets = makeRefVector<ParticleSet>(psets);
229  auto ref_wfns = makeRefVector<TrialWaveFunction>(wfns);
230  auto ref_hams = makeRefVector<QMCHamiltonian>(hams);
231 
233 
234  sdn.accumulate(ref_walkers, ref_psets, ref_wfns, ref_hams, rng);
235 
236  std::vector<QMCT::RealType>& data_ref = sdn.get_data();
237  // There should be a check that the discretization of particle locations expressed in lattice coords
238  // is correct. This just checks it hasn't changed from how it was in SpinDensity which lacked testing.
239  CHECK(data_ref[555] == 4);
240  CHECK(data_ref[1777] == 4);
241 }
242 
243 TEST_CASE("SpinDensityNew::collect(DataLocality::crowd)", "[estimators]")
244 {
245  {
247  using QMCT = QMCTraits;
248 
250  using input = testing::ValidSpinDensityInput;
252  REQUIRE(okay);
253  xmlNodePtr node = doc.getRoot();
254  SpinDensityInput sdi(node);
255  SpeciesSet species_set;
256  int ispecies = species_set.addSpecies("u");
257  ispecies = species_set.addSpecies("d");
258  CHECK(ispecies == 1);
259  int iattribute = species_set.addAttribute("membersize");
260  species_set(iattribute, 0) = 1;
261  species_set(iattribute, 1) = 1;
262 
263  SpinDensityNew sdn(std::move(sdi), species_set);
264 
265  UPtrVector<OperatorEstBase> crowd_sdns;
266  int ncrowds = 2;
267 
268  accumulateFromPsets(ncrowds, sdn, crowd_sdns);
269 
270  RefVector<OperatorEstBase> crowd_oeb_refs = convertUPtrToRefVector(crowd_sdns);
271  sdn.collect(crowd_oeb_refs);
272 
273  std::vector<QMCT::RealType>& data_ref = sdn.get_data();
274  // There should be a check that the discretization of particle locations expressed in lattice coords
275  // is correct. This just checks it hasn't changed from how it was in SpinDensity which lacked testing.
276  CHECK(data_ref[555] == 4 * ncrowds);
277  CHECK(data_ref[1666] == 4 * ncrowds);
278  }
279 }
280 
281 TEST_CASE("SpinDensityNew::collect(DataLocality::rank)", "[estimators]")
282 {
283  {
285  using QMCT = QMCTraits;
286 
288  using input = testing::ValidSpinDensityInput;
290  REQUIRE(okay);
291  xmlNodePtr node = doc.getRoot();
292  SpinDensityInput sdi(node);
293  SpeciesSet species_set;
294  int ispecies = species_set.addSpecies("u");
295  ispecies = species_set.addSpecies("d");
296  CHECK(ispecies == 1);
297  int iattribute = species_set.addAttribute("membersize");
298  species_set(iattribute, 0) = 1;
299  species_set(iattribute, 1) = 1;
300 
302 
304 
305  UPtrVector<OperatorEstBase> crowd_sdns;
306  int ncrowds = 2;
307 
308  accumulateFromPsets(ncrowds, sdn, crowd_sdns);
309 
310  RefVector<OperatorEstBase> crowd_oeb_refs = convertUPtrToRefVector(crowd_sdns);
311  sdn.collect(crowd_oeb_refs);
312 
313  std::vector<QMCT::RealType>& data_ref = sdn.get_data();
314  // There should be a check that the discretization of particle locations expressed in lattice coords
315  // is correct. This just checks it hasn't changed from how it was in SpinDensity which lacked testing.
316  CHECK(data_ref[555] == 4 * ncrowds);
317  CHECK(data_ref[1666] == 4 * ncrowds);
318  }
319 }
320 
321 TEST_CASE("SpinDensityNew algorithm comparison", "[estimators]")
322 {
324  using QMCT = QMCTraits;
325 
327  using input = testing::ValidSpinDensityInput;
329  REQUIRE(okay);
330  xmlNodePtr node = doc.getRoot();
331  SpinDensityInput sdi(node);
332  SpeciesSet species_set;
333  int ispecies = species_set.addSpecies("u");
334  ispecies = species_set.addSpecies("d");
335  CHECK(ispecies == 1);
336  int iattribute = species_set.addAttribute("membersize");
337  species_set(iattribute, 0) = 1;
338  species_set(iattribute, 1) = 1;
339 
340  SpinDensityInput sdi_copy = sdi;
341 
342  int ncrowds = 3;
343  int nsteps = 4;
344 
345  SpinDensityNew sdn_rank(std::move(sdi), species_set, DataLocality::rank);
346  UPtrVector<OperatorEstBase> crowd_sdns_rank;
347  accumulateFromPsets(ncrowds, sdn_rank, crowd_sdns_rank);
348  testing::RandomForTest<QMCT::RealType> rng_for_test_rank;
349  for (int i = 0; i < nsteps; ++i)
350  randomUpdateAccumulate(rng_for_test_rank, crowd_sdns_rank);
351  RefVector<OperatorEstBase> crowd_oeb_refs_rank = convertUPtrToRefVector(crowd_sdns_rank);
352  sdn_rank.collect(crowd_oeb_refs_rank);
353  std::vector<QMCT::RealType>& data_ref_rank = sdn_rank.get_data();
354 
355  SpinDensityNew sdn_crowd(std::move(sdi), species_set, DataLocality::crowd);
356  UPtrVector<OperatorEstBase> crowd_sdns_crowd;
357  accumulateFromPsets(ncrowds, sdn_crowd, crowd_sdns_crowd);
358  testing::RandomForTest<QMCT::RealType> rng_for_test_crowd;
359  for (int i = 0; i < nsteps; ++i)
360  randomUpdateAccumulate(rng_for_test_crowd, crowd_sdns_crowd);
361  RefVector<OperatorEstBase> crowd_oeb_refs_crowd = convertUPtrToRefVector(crowd_sdns_crowd);
362  sdn_crowd.collect(crowd_oeb_refs_crowd);
363  std::vector<QMCT::RealType>& data_ref_crowd = sdn_crowd.get_data();
364 
365  for (size_t i = 0; i < data_ref_rank.size(); ++i)
366  {
367  if (data_ref_crowd[i] != data_ref_rank[i])
368  FAIL_CHECK("crowd local " << data_ref_crowd[i] << " != rank local " << data_ref_rank[i] << " at index " << i);
369  break;
370  }
371 }
372 
373 
374 } // namespace qmcplusplus
a class that defines a supercell in D-dimensional Euclean space.
void accumulateFromPsets(int ncrowds, SpinDensityNew &sdn, UPtrVector< OperatorEstBase > &crowd_sdns)
std::vector< QMCT::RealType > & get_data()
class that handles xmlDoc
Definition: Libxml2Doc.h:76
void accumulate(const RefVector< MCPWalker > &walkers, const RefVector< ParticleSet > &psets, const RefVector< TrialWaveFunction > &wfns, const RefVector< QMCHamiltonian > &hams, RandomBase< FullPrecRealType > &rng) override
accumulate 1 or more walkers of SpinDensity samples
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
if(!okay) throw std xmlNodePtr node
void testCopyConstructor(const SpinDensityNew &sdn)
Get a known sequence of random numbers for testing.
Definition: RandomForTest.h:31
TEST_CASE("complex_helper", "[type_traits]")
SpinDensityNewTests sdnt
xmlNodePtr getRoot()
Definition: Libxml2Doc.h:88
void collect(const RefVector< OperatorEstBase > &operator_estimators) override
this allows the EstimatorManagerNew to reduce without needing to know the details of SpinDensityNew&#39;s...
std::vector< std::unique_ptr< T > > UPtrVector
const char walkers[]
Definition: HDFVersion.h:36
class to preserve access control in MomentumDistribution
std::unique_ptr< OperatorEstBase > spawnCrowdClone() const override
standard interface
static RefVector< T > convertUPtrToRefVector(const UPtrVector< T > &ptr_list)
convert a vector of std::unique_ptrs<T> to a refvector<T>
void randomUpdateAccumulate(testing::RandomForTest< QMCT::RealType > &rft, UPtrVector< OperatorEstBase > &crowd_sdns)
static constexpr std::array< std::string_view, 3 > xml
CrystalLattice< OHMMS_PRECISION, OHMMS_DIM > lattice
SpinDensityNew(std::move(sdi), species_set)
void fillVecRng(std::vector< VT > &rng_reals)
Specialized paritlce class for atomistic simulations.
Definition: ParticleSet.h:55
const std::vector< int > species_size_
REQUIRE(std::filesystem::exists(filename))
QTBase::PosType PosType
Definition: Configuration.h:61
Native representation for Spin Density Estimators inputs.
Declaration of a TrialWaveFunction.
bool parseFromString(const std::string_view data)
Definition: Libxml2Doc.cpp:204
Walker< QMCTraits, PtclOnLatticeTraits > MCPWalker
Definition: test_walker.cpp:31
Class that collects density per species of particle.
CHECK(log_values[0]==ComplexApprox(std::complex< double >{ 5.603777579195571, -6.1586603331188225 }))
OEBAccessor oeba(sdn)
testing::ValidSpinDensityInput input
Custom container for set of attributes for a set of species.
Definition: SpeciesSet.h:33
traits for QMC variables
Definition: Configuration.h:49
SpinDensityNew original(std::move(sdi), lattice, species_set)
A container class to represent a walker.
Definition: Walker.h:49
SpinDensityInput sdi(node)
SpinDensityInput sdi_copy
SpinDensityNew sdn(std::move(sdi), lattice, species_set)
Walker< QMCTraits, PtclOnLatticeTraits > MCPWalker