From a3ebafc4b4647b1af9d5ff31010a95cb0bc5018d Mon Sep 17 00:00:00 2001 From: simone-romiti Date: Tue, 23 May 2023 14:51:56 +0200 Subject: [PATCH 01/51] input file parameter for heavy meson correlators --- meas/measurements.h | 4 ++++ read_input.l | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/meas/measurements.h b/meas/measurements.h index 0f5d6d6ab..2852bfadf 100644 --- a/meas/measurements.h +++ b/meas/measurements.h @@ -70,6 +70,10 @@ typedef struct { void (*measurefunc) (const int traj, const int id, const int ieo); ExternalLibrary external_library; + + // measuring the 4x4 matrix of correlators in the 1+1 sector: https://arxiv.org/abs/1005.2042 + int measure_heavy_mesons = 0; // default: heavy mesons not measured + } measurement; diff --git a/read_input.l b/read_input.l index c4e8c0764..74864c80e 100644 --- a/read_input.l +++ b/read_input.l @@ -3038,6 +3038,14 @@ static inline double fltlist_next_token(int * const list_end){ meas->external_library = QUDA_LIB; if(myverbose) printf(" UseExternalLibrary set to quda in line %d, monomial %d\n", line_of_file, current_monomial); } + {SPC}*HeavyMesons{EQL}yes { + meas->measure_heavy_mesons = 1; + if(myverbose) printf(" HeavyMesons set to yes in line %d, monomial %d\n", line_of_file, current_monomial); + } + {SPC}*HeavyMesons{EQL}no { + meas->measure_heavy_mesons = 0; + if(myverbose) printf(" HeavyMesons set to no in line %d, monomial %d\n", line_of_file, current_monomial); + } } { From a4f19a344331c4bd78a11dd46633ab5d4e9e6a57 Mon Sep 17 00:00:00 2001 From: simone-romiti Date: Tue, 23 May 2023 18:17:03 +0200 Subject: [PATCH 02/51] light correlators use that mu==md, need for 2 separate functions --- meas/correlators.c | 18 +++++++++++++++++- meas/correlators.h | 15 +++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/meas/correlators.c b/meas/correlators.c index de7334edf..f05f91319 100644 --- a/meas/correlators.c +++ b/meas/correlators.c @@ -55,7 +55,7 @@ #define TM_OMEAS_FILENAME_LENGTH 100 -void correlators_measurement(const int traj, const int id, const int ieo) { +void light_correlators_measurement(const int traj, const int id, const int ieo) { tm_stopwatch_push(&g_timers, __func__, ""); int i, j, t, tt, t0; double *Cpp = NULL, *Cpa = NULL, *Cp4 = NULL; @@ -252,3 +252,19 @@ void correlators_measurement(const int traj, const int id, const int ieo) { tm_stopwatch_pop(&g_timers, 0, 1, ""); return; } + + +void heavy_quarks_correlators_measurement(const int traj, const int t0, const int ieo){ + // WRITE IMPLEMENTATION HERE !!! +} + + +void correlators_measurement(const int traj, const int id, const int ieo) { + + light_correlators_measurement(traj, id, ieo); + + if(measurement_list[id].measure_heavy_mesons == 1){ + heavy_correlators_measurement(traj, id, ieo); + } + +} diff --git a/meas/correlators.h b/meas/correlators.h index c9a1c4ac0..c3e3fc58c 100644 --- a/meas/correlators.h +++ b/meas/correlators.h @@ -21,6 +21,21 @@ #ifndef _ONLINE_MEASUREMENT_H #define _ONLINE_MEASUREMENT_H +/* measurement of the correlators involving the light doublet (see tmLQCD documentation)*/ +void light_quarks_correlators_measurement(const int traj, const int t0, const int ieo); + +/* [TO BE IMPLEMENTED !!!] + +measurement of the 4x4 matrix for the heavy doublet: eq. 20 of https://arxiv.org/pdf/1005.2042.pdf +*/ +void heavy_quarks_correlators_measurement(const int traj, const int t0, const int ieo); + + +/* + Function that is called when the correlator measurement is specified in the input file. + Internally, it calls the functions for the measure of the light and (optionally) the heavy mesons correlators + */ void correlators_measurement(const int traj, const int t0, const int ieo); + #endif From 6d12f7967d088d35aae4a2f5684977f166b1f26b Mon Sep 17 00:00:00 2001 From: simone-romiti Date: Tue, 13 Jun 2023 09:01:40 +0200 Subject: [PATCH 03/51] code skeleton for the onlinemeas of the heavy mesons correlators --- meas/correlators.c | 210 ++++++++++++++++++++++++++++++++++++++++++++- meas/correlators.h | 4 +- 2 files changed, 208 insertions(+), 6 deletions(-) diff --git a/meas/correlators.c b/meas/correlators.c index f05f91319..e5ddb1362 100644 --- a/meas/correlators.c +++ b/meas/correlators.c @@ -40,6 +40,9 @@ #include "gettime.h" + +#define TM_OMEAS_FILENAME_LENGTH 100 + /****************************************************** * * This routine computes the correlators @@ -52,9 +55,6 @@ * * ******************************************************/ - -#define TM_OMEAS_FILENAME_LENGTH 100 - void light_correlators_measurement(const int traj, const int id, const int ieo) { tm_stopwatch_push(&g_timers, __func__, ""); int i, j, t, tt, t0; @@ -254,8 +254,210 @@ void light_correlators_measurement(const int traj, const int id, const int ieo) } +/****************************************************** + * + * This routine computes the correlator matrix (), + * where G1 and G2 are 2 gamma matrices from the set {1, gamma5} --> {S,P} (scalar and pseudoscalar current), + * , , for all the choices of h1 and h2 (see eq. 18 and 20 of https://arxiv.org/pdf/1005.2042.pdf) + * + * + ******************************************************/ void heavy_quarks_correlators_measurement(const int traj, const int t0, const int ieo){ - // WRITE IMPLEMENTATION HERE !!! + tm_stopwatch_push(&g_timers, __func__, ""); + int i, j, t, tt, t0; + double *Cpp = NULL, *Cpa = NULL, *Cp4 = NULL; + double res = 0., respa = 0., resp4 = 0.; + double atime, etime; + float tmp; + operator * optr1, optr2; +#ifdef TM_USE_MPI + double mpi_res = 0., mpi_respa = 0., mpi_resp4 = 0.; + // send buffer for MPI_Gather + double *sCpp = NULL, *sCpa = NULL, *sCp4 = NULL; +#endif + FILE *ofs; + char filename[TM_OMEAS_FILENAME_LENGTH]; + spinor phi; + + init_operators(); + if(no_operators < 1) { + if(g_proc_id == 0) { + fprintf(stderr, "Warning! no operators defined in input file, cannot perform online correlator mesurements!\n"); + } + tm_stopwatch_pop(&g_timers, 0, 0, ""); + return; + } + if(no_operators > 1 && g_proc_id == 0) { + fprintf(stderr, "Warning! number of operators defined larger than 1, using only the first!\n"); + } + optr = &operator_list[0]; + // we don't want to do inversion twice for this purpose here + optr->DownProp = 0; + if(optr->type != TMWILSON && optr->type != WILSON && optr->type != CLOVER) { + if(g_proc_id == 0) { + fprintf(stderr, "Warning! correlator online measurement currently only implemented for TMWILSON, WILSON and CLOVER\n"); + fprintf(stderr, "Cannot perform correlator online measurement!\n"); + } + tm_stopwatch_pop(&g_timers, 0, 0, ""); + return; + } + + if(ranlxs_init == 0) { + rlxs_init(1, 123456); + } + + // there are three modes of operation + // 1) one single time-slice source (default) + // 2) no_samples time-slice sources on random time-slices + // 3) one sample on all time-slices + int max_samples = measurement_list[id].all_time_slices ? 1 : measurement_list[id].no_samples; + int max_time_slices = measurement_list[id].all_time_slices ? measurement_list[id].max_source_slice : 1; + for(int sample = 0; sample < max_samples; sample++ ){ + for(int ts = 0; ts < max_time_slices; ts++){ + + if( max_samples == 1 && max_time_slices == 1 ){ + snprintf(filename, TM_OMEAS_FILENAME_LENGTH, + "%s%06d", "onlinemeas." ,traj); + } else if ( max_samples == 1 && max_time_slices > 1){ + snprintf(filename, TM_OMEAS_FILENAME_LENGTH, + "%s.t%03d.%06d", "onlinemeas", ts, traj ); + } else { + snprintf(filename, TM_OMEAS_FILENAME_LENGTH, + "%s.s%03d.%06d", "onlinemeas", sample, traj); + } + /* generate random timeslice */ + t0 = ts; + if( !measurement_list[id].all_time_slices ){ + ranlxs(&tmp, 1); + t0 = (int)(measurement_list[id].max_source_slice*tmp); + } +#ifdef TM_USE_MPI + MPI_Bcast(&t0, 1, MPI_INT, 0, MPI_COMM_WORLD); +#endif + if(g_debug_level > 1 && g_proc_id == 0) { + printf("# timeslice set to %d (T=%d) for online measurement\n", t0, g_nproc_t*T); + printf("# online measurements parameters: kappa = %.12f, mu = %.12f\n", optr->kappa, optr->mu/2./optr->kappa); + } + //atime = gettime(); + +#ifdef TM_USE_MPI + sCpp = (double*) calloc(T, sizeof(double)); + sCpa = (double*) calloc(T, sizeof(double)); + sCp4 = (double*) calloc(T, sizeof(double)); + if(g_mpi_time_rank == 0) { + Cpp = (double*) calloc(g_nproc_t*T, sizeof(double)); + Cpa = (double*) calloc(g_nproc_t*T, sizeof(double)); + Cp4 = (double*) calloc(g_nproc_t*T, sizeof(double)); + } +#else + Cpp = (double*) calloc(T, sizeof(double)); + Cpa = (double*) calloc(T, sizeof(double)); + Cp4 = (double*) calloc(T, sizeof(double)); +#endif + source_generation_pion_only(g_spinor_field[0], g_spinor_field[1], + t0, sample, traj, measurement_list[id].seed); + optr->sr0 = g_spinor_field[0]; + optr->sr1 = g_spinor_field[1]; + optr->prop0 = g_spinor_field[2]; + optr->prop1 = g_spinor_field[3]; + + // op_id = 0, index_start = 0, write_prop = 0 + optr->inverter(0, 0, 0); + + /* now we bring it to normal format */ + /* here we use implicitly DUM_MATRIX and DUM_MATRIX+1 */ + convert_eo_to_lexic(g_spinor_field[DUM_MATRIX], g_spinor_field[2], g_spinor_field[3]); + + /* now we sum only over local space for every t */ + for(t = 0; t < T; t++) { + j = g_ipt[t][0][0][0]; + res = 0.; + respa = 0.; + resp4 = 0.; + for(i = j; i < j+LX*LY*LZ; i++) { + res += _spinor_prod_re(g_spinor_field[DUM_MATRIX][i], g_spinor_field[DUM_MATRIX][i]); + _gamma0(phi, g_spinor_field[DUM_MATRIX][i]); + respa += _spinor_prod_re(g_spinor_field[DUM_MATRIX][i], phi); + _gamma5(phi, phi); + resp4 += _spinor_prod_im(g_spinor_field[DUM_MATRIX][i], phi); + } + +#if defined TM_USE_MPI + MPI_Reduce(&res, &mpi_res, 1, MPI_DOUBLE, MPI_SUM, 0, g_mpi_time_slices); + res = mpi_res; + MPI_Reduce(&respa, &mpi_respa, 1, MPI_DOUBLE, MPI_SUM, 0, g_mpi_time_slices); + respa = mpi_respa; + MPI_Reduce(&resp4, &mpi_resp4, 1, MPI_DOUBLE, MPI_SUM, 0, g_mpi_time_slices); + resp4 = mpi_resp4; + sCpp[t] = +res/(g_nproc_x*LX)/(g_nproc_y*LY)/(g_nproc_z*LZ)/2./optr->kappa/optr->kappa; + sCpa[t] = -respa/(g_nproc_x*LX)/(g_nproc_y*LY)/(g_nproc_z*LZ)/2./optr->kappa/optr->kappa; + sCp4[t] = +resp4/(g_nproc_x*LX)/(g_nproc_y*LY)/(g_nproc_z*LZ)/2./optr->kappa/optr->kappa; +#else + Cpp[t] = +res/(g_nproc_x*LX)/(g_nproc_y*LY)/(g_nproc_z*LZ)/2./optr->kappa/optr->kappa; + Cpa[t] = -respa/(g_nproc_x*LX)/(g_nproc_y*LY)/(g_nproc_z*LZ)/2./optr->kappa/optr->kappa; + Cp4[t] = +resp4/(g_nproc_x*LX)/(g_nproc_y*LY)/(g_nproc_z*LZ)/2./optr->kappa/optr->kappa; +#endif + } + +#ifdef TM_USE_MPI + /* some gymnastics needed in case of parallelisation */ + if(g_mpi_time_rank == 0) { + MPI_Gather(sCpp, T, MPI_DOUBLE, Cpp, T, MPI_DOUBLE, 0, g_mpi_SV_slices); + MPI_Gather(sCpa, T, MPI_DOUBLE, Cpa, T, MPI_DOUBLE, 0, g_mpi_SV_slices); + MPI_Gather(sCp4, T, MPI_DOUBLE, Cp4, T, MPI_DOUBLE, 0, g_mpi_SV_slices); + } +#endif + + /* and write everything into a file */ + if(g_mpi_time_rank == 0 && g_proc_coords[0] == 0) { + ofs = fopen(filename, "w"); + fprintf( ofs, "1 1 0 %e %e\n", Cpp[t0], 0.); + for(t = 1; t < g_nproc_t*T/2; t++) { + tt = (t0+t)%(g_nproc_t*T); + fprintf( ofs, "1 1 %d %e ", t, Cpp[tt]); + tt = (t0+g_nproc_t*T-t)%(g_nproc_t*T); + fprintf( ofs, "%e\n", Cpp[tt]); + } + tt = (t0+g_nproc_t*T/2)%(g_nproc_t*T); + fprintf( ofs, "1 1 %d %e %e\n", t, Cpp[tt], 0.); + + fprintf( ofs, "2 1 0 %e %e\n", Cpa[t0], 0.); + for(t = 1; t < g_nproc_t*T/2; t++) { + tt = (t0+t)%(g_nproc_t*T); + fprintf( ofs, "2 1 %d %e ", t, Cpa[tt]); + tt = (t0+g_nproc_t*T-t)%(g_nproc_t*T); + fprintf( ofs, "%e\n", Cpa[tt]); + } + tt = (t0+g_nproc_t*T/2)%(g_nproc_t*T); + fprintf( ofs, "2 1 %d %e %e\n", t, Cpa[tt], 0.); + + fprintf( ofs, "6 1 0 %e %e\n", Cp4[t0], 0.); + for(t = 1; t < g_nproc_t*T/2; t++) { + tt = (t0+t)%(g_nproc_t*T); + fprintf( ofs, "6 1 %d %e ", t, Cp4[tt]); + tt = (t0+g_nproc_t*T-t)%(g_nproc_t*T); + fprintf( ofs, "%e\n", Cp4[tt]); + } + tt = (t0+g_nproc_t*T/2)%(g_nproc_t*T); + fprintf( ofs, "6 1 %d %e %e\n", t, Cp4[tt], 0.); + fclose(ofs); + } +#ifdef TM_USE_MPI + if(g_mpi_time_rank == 0) { + free(Cpp); free(Cpa); free(Cp4); + } + free(sCpp); free(sCpa); free(sCp4); +#else + free(Cpp); free(Cpa); free(Cp4); +#endif + } // for(max_time_slices) + } // for(max_samples) + //etime = gettime(); + //if(g_proc_id == 0 && g_debug_level > 0) { + // printf("ONLINE: measurement done int t/s = %1.4e\n", etime - atime); + //} + tm_stopwatch_pop(&g_timers, 0, 1, ""); + return; } diff --git a/meas/correlators.h b/meas/correlators.h index c3e3fc58c..7db749fe8 100644 --- a/meas/correlators.h +++ b/meas/correlators.h @@ -24,8 +24,8 @@ /* measurement of the correlators involving the light doublet (see tmLQCD documentation)*/ void light_quarks_correlators_measurement(const int traj, const int t0, const int ieo); -/* [TO BE IMPLEMENTED !!!] - +/* +[TO BE IMPLEMENTED !!!] measurement of the 4x4 matrix for the heavy doublet: eq. 20 of https://arxiv.org/pdf/1005.2042.pdf */ void heavy_quarks_correlators_measurement(const int traj, const int t0, const int ieo); From 558dd270f7316e4a806956270a28e036a1d2c326 Mon Sep 17 00:00:00 2001 From: simone-romiti Date: Tue, 13 Jun 2023 11:18:23 +0200 Subject: [PATCH 04/51] first draft version: computing only one correlator for now --- meas/correlators.c | 297 ++++++++++++++++++++++++--------------------- meas/correlators.h | 6 +- 2 files changed, 160 insertions(+), 143 deletions(-) diff --git a/meas/correlators.c b/meas/correlators.c index e5ddb1362..552e8a346 100644 --- a/meas/correlators.c +++ b/meas/correlators.c @@ -253,57 +253,63 @@ void light_correlators_measurement(const int traj, const int id, const int ieo) return; } - /****************************************************** * * This routine computes the correlator matrix (), - * where G1 and G2 are 2 gamma matrices from the set {1, gamma5} --> {S,P} (scalar and pseudoscalar current), - * , , for all the choices of h1 and h2 (see eq. 18 and 20 of https://arxiv.org/pdf/1005.2042.pdf) - * + * where G1 and G2 are 2 gamma matrices from the set {1, gamma5} --> {S,P} (scalar and pseudoscalar + *current), , , for all the choices of h1 and h2 (see eq. 18 and 20 of + *https://arxiv.org/pdf/1005.2042.pdf) + * + * i1, i2 = source and sink operator indices from the list of the operators in the input file. + * * ******************************************************/ -void heavy_quarks_correlators_measurement(const int traj, const int t0, const int ieo){ - tm_stopwatch_push(&g_timers, __func__, ""); - int i, j, t, tt, t0; - double *Cpp = NULL, *Cpa = NULL, *Cp4 = NULL; - double res = 0., respa = 0., resp4 = 0.; - double atime, etime; - float tmp; - operator * optr1, optr2; +void heavy_quarks_correlators_measurement(const int traj, const int t0, const int ieo, const int i1, + const int i2) { + tm_stopwatch_push(&g_timers, __func__, ""); // timer for profiling + int i, j, t, tt, t0; // dummy indices + double *Cpp = NULL; // array of the values of the correlator C(t) + double res = 0.; // result of the accumulation of MPI partial sums + float tmp; // dummy variable + operator* optr1; // pointer to the operator (see some lines later) #ifdef TM_USE_MPI double mpi_res = 0., mpi_respa = 0., mpi_resp4 = 0.; // send buffer for MPI_Gather - double *sCpp = NULL, *sCpa = NULL, *sCp4 = NULL; + double *sCpp = NULL; //, *sCpa = NULL, *sCp4 = NULL; #endif - FILE *ofs; - char filename[TM_OMEAS_FILENAME_LENGTH]; - spinor phi; - - init_operators(); - if(no_operators < 1) { - if(g_proc_id == 0) { - fprintf(stderr, "Warning! no operators defined in input file, cannot perform online correlator mesurements!\n"); + FILE *ofs; // output file stream + char filename[TM_OMEAS_FILENAME_LENGTH]; // file path + spinor phi; // full spinor of 4 components (we use the spin dilution) + + init_operators(); // initialize the operators in the action (if not already done) + if (no_operators < 1) { + if (g_proc_id == 0) { + // we don't want the simulation to stop, we can do the measurements offline afterwards + fprintf(stderr, + "Warning! no operators defined in input file, cannot perform online correlator " + "mesurements!\n"); } - tm_stopwatch_pop(&g_timers, 0, 0, ""); + tm_stopwatch_pop(&g_timers, 0, 0, ""); // timer for profiling return; } - if(no_operators > 1 && g_proc_id == 0) { - fprintf(stderr, "Warning! number of operators defined larger than 1, using only the first!\n"); - } - optr = &operator_list[0]; - // we don't want to do inversion twice for this purpose here - optr->DownProp = 0; - if(optr->type != TMWILSON && optr->type != WILSON && optr->type != CLOVER) { - if(g_proc_id == 0) { - fprintf(stderr, "Warning! correlator online measurement currently only implemented for TMWILSON, WILSON and CLOVER\n"); + + // selecting the operators i1 and i2 from the list of operators initialized before + optr1 = &operator_list[i1]; + + bool b1 = (optr1->type != DBTMWILSON && optr1->type != DBCLOVER); + if (b1) { + if (g_proc_id == 0) { + fprintf(stderr, + "Warning! correlator online measurement currently only implemented for DBTMWILSON, " + "DBCLOVER\n"); fprintf(stderr, "Cannot perform correlator online measurement!\n"); } - tm_stopwatch_pop(&g_timers, 0, 0, ""); + tm_stopwatch_pop(&g_timers, 0, 0, ""); // timer for profiling return; } - - if(ranlxs_init == 0) { - rlxs_init(1, 123456); + + if (ranlxs_init == 0) { + rlxs_init(1, 123456); // initializing random number generator RANLUX } // there are three modes of operation @@ -311,162 +317,177 @@ void heavy_quarks_correlators_measurement(const int traj, const int t0, const in // 2) no_samples time-slice sources on random time-slices // 3) one sample on all time-slices int max_samples = measurement_list[id].all_time_slices ? 1 : measurement_list[id].no_samples; - int max_time_slices = measurement_list[id].all_time_slices ? measurement_list[id].max_source_slice : 1; - for(int sample = 0; sample < max_samples; sample++ ){ - for(int ts = 0; ts < max_time_slices; ts++){ - - if( max_samples == 1 && max_time_slices == 1 ){ - snprintf(filename, TM_OMEAS_FILENAME_LENGTH, - "%s%06d", "onlinemeas." ,traj); - } else if ( max_samples == 1 && max_time_slices > 1){ - snprintf(filename, TM_OMEAS_FILENAME_LENGTH, - "%s.t%03d.%06d", "onlinemeas", ts, traj ); + int max_time_slices = + measurement_list[id].all_time_slices ? measurement_list[id].max_source_slice : 1; + for (int sample = 0; sample < max_samples; sample++) { + for (int ts = 0; ts < max_time_slices; ts++) { + // setting output filename + if (max_samples == 1 && max_time_slices == 1) { + snprintf(filename, TM_OMEAS_FILENAME_LENGTH, "%s%06d", "heavy_mesons.", traj); + } else if (max_samples == 1 && max_time_slices > 1) { + snprintf(filename, TM_OMEAS_FILENAME_LENGTH, "%s.t%03d.%06d", "heavy_mesons", ts, traj); } else { - snprintf(filename, TM_OMEAS_FILENAME_LENGTH, - "%s.s%03d.%06d", "onlinemeas", sample, traj); + snprintf(filename, TM_OMEAS_FILENAME_LENGTH, "%s.s%03d.%06d", "heavy_mesons", sample, traj); } + /* generate random timeslice */ t0 = ts; - if( !measurement_list[id].all_time_slices ){ + if (!measurement_list[id].all_time_slices) { ranlxs(&tmp, 1); - t0 = (int)(measurement_list[id].max_source_slice*tmp); + t0 = (int)(measurement_list[id].max_source_slice * tmp); } #ifdef TM_USE_MPI - MPI_Bcast(&t0, 1, MPI_INT, 0, MPI_COMM_WORLD); + MPI_Bcast(&t0, 1, MPI_INT, 0, MPI_COMM_WORLD); // broadcast t0 to all the ranks #endif - if(g_debug_level > 1 && g_proc_id == 0) { - printf("# timeslice set to %d (T=%d) for online measurement\n", t0, g_nproc_t*T); - printf("# online measurements parameters: kappa = %.12f, mu = %.12f\n", optr->kappa, optr->mu/2./optr->kappa); + if (g_debug_level > 1 && g_proc_id == 0) { + printf("# timeslice set to %d (T=%d) for online measurement\n", t0, g_nproc_t * T); + printf("# online measurements parameters: kappa = %.12f, mubar = %.12f, epsbar = %.12f\n", + optr1->kappa, optr1->mubar, optr1->epsbar); } - //atime = gettime(); #ifdef TM_USE_MPI - sCpp = (double*) calloc(T, sizeof(double)); - sCpa = (double*) calloc(T, sizeof(double)); - sCp4 = (double*) calloc(T, sizeof(double)); - if(g_mpi_time_rank == 0) { - Cpp = (double*) calloc(g_nproc_t*T, sizeof(double)); - Cpa = (double*) calloc(g_nproc_t*T, sizeof(double)); - Cp4 = (double*) calloc(g_nproc_t*T, sizeof(double)); + sCpp = (double *)calloc(T, sizeof(double)); + // sCpa = (double*) calloc(T, sizeof(double)); + // sCp4 = (double*) calloc(T, sizeof(double)); + if (g_mpi_time_rank == 0) { + Cpp = (double *)calloc(g_nproc_t * T, sizeof(double)); + // Cpa = (double*) calloc(g_nproc_t*T, sizeof(double)); + // Cp4 = (double*) calloc(g_nproc_t*T, sizeof(double)); } #else - Cpp = (double*) calloc(T, sizeof(double)); - Cpa = (double*) calloc(T, sizeof(double)); - Cp4 = (double*) calloc(T, sizeof(double)); + Cpp = (double *)calloc(T, sizeof(double)); + // Cpa = (double*) calloc(T, sizeof(double)); + // Cp4 = (double*) calloc(T, sizeof(double)); #endif - source_generation_pion_only(g_spinor_field[0], g_spinor_field[1], - t0, sample, traj, measurement_list[id].seed); - optr->sr0 = g_spinor_field[0]; - optr->sr1 = g_spinor_field[1]; - optr->prop0 = g_spinor_field[2]; - optr->prop1 = g_spinor_field[3]; + source_generation_pion_only(g_spinor_field[0], g_spinor_field[1], t0, sample, traj, + measurement_list[id].seed); + + spinor *up_spinors = &g_bispinor_field[0][0]; + spinor *down_spinors = &g_bispinor_field[0][1]; + // sources + optr1->sr0 = up_spinors[0]; + optr1->sr1 = up_spinors[1]; + optr1->sr2 = down_spinors[0]; + optr1->sr3 = down_spinors[1]; + // propagators, i.e. D^{-1}*eta (eta = stochastic vector for the inversion) + optr1->prop0 = up_spinors[2]; + optr1->prop1 = up_spinors[3]; + optr1->prop2 = down_spinors[2]; + optr1->prop3 = down_spinors[3]; + + // even-odd sites for the down + // sources + optr1->sr2 = g_bispinor_field[1][0]; + optr1->sr3 = g_bispinor_field[1][1]; + // propagators, i.e. D^{-1}*eta (eta = stochastic vector for the inversion) + optr1->prop2 = g_bispinor_field[1][2]; + optr1->prop3 = g_bispinor_field[1][3]; // op_id = 0, index_start = 0, write_prop = 0 - optr->inverter(0, 0, 0); + optr1->inverter(i1, 0, 0); /* now we bring it to normal format */ /* here we use implicitly DUM_MATRIX and DUM_MATRIX+1 */ - convert_eo_to_lexic(g_spinor_field[DUM_MATRIX], g_spinor_field[2], g_spinor_field[3]); - + convert_eo_to_lexic(down_spinors[DUM_MATRIX], down_spinors[2], down_spinors[3]); + convert_eo_to_lexic(down_spinors[DUM_MATRIX], down_spinors[2], down_spinors[3]); + /* now we sum only over local space for every t */ - for(t = 0; t < T; t++) { + for (t = 0; t < T; t++) { j = g_ipt[t][0][0][0]; res = 0.; - respa = 0.; - resp4 = 0.; - for(i = j; i < j+LX*LY*LZ; i++) { - res += _spinor_prod_re(g_spinor_field[DUM_MATRIX][i], g_spinor_field[DUM_MATRIX][i]); - _gamma0(phi, g_spinor_field[DUM_MATRIX][i]); - respa += _spinor_prod_re(g_spinor_field[DUM_MATRIX][i], phi); - _gamma5(phi, phi); - resp4 += _spinor_prod_im(g_spinor_field[DUM_MATRIX][i], phi); + // respa = 0.; + // resp4 = 0.; + for (i = j; i < j + LX * LY * LZ; i++) { + res += _spinor_prod_re(up_spinors[DUM_MATRIX][i], up_spinors[DUM_MATRIX][i]); + // _gamma0(phi, g_spinor_field[DUM_MATRIX][i]); + // respa += _spinor_prod_re(g_spinor_field[DUM_MATRIX][i], phi); + // _gamma5(phi, phi); + // resp4 += _spinor_prod_im(g_spinor_field[DUM_MATRIX][i], phi); } #if defined TM_USE_MPI MPI_Reduce(&res, &mpi_res, 1, MPI_DOUBLE, MPI_SUM, 0, g_mpi_time_slices); res = mpi_res; - MPI_Reduce(&respa, &mpi_respa, 1, MPI_DOUBLE, MPI_SUM, 0, g_mpi_time_slices); - respa = mpi_respa; - MPI_Reduce(&resp4, &mpi_resp4, 1, MPI_DOUBLE, MPI_SUM, 0, g_mpi_time_slices); - resp4 = mpi_resp4; - sCpp[t] = +res/(g_nproc_x*LX)/(g_nproc_y*LY)/(g_nproc_z*LZ)/2./optr->kappa/optr->kappa; - sCpa[t] = -respa/(g_nproc_x*LX)/(g_nproc_y*LY)/(g_nproc_z*LZ)/2./optr->kappa/optr->kappa; - sCp4[t] = +resp4/(g_nproc_x*LX)/(g_nproc_y*LY)/(g_nproc_z*LZ)/2./optr->kappa/optr->kappa; + // MPI_Reduce(&respa, &mpi_respa, 1, MPI_DOUBLE, MPI_SUM, 0, g_mpi_time_slices); + // respa = mpi_respa; + // MPI_Reduce(&resp4, &mpi_resp4, 1, MPI_DOUBLE, MPI_SUM, 0, g_mpi_time_slices); + // resp4 = mpi_resp4; + sCpp[t] = +res / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ) / 2. / optr->kappa / + optr->kappa; + // sCpa[t] = -respa/(g_nproc_x*LX)/(g_nproc_y*LY)/(g_nproc_z*LZ)/2./optr->kappa/optr->kappa; + // sCp4[t] = +resp4/(g_nproc_x*LX)/(g_nproc_y*LY)/(g_nproc_z*LZ)/2./optr->kappa/optr->kappa; #else - Cpp[t] = +res/(g_nproc_x*LX)/(g_nproc_y*LY)/(g_nproc_z*LZ)/2./optr->kappa/optr->kappa; - Cpa[t] = -respa/(g_nproc_x*LX)/(g_nproc_y*LY)/(g_nproc_z*LZ)/2./optr->kappa/optr->kappa; - Cp4[t] = +resp4/(g_nproc_x*LX)/(g_nproc_y*LY)/(g_nproc_z*LZ)/2./optr->kappa/optr->kappa; + Cpp[t] = +res / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ) / 2. / optr->kappa / + optr->kappa; + // Cpa[t] = -respa/(g_nproc_x*LX)/(g_nproc_y*LY)/(g_nproc_z*LZ)/2./optr->kappa/optr->kappa; + // Cp4[t] = +resp4/(g_nproc_x*LX)/(g_nproc_y*LY)/(g_nproc_z*LZ)/2./optr->kappa/optr->kappa; #endif } #ifdef TM_USE_MPI /* some gymnastics needed in case of parallelisation */ - if(g_mpi_time_rank == 0) { + if (g_mpi_time_rank == 0) { MPI_Gather(sCpp, T, MPI_DOUBLE, Cpp, T, MPI_DOUBLE, 0, g_mpi_SV_slices); - MPI_Gather(sCpa, T, MPI_DOUBLE, Cpa, T, MPI_DOUBLE, 0, g_mpi_SV_slices); - MPI_Gather(sCp4, T, MPI_DOUBLE, Cp4, T, MPI_DOUBLE, 0, g_mpi_SV_slices); + // MPI_Gather(sCpa, T, MPI_DOUBLE, Cpa, T, MPI_DOUBLE, 0, g_mpi_SV_slices); + // MPI_Gather(sCp4, T, MPI_DOUBLE, Cp4, T, MPI_DOUBLE, 0, g_mpi_SV_slices); } #endif /* and write everything into a file */ - if(g_mpi_time_rank == 0 && g_proc_coords[0] == 0) { + if (g_mpi_time_rank == 0 && g_proc_coords[0] == 0) { ofs = fopen(filename, "w"); - fprintf( ofs, "1 1 0 %e %e\n", Cpp[t0], 0.); - for(t = 1; t < g_nproc_t*T/2; t++) { - tt = (t0+t)%(g_nproc_t*T); - fprintf( ofs, "1 1 %d %e ", t, Cpp[tt]); - tt = (t0+g_nproc_t*T-t)%(g_nproc_t*T); - fprintf( ofs, "%e\n", Cpp[tt]); + fprintf(ofs, "1 1 0 %e %e\n", Cpp[t0], 0.); + for (t = 1; t < g_nproc_t * T / 2; t++) { + tt = (t0 + t) % (g_nproc_t * T); + fprintf(ofs, "1 1 %d %e ", t, Cpp[tt]); + tt = (t0 + g_nproc_t * T - t) % (g_nproc_t * T); + fprintf(ofs, "%e\n", Cpp[tt]); } - tt = (t0+g_nproc_t*T/2)%(g_nproc_t*T); - fprintf( ofs, "1 1 %d %e %e\n", t, Cpp[tt], 0.); - - fprintf( ofs, "2 1 0 %e %e\n", Cpa[t0], 0.); - for(t = 1; t < g_nproc_t*T/2; t++) { - tt = (t0+t)%(g_nproc_t*T); - fprintf( ofs, "2 1 %d %e ", t, Cpa[tt]); - tt = (t0+g_nproc_t*T-t)%(g_nproc_t*T); - fprintf( ofs, "%e\n", Cpa[tt]); - } - tt = (t0+g_nproc_t*T/2)%(g_nproc_t*T); - fprintf( ofs, "2 1 %d %e %e\n", t, Cpa[tt], 0.); + tt = (t0 + g_nproc_t * T / 2) % (g_nproc_t * T); + fprintf(ofs, "1 1 %d %e %e\n", t, Cpp[tt], 0.); + + // fprintf( ofs, "2 1 0 %e %e\n", Cpa[t0], 0.); + // for(t = 1; t < g_nproc_t*T/2; t++) { + // tt = (t0+t)%(g_nproc_t*T); + // fprintf( ofs, "2 1 %d %e ", t, Cpa[tt]); + // tt = (t0+g_nproc_t*T-t)%(g_nproc_t*T); + // fprintf( ofs, "%e\n", Cpa[tt]); + // } + // tt = (t0+g_nproc_t*T/2)%(g_nproc_t*T); + // fprintf( ofs, "2 1 %d %e %e\n", t, Cpa[tt], 0.); + + // fprintf( ofs, "6 1 0 %e %e\n", Cp4[t0], 0.); + // for(t = 1; t < g_nproc_t*T/2; t++) { + // tt = (t0+t)%(g_nproc_t*T); + // fprintf( ofs, "6 1 %d %e ", t, Cp4[tt]); + // tt = (t0+g_nproc_t*T-t)%(g_nproc_t*T); + // fprintf( ofs, "%e\n", Cp4[tt]); + // } + // tt = (t0+g_nproc_t*T/2)%(g_nproc_t*T); + // fprintf( ofs, "6 1 %d %e %e\n", t, Cp4[tt], 0.); - fprintf( ofs, "6 1 0 %e %e\n", Cp4[t0], 0.); - for(t = 1; t < g_nproc_t*T/2; t++) { - tt = (t0+t)%(g_nproc_t*T); - fprintf( ofs, "6 1 %d %e ", t, Cp4[tt]); - tt = (t0+g_nproc_t*T-t)%(g_nproc_t*T); - fprintf( ofs, "%e\n", Cp4[tt]); - } - tt = (t0+g_nproc_t*T/2)%(g_nproc_t*T); - fprintf( ofs, "6 1 %d %e %e\n", t, Cp4[tt], 0.); fclose(ofs); } #ifdef TM_USE_MPI - if(g_mpi_time_rank == 0) { - free(Cpp); free(Cpa); free(Cp4); + if (g_mpi_time_rank == 0) { + free(Cpp); // free(Cpa); free(Cp4); } - free(sCpp); free(sCpa); free(sCp4); + free(sCpp); // free(sCpa); free(sCp4); #else - free(Cpp); free(Cpa); free(Cp4); + free(Cpp); // free(Cpa); free(Cp4); #endif - } // for(max_time_slices) - } // for(max_samples) - //etime = gettime(); - //if(g_proc_id == 0 && g_debug_level > 0) { - // printf("ONLINE: measurement done int t/s = %1.4e\n", etime - atime); - //} + } // for(max_time_slices) + } // for(max_samples) + tm_stopwatch_pop(&g_timers, 0, 1, ""); return; } - void correlators_measurement(const int traj, const int id, const int ieo) { - light_correlators_measurement(traj, id, ieo); - if(measurement_list[id].measure_heavy_mesons == 1){ - heavy_correlators_measurement(traj, id, ieo); + if (measurement_list[id].measure_heavy_mesons == 1) { + const int i1 = 1; + heavy_correlators_measurement(i1, traj, id, ieo); } - } diff --git a/meas/correlators.h b/meas/correlators.h index 7db749fe8..9ab1e10e5 100644 --- a/meas/correlators.h +++ b/meas/correlators.h @@ -24,13 +24,9 @@ /* measurement of the correlators involving the light doublet (see tmLQCD documentation)*/ void light_quarks_correlators_measurement(const int traj, const int t0, const int ieo); -/* -[TO BE IMPLEMENTED !!!] -measurement of the 4x4 matrix for the heavy doublet: eq. 20 of https://arxiv.org/pdf/1005.2042.pdf -*/ +/* measurement of the 4x4 matrix for the heavy doublet: eq. 20 of https://arxiv.org/pdf/1005.2042.pdf */ void heavy_quarks_correlators_measurement(const int traj, const int t0, const int ieo); - /* Function that is called when the correlator measurement is specified in the input file. Internally, it calls the functions for the measure of the light and (optionally) the heavy mesons correlators From f11e8dab27655528a34c5dc1f69082074279f777 Mon Sep 17 00:00:00 2001 From: simone-romiti Date: Tue, 13 Jun 2023 17:35:20 +0200 Subject: [PATCH 05/51] minor changes --- meas/correlators.c | 23 +++++++++++++++-------- su3.h | 2 ++ 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/meas/correlators.c b/meas/correlators.c index 552e8a346..a6511a9af 100644 --- a/meas/correlators.c +++ b/meas/correlators.c @@ -359,19 +359,26 @@ void heavy_quarks_correlators_measurement(const int traj, const int t0, const in // Cpa = (double*) calloc(T, sizeof(double)); // Cp4 = (double*) calloc(T, sizeof(double)); #endif - source_generation_pion_only(g_spinor_field[0], g_spinor_field[1], t0, sample, traj, - measurement_list[id].seed); + // /// ??? what to use here + // source_generation_pion_only(g_spinor_field[0], g_spinor_field[1], t0, sample, traj, + // measurement_list[id].seed); + // initialize the random sources + for (size_t srd_d = 0; srd_d < 2; srd_d++) { + full_source_spinor_field_spin_diluted_oet_ts(g_bispinor_field[i1][src_d], t0, src_d, sample, traj, + measurement_list[id].seed); + } - spinor *up_spinors = &g_bispinor_field[0][0]; + // ??? not sure how to use g_bispinor + spinor *up_spinors = &g_bispinor_field[i1][0][0]; spinor *down_spinors = &g_bispinor_field[0][1]; // sources - optr1->sr0 = up_spinors[0]; - optr1->sr1 = up_spinors[1]; + optr1->sr0 = g_bispinor_field[i1][0][0]; + optr1->sr1 = g_bispinor_field[i1][0][1]; optr1->sr2 = down_spinors[0]; optr1->sr3 = down_spinors[1]; // propagators, i.e. D^{-1}*eta (eta = stochastic vector for the inversion) - optr1->prop0 = up_spinors[2]; - optr1->prop1 = up_spinors[3]; + optr1->prop0 = g_bispinor_field[i1][0][2]; + optr1->prop1 = g_bispinor_field[i1][0][3]; optr1->prop2 = down_spinors[2]; optr1->prop3 = down_spinors[3]; @@ -487,7 +494,7 @@ void correlators_measurement(const int traj, const int id, const int ieo) { light_correlators_measurement(traj, id, ieo); if (measurement_list[id].measure_heavy_mesons == 1) { - const int i1 = 1; + const int i1 = 1; // ??? is it? heavy_correlators_measurement(i1, traj, id, ieo); } } diff --git a/su3.h b/su3.h index b66652fe5..d8f238161 100644 --- a/su3.h +++ b/su3.h @@ -47,6 +47,7 @@ typedef struct _Complex float c00, c01, c02, c10, c11, c12, c20, c21, c22; } su3_32; +// vector in color space typedef struct { _Complex double c0,c1,c2; @@ -57,6 +58,7 @@ typedef struct _Complex float c0,c1,c2; } su3_vector32; +// 4 Dirac components of the (colored) spinor (vector in color space) typedef struct { su3_vector s0,s1,s2,s3; From 20081dc72f513f2373e2ef2e12d4cd0af1b9f7fe Mon Sep 17 00:00:00 2001 From: simone-romiti Date: Fri, 16 Jun 2023 16:23:21 +0200 Subject: [PATCH 06/51] initialization of sources and propagator spinores + inversion + even-odd lexic conversione --- meas/correlators.c | 184 ++++++++++++++++++++++++++++++++------------- 1 file changed, 132 insertions(+), 52 deletions(-) diff --git a/meas/correlators.c b/meas/correlators.c index a6511a9af..6ac6f0664 100644 --- a/meas/correlators.c +++ b/meas/correlators.c @@ -260,26 +260,15 @@ void light_correlators_measurement(const int traj, const int id, const int ieo) *current), , , for all the choices of h1 and h2 (see eq. 18 and 20 of *https://arxiv.org/pdf/1005.2042.pdf) * - * i1, i2 = source and sink operator indices from the list of the operators in the input file. + * i1, i2 = operator indices from the list of the operators in the input file. * * ******************************************************/ void heavy_quarks_correlators_measurement(const int traj, const int t0, const int ieo, const int i1, const int i2) { tm_stopwatch_push(&g_timers, __func__, ""); // timer for profiling - int i, j, t, tt, t0; // dummy indices - double *Cpp = NULL; // array of the values of the correlator C(t) - double res = 0.; // result of the accumulation of MPI partial sums - float tmp; // dummy variable - operator* optr1; // pointer to the operator (see some lines later) -#ifdef TM_USE_MPI - double mpi_res = 0., mpi_respa = 0., mpi_resp4 = 0.; - // send buffer for MPI_Gather - double *sCpp = NULL; //, *sCpa = NULL, *sCp4 = NULL; -#endif - FILE *ofs; // output file stream - char filename[TM_OMEAS_FILENAME_LENGTH]; // file path - spinor phi; // full spinor of 4 components (we use the spin dilution) + + /* building the stichastic propagator spinors needed for the correlators */ init_operators(); // initialize the operators in the action (if not already done) if (no_operators < 1) { @@ -294,7 +283,8 @@ void heavy_quarks_correlators_measurement(const int traj, const int t0, const in } // selecting the operators i1 and i2 from the list of operators initialized before - optr1 = &operator_list[i1]; + operator* optr1 = &operator_list[i1]; + operator* optr2 = &operator_list[i2]; bool b1 = (optr1->type != DBTMWILSON && optr1->type != DBCLOVER); if (b1) { @@ -345,6 +335,129 @@ void heavy_quarks_correlators_measurement(const int traj, const int t0, const in optr1->kappa, optr1->mubar, optr1->epsbar); } + + // even-odd spinor fields for the light and heavy doublet correlators + // source+propagator, even-odd, 2 flavors + // psi = psi[(s,p)][eo][f][x][alpha][c] + // Note: propagator in th sense that it is D^{-1}*source after the inversion + init_spinor_field(VOLUMEPLUSRAND / 2, 1); // initialize g_spinor_field so that I can copy it + spinor ****l_eo_spinor_field = (spinor ****)malloc(8 * VOLUME / 2); + spinor ****h_eo_spinor_field = (spinor ****)malloc(8 * VOLUME / 2); + // initalize to zero the source spinor fields (necessary??? isn't it enough to use the source + // generator?) + for (size_t i_sp = 0; i_sp < 2; i_sp++) { // source or propagator + + for (size_t i_eo = 0; i_eo < 2; i_eo++) { // even-odd + for (size_t i_f = 0; i_f < 2; i++) { // up-down flavor + assign(l_eo_spinor_field[0][i_eo][i_f], g_spinor_field[0], VOLUME / 2); + assign(h_eo_spinor_field[0][i_eo][i_f], g_spinor_field[0], VOLUME / 2); + } + } + } + + // initalize the random sources + // one source for each --> spin dilution + for (size_t i_f = 0; i_f < 2; i_f++) { + for (size_t src_d = 0; src_d < 4; src_d++) { + const unsigned int seed_i = src_d + measurement_list[id].seed; + // light doublet + eo_source_spinor_field_spin_diluted_oet_ts(l_eo_spinor_field[0][0][i_f], + l_eo_spinor_field[0][1][i_f], t0, src_d, + sample, traj, seed_i); + // heavy doublet + eo_source_spinor_field_spin_diluted_oet_ts(h_eo_spinor_field[0][0][i_f], + h_eo_spinor_field[0][1][i_f], t0, src_d, + sample, traj, seed_i); + } + } + + // heavy doublet: for each even-odd block, I multiply by (1 + i*tau_2) + // the basis for the inversion should be the same as for the light + // --> I will multiply later by the inverse, namely at the end of the inversion + for (size_t i_eo = 0; i_eo < 2; i_eo++) { + for (size_t i_f = 0; i_f < 2; i_f++) { + // (u,d) --> [(1+i*tau_2)/sqrt(2)] * (u,d) , stored at temporarely in the propagator spinors (used as dummy spinors) + mul_one_pm_itau2(h_eo_spinor_field[1][i_eo][i_f], h_eo_spinor_field[1][i_eo][i_f+1], + h_eo_spinor_field[0][i_eo][i_f], h_eo_spinor_field[0][i_eo][i_f+1], +1.0, VOLUME / 2); + // assigning the result to the first components (the sources). + // The propagators will be overwritten with the inversion + assign(h_eo_spinor_field[0][i_eo][i_f], h_eo_spinor_field[1][i_eo][i_f], VOLUME / 2); + } + } + + /* + assign the sources and propagator pointes for the operators + these need to be know when calling the inverter() method + */ + + // light doublet + optr1->sr0 = l_eo_spinor_field[0][0][0]; + optr1->sr1 = l_eo_spinor_field[0][0][1]; + optr1->sr2 = l_eo_spinor_field[0][1][0]; + optr1->sr3 = l_eo_spinor_field[0][1][1]; + + optr1->prop0 = l_eo_spinor_field[1][0][0]; + optr1->prop1 = l_eo_spinor_field[1][0][1]; + optr1->prop2 = l_eo_spinor_field[1][1][0]; + optr1->prop3 = l_eo_spinor_field[1][1][1]; + + // heavy doublet + optr2->sr0 = h_eo_spinor_field[0][0][0]; + optr2->sr1 = h_eo_spinor_field[0][0][1]; + optr2->sr2 = h_eo_spinor_field[0][1][0]; + optr2->sr3 = h_eo_spinor_field[0][1][1]; + + optr2->prop0 = h_eo_spinor_field[1][0][0]; + optr2->prop1 = h_eo_spinor_field[1][0][1]; + optr2->prop2 = h_eo_spinor_field[1][1][0]; + optr2->prop3 = h_eo_spinor_field[1][1][1]; + + // inverting the Dirac operators for the light and heavy doublet + // op_id = i1 or i2, index_start = 0, write_prop = 0 + optr1->inverter(i1, 0, 0); + optr2->inverter(i2, 0, 0); + + // conclude the change of basis for the heavy doublet + for (size_t i_eo = 0; i_eo < 2; i_eo++) { + for (size_t i_f = 0; i_f < 2; i_f++) { + // (u,d) --> [(1+i*tau_2)/sqrt(2)] * (u,d) , stored at temporarely in the propagator spinors (used as dummy spinors) + mul_one_pm_itau2(h_eo_spinor_field[1][i_eo][i_f], h_eo_spinor_field[1][i_eo][i_f+1], + h_eo_spinor_field[0][i_eo][i_f], h_eo_spinor_field[0][i_eo][i_f+1], -1.0, VOLUME / 2); + // assigning the result to the first components (the sources). + // The propagators will be overwritten with the inversion + assign(h_eo_spinor_field[0][i_eo][i_f], h_eo_spinor_field[1][i_eo][i_f], VOLUME / 2); + } + } + + // now we switch from even-odd representation to standard + // propagator, 2 flavors : psi = psi[f][x][alpha][c] + spinor ***l_propagator = (spinor ****)malloc(2 * VOLUME); + spinor ***h_propagator = (spinor ****)malloc(2 * VOLUME); + for (size_t i_f = 0; i_f < 2; i_f++) { + convert_eo_to_lexic(l_propagator[i_f], l_spinor_field[1][0][i_f], l_spinor_field[1][1][i_f]); + convert_eo_to_lexic(h_propagator[i_f], h_spinor_field[1][0][i_f], h_spinor_field[1][1][i_f]); + } + + /* + Now that I have all the propagators (all in the basis of + https://arxiv.org/pdf/1005.2042.pdf) I can build the correlators of eq. 20 + */ + + spinor phi; // dummy spinor + + // light-light + + int i, j, t, tt, t0; // dummy indices + double *Cpp = NULL; // array of the values of the correlator C(t) + double res = 0.; // result of the accumulation of MPI partial sums + float tmp; // dummy variable +#ifdef TM_USE_MPI + double mpi_res = 0., mpi_respa = 0., mpi_resp4 = 0.; + // send buffer for MPI_Gather + double *sCpp = NULL; //, *sCpa = NULL, *sCp4 = NULL; +#endif + FILE *ofs; // output file stream + char filename[TM_OMEAS_FILENAME_LENGTH]; // file path #ifdef TM_USE_MPI sCpp = (double *)calloc(T, sizeof(double)); // sCpa = (double*) calloc(T, sizeof(double)); @@ -357,46 +470,13 @@ void heavy_quarks_correlators_measurement(const int traj, const int t0, const in #else Cpp = (double *)calloc(T, sizeof(double)); // Cpa = (double*) calloc(T, sizeof(double)); - // Cp4 = (double*) calloc(T, sizeof(double)); -#endif - // /// ??? what to use here - // source_generation_pion_only(g_spinor_field[0], g_spinor_field[1], t0, sample, traj, - // measurement_list[id].seed); - // initialize the random sources - for (size_t srd_d = 0; srd_d < 2; srd_d++) { - full_source_spinor_field_spin_diluted_oet_ts(g_bispinor_field[i1][src_d], t0, src_d, sample, traj, - measurement_list[id].seed); - } + // Cp4 = (double*) calloc(T, sizeof(double));// INIT SOME SPINOR FIELD FOR THE LIGHT - // ??? not sure how to use g_bispinor - spinor *up_spinors = &g_bispinor_field[i1][0][0]; - spinor *down_spinors = &g_bispinor_field[0][1]; - // sources - optr1->sr0 = g_bispinor_field[i1][0][0]; - optr1->sr1 = g_bispinor_field[i1][0][1]; - optr1->sr2 = down_spinors[0]; - optr1->sr3 = down_spinors[1]; - // propagators, i.e. D^{-1}*eta (eta = stochastic vector for the inversion) - optr1->prop0 = g_bispinor_field[i1][0][2]; - optr1->prop1 = g_bispinor_field[i1][0][3]; - optr1->prop2 = down_spinors[2]; - optr1->prop3 = down_spinors[3]; - - // even-odd sites for the down - // sources - optr1->sr2 = g_bispinor_field[1][0]; - optr1->sr3 = g_bispinor_field[1][1]; - // propagators, i.e. D^{-1}*eta (eta = stochastic vector for the inversion) - optr1->prop2 = g_bispinor_field[1][2]; - optr1->prop3 = g_bispinor_field[1][3]; +#endif - // op_id = 0, index_start = 0, write_prop = 0 - optr1->inverter(i1, 0, 0); + // heavy-light - /* now we bring it to normal format */ - /* here we use implicitly DUM_MATRIX and DUM_MATRIX+1 */ - convert_eo_to_lexic(down_spinors[DUM_MATRIX], down_spinors[2], down_spinors[3]); - convert_eo_to_lexic(down_spinors[DUM_MATRIX], down_spinors[2], down_spinors[3]); + /* now we sum only over local space for every t */ for (t = 0; t < T; t++) { From c80b84bd87a70c34349bb12532acade598725378 Mon Sep 17 00:00:00 2001 From: simone-romiti Date: Fri, 16 Jun 2023 16:54:15 +0200 Subject: [PATCH 07/51] heavy_correlators_measurement() should be the same as light_correlators_measurement() now. Next: use the dummy variables defined for the heavy for building the light-heavy correlators --- meas/correlators.c | 218 ++++++++++++++++++++++++++------------------- 1 file changed, 124 insertions(+), 94 deletions(-) diff --git a/meas/correlators.c b/meas/correlators.c index 6ac6f0664..84bfd5685 100644 --- a/meas/correlators.c +++ b/meas/correlators.c @@ -268,7 +268,53 @@ void heavy_quarks_correlators_measurement(const int traj, const int t0, const in const int i2) { tm_stopwatch_push(&g_timers, __func__, ""); // timer for profiling - /* building the stichastic propagator spinors needed for the correlators */ + spinor phi; // dummy spinor + int i, j, t, tt, t0; // dummy indices + float tmp; // dummy variable + + + /* light-light correlators: dummy variables */ + + // array of the values of the correlator C(t) + double *Cpp = NULL, *Cpa = NULL, *Cp4 = NULL; + // result of the accumulation of MPI partial sums + double res = 0., respa = 0., resp4 = 0.; +#ifdef TM_USE_MPI + double mpi_res = 0., mpi_respa = 0., mpi_resp4 = 0.; + // send buffer for MPI_Gather + double *sCpp = NULL, *sCpa = NULL, *sCp4 = NULL; +#endif + +#ifdef TM_USE_MPI + sCpp = (double *)calloc(T, sizeof(double)); + sCpa = (double *)calloc(T, sizeof(double)); + sCp4 = (double *)calloc(T, sizeof(double)); + if (g_mpi_time_rank == 0) { + Cpp = (double *)calloc(g_nproc_t * T, sizeof(double)); + Cpa = (double *)calloc(g_nproc_t * T, sizeof(double)); + Cp4 = (double *)calloc(g_nproc_t * T, sizeof(double)); + } +#else + Cpp = (double *)calloc(T, sizeof(double)); + Cpa = (double *)calloc(T, sizeof(double)); + Cp4 = (double *)calloc(T, sizeof(double)); +#endif + + /* heavy-light correlator: dummy variables */ + + // the number of independent correlators is 6=4*(4-1)/2 + double **C_ij = (double *)calloc(6*T, sizeof(double)); // C[i][] + double **res_ij = (double *)calloc(6*T, sizeof(double)); +#ifdef TM_USE_MPI + double **mpi_res_ij = (double *)calloc(6*T, sizeof(double)); + // send buffer for MPI_Gather + double **sC_ij = (double *)calloc(6*T, sizeof(double)); +#endif + + FILE *ofs; // output file stream + char filename[TM_OMEAS_FILENAME_LENGTH]; // file path + + /* building the stochastic propagator spinors needed for the correlators */ init_operators(); // initialize the operators in the action (if not already done) if (no_operators < 1) { @@ -283,8 +329,8 @@ void heavy_quarks_correlators_measurement(const int traj, const int t0, const in } // selecting the operators i1 and i2 from the list of operators initialized before - operator* optr1 = &operator_list[i1]; - operator* optr2 = &operator_list[i2]; + operator* optr1 = & operator_list[i1]; + operator* optr2 = & operator_list[i2]; bool b1 = (optr1->type != DBTMWILSON && optr1->type != DBCLOVER); if (b1) { @@ -335,7 +381,6 @@ void heavy_quarks_correlators_measurement(const int traj, const int t0, const in optr1->kappa, optr1->mubar, optr1->epsbar); } - // even-odd spinor fields for the light and heavy doublet correlators // source+propagator, even-odd, 2 flavors // psi = psi[(s,p)][eo][f][x][alpha][c] @@ -376,12 +421,14 @@ void heavy_quarks_correlators_measurement(const int traj, const int t0, const in // --> I will multiply later by the inverse, namely at the end of the inversion for (size_t i_eo = 0; i_eo < 2; i_eo++) { for (size_t i_f = 0; i_f < 2; i_f++) { - // (u,d) --> [(1+i*tau_2)/sqrt(2)] * (u,d) , stored at temporarely in the propagator spinors (used as dummy spinors) - mul_one_pm_itau2(h_eo_spinor_field[1][i_eo][i_f], h_eo_spinor_field[1][i_eo][i_f+1], - h_eo_spinor_field[0][i_eo][i_f], h_eo_spinor_field[0][i_eo][i_f+1], +1.0, VOLUME / 2); - // assigning the result to the first components (the sources). - // The propagators will be overwritten with the inversion - assign(h_eo_spinor_field[0][i_eo][i_f], h_eo_spinor_field[1][i_eo][i_f], VOLUME / 2); + // (u,d) --> [(1+i*tau_2)/sqrt(2)] * (u,d) , stored at temporarely in the propagator + // spinors (used as dummy spinors) + mul_one_pm_itau2(h_eo_spinor_field[1][i_eo][i_f], h_eo_spinor_field[1][i_eo][i_f + 1], + h_eo_spinor_field[0][i_eo][i_f], h_eo_spinor_field[0][i_eo][i_f + 1], + +1.0, VOLUME / 2); + // assigning the result to the first components (the sources). + // The propagators will be overwritten with the inversion + assign(h_eo_spinor_field[0][i_eo][i_f], h_eo_spinor_field[1][i_eo][i_f], VOLUME / 2); } } @@ -420,12 +467,14 @@ void heavy_quarks_correlators_measurement(const int traj, const int t0, const in // conclude the change of basis for the heavy doublet for (size_t i_eo = 0; i_eo < 2; i_eo++) { for (size_t i_f = 0; i_f < 2; i_f++) { - // (u,d) --> [(1+i*tau_2)/sqrt(2)] * (u,d) , stored at temporarely in the propagator spinors (used as dummy spinors) - mul_one_pm_itau2(h_eo_spinor_field[1][i_eo][i_f], h_eo_spinor_field[1][i_eo][i_f+1], - h_eo_spinor_field[0][i_eo][i_f], h_eo_spinor_field[0][i_eo][i_f+1], -1.0, VOLUME / 2); - // assigning the result to the first components (the sources). - // The propagators will be overwritten with the inversion - assign(h_eo_spinor_field[0][i_eo][i_f], h_eo_spinor_field[1][i_eo][i_f], VOLUME / 2); + // (u,d) --> [(1+i*tau_2)/sqrt(2)] * (u,d) , stored at temporarely in the propagator + // spinors (used as dummy spinors) + mul_one_pm_itau2(h_eo_spinor_field[1][i_eo][i_f], h_eo_spinor_field[1][i_eo][i_f + 1], + h_eo_spinor_field[0][i_eo][i_f], h_eo_spinor_field[0][i_eo][i_f + 1], + -1.0, VOLUME / 2); + // assigning the result to the first components (the sources). + // The propagators will be overwritten with the inversion + assign(h_eo_spinor_field[0][i_eo][i_f], h_eo_spinor_field[1][i_eo][i_f], VOLUME / 2); } } @@ -434,8 +483,10 @@ void heavy_quarks_correlators_measurement(const int traj, const int t0, const in spinor ***l_propagator = (spinor ****)malloc(2 * VOLUME); spinor ***h_propagator = (spinor ****)malloc(2 * VOLUME); for (size_t i_f = 0; i_f < 2; i_f++) { - convert_eo_to_lexic(l_propagator[i_f], l_spinor_field[1][0][i_f], l_spinor_field[1][1][i_f]); - convert_eo_to_lexic(h_propagator[i_f], h_spinor_field[1][0][i_f], h_spinor_field[1][1][i_f]); + convert_eo_to_lexic(l_propagator[i_f], l_spinor_field[1][0][i_f], + l_spinor_field[1][1][i_f]); + convert_eo_to_lexic(h_propagator[i_f], h_spinor_field[1][0][i_f], + h_spinor_field[1][1][i_f]); } /* @@ -443,71 +494,40 @@ void heavy_quarks_correlators_measurement(const int traj, const int t0, const in https://arxiv.org/pdf/1005.2042.pdf) I can build the correlators of eq. 20 */ - spinor phi; // dummy spinor - - // light-light - - int i, j, t, tt, t0; // dummy indices - double *Cpp = NULL; // array of the values of the correlator C(t) - double res = 0.; // result of the accumulation of MPI partial sums - float tmp; // dummy variable -#ifdef TM_USE_MPI - double mpi_res = 0., mpi_respa = 0., mpi_resp4 = 0.; - // send buffer for MPI_Gather - double *sCpp = NULL; //, *sCpa = NULL, *sCp4 = NULL; -#endif - FILE *ofs; // output file stream - char filename[TM_OMEAS_FILENAME_LENGTH]; // file path -#ifdef TM_USE_MPI - sCpp = (double *)calloc(T, sizeof(double)); - // sCpa = (double*) calloc(T, sizeof(double)); - // sCp4 = (double*) calloc(T, sizeof(double)); - if (g_mpi_time_rank == 0) { - Cpp = (double *)calloc(g_nproc_t * T, sizeof(double)); - // Cpa = (double*) calloc(g_nproc_t*T, sizeof(double)); - // Cp4 = (double*) calloc(g_nproc_t*T, sizeof(double)); - } -#else - Cpp = (double *)calloc(T, sizeof(double)); - // Cpa = (double*) calloc(T, sizeof(double)); - // Cp4 = (double*) calloc(T, sizeof(double));// INIT SOME SPINOR FIELD FOR THE LIGHT - -#endif - - // heavy-light - - - /* now we sum only over local space for every t */ for (t = 0; t < T; t++) { j = g_ipt[t][0][0][0]; res = 0.; - // respa = 0.; - // resp4 = 0.; + respa = 0.; + resp4 = 0.; for (i = j; i < j + LX * LY * LZ; i++) { - res += _spinor_prod_re(up_spinors[DUM_MATRIX][i], up_spinors[DUM_MATRIX][i]); - // _gamma0(phi, g_spinor_field[DUM_MATRIX][i]); - // respa += _spinor_prod_re(g_spinor_field[DUM_MATRIX][i], phi); - // _gamma5(phi, phi); - // resp4 += _spinor_prod_im(g_spinor_field[DUM_MATRIX][i], phi); + res += _spinor_prod_re(l_propagator[0][i], l_propagator[0][i]); + _gamma0(phi, l_propagator[0][i]); + respa += _spinor_prod_re(l_propagator[0][i], phi); + _gamma5(phi, phi); + resp4 += _spinor_prod_im(l_propagator[0][i], phi); } #if defined TM_USE_MPI MPI_Reduce(&res, &mpi_res, 1, MPI_DOUBLE, MPI_SUM, 0, g_mpi_time_slices); res = mpi_res; - // MPI_Reduce(&respa, &mpi_respa, 1, MPI_DOUBLE, MPI_SUM, 0, g_mpi_time_slices); - // respa = mpi_respa; - // MPI_Reduce(&resp4, &mpi_resp4, 1, MPI_DOUBLE, MPI_SUM, 0, g_mpi_time_slices); - // resp4 = mpi_resp4; + MPI_Reduce(&respa, &mpi_respa, 1, MPI_DOUBLE, MPI_SUM, 0, g_mpi_time_slices); + respa = mpi_respa; + MPI_Reduce(&resp4, &mpi_resp4, 1, MPI_DOUBLE, MPI_SUM, 0, g_mpi_time_slices); + resp4 = mpi_resp4; sCpp[t] = +res / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ) / 2. / optr->kappa / optr->kappa; - // sCpa[t] = -respa/(g_nproc_x*LX)/(g_nproc_y*LY)/(g_nproc_z*LZ)/2./optr->kappa/optr->kappa; - // sCp4[t] = +resp4/(g_nproc_x*LX)/(g_nproc_y*LY)/(g_nproc_z*LZ)/2./optr->kappa/optr->kappa; + sCpa[t] = -respa / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ) / 2. / + optr->kappa / optr->kappa; + sCp4[t] = +resp4 / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ) / 2. / + optr->kappa / optr->kappa; #else Cpp[t] = +res / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ) / 2. / optr->kappa / optr->kappa; - // Cpa[t] = -respa/(g_nproc_x*LX)/(g_nproc_y*LY)/(g_nproc_z*LZ)/2./optr->kappa/optr->kappa; - // Cp4[t] = +resp4/(g_nproc_x*LX)/(g_nproc_y*LY)/(g_nproc_z*LZ)/2./optr->kappa/optr->kappa; + Cpa[t] = -respa / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ) / 2. / + optr->kappa / optr->kappa; + Cp4[t] = +resp4 / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ) / 2. / + optr->kappa / optr->kappa; #endif } @@ -515,8 +535,8 @@ void heavy_quarks_correlators_measurement(const int traj, const int t0, const in /* some gymnastics needed in case of parallelisation */ if (g_mpi_time_rank == 0) { MPI_Gather(sCpp, T, MPI_DOUBLE, Cpp, T, MPI_DOUBLE, 0, g_mpi_SV_slices); - // MPI_Gather(sCpa, T, MPI_DOUBLE, Cpa, T, MPI_DOUBLE, 0, g_mpi_SV_slices); - // MPI_Gather(sCp4, T, MPI_DOUBLE, Cp4, T, MPI_DOUBLE, 0, g_mpi_SV_slices); + MPI_Gather(sCpa, T, MPI_DOUBLE, Cpa, T, MPI_DOUBLE, 0, g_mpi_SV_slices); + MPI_Gather(sCp4, T, MPI_DOUBLE, Cp4, T, MPI_DOUBLE, 0, g_mpi_SV_slices); } #endif @@ -533,48 +553,58 @@ void heavy_quarks_correlators_measurement(const int traj, const int t0, const in tt = (t0 + g_nproc_t * T / 2) % (g_nproc_t * T); fprintf(ofs, "1 1 %d %e %e\n", t, Cpp[tt], 0.); - // fprintf( ofs, "2 1 0 %e %e\n", Cpa[t0], 0.); - // for(t = 1; t < g_nproc_t*T/2; t++) { - // tt = (t0+t)%(g_nproc_t*T); - // fprintf( ofs, "2 1 %d %e ", t, Cpa[tt]); - // tt = (t0+g_nproc_t*T-t)%(g_nproc_t*T); - // fprintf( ofs, "%e\n", Cpa[tt]); - // } - // tt = (t0+g_nproc_t*T/2)%(g_nproc_t*T); - // fprintf( ofs, "2 1 %d %e %e\n", t, Cpa[tt], 0.); - - // fprintf( ofs, "6 1 0 %e %e\n", Cp4[t0], 0.); - // for(t = 1; t < g_nproc_t*T/2; t++) { - // tt = (t0+t)%(g_nproc_t*T); - // fprintf( ofs, "6 1 %d %e ", t, Cp4[tt]); - // tt = (t0+g_nproc_t*T-t)%(g_nproc_t*T); - // fprintf( ofs, "%e\n", Cp4[tt]); - // } - // tt = (t0+g_nproc_t*T/2)%(g_nproc_t*T); - // fprintf( ofs, "6 1 %d %e %e\n", t, Cp4[tt], 0.); + fprintf(ofs, "2 1 0 %e %e\n", Cpa[t0], 0.); + for (t = 1; t < g_nproc_t * T / 2; t++) { + tt = (t0 + t) % (g_nproc_t * T); + fprintf(ofs, "2 1 %d %e ", t, Cpa[tt]); + tt = (t0 + g_nproc_t * T - t) % (g_nproc_t * T); + fprintf(ofs, "%e\n", Cpa[tt]); + } + tt = (t0 + g_nproc_t * T / 2) % (g_nproc_t * T); + fprintf(ofs, "2 1 %d %e %e\n", t, Cpa[tt], 0.); + fprintf(ofs, "6 1 0 %e %e\n", Cp4[t0], 0.); + for (t = 1; t < g_nproc_t * T / 2; t++) { + tt = (t0 + t) % (g_nproc_t * T); + fprintf(ofs, "6 1 %d %e ", t, Cp4[tt]); + tt = (t0 + g_nproc_t * T - t) % (g_nproc_t * T); + fprintf(ofs, "%e\n", Cp4[tt]); + } + tt = (t0 + g_nproc_t * T / 2) % (g_nproc_t * T); + fprintf(ofs, "6 1 %d %e %e\n", t, Cp4[tt], 0.); fclose(ofs); } #ifdef TM_USE_MPI if (g_mpi_time_rank == 0) { - free(Cpp); // free(Cpa); free(Cp4); + free(Cpp); + free(Cpa); + free(Cp4); + free(C_ij) } - free(sCpp); // free(sCpa); free(sCp4); + free(sCpp); + free(sCpa); + free(sCp4); + free(sC_ij) #else - free(Cpp); // free(Cpa); free(Cp4); + free(Cpp); + free(Cpa); + free(Cp4); + free(C_ij) #endif } // for(max_time_slices) } // for(max_samples) tm_stopwatch_pop(&g_timers, 0, 1, ""); + return; } void correlators_measurement(const int traj, const int id, const int ieo) { light_correlators_measurement(traj, id, ieo); + // ??? maybe add a double check? if (measurement_list[id].measure_heavy_mesons == 1) { - const int i1 = 1; // ??? is it? - heavy_correlators_measurement(i1, traj, id, ieo); + const unsigned int i1 = 0, i2 = 1; + heavy_correlators_measurement(traj, id, ieo, i1, i2); } } From ff9bdda63a4e30db127e6d0bcdfe00caf2fc5899 Mon Sep 17 00:00:00 2001 From: simone-romiti Date: Tue, 20 Jun 2023 14:47:03 +0200 Subject: [PATCH 08/51] fixed compilation errors --- meas/correlators.c | 38 +++++++++++++++++++------------------- meas/correlators.h | 8 +++++--- meas/measurements.h | 6 +++--- offline_measurement.c | 2 +- 4 files changed, 28 insertions(+), 26 deletions(-) diff --git a/meas/correlators.c b/meas/correlators.c index 84bfd5685..f5ffe63c9 100644 --- a/meas/correlators.c +++ b/meas/correlators.c @@ -60,7 +60,7 @@ void light_correlators_measurement(const int traj, const int id, const int ieo) int i, j, t, tt, t0; double *Cpp = NULL, *Cpa = NULL, *Cp4 = NULL; double res = 0., respa = 0., resp4 = 0.; - double atime, etime; + // double atime, etime; float tmp; operator * optr; #ifdef TM_USE_MPI @@ -264,7 +264,7 @@ void light_correlators_measurement(const int traj, const int id, const int ieo) * * ******************************************************/ -void heavy_quarks_correlators_measurement(const int traj, const int t0, const int ieo, const int i1, +void heavy_correlators_measurement(const int traj, const int id, const int ieo, const int i1, const int i2) { tm_stopwatch_push(&g_timers, __func__, ""); // timer for profiling @@ -480,13 +480,13 @@ void heavy_quarks_correlators_measurement(const int traj, const int t0, const in // now we switch from even-odd representation to standard // propagator, 2 flavors : psi = psi[f][x][alpha][c] - spinor ***l_propagator = (spinor ****)malloc(2 * VOLUME); - spinor ***h_propagator = (spinor ****)malloc(2 * VOLUME); + spinor **l_propagator = (spinor **)malloc(2 * VOLUME * sizeof(spinor)); + spinor **h_propagator = (spinor **)malloc(2 * VOLUME * sizeof(spinor)); for (size_t i_f = 0; i_f < 2; i_f++) { - convert_eo_to_lexic(l_propagator[i_f], l_spinor_field[1][0][i_f], - l_spinor_field[1][1][i_f]); - convert_eo_to_lexic(h_propagator[i_f], h_spinor_field[1][0][i_f], - h_spinor_field[1][1][i_f]); + convert_eo_to_lexic(l_propagator[i_f], l_eo_spinor_field[1][0][i_f], + l_eo_spinor_field[1][1][i_f]); + convert_eo_to_lexic(h_propagator[i_f], h_eo_spinor_field[1][0][i_f], + h_eo_spinor_field[1][1][i_f]); } /* @@ -515,19 +515,19 @@ void heavy_quarks_correlators_measurement(const int traj, const int t0, const in respa = mpi_respa; MPI_Reduce(&resp4, &mpi_resp4, 1, MPI_DOUBLE, MPI_SUM, 0, g_mpi_time_slices); resp4 = mpi_resp4; - sCpp[t] = +res / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ) / 2. / optr->kappa / - optr->kappa; + sCpp[t] = +res / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ) / 2. / optr1->kappa / + optr1->kappa; sCpa[t] = -respa / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ) / 2. / - optr->kappa / optr->kappa; + optr1->kappa / optr1->kappa; sCp4[t] = +resp4 / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ) / 2. / - optr->kappa / optr->kappa; + optr1->kappa / optr1->kappa; #else - Cpp[t] = +res / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ) / 2. / optr->kappa / - optr->kappa; + Cpp[t] = +res / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ) / 2. / optr1->kappa / + optr1->kappa; Cpa[t] = -respa / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ) / 2. / - optr->kappa / optr->kappa; + optr1->kappa / optr1->kappa; Cp4[t] = +resp4 / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ) / 2. / - optr->kappa / optr->kappa; + optr1->kappa / optr1->kappa; #endif } @@ -579,17 +579,17 @@ void heavy_quarks_correlators_measurement(const int traj, const int t0, const in free(Cpp); free(Cpa); free(Cp4); - free(C_ij) + free(C_ij); } free(sCpp); free(sCpa); free(sCp4); - free(sC_ij) + free(sC_ij); #else free(Cpp); free(Cpa); free(Cp4); - free(C_ij) + free(C_ij); #endif } // for(max_time_slices) } // for(max_samples) diff --git a/meas/correlators.h b/meas/correlators.h index 9ab1e10e5..8fa2a9990 100644 --- a/meas/correlators.h +++ b/meas/correlators.h @@ -21,17 +21,19 @@ #ifndef _ONLINE_MEASUREMENT_H #define _ONLINE_MEASUREMENT_H +#include + /* measurement of the correlators involving the light doublet (see tmLQCD documentation)*/ -void light_quarks_correlators_measurement(const int traj, const int t0, const int ieo); +void light_correlators_measurement(const int traj, const int id, const int ieo); /* measurement of the 4x4 matrix for the heavy doublet: eq. 20 of https://arxiv.org/pdf/1005.2042.pdf */ -void heavy_quarks_correlators_measurement(const int traj, const int t0, const int ieo); +void heavy_correlators_measurement(const int traj, const int id, const int ieo, const int i1, const int i2); /* Function that is called when the correlator measurement is specified in the input file. Internally, it calls the functions for the measure of the light and (optionally) the heavy mesons correlators */ -void correlators_measurement(const int traj, const int t0, const int ieo); +void correlators_measurement(const int traj, const int id, const int ieo); #endif diff --git a/meas/measurements.h b/meas/measurements.h index 2852bfadf..f795e7e04 100644 --- a/meas/measurements.h +++ b/meas/measurements.h @@ -68,11 +68,11 @@ typedef struct { /* functions for the measurement */ void (*measurefunc) (const int traj, const int id, const int ieo); - - ExternalLibrary external_library; + ExternalLibrary external_library; + // measuring the 4x4 matrix of correlators in the 1+1 sector: https://arxiv.org/abs/1005.2042 - int measure_heavy_mesons = 0; // default: heavy mesons not measured + int measure_heavy_mesons; // 1 or 0: heavy mesons measured or not } measurement; diff --git a/offline_measurement.c b/offline_measurement.c index f9d4b1215..766dc1472 100644 --- a/offline_measurement.c +++ b/offline_measurement.c @@ -75,7 +75,7 @@ static void set_default_filenames(char ** input_filename, char ** filename); int main(int argc, char *argv[]) { FILE *parameterfile = NULL; - int j, i, ix = 0, isample = 0, op_id = 0; + int j, i; //, ix = 0, isample = 0, op_id = 0; char datafilename[206]; char parameterfilename[206]; char conf_filename[CONF_FILENAME_LENGTH]; From 89674c3bcdf737a43c8c9b48c088bbe54c44d293 Mon Sep 17 00:00:00 2001 From: simone-romiti Date: Tue, 20 Jun 2023 14:54:50 +0200 Subject: [PATCH 09/51] name of function `mul_one_pm_itau2()` is misleading --> it also divides by sqrt(2). --- meas/correlators.c | 14 ++++++++------ operator.c | 12 ++++++------ operator/tm_operators_nd.c | 2 +- operator/tm_operators_nd.h | 2 +- prepare_source.c | 4 ++-- 5 files changed, 18 insertions(+), 16 deletions(-) diff --git a/meas/correlators.c b/meas/correlators.c index f5ffe63c9..b65b2223f 100644 --- a/meas/correlators.c +++ b/meas/correlators.c @@ -423,9 +423,10 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, for (size_t i_f = 0; i_f < 2; i_f++) { // (u,d) --> [(1+i*tau_2)/sqrt(2)] * (u,d) , stored at temporarely in the propagator // spinors (used as dummy spinors) - mul_one_pm_itau2(h_eo_spinor_field[1][i_eo][i_f], h_eo_spinor_field[1][i_eo][i_f + 1], - h_eo_spinor_field[0][i_eo][i_f], h_eo_spinor_field[0][i_eo][i_f + 1], - +1.0, VOLUME / 2); + mul_one_pm_itau2_and_div_by_sqrt2( + h_eo_spinor_field[1][i_eo][i_f], h_eo_spinor_field[1][i_eo][i_f + 1], + h_eo_spinor_field[0][i_eo][i_f], h_eo_spinor_field[0][i_eo][i_f + 1], + +1.0, VOLUME / 2); // assigning the result to the first components (the sources). // The propagators will be overwritten with the inversion assign(h_eo_spinor_field[0][i_eo][i_f], h_eo_spinor_field[1][i_eo][i_f], VOLUME / 2); @@ -469,9 +470,10 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, for (size_t i_f = 0; i_f < 2; i_f++) { // (u,d) --> [(1+i*tau_2)/sqrt(2)] * (u,d) , stored at temporarely in the propagator // spinors (used as dummy spinors) - mul_one_pm_itau2(h_eo_spinor_field[1][i_eo][i_f], h_eo_spinor_field[1][i_eo][i_f + 1], - h_eo_spinor_field[0][i_eo][i_f], h_eo_spinor_field[0][i_eo][i_f + 1], - -1.0, VOLUME / 2); + mul_one_pm_itau2_and_div_by_sqrt2( + h_eo_spinor_field[1][i_eo][i_f], h_eo_spinor_field[1][i_eo][i_f + 1], + h_eo_spinor_field[0][i_eo][i_f], h_eo_spinor_field[0][i_eo][i_f + 1], + -1.0, VOLUME / 2); // assigning the result to the first components (the sources). // The propagators will be overwritten with the inversion assign(h_eo_spinor_field[0][i_eo][i_f], h_eo_spinor_field[1][i_eo][i_f], VOLUME / 2); diff --git a/operator.c b/operator.c index 6df4cc7cd..a4e5815bf 100644 --- a/operator.c +++ b/operator.c @@ -471,9 +471,9 @@ void op_invert(const int op_id, const int index_start, const int write_prop) { /* this requires multiplication of source with */ /* (1+itau_2)/sqrt(2) and the result with (1-itau_2)/sqrt(2) */ - mul_one_pm_itau2(optr->prop0, optr->prop2, g_spinor_field[DUM_DERI], + mul_one_pm_itau2_and_div_by_sqrt2(optr->prop0, optr->prop2, g_spinor_field[DUM_DERI], g_spinor_field[DUM_DERI+2], -1., VOLUME/2); - mul_one_pm_itau2(optr->prop1, optr->prop3, g_spinor_field[DUM_DERI+1], + mul_one_pm_itau2_and_div_by_sqrt2(optr->prop1, optr->prop3, g_spinor_field[DUM_DERI+1], g_spinor_field[DUM_DERI+3], -1., VOLUME/2); /* write propagator */ if(write_prop) optr->write_prop(op_id, index_start, i); @@ -489,11 +489,11 @@ void op_invert(const int op_id, const int index_start, const int write_prop) { fprintf(stdout, "# Inversion done in %d iterations, squared residue = %e!\n", optr->iterations, optr->reached_prec); } - mul_one_pm_itau2(g_spinor_field[DUM_DERI], g_spinor_field[DUM_DERI+2], optr->sr0, optr->sr2, -1., VOLUME/2); - mul_one_pm_itau2(g_spinor_field[DUM_DERI+1], g_spinor_field[DUM_DERI+3], optr->sr1, optr->sr3, -1., VOLUME/2); + mul_one_pm_itau2_and_div_by_sqrt2(g_spinor_field[DUM_DERI], g_spinor_field[DUM_DERI+2], optr->sr0, optr->sr2, -1., VOLUME/2); + mul_one_pm_itau2_and_div_by_sqrt2(g_spinor_field[DUM_DERI+1], g_spinor_field[DUM_DERI+3], optr->sr1, optr->sr3, -1., VOLUME/2); - mul_one_pm_itau2(optr->sr0, optr->sr2, g_spinor_field[DUM_DERI+2], g_spinor_field[DUM_DERI], +1., VOLUME/2); - mul_one_pm_itau2(optr->sr1, optr->sr3, g_spinor_field[DUM_DERI+3], g_spinor_field[DUM_DERI+1], +1., VOLUME/2); + mul_one_pm_itau2_and_div_by_sqrt2(optr->sr0, optr->sr2, g_spinor_field[DUM_DERI+2], g_spinor_field[DUM_DERI], +1., VOLUME/2); + mul_one_pm_itau2_and_div_by_sqrt2(optr->sr1, optr->sr3, g_spinor_field[DUM_DERI+3], g_spinor_field[DUM_DERI+1], +1., VOLUME/2); } /* volume sources need only one inversion */ else if(SourceInfo.type == SRC_TYPE_VOL) i++; diff --git a/operator/tm_operators_nd.c b/operator/tm_operators_nd.c index 5cdc4f385..41729dc36 100644 --- a/operator/tm_operators_nd.c +++ b/operator/tm_operators_nd.c @@ -722,7 +722,7 @@ void Q_test_epsilon(spinor * const l_strange, spinor * const l_charm, } -void mul_one_pm_itau2(spinor * const p, spinor * const q, +void mul_one_pm_itau2_and_div_by_sqrt2(spinor * const p, spinor * const q, spinor * const r, spinor * const s, const double sign, const int N) { double fac = 1./sqrt(2.); diff --git a/operator/tm_operators_nd.h b/operator/tm_operators_nd.h index 138e9b93b..d50da769d 100644 --- a/operator/tm_operators_nd.h +++ b/operator/tm_operators_nd.h @@ -22,7 +22,7 @@ #ifndef _TM_OPERATTORS_ND_H #define _TM_OPERATTORS_ND_H -void mul_one_pm_itau2(spinor * const p, spinor * const q, +void mul_one_pm_itau2_and_div_by_sqrt2(spinor * const p, spinor * const q, spinor * const r, spinor * const s, const double sign, const int N); diff --git a/prepare_source.c b/prepare_source.c index b4d726ba3..9974df558 100644 --- a/prepare_source.c +++ b/prepare_source.c @@ -311,8 +311,8 @@ void prepare_source(const int nstore, const int isample, const int ix, const int gaussian_volume_source(g_spinor_field[2], g_spinor_field[3], isample, nstore, 2); } - mul_one_pm_itau2(g_spinor_field[4], g_spinor_field[6], g_spinor_field[0], g_spinor_field[2], +1., VOLUME/2); - mul_one_pm_itau2(g_spinor_field[5], g_spinor_field[7], g_spinor_field[1], g_spinor_field[3], +1., VOLUME/2); + mul_one_pm_itau2_and_div_by_sqrt2(g_spinor_field[4], g_spinor_field[6], g_spinor_field[0], g_spinor_field[2], +1., VOLUME/2); + mul_one_pm_itau2_and_div_by_sqrt2(g_spinor_field[5], g_spinor_field[7], g_spinor_field[1], g_spinor_field[3], +1., VOLUME/2); assign(g_spinor_field[0], g_spinor_field[4], VOLUME/2); assign(g_spinor_field[1], g_spinor_field[5], VOLUME/2); assign(g_spinor_field[2], g_spinor_field[6], VOLUME/2); From 92cf6cf6bbaca792c33a9d2538e18ab800f24086 Mon Sep 17 00:00:00 2001 From: simone-romiti Date: Tue, 20 Jun 2023 14:56:47 +0200 Subject: [PATCH 10/51] some documentation for mul_one_pm_itau2_and_div_by_sqrt2() --- operator/tm_operators_nd.h | 1 + 1 file changed, 1 insertion(+) diff --git a/operator/tm_operators_nd.h b/operator/tm_operators_nd.h index d50da769d..35ff75d67 100644 --- a/operator/tm_operators_nd.h +++ b/operator/tm_operators_nd.h @@ -22,6 +22,7 @@ #ifndef _TM_OPERATTORS_ND_H #define _TM_OPERATTORS_ND_H +// \frac{1}{\sqrt(2)} (1 \pm \tau_2) void mul_one_pm_itau2_and_div_by_sqrt2(spinor * const p, spinor * const q, spinor * const r, spinor * const s, const double sign, const int N); From df58ec7c8167be70d9fac7a33971f9d09d1fd2a7 Mon Sep 17 00:00:00 2001 From: simone-romiti Date: Tue, 20 Jun 2023 18:36:55 +0200 Subject: [PATCH 11/51] todo: check if the handwritten derivation is correct and implement --- meas/correlators.c | 246 ++++++++++++++++++++++++++------------------- meas/correlators.h | 5 + 2 files changed, 147 insertions(+), 104 deletions(-) diff --git a/meas/correlators.c b/meas/correlators.c index b65b2223f..df4866021 100644 --- a/meas/correlators.c +++ b/meas/correlators.c @@ -258,7 +258,10 @@ void light_correlators_measurement(const int traj, const int id, const int ieo) * This routine computes the correlator matrix (), * where G1 and G2 are 2 gamma matrices from the set {1, gamma5} --> {S,P} (scalar and pseudoscalar *current), , , for all the choices of h1 and h2 (see eq. 18 and 20 of - *https://arxiv.org/pdf/1005.2042.pdf) + *https://arxiv.org/pdf/1005.2042.pdf): + * + * C = Tr[S_l * Gamma_1 * S_h * Gamma_2] + * where S_l, S_h are the propagators of the light and heavy quark of the meson (e.g. K --> u, ) * * i1, i2 = operator indices from the list of the operators in the input file. * @@ -302,13 +305,15 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, /* heavy-light correlator: dummy variables */ - // the number of independent correlators is 6=4*(4-1)/2 - double **C_ij = (double *)calloc(6*T, sizeof(double)); // C[i][] - double **res_ij = (double *)calloc(6*T, sizeof(double)); + // the number of independent correlators is 8 = 2 * (2*2) + // 2: strange or charm flavor + // 2*2: all combinations of (1, gamma_5) + double ****C_ij = (double ****)calloc(8*T, sizeof(double)); // C[i_f][gamma1][gamma2][t] + double ****res_ij = (double ****)calloc(8*T, sizeof(double)); #ifdef TM_USE_MPI - double **mpi_res_ij = (double *)calloc(6*T, sizeof(double)); + double ****mpi_res_ij = (double ****)calloc(8*T, sizeof(double)); // send buffer for MPI_Gather - double **sC_ij = (double *)calloc(6*T, sizeof(double)); + double ****sC_ij = (double ****)calloc(8*T, sizeof(double)); #endif FILE *ofs; // output file stream @@ -382,113 +387,130 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, } // even-odd spinor fields for the light and heavy doublet correlators - // source+propagator, even-odd, 2 flavors - // psi = psi[(s,p)][eo][f][x][alpha][c] + // the gamma matrix in front specifies if we are working with + // psi_1 or psi_2 of eqs. (2.7, 2.8) https://arxiv.org/pdf/0804.1501.pdf + // INDICES: gamma matrix in front, source+propagator, even-odd, 2 flavors + // psi = psi[i_gamma][(s,p)][eo][f][x][alpha][c] // Note: propagator in th sense that it is D^{-1}*source after the inversion init_spinor_field(VOLUMEPLUSRAND / 2, 1); // initialize g_spinor_field so that I can copy it - spinor ****l_eo_spinor_field = (spinor ****)malloc(8 * VOLUME / 2); - spinor ****h_eo_spinor_field = (spinor ****)malloc(8 * VOLUME / 2); - // initalize to zero the source spinor fields (necessary??? isn't it enough to use the source - // generator?) - for (size_t i_sp = 0; i_sp < 2; i_sp++) { // source or propagator - - for (size_t i_eo = 0; i_eo < 2; i_eo++) { // even-odd - for (size_t i_f = 0; i_f < 2; i++) { // up-down flavor - assign(l_eo_spinor_field[0][i_eo][i_f], g_spinor_field[0], VOLUME / 2); - assign(h_eo_spinor_field[0][i_eo][i_f], g_spinor_field[0], VOLUME / 2); + spinor *****l_eo_spinor_field = (spinor *****)malloc(16 * VOLUME / 2); + spinor *****h_eo_spinor_field = (spinor *****)malloc(16 * VOLUME / 2); + + // propagator: gamma matrix in front, 2 flavors : psi = psi[i_gamma][f][x][alpha][c] + spinor ***l_propagator = (spinor ***)calloc(4 * VOLUME, sizeof(spinor)); + spinor ***h_propagator = (spinor ***)calloc(4 * VOLUME, sizeof(spinor)); + + // loop over (1, gamma_5) multiplying the stochastic source by it + for (size_t i_gamma = 0; i_gamma < 2; i_gamma++){ // psi_1 or psi_2 + + /* initalize the random sources: one source for each --> spin dilution */ + for (size_t i_f = 0; i_f < 2; i_f++) { + for (size_t src_d = 0; src_d < 4; src_d++) { + const unsigned int seed_i = src_d + measurement_list[id].seed; + // light doublet + eo_source_spinor_field_spin_diluted_oet_ts(l_eo_spinor_field[i_gamma][0][0][i_f], + l_eo_spinor_field[i_gamma][0][1][i_f], t0, + src_d, sample, traj, seed_i); + // heavy doublet + eo_source_spinor_field_spin_diluted_oet_ts(h_eo_spinor_field[i_gamma][0][0][i_f], + h_eo_spinor_field[i_gamma][0][1][i_f], t0, + src_d, sample, traj, seed_i); } } - } - // initalize the random sources - // one source for each --> spin dilution - for (size_t i_f = 0; i_f < 2; i_f++) { - for (size_t src_d = 0; src_d < 4; src_d++) { - const unsigned int seed_i = src_d + measurement_list[id].seed; - // light doublet - eo_source_spinor_field_spin_diluted_oet_ts(l_eo_spinor_field[0][0][i_f], - l_eo_spinor_field[0][1][i_f], t0, src_d, - sample, traj, seed_i); - // heavy doublet - eo_source_spinor_field_spin_diluted_oet_ts(h_eo_spinor_field[0][0][i_f], - h_eo_spinor_field[0][1][i_f], t0, src_d, - sample, traj, seed_i); + // heavy doublet: for each even-odd block, I multiply by (1 + i*tau_2) + // the basis for the inversion should be the same as for the light + // --> I will multiply later by the inverse, namely at the end of the inversion + for (size_t i_eo = 0; i_eo < 2; i_eo++) { + for (size_t i_f = 0; i_f < 2; i_f++) { + // (u,d) --> [(1+i*tau_2)/sqrt(2)] * (u,d) , stored at temporarely in the propagator + // spinors (used as dummy spinors) + mul_one_pm_itau2_and_div_by_sqrt2(h_eo_spinor_field[i_gamma][1][i_eo][i_f], + h_eo_spinor_field[i_gamma][1][i_eo][i_f + 1], + h_eo_spinor_field[i_gamma][0][i_eo][i_f], + h_eo_spinor_field[i_gamma][0][i_eo][i_f + 1], +1.0, + VOLUME / 2); + // assigning the result to the first components (the sources). + // The propagators will be overwritten with the inversion + assign(h_eo_spinor_field[i_gamma][0][i_eo][i_f], + h_eo_spinor_field[i_gamma][1][i_eo][i_f], VOLUME / 2); + } } - } - // heavy doublet: for each even-odd block, I multiply by (1 + i*tau_2) - // the basis for the inversion should be the same as for the light - // --> I will multiply later by the inverse, namely at the end of the inversion - for (size_t i_eo = 0; i_eo < 2; i_eo++) { - for (size_t i_f = 0; i_f < 2; i_f++) { - // (u,d) --> [(1+i*tau_2)/sqrt(2)] * (u,d) , stored at temporarely in the propagator - // spinors (used as dummy spinors) - mul_one_pm_itau2_and_div_by_sqrt2( - h_eo_spinor_field[1][i_eo][i_f], h_eo_spinor_field[1][i_eo][i_f + 1], - h_eo_spinor_field[0][i_eo][i_f], h_eo_spinor_field[0][i_eo][i_f + 1], - +1.0, VOLUME / 2); - // assigning the result to the first components (the sources). - // The propagators will be overwritten with the inversion - assign(h_eo_spinor_field[0][i_eo][i_f], h_eo_spinor_field[1][i_eo][i_f], VOLUME / 2); + if (i_gamma == 1) { // multiply by gamma_5 + for (size_t i_eo = 0; i_eo < 2; i_eo++) { + for (size_t i_f = 0; i_f < 2; i_f++) { + for (t = 0; t < T; t++) { + j = g_ipt[t][0][0][0]; + for (i = j; i < j + LX * LY * LZ; i++) { + _gamma5(phi, l_eo_spinor_field[i_gamma][0][i_eo][i_f][i]); + l_eo_spinor_field[i_gamma][1][i_eo][i_f][i] = phi; + _gamma5(phi, h_eo_spinor_field[i_gamma][0][i_eo][i_f][i]); + h_eo_spinor_field[i_gamma][1][i_eo][i_f][i] = phi; + } + } + } + } } - } - /* - assign the sources and propagator pointes for the operators - these need to be know when calling the inverter() method - */ + /* + assign the sources and propagator pointes for the operators + these need to be know when calling the inverter() method + */ + + // light doublet + optr1->sr0 = l_eo_spinor_field[i_gamma][0][0][0]; + optr1->sr1 = l_eo_spinor_field[i_gamma][0][0][1]; + optr1->sr2 = l_eo_spinor_field[i_gamma][0][1][0]; + optr1->sr3 = l_eo_spinor_field[i_gamma][0][1][1]; - // light doublet - optr1->sr0 = l_eo_spinor_field[0][0][0]; - optr1->sr1 = l_eo_spinor_field[0][0][1]; - optr1->sr2 = l_eo_spinor_field[0][1][0]; - optr1->sr3 = l_eo_spinor_field[0][1][1]; - - optr1->prop0 = l_eo_spinor_field[1][0][0]; - optr1->prop1 = l_eo_spinor_field[1][0][1]; - optr1->prop2 = l_eo_spinor_field[1][1][0]; - optr1->prop3 = l_eo_spinor_field[1][1][1]; - - // heavy doublet - optr2->sr0 = h_eo_spinor_field[0][0][0]; - optr2->sr1 = h_eo_spinor_field[0][0][1]; - optr2->sr2 = h_eo_spinor_field[0][1][0]; - optr2->sr3 = h_eo_spinor_field[0][1][1]; - - optr2->prop0 = h_eo_spinor_field[1][0][0]; - optr2->prop1 = h_eo_spinor_field[1][0][1]; - optr2->prop2 = h_eo_spinor_field[1][1][0]; - optr2->prop3 = h_eo_spinor_field[1][1][1]; - - // inverting the Dirac operators for the light and heavy doublet - // op_id = i1 or i2, index_start = 0, write_prop = 0 - optr1->inverter(i1, 0, 0); - optr2->inverter(i2, 0, 0); - - // conclude the change of basis for the heavy doublet - for (size_t i_eo = 0; i_eo < 2; i_eo++) { + optr1->prop0 = l_eo_spinor_field[i_gamma][1][0][0]; + optr1->prop1 = l_eo_spinor_field[i_gamma][1][0][1]; + optr1->prop2 = l_eo_spinor_field[i_gamma][1][1][0]; + optr1->prop3 = l_eo_spinor_field[i_gamma][1][1][1]; + + // heavy doublet + optr2->sr0 = h_eo_spinor_field[i_gamma][0][0][0]; + optr2->sr1 = h_eo_spinor_field[i_gamma][0][0][1]; + optr2->sr2 = h_eo_spinor_field[i_gamma][0][1][0]; + optr2->sr3 = h_eo_spinor_field[i_gamma][0][1][1]; + + optr2->prop0 = h_eo_spinor_field[i_gamma][1][0][0]; + optr2->prop1 = h_eo_spinor_field[i_gamma][1][0][1]; + optr2->prop2 = h_eo_spinor_field[i_gamma][1][1][0]; + optr2->prop3 = h_eo_spinor_field[i_gamma][1][1][1]; + + // inverting the Dirac operators for the light and heavy doublet + // op_id = i1 or i2, index_start = 0, write_prop = 0 + optr1->inverter(i1, 0, 0); + optr2->inverter(i2, 0, 0); + + // conclude the change of basis for the heavy doublet + for (size_t i_eo = 0; i_eo < 2; i_eo++) { + for (size_t i_f = 0; i_f < 2; i_f++) { + // (u,d) --> [(1+i*tau_2)/sqrt(2)] * (u,d) , stored at temporarely in the propagator + // spinors (used as dummy spinors) + mul_one_pm_itau2_and_div_by_sqrt2(h_eo_spinor_field[i_gamma][1][i_eo][i_f], + h_eo_spinor_field[i_gamma][1][i_eo][i_f + 1], + h_eo_spinor_field[i_gamma][0][i_eo][i_f], + h_eo_spinor_field[i_gamma][0][i_eo][i_f + 1], -1.0, + VOLUME / 2); + // assigning the result to the first components (the sources). + // The propagators will be overwritten with the inversion + assign(h_eo_spinor_field[i_gamma][0][i_eo][i_f], + h_eo_spinor_field[i_gamma][1][i_eo][i_f], VOLUME / 2); + } + } + + + // now we switch from even-odd representation to standard for (size_t i_f = 0; i_f < 2; i_f++) { - // (u,d) --> [(1+i*tau_2)/sqrt(2)] * (u,d) , stored at temporarely in the propagator - // spinors (used as dummy spinors) - mul_one_pm_itau2_and_div_by_sqrt2( - h_eo_spinor_field[1][i_eo][i_f], h_eo_spinor_field[1][i_eo][i_f + 1], - h_eo_spinor_field[0][i_eo][i_f], h_eo_spinor_field[0][i_eo][i_f + 1], - -1.0, VOLUME / 2); - // assigning the result to the first components (the sources). - // The propagators will be overwritten with the inversion - assign(h_eo_spinor_field[0][i_eo][i_f], h_eo_spinor_field[1][i_eo][i_f], VOLUME / 2); + convert_eo_to_lexic(l_propagator[i_gamma][i_f], l_eo_spinor_field[i_gamma][1][0][i_f], + l_eo_spinor_field[i_gamma][1][1][i_f]); + convert_eo_to_lexic(h_propagator[i_gamma][i_f], h_eo_spinor_field[i_gamma][1][0][i_f], + h_eo_spinor_field[i_gamma][1][1][i_f]); } - } - // now we switch from even-odd representation to standard - // propagator, 2 flavors : psi = psi[f][x][alpha][c] - spinor **l_propagator = (spinor **)malloc(2 * VOLUME * sizeof(spinor)); - spinor **h_propagator = (spinor **)malloc(2 * VOLUME * sizeof(spinor)); - for (size_t i_f = 0; i_f < 2; i_f++) { - convert_eo_to_lexic(l_propagator[i_f], l_eo_spinor_field[1][0][i_f], - l_eo_spinor_field[1][1][i_f]); - convert_eo_to_lexic(h_propagator[i_f], h_eo_spinor_field[1][0][i_f], - h_eo_spinor_field[1][1][i_f]); } /* @@ -503,11 +525,27 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, respa = 0.; resp4 = 0.; for (i = j; i < j + LX * LY * LZ; i++) { - res += _spinor_prod_re(l_propagator[0][i], l_propagator[0][i]); - _gamma0(phi, l_propagator[0][i]); - respa += _spinor_prod_re(l_propagator[0][i], phi); + res += _spinor_prod_re(l_propagator[0][0][i], l_propagator[0][0][i]); + _gamma0(phi, l_propagator[0][0][i]); + respa += _spinor_prod_re(l_propagator[0][0][i], phi); _gamma5(phi, phi); - resp4 += _spinor_prod_im(l_propagator[0][i], phi); + resp4 += _spinor_prod_im(l_propagator[0][0][i], phi); + + // if (measurement_list[id].measure_heavy_mesons == 1) { + // for (size_t i_f = 0; i_f < 2; i_f++) { + // for (size_t i_gamma = 0; i_gamma < 2; i_gamma++) { + // for (size_t j_gamma = 0; j_gamma < 2; j_gamma++) { + // // phi = h_propagator[i_gamma][1 - i_f][i]; + // // if (i_gammaj_gamma == 1) { // gamma_5 + // // _gamma5(phi, phi); + // // } + + // // C_ij[i_f][i_gamma][j_gamma][t] += + // // _spinor_prod_re(l_propagator[i_gamma][i_f][i], phi); + // } + // } + // } + // } } #if defined TM_USE_MPI diff --git a/meas/correlators.h b/meas/correlators.h index 8fa2a9990..3f817734f 100644 --- a/meas/correlators.h +++ b/meas/correlators.h @@ -23,6 +23,11 @@ #include +#include "init/init_spinor_field.h" +#include "linalg/assign.h" +#include "operator/tm_operators.h" + + /* measurement of the correlators involving the light doublet (see tmLQCD documentation)*/ void light_correlators_measurement(const int traj, const int id, const int ieo); From 02d89c095d35a716f2ccc28c31379524126489e1 Mon Sep 17 00:00:00 2001 From: simone-romiti Date: Tue, 27 Jun 2023 18:32:37 +0200 Subject: [PATCH 12/51] documentation on the theoretical form of heavy meson correlators --- doc/acta-ecologica-sinica.csl | 14 ++ doc/bibliography.bib | 24 +++ doc/mathjax-config.html | 31 ++++ doc/omeas_heavy_mesons.qmd | 279 ++++++++++++++++++++++++++++++++++ 4 files changed, 348 insertions(+) create mode 100644 doc/acta-ecologica-sinica.csl create mode 100644 doc/mathjax-config.html create mode 100644 doc/omeas_heavy_mesons.qmd diff --git a/doc/acta-ecologica-sinica.csl b/doc/acta-ecologica-sinica.csl new file mode 100644 index 000000000..1d78dcb63 --- /dev/null +++ b/doc/acta-ecologica-sinica.csl @@ -0,0 +1,14 @@ + + diff --git a/doc/bibliography.bib b/doc/bibliography.bib index 1e4fcf20c..341c50793 100644 --- a/doc/bibliography.bib +++ b/doc/bibliography.bib @@ -27,6 +27,18 @@ @article{Boyle:2017xcy SLACcitation = "%%CITATION = ARXIV:1711.04883;%%" } +@article{baron2011computing, + title={{Computing K and D meson masses with $N_f= 2 + 1 + 1$ twisted mass lattice QCD}}, + author={Baron, Remi and Boucaud, Philippe and Carbonell, Jaume and Drach, Vincent and Farchioni, Federico and Herdoiza, Gregorio and Jansen, Karl and Michael, Chris and Montvay, Istvan and Pallante, Elisabetta and others}, + journal={Computer Physics Communications}, + volume={182}, + number={2}, + pages={299--316}, + year={2011}, + publisher={Elsevier}, + doi = {https://doi.org/10.1016/j.cpc.2010.10.004} +} + @article{Babich:2011np, archiveprefix = "arXiv", author = "Babich, R. and Clark, M.A. and Joo, B. and Shi, G. and Brower, R.C. and others", @@ -139,6 +151,18 @@ @article{Abdel-Rehim:2004gx year = "2005" } +@article{foley2005practical, + title={Practical all-to-all propagators for lattice QCD}, + author={Foley, Justin and Juge, K Jimmy and Cais, Alan {\'O} and Peardon, Mike and Ryan, Sin{\'e}ad M and Skullerud, Jon-Ivar and TrinLat Collaboration and others}, + journal={Computer physics communications}, + volume={172}, + number={3}, + pages={145--162}, + year={2005}, + publisher={Elsevier}, + doi = {10.1016/j.cpc.2005.06.008} +} + @article{Abdel-Rehim:2005gz, author = "Abdel-Rehim, Abdou M. and Lewis, Randy and Woloshyn, R. M.", eprint = "hep-lat/0503007", diff --git a/doc/mathjax-config.html b/doc/mathjax-config.html new file mode 100644 index 000000000..8fc201d95 --- /dev/null +++ b/doc/mathjax-config.html @@ -0,0 +1,31 @@ + + \ No newline at end of file diff --git a/doc/omeas_heavy_mesons.qmd b/doc/omeas_heavy_mesons.qmd new file mode 100644 index 000000000..bb66be4c2 --- /dev/null +++ b/doc/omeas_heavy_mesons.qmd @@ -0,0 +1,279 @@ +--- +title: Online measurements of heavy meson correlators +author: Simone Romiti +date: last-modified +jupyter: python3 +format-links: false # hide the existence of other formats +format: + html: + embed-resources: true # standalon html + html-math-method: mathjax # use the common latex commands + include-in-header: mathjax-config.html # equation numbering with sections + fontsize: 14pt + pdf: + pdf-engine: pdflatex + fontsize: 12pt +bibliography: bibliography.bib +csl: acta-ecologica-sinica.csl +fontsize: 16pt +--- + +`tmLQCD`can compute the correlators for the heavy mesons $K$ and $D$. +The twisted mass formulation of the heavy doublet $(s, c)$ is such that $K$ and $D$ mix in the correlators @baron2011computing. +In fact, the Dirac operator is not diagonal in flavor, +and the extraction of their masses requires the evaluation of a $(2 \times 2) \otimes (2 \times 2)$ matrix of correlators. +In the following we use the twisted basis $\chi$ for fermion fields: + +\begin{align} +\label{eq:LightFlavorSpinorFields} +\chi_{\ell} &= +\chi_{u} + \chi_{d} = + \begin{bmatrix} + \hat{\chi}_{u} \\ + 0 + \end{bmatrix} + + + \begin{bmatrix} + 0 \\ + \hat{\chi}_{d} + \end{bmatrix} +\, , \\[1em] +\label{eq:HeavyFlavorSpinorFields} +\chi_{h} &= +\chi_{c} + \chi_{s} = + \begin{bmatrix} + \hat{\chi}_{c} \\ + 0 + \end{bmatrix} + + + \begin{bmatrix} + 0 \\ + \hat{\chi}_{s} + \end{bmatrix} +\, . +\end{align} + + +## Correlators for the $K$ and $D$ + +The required correlators are given by the following +expectation values on the interacting vacuum +${\bra{\Omega} \cdot \ket{\Omega} = \braket{\cdot}}$: + +\begin{equation} +\begin{split} +{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t) &= +\eta_1 \frac{1}{V} +\sum_{\vec{x}} +\mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) +\\ +&= +- \eta_{1} \eta_{2} +\frac{1}{V} +\sum_{\vec{x}} +\braket{ +[\bar{\chi}_{\ell_{\bar{i}}} \Gamma_1 \chi_{h_i}](x) +[\bar{\chi}_{\ell_{\bar{j}}} \Gamma_2 \chi_{h_j}]^{\dagger}(0) +} +\, , +\end{split} +\end{equation} + +where $h_i=c,s$, $\Gamma_i = 1, \gamma_5$. +The minus sign will vanish when doing the Wick contractions, +while +$\eta_{\mathbb{1}} = \pm 1$ and $\eta_{\gamma_5} = \pm i$ +are used just to compensate the sign change when daggering the spinor bilinears at the source: + +\begin{equation} +\eta_\Gamma (\bar{\chi}_a \Gamma \chi_b)^\dagger = +\eta_\Gamma \bar{\chi}_b \gamma_0 \Gamma^\dagger \gamma_0 \chi_a = +\bar{\chi}_b \Gamma \chi_a +\, . +\end{equation} + +The index $\bar{i}$ ($\bar{j}$) is the flavor index in the doublet that is opposite to $i$ ($j$): + +\begin{equation} +h_i=c,s \to i = 0,1 \to \bar{i} = 1,0 \to \ell_{\bar{i}} = d,u +\, . +\end{equation} + +We now write the explicit Wick contractions for the object: + +\begin{equation} +\begin{split} +\mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) &= +- \eta_{2} +\braket{ +[\bar{\chi}_{\ell_{\bar{i}}} \Gamma_1 \chi_{h_i}](x) +[\bar{\chi}_{\ell_{\bar{j}}} \Gamma_2 \chi_{h_j}]^{\dagger}(0) +} +\\ +&= - \braket{ +[\bar{\chi}_{\ell_{\bar{i}}} \Gamma_1 \chi_{h_i}](x) +[\bar{\chi}_{h_j} \Gamma_2 \chi_{\ell_{\bar{j}}}](0) +} +\end{split} +\end{equation} + + +A few observations are useful here: + +- In flavor space, + ${\sigma_1 = + \begin{bmatrix} + 0 & 1 \\ + 1 & 0 + \end{bmatrix} + }$ + switches between the up and down flavor. + Moreover, $\sigma_1 = \sigma_1^\dagger$. + +- The spinor fields $\chi_{u,d}$ and $\chi_{c,s}$ of eq. +\eqref{eq:LightFlavorSpinorFields} and +\eqref{eq:HeavyFlavorSpinorFields} +can be obtained with the projector: + +\begin{equation} +P_{i} = \frac{1}{2} [1 + (-1)^i \sigma_3] \, , \, i=0,1 +\, , +\end{equation} + +where ${\sigma_3 = + \begin{bmatrix} + 1 & 0 \\ + 0 & -1 + \end{bmatrix} + }$. + As a projector, it satisfies $P_i^2 = P_i$. + Moreover, $\sigma_3 = \sigma_3^\dagger$, + hence $P_i^\dagger = P_i$. + +- Obviously, $P_i$ commutes with the $\gamma$ matrices asthey act on different spaces. + +## Wick contractions + +Using the above remarks, +we can write: + +\begin{equation} +\begin{split} +\mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) &= +- \braket{ +[\bar{\chi}_{\ell_{\bar{i}}} \Gamma_1 \chi_{h_i}](x) +[\bar{\chi}_{h_j} \Gamma_2 \chi_{\ell_{\bar{j}}}](0) +} +\\ +&= +- \braket{ +[\bar{\chi}_{\ell} (\tau_1 P_i) \Gamma_1 \chi_{h}](x) +[\bar{\chi}_{h} (P_j \tau_1) \Gamma_2 \chi_{\ell}](0) +} +\, . +\end{split} +\end{equation} + +An implicit summation on flavor indices is understood: + +\begin{equation} +\mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) = +- \braket{ +[(\bar{\chi}_{\ell})_{f_1} (\tau_1 P_i)_{f_1 f_2} \Gamma_1 (\chi_{h})_{f_2}](x) +[(\bar{\chi}_{h})_{f_3} (P_j \tau_1)_{f_3 f_4} \Gamma_2 (\chi_{\ell})_{f_4}](0) +} +\, . +\end{equation} + + +If we now call $S = D^{-1}$ the inverse of the Dirac operator, +and use Wick's theorem: + +\begin{equation} +\braket{\psi_{a}(x) \bar{\psi}_{b}(0)} = S_{ab}(x|0) \, , +\end{equation} + +where $a$ and $b$ are a shortcut for the other indices of the spinor (spin, flavor, color, etc.). +we write: + +\begin{equation} +\mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) = +(S_\ell)_{\substack{f_1 f_2 \\ \alpha_1 \alpha_2}} (0|x) +(\tau_1 P_i)_{f_1 f_2} (\Gamma_1)_{\alpha_2 \alpha_3} +(S_h)_{\substack{f_2 f_3 \\ \alpha_3 \alpha_4}} (x|0) +(P_j \tau_1)_{f_3 f_4} (\Gamma_2)_{\alpha_4 \alpha_1} +\, . +\end{equation} + + +## Stochastic sampling + +Analogously to @foley2005practical, +we now use $N_r$ stochastic samples in order to approximate $S$. +The difference here is that the dilution is not on time but on Dirac index (spin). +Therefore, our estimator for $S$ is +(cf. eqs. (5) and (7) of @foley2005practical): + +\begin{equation} +(S_\phi)_{\substack{f_1 f_2 \\ \alpha_1 \alpha_2}}(x|y) +\approx +\sum_{\beta=1}^{N_D=4} +\braket{ + (\psi_\phi^{(\beta)})_{\substack{f_1 \\ \alpha_1}}(x) + (\eta_\phi^{(\beta)})^*_{\substack{f_2 \\ \alpha_2}}(y) +} +\, , +\end{equation} + +where $\braket{\cdot}$ here denotes the expectation value over the $N_r$ stochastic samples. +The sources are such that +${\eta^{(\beta)}_{\alpha} = \delta_{\alpha \beta}}$, +and $\psi^{\beta}$ are the solutions to: + +\begin{equation} +\begin{split} +&(D_{\phi})_{\substack{f_1 f_2 \\ \alpha_1 \alpha_2}}(x|y) +\, +(\psi_\phi)^{\beta}_{\substack{f_2 \\ \alpha_2}}(y) = +(\eta_\phi)^{\beta}_{\substack{f_1 \\ \alpha_1}}(x) +\\[1em] +& \implies \, \, +(\psi_\phi)^{\beta}_{\substack{f_1 \\ \alpha_1}}(x) = +(S_{\phi})_{\substack{f_1 f_2 \\ \alpha_1 \alpha_2}}(x|y) +\, +(\eta_\phi)^{\beta}_{\substack{f_2 \\ \alpha_1}}(y) +\end{split} +\end{equation} + + + +Therefore, back to our correlators, we can write: + +\begin{equation} +\begin{split} +\mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) += +\sum_{\beta_1, \beta_2} +& +(\psi_{\ell}^{(\beta_1)})_{\substack{f_1 \\ \alpha_1}}(0) +(\eta_{\ell}^{(\beta_1)})^*_{\substack{f_2 \\ \alpha_2}}(x) +(\tau_1 P_i)_{f_1 f_2} (\Gamma_1)_{\alpha_2 \alpha_3} +\\ +\times +& +(\psi_{h}^{(\beta_2)})_{\substack{f_2 \\ \alpha_2}}(x) +(\eta_{h}^{(\beta_2)})^*_{\substack{f_3 \\ \alpha_3}}(0) +(P_j \tau_1)_{f_3 f_4} (\Gamma_2)_{\alpha_4 \alpha_1} +\, . +\end{split} +\end{equation} + + +## Implementation + +See comments in the code: `correlators.c`. + + + + + From c10659c8935f1bc058459d63a7ee7279952abd8e Mon Sep 17 00:00:00 2001 From: simone-romiti Date: Tue, 27 Jun 2023 23:08:44 +0200 Subject: [PATCH 13/51] implementing. next: express correlator using _spinor_prod_re() or _spinor_prod_im() --- doc/omeas_heavy_mesons.qmd | 10 +- meas/correlators.c | 316 +++++++++++++++++++++---------------- 2 files changed, 189 insertions(+), 137 deletions(-) diff --git a/doc/omeas_heavy_mesons.qmd b/doc/omeas_heavy_mesons.qmd index bb66be4c2..0d7146f56 100644 --- a/doc/omeas_heavy_mesons.qmd +++ b/doc/omeas_heavy_mesons.qmd @@ -6,7 +6,7 @@ jupyter: python3 format-links: false # hide the existence of other formats format: html: - embed-resources: true # standalon html + embed-resources: true # standalone html html-math-method: mathjax # use the common latex commands include-in-header: mathjax-config.html # equation numbering with sections fontsize: 14pt @@ -193,12 +193,12 @@ and use Wick's theorem: \braket{\psi_{a}(x) \bar{\psi}_{b}(0)} = S_{ab}(x|0) \, , \end{equation} -where $a$ and $b$ are a shortcut for the other indices of the spinor (spin, flavor, color, etc.). +where $a$ and $b$ are a shortcut for the other indices of the spinor (spin, flavor, color, etc.), we write: \begin{equation} \mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) = -(S_\ell)_{\substack{f_1 f_2 \\ \alpha_1 \alpha_2}} (0|x) +(S_\ell)_{\substack{f_4 f_1 \\ \alpha_1 \alpha_2}} (0|x) (\tau_1 P_i)_{f_1 f_2} (\Gamma_1)_{\alpha_2 \alpha_3} (S_h)_{\substack{f_2 f_3 \\ \alpha_3 \alpha_4}} (x|0) (P_j \tau_1)_{f_3 f_4} (\Gamma_2)_{\alpha_4 \alpha_1} @@ -255,8 +255,8 @@ Therefore, back to our correlators, we can write: = \sum_{\beta_1, \beta_2} & -(\psi_{\ell}^{(\beta_1)})_{\substack{f_1 \\ \alpha_1}}(0) -(\eta_{\ell}^{(\beta_1)})^*_{\substack{f_2 \\ \alpha_2}}(x) +(\psi_{\ell}^{(\beta_1)})_{\substack{f_4 \\ \alpha_1}}(0) +(\eta_{\ell}^{(\beta_1)})^*_{\substack{f_1 \\ \alpha_2}}(x) (\tau_1 P_i)_{f_1 f_2} (\Gamma_1)_{\alpha_2 \alpha_3} \\ \times diff --git a/meas/correlators.c b/meas/correlators.c index df4866021..831980143 100644 --- a/meas/correlators.c +++ b/meas/correlators.c @@ -253,6 +253,45 @@ void light_correlators_measurement(const int traj, const int id, const int ieo) return; } + +// Function to allocate memory for a pointer of pointers for an array of d dimensions +void* allocateMultiDimensionalArray(int* sizes, int numDimensions, size_t elementSize) { + if (numDimensions == 1) { + void* array = malloc(sizes[0] * sizeof(elementSize)); + + if (array == NULL) { + printf("Memory allocation failed for dimension 0!"); + return NULL; + } + + return array; + } + + void** pointerArray = (void**)malloc(sizes[0] * sizeof(void*)); + + if (pointerArray == NULL) { + printf("Memory allocation failed for dimension %d!", numDimensions - 1); + return NULL; + } + + for (int i = 0; i < sizes[0]; i++) { + pointerArray[i] = allocateMultiDimensionalArray(sizes + 1, numDimensions - 1); + + if (pointerArray[i] == NULL) { + printf("Memory allocation failed for subarray %d in dimension %d!", i, numDimensions - 1); + // Free memory allocated so far + for (int j = 0; j < i; j++) { + free(pointerArray[j]); + } + free(pointerArray); + return NULL; + } + } + + return pointerArray; +} + + /****************************************************** * * This routine computes the correlator matrix (), @@ -305,15 +344,14 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, /* heavy-light correlator: dummy variables */ - // the number of independent correlators is 8 = 2 * (2*2) - // 2: strange or charm flavor - // 2*2: all combinations of (1, gamma_5) - double ****C_ij = (double ****)calloc(8*T, sizeof(double)); // C[i_f][gamma1][gamma2][t] - double ****res_ij = (double ****)calloc(8*T, sizeof(double)); + // the number of independent correlators is 16 = (2*2)_{h_1 h_2} * (2*2)_{Gamma_1 Gamma_2} + // h_i: c,s, Gamma = (1, gamma_5) + double *****C_hihj_Gamma1Gamma2 = (double *****) allocateMultiDimensionalArray({2,2,2,2,T}, 5, sizeof(double)); + double *****res_hihj_Gamma1Gamma2 = (double *****) allocateMultiDimensionalArray({2,2,2,2,T}, 5, sizeof(double)); #ifdef TM_USE_MPI - double ****mpi_res_ij = (double ****)calloc(8*T, sizeof(double)); + double *****mpi_res_ij = (double *****) allocateMultiDimensionalArray({2,2,2,2,T}, 5, sizeof(double)); // send buffer for MPI_Gather - double ****sC_ij = (double ****)calloc(8*T, sizeof(double)); + double *****sC_ij = (double *****) allocateMultiDimensionalArray({2,2,2,2,T}, 5, sizeof(double)); #endif FILE *ofs; // output file stream @@ -334,15 +372,20 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, } // selecting the operators i1 and i2 from the list of operators initialized before - operator* optr1 = & operator_list[i1]; - operator* optr2 = & operator_list[i2]; + operator* optr1 = & operator_list[i1]; // light doublet + operator* optr2 = & operator_list[i2]; // heavy c,s doublet - bool b1 = (optr1->type != DBTMWILSON && optr1->type != DBCLOVER); - if (b1) { + bool b1 = (optr->type != TMWILSON && optr->type != WILSON && optr->type != CLOVER); + bool b2 = (optr2->type != DBTMWILSON && optr2->type != DBCLOVER); + if(b1 || b2) { if (g_proc_id == 0) { - fprintf(stderr, - "Warning! correlator online measurement currently only implemented for DBTMWILSON, " - "DBCLOVER\n"); + if(b1){ + fprintf(stderr, "Warning! optr1 should be one of the following: TMWILSON, WILSON and CLOVER\n"); + fprintf(stderr, "Cannot perform correlator online measurement!\n"); + } + if (b2) { + fprintf(stderr, "Warning! optr2 should be one of the following: DBTMWILSON, DBCLOVER\n"); + } fprintf(stderr, "Cannot perform correlator online measurement!\n"); } tm_stopwatch_pop(&g_timers, 0, 0, ""); // timer for profiling @@ -386,136 +429,147 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, optr1->kappa, optr1->mubar, optr1->epsbar); } + ///////////// OLD COMMENT + ///////////// the gamma matrix in front specifies if we are working with + ///////////// psi_1 or psi_2 of eqs. (2.7, 2.8) https://arxiv.org/pdf/0804.1501.pdf + //////////// END OLD COMMENT // even-odd spinor fields for the light and heavy doublet correlators - // the gamma matrix in front specifies if we are working with - // psi_1 or psi_2 of eqs. (2.7, 2.8) https://arxiv.org/pdf/0804.1501.pdf - // INDICES: gamma matrix in front, source+propagator, even-odd, 2 flavors - // psi = psi[i_gamma][(s,p)][eo][f][x][alpha][c] - // Note: propagator in th sense that it is D^{-1}*source after the inversion - init_spinor_field(VOLUMEPLUSRAND / 2, 1); // initialize g_spinor_field so that I can copy it - spinor *****l_eo_spinor_field = (spinor *****)malloc(16 * VOLUME / 2); - spinor *****h_eo_spinor_field = (spinor *****)malloc(16 * VOLUME / 2); - - // propagator: gamma matrix in front, 2 flavors : psi = psi[i_gamma][f][x][alpha][c] - spinor ***l_propagator = (spinor ***)calloc(4 * VOLUME, sizeof(spinor)); - spinor ***h_propagator = (spinor ***)calloc(4 * VOLUME, sizeof(spinor)); + // INDICES: source+propagator, doublet, spin dilution index, even-odd, flavor, position (+ Dirac, color) + // psi = (psi[(s,p)][phi][beta][eo][f][x])[alpha][c] // last 3 indices are proper of the spinor struct + // Note: propagator in the sense that it is D^{-1}*source after the inversion - // loop over (1, gamma_5) multiplying the stochastic source by it - for (size_t i_gamma = 0; i_gamma < 2; i_gamma++){ // psi_1 or psi_2 - - /* initalize the random sources: one source for each --> spin dilution */ - for (size_t i_f = 0; i_f < 2; i_f++) { - for (size_t src_d = 0; src_d < 4; src_d++) { + // unnecessary: // init_spinor_field(VOLUMEPLUSRAND / 2, 1); // initialize g_spinor_field so that I can copy it + + spinor ******arr_eo_spinor = (spinor ******)allocateMultiDimensionalArray({2,2,4,2,2,VOLUME/2}, 6, sizeof(spinor)); +// spinor ******h_arr_eo_spinor = (spinor ******)allocateMultiDimensionalArray({2,2,4,2,2,VOLUME/2}, 6, sizeof(spinor)); + + // (no even-odd): source+propagator, doublet, spin dilution index, even-odd, flavor, position (+ Dirac, color) + // (psi[phi][beta][f][x])[alpha][c] // last 3 indices are proper of the spinor struct + spinor ****arr_spinor = (spinor ****) allocateMultiDimensionalArray({2,4,2,VOLUME}, 4, sizeof(spinor)); +// spinor ****h_propagator = (spinor ****) allocateMultiDimensionalArray({2,4,2,VOLUME/2}, 4, sizeof(spinor)); + + /* initalize the random sources: one source for each Dirc index beta=src_d --> spin dilution + */ + for (size_t i_phi = 0; i_phi < 2; i_phi++) { // doublet: light or heavy + for (size_t src_d = 0; src_d < 4; src_d++) { // spin dilution index + for (size_t i_f = 0; i_f < 2; i_f++) { // flavor index of the doublet const unsigned int seed_i = src_d + measurement_list[id].seed; // light doublet - eo_source_spinor_field_spin_diluted_oet_ts(l_eo_spinor_field[i_gamma][0][0][i_f], - l_eo_spinor_field[i_gamma][0][1][i_f], t0, - src_d, sample, traj, seed_i); - // heavy doublet - eo_source_spinor_field_spin_diluted_oet_ts(h_eo_spinor_field[i_gamma][0][0][i_f], - h_eo_spinor_field[i_gamma][0][1][i_f], t0, + eo_source_spinor_field_spin_diluted_oet_ts(arr_eo_spinor[0][i_phi][src_d][0][i_f], + arr_eo_spinor[0][i_phi][src_d][1][i_f], t0, src_d, sample, traj, seed_i); } } + } - // heavy doublet: for each even-odd block, I multiply by (1 + i*tau_2) - // the basis for the inversion should be the same as for the light - // --> I will multiply later by the inverse, namely at the end of the inversion + // heavy doublet: for each even-odd block, I multiply by (1 + i*tau_2)/sqrt(2) + // the basis for the inversion should be the same as for the light + // --> I will multiply later by the inverse, namely at the end of the inversion + for (size_t src_d = 0; src_d < 4; src_d++) { // spin dilution index for (size_t i_eo = 0; i_eo < 2; i_eo++) { - for (size_t i_f = 0; i_f < 2; i_f++) { - // (u,d) --> [(1+i*tau_2)/sqrt(2)] * (u,d) , stored at temporarely in the propagator + // (c,s) --> [(1+i*tau_2)/sqrt(2)] * (c,s) , stored at temporarely in the propagator // spinors (used as dummy spinors) - mul_one_pm_itau2_and_div_by_sqrt2(h_eo_spinor_field[i_gamma][1][i_eo][i_f], - h_eo_spinor_field[i_gamma][1][i_eo][i_f + 1], - h_eo_spinor_field[i_gamma][0][i_eo][i_f], - h_eo_spinor_field[i_gamma][0][i_eo][i_f + 1], +1.0, + mul_one_pm_itau2_and_div_by_sqrt2(arr_eo_spinor[1][1][src_d][i_eo][0], + arr_eo_spinor[1][1][src_d][i_eo][0 + 1], + arr_eo_spinor[0][1][src_d][i_eo][0], + arr_eo_spinor[0][1][src_d][i_eo][0 + 1], +1.0, VOLUME / 2); + for (size_t i_f = 0; i_f < 2; i_f++) { // assigning the result to the first components (the sources). // The propagators will be overwritten with the inversion - assign(h_eo_spinor_field[i_gamma][0][i_eo][i_f], - h_eo_spinor_field[i_gamma][1][i_eo][i_f], VOLUME / 2); + assign(arr_eo_spinor[0][1][src_d][i_eo][i_f], + arr_eo_spinor[1][1][src_d][i_eo][i_f], VOLUME / 2); } } + } - if (i_gamma == 1) { // multiply by gamma_5 - for (size_t i_eo = 0; i_eo < 2; i_eo++) { - for (size_t i_f = 0; i_f < 2; i_f++) { - for (t = 0; t < T; t++) { - j = g_ipt[t][0][0][0]; - for (i = j; i < j + LX * LY * LZ; i++) { - _gamma5(phi, l_eo_spinor_field[i_gamma][0][i_eo][i_f][i]); - l_eo_spinor_field[i_gamma][1][i_eo][i_f][i] = phi; - _gamma5(phi, h_eo_spinor_field[i_gamma][0][i_eo][i_f][i]); - h_eo_spinor_field[i_gamma][1][i_eo][i_f][i] = phi; - } - } - } + /* + assign the sources and propagator pointes for the operators + these need to be know when calling the inverter() method + */ + // psi = (psi[(s,p)][phi][beta][eo][f][x])[alpha][c] // last 3 indices are proper of the spinor struct + + for (size_t src_d = 0; src_d < 4; src_d++) { // spin dilution index + /* light doublet */ + + // up + + // sorces + optr1->sr0 = arr_eo_spinor[0][0][src_d][0][0]; + optr1->sr1 = arr_eo_spinor[0][0][src_d][1][0]; + // propagators + optr1->prop0 = arr_eo_spinor[1][0][src_d][0][0]; + optr1->prop1 = arr_eo_spinor[1][0][src_d][1][0]; + + optr1->inverter(i1, 0, 0); // inversion for the up flavor + + // inversion of the light doublet only inverts the up block (the operator is diagonal in flavor) + // down components in flavor will be empty + optr1->DownProp = 1; + + // sources + optr1->sr2 = arr_eo_spinor[0][0][src_d][0][1]; + optr1->sr3 = arr_eo_spinor[0][0][src_d][1][1]; + //propagator + optr1->prop2 = arr_eo_spinor[1][0][src_d][0][1]; + optr1->prop3 = arr_eo_spinor[1][0][src_d][1][1]; + + optr1->DownProp = 0; //restoring to default + + optr1->inverter(i1, 0, 0); //inversion for the down + + /* heavy doublet */ + + optr1->sr0 = arr_eo_spinor[0][1][src_d][0][0]; + optr1->sr1 = arr_eo_spinor[0][1][src_d][1][0]; + optr1->sr2 = arr_eo_spinor[0][1][src_d][0][1]; + optr1->sr3 = arr_eo_spinor[0][1][src_d][1][1]; + + optr1->prop0 = arr_eo_spinor[1][1][src_d][0][0]; + optr1->prop1 = arr_eo_spinor[1][1][src_d][1][0]; + optr1->prop2 = arr_eo_spinor[1][1][src_d][0][1]; + optr1->prop3 = arr_eo_spinor[1][1][src_d][1][1]; + + optr2->inverter(i2, 0, 0); // inversion for both flavor components + } + + + // conclude the change of basis for the heavy doublet + for (size_t src_d = 0; src_d < 4; src_d++) { // spin dilution index + for (size_t i_eo = 0; i_eo < 2; i_eo++) { + // (c,s) --> [(1-i*tau_2)/sqrt(2)] * (c,s) , stored at temporarely in the propagator + // spinors (used as dummy spinors) + mul_one_pm_itau2_and_div_by_sqrt2(arr_eo_spinor[1][1][src_d][i_eo][0], + arr_eo_spinor[1][1][src_d][i_eo][0 + 1], + arr_eo_spinor[0][1][src_d][i_eo][0], + arr_eo_spinor[0][1][src_d][i_eo][0 + 1], -1.0, + VOLUME / 2); + for (size_t i_f = 0; i_f < 2; i_f++) { + // assigning the result to the first components (the sources). + // The propagators will be overwritten with the inversion + assign(arr_eo_spinor[0][1][src_d][i_eo][i_f], + arr_eo_spinor[1][1][src_d][i_eo][i_f], VOLUME / 2); } } + } - /* - assign the sources and propagator pointes for the operators - these need to be know when calling the inverter() method - */ - - // light doublet - optr1->sr0 = l_eo_spinor_field[i_gamma][0][0][0]; - optr1->sr1 = l_eo_spinor_field[i_gamma][0][0][1]; - optr1->sr2 = l_eo_spinor_field[i_gamma][0][1][0]; - optr1->sr3 = l_eo_spinor_field[i_gamma][0][1][1]; - - optr1->prop0 = l_eo_spinor_field[i_gamma][1][0][0]; - optr1->prop1 = l_eo_spinor_field[i_gamma][1][0][1]; - optr1->prop2 = l_eo_spinor_field[i_gamma][1][1][0]; - optr1->prop3 = l_eo_spinor_field[i_gamma][1][1][1]; - - // heavy doublet - optr2->sr0 = h_eo_spinor_field[i_gamma][0][0][0]; - optr2->sr1 = h_eo_spinor_field[i_gamma][0][0][1]; - optr2->sr2 = h_eo_spinor_field[i_gamma][0][1][0]; - optr2->sr3 = h_eo_spinor_field[i_gamma][0][1][1]; - - optr2->prop0 = h_eo_spinor_field[i_gamma][1][0][0]; - optr2->prop1 = h_eo_spinor_field[i_gamma][1][0][1]; - optr2->prop2 = h_eo_spinor_field[i_gamma][1][1][0]; - optr2->prop3 = h_eo_spinor_field[i_gamma][1][1][1]; - - // inverting the Dirac operators for the light and heavy doublet - // op_id = i1 or i2, index_start = 0, write_prop = 0 - optr1->inverter(i1, 0, 0); - optr2->inverter(i2, 0, 0); - - // conclude the change of basis for the heavy doublet - for (size_t i_eo = 0; i_eo < 2; i_eo++) { + // now we switch from even-odd representation to standard + for (size_t i_sp = 0; i_sp < 2; i_sp++) { // source or sink + for (size_t i_phi = 0; i_phi < 2; i_phi++) { // doublet index + for (size_t src_d = 0; src_d < 4; src_d++) { // spin dilution index for (size_t i_f = 0; i_f < 2; i_f++) { - // (u,d) --> [(1+i*tau_2)/sqrt(2)] * (u,d) , stored at temporarely in the propagator - // spinors (used as dummy spinors) - mul_one_pm_itau2_and_div_by_sqrt2(h_eo_spinor_field[i_gamma][1][i_eo][i_f], - h_eo_spinor_field[i_gamma][1][i_eo][i_f + 1], - h_eo_spinor_field[i_gamma][0][i_eo][i_f], - h_eo_spinor_field[i_gamma][0][i_eo][i_f + 1], -1.0, - VOLUME / 2); - // assigning the result to the first components (the sources). - // The propagators will be overwritten with the inversion - assign(h_eo_spinor_field[i_gamma][0][i_eo][i_f], - h_eo_spinor_field[i_gamma][1][i_eo][i_f], VOLUME / 2); + convert_eo_to_lexic(arr_spinor[i_sp][i_phi][src_d][i_f], + arr_eo_spinor[i_sp][i_phi][src_d][0][i_f], + arr_eo_spinor[i_sp][i_phi][src_d][1][i_f]); } } - - - // now we switch from even-odd representation to standard - for (size_t i_f = 0; i_f < 2; i_f++) { - convert_eo_to_lexic(l_propagator[i_gamma][i_f], l_eo_spinor_field[i_gamma][1][0][i_f], - l_eo_spinor_field[i_gamma][1][1][i_f]); - convert_eo_to_lexic(h_propagator[i_gamma][i_f], h_eo_spinor_field[i_gamma][1][0][i_f], - h_eo_spinor_field[i_gamma][1][1][i_f]); } - } + free(arr_eo_spinor); // freeing up space: eo spinors not needed anymore /* Now that I have all the propagators (all in the basis of - https://arxiv.org/pdf/1005.2042.pdf) I can build the correlators of eq. 20 + https://arxiv.org/pdf/1005.2042.pdf) I can build the correlators of eq. (20) */ /* now we sum only over local space for every t */ @@ -531,21 +585,19 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, _gamma5(phi, phi); resp4 += _spinor_prod_im(l_propagator[0][0][i], phi); - // if (measurement_list[id].measure_heavy_mesons == 1) { - // for (size_t i_f = 0; i_f < 2; i_f++) { - // for (size_t i_gamma = 0; i_gamma < 2; i_gamma++) { - // for (size_t j_gamma = 0; j_gamma < 2; j_gamma++) { - // // phi = h_propagator[i_gamma][1 - i_f][i]; - // // if (i_gammaj_gamma == 1) { // gamma_5 - // // _gamma5(phi, phi); - // // } - - // // C_ij[i_f][i_gamma][j_gamma][t] += - // // _spinor_prod_re(l_propagator[i_gamma][i_f][i], phi); - // } - // } - // } - // } + for (size_t beta1 = 0; beta1 < 4; beta1++) { + for (size_t beta2 = 0; beta2 < 4; beta2++) { + for (size_t i = 0; i < 2; i++) { + for (size_t j = 0; j < 2; j++) { + for (size_t i_Gamma1 = 0; i_Gamma1 < 2; i_Gamma1++) { + for (size_t i_Gamma2 = 0; i_Gamma2 < 2; i_Gamma2++) { + res_hihj_Gamma1Gamma2 += _spinor_scalar_prod(); // COMPLETE HERE + } + } + } + } + } + } } #if defined TM_USE_MPI From 1cfb721c6a3e0ee1d2fac14c1e94297d1448edcf Mon Sep 17 00:00:00 2001 From: simone-romiti Date: Wed, 28 Jun 2023 09:30:37 +0200 Subject: [PATCH 14/51] contruction of correlators and MPI parallelization. todo: writing into a file --- doc/omeas_heavy_mesons.qmd | 38 +++++++++--- meas/correlators.c | 118 ++++++++++++++++++++++++++----------- 2 files changed, 113 insertions(+), 43 deletions(-) diff --git a/doc/omeas_heavy_mesons.qmd b/doc/omeas_heavy_mesons.qmd index 0d7146f56..2403b5f0b 100644 --- a/doc/omeas_heavy_mesons.qmd +++ b/doc/omeas_heavy_mesons.qmd @@ -6,6 +6,8 @@ jupyter: python3 format-links: false # hide the existence of other formats format: html: + toc: true + toc-location: body embed-resources: true # standalone html html-math-method: mathjax # use the common latex commands include-in-header: mathjax-config.html # equation numbering with sections @@ -63,12 +65,12 @@ ${\bra{\Omega} \cdot \ket{\Omega} = \braket{\cdot}}$: \begin{equation} \begin{split} {C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t) &= -\eta_1 \frac{1}{V} +- \eta_1 \frac{1}{V} \sum_{\vec{x}} \mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) \\ &= -- \eta_{1} \eta_{2} +\eta_{1} \eta_{2} \frac{1}{V} \sum_{\vec{x}} \braket{ @@ -82,7 +84,7 @@ ${\bra{\Omega} \cdot \ket{\Omega} = \braket{\cdot}}$: where $h_i=c,s$, $\Gamma_i = 1, \gamma_5$. The minus sign will vanish when doing the Wick contractions, while -$\eta_{\mathbb{1}} = \pm 1$ and $\eta_{\gamma_5} = \pm i$ +$\eta_{\mathbb{1}} = 1$ and $\eta_{\gamma_5} = -1$ are used just to compensate the sign change when daggering the spinor bilinears at the source: \begin{equation} @@ -147,7 +149,7 @@ where ${\sigma_3 = \end{bmatrix} }$. As a projector, it satisfies $P_i^2 = P_i$. - Moreover, $\sigma_3 = \sigma_3^\dagger$, + Moreover $\sigma_3 = \sigma_3^\dagger$, hence $P_i^\dagger = P_i$. - Obviously, $P_i$ commutes with the $\gamma$ matrices asthey act on different spaces. @@ -190,7 +192,7 @@ If we now call $S = D^{-1}$ the inverse of the Dirac operator, and use Wick's theorem: \begin{equation} -\braket{\psi_{a}(x) \bar{\psi}_{b}(0)} = S_{ab}(x|0) \, , +\braket{\Psi_{a}(x) \bar{\Psi}_{b}(0)} = S_{ab}(x|0) \, , \end{equation} where $a$ and $b$ are a shortcut for the other indices of the spinor (spin, flavor, color, etc.), @@ -261,14 +263,36 @@ Therefore, back to our correlators, we can write: \\ \times & -(\psi_{h}^{(\beta_2)})_{\substack{f_2 \\ \alpha_2}}(x) -(\eta_{h}^{(\beta_2)})^*_{\substack{f_3 \\ \alpha_3}}(0) +(\psi_{h}^{(\beta_2)})_{\substack{f_2 \\ \alpha_3}}(x) +(\eta_{h}^{(\beta_2)})^*_{\substack{f_3 \\ \alpha_4}}(0) (P_j \tau_1)_{f_3 f_4} (\Gamma_2)_{\alpha_4 \alpha_1} \, . \end{split} \end{equation} +In terms of dot products (flavor and Dirac indices contracted): + +\begin{equation} +\begin{split} +\mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) += +\sum_{\beta_1, \beta_2} +& +\left[ +(\eta_\ell^{(\beta_1)}(x))^{\dagger} (\tau_1 P_i) \Gamma_1 \psi_h^{(\beta_2)}(x) +\right] +\\ +\times& +\left[ +(\eta_h^{(\beta_2)}(0))^{\dagger} (P_j \tau_1) \Gamma_2 \psi_\ell^{(\beta_1)}(0) +\right] +\end{split} +\end{equation} + + + + ## Implementation See comments in the code: `correlators.c`. diff --git a/meas/correlators.c b/meas/correlators.c index 831980143..f51774e18 100644 --- a/meas/correlators.c +++ b/meas/correlators.c @@ -255,9 +255,9 @@ void light_correlators_measurement(const int traj, const int id, const int ieo) // Function to allocate memory for a pointer of pointers for an array of d dimensions -void* allocateMultiDimensionalArray(int* sizes, int numDimensions, size_t elementSize) { +void* callocMultiDimensional(int* sizes, int numDimensions, size_t elementSize) { if (numDimensions == 1) { - void* array = malloc(sizes[0] * sizeof(elementSize)); + void* array = calloc(sizes[0], sizeof(elementSize)); if (array == NULL) { printf("Memory allocation failed for dimension 0!"); @@ -267,7 +267,7 @@ void* allocateMultiDimensionalArray(int* sizes, int numDimensions, size_t elemen return array; } - void** pointerArray = (void**)malloc(sizes[0] * sizeof(void*)); + void** pointerArray = (void**)calloc(sizes[0], sizeof(void*)); if (pointerArray == NULL) { printf("Memory allocation failed for dimension %d!", numDimensions - 1); @@ -275,7 +275,7 @@ void* allocateMultiDimensionalArray(int* sizes, int numDimensions, size_t elemen } for (int i = 0; i < sizes[0]; i++) { - pointerArray[i] = allocateMultiDimensionalArray(sizes + 1, numDimensions - 1); + pointerArray[i] = callocMultiDimensional(sizes + 1, numDimensions - 1); if (pointerArray[i] == NULL) { printf("Memory allocation failed for subarray %d in dimension %d!", i, numDimensions - 1); @@ -345,13 +345,14 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, /* heavy-light correlator: dummy variables */ // the number of independent correlators is 16 = (2*2)_{h_1 h_2} * (2*2)_{Gamma_1 Gamma_2} - // h_i: c,s, Gamma = (1, gamma_5) - double *****C_hihj_Gamma1Gamma2 = (double *****) allocateMultiDimensionalArray({2,2,2,2,T}, 5, sizeof(double)); - double *****res_hihj_Gamma1Gamma2 = (double *****) allocateMultiDimensionalArray({2,2,2,2,T}, 5, sizeof(double)); + // h_i: c,s + // Gamma = 1, gamma_5 + double *****C_hihj_Gamma1Gamma2 = (double *****) callocMultiDimensional({2,2,2,2,T}, 5, sizeof(double)); + double ****res_hihj_Gamma1Gamma2 = (double ****) callocMultiDimensional({2,2,2,2}, 4, sizeof(double)); #ifdef TM_USE_MPI - double *****mpi_res_ij = (double *****) allocateMultiDimensionalArray({2,2,2,2,T}, 5, sizeof(double)); + double ****mpi_res_hihj_Gamma1Gamma2 = (double ****) callocMultiDimensional({2,2,2,2}, 4, sizeof(double)); // send buffer for MPI_Gather - double *****sC_ij = (double *****) allocateMultiDimensionalArray({2,2,2,2,T}, 5, sizeof(double)); + double *****sC_hihj_Gamma1Gamma2 = (double *****) callocMultiDimensional({2,2,2,2,T}, 5, sizeof(double)); #endif FILE *ofs; // output file stream @@ -438,18 +439,9 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, // psi = (psi[(s,p)][phi][beta][eo][f][x])[alpha][c] // last 3 indices are proper of the spinor struct // Note: propagator in the sense that it is D^{-1}*source after the inversion - // unnecessary: // init_spinor_field(VOLUMEPLUSRAND / 2, 1); // initialize g_spinor_field so that I can copy it + spinor ******arr_eo_spinor = (spinor ******)callocMultiDimensional({2,2,4,2,2,VOLUME/2}, 6, sizeof(spinor)); - spinor ******arr_eo_spinor = (spinor ******)allocateMultiDimensionalArray({2,2,4,2,2,VOLUME/2}, 6, sizeof(spinor)); -// spinor ******h_arr_eo_spinor = (spinor ******)allocateMultiDimensionalArray({2,2,4,2,2,VOLUME/2}, 6, sizeof(spinor)); - - // (no even-odd): source+propagator, doublet, spin dilution index, even-odd, flavor, position (+ Dirac, color) - // (psi[phi][beta][f][x])[alpha][c] // last 3 indices are proper of the spinor struct - spinor ****arr_spinor = (spinor ****) allocateMultiDimensionalArray({2,4,2,VOLUME}, 4, sizeof(spinor)); -// spinor ****h_propagator = (spinor ****) allocateMultiDimensionalArray({2,4,2,VOLUME/2}, 4, sizeof(spinor)); - - /* initalize the random sources: one source for each Dirc index beta=src_d --> spin dilution - */ + /* initalize the random sources: one source for each Dirac index beta=src_d --> spin dilution */ for (size_t i_phi = 0; i_phi < 2; i_phi++) { // doublet: light or heavy for (size_t src_d = 0; src_d < 4; src_d++) { // spin dilution index for (size_t i_f = 0; i_f < 2; i_f++) { // flavor index of the doublet @@ -553,6 +545,10 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, } } + // (no even-odd): source+propagator, doublet, spin dilution index, even-odd, flavor, position (+ Dirac, color) + // (psi[i_sp][phi][beta][f][x])[alpha][c] // last 3 indices are proper of the spinor struct + spinor *****arr_spinor = (spinor *****) callocMultiDimensional({2,2,4,2,VOLUME}, 5, sizeof(spinor)); + // now we switch from even-odd representation to standard for (size_t i_sp = 0; i_sp < 2; i_sp++) { // source or sink for (size_t i_phi = 0; i_phi < 2; i_phi++) { // doublet index @@ -575,23 +571,45 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, /* now we sum only over local space for every t */ for (t = 0; t < T; t++) { j = g_ipt[t][0][0][0]; + + // dummy variables res = 0.; respa = 0.; resp4 = 0.; + for (i = j; i < j + LX * LY * LZ; i++) { - res += _spinor_prod_re(l_propagator[0][0][i], l_propagator[0][0][i]); - _gamma0(phi, l_propagator[0][0][i]); - respa += _spinor_prod_re(l_propagator[0][0][i], phi); - _gamma5(phi, phi); - resp4 += _spinor_prod_im(l_propagator[0][0][i], phi); - - for (size_t beta1 = 0; beta1 < 4; beta1++) { - for (size_t beta2 = 0; beta2 < 4; beta2++) { - for (size_t i = 0; i < 2; i++) { - for (size_t j = 0; j < 2; j++) { - for (size_t i_Gamma1 = 0; i_Gamma1 < 2; i_Gamma1++) { - for (size_t i_Gamma2 = 0; i_Gamma2 < 2; i_Gamma2++) { - res_hihj_Gamma1Gamma2 += _spinor_scalar_prod(); // COMPLETE HERE + // light correlators + for (size_t beta = 0; beta < 4; beta++) { // spin dilution + res += _spinor_prod_re(arr_spinor[1][0][beta][0][i], arr_spinor[1][0][beta][0][i]); + _gamma0(phi, arr_spinor[1][0][beta][0][i]); + respa += _spinor_prod_re(arr_spinor[1][0][beta][0][i], phi); + _gamma5(phi, phi); + resp4 += _spinor_prod_im(arr_spinor[1][0][beta][0][i], phi); + } + + for (size_t i_f = 0; i_f < 2; i_f++) { + for (size_t j_f = 0; j_f < 2; j_f++) { + for (size_t i_Gamma1 = 0; i_Gamma1 < 2; i_Gamma1++) { + for (size_t i_Gamma2 = 0; i_Gamma2 < 2; i_Gamma2++) { + for (size_t beta1 = 0; beta1 < 4; beta1++) { + for (size_t beta2 = 0; beta2 < 4; beta2++) { + double dum1, dum2 = 0.0, 0.0; // dummy variables + + // 1st contribution + phi = arr_spinor[1][1][beta_2][i_f][i]; + if (Gamma_1 == 1) { // Gamma_1 = 1 + _gamma5(phi, phi); + } + _spinor_scalar_prod(dum1, arr_spinor[0][0][beta_1][1 - i_f][i], phi); + + // 2nd contribution + phi = arr_spinor[1][0][beta_1][1 - i_f][i]; + if (Gamma_2 == 1) { // Gamma_1 = gamma_5 + _gamma5(phi, phi); + } + _spinor_scalar_prod(dum2, arr_spinor[0][1][beta_2][i_f][i], phi); + + res_hihj_Gamma1Gamma2[i_f][j_f][beta_1][beta_2] += dum1 * dum2; } } } @@ -621,14 +639,42 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, Cp4[t] = +resp4 / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ) / 2. / optr1->kappa / optr1->kappa; #endif + + for (size_t i_f = 0; i_f < 2; i_f++) { + for (size_t j_f = 0; j_f < 2; j_f++) { + for (size_t i_Gamma1 = 0; i_Gamma1 < 2; i_Gamma1++) { + for (size_t i_Gamma2 = 0; i_Gamma2 < 2; i_Gamma2++) { +#if defined TM_USE_MPI + MPI_Reduce(&res_hihj_Gamma1Gamma2[i_f][j_f][beta_1][beta_2], &mpi_res_hihj_Gamma1Gamma2[i_f][j_f][beta_1][beta_2], 1, MPI_DOUBLE, MPI_SUM, 0, g_mpi_time_slices); + res_hihj_Gamma1Gamma2[i_f][j_f][beta_1][beta_2] = mpi_res_hihj_Gamma1Gamma2[i_f][j_f][beta_1][beta_2]; + C_hihj_Gamma1Gamma2[i_f][j_f][beta_1][beta_2][t] = -eta_Gamma[i_Gamma1]*res / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ); +#else + C_hihj_Gamma1Gamma2[i_f][j_f][beta_1][beta_2][t] = -eta_Gamma[i_Gamma1]*res / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ); +#endif + } + } + } + } } #ifdef TM_USE_MPI /* some gymnastics needed in case of parallelisation */ if (g_mpi_time_rank == 0) { + // light correlators MPI_Gather(sCpp, T, MPI_DOUBLE, Cpp, T, MPI_DOUBLE, 0, g_mpi_SV_slices); MPI_Gather(sCpa, T, MPI_DOUBLE, Cpa, T, MPI_DOUBLE, 0, g_mpi_SV_slices); MPI_Gather(sCp4, T, MPI_DOUBLE, Cp4, T, MPI_DOUBLE, 0, g_mpi_SV_slices); + + // heavy mesons + for (size_t i_f = 0; i_f < 2; i_f++) { + for (size_t j_f = 0; j_f < 2; j_f++) { + for (size_t i_Gamma1 = 0; i_Gamma1 < 2; i_Gamma1++) { + for (size_t i_Gamma2 = 0; i_Gamma2 < 2; i_Gamma2++) { + MPI_Gather(sC_hihj_Gamma1Gamma2[i_f][j_f][beta_1][beta_2], T, MPI_DOUBLE, C_hihj_Gamma1Gamma2[i_f][j_f][beta_1][beta_2], T, MPI_DOUBLE, 0, g_mpi_SV_slices); + } + } + } + } } #endif @@ -671,17 +717,17 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, free(Cpp); free(Cpa); free(Cp4); - free(C_ij); + free(C_hihj_Gamma1Gamma2); } free(sCpp); free(sCpa); free(sCp4); - free(sC_ij); + free(sC_hihj_Gamma1Gamma2); #else free(Cpp); free(Cpa); free(Cp4); - free(C_ij); + free(C_hihj_Gamma1Gamma2); #endif } // for(max_time_slices) } // for(max_samples) From 46a95f8b2d279434b1e9abe58c16b7c4a07e6d5e Mon Sep 17 00:00:00 2001 From: simone-romiti Date: Wed, 28 Jun 2023 09:56:41 +0200 Subject: [PATCH 15/51] typo + writing correlators to file --- meas/correlators.c | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/meas/correlators.c b/meas/correlators.c index f51774e18..9cccc0d86 100644 --- a/meas/correlators.c +++ b/meas/correlators.c @@ -342,7 +342,8 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, Cp4 = (double *)calloc(T, sizeof(double)); #endif - /* heavy-light correlator: dummy variables */ + /* heavy-light correlators variables */ + double eta_Gamma[2] = {1.0, -1.0}; // sign change compensation from daggering bilinear with Gamma = 1,gamma_5 // the number of independent correlators is 16 = (2*2)_{h_1 h_2} * (2*2)_{Gamma_1 Gamma_2} // h_i: c,s @@ -532,9 +533,9 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, // (c,s) --> [(1-i*tau_2)/sqrt(2)] * (c,s) , stored at temporarely in the propagator // spinors (used as dummy spinors) mul_one_pm_itau2_and_div_by_sqrt2(arr_eo_spinor[1][1][src_d][i_eo][0], - arr_eo_spinor[1][1][src_d][i_eo][0 + 1], + arr_eo_spinor[1][1][src_d][i_eo][1], arr_eo_spinor[0][1][src_d][i_eo][0], - arr_eo_spinor[0][1][src_d][i_eo][0 + 1], -1.0, + arr_eo_spinor[0][1][src_d][i_eo][1], -1.0, VOLUME / 2); for (size_t i_f = 0; i_f < 2; i_f++) { // assigning the result to the first components (the sources). @@ -603,11 +604,11 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, _spinor_scalar_prod(dum1, arr_spinor[0][0][beta_1][1 - i_f][i], phi); // 2nd contribution - phi = arr_spinor[1][0][beta_1][1 - i_f][i]; + phi = arr_spinor[1][0][beta_1][1 - j_f][i]; if (Gamma_2 == 1) { // Gamma_1 = gamma_5 _gamma5(phi, phi); } - _spinor_scalar_prod(dum2, arr_spinor[0][1][beta_2][i_f][i], phi); + _spinor_scalar_prod(dum2, arr_spinor[0][1][beta_2][j_f][i], phi); res_hihj_Gamma1Gamma2[i_f][j_f][beta_1][beta_2] += dum1 * dum2; } @@ -655,7 +656,8 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, } } } - } + + } //end loop over "t" #ifdef TM_USE_MPI /* some gymnastics needed in case of parallelisation */ @@ -710,6 +712,26 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, } tt = (t0 + g_nproc_t * T / 2) % (g_nproc_t * T); fprintf(ofs, "6 1 %d %e %e\n", t, Cp4[tt], 0.); + + + for (size_t i_f = 0; i_f < 2; i_f++) { + for (size_t j_f = 0; j_f < 2; j_f++) { + for (size_t i_Gamma1 = 0; i_Gamma1 < 2; i_Gamma1++) { + for (size_t i_Gamma2 = 0; i_Gamma2 < 2; i_Gamma2++) { + fprintf(ofs, "%d %d %d %d 0 %e %e\n", i_f, j_f, i_Gamma1, i_Gamma2, C_hihj_Gamma1Gamma2[i_f][j_f][beta_1][beta_2][t0], 0.); + for (t = 1; t < g_nproc_t * T / 2; t++) { + tt = (t0 + t) % (g_nproc_t * T); + fprintf(ofs, "%d %d %d %d %d %e ", i_f, j_f, i_Gamma1, i_Gamma2, t, C_hihj_Gamma1Gamma2[i_f][j_f][beta_1][beta_2][tt]); + tt = (t0 + g_nproc_t * T - t) % (g_nproc_t * T); + fprintf(ofs, "%e\n", C_hihj_Gamma1Gamma2[i_f][j_f][beta_1][beta_2][tt]); + } + tt = (t0 + g_nproc_t * T / 2) % (g_nproc_t * T); + fprintf(ofs, "%d %d %d %d %d %d %e %e\n", i_f, j_f, i_Gamma1, i_Gamma2, t, C_hihj_Gamma1Gamma2[i_f][j_f][beta_1][beta_2][tt], 0.0); + } + } + } + } + fclose(ofs); } #ifdef TM_USE_MPI From 1a646b5c2423072cbcb211f052e22b0369aee0df Mon Sep 17 00:00:00 2001 From: simone-romiti Date: Sat, 1 Jul 2023 14:09:51 +0200 Subject: [PATCH 16/51] fixed some typos --- doc/omeas_heavy_mesons.html | 3620 +++++++++++++++++++++++++++++++++++ meas/correlators.c | 24 +- 2 files changed, 3634 insertions(+), 10 deletions(-) create mode 100644 doc/omeas_heavy_mesons.html diff --git a/doc/omeas_heavy_mesons.html b/doc/omeas_heavy_mesons.html new file mode 100644 index 000000000..6d47a2a5f --- /dev/null +++ b/doc/omeas_heavy_mesons.html @@ -0,0 +1,3620 @@ + + + + + + + + + + + +Online measurements of heavy meson correlators + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+

Online measurements of heavy meson correlators

+
+ + + +
+ +
+
Author
+
+

Simone Romiti

+
+
+ +
+
Published
+
+

June 28, 2023

+
+
+ + +
+ + +
+ +

tmLQCDcan compute the correlators for the heavy mesons \(K\) and \(D\). The twisted mass formulation of the heavy doublet \((s, c)\) is such that \(K\) and \(D\) mix in the correlators [1]. In fact, the Dirac operator is not diagonal in flavor, and the extraction of their masses requires the evaluation of a \((2 \times 2) \otimes (2 \times 2)\) matrix of correlators. In the following we use the twisted basis \(\chi\) for fermion fields: \[\begin{align} +\label{eq:LightFlavorSpinorFields} +\chi_{\ell} &= +\chi_{u} + \chi_{d} = + \begin{bmatrix} + \hat{\chi}_{u} \\ + 0 + \end{bmatrix} + + + \begin{bmatrix} + 0 \\ + \hat{\chi}_{d} + \end{bmatrix} +\, , \\[1em] +\label{eq:HeavyFlavorSpinorFields} +\chi_{h} &= +\chi_{c} + \chi_{s} = + \begin{bmatrix} + \hat{\chi}_{c} \\ + 0 + \end{bmatrix} + + + \begin{bmatrix} + 0 \\ + \hat{\chi}_{s} + \end{bmatrix} +\, . +\end{align}\]

+
+

Correlators for the \(K\) and \(D\)

+

The required correlators are given by the following expectation values on the interacting vacuum \({\bra{\Omega} \cdot \ket{\Omega} = \braket{\cdot}}\): \[\begin{equation} +\begin{split} +{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t) &= +- \eta_1 \frac{1}{V} +\sum_{\vec{x}} +\mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) +\\ +&= +\eta_{1} \eta_{2} +\frac{1}{V} +\sum_{\vec{x}} +\braket{ +[\bar{\chi}_{\ell_{\bar{i}}} \Gamma_1 \chi_{h_i}](x) +[\bar{\chi}_{\ell_{\bar{j}}} \Gamma_2 \chi_{h_j}]^{\dagger}(0) +} +\, , +\end{split} +\end{equation}\] where \(h_i=c,s\), \(\Gamma_i = 1, \gamma_5\). The minus sign will vanish when doing the Wick contractions, while \(\eta_{\mathbb{1}} = 1\) and \(\eta_{\gamma_5} = -1\) are used just to compensate the sign change when daggering the spinor bilinears at the source: \[\begin{equation} +\eta_\Gamma (\bar{\chi}_a \Gamma \chi_b)^\dagger = +\eta_\Gamma \bar{\chi}_b \gamma_0 \Gamma^\dagger \gamma_0 \chi_a = +\bar{\chi}_b \Gamma \chi_a +\, . +\end{equation}\] The index \(\bar{i}\) (\(\bar{j}\)) is the flavor index in the doublet that is opposite to \(i\) (\(j\)): \[\begin{equation} +h_i=c,s \to i = 0,1 \to \bar{i} = 1,0 \to \ell_{\bar{i}} = d,u +\, . +\end{equation}\]

+

We now write the explicit Wick contractions for the object: \[\begin{equation} +\begin{split} +\mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) &= +- \eta_{2} +\braket{ +[\bar{\chi}_{\ell_{\bar{i}}} \Gamma_1 \chi_{h_i}](x) +[\bar{\chi}_{\ell_{\bar{j}}} \Gamma_2 \chi_{h_j}]^{\dagger}(0) +} +\\ +&= - \braket{ +[\bar{\chi}_{\ell_{\bar{i}}} \Gamma_1 \chi_{h_i}](x) +[\bar{\chi}_{h_j} \Gamma_2 \chi_{\ell_{\bar{j}}}](0) +} +\end{split} +\end{equation}\]

+

A few observations are useful here:

+
    +
  • In flavor space, \({\sigma_1 = \begin{bmatrix} 0 & 1 \\ 1 & 0 \end{bmatrix} }\) switches between the up and down flavor. Moreover, \(\sigma_1 = \sigma_1^\dagger\).

  • +
  • The spinor fields \(\chi_{u,d}\) and \(\chi_{c,s}\) of eq. \(\eqref{eq:LightFlavorSpinorFields}\) and \(\eqref{eq:HeavyFlavorSpinorFields}\) can be obtained with the projector: \[\begin{equation} +P_{i} = \frac{1}{2} [1 + (-1)^i \sigma_3] \, , \, i=0,1 +\, , +\end{equation}\] where \({\sigma_3 = \begin{bmatrix} 1 & 0 \\ 0 & -1 \end{bmatrix} }\). As a projector, it satisfies \(P_i^2 = P_i\). Moreover \(\sigma_3 = \sigma_3^\dagger\), hence \(P_i^\dagger = P_i\).

  • +
  • Obviously, \(P_i\) commutes with the \(\gamma\) matrices asthey act on different spaces.

  • +
+
+
+

Wick contractions

+

Using the above remarks, we can write: \[\begin{equation} +\begin{split} +\mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) &= +- \braket{ +[\bar{\chi}_{\ell_{\bar{i}}} \Gamma_1 \chi_{h_i}](x) +[\bar{\chi}_{h_j} \Gamma_2 \chi_{\ell_{\bar{j}}}](0) +} +\\ +&= +- \braket{ +[\bar{\chi}_{\ell} (\tau_1 P_i) \Gamma_1 \chi_{h}](x) +[\bar{\chi}_{h} (P_j \tau_1) \Gamma_2 \chi_{\ell}](0) +} +\, . +\end{split} +\end{equation}\] An implicit summation on flavor indices is understood: \[\begin{equation} +\mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) = +- \braket{ +[(\bar{\chi}_{\ell})_{f_1} (\tau_1 P_i)_{f_1 f_2} \Gamma_1 (\chi_{h})_{f_2}](x) +[(\bar{\chi}_{h})_{f_3} (P_j \tau_1)_{f_3 f_4} \Gamma_2 (\chi_{\ell})_{f_4}](0) +} +\, . +\end{equation}\]

+

If we now call \(S = D^{-1}\) the inverse of the Dirac operator, and use Wick’s theorem: \[\begin{equation} +\braket{\Psi_{a}(x) \bar{\Psi}_{b}(0)} = S_{ab}(x|0) \, , +\end{equation}\] where \(a\) and \(b\) are a shortcut for the other indices of the spinor (spin, flavor, color, etc.), we write: \[\begin{equation} +\mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) = +(S_\ell)_{\substack{f_4 f_1 \\ \alpha_1 \alpha_2}} (0|x) +(\tau_1 P_i)_{f_1 f_2} (\Gamma_1)_{\alpha_2 \alpha_3} +(S_h)_{\substack{f_2 f_3 \\ \alpha_3 \alpha_4}} (x|0) +(P_j \tau_1)_{f_3 f_4} (\Gamma_2)_{\alpha_4 \alpha_1} +\, . +\end{equation}\]

+
+
+

Stochastic sampling

+

Analogously to [2], we now use \(N_r\) stochastic samples in order to approximate \(S\). The difference here is that the dilution is not on time but on Dirac index (spin). Therefore, our estimator for \(S\) is (cf. eqs. (5) and (7) of [2]): \[\begin{equation} +(S_\phi)_{\substack{f_1 f_2 \\ \alpha_1 \alpha_2}}(x|y) +\approx +\sum_{\beta=1}^{N_D=4} +\braket{ + (\psi_\phi^{(\beta)})_{\substack{f_1 \\ \alpha_1}}(x) + (\eta_\phi^{(\beta)})^*_{\substack{f_2 \\ \alpha_2}}(y) +} +\, , +\end{equation}\] where \(\braket{\cdot}\) here denotes the expectation value over the \(N_r\) stochastic samples. The sources are such that \({\eta^{(\beta)}_{\alpha} = \delta_{\alpha \beta}}\), and \(\psi^{\beta}\) are the solutions to: \[\begin{equation} +\begin{split} +&(D_{\phi})_{\substack{f_1 f_2 \\ \alpha_1 \alpha_2}}(x|y) +\, +(\psi_\phi)^{\beta}_{\substack{f_2 \\ \alpha_2}}(y) = +(\eta_\phi)^{\beta}_{\substack{f_1 \\ \alpha_1}}(x) +\\[1em] +& \implies \, \, +(\psi_\phi)^{\beta}_{\substack{f_1 \\ \alpha_1}}(x) = +(S_{\phi})_{\substack{f_1 f_2 \\ \alpha_1 \alpha_2}}(x|y) +\, +(\eta_\phi)^{\beta}_{\substack{f_2 \\ \alpha_1}}(y) +\end{split} +\end{equation}\]

+

Therefore, back to our correlators, we can write: \[\begin{equation} +\begin{split} +\mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) += +\sum_{\beta_1, \beta_2} +& +(\psi_{\ell}^{(\beta_1)})_{\substack{f_4 \\ \alpha_1}}(0) +(\eta_{\ell}^{(\beta_1)})^*_{\substack{f_1 \\ \alpha_2}}(x) +(\tau_1 P_i)_{f_1 f_2} (\Gamma_1)_{\alpha_2 \alpha_3} +\\ +\times +& +(\psi_{h}^{(\beta_2)})_{\substack{f_2 \\ \alpha_3}}(x) +(\eta_{h}^{(\beta_2)})^*_{\substack{f_3 \\ \alpha_4}}(0) +(P_j \tau_1)_{f_3 f_4} (\Gamma_2)_{\alpha_4 \alpha_1} +\, . +\end{split} +\end{equation}\]

+

In terms of dot products (flavor and Dirac indices contracted): \[\begin{equation} +\begin{split} +\mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) += +\sum_{\beta_1, \beta_2} +& +\left[ +(\eta_\ell^{(\beta_1)}(x))^{\dagger} (\tau_1 P_i) \Gamma_1 \psi_h^{(\beta_2)}(x) +\right] +\\ +\times& +\left[ +(\eta_h^{(\beta_2)}(0))^{\dagger} (P_j \tau_1) \Gamma_2 \psi_\ell^{(\beta_1)}(0) +\right] +\end{split} +\end{equation}\]

+
+
+

Implementation

+

See comments in the code: correlators.c.

+ +
+ +

References

+
+
[1]
R. Baron, P. Boucaud, J. Carbonell, V. Drach, F. Farchioni, G. Herdoiza, K. Jansen, C. Michael, I. Montvay, E. Pallante, others, Computing K and D meson masses with \(N_f= 2 + 1 + 1\) twisted mass lattice QCD, Computer Physics Communications. 182 (2011) 299–316. https://doi.org/https://doi.org/10.1016/j.cpc.2010.10.004.
+
+
+
[2]
J. Foley, K.J. Juge, A.Ó. Cais, M. Peardon, S.M. Ryan, J.-I. Skullerud, T. Collaboration, others, Practical all-to-all propagators for lattice QCD, Computer Physics Communications. 172 (2005) 145–162. https://doi.org/10.1016/j.cpc.2005.06.008.
+
+
+ + +
+ + + + \ No newline at end of file diff --git a/meas/correlators.c b/meas/correlators.c index 9cccc0d86..b90b2913d 100644 --- a/meas/correlators.c +++ b/meas/correlators.c @@ -443,10 +443,10 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, spinor ******arr_eo_spinor = (spinor ******)callocMultiDimensional({2,2,4,2,2,VOLUME/2}, 6, sizeof(spinor)); /* initalize the random sources: one source for each Dirac index beta=src_d --> spin dilution */ + const unsigned int seed_i = measurement_list[id].seed; // has to be same seed for (size_t i_phi = 0; i_phi < 2; i_phi++) { // doublet: light or heavy for (size_t src_d = 0; src_d < 4; src_d++) { // spin dilution index for (size_t i_f = 0; i_f < 2; i_f++) { // flavor index of the doublet - const unsigned int seed_i = src_d + measurement_list[id].seed; // light doublet eo_source_spinor_field_spin_diluted_oet_ts(arr_eo_spinor[0][i_phi][src_d][0][i_f], arr_eo_spinor[0][i_phi][src_d][1][i_f], t0, @@ -501,16 +501,16 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, optr1->DownProp = 1; // sources - optr1->sr2 = arr_eo_spinor[0][0][src_d][0][1]; - optr1->sr3 = arr_eo_spinor[0][0][src_d][1][1]; + optr1->sr0 = arr_eo_spinor[0][0][src_d][0][1]; + optr1->sr1 = arr_eo_spinor[0][0][src_d][1][1]; //propagator - optr1->prop2 = arr_eo_spinor[1][0][src_d][0][1]; - optr1->prop3 = arr_eo_spinor[1][0][src_d][1][1]; - - optr1->DownProp = 0; //restoring to default + optr1->prop0 = arr_eo_spinor[1][0][src_d][0][1]; + optr1->prop1 = arr_eo_spinor[1][0][src_d][1][1]; optr1->inverter(i1, 0, 0); //inversion for the down + optr1->DownProp = 0; //restoring to default + /* heavy doublet */ optr1->sr0 = arr_eo_spinor[0][1][src_d][0][0]; @@ -581,11 +581,15 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, for (i = j; i < j + LX * LY * LZ; i++) { // light correlators for (size_t beta = 0; beta < 4; beta++) { // spin dilution - res += _spinor_prod_re(arr_spinor[1][0][beta][0][i], arr_spinor[1][0][beta][0][i]); + double sign = 1.0; // the light source sould be multiplied by gamma_5 + if(beta >= 2){ + sign = -1.0; + } + res += sign*_spinor_prod_re(arr_spinor[1][0][beta][0][i], arr_spinor[1][0][beta][0][i]); _gamma0(phi, arr_spinor[1][0][beta][0][i]); - respa += _spinor_prod_re(arr_spinor[1][0][beta][0][i], phi); + respa += sign*_spinor_prod_re(arr_spinor[1][0][beta][0][i], phi); _gamma5(phi, phi); - resp4 += _spinor_prod_im(arr_spinor[1][0][beta][0][i], phi); + resp4 += sign*_spinor_prod_im(arr_spinor[1][0][beta][0][i], phi); } for (size_t i_f = 0; i_f < 2; i_f++) { From 259019c2d69b49c7a0fb4f208430a58fb298aca8 Mon Sep 17 00:00:00 2001 From: simone-romiti Date: Tue, 4 Jul 2023 17:15:13 +0200 Subject: [PATCH 17/51] is the correlator =0 for i!=j ??? --- doc/omeas_heavy_mesons.qmd | 170 ++++++++++++++++++++++++++++++++----- 1 file changed, 148 insertions(+), 22 deletions(-) diff --git a/doc/omeas_heavy_mesons.qmd b/doc/omeas_heavy_mesons.qmd index 2403b5f0b..0ac8dfa86 100644 --- a/doc/omeas_heavy_mesons.qmd +++ b/doc/omeas_heavy_mesons.qmd @@ -152,7 +152,7 @@ where ${\sigma_3 = Moreover $\sigma_3 = \sigma_3^\dagger$, hence $P_i^\dagger = P_i$. -- Obviously, $P_i$ commutes with the $\gamma$ matrices asthey act on different spaces. +- Obviously, $P_i$ commutes with the $\gamma$ matrices as they act on different spaces. ## Wick contractions @@ -169,8 +169,8 @@ we can write: \\ &= - \braket{ -[\bar{\chi}_{\ell} (\tau_1 P_i) \Gamma_1 \chi_{h}](x) -[\bar{\chi}_{h} (P_j \tau_1) \Gamma_2 \chi_{\ell}](0) +[\bar{\chi}_{\ell} (\sigma_1 P_i) \Gamma_1 \chi_{h}](x) +[\bar{\chi}_{h} (P_j \sigma_1) \Gamma_2 \chi_{\ell}](0) } \, . \end{split} @@ -181,42 +181,71 @@ An implicit summation on flavor indices is understood: \begin{equation} \mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) = - \braket{ -[(\bar{\chi}_{\ell})_{f_1} (\tau_1 P_i)_{f_1 f_2} \Gamma_1 (\chi_{h})_{f_2}](x) -[(\bar{\chi}_{h})_{f_3} (P_j \tau_1)_{f_3 f_4} \Gamma_2 (\chi_{\ell})_{f_4}](0) +[(\bar{\chi}_{\ell})_{f_1} (\sigma_1 P_i)_{f_1 f_2} \Gamma_1 (\chi_{h})_{f_2}](x) +[(\bar{\chi}_{h})_{f_3} (P_j \sigma_1)_{f_3 f_4} \Gamma_2 (\chi_{\ell})_{f_4}](0) } \, . \end{equation} -If we now call $S = D^{-1}$ the inverse of the Dirac operator, +We now call $S = D^{-1}$ the inverse of the Dirac operator and use Wick's theorem: \begin{equation} \braket{\Psi_{a}(x) \bar{\Psi}_{b}(0)} = S_{ab}(x|0) \, , \end{equation} -where $a$ and $b$ are a shortcut for the other indices of the spinor (spin, flavor, color, etc.), -we write: +where $a$ and $b$ are a shortcut for the other indices of the spinor (spin, flavor, color, etc.). +The correlator is: \begin{equation} -\mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) = +\begin{split} +\mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) +&= (S_\ell)_{\substack{f_4 f_1 \\ \alpha_1 \alpha_2}} (0|x) -(\tau_1 P_i)_{f_1 f_2} (\Gamma_1)_{\alpha_2 \alpha_3} +(\sigma_1 P_i)_{f_1 f_2} (\Gamma_1)_{\alpha_2 \alpha_3} (S_h)_{\substack{f_2 f_3 \\ \alpha_3 \alpha_4}} (x|0) -(P_j \tau_1)_{f_3 f_4} (\Gamma_2)_{\alpha_4 \alpha_1} +(P_j \sigma_1)_{f_3 f_4} (\Gamma_2)_{\alpha_4 \alpha_1} +\\ +&= +\operatorname{Tr}_f +\operatorname{Tr} +\left[ + S_h(x|0) (P_j \sigma_1) \Gamma_2 S_\ell(0|x) (\sigma_1 P_i) \Gamma_1 + \right] \, . +\end{split} \end{equation} +Using $\gamma_5$ hermiticity, +${(S_\ell)_{f_1 f_2} = (\sigma_1)_{f_1 g_1} \gamma_5 (S_\ell)_{g_1 g_2}^\dagger \gamma_5 (\sigma_1)_{g_2 f_2}}$, +we find: + +\begin{equation} +\mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) += +\operatorname{Tr}_f +\operatorname{Tr} +\left[ + S_h(x|0) P_j \Gamma_2 S_\ell (x|0) P_i \Gamma_1 +\right] +\end{equation} + +**Check: does this vanish for $i\neq j$ !?!?** + + ## Stochastic sampling Analogously to @foley2005practical, we now use $N_r$ stochastic samples in order to approximate $S$. The difference here is that the dilution is not on time but on Dirac index (spin). -Therefore, our estimator for $S$ is +Therefore, our estimators for $S$ and $S^{\dagger}$ are (cf. eqs. (5) and (7) of @foley2005practical): \begin{equation} +\label{eq:StochasticPropagator} +\begin{split} (S_\phi)_{\substack{f_1 f_2 \\ \alpha_1 \alpha_2}}(x|y) \approx \sum_{\beta=1}^{N_D=4} @@ -225,25 +254,35 @@ Therefore, our estimator for $S$ is (\eta_\phi^{(\beta)})^*_{\substack{f_2 \\ \alpha_2}}(y) } \, , +\\ +(S_\phi^{\dagger})_{\substack{f_1 f_2 \\ \alpha_1 \alpha_2}}(x|y) +\approx +\sum_{\beta=1}^{N_D=4} +\braket{ + (\eta_\phi^{(\beta)})_{\substack{f_1 \\ \alpha_1}}(x) + (\psi_\phi^{(\beta)})^{*}_{\substack{f_2 \\ \alpha_2}}(y) +} +\, , +\end{split} \end{equation} where $\braket{\cdot}$ here denotes the expectation value over the $N_r$ stochastic samples. The sources are such that ${\eta^{(\beta)}_{\alpha} = \delta_{\alpha \beta}}$, -and $\psi^{\beta}$ are the solutions to: +and $\psi^{(\beta)}$ are the solutions to: \begin{equation} \begin{split} &(D_{\phi})_{\substack{f_1 f_2 \\ \alpha_1 \alpha_2}}(x|y) \, -(\psi_\phi)^{\beta}_{\substack{f_2 \\ \alpha_2}}(y) = -(\eta_\phi)^{\beta}_{\substack{f_1 \\ \alpha_1}}(x) +(\psi_\phi^{(\beta)})_{\substack{f_2 \\ \alpha_2}}(y) = +(\eta_\phi^{(\beta)})_{\substack{f_1 \\ \alpha_1}}(x) \\[1em] & \implies \, \, -(\psi_\phi)^{\beta}_{\substack{f_1 \\ \alpha_1}}(x) = +(\psi_\phi^{(\beta)})_{\substack{f_1 \\ \alpha_1}}(x) = (S_{\phi})_{\substack{f_1 f_2 \\ \alpha_1 \alpha_2}}(x|y) \, -(\eta_\phi)^{\beta}_{\substack{f_2 \\ \alpha_1}}(y) +(\eta_\phi^{(\beta)})_{\substack{f_2 \\ \alpha_1}}(y) \end{split} \end{equation} @@ -259,13 +298,13 @@ Therefore, back to our correlators, we can write: & (\psi_{\ell}^{(\beta_1)})_{\substack{f_4 \\ \alpha_1}}(0) (\eta_{\ell}^{(\beta_1)})^*_{\substack{f_1 \\ \alpha_2}}(x) -(\tau_1 P_i)_{f_1 f_2} (\Gamma_1)_{\alpha_2 \alpha_3} +(\sigma_1 P_i)_{f_1 f_2} (\Gamma_1)_{\alpha_2 \alpha_3} \\ \times & (\psi_{h}^{(\beta_2)})_{\substack{f_2 \\ \alpha_3}}(x) (\eta_{h}^{(\beta_2)})^*_{\substack{f_3 \\ \alpha_4}}(0) -(P_j \tau_1)_{f_3 f_4} (\Gamma_2)_{\alpha_4 \alpha_1} +(P_j \sigma_1)_{f_3 f_4} (\Gamma_2)_{\alpha_4 \alpha_1} \, . \end{split} \end{equation} @@ -280,22 +319,109 @@ In terms of dot products (flavor and Dirac indices contracted): \sum_{\beta_1, \beta_2} & \left[ -(\eta_\ell^{(\beta_1)}(x))^{\dagger} (\tau_1 P_i) \Gamma_1 \psi_h^{(\beta_2)}(x) +(\eta_\ell^{(\beta_1)}(x))^{\dagger} (\sigma_1 P_i) \Gamma_1 \psi_h^{(\beta_2)}(x) \right] \\ \times& \left[ -(\eta_h^{(\beta_2)}(0))^{\dagger} (P_j \tau_1) \Gamma_2 \psi_\ell^{(\beta_1)}(0) +(\eta_h^{(\beta_2)}(0))^{\dagger} (P_j \sigma_1) \Gamma_2 \psi_\ell^{(\beta_1)}(0) \right] \end{split} \end{equation} +## Stochastic improvements + +There are some tricks we can use in order to enhance the signal-to-noise ratio. + +- Use the $\gamma_5$ hermiticity of the Dirac operator: + +\begin{equation} +\gamma_5 (S_\ell)_{f_1 f_2} \gamma_5 += (\sigma_1)_{f_1 g_1} (S_\ell)_{g_1 g_2}^\dagger (\sigma_1)_{g_2 f_2} +\, , +\end{equation} + + + + +- We also use the "one-end-trick", namely use the same source for each flavor: + +\begin{equation} +\eta_\phi = \eta \, , +\end{equation} + + + +Therefore (cf. eq. \eqref{eq:StochasticPropagator}): + +\begin{equation} +\begin{split} +&\mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) += +\\[1em] +&\sum_{\beta_1 \beta_2} +(\sigma_1)_{f_1 g_1} +(\gamma_5)_{\alpha_1 \alpha_5} +(\eta^{(\beta_1)})_{\substack{g_1 \\ \alpha_5}} (0) +(\psi_\ell^{(\beta_1)})^{*}_{\substack{g_2 \\ \alpha_6}} (x) +(\gamma_5)_{\alpha_6 \alpha_2} +(\sigma_1)_{g_2 f_4} +(\sigma_1 P_i)_{f_1 f_2} (\Gamma_1)_{\alpha_2 \alpha_3} \\ +&\times +(\psi_h^{(\beta_2)})_{\substack{f_2\\ \alpha_3}} (x) +(\eta^{(\beta_2)})^{*}_{\substack{f_3 \\ \alpha_4}} (0) +(P_j \sigma_1)_{f_3 f_4} (\Gamma_2)_{\alpha_4 \alpha_1} +\\[1em] +=& +\sum_{\beta} +(\sigma_1)_{f_1 g_1} +(\gamma_5)_{\alpha_1 \alpha_4} +(\psi_\ell^{(\beta)})^{*}_{\substack{g_2 \\ \alpha_6}} (x) +(\gamma_5)_{\alpha_6 \alpha_2} +(\sigma_1)_{g_2 f_4} +(\sigma_1 P_i)_{f_1 f_2} (\Gamma_1)_{\alpha_2 \alpha_3} \\ +&\times +(\psi_h^{(\beta)})_{\substack{f_2\\ \alpha_3}} (x) +(P_j \sigma_1)_{g_1 f_4} (\Gamma_2)_{\alpha_4 \alpha_1} +\, . +\end{split} +\end{equation} + + +The stochastic sources $\eta$ are such that: + +\begin{equation} +\braket{ + (\eta^{\beta_1})_{\substack{f_1 \\ \alpha_1}}^{*} (x) + (\eta^{\beta_2})_{\substack{f_2 \\ \alpha_2}}^{*} (y) + }= + \delta_{xy} \delta_{f_1 f_2} \delta_{\alpha_1 \alpha_2} \delta_{\beta_1 \alpha_1} \delta_{\beta_2 \alpha_2} + \, +\end{equation} + + ## Implementation -See comments in the code: `correlators.c`. +See comments in the code: `tmLQCD/meas/correlators.c`. From 9d8b489b396719494fdfdf3af5a5e0c17bd5f899 Mon Sep 17 00:00:00 2001 From: simone-romiti Date: Thu, 6 Jul 2023 15:53:25 +0200 Subject: [PATCH 18/51] updated documentation --- doc/omeas_heavy_mesons.html | 3620 ----------------------------------- doc/omeas_heavy_mesons.qmd | 328 ++-- 2 files changed, 107 insertions(+), 3841 deletions(-) delete mode 100644 doc/omeas_heavy_mesons.html diff --git a/doc/omeas_heavy_mesons.html b/doc/omeas_heavy_mesons.html deleted file mode 100644 index 6d47a2a5f..000000000 --- a/doc/omeas_heavy_mesons.html +++ /dev/null @@ -1,3620 +0,0 @@ - - - - - - - - - - - -Online measurements of heavy meson correlators - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
-

Online measurements of heavy meson correlators

-
- - - -
- -
-
Author
-
-

Simone Romiti

-
-
- -
-
Published
-
-

June 28, 2023

-
-
- - -
- - -
- -

tmLQCDcan compute the correlators for the heavy mesons \(K\) and \(D\). The twisted mass formulation of the heavy doublet \((s, c)\) is such that \(K\) and \(D\) mix in the correlators [1]. In fact, the Dirac operator is not diagonal in flavor, and the extraction of their masses requires the evaluation of a \((2 \times 2) \otimes (2 \times 2)\) matrix of correlators. In the following we use the twisted basis \(\chi\) for fermion fields: \[\begin{align} -\label{eq:LightFlavorSpinorFields} -\chi_{\ell} &= -\chi_{u} + \chi_{d} = - \begin{bmatrix} - \hat{\chi}_{u} \\ - 0 - \end{bmatrix} - + - \begin{bmatrix} - 0 \\ - \hat{\chi}_{d} - \end{bmatrix} -\, , \\[1em] -\label{eq:HeavyFlavorSpinorFields} -\chi_{h} &= -\chi_{c} + \chi_{s} = - \begin{bmatrix} - \hat{\chi}_{c} \\ - 0 - \end{bmatrix} - + - \begin{bmatrix} - 0 \\ - \hat{\chi}_{s} - \end{bmatrix} -\, . -\end{align}\]

-
-

Correlators for the \(K\) and \(D\)

-

The required correlators are given by the following expectation values on the interacting vacuum \({\bra{\Omega} \cdot \ket{\Omega} = \braket{\cdot}}\): \[\begin{equation} -\begin{split} -{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t) &= -- \eta_1 \frac{1}{V} -\sum_{\vec{x}} -\mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) -\\ -&= -\eta_{1} \eta_{2} -\frac{1}{V} -\sum_{\vec{x}} -\braket{ -[\bar{\chi}_{\ell_{\bar{i}}} \Gamma_1 \chi_{h_i}](x) -[\bar{\chi}_{\ell_{\bar{j}}} \Gamma_2 \chi_{h_j}]^{\dagger}(0) -} -\, , -\end{split} -\end{equation}\] where \(h_i=c,s\), \(\Gamma_i = 1, \gamma_5\). The minus sign will vanish when doing the Wick contractions, while \(\eta_{\mathbb{1}} = 1\) and \(\eta_{\gamma_5} = -1\) are used just to compensate the sign change when daggering the spinor bilinears at the source: \[\begin{equation} -\eta_\Gamma (\bar{\chi}_a \Gamma \chi_b)^\dagger = -\eta_\Gamma \bar{\chi}_b \gamma_0 \Gamma^\dagger \gamma_0 \chi_a = -\bar{\chi}_b \Gamma \chi_a -\, . -\end{equation}\] The index \(\bar{i}\) (\(\bar{j}\)) is the flavor index in the doublet that is opposite to \(i\) (\(j\)): \[\begin{equation} -h_i=c,s \to i = 0,1 \to \bar{i} = 1,0 \to \ell_{\bar{i}} = d,u -\, . -\end{equation}\]

-

We now write the explicit Wick contractions for the object: \[\begin{equation} -\begin{split} -\mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) &= -- \eta_{2} -\braket{ -[\bar{\chi}_{\ell_{\bar{i}}} \Gamma_1 \chi_{h_i}](x) -[\bar{\chi}_{\ell_{\bar{j}}} \Gamma_2 \chi_{h_j}]^{\dagger}(0) -} -\\ -&= - \braket{ -[\bar{\chi}_{\ell_{\bar{i}}} \Gamma_1 \chi_{h_i}](x) -[\bar{\chi}_{h_j} \Gamma_2 \chi_{\ell_{\bar{j}}}](0) -} -\end{split} -\end{equation}\]

-

A few observations are useful here:

-
    -
  • In flavor space, \({\sigma_1 = \begin{bmatrix} 0 & 1 \\ 1 & 0 \end{bmatrix} }\) switches between the up and down flavor. Moreover, \(\sigma_1 = \sigma_1^\dagger\).

  • -
  • The spinor fields \(\chi_{u,d}\) and \(\chi_{c,s}\) of eq. \(\eqref{eq:LightFlavorSpinorFields}\) and \(\eqref{eq:HeavyFlavorSpinorFields}\) can be obtained with the projector: \[\begin{equation} -P_{i} = \frac{1}{2} [1 + (-1)^i \sigma_3] \, , \, i=0,1 -\, , -\end{equation}\] where \({\sigma_3 = \begin{bmatrix} 1 & 0 \\ 0 & -1 \end{bmatrix} }\). As a projector, it satisfies \(P_i^2 = P_i\). Moreover \(\sigma_3 = \sigma_3^\dagger\), hence \(P_i^\dagger = P_i\).

  • -
  • Obviously, \(P_i\) commutes with the \(\gamma\) matrices asthey act on different spaces.

  • -
-
-
-

Wick contractions

-

Using the above remarks, we can write: \[\begin{equation} -\begin{split} -\mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) &= -- \braket{ -[\bar{\chi}_{\ell_{\bar{i}}} \Gamma_1 \chi_{h_i}](x) -[\bar{\chi}_{h_j} \Gamma_2 \chi_{\ell_{\bar{j}}}](0) -} -\\ -&= -- \braket{ -[\bar{\chi}_{\ell} (\tau_1 P_i) \Gamma_1 \chi_{h}](x) -[\bar{\chi}_{h} (P_j \tau_1) \Gamma_2 \chi_{\ell}](0) -} -\, . -\end{split} -\end{equation}\] An implicit summation on flavor indices is understood: \[\begin{equation} -\mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) = -- \braket{ -[(\bar{\chi}_{\ell})_{f_1} (\tau_1 P_i)_{f_1 f_2} \Gamma_1 (\chi_{h})_{f_2}](x) -[(\bar{\chi}_{h})_{f_3} (P_j \tau_1)_{f_3 f_4} \Gamma_2 (\chi_{\ell})_{f_4}](0) -} -\, . -\end{equation}\]

-

If we now call \(S = D^{-1}\) the inverse of the Dirac operator, and use Wick’s theorem: \[\begin{equation} -\braket{\Psi_{a}(x) \bar{\Psi}_{b}(0)} = S_{ab}(x|0) \, , -\end{equation}\] where \(a\) and \(b\) are a shortcut for the other indices of the spinor (spin, flavor, color, etc.), we write: \[\begin{equation} -\mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) = -(S_\ell)_{\substack{f_4 f_1 \\ \alpha_1 \alpha_2}} (0|x) -(\tau_1 P_i)_{f_1 f_2} (\Gamma_1)_{\alpha_2 \alpha_3} -(S_h)_{\substack{f_2 f_3 \\ \alpha_3 \alpha_4}} (x|0) -(P_j \tau_1)_{f_3 f_4} (\Gamma_2)_{\alpha_4 \alpha_1} -\, . -\end{equation}\]

-
-
-

Stochastic sampling

-

Analogously to [2], we now use \(N_r\) stochastic samples in order to approximate \(S\). The difference here is that the dilution is not on time but on Dirac index (spin). Therefore, our estimator for \(S\) is (cf. eqs. (5) and (7) of [2]): \[\begin{equation} -(S_\phi)_{\substack{f_1 f_2 \\ \alpha_1 \alpha_2}}(x|y) -\approx -\sum_{\beta=1}^{N_D=4} -\braket{ - (\psi_\phi^{(\beta)})_{\substack{f_1 \\ \alpha_1}}(x) - (\eta_\phi^{(\beta)})^*_{\substack{f_2 \\ \alpha_2}}(y) -} -\, , -\end{equation}\] where \(\braket{\cdot}\) here denotes the expectation value over the \(N_r\) stochastic samples. The sources are such that \({\eta^{(\beta)}_{\alpha} = \delta_{\alpha \beta}}\), and \(\psi^{\beta}\) are the solutions to: \[\begin{equation} -\begin{split} -&(D_{\phi})_{\substack{f_1 f_2 \\ \alpha_1 \alpha_2}}(x|y) -\, -(\psi_\phi)^{\beta}_{\substack{f_2 \\ \alpha_2}}(y) = -(\eta_\phi)^{\beta}_{\substack{f_1 \\ \alpha_1}}(x) -\\[1em] -& \implies \, \, -(\psi_\phi)^{\beta}_{\substack{f_1 \\ \alpha_1}}(x) = -(S_{\phi})_{\substack{f_1 f_2 \\ \alpha_1 \alpha_2}}(x|y) -\, -(\eta_\phi)^{\beta}_{\substack{f_2 \\ \alpha_1}}(y) -\end{split} -\end{equation}\]

-

Therefore, back to our correlators, we can write: \[\begin{equation} -\begin{split} -\mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) -= -\sum_{\beta_1, \beta_2} -& -(\psi_{\ell}^{(\beta_1)})_{\substack{f_4 \\ \alpha_1}}(0) -(\eta_{\ell}^{(\beta_1)})^*_{\substack{f_1 \\ \alpha_2}}(x) -(\tau_1 P_i)_{f_1 f_2} (\Gamma_1)_{\alpha_2 \alpha_3} -\\ -\times -& -(\psi_{h}^{(\beta_2)})_{\substack{f_2 \\ \alpha_3}}(x) -(\eta_{h}^{(\beta_2)})^*_{\substack{f_3 \\ \alpha_4}}(0) -(P_j \tau_1)_{f_3 f_4} (\Gamma_2)_{\alpha_4 \alpha_1} -\, . -\end{split} -\end{equation}\]

-

In terms of dot products (flavor and Dirac indices contracted): \[\begin{equation} -\begin{split} -\mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) -= -\sum_{\beta_1, \beta_2} -& -\left[ -(\eta_\ell^{(\beta_1)}(x))^{\dagger} (\tau_1 P_i) \Gamma_1 \psi_h^{(\beta_2)}(x) -\right] -\\ -\times& -\left[ -(\eta_h^{(\beta_2)}(0))^{\dagger} (P_j \tau_1) \Gamma_2 \psi_\ell^{(\beta_1)}(0) -\right] -\end{split} -\end{equation}\]

-
-
-

Implementation

-

See comments in the code: correlators.c.

- -
- -

References

-
-
[1]
R. Baron, P. Boucaud, J. Carbonell, V. Drach, F. Farchioni, G. Herdoiza, K. Jansen, C. Michael, I. Montvay, E. Pallante, others, Computing K and D meson masses with \(N_f= 2 + 1 + 1\) twisted mass lattice QCD, Computer Physics Communications. 182 (2011) 299–316. https://doi.org/https://doi.org/10.1016/j.cpc.2010.10.004.
-
-
-
[2]
J. Foley, K.J. Juge, A.Ó. Cais, M. Peardon, S.M. Ryan, J.-I. Skullerud, T. Collaboration, others, Practical all-to-all propagators for lattice QCD, Computer Physics Communications. 172 (2005) 145–162. https://doi.org/10.1016/j.cpc.2005.06.008.
-
-
- - -
- - - - \ No newline at end of file diff --git a/doc/omeas_heavy_mesons.qmd b/doc/omeas_heavy_mesons.qmd index 0ac8dfa86..7bae96e3a 100644 --- a/doc/omeas_heavy_mesons.qmd +++ b/doc/omeas_heavy_mesons.qmd @@ -29,28 +29,26 @@ In the following we use the twisted basis $\chi$ for fermion fields: \begin{align} \label{eq:LightFlavorSpinorFields} \chi_{\ell} &= -\chi_{u} + \chi_{d} = \begin{bmatrix} - \hat{\chi}_{u} \\ + {\chi}_{u} \\ 0 \end{bmatrix} + \begin{bmatrix} 0 \\ - \hat{\chi}_{d} + {\chi}_{d} \end{bmatrix} \, , \\[1em] \label{eq:HeavyFlavorSpinorFields} \chi_{h} &= -\chi_{c} + \chi_{s} = \begin{bmatrix} - \hat{\chi}_{c} \\ + {\chi}_{c} \\ 0 \end{bmatrix} + \begin{bmatrix} 0 \\ - \hat{\chi}_{s} + {\chi}_{s} \end{bmatrix} \, . \end{align} @@ -74,8 +72,8 @@ ${\bra{\Omega} \cdot \ket{\Omega} = \braket{\cdot}}$: \frac{1}{V} \sum_{\vec{x}} \braket{ -[\bar{\chi}_{\ell_{\bar{i}}} \Gamma_1 \chi_{h_i}](x) -[\bar{\chi}_{\ell_{\bar{j}}} \Gamma_2 \chi_{h_j}]^{\dagger}(0) +[\bar{\chi}_{d} \Gamma_1 \chi_{h_i}](x) +[\bar{\chi}_{d} \Gamma_2 \chi_{h_j}]^{\dagger}(0) } \, , \end{split} @@ -94,12 +92,6 @@ are used just to compensate the sign change when daggering the spinor bilinears \, . \end{equation} -The index $\bar{i}$ ($\bar{j}$) is the flavor index in the doublet that is opposite to $i$ ($j$): - -\begin{equation} -h_i=c,s \to i = 0,1 \to \bar{i} = 1,0 \to \ell_{\bar{i}} = d,u -\, . -\end{equation} We now write the explicit Wick contractions for the object: @@ -108,31 +100,21 @@ We now write the explicit Wick contractions for the object: \mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) &= - \eta_{2} \braket{ -[\bar{\chi}_{\ell_{\bar{i}}} \Gamma_1 \chi_{h_i}](x) -[\bar{\chi}_{\ell_{\bar{j}}} \Gamma_2 \chi_{h_j}]^{\dagger}(0) +[\bar{\chi}_{d} \Gamma_1 \chi_{h_i}](x) +[\bar{\chi}_{d} \Gamma_2 \chi_{h_j}]^{\dagger}(0) } \\ &= - \braket{ -[\bar{\chi}_{\ell_{\bar{i}}} \Gamma_1 \chi_{h_i}](x) -[\bar{\chi}_{h_j} \Gamma_2 \chi_{\ell_{\bar{j}}}](0) +[\bar{\chi}_{d} \Gamma_1 \chi_{h_i}](x) +[\bar{\chi}_{h_j} \Gamma_2 \chi_{d}](0) } \end{split} \end{equation} -A few observations are useful here: - -- In flavor space, - ${\sigma_1 = - \begin{bmatrix} - 0 & 1 \\ - 1 & 0 - \end{bmatrix} - }$ - switches between the up and down flavor. - Moreover, $\sigma_1 = \sigma_1^\dagger$. +::: {.remark} -- The spinor fields $\chi_{u,d}$ and $\chi_{c,s}$ of eq. +1. The spinor fields $\chi_{u,d}$ and $\chi_{c,s}$ of eq. \eqref{eq:LightFlavorSpinorFields} and \eqref{eq:HeavyFlavorSpinorFields} can be obtained with the projector: @@ -152,7 +134,10 @@ where ${\sigma_3 = Moreover $\sigma_3 = \sigma_3^\dagger$, hence $P_i^\dagger = P_i$. -- Obviously, $P_i$ commutes with the $\gamma$ matrices as they act on different spaces. +2. Obviously, $P_i$ commutes with the $\gamma$ matrices as they act on different spaces. + +3. The action of $\sigma_1$ swaps the up and down flavor components of a spinor. +::: ## Wick contractions @@ -163,30 +148,20 @@ we can write: \begin{split} \mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) &= - \braket{ -[\bar{\chi}_{\ell_{\bar{i}}} \Gamma_1 \chi_{h_i}](x) -[\bar{\chi}_{h_j} \Gamma_2 \chi_{\ell_{\bar{j}}}](0) +[\bar{\chi}_{d} \Gamma_1 \chi_{h_i}](x) +[\bar{\chi}_{h_j} \Gamma_2 \chi_{d}](0) } \\ &= - \braket{ -[\bar{\chi}_{\ell} (\sigma_1 P_i) \Gamma_1 \chi_{h}](x) -[\bar{\chi}_{h} (P_j \sigma_1) \Gamma_2 \chi_{\ell}](0) +[\bar{\chi}_{\ell} \Gamma_1 (\sigma_1)^{1-i} P_i \chi_{h}](x) +[\bar{\chi}_{h} P_j (\sigma_1)^{1-j} \Gamma_2 \chi_{\ell}](0) } \, . \end{split} \end{equation} -An implicit summation on flavor indices is understood: - -\begin{equation} -\mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) = -- \braket{ -[(\bar{\chi}_{\ell})_{f_1} (\sigma_1 P_i)_{f_1 f_2} \Gamma_1 (\chi_{h})_{f_2}](x) -[(\bar{\chi}_{h})_{f_3} (P_j \sigma_1)_{f_3 f_4} \Gamma_2 (\chi_{\ell})_{f_4}](0) -} -\, . -\end{equation} - +An implicit summation on flavor indices is understood. We now call $S = D^{-1}$ the inverse of the Dirac operator and use Wick's theorem: @@ -199,222 +174,133 @@ where $a$ and $b$ are a shortcut for the other indices of the spinor (spin, flav The correlator is: \begin{equation} -\begin{split} \mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) -&= -(S_\ell)_{\substack{f_4 f_1 \\ \alpha_1 \alpha_2}} (0|x) -(\sigma_1 P_i)_{f_1 f_2} (\Gamma_1)_{\alpha_2 \alpha_3} -(S_h)_{\substack{f_2 f_3 \\ \alpha_3 \alpha_4}} (x|0) -(P_j \sigma_1)_{f_3 f_4} (\Gamma_2)_{\alpha_4 \alpha_1} -\\ -&= -\operatorname{Tr}_f -\operatorname{Tr} -\left[ - S_h(x|0) (P_j \sigma_1) \Gamma_2 S_\ell(0|x) (\sigma_1 P_i) \Gamma_1 - \right] -\, . -\end{split} += +S_\ell(0|x) +(\sigma_1)^{1-i} P_i \Gamma_1 +S_h(x|0) +P_j (\sigma_1)^{1-j} \Gamma_2 \end{equation} -Using $\gamma_5$ hermiticity, -${(S_\ell)_{f_1 f_2} = (\sigma_1)_{f_1 g_1} \gamma_5 (S_\ell)_{g_1 g_2}^\dagger \gamma_5 (\sigma_1)_{g_2 f_2}}$, -we find: +We now use $\gamma_5$ hermiticity: +$(S_\ell) = \sigma_1 \gamma_5 S_\ell^\dagger \gamma_5 \sigma_1$. +Please note that the $\dagger$ is not on flavor space indices, +but here it makes no difference because $S_\ell$ is diagonal in flavor. +Our correlator becomes: \begin{equation} \mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) = -\operatorname{Tr}_f \operatorname{Tr} \left[ - S_h(x|0) P_j \Gamma_2 S_\ell (x|0) P_i \Gamma_1 + S_h(x|0) + \Gamma_2 \gamma_5 + P_j (\sigma_1)^{j} + (S_\ell)^\dagger (x|0) + (\sigma_1)^i P_i + \gamma_5 \Gamma_1 \right] -\end{equation} - -**Check: does this vanish for $i\neq j$ !?!?** - - -## Stochastic sampling - -Analogously to @foley2005practical, -we now use $N_r$ stochastic samples in order to approximate $S$. -The difference here is that the dilution is not on time but on Dirac index (spin). -Therefore, our estimators for $S$ and $S^{\dagger}$ are -(cf. eqs. (5) and (7) of @foley2005practical): - -\begin{equation} -\label{eq:StochasticPropagator} -\begin{split} -(S_\phi)_{\substack{f_1 f_2 \\ \alpha_1 \alpha_2}}(x|y) -\approx -\sum_{\beta=1}^{N_D=4} -\braket{ - (\psi_\phi^{(\beta)})_{\substack{f_1 \\ \alpha_1}}(x) - (\eta_\phi^{(\beta)})^*_{\substack{f_2 \\ \alpha_2}}(y) -} -\, , -\\ -(S_\phi^{\dagger})_{\substack{f_1 f_2 \\ \alpha_1 \alpha_2}}(x|y) -\approx -\sum_{\beta=1}^{N_D=4} -\braket{ - (\eta_\phi^{(\beta)})_{\substack{f_1 \\ \alpha_1}}(x) - (\psi_\phi^{(\beta)})^{*}_{\substack{f_2 \\ \alpha_2}}(y) -} -\, , -\end{split} -\end{equation} - -where $\braket{\cdot}$ here denotes the expectation value over the $N_r$ stochastic samples. -The sources are such that -${\eta^{(\beta)}_{\alpha} = \delta_{\alpha \beta}}$, -and $\psi^{(\beta)}$ are the solutions to: - -\begin{equation} -\begin{split} -&(D_{\phi})_{\substack{f_1 f_2 \\ \alpha_1 \alpha_2}}(x|y) -\, -(\psi_\phi^{(\beta)})_{\substack{f_2 \\ \alpha_2}}(y) = -(\eta_\phi^{(\beta)})_{\substack{f_1 \\ \alpha_1}}(x) -\\[1em] -& \implies \, \, -(\psi_\phi^{(\beta)})_{\substack{f_1 \\ \alpha_1}}(x) = -(S_{\phi})_{\substack{f_1 f_2 \\ \alpha_1 \alpha_2}}(x|y) -\, -(\eta_\phi^{(\beta)})_{\substack{f_2 \\ \alpha_1}}(y) -\end{split} -\end{equation} - - - -Therefore, back to our correlators, we can write: - -\begin{equation} -\begin{split} -\mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) -= -\sum_{\beta_1, \beta_2} -& -(\psi_{\ell}^{(\beta_1)})_{\substack{f_4 \\ \alpha_1}}(0) -(\eta_{\ell}^{(\beta_1)})^*_{\substack{f_1 \\ \alpha_2}}(x) -(\sigma_1 P_i)_{f_1 f_2} (\Gamma_1)_{\alpha_2 \alpha_3} -\\ -\times -& -(\psi_{h}^{(\beta_2)})_{\substack{f_2 \\ \alpha_3}}(x) -(\eta_{h}^{(\beta_2)})^*_{\substack{f_3 \\ \alpha_4}}(0) -(P_j \sigma_1)_{f_3 f_4} (\Gamma_2)_{\alpha_4 \alpha_1} \, . -\end{split} \end{equation} - -In terms of dot products (flavor and Dirac indices contracted): +Upon a careful calculation for all values $i,j = 0,1$ we find, equivalently: \begin{equation} -\begin{split} \mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) = -\sum_{\beta_1, \beta_2} -& -\left[ -(\eta_\ell^{(\beta_1)}(x))^{\dagger} (\sigma_1 P_i) \Gamma_1 \psi_h^{(\beta_2)}(x) -\right] -\\ -\times& +\operatorname{Tr} \left[ -(\eta_h^{(\beta_2)}(0))^{\dagger} (P_j \sigma_1) \Gamma_2 \psi_\ell^{(\beta_1)}(0) + (S_h)_{f_i f_j} (x|0) + \Gamma_2 \gamma_5 + (S_u)^\dagger (x|0) + \gamma_5 \Gamma_1 \right] -\end{split} +\, . \end{equation} +We now approximate the propagator using stochastic sources. +Additionally, we use: -## Stochastic improvements - -There are some tricks we can use in order to enhance the signal-to-noise ratio. - -- Use the $\gamma_5$ hermiticity of the Dirac operator: - -\begin{equation} -\gamma_5 (S_\ell)_{f_1 f_2} \gamma_5 -= (\sigma_1)_{f_1 g_1} (S_\ell)_{g_1 g_2}^\dagger (\sigma_1)_{g_2 f_2} -\, , -\end{equation} - - - +- The one-end-trick @Boucaud:2008xu: non vanishing source only at $x=0$. +- Same source for light and heavy doublet +- Spin dilution (cf. @foley2005practical): one source for each Dirac index $\beta$. The components with index different from the dilution index are set to zero. +- Flavor projection: sources have an additional flavor index $\phi$, such that their flavor component different from the index vanish. The value of the flavor component however is the same, it changes only its position in the doublet: -- We also use the "one-end-trick", namely use the same source for each flavor: \begin{equation} -\eta_\phi = \eta \, , +\eta^{(\phi=0)} = + \begin{bmatrix} + \eta \\ + 0 + \end{bmatrix} +\, , \, +\eta^{(\phi=1)} = + \begin{bmatrix} + 0 \\ + \eta + \end{bmatrix} +\, . \end{equation} - -Therefore (cf. eq. \eqref{eq:StochasticPropagator}): +Since $\Gamma_2=1,\gamma_5$ we always have $\Gamma_2 = \Gamma_2^\dagger$. +In this way, if $\eta^{(\beta, \phi)}$ is the diluted source, +we can define: \begin{equation} \begin{split} -&\mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) -= -\\[1em] -&\sum_{\beta_1 \beta_2} -(\sigma_1)_{f_1 g_1} -(\gamma_5)_{\alpha_1 \alpha_5} -(\eta^{(\beta_1)})_{\substack{g_1 \\ \alpha_5}} (0) -(\psi_\ell^{(\beta_1)})^{*}_{\substack{g_2 \\ \alpha_6}} (x) -(\gamma_5)_{\alpha_6 \alpha_2} -(\sigma_1)_{g_2 f_4} -(\sigma_1 P_i)_{f_1 f_2} (\Gamma_1)_{\alpha_2 \alpha_3} \\ -&\times -(\psi_h^{(\beta_2)})_{\substack{f_2\\ \alpha_3}} (x) -(\eta^{(\beta_2)})^{*}_{\substack{f_3 \\ \alpha_4}} (0) -(P_j \sigma_1)_{f_3 f_4} (\Gamma_2)_{\alpha_4 \alpha_1} -\\[1em] -=& -\sum_{\beta} -(\sigma_1)_{f_1 g_1} -(\gamma_5)_{\alpha_1 \alpha_4} -(\psi_\ell^{(\beta)})^{*}_{\substack{g_2 \\ \alpha_6}} (x) -(\gamma_5)_{\alpha_6 \alpha_2} -(\sigma_1)_{g_2 f_4} -(\sigma_1 P_i)_{f_1 f_2} (\Gamma_1)_{\alpha_2 \alpha_3} \\ -&\times -(\psi_h^{(\beta)})_{\substack{f_2\\ \alpha_3}} (x) -(P_j \sigma_1)_{g_1 f_4} (\Gamma_2)_{\alpha_4 \alpha_1} +&D_{\ell} {\psi}_{\ell}^{(\beta, \phi)} += \gamma_5 \Gamma_2 \eta^{(\beta, \phi)} +\, \implies \, +(\psi_{\ell}^{(\beta, \phi)})^\dagger += +(\eta^{(\beta, \phi)})^\dagger +\Gamma_2 \gamma_5 S_{\ell}^\dagger +\\ +&D_{h} \psi_{h}^{(\beta, \phi)} += \eta^{(\beta, \phi)} +\, \implies \, +\psi_{h}^{(\beta, \phi)} += S_{h} \eta^{(\beta, \phi)} \, . \end{split} \end{equation} +This means that for our matrix of correlators we have to do ${4_D \times 2_f \times 2_{h,\ell}} = 16$ inversions. -The stochastic sources $\eta$ are such that: +::: {.remark} +1. For the light doublet `tmLQCD` computes only $S_u$, which is obtained with $(\psi_h^{(\beta, f_0)})_{f_0}$. This is the only propagator we need. + +2. For the heavy propagator, we can access the $(i,j)$ component of $S_h$ with $(\psi_h^{(\beta, f_j)})_{f_i}$. +::: + +Our correlator is given by the following expectation value +(no summation on flavor indices): \begin{equation} +\begin{split} +\mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) +&= +\sum_{\beta=1}^{N_D} +\langle +\operatorname{Tr} +\left[ + (\psi_h^{(\beta, f_i)})_{f_j}(x) + (\psi_\ell^{(\beta, f_0)})_{f_0}^\dagger (x) + \gamma_5 \Gamma_1 +\right] +\rangle +\\ +&= +\sum_{\beta=1}^{N_D} \braket{ - (\eta^{\beta_1})_{\substack{f_1 \\ \alpha_1}}^{*} (x) - (\eta^{\beta_2})_{\substack{f_2 \\ \alpha_2}}^{*} (y) - }= - \delta_{xy} \delta_{f_1 f_2} \delta_{\alpha_1 \alpha_2} \delta_{\beta_1 \alpha_1} \delta_{\beta_2 \alpha_2} - \, + (\psi_\ell^{(\beta, 0)})_{f_0}^\dagger (x) + \gamma_5 \Gamma_1 + (\psi_h^{(\beta, f_j)})_{f_i}(x) +} +\end{split} \end{equation} From 87da538f3a35c35edc70e548825f117b4b66d7f1 Mon Sep 17 00:00:00 2001 From: simone-romiti Date: Thu, 6 Jul 2023 15:57:52 +0200 Subject: [PATCH 19/51] typo --- doc/omeas_heavy_mesons.qmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/omeas_heavy_mesons.qmd b/doc/omeas_heavy_mesons.qmd index 7bae96e3a..747c5c514 100644 --- a/doc/omeas_heavy_mesons.qmd +++ b/doc/omeas_heavy_mesons.qmd @@ -296,7 +296,7 @@ Our correlator is given by the following expectation value &= \sum_{\beta=1}^{N_D} \braket{ - (\psi_\ell^{(\beta, 0)})_{f_0}^\dagger (x) + (\psi_\ell^{(\beta, f_0)})_{f_0}^\dagger (x) \gamma_5 \Gamma_1 (\psi_h^{(\beta, f_j)})_{f_i}(x) } From bbb6c5a8e923ca19f8657450f4b90bdd1bc6ce02 Mon Sep 17 00:00:00 2001 From: simone-romiti Date: Thu, 6 Jul 2023 16:02:57 +0200 Subject: [PATCH 20/51] minor comment --- doc/omeas_heavy_mesons.html | 3647 +++++++++++++++++++++++++++++++++++ doc/omeas_heavy_mesons.qmd | 2 +- 2 files changed, 3648 insertions(+), 1 deletion(-) create mode 100644 doc/omeas_heavy_mesons.html diff --git a/doc/omeas_heavy_mesons.html b/doc/omeas_heavy_mesons.html new file mode 100644 index 000000000..ca1eb4d4a --- /dev/null +++ b/doc/omeas_heavy_mesons.html @@ -0,0 +1,3647 @@ + + + + + + + + + + + +Online measurements of heavy meson correlators + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+

Online measurements of heavy meson correlators

+
+ + + +
+ +
+
Author
+
+

Simone Romiti

+
+
+ +
+
Published
+
+

July 6, 2023

+
+
+ + +
+ + +
+ +

tmLQCDcan compute the correlators for the heavy mesons \(K\) and \(D\). The twisted mass formulation of the heavy doublet \((s, c)\) is such that \(K\) and \(D\) mix in the spectral decomposition [1]. In fact, the Dirac operator is not diagonal in flavor, and the extraction of their masses requires the evaluation of a \((2 \times 2) \otimes (2 \times 2)\) matrix of correlators. In the following we use the twisted basis \(\chi\) for fermion fields: \[\begin{align} +\label{eq:LightFlavorSpinorFields} +\chi_{\ell} &= + \begin{bmatrix} + {\chi}_{u} \\ + 0 + \end{bmatrix} + + + \begin{bmatrix} + 0 \\ + {\chi}_{d} + \end{bmatrix} +\, , \\[1em] +\label{eq:HeavyFlavorSpinorFields} +\chi_{h} &= + \begin{bmatrix} + {\chi}_{c} \\ + 0 + \end{bmatrix} + + + \begin{bmatrix} + 0 \\ + {\chi}_{s} + \end{bmatrix} +\, . +\end{align}\]

+
+

Correlators for the \(K\) and \(D\)

+

The required correlators are given by the following expectation values on the interacting vacuum \({\bra{\Omega} \cdot \ket{\Omega} = \braket{\cdot}}\): \[\begin{equation} +\begin{split} +{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t) &= +- \eta_1 \frac{1}{V} +\sum_{\vec{x}} +\mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) +\\ +&= +\eta_{1} \eta_{2} +\frac{1}{V} +\sum_{\vec{x}} +\braket{ +[\bar{\chi}_{d} \Gamma_1 \chi_{h_i}](x) +[\bar{\chi}_{d} \Gamma_2 \chi_{h_j}]^{\dagger}(0) +} +\, , +\end{split} +\end{equation}\] where \(h_i=c,s\), \(\Gamma_i = 1, \gamma_5\). The minus sign will vanish when doing the Wick contractions, while \(\eta_{\mathbb{1}} = 1\) and \(\eta_{\gamma_5} = -1\) are used just to compensate the sign change when daggering the spinor bilinears at the source: \[\begin{equation} +\eta_\Gamma (\bar{\chi}_a \Gamma \chi_b)^\dagger = +\eta_\Gamma \bar{\chi}_b \gamma_0 \Gamma^\dagger \gamma_0 \chi_a = +\bar{\chi}_b \Gamma \chi_a +\, . +\end{equation}\]

+

We now write the explicit Wick contractions for the object: \[\begin{equation} +\begin{split} +\mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) &= +- \eta_{2} +\braket{ +[\bar{\chi}_{d} \Gamma_1 \chi_{h_i}](x) +[\bar{\chi}_{d} \Gamma_2 \chi_{h_j}]^{\dagger}(0) +} +\\ +&= - \braket{ +[\bar{\chi}_{d} \Gamma_1 \chi_{h_i}](x) +[\bar{\chi}_{h_j} \Gamma_2 \chi_{d}](0) +} +\end{split} +\end{equation}\]

+
+

Remark.

+
    +
  1. The spinor fields \(\chi_{u,d}\) and \(\chi_{c,s}\) of eq. \(\eqref{eq:LightFlavorSpinorFields}\) and \(\eqref{eq:HeavyFlavorSpinorFields}\) can be obtained with the projector: \[\begin{equation} +P_{i} = \frac{1}{2} [1 + (-1)^i \sigma_3] \, , \, i=0,1 +\, , +\end{equation}\] where \({\sigma_3 = \begin{bmatrix} 1 & 0 \\ 0 & -1 \end{bmatrix} }\). As a projector, it satisfies \(P_i^2 = P_i\). Moreover \(\sigma_3 = \sigma_3^\dagger\), hence \(P_i^\dagger = P_i\).

  2. +
  3. Obviously, \(P_i\) commutes with the \(\gamma\) matrices as they act on different spaces.

  4. +
  5. The action of \(\sigma_1\) swaps the up and down flavor components of a spinor.

  6. +
+
+
+
+

Wick contractions

+

Using the above remarks, we can write: \[\begin{equation} +\begin{split} +\mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) &= +- \braket{ +[\bar{\chi}_{d} \Gamma_1 \chi_{h_i}](x) +[\bar{\chi}_{h_j} \Gamma_2 \chi_{d}](0) +} +\\ +&= +- \braket{ +[\bar{\chi}_{\ell} \Gamma_1 (\sigma_1)^{1-i} P_i \chi_{h}](x) +[\bar{\chi}_{h} P_j (\sigma_1)^{1-j} \Gamma_2 \chi_{\ell}](0) +} +\, . +\end{split} +\end{equation}\] An implicit summation on flavor indices is understood.

+

We now call \(S = D^{-1}\) the inverse of the Dirac operator and use Wick’s theorem: \[\begin{equation} +\braket{\Psi_{a}(x) \bar{\Psi}_{b}(0)} = S_{ab}(x|0) \, , +\end{equation}\] where \(a\) and \(b\) are a shortcut for the other indices of the spinor (spin, flavor, color, etc.). The correlator is: \[\begin{equation} +\mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) += +S_\ell(0|x) +(\sigma_1)^{1-i} P_i \Gamma_1 +S_h(x|0) +P_j (\sigma_1)^{1-j} \Gamma_2 +\end{equation}\]

+

We now use \(\gamma_5\) hermiticity: \((S_\ell) = \sigma_1 \gamma_5 S_\ell^\dagger \gamma_5 \sigma_1\). Please note that the \(\dagger\) is not on flavor space indices, but here it makes no difference because \(S_\ell\) is diagonal in flavor. Our correlator becomes: \[\begin{equation} +\mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) += +\operatorname{Tr} +\left[ + S_h(x|0) + \Gamma_2 \gamma_5 + P_j (\sigma_1)^{j} + (S_\ell)^\dagger (x|0) + (\sigma_1)^i P_i + \gamma_5 \Gamma_1 +\right] +\, . +\end{equation}\] Upon a careful calculation for all values \(i,j = 0,1\) we find, equivalently: \[\begin{equation} +\mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) += +\operatorname{Tr} +\left[ + (S_h)_{f_i f_j} (x|0) + \Gamma_2 \gamma_5 + (S_u)^\dagger (x|0) + \gamma_5 \Gamma_1 +\right] +\, . +\end{equation}\]

+

We now approximate the propagator using stochastic sources. Additionally, we use:

+
    +
  • The one-end-trick [2]: non vanishing source only at \(x=0\).
  • +
  • Same source for light and heavy doublet
  • +
  • Spin dilution (cf. [3]): one source for each Dirac index \(\beta\). The components with index different from the dilution index are set to zero.
  • +
  • Flavor projection: sources have an additional flavor index \(\phi\), such that their flavor component different from the index vanish. The value of the flavor component however is the same, it changes only its position in the doublet:
  • +
+ +

\[\begin{equation} +\eta^{(\phi=0)} = + \begin{bmatrix} + \eta \\ + 0 + \end{bmatrix} +\, , \, +\eta^{(\phi=1)} = + \begin{bmatrix} + 0 \\ + \eta + \end{bmatrix} +\, . +\end{equation}\]

+

Since \(\Gamma_2=1,\gamma_5\) we always have \(\Gamma_2 = \Gamma_2^\dagger\). In this way, if \(\eta^{(\beta, \phi)}\) is the diluted source, we can define: \[\begin{equation} +\begin{split} +&D_{\ell} {\psi}_{\ell}^{(\beta, \phi)} += \gamma_5 \Gamma_2 \eta^{(\beta, \phi)} +\, \implies \, +(\psi_{\ell}^{(\beta, \phi)})^\dagger += +(\eta^{(\beta, \phi)})^\dagger +\Gamma_2 \gamma_5 S_{\ell}^\dagger +\\ +&D_{h} \psi_{h}^{(\beta, \phi)} += \eta^{(\beta, \phi)} +\, \implies \, +\psi_{h}^{(\beta, \phi)} += S_{h} \eta^{(\beta, \phi)} +\, . +\end{split} +\end{equation}\] This means that for our matrix of correlators we have to do \({4_D \times 2_f \times 2_{h,\ell}} = 16\) inversions.

+
+

Remark.

+
    +
  1. For the light doublet tmLQCD computes only \(S_u\), which is obtained with \((\psi_h^{(\beta, f_0)})_{f_0}\). This is the only propagator we need.

  2. +
  3. For the heavy propagator, we can access the \((i,j)\) component of \(S_h\) with \((\psi_h^{(\beta, f_j)})_{f_i}\).

  4. +
+
+

Our correlator is given by the following expectation value (no summation on flavor indices): \[\begin{equation} +\begin{split} +\mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) +&= +\sum_{\beta=1}^{N_D} +\langle +\operatorname{Tr} +\left[ + (\psi_h^{(\beta, f_i)})_{f_j}(x) + (\psi_\ell^{(\beta, f_0)})_{f_0}^\dagger (x) + \gamma_5 \Gamma_1 +\right] +\rangle +\\ +&= +\sum_{\beta=1}^{N_D} +\braket{ + (\psi_\ell^{(\beta, f_0)})_{f_0}^\dagger (x) + \gamma_5 \Gamma_1 + (\psi_h^{(\beta, f_j)})_{f_i}(x) +} +\end{split} +\end{equation}\]

+
+
+

Implementation

+

See comments in the code: tmLQCD/meas/correlators.c.

+ +
+ +

References

+
+
[1]
R. Baron, P. Boucaud, J. Carbonell, V. Drach, F. Farchioni, G. Herdoiza, K. Jansen, C. Michael, I. Montvay, E. Pallante, others, Computing K and D meson masses with \(N_f= 2 + 1 + 1\) twisted mass lattice QCD, Computer Physics Communications. 182 (2011) 299–316. https://doi.org/https://doi.org/10.1016/j.cpc.2010.10.004.
+
+
+
[2]
Ph. Boucaud, others, Dynamical Twisted Mass Fermions with Light Quarks: Simulation and Analysis Details, Comput. Phys. Commun. 179 (2008) 695–715. https://doi.org/10.1016/j.cpc.2008.06.013.
+
+
+
[3]
J. Foley, K.J. Juge, A.Ó. Cais, M. Peardon, S.M. Ryan, J.-I. Skullerud, T. Collaboration, others, Practical all-to-all propagators for lattice QCD, Computer Physics Communications. 172 (2005) 145–162. https://doi.org/10.1016/j.cpc.2005.06.008.
+
+
+ + +
+ + + + \ No newline at end of file diff --git a/doc/omeas_heavy_mesons.qmd b/doc/omeas_heavy_mesons.qmd index 747c5c514..74a6bc261 100644 --- a/doc/omeas_heavy_mesons.qmd +++ b/doc/omeas_heavy_mesons.qmd @@ -21,7 +21,7 @@ fontsize: 16pt --- `tmLQCD`can compute the correlators for the heavy mesons $K$ and $D$. -The twisted mass formulation of the heavy doublet $(s, c)$ is such that $K$ and $D$ mix in the correlators @baron2011computing. +The twisted mass formulation of the heavy doublet $(s, c)$ is such that $K$ and $D$ mix in the spectral decomposition @baron2011computing. In fact, the Dirac operator is not diagonal in flavor, and the extraction of their masses requires the evaluation of a $(2 \times 2) \otimes (2 \times 2)$ matrix of correlators. In the following we use the twisted basis $\chi$ for fermion fields: From c02db249e6efc53292fa626c94d214acda1539fb Mon Sep 17 00:00:00 2001 From: simone-romiti Date: Tue, 18 Jul 2023 11:19:35 +0200 Subject: [PATCH 21/51] outputting to file: appending correlators --- .gitignore | 1 + doc/omeas_heavy_mesons.html | 3647 ----------------------------------- meas/correlators.c | 57 +- 3 files changed, 30 insertions(+), 3675 deletions(-) delete mode 100644 doc/omeas_heavy_mesons.html diff --git a/.gitignore b/.gitignore index 82a86fead..9489a23c2 100644 --- a/.gitignore +++ b/.gitignore @@ -39,5 +39,6 @@ doc/*.ps doc/*.txt doc/*.gpl doc/wrapper* +doc/omeas_heavy_mesons.html history_hmc_tm .vscode/* \ No newline at end of file diff --git a/doc/omeas_heavy_mesons.html b/doc/omeas_heavy_mesons.html deleted file mode 100644 index ca1eb4d4a..000000000 --- a/doc/omeas_heavy_mesons.html +++ /dev/null @@ -1,3647 +0,0 @@ - - - - - - - - - - - -Online measurements of heavy meson correlators - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
-

Online measurements of heavy meson correlators

-
- - - -
- -
-
Author
-
-

Simone Romiti

-
-
- -
-
Published
-
-

July 6, 2023

-
-
- - -
- - -
- -

tmLQCDcan compute the correlators for the heavy mesons \(K\) and \(D\). The twisted mass formulation of the heavy doublet \((s, c)\) is such that \(K\) and \(D\) mix in the spectral decomposition [1]. In fact, the Dirac operator is not diagonal in flavor, and the extraction of their masses requires the evaluation of a \((2 \times 2) \otimes (2 \times 2)\) matrix of correlators. In the following we use the twisted basis \(\chi\) for fermion fields: \[\begin{align} -\label{eq:LightFlavorSpinorFields} -\chi_{\ell} &= - \begin{bmatrix} - {\chi}_{u} \\ - 0 - \end{bmatrix} - + - \begin{bmatrix} - 0 \\ - {\chi}_{d} - \end{bmatrix} -\, , \\[1em] -\label{eq:HeavyFlavorSpinorFields} -\chi_{h} &= - \begin{bmatrix} - {\chi}_{c} \\ - 0 - \end{bmatrix} - + - \begin{bmatrix} - 0 \\ - {\chi}_{s} - \end{bmatrix} -\, . -\end{align}\]

-
-

Correlators for the \(K\) and \(D\)

-

The required correlators are given by the following expectation values on the interacting vacuum \({\bra{\Omega} \cdot \ket{\Omega} = \braket{\cdot}}\): \[\begin{equation} -\begin{split} -{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t) &= -- \eta_1 \frac{1}{V} -\sum_{\vec{x}} -\mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) -\\ -&= -\eta_{1} \eta_{2} -\frac{1}{V} -\sum_{\vec{x}} -\braket{ -[\bar{\chi}_{d} \Gamma_1 \chi_{h_i}](x) -[\bar{\chi}_{d} \Gamma_2 \chi_{h_j}]^{\dagger}(0) -} -\, , -\end{split} -\end{equation}\] where \(h_i=c,s\), \(\Gamma_i = 1, \gamma_5\). The minus sign will vanish when doing the Wick contractions, while \(\eta_{\mathbb{1}} = 1\) and \(\eta_{\gamma_5} = -1\) are used just to compensate the sign change when daggering the spinor bilinears at the source: \[\begin{equation} -\eta_\Gamma (\bar{\chi}_a \Gamma \chi_b)^\dagger = -\eta_\Gamma \bar{\chi}_b \gamma_0 \Gamma^\dagger \gamma_0 \chi_a = -\bar{\chi}_b \Gamma \chi_a -\, . -\end{equation}\]

-

We now write the explicit Wick contractions for the object: \[\begin{equation} -\begin{split} -\mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) &= -- \eta_{2} -\braket{ -[\bar{\chi}_{d} \Gamma_1 \chi_{h_i}](x) -[\bar{\chi}_{d} \Gamma_2 \chi_{h_j}]^{\dagger}(0) -} -\\ -&= - \braket{ -[\bar{\chi}_{d} \Gamma_1 \chi_{h_i}](x) -[\bar{\chi}_{h_j} \Gamma_2 \chi_{d}](0) -} -\end{split} -\end{equation}\]

-
-

Remark.

-
    -
  1. The spinor fields \(\chi_{u,d}\) and \(\chi_{c,s}\) of eq. \(\eqref{eq:LightFlavorSpinorFields}\) and \(\eqref{eq:HeavyFlavorSpinorFields}\) can be obtained with the projector: \[\begin{equation} -P_{i} = \frac{1}{2} [1 + (-1)^i \sigma_3] \, , \, i=0,1 -\, , -\end{equation}\] where \({\sigma_3 = \begin{bmatrix} 1 & 0 \\ 0 & -1 \end{bmatrix} }\). As a projector, it satisfies \(P_i^2 = P_i\). Moreover \(\sigma_3 = \sigma_3^\dagger\), hence \(P_i^\dagger = P_i\).

  2. -
  3. Obviously, \(P_i\) commutes with the \(\gamma\) matrices as they act on different spaces.

  4. -
  5. The action of \(\sigma_1\) swaps the up and down flavor components of a spinor.

  6. -
-
-
-
-

Wick contractions

-

Using the above remarks, we can write: \[\begin{equation} -\begin{split} -\mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) &= -- \braket{ -[\bar{\chi}_{d} \Gamma_1 \chi_{h_i}](x) -[\bar{\chi}_{h_j} \Gamma_2 \chi_{d}](0) -} -\\ -&= -- \braket{ -[\bar{\chi}_{\ell} \Gamma_1 (\sigma_1)^{1-i} P_i \chi_{h}](x) -[\bar{\chi}_{h} P_j (\sigma_1)^{1-j} \Gamma_2 \chi_{\ell}](0) -} -\, . -\end{split} -\end{equation}\] An implicit summation on flavor indices is understood.

-

We now call \(S = D^{-1}\) the inverse of the Dirac operator and use Wick’s theorem: \[\begin{equation} -\braket{\Psi_{a}(x) \bar{\Psi}_{b}(0)} = S_{ab}(x|0) \, , -\end{equation}\] where \(a\) and \(b\) are a shortcut for the other indices of the spinor (spin, flavor, color, etc.). The correlator is: \[\begin{equation} -\mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) -= -S_\ell(0|x) -(\sigma_1)^{1-i} P_i \Gamma_1 -S_h(x|0) -P_j (\sigma_1)^{1-j} \Gamma_2 -\end{equation}\]

-

We now use \(\gamma_5\) hermiticity: \((S_\ell) = \sigma_1 \gamma_5 S_\ell^\dagger \gamma_5 \sigma_1\). Please note that the \(\dagger\) is not on flavor space indices, but here it makes no difference because \(S_\ell\) is diagonal in flavor. Our correlator becomes: \[\begin{equation} -\mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) -= -\operatorname{Tr} -\left[ - S_h(x|0) - \Gamma_2 \gamma_5 - P_j (\sigma_1)^{j} - (S_\ell)^\dagger (x|0) - (\sigma_1)^i P_i - \gamma_5 \Gamma_1 -\right] -\, . -\end{equation}\] Upon a careful calculation for all values \(i,j = 0,1\) we find, equivalently: \[\begin{equation} -\mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) -= -\operatorname{Tr} -\left[ - (S_h)_{f_i f_j} (x|0) - \Gamma_2 \gamma_5 - (S_u)^\dagger (x|0) - \gamma_5 \Gamma_1 -\right] -\, . -\end{equation}\]

-

We now approximate the propagator using stochastic sources. Additionally, we use:

-
    -
  • The one-end-trick [2]: non vanishing source only at \(x=0\).
  • -
  • Same source for light and heavy doublet
  • -
  • Spin dilution (cf. [3]): one source for each Dirac index \(\beta\). The components with index different from the dilution index are set to zero.
  • -
  • Flavor projection: sources have an additional flavor index \(\phi\), such that their flavor component different from the index vanish. The value of the flavor component however is the same, it changes only its position in the doublet:
  • -
- -

\[\begin{equation} -\eta^{(\phi=0)} = - \begin{bmatrix} - \eta \\ - 0 - \end{bmatrix} -\, , \, -\eta^{(\phi=1)} = - \begin{bmatrix} - 0 \\ - \eta - \end{bmatrix} -\, . -\end{equation}\]

-

Since \(\Gamma_2=1,\gamma_5\) we always have \(\Gamma_2 = \Gamma_2^\dagger\). In this way, if \(\eta^{(\beta, \phi)}\) is the diluted source, we can define: \[\begin{equation} -\begin{split} -&D_{\ell} {\psi}_{\ell}^{(\beta, \phi)} -= \gamma_5 \Gamma_2 \eta^{(\beta, \phi)} -\, \implies \, -(\psi_{\ell}^{(\beta, \phi)})^\dagger -= -(\eta^{(\beta, \phi)})^\dagger -\Gamma_2 \gamma_5 S_{\ell}^\dagger -\\ -&D_{h} \psi_{h}^{(\beta, \phi)} -= \eta^{(\beta, \phi)} -\, \implies \, -\psi_{h}^{(\beta, \phi)} -= S_{h} \eta^{(\beta, \phi)} -\, . -\end{split} -\end{equation}\] This means that for our matrix of correlators we have to do \({4_D \times 2_f \times 2_{h,\ell}} = 16\) inversions.

-
-

Remark.

-
    -
  1. For the light doublet tmLQCD computes only \(S_u\), which is obtained with \((\psi_h^{(\beta, f_0)})_{f_0}\). This is the only propagator we need.

  2. -
  3. For the heavy propagator, we can access the \((i,j)\) component of \(S_h\) with \((\psi_h^{(\beta, f_j)})_{f_i}\).

  4. -
-
-

Our correlator is given by the following expectation value (no summation on flavor indices): \[\begin{equation} -\begin{split} -\mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) -&= -\sum_{\beta=1}^{N_D} -\langle -\operatorname{Tr} -\left[ - (\psi_h^{(\beta, f_i)})_{f_j}(x) - (\psi_\ell^{(\beta, f_0)})_{f_0}^\dagger (x) - \gamma_5 \Gamma_1 -\right] -\rangle -\\ -&= -\sum_{\beta=1}^{N_D} -\braket{ - (\psi_\ell^{(\beta, f_0)})_{f_0}^\dagger (x) - \gamma_5 \Gamma_1 - (\psi_h^{(\beta, f_j)})_{f_i}(x) -} -\end{split} -\end{equation}\]

-
-
-

Implementation

-

See comments in the code: tmLQCD/meas/correlators.c.

- -
- -

References

-
-
[1]
R. Baron, P. Boucaud, J. Carbonell, V. Drach, F. Farchioni, G. Herdoiza, K. Jansen, C. Michael, I. Montvay, E. Pallante, others, Computing K and D meson masses with \(N_f= 2 + 1 + 1\) twisted mass lattice QCD, Computer Physics Communications. 182 (2011) 299–316. https://doi.org/https://doi.org/10.1016/j.cpc.2010.10.004.
-
-
-
[2]
Ph. Boucaud, others, Dynamical Twisted Mass Fermions with Light Quarks: Simulation and Analysis Details, Comput. Phys. Commun. 179 (2008) 695–715. https://doi.org/10.1016/j.cpc.2008.06.013.
-
-
-
[3]
J. Foley, K.J. Juge, A.Ó. Cais, M. Peardon, S.M. Ryan, J.-I. Skullerud, T. Collaboration, others, Practical all-to-all propagators for lattice QCD, Computer Physics Communications. 172 (2005) 145–162. https://doi.org/10.1016/j.cpc.2005.06.008.
-
-
- - -
- - - - \ No newline at end of file diff --git a/meas/correlators.c b/meas/correlators.c index b90b2913d..afcfd7b35 100644 --- a/meas/correlators.c +++ b/meas/correlators.c @@ -346,14 +346,14 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, double eta_Gamma[2] = {1.0, -1.0}; // sign change compensation from daggering bilinear with Gamma = 1,gamma_5 // the number of independent correlators is 16 = (2*2)_{h_1 h_2} * (2*2)_{Gamma_1 Gamma_2} - // h_i: c,s + // hi: c,s // Gamma = 1, gamma_5 - double *****C_hihj_Gamma1Gamma2 = (double *****) callocMultiDimensional({2,2,2,2,T}, 5, sizeof(double)); - double ****res_hihj_Gamma1Gamma2 = (double ****) callocMultiDimensional({2,2,2,2}, 4, sizeof(double)); + double *****C_hihj_g1g2 = (double *****) callocMultiDimensional({2,2,2,2,T}, 5, sizeof(double)); + double ****res_hihj_g1g2 = (double ****) callocMultiDimensional({2,2,2,2}, 4, sizeof(double)); #ifdef TM_USE_MPI - double ****mpi_res_hihj_Gamma1Gamma2 = (double ****) callocMultiDimensional({2,2,2,2}, 4, sizeof(double)); + double ****mpi_res_hihj_g1g2 = (double ****) callocMultiDimensional({2,2,2,2}, 4, sizeof(double)); // send buffer for MPI_Gather - double *****sC_hihj_Gamma1Gamma2 = (double *****) callocMultiDimensional({2,2,2,2,T}, 5, sizeof(double)); + double *****sC_hihj_g1g2 = (double *****) callocMultiDimensional({2,2,2,2,T}, 5, sizeof(double)); #endif FILE *ofs; // output file stream @@ -594,8 +594,8 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, for (size_t i_f = 0; i_f < 2; i_f++) { for (size_t j_f = 0; j_f < 2; j_f++) { - for (size_t i_Gamma1 = 0; i_Gamma1 < 2; i_Gamma1++) { - for (size_t i_Gamma2 = 0; i_Gamma2 < 2; i_Gamma2++) { + for (size_t g1 = 0; g1 < 2; g1++) { + for (size_t g2 = 0; g2 < 2; g2++) { for (size_t beta1 = 0; beta1 < 4; beta1++) { for (size_t beta2 = 0; beta2 < 4; beta2++) { double dum1, dum2 = 0.0, 0.0; // dummy variables @@ -614,7 +614,7 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, } _spinor_scalar_prod(dum2, arr_spinor[0][1][beta_2][j_f][i], phi); - res_hihj_Gamma1Gamma2[i_f][j_f][beta_1][beta_2] += dum1 * dum2; + res_hihj_g1g2[i_f][j_f][beta_1][beta_2] += dum1 * dum2; } } } @@ -647,14 +647,14 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, for (size_t i_f = 0; i_f < 2; i_f++) { for (size_t j_f = 0; j_f < 2; j_f++) { - for (size_t i_Gamma1 = 0; i_Gamma1 < 2; i_Gamma1++) { - for (size_t i_Gamma2 = 0; i_Gamma2 < 2; i_Gamma2++) { + for (size_t g1 = 0; g1 < 2; g1++) { + for (size_t g2 = 0; g2 < 2; g2++) { #if defined TM_USE_MPI - MPI_Reduce(&res_hihj_Gamma1Gamma2[i_f][j_f][beta_1][beta_2], &mpi_res_hihj_Gamma1Gamma2[i_f][j_f][beta_1][beta_2], 1, MPI_DOUBLE, MPI_SUM, 0, g_mpi_time_slices); - res_hihj_Gamma1Gamma2[i_f][j_f][beta_1][beta_2] = mpi_res_hihj_Gamma1Gamma2[i_f][j_f][beta_1][beta_2]; - C_hihj_Gamma1Gamma2[i_f][j_f][beta_1][beta_2][t] = -eta_Gamma[i_Gamma1]*res / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ); + MPI_Reduce(&res_hihj_g1g2[i_f][j_f][beta_1][beta_2], &mpi_res_hihj_g1g2[i_f][j_f][beta_1][beta_2], 1, MPI_DOUBLE, MPI_SUM, 0, g_mpi_time_slices); + res_hihj_g1g2[i_f][j_f][beta_1][beta_2] = mpi_res_hihj_g1g2[i_f][j_f][beta_1][beta_2]; + C_hihj_g1g2[i_f][j_f][beta_1][beta_2][t] = -eta_Gamma[g1]*res / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ); #else - C_hihj_Gamma1Gamma2[i_f][j_f][beta_1][beta_2][t] = -eta_Gamma[i_Gamma1]*res / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ); + C_hihj_g1g2[i_f][j_f][beta_1][beta_2][t] = -eta_Gamma[g1]*res / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ); #endif } } @@ -674,9 +674,9 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, // heavy mesons for (size_t i_f = 0; i_f < 2; i_f++) { for (size_t j_f = 0; j_f < 2; j_f++) { - for (size_t i_Gamma1 = 0; i_Gamma1 < 2; i_Gamma1++) { - for (size_t i_Gamma2 = 0; i_Gamma2 < 2; i_Gamma2++) { - MPI_Gather(sC_hihj_Gamma1Gamma2[i_f][j_f][beta_1][beta_2], T, MPI_DOUBLE, C_hihj_Gamma1Gamma2[i_f][j_f][beta_1][beta_2], T, MPI_DOUBLE, 0, g_mpi_SV_slices); + for (size_t g1 = 0; g1 < 2; g1++) { + for (size_t g2 = 0; g2 < 2; g2++) { + MPI_Gather(sC_hihj_g1g2[i_f][j_f][beta_1][beta_2], T, MPI_DOUBLE, C_hihj_g1g2[i_f][j_f][beta_1][beta_2], T, MPI_DOUBLE, 0, g_mpi_SV_slices); } } } @@ -718,19 +718,20 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, fprintf(ofs, "6 1 %d %e %e\n", t, Cp4[tt], 0.); - for (size_t i_f = 0; i_f < 2; i_f++) { - for (size_t j_f = 0; j_f < 2; j_f++) { - for (size_t i_Gamma1 = 0; i_Gamma1 < 2; i_Gamma1++) { - for (size_t i_Gamma2 = 0; i_Gamma2 < 2; i_Gamma2++) { - fprintf(ofs, "%d %d %d %d 0 %e %e\n", i_f, j_f, i_Gamma1, i_Gamma2, C_hihj_Gamma1Gamma2[i_f][j_f][beta_1][beta_2][t0], 0.); + // heavy meson correlators + for (size_t hi = 0; hi < 2; hi++) { + for (size_t hj = 0; hj < 2; hj++) { + for (size_t g1 = 0; g1 < 2; g1++) { + for (size_t g2 = 0; g2 < 2; g2++) { + fprintf(ofs, "%d %d %d %d 0 %e %e\n", hi, hj, g1, g2, C_hihj_g1g2[hi][hj][g1][g1][t0], 0.); for (t = 1; t < g_nproc_t * T / 2; t++) { tt = (t0 + t) % (g_nproc_t * T); - fprintf(ofs, "%d %d %d %d %d %e ", i_f, j_f, i_Gamma1, i_Gamma2, t, C_hihj_Gamma1Gamma2[i_f][j_f][beta_1][beta_2][tt]); + fprintf(ofs, "%d %d %d %d %d %e ", hi, hj, g1, g2, t, C_hihj_g1g2[hi][hj][g1][g2][tt]); tt = (t0 + g_nproc_t * T - t) % (g_nproc_t * T); - fprintf(ofs, "%e\n", C_hihj_Gamma1Gamma2[i_f][j_f][beta_1][beta_2][tt]); + fprintf(ofs, "%e\n", C_hihj_g1g2[hi][hj][g1][g2][tt]); } tt = (t0 + g_nproc_t * T / 2) % (g_nproc_t * T); - fprintf(ofs, "%d %d %d %d %d %d %e %e\n", i_f, j_f, i_Gamma1, i_Gamma2, t, C_hihj_Gamma1Gamma2[i_f][j_f][beta_1][beta_2][tt], 0.0); + fprintf(ofs, "%d %d %d %d %d %d %e %e\n", hi, hj, g1, g2, t, C_hihj_g1g2[hi][hj][g1][g2][tt], 0.0); } } } @@ -743,17 +744,17 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, free(Cpp); free(Cpa); free(Cp4); - free(C_hihj_Gamma1Gamma2); + free(C_hihj_g1g2); } free(sCpp); free(sCpa); free(sCp4); - free(sC_hihj_Gamma1Gamma2); + free(sC_hihj_g1g2); #else free(Cpp); free(Cpa); free(Cp4); - free(C_hihj_Gamma1Gamma2); + free(C_hihj_g1g2); #endif } // for(max_time_slices) } // for(max_samples) From 3f57f5b0de2639d9a7feb6b50d05e265be5c4519 Mon Sep 17 00:00:00 2001 From: simone-romiti Date: Tue, 18 Jul 2023 11:25:01 +0200 Subject: [PATCH 22/51] MPI reduce and gather for bulding correlator C(t) --- meas/correlators.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/meas/correlators.c b/meas/correlators.c index afcfd7b35..69205e1ef 100644 --- a/meas/correlators.c +++ b/meas/correlators.c @@ -645,16 +645,16 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, optr1->kappa / optr1->kappa; #endif - for (size_t i_f = 0; i_f < 2; i_f++) { - for (size_t j_f = 0; j_f < 2; j_f++) { + for (size_t hi = 0; hi < 2; hi++) { + for (size_t hj = 0; hj < 2; hj++) { for (size_t g1 = 0; g1 < 2; g1++) { for (size_t g2 = 0; g2 < 2; g2++) { #if defined TM_USE_MPI - MPI_Reduce(&res_hihj_g1g2[i_f][j_f][beta_1][beta_2], &mpi_res_hihj_g1g2[i_f][j_f][beta_1][beta_2], 1, MPI_DOUBLE, MPI_SUM, 0, g_mpi_time_slices); - res_hihj_g1g2[i_f][j_f][beta_1][beta_2] = mpi_res_hihj_g1g2[i_f][j_f][beta_1][beta_2]; - C_hihj_g1g2[i_f][j_f][beta_1][beta_2][t] = -eta_Gamma[g1]*res / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ); + MPI_Reduce(&res_hihj_g1g2[hi][hj][g1][g2], &mpi_res_hihj_g1g2[hi][hj][g1][g2], 1, MPI_DOUBLE, MPI_SUM, 0, g_mpi_time_slices); + res_hihj_g1g2[hi][hj][g1][g2] = mpi_res_hihj_g1g2[hi][hj][g1][g2]; + C_hihj_g1g2[hi][hj][g1][g2][t] = -eta_Gamma[g1] * res / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ); #else - C_hihj_g1g2[i_f][j_f][beta_1][beta_2][t] = -eta_Gamma[g1]*res / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ); + C_hihj_g1g2[hi][hj][g1][g2][t] = -eta_Gamma[g1] * res / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ); #endif } } @@ -672,11 +672,11 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, MPI_Gather(sCp4, T, MPI_DOUBLE, Cp4, T, MPI_DOUBLE, 0, g_mpi_SV_slices); // heavy mesons - for (size_t i_f = 0; i_f < 2; i_f++) { - for (size_t j_f = 0; j_f < 2; j_f++) { + for (size_t hi = 0; hi < 2; hi++) { + for (size_t hj = 0; hj < 2; hj++) { for (size_t g1 = 0; g1 < 2; g1++) { for (size_t g2 = 0; g2 < 2; g2++) { - MPI_Gather(sC_hihj_g1g2[i_f][j_f][beta_1][beta_2], T, MPI_DOUBLE, C_hihj_g1g2[i_f][j_f][beta_1][beta_2], T, MPI_DOUBLE, 0, g_mpi_SV_slices); + MPI_Gather(sC_hihj_g1g2[hi][hj][g1][g2], T, MPI_DOUBLE, C_hihj_g1g2[hi][hj][g1][g2], T, MPI_DOUBLE, 0, g_mpi_SV_slices); } } } From 159bf49ddd746f1960b2ad290c3206092b1a6d4e Mon Sep 17 00:00:00 2001 From: simone-romiti Date: Tue, 18 Jul 2023 11:50:38 +0200 Subject: [PATCH 23/51] C(t) volume average over spinor scalar products --- meas/correlators.c | 54 +++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 29 deletions(-) diff --git a/meas/correlators.c b/meas/correlators.c index 69205e1ef..6f2f56c01 100644 --- a/meas/correlators.c +++ b/meas/correlators.c @@ -546,9 +546,9 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, } } - // (no even-odd): source+propagator, doublet, spin dilution index, even-odd, flavor, position (+ Dirac, color) - // (psi[i_sp][phi][beta][f][x])[alpha][c] // last 3 indices are proper of the spinor struct - spinor *****arr_spinor = (spinor *****) callocMultiDimensional({2,2,4,2,VOLUME}, 5, sizeof(spinor)); + // (no even-odd): source+propagator, doublet, spin dilution index, flavor proj, flavor index, position (+ Dirac, color) + // (psi[i_sp][d][beta][F][f][x])[alpha][c] // last 3 indices are proper of the spinor struct + spinor ******arr_spinor = (spinor ******) callocMultiDimensional({2,2,4,2,2,VOLUME}, 6, sizeof(spinor)); // now we switch from even-odd representation to standard for (size_t i_sp = 0; i_sp < 2; i_sp++) { // source or sink @@ -581,40 +581,36 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, for (i = j; i < j + LX * LY * LZ; i++) { // light correlators for (size_t beta = 0; beta < 4; beta++) { // spin dilution - double sign = 1.0; // the light source sould be multiplied by gamma_5 - if(beta >= 2){ + double sign = 1.0; // the light source sould be multiplied by gamma_5 + if (beta >= 2) { sign = -1.0; } - res += sign*_spinor_prod_re(arr_spinor[1][0][beta][0][i], arr_spinor[1][0][beta][0][i]); + res += + sign * _spinor_prod_re(arr_spinor[1][0][beta][0][i], arr_spinor[1][0][beta][0][i]); _gamma0(phi, arr_spinor[1][0][beta][0][i]); - respa += sign*_spinor_prod_re(arr_spinor[1][0][beta][0][i], phi); + respa += sign * _spinor_prod_re(arr_spinor[1][0][beta][0][i], phi); _gamma5(phi, phi); - resp4 += sign*_spinor_prod_im(arr_spinor[1][0][beta][0][i], phi); + resp4 += sign * _spinor_prod_im(arr_spinor[1][0][beta][0][i], phi); } - for (size_t i_f = 0; i_f < 2; i_f++) { - for (size_t j_f = 0; j_f < 2; j_f++) { - for (size_t g1 = 0; g1 < 2; g1++) { - for (size_t g2 = 0; g2 < 2; g2++) { - for (size_t beta1 = 0; beta1 < 4; beta1++) { - for (size_t beta2 = 0; beta2 < 4; beta2++) { - double dum1, dum2 = 0.0, 0.0; // dummy variables - - // 1st contribution - phi = arr_spinor[1][1][beta_2][i_f][i]; - if (Gamma_1 == 1) { // Gamma_1 = 1 + const int f0 = 0; // flavor index of the up + for (size_t F = 0; F < 4; F++) { // flavor projection + for (size_t beta = 0; beta < 4; beta++) { // spin dilution + spinor psi_u = arr_spinor[1][0][beta][f0][f0][i]; + for (size_t hi = 0; hi < 2; hi++) { + for (size_t hj = 0; hj < 2; hj++) { + for (size_t g1 = 0; g1 < 2; g1++) { + for (size_t g2 = 0; g2 < 2; g2++) { + double dum = 0.0; // dummy variable + + // heavy doublet spinor propagator + phi = arr_spinor[1][1][beta][hj][hi][i]; + if (g1 == 1) { // Gamma_1 = 1 _gamma5(phi, phi); } - _spinor_scalar_prod(dum1, arr_spinor[0][0][beta_1][1 - i_f][i], phi); + _spinor_scalar_prod(dum, psi_u, phi); - // 2nd contribution - phi = arr_spinor[1][0][beta_1][1 - j_f][i]; - if (Gamma_2 == 1) { // Gamma_1 = gamma_5 - _gamma5(phi, phi); - } - _spinor_scalar_prod(dum2, arr_spinor[0][1][beta_2][j_f][i], phi); - - res_hihj_g1g2[i_f][j_f][beta_1][beta_2] += dum1 * dum2; + res_hihj_g1g2[hi][hj][g1][g2] += dum; } } } @@ -652,7 +648,7 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, #if defined TM_USE_MPI MPI_Reduce(&res_hihj_g1g2[hi][hj][g1][g2], &mpi_res_hihj_g1g2[hi][hj][g1][g2], 1, MPI_DOUBLE, MPI_SUM, 0, g_mpi_time_slices); res_hihj_g1g2[hi][hj][g1][g2] = mpi_res_hihj_g1g2[hi][hj][g1][g2]; - C_hihj_g1g2[hi][hj][g1][g2][t] = -eta_Gamma[g1] * res / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ); + sC_hihj_g1g2[hi][hj][g1][g2][t] = -eta_Gamma[g1] * res / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ); #else C_hihj_g1g2[hi][hj][g1][g2][t] = -eta_Gamma[g1] * res / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ); #endif From 00d9cdc892b3c76a8215e9da41bc4bada99b778e Mon Sep 17 00:00:00 2001 From: simone-romiti Date: Tue, 18 Jul 2023 17:37:28 +0200 Subject: [PATCH 24/51] todo: add gamma_5*Gamma_2 case condition for the light spinor --- meas/correlators.c | 759 +++++++++++++++++++++++---------------------- 1 file changed, 389 insertions(+), 370 deletions(-) diff --git a/meas/correlators.c b/meas/correlators.c index 6f2f56c01..a957c1059 100644 --- a/meas/correlators.c +++ b/meas/correlators.c @@ -307,419 +307,438 @@ void* callocMultiDimensional(int* sizes, int numDimensions, size_t elementSize) * ******************************************************/ void heavy_correlators_measurement(const int traj, const int id, const int ieo, const int i1, - const int i2) { - tm_stopwatch_push(&g_timers, __func__, ""); // timer for profiling + const int i2) { + tm_stopwatch_push(&g_timers, __func__, ""); // timer for profiling - spinor phi; // dummy spinor - int i, j, t, tt, t0; // dummy indices - float tmp; // dummy variable + spinor phi; // dummy spinor + int i, j, t, tt, t0; // dummy indices + float tmp; // dummy variable - - /* light-light correlators: dummy variables */ + /* light-light correlators: dummy variables */ - // array of the values of the correlator C(t) - double *Cpp = NULL, *Cpa = NULL, *Cp4 = NULL; - // result of the accumulation of MPI partial sums - double res = 0., respa = 0., resp4 = 0.; + // array of the values of the correlator C(t) + double *Cpp = NULL, *Cpa = NULL, *Cp4 = NULL; + // result of the accumulation of MPI partial sums + double res = 0., respa = 0., resp4 = 0.; #ifdef TM_USE_MPI - double mpi_res = 0., mpi_respa = 0., mpi_resp4 = 0.; - // send buffer for MPI_Gather - double *sCpp = NULL, *sCpa = NULL, *sCp4 = NULL; + double mpi_res = 0., mpi_respa = 0., mpi_resp4 = 0.; + // send buffer for MPI_Gather + double *sCpp = NULL, *sCpa = NULL, *sCp4 = NULL; #endif #ifdef TM_USE_MPI - sCpp = (double *)calloc(T, sizeof(double)); - sCpa = (double *)calloc(T, sizeof(double)); - sCp4 = (double *)calloc(T, sizeof(double)); - if (g_mpi_time_rank == 0) { - Cpp = (double *)calloc(g_nproc_t * T, sizeof(double)); - Cpa = (double *)calloc(g_nproc_t * T, sizeof(double)); - Cp4 = (double *)calloc(g_nproc_t * T, sizeof(double)); - } + sCpp = (double *)calloc(T, sizeof(double)); + sCpa = (double *)calloc(T, sizeof(double)); + sCp4 = (double *)calloc(T, sizeof(double)); + if (g_mpi_time_rank == 0) { + Cpp = (double *)calloc(g_nproc_t * T, sizeof(double)); + Cpa = (double *)calloc(g_nproc_t * T, sizeof(double)); + Cp4 = (double *)calloc(g_nproc_t * T, sizeof(double)); + } #else - Cpp = (double *)calloc(T, sizeof(double)); - Cpa = (double *)calloc(T, sizeof(double)); - Cp4 = (double *)calloc(T, sizeof(double)); + Cpp = (double *)calloc(T, sizeof(double)); + Cpa = (double *)calloc(T, sizeof(double)); + Cp4 = (double *)calloc(T, sizeof(double)); #endif - /* heavy-light correlators variables */ - double eta_Gamma[2] = {1.0, -1.0}; // sign change compensation from daggering bilinear with Gamma = 1,gamma_5 + /* heavy-light correlators variables */ + double eta_Gamma[2] = { + 1.0, -1.0}; // sign change compensation from daggering bilinear with Gamma = 1,gamma_5 - // the number of independent correlators is 16 = (2*2)_{h_1 h_2} * (2*2)_{Gamma_1 Gamma_2} - // hi: c,s - // Gamma = 1, gamma_5 - double *****C_hihj_g1g2 = (double *****) callocMultiDimensional({2,2,2,2,T}, 5, sizeof(double)); - double ****res_hihj_g1g2 = (double ****) callocMultiDimensional({2,2,2,2}, 4, sizeof(double)); + // the number of independent correlators is 16 = (2*2)_{h_1 h_2} * (2*2)_{Gamma_1 Gamma_2} + // hi: c,s + // Gamma = 1, gamma_5 + double *****C_hihj_g1g2 = + (double *****)callocMultiDimensional({2, 2, 2, 2, T}, 5, sizeof(double)); + double ****res_hihj_g1g2 = (double ****)callocMultiDimensional({2, 2, 2, 2}, 4, sizeof(double)); #ifdef TM_USE_MPI - double ****mpi_res_hihj_g1g2 = (double ****) callocMultiDimensional({2,2,2,2}, 4, sizeof(double)); - // send buffer for MPI_Gather - double *****sC_hihj_g1g2 = (double *****) callocMultiDimensional({2,2,2,2,T}, 5, sizeof(double)); + double ****mpi_res_hihj_g1g2 = + (double ****)callocMultiDimensional({2, 2, 2, 2}, 4, sizeof(double)); + // send buffer for MPI_Gather + double *****sC_hihj_g1g2 = + (double *****)callocMultiDimensional({2, 2, 2, 2, T}, 5, sizeof(double)); #endif - FILE *ofs; // output file stream - char filename[TM_OMEAS_FILENAME_LENGTH]; // file path + FILE *ofs; // output file stream + char filename[TM_OMEAS_FILENAME_LENGTH]; // file path - /* building the stochastic propagator spinors needed for the correlators */ + /* building the stochastic propagator spinors needed for the correlators */ - init_operators(); // initialize the operators in the action (if not already done) - if (no_operators < 1) { - if (g_proc_id == 0) { - // we don't want the simulation to stop, we can do the measurements offline afterwards - fprintf(stderr, - "Warning! no operators defined in input file, cannot perform online correlator " - "mesurements!\n"); + init_operators(); // initialize the operators in the action (if not already done) + if (no_operators < 1) { + if (g_proc_id == 0) { + // we don't want the simulation to stop, we can do the measurements offline afterwards + fprintf(stderr, + "Warning! no operators defined in input file, cannot perform online correlator " + "mesurements!\n"); + } + tm_stopwatch_pop(&g_timers, 0, 0, ""); // timer for profiling + return; } - tm_stopwatch_pop(&g_timers, 0, 0, ""); // timer for profiling - return; - } - // selecting the operators i1 and i2 from the list of operators initialized before - operator* optr1 = & operator_list[i1]; // light doublet - operator* optr2 = & operator_list[i2]; // heavy c,s doublet - - bool b1 = (optr->type != TMWILSON && optr->type != WILSON && optr->type != CLOVER); - bool b2 = (optr2->type != DBTMWILSON && optr2->type != DBCLOVER); - if(b1 || b2) { - if (g_proc_id == 0) { - if(b1){ - fprintf(stderr, "Warning! optr1 should be one of the following: TMWILSON, WILSON and CLOVER\n"); - fprintf(stderr, "Cannot perform correlator online measurement!\n"); - } - if (b2) { - fprintf(stderr, "Warning! optr2 should be one of the following: DBTMWILSON, DBCLOVER\n"); - } - fprintf(stderr, "Cannot perform correlator online measurement!\n"); + // selecting the operators i1 and i2 from the list of operators initialized before + operator* optr1 = & operator_list[i1]; // light doublet + operator* optr2 = & operator_list[i2]; // heavy c,s doublet + + bool b1 = (optr->type != TMWILSON && optr->type != WILSON && optr->type != CLOVER); + bool b2 = (optr2->type != DBTMWILSON && optr2->type != DBCLOVER); + if (b1 || b2) { + if (g_proc_id == 0) { + if (b1) { + fprintf( + stderr, + "Warning! optr1 should be one of the following: TMWILSON, WILSON and CLOVER\n"); + fprintf(stderr, "Cannot perform correlator online measurement!\n"); + } + if (b2) { + fprintf(stderr, + "Warning! optr2 should be one of the following: DBTMWILSON, DBCLOVER\n"); + } + fprintf(stderr, "Cannot perform correlator online measurement!\n"); + } + tm_stopwatch_pop(&g_timers, 0, 0, ""); // timer for profiling + return; } - tm_stopwatch_pop(&g_timers, 0, 0, ""); // timer for profiling - return; - } - if (ranlxs_init == 0) { - rlxs_init(1, 123456); // initializing random number generator RANLUX - } + if (ranlxs_init == 0) { + rlxs_init(1, 123456); // initializing random number generator RANLUX + } - // there are three modes of operation - // 1) one single time-slice source (default) - // 2) no_samples time-slice sources on random time-slices - // 3) one sample on all time-slices - int max_samples = measurement_list[id].all_time_slices ? 1 : measurement_list[id].no_samples; - int max_time_slices = - measurement_list[id].all_time_slices ? measurement_list[id].max_source_slice : 1; - for (int sample = 0; sample < max_samples; sample++) { - for (int ts = 0; ts < max_time_slices; ts++) { - // setting output filename - if (max_samples == 1 && max_time_slices == 1) { - snprintf(filename, TM_OMEAS_FILENAME_LENGTH, "%s%06d", "heavy_mesons.", traj); - } else if (max_samples == 1 && max_time_slices > 1) { - snprintf(filename, TM_OMEAS_FILENAME_LENGTH, "%s.t%03d.%06d", "heavy_mesons", ts, traj); - } else { - snprintf(filename, TM_OMEAS_FILENAME_LENGTH, "%s.s%03d.%06d", "heavy_mesons", sample, traj); - } + // there are three modes of operation + // 1) one single time-slice source (default) + // 2) no_samples time-slice sources on random time-slices + // 3) one sample on all time-slices + int max_samples = measurement_list[id].all_time_slices ? 1 : measurement_list[id].no_samples; + int max_time_slices = + measurement_list[id].all_time_slices ? measurement_list[id].max_source_slice : 1; + for (int sample = 0; sample < max_samples; sample++) { + for (int ts = 0; ts < max_time_slices; ts++) { + // setting output filename + if (max_samples == 1 && max_time_slices == 1) { + snprintf(filename, TM_OMEAS_FILENAME_LENGTH, "%s%06d", "heavy_mesons.", traj); + } else if (max_samples == 1 && max_time_slices > 1) { + snprintf(filename, TM_OMEAS_FILENAME_LENGTH, "%s.t%03d.%06d", "heavy_mesons", ts, + traj); + } else { + snprintf(filename, TM_OMEAS_FILENAME_LENGTH, "%s.s%03d.%06d", "heavy_mesons", + sample, traj); + } - /* generate random timeslice */ - t0 = ts; - if (!measurement_list[id].all_time_slices) { - ranlxs(&tmp, 1); - t0 = (int)(measurement_list[id].max_source_slice * tmp); - } + /* generate random timeslice */ + t0 = ts; + if (!measurement_list[id].all_time_slices) { + ranlxs(&tmp, 1); + t0 = (int)(measurement_list[id].max_source_slice * tmp); + } #ifdef TM_USE_MPI - MPI_Bcast(&t0, 1, MPI_INT, 0, MPI_COMM_WORLD); // broadcast t0 to all the ranks + MPI_Bcast(&t0, 1, MPI_INT, 0, MPI_COMM_WORLD); // broadcast t0 to all the ranks #endif - if (g_debug_level > 1 && g_proc_id == 0) { - printf("# timeslice set to %d (T=%d) for online measurement\n", t0, g_nproc_t * T); - printf("# online measurements parameters: kappa = %.12f, mubar = %.12f, epsbar = %.12f\n", - optr1->kappa, optr1->mubar, optr1->epsbar); - } - - ///////////// OLD COMMENT - ///////////// the gamma matrix in front specifies if we are working with - ///////////// psi_1 or psi_2 of eqs. (2.7, 2.8) https://arxiv.org/pdf/0804.1501.pdf - //////////// END OLD COMMENT - // even-odd spinor fields for the light and heavy doublet correlators - // INDICES: source+propagator, doublet, spin dilution index, even-odd, flavor, position (+ Dirac, color) - // psi = (psi[(s,p)][phi][beta][eo][f][x])[alpha][c] // last 3 indices are proper of the spinor struct - // Note: propagator in the sense that it is D^{-1}*source after the inversion - - spinor ******arr_eo_spinor = (spinor ******)callocMultiDimensional({2,2,4,2,2,VOLUME/2}, 6, sizeof(spinor)); - - /* initalize the random sources: one source for each Dirac index beta=src_d --> spin dilution */ - const unsigned int seed_i = measurement_list[id].seed; // has to be same seed - for (size_t i_phi = 0; i_phi < 2; i_phi++) { // doublet: light or heavy - for (size_t src_d = 0; src_d < 4; src_d++) { // spin dilution index - for (size_t i_f = 0; i_f < 2; i_f++) { // flavor index of the doublet - // light doublet - eo_source_spinor_field_spin_diluted_oet_ts(arr_eo_spinor[0][i_phi][src_d][0][i_f], - arr_eo_spinor[0][i_phi][src_d][1][i_f], t0, - src_d, sample, traj, seed_i); - } - } - } - - // heavy doublet: for each even-odd block, I multiply by (1 + i*tau_2)/sqrt(2) - // the basis for the inversion should be the same as for the light - // --> I will multiply later by the inverse, namely at the end of the inversion - for (size_t src_d = 0; src_d < 4; src_d++) { // spin dilution index - for (size_t i_eo = 0; i_eo < 2; i_eo++) { - // (c,s) --> [(1+i*tau_2)/sqrt(2)] * (c,s) , stored at temporarely in the propagator - // spinors (used as dummy spinors) - mul_one_pm_itau2_and_div_by_sqrt2(arr_eo_spinor[1][1][src_d][i_eo][0], - arr_eo_spinor[1][1][src_d][i_eo][0 + 1], - arr_eo_spinor[0][1][src_d][i_eo][0], - arr_eo_spinor[0][1][src_d][i_eo][0 + 1], +1.0, - VOLUME / 2); - for (size_t i_f = 0; i_f < 2; i_f++) { - // assigning the result to the first components (the sources). - // The propagators will be overwritten with the inversion - assign(arr_eo_spinor[0][1][src_d][i_eo][i_f], - arr_eo_spinor[1][1][src_d][i_eo][i_f], VOLUME / 2); - } - } - } - - /* - assign the sources and propagator pointes for the operators - these need to be know when calling the inverter() method - */ - // psi = (psi[(s,p)][phi][beta][eo][f][x])[alpha][c] // last 3 indices are proper of the spinor struct + if (g_debug_level > 1 && g_proc_id == 0) { + printf("# timeslice set to %d (T=%d) for online measurement\n", t0, g_nproc_t * T); + printf( + "# online measurements parameters: kappa = %.12f, mubar = %.12f, epsbar = " + "%.12f\n", + optr1->kappa, optr1->mubar, optr1->epsbar); + } - for (size_t src_d = 0; src_d < 4; src_d++) { // spin dilution index - /* light doublet */ + // even-odd spinor fields for the light and heavy doublet correlators + // INDICES: source+propagator, doublet, spin dilution index, flavor projection, even-odd, flavor, position + // (+ Dirac, color) psi = (psi[(s,p)][db][beta][F][eo][f][x])[alpha][c] + // last 3 indices come from spinor struct + // Note: propagator in the sense that it is D^{-1}*source after the inversion + spinor *******arr_eo_spinor = (spinor *******)callocMultiDimensional( + {2, 2, 4, 2, 2, 2, VOLUME / 2}, 7, sizeof(spinor)); + + /* initalize the random sources: one source for each Dirac index beta=src_d --> spin + * dilution */ + const unsigned int seed_i = measurement_list[id].seed; // has to be same seed + for (size_t db = 0; db < 2; db++) { // doublet: light or heavy + for (size_t beta = 0; beta < 4; beta++) { // spin dilution index + for (size_t F = 0; F < 2; F++) { // flavor index of the doublet + for (size_t i_f = 0; i_f < 2; i_f++) { // flavor index of the doublet + // light doublet + eo_source_spinor_field_spin_diluted_oet_ts(arr_eo_spinor[0][db][beta][0][i_f], + arr_eo_spinor[0][db][beta][1][i_f], t0, + beta, sample, traj, seed_i); + } + } + } + } - // up + // heavy doublet: for each even-odd block, I multiply by (1 + i*tau_2)/sqrt(2) + // the basis for the inversion should be the same as for the light + // --> I will multiply later by the inverse, namely at the end of the inversion + for (size_t beta = 0; beta < 4; beta++) { // spin dilution index + for (size_t F = 0; F < 2; F++) { // flavor projection index + for (size_t i_eo = 0; i_eo < 2; i_eo++) { // even-odd + // (c,s) --> [(1-i*tau_2)/sqrt(2)] * (c,s) + // stored temporarely in the propagator spinors (used as dummy) + mul_one_pm_itau2_and_div_by_sqrt2( + arr_eo_spinor[1][1][beta][F][i_eo][0], arr_eo_spinor[1][1][beta][F][i_eo][1], + arr_eo_spinor[0][1][beta][F][i_eo][0], arr_eo_spinor[0][1][beta][F][i_eo][1], +1.0, + VOLUME / 2); + + for (size_t i_f = 0; i_f < 2; i_f++) { + // assigning the result to the first components (the sources). + // The propagators will be overwritten with the inversion + assign(arr_eo_spinor[0][1][beta][F][i_eo][i_f], + arr_eo_spinor[1][1][beta][F][i_eo][i_f], VOLUME / 2); + } + } + } + } - // sorces - optr1->sr0 = arr_eo_spinor[0][0][src_d][0][0]; - optr1->sr1 = arr_eo_spinor[0][0][src_d][1][0]; - // propagators - optr1->prop0 = arr_eo_spinor[1][0][src_d][0][0]; - optr1->prop1 = arr_eo_spinor[1][0][src_d][1][0]; + /* + assign the sources and propagator pointes for the operators + these need to be know when calling the inverter() method */ + for (size_t beta = 0; beta < 4; beta++) { // spin dilution index + /* light doublet */ - optr1->inverter(i1, 0, 0); // inversion for the up flavor + // up - // inversion of the light doublet only inverts the up block (the operator is diagonal in flavor) - // down components in flavor will be empty - optr1->DownProp = 1; + // sorces + optr1->sr0 = arr_eo_spinor[0][0][beta][0][0]; + optr1->sr1 = arr_eo_spinor[0][0][beta][1][0]; + // propagators + optr1->prop0 = arr_eo_spinor[1][0][beta][0][0]; + optr1->prop1 = arr_eo_spinor[1][0][beta][1][0]; - // sources - optr1->sr0 = arr_eo_spinor[0][0][src_d][0][1]; - optr1->sr1 = arr_eo_spinor[0][0][src_d][1][1]; - //propagator - optr1->prop0 = arr_eo_spinor[1][0][src_d][0][1]; - optr1->prop1 = arr_eo_spinor[1][0][src_d][1][1]; + optr1->inverter(i1, 0, 0); // inversion for the up flavor - optr1->inverter(i1, 0, 0); //inversion for the down + // // inversion of the light doublet only inverts the up block (the operator is + // // diagonal in flavor) down components in flavor will be empty + // optr1->DownProp = 1; - optr1->DownProp = 0; //restoring to default + // // sources + // optr1->sr0 = arr_eo_spinor[0][0][beta][0][1]; + // optr1->sr1 = arr_eo_spinor[0][0][beta][1][1]; + // // propagator + // optr1->prop0 = arr_eo_spinor[1][0][beta][0][1]; + // optr1->prop1 = arr_eo_spinor[1][0][beta][1][1]; - /* heavy doublet */ - - optr1->sr0 = arr_eo_spinor[0][1][src_d][0][0]; - optr1->sr1 = arr_eo_spinor[0][1][src_d][1][0]; - optr1->sr2 = arr_eo_spinor[0][1][src_d][0][1]; - optr1->sr3 = arr_eo_spinor[0][1][src_d][1][1]; + // optr1->inverter(i1, 0, 0); // inversion for the down - optr1->prop0 = arr_eo_spinor[1][1][src_d][0][0]; - optr1->prop1 = arr_eo_spinor[1][1][src_d][1][0]; - optr1->prop2 = arr_eo_spinor[1][1][src_d][0][1]; - optr1->prop3 = arr_eo_spinor[1][1][src_d][1][1]; + // optr1->DownProp = 0; // restoring to default - optr2->inverter(i2, 0, 0); // inversion for both flavor components - } + /* heavy doublet */ + optr1->sr0 = arr_eo_spinor[0][1][beta][0][0]; + optr1->sr1 = arr_eo_spinor[0][1][beta][1][0]; + optr1->sr2 = arr_eo_spinor[0][1][beta][0][1]; + optr1->sr3 = arr_eo_spinor[0][1][beta][1][1]; - // conclude the change of basis for the heavy doublet - for (size_t src_d = 0; src_d < 4; src_d++) { // spin dilution index - for (size_t i_eo = 0; i_eo < 2; i_eo++) { - // (c,s) --> [(1-i*tau_2)/sqrt(2)] * (c,s) , stored at temporarely in the propagator - // spinors (used as dummy spinors) - mul_one_pm_itau2_and_div_by_sqrt2(arr_eo_spinor[1][1][src_d][i_eo][0], - arr_eo_spinor[1][1][src_d][i_eo][1], - arr_eo_spinor[0][1][src_d][i_eo][0], - arr_eo_spinor[0][1][src_d][i_eo][1], -1.0, - VOLUME / 2); - for (size_t i_f = 0; i_f < 2; i_f++) { - // assigning the result to the first components (the sources). - // The propagators will be overwritten with the inversion - assign(arr_eo_spinor[0][1][src_d][i_eo][i_f], - arr_eo_spinor[1][1][src_d][i_eo][i_f], VOLUME / 2); - } - } - } + optr1->prop0 = arr_eo_spinor[1][1][beta][0][0]; + optr1->prop1 = arr_eo_spinor[1][1][beta][1][0]; + optr1->prop2 = arr_eo_spinor[1][1][beta][0][1]; + optr1->prop3 = arr_eo_spinor[1][1][beta][1][1]; - // (no even-odd): source+propagator, doublet, spin dilution index, flavor proj, flavor index, position (+ Dirac, color) - // (psi[i_sp][d][beta][F][f][x])[alpha][c] // last 3 indices are proper of the spinor struct - spinor ******arr_spinor = (spinor ******) callocMultiDimensional({2,2,4,2,2,VOLUME}, 6, sizeof(spinor)); - - // now we switch from even-odd representation to standard - for (size_t i_sp = 0; i_sp < 2; i_sp++) { // source or sink - for (size_t i_phi = 0; i_phi < 2; i_phi++) { // doublet index - for (size_t src_d = 0; src_d < 4; src_d++) { // spin dilution index - for (size_t i_f = 0; i_f < 2; i_f++) { - convert_eo_to_lexic(arr_spinor[i_sp][i_phi][src_d][i_f], - arr_eo_spinor[i_sp][i_phi][src_d][0][i_f], - arr_eo_spinor[i_sp][i_phi][src_d][1][i_f]); + optr2->inverter(i2, 0, 0); // inversion for both flavor components } - } - } - } - free(arr_eo_spinor); // freeing up space: eo spinors not needed anymore - - /* - Now that I have all the propagators (all in the basis of - https://arxiv.org/pdf/1005.2042.pdf) I can build the correlators of eq. (20) - */ - - /* now we sum only over local space for every t */ - for (t = 0; t < T; t++) { - j = g_ipt[t][0][0][0]; - - // dummy variables - res = 0.; - respa = 0.; - resp4 = 0.; - for (i = j; i < j + LX * LY * LZ; i++) { - // light correlators - for (size_t beta = 0; beta < 4; beta++) { // spin dilution - double sign = 1.0; // the light source sould be multiplied by gamma_5 - if (beta >= 2) { - sign = -1.0; + // conclude the change of basis for the heavy doublet + for (size_t beta = 0; beta < 4; beta++) { // spin dilution index + for (size_t F = 0; F < 2; F++) { // flavor projection index + for (size_t i_eo = 0; i_eo < 2; i_eo++) { // even-odd + // (c,s) --> [(1-i*tau_2)/sqrt(2)] * (c,s) + // stored temporarely in the propagator spinors (used as dummy) + mul_one_pm_itau2_and_div_by_sqrt2( + arr_eo_spinor[1][1][beta][F][i_eo][0], arr_eo_spinor[1][1][beta][F][i_eo][1], + arr_eo_spinor[0][1][beta][F][i_eo][0], arr_eo_spinor[0][1][beta][F][i_eo][1], -1.0, + VOLUME / 2); + + for (size_t i_f = 0; i_f < 2; i_f++) { + // assigning the result to the first components (the sources). + // The propagators will be overwritten with the inversion + assign(arr_eo_spinor[0][1][beta][F][i_eo][i_f], + arr_eo_spinor[1][1][beta][F][i_eo][i_f], VOLUME / 2); + } + } + } } - res += - sign * _spinor_prod_re(arr_spinor[1][0][beta][0][i], arr_spinor[1][0][beta][0][i]); - _gamma0(phi, arr_spinor[1][0][beta][0][i]); - respa += sign * _spinor_prod_re(arr_spinor[1][0][beta][0][i], phi); - _gamma5(phi, phi); - resp4 += sign * _spinor_prod_im(arr_spinor[1][0][beta][0][i], phi); - } - const int f0 = 0; // flavor index of the up - for (size_t F = 0; F < 4; F++) { // flavor projection - for (size_t beta = 0; beta < 4; beta++) { // spin dilution - spinor psi_u = arr_spinor[1][0][beta][f0][f0][i]; - for (size_t hi = 0; hi < 2; hi++) { - for (size_t hj = 0; hj < 2; hj++) { - for (size_t g1 = 0; g1 < 2; g1++) { - for (size_t g2 = 0; g2 < 2; g2++) { - double dum = 0.0; // dummy variable + // (no even-odd): source+propagator, doublet, spin dilution index, flavor proj, flavor + // index, position (+ Dirac, color) (psi[i_sp][d][beta][F][f][x])[alpha][c] + // last 3 indices come from the spinor struct + spinor ******arr_spinor = + (spinor ******)callocMultiDimensional({2, 2, 4, 2, 2, VOLUME}, 6, sizeof(spinor)); + + // now we switch from even-odd representation to standard + + for (size_t i_sp = 0; i_sp < 2; i_sp++) { // source or sink + for (size_t db = 0; db < 2; db++) { // doublet: light of heavy + for (size_t F = 0; F < 2; F++) { // flavor projection index + for (size_t beta = 0; beta < 4; beta++) { // spin dilution index + for (size_t i_f = 0; i_f < 2; i_f++) { + convert_eo_to_lexic(arr_spinor[i_sp][db][F][beta][i_f], + arr_eo_spinor[i_sp][db][F][beta][0][i_f], + arr_eo_spinor[i_sp][db][F][beta][1][i_f]); + } + } + } + } + } - // heavy doublet spinor propagator - phi = arr_spinor[1][1][beta][hj][hi][i]; - if (g1 == 1) { // Gamma_1 = 1 - _gamma5(phi, phi); + free(arr_eo_spinor); // freeing up space: eo spinors not needed anymore + + /* + Now that I have all the propagators (all in the basis of + https://arxiv.org/pdf/1005.2042.pdf) I can build the correlators of eq. (20) + */ + + const int f0 = 0; // flavor index of the up + + /* now we sum only over local space for every t */ + for (t = 0; t < T; t++) { + j = g_ipt[t][0][0][0]; + + // dummy variables + res = 0.; + respa = 0.; + resp4 = 0.; + + for (i = j; i < j + LX * LY * LZ; i++) { + for (size_t beta = 0; beta < 4; beta++) { // spin dilution + // spinor psi_00 = arr_spinor_gamma5_Gamma2[1][0][beta][f0][f0][i]; + spinor psi_u = arr_spinor[1][0][beta][f0][f0][i]; + + // // light correlators + // double sign = 1.0; // the light source sould be multiplied by gamma_5 + // if (beta >= 2) { sign = -1.0; } + + // CORRECT HERE! psi_up can't be used as is for the poin correlator + + res += sign * _spinor_prod_re(psi_u, psi_u); + _gamma0(phi, psi_u); + respa += sign * _spinor_prod_re(psi_u, phi); + _gamma5(phi, phi); + resp4 += sign * _spinor_prod_im(psi_u, phi); + + for (size_t F = 0; F < 4; F++) { // flavor projection + for (size_t hi = 0; hi < 2; hi++) { + for (size_t hj = 0; hj < 2; hj++) { + for (size_t g1 = 0; g1 < 2; g1++) { + for (size_t g2 = 0; g2 < 2; g2++) { + double dum = 0.0; // dummy variable + + // heavy doublet spinor propagator + phi = arr_spinor[1][1][beta][hj][hi][i]; + if (g1 == 1) { // Gamma_1 = 1 + _gamma5(phi, phi); + } + _spinor_scalar_prod(dum, psi_00, phi); + + res_hihj_g1g2[hi][hj][g1][g2] += dum; + } + } } - _spinor_scalar_prod(dum, psi_u, phi); - - res_hihj_g1g2[hi][hj][g1][g2] += dum; } } } } - } - } - } #if defined TM_USE_MPI - MPI_Reduce(&res, &mpi_res, 1, MPI_DOUBLE, MPI_SUM, 0, g_mpi_time_slices); - res = mpi_res; - MPI_Reduce(&respa, &mpi_respa, 1, MPI_DOUBLE, MPI_SUM, 0, g_mpi_time_slices); - respa = mpi_respa; - MPI_Reduce(&resp4, &mpi_resp4, 1, MPI_DOUBLE, MPI_SUM, 0, g_mpi_time_slices); - resp4 = mpi_resp4; - sCpp[t] = +res / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ) / 2. / optr1->kappa / - optr1->kappa; - sCpa[t] = -respa / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ) / 2. / - optr1->kappa / optr1->kappa; - sCp4[t] = +resp4 / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ) / 2. / - optr1->kappa / optr1->kappa; + MPI_Reduce(&res, &mpi_res, 1, MPI_DOUBLE, MPI_SUM, 0, g_mpi_time_slices); + res = mpi_res; + MPI_Reduce(&respa, &mpi_respa, 1, MPI_DOUBLE, MPI_SUM, 0, g_mpi_time_slices); + respa = mpi_respa; + MPI_Reduce(&resp4, &mpi_resp4, 1, MPI_DOUBLE, MPI_SUM, 0, g_mpi_time_slices); + resp4 = mpi_resp4; + sCpp[t] = +res / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ) / 2. / + optr1->kappa / optr1->kappa; + sCpa[t] = -respa / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ) / 2. / + optr1->kappa / optr1->kappa; + sCp4[t] = +resp4 / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ) / 2. / + optr1->kappa / optr1->kappa; #else - Cpp[t] = +res / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ) / 2. / optr1->kappa / - optr1->kappa; - Cpa[t] = -respa / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ) / 2. / - optr1->kappa / optr1->kappa; - Cp4[t] = +resp4 / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ) / 2. / - optr1->kappa / optr1->kappa; + Cpp[t] = +res / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ) / 2. / + optr1->kappa / optr1->kappa; + Cpa[t] = -respa / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ) / 2. / + optr1->kappa / optr1->kappa; + Cp4[t] = +resp4 / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ) / 2. / + optr1->kappa / optr1->kappa; #endif - for (size_t hi = 0; hi < 2; hi++) { - for (size_t hj = 0; hj < 2; hj++) { - for (size_t g1 = 0; g1 < 2; g1++) { - for (size_t g2 = 0; g2 < 2; g2++) { + for (size_t hi = 0; hi < 2; hi++) { + for (size_t hj = 0; hj < 2; hj++) { + for (size_t g1 = 0; g1 < 2; g1++) { + for (size_t g2 = 0; g2 < 2; g2++) { #if defined TM_USE_MPI - MPI_Reduce(&res_hihj_g1g2[hi][hj][g1][g2], &mpi_res_hihj_g1g2[hi][hj][g1][g2], 1, MPI_DOUBLE, MPI_SUM, 0, g_mpi_time_slices); - res_hihj_g1g2[hi][hj][g1][g2] = mpi_res_hihj_g1g2[hi][hj][g1][g2]; - sC_hihj_g1g2[hi][hj][g1][g2][t] = -eta_Gamma[g1] * res / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ); + MPI_Reduce( + &res_hihj_g1g2[hi][hj][g1][g2], &mpi_res_hihj_g1g2[hi][hj][g1][g2], 1, + MPI_DOUBLE, MPI_SUM, 0, g_mpi_time_slices); + res_hihj_g1g2[hi][hj][g1][g2] = mpi_res_hihj_g1g2[hi][hj][g1][g2]; + sC_hihj_g1g2[hi][hj][g1][g2][t] = -eta_Gamma[g1] * res / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ); #else - C_hihj_g1g2[hi][hj][g1][g2][t] = -eta_Gamma[g1] * res / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ); + C_hihj_g1g2[hi][hj][g1][g2][t] = -eta_Gamma[g1] * res / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ); #endif + } + } + } } - } - } - } - } //end loop over "t" + } // end loop over "t" #ifdef TM_USE_MPI - /* some gymnastics needed in case of parallelisation */ - if (g_mpi_time_rank == 0) { - // light correlators - MPI_Gather(sCpp, T, MPI_DOUBLE, Cpp, T, MPI_DOUBLE, 0, g_mpi_SV_slices); - MPI_Gather(sCpa, T, MPI_DOUBLE, Cpa, T, MPI_DOUBLE, 0, g_mpi_SV_slices); - MPI_Gather(sCp4, T, MPI_DOUBLE, Cp4, T, MPI_DOUBLE, 0, g_mpi_SV_slices); - - // heavy mesons - for (size_t hi = 0; hi < 2; hi++) { - for (size_t hj = 0; hj < 2; hj++) { - for (size_t g1 = 0; g1 < 2; g1++) { - for (size_t g2 = 0; g2 < 2; g2++) { - MPI_Gather(sC_hihj_g1g2[hi][hj][g1][g2], T, MPI_DOUBLE, C_hihj_g1g2[hi][hj][g1][g2], T, MPI_DOUBLE, 0, g_mpi_SV_slices); + /* some gymnastics needed in case of parallelisation */ + if (g_mpi_time_rank == 0) { + // light correlators + MPI_Gather(sCpp, T, MPI_DOUBLE, Cpp, T, MPI_DOUBLE, 0, g_mpi_SV_slices); + MPI_Gather(sCpa, T, MPI_DOUBLE, Cpa, T, MPI_DOUBLE, 0, g_mpi_SV_slices); + MPI_Gather(sCp4, T, MPI_DOUBLE, Cp4, T, MPI_DOUBLE, 0, g_mpi_SV_slices); + + // heavy mesons + for (size_t hi = 0; hi < 2; hi++) { + for (size_t hj = 0; hj < 2; hj++) { + for (size_t g1 = 0; g1 < 2; g1++) { + for (size_t g2 = 0; g2 < 2; g2++) { + MPI_Gather(sC_hihj_g1g2[hi][hj][g1][g2], T, MPI_DOUBLE, C_hihj_g1g2[hi][hj][g1][g2], + T, MPI_DOUBLE, 0, g_mpi_SV_slices); + } + } } } } - } - } #endif - /* and write everything into a file */ - if (g_mpi_time_rank == 0 && g_proc_coords[0] == 0) { - ofs = fopen(filename, "w"); - fprintf(ofs, "1 1 0 %e %e\n", Cpp[t0], 0.); - for (t = 1; t < g_nproc_t * T / 2; t++) { - tt = (t0 + t) % (g_nproc_t * T); - fprintf(ofs, "1 1 %d %e ", t, Cpp[tt]); - tt = (t0 + g_nproc_t * T - t) % (g_nproc_t * T); - fprintf(ofs, "%e\n", Cpp[tt]); - } - tt = (t0 + g_nproc_t * T / 2) % (g_nproc_t * T); - fprintf(ofs, "1 1 %d %e %e\n", t, Cpp[tt], 0.); - - fprintf(ofs, "2 1 0 %e %e\n", Cpa[t0], 0.); - for (t = 1; t < g_nproc_t * T / 2; t++) { - tt = (t0 + t) % (g_nproc_t * T); - fprintf(ofs, "2 1 %d %e ", t, Cpa[tt]); - tt = (t0 + g_nproc_t * T - t) % (g_nproc_t * T); - fprintf(ofs, "%e\n", Cpa[tt]); - } - tt = (t0 + g_nproc_t * T / 2) % (g_nproc_t * T); - fprintf(ofs, "2 1 %d %e %e\n", t, Cpa[tt], 0.); - - fprintf(ofs, "6 1 0 %e %e\n", Cp4[t0], 0.); - for (t = 1; t < g_nproc_t * T / 2; t++) { - tt = (t0 + t) % (g_nproc_t * T); - fprintf(ofs, "6 1 %d %e ", t, Cp4[tt]); - tt = (t0 + g_nproc_t * T - t) % (g_nproc_t * T); - fprintf(ofs, "%e\n", Cp4[tt]); - } - tt = (t0 + g_nproc_t * T / 2) % (g_nproc_t * T); - fprintf(ofs, "6 1 %d %e %e\n", t, Cp4[tt], 0.); - - - // heavy meson correlators - for (size_t hi = 0; hi < 2; hi++) { - for (size_t hj = 0; hj < 2; hj++) { - for (size_t g1 = 0; g1 < 2; g1++) { - for (size_t g2 = 0; g2 < 2; g2++) { - fprintf(ofs, "%d %d %d %d 0 %e %e\n", hi, hj, g1, g2, C_hihj_g1g2[hi][hj][g1][g1][t0], 0.); + /* and write everything into a file */ + if (g_mpi_time_rank == 0 && g_proc_coords[0] == 0) { + ofs = fopen(filename, "w"); + fprintf(ofs, "1 1 0 %e %e\n", Cpp[t0], 0.); + for (t = 1; t < g_nproc_t * T / 2; t++) { + tt = (t0 + t) % (g_nproc_t * T); + fprintf(ofs, "1 1 %d %e ", t, Cpp[tt]); + tt = (t0 + g_nproc_t * T - t) % (g_nproc_t * T); + fprintf(ofs, "%e\n", Cpp[tt]); + } + tt = (t0 + g_nproc_t * T / 2) % (g_nproc_t * T); + fprintf(ofs, "1 1 %d %e %e\n", t, Cpp[tt], 0.); + + fprintf(ofs, "2 1 0 %e %e\n", Cpa[t0], 0.); + for (t = 1; t < g_nproc_t * T / 2; t++) { + tt = (t0 + t) % (g_nproc_t * T); + fprintf(ofs, "2 1 %d %e ", t, Cpa[tt]); + tt = (t0 + g_nproc_t * T - t) % (g_nproc_t * T); + fprintf(ofs, "%e\n", Cpa[tt]); + } + tt = (t0 + g_nproc_t * T / 2) % (g_nproc_t * T); + fprintf(ofs, "2 1 %d %e %e\n", t, Cpa[tt], 0.); + + fprintf(ofs, "6 1 0 %e %e\n", Cp4[t0], 0.); + for (t = 1; t < g_nproc_t * T / 2; t++) { + tt = (t0 + t) % (g_nproc_t * T); + fprintf(ofs, "6 1 %d %e ", t, Cp4[tt]); + tt = (t0 + g_nproc_t * T - t) % (g_nproc_t * T); + fprintf(ofs, "%e\n", Cp4[tt]); + } + tt = (t0 + g_nproc_t * T / 2) % (g_nproc_t * T); + fprintf(ofs, "6 1 %d %e %e\n", t, Cp4[tt], 0.); + + // heavy meson correlators + for (size_t hi = 0; hi < 2; hi++) { + for (size_t hj = 0; hj < 2; hj++) { + for (size_t g1 = 0; g1 < 2; g1++) { + for (size_t g2 = 0; g2 < 2; g2++) { + fprintf(ofs, "%d %d %d %d 0 %e %e\n", hi, hj, g1, g2, C_hihj_g1g2[hi][hj][g1][g1][t0], 0.); for (t = 1; t < g_nproc_t * T / 2; t++) { tt = (t0 + t) % (g_nproc_t * T); fprintf(ofs, "%d %d %d %d %d %e ", hi, hj, g1, g2, t, C_hihj_g1g2[hi][hj][g1][g2][tt]); @@ -727,37 +746,37 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, fprintf(ofs, "%e\n", C_hihj_g1g2[hi][hj][g1][g2][tt]); } tt = (t0 + g_nproc_t * T / 2) % (g_nproc_t * T); - fprintf(ofs, "%d %d %d %d %d %d %e %e\n", hi, hj, g1, g2, t, C_hihj_g1g2[hi][hj][g1][g2][tt], 0.0); + fprintf(ofs, "%d %d %d %d %d %d %e %e\n", hi, hj, g1, g2, t, + C_hihj_g1g2[hi][hj][g1][g2][tt], 0.0); + } } } } + fclose(ofs); } - - fclose(ofs); - } #ifdef TM_USE_MPI - if (g_mpi_time_rank == 0) { - free(Cpp); - free(Cpa); - free(Cp4); - free(C_hihj_g1g2); - } - free(sCpp); - free(sCpa); - free(sCp4); - free(sC_hihj_g1g2); + if (g_mpi_time_rank == 0) { + free(Cpp); + free(Cpa); + free(Cp4); + free(C_hihj_g1g2); + } + free(sCpp); + free(sCpa); + free(sCp4); + free(sC_hihj_g1g2); #else - free(Cpp); - free(Cpa); - free(Cp4); - free(C_hihj_g1g2); + free(Cpp); + free(Cpa); + free(Cp4); + free(C_hihj_g1g2); #endif - } // for(max_time_slices) - } // for(max_samples) + } // for(max_time_slices) + } // for(max_samples) - tm_stopwatch_pop(&g_timers, 0, 1, ""); + tm_stopwatch_pop(&g_timers, 0, 1, ""); - return; + return; } void correlators_measurement(const int traj, const int id, const int ieo) { From 0c6a6bcfe2e23993e0bf5109b6e09f9550582cc1 Mon Sep 17 00:00:00 2001 From: simone-romiti Date: Wed, 26 Jul 2023 16:49:10 +0200 Subject: [PATCH 25/51] solved theoretical doubts on the correlator with spin dilution --- doc/bibliography.bib | 16 +++++++ doc/omeas_heavy_mesons.qmd | 98 +++++++++++++++++++++++++------------- meas/correlators.c | 33 +++++++------ 3 files changed, 100 insertions(+), 47 deletions(-) diff --git a/doc/bibliography.bib b/doc/bibliography.bib index 341c50793..d3219dead 100644 --- a/doc/bibliography.bib +++ b/doc/bibliography.bib @@ -644,6 +644,22 @@ @article{Becher:1999he year = "1999" } +@article{PhysRevD.59.074503, + title = {Quark mass dependence of hadron masses from lattice QCD}, + author = {Foster, M. and Michael, C.}, + collaboration = {UKQCD Collaboration}, + journal = {Phys. Rev. D}, + volume = {59}, + issue = {7}, + pages = {074503}, + numpages = {10}, + year = {1999}, + month = {Feb}, + publisher = {American Physical Society}, + doi = {10.1103/PhysRevD.59.074503}, + url = {https://link.aps.org/doi/10.1103/PhysRevD.59.074503} +} + @article{Bietenholz:2004sa, author = "Bietenholz, W. and others", collaboration = "\xlf", diff --git a/doc/omeas_heavy_mesons.qmd b/doc/omeas_heavy_mesons.qmd index 74a6bc261..98b54930a 100644 --- a/doc/omeas_heavy_mesons.qmd +++ b/doc/omeas_heavy_mesons.qmd @@ -219,15 +219,22 @@ Upon a careful calculation for all values $i,j = 0,1$ we find, equivalently: \, . \end{equation} +This is a generalized case of eq. (A9) of @PhysRevD.59.074503. We now approximate the propagator using stochastic sources. Additionally, we use: - The one-end-trick @Boucaud:2008xu: non vanishing source only at $x=0$. - Same source for light and heavy doublet -- Spin dilution (cf. @foley2005practical): one source for each Dirac index $\beta$. The components with index different from the dilution index are set to zero. -- Flavor projection: sources have an additional flavor index $\phi$, such that their flavor component different from the index vanish. The value of the flavor component however is the same, it changes only its position in the doublet: - +- Spin dilution (cf. @foley2005practical): one source for each Dirac index $\beta$, with unit norm in color space. The components with index different from the dilution index are set to zero: + + \begin{equation} + \eta^{(\alpha)}_{\beta, c} = + \eta_c \, \delta^\alpha_\beta \,\, , \, \, + \eta^\dagger_c \eta_c = 1 \, . + \end{equation} + +- Flavor dilution: sources have an additional flavor index $\phi$, such that their flavor component different from the index vanish. The value of the flavor component however is the same, it changes only its position in the doublet: \begin{equation} \eta^{(\phi=0)} = @@ -245,34 +252,44 @@ Additionally, we use: \end{equation} -Since $\Gamma_2=1,\gamma_5$ we always have $\Gamma_2 = \Gamma_2^\dagger$. -In this way, if $\eta^{(\beta, \phi)}$ is the diluted source, -we can define: + +Therefore, we can use spin dilutions to rephrase the correlator in a form which will turn out to be convenient later +($c$ is the color index): \begin{equation} -\begin{split} -&D_{\ell} {\psi}_{\ell}^{(\beta, \phi)} -= \gamma_5 \Gamma_2 \eta^{(\beta, \phi)} +\mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) += +[(S_h)_{f_i f_j}]_{\alpha_1 \beta_1} (x|0) +[\eta^{(\alpha_2)}_{\beta_1}]_c +(\Gamma_2 \gamma_5)_{\alpha_2 \alpha_3} +[{(\eta^\dagger)}^{(\alpha_3)}_{\beta_2}]_c +[(S_u)^\dagger]_{\beta_2 \alpha_4} (x|0) +(\gamma_5 \Gamma_1)_{\alpha_4 \alpha_1} +\, . +\end{equation} + + + + + + +We now define our spinor propagators. +If $\eta^{(\beta, \phi)}$ is the diluted source: + +\begin{equation} +(D_{\ell/h})_{\alpha_1 \alpha_2} ({\psi}_{\ell/h}^{(\beta, \phi)})_{\alpha_2} += (\eta^{(\beta, \phi)})_{\alpha_1} \, \implies \, -(\psi_{\ell}^{(\beta, \phi)})^\dagger +(\psi_{\ell/h}^{(\beta, \phi)})^\dagger_{\alpha_1} = -(\eta^{(\beta, \phi)})^\dagger -\Gamma_2 \gamma_5 S_{\ell}^\dagger -\\ -&D_{h} \psi_{h}^{(\beta, \phi)} -= \eta^{(\beta, \phi)} -\, \implies \, -\psi_{h}^{(\beta, \phi)} -= S_{h} \eta^{(\beta, \phi)} -\, . -\end{split} +(\eta^{(\beta, \phi)})^\dagger_{\alpha_2} +(S_{\ell/h}^\dagger)_{\alpha_2 \alpha_1} \end{equation} This means that for our matrix of correlators we have to do ${4_D \times 2_f \times 2_{h,\ell}} = 16$ inversions. ::: {.remark} 1. For the light doublet `tmLQCD` computes only $S_u$, which is obtained with $(\psi_h^{(\beta, f_0)})_{f_0}$. This is the only propagator we need. - 2. For the heavy propagator, we can access the $(i,j)$ component of $S_h$ with $(\psi_h^{(\beta, f_j)})_{f_i}$. ::: @@ -283,27 +300,44 @@ Our correlator is given by the following expectation value \begin{split} \mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) &= -\sum_{\beta=1}^{N_D} \langle -\operatorname{Tr} -\left[ - (\psi_h^{(\beta, f_i)})_{f_j}(x) - (\psi_\ell^{(\beta, f_0)})_{f_0}^\dagger (x) - \gamma_5 \Gamma_1 -\right] +[(\psi_h^{(\alpha_2, f_i)})_{f_j}]_{\alpha_1}(x) +(\Gamma_2 \gamma_5)_{\alpha_2 \alpha_3} +[(\psi_\ell^{(\alpha_3, f_0)})_{f_0}^\dagger]_{\alpha_4} (x) +(\gamma_5 \Gamma_1)_{\alpha_4 \alpha_1} \rangle \\ &= -\sum_{\beta=1}^{N_D} \braket{ - (\psi_\ell^{(\beta, f_0)})_{f_0}^\dagger (x) - \gamma_5 \Gamma_1 - (\psi_h^{(\beta, f_j)})_{f_i}(x) +(\psi_\ell^{(\alpha_3, f_0)})_{f_0}^\dagger (x) +\cdot +(\gamma_5 \Gamma_1) +\cdot +(\psi_h^{(\alpha_2, f_j)})_{f_i}(x) } +\, +(\Gamma_2 \gamma_5)_{\alpha_2 \alpha_3} +\\ +&= +\mathcal{S}^{\alpha_2 \alpha_3} (\Gamma_2 \gamma_5)_{\alpha_2 \alpha_3} \end{split} \end{equation} +More explicitly: + +\begin{equation} +\begin{split} +\Gamma_2=1 &\implies \mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) += S^{00}+S^{11}-S^{22}-S^{33} +\\ +\Gamma_2=\gamma_5 &\implies \mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) += S^{00}+S^{11}+S^{22}+S^{33} +\end{split} +\end{equation} + + + ## Implementation diff --git a/meas/correlators.c b/meas/correlators.c index a957c1059..cdac4db45 100644 --- a/meas/correlators.c +++ b/meas/correlators.c @@ -444,7 +444,7 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, // even-odd spinor fields for the light and heavy doublet correlators // INDICES: source+propagator, doublet, spin dilution index, flavor projection, even-odd, flavor, position // (+ Dirac, color) psi = (psi[(s,p)][db][beta][F][eo][f][x])[alpha][c] - // last 3 indices come from spinor struct + // last 2 indices come from spinor struct // Note: propagator in the sense that it is D^{-1}*source after the inversion spinor *******arr_eo_spinor = (spinor *******)callocMultiDimensional( {2, 2, 4, 2, 2, 2, VOLUME / 2}, 7, sizeof(spinor)); @@ -454,14 +454,16 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, const unsigned int seed_i = measurement_list[id].seed; // has to be same seed for (size_t db = 0; db < 2; db++) { // doublet: light or heavy for (size_t beta = 0; beta < 4; beta++) { // spin dilution index - for (size_t F = 0; F < 2; F++) { // flavor index of the doublet + for (size_t F = 0; F < 2; F++) { // flavor dilution index for (size_t i_f = 0; i_f < 2; i_f++) { // flavor index of the doublet // light doublet - eo_source_spinor_field_spin_diluted_oet_ts(arr_eo_spinor[0][db][beta][0][i_f], - arr_eo_spinor[0][db][beta][1][i_f], t0, - beta, sample, traj, seed_i); - } - } + eo_source_spinor_field_spin_diluted_oet_ts( + arr_eo_spinor[0][db][beta][F][0][i_f], arr_eo_spinor[0][db][beta][F][1][i_f], + t0, beta, sample, traj, seed_i + ); + + } + } } } @@ -505,6 +507,7 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, optr1->inverter(i1, 0, 0); // inversion for the up flavor + // PLEASE KEEP THESE LINES COMMENTED, MAY BE USEFUL IN THE FUTURE // // inversion of the light doublet only inverts the up block (the operator is // // diagonal in flavor) down components in flavor will be empty // optr1->DownProp = 1; @@ -522,15 +525,15 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, /* heavy doublet */ - optr1->sr0 = arr_eo_spinor[0][1][beta][0][0]; - optr1->sr1 = arr_eo_spinor[0][1][beta][1][0]; - optr1->sr2 = arr_eo_spinor[0][1][beta][0][1]; - optr1->sr3 = arr_eo_spinor[0][1][beta][1][1]; + optr2->sr0 = arr_eo_spinor[0][1][beta][0][0]; + optr2->sr1 = arr_eo_spinor[0][1][beta][1][0]; + optr2->sr2 = arr_eo_spinor[0][1][beta][0][1]; + optr2->sr3 = arr_eo_spinor[0][1][beta][1][1]; - optr1->prop0 = arr_eo_spinor[1][1][beta][0][0]; - optr1->prop1 = arr_eo_spinor[1][1][beta][1][0]; - optr1->prop2 = arr_eo_spinor[1][1][beta][0][1]; - optr1->prop3 = arr_eo_spinor[1][1][beta][1][1]; + optr2->prop0 = arr_eo_spinor[1][1][beta][0][0]; + optr2->prop1 = arr_eo_spinor[1][1][beta][1][0]; + optr2->prop2 = arr_eo_spinor[1][1][beta][0][1]; + optr2->prop3 = arr_eo_spinor[1][1][beta][1][1]; optr2->inverter(i2, 0, 0); // inversion for both flavor components } From a4c1760ffadb1e94aa95589a89121b3a127c81c8 Mon Sep 17 00:00:00 2001 From: simone-romiti Date: Wed, 26 Jul 2023 16:59:12 +0200 Subject: [PATCH 26/51] code now conceptually true --> debug --- meas/correlators.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/meas/correlators.c b/meas/correlators.c index cdac4db45..3df711097 100644 --- a/meas/correlators.c +++ b/meas/correlators.c @@ -601,22 +601,15 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, for (i = j; i < j + LX * LY * LZ; i++) { for (size_t beta = 0; beta < 4; beta++) { // spin dilution - // spinor psi_00 = arr_spinor_gamma5_Gamma2[1][0][beta][f0][f0][i]; spinor psi_u = arr_spinor[1][0][beta][f0][f0][i]; - // // light correlators - // double sign = 1.0; // the light source sould be multiplied by gamma_5 - // if (beta >= 2) { sign = -1.0; } - - // CORRECT HERE! psi_up can't be used as is for the poin correlator - res += sign * _spinor_prod_re(psi_u, psi_u); _gamma0(phi, psi_u); respa += sign * _spinor_prod_re(psi_u, phi); _gamma5(phi, phi); resp4 += sign * _spinor_prod_im(psi_u, phi); - for (size_t F = 0; F < 4; F++) { // flavor projection + for (size_t F = 0; F < 2; F++) { // flavor projection for (size_t hi = 0; hi < 2; hi++) { for (size_t hj = 0; hj < 2; hj++) { for (size_t g1 = 0; g1 < 2; g1++) { @@ -625,12 +618,16 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, // heavy doublet spinor propagator phi = arr_spinor[1][1][beta][hj][hi][i]; - if (g1 == 1) { // Gamma_1 = 1 + if (g1 == 0) { // Gamma_1 = \mathbb{1} _gamma5(phi, phi); } - _spinor_scalar_prod(dum, psi_00, phi); + _spinor_scalar_prod(dum, psi_u, phi); - res_hihj_g1g2[hi][hj][g1][g2] += dum; + double sign_beta = +1; + if(g2 == 0 /* Gamma_2 == \mathbb{1} */ && beta>2){ + sign_beta = -1; + } + res_hihj_g1g2[hi][hj][g1][g2] += sign_beta*dum; } } } From ceecbf9cc70f975525d144244333a518863b9ba5 Mon Sep 17 00:00:00 2001 From: simone-romiti Date: Wed, 26 Jul 2023 17:32:33 +0200 Subject: [PATCH 27/51] fixed compile-time bugs --- meas/correlators.c | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/meas/correlators.c b/meas/correlators.c index 3df711097..213a929da 100644 --- a/meas/correlators.c +++ b/meas/correlators.c @@ -275,7 +275,7 @@ void* callocMultiDimensional(int* sizes, int numDimensions, size_t elementSize) } for (int i = 0; i < sizes[0]; i++) { - pointerArray[i] = callocMultiDimensional(sizes + 1, numDimensions - 1); + pointerArray[i] = callocMultiDimensional(sizes + 1, numDimensions - 1, elementSize); if (pointerArray[i] == NULL) { printf("Memory allocation failed for subarray %d in dimension %d!", i, numDimensions - 1); @@ -342,21 +342,23 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, #endif /* heavy-light correlators variables */ - double eta_Gamma[2] = { - 1.0, -1.0}; // sign change compensation from daggering bilinear with Gamma = 1,gamma_5 + double eta_Gamma[2] = {1.0, -1.0}; // sign change bilinear^\dagger, with Gamma = 1,gamma_5 // the number of independent correlators is 16 = (2*2)_{h_1 h_2} * (2*2)_{Gamma_1 Gamma_2} // hi: c,s // Gamma = 1, gamma_5 - double *****C_hihj_g1g2 = - (double *****)callocMultiDimensional({2, 2, 2, 2, T}, 5, sizeof(double)); - double ****res_hihj_g1g2 = (double ****)callocMultiDimensional({2, 2, 2, 2}, 4, sizeof(double)); + const int sizes_C_hihj_g1g2[5] = {2, 2, 2, 2, T}; + double *****C_hihj_g1g2 = + (double *****)callocMultiDimensional(sizes_C_hihj_g1g2, 5, sizeof(double)); + + const int sizes_res_hihj_g1g2[4] = {2, 2, 2, 2}; + double ****res_hihj_g1g2 = (double ****)callocMultiDimensional(sizes_res_hihj_g1g2, 4, sizeof(double)); #ifdef TM_USE_MPI double ****mpi_res_hihj_g1g2 = - (double ****)callocMultiDimensional({2, 2, 2, 2}, 4, sizeof(double)); + (double ****)callocMultiDimensional(sizes_res_hihj_g1g2, 4, sizeof(double)); // send buffer for MPI_Gather double *****sC_hihj_g1g2 = - (double *****)callocMultiDimensional({2, 2, 2, 2, T}, 5, sizeof(double)); + (double *****)callocMultiDimensional(sizes_C_hihj_g1g2, 5, sizeof(double)); #endif FILE *ofs; // output file stream @@ -380,7 +382,7 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, operator* optr1 = & operator_list[i1]; // light doublet operator* optr2 = & operator_list[i2]; // heavy c,s doublet - bool b1 = (optr->type != TMWILSON && optr->type != WILSON && optr->type != CLOVER); + bool b1 = (optr1->type != TMWILSON && optr1->type != WILSON && optr1->type != CLOVER); bool b2 = (optr2->type != DBTMWILSON && optr2->type != DBCLOVER); if (b1 || b2) { if (g_proc_id == 0) { @@ -446,8 +448,9 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, // (+ Dirac, color) psi = (psi[(s,p)][db][beta][F][eo][f][x])[alpha][c] // last 2 indices come from spinor struct // Note: propagator in the sense that it is D^{-1}*source after the inversion - spinor *******arr_eo_spinor = (spinor *******)callocMultiDimensional( - {2, 2, 4, 2, 2, 2, VOLUME / 2}, 7, sizeof(spinor)); + const int sizes_arr_eo_spinor[7] = {2, 2, 4, 2, 2, 2, VOLUME / 2}; + spinor *******arr_eo_spinor = + (spinor *******)callocMultiDimensional(sizes_arr_eo_spinor, 7, sizeof(spinor)); /* initalize the random sources: one source for each Dirac index beta=src_d --> spin * dilution */ @@ -562,8 +565,9 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, // (no even-odd): source+propagator, doublet, spin dilution index, flavor proj, flavor // index, position (+ Dirac, color) (psi[i_sp][d][beta][F][f][x])[alpha][c] // last 3 indices come from the spinor struct + const int sizes_arr_spinor = {2, 2, 4, 2, 2, VOLUME}; spinor ******arr_spinor = - (spinor ******)callocMultiDimensional({2, 2, 4, 2, 2, VOLUME}, 6, sizeof(spinor)); + (spinor ******)callocMultiDimensional(sizes_arr_spinor, 6, sizeof(spinor)); // now we switch from even-odd representation to standard @@ -603,11 +607,11 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, for (size_t beta = 0; beta < 4; beta++) { // spin dilution spinor psi_u = arr_spinor[1][0][beta][f0][f0][i]; - res += sign * _spinor_prod_re(psi_u, psi_u); + res += _spinor_prod_re(psi_u, psi_u); _gamma0(phi, psi_u); - respa += sign * _spinor_prod_re(psi_u, phi); + respa += _spinor_prod_re(psi_u, phi); _gamma5(phi, phi); - resp4 += sign * _spinor_prod_im(psi_u, phi); + resp4 += _spinor_prod_im(psi_u, phi); for (size_t F = 0; F < 2; F++) { // flavor projection for (size_t hi = 0; hi < 2; hi++) { From a0123650fd7b63c843b8f9742c95b5d6281348db Mon Sep 17 00:00:00 2001 From: simone-romiti Date: Wed, 26 Jul 2023 20:43:26 +0200 Subject: [PATCH 28/51] small typo --- doc/omeas_heavy_mesons.qmd | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/omeas_heavy_mesons.qmd b/doc/omeas_heavy_mesons.qmd index 98b54930a..3b86d3bd8 100644 --- a/doc/omeas_heavy_mesons.qmd +++ b/doc/omeas_heavy_mesons.qmd @@ -301,7 +301,7 @@ Our correlator is given by the following expectation value \mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) &= \langle -[(\psi_h^{(\alpha_2, f_i)})_{f_j}]_{\alpha_1}(x) +[(\psi_h^{(\alpha_2, f_j)})_{f_i}]_{\alpha_1}(x) (\Gamma_2 \gamma_5)_{\alpha_2 \alpha_3} [(\psi_\ell^{(\alpha_3, f_0)})_{f_0}^\dagger]_{\alpha_4} (x) (\gamma_5 \Gamma_1)_{\alpha_4 \alpha_1} @@ -319,7 +319,7 @@ Our correlator is given by the following expectation value (\Gamma_2 \gamma_5)_{\alpha_2 \alpha_3} \\ &= -\mathcal{S}^{\alpha_2 \alpha_3} (\Gamma_2 \gamma_5)_{\alpha_2 \alpha_3} +\mathcal{S}^{\alpha_3 \alpha_2} (\Gamma_2 \gamma_5)_{\alpha_2 \alpha_3} \end{split} \end{equation} @@ -329,10 +329,10 @@ More explicitly: \begin{equation} \begin{split} \Gamma_2=1 &\implies \mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) -= S^{00}+S^{11}-S^{22}-S^{33} += \mathcal{S}^{00}+\mathcal{S}^{11}-\mathcal{S}^{22}-\mathcal{S}^{33} \\ \Gamma_2=\gamma_5 &\implies \mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) -= S^{00}+S^{11}+S^{22}+S^{33} += \mathcal{S}^{00}+\mathcal{S}^{11}+\mathcal{S}^{22}+\mathcal{S}^{33} \end{split} \end{equation} From b127a7e929da1a61f5aa5bd692d517542f0d74a8 Mon Sep 17 00:00:00 2001 From: simone-romiti Date: Wed, 4 Oct 2023 14:50:53 +0200 Subject: [PATCH 29/51] added a note: testing invert_doublet_eo_quda --- doc/omeas_heavy_mesons.qmd | 58 ++- meas/correlators.c | 785 ++++++++++++++++++------------------- 2 files changed, 432 insertions(+), 411 deletions(-) diff --git a/doc/omeas_heavy_mesons.qmd b/doc/omeas_heavy_mesons.qmd index 3b86d3bd8..41fa08823 100644 --- a/doc/omeas_heavy_mesons.qmd +++ b/doc/omeas_heavy_mesons.qmd @@ -204,11 +204,12 @@ Our correlator becomes: \, . \end{equation} -Upon a careful calculation for all values $i,j = 0,1$ we find, equivalently: +Upon a careful calculation for all values $i,j = 0,1$ we find, equivalently (using spacetime translational symmetry): \begin{equation} +\begin{split} \mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) -= +&= \operatorname{Tr} \left[ (S_h)_{f_i f_j} (x|0) @@ -216,7 +217,19 @@ Upon a careful calculation for all values $i,j = 0,1$ we find, equivalently: (S_u)^\dagger (x|0) \gamma_5 \Gamma_1 \right] +\\ +&= +\sum_{y,z} +\operatorname{Tr} +\left[ + (S_h)_{f_i f_j} (x+y|y) + \Gamma_2 \gamma_5 + (S_u)^\dagger (x+z|z) + \gamma_5 \Gamma_1 + \delta_{yz} +\right] \, . +\end{split} \end{equation} This is a generalized case of eq. (A9) of @PhysRevD.59.074503. @@ -269,22 +282,31 @@ Therefore, we can use spin dilutions to rephrase the correlator in a form which \end{equation} - - - - We now define our spinor propagators. If $\eta^{(\beta, \phi)}$ is the diluted source: -\begin{equation} -(D_{\ell/h})_{\alpha_1 \alpha_2} ({\psi}_{\ell/h}^{(\beta, \phi)})_{\alpha_2} -= (\eta^{(\beta, \phi)})_{\alpha_1} -\, \implies \, -(\psi_{\ell/h}^{(\beta, \phi)})^\dagger_{\alpha_1} +\begin{align} +& (D_{\ell/h})_{\alpha_1 \alpha_2} (x|y) ({\psi}_{\ell/h}^{(\beta, \phi)})_{\alpha_2} (y) += (\eta^{(\beta, \phi)})_{\alpha_1} (x) +\\ +& \, \implies \, +(\psi_{\ell/h}^{(\beta, \phi)})_{\alpha_1} (x) = -(\eta^{(\beta, \phi)})^\dagger_{\alpha_2} -(S_{\ell/h}^\dagger)_{\alpha_2 \alpha_1} -\end{equation} +(S_{\ell/h})_{\alpha_2 \alpha_1} (x | y) +\eta^{(\beta, \phi)}_{\alpha_2} (y) += +(S_{\ell/h})_{\alpha_2 \alpha_1} (x | 0) +\eta^{(\beta, \phi)}_{\alpha_2} (0) +\\ +& \, \implies \, +(\psi_{\ell/h}^{(\beta, \phi)})^{*}_{\alpha_1} (x) += +(\eta^{(\beta, \phi)})^{*}_{\alpha_2} (y) +(S_{\ell/h}^\dagger)_{\alpha_2 \alpha_1} (x | y) += +(\eta^{(\beta, \phi)})^\dagger_{\alpha_2} (0) +(S_{\ell/h}^\dagger)_{\alpha_2 \alpha_1} (x | 0) +\end{align} This means that for our matrix of correlators we have to do ${4_D \times 2_f \times 2_{h,\ell}} = 16$ inversions. @@ -319,7 +341,7 @@ Our correlator is given by the following expectation value (\Gamma_2 \gamma_5)_{\alpha_2 \alpha_3} \\ &= -\mathcal{S}^{\alpha_3 \alpha_2} (\Gamma_2 \gamma_5)_{\alpha_2 \alpha_3} +\mathcal{R}^{\alpha_3 \alpha_2} (\Gamma_2 \gamma_5)_{\alpha_2 \alpha_3} \end{split} \end{equation} @@ -329,10 +351,10 @@ More explicitly: \begin{equation} \begin{split} \Gamma_2=1 &\implies \mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) -= \mathcal{S}^{00}+\mathcal{S}^{11}-\mathcal{S}^{22}-\mathcal{S}^{33} += \mathcal{R}^{00}+\mathcal{R}^{11}-\mathcal{R}^{22}-\mathcal{R}^{33} \\ \Gamma_2=\gamma_5 &\implies \mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) -= \mathcal{S}^{00}+\mathcal{S}^{11}+\mathcal{S}^{22}+\mathcal{S}^{33} += \mathcal{R}^{00}+\mathcal{R}^{11}+\mathcal{R}^{22}+\mathcal{R}^{33} \end{split} \end{equation} @@ -343,7 +365,7 @@ More explicitly: See comments in the code: `tmLQCD/meas/correlators.c`. - +**NOTE**: test if `invert_doublet_eo_quda` works (do one inversion and check the residual) diff --git a/meas/correlators.c b/meas/correlators.c index 213a929da..c6b87a86c 100644 --- a/meas/correlators.c +++ b/meas/correlators.c @@ -308,479 +308,478 @@ void* callocMultiDimensional(int* sizes, int numDimensions, size_t elementSize) ******************************************************/ void heavy_correlators_measurement(const int traj, const int id, const int ieo, const int i1, const int i2) { - tm_stopwatch_push(&g_timers, __func__, ""); // timer for profiling + tm_stopwatch_push(&g_timers, __func__, ""); // timer for profiling - spinor phi; // dummy spinor - int i, j, t, tt, t0; // dummy indices - float tmp; // dummy variable + spinor phi; // dummy spinor + int i, j, t, tt, t0; // dummy indices + float tmp; // dummy variable - /* light-light correlators: dummy variables */ + /* light-light correlators: dummy variables */ - // array of the values of the correlator C(t) - double *Cpp = NULL, *Cpa = NULL, *Cp4 = NULL; - // result of the accumulation of MPI partial sums - double res = 0., respa = 0., resp4 = 0.; + // array of the values of the correlator C(t) + double *Cpp = NULL, *Cpa = NULL, *Cp4 = NULL; + // result of the accumulation of MPI partial sums + double res = 0., respa = 0., resp4 = 0.; #ifdef TM_USE_MPI - double mpi_res = 0., mpi_respa = 0., mpi_resp4 = 0.; - // send buffer for MPI_Gather - double *sCpp = NULL, *sCpa = NULL, *sCp4 = NULL; + double mpi_res = 0., mpi_respa = 0., mpi_resp4 = 0.; + // send buffer for MPI_Gather + double *sCpp = NULL, *sCpa = NULL, *sCp4 = NULL; #endif #ifdef TM_USE_MPI - sCpp = (double *)calloc(T, sizeof(double)); - sCpa = (double *)calloc(T, sizeof(double)); - sCp4 = (double *)calloc(T, sizeof(double)); - if (g_mpi_time_rank == 0) { - Cpp = (double *)calloc(g_nproc_t * T, sizeof(double)); - Cpa = (double *)calloc(g_nproc_t * T, sizeof(double)); - Cp4 = (double *)calloc(g_nproc_t * T, sizeof(double)); - } + sCpp = (double *)calloc(T, sizeof(double)); + sCpa = (double *)calloc(T, sizeof(double)); + sCp4 = (double *)calloc(T, sizeof(double)); + if (g_mpi_time_rank == 0) { + Cpp = (double *)calloc(g_nproc_t * T, sizeof(double)); + Cpa = (double *)calloc(g_nproc_t * T, sizeof(double)); + Cp4 = (double *)calloc(g_nproc_t * T, sizeof(double)); + } #else - Cpp = (double *)calloc(T, sizeof(double)); - Cpa = (double *)calloc(T, sizeof(double)); - Cp4 = (double *)calloc(T, sizeof(double)); + Cpp = (double *)calloc(T, sizeof(double)); + Cpa = (double *)calloc(T, sizeof(double)); + Cp4 = (double *)calloc(T, sizeof(double)); #endif - /* heavy-light correlators variables */ - double eta_Gamma[2] = {1.0, -1.0}; // sign change bilinear^\dagger, with Gamma = 1,gamma_5 + /* heavy-light correlators variables */ + double eta_Gamma[2] = {1.0, -1.0}; // sign change bilinear^\dagger, with Gamma = 1,gamma_5 - // the number of independent correlators is 16 = (2*2)_{h_1 h_2} * (2*2)_{Gamma_1 Gamma_2} - // hi: c,s - // Gamma = 1, gamma_5 - const int sizes_C_hihj_g1g2[5] = {2, 2, 2, 2, T}; - double *****C_hihj_g1g2 = - (double *****)callocMultiDimensional(sizes_C_hihj_g1g2, 5, sizeof(double)); + // the number of independent correlators is 16 = (2*2)_{h_1 h_2} * (2*2)_{Gamma_1 Gamma_2} + // hi: c,s + // Gamma = 1, gamma_5 + const int sizes_C_hihj_g1g2[5] = {2, 2, 2, 2, T}; + double *****C_hihj_g1g2 = + (double *****)callocMultiDimensional(sizes_C_hihj_g1g2, 5, sizeof(double)); - const int sizes_res_hihj_g1g2[4] = {2, 2, 2, 2}; - double ****res_hihj_g1g2 = (double ****)callocMultiDimensional(sizes_res_hihj_g1g2, 4, sizeof(double)); + const int sizes_res_hihj_g1g2[4] = {2, 2, 2, 2}; + double ****res_hihj_g1g2 = + (double ****)callocMultiDimensional(sizes_res_hihj_g1g2, 4, sizeof(double)); #ifdef TM_USE_MPI - double ****mpi_res_hihj_g1g2 = - (double ****)callocMultiDimensional(sizes_res_hihj_g1g2, 4, sizeof(double)); - // send buffer for MPI_Gather - double *****sC_hihj_g1g2 = - (double *****)callocMultiDimensional(sizes_C_hihj_g1g2, 5, sizeof(double)); + double ****mpi_res_hihj_g1g2 = + (double ****)callocMultiDimensional(sizes_res_hihj_g1g2, 4, sizeof(double)); + // send buffer for MPI_Gather + double *****sC_hihj_g1g2 = + (double *****)callocMultiDimensional(sizes_C_hihj_g1g2, 5, sizeof(double)); #endif - FILE *ofs; // output file stream - char filename[TM_OMEAS_FILENAME_LENGTH]; // file path + FILE *ofs; // output file stream + char filename[TM_OMEAS_FILENAME_LENGTH]; // file path - /* building the stochastic propagator spinors needed for the correlators */ + /* building the stochastic propagator spinors needed for the correlators */ - init_operators(); // initialize the operators in the action (if not already done) - if (no_operators < 1) { - if (g_proc_id == 0) { - // we don't want the simulation to stop, we can do the measurements offline afterwards - fprintf(stderr, - "Warning! no operators defined in input file, cannot perform online correlator " - "mesurements!\n"); - } - tm_stopwatch_pop(&g_timers, 0, 0, ""); // timer for profiling - return; + init_operators(); // initialize the operators in the action (if not already done) + if (no_operators < 1) { + if (g_proc_id == 0) { + // we don't want the simulation to stop, we can do the measurements offline afterwards + fprintf(stderr, + "Warning! no operators defined in input file, cannot perform online correlator " + "mesurements!\n"); } + tm_stopwatch_pop(&g_timers, 0, 0, ""); // timer for profiling + return; + } - // selecting the operators i1 and i2 from the list of operators initialized before - operator* optr1 = & operator_list[i1]; // light doublet - operator* optr2 = & operator_list[i2]; // heavy c,s doublet - - bool b1 = (optr1->type != TMWILSON && optr1->type != WILSON && optr1->type != CLOVER); - bool b2 = (optr2->type != DBTMWILSON && optr2->type != DBCLOVER); - if (b1 || b2) { - if (g_proc_id == 0) { - if (b1) { - fprintf( - stderr, - "Warning! optr1 should be one of the following: TMWILSON, WILSON and CLOVER\n"); - fprintf(stderr, "Cannot perform correlator online measurement!\n"); - } - if (b2) { - fprintf(stderr, - "Warning! optr2 should be one of the following: DBTMWILSON, DBCLOVER\n"); - } - fprintf(stderr, "Cannot perform correlator online measurement!\n"); - } - tm_stopwatch_pop(&g_timers, 0, 0, ""); // timer for profiling - return; + // selecting the operators i1 and i2 from the list of operators initialized before + operator* optr1 = & operator_list[i1]; // light doublet + operator* optr2 = & operator_list[i2]; // heavy c,s doublet + + bool b1 = (optr1->type != TMWILSON && optr1->type != WILSON && optr1->type != CLOVER); + bool b2 = (optr2->type != DBTMWILSON && optr2->type != DBCLOVER); + if (b1 || b2) { + if (g_proc_id == 0) { + if (b1) { + fprintf(stderr, + "Warning! optr1 should be one of the following: TMWILSON, WILSON and CLOVER\n"); + fprintf(stderr, "Cannot perform correlator online measurement!\n"); + } + if (b2) { + fprintf(stderr, "Warning! optr2 should be one of the following: DBTMWILSON, DBCLOVER\n"); + } + fprintf(stderr, "Cannot perform correlator online measurement!\n"); } + tm_stopwatch_pop(&g_timers, 0, 0, ""); // timer for profiling + return; + } - if (ranlxs_init == 0) { - rlxs_init(1, 123456); // initializing random number generator RANLUX - } + if (ranlxs_init == 0) { + rlxs_init(1, 123456); // initializing random number generator RANLUX + } - // there are three modes of operation - // 1) one single time-slice source (default) - // 2) no_samples time-slice sources on random time-slices - // 3) one sample on all time-slices - int max_samples = measurement_list[id].all_time_slices ? 1 : measurement_list[id].no_samples; - int max_time_slices = - measurement_list[id].all_time_slices ? measurement_list[id].max_source_slice : 1; - for (int sample = 0; sample < max_samples; sample++) { - for (int ts = 0; ts < max_time_slices; ts++) { - // setting output filename - if (max_samples == 1 && max_time_slices == 1) { - snprintf(filename, TM_OMEAS_FILENAME_LENGTH, "%s%06d", "heavy_mesons.", traj); - } else if (max_samples == 1 && max_time_slices > 1) { - snprintf(filename, TM_OMEAS_FILENAME_LENGTH, "%s.t%03d.%06d", "heavy_mesons", ts, - traj); - } else { - snprintf(filename, TM_OMEAS_FILENAME_LENGTH, "%s.s%03d.%06d", "heavy_mesons", - sample, traj); - } + // there are three modes of operation + // 1) one single time-slice source (default) + // 2) no_samples time-slice sources on random time-slices + // 3) one sample on all time-slices + int max_samples = measurement_list[id].all_time_slices ? 1 : measurement_list[id].no_samples; + int max_time_slices = + measurement_list[id].all_time_slices ? measurement_list[id].max_source_slice : 1; + for (int sample = 0; sample < max_samples; sample++) { + for (int ts = 0; ts < max_time_slices; ts++) { + // setting output filename + if (max_samples == 1 && max_time_slices == 1) { + snprintf(filename, TM_OMEAS_FILENAME_LENGTH, "%s%06d", "heavy_mesons.", traj); + } else if (max_samples == 1 && max_time_slices > 1) { + snprintf(filename, TM_OMEAS_FILENAME_LENGTH, "%s.t%03d.%06d", "heavy_mesons", ts, traj); + } else { + snprintf(filename, TM_OMEAS_FILENAME_LENGTH, "%s.s%03d.%06d", "heavy_mesons", sample, traj); + } - /* generate random timeslice */ - t0 = ts; - if (!measurement_list[id].all_time_slices) { - ranlxs(&tmp, 1); - t0 = (int)(measurement_list[id].max_source_slice * tmp); - } + /* generate random timeslice */ + t0 = ts; + if (!measurement_list[id].all_time_slices) { + ranlxs(&tmp, 1); + t0 = (int)(measurement_list[id].max_source_slice * tmp); + } #ifdef TM_USE_MPI - MPI_Bcast(&t0, 1, MPI_INT, 0, MPI_COMM_WORLD); // broadcast t0 to all the ranks + MPI_Bcast(&t0, 1, MPI_INT, 0, MPI_COMM_WORLD); // broadcast t0 to all the ranks #endif - if (g_debug_level > 1 && g_proc_id == 0) { - printf("# timeslice set to %d (T=%d) for online measurement\n", t0, g_nproc_t * T); - printf( - "# online measurements parameters: kappa = %.12f, mubar = %.12f, epsbar = " - "%.12f\n", - optr1->kappa, optr1->mubar, optr1->epsbar); - } + if (g_debug_level > 1 && g_proc_id == 0) { + printf("# timeslice set to %d (T=%d) for online measurement\n", t0, g_nproc_t * T); + printf( + "# online measurements parameters: kappa = %.12f, mubar = %.12f, epsbar = " + "%.12f\n", + optr1->kappa, optr1->mubar, optr1->epsbar); + } - // even-odd spinor fields for the light and heavy doublet correlators - // INDICES: source+propagator, doublet, spin dilution index, flavor projection, even-odd, flavor, position - // (+ Dirac, color) psi = (psi[(s,p)][db][beta][F][eo][f][x])[alpha][c] - // last 2 indices come from spinor struct - // Note: propagator in the sense that it is D^{-1}*source after the inversion - const int sizes_arr_eo_spinor[7] = {2, 2, 4, 2, 2, 2, VOLUME / 2}; - spinor *******arr_eo_spinor = - (spinor *******)callocMultiDimensional(sizes_arr_eo_spinor, 7, sizeof(spinor)); - - /* initalize the random sources: one source for each Dirac index beta=src_d --> spin - * dilution */ - const unsigned int seed_i = measurement_list[id].seed; // has to be same seed - for (size_t db = 0; db < 2; db++) { // doublet: light or heavy - for (size_t beta = 0; beta < 4; beta++) { // spin dilution index - for (size_t F = 0; F < 2; F++) { // flavor dilution index - for (size_t i_f = 0; i_f < 2; i_f++) { // flavor index of the doublet - // light doublet - eo_source_spinor_field_spin_diluted_oet_ts( - arr_eo_spinor[0][db][beta][F][0][i_f], arr_eo_spinor[0][db][beta][F][1][i_f], - t0, beta, sample, traj, seed_i - ); - - } - } - } + // even-odd spinor fields for the light and heavy doublet correlators + // INDICES: source+propagator, doublet, spin dilution index, flavor projection, even-odd, + // flavor, position + // (+ Dirac, color) psi = (psi[(s,p)][db][beta][F][eo][f][x])[alpha][c] + // last 2 indices come from spinor struct + // Note: propagator in the sense that it is D^{-1}*source after the inversion + const int sizes_arr_eo_spinor[7] = {2, 2, 4, 2, 2, 2, VOLUME / 2}; + spinor *******arr_eo_spinor = + (spinor *******)callocMultiDimensional(sizes_arr_eo_spinor, 7, sizeof(spinor)); + + /* initalize the random sources: one source for each Dirac index beta=src_d --> spin + * dilution */ + const unsigned int seed_i = measurement_list[id].seed; // has to be same seed + for (size_t db = 0; db < 2; db++) { // doublet: light or heavy + for (size_t beta = 0; beta < 4; beta++) { // spin dilution index + for (size_t F = 0; F < 2; F++) { // flavor dilution index + for (size_t i_f = 0; i_f < 2; i_f++) { // flavor index of the doublet + // light doublet + eo_source_spinor_field_spin_diluted_oet_ts(arr_eo_spinor[0][db][beta][F][0][i_f], + arr_eo_spinor[0][db][beta][F][1][i_f], t0, + beta, sample, traj, seed_i); } + } + } + } - // heavy doublet: for each even-odd block, I multiply by (1 + i*tau_2)/sqrt(2) - // the basis for the inversion should be the same as for the light - // --> I will multiply later by the inverse, namely at the end of the inversion - for (size_t beta = 0; beta < 4; beta++) { // spin dilution index - for (size_t F = 0; F < 2; F++) { // flavor projection index - for (size_t i_eo = 0; i_eo < 2; i_eo++) { // even-odd - // (c,s) --> [(1-i*tau_2)/sqrt(2)] * (c,s) - // stored temporarely in the propagator spinors (used as dummy) - mul_one_pm_itau2_and_div_by_sqrt2( - arr_eo_spinor[1][1][beta][F][i_eo][0], arr_eo_spinor[1][1][beta][F][i_eo][1], - arr_eo_spinor[0][1][beta][F][i_eo][0], arr_eo_spinor[0][1][beta][F][i_eo][1], +1.0, - VOLUME / 2); - - for (size_t i_f = 0; i_f < 2; i_f++) { - // assigning the result to the first components (the sources). - // The propagators will be overwritten with the inversion - assign(arr_eo_spinor[0][1][beta][F][i_eo][i_f], - arr_eo_spinor[1][1][beta][F][i_eo][i_f], VOLUME / 2); - } - } - } + // heavy doublet: for each even-odd block, I multiply by (1 + i*tau_2)/sqrt(2) + // the basis for the inversion should be the same as for the light + // --> I will multiply later by the inverse, namely at the end of the inversion + for (size_t beta = 0; beta < 4; beta++) { // spin dilution index + for (size_t F = 0; F < 2; F++) { // flavor projection index + for (size_t i_eo = 0; i_eo < 2; i_eo++) { // even-odd + // (c,s) --> [(1-i*tau_2)/sqrt(2)] * (c,s) + // stored temporarely in the propagator spinors (used as dummy) + mul_one_pm_itau2_and_div_by_sqrt2( + arr_eo_spinor[1][1][beta][F][i_eo][0], arr_eo_spinor[1][1][beta][F][i_eo][1], + arr_eo_spinor[0][1][beta][F][i_eo][0], arr_eo_spinor[0][1][beta][F][i_eo][1], +1.0, + VOLUME / 2); + + for (size_t i_f = 0; i_f < 2; i_f++) { + // assigning the result to the first components (the sources). + // The propagators will be overwritten with the inversion + assign(arr_eo_spinor[0][1][beta][F][i_eo][i_f], + arr_eo_spinor[1][1][beta][F][i_eo][i_f], VOLUME / 2); } + } + } + } - /* - assign the sources and propagator pointes for the operators - these need to be know when calling the inverter() method */ - for (size_t beta = 0; beta < 4; beta++) { // spin dilution index - /* light doublet */ + /* + assign the sources and propagator pointes for the operators + these need to be know when calling the inverter() method */ + for (size_t beta = 0; beta < 4; beta++) { // spin dilution index + /* light doublet */ - // up + // up - // sorces - optr1->sr0 = arr_eo_spinor[0][0][beta][0][0]; - optr1->sr1 = arr_eo_spinor[0][0][beta][1][0]; - // propagators - optr1->prop0 = arr_eo_spinor[1][0][beta][0][0]; - optr1->prop1 = arr_eo_spinor[1][0][beta][1][0]; + // sorces + optr1->sr0 = arr_eo_spinor[0][0][beta][0][0]; + optr1->sr1 = arr_eo_spinor[0][0][beta][1][0]; + // propagators + optr1->prop0 = arr_eo_spinor[1][0][beta][0][0]; + optr1->prop1 = arr_eo_spinor[1][0][beta][1][0]; - optr1->inverter(i1, 0, 0); // inversion for the up flavor + optr1->inverter(i1, 0, 0); // inversion for the up flavor - // PLEASE KEEP THESE LINES COMMENTED, MAY BE USEFUL IN THE FUTURE - // // inversion of the light doublet only inverts the up block (the operator is - // // diagonal in flavor) down components in flavor will be empty - // optr1->DownProp = 1; + // PLEASE KEEP THESE LINES COMMENTED, MAY BE USEFUL IN THE FUTURE + // // inversion of the light doublet only inverts the up block (the operator is + // // diagonal in flavor) down components in flavor will be empty + // optr1->DownProp = 1; - // // sources - // optr1->sr0 = arr_eo_spinor[0][0][beta][0][1]; - // optr1->sr1 = arr_eo_spinor[0][0][beta][1][1]; - // // propagator - // optr1->prop0 = arr_eo_spinor[1][0][beta][0][1]; - // optr1->prop1 = arr_eo_spinor[1][0][beta][1][1]; + // // sources + // optr1->sr0 = arr_eo_spinor[0][0][beta][0][1]; + // optr1->sr1 = arr_eo_spinor[0][0][beta][1][1]; + // // propagator + // optr1->prop0 = arr_eo_spinor[1][0][beta][0][1]; + // optr1->prop1 = arr_eo_spinor[1][0][beta][1][1]; - // optr1->inverter(i1, 0, 0); // inversion for the down + // optr1->inverter(i1, 0, 0); // inversion for the down - // optr1->DownProp = 0; // restoring to default + // optr1->DownProp = 0; // restoring to default - /* heavy doublet */ + /* heavy doublet */ - optr2->sr0 = arr_eo_spinor[0][1][beta][0][0]; - optr2->sr1 = arr_eo_spinor[0][1][beta][1][0]; - optr2->sr2 = arr_eo_spinor[0][1][beta][0][1]; - optr2->sr3 = arr_eo_spinor[0][1][beta][1][1]; + optr2->sr0 = arr_eo_spinor[0][1][beta][0][0]; + optr2->sr1 = arr_eo_spinor[0][1][beta][1][0]; + optr2->sr2 = arr_eo_spinor[0][1][beta][0][1]; + optr2->sr3 = arr_eo_spinor[0][1][beta][1][1]; - optr2->prop0 = arr_eo_spinor[1][1][beta][0][0]; - optr2->prop1 = arr_eo_spinor[1][1][beta][1][0]; - optr2->prop2 = arr_eo_spinor[1][1][beta][0][1]; - optr2->prop3 = arr_eo_spinor[1][1][beta][1][1]; + optr2->prop0 = arr_eo_spinor[1][1][beta][0][0]; + optr2->prop1 = arr_eo_spinor[1][1][beta][1][0]; + optr2->prop2 = arr_eo_spinor[1][1][beta][0][1]; + optr2->prop3 = arr_eo_spinor[1][1][beta][1][1]; - optr2->inverter(i2, 0, 0); // inversion for both flavor components - } + optr2->inverter(i2, 0, 0); // inversion for both flavor components + } - // conclude the change of basis for the heavy doublet - for (size_t beta = 0; beta < 4; beta++) { // spin dilution index - for (size_t F = 0; F < 2; F++) { // flavor projection index - for (size_t i_eo = 0; i_eo < 2; i_eo++) { // even-odd - // (c,s) --> [(1-i*tau_2)/sqrt(2)] * (c,s) - // stored temporarely in the propagator spinors (used as dummy) - mul_one_pm_itau2_and_div_by_sqrt2( - arr_eo_spinor[1][1][beta][F][i_eo][0], arr_eo_spinor[1][1][beta][F][i_eo][1], - arr_eo_spinor[0][1][beta][F][i_eo][0], arr_eo_spinor[0][1][beta][F][i_eo][1], -1.0, - VOLUME / 2); - - for (size_t i_f = 0; i_f < 2; i_f++) { - // assigning the result to the first components (the sources). - // The propagators will be overwritten with the inversion - assign(arr_eo_spinor[0][1][beta][F][i_eo][i_f], - arr_eo_spinor[1][1][beta][F][i_eo][i_f], VOLUME / 2); - } - } - } + // conclude the change of basis for the heavy doublet + for (size_t beta = 0; beta < 4; beta++) { // spin dilution index + for (size_t F = 0; F < 2; F++) { // flavor projection index + for (size_t i_eo = 0; i_eo < 2; i_eo++) { // even-odd + // (c,s) --> [(1-i*tau_2)/sqrt(2)] * (c,s) + // stored temporarely in the propagator spinors (used as dummy) + mul_one_pm_itau2_and_div_by_sqrt2( + arr_eo_spinor[1][1][beta][F][i_eo][0], arr_eo_spinor[1][1][beta][F][i_eo][1], + arr_eo_spinor[0][1][beta][F][i_eo][0], arr_eo_spinor[0][1][beta][F][i_eo][1], -1.0, + VOLUME / 2); + + for (size_t i_f = 0; i_f < 2; i_f++) { + // assigning the result to the first components (the sources). + // The propagators will be overwritten with the inversion + assign(arr_eo_spinor[0][1][beta][F][i_eo][i_f], + arr_eo_spinor[1][1][beta][F][i_eo][i_f], VOLUME / 2); } + } + } + } - // (no even-odd): source+propagator, doublet, spin dilution index, flavor proj, flavor - // index, position (+ Dirac, color) (psi[i_sp][d][beta][F][f][x])[alpha][c] - // last 3 indices come from the spinor struct - const int sizes_arr_spinor = {2, 2, 4, 2, 2, VOLUME}; - spinor ******arr_spinor = - (spinor ******)callocMultiDimensional(sizes_arr_spinor, 6, sizeof(spinor)); - - // now we switch from even-odd representation to standard - - for (size_t i_sp = 0; i_sp < 2; i_sp++) { // source or sink - for (size_t db = 0; db < 2; db++) { // doublet: light of heavy - for (size_t F = 0; F < 2; F++) { // flavor projection index - for (size_t beta = 0; beta < 4; beta++) { // spin dilution index - for (size_t i_f = 0; i_f < 2; i_f++) { - convert_eo_to_lexic(arr_spinor[i_sp][db][F][beta][i_f], + // (no even-odd): source+propagator, doublet, spin dilution index, flavor proj, flavor + // index, position (+ Dirac, color) (psi[i_sp][d][beta][F][f][x])[alpha][c] + // last 3 indices come from the spinor struct + const int sizes_arr_spinor = {2, 2, 4, 2, 2, VOLUME}; + spinor ******arr_spinor = + (spinor ******)callocMultiDimensional(sizes_arr_spinor, 6, sizeof(spinor)); + + // now we switch from even-odd representation to standard + + for (size_t i_sp = 0; i_sp < 2; i_sp++) { // source or sink + for (size_t db = 0; db < 2; db++) { // doublet: light of heavy + for (size_t F = 0; F < 2; F++) { // flavor projection index + for (size_t beta = 0; beta < 4; beta++) { // spin dilution index + for (size_t i_f = 0; i_f < 2; i_f++) { + convert_eo_to_lexic(arr_spinor[i_sp][db][F][beta][i_f], arr_eo_spinor[i_sp][db][F][beta][0][i_f], arr_eo_spinor[i_sp][db][F][beta][1][i_f]); - } - } - } } } + } + } + } + + free(arr_eo_spinor); // freeing up space: eo spinors not needed anymore + + /* + Now that I have all the propagators (all in the basis of + https://arxiv.org/pdf/1005.2042.pdf) I can build the correlators of eq. (20) + */ - free(arr_eo_spinor); // freeing up space: eo spinors not needed anymore - - /* - Now that I have all the propagators (all in the basis of - https://arxiv.org/pdf/1005.2042.pdf) I can build the correlators of eq. (20) - */ - - const int f0 = 0; // flavor index of the up - - /* now we sum only over local space for every t */ - for (t = 0; t < T; t++) { - j = g_ipt[t][0][0][0]; - - // dummy variables - res = 0.; - respa = 0.; - resp4 = 0.; - - for (i = j; i < j + LX * LY * LZ; i++) { - for (size_t beta = 0; beta < 4; beta++) { // spin dilution - spinor psi_u = arr_spinor[1][0][beta][f0][f0][i]; - - res += _spinor_prod_re(psi_u, psi_u); - _gamma0(phi, psi_u); - respa += _spinor_prod_re(psi_u, phi); - _gamma5(phi, phi); - resp4 += _spinor_prod_im(psi_u, phi); - - for (size_t F = 0; F < 2; F++) { // flavor projection - for (size_t hi = 0; hi < 2; hi++) { - for (size_t hj = 0; hj < 2; hj++) { - for (size_t g1 = 0; g1 < 2; g1++) { - for (size_t g2 = 0; g2 < 2; g2++) { - double dum = 0.0; // dummy variable - - // heavy doublet spinor propagator - phi = arr_spinor[1][1][beta][hj][hi][i]; - if (g1 == 0) { // Gamma_1 = \mathbb{1} - _gamma5(phi, phi); - } - _spinor_scalar_prod(dum, psi_u, phi); - - double sign_beta = +1; - if(g2 == 0 /* Gamma_2 == \mathbb{1} */ && beta>2){ - sign_beta = -1; - } - res_hihj_g1g2[hi][hj][g1][g2] += sign_beta*dum; - } - } + const int f0 = 0; // flavor index of the up + + /* now we sum only over local space for every t */ + for (t = 0; t < T; t++) { + j = g_ipt[t][0][0][0]; + + // dummy variables + res = 0.; + respa = 0.; + resp4 = 0.; + + for (i = j; i < j + LX * LY * LZ; i++) { + for (size_t beta = 0; beta < 4; beta++) { // spin dilution + spinor psi_u = arr_spinor[1][0][beta][f0][f0][i]; + + res += _spinor_prod_re(psi_u, psi_u); + _gamma0(phi, psi_u); + respa += _spinor_prod_re(psi_u, phi); + _gamma5(phi, phi); + resp4 += _spinor_prod_im(psi_u, phi); + + for (size_t F = 0; F < 2; F++) { // flavor projection + for (size_t hi = 0; hi < 2; hi++) { + for (size_t hj = 0; hj < 2; hj++) { + for (size_t g1 = 0; g1 < 2; g1++) { + for (size_t g2 = 0; g2 < 2; g2++) { + double dum = 0.0; // dummy variable + + // heavy doublet spinor propagator + phi = arr_spinor[1][1][beta][hj][hi][i]; + if (g1 == 0) { // Gamma_1 = \mathbb{1} + _gamma5(phi, phi); + } + _spinor_scalar_prod(dum, psi_u, phi); + + double sign_beta = +1; + if (g2 == 0 /* Gamma_2 == \mathbb{1} */ && beta > 2) { + sign_beta = -1; } + res_hihj_g1g2[hi][hj][g1][g2] += sign_beta * dum; } } } } + } + } + } #if defined TM_USE_MPI - MPI_Reduce(&res, &mpi_res, 1, MPI_DOUBLE, MPI_SUM, 0, g_mpi_time_slices); - res = mpi_res; - MPI_Reduce(&respa, &mpi_respa, 1, MPI_DOUBLE, MPI_SUM, 0, g_mpi_time_slices); - respa = mpi_respa; - MPI_Reduce(&resp4, &mpi_resp4, 1, MPI_DOUBLE, MPI_SUM, 0, g_mpi_time_slices); - resp4 = mpi_resp4; - sCpp[t] = +res / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ) / 2. / - optr1->kappa / optr1->kappa; - sCpa[t] = -respa / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ) / 2. / - optr1->kappa / optr1->kappa; - sCp4[t] = +resp4 / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ) / 2. / - optr1->kappa / optr1->kappa; + MPI_Reduce(&res, &mpi_res, 1, MPI_DOUBLE, MPI_SUM, 0, g_mpi_time_slices); + res = mpi_res; + MPI_Reduce(&respa, &mpi_respa, 1, MPI_DOUBLE, MPI_SUM, 0, g_mpi_time_slices); + respa = mpi_respa; + MPI_Reduce(&resp4, &mpi_resp4, 1, MPI_DOUBLE, MPI_SUM, 0, g_mpi_time_slices); + resp4 = mpi_resp4; + sCpp[t] = +res / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ) / 2. / + optr1->kappa / optr1->kappa; + sCpa[t] = -respa / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ) / 2. / + optr1->kappa / optr1->kappa; + sCp4[t] = +resp4 / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ) / 2. / + optr1->kappa / optr1->kappa; #else - Cpp[t] = +res / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ) / 2. / - optr1->kappa / optr1->kappa; - Cpa[t] = -respa / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ) / 2. / - optr1->kappa / optr1->kappa; - Cp4[t] = +resp4 / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ) / 2. / - optr1->kappa / optr1->kappa; + Cpp[t] = +res / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ) / 2. / optr1->kappa / + optr1->kappa; + Cpa[t] = -respa / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ) / 2. / + optr1->kappa / optr1->kappa; + Cp4[t] = +resp4 / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ) / 2. / + optr1->kappa / optr1->kappa; #endif - for (size_t hi = 0; hi < 2; hi++) { - for (size_t hj = 0; hj < 2; hj++) { - for (size_t g1 = 0; g1 < 2; g1++) { - for (size_t g2 = 0; g2 < 2; g2++) { + for (size_t hi = 0; hi < 2; hi++) { + for (size_t hj = 0; hj < 2; hj++) { + for (size_t g1 = 0; g1 < 2; g1++) { + for (size_t g2 = 0; g2 < 2; g2++) { #if defined TM_USE_MPI - MPI_Reduce( - &res_hihj_g1g2[hi][hj][g1][g2], &mpi_res_hihj_g1g2[hi][hj][g1][g2], 1, - MPI_DOUBLE, MPI_SUM, 0, g_mpi_time_slices); - res_hihj_g1g2[hi][hj][g1][g2] = mpi_res_hihj_g1g2[hi][hj][g1][g2]; - sC_hihj_g1g2[hi][hj][g1][g2][t] = -eta_Gamma[g1] * res / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ); + MPI_Reduce(&res_hihj_g1g2[hi][hj][g1][g2], &mpi_res_hihj_g1g2[hi][hj][g1][g2], 1, + MPI_DOUBLE, MPI_SUM, 0, g_mpi_time_slices); + res_hihj_g1g2[hi][hj][g1][g2] = mpi_res_hihj_g1g2[hi][hj][g1][g2]; + sC_hihj_g1g2[hi][hj][g1][g2][t] = + -eta_Gamma[g1] * res / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ); #else - C_hihj_g1g2[hi][hj][g1][g2][t] = -eta_Gamma[g1] * res / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ); + C_hihj_g1g2[hi][hj][g1][g2][t] = + -eta_Gamma[g1] * res / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ); #endif - } - } - } } + } + } + } - } // end loop over "t" + } // end loop over "t" #ifdef TM_USE_MPI - /* some gymnastics needed in case of parallelisation */ - if (g_mpi_time_rank == 0) { - // light correlators - MPI_Gather(sCpp, T, MPI_DOUBLE, Cpp, T, MPI_DOUBLE, 0, g_mpi_SV_slices); - MPI_Gather(sCpa, T, MPI_DOUBLE, Cpa, T, MPI_DOUBLE, 0, g_mpi_SV_slices); - MPI_Gather(sCp4, T, MPI_DOUBLE, Cp4, T, MPI_DOUBLE, 0, g_mpi_SV_slices); - - // heavy mesons - for (size_t hi = 0; hi < 2; hi++) { - for (size_t hj = 0; hj < 2; hj++) { - for (size_t g1 = 0; g1 < 2; g1++) { - for (size_t g2 = 0; g2 < 2; g2++) { - MPI_Gather(sC_hihj_g1g2[hi][hj][g1][g2], T, MPI_DOUBLE, C_hihj_g1g2[hi][hj][g1][g2], - T, MPI_DOUBLE, 0, g_mpi_SV_slices); - } - } + /* some gymnastics needed in case of parallelisation */ + if (g_mpi_time_rank == 0) { + // light correlators + MPI_Gather(sCpp, T, MPI_DOUBLE, Cpp, T, MPI_DOUBLE, 0, g_mpi_SV_slices); + MPI_Gather(sCpa, T, MPI_DOUBLE, Cpa, T, MPI_DOUBLE, 0, g_mpi_SV_slices); + MPI_Gather(sCp4, T, MPI_DOUBLE, Cp4, T, MPI_DOUBLE, 0, g_mpi_SV_slices); + + // heavy mesons + for (size_t hi = 0; hi < 2; hi++) { + for (size_t hj = 0; hj < 2; hj++) { + for (size_t g1 = 0; g1 < 2; g1++) { + for (size_t g2 = 0; g2 < 2; g2++) { + MPI_Gather(sC_hihj_g1g2[hi][hj][g1][g2], T, MPI_DOUBLE, C_hihj_g1g2[hi][hj][g1][g2], + T, MPI_DOUBLE, 0, g_mpi_SV_slices); } } } + } + } #endif - /* and write everything into a file */ - if (g_mpi_time_rank == 0 && g_proc_coords[0] == 0) { - ofs = fopen(filename, "w"); - fprintf(ofs, "1 1 0 %e %e\n", Cpp[t0], 0.); - for (t = 1; t < g_nproc_t * T / 2; t++) { - tt = (t0 + t) % (g_nproc_t * T); - fprintf(ofs, "1 1 %d %e ", t, Cpp[tt]); - tt = (t0 + g_nproc_t * T - t) % (g_nproc_t * T); - fprintf(ofs, "%e\n", Cpp[tt]); - } - tt = (t0 + g_nproc_t * T / 2) % (g_nproc_t * T); - fprintf(ofs, "1 1 %d %e %e\n", t, Cpp[tt], 0.); - - fprintf(ofs, "2 1 0 %e %e\n", Cpa[t0], 0.); - for (t = 1; t < g_nproc_t * T / 2; t++) { - tt = (t0 + t) % (g_nproc_t * T); - fprintf(ofs, "2 1 %d %e ", t, Cpa[tt]); - tt = (t0 + g_nproc_t * T - t) % (g_nproc_t * T); - fprintf(ofs, "%e\n", Cpa[tt]); - } - tt = (t0 + g_nproc_t * T / 2) % (g_nproc_t * T); - fprintf(ofs, "2 1 %d %e %e\n", t, Cpa[tt], 0.); - - fprintf(ofs, "6 1 0 %e %e\n", Cp4[t0], 0.); - for (t = 1; t < g_nproc_t * T / 2; t++) { - tt = (t0 + t) % (g_nproc_t * T); - fprintf(ofs, "6 1 %d %e ", t, Cp4[tt]); - tt = (t0 + g_nproc_t * T - t) % (g_nproc_t * T); - fprintf(ofs, "%e\n", Cp4[tt]); - } - tt = (t0 + g_nproc_t * T / 2) % (g_nproc_t * T); - fprintf(ofs, "6 1 %d %e %e\n", t, Cp4[tt], 0.); - - // heavy meson correlators - for (size_t hi = 0; hi < 2; hi++) { - for (size_t hj = 0; hj < 2; hj++) { - for (size_t g1 = 0; g1 < 2; g1++) { - for (size_t g2 = 0; g2 < 2; g2++) { - fprintf(ofs, "%d %d %d %d 0 %e %e\n", hi, hj, g1, g2, C_hihj_g1g2[hi][hj][g1][g1][t0], 0.); - for (t = 1; t < g_nproc_t * T / 2; t++) { - tt = (t0 + t) % (g_nproc_t * T); - fprintf(ofs, "%d %d %d %d %d %e ", hi, hj, g1, g2, t, C_hihj_g1g2[hi][hj][g1][g2][tt]); - tt = (t0 + g_nproc_t * T - t) % (g_nproc_t * T); - fprintf(ofs, "%e\n", C_hihj_g1g2[hi][hj][g1][g2][tt]); - } - tt = (t0 + g_nproc_t * T / 2) % (g_nproc_t * T); - fprintf(ofs, "%d %d %d %d %d %d %e %e\n", hi, hj, g1, g2, t, - C_hihj_g1g2[hi][hj][g1][g2][tt], 0.0); - } + /* and write everything into a file */ + if (g_mpi_time_rank == 0 && g_proc_coords[0] == 0) { + ofs = fopen(filename, "w"); + fprintf(ofs, "1 1 0 %e %e\n", Cpp[t0], 0.); + for (t = 1; t < g_nproc_t * T / 2; t++) { + tt = (t0 + t) % (g_nproc_t * T); + fprintf(ofs, "1 1 %d %e ", t, Cpp[tt]); + tt = (t0 + g_nproc_t * T - t) % (g_nproc_t * T); + fprintf(ofs, "%e\n", Cpp[tt]); + } + tt = (t0 + g_nproc_t * T / 2) % (g_nproc_t * T); + fprintf(ofs, "1 1 %d %e %e\n", t, Cpp[tt], 0.); + + fprintf(ofs, "2 1 0 %e %e\n", Cpa[t0], 0.); + for (t = 1; t < g_nproc_t * T / 2; t++) { + tt = (t0 + t) % (g_nproc_t * T); + fprintf(ofs, "2 1 %d %e ", t, Cpa[tt]); + tt = (t0 + g_nproc_t * T - t) % (g_nproc_t * T); + fprintf(ofs, "%e\n", Cpa[tt]); + } + tt = (t0 + g_nproc_t * T / 2) % (g_nproc_t * T); + fprintf(ofs, "2 1 %d %e %e\n", t, Cpa[tt], 0.); + + fprintf(ofs, "6 1 0 %e %e\n", Cp4[t0], 0.); + for (t = 1; t < g_nproc_t * T / 2; t++) { + tt = (t0 + t) % (g_nproc_t * T); + fprintf(ofs, "6 1 %d %e ", t, Cp4[tt]); + tt = (t0 + g_nproc_t * T - t) % (g_nproc_t * T); + fprintf(ofs, "%e\n", Cp4[tt]); + } + tt = (t0 + g_nproc_t * T / 2) % (g_nproc_t * T); + fprintf(ofs, "6 1 %d %e %e\n", t, Cp4[tt], 0.); + + // heavy meson correlators + for (size_t hi = 0; hi < 2; hi++) { + for (size_t hj = 0; hj < 2; hj++) { + for (size_t g1 = 0; g1 < 2; g1++) { + for (size_t g2 = 0; g2 < 2; g2++) { + fprintf(ofs, "%d %d %d %d 0 %e %e\n", hi, hj, g1, g2, + C_hihj_g1g2[hi][hj][g1][g1][t0], 0.); + for (t = 1; t < g_nproc_t * T / 2; t++) { + tt = (t0 + t) % (g_nproc_t * T); + fprintf(ofs, "%d %d %d %d %d %e ", hi, hj, g1, g2, t, + C_hihj_g1g2[hi][hj][g1][g2][tt]); + tt = (t0 + g_nproc_t * T - t) % (g_nproc_t * T); + fprintf(ofs, "%e\n", C_hihj_g1g2[hi][hj][g1][g2][tt]); } + tt = (t0 + g_nproc_t * T / 2) % (g_nproc_t * T); + fprintf(ofs, "%d %d %d %d %d %d %e %e\n", hi, hj, g1, g2, t, + C_hihj_g1g2[hi][hj][g1][g2][tt], 0.0); } } - fclose(ofs); } + } + fclose(ofs); + } #ifdef TM_USE_MPI - if (g_mpi_time_rank == 0) { - free(Cpp); - free(Cpa); - free(Cp4); - free(C_hihj_g1g2); - } - free(sCpp); - free(sCpa); - free(sCp4); - free(sC_hihj_g1g2); + if (g_mpi_time_rank == 0) { + free(Cpp); + free(Cpa); + free(Cp4); + free(C_hihj_g1g2); + } + free(sCpp); + free(sCpa); + free(sCp4); + free(sC_hihj_g1g2); #else - free(Cpp); - free(Cpa); - free(Cp4); - free(C_hihj_g1g2); + free(Cpp); + free(Cpa); + free(Cp4); + free(C_hihj_g1g2); #endif - } // for(max_time_slices) - } // for(max_samples) + } // for(max_time_slices) + } // for(max_samples) - tm_stopwatch_pop(&g_timers, 0, 1, ""); + tm_stopwatch_pop(&g_timers, 0, 1, ""); - return; + return; } void correlators_measurement(const int traj, const int id, const int ieo) { From 9a9a68975331c0ecfaa311d028bf9fb1abd3f48e Mon Sep 17 00:00:00 2001 From: simone-romiti Date: Thu, 7 Dec 2023 15:48:41 +0100 Subject: [PATCH 30/51] debugging --- meas/correlators.c | 112 ++++++++++++++++++++++++++++++++------------- 1 file changed, 81 insertions(+), 31 deletions(-) diff --git a/meas/correlators.c b/meas/correlators.c index c6b87a86c..426a19e64 100644 --- a/meas/correlators.c +++ b/meas/correlators.c @@ -256,39 +256,82 @@ void light_correlators_measurement(const int traj, const int id, const int ieo) // Function to allocate memory for a pointer of pointers for an array of d dimensions void* callocMultiDimensional(int* sizes, int numDimensions, size_t elementSize) { - if (numDimensions == 1) { - void* array = calloc(sizes[0], sizeof(elementSize)); + + if (numDimensions == 1) { + return (void *)malloc(elementSize); + } else { + + int totSize = 1; + for (int i = 0; i < numDimensions; i++) { + totSize *= sizes[i]; + } + + void ***multiArray = malloc(totSize * elementSize); + for (int i = 0; i < totSize; i++) { + multiArray[i] = callocMultiDimensional(sizes + 1, numDimensions - 1, elementSize); + } + + return multiArray; + } + + + + + /* printf("for loop\n"); */ + /* for (int i=0; i spin * dilution */ const unsigned int seed_i = measurement_list[id].seed; // has to be same seed @@ -701,6 +748,9 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, } #endif + printf("ciao Simone\n"); + exit(1); + /* and write everything into a file */ if (g_mpi_time_rank == 0 && g_proc_coords[0] == 0) { ofs = fopen(filename, "w"); @@ -783,11 +833,11 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, } void correlators_measurement(const int traj, const int id, const int ieo) { - light_correlators_measurement(traj, id, ieo); + //light_correlators_measurement(traj, id, ieo); // ??? maybe add a double check? if (measurement_list[id].measure_heavy_mesons == 1) { - const unsigned int i1 = 0, i2 = 1; + const unsigned int i1 = 0, i2 = 1; heavy_correlators_measurement(traj, id, ieo, i1, i2); } } From ce867bc53343cc994e9395608053b7e742e09040 Mon Sep 17 00:00:00 2001 From: simone-romiti Date: Fri, 5 Jan 2024 16:01:13 +0100 Subject: [PATCH 31/51] still debugging --- meas/correlators.c | 190 +++++++++++++++++++++++------------------- meas/measurements.c | 2 +- offline_measurement.c | 3 + 3 files changed, 108 insertions(+), 87 deletions(-) diff --git a/meas/correlators.c b/meas/correlators.c index 426a19e64..e53448884 100644 --- a/meas/correlators.c +++ b/meas/correlators.c @@ -257,84 +257,34 @@ void light_correlators_measurement(const int traj, const int id, const int ieo) // Function to allocate memory for a pointer of pointers for an array of d dimensions void* callocMultiDimensional(int* sizes, int numDimensions, size_t elementSize) { + if (g_proc_id == 0){ + /* printf("sizes[0]=%d, numDimensions=%d\n", sizes[0], numDimensions); */ + } + if (numDimensions == 1) { - return (void *)malloc(elementSize); + //printf("Final return\n"); + return (void *)malloc(sizes[0]*elementSize); } else { int totSize = 1; for (int i = 0; i < numDimensions; i++) { totSize *= sizes[i]; } + + if (g_proc_id == 0){ + //printf("numDimensions=%d, totSize=%d\n", numDimensions, totSize); + } void ***multiArray = malloc(totSize * elementSize); - for (int i = 0; i < totSize; i++) { - multiArray[i] = callocMultiDimensional(sizes + 1, numDimensions - 1, elementSize); - } + return multiArray; + /* for (int i = 0; i < sizes[0]; i++) { */ + /* multiArray[i] = callocMultiDimensional(sizes + 1, numDimensions - 1, elementSize); */ + /* } */ - return multiArray; + /* return multiArray; */ } - - - - - /* printf("for loop\n"); */ - /* for (int i=0; i (), @@ -352,6 +302,7 @@ void* callocMultiDimensional(int* sizes, int numDimensions, size_t elementSize) void heavy_correlators_measurement(const int traj, const int id, const int ieo, const int i1, const int i2) { tm_stopwatch_push(&g_timers, __func__, ""); // timer for profiling + printf("Called: %s\n", __func__); spinor phi; // dummy spinor int i, j, t, tt, t0; // dummy indices @@ -384,34 +335,71 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, Cp4 = (double *)calloc(T, sizeof(double)); #endif + if (g_proc_id == 0){ + printf("Checkpoint 1 - %d\n", g_mpi_time_rank); + } + /* heavy-light correlators variables */ - double eta_Gamma[2] = {1.0, -1.0}; // sign change bilinear^\dagger, with Gamma = 1,gamma_5 + + // sign change bilinear^\dagger, with Gamma = 1,gamma_ + double eta_Gamma[2] = {1.0, -1.0}; // the number of independent correlators is 16 = (2*2)_{h_1 h_2} * (2*2)_{Gamma_1 Gamma_2} // hi: c,s // Gamma = 1, gamma_5 + double *****C_hihj_g1g2 = NULL; + +#ifdef TM_USE_MPI + const int sizes_C_hihj_g1g2[5] = {2, 2, 2, 2, g_nproc_t*T}; + if (g_mpi_time_rank == 0) { + C_hihj_g1g2 = (double *****)callocMultiDimensional(&sizes_C_hihj_g1g2[0], 5, sizeof(double)); + } +#else const int sizes_C_hihj_g1g2[5] = {2, 2, 2, 2, T}; - double *****C_hihj_g1g2 = - (double *****)callocMultiDimensional(sizes_C_hihj_g1g2, 5, sizeof(double)); + C_hihj_g1g2 = (double *****)callocMultiDimensional(&sizes_C_hihj_g1g2[0], 5, sizeof(double)); +#endif + + + if (g_proc_id == 0){ + //C_hihj_g1g2[0][1][0][0][10] = 1.0; + printf("Checkpoint 2 - T=%d\n", T); + } const int sizes_res_hihj_g1g2[4] = {2, 2, 2, 2}; - double ****res_hihj_g1g2 = - (double ****)callocMultiDimensional(sizes_res_hihj_g1g2, 4, sizeof(double)); + double ****res_hihj_g1g2 = NULL; + /* = (double ****)callocMultiDimensional(&sizes_res_hihj_g1g2[0], 4, sizeof(double)); */ + + if (g_proc_id == 0){ + printf("Checkpoint 3\n"); + } + #ifdef TM_USE_MPI double ****mpi_res_hihj_g1g2 = - (double ****)callocMultiDimensional(sizes_res_hihj_g1g2, 4, sizeof(double)); + (double ****)callocMultiDimensional(&sizes_res_hihj_g1g2[0], 4, sizeof(double)); // send buffer for MPI_Gather double *****sC_hihj_g1g2 = - (double *****)callocMultiDimensional(sizes_C_hihj_g1g2, 5, sizeof(double)); + (double *****)callocMultiDimensional(&sizes_C_hihj_g1g2[0], 5, sizeof(double)); + if (g_mpi_time_rank == 0) { + res_hihj_g1g2 = (double ****)callocMultiDimensional(&sizes_res_hihj_g1g2[0], 4, sizeof(double)); + } +#else + res_hihj_g1g2 = (double ****)callocMultiDimensional(&sizes_res_hihj_g1g2[0], 4, sizeof(double)); #endif + FILE *ofs; // output file stream char filename[TM_OMEAS_FILENAME_LENGTH]; // file path /* building the stochastic propagator spinors needed for the correlators */ - init_operators(); // initialize the operators in the action (if not already done) - if (no_operators < 1) { + // MPI_Barrier(MPI_COMM_WORLD); + init_operators(); // initialize operators (if not already done) + + if (g_proc_id == 0){ + printf("Checkpoint 4\n"); + } + + if (no_operators < 1) { if (g_proc_id == 0) { // we don't want the simulation to stop, we can do the measurements offline afterwards fprintf(stderr, @@ -425,6 +413,7 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, // selecting the operators i1 and i2 from the list of operators initialized before operator* optr1 = & operator_list[i1]; // light doublet operator* optr2 = & operator_list[i2]; // heavy c,s doublet + printf("Initialized the operators\n"); bool b1 = (optr1->type != TMWILSON && optr1->type != WILSON && optr1->type != CLOVER); bool b2 = (optr2->type != DBTMWILSON && optr2->type != DBCLOVER); @@ -448,7 +437,6 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, rlxs_init(1, 123456); // initializing random number generator RANLUX } - // there are three modes of operation // 1) one single time-slice source (default) // 2) no_samples time-slice sources on random time-slices @@ -484,6 +472,7 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, optr1->kappa, optr1->mubar, optr1->epsbar); } + // even-odd spinor fields for the light and heavy doublet correlators // INDICES: source+propagator, doublet, spin dilution index, flavor projection, even-odd, // flavor, position @@ -493,9 +482,18 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, const int sizes_arr_eo_spinor[7] = {2, 2, 4, 2, 2, 2, VOLUME / 2}; - spinor *******arr_eo_spinor = - (spinor *******)callocMultiDimensional(sizes_arr_eo_spinor, 7, sizeof(spinor)); + + //spinor *******arr_eo_spinor = (spinor *******) callocMultiDimensional(&sizes_arr_eo_spinor[0], 7, sizeof(spinor)); + printf("HELLO Simone\n"); + spinor* arr_eo_spinor[2][2][4][2][2][2]; + + MPI_Barrier(MPI_COMM_WORLD); + printf("HELLO\n"); + MPI_Barrier(MPI_COMM_WORLD); + if (g_proc_id == 0){ + //printf("s1=%d, s2=%d\n", sizeof(arr_eo_spinor[0][0][0][0][0][0][1]), sizeof(spinor)); + } /* initalize the random sources: one source for each Dirac index beta=src_d --> spin * dilution */ @@ -505,14 +503,32 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, for (size_t F = 0; F < 2; F++) { // flavor dilution index for (size_t i_f = 0; i_f < 2; i_f++) { // flavor index of the doublet // light doublet - eo_source_spinor_field_spin_diluted_oet_ts(arr_eo_spinor[0][db][beta][F][0][i_f], - arr_eo_spinor[0][db][beta][F][1][i_f], t0, - beta, sample, traj, seed_i); + MPI_Barrier(MPI_COMM_WORLD); + spinor* sp1 = malloc((VOLUME/2)*sizeof(spinor)); + spinor* sp2 = malloc((VOLUME/2)*sizeof(spinor)); + arr_eo_spinor[0][db][beta][F][0][i_f][0] = (spinor*) malloc((VOLUME/2)*sizeof(spinor)); + arr_eo_spinor[0][db][beta][F][1][i_f][0] = (spinor*) malloc((VOLUME/2)*sizeof(spinor)); + eo_source_spinor_field_spin_diluted_oet_ts(sp1, sp2, t0, beta, sample, traj, seed_i); + + /* eo_source_spinor_field_spin_diluted_oet_ts(&arr_eo_spinor[0][db][beta][F][0][i_f][0], */ + /* &arr_eo_spinor[0][db][beta][F][1][i_f][0], t0, */ + /* beta, sample, traj, seed_i); */ + for (size_t isp = 0; isp < VOLUME/2; isp++) { + //arr_eo_spinor[0][db][beta][F][1][i_f][isp] = sp1[isp]; + } + if (g_proc_id == 0){ + printf("size sp1=%d, spinor_size=%d, volume_half=%d\n", sizeof(sp1), sizeof(spinor), VOLUME/2); + } } } } } + MPI_Barrier(MPI_COMM_WORLD); + if (g_proc_id == 0){ + printf("Checkpoint 5\n"); + } + // heavy doublet: for each even-odd block, I multiply by (1 + i*tau_2)/sqrt(2) // the basis for the inversion should be the same as for the light // --> I will multiply later by the inverse, namely at the end of the inversion @@ -551,6 +567,7 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, optr1->prop0 = arr_eo_spinor[1][0][beta][0][0]; optr1->prop1 = arr_eo_spinor[1][0][beta][1][0]; + printf("inverting the light doublet\n"); optr1->inverter(i1, 0, 0); // inversion for the up flavor // PLEASE KEEP THESE LINES COMMENTED, MAY BE USEFUL IN THE FUTURE @@ -581,6 +598,7 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, optr2->prop2 = arr_eo_spinor[1][1][beta][0][1]; optr2->prop3 = arr_eo_spinor[1][1][beta][1][1]; + printf("Inverting the heavy doublet\n"); optr2->inverter(i2, 0, 0); // inversion for both flavor components } @@ -748,7 +766,7 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, } #endif - printf("ciao Simone\n"); + printf("ciao Simone, I'm exiting\n"); exit(1); /* and write everything into a file */ @@ -834,10 +852,10 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, void correlators_measurement(const int traj, const int id, const int ieo) { //light_correlators_measurement(traj, id, ieo); - - // ??? maybe add a double check? - if (measurement_list[id].measure_heavy_mesons == 1) { - const unsigned int i1 = 0, i2 = 1; - heavy_correlators_measurement(traj, id, ieo, i1, i2); + + // ??? maybe add a double check? + if (measurement_list[id].measure_heavy_mesons == 1) { + const unsigned int i1 = 0, i2 = 1; + heavy_correlators_measurement(traj, id, ieo, i1, i2); } } diff --git a/meas/measurements.c b/meas/measurements.c index b18d263f9..1b9eca94b 100644 --- a/meas/measurements.c +++ b/meas/measurements.c @@ -43,7 +43,7 @@ int no_measurements = 0; int add_measurement(const enum MEAS_TYPE meas_type) { if(no_measurements == max_no_measurements) { - fprintf(stderr, "maximal number of measurementss %d exceeded!\n", max_no_measurements); + fprintf(stderr, "maximal number of measurements %d exceeded!\n", max_no_measurements); exit(-1); } measurement_list[no_measurements].measurefunc = &dummy_meas; diff --git a/offline_measurement.c b/offline_measurement.c index 766dc1472..95ea094e8 100644 --- a/offline_measurement.c +++ b/offline_measurement.c @@ -83,6 +83,7 @@ int main(int argc, char *argv[]) char * filename = NULL; double plaquette_energy; + init_critical_globals(TM_PROGRAM_OFFLINE_MEASUREMENT); #ifdef _KOJAK_INST @@ -292,7 +293,9 @@ int main(int argc, char *argv[]) if (g_proc_id == 0) { fprintf(stdout, "#\n# Beginning offline measurement.\n"); } + //printf("Ciao Simone4!\n"); meas->measurefunc(nstore, imeas, even_odd_flag); + printf("Ciao Simone5!\n"); } nstore += Nsave; } From 9ce773487bcb40eddbb2c900588e758ed6603959 Mon Sep 17 00:00:00 2001 From: simone-romiti Date: Fri, 5 Jan 2024 16:43:03 +0100 Subject: [PATCH 32/51] probably solved the issue with allocarion of spinor arrays --- meas/correlators.c | 103 ++++++++++++++++++++++++--------------------- 1 file changed, 54 insertions(+), 49 deletions(-) diff --git a/meas/correlators.c b/meas/correlators.c index e53448884..7cb1aa165 100644 --- a/meas/correlators.c +++ b/meas/correlators.c @@ -479,20 +479,27 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, // (+ Dirac, color) psi = (psi[(s,p)][db][beta][F][eo][f][x])[alpha][c] // last 2 indices come from spinor struct // Note: propagator in the sense that it is D^{-1}*source after the inversion - const int sizes_arr_eo_spinor[7] = {2, 2, 4, 2, 2, 2, VOLUME / 2}; - - - - //spinor *******arr_eo_spinor = (spinor *******) callocMultiDimensional(&sizes_arr_eo_spinor[0], 7, sizeof(spinor)); - printf("HELLO Simone\n"); + // const int sizes_arr_eo_spinor[7] = {2, 2, 4, 2, 2, 2, VOLUME / 2}; + // spinor *******arr_eo_spinor = (spinor *******) callocMultiDimensional(&sizes_arr_eo_spinor[0], 7, sizeof(spinor)); spinor* arr_eo_spinor[2][2][4][2][2][2]; - - MPI_Barrier(MPI_COMM_WORLD); - printf("HELLO\n"); - - MPI_Barrier(MPI_COMM_WORLD); - if (g_proc_id == 0){ - //printf("s1=%d, s2=%d\n", sizeof(arr_eo_spinor[0][0][0][0][0][0][1]), sizeof(spinor)); + spinor* arr_spinor[2][2][4][2][2]; + + // allocating memory + for (size_t i_sp = 0; i_sp < 2; i_sp++) { // source or propagator + for (size_t db = 0; db < 2; db++) { // doublet: light or heavy + for (size_t beta = 0; beta < 4; beta++) { // spin dilution index + for (size_t F = 0; F < 2; F++) { // flavor dilution index + for (size_t i_eo = 0; i_eo < 2; i_eo++) { // even-odd index + for (size_t i_f = 0; i_f < 2; i_f++){// flavor index of the doublet + arr_eo_spinor[i_sp][db][beta][F][i_eo][i_f] = (spinor*) malloc((VOLUME/2)*sizeof(spinor)); + if (i_eo ==0){ // doing it only once -> no eo index + arr_spinor[i_sp][db][beta][F][i_f] = (spinor*) malloc((VOLUME/2)*sizeof(spinor)); + } + } + } + } + } + } } /* initalize the random sources: one source for each Dirac index beta=src_d --> spin @@ -503,22 +510,9 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, for (size_t F = 0; F < 2; F++) { // flavor dilution index for (size_t i_f = 0; i_f < 2; i_f++) { // flavor index of the doublet // light doublet - MPI_Barrier(MPI_COMM_WORLD); - spinor* sp1 = malloc((VOLUME/2)*sizeof(spinor)); - spinor* sp2 = malloc((VOLUME/2)*sizeof(spinor)); - arr_eo_spinor[0][db][beta][F][0][i_f][0] = (spinor*) malloc((VOLUME/2)*sizeof(spinor)); - arr_eo_spinor[0][db][beta][F][1][i_f][0] = (spinor*) malloc((VOLUME/2)*sizeof(spinor)); - eo_source_spinor_field_spin_diluted_oet_ts(sp1, sp2, t0, beta, sample, traj, seed_i); - - /* eo_source_spinor_field_spin_diluted_oet_ts(&arr_eo_spinor[0][db][beta][F][0][i_f][0], */ - /* &arr_eo_spinor[0][db][beta][F][1][i_f][0], t0, */ - /* beta, sample, traj, seed_i); */ - for (size_t isp = 0; isp < VOLUME/2; isp++) { - //arr_eo_spinor[0][db][beta][F][1][i_f][isp] = sp1[isp]; - } - if (g_proc_id == 0){ - printf("size sp1=%d, spinor_size=%d, volume_half=%d\n", sizeof(sp1), sizeof(spinor), VOLUME/2); - } + eo_source_spinor_field_spin_diluted_oet_ts(arr_eo_spinor[0][db][beta][F][0][i_f], + arr_eo_spinor[0][db][beta][F][1][i_f], t0, + beta, sample, traj, seed_i); } } } @@ -552,6 +546,11 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, } } + MPI_Barrier(MPI_COMM_WORLD); + if (g_proc_id == 0){ + printf("Checkpoint 6\n"); + } + /* assign the sources and propagator pointes for the operators these need to be know when calling the inverter() method */ @@ -560,12 +559,17 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, // up - // sorces - optr1->sr0 = arr_eo_spinor[0][0][beta][0][0]; - optr1->sr1 = arr_eo_spinor[0][0][beta][1][0]; + // sources + optr1->sr0 = arr_eo_spinor[0][0][beta][0][0][0]; + optr1->sr1 = arr_eo_spinor[0][0][beta][0][1][0]; + MPI_Barrier(MPI_COMM_WORLD); + if (g_proc_id == 0){ + printf("Checkpoint 7\n"); + } + // propagators - optr1->prop0 = arr_eo_spinor[1][0][beta][0][0]; - optr1->prop1 = arr_eo_spinor[1][0][beta][1][0]; + optr1->prop0 = arr_eo_spinor[1][0][beta][0][0][0]; + optr1->prop1 = arr_eo_spinor[1][0][beta][0][1][0]; printf("inverting the light doublet\n"); optr1->inverter(i1, 0, 0); // inversion for the up flavor @@ -587,19 +591,20 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, // optr1->DownProp = 0; // restoring to default /* heavy doublet */ - - optr2->sr0 = arr_eo_spinor[0][1][beta][0][0]; - optr2->sr1 = arr_eo_spinor[0][1][beta][1][0]; - optr2->sr2 = arr_eo_spinor[0][1][beta][0][1]; - optr2->sr3 = arr_eo_spinor[0][1][beta][1][1]; - - optr2->prop0 = arr_eo_spinor[1][1][beta][0][0]; - optr2->prop1 = arr_eo_spinor[1][1][beta][1][0]; - optr2->prop2 = arr_eo_spinor[1][1][beta][0][1]; - optr2->prop3 = arr_eo_spinor[1][1][beta][1][1]; - printf("Inverting the heavy doublet\n"); - optr2->inverter(i2, 0, 0); // inversion for both flavor components + for (size_t F = 0; F < 2; F++) { // flavor projection index + optr2->sr0 = arr_eo_spinor[0][1][beta][F][0][0]; + optr2->sr1 = arr_eo_spinor[0][1][beta][F][1][0]; + optr2->sr2 = arr_eo_spinor[0][1][beta][F][0][1]; + optr2->sr3 = arr_eo_spinor[0][1][beta][F][1][1]; + + optr2->prop0 = arr_eo_spinor[1][1][beta][F][0][0]; + optr2->prop1 = arr_eo_spinor[1][1][beta][F][1][0]; + optr2->prop2 = arr_eo_spinor[1][1][beta][F][0][1]; + optr2->prop3 = arr_eo_spinor[1][1][beta][F][1][1]; + + optr2->inverter(i2, 0, 0); // inversion for both flavor components + } } // conclude the change of basis for the heavy doublet @@ -626,9 +631,9 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, // (no even-odd): source+propagator, doublet, spin dilution index, flavor proj, flavor // index, position (+ Dirac, color) (psi[i_sp][d][beta][F][f][x])[alpha][c] // last 3 indices come from the spinor struct - const int sizes_arr_spinor = {2, 2, 4, 2, 2, VOLUME}; - spinor ******arr_spinor = - (spinor ******)callocMultiDimensional(sizes_arr_spinor, 6, sizeof(spinor)); + /* const int sizes_arr_spinor = {2, 2, 4, 2, 2, VOLUME}; */ + /* spinor ******arr_spinor = */ + /* (spinor ******)callocMultiDimensional(sizes_arr_spinor, 6, sizeof(spinor)); */ // now we switch from even-odd representation to standard From 5c873a9c15938fd50ea12b32e8cdaf9f3348dbf3 Mon Sep 17 00:00:00 2001 From: simone-romiti Date: Mon, 8 Jan 2024 11:36:20 +0100 Subject: [PATCH 33/51] making progress: no memory leaks if commenting the 2 lines of the inversion --- meas/correlators.c | 151 +++++++++++++++++++++++++++++++++------------ 1 file changed, 110 insertions(+), 41 deletions(-) diff --git a/meas/correlators.c b/meas/correlators.c index 7cb1aa165..56c9cb269 100644 --- a/meas/correlators.c +++ b/meas/correlators.c @@ -347,17 +347,36 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, // the number of independent correlators is 16 = (2*2)_{h_1 h_2} * (2*2)_{Gamma_1 Gamma_2} // hi: c,s // Gamma = 1, gamma_5 - double *****C_hihj_g1g2 = NULL; - + double* C_hihj_g1g2[2][2][2][2]; + double *sC_hihj_g1g2[2][2][2][2]; + + // allocating memory + for (int h1=0; h1<2; h1++){ + for (int h2=0; h2<2; h2++){ + for (int g1=0; g1<2; g1++){ + for (int g2=0; g2<2; g2++){ #ifdef TM_USE_MPI - const int sizes_C_hihj_g1g2[5] = {2, 2, 2, 2, g_nproc_t*T}; - if (g_mpi_time_rank == 0) { - C_hihj_g1g2 = (double *****)callocMultiDimensional(&sizes_C_hihj_g1g2[0], 5, sizeof(double)); - } + sC_hihj_g1g2[h1][h2][g1][g2] = (double*) malloc(T*sizeof(double)); + if (g_mpi_time_rank == 0) { + C_hihj_g1g2[h1][h2][g1][g2] = (double*) malloc(g_nproc_t*T*sizeof(double)); + } #else - const int sizes_C_hihj_g1g2[5] = {2, 2, 2, 2, T}; - C_hihj_g1g2 = (double *****)callocMultiDimensional(&sizes_C_hihj_g1g2[0], 5, sizeof(double)); + C_hihj_g1g2[h1][h2][g1][g2] = (double*) malloc(T*sizeof(double)); #endif + } + } + } + } + +/* #ifdef TM_USE_MPI */ +/* const int sizes_C_hihj_g1g2[5] = {2, 2, 2, 2, g_nproc_t*T}; */ +/* if (g_mpi_time_rank == 0) { */ +/* C_hihj_g1g2 = (double *****)callocMultiDimensional(&sizes_C_hihj_g1g2[0], 5, sizeof(double)); */ +/* } */ +/* #else */ +/* const int sizes_C_hihj_g1g2[5] = {2, 2, 2, 2, T}; */ +/* C_hihj_g1g2 = (double *****)callocMultiDimensional(&sizes_C_hihj_g1g2[0], 5, sizeof(double)); */ +/* #endif */ if (g_proc_id == 0){ @@ -365,27 +384,13 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, printf("Checkpoint 2 - T=%d\n", T); } - const int sizes_res_hihj_g1g2[4] = {2, 2, 2, 2}; - double ****res_hihj_g1g2 = NULL; - /* = (double ****)callocMultiDimensional(&sizes_res_hihj_g1g2[0], 4, sizeof(double)); */ + double res_hihj_g1g2[2][2][2][2]; + double mpi_res_hihj_g1g2[2][2][2][2]; if (g_proc_id == 0){ printf("Checkpoint 3\n"); } -#ifdef TM_USE_MPI - double ****mpi_res_hihj_g1g2 = - (double ****)callocMultiDimensional(&sizes_res_hihj_g1g2[0], 4, sizeof(double)); - // send buffer for MPI_Gather - double *****sC_hihj_g1g2 = - (double *****)callocMultiDimensional(&sizes_C_hihj_g1g2[0], 5, sizeof(double)); - if (g_mpi_time_rank == 0) { - res_hihj_g1g2 = (double ****)callocMultiDimensional(&sizes_res_hihj_g1g2[0], 4, sizeof(double)); - } -#else - res_hihj_g1g2 = (double ****)callocMultiDimensional(&sizes_res_hihj_g1g2[0], 4, sizeof(double)); -#endif - FILE *ofs; // output file stream char filename[TM_OMEAS_FILENAME_LENGTH]; // file path @@ -482,6 +487,9 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, // const int sizes_arr_eo_spinor[7] = {2, 2, 4, 2, 2, 2, VOLUME / 2}; // spinor *******arr_eo_spinor = (spinor *******) callocMultiDimensional(&sizes_arr_eo_spinor[0], 7, sizeof(spinor)); spinor* arr_eo_spinor[2][2][4][2][2][2]; + + // (no even-odd): source+propagator, doublet, spin dilution index, flavor proj, flavor + // index, position (+ Dirac, color) (psi[i_sp][d][beta][F][f][x])[alpha][c] spinor* arr_spinor[2][2][4][2][2]; // allocating memory @@ -492,8 +500,8 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, for (size_t i_eo = 0; i_eo < 2; i_eo++) { // even-odd index for (size_t i_f = 0; i_f < 2; i_f++){// flavor index of the doublet arr_eo_spinor[i_sp][db][beta][F][i_eo][i_f] = (spinor*) malloc((VOLUME/2)*sizeof(spinor)); - if (i_eo ==0){ // doing it only once -> no eo index - arr_spinor[i_sp][db][beta][F][i_f] = (spinor*) malloc((VOLUME/2)*sizeof(spinor)); + if (i_eo == 0){ // doing it only once -> no eo index + arr_spinor[i_sp][db][beta][F][i_f] = (spinor*) malloc(VOLUME*sizeof(spinor)); } } } @@ -572,7 +580,9 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, optr1->prop1 = arr_eo_spinor[1][0][beta][0][1][0]; printf("inverting the light doublet\n"); - optr1->inverter(i1, 0, 0); // inversion for the up flavor + + // Simone: uncomment the next line + // optr1->inverter(i1, 0, 0); // inversion for the up flavor // PLEASE KEEP THESE LINES COMMENTED, MAY BE USEFUL IN THE FUTURE // // inversion of the light doublet only inverts the up block (the operator is @@ -593,6 +603,7 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, /* heavy doublet */ printf("Inverting the heavy doublet\n"); for (size_t F = 0; F < 2; F++) { // flavor projection index + printf("F=%d\n", F); optr2->sr0 = arr_eo_spinor[0][1][beta][F][0][0]; optr2->sr1 = arr_eo_spinor[0][1][beta][F][1][0]; optr2->sr2 = arr_eo_spinor[0][1][beta][F][0][1]; @@ -602,11 +613,18 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, optr2->prop1 = arr_eo_spinor[1][1][beta][F][1][0]; optr2->prop2 = arr_eo_spinor[1][1][beta][F][0][1]; optr2->prop3 = arr_eo_spinor[1][1][beta][F][1][1]; - - optr2->inverter(i2, 0, 0); // inversion for both flavor components + + // Simone: uncomment the next line + // optr2->inverter(i2, 0, 0); // inversion for both flavor components } } + MPI_Barrier(MPI_COMM_WORLD); + if (g_proc_id == 0){ + printf("Checkpoint 8\n"); + } + + // conclude the change of basis for the heavy doublet for (size_t beta = 0; beta < 4; beta++) { // spin dilution index for (size_t F = 0; F < 2; F++) { // flavor projection index @@ -624,10 +642,17 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, assign(arr_eo_spinor[0][1][beta][F][i_eo][i_f], arr_eo_spinor[1][1][beta][F][i_eo][i_f], VOLUME / 2); } + } } } + MPI_Barrier(MPI_COMM_WORLD); + if (g_proc_id == 0){ + printf("Checkpoint 9\n"); + } + + // (no even-odd): source+propagator, doublet, spin dilution index, flavor proj, flavor // index, position (+ Dirac, color) (psi[i_sp][d][beta][F][f][x])[alpha][c] // last 3 indices come from the spinor struct @@ -636,13 +661,12 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, /* (spinor ******)callocMultiDimensional(sizes_arr_spinor, 6, sizeof(spinor)); */ // now we switch from even-odd representation to standard - for (size_t i_sp = 0; i_sp < 2; i_sp++) { // source or sink for (size_t db = 0; db < 2; db++) { // doublet: light of heavy for (size_t F = 0; F < 2; F++) { // flavor projection index for (size_t beta = 0; beta < 4; beta++) { // spin dilution index for (size_t i_f = 0; i_f < 2; i_f++) { - convert_eo_to_lexic(arr_spinor[i_sp][db][F][beta][i_f], + convert_eo_to_lexic(arr_spinor[i_sp][db][F][beta][i_f], arr_eo_spinor[i_sp][db][F][beta][0][i_f], arr_eo_spinor[i_sp][db][F][beta][1][i_f]); } @@ -651,8 +675,33 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, } } - free(arr_eo_spinor); // freeing up space: eo spinors not needed anymore + MPI_Barrier(MPI_COMM_WORLD); + if (g_proc_id == 0){ + printf("Checkpoint 10\n"); + } + + // freeing up memory + for (size_t i_sp = 0; i_sp < 2; i_sp++) { // source or propagator + for (size_t db = 0; db < 2; db++) { // doublet: light or heavy + for (size_t beta = 0; beta < 4; beta++) { // spin dilution index + for (size_t F = 0; F < 2; F++) { // flavor dilution index + for (size_t i_eo = 0; i_eo < 2; i_eo++) { // even-odd index + for (size_t i_f = 0; i_f < 2; i_f++){// flavor index of the doublet + free(arr_eo_spinor[i_sp][db][beta][F][i_eo][i_f]); + } + } + } + } + } + } + + // free(arr_eo_spinor); // freeing up space: eo spinors not needed anymore + MPI_Barrier(MPI_COMM_WORLD); + if (g_proc_id == 0){ + printf("Checkpoint 11\n"); + } + /* Now that I have all the propagators (all in the basis of https://arxiv.org/pdf/1005.2042.pdf) I can build the correlators of eq. (20) @@ -771,8 +820,10 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, } #endif - printf("ciao Simone, I'm exiting\n"); - exit(1); + MPI_Barrier(MPI_COMM_WORLD); + if (g_proc_id == 0){ + printf("Checkpoint 12\n"); + } /* and write everything into a file */ if (g_mpi_time_rank == 0 && g_proc_coords[0] == 0) { @@ -830,35 +881,53 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, } fclose(ofs); } + + // freeing memory: light correlators #ifdef TM_USE_MPI if (g_mpi_time_rank == 0) { free(Cpp); free(Cpa); free(Cp4); - free(C_hihj_g1g2); } free(sCpp); free(sCpa); free(sCp4); - free(sC_hihj_g1g2); #else free(Cpp); free(Cpa); free(Cp4); - free(C_hihj_g1g2); #endif - } // for(max_time_slices) + + // freeing memory: heavy-light correlators + for (int h1=0; h1<2; h1++){ + for (int h2=0; h2<2; h2++){ + for (int g1=0; g1<2; g1++){ + for (int g2=0; g2<2; g2++){ +#ifdef TM_USE_MPI + free(sC_hihj_g1g2[h1][h2][g1][g2]); + if (g_mpi_time_rank == 0) { + free(C_hihj_g1g2[h1][h2][g1][g2]); + } +#else + free(C_hihj_g1g2[h1][h2][g1][g2]); +#endif + } + } + } + } + + } // for(max_time_slices) } // for(max_samples) - + tm_stopwatch_pop(&g_timers, 0, 1, ""); - + return; } void correlators_measurement(const int traj, const int id, const int ieo) { //light_correlators_measurement(traj, id, ieo); - // ??? maybe add a double check? + // ??? maybe add a double check? does i1 --> light and i2 --> heavy? if (measurement_list[id].measure_heavy_mesons == 1) { const unsigned int i1 = 0, i2 = 1; heavy_correlators_measurement(traj, id, ieo, i1, i2); From abbf92cf90845f0c57da35bc316253055f11ce4f Mon Sep 17 00:00:00 2001 From: simone-romiti Date: Mon, 8 Jan 2024 13:01:25 +0100 Subject: [PATCH 34/51] some issues when going to the next configuration (even without actual inversion) --- meas/correlators.c | 40 +++++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/meas/correlators.c b/meas/correlators.c index 56c9cb269..e6574fe48 100644 --- a/meas/correlators.c +++ b/meas/correlators.c @@ -356,12 +356,12 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, for (int g1=0; g1<2; g1++){ for (int g2=0; g2<2; g2++){ #ifdef TM_USE_MPI - sC_hihj_g1g2[h1][h2][g1][g2] = (double*) malloc(T*sizeof(double)); + sC_hihj_g1g2[h1][h2][g1][g2] = (double*) calloc(T, sizeof(double)); if (g_mpi_time_rank == 0) { - C_hihj_g1g2[h1][h2][g1][g2] = (double*) malloc(g_nproc_t*T*sizeof(double)); + C_hihj_g1g2[h1][h2][g1][g2] = (double*) calloc(g_nproc_t*T, sizeof(double)); } #else - C_hihj_g1g2[h1][h2][g1][g2] = (double*) malloc(T*sizeof(double)); + C_hihj_g1g2[h1][h2][g1][g2] = (double*) calloc(T, sizeof(double)); #endif } } @@ -580,9 +580,7 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, optr1->prop1 = arr_eo_spinor[1][0][beta][0][1][0]; printf("inverting the light doublet\n"); - - // Simone: uncomment the next line - // optr1->inverter(i1, 0, 0); // inversion for the up flavor + //optr1->inverter(i1, 0, 0); // inversion for the up flavor // PLEASE KEEP THESE LINES COMMENTED, MAY BE USEFUL IN THE FUTURE // // inversion of the light doublet only inverts the up block (the operator is @@ -614,8 +612,7 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, optr2->prop2 = arr_eo_spinor[1][1][beta][F][0][1]; optr2->prop3 = arr_eo_spinor[1][1][beta][F][1][1]; - // Simone: uncomment the next line - // optr2->inverter(i2, 0, 0); // inversion for both flavor components + //optr2->inverter(i2, 0, 0); // inversion for both flavor components } } @@ -817,6 +814,7 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, } } } + } #endif @@ -858,22 +856,22 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, tt = (t0 + g_nproc_t * T / 2) % (g_nproc_t * T); fprintf(ofs, "6 1 %d %e %e\n", t, Cp4[tt], 0.); - // heavy meson correlators + // heavy mesons correlators for (size_t hi = 0; hi < 2; hi++) { for (size_t hj = 0; hj < 2; hj++) { for (size_t g1 = 0; g1 < 2; g1++) { for (size_t g2 = 0; g2 < 2; g2++) { - fprintf(ofs, "%d %d %d %d 0 %e %e\n", hi, hj, g1, g2, + fprintf(ofs, "%u %u %u %u 0 %e %e\n", hi, hj, g1, g2, C_hihj_g1g2[hi][hj][g1][g1][t0], 0.); for (t = 1; t < g_nproc_t * T / 2; t++) { tt = (t0 + t) % (g_nproc_t * T); - fprintf(ofs, "%d %d %d %d %d %e ", hi, hj, g1, g2, t, + fprintf(ofs, "%u %u %u %u %d %e ", hi, hj, g1, g2, t, C_hihj_g1g2[hi][hj][g1][g2][tt]); tt = (t0 + g_nproc_t * T - t) % (g_nproc_t * T); fprintf(ofs, "%e\n", C_hihj_g1g2[hi][hj][g1][g2][tt]); } tt = (t0 + g_nproc_t * T / 2) % (g_nproc_t * T); - fprintf(ofs, "%d %d %d %d %d %d %e %e\n", hi, hj, g1, g2, t, + fprintf(ofs, "%u %u %u %u %d %e %e\n", hi, hj, g1, g2, t, C_hihj_g1g2[hi][hj][g1][g2][tt], 0.0); } } @@ -882,6 +880,11 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, fclose(ofs); } + MPI_Barrier(MPI_COMM_WORLD); + if (g_proc_id == 0){ + printf("Checkpoint 13\n"); + } + // freeing memory: light correlators #ifdef TM_USE_MPI if (g_mpi_time_rank == 0) { @@ -897,7 +900,12 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, free(Cpa); free(Cp4); #endif - + + MPI_Barrier(MPI_COMM_WORLD); + if (g_proc_id == 0){ + printf("Checkpoint 14\n"); + } + // freeing memory: heavy-light correlators for (int h1=0; h1<2; h1++){ for (int h2=0; h2<2; h2++){ @@ -915,6 +923,12 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, } } } + + MPI_Barrier(MPI_COMM_WORLD); + if (g_proc_id == 0){ + printf("Checkpoint 15\n"); + } + } // for(max_time_slices) } // for(max_samples) From 5cf93744d813dc82314ced5b9d6b857a600c943c Mon Sep 17 00:00:00 2001 From: simone-romiti Date: Wed, 10 Jan 2024 16:02:59 +0100 Subject: [PATCH 35/51] inversions working but the now output contains a bunch of "inf" --- meas/correlators.c | 452 +++++++++++++++++++++------------------------ 1 file changed, 209 insertions(+), 243 deletions(-) diff --git a/meas/correlators.c b/meas/correlators.c index e6574fe48..0c6ff28f8 100644 --- a/meas/correlators.c +++ b/meas/correlators.c @@ -204,7 +204,7 @@ void light_correlators_measurement(const int traj, const int id, const int ieo) /* and write everything into a file */ if(g_mpi_time_rank == 0 && g_proc_coords[0] == 0) { ofs = fopen(filename, "w"); - fprintf( ofs, "1 1 0 %e %e\n", Cpp[t0], 0.); + fprintf( ofs, "1 1 0 %e %e\n", Cpp[t0], 0.0); for(t = 1; t < g_nproc_t*T/2; t++) { tt = (t0+t)%(g_nproc_t*T); fprintf( ofs, "1 1 %d %e ", t, Cpp[tt]); @@ -212,9 +212,9 @@ void light_correlators_measurement(const int traj, const int id, const int ieo) fprintf( ofs, "%e\n", Cpp[tt]); } tt = (t0+g_nproc_t*T/2)%(g_nproc_t*T); - fprintf( ofs, "1 1 %d %e %e\n", t, Cpp[tt], 0.); + fprintf( ofs, "1 1 %d %e %e\n", t, Cpp[tt], 0.0); - fprintf( ofs, "2 1 0 %e %e\n", Cpa[t0], 0.); + fprintf( ofs, "2 1 0 %e %e\n", Cpa[t0], 0.0); for(t = 1; t < g_nproc_t*T/2; t++) { tt = (t0+t)%(g_nproc_t*T); fprintf( ofs, "2 1 %d %e ", t, Cpa[tt]); @@ -222,9 +222,9 @@ void light_correlators_measurement(const int traj, const int id, const int ieo) fprintf( ofs, "%e\n", Cpa[tt]); } tt = (t0+g_nproc_t*T/2)%(g_nproc_t*T); - fprintf( ofs, "2 1 %d %e %e\n", t, Cpa[tt], 0.); + fprintf( ofs, "2 1 %d %e %e\n", t, Cpa[tt], 0.0); - fprintf( ofs, "6 1 0 %e %e\n", Cp4[t0], 0.); + fprintf( ofs, "6 1 0 %e %e\n", Cp4[t0], 0.0); for(t = 1; t < g_nproc_t*T/2; t++) { tt = (t0+t)%(g_nproc_t*T); fprintf( ofs, "6 1 %d %e ", t, Cp4[tt]); @@ -232,7 +232,7 @@ void light_correlators_measurement(const int traj, const int id, const int ieo) fprintf( ofs, "%e\n", Cp4[tt]); } tt = (t0+g_nproc_t*T/2)%(g_nproc_t*T); - fprintf( ofs, "6 1 %d %e %e\n", t, Cp4[tt], 0.); + fprintf( ofs, "6 1 %d %e %e\n", t, Cp4[tt], 0.0); fclose(ofs); } #ifdef TM_USE_MPI @@ -253,38 +253,6 @@ void light_correlators_measurement(const int traj, const int id, const int ieo) return; } - -// Function to allocate memory for a pointer of pointers for an array of d dimensions -void* callocMultiDimensional(int* sizes, int numDimensions, size_t elementSize) { - - if (g_proc_id == 0){ - /* printf("sizes[0]=%d, numDimensions=%d\n", sizes[0], numDimensions); */ - } - - if (numDimensions == 1) { - //printf("Final return\n"); - return (void *)malloc(sizes[0]*elementSize); - } else { - - int totSize = 1; - for (int i = 0; i < numDimensions; i++) { - totSize *= sizes[i]; - } - - if (g_proc_id == 0){ - //printf("numDimensions=%d, totSize=%d\n", numDimensions, totSize); - } - - void ***multiArray = malloc(totSize * elementSize); - return multiArray; - /* for (int i = 0; i < sizes[0]; i++) { */ - /* multiArray[i] = callocMultiDimensional(sizes + 1, numDimensions - 1, elementSize); */ - /* } */ - - /* return multiArray; */ - } -} - /****************************************************** * * This routine computes the correlator matrix (), @@ -305,6 +273,9 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, printf("Called: %s\n", __func__); spinor phi; // dummy spinor + // dummy spinors for the heavy doublet inversion + spinor* phi1 = calloc(VOLUME/2, sizeof(spinor)); + spinor* phi2 = calloc(VOLUME/2, sizeof(spinor)); int i, j, t, tt, t0; // dummy indices float tmp; // dummy variable @@ -320,68 +291,49 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, double *sCpp = NULL, *sCpa = NULL, *sCp4 = NULL; #endif -#ifdef TM_USE_MPI - sCpp = (double *)calloc(T, sizeof(double)); - sCpa = (double *)calloc(T, sizeof(double)); - sCp4 = (double *)calloc(T, sizeof(double)); - if (g_mpi_time_rank == 0) { - Cpp = (double *)calloc(g_nproc_t * T, sizeof(double)); - Cpa = (double *)calloc(g_nproc_t * T, sizeof(double)); - Cp4 = (double *)calloc(g_nproc_t * T, sizeof(double)); - } -#else - Cpp = (double *)calloc(T, sizeof(double)); - Cpa = (double *)calloc(T, sizeof(double)); - Cp4 = (double *)calloc(T, sizeof(double)); -#endif - if (g_proc_id == 0){ - printf("Checkpoint 1 - %d\n", g_mpi_time_rank); - } - - /* heavy-light correlators variables */ + /* heavy-light correlators variables */ // sign change bilinear^\dagger, with Gamma = 1,gamma_ double eta_Gamma[2] = {1.0, -1.0}; - // the number of independent correlators is 16 = (2*2)_{h_1 h_2} * (2*2)_{Gamma_1 Gamma_2} - // hi: c,s - // Gamma = 1, gamma_5 - double* C_hihj_g1g2[2][2][2][2]; - double *sC_hihj_g1g2[2][2][2][2]; + // even-odd spinor fields for the light and heavy doublet correlators + // INDICES: source+propagator, doublet, spin dilution index, flavor projection, even-odd, + // flavor, position + // (+ Dirac, color) psi = (psi[(s,p)][db][beta][F][eo][f][x])[alpha][c] + // last 2 indices come from spinor struct + // Note: propagator in the sense that it is D^{-1}*source after the inversion + spinor* arr_eo_spinor[2][2][4][2][2][2]; + + // (no even-odd): source+propagator, doublet, spin dilution index, flavor proj, flavor + // index, position (+ Dirac, color) (psi[i_sp][d][beta][F][f][x])[alpha][c] + spinor* arr_spinor[2][2][4][2][2]; // allocating memory - for (int h1=0; h1<2; h1++){ - for (int h2=0; h2<2; h2++){ - for (int g1=0; g1<2; g1++){ - for (int g2=0; g2<2; g2++){ -#ifdef TM_USE_MPI - sC_hihj_g1g2[h1][h2][g1][g2] = (double*) calloc(T, sizeof(double)); - if (g_mpi_time_rank == 0) { - C_hihj_g1g2[h1][h2][g1][g2] = (double*) calloc(g_nproc_t*T, sizeof(double)); + for (size_t i_sp = 0; i_sp < 2; i_sp++) { // source or propagator + for (size_t db = 0; db < 2; db++) { // doublet: light or heavy + for (size_t beta = 0; beta < 4; beta++) { // spin dilution index + for (size_t F = 0; F < 2; F++) { // flavor dilution index + for (size_t i_eo = 0; i_eo < 2; i_eo++) { // even-odd index + for (size_t i_f = 0; i_f < 2; i_f++){// flavor index of the doublet + arr_eo_spinor[i_sp][db][beta][F][i_eo][i_f] = (spinor*) calloc(VOLUME/2, sizeof(spinor)); + if (i_eo == 0){ // (trick) doing it only once -> no eo index + arr_spinor[i_sp][db][beta][F][i_f] = (spinor*) calloc(VOLUME, sizeof(spinor)); + } + } } -#else - C_hihj_g1g2[h1][h2][g1][g2] = (double*) calloc(T, sizeof(double)); -#endif } } } } -/* #ifdef TM_USE_MPI */ -/* const int sizes_C_hihj_g1g2[5] = {2, 2, 2, 2, g_nproc_t*T}; */ -/* if (g_mpi_time_rank == 0) { */ -/* C_hihj_g1g2 = (double *****)callocMultiDimensional(&sizes_C_hihj_g1g2[0], 5, sizeof(double)); */ -/* } */ -/* #else */ -/* const int sizes_C_hihj_g1g2[5] = {2, 2, 2, 2, T}; */ -/* C_hihj_g1g2 = (double *****)callocMultiDimensional(&sizes_C_hihj_g1g2[0], 5, sizeof(double)); */ -/* #endif */ - + if (g_proc_id == 0){ + printf("Checkpoint 1 - %d\n", g_mpi_time_rank); + } + if (g_proc_id == 0){ - //C_hihj_g1g2[0][1][0][0][10] = 1.0; - printf("Checkpoint 2 - T=%d\n", T); + printf("Checkpoint 2\n"); } double res_hihj_g1g2[2][2][2][2]; @@ -447,10 +399,9 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, // 2) no_samples time-slice sources on random time-slices // 3) one sample on all time-slices int max_samples = measurement_list[id].all_time_slices ? 1 : measurement_list[id].no_samples; - int max_time_slices = - measurement_list[id].all_time_slices ? measurement_list[id].max_source_slice : 1; - for (int sample = 0; sample < max_samples; sample++) { - for (int ts = 0; ts < max_time_slices; ts++) { + int max_time_slices = measurement_list[id].all_time_slices ? measurement_list[id].max_source_slice : 1; + for (int sample = 0; sample < max_samples; sample++) { + for (int ts = 0; ts < max_time_slices; ts++) { // setting output filename if (max_samples == 1 && max_time_slices == 1) { snprintf(filename, TM_OMEAS_FILENAME_LENGTH, "%s%06d", "heavy_mesons.", traj); @@ -477,38 +428,46 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, optr1->kappa, optr1->mubar, optr1->epsbar); } + #ifdef TM_USE_MPI + sCpp = (double *)calloc(T, sizeof(double)); + sCpa = (double *)calloc(T, sizeof(double)); + sCp4 = (double *)calloc(T, sizeof(double)); + if (g_mpi_time_rank == 0) { + Cpp = (double *)calloc(g_nproc_t * T, sizeof(double)); + Cpa = (double *)calloc(g_nproc_t * T, sizeof(double)); + Cp4 = (double *)calloc(g_nproc_t * T, sizeof(double)); + } + #else + Cpp = (double *)calloc(T, sizeof(double)); + Cpa = (double *)calloc(T, sizeof(double)); + Cp4 = (double *)calloc(T, sizeof(double)); + #endif + + // the number of independent correlators is 16 = (2*2)_{h_1 h_2} * (2*2)_{Gamma_1 Gamma_2} + // hi: c,s + // Gamma = 1, gamma_5 + double* C_hihj_g1g2[2][2][2][2]; + double* sC_hihj_g1g2[2][2][2][2]; + + // allocating memory + for (int h1=0; h1<2; h1++){ + for (int h2=0; h2<2; h2++){ + for (int g1=0; g1<2; g1++){ + for (int g2=0; g2<2; g2++){ + #ifdef TM_USE_MPI + sC_hihj_g1g2[h1][h2][g1][g2] = (double*) calloc(T, sizeof(double)); + if (g_mpi_time_rank == 0) { + C_hihj_g1g2[h1][h2][g1][g2] = (double*) calloc(g_nproc_t*T, sizeof(double)); + } + #else + C_hihj_g1g2[h1][h2][g1][g2] = (double*) calloc(T, sizeof(double)); + #endif + } + } + } + } + - // even-odd spinor fields for the light and heavy doublet correlators - // INDICES: source+propagator, doublet, spin dilution index, flavor projection, even-odd, - // flavor, position - // (+ Dirac, color) psi = (psi[(s,p)][db][beta][F][eo][f][x])[alpha][c] - // last 2 indices come from spinor struct - // Note: propagator in the sense that it is D^{-1}*source after the inversion - // const int sizes_arr_eo_spinor[7] = {2, 2, 4, 2, 2, 2, VOLUME / 2}; - // spinor *******arr_eo_spinor = (spinor *******) callocMultiDimensional(&sizes_arr_eo_spinor[0], 7, sizeof(spinor)); - spinor* arr_eo_spinor[2][2][4][2][2][2]; - - // (no even-odd): source+propagator, doublet, spin dilution index, flavor proj, flavor - // index, position (+ Dirac, color) (psi[i_sp][d][beta][F][f][x])[alpha][c] - spinor* arr_spinor[2][2][4][2][2]; - - // allocating memory - for (size_t i_sp = 0; i_sp < 2; i_sp++) { // source or propagator - for (size_t db = 0; db < 2; db++) { // doublet: light or heavy - for (size_t beta = 0; beta < 4; beta++) { // spin dilution index - for (size_t F = 0; F < 2; F++) { // flavor dilution index - for (size_t i_eo = 0; i_eo < 2; i_eo++) { // even-odd index - for (size_t i_f = 0; i_f < 2; i_f++){// flavor index of the doublet - arr_eo_spinor[i_sp][db][beta][F][i_eo][i_f] = (spinor*) malloc((VOLUME/2)*sizeof(spinor)); - if (i_eo == 0){ // doing it only once -> no eo index - arr_spinor[i_sp][db][beta][F][i_f] = (spinor*) malloc(VOLUME*sizeof(spinor)); - } - } - } - } - } - } - } /* initalize the random sources: one source for each Dirac index beta=src_d --> spin * dilution */ @@ -517,7 +476,6 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, for (size_t beta = 0; beta < 4; beta++) { // spin dilution index for (size_t F = 0; F < 2; F++) { // flavor dilution index for (size_t i_f = 0; i_f < 2; i_f++) { // flavor index of the doublet - // light doublet eo_source_spinor_field_spin_diluted_oet_ts(arr_eo_spinor[0][db][beta][F][0][i_f], arr_eo_spinor[0][db][beta][F][1][i_f], t0, beta, sample, traj, seed_i); @@ -526,7 +484,7 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, } } - MPI_Barrier(MPI_COMM_WORLD); + //MPI_Barrier(MPI_COMM_WORLD); if (g_proc_id == 0){ printf("Checkpoint 5\n"); } @@ -539,10 +497,18 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, for (size_t i_eo = 0; i_eo < 2; i_eo++) { // even-odd // (c,s) --> [(1-i*tau_2)/sqrt(2)] * (c,s) // stored temporarely in the propagator spinors (used as dummy) - mul_one_pm_itau2_and_div_by_sqrt2( - arr_eo_spinor[1][1][beta][F][i_eo][0], arr_eo_spinor[1][1][beta][F][i_eo][1], - arr_eo_spinor[0][1][beta][F][i_eo][0], arr_eo_spinor[0][1][beta][F][i_eo][1], +1.0, - VOLUME / 2); + if (F==0){ + mul_one_pm_itau2_and_div_by_sqrt2( + arr_eo_spinor[1][1][beta][F][i_eo][0], arr_eo_spinor[1][1][beta][F][i_eo][1], + arr_eo_spinor[0][1][beta][F][i_eo][0], phi1, +1.0, + VOLUME / 2); + } + if (F==1){ + mul_one_pm_itau2_and_div_by_sqrt2( + arr_eo_spinor[1][1][beta][F][i_eo][0], arr_eo_spinor[1][1][beta][F][i_eo][1], + phi2, arr_eo_spinor[0][1][beta][F][i_eo][1], +1.0, + VOLUME / 2); + } for (size_t i_f = 0; i_f < 2; i_f++) { // assigning the result to the first components (the sources). @@ -554,7 +520,7 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, } } - MPI_Barrier(MPI_COMM_WORLD); + //MPI_Barrier(MPI_COMM_WORLD); if (g_proc_id == 0){ printf("Checkpoint 6\n"); } @@ -570,131 +536,106 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, // sources optr1->sr0 = arr_eo_spinor[0][0][beta][0][0][0]; optr1->sr1 = arr_eo_spinor[0][0][beta][0][1][0]; - MPI_Barrier(MPI_COMM_WORLD); - if (g_proc_id == 0){ - printf("Checkpoint 7\n"); - } + + MPI_Barrier(MPI_COMM_WORLD); + if (g_proc_id == 0){ + printf("Checkpoint 7\n"); + } // propagators optr1->prop0 = arr_eo_spinor[1][0][beta][0][0][0]; optr1->prop1 = arr_eo_spinor[1][0][beta][0][1][0]; - + printf("inverting the light doublet\n"); - //optr1->inverter(i1, 0, 0); // inversion for the up flavor - + optr1->inverter(i1, 0, 0); // inversion for the up flavor + // PLEASE KEEP THESE LINES COMMENTED, MAY BE USEFUL IN THE FUTURE // // inversion of the light doublet only inverts the up block (the operator is // // diagonal in flavor) down components in flavor will be empty // optr1->DownProp = 1; - + // // sources // optr1->sr0 = arr_eo_spinor[0][0][beta][0][1]; // optr1->sr1 = arr_eo_spinor[0][0][beta][1][1]; // // propagator // optr1->prop0 = arr_eo_spinor[1][0][beta][0][1]; // optr1->prop1 = arr_eo_spinor[1][0][beta][1][1]; - + // optr1->inverter(i1, 0, 0); // inversion for the down - + // optr1->DownProp = 0; // restoring to default - + /* heavy doublet */ printf("Inverting the heavy doublet\n"); for (size_t F = 0; F < 2; F++) { // flavor projection index printf("F=%d\n", F); - optr2->sr0 = arr_eo_spinor[0][1][beta][F][0][0]; - optr2->sr1 = arr_eo_spinor[0][1][beta][F][1][0]; - optr2->sr2 = arr_eo_spinor[0][1][beta][F][0][1]; - optr2->sr3 = arr_eo_spinor[0][1][beta][F][1][1]; - + + optr2->sr0 = arr_eo_spinor[0][1][beta][F][0][0]; + optr2->sr1 = arr_eo_spinor[0][1][beta][F][1][0]; + optr2->sr2 = arr_eo_spinor[0][1][beta][F][0][1]; + optr2->sr3 = arr_eo_spinor[0][1][beta][F][1][1]; + optr2->prop0 = arr_eo_spinor[1][1][beta][F][0][0]; optr2->prop1 = arr_eo_spinor[1][1][beta][F][1][0]; optr2->prop2 = arr_eo_spinor[1][1][beta][F][0][1]; optr2->prop3 = arr_eo_spinor[1][1][beta][F][1][1]; - - //optr2->inverter(i2, 0, 0); // inversion for both flavor components + + SourceInfo.no_flavours = 1; // only for the heavy + optr2->inverter(i2, 0, 0); // inversion for both flavor components + SourceInfo.no_flavours = 0; // reset to previous value } } - - MPI_Barrier(MPI_COMM_WORLD); + + //MPI_Barrier(MPI_COMM_WORLD); if (g_proc_id == 0){ printf("Checkpoint 8\n"); } - // conclude the change of basis for the heavy doublet for (size_t beta = 0; beta < 4; beta++) { // spin dilution index for (size_t F = 0; F < 2; F++) { // flavor projection index for (size_t i_eo = 0; i_eo < 2; i_eo++) { // even-odd // (c,s) --> [(1-i*tau_2)/sqrt(2)] * (c,s) - // stored temporarely in the propagator spinors (used as dummy) - mul_one_pm_itau2_and_div_by_sqrt2( - arr_eo_spinor[1][1][beta][F][i_eo][0], arr_eo_spinor[1][1][beta][F][i_eo][1], - arr_eo_spinor[0][1][beta][F][i_eo][0], arr_eo_spinor[0][1][beta][F][i_eo][1], -1.0, - VOLUME / 2); - - for (size_t i_f = 0; i_f < 2; i_f++) { - // assigning the result to the first components (the sources). - // The propagators will be overwritten with the inversion - assign(arr_eo_spinor[0][1][beta][F][i_eo][i_f], - arr_eo_spinor[1][1][beta][F][i_eo][i_f], VOLUME / 2); - } - + // stored temporarely in phi1, phi2 + mul_one_pm_itau2_and_div_by_sqrt2(phi1, phi2, + arr_eo_spinor[1][1][beta][F][i_eo][0], arr_eo_spinor[1][1][beta][F][i_eo][1], -1.0, + VOLUME / 2); + + assign(arr_eo_spinor[1][1][beta][F][i_eo][0], phi1, VOLUME / 2); + assign(arr_eo_spinor[1][1][beta][F][i_eo][1], phi2, VOLUME / 2); } } } + zero_spinor_field(phi1, VOLUME/2); + zero_spinor_field(phi2, VOLUME/2); + - MPI_Barrier(MPI_COMM_WORLD); + //MPI_Barrier(MPI_COMM_WORLD); if (g_proc_id == 0){ printf("Checkpoint 9\n"); } - - - // (no even-odd): source+propagator, doublet, spin dilution index, flavor proj, flavor - // index, position (+ Dirac, color) (psi[i_sp][d][beta][F][f][x])[alpha][c] - // last 3 indices come from the spinor struct - /* const int sizes_arr_spinor = {2, 2, 4, 2, 2, VOLUME}; */ - /* spinor ******arr_spinor = */ - /* (spinor ******)callocMultiDimensional(sizes_arr_spinor, 6, sizeof(spinor)); */ - + // now we switch from even-odd representation to standard - for (size_t i_sp = 0; i_sp < 2; i_sp++) { // source or sink - for (size_t db = 0; db < 2; db++) { // doublet: light of heavy - for (size_t F = 0; F < 2; F++) { // flavor projection index - for (size_t beta = 0; beta < 4; beta++) { // spin dilution index - for (size_t i_f = 0; i_f < 2; i_f++) { - convert_eo_to_lexic(arr_spinor[i_sp][db][F][beta][i_f], - arr_eo_spinor[i_sp][db][F][beta][0][i_f], - arr_eo_spinor[i_sp][db][F][beta][1][i_f]); + for (size_t i_sp = 0; i_sp < 2; i_sp++) { // source or sink + for (size_t db = 0; db < 2; db++) { // doublet: light of heavy + for (size_t beta = 0; beta < 4; beta++) { // spin dilution index + for (size_t F = 0; F < 2; F++) { // flavor projection index + for (size_t i_f = 0; i_f < 2; i_f++) { // flavor index + convert_eo_to_lexic(arr_spinor[i_sp][db][beta][F][i_f], + arr_eo_spinor[i_sp][db][beta][F][0][i_f], + arr_eo_spinor[i_sp][db][beta][F][1][i_f]); } } } } } - - MPI_Barrier(MPI_COMM_WORLD); + + //MPI_Barrier(MPI_COMM_WORLD); if (g_proc_id == 0){ printf("Checkpoint 10\n"); } - - // freeing up memory - for (size_t i_sp = 0; i_sp < 2; i_sp++) { // source or propagator - for (size_t db = 0; db < 2; db++) { // doublet: light or heavy - for (size_t beta = 0; beta < 4; beta++) { // spin dilution index - for (size_t F = 0; F < 2; F++) { // flavor dilution index - for (size_t i_eo = 0; i_eo < 2; i_eo++) { // even-odd index - for (size_t i_f = 0; i_f < 2; i_f++){// flavor index of the doublet - free(arr_eo_spinor[i_sp][db][beta][F][i_eo][i_f]); - } - } - } - } - } - } - - // free(arr_eo_spinor); // freeing up space: eo spinors not needed anymore - - MPI_Barrier(MPI_COMM_WORLD); + + //MPI_Barrier(MPI_COMM_WORLD); if (g_proc_id == 0){ printf("Checkpoint 11\n"); } @@ -703,11 +644,9 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, Now that I have all the propagators (all in the basis of https://arxiv.org/pdf/1005.2042.pdf) I can build the correlators of eq. (20) */ - const int f0 = 0; // flavor index of the up - /* now we sum only over local space for every t */ - for (t = 0; t < T; t++) { + for (t = 0; t < T; t++) { j = g_ipt[t][0][0][0]; // dummy variables @@ -715,6 +654,7 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, respa = 0.; resp4 = 0.; + for (i = j; i < j + LX * LY * LZ; i++) { for (size_t beta = 0; beta < 4; beta++) { // spin dilution spinor psi_u = arr_spinor[1][0][beta][f0][f0][i]; @@ -750,8 +690,9 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, } } } - } + } + double vol_fact = (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ); #if defined TM_USE_MPI MPI_Reduce(&res, &mpi_res, 1, MPI_DOUBLE, MPI_SUM, 0, g_mpi_time_slices); res = mpi_res; @@ -759,42 +700,41 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, respa = mpi_respa; MPI_Reduce(&resp4, &mpi_resp4, 1, MPI_DOUBLE, MPI_SUM, 0, g_mpi_time_slices); resp4 = mpi_resp4; - sCpp[t] = +res / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ) / 2. / - optr1->kappa / optr1->kappa; - sCpa[t] = -respa / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ) / 2. / - optr1->kappa / optr1->kappa; - sCp4[t] = +resp4 / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ) / 2. / - optr1->kappa / optr1->kappa; + sCpp[t] = +res / vol_fact / 2. / optr1->kappa / optr1->kappa; + sCpa[t] = -respa / vol_fact / 2. / optr1->kappa / optr1->kappa; + sCp4[t] = +resp4 / vol_fact / 2. / optr1->kappa / optr1->kappa; #else - Cpp[t] = +res / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ) / 2. / optr1->kappa / + Cpp[t] = +res / vol_fact / 2. / optr1->kappa / optr1->kappa; - Cpa[t] = -respa / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ) / 2. / - optr1->kappa / optr1->kappa; - Cp4[t] = +resp4 / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ) / 2. / - optr1->kappa / optr1->kappa; + Cpa[t] = -respa / vol_fact / 2. / optr1->kappa / optr1->kappa; + Cp4[t] = +resp4 / vol_fact / 2. / optr1->kappa / optr1->kappa; #endif + printf("%d: Checkpoint 11.5\n", g_proc_id); + for (size_t hi = 0; hi < 2; hi++) { for (size_t hj = 0; hj < 2; hj++) { for (size_t g1 = 0; g1 < 2; g1++) { for (size_t g2 = 0; g2 < 2; g2++) { #if defined TM_USE_MPI - MPI_Reduce(&res_hihj_g1g2[hi][hj][g1][g2], &mpi_res_hihj_g1g2[hi][hj][g1][g2], 1, - MPI_DOUBLE, MPI_SUM, 0, g_mpi_time_slices); + MPI_Reduce(&res_hihj_g1g2[hi][hj][g1][g2], &mpi_res_hihj_g1g2[hi][hj][g1][g2], 1, MPI_DOUBLE, MPI_SUM, 0, g_mpi_time_slices); res_hihj_g1g2[hi][hj][g1][g2] = mpi_res_hihj_g1g2[hi][hj][g1][g2]; - sC_hihj_g1g2[hi][hj][g1][g2][t] = - -eta_Gamma[g1] * res / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ); + sC_hihj_g1g2[hi][hj][g1][g2][t] = -eta_Gamma[g1] * res_hihj_g1g2[hi][hj][g1][g2] / vol_fact; #else - C_hihj_g1g2[hi][hj][g1][g2][t] = - -eta_Gamma[g1] * res / (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ); + C_hihj_g1g2[hi][hj][g1][g2][t] = -eta_Gamma[g1] * res_hihj_g1g2[hi][hj][g1][g2] / vol_fact; #endif } } } - } - - } // end loop over "t" + } + + } // end 1st loop over "t" + + if (g_proc_id == 0){ + printf("Checkpoint 11.6\n"); + } + #ifdef TM_USE_MPI /* some gymnastics needed in case of parallelisation */ if (g_mpi_time_rank == 0) { @@ -803,30 +743,36 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, MPI_Gather(sCpa, T, MPI_DOUBLE, Cpa, T, MPI_DOUBLE, 0, g_mpi_SV_slices); MPI_Gather(sCp4, T, MPI_DOUBLE, Cp4, T, MPI_DOUBLE, 0, g_mpi_SV_slices); + // heavy mesons for (size_t hi = 0; hi < 2; hi++) { for (size_t hj = 0; hj < 2; hj++) { for (size_t g1 = 0; g1 < 2; g1++) { for (size_t g2 = 0; g2 < 2; g2++) { - MPI_Gather(sC_hihj_g1g2[hi][hj][g1][g2], T, MPI_DOUBLE, C_hihj_g1g2[hi][hj][g1][g2], - T, MPI_DOUBLE, 0, g_mpi_SV_slices); + MPI_Gather(&sC_hihj_g1g2[hi][hj][g1][g2][0], T, MPI_DOUBLE, &C_hihj_g1g2[hi][hj][g1][g2][0], T, MPI_DOUBLE, 0, g_mpi_SV_slices); } } } } + } #endif - MPI_Barrier(MPI_COMM_WORLD); + //MPI_Barrier(MPI_COMM_WORLD); if (g_proc_id == 0){ printf("Checkpoint 12\n"); } + printf("check: %d, %d\n", g_mpi_time_rank, g_proc_coords[0]); + /* and write everything into a file */ if (g_mpi_time_rank == 0 && g_proc_coords[0] == 0) { + printf("Checkpoint 12.1 : -%s-\n", filename); ofs = fopen(filename, "w"); - fprintf(ofs, "1 1 0 %e %e\n", Cpp[t0], 0.); + printf("Checkpoint 12.2\n"); + + fprintf(ofs, "1 1 0 %e %e\n", Cpp[t0], 0.0); for (t = 1; t < g_nproc_t * T / 2; t++) { tt = (t0 + t) % (g_nproc_t * T); fprintf(ofs, "1 1 %d %e ", t, Cpp[tt]); @@ -834,9 +780,9 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, fprintf(ofs, "%e\n", Cpp[tt]); } tt = (t0 + g_nproc_t * T / 2) % (g_nproc_t * T); - fprintf(ofs, "1 1 %d %e %e\n", t, Cpp[tt], 0.); + fprintf(ofs, "1 1 %d %e %e\n", t, Cpp[tt], 0.0); - fprintf(ofs, "2 1 0 %e %e\n", Cpa[t0], 0.); + fprintf(ofs, "2 1 0 %e %e\n", Cpa[t0], 0.0); for (t = 1; t < g_nproc_t * T / 2; t++) { tt = (t0 + t) % (g_nproc_t * T); fprintf(ofs, "2 1 %d %e ", t, Cpa[tt]); @@ -844,9 +790,9 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, fprintf(ofs, "%e\n", Cpa[tt]); } tt = (t0 + g_nproc_t * T / 2) % (g_nproc_t * T); - fprintf(ofs, "2 1 %d %e %e\n", t, Cpa[tt], 0.); + fprintf(ofs, "2 1 %d %e %e\n", t, Cpa[tt], 0.0); - fprintf(ofs, "6 1 0 %e %e\n", Cp4[t0], 0.); + fprintf(ofs, "6 1 0 %e %e\n", Cp4[t0], 0.0); for (t = 1; t < g_nproc_t * T / 2; t++) { tt = (t0 + t) % (g_nproc_t * T); fprintf(ofs, "6 1 %d %e ", t, Cp4[tt]); @@ -854,25 +800,23 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, fprintf(ofs, "%e\n", Cp4[tt]); } tt = (t0 + g_nproc_t * T / 2) % (g_nproc_t * T); - fprintf(ofs, "6 1 %d %e %e\n", t, Cp4[tt], 0.); + fprintf(ofs, "6 1 %d %e %e\n", t, Cp4[tt], 0.0); + printf("Checkpoint 12.3\n"); // heavy mesons correlators for (size_t hi = 0; hi < 2; hi++) { for (size_t hj = 0; hj < 2; hj++) { for (size_t g1 = 0; g1 < 2; g1++) { for (size_t g2 = 0; g2 < 2; g2++) { - fprintf(ofs, "%u %u %u %u 0 %e %e\n", hi, hj, g1, g2, - C_hihj_g1g2[hi][hj][g1][g1][t0], 0.); + fprintf(ofs, "%u %u %u %u 0 %e %e\n", hi, hj, g1, g2, C_hihj_g1g2[hi][hj][g1][g1][t0], 0.0); for (t = 1; t < g_nproc_t * T / 2; t++) { tt = (t0 + t) % (g_nproc_t * T); - fprintf(ofs, "%u %u %u %u %d %e ", hi, hj, g1, g2, t, - C_hihj_g1g2[hi][hj][g1][g2][tt]); + fprintf(ofs, "%u %u %u %u %d %e ", hi, hj, g1, g2, t, C_hihj_g1g2[hi][hj][g1][g2][tt]); tt = (t0 + g_nproc_t * T - t) % (g_nproc_t * T); fprintf(ofs, "%e\n", C_hihj_g1g2[hi][hj][g1][g2][tt]); } tt = (t0 + g_nproc_t * T / 2) % (g_nproc_t * T); - fprintf(ofs, "%u %u %u %u %d %e %e\n", hi, hj, g1, g2, t, - C_hihj_g1g2[hi][hj][g1][g2][tt], 0.0); + fprintf(ofs, "%u %u %u %u %d %e %e\n", hi, hj, g1, g2, t, C_hihj_g1g2[hi][hj][g1][g2][tt], 0.0); } } } @@ -880,7 +824,7 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, fclose(ofs); } - MPI_Barrier(MPI_COMM_WORLD); + //MPI_Barrier(MPI_COMM_WORLD); if (g_proc_id == 0){ printf("Checkpoint 13\n"); } @@ -901,11 +845,12 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, free(Cp4); #endif - MPI_Barrier(MPI_COMM_WORLD); + //MPI_Barrier(MPI_COMM_WORLD); if (g_proc_id == 0){ printf("Checkpoint 14\n"); } + // freeing memory: heavy-light correlators for (int h1=0; h1<2; h1++){ for (int h2=0; h2<2; h2++){ @@ -924,7 +869,7 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, } } - MPI_Barrier(MPI_COMM_WORLD); + //MPI_Barrier(MPI_COMM_WORLD); if (g_proc_id == 0){ printf("Checkpoint 15\n"); } @@ -932,6 +877,27 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, } // for(max_time_slices) } // for(max_samples) + + // freeing up memory + for (size_t i_sp = 0; i_sp < 2; i_sp++) { // source or propagator + for (size_t db = 0; db < 2; db++) { // doublet: light or heavy + for (size_t beta = 0; beta < 4; beta++) { // spin dilution index + for (size_t F = 0; F < 2; F++) { // flavor dilution index + for (size_t i_eo = 0; i_eo < 2; i_eo++) { // even-odd index + for (size_t i_f = 0; i_f < 2; i_f++){// flavor index of the doublet + free(arr_eo_spinor[i_sp][db][beta][F][i_eo][i_f]); + if(i_eo == 0){ // only once: no "eo" index for arr_spinor + free(arr_spinor[i_sp][db][beta][F][i_f]); + } + } + } + } + } + } + } + + free(phi1); + free(phi2); tm_stopwatch_pop(&g_timers, 0, 1, ""); @@ -943,7 +909,7 @@ void correlators_measurement(const int traj, const int id, const int ieo) { // ??? maybe add a double check? does i1 --> light and i2 --> heavy? if (measurement_list[id].measure_heavy_mesons == 1) { - const unsigned int i1 = 0, i2 = 1; + const int i1 = 0, i2 = 1; heavy_correlators_measurement(traj, id, ieo, i1, i2); } } From e9447bea5bde25e71d33f5c15eba3f501ec760f9 Mon Sep 17 00:00:00 2001 From: simone-romiti Date: Tue, 16 Jan 2024 17:40:19 +0100 Subject: [PATCH 36/51] solved previous issue: some MPI reduction variables were not properly initialized. --- meas/correlators.c | 863 ++++++++++++++++++++++----------------------- 1 file changed, 431 insertions(+), 432 deletions(-) diff --git a/meas/correlators.c b/meas/correlators.c index 0c6ff28f8..9bfe25db5 100644 --- a/meas/correlators.c +++ b/meas/correlators.c @@ -268,31 +268,29 @@ void light_correlators_measurement(const int traj, const int id, const int ieo) * ******************************************************/ void heavy_correlators_measurement(const int traj, const int id, const int ieo, const int i1, - const int i2) { - tm_stopwatch_push(&g_timers, __func__, ""); // timer for profiling + const int i2) { + tm_stopwatch_push(&g_timers, __func__, ""); // timer for profiling printf("Called: %s\n", __func__); - spinor phi; // dummy spinor - // dummy spinors for the heavy doublet inversion - spinor* phi1 = calloc(VOLUME/2, sizeof(spinor)); - spinor* phi2 = calloc(VOLUME/2, sizeof(spinor)); - int i, j, t, tt, t0; // dummy indices - float tmp; // dummy variable - - /* light-light correlators: dummy variables */ - - // array of the values of the correlator C(t) - double *Cpp = NULL, *Cpa = NULL, *Cp4 = NULL; - // result of the accumulation of MPI partial sums - double res = 0., respa = 0., resp4 = 0.; + spinor phi; // dummy spinor + // dummy spinors for the heavy doublet inversion + spinor* phi1 = calloc(VOLUME/2, sizeof(spinor)); + spinor* phi2 = calloc(VOLUME/2, sizeof(spinor)); + int i, j, t, tt, t0; // dummy indices + float tmp; // dummy variable + + /* light-light correlators: dummy variables */ + + // array of the values of the correlator C(t) + double *Cpp = NULL, *Cpa = NULL, *Cp4 = NULL; + // result of the accumulation of MPI partial sums + double res = 0., respa = 0., resp4 = 0.; #ifdef TM_USE_MPI - double mpi_res = 0., mpi_respa = 0., mpi_resp4 = 0.; - // send buffer for MPI_Gather - double *sCpp = NULL, *sCpa = NULL, *sCp4 = NULL; + double mpi_res = 0., mpi_respa = 0., mpi_resp4 = 0.; + // send buffer for MPI_Gather + double *sCpp = NULL, *sCpa = NULL, *sCp4 = NULL; #endif - - - + /* heavy-light correlators variables */ // sign change bilinear^\dagger, with Gamma = 1,gamma_ double eta_Gamma[2] = {1.0, -1.0}; @@ -317,8 +315,11 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, for (size_t i_eo = 0; i_eo < 2; i_eo++) { // even-odd index for (size_t i_f = 0; i_f < 2; i_f++){// flavor index of the doublet arr_eo_spinor[i_sp][db][beta][F][i_eo][i_f] = (spinor*) calloc(VOLUME/2, sizeof(spinor)); + zero_spinor_field(arr_eo_spinor[i_sp][db][beta][F][i_eo][i_f], VOLUME/2); + if (i_eo == 0){ // (trick) doing it only once -> no eo index arr_spinor[i_sp][db][beta][F][i_f] = (spinor*) calloc(VOLUME, sizeof(spinor)); + zero_spinor_field(arr_spinor[i_sp][db][beta][F][i_f], VOLUME); } } } @@ -328,307 +329,306 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, } if (g_proc_id == 0){ - printf("Checkpoint 1 - %d\n", g_mpi_time_rank); + printf("Checkpoint 1\n"); } - if (g_proc_id == 0){ printf("Checkpoint 2\n"); } - - double res_hihj_g1g2[2][2][2][2]; - double mpi_res_hihj_g1g2[2][2][2][2]; - + + double res_hihj_g1g2[2][2][2][2]; + double mpi_res_hihj_g1g2[2][2][2][2]; + if (g_proc_id == 0){ printf("Checkpoint 3\n"); } - - - FILE *ofs; // output file stream - char filename[TM_OMEAS_FILENAME_LENGTH]; // file path - - /* building the stochastic propagator spinors needed for the correlators */ - + + FILE *ofs; // output file stream + char filename[TM_OMEAS_FILENAME_LENGTH]; // file path + + /* building the stochastic propagator spinors needed for the correlators */ + // MPI_Barrier(MPI_COMM_WORLD); - init_operators(); // initialize operators (if not already done) + init_operators(); // initialize operators (if not already done) if (g_proc_id == 0){ printf("Checkpoint 4\n"); } if (no_operators < 1) { - if (g_proc_id == 0) { - // we don't want the simulation to stop, we can do the measurements offline afterwards - fprintf(stderr, - "Warning! no operators defined in input file, cannot perform online correlator " - "mesurements!\n"); - } - tm_stopwatch_pop(&g_timers, 0, 0, ""); // timer for profiling - return; - } - - // selecting the operators i1 and i2 from the list of operators initialized before - operator* optr1 = & operator_list[i1]; // light doublet - operator* optr2 = & operator_list[i2]; // heavy c,s doublet + if (g_proc_id == 0) { + // we don't want the simulation to stop, we can do the measurements offline afterwards + fprintf(stderr, + "Warning! no operators defined in input file, cannot perform online correlator " + "mesurements!\n"); + } + tm_stopwatch_pop(&g_timers, 0, 0, ""); // timer for profiling + return; + } + + // selecting the operators i1 and i2 from the list of operators initialized before + operator* optr1 = & operator_list[i1]; // light doublet + operator* optr2 = & operator_list[i2]; // heavy c,s doublet printf("Initialized the operators\n"); - bool b1 = (optr1->type != TMWILSON && optr1->type != WILSON && optr1->type != CLOVER); - bool b2 = (optr2->type != DBTMWILSON && optr2->type != DBCLOVER); - if (b1 || b2) { - if (g_proc_id == 0) { - if (b1) { - fprintf(stderr, - "Warning! optr1 should be one of the following: TMWILSON, WILSON and CLOVER\n"); - fprintf(stderr, "Cannot perform correlator online measurement!\n"); - } - if (b2) { - fprintf(stderr, "Warning! optr2 should be one of the following: DBTMWILSON, DBCLOVER\n"); - } - fprintf(stderr, "Cannot perform correlator online measurement!\n"); - } - tm_stopwatch_pop(&g_timers, 0, 0, ""); // timer for profiling - return; - } + bool b1 = (optr1->type != TMWILSON && optr1->type != WILSON && optr1->type != CLOVER); + bool b2 = (optr2->type != DBTMWILSON && optr2->type != DBCLOVER); + if (b1 || b2) { + if (g_proc_id == 0) { + if (b1) { + fprintf(stderr, + "Warning! optr1 should be one of the following: TMWILSON, WILSON and CLOVER\n"); + fprintf(stderr, "Cannot perform correlator online measurement!\n"); + } + if (b2) { + fprintf(stderr, "Warning! optr2 should be one of the following: DBTMWILSON, DBCLOVER\n"); + } + fprintf(stderr, "Cannot perform correlator online measurement!\n"); + } + tm_stopwatch_pop(&g_timers, 0, 0, ""); // timer for profiling + return; + } - if (ranlxs_init == 0) { - rlxs_init(1, 123456); // initializing random number generator RANLUX - } + if (ranlxs_init == 0) { + rlxs_init(1, 123456); // initializing random number generator RANLUX + } - // there are three modes of operation - // 1) one single time-slice source (default) - // 2) no_samples time-slice sources on random time-slices - // 3) one sample on all time-slices - int max_samples = measurement_list[id].all_time_slices ? 1 : measurement_list[id].no_samples; - int max_time_slices = measurement_list[id].all_time_slices ? measurement_list[id].max_source_slice : 1; + // there are three modes of operation + // 1) one single time-slice source (default) + // 2) no_samples time-slice sources on random time-slices + // 3) one sample on all time-slices + int max_samples = measurement_list[id].all_time_slices ? 1 : measurement_list[id].no_samples; + int max_time_slices = measurement_list[id].all_time_slices ? measurement_list[id].max_source_slice : 1; for (int sample = 0; sample < max_samples; sample++) { for (int ts = 0; ts < max_time_slices; ts++) { - // setting output filename - if (max_samples == 1 && max_time_slices == 1) { - snprintf(filename, TM_OMEAS_FILENAME_LENGTH, "%s%06d", "heavy_mesons.", traj); - } else if (max_samples == 1 && max_time_slices > 1) { - snprintf(filename, TM_OMEAS_FILENAME_LENGTH, "%s.t%03d.%06d", "heavy_mesons", ts, traj); - } else { - snprintf(filename, TM_OMEAS_FILENAME_LENGTH, "%s.s%03d.%06d", "heavy_mesons", sample, traj); - } - - /* generate random timeslice */ - t0 = ts; - if (!measurement_list[id].all_time_slices) { - ranlxs(&tmp, 1); - t0 = (int)(measurement_list[id].max_source_slice * tmp); - } + // setting output filename + if (max_samples == 1 && max_time_slices == 1) { + snprintf(filename, TM_OMEAS_FILENAME_LENGTH, "%s%06d", "heavy_mesons.", traj); + } else if (max_samples == 1 && max_time_slices > 1) { + snprintf(filename, TM_OMEAS_FILENAME_LENGTH, "%s.t%03d.%06d", "heavy_mesons", ts, traj); + } else { + snprintf(filename, TM_OMEAS_FILENAME_LENGTH, "%s.s%03d.%06d", "heavy_mesons", sample, traj); + } + + /* generate random timeslice */ + t0 = ts; + if (!measurement_list[id].all_time_slices) { + ranlxs(&tmp, 1); + t0 = (int)(measurement_list[id].max_source_slice * tmp); + } #ifdef TM_USE_MPI - MPI_Bcast(&t0, 1, MPI_INT, 0, MPI_COMM_WORLD); // broadcast t0 to all the ranks + MPI_Bcast(&t0, 1, MPI_INT, 0, MPI_COMM_WORLD); // broadcast t0 to all the ranks +#endif + if (g_debug_level > 1 && g_proc_id == 0) { + printf("# timeslice set to %d (T=%d) for online measurement\n", t0, g_nproc_t * T); + printf("# online measurements parameters: kappa = %.12f, mubar = %.12f, epsbar = %.12f\n", + optr1->kappa, optr1->mubar, optr1->epsbar); + } + +#ifdef TM_USE_MPI + sCpp = (double *)calloc(T, sizeof(double)); + sCpa = (double *)calloc(T, sizeof(double)); + sCp4 = (double *)calloc(T, sizeof(double)); + if (g_mpi_time_rank == 0) { + Cpp = (double *)calloc(g_nproc_t * T, sizeof(double)); + Cpa = (double *)calloc(g_nproc_t * T, sizeof(double)); + Cp4 = (double *)calloc(g_nproc_t * T, sizeof(double)); + } +#else + Cpp = (double *)calloc(T, sizeof(double)); + Cpa = (double *)calloc(T, sizeof(double)); + Cp4 = (double *)calloc(T, sizeof(double)); #endif - if (g_debug_level > 1 && g_proc_id == 0) { - printf("# timeslice set to %d (T=%d) for online measurement\n", t0, g_nproc_t * T); - printf( - "# online measurements parameters: kappa = %.12f, mubar = %.12f, epsbar = " - "%.12f\n", - optr1->kappa, optr1->mubar, optr1->epsbar); - } - - #ifdef TM_USE_MPI - sCpp = (double *)calloc(T, sizeof(double)); - sCpa = (double *)calloc(T, sizeof(double)); - sCp4 = (double *)calloc(T, sizeof(double)); - if (g_mpi_time_rank == 0) { - Cpp = (double *)calloc(g_nproc_t * T, sizeof(double)); - Cpa = (double *)calloc(g_nproc_t * T, sizeof(double)); - Cp4 = (double *)calloc(g_nproc_t * T, sizeof(double)); - } - #else - Cpp = (double *)calloc(T, sizeof(double)); - Cpa = (double *)calloc(T, sizeof(double)); - Cp4 = (double *)calloc(T, sizeof(double)); - #endif - - // the number of independent correlators is 16 = (2*2)_{h_1 h_2} * (2*2)_{Gamma_1 Gamma_2} - // hi: c,s - // Gamma = 1, gamma_5 - double* C_hihj_g1g2[2][2][2][2]; - double* sC_hihj_g1g2[2][2][2][2]; - - // allocating memory - for (int h1=0; h1<2; h1++){ - for (int h2=0; h2<2; h2++){ - for (int g1=0; g1<2; g1++){ - for (int g2=0; g2<2; g2++){ - #ifdef TM_USE_MPI - sC_hihj_g1g2[h1][h2][g1][g2] = (double*) calloc(T, sizeof(double)); - if (g_mpi_time_rank == 0) { - C_hihj_g1g2[h1][h2][g1][g2] = (double*) calloc(g_nproc_t*T, sizeof(double)); - } - #else - C_hihj_g1g2[h1][h2][g1][g2] = (double*) calloc(T, sizeof(double)); - #endif - } - } - } - } - - - - /* initalize the random sources: one source for each Dirac index beta=src_d --> spin - * dilution */ - const unsigned int seed_i = measurement_list[id].seed; // has to be same seed - for (size_t db = 0; db < 2; db++) { // doublet: light or heavy - for (size_t beta = 0; beta < 4; beta++) { // spin dilution index - for (size_t F = 0; F < 2; F++) { // flavor dilution index - for (size_t i_f = 0; i_f < 2; i_f++) { // flavor index of the doublet - eo_source_spinor_field_spin_diluted_oet_ts(arr_eo_spinor[0][db][beta][F][0][i_f], - arr_eo_spinor[0][db][beta][F][1][i_f], t0, - beta, sample, traj, seed_i); - } - } - } - } + // the number of independent correlators is 16 = (2*2)_{h_1 h_2} * (2*2)_{Gamma_1 Gamma_2} + // hi: c,s + // Gamma = 1, gamma_5 + double* C_hihj_g1g2[2][2][2][2]; + double* sC_hihj_g1g2[2][2][2][2]; + + // allocating memory + for (int h1=0; h1<2; h1++){ + for (int h2=0; h2<2; h2++){ + for (int g1=0; g1<2; g1++){ + for (int g2=0; g2<2; g2++){ +#ifdef TM_USE_MPI + mpi_res_hihj_g1g2[h1][h2][g1][g2] = 0.0; + res_hihj_g1g2[h1][h2][g1][g2] = 0.0; + sC_hihj_g1g2[h1][h2][g1][g2] = (double*) calloc(T, sizeof(double)); + if (g_mpi_time_rank == 0) { + C_hihj_g1g2[h1][h2][g1][g2] = (double*) calloc(g_nproc_t*T, sizeof(double)); + } +#else + res_hihj_g1g2[h1][h2][g1][g2] = 0.0; + C_hihj_g1g2[h1][h2][g1][g2] = (double*) calloc(T, sizeof(double)); +#endif + } + } + } + } + + /* init random sources: one for each Dirac index beta --> spin dilution */ + const unsigned int seed_i = measurement_list[id].seed; // has to be same seed + for (size_t db = 0; db < 2; db++) { // doublet: light or heavy + for (size_t beta = 0; beta < 4; beta++) { // spin dilution index + for (size_t F = 0; F < 2; F++) { // flavor dilution index + for (size_t i_f = 0; i_f < 2; i_f++) { // flavor index of the doublet + eo_source_spinor_field_spin_diluted_oet_ts(arr_eo_spinor[0][db][beta][F][0][i_f], + arr_eo_spinor[0][db][beta][F][1][i_f], t0, + beta, sample, traj, seed_i); + } + } + } + } + zero_spinor_field(phi1, VOLUME/2); + zero_spinor_field(phi2, VOLUME/2); + //MPI_Barrier(MPI_COMM_WORLD); if (g_proc_id == 0){ printf("Checkpoint 5\n"); } - - // heavy doublet: for each even-odd block, I multiply by (1 + i*tau_2)/sqrt(2) - // the basis for the inversion should be the same as for the light - // --> I will multiply later by the inverse, namely at the end of the inversion - for (size_t beta = 0; beta < 4; beta++) { // spin dilution index - for (size_t F = 0; F < 2; F++) { // flavor projection index - for (size_t i_eo = 0; i_eo < 2; i_eo++) { // even-odd - // (c,s) --> [(1-i*tau_2)/sqrt(2)] * (c,s) - // stored temporarely in the propagator spinors (used as dummy) - if (F==0){ - mul_one_pm_itau2_and_div_by_sqrt2( - arr_eo_spinor[1][1][beta][F][i_eo][0], arr_eo_spinor[1][1][beta][F][i_eo][1], - arr_eo_spinor[0][1][beta][F][i_eo][0], phi1, +1.0, - VOLUME / 2); - } - if (F==1){ - mul_one_pm_itau2_and_div_by_sqrt2( - arr_eo_spinor[1][1][beta][F][i_eo][0], arr_eo_spinor[1][1][beta][F][i_eo][1], - phi2, arr_eo_spinor[0][1][beta][F][i_eo][1], +1.0, - VOLUME / 2); - } - - for (size_t i_f = 0; i_f < 2; i_f++) { - // assigning the result to the first components (the sources). - // The propagators will be overwritten with the inversion - assign(arr_eo_spinor[0][1][beta][F][i_eo][i_f], - arr_eo_spinor[1][1][beta][F][i_eo][i_f], VOLUME / 2); - } - } - } - } + + // heavy doublet: for each even-odd block, I multiply by (1 + i*tau_2)/sqrt(2) + // the basis for the inversion should be the same as for the light + // --> I will multiply later by the inverse, namely at the end of the inversion + for (size_t beta = 0; beta < 4; beta++) { // spin dilution index + for (size_t F = 0; F < 2; F++) { // flavor projection index + for (size_t i_eo = 0; i_eo < 2; i_eo++) { // even-odd + // (c,s) --> [(1-i*tau_2)/sqrt(2)] * (c,s) + // stored temporarely in the propagator spinors (used as dummy) + if (F==0){ + mul_one_pm_itau2_and_div_by_sqrt2( + arr_eo_spinor[1][1][beta][F][i_eo][0], arr_eo_spinor[1][1][beta][F][i_eo][1], + arr_eo_spinor[0][1][beta][F][i_eo][0], phi1, +1.0, + VOLUME / 2); + } + if (F==1){ + mul_one_pm_itau2_and_div_by_sqrt2( + arr_eo_spinor[1][1][beta][F][i_eo][0], arr_eo_spinor[1][1][beta][F][i_eo][1], + phi2, arr_eo_spinor[0][1][beta][F][i_eo][1], +1.0, + VOLUME / 2); + } + + for (size_t i_f = 0; i_f < 2; i_f++) { + // assigning the result to the first components (the sources). + // The propagators will be overwritten with the inversion + assign(arr_eo_spinor[0][1][beta][F][i_eo][i_f], + arr_eo_spinor[1][1][beta][F][i_eo][i_f], VOLUME / 2); + zero_spinor_field(arr_eo_spinor[1][1][beta][F][i_eo][i_f], VOLUME / 2); + } + } + } + } //MPI_Barrier(MPI_COMM_WORLD); if (g_proc_id == 0){ printf("Checkpoint 6\n"); } - /* - assign the sources and propagator pointes for the operators - these need to be know when calling the inverter() method */ - for (size_t beta = 0; beta < 4; beta++) { // spin dilution index - /* light doublet */ - - // up - - // sources - optr1->sr0 = arr_eo_spinor[0][0][beta][0][0][0]; - optr1->sr1 = arr_eo_spinor[0][0][beta][0][1][0]; - + /* + assign the sources and propagator pointes for the operators + these need to be know when calling the inverter() method */ + for (size_t beta = 0; beta < 4; beta++) { // spin dilution index + /* light doublet */ + + // up + + // sources + optr1->sr0 = arr_eo_spinor[0][0][beta][0][0][0]; + optr1->sr1 = arr_eo_spinor[0][0][beta][0][1][0]; + MPI_Barrier(MPI_COMM_WORLD); if (g_proc_id == 0){ printf("Checkpoint 7\n"); } - - // propagators - optr1->prop0 = arr_eo_spinor[1][0][beta][0][0][0]; - optr1->prop1 = arr_eo_spinor[1][0][beta][0][1][0]; + + // propagators + optr1->prop0 = arr_eo_spinor[1][0][beta][0][0][0]; + optr1->prop1 = arr_eo_spinor[1][0][beta][0][1][0]; printf("inverting the light doublet\n"); - optr1->inverter(i1, 0, 0); // inversion for the up flavor + optr1->inverter(i1, 0, 0); // inversion for the up flavor - // PLEASE KEEP THESE LINES COMMENTED, MAY BE USEFUL IN THE FUTURE - // // inversion of the light doublet only inverts the up block (the operator is - // // diagonal in flavor) down components in flavor will be empty - // optr1->DownProp = 1; + // PLEASE KEEP THESE LINES COMMENTED, MAY BE USEFUL IN THE FUTURE + // // inversion of the light doublet only inverts the up block (the operator is + // // diagonal in flavor) down components in flavor will be empty + // optr1->DownProp = 1; - // // sources - // optr1->sr0 = arr_eo_spinor[0][0][beta][0][1]; - // optr1->sr1 = arr_eo_spinor[0][0][beta][1][1]; - // // propagator - // optr1->prop0 = arr_eo_spinor[1][0][beta][0][1]; - // optr1->prop1 = arr_eo_spinor[1][0][beta][1][1]; + // // sources + // optr1->sr0 = arr_eo_spinor[0][0][beta][0][1]; + // optr1->sr1 = arr_eo_spinor[0][0][beta][1][1]; + // // propagator + // optr1->prop0 = arr_eo_spinor[1][0][beta][0][1]; + // optr1->prop1 = arr_eo_spinor[1][0][beta][1][1]; - // optr1->inverter(i1, 0, 0); // inversion for the down + // optr1->inverter(i1, 0, 0); // inversion for the down - // optr1->DownProp = 0; // restoring to default + // optr1->DownProp = 0; // restoring to default - /* heavy doublet */ + /* heavy doublet */ printf("Inverting the heavy doublet\n"); - for (size_t F = 0; F < 2; F++) { // flavor projection index + for (size_t F = 0; F < 2; F++) { // flavor projection index printf("F=%d\n", F); - - optr2->sr0 = arr_eo_spinor[0][1][beta][F][0][0]; - optr2->sr1 = arr_eo_spinor[0][1][beta][F][1][0]; - optr2->sr2 = arr_eo_spinor[0][1][beta][F][0][1]; - optr2->sr3 = arr_eo_spinor[0][1][beta][F][1][1]; - + + optr2->sr0 = arr_eo_spinor[0][1][beta][F][0][0]; + optr2->sr1 = arr_eo_spinor[0][1][beta][F][1][0]; + optr2->sr2 = arr_eo_spinor[0][1][beta][F][0][1]; + optr2->sr3 = arr_eo_spinor[0][1][beta][F][1][1]; + optr2->prop0 = arr_eo_spinor[1][1][beta][F][0][0]; optr2->prop1 = arr_eo_spinor[1][1][beta][F][1][0]; optr2->prop2 = arr_eo_spinor[1][1][beta][F][0][1]; optr2->prop3 = arr_eo_spinor[1][1][beta][F][1][1]; - SourceInfo.no_flavours = 1; // only for the heavy + SourceInfo.no_flavours = 1; // only for the heavy optr2->inverter(i2, 0, 0); // inversion for both flavor components - SourceInfo.no_flavours = 0; // reset to previous value + SourceInfo.no_flavours = 0; // reset to previous value } - } + } //MPI_Barrier(MPI_COMM_WORLD); if (g_proc_id == 0){ printf("Checkpoint 8\n"); } - // conclude the change of basis for the heavy doublet - for (size_t beta = 0; beta < 4; beta++) { // spin dilution index - for (size_t F = 0; F < 2; F++) { // flavor projection index - for (size_t i_eo = 0; i_eo < 2; i_eo++) { // even-odd - // (c,s) --> [(1-i*tau_2)/sqrt(2)] * (c,s) - // stored temporarely in phi1, phi2 - mul_one_pm_itau2_and_div_by_sqrt2(phi1, phi2, + // conclude the change of basis for the heavy doublet + for (size_t beta = 0; beta < 4; beta++) { // spin dilution index + for (size_t F = 0; F < 2; F++) { // flavor projection index + for (size_t i_eo = 0; i_eo < 2; i_eo++) { // even-odd + // (c,s) --> [(1-i*tau_2)/sqrt(2)] * (c,s) + // stored temporarely in phi1, phi2 + mul_one_pm_itau2_and_div_by_sqrt2(phi1, phi2, arr_eo_spinor[1][1][beta][F][i_eo][0], arr_eo_spinor[1][1][beta][F][i_eo][1], -1.0, VOLUME / 2); - assign(arr_eo_spinor[1][1][beta][F][i_eo][0], phi1, VOLUME / 2); - assign(arr_eo_spinor[1][1][beta][F][i_eo][1], phi2, VOLUME / 2); - } - } - } - zero_spinor_field(phi1, VOLUME/2); - zero_spinor_field(phi2, VOLUME/2); - - + assign(arr_eo_spinor[1][1][beta][F][i_eo][0], phi1, VOLUME / 2); + assign(arr_eo_spinor[1][1][beta][F][i_eo][1], phi2, VOLUME / 2); + } + } + } + // reset to zero the dummy spinors + zero_spinor_field(phi1, VOLUME/2); + zero_spinor_field(phi2, VOLUME/2); + //MPI_Barrier(MPI_COMM_WORLD); if (g_proc_id == 0){ printf("Checkpoint 9\n"); } - // now we switch from even-odd representation to standard - for (size_t i_sp = 0; i_sp < 2; i_sp++) { // source or sink - for (size_t db = 0; db < 2; db++) { // doublet: light of heavy - for (size_t beta = 0; beta < 4; beta++) { // spin dilution index - for (size_t F = 0; F < 2; F++) { // flavor projection index - for (size_t i_f = 0; i_f < 2; i_f++) { // flavor index - convert_eo_to_lexic(arr_spinor[i_sp][db][beta][F][i_f], - arr_eo_spinor[i_sp][db][beta][F][0][i_f], - arr_eo_spinor[i_sp][db][beta][F][1][i_f]); - } - } - } - } - } + // now we switch from even-odd representation to standard + //for (size_t i_sp = 0; i_sp < 2; i_sp++) { // source or sink + for (size_t db = 0; db < 2; db++) { // doublet: light of heavy + for (size_t beta = 0; beta < 4; beta++) { // spin dilution index + for (size_t F = 0; F < 2; F++) { // flavor projection index + for (size_t i_f = 0; i_f < 2; i_f++) { // flavor index + convert_eo_to_lexic(arr_spinor[1][db][beta][F][i_f], + arr_eo_spinor[1][db][beta][F][0][i_f], + arr_eo_spinor[1][db][beta][F][1][i_f]); + } + } + } + } + // } //MPI_Barrier(MPI_COMM_WORLD); if (g_proc_id == 0){ @@ -640,92 +640,93 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, printf("Checkpoint 11\n"); } - /* - Now that I have all the propagators (all in the basis of - https://arxiv.org/pdf/1005.2042.pdf) I can build the correlators of eq. (20) - */ - const int f0 = 0; // flavor index of the up - /* now we sum only over local space for every t */ - for (t = 0; t < T; t++) { - j = g_ipt[t][0][0][0]; + /* + Now that I have all the propagators (all in the basis of + https://arxiv.org/pdf/1005.2042.pdf) I can build the correlators of eq. (20) + */ + const int f0 = 0; // flavor index of the up + /* now we sum only over local space for every t */ - // dummy variables - res = 0.; - respa = 0.; - resp4 = 0.; + for (t = 0; t < T; t++) { + j = g_ipt[t][0][0][0]; + // dummy variables + res = 0.0; + respa = 0.0; + resp4 = 0.0; - for (i = j; i < j + LX * LY * LZ; i++) { - for (size_t beta = 0; beta < 4; beta++) { // spin dilution - spinor psi_u = arr_spinor[1][0][beta][f0][f0][i]; - - res += _spinor_prod_re(psi_u, psi_u); - _gamma0(phi, psi_u); - respa += _spinor_prod_re(psi_u, phi); - _gamma5(phi, phi); - resp4 += _spinor_prod_im(psi_u, phi); - - for (size_t F = 0; F < 2; F++) { // flavor projection - for (size_t hi = 0; hi < 2; hi++) { - for (size_t hj = 0; hj < 2; hj++) { - for (size_t g1 = 0; g1 < 2; g1++) { - for (size_t g2 = 0; g2 < 2; g2++) { - double dum = 0.0; // dummy variable - - // heavy doublet spinor propagator - phi = arr_spinor[1][1][beta][hj][hi][i]; - if (g1 == 0) { // Gamma_1 = \mathbb{1} - _gamma5(phi, phi); - } - _spinor_scalar_prod(dum, psi_u, phi); - - double sign_beta = +1; - if (g2 == 0 /* Gamma_2 == \mathbb{1} */ && beta > 2) { - sign_beta = -1; - } - res_hihj_g1g2[hi][hj][g1][g2] += sign_beta * dum; - } - } - } - } - } - } + + for (i = j; i < j + LX * LY * LZ; i++) { + for (size_t beta = 0; beta < 4; beta++) { // spin dilution + spinor psi_u = arr_spinor[1][0][beta][f0][f0][i]; + + res += _spinor_prod_re(psi_u, psi_u); + _gamma0(phi, psi_u); + respa += _spinor_prod_re(psi_u, phi); + _gamma5(phi, phi); + resp4 += _spinor_prod_im(psi_u, phi); + + for (size_t hi = 0; hi < 2; hi++) { + for (size_t hj = 0; hj < 2; hj++) { + for (size_t g1 = 0; g1 < 2; g1++) { + for (size_t g2 = 0; g2 < 2; g2++) { + double dum = 0.0; // dummy variable + + // heavy doublet spinor propagator + phi = arr_spinor[1][1][beta][hj][hi][i]; + if (g1 == 0) { // Gamma_1 = \mathbb{1} + _gamma5(phi, phi); + } + _spinor_scalar_prod(dum, psi_u, phi); + + double sign_beta = +1.0; + if (g2 == 0 /* Gamma_2 == \mathbb{1} */ && beta >= 2) { + sign_beta = -1.0; + } + res_hihj_g1g2[hi][hj][g1][g2] += sign_beta * dum; + } + } + } + } + + } } - - double vol_fact = (g_nproc_x * LX) / (g_nproc_y * LY) / (g_nproc_z * LZ); + + const double vol_fact = (g_nproc_x * LX) * (g_nproc_y * LY) * (g_nproc_z * LZ); #if defined TM_USE_MPI - MPI_Reduce(&res, &mpi_res, 1, MPI_DOUBLE, MPI_SUM, 0, g_mpi_time_slices); - res = mpi_res; - MPI_Reduce(&respa, &mpi_respa, 1, MPI_DOUBLE, MPI_SUM, 0, g_mpi_time_slices); - respa = mpi_respa; - MPI_Reduce(&resp4, &mpi_resp4, 1, MPI_DOUBLE, MPI_SUM, 0, g_mpi_time_slices); - resp4 = mpi_resp4; - sCpp[t] = +res / vol_fact / 2. / optr1->kappa / optr1->kappa; - sCpa[t] = -respa / vol_fact / 2. / optr1->kappa / optr1->kappa; - sCp4[t] = +resp4 / vol_fact / 2. / optr1->kappa / optr1->kappa; + MPI_Reduce(&res, &mpi_res, 1, MPI_DOUBLE, MPI_SUM, 0, g_mpi_time_slices); + res = mpi_res; + MPI_Reduce(&respa, &mpi_respa, 1, MPI_DOUBLE, MPI_SUM, 0, g_mpi_time_slices); + respa = mpi_respa; + MPI_Reduce(&resp4, &mpi_resp4, 1, MPI_DOUBLE, MPI_SUM, 0, g_mpi_time_slices); + resp4 = mpi_resp4; + + sCpp[t] = +res / vol_fact / 2.0 / optr1->kappa / optr1->kappa; + sCpa[t] = -respa / vol_fact / 2.0 / optr1->kappa / optr1->kappa; + sCp4[t] = +resp4 / vol_fact / 2.0 / optr1->kappa / optr1->kappa; #else - Cpp[t] = +res / vol_fact / 2. / optr1->kappa / - optr1->kappa; - Cpa[t] = -respa / vol_fact / 2. / optr1->kappa / optr1->kappa; - Cp4[t] = +resp4 / vol_fact / 2. / optr1->kappa / optr1->kappa; + Cpp[t] = +res / vol_fact / 2.0 / optr1->kappa / optr1->kappa; + Cpa[t] = -respa / vol_fact / 2.0 / optr1->kappa / optr1->kappa; + Cp4[t] = +resp4 / vol_fact / 2.0 / optr1->kappa / optr1->kappa; #endif - + printf("%d: Checkpoint 11.5\n", g_proc_id); - - for (size_t hi = 0; hi < 2; hi++) { - for (size_t hj = 0; hj < 2; hj++) { - for (size_t g1 = 0; g1 < 2; g1++) { - for (size_t g2 = 0; g2 < 2; g2++) { + + for (size_t hi = 0; hi < 2; hi++) { + for (size_t hj = 0; hj < 2; hj++) { + for (size_t g1 = 0; g1 < 2; g1++) { + for (size_t g2 = 0; g2 < 2; g2++) { #if defined TM_USE_MPI - MPI_Reduce(&res_hihj_g1g2[hi][hj][g1][g2], &mpi_res_hihj_g1g2[hi][hj][g1][g2], 1, MPI_DOUBLE, MPI_SUM, 0, g_mpi_time_slices); - res_hihj_g1g2[hi][hj][g1][g2] = mpi_res_hihj_g1g2[hi][hj][g1][g2]; - sC_hihj_g1g2[hi][hj][g1][g2][t] = -eta_Gamma[g1] * res_hihj_g1g2[hi][hj][g1][g2] / vol_fact; + MPI_Reduce(&res_hihj_g1g2[hi][hj][g1][g2], &mpi_res_hihj_g1g2[hi][hj][g1][g2], 1, MPI_DOUBLE, MPI_SUM, 0, g_mpi_time_slices); + res_hihj_g1g2[hi][hj][g1][g2] = mpi_res_hihj_g1g2[hi][hj][g1][g2]; + + sC_hihj_g1g2[hi][hj][g1][g2][t] = - eta_Gamma[g1] * res_hihj_g1g2[hi][hj][g1][g2] / vol_fact; #else - C_hihj_g1g2[hi][hj][g1][g2][t] = -eta_Gamma[g1] * res_hihj_g1g2[hi][hj][g1][g2] / vol_fact; + C_hihj_g1g2[hi][hj][g1][g2][t] = - eta_Gamma[g1] * res_hihj_g1g2[hi][hj][g1][g2] / vol_fact; #endif - } - } - } + } + } + } } } // end 1st loop over "t" @@ -736,115 +737,114 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, } #ifdef TM_USE_MPI - /* some gymnastics needed in case of parallelisation */ - if (g_mpi_time_rank == 0) { - // light correlators - MPI_Gather(sCpp, T, MPI_DOUBLE, Cpp, T, MPI_DOUBLE, 0, g_mpi_SV_slices); - MPI_Gather(sCpa, T, MPI_DOUBLE, Cpa, T, MPI_DOUBLE, 0, g_mpi_SV_slices); - MPI_Gather(sCp4, T, MPI_DOUBLE, Cp4, T, MPI_DOUBLE, 0, g_mpi_SV_slices); - - - // heavy mesons - for (size_t hi = 0; hi < 2; hi++) { - for (size_t hj = 0; hj < 2; hj++) { - for (size_t g1 = 0; g1 < 2; g1++) { - for (size_t g2 = 0; g2 < 2; g2++) { - MPI_Gather(&sC_hihj_g1g2[hi][hj][g1][g2][0], T, MPI_DOUBLE, &C_hihj_g1g2[hi][hj][g1][g2][0], T, MPI_DOUBLE, 0, g_mpi_SV_slices); - } - } - } - } - + /* some gymnastics needed in case of parallelisation */ + if (g_mpi_time_rank == 0) { + // light correlators + MPI_Gather(sCpp, T, MPI_DOUBLE, Cpp, T, MPI_DOUBLE, 0, g_mpi_SV_slices); + MPI_Gather(sCpa, T, MPI_DOUBLE, Cpa, T, MPI_DOUBLE, 0, g_mpi_SV_slices); + MPI_Gather(sCp4, T, MPI_DOUBLE, Cp4, T, MPI_DOUBLE, 0, g_mpi_SV_slices); - } + // heavy mesons + for (size_t hi = 0; hi < 2; hi++) { + for (size_t hj = 0; hj < 2; hj++) { + for (size_t g1 = 0; g1 < 2; g1++) { + for (size_t g2 = 0; g2 < 2; g2++) { + MPI_Gather(sC_hihj_g1g2[hi][hj][g1][g2], T, MPI_DOUBLE, C_hihj_g1g2[hi][hj][g1][g2], T, MPI_DOUBLE, 0, g_mpi_SV_slices); + } + } + } + } + + } #endif - + //MPI_Barrier(MPI_COMM_WORLD); if (g_proc_id == 0){ printf("Checkpoint 12\n"); } + + printf("check: %d, %d\n", g_mpi_time_rank, g_proc_coords[0]); + + /* and write everything into a file */ + if (g_mpi_time_rank == 0 && g_proc_coords[0] == 0) { + printf("Checkpoint 12.1 : -%s-\n", filename); + ofs = fopen(filename, "w"); + printf("Checkpoint 12.2\n"); - printf("check: %d, %d\n", g_mpi_time_rank, g_proc_coords[0]); - - /* and write everything into a file */ - if (g_mpi_time_rank == 0 && g_proc_coords[0] == 0) { - printf("Checkpoint 12.1 : -%s-\n", filename); - ofs = fopen(filename, "w"); - printf("Checkpoint 12.2\n"); - - fprintf(ofs, "1 1 0 %e %e\n", Cpp[t0], 0.0); - for (t = 1; t < g_nproc_t * T / 2; t++) { - tt = (t0 + t) % (g_nproc_t * T); - fprintf(ofs, "1 1 %d %e ", t, Cpp[tt]); - tt = (t0 + g_nproc_t * T - t) % (g_nproc_t * T); - fprintf(ofs, "%e\n", Cpp[tt]); - } - tt = (t0 + g_nproc_t * T / 2) % (g_nproc_t * T); - fprintf(ofs, "1 1 %d %e %e\n", t, Cpp[tt], 0.0); - - fprintf(ofs, "2 1 0 %e %e\n", Cpa[t0], 0.0); - for (t = 1; t < g_nproc_t * T / 2; t++) { - tt = (t0 + t) % (g_nproc_t * T); - fprintf(ofs, "2 1 %d %e ", t, Cpa[tt]); - tt = (t0 + g_nproc_t * T - t) % (g_nproc_t * T); - fprintf(ofs, "%e\n", Cpa[tt]); - } - tt = (t0 + g_nproc_t * T / 2) % (g_nproc_t * T); - fprintf(ofs, "2 1 %d %e %e\n", t, Cpa[tt], 0.0); - - fprintf(ofs, "6 1 0 %e %e\n", Cp4[t0], 0.0); - for (t = 1; t < g_nproc_t * T / 2; t++) { - tt = (t0 + t) % (g_nproc_t * T); - fprintf(ofs, "6 1 %d %e ", t, Cp4[tt]); - tt = (t0 + g_nproc_t * T - t) % (g_nproc_t * T); - fprintf(ofs, "%e\n", Cp4[tt]); - } - tt = (t0 + g_nproc_t * T / 2) % (g_nproc_t * T); - fprintf(ofs, "6 1 %d %e %e\n", t, Cp4[tt], 0.0); - - printf("Checkpoint 12.3\n"); - // heavy mesons correlators - for (size_t hi = 0; hi < 2; hi++) { - for (size_t hj = 0; hj < 2; hj++) { - for (size_t g1 = 0; g1 < 2; g1++) { - for (size_t g2 = 0; g2 < 2; g2++) { - fprintf(ofs, "%u %u %u %u 0 %e %e\n", hi, hj, g1, g2, C_hihj_g1g2[hi][hj][g1][g1][t0], 0.0); - for (t = 1; t < g_nproc_t * T / 2; t++) { - tt = (t0 + t) % (g_nproc_t * T); - fprintf(ofs, "%u %u %u %u %d %e ", hi, hj, g1, g2, t, C_hihj_g1g2[hi][hj][g1][g2][tt]); - tt = (t0 + g_nproc_t * T - t) % (g_nproc_t * T); - fprintf(ofs, "%e\n", C_hihj_g1g2[hi][hj][g1][g2][tt]); - } - tt = (t0 + g_nproc_t * T / 2) % (g_nproc_t * T); - fprintf(ofs, "%u %u %u %u %d %e %e\n", hi, hj, g1, g2, t, C_hihj_g1g2[hi][hj][g1][g2][tt], 0.0); - } - } - } - } - fclose(ofs); - } - + + fprintf(ofs, "1 1 0 %e %e\n", Cpp[t0], 0.0); + for (t = 1; t < g_nproc_t * T / 2; t++) { + tt = (t0 + t) % (g_nproc_t * T); + fprintf(ofs, "1 1 %d %e ", t, Cpp[tt]); + tt = (t0 + g_nproc_t * T - t) % (g_nproc_t * T); + fprintf(ofs, "%e\n", Cpp[tt]); + } + tt = (t0 + g_nproc_t * T / 2) % (g_nproc_t * T); + fprintf(ofs, "1 1 %d %e %e\n", t, Cpp[tt], 0.0); + + fprintf(ofs, "2 1 0 %e %e\n", Cpa[t0], 0.0); + for (t = 1; t < g_nproc_t * T / 2; t++) { + tt = (t0 + t) % (g_nproc_t * T); + fprintf(ofs, "2 1 %d %e ", t, Cpa[tt]); + tt = (t0 + g_nproc_t * T - t) % (g_nproc_t * T); + fprintf(ofs, "%e\n", Cpa[tt]); + } + tt = (t0 + g_nproc_t * T / 2) % (g_nproc_t * T); + fprintf(ofs, "2 1 %d %e %e\n", t, Cpa[tt], 0.0); + + fprintf(ofs, "6 1 0 %e %e\n", Cp4[t0], 0.0); + for (t = 1; t < g_nproc_t * T / 2; t++) { + tt = (t0 + t) % (g_nproc_t * T); + fprintf(ofs, "6 1 %d %e ", t, Cp4[tt]); + tt = (t0 + g_nproc_t * T - t) % (g_nproc_t * T); + fprintf(ofs, "%e\n", Cp4[tt]); + } + tt = (t0 + g_nproc_t * T / 2) % (g_nproc_t * T); + fprintf(ofs, "6 1 %d %e %e\n", t, Cp4[tt], 0.0); + + printf("Checkpoint 12.3\n"); + // heavy mesons correlators + for (size_t hi = 0; hi < 2; hi++) { + for (size_t hj = 0; hj < 2; hj++) { + for (size_t g1 = 0; g1 < 2; g1++) { + for (size_t g2 = 0; g2 < 2; g2++) { + fprintf(ofs, "%u %u %u %u 0 %e %e\n", hi, hj, g1, g2, C_hihj_g1g2[hi][hj][g1][g1][t0], 0.0); + for (t = 1; t < g_nproc_t * T / 2; t++) { + tt = (t0 + t) % (g_nproc_t * T); + fprintf(ofs, "%u %u %u %u %d %e ", hi, hj, g1, g2, t, C_hihj_g1g2[hi][hj][g1][g2][tt]); + tt = (t0 + g_nproc_t * T - t) % (g_nproc_t * T); + fprintf(ofs, "%e\n", C_hihj_g1g2[hi][hj][g1][g2][tt]); + } + tt = (t0 + g_nproc_t * T / 2) % (g_nproc_t * T); + fprintf(ofs, "%u %u %u %u %d %e %e\n", hi, hj, g1, g2, t, C_hihj_g1g2[hi][hj][g1][g2][tt], 0.0); + } + } + } + } + fclose(ofs); + } + //MPI_Barrier(MPI_COMM_WORLD); if (g_proc_id == 0){ printf("Checkpoint 13\n"); } - + // freeing memory: light correlators #ifdef TM_USE_MPI - if (g_mpi_time_rank == 0) { - free(Cpp); - free(Cpa); - free(Cp4); - } - free(sCpp); - free(sCpa); - free(sCp4); + if (g_mpi_time_rank == 0) { + free(Cpp); + free(Cpa); + free(Cp4); + } + free(sCpp); + free(sCpa); + free(sCp4); #else - free(Cpp); - free(Cpa); - free(Cp4); + free(Cpp); + free(Cpa); + free(Cp4); #endif - + //MPI_Barrier(MPI_COMM_WORLD); if (g_proc_id == 0){ printf("Checkpoint 14\n"); @@ -873,11 +873,10 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, if (g_proc_id == 0){ printf("Checkpoint 15\n"); } - } // for(max_time_slices) - } // for(max_samples) - + } // for(max_samples) + // freeing up memory for (size_t i_sp = 0; i_sp < 2; i_sp++) { // source or propagator for (size_t db = 0; db < 2; db++) { // doublet: light or heavy @@ -896,20 +895,20 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, } } - free(phi1); - free(phi2); + free(phi1); + free(phi2); - tm_stopwatch_pop(&g_timers, 0, 1, ""); + tm_stopwatch_pop(&g_timers, 0, 1, ""); - return; + return; } void correlators_measurement(const int traj, const int id, const int ieo) { - //light_correlators_measurement(traj, id, ieo); + //light_correlators_measurement(traj, id, ieo); // ??? maybe add a double check? does i1 --> light and i2 --> heavy? if (measurement_list[id].measure_heavy_mesons == 1) { const int i1 = 0, i2 = 1; heavy_correlators_measurement(traj, id, ieo, i1, i2); - } + } } From 59f64e7c7628728caafff58d32d90f8e9859aeac Mon Sep 17 00:00:00 2001 From: simone-romiti Date: Mon, 22 Jan 2024 09:32:06 +0100 Subject: [PATCH 37/51] small typo --- doc/omeas_heavy_mesons.qmd | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/omeas_heavy_mesons.qmd b/doc/omeas_heavy_mesons.qmd index 41fa08823..91774a64b 100644 --- a/doc/omeas_heavy_mesons.qmd +++ b/doc/omeas_heavy_mesons.qmd @@ -176,10 +176,12 @@ The correlator is: \begin{equation} \mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) = +\operatorname{Tr} \left[ S_\ell(0|x) (\sigma_1)^{1-i} P_i \Gamma_1 S_h(x|0) P_j (\sigma_1)^{1-j} \Gamma_2 +\right] \end{equation} From e2d1ceaf61596d6716f6bb1ac15413011870645c Mon Sep 17 00:00:00 2001 From: simone-romiti Date: Tue, 23 Jan 2024 10:24:13 +0100 Subject: [PATCH 38/51] documentation for ndd correlators: simpler notation --- doc/omeas_heavy_mesons.qmd | 168 ++++++++++++++++--------------------- 1 file changed, 74 insertions(+), 94 deletions(-) diff --git a/doc/omeas_heavy_mesons.qmd b/doc/omeas_heavy_mesons.qmd index 91774a64b..e5fcb31b1 100644 --- a/doc/omeas_heavy_mesons.qmd +++ b/doc/omeas_heavy_mesons.qmd @@ -20,6 +20,10 @@ csl: acta-ecologica-sinica.csl fontsize: 16pt --- +### Preamble and notation +
+ Show Content + `tmLQCD`can compute the correlators for the heavy mesons $K$ and $D$. The twisted mass formulation of the heavy doublet $(s, c)$ is such that $K$ and $D$ mix in the spectral decomposition @baron2011computing. In fact, the Dirac operator is not diagonal in flavor, @@ -54,8 +58,13 @@ In the following we use the twisted basis $\chi$ for fermion fields: \end{align} +
+ ## Correlators for the $K$ and $D$ +
+ Show Content + The required correlators are given by the following expectation values on the interacting vacuum ${\bra{\Omega} \cdot \ket{\Omega} = \braket{\cdot}}$: @@ -139,8 +148,13 @@ where ${\sigma_3 = 3. The action of $\sigma_1$ swaps the up and down flavor components of a spinor. ::: +
+ ## Wick contractions +
+ Show Content + Using the above remarks, we can write: @@ -208,7 +222,7 @@ Our correlator becomes: Upon a careful calculation for all values $i,j = 0,1$ we find, equivalently (using spacetime translational symmetry): -\begin{equation} +\begin{equation} \label{eq:C.hihj.Gamma1Gamma2} \begin{split} \mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) &= @@ -219,23 +233,52 @@ Upon a careful calculation for all values $i,j = 0,1$ we find, equivalently (usi (S_u)^\dagger (x|0) \gamma_5 \Gamma_1 \right] -\\ -&= -\sum_{y,z} -\operatorname{Tr} -\left[ - (S_h)_{f_i f_j} (x+y|y) - \Gamma_2 \gamma_5 - (S_u)^\dagger (x+z|z) - \gamma_5 \Gamma_1 - \delta_{yz} -\right] -\, . \end{split} \end{equation} This is a generalized case of eq. (A9) of @PhysRevD.59.074503. +
+ + +## Stochastic approximation of the correlators + +### Index dilution + +
+ Show Content + + +We now make the following remark. If we want to invert numerically the system $D_{ij} \psi_{j} = \eta_{i}$ (where the $i,j$ indices include all internal indices), we have: + +\begin{equation} +D_{ij} \psi_{j} = \eta_{i} \, \implies +\psi_{i} = S_{ij} \eta_{j} \, . +\end{equation} + +If $\eta_i \eta_i^{*} = 1$ we have: + +\begin{equation} +S_{ij} = \psi_{i} \eta_{j}^{*} \, . +\end{equation} + +--- + +We can also use **index dilution** in order to select the components we want. In fact, if we define: $\eta_i^{(a)} = \eta \delta_{i}^{a}$, with $\eta^{*} \eta =1$ we have: + +\begin{equation} +S_{ab} = S_{ij} \delta_{i}^{a} \delta_{j}^{b} = +S_{ij} (\eta* \delta_{i}^{a}) (\eta \delta_{j}^{b}) = +(\psi_{i}^{(b)})^{*} \eta_{i}^{a} = \psi^{(b)} \cdot \eta^{(a)} \, . +\end{equation} + +
+ +### Stochastic expression of the correlators + +
+ Show Content + We now approximate the propagator using stochastic sources. Additionally, we use: @@ -267,99 +310,36 @@ Additionally, we use: \end{equation} +Therefore, we can approximate the correlators of eq. \eqref{eq:C.hihj.Gamma1Gamma2} above with: -Therefore, we can use spin dilutions to rephrase the correlator in a form which will turn out to be convenient later -($c$ is the color index): \begin{equation} +\begin{split} \mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) = -[(S_h)_{f_i f_j}]_{\alpha_1 \beta_1} (x|0) -[\eta^{(\alpha_2)}_{\beta_1}]_c -(\Gamma_2 \gamma_5)_{\alpha_2 \alpha_3} -[{(\eta^\dagger)}^{(\alpha_3)}_{\beta_2}]_c -[(S_u)^\dagger]_{\beta_2 \alpha_4} (x|0) +& +\left( + (\psi_h)^{(f_j, \alpha_2)}(x) + \cdot + \eta^{(f_i, \alpha_1)}(0) +\right) +(\Gamma_2 \gamma_5)_{\alpha_2 \alpha_3} +\\ +& +\left( + (\psi_u)^{(0, \alpha_4)}(x) + \cdot + \eta^{(0, \alpha_3)}(0) +\right) (\gamma_5 \Gamma_1)_{\alpha_4 \alpha_1} -\, . +\end{split} \end{equation} -We now define our spinor propagators. -If $\eta^{(\beta, \phi)}$ is the diluted source: - -\begin{align} -& (D_{\ell/h})_{\alpha_1 \alpha_2} (x|y) ({\psi}_{\ell/h}^{(\beta, \phi)})_{\alpha_2} (y) -= (\eta^{(\beta, \phi)})_{\alpha_1} (x) -\\ -& \, \implies \, -(\psi_{\ell/h}^{(\beta, \phi)})_{\alpha_1} (x) -= -(S_{\ell/h})_{\alpha_2 \alpha_1} (x | y) -\eta^{(\beta, \phi)}_{\alpha_2} (y) -= -(S_{\ell/h})_{\alpha_2 \alpha_1} (x | 0) -\eta^{(\beta, \phi)}_{\alpha_2} (0) -\\ -& \, \implies \, -(\psi_{\ell/h}^{(\beta, \phi)})^{*}_{\alpha_1} (x) -= -(\eta^{(\beta, \phi)})^{*}_{\alpha_2} (y) -(S_{\ell/h}^\dagger)_{\alpha_2 \alpha_1} (x | y) -= -(\eta^{(\beta, \phi)})^\dagger_{\alpha_2} (0) -(S_{\ell/h}^\dagger)_{\alpha_2 \alpha_1} (x | 0) -\end{align} - -This means that for our matrix of correlators we have to do ${4_D \times 2_f \times 2_{h,\ell}} = 16$ inversions. +
-::: {.remark} -1. For the light doublet `tmLQCD` computes only $S_u$, which is obtained with $(\psi_h^{(\beta, f_0)})_{f_0}$. This is the only propagator we need. -2. For the heavy propagator, we can access the $(i,j)$ component of $S_h$ with $(\psi_h^{(\beta, f_j)})_{f_i}$. -::: -Our correlator is given by the following expectation value -(no summation on flavor indices): - -\begin{equation} -\begin{split} -\mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) -&= -\langle -[(\psi_h^{(\alpha_2, f_j)})_{f_i}]_{\alpha_1}(x) -(\Gamma_2 \gamma_5)_{\alpha_2 \alpha_3} -[(\psi_\ell^{(\alpha_3, f_0)})_{f_0}^\dagger]_{\alpha_4} (x) -(\gamma_5 \Gamma_1)_{\alpha_4 \alpha_1} -\rangle -\\ -&= -\braket{ -(\psi_\ell^{(\alpha_3, f_0)})_{f_0}^\dagger (x) -\cdot -(\gamma_5 \Gamma_1) -\cdot -(\psi_h^{(\alpha_2, f_j)})_{f_i}(x) -} -\, -(\Gamma_2 \gamma_5)_{\alpha_2 \alpha_3} -\\ -&= -\mathcal{R}^{\alpha_3 \alpha_2} (\Gamma_2 \gamma_5)_{\alpha_2 \alpha_3} -\end{split} -\end{equation} - -More explicitly: - -\begin{equation} -\begin{split} -\Gamma_2=1 &\implies \mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) -= \mathcal{R}^{00}+\mathcal{R}^{11}-\mathcal{R}^{22}-\mathcal{R}^{33} -\\ -\Gamma_2=\gamma_5 &\implies \mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) -= \mathcal{R}^{00}+\mathcal{R}^{11}+\mathcal{R}^{22}+\mathcal{R}^{33} -\end{split} -\end{equation} - From 3d93a019af979bf43fe650a8a584764c3ff48e5b Mon Sep 17 00:00:00 2001 From: simone-romiti Date: Tue, 23 Jan 2024 20:22:57 +0100 Subject: [PATCH 39/51] minor changes --- meas/correlators.c | 5 +++-- offline_measurement.c | 2 -- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/meas/correlators.c b/meas/correlators.c index 9bfe25db5..b4ca90ca0 100644 --- a/meas/correlators.c +++ b/meas/correlators.c @@ -292,7 +292,7 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, #endif /* heavy-light correlators variables */ - // sign change bilinear^\dagger, with Gamma = 1,gamma_ + // sign change bilinear^\dagger, with Gamma = 1,gamma_5 double eta_Gamma[2] = {1.0, -1.0}; // even-odd spinor fields for the light and heavy doublet correlators @@ -904,11 +904,12 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, } void correlators_measurement(const int traj, const int id, const int ieo) { - //light_correlators_measurement(traj, id, ieo); // ??? maybe add a double check? does i1 --> light and i2 --> heavy? if (measurement_list[id].measure_heavy_mesons == 1) { const int i1 = 0, i2 = 1; heavy_correlators_measurement(traj, id, ieo, i1, i2); } + + light_correlators_measurement(traj, id, ieo); } diff --git a/offline_measurement.c b/offline_measurement.c index 95ea094e8..4911ecd14 100644 --- a/offline_measurement.c +++ b/offline_measurement.c @@ -293,9 +293,7 @@ int main(int argc, char *argv[]) if (g_proc_id == 0) { fprintf(stdout, "#\n# Beginning offline measurement.\n"); } - //printf("Ciao Simone4!\n"); meas->measurefunc(nstore, imeas, even_odd_flag); - printf("Ciao Simone5!\n"); } nstore += Nsave; } From 500705e7fdd1047c749e34f6d40ee7ac7d2517a7 Mon Sep 17 00:00:00 2001 From: simone-romiti Date: Tue, 23 Jan 2024 20:23:41 +0100 Subject: [PATCH 40/51] typo in doc for ndd_correlators --- doc/omeas_heavy_mesons.qmd | 48 +++++++++++++++++++++++++++++++------- 1 file changed, 40 insertions(+), 8 deletions(-) diff --git a/doc/omeas_heavy_mesons.qmd b/doc/omeas_heavy_mesons.qmd index e5fcb31b1..78622438d 100644 --- a/doc/omeas_heavy_mesons.qmd +++ b/doc/omeas_heavy_mesons.qmd @@ -256,7 +256,7 @@ D_{ij} \psi_{j} = \eta_{i} \, \implies \psi_{i} = S_{ij} \eta_{j} \, . \end{equation} -If $\eta_i \eta_i^{*} = 1$ we have: +If $\eta_i \eta_j^{*} = \delta_{ij}$ we have: \begin{equation} S_{ij} = \psi_{i} \eta_{j}^{*} \, . @@ -268,8 +268,9 @@ We can also use **index dilution** in order to select the components we want. In \begin{equation} S_{ab} = S_{ij} \delta_{i}^{a} \delta_{j}^{b} = -S_{ij} (\eta* \delta_{i}^{a}) (\eta \delta_{j}^{b}) = -(\psi_{i}^{(b)})^{*} \eta_{i}^{a} = \psi^{(b)} \cdot \eta^{(a)} \, . +S_{ij} (\eta^{*} \delta_{i}^{a}) (\eta \delta_{j}^{b}) = +\psi_{i}^{(b)} (\eta_{i}^{a})^{*} += \eta^{(a)} \cdot \psi^{(b)} \, . \end{equation} @@ -289,7 +290,7 @@ Additionally, we use: \begin{equation} \eta^{(\alpha)}_{\beta, c} = \eta_c \, \delta^\alpha_\beta \,\, , \, \, - \eta^\dagger_c \eta_c = 1 \, . + \eta_c \otimes \eta^\dagger_c = \mathbb{1}_{N_c \times N_c} \, . \end{equation} - Flavor dilution: sources have an additional flavor index $\phi$, such that their flavor component different from the index vanish. The value of the flavor component however is the same, it changes only its position in the doublet: @@ -319,23 +320,54 @@ Therefore, we can approximate the correlators of eq. \eqref{eq:C.hihj.Gamma1Gamm = & \left( - (\psi_h)^{(f_j, \alpha_2)}(x) - \cdot \eta^{(f_i, \alpha_1)}(0) + \cdot + \psi_h^{(f_j, \alpha_2)}(x) \right) (\Gamma_2 \gamma_5)_{\alpha_2 \alpha_3} \\ & \left( - (\psi_u)^{(0, \alpha_4)}(x) - \cdot \eta^{(0, \alpha_3)}(0) + \cdot + \psi_u^{(0, \alpha_4)}(x) \right) (\gamma_5 \Gamma_1)_{\alpha_4 \alpha_1} \end{split} \end{equation} +In our case $\Gamma_{1/2} = 1, \gamma_5$, so that $\Gamma_i \gamma_5$ is diagonal in the Dirac indices. +Thus the correlator can be written as (explicit summation over the indices): + + +\begin{equation} +\begin{split} +\mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) += +& +\sum_{\alpha_{1}, \alpha_{2}} +\left( + \eta^{(f_i, \alpha_1)}(0) + \cdot + \psi_h^{(f_j, \alpha_2)}(x) +\right) +(\Gamma_2 \gamma_5)_{\alpha_2 \alpha_2} +\\ +& +\left( + \eta^{(0, \alpha_2)}(0) + \cdot + \psi_u^{(0, \alpha_1)}(x) +\right) +(\gamma_5 \Gamma_1)_{\alpha_1 \alpha_1} +\end{split} +\end{equation} + + + + + From 7608a7eacb27ac53649664e074f71b6bf983e548 Mon Sep 17 00:00:00 2001 From: simone-romiti Date: Tue, 23 Jan 2024 10:24:13 +0100 Subject: [PATCH 41/51] documentation for ndd correlators: simpler notation --- doc/omeas_heavy_mesons.qmd | 168 ++++++++++++++++--------------------- 1 file changed, 74 insertions(+), 94 deletions(-) diff --git a/doc/omeas_heavy_mesons.qmd b/doc/omeas_heavy_mesons.qmd index 91774a64b..e5fcb31b1 100644 --- a/doc/omeas_heavy_mesons.qmd +++ b/doc/omeas_heavy_mesons.qmd @@ -20,6 +20,10 @@ csl: acta-ecologica-sinica.csl fontsize: 16pt --- +### Preamble and notation +
+ Show Content + `tmLQCD`can compute the correlators for the heavy mesons $K$ and $D$. The twisted mass formulation of the heavy doublet $(s, c)$ is such that $K$ and $D$ mix in the spectral decomposition @baron2011computing. In fact, the Dirac operator is not diagonal in flavor, @@ -54,8 +58,13 @@ In the following we use the twisted basis $\chi$ for fermion fields: \end{align} +
+ ## Correlators for the $K$ and $D$ +
+ Show Content + The required correlators are given by the following expectation values on the interacting vacuum ${\bra{\Omega} \cdot \ket{\Omega} = \braket{\cdot}}$: @@ -139,8 +148,13 @@ where ${\sigma_3 = 3. The action of $\sigma_1$ swaps the up and down flavor components of a spinor. ::: +
+ ## Wick contractions +
+ Show Content + Using the above remarks, we can write: @@ -208,7 +222,7 @@ Our correlator becomes: Upon a careful calculation for all values $i,j = 0,1$ we find, equivalently (using spacetime translational symmetry): -\begin{equation} +\begin{equation} \label{eq:C.hihj.Gamma1Gamma2} \begin{split} \mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) &= @@ -219,23 +233,52 @@ Upon a careful calculation for all values $i,j = 0,1$ we find, equivalently (usi (S_u)^\dagger (x|0) \gamma_5 \Gamma_1 \right] -\\ -&= -\sum_{y,z} -\operatorname{Tr} -\left[ - (S_h)_{f_i f_j} (x+y|y) - \Gamma_2 \gamma_5 - (S_u)^\dagger (x+z|z) - \gamma_5 \Gamma_1 - \delta_{yz} -\right] -\, . \end{split} \end{equation} This is a generalized case of eq. (A9) of @PhysRevD.59.074503. +
+ + +## Stochastic approximation of the correlators + +### Index dilution + +
+ Show Content + + +We now make the following remark. If we want to invert numerically the system $D_{ij} \psi_{j} = \eta_{i}$ (where the $i,j$ indices include all internal indices), we have: + +\begin{equation} +D_{ij} \psi_{j} = \eta_{i} \, \implies +\psi_{i} = S_{ij} \eta_{j} \, . +\end{equation} + +If $\eta_i \eta_i^{*} = 1$ we have: + +\begin{equation} +S_{ij} = \psi_{i} \eta_{j}^{*} \, . +\end{equation} + +--- + +We can also use **index dilution** in order to select the components we want. In fact, if we define: $\eta_i^{(a)} = \eta \delta_{i}^{a}$, with $\eta^{*} \eta =1$ we have: + +\begin{equation} +S_{ab} = S_{ij} \delta_{i}^{a} \delta_{j}^{b} = +S_{ij} (\eta* \delta_{i}^{a}) (\eta \delta_{j}^{b}) = +(\psi_{i}^{(b)})^{*} \eta_{i}^{a} = \psi^{(b)} \cdot \eta^{(a)} \, . +\end{equation} + +
+ +### Stochastic expression of the correlators + +
+ Show Content + We now approximate the propagator using stochastic sources. Additionally, we use: @@ -267,99 +310,36 @@ Additionally, we use: \end{equation} +Therefore, we can approximate the correlators of eq. \eqref{eq:C.hihj.Gamma1Gamma2} above with: -Therefore, we can use spin dilutions to rephrase the correlator in a form which will turn out to be convenient later -($c$ is the color index): \begin{equation} +\begin{split} \mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) = -[(S_h)_{f_i f_j}]_{\alpha_1 \beta_1} (x|0) -[\eta^{(\alpha_2)}_{\beta_1}]_c -(\Gamma_2 \gamma_5)_{\alpha_2 \alpha_3} -[{(\eta^\dagger)}^{(\alpha_3)}_{\beta_2}]_c -[(S_u)^\dagger]_{\beta_2 \alpha_4} (x|0) +& +\left( + (\psi_h)^{(f_j, \alpha_2)}(x) + \cdot + \eta^{(f_i, \alpha_1)}(0) +\right) +(\Gamma_2 \gamma_5)_{\alpha_2 \alpha_3} +\\ +& +\left( + (\psi_u)^{(0, \alpha_4)}(x) + \cdot + \eta^{(0, \alpha_3)}(0) +\right) (\gamma_5 \Gamma_1)_{\alpha_4 \alpha_1} -\, . +\end{split} \end{equation} -We now define our spinor propagators. -If $\eta^{(\beta, \phi)}$ is the diluted source: - -\begin{align} -& (D_{\ell/h})_{\alpha_1 \alpha_2} (x|y) ({\psi}_{\ell/h}^{(\beta, \phi)})_{\alpha_2} (y) -= (\eta^{(\beta, \phi)})_{\alpha_1} (x) -\\ -& \, \implies \, -(\psi_{\ell/h}^{(\beta, \phi)})_{\alpha_1} (x) -= -(S_{\ell/h})_{\alpha_2 \alpha_1} (x | y) -\eta^{(\beta, \phi)}_{\alpha_2} (y) -= -(S_{\ell/h})_{\alpha_2 \alpha_1} (x | 0) -\eta^{(\beta, \phi)}_{\alpha_2} (0) -\\ -& \, \implies \, -(\psi_{\ell/h}^{(\beta, \phi)})^{*}_{\alpha_1} (x) -= -(\eta^{(\beta, \phi)})^{*}_{\alpha_2} (y) -(S_{\ell/h}^\dagger)_{\alpha_2 \alpha_1} (x | y) -= -(\eta^{(\beta, \phi)})^\dagger_{\alpha_2} (0) -(S_{\ell/h}^\dagger)_{\alpha_2 \alpha_1} (x | 0) -\end{align} - -This means that for our matrix of correlators we have to do ${4_D \times 2_f \times 2_{h,\ell}} = 16$ inversions. +
-::: {.remark} -1. For the light doublet `tmLQCD` computes only $S_u$, which is obtained with $(\psi_h^{(\beta, f_0)})_{f_0}$. This is the only propagator we need. -2. For the heavy propagator, we can access the $(i,j)$ component of $S_h$ with $(\psi_h^{(\beta, f_j)})_{f_i}$. -::: -Our correlator is given by the following expectation value -(no summation on flavor indices): - -\begin{equation} -\begin{split} -\mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) -&= -\langle -[(\psi_h^{(\alpha_2, f_j)})_{f_i}]_{\alpha_1}(x) -(\Gamma_2 \gamma_5)_{\alpha_2 \alpha_3} -[(\psi_\ell^{(\alpha_3, f_0)})_{f_0}^\dagger]_{\alpha_4} (x) -(\gamma_5 \Gamma_1)_{\alpha_4 \alpha_1} -\rangle -\\ -&= -\braket{ -(\psi_\ell^{(\alpha_3, f_0)})_{f_0}^\dagger (x) -\cdot -(\gamma_5 \Gamma_1) -\cdot -(\psi_h^{(\alpha_2, f_j)})_{f_i}(x) -} -\, -(\Gamma_2 \gamma_5)_{\alpha_2 \alpha_3} -\\ -&= -\mathcal{R}^{\alpha_3 \alpha_2} (\Gamma_2 \gamma_5)_{\alpha_2 \alpha_3} -\end{split} -\end{equation} - -More explicitly: - -\begin{equation} -\begin{split} -\Gamma_2=1 &\implies \mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) -= \mathcal{R}^{00}+\mathcal{R}^{11}-\mathcal{R}^{22}-\mathcal{R}^{33} -\\ -\Gamma_2=\gamma_5 &\implies \mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) -= \mathcal{R}^{00}+\mathcal{R}^{11}+\mathcal{R}^{22}+\mathcal{R}^{33} -\end{split} -\end{equation} - From f9eb405831908e5dc09bb364f345c6b1f6fac08c Mon Sep 17 00:00:00 2001 From: simone-romiti Date: Tue, 23 Jan 2024 20:22:57 +0100 Subject: [PATCH 42/51] minor changes --- meas/correlators.c | 5 +++-- offline_measurement.c | 2 -- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/meas/correlators.c b/meas/correlators.c index 9bfe25db5..b4ca90ca0 100644 --- a/meas/correlators.c +++ b/meas/correlators.c @@ -292,7 +292,7 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, #endif /* heavy-light correlators variables */ - // sign change bilinear^\dagger, with Gamma = 1,gamma_ + // sign change bilinear^\dagger, with Gamma = 1,gamma_5 double eta_Gamma[2] = {1.0, -1.0}; // even-odd spinor fields for the light and heavy doublet correlators @@ -904,11 +904,12 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, } void correlators_measurement(const int traj, const int id, const int ieo) { - //light_correlators_measurement(traj, id, ieo); // ??? maybe add a double check? does i1 --> light and i2 --> heavy? if (measurement_list[id].measure_heavy_mesons == 1) { const int i1 = 0, i2 = 1; heavy_correlators_measurement(traj, id, ieo, i1, i2); } + + light_correlators_measurement(traj, id, ieo); } diff --git a/offline_measurement.c b/offline_measurement.c index 95ea094e8..4911ecd14 100644 --- a/offline_measurement.c +++ b/offline_measurement.c @@ -293,9 +293,7 @@ int main(int argc, char *argv[]) if (g_proc_id == 0) { fprintf(stdout, "#\n# Beginning offline measurement.\n"); } - //printf("Ciao Simone4!\n"); meas->measurefunc(nstore, imeas, even_odd_flag); - printf("Ciao Simone5!\n"); } nstore += Nsave; } From cd605f7a7749c6c65f8a15c98b4036c12fdc0baa Mon Sep 17 00:00:00 2001 From: simone-romiti Date: Tue, 23 Jan 2024 20:23:41 +0100 Subject: [PATCH 43/51] typo in doc for ndd_correlators --- doc/omeas_heavy_mesons.qmd | 48 +++++++++++++++++++++++++++++++------- 1 file changed, 40 insertions(+), 8 deletions(-) diff --git a/doc/omeas_heavy_mesons.qmd b/doc/omeas_heavy_mesons.qmd index e5fcb31b1..78622438d 100644 --- a/doc/omeas_heavy_mesons.qmd +++ b/doc/omeas_heavy_mesons.qmd @@ -256,7 +256,7 @@ D_{ij} \psi_{j} = \eta_{i} \, \implies \psi_{i} = S_{ij} \eta_{j} \, . \end{equation} -If $\eta_i \eta_i^{*} = 1$ we have: +If $\eta_i \eta_j^{*} = \delta_{ij}$ we have: \begin{equation} S_{ij} = \psi_{i} \eta_{j}^{*} \, . @@ -268,8 +268,9 @@ We can also use **index dilution** in order to select the components we want. In \begin{equation} S_{ab} = S_{ij} \delta_{i}^{a} \delta_{j}^{b} = -S_{ij} (\eta* \delta_{i}^{a}) (\eta \delta_{j}^{b}) = -(\psi_{i}^{(b)})^{*} \eta_{i}^{a} = \psi^{(b)} \cdot \eta^{(a)} \, . +S_{ij} (\eta^{*} \delta_{i}^{a}) (\eta \delta_{j}^{b}) = +\psi_{i}^{(b)} (\eta_{i}^{a})^{*} += \eta^{(a)} \cdot \psi^{(b)} \, . \end{equation} @@ -289,7 +290,7 @@ Additionally, we use: \begin{equation} \eta^{(\alpha)}_{\beta, c} = \eta_c \, \delta^\alpha_\beta \,\, , \, \, - \eta^\dagger_c \eta_c = 1 \, . + \eta_c \otimes \eta^\dagger_c = \mathbb{1}_{N_c \times N_c} \, . \end{equation} - Flavor dilution: sources have an additional flavor index $\phi$, such that their flavor component different from the index vanish. The value of the flavor component however is the same, it changes only its position in the doublet: @@ -319,23 +320,54 @@ Therefore, we can approximate the correlators of eq. \eqref{eq:C.hihj.Gamma1Gamm = & \left( - (\psi_h)^{(f_j, \alpha_2)}(x) - \cdot \eta^{(f_i, \alpha_1)}(0) + \cdot + \psi_h^{(f_j, \alpha_2)}(x) \right) (\Gamma_2 \gamma_5)_{\alpha_2 \alpha_3} \\ & \left( - (\psi_u)^{(0, \alpha_4)}(x) - \cdot \eta^{(0, \alpha_3)}(0) + \cdot + \psi_u^{(0, \alpha_4)}(x) \right) (\gamma_5 \Gamma_1)_{\alpha_4 \alpha_1} \end{split} \end{equation} +In our case $\Gamma_{1/2} = 1, \gamma_5$, so that $\Gamma_i \gamma_5$ is diagonal in the Dirac indices. +Thus the correlator can be written as (explicit summation over the indices): + + +\begin{equation} +\begin{split} +\mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) += +& +\sum_{\alpha_{1}, \alpha_{2}} +\left( + \eta^{(f_i, \alpha_1)}(0) + \cdot + \psi_h^{(f_j, \alpha_2)}(x) +\right) +(\Gamma_2 \gamma_5)_{\alpha_2 \alpha_2} +\\ +& +\left( + \eta^{(0, \alpha_2)}(0) + \cdot + \psi_u^{(0, \alpha_1)}(x) +\right) +(\gamma_5 \Gamma_1)_{\alpha_1 \alpha_1} +\end{split} +\end{equation} + + + + + From f7a94a30a0e3a09870d74cd30a1198ff5cd50d2a Mon Sep 17 00:00:00 2001 From: simone-romiti Date: Tue, 23 Jan 2024 20:52:12 +0100 Subject: [PATCH 44/51] applied formula in the documentation for ndd_correlators --- meas/correlators.c | 53 +++++++++++++++++++++++++++++++--------------- 1 file changed, 36 insertions(+), 17 deletions(-) diff --git a/meas/correlators.c b/meas/correlators.c index b4ca90ca0..c363aeff7 100644 --- a/meas/correlators.c +++ b/meas/correlators.c @@ -659,33 +659,52 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, for (i = j; i < j + LX * LY * LZ; i++) { for (size_t beta = 0; beta < 4; beta++) { // spin dilution spinor psi_u = arr_spinor[1][0][beta][f0][f0][i]; + spinor eta_u = arr_spinor[0][0][beta][f0][f0][0]; res += _spinor_prod_re(psi_u, psi_u); _gamma0(phi, psi_u); respa += _spinor_prod_re(psi_u, phi); _gamma5(phi, phi); resp4 += _spinor_prod_im(psi_u, phi); + } + + // diagonal elements of Gamma_i*gamma_5 + double diag_G1g5[4] = {1.0, 1.0, 1.0, 1.0}; + double diag_G2g5[4] = {1.0, 1.0, 1.0, 1.0}; - for (size_t hi = 0; hi < 2; hi++) { - for (size_t hj = 0; hj < 2; hj++) { - for (size_t g1 = 0; g1 < 2; g1++) { - for (size_t g2 = 0; g2 < 2; g2++) { - double dum = 0.0; // dummy variable - - // heavy doublet spinor propagator - phi = arr_spinor[1][1][beta][hj][hi][i]; - if (g1 == 0) { // Gamma_1 = \mathbb{1} - _gamma5(phi, phi); - } - _spinor_scalar_prod(dum, psi_u, phi); - - double sign_beta = +1.0; - if (g2 == 0 /* Gamma_2 == \mathbb{1} */ && beta >= 2) { - sign_beta = -1.0; + for (size_t hi = 0; hi < 2; hi++) { + for (size_t hj = 0; hj < 2; hj++) { + for (size_t g1 = 0; g1 < 2; g1++) { + if (g1 == 0) { // Gamma_1 = \mathbb{1} + diag_G1g5[2] = -1; + diag_G1g5[3] = -1; + } + for (size_t g2 = 0; g2 < 2; g2++) { + // heavy doublet spinor propagator + for (int alpha_1=0; alpha_1 < 4; alpha_1++){ + spinor eta_h = arr_spinor[1][1][alpha_1][hj][hi][0]; + spinor psi_u = arr_spinor[1][0][alpha_1][f0][f0][i]; + for (int alpha_2=0; alpha_2 < 4; alpha_2++){ + spinor eta_u = arr_spinor[0][0][alpha_2][f0][f0][0]; + double dum1 = 0.0; // dummy variable + _spinor_scalar_prod(dum1, eta_u, psi_u); + double dum2 = 0.0; // dummy variable + spinor psi_h = arr_spinor[1][1][alpha_2][hj][hi][i]; + if (g2 == 0) { // Gamma_2 = \mathbb{1} + diag_G2g5[2] = -1.0; + diag_G2g5[3] = -1.0; + } + _spinor_scalar_prod(dum2, eta_h, psi_h); + res_hihj_g1g2[hi][hj][g1][g2] += dum2*diag_G2g5[alpha_2]*dum1*diag_G1g5[alpha_1]; } - res_hihj_g1g2[hi][hj][g1][g2] += sign_beta * dum; } + // restoring to default + diag_G2g5[2] = 1.0; + diag_G2g5[3] = 1.0; } + // restoring to default + diag_G1g5[2] = 1.0; + diag_G1g5[3] = 1.0; } } From 13db981a26bb6284d6d51a9a64c9fc0bc5be6cfa Mon Sep 17 00:00:00 2001 From: simone-romiti Date: Tue, 23 Jan 2024 20:58:58 +0100 Subject: [PATCH 45/51] fixed typo --- meas/correlators.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meas/correlators.c b/meas/correlators.c index c363aeff7..9d52eea19 100644 --- a/meas/correlators.c +++ b/meas/correlators.c @@ -682,7 +682,7 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, for (size_t g2 = 0; g2 < 2; g2++) { // heavy doublet spinor propagator for (int alpha_1=0; alpha_1 < 4; alpha_1++){ - spinor eta_h = arr_spinor[1][1][alpha_1][hj][hi][0]; + spinor eta_h = arr_spinor[0][1][alpha_1][hj][hi][0]; spinor psi_u = arr_spinor[1][0][alpha_1][f0][f0][i]; for (int alpha_2=0; alpha_2 < 4; alpha_2++){ spinor eta_u = arr_spinor[0][0][alpha_2][f0][f0][0]; From 29086ea2a276fb4359f245583455dd0da828e0f5 Mon Sep 17 00:00:00 2001 From: simone-romiti Date: Wed, 24 Jan 2024 13:30:25 +0100 Subject: [PATCH 46/51] minor change to the ndd documentation --- doc/omeas_heavy_mesons.qmd | 6 ------ 1 file changed, 6 deletions(-) diff --git a/doc/omeas_heavy_mesons.qmd b/doc/omeas_heavy_mesons.qmd index 78622438d..c5081381a 100644 --- a/doc/omeas_heavy_mesons.qmd +++ b/doc/omeas_heavy_mesons.qmd @@ -318,15 +318,12 @@ Therefore, we can approximate the correlators of eq. \eqref{eq:C.hihj.Gamma1Gamm \begin{split} \mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) = -& \left( \eta^{(f_i, \alpha_1)}(0) \cdot \psi_h^{(f_j, \alpha_2)}(x) \right) (\Gamma_2 \gamma_5)_{\alpha_2 \alpha_3} -\\ -& \left( \eta^{(0, \alpha_3)}(0) \cdot @@ -345,7 +342,6 @@ Thus the correlator can be written as (explicit summation over the indices): \begin{split} \mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) = -& \sum_{\alpha_{1}, \alpha_{2}} \left( \eta^{(f_i, \alpha_1)}(0) @@ -353,8 +349,6 @@ Thus the correlator can be written as (explicit summation over the indices): \psi_h^{(f_j, \alpha_2)}(x) \right) (\Gamma_2 \gamma_5)_{\alpha_2 \alpha_2} -\\ -& \left( \eta^{(0, \alpha_2)}(0) \cdot From 142b15212242c189c14be4b8718bc8e20e1ca316 Mon Sep 17 00:00:00 2001 From: simone-romiti Date: Fri, 26 Jan 2024 16:30:06 +0100 Subject: [PATCH 47/51] no need for the sources when building the correlator --- meas/correlators.c | 112 ++++++++++++++------------- solver/dirac_operator_eigenvectors.h | 8 ++ 2 files changed, 65 insertions(+), 55 deletions(-) diff --git a/meas/correlators.c b/meas/correlators.c index 9d52eea19..6f3c1060a 100644 --- a/meas/correlators.c +++ b/meas/correlators.c @@ -40,7 +40,6 @@ #include "gettime.h" - #define TM_OMEAS_FILENAME_LENGTH 100 /****************************************************** @@ -253,6 +252,15 @@ void light_correlators_measurement(const int traj, const int id, const int ieo) return; } + +void spinor_dirac_array(su3_vector* phi, spinor psi){ + phi[0] = psi.s0; + phi[1] = psi.s1; + phi[2] = psi.s2; + phi[3] = psi.s3; +} + + /****************************************************** * * This routine computes the correlator matrix (), @@ -473,9 +481,10 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, for (size_t beta = 0; beta < 4; beta++) { // spin dilution index for (size_t F = 0; F < 2; F++) { // flavor dilution index for (size_t i_f = 0; i_f < 2; i_f++) { // flavor index of the doublet - eo_source_spinor_field_spin_diluted_oet_ts(arr_eo_spinor[0][db][beta][F][0][i_f], - arr_eo_spinor[0][db][beta][F][1][i_f], t0, - beta, sample, traj, seed_i); + eo_source_spinor_field_spin_diluted_oet_ts( + arr_eo_spinor[0][db][beta][F][0][i_f], + arr_eo_spinor[0][db][beta][F][1][i_f], t0, + beta, sample, traj, seed_i); } } } @@ -498,15 +507,15 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, // stored temporarely in the propagator spinors (used as dummy) if (F==0){ mul_one_pm_itau2_and_div_by_sqrt2( - arr_eo_spinor[1][1][beta][F][i_eo][0], arr_eo_spinor[1][1][beta][F][i_eo][1], - arr_eo_spinor[0][1][beta][F][i_eo][0], phi1, +1.0, - VOLUME / 2); + arr_eo_spinor[1][1][beta][F][i_eo][0], arr_eo_spinor[1][1][beta][F][i_eo][1], + arr_eo_spinor[0][1][beta][F][i_eo][0], phi1, +1.0, + VOLUME / 2); } if (F==1){ mul_one_pm_itau2_and_div_by_sqrt2( - arr_eo_spinor[1][1][beta][F][i_eo][0], arr_eo_spinor[1][1][beta][F][i_eo][1], - phi2, arr_eo_spinor[0][1][beta][F][i_eo][1], +1.0, - VOLUME / 2); + arr_eo_spinor[1][1][beta][F][i_eo][0], arr_eo_spinor[1][1][beta][F][i_eo][1], + phi2, arr_eo_spinor[0][1][beta][F][i_eo][1], +1.0, + VOLUME / 2); } for (size_t i_f = 0; i_f < 2; i_f++) { @@ -598,9 +607,9 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, // (c,s) --> [(1-i*tau_2)/sqrt(2)] * (c,s) // stored temporarely in phi1, phi2 mul_one_pm_itau2_and_div_by_sqrt2(phi1, phi2, - arr_eo_spinor[1][1][beta][F][i_eo][0], arr_eo_spinor[1][1][beta][F][i_eo][1], -1.0, - VOLUME / 2); - + arr_eo_spinor[1][1][beta][F][i_eo][0], arr_eo_spinor[1][1][beta][F][i_eo][1], -1.0, + VOLUME / 2); + assign(arr_eo_spinor[1][1][beta][F][i_eo][0], phi1, VOLUME / 2); assign(arr_eo_spinor[1][1][beta][F][i_eo][1], phi2, VOLUME / 2); } @@ -616,19 +625,19 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, } // now we switch from even-odd representation to standard - //for (size_t i_sp = 0; i_sp < 2; i_sp++) { // source or sink - for (size_t db = 0; db < 2; db++) { // doublet: light of heavy - for (size_t beta = 0; beta < 4; beta++) { // spin dilution index - for (size_t F = 0; F < 2; F++) { // flavor projection index - for (size_t i_f = 0; i_f < 2; i_f++) { // flavor index - convert_eo_to_lexic(arr_spinor[1][db][beta][F][i_f], - arr_eo_spinor[1][db][beta][F][0][i_f], - arr_eo_spinor[1][db][beta][F][1][i_f]); + for (size_t i_sp = 0; i_sp < 2; i_sp++) { // source or sink + for (size_t db = 0; db < 2; db++) { // doublet: light of heavy + for (size_t beta = 0; beta < 4; beta++) { // spin dilution index + for (size_t F = 0; F < 2; F++) { // flavor projection index + for (size_t i_f = 0; i_f < 2; i_f++) { // flavor index + convert_eo_to_lexic(arr_spinor[i_sp][db][beta][F][i_f], + arr_eo_spinor[i_sp][db][beta][F][0][i_f], + arr_eo_spinor[i_sp][db][beta][F][1][i_f]); + } } } } } - // } //MPI_Barrier(MPI_COMM_WORLD); if (g_proc_id == 0){ @@ -637,7 +646,7 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, //MPI_Barrier(MPI_COMM_WORLD); if (g_proc_id == 0){ - printf("Checkpoint 11\n"); + printf("Checkpoint 11.0\n"); } /* @@ -645,21 +654,23 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, https://arxiv.org/pdf/1005.2042.pdf) I can build the correlators of eq. (20) */ const int f0 = 0; // flavor index of the up + /* now we sum only over local space for every t */ + const int j_ts = t0-g_proc_coords[0]*T; // checkerboard index of the time at the source for (t = 0; t < T; t++) { - j = g_ipt[t][0][0][0]; + j = g_ipt[t][0][0][0]; // source and sink separated by "t" // dummy variables res = 0.0; respa = 0.0; resp4 = 0.0; - for (i = j; i < j + LX * LY * LZ; i++) { + + // light correlators for (size_t beta = 0; beta < 4; beta++) { // spin dilution spinor psi_u = arr_spinor[1][0][beta][f0][f0][i]; - spinor eta_u = arr_spinor[0][0][beta][f0][f0][0]; res += _spinor_prod_re(psi_u, psi_u); _gamma0(phi, psi_u); @@ -668,43 +679,34 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, resp4 += _spinor_prod_im(psi_u, phi); } - // diagonal elements of Gamma_i*gamma_5 - double diag_G1g5[4] = {1.0, 1.0, 1.0, 1.0}; - double diag_G2g5[4] = {1.0, 1.0, 1.0, 1.0}; - + // heavy correlators for (size_t hi = 0; hi < 2; hi++) { for (size_t hj = 0; hj < 2; hj++) { for (size_t g1 = 0; g1 < 2; g1++) { - if (g1 == 0) { // Gamma_1 = \mathbb{1} - diag_G1g5[2] = -1; - diag_G1g5[3] = -1; - } for (size_t g2 = 0; g2 < 2; g2++) { - // heavy doublet spinor propagator - for (int alpha_1=0; alpha_1 < 4; alpha_1++){ - spinor eta_h = arr_spinor[0][1][alpha_1][hj][hi][0]; - spinor psi_u = arr_spinor[1][0][alpha_1][f0][f0][i]; - for (int alpha_2=0; alpha_2 < 4; alpha_2++){ - spinor eta_u = arr_spinor[0][0][alpha_2][f0][f0][0]; - double dum1 = 0.0; // dummy variable - _spinor_scalar_prod(dum1, eta_u, psi_u); - double dum2 = 0.0; // dummy variable - spinor psi_h = arr_spinor[1][1][alpha_2][hj][hi][i]; - if (g2 == 0) { // Gamma_2 = \mathbb{1} - diag_G2g5[2] = -1.0; - diag_G2g5[3] = -1.0; + double complex dum_tot = 0.0; + for (int alpha_1 = 0; alpha_1 < 4; alpha_1++){ + for (int alpha_2 = 0; alpha_2 < 4; alpha_2++){ + // S_\ell + spinor psi_h = arr_spinor[1][1][alpha_1][hj][hi][i]; + if (g1 == 0){ // Gamma_1 = Id + _gamma5(psi_h, psi_h); + } + su3_vector psi_h_su3[4]; + spinor_dirac_array(&psi_h_su3[0], psi_h); + spinor psi_u_star = arr_spinor[1][0][alpha_2][f0][f0][i]; + if (g2 == 0){ // Gamma_2 = Id. NOTE: works because Gamma_2=Gamma_2* for Gamma_2=1,gamma_5 + _gamma5(psi_u_star, psi_u_star); } - _spinor_scalar_prod(dum2, eta_h, psi_h); - res_hihj_g1g2[hi][hj][g1][g2] += dum2*diag_G2g5[alpha_2]*dum1*diag_G1g5[alpha_1]; + su3_vector psi_u_star_su3[4]; + spinor_dirac_array(&psi_u_star_su3[0], psi_u_star); + complex double dum_12 = 0.0; + _colorvec_scalar_prod(dum_12, psi_u_star_su3[alpha_1], psi_h_su3[alpha_2]); + dum_tot =+ dum_12; } } - // restoring to default - diag_G2g5[2] = 1.0; - diag_G2g5[3] = 1.0; + res_hihj_g1g2[hi][hj][g1][g2] = creal(dum_tot); // correlators are real } - // restoring to default - diag_G1g5[2] = 1.0; - diag_G1g5[3] = 1.0; } } diff --git a/solver/dirac_operator_eigenvectors.h b/solver/dirac_operator_eigenvectors.h index b4ef212e1..6b7454533 100644 --- a/solver/dirac_operator_eigenvectors.h +++ b/solver/dirac_operator_eigenvectors.h @@ -265,6 +265,14 @@ int cyclicDiff(int a,int b, int period); conj((r).s3.c2) * (s).s3.c2; + +#define _colorvec_scalar_prod(proj,r,s)\ + (proj) = conj((r).c0) * (s).c0 + \ + conj((r).c1) * (s).c1; + \ + conj((r).c2) * (s).c2; + + + #define PROJECTSPLIT(p_plus,up_plus,col_proj,phi_o,phi_plus,col_phi)\ p_plus = 0; \ p_plus += conj(up_plus->s0.col_proj) * (phi_o->s0.col_phi); \ From 3926b0243ae0187ac18a2401e4464342e3ffcb0d Mon Sep 17 00:00:00 2001 From: simone-romiti Date: Fri, 26 Jan 2024 16:33:43 +0100 Subject: [PATCH 48/51] updated documentation for ndd correlators --- doc/omeas_heavy_mesons.qmd | 44 ++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/doc/omeas_heavy_mesons.qmd b/doc/omeas_heavy_mesons.qmd index c5081381a..b1ef91910 100644 --- a/doc/omeas_heavy_mesons.qmd +++ b/doc/omeas_heavy_mesons.qmd @@ -317,7 +317,7 @@ Therefore, we can approximate the correlators of eq. \eqref{eq:C.hihj.Gamma1Gamm \begin{equation} \begin{split} \mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) -= +&= \left( \eta^{(f_i, \alpha_1)}(0) \cdot @@ -328,37 +328,39 @@ Therefore, we can approximate the correlators of eq. \eqref{eq:C.hihj.Gamma1Gamm \eta^{(0, \alpha_3)}(0) \cdot \psi_u^{(0, \alpha_4)}(x) -\right) +\right)^{*} +(\gamma_5 \Gamma_1)_{\alpha_4 \alpha_1} +\\ +&= +(\psi_h)_{f_i, \alpha_1}^{(f_j, \alpha_2)}(x) +(\Gamma_2 \gamma_5)_{\alpha_2 \alpha_3} +(\psi_u)_{\alpha_3}^{(0, \alpha_4)}(x)^{*} (\gamma_5 \Gamma_1)_{\alpha_4 \alpha_1} \end{split} \end{equation} -In our case $\Gamma_{1/2} = 1, \gamma_5$, so that $\Gamma_i \gamma_5$ is diagonal in the Dirac indices. -Thus the correlator can be written as (explicit summation over the indices): +In the end we have: - \begin{equation} -\begin{split} \mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) = -\sum_{\alpha_{1}, \alpha_{2}} -\left( - \eta^{(f_i, \alpha_1)}(0) - \cdot - \psi_h^{(f_j, \alpha_2)}(x) -\right) -(\Gamma_2 \gamma_5)_{\alpha_2 \alpha_2} -\left( - \eta^{(0, \alpha_2)}(0) - \cdot - \psi_u^{(0, \alpha_1)}(x) -\right) -(\gamma_5 \Gamma_1)_{\alpha_1 \alpha_1} -\end{split} +[\Gamma_2 \gamma_5 (\psi_u)^{(0, \alpha_2)}(x)^{*}]_{\alpha_1} +[\gamma_5 \Gamma_1 (\psi_h)_{f_i}^{(f_j, \alpha_1)}(x) ]_{\alpha_2} +\end{equation} + +In our case $\Gamma_{1,2} = 1,\gamma_5$. Since we use the chiral basis ${\Gamma_{1,2}^{*} = (\Gamma_{1,2}^{T})^\dagger = \Gamma_{1,2}}$. +Therefore we can equivalently write the correlator as: + +\begin{equation} +\mathcal{C}^{h_i, h_j}_{\Gamma_1, \Gamma_2}(t, \vec{x}) += +[\Gamma_2 \gamma_5 (\psi_u)^{(0, \alpha_2)}(x)]^{*}_{\alpha_1} +\cdot +[\gamma_5 \Gamma_1 (\psi_h)_{f_i}^{(f_j, \alpha_1)}(x) ]_{\alpha_2} \, \end{equation} - +where $\cdot$ is the dot product in color space (NOTE: it complex-conjugates the 1st vector). From 56dd8125fb778a0a6ad0f257d0ba98fbb5207729 Mon Sep 17 00:00:00 2001 From: simone-romiti Date: Tue, 9 Apr 2024 22:50:27 +0200 Subject: [PATCH 49/51] small typo only for correlator at t=0 --- meas/correlators.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meas/correlators.c b/meas/correlators.c index 6f3c1060a..61504f43c 100644 --- a/meas/correlators.c +++ b/meas/correlators.c @@ -829,7 +829,7 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, for (size_t hj = 0; hj < 2; hj++) { for (size_t g1 = 0; g1 < 2; g1++) { for (size_t g2 = 0; g2 < 2; g2++) { - fprintf(ofs, "%u %u %u %u 0 %e %e\n", hi, hj, g1, g2, C_hihj_g1g2[hi][hj][g1][g1][t0], 0.0); + fprintf(ofs, "%u %u %u %u 0 %e %e\n", hi, hj, g1, g2, C_hihj_g1g2[hi][hj][g1][g2][t0], 0.0); for (t = 1; t < g_nproc_t * T / 2; t++) { tt = (t0 + t) % (g_nproc_t * T); fprintf(ofs, "%u %u %u %u %d %e ", hi, hj, g1, g2, t, C_hihj_g1g2[hi][hj][g1][g2][tt]); From 4b5e0cd258d83e663dd66d4d18d2d38022a13fdd Mon Sep 17 00:00:00 2001 From: simone-romiti Date: Wed, 10 Apr 2024 14:34:17 +0200 Subject: [PATCH 50/51] typo: =+ instead of += --- meas/correlators.c | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/meas/correlators.c b/meas/correlators.c index 61504f43c..245e42020 100644 --- a/meas/correlators.c +++ b/meas/correlators.c @@ -679,21 +679,20 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, resp4 += _spinor_prod_im(psi_u, phi); } - // heavy correlators + // heavy correlators for (size_t hi = 0; hi < 2; hi++) { for (size_t hj = 0; hj < 2; hj++) { for (size_t g1 = 0; g1 < 2; g1++) { for (size_t g2 = 0; g2 < 2; g2++) { double complex dum_tot = 0.0; for (int alpha_1 = 0; alpha_1 < 4; alpha_1++){ + spinor psi_h = arr_spinor[1][1][alpha_1][hj][hi][i]; + if (g1 == 0){ // Gamma_1 = Id + _gamma5(psi_h, psi_h); + } + su3_vector psi_h_su3[4]; + spinor_dirac_array(&psi_h_su3[0], psi_h); for (int alpha_2 = 0; alpha_2 < 4; alpha_2++){ - // S_\ell - spinor psi_h = arr_spinor[1][1][alpha_1][hj][hi][i]; - if (g1 == 0){ // Gamma_1 = Id - _gamma5(psi_h, psi_h); - } - su3_vector psi_h_su3[4]; - spinor_dirac_array(&psi_h_su3[0], psi_h); spinor psi_u_star = arr_spinor[1][0][alpha_2][f0][f0][i]; if (g2 == 0){ // Gamma_2 = Id. NOTE: works because Gamma_2=Gamma_2* for Gamma_2=1,gamma_5 _gamma5(psi_u_star, psi_u_star); @@ -702,10 +701,24 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, spinor_dirac_array(&psi_u_star_su3[0], psi_u_star); complex double dum_12 = 0.0; _colorvec_scalar_prod(dum_12, psi_u_star_su3[alpha_1], psi_h_su3[alpha_2]); - dum_tot =+ dum_12; + dum_tot += dum_12; + } + } + // if (g_proc_id == 0){ + // printf("dum_tot = %d %d %d %d %d %e %e \n", t, hi, hj, g1, g2, creal(dum_tot), cimag(dum_tot)); + // } + if (hi != hj){ + dum_tot *= -1; + } + if (g1==g2){ + res_hihj_g1g2[hi][hj][g1][g2] = creal(dum_tot); // correlators is real + } + else{ + if (g2==1){ + dum_tot *= -1; } + res_hihj_g1g2[hi][hj][g1][g2] = cimag(dum_tot); // correlator is imaginary } - res_hihj_g1g2[hi][hj][g1][g2] = creal(dum_tot); // correlators are real } } } @@ -829,6 +842,7 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, for (size_t hj = 0; hj < 2; hj++) { for (size_t g1 = 0; g1 < 2; g1++) { for (size_t g2 = 0; g2 < 2; g2++) { + printf("check matrix: %e\n", C_hihj_g1g2[hi][hj][g1][g2][3]); fprintf(ofs, "%u %u %u %u 0 %e %e\n", hi, hj, g1, g2, C_hihj_g1g2[hi][hj][g1][g2][t0], 0.0); for (t = 1; t < g_nproc_t * T / 2; t++) { tt = (t0 + t) % (g_nproc_t * T); From c713145dc7265cbac75d95a55972d30ffd8249a3 Mon Sep 17 00:00:00 2001 From: Marcogarofalo Date: Fri, 27 Sep 2024 23:30:33 +0200 Subject: [PATCH 51/51] volume average for heavy correlators --- meas/correlators.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/meas/correlators.c b/meas/correlators.c index 245e42020..8aa929f3c 100644 --- a/meas/correlators.c +++ b/meas/correlators.c @@ -665,7 +665,15 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, res = 0.0; respa = 0.0; resp4 = 0.0; - + for (size_t hi = 0; hi < 2; hi++) { + for (size_t hj = 0; hj < 2; hj++) { + for (size_t g1 = 0; g1 < 2; g1++) { + for (size_t g2 = 0; g2 < 2; g2++) { + res_hihj_g1g2[hi][hj][g1][g2] = 0.0; + } + } + } + } for (i = j; i < j + LX * LY * LZ; i++) { // light correlators @@ -711,13 +719,13 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, dum_tot *= -1; } if (g1==g2){ - res_hihj_g1g2[hi][hj][g1][g2] = creal(dum_tot); // correlators is real + res_hihj_g1g2[hi][hj][g1][g2] += creal(dum_tot); // correlators is real } else{ if (g2==1){ dum_tot *= -1; } - res_hihj_g1g2[hi][hj][g1][g2] = cimag(dum_tot); // correlator is imaginary + res_hihj_g1g2[hi][hj][g1][g2] += cimag(dum_tot); // correlator is imaginary } } } @@ -744,7 +752,6 @@ void heavy_correlators_measurement(const int traj, const int id, const int ieo, Cp4[t] = +resp4 / vol_fact / 2.0 / optr1->kappa / optr1->kappa; #endif - printf("%d: Checkpoint 11.5\n", g_proc_id); for (size_t hi = 0; hi < 2; hi++) { for (size_t hj = 0; hj < 2; hj++) {