QMCPACK
QMCUpdateBase.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) 2016 Jeongnim Kim and QMCPACK developers.
6 //
7 // File developed by: Jeremy McMinnis, jmcminis@gmail.com, University of Illinois at Urbana-Champaign
8 // Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
9 // Paul Yang, yyang173@illinois.edu, University of Illinois at Urbana-Champaign
10 // Jaron T. Krogel, krogeljt@ornl.gov, Oak Ridge National Laboratory
11 // Mark A. Berrill, berrillma@ornl.gov, Oak Ridge National Laboratory
12 //
13 // File created by: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
14 //////////////////////////////////////////////////////////////////////////////////////
15 
16 
17 #include "QMCUpdateBase.h"
18 #include "MemoryUsage.h"
22 #include "OhmmsData/AttributeSet.h"
23 #include "Concurrency/OpenMP.h"
24 #if !defined(REMOVE_TRACEMANAGER)
26 #else
27 using TraceManager = int;
28 #endif
29 #include "WalkerLogCollector.h"
30 
31 namespace qmcplusplus
32 {
33 /// Constructor.
35  TrialWaveFunction& psi,
36  TrialWaveFunction& guide,
37  QMCHamiltonian& h,
39  : csoffset(0),
40  Traces(0),
41  wlog_collector(0),
42  W(w),
43  Psi(psi),
44  Guide(guide),
45  H(h),
46  RandomGen(rg),
47  branchEngine(0),
48  DriftModifier(0),
49  Estimators(0),
50  initWalkers_timer_(createGlobalTimer("QMCUpdateBase::WalkerInit", timer_level_medium))
51 {
52  setDefaults();
53 }
54 
55 /// Constructor.
57  TrialWaveFunction& psi,
58  QMCHamiltonian& h,
60  : csoffset(0),
61  Traces(0),
62  wlog_collector(0),
63  W(w),
64  Psi(psi),
65  Guide(psi),
66  H(h),
67  RandomGen(rg),
68  branchEngine(0),
69  DriftModifier(0),
70  Estimators(0),
71  initWalkers_timer_(createGlobalTimer("QMCUpdateBase::WalkerInit", timer_level_medium))
72 {
73  setDefaults();
74 }
75 
76 /// destructor
78 
80 {
81  UpdatePbyP = true;
82  UseDrift = true;
83  NumPtcl = 0;
84  nSubSteps = 1;
85  MaxAge = 10;
86  m_r2max = -1;
87  myParams.add(m_r2max, "maxDisplSq"); //maximum displacement
88  myParams.add(debug_checks_str_, "debug_checks", {"no", "all", "checkGL_after_moves"});
89  //store 1/mass per species
90  SpeciesSet tspecies(W.getSpeciesSet());
91  assert(tspecies.getTotalNum() == W.groups());
92  int massind = tspecies.addAttribute("mass");
93  MassInvS.resize(tspecies.getTotalNum());
94  for (int ig = 0; ig < tspecies.getTotalNum(); ++ig)
95  MassInvS[ig] = 1.0 / tspecies(massind, ig);
96  MassInvP.resize(W.getTotalNum());
97  for (int ig = 0; ig < W.groups(); ++ig)
98  for (int iat = W.first(ig); iat < W.last(ig); ++iat)
99  MassInvP[iat] = MassInvS[ig];
100 }
101 
102 bool QMCUpdateBase::put(xmlNodePtr cur)
103 {
104  H.setNonLocalMoves(cur);
105  bool s = myParams.put(cur);
106  if (debug_checks_str_ == "no")
108  else
109  {
110  if (debug_checks_str_ == "all" || debug_checks_str_ == "checkGL_after_load")
112  if (debug_checks_str_ == "all" || debug_checks_str_ == "checkGL_after_moves")
114  if (debug_checks_str_ == "all" || debug_checks_str_ == "checkGL_after_tmove")
116  }
117  return s;
118 }
119 
122  TraceManager* traces,
123  WalkerLogCollector* wlog_collector_,
124  const DriftModifierBase* driftmodifer)
125 {
126  wlog_collector = wlog_collector_;
127  resetRun(brancher,est,traces,driftmodifer);
128 }
129 
132  TraceManager* traces,
133  const DriftModifierBase* driftmodifer)
134 {
135  Estimators = est;
136  branchEngine = brancher;
137  DriftModifier = driftmodifer;
138  Traces = traces;
139 
140  NumPtcl = W.getTotalNum();
141  deltaR.resize(NumPtcl);
142  deltaS.resize(NumPtcl);
143  drift.resize(NumPtcl);
144  G.resize(NumPtcl);
145  dG.resize(NumPtcl);
146  L.resize(NumPtcl);
147  dL.resize(NumPtcl);
148  //set the default tau-mass related values with electrons
149  Tau = brancher->getTau();
150  m_tauovermass = Tau * MassInvS[0];
151  m_oneover2tau = 0.5 / (m_tauovermass);
153  if (!UpdatePbyP)
154  {
155  // store sqrt(tau/mass)
156  SqrtTauOverMass.resize(W.getTotalNum());
157  for (int iat = 0; iat < W.getTotalNum(); ++iat)
158  SqrtTauOverMass[iat] = std::sqrt(Tau * MassInvP[iat]);
159  }
160  //app_log() << " QMCUpdateBase::resetRun m/tau=" << m_tauovermass << std::endl;
161  if (m_r2max < 0)
162  m_r2max = W.getLattice().LR_rc * W.getLattice().LR_rc;
163  //app_log() << " Setting the bound for the displacement std::max(r^2) = " << m_r2max << std::endl;
164 }
165 
166 void QMCUpdateBase::startRun(int blocks, bool record)
167 {
168  Estimators->start(blocks, record);
169 #if !defined(REMOVE_TRACEMANAGER)
170  if (!Traces)
171  {
172  APP_ABORT(
173  "QMCUpdateBase::startRun\n derived QMCDriver class has not setup trace clones properly\n null TraceManager "
174  "pointer encountered in derived QMCUpdateBase class\n see VMCLinearOptOMP.cpp for a correct minimal interface "
175  "(search on 'trace')\n refer to changes made in SVN revision 6597 for further guidance");
176  }
179 #endif
180 }
181 
183 
184 //ugly, but will use until general usage of stopRun is clear
185 // DMC and VMC do not use stopRun anymore
187 {
188 #if !defined(REMOVE_TRACEMANAGER)
189  H.finalize_traces();
191 #endif
192 }
193 
195 {
196  Estimators->startBlock(steps);
197 #if !defined(REMOVE_TRACEMANAGER)
198  Traces->startBlock(steps);
199 #endif
200  if(wlog_collector)
202  nAccept = 0;
203  nReject = 0;
204  nAllRejected = 0;
205  nNodeCrossing = 0;
207 }
208 
209 void QMCUpdateBase::stopBlock(bool collectall)
210 {
211  Estimators->stopBlock(acceptRatio(), collectall);
212 #if !defined(REMOVE_TRACEMANAGER)
213  Traces->stopBlock();
214 #endif
215 }
216 
218 {
220  UpdatePbyP = false;
221  //ignore different mass
222  //RealType tauovermass = Tau*MassInv[0];
223  for (; it != it_end; ++it)
224  {
225  auto& walker = *it;
226  W.R = walker->R;
227  W.update();
228  RealType logpsi(Psi.evaluateLog(W));
229  walker->G = W.G;
230  walker->L = W.L;
232  RealType ene = H.evaluate(W);
233  // cannot call auxHevalate() here because walkers are not initialized
234  // for example, DensityEstimator needs the weights of the walkers
235  //H.auxHevaluate(W);
236  walker->resetProperty(logpsi, Psi.getPhase(), ene, 0.0, 0.0, nodecorr);
237  walker->Weight = 1.0;
238  H.saveProperty(walker->getPropertyBase());
239  }
240 }
241 
243 {
245  UpdatePbyP = true;
246  if (it == it_end)
247  {
248  // a particular case, no walker enters in this call.
249  // but need to free the memory of Psi.
250  Walker_t dummy_walker(W.getTotalNum());
251  dummy_walker.Properties = W.Properties;
252  dummy_walker.registerData();
253  Psi.registerData(W, dummy_walker.DataSet);
254  }
255  for (; it != it_end; ++it)
256  {
257  Walker_t& awalker(**it);
258  W.R = awalker.R;
259  W.spins = awalker.spins;
260  W.update();
261  if (awalker.DataSet.size())
262  awalker.DataSet.clear();
263  awalker.DataSet.rewind();
264  awalker.registerData();
265  Psi.registerData(W, awalker.DataSet);
266  awalker.DataSet.allocate();
267  // This from here on should happen in the scope of the block
268  Psi.copyFromBuffer(W, awalker.DataSet);
269  Psi.evaluateLog(W);
270  RealType logpsi = Psi.updateBuffer(W, awalker.DataSet, false);
271  W.saveWalker(awalker);
272  RealType eloc = H.evaluate(W);
273  awalker.resetProperty(logpsi, Psi.getPhase(), eloc);
274  H.auxHevaluate(W, awalker);
275  H.saveProperty(awalker.getPropertyBase());
276  awalker.Weight = 1.;
277  }
278 #pragma omp master
279  print_mem("Memory Usage after the buffer registration", app_log());
280 }
281 
283  ParticleSet::ParticlePos& gscaled)
284 {
285  //setScaledDrift(m_tauovermass,g,gscaled);
286  //RealType vsq=Dot(g,g);
287  //RealType x=m_tauovermass*vsq;
288  //return (vsq<std::numeric_limits<RealType>::epsilon())? 1.0:((-1.0+std::sqrt(1.0+2.0*x))/x);
289  return setScaledDriftPbyPandNodeCorr(Tau, MassInvP, g, gscaled);
290 }
291 
292 void QMCUpdateBase::checkLogAndGL(ParticleSet& pset, TrialWaveFunction& twf, const std::string_view location)
293 {
294  bool success = true;
295  TrialWaveFunction::LogValue log_value{twf.getLogPsi(), twf.getPhase()};
298 
299  pset.update();
300  twf.evaluateLog(pset);
301 
302  RealType threshold;
303  // mixed precision can't make this test with cuda direct inversion
304  if constexpr (std::is_same<RealType, FullPrecRealType>::value)
305  threshold = 100 * std::numeric_limits<float>::epsilon();
306  else
307  threshold = 500 * std::numeric_limits<float>::epsilon();
308 
309  std::ostringstream msg;
310  auto& ref_G = twf.G;
311  auto& ref_L = twf.L;
312  TrialWaveFunction::LogValue ref_log{twf.getLogPsi(), twf.getPhase()};
313  if (std::abs(std::exp(log_value) - std::exp(ref_log)) > std::abs(std::exp(ref_log)) * threshold)
314  {
315  success = false;
316  msg << "Logpsi " << log_value << " ref " << ref_log << std::endl;
317  }
318 
319  for (int iel = 0; iel < ref_G.size(); iel++)
320  {
321  auto grad_diff = ref_G[iel] - G_saved[iel];
322  if (std::sqrt(std::abs(dot(grad_diff, grad_diff))) > std::sqrt(std::abs(dot(ref_G[iel], ref_G[iel]))) * threshold)
323  {
324  success = false;
325  msg << "Grad[" << iel << "] ref = " << ref_G[iel] << " wrong = " << G_saved[iel] << " Delta " << grad_diff
326  << std::endl;
327  }
328 
329  auto lap_diff = ref_L[iel] - L_saved[iel];
330  if (std::abs(lap_diff) > std::abs(ref_L[iel]) * threshold)
331  {
332  // very hard to check mixed precision case, only print, no error out
333  if (std::is_same<RealType, FullPrecRealType>::value)
334  success = false;
335  msg << "lap[" << iel << "] ref = " << ref_L[iel] << " wrong = " << L_saved[iel] << " Delta " << lap_diff
336  << std::endl;
337  }
338  }
339 
340  std::cerr << msg.str();
341  if (!success)
342  throw std::runtime_error(std::string("checkLogAndGL failed at ") + std::string(location) + std::string("\n"));
343 }
344 
346 {
347  for (; it != it_end; ++it)
348  {
349  auto& walker = *it;
350  RealType M = walker->Weight;
351  if (walker->Age > MaxAge)
352  M = std::min((RealType)0.5, M);
353  else if (walker->Age > 0)
354  M = std::min((RealType)1.0, M);
355  walker->Multiplicity = M + RandomGen();
356  }
357 }
358 
360 {
361  for (; it != it_end; ++it)
362  {
363  advanceWalker(**it, recompute);
364  }
365 }
366 
367 } // namespace qmcplusplus
TraceManager * Traces
traces
RealType evaluateLog(ParticleSet &P)
evalaute the log (internally gradients and laplacian) of the trial wavefunction.
const BranchEngineType * branchEngine
branch engine, stateless reference to the one in QMCDriver
ParticleSet::ParticlePos drift
temporary storage for drift
WalkerLogCollector * wlog_collector
RealType m_tauovermass
tau/mass
PropertyContainer_t Properties
scalar properties of a walker
Definition: Walker.h:125
void setNonLocalMoves(xmlNodePtr cur)
set non local moves options
WFBuffer_t DataSet
buffer for the data for particle-by-particle update
Definition: Walker.h:135
A set of walkers that are to be advanced by Metropolis Monte Carlo.
MCWalkerConfiguration::iterator WalkerIter_t
Definition: QMCUpdateBase.h:45
void copyFromBuffer(ParticleSet &P, WFBufferType &buf)
copy all the wavefunction components from buffer.
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
ParticleScalar spins
internal spin variables for dynamical spin calculations
Definition: ParticleSet.h:81
PropertyContainer_t Properties
properties of the current walker
Definition: ParticleSet.h:119
QTBase::RealType RealType
Definition: Configuration.h:58
TrialWaveFunction & Psi
trial function
MakeReturn< UnaryNode< FnFabs, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t abs(const Vector< T1, C1 > &l)
size_t getTotalNum() const
Definition: ParticleSet.h:493
ParticleSet::ParticleScalar deltaS
temporart storage for spin displacement
std::ostream & app_log()
Definition: OutputManager.h:65
void saveProperty(IT first)
save the values of Hamiltonian elements to the Properties
virtual bool put(xmlNodePtr cur)
process options
void registerData()
Definition: Walker.h:369
WaveFunctionComponent::LogValue LogValue
Collection of Local Energy Operators.
ParticleAttrib< QTFull::ValueType > ParticleLaplacian
Definition: Configuration.h:96
this class implements drift modification
void allocate()
allocate the data
Definition: PooledMemory.h:104
Crowd-level resource for walker log collection.
int first(int igroup) const
return the first index of a group i
Definition: ParticleSet.h:514
RealType m_sqrttau
Time-step factor .
void update(bool skipSK=false)
update the internal data
ParticleSet::ParticlePos deltaR
temporary storage for random displacement
ParticleLaplacian L
laplacians of the particles
Definition: ParticleSet.h:85
int addAttribute(const std::string &aname)
for a new attribute, allocate the data, !More often used to get the index of a species ...
Definition: SpeciesSet.cpp:45
void print_mem(const std::string &title, std::ostream &log)
Definition: MemoryUsage.cpp:30
RealType updateBuffer(ParticleSet &P, WFBufferType &buf, bool fromscratch=false)
update all the wavefunction components in buffer.
void startBlock(int nsteps)
T min(T a, T b)
DriverDebugChecks debug_checks_
determine additional checks for debugging purpose
Definition: QMCUpdateBase.h:58
bool put(std::istream &is) override
read from std::istream
Definition: ParameterSet.h:42
void startBlock(int steps)
prepare to start a block
IndexType nNodeCrossing
Total number of node crossings per block.
Definition: QMCUpdateBase.h:69
ParticleScalar spins
Definition: Walker.h:117
int groups() const
return the number of groups
Definition: ParticleSet.h:511
void resetRun(BranchEngineType *brancher, EstimatorManagerBase *est, TraceManager *traces, const DriftModifierBase *driftmodifer)
reset the QMCUpdateBase parameters
void startBlock(int steps)
start a block
Specialized paritlce class for atomistic simulations.
Definition: ParticleSet.h:55
Manages the state of QMC sections and handles population control for DMCs.
T setScaledDriftPbyPandNodeCorr(T tau, const ParticleAttrib< TinyVector< T1, D >> &qf, ParticleAttrib< TinyVector< T, D >> &drift)
scale drift
EstimatorManagerBase * Estimators
estimator
virtual void initWalkers(WalkerIter_t it, WalkerIter_t it_end)
initialize Walker for walker update
std::vector< RealType > SqrtTauOverMass
sqrt(tau/Mass) per particle
ParticleGradient G
gradients of the particles
Definition: ParticleSet.h:83
void saveWalker(Walker_t &awalker)
save this to awalker
virtual void advanceWalker(Walker_t &thisWalker, bool recompute)=0
move a walker
NewTimer & createGlobalTimer(const std::string &myname, timer_levels mylevel)
RealType Tau
timestep
Definition: QMCUpdateBase.h:73
void registerData(ParticleSet &P, WFBufferType &buf)
register all the wavefunction components in buffer.
ParticlePos R
Position.
Definition: ParticleSet.h:79
#define APP_ABORT(msg)
Widely used but deprecated fatal error macros from legacy code.
Definition: AppAbort.h:27
void stopBlock(bool collectall=true)
stop a block
int last(int igroup) const
return the last index of a group i
Definition: ParticleSet.h:517
ParticleSet::ParticleLaplacian dL
MakeReturn< UnaryNode< FnExp, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t exp(const Vector< T1, C1 > &l)
MCWalkerConfiguration & W
walker ensemble
void setDefaults()
set default parameters
std::vector< RealType > MassInvP
1/Mass per particle
static void checkLogAndGL(ParticleSet &pset, TrialWaveFunction &twf, const std::string_view location)
check logpsi and grad and lap against values computed from scratch
RealType getNodeCorrection(const ParticleSet::ParticleGradient &g, ParticleSet::ParticlePos &gscaled)
evaluate the ratio of scaled velocity and velocity
QMCUpdateBase(MCWalkerConfiguration &w, TrialWaveFunction &psi, QMCHamiltonian &h, RandomBase< FullPrecRealType > &rg)
Constructor.
SpeciesSet & getSpeciesSet()
retrun the SpeciesSet of this particle set
Definition: ParticleSet.h:231
void initialize_traces(TraceManager &tm, ParticleSet &P)
initialize trace data
Class to manage a set of ScalarEstimators.
void auxHevaluate(ParticleSet &P)
int nSubSteps
number of steps per measurement
Definition: QMCUpdateBase.h:56
void add(PDT &aparam, const std::string &aname_in, std::vector< PDT > candidate_values={}, TagStatus status=TagStatus::OPTIONAL)
add a new parameter corresponding to an xmlNode <parameter>
IndexType MaxAge
MaxAge>0 indicates branch is done.
Definition: QMCUpdateBase.h:61
MakeReturn< UnaryNode< FnSqrt, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t sqrt(const Vector< T1, C1 > &l)
virtual ~QMCUpdateBase()
destructor
size_type size() const
return the size of the data
Definition: PooledMemory.h:73
Class to represent a many-body trial wave function.
RandomBase< FullPrecRealType > & RandomGen
random number generator
FullPrecRealType evaluate(ParticleSet &P)
evaluate Local Energy
void stopBlock(RealType accept, bool collectall=true)
stop a block
ParticleAttrib< SingleParticlePos > ParticlePos
Definition: Configuration.h:92
void startBlock()
resize buffers to zero rows at beginning of each MC block
virtual void initWalkersForPbyP(WalkerIter_t it, WalkerIter_t it_end)
initialize Walker buffers for PbyP update
FullPrecRealType Weight
Weight of the walker.
Definition: Walker.h:102
const auto & getLattice() const
Definition: ParticleSet.h:251
void finalize_traces()
finalize trace data
Tensor< typename BinaryReturn< T1, T2, OpMultiply >::Type_t, D > dot(const AntiSymTensor< T1, D > &lhs, const AntiSymTensor< T2, D > &rhs)
ParticleAttrib< QTFull::GradType > ParticleGradient
Definition: Configuration.h:95
Custom container for set of attributes for a set of species.
Definition: SpeciesSet.h:33
IndexType nAccept
counter for number of moves accepted
Definition: QMCUpdateBase.h:63
RealType m_oneover2tau
Time-step factor .
IndexType nReject
counter for number of moves rejected
Definition: QMCUpdateBase.h:65
virtual void advanceWalkers(WalkerIter_t it, WalkerIter_t it_end, bool recompute)
advance walkers executed at each step
ParticleSet::ParticleLaplacian L
storage for differential laplacians for PbyP update
FullPrecRealType * getPropertyBase()
Definition: Walker.h:277
ParticleSet::ParticleGradient dG
ParticleSet::ParticleGradient G
storage for differential gradients for PbyP update
void start(int blocks, bool record=true)
start a run
Declare QMCUpdateBase class.
void clear()
clear the data and set Current=0
Definition: PooledMemory.h:92
std::vector< RealType > MassInvS
1/Mass per species
void setMultiplicity(WalkerIter_t it, WalkerIter_t it_end)
set the multiplicity of the walkers to branch
void rewind(size_type cur=0, size_type cur_scalar=0)
set the cursors
Definition: PooledMemory.h:85
IndexType NumPtcl
number of particles
A container class to represent a walker.
Definition: Walker.h:49
QMCHamiltonian & H
Hamiltonian.
ParameterSet myParams
parameters
RealType m_r2max
maximum displacement^2
RealType acceptRatio() const
Definition: QMCUpdateBase.h:90
void resetProperty(FullPrecRealType logpsi, FullPrecRealType sigN, FullPrecRealType ene)
reset the property of a walker
Definition: Walker.h:296
void startRun(int blocks, bool record)
start a run
IndexType NonLocalMoveAccepted
Total numer of non-local moves accepted.
Definition: QMCUpdateBase.h:71
ParticlePos R
The configuration vector (3N-dimensional vector to store the positions of all the particles for a sin...
Definition: Walker.h:114
IndexType nAllRejected
Total number of the steps when all the particle moves are rejected.
Definition: QMCUpdateBase.h:67
void resetRun2(BranchEngineType *brancher, EstimatorManagerBase *est, TraceManager *traces, WalkerLogCollector *wlog_collector_, const DriftModifierBase *driftmodifer)
bool UpdatePbyP
update particle-by-particle
const DriftModifierBase * DriftModifier
drift modifer, stateless reference to the one in QMCDriver