QMCPACK
CSUpdateBase.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: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
8 // Jeremy McMinnis, jmcminis@gmail.com, University of Illinois at Urbana-Champaign
9 // Raymond Clay III, j.k.rofling@gmail.com, Lawrence Livermore National Laboratory
10 // Mark A. Berrill, berrillma@ornl.gov, Oak Ridge National Laboratory
11 //
12 // File created by: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
13 //////////////////////////////////////////////////////////////////////////////////////
14 
15 
16 #include "CSUpdateBase.h"
17 #include "MemoryUsage.h"
22 #include <numeric>
23 
24 namespace qmcplusplus
25 {
26 
28 
30  std::vector<TrialWaveFunction*>& psipool,
31  std::vector<QMCHamiltonian*>& hpool,
33  : QMCUpdateBase(w, *psipool[0], *hpool[0], rg), nPsi(0), useDriftOption("no"), H1(hpool), Psi1(psipool)
34 {
35  myParams.add(useDriftOption, "useDrift");
36 }
37 
39 {
40  delete_iter(G1.begin(), G1.end());
41  delete_iter(L1.begin(), L1.end());
42 }
43 
44 void CSUpdateBase::resizeWorkSpace(int nw, int nptcls)
45 {
46  if (logpsi.size())
47  return;
48  logpsi.resize(nPsi);
49  ratio.resize(nPsi);
50  sumratio.resize(nPsi);
51  invsumratio.resize(nPsi);
52  avgNorm.resize(nPsi, 1.0);
53  logNorm.resize(nPsi, 0.0);
54  cumNorm.resize(nPsi, 0.0);
55  avgWeight.resize(nPsi, 1.0);
56  instRij.resize(nPsi * (nPsi - 1) / 2);
57  ratioIJ.resize(nw, nPsi * (nPsi - 1) / 2);
59  dG.resize(nptcls);
60 
61  g1_new.resize(nPsi);
62  g1_old.resize(nPsi);
63 
64  for (int ipsi = 0; ipsi < nPsi; ipsi++)
65  {
66  Psi1[ipsi]->G.resize(nptcls);
67  Psi1[ipsi]->L.resize(nptcls);
68  G1.push_back(new ParticleSet::ParticleGradient(nptcls));
69  L1.push_back(new ParticleSet::ParticleLaplacian(nptcls));
70  }
71 }
72 
74 {
75  //for(int ipsi=0; ipsi< nPsi; ipsi++)
76  // cumNorm[ipsi]+=multiEstimator->getUmbrellaWeight(ipsi);
77  //if(block==(equilBlocks-1) || block==(nBlocks-1)){
78  // app_log()<<"Inside UpdateNorm\n";
79  RealType winv = 1.0 / double(std::accumulate(cumNorm.begin(), cumNorm.end(), 0.0));
80  for (int ipsi = 0; ipsi < nPsi; ipsi++)
81  {
82  avgNorm[ipsi] = cumNorm[ipsi] * winv;
83  // avgNorm[ipsi]=0.5;
84  logNorm[ipsi] = std::log(avgNorm[ipsi]);
85  // app_log()<<ipsi<<" "<<avgNorm[ipsi]<<" "<<logNorm[ipsi]<<" "<<winv<< std::endl;
86  cumNorm[ipsi] = 0;
87  }
88 
89  //}
90 }
92 {
93  RealType winv = 1.0 / double(std::accumulate(cumNorm.begin(), cumNorm.end(), 0.0));
94  for (int ipsi = 0; ipsi < nPsi; ipsi++)
95  {
96  avgWeight[ipsi] = cumNorm[ipsi] * winv;
97  // app_log()<<ipsi<<" "<<avgWeight[ipsi]<< std::endl;
98  // avgNorm[ipsi]=0.5;
99  cumNorm[ipsi] = 0;
100  }
101 }
102 
103 void CSUpdateBase::computeSumRatio(const std::vector<RealType>& lpsi,
104  const std::vector<RealType>& avnorm,
105  std::vector<RealType>& sumrat)
106 {
107  for (int ipsi = 0; ipsi < nPsi; ipsi++)
108  sumrat[ipsi] = 1.0;
109 
110  for (int ipsi = 0; ipsi < nPsi - 1; ipsi++)
111  {
112  for (int jpsi = ipsi + 1; jpsi < nPsi; jpsi++)
113  {
114  RealType ratioij = avnorm[ipsi] / avnorm[jpsi] * std::exp(2.0 * (lpsi[jpsi] - lpsi[ipsi]));
115  sumrat[ipsi] += ratioij;
116  sumrat[jpsi] += 1.0 / ratioij;
117  }
118  }
119 }
120 
121 //This function assumes logpsi and avgnorm are available. it returns
122 //ratioij and sumratio.
123 void CSUpdateBase::computeSumRatio(const std::vector<RealType>& lpsi,
124  const std::vector<RealType>& avnorm,
125  Matrix<RealType>& Ratioij,
126  std::vector<RealType>& sumrat)
127 {
128  for (int ipsi = 0; ipsi < nPsi; ipsi++)
129  {
130  sumrat[ipsi] = 1.0;
131  Ratioij[ipsi][ipsi] = 1.0;
132  }
133 
134  for (int ipsi = 0; ipsi < nPsi - 1; ipsi++)
135  {
136  for (int jpsi = ipsi + 1; jpsi < nPsi; jpsi++)
137  {
138  Ratioij[ipsi][jpsi] = avnorm[ipsi] / avnorm[jpsi] * std::exp(2.0 * (lpsi[jpsi] - lpsi[ipsi]));
139  Ratioij[jpsi][ipsi] = 1.0 / Ratioij[ipsi][jpsi];
140  sumrat[ipsi] += Ratioij[ipsi][jpsi];
141  sumrat[jpsi] += Ratioij[jpsi][ipsi];
142  }
143  }
144 }
145 
146 //This function assumes that Ratioij has been given, then computes sumratio.
147 void CSUpdateBase::computeSumRatio(const Matrix<RealType>& Ratioij, std::vector<RealType>& sumrat)
148 {
149  for (int ipsi = 0; ipsi < nPsi; ipsi++)
150  sumrat[ipsi] = 1.0;
151 
152  for (int ipsi = 0; ipsi < nPsi - 1; ipsi++)
153  {
154  for (int jpsi = ipsi + 1; jpsi < nPsi; jpsi++)
155  {
156  sumrat[ipsi] += Ratioij[ipsi][jpsi];
157  sumrat[jpsi] += Ratioij[jpsi][ipsi];
158  }
159  }
160 }
161 
162 //this function takes a matrix containing |psi_i(r)/psi_j(r)|^2, and a vector
163 //containing |\psi_i(r')/\psi_i(r)|^2 to yield |psi_i(r')/psi_j(r')|^2
164 void CSUpdateBase::updateRatioMatrix(const std::vector<RealType>& ratio_i, Matrix<RealType>& Ratioij)
165 {
166  for (int ipsi = 0; ipsi < nPsi; ipsi++)
167  Ratioij[ipsi][ipsi] = 1.0;
168 
169  for (int ipsi = 0; ipsi < nPsi - 1; ipsi++)
170  {
171  for (int jpsi = ipsi + 1; jpsi < nPsi; jpsi++)
172  {
173  Ratioij[ipsi][jpsi] = Ratioij[ipsi][jpsi] * ratio_i[jpsi] / ratio_i[ipsi];
174  Ratioij[jpsi][ipsi] = 1.0 / Ratioij[ipsi][jpsi];
175  }
176  }
177 }
178 
179 
180 void CSUpdateBase::initCSWalkers(WalkerIter_t it, WalkerIter_t it_end, bool resetNorms)
181 {
182  nPsi = Psi1.size();
183  useDrift = (useDriftOption == "yes");
184  if (nPsi == 0)
185  {
186  app_error() << " CSUpdateBase::initCSWalkers fails. Empyty Psi/H pairs" << std::endl;
187  abort(); //FIX_ABORT
188  }
189  int nw = it_end - it; //W.getActiveWalkers();
191  if (resetNorms)
192  logNorm.resize(nPsi, 0.0);
193  for (int ipsi = 0; ipsi < nPsi; ipsi++)
194  avgNorm[ipsi] = std::exp(logNorm[ipsi]);
195  int iw(0);
196  while (it != it_end)
197  {
198  Walker_t& thisWalker(**it);
199  W.R = thisWalker.R;
200 
201  W.update();
202  //evalaute the wavefunction and hamiltonian
203  for (int ipsi = 0; ipsi < nPsi; ipsi++)
204  {
205  logpsi[ipsi] = Psi1[ipsi]->evaluateLog(W);
206  Psi1[ipsi]->G = W.G;
207  thisWalker.Properties(ipsi, WP::LOGPSI) = logpsi[ipsi];
208  RealType e = thisWalker.Properties(ipsi, WP::LOCALENERGY) = H1[ipsi]->evaluate(W);
209  H1[ipsi]->saveProperty(thisWalker.getPropertyBase(ipsi));
210  sumratio[ipsi] = 1.0;
211  }
212  //Check SIMONE's note
213  //Compute the sum over j of Psi^2[j]/Psi^2[i] for each i
214  int indexij(0);
215  RealType* restrict rPtr = ratioIJ[iw];
216  for (int ipsi = 0; ipsi < nPsi - 1; ipsi++)
217  {
218  for (int jpsi = ipsi + 1; jpsi < nPsi; jpsi++)
219  {
220  RealType r = std::exp(2.0 * (logpsi[jpsi] - logpsi[ipsi]));
221  rPtr[indexij++] = r * avgNorm[ipsi] / avgNorm[jpsi];
222  sumratio[ipsi] += r;
223  sumratio[jpsi] += 1.0 / r;
224  }
225  }
226  //Re-use Multiplicity as the sumratio
227  thisWalker.Multiplicity = sumratio[0];
228  for (int ipsi = 0; ipsi < nPsi; ipsi++)
229  {
230  thisWalker.Properties(ipsi, WP::UMBRELLAWEIGHT) = invsumratio[ipsi] = 1.0 / sumratio[ipsi];
231  cumNorm[ipsi] += 1.0 / sumratio[ipsi];
232  }
233  //DON't forget DRIFT!!!
234  /// thisWalker.Drift=0.0;
235  /// if(useDrift)
236  /// {
237  /// for(int ipsi=0; ipsi< nPsi; ipsi++)
238  /// PAOps<RealType,DIM>::axpy(invsumratio[ipsi],Psi1[ipsi]->G,thisWalker.Drift);
239  /// setScaledDrift(Tau,thisWalker.Drift);
240  /// }
241  ++it;
242  ++iw;
243  }
244 }
245 
247 {
248  UpdatePbyP = true;
249  nPsi = Psi1.size();
250  int nw = it_end - it;
251  int iw(0);
253  //ratio is for temporary holding of psi_i(...r'...)/psi_i(...r...).
254  ratio.resize(nPsi, 1.0);
255 
256  if (resetNorms)
257  logNorm.resize(nPsi, 0.0);
258  for (int ipsi = 0; ipsi < nPsi; ipsi++)
259  avgNorm[ipsi] = std::exp(logNorm[ipsi]);
260 
261  for (; it != it_end; ++it)
262  {
263  Walker_t& awalker(**it);
264  W.R = awalker.R;
265  W.update(true);
266  //W.loadWalker(awalker,UpdatePbyP);
267  // if (awalker.MDataSet.size()!=nPsi)
268  // awalker.MultDataSet.resize(nPsi);
269 
270  awalker.DataSet.clear();
271  awalker.DataSet.rewind();
272  awalker.registerData();
273  for (int ipsi = 0; ipsi < nPsi; ipsi++)
274  {
275  Psi1[ipsi]->registerData(W, awalker.DataSet);
276  }
277  awalker.DataSet.allocate();
278  for (int ipsi = 0; ipsi < nPsi; ipsi++)
279  {
280  Psi1[ipsi]->copyFromBuffer(W, awalker.DataSet);
281  Psi1[ipsi]->evaluateLog(W);
282  logpsi[ipsi] = Psi1[ipsi]->updateBuffer(W, awalker.DataSet, false);
283  Psi1[ipsi]->G = W.G;
284  *G1[ipsi] = W.G;
285  Psi1[ipsi]->L = W.L;
286  *L1[ipsi] = W.L;
287 
288  awalker.Properties(ipsi, WP::LOGPSI) = logpsi[ipsi];
289  awalker.Properties(ipsi, WP::LOCALENERGY) = H1[ipsi]->evaluate(W);
290  H1[ipsi]->saveProperty(awalker.getPropertyBase(ipsi));
291  sumratio[ipsi] = 1.0;
292  }
293  awalker.G = W.G;
294  awalker.L = W.L;
295  // randomize(awalker);
296 
297  int indexij(0);
298  RealType* rPtr = ratioIJ[iw++];
299  for (int ipsi = 0; ipsi < nPsi - 1; ipsi++)
300  {
301  for (int jpsi = ipsi + 1; jpsi < nPsi; jpsi++, indexij++)
302  {
303  RealType r = std::exp(2.0 * (logpsi[jpsi] - logpsi[ipsi]));
304  //rPtr[indexij++]=r*avgNorm[ipsi]/avgNorm[jpsi];
305  rPtr[indexij] = r * avgNorm[ipsi] / avgNorm[jpsi];
306  sumratio[ipsi] += r;
307  sumratio[jpsi] += 1.0 / r;
308  }
309  }
310  //Re-use Multiplicity as the sumratio
311  awalker.Multiplicity = sumratio[0];
312  for (int ipsi = 0; ipsi < nPsi; ipsi++)
313  {
314  awalker.Properties(ipsi, WP::UMBRELLAWEIGHT) = invsumratio[ipsi] = 1.0 / sumratio[ipsi];
315  cumNorm[ipsi] += 1.0 / sumratio[ipsi];
316  }
317  }
318 #pragma omp master
319  print_mem("Memory Usage after the buffer registration", app_log());
320 }
321 
323 {
324  int iw = 0;
325  while (it != it_end)
326  {
327  Walker_t& thisWalker(**it);
328  Walker_t::WFBuffer_t& w_buffer((*it)->DataSet);
329  //app_log()<<"DAMN. YOU FOUND ME. (updateCSWalkers called)\n";
330  // w_buffer.rewind();
331  // W.updateBuffer(**it,w_buffer);
332  //evalaute the wavefunction and hamiltonian
333  for (int ipsi = 0; ipsi < nPsi; ipsi++)
334  {
335  //Need to modify the return value of WaveFunctionComponent::registerData
336  logpsi[ipsi] = Psi1[ipsi]->updateBuffer(W, (*it)->DataSet);
337  Psi1[ipsi]->G = W.G;
338  thisWalker.Properties(ipsi, WP::LOGPSI) = logpsi[ipsi];
339  thisWalker.Properties(ipsi, WP::LOCALENERGY) = H1[ipsi]->evaluate(W);
340  H1[ipsi]->saveProperty(thisWalker.getPropertyBase(ipsi));
341  sumratio[ipsi] = 1.0;
342  }
343  int indexij(0);
344  RealType* rPtr = ratioIJ[iw];
345  for (int ipsi = 0; ipsi < nPsi - 1; ipsi++)
346  {
347  for (int jpsi = ipsi + 1; jpsi < nPsi; jpsi++)
348  {
349  RealType r = std::exp(2.0 * (logpsi[jpsi] - logpsi[ipsi]));
350  rPtr[indexij++] = r * avgNorm[ipsi] / avgNorm[jpsi];
351  sumratio[ipsi] += r;
352  sumratio[jpsi] += 1.0 / r;
353  }
354  }
355  //Re-use Multiplicity as the sumratio
356  thisWalker.Multiplicity = sumratio[0];
357  for (int ipsi = 0; ipsi < nPsi; ipsi++)
358  {
359  thisWalker.Properties(ipsi, WP::UMBRELLAWEIGHT) = invsumratio[ipsi] = 1.0 / sumratio[ipsi];
360  }
361  //DON't forget DRIFT!!!
362  /// thisWalker.Drift=0.0;
363  /// if(useDrift)
364  /// {
365  /// for(int ipsi=0; ipsi< nPsi; ipsi++)
366  /// PAOps<RealType,DIM>::axpy(invsumratio[ipsi],Psi1[ipsi]->G,thisWalker.Drift);
367  /// setScaledDrift(Tau,thisWalker.Drift);
368  /// }
369  ++it;
370  ++iw;
371  }
372 }
373 
374 
375 } // namespace qmcplusplus
std::vector< RealType > logNorm
Definition: CSUpdateBase.h:44
void initCSWalkers(WalkerIter_t it, WalkerIter_t it_end, bool resetNorms)
std::vector< RealType > sumratio
Definition: CSUpdateBase.h:40
PropertyContainer_t Properties
scalar properties of a walker
Definition: Walker.h:125
Base class for update methods for each step.
Definition: QMCUpdateBase.h:41
std::vector< RealType > cumNorm
Definition: CSUpdateBase.h:45
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 delete_iter(IT first, IT last)
delete the pointers in [first,last)
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
void computeSumRatio(const std::vector< RealType > &logpsi, const std::vector< RealType > &avgNorm, std::vector< RealType > &sumratio)
CSUpdateBase(MCWalkerConfiguration &w, std::vector< TrialWaveFunction *> &psi, std::vector< QMCHamiltonian *> &h, RandomBase< FullPrecRealType > &rg)
size_t getTotalNum() const
Definition: ParticleSet.h:493
std::ostream & app_log()
Definition: OutputManager.h:65
void registerData()
Definition: Walker.h:369
std::ostream & app_error()
Definition: OutputManager.h:67
void updateRatioMatrix(const std::vector< RealType > &ratio_pbyp, Matrix< RealType > &ratioij)
void allocate()
allocate the data
Definition: PooledMemory.h:104
void resize(size_type n, size_type m)
Resize the container.
Definition: OhmmsMatrix.h:99
void update(bool skipSK=false)
update the internal data
Attaches a unit to a Vector for IO.
ParticleLaplacian L
laplacians of the particles
Definition: ParticleSet.h:85
Definition of CSVUpdateBase.
std::vector< RealType > avgWeight
Definition: CSUpdateBase.h:43
std::vector< TrialWaveFunction * > Psi1
a list of TrialWaveFunctions for multiple method
Definition: CSUpdateBase.h:57
void print_mem(const std::string &title, std::ostream &log)
Definition: MemoryUsage.cpp:30
void resizeWorkSpace(int nw, int nptcls)
std::vector< RealType > logpsi
Definition: CSUpdateBase.h:39
WalkerProperties::Indexes WP
Definition: ParticleSet.cpp:34
void updateCSWalkers(WalkerIter_t it, WalkerIter_t it_end)
std::vector< RealType > invsumratio
Definition: CSUpdateBase.h:41
ParticleGradient G
gradients of the particles
Definition: ParticleSet.h:83
ParticlePos R
Position.
Definition: ParticleSet.h:79
std::vector< ParticleSet::ParticleGradient * > G1
Definition: CSUpdateBase.h:59
Matrix< RealType > RatioIJ
Definition: CSUpdateBase.h:51
MakeReturn< UnaryNode< FnExp, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t exp(const Vector< T1, C1 > &l)
std::vector< GradType > g1_old
Definition: CSUpdateBase.h:63
void initCSWalkersForPbyP(WalkerIter_t it, WalkerIter_t it_end, bool resetNorms)
MCWalkerConfiguration & W
walker ensemble
std::vector< RealType > instRij
Definition: CSUpdateBase.h:46
MakeReturn< UnaryNode< FnLog, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t log(const Vector< T1, C1 > &l)
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>
std::vector< GradType > g1_new
Definition: CSUpdateBase.h:64
Indexes
an enum denoting index of physical properties
std::vector< RealType > ratio
Definition: CSUpdateBase.h:47
std::vector< RealType > avgNorm
Definition: CSUpdateBase.h:42
ParticleAttrib< QTFull::GradType > ParticleGradient
Definition: Configuration.h:95
std::vector< ParticleSet::ParticleLaplacian * > L1
Definition: CSUpdateBase.h:60
Matrix< RealType > ratioIJ
Definition: CSUpdateBase.h:48
FullPrecRealType * getPropertyBase()
Definition: Walker.h:277
ParticleSet::ParticleGradient dG
FullPrecRealType Multiplicity
Number of copies for branching When Multiplicity = 0, this walker will be destroyed.
Definition: Walker.h:106
void clear()
clear the data and set Current=0
Definition: PooledMemory.h:92
void rewind(size_type cur=0, size_type cur_scalar=0)
set the cursors
Definition: PooledMemory.h:85
A container class to represent a walker.
Definition: Walker.h:49
ParameterSet myParams
parameters
std::vector< QMCHamiltonian * > H1
a list of QMCHamiltonians for multiple method
Definition: CSUpdateBase.h:55
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
bool UpdatePbyP
update particle-by-particle