int main(int argc, char **argv) { double T=0;; double mag=0.0; int N; int i; Ising **S; double tot_Erg=0; double capacity=0.0; double kai=0.0; init_rnd(gus()); N=atoi(argv[1]); S=(Ising **)malloc(sizeof(Ising *) * N); for(i=0; i<N; i++) S[i]=(Ising *)malloc(sizeof(Ising) * N); initialize(N, S); for(T=3.01; T>=0.01; T-=0.01) { mag=0.0; tot_Erg=0.0; kai=0.0; capacity=0.0; for(i=0; i<200000; i++) mcstep(N, T, S); for(i=0; i<200000; i++) { mcstep(N, T, S); mag+=magnetization(N, S); tot_Erg+=energy(N, S); kai+=pow(magnetization(N, S), 2); capacity+=pow(energy(N,S), 2); } mag=mag/200000; tot_Erg=tot_Erg/200000; kai=kai/200000; capacity=capacity/200000; kai=(kai-mag*mag)/T; capacity=(capacity - tot_Erg*tot_Erg)/(T*T); kai=kai*N*N; capacity=capacity*N*N; printf("%lf\t%lf\t%lf\t%lf\t%lf\n", T, mag, tot_Erg, kai, capacity); } free(S); return 0; }
/******************************************************************************** * clusterupdatebatch: Runs clusterupdate multiple times and gets physics as well * as error estimates. *******************************************************************************/ int clusterupdatebatch(lattice_site * lattice, settings conf, double beta, datapoint * data ) { int i,j; double * e_block, * m_block, * e_block_avg, * m_block_avg, \ * e_block_error, * m_block_error, * c_block , * chi_block; gsl_vector * mag_vector; e_block = (double *) malloc(conf.block_size*sizeof(double)); m_block = (double *) malloc(conf.block_size*sizeof(double)); e_block_avg = (double *) malloc(conf.blocks*sizeof(double)); m_block_avg = (double *) malloc(conf.blocks*sizeof(double)); c_block = (double *) malloc(conf.blocks*sizeof(double)); chi_block = (double *) malloc(conf.blocks*sizeof(double)); e_block_error = (double *) malloc(conf.blocks*sizeof(double)); m_block_error = (double *) malloc(conf.blocks*sizeof(double)); mag_vector = gsl_vector_alloc(conf.spindims); //Settle first for(i = 0 ; i < conf.max_settle ; i++) { clusterupdate(lattice,conf,beta); } //Get averages and stdev for messurements for(i = 0 ; i < conf.blocks ; i++) { for(j = 0 ; j < conf.block_size ; j++) { clusterupdate(lattice,conf,beta); e_block[j] = total_energy(lattice,conf); m_block[j] = magnetization(lattice,conf,mag_vector); } e_block_avg[i] = gsl_stats_mean(e_block,1,conf.block_size); e_block_error[i] = gsl_stats_sd(e_block,1,conf.block_size); m_block_avg[i] = gsl_stats_mean(m_block,1,conf.block_size); m_block_error[i] = gsl_stats_sd(m_block,1,conf.block_size); c_block[i] = gsl_pow_2(beta)*gsl_pow_2(e_block_error[i]); chi_block[i] = beta*gsl_pow_2(m_block_error[i]); } (*data).beta = beta; (*data).erg = gsl_stats_mean(e_block_avg,1,conf.blocks); (*data).erg_error = gsl_stats_sd(e_block_avg,1,conf.blocks); (*data).mag = gsl_stats_mean(m_block_avg,1,conf.blocks); (*data).mag_error = gsl_stats_sd(m_block_avg,1,conf.blocks); (*data).c = gsl_stats_mean(c_block,1,conf.blocks); (*data).c_error = gsl_stats_sd(c_block,1,conf.blocks); (*data).chi = gsl_stats_mean(chi_block,1,conf.blocks); (*data).chi_error = gsl_stats_sd(chi_block,1,conf.blocks); free(e_block); free(m_block); free(e_block_avg); free(m_block_avg); free(e_block_error); free(m_block_error); gsl_vector_free(mag_vector); return(0); }
THREADABLE_FUNCTION_END //compute the magnetization void magnetization(complex *magn,complex *magn_proj_x,quad_su3 **conf,int quantization,quad_u1 **u1b,quark_content_t *quark,double residue) { //allocate source and generate it color *rnd[2]={nissa_malloc("rnd_EVN",loc_volh+bord_volh,color),nissa_malloc("rnd_ODD",loc_volh+bord_volh,color)}; generate_fully_undiluted_eo_source(rnd,RND_GAUSS,-1); //call inner function magnetization(magn,magn_proj_x,conf,quantization,u1b,quark,residue,rnd); for(int par=0;par<2;par++) nissa_free(rnd[par]); }
//measure magnetization void measure_magnetization(quad_su3 **conf,theory_pars_t &theory_pars,magnetization_meas_pars_t &meas_pars,int iconf,int conf_created) { FILE *file=open_file(meas_pars.path,conf_created?"w":"a"); FILE *file_proj=open_file(meas_pars.path+"%s_proj_x",conf_created?"w":"a"); int ncopies=meas_pars.ncopies; for(int icopy=0;icopy<ncopies;icopy++) { master_fprintf(file,"%d",iconf); //measure magnetization for each quark for(int iflav=0;iflav<theory_pars.nflavs();iflav++) { if(theory_pars.quarks[iflav].discretiz!=ferm_discretiz::ROOT_STAG) crash("not defined for non-staggered quarks"); complex magn={0,0}; complex magn_proj_x[glb_size[1]]; //this makes pair and pact with "1" and "2" upstairs for(int i=0;i<glb_size[1];i++) magn_proj_x[i][RE]=magn_proj_x[i][IM]=0; //loop over hits int nhits=meas_pars.nhits; for(int hit=0;hit<nhits;hit++) { verbosity_lv2_master_printf("Evaluating magnetization for flavor %d/%d, ncopies %d/%d nhits %d/%d\n", iflav+1,theory_pars.nflavs(),icopy+1,ncopies,hit+1,nhits); //compute and summ complex temp,temp_magn_proj_x[glb_size[1]]; magnetization(&temp,temp_magn_proj_x,conf,theory_pars.em_field_pars.flag,theory_pars.backfield[iflav],&theory_pars.quarks[iflav],meas_pars.residue); //flag holds quantization //normalize complex_summ_the_prod_double(magn,temp,1.0/nhits); for(int x=0;x<glb_size[1];x++) complex_summ_the_prod_double(magn_proj_x[x],temp_magn_proj_x[x],1.0/nhits); } //output master_fprintf(file,"\t%+016.16lg \t%+016.16lg",magn[RE],magn[IM]); for(int x=0;x<glb_size[1];x++) master_fprintf(file_proj,"%d\t%d\t%d\t%d\t%+016.16lg \t%+016.16lg\n",iconf,icopy,iflav,x,magn_proj_x[x][RE],magn_proj_x[x][IM]); } master_fprintf(file,"\n"); } close_file(file); close_file(file_proj); }
THREADABLE_FUNCTION_END //compute the magnetization THREADABLE_FUNCTION_8ARG(magnetization, complex*,magn, complex*,magn_proj_x, quad_su3**,conf, int,quantization, quad_u1**,u1b, quark_content_t*,quark, double,residue, color**,rnd) { GET_THREAD_ID(); //fixed to Z magnetization int mu=1,nu=2; //allocate source and propagator color *chi[2]={nissa_malloc("chi_EVN",loc_volh+bord_volh,color),nissa_malloc("chi_ODD",loc_volh+bord_volh,color)}; //we need to store phases coords *arg=nissa_malloc("arg",loc_vol+bord_vol,coords); NISSA_PARALLEL_LOOP(ivol,0,loc_vol+bord_vol) get_args_of_quantization[quantization](arg[ivol],ivol,mu,nu); //array to store magnetization on single site (actually storing backward contrib at displaced site) complex *point_magn=nissa_malloc("app",loc_vol,complex); //we add backfield externally because we need them for derivative add_backfield_to_conf(conf,u1b); //invert inv_stD_cg(chi,conf,quark->mass,1000000,residue,rnd); //compute mag magnetization(magn,magn_proj_x,conf,quark,rnd,chi,point_magn,arg,mu,nu); //remove backfield rem_backfield_from_conf(conf,u1b); //free for(int par=0;par<2;par++) nissa_free(chi[par]); nissa_free(point_magn); nissa_free(arg); }
double magnetization(int L, std::vector<std::pair<int, int> >& lattice, int power, const std::vector<double>& v) { return magnetization(L, lattice, power, &v[0]); }
int main() { clock_t begin,end; double time_spent; begin = clock(); int latsizes[7] = {5,64,16,32,64,128,512}; //try these different lattice sizes /* * ntrials : Number of monte carlo steps to run. Each monte carlo step is an attempt to flip N spins. * So for a 4x4 lattice 1 monte carlo step is an attempt to flip 16 times. * N : Lattice size * temp : Array of temperatures to try. * meanE : Array containing mean energy for each temperature. * meanE2 : Array contaiing square of mean energies. Useful to calculate the variance as meanE2 - (meanE)^2 * meanMag : Array for mean magnetization * meanMag2: Array for square mean magnetization. Again used for variance calculation * cv : Specific heat at a temperature * chi : Magnetic susceptibility at a temperature * */ int const ntrials = 1e4; int N = 0; double temp[500] = {0}; double meanE[500] = {0}; double meanE2[500] = {0}; double meanMag[500] = {0}; double meanMag2[500] = {0}; double cv[500] = {0}; double chi[500]={0}; int skip = ntrials*0.2; double E = 0; //loop counters int i,t,ss; //declaring spin array once int *spins = NULL; int **Nbr = NULL; //int spins[19600] = {0}; //int Nbr[19600][4] = {0}; int row = 0; int rowMin = 0; int col = 0; int l = 0; double toss=0; double tempMag = 0; double beta; FILE* stat_file; //char fn_stat[200] = "/home/a/ahamed/scratch/\0"; //monte carlo variables int k,field_k,delE,j; double probRatio; spins = (int *) malloc(sizeof(int)*262144); Nbr = (int **)malloc(sizeof(int *)*262144); Nbr[0] = (int *)malloc(sizeof(int)*262144*4); for(int i=1;i<262144;i++) Nbr[i] = Nbr[i-1]+4; //for (i=0;i<500;i++) // temp[i] = 0.01*(500 - i + 1); for(int cnt=0;cnt<1;cnt++) { N = latsizes[cnt]; srand(time(NULL)); //int* spins = (int *)malloc(N*N * sizeof(int)); /* * This following loop sets of the initial lattice. Initial configuration is completely random */ for(i=0;i<N*N;i++) { /*toss = RAND(0.0,1.0); if(toss > 0.5) spins[i] = -1; else spins[i] = 1;*/ spins[i] = (toss<0.5) - (toss>=0.5); } /* * The neighbour table. Calculate the neighbours and store them in a lookup table so that in every loop a function call is saved */ //int (*Nbr)[4] = (int(*)[4])malloc((sizeof *Nbr)*N*N); for (i = 0; i < N*N; i++) { row = i / N; rowMin = row*N; col = i - rowMin; l=(i - col)/N; Nbr[i][0] = ((i+1) + N)%N + rowMin; Nbr[i][1] = (((l+1) + N)%N)*N + col; Nbr[i][2] = ((i-1) + N)%N + rowMin; Nbr[i][3] = (((l-1) + N)%N)*N + col; } /* * E is the current energy of the lattice. Calculate the energy of the initial random configuration */ E = 0; for(i=0;i<N*N;i++) E = E - spins[i]*spins[Nbr[i][0]] - spins[i]*spins[Nbr[i][1]]; /* * ntrials : Number of monte carlo steps to run. Each monte carlo step is an attempt to flip N spins. * So for a 4x4 lattice 1 monte carlo step is an attempt to flip 16 times. * temp : Array of temperatures to try. * meanE : Array containing mean energy for each temperature. * meanE2 : Array contaiing square of mean energies. Useful to calculate the variance as meanE2 - (meanE)^2 * meanMag : Array for mean magnetization * meanMag2: Array for square mean magnetization. Again used for variance calculation * cv : Specific heat at a temperature * chi : Magnetic susceptibility at a temperature * */ //for (i=0;i<500;i++) // temp[i] = 0.01*(i + 1); //double tempMag = magnetization(spins,N); //FILE* file, stat_file; //char nlat[100]; //sprintf(nlat, "%d", N); //char* end = "spins.txt\0"; //char fn[200] = "/home/a/ahamed/work/\\"; //strcat(fn, strcat(nlat,end)); //file=fopen(fn, "w"); //char* endst = "stat.csv\0"; //char fn_st[200] = "/home/a/ahamed/work/\\"; //strcat(fn_st, strcat(nlat,endst)); //stat_file=fopen(fn_st, "w"); //FILE* file; //FILE* stat_file; //char fn_spins[200] = "/home/a/ahamed/scratch/\0"; //file_name(N,"spins.txt\0",fn_spins); char fn_stat[200] = "/home/a/ahamed/scratch/\0"; //fn_stat = "/home/a/ahamed/scratch/\0"; file_name(N,"stat.csv\0",fn_stat); //file = fopen(fn_spins, "w"); stat_file = fopen(fn_stat,"w"); for(t=0; t< 500; t++) { //double beta = 1/temp[t]; //beta is inverse temperature in boltzmann distrubution beta = 1/( 0.01*(500 - i + 1)); for(i=1;i<ntrials;i++) //run ntrials MC steps { //int k,field_k,delE; //double probRatio, toss; //Monte Carlo Loop //One Monte Carlo step is attempt to flip (N*N) spins for(ss=0; ss<N*N;ss++) { k = floor(RAND(1,N*N)); //get a random site on lattice field_k = spins[Nbr[k][0]] + spins[Nbr[k][1]] +spins[Nbr[k][2]] + spins[Nbr[k][3]]; // Calculate the neighbouring field on it delE = 2*field_k*spins[k]; //calculate the change in energy if the spin was to be flipped probRatio = exp(-1*beta*delE); //calculate the boltzmann prob of the state corresponding to the energy toss = RAND(0,1); //toss a coin, generate a random number between 0 and 1 if(toss < probRatio) // if less than probratio accept, i.e. accept the next state with a probability with probratio { spins[k] = -1*spins[k]; //flip the spin E = E + delE; //calculate the change in energy } } if(i>=skip) //skip is how many MC steps to let the system equilibriate. collect stats every markov step or every 10 { tempMag = magnetization(spins, N); meanE[t] = (meanE[t] + E); meanMag[t] = (meanMag[t]) + tempMag; meanE2[t] = (meanE2[t]) + E*E; meanMag2[t] = (meanMag2[t]) + tempMag*tempMag; } } j= (ntrials - skip); meanE[t] = meanE[t]/j; meanMag[t] = meanMag[t]/j; meanE2[t] = meanE2[t]/j; meanMag2[t] = meanMag2[t]/j; cv[t] = (beta*beta*(meanE2[t] - meanE[t]*meanE[t]))/(N*N); chi[t] = (beta*(meanMag2[t] - meanMag[t]*meanMag[t]))/(N*N); fprintf(stat_file, "%f\t%f\t%f\t%f\n", meanMag[t], meanE[t], chi[t], cv[t]); //for (int i=0;i<N*N;i++) // fprintf(file, "%d\t", spins[i]); //fprintf(file,"\n"); } //fclose(file); fclose(stat_file); free(spins); } end = clock(); time_spent = (double)(end - begin) / CLOCKS_PER_SEC; printf("Time spent in execution %f\n",time_spent); return time_spent; }
int main (int argc, char * argv[]) { int i,j; int size = argc - 2; int *data = (int *) malloc(sizeof(int)*size); int sidelength, spacedims, spindims; int * loc; int num; gsl_rng * rng; const gsl_rng_type * RngType; gsl_rng_env_setup(); RngType = gsl_rng_default; rng = gsl_rng_alloc (RngType); gsl_vector ** lattice; gsl_vector * magnet; double mag,energy; /* Read in data */ if(size != 0) { for (i = 0 ; i< size ; i++) { data[i] = atoi(argv[i+2]); } } switch(atoi(argv[1])) { case 0: /* Magnetization */ /********************************************** * Outputs magnetization of a uniform lattice * **********************************************/ sidelength = data[0]; spacedims = data[1]; spindims = data[2]; magnet = gsl_vector_alloc(spindims); lattice = allocate_lattice(sidelength,spacedims,spindims); set_homogenious_spins(lattice,sidelength,spacedims,spindims); mag = magnetization(lattice,sidelength,spacedims,spindims,magnet); free_lattice(lattice,sidelength,spacedims); printf("%2.1f\n",mag); break; case 1: /* Local Energy */ /********************************************** * Outputs energy of a uniform lattice point * **********************************************/ sidelength = data[0]; spacedims = data[1]; spindims = data[2]; loc = (int *) malloc(sizeof(int)*spacedims); for(i = 0 ; i < spacedims ; i++) loc[i] = data[i+3]; lattice = allocate_lattice(sidelength,spacedims,spindims); set_homogenious_spins(lattice,sidelength,spacedims,spindims); energy = 0; energy = local_energy(lattice, sidelength, spacedims, spindims, loc); free_lattice(lattice,sidelength,spacedims); printf("%1.3e\n",energy); break; case 2: /* Total Energy */ /******************************************** * Outputs energy of a checkerboard lattice * ********************************************/ sidelength = data[0]; spacedims = data[1]; spindims = data[2]; lattice = allocate_lattice(sidelength,spacedims,spindims); set_checkerboard_spins(lattice,sidelength,spacedims,spindims); energy = total_energy(lattice, sidelength, spacedims, spindims ); printf("%1.3e\n",energy); break; default: printf("No arguments!\n"); exit(EXIT_FAILURE); } }