2 Dimensional Ising Model
Simulate the change in energy and magnetization in a ferro magnet
Loading...
Searching...
No Matches
monte_carlo.cpp
Go to the documentation of this file.
1/** @file monte_carlo.cpp
2 *
3 * @author Cory Alexander Balaton (coryab)
4 * @author Janita Ovidie Sandtrøen Willumsen (janitaws)
5 *
6 * @version 1.0
7 *
8 * @brief Implementation of the monte carlo functions
9 *
10 * @bug No known bugs
11 * */
12#include "monte_carlo.hpp"
13
14namespace montecarlo {
15void progression(double T, int L, int cycles, const std::string filename,
16 int burn_in_time)
17{
18 // Set some variables
19 data_t data, tmp;
20 int n_spins = L * L;
21
22 // File stuff
23 std::string directory = utils::dirname(filename);
24 std::ofstream ofile;
25
26 // Create random engine using the mersenne twister
27 std::random_device rd;
28 uint32_t rd_sample = rd();
29 std::mt19937 engine(rd_sample);
30
31 std::cout << "Seed: " << rd_sample << std::endl;
32
33 IsingModel ising(L, T);
34
35 // Create path and open file
36 utils::mkpath(directory);
37 ofile.open(filename);
38
39 for (size_t i = 0; i < burn_in_time; i++) {
40 ising.Metropolis();
41 }
42
43 // Loop through cycles
44 for (size_t i = 1; i <= cycles; i++) {
45 data += ising.Metropolis();
46 tmp = data / (i * n_spins);
47 ofile << i << ',' << tmp.E << ',' << tmp.E2 << ',' << tmp.M << ','
48 << tmp.M2 << ',' << tmp.M_abs << '\n';
49 }
50 ofile.close();
51}
52
53void progression(double T, int L, int cycles, int value,
54 const std::string filename, int burn_in_time)
55{
56 // Set some variables
57 data_t data, tmp;
58 int n_spins = L * L;
59
60 // File stuff
61 std::string directory = utils::dirname(filename);
62 std::ofstream ofile;
63
64 // Create random engine using the mersenne twister
65 std::random_device rd;
66 uint32_t rd_sample = rd();
67 std::mt19937 engine(rd());
68
69 std::cout << "Seed: " << rd_sample << std::endl;
70
71 IsingModel ising(L, T, value);
72
73 for (size_t i = 0; i < burn_in_time; i++) {
74 ising.Metropolis();
75 }
76
77 // Create path and open file
78 utils::mkpath(directory);
79 ofile.open(filename);
80
81 // Loop through cycles
82 for (size_t i = 1; i <= cycles; i++) {
83 data += ising.Metropolis();
84 tmp = data / (i * n_spins);
85 ofile << i << ',' << tmp.E << ',' << tmp.E2 << ',' << tmp.M << ','
86 << tmp.M2 << ',' << tmp.M_abs << '\n';
87 }
88 ofile.close();
89}
90
91void pd_estimate(double T, int L, int cycles, const std::string filename,
92 int burn_in_time)
93{
94 // Set some variables
95 data_t data, tmp;
96 int n_spins = L * L;
97
98 // File stuff
99 std::string directory = utils::dirname(filename);
100 std::ofstream ofile;
101
102 IsingModel ising(L, T);
103
104 for (size_t i = 0; i < burn_in_time; i++) {
105 ising.Metropolis();
106 }
107
108 // Create path and open file
109 utils::mkpath(directory);
110 ofile.open(filename);
111
112 // Loop through cycles
113 for (size_t i = 1; i <= cycles; i++) {
114 data = ising.Metropolis() / n_spins;
115 ofile << data.E << ',' << data.E2 << ',' << data.M << ',' << data.M2
116 << ',' << data.M_abs << '\n';
117 }
118 ofile.close();
119}
120
121// Code for seeing phase transitions.
122data_t mcmc_serial(int L, double T, int cycles, int burn_in_time)
123{
124 data_t data;
125 IsingModel model(L, T);
126
127 for (size_t i = 0; i < burn_in_time; i++) {
128 model.Metropolis();
129 }
130
131 double E, M;
132 for (size_t i = 0; i < (uint)cycles; i++) {
133 data += model.Metropolis();
134 }
135
136 double norm = 1. / (double)cycles;
137
138 return data * norm;
139}
140
141data_t mcmc_parallel(int L, double T, int cycles, int burn_in_time)
142{
143 data_t data;
144#pragma omp parallel
145 {
146 // Each thread creates an instance of IsingModel.
147 IsingModel model(L, T);
148
149 // Each thread runs the Metropolis algorithm before starting to collect
150 // samples
151 for (size_t i = 0; i < burn_in_time; i++) {
152 model.Metropolis();
153 }
154
155 // Now each thread work on one loop together, but using their own
156 // instances of things, but the total of cycles add up.
157 // static ensure that each thread gets the same amount of iterations
158#pragma omp for schedule(static) reduction(+ : data)
159 for (size_t i = 0; i < (uint)cycles; i++) {
160 data += model.Metropolis();
161 }
162 }
163
164 double norm = 1. / (double)cycles;
165
166 return data * norm;
167}
168
169void phase_transition(int L, double start, double end, int points, int cycles,
170 std::function<data_t(int, double, int, int)> monte_carlo,
171 std::string outfile, int burn_in_time)
172{
173 double dt = (end - start) / (double)points;
174 int N = L * L;
175 std::ofstream ofile;
176
177 data_t data;
178
179 utils::mkpath(utils::dirname(outfile));
180 ofile.open(outfile);
181
182 double temp, CV, X, E_var, M_var;
183
184 using utils::scientific_format;
185 for (size_t i = 0; i < points; i++) {
186 temp = start + dt * i;
187 data = monte_carlo(L, temp, cycles, burn_in_time);
188 E_var = (data.E2 - data.E * data.E) / (double)N;
189 M_var = (data.M2 - data.M_abs * data.M_abs) / (double)N;
190
191 ofile << scientific_format(temp) << ','
192 << scientific_format(data.E / (double)N) << ','
193 << scientific_format(data.M_abs / N) << ','
194 << scientific_format(E_var / (temp * temp)) << ','
195 << scientific_format(M_var / temp) << '\n';
196 }
197 ofile.close();
198}
199} // namespace montecarlo
The Ising model in 2 dimensions.
Definition: IsingModel.hpp:36
IsingModel(int L, double T, int val)
Constructor for the Ising model.
Definition: IsingModel.cpp:31
IsingModel(int L, double T)
Constructor for the Ising model.
Definition: IsingModel.cpp:19
data_t Metropolis()
The Metropolis algorithm.
Definition: IsingModel.cpp:110
Type to use with the IsingModel class and montecarlo module.
Definition: data_type.hpp:19
double M_abs
Absolute Magnetization.
Definition: data_type.hpp:25
double E
Energy.
Definition: data_type.hpp:21
data_t & operator+=(const data_t &b)
Overload of the addition equals operator.
Definition: data_type.hpp:150
double M2
Magnetization squared.
Definition: data_type.hpp:24
double E2
Energy squared.
Definition: data_type.hpp:23
double M
Magnetization.
Definition: data_type.hpp:22
void progression(double T, int L, int cycles, int value, const std::string filename, int burn_in_time=BURN_IN_TIME)
Write the expected values for each Monte Carlo cycles to file.
Definition: monte_carlo.cpp:53
void phase_transition(int L, double start_T, double end_T, int points_T, int cycles, std::function< data_t(int, double, int, int)> monte_carlo, std::string outfile, int burn_in_time=BURN_IN_TIME)
Perform the MCMC algorithm using a range of temperatures.
void progression(double T, int L, int cycles, const std::string filename, int burn_in_time=BURN_IN_TIME)
Write the expected values for each Monte Carlo cycles to file.
Definition: monte_carlo.cpp:15
data_t mcmc_parallel(int L, double T, int cycles, int burn_in_time=BURN_IN_TIME)
Execute the Metropolis algorithm for a certain amount of Monte Carlo cycles in parallel.
data_t mcmc_serial(int L, double T, int cycles, int burn_in_time=BURN_IN_TIME)
Execute the Metropolis algorithm for a certain amount of Monte Carlo cycles.
void pd_estimate(double T, int L, int cycles, const std::string filename, int burn_in_time=BURN_IN_TIME)
Estimate the probability distribution for the energy.
Definition: monte_carlo.cpp:91
bool mkpath(std::string path, int mode=0777)
Make path given.
Definition: utils.cpp:32
std::string scientific_format(double d, int width=20, int prec=10)
Turns a double into a string written in scientific format.
Definition: utils.cpp:16
std::string dirname(const std::string &path)
Get the directory name of the path.
Definition: utils.cpp:58