Loading...
Searching...
No Matches
monte_carlo.cpp
Go to the documentation of this file.
#include "monte_carlo.hpp"
#include <cmath>
#include <cstdint>
void monte_carlo_progression(double T, int L, int cycles,
const std::string filename)
{
// Set some variables
data_t data, tmp;
int n_spins = L * L;
// File stuff
std::string directory = utils::dirname(filename);
std::ofstream ofile;
// Create random engine using the mersenne twister
std::random_device rd;
uint32_t rd_sample = rd();
std::mt19937 engine(rd_sample);
std::cout << "Seed: " << rd_sample << std::endl;
IsingModel ising(L, T);
// Create path and open file
utils::mkpath(directory);
ofile.open(filename);
// Loop through cycles
for (size_t i = 1; i <= cycles; i++) {
data += ising.Metropolis();
tmp = data / (i * n_spins);
ofile << i << ',' << tmp.E << ',' << tmp.E2 << ',' << tmp.M << ','
<< tmp.M2 << ',' << tmp.M_abs << '\n';
}
ofile.close();
}
void monte_carlo_progression(double T, int L, int cycles, int value,
const std::string filename)
{
// Set some variables
data_t data, tmp;
int n_spins = L * L;
// File stuff
std::string directory = utils::dirname(filename);
std::ofstream ofile;
// Create random engine using the mersenne twister
std::random_device rd;
uint32_t rd_sample = rd();
std::mt19937 engine(rd());
std::cout << "Seed: " << rd_sample << std::endl;
IsingModel ising(L, T, value);
// Create path and open file
utils::mkpath(directory);
ofile.open(filename);
// Loop through cycles
for (size_t i = 1; i <= cycles; i++) {
data += ising.Metropolis();
tmp = data / (i * n_spins);
ofile << i << ',' << tmp.E << ',' << tmp.E2 << ',' << tmp.M << ','
<< tmp.M2 << ',' << tmp.M_abs << '\n';
}
ofile.close();
}
void pd_estimate(double T, int L, int cycles, const std::string filename)
{
// Set some variables
data_t data, tmp;
int n_spins = L * L;
// File stuff
std::string directory = utils::dirname(filename);
std::ofstream ofile;
IsingModel ising(L, T);
// Create path and open file
utils::mkpath(directory);
ofile.open(filename);
// Loop through cycles
for (size_t i = 1; i <= cycles; i++) {
data = ising.Metropolis() / n_spins;
ofile << data.E << ',' << data.E2 << ',' << data.M << ',' << data.M2
<< ',' << data.M_abs << '\n';
}
ofile.close();
}
// Code for seeing phase transitions.
data_t monte_carlo_serial(int L, double T, int cycles)
{
data_t data;
IsingModel model(L, T);
for (size_t i = 0; i < BURN_IN_TIME; i++) {
model.Metropolis();
}
double E, M;
for (size_t i = 0; i < (uint)cycles; i++) {
data += model.Metropolis();
}
return data;
}
data_t monte_carlo_parallel(int L, double T, int cycles)
{
data_t data;
#pragma omp parallel
{
// Each thread creates an instance of IsingModel.
IsingModel model(L, T);
// Each thread runs the Metropolis algorithm before starting to collect
// samples
for (size_t i = 0; i < BURN_IN_TIME; i++) {
model.Metropolis();
}
// Now each thread work on one loop together, but using their own
// instances of things, but the total of cycles add up.
// static ensure that each thread gets the same amount of iterations
#pragma omp for schedule(static) reduction(+ : data)
for (size_t i = 0; i < (uint)cycles; i++) {
data += model.Metropolis();
}
}
double norm = 1. / (double)cycles;
return data * norm;
}
void phase_transition(int L, double start, double end, int points,
std::function<data_t(int, double, int)> monte_carlo,
std::string outfile)
{
double dt = (end - start) / (double)points;
int cycles = 10000;
int N = L * L;
std::ofstream ofile;
data_t data;
utils::mkpath(utils::dirname(outfile));
ofile.open(outfile);
double temp, CV, X, E_var, M_var;
using utils::scientific_format;
for (size_t i = 0; i < points; i++) {
temp = start + dt * i;
data = monte_carlo(L, temp, cycles);
E_var = (data.E2 - data.E * data.E) / (double)N;
M_var = (data.M2 - data.M_abs * data.M_abs) / (double)N;
ofile << scientific_format(temp) << ','
<< scientific_format(data.E / (double)N) << ','
<< scientific_format(data.M_abs / N) << ','
<< scientific_format(E_var / (temp * temp)) << ','
<< scientific_format(M_var / temp) << '\n';
}
ofile.close();
}
IsingModel
The Ising model in 2 dimensions.
Definition: IsingModel.hpp:37
IsingModel::Metropolis
data_t Metropolis()
The Metropolis algorithm.
Definition: IsingModel.cpp:96
data_t
Definition: data_type.hpp:18
monte_carlo_serial
data_t monte_carlo_serial(int L, double T, int cycles)
Execute the Metropolis algorithm for a certain amount of Monte Carlo cycles.
Definition: monte_carlo.cpp:111
monte_carlo_progression
void monte_carlo_progression(double T, int L, int cycles, const std::string filename)
Write the expected values for each Monte Carlo cycles to file.
Definition: monte_carlo.cpp:17
monte_carlo_parallel
data_t monte_carlo_parallel(int L, double T, int cycles)
Execute the Metropolis algorithm for a certain amount of Monte Carlo cycles in parallel.
Definition: monte_carlo.cpp:128
monte_carlo.hpp
Functions for monte carlo simulations.
phase_transition
void phase_transition(int L, double start_T, double end_T, int points_T, std::function< data_t(int, double, int)> monte_carlo, std::string outfile)
Perform the MCMC algorithm using a range of temperatures.
Definition: monte_carlo.cpp:156
pd_estimate
void pd_estimate(double T, int L, int cycles, const std::string filename)
Estimate the probability distribution for the energy.
Definition: monte_carlo.cpp:85