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
12#include "monte_carlo.hpp"
13
14#include <cmath>
15#include <cstdint>
16
17void monte_carlo_progression(double T, int L, int cycles,
18 const std::string filename)
19{
20 // Set some variables
21 data_t data, tmp;
22 int n_spins = L * L;
23
24 // File stuff
25 std::string directory = utils::dirname(filename);
26 std::ofstream ofile;
27
28 // Create random engine using the mersenne twister
29 std::random_device rd;
30 uint32_t rd_sample = rd();
31 std::mt19937 engine(rd_sample);
32
33 std::cout << "Seed: " << rd_sample << std::endl;
34
35 IsingModel ising(L, T);
36
37 // Create path and open file
38 utils::mkpath(directory);
39 ofile.open(filename);
40
41 // Loop through cycles
42 for (size_t i = 1; i <= cycles; i++) {
43 data += ising.Metropolis();
44 tmp = data / (i * n_spins);
45 ofile << i << ',' << tmp.E << ',' << tmp.E2 << ',' << tmp.M << ','
46 << tmp.M2 << ',' << tmp.M_abs << '\n';
47 }
48 ofile.close();
49}
50
51void monte_carlo_progression(double T, int L, int cycles, int value,
52 const std::string filename)
53{
54 // Set some variables
55 data_t data, tmp;
56 int n_spins = L * L;
57
58 // File stuff
59 std::string directory = utils::dirname(filename);
60 std::ofstream ofile;
61
62 // Create random engine using the mersenne twister
63 std::random_device rd;
64 uint32_t rd_sample = rd();
65 std::mt19937 engine(rd());
66
67 std::cout << "Seed: " << rd_sample << std::endl;
68
69 IsingModel ising(L, T, value);
70
71 // Create path and open file
72 utils::mkpath(directory);
73 ofile.open(filename);
74
75 // Loop through cycles
76 for (size_t i = 1; i <= cycles; i++) {
77 data += ising.Metropolis();
78 tmp = data / (i * n_spins);
79 ofile << i << ',' << tmp.E << ',' << tmp.E2 << ',' << tmp.M << ','
80 << tmp.M2 << ',' << tmp.M_abs << '\n';
81 }
82 ofile.close();
83}
84
85void pd_estimate(double T, int L, int cycles, const std::string filename)
86{
87 // Set some variables
88 data_t data, tmp;
89 int n_spins = L * L;
90
91 // File stuff
92 std::string directory = utils::dirname(filename);
93 std::ofstream ofile;
94
95 IsingModel ising(L, T);
96
97 // Create path and open file
98 utils::mkpath(directory);
99 ofile.open(filename);
100
101 // Loop through cycles
102 for (size_t i = 1; i <= cycles; i++) {
103 data = ising.Metropolis() / n_spins;
104 ofile << data.E << ',' << data.E2 << ',' << data.M << ',' << data.M2
105 << ',' << data.M_abs << '\n';
106 }
107 ofile.close();
108}
109
110// Code for seeing phase transitions.
111data_t monte_carlo_serial(int L, double T, int cycles)
112{
113 data_t data;
114 IsingModel model(L, T);
115
116 for (size_t i = 0; i < BURN_IN_TIME; i++) {
117 model.Metropolis();
118 }
119
120 double E, M;
121 for (size_t i = 0; i < (uint)cycles; i++) {
122 data += model.Metropolis();
123 }
124
125 return data;
126}
127
128data_t monte_carlo_parallel(int L, double T, int cycles)
129{
130 data_t data;
131#pragma omp parallel
132 {
133 // Each thread creates an instance of IsingModel.
134 IsingModel model(L, T);
135
136 // Each thread runs the Metropolis algorithm before starting to collect
137 // samples
138 for (size_t i = 0; i < BURN_IN_TIME; i++) {
139 model.Metropolis();
140 }
141
142 // Now each thread work on one loop together, but using their own
143 // instances of things, but the total of cycles add up.
144 // static ensure that each thread gets the same amount of iterations
145#pragma omp for schedule(static) reduction(+ : data)
146 for (size_t i = 0; i < (uint)cycles; i++) {
147 data += model.Metropolis();
148 }
149 }
150
151 double norm = 1. / (double)cycles;
152
153 return data * norm;
154}
155
156void phase_transition(int L, double start, double end, int points,
157 std::function<data_t(int, double, int)> monte_carlo,
158 std::string outfile)
159{
160 double dt = (end - start) / (double)points;
161 int cycles = 10000;
162 int N = L * L;
163 std::ofstream ofile;
164
165 data_t data;
166
167 utils::mkpath(utils::dirname(outfile));
168 ofile.open(outfile);
169
170 double temp, CV, X, E_var, M_var;
171
172 using utils::scientific_format;
173 for (size_t i = 0; i < points; i++) {
174 temp = start + dt * i;
175 data = monte_carlo(L, temp, cycles);
176 E_var = (data.E2 - data.E * data.E) / (double)N;
177 M_var = (data.M2 - data.M_abs * data.M_abs) / (double)N;
178
179 ofile << scientific_format(temp) << ','
180 << scientific_format(data.E / (double)N) << ','
181 << scientific_format(data.M_abs / N) << ','
182 << scientific_format(E_var / (temp * temp)) << ','
183 << scientific_format(M_var / temp) << '\n';
184 }
185 ofile.close();
186}
The Ising model in 2 dimensions.
Definition: IsingModel.hpp:37
data_t Metropolis()
The Metropolis algorithm.
Definition: IsingModel.cpp:96
data_t monte_carlo_serial(int L, double T, int cycles)
Execute the Metropolis algorithm for a certain amount of Monte Carlo cycles.
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
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.
Functions for monte carlo simulations.
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.
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