QMCPACK
RMCUpdatePbyP.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 // Raymond Clay III, j.k.rofling@gmail.com, Lawrence Livermore National Laboratory
9 // Mark A. Berrill, berrillma@ornl.gov, Oak Ridge National Laboratory
10 //
11 // File created by: Jeremy McMinnis, jmcminis@gmail.com, University of Illinois at Urbana-Champaign
12 //////////////////////////////////////////////////////////////////////////////////////
13 
14 
15 #include "RMCUpdatePbyP.h"
17 #include "Concurrency/OpenMP.h"
18 #include "Configuration.h"
19 #include "Particle/Reptile.h"
20 #include <cmath>
21 //////////////////////////////////////////////////////////////////////////
22 // This driver is strongly based off the method used by Lucas Wagner in QWalk.
23 //
24 // This driver proposes an "all-electron" configuration by performing N single particle moves,
25 // accepting or rejecting at each step. Umrigar's scaled drift is used to generate the VMC configurations.
26 //
27 // The configuration is then accepted/rejected based only on the symmetrized DMC action, which
28 // amounts to Maroni/Baroni's method. Note that energy filtering (like in DMC) is used here as well.
29 //
30 // Until serious discrepencies are detected, it is strongly advised that this driver be used over the
31 // RMCUpdateAll, as the time step errors seem to be really reduced using this method.
32 //////////////////////////////////////////////////////////////////////////////
33 
34 
35 namespace qmcplusplus
36 {
38 
39 /// Constructor.
41  TrialWaveFunction& psi,
42  QMCHamiltonian& h,
44  std::vector<int> act,
45  std::vector<int> tp)
46  : QMCUpdateBase(w, psi, h, rg),
47  Action(act),
48  TransProb(tp),
49  advance_timer_(createGlobalTimer("RMCUpdatePbyP::advance", timer_level_medium)),
50  movepbyp_timer_(createGlobalTimer("RMCUpdatePbyP::movePbyP", timer_level_medium)),
51  update_mbo_timer_(createGlobalTimer("RMCUpdatePbyP::updateMBO", timer_level_medium)),
52  energy_timer_(createGlobalTimer("RMCUpdatePbyP::energy", timer_level_medium))
53 {
54  scaleDrift = false;
56 }
57 
59 
60 
62 {
63  UpdatePbyP = true;
64 
65  for (; it != it_end; ++it)
66  {
67  Walker_t& awalker = **it; //W.reptile->getHead();
68  W.R = awalker.R;
69  W.update(true);
70  W.donePbyP();
71  if (awalker.DataSet.size())
72  awalker.DataSet.clear();
73  awalker.DataSet.rewind();
74  Psi.registerData(W, awalker.DataSet);
75  awalker.DataSet.allocate();
76  Psi.copyFromBuffer(W, awalker.DataSet);
77  Psi.evaluateLog(W);
78  RealType logpsi = Psi.updateBuffer(W, awalker.DataSet, false);
79  awalker.G = W.G;
80  awalker.L = W.L;
81  RealType eloc = H.evaluate(W);
82  awalker.resetProperty(logpsi, Psi.getPhase(), eloc);
83  }
84 }
85 
86 bool RMCUpdatePbyPWithDrift::put(xmlNodePtr cur)
87 {
88  QMCUpdateBase::put(cur);
89 
90  ParameterSet m_param;
91  bool usedrift = true;
92  std::string action = "SLA";
93  m_param.add(usedrift, "useDrift");
94  m_param.add(action, "Action");
95  m_param.add(equilSteps, "equilsteps");
96  m_param.add(equilSteps, "equilSteps");
97  m_param.put(cur);
98 
99  if (usedrift == true)
100  {
101  if (omp_get_thread_num() == 0)
102  app_log() << " Using Umrigar scaled drift\n";
103  }
104  else
105  {
106  if (omp_get_thread_num() == 0)
107  app_log() << " Using non-scaled drift\n";
108  }
109 
110  if (action == "DMC")
111  {
113  if (omp_get_thread_num() == 0)
114  app_log() << " Using DMC link-action\n";
115  }
116  else
117  {
118  if (omp_get_thread_num() == 0)
119  app_log() << " Using Symmetrized Link-Action\n";
120  }
121 
122  return true;
123 }
125 {
127  Walker_t& curhead = W.reptile->getHead();
128  Walker_t prophead(curhead);
129  Walker_t::WFBuffer_t& w_buffer(prophead.DataSet);
130  W.loadWalker(prophead, true);
131  Psi.copyFromBuffer(W, w_buffer);
132  //create a 3N-Dimensional Gaussian with variance=1
134  int nAcceptTemp(0);
135  //copy the old energy and scale factor of drift
136  RealType eold(prophead.Properties(WP::LOCALENERGY));
137  RealType vqold(prophead.Properties(WP::DRIFTSCALE));
138  RealType enew(eold);
139  RealType rr_proposed = 0.0;
140  RealType rr_accepted = 0.0;
142  for (int ig = 0; ig < W.groups(); ++ig) //loop over species
143  {
144  RealType tauovermass = Tau * MassInvS[ig];
145  RealType oneover2tau = 0.5 / (tauovermass);
146  RealType sqrttau = std::sqrt(tauovermass);
147  for (int iat = W.first(ig); iat < W.last(ig); ++iat)
148  {
149  //get the displacement
150  GradType grad_iat = Psi.evalGrad(W, iat);
151  PosType dr;
152  DriftModifier->getDrift(tauovermass, grad_iat, dr);
153  dr += sqrttau * deltaR[iat];
154  bool is_valid = W.makeMoveAndCheck(iat, dr);
155  RealType rr = tauovermass * dot(deltaR[iat], deltaR[iat]);
156  rr_proposed += rr;
157  if (!is_valid || rr > m_r2max)
158  {
159  W.accept_rejectMove(iat, false);
160  continue;
161  }
162  ValueType ratio = Psi.calcRatioGrad(W, iat, grad_iat);
163  //node is crossed reject the move
165  {
166  ++nNodeCrossing;
167  W.accept_rejectMove(iat, false);
168  Psi.rejectMove(iat);
169  }
170  else
171  {
172  RealType logGf = -0.5 * dot(deltaR[iat], deltaR[iat]);
173  //Use the force of the particle iat
174  DriftModifier->getDrift(tauovermass, grad_iat, dr);
175  dr = W.R[iat] - W.getActivePos() - dr;
176  RealType logGb = -oneover2tau * dot(dr, dr);
177  RealType prob = std::norm(ratio) * std::exp(logGb - logGf);
178  bool is_accepted = false;
179  if (RandomGen() < prob)
180  {
181  is_accepted = true;
182  ++nAcceptTemp;
183  Psi.acceptMove(W, iat, true);
184  rr_accepted += rr;
185  }
186  else
187  {
188  Psi.rejectMove(iat);
189  }
190  W.accept_rejectMove(iat, is_accepted);
191  }
192  }
193  }
196  W.donePbyP();
197 
198  if (nAcceptTemp > 0)
199  {
200  //need to overwrite the walker properties
203  prophead.Age = 0;
204  prophead.R = W.R;
205  RealType logpsi = Psi.updateBuffer(W, w_buffer, false);
206  W.saveWalker(prophead);
209  enew = H.evaluate(W);
211  prophead.resetProperty(logpsi, Psi.getPhase(), enew, rr_accepted, rr_proposed, 0.0);
212  prophead.Weight = 1.0;
213  H.auxHevaluate(W, prophead, true, false); //evaluate properties but not collectables.
214  H.saveProperty(prophead.getPropertyBase());
215  newhead = prophead;
216  nAccept++;
217  }
218  else
219  {
220  //all moves are rejected: does not happen normally with reasonable wavefunctions
221  curhead.Age++;
222  curhead.Properties(WP::R2ACCEPTED) = 0.0;
223  //weight is set to 0 for traces
224  // consistent w/ no evaluate/auxHevaluate
225  RealType wtmp = prophead.Weight;
226  curhead.Weight = 0.0;
227  H.rejectedMove(W, curhead);
228  curhead.Weight = wtmp;
229  ++nAllRejected;
230  nReject++;
231  }
232  Walker_t& centerbead = W.reptile->getCenter();
233  W.loadWalker(centerbead, true);
234  W.update();
235  H.auxHevaluate(W, centerbead); //evaluate collectables but not properties.
236  // Traces->buffer_sample();
237 }
238 
239 
241 {
242  IndexType initsteps = W.reptile->nbeads * 2;
243 
244  vmcSteps = W.reptile->nbeads + 1;
245 
246  for (int n = 0; n < initsteps; n++)
248 }
249 
251 {
252  Walker_t& curhead = W.reptile->getHead();
253  Walker_t prophead(curhead);
254  Walker_t::WFBuffer_t& w_buffer(prophead.DataSet);
255  W.loadWalker(prophead, true);
256  Psi.copyFromBuffer(W, w_buffer);
257 
259  int nAcceptTemp(0);
260  //copy the old energy and scale factor of drift
261  RealType eold(prophead.Properties(WP::LOCALENERGY));
262  RealType vqold(prophead.Properties(WP::DRIFTSCALE));
263  RealType rr_proposed = 0.0;
264  RealType rr_accepted = 0.0;
266  for (int ig = 0; ig < W.groups(); ++ig) //loop over species
267  {
268  RealType tauovermass = Tau * MassInvS[ig];
269  RealType oneover2tau = 0.5 / (tauovermass);
270  RealType sqrttau = std::sqrt(tauovermass);
271  for (int iat = W.first(ig); iat < W.last(ig); ++iat)
272  {
273  //get the displacement
274  GradType grad_iat = Psi.evalGrad(W, iat);
275  PosType dr;
276  DriftModifier->getDrift(tauovermass, grad_iat, dr);
277  dr += sqrttau * deltaR[iat];
278  bool is_valid = W.makeMoveAndCheck(iat, dr);
279  RealType rr = tauovermass * dot(deltaR[iat], deltaR[iat]);
280  rr_proposed += rr;
281  if (!is_valid || rr > m_r2max)
282  {
283  W.accept_rejectMove(iat, false);
284  continue;
285  }
286  ValueType ratio = Psi.calcRatioGrad(W, iat, grad_iat);
287  //node is crossed reject the move
289  {
290  ++nNodeCrossing;
291  W.accept_rejectMove(iat, false);
292  Psi.rejectMove(iat);
293  }
294  else
295  {
296  RealType logGf = -0.5 * dot(deltaR[iat], deltaR[iat]);
297  //Use the force of the particle iat
298  DriftModifier->getDrift(tauovermass, grad_iat, dr);
299  dr = W.R[iat] - W.getActivePos() - dr;
300  RealType logGb = -oneover2tau * dot(dr, dr);
301  RealType prob = std::norm(ratio) * std::exp(logGb - logGf);
302  bool is_accepted = false;
303  if (RandomGen() < prob)
304  {
305  is_accepted = true;
306  ++nAcceptTemp;
307  Psi.acceptMove(W, iat, true);
308  rr_accepted += rr;
309  }
310  else
311  {
312  Psi.rejectMove(iat);
313  }
314  W.accept_rejectMove(iat, is_accepted);
315  }
316  }
317  }
320  W.donePbyP();
321  // In the rare case that all proposed moves fail, we bounce.
322  if (nAcceptTemp == 0)
323  {
324  ++nReject;
325  H.rejectedMove(W, prophead);
326  curhead.Age += 1;
327  W.reptile->flip();
328  }
329  prophead.R = W.R;
330  RealType logpsi = Psi.updateBuffer(W, w_buffer, false);
331  W.saveWalker(prophead);
332  Walker_t &lastbead(W.reptile->getTail()), nextlastbead(W.reptile->getNext());
333  RealType eloc = H.evaluate(W);
334  RealType dS = branchEngine->DMCLinkAction(eloc, curhead.Properties(WP::LOCALENERGY)) -
335  branchEngine->DMCLinkAction(lastbead.Properties(WP::LOCALENERGY), nextlastbead.Properties(WP::LOCALENERGY));
336  RealType acceptProb = std::min((RealType)1.0, std::exp(-dS));
337  if ((RandomGen() <= acceptProb) || (prophead.Age >= MaxAge || lastbead.Age >= MaxAge))
338  {
340  if (curhead.Age >= MaxAge || lastbead.Age >= MaxAge)
341  app_log() << "\tForce Acceptance...\n";
342 
343  prophead.Properties(WP::LOCALENERGY) = eloc;
344  prophead.Properties(WP::R2ACCEPTED) = rr_accepted;
345  prophead.Properties(WP::R2PROPOSED) = rr_proposed;
346  H.auxHevaluate(W, prophead, true, false); //evaluate properties? true. collectables? false.
347  H.saveProperty(prophead.getPropertyBase());
348  prophead.Age = 0;
349  overwriteWalker = prophead;
350  ++nAccept;
351  }
352  else
353  {
354  ++nReject;
355  H.rejectedMove(W, prophead);
356  curhead.Properties(WP::R2ACCEPTED) = 0;
357  curhead.Properties(WP::R2PROPOSED) = rr_proposed;
358  curhead.Age += 1;
359  W.reptile->flip();
360  // return;
361  }
362  //Collectables should be evaluated on center bead. Here we go.
363  Walker_t& centerbead = W.reptile->getCenter();
364  W.loadWalker(centerbead, true);
365  W.update(); //Called to recompute S(k) and distance tables.
366  H.auxHevaluate(W, centerbead, false, true); //evaluate properties? false. Collectables? true.
367 }
368 
369 void RMCUpdatePbyPWithDrift::advanceWalker(Walker_t& thisWalker, bool recompute)
370 {
371  //empty function to
372 }
373 
375 {
376  if (init == true)
378  else
380 }
381 
383 
384 } // namespace qmcplusplus
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
Fixed-size array.
Definition: OhmmsTinyMeta.h:30
PropertyContainer_t Properties
scalar properties of a walker
Definition: Walker.h:125
Base class for update methods for each step.
Definition: QMCUpdateBase.h:41
void rejectMove(int iat)
restore to the original state
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
void accumulate(MCWalkerConfiguration &W)
accumulate the measurements
Walker_t & getTail()
Definition: Reptile.h:98
QTBase::RealType RealType
Definition: Configuration.h:58
TrialWaveFunction & Psi
trial function
void acceptMove(ParticleSet &P, int iat, bool safe_to_delay=false)
update the state with the new data
std::ostream & app_log()
Definition: OutputManager.h:65
void saveProperty(IT first)
save the values of Hamiltonian elements to the Properties
bool phaseChanged(RealType psi0) const
virtual bool put(xmlNodePtr cur)
process options
RealType DMCLinkAction(RealType enew, RealType eold) const
Collection of Local Energy Operators.
Walker_t & getNewHead()
Definition: Reptile.h:128
void allocate()
allocate the data
Definition: PooledMemory.h:104
int first(int igroup) const
return the first index of a group i
Definition: ParticleSet.h:514
void accumulate(WalkerIter_t it, WalkerIter_t it_end)
void update(bool skipSK=false)
update the internal data
Walker_t & getCenter()
Definition: Reptile.h:100
ParticleSet::ParticlePos deltaR
temporary storage for random displacement
ParticleLaplacian L
laplacians of the particles
Definition: ParticleSet.h:85
RealType updateBuffer(ParticleSet &P, WFBufferType &buf, bool fromscratch=false)
update all the wavefunction components in buffer.
int Age
Age of this walker age is incremented when a walker is not moved after a sweep.
Definition: Walker.h:100
T min(T a, T b)
bool put(std::istream &is) override
read from std::istream
Definition: ParameterSet.h:42
IndexType nNodeCrossing
Total number of node crossings per block.
Definition: QMCUpdateBase.h:69
int groups() const
return the number of groups
Definition: ParticleSet.h:511
omp_int_t omp_get_thread_num()
Definition: OpenMP.h:25
const PosType & getActivePos() const
Definition: ParticleSet.h:261
class to handle a set of parameters
Definition: ParameterSet.h:27
double norm(const zVec &c)
Definition: VectorOps.h:118
WalkerProperties::Indexes WP
Definition: ParticleSet.cpp:34
QTBase::ValueType ValueType
Definition: Configuration.h:60
EstimatorManagerBase * Estimators
estimator
RMCUpdatePbyPWithDrift(MCWalkerConfiguration &w, TrialWaveFunction &psi, QMCHamiltonian &h, RandomBase< FullPrecRealType > &rg, std::vector< int > act, std::vector< int > tp)
Constructor.
ParticleGradient G
gradients of the particles
Definition: ParticleSet.h:83
void saveWalker(Walker_t &awalker)
save this to awalker
NewTimer & createGlobalTimer(const std::string &myname, timer_levels mylevel)
RealType Tau
timestep
Definition: QMCUpdateBase.h:73
void accept_rejectMove(Index_t iat, bool accepted, bool forward_mode=true)
accept or reject a proposed move Two operation modes: The using and updating distance tables via Part...
void registerData(ParticleSet &P, WFBufferType &buf)
register all the wavefunction components in buffer.
ParticlePos R
Position.
Definition: ParticleSet.h:79
int last(int igroup) const
return the last index of a group i
Definition: ParticleSet.h:517
MakeReturn< UnaryNode< FnExp, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t exp(const Vector< T1, C1 > &l)
Walker_t & getNext()
Definition: Reptile.h:99
MCWalkerConfiguration & W
walker ensemble
OHMMS_INDEXTYPE IndexType
define other types
Definition: Configuration.h:65
void advanceWalker(Walker_t &thisWalker, bool recompute) override
move a walker
void loadWalker(Walker_t &awalker, bool pbyp)
load a Walker_t to the current ParticleSet
void auxHevaluate(ParticleSet &P)
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)
void rejectedMove(ParticleSet &P, Walker_t &ThisWalker)
Looks like a hack see DMCBatched.cpp and DMC.cpp weight is used like temporary flag from DMC...
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
GradType evalGrad(ParticleSet &P, int iat)
Indexes
an enum denoting index of physical properties
FullPrecRealType evaluate(ParticleSet &P)
evaluate Local Energy
FullPrecRealType Weight
Weight of the walker.
Definition: Walker.h:102
void initWalkers(WalkerIter_t it, WalkerIter_t it_end) override
initialize Walker for walker update
Walker_t & getHead()
Definition: Reptile.h:97
Tensor< typename BinaryReturn< T1, T2, OpMultiply >::Type_t, D > dot(const AntiSymTensor< T1, D > &lhs, const AntiSymTensor< T2, D > &rhs)
bool makeMoveAndCheck(Index_t iat, const SingleParticlePos &displ)
move the iat-th particle to active_pos_
void initWalkersForPbyP(WalkerIter_t it, WalkerIter_t it_end) override
initialize Walker buffers for PbyP update
IndexType nAccept
counter for number of moves accepted
Definition: QMCUpdateBase.h:63
bool put(xmlNodePtr cur) override
process options
IndexType nReject
counter for number of moves rejected
Definition: QMCUpdateBase.h:65
FullPrecRealType * getPropertyBase()
Definition: Walker.h:277
void clear()
clear the data and set Current=0
Definition: PooledMemory.h:92
virtual void getDrift(RealType tau, const GradType &qf, PosType &drift) const =0
evaluate a drift with a real force
std::vector< RealType > MassInvS
1/Mass per species
void rewind(size_type cur=0, size_type cur_scalar=0)
set the cursors
Definition: PooledMemory.h:85
IndexType nbeads
Definition: Reptile.h:59
A container class to represent a walker.
Definition: Walker.h:49
QMCHamiltonian & H
Hamiltonian.
ValueType calcRatioGrad(ParticleSet &P, int iat, GradType &grad_iat)
compute psi(R_new) / psi(R_current) ratio and ln(psi(R_new)) gradients It returns a complex value if...
RealType m_r2max
maximum displacement^2
void donePbyP(bool skipSK=false)
update structure factor and unmark active_ptcl_
void resetProperty(FullPrecRealType logpsi, FullPrecRealType sigN, FullPrecRealType ene)
reset the property of a walker
Definition: Walker.h:296
void completeUpdates()
complete all the delayed or asynchronous operations before leaving the p-by-p move region...
void advanceWalkers(WalkerIter_t it, WalkerIter_t it_end, bool measure) override
advance walkers executed at each step
ParticleLaplacian L
^2_i d for the i-th particle
Definition: Walker.h:122
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
bool UpdatePbyP
update particle-by-particle
const DriftModifierBase * DriftModifier
drift modifer, stateless reference to the one in QMCDriver
void makeGaussRandomWithEngine(ParticleAttrib< TinyVector< T, D >> &a, RG &rng)