QMCPACK
OneBodyDensityMatrices.h
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: Peter Doak, doakpw@ornl.gov, Oak Ridge National Laboratory
8 //
9 // Based on code from: QMCHamiltonians/DensityMatrices1B.h
10 //////////////////////////////////////////////////////////////////////////////////////
11 
12 #ifndef QMCPLUSPLUS_ONE_BODY_DENSITY_MATRICES_H
13 #define QMCPLUSPLUS_ONE_BODY_DENSITY_MATRICES_H
14 
15 #include <vector>
16 #include <functional>
17 
24 #include "OhmmsPETE/OhmmsMatrix.h"
25 #include <SpeciesSet.h>
26 #include <StdRandom.h>
27 
28 namespace qmcplusplus
29 {
30 
31 namespace testing
32 {
33 template<typename T>
35 }
36 
37 /** Per crowd Estimator for OneBodyDensityMatrices aka 1RDM DensityMatrices1B
38  *
39  * \todo most matrices are written to by incrementing a single vector index
40  * into their memory. This isn't compatible with aligned rows and ignores
41  * much less error prone accessing that Matrix supplys. Fix it.
42  * \todo functions favor output arguments or state updates over return values,
43  * simplify.
44  */
46 {
47 public:
55 
59 
60  enum class Sampling
61  {
63  METROPOLIS,
65  };
66 
67 private:
71 
72  /** @ingroup Derived simulation parameters determined by computation based in input
73  * @{
74  */
75  /// samples_ are altered based on integrator_ so always have a simulation object copy.
76  size_t samples_;
77  /// Sampling method, this derived values in input_
79  /// If not defined in OBDMI taken from lattice_
81  /// with respect to center_ using lattice_;
84  bool periodic_;
85  /** @} */
86 
87  //data members \todo analyze lifecycles allocation optimization or state?
94  std::vector<Position> rsamples_;
95  std::vector<Real> ssamples_;
98  std::vector<int> species_sizes_;
99  std::vector<std::string> species_names_;
100  /** @ingroup Working space, I'm assuming not longterm state.
101  * @{ */
102  /** per particle ratios
103  * size: particles
104  */
105  std::vector<Value> psi_ratios_;
106 
107  /// row major per sample workspaces
108  /** conj(basis_values) for each particle
109  * size: samples * basis_size
110  * vector is over species
111  * each matrix row: particle column: basis_value
112  */
113  std::vector<Matrix<Value>> Phi_NB_;
114  /** ratio per particle per sample
115  * size: particles * samples
116  * vector is over species
117  * each matrix row: particle col: sample
118  */
119  std::vector<Matrix<Value>> Psi_NM_;
120  std::vector<Matrix<Value>> Phi_Psi_NB_, N_BB_;
121  /** basis_values_ at each r of rsamples_ row: sample col: basis_value
122  * size: samples * basis_size
123  */
125  /** @} */
126 
127  /** @ingroup DensityIntegration only used for density integration
128  * @{
129  */
130  /// number of moves
131  int nmoves_ = 0;
132  /// number of accepted samples
133  int naccepted_ = 0;
134  /// running acceptance ratio over all samples
137  bool warmed_up_ = false;
138  /// }@
139 
140  Real metric_ = 1.0;
141 
142  // \todo is this state necessay, would it be better passed down the call stack?
143  /// current position -- As long Positions are TinyVectors they are intialized to zero vectors
145  /// current drift
147  /// current density
148  Real rhocur_ = 0.0;
149 
150  ///spin related variables
151  Real spcur_ = 0.0;
152  Real dspcur_ = 0.0;
153  const bool is_spinor_;
154 
155 public:
156  /** Standard Constructor
157  * Call this to make a new OBDM this is what you should be calling
158  */
160  const Lattice& lattice,
161  const SpeciesSet& species,
162  const SPOMap& spomap,
163  const ParticleSet& pset_target);
164 
165  /** Constructor used when spawing crowd clones
166  * needs to be public so std::make_unique can call it.
167  * Do not use directly unless you've really thought it through.
168  */
170 
171  std::unique_ptr<OperatorEstBase> spawnCrowdClone() const override;
172 
174  const RefVector<ParticleSet>& psets,
175  const RefVector<TrialWaveFunction>& wfns,
176  const RefVector<QMCHamiltonian>& hams,
177  RandomBase<FullPrecReal>& rng) override;
178 
179  void startBlock(int steps) override;
180 
181  /** create and tie OperatorEstimator's observable_helper hdf5 wrapper to stat.h5 file
182  * @param gid hdf5 group to which the observables belong
183  *
184  * The default implementation does nothing. The derived classes which compute
185  * big data, e.g. density, should overwrite this function.
186  */
187  void registerOperatorEstimator(hdf_archive& file) override;
188 
189 private:
190  /** Default copy constructor.
191  * Instances of this estimator is assume to be thread scope, i.e. never
192  * called by more than one thread at a time. note the OperatorEstBase copy constructor does
193  * not copy or even allocate data_
194  */
195  OneBodyDensityMatrices(const OneBodyDensityMatrices& obdm) = default;
196 
197  /** Unfortunate design RandomGenerator type aliasing and
198  * virtual inheritance requires this for testing.
199  */
201  const RefVector<ParticleSet>& psets,
202  const RefVector<TrialWaveFunction>& wfns,
204 
205  size_t calcFullDataSize(size_t basis_size, int num_species);
206  //local functions
208  // printing
209  void report(const std::string& pad = "");
210 
212  TrialWaveFunction& psi_target,
213  const MCPWalker& walker,
215  // sample generation
216  /** Dispatch method to difference methods of generating samples.
217  * dispatch determined by Integrator.
218  * \param[in] weight of this walker's samples
219  * \param[in] pset_target will be returned to its initial state but is mutated.
220  * \param[in] rng random generator. templated for testing without dependency on app level rng.
221  * \param[in] steps If integrator_ = Integrator::DENSITY steps is a key parameter otherwise ignored.
222  * when set to 0 it is reset to samples_ internally
223  *
224  * sideeffects:
225  * * samples_weights_ are set.
226  * * rsamples_ are set.
227  * for Density
228  * * update basis_values_, basis_gradients_, basis_laplacians_
229  */
230  // These functions deserve unit tests and likely should be pure functions.
231  void generateSamples(const Real weight, ParticleSet& pset_target, RandomBase<FullPrecReal>& rng, int steps = 0);
234  /** generate samples for density integration
235  * \param[in] save if false throw out the samples
236  * \param[in] steps actually the number of samples which are basically steps.
237  * \param[in] rng random generator
238  * \param[in] pset_target will be returned to its initial state but is mutated.
239  *
240  * sideeffects:
241  * *
242  */
243  void generateDensitySamples(bool save, int steps, RandomBase<FullPrecReal>& rng, ParticleSet& pset_target);
244 
245  /// same as above, but with spin variables included
247 
249  TrialWaveFunction& psi_target,
250  std::vector<Matrix<Value>>& Psi_nm);
251  /// produce a position difference vector from timestep
253 
254  /// spin diffusion
256 
257  /** calculate density based on r
258  * \param[in] r position
259  * \param[out] dens density
260  *
261  * called by generateDensitySamples to get trial dens.
262  * also called by test_derivatives.
263  * sideeffects:
264  * * updateBasis is called
265  */
266  void calcDensity(const Position& r, Real& dens, ParticleSet& pset_target);
267  /// same as above, but with spin move
268  void calcDensityWithSpin(const Position& r, const Real& s, Real& dens, ParticleSet& pset_target);
269  /** calculate density and drift bashed on r
270  * \param[in] r position
271  * \param[out] dens density
272  * \param[out] drift drift
273  *
274  * called by warmupSamples to get an initial drift and density.
275  * called by generateDensitySamples to get trial drift and trial dens.
276  * also called by test_derivatives.
277  * sideeffects:
278  * * updateBasisD012 is called
279  */
280  void calcDensityDrift(const Position& r, Real& dens, Position& drift, ParticleSet& pset_target);
281  /// same as above, but with spin move
282  void calcDensityDriftWithSpin(const Position& r,
283  const Real& s,
284  Real& dens,
285  Position& drift,
286  Real& sdrift,
288  // basis & wavefunction ratio matrix construction
289 
290  /** set Phi_mp to basis vaules per sample
291  * sideeffects:
292  * * updates basis_values_ to last rsample
293  */
295  /** set phi_nb to basis values per target particleset particle
296  * sideeffects:
297  * * updates basis_values_ to last rsample
298  */
299  void generateParticleBasis(ParticleSet& pset_target, std::vector<Matrix<Value>>& phi_nb);
300 
301  /// basis set updates
302  void updateBasis(const Position& r, ParticleSet& pset_target);
303  /// basis set updates with spin
304  void updateBasisWithSpin(const Position& r, const Real& s, ParticleSet& pset_target);
305  /** evaluates vgl on basis_functions_ for r
306  * sideeffects:
307  * * sets basis_values_, basis_gradients_, basis_laplacians_
308  * all are normalized by basis norms_
309  */
311  /// same as above, but includes spin gradients
313  /** does some warmup sampling i.e. samples but throws away the results
314  * Only when integrator_ = Integrator::DENSITY
315  * sets rpcur_ initial rpcur + one diffusion step
316  * sets initial rhocur_ and dpcur_
317  * Then calls generateSamples with number of input warmup samples.
318  */
320 
322  {
330  OneBodyDensityMatrixTimers(const std::string& prefix)
331  : eval_timer(createGlobalTimer(prefix + "Eval", timer_level_fine)),
332  gen_samples_timer(createGlobalTimer(prefix + "GenSamples", timer_level_fine)),
333  gen_sample_basis_timer(createGlobalTimer(prefix + "GenSampleBasis", timer_level_fine)),
334  gen_sample_ratios_timer(createGlobalTimer(prefix + "GenSampleRatios", timer_level_fine)),
335  gen_particle_basis_timer(createGlobalTimer(prefix + "GenParticleBasis", timer_level_fine)),
336  matrix_products_timer(createGlobalTimer(prefix + "MatrixProducts", timer_level_fine)),
337  accumulate_timer(createGlobalTimer(prefix + "Accumulate", timer_level_fine))
338  {}
339  };
340 
342 
343 public:
344  template<typename T>
346 };
347 } // namespace qmcplusplus
348 
349 #endif
a class that defines a supercell in D-dimensional Euclean space.
void generateSampleRatios(ParticleSet &pset_target, TrialWaveFunction &psi_target, std::vector< Matrix< Value >> &Psi_nm)
Fixed-size array.
Definition: OhmmsTinyMeta.h:30
std::vector< std::string > species_names_
Real acceptance_ratio_
running acceptance ratio over all samples
void updateBasisD012(const Position &r, ParticleSet &pset_target)
evaluates vgl on basis_functions_ for r sideeffects:
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
RealAlias< FullPrecValue > FullPrecReal
Position center_
If not defined in OBDMI taken from lattice_.
Per crowd Estimator for OneBodyDensityMatrices aka 1RDM DensityMatrices1B.
void accumulate(const RefVector< MCPWalker > &walkers, const RefVector< ParticleSet > &psets, const RefVector< TrialWaveFunction > &wfns, const RefVector< QMCHamiltonian > &hams, RandomBase< FullPrecReal > &rng) override
CrystalLattice< OHMMS_PRECISION, OHMMS_DIM > ParticleLayout
Definition: Configuration.h:79
void calcDensity(const Position &r, Real &dens, ParticleSet &pset_target)
calculate density based on r
std::unique_ptr< OperatorEstBase > spawnCrowdClone() const override
class to handle hdf file
Definition: hdf_archive.h:51
Timer accumulates time and call counts.
Definition: NewTimer.h:135
const char walkers[]
Definition: HDFVersion.h:36
Position rcorner_
with respect to center_ using lattice_;
std::vector< Matrix< Value > > Phi_NB_
row major per sample workspaces
size_t calcFullDataSize(size_t basis_size, int num_species)
void generateSampleBasis(Matrix< Value > &Phi_mb, ParticleSet &pset_target, TrialWaveFunction &psi_target)
set Phi_mp to basis vaules per sample sideeffects:
void updateBasisWithSpin(const Position &r, const Real &s, ParticleSet &pset_target)
basis set updates with spin
void calcDensityDrift(const Position &r, Real &dens, Position &drift, ParticleSet &pset_target)
calculate density and drift bashed on r
Matrix< Value > Phi_MB_
basis_values_ at each r of rsamples_ row: sample col: basis_value size: samples * basis_size ...
void normalizeBasis(ParticleSet &pset_target)
#define OHMMS_DIM
Definition: config.h:64
void generateDensitySamplesWithSpin(bool save, int steps, RandomBase< FullPrecReal > &rng, ParticleSet &pset_target)
same as above, but with spin variables included
void generateSamples(const Real weight, ParticleSet &pset_target, RandomBase< FullPrecReal > &rng, int steps=0)
Dispatch method to difference methods of generating samples.
CrystalLattice< OHMMS_PRECISION, OHMMS_DIM > lattice
void evaluateMatrix(ParticleSet &pset_target, TrialWaveFunction &psi_target, const MCPWalker &walker, RandomBase< FullPrecReal > &rng)
Specialized paritlce class for atomistic simulations.
Definition: ParticleSet.h:55
Native representation for DensityMatrices1B Estimator&#39;s inputs.
void generateDensitySamples(bool save, int steps, RandomBase< FullPrecReal > &rng, ParticleSet &pset_target)
generate samples for density integration
QTFull::ValueType FullPrecValueType
Definition: Configuration.h:67
void warmupSampling(ParticleSet &pset_target, RandomBase< FullPrecReal > &rng)
does some warmup sampling i.e.
QTBase::ValueType ValueType
Definition: Configuration.h:60
NewTimer & createGlobalTimer(const std::string &myname, timer_levels mylevel)
A minimally functional wrapper for the since c++11 <random>
void report(const std::string &pad="")
An abstract class for gridded estimators.
Position diffuse(const Real sqt, RandomBase< FullPrecReal > &rng)
produce a position difference vector from timestep
void generateParticleBasis(ParticleSet &pset_target, std::vector< Matrix< Value >> &phi_nb)
set phi_nb to basis values per target particleset particle sideeffects:
QTBase::PosType PosType
Definition: Configuration.h:61
OneBodyDensityMatricesInput obdmi(node)
void generateUniformGrid(RandomBase< FullPrecReal > &rng)
void calcDensityDriftWithSpin(const Position &r, const Real &s, Real &dens, Position &drift, Real &sdrift, ParticleSet &pset_target)
same as above, but with spin move
void calcDensityWithSpin(const Position &r, const Real &s, Real &dens, ParticleSet &pset_target)
same as above, but with spin move
void implAccumulate(const RefVector< MCPWalker > &walkers, const RefVector< ParticleSet > &psets, const RefVector< TrialWaveFunction > &wfns, RandomBase< FullPrecReal > &rng)
Unfortunate design RandomGenerator type aliasing and virtual inheritance requires this for testing...
Sampling sampling_
Sampling method, this derived values in input_.
std::vector< std::reference_wrapper< T > > RefVector
void updateBasis(const Position &r, ParticleSet &pset_target)
basis set updates
Class to represent a many-body trial wave function.
typename RealAlias_impl< T >::value_type RealAlias
If you have a function templated on a value that can be real or complex and you need to get the base ...
std::map< std::string, const std::unique_ptr< const SPOSet > > SPOMap
Definition: SPOSet.h:57
Real diffuseSpin(const Real sqt, RandomBase< FullPrecReal > &rng)
spin diffusion
std::vector< Matrix< Value > > Phi_Psi_NB_
DataLocality
data locality with respect to walker buffer
Definition: DataLocality.h:19
Custom container for set of attributes for a set of species.
Definition: SpeciesSet.h:33
std::vector< Matrix< Value > > N_BB_
Position rpcur_
current position – As long Positions are TinyVectors they are intialized to zero vectors ...
void registerOperatorEstimator(hdf_archive &file) override
create and tie OperatorEstimator&#39;s observable_helper hdf5 wrapper to stat.h5 file ...
int naccepted_
number of accepted samples
OneBodyDensityMatrices(OneBodyDensityMatricesInput &&obdmi, const Lattice &lattice, const SpeciesSet &species, const SPOMap &spomap, const ParticleSet &pset_target)
Standard Constructor Call this to make a new OBDM this is what you should be calling.
A container class to represent a walker.
Definition: Walker.h:49
void generateUniformSamples(RandomBase< FullPrecReal > &rng)
void updateBasisD012WithSpin(const Position &r, const Real &s, ParticleSet &pset_target)
same as above, but includes spin gradients
std::vector< Value > psi_ratios_
, &#39; .
QMCTraits::FullPrecValueType FullPrecValue
std::vector< Matrix< Value > > Psi_NM_
ratio per particle per sample size: particles * samples vector is over species each matrix row: parti...