Bridge++  Version 1.4.4
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
projection_Stout_SU3.cpp
Go to the documentation of this file.
1 
14 #include "projection_Stout_SU3.h"
15 
16 
17 #ifdef USE_FACTORY
18 namespace {
19  Projection *create_object()
20  {
21  return new Projection_Stout_SU3();
22  }
23 
24 
25  bool init = Projection::Factory::Register("Stout_SU3", create_object);
26 }
27 #endif
28 
29 
30 
31 const std::string Projection_Stout_SU3::class_name = "Projection_Stout_SU3";
32 
33 //====================================================================
35 {
36  const string str_vlevel = params.get_string("verbose_level");
37 
38  m_vl = vout.set_verbose_level(str_vlevel);
39 }
40 
41 
42 //====================================================================
44 {
45  m_flop = 0;
46  m_time = 0.0;
47 
48  assert(CommonParameters::Nc() == NC);
49 }
50 
51 
52 //====================================================================
54 {
55  double gflops = 1.e-9 * double(m_flop) / m_time;
56 
57  vout.general(m_vl, "%s:\n", class_name.c_str());
58  vout.general(m_vl, " total time: %f\n", m_time);
59  vout.general(m_vl, " total flop: %d\n", m_flop);
60  vout.general(m_vl, " GFlops : %f\n", gflops);
61 }
62 
63 
64 //====================================================================
66  double alpha,
67  const Field_G& Cst, const Field_G& Uorg)
68 {
69  // int id = 31;
70  // KEK_FopCountStart(id);
71  double time0 = Communicator::get_time();
72 
73  // in stout projection, parameter alpha is dummy.
74 
75  int Nex = Uorg.nex();
76  int Nvol = Uorg.nvol();
77 
78  assert(Cst.nex() == Nex);
79  assert(Cst.nvol() == Nvol);
80  assert(U.nex() == Nex);
81  assert(U.nvol() == Nvol);
82 
83  int NinG = Uorg.nin();
84 
85  Mat_SU_N iQ0(NC), iQ1(NC), iQ2(NC), iQ3(NC);
86  Mat_SU_N ct(NC), ut(NC), ut2(NC), e_iQ(NC);
87  iQ0.unit();
88 
89  double u, w;
90  dcomplex f0, f1, f2;
91 
92  for (int mu = 0; mu < Nex; ++mu) {
93  for (int site = 0; site < Nvol; ++site) {
94  Uorg.mat(ut, site, mu);
95  Cst.mat(ct, site, mu);
96  iQ1.mult_nd(ct, ut);
97  iQ1.at();
98  iQ2.mult_nn(iQ1, iQ1);
99  iQ3.mult_nn(iQ1, iQ2);
100 
101  double norm = iQ1.norm2();
102  if (norm > 1.0e-10) {
103  set_uw(u, w, iQ2, iQ3);
104  set_fj(f0, f1, f2, u, w);
105 
106  for (int cc = 0; cc < NC * NC; ++cc) {
107  dcomplex qt = f0 * cmplx(iQ0.r(cc), iQ0.i(cc))
108  + f1 * cmplx(iQ1.i(cc), -iQ1.r(cc))
109  - f2 * cmplx(iQ2.r(cc), iQ2.i(cc));
110  e_iQ.set_r(cc, real(qt));
111  e_iQ.set_i(cc, imag(qt));
112  }
113  } else {
114  // vout.general(m_vl,"project: |iQ1|^2 too small: %lf. Set e_iQ=1.\n",norm);
115  e_iQ.unit();
116  }
117 
118  ut2.mult_nn(e_iQ, ut);
119  U.set_mat(site, mu, ut2);
120  }
121  }
122 
123  /*
124  unsigned long count;
125  double time;
126  KEK_FopCountFinish(id,&count,&time);
127  m_time += time;
128  m_flop += count;
129  */
130  double time1 = Communicator::get_time();
131  m_time += time1 - time0;
132 }
133 
134 
135 //====================================================================
137 {
138  int Nvol = iQ.nvol();
139  int Nex = iQ.nex();
140 
141  Mat_SU_N iQ0(NC), iQ1(NC), iQ2(NC), iQ3(NC);
142 
143  iQ0.unit();
144 
145  double u, w;
146  dcomplex f0, f1, f2;
147 
148  for (int mu = 0; mu < Nex; ++mu) {
149  for (int site = 0; site < Nvol; ++site) {
150  iQ1 = iQ.mat(site, mu);
151  iQ2 = iQ1 * iQ1;
152  iQ3 = iQ1 * iQ2;
153 
154  double norm = iQ1.norm2();
155  if (norm > 1.0e-10) {
156  set_uw(u, w, iQ2, iQ3);
157  set_fj(f0, f1, f2, u, w);
158 
159  for (int cc = 0; cc < NC * NC; ++cc) {
160  dcomplex qt = f0 * cmplx(iQ0.r(cc), iQ0.i(cc))
161  + f1 * cmplx(iQ1.i(cc), -iQ1.r(cc))
162  - f2 * cmplx(iQ2.r(cc), iQ2.i(cc));
163  e_iQ.set_ri(cc, site, mu, real(qt), imag(qt));
164  }
165  } else {
166  // vout.general(m_vl,"exp_iQ: |iQ1|^2 too small: %lf. Set e_iQ=1.\n",norm);
167  e_iQ.set_mat(site, mu, iQ0);
168  }
169  }
170  }
171 }
172 
173 
174 //====================================================================
175 
188 //====================================================================
190  double alpha, const Field_G& Sigmap,
191  const Field_G& Cst, const Field_G& Uorg)
192 {
193  // in stout projection, parameter alpha is dummy.
194 
195  // int id = 31;
196  // KEK_FopCountStart(id);
197  double time0 = Communicator::get_time();
198 
199  int Nvol = CommonParameters::Nvol();
200  // int NinG = 2 * NC * NC;
201  int Nex = Xi.nex();
202 
203  assert(Xi.nvol() == Nvol);
204  assert(iTheta.nvol() == Nvol);
205  assert(Sigmap.nvol() == Nvol);
206  assert(Cst.nvol() == Nvol);
207  assert(Uorg.nvol() == Nvol);
208  assert(iTheta.nex() == Nex);
209  assert(Sigmap.nex() == Nex);
210  assert(Cst.nex() == Nex);
211  assert(Uorg.nex() == Nex);
212 
213  Mat_SU_N C_tmp(NC), U_tmp(NC), Sigmap_tmp(NC);
214  Mat_SU_N iQ0(NC), iQ1(NC), iQ2(NC), iQ3(NC), e_iQ(NC);
215  Mat_SU_N B1(NC), B2(NC);
216  Mat_SU_N USigmap(NC), iQUS(NC), iUSQ(NC), iGamma(NC);
217  Mat_SU_N Xi_tmp(NC), iTheta_tmp(NC);
218  Mat_SU_N tmp1(NC), tmp2(NC);
219  iQ0.unit();
220 
221  double u, w;
222  dcomplex f0, f1, f2;
223 
224  for (int mu = 0; mu < Nex; ++mu) {
225  for (int site = 0; site < Nvol; ++site) {
227  Cst.mat(C_tmp, site, mu);
229  Uorg.mat(U_tmp, site, mu);
230  // Sigmap_tmp \f$=\Sigma_\mu'(x)\f$
231  Sigmap.mat(Sigmap_tmp, site, mu);
232 
234  iQ1.mult_nd(C_tmp, U_tmp);
235  iQ1.at();
236  iQ2.mult_nn(iQ1, iQ1);
237  iQ3.mult_nn(iQ1, iQ2);
238 
239  // In order to aviod 1Q1=0
240  double norm = iQ1.norm2();
241  if (norm > 1.0e-10) {
242  set_uw(u, w, iQ2, iQ3);
243  set_fj(f0, f1, f2, u, w);
244 
245  for (int cc = 0; cc < NC * NC; ++cc) {
246  dcomplex qt = f0 * cmplx(iQ0.r(cc), iQ0.i(cc))
247  + f1 * cmplx(iQ1.i(cc), -iQ1.r(cc))
248  - f2 * cmplx(iQ2.r(cc), iQ2.i(cc));
249  e_iQ.set(cc, real(qt), imag(qt));
250  }
251 
252  double xi0 = func_xi0(w);
253  double xi1 = func_xi1(w);
254  double u2 = u * u;
255  double w2 = w * w;
256  double cos_w = cos(w);
257 
258  dcomplex emiu = cmplx(cos(u), -sin(u));
259  dcomplex e2iu = cmplx(cos(2.0 * u), sin(2.0 * u));
260 
261  dcomplex r01 = cmplx(2.0 * u, 2.0 * (u2 - w2)) * e2iu
262  + emiu * cmplx(16.0 * u * cos_w + 2.0 * u * (3.0 * u2 + w2) * xi0,
263  -8.0 * u2 * cos_w + 2.0 * (9.0 * u2 + w2) * xi0);
264 
265  dcomplex r11 = cmplx(2.0, 4.0 * u) * e2iu
266  + emiu * cmplx(-2.0 * cos_w + (3.0 * u2 - w2) * xi0,
267  2.0 * u * cos_w + 6.0 * u * xi0);
268 
269  dcomplex r21 = cmplx(0.0, 2.0) * e2iu
270  + emiu * cmplx(-3.0 * u * xi0, cos_w - 3.0 * xi0);
271 
272  dcomplex r02 = cmplx(-2.0, 0.0) * e2iu
273  + emiu * cmplx(-8.0 * u2 * xi0,
274  2.0 * u * (cos_w + xi0 + 3.0 * u2 * xi1));
275 
276  dcomplex r12 = emiu * cmplx(2.0 * u * xi0,
277  -cos_w - xi0 + 3.0 * u2 * xi1);
278 
279  dcomplex r22 = emiu * cmplx(xi0, -3.0 * u * xi1);
280 
281  double fden = 1.0 / (2 * (9.0 * u2 - w2) * (9.0 * u2 - w2));
282 
283  dcomplex b10 = cmplx(2.0 * u, 0.0) * r01 + cmplx(3.0 * u2 - w2, 0.0) * r02
284  - cmplx(30.0 * u2 + 2.0 * w2, 0.0) * f0;
285  dcomplex b11 = cmplx(2.0 * u, 0.0) * r11 + cmplx(3.0 * u2 - w2, 0.0) * r12
286  - cmplx(30.0 * u2 + 2.0 * w2, 0.0) * f1;
287  dcomplex b12 = cmplx(2.0 * u, 0.0) * r21 + cmplx(3.0 * u2 - w2, 0.0) * r22
288  - cmplx(30.0 * u2 + 2.0 * w2, 0.0) * f2;
289 
290  dcomplex b20 = r01 - cmplx(3.0 * u, 0.0) * r02 - cmplx(24.0 * u, 0.0) * f0;
291  dcomplex b21 = r11 - cmplx(3.0 * u, 0.0) * r12 - cmplx(24.0 * u, 0.0) * f1;
292  dcomplex b22 = r21 - cmplx(3.0 * u, 0.0) * r22 - cmplx(24.0 * u, 0.0) * f2;
293 
294  b10 *= cmplx(fden, 0.0);
295  b11 *= cmplx(fden, 0.0);
296  b12 *= cmplx(fden, 0.0);
297  b20 *= cmplx(fden, 0.0);
298  b21 *= cmplx(fden, 0.0);
299  b22 *= cmplx(fden, 0.0);
300 
301  for (int cc = 0; cc < NC * NC; ++cc) {
302  dcomplex qt1 = b10 * cmplx(iQ0.r(cc), iQ0.i(cc))
303  + b11 * cmplx(iQ1.i(cc), -iQ1.r(cc))
304  - b12 * cmplx(iQ2.r(cc), iQ2.i(cc));
305  B1.set(cc, real(qt1), imag(qt1));
306 
307  dcomplex qt2 = b20 * cmplx(iQ0.r(cc), iQ0.i(cc))
308  + b21 * cmplx(iQ1.i(cc), -iQ1.r(cc))
309  - b22 * cmplx(iQ2.r(cc), iQ2.i(cc));
310  B2.set(cc, real(qt2), imag(qt2));
311  }
312 
313  USigmap.mult_nn(U_tmp, Sigmap_tmp);
314 
315  tmp1.mult_nn(USigmap, B1);
316  tmp2.mult_nn(USigmap, B2);
317 
318  dcomplex tr1 = cmplx(tmp1.r(0) + tmp1.r(4) + tmp1.r(8),
319  tmp1.i(0) + tmp1.i(4) + tmp1.i(8));
320  dcomplex tr2 = cmplx(tmp2.r(0) + tmp2.r(4) + tmp2.r(8),
321  tmp2.i(0) + tmp2.i(4) + tmp2.i(8));
322 
323  iQUS.mult_nn(iQ1, USigmap);
324  iUSQ.mult_nn(USigmap, iQ1);
325 
326  for (int cc = 0; cc < NC * NC; ++cc) {
327  dcomplex qt = tr1 * cmplx(iQ1.i(cc), -iQ1.r(cc))
328  - tr2 * cmplx(iQ2.r(cc), iQ2.i(cc))
329  + f1 * cmplx(USigmap.r(cc), USigmap.i(cc))
330  + f2 * cmplx(iQUS.i(cc), -iQUS.r(cc))
331  + f2 * cmplx(iUSQ.i(cc), -iUSQ.r(cc));
332  iGamma.set(cc, -imag(qt), real(qt));
333  }
334  } else {
335  // vout.general(m_vl,"force_recursive: |iQ1|^2 too small: %lf. Set e_iQ=1.\n",norm);
336  iGamma.zero();
337  e_iQ.unit();
338  }
339 
341  iGamma.at();
342  iTheta_tmp.mult_nn(iGamma, U_tmp);
344  iTheta.set_mat(site, mu, iTheta_tmp);
345 
346  Xi_tmp.mult_nn(Sigmap_tmp, e_iQ);
347  Xi_tmp.multadd_dn(C_tmp, iGamma);
349  Xi.set_mat(site, mu, Xi_tmp);
350  }
351  }
352 
353  /*
354  unsigned long count;
355  double time;
356  KEK_FopCountFinish(id,&count,&time);
357  m_time += time;
358  m_flop += count;
359  */
360  double time1 = Communicator::get_time();
361  m_time += time1 - time0;
362 }
363 
364 
365 //====================================================================
366 void Projection_Stout_SU3::set_fj(dcomplex& f0, dcomplex& f1, dcomplex& f2,
367  const double& u, const double& w)
368 {
369  double xi0 = func_xi0(w);
370  double u2 = u * u;
371  double w2 = w * w;
372  double cos_w = cos(w);
373 
374  double cos_u = cos(u);
375  double sin_u = sin(u);
376 
377  dcomplex emiu = cmplx(cos_u, -sin_u);
378  dcomplex e2iu = cmplx(cos_u * cos_u - sin_u * sin_u, 2.0 * sin_u * cos_u);
379 
380  dcomplex h0 = e2iu * cmplx(u2 - w2, 0.0)
381  + emiu * cmplx(8.0 * u2 * cos_w, 2.0 * u * (3.0 * u2 + w2) * xi0);
382  dcomplex h1 = cmplx(2 * u, 0.0) * e2iu
383  - emiu * cmplx(2.0 * u * cos_w, -(3.0 * u2 - w2) * xi0);
384  dcomplex h2 = e2iu - emiu * cmplx(cos_w, 3.0 * u * xi0);
385 
386  double fden = 1.0 / (9.0 * u2 - w2);
387 
388  //- output
389  f0 = h0 * fden;
390  f1 = h1 * fden;
391  f2 = h2 * fden;
392 }
393 
394 
395 //====================================================================
396 void Projection_Stout_SU3::set_uw(double& u, double& w,
397  const Mat_SU_N& iQ2, const Mat_SU_N& iQ3)
398 {
399  double c0 = -(iQ3.i(0, 0) + iQ3.i(1, 1) + iQ3.i(2, 2)) / 3.0;
400  double c1 = -0.5 * (iQ2.r(0, 0) + iQ2.r(1, 1) + iQ2.r(2, 2));
401  double c13r = sqrt(c1 / 3.0);
402  double c0max = 2.0 * c13r * c13r * c13r;
403 
404  double theta = acos(c0 / c0max);
405 
406  //- output
407  u = c13r * cos(theta / 3.0);
408  w = sqrt(c1) * sin(theta / 3.0);
409 }
410 
411 
412 //====================================================================
414 {
415  if (w == 0.0) {
416  return 1.0;
417  } else {
418  return sin(w) / w;
419  }
420 }
421 
422 
423 //====================================================================
425 {
426  if (w < 0.25) {
427  double w2 = w * w;
428  static double c0 = -1.0 / 3.0;
429  static double c1 = 1.0 / 30.0;
430  static double c2 = -1.0 / 840.0;
431  static double c3 = 1.0 / 45360.0;
432  static double c4 = -1.0 / 3991680.0;
433 
434  return c0 + w2 * (c1 + w2 * (c2 + w2 * (c3 + w2 * c4)));
435  } else {
436  return (w * cos(w) - sin(w)) / (w * w * w);
437  }
438 }
439 
440 
441 //====================================================================
443 {
444  // brute force version of exponentiation: for check
445 
446  int Nprec = 32;
447 
448  int Nvol = iQ.nvol();
449  int Nex = iQ.nex();
450 
451  Mat_SU_N u0(NC), u1(NC), u2(NC);
452  Mat_SU_N h1(NC);
453 
454  for (int ex = 0; ex < Nex; ++ex) {
455  for (int site = 0; site < Nvol; ++site) {
456  u0.unit();
457  u1.unit();
458  h1 = iQ.mat(site, ex);
459 
460  for (int iprec = 0; iprec < Nprec; ++iprec) {
461  double exf = 1.0 / (Nprec - iprec);
462  u2 = h1 * u1;
463  u2 *= exf;
464  u1 = u2;
465  u1 += u0;
466  }
467 
468  u1.reunit();
469  e_iQ.set_mat(site, ex, u1);
470  }
471  }
472 }
473 
474 
475 //====================================================================
476 //============================================================END=====
BridgeIO vout
Definition: bridgeIO.cpp:495
double i(int c) const
Definition: mat_SU_N.h:115
unsigned long int m_flop
void general(const char *format,...)
Definition: bridgeIO.cpp:195
Mat_SU_N & zero()
Definition: mat_SU_N.h:383
int nvol() const
Definition: field.h:116
void force_recursive(Field_G &Xi, Field_G &iTheta, double alpha, const Field_G &Sigmap, const Field_G &C, const Field_G &U)
determination of fields for force calculation
void set_uw(double &u, double &w, const Mat_SU_N &iQ1, const Mat_SU_N &iQ2)
Class for parameters.
Definition: parameters.h:46
Mat_SU_N & at()
antihermitian traceless
Definition: mat_SU_N.h:329
#define NC
Mat_SU_N & reunit()
Definition: mat_SU_N.h:71
void set_i(int c, const double &im)
Definition: mat_SU_N.h:121
int nin() const
Definition: field.h:115
void project(Field_G &U, double alpha, const Field_G &C, const Field_G &Uorg)
projection U = P[alpha, C, Uorg]
void set_r(int c, const double &re)
Definition: mat_SU_N.h:120
SU(N) gauge field.
Definition: field_G.h:38
int nex() const
Definition: field.h:117
void mult_nd(const Mat_SU_N &u1, const Mat_SU_N &u2)
Definition: mat_SU_N.h:197
void set_fj(dcomplex &f0, dcomplex &f1, dcomplex &f2, const double &u, const double &w)
double norm2()
Definition: mat_SU_N.h:155
base class for projection operator into gauge group.
Definition: projection.h:31
void set_parameters(const Parameters &param)
void exp_iQ(Field_G &e_iQ, const Field_G &iQ)
void exp_iQ_bf(Field_G &e_iQ, const Field_G &iQ)
static const std::string class_name
static double get_time()
obtain a wall-clock time.
Mat_SU_N & unit()
Definition: mat_SU_N.h:373
double r(int c) const
Definition: mat_SU_N.h:114
void set(int c, double re, const double &im)
Definition: mat_SU_N.h:133
string get_string(const string &key) const
Definition: parameters.cpp:116
void set_mat(const int site, const int mn, const Mat_SU_N &U)
Definition: field_G.h:159
Stout(exponential)-type projection to SU(N) gauge group.
Mat_SU_N mat(const int site, const int mn=0) const
Definition: field_G.h:113
void mult_nn(const Mat_SU_N &u1, const Mat_SU_N &u2)
Definition: mat_SU_N.h:163
static VerboseLevel set_verbose_level(const std::string &str)
Definition: bridgeIO.cpp:131
Bridge::VerboseLevel m_vl
Definition: projection.h:34
void set_ri(const int cc, const int site, const int mn, const double re, const double im)
Definition: field_G.h:106