Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

alg_pot2.C

Go to the documentation of this file.
00001 #include<config.h>
00002 CPS_START_NAMESPACE
00003 //--------------------------------------------------------------------
00004 //  CVS keywords
00005 //
00006 //  $Author: chulwoo $
00007 //  $Date: 2006/05/30 20:32:27 $
00008 //  $Header: /space/cvs/cps/cps++/src/alg/alg_pot2/alg_pot2.C,v 1.2 2006/05/30 20:32:27 chulwoo Exp $
00009 //  $Id: alg_pot2.C,v 1.2 2006/05/30 20:32:27 chulwoo Exp $
00010 //  $Name: v5_0_8 $
00011 //  $Locker:  $
00012 //  $RCSfile: alg_pot2.C,v $
00013 //  $Revision: 1.2 $
00014 //  $Source: /space/cvs/cps/cps++/src/alg/alg_pot2/alg_pot2.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_pot2.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 //------------------------------------------------------------------
00045 // Constructor 
00046 //------------------------------------------------------------------
00047 AlgPot2::AlgPot2(Lattice& latt, 
00048              CommonArg *c_arg,
00049              PotArg *arg) : 
00050              Alg(latt, c_arg) 
00051 {
00052   cname = "AlgPot2";
00053   char *fname = "AlgPot2(L&,CommonArg*,PotArg*)";
00054   VRB.Func(cname,fname);
00055 
00056   // Initialize the argument pointer
00057   //----------------------------------------------------------------
00058   if(arg == 0)
00059     ERR.Pointer(cname,fname, "arg");
00060   alg_pot_arg = arg;
00061 
00062   // Calculate normalization factor for each processor
00063   //----------------------------------------------------------------
00064 
00065   int total_sites    = GJP.VolNodeSites() * GJP.Xnodes() *
00066                        GJP.Ynodes() * GJP.Znodes() * GJP.Tnodes();
00067   int int_norm       = GJP.Colors()*total_sites;
00068 
00069   norm_fac           = 1.0 / ( Float(int_norm) );
00070   xiB2               = GJP.XiBare()*GJP.XiBare();
00071 }
00072 
00073 
00074 //------------------------------------------------------------------
00075 // Destructor
00076 //------------------------------------------------------------------
00077 AlgPot2::~AlgPot2() {
00078   char *fname = "~AlgPot2()";
00079   VRB.Func(cname,fname);
00080 }
00081 
00082 
00083 
00084 
00085 
00086 //------------------------------------------------------------------
00087 // run()
00088 //   check is used to set r2max
00089 //------------------------------------------------------------------
00090 void AlgPot2::run()
00091 {
00092 #if TARGET==cpsMPI
00093   using MPISCU::fprintf;
00094 #endif
00095   
00096   char *fname = "run()";
00097   VRB.Func(cname,fname);
00098   
00099   int sweep    = alg_pot_arg->sweep;
00100   int prop_dir = alg_pot_arg->prop_dir;
00101   int check    = alg_pot_arg->check;
00102 
00103   // maximal loop extent in (X,Y,Z,T) direction 
00104   // running over all the biggest loops would often be very expensive
00105 
00106   int max_ext[4];
00107  
00108   int max_X = alg_pot_arg->max_X;
00109   int max_Y = alg_pot_arg->max_Y;
00110   int max_Z = alg_pot_arg->max_Z;
00111   int max_T = alg_pot_arg->max_T;
00112 
00113   max_ext[0] = max_X;
00114   max_ext[1] = max_Y;
00115   max_ext[2] = max_Z;
00116   max_ext[3] = max_T;
00117 
00118   int max_prop = max_ext[prop_dir];
00119 
00120   /*
00121   // to use pot_arg, r2max is defined here 
00122   int r2max = 1;
00123   for (int i = 0; i < 4; i++)
00124     if( i != prop_dir ) {
00125       if( r2max <= max_ext[i] ) r2max = max_ext[i];
00126     }
00127   r2max = r2max*r2max;
00128   */
00129   int r2max = check*check;
00130 
00131   // orthogonal directions to prop_dir 
00132   int dir_orth[3];
00133   int idir = 0;
00134   for (int i = 0; i < 4; i++)
00135     if( i != prop_dir ) {
00136       dir_orth[idir] = i;
00137       idir++;
00138     }
00139 
00140   int max_1 = max_ext[dir_orth[0]];
00141   int max_2 = max_ext[dir_orth[1]];
00142   int max_3 = max_ext[dir_orth[2]];
00143 
00144   int num_loop = 0;
00145   for (int ext1 = 0; ext1 <= max_1; ext1++){
00146     for (int ext2 = 0; ext2 <= max_2; ext2++){
00147       for (int ext3 = 0; ext3 <= max_3; ext3++){  
00148 
00149         int cmax = ext3; 
00150         if (cmax <= ext2) {cmax = ext2;}
00151         if (cmax <= ext1) {cmax = ext1;}
00152         int cmin = ext1;
00153         if (cmin >= ext2) {cmin = ext2;}
00154         if (cmin >= ext3) {cmin = ext3;}
00155           
00156         int cmid = ext1+ext2+ext3 - cmax - cmin;
00157           
00158         int r2 = ext1*ext1 + ext2*ext2 + ext3*ext3;
00159         if( r2 <= r2max || cmid == 0 ) num_loop+=max_prop;
00160       }
00161     }
00162   }
00163                               
00164   Float aniso_factor;
00165   Float pot_real;
00166   Float pot_imag;
00167 
00168   // Set the Lattice pointer
00169   //----------------------------------------------------------------
00170   Lattice& lat = AlgLattice();
00171 
00172   // static QQ-pair propagates in temporal direction
00173   // calculate potential for all possible distances
00174   // on-axis and off-axis
00175   
00176   // allocate space for potential and multiplicity
00177   // actually the following is bigger than necessary
00178   // as the loops below are only UP TO < MAX_R2
00179   // its safe for now though
00180   //  Complex *Wts = new Complex[max_r2];
00181   //  int *number  = new int[max_r2];
00182   Complex *Wloop = new Complex[num_loop];
00183   //  int (*qq_sep)[6];
00184   //  qq_sep = new int[num_loop][6];
00185   int *qq_sep0 = new int[num_loop];
00186   int *qq_sep1 = new int[num_loop];
00187   int *qq_sep2 = new int[num_loop];
00188   int *qq_sep3 = new int[num_loop];
00189   int *qq_sep4 = new int[num_loop];
00190   int *qq_sep5 = new int[num_loop];
00191 
00192 
00193   for (int i = 0; i < num_loop; i++){
00194     Wloop[i] = 0.;
00195     qq_sep0[i] = -1;  // x
00196     qq_sep1[i] = -1;  // y
00197     qq_sep2[i] = -1;  // z
00198     qq_sep3[i] = -1;  // t
00199     qq_sep4[i] =  0;  // prop 
00200     qq_sep5[i] =  0;  // r2
00201   }
00202 
00203   int iloop = 0;
00204   for (int ext_prop=1; ext_prop <= max_prop ; ext_prop++){
00205 
00206     // aniso_factor = xi0^{-2* (number of temporal links) }
00207     aniso_factor = power(xiB2,-1.*ext_prop);
00208     
00209     // vary the extent of static Q\bar Q source along the three
00210     // different spatial directions
00211     // there is a certain restrcition here in that we only
00212     // consider spatial paths like (x,x,x,x,y,y,z,z,z,z,z)
00213     // but not the Oh-related ones
00214     //  e.g. not: (x,y,z,z,x,x,y,z,z,x,z)
00215     
00216     for (int ext1 = 0; ext1 <= max_1; ext1++){
00217       for (int ext2 = 0; ext2 <= max_2; ext2++){
00218         for (int ext3 = 0; ext3 <= max_3; ext3++){  
00219 
00220           int cmax = ext3; 
00221           int dir_max = 2;
00222           if (cmax <= ext2) {cmax = ext2; dir_max=1;}
00223           if (cmax <= ext1) {cmax = ext1; dir_max=0;}
00224           int cmin = ext1;
00225           int dir_min = 0;
00226           if (cmin >= ext2) {cmin = ext2; dir_min=1;}
00227           if (cmin >= ext3) {cmin = ext3; dir_min=2;}
00228           
00229           int cmid = ext1+ext2+ext3 - cmax - cmin;
00230           int dir_mid = 0+1+2 - dir_max - dir_min;
00231           
00232           int r2 = ext1*ext1 + ext2*ext2 + ext3*ext3;
00233           //      if( r2 <= r2max ) {
00234           if( r2 <= r2max || cmid == 0 ) {
00235             
00236             int check1 = 
00237               dir_max*dir_max + dir_mid*dir_mid + dir_min*dir_min;
00238             if ( check1 != 5 ) {
00239               cout << " sum dir*dir should be 5 not " << check1 << endl;
00240               exit(-1);
00241             }
00242 
00243             int cmax2 = 2*cmax;
00244             int cmid2 = 2*cmid;
00245             int cmin2 = 2*cmin;
00246             int chi_mid = cmid2 - cmax;
00247             int chi_min = cmin2 - cmax;
00248 
00249             // squared distance between poitn and origin
00250             // int r2 = ext1*ext1 + ext2*ext2 + ext3*ext3;
00251             // number of links in Wilson Loop
00252             int nlinks = 2*(ext1+ext2+ext3+ext_prop);
00253             
00254             // allocate space for path
00255             int *path = new int[nlinks]; 
00256             int ipath = 0;
00257 
00258             // path between Q and Qbar
00259             for (int i = 1; i <= cmax; i++) {
00260               path[ipath] = dir_orth[dir_max];
00261               ipath++;
00262               if (chi_mid >= 0) {
00263                 chi_mid -= cmax2;
00264                 path[ipath] = dir_orth[dir_mid];
00265                 ipath++;
00266               }
00267               if (chi_min >= 0) {
00268                 chi_min -= cmax2;
00269                 path[ipath] = dir_orth[dir_min];
00270                 ipath++;
00271               }
00272               chi_mid += cmid2;
00273               chi_min += cmin2;
00274             }
00275             
00276             // path for propagation
00277             for (int i = 0; i < ext_prop; i++) {
00278               path[ipath] = prop_dir;
00279               ipath++;
00280             }
00281             
00282             // x = 0 , -x = 4 = x + 4
00283             // y = 1 , -y = 5 = y + 4
00284             // z = 2 , -z = 6 = z + 4
00285             // t = 3 , -t = 7 = t + 4
00286             // inverse path between Q and Qbar
00287             int qq_path = ext1 + ext2 + ext3;
00288             int inv_path = qq_path - 1;
00289             for (int i = 0; i < qq_path; i++) {
00290               path[ipath] = path[inv_path] + 4;  // inverse direction
00291               ipath++;
00292               inv_path--;
00293             }
00294             
00295             // inverse path for propagation
00296             for (int i = 0; i < ext_prop; i++) {
00297               path[ipath] = prop_dir + 4;
00298               ipath++;
00299             }
00300             
00301             // check for path length
00302             if (ipath != nlinks) {
00303               cout << "illegal path !!!" << endl;
00304               cout << "ipath  = " << ipath << endl;
00305               cout << "nlinks = " << nlinks << endl;
00306               exit(-1);
00307             }
00308             
00309             // calculated and accumulate the LOOP
00310             // over all possible origins on the lattice
00311             // printf("Looping over all sources \n");
00312             
00313             int x[4]={0,0,0,0};
00314             Matrix LOOP;
00315             //    LOOP.ZeroMatrix();
00316             Complex pot=0.;
00317             
00318             int isite = 0;
00319             for(x[0]=0;x[0]<GJP.XnodeSites();x[0]++)
00320               for(x[1]=0;x[1]<GJP.YnodeSites();x[1]++)
00321                 for(x[2]=0;x[2]<GJP.ZnodeSites();x[2]++)
00322                   for(x[3]=0;x[3]<GJP.TnodeSites();x[3]++){
00323                     
00324                     LOOP.ZeroMatrix();
00325                     lat.PathOrdProdPlus(LOOP, x, path, nlinks);
00326                     pot += LOOP.Tr();
00327                     isite++;
00328                     
00329                   } // end loop over all local origins
00330             // accumulate result for each distance and its multiplicity.
00331             // Notice that some distances can not be
00332             // represented on the 3D spatial lattice ==
00333             // some integers can not be represented as
00334             // a sum of 3 squares, in this case number[r2] remains zero
00335             Wloop[iloop] = pot;
00336             int tmp_sep[4] = {-1,-1,-1,-1};
00337             tmp_sep[dir_orth[0]] = ext1;
00338             tmp_sep[dir_orth[1]] = ext2;
00339             tmp_sep[dir_orth[2]] = ext3;
00340             qq_sep0[iloop] = tmp_sep[0];
00341             qq_sep1[iloop] = tmp_sep[1];
00342             qq_sep2[iloop] = tmp_sep[2];
00343             qq_sep3[iloop] = tmp_sep[3];
00344             qq_sep4[iloop] = ext_prop;
00345             qq_sep5[iloop] = r2;
00346             iloop++;
00347             
00348             // deallocate space for path
00349             delete [] path;
00350             //    cout << "after delete path" << endl;
00351           } // end for if(r2<=r2max||cmid==0)
00352         } // end for ext3
00353       } // end for ext2
00354     } // end for ext1
00355     
00356   } // end for ext_prop=0; ext_prop <= max_T
00357   
00358   if (iloop != num_loop ) {
00359     cout << "something is wrong about loop counting" << endl;
00360     cout << "iloop = " << iloop << endl;
00361     cout << "num_loop = " << num_loop << endl;
00362     exit(-1);
00363   }
00364   
00365   // dump the averaged potential for all r2 at this timeslice
00366   char wfname[100];
00367   sprintf(wfname, "Wloop%04dsme%03d.dat", sweep/1000, sweep%1000);
00368   FILE *fp= Fopen(wfname, "w");
00369   //  FILE *fp= Fopen("Wloop_new.dat", "w");
00370   
00371   Fprintf(fp, "# max_X= %d max_Y= %d max_Z= %d max_T= %d \n",
00372           max_X, max_Y, max_Z, max_T);
00373   Fprintf(fp, "# sweep= %d  prop_dir= %d  num_loop= %d\n",
00374           sweep/1000, prop_dir, num_loop);
00375   Fprintf(fp, "# smear= %d \n", sweep%1000);
00376   Fprintf(fp, "# x  y  z  t prop   pot_real       pot_imag\n");
00377   
00378   for (int i = 0; i < num_loop; i++){
00379     Complex W =  Wloop[i];
00380     pot_real = real(W);
00381     pot_imag = imag(W);
00382     glb_sum(&pot_real) ;
00383     glb_sum(&pot_imag) ;
00384     
00385     // normalise wrt colour and total space-time
00386     // take into account the anisotropy factor for each temporal link
00387     pot_real *= aniso_factor*norm_fac;
00388     pot_imag *= aniso_factor*norm_fac;
00389 
00390     Fprintf(fp," %d  %d  %d  %d  %d    %e   %e  \n",
00391             //      qq_sep[i][0],qq_sep[i][1],qq_sep[i][2],qq_sep[i][3],
00392             //      qq_sep[i][4], pot_real, pot_imag);
00393             qq_sep0[i],qq_sep1[i],qq_sep2[i],qq_sep3[i],
00394             qq_sep4[i], pot_real, pot_imag);
00395     //    Fprintf(fp," %d  %d  %d  %d  %d  %d   %e   %e  \n",
00396     //      qq_sep[i][0],qq_sep[i][1],qq_sep[i][2],qq_sep[i][3],
00397     //      qq_sep[i][4], qq_sep[i][5], pot_real, pot_imag);
00398   }
00399   
00400   Fclose(fp);
00401   //  cout << "total_site = " << (1.0 / norm_fac)/3.0 << endl;
00402 
00403   delete[] Wloop;
00404   //  delete[] qq_sep;
00405   delete[] qq_sep0;
00406   delete[] qq_sep1;
00407   delete[] qq_sep2;
00408   delete[] qq_sep3;
00409   delete[] qq_sep4;
00410   delete[] qq_sep5;
00411 
00412 }
00413 CPS_END_NAMESPACE

Generated on Sat Oct 10 14:11:19 2009 for Columbia Physics System by  doxygen 1.3.9.1