void base_mc(int steps, Fn &&ctrl_tempr) { Move mv; int cycle_steps = 10, len = c.rows(), local_succ_num = 0; double en = total_energy(c), min_en = en; auto min_coord = c; for (int i = 0; i < steps; i++) { auto index = mv.pick(len); auto en_atom_old = atom_energy(c, index); mv.move(c); auto en_atom_new = atom_energy(c, index); if (en_atom_new > en_atom_old && rand() > exp(-(en_atom_new - en_atom_old) / _mc_tempr)) { mv.back(c); } else { en = en - en_atom_old + en_atom_new; local_succ_num++; if (en < min_en) (min_en = en, min_coord = c); } if (i % cycle_steps == cycle_steps - 1) { double local_succ_rate = double(local_succ_num) / cycle_steps; local_succ_num = 0; LOG << i + 1 << ": " << total_dist_energy(c) << "(dist energy) " << total_dih_energy() << "(dih energy) " << _mc_tempr << "(temprature) " << local_succ_rate << "(success rate)" << std::endl; if (! ctrl_tempr(local_succ_rate)) break; } } c = min_coord; gradient(); }
/******************************************************************************** * 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); }
void volume_move(){ total_vol_moves+=1.0; float old_e = total_energy(old_argons); float old_vol = powf(L,3); float new_vol = expf(logf(old_vol) + (random() - 0.5)*VOL_MOVE); float new_L = cbrtf(new_vol); for(size_t i = NA; i>0;i--){ new_argons[i].x*=(new_L/L); new_argons[i].y*=(new_L/L); new_argons[i].z*=(new_L/L); } float new_e = total_energy(new_argons); if (random()<expf(-(1.0/(KB *TEMPERATURE))*((new_e - old_e) + (PRESSURE*(new_vol- old_vol)) - ((NA+1)*(KB*TEMPERATURE)*logf(new_vol/old_vol))))){ accepted_vol_moves +=1.0; memcpy(old_argons, new_argons, sizeof(new_argons)); L=new_L; } else{ memcpy(new_argons,old_argons,sizeof(new_argons)); } }
void translational_move_all(){ total_trans_moves+=(float)NA; float old_e = total_energy(old_argons); // 1. update all atom positions // 2. calculate all energies // 3. accept or reject for(size_t i = NA; i>0; i--){ float random_x = (random()-0.5)*MC_MOVE; float random_y= (random()-0.5)*MC_MOVE; float random_z = (random()-0.5)*MC_MOVE; new_argons[i].x += random_x; new_argons[i].y += random_y; new_argons[i].z += random_z; if(new_argons[i].x<0){ new_argons[i].x+=L; } if(new_argons[i].y<0){ new_argons[i].y+=L; } if(new_argons[i].z<0){ new_argons[i].z+=L; } if(new_argons[i].x>L){ new_argons[i].x-=L; } if(new_argons[i].y>L){ new_argons[i].y-=L; } if(new_argons[i].z>L){ new_argons[i].z-=L; } float new_e = total_energy(new_argons); if (random()<expf(-(1.0/(KB *TEMPERATURE))*(new_e - old_e))){ accepted_trans_moves +=1.0; old_e = new_e; memcpy(old_argons, new_argons, sizeof(new_argons)); } else{ memcpy(new_argons,old_argons,sizeof(new_argons)); } } }
void translational_move(){ total_trans_moves+=1.0; float old_e = total_energy(old_argons); size_t random_particle = (int) round(random()*NA); float random_x = (random()-0.5)*MC_MOVE; float random_y= (random()-0.5)*MC_MOVE; float random_z = (random()-0.5)*MC_MOVE; new_argons[random_particle].x += random_x; new_argons[random_particle].y += random_y; new_argons[random_particle].z += random_z; if(new_argons[random_particle].x<0){ new_argons[random_particle].x+=L; } if(new_argons[random_particle].y<0){ new_argons[random_particle].y+=L; } if(new_argons[random_particle].z<0){ new_argons[random_particle].z+=L; } if(new_argons[random_particle].x>L){ new_argons[random_particle].x-=L; } if(new_argons[random_particle].y>L){ new_argons[random_particle].y-=L; } if(new_argons[random_particle].z>L){ new_argons[random_particle].z-=L; } float new_e = total_energy(new_argons); if (random()<expf(-(1.0/(KB *TEMPERATURE))*(new_e - old_e))){ accepted_trans_moves +=1.0; memcpy(old_argons, new_argons, sizeof(new_argons)); } else{ memcpy(new_argons,old_argons,sizeof(new_argons)); } }
int main(){ FILE *output, *xyzfile; output = fopen("output.data","w"); xyzfile = fopen("trajectory.xyz", "w"); setup_histogram(); setup_system(new_argons); // Comment out one of the two lines, they should be equivalent to // each other. setup_system(old_argons); // memcpy(&old_argons, &new_argons, sizeof(new_argons)); print_startup_info(); /* Don't attempt a vol move every n steps frenkel smit pg 119 */ srand(time(NULL)); print_XYZ(old_argons, NULL); printf("\n*****************\n"); printf("Equilibration run\n"); printf("*****************\n\n"); fprintf(output,"Energy \t Vol \t L\n"); for(size_t n_equil = 0; n_equil < NUM_EQUIL; n_equil++){ if(random()*(NA+1)+1<= NA){ translational_move(); } else{ volume_move(); } } printf("\nStats run\n"); printf("*****************\n\n"); float temp_E = 0.0; float count = 0.0; float percent1 = 0.0; float percent2 = 0.0; accepted_vol_moves = 0.0; accepted_trans_moves = 0.0; for(size_t n_stats = 0; n_stats < NUM_STATS; n_stats++){ temp_E = total_energy(old_argons); count +=1.0; percent1 = accepted_vol_moves/total_vol_moves; percent2 = accepted_trans_moves/total_trans_moves; printf("%g\t%g\t%g\t%g\t%g\t%g\t%g\n",L,total_energy(old_argons)*6.022E23/NA,currdensity,total_vol_moves,total_trans_moves,percent1,percent2); if(random()*(NA+1)+1<= NA){ translational_move(); } else{ volume_move(); } if(n_stats % SAMPLE_FREQ == 0){ make_histogram(); temp_E = total_energy(old_argons); currdensity = (NA*39.948/6.022E23)/powf(L*100.0,3); fprintf(output,"%g\t%g\t%g\n", temp_E, powf(L,3),L); avg_E += temp_E/((float)NUM_STATS / SAMPLE_FREQ); avg_L += L/((float)NUM_STATS/ SAMPLE_FREQ); } print_XYZ(old_argons, xyzfile); } save_histogram(); printf("Avg E %g\n", avg_E); printf("Avg L %g\n", avg_L); printf("\nXYZ OF ARGS\n"); printf("*****************\n\n"); print_XYZ(old_argons, NULL); fclose(output); fclose(xyzfile); printf("\n\n\nSuccessful Termination\n" ); return 0; }
/************************ begin main **********************************/ int main() { FILE *fp; /* file to output data */ int lattice[ SIZE+1 ]; /* 1d lattice for spins */ double T = 1; /* temperature loop variable */ int i, j, k; /* loop variables */ double E, E_avg, E_tot=0; /* for energy observables */ double norm; int de; int samples; int step[TESTS] = {1, 5, 10, 25, 50, 100, 150, 200, 250, 500, 750, 1000, 5000, 10000, 50000, 75000, 100000, 200000, 500000, 750000}; /* initialize random number generator */ init_KISS(); fp = fopen("MCsteps.txt", "w"); fprintf(fp, "# steps, energy\n"); fill_lattice(lattice); initialize(lattice, T); E = total_energy(lattice); E_tot = 0; samples = 0; i = 0; k = 0; while( i <= 18 ) { /* Metropolis loop */ for (j=0; j<=SIZE; j++) { de = new_energy(lattice, j) - local_energy(lattice, j); if ( test_flip(lattice, j, T, de) ) { flip(lattice, j); E += de; } } if ( k % 20 == 0 ) { E_tot += E / 2.0; samples++; } if ( samples == step[i] ) { norm = 1 / ((double)samples * SIZE); E_avg = E_tot * norm; fprintf(fp, "%d, %f\n", samples, E_avg); i++; } k++; } fclose(fp); return 0; }
main (int argc, char **argv) { /* Allocate memory for the structure grid */ GRID_INFO_TYPE *grid = (GRID_INFO_TYPE *)malloc(sizeof(GRID_INFO_TYPE)); /* Initialize MPI */ MPI_Init(&argc, &argv); /* Find out this process number */ MPI_Comm_rank(MPI_COMM_WORLD, &rank); /* Find out the number of processes */ MPI_Comm_size(MPI_COMM_WORLD, &nworkers); Setup_grid(grid); int itime; int i; int big_energy,E; int big_mag,M; double E_per_spin; double M_per_spin; NP=sqrt(nworkers); iseed=iseed*(rank+1); itime = 0; big_energy = 0; big_mag = 0; /* get started */ initialize(grid,spin, nbr1, nbr2); boundary(grid,spin, nbr1, nbr2); /* warm up system */ for (i = 1 ; i <= WARM; i++) { itime = i; mcmove(grid,spin, nbr1, nbr2); boundary(grid,spin, nbr1, nbr2); } /* do Monte Carlo steps and collect stuff for averaging */ for (i = (WARM + 1) ; i <= MCS; i++) { itime = i; mcmove(grid,spin, nbr1, nbr2); if(i!=MCS)boundary(grid,spin, nbr1, nbr2); big_mag = big_mag + total_mag(spin); big_energy = big_energy + total_energy(spin,nbr1,nbr2); } printf("Mag %f rank %d time %d\n", 1.0*big_mag/(MCS-WARM), rank, MCS-WARM); MPI_Reduce (&big_mag, &M,1,MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD); /* process 0 adds total magentization from each process to find the net magnetization. */ MPI_Reduce (&big_energy, &E,1,MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD); if(rank==0) { M_per_spin = (float)M/((MCS - WARM)*(nworkers*(LENGTH-2)*(LENGTH-2))); E_per_spin = (float)E/((MCS - WARM)*nworkers*((LENGTH-2)*(LENGTH-2))); // finish off printf("Mag %d Mag/spin %lf rank %d\n",M, M_per_spin, rank); printf("Energy %d Energy/spin %lf rank %d\n",E, E_per_spin, rank); printf("Analytic: Mag/spin %f, Energy/spin -2 to 0\n", mag_analytic(TEMP)); printf("Temperature %lf, Edge length of system %d \n", TEMP , LENGTH); printf("No. of warm-up steps %d, No. of MCS %d \n", WARM , MCS); } print_config(grid, spin, itime ); MPI_Finalize(); /* exit all MPI functions */ }
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); } }