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

alg_pbp.C

Go to the documentation of this file.
00001 #include<config.h>
00002 CPS_START_NAMESPACE
00008 //--------------------------------------------------------------------
00009 //  CVS keywords
00010 //
00011 //  $Author: chulwoo $
00012 //  $Date: 2006/02/21 21:14:07 $
00013 //  $Header: /space/cvs/cps/cps++/src/alg/alg_pbp/alg_pbp.C,v 1.13 2006/02/21 21:14:07 chulwoo Exp $
00014 //  $Id: alg_pbp.C,v 1.13 2006/02/21 21:14:07 chulwoo Exp $
00015 //  $Name: v5_0_8 $
00016 //  $Locker:  $
00017 //  $RCSfile: alg_pbp.C,v $
00018 //  $Revision: 1.13 $
00019 //  $Source: /space/cvs/cps/cps++/src/alg/alg_pbp/alg_pbp.C,v $
00020 //  $State: Exp $
00021 //
00022 //--------------------------------------------------------------------
00023 //------------------------------------------------------------------
00024 //
00025 // alg_pbp.C
00026 //
00027 // AlgPbp is derived from Alg and is relevant to the 
00028 // stochastic measurement of PsiBar Psi using the
00029 // Conjugate Gradient algorithm. The type of fermion is
00030 // determined by the argument to the constructor.
00031 //
00032 // PsiBarPsi is normalized so that for large values of the
00033 // PbpArg.mass  PsiBarPsi =  1 / mass for any fermion type.
00034 // This normalization results to the following small mass
00035 // behavior for a trivial background gauge field with periodic
00036 // boundary conditions:
00037 // Staggered = 16 / ( Volume * mass )
00038 // Wilson    =  1 / ( Volume * mass )
00039 // Dwf       =  1 / ( Volume * mass )
00040 //
00041 //------------------------------------------------------------------
00042 
00043 CPS_END_NAMESPACE
00044 #include <util/qcdio.h>
00045 #include <alg/alg_pbp.h>
00046 #include <util/lattice.h>
00047 #include <util/gjp.h>
00048 #include <util/smalloc.h>
00049 #include <util/vector.h>
00050 #include <util/verbose.h>
00051 #include <util/error.h>
00052 CPS_START_NAMESPACE
00053 
00054 #define POINT
00055 #undef POINT
00056 #define Z2
00057 #undef Z2
00058 //------------------------------------------------------------------
00064 //------------------------------------------------------------------
00065 AlgPbp::AlgPbp(Lattice& latt, 
00066                CommonArg *c_arg,
00067                PbpArg *arg) : 
00068                Alg(latt, c_arg) 
00069 {
00070   cname = "AlgPbp";
00071   char *fname = "AlgPbp(L&,CommonArg*,PbpArg*)";
00072   VRB.Func(cname,fname);
00073 
00074   // Initialize the argument pointer
00075   //----------------------------------------------------------------
00076   if(arg == 0)
00077     ERR.Pointer(cname,fname, "arg");
00078   alg_pbp_arg = arg;
00079 
00080 
00081   // Set the node size of the full (non-checkerboarded) fermion field
00082   //----------------------------------------------------------------
00083   f_size = GJP.VolNodeSites() * latt.FsiteSize();
00084 
00085 
00086   // Allocate memory for the source.
00087   //----------------------------------------------------------------
00088   src = (Vector *) smalloc(f_size * sizeof(Float));
00089   if(src == 0)
00090     ERR.Pointer(cname,fname, "src");
00091   VRB.Smalloc(cname,fname, "src", src, f_size * sizeof(Float));
00092 
00093 
00094   // Allocate memory for the solution
00095   //----------------------------------------------------------------
00096   sol = (Vector *) smalloc(f_size * sizeof(Float));
00097   if(sol == 0)
00098     ERR.Pointer(cname,fname, "sol");
00099   VRB.Smalloc(cname,fname, "sol", sol, f_size * sizeof(Float));
00100 
00101 
00102 }
00103 
00104 
00105 //------------------------------------------------------------------
00106 // Destructor
00107 //------------------------------------------------------------------
00108 AlgPbp::~AlgPbp() {
00109   char *fname = "~AlgPbp()";
00110   VRB.Func(cname,fname);
00111 
00112   // Free memory
00113   //----------------------------------------------------------------
00114   VRB.Sfree(cname,fname, "sol", sol);
00115   sfree(sol);
00116   VRB.Sfree(cname,fname, "src", src);
00117   sfree(src);
00118 }
00119 
00120 
00121 //------------------------------------------------------------------
00123 
00127 //------------------------------------------------------------------
00128 void AlgPbp::run()
00129 {
00130 #if TARGET==cpsMPI
00131     using MPISCU::fprintf;
00132 #endif
00133   int iter;
00134   int ls;
00135   int ls_glb;
00136   Float pbp= 0., pbd0p, pbdip;
00137   Float pbg5p= 0.;
00138   Float pbp_norm;
00139   Float true_res;
00140   PbpArg *pbp_arg;
00141   CgArg cg_arg_struct;
00142   CgArg *cg_arg = &cg_arg_struct;
00143   char *fname = "run()";
00144   VRB.Func(cname,fname);
00145 
00147 
00148 
00149   // Set the Lattice pointer pbp_arg and cg_arg
00150   //----------------------------------------------------------------
00151   Lattice& lat = AlgLattice();
00152   pbp_arg = alg_pbp_arg;
00153   cg_arg->max_num_iter = pbp_arg->max_num_iter;
00154   cg_arg->stop_rsd = pbp_arg->stop_rsd;
00155   
00156   // Make a Float pointer to sol
00157   //----------------------------------------------------------------
00158   Float *f_sol = (Float *) sol;
00159 
00160   //----------------------------------------------------------------
00161   // Initialize source and solution (initial guess)
00162   // and calculate PsiBarPsi for:
00163   //----------------------------------------------------------------
00164 
00165 
00166   //----------------------------------------------------------------
00167   // Domain Wall fermions
00168   //----------------------------------------------------------------
00169   if(lat.Fclass() == F_CLASS_DWF){
00170     ls = GJP.SnodeSites();
00171     ls_glb = GJP.Snodes() * GJP.SnodeSites();
00172 
00173     // Allocate memory for the 4-dimensional source, solution
00174     Vector *src_4d = (Vector *) smalloc(f_size * sizeof(Float) / ls);
00175     if(src_4d == 0)
00176       ERR.Pointer(cname,fname, "src_4d");
00177     VRB.Smalloc(cname,fname, "src_4d", src_4d, f_size * sizeof(Float) / ls);
00178     Vector *sol_4d = (Vector *) smalloc(f_size * sizeof(Float) / ls);
00179     if(sol_4d == 0)
00180       ERR.Pointer(cname,fname, "sol_4d");
00181     VRB.Smalloc(cname,fname, "sol_4d", sol_4d, f_size * sizeof(Float) / ls);
00182 
00183     // allocate space for pbp, pb_g5_p array
00184     Float * pbp_all = (Float *) smalloc(ls_glb * sizeof(Float));
00185     if(pbp_all == 0)
00186       ERR.Pointer(cname,fname, "pbp_all");
00187     VRB.Smalloc(cname,fname, "pbp_all", pbp_all, ls_glb * sizeof(Float));
00188 
00189     Float * pbg5p_all = (Float *) smalloc(ls_glb * sizeof(Float));
00190     if(pbg5p_all == 0)
00191       ERR.Pointer(cname,fname, "pbg5p_all");
00192     VRB.Smalloc(cname,fname, "pbg5p_all", pbg5p_all, ls_glb * sizeof(Float));
00193 
00194 
00195     // initialize 4-dimensional source
00196     lat.RandGaussVector(src_4d, 0.5, FOUR_D);
00197 
00198     // set the 5-dimensional source
00199     lat.Ffour2five(src, src_4d, pbp_arg->src_u_s, pbp_arg->src_l_s);
00200 
00201     // Initialize the cg_arg mass, with the first mass we
00202     // want to compute for:
00203     switch( pbp_arg->pattern_kind ) {
00204     case ARRAY: 
00205       cg_arg->mass = pbp_arg->mass[0]; 
00206       break;
00207     case LIN:   
00208       cg_arg->mass = pbp_arg->mass_start; 
00209       break;
00210     case LOG:   
00211       cg_arg->mass = pbp_arg->mass_start; 
00212       break;
00213     default: 
00214       ERR.General(cname, fname,
00215                   "pbp_arg->pattern_kind = %d is unrecognized\n", 
00216                   pbp_arg->pattern_kind);
00217       break;
00218     }
00219 
00220     // Loop over masses
00221     for(int m=0; m<pbp_arg->n_masses; m++){
00222 
00223       // initialize 5-dimensional solution (initial guess) to 1
00224       for(int i=0; i< f_size/2; i++){
00225         f_sol[2*i] = 1.0;     // real part
00226         f_sol[2*i+1] = 0.0;   // imaginary part
00227       }
00228 
00229       // do inversion
00230       iter = lat.FmatInv(sol, src, cg_arg, &true_res, CNV_FRM_YES);
00231 
00232       // Calculate the pbp normalization factor 
00233       pbp_norm = (4.0 + GJP.DwfA5Inv() - GJP.DwfHeight())
00234         * GJP.VolSites() 
00235         * ( lat.FsiteSize() / (2 * GJP.SnodeSites()) );  
00236 
00237       if (pbp_arg->snk_loop) {
00238         // Loop over sink - source separation
00239         for (int i = 0; i < ls_glb; i++) {
00240           // set the 4-dimensional solution
00241           lat.Ffive2four(sol_4d, sol, i, ls_glb - i - 1);
00242           
00243           // Calculate pbp
00244           pbp_all[i] = sol_4d->ReDotProductGlbSum4D(src_4d, f_size/ls)
00245                      / pbp_norm;
00246 
00247           // Calculate pbg5p = Tr[ PsiBar * Gamma5 * Psi]
00248           lat.Gamma5(sol_4d, sol_4d, GJP.VolNodeSites());
00249           pbg5p_all[i] = sol_4d->ReDotProductGlbSum4D(src_4d, f_size/ls)
00250                        / pbp_norm;
00251         }
00252       } 
00253       else {
00254         // set the 4-dimensional solution
00255         lat.Ffive2four(sol_4d, sol, pbp_arg->snk_u_s, pbp_arg->snk_l_s);
00256 
00257         // Calculate pbp
00258         pbp = sol_4d->ReDotProductGlbSum4D(src_4d, f_size/ls) / pbp_norm;
00259 
00260         // Calculate pbg5p = Tr[ PsiBar * Gamma5 * Psi]
00261         lat.Gamma5(sol_4d, sol_4d, GJP.VolNodeSites());
00262         pbg5p = sol_4d->ReDotProductGlbSum4D(src_4d, f_size/ls) / pbp_norm;
00263       }
00264 
00265       // Open file for results
00266       if(common_arg->results != 0){
00267         FILE *fp;
00268         if( (fp = Fopen((char *)common_arg->results, "a")) == NULL ) {
00269           ERR.FileA(cname,fname, (char *)common_arg->results);
00270         }
00271         if (pbp_arg->snk_loop) {
00272           // Print out mass, s-slice, pbp ,pbg5p, number of iterations
00273           // and true residual
00274           for (int i = 0; i < ls_glb; i++) {
00275             Fprintf(fp,"%0.16e %d %0.16e %0.16e %d %0.16e\n", 
00276                     IFloat(cg_arg->mass), 
00277                     i,
00278                     IFloat(pbp_all[i]), 
00279                     IFloat(pbg5p_all[i]), 
00280                     iter,
00281                     IFloat(true_res));
00282           }
00283         } 
00284         else {
00285           // Print out mass, pbp, pbg5p, number of iterations and true residual
00286           Fprintf(fp, "%0.16e %0.16e %0.16e %d %0.16e\n", 
00287                   IFloat(cg_arg->mass),
00288                   IFloat(pbp), 
00289                   IFloat(pbg5p), 
00290                   iter, 
00291                   IFloat(true_res));
00292         }
00293         Fclose(fp);
00294       }
00295 
00296       // If there is another mass loop iteration ahead, we should
00297       // set the cg_arg->mass to it's next desired value
00298       if( m < pbp_arg->n_masses - 1 ) {
00299         switch( pbp_arg->pattern_kind ) {
00300         case ARRAY: 
00301           cg_arg->mass = pbp_arg->mass[m+1]; 
00302           break;
00303         case LIN:   
00304           cg_arg->mass += pbp_arg->mass_step; 
00305           break;
00306         case LOG:   
00307           cg_arg->mass *= pbp_arg->mass_step; 
00308           break;
00309         }
00310       }
00311     }
00312 
00313     // free the 4-dimensional source, solution, pbp, and pbg5p
00314     VRB.Sfree(cname,fname, "pbg5p_all", pbg5p_all);
00315     sfree(pbg5p_all);
00316     VRB.Sfree(cname,fname, "pbp_all", pbp_all);
00317     sfree(pbp_all);
00318     VRB.Sfree(cname,fname, "sol_4d", sol_4d);
00319     sfree(sol_4d);
00320     VRB.Sfree(cname,fname, "src_4d", src_4d);
00321     sfree(src_4d);
00322 
00323   }
00324 
00325   //----------------------------------------------------------------
00326   // Wilson or Clover fermions
00327   //----------------------------------------------------------------
00328   else if (   (lat.Fclass() == F_CLASS_WILSON) 
00329            || (lat.Fclass() == F_CLASS_CLOVER)   ) {  
00330 
00331     // Allocate memory for gamma_5 * solution
00332     Vector *sol_g5 = (Vector *) smalloc(f_size * sizeof(Float));
00333     if(sol_g5 == 0)
00334       ERR.Pointer(cname,fname, "sol_g5");
00335     VRB.Smalloc(cname,fname, "sol_g5", sol_g5, f_size * sizeof(Float));
00336 
00337     // set source
00338     lat.RandGaussVector(src, 0.5);
00339 
00340     // Initialize the cg_arg mass, with the first mass we
00341     // want to compute for:
00342     switch( pbp_arg->pattern_kind ) {
00343     case ARRAY: 
00344       cg_arg->mass = pbp_arg->mass[0]; 
00345       break;
00346     case LIN:   
00347       cg_arg->mass = pbp_arg->mass_start; 
00348       break;
00349     case LOG:   
00350       cg_arg->mass = pbp_arg->mass_start; 
00351       break;
00352     default: 
00353       ERR.General(cname, fname,
00354                   "pbp_arg->kind = %d is unrecognized\n", 
00355                   pbp_arg->pattern_kind);
00356       break;
00357     }
00358 
00359     // Loop over masses
00360     for(int m=0; m<pbp_arg->n_masses; m++){
00361       
00362       // initialize solution (initial guess) to 1
00363       for(int i=0; i< f_size/2; i++){
00364         f_sol[2*i] = 1.0;     // real part
00365         f_sol[2*i+1] = 0.0;   // imaginary part
00366       }
00367 
00368       // do inversion
00369       iter = lat.FmatInv(sol, src, cg_arg, &true_res, CNV_FRM_YES);
00370 
00371       // Calculate the pbp normalization factor
00372       pbp_norm = ( (4.0 + cg_arg->mass) )
00373                  * (GJP.VolSites() 
00374                  * ( lat.FsiteSize()) / 2 );
00375 
00376       // calculate pbp
00377       pbp = sol->ReDotProductGlbSum4D(src, f_size) / pbp_norm;
00378 
00379       // Calculate pbg5p = Tr[ PsiBar * Gamma5 * Psi]
00380       lat.Gamma5(sol_g5, sol, GJP.VolNodeSites());
00381       pbg5p = sol_g5->ReDotProductGlbSum4D(src, f_size) / pbp_norm;
00382 
00383       // Print out mass, pbp, pbg5p number of iterations and true residual
00384       if(common_arg->results != 0){
00385         FILE *fp;
00386         if( (fp = Fopen((char *)common_arg->results, "a")) == NULL ) {
00387           ERR.FileA(cname,fname, (char *)common_arg->results);
00388         }
00389         Fprintf(fp, "%0.16e %0.16e %0.16e %d %0.16e\n", 
00390                 IFloat(cg_arg->mass), 
00391                 IFloat(pbp), 
00392                 IFloat(pbg5p), 
00393                 iter, 
00394                 IFloat(true_res));
00395         Fclose(fp);
00396       }
00397 
00398       // If there is another mass loop iteration ahead, we should
00399       // set the cg_arg->mass to it's next desired value
00400       if( m < pbp_arg->n_masses - 1 ) {
00401         switch( pbp_arg->pattern_kind ) {
00402         case ARRAY: 
00403           cg_arg->mass = pbp_arg->mass[m+1]; 
00404           break;
00405         case LIN:   
00406           cg_arg->mass += pbp_arg->mass_step; 
00407           break;
00408         case LOG:   
00409           cg_arg->mass *= pbp_arg->mass_step; 
00410           break;
00411         }
00412       }
00413 
00414     }
00415 
00416     // free the gamma_5 * solution
00417     VRB.Sfree(cname,fname, "sol_g5", sol_g5);
00418     sfree(sol_g5);
00419   }
00420 
00421   //----------------------------------------------------------------
00422   // Staggered fermions
00423   //----------------------------------------------------------------
00424   else if ( (lat.Fclass() == F_CLASS_STAG)
00425            || (lat.Fclass() == F_CLASS_P4)
00426            || (lat.Fclass() == F_CLASS_ASQTAD)   ) {  
00427 
00428     Vector*  alt_sol = (Vector *) smalloc(f_size * sizeof(Float));
00429     if(alt_sol == 0)
00430       ERR.Pointer(cname,fname, "alt_sol");
00431     VRB.Smalloc(cname,fname, "alt_sol", alt_sol, f_size * sizeof(Float));
00432 
00433     // set source
00434 #ifdef POINT
00435     bzero((char *)src, f_size*sizeof(Float));
00436     if(CoorX()==0 && CoorY()==0 && CoorZ()==0 && CoorT()==0)
00437       {
00438         *((IFloat *) &src[0]) = 1.0;
00439         printf("Setting point source at origin\n");
00440       }
00441     for(int zz = 0; zz < GJP.VolNodeSites(); zz++)
00442       for(int yy = 0; yy < 6; yy++)
00443         if(*(((IFloat *)&src[zz])+yy) > 1e-15)
00444           printf("zz = %d, yy = %d, *(src+zz) = %0.16e\n", zz, yy, *(((IFloat *)&src[zz])+yy));
00445 #else
00446     lat.RandGaussVector(src, 0.5);
00447 #endif
00448 
00449 #ifdef Z2
00450     IFloat * tmp1;
00451     for(int zz = 0; zz < GJP.VolNodeSites(); zz++)
00452       for(int yy = 0; yy < 6; yy+=2)
00453         {
00454           tmp1 = (IFloat *)(src + zz);
00455           if(*(tmp1+yy) > 0)
00456             *(tmp1+yy) = 1.0;
00457           else
00458             *(tmp1+yy) = -1.0;
00459           *(tmp1 +yy+ 1) = 0.0;
00460         }
00461     //printf("Setting Z_2 source.\n");
00462     //int check_site = 29;
00463     //printf("Site %d =\n",check_site);
00464     //tmp1 = (IFloat *)(src + check_site);
00465     //for(int yy = 0; yy < 6; yy++)
00466     //  printf("%0.16e  ",*(tmp1+yy));
00467     //printf("\n");
00468 #endif
00469 
00470     // Initialize the cg_arg mass, with the first mass we
00471     // want to compute for:
00472     switch( pbp_arg->pattern_kind ) {
00473     case ARRAY: 
00474       cg_arg->mass = pbp_arg->mass[0]; 
00475       break;
00476     case LIN:   
00477       cg_arg->mass = pbp_arg->mass_start; 
00478       break;
00479     case LOG:   
00480       cg_arg->mass = pbp_arg->mass_start; 
00481       break;
00482     default: 
00483       ERR.General(cname, fname,
00484                   "pbp_arg->kind = %d is unrecognized\n", 
00485                   pbp_arg->pattern_kind);
00486       break;
00487     }
00488 
00489     // Loop over masses
00490     for(int m=0; m<pbp_arg->n_masses; m++){
00491       
00492       // initialize solution (initial guess) to 1
00493       for(int i=0; i< f_size/2; i++){
00494         f_sol[2*i] = 1.0;     // real part
00495         f_sol[2*i+1] = 0.0;   // imaginary part
00496       }
00497 
00498       // do inversion
00499       iter = lat.FmatInv(sol, src, cg_arg, &true_res, CNV_FRM_YES);
00500 
00501       // Modified for anisotropic lattices
00502       // Calculate the pbp normalization factor
00503 #ifdef POINT
00504       pbp_norm = 1.0;
00505 #else
00506       pbp_norm = GJP.VolSites() * ( lat.FsiteSize() / 2 );
00507 #endif
00508 
00509       Float norm = src->ReDotProductGlbSum4D(src, f_size) / pbp_norm;
00510 
00511       lat.Fdslash(alt_sol, sol, cg_arg, CNV_FRM_YES, 1);
00512       pbd0p = alt_sol->ReDotProductGlbSum4D(src, f_size) 
00513         / (pbp_norm * GJP.XiVXi());
00514 
00515       pbp_norm *= GJP.XiV()/GJP.XiBare(); 
00516       
00517       // calculate pbp and pbdip
00518       pbp = sol->ReDotProductGlbSum4D(src, f_size) / pbp_norm * 2;
00519       pbdip = (norm- (cg_arg->mass)*pbp 
00520                - GJP.XiVXi()*pbd0p)*GJP.XiBare()/GJP.XiV();
00521         
00522       // Print out mass, pbp number of iterations and true residual
00523       if(common_arg->results != 0){
00524         FILE *fp;
00525         if( (fp = Fopen((char *)common_arg->results, "a")) == NULL ) {
00526           ERR.FileA(cname,fname, (char *)common_arg->results);
00527         }
00528         Fprintf(fp, "%0.16e %0.16e %0.16e %0.16e %d %0.16e\n", 
00529                 IFloat(cg_arg->mass), 
00530                 IFloat(pbp), IFloat(pbd0p), IFloat(pbdip), 
00531                 iter, 
00532                 IFloat(true_res));
00533         Fclose(fp);
00534       }
00535 
00536       // If there is another mass loop iteration ahead, we should
00537       // set the cg_arg->mass to it's next desired value
00538       if( m < pbp_arg->n_masses - 1 ) {
00539         switch( pbp_arg->pattern_kind ) {
00540         case ARRAY: 
00541           cg_arg->mass = pbp_arg->mass[m+1]; 
00542           break;
00543         case LIN:   
00544           cg_arg->mass += pbp_arg->mass_step; 
00545           break;
00546         case LOG:   
00547           cg_arg->mass *= pbp_arg->mass_step; 
00548           break;
00549         }
00550       }
00551 
00552     }
00553     VRB.Sfree(cname,fname, "alt_sol", alt_sol);
00554     sfree(alt_sol);
00555     
00556   }
00557 
00558   //----------------------------------------------------------------
00559   // Unknown fermion type
00560   //----------------------------------------------------------------
00561   else {
00562     ERR.General(cname,fname,"Unknown class type %d\n",int(lat.Fclass()));
00563   }
00564 
00565 }
00566 
00567 
00568 
00569 
00570 //------------------------------------------------------------------
00572 
00591 //------------------------------------------------------------------
00592 void AlgPbp::runPointSource(int x, int y, int z, int t)
00593 {
00594 #if TARGET==cpsMPI
00595     using MPISCU::fprintf;
00596 #endif
00597   int i;
00598   int iter;
00599   int ls;
00600   int ls_glb;
00601   Float pbp, pbptmp;
00602   Float pbg5p, pbg5ptmp;
00603   Float pbp_norm;
00604   Float true_res;
00605   PbpArg *pbp_arg;
00606   CgArg cg_arg_struct;
00607   CgArg *cg_arg = &cg_arg_struct;
00608   char *fname = "runPointSource()";
00609   VRB.Func(cname,fname);
00610 
00611   // Set the Lattice pointer pbp_arg and cg_arg
00612   //----------------------------------------------------------------
00613   Lattice& lat = AlgLattice();
00614   pbp_arg = alg_pbp_arg;
00615   cg_arg->max_num_iter = pbp_arg->max_num_iter;
00616   cg_arg->stop_rsd = pbp_arg->stop_rsd;
00617   
00618   // Make a Float pointer to sol
00619   //----------------------------------------------------------------
00620   Float *f_sol = (Float *) sol;
00621 
00622   //----------------------------------------------------------------
00623   // Initialize source and solution (initial guess)
00624   // and calculate PsiBarPsi for:
00625   //----------------------------------------------------------------
00626 
00627 
00628   //----------------------------------------------------------------
00629   // Domain Wall fermions
00630   //----------------------------------------------------------------
00631   if(lat.Fclass() == F_CLASS_DWF){
00632     ls = GJP.SnodeSites();
00633     ls_glb = GJP.Snodes() * GJP.SnodeSites();
00634 
00635     // Allocate memory for the 4-dimensional source, solution
00636     Vector *src_4d = (Vector *) smalloc(f_size * sizeof(Float) / ls);
00637     if(src_4d == 0)
00638       ERR.Pointer(cname,fname, "src_4d");
00639     VRB.Smalloc(cname,fname, "src_4d", src_4d, f_size * sizeof(Float) / ls);
00640     Vector *sol_4d = (Vector *) smalloc(f_size * sizeof(Float) / ls);
00641     if(sol_4d == 0)
00642       ERR.Pointer(cname,fname, "sol_4d");
00643     VRB.Smalloc(cname,fname, "sol_4d", sol_4d, f_size * sizeof(Float) / ls);
00644 
00645     // allocate space for pbp, pb_g5_p array
00646     Float * pbp_all = (Float *) smalloc(ls_glb * sizeof(Float));
00647     if(pbp_all == 0)
00648       ERR.Pointer(cname,fname, "pbp_all");
00649     VRB.Smalloc(cname,fname, "pbp_all", pbp_all, ls_glb * sizeof(Float));
00650 
00651     Float * pbg5p_all = (Float *) smalloc(ls_glb * sizeof(Float));
00652     if(pbg5p_all == 0)
00653       ERR.Pointer(cname,fname, "pbg5p_all");
00654     VRB.Smalloc(cname,fname, "pbg5p_all", pbg5p_all, ls_glb * sizeof(Float));
00655 
00656     // allocate space for pbp, pb_g5_p temporary array
00657     Float * pbp_tmp = (Float *) smalloc(ls_glb * sizeof(Float));
00658     if(pbp_tmp == 0)
00659       ERR.Pointer(cname,fname, "pbp_tmp");
00660     VRB.Smalloc(cname,fname, "pbp_tmp", pbp_tmp, ls_glb * sizeof(Float));
00661 
00662     Float * pbg5p_tmp = (Float *) smalloc(ls_glb * sizeof(Float));
00663     if(pbg5p_all == 0)
00664       ERR.Pointer(cname,fname, "pbg5p_tmp");
00665     VRB.Smalloc(cname,fname, "pbg5p_tmp", pbg5p_tmp, ls_glb * sizeof(Float));
00666 
00667     // Initialize the cg_arg mass, with the first mass we
00668     // want to compute for:
00669     switch( pbp_arg->pattern_kind ) {
00670     case ARRAY: 
00671       cg_arg->mass = pbp_arg->mass[0]; 
00672       break;
00673     case LIN:   
00674       cg_arg->mass = pbp_arg->mass_start; 
00675       break;
00676     case LOG:   
00677       cg_arg->mass = pbp_arg->mass_start; 
00678       break;
00679     default: 
00680       ERR.General(cname, fname,
00681                   "pbp_arg->pattern_kind = %d is unrecognized\n", 
00682                   pbp_arg->pattern_kind);
00683       break;
00684     }
00685     
00686     // Loop over masses
00687     for(int m=0; m<pbp_arg->n_masses; m++){
00688           
00689       pbptmp = (Float) 0.0;
00690       pbg5ptmp = (Float) 0.0;
00691 
00692       for (i = 0; i < ls_glb; i++) {
00693         pbp_tmp[i] = (Float) 0.0;
00694         pbg5p_tmp[i] = (Float) 0.0;
00695       }
00696       
00697       // initialize 4-dimensional source 
00698       for (int color = 0; color < GJP.Colors(); color++)
00699           for (int spin = 0; spin < 4; spin++) {
00700             
00701             // trap for wrong arguments
00702             if (x < 0 || x >= GJP.Xnodes() * GJP.XnodeSites() ||
00703                 y < 0 || y >= GJP.Ynodes() * GJP.YnodeSites() ||
00704                 z < 0 || z >= GJP.Znodes() * GJP.ZnodeSites() ||
00705                 t < 0 || t >= GJP.Tnodes() * GJP.TnodeSites())
00706               ERR.General(cname, fname, 
00707                  "Coordonate arguments out of range: x=%d, y=%d, z=%d, t=%d\n",
00708                           x, y, z, t);
00709         
00710             if (color < 0 || color >= GJP.Colors())
00711               ERR.General(cname, fname,
00712                           "Color index out of range: color = %d\n", color);
00713           
00714             if (spin < 0 || spin > 3)
00715               ERR.General(cname, fname,
00716                           "Spin index out of range: spin = %d\n", spin);
00717           
00718             // zero the vector
00719             int fv_size = GJP.VolNodeSites() * GJP.Colors() * 8;
00720             for ( i = 0; i < fv_size; i++)
00721               *((IFloat *)src_4d + i) = 0;
00722             
00723             // set point source
00724             int procCoorX = x / GJP.XnodeSites();
00725             int procCoorY = y / GJP.YnodeSites();
00726             int procCoorZ = z / GJP.ZnodeSites();
00727             int procCoorT = t / GJP.TnodeSites();
00728             int localX = x % GJP.XnodeSites();
00729             int localY = y % GJP.YnodeSites();
00730             int localZ = z % GJP.ZnodeSites();
00731             int localT = t % GJP.TnodeSites();
00732             
00733             int coor_x = GJP.XnodeCoor();
00734             int coor_y = GJP.YnodeCoor();
00735             int coor_z = GJP.ZnodeCoor();
00736             int coor_t = GJP.TnodeCoor();
00737             
00738             if (coor_x == procCoorX &&
00739                 coor_y == procCoorY &&
00740                 coor_z == procCoorZ &&
00741                 coor_t == procCoorT)
00742               *((IFloat *)src_4d + 2 * (color + GJP.Colors() * (spin + 4 * (
00743                   localX + GJP.XnodeSites() * (
00744                   localY + GJP.YnodeSites() * (
00745                   localZ + GJP.ZnodeSites() * localT)))))) = 1.0;
00746    
00747             // set the 5-dimensional source
00748             lat.Ffour2five(src, src_4d, pbp_arg->src_u_s, pbp_arg->src_l_s);
00749             
00750             // initialize 5-dimensional solution (initial guess) to 1
00751             for(i=0; i< f_size/2; i++){
00752               f_sol[2*i] = 1.0;     // real part
00753               f_sol[2*i+1] = 0.0;   // imaginary part
00754             }
00755             
00756             // do inversion
00757             iter = lat.FmatInv(sol, src, cg_arg, &true_res, CNV_FRM_YES);
00758             
00759             // Calculate the pbp normalization factor
00760             pbp_norm = (5.0 - GJP.DwfHeight());
00761           
00762             if (pbp_arg->snk_loop) {
00763               // Loop over sink - source separation
00764               for ( i = 0; i < ls_glb; i++) {
00765                 // set the 4-dimensional solution
00766                 lat.Ffive2four(sol_4d, sol, i, ls_glb - i - 1);
00767                 
00768                 // Calculate pbp
00769                 pbp_all[i] = sol_4d->ReDotProductGlbSum4D(src_4d, f_size/ls)
00770                   / pbp_norm;
00771                 
00772                 pbp_tmp[i] += pbp_all[i];
00773                 
00774                 // Calculate pbg5p = Tr[ PsiBar * Gamma5 * Psi]
00775                 lat.Gamma5(sol_4d, sol_4d, GJP.VolNodeSites());
00776                 pbg5p_all[i] = sol_4d->ReDotProductGlbSum4D(src_4d, f_size/ls)
00777                   / pbp_norm;
00778                 
00779                 pbg5p_tmp[i] += pbg5p_all[i];
00780                 
00781               }
00782             } 
00783             else {
00784               // set the 4-dimensional solution
00785               lat.Ffive2four(sol_4d, sol, pbp_arg->snk_u_s, pbp_arg->snk_l_s);
00786               
00787               // Calculate pbp
00788               pbp = sol_4d->ReDotProductGlbSum4D(src_4d, f_size/ls) / pbp_norm;
00789               pbptmp += pbp;
00790               
00791               // Calculate pbg5p = Tr[ PsiBar * Gamma5 * Psi]
00792               lat.Gamma5(sol_4d, sol_4d, GJP.VolNodeSites());
00793               pbg5p = sol_4d->ReDotProductGlbSum4D(src_4d, f_size/ls) / pbp_norm;
00794               pbg5ptmp += pbg5p;
00795               
00796             }
00797           }
00798       // Open file for results
00799       if(common_arg->results != 0){
00800         FILE *fp;
00801         if( (fp = Fopen((char *)common_arg->results, "a")) == NULL ) {
00802           ERR.FileA(cname,fname, (char *)common_arg->results);
00803         }
00804         if (pbp_arg->snk_loop) {
00805           // Print out mass, s-slice, pbp ,pbg5p, number of iterations
00806           // and true residual
00807           for ( i = 0; i < ls_glb; i++) {
00808             Fprintf(fp,"%0.16e %d %0.16e %0.16e %d %0.16e\n", 
00809                     IFloat(cg_arg->mass), 
00810                     i,
00811                     IFloat(pbp_tmp[i]/4/GJP.Colors()), 
00812                     IFloat(pbg5p_tmp[i]/4/GJP.Colors()), 
00813                     iter,
00814                     IFloat(true_res));
00815           }
00816         } 
00817         else {
00818           // Print out mass, pbp, pbg5p, number of iterations and true residual
00819           Fprintf(fp, "%0.16e %0.16e %0.16e %d %0.16e\n", 
00820                   IFloat(cg_arg->mass),
00821                   IFloat(pbptmp/4/GJP.Colors()), 
00822                   IFloat(pbg5ptmp/4/GJP.Colors()), 
00823                   iter, 
00824                   IFloat(true_res));
00825         }
00826         Fclose(fp);
00827       }
00828       
00829       // If there is another mass loop iteration ahead, we should
00830       // set the cg_arg->mass to it's next desired value
00831       if( m < pbp_arg->n_masses - 1 ) {
00832         switch( pbp_arg->pattern_kind ) {
00833         case ARRAY: 
00834           cg_arg->mass = pbp_arg->mass[m+1]; 
00835           break;
00836         case LIN:   
00837           cg_arg->mass += pbp_arg->mass_step; 
00838           break;
00839         case LOG:   
00840           cg_arg->mass *= pbp_arg->mass_step; 
00841           break;
00842         }
00843       }
00844     }
00845     
00846     // free the 4-dimensional source, solution, pbp, and pbg5p
00847     VRB.Sfree(cname,fname, "pbg5p_tmp", pbg5p_tmp);
00848     sfree(pbg5p_tmp);
00849     VRB.Sfree(cname,fname, "pbg5p_all", pbg5p_all);
00850     sfree(pbg5p_all);
00851     VRB.Sfree(cname,fname, "pbp_tmp", pbp_tmp);
00852     sfree(pbp_tmp);
00853     VRB.Sfree(cname,fname, "pbp_all", pbp_all);
00854     sfree(pbp_all);
00855     VRB.Sfree(cname,fname, "sol_4d", sol_4d);
00856     sfree(sol_4d);
00857     VRB.Sfree(cname,fname, "src_4d", src_4d);
00858     sfree(src_4d);
00859 
00860   }
00861 
00862   //----------------------------------------------------------------
00863   // Other fermion type
00864   //----------------------------------------------------------------
00865   else {
00866     ERR.General(cname,fname,"Not implemented for class type %d\n",int(lat.Fclass()));
00867   }
00868   
00869 }
00870 
00871 CPS_END_NAMESPACE

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