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