//CK: In this test we check that the DWF fermion force term is evaluated correctly #include #include #include #include #include #include #ifdef PARALLEL #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if(0==1) #include #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_BFM #include #endif using namespace std; USING_NAMESPACE_CPS void setup_double_latt(Lattice &double_latt, Matrix* orig_gfield, bool gparity_X, bool gparity_Y); void setup_double_rng(bool gparity_X, bool gparity_Y); void setup_double_matrixfield(Matrix* double_mat, Matrix* orig_mat, int nmat_per_site, bool gparity_X, bool gparity_Y); void EvolveMomFforceUstarGparity(Lattice &lat, Matrix *mom, Vector *chi, Float mass, Float dt); void GaugeTransformU(Matrix *gtrans, Lattice &lat); void GaugeTransformP(Matrix *gtrans, Matrix* mom, Lattice &lat); void GaugeTransformF(Matrix *gtrans,Vector* ferm,Lattice &lat); IFloat vect_norm(Vector *v, int n){ IFloat out(0.0); for (int i=0; i< n; i++) out += v[i].NormSqGlbSum(6); return out; } int main(int argc,char *argv[]) { Start(&argc,&argv); //initialises QMP #ifdef HAVE_BFM Chroma::initialize(&argc,&argv); #endif CommandLine::is(argc,argv); bool gparity_X(false); bool gparity_Y(false); int arg0 = CommandLine::arg_as_int(0); printf("Arg0 is %d\n",arg0); if(arg0==0){ gparity_X=true; printf("Doing G-parity HMC test in X direction\n"); }else{ printf("Doing G-parity HMC test in X and Y directions\n"); gparity_X = true; gparity_Y = true; } bool dbl_latt_storemode(false); bool save_config(false); bool load_config(false); bool load_lrg(false); bool save_lrg(false); char *load_config_file; char *save_config_file; char *save_lrg_file; char *load_lrg_file; bool gauge_fix(false); bool verbose(false); int size[] = {2,2,2,2,2}; { int i=2; while(iargc-6){ printf("Did not specify enough arguments for 'latt' (require 5 dimensions)\n"); exit(-1); } size[0] = CommandLine::arg_as_int(i); //CommandLine ignores zeroth input arg (i.e. executable name) size[1] = CommandLine::arg_as_int(i+1); size[2] = CommandLine::arg_as_int(i+2); size[3] = CommandLine::arg_as_int(i+3); size[4] = CommandLine::arg_as_int(i+4); i+=6; }else if( strncmp(cmd,"-save_double_latt",20) == 0){ dbl_latt_storemode = true; i++; }else if( strncmp(cmd,"-load_lrg",15) == 0){ if(i==argc-1){ printf("-load_lrg requires an argument\n"); exit(-1); } load_lrg=true; load_lrg_file = argv[i+1]; i+=2; }else if( strncmp(cmd,"-save_lrg",15) == 0){ if(i==argc-1){ printf("-save_lrg requires an argument\n"); exit(-1); } save_lrg=true; save_lrg_file = argv[i+1]; i+=2; }else if( strncmp(cmd,"-gauge_fix",15) == 0){ gauge_fix=true; i++; }else if( strncmp(cmd,"-verbose",15) == 0){ verbose=true; i++; }else{ if(UniqueID()==0) printf("Unrecognised argument: %s\n",cmd); exit(-1); } } } printf("Lattice size is %d %d %d %d\n",size[0],size[1],size[2],size[3],size[4]); DoArg do_arg; do_arg.x_sites = size[0]; do_arg.y_sites = size[1]; do_arg.z_sites = size[2]; do_arg.t_sites = size[3]; do_arg.s_sites = size[4]; do_arg.x_node_sites = 0; do_arg.y_node_sites = 0; do_arg.z_node_sites = 0; do_arg.t_node_sites = 0; do_arg.s_node_sites = 0; do_arg.x_nodes = 0; do_arg.y_nodes = 0; do_arg.z_nodes = 0; do_arg.t_nodes = 0; do_arg.s_nodes = 0; do_arg.updates = 0; do_arg.measurements = 0; do_arg.measurefreq = 0; do_arg.cg_reprod_freq = 10; do_arg.x_bc = BND_CND_PRD; do_arg.y_bc = BND_CND_PRD; do_arg.z_bc = BND_CND_PRD; do_arg.t_bc = BND_CND_APRD; do_arg.start_conf_kind = START_CONF_ORD; do_arg.start_conf_load_addr = 0x0; do_arg.start_seed_kind = START_SEED_FIXED; do_arg.start_seed_filename = "../rngs/ckpoint_rng.0"; do_arg.start_conf_filename = "../configurations/ckpoint_lat.0"; do_arg.start_conf_alloc_flag = 6; do_arg.wfm_alloc_flag = 2; do_arg.wfm_send_alloc_flag = 2; do_arg.start_seed_value = 83209; do_arg.beta = 2.25; do_arg.c_1 = -3.3100000000000002e-01; do_arg.u0 = 1.0000000000000000e+00; do_arg.dwf_height = 1.8000000000000000e+00; do_arg.dwf_a5_inv = 1.0000000000000000e+00; do_arg.power_plaq_cutoff = 0.0000000000000000e+00; do_arg.power_plaq_exponent = 0; do_arg.power_rect_cutoff = 0.0000000000000000e+00; do_arg.power_rect_exponent = 0; do_arg.verbose_level = -1202;// -1202;//VERBOSE_DEBUG_LEVEL; //-1202; do_arg.checksum_level = 0; do_arg.exec_task_list = 0; do_arg.xi_bare = 1.0000000000000000e+00; do_arg.xi_dir = 3; do_arg.xi_v = 1.0000000000000000e+00; do_arg.xi_v_xi = 1.0000000000000000e+00; do_arg.clover_coeff = 0.0000000000000000e+00; do_arg.clover_coeff_xi = 0.0000000000000000e+00; do_arg.xi_gfix = 1.0000000000000000e+00; do_arg.gfix_chkb = 1; do_arg.asqtad_KS = 0.0000000000000000e+00; do_arg.asqtad_naik = 0.0000000000000000e+00; do_arg.asqtad_3staple = 0.0000000000000000e+00; do_arg.asqtad_5staple = 0.0000000000000000e+00; do_arg.asqtad_7staple = 0.0000000000000000e+00; do_arg.asqtad_lepage = 0.0000000000000000e+00; do_arg.p4_KS = 0.0000000000000000e+00; do_arg.p4_knight = 0.0000000000000000e+00; do_arg.p4_3staple = 0.0000000000000000e+00; do_arg.p4_5staple = 0.0000000000000000e+00; do_arg.p4_7staple = 0.0000000000000000e+00; do_arg.p4_lepage = 0.0000000000000000e+00; if(verbose) do_arg.verbose_level = VERBOSE_CLOCK_LEVEL; if(gparity_X) do_arg.x_bc = BND_CND_GPARITY; if(gparity_Y) do_arg.y_bc = BND_CND_GPARITY; GJP.Initialize(do_arg); SerialIO::dbl_latt_storemode = dbl_latt_storemode; LRG.Initialize(); //usually initialised when lattice generated, but I pre-init here so I can load the state from file if(load_lrg){ if(UniqueID()==0) printf("Loading RNG state from %s\n",load_lrg_file); LRG.Read(load_lrg_file,32); } if(save_lrg){ if(UniqueID()==0) printf("Writing RNG state to %s\n",save_lrg_file); LRG.Write(save_lrg_file,32); } GwilsonFdwf* lattice = new GwilsonFdwf; if(!load_config){ printf("Creating gauge field\n"); lattice->SetGfieldDisOrd(); //unit gauge }else{ ReadLatticeParallel readLat; if(UniqueID()==0) printf("Reading: %s (NERSC-format)\n",load_config_file); readLat.read(*lattice,load_config_file); if(UniqueID()==0) printf("Config read.\n"); } if(save_config){ if(UniqueID()==0) printf("Saving config to %s\n",save_config_file); QioArg wt_arg(save_config_file,0.001); wt_arg.ConcurIONumber=32; WriteLatticeParallel wl; wl.setHeader("disord_id","disord_label",0); wl.write(*lattice,wt_arg); if(!wl.good()) ERR.General("main","()","Failed write lattice %s",save_config_file); if(UniqueID()==0) printf("Config written.\n"); } if(gauge_fix){ lattice->FixGaugeAllocate(FIX_GAUGE_COULOMB_T); lattice->FixGauge(1e-06,2000); if(!UniqueID()){ printf("Gauge fixing finished\n"); fflush(stdout); } } #define U_USTAR_EVOLVE_CHECK #ifdef U_USTAR_EVOLVE_CHECK { printf("Starting U U* evolve check\n"); Lattice &lat = *lattice; //test the gauge field evolution by calculating the conjugate momentum for the U links //and separately for the U* links and compare them int f_sites = GJP.SnodeSites()*GJP.VolNodeSites() / (lat.FchkbEvl()+1); //half-checkerboard fermion int f_vec_count = 2* f_sites * lat.SpinComponents(); //number of 3-vectors in fermion size_t f_size = f_vec_count * lat.Colors() * 2; int Ncb; if(lat.FchkbEvl() == 1) Ncb = 1; else if(lat.FchkbEvl() == 0) Ncb = 2; Vector* tmp1 = (Vector*)smalloc(f_size*sizeof(Float),"tmp1","",""); Vector* tmp2 = (Vector*)smalloc(f_size*sizeof(Float),"tmp2","",""); Vector* phi = (Vector *) smalloc(f_size*sizeof(Float),"phi","",""); //~~make a random two-flavour pseudofermion field from the heatbath as usual~~ LatRanGen LRGbak(LRG); lat.RandGaussVector(tmp1, 0.5, Ncb); lat.RandGaussVector(tmp2, 0.5, Ncb); LRG = LRGbak; Float h_init = 0.0; // phi <- M_f^\dag (RGV) h_init += lat.SetPhi(phi, tmp1, tmp2, 0.2, DAG_YES); //mass is 0.2 //~~mom field evolve~~ //invert D^\dag D on phi Vector *cg_sol = (Vector*)smalloc(f_size*sizeof(Float),"cg_sol","",""); CgArg frm_cg_arg_md; frm_cg_arg_md.mass = 0.2; frm_cg_arg_md.max_num_iter = 5000; frm_cg_arg_md.stop_rsd = 1e-06; lat.FmatEvlInv(cg_sol, phi, &frm_cg_arg_md, CNV_FRM_NO); int g_size = 2*GJP.VolNodeSites() * lat.GsiteSize(); // //take a copy of the gauge field Matrix* gcopy = (Matrix*)smalloc(g_size*sizeof(Float),"gcopy","",""); memcpy((void*)gcopy,(void*)lat.GaugeField(),g_size*sizeof(Float)); //evolve U conj mom then copy-conjugate to U* field conj mom Matrix* mom = (Matrix*)smalloc(g_size*sizeof(Float),"mom","",""); for(int i=0;i<2*4*GJP.VolNodeSites();i++) mom[i].ZeroMatrix(); lat.EvolveMomFforce(mom, cg_sol, 0.5, 1.0); //evolve //restore the gauge field memcpy((void*)lat.GaugeField(),(void*)gcopy,g_size*sizeof(Float)); Matrix* mom2 = (Matrix*)smalloc(g_size*sizeof(Float),"mom2","",""); for(int i=0;i<2*4*GJP.VolNodeSites();i++) mom2[i].ZeroMatrix(); //evolve U* conj mom then copy-conjugate to U field conj mom EvolveMomFforceUstarGparity(lat, mom2, cg_sol, 0.5, 1.0); //restore the gauge field memcpy((void*)lat.GaugeField(),(void*)gcopy,g_size*sizeof(Float)); int flav_off = GJP.VolNodeSites()*4; printf("Checking momentum fields\n"); //mom and mom2 should be the same Float err(0.0); for(int f=0;f<2;f++){ for(int t=0;t 1e-08 || fabs(*(m+1) - *(mc+1)) > 1e-08 ){ printf("Node %d %d %d %d , Error: f%d (%d %d %d %d), %d: (%f %f), (%f %f)\n",GJP.XnodeCoor(),GJP.YnodeCoor(),GJP.ZnodeCoor(),GJP.TnodeCoor(),f,x,y,z,t,mu,*m,*(m+1),*mc, *(mc+1)); err=1.0; } } } } } } } glb_sum(&err); if(err>0.0){ printf("U U* evolve check failed\n"); exit(-1); } sfree(tmp1); sfree(tmp2); sfree(phi); sfree(cg_sol); sfree(gcopy); sfree(mom); sfree(mom2); printf("U U* evolve check passed\n"); } #endif #define GAUGE_TRANSFORM_CHECK #ifdef GAUGE_TRANSFORM_CHECK { printf("Starting gauge transform check\n"); //test the code by performing a gauge transformation and checking the conjugate momentum transforms in the correct way //U -> e^{i \pi^a T^a}U //V_x U^mu_x V_{x+\mu}^\dagger -> V_x e^{i \pi^a T^a} U^\mu_x V_{x+\mu}^\dagger = V_x(1 + [i\pi^aT^a] + [i\pi^aT^a][i\pi^bT^b]/2 +....)U^\mu_x V^\dagger_{x+\mu} // = V_x(1 + [i\pi^aT^a] + [i\pi^aT^a]V^\dagger V[i\pi^bT^b]/2 +....)V_x^\dagger V_x U^\mu_x V^\dagger_{x+\mu} // = e^{iV_x\pi^a T^a V_x^\dagger} V_x U V_{x+\mu}^\dagger // so (\pi^a T^a) -> V_x (\pi^a T^a) V_x^\dagger //remember that the gauge link on the G-parity boundary transforms as V U V^T Lattice &lat = *lattice; //test the gauge field evolution by calculating the conjugate momentum for the U links //and separately for the U* links and compare them int f_sites = GJP.SnodeSites()*GJP.VolNodeSites() / (lat.FchkbEvl()+1); //half-checkerboard fermion int f_vec_count = 2* f_sites * lat.SpinComponents(); //number of 3-vectors in fermion size_t f_size = f_vec_count * lat.Colors() * 2; int Ncb; if(lat.FchkbEvl() == 1) Ncb = 1; else if(lat.FchkbEvl() == 0) Ncb = 2; Vector* tmp1 = (Vector*)smalloc(f_size*sizeof(Float),"tmp1","",""); Vector* tmp2 = (Vector*)smalloc(f_size*sizeof(Float),"tmp2","",""); Vector* phi = (Vector *) smalloc(f_size*sizeof(Float),"phi","",""); //~~make a random two-flavour pseudofermion field from the heatbath as usual~~ LatRanGen LRGbak(LRG); lat.RandGaussVector(tmp1, 0.5, Ncb); lat.RandGaussVector(tmp2, 0.5, Ncb); LRG = LRGbak; Float h_init; // phi <- M_f^\dag (RGV) h_init = lat.SetPhi(phi, tmp1, tmp2, 0.2, DAG_YES); //mass is 0.2 printf("h_init = %f\n", h_init); //~~mom field evolve~~ //invert D^\dag D on phi Vector *cg_sol = (Vector*)smalloc(f_size*sizeof(Float),"cg_sol","",""); CgArg frm_cg_arg_md; frm_cg_arg_md.mass = 0.2; frm_cg_arg_md.max_num_iter = 5000; frm_cg_arg_md.stop_rsd = 1e-08; lat.FmatEvlInv(cg_sol, phi, &frm_cg_arg_md, CNV_FRM_NO); int g_size = 2*GJP.VolNodeSites() * lat.GsiteSize(); //take a copy of the gauge field Matrix* gcopy = (Matrix*)smalloc(g_size*sizeof(Float),"gcopy","",""); memcpy((void*)gcopy,(void*)lat.GaugeField(),g_size*sizeof(Float)); //evolve U conj mom then copy-conjugate to U* field conj mom Matrix* mom = (Matrix*)smalloc(g_size*sizeof(Float),"mom","",""); for(int i=0;i<2*4*GJP.VolNodeSites();i++) mom[i].ZeroMatrix(); lat.EvolveMomFforce(mom, cg_sol, 0.5, 1.0); //evolve //restore the gauge field memcpy((void*)lat.GaugeField(),(void*)gcopy,g_size*sizeof(Float)); //generate a random gauge transformation Matrix *gtrans = (Matrix *) pmalloc(GJP.VolNodeSites()*18*sizeof(Float)); #if 1 for(int i=0;iUnitarize(); //make SU(3) } #endif #if 0 //unit matrix test for(int i=0;i 1e-06 || fabs(*(m+1) - *(mc+1)) > 1e-06 ){ printf("Node %d %d %d %d , Error: f%d (%d %d %d %d), %d: (%f %f), (%f %f)\n",GJP.XnodeCoor(),GJP.YnodeCoor(),GJP.ZnodeCoor(),GJP.TnodeCoor(),f,x,y,z,t,mu,*m,*(m+1),*mc, *(mc+1)); err=1.0; } } } } } } } glb_sum(&err); if(err>0.0){ printf("Gauge transform check failed\n"); exit(-1); } sfree(tmp1); sfree(tmp2); sfree(phi); sfree(cg_sol); sfree(gcopy); sfree(mom); sfree(mom2); printf("Gauge transform check passed\n"); } #endif #define _1F_2F_COMPARISON #ifdef _1F_2F_COMPARISON Matrix *_2f_mom; int _2f_norm; { printf("Starting 1f 2f evolve check\n"); Lattice &lat = *lattice; //test the gauge field evolution by calculating the conjugate momentum in both the 2f and 1f models //and compare them int f_sites = GJP.SnodeSites()*GJP.VolNodeSites() / (lat.FchkbEvl()+1); //half-checkerboard fermion int f_vec_count = 2* f_sites * lat.SpinComponents(); //number of 3-vectors in fermion size_t f_size = f_vec_count * lat.Colors() * 2; int Ncb; if(lat.FchkbEvl() == 1) Ncb = 1; else if(lat.FchkbEvl() == 0) Ncb = 2; Vector* tmp1 = (Vector*)smalloc(f_size*sizeof(Float),"tmp1","",""); Vector* tmp2 = (Vector*)smalloc(f_size*sizeof(Float),"tmp2","",""); Vector* phi = (Vector *) smalloc(f_size*sizeof(Float),"phi","",""); //backup the RNG LatRanGen LRGbak(LRG); //~~make a random two-flavour pseudofermion field from the heatbath as usual~~ lat.RandGaussVector(tmp1, 0.5, Ncb); lat.RandGaussVector(tmp2, 0.5, Ncb); //restore the RNG LRG = LRGbak; Float h_init = 0.0; // phi <- M_f^\dag (RGV) h_init += lat.SetPhi(phi, tmp1, tmp2, 0.2, DAG_YES); //mass is 0.2 //~~mom field evolve~~ //invert D^\dag D on phi Vector *cg_sol = (Vector*)smalloc(f_size*sizeof(Float),"cg_sol","",""); CgArg frm_cg_arg_md; frm_cg_arg_md.mass = 0.2; frm_cg_arg_md.max_num_iter = 5000; frm_cg_arg_md.stop_rsd = 1e-08; lat.FmatEvlInv(cg_sol, phi, &frm_cg_arg_md, CNV_FRM_NO); _2f_norm = vect_norm(cg_sol,f_vec_count); int g_size = 2*GJP.VolNodeSites() * lat.GsiteSize(); //evolve U conj mom then copy-conjugate to U* field conj mom Matrix* mom = (Matrix*)smalloc(g_size*sizeof(Float),"mom","",""); for(int i=0;i<2*4*GJP.VolNodeSites();i++) mom[i].ZeroMatrix(); lat.EvolveMomFforce(mom, cg_sol, 0.5, 1.0); //evolve _2f_mom = mom; sfree(tmp1); sfree(tmp2); sfree(phi); sfree(cg_sol); } #endif if(gauge_fix) lattice->FixGaugeFree(); if(UniqueID()==0){ printf("Starting double lattice force\n"); fflush(stdout); } int array_size = 2*lattice->GsiteSize() * GJP.VolNodeSites() * sizeof(Float); Matrix *orig_lattice = (Matrix *) pmalloc(array_size); memcpy((void*)orig_lattice, (void*)lattice->GaugeField(), array_size); lattice->FreeGauge(); //free memory and reset delete lattice; //lattice objects are singleton (scope_lock) //setup 1f model. Upon calling GJP.Initialize the lattice size will be doubled in the appropriate directions //and the boundary condition set to APRD if(gparity_X) do_arg.gparity_1f_X = 1; if(gparity_Y) do_arg.gparity_1f_Y = 1; GJP.Initialize(do_arg); if(GJP.Gparity()){ printf("Que?\n"); exit(-1); } if(UniqueID()==0) printf("Doubled lattice : %d %d %d %d\n", GJP.XnodeSites()*GJP.Xnodes(),GJP.YnodeSites()*GJP.Ynodes(), GJP.ZnodeSites()*GJP.Znodes(),GJP.TnodeSites()*GJP.Tnodes()); #ifdef HAVE_BFM { QDP::multi1d nrow(Nd); for(int i = 0;i test(Nd); // nrow=size; QDP::Layout::setLattSize(nrow); QDP::Layout::create(); } #endif GwilsonFdwf* doubled_lattice = new GwilsonFdwf; setup_double_latt(*doubled_lattice,orig_lattice,gparity_X,gparity_Y); setup_double_rng(gparity_X,gparity_Y); if(gauge_fix){ doubled_lattice->FixGaugeAllocate(FIX_GAUGE_COULOMB_T); doubled_lattice->FixGauge(1e-06,2000); if(!UniqueID()){ printf("Gauge fixing finished\n"); fflush(stdout); } } #ifdef _1F_2F_COMPARISON { printf("Starting 1f 2f evolve check part II\n"); Lattice &lat = *doubled_lattice; int g_size = GJP.VolNodeSites() * lat.GsiteSize(); Matrix *_2f_mom_dbl = (Matrix*)smalloc(g_size*sizeof(Float),"mom","",""); setup_double_matrixfield(_2f_mom_dbl, _2f_mom, 4, gparity_X,gparity_Y); //test the gauge field evolution by calculating the conjugate momentum in both the 2f and 1f models //and compare them int f_sites = GJP.SnodeSites()*GJP.VolNodeSites() / (lat.FchkbEvl()+1); //half-checkerboard fermion int f_vec_count = f_sites * lat.SpinComponents(); //number of 3-vectors in fermion size_t f_size = f_vec_count * lat.Colors() * 2; int Ncb; if(lat.FchkbEvl() == 1) Ncb = 1; else if(lat.FchkbEvl() == 0) Ncb = 2; Vector* tmp1 = (Vector*)smalloc(f_size*sizeof(Float),"tmp1","",""); Vector* tmp2 = (Vector*)smalloc(f_size*sizeof(Float),"tmp2","",""); Vector* phi = (Vector *) smalloc(f_size*sizeof(Float),"phi","",""); //backup the RNG LatRanGen LRGbak(LRG); //~~make a random one-flavour pseudofermion field from the heatbath as usual~~ lat.RandGaussVector(tmp1, 0.5, Ncb); lat.RandGaussVector(tmp2, 0.5, Ncb); if(GJP.Gparity1fY()){ //make source on upper-right quadrant negative (RNGs should be correct) for(int s=0;s=GJP.Xnodes()*GJP.XnodeSites()/2 && gy>=GJP.Ynodes()*GJP.YnodeSites()/2){ int pos[5] = {x,y,z,t,s}; int f_off = lat.FsiteOffsetChkb(pos) * lat.SpinComponents(); for(int spn=0;spn 0.01 ){ printf("Node %d, 2f and 1f prop norms not equal: %d %d\n", UniqueID(), _2f_norm, _1f_norm); exit(-1); }else{ printf("Node %d, 2f and 1f prop norms are equal: %d %d\n", UniqueID(), _2f_norm, _1f_norm); } //evolve U conj mom then copy-conjugate to U* field conj mom Matrix* mom = (Matrix*)smalloc(g_size*sizeof(Float),"mom","",""); for(int i=0;i<4*GJP.VolNodeSites();i++) mom[i].ZeroMatrix(); lat.EvolveMomFforce(mom, cg_sol, 0.5, 1.0); //evolve //check 1f vs 2f mom { bool err(false); for(int t=0;t 1e-05 || fabs(*(m+1) - *(mc+1)) > 1e-05 ){ printf("Error: Xnode %d, 1f:2f (%d %d %d %d), %d: (%f %f), (%f %f)\n",GJP.XnodeCoor(),gpos[0],gpos[1],gpos[2],gpos[3],mu,*m,*(m+1),*mc, *(mc+1)); err=true; } } } } } } if(err){ printf("Failed 1f-2f comparison\n"); exit(-1); } printf("Passed 1f-2f comparison\n"); } sfree(tmp1); sfree(tmp2); sfree(phi); sfree(cg_sol); } #endif if(gauge_fix) doubled_lattice->FixGaugeFree(); doubled_lattice->FreeGauge(); //free memory and reset delete doubled_lattice; //lattice objects are singleton (scope_lock) //#define TEST_U_USTAR_FORCE_RELN #ifdef TEST_U_USTAR_FORCE_RELN { if(gparity_X && gparity_Y){ printf("TEST_U_USTAR_FORCE_RELN test not valid for quad lattice\n"); exit(-1); } //generate a single lattice with random gauge links and APBC do_arg.x_bc = BND_CND_PRD; do_arg.x_sites = size[0]; if(do_arg.x_sites/GJP.Xnodes() < 2){ ERR.General("main","TEST_U_USTAR_FORCE_RELN","After dividing initial Xnodesites by 2, too few sites on node: %d\n",do_arg.x_sites/GJP.Xnodes()); } GJP.Initialize(do_arg); #ifdef HAVE_BFM { QDP::multi1d nrow(Nd); for(int i = 0;i test(Nd); // nrow=size; QDP::Layout::setLattSize(nrow); QDP::Layout::create(); } #endif GwilsonFdwf* lattice = new GwilsonFdwf; lattice->SetGfieldDisOrd(); Lattice &lat = *lattice; int f_sites = GJP.SnodeSites()*GJP.VolNodeSites() / (lat.FchkbEvl()+1); //half-checkerboard fermion int f_vec_count = f_sites * lat.SpinComponents(); //number of 3-vectors in fermion size_t f_size = f_vec_count * lat.Colors() * 2; int Ncb; if(lat.FchkbEvl() == 1) Ncb = 1; else if(lat.FchkbEvl() == 0) Ncb = 2; Vector* tmp1 = (Vector*)smalloc(f_size*sizeof(Float),"tmp1","",""); Vector* tmp2 = (Vector*)smalloc(f_size*sizeof(Float),"tmp2","",""); Vector* phi = (Vector *) smalloc(f_size*sizeof(Float),"phi","",""); //~~make a random pseudofermion field from the heatbath as usual~~ lat.RandGaussVector(tmp1, 0.5, Ncb); lat.RandGaussVector(tmp2, 0.5, Ncb); Float h_init = 0.0; // phi <- M_f^\dag (RGV) h_init += lat.SetPhi(phi, tmp1, tmp2, 0.2, DAG_YES); //mass is 0.2 //~~mom field evolve~~ //invert D^\dag D on phi Vector *cg_sol = (Vector*)smalloc(f_size*sizeof(Float),"cg_sol","",""); CgArg frm_cg_arg_md; frm_cg_arg_md.mass = 0.2; frm_cg_arg_md.max_num_iter = 5000; frm_cg_arg_md.stop_rsd = 1e-06; lat.FmatEvlInv(cg_sol, phi, &frm_cg_arg_md, CNV_FRM_NO); //evolve the momentum int g_size = GJP.VolNodeSites() * lat.GsiteSize(); Matrix* mom = (Matrix*)smalloc(g_size*sizeof(Float),"mom","",""); for(int i=0;i<4*GJP.VolNodeSites();i++) mom[i].ZeroMatrix(); lat.EvolveMomFforce(mom, cg_sol, 0.5, 1.0); //evolve //complex conjugate all links on lattice U->U*, U*->U Matrix *lp = lat.GaugeField(); for(int t=0;tconj().ccl(1).gamma(-5); vec_base+=vec_size; } //evolve the momentum Matrix* momconj = (Matrix*)smalloc(g_size*sizeof(Float),"momconj","",""); for(int i=0;i<4*GJP.VolNodeSites();i++) momconj[i].ZeroMatrix(); lat.EvolveMomFforce(momconj, cg_sol, 0.5, 1.0); //evolve //printf("h_init %f, h_init_conj %f\n",h_init,h_init_conj); //mom and momconj should be complex conjugates of each other for(int t=0;t e^{i \pi^a T^a}U //V_x U^mu_x V_{x+\mu}^\dagger -> V_x e^{i \pi^a T^a} U^\mu_x V_{x+\mu}^\dagger = V_x(1 + [i\pi^aT^a] + [i\pi^aT^a][i\pi^bT^b]/2 +....)U^\mu_x V^\dagger_{x+\mu} // = V_x(1 + [i\pi^aT^a] + [i\pi^aT^a]V^\dagger V[i\pi^bT^b]/2 +....)V_x^\dagger V_x U^\mu_x V^\dagger_{x+\mu} // = e^{iV_x\pi^a T^a V_x^\dagger} V_x U V_{x+\mu}^\dagger // so (\pi^a T^a) -> V_x (\pi^a T^a) V_x^\dagger do_arg.x_bc = BND_CND_PRD; do_arg.x_sites = size[0]; if(do_arg.x_sites/GJP.Xnodes() < 2){ ERR.General("main","TEST_SINGLE_LATT_GTRANS","After dividing initial Xnodesites by 2, too few sites on node: %d\n",do_arg.x_sites/GJP.Xnodes()); } GJP.Initialize(do_arg); #ifdef HAVE_BFM { QDP::multi1d nrow(Nd); for(int i = 0;i test(Nd); // nrow=size; QDP::Layout::setLattSize(nrow); QDP::Layout::create(); } #endif GwilsonFdwf* lattice = new GwilsonFdwf; lattice->SetGfieldDisOrd(); Lattice &lat = *lattice; //test the gauge field evolution by calculating the conjugate momentum for the U links //and separately for the U* links and compare them int f_sites = GJP.SnodeSites()*GJP.VolNodeSites() / (lat.FchkbEvl()+1); //half-checkerboard fermion int f_vec_count = f_sites * lat.SpinComponents(); //number of 3-vectors in fermion size_t f_size = 2*f_vec_count * lat.Colors(); int Ncb; if(lat.FchkbEvl() == 1) Ncb = 1; else if(lat.FchkbEvl() == 0) Ncb = 2; Vector* tmp1 = (Vector*)smalloc(f_size*sizeof(Float),"tmp1","",""); Vector* tmp2 = (Vector*)smalloc(f_size*sizeof(Float),"tmp2","",""); Vector* phi = (Vector *) smalloc(f_size*sizeof(Float),"phi","",""); //~~make a random two-flavour pseudofermion field from the heatbath as usual~~ lat.RandGaussVector(tmp1, 0.5, Ncb); lat.RandGaussVector(tmp2, 0.5, Ncb); Float h_init; // phi <- M_f^\dag (RGV) h_init = lat.SetPhi(phi, tmp1, tmp2, 0.2, DAG_YES); //mass is 0.2 printf("h_init = %f\n", h_init); //~~mom field evolve~~ //invert D^\dag D on phi Vector *cg_sol = (Vector*)smalloc(f_size*sizeof(Float),"cg_sol","",""); CgArg frm_cg_arg_md; frm_cg_arg_md.mass = 0.2; frm_cg_arg_md.max_num_iter = 5000; frm_cg_arg_md.stop_rsd = 1e-08; lat.FmatEvlInv(cg_sol, phi, &frm_cg_arg_md, CNV_FRM_NO); int g_size = GJP.VolNodeSites() * lat.GsiteSize(); //calculate U conj mom Matrix* mom = (Matrix*)smalloc(g_size*sizeof(Float),"mom","",""); for(int i=0;i<4*GJP.VolNodeSites();i++) mom[i].ZeroMatrix(); lat.EvolveMomFforce(mom, cg_sol, 0.5, 1.0); //evolve //generate a random gauge transformation Matrix *gtrans = (Matrix *) pmalloc(GJP.VolNodeSites()*18*sizeof(Float)); #if 1 for(int i=0;iUnitarize(); //make SU(3) } #endif #if 0 //unit matrix test for(int i=0;i 1e-06 || fabs(*(m+1) - *(mc+1)) > 1e-06 ){ printf("Error: U_new (%d %d %d %d), %d: (%f %f), (%f %f)\n",x,y,z,t,mu,*m,*(m+1),*mc, *(mc+1)); err=true; } } } } } } if(err) exit(-1); printf("Passed test of mom field gtrans relation\n"); pfree(evolved); pfree(evolvedprime); } //----prepare to recalculated conjugate momentum for transformed field------ //restore transformed gauge field memcpy((void*)lat.GaugeField(),(void*)uprimecopy,g_size*sizeof(Float)); //gauge transform the fields GaugeTransformF(gtrans,tmp1,lat); GaugeTransformF(gtrans,tmp2,lat); // redo phi phi <- M_f^\dag (RGV) and recalculate cg_sol = D^\dag D on phi h_init = lat.SetPhi(phi, tmp1, tmp2, 0.2, DAG_YES); //mass is 0.2 printf("h_init post gauge-transform = %f\n", h_init); lat.FmatEvlInv(cg_sol, phi, &frm_cg_arg_md, CNV_FRM_NO); //evolve U conj mom then copy-conjugate to U* field conj mom Matrix* mom2 = (Matrix*)smalloc(g_size*sizeof(Float),"mom2","",""); for(int i=0;i<4*GJP.VolNodeSites();i++) mom2[i].ZeroMatrix(); lat.EvolveMomFforce(mom2, cg_sol, 0.5, 1.0); //evolve //mom and mom2 should be the same bool err(false); for(int t=0;t 1e-06 || fabs(*(m+1) - *(mc+1)) > 1e-06 ){ printf("Error: (%d %d %d %d), %d: (%f %f), (%f %f)\n",x,y,z,t,mu,*m,*(m+1),*mc, *(mc+1)); err=true; } } } } } } if(err) exit(-1); sfree(tmp1); sfree(tmp2); sfree(phi); sfree(cg_sol); sfree(ucopy); sfree(mom); sfree(mom2); sfree(gtrans); printf("Single lattice Gauge transform check passed\n"); } #endif #ifdef HAVE_BFM Chroma::finalize(); #endif if(UniqueID()==0){ printf("Main job complete\n"); fflush(stdout); } return 0; } void setup_double_latt(Lattice &double_latt, Matrix* orig_gfield, bool gparity_X, bool gparity_Y){ //orig latt ( U_0 U_1 ) ( U_2 U_3 ) ( U_4 U_5 ) ( U_6 U_7 ) //double tatt ( U_0 U_1 U_2 U_3 ) ( U_4 U_5 U_6 U_7 ) ( U_0* U_1* U_2* U_3* ) ( U_4* U_5* U_6* U_7* ) Matrix *dbl_gfield = double_latt.GaugeField(); if(!UniqueID()){ printf("Setting up 1f lattice.\n"); fflush(stdout); } SingleToDoubleLattice lattdoubler(gparity_X,gparity_Y,orig_gfield,double_latt); lattdoubler.Run(); if(!UniqueID()){ printf("Finished setting up 1f lattice\n"); fflush(stdout); } } void setup_double_rng(bool gparity_X, bool gparity_Y){ //orig 4D rng 2 stacked 4D volumes //orig ([R_0 R_1][R'_0 R'_1])([R_2 R_3][R'_2 R'_3])([R_4 R_5][R'_4 R'_5])([R_6 R_7][R'_6 R'_7]) //double (R_0 R_1 R_2 R_3)(R_4 R_5 R_6 R_7)(R'_0 R'_1 R'_2 R'_3)(R'_4 R'_5 R'_6 R'_7) //orig 5D rng 2 stacked 4D volumes per ls/2 slice (ls/2 as only one RNG per 2^4 block) SingleToDouble4dRNG fourDsetup(gparity_X,gparity_Y); SingleToDouble5dRNG fiveDsetup(gparity_X,gparity_Y); LRG.Reinitialize(); //reset the LRG and prepare for doubled lattice form if(!UniqueID()){ printf("Setting up 1f 4D RNG\n"); fflush(stdout); } fourDsetup.Run(); if(!UniqueID()){ printf("Setting up 1f 5D RNG\n"); fflush(stdout); } fiveDsetup.Run(); } void setup_double_matrixfield(Matrix* double_mat, Matrix* orig_mat, int nmat_per_site, bool gparity_X, bool gparity_Y){ if(!UniqueID()){ printf("Setting up 1f matrix field.\n"); fflush(stdout); } SingleToDoubleMatrixField doubler(gparity_X,gparity_Y,nmat_per_site,orig_mat,double_mat); doubler.Run(); if(!UniqueID()){ printf("Finished setting up 1f matrixfield\n"); fflush(stdout); } } #include void EvolveMomFforceUstarGparity(Lattice &lat, Matrix *mom, Vector *chi, double mass, double dt){ printf("Test version\n"); char* cname = ""; char* fname = "EvolveMomFforceUstarGparity"; if(!GJP.Gparity()) ERR.General(cname,fname,"Function executed when G-parity BCs not in use\n"); Matrix *gauge = lat.GaugeField() ; if (lat.Colors() != 3) ERR.General(cname,fname,"Wrong nbr of colors.") ; if (lat.SpinComponents() != 4) ERR.General(cname,fname,"Wrong nbr of spin comp.") ; if (mom == 0) ERR.Pointer(cname,fname,"mom") ; if (chi == 0) ERR.Pointer(cname,fname,"chi") ; //---------------------------------------------------------------- // allocate space for two CANONICAL fermion fields //---------------------------------------------------------------- size_t f_size = lat.FsiteSize() * GJP.VolNodeSites() ; int f_site_size_4d = 2 * lat.Colors() * lat.SpinComponents(); size_t f_size_4d = f_site_size_4d * GJP.VolNodeSites() ; //CK: Need space for both d and C\bar u^T fields stacked //Two 4d volumes are stacked on each Ls such that Ls can be split over multiple nodes size_t f_size_alloc = f_size *2 *sizeof(double); int f_single4dsite_alloc = lat.FsiteSize()*sizeof(double)*2; char *str_v1 = "v1" ; Vector *v1 = (Vector *)smalloc(f_size_alloc) ; if (v1 == 0) ERR.Pointer(cname, fname, str_v1) ; VRB.Smalloc(cname, fname, str_v1, v1, f_size_alloc) ; char *str_v2 = "v2" ; Vector *v2 = (Vector *)smalloc(f_size_alloc) ; if (v2 == 0) ERR.Pointer(cname, fname, str_v2) ; VRB.Smalloc(cname, fname, str_v2, v2, f_size_alloc) ; //---------------------------------------------------------------- // allocate buffer space for two fermion fields that are assoc // with only one 4-D site. //---------------------------------------------------------------- char *str_site_v1 = "site_v1" ; double *site_v1 = (double *)smalloc(f_single4dsite_alloc) ; if (site_v1 == 0) ERR.Pointer(cname, fname, str_site_v1) ; VRB.Smalloc(cname, fname, str_site_v1, site_v1, f_single4dsite_alloc) ; char *str_site_v2 = "site_v2" ; double *site_v2 = (double *)smalloc(f_single4dsite_alloc) ; if (site_v2 == 0) ERR.Pointer(cname, fname, str_site_v2) ; VRB.Smalloc(cname, fname, str_site_v2, site_v2, f_single4dsite_alloc) ; //CK: G-parity site vectors on each Ls are 2 * flavours 4 spin * 3 clr * 2 re/im //Sticking with same layout as 5d guys, stack 2 site vectors on each Ls //Ls=0 [ d ][ CubarT ] Ls=1 [ d ][ CubarT ] ..... //---------------------------------------------------------------- // Calculate v1, v2. Both v1, v2 must be in CANONICAL order after // the calculation. //---------------------------------------------------------------- { CgArg cg_arg ; cg_arg.mass = mass ; DiracOpDwf dwf(lat, v1, v2, &cg_arg, CNV_FRM_YES) ; dwf.CalcHmdForceVecs(chi) ; } int mu, x, y, z, t, s, lx, ly, lz, lt, ls ; lx = GJP.XnodeSites() ; ly = GJP.YnodeSites() ; lz = GJP.ZnodeSites() ; lt = GJP.TnodeSites() ; ls = GJP.SnodeSites() ; Matrix tmp_mat1, tmp_mat2, tmp_mat3; for (mu=0; mu<4; mu++){ for (t=0; t(&lat); // if(gauge_offset == 4){ //site is x=y=z=t=mu=0 // double v[24]; // double w[24]; // for(int i=0;i<24;i++){ // v[i] = LRG.Urand(); // w[i] = LRG.Urand(); // } // Matrix test1; // lattice->sproj_tr[mu]( (double *)&test1, // v,w, // 1, 0,0) ; // printf("test a:\n"); // double *m = (double *)&test1; // for(int i=0;i<3;i++){ // for(int j=0;j<3;j++){ // printf("(%f,%f) ",*m,*(m+1)); m+=2; // } // printf("\n"); // } // lattice->sproj_tr[mu]( (double *)&test1, // w,v, // 1, 0,0) ; // printf("test b:\n"); // m = (double *)&test1; // for(int i=0;i<3;i++){ // for(int j=0;j<3;j++){ // printf("(%f,%f) ",*m,*(m+1)); m+=2; // } // printf("\n"); // } // //tmp_mat1_{ij} = tr_s ( P_+^mu v1(x+mu)_i v2^\dagger(x)_j // lattice->sproj_tr[mu]( (double *)&test1, // (double *)v1_plus_mu, // (double *)v2+vec_offset, // 1, vec_plus_mu_stride, 2*f_size_4d-f_site_size_4d) ; // if(gauge_offset == 4){ // printf("f1 contrib a normal s1:\n"); // double *m = (double *)&test1; // for(int i=0;i<3;i++){ // for(int j=0;j<3;j++){ // printf("(%f,%f) ",*m,*(m+1)); m+=2; // } // printf("\n"); // } // } // lattice->sproj_tr[mu]( (double *)&test1, // (double *)v2+vec_offset, // (double *)v1_plus_mu, // 1, vec_plus_mu_stride, 2*f_size_4d-f_site_size_4d) ; // if(gauge_offset == 4){ // printf("f1 contrib a s1:\n"); // double *m = (double *)&tmp_mat1; // for(int i=0;i<3;i++){ // for(int j=0;j<3;j++){ // printf("(%f,%f) ",*m,*(m+1)); m+=2; // } // printf("\n"); // } // } // } //Calculate contributions to force at site //from d field //d field part 1 //normally tmp_mat1_{ij} = tr_s ( P_+^mu v1(x+mu)_i v2^\dagger(x)_j with v1 = X, v2 = M X //for conjugate instead we want tmp_mat1_{ij} = tr_s ( P_+^mu v2(x)_i v1^\dagger(x+mu)_j lattice->sproj_tr[mu]( (double *)&tmp_mat1, (double *)v2+vec_offset, (double *)v1_plus_mu, ls, 2*f_size_4d-f_site_size_4d, vec_plus_mu_stride) ; // if(gauge_offset == 4){ // printf("f1 contrib a:\n"); // double *m = (double *)&tmp_mat1; // for(int i=0;i<3;i++){ // for(int j=0;j<3;j++){ // printf("(%f,%f) ",*m,*(m+1)); m+=2; // } // printf("\n"); // } // } //d field part 2 //normally tmp_mat2_{ij} = tr_s ( P_-^mu v2(x+mu)_i v1^\dagger(x)_j //for conjugate instead we want tmp_mat2_{ij} = tr_s ( P_-^mu v1(x)_i v2^\dagger(x+mu)_j lattice->sproj_tr[mu+4]( (double *)&tmp_mat2, (double *)v1+vec_offset, (double *)v2_plus_mu, ls, 2*f_size_4d-f_site_size_4d, vec_plus_mu_stride) ; // if(gauge_offset == 4){ // printf("f1 contrib b:\n"); // double *m = (double *)&tmp_mat2; // for(int i=0;i<3;i++){ // for(int j=0;j<3;j++){ // printf("(%f,%f) ",*m,*(m+1)); m+=2; // } // printf("\n"); // } // } tmp_mat1 += tmp_mat2; tmp_mat2.Trans(tmp_mat1);//must transpose outer product on colour index tmp_mat1 = tmp_mat2; tmp_mat1 *=d_coeff; //different coefficient for the two flavours // if(gauge_offset == 4){ // printf("f1 contrib:\n"); // double *m = (double *)&tmp_mat1; // for(int i=0;i<3;i++){ // for(int j=0;j<3;j++){ // printf("(%f,%f) ",*m,*(m+1)); m+=2; // } // printf("\n"); // } // } //Cubar^T field part 1 //normally tmp_mat2_{ij} = tr_s ( P_-^mu v1(x)_i v2^\dagger(x+mu)_j //for conjugate we want tmp_mat2_{ij} = tr_s ( P_-^mu v2(x+mu)_i v1^\dagger(x)_j lattice->sproj_tr[mu+4]( (double *)&tmp_mat2, (double *)v2_plus_mu_CubarT, (double *)v1+vec_offset+f_size_4d, ls, vec_plus_mu_stride, 2*f_size_4d-f_site_size_4d) ; // if(gauge_offset == 4){ // printf("f2 contrib a:\n"); // double *m = (double *)&tmp_mat2; // for(int i=0;i<3;i++){ // for(int j=0;j<3;j++){ // printf("(%f,%f) ",*m,*(m+1)); m+=2; // } // printf("\n"); // } // } //Cubar^T field part 2 //tmp_mat3_{ij} = tr_s ( P_+^mu v2(x)_i v1^\dagger(x+mu)_j //for conjugate we want tmp_mat3_{ij} = tr_s ( P_+^mu v1(x+mu)_i v2^\dagger(x)_j lattice->sproj_tr[mu]( (double *)&tmp_mat3, (double *)v1_plus_mu_CubarT, (double *)v2+vec_offset+f_size_4d, ls, vec_plus_mu_stride, 2*f_size_4d-f_site_size_4d) ; // if(gauge_offset == 4){ // printf("f2 contrib b:\n"); // double *m = (double *)&tmp_mat3; // for(int i=0;i<3;i++){ // for(int j=0;j<3;j++){ // printf("(%f,%f) ",*m,*(m+1)); m+=2; // } // printf("\n"); // } // } tmp_mat2+= tmp_mat3; tmp_mat2*=CubarT_coeff; tmp_mat1 += tmp_mat2; // if(gauge_offset == 4){ // printf("f2 contrib:\n"); // double *m = (double *)&tmp_mat2; // for(int i=0;i<3;i++){ // for(int j=0;j<3;j++){ // printf("(%f,%f) ",*m,*(m+1)); m+=2; // } // printf("\n"); // } // } // If GJP.Snodes > 1 sum up contributions from all s nodes if(GJP.Snodes() > 1) { glb_sum_multi_dir((double *)&tmp_mat1,4,sizeof(Matrix)/sizeof(double)); } tmp_mat2.DotMEqual(*(gauge+gauge_offset+GJP.VolNodeSites()*4), tmp_mat1) ; //multiply by U* field rather than U field //tmp_mat1.Trans(tmp_mat2) ; //tmp_mat2.TrLessAntiHermMatrix(tmp_mat1) ; //tmp_mat2.Conj(tmp_mat2); //these 3 steps give 0 tmp_mat1.Dagger(tmp_mat2) ; tmp_mat2.TrLessAntiHermMatrix(tmp_mat1) ; *(mom+gauge_offset+GJP.VolNodeSites()*4) += tmp_mat2 ; //set force for U link Matrix* mom_ustar = mom+gauge_offset+GJP.VolNodeSites()*4; Matrix* mom_u = mom+gauge_offset; mom_u->Conj((double*)mom_ustar); } } } } // end for x,y,z,t } // end for mu //------------------------------------------------------------------ // deallocate smalloc'd space //------------------------------------------------------------------ VRB.Sfree(cname, fname, str_site_v2, site_v2) ; sfree(site_v2) ; VRB.Sfree(cname, fname, str_site_v1, site_v1) ; sfree(site_v1) ; VRB.Sfree(cname, fname, str_v2, v2) ; sfree(v2) ; VRB.Sfree(cname, fname, str_v1, v1) ; sfree(v1) ; } void GaugeTransformU(Matrix *gtrans, Lattice &lat){ Matrix recv_buf; Matrix tmp; //apply the gauge transformation to U for(int t=0;t1){ // if(!UniqueID()){ printf("Setting up doubled lattice. sizeof(Float) %d sizeof(IFloat) %d\n",sizeof(Float), sizeof(IFloat)); fflush(stdout); } // SingleToDoubleLattice lattdoubler(orig_gfield,double_latt); // lattdoubler.Run(gparity_X,gparity_Y); // if(!UniqueID()){ printf("Finished setting up doubled lattice\n"); fflush(stdout); } // }else{ // //only one node in X-direction // //copy data from orig_latt stored on this node // int pos[4]; // for(pos[0]=0;pos[0]1){ // SingleToDouble4dRNG fourDsetup; // SingleToDouble5dRNG fiveDsetup; // LRG.Reinitialize(); //reset the LRG and prepare for doubled lattice form // if(!UniqueID()){ printf("Setting up 4D RNG\n"); fflush(stdout); } // fourDsetup.Run(gparity_X,gparity_Y); // if(!UniqueID()){ printf("Setting up 5D RNG\n"); fflush(stdout); } // fiveDsetup.Run(gparity_X,gparity_Y); // }else{ // int n_rgen_4d = GJP.VolNodeSites()/16; //applies both to original and doubled latt // int n_rgen = n_rgen_4d; // if (GJP.SnodeSites()>=2) // n_rgen = GJP.VolNodeSites()*GJP.SnodeSites() / 32; // int stk_index_4d_off = n_rgen_4d/2; //offset for R' on 4D orig latt // int blocks_per_s_layer = n_rgen /( GJP.SnodeSites() / 2 ); //also same for original and doubled latt // int stk_index_5d_off = blocks_per_s_layer/2; //offset for R' on 5D orig latt // //copy the originals // UGrandomGenerator *ugran_4d_orig = new UGrandomGenerator[n_rgen_4d]; // for(int i=0;i=GJP.XnodeSites()/2){ // int orig_idx = (pos[0]-GJP.XnodeSites()/2)/2 + GJP.XnodeSites()/4*(pos[1]/2 + GJP.YnodeSites()/2*(pos[2]/2 + GJP.ZnodeSites()/2*pos[3]/2)) + stk_index_4d_off; // int new_idx = pos[0]/2 + GJP.XnodeSites()/2*(pos[1]/2 + GJP.YnodeSites()/2*(pos[2]/2 + GJP.ZnodeSites()/2*pos[3]/2)); // LRG.UGrandGen4D(new_idx) = ugran_4d_orig[orig_idx]; // }else{ // int orig_idx = pos[0]/2 + GJP.XnodeSites()/4*(pos[1]/2 + GJP.YnodeSites()/2*(pos[2]/2 + GJP.ZnodeSites()/2*pos[3]/2)); // int new_idx = pos[0]/2 + GJP.XnodeSites()/2*(pos[1]/2 + GJP.YnodeSites()/2*(pos[2]/2 + GJP.ZnodeSites()/2*pos[3]/2)); // LRG.UGrandGen4D(new_idx) = ugran_4d_orig[orig_idx]; // } // } // //do the 5D RNG // if(pos[0]>=GJP.XnodeSites()/2){ // int orig_idx = pos[4]/2*blocks_per_s_layer + (pos[0]-GJP.XnodeSites()/2)/2 + GJP.XnodeSites()/4*(pos[1]/2 + GJP.YnodeSites()/2*(pos[2]/2 + GJP.ZnodeSites()/2*pos[3]/2)) + stk_index_5d_off; // int new_idx = pos[4]/2*blocks_per_s_layer + pos[0]/2 + GJP.XnodeSites()/2*(pos[1]/2 + GJP.YnodeSites()/2*(pos[2]/2 + GJP.ZnodeSites()/2*pos[3]/2)); // LRG.UGrandGen(new_idx) = ugran_orig[orig_idx]; // }else{ // int orig_idx = pos[4]/2*blocks_per_s_layer + pos[0]/2 + GJP.XnodeSites()/4*(pos[1]/2 + GJP.YnodeSites()/2*(pos[2]/2 + GJP.ZnodeSites()/2*pos[3]/2)); // int new_idx = pos[4]/2*blocks_per_s_layer + pos[0]/2 + GJP.XnodeSites()/2*(pos[1]/2 + GJP.YnodeSites()/2*(pos[2]/2 + GJP.ZnodeSites()/2*pos[3]/2)); // LRG.UGrandGen(new_idx) = ugran_orig[orig_idx]; // } // } // } // } // } // } // delete[] ugran_4d_orig; // delete[] ugran_orig; // }//single node // }//gpx and gpy // }