Beispiel #1
0
    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();
    }
Beispiel #2
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);
}
Beispiel #3
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));
    }
}
Beispiel #4
0
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));
      }
    }
}
Beispiel #5
0
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));
    }
}
Beispiel #6
0
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;
}
Beispiel #7
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 */
}
Beispiel #9
0
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);
  }

}