00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00014 void multiply_by_gamma5(fermi_field &r, fermi_field &s) {
00015 site x(r.lattice());
00016 #if defined(SSE2) && defined(USE_DOUBLE_PRECISION) && !defined(NO_SSE2_LINALG)
00017 if(r.nc==3) {
00018 _sse_spinor* a;
00019 _sse_spinor* b;
00020 _sse_spinor c;
00021 forallsites(x) {
00022 a=(_sse_spinor*) &s(x,0,0);
00023 b=(_sse_spinor*) &r(x,0,0);
00024
00025 _sse_double_load_up((*a).c1);
00026 _sse_double_vector_minus_i_mul();
00027 _sse_double_store_up(c.c3);
00028
00029 _sse_double_load_up((*a).c3);
00030 _sse_double_vector_i_mul();
00031 _sse_double_store_up((*b).c1);
00032 (*b).c3=c.c3;
00033
00034 _sse_double_load_up((*a).c2);
00035 _sse_double_vector_minus_i_mul();
00036 _sse_double_store_up(c.c4);
00037
00038 _sse_double_load_up((*a).c4);
00039 _sse_double_vector_i_mul();
00040 _sse_double_store_up((*b).c2);
00041 (*b).c4=c.c4;
00042 }
00043 return;
00044 }
00045 #endif
00046 uint i;
00047 mdp_complex tmp[4];
00048 mdp_complex c0=Gamma5_val[0];
00049 mdp_complex c1=Gamma5_val[1];
00050 mdp_complex c2=Gamma5_val[2];
00051 mdp_complex c3=Gamma5_val[3];
00052 int i0=Gamma5_idx[0];
00053 int i1=Gamma5_idx[1];
00054 int i2=Gamma5_idx[2];
00055 int i3=Gamma5_idx[3];
00056 forallsites(x) {
00057 for(i=0; i<3; i++) {
00058 tmp[i0]=c0*s(x,0,i);
00059 tmp[i1]=c1*s(x,1,i);
00060 tmp[i2]=c2*s(x,2,i);
00061 tmp[i3]=c3*s(x,3,i);
00062 r(x,0,i)=tmp[0];
00063 r(x,1,i)=tmp[1];
00064 r(x,2,i)=tmp[2];
00065 r(x,3,i)=tmp[3];
00066 }
00067 }
00068 }
00069
00070
00071
00072
00073
00075
00076 void (*default_fermi_action)(fermi_field &,
00077 fermi_field &,
00078 gauge_field &,
00079 coefficients &,
00080 int) = FermiCloverActionFast::mul_Q;
00081
00083 void mul_Q(fermi_field &psi_out,
00084 fermi_field &psi_in,
00085 gauge_field &U,
00086 coefficients &coeff,
00087 int parity=EVENODD) {
00088 (*default_fermi_action)(psi_out, psi_in, U, coeff, parity);
00089 }
00090
00092 inversion_stats (*default_fermi_inverter)(fermi_field &,
00093 fermi_field &,
00094 gauge_field &,
00095 coefficients &,
00096 mdp_real,mdp_real,int)=&(MinRes::inverter<fermi_field,gauge_field>);
00097
00099 inversion_stats mul_invQ(fermi_field &psi_out,
00100 fermi_field &psi_in,
00101 gauge_field &U,
00102 coefficients &coeff,
00103 mdp_real absolute_precision=fermi_inversion_precision,
00104 mdp_real relative_precision=0,
00105 int max_steps=2000) {
00106 return (*default_fermi_inverter)(psi_out,
00107 psi_in,
00108 U,
00109 coeff,
00110 absolute_precision,
00111 relative_precision,
00112 max_steps);
00113 }
00114
00116 mdp_real check_inversion(fermi_field &phi,
00117 gauge_field &U,
00118 coefficients &coeff) {
00119 begin_function("check_inversion");
00120 fermi_field psi(phi.lattice(), phi.nc, phi.nspin);
00121 fermi_field chi(phi.lattice(), phi.nc, phi.nspin);
00122 site x(phi.lattice());
00123 int a,i;
00124 mdp_real precision=0;
00125 mul_Q(psi,phi,U,coeff);
00126 psi.update();
00127 mul_invQ(chi,psi,U,coeff);
00128 forallsites(x)
00129 for(a=0; a<phi.nspin; a++)
00130 for(i=0; i<phi.nc; i++)
00131 precision+=real(pow(phi(x,a,i)-chi(x,a,i),2));
00132 mpi.add(precision);
00133 precision/=phi.lattice().global_volume()*phi.nc*phi.nspin;
00134 mdp << "Inversion precision=" << precision << '\n';
00135 begin_function("end_inversion");
00136 return precision;
00137 }
00138