QMCPACK
WalkerLogCollector.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: Jaron T. Krogel, krogeljt@ornl.gov, Oak Ridge National Laboratory
8 //
9 // File created by: Jaron T. Krogel, krogeljt@ornl.gov, Oak Ridge National Laboratory
10 //////////////////////////////////////////////////////////////////////////////////////
11 
12 
13 #include "WalkerLogCollector.h"
14 
15 #include "Particle/Walker.h"
16 #include "Particle/ParticleSet.h"
19 
20 
21 namespace qmcplusplus
22 {
23 
24 using MCPWalker = Walker<QMCTraits, PtclOnLatticeTraits>;
25 
26 WalkerLogCollector::WalkerLogCollector(const WalkerLogState& state) : state_(state) { init(); }
27 
28 
30 {
31  properties_include = {"R2Accepted", "R2Proposed", "LocalEnergy", "LocalPotential", "Kinetic",
32  "ElecElec", "ElecIon", "LocalECP", "NonLocalECP"};
33  energy_index = -1;
34  // empty walker steps and energy vectors for the MC block
35  steps.resize(0);
36  energies.resize(0);
37  // label the buffers for HDF file write
38  walker_property_int_buffer.label = "walker_property_int";
39  walker_property_real_buffer.label = "walker_property_real";
40  walker_particle_real_buffer.label = "walker_particle_real";
41 }
42 
43 
45 {
46  if (!state_.logs_active)
47  return; // no-op for driver if logs are inactive
48  if (state_.verbose)
49  app_log() << "WalkerLogCollector::startBlock " << std::endl;
50  resetBuffers(); // resize buffers to zero rows
51 }
52 
53 
55  const ParticleSet& pset,
56  const TrialWaveFunction& wfn,
57  const QMCHamiltonian& ham,
58  int step)
59 {
60  if (!state_.logs_active)
61  return; // no-op for driver if logs are inactive
62 
63  // only collect walker data at steps matching the period (default 1)
64  int current_step = (step == -1) ? pset.current_step : step;
65  if (current_step % state_.step_period != 0)
66  return;
67 
68  auto& bsi = walker_property_int_buffer;
69  auto& bsr = walker_property_real_buffer;
71 
72  // collect per-particle walker quantities
73  size_t nparticles = walker.R.size();
74  size_t ndim = walker.R[0].size();
75  // per-particle positions (walker.R)
76  Rtmp.resize(nparticles, ndim);
77  for (size_t p = 0; p < nparticles; ++p)
78  for (size_t d = 0; d < ndim; ++d)
79  Rtmp(p, d) = (WLog::Real)walker.R[p][d];
80  bar.collect("R", Rtmp);
81  // per-particle "spin" (walker.spins)
82  if (pset.isSpinor())
83  {
84  Stmp.resize(nparticles);
85  for (size_t p = 0; p < nparticles; ++p)
86  Stmp(p) = (WLog::Real)walker.spins[p];
87  bar.collect("S", Stmp);
88  }
89  // per-particle gradient(log(psi)) (pset.G)
90  Gtmp.resize(nparticles, ndim);
91  for (size_t p = 0; p < nparticles; ++p)
92  for (size_t d = 0; d < ndim; ++d)
93  Gtmp(p, d) = (WLog::PsiVal)pset.G[p][d];
94  bar.collect("G", Gtmp);
95  // per-particle laplacian(log(psi)) (pset.L)
96  Ltmp.resize(nparticles);
97  for (size_t p = 0; p < nparticles; ++p)
98  Ltmp(p) = (WLog::PsiVal)pset.L[p];
99  bar.collect("L", Ltmp);
100  bar.resetCollect();
101 
102  // collect integer walker properties
103  bsi.collect("step", (WLog::Int)current_step);
104  bsi.collect("id", (WLog::Int)walker.getWalkerID());
105  bsi.collect("parent_id", (WLog::Int)walker.getParentID());
106  bsi.collect("age", (WLog::Int)walker.Age);
107  bsi.resetCollect();
108 
109  // collect real walker properties
110  bsr.collect("weight", (WLog::Real)walker.Weight);
111  bsr.collect("multiplicity", (WLog::Real)walker.Multiplicity);
112  bsr.collect("logpsi", (WLog::Real)wfn.getLogPsi());
113  bsr.collect("phase", (WLog::Real)wfn.getPhase());
114  // from PropertyList
115  if (bsr.first_collect)
116  {
117  for (size_t n = 0; n < pset.PropertyList.size(); ++n)
118  {
119  auto& name = pset.PropertyList.Names[n];
120  auto& value = walker.Properties(0, n);
121  if (properties_include.find(name) != properties_include.end())
122  {
123  bsr.collect(name, (WLog::Real)value);
124  property_indices.push_back(n);
125  }
126  if (name == "LocalEnergy")
127  energy_index = n;
128  }
129  if (energy_index < 0)
130  throw std::runtime_error("LogCollector::collect energy_index must not be negative");
131  }
132  else
133  for (auto n : property_indices)
134  {
135  auto& name = pset.PropertyList.Names[n];
136  auto& value = walker.Properties(0, n);
137  bsr.collect(name, (WLog::Real)value);
138  }
139  // nodal proximity measures
140  auto& gv = Gtmp.storage();
141  WLog::Real dr = std::numeric_limits<WLog::Real>::max();
142  for (size_t n = 0; n < gv.size(); ++n)
143  dr = std::min(dr, std::abs(1. / std::real(gv[n])));
144  auto dr_node_min = dr;
145  WLog::Real dlogpsi2 = 0.;
146  for (size_t n = 0; n < gv.size(); ++n)
147  dlogpsi2 += std::real(gv[n]) * std::real(gv[n]);
148  WLog::Real dphase2 = 0.;
149  for (size_t n = 0; n < gv.size(); ++n)
150  dphase2 += std::imag(gv[n]) * std::imag(gv[n]);
151  bsr.collect("dr_node_min", dr_node_min);
152  bsr.collect("dlogpsi2", dlogpsi2); // dr_node = 1/sqrt(dlogpsi2)
153  bsr.collect("dphase2", dphase2); // dr_node = 1/sqrt(dphase2)
154  bsr.resetCollect();
155 
156  // save the energy of this walker
157  steps.push_back((size_t)current_step);
158  energies.push_back((WLog::Real)walker.Properties(0, energy_index));
159 }
160 
161 
163 {
164  if (state_.verbose)
165  app_log() << "WalkerLogCollector::reset_buffers" << std::endl;
166  // resize all buffers to zero rows
170  // similar for step/energy vectors
171  steps.resize(0);
172  energies.resize(0);
173 }
174 
175 
177 {
178  if (state_.verbose)
179  app_log() << "WalkerLogCollector::checkBuffers" << std::endl;
180  size_t nrows = walker_property_int_buffer.nrows();
181  auto prop_real_bad = walker_property_real_buffer.nrows() != nrows;
182  auto part_real_bad = walker_particle_real_buffer.nrows() != nrows;
183  auto steps_bad = steps.size() != nrows;
184  auto energies_bad = energies.size() != nrows;
185  auto any_bad = prop_real_bad || part_real_bad || steps_bad || energies_bad;
186 
187  if (prop_real_bad)
188  app_log() << "WalkerLogCollector::checkBuffers walker_property_real_buffer row count does not match\n";
189  if (part_real_bad)
190  app_log() << "WalkerLogCollector::checkBuffers walker_particle_real_buffer row count does not match\n";
191  if (steps_bad)
192  app_log() << "WalkerLogCollector::checkBuffers steps entry count does not match\n";
193  if (energies_bad)
194  app_log() << "WalkerLogCollector::checkBuffers energies entry count does not match\n";
195  if (any_bad)
196  throw std::runtime_error("WalkerLogCollector::checkBuffers buffer lengths do not match");
197 }
198 
199 
200 } // namespace qmcplusplus
Array< WLog::PsiVal, 2 > Gtmp
tmp storage for walker wavefunction gradients
Array< WLog::Real, 2 > Rtmp
tmp storage for walker positions
QMCTraits::RealType real
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
Array< WLog::PsiVal, 1 > Ltmp
tmp storage for walker wavefunciton laplacians
int energy_index
location of LocalEnergy in ParticleSet::PropertyList
bool verbose
controls verbosity of log file writes
int step_period
period between MC steps for data collection
MakeReturn< UnaryNode< FnFabs, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t abs(const Vector< T1, C1 > &l)
WalkerLogBuffer< WLog::Int > walker_property_int_buffer
buffer containing integer walker properties
std::ostream & app_log()
Definition: OutputManager.h:65
if(c->rank()==0)
void checkBuffers()
Check that all buffers have the same number of rows.
std::vector< size_t > property_indices
indices in ParticleSet::PropertyList for included quantities
WalkerLogBuffer< WLog::Real > walker_property_real_buffer
buffer containing real-valued walker properties
Collection of Local Energy Operators.
OHMMS_PRECISION_FULL Real
std::unordered_set< std::string > properties_include
ParticleSet::PropertyList quantities to include.
const WalkerLogState & state_
state data set by WalkerLogManager
void resize(const std::array< SIZET, D > &dims)
Resize the container.
Definition: OhmmsArray.h:65
void resetBuffers()
resize buffers to zero rows
std::string label
label for this data in HDF file
Array< WLog::Real, 1 > Stmp
tmp storage for walker spins
T min(T a, T b)
bool logs_active
whether logs are active in the current driver
Specialized paritlce class for atomistic simulations.
Definition: ParticleSet.h:55
Container_t & storage()
Definition: OhmmsArray.h:60
float imag(const float &c)
imaginary part of a scalar. Cannot be replaced by std::imag due to AFQMC specific needs...
WalkerLogBuffer< WLog::Real > walker_particle_real_buffer
buffer containing per-particle walker data
void init()
shared variable setting in constructors
size_t nrows()
current number of rows in the data buffer
void collect(const MCPWalker &walker, const ParticleSet &pset, const TrialWaveFunction &wfn, const QMCHamiltonian &ham, int step=-1)
collect all data for one walker into the data buffers
Declaration of a TrialWaveFunction.
Class to represent a many-body trial wave function.
std::vector< WLog::Real > energies
LocalEnergy information for each walker throughout the MC block.
Walker< QMCTraits, PtclOnLatticeTraits > MCPWalker
Definition: test_walker.cpp:31
void resetBuffer()
resize the buffer to zero
void startBlock()
resize buffers to zero rows at beginning of each MC block
Helper struct holding data transferred from WalkerLogManager to WalkerLogCollector following input re...
std::vector< size_t > steps
MC step information for each walker throughout the MC block.
A container class to represent a walker.
Definition: Walker.h:49
WalkerLogCollector(const WalkerLogState &state)
constructor. The state should be given by the manager.
Declaration of QMCHamiltonian.