From 8056fe046011a46b25b6924b2d96229d06dbb4f7 Mon Sep 17 00:00:00 2001 From: Jaron Kent-Dobias Date: Tue, 3 Dec 2019 15:49:20 -0500 Subject: refactoring and generalization in preparation for pressure ensemble --- space_wolff.hpp | 215 ++++++++++++++++++++++++++------------------------------ spheres.cpp | 49 +++++++++++-- 2 files changed, 144 insertions(+), 120 deletions(-) diff --git a/space_wolff.hpp b/space_wolff.hpp index 02c544d..1335f07 100644 --- a/space_wolff.hpp +++ b/space_wolff.hpp @@ -244,125 +244,136 @@ public: unsigned num_added() const { return n - wait; } }; -template class Model; +template class Model; -template class measurement { +template class measurement { public: - virtual void pre_cluster(const Model&, unsigned, const Euclidean&){}; - virtual void plain_bond_visited(const Model&, const Spin*, const Spin*, + virtual void pre_cluster(const Model&, unsigned, const R&){}; + virtual void plain_bond_visited(const Model&, const Spin*, const Spin*, const Spin&, double){}; - virtual void plain_site_transformed(const Model&, const Spin*, + virtual void plain_site_transformed(const Model&, const Spin*, const Spin&){}; - virtual void ghost_bond_visited(const Model&, const Spin&, const Spin&, + virtual void ghost_bond_visited(const Model&, const Spin&, const Spin&, double){}; - virtual void ghost_site_transformed(const Model&, const Euclidean&){}; + virtual void ghost_site_transformed(const Model&, const R&){}; - virtual void post_cluster(const Model&){}; + virtual void post_cluster(const Model&){}; }; -template class Model { -public: - U L; - Euclidean s0; - std::vector> s; - Octree dict; - unsigned dDepth; - unsigned nDepth; - std::function&, const Spin&)> Z; - std::function&)> B; - std::vector> mats; - std::vector> steps; - double E; - measurement& A; - - void one_sequences(std::list>& sequences, unsigned level) { - if (level > 0) { - unsigned new_level = level - 1; - unsigned old_length = sequences.size(); - for (std::array& sequence : sequences) { - std::array new_sequence = sequence; - new_sequence[new_level] = -1; - sequences.push_front(new_sequence); - } - one_sequences(sequences, new_level); +template +void one_sequences(std::list>& sequences, unsigned level) { + if (level > 0) { + unsigned new_level = level - 1; + unsigned old_length = sequences.size(); + for (std::array& sequence : sequences) { + std::array new_sequence = sequence; + new_sequence[new_level] = -1; + sequences.push_front(new_sequence); } + one_sequences(sequences, new_level); } +} - Model(U L, std::function&, const Spin&)> Z, - std::function&)> B, unsigned dDepth, unsigned nDepth, - measurement& A) - : L(L), s0(L), dict(L, dDepth), Z(Z), B(B), dDepth(dDepth), nDepth(nDepth), A(A) { - std::array ini_sequence; - ini_sequence.fill(1); - std::list> sequences; - sequences.push_back(ini_sequence); +template +std::vector> torus_vecs(U L) { + std::vector> vecs; + std::array ini_sequence; + ini_sequence.fill(1); + std::list> sequences; + sequences.push_back(ini_sequence); + sequences.pop_front(); // don't want the identity matrix! + + for (std::array sequence : sequences) { + Vector v; + for (unsigned i = 0; i < D; i++) { + if (sequence[i] == 1) { + v(i) = 0; + } else { + v(i) = L / 2; + } + } + + vecs.push_back(v); + } - one_sequences(sequences, D); + return vecs; +} - sequences.pop_front(); // don't want the identity matrix! +template +std::vector> torus_mats() { + std::vector> mats; - for (std::array sequence : sequences) { - Matrix m; - for (unsigned i = 0; i < D; i++) { - for (unsigned j = 0; j < D; j++) { - if (i == j) { - m(i, j) = sequence[i]; - } else { - m(i, j) = 0; - } - } - } + std::array ini_sequence; + ini_sequence.fill(1); + std::list> sequences; + sequences.push_back(ini_sequence); - mats.push_back(m); + one_sequences(sequences, D); - Vector v; - for (unsigned i = 0; i < D; i++) { - if (sequence[i] == 1) { - v(i) = 0; + sequences.pop_front(); // don't want the identity matrix! + + for (std::array sequence : sequences) { + Matrix m; + for (unsigned i = 0; i < D; i++) { + for (unsigned j = 0; j < D; j++) { + if (i == j) { + m(i, j) = sequence[i]; } else { - v(i) = L / 2; + m(i, j) = 0; } } - - steps.push_back(v); } - for (unsigned i = 0; i < D; i++) { - for (unsigned j = 0; j < D; j++) { - if (i != j) { - Matrix m; - for (unsigned k = 0; k < D; k++) { - for (unsigned l = 0; l < D; l++) { - if ((k == i && l == j) || (k == j && l == i)) { - if (i < j) { - m(k, l) = 1; - } else { - m(k, l) = -1; - } + mats.push_back(m); + } + + for (unsigned i = 0; i < D; i++) { + for (unsigned j = 0; j < D; j++) { + if (i != j) { + Matrix m; + for (unsigned k = 0; k < D; k++) { + for (unsigned l = 0; l < D; l++) { + if ((k == i && l == j) || (k == j && l == i)) { + if (i < j) { + m(k, l) = 1; } else { - m(k, l) = 0; + m(k, l) = -1; } + } else { + m(k, l) = 0; } } - mats.push_back(m); } + mats.push_back(m); } } } - void update_energy() { - E = 0; - for (unsigned i = 0; i < s.size(); i++) { - for (unsigned j = 0; j < i; j++) { - E -= Z(s[i], s[j]); - } + return mats; +} - E -= B(s0.inverse().act(s[i])); - } - } +template class Model { +public: + U L; + R s0; + std::vector> s; + Octree dict; + unsigned dDepth; + unsigned nDepth; + std::function&, const Spin&)> Z; + std::function&)> B; + std::function&, randutils::mt19937_rng&)> g; + randutils::mt19937_rng rng; + measurement& A; + + + Model(U L, std::function&, const Spin&)> Z, + std::function&)> B, std::function&, randutils::mt19937_rng&)> g, unsigned dDepth, unsigned nDepth, + measurement& A) + : L(L), s0(L), dict(L, dDepth), Z(Z), B(B), g(g), dDepth(dDepth), nDepth(nDepth), rng(), A(A) {} - void step(double T, unsigned ind, Euclidean r, std::mt19937& rng) { + void step(double T, unsigned ind, Euclidean r) { unsigned cluster_size = 0; std::uniform_real_distribution dist(0.0, 1.0); @@ -427,37 +438,11 @@ public: } } - void wolff(double T, unsigned N, std::mt19937& rng) { - std::uniform_real_distribution t_dist(0, L); - std::uniform_int_distribution r_dist(0, D - 1); + void wolff(double T, unsigned N) { std::uniform_int_distribution ind_dist(0, s.size() - 1); - std::uniform_int_distribution coin(0, mats.size() + steps.size() - 1); for (unsigned i = 0; i < N; i++) { - Vector t; - Matrix m; - unsigned flip = coin(rng); - if (flip < mats.size()) { - for (unsigned j = 0; j < D; j++) { - t(j) = (U)t_dist(rng); - } - m = mats[flip]; - } else { - for (unsigned j = 0; j < D; j++) { - for (unsigned k = 0; k < D; k++) { - if (j == k) { - m(j, k) = 1; - } else { - m(j, k) = 0; - } - } - } - - t = steps[flip - mats.size()]; - } - - Euclidean g(L, t, m); - + R g = g(*this, rng); unsigned ind = ind_dist(rng); A.pre_cluster(*this, ind, g); @@ -465,8 +450,6 @@ public: this->step(T, ind, g, rng); A.post_cluster(*this); - - this->update_energy(); } } }; diff --git a/spheres.cpp b/spheres.cpp index 25c5a67..9e67b87 100644 --- a/spheres.cpp +++ b/spheres.cpp @@ -2,7 +2,10 @@ #include "space_wolff.hpp" #include -class animation : public measurement { +const unsigned D = 2; +typedef Model, double> model; + +class animation : public measurement, double> { public: animation(double L, unsigned w, int argc, char *argv[]) { glutInit(&argc, argv); @@ -15,7 +18,7 @@ class animation : public measurement { gluOrtho2D(-1, L + 1, -1 , L + 1); } - void post_cluster(const Model& m) override { + void post_cluster(const model& m) override { glClearColor(1.0f, 1.0f, 1.0f, 1.0f ); glClear(GL_COLOR_BUFFER_BIT); for (const Spin& s : m.s) { @@ -32,6 +35,41 @@ class animation : public measurement { } }; +std::function(const model&, randutils::mt19937_rng&)> eGen(const std::vector>& mats, const std::vector>& vecs) { + return [&mats, &vecs] (const model& M, randutils::mt19937_rng& rng) -> Euclidean { + std::uniform_real_distribution t_dist(0, M.L); + std::uniform_int_distribution r_dist(0, D - 1); + std::uniform_int_distribution ind_dist(0, M.s.size() - 1); + std::uniform_int_distribution coin(0, mats.size() + vecs.size() - 1); + + Vector t; + Matrix m; + unsigned flip = coin(rng); + if (flip < mats.size()) { + for (unsigned j = 0; j < D; j++) { + t(j) = (double)t_dist(rng); + } + m = mats[flip]; + } else { + for (unsigned j = 0; j < D; j++) { + for (unsigned k = 0; k < D; k++) { + if (j == k) { + m(j, k) = 1; + } else { + m(j, k) = 0; + } + } + } + + t = vecs[flip - mats.size()]; + } + + Euclidean g(M.L, t, m); + return g; + }; + +} + int main(int argc, char* argv[]) { const unsigned D = 2; @@ -85,8 +123,11 @@ int main(int argc, char* argv[]) { return H * sin(2 * M_PI * 3 * s.x(0) / L); }; + std::vector> mats = torus_mats(); + std::vector> vecs = torus_vecs(L); + auto g = eGen(mats, vecs); animation A(L, 750, argc, argv); - Model sphere(L, Z, B, std::floor(log2(L)), 2, A); + model sphere(L, Z, B, g, std::floor(log2(L)), 2, A); randutils::auto_seed_128 seeds; std::mt19937 rng{seeds}; @@ -102,7 +143,7 @@ int main(int argc, char* argv[]) { } - sphere.wolff(T, N, rng); + sphere.wolff(T, N); std::ofstream snapfile; snapfile.open("sphere_snap.dat"); -- cgit v1.2.3-70-g09d2