void ov_check_operator(int t, int x, int y, int z) { /* Create delta source at origin */ source_spinor_field(g_spinor_field[1], g_spinor_field[0], 0, 0); convert_eo_to_lexic(g_spinor_field[2], g_spinor_field[1], g_spinor_field[0]); /* Evaluate Dov(psi) */ Dov_psi(g_spinor_field[3], g_spinor_field[2]); ov_print_spinor(&g_spinor_field[3][g_ipt[t][x][y][z]]); }
int main(int argc,char *argv[]) { FILE *parameterfile=NULL; int c, j, is=0, ic=0; int x, X, y, Y, z, Z, t, tt, i, sum; char * filename = NULL; char datafilename[50]; char parameterfilename[50]; char conf_filename[50]; char * input_filename = NULL; double plaquette_energy, nrm; double * norm; struct stout_parameters params_smear; #ifdef _GAUGE_COPY int kb=0; #endif #ifdef MPI double atime=0., etime=0.; #endif #ifdef _KOJAK_INST #pragma pomp inst init #pragma pomp inst begin(main) #endif DUM_DERI = 6; /* DUM_DERI + 2 is enough (not 7) */ DUM_SOLVER = DUM_DERI+2; DUM_MATRIX = DUM_SOLVER+6; /* DUM_MATRIX + 2 is enough (not 6) */ NO_OF_SPINORFIELDS = DUM_MATRIX+2; verbose = 0; g_use_clover_flag = 0; g_nr_of_psf = 1; #ifdef MPI MPI_Init(&argc, &argv); #endif while ((c = getopt(argc, argv, "h?f:o:")) != -1) { switch (c) { case 'f': input_filename = calloc(200, sizeof(char)); strcpy(input_filename,optarg); break; case 'o': filename = calloc(200, sizeof(char)); strcpy(filename,optarg); break; case 'h': case '?': default: usage(); break; } } if(input_filename == NULL){ input_filename = "hmc.input"; } if(filename == NULL){ filename = "output"; } /* Read the input file */ read_input(input_filename); /* here we want no even/odd preconditioning */ even_odd_flag = 0; /* this DBW2 stuff is not needed for the inversion ! */ g_rgi_C1 = 0; if(Nsave == 0){ Nsave = 1; } tmlqcd_mpi_init(argc, argv); g_dbw2rand = 0; #ifndef MPI g_dbw2rand = 0; #endif #ifdef _GAUGE_COPY j = init_gauge_field(VOLUMEPLUSRAND, 1); #else j = init_gauge_field(VOLUMEPLUSRAND, 0); #endif if ( j!= 0) { fprintf(stderr, "Not enough memory for gauge_fields! Aborting...\n"); exit(-1); } j = init_geometry_indices(VOLUMEPLUSRAND); if ( j!= 0) { fprintf(stderr, "Not enough memory for geometry indices! Aborting...\n"); exit(-1); } if(even_odd_flag) { j = init_spinor_field(VOLUMEPLUSRAND/2, NO_OF_SPINORFIELDS); } else { j = init_spinor_field(VOLUMEPLUSRAND, NO_OF_SPINORFIELDS); } if ( j!= 0) { fprintf(stderr, "Not enough memory for spinor fields! Aborting...\n"); exit(-1); } g_mu = g_mu1; if(g_proc_id == 0){ /*construct the filenames for the observables and the parameters*/ strcpy(datafilename,filename); strcat(datafilename,".data"); strcpy(parameterfilename,filename); strcat(parameterfilename,".para"); parameterfile=fopen(parameterfilename, "w"); write_first_messages(parameterfile, 0, 1); } /* define the geometry */ geometry(); /* define the boundary conditions for the fermion fields */ boundary(); #ifdef _USE_HALFSPINOR j = init_dirac_halfspinor(); if ( j!= 0) { fprintf(stderr, "Not enough memory for halffield! Aborting...\n"); exit(-1); } if(g_sloppy_precision_flag == 1) { j = init_dirac_halfspinor32(); if ( j!= 0) { fprintf(stderr, "Not enough memory for 32-Bit halffield! Aborting...\n"); exit(-1); } } # if (defined _PERSISTENT) init_xchange_halffield(); # endif #endif norm = (double*)calloc(3.*LX/2.+T/2., sizeof(double)); for(j=0;j<Nmeas; j++) { sprintf(conf_filename,"%s.%.4d", gauge_input_filename, nstore); if (g_proc_id == 0){ printf("Reading Gauge field from file %s\n", conf_filename); fflush(stdout); } read_lime_gauge_field(conf_filename); if (g_proc_id == 0){ printf("done!\n"); fflush(stdout); } #ifdef MPI xchange_gauge(); #endif #ifdef _GAUGE_COPY update_backward_gauge(); #endif /* Compute minimal eigenvalues, if wanted */ if(compute_evs != 0) { eigenvalues(&no_eigenvalues, 1000, eigenvalue_precision, 0, compute_evs, nstore, even_odd_flag); } /*compute the energy of the gauge field*/ plaquette_energy = measure_gauge_action(); if(g_proc_id == 0) { printf("The plaquette value is %e\n", plaquette_energy/(6.*VOLUME*g_nproc)); fflush(stdout); } if (use_stout_flag == 1){ params_smear.rho = stout_rho; params_smear.iterations = stout_no_iter; if (stout_smear((su3_tuple*)(g_gauge_field[0]), ¶ms_smear, (su3_tuple*)(g_gauge_field[0])) != 0) exit(1) ; g_update_gauge_copy = 1; g_update_gauge_energy = 1; g_update_rectangle_energy = 1; plaquette_energy = measure_gauge_action(); if (g_proc_id == 0) { printf("# The plaquette value after stouting is %e\n", plaquette_energy / (6.*VOLUME*g_nproc)); fflush(stdout); } } source_spinor_field(g_spinor_field[0], g_spinor_field[1], 0, 0); convert_eo_to_lexic(g_spinor_field[DUM_DERI], g_spinor_field[0], g_spinor_field[1]); D_psi(g_spinor_field[DUM_DERI+1], g_spinor_field[DUM_DERI]); if(even_odd_flag) { i = invert_eo(g_spinor_field[2], g_spinor_field[3], g_spinor_field[0], g_spinor_field[1], solver_precision, max_solver_iterations, solver_flag, g_relative_precision_flag, sub_evs_cg_flag, even_odd_flag); convert_eo_to_lexic(g_spinor_field[DUM_DERI+1], g_spinor_field[2], g_spinor_field[3]); } for(i = 0; i < 3*LX/2+T/2; i++){ norm[i] = 0.; } for(x = 0; x < LX; x++){ if(x > LX/2) X = LX-x; else X = x; for(y = 0; y < LY; y++){ if(y > LY/2) Y = LY-y; else Y = y; for(z = 0; z < LZ; z++){ if(z > LZ/2) Z = LZ-z; else Z = z; for(t = 0; t < T; t++){ if(t > T/2) tt = T - t; else tt = t; sum = X + Y + Z + tt; _spinor_norm_sq(nrm, g_spinor_field[DUM_DERI+1][ g_ipt[t][x][y][z] ]); /* _spinor_norm_sq(nrm, qprop[0][0][1][ g_ipt[t][x][y][z] ]); */ printf("%e %e\n", g_spinor_field[DUM_DERI+1][ g_ipt[t][x][y][z] ].s0.c0.re, g_spinor_field[DUM_DERI+1][ g_ipt[t][x][y][z] ].s0.c0.im); nrm = sqrt( nrm ); printf("%1.12e\n", nrm); if(nrm > norm[sum]) norm[sum] = nrm; } } } } for(i = 0; i < 3*L/2+T/2; i++){ printf("%d %1.12e\n", i, norm[i]); } printf("\n"); nstore+=Nsave; } #ifdef MPI MPI_Finalize(); #endif free_gauge_field(); free_geometry_indices(); free_spinor_field(); free_moment_field(); return(0); #ifdef _KOJAK_INST #pragma pomp inst end(main) #endif }
void prepare_source(const int nstore, const int isample, const int ix, const int op_id, const int read_source_flag, const int source_location) { FILE * ifs = NULL; int is = ix / 3, ic = ix %3, err = 0, rstat=0, t = 0; operator * optr = &operator_list[op_id]; char source_filename[100]; int source_type = SourceInfo.type; static int nstore_ = -1; static int isample_ = -1; static int ix_ = -1; static int op_id_ = -1; SourceInfo.nstore = nstore; SourceInfo.sample = isample; SourceInfo.ix = ix; if(optr->type != DBTMWILSON && optr->type != DBCLOVER && optr->type != BSM && optr->type != BSM2b && optr->type != BSM2m ) { SourceInfo.no_flavours = 1; /* no volume sources */ if(source_type != 1) { /* either "Don't read inversion source from file" or */ /* "Don't read inversion source from file, but save the one generated" */ if (read_source_flag == 0 || read_source_flag == 2) { if (source_location == 0) { source_spinor_field(g_spinor_field[0], g_spinor_field[1], is, ic); } else { source_spinor_field_point_from_file(g_spinor_field[0], g_spinor_field[1], is, ic, source_location); } } /* "Read inversion source from file" */ else { if (SourceInfo.splitted) { /* timeslice needs to be put into filename */ if(SourceInfo.automaticTS) { /* automatic timeslice detection */ if(g_proc_id == 0) { for(t = 0; t < g_nproc_t*T; t++) { if(T_global > 99) sprintf(source_filename, "%s.%.4d.%.3d.%.2d", SourceInfo.basename, nstore, t, ix); else sprintf(source_filename, "%s.%.4d.%.2d.%.2d", SourceInfo.basename, nstore, t, ix); if( (ifs = fopen(source_filename, "r")) != NULL) { fclose(ifs); break; } } } #ifdef MPI MPI_Bcast(&t, 1, MPI_INT, 0, MPI_COMM_WORLD); #endif SourceInfo.t = t; } if(T_global > 99) sprintf(source_filename, "%s.%.4d.%.3d.%.2d", SourceInfo.basename, nstore, SourceInfo.t, ix); else sprintf(source_filename, "%s.%.4d.%.2d.%.2d", SourceInfo.basename, nstore, SourceInfo.t, ix); if (g_cart_id == 0) { printf("# Trying to read source from %s\n", source_filename); } rstat = read_spinor(g_spinor_field[0], g_spinor_field[1], source_filename, 0); } else { sprintf(source_filename, "%s", SourceInfo.basename); if (g_cart_id == 0) { printf("# Trying to read source no %d from %s\n", ix, source_filename); } rstat = read_spinor(g_spinor_field[0], g_spinor_field[1], source_filename, ix); } if(rstat) { fprintf(stderr, "Error reading file %s in prepare_source.c\nUnable to proceed, aborting....\n", source_filename); exit(-1); } } if (PropInfo.splitted) { if(T_global > 99) sprintf(source_filename, "%s.%.4d.%.3d.%.2d.inverted", PropInfo.basename, nstore, SourceInfo.t, ix); else sprintf(source_filename, "%s.%.4d.%.2d.%.2d.inverted", PropInfo.basename, nstore, SourceInfo.t, ix); } else { if(T_global > 99) sprintf(source_filename, "%s.%.4d.%.3d.inverted", PropInfo.basename, nstore, SourceInfo.t); else sprintf(source_filename, "%s.%.4d.%.2d.inverted", PropInfo.basename, nstore, SourceInfo.t); } } else if(source_type == 1) { /* Volume sources */ if(read_source_flag == 0 || read_source_flag == 2) { if(g_proc_id == 0 && g_debug_level > 0) { printf("# Preparing 1 flavour volume source\n"); } gaussian_volume_source(g_spinor_field[0], g_spinor_field[1], isample, nstore, 0); } else { sprintf(source_filename, "%s.%.4d.%.5d", SourceInfo.basename, nstore, isample); if (g_cart_id == 0) { printf("# Trying to read source from %s\n", source_filename); } rstat = read_spinor(g_spinor_field[0], g_spinor_field[1], source_filename, 0); if(rstat) { fprintf(stderr, "Error reading file %s in prepare_source.c.\nUnable to proceed, aborting....\n", source_filename); exit(-1); } } sprintf(source_filename, "%s.%.4d.%.5d.inverted", PropInfo.basename, nstore, isample); } optr->sr0 = g_spinor_field[0]; optr->sr1 = g_spinor_field[1]; optr->prop0 = g_spinor_field[2]; optr->prop1 = g_spinor_field[3]; /* If the solver is _not_ CG we might read in */ /* here some better guess */ /* This also works for re-iteration */ if (optr->solver != CG && optr->solver != PCG && optr->solver != MIXEDCG && optr->solver != RGMIXEDCG) { ifs = fopen(source_filename, "r"); if (ifs != NULL) { if (g_cart_id == 0) { printf("# Trying to read guess from file %s\n", source_filename); fflush(stdout); } fclose(ifs); err = 0; /* iter = get_propagator_type(source_filename); */ rstat = read_spinor(optr->prop0, optr->prop1, source_filename, (PropInfo.splitted ? 0 : ix)); if(rstat) { fprintf(stderr, "Error reading file %s in prepare_source.c, rstat = %d\n", source_filename, rstat); exit(-1); } if (g_kappa != 0.) { mul_r(optr->prop1, 1. / (2*optr->kappa), optr->prop1, VOLUME / 2); mul_r(optr->prop0, 1. / (2*optr->kappa), optr->prop0, VOLUME / 2); } if (err != 0) { zero_spinor_field(optr->prop0, VOLUME / 2); zero_spinor_field(optr->prop1, VOLUME / 2); } } else { zero_spinor_field(optr->prop0, VOLUME / 2); zero_spinor_field(optr->prop1, VOLUME / 2); } } else { zero_spinor_field(optr->prop0, VOLUME / 2); zero_spinor_field(optr->prop1, VOLUME / 2); } /* if(optr->even_odd_flag) { */ /* assign(optr->sr0, g_spinor_field[0], VOLUME/2); */ /* assign(optr->sr1, g_spinor_field[1], VOLUME/2); */ /* } */ /* else { */ /* convert_eo_to_lexic(optr->sr0, g_spinor_field[0], g_spinor_field[1]); */ /* } */ } else { /* for the ND 2 flavour twisted operator and BSM(2) */ SourceInfo.no_flavours = 2; zero_spinor_field(g_spinor_field[0], VOLUME/2); zero_spinor_field(g_spinor_field[1], VOLUME/2); if(source_type != 1) { if(read_source_flag == 0 || read_source_flag == 2) { if(source_location == 0) { source_spinor_field(g_spinor_field[2], g_spinor_field[3], is, ic); } else { source_spinor_field_point_from_file(g_spinor_field[2], g_spinor_field[3], is, ic, source_location); } } else { if(SourceInfo.splitted) { if(T_global > 99) sprintf(source_filename, "%s.%.4d.%.3d.%.2d", SourceInfo.basename, nstore, SourceInfo.t, ix); else sprintf(source_filename, "%s.%.4d.%.2d.%.2d", SourceInfo.basename, nstore, SourceInfo.t, ix); } else { sprintf(source_filename,"%s", SourceInfo.basename); } if(g_proc_id == 0) { printf("# Trying to read source from %s\n", source_filename); } if(read_spinor(g_spinor_field[2], g_spinor_field[3], source_filename, 0) != 0) { fprintf(stderr, "Error reading source! Aborting...\n"); #ifdef MPI MPI_Abort(MPI_COMM_WORLD, 1); MPI_Finalize(); #endif exit(-1); } } } else if(source_type == 1) { /* Volume sources */ if(g_proc_id == 0 && g_debug_level > 0) { printf("# Preparing 2 flavour volume source\n"); } gaussian_volume_source(g_spinor_field[0], g_spinor_field[1], isample, nstore, 1); gaussian_volume_source(g_spinor_field[2], g_spinor_field[3], isample, nstore, 2); } if( optr->type != BSM && optr->type != BSM2b && optr->type != BSM2m ) { 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); 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); assign(g_spinor_field[3], g_spinor_field[7], VOLUME/2); } optr->sr0 = g_spinor_field[0]; optr->sr1 = g_spinor_field[1]; optr->sr2 = g_spinor_field[2]; optr->sr3 = g_spinor_field[3]; optr->prop0 = g_spinor_field[4]; optr->prop1 = g_spinor_field[5]; optr->prop2 = g_spinor_field[6]; optr->prop3 = g_spinor_field[7]; } nstore_ = nstore; isample_ = isample; ix_ = ix; op_id_ = op_id; return; }
/* Checks GW relation only by applying Dov to delta(0,0) */ void ov_check_ginsparg_wilson_relation(void) { double norm_diff, norm_left, norm_right, norm, max_rel = 0.0, min_left = 1.0e100, min_right = 1.0e100, max_diff = 0.0, min_norm = 1.0e100; int x, y, z, t, i; spinor *S_left, *S_right, *S_diff; /* get memory for the spinor fields */ S_left = ov_alloc_spinor(); S_right = ov_alloc_spinor(); S_diff = ov_alloc_spinor(); /* Create delta source at origin */ source_spinor_field(g_spinor_field[1], g_spinor_field[0], 0, 0); convert_eo_to_lexic(g_spinor_field[2], g_spinor_field[1], g_spinor_field[0]); /* S_right = D gamma_5 D */ Dov_psi(g_spinor_field[3], g_spinor_field[2]); gamma5(S_left, g_spinor_field[3], VOLUME); Dov_psi(S_right, S_left); /* S_left = {gamma_5, D} */ gamma5(g_spinor_field[3], g_spinor_field[2], VOLUME); Dov_psi(g_spinor_field[4], g_spinor_field[3]); add(S_left, S_left, g_spinor_field[4], VOLUME); /* S_diff = S_left-S_right */ diff(S_diff, S_left, S_right, VOLUME); /* scan the whole lattice */ printf("// test of the Ginsparg-Wilson relation\n"); for(x=0; x<LX; x++) for(y = 0; y < LY; y++) for(z = 0; z < LZ; z++) for(t = 0; t < T; t++) { i = g_ipt[t][x][y][z]; _spinor_norm_sq(norm_diff, S_diff[i]); _spinor_norm_sq(norm_left, S_left[i]); _spinor_norm_sq(norm_right, S_right[i]); norm_diff = sqrt(norm_diff); norm_left = sqrt(norm_left); norm_right = sqrt(norm_right); norm = norm_left+norm_right; if (norm < min_norm) min_norm = norm; if (norm > 0.0) { norm = 2.*norm_diff/norm; if (norm > max_rel) max_rel = norm; } if (norm_left < min_left) min_left = norm_left; if (norm_right < min_right) min_right = norm_right; if (norm_diff > max_diff) max_diff = norm_diff; } /* print results */ printf(" - maximum absoulte deviation: %.4le\n", max_diff); printf(" - maximum relative deviation: %.4le\n", max_rel); printf(" - minimum mean norm: %4.le\n", min_norm); printf(" - minimum norm {gamma_5, D}: %.4le\n", min_left); printf(" - minimum norm D gamma_5 D: %.4le\n", min_right); /* free memory */ ov_free_spinor(S_left); ov_free_spinor(S_right); ov_free_spinor(S_diff); }
/* Check GW relation with operator norm over the full lattice */ void ov_check_ginsparg_wilson_relation_strong(void) { double norm_diff, norm_left, norm_right, norm, max_rel = 0.0, min_left = 1.0e100, min_right = 1.0e100, max_diff = 0.0, min_norm = 1.0e100; int x, y, z, t, i, j, k; spinor *S_left[4][3], *S_right[4][3], *S_diff[4][3]; if (g_debug_level>0) { printf("// creating spinor fields and calculating {gamma_5,D} psi and a D gamma_5 D psi\n"); fflush(stdout); } for (i=0; i<4; i++) for (j=0; j<3; j++) { if (g_debug_level>1) { printf("// spinor field: delta_dirac at %d, delta_color at %d\n", i, j); fflush(stdout); } /* get memory for the spinor */ S_left[i][j] = ov_alloc_spinor(); S_right[i][j] = ov_alloc_spinor(); S_diff[i][j] = ov_alloc_spinor(); /* Create delta source at origin */ source_spinor_field(g_spinor_field[1], g_spinor_field[0], i, j); convert_eo_to_lexic(g_spinor_field[2], g_spinor_field[1], g_spinor_field[0]); /* S_right = D gamma_5 D psi */ Dov_psi(g_spinor_field[3], g_spinor_field[2]); gamma5(S_left[i][j], g_spinor_field[3], VOLUME); Dov_psi(S_right[i][j], S_left[i][j]); /* S_left = {gamma_5, D} psi */ gamma5(g_spinor_field[3], g_spinor_field[2], VOLUME); Dov_psi(g_spinor_field[4], g_spinor_field[3]); add(S_left[i][j], S_left[i][j], g_spinor_field[4], VOLUME); /* S_diff = (S_left-S_right) psi, should be zero (GW relation) */ diff(S_diff[i][j], S_left[i][j], S_right[i][j], VOLUME); } /* scan the whole lattice and check GW relation */ printf("// test of the Ginsparg-Wilson relation:\n"); if (g_debug_level>0) fflush(stdout); for(x=0; x<LX; x++) for(y = 0; y < LY; y++) for(z = 0; z < LZ; z++) for(t = 0; t < T; t++) { k = g_ipt[t][x][y][z]; norm_diff = ov_operator_colsumnorm(S_diff, k); norm_left = ov_operator_colsumnorm(S_left, k); norm_right = ov_operator_colsumnorm(S_right, k); norm = (norm_left+norm_right)/2.; if (norm < min_norm) min_norm = norm; if (norm > 0.0) { norm = norm_diff/norm; if (norm > max_rel) max_rel = norm; if ((norm > 1.8) && (g_debug_level)>=5) { printf("(%d,%d,%d,%d): taxi = %d, rel = %.20le, lr = [%.4le, %.4le], diff = %.4le\n", t, x, y, z, ((x>LX/2) ? LX-x : x)+((y>LY/2) ? LY-y : y)+((z>LZ/2) ? LZ-z : z)+((t>T/2) ? T-t : t), norm, norm_left, norm_right, norm_diff); printf("// left[0][0]:\n"); ov_print_spinor(&S_left[0][0][k]); printf("// right[0][0]:\n"); ov_print_spinor(&S_right[0][0][k]); printf("// diff[0][0]:\n"); ov_print_spinor(&S_diff[0][0][k]); } } if (norm_left < min_left) min_left = norm_left; if (norm_right < min_right) min_right = norm_right; if (norm_diff > max_diff) max_diff = norm_diff; } /* print results */ printf(" - maximum absolute deviation: %.4le\n", max_diff); printf(" - maximum relative deviation: %.4le\n", max_rel); printf(" - minimum mean norm: %.4le\n", min_norm); printf(" - minimum norm {gamma_5, D}: %.4le\n", min_left); printf(" - minimum norm D gamma_5 D: %.4le\n", min_right); /* free memory */ for (i=0; i<4; i++) for (j=0; j<3; j++) { ov_free_spinor(S_left[i][j]); ov_free_spinor(S_right[i][j]); ov_free_spinor(S_diff[i][j]); } }
/* saves the operator to the given filename */ void ov_save_12x12(const char * pFileName) { int i, j, k, x, y, z, t; spinor *s[4][3]; matrix12x12 mat; FILE * pCompare; /* evaluate Dov(psi) */ for (i=0; i<4; i++) for (j=0; j<3; j++) { /* get memory for the spinor */ s[i][j] = ov_alloc_spinor(); /* create delta source at origin */ source_spinor_field(g_spinor_field[1], g_spinor_field[0], i, j); convert_eo_to_lexic(g_spinor_field[2], g_spinor_field[1], g_spinor_field[0]); /* apply Dov */ Dov_psi(s[i][j], g_spinor_field[2]); } /* open file for storing the operator */ pCompare = fopen(pFileName, "w"); if (pCompare == NULL) { fprintf(stderr, "Error: could not open '%s' for writing the operator\n", pFileName); exit(1); } for(t = 0; t < T; t++){ for(x = 0; x < LX; x++){ for(y = 0; y < LY; y++){ for(z=0; z<LZ; z++) { k = g_ipt[t][x][y][z]; for (j=0; j<3; j++) for (i=0; i<4; i++) { mat[0][i+4*j] = s[i][j][k].s0.c0; mat[1][i+4*j] = s[i][j][k].s1.c0; mat[2][i+4*j] = s[i][j][k].s2.c0; mat[3][i+4*j] = s[i][j][k].s3.c0; mat[4][i+4*j] = s[i][j][k].s0.c1; mat[5][i+4*j] = s[i][j][k].s0.c1; mat[6][i+4*j] = s[i][j][k].s1.c1; mat[7][i+4*j] = s[i][j][k].s2.c1; mat[8][i+4*j] = s[i][j][k].s3.c2; mat[9][i+4*j] = s[i][j][k].s1.c2; mat[10][i+4*j] = s[i][j][k].s2.c2; mat[11][i+4*j] = s[i][j][k].s3.c2; } for (i=0;i<12; i++) for (j=0; j<12; j++) fprintf(pCompare, "%.20le %.20le ", creal(mat[i][j]), cimag(mat[i][j])); } } } } /* close file */ fclose(pCompare); /* free memory */ for (i=0; i<4; i++) for (j=0; j<3; j++) ov_free_spinor(s[i][j]); }
/* compares the operator with the one given in pFileName */ void ov_compare_12x12(const char * pFileName) { double norm, rel, *max_rel, *max_abs, Max_rel = 0.0, Max_abs = 0.0; int i, j, k, x, x_taxi, y, y_taxi, z, z_taxi, t, t_taxi, maxtaxi, taxi; spinor *s[4][3]; matrix12x12 mat, mat2, diff; FILE * pCompare; /* evaluate Dov(psi) */ for (i=0; i<4; i++) for (j=0; j<3; j++) { /* get memory for the spinor */ s[i][j] = ov_alloc_spinor(); /* create delta source at origin */ source_spinor_field(g_spinor_field[1], g_spinor_field[0], i, j); convert_eo_to_lexic(g_spinor_field[2], g_spinor_field[1], g_spinor_field[0]); /* apply Dov */ Dov_psi(s[i][j], g_spinor_field[2]); } /* init locality table */ maxtaxi = (LX/2)+(LY/2)+(LZ/2)+T/2; max_abs = (double*)calloc(maxtaxi+1, sizeof(double)); max_rel = (double*)calloc(maxtaxi+1, sizeof(double)); for(i = 0; i <= maxtaxi; i++) { max_abs[i] = 0.0; max_rel[i] = 0.0; } /* open file containing operator for comparison */ pCompare = fopen(pFileName, "r"); if (pCompare == NULL) { fprintf(stderr, "Error: could not open '%s' for comparison of operator\n", pFileName); exit(1); } /* fill locality table */ if (g_debug_level > 0) { printf("// beginning comparison\n"); fflush(stdout); } for(t = 0; t < T; t++){ t_taxi = (t > T/2) ? T - t : t; for(x = 0; x < LX; x++){ x_taxi = (x > LX/2) ? LX-x : x; for(y = 0; y < LY; y++){ y_taxi = (y > LY/2) ? LY-y : y; for(z=0; z<LZ; z++) { z_taxi = (z > LZ/2) ? LZ-z : z; taxi = x_taxi + y_taxi + z_taxi + t_taxi; k = g_ipt[t][x][y][z]; for (j=0; j<3; j++) for (i=0; i<4; i++) { mat[0][i+4*j] = s[i][j][k].s0.c0; mat[1][i+4*j] = s[i][j][k].s1.c0; mat[2][i+4*j] = s[i][j][k].s2.c0; mat[3][i+4*j] = s[i][j][k].s3.c0; mat[4][i+4*j] = s[i][j][k].s0.c1; mat[5][i+4*j] = s[i][j][k].s0.c1; mat[6][i+4*j] = s[i][j][k].s1.c1; mat[7][i+4*j] = s[i][j][k].s2.c1; mat[8][i+4*j] = s[i][j][k].s3.c2; mat[9][i+4*j] = s[i][j][k].s1.c2; mat[10][i+4*j] = s[i][j][k].s2.c2; mat[11][i+4*j] = s[i][j][k].s3.c2; } for (i=0;i<12; i++) for (j=0; j<12; j++) fscanf(pCompare, "%le %le", (double*)&mat2[i][j], (double*)&mat2[i][j] + 1); ov_matrix12x12_diff(diff, mat, mat2); /* statistics */ norm = ov_matrix12x12_rowsumnorm(diff); if (norm > max_abs[taxi]) { max_abs[taxi] = norm; if (norm > Max_abs) Max_abs = norm; } rel = (ov_matrix12x12_rowsumnorm(mat) + ov_matrix12x12_rowsumnorm(mat2))/2; if (rel>0.0) { rel = norm/rel; if (rel > max_rel[taxi]) { max_rel[taxi] = rel; if (rel > Max_rel) Max_rel = rel; } } } } } } /* print locality table */ printf("// comparison of overlap operator to %s\n", pFileName); printf(" - maximum absolute deviation: %.4le\n", Max_abs); printf(" - maximum relative deviation: %.4le\n", Max_rel); printf("// taxi | max abs | max rel\n"); for(i = 0; i <= maxtaxi; i++) printf("%7d %10.6le %10.6le\n", i, max_abs[i], max_rel[i]); printf("\n"); /* close file */ fclose(pCompare); /* free memory */ free(max_abs); free(max_rel); for (i=0; i<4; i++) for (j=0; j<3; j++) ov_free_spinor(s[i][j]); }
void ov_check_locality() { double norm, *maxnorm, *minnorm, *avgnorm; int i, j, k, x, x_taxi, y, y_taxi, z, z_taxi, t, t_taxi, maxtaxi, *samples, taxi; spinor *s[4][3]; /* evaluate Dov(psi) */ for (i=0; i<4; i++) for (j=0; j<3; j++) { /* get memory for the spinor */ s[i][j] = ov_alloc_spinor(); /* create delta source at origin */ source_spinor_field(g_spinor_field[1], g_spinor_field[0], i, j); convert_eo_to_lexic(g_spinor_field[2], g_spinor_field[1], g_spinor_field[0]); /* apply Dov */ Dov_psi(s[i][j], g_spinor_field[2]); } /* init locality table */ maxtaxi = (LX/2)+(LY/2)+(LZ/2)+T/2; maxnorm = (double*)calloc(maxtaxi+1, sizeof(double)); minnorm = (double*)calloc(maxtaxi+1, sizeof(double)); avgnorm = (double*)calloc(maxtaxi+1, sizeof(double)); samples = (int*)calloc(maxtaxi+1, sizeof(int)); for(i = 0; i <= maxtaxi; i++) { maxnorm[i] = 0.; minnorm[i] = 1.0e100; avgnorm[i] = 0.; samples[i] = 0; } /* fill locality table */ printf("// beginning locality test\n"); for(x=0; x<LX; x++) { x_taxi = (x > LX/2) ? LX-x : x; for(y = 0; y < LY; y++){ y_taxi = (y > LY/2) ? LY-y : y; for(z = 0; z < LZ; z++){ z_taxi = (z > LZ/2) ? LZ-z : z; for(t = 0; t < T; t++){ t_taxi = (t > T/2) ? T - t : t; taxi = x_taxi + y_taxi + z_taxi + t_taxi; k = g_ipt[t][x][y][z]; norm = ov_operator_colsumnorm(s, k); // statistics if (norm > maxnorm[taxi]) maxnorm[taxi] = norm; if (norm < minnorm[taxi]) minnorm[taxi] = norm; avgnorm[taxi] += norm; samples[taxi]++; } } } } /* print locality table */ printf("// locality check of overlap operator\n"); printf("// taxi | max norm | avg norm | min norm | #samples\n"); for(i = 0; i <= maxtaxi; i++) printf("%7d %10.6le %10.6le %10.6le %8d\n", i, maxnorm[i], (double)(avgnorm[i]/samples[i]), minnorm[i], samples[i]); printf("\n"); /* free memory */ free(maxnorm); free(minnorm); free(avgnorm); free(samples); for (i=0; i<4; i++) for (j=0; j<3; j++) ov_free_spinor(s[i][j]); }