Bridge++  Ver. 1.3.x
topologicalCharge.cpp
Go to the documentation of this file.
1 
14 #include "topologicalCharge.h"
15 
16 #ifdef USE_PARAMETERS_FACTORY
17 #include "parameters_factory.h"
18 #endif
19 
20 
21 //- parameter entries
22 namespace {
23  void append_entry(Parameters& param)
24  {
25  param.Register_double("c_plaq", 0.0);
26  param.Register_double("c_rect", 0.0);
27 
28  param.Register_string("verbose_level", "NULL");
29  }
30 
31 
32 #ifdef USE_PARAMETERS_FACTORY
33  bool init_param = ParametersFactory::Register("TopologicalCharge", append_entry);
34 #endif
35 }
36 //- end
37 
38 //- parameters class
40 //- end
41 
42 const std::string TopologicalCharge::class_name = "TopologicalCharge";
43 
44 //====================================================================
46 {
47  const string str_vlevel = params.get_string("verbose_level");
48 
49  m_vl = vout.set_verbose_level(str_vlevel);
50 
51  //- fetch and check input parameters
52  double c_plaq, c_rect;
53 
54  int err = 0;
55  err += params.fetch_double("c_plaq", c_plaq);
56  err += params.fetch_double("c_rect", c_rect);
57 
58  if (err) {
59  vout.crucial(m_vl, "%s: fetch error, input parameter not found.\n", class_name.c_str());
60  exit(EXIT_FAILURE);
61  }
62 
63 
64  set_parameters(c_plaq, c_rect);
65 }
66 
67 
68 //====================================================================
69 void TopologicalCharge::set_parameters(double c_plaq, double c_rect)
70 {
71  //- print input parameters
72  vout.general(m_vl, "Topological Charge measurement:\n");
73  vout.general(m_vl, " c_plaq = %12.6f\n", c_plaq);
74  vout.general(m_vl, " c_rect = %12.6f\n", c_rect);
75 
76  //- range check
77  // NB. beta,c_plaq,c_rect == 0 is allowed.
78 
79  //- store values
80  m_c_plaq = c_plaq;
81  m_c_rect = c_rect;
82 
83  //- post-process
84 }
85 
86 
87 //====================================================================
89 {
90  int Ndim = CommonParameters::Ndim();
91  int Nvol = CommonParameters::Nvol();
92  static const double PI = 4.0 * atan(1.0);
93  static const double PI2 = PI * PI;
94 
95  // NB. #(mu,nu)=6 i.e. (1,2),(1,3),(1,4),(2,3),(2,4),(3,4)
96  std::vector<Field_G> Fmunu_1x1(6), Fmunu_1x2(6);
97 
98 
99  vout.paranoiac(m_vl, "%s: measurement start.\n", class_name.c_str());
100 
101  int i_munu = 0;
102  for (int mu = 0; mu < Ndim; ++mu) {
103  for (int nu = mu + 1; nu < Ndim; ++nu) {
104  construct_Fmunu_1x1(Fmunu_1x1[i_munu], mu, nu, U);
105  construct_Fmunu_1x2(Fmunu_1x2[i_munu], mu, nu, U);
106 
107  ++i_munu;
108  }
109  }
110 
111 
112  double Q_1x1 = 0.0;
113 
114  // (mu,nu, rho,sigma) = (1,2, 3,4)
115  Q_1x1 += contract_epsilon_tensor(Fmunu_1x1[0], Fmunu_1x1[5]);
116 
117  // (mu,nu, rho,sigma) = (1,3, 2,4)
118  Q_1x1 -= contract_epsilon_tensor(Fmunu_1x1[1], Fmunu_1x1[4]);
119 
120  // (mu,nu, rho,sigma) = (1,4, 2,3)
121  Q_1x1 += contract_epsilon_tensor(Fmunu_1x1[2], Fmunu_1x1[3]);
122 
123  // #degeneracy of (mu,nu, rho,sigma) is 8
124  Q_1x1 *= 8.0;
125 
126 
127  double Q_1x2 = 0.0;
128  Q_1x2 += contract_epsilon_tensor(Fmunu_1x2[0], Fmunu_1x2[5]);
129  Q_1x2 -= contract_epsilon_tensor(Fmunu_1x2[1], Fmunu_1x2[4]);
130  Q_1x2 += contract_epsilon_tensor(Fmunu_1x2[2], Fmunu_1x2[3]);
131  Q_1x2 *= 8.0;
132 
133 
134  double Q_topo = (m_c_plaq * Q_1x1 + m_c_rect * Q_1x2 / 2.0) / (32.0 * PI2);
135 
136 
137 
138  vout.general(m_vl, " Q_1x1,Q_1x2 = %20.16e %20.16e\n",
139  Q_1x1 / (32.0 * PI2),
140  Q_1x2 / (2.0 * (32.0 * PI2)));
141 
142  vout.paranoiac(m_vl, "%s: measurement finished.\n", class_name.c_str());
143 
144 
145  return Q_topo;
146 }
147 
148 
149 //====================================================================
151  const int mu, const int nu, Field_G& U)
152 {
153  int Nvol = CommonParameters::Nvol();
154 
155  Staples staple;
156 
157  Field_G Cup(Nvol, 1), Cdn(Nvol, 1);
158  Field_G Umu(Nvol, 1);
159  Field_G v(Nvol, 1), v2(Nvol, 1);
160 
161 
162  //- building blocks
163  // (1) mu (2)
164  // +->-+
165  // nu | |
166  // i+ +
167  staple.upper(Cup, U, mu, nu);
168 
169  // (1) mu (2)
170  // i+ +
171  // nu | |
172  // +->-+
173  staple.lower(Cdn, U, mu, nu);
174  Umu.setpart_ex(0, U, mu);
175 
176 
177  //- right clover leaf
178  // (2) +-<-+
179  // nu | |
180  // i+->-+
181  // mu (1)
182  mult_Field_Gnd(Fmunu_1x1, 0, Umu, 0, Cup, 0);
183 
184  // (1) i+-<-+
185  // nu | |
186  // +->-+
187  // mu (2)
188  multadd_Field_Gnd(Fmunu_1x1, 0, Cdn, 0, Umu, 0, 1.0);
189 
190 
191  //- left clover leaf
192  // mu (2)
193  // +-<-+ (1)
194  // | | nu mu (1)
195  // +->-+i + +-<-+i (2)
196  // | | nu
197  // +->-+
198  mult_Field_Gdn(v, 0, Cup, 0, Umu, 0);
199  multadd_Field_Gdn(v, 0, Umu, 0, Cdn, 0, 1.0);
200 
201  // NB. shift.forward(mu)
202  // mu (2) mu (2)
203  // +-<-+ (1) +-<-+ (1)
204  // | | nu -> | | nu
205  // i+->-+ +->-+i
206  m_shift.forward(v2, v, mu);
207 
208  axpy(Fmunu_1x1, 1.0, v2);
209 
210  ah_Field_G(Fmunu_1x1, 0);
211 
212  scal(Fmunu_1x1, -0.25);
213  Fmunu_1x1.xI();
214 }
215 
216 
217 //====================================================================
219  const int mu, const int nu, Field_G& U)
220 {
221  int Nvol = CommonParameters::Nvol();
222 
223  Staples staple;
224 
225  Field_G Cup1(Nvol, 1), Cup2(Nvol, 1);
226  Field_G Cdn1(Nvol, 1), Cdn2(Nvol, 1);
227  Field_G Umu(Nvol, 1), Unu(Nvol, 1);
228  Field_G Umu_nu(Nvol, 1), Unu_mu(Nvol, 1);
229  Field_G rect(Nvol, 1);
230  Field_G v(Nvol, 1), w(Nvol, 1), c(Nvol, 1);
231 
232  //-- building blocks
233  // mu (2)
234  // (1) +->-+
235  // nu | |
236  // i+ +
237  staple.upper(Cup1, U, mu, nu);
238 
239  // +-<-+ (2)
240  // | nu
241  // i+->-+
242  // mu (1)
243  staple.upper(Cup2, U, nu, mu);
244 
245  // (1) i+ +
246  // nu | |
247  // +->-+
248  // mu (2)
249  staple.lower(Cdn1, U, mu, nu);
250 
251  // (2) +->-+
252  // nu |
253  // +-<-+i
254  // mu (1)
255  staple.lower(Cdn2, U, nu, mu);
256 
257  Umu.setpart_ex(0, U, mu);
258  Unu.setpart_ex(0, U, nu);
259 
260  // +->-+
261  //
262  // i+
263  m_shift.backward(Umu_nu, Umu, nu);
264 
265  // +
266  // |
267  // i+ +
268  m_shift.backward(Unu_mu, Unu, mu);
269 
270  //============================================================
271  //-- 2x1 part
272 
273  //- upper-right(2x1)
274  // +---<---+ + +-<-+ <---+
275  // nu | | = | + + | +
276  // i+--->---+ i+ i+ i+ >---+ i+->-+
277  m_shift.backward(c, Cup2, mu);
278 
279  mult_Field_Gdd(v, 0, Umu_nu, 0, Unu, 0);
280  mult_Field_Gnn(w, 0, c, 0, v, 0);
281 
282  mult_Field_Gnn(rect, 0, Umu, 0, w, 0);
283 
284  Fmunu_1x2 = rect;
285 
286  //- lower-right(2x1)
287  // (1) +---<---+ (1) i+---<---+
288  // nu | | -> nu | |
289  // i+--->---+ +--->---+
290  // mu (2) mu (2)
291  mult_Field_Gnd(v, 0, c, 0, Umu_nu, 0);
292  mult_Field_Gnn(w, 0, Umu, 0, v, 0);
293 
294  mult_Field_Gdn(rect, 0, Unu, 0, w, 0);
295 
296  m_shift.forward(v, rect, nu);
297 
298  axpy(Fmunu_1x2, 1.0, v);
299 
300  //- upper-left(2x1)
301  // mu (2)
302  // +---<---+ (1) +-<-+ +-<-+ +
303  // | | nu = + | + + |
304  // +---i---+ i+->-+ +->-+i +i +i +
305  //
306  // NB. shift.forward(mu)
307  // mu (2) mu (2)
308  // +---<---+ (1) +---<---+ (1)
309  // | | nu -> | | nu
310  // +---i---+ +--->---+i
311  mult_Field_Gdn(v, 0, Cdn2, 0, Umu, 0);
312  mult_Field_Gdn(w, 0, Umu_nu, 0, v, 0);
313 
314  mult_Field_Gnn(rect, 0, Unu_mu, 0, w, 0);
315 
316  m_shift.forward(v, rect, mu);
317 
318  axpy(Fmunu_1x2, 1.0, v);
319 
320  //- lower-left(2x1)
321  // mu (1)
322  // +---<---+ (2) + +-<-+ +-<-+
323  // | | nu = | + + | +
324  // +---i---+ +i + i+->-+ +->-+i +i
325  //
326  // NB. shift.forward(mu+nu)
327  // mu (1) mu (1) mu (1)
328  // +---<---+ (2) +---<---+ (2) +---<---+i (2)
329  // | | nu -> | | nu -> | | nu
330  // +---i---+ +--->---+i +--->---+
331  mult_Field_Gnn(v, 0, Umu, 0, Unu_mu, 0);
332  mult_Field_Gdn(w, 0, Cdn2, 0, v, 0);
333 
334  mult_Field_Gdn(rect, 0, Umu_nu, 0, w, 0);
335 
336  m_shift.forward(w, rect, mu);
337  m_shift.forward(v, w, nu);
338 
339  axpy(Fmunu_1x2, 1.0, v);
340  //============================================================
341 
342 
343  //============================================================
344  //-- 1x2 part
345 
346  //- upper-right(1x2)
347  // +-<-+ +-<-+
348  // | | | |
349  // (2) + + = + + + + + + +
350  // nu | | | |
351  // i+->-+ i+ i+ i+ + i+->-+
352  // mu (1)
353  m_shift.backward(c, Cup1, nu);
354 
355  mult_Field_Gdd(v, 0, c, 0, Unu, 0);
356  mult_Field_Gnn(w, 0, Unu_mu, 0, v, 0);
357 
358  mult_Field_Gnn(rect, 0, Umu, 0, w, 0);
359 
360  axpy(Fmunu_1x2, 1.0, rect);
361 
362  //- lower-right(1x2)
363  // mu (2)
364  // (1) +-<-+ +-<-+ + +
365  // nu | | | |
366  // i+ + = i+ + i+ + + i+ + + i+
367  // | | | |
368  // +->-+ +->-+
369  //
370  // NB. shift.forward(nu)
371  // mu (2) mu (2)
372  // (1) +-<-+ (1) i+-<-+
373  // nu | | nu | |
374  // i+ + -> + +
375  // | | | |
376  // +->-+ +->-+
377  mult_Field_Gnd(v, 0, Unu_mu, 0, Umu_nu, 0);
378  mult_Field_Gnn(w, 0, Cdn1, 0, v, 0);
379 
380  mult_Field_Gdn(rect, 0, Unu, 0, w, 0);
381 
382  m_shift.forward(v, rect, nu);
383 
384  axpy(Fmunu_1x2, 1.0, v);
385 
386  //- upper-left(1x2)
387  // +-<-+ +-<-+
388  // | | | |
389  // + + (1) = + + + + + + +
390  // | | nu | |
391  // i+->-+ i+->-+ i+ i+ i+ +
392  // mu (2)
393  //
394  // NB. shift.forward(mu)
395  // +-<-+ +-<-+
396  // | | | |
397  // + + (1) -> + + (1)
398  // | | nu | | nu
399  // i+->-+ +->-+i
400  // mu (2) mu (2)
401  mult_Field_Gdn(v, 0, Unu, 0, Umu, 0);
402  mult_Field_Gdn(w, 0, c, 0, v, 0);
403 
404  mult_Field_Gnn(rect, 0, Unu_mu, 0, w, 0);
405 
406  m_shift.forward(v, rect, mu);
407 
408  axpy(Fmunu_1x2, 1.0, v);
409 
410  //- lower-left(1x2)
411  // mu (1)
412  // (2) +-<-+ + + +-<-+
413  // nu | | | |
414  // i+ + = i+ + + i+ + + i+ + i+
415  // | | | |
416  // +->-+ +->-+
417  //
418  // NB. shift.forward(mu+nu)
419  // mu (1) mu (1)
420  // (2) +-<-+ (2) +-<-+i
421  // nu | | nu | |
422  // i+ + -> + +
423  // | | | |
424  // +->-+ +->-+
425  mult_Field_Gnn(v, 0, Cdn1, 0, Unu_mu, 0);
426  mult_Field_Gdn(w, 0, Unu, 0, v, 0);
427 
428  mult_Field_Gdn(rect, 0, Umu_nu, 0, w, 0);
429 
430  m_shift.forward(w, rect, mu);
431  m_shift.forward(v, w, nu);
432 
433  axpy(Fmunu_1x2, 1.0, v);
434  //============================================================
435 
436  ah_Field_G(Fmunu_1x2, 0);
437 
438  scal(Fmunu_1x2, -0.25);
439  Fmunu_1x2.xI();
440 }
441 
442 
443 //====================================================================
445 {
446  int Nvol = CommonParameters::Nvol();
447 
448  double Q_topo = 0.0;
449 
450  for (int site = 0; site < Nvol; ++site) {
451  Q_topo += ReTr(Fmunu_1.mat(site) * Fmunu_2.mat(site));
452  }
453  double result = Communicator::reduce_sum(Q_topo);
454 
455  return result;
456 }
457 
458 
459 //====================================================================
460 //============================================================END=====
void scal(Field &x, const double a)
scal(x, a): x = a * x
Definition: field.cpp:282
BridgeIO vout
Definition: bridgeIO.cpp:278
void Register_string(const string &, const string &)
Definition: parameters.cpp:351
Staple construction.
Definition: staples.h:40
void mult_Field_Gdn(Field_G &w, const int ex, const Field_G &u1, const int ex1, const Field_G &u2, const int ex2)
static const std::string class_name
void general(const char *format,...)
Definition: bridgeIO.cpp:65
double measure(Field_G &U)
main function to measure Topological Charge.
ShiftField_lex m_shift
void construct_Fmunu_1x2(Field_G &Fmunu, int mu, int nu, Field_G &U)
void construct_Fmunu_1x1(Field_G &Fmunu, int mu, int nu, Field_G &U)
Class for parameters.
Definition: parameters.h:38
void mult_Field_Gdd(Field_G &w, const int ex, const Field_G &u1, const int ex1, const Field_G &u2, const int ex2)
double contract_epsilon_tensor(Field_G &Fmunu_1, Field_G &Fmunu_2)
void ah_Field_G(Field_G &w, const int ex)
SU(N) gauge field.
Definition: field_G.h:38
void multadd_Field_Gdn(Field_G &w, const int ex, const Field_G &u1, const int ex1, const Field_G &u2, const int ex2, const double ff)
void mult_Field_Gnd(Field_G &w, const int ex, const Field_G &u1, const int ex1, const Field_G &u2, const int ex2)
void mult_Field_Gnn(Field_G &w, const int ex, const Field_G &u1, const int ex1, const Field_G &u2, const int ex2)
void backward(Field &, const Field &, const int mu)
void paranoiac(const char *format,...)
Definition: bridgeIO.cpp:99
void multadd_Field_Gnd(Field_G &w, const int ex, const Field_G &u1, const int ex1, const Field_G &u2, const int ex2, const double ff)
void axpy(Field &y, const double a, const Field &x)
axpy(y, a, x): y := a * x + y
Definition: field.cpp:168
void crucial(const char *format,...)
Definition: bridgeIO.cpp:48
void lower(Field_G &, const Field_G &, const int mu, const int nu)
constructs lower staple in mu-nu plane.
Definition: staples.cpp:152
static bool Register(const std::string &realm, const creator_callback &cb)
Bridge::VerboseLevel m_vl
virtual void set_parameters(const Parameters &params)
setting parameters.
static int reduce_sum(int count, double *recv_buf, double *send_buf, int pattern=0)
make a global sum of an array of double over the communicator. pattern specifies the dimensions to be...
void Register_double(const string &, const double)
Definition: parameters.cpp:323
void setpart_ex(int ex, const Field &w, int exw)
Definition: field.h:177
int fetch_double(const string &key, double &val) const
Definition: parameters.cpp:124
string get_string(const string &key) const
Definition: parameters.cpp:87
Mat_SU_N mat(const int site, const int mn=0) const
Definition: field_G.h:113
void upper(Field_G &, const Field_G &, const int mu, const int nu)
constructs upper staple in mu-nu plane.
Definition: staples.cpp:128
static VerboseLevel set_verbose_level(const std::string &str)
Definition: bridgeIO.cpp:28
double ReTr(const Mat_SU_N &m)
Definition: mat_SU_N.h:488
void forward(Field &, const Field &, const int mu)
void xI()
Definition: field_G.h:183