Bridge++  Ver. 1.2.x
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
integrator.cpp
Go to the documentation of this file.
1 
14 #include "hmc_General.h"
15 
16 //====================================================================
17 void HMC_General::set_parameters(double Estep, int Nmdc,
18  int Mtpl_test,
19  int Naction0, int Naction1, int Naction2,
20  int Nmd1, int Nmd2)
21 {
22  vout.general(m_vl, "HMC (3-level leapfrog) setup:\n");
23 
24  vout.general(m_vl, " Number of actions: %4d\n", m_action.size());
25 
26  m_Estep = Estep;
27  m_Nmdc = Nmdc;
28  m_Mtpl_test = Mtpl_test;
29 
30  m_Naction0 = Naction0;
31  m_Naction1 = Naction1;
32  m_Naction2 = Naction2;
33  m_Nmd1 = Nmd1;
34  m_Nmd2 = Nmd2;
35 
36  assert(m_action.size() == m_Naction0 + m_Naction1 + m_Naction2);
37 
38  m_Nprec = 8;
39 
40  vout.general(m_vl, " Estep = %10.6f\n", m_Estep);
41  vout.general(m_vl, " Nmdc = %4d\n", m_Nmdc);
42  vout.general(m_vl, " Naction0 = %4d\n", m_Naction0);
43  vout.general(m_vl, " Naction1 = %4d\n", m_Naction1);
44  vout.general(m_vl, " Naction2 = %4d\n", m_Naction2);
45  vout.general(m_vl, " Nmd1 = %4d\n", m_Nmd1);
46  vout.general(m_vl, " Nmd2 = %4d\n", m_Nmd2);
47  vout.general(m_vl, " Nprec = %4d\n", m_Nprec);
48 }
49 
50 
51 //====================================================================
52 void HMC_General::update(Field_G& conf_org)
53 {
54  vout.general(m_vl, "HMC (single leapfrog) start.\n");
55 
56  Field_G U(conf_org);
57 
58  for (int i = 0; i < m_action.size(); ++i) {
59  m_action[i]->set_config(&U);
60  }
61 
62  int Nin = U.nin();
63  int Nvol = U.nvol();
64  int Nex = U.nex();
65 
66  int Nc = CommonParameters::Nc();
67  int Lvol = CommonParameters::Lvol();
68 
69  Field_G iP(Nvol, Nex);
70 
71  // Langevin step
72  double H_tot0 = langevin(iP, U);
73  vout.general(m_vl, " H_tot(init) = %20.10f\n", H_tot0);
74 
75  double plaq0 = m_staple->plaquette(&U);
76  vout.general(m_vl, " plaq(init) = %20.12f\n", plaq0);
77 
78  // initial Hamiltonian
79  // H_tot0 = calc_Hamiltonian(iP,U);
80 
81  // molecular dynamical integration
82  integrate(iP, U);
83 
84  // final Hamiltonian
85  double H_tot1 = calc_Hamiltonian(iP, U);
86  vout.general(m_vl, " H_tot(fin) = %20.10f\n", H_tot1);
87 
88  double plaq1 = m_staple->plaquette(&U);
89  vout.general(m_vl, " plaq(fin) = %20.12f\n", plaq1);
90 
91 
92  // Metropolis test
93  vout.general(m_vl, "Metropolis test.\n");
94 
95  double diff_H = H_tot1 - H_tot0;
96  double Arprob = exp(-diff_H);
97  double rn = -1.0;
98  if (m_Mtpl_test != 0) {
99  rn = m_rand->get();
100  }
101  vout.general(m_vl, " H(diff) = %14.8f\n", diff_H);
102  vout.general(m_vl, " Acceptance = %14.8f\n", Arprob);
103  vout.general(m_vl, " Random number = %14.8f\n", rn);
104 
105  if (rn <= Arprob) { // accepted
106  vout.general(m_vl, " Accepted\n");
107  conf_org = U;
108  } else { // rejected
109  vout.general(m_vl, " Rejected\n");
110  }
111 }
112 
113 
114 //====================================================================
115 double HMC_General::langevin(Field_G& iP, Field_G& U)
116 {
117  int Nc = CommonParameters::Nc();
118  int Lvol = CommonParameters::Lvol();
119  int Ndim = CommonParameters::Ndim();
120  int NcA = Nc * Nc - 1;
121 
122  int size_iP = NcA * Lvol * Ndim;
123 
124  vout.general(m_vl, "Langevin step.\n");
125 
126  for (int i = 0; i < m_action.size(); ++i) {
127  m_action[i]->notify_linkv();
128  }
129 
130  for (int i = 0; i < m_director.size(); ++i) {
131  m_director[i]->notify_linkv();
132  }
133 
134  // kinetic term
135  double H_iP = langevin_P(iP);
136  vout.general(m_vl, " Kinetic term:\n");
137  vout.general(m_vl, " H_kin = %18.8f\n", H_iP);
138  vout.general(m_vl, " H_kin/dof = %18.8f\n", H_iP / size_iP);
139 
140 
141  double H_actions = 0.0;
142  for (int i = 0; i < m_action.size(); ++i) {
143  H_actions += m_action[i]->langevin(m_rand);
144  }
145 
146  double H_tot = H_iP + H_actions;
147  return H_tot;
148 }
149 
150 
151 //====================================================================
152 double HMC_General::langevin_P(Field_G& iP)
153 {
154  int Nin = iP.nin();
155  int Nvol = iP.nvol();
156  int Nex = iP.nex();
157 
158  int Nc = CommonParameters::Nc();
159  int NcA = Nc * Nc - 1;
160 
161  // confirm that now gauge group is SU(3)
162  assert(NcA == 8);
163 
164  Field Hrand(NcA, Nvol, Nex);
165 
166  m_rand->gauss_lex_global(Hrand);
167 
168  double sq3r = 1.0 / sqrt(3.0);
169  double sq3r2 = 2.0 * sq3r;
170 
171  for (int ex = 0; ex < Nex; ++ex) {
172  for (int site = 0; site < Nvol; ++site) {
173  //here SU(3) is explicitly assumed. need to generalize.
174  double hc1 = Hrand.cmp(0, site, ex);
175  double hc2 = Hrand.cmp(1, site, ex);
176  double hc3 = Hrand.cmp(2, site, ex);
177  double hc4 = Hrand.cmp(3, site, ex);
178  double hc5 = Hrand.cmp(4, site, ex);
179  double hc6 = Hrand.cmp(5, site, ex);
180  double hc7 = Hrand.cmp(6, site, ex);
181  double hc8 = Hrand.cmp(7, site, ex);
182  iP.set(0, site, ex, 0.0);
183  iP.set(1, site, ex, hc3 + hc8 * sq3r);
184  iP.set(2, site, ex, hc2);
185  iP.set(3, site, ex, hc1);
186  iP.set(4, site, ex, hc5);
187  iP.set(5, site, ex, hc4);
188  iP.set(6, site, ex, -hc2);
189  iP.set(7, site, ex, hc1);
190  iP.set(8, site, ex, 0.0);
191  iP.set(9, site, ex, -hc3 + hc8 * sq3r);
192  iP.set(10, site, ex, hc7);
193  iP.set(11, site, ex, hc6);
194  iP.set(12, site, ex, -hc5);
195  iP.set(13, site, ex, hc4);
196  iP.set(14, site, ex, -hc7);
197  iP.set(15, site, ex, hc6);
198  iP.set(16, site, ex, 0.0);
199  iP.set(17, site, ex, -hc8 * sq3r2);
200  }
201  }
202 
203  double iP2 = iP.norm();
204  iP2 = 0.5 * iP2 * iP2;
205 
206  return iP2;
207 }
208 
209 
210 //====================================================================
212 {
213  vout.general(m_vl, "Hamiltonian calculation.\n");
214 
215  int Nin = U.nin();
216  int Nvol = U.nvol();
217  int Nex = U.nex();
218 
219  int Nc = CommonParameters::Nc();
220  int Nd = CommonParameters::Nd();
221  int Lvol = CommonParameters::Lvol();
222  int NcA = Nc * Nc - 1;
223 
224  int size_iP = NcA * Lvol * Nex;
225  int size_U = Lvol * 6.0;
226  int size_psf = Lvol * Nc * Nd;
227 
228  // kinetic term
229  double H_iP = calcH_P(iP);
230  vout.general(m_vl, " Kinetic term:\n");
231  vout.general(m_vl, " H_kin = %18.8f\n", H_iP);
232  vout.general(m_vl, " H_kin/dof = %18.8f\n", H_iP / size_iP);
233 
234  double H_actions = 0.0;
235  for (int i = 0; i < m_action.size(); ++i) {
236  H_actions += m_action[i]->calcH();
237  }
238 
239  double H_tot = H_iP + H_actions;
240  return H_tot;
241 }
242 
243 
244 //====================================================================
245 double HMC_General::calcH_P(Field_G& iP)
246 {
247  double hn = iP.norm();
248  double H_iP = 0.5 * hn * hn;
249 
250  return H_iP;
251 }
252 
253 
254 //====================================================================
255 void HMC_General::integrate(Field_G& iP, Field_G& U)
256 {
257  vout.general(m_vl, "Integration level-0 start.\n");
258 
259  int Nin = U.nin();
260  int Nvol = U.nvol();
261  int Nex = U.nex();
262  int Nc = CommonParameters::Nc();
263 
264  double estep = m_Estep;
265  double esteph = 0.5 * estep;
266  double estep2;
267 
268  Field force(Nin, Nvol, Nex), force1(Nin, Nvol, Nex);
269 
270  // Initial half step of update of iP
271  if (m_Nmdc > 0) {
272  int imdc = 0;
273  vout.general(m_vl, "imdc = %d\n", imdc);
274  force = 0.0;
275  for (int i = 0; i < m_Naction0; ++i) {
276  force1 = m_action[i]->force();
277  force += esteph * force1;
278  }
279  iP += (Field_G)force;
280  }
281 
282  // Molecular dynamics step
283  for (int imdc = 1; imdc < m_Nmdc + 1; imdc++) {
284  vout.general(m_vl, "imdc = %d\n", imdc);
285 
286  integrate1(iP, U);
287 
288  estep2 = estep;
289  if (imdc == m_Nmdc) estep2 = esteph;
290 
291  force = 0.0;
292  for (int i = 0; i < m_Naction0; ++i) {
293  force1 = m_action[i]->force();
294  force += estep2 * force1;
295  }
296  iP += (Field_G)force;
297  } // here imdc loop ends
298 
299  vout.general(m_vl, "Integration level-0 finished.\n");
300 }
301 
302 
303 //====================================================================
304 void HMC_General::integrate1(Field_G& iP, Field_G& U)
305 {
306  vout.general(m_vl, "Integration level-1 start.\n");
307 
308  int Nin = U.nin();
309  int Nvol = U.nvol();
310  int Nex = U.nex();
311  int Nc = CommonParameters::Nc();
312 
313  double estep = m_Estep / ((double)m_Nmd1);
314  double esteph = 0.5 * estep;
315  double estep2;
316 
317  Field force(Nin, Nvol, Nex), force1(Nin, Nvol, Nex);
318 
319  // Initial half step of update of h
320  if (m_Nmd1 > 0) {
321  int imd1 = 0;
322  vout.general(m_vl, "imd1 = %d\n", imd1);
323  force = 0.0;
324  for (int i = 0; i < m_Naction1; ++i) {
325  int i2 = i + m_Naction0;
326  force1 = m_action[i2]->force();
327  force += esteph * force1;
328  }
329  iP += (Field_G)force;
330  }
331 
332  // Molecular dynamics step
333  for (int imd1 = 1; imd1 < m_Nmd1 + 1; imd1++) {
334  vout.general(m_vl, "imd1 = %d\n", imd1);
335 
336  integrate2(iP, U);
337 
338  estep2 = estep;
339  if (imd1 == m_Nmd1) estep2 = esteph;
340 
341  force = 0.0;
342  for (int i = 0; i < m_Naction1; ++i) {
343  int i2 = i + m_Naction0;
344  force1 = m_action[i2]->force();
345  force += estep2 * force1;
346  }
347  iP += (Field_G)force;
348  } // here imdc loop ends
349 
350  vout.general(m_vl, "Integration level-1 finished.\n");
351 }
352 
353 
354 //====================================================================
355 void HMC_General::integrate2(Field_G& iP, Field_G& U)
356 {
357  vout.general(m_vl, "Integration level-2 start.\n");
358 
359  int Nin = U.nin();
360  int Nvol = U.nvol();
361  int Nex = U.nex();
362  int Nc = CommonParameters::Nc();
363 
364  double estep = m_Estep / ((double)(m_Nmd1 * m_Nmd2));
365  double esteph = 0.5 * estep;
366  double estep2;
367 
368  Field force(Nin, Nvol, Nex), force1(Nin, Nvol, Nex);
369 
370  // Initial half step of update of h
371  if (m_Nmd2 > 0) {
372  int imd2 = 0;
373  vout.general(m_vl, "imd2 = %d\n", imd2);
374  force = 0.0;
375  for (int i = 0; i < m_Naction2; ++i) {
376  int i2 = i + m_Naction0 + m_Naction1;
377  force1 = m_action[i2]->force();
378  force += esteph * force1;
379  }
380  iP += (Field_G)force;
381  }
382 
383  // Molecular dynamics step
384  for (int imd2 = 1; imd2 < m_Nmd2 + 1; imd2++) {
385  vout.general(m_vl, "imd2 = %d\n", imd2);
386 
387  update_U(estep, iP, U);
388 
389  estep2 = estep;
390  if (imd2 == m_Nmd2) estep2 = esteph;
391 
392  force = 0.0;
393  for (int i = 0; i < m_Naction2; ++i) {
394  int i2 = i + m_Naction0 + m_Naction1;
395  force1 = m_action[i2]->force();
396  force += estep2 * force1;
397  }
398  iP += (Field_G)force;
399  } // here imdc loop ends
400 
401  vout.general(m_vl, "Integration level-2 finished.\n");
402 }
403 
404 
405 //====================================================================
406 void HMC_General::update_U(double estep,
407  Field_G& iP, Field_G& U)
408 {
409  int Nvol = U.nvol();
410  int Nex = U.nex();
411  int Nc = CommonParameters::Nc();
412 
413  Mat_SU_N u0(Nc), u1(Nc), u2(Nc);
414  Mat_SU_N h1(Nc);
415 
416  for (int ex = 0; ex < Nex; ++ex) {
417  for (int site = 0; site < Nvol; ++site) {
418  u0 = U.mat(site, ex);
419  u1 = U.mat(site, ex);
420  h1 = iP.mat(site, ex);
421 
422  for (int iprec = 0; iprec < m_Nprec; ++iprec) {
423  double exf = estep / (m_Nprec - iprec);
424  u2 = h1 * u1;
425  u2 *= exf;
426  u1 = u2;
427  u1 += u0;
428  }
429 
430  u1.reunit();
431  U.set_mat(site, ex, u1);
432  }
433  }
434 
435  for (int i = 0; i < m_action.size(); ++i) {
436  m_action[i]->notify_linkv();
437  }
438 
439  for (int i = 0; i < m_director.size(); ++i) {
440  m_director[i]->notify_linkv();
441  }
442 }
443 
444 
445 //====================================================================
446 //============================================================END=====
BridgeIO vout
Definition: bridgeIO.cpp:207
virtual double get()=0
void set(const int jin, const int site, const int jex, double v)
Definition: field.h:128
double calc_Hamiltonian(Field_G &iP, Field_G &U)
void set_parameters(const Parameters &params)
Definition: hmc_General.cpp:43
void general(const char *format,...)
Definition: bridgeIO.cpp:38
int m_Mtpl_test
Metropolis test: Mtpl_test=0: no test, !=0: test.
Definition: hmc_General.h:59
Container of Field-type object.
Definition: field.h:37
int nvol() const
Definition: field.h:101
Bridge::VerboseLevel m_vl
Definition: hmc_General.h:66
double plaquette(const Field_G &)
calculates plaquette value.
Definition: staples.cpp:32
RandomNumbers * m_rand
random number generator
Definition: hmc_General.h:63
double calcH_P(Field_G &iP)
valarray< Action * > m_action
actions
Definition: hmc_General.h:60
static int Lvol()
virtual void gauss_lex_global(Field &)
gaussian random number defined on global lattice.
Mat_SU_N & reunit()
Definition: mat_SU_N.h:71
double langevin(Field_G &iP, Field_G &U)
int nin() const
Definition: field.h:100
SU(N) gauge field.
Definition: field_G.h:36
double norm() const
Definition: field.h:210
int nex() const
Definition: field.h:102
valarray< Director * > m_director
directors
Definition: hmc_General.h:61
void set_mat(const int site, const int mn, const Mat_SU_N &U)
Definition: field_G.h:156
double update(Field_G &)
Definition: hmc_General.cpp:81
Mat_SU_N mat(const int site, const int mn=0) const
Definition: field_G.h:110
Staples * m_staple
Definition: hmc_General.h:64