wupp_smear.cc

Go to the documentation of this file.
00001 // $Id: wupp_smear.cc,v 3.2 2009/07/22 02:44:04 edwards Exp $
00002 /*! \file
00003  *  \brief 3d Laplacian solution on color vector
00004  */
00005 
00006 #error "THIS CODE IS NOT YET READY"
00007 
00008 #include "chromabase.h"
00009 #include "meas/smear/wupp_smear.h"
00010 #include "util/ft/sftmom.h"
00011 
00012 namespace Chroma 
00013 {
00014 
00015   //! Do a covariant Gaussian smearing of a lattice field
00016   /*!
00017    * Arguments:
00018    *
00019    *  \param u        gauge field ( Read )
00020    *  \param chi      color vector field ( Modify )
00021    *  \param width    width of "shell" wave function ( Read )
00022    *  \param ItrGaus  number of iterations to approximate Gaussian ( Read )
00023    *  \param j_decay  direction of decay ( Read )
00024    */
00025 
00026   template<typename T>
00027   void gausSmear(const multi1d<LatticeColorMatrix>& u, 
00028                  T& chi, 
00029                  const Real& width, int ItrGaus, int j_decay)
00030   {
00031     T psi;
00032 
00033     Real ftmp = - (width*width) / Real(4*ItrGaus);
00034     /* The Klein-Gordon operator is (Lapl + mass_sq), where Lapl = -d^2/dx^2.. */
00035     /* We want (1 + ftmp * Lapl ) = (Lapl + 1/ftmp)*ftmp */
00036     Real ftmpi = Real(1) / ftmp;
00037   
00038     for(int n = 0; n < ItrGaus; ++n)
00039     {
00040       psi = chi * ftmp;
00041       klein_gord(u, psi, chi, ftmpi, j_decay);
00042     }
00043   }
00044 
00045 
00046   //! Do a covariant Gaussian smearing of a lattice color vector field
00047   /*! This is a wrapper over the template definition
00048    *
00049    * \ingroup smear
00050    *
00051    * Arguments:
00052    *
00053    *  \param u        gauge field ( Read )
00054    *  \param chi      color vector field ( Modify )
00055    *  \param width    width of "shell" wave function ( Read )
00056    *  \param ItrGaus  number of iterations to approximate Gaussian ( Read )
00057    *  \param j_decay  direction of decay ( Read )
00058    */
00059 
00060   void gausSmear(const multi1d<LatticeColorMatrix>& u, 
00061                  LatticeColorVector& chi, 
00062                  const Real& width, int ItrGaus, int j_decay)
00063   {
00064     gausSmear<LatticeColorVector>(u, chi, width, ItrGaus, j_decay);
00065   }
00066 
00067 
00068 
00069 
00070   //! Do a covariant Wuppertal smearing of a color vector field
00071   /*  u -- gauge field ( Read ) */
00072   /*  chi -- color vector field ( Modify ) */
00073   /*  mass_sq  -- mass_sq of Wuppertal "shell" wave function ( Read ) */
00074   /*  ItrMax -- maximal number of iterations to invert ( Read ) */
00075   /*  j_decay  -- direction of decay ( Read ) */
00076   /*  RsdCG  -- residue for CG inverter ( Read ) */
00077 
00078   void wuppSmear(const multi1d<LatticeColorMatrix>& u, 
00079                  LatticeColorVector& chi, 
00080                  const Real& mass_sq, int ItrMax, int j_decay, const Real& RsdCG)
00081   {
00082     LatticeColorVector p;
00083     LatticeColorVector r;
00084     LatticeColorVector ap;
00085     LatticeReal apa;
00086     LatticeReal tmp;
00087     LatticeInteger t_coord;
00088     LatticeBoolean t_mask;
00089     Real Rsd;
00090     multi1d<Real> zero(length);
00091     multi1d<Real> ab(length);
00092     multi1d<Double> c(length);
00093     multi1d<Double> d(length);
00094     multi1d<Double> dd(length);
00095     multi1d<Double> chi_norm(length);
00096     multi1d<Double> cp(length);
00097     int length;
00098     int t;
00099     int k;
00100     int cb;
00101     int converged;
00102     multi1d<Boolean> is_zero(length);
00103     Boolean any_zero;
00104 
00105     START_CODE();
00106 
00107     length = nrow[j_decay];
00108     Rsd = RsdCG * RsdCG;
00109 
00110     /* The Klein-Gordon operator is (Lapl + mass_sq), where Lapl = -d^2/dx^2.. */
00111     /* Use CG to compute psi = (Lapl + mass_sq)^(-1) chi */
00112     /* Note: Lapl is a 3-d laplacian; each time slice is handled independently. */
00113 
00114                               
00115     zero = 0;
00116 
00117     /* chi_norm = |chi[0]|^2 */
00118     chi_norm = 0;
00119     for(cb = 0; cb < Nsubl; cb++)
00120       SLICE_SUMSQ(chi(cb), j_decay, chi_norm, ADD);
00121 
00122     dd = 0;
00123     is_zero = chi_norm == dd;
00124     FILL(any_zero,FALSE);
00125     for(t = 0; t < length; t++)
00126       any_zero = any_zero | is_zero[t];
00127 
00128     /* p[1] = r[0] = chi */
00129     r = chi;
00130     p = r;
00131 
00132     /* Cp = |r[0]|^2 = chi_norm */
00133     cp = chi_norm;
00134 
00135     for(t = 0; t < length; t++)
00136       chi_norm[t] *= Rsd;
00137 
00138     /* We overwrite chi with the solution; initial solution is zero */
00139     chi = 0;
00140 
00141     t_coord = Layout::latticeCoordinate(j_decay);
00142 
00143     for(k = 1; k <= ItrMax; k++)
00144     {
00145       /* c = |r[k-1]|^2 */
00146       c = cp;
00147 
00148       /* a[k] = |r[k-1]|^2 / < p[k], Ap[k] > ; */
00149       /* First compute ap = Ap[k] */
00150       klein_gord (u, p, ap, mass_sq, j_decay);
00151 
00152       apa = real(trace(adj[p[0]] * ap[0]))
00153         tmp = real(trace(adj[p[1]] * ap[1]))
00154         apa += tmp;
00155 
00156       d = sumMulti(apa, timeslice)
00157 
00158         dd = c / d;
00159       ab = FLOAT(dd);
00160       if( any_zero )
00161         copymask(ab, is_zero, zero, REPLACE);
00162 
00163       /* Chi[k] += a[k] p[k] */
00164       /* SLICE_FILL(apa, ab); */
00165       apa = 0;
00166       for(t = 0; t < length; t++)
00167         if( ! is_zero[t] )
00168         {
00169           FILL(tmp, ab(t));
00170           t_mask = t_coord == t;
00171           copymask(apa, t_mask, tmp, REPLACE);
00172         }
00173       for(cb = 0; cb < Nsubl; cb++)
00174         chi[cb] += p[cb] * apa;
00175       /*  r[k] -= a[k] Ap[k] */
00176       for(cb = 0; cb < Nsubl; cb++)
00177         r[cb] -= ap[cb] * apa;
00178 
00179       /* cp = |r[k]|^2 */
00180       cp = 0;
00181       for(cb = 0; cb < Nsubl; cb++)
00182         SLICE_SUMSQ(r(cb), j_decay, cp, ADD);
00183 
00184       converged = 0;
00185       for(t = 0; t < length; t++)
00186         if( cp[t] <= chi_norm[t] )
00187           converged += 1;
00188 
00189       /* push(xml_out,"Residues");
00190          write(xml_out, "k", k);
00191          write(xml_out, "cp", cp);
00192          pop(xml_out); */
00193 
00194       if( converged == length )
00195       {
00196         push(xml_out,"Wupp_smear_needed");
00197         write(xml_out, "k", k);
00198         pop(xml_out);
00199         return;
00200       }
00201 
00202       /* b[k+1] = |r[k]|^2 / |r[k-1]|^2 */
00203       dd = cp / c;
00204       ab = FLOAT(dd);
00205       if( any_zero )
00206         copymask(ab, is_zero, zero, REPLACE);
00207 
00208       /* p[k+1] = r[k] + b[k+1] p[k] */
00209       /* SLICE_FILL(apa, ab); */
00210       apa = 0;
00211       for(t = 0; t < length; t++)
00212         if( ! is_zero[t] )
00213         {
00214           FILL(tmp, ab(t));
00215           t_mask = t_coord == t;
00216           copymask(apa, t_mask, tmp, REPLACE);
00217         }
00218       for(cb = 0; cb < Nsubl; cb++)
00219       {
00220         p[cb] = p[cb] * apa;
00221         p[cb] += r[cb];
00222       }
00223     }
00224 
00225     push(xml_out,"Wupp_smear_not_converged");
00226     write(xml_out, "k", k);
00227     pop(xml_out);
00228                               
00229     END_CODE();
00230   }
00231 
00232 } // namespace Chroma

Generated on Sat Mar 13 04:38:18 2010 for CHROMA by  doxygen 1.4.7