00001 #include<config.h> 00002 CPS_START_NAMESPACE 00003 //-------------------------------------------------------------------- 00004 // CVS keywords 00005 // 00006 // $Author: zs $ 00007 // $Date: 2004/08/18 11:57:39 $ 00008 // $Header: /space/cvs/cps/cps++/src/alg/alg_pot/alg_pot.C,v 1.8 2004/08/18 11:57:39 zs Exp $ 00009 // $Id: alg_pot.C,v 1.8 2004/08/18 11:57:39 zs Exp $ 00010 // $Name: v5_0_8 $ 00011 // $Locker: $ 00012 // $RCSfile: alg_pot.C,v $ 00013 // $Revision: 1.8 $ 00014 // $Source: /space/cvs/cps/cps++/src/alg/alg_pot/alg_pot.C,v $ 00015 // $State: Exp $ 00016 // 00017 //-------------------------------------------------------------------- 00018 // last modification: manke, Feb 1, 2001 00019 // 1. changes Vst --> Vts (for consistency) 00020 // 2. explicitly transfer max_XYZT in pot_arg 00021 // 3. print out potentials V(x,y,z,t) separately for x,y,z 00022 // 4. changed V?? (potential) --> W?? (wilson loop) 00023 //------------------------------------------------------------------ 00024 // 00025 // alg_pot.C 00026 // 00027 // AlgPot is derived from Alg and it measures the potential 00028 // into different propagation directions 00029 // 00030 //------------------------------------------------------------------ 00031 00032 CPS_END_NAMESPACE 00033 #include <util/qcdio.h> 00034 #include <alg/alg_pot.h> 00035 #include <util/lattice.h> 00036 #include <util/gjp.h> 00037 #include <util/smalloc.h> 00038 #include <util/vector.h> // Tr() and ReTr() 00039 #include <util/verbose.h> 00040 #include <util/error.h> 00041 #include <comms/glb.h> 00042 CPS_START_NAMESPACE 00043 00044 // #define max(A, B) ((A) > (B) ? (A) : (B)) 00045 // #define min(A, B) ((A) < (B) ? (A) : (B)) 00046 00047 //------------------------------------------------------------------ 00048 // Constructor 00049 //------------------------------------------------------------------ 00050 AlgPot::AlgPot(Lattice& latt, 00051 CommonArg *c_arg, 00052 PotArg *arg) : 00053 Alg(latt, c_arg) 00054 { 00055 cname = "AlgPot"; 00056 char *fname = "AlgPot(L&,CommonArg*,PotArg*)"; 00057 VRB.Func(cname,fname); 00058 00059 // Initialize the argument pointer 00060 //---------------------------------------------------------------- 00061 if(arg == 0) 00062 ERR.Pointer(cname,fname, "arg"); 00063 alg_pot_arg = arg; 00064 00065 // Calculate normalization factor for each processor 00066 //---------------------------------------------------------------- 00067 00068 int total_sites = GJP.VolNodeSites() * GJP.Xnodes() * 00069 GJP.Ynodes() * GJP.Znodes() * GJP.Tnodes(); 00070 int int_norm = GJP.Colors()*total_sites; 00071 00072 norm_fac = 1.0 / ( Float(int_norm) ); 00073 xiB2 = GJP.XiBare()*GJP.XiBare(); 00074 } 00075 00076 00077 //------------------------------------------------------------------ 00078 // Destructor 00079 //------------------------------------------------------------------ 00080 AlgPot::~AlgPot() { 00081 char *fname = "~AlgPot()"; 00082 VRB.Func(cname,fname); 00083 } 00084 00085 00086 00087 00088 00089 //------------------------------------------------------------------ 00090 // run() 00091 // 00092 // this calculates 00093 // 1. the regular potential from the Wilson Loop in temporal direction 00094 // and with all squared spatial distances r2=x*x + y*y + z*z 00095 // --> Wts 00096 // 2. the sideways potential from wilson Loop in z-direction (=2) 00097 // and with QQ separaton on-axis along 00098 // a) x --> Wzx 00099 // b) t --> Wzt 00100 //------------------------------------------------------------------ 00101 void AlgPot::run() 00102 { 00103 #if TARGET==cpsMPI 00104 using MPISCU::fprintf; 00105 #endif 00106 00107 char *fname = "run()"; 00108 VRB.Func(cname,fname); 00109 00110 int sweep = alg_pot_arg->sweep; 00111 int prop_dir = alg_pot_arg->prop_dir; 00112 // int check = alg_pot_arg->check; 00113 00114 // maximal loop extent in (X,Y,Z,T) direction 00115 // running over all the biggest loops would often be very expensive 00116 int max_X = alg_pot_arg->max_X; 00117 int max_Y = alg_pot_arg->max_Y; 00118 int max_Z = alg_pot_arg->max_Z; 00119 int max_T = alg_pot_arg->max_T; 00120 // maximal squared distance from origin (0,0,0) 00121 int max_r2 = (max_X*max_X + max_Y*max_Y + max_Z*max_Z); 00122 00123 // printf(" max_XYZT = %d %d %d %d max_r2 = %d \n",max_X,max_Y,max_Z,max_T,max_r2); 00124 00125 Float aniso_factor; 00126 Float pot_real; 00127 Float pot_imag; 00128 00129 00130 00131 // Set the Lattice pointer 00132 //---------------------------------------------------------------- 00133 Lattice& lat = AlgLattice(); 00134 00135 printf("prop_dir = %d sweep = %d \n",prop_dir,sweep); 00136 // printf("norm_fac = %e \n", norm_fac); 00137 // printf("XI0 = %e XI02 = %e \n", GJP.XiBare(),xiB2); 00138 00139 // if propagation direction is NOT t=3 or z=2 --> exit 00140 if ((prop_dir != 3) && (prop_dir !=2) ){ 00141 printf("Lattice: prop_dir= %d -- not yet implemented\n",prop_dir); 00142 // exit(1); 00143 } 00144 00145 if (prop_dir == 3) { 00146 // static QQ-pair propagates in temporal direction 00147 // calculate potential for all possible distances 00148 // on-axis and off-axis 00149 00150 // printf(" calculate regular potential in temporal direction\n"); 00151 00152 // allocate space for potential and multiplicity 00153 // actually the following is bigger than necessary 00154 // as the loops below are only UP TO < MAX_R2 00155 // its safe for now though 00156 Complex *Wts = new Complex[max_r2]; 00157 int *number = new int[max_r2]; 00158 00159 for (int ext_prop=1; ext_prop < max_T ; ext_prop++){ 00160 //printf("ext_prop = %d max_T = %d \n",ext_prop,max_T); 00161 00162 // aniso_factor = xi0^{-2* (number of temporal links) } 00163 aniso_factor = power(xiB2,-1.*ext_prop); 00164 // printf("XiBare = %e -> temporal links needs factor %e \n",GJP.XiBare(),aniso_factor); 00165 00166 // initialisation of potential and the number of points 00167 // with distance r2 (new for every different ext_prop) 00168 int r2; 00169 for (r2=0; r2 < max_r2; r2++){ 00170 Wts[r2] = 0.; 00171 number[r2] = 0; 00172 } 00173 00174 // vary the extent of static Q\bar Q source along the three 00175 // different spatial directions 00176 // there is a certain restrcition here in that we only 00177 // consider spatial paths like (x,x,x,x,y,y,z,z,z,z,z) 00178 // but not the Oh-related ones 00179 // e.g. not: (x,y,z,z,x,x,y,z,z,x,z) 00180 00181 for (int ext1 = 0; ext1 < max_X; ext1++){ 00182 for (int ext2 = 0; ext2 < max_Y; ext2++){ 00183 for (int ext3 = 0; ext3 < max_Z; ext3++){ 00184 // printf("ext1-3 = %d %d %d ",ext1,ext2,ext3); 00185 00186 int offset=0; 00187 // squared distance between poitn and origin 00188 r2 = ext1*ext1 + ext2*ext2 + ext3*ext3; 00189 // number of links in Wilson Loop 00190 int nlinks = 2*(ext1+ext2+ext3+ext_prop); 00191 // printf("r2 = %d nlinks = %d ",r2,nlinks); 00192 00193 // allocate space for path 00194 int *path = new int[nlinks]; 00195 int i; 00196 // set up path 00197 for (i=0; i < ext1; i++) path[i] = 0; // x = 0 00198 offset = ext1; 00199 for (i=offset; i < offset+ext2; i++) path[i] = 1; // y = 1 00200 offset = offset + ext2; 00201 for (i=offset; i < offset+ext3; i++) path[i] = 2; // z = 2 00202 offset = offset + ext3; 00203 for (i=offset; i < offset+ext_prop; i++) path[i] = 3; // t = 3 00204 offset = offset + ext_prop; 00205 00206 // now the whole way back 00207 for (i=offset; i < offset+ext3; i++) path[i] = 6; // -z = 6 00208 offset = offset + ext3; 00209 for (i=offset; i < offset+ext2; i++) path[i] = 5; // -y = 5 00210 offset = offset + ext2; 00211 for (i=offset; i < offset+ext1; i++) path[i] = 4; // -x = 4 00212 offset = offset + ext1; 00213 for (i=offset; i < offset+ext_prop; i++) path[i] = 7; // -t=7 00214 00215 /* 00216 printf("path = "); 00217 for (i=0;i<nlinks;i++) printf("%d ",path[i]); 00218 printf("\n "); 00219 */ 00220 00221 // calculated and accumulate the LOOP 00222 // over all possible origins on the lattice 00223 // printf("Looping over all sources \n"); 00224 00225 int x[4]={0,0,0,0}; 00226 Matrix LOOP; 00227 LOOP.ZeroMatrix(); 00228 Complex pot=0.; 00229 00230 for(x[0]=0;x[0]<GJP.XnodeSites();x[0]++) 00231 for(x[1]=0;x[1]<GJP.YnodeSites();x[1]++) 00232 for(x[2]=0;x[2]<GJP.ZnodeSites();x[2]++) 00233 for(x[3]=0;x[3]<GJP.TnodeSites();x[3]++){ 00234 // lat.PathOrdProdPlus(LOOP, x, path, nlinks); 00235 00236 lat.PathOrdProd(LOOP, x, path, nlinks); 00237 pot += LOOP.Tr(); 00238 00239 } // end loop over all local origins 00240 00241 // for PathOrdProdPlus calculate trace of accumulated LOOP 00242 // pot = LOOP.Tr(); 00243 00244 // printf("Trace = %e %e \n", real(pot),imag(pot)); 00245 00246 00247 // accumulate result for each distance and its multiplicity. 00248 // Notice that some distances can not be 00249 // represented on the 3D spatial lattice == 00250 // some integers can not be represented as 00251 // a sum of 3 squares, in this case number[r2] remains zero 00252 number[r2] += 1; 00253 Wts[r2] += pot; 00254 00255 // printf("r2 = %d, number = %d, pot = %e %e Wts = %e \n", 00256 // r2, number[r2], real(pot),imag(pot),real(Wts[r2])); 00257 00258 00259 // write this potential to file 00260 // i.e before summing over all other pot with the same 00261 // value of r2 00262 // e.g. r=5 is either (5,0,0) or (4,3,0) 00263 // treat those seperately here 00264 00265 char *filename="Wt_x_y_z"; // example name 00266 sprintf(filename,"Wt_%d_%d_%d",ext1,ext2,ext3); 00267 FILE *fp= Fopen(filename, "a"); 00268 Float pot_tmp_real = real(pot); 00269 Float pot_tmp_imag = imag(pot); 00270 glb_sum(&pot_tmp_real) ; 00271 glb_sum(&pot_tmp_imag) ; 00272 pot_tmp_real *= aniso_factor*norm_fac; 00273 pot_tmp_imag *= aniso_factor*norm_fac; 00274 Fprintf(fp,"%d %d %d %e %e \n", 00275 sweep, ext_prop, r2, pot_tmp_real,pot_tmp_imag); 00276 Fclose(fp); 00277 00278 // deallocate space for path 00279 delete [] path; 00280 } // end for ext3 00281 } // end for ext2 00282 } // end for ext1 00283 00284 // dump the averaged potential for all r2 at this timeslice 00285 FILE *fp= Fopen("Wts", "a"); 00286 00287 for (r2=0; r2 < max_r2; r2++){ 00288 if (number[r2]!=0) { 00289 Complex W = Wts[r2]/number[r2]; 00290 pot_real = real(W); 00291 pot_imag = imag(W); 00292 // printf("before global sum %d %d %d %e %e \n", 00293 // sweep, ext_prop, r2, pot_real,pot_imag); 00294 glb_sum(&pot_real) ; 00295 glb_sum(&pot_imag) ; 00296 00297 // normalise wrt colour and total space-time 00298 // take into account the anisotropy factor for each temporal link 00299 pot_real *= aniso_factor*norm_fac; 00300 pot_imag *= aniso_factor*norm_fac; 00301 00302 00303 //printf("after global sum %d %d %d %e %e \n", 00304 //sweep, ext_prop, r2, pot_real,pot_imag); 00305 00306 Fprintf(fp,"%d %d %d %e %e \n", 00307 sweep, ext_prop, r2, pot_real,pot_imag); 00308 00309 } // end if (number[r2] !=0) 00310 } // end for r2=0; r2 < max_r2 00311 00312 Fclose(fp); 00313 00314 } // end for ext_prop=0; ext_prop < max_T 00315 00316 // deallocate space for potential and multiplicity 00317 delete[] Wts; 00318 delete[] number; 00319 } // endif (prop_dir == 3 := TIME) 00320 00321 00322 // ====================================================== 00323 00324 if (prop_dir == 2) { 00325 00326 // calculate "side-ways" potential where the 00327 // Q-Q pair propagates only into the spatial z-direction 00328 // in this case we calculate only the TWO ON-AXIS Potential 00329 // with the quark separation into the X- or T-direction 00330 00331 //printf(" calculate sideways potential in direction %d \n",prop_dir); 00332 00333 // loop over all possible "time" extents 00334 00335 for (int ext_prop=1; ext_prop < max_Z ; ext_prop++){ 00336 //printf("ext_prop = %d of max_Z = %d\n",ext_prop,max_Z); 00337 00338 // loop over the two different choices for the spatial 00339 // separation, i.e. X and T 00340 for (int choice=0; choice < 2 ; choice++){ 00341 int sep_dir; // direction of Q-Q separation 00342 int max_ext; // maximal extent of Q-Q separation 00343 char *filename; // filename for potential data 00344 00345 //printf("choice = %d\n",choice); 00346 switch (choice) { 00347 case 0 : sep_dir = 0; max_ext = max_X; filename = "Wzx"; break; 00348 case 1 : sep_dir = 3; max_ext = max_T; filename = "Wzt"; break; 00349 default : sep_dir = 3; max_ext = max_T; filename = "Wzt"; break; 00350 } 00351 //printf(" calculate quark separation in %d -> %s \n",sep_dir,filename); 00352 00353 // this is now simpler than above as we have only 00354 // on-axis separation and there is a unique squared distance 00355 // for each extent "ext" in this particular direction (x or t) 00356 00357 for (int ext=1; ext < max_ext ; ext++){ 00358 00359 int i; 00360 int offset; 00361 // squared distance (on-axis) 00362 // int r2 = ext*ext; 00363 // number of links in loop based on this separation 00364 int nlinks = 2*(ext+ext_prop); 00365 00366 // allocate space for path 00367 int *path = new int[nlinks]; 00368 00369 // set up path 00370 // QQ-separation ( 00371 for (i=0; i < ext; i++) path[i] = sep_dir; 00372 offset = ext; 00373 // QQ-propagation 00374 for (i=offset; i < offset+ext_prop; i++) path[i] = prop_dir; 00375 offset = offset + ext_prop; 00376 00377 // now the whole way back 00378 // -sep_dir (-x=4, -t=7 ) --> sep_dir + 4 00379 for (i=offset; i < offset+ext; i++) path[i] = sep_dir+4; 00380 offset = offset + ext; 00381 00382 // now go backward in "time"=-z=6 00383 for (i=offset; i < offset+ext_prop; i++) path[i] = prop_dir+4; 00384 00385 /* 00386 printf("path = "); 00387 for (int j=0; j<nlinks; j++) printf("%d",path[j]); 00388 printf("\n"); 00389 */ 00390 00391 // calculated and accumulate the LOOP 00392 // over all possible origins on the lattice 00393 int x[4]; 00394 Matrix LOOP; 00395 Complex pot = 0.; 00396 00397 for(x[0]=0;x[0]<GJP.XnodeSites();x[0]++) 00398 for(x[1]=0;x[1]<GJP.YnodeSites();x[1]++) 00399 for(x[2]=0;x[2]<GJP.ZnodeSites();x[2]++) 00400 for(x[3]=0;x[3]<GJP.TnodeSites();x[3]++){ 00401 00402 lat.PathOrdProd(LOOP, x, path, nlinks); 00403 pot += LOOP.Tr(); 00404 00405 } 00406 00407 00408 00409 //printf("write to file = %s \n",filename); 00410 //printf("%d %d %d %e %e \n", 00411 // sweep, ext_prop, r2, real(pot),imag(pot)); 00412 00413 pot_real = real(pot); 00414 pot_imag = imag(pot); 00415 00416 00417 // printf("before global sum %d %d %d %e %e \n", 00418 // sweep, ext_prop, r2, pot_real,pot_imag); 00419 00420 // global sum over all processors 00421 glb_sum(&pot_real) ; 00422 glb_sum(&pot_imag) ; 00423 00424 00425 // normalise wrt colour and total space-time 00426 // for anisotropic lattices this is dependent on 00427 // whether this loop extented into the temporal direction 00428 00429 if (sep_dir==3){ 00430 00431 // each temporal link should be divided by xi0 00432 // aniso_factor = xi0^{-2*temp_ext} 00433 aniso_factor = power(xiB2,-1.*ext); 00434 00435 //printf("ext = %d, xiB2 = %e, aniso_factor = %e pot before = %e\n", 00436 // ext,xiB2,aniso_factor,pot*norm_fac); 00437 00438 pot_real *= aniso_factor*norm_fac; 00439 pot_imag *= aniso_factor*norm_fac; 00440 00441 // if (ext_prop==1) Wzt[ext] = pot_real; // for external use 00442 00443 /* 00444 // write W(z,t) to file 00445 char *fn="Wz99t99"; 00446 sprintf(fn,"Wz%dt%d",ext_prop,ext); 00447 FILE *fp= Fopen(fn, "a"); 00448 Fprintf(fp,"%d %e %e \n",sweep, pot_real,pot_imag); 00449 Fclose(fp); 00450 */ 00451 } else { 00452 00453 // if seperation is in spatial direction 00454 // no extra care is necessary --> loop is completely spatial 00455 00456 pot_real *= norm_fac; 00457 pot_imag *= norm_fac; 00458 00459 // if (ext_prop==1) Wzx[ext] = pot_real; // for external use 00460 00461 /* 00462 // write W(z,x) to file 00463 char *fn = "Wz99x99"; 00464 sprintf(fn,"Wz%dx%d",ext_prop,ext); 00465 FILE *fp= Fopen(fn, "a"); 00466 Fprintf(fp,"%d %e %e \n",sweep, pot_real,pot_imag); 00467 Fclose(fp); 00468 */ 00469 } 00470 00471 // printf("after global sum %d %d %d %e %e \n", 00472 // sweep, ext_prop, r2, pot_real,pot_imag); 00473 00474 FILE *fp= Fopen(filename, "a"); 00475 Fprintf(fp,"%d %d %d %e %e \n", 00476 sweep, ext_prop, ext, pot_real,pot_imag); 00477 Fclose(fp); 00478 00479 // deallocate space for path 00480 delete [] path; 00481 00482 } // end for ext=0; ext< max_ext; 00483 } // end for choice=0; choice < 2 ; 00484 } // end for ext_prop =0; ext_prop < max_Z ; 00485 } // endif (prop_dir == 2 := Z-direction) 00486 } 00487 00488 CPS_END_NAMESPACE
1.3.9.1