Bridge++  Version 1.4.4
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
hmc_Leapfrog.cpp
Go to the documentation of this file.
1 
14 #include "hmc_Leapfrog.h"
15 
16 
17 
18 const std::string HMC_Leapfrog::class_name = "HMC_Leapfrog";
19 
20 //====================================================================
22 HMC_Leapfrog::HMC_Leapfrog(std::vector<Action *> action,
23  RandomNumbers *rand)
24  : m_vl(CommonParameters::Vlevel())
25 {
26  m_action.resize(action.size());
27  for (int i = 0; i < action.size(); ++i) {
28  m_action[i] = action[i];
29  }
30  m_staple = new Staple_lex;
31  m_rand = rand;
32  m_Estep = 0.0;
33  m_Nmdc = 0;
34  m_Nprec = 0;
37 }
38 
39 
40 //====================================================================
41 HMC_Leapfrog::HMC_Leapfrog(std::vector<Action *> action,
43  : m_vl(CommonParameters::Vlevel())
44 {
45  m_action.resize(action.size());
46  for (int i = 0; i < action.size(); ++i) {
47  m_action[i] = action[i];
48  }
49  m_staple = new Staple_lex;
50  m_rand = rand.get();
51  m_Estep = 0.0;
52  m_Nmdc = 0;
53  m_Nprec = 0;
56 }
57 
58 
59 //====================================================================
61 HMC_Leapfrog::HMC_Leapfrog(std::vector<Action *> action,
62  std::vector<Director *> director,
63  RandomNumbers *rand)
64  : m_vl(CommonParameters::Vlevel())
65 {
66  m_action.resize(action.size());
67  for (int i = 0; i < action.size(); ++i) {
68  m_action[i] = action[i];
69  }
70  m_director.resize(director.size());
71  for (int i = 0; i < director.size(); ++i) {
72  m_director[i] = director[i];
73  }
74  m_staple = new Staple_lex;
75  m_rand = rand;
76  m_Estep = 0.0;
77  m_Nmdc = 0;
78  m_Nprec = 0;
81 }
82 
83 
84 //====================================================================
85 HMC_Leapfrog::HMC_Leapfrog(std::vector<Action *> action,
86  std::vector<Director *> director,
88  : m_vl(CommonParameters::Vlevel())
89 {
90  m_action.resize(action.size());
91  for (int i = 0; i < action.size(); ++i) {
92  m_action[i] = action[i];
93  }
94  m_director.resize(director.size());
95  for (int i = 0; i < director.size(); ++i) {
96  m_director[i] = director[i];
97  }
98  m_staple = new Staple_lex;
99  m_rand = rand.get();
100  m_Estep = 0.0;
101  m_Nmdc = 0;
102  m_Nprec = 0;
103  m_Metropolis_test = 0;
105 }
106 
107 
108 //====================================================================
111  RandomNumbers *rand)
112  : m_vl(CommonParameters::Vlevel())
113 {
114  ActionSet action_set = action_list.get_actions();
115 
116  m_action.resize(action_set.size());
117  for (int i = 0; i < action_set.size(); ++i) {
118  m_action[i] = action_set[i];
119  }
120  m_staple = new Staple_lex;
121  m_rand = rand;
122  m_Estep = 0.0;
123  m_Nmdc = 0;
124  m_Nprec = 0;
125  m_Metropolis_test = 0;
127 }
128 
129 
130 //====================================================================
133  : m_vl(CommonParameters::Vlevel())
134 {
135  ActionSet action_set = action_list.get_actions();
136 
137  m_action.resize(action_set.size());
138  for (int i = 0; i < action_set.size(); ++i) {
139  m_action[i] = action_set[i];
140  }
141  m_staple = new Staple_lex;
142  m_rand = rand.get();
143  m_Estep = 0.0;
144  m_Nmdc = 0;
145  m_Nprec = 0;
146  m_Metropolis_test = 0;
148 }
149 
150 
151 //====================================================================
154  std::vector<Director *> director,
155  RandomNumbers *rand)
156  : m_vl(CommonParameters::Vlevel())
157 {
158  ActionSet action_set = action_list.get_actions();
159 
160  m_action.resize(action_set.size());
161  for (int i = 0; i < action_set.size(); ++i) {
162  m_action[i] = action_set[i];
163  }
164  m_director.resize(director.size());
165  for (int i = 0; i < director.size(); ++i) {
166  m_director[i] = director[i];
167  }
168  m_staple = new Staple_lex;
169  m_rand = rand;
170  m_Estep = 0.0;
171  m_Nmdc = 0;
172  m_Nprec = 0;
173  m_Metropolis_test = 0;
175 }
176 
177 
178 //====================================================================
180  std::vector<Director *> director,
182  : m_vl(CommonParameters::Vlevel())
183 {
184  ActionSet action_set = action_list.get_actions();
185 
186  m_action.resize(action_set.size());
187  for (int i = 0; i < action_set.size(); ++i) {
188  m_action[i] = action_set[i];
189  }
190  m_director.resize(director.size());
191  for (int i = 0; i < director.size(); ++i) {
192  m_director[i] = director[i];
193  }
194  m_staple = new Staple_lex;
195  m_rand = rand.get();
196  m_Estep = 0.0;
197  m_Nmdc = 0;
198  m_Nprec = 0;
199  m_Metropolis_test = 0;
201 }
202 
203 
204 //====================================================================
207 {
208  delete m_staple;
209  delete m_Langevin_P;
210 }
211 
212 
213 //====================================================================
215 {
216  const string str_vlevel = params.get_string("verbose_level");
217 
218  m_vl = vout.set_verbose_level(str_vlevel);
219 
220  //- fetch and check input parameters
221  double Estep;
222  int Nmdc, Nprec, Metropolis_test;
223 
224  int err = 0;
225  err += params.fetch_double("step_size", Estep);
226  err += params.fetch_int("number_of_steps", Nmdc);
227  err += params.fetch_int("order_of_exp_iP", Nprec);
228  err += params.fetch_int("Metropolis_test", Metropolis_test);
229 
230  if (err) {
231  vout.crucial(m_vl, "Error at %s: input parameter not found.\n", class_name.c_str());
232  exit(EXIT_FAILURE);
233  }
234 
235 
236  set_parameters(Estep, Nmdc, Nprec, Metropolis_test);
237 }
238 
239 
240 //====================================================================
241 void HMC_Leapfrog::set_parameters(double Estep, int Nmdc, int Nprec, int Metropolis_test)
242 {
243  //- print input parameters
244  vout.general(m_vl, "%s:\n", class_name.c_str());
245  vout.general(m_vl, " Number of actions: %d\n", m_action.size());
246  vout.general(m_vl, " Estep = %10.6f\n", Estep);
247  vout.general(m_vl, " Nmdc = %d\n", Nmdc);
248  vout.general(m_vl, " Nprec = %d\n", Nprec);
249  vout.general(m_vl, " Metropolis_test = %d\n", Metropolis_test);
250 
251  //- range check
252  // NB. Estep,Nmdc,Nprec,Metropolis_test == 0 is allowed.
253 
254  //- store values
255  m_Estep = Estep; // step size (SA)
256  m_Nmdc = Nmdc; // a number of steps (SA)
257  m_Nprec = Nprec; // order of approximation for e^{iP} (SA)
258  m_Metropolis_test = Metropolis_test; // Metropolis test on/off (SA)
259 }
260 
261 
262 //====================================================================
264 {
265  int Nc = CommonParameters::Nc(); //color (SA)
266  int Lvol = CommonParameters::Lvol(); // global volume (SA)
267 
268  Field_G U(Uorg); // set original gauge conf. to U (SA)
269 
270  for (int i = 0; i < m_action.size(); ++i) {
271  m_action[i]->set_config(&U); // set gauge conf. for each action (SA)
272  }
273 
274  int Nin = U.nin(); // 2x(complex) 3(color) x 3(color) part (SA)
275  int Nvol = U.nvol(); // local volume (SA)
276  int Nex = U.nex(); // direction mu (SA)
277 
278  Field_G iP(Nvol, Nex); // define momentum iP for gauge fields (SA)
279 
280 
281  vout.general(m_vl, "HMC (single leapfrog) start.\n");
282 
283  //- Langevin step
284  double H_total0 = langevin(iP, U); // calculate initial hamiltonian (SA)
285  // H=p^2/s + S_G + all fermion contributions (SA)
286  vout.general(m_vl, " H_total(init) = %18.8f\n", H_total0);
287 
288  double plaq0 = m_staple->plaquette(U); // calculate plaquette of old U (SA)
289  vout.general(m_vl, " plaq(init) = %18.8f\n", plaq0);
290 
291  //- initial Hamiltonian
292  // H_total0 = calc_Hamiltonian(iP,U);
293 
294  //- molecular dynamical integration
295  integrate(iP, U); // MD step (SA)
296 
297  //- trial Hamiltonian
298  double H_total1 = calc_Hamiltonian(iP, U); // calculate final hamiltonian (SA)
299  vout.general(m_vl, " H_total(trial) = %18.8f\n", H_total1);
300 
301  double plaq1 = m_staple->plaquette(U); // calculate plaquette of new U (SA)
302  vout.general(m_vl, " plaq(trial) = %18.8f\n", plaq1);
303 
304 
305  //- Metropolis test
306  vout.general(m_vl, "Metropolis test.\n");
307 
308  double diff_H = H_total1 - H_total0; // Delta H (SA)
309  double exp_minus_diff_H = exp(-diff_H); // e^{-Delta H} (SA)
310  double rand = -1.0;
311  if (m_Metropolis_test != 0) {
312  rand = m_rand->get(); // random number 0 <= rand < 1 (SA)
313  }
314  vout.general(m_vl, " H(diff) = %10.6f\n", diff_H);
315  vout.general(m_vl, " exp(-diff_H) = %10.6f\n", exp_minus_diff_H);
316  vout.general(m_vl, " Random number = %10.6f\n", rand);
317 
318  if (rand <= exp_minus_diff_H) { // accepted
319  vout.general(m_vl, " Accepted\n");
320  Uorg = U; // set new U to gauge conf. (SA)
321  } else { // rejected
322  vout.general(m_vl, " Rejected\n");
323  }
324 
325 
326  double plaq_final = m_staple->plaquette(Uorg);
327  vout.general(m_vl, " plaq(final) = %18.8f\n", plaq_final);
328 
329  return plaq_final;
330 }
331 
332 
333 //====================================================================
335 {
336  int Nc = CommonParameters::Nc();
337  int Lvol = CommonParameters::Lvol(); //global volume (SA)
338  int Ndim = CommonParameters::Ndim();
339  int NcA = Nc * Nc - 1; // Nc^2-1 (SA)
340 
341  int size_iP = NcA * Lvol * Ndim; // global size of momentum iP (SA)
342 
343  vout.general(m_vl, "Langevin step.\n");
344 
345  // discard caches
346  for (int i = 0; i < m_director.size(); ++i) {
347  m_director[i]->notify_linkv(); // tell director that gauge filed is modified.(SA)
348  }
349 
350  //- kinetic term
351  double H_iP = m_Langevin_P->set_iP(iP);
352  // calculate hamiltonian of momenta iP. (SA)
353  vout.general(m_vl, " H_kin = %18.8f\n", H_iP);
354  vout.general(m_vl, " H_kin/dof = %18.8f\n", H_iP / size_iP);
355 
356 
357  double H_actions = 0.0;
358  for (int i = 0; i < m_action.size(); ++i) {
359  H_actions += m_action[i]->langevin(m_rand);
360  // calculate contribution to hamiltonian from each action. (SA)
361  }
362 
363  double H_total = H_iP + H_actions; // total hamiltonian. (SA)
364  return H_total;
365 }
366 
367 
368 //====================================================================
370 {
371  int Nin = U.nin(); // Local volume (SA)
372  int Nvol = U.nvol();
373  int Nex = U.nex();
374 
375  int Nc = CommonParameters::Nc();
376  int Nd = CommonParameters::Nd();
377  int Lvol = CommonParameters::Lvol(); //Global volume (SA)
378  int NcA = Nc * Nc - 1;
379 
380  int size_iP = NcA * Lvol * Nex; // Global size of iP (SA)
381 
382  // int size_U = Lvol * 6.0; // Global size of U (SA)
383  // int size_psf = Lvol * Nc * Nd; // Global size of pseudo-fermion (SA)
384 
385 
386  vout.general(m_vl, "Hamiltonian calculation.\n");
387 
388  // kinetic term
389  double H_iP = calcH_P(iP); // calculate hamiltonian for iP (SA)
390  vout.general(m_vl, " H_kin = %18.8f\n", H_iP);
391  vout.general(m_vl, " H_kin/dof = %18.8f\n", H_iP / size_iP);
392 
393  double H_actions = 0.0;
394  for (int i = 0; i < m_action.size(); ++i) {
395  // calculate contribution to hamiltonian from each action (SA)
396  H_actions += m_action[i]->calcH();
397  }
398 
399  double H_total = H_iP + H_actions;
400  return H_total;
401 }
402 
403 
404 //====================================================================
406 {
407  //calculate hamiltonian for iP: |iP|^2/2 (SA)
408  double hn = iP.norm();
409  double H_iP = 0.5 * hn * hn;
410 
411  return H_iP;
412 }
413 
414 
415 //====================================================================
417 {
418  vout.general(m_vl, "Integration.\n");
419 
420  double estep = m_Estep;
421  double estep2 = 0.5 * m_Estep;
422 
423  // Initial half step of update of h
424  if (m_Nmdc > 0) {
425  int imdc = 0;
426  vout.general(m_vl, " imdc = %d\n", imdc);
427  update_P(estep2, iP, U); // update momentum iP at first half step (SA)
428  }
429 
430  // Molecular dynamics step
431  for (int imdc = 1; imdc < m_Nmdc + 1; imdc++) {
432  vout.general(m_vl, " imdc = %d\n", imdc);
433 
434  update_U(estep, iP, U); // update gauge field U at full step (SA)
435 
436  if (imdc < m_Nmdc) {
437  update_P(estep, iP, U); // update momentum iP at full step (SA)
438  } else {
439  update_P(estep2, iP, U); // update momentum iP at last half step (SA)
440  }
441  } // here imdc loop ends
442 }
443 
444 
445 //====================================================================
446 void HMC_Leapfrog::update_P(double estep, Field_G& iP, Field_G& U)
447 {
448  int Nin = U.nin();
449  int Nvol = U.nvol();
450  int Nex = U.nex();
451  int Nc = CommonParameters::Nc();
452 
453  Field force(Nin, Nvol, Nex);
454 
455  force.set(0.0);
456 
457  Field force1(Nin, Nvol, Nex);
458  // double H_actions = 0.0;
459  for (int i = 0; i < m_action.size(); ++i) {
460  m_action[i]->force(force1); // calculate force for each action (SA)
461  axpy(force, estep, force1);
462  }
463 
464  // iP = iP + step-size * force (SA)
465  axpy(iP, 1.0, force);
466 }
467 
468 
469 //====================================================================
470 void HMC_Leapfrog::update_U(double estep, Field_G& iP, Field_G& U)
471 {
472  int Nvol = U.nvol();
473  int Nex = U.nex();
474  int Nc = CommonParameters::Nc();
475 
476  Mat_SU_N u0(Nc), u1(Nc), u2(Nc);
477  Mat_SU_N h1(Nc);
478 
479  for (int ex = 0; ex < Nex; ++ex) {
480  for (int site = 0; site < Nvol; ++site) {
481  u0 = U.mat(site, ex);
482  u1 = U.mat(site, ex);
483  h1 = iP.mat(site, ex);
484 
485  for (int iprec = 0; iprec < m_Nprec; ++iprec) {
486  double exf = estep / (m_Nprec - iprec); // step_size/(N-k) (SA)
487  u2 = h1 * u1; // iP* u1 (SA)
488  u2 *= exf; // step_size*iP*u1/(N-K) (SA)
489  u1 = u2;
490  u1 += u0; // U + step_size*iP*u1/(N-K) (SA)
491  }
492  // u1 =sum_{k=0}^{N-1} (step_size * iP)^k/k!, N=m_Nprec (SA)
493  u1.reunit(); // reunitarize u1 (SA)
494  U.set_mat(site, ex, u1); // U = u1 (SA)
495  }
496  }
497 
498  for (int i = 0; i < m_director.size(); ++i) {
499  m_director[i]->notify_linkv(); // notify all directors about update of U (SA)
500  }
501 }
502 
503 
504 //====================================================================
505 //============================================================END=====
BridgeIO vout
Definition: bridgeIO.cpp:495
virtual double get()=0
void set_parameters(const Parameters &params)
void set(const int jin, const int site, const int jex, double v)
Definition: field.h:164
double m_Estep
Definition: hmc_Leapfrog.h:53
void general(const char *format,...)
Definition: bridgeIO.cpp:195
Container of Field-type object.
Definition: field.h:39
int fetch_double(const string &key, double &value) const
Definition: parameters.cpp:211
double plaquette(const Field_G &)
calculates plaquette value.
Definition: staple_lex.cpp:46
static const std::string class_name
Definition: hmc_Leapfrog.h:47
int m_Metropolis_test
Definition: hmc_Leapfrog.h:52
int nvol() const
Definition: field.h:116
double set_iP(Field_G &iP)
Setting conjugate momenta and returns kinetic part of Hamiltonian.
Class for parameters.
Definition: parameters.h:46
RandomNumbers * m_rand
Definition: hmc_Leapfrog.h:60
static int Lvol()
Langevin_Momentum * m_Langevin_P
Definition: hmc_Leapfrog.h:55
void update_P(double estep, Field_G &iP, Field_G &U)
Mat_SU_N & reunit()
Definition: mat_SU_N.h:71
Bridge::VerboseLevel m_vl
Definition: hmc_Leapfrog.h:61
std::vector< Action * > m_action
Definition: hmc_Leapfrog.h:58
int nin() const
Definition: field.h:115
ActionSet get_actions() const
Definition: action_list.cpp:80
Staple construction.
Definition: staple_lex.h:39
SU(N) gauge field.
Definition: field_G.h:38
int fetch_int(const string &key, int &value) const
Definition: parameters.cpp:230
void integrate(Field_G &iP, Field_G &U)
double norm() const
Definition: field.h:211
double update(Field_G &)
void update_U(double estep, Field_G &iP, Field_G &U)
pointer get() const
int nex() const
Definition: field.h:117
Common parameter class: provides parameters as singleton.
double langevin(Field_G &iP, Field_G &U)
Staple_lex * m_staple
Definition: hmc_Leapfrog.h:56
void axpy(Field &y, const double a, const Field &x)
axpy(y, a, x): y := a * x + y
Definition: field.cpp:168
double calcH_P(Field_G &iP)
void crucial(const char *format,...)
Definition: bridgeIO.cpp:178
std::vector< Director * > m_director
Definition: hmc_Leapfrog.h:59
lists of actions at respective integrator levels.
Definition: action_list.h:40
Base class of random number generators.
Definition: randomNumbers.h:36
~HMC_Leapfrog()
destructor
string get_string(const string &key) const
Definition: parameters.cpp:116
void set_mat(const int site, const int mn, const Mat_SU_N &U)
Definition: field_G.h:159
std::vector< Action * > ActionSet
Definition: action_list.h:38
Mat_SU_N mat(const int site, const int mn=0) const
Definition: field_G.h:113
double calc_Hamiltonian(Field_G &iP, Field_G &U)
static VerboseLevel set_verbose_level(const std::string &str)
Definition: bridgeIO.cpp:131
HMC_Leapfrog(std::vector< Action * > action, RandomNumbers *rand)
constructor: with array of actions
Langevin part of HMC for conjugate momentum to link variable.