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

QPropW.C

Go to the documentation of this file.
00001 //------------------------------------------------------------------
00002 //
00003 // QPropW.C
00004 //
00005 // Kostas Orginos  (February 2002)
00006 //
00007 // The class functions for QPropW.
00008 //
00009 // For now this is specific to three colors. The constructor
00010 // will exit if the number of colors is not equal to three.
00011 //
00012 // In AlgThreept the QPropWRandWallSrc has to be replaced with 
00013 // QPropWRandSlabSrc
00014 //
00015 //
00016 //------------------------------------------------------------------
00017 
00018 #include <config.h> 
00019 #include <stdlib.h>     // exit()
00020 #include <stdio.h>
00021 #include <string.h>
00022 #include <alg/common_arg.h>
00023 #include <comms/glb.h>
00024 #include <comms/scu.h>
00025 // #include <util/data_io.h>
00026 #include <comms/sysfunc_cps.h>
00027 
00028 #include <fcntl.h>      // read and write control flags,
00029 #include <unistd.h>     // close(). These are needed for io parts to
00030                         // compile on PCs
00031 #include <alg/qpropw.h>
00032 #include <util/qcdio.h>
00033 
00034 #include <util/qioarg.h>
00035 #include <util/sproj_tr.h>
00036 #include <util/time_cps.h>
00037 
00038 //YA
00039 #include <alg/alg_plaq.h>
00040 #include <alg/alg_smear.h>
00041 #include <alg/no_arg.h>
00042 
00043 #define VOLFMT QIO_VOLFMT
00044 
00045 CPS_START_NAMESPACE
00046 
00047 // Allocate space for propagators
00048 void QPropW::Allocate(int mid) {
00049 
00050   char *fname = "Allocate(int)";
00051   VRB.Func(cname, fname);
00052 
00053   if (!mid) {
00054     if (prop == NULL) { // Allocate only if needed
00055         prop = (WilsonMatrix*)smalloc(GJP.VolNodeSites()*sizeof(WilsonMatrix));
00056         if (prop == 0) ERR.Pointer(cname, fname, "prop");
00057         VRB.Smalloc(cname, fname, "prop", prop,
00058                                 GJP.VolNodeSites() * sizeof(WilsonMatrix));
00059         }
00060   } else {
00061     if (midprop == NULL) { // Allocate only if needed
00062           midprop = (WilsonMatrix*)smalloc(GJP.VolNodeSites()*sizeof(WilsonMatrix));
00063           if (midprop == 0) ERR.Pointer(cname, fname, "midprop");
00064           VRB.Smalloc(cname, fname, "midprop", midprop,
00065                                   GJP.VolNodeSites() * sizeof(WilsonMatrix));
00066         }
00067   }
00068 }
00069 // Free space for propagators
00070 void QPropW::Delete(int mid) {
00071 
00072   char *fname = "Delete(int)";
00073   VRB.Func(cname, fname);
00074 
00075   if (!mid) {
00076     if (prop != NULL) {
00077           VRB.Sfree(cname, fname, "prop", prop);
00078           sfree(prop);
00079           prop = NULL;
00080         }
00081   } else {
00082         if (midprop != NULL) {
00083           VRB.Sfree(cname, fname, "midprop", midprop);
00084           sfree(midprop);
00085           midprop = NULL;
00086         }
00087   }
00088 }
00089 
00090 // Constructor without and with QPropWArg
00091 QPropW::QPropW(Lattice& lat, CommonArg* c_arg): Alg(lat, c_arg) {
00092 
00093   char *fname = "QPropW(L&, ComArg*)";
00094   cname = "QPropW";
00095   VRB.Func(cname, fname);
00096   
00097   prop = NULL;
00098   midprop = NULL;
00099   // EES
00100   propls = NULL;
00101 
00102   // YA
00103   lat_back = NULL;
00104   link_status_smeared = false;
00105   sink_type = POINT;
00106 }
00107 QPropW::QPropW(Lattice& lat, QPropWArg* arg, CommonArg* c_arg): 
00108   Alg(lat, c_arg) {
00109 
00110   char *fname = "QPropW(L&, QPropWArg*, ComArg*)";
00111   cname = "QPropW";
00112   VRB.Func(cname, fname);
00113 
00114   qp_arg = *arg;
00115   prop = NULL;
00116   midprop = NULL;
00117   propls = NULL;
00118 
00119   // YA
00120   lat_back = NULL;
00121   link_status_smeared = false;
00122   sink_type = POINT;
00123 
00124   //-----------------------------------------------------------------
00125   // TY Add Start
00126   if(qp_arg.save_ls_prop == 1){
00127   char sname[100];
00128   for(int nls(0);nls<GJP.SnodeSites();nls++){
00129 #if TARGET == QCDOC
00130   sprintf(sname,"/pfs/%s.m%0.3f.l%d.id%d.dat",
00131           qp_arg.file,qp_arg.cg.mass,nls,UniqueID());
00132 #else
00133   sprintf(sname,"pfs/%s.m%0.3f.l%d.id%d.dat",
00134           qp_arg.file,qp_arg.cg.mass,nls,UniqueID());
00135 #endif
00136   FILE *fp;
00137   if ((fp=fopen(sname,"w"))!=NULL) {
00138         VRB.Flow(cname,fname,"Remove file %s\n", sname);
00139   } else {
00140         ERR.FileA(cname, fname, sname);
00141   }
00142   fclose(fp);
00143   }
00144   }
00145   if(qp_arg.save_ls_prop == 2){
00146   VRB.Debug(cname,fname,"Before allocate porpls\n");
00147   if (propls == NULL) { 
00148   propls = (WilsonMatrix*)smalloc(GJP.VolNodeSites()*GJP.SnodeSites()*sizeof(WilsonMatrix));
00149   if (propls == 0) ERR.Pointer(cname, fname, "propls");
00150   VRB.Smalloc(cname, fname, "propls", propls,
00151               GJP.VolNodeSites()*GJP.SnodeSites()*sizeof(WilsonMatrix));
00152   VRB.Debug(cname,fname,"Allocate porpls\n");
00153   }
00154   }
00155   // TY Add End
00156   //-----------------------------------------------------------------
00157 }
00158 // copy constructor
00159 QPropW::QPropW(const QPropW& rhs):Alg(rhs),midprop(NULL),prop(NULL) {
00160 
00161   char *fname = "QPropW(const QPropW&)";
00162   cname = "QPropW";
00163   VRB.Func(cname, fname);
00164    
00165   Allocate(PROP);
00166   for (int i=0;i<GJP.VolNodeSites();i++)
00167     prop[i] = rhs.prop[i];
00168   
00169   if (rhs.StoreMidprop()) {
00170         Allocate(MIDPROP);
00171         for (int i=0;i<GJP.VolNodeSites();i++)
00172           midprop[i] = rhs.midprop[i];
00173   }
00174 
00175   // YA
00176   lat_back = NULL;
00177   link_status_smeared = false;
00178   sink_type = rhs.sink_type;
00179 
00180   //-----------------------------------------------------------------
00181   // TY Add Start
00182   propls = rhs.propls;
00183   // TY Add End
00184   //-----------------------------------------------------------------
00185   qp_arg = rhs.qp_arg;
00186 }
00187 
00188 // asignment operator
00189 QPropW& QPropW::operator=(const QPropW& rhs) { 
00190 
00191   char *fname = "operator=(const QPropW& rhs)";
00192   VRB.Func(cname, fname);
00193 
00194   if (this != &rhs) {
00195 
00196     Allocate(PROP);
00197     
00198     for (int i=0;i<GJP.VolNodeSites();i++)
00199       prop[i] = rhs.prop[i];
00200 
00201     if (rhs.StoreMidprop()) {
00202           Allocate(MIDPROP);
00203           for (int i=0;i<GJP.VolNodeSites();i++)
00204           midprop[i]=rhs.midprop[i];
00205         }
00206   
00207     qp_arg = rhs.qp_arg;
00208 
00209     // YA
00210     lat_back = NULL;
00211     link_status_smeared = false;
00212     sink_type = rhs.sink_type;
00213 
00214   }
00215   
00216   return *this;
00217 }
00218 
00219 // averaging constructor
00220 QPropW::QPropW(QPropW& prop1, QPropW& prop2):Alg(prop1)
00221 {
00222    cname = "QPropW"; 
00223    char *fname = "QPropW(QPropW&,QPropW&)";
00224    VRB.Func(cname, fname);
00225 
00226    prop = NULL;
00227    midprop = NULL;
00228    // YA
00229    lat_back = NULL;
00230    link_status_smeared = false;
00231    sink_type = prop1.sink_type;
00232 
00233    Allocate(PROP);
00234    for (int i=0; i<GJP.VolNodeSites(); i++)
00235      prop[i] = ((Float)0.5)*(prop1.prop[i]+prop2.prop[i]);
00236 
00237    qp_arg = prop1.qp_arg;
00238 }
00239 
00240 
00241 // EES merged with ReRun()
00242 void QPropW::Run(const int do_rerun, const Float precision) {
00243 
00244    char *fname = "Run()";
00245    VRB.Func(cname, fname);
00246 
00247    // Set the node size of the full (non-checkerboarded) fermion field
00248    //----------------------------------------------------------------
00249    //int f_size = GJP.VolNodeSites() * Lat.FsiteSize()/GJP.SnodeSites();
00250    int iter;
00251    Float true_res;
00252 
00253    int Nspins = 4; // Number of spin components to be done
00254    
00255    // Flag set if sequential propagator 
00256    int seq_src = ((SrcType()==PROT_U_SEQ)||
00257                                   (SrcType()==PROT_D_SEQ)||
00258                                   (SrcType()==MESSEQ)      );
00259 
00260    if (DoHalfFermion()) Nspins = 2;
00261 
00262    // does prop exist? Assume it does not.
00263    int do_cg = 1;
00264 
00265    /****************************************************************
00266      The code below is temporarily isolated for purposes of merging
00267      with CPS main branch,  12/09/04, Oleg Loktik
00268    -------------------- Quarantine starts --------------------------
00269 
00270    if (pfs_file_exists(Arg.file)){
00271      // read data into prop
00272      RestoreQProp(Arg.file,PROP); // Only restores stuff into prop 
00273 
00274      // multiply source by 1/2(1+gamma_t). If the propagator  
00275      // on disk is half fermion it does nothing. Otherwise it gets
00276      // converted to the half fermion propagator. 
00277      if (Arg.DoHalfFermion) 
00278        for (int s(0);s<GJP.VolNodeSites();s++)
00279          prop[s].PParProjectSink() ;
00280       
00281      do_cg = 0;
00282    }
00283    -------------------- End of quarantine -------------------------*/ 
00284 
00285   //-----------------------------------------------------------------
00286   // TY Add Start
00287    // we need to store the source
00288    Float *save_source=NULL;
00289   // TY Add End
00290   //-----------------------------------------------------------------
00291    WilsonMatrix *read_prop=NULL;
00292    WilsonMatrix *save_prop=NULL;
00293 
00294    if (do_cg) {
00295 
00296      Allocate(PROP); 
00297      if (StoreMidprop()) Allocate(MIDPROP);
00298      
00299      FermionVectorTp src;
00300      FermionVectorTp sol;
00301      FermionVectorTp midsol;
00302      
00303   //-----------------------------------------------------------------
00304   // TY Add Start
00305   // For conserved axial current
00306      int glb_walls = GJP.TnodeSites()*GJP.Tnodes();
00307      int fsize = glb_walls * sizeof(Float);
00308      conserved = (Float *) smalloc(fsize);
00309      if (!conserved)
00310        ERR.Pointer(cname, fname, "d_conserved_p");
00311      VRB.Smalloc(cname, fname, "d_conserved_p", conserved, fsize);
00312   
00313      Float* flt_p = (Float *)conserved;
00314      for ( int i = 0; i < glb_walls; i++) *flt_p++ = 0.0;
00315 
00316      spnclr_cnt = 0;
00317 
00318      // we need to store the source
00319      if (qp_arg.save_prop || do_rerun ){ 
00320        save_source = (Float*)smalloc(GJP.VolNodeSites()*288*sizeof(Float));
00321        if (save_source == 0) ERR.Pointer(cname, fname, "save_source");
00322        VRB.Smalloc(cname, fname, "save_source", save_source,
00323                    GJP.VolNodeSites() * 288*sizeof(Float));
00324      }
00325      // TY Add End
00326      //-----------------------------------------------------------------
00327 
00328      // in case we do a rerun, we also need to store a propagator
00329      if(do_rerun){
00330        read_prop = (WilsonMatrix*)smalloc(GJP.VolNodeSites()*sizeof(WilsonMatrix));
00331        if (read_prop == 0) ERR.Pointer(cname, fname, "pr3op");
00332        VRB.Smalloc(cname, fname, "read_prop", read_prop,
00333                    GJP.VolNodeSites() * sizeof(WilsonMatrix));     
00334        
00335 #ifdef USE_QIO
00336        qio_readPropagator readPropQio(qp_arg.file, QIO_FULL_SOURCE, read_prop, save_source,
00337                                       GJP.argc(), GJP.argv(), VOLFMT);
00338 #endif //USE_QIO
00339 
00340        if(AlgLattice().Fclass() == F_CLASS_DWF){
00341          
00342          Float renFac = 5. - GJP.DwfHeight();
00343          
00344          for(int ii(0); ii <  GJP.VolNodeSites(); ++ii)
00345            *(read_prop +ii) *= renFac;
00346        }
00347        
00348      }
00349      
00350      //-----------------------------------------------------------------
00351      // M. Lightman
00352      // For m_res
00353      j5q_pion = (Float *) smalloc(fsize);
00354      if (!j5q_pion)
00355        ERR.Pointer(cname, fname, "d_j5q_pion_p");
00356      VRB.Smalloc(cname, fname, "d_j5q_pion_p", j5q_pion, fsize);
00357      
00358      flt_p = (Float *) j5q_pion;
00359      for ( int i = 0; i < glb_walls; i++) *flt_p++ = 0.0;
00360      // End M. Lightman
00361      //-----------------------------------------------------------------
00362      
00363 
00364 
00365      for (int spn=0; spn < Nspins; spn++)
00366        for (int col=0; col < GJP.Colors(); col++) {
00367                  
00368          // initial guess (Zero)
00369          sol.ZeroSource();
00370 
00371          if(!do_rerun){
00372            SetSource(src,spn,col);
00373            
00374            // store the source
00375            if (qp_arg.save_prop) {
00376              for(int index(0); index < GJP.VolNodeSites(); ++index)
00377                for(int mm(0); mm < 4; ++ mm)
00378                  for(int cc(0); cc < GJP.Colors(); ++cc){
00379                    // now same ordering as propagator [volume][spin][color][solution_spin][solution_color][ReIm]
00380                    *(save_source + 288*index + 72*mm + 24*cc + 6*spn + 2*col)       = src[24*index + 6*mm + 2*cc];
00381                    *(save_source + 288*index + 72*mm + 24*cc + 6*spn + 2*col + 1)   = src[24*index + 6*mm + 2*cc+1];
00382                  }
00383            }
00384          }
00385          else{ // rerun
00386            for(int index(0); index < GJP.VolNodeSites(); ++index){
00387            
00388              WilsonMatrix *tmp_mat= (WilsonMatrix *) save_source+index;
00389              
00390              src.CopyWilsonMatSink(index, spn, col,*tmp_mat);
00391            }
00392          }
00393 
00394          if ((DoHalfFermion())&&(!seq_src)) // Rotate to chiral basis
00395            src.DiracToChiral();
00396                  
00397 
00398 
00399 
00400          // Get the prop
00401          VRB.Debug(cname,fname,"Before CG in QpropW.Run() \n");
00402          CG(src, sol, midsol, iter, true_res);
00403          //gauge fix solution
00404          FixSol(sol);
00405          if (StoreMidprop()) FixSol(midsol);
00406          
00407          // Collect solutions in propagator.
00408          LoadRow(spn,col,sol,midsol);
00409          
00410          if (DoHalfFermion()) {// copy spin 0 to spin 1 and spin 2 to spin 3
00411            int spn2 = spn + 2;
00412            if (seq_src) {
00413              LoadRow(spn2,col,sol,midsol);
00414            } else { // Regular propagator zero the extra components
00415              src.ZeroSource();
00416              LoadRow(spn2,col,src,src);
00417            }
00418          }
00419                  
00420          if (common_arg->results != 0) {
00421            FILE *fp;
00422            if ((fp = Fopen((char *)common_arg->results, "a")) == NULL) {
00423              ERR.FileA(cname,fname, (char *)common_arg->results);
00424            }
00425            Fprintf(fp, "Cg iters = %d true residual = %e\n",
00426                    iter, (Float)true_res);
00427            Fclose(fp);
00428          }
00429          
00430        } // End spin-color loop
00431      
00432      // Rotate the source indices to Chiral basis if needed
00433      if ((DoHalfFermion())&&(!seq_src)) {       
00434        for (int s=0;s<GJP.VolNodeSites();s++)
00435          prop[s].SinkChiralToDirac(); // multiply by V^\dagger
00436        
00437        if (StoreMidprop())
00438          for (int s=0;s<GJP.VolNodeSites();s++)
00439            midprop[s].SinkChiralToDirac(); // multiply by V^\dagger
00440      }
00441    }
00442 
00443    //-----------------------------------------------------------------
00444    // TY Add Start
00445    // Print out conserved axial results
00446    int time_size = GJP.TnodeSites()*GJP.Tnodes();
00447    for(int t(0);t<time_size;t++)
00448      slice_sum((Float*)&conserved[t], 1, 99);
00449    if(common_arg->results != 0){
00450      FILE *fp;
00451      if( (fp = Fopen((char *)common_arg->results, "a")) == NULL ) {
00452        ERR.FileA(cname,fname, (char *)common_arg->results);
00453      }
00454      Fprintf(fp,"Conserved Axial w_spect\n");
00455      for(int t=0; t<time_size; t++){
00456        Fprintf(fp,"%d = %.16e\n", t,conserved[t]);
00457      }
00458      Fclose(fp);
00459    }
00460    sfree(conserved);
00461    // TY Add End
00462    //-----------------------------------------------------------------
00463 
00464    //-----------------------------------------------------------------
00465    // M. Lightman
00466    // Print out J5q Pion contraction
00467    for(int t(0);t<time_size;t++)
00468      slice_sum((Float*)&j5q_pion[t], 1, 99);
00469    if(common_arg->results != 0){
00470      FILE *fp1;
00471      if( (fp1 = Fopen((char *)common_arg->results, "a")) == NULL ) {
00472        ERR.FileA(cname,fname, (char *)common_arg->results);
00473      }
00474      Fprintf(fp1,"J5q Pion Contraction\n");
00475      for(int t=0; t<time_size; t++){
00476        Fprintf(fp1,"%d = %.16e\n", t, j5q_pion[t]);
00477      }
00478     Fclose(fp1);
00479    }
00480    sfree(j5q_pion);
00481    // End M. Lightman
00482    //-----------------------------------------------------------------
00483 
00484    // save prop
00485    if (do_cg && qp_arg.save_prop) {
00486      
00487      char propType[256], sourceType[256], propOutfile[256];
00488 
00489      char gfixInfo[256];
00490 
00491      switch ( AlgLattice().FixGaugeKind() ){
00492 
00493      case FIX_GAUGE_NONE:
00494        sprintf(gfixInfo,"no GF");
00495        break;
00496 
00497      case FIX_GAUGE_LANDAU:
00498        sprintf(gfixInfo,"Landau GF, StpCnd=%0.0E", AlgLattice().FixGaugeStopCond());
00499        break;
00500 
00501      case FIX_GAUGE_COULOMB_T:
00502        sprintf(gfixInfo,"Coulomb(T) GF, StpCnd=%0.0E", AlgLattice().FixGaugeStopCond());
00503        break;
00504 
00505      default:
00506        sprintf(gfixInfo,"UNKNOWN GF");
00507 
00508      }
00509 
00510 
00511      char fermionInfo[256];
00512      
00513      switch (AlgLattice().Fclass() ){
00514 
00515      case F_CLASS_DWF:
00516        sprintf(fermionInfo,"DWF, Ls=%i, M5=%0.2f",GJP.Sites(4),GJP.DwfHeight());
00517        break;
00518          
00519      case F_CLASS_NONE:
00520        sprintf(fermionInfo,"NO FERMION TYPE");
00521        break;
00522 
00523      case F_CLASS_STAG:
00524        sprintf(fermionInfo,"staggered fermion");
00525        break;
00526 
00527      case F_CLASS_WILSON:
00528        sprintf(fermionInfo,"Wilson fermion");
00529        break;
00530 
00531      case F_CLASS_CLOVER:
00532        sprintf(fermionInfo,"Clover fermion");
00533        break;
00534         
00535      case F_CLASS_ASQTAD:
00536        sprintf(fermionInfo,"aSqTad fermion");
00537        break;
00538 
00539      case F_CLASS_P4: 
00540        sprintf(fermionInfo,"P4 fermion");
00541        break;
00542 
00543      default:
00544        sprintf(fermionInfo,"UNKNOWN FERMION TYPE");
00545       
00546      }
00547 
00548        
00549 
00550      sprintf(propType,"4D propagator, mass=%0.3f, StpCond=%0.0E,\nBC=%s%s%s%s,\n%s,\n%s", 
00551              qp_arg.cg.mass, qp_arg.cg.stop_rsd,
00552              ((GJP.Xbc()==BND_CND_PRD) ? "P" : "A"),
00553              ((GJP.Ybc()==BND_CND_PRD) ? "P" : "A"),
00554              ((GJP.Zbc()==BND_CND_PRD) ? "P" : "A"),
00555              ((GJP.Tbc()==BND_CND_PRD) ? "P" : "A"),   
00556              gfixInfo, fermionInfo
00557              );
00558     
00559      //sprintf(sourceType, "fullSource");
00560      // be a bit more sophisticated
00561      sprintf(sourceType,"%s-source at t=%i",SourceType_map[SrcType()].name ,SourceTime());
00562    
00563      if(!do_rerun)
00564        sprintf(propOutfile,qp_arg.file);
00565      else
00566        sprintf(propOutfile,"%s.rewrite",qp_arg.file);
00567 
00568      //in case of DWF, renormalize first
00569      if(AlgLattice().Fclass() == F_CLASS_DWF){
00570        
00571        Float renFac = 1./(5. - GJP.DwfHeight());
00572        
00573        save_prop = (WilsonMatrix*)smalloc(GJP.VolNodeSites()*sizeof(WilsonMatrix));
00574        if (save_prop == 0) ERR.Pointer(cname, fname, "pr3op");
00575        VRB.Smalloc(cname, fname, "save_prop", save_prop,
00576                    GJP.VolNodeSites() * sizeof(WilsonMatrix));
00577        
00578        for(int ii(0); ii <  GJP.VolNodeSites(); ++ii)
00579          *(save_prop + ii) = renFac * prop[ii];
00580 
00581        
00582      }
00583      else
00584        save_prop = &prop[0];
00585      
00586 #ifdef USE_QIO
00587      Float qio_time = -dclock();
00588      
00589      // always writes the full 4D source
00590      //qio_writePropagator writePropQio(propOutfile, QIO_FULL_SOURCE, save_prop, save_source,
00591      //                       qp_arg.ensemble_id, qp_arg.ensemble_label, qp_arg.seqNum, propType, sourceType,
00592      //                       GJP.argc(), GJP.argv(), VOLFMT);
00593      
00594      // write a t-slice/slices or hypercube in some cases for the source
00595      qio_writePropagator writePropQio;
00596 
00597      writePropQio.setHeader(qp_arg.ensemble_id, qp_arg.ensemble_label, qp_arg.seqNum, propType, sourceType);
00598      
00599      // just writing one time-slice?
00600      if(  (!do_rerun) && 
00601           ( (SrcType() == POINT) || (SrcType() == BOX) || (SrcType() == WALL) ) ){
00602        VRB.Flow(cname,fname," source-type: %s only write t-slice %i to file\n",SourceType_map[SrcType()].name ,SourceTime());
00603        writePropQio.setSourceTslice(SourceTime());
00604      }
00605 
00606      writePropQio.write_12pairs(propOutfile, QIO_FULL_SOURCE, save_prop, save_source, VOLFMT);
00607      qio_time +=dclock();
00608      print_time("QPropW::Run","qio_writePropagator",qio_time);
00609 
00610 
00611 #endif // USE_QIO
00612      
00613      if(AlgLattice().Fclass() == F_CLASS_DWF)
00614        sfree(save_prop);
00615      
00616      // the old storage function
00617      //SaveQProp(qp_arg.file,PROP); 
00618    }
00619 
00620    
00621    sfree(save_source);
00622    
00623    if(do_rerun){
00624      
00625      //now compare prop and read_prop
00626      
00627      Float errCnt(0.);
00628      Float sumerr(0.);
00629      
00630      for(int index(0); index < GJP.VolNodeSites(); ++index){
00631        
00632        WilsonMatrix mat_read, mat_calc;
00633        
00634        mat_calc = prop[index];
00635        mat_read = *(read_prop + index);
00636        
00637        for(int s_src(0); s_src < 4; ++s_src)
00638          for(int c_src(0); c_src < 3; ++c_src)
00639            for(int s_snk(0); s_snk < 4; ++s_snk)
00640              for(int c_snk(0); c_snk < 3; ++c_snk){
00641                
00642                Complex tmp_calc = mat_calc(s_snk,c_snk,s_src,c_src);
00643                Complex tmp_read = mat_read(s_snk,c_snk,s_src,c_src);
00644                
00645                Float diff;
00646                diff = ( fabs(tmp_calc.real()-tmp_read.real()) + fabs(tmp_calc.imag()-tmp_read.imag()) )/ sqrt((tmp_calc.real()*tmp_calc.real() + tmp_calc.imag()*tmp_calc.imag()));
00647                
00648                if( diff > precision){
00649                  
00650                  errCnt += 1.0;
00651                  sumerr+=diff;
00652                  VRB.Result(cname,fname,"mismatch propagator: index %i snk %i %i src %i %i\n %f: (%f,%f) <-> (%f,%f)\n",
00653                         index, s_snk,c_snk,s_src,c_src,
00654                         diff, tmp_calc.real(), tmp_calc.imag(), tmp_read.real(), tmp_read.imag() );
00655                }
00656                
00657              }
00658      }
00659      
00660      
00661      glb_sum_five(&errCnt);
00662      glb_sum_five(&sumerr);
00663      Float averr=sumerr/errCnt;
00664      
00665      if( fabs(errCnt) > 0.){
00666        VRB.Result(cname,fname," ReRun prop. with TOTAL NUMBER OF ERRORS: %f\n",errCnt);
00667        VRB.Result(cname,fname," Average error: %e\n",averr);
00668        VRB.Result(cname,fname," The precision is set at: %e\n",precision);
00669      } else {
00670        VRB.Result(cname,fname," ReRun prop. successfully!\n");
00671        VRB.Result(cname,fname," The precision is set at: %e\n",precision);
00672      }
00673      
00674    }
00675    
00676    if (qp_arg.save_prop || do_rerun )   
00677      sfree(read_prop);
00678    
00679 }
00680 
00681 
00682 void QPropW::ReLoad( char *infile){
00683 
00684   char *fname = "ReLoad( char *)";
00685 
00686   int float_size = sizeof(WilsonMatrix)*GJP.VolNodeSites()/sizeof(Float);
00687 
00688 
00689   if (prop == NULL) { // Allocate only if needed
00690     prop = (WilsonMatrix*)smalloc(GJP.VolNodeSites()*sizeof(WilsonMatrix));
00691     if (prop == 0) ERR.Pointer(cname, fname, "prop");
00692     VRB.Smalloc(cname, fname, "prop", prop,
00693                 GJP.VolNodeSites() * sizeof(WilsonMatrix));
00694   }
00695   
00696   Float *dummy_source = (Float*)smalloc(float_size*sizeof(Float));
00697   if (dummy_source == 0) ERR.Pointer(cname, fname, "dummy_source");
00698   VRB.Smalloc(cname, fname, "dummy_source", dummy_source,
00699               float_size * sizeof(Float));
00700 
00701 #ifdef USE_QIO
00702   qio_readPropagator readPropQio(infile, &prop[0], dummy_source, float_size, float_size, VOLFMT);
00703 #endif
00704 
00705   if(AlgLattice().Fclass() == F_CLASS_DWF){
00706     
00707     Float renFac = 5.-GJP.DwfHeight();
00708     
00709     for(int ii(0); ii < GJP.VolNodeSites(); ++ii)
00710       prop[ii] *= renFac;
00711     
00712   }
00713   
00714   sfree(dummy_source);
00715   
00716 }
00717 
00718 
00719 void QPropW::CG(Lattice &lat, CgArg *arg, FermionVectorTp& source,
00720         FermionVectorTp& sol , int& iter, Float& true_res){
00721         ERR.NotImplemented(cname,"CG(Lattice,CgArg,FermionVector...)");
00722 }
00723 
00724 // Do conjugate gradient
00725 void QPropW::CG(FermionVectorTp& source, FermionVectorTp& sol, 
00726                 FermionVectorTp& midsol, int& iter, Float& true_res) {
00727 
00728   char *fname = "CG(source&, sol&, midsol&, int&, Float&)";
00729   VRB.Func(cname, fname);
00730 
00731   /*
00732   CgArg cg_arg;
00733   cg_arg.mass = 0.03;
00734   cg_arg.max_num_iter = 1000;
00735   cg_arg.stop_rsd = 1.0e-8;
00736   */
00737 
00738   Lattice& Lat = AlgLattice();
00739 
00740   // Set the node size of the full (non-checkerboarded) fermion field
00741   //----------------------------------------------------------------
00742   int ls = GJP.SnodeSites();
00743   int ls_glb = GJP.SnodeSites()*GJP.Snodes();
00744   int f_size = GJP.VolNodeSites() * Lat.FsiteSize()/GJP.SnodeSites();
00745   int f_size_5d = f_size * ls;
00746 
00747   // Do inversion
00748   //----------------------------------------------------------------
00749   if (Lat.Fclass() == F_CLASS_DWF) {
00750     Vector *src_4d    = (Vector*)source.data();
00751     Vector *sol_4d    = (Vector*)sol.data();
00752     Vector *midsol_4d = (Vector*)midsol.data();
00753     Vector *src_5d    = (Vector*)smalloc(f_size_5d * sizeof(IFloat));
00754     Vector *sol_5d    = (Vector*)smalloc(f_size_5d * sizeof(IFloat));
00755     if (src_5d == 0)
00756       ERR.Pointer(cname,fname, "src_5d");
00757     VRB.Smalloc(cname,fname, "src_5d", src_5d, f_size_5d * sizeof(IFloat));
00758     if (sol_5d == 0)
00759       ERR.Pointer(cname,fname, "sol_5d");
00760     VRB.Smalloc(cname,fname, "sol_5d", sol_5d, f_size_5d * sizeof(IFloat));
00761 
00762     //Get the lattice form the Alg base class
00763     Lattice& Lat = this->AlgLattice() ;
00764 
00765     Lat.Ffour2five(src_5d, src_4d, 0, ls_glb-1);
00766     Lat.Ffour2five(sol_5d, sol_4d, ls_glb-1, 0);
00767 
00768         iter = Lat.FmatInv(sol_5d, src_5d, &(qp_arg.cg), &true_res,
00769                                            CNV_FRM_YES, PRESERVE_NO);
00770         
00771    /****************************************************************
00772      The code below is temporarily isolated for purposes of merging
00773      with CPS main branch,  12/09/04, Oleg Loktik 
00774    -------------------- Quarantine starts --------------------------
00775 
00776      iter = Lat.FmatInv4dSrc(sol_5d, src_5d, 0, ls_glb-1, &(Arg.cg), &true_res, 
00777                              CNV_FRM_YES, PRESERVE_NO);
00778    -------------------- End of quarantine -------------------------*/ 
00779 
00780   //-----------------------------------------------------------------
00781   // TY Add Start
00782     if(qp_arg.save_ls_prop) 
00783        for(int nls(0);nls<GJP.SnodeSites();nls++) SaveQPropLs(sol_5d, qp_arg.file, nls);
00784     spnclr_cnt++;
00785 
00786     MeasConAxialOld(sol_5d);
00787   // TY Add End
00788   //-----------------------------------------------------------------
00789 
00790   //-----------------------------------------------------------------
00791   // M. Lightman
00792     MeasJ5qPion(sol_5d);
00793   // End M. Lightman
00794   //-----------------------------------------------------------------
00795 
00796     // prop on walls
00797     Lat.Ffive2four(sol_4d, sol_5d, ls_glb-1, 0);
00798     // midpoint prop
00799     if (StoreMidprop())
00800       Lat.Ffive2four(midsol_4d, sol_5d, ls_glb/2-1, ls_glb/2);
00801 
00802     VRB.Sfree(cname,fname, "sol_5d", sol_5d);
00803     sfree(sol_5d);
00804     VRB.Sfree(cname,fname, "src_5d", src_5d);
00805     sfree(src_5d);
00806 
00807   } else {
00808     iter = Lat.FmatInv((Vector*)sol.data(),(Vector*)source.data(),
00809                                            &(qp_arg.cg), &true_res, CNV_FRM_YES, PRESERVE_NO);
00810   }
00811 
00812 }
00813 
00818 void QPropW::FixSol(FermionVectorTp& sol) {
00819 
00820    char *fname = "FixSol()";
00821    VRB.Func(cname, fname);
00822 
00823    // replace with check for FIX_GAUGE_NONE ??
00824    if (GFixedSnk()) {
00825          Lattice& latt(AlgLattice());
00826          switch ( latt.FixGaugeKind() ) {
00827          case ( FIX_GAUGE_NONE ):
00828            ERR.General(cname,fname,"Gauge fixing matrices not calculated\n");
00829            break;
00830          case ( FIX_GAUGE_COULOMB_T ):
00831            // GaugeFixSink seems to be broken for anything
00832            // except timeslice fixing ( dir isn't even used 
00833            // in the function )
00834            sol.GaugeFixSink(latt, 3);
00835            break;
00836            
00837          case ( FIX_GAUGE_LANDAU ):
00838            sol.LandauGaugeFixSink(latt);
00839            break;
00840            
00841          default:
00842            // should never be reached
00843            ERR.General(cname,fname,"Unimplemented gauge fixing\n");
00844            break;
00845          }
00846    }
00847 }
00848 
00852 void QPropW::LoadRow(int spin, int color, FermionVectorTp& sol, 
00853                                          FermionVectorTp& midsol) {
00854   int i;
00855   for (int s=0; s<GJP.VolNodeSites(); s++) {
00856     i = s*SPINOR_SIZE; // FermionVector index
00857     prop[s].load_row(spin, color, (wilson_vector &)sol[i]);
00858   }
00859   if (StoreMidprop()) { // Collect solutions in midpoint propagator.
00860     for (int s=0; s<GJP.VolNodeSites(); s++) {
00861       i = s*SPINOR_SIZE; // lattice site
00862       midprop[s].load_row(spin, color, (wilson_vector &)midsol[i]);
00863     }
00864   }
00865 } 
00866 
00867 //sets the filename for IO
00868 //void QPropW::SetFileName(char *nm)
00869 //{
00870 //  char *fname = "SetFileName(char*)";
00871 //
00872 //  if (Arg.file!=NULL) {
00873 //    VRB.Sfree(cname, fname, "Arg.file", qp_arg.file);
00874 //    sfree(Arg.file);
00875 //  }
00876 //
00877 //  qp_arg.file = (char*) smalloc(100) ; // string is 100 characters long
00878 //  if (Arg.file == 0) ERR.Pointer(cname, fname, "Arg.file");
00879 //  VRB.Smalloc(cname, fname, "Arg.file", qp_arg.file, 100 );
00880 //
00881 //  strcpy(Arg.file,nm);
00882 //}
00883 
00884 // Needed by alg_threept. Could be replaced by the disk system.
00885 void QPropW::ShiftPropForward(int n) {
00886 
00887    char *fname = "ShiftPropForward(int)";
00888 
00889    Float* recv_buf;
00890    Float* send_buf;
00891    int len =  12 * 12 * 2;
00892    // size of transfer in words
00893    recv_buf = (Float*)smalloc(len*sizeof(Float));
00894    if (recv_buf == 0) ERR.Pointer(cname,fname, "recv_buf");
00895    VRB.Smalloc(cname, fname, "recv_buf", recv_buf, 
00896                            12 * 12 * sizeof(Float));
00897  
00898    for (int j=0; j<n; j++) {
00899      // shift 1 node in t-dir.  prop -> prop
00900      for (int i=0; i<GJP.VolNodeSites(); i++) {
00901        send_buf = (Float*)&prop[i];
00902        getMinusData((IFloat*)recv_buf, (IFloat*)send_buf, len, 3);
00903        moveMem((IFloat *)&prop[i], (IFloat*)recv_buf, len*sizeof(IFloat) );
00904      }
00905    }
00906 
00907    VRB.Sfree(cname, fname, "recv_buf", recv_buf);
00908    sfree(recv_buf);
00909 
00910 }
00911 // Needed by alg_threept. Could be replaced by the disk system.
00912 void QPropW::ShiftPropBackward(int n) {
00913 
00914    char *fname = "ShiftPropBack()";
00915 
00916    Float* recv_buf;
00917    Float* send_buf;
00918    int len = 12 * 12 * 2;
00919        // size of transfer in words
00920    recv_buf = (Float*)smalloc(len*sizeof(Float));
00921    if (recv_buf == 0) ERR.Pointer(cname,fname, "recv_buf");
00922    VRB.Smalloc(cname, fname, "recv_buf", recv_buf, 
00923                12 * 12 * sizeof(Float));
00924  
00925    for (int j=0; j<n; j++) {
00926      // shift 1 node in t-dir.  prop -> prop
00927      for (int i=0; i<GJP.VolNodeSites(); i++) {
00928        send_buf = (Float*)&prop[i];
00929        getPlusData((IFloat*)recv_buf, (IFloat*)send_buf, len, 3);
00930        moveMem((IFloat*)&prop[i], (IFloat*)recv_buf, len*sizeof(IFloat));
00931      }
00932    }
00933 
00934    VRB.Sfree(cname, fname, "recv_buf", recv_buf);
00935    sfree(recv_buf);
00936 
00937 }
00938 
00949 void QPropW::Average(QPropW& Q) {
00950 
00951   if ((Q.prop != NULL)&&(prop !=NULL))
00952     for (int i=0; i< GJP.VolNodeSites(); i++)
00953       prop[i] = ((Float)0.5)*(prop[i]+Q.prop[i]);
00954 
00955   if ((Q.midprop != NULL)&&(midprop !=NULL))
00956     for (int i=0; i< GJP.VolNodeSites(); i++)
00957       midprop[i] = ((Float)0.5)*(midprop[i]+Q.midprop[i]);
00958 }
00959 
00975 WilsonMatrix& QPropW::GetMatrix(const int *vec, WilsonMatrix& tmp) const {
00976 
00977   // offset out-of-range coordinates site[] into on_node_site[]
00978   // in order to locate the Matrix
00979   //------------------------------------------------------------------------
00980   int on_node_site[4],site[4];
00981   int on_node = 1;
00982   WilsonMatrix *on_node_wmat;
00983   {
00984     for (int i=0; i<4; i++) {
00985       site[i] = on_node_site[i] = vec[i] ;
00986       while (on_node_site[i] < 0) {
00987         on_node_site[i] += GJP.NodeSites(i) ;
00988       }
00989       on_node_site[i] %= GJP.NodeSites(i) ;
00990       if (on_node_site[i] != site[i]) {
00991         on_node = 0;
00992       }
00993     }
00994     on_node_wmat = prop + (on_node_site[0] + GJP.XnodeSites()*(
00995                                                    on_node_site[1] + GJP.YnodeSites()*(
00996                            on_node_site[2] + GJP.ZnodeSites()*
00997                            on_node_site[3])));
00998   }
00999 
01000 #ifndef PARALLEL
01001 //VRB.FuncEnd(cname, fname) ;
01002   return *on_node_wmat;
01003 #endif
01004 
01005   // send to the destination node if the site is off-node
01006   //------------------------------------------------------------------------
01007   if (on_node) {
01008         //VRB.FuncEnd(cname, fname);
01009     return *on_node_wmat;
01010   } else {
01011     WilsonMatrix send = *on_node_wmat;
01012     WilsonMatrix &recv = tmp;
01013     for (int i=0; i<4; i++) {
01014       while (site[i] != on_node_site[i]) {
01015         if (site[i] < 0) {
01016           // the WilsonMatrix has 288 number of floats 
01017           //getMinusData((IFloat*)&recv, (IFloat*)&send, sizeof(WilsonMatrix),i);
01018           getMinusData((IFloat*)&recv, (IFloat*)&send, 288 ,i);
01019           on_node_site[i] -= GJP.NodeSites(i);
01020         } else {
01021           // the WilsonMatrix has 288 number of floats 
01022           //getPlusData ((IFloat*)&recv, (IFloat*)&send, sizeof(WilsonMatrix),i);
01023           getPlusData ((IFloat*)&recv, (IFloat*)&send, 288 ,i);
01024           on_node_site[i] += GJP.NodeSites(i);
01025         }
01026         send = recv;
01027       }
01028     }
01029 //  VRB.FuncEnd(cname, fname) ;
01030     return recv ;
01031   }
01032 }
01033 
01034 
01035 
01036 void QPropW::SetSource(FermionVectorTp& src, int spin, int color) {
01037 
01038    char *fname = "SetSource()";
01039    VRB.Func(cname, fname);
01040 
01041    // Do nothing
01042    // This function should be overridden by specific QPropW types
01043    
01044 }
01045 
01046 Complex& QPropW::rand_src(int i) const { 
01047   //Do nothing ....
01048   ERR.General("QPropW","rand_src","No random source\n");
01049   // This is just to keep the compiler happy
01050   return *((Complex*)prop); 
01051 }
01052 
01053 WilsonMatrix QPropW::WallSinkProp(int t_sink) {
01054 
01055     WilsonMatrix wmat = (Float)0.0;
01056 
01057     for (int i=0; i<GJP.VolNodeSites(); i++) {
01058           int t = i/(GJP.VolNodeSites()/GJP.TnodeSites());
01059           t += GJP.TnodeCoor()*GJP.TnodeSites();
01060           if (t != t_sink) continue;
01061           wmat += prop[i];        
01062     }
01063         
01064 #ifdef PARALLEL
01065     slice_sum((Float*)&wmat, 288, 99);
01066 #endif
01067         
01068     return wmat;
01069 }
01070 
01071 
01072 QPropW::~QPropW() {
01073 
01074   char *fname = "~QPropW()";
01075   VRB.Func(cname, fname);
01076 
01077   Delete(PROP);
01078   Delete(MIDPROP);
01079   propls = NULL;
01080   //  if (Arg.file!=NULL) {
01081   //  VRB.Sfree(cname, fname, "Arg.file", qp_arg.file);
01082   //  sfree(Arg.file);
01083   // }
01084 
01085   // YA 
01086   //UndoLinkSmear(); // set original link back if replaced with smeared link
01087   if( lat_back )
01088     delete[] lat_back;
01089 }
01090 
01091 void QPropW::SaveQProp(char* name, int mid) {
01092 
01093   char *fname = "SaveQProp()";
01094   
01095   VRB.Func(cname, fname);
01096 
01097    /****************************************************************
01098      The code below is temporarily isolated for purposes of merging
01099      with CPS main branch,  12/09/04, Oleg Loktik 
01100    -------------------- Quarantine starts --------------------------
01101 
01102   if (! mid) {
01103     unsigned int* data;
01104     data = (unsigned int*)prop;
01105     save_data(name, data, GJP.VolNodeSites() * sizeof(WilsonMatrix));
01106     
01107     if (common_arg->results != 0) {
01108       FILE *fp;
01109       if ( (fp = Fopen((char *)common_arg->results, "a")) == NULL ) {
01110         ERR.FileA(cname,fname, (char *)common_arg->results);
01111       }
01112       Fprintf(fp, "Saved prop in file %s\n", name);
01113       Fclose(fp);
01114     }
01115   } else {
01116     unsigned int* data;
01117     data = (unsigned int*)midprop;
01118     save_data(name, data, GJP.VolNodeSites() * sizeof(WilsonMatrix));
01119     if (common_arg->results != 0) {
01120       FILE *fp;
01121       if ( (fp = Fopen((char *)common_arg->results, "a")) == NULL ) {
01122         ERR.FileA(cname,fname, (char *)common_arg->results);
01123       }
01124       Fprintf(fp, "Saved mid-point prop in file %s\n", name);
01125       Fclose(fp);
01126     }
01127   }
01128    -------------------- Quarantine ends ----------------------------*/
01129 }
01130 
01131 // Restore prop
01132 void QPropW::RestoreQProp(char* name, int mid) {
01133 
01134   char *fname = "RestoreQProp()";
01135   VRB.Func(cname, fname);
01136 
01137   if( prop == NULL ) Allocate(PROP);
01138 
01139   // we need to store the source
01140   Float *read_source = (Float*)smalloc(GJP.VolNodeSites()*288*sizeof(Float));
01141   if (read_source == 0) ERR.Pointer(cname, fname, "read_source");
01142   VRB.Smalloc(cname, fname, "read_source", read_source,
01143               GJP.VolNodeSites() * 288*sizeof(Float));
01144 
01145 #ifdef USE_QIO
01146 
01147   //char tmp_filename[256];
01148   // strcpy(tmp_filename, qp_arg.file);
01149 
01150   qio_readPropagator readPropQio(qp_arg.file, QIO_FULL_SOURCE, &prop[0], read_source,
01151                                 GJP.argc(), GJP.argv(), VOLFMT);
01152 #endif // USE_QIO
01153   sfree(read_source);
01154 
01155   // Flag set if sequential propagator 
01156   int seq_src = ((SrcType()==PROT_U_SEQ)||
01157                  (SrcType()==PROT_D_SEQ)||
01158                  (SrcType()==MESSEQ));
01159 
01160   if(seq_src) {
01161     Site s;
01162     for (s.Begin();s.End();s.nextSite()) {
01163       QPropW::operator[](s.Index()).gl(-5);
01164       QPropW::operator[](s.Index()).hconj();
01165     }
01166   }
01167 }
01168 
01169   //-----------------------------------------------------------------
01170   // TY Add Start
01171 // Save 5d prop at each ls
01172  void QPropW::SaveQPropLs(Vector* sol_5d, char* name, int ls) {
01173 
01174   char *fname = "SaveQPropLs()";
01175   
01176   VRB.Func(cname, fname);
01177 
01178   VRB.Flow(cname,fname,"Saving propagator to pfs...\n");
01179 
01180   int fv_size = GJP.Colors() * 4 * 2 * sizeof(Float) * GJP.VolNodeSites();
01181   char sname[100];
01182 
01183 
01184   if(qp_arg.save_ls_prop == 1){
01185   int skip_buf = fv_size * ls / sizeof(Vector);
01186 
01187 #if TARGET == QCDOC
01188   sprintf(sname,"/pfs/%s.m%0.3f.l%d.id%d.dat",
01189           qp_arg.file,qp_arg.cg.mass,ls,UniqueID());
01190 #else
01191   sprintf(sname,"pfs/%s.m%0.3f.l%d.id%d.dat",
01192           qp_arg.file,qp_arg.cg.mass,ls,UniqueID());
01193 #endif
01194 
01195   FILE *fp;
01196   if ((fp=fopen(sname,"a"))!=NULL) {
01197         fwrite(sol_5d+skip_buf,1,fv_size,fp);
01198   } else {
01199         ERR.FileA(cname, fname, sname);
01200   }
01201   fclose(fp);
01202 
01203   }
01204 
01205   if(qp_arg.save_ls_prop == 2){
01206   // Flag set if sequential propagator 
01207   int seq_src = ((SrcType()==PROT_U_SEQ)||
01208                  (SrcType()==PROT_D_SEQ)||
01209                  (SrcType()==MESSEQ));
01210   int spn = spnclr_cnt / GJP.Colors();
01211   int clr = spnclr_cnt - spn * GJP.Colors();
01212   int shft_buf = GJP.VolNodeSites() * ls;
01213   int skip_buf = shft_buf * SPINOR_SIZE * sizeof(Float) / sizeof(Vector) ;
01214   int i;
01215   for (int s=0; s<GJP.VolNodeSites(); s++) {
01216     i = s*SPINOR_SIZE * sizeof(Float) / sizeof(Vector) ; // FermionVector index
01217     propls[s+shft_buf].load_row(spn, clr, (wilson_vector &)sol_5d[i+skip_buf]);
01218   }
01219 
01220   if(DoHalfFermion()) {
01221     int spn2 = spn + 2;
01222     if(!seq_src) {
01223       FermionVectorTp src;
01224       src.ZeroSource();
01225       for (int s=0; s<GJP.VolNodeSites(); s++) {
01226         i = s*SPINOR_SIZE * sizeof(Float) / sizeof(Vector) ; // FermionVector index
01227         propls[s+shft_buf].load_row(spn2, clr, (wilson_vector &)src[i]);
01228       }
01229     } else {
01230       for (int s=0; s<GJP.VolNodeSites(); s++) {
01231         i = s*SPINOR_SIZE * sizeof(Float) / sizeof(Vector) ; // FermionVector index
01232         propls[s+shft_buf].load_row(spn2, clr, (wilson_vector &)sol_5d[i+skip_buf]);
01233       }      
01234     }
01235 
01236   }
01237 
01238   //printf("End propagator to pfs... spn=%d clr=%d\n",spn,clr);
01239   }
01240  
01241 #ifdef PARALLEL
01242   QioControl sync;
01243   if( sync.synchronize(1)==1 ) ERR.General(cname, fname, "Synchronize Error\n");
01244 #endif
01245 }
01246 
01247 // Restore 5d prop at ls
01248 void QPropW::RestoreQPropLs(char* name, int ls) {
01249 
01250   char *fname = "RestoreQPropLs()";
01251   VRB.Func(cname, fname);
01252 
01253   // Flag set if sequential propagator 
01254   int seq_src = ((SrcType()==PROT_U_SEQ)||
01255                  (SrcType()==PROT_D_SEQ)||
01256                  (SrcType()==MESSEQ));
01257 
01258   if(qp_arg.save_ls_prop == 1){
01259   FermionVectorTp sol;
01260   FermionVectorTp midsol;
01261     
01262   int fv_size = GJP.Colors() * 4 * 2 * sizeof(Float) * GJP.VolNodeSites();
01263   char sname[100];
01264 
01265 #if TARGET == QCDOC
01266   sprintf(sname,"/pfs/%s.m%0.3f.l%d.id%d.dat",
01267           qp_arg.file,qp_arg.cg.mass,ls,UniqueID());
01268 #else
01269   sprintf(sname,"pfs/%s.m%0.3f.l%d.id%d.dat",
01270           qp_arg.file,qp_arg.cg.mass,ls,UniqueID());
01271 #endif
01272 
01273   int Nspin = 4;
01274   if (DoHalfFermion()) Nspin = 2;
01275 
01276   FILE *fp;
01277   if ((fp=fopen(sname,"r"))!=NULL) {
01278     for (int spn=0; spn < Nspin; spn++)
01279     for (int col=0; col < GJP.Colors(); col++) {
01280       fread((Vector*)sol.data(),1,fv_size,fp);
01281       LoadRow(spn,col,sol,midsol);
01282 
01283       if ((DoHalfFermion())&&(!seq_src)) {
01284         int spn2 = spn + 2;
01285         sol.ZeroSource();
01286         LoadRow(spn2,col,sol,midsol);
01287       } else {
01288         int spn2 = spn + 2;
01289         LoadRow(spn2,col,sol,midsol);
01290       }
01291 
01292     }
01293   } else {
01294         ERR.FileA(cname, fname, name);
01295   }
01296 
01297   VRB.Flow(cname,fname,"Read prop from file %s\n", sname);
01298   fclose(fp);
01299   }
01300 
01301   if(qp_arg.save_ls_prop == 2){
01302     int f_size = sizeof(WilsonMatrix) * GJP.VolNodeSites() / sizeof(Float);
01303 
01304     int s_local = ls % GJP.SnodeSites();
01305     int s_node = ls / GJP.SnodeSites();
01306     if( GJP.Snodes() > 1) for(int s=0; s<GJP.VolNodeSites(); s++) prop[s] = 0.0;
01307 
01308     if( s_node == GJP.SnodeCoor() ){
01309       int shft_buf = GJP.VolNodeSites() * s_local;
01310       for (int s=0; s<GJP.VolNodeSites(); s++) {
01311         prop[s] = propls[s+shft_buf];
01312         //printf("%d %e %e\n",s,*((Float*)&prop[s]),*((Float*)&propls[s+shft_buf]));
01313       }
01314       VRB.Debug(cname,fname,"End read propagator from memory\n");
01315     }
01316     if( GJP.Snodes() > 1 && GJP.Snodes() != 2 )  {
01317       VRB.Flow(cname,fname,"d gsum start restore\n",f_size);
01318       Float sum;
01319       Float* field_4D  = (Float *) prop;
01320       for(int i=0; i<f_size; i++){
01321         sum = field_4D[i];
01322         glb_sum_dir(&sum, 4);
01323         field_4D[i] = sum;    
01324       }
01325       VRB.Flow(cname,fname,"d gsum end restore\n",f_size);
01326     }
01327   }
01328 
01329   // Rotate the source indices to Chiral basis if needed
01330   if ((DoHalfFermion())&&(!seq_src)&&(DoHalfFermion()!=2)) {    
01331     for (int s=0;s<GJP.VolNodeSites();s++)
01332       prop[s].SinkChiralToDirac(); // multiply by V^\dagger
01333   }
01334 
01335 #ifdef PARALLEL
01336   QioControl sync;
01337   if( sync.synchronize(1)==1 ) ERR.General(cname, fname, "Synchronize error\n");
01338 #endif
01339 }
01340 
01341 // Restore 5d prop from file to memory
01342 void QPropW::RestoreQPropLs_ftom(char* name) {
01343 
01344   char *fname = "RestoreQPropLs()";
01345   VRB.Func(cname, fname);
01346 
01347   // Flag set if sequential propagator 
01348   int seq_src = ((SrcType()==PROT_U_SEQ)||
01349                  (SrcType()==PROT_D_SEQ)||
01350                  (SrcType()==MESSEQ));
01351 
01352   if(qp_arg.save_ls_prop == 1){
01353   FermionVectorTp sol;
01354   FermionVectorTp midsol;
01355     
01356   int fv_size = GJP.Colors() * 4 * 2 * sizeof(Float) * GJP.VolNodeSites();
01357   char sname[100];
01358 
01359   // Allocate 5d memory
01360   if (propls == NULL) { 
01361   propls = (WilsonMatrix*)smalloc(GJP.VolNodeSites()*GJP.SnodeSites()*sizeof(WilsonMatrix));
01362   if (propls == 0) ERR.Pointer(cname, fname, "propls");
01363   VRB.Smalloc(cname, fname, "propls", propls,
01364               GJP.VolNodeSites()*GJP.SnodeSites()*sizeof(WilsonMatrix));
01365   VRB.Debug(cname,fname,"Allocate porpls\n");
01366   }
01367 
01368   FILE *fp;
01369 
01370   int Nspin = 4;
01371   if (DoHalfFermion()) Nspin = 2;
01372 
01373   for(int ls(0); ls<GJP.SnodeSites(); ls++){
01374   int shft_buf = GJP.VolNodeSites() * ls;
01375 
01376 #if TARGET == QCDOC
01377   sprintf(sname,"/pfs/%s.m%0.3f.l%d.id%d.dat",
01378           qp_arg.file,qp_arg.cg.mass,ls,UniqueID());
01379 #else
01380   sprintf(sname,"pfs/%s.m%0.3f.l%d.id%d.dat",
01381           qp_arg.file,qp_arg.cg.mass,ls,UniqueID());
01382 #endif
01383   if (fp=fopen(sname,"r")) {
01384     for (int spn=0; spn < Nspin; spn++)
01385     for (int col=0; col < GJP.Colors(); col++) {
01386       fread((Vector*)sol.data(),1,fv_size,fp);
01387       int i;
01388       for (int s=0; s<GJP.VolNodeSites(); s++) {
01389         i = s*SPINOR_SIZE; // FermionVector index
01390         propls[s+shft_buf].load_row(spn, col, (wilson_vector &)sol[i]);
01391       }
01392 
01393       if ((DoHalfFermion())&&(!seq_src)) {
01394         int spn2 = spn + 2;
01395         sol.ZeroSource();
01396         for (int s=0; s<GJP.VolNodeSites(); s++) {
01397           i = s*SPINOR_SIZE; // FermionVector index
01398           propls[s+shft_buf].load_row(spn2, col, (wilson_vector &)sol[i]);
01399         }
01400       } else {
01401         int spn2 = spn + 2;
01402         for (int s=0; s<GJP.VolNodeSites(); s++) {
01403           i = s*SPINOR_SIZE; // FermionVector index
01404           propls[s+shft_buf].load_row(spn2, col, (wilson_vector &)sol[i]);
01405         }
01406       }
01407 
01408     }
01409   } else {
01410         ERR.FileA(cname, fname, name);
01411   }
01412 
01413   VRB.Debug(cname,fname,"Read 5d prop from file to memory\n");
01414   fclose(fp);
01415   } // ls loop
01416 
01417   // 5d prop in memory
01418   qp_arg.save_ls_prop = 2;
01419   }
01420 
01421 #ifdef PARALLEL
01422   QioControl sync;
01423   if( sync.synchronize(1)==1 ) ERR.General(cname, fname, "Synchronize error\n");
01424 #endif
01425   }
01426 
01427 
01428 // Swap 5d prop at ls=0 to GJP.SnodeSites()-1
01429 void QPropW::SwapQPropLs() {
01430 
01431   char *fname = "RestoreQPropLs()";
01432   VRB.Func(cname, fname);
01433 
01434   if(qp_arg.save_ls_prop == 1){
01435     ERR.General(cname, fname, "qp_arg.save_ls_prop == 1 does not implement.\n");
01436   }
01437 
01438   if(GJP.Snodes() != 2){
01439     ERR.General(cname, fname, "GJP.Snodes() should be 2.\n");
01440   }
01441 
01442   if(qp_arg.save_ls_prop == 2){
01443     int f_size = sizeof(WilsonMatrix) * GJP.VolNodeSites() / sizeof(Float);
01444 //    int ls;
01445 
01446     for(int ls=0; ls<GJP.SnodeSites(); ls++){
01447       int s_local = ls % GJP.SnodeSites();
01448       int s_node = ls / GJP.SnodeSites();
01449 //      int l_local = ( ls + GJP.SnodeSites() ) % GJP.SnodeSites();
01450       int l_node = ( ls + GJP.SnodeSites() ) / GJP.SnodeSites();
01451       // for(int s=0; s<GJP.VolNodeSites(); s++) prop[s] = 0.0;
01452 
01453       VRB.Debug(cname,fname,"d gsum start swap\n",f_size);
01454       int shft = f_size * s_local;
01455       Float sum;
01456       Float* field_5D = (Float *) propls;
01457 //      Float* field_4D = (Float *) prop;
01458       Float tmp=0.; 
01459       for(int i=0; i<f_size; i++){
01460         // ls=0 to ls=GJP.SnodeCoor()
01461         if( s_node == GJP.SnodeCoor() ) sum = field_5D[i+shft];
01462         if( s_node != GJP.SnodeCoor() ) sum = 0;
01463         glb_sum_dir(&sum, 4);
01464         if( s_node != GJP.SnodeCoor() ) tmp = sum;
01465 
01466         // ls=GJP.SnodeCoor() to ls=0
01467         if( l_node == GJP.SnodeCoor() ) sum = field_5D[i+shft];
01468         if( l_node != GJP.SnodeCoor() ) sum = 0;
01469         glb_sum_dir(&sum, 4);
01470 
01471         // propls[ls=0]=sum, propls[ls=GJP.SnodeCoor()]=tmp
01472         if( s_node == GJP.SnodeCoor() ) field_5D[i+shft] = sum;
01473         if( l_node == GJP.SnodeCoor() ) field_5D[i+shft] = tmp;
01474       }
01475       VRB.Debug(cname,fname,"d gsum end swap\n",f_size);
01476     }
01477   }
01478 
01479 
01480 #ifdef PARALLEL
01481   QioControl sync;
01482   if( sync.synchronize(1)==1 ) ERR.General(cname, fname, "Synchronize error\n");
01483 #endif
01484 }
01485 
01486 
01487 void QPropW::DeleteQPropLs() {
01488 
01489   char *fname = "DeleterQPropLs()";
01490   VRB.Func(cname, fname);
01491 
01492   if (propls != NULL) {
01493     VRB.Sfree(cname, fname, "propls", propls);
01494     sfree(propls);
01495     propls = NULL;
01496   }
01497 }
01498 
01499 
01500 // Restore 4d prop from file
01501 void QPropW::RestoreOrgProp(char* name, int ls) {
01502 
01503   int ls_glb = GJP.SnodeSites() * GJP.Snodes();
01504 
01505   char *fname = "RestoreOrgProp()";
01506   VRB.Func(cname, fname);
01507 
01508   // Flag set if sequential propagator 
01509   int seq_src = ((SrcType()==PROT_U_SEQ)||
01510                  (SrcType()==PROT_D_SEQ)||
01511                  (SrcType()==MESSEQ));
01512 
01513   FermionVectorTp sol;
01514   FermionVectorTp midsol;
01515 
01516   int org_ls = ls;
01517 
01518   if(qp_arg.save_ls_prop == 1){
01519   int fv_size = GJP.Colors() * 4 * 2 * sizeof(Float) * GJP.VolNodeSites();
01520   char sname[100], lname[100];
01521 
01522   ls=GJP.SnodeSites()-1;
01523 #if TARGET == QCDOC
01524   sprintf(sname,"/pfs/%s.m%0.3f.l%d.id%d.dat",
01525           qp_arg.file,qp_arg.cg.mass,ls,UniqueID());
01526 #else
01527   sprintf(sname,"pfs/%s.m%0.3f.l%d.id%d.dat",
01528           qp_arg.file,qp_arg.cg.mass,ls,UniqueID());
01529 #endif
01530 
01531   ls=0;
01532 #if TARGET == QCDOC
01533   sprintf(lname,"/pfs/%s.m%0.3f.l%d.id%d.dat",
01534           qp_arg.file,qp_arg.cg.mass,ls,UniqueID());
01535 #else
01536   sprintf(lname,"pfs/%s.m%0.3f.l%d.id%d.dat",
01537           qp_arg.file,qp_arg.cg.mass,ls,UniqueID());
01538 #endif
01539 
01540   int vol_4d = GJP.VolNodeSites();
01541 
01542   int Nspin = 4;
01543   if (DoHalfFermion()) Nspin = 2;
01544 
01545   FILE *fp, *gp=NULL;
01546   if ((fp=fopen(sname,"r"))!=NULL)
01547   if ((gp=fopen(lname,"r"))!=NULL) {
01548     for (int spn=0; spn < Nspin; spn++)
01549     for (int col=0; col < GJP.Colors(); col++) {
01550       fread((Vector*)sol.data(),1,fv_size,fp);
01551       fread((Vector*)midsol.data(),1,fv_size,gp);
01552     
01553       int x;
01554       int i;
01555       Float *field_4D;
01556       Float *field_5D;
01557       field_4D = (Float *) sol.data();
01558       field_5D = (Float *) midsol.data();
01559       field_4D = field_4D + 12;
01560       field_5D = field_5D + 12;
01561       for(x=0; x<vol_4d; x++){
01562         for(i=0; i<12; i++){
01563           field_4D[i] = field_5D[i];
01564         }
01565         field_4D = field_4D + 24;
01566         field_5D = field_5D + 24;
01567       }
01568       
01569       LoadRow(spn,col,sol,midsol);
01570 
01571       if ((DoHalfFermion())&&(!seq_src)) {
01572         int spn2 = spn + 2;
01573         sol.ZeroSource();
01574         LoadRow(spn2,col,sol,midsol);
01575       } else {
01576         int spn2 = spn + 2;
01577         LoadRow(spn2,col,sol,midsol);
01578       }
01579 
01580     }
01581   } else {
01582     ERR.FileA(cname, fname, name);
01583   }
01584 
01585   fclose(fp);
01586   fclose(gp);
01587   }
01588 
01589   if(qp_arg.save_ls_prop == 2){
01590     if( GJP.Snodes() > 1 && org_ls == 0 )  {
01591       int f_size = sizeof(WilsonMatrix) * GJP.VolNodeSites() / sizeof(Float);
01592 
01593       int s_u_local = (ls_glb - 1) % GJP.SnodeSites();
01594       int s_l_local = 0;
01595       int s_u_node = (ls_glb - 1) / GJP.SnodeSites();
01596       int s_l_node = 0;
01597       for (int s=0; s<GJP.VolNodeSites(); s++) prop[s] = 0.0;
01598 
01599       if( s_u_node == GJP.SnodeCoor() ){
01600         int shft_buf_l = GJP.VolNodeSites() * s_u_local;
01601         for (int s=0; s<GJP.VolNodeSites(); s++) {
01602           WilsonMatrix temp1, temp2;
01603           temp1 = propls[s+shft_buf_l];
01604           temp2 = 0.0;
01605           for(int sr_s=0; sr_s<2; sr_s++) for(int sr_c=0; sr_c<3; sr_c++){
01606             wilson_vector temp3;
01607             temp3 = temp1.sol(sr_s,sr_c);
01608             temp2.load_vec(sr_s,sr_c,temp3);
01609           }
01610           prop[s] = temp2;
01611         }
01612       }
01613 
01614       if( s_l_node == GJP.SnodeCoor() ){
01615         int shft_buf_l = GJP.VolNodeSites() * s_l_local;
01616         for (int s=0; s<GJP.VolNodeSites(); s++) {
01617           WilsonMatrix temp1, temp2;
01618           temp1 = propls[s+shft_buf_l];
01619           temp2 = 0.0;
01620           for(int sr_s=2; sr_s<4; sr_s++) for(int sr_c=0; sr_c<3; sr_c++){
01621             wilson_vector temp3;
01622             temp3 = temp1.sol(sr_s,sr_c);
01623             temp2.load_vec(sr_s,sr_c,temp3);
01624           }
01625           prop[s] = temp2;
01626         }
01627       }
01628       
01629       VRB.Debug(cname,fname,"d gsum start org 0\n",f_size);
01630       Float sum;
01631       Float* field_4D  = (Float *) prop;
01632       for(int i=0; i<f_size; i++){
01633         sum = field_4D[i];
01634         glb_sum_dir(&sum, 4);
01635         field_4D[i] = sum;    
01636       }
01637 
01638     } else if( GJP.Snodes() == 2 && org_ls != 0 ) {
01639       int f_size = sizeof(WilsonMatrix) * GJP.VolNodeSites() / sizeof(Float);
01640 
01641       int s_u_local = GJP.SnodeSites() - 1;
01642       int s_l_local = 0;
01643       int s_u_node = 0;
01644       int s_l_node = 1;
01645       for (int s=0; s<GJP.VolNodeSites(); s++) prop[s] = 0.0;
01646 
01647       if( s_u_node == GJP.SnodeCoor() ){
01648         int shft_buf_l = GJP.VolNodeSites() * s_u_local;
01649         for (int s=0; s<GJP.VolNodeSites(); s++) {
01650           WilsonMatrix temp1, temp2;
01651           temp1 = propls[s+shft_buf_l];
01652           temp2 = 0.0;
01653           for(int sr_s=0; sr_s<2; sr_s++) for(int sr_c=0; sr_c<3; sr_c++){
01654             wilson_vector temp3;
01655             temp3 = temp1.sol(sr_s,sr_c);
01656             temp2.load_vec(sr_s,sr_c,temp3);
01657           }
01658           prop[s] = temp2;
01659         }
01660       }
01661 
01662       if( s_l_node == GJP.SnodeCoor() ){
01663         int shft_buf_l = GJP.VolNodeSites() * s_l_local;
01664         for (int s=0; s<GJP.VolNodeSites(); s++) {
01665           WilsonMatrix temp1, temp2;
01666           temp1 = propls[s+shft_buf_l];
01667           temp2 = 0.0;
01668           for(int sr_s=2; sr_s<4; sr_s++) for(int sr_c=0; sr_c<3; sr_c++){
01669             wilson_vector temp3;
01670             temp3 = temp1.sol(sr_s,sr_c);
01671             temp2.load_vec(sr_s,sr_c,temp3);
01672           }
01673           prop[s] = temp2;
01674         }
01675       }
01676       
01677       VRB.Debug(cname,fname,"d gsum start org 1\n",f_size);
01678       Float sum;
01679       Float* field_4D  = (Float *) prop;
01680       for(int i=0; i<f_size; i++){
01681         sum = field_4D[i];
01682         glb_sum_dir(&sum, 4);
01683         field_4D[i] = sum;    
01684       }
01685 
01686     } else {
01687       ls = 0;
01688       int shft_buf_z = GJP.VolNodeSites() * ls;
01689       ls = GJP.SnodeSites() - 1;
01690       int shft_buf_l = GJP.VolNodeSites() * ls;
01691       for (int s=0; s<GJP.VolNodeSites(); s++) {
01692         WilsonMatrix temp1, temp2;
01693         temp1 = propls[s+shft_buf_z];
01694         temp2 = propls[s+shft_buf_l];
01695         for(int sr_s=2; sr_s<4; sr_s++) for(int sr_c=0; sr_c<3; sr_c++){
01696           wilson_vector temp3;
01697           temp3 = temp1.sol(sr_s,sr_c);
01698           temp2.load_vec(sr_s,sr_c,temp3);
01699         }
01700         prop[s] = temp2;
01701       }
01702     }
01703   }
01704 
01705   // Rotate the source indices to Chiral basis if needed
01706   if ((DoHalfFermion())&&(!seq_src)&&(DoHalfFermion()!=2)) {    
01707     for (int s=0;s<GJP.VolNodeSites();s++)
01708       prop[s].SinkChiralToDirac(); // multiply by V^\dagger
01709   }
01710 
01711   if(seq_src) {
01712     Site s;
01713     for (s.Begin();s.End();s.nextSite()) {
01714       QPropW::operator[](s.Index()).gl(-5);
01715       QPropW::operator[](s.Index()).hconj();
01716     }
01717   }
01718 
01719 #ifdef PARALLEL
01720   QioControl sync;
01721   if( sync.synchronize(1)==1 ) ERR.General(cname, fname, "Synchronize error\n");
01722 #endif
01723 }
01724 
01725 // Dirac to Chiral propagator
01726 void QPropW::NonRelProp(int lss) {
01727   if( !DoHalfFermion() ) {
01728   for (int s=0;s<GJP.VolNodeSites();s++){ 
01729     //prop[s].PParProjectSink();
01730     prop[s].PParProjectSource();
01731   }
01732 
01733   if(qp_arg.save_ls_prop == 2 && lss == 1) {
01734     for (int ls=0; ls<GJP.SnodeSites(); ls++) {
01735       int shft_buf = GJP.VolNodeSites() * ls;
01736       for (int s=0;s<GJP.VolNodeSites();s++){ 
01737         propls[s+shft_buf].PParProjectSource();
01738       }
01739     }
01740   }
01741   qp_arg.do_half_fermion = 2;
01742   }
01743 }
01744 
01745 
01746 void (*sproj_tr[8])(IFloat *f, 
01747                     IFloat *v, 
01748                     IFloat *w, 
01749                     int num_blk, 
01750                     int v_stride,
01751                     int w_stride) ;
01752 int siteOffset(const int lcl[], const int lcl_sites[]);
01753 
01754 
01755 // Measure conserved axial correlator
01756 void QPropW::MeasConAxialOld(Vector* sol_5d) {
01757 
01758   char *fname = "MeasConAxialOld()";
01759   VRB.Func(cname, fname);
01760 
01761   int prop_dir = 3;
01762 
01763 //  int fv_size = GJP.Colors() * 4 * 2 * sizeof(Float) * GJP.VolNodeSites();
01764   int ls_glb = GJP.SnodeSites() * GJP.Snodes();
01765 
01766   const int LORENTZs(4); 
01767   int lcl_sites[LORENTZs]; 
01768   lcl_sites[0] = GJP.XnodeSites();
01769   lcl_sites[1] = GJP.YnodeSites();
01770   lcl_sites[2] = GJP.ZnodeSites();
01771   lcl_sites[3] = GJP.TnodeSites();
01772 
01773   int lclMin[LORENTZs], lclMax[LORENTZs];
01774   lclMin[0] = lclMin[1] = lclMin[2] = lclMin[3] = 0;
01775   for(int i(0);i<LORENTZs;i++) lclMax[i] = lcl_sites[i]-1;
01776 
01777   int lcl_node[LORENTZs];
01778   lcl_node[0] = GJP.XnodeCoor();
01779   lcl_node[1] = GJP.YnodeCoor();
01780   lcl_node[2] = GJP.ZnodeCoor();
01781   lcl_node[3] = GJP.TnodeCoor();
01782 
01783   int lcl2glb_offset[LORENTZs];
01784   for (int i = 0; i < LORENTZs; ++i) 
01785     lcl2glb_offset[i] = lcl_sites[i] * lcl_node[i];
01786 
01787  
01788   int SPINORs = 2 * GJP.Colors() * LORENTZs;
01789 
01790 //  int glb_walls = lcl_sites[prop_dir];
01791 //  int fsize = glb_walls * sizeof(Float);
01792 
01793     
01794   // allocate space for two 4d field 
01795   //-----------------------------------------------------------------------
01796     
01797     int d_size_4d = GJP.VolNodeSites() * SPINORs ;
01798       
01799     Float* d_data_p1 = (IFloat *) smalloc(d_size_4d * sizeof(IFloat));
01800     if ( d_data_p1 == 0)
01801       ERR.Pointer(cname, fname, "d_data_p1");
01802     VRB.Smalloc(cname, fname, "d_data_p1", d_data_p1,
01803                 d_size_4d * sizeof(IFloat));
01804       
01805     Float* d_data_p2 = (IFloat *) smalloc(d_size_4d * sizeof(IFloat));
01806     if ( d_data_p2 == 0)
01807       ERR.Pointer(cname, fname, "d_data_p2");
01808       VRB.Smalloc(cname, fname, "d_data_p2", d_data_p2,
01809                   d_size_4d * sizeof(IFloat));
01810     
01811   //-----------------------------------------------------------------------
01812   // allocate space for two spinor fields for SCU transfer
01813   //-----------------------------------------------------------------------
01814     
01815     Float* tmp_p1 = (Float *)smalloc(SPINORs * sizeof(Float));
01816     if (tmp_p1 == 0)
01817       ERR.Pointer(cname, fname, "tmp_p1") ;
01818     VRB.Smalloc(cname, fname, "tmp_p1", tmp_p1,
01819                 SPINORs * sizeof(Float)) ;
01820       
01821     Float* tmp_p2 = (Float *)smalloc(SPINORs * sizeof(Float));
01822     if (tmp_p2 == 0)
01823       ERR.Pointer(cname, fname, "tmp_p2") ;
01824     VRB.Smalloc(cname, fname, "tmp_p2", tmp_p2,
01825                 SPINORs * sizeof(Float)) ;
01826       
01827     
01828   //-----------------------------------------------------------------------
01829   // allocate space for two spinor fields for gamma_5 multiplication 
01830   //-----------------------------------------------------------------------
01831     
01832     Float* v1_g5 = (Float *)smalloc(SPINORs * sizeof(Float));
01833     if (v1_g5 == 0)
01834       ERR.Pointer(cname, fname, "v1_g5") ;
01835     VRB.Smalloc(cname, fname, "v1_g5", v1_g5,
01836                 SPINORs * sizeof(Float)) ;
01837       
01838     Float* v1_next_g5 = (Float *)smalloc(cname, fname,
01839                                   "v1_next_g5", SPINORs * sizeof(Float));
01840     if (v1_next_g5 == 0)
01841       ERR.Pointer(cname, fname, "v1_next_g5") ;
01842     //      VRB.Smalloc(d_class_name, ctor_str, "v1_next_g5", v1_next_g5,
01843     //            SPINORs * sizeof(Float)) ;
01844       
01845 
01846     //-----------------------------------------------------------------------
01847     // Fill in the array of sproj_tr functions
01848     //-----------------------------------------------------------------------
01849     sproj_tr[SPROJ_XM] = sprojTrXm;
01850     sproj_tr[SPROJ_YM] = sprojTrYm;
01851     sproj_tr[SPROJ_ZM] = sprojTrZm;
01852     sproj_tr[SPROJ_TM] = sprojTrTm;
01853     sproj_tr[SPROJ_XP] = sprojTrXp;
01854     sproj_tr[SPROJ_YP] = sprojTrYp;
01855     sproj_tr[SPROJ_ZP] = sprojTrZp;
01856     sproj_tr[SPROJ_TP] = sprojTrTp;
01857 
01858 
01859   Lattice& lat = AlgLattice();
01860   Matrix *gauge_field = lat.GaugeField();  
01861 
01862 
01863   //  To avoid duplicate work, stop at the middle of the s direction
01864   for (int s = 0; s < ls_glb/2; s++) {
01865     lat.Ffive2four((Vector *) d_data_p1, sol_5d, s, s);
01866     lat.Ffive2four((Vector *) d_data_p2, sol_5d, ls_glb-1-s, ls_glb-1-s);
01867 
01868     int lcl_walls = lcl_sites[prop_dir];
01869       
01870     for( int lclW = 0; lclW < lcl_walls; ++lclW) {
01871       int lcl[LORENTZs];
01872       int lcl_next[LORENTZs]; // Next site along propagation direction
01873 
01874       // Define hyperplane    
01875       lclMin[prop_dir]=lclMax[prop_dir] = lclW;
01876 
01877       for(lcl[0]=lclMin[0]; lcl[0]<=lclMax[0]; lcl[0]++) 
01878       for(lcl[1]=lclMin[1]; lcl[1]<=lclMax[1]; lcl[1]++) 
01879       for(lcl[2]=lclMin[2]; lcl[2]<=lclMax[2]; lcl[2]++) 
01880       for(lcl[3]=lclMin[3]; lcl[3]<=lclMax[3]; lcl[3]++) {
01881 
01882         int lcl_offset = siteOffset(lcl,lcl_sites) * SPINORs ;
01883 
01884         // coordinates and offset for lcl_next
01885         for (int i  = 0; i < LORENTZs; i++ ) 
01886           lcl_next[i] = ( (i == prop_dir) ? (lcl[i]+1)%lcl_sites[i]
01887                           : lcl[i] );
01888 
01889         int lcl_next_offset = siteOffset(lcl_next,lcl_sites) * SPINORs;
01890 
01891         // U_mu(x) where mu = prop_dir
01892         Matrix * link = gauge_field + siteOffset(lcl,lcl_sites) * 4 + prop_dir ;
01893 
01894         { 
01895           Float * v1, * v2;
01896           Float * v1_next, * v2_next;
01897           Float coeff = 1.0;
01898             
01899           // S_F(x, s)
01900           v1 = (Float *)d_data_p1+lcl_offset ;
01901           // S_F(x, ls_glb-1-s)
01902           v2 = (Float *)d_data_p2+lcl_offset ;
01903 
01904           // v1_next = S_F(x+prop_dir, s)
01905           // v2_next = S_F(x+prop_dir, ls_glb-1-s)
01906           if ((lcl[prop_dir]+1) == lcl_sites[prop_dir]) {
01907             getPlusData( (IFloat *)tmp_p1,
01908                          (IFloat *)d_data_p1+lcl_next_offset, SPINORs, 
01909                          prop_dir) ;
01910             getPlusData( (IFloat *)tmp_p2,
01911                          (IFloat *)d_data_p2+lcl_next_offset, SPINORs, 
01912                          prop_dir) ;
01913             v1_next = tmp_p1;
01914             v2_next = tmp_p2;
01915 
01916             // fix boundary condition
01917             switch( prop_dir ) {
01918             case 0:
01919               if (GJP.XnodeBc()==BND_CND_APRD) coeff = -coeff ;
01920               break;
01921             case 1:
01922               if (GJP.YnodeBc()==BND_CND_APRD) coeff = -coeff ;
01923               break;
01924             case 2:
01925               if (GJP.ZnodeBc()==BND_CND_APRD) coeff = -coeff ;
01926               break;
01927             case 3:
01928               if (GJP.TnodeBc()==BND_CND_APRD) coeff = -coeff ;
01929               break;
01930             } // end switch
01931 
01932           } else {
01933             v1_next = (Float *)d_data_p1+lcl_next_offset ;
01934             v2_next = (Float *)d_data_p2+lcl_next_offset ;
01935           }
01936             
01937           {
01938             // Gamma^5 S_F(x, s)
01939             lat.Gamma5((Vector *) v1_g5, (Vector *) v1, 1 );
01940 
01941             // Gamma^5 S_F(x+prop_dir, s)
01942             lat.Gamma5((Vector *) v1_next_g5, (Vector *) v1_next, 1 );
01943             
01944             Matrix tmp1, tmp2, f;
01945             Float result = 0.0 ;
01946 
01947             // tmp1 = Tr_spin ( (1 + gamma_{prop_dir} ) 
01948             //       gamma_5 S_F(x+prop_dir, s) S_F^dagger(x, ls_glb-1-s))
01949             sproj_tr[prop_dir+4]((IFloat *)&tmp1,
01950                                  (IFloat *)v1_next_g5,
01951                                  (IFloat *)v2, 1, 0, 0);
01952               
01953             f.DotMEqual(*link, tmp1);
01954 
01955             result = f.ReTr();
01956               
01957             // tmp2 = Tr_spin ( (1 - gamma_{prop_dir} ) 
01958             //       gamma_5 S_F(x, s) S_F^dagger(x+prop_dir, ls_glb-1-s))
01959             sproj_tr[prop_dir]( (IFloat *)&tmp2,
01960                                 (IFloat *)v1_g5,
01961                                 (IFloat *)v2_next, 1, 0, 0);
01962                                         
01963             tmp1.Dagger(*link);
01964             f.DotMEqual(tmp1, tmp2);
01965             result -= f.ReTr();
01966             
01967             result *= coeff;
01968 
01969 
01970             *( conserved + lclW + lcl2glb_offset[prop_dir] ) += result;
01971           }
01972         
01973         }
01974       } // for(lcl[_]..)
01975     } // for (int lclW...)
01976 
01977     //printf("ls %d %e\n",s,conserved[0]);
01978 
01979   } // for (int s ... )
01980 
01981   sfree(v1_next_g5);
01982   sfree(v1_g5);
01983   sfree(tmp_p2);
01984   sfree(tmp_p1);
01985   sfree(d_data_p2);
01986   sfree(d_data_p1);
01987 }
01988   // TY Add End
01989   //-----------------------------------------------------------------
01990 
01991 //-----------------------------------------------------------------
01992 //M. Lightman
01993 void QPropW::MeasJ5qPion(Vector* sol_5d) {
01994 
01995   char *fname = "MeasJ5()";
01996   VRB.Func(cname, fname);
01997 
01998   int prop_dir=3;
01999   int ls_glb = GJP.SnodeSites() * GJP.Snodes();
02000   
02001   const int LORENTZs(4); 
02002   int SPINORs=2*GJP.Colors()*LORENTZs;
02003 
02004   int lcl_sites[LORENTZs];
02005   lcl_sites[0] = GJP.XnodeSites();
02006   lcl_sites[1] = GJP.YnodeSites();
02007   lcl_sites[2] = GJP.ZnodeSites();
02008   lcl_sites[3] = GJP.TnodeSites();
02009 
02010   int lclMin[LORENTZs], lclMax[LORENTZs];
02011   lclMin[0] = lclMin[1] = lclMin[2] = lclMin[3] = 0;
02012   for(int i(0);i<LORENTZs;i++) lclMax[i] = lcl_sites[i]-1;
02013 
02014   int lcl_node[LORENTZs];
02015   lcl_node[0] = GJP.XnodeCoor();
02016   lcl_node[1] = GJP.YnodeCoor();
02017   lcl_node[2] = GJP.ZnodeCoor();
02018   lcl_node[3] = GJP.TnodeCoor();
02019 
02020   int lcl2glb_offset[LORENTZs];
02021   for (int i = 0; i < LORENTZs; ++i) 
02022     lcl2glb_offset[i] = lcl_sites[i] * lcl_node[i];
02023 
02024   
02025 
02026   //-----------------------------------------------------------------------
02027   //allocate space for the 4d field (?)
02028   //-----------------------------------------------------------------------
02029   int d_size_4d = GJP.VolNodeSites() * SPINORs ;
02030   
02031   Float* d_data = (IFloat *) smalloc(d_size_4d * sizeof(IFloat));
02032   if ( d_data == 0)
02033     ERR.Pointer(cname, fname, "d_data");
02034   VRB.Smalloc(cname, fname, "d_data", d_data, d_size_4d * sizeof(IFloat));
02035   //-----------------------------------------------------------------------
02036 
02037   //-----------------------------------------------------------------------
02038   //define the 4d field from the 5d field
02039   //-----------------------------------------------------------------------
02040   Lattice& lat = AlgLattice();
02041   lat.Ffive2four((Vector *) d_data, sol_5d, ls_glb/2-1, ls_glb/2);
02042   
02043   //-----------------------------------------------------------------------
02044   //Calculate the correlator
02045   //-----------------------------------------------------------------------
02046   int lcl_walls = lcl_sites[prop_dir];
02047   
02048   for( int lclW = 0; lclW < lcl_walls; ++lclW) {
02049     int lcl[LORENTZs];
02050     
02051     // Define hyperplane    
02052     lclMin[prop_dir]=lclMax[prop_dir] = lclW;
02053     
02054     //Loop over sites in this hyperplane in the local lattice
02055     for(lcl[0]=lclMin[0]; lcl[0]<=lclMax[0]; lcl[0]++) 
02056       for(lcl[1]=lclMin[1]; lcl[1]<=lclMax[1]; lcl[1]++) 
02057         for(lcl[2]=lclMin[2]; lcl[2]<=lclMax[2]; lcl[2]++) 
02058           for(lcl[3]=lclMin[3]; lcl[3]<=lclMax[3]; lcl[3]++) {
02059             
02060             int lcl_offset = siteOffset(lcl,lcl_sites) * SPINORs ;
02061 
02062             Float* v1 = (Float *)d_data+lcl_offset;
02063             
02064             for(int vec_ind=0; vec_ind<SPINORs; vec_ind++)
02065               *( j5q_pion + lclW + lcl2glb_offset[prop_dir] ) += (*(v1+vec_ind)) * (*(v1+vec_ind));
02066             
02067           } //lcl
02068   } //lclW
02069   sfree(d_data);
02070 
02071 }
02072 //End M. Lightman
02073 //-----------------------------------------------------------------
02074 
02075 // YA, this does smearing of the link in the kernel of the Gaussian src smear
02076 void QPropW::DoLinkSmear(const QPropWGaussArg& gauss_arg) {
02077   char *fname = "DoLinkSmear()";
02078   VRB.Func(cname, fname);
02079 
02080   Lattice& lattice = AlgLattice();
02081   CommonArg ca; // if output of smearing needed, set ca.filename
02082 
02083   if( link_status_smeared || gauss_arg.gauss_link_smear_type == GKLS_NONE ) {
02084     return;
02085   }
02086   if( lat_back != NULL ) {
02087     // and as (! link_status_smeared), then lat_back is smeared link
02088     // which has been previouly calculated.
02089     // rotate lattice <-> lat_back
02090 
02091     Matrix* lat_tmp = new Matrix[GJP.VolNodeSites()*4];
02092     if( lat_tmp == NULL ) { ERR.Pointer(cname, cname,"lat_tmp"); }
02093     // make the temporal copy of orginal link
02094     lattice.CopyGaugeField(lat_tmp);
02095     // set the smeared link
02096     lattice.GaugeField(lat_back);
02097 
02098     for(int j=0;j<GJP.VolNodeSites()*4;j++) {
02099       lat_back[j] = lat_tmp[j];
02100     }
02101     // now lat_back is orginal & lattice is smeared link
02102 
02103     delete[] lat_tmp;
02104   
02105   } else { // then calculate smeared link
02106 
02107     // print plaq before smearing
02108     NoArg no_arg;
02109     AlgPlaq ap(lattice,common_arg,&no_arg);
02110     if (common_arg->results != 0) {
02111       FILE *fp;
02112       if ((fp = Fopen((char *)common_arg->results, "a")) == NULL) {
02113         ERR.FileA(cname,fname, (char *)common_arg->results);
02114       }
02115       Fprintf(fp, "QPropW::DoLinkSmear():Plaq_before ");
02116       Fclose(fp);
02117     }
02118     ap.run();
02119 
02120     lat_back = new Matrix[GJP.VolNodeSites()*4];
02121     if( lat_back == NULL ) { ERR.Pointer(cname, cname,"lat_back"); }
02122     // make the copy of orginal link
02123     lattice.CopyGaugeField(lat_back);
02124 
02125     // AlgSmear* as(NULL);
02126     // we could use pointer and then run after selection of smearing scheme,
02127     // if AlgSmear::run() were a virtual function.
02128 
02129     switch(gauss_arg.gauss_link_smear_type) {
02130       /*
02131     case GKLS_NONE:
02132       // actually this already returned
02133       return;
02134       break;
02135       */
02136     case GKLS_APE:
02137       {
02138         ApeSmearArg asa;
02139         asa.coef = gauss_arg.gauss_link_smear_coeff;
02140         asa.orthog = 3; // set the smear orthogonal direction to temporal
02141         AlgApeSmear as(lattice,&ca,&asa,1);
02142         for(int i=0;i<gauss_arg.gauss_link_smear_N;i++)
02143           as.run();
02144       }
02145       break;
02146     case GKLS_STOUT:
02147       ERR.NotImplemented(cname,fname, "GKLS_STOUT yet to implement");
02148       /*
02149         StoutSmearArg asa;
02150         asa.rho = action_link_smear_coeff;
02151         as = new AlgStoutSmear(lattice,&ca,&asa);
02152         break;
02153       */
02154       break;
02155     default:
02156       ERR.General(cname,fname, "unknown qp_arg.gauss_link_smear_type=%d",\
02157                   gauss_arg.gauss_link_smear_type);
02158     }
02159 
02160     // print plaq after smear
02161     if (common_arg->results != 0) {
02162       FILE *fp;
02163       if ((fp = Fopen((char *)common_arg->results, "a")) == NULL) {
02164         ERR.FileA(cname,fname, (char *)common_arg->results);
02165       }
02166       Fprintf(fp, "QPropW::DoLinkSmear():Plaq_after  ");
02167       Fclose(fp);
02168     }
02169     ap.run();
02170   }
02171 
02172   link_status_smeared=true;
02173 }
02174 
02175 // YA, use this to set back the original link which has been replaced with
02176 //    the smeared link for the Gaissian src smearing.
02177 //    The smeared link is kept in lat_back.
02178 void QPropW::UndoLinkSmear(const QPropWGaussArg& gauss_arg) {
02179   char *fname = "UndoLinkSmear()";
02180   VRB.Func(cname, fname);
02181 
02182   if( (! link_status_smeared) || gauss_arg.gauss_link_smear_type == GKLS_NONE ) {
02183     return;
02184   }
02185   // then lattice is smeared link & lat_back is original link
02186   // now rotate lattice <-> lat_back
02187   Lattice& lattice = AlgLattice();
02188   if( lat_back == NULL )
02189     ERR.General(cname,fname, "lat_back=NULL, DoLinkSmear never called");
02190   Matrix* lat_tmp = new Matrix[GJP.VolNodeSites()*4];
02191   if( lat_tmp == NULL ) { ERR.Pointer(cname, cname,"lat_tmp"); }
02192   // make the temporal copy of smeared link
02193   lattice.CopyGaugeField(lat_tmp);
02194   // set the original link back
02195   lattice.GaugeField(lat_back);
02196 
02197   for(int j=0;j<GJP.VolNodeSites()*4;j++) {
02198     lat_back[j] = lat_tmp[j];
02199   }
02200   // now lat_back is smeared & lattice is original link
02201 
02202   delete[] lat_tmp;
02203   
02204   link_status_smeared=false;
02205 }
02206 
02207 
02208 
02209 //HueyWen and Peter
02210 QPropWGFLfuncSrc::QPropWGFLfuncSrc(Lattice &lat, 
02211                                    CgArg *arg,
02212                                    CommonArg *common_arg,
02213                                    Float (*fn) (int,int,int,int)
02214                                    ):QPropW(lat, common_arg)
02215 {
02216    func = fn;
02217 
02218    char *fname = "QPropWGFLfuncSrc(L&, CgArg*, blah)";
02219    char *cname = "QPropWGFLfuncSrc";
02220    VRB.Func(cname, fname);
02221 
02222    // Set the node size of the full (non-checkerboarded) fermion field
02223    //----------------------------------------------------------------
02224    int f_size = GJP.VolNodeSites() * lat.FsiteSize()/GJP.SnodeSites();
02225    int iter=0;
02226    Float true_res=0.;
02227 
02228    // allocate space for the quark propagator
02229    //----------------------------------------------------------------
02230    prop = (WilsonMatrix*) smalloc(GJP.VolNodeSites() * sizeof(WilsonMatrix));
02231    if (prop == 0) ERR.Pointer(cname, fname, "prop");
02232    VRB.Smalloc(cname, fname, "prop", prop, 12 * f_size * sizeof(Float));
02233    FermionVectorTp src;
02234    FermionVectorTp sol;
02235 
02236    for (int spin = 0; spin < 4; spin++)
02237      for (int color = 0; color < GJP.Colors(); color++){
02238 
02239         // initial guess
02240         sol.SetVolSource(color, spin);
02241         // set the source
02242 
02243         //src.SetGFLfuncSource(lat, color, spin, fn);
02244 
02245         // Get the prop
02246         //CG(lat, arg, src, sol, iter, true_res);
02247         
02248         // HueyWen 
02249         //sol.LandauGaugeFixSink(lat, 3);
02250         sol.LandauGaugeFixSink(lat);
02251 
02252         // Collect solutions in propagator.
02253         int j;
02254         for(int i=0; i<f_size; i+=SPINOR_SIZE){
02255            j=i/SPINOR_SIZE; // lattice site
02256            prop[j].load_vec(spin, color, (wilson_vector &)sol[i]);
02257         }
02258 
02259         if(common_arg->results != 0){
02260           FILE *fp;
02261           if( (fp = Fopen((char *)common_arg->results, "a")) == NULL ) {
02262              ERR.FileA(cname,fname, (char *)common_arg->results);
02263           }
02264           Fprintf(fp, "Cg iters = %d true residual = %e\n",
02265                         iter, true_res);
02266           Fclose(fp);
02267         }
02268 
02269 
02270    } // End spin-color loop
02271 }
02272 
02273 QPropWGFLfuncSrc::~QPropWGFLfuncSrc()
02274 {
02275   char *fname = "~QPropWGFLfuncSrc()";
02276   char *cname = "QPropWGFLfuncSrc";
02277   VRB.Func(cname, fname);
02278   VRB.Sfree(cname, fname, "prop", prop);
02279   sfree(prop);
02280 }
02281 
02282 
02283 //------------------------------------------------------------------
02284 // Quark Propagator (Wilson type) with Wall Source
02285 //------------------------------------------------------------------
02286 QPropWWallSrc::QPropWWallSrc(Lattice& lat, CommonArg* c_arg):QPropW(lat, c_arg) {
02287  
02288   char *fname = "QPropWWallSrc(L&, ComArg*)";
02289   cname = "QPropWWallSrc";
02290   VRB.Func(cname, fname);
02291 }
02292 QPropWWallSrc::QPropWWallSrc(Lattice& lat,  QPropWArg* arg, CommonArg* c_arg):
02293   QPropW(lat, arg, c_arg) { 
02294 
02295   char *fname = "QPropWWallSrc(L&, QPropWArg*, ComArg*)";
02296   cname = "QPropWWallSrc";
02297   VRB.Func(cname, fname);
02298 
02299   // get the propagator
02300   Run();
02301 }
02302 QPropWWallSrc::QPropWWallSrc(QPropWWallSrc& prop1, QPropWWallSrc& prop2): 
02303   QPropW(prop1,prop2) {
02304   
02305   char *fname = "QPropWWallSrc(prop&, prop&)";
02306   cname = "QPropWWallSrc";
02307   VRB.Func(cname, fname);
02308 }
02309 
02310 //set wall source
02311 void QPropWWallSrc::SetSource(FermionVectorTp& src, int spin, int color) {
02312 
02313   char *fname = "SetSource()";
02314   VRB.Func(cname, fname);
02315   
02316   src.ZeroSource() ;
02317   src.SetWallSource(color, spin, qp_arg.t);
02318   if (GFixedSrc())
02319     src.GFWallSource(AlgLattice(), spin, 3, qp_arg.t);
02320 }
02321 
02322 // === for gaussian smeared source ===================================
02323 
02324 QPropWGaussSrc::QPropWGaussSrc(Lattice& lat, CommonArg* c_arg):QPropW(lat, c_arg)
02325 {
02326   char *fname = "QPropWGaussSrc(L&, ComArg*)";
02327   cname = "QPropWGaussSrc";
02328 
02329   VRB.Func(cname, fname);
02330 
02331 }
02332 
02333 QPropWGaussSrc::QPropWGaussSrc(Lattice& lat,  QPropWArg* arg, QPropWGaussArg *g_arg, CommonArg* c_arg):
02334 QPropW(lat, arg, c_arg),gauss_arg(*g_arg)
02335 {
02336   char *fname = "QPropWGaussSrc(L&, QPropWArg*, ComArg*)";
02337   cname = "QPropWGaussSrc";
02338 
02339   VRB.Func(cname, fname);
02340 
02341   // get the propagator
02342   Run();
02343 }
02344 
02345 
02346 // This routine should be eliminated
02347 QPropWGaussSrc::QPropWGaussSrc(QPropWGaussSrc* prop1, QPropWGaussSrc* prop2) :
02348   QPropW(*prop1, *prop2)
02349 {
02350   //char *fname = "QPropWGaussSrc(prop*, prop*)";
02351   //cname = "QPropWGaussSrc";
02352   //VRB.Func(cname, fname);
02353   gauss_arg = prop1->GaussArg();
02354 
02355 }
02356 
02357 QPropWGaussSrc::QPropWGaussSrc(QPropWGaussSrc& prop1, QPropWGaussSrc& prop2) :
02358   QPropW(prop1,prop2)
02359 {
02360   //char *fname = "QPropWGaussSrc(prop&, prop&)";
02361   //cname = "QPropWGaussSrc";
02362   //VRB.Func(cname, fname);
02363   gauss_arg = prop1.GaussArg();
02364 }
02365 
02366 QPropWGaussSrc::QPropWGaussSrc(QPropW& prop1) :
02367   QPropW(prop1)
02368 {
02369   // char *fname = "QPropW(prop&)";
02370   // cname = "QPropWGaussSrc";
02371   // VRB.Func(cname, fname);
02372   gauss_arg = prop1.GaussArg();
02373 }
02374 
02375 
02376 QPropWGaussSrc::QPropWGaussSrc(Lattice& lat,  QPropWArg* arg, QPropWGaussArg *g_arg, CommonArg* c_arg, char* dummy):
02377 QPropW(lat, arg, c_arg),gauss_arg(*g_arg)
02378 {
02379   //char *fname = "QPropWGaussSrc(L&, QPropWArg*, ComArg*)";
02380   //cname = "QPropWGaussSrc";
02381   //VRB.Func(cname, fname);
02382 }
02383 
02384 
02385 //Set gaussian source
02386 void QPropWGaussSrc::SetSource(FermionVectorTp& src, int spin, int color)
02387 {
02388   char *fname = "SetSource()";
02389   VRB.Func(cname, fname);
02390 
02391   src.ZeroSource();
02392   src.SetPointSource(color, spin, qp_arg.x,qp_arg.y,qp_arg.z,qp_arg.t);
02393   DoLinkSmear(gauss_arg);  // YA: smear link if needed
02394   src.GaussianSmearVector(AlgLattice(),spin, gauss_arg.gauss_N, gauss_arg.gauss_W, qp_arg.t);
02395   UndoLinkSmear(gauss_arg); // YA: get back the original link
02396 }
02397 
02398 // Smear the sink of a propagator
02399 void QPropW::GaussSmearSinkProp(int t_sink, const QPropWGaussArg &gauss_arg){
02400   Site site; 
02401   FermionVectorTp tmp ;
02402   WilsonMatrix wm ;
02403 
02404   DoLinkSmear(gauss_arg); // YA: smear link if needed
02405   for(int spin(0);spin<4;spin++)
02406     for(int color(0);color<3;color++){    
02407       //Copy to FermionVector
02408       for(site.Begin();site.End();site.nextSite())
02409         tmp.CopyWilsonMatSink(site.Index(),spin,color,prop[site.Index()]) ;
02410       //smear sink
02411       for(int s(0);s<4;s++)
02412         tmp.GaussianSmearVector(AlgLattice(),s,gauss_arg.gauss_N,gauss_arg.gauss_W,t_sink);
02413       //Copy back to propagator
02414       for(site.Begin();site.End();site.nextSite()){
02415         int i(site.Index()*SPINOR_SIZE);
02416         prop[site.Index()].load_row(spin,color,(wilson_vector &)tmp[i]);
02417       }
02418     }
02419   UndoLinkSmear(gauss_arg); // YA: get original link back
02420 
02421   qp_arg.SeqSmearSink=GAUSS_GAUGE_INV ;
02422   // This is a little dangerous. It's up to the user to know which
02423   // sink time slice is smeared. For the moment it's OK
02424 }
02425 
02426 // Smear the sink of a propagator
02427 void QPropW::GaussSmearSinkProp(const QPropWGaussArg &gauss_arg){
02428   Site site; 
02429   FermionVectorTp tmp ;
02430   WilsonMatrix wm ;
02431 
02432   DoLinkSmear(gauss_arg); // YA: smear link if needed
02433   for(int spin(0);spin<4;spin++)
02434     for(int color(0);color<3;color++){    
02435       //Copy to FermionVector
02436       for(site.Begin();site.End();site.nextSite())
02437         tmp.CopyWilsonMatSink(site.Index(),spin,color,prop[site.Index()]) ;
02438       //smear sink
02439       for(int s(0);s<4;s++)
02440         tmp.GaussianSmearVector(AlgLattice(),s,gauss_arg.gauss_N,gauss_arg.gauss_W);
02441       //Copy back to propagator
02442       for(site.Begin();site.End();site.nextSite()){
02443         int i(site.Index()*SPINOR_SIZE);
02444         prop[site.Index()].load_row(spin,color,(wilson_vector &)tmp[i]);
02445       }
02446     }
02447   UndoLinkSmear(gauss_arg); // YA: get original link back
02448 
02449   qp_arg.SeqSmearSink=GAUSS_GAUGE_INV ;
02450   // This is a little dangerous. It's up to the user to know which
02451   // sink time slice is smeared. For the moment it's OK
02452 }
02453 
02454 // === for exponetial smeared source ===================================
02455 
02456 
02457 // === for multi gaussian smeared source ===================================
02458 
02459 QPropWMultGaussSrc::QPropWMultGaussSrc(Lattice& lat, CommonArg* c_arg):QPropW(lat, c_arg)
02460 {
02461   char *fname = "QPropWGaussSrc(L&, ComArg*)";
02462   cname = "QPropWGaussSrc";
02463 
02464   VRB.Func(cname, fname);
02465 
02466 }
02467 
02468 QPropWMultGaussSrc::QPropWMultGaussSrc(Lattice& lat,  QPropWArg* arg, QPropWGaussArg *g_arg, CommonArg* c_arg):
02469 QPropW(lat, arg, c_arg),gauss_arg(*g_arg)
02470 {
02471   char *fname = "QPropWGaussSrc(L&, QPropWArg*, ComArg*)";
02472   cname = "QPropWGaussSrc";
02473 
02474   VRB.Func(cname, fname);
02475 
02476   // get the propagator
02477   Run();
02478 }
02479 
02480 
02481 // This routine should be eliminated
02482 QPropWMultGaussSrc::QPropWMultGaussSrc(QPropWGaussSrc* prop1, QPropWGaussSrc* prop2) :
02483   QPropW(*prop1, *prop2)
02484 {
02485   //char *fname = "QPropWGaussSrc(prop*, prop*)";
02486   //cname = "QPropWGaussSrc";
02487   //VRB.Func(cname, fname);
02488   gauss_arg = prop1->GaussArg();
02489 
02490 }
02491 
02492 QPropWMultGaussSrc::QPropWMultGaussSrc(QPropWGaussSrc& prop1, QPropWGaussSrc& prop2) :
02493   QPropW(prop1,prop2)
02494 {
02495   //char *fname = "QPropWGaussSrc(prop&, prop&)";
02496   //cname = "QPropWGaussSrc";
02497   //VRB.Func(cname, fname);
02498   gauss_arg = prop1.GaussArg();
02499 }
02500 
02501 QPropWMultGaussSrc::QPropWMultGaussSrc(QPropW& prop1) :
02502   QPropW(prop1)
02503 {
02504   const char *fname = "QPropW(prop&)";
02505   cname = "QPropWGaussSrc";
02506   // VRB.Func(cname, fname);
02507   ERR.NotImplemented(cname,fname);
02508 //  gauss_arg = prop1.GaussArg();
02509 }
02510 //Set gaussian source
02511 void QPropWMultGaussSrc::SetSource(FermionVectorTp& src, int spin, int color)
02512 {
02513   char *fname = "SetSource()";
02514   VRB.Func(cname, fname);
02515 
02516   src.ZeroSource();
02517 
02518   for(int nt(0); nt<gauss_arg.nt; nt++){
02519   src.SetPointSource(color, spin, qp_arg.x,qp_arg.y,qp_arg.z,gauss_arg.mt[nt]);
02520   DoLinkSmear(gauss_arg); // YA: smear link if needed
02521   src.GaussianSmearVector(AlgLattice(),spin, gauss_arg.gauss_N, gauss_arg.gauss_W, gauss_arg.mt[nt]);
02522   UndoLinkSmear(gauss_arg); // YA: get back the original link
02523   }
02524 }
02525 
02526 // === for exponetial smeared source ===================================
02527 
02528 
02529 // exponential smeared source
02530 QPropWExpSrc::QPropWExpSrc(Lattice& lat, CommonArg* c_arg):QPropW(lat, c_arg)
02531 {
02532   char *fname = "QPropWExpSrc(L&, ComArg*)";
02533   cname = "QPropWExpSrc";
02534 
02535   VRB.Func(cname, fname);
02536 }
02537 
02538 QPropWExpSrc::QPropWExpSrc(Lattice& lat,  QPropWArg* arg, QPropWExpArg *e_arg,
02539   CommonArg* c_arg): QPropW(lat, arg, c_arg), exp_arg (*e_arg)
02540 {
02541   char *fname = "QPropWExpSrc(L&, QPropWArg*, ComArg*)";
02542   cname = "QPropWExpSrc";
02543 
02544   VRB.Func(cname, fname);
02545 
02546   // get the propagator
02547   Run();
02548 }
02549 
02550 
02551 QPropWExpSrc::QPropWExpSrc(QPropWExpSrc* prop1, QPropWExpSrc* prop2) :
02552   QPropW(*prop1, *prop2)
02553 {
02554   //char *fname = "QPropWExpSrc(prop*, prop*)";
02555   //cname = "QPropWExpSrc";
02556   //VRB.Func(cname, fname);
02557 
02558 }
02559 
02560 QPropWExpSrc::QPropWExpSrc(QPropWExpSrc& prop1, QPropWExpSrc& prop2) : 
02561 QPropW(prop1,prop2)
02562 {
02563   //char *fname = "QPropWExpSrc(prop&, prop&)";
02564   //cname = "QPropWExpSrc";
02565   //VRB.Func(cname, fname);
02566 
02567 }
02568 
02569 QPropWExpSrc::QPropWExpSrc(QPropW& prop1) : 
02570 QPropW(prop1)
02571 {
02572   //CJ: Have to set exp_arg: how?
02573   //char *fname = "QPropW(prop&)";
02574   //cname = "QPropWExpSrc";
02575   //VRB.Func(cname, fname);
02576   exp_arg.exp_A=1.2;
02577   exp_arg.exp_B=0.1;
02578   exp_arg.exp_C=8;
02579 }
02580 
02581 // Set exponential smeared source
02582 void QPropWExpSrc::SetSource(FermionVectorTp& src, int spin, int color)
02583 {
02584   char *fname = "SetSource()";
02585   VRB.Func(cname, fname);
02586 
02587   src.ZeroSource() ;
02588   //src.SetExpSource(color, spin, qp_arg.x, qp_arg.y, qp_arg.z, qp_arg.t,
02589   //                 exp_arg.exp_A, exp_arg.exp_B, exp_arg.exp_C);
02590   if(qp_arg.gauge_fix_src)
02591     src.GFWallSource(AlgLattice(), spin, 3, qp_arg.t);
02592 }
02593 
02594 //------------------------------------------------------------------
02595 // Quark Propagator (Wilson type) with Momentum Source
02596 //------------------------------------------------------------------
02597 QPropWMomSrc::QPropWMomSrc(Lattice& lat, CommonArg* c_arg):
02598   QPropWWallSrc(lat, c_arg) {
02599   
02600   char *fname = "QPropWMomSrc(L&, ComArg*)";
02601   cname = "QPropWMomSrc";
02602   VRB.Func(cname, fname);
02603 }
02604 QPropWMomSrc::QPropWMomSrc(Lattice& lat,  QPropWArg* arg, 
02605                            int* p, CommonArg* c_arg): 
02606   QPropWWallSrc(lat, c_arg), mom(p) {
02607  
02608   char *fname = "QPropWMomSrc(L&, QPropWArg*, ComArg*)";
02609   cname = "QPropWMomSrc";
02610   VRB.Func(cname, fname);
02611 
02612 //------------------------------------------------------------------
02613 // T.Y Add
02614   qp_arg = *arg;
02615 // T.Y Add
02616 //------------------------------------------------------------------
02617 
02618   Run();
02619 }
02620 // copy constructor
02621 QPropWMomSrc::QPropWMomSrc(const QPropWMomSrc& rhs) : 
02622   QPropWWallSrc(rhs), mom(rhs.mom) {
02623 
02624   char *fname = "QPropW(const QPropW&)";
02625   cname = "QPropW";
02626   VRB.Func(cname, fname);
02627 }
02628 
02629 void QPropWMomSrc::SetSource(FermionVectorTp& src, int spin, int color) {
02630   char *fname = "SetSource()";
02631   VRB.Func(cname, fname);
02632   
02633   src.ZeroSource();
02634   src.SetMomSource(color, spin, qp_arg.t, mom);
02635   if (GFixedSrc())
02636     src.GFWallSource(AlgLattice(), spin, 3, qp_arg.t);
02637 }
02638 
02639 //------------------------------------------------------------------
02640 // Quark Propagator (Wilson type) with Volume Source
02641 //------------------------------------------------------------------
02642 QPropWVolSrc::QPropWVolSrc(Lattice& lat, CommonArg* c_arg) : QPropW(lat, c_arg) {
02643 
02644   char *fname = "QPropWVolSrc(L&, ComArg*)";
02645   cname = "QPropWVolSrc";
02646   VRB.Func(cname, fname);
02647 }
02648 QPropWVolSrc::QPropWVolSrc(Lattice& lat,  QPropWArg* arg, CommonArg* c_arg) : 
02649   QPropW(lat, arg, c_arg) {
02650  
02651   char *fname = "QPropWVolSrc(L&, QPropWArg*, ComArg*)";
02652   cname = "QPropWVolSrc";
02653   VRB.Func(cname, fname);
02654 
02655   Run();
02656 }
02657 
02658 void QPropWVolSrc::SetSource(FermionVectorTp& src, int spin, int color) {
02659 
02660   char *fname = "SetSource()";
02661   VRB.Func(cname, fname);
02662   
02663   src.SetVolSource(color, spin);
02664   if (GFixedSrc())
02665     for (int t=0; t<GJP.Tnodes()*GJP.TnodeSites(); t++)
02666       src.GFWallSource(AlgLattice(), spin, 3, t);
02667 }
02668 
02669 //------------------------------------------------------------------
02670 // Quark Propagator (Wilson type) with Point Source
02671 //------------------------------------------------------------------
02672 QPropWPointSrc::QPropWPointSrc(Lattice& lat, CommonArg* c_arg) : 
02673   QPropW(lat, c_arg) {
02674  
02675   char *fname = "QPropWPointSrc(L&, ComArg*)";
02676   cname = "QPropWPointSrc";
02677   VRB.Func(cname, fname);
02678 }
02679 QPropWPointSrc::QPropWPointSrc(Lattice& lat,  QPropWArg* arg,
02680                                                            CommonArg* c_arg) : 
02681   QPropW(lat, arg, c_arg) {
02682  
02683   char *fname = "QPropWPointSrc(L&, ComArg*)";
02684   cname = "QPropWPointSrc";
02685   VRB.Func(cname, fname);
02686 
02687   Run();
02688 }
02689 
02690 void QPropWPointSrc::SetSource(FermionVectorTp& src, int spin, int color) {
02691 
02692   char *fname = "SetSource()";
02693   VRB.Func(cname, fname);
02694 
02695   src.ZeroSource();
02696   src.SetPointSource(color,spin,qp_arg.x,qp_arg.y,qp_arg.z,qp_arg.t);
02697 }
02698 
02699 //------------------------------------------------------------------
02700 // Quark Propagator (Wilson type) with Box Source
02701 //------------------------------------------------------------------
02702 QPropWBoxSrc::QPropWBoxSrc(Lattice& lat, CommonArg* c_arg) :
02703   QPropW(lat, c_arg) { 
02704 
02705   char *fname = "QPropWBoxSrc(L&, ComArg*)";
02706   cname = "QPropWBoxSrc";
02707   VRB.Func(cname, fname);
02708 }
02709 QPropWBoxSrc::QPropWBoxSrc(Lattice& lat,  QPropWArg* arg,  QPropWBoxArg *b_arg, CommonArg* c_arg) : 
02710   QPropW(lat, arg, c_arg), box_arg(*b_arg) {
02711  
02712   char *fname = "QPropWBoxSrc(L&, QPropWArg*, ComArg*)";
02713   cname = "QPropWBoxSrc";
02714   VRB.Func(cname, fname);
02715 
02716   Run();
02717 }
02718 
02719 void QPropWBoxSrc::SetSource(FermionVectorTp& src, int spin, int color) {
02720 
02721   char *fname = "SetSource()";
02722   VRB.Func(cname, fname);
02723   
02724   src.SetBoxSource(color, spin, box_arg.box_start, box_arg.box_end, qp_arg.t );
02725   if (GFixedSrc()) 
02726     src.GFWallSource(AlgLattice(), spin, 3, qp_arg.t);
02727 }
02728 
02729 //------------------------------------------------------------------
02730 // Quark Propagator (Wilson type) with Random Source
02731 //------------------------------------------------------------------
02732 QPropWRand::QPropWRand(Lattice& lat, CommonArg* c_arg) : QPropW(lat, c_arg) {
02733 
02734   char *fname = "QPropWRand(L&, ComArg*)";
02735   cname = "QPropWRand";
02736   VRB.Func(cname, fname);
02737 
02738   rsrc = NULL;
02739 }
02740 
02741 // Allocate and Delete space for the random source
02742 void QPropWRand::AllocateRsrc() {
02743 
02744   char *fname = "AllocateRsrc()";
02745   VRB.Func(cname, fname);
02746 
02747   if (rsrc == NULL) {
02748         int rsrc_size = 2 * GJP.VolNodeSites();
02749         rsrc = (Float*)smalloc(rsrc_size * sizeof(Float));
02750         if (rsrc == 0) ERR.Pointer(cname, fname, "rsrc");
02751         VRB.Smalloc(cname, fname, "rsrc", rsrc, rsrc_size * sizeof(Float));
02752   }
02753 }
02754 void QPropWRand::DeleteRsrc() {
02755 
02756   char *fname = "DeleteRsrc()";
02757   VRB.Func(cname, fname);
02758 
02759   if (rsrc != NULL) {
02760         VRB.Sfree(cname, fname, "rsrc", rsrc);
02761         sfree(rsrc);
02762         rsrc = NULL;
02763   }
02764 }
02765 
02766 QPropWRand::QPropWRand(Lattice& lat,  QPropWArg* arg, QPropWRandArg *r_arg, 
02767 CommonArg* c_arg) : QPropW(lat, arg, c_arg),rand_arg(*r_arg) 
02768 {
02769   char *fname = "QPropWRand(L&, QPropWArg*, ComArg*)";
02770   cname = "QPropWRand";
02771   VRB.Func(cname, fname);
02772 
02773   rsrc = NULL;
02774   AllocateRsrc();
02775 
02776   int rsrc_size = 2*GJP.VolNodeSites();
02777 
02778   if (rand_arg.rng == GAUSS) {
02779     // MGE 06/10/2008
02780         LRG.SetSigma(0.5);
02781     for (int i=0; i<rsrc_size/2; i++) {
02782       LRG.AssignGenerator(i);
02783       rsrc[2*i] = LRG.Grand(FOUR_D);
02784       rsrc[2*i+1] = LRG.Grand(FOUR_D);
02785     }
02786     // END MGE 06/10/2008
02787 
02788   }
02789   if (rand_arg.rng == UONE) {
02790     // MGE 06/10/2008
02791         LRG.SetInterval(6.283185307179586,0);
02792     for (int i=0; i<rsrc_size/2; i++) {
02793       LRG.AssignGenerator(i);
02794       Float theta(LRG.Urand(FOUR_D));
02795       rsrc[2*i  ] = cos(theta); // real part
02796       rsrc[2*i+1] = sin(theta); // imaginary part
02797     }
02798     // END MGE 06/10/2008
02799   } 
02800   if (rand_arg.rng == ZTWO) {
02801     // MGE 06/10/2008  
02802         LRG.SetInterval(1,-1);
02803     for (int i=0; i<rsrc_size/2; i++) {
02804       LRG.AssignGenerator(i);
02805       if (LRG.Urand(FOUR_D)>0.) {
02806         rsrc[2*i] =  1.;
02807       } else {
02808         rsrc[2*i] = -1.;
02809       }
02810       rsrc[2*i+1] = 0.0; // source is purely real
02811     }
02812     // END MGE 06/10/2008
02813   }
02814 }
02815 
02816 QPropWRand::QPropWRand(const QPropWRand& rhs) : QPropW(rhs),rsrc(NULL) {
02817 
02818   char *fname = "QPropW(const QPropW&)";
02819   cname = "QPropW";
02820   VRB.Func(cname, fname);
02821 
02822   AllocateRsrc();
02823   for (int i=0; i<2*GJP.VolNodeSites(); i++)
02824     rsrc[i] = rhs.rsrc[i];
02825 }
02826 
02827 Complex& QPropWRand::rand_src(int i) const   
02828 { return ((Complex*)rsrc)[i]; }
02829 
02830 QPropWRand& QPropWRand::operator=(const QPropWRand& rhs) {
02831 
02832   char *fname = "operator=(const QPropWRand& rhs)";
02833   VRB.Func(cname, fname);
02834 
02835   if (this != &rhs) {
02836         QPropW::operator=(rhs) ; // This copies the QPropW stuff...
02837       
02838         AllocateRsrc();    
02839         for (int i=0; i<2*GJP.VolNodeSites(); i++)
02840           rsrc[i] = rhs.rsrc[i];
02841   }
02842   
02843   return *this;
02844 }
02845 
02846 QPropWRand::~QPropWRand() {
02847   char *fname = "~QPropWRand()";
02848   VRB.Func(cname, fname);
02849 
02850   DeleteRsrc();
02851 }
02852 
02853 void QPropWRand::ShiftPropForward(int n) {
02854 
02855   char *fname = "ShiftPropForward()";
02856   VRB.Func(cname, fname);
02857 
02858   QPropW::ShiftPropForward(n) ;
02859 
02860   Float* recv_buf;
02861   Float* send_buf;
02862   int len = 12 * 12 * 2;
02863   int len2 = 4;
02864   // size of transfers in words
02865   recv_buf = (Float*)smalloc(len*sizeof(Float));
02866   if (recv_buf == 0) ERR.Pointer(cname,fname, "recv_buf");
02867   VRB.Smalloc(cname, fname, "recv_buf", recv_buf,
02868                           len * sizeof(Float));
02869   
02870   for (int j=0; j<n; j++) {
02871     // shift 1 node in t-dir.  prop -> prop
02872     for (int i=0; i < 2 * GJP.VolNodeSites(); i+=len2) {
02873       send_buf = &rsrc[i];
02874       getMinusData((IFloat*)recv_buf, (IFloat*)send_buf, len2, 3);
02875       moveMem((IFloat*)&rsrc[i], (IFloat*)recv_buf, len2*sizeof(IFloat));
02876     }
02877     
02878   }
02879   
02880   VRB.Sfree(cname, fname, "recv_buf", recv_buf);
02881   sfree(recv_buf);
02882 }
02883 void QPropWRand::ShiftPropBackward(int n) {
02884 
02885   char *fname = "ShiftPropBackward()";
02886   VRB.Func(cname, fname);
02887 
02888   QPropW::ShiftPropBackward(n) ;
02889 
02890   Float* recv_buf;
02891   Float* send_buf;
02892   int len = 12 * 12 * 2;
02893   int len2 = 4;
02894   // size of transfer in words
02895   recv_buf = (Float*)smalloc(len * sizeof(Float));
02896   if (recv_buf == 0) ERR.Pointer(cname,fname, "recv_buf");
02897   VRB.Smalloc(cname, fname, "recv_buf", recv_buf,
02898               len * sizeof(Float));
02899   
02900   for (int j=0; j<n; j++) {
02901     // shift 1 node in t-dir.  prop -> prop
02902     for (int i=0; i < 2 * GJP.VolNodeSites(); i+=len2) {
02903       send_buf = &rsrc[i];
02904       getPlusData((IFloat*)recv_buf, (IFloat*)send_buf, len2, 3);
02905       moveMem((IFloat*)&rsrc[i], (IFloat*)recv_buf, len2*sizeof(IFloat));
02906     }
02907     
02908   }
02909   
02910   VRB.Sfree(cname, fname, "recv_buf", recv_buf);
02911   sfree(recv_buf);
02912 }
02913 
02914 // Restore prop
02915 void QPropWRand::RestoreQProp(char* name, int mid) {
02916 
02917    char *fname = "RestoreQProp()";
02918    VRB.Func(cname, fname);
02919    /****************************************************************
02920      The code below is temporarily isolated for purposes of merging
02921      with CPS main branch,  12/09/04, Oleg Loktik 
02922    -------------------- Quarantine starts --------------------------
02923 
02924    
02925    QPropW::RestoreQProp(name,mid) ;
02926 
02927    AllocateRsrc();
02928    
02929    unsigned int* data;
02930    data = (unsigned int*)rsrc;
02931    read_data(name, data, 
02932              GJP.VolNodeSites() * sizeof(Complex),
02933              GJP.VolNodeSites() * sizeof(WilsonMatrix));
02934    VRB.Flow(cname,fname,"Read rsrc from file %s\n", name);
02935   -------------------- Quarantine ends ---------------------------*/
02936 }
02937 // Save prop
02938 void QPropWRand::SaveQProp(char* name, int mid) {
02939   char *fname = "SaveQProp()";
02940   VRB.Func(cname, fname);
02941    /****************************************************************
02942      The code below is temporarily isolated for purposes of merging
02943      with CPS main branch,  12/09/04, Oleg Loktik 
02944    -------------------- Quarantine starts --------------------------
02945   
02946 
02947   QPropW::SaveQProp(name,mid) ;
02948   
02949   unsigned int* data;
02950   data = (unsigned int*)rsrc;
02951   append_data(name, data, GJP.VolNodeSites() * sizeof(Complex));
02952   VRB.Flow(cname,fname,"Appended rsrc to file %s\n", name);
02953   DeleteRsrc();
02954   -------------------- Quarantine ends ---------------------------*/
02955 }
02956 
02957 //------------------------------------------------------------------
02958 // Quark Propagator (Wilson type) with Random Wall Source
02959 //------------------------------------------------------------------
02960 QPropWRandWallSrc::QPropWRandWallSrc(Lattice& lat, CommonArg* c_arg) : 
02961   QPropWRand(lat, c_arg) {
02962   
02963   char *fname = "QPropWRandWallSrc(L&, ComArg*)";
02964   cname = "QPropWRandWallSrc";
02965   VRB.Func(cname, fname);
02966 }
02967 QPropWRandWallSrc::QPropWRandWallSrc(Lattice& lat,  QPropWArg* arg, 
02968   QPropWRandArg *r_arg, CommonArg* c_arg) 
02969   : QPropWRand(lat, arg, r_arg, c_arg) {
02970  
02971   char *fname = "QPropWRandWallSrc(L&, ComArg*)";
02972   cname = "QPropWRandWallSrc";
02973   VRB.Func(cname, fname);
02974 
02975   Run();
02976 }
02977 
02978 void QPropWRandWallSrc::SetSource(FermionVectorTp& src, int spin, int color) {
02979 
02980   char *fname = "SetSource()"; 
02981   VRB.Func(cname, fname);
02982 
02983   if (rsrc==NULL) {//need random numbers may implemented later
02984     ERR.General(cname,fname,"No randrom numbers found!\n") ;
02985   }
02986 
02987   src.ZeroSource();
02988   src.SetWallSource(color, spin, qp_arg.t, rsrc);
02989   if (GFixedSrc())
02990     src.GFWallSource(AlgLattice(), spin, 3, qp_arg.t);
02991 }
02992 
02993 
02994 //------------------------------------------------------------------
02995 // Quark Propagator (Wilson type) with Random Volume Source
02996 //------------------------------------------------------------------
02997 QPropWRandVolSrc::QPropWRandVolSrc(Lattice& lat, CommonArg* c_arg) : 
02998   QPropWRand(lat, c_arg) {
02999 
03000   char *fname = "QPropWRandVolSrc(L&, ComArg*)";
03001   cname = "QPropWRandVolSrc";
03002   VRB.Func(cname, fname);
03003 }
03004 QPropWRandVolSrc::QPropWRandVolSrc(Lattice& lat,  QPropWArg* arg, 
03005   QPropWRandArg *r_arg, CommonArg* c_arg) 
03006   : QPropWRand(lat, arg, r_arg, c_arg) {
03007  
03008   char *fname = "QPropWRandVolSrc(L&, ComArg*)";
03009   cname = "QPropWRandVolSrc";
03010   VRB.Func(cname, fname);
03011 
03012   Run();
03013 }
03014 
03015 //set the random source
03016 void QPropWRandVolSrc::SetSource(FermionVectorTp& src, int spin, int color) {
03017 
03018   char *fname = "SetSource()"; 
03019   VRB.Func(cname, fname);
03020 
03021   if (rsrc==NULL) {//need random numbers may implemented later
03022     ERR.General(cname,fname,"No randrom numbers found!\n") ;
03023   }
03024   
03025   src.SetVolSource(color, spin, rsrc);
03026   if (GFixedSrc()) 
03027     for (int t=0;t<GJP.Tnodes()*GJP.TnodeSites(); t++)
03028       src.GFWallSource(AlgLattice(), spin, 3, t);
03029 }
03030 
03031 
03032 //------------------------------------------------------------------
03033 // Quark Propagator (Wilson type) with Random Slab Source
03034 //------------------------------------------------------------------
03035 QPropWRandSlabSrc::QPropWRandSlabSrc(Lattice& lat, CommonArg* c_arg) : 
03036   QPropWRand(lat, c_arg) {
03037 
03038   char *fname = "QPropWRandSlabSrc(L&, ComArg*)";
03039   cname = "QPropWRandSlabSrc";
03040   VRB.Func(cname, fname);
03041 }
03042 
03043 QPropWRandSlabSrc::QPropWRandSlabSrc(Lattice& lat,  QPropWArg* arg, 
03044   QPropWSlabArg *s_arg, CommonArg* c_arg) 
03045   : QPropWRand(lat, arg, &(s_arg->rand_arg), c_arg),slab_width(s_arg->slab_width) {
03046  
03047   char *fname = "QPropWRandSlabSrc(L&, ComArg*)";
03048   cname = "QPropWRandSlabSrc";
03049   VRB.Func(cname, fname);
03050 
03051   Run();
03052 }
03053 
03054 QPropWRandSlabSrc::QPropWRandSlabSrc(Lattice &lat, QPropWArg* arg, 
03055                                      Float* src, CommonArg* c_arg): 
03056   QPropWRand(lat, c_arg) {
03057 
03058   char *fname = "QPropWRandSlabSrc(L&, QPropWArg*, Float*, CommonArg*)";
03059   cname = "QPropWRandSlabSrc";
03060   VRB.Func(cname, fname);
03061    
03062   for (int i=0; i<2*GJP.VolNodeSites(); i++)
03063     rsrc[i] = src[i];
03064 
03065   Run();
03066 }
03067 
03068 void QPropWRandSlabSrc::SetSource(FermionVectorTp& src, int spin, int color) {
03069 
03070   char *fname = "SetSource()"; 
03071   VRB.Func(cname, fname);
03072 
03073   if (rsrc==NULL) {//need random numbers may implemented later
03074     ERR.General(cname,fname,"No randrom numbers found!\n") ;
03075   }
03076   src.ZeroSource();
03077   
03078   for (int t=qp_arg.t; t < qp_arg.t+slab_width; t++) {
03079     src.SetWallSource(color, spin, t, rsrc);
03080     if (GFixedSrc()) 
03081       src.GFWallSource(AlgLattice(), spin, 3, t);
03082   }
03083 }
03084 
03085 //------------------------------------------------------------------
03086 // Quark Propagator (Wilson type) with Sequential Sources
03087 //------------------------------------------------------------------
03088 QPropWSeq::QPropWSeq(Lattice& lat, QPropW& q, int *p, 
03089                      QPropWArg* q_arg, CommonArg* c_arg) : 
03090   QPropW(lat, q_arg, c_arg), quark(q), mom(p) {
03091 
03092   char *fname = "QPropWSeq(L&, ComArg*)";
03093   cname = "QPropWSeq";
03094   VRB.Func(cname, fname);
03095   
03096   // Stores the quark mass of the source propagator
03097   // Needed by Yasumichi's not degenerate mass runs
03098   quark_mass = quark.Mass() ; 
03099   
03100   //if the QPropW used for constructing the sequential source
03101   //propagator is done using HalfFerion set the DoHalfFermion 
03102   //in case the user forgot to do so.
03103   if (q.DoHalfFermion()) qp_arg.do_half_fermion = 1;
03104 }
03105 
03106 
03107 QPropWSeqMesSrc::QPropWSeqMesSrc(Lattice& lat, QPropW& quark,  int *p, 
03108                                  int g, QPropWArg* q_arg, CommonArg* c_arg) : 
03109   QPropWSeq(lat, quark, p, q_arg, c_arg),gamma(g) {
03110 
03111   char *fname = "QPropWSeq(L&,...)";
03112   cname = "QPropWSeq";
03113   VRB.Func(cname, fname);
03114 
03115   Run();
03116 }
03117 
03118 void QPropWSeqMesSrc::SetSource(FermionVectorTp& src, int spin, int color) {
03119 
03120   char *fname = "SetSource()";
03121   cname = "QPropWSeqMesSrc";
03122   VRB.Func(cname, fname);
03123 
03124   if (color < 0 || color >= GJP.Colors())
03125     ERR.General(cname, fname,
03126                                 "Color index out of range: color = %d\n", color);
03127   
03128   if (spin < 0 || spin > 3)
03129     ERR.General(cname, fname,
03130                                 "Spin index out of range: spin = %d\n", spin);
03131 
03132   src.ZeroSource();
03133   Site s;
03134   WilsonMatrix tmp;
03135   for (s.Begin();s.End();s.nextSite())
03136     if (qp_arg.t == s.physT()) {
03137       tmp = quark[s.Index()];
03138       tmp.gl(gamma); // Multiply by the meson operator
03139       // multiply by the mommentum factor exp(ipx)
03140       Complex tt(conj(mom.Fact(s)));
03141       tmp*=tt;
03142       src.CopyWilsonMatSink(s.Index(),spin,color,tmp);
03143     }
03144 
03145   // Gauge fix the source. If QPropW sink is gauge fixed
03146   // this has to be done!
03147   if (quark.GFixedSnk()) {
03148         for (int ss=0;ss<4;ss++)
03149           src.GFWallSource(AlgLattice(), ss, 3, qp_arg.t);
03150   }
03151 }
03152 
03153 QPropWSeqBar::QPropWSeqBar(Lattice& lat, QPropW& quark,  int *p, 
03154                                                    ProjectType pp, QPropWArg* q_arg, 
03155                                                    CommonArg* c_arg) : 
03156   QPropWSeq(lat, quark, p, q_arg, c_arg), proj(pp) {
03157 
03158   char *fname = "QPropWSeqBar(L&,...)";
03159   cname = "QPropWSeq";
03160   VRB.Func(cname, fname);
03161 }
03162 
03163 
03164 QPropWSeqProtDSrc::QPropWSeqProtDSrc(Lattice& lat, QPropW& quark,  int *p, 
03165                                                                          ProjectType pp, QPropWArg* q_arg,
03166                                                                          QPropWGaussArg *g_arg, CommonArg* c_arg):
03167   QPropWSeqBar(lat, quark, p, pp, q_arg, c_arg),gauss_arg(*g_arg) {
03168 
03169   char *fname = "QPropWSeqProtDSrc(L&,...)";
03170   cname = "QPropWSeq";
03171   VRB.Func(cname, fname);
03172 
03173   Run();
03174 
03175   //Multiply by gamma5 and take the dagger to make it in to quark.
03176   Site s;
03177   for (s.Begin();s.End();s.nextSite()) {
03178         QPropW::operator[](s.Index()).gl(-5);
03179         QPropW::operator[](s.Index()).hconj();
03180   }
03181 }
03182 
03183 QPropWSeqProtDSrc::QPropWSeqProtDSrc(Lattice& lat, QPropW& quark, int *p, ProjectType pp, QPropWArg* q_arg, QPropWGaussArg *g_arg, CommonArg* c_arg, char* dummy):
03184   QPropWSeqBar(lat, quark, p, pp, q_arg, c_arg), gauss_arg(*g_arg) 
03185 {
03186   // char *fname = "QPropW(prop&)";
03187   // cname = "QPropWGaussSrc";
03188   // VRB.Func(cname, fname);
03189 }
03190 
03191 void QPropWSeqProtDSrc::SetSource(FermionVectorTp& src, int spin, int color) {
03192 
03193   char *fname = "SetSource()";  
03194   VRB.Func(cname, fname);
03195 
03196   if (color < 0 || color >= GJP.Colors())
03197     ERR.General(cname, fname,
03198                                 "Color index out of range: color = %d\n", color);
03199   
03200   if (spin < 0 || spin > 3)
03201     ERR.General(cname, fname,
03202                                 "Spin index out of range: spin = %d\n", spin);
03203   
03204   src.ZeroSource();
03205   Site s;
03206   Diquark diq;
03207   WilsonVector S;
03208 
03209   WilsonMatrix q;
03210   WilsonMatrix OqO;
03211   WilsonMatrix qO ;
03212   WilsonMatrix Oq ;
03213   for (s.Begin();s.End();s.nextSite())
03214     for(int nt=0; nt<gauss_arg.nt; nt++){
03215     if (gauss_arg.mt[nt] == s.physT()) {
03216           int i = s.Index();
03217           q = quark[i];
03218           // If DoHalfFermion is on we have non-relativistic sources
03219           // Multiply the sink by 1/2(1+gamma_t) when we do Half Spinors
03220           // By doing this we implement the non-relativistic sink
03221           if (DoHalfFermion()) q.PParProjectSink(); 
03222           Oq = qO = q;
03223           // multiply C*gamma_5 left  C is the charge conjugation
03224           Oq.ccl(5);
03225           // multiply C*gamma_5 right C is the charge conjugation
03226           qO.ccr(5);
03227           OqO = Oq;
03228           // multiply C*gamma_5 right C is the charge conjugation
03229           // Shoichi's code misses a minus sign here (or in ccl)
03230           OqO.ccr(5);
03231           // spin is denoted as delta in notes
03232           // color is denoted as d in notes
03233           diq.D_diquark(OqO, q, Oq, qO, spin, color);
03234           diq.Project(S,proj);
03235           
03236           //multiply by the momentum factor exp(ipx)
03237           Complex tt(conj(mom.Fact(s)));
03238           S*=tt;
03239 
03240           S.conj();
03241 
03242           //if non-relativistic sink is needed multiply  by 1/2(1+gamma_t)
03243           if (DoHalfFermion()) S.PParProject(); 
03244           //Note the order first project then multiply by gamma5 
03245           //multily by gamma5
03246           S.gamma(-5);  
03247           
03248           src.CopyWilsonVec(i,S);
03249     }
03250     } // nt loop
03251   
03252   // Gauge fix the source. If quark sink is gauge fixed
03253   // this has to be done!
03254   if (quark.GFixedSnk()) {
03255         for (int ss=0;ss<4;ss++)
03256           src.GFWallSource(AlgLattice(), ss, 3, qp_arg.t);
03257   }
03258   if(quark.SeqSmearSink()==GAUSS_GAUGE_INV){
03259   DoLinkSmear(gauss_arg);  // YA: smear link if needed
03260   for(int nt=0; nt<gauss_arg.nt; nt++){
03261     for(int ss=0;ss<4;ss++)
03262       src.GaussianSmearVector(AlgLattice(),ss,
03263                               quark.GaussArg().gauss_N,quark.GaussArg().gauss_W,gauss_arg.mt[nt]);
03264     //source sink smearing is the same
03265   }
03266   UndoLinkSmear(gauss_arg); // YA: get back the original link
03267   }
03268 }
03269 
03270 QPropWSeqProtUSrc::QPropWSeqProtUSrc(Lattice& lat, QPropW& quark,  int *p, 
03271                                                                          ProjectType pp, QPropWArg* q_arg,
03272                                                                          QPropWGaussArg *g_arg, CommonArg* c_arg):
03273   QPropWSeqBar(lat, quark, p, pp, q_arg, c_arg),gauss_arg(*g_arg) {
03274 
03275   char *fname = "QPropWSeqProtUSrc(L&,...)";
03276   cname = "QPropWSeq";
03277   VRB.Func(cname, fname);
03278 
03279   Run();
03280 
03281   //Multiply by gamma5 and take the dagger to make it in to quark.
03282   Site s;
03283   for (s.Begin();s.End();s.nextSite()) {
03284         QPropW::operator[](s.Index()).gl(-5);
03285         QPropW::operator[](s.Index()).hconj(); 
03286   }
03287 }
03288 
03289 QPropWSeqProtUSrc::QPropWSeqProtUSrc(Lattice& lat, QPropW& quark, int *p, ProjectType pp, QPropWArg* q_arg, QPropWGaussArg *g_arg, CommonArg* c_arg, char* dummy):
03290   QPropWSeqBar(lat, quark, p, pp, q_arg, c_arg),gauss_arg(*g_arg)
03291 {
03292   // char *fname = "QPropW(prop&)";
03293   // cname = "QPropWGaussSrc";
03294   // VRB.Func(cname, fname);
03295 }
03296 
03297 void QPropWSeqProtUSrc::SetSource(FermionVectorTp& src, int spin, int color) {
03298 
03299   char *fname = "SetSource()";  
03300   VRB.Func(cname, fname);
03301 
03302   if (color < 0 || color >= GJP.Colors())
03303     ERR.General(cname, fname,
03304                                 "Color index out of range: color = %d\n", color);
03305   
03306   if (spin < 0 || spin > 3)
03307     ERR.General(cname, fname,
03308                                 "Spin index out of range: spin = %d\n", spin);
03309   
03310   src.ZeroSource();
03311   Site s;
03312   Diquark diq;
03313   WilsonVector S;
03314   WilsonMatrix q;
03315   WilsonMatrix OqO;
03316 
03317   for (s.Begin();s.End();s.nextSite())
03318     for(int nt=0; nt<gauss_arg.nt; nt++){
03319     if (gauss_arg.mt[nt] == s.physT()) {
03320           int i(s.Index());
03321           q = quark[i];
03322           // If DoHalfFermion is on we have non-relativistic sources
03323           // Multiply the sink by 1/2(1+gamma_t) when we do Half Spinors
03324           // By doing this we implement the non-relativistic sink
03325           if (DoHalfFermion()) q.PParProjectSink();
03326           OqO = q;
03327           
03328           // multiply C*gamma_5 left  C is the charge conjugation
03329           OqO.ccl(5);
03330           // multiply C*gamma_5 right C is the charge conjugation
03331           OqO.ccr(5);
03332           // spin is denoted as delta in notes
03333           // color is denoted as d in notes
03334           
03335           diq.U_diquark(OqO, q, spin, color);
03336           diq.Project(S,proj);
03337           
03338           //multiply by the momentum factor exp(ipx)
03339           Complex tt(conj(mom.Fact(s)));
03340           S*=tt;
03341           
03342           S.conj();
03343           
03344           //if non-relativistic sink is needed multiply  by 1/2(1+gamma_t)
03345           if (DoHalfFermion()) S.PParProject(); 
03346           //Note the order first project then multiply by gamma5 
03347           //multily by gamma5
03348           S.gamma(-5);
03349           
03350           src.CopyWilsonVec(i,S);
03351     }// Loop over sites
03352     } // nt loop
03353   
03354   // Gauge fix the source. If quark sink is gauge fixed
03355   // this has to be done!
03356   if (quark.GFixedSnk()) {
03357         for (int ss=0;ss<4;ss++)
03358           src.GFWallSource(AlgLattice(), ss, 3, qp_arg.t);
03359   }
03360   if(quark.SeqSmearSink()==GAUSS_GAUGE_INV){
03361   DoLinkSmear(gauss_arg);  // YA: smear link if needed
03362   for(int nt=0; nt<gauss_arg.nt; nt++){
03363     for(int ss=0;ss<4;ss++)
03364       src.GaussianSmearVector(AlgLattice(),ss,
03365                               quark.GaussArg().gauss_N,quark.GaussArg().gauss_W,gauss_arg.mt[nt]);
03366     //source sink smearing is the same
03367   }
03368   UndoLinkSmear(gauss_arg); // YA: get back the original link
03369   }
03370 }
03371 
03372   //-----------------------------------------------------------------
03373   // TY Add Start
03374 int QPropW::siteOffset(const int lcl[], const int lcl_sites[]) const
03375 {
03376   int l = 4 - 1;
03377   int offset = lcl[l];
03378   while (l-- > 0) {
03379       offset *= lcl_sites[l];
03380       offset += lcl[l];
03381   }
03382   return offset;
03383 }
03384   // TY Add End
03385   //-----------------------------------------------------------------
03386 
03387 int QPropW::BoxSrcStart() const{
03388   ERR.NotImplemented(cname,"BoxSrcStart()");
03389   return 0;
03390 }
03391 int QPropW::BoxSrcEnd() const{
03392   ERR.NotImplemented(cname,"BoxSrcEnd()");
03393   return 0;
03394 }
03395 
03396 static  QPropWGaussArg dummy_arg;
03397 const QPropWGaussArg &QPropW::GaussArg(void){
03398   ERR.NotImplemented(cname,"GaussArg()");
03399   //dummy code to get rid or warnings
03400   return dummy_arg;
03401 }
03402 int QPropW::Gauss_N() const{
03403   ERR.NotImplemented(cname,"Gauss_N()");
03404   return 0;
03405 }
03406 Float QPropW::Gauss_W() const{
03407   ERR.NotImplemented(cname,"Gauss_W()");
03408   return 0;
03409 }
03410 
03411 CPS_END_NAMESPACE

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