void cloverdet_heatbath(const int id, hamiltonian_field_t * const hf) { monomial * mnl = &monomial_list[id]; g_mu = mnl->mu; g_mu3 = mnl->rho; g_c_sw = mnl->c_sw; boundary(mnl->kappa); mnl->csg_n = 0; mnl->csg_n2 = 0; mnl->iter0 = 0; mnl->iter1 = 0; init_sw_fields(); sw_term(hf->gaugefield, mnl->kappa, mnl->c_sw); sw_invert(EE, mnl->mu); random_spinor_field(g_spinor_field[2], VOLUME/2, mnl->rngrepro); mnl->energy0 = square_norm(g_spinor_field[2], VOLUME/2, 1); mnl->Qp(mnl->pf, g_spinor_field[2]); chrono_add_solution(mnl->pf, mnl->csg_field, mnl->csg_index_array, mnl->csg_N, &mnl->csg_n, VOLUME/2); g_mu = g_mu1; g_mu3 = 0.; boundary(g_kappa); if(g_proc_id == 0 && g_debug_level > 3) { printf("called cloverdet_heatbath for id %d %d\n", id, mnl->even_odd_flag); } return; }
void det_heatbath(const int id, hamiltonian_field_t * const hf) { monomial * mnl = &monomial_list[id]; g_mu = mnl->mu; boundary(mnl->kappa); mnl->csg_n = 0; mnl->csg_n2 = 0; mnl->iter0 = 0; mnl->iter1 = 0; if(mnl->even_odd_flag) { random_spinor_field(g_spinor_field[2], VOLUME/2, mnl->rngrepro); mnl->energy0 = square_norm(g_spinor_field[2], VOLUME/2, 1); Qtm_plus_psi(mnl->pf, g_spinor_field[2]); chrono_add_solution(mnl->pf, mnl->csg_field, mnl->csg_index_array, mnl->csg_N, &mnl->csg_n, VOLUME/2); if(mnl->solver != CG) { chrono_add_solution(mnl->pf, mnl->csg_field2, mnl->csg_index_array2, mnl->csg_N2, &mnl->csg_n2, VOLUME/2); } } else { random_spinor_field(g_spinor_field[2], VOLUME, mnl->rngrepro); mnl->energy0 = square_norm(g_spinor_field[2], VOLUME, 1); Q_plus_psi(mnl->pf, g_spinor_field[2]); chrono_add_solution(mnl->pf, mnl->csg_field, mnl->csg_index_array, mnl->csg_N, &mnl->csg_n, VOLUME/2); if(mnl->solver != CG) { chrono_add_solution(mnl->pf, mnl->csg_field2, mnl->csg_index_array2, mnl->csg_N2, &mnl->csg_n2, VOLUME/2); } } g_mu = g_mu1; boundary(g_kappa); if(g_proc_id == 0 && g_debug_level > 3) { printf("called det_heatbath for id %d %d\n", id, mnl->even_odd_flag); } return; }
/*lambda: smallest eigenvalue, k eigenvector */ int evamax0(double *rz, int k, double q_off, double eps_sq) { static double norm,norm0; int j; random_spinor_field(g_spinor_field[k], VOLUME/2); norm0=square_norm(g_spinor_field[k], VOLUME/2, 1); norm=1000.; assign_mul_bra_add_mul_r( g_spinor_field[k], 1./sqrt(norm0),0., g_spinor_field[k], VOLUME/2); for(j=1;j<ITER_MAX_BCG;j++) { Q_psi(k,k,q_off); Q_psi(k,k,q_off); norm0=square_norm(g_spinor_field[k], VOLUME/2, 1); norm0=sqrt(norm0); assign_mul_bra_add_mul_r( g_spinor_field[k], 1./norm0,0., g_spinor_field[k], VOLUME/2); if((norm-norm0)*(norm-norm0) <= eps_sq) break; norm=norm0; } *rz=norm0; return j; }
void cloverdetratio_heatbath(const int id, hamiltonian_field_t * const hf) { monomial * mnl = &monomial_list[id]; g_mu = mnl->mu; g_c_sw = mnl->c_sw; boundary(mnl->kappa); mnl->csg_n = 0; mnl->csg_n2 = 0; mnl->iter0 = 0; mnl->iter1 = 0; init_sw_fields(); sw_term( (const su3**) hf->gaugefield, mnl->kappa, mnl->c_sw); sw_invert(EE, mnl->mu); random_spinor_field(g_spinor_field[4], VOLUME/2, mnl->rngrepro); mnl->energy0 = square_norm(g_spinor_field[4], VOLUME/2, 1); g_mu3 = mnl->rho; mnl->Qp(g_spinor_field[3], g_spinor_field[4]); g_mu3 = mnl->rho2; zero_spinor_field(mnl->pf,VOLUME/2); mnl->iter0 = cg_her(mnl->pf, g_spinor_field[3], mnl->maxiter, mnl->accprec, g_relative_precision_flag, VOLUME/2, mnl->Qsq); chrono_add_solution(mnl->pf, mnl->csg_field, mnl->csg_index_array, mnl->csg_N, &mnl->csg_n, VOLUME/2); mnl->Qm(mnl->pf, mnl->pf); if(g_proc_id == 0 && g_debug_level > 3) { printf("called cloverdetratio_heatbath for id %d \n", id); } g_mu3 = 0.; g_mu = g_mu1; boundary(g_kappa); return; }
int main(int argc,char *argv[]) { int j,j_max,k,k_max = 2; paramsXlfInfo *xlfInfo; int ix, n, *nn,*mm,i; double delta, deltamax; spinor rsp; int status = 0; #ifdef MPI DUM_DERI = 6; DUM_SOLVER = DUM_DERI+2; DUM_MATRIX = DUM_SOLVER+6; NO_OF_SPINORFIELDS = DUM_MATRIX+2; MPI_Init(&argc, &argv); #endif g_rgi_C1 = 1.; /* Read the input file */ read_input("hopping_test.input"); tmlqcd_mpi_init(argc, argv); if(g_proc_id==0) { #ifdef SSE printf("# The code was compiled with SSE instructions\n"); #endif #ifdef SSE2 printf("# The code was compiled with SSE2 instructions\n"); #endif #ifdef SSE3 printf("# The code was compiled with SSE3 instructions\n"); #endif #ifdef P4 printf("# The code was compiled for Pentium4\n"); #endif #ifdef OPTERON printf("# The code was compiled for AMD Opteron\n"); #endif #ifdef _GAUGE_COPY printf("# The code was compiled with -D_GAUGE_COPY\n"); #endif #ifdef BGL printf("# The code was compiled for Blue Gene/L\n"); #endif #ifdef BGP printf("# The code was compiled for Blue Gene/P\n"); #endif #ifdef _USE_HALFSPINOR printf("# The code was compiled with -D_USE_HALFSPINOR\n"); #endif #ifdef _USE_SHMEM printf("# the code was compiled with -D_USE_SHMEM\n"); # ifdef _PERSISTENT printf("# the code was compiled for persistent MPI calls (halfspinor only)\n"); # endif #endif #ifdef _INDEX_INDEP_GEOM printf("# the code was compiled with index independent geometry\n"); #endif #ifdef MPI # ifdef _NON_BLOCKING printf("# the code was compiled for non-blocking MPI calls (spinor and gauge)\n"); # endif # ifdef _USE_TSPLITPAR printf("# the code was compiled with tsplit parallelization\n"); # endif #endif printf("\n"); fflush(stdout); } #ifdef _GAUGE_COPY init_gauge_field(VOLUMEPLUSRAND + g_dbw2rand, 1); #else init_gauge_field(VOLUMEPLUSRAND + g_dbw2rand, 0); #endif init_geometry_indices(VOLUMEPLUSRAND + g_dbw2rand); if(even_odd_flag) { j = init_spinor_field(VOLUMEPLUSRAND/2, 2*k_max+1); } else { j = init_spinor_field(VOLUMEPLUSRAND, 2*k_max); } if ( j!= 0) { fprintf(stderr, "Not enough memory for spinor fields! Aborting...\n"); exit(0); } j = init_moment_field(VOLUME, VOLUMEPLUSRAND); if ( j!= 0) { fprintf(stderr, "Not enough memory for moment fields! Aborting...\n"); exit(0); } if(g_proc_id == 0) { fprintf(stdout,"The number of processes is %d \n",g_nproc); printf("# The lattice size is %d x %d x %d x %d\n", (int)(T*g_nproc_t), (int)(LX*g_nproc_x), (int)(LY*g_nproc_y), (int)(g_nproc_z*LZ)); printf("# The local lattice size is %d x %d x %d x %d\n", (int)(T), (int)(LX), (int)(LY),(int) LZ); if(even_odd_flag) { printf("# testinging the even/odd preconditioned Dirac operator\n"); } else { printf("# testinging the standard Dirac operator\n"); } fflush(stdout); } /* define the geometry */ geometry(); /* define the boundary conditions for the fermion fields */ boundary(g_kappa); #ifdef _USE_HALFSPINOR j = init_dirac_halfspinor(); if ( j!= 0) { fprintf(stderr, "Not enough memory for halfspinor fields! Aborting...\n"); exit(0); } if(g_sloppy_precision_flag == 1) { g_sloppy_precision = 1; j = init_dirac_halfspinor32(); if ( j!= 0) { fprintf(stderr, "Not enough memory for 32-Bit halfspinor fields! Aborting...\n"); exit(0); } } # if (defined _PERSISTENT) init_xchange_halffield(); # endif #endif status = check_geometry(); if (status != 0) { fprintf(stderr, "Checking of geometry failed. Unable to proceed.\nAborting....\n"); exit(1); } #if (defined MPI && !(defined _USE_SHMEM)) check_xchange(); #endif start_ranlux(1, 123456); xlfInfo = construct_paramsXlfInfo(0.5, 0); random_gauge_field(reproduce_randomnumber_flag); if ( startoption == 2 ) { /* restart */ write_gauge_field(gauge_input_filename,gauge_precision_write_flag,xlfInfo); } else if ( startoption == 0 ) { /* cold */ unit_g_gauge_field(); } else if (startoption == 3 ) { /* continue */ read_gauge_field(gauge_input_filename); } else if ( startoption == 1 ) { /* hot */ } #ifdef MPI /*For parallelization: exchange the gaugefield */ xchange_gauge(); #endif #ifdef _GAUGE_COPY update_backward_gauge(); #endif if(even_odd_flag) { /*initialize the pseudo-fermion fields*/ j_max=1; for (k = 0; k < k_max; k++) { random_spinor_field(g_spinor_field[k], VOLUME/2, 0); } if (read_source_flag == 2) { /* save */ /* even first, odd second */ write_spinorfield_cm_single(g_spinor_field[0],g_spinor_field[1],SourceInfo.basename); } else if (read_source_flag == 1) { /* yes */ /* even first, odd second */ read_spinorfield_cm_single(g_spinor_field[0],g_spinor_field[1],SourceInfo.basename,-1,0); # if (!defined MPI) if (write_cp_flag == 1) { strcat(SourceInfo.basename,".2"); read_spinorfield_cm_single(g_spinor_field[2],g_spinor_field[3],SourceInfo.basename,-1,0); nn=(int*)calloc(VOLUME,sizeof(int)); if((void*)nn == NULL) return(100); mm=(int*)calloc(VOLUME,sizeof(int)); if((void*)mm == NULL) return(100); n=0; deltamax=0.0; for(ix=0;ix<VOLUME/2;ix++){ (rsp.s0).c0.re = (g_spinor_field[2][ix].s0).c0.re - (g_spinor_field[0][ix].s0).c0.re; (rsp.s0).c0.im = (g_spinor_field[2][ix].s0).c0.im - (g_spinor_field[0][ix].s0).c0.im; (rsp.s0).c1.re = (g_spinor_field[2][ix].s0).c1.re - (g_spinor_field[0][ix].s0).c1.re; (rsp.s0).c1.im = (g_spinor_field[2][ix].s0).c1.im - (g_spinor_field[0][ix].s0).c1.im; (rsp.s0).c2.re = (g_spinor_field[2][ix].s0).c2.re - (g_spinor_field[0][ix].s0).c2.re; (rsp.s0).c2.im = (g_spinor_field[2][ix].s0).c2.im - (g_spinor_field[0][ix].s0).c2.im; (rsp.s1).c0.re = (g_spinor_field[2][ix].s1).c0.re - (g_spinor_field[0][ix].s1).c0.re; (rsp.s1).c0.im = (g_spinor_field[2][ix].s1).c0.im - (g_spinor_field[0][ix].s1).c0.im; (rsp.s1).c1.re = (g_spinor_field[2][ix].s1).c1.re - (g_spinor_field[0][ix].s1).c1.re; (rsp.s1).c1.im = (g_spinor_field[2][ix].s1).c1.im - (g_spinor_field[0][ix].s1).c1.im; (rsp.s1).c2.re = (g_spinor_field[2][ix].s1).c2.re - (g_spinor_field[0][ix].s1).c2.re; (rsp.s1).c2.im = (g_spinor_field[2][ix].s1).c2.im - (g_spinor_field[0][ix].s1).c2.im; (rsp.s2).c0.re = (g_spinor_field[2][ix].s2).c0.re - (g_spinor_field[0][ix].s2).c0.re; (rsp.s2).c0.im = (g_spinor_field[2][ix].s2).c0.im - (g_spinor_field[0][ix].s2).c0.im; (rsp.s2).c1.re = (g_spinor_field[2][ix].s2).c1.re - (g_spinor_field[0][ix].s2).c1.re; (rsp.s2).c1.im = (g_spinor_field[2][ix].s2).c1.im - (g_spinor_field[0][ix].s2).c1.im; (rsp.s2).c2.re = (g_spinor_field[2][ix].s2).c2.re - (g_spinor_field[0][ix].s2).c2.re; (rsp.s2).c2.im = (g_spinor_field[2][ix].s2).c2.im - (g_spinor_field[0][ix].s2).c2.im; (rsp.s3).c0.re = (g_spinor_field[2][ix].s3).c0.re - (g_spinor_field[0][ix].s3).c0.re; (rsp.s3).c0.im = (g_spinor_field[2][ix].s3).c0.im - (g_spinor_field[0][ix].s3).c0.im; (rsp.s3).c1.re = (g_spinor_field[2][ix].s3).c1.re - (g_spinor_field[0][ix].s3).c1.re; (rsp.s3).c1.im = (g_spinor_field[2][ix].s3).c1.im - (g_spinor_field[0][ix].s3).c1.im; (rsp.s3).c2.re = (g_spinor_field[2][ix].s3).c2.re - (g_spinor_field[0][ix].s3).c2.re; (rsp.s3).c2.im = (g_spinor_field[2][ix].s3).c2.im - (g_spinor_field[0][ix].s3).c2.im; _spinor_norm_sq(delta,rsp); if (delta > 1.0e-12) { nn[n] = g_eo2lexic[ix]; mm[n]=ix; n++; } if(delta>deltamax) deltamax=delta; } if (n>0){ printf("mismatch in even spincolorfield in %d points:\n",n); for(i=0; i< MIN(n,1000); i++){ printf("%d,(%d,%d,%d,%d):%f vs. %f\n",nn[i],g_coord[nn[i]][0],g_coord[nn[i]][1],g_coord[nn[i]][2],g_coord[nn[i]][3],(g_spinor_field[2][mm[i]].s0).c0.re, (g_spinor_field[0][mm[i]].s0).c0.re);fflush(stdout); } } n = 0; for(ix=0;ix<VOLUME/2;ix++){ (rsp.s0).c0.re = (g_spinor_field[3][ix].s0).c0.re - (g_spinor_field[1][ix].s0).c0.re; (rsp.s0).c0.im = (g_spinor_field[3][ix].s0).c0.im - (g_spinor_field[1][ix].s0).c0.im; (rsp.s0).c1.re = (g_spinor_field[3][ix].s0).c1.re - (g_spinor_field[1][ix].s0).c1.re; (rsp.s0).c1.im = (g_spinor_field[3][ix].s0).c1.im - (g_spinor_field[1][ix].s0).c1.im; (rsp.s0).c2.re = (g_spinor_field[3][ix].s0).c2.re - (g_spinor_field[1][ix].s0).c2.re; (rsp.s0).c2.im = (g_spinor_field[3][ix].s0).c2.im - (g_spinor_field[1][ix].s0).c2.im; (rsp.s1).c0.re = (g_spinor_field[3][ix].s1).c0.re - (g_spinor_field[1][ix].s1).c0.re; (rsp.s1).c0.im = (g_spinor_field[3][ix].s1).c0.im - (g_spinor_field[1][ix].s1).c0.im; (rsp.s1).c1.re = (g_spinor_field[3][ix].s1).c1.re - (g_spinor_field[1][ix].s1).c1.re; (rsp.s1).c1.im = (g_spinor_field[3][ix].s1).c1.im - (g_spinor_field[1][ix].s1).c1.im; (rsp.s1).c2.re = (g_spinor_field[3][ix].s1).c2.re - (g_spinor_field[1][ix].s1).c2.re; (rsp.s1).c2.im = (g_spinor_field[3][ix].s1).c2.im - (g_spinor_field[1][ix].s1).c2.im; (rsp.s2).c0.re = (g_spinor_field[3][ix].s2).c0.re - (g_spinor_field[1][ix].s2).c0.re; (rsp.s2).c0.im = (g_spinor_field[3][ix].s2).c0.im - (g_spinor_field[1][ix].s2).c0.im; (rsp.s2).c1.re = (g_spinor_field[3][ix].s2).c1.re - (g_spinor_field[1][ix].s2).c1.re; (rsp.s2).c1.im = (g_spinor_field[3][ix].s2).c1.im - (g_spinor_field[1][ix].s2).c1.im; (rsp.s2).c2.re = (g_spinor_field[3][ix].s2).c2.re - (g_spinor_field[1][ix].s2).c2.re; (rsp.s2).c2.im = (g_spinor_field[3][ix].s2).c2.im - (g_spinor_field[1][ix].s2).c2.im; (rsp.s3).c0.re = (g_spinor_field[3][ix].s3).c0.re - (g_spinor_field[1][ix].s3).c0.re; (rsp.s3).c0.im = (g_spinor_field[3][ix].s3).c0.im - (g_spinor_field[1][ix].s3).c0.im; (rsp.s3).c1.re = (g_spinor_field[3][ix].s3).c1.re - (g_spinor_field[1][ix].s3).c1.re; (rsp.s3).c1.im = (g_spinor_field[3][ix].s3).c1.im - (g_spinor_field[1][ix].s3).c1.im; (rsp.s3).c2.re = (g_spinor_field[3][ix].s3).c2.re - (g_spinor_field[1][ix].s3).c2.re; (rsp.s3).c2.im = (g_spinor_field[3][ix].s3).c2.im - (g_spinor_field[1][ix].s3).c2.im; _spinor_norm_sq(delta,rsp); if (delta > 1.0e-12) { nn[n]=g_eo2lexic[ix+(VOLUME+RAND)/2]; mm[n]=ix; n++; } if(delta>deltamax) deltamax=delta; } if (n>0){ printf("mismatch in odd spincolorfield in %d points:\n",n); for(i=0; i< MIN(n,1000); i++){ printf("%d,(%d,%d,%d,%d):%f vs. %f\n",nn[i],g_coord[nn[i]][0],g_coord[nn[i]][1],g_coord[nn[i]][2],g_coord[nn[i]][3],(g_spinor_field[3][mm[i]].s0).c0.re, (g_spinor_field[1][mm[i]].s0).c0.re);fflush(stdout); } } printf("max delta=%e",deltamax);fflush(stdout); } # endif } if (read_source_flag > 0 && write_cp_flag == 0) { /* read-source yes or nobutsave; checkpoint no */ /* first spinorial arg is output, the second is input */ Hopping_Matrix(1, g_spinor_field[1], g_spinor_field[0]); /*ieo=1 M_{eo}*/ Hopping_Matrix(0, g_spinor_field[0], g_spinor_field[1]); /*ieo=0 M_{oe}*/ strcat(SourceInfo.basename,".out"); write_spinorfield_cm_single(g_spinor_field[0],g_spinor_field[1],SourceInfo.basename); printf("Check-field printed. Exiting...\n"); fflush(stdout); } #ifdef MPI MPI_Barrier(MPI_COMM_WORLD); MPI_Finalize(); #endif } free_gauge_field(); free_geometry_indices(); free_spinor_field(); free_moment_field(); return(0); }
/*lambda: largest eigenvalue, k eigenvector */ int evamax(double *rz, int k, double q_off, double eps_sq) { static double ritz,norm0,normg,normg0,beta_cg; static double costh,sinth,cosd,sind,aaa,normp,xxx; static double xs1,xs2,xs3; int iteration; /* Initialize k to be gaussian */ random_spinor_field(g_spinor_field[k], VOLUME/2); norm0=square_norm(g_spinor_field[k], VOLUME/2, 1); /*normalize k */ assign_mul_bra_add_mul_r( g_spinor_field[k], 1./sqrt(norm0),0., g_spinor_field[k], VOLUME/2); Q_psi(DUM_SOLVER,k,q_off); Q_psi(DUM_SOLVER,DUM_SOLVER,q_off); /*compute the ritz functional */ /*put g on DUM_SOLVER+2 and p on DUM_SOLVER+1*/ ritz=scalar_prod_r(g_spinor_field[DUM_SOLVER], g_spinor_field[k], VOLUME/2, 1); zero_spinor_field(g_spinor_field[DUM_SOLVER+2],VOLUME/2); assign_add_mul_r_add_mul(g_spinor_field[DUM_SOLVER+2], g_spinor_field[DUM_SOLVER], g_spinor_field[k], 1., -ritz, VOLUME/2); assign(g_spinor_field[DUM_SOLVER+1], g_spinor_field[DUM_SOLVER+2], VOLUME/2); normg0=square_norm(g_spinor_field[DUM_SOLVER+2], VOLUME/2, 1); /* main loop */ for(iteration=1;iteration<=ITER_MAX_BCG;iteration++) { if(normg0 <= eps_sq) break; Q_psi(DUM_SOLVER+2,DUM_SOLVER+1,q_off); Q_psi(DUM_SOLVER+2,DUM_SOLVER+2,q_off); /* compute costh and sinth */ normp=square_norm(g_spinor_field[DUM_SOLVER+1], VOLUME/2, 1); xxx=scalar_prod_r(g_spinor_field[DUM_SOLVER+2], g_spinor_field[DUM_SOLVER+1], VOLUME/2, 1); xs1=0.5*(ritz+xxx/normp); xs2=0.5*(ritz-xxx/normp); normp=sqrt(normp); xs3=normg0/normp; aaa=sqrt(xs2*xs2+xs3*xs3); cosd=xs2/aaa; sind=xs3/aaa; if(cosd>=0.) { costh=sqrt(0.5*(1.+cosd)); sinth=0.5*sind/costh; } else { sinth=sqrt(0.5*(1.-cosd)); costh=0.5*sind/sinth; } ritz=xs1+aaa; assign_add_mul_r_add_mul(g_spinor_field[k], g_spinor_field[k], g_spinor_field[DUM_SOLVER+1], costh-1., sinth/normp, VOLUME/2); assign_add_mul_r_add_mul(g_spinor_field[DUM_SOLVER], g_spinor_field[DUM_SOLVER], g_spinor_field[DUM_SOLVER+2], costh-1., sinth/normp, VOLUME/2); /* compute g */ zero_spinor_field(g_spinor_field[DUM_SOLVER+2],VOLUME/2); assign_add_mul_r_add_mul(g_spinor_field[DUM_SOLVER+2], g_spinor_field[DUM_SOLVER], g_spinor_field[k], 1., -ritz, VOLUME/2); /* calculate the norm of g' and beta_cg=costh g'^2/g^2 */ normg=square_norm(g_spinor_field[DUM_SOLVER+2], VOLUME/2, 1); beta_cg=costh*normg/normg0; if(beta_cg*costh*normp>20.*sqrt(normg)) beta_cg=0.; normg0=normg; /* compute the new value of p */ assign_add_mul_r(g_spinor_field[DUM_SOLVER+1], g_spinor_field[k], -scalar_prod_r(g_spinor_field[k], g_spinor_field[DUM_SOLVER+1], VOLUME/2), VOLUME/2, 1); assign_mul_add_r(g_spinor_field[DUM_SOLVER+1],beta_cg, g_spinor_field[DUM_SOLVER+2], VOLUME/2); /* restore the state of the iteration */ if(iteration%20==0) { /* readjust x */ xxx=sqrt(square_norm(g_spinor_field[k], VOLUME/2), 1); assign_mul_bra_add_mul_r( g_spinor_field[k], 1./xxx,0., g_spinor_field[k], VOLUME/2); Q_psi(DUM_SOLVER,k,q_off); Q_psi(DUM_SOLVER,DUM_SOLVER,q_off); /*compute the ritz functional */ ritz=scalar_prod_r(g_spinor_field[DUM_SOLVER], g_spinor_field[k], VOLUME/2, 1); /*put g on DUM_SOLVER+2 and p on DUM_SOLVER+1*/ zero_spinor_field(g_spinor_field[DUM_SOLVER+2],VOLUME/2); assign_add_mul_r_add_mul(g_spinor_field[DUM_SOLVER+2], g_spinor_field[DUM_SOLVER], g_spinor_field[k], 1., -ritz, VOLUME/2); normg0=square_norm(g_spinor_field[DUM_SOLVER+2], VOLUME/2, 1); /*subtract a linear combination of x and g from p to insure (x,p)=0 and (p,g)=(g,g) */ cosd=scalar_prod_r(g_spinor_field[k], g_spinor_field[DUM_SOLVER+1], VOLUME/2, 1); assign_add_mul_r(g_spinor_field[DUM_SOLVER+1], g_spinor_field[k], -cosd, VOLUME/2); cosd=scalar_prod_r(g_spinor_field[DUM_SOLVER+1], g_spinor_field[DUM_SOLVER+2], VOLUME/2, 1)-normg0; assign_add_mul_r(g_spinor_field[DUM_SOLVER+1], g_spinor_field[DUM_SOLVER+2], -cosd/sqrt(normg0), VOLUME/2); } } *rz=ritz; return iteration; }
void ndpoly_heatbath(const int id) { int j; double temp; monomial * mnl = &monomial_list[id]; (*mnl).energy0 = 0.; random_spinor_field(g_chi_up_spinor_field[0], VOLUME/2, (*mnl).rngrepro); (*mnl).energy0 = square_norm(g_chi_up_spinor_field[0], VOLUME/2, 1); if(g_epsbar!=0.0 || phmc_exact_poly == 0){ random_spinor_field(g_chi_dn_spinor_field[0], VOLUME/2, (*mnl).rngrepro); (*mnl).energy0 += square_norm(g_chi_dn_spinor_field[0], VOLUME/2, 1); } else { zero_spinor_field(g_chi_dn_spinor_field[0], VOLUME/2); } if((g_proc_id == g_stdio_proc) && (g_debug_level > 2)) { printf("PHMC: Here comes the computation of H_old with \n \n"); printf("PHMC: First: random spinors and their norm \n "); printf("PHMC: OLD Ennergy UP %e \n", (*mnl).energy0); printf("PHMC: OLD Energy DN + UP %e \n\n", (*mnl).energy0); } if(phmc_exact_poly==0){ QNon_degenerate(g_chi_up_spinor_field[1], g_chi_dn_spinor_field[1], g_chi_up_spinor_field[0], g_chi_dn_spinor_field[0]); for(j = 1; j < (phmc_dop_n_cheby); j++){ assign(g_chi_up_spinor_field[0], g_chi_up_spinor_field[1], VOLUME/2); assign(g_chi_dn_spinor_field[0], g_chi_dn_spinor_field[1], VOLUME/2); Q_tau1_min_cconst_ND(g_chi_up_spinor_field[1], g_chi_dn_spinor_field[1], g_chi_up_spinor_field[0], g_chi_dn_spinor_field[0], phmc_root[phmc_dop_n_cheby-2+j]); } Poly_tilde_ND(g_chi_up_spinor_field[0], g_chi_dn_spinor_field[0], phmc_ptilde_cheby_coef, phmc_ptilde_n_cheby, g_chi_up_spinor_field[1], g_chi_dn_spinor_field[1]); } else if( phmc_exact_poly==1 && g_epsbar!=0.0) { /* Attention this is Q * tau1, up/dn are exchanged in the input spinor */ /* this is used as an preconditioner */ QNon_degenerate(g_chi_up_spinor_field[1],g_chi_dn_spinor_field[1], g_chi_dn_spinor_field[0],g_chi_up_spinor_field[0]); assign(g_chi_up_spinor_field[0], g_chi_up_spinor_field[1], VOLUME/2); assign(g_chi_dn_spinor_field[0], g_chi_dn_spinor_field[1], VOLUME/2); /* solve Q*tau1*P(Q^2) *x=y */ cg_her_nd(g_chi_up_spinor_field[1],g_chi_dn_spinor_field[1], g_chi_up_spinor_field[0],g_chi_dn_spinor_field[0], 1000,1.e-16,0,VOLUME/2, Qtau1_P_ND); /* phi= Bdagger phi */ for(j = 1; j < (phmc_dop_n_cheby); j++){ assign(g_chi_up_spinor_field[0], g_chi_up_spinor_field[1], VOLUME/2); assign(g_chi_dn_spinor_field[0], g_chi_dn_spinor_field[1], VOLUME/2); Q_tau1_min_cconst_ND(g_chi_up_spinor_field[1], g_chi_dn_spinor_field[1], g_chi_up_spinor_field[0], g_chi_dn_spinor_field[0], phmc_root[phmc_dop_n_cheby-2+j]); } assign(g_chi_up_spinor_field[0], g_chi_up_spinor_field[1], VOLUME/2); assign(g_chi_dn_spinor_field[0], g_chi_dn_spinor_field[1], VOLUME/2); } else if(phmc_exact_poly==1 && g_epsbar==0.0) { Qtm_pm_psi(g_chi_up_spinor_field[1], g_chi_up_spinor_field[0]); assign(g_chi_up_spinor_field[0], g_chi_up_spinor_field[1], VOLUME/2); /* solve (Q+)*(Q-)*P((Q+)*(Q-)) *x=y */ cg_her(g_chi_up_spinor_field[1], g_chi_up_spinor_field[0], 1000,1.e-16,0,VOLUME/2, Qtm_pm_Ptm_pm_psi); /* phi= Bdagger phi */ for(j = 1; j < (phmc_dop_n_cheby); j++){ assign(g_chi_up_spinor_field[0], g_chi_up_spinor_field[1], VOLUME/2); Qtm_pm_min_cconst_nrm(g_chi_up_spinor_field[1], g_chi_up_spinor_field[0], phmc_root[phmc_dop_n_cheby-2+j]); } assign(g_chi_up_spinor_field[0], g_chi_up_spinor_field[1], VOLUME/2); } assign(mnl->pf, g_chi_up_spinor_field[0], VOLUME/2); assign(mnl->pf2, g_chi_dn_spinor_field[0], VOLUME/2); temp = square_norm(g_chi_up_spinor_field[0], VOLUME/2, 1); if((g_proc_id == g_stdio_proc) && (g_debug_level > 2)) { printf("PHMC: Then: evaluate Norm of pseudofermion heatbath BHB \n "); printf("PHMC: Norm of BHB up squared %e \n", temp); } if(g_epsbar!=0.0 || phmc_exact_poly==0) temp += square_norm(g_chi_dn_spinor_field[0], VOLUME/2, 1); if((g_proc_id == g_stdio_proc) && (g_debug_level > 2)){ printf("PHMC: Norm of BHB up + BHB dn squared %e \n\n", temp); } if(g_proc_id == 0 && g_debug_level > 3) { printf("called ndpoly_heatbath for id %d with g_running_phmc = %d\n", id, g_running_phmc); } return; }
int main(int argc,char *argv[]) { int j,j_max,k,k_max = 1; #ifdef HAVE_LIBLEMON paramsXlfInfo *xlfInfo; #endif int status = 0; static double t1,t2,dt,sdt,dts,qdt,sqdt; double antioptaway=0.0; #ifdef MPI static double dt2; DUM_DERI = 6; DUM_SOLVER = DUM_DERI+2; DUM_MATRIX = DUM_SOLVER+6; NO_OF_SPINORFIELDS = DUM_MATRIX+2; # ifdef OMP int mpi_thread_provided; MPI_Init_thread(&argc, &argv, MPI_THREAD_SERIALIZED, &mpi_thread_provided); # else MPI_Init(&argc, &argv); # endif MPI_Comm_rank(MPI_COMM_WORLD, &g_proc_id); #else g_proc_id = 0; #endif g_rgi_C1 = 1.; /* Read the input file */ if((status = read_input("benchmark.input")) != 0) { fprintf(stderr, "Could not find input file: benchmark.input\nAborting...\n"); exit(-1); } #ifdef OMP if(omp_num_threads > 0) { omp_set_num_threads(omp_num_threads); } else { if( g_proc_id == 0 ) printf("# No value provided for OmpNumThreads, running in single-threaded mode!\n"); omp_num_threads = 1; omp_set_num_threads(omp_num_threads); } init_omp_accumulators(omp_num_threads); #endif tmlqcd_mpi_init(argc, argv); if(g_proc_id==0) { #ifdef SSE printf("# The code was compiled with SSE instructions\n"); #endif #ifdef SSE2 printf("# The code was compiled with SSE2 instructions\n"); #endif #ifdef SSE3 printf("# The code was compiled with SSE3 instructions\n"); #endif #ifdef P4 printf("# The code was compiled for Pentium4\n"); #endif #ifdef OPTERON printf("# The code was compiled for AMD Opteron\n"); #endif #ifdef _GAUGE_COPY printf("# The code was compiled with -D_GAUGE_COPY\n"); #endif #ifdef BGL printf("# The code was compiled for Blue Gene/L\n"); #endif #ifdef BGP printf("# The code was compiled for Blue Gene/P\n"); #endif #ifdef _USE_HALFSPINOR printf("# The code was compiled with -D_USE_HALFSPINOR\n"); #endif #ifdef _USE_SHMEM printf("# The code was compiled with -D_USE_SHMEM\n"); # ifdef _PERSISTENT printf("# The code was compiled for persistent MPI calls (halfspinor only)\n"); # endif #endif #ifdef MPI # ifdef _NON_BLOCKING printf("# The code was compiled for non-blocking MPI calls (spinor and gauge)\n"); # endif #endif printf("\n"); fflush(stdout); } #ifdef _GAUGE_COPY init_gauge_field(VOLUMEPLUSRAND + g_dbw2rand, 1); #else init_gauge_field(VOLUMEPLUSRAND + g_dbw2rand, 0); #endif init_geometry_indices(VOLUMEPLUSRAND + g_dbw2rand); if(even_odd_flag) { j = init_spinor_field(VOLUMEPLUSRAND/2, 2*k_max+1); } else { j = init_spinor_field(VOLUMEPLUSRAND, 2*k_max); } if ( j!= 0) { fprintf(stderr, "Not enough memory for spinor fields! Aborting...\n"); exit(0); } j = init_moment_field(VOLUME, VOLUMEPLUSRAND + g_dbw2rand); if ( j!= 0) { fprintf(stderr, "Not enough memory for moment fields! Aborting...\n"); exit(0); } if(g_proc_id == 0) { fprintf(stdout,"# The number of processes is %d \n",g_nproc); printf("# The lattice size is %d x %d x %d x %d\n", (int)(T*g_nproc_t), (int)(LX*g_nproc_x), (int)(LY*g_nproc_y), (int)(g_nproc_z*LZ)); printf("# The local lattice size is %d x %d x %d x %d\n", (int)(T), (int)(LX), (int)(LY),(int) LZ); if(even_odd_flag) { printf("# benchmarking the even/odd preconditioned Dirac operator\n"); } else { printf("# benchmarking the standard Dirac operator\n"); } fflush(stdout); } /* define the geometry */ geometry(); /* define the boundary conditions for the fermion fields */ boundary(g_kappa); #ifdef _USE_HALFSPINOR j = init_dirac_halfspinor(); if ( j!= 0) { fprintf(stderr, "Not enough memory for halfspinor fields! Aborting...\n"); exit(0); } if(g_sloppy_precision_flag == 1) { g_sloppy_precision = 1; j = init_dirac_halfspinor32(); if ( j!= 0) { fprintf(stderr, "Not enough memory for 32-Bit halfspinor fields! Aborting...\n"); exit(0); } } # if (defined _PERSISTENT) init_xchange_halffield(); # endif #endif status = check_geometry(); if (status != 0) { fprintf(stderr, "Checking of geometry failed. Unable to proceed.\nAborting....\n"); exit(1); } #if (defined MPI && !(defined _USE_SHMEM)) check_xchange(); #endif start_ranlux(1, 123456); random_gauge_field(reproduce_randomnumber_flag); #ifdef MPI /*For parallelization: exchange the gaugefield */ xchange_gauge(g_gauge_field); #endif if(even_odd_flag) { /*initialize the pseudo-fermion fields*/ j_max=2048; sdt=0.; for (k = 0; k < k_max; k++) { random_spinor_field(g_spinor_field[k], VOLUME/2, 0); } while(sdt < 30.) { #ifdef MPI MPI_Barrier(MPI_COMM_WORLD); #endif t1 = gettime(); antioptaway=0.0; for (j=0;j<j_max;j++) { for (k=0;k<k_max;k++) { Hopping_Matrix(0, g_spinor_field[k+k_max], g_spinor_field[k]); Hopping_Matrix(1, g_spinor_field[2*k_max], g_spinor_field[k+k_max]); antioptaway+=creal(g_spinor_field[2*k_max][0].s0.c0); } } t2 = gettime(); dt = t2-t1; #ifdef MPI MPI_Allreduce (&dt, &sdt, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); #else sdt = dt; #endif qdt=dt*dt; #ifdef MPI MPI_Allreduce (&qdt, &sqdt, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); #else sqdt = qdt; #endif sdt=sdt/((double)g_nproc); sqdt=sqrt(sqdt/g_nproc-sdt*sdt); j_max*=2; } j_max=j_max/2; dts=dt; sdt=1.0e6f*sdt/((double)(k_max*j_max*(VOLUME))); sqdt=1.0e6f*sqdt/((double)(k_max*j_max*(VOLUME))); if(g_proc_id==0) { printf("# The following result is just to make sure that the calculation is not optimized away: %e\n", antioptaway); printf("# Total compute time %e sec, variance of the time %e sec. (%d iterations).\n", sdt, sqdt, j_max); printf("# Communication switched on:\n# (%d Mflops [%d bit arithmetic])\n", (int)(1608.0f/sdt),(int)sizeof(spinor)/3); #ifdef OMP printf("# Mflops per OpenMP thread ~ %d\n",(int)(1608.0f/(omp_num_threads*sdt))); #endif printf("\n"); fflush(stdout); } #ifdef MPI /* isolated computation */ t1 = gettime(); antioptaway=0.0; for (j=0;j<j_max;j++) { for (k=0;k<k_max;k++) { Hopping_Matrix_nocom(0, g_spinor_field[k+k_max], g_spinor_field[k]); Hopping_Matrix_nocom(1, g_spinor_field[2*k_max], g_spinor_field[k+k_max]); antioptaway += creal(g_spinor_field[2*k_max][0].s0.c0); } } t2 = gettime(); dt2 = t2-t1; /* compute the bandwidth */ dt=dts-dt2; MPI_Allreduce (&dt, &sdt, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); sdt=sdt/((double)g_nproc); MPI_Allreduce (&dt2, &dt, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); dt=dt/((double)g_nproc); dt=1.0e6f*dt/((double)(k_max*j_max*(VOLUME))); if(g_proc_id==0) { printf("# The following result is printed just to make sure that the calculation is not optimized away: %e\n",antioptaway); printf("# Communication switched off: \n# (%d Mflops [%d bit arithmetic])\n", (int)(1608.0f/dt),(int)sizeof(spinor)/3); #ifdef OMP printf("# Mflops per OpenMP thread ~ %d\n",(int)(1608.0f/(omp_num_threads*dt))); #endif printf("\n"); fflush(stdout); } sdt=sdt/((double)k_max); sdt=sdt/((double)j_max); sdt=sdt/((double)(2*SLICE)); if(g_proc_id==0) { printf("# The size of the package is %d bytes.\n",(SLICE)*192); #ifdef _USE_HALFSPINOR printf("# The bandwidth is %5.2f + %5.2f MB/sec\n", 192./sdt/1024/1024, 192./sdt/1024./1024); #else printf("# The bandwidth is %5.2f + %5.2f MB/sec\n", 2.*192./sdt/1024/1024, 2.*192./sdt/1024./1024); #endif } #endif fflush(stdout); } else { /* the non even/odd case now */ /*initialize the pseudo-fermion fields*/ j_max=1; sdt=0.; for (k=0;k<k_max;k++) { random_spinor_field(g_spinor_field[k], VOLUME, 0); } while(sdt < 3.) { #ifdef MPI MPI_Barrier(MPI_COMM_WORLD); #endif t1 = gettime(); for (j=0;j<j_max;j++) { for (k=0;k<k_max;k++) { D_psi(g_spinor_field[k+k_max], g_spinor_field[k]); antioptaway+=creal(g_spinor_field[k+k_max][0].s0.c0); } } t2 = gettime(); dt=t2-t1; #ifdef MPI MPI_Allreduce (&dt, &sdt, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); #else sdt = dt; #endif qdt=dt*dt; #ifdef MPI MPI_Allreduce (&qdt, &sqdt, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); #else sqdt = qdt; #endif sdt=sdt/((double)g_nproc); sqdt=sqrt(sqdt/g_nproc-sdt*sdt); j_max*=2; } j_max=j_max/2; dts=dt; sdt=1.0e6f*sdt/((double)(k_max*j_max*(VOLUME))); sqdt=1.0e6f*sqdt/((double)(k_max*j_max*(VOLUME))); if(g_proc_id==0) { printf("# The following result is just to make sure that the calculation is not optimized away: %e\n", antioptaway); printf("# Total compute time %e sec, variance of the time %e sec. (%d iterations).\n", sdt, sqdt, j_max); printf("\n# (%d Mflops [%d bit arithmetic])\n", (int)(1680.0f/sdt),(int)sizeof(spinor)/3); #ifdef OMP printf("# Mflops per OpenMP thread ~ %d\n",(int)(1680.0f/(omp_num_threads*sdt))); #endif printf("\n"); fflush(stdout); } } #ifdef HAVE_LIBLEMON if(g_proc_id==0) { printf("# Performing parallel IO test ...\n"); } xlfInfo = construct_paramsXlfInfo(0.5, 0); write_gauge_field( "conf.test", 64, xlfInfo); free(xlfInfo); if(g_proc_id==0) { printf("# done ...\n"); } #endif #ifdef MPI MPI_Finalize(); #endif #ifdef OMP free_omp_accumulators(); #endif free_gauge_field(); free_geometry_indices(); free_spinor_field(); free_moment_field(); return(0); }
double reweighting_factor_nd(const int N) { int i, n_iter; double sq_norm, corr, sum=0., sq_sum = 0., temp1; double mu1, mu2; complex temp2; mu1 = g_mu1; mu2 = g_mu1; /* Use spinor_field 2,3,5 */ /* in order not to conflict with anything else... */ for(i = 0; i < N; i++) { random_spinor_field(g_chi_up_spinor_field[2],VOLUME/2, 1); random_spinor_field(g_chi_dn_spinor_field[2],VOLUME/2, 1); zero_spinor_field(g_chi_up_spinor_field[3],VOLUME/2); zero_spinor_field(g_chi_dn_spinor_field[3],VOLUME/2); temp1 = phmc_ptilde_cheby_coef[0]; phmc_ptilde_cheby_coef[0] = temp1 - 1; Poly_tilde_ND(g_chi_up_spinor_field[3], g_chi_dn_spinor_field[3], phmc_ptilde_cheby_coef, phmc_ptilde_n_cheby, g_chi_up_spinor_field[2], g_chi_dn_spinor_field[2]); phmc_ptilde_cheby_coef[0] = temp1; temp2 = scalar_prod(g_chi_up_spinor_field[2], g_chi_up_spinor_field[3], VOLUME/2, 1); if(temp2.im > 1.0e-8) { printf("!!! WARNING Immaginary part of CORR-UP LARGER than 10^-8 !!! \n"); printf(" CORR-UP: Re=%12.10e Im=%12.10e \n", temp2.re, temp2.im); } corr = temp2.re; printf(" CORR-UP: Re=%12.10e \n", corr); temp2 = scalar_prod(g_chi_dn_spinor_field[2], g_chi_dn_spinor_field[3], VOLUME/2, 1); if(temp2.im > 1.0e-8) { printf("!!! WARNING Immaginary part of CORR_DN LARGER than 10^-8 !!! \n"); printf(" CORR-DN: Re=%12.10e Im=%12.10e \n", temp2.re, temp2.im); } corr += temp2.re; printf(" CORR-DN: Re=%12.10e \n", temp2.im); temp1 = -corr; sum += temp1; sq_sum += temp1*temp1; printf("rew: n_iter = %d, sq_norm = %e, corr = %e\n", n_iter, sq_norm, corr); /* random_spinor_field(g_spinor_field[2],VOLUME/2, 1); g_mu = mu2; zero_spinor_field(g_spinor_field[3],VOLUME/2); n_iter = solve_cg(3, 2, 0., 1.e-15, 1); g_mu = mu1; Qtm_pm_psi(g_spinor_field[5] , g_spinor_field[3]); sq_norm = square_norm(g_spinor_field[2], VOLUME/2, 1); corr = scalar_prod_r(g_spinor_field[2], g_spinor_field[5], VOLUME/2, 1); sq_norm -= corr; temp1 = sq_norm; sum += temp1; sq_sum += temp1*temp1; printf("rew: n_iter = %d, sq_norm = %e, corr = %e\n", n_iter, sq_norm, corr); */ } sum/=(double)N; sq_sum/=(double)N; printf("rew: factor = %e, err = %e\n", sum, sqrt(sum*sum-sq_sum)/((double)N-1)); return(sum); }
void index_jd(int * nr_of_eigenvalues_ov, const int max_iterations, const double precision_ov, char *conf_filename, const int nstore, const int method){ complex *eval; spinor *eigenvectors_ov, *eigenvectors_ov_; spinor *lowvectors, *lowvectors_; int i=0 , k=0, returncode=0, index = 0, determined = 0, signed_index = 0; char filename[120]; FILE * ifs = NULL; matrix_mult Operator[2]; double absdifference; const int N2 = VOLUMEPLUSRAND; #ifdef MPI double atime, etime; #endif double lowestmodes[20]; int intsign, max_iter, first_blocksize = 1; int * idx = NULL; /********************** * For Jacobi-Davidson **********************/ int verbosity = 3, converged = 0, blocksize = 1, blockwise = 0; int solver_it_max = 50, j_max, j_min, v0dim = 0; double * eigenvalues_ov = NULL; double decay_min = 1.7, threshold_min = 1.e-3, prec; WRITER *writer=NULL; spinor *s; double sqnorm; paramsPropagatorFormat *propagatorFormat = NULL; double ap_eps_sq; int switch_on_adaptive_precision = 0; double ov_s = 0; /********************** * General variables **********************/ eval= calloc((*nr_of_eigenvalues_ov),sizeof(complex)); shift = 0.0; // ov_s = 0.5*(1./g_kappa - 8.) - 1.; ap_eps_sq = precision_ov*precision_ov; #if (defined SSE || defined SSE2 ) eigenvectors_ov_= calloc(VOLUMEPLUSRAND*(*nr_of_eigenvalues_ov)+1, sizeof(spinor)); eigenvectors_ov = (spinor *)(((unsigned long int)(eigenvectors_ov_)+ALIGN_BASE)&~ALIGN_BASE); lowvectors_ = calloc(2*first_blocksize*VOLUMEPLUSRAND+1, sizeof(spinor)); lowvectors = (spinor *)(((unsigned long int)(lowvectors_)+ALIGN_BASE)&~ALIGN_BASE); #else // eigenvectors_ov_ = calloc(VOLUMEPLUSRAND*(*nr_of_eigenvalues_ov), sizeof(spinor)); eigenvectors_ov_ = calloc(VOLUMEPLUSRAND*(*nr_of_eigenvalues_ov), sizeof(spinor)); lowvectors_ = calloc(2*first_blocksize*VOLUMEPLUSRAND, sizeof(spinor)); eigenvectors_ov = eigenvectors_ov_; lowvectors = lowvectors_; #endif // idx = malloc((*nr_of_eigenvalues_ov)*sizeof(int)); idx = malloc((*nr_of_eigenvalues_ov)*sizeof(int)); Operator[0]=&Dov_proj_plus; Operator[1]=&Dov_proj_minus; if(g_proc_id == g_stdio_proc){ printf("Computing first the two lowest modes in the positive and negative chirality sector, respectively\n"); if(switch_on_adaptive_precision == 1) { printf("We have switched on adaptive precision with ap_eps_sq = %e!\n", ap_eps_sq); } printf("We have set the mass to zero within this computation!\n"); fflush(stdout); } prec = precision_ov; j_min = 8; j_max = 16; max_iter = 70; #ifdef MPI atime = MPI_Wtime(); #endif v0dim = first_blocksize; blocksize = v0dim; for(intsign = 0; intsign < 2; intsign++){ converged = 0; if(g_proc_id == g_stdio_proc){ printf("%s chirality sector: \n", intsign ? "negative" : "positive"); fflush(stdout); } if(max_iter == 70){ /******************************************************************** * * We need random start spinor fields, but they must be half zero, * that's why we apply the Projektor once * ********************************************************************/ for(i = 0; i < first_blocksize; i++) { random_spinor_field(&lowvectors[(first_blocksize*intsign+i)*VOLUMEPLUSRAND],N2,0); Proj(&lowvectors[(first_blocksize*intsign+i)*VOLUMEPLUSRAND], &lowvectors[(first_blocksize*intsign+i)*VOLUMEPLUSRAND],N2, intsign); } } jdher(VOLUME*sizeof(spinor)/sizeof(complex), VOLUMEPLUSRAND*sizeof(spinor)/sizeof(complex), shift, prec, blocksize, j_max, j_min, max_iter, blocksize, blockwise, v0dim, (complex*) &lowvectors[first_blocksize*intsign*VOLUMEPLUSRAND], CG, solver_it_max, threshold_min, decay_min, verbosity, &converged, (complex*) &lowvectors[first_blocksize*intsign*VOLUMEPLUSRAND], &lowestmodes[first_blocksize*intsign], &returncode, JD_MINIMAL, 1, Operator[intsign]); if(converged != blocksize && max_iter == 70){ if(g_proc_id == g_stdio_proc){ printf("Restarting %s chirality sector with more iterations!\n", intsign ? "negative" : "positive"); fflush(stdout); } max_iter = 140; intsign-=1; } else { max_iter = 70; /* Save the allready computed eigenvectors_ov */ for(i = 0; i< first_blocksize; i++) { sprintf(filename, "eigenvector_of_D%s.%.2d.%s.%.4d",((intsign==0)?"plus":"minus"),i , conf_filename, nstore); construct_writer(&writer, filename, 0); /* todo write propagator format */ propagatorFormat = construct_paramsPropagatorFormat(64, 1); write_propagator_format(writer, propagatorFormat); free(propagatorFormat); s=(spinor*)&lowvectors[first_blocksize*intsign*VOLUMEPLUSRAND]; write_spinor(writer, &s,NULL, 1, 64); destruct_writer(writer); writer=NULL; sqnorm=square_norm(s,VOLUME,1); printf(" wrote eigenvector of overlap operator !!! | |^2 = %e \n",sqnorm); } } } #ifdef MPI etime = MPI_Wtime(); if(g_proc_id == g_stdio_proc){ printf("It took %f sec to determine the sector with zero modes, if any!\n", etime-atime); } #endif /*Compare the two lowest modes */ absdifference = fabs(lowestmodes[0]-lowestmodes[first_blocksize]); if(absdifference < 0.1*max(lowestmodes[0],lowestmodes[first_blocksize])){ /* They are equal within the errors */ if(g_proc_id == g_stdio_proc){ printf("Index is 0!\n"); fflush(stdout); sprintf(filename, "eigenvalues_of_overlap_proj.%s.%.4d", conf_filename, nstore); ifs = fopen(filename, "w"); printf("\nThe following lowest modes have been computed:\n"); fprintf(ifs, "Index is 0\n\n"); fprintf(ifs, "Sector with positive chirality:\n"); for(i = 0; i < first_blocksize; i++) { lowestmodes[i] = 2.*(1.+ov_s)*lowestmodes[i]; fprintf(ifs, "%d %e positive\n", i, lowestmodes[i]); printf("%d %e positive\n", i, lowestmodes[i]); } fprintf(ifs, "Sector with negative chirality:\n"); for(i = 0; i < first_blocksize; i++) { lowestmodes[i+first_blocksize] = 2.*(1.+ov_s)*lowestmodes[i+first_blocksize]; fprintf(ifs, "%d %e negative\n", i, lowestmodes[i+first_blocksize]); printf("%d %e negative\n", i, lowestmodes[i+first_blocksize]); } fclose(ifs); for(k = 0; k < 2; k++) { sprintf(filename, "eigenvalues_of_D%s.%s.%.4d", k ? "minus" : "plus", conf_filename, nstore); ifs = fopen(filename, "w"); fwrite(&first_blocksize, sizeof(int), 1, ifs); index = 0; fwrite(&index, sizeof(int), 1, ifs); for(i = 0; i < first_blocksize; i++) { fwrite(&lowestmodes[((intsign+1)%2)*first_blocksize+i], sizeof(double), 1, ifs); } fclose(ifs); } } } else{ /* they are not equal */ /* determine the sector with not trivial topology */ if(lowestmodes[0] < lowestmodes[first_blocksize]){ intsign = 0; } else{ intsign = 1; } if(g_proc_id == g_stdio_proc){ printf("Computing now up to %d modes in the sector with %s chirality\n", (*nr_of_eigenvalues_ov), intsign ? "negative" : "positive"); fflush(stdout); } /* Here we set the (absolute) precision to be */ /* such that we can compare to the lowest mode */ /* in the other sector */ prec = (lowestmodes[first_blocksize*((intsign+1)%2)])*1.e-1; eigenvalues_ov = (double*)malloc((*nr_of_eigenvalues_ov)*sizeof(double)); /* Copy the allready computed eigenvectors_ov */ for(i = 0; i < first_blocksize; i++) { assign(&eigenvectors_ov[i], &lowvectors[(first_blocksize*intsign+i)*VOLUMEPLUSRAND],N2); eigenvalues_ov[i] = lowestmodes[first_blocksize*intsign+i]; } #ifdef MPI atime = MPI_Wtime(); #endif blocksize = 3; j_min = 8; j_max = 16; converged = first_blocksize; for(i = first_blocksize; i < (*nr_of_eigenvalues_ov); i+=3) { if((i + blocksize) > (*nr_of_eigenvalues_ov) ) { blocksize = (*nr_of_eigenvalues_ov) - i; } /* Fill up the rest with random spinor fields */ /* and project it to the corresponding sector */ for(v0dim = i; v0dim < i+blocksize; v0dim++){ random_spinor_field(&eigenvectors_ov[v0dim*VOLUMEPLUSRAND],N2,0); Proj(&eigenvectors_ov[v0dim*VOLUMEPLUSRAND], &eigenvectors_ov[v0dim*VOLUMEPLUSRAND],N2, intsign); } v0dim = blocksize; returncode = 0; /* compute minimal eigenvalues */ #ifdef MPI /* pjdher(VOLUME*sizeof(spinor)/sizeof(complex), VOLUMEPLUSRAND*sizeof(spinor)/sizeof(complex), shift, prec, omega, n_omega, ev_tr, i+blocksize, j_max, j_min, max_iterations, blocksize, blockwise, v0dim, (complex*)(&eigenvectors_ov[i*VOLUMEPLUSRAND]), CG, solver_it_max, threshold_min, decay_min, verbosity, &converged, (complex*) eigenvectors_ov, eigenvalues_ov, &returncode, JD_MINIMAL, 1, use_AV, Operator[intsign]);*/ #else jdher(VOLUME*sizeof(spinor)/sizeof(complex), VOLUMEPLUSRAND*sizeof(spinor)/sizeof(complex), shift, prec, blocksize, j_max, j_min, max_iter, blocksize, blockwise, v0dim, (complex*) &eigenvectors_ov[i*VOLUMEPLUSRAND], CG, solver_it_max, threshold_min, decay_min, verbosity, &converged, (complex*) eigenvectors_ov, eigenvalues_ov, &returncode, JD_MINIMAL, 1, Operator[intsign]); #endif /* Save eigenvectors_ov temporary */ /* in order to be able to restart */ for (k=i; k < converged; k++){ if(intsign == 0){ sprintf(filename, "eigenvector_of_Dplus.%.2d.%s.%.4d", k, conf_filename, nstore); } else{ sprintf(filename, "eigenvector_of_Dminus.%.2d.%s.%.4d", k, conf_filename, nstore); } /* write_spinorfield(&eigenvectors_ov[k*VOLUMEPLUSRAND], filename);*/ } /* order the eigenvalues_ov and vectors */ for(k = 0; k < converged; k++) { idx[k] = k; } /* quicksort(converged, eigenvalues_ov, idx);*/ /* Check whether the index is detemined */ index = 0; for(k = 0; k < converged; k++) { absdifference = fabs(lowestmodes[first_blocksize*((intsign+1)%2)] - eigenvalues_ov[k]); if(absdifference < 0.1*lowestmodes[first_blocksize*((intsign+1)%2)]) { /* We have found the first non zero */ if(k < converged-1) { determined = 1; break; } else { blocksize = 1; shift = eigenvalues_ov[converged-1]; } } else { index++; } } /* If we have determined the index or */ /* hit the maximal number of ev */ if(determined == 1 || converged == (*nr_of_eigenvalues_ov)) { break; } else if(g_proc_id == g_stdio_proc) { if(blocksize != 1) { printf("Index %s (or equal) than %s%d, continuing!\n\n", intsign ? "lower" : "bigger", intsign ? "-" : "+", index); fflush( stdout ); } else { printf("Index is %s%d, one non zero is missing, continuing!\n\n", intsign ? "-" : "+", index); fflush( stdout ); } } } #ifdef MPI etime = MPI_Wtime(); #endif /* Save the eigenvectors_ov */ for(i = 0; i < converged; i++){ eval[i].re = 2.*(1.+ov_s)*eigenvalues_ov[i]; eval[i].im = 0.; if(intsign == 0){ sprintf(filename, "eigenvector_of_Dplus.%.2d.%s.%.4d", i, conf_filename, nstore); } else{ sprintf(filename, "eigenvector_of_Dminus.%.2d.%s.%.4d", i, conf_filename, nstore); } /* write_spinorfield(&eigenvectors_ov[idx[i]*VOLUMEPLUSRAND], filename);*/ } /* Some Output */ if(g_proc_id == g_stdio_proc) { printf("Index is %s%d!\n", intsign ? "-" : "+", index); #ifdef MPI printf("Zero modes determined in %f sec!\n", etime-atime); #endif } if(g_proc_id == 0) { sprintf(filename, "eigenvalues_of_overlap_proj.%s.%.4d", conf_filename, nstore); ifs = fopen(filename, "w"); printf("\nThe following lowest modes have been computed:\n"); fprintf(ifs, "Index is %s%d!\n\n", intsign ? "-" : "+", index); for(k = 0; k < 2; k++) { if(k == intsign) { for (i=0; i < converged; i++) { fprintf(ifs, "%d %e %s\n", i, eval[i].re, intsign ? "negative" : "positive"); printf("%d %e %s\n", i, eval[i].re, intsign ? "negative" : "positive"); } } else { for(i = 0; i < first_blocksize; i++) { lowestmodes[((intsign+1)%2)*first_blocksize+i] = 2.*(1.+ov_s)*lowestmodes[((intsign+1)%2)*first_blocksize+i]; fprintf(ifs, "%d %e %s\n", i, lowestmodes[((intsign+1)%2)*first_blocksize+i], intsign ? "positive" : "negative"); printf("%d %e %s\n", i, lowestmodes[((intsign+1)%2)*first_blocksize+i], intsign ? "positive" : "negative"); } } } fclose(ifs); if(intsign != 0) signed_index = -index; else signed_index = index; for(k = 0; k < 2; k++) { sprintf(filename, "eigenvalues_of_D%s.%s.%.4d", k ? "minus" : "plus", conf_filename, nstore); ifs = fopen(filename, "w"); if(k == intsign) { fwrite(&converged, sizeof(int), 1, ifs); fwrite(&signed_index, sizeof(int), 1, ifs); for (i=index; i < converged; i++) { fwrite(&eval[i].re, sizeof(double), 1, ifs); } } else { fwrite(&first_blocksize, sizeof(int), 1, ifs); fwrite(&signed_index, sizeof(int), 1, ifs); for(i = 0; i < first_blocksize; i++) { fwrite(&lowestmodes[((intsign+1)%2)*first_blocksize+i], sizeof(double), 1, ifs); } } fclose(ifs); } } } switch_on_adaptive_precision = 0; /* Free memory */ free(eigenvectors_ov_); free(lowvectors_); free(eval); free(eigenvalues_ov); free(idx); }