Bridge++  Ver. 1.2.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 
20 //- parameter entries
21 namespace {
22  void append_entry(Parameters& param)
23  {
24  param.Register_int("order_of_RungeKutta", 0);
25  param.Register_double("step_size", 0.0);
26  param.Register_int("number_of_steps", 0);
27  param.Register_int("order_of_approx_for_exp_iP", 0);
28 
29  param.Register_string("verbose_level", "NULL");
30  }
31 
32 
33 #ifdef USE_PARAMETERS_FACTORY
34  bool init_param = ParametersFactory::Register("GradientFlow",append_entry);
35 #endif
36 }
37 //- end
38 
39 //- parameters class
41 //- end
42 
43 const std::string GradientFlow::class_name = "GradientFlow";
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  int order_RK;
54  double Estep;
55  int Nstep, Nprec;
56 
57  int err = 0;
58  err += params.fetch_int("order_of_RungeKutta", order_RK);
59  err += params.fetch_double("step_size", Estep);
60  err += params.fetch_int("number_of_steps", Nstep);
61  err += params.fetch_int("order_of_approx_for_exp_iP", Nprec);
62 
63  if (err) {
64  vout.crucial(m_vl, "%s: fetch error, input parameter not found.\n", class_name.c_str());
65  abort();
66  }
67 
68 
69  set_parameters(order_RK, Estep, Nstep, Nprec);
70 }
71 
72 //====================================================================
73 void GradientFlow::set_parameters(const int order_RK,
74  const double Estep, const int Nstep, const int Nprec)
75 {
76  //- print input parameters
77  vout.general(m_vl, "Parameters of %s:\n", class_name.c_str());
78  vout.general(m_vl, " order_RK = %d\n", order_RK);
79  vout.general(m_vl, " Estep = %10.6f\n", Estep);
80  vout.general(m_vl, " Nstep = %d\n", Nstep);
81  vout.general(m_vl, " Nprec = %d\n", Nprec);
82 
83  //- range check
84  int err = 0;
85  err += ParameterCheck::non_negative(order_RK);
86  err += ParameterCheck::square_non_zero(Estep);
87  err += ParameterCheck::non_negative(Nstep);
88  err += ParameterCheck::non_negative(Nprec);
89 
90  if (err) {
91  vout.crucial(m_vl, "%s: parameter range check failed.\n", class_name.c_str());
92  abort();
93  }
94 
95  //- store values
96  m_order_RK = order_RK; // order of Runge-Kutta
97  m_Estep = Estep; // step size (SA)
98  m_Nstep = Nstep; // a number of steps (SA)
99  m_Nprec = Nprec; // order of approximation for e^{iP} (SA)
100 }
101 
102 //====================================================================
104 {
105  double Eplaq = 0.0; // superficial initialization
106  double tt;
107 
108  m_action->set_config(&U); // give gauge conf pointer &U to d_action (SA)
109 
110  Staples wl;
111  double plaq = wl.plaquette(U); // calculate plaqutte (SA)
112 
113  vout.general(m_vl, " plaq_org = %.16f\n", plaq); // write-out
114 
115  //- time evolution (SA)
116  for (int i = 0; i < m_Nstep; ++i) {
117  if (m_order_RK == 1) {
118  gradientFlow_1st(U);
119  } else if (m_order_RK == 2) {
120  gradientFlow_2nd(U);
121  } else if (m_order_RK == 3) {
122  gradientFlow_3rd(U);
123  } else if (m_order_RK == 4) {
124  gradientFlow_4th(U);
125  } else {
126  vout.crucial(m_vl, "%s: order of Runge-Kutta is out of range.\n", class_name.c_str());
127  abort();
128  }
129 
130  plaq = wl.plaquette(U); // calculate plaqutte (SA)
131  Eplaq = 36.0 * (1.0 - plaq); // E=36*(1-Plaq)
132  tt = (i + 1) * m_Estep;
133  Eplaq = tt * tt * Eplaq;
134 
135  vout.general(m_vl, " (t, plaq, t^2 E_plaq) = %.8f %.16f %.16f\n", tt, plaq, Eplaq); // write-out
136  }
137 
138  double result = Eplaq;
139 
140  return result;
141 }
142 
143 //====================================================================
144 void GradientFlow::update_U(double estep, Field_G& iP, Field_G& U)
145 {
146  int Nvol = U.nvol();
147  int Nex = U.nex();
148  int Nc = CommonParameters::Nc();
149 
150  Mat_SU_N u0(Nc), u1(Nc), u2(Nc);
151  Mat_SU_N h1(Nc);
152 
153  for (int ex = 0; ex < Nex; ++ex) {
154  for (int site = 0; site < Nvol; ++site) {
155  u0 = U.mat(site, ex);
156  u1 = U.mat(site, ex);
157  h1 = iP.mat(site, ex);
158 
159  for (int iprec = 0; iprec < m_Nprec; ++iprec) {
160  double exf = estep / (m_Nprec - iprec); // step_size/(N-k) (SA)
161 
162  u2 = h1 * u1; // iP*u1 (SA)
163  u2 *= exf; // step_size*iP*u1/(N-k) (SA)
164  u1 = u2;
165  u1 += u0; // U + step_size*iP*u1/(N-k) (SA)
166  }
167 
168  // u1 = sum_{k=0}^{N-1} (step_size * iP)^k/ k!*U, N=m_Nprec (SA)
169  u1.reunit(); // reunitarize u1 (SA)
170  U.set_mat(site, ex, u1); // U=u1 (SA)
171  }
172  }
173 
174  m_action->notify_linkv(); // notify action about update of U (SA)
175 }
176 
177 //====================================================================
179 {
180  //- step 0
181  m_iP = (Field_G)m_action->force(); // calculate gradient of m_action Z_0 (SA)
182  update_U(m_Estep, m_iP, U); // W_1=e^{Z_0}*U
183 }
184 
185 //====================================================================
187 {
188  const double c2 = 0.5;
189 
190  copy(m_U_0, U);
191 
192  //- step 0
193  m_iP = (Field_G)m_action->force(); // calculate gradient of m_action Z_0 (SA)
194  update_U(c2 * m_Estep, m_iP, U); // W_1=e^{c2*Z_0}*U
195 
196  //- step 1
197  m_iPP = (Field_G)m_action->force(); // Z_1
198  copy(U, m_U_0);
199  update_U(m_Estep, m_iPP, U); // V_out=e^{Z_1}*W_0
200 }
201 
202 //====================================================================
204 {
205  const double c3[] =
206  { 0.25, -17.0 / 36.0, 8.0 / 9.0, 0.75, };
207 
208  //- step 0
209  m_iP = (Field_G)m_action->force(); // calculate gradient of m_action Z_0 (SA)
210  update_U(c3[0] * m_Estep, m_iP, U); // W_1=e^{Z_0/4}*U (SA)
211 
212  //- step 1
213  scal(m_iP, c3[1]); // -(17/36)Z_0 (SA)
214  m_iPP = (Field_G)m_action->force(); // Z_1 (SA)
215  scal(m_iPP, c3[2]); // (8/9)*Z_1 (SA)
216  axpy(m_iP, 1.0, m_iPP); // (8/9)*Z_1-(17/36)*Z_0 (SA)
217  update_U(m_Estep, m_iP, U); // W_2=e^{8*Z_1/9-17*Z_0/36}*W_1 (SA)
218 
219  //- step 2
220  m_iPP = (Field_G)m_action->force(); // Z_2 (SA)
221  scal(m_iPP, c3[3]); // (3/4)*Z_2 (SA)
222  axpy(m_iPP, -1.0, m_iP); // (3/4)*Z_2-(8/9)*Z_1+(17/36)*Z_0 (SA)
223  update_U(m_Estep, m_iPP, U); // V_out=e^{3*Z_2/4-8*Z_1/9+17*Z_0/36}*W_2 (SA)
224 }
225 
226 //====================================================================
228 {
229  const double c4[] =
230  {
231  0.5,
232  -0.5,
233  3.0,
234  2.0,
235  -1.0,
236  1.0 / 12.0,
237  };
238 
239  copy(m_U_0, U); // m_U_0 = U
240 
241  //- step 0
242  m_iP = (Field_G)m_action->force(); // calculate gradient of m_action Z_0 (SA)
243  update_U(c4[0] * m_Estep, m_iP, U); // W_1=e^{Z_0/2}*U (SA)
244 
245  copy(m_W_1, U); // W_1 = U
246 
247  //- step 1
248  m_iP1 = (Field_G)m_action->force(); // Z_1
249  copy(U, m_U_0); // U = m_U_0
250  update_U(c4[0] * m_Estep, m_iP1, U); // W_2=e^{(1/2)*Z_1}*W_0
251 
252  //- step 2
253  m_iP2 = (Field_G)m_action->force(); // Z_2
254  copy(m_iPP, m_iP2); // m_iPP = m_iP2
255  axpy(m_iPP, c4[1], m_iP); // Z_2 - (1/2)*Z_0
256  copy(U, m_W_1); // U = W_1 NB. not m_U_0
257  update_U(m_Estep, m_iPP, U); // W_3=e^{Z_2 - (1/2)*Z_0}*W_1 NB. not W_0
258 
259  //- step 3
260  m_iP3 = (Field_G)m_action->force(); // Z_3
261 
262  copy(m_iPP, m_iP); // m_iPP = Z_0
263  scal(m_iPP, c4[2]); // 3*Z_0
264  axpy(m_iPP, c4[3], m_iP1); // 3*Z_0+2*Z_1
265  axpy(m_iPP, c4[3], m_iP2); // 3*Z_0+2*Z_1+2*Z_2
266  axpy(m_iPP, c4[4], m_iP3); // 3*Z_0+2*Z_1+2*Z_2-Z_3
267  copy(U, m_U_0); // U = m_U_0
268  update_U(c4[5] * m_Estep, m_iPP, U); // W_4=e^{(1/12)*(3*Z_0+2*Z_1+2*Z_2-Z_3)}*W_0
269 
270  //- step 4 (extra step)
271  copy(m_iPP, m_iP); // m_iPP = Z_0
272  scal(m_iPP, c4[4]); // -Z_0
273  axpy(m_iPP, c4[3], m_iP1); // -Z_0+2*Z_1
274  axpy(m_iPP, c4[3], m_iP2); // -Z_0+2*Z_1+2*Z_2
275  axpy(m_iPP, c4[2], m_iP3); // -Z_0+2*Z_1+2*Z_2+3*Z_3
276  update_U(c4[5] * m_Estep, m_iPP, U); // V_t=e^{(1/12)*(-Z_0+2*Z_1+2*Z_2+3*Z_3)}*W_4 NB. not W_0
277 }
278 
279 //====================================================================
280 //============================================================END=====
static const std::string class_name
Definition: gradientFlow.h:46
double m_Estep
Definition: gradientFlow.h:53
void scal(Field &x, const double a)
scal(x, a): x = a * x
Definition: field.cpp:310
virtual void notify_linkv()=0
to be called when gauge configuration is updated.
Field_G m_W_1
Definition: gradientFlow.h:59
BridgeIO vout
Definition: bridgeIO.cpp:207
Action * m_action
Definition: gradientFlow.h:57
void Register_string(const string &, const string &)
Definition: parameters.cpp:352
Staple construction.
Definition: staples.h:40
void update_U(double estep, Field_G &iP, Field_G &U)
void gradientFlow_3rd(Field_G &U)
void general(const char *format,...)
Definition: bridgeIO.cpp:38
void Register_int(const string &, const int)
Definition: parameters.cpp:331
int nvol() const
Definition: field.h:101
double plaquette(const Field_G &)
calculates plaquette value.
Definition: staples.cpp:32
Field_G m_iP3
Definition: gradientFlow.h:58
virtual const Field force()=0
returns force for molcular dynamical update of conjugate momenta.
Class for parameters.
Definition: parameters.h:40
void copy(Field &y, const Field &x)
copy(y, x): y = x
Definition: field.cpp:409
void gradientFlow_2nd(Field_G &U)
Mat_SU_N & reunit()
Definition: mat_SU_N.h:71
void gradientFlow_4th(Field_G &U)
virtual void set_config(Field *U)=0
setting pointer to the gauge configuration.
int square_non_zero(const double v)
Definition: checker.cpp:41
SU(N) gauge field.
Definition: field_G.h:36
int nex() const
Definition: field.h:102
void axpy(Field &y, const double a, const Field &x)
axpy(y, a, x): y := a * x + y
Definition: field.cpp:193
double evolve(Field_G &U)
void gradientFlow_1st(Field_G &U)
void crucial(const char *format,...)
Definition: bridgeIO.cpp:26
Field_G m_iP
Definition: gradientFlow.h:58
static bool Register(const std::string &realm, const creator_callback &cb)
Bridge::VerboseLevel m_vl
Definition: gradientFlow.h:49
int non_negative(const int v)
Definition: checker.cpp:21
void Register_double(const string &, const double)
Definition: parameters.cpp:324
Field_G m_U_0
Definition: gradientFlow.h:59
Field_G m_iP2
Definition: gradientFlow.h:58
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
int fetch_int(const string &key, int &val) const
Definition: parameters.cpp:141
void set_parameters(const Parameters &params)
Field_G m_iP1
Definition: gradientFlow.h:58
static VerboseLevel set_verbose_level(const std::string &str)
Definition: bridgeIO.cpp:191
Field_G m_iPP
Definition: gradientFlow.h:58