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