00001
00009
00010 #include <config.h>
00011 #include <math.h>
00012 #include <util/qcdio.h>
00013 #include <alg/alg_smear2.h>
00014 #include <util/lattice.h>
00015 #include <util/gjp.h>
00016 #include <util/error.h>
00017 #include <util/site.h>
00018 #include <util/link_buffer.h>
00019 #include <util/smalloc.h>
00020
00021 CPS_START_NAMESPACE
00022
00027 void sub( Matrix& x, Matrix& y , int ind )
00028 {
00029
00030 const int su2_index[][3]= { {0,1,2},
00031 {0,2,1},
00032 {1,2,0} };
00033 y=x;
00034 const int zero_rc(su2_index[ind][2]);
00035 const int i1 (su2_index[ind][0]);
00036 const int i2 (su2_index[ind][1]);
00037
00038 int i;
00039 for (i=0;i<3;i++) { y(zero_rc,i)=Complex(0,0); }
00040 for (i=0;i<3;i++) { y(i,zero_rc)=Complex(0,0); }
00041 y(zero_rc,zero_rc)=Complex(1,0);
00042
00043 Float p0(x(i1,i1).real() + x(i2,i2).real());
00044 Float p1(x(i1,i2).imag() + x(i2,i1).imag());
00045 Float p2(x(i1,i2).real() - x(i2,i1).real());
00046 Float p3(x(i1,i1).imag() - x(i2,i2).imag());
00047 const Float psqr( sqrt(p0*p0 + p1*p1 + p2*p2 + p3*p3) );
00048 Float ipsqr;
00049 if ( psqr == 0. ) { ipsqr=1; }
00050 else { ipsqr=1/psqr;}
00051 p0*=ipsqr; p1*=ipsqr; p2*=ipsqr; p3*=ipsqr;
00052
00053 y(i1,i1) = Complex( p0,-p3);
00054 y(i2,i2) = Complex( p0, p3);
00055 y(i1,i2) = Complex(-p2,-p1);
00056 y(i2,i1) = Complex( p2,-p1);
00057 }
00058
00059 int su3_proj( Matrix& x , Float tolerance )
00060 {
00061
00062
00063
00064 const int max_iter(10000);
00065 Matrix tmp ;
00066 Matrix inv ;
00067 Matrix y ;
00068 Matrix ycopy;
00069 Matrix xdag ; xdag.Dagger(x);
00070 y.UnitMatrix();
00071 tmp = xdag;
00072 Float old_tr( xdag.ReTr() );
00073 int i,j;
00074 for (i=0;i<max_iter;i++)
00075 {
00076
00077 Float diff(-1);
00078 for (j=0;j<3;j++)
00079 {
00080 sub(tmp,inv,j);
00081 ycopy = y ;
00082 y .DotMEqual( inv, ycopy );
00083 tmp.DotMEqual( y, xdag );
00084 const Float tr (tmp.ReTr());
00085 const Float dtr(tr-old_tr );
00086 if ( dtr > diff ) { diff = dtr ; }
00087 old_tr = tr;
00088 }
00089
00090
00091 if (diff < tolerance) { break; }
00092 }
00093 if ( i == max_iter )
00094 {
00095
00096 ERR.General("","su3_proj","Max iterations");
00097 }
00098 x=y;
00099 return i;
00100 }
00101
00109 AlgSmear2::AlgSmear2( Lattice& lat,
00110 CommonArg* ca ,
00111 int su3_proj ):
00112 Alg(lat,ca),
00113 bool_su3_proj(su3_proj),
00114 tolerance (1e-6),
00115 orthog (-1)
00116 {
00117 cname = "AlgSmear2";
00118 lat_back = new Matrix[GJP.VolNodeSites()*4];
00119 if ( lat_back == 0x0 ) { ERR.Pointer(cname, cname,"lat_back"); }
00120 }
00121
00122 AlgSmear2::~AlgSmear2()
00123 {
00124 delete[] lat_back;
00125 }
00126
00127
00128 void AlgSmear2::run()
00129 {
00130 Lattice& lattice(AlgLattice());
00131
00132
00133
00134
00135
00136
00137 lattice.CopyGaugeField(lat_back);
00138
00139 Site nloop;
00140
00141 while ( nloop.LoopsOverNode() )
00142 {
00143 int mu;
00144
00145 for (mu=0;mu<3;++mu)
00146 {
00147
00148
00149
00150 if ( mu != get_orthog() )
00151 {
00152
00153
00154
00155 Matrix& link(*(lat_back + 4*nloop.Index() + mu ));
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165 smear_link2(link,nloop.pos(),mu);
00166
00167
00168
00169 if ( bool_su3_proj ) { su3_proj( link , tolerance ); }
00170 }
00171 }
00172 }
00173
00174
00175
00176 lattice.GaugeField(lat_back);
00177 lattice.ClearAllBufferedLink();
00178
00179 }
00180
00188 void three_staple2( Lattice& latt, Matrix& link ,
00189 int *pos, int u, int orth )
00190 {
00191 Matrix acumulate_mp; acumulate_mp.ZeroMatrix();
00192 int dir[3];
00193
00194
00195 for ( int v=0; v<8; v++ )
00196 {
00197
00198
00199 if((v&3) == u) continue;
00200 if((v&3) == orth) continue;
00201 if((v&3) == 3) continue;
00202
00203 const int v1((v+4)&7);
00204
00205 dir[0] = v;
00206 dir[1] = u;
00207 dir[2] = v1;
00208
00209 latt.PathOrdProdPlus(acumulate_mp, pos, dir, 3);
00210 }
00211
00212 moveMem((Float *) &link, (Float*)&acumulate_mp, 18*sizeof(Float));
00213 }
00214
00215 AlgApeSmear2::AlgApeSmear2(Lattice& lat,
00216 CommonArg* ca ,
00217 ApeSmearArg* asa ):
00218 AlgSmear2(lat,ca,1),
00219 cname("AlgApeSmear2")
00220 {
00221 c = asa->coef;
00222 set_tol (asa->tolerance);
00223 set_orthog(asa->orthog);
00224 }
00225
00231 void AlgApeSmear2::run()
00232 {
00233 if(common_arg->filename != 0){
00234 FILE* f = Fopen(common_arg->filename, "a");
00235 if(!f) ERR.FileA(cname, "run", common_arg->filename);
00236 Fprintf(f,"AlgApeSmear2: coef = %e \n",c);
00237 Fclose(f);
00238 }
00239 AlgSmear2::run();
00240 }
00241
00242
00243
00244 void AlgApeSmear2::smear_link2(Matrix& link,
00245 int* pos,
00246 int mu)
00247 {
00248 Lattice& lattice(AlgLattice());
00249 Matrix stap;
00250 three_staple2(lattice,stap,pos,mu,get_orthog());
00251 link*=(1.0-c);
00252 stap*=c/6.0;
00253 link+=stap;
00254 }
00255
00256 CPS_END_NAMESPACE