#include #include //------------------------------------------------------------------ // // alg_threept.C // // AlgThreePt is derived from Alg and is relevant to // three point correlation functions with Wilson-type // fermions (i.e. Wilson, Clover, Dwf). // The type of fermion is determined by the argument to the // constructor but it should not be a non-Wilson-type lattice. // // PLEASE NOTE that the propagators passed to this method will // be altered to change propagators with periodic (P) and // antiperiodic (A) boundary conditions into P+A and P-A if // necessary. This is done so that extra memory isn't taken // up storing separate P+A and P-A propagators. //------------------------------------------------------------------ #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_QCDOCOS_SCU_CHECKSUM_H #include #endif CPS_START_NAMESPACE #ifdef PARALLEL CPS_END_NAMESPACE #include CPS_START_NAMESPACE #endif CPS_END_NAMESPACE //#include #include #include #include #include CPS_START_NAMESPACE // Sums a quantity over the whole lattice; 99 is a magic number. void lat_sum(Float *float_p, int block) {slice_sum(float_p,block,99);} // Assigns a pointer of type TYPE to PTR with enough memory allocated // for SIZE objects of that type. Prints error on fail. #define SMALLOC(PTR,TYPE,SIZE) PTR = (TYPE*)smalloc(SIZE*sizeof(TYPE)); \ if (PTR == 0) ERR.Pointer(cname,fname,#PTR); \ VRB.Smalloc(cname,fname,#PTR,PTR,SIZE); // Checkpoint function for timing. void chkpt(const int num_nodes,int& chkpoint_no,const Float dtime_start,Float& dtime_last,Float& dtime_now); #define FFLUSH(A) //------------------------------------------------------------------ /*! \param latt The lattice on which to compute the three-point function. \param c_arg The common argument structure for all algorithms. \param arg The parameters specific to this algorithm. */ //------------------------------------------------------------------ AlgThreePt::AlgThreePt(Lattice& latt, CommonArg *c_arg, ThreePtArg *arg, ThreePtPropArg *p_arg): Alg(latt,c_arg) { cname = "AlgThreePt"; char *fname = "AlgThreePt(L&,CommonArg*,ThreePtArg*,ThreePtPropArg*)"; VRB.Func(cname,fname); if (arg == 0) ERR.Pointer(cname,fname, "arg"); alg_threept_arg = arg; if (p_arg == 0) ERR.Pointer(cname,fname, "p_arg"); alg_threept_prop_arg = p_arg; VRB.Input(cname,fname, "stop_rsd = %g\n",IFloat (alg_threept_arg->cg.stop_rsd)); VRB.Input(cname,fname, "max_num_iter = %d\n", alg_threept_arg->cg.max_num_iter); VRB.Input(cname,fname, "mass = %g\n",IFloat (alg_threept_arg->cg.mass)); char tag[3][5] = {"SP","VA","TT"}; for (int i=0;i<3;i++) strcpy(gam[i],tag[i]); char tag2[3][5] = {"SS","VV","TT"}; for (int i=0;i<3;i++) strcpy(gam2[i],tag2[i]); char tag3[4][10] ={"TR_","TRTR_","TR_MX_","TRTR_MX_"}; for (int i=0;i<4;i++) strcpy(tra[i],tag3[i]); if (arg->results != 0) { if ((fp = Fopen((char*)arg->results, "w")) == NULL) { ERR.FileW(cname,fname,(char*)arg->results); } } Fprintf(fp,"Three-Point Code Version 4.9.20\nMASS= STRANGE LIGHT (PUPIL)\n"); FFLUSH(fp); if (arg->results_mres_ZA != 0) { if ((fp_mres_ZA = Fopen((char*)arg->results_mres_ZA, "w")) == NULL) { ERR.FileW(cname,fname,(char*)arg->results_mres_ZA); } } Fprintf(fp_mres_ZA,"Three-Point Code Version 4.9.20\nMASS= STRANGE LIGHT (PUPIL)\n"); FFLUSH(fp_mres_ZA); if (arg->results_pipi != 0) { if ((fp_pipi = Fopen((char*)arg->results_pipi, "w")) == NULL) { ERR.FileW(cname,fname,(char*)arg->results_pipi); } } Fprintf(fp_pipi,"Three-Point Code Version 4.9.20\nMASS= STRANGE LIGHT (PUPIL)\n"); FFLUSH(fp_pipi); } // Destructor //------------------------------------------------------------------ AlgThreePt::~AlgThreePt() { char *fname = "~AlgThreePt()"; VRB.Func(cname,fname); Fclose(fp); Fclose(fp_mres_ZA); Fclose(fp_pipi); } // Solves for propagators and combines them into matrix elements //------------------------------------------------------------------ void AlgThreePt::run() { //Initialize Timing Float dtime_start=dclock(); Float dtime_last=dtime_start; Float dtime_now=dtime_start; int chkpoint_no=0; int chkpoints = alg_threept_arg->chkpoints; const int num_nodes=GJP.Xnodes()*GJP.Ynodes()*GJP.Znodes()*GJP.Tnodes()*GJP.Snodes(); char *fname = "run()"; VRB.Func(cname,fname); VRB.Flow(cname,fname,"Starting AlgThreePt::run()\n"); //Checkpoint if (chkpoints) chkpt(num_nodes,chkpoint_no,dtime_start,dtime_last,dtime_now); int num_light = alg_threept_arg->num_light; int num_strange = alg_threept_arg->num_strange; int num_heavy = alg_threept_arg->num_heavy; int num_tK = alg_threept_arg->num_tK; int num_hits = alg_threept_arg->num_hits; do_susy = alg_threept_arg->do_susy; Float *l_mass = alg_threept_arg->l_mass; // light masses Float *s_mass = alg_threept_arg->s_mass; // strange masses Float *h_mass = alg_threept_arg->h_mass; // heavy masses (pupils only) int *tK = alg_threept_arg->tK; // times to put kaon sources int do_zero_mom = alg_threept_arg->do_zero_mom; int do_first_mom = alg_threept_arg->do_first_mom; int do_second_mom = alg_threept_arg->do_second_mom; int do_third_mom = alg_threept_arg->do_third_mom; int do_p_plus_a_kaon = alg_threept_arg->do_p_plus_a_kaon; int do_kaon_at_walls = alg_threept_arg->do_kaon_at_walls; int do_kaons_tK = alg_threept_arg->do_kaons_tK; Lattice& lat = AlgLattice(); QPropWArg qp_arg; qp_arg.cg = alg_threept_arg->cg; qp_arg.gauge_fix_src = TRUE; qp_arg.gauge_fix_snk = TRUE; qp_arg.save_prop = FALSE; // don't save propagators inside alg_threept qp_arg.x=0; qp_arg.y=0; qp_arg.z=0; qp_arg.store_midprop=0; qp_arg.save_ls_prop=0; qp_arg.do_half_fermion=0; qp_arg.ensemble_label=alg_threept_arg->ensemble_label; qp_arg.ensemble_id=alg_threept_arg->ensemble_id; qp_arg.seqNum=alg_threept_arg->seqNum; //Note that the figure8_spectator function (K->Pi Pi) is used in this version //of the code in a way that assumes t_src=0 and t_snk=time_size. int t_src = alg_threept_arg->t_src; // source location int t_snk = alg_threept_arg->t_snk; // sink location int t_shift = alg_threept_arg->t_shift; // amount to shift lattice if generating propagators int t_op = alg_threept_arg->t_op; // operator (& pupil) location int width = alg_threept_arg->width; // set spatial boundary conditions periodic GJP.Xbc(BND_CND_PRD); GJP.Ybc(BND_CND_PRD); GJP.Zbc(BND_CND_PRD); #ifdef HAVE_QCDOCOS_SCU_CHECKSUM_H if(!ScuChecksum::ChecksumsOn()) ScuChecksum::Initialise(true,true); #endif //NOTE: Propagators passed to this function will now be altered // to change P and A propagators into P+A and P-A so that // extra memory isn't need to store the P+A and P-A propagators. QPropW* q_light_tpi[num_light][2][4][3]; QPropW* q_light_tK[num_light][2][num_tK]; QPropW* q_strange_tpi[num_strange][2]; QPropW* q_strange_tK[num_strange][2][num_tK]; //Make these pointers point to the propagators passed via threept_prop_arg. for (int i=0; iq_light_tpi[i][bc][mom_num][mom_dir]; q_light_tpi[i][bc][mom_num][mom_dir]->ChangeSourceTime(t_src+(t_snk-t_src)*bc); } } //mom_num for loop if (do_kaons_tK) for (int j=0; jq_light_tK[i][bc][j]; q_light_tK[i][bc][j]->ChangeSourceTime(tK[j]); } } //bc for loop } //i for loop for (int i=0; iq_strange_tpi[i][bc]; q_strange_tpi[i][bc]->ChangeSourceTime(t_src+(t_snk-t_src)*bc); } } int bc_num=1+do_p_plus_a_kaon; for (int bc=0; bcq_strange_tK[i][bc][j]; q_strange_tK[i][bc][j]->ChangeSourceTime(tK[j]); } } } //Do P+A and P-A //Light quarks for (int m=0; mAverage(*q_light_tpi[m][1][0][0]); //q_light_tpi[m][0][0][0] is now (P+A)/2 q_light_tpi[m][1][0][0]->LinComb(*q_light_tpi[m][0][0][0],-1.0,1.0); //q_light_tpi[m][1][0][0] is now -A+(P+A)/2 = (P-A)/2 //Now do it for the non-zero momentum for (int mom_num=1; mom_num<4; mom_num++) { if (!do_first_mom && mom_num==1) continue; if (!do_second_mom && mom_num==2) continue; if (!do_third_mom && mom_num==3) continue; int n_dir; if (mom_num==3) n_dir=1; else n_dir=3; for (int mom_dir=0; mom_dirAverage(*q_light_tpi[m][1][mom_num][mom_dir]); //q_light_tpi[m][0][mom_num][mom_dir] is now (P+A)/2 q_light_tpi[m][1][mom_num][mom_dir]->LinComb(*q_light_tpi[m][0][mom_num][mom_dir],-1.0,1.0); //q_light_tpi[m][1][mom_num][mom_dir] is now -A+(P+A)/2 = (P-A)/2 } //mom_dir for loop } //mom_num for loop //tK light quarks if (do_kaons_tK) { for (int j=0; jAverage(*q_light_tK[m][1][j]); //q_light_tK[m][0][j] is now (P+A)/2 } } } //m (for loop, light quarks) //Light quarks for (int m=0; mAverage(*q_strange_tpi[m][1]); //q_strange_tpi[m][0] is now (P+A)/2 q_strange_tpi[m][1]->LinComb(*q_strange_tpi[m][0],-1.0,1.0); //q_strange_tpi[m][1] is now -A+(P+A)/2 = (P-A)/2 } //tK strange quarks if (do_p_plus_a_kaon) { for (int j=0; jAverage(*q_strange_tK[m][1][j]); //q_strange_tK[m][0][j] is now (P+A)/2 } } } //m (for loop, strange quarks) FFLUSH(fp_mres_ZA); /*---------------------------------------------------------------------------------- At this point q_light_tpi[m][0][mom_num][mom_dir] and q_strange_tpi[m][0] are "source" propagators (their sources are at t_src) and q_light_tpi[m][1][mom_num][mom_dir] and q_strange_tpi[m][1] are "sink" propagators (their sources are at t_snk). The q_strange_tK[m][0][src_num] have their sources at tK[src_num] and are P+A if the do_p_plus_a_kaon flag is turned on and are just P if this flag is turned off. Either way, DON'T use the q_strange_tK[m][1][src_num] anymore. The q_light_tK[m][0][src_num] have their sources at tK[src_num] and are P+A. DON'T use the q_light_tK[m][1][src_num] anymore. ----------------------------------------------------------------------------------*/ //Do Pi Pi correlators for all masses first. for (int m=0; mPiPi using the figure8_spectator function. //NOTE that the figure8_spectator function has been CHANGED from the original so that it works //for the specific way it is used in this version of the code (see note inside the function). //Kaon and pion at very left (t=t_src) and very right (t=t_snk) walls. //---------------------------------------------- figure8_spectator(*q_strange_tpi[m_s][0],*q_light_tpi[m_l][1][0][0],*q_light_tpi[m_l][1][0][0],*q_light_tpi[m_l][1][0][0],*q_light_tpi[m_l][1][0][0]); VRB.Flow(cname,fname,"Did figure8_spectator number 1, 0 momentum, m_s=%f, m_l=%f.\n",s_mass[m_s],l_mass[m_l]); //Checkpoint if (chkpoints) chkpt(num_nodes,chkpoint_no,dtime_start,dtime_last,dtime_now); //---------------------------------------------- figure8_spectator(*q_strange_tpi[m_s][1],*q_light_tpi[m_l][1][0][0],*q_light_tpi[m_l][0][0][0],*q_light_tpi[m_l][0][0][0],*q_light_tpi[m_l][0][0][0]); VRB.Flow(cname,fname,"Did figure8_spectator number 2, 0 momentum, m_s=%f, m_l=%f.\n",s_mass[m_s],l_mass[m_l]); //Checkpoint if (chkpoints) chkpt(num_nodes,chkpoint_no,dtime_start,dtime_last,dtime_now); } //do_kaon_at_walls if statement //Kaon correlator at tK[j] if (do_kaons_tK) { for (int j=0; jPiPi using figure8_spectator for non-zero momentum pions //q_snk1 and q_snk3 are d, q_snk2 and q_spc are u if (do_kaon_at_walls) { //Kaon and pion at very left (t=t_src) and very right (t=t_snk) walls. figure8_spectator(*q_strange_tpi[m_s][0],*q_light_tpi[m_l][1][0][0],*q_light_tpi[m_l][1][mom_num][mom_dir],*q_light_tpi[m_l][1][0][0],*q_light_tpi[m_l][1][mom_num][mom_dir],mom_num,mom_dir); figure8_spectator(*q_strange_tpi[m_s][1],*q_light_tpi[m_l][1][0][0],*q_light_tpi[m_l][0][mom_num][mom_dir],*q_light_tpi[m_l][0][0][0],*q_light_tpi[m_l][0][mom_num][mom_dir],mom_num,mom_dir); } //do_kaon_at_walls if statement VRB.Flow(cname,fname,"Did figure8_spectator at walls, momnum=%d, momdir=%d, m_s=%f, m_l=%f.\n",mom_num,mom_dir,s_mass[m_s],l_mass[m_l]); //Checkpoint if (chkpoints) chkpt(num_nodes,chkpoint_no,dtime_start,dtime_last,dtime_now); //Kaon at tK[j] and pion at left and right for (int j=0; jRun(); // manually activate inversion //---------------------------------------------------------------- for (int m_l=0; m_l and |p2,p1> even though they are the same by Bose symmetry). //n_comb=2^mom_num if not doing non-zero total momentum correlators, otherwise //n_comb=2^(2*mom_num)=(2^mom_num)^2 if (mom_num==1) n_comb=2; else if (mom_num==2) n_comb=4; else if (mom_num==3) n_comb=8; else ERR.General(cname,fname,"Input parameter mom_num must be 1, 2, or 3, but received mom_num=%d\n",mom_num); if (mom_dir<0 || mom_dir>2) ERR.General(cname,fname,"Input parameter mom_dir must be 0, 1, or 2, but received mom_dir=%d\n",mom_dir); if (alg_threept_arg->do_pipi_non_zero_tot_mom) n_comb=n_comb*n_comb; Rcomplex *tr[n_comb], *trtr[n_comb]; Rcomplex *tr_cos, *trtr_cos; //Cosine sink for (int i=0; ido_pipi_non_zero_tot_mom && (p_tot[0]!=0 || p_tot[1]!=0 || p_tot[2]!=0)) continue; WilsonMatrix tmp_qd_p1_h = q_d_mom.TwistMomSinkProp(t,p1); tmp_qd_p1_h.hconj(); WilsonMatrix tmp_qd_p2_h = q_d_mom.TwistMomSinkProp(t,p2); tmp_qd_p2_h.hconj(); tr[comb_num][t] += Trace(tmp_qu * tmp_qd_p1_h, tmp_qu * tmp_qd_p2_h); trtr[comb_num][t] += Trace(tmp_qu, tmp_qd_p1_h) * Trace(tmp_qu, tmp_qd_p2_h); //String to describe this momentum combination in the output sprintf(mom_string[comb_num],"p1=(%d,%d,%d)_p2=(%d,%d,%d)",p1[0],p1[1],p1[2],p2[0],p2[1],p2[2]); comb_num++; } //q2[2] for loop //end q1[i], q2[i] for loops if (comb_num!=n_comb) ERR.General(cname,fname,"Number of momentum combinations done incorrect for some reason.\nDid %d, should have done %d.\nmom_num=%d mom_dir=%d\n",comb_num,n_comb,mom_num,mom_dir); //Cosine sink //Use p with all non-zero entries equal to +1 (+/-1 doesn't matter for cosine sink). //This p was already calculated above for the mom_info string. WilsonMatrix tmp_qd_cos_h = q_d_mom.TwistCosSinkProp(t,p); tmp_qd_cos_h.hconj(); tr_cos[t] += Trace(tmp_qu * tmp_qd_cos_h, tmp_qu * tmp_qd_cos_h); trtr_cos[t] += Trace(tmp_qu, tmp_qd_cos_h) * Trace(tmp_qu, tmp_qd_cos_h); } // t for loop // Print out results //---------------------------------------------------------------- for (int comb_num=0; comb_num2) ERR.General(cname,fname,"bc must be 0, 1, or 2, received %d\n",bc); int t_src = q1_src.SourceTime(); int time_size=GJP.Tnodes()*GJP.TnodeSites(); Rcomplex *ps, *sc, *vc, *ax, *tn, *a0, *v0, *psax; SMALLOC(ps, Rcomplex,time_size); // pseudo SMALLOC(sc, Rcomplex,time_size); // scalar SMALLOC(vc, Rcomplex,time_size); // vector SMALLOC(ax, Rcomplex,time_size); // axial SMALLOC(tn, Rcomplex,time_size); // tensor SMALLOC(a0, Rcomplex,time_size); // axial-0 SMALLOC(v0, Rcomplex,time_size); // vector-0 SMALLOC(psax,Rcomplex,time_size); // pseudo-axial WilsonMatrix tmp_src; int t; for (t=0; tt_snk) sprintf(src_string,"A"); else if (bc==0 && t_src==alg_threept_arg->t_src) sprintf(src_string,"P"); else ERR.General(cname,fname,"Inconsistent bc and source time.\nt_src = %d , bc = %d\n",t_src,bc); } for (t=0; t2) ERR.General(cname,fname,"Input parameter mom_dir must be 0, 1, or 2, but received mom_dir=%d\n",mom_dir); Rcomplex *ps[n_mom], *sc[n_mom], *vc[n_mom], *ax[n_mom], *tn[n_mom], *a0[n_mom], *v0[n_mom], *psax[n_mom]; Rcomplex *ps_cos, *sc_cos, *vc_cos, *ax_cos, *tn_cos, *a0_cos, *v0_cos, *psax_cos; //Cosine sink for (int i=0; i2) ERR.General(cname,fname,"bc must be 0, 1, or 2, received %d\n",bc); int t_src = q1_src.SourceTime(); int t, time_size=GJP.Tnodes()*GJP.TnodeSites(); Rcomplex *ps, *psax; SMALLOC(ps,Rcomplex,time_size); // pseudo-pseudo SMALLOC(psax,Rcomplex,time_size); // pseudo-axial0 for (t=0; tt_snk) sprintf(src_string,"A"); else if (bc==0 && t_src==alg_threept_arg->t_src) sprintf(src_string,"P"); else ERR.General(cname,fname,"Inconsistent bc and source time.\nt_src = %d , bc = %d\n",t_src,bc); } for (t=0; t2) ERR.General(cname,fname,"Input parameter mom_dir must be 0, 1, or 2, but received mom_dir=%d\n",mom_dir); Rcomplex *ps[n_mom], *psax[n_mom]; Rcomplex *ps_cos, *psax_cos; //Cosine sink for (int i=0; i-1 && nu<3 && nu>-1 && mu<=nu) continue; gat = (nu<0?0:(mu<0?1:2)); if (!do_susy && gat!=1) continue; for (int i=0; ipi style)) //---------------------------------------------------------------- void AlgThreePt::figure8(QPropW& q_str, QPropW& q_src, QPropW& q_snk1, QPropW& q_snk2, int is_light) { char *fname = "figure8()"; VRB.Func(cname,fname); int gat, trt; int t_src = q_str.SourceTime(); int t_snk = q_snk1.SourceTime(); int t, time_size = GJP.Tnodes()*GJP.TnodeSites(); Rcomplex *oo[3][4], *pp[3][4]; for (gat=0;gat<3;gat++) for (trt=0;trt<4;trt++) { SMALLOC(oo[gat][trt],Rcomplex,time_size); SMALLOC(pp[gat][trt],Rcomplex,time_size); } WilsonMatrix tmp_str, tmp_snk; // strange, sink SpinMatrix spn_src, spn_snk; // source, sink Matrix col_src, col_snk; for (gat=0;gat<3;gat++) for (trt=0;trt<4;trt++) for (t=0;t-1 && nu<3 && nu>-1 && mu<=nu) continue; gat = (nu<0?0:(mu<0?1:2)); if (!do_susy && gat!=1) continue; for (int i=0; i=0 ? t_snk%time_size : (time_size+(t_snk%time_size))%time_size; // puts t_snk into the domain [0,time_size-1] using mod // special treatment is needed for t_snk<0 // this is needed for example because t_snk=time_size for // P-A t_displace = t_snk>=0 ? t_snk/time_size : (-t_snk-1)/time_size+1; // this is the number of domains that t_snk is away from // the fundamental domain [0,time_size-1] // it is >= 0 if ( t_displace%2 == 0 ) tmp_spc = q_spc.WallSinkProp(t_snk_mod); else { //If t_displace is odd then use the other propagator, //i.e. if q_spc is P+A then use P-A and vice versa. tmp_spc = q_snk.WallSinkProp(t_snk_mod); } int shift_t = GJP.TnodeCoor()*GJP.TnodeSites(); int vol = GJP.VolNodeSites()/GJP.TnodeSites(); for (int mu=-1; mu<4; mu++) { for (int nu=-1; nu<4; nu++) { if (mu<3 && mu>-1 && nu<3 && nu>-1 && mu<=nu) continue; gat = (nu<0?0:(mu<0?1:2)); if (!do_susy && gat!=1) continue; for (int i=0; iexplicit_src_snk && (t_snk<0 || t_snk>=time_size) ) ERR.General(cname,fname,"Source/sink time set to %d, should be between 0 and %d since explicit_src_snk is turned on.\n",t_snk,time_size); */ int t_snk_mod, t_displace; t_snk_mod = t_snk>=0 ? t_snk%time_size : (time_size+(t_snk%time_size))%time_size; // puts t_snk into the domain [0,time_size-1] using mod // special treatment is needed for t_snk<0 // this is needed for example because t_snk=time_size for // P-A t_displace = t_snk>=0 ? t_snk/time_size : (-t_snk-1)/time_size+1; // this is the number of domains that t_snk is away from // the fundamental domain [0,time_size-1] // it is >= 0 if ( t_displace%2 == 0 ) tmp_spc = q_spc.WallSinkProp(t_snk_mod); else { //If t_displace is odd then use the other propagator, //i.e. if q_spc is P+A then use P-A and vice versa. tmp_spc = q_snk1.WallSinkProp(t_snk_mod); } tmp_spc.gl(-5); // pion-quark int shift_t = GJP.TnodeCoor()*GJP.TnodeSites(); int vol = GJP.VolNodeSites()/GJP.TnodeSites(); for (int mu=-1; mu<4; mu++) { for (int nu=-1; nu<4; nu++) { if (mu>0 && nu>0 && mu<=nu) continue; gat = (nu<0?0:(mu<0?1:2)); if (!do_susy && gat!=1) continue; for (int i=0; i0 && t_src2) ERR.General(cname,fname,"Input parameter mom_dir must be 0, 1, or 2, but received mom_dir=%d\n",mom_dir); char mom_string[100]; int p[3]; for (int i=0; i<3; i++) p[i]=0; if (mom_num==0) sprintf(mom_string,""); else { if (mom_num==1) { p[mom_dir]=1; } else if (mom_num==2) { for (int mom_dir_tmp=0; mom_dir_tmp<3; mom_dir_tmp++) if (mom_dir_tmp!=mom_dir) p[mom_dir_tmp]=1; } else if (mom_num==3) { for (int i=0; i<3; i++) p[i]=1; } else { ERR.General(cname,fname,"Input parameter mom_num must be 0, 1, 2, or 3, but received mom_num=%d\n",mom_num); } sprintf(mom_string,"_Cos_p=(%d,%d,%d)",p[0],p[1],p[2]); } int gat, trt; Rcomplex *op[3][4], *po[3][4], *sd; for (gat=0;gat<3;gat++) for (trt=0;trt<4;trt++) { SMALLOC(op[gat][trt],Rcomplex,time_size); SMALLOC(po[gat][trt],Rcomplex,time_size); } SMALLOC(sd,Rcomplex,time_size); // strange-down insertion WilsonMatrix tmp_str, tmp_snk; // source, sink WilsonMatrix tmp_spc = (Float)0.0; // spectator SpinMatrix spn_eye, spn_vac; // eye, vacuum bubble Matrix col_eye, col_vac; for (gat=0;gat<3;gat++) for (trt=0;trt<4;trt++) for (t=0;t-1 && nu<3 && nu>-1 && mu<=nu) continue; gat = (nu<0?0:(mu<0?1:2)); if (!do_susy && gat!=1) continue; for (int i=0; i=0 ? t_snk%time_size : (time_size+(t_snk%time_size))%time_size; // puts t_snk into the domain [0,time_size-1] using mod // special treatment is needed for t_snk<0 // this is needed for example because t_snk=time_size for // P-A t_displace = t_snk>=0 ? t_snk/time_size : (-t_snk-1)/time_size+1; // this is the number of domains that t_snk is away from // the fundamental domain [0,time_size-1] // it is >= 0 if ( t_displace%2 == 0 ) tmp_vac = q_vac.WallSinkProp(t_snk_mod); else { //If t_displace is odd then use the other propagator, //i.e. if q_spc is P+A then use P-A and vice versa. tmp_vac = q_src.WallSinkProp(t_snk_mod); } tmp_vac.gl(-5); // pion-quark int shift_t = GJP.TnodeCoor()*GJP.TnodeSites(); int vol = GJP.VolNodeSites()/GJP.TnodeSites(); for (int mu=-1; mu<4; mu++) { for (int nu=-1; nu<4; nu++) { if (mu<3 && mu>-1 && nu<3 && nu>-1 && mu<=nu) continue; gat = (nu<0?0:(mu<0?1:2)); if (!do_susy && gat!=1) continue; for (int i=0; i=0 ? t_snk%time_size : (time_size+(t_snk%time_size))%time_size; // puts t_snk into the domain [0,time_size-1] using mod // special treatment is needed for t_snk<0 // this is needed for example because t_snk=time_size for // P-A t_displace = t_snk>=0 ? t_snk/time_size : (-t_snk-1)/time_size+1; // this is the number of domains that t_snk is away from // the fundamental domain [0,time_size-1] // it is >= 0 if ( t_displace%2 == 0 ) { tmp_spc = q_spc.WallSinkProp(t_snk_mod); tmp_vac = q_vac.WallSinkProp(t_snk_mod); } else { //If t_displace is odd then use the other propagator, //i.e. if q_spc is P+A then use P-A and vice versa. tmp_spc = q_vac.WallSinkProp(t_snk_mod); tmp_vac = q_spc.WallSinkProp(t_snk_mod); } tmp_vac.hconj(); // pion-antiquark-pion int shift_t = GJP.TnodeCoor()*GJP.TnodeSites(); int vol = GJP.VolNodeSites()/GJP.TnodeSites(); for (int mu=-1; mu<4; mu++) { for (int nu=-1; nu<4; nu++) { if (mu<3 && mu>-1 && nu<3 && nu>-1 && mu<=nu) continue; gat = (nu<0?0:(mu<0?1:2)); if (!do_susy && gat!=1) continue; for (int i=0; i