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 void (*default_fermi_action)(fermi_field &,
00076 fermi_field &,
00077 gauge_field &,
00078 coefficients &,
00079 int) = FermiCloverActionFast::mul_Q;
00080
00082 void mul_Q(fermi_field &psi_out,
00083 fermi_field &psi_in,
00084 gauge_field &U,
00085 coefficients &coeff,
00086 int parity=EVENODD) {
00087 (*default_fermi_action)(psi_out, psi_in, U, coeff, parity);
00088 }
00089
00091 inversion_stats (*default_fermi_inverter)(fermi_field &,
00092 fermi_field &,
00093 gauge_field &,
00094 coefficients &,
00095 mdp_real,mdp_real,int)=MinRes::inverter<fermi_field,gauge_field>;
00096
00098 inversion_stats mul_invQ(fermi_field &psi_out,
00099 fermi_field &psi_in,
00100 gauge_field &U,
00101 coefficients &coeff,
00102 mdp_real absolute_precision=fermi_inversion_precision,
00103 mdp_real relative_precision=0,
00104 int max_steps=2000) {
00105 return (*default_fermi_inverter)(psi_out,
00106 psi_in,
00107 U,
00108 coeff,
00109 absolute_precision,
00110 relative_precision,
00111 max_steps);
00112 }
00113
00115 mdp_real check_inversion(fermi_field &phi,
00116 gauge_field &U,
00117 coefficients &coeff) {
00118 begin_function("check_inversion");
00119 fermi_field psi(phi.lattice(), phi.nc, phi.nspin);
00120 fermi_field chi(phi.lattice(), phi.nc, phi.nspin);
00121 site x(phi.lattice());
00122 int a,i;
00123 mdp_real precision=0;
00124 mul_Q(psi,phi,U,coeff);
00125 psi.update();
00126 mul_invQ(chi,psi,U,coeff);
00127 forallsites(x)
00128 for(a=0; a<phi.nspin; a++)
00129 for(i=0; i<phi.nc; i++)
00130 precision+=real(pow(phi(x,a,i)-chi(x,a,i),2));
00131 mpi.add(precision);
00132 precision/=phi.lattice().global_volume()*phi.nc*phi.nspin;
00133 mdp << "Inversion precision=" << precision << '\n';
00134 begin_function("end_inversion");
00135 return precision;
00136 }
00137