Bridge++  Ver. 1.2.x
 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 #ifdef USE_PARAMETERS_FACTORY
17 #include "parameters_factory.h"
18 #endif
19 
20 //- parameter entries
21 namespace {
22  void append_entry(Parameters& param)
23  {
24  param.Register_double("step_size", 0.0);
25  param.Register_int("number_of_steps", 0);
26  param.Register_int("order_of_exp_iP", 0);
27  param.Register_int("Metropolis_test", 0);
28 
29  param.Register_string("verbose_level", "NULL");
30  }
31 
32 
33 #ifdef USE_PARAMETERS_FACTORY
34  bool init_param = ParametersFactory::Register("HMC.Leapfrog", append_entry);
35 #endif
36 }
37 //- end
38 
39 //- parameters class
41 //- end
42 
43 const std::string HMC_Leapfrog::class_name = "HMC_Leapfrog";
44 
45 //====================================================================
47 {
48  const string str_vlevel = params.get_string("verbose_level");
49 
50  m_vl = vout.set_verbose_level(str_vlevel);
51 
52  //- fetch and check input parameters
53  double Estep;
54  int Nmdc, Nprec, Mtpl_test;
55 
56  int err = 0;
57  err += params.fetch_double("step_size", Estep);
58  err += params.fetch_int("number_of_steps", Nmdc);
59  err += params.fetch_int("order_of_exp_iP", Nprec);
60  err += params.fetch_int("Metropolis_test", Mtpl_test);
61 
62  if (err) {
63  vout.crucial(m_vl, "%s: fetch error, input parameter not found.\n", class_name.c_str());
64  abort();
65  }
66 
67 
68  set_parameters(Estep, Nmdc, Nprec, Mtpl_test);
69 }
70 
71 
72 //====================================================================
73 void HMC_Leapfrog::set_parameters(double Estep, int Nmdc, int Nprec, int Mtpl_test)
74 {
75  //- print input parameters
76  vout.general(m_vl, "Parameters of %s:\n", class_name.c_str());
77  vout.general(m_vl, " Number of actions: %d\n", m_action.size());
78  vout.general(m_vl, " Estep = %10.6f\n", Estep);
79  vout.general(m_vl, " Nmdc = %d\n", Nmdc);
80  vout.general(m_vl, " Nprec = %d\n", Nprec);
81  vout.general(m_vl, " Mtpl_test = %d\n", Mtpl_test);
82 
83  //- range check
84  // NB. Estep,Nmdc,Nprec,Mtpl_test == 0 is allowed.
85 
86  //- store values
87  m_Estep = Estep; // step size (SA)
88  m_Nmdc = Nmdc; // a number of steps (SA)
89  m_Nprec = Nprec; // order of approximation for e^{iP} (SA)
90  m_Mtpl_test = Mtpl_test; // Metropolis test on/off (SA)
91 }
92 
93 
94 //====================================================================
95 double HMC_Leapfrog::update(Field_G& conf_org)
96 {
97  int Nc = CommonParameters::Nc(); //color (SA)
98  int Lvol = CommonParameters::Lvol(); // global volume (SA)
99 
100  Field_G U(conf_org); // set original gauge conf. to U (SA)
101 
102  for (int i = 0; i < m_action.size(); ++i) {
103  m_action[i]->set_config(&U); // set gauge conf. for each action (SA)
104  }
105 
106  int Nin = U.nin(); // 2x(complex) 3(color) x 3(color) part (SA)
107  int Nvol = U.nvol(); // local volume (SA)
108  int Nex = U.nex(); // direction mu (SA)
109 
110  Field_G iP(Nvol, Nex); // define momentum iP for gauge fields (SA)
111 
112 
113  vout.general(m_vl, "HMC (single leapfrog) start.\n");
114 
115  //- Langevin step
116  double H_tot0 = langevin(iP, U); // calculate initial hamiltonian (SA)
117  // H=p^2/s + S_G + all fermion contributions (SA)
118  vout.general(m_vl, " H_total(init) = %18.8f\n", H_tot0);
119 
120  double plaq0 = m_staple->plaquette(U); // calculate plaquette of old U (SA)
121  vout.general(m_vl, " plaq(init) = %18.8f\n", plaq0);
122 
123  //- initial Hamiltonian
124  // H_tot0 = calc_Hamiltonian(iP,U);
125 
126  //- molecular dynamical integration
127  integrate(iP, U); // MD step (SA)
128 
129  //- trial Hamiltonian
130  double H_tot1 = calc_Hamiltonian(iP, U); // calculate final hamiltonian (SA)
131  vout.general(m_vl, " H_total(trial) = %18.8f\n", H_tot1);
132 
133  double plaq1 = m_staple->plaquette(U); // calculate plaquette of new U (SA)
134  vout.general(m_vl, " plaq(trial) = %18.8f\n", plaq1);
135 
136 
137  //- Metropolis test
138  vout.general(m_vl, "Metropolis test.\n");
139 
140  double diff_H = H_tot1 - H_tot0; // Delta H (SA)
141  double Arprob = exp(-diff_H); // e^{-Delta H} (SA)
142  double rn = -1.0;
143  if (m_Mtpl_test != 0) {
144  rn = m_rand->get(); // random number 0 <= rn < 1 (SA)
145  }
146  vout.general(m_vl, " H(diff) = %10.6f\n", diff_H);
147  vout.general(m_vl, " Acceptance probability = %10.6f\n", Arprob);
148  vout.general(m_vl, " Random number = %10.6f\n", rn);
149 
150  if (rn <= Arprob) { // accepted
151  vout.general(m_vl, " Accepted\n");
152  conf_org = U; // set new U to gauge conf. (SA)
153  } else { // rejected
154  vout.general(m_vl, " Rejected\n");
155  }
156 
157 
158  double plaq_final = m_staple->plaquette(conf_org);
159  vout.general(m_vl, " plaq(final) = %18.8f\n", plaq_final);
160 
161  return plaq_final;
162 }
163 
164 
165 //====================================================================
167 {
168  int Nc = CommonParameters::Nc();
169  int Lvol = CommonParameters::Lvol(); //global volume (SA)
170  int Ndim = CommonParameters::Ndim();
171  int NcA = Nc * Nc - 1; // Nc^2-1 (SA)
172 
173  int size_iP = NcA * Lvol * Ndim; // global size of momentum iP (SA)
174 
175  vout.general(m_vl, "Langevin step.\n");
176 
177  for (int i = 0; i < m_action.size(); ++i) {
178  m_action[i]->notify_linkv(); // tell action that gauge field is modified.(SA)
179  }
180 
181  for (int i = 0; i < m_director.size(); ++i) {
182  m_director[i]->notify_linkv(); // tell director that gauge filed is modified.(SA)
183  }
184 
185  //- kinetic term
186  double H_iP = m_Langevin_P->set_iP(iP);
187  // calculate hamiltonian of momenta iP. (SA)
188  vout.general(m_vl, " H_kin = %18.8f\n", H_iP);
189  vout.general(m_vl, " H_kin/dof = %18.8f\n", H_iP / size_iP);
190 
191 
192  double H_actions = 0.0;
193  for (int i = 0; i < m_action.size(); ++i) {
194  H_actions += m_action[i]->langevin(m_rand);
195  // calculate contribution to hamiltonian from each action. (SA)
196  }
197 
198  double H_tot = H_iP + H_actions; // total hamiltonian. (SA)
199  return H_tot;
200 }
201 
202 
203 //====================================================================
205 {
206  int Nin = U.nin(); // Local volume (SA)
207  int Nvol = U.nvol();
208  int Nex = U.nex();
209 
210  int Nc = CommonParameters::Nc();
211  int Nd = CommonParameters::Nd();
212  int Lvol = CommonParameters::Lvol(); //Global volume (SA)
213  int NcA = Nc * Nc - 1;
214 
215  int size_iP = NcA * Lvol * Nex; // Global size of iP (SA)
216  // int size_U = Lvol * 6.0; // Global size of U (SA)
217  // int size_psf = Lvol * Nc * Nd; // Global size of pseudo-fermion (SA)
218 
219 
220  vout.general(m_vl, "Hamiltonian calculation.\n");
221 
222  // kinetic term
223  double H_iP = calcH_P(iP); // calculate hamiltonian for iP (SA)
224  vout.general(m_vl, " H_kin = %18.8f\n", H_iP);
225  vout.general(m_vl, " H_kin/dof = %18.8f\n", H_iP / size_iP);
226 
227  double H_actions = 0.0;
228  for (int i = 0; i < m_action.size(); ++i) {
229  // calculate contribution to hamiltonian from each action (SA)
230  H_actions += m_action[i]->calcH();
231  }
232 
233  double H_tot = H_iP + H_actions;
234  return H_tot;
235 }
236 
237 
238 //====================================================================
240 {
241  //calculate hamiltonian for iP: |iP|^2/2 (SA)
242  double hn = iP.norm();
243  double H_iP = 0.5 * hn * hn;
244 
245  return H_iP;
246 }
247 
248 
249 //====================================================================
251 {
252  vout.general(m_vl, "Integration.\n");
253 
254  double estep = m_Estep;
255  double estep2 = 0.5 * m_Estep;
256 
257  // Initial half step of update of h
258  if (m_Nmdc > 0) {
259  int imdc = 0;
260  vout.general(m_vl, " imdc = %d\n", imdc);
261  update_P(estep2, iP, U); // update momentum iP at first half step (SA)
262  }
263 
264  // Molecular dynamics step
265  for (int imdc = 1; imdc < m_Nmdc + 1; imdc++) {
266  vout.general(m_vl, " imdc = %d\n", imdc);
267 
268  update_U(estep, iP, U); // update gauge field U at full step (SA)
269 
270  if (imdc < m_Nmdc) {
271  update_P(estep, iP, U); // update momentum iP at full step (SA)
272  } else {
273  update_P(estep2, iP, U); // update momentum iP at last half step (SA)
274  }
275  } // here imdc loop ends
276 }
277 
278 
279 //====================================================================
280 void HMC_Leapfrog::update_P(double estep, Field_G& iP, Field_G& U)
281 {
282  int Nin = U.nin();
283  int Nvol = U.nvol();
284  int Nex = U.nex();
285  int Nc = CommonParameters::Nc();
286 
287  Field force(Nin, Nvol, Nex);
288 
289  force = 0.0;
290 
291  Field force1(Nin, Nvol, Nex);
292  // double H_actions = 0.0;
293  for (int i = 0; i < m_action.size(); ++i) {
294  force1 = m_action[i]->force(); // calculate force for each action (SA)
295  force += estep * force1;
296  }
297 
298  iP += (Field_G)force; // iP = iP + step-size * force (SA)
299 }
300 
301 
302 //====================================================================
303 void HMC_Leapfrog::update_U(double estep, Field_G& iP, Field_G& U)
304 {
305  int Nvol = U.nvol();
306  int Nex = U.nex();
307  int Nc = CommonParameters::Nc();
308 
309  Mat_SU_N u0(Nc), u1(Nc), u2(Nc);
310  Mat_SU_N h1(Nc);
311 
312  for (int ex = 0; ex < Nex; ++ex) {
313  for (int site = 0; site < Nvol; ++site) {
314  u0 = U.mat(site, ex);
315  u1 = U.mat(site, ex);
316  h1 = iP.mat(site, ex);
317 
318  for (int iprec = 0; iprec < m_Nprec; ++iprec) {
319  double exf = estep / (m_Nprec - iprec); // step_size/(N-k) (SA)
320  u2 = h1 * u1; // iP* u1 (SA)
321  u2 *= exf; // step_size*iP*u1/(N-K) (SA)
322  u1 = u2;
323  u1 += u0; // U + step_size*iP*u1/(N-K) (SA)
324  }
325  // u1 =sum_{k=0}^{N-1} (step_size * iP)^k/k!, N=m_Nprec (SA)
326  u1.reunit(); // reunitarize u1 (SA)
327  U.set_mat(site, ex, u1); // U = u1 (SA)
328  }
329  }
330 
331  for (int i = 0; i < m_action.size(); ++i) {
332  m_action[i]->notify_linkv(); // notify all actions about update of U (SA)
333  }
334 
335  for (int i = 0; i < m_director.size(); ++i) {
336  m_director[i]->notify_linkv(); // notify all directors about update of U (SA)
337  }
338 }
339 
340 
341 //====================================================================
342 //============================================================END=====
BridgeIO vout
Definition: bridgeIO.cpp:207
virtual double get()=0
void set_parameters(const Parameters &params)
void Register_string(const string &, const string &)
Definition: parameters.cpp:352
double m_Estep
Definition: hmc_Leapfrog.h:59
void general(const char *format,...)
Definition: bridgeIO.cpp:38
void Register_int(const string &, const int)
Definition: parameters.cpp:331
Container of Field-type object.
Definition: field.h:37
static const std::string class_name
Definition: hmc_Leapfrog.h:53
std::valarray< Director * > m_director
Definition: hmc_Leapfrog.h:65
int nvol() const
Definition: field.h:101
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:32
Class for parameters.
Definition: parameters.h:40
RandomNumbers * m_rand
Definition: hmc_Leapfrog.h:66
static int Lvol()
Langevin_Momentum * m_Langevin_P
Definition: hmc_Leapfrog.h:61
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:67
int nin() const
Definition: field.h:100
SU(N) gauge field.
Definition: field_G.h:36
void integrate(Field_G &iP, Field_G &U)
double norm() const
Definition: field.h:210
double update(Field_G &)
void update_U(double estep, Field_G &iP, Field_G &U)
int nex() const
Definition: field.h:102
double langevin(Field_G &iP, Field_G &U)
double calcH_P(Field_G &iP)
void crucial(const char *format,...)
Definition: bridgeIO.cpp:26
std::valarray< Action * > m_action
Definition: hmc_Leapfrog.h:64
static bool Register(const std::string &realm, const creator_callback &cb)
void Register_double(const string &, const double)
Definition: parameters.cpp:324
int fetch_double(const string &key, double &val) const
Definition: parameters.cpp:124
string get_string(const string &key) const
Definition: parameters.cpp:85
void set_mat(const int site, const int mn, const Mat_SU_N &U)
Definition: field_G.h:156
Mat_SU_N mat(const int site, const int mn=0) const
Definition: field_G.h:110
Staples * m_staple
Definition: hmc_Leapfrog.h:62
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:191