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