pade_trln_w.cc

Go to the documentation of this file.
00001 // $Id: pade_trln_w.cc,v 3.0 2006/04/03 04:59:06 edwards Exp $
00002 
00003 #error "NOT FULLY CONVERTED"
00004 
00005 
00006 include(types.mh)
00007 
00008 
00009 /* Parameters:
00010    
00011    u             -- The Gauge Field         (Read)
00012    chi           -- Z2 noise vector         (Read)
00013    Ncb           -- No of checkerboards     (Read)
00014    Nkappa        -- The no of kappa values  (Read)
00015    Npade         -- The order of the Pade approx (Read)
00016    Kappas        -- The array of Kappa values (Read)
00017    Pade_c        -- Array holding the denominator Pade coeffs  (Read)
00018    Pade_b0       -- b0 from the Pade Expansion (Read)
00019    Pade_b        -- Array holding numerator Pade coeffs (Read)
00020    RsdMR         -- Stopping Criterion for the MR algorithm    (Read)
00021    psibp         -- An array to hold the psibar-psi values     (Write)
00022    trlns         -- An array to hold the trace log values      (Write)
00023    n_count       -- The number of MR iterations taken          (n_count)
00024 */
00025 SUBROUTINE(PadeTrLn, u, chi, Ncb, Nkappa, Kappas, Npade,
00026            Pade_b0, Pade_b, Pade_c, Nimpr, Omega_impr,
00027            RsdMR, psibp_unimp, trlns_unimp, psibp_imp, trlns_imp,
00028            n_count)
00029 
00030      /* Gauge field */
00031      multi1d<LatticeColorMatrix> u(Nd);
00032 
00033      /* Z2 src */
00034      multi1d<LatticeFermion> chi(Ncb);
00035      
00036      /* No of checkerboards */
00037      int Ncb;
00038      
00039      /* No of Kappa values */
00040      int Nkappa;
00041     
00042      /* No of Pade Coeffs */
00043      int Npade;
00044 
00045      /* The array of Kappas */
00046      multi1d<Real> Kappas(Nkappa);
00047 
00048      /* Index of largest kappa (smallest mass) */
00049      /* The array of Pade_c */
00050      multi1d<Real> Pade_c(Npade);
00051      Real Pade_b0;
00052      multi1d<Real> Pade_b(Npade);
00053 
00054      /* Stopping criterion for the Multi Mass MR solver */
00055      Real RsdMR;
00056      
00057      /* Array for unimproved psibar psi estimates */
00058      multi1d<Complex> psibp_unimp(Nkappa);
00059 
00060      /* Array of unimproved Trace Log estimates */
00061      multi1d<Complex> trlns_unimp(Nkappa);
00062 
00063     /* Array for improved psibar psi estimates */
00064      multi1d<Complex> psibp_imp(Nkappa);
00065 
00066      /* Array of improved Trace Log estimates */
00067      multi1d<Complex> trlns_imp(Nkappa);
00068 
00069      /* No of solver iters taken */
00070      int n_count;
00071      
00072      /* Order of unbiased subtraction */
00073      int Nimpr;
00074      multi1d<Real> Omega_impr(Nimpr);
00075 
00076 {
00077   include(COMMON_DECLARATIONS)
00078 
00079   multi2d<LatticeFermion> psi(Ncb, Nshift);   /* Array of solver solutions */
00080   
00081   multi1d<LatticeFermion> psi_test(Ncb); /* SOmething to check the residuals with */
00082   multi1d<LatticeFermion> r(Ncb);
00083 
00084   multi1d<LatticeFermion> Dchi(Ncb);
00085 
00086   Double chi_norm;               /* The norm of the source */
00087   Double r_norm;                 /* The norm of the residuals */
00088 
00089   /* The shifted and unshifted operators */
00090 
00091   /* A dslash operator */
00092   LINEAR_OPERATOR(D);
00093 
00094   LINEAR_OPERATOR(Mshifted);
00095   PROTOTYPE(`Mshifted', `DESC', `DESC', `DESC', `VAL', `VAL')
00096 
00097   LINEAR_OPERATOR(Munshifted);
00098   PROTOTYPE(`Munshifted', `DESC', `DESC', `DESC', `VAL', `VAL')
00099 
00100   /* The number of shifted solutions */
00101   int Nshift;             /* No of shifts for solver */
00102   multi1d<Real> Shifts(Nshift);        /* The array of shifts */
00103 
00104   multi1d<Real> RsdMR_array(Nshift);   /* An array version of RsdMR needed by solver */
00105 
00106   Real Shiftmass;             /* Useful for testing the solutions */
00107 
00108   Real MaxRsd;
00109   /* Various Counters */
00110   int i;
00111   int j;
00112   int l;
00113   int kappa;
00114   int cb;
00115 
00116    /* Two variables for tracing */
00117   LatticeComplex lc;             
00118   LatticeComplex lct; 
00119   DComplex dcsum;
00120   Complex csum;
00121 
00122   /* Temporaries */
00123   multi1d<Real> first_terms(Nkappa);
00124   multi1d<Complex> pade_terms(Npade);
00125                     
00126   
00127   /* Stuff for Trln */
00128   Real TrI;
00129   Real minusone;
00130   Real tmp;
00131   Real kappa_pow;
00132   Real pade_c_pow;
00133 
00134 
00135   /* Dslash Bilinears */
00136   multi1d<Complex> bilinear(Nimpr);
00137 
00138   /* Psibar Psi improvement terms */
00139   multi2d<Complex> psib_offterms(Nkappa, Nimpr);
00140   multi3d<Complex> trln_offterms(Nkappa, Npade, Nimpr);
00141   multi2d<Complex> sum_trln_offterms(Nkappa, Nimpr);
00142   
00143   /* Glue improvement : 'Plaquette' */
00144   Double w_plaq;
00145   Double s_plaq;
00146   Double t_plaq;
00147   Double link;
00148   Real f_plaq;
00149   Complex c_plaq;
00150 
00151   /* index of the smallest shift */
00152   int isz;
00153   Real minshift;
00154   
00155   START_CODE();
00156   
00157   minusone = - TO_REAL(1);
00158 
00159   /* First work out the shifts from the kappas and the sigmas */
00160   Nshift = Nkappa * ( Npade + 1 );
00161 
00162   /* Allocate the space */
00163       
00164   /* Work out the shifts */
00165   j=0;
00166   
00167   /* First just the 1/kappa's */
00168   for(i = 0; i < Nkappa; i++) {
00169     Shifts[j] = TO_REAL(1) / Kappas[i]; 
00170     j++;
00171   }
00172 
00173   /* Then the (1 + shift)/kappa's */
00174   for(i = 0; i < Nkappa; i++) { 
00175     for(l = 0; l < Npade; l++) { 
00176       Shifts[j] = ( TO_REAL(1) + Pade_c[l] ) / Kappas[i];
00177       j++;
00178     }
00179   }
00180   
00181   /* Set up the solver */
00182     
00183   FILL(RsdMR_array, RsdMR);
00184   /* push(xml_out,"pade_trln");
00185 write(xml_out, "Nshift", Nshift);
00186 write(xml_out, "Shifts", Shifts);
00187 write(xml_out, "RsdMR", RsdMR);
00188 write(xml_out, "MaxCG", MaxCG);
00189 pop(xml_out); */
00190 
00191   /* Fill all Psi-s with 0 to start with */
00192   psi = 0;
00193 
00194   /* Compute the norm of chi */
00195   chi_norm=TO_REAL(0);
00196 
00197   for(cb=0; cb < Ncb; cb++) {
00198     chi_norm += norm2(chi[cb]);
00199   }
00200   chi_norm = sqrt(chi_norm);
00201 
00202   /* Flick on fermionic Bc's */
00203   phfctr (u, FORWARD);
00204 
00205 
00206     Shiftmass = 0;
00207   ConsDslash (D, u, Shiftmass, WILSON_DSLASH);
00208 
00209     CONSTRUCT_LINEAR_OPERATOR(Munshifted, ldunshifted, D);
00210 
00211   /* Work out what the smallest shift */
00212   minshift = Shifts[0];
00213   isz = 0;
00214   for(i=1; i < Nshift; i++) { 
00215     if(  Shifts[i] < minshift ) { 
00216       minshift = Shifts[i];
00217       isz = i;
00218     }
00219   }
00220 
00221   /* Call the solver */
00222   MInvMRm (Munshifted, chi, psi, chi_norm, Shifts, Nshift, isz, RsdMR_array, Ncb, n_count);
00223 
00224   /* push(xml_out,"Pade_MR_Solver");
00225 write(xml_out, "n_count", n_count);
00226 pop(xml_out); */
00227 
00228   FREE_LINEAR_OPERATOR(Munshifted);
00229   
00230         
00231   for(i=0; i < Nshift; i++) { 
00232     
00233     for(cb = 0; cb < Ncb; cb++) { 
00234       psi_test[cb] = psi[i][cb];
00235     }
00236    
00237 
00238     Shiftmass = Shifts[i];
00239     CONSTRUCT_LINEAR_OPERATOR(Mshifted, ldshifted, D, Shiftmass);
00240 
00241     Mshifted (Mshifted, psi_test, r, Ncb, PLUS);
00242 
00243     FREE_LINEAR_OPERATOR(Mshifted);
00244     
00245     Shiftmass = - TO_REAL(1);
00246     for(cb = 0; cb < Ncb; cb++) { 
00247       r[cb] = r[cb] * Shiftmass;
00248       r[cb] = chi[cb] + r[cb];
00249     }
00250 
00251 
00252     r_norm = 0;
00253     for(cb = 0; cb < Ncb; cb++) { 
00254       r_norm += norm2(r[cb]);
00255     }
00256 
00257     r_norm = sqrt(r_norm);
00258     r_norm /= chi_norm;
00259     RsdMR_array[i] = FLOAT(r_norm); 
00260   }
00261 
00262   MaxRsd = RsdMR_array[0];
00263   for( i=1; i < Nshift; i++) { 
00264     if( RsdMR_array[i] > MaxRsd ) { 
00265       MaxRsd  = RsdMR_array[i];
00266     }
00267   }
00268   PRINTF("TrLnSolve: n_count = %d, RsdMR = %16.8e, MaxRsd = %16.8e\n", 
00269          n_count, RsdMR, MaxRsd);
00270 
00271     /* Flip off Boundary Conditions */
00272   phfctr (u, BACKWARD);
00273 
00274 
00275   /* Now make sure we have all converged */
00276   /* push(xml_out,"pade_trln_rsd");
00277 write(xml_out, "RsdMR_array", RsdMR_array);
00278 pop(xml_out); */
00279 
00280   
00281 
00282   for(i=0; i < Nkappa; i++) { 
00283     tmp = TO_REAL(1) / Kappas[i];
00284     for(cb = 0; cb < Ncb; cb++) { 
00285       psi[i][cb] = psi[i][cb] * tmp;
00286     }
00287   }
00288 
00289   j=Nkappa; 
00290   for(i=0; i < Nkappa; i++) { 
00291     tmp = TO_REAL(1) / Kappas[i];
00292     for(l=0; l < Npade; l++) { 
00293       for(cb = 0; cb < Ncb; cb++) {
00294         psi[j][cb] = psi[j][cb] * tmp; 
00295       }
00296       j++;
00297     }
00298   }
00299 
00300   /* Work out dumb psibar psi estimates */
00301       
00302 
00303   for(i = 0; i < Nkappa; i++) { 
00304 
00305     lc = trace(adj[chi[0]] * psi[i][0]);
00306    
00307     for(cb = 1; cb < Ncb; cb++) { 
00308       lct = trace(adj[chi[cb]] * psi[i][cb]);
00309       lc += lct;
00310     }
00311  
00312     dcsum = sum(lc);
00313    
00314     psibp_unimp[i] = FLOAT(dcsum);
00315   
00316   }
00317   
00318 
00319   /* Now try to compute TrLn = b0 TrI - sum Pade_c(l) chi (M + c(l))^{-1} chi */
00320 
00321   /* First find the first term: Pade_b0 * Tr I, where Tr I = Nc * Nd * V */
00322     TrI = TO_REAL(Ns*Nc)*TO_REAL(2)*TO_REAL(vol_cb);
00323   trlns_unimp = 1;
00324   tmp = TrI * Pade_b0;
00325   FILL(first_terms, tmp);
00326   trlns_unimp = first_terms * trlns_unimp;
00327   
00328   /* Now get the remaining Npade terms */
00329   
00330   j = Nkappa;
00331   for(i = 0 ; i < Nkappa; i++) {
00332     for(l = 0; l < Npade; l++) {
00333 
00334       /* pade_diag_term(l) = < chi, M(kappa, pade_c) chi > */
00335       lc = trace(adj[chi[0]] * psi[j][0]);
00336       for(cb = 1; cb < Ncb; cb++) {
00337         lct = trace(adj[chi[cb]] * psi[j][cb]);
00338         lc += lct;
00339       }
00340 
00341       /* Sum up the traces */
00342       dcsum = sum(lc);
00343 
00344       /* Change to floating point */
00345       csum = FLOAT(dcsum);
00346       csum = Pade_b[l] * csum;
00347       pade_terms[l] = csum * minusone;
00348       trlns_unimp[i] += pade_terms[l];
00349       j++;
00350       
00351     }
00352   }
00353 
00354   /* Work out subtraction terms. First the estimators of the 
00355      traceless operators */
00356 
00357   /* 1 Work out plaquette for 4-th order term */
00358   MesPlq (u, w_plaq, s_plaq, t_plaq, link);
00359   
00360   f_plaq = FLOAT(w_plaq);
00361 
00362   
00363      
00364     bilinear = 0;
00365 
00366   
00367   
00368   /* Copy chi -> r */
00369   for(cb=0; cb < Ncb; cb++) {
00370     r[cb] = chi[cb];
00371   }
00372   
00373   
00374   /* Flip bc-s back on */
00375   phfctr (u, FORWARD);
00376 
00377   for(i=0; i < Nimpr; i++) { 
00378     
00379     /* Apply Dslash: Dchi = Dslash r */
00380     for(cb=0; cb < Ncb; cb++) {
00381       dslash (u, r[cb], Dchi[1-cb], PLUS, cb);
00382     }
00383 
00384     /* Now trace Dchi with chi to get the bilinear(term) chi D chi */
00385     lc = trace(adj[chi[0]] * Dchi[0]);
00386     for(cb = 1; cb < Ncb; cb++) {
00387       lct = trace(adj[chi[cb]] * Dchi[cb]);
00388       lc += lct;
00389     }
00390     
00391     /* Sum up the traces */
00392     dcsum = sum(lc);
00393 
00394     /* Change to floating point */
00395     bilinear[i] = FLOAT(dcsum);
00396 
00397     /* If i corresponds to an even powered term (recall i goes from 0) */
00398     if ( (i + 1) % 2 == 0 ) {
00399 
00400       /* Deal with the even power appropriately */
00401       switch( i + 1 ) { 
00402       case 2:
00403         /* Second order term is traceless */
00404         break;
00405       case 4:
00406         
00407         /* Here we will put the plaquette */
00408         c_plaq = 1;
00409         tmp = TO_REAL(64)*f_plaq*TO_REAL(3)*TO_REAL(6)*TO_REAL(Ncb)*TO_REAL(vol_cb);
00410         c_plaq = tmp * c_plaq;
00411         bilinear[i] += c_plaq;
00412         break;
00413       default:
00414 
00415         /* Anything higher than 4th order we will ignore for now */
00416         bilinear[i] = 0;
00417         break;
00418       }
00419 
00420     }
00421 
00422     /* Now copy Dchi back to R for the next iteration */
00423     for(cb = 0; cb < Ncb; cb++) { 
00424       r[cb] = Dchi[cb];
00425     }
00426   }
00427 
00428   phfctr (u, BACKWARD);
00429 
00430   /* We are done with Dchi -> NOw dealing with the bilinears only */
00431   
00432   for(kappa=0; kappa < Nkappa; kappa++) { 
00433     for(i = 0; i < Nimpr; i++) { 
00434       
00435       /* psib_offterm = kappa^{i+1} bilinear(i) */
00436       kappa_pow = pow((double)Kappas[kappa], (double)TO_REAL(i+1));
00437       
00438       psib_offterms[i][kappa] = kappa_pow * bilinear[i];
00439 
00440       for(l = 0; l < Npade; l++) { 
00441         
00442         /* Pade_offterm(order) = kappa^{i+1}/(1 + c(order))^{i+2} */
00443         tmp = TO_REAL(1) / (TO_REAL(1) + Pade_c[l]);
00444         pade_c_pow = pow((double)tmp, (double)TO_REAL(i+2));
00445         tmp = -Pade_b[l]*kappa_pow * pade_c_pow;
00446         trln_offterms[i][l][kappa] = tmp * bilinear[i];
00447       }
00448     }
00449   }
00450 
00451   
00452   sum_trln_offterms = 0;
00453 
00454   for(kappa=0; kappa < Nkappa; kappa++) { 
00455     for(i = 0; i < Nimpr; i++) { 
00456       for(l = 0; l < Npade; l++) { 
00457         sum_trln_offterms[i][kappa] += trln_offterms[i][l][kappa];
00458       }
00459 
00460       /* Multiply each term by the subtraction coefficient omega */
00461       sum_trln_offterms[i][kappa] = Omega_impr[i] * sum_trln_offterms[i][kappa];
00462 
00463       psib_offterms[i][kappa] = Omega_impr[i] * psib_offterms[i][kappa];
00464     }
00465   }
00466 
00467   /* push(xml_out,"PsiBarPsiOffterms");
00468 write(xml_out, "psib_offterms", psib_offterms);
00469 pop(xml_out);
00470      push(xml_out,"TrlnOffterms");
00471 write(xml_out, "sum_trln_offterms", sum_trln_offterms);
00472 pop(xml_out); */
00473 
00474   /* Now construct improved estimates */
00475   psibp_imp = psibp_unimp;
00476   trlns_imp = trlns_unimp;
00477 
00478   for(kappa=0; kappa < Nkappa; kappa++) { 
00479 
00480     for(i=0; i < Nimpr; i++) { 
00481       psibp_imp[kappa] -= psib_offterms[i][kappa];
00482       trlns_imp[kappa] -= sum_trln_offterms[i][kappa];
00483     }
00484   }
00485 
00486   /* Normalise psi bar psi */
00487   TrI = TO_REAL(1)/ TrI;
00488 
00489   for(kappa=0; kappa < Nkappa; kappa++) { 
00490     psibp_imp[kappa] = psibp_imp[kappa] * TrI;
00491     psibp_unimp[kappa] = psibp_unimp[kappa] * TrI;
00492   }
00493 
00494 
00495         
00496               DestDslash (D, WILSON_DSLASH);
00497        
00498       
00499   END_CODE();
00500 }

Generated on Sun Nov 22 04:33:38 2009 for CHROMA by  doxygen 1.4.7