From 734dea28279ce7272e6ed23f821c69c225e2d947 Mon Sep 17 00:00:00 2001 From: Jaron Kent-Dobias Date: Fri, 14 Feb 2020 14:22:59 -0500 Subject: Split up Ising-related functions and added an executable for measuring Ising energy autocorrelation time. --- ising.hpp | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 ising.hpp (limited to 'ising.hpp') diff --git a/ising.hpp b/ising.hpp new file mode 100644 index 0000000..6f140be --- /dev/null +++ b/ising.hpp @@ -0,0 +1,106 @@ + +#include "smiley.hpp" +#include "space_wolff.hpp" +#include "torus_symmetries.hpp" + +const unsigned D = 2; +typedef Model, signed> isingModel; +typedef Spin isingSpin; + +std::function isingZ(unsigned L) { + return [L](const isingSpin& s1, const isingSpin& s2) -> double { + bool old_one_one = false; + bool old_many_ones = false; + bool old_any_two = false; + + Vector old_diff = diff(L, s1.x, s2.x); + + for (unsigned i = 0; i < D; i++) { + if (old_diff(i) == 1 && !old_one_one) { + old_one_one = true; + } else if (old_diff(i) == 1 && old_one_one) { + old_many_ones = true; + } else if (old_diff(i) > 1) { + old_any_two = true; + } + } + + bool were_on_someone = !old_one_one && !old_any_two; + bool were_nearest_neighbors = old_one_one && !old_many_ones && !old_any_two; + + if (were_on_someone) { + return -std::numeric_limits::infinity(); + ; + } else if (were_nearest_neighbors) { + return s1.s * s2.s; + } else { + return 0.0; + } + }; +} + +std::function isingBFace(unsigned L, double H) { + return [L, H](const isingSpin& s) -> double { + return H * s.s * smiley[15 - s.x(1) * 16 / L][s.x(0) * 16 / L]; + }; +} + +std::function isingBMod(unsigned L, unsigned mod, double H) { + return [mod, L, H](const isingSpin& s) -> double { + return H * s.s * sin(s.x(0) * mod * 2 * M_PI / L); + }; +} + +Gen, signed> isingGen(unsigned L) { + std::vector> torusVectors = torus_vecs(L); + std::vector> torusMatrices = torus_mats(); + return [L, torusVectors, + torusMatrices](Model, signed>& M, + Rng& r) -> Transformation, signed>* { + Matrix m; + Vector t; + + m = r.pick(torusMatrices); + t(0) = r.uniform(0, L); + t(1) = r.uniform(0, L); + t = t - m * t; + + TorusGroup g = TorusGroup({(signed)L, t, m}); + + Spin* ss = r.pick(M.s); + Spin s2 = g.act(*ss); + + while (ss->x(0) == s2.x(0) && ss->x(1) == s2.x(1)) { + ss = r.pick(M.s); + s2 = g.act(*ss); + } + + std::set*> s2s = M.dict.at(s2.x); + + if (s2s.empty()) { + return new SpinFlip, signed>(M, g, ss); + } else { + return new PairFlip, signed>(M, g, ss, *s2s.begin()); + } + }; +} + +void isingPopulate(isingModel& m, unsigned L, double pop, double mag) { + Rng rng; + + for (unsigned i = 0; i < L; i++) { + for (unsigned j = 0; j < L; j++) { + if (rng.uniform(0, 1) < pop) { + Spin* ss = new Spin(); + ss->x = {i, j}; + if (rng.uniform(0, 1) < mag) { + ss->s = 1; + } else { + ss->s = -1; + } + m.s.push_back(ss); + m.dict.insert(ss); + } + } + } +} -- cgit v1.2.3-54-g00ecf