QMCPACK
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) 2020 QMCPACK developers.
6 //
7 // File developed by: Peter Doak, doakpw@ornl.gov, Oak Ridge National Laboratory
8 //
9 // File refactored from: SpinDensity.cpp
10 //////////////////////////////////////////////////////////////////////////////////////
11 
12 
13 #include "SpinDensityNew.h"
14 
15 #include "hdf5.h"
16 
17 #include <iostream>
18 #include <numeric>
19 #include <SpeciesSet.h>
20 
21 namespace qmcplusplus
22 {
24  : OperatorEstBase(dl), input_(std::move(input)), species_(species), species_size_(getSpeciesSize(species))
25 {
26  my_name_ = "SpinDensity";
27 
29  if (input_.get_save_memory())
30  dl = DataLocality::rank;
31 
32  if (input_.get_cell().explicitly_defined == true)
34  else
35  throw std::runtime_error("If SpinDensityInput does not contain a cell definition you must call the constructor "
36  "with an explicit lattice defined");
37 
39 
40  data_.resize(getFullDataSize(), 0.0);
41 
43  report(" ");
44 }
45 
47  const Lattice& lattice,
48  const SpeciesSet& species,
49  const DataLocality dl)
50  : OperatorEstBase(dl),
51  input_(std::move(input)),
52  species_(species),
53  species_size_(getSpeciesSize(species)),
54  lattice_(lattice)
55 {
56  my_name_ = "SpinDensity";
57  data_locality_ = dl;
58  if (input_.get_cell().explicitly_defined == true)
61  data_.resize(getFullDataSize());
63  report(" ");
64 }
65 
67 {
68  data_locality_ = dl;
69 }
70 
71 std::vector<int> SpinDensityNew::getSpeciesSize(const SpeciesSet& species)
72 {
73  std::vector<int> species_size;
74  int index = species.findAttribute("membersize");
75  if (index < 0)
76  throw std::runtime_error("SpinDensity(P) Species set does not have the required attribute 'membersize'");
77  for (int s = 0; s < species.size(); ++s)
78  species_size.push_back(species(index, s));
79  return species_size;
80 }
81 
83 
84 std::unique_ptr<OperatorEstBase> SpinDensityNew::spawnCrowdClone() const
85 {
86  std::size_t data_size = data_.size();
87  auto spawn_data_locality = data_locality_;
89  {
90  spawn_data_locality = DataLocality::queue;
91  // at construction we don't know what the data requirement is going to be
92  // since its steps per block dependent. so start with 10 steps worth.
93  int num_particles = std::accumulate(species_size_.begin(), species_size_.end(), 0);
94  data_size = num_particles * 20;
95  }
96  UPtr<SpinDensityNew> spawn(std::make_unique<SpinDensityNew>(*this, spawn_data_locality));
97  spawn->get_data().resize(data_size);
98  return spawn;
99 }
100 
102 {
104  {
105  int num_particles = std::accumulate(species_size_.begin(), species_size_.end(), 0);
106  size_t data_size = num_particles * steps * 2;
107  data_.reserve(data_size);
108  data_.resize(0);
109  }
110 }
111 
112 /** Gets called every step and writes to thread local data.
113  *
114  * I tried for readable and not doing the optimizers job.
115  * The offsets into bare data are already bad enough.
116  */
118  const RefVector<ParticleSet>& psets,
119  const RefVector<TrialWaveFunction>& wfns,
120  const RefVector<QMCHamiltonian>& hams,
122 {
123  auto& dp_ = derived_parameters_;
124  for (int iw = 0; iw < walkers.size(); ++iw)
125  {
126  MCPWalker& walker = walkers[iw];
127  ParticleSet& pset = psets[iw];
128  QMCT::RealType weight = walker.Weight;
129  assert(weight >= 0);
130  // for testing
131  walkers_weight_ += weight;
132  int p = 0;
133  size_t offset = 0;
134  for (int s = 0; s < species_.size(); ++s, offset += dp_.npoints)
135  for (int ps = 0; ps < species_size_[s]; ++ps, ++p)
136  {
137  QMCT::PosType u = lattice_.toUnit(pset.R[p] - dp_.corner);
138  size_t point = offset;
139  for (int d = 0; d < QMCT::DIM; ++d)
140  point += dp_.gdims[d] * ((int)(dp_.grid[d] * (u[d] - std::floor(u[d])))); //periodic only
141  accumulateToData(point, weight);
142  }
143  }
144 }
145 
147 {
149  {
150  data_[point] += weight;
151  }
153  {
154  data_.push_back(point);
155  data_.push_back(weight);
156  }
157  else
158  {
159  throw std::runtime_error("You cannot accumulate to a SpinDensityNew with datalocality of this type");
160  }
161 }
162 
163 void SpinDensityNew::collect(const RefVector<OperatorEstBase>& type_erased_operator_estimators)
164 {
166  {
167  for (OperatorEstBase& crowd_oeb : type_erased_operator_estimators)
168  {
169  // This will throw a std::bad_cast in debug if the calling code hands the
170  // wrong type erased operator_estimator type into here.
171  // In release we don't want that overhead.
172 #ifndef NDEBUG
173  auto& oeb = dynamic_cast<SpinDensityNew&>(crowd_oeb);
174 #else
175  auto& oeb = static_cast<SpinDensityNew&>(crowd_oeb);
176 #endif
177  auto& data = oeb.get_data();
178  for (int id = 0; id < data.size(); id += 2)
179  {
180  // This is a smell
181  size_t point{static_cast<size_t>(data[id])};
182  const QMCT::RealType weight{data[id + 1]};
183  data_[point] += weight;
184  walkers_weight_ += weight;
185  }
186  oeb.zero();
187  }
188  }
190  {
191  OperatorEstBase::collect(type_erased_operator_estimators);
192  }
193  else
194  {
195  throw std::runtime_error("You cannot call collect on a SpinDensityNew with this DataLocality");
196  }
197 }
198 
199 void SpinDensityNew::report(const std::string& pad)
200 {
201  auto& dp_ = derived_parameters_;
202  app_log() << pad << "SpinDensity report" << std::endl;
203  app_log() << pad << " dim = " << QMCT::DIM << std::endl;
204  app_log() << pad << " npoints = " << dp_.npoints << std::endl;
205  app_log() << pad << " grid = " << dp_.grid << std::endl;
206  app_log() << pad << " gdims = " << dp_.gdims << std::endl;
207  app_log() << pad << " corner = " << dp_.corner << std::endl;
208  app_log() << pad << " center = " << dp_.corner + lattice_.Center << std::endl;
209  app_log() << pad << " cell " << std::endl;
210  for (int d = 0; d < QMCT::DIM; ++d)
211  app_log() << pad << " " << d << " " << lattice_.Rv[d] << std::endl;
212  app_log() << pad << " end cell " << std::endl;
213  app_log() << pad << " nspecies = " << species_.size() << std::endl;
214  for (int s = 0; s < species_.size(); ++s)
215  app_log() << pad << " species[" << s << "]"
216  << " = " << species_.speciesName[s] << " " << species_size_[s] << std::endl;
217  app_log() << pad << "end SpinDensity report" << std::endl;
218 }
219 
221 {
222  std::vector<size_t> my_indexes;
223 
224  std::vector<int> ng(1, derived_parameters_.npoints);
225 
226  hdf_path hdf_name{my_name_};
227  for (int s = 0; s < species_.size(); ++s)
228  {
229  h5desc_.emplace_back(hdf_name / species_.speciesName[s]);
230  auto& oh = h5desc_.back();
232  }
233 }
234 
235 
236 } // namespace qmcplusplus
a class that defines a supercell in D-dimensional Euclean space.
SingleParticlePos Center
Center of the cell sum(Rv[i])/2.
std::vector< QMCT::RealType > & get_data()
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
QTBase::RealType RealType
Definition: Configuration.h:58
std::vector< ObservableHelper > h5desc_
std::ostream & app_log()
Definition: OutputManager.h:65
void collect(const RefVector< OperatorEstBase > &operator_estimators) override
this allows the EstimatorManagerNew to reduce without needing to know the details of SpinDensityNew&#39;s...
class to handle hdf file
Definition: hdf_archive.h:51
const char walkers[]
Definition: HDFVersion.h:36
std::unique_ptr< OperatorEstBase > spawnCrowdClone() const override
standard interface
int size() const
return the number of species
Definition: SpeciesSet.h:53
DataLocality data_locality_
locality for accumulation of estimator data.
TinyVector< SingleParticlePos, D > Rv
Real-space unit vectors.
void report(const std::string &pad)
CrystalLattice< OHMMS_PRECISION, OHMMS_DIM > lattice
Specialized paritlce class for atomistic simulations.
Definition: ParticleSet.h:55
QMCT::FullPrecRealType walkers_weight_
const std::vector< int > species_size_
static std::vector< int > getSpeciesSize(const SpeciesSet &species)
void accumulateToData(size_t point, QMCT::RealType weight)
SpinDensityNew(SpinDensityInput &&sdi, const SpeciesSet &species, DataLocality dl=DataLocality::crowd)
Constructor for SpinDensityNew that contains an explicitly defined cell part of legacy input handling...
size_t getFullDataSize()
derived_parameters_ must be valid i.e.
void registerOperatorEstimator(hdf_archive &file) override
this allows the EstimatorManagerNew to reduce without needing to know the details of SpinDensityNew&#39;s...
An abstract class for gridded estimators.
SingleParticlePos toUnit(const TinyVector< T1, D > &r) const
Convert a cartesian vector to a unit vector.
std::unique_ptr< T > UPtr
const SpeciesSet & species_
Lattice lattice_
they should be limited to values that can be changed from input or are not present explicitly in t...
Native representation for Spin Density Estimators inputs.
std::vector< std::string > speciesName
Species name list.
Definition: SpeciesSet.h:44
std::vector< std::reference_wrapper< T > > RefVector
void set_dimensions(const std::vector< int > &dims, int first)
set the shape of this observable
SpinDensityInput::DerivedParameters derived_parameters_
Class that collects density per species of particle.
void startBlock(int steps) override
This allows us to allocate the necessary data for the DataLocality::queue.
DataLocality
data locality with respect to walker buffer
Definition: DataLocality.h:19
const SpinDensityInput input_
bool explicitly_defined
true, the lattice is defined by the input instead of an artificial default
Custom container for set of attributes for a set of species.
Definition: SpeciesSet.h:33
int findAttribute(const std::string &name) const
almost all code ignores this and just uses addAttribute for the same purpose.
Definition: SpeciesSet.h:128
A container class to represent a walker.
Definition: Walker.h:49
ObservableHelper oh
DerivedParameters calculateDerivedParameters(const Lattice &lattice) const
Derived parameters of SpinDensity.
virtual void collect(const RefVector< OperatorEstBase > &oebs)
Reduce estimator result data from crowds to rank.
MakeReturn< UnaryNode< FnFloor, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t floor(const Vector< T1, C1 > &l)
SpinDensityNew sdn(std::move(sdi), lattice, species_set)
std::string my_name_
name of this object – only used for debugging and h5 output