Bridge++  Ver. 1.1.x
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
gradientFlow.cpp
Go to the documentation of this file.
1 
13 #include "gradientFlow.h"
14 
15 #ifdef USE_PARAMETERS_FACTORY
16 #include "parameters_factory.h"
17 #endif
18 
19 const double GradientFlow::c4[] =
20 { 0.25, -17.0 / 36.0, 8.0 / 9.0, 0.75, };
21 
22 const double GradientFlow::c5[] =
23 {
24  1.0 / 6.0,
25  1.0 - 1.0 / sqrt(2.0),
26  2.0 - c5[1], /* 1.0+1.0/sqrt(2.0) */
27  c5[1] - 0.5,
28  -4.0 * c5[2],
29  6.0 - 4.0 * c5[1],
30  1.0 / c5[3],
31 };
32 
33 
34 //- parameter entries
35 namespace {
36  void append_entry(Parameters& param)
37  {
38  param.Register_int("order_of_RungeKutta", 0);
39  param.Register_double("step_size", 0.0);
40  param.Register_int("number_of_steps", 0);
41  param.Register_int("order_of_approx_for_exp_iP", 0);
42 
43  param.Register_string("verbose_level", "NULL");
44  }
45 
46 
47 #ifdef USE_PARAMETERS_FACTORY
48  bool init_param = ParametersFactory::Register("GradientFlow",append_entry);
49 #endif
50 }
51 //- end
52 
53 //- parameters class
55 //- end
56 
57 //====================================================================
59 {
60  const string str_vlevel = params.get_string("verbose_level");
61 
62  m_vl = vout.set_verbose_level(str_vlevel);
63 
64  //- fetch and check input parameters
65  int order_RK;
66  double Estep;
67  int Nstep, Nprec;
68 
69  int err = 0;
70  err += params.fetch_int("order_of_RungeKutta", order_RK);
71  err += params.fetch_double("step_size", Estep);
72  err += params.fetch_int("number_of_steps", Nstep);
73  err += params.fetch_int("order_of_approx_for_exp_iP", Nprec);
74 
75  if (err) {
76  vout.crucial(m_vl, "GradientFlow: fetch error, input parameter not found.\n");
77  abort();
78  }
79 
80 
81  set_parameters(order_RK, Estep, Nstep, Nprec);
82 }
83 
84 
85 //====================================================================
86 void GradientFlow::set_parameters(const int order_RK,
87  const double Estep, const int Nstep, const int Nprec)
88 {
89  //- print input parameters
90  vout.general(m_vl, "Parameters of GradientFlow:\n");
91  vout.general(m_vl, " order_RK = %d\n", order_RK);
92  vout.general(m_vl, " Estep = %10.6f\n", Estep);
93  vout.general(m_vl, " Nstep = %d\n", Nstep);
94  vout.general(m_vl, " Nprec = %d\n", Nprec);
95 
96  //- range check
97  int err = 0;
98  err += ParameterCheck::non_negative(order_RK);
99  err += ParameterCheck::square_non_zero(Estep);
100  err += ParameterCheck::non_negative(Nstep);
101  err += ParameterCheck::non_negative(Nprec);
102 
103  if (err) {
104  vout.crucial(m_vl, "GradientFlow: parameter range check failed.\n");
105  abort();
106  }
107 
108  //- store values
109  m_order_RK = order_RK; // order of Runge-Kutta
110  m_Estep = Estep; // step size (SA)
111  m_Nstep = Nstep; // a number of steps (SA)
112  m_Nprec = Nprec; // order of approximation for e^{iP} (SA)
113 }
114 
115 
116 //====================================================================
118 {
119  double Eplaq = 0.0; // superficial initialization
120  double tt;
121 
122  m_action->set_config(&U); // give gauge conf pointer &U to d_action (SA)
123 
124  Staples wl;
125  double plaq = wl.plaquette(U); // calculate plaqutte (SA)
126 
127  vout.general(m_vl, " plaq_org = %.16f\n", plaq); // write-out
128 
129  //- time evolution (SA)
130  for (int i = 0; i < m_Nstep; ++i) {
131  if (m_order_RK == 4) {
132  //- 4th order Runge-Kutta (SA)
133  gradientFlow_4th(U);
134  } else if (m_order_RK == 5) {
135  //- 5th order Runge-Kutta (SA)
136  gradientFlow_5th(U);
137  } else {
138  vout.crucial(m_vl, "GradientFlow: order of Runge-Kutta is out of range.\n");
139  abort();
140  }
141 
142  plaq = wl.plaquette(U); // calculate plaqutte (SA)
143  Eplaq = 36.0 * (1.0 - plaq); // E=36*(1-Plaq)
144  tt = (i + 1) * m_Estep;
145  Eplaq = tt * tt * Eplaq;
146 
147  vout.general(m_vl, " (t, t^2 E_plaq) = %.8f %.16f\n", tt, Eplaq); //write-out
148  }
149 
150  double result = Eplaq;
151 
152  return result;
153 }
154 
155 
156 //====================================================================
157 void GradientFlow::update_U(double estep, Field_G& iP, Field_G& U)
158 {
159  int Nvol = U.nvol();
160  int Nex = U.nex();
161  int Nc = CommonParameters::Nc();
162 
163  Mat_SU_N u0(Nc), u1(Nc), u2(Nc);
164  Mat_SU_N h1(Nc);
165 
166  for (int ex = 0; ex < Nex; ++ex) {
167  for (int site = 0; site < Nvol; ++site) {
168  u0 = U.mat(site, ex);
169  u1 = U.mat(site, ex);
170  h1 = iP.mat(site, ex);
171 
172  for (int iprec = 0; iprec < m_Nprec; ++iprec) {
173  double exf = estep / (m_Nprec - iprec); // step_size/(N-k) (SA)
174 
175  u2 = h1 * u1; // iP*u1 (SA)
176  u2 *= exf; // step_size*iP*u1/(N-k) (SA)
177  u1 = u2;
178  u1 += u0; // U + step_size*iP*u1/(N-k) (SA)
179  }
180 
181  // u1 = sum_{k=0}^{N-1} (step_size * iP)^k/ k!*U, N=m_Nprec (SA)
182  u1.reunit(); // reunitarize u1 (SA)
183  U.set_mat(site, ex, u1); // U=u1 (SA)
184  }
185  }
186 
187  m_action->notify_linkv(); // notify action about update of U (SA)
188 }
189 
190 
191 //====================================================================
193 {
194  //- step 0
195  iP = (Field_G)m_action->force(); // calculate gradient of m_action Z_0 (SA)
196  update_U(c4[0] * m_Estep, iP, U); // W_1=e^{Z_0/4}*U (SA)
197 
198  //- step 1
199  iP *= c4[1]; // -(17/36)Z_0 (SA)
200  iPP = (Field_G)m_action->force(); // Z_1 (SA)
201  iPP *= c4[2]; // (8/9)*Z_1 (SA)
202  iP += iPP; // calculate (8/9)*Z_1-(17/36)*Z_0 (SA)
203  update_U(m_Estep, iP, U); // W_2=e^{8*Z_1/9-17*Z_0/36}*W_1 (SA)
204 
205  //- step 2
206  iPP = (Field_G)m_action->force(); // Z_2 (SA)
207  iPP *= c4[3]; // (3/4)*Z_2 (SA)
208  iPP -= iP; // calculate (3/4)*Z_2-(8/9)*Z_1+(17/36)*Z_0 (SA)
209  update_U(m_Estep, iPP, U); // V_out=e^{3*Z_2/4-8*Z_1/9+17*Z_0/36}*W_2 (SA)
210 }
211 
212 
213 //====================================================================
215 {
216  //- step 0
217  iP = (Field_G)m_action->force(); // calculate gradient of m_action Z_0 (SA)
218  // iP=iPP; // Z_0
219  update_U(0.5 * m_Estep, iP, U); // W_1=e^{Z_0/4}*U (SA)
220 
221  //- step 1
222  iP1 = (Field_G)m_action->force(); // Z_1
223  iPP = iP1;
224  iPP -= iP; // calculate Z_1-Z_0 (SA)
225  update_U(c5[1] * m_Estep, iPP, U); // W_2=e^{c_1*(Z_1-Z_0)}*W_1 (SA)
226 
227  //- step 2
228  iPP = (Field_G)m_action->force(); // Z_2
229  iP2 = iPP; // Z_2
230  iPP *= c5[2]; // c_2*Z_2
231  iPP -= iP1; // c_2*Z_2-Z_1
232  iP *= c5[3]; // c_3*Z_0
233  iPP += iP; // c_2*Z_2-Z_1+c_3*Z_0
234  update_U(m_Estep, iPP, U); // W_3=e^{c_2*Z_2-Z_1+c_3*Z_0}*W_2 (SA)
235 
236  iPP = (Field_G)m_action->force(); // Z_3
237  iP2 *= c5[4]; // c_4*Z_2
238  iPP += iP2; // Z_3+c_4*Z_2
239  iP1 *= c5[5]; // c_5*Z_1
240  iPP += iP1; // Z_3+c_4*Z_2+c_5*Z_1
241  iP *= c5[6]; // Z_0
242  iPP += iP; // Z_3+c_4*Z_2+c_5*Z_1+Z_0
243  update_U(c5[0] * m_Estep, iPP, U); // V_t=e^{(Z_3+c_4*Z_2+c_5*Z_1+Z_0)/6}*W_3 (SA)
244 }
245 
246 
247 //====================================================================
248 //============================================================END=====