void op_invert(const int op_id, const int index_start, const int write_prop) { operator * optr = &operator_list[op_id]; double atime = 0., etime = 0., nrm1 = 0., nrm2 = 0.; int i; optr->iterations = 0; optr->reached_prec = -1.; g_kappa = optr->kappa; boundary(g_kappa); atime = gettime(); if(optr->type == TMWILSON || optr->type == WILSON || optr->type == CLOVER) { g_mu = optr->mu; g_c_sw = optr->c_sw; if(optr->type == CLOVER) { if (g_cart_id == 0 && g_debug_level > 1) { printf("#\n# csw = %e, computing clover leafs\n", g_c_sw); } init_sw_fields(VOLUME); sw_term( (const su3**) g_gauge_field, optr->kappa, optr->c_sw); /* this must be EE here! */ /* to match clover_inv in Qsw_psi */ sw_invert(EE, optr->mu); } for(i = 0; i < 2; i++) { if (g_cart_id == 0) { printf("#\n# 2 kappa mu = %e, kappa = %e, c_sw = %e\n", g_mu, g_kappa, g_c_sw); } if(optr->type != CLOVER) { if(use_preconditioning){ g_precWS=(void*)optr->precWS; } else { g_precWS=NULL; } optr->iterations = invert_eo( optr->prop0, optr->prop1, optr->sr0, optr->sr1, optr->eps_sq, optr->maxiter, optr->solver, optr->rel_prec, 0, optr->even_odd_flag,optr->no_extra_masses, optr->extra_masses, optr->id ); /* check result */ M_full(g_spinor_field[4], g_spinor_field[5], optr->prop0, optr->prop1); } else { optr->iterations = invert_clover_eo(optr->prop0, optr->prop1, optr->sr0, optr->sr1, optr->eps_sq, optr->maxiter, optr->solver, optr->rel_prec, &g_gauge_field, &Qsw_pm_psi, &Qsw_minus_psi); /* check result */ Msw_full(g_spinor_field[4], g_spinor_field[5], optr->prop0, optr->prop1); } diff(g_spinor_field[4], g_spinor_field[4], optr->sr0, VOLUME / 2); diff(g_spinor_field[5], g_spinor_field[5], optr->sr1, VOLUME / 2); nrm1 = square_norm(g_spinor_field[4], VOLUME / 2, 1); nrm2 = square_norm(g_spinor_field[5], VOLUME / 2, 1); optr->reached_prec = nrm1 + nrm2; /* convert to standard normalisation */ /* we have to mult. by 2*kappa */ if (optr->kappa != 0.) { mul_r(optr->prop0, (2*optr->kappa), optr->prop0, VOLUME / 2); mul_r(optr->prop1, (2*optr->kappa), optr->prop1, VOLUME / 2); } if (optr->solver != CGMMS && write_prop) /* CGMMS handles its own I/O */ optr->write_prop(op_id, index_start, i); if(optr->DownProp) { optr->mu = -optr->mu; } else break; } } else if(optr->type == DBTMWILSON || optr->type == DBCLOVER) { g_mubar = optr->mubar; g_epsbar = optr->epsbar; g_c_sw = 0.; if(optr->type == DBCLOVER) { g_c_sw = optr->c_sw; if (g_cart_id == 0 && g_debug_level > 1) { printf("#\n# csw = %e, computing clover leafs\n", g_c_sw); } init_sw_fields(VOLUME); sw_term( (const su3**) g_gauge_field, optr->kappa, optr->c_sw); sw_invert_nd(optr->mubar*optr->mubar-optr->epsbar*optr->epsbar); } for(i = 0; i < SourceInfo.no_flavours; i++) { if(optr->type != DBCLOVER) { optr->iterations = invert_doublet_eo( optr->prop0, optr->prop1, optr->prop2, optr->prop3, optr->sr0, optr->sr1, optr->sr2, optr->sr3, optr->eps_sq, optr->maxiter, optr->solver, optr->rel_prec); } else { optr->iterations = invert_cloverdoublet_eo( optr->prop0, optr->prop1, optr->prop2, optr->prop3, optr->sr0, optr->sr1, optr->sr2, optr->sr3, optr->eps_sq, optr->maxiter, optr->solver, optr->rel_prec); } g_mu = optr->mubar; if(optr->type != DBCLOVER) { M_full(g_spinor_field[DUM_DERI+1], g_spinor_field[DUM_DERI+2], optr->prop0, optr->prop1); } else { Msw_full(g_spinor_field[DUM_DERI+1], g_spinor_field[DUM_DERI+2], optr->prop0, optr->prop1); } assign_add_mul_r(g_spinor_field[DUM_DERI+1], optr->prop2, -optr->epsbar, VOLUME/2); assign_add_mul_r(g_spinor_field[DUM_DERI+2], optr->prop3, -optr->epsbar, VOLUME/2); g_mu = -g_mu; if(optr->type != DBCLOVER) { M_full(g_spinor_field[DUM_DERI+3], g_spinor_field[DUM_DERI+4], optr->prop2, optr->prop3); } else { Msw_full(g_spinor_field[DUM_DERI+3], g_spinor_field[DUM_DERI+4], optr->prop2, optr->prop3); } assign_add_mul_r(g_spinor_field[DUM_DERI+3], optr->prop0, -optr->epsbar, VOLUME/2); assign_add_mul_r(g_spinor_field[DUM_DERI+4], optr->prop1, -optr->epsbar, VOLUME/2); diff(g_spinor_field[DUM_DERI+1], g_spinor_field[DUM_DERI+1], optr->sr0, VOLUME/2); diff(g_spinor_field[DUM_DERI+2], g_spinor_field[DUM_DERI+2], optr->sr1, VOLUME/2); diff(g_spinor_field[DUM_DERI+3], g_spinor_field[DUM_DERI+3], optr->sr2, VOLUME/2); diff(g_spinor_field[DUM_DERI+4], g_spinor_field[DUM_DERI+4], optr->sr3, VOLUME/2); nrm1 = square_norm(g_spinor_field[DUM_DERI+1], VOLUME/2, 1); nrm1 += square_norm(g_spinor_field[DUM_DERI+2], VOLUME/2, 1); nrm1 += square_norm(g_spinor_field[DUM_DERI+3], VOLUME/2, 1); nrm1 += square_norm(g_spinor_field[DUM_DERI+4], VOLUME/2, 1); optr->reached_prec = nrm1; g_mu = g_mu1; /* For standard normalisation */ /* we have to mult. by 2*kappa */ mul_r(g_spinor_field[DUM_DERI], (2*optr->kappa), optr->prop0, VOLUME/2); mul_r(g_spinor_field[DUM_DERI+1], (2*optr->kappa), optr->prop1, VOLUME/2); mul_r(g_spinor_field[DUM_DERI+2], (2*optr->kappa), optr->prop2, VOLUME/2); mul_r(g_spinor_field[DUM_DERI+3], (2*optr->kappa), optr->prop3, VOLUME/2); /* the final result should be stored in the convention used in */ /* hep-lat/0606011 */ /* 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], g_spinor_field[DUM_DERI+2], -1., VOLUME/2); mul_one_pm_itau2(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); mul_r(optr->prop0, 1./(2*optr->kappa), g_spinor_field[DUM_DERI], VOLUME/2); mul_r(optr->prop1, 1./(2*optr->kappa), g_spinor_field[DUM_DERI+1], VOLUME/2); mul_r(optr->prop2, 1./(2*optr->kappa), g_spinor_field[DUM_DERI+2], VOLUME/2); mul_r(optr->prop3, 1./(2*optr->kappa), g_spinor_field[DUM_DERI+3], VOLUME/2); /* mirror source, but not for volume sources */ if(i == 0 && SourceInfo.no_flavours == 2 && SourceInfo.type != 1) { if (g_cart_id == 0) { 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(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); } /* volume sources need only one inversion */ else if(SourceInfo.type == 1) i++; } } else if(optr->type == OVERLAP) { g_mu = 0.; m_ov=optr->m; eigenvalues(&optr->no_ev, 5000, optr->ev_prec, 0, optr->ev_readwrite, nstore, optr->even_odd_flag); /* ov_check_locality(); */ /* index_jd(&optr->no_ev_index, 5000, 1.e-12, optr->conf_input, nstore, 4); */ ov_n_cheby=optr->deg_poly; if(use_preconditioning==1) g_precWS=(void*)optr->precWS; else g_precWS=NULL; if(g_debug_level > 3) ov_check_ginsparg_wilson_relation_strong(); invert_overlap(op_id, index_start); if(write_prop) optr->write_prop(op_id, index_start, 0); } etime = gettime(); if (g_cart_id == 0 && g_debug_level > 0) { fprintf(stdout, "# Inversion done in %d iterations, squared residue = %e!\n", optr->iterations, optr->reached_prec); fprintf(stdout, "# Inversion done in %1.2e sec. \n", etime - atime); } return; }
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; }