From 1343a3fe6bd17a2487f12a0d61be8dc83cd722a0 Mon Sep 17 00:00:00 2001 From: Jaron Kent-Dobias Date: Mon, 15 Oct 2018 22:57:17 -0400 Subject: many changes, including reworking the measurements system --- lib/include/wolff.hpp | 15 +++----- lib/include/wolff/cluster.hpp | 20 +++++------ lib/include/wolff/graph.hpp | 9 +++-- lib/include/wolff/meas.h | 19 ++++++++++ lib/include/wolff/state.hpp | 81 ++++--------------------------------------- 5 files changed, 46 insertions(+), 98 deletions(-) create mode 100644 lib/include/wolff/meas.h (limited to 'lib/include') diff --git a/lib/include/wolff.hpp b/lib/include/wolff.hpp index c10a211..b730c8d 100644 --- a/lib/include/wolff.hpp +++ b/lib/include/wolff.hpp @@ -3,7 +3,7 @@ #include "wolff/state.hpp" template -void wolff(count_t N, state_t & s, std::function gen_R, std::function &)> measurements, std::mt19937& r, bool silent) { +void wolff(count_t N, state_t & s, std::function gen_R, wolff_measurement& m, std::mt19937& r) { #ifdef FINITE_STATES #ifdef NOFIELD @@ -15,21 +15,16 @@ void wolff(count_t N, state_t & s, std::function dist(0, s.nv); - if (!silent) printf("\n"); for (count_t steps = 0; steps < N; steps++) { - if (!silent) printf("\033[F\033[JWOLFF: step %" PRIu64 " / %" PRIu64 ": E = %.2f, S = %" PRIv "\n", steps, N, s.E, s.last_cluster_size); - v_t v0 = dist(r); R_t step = gen_R(r, s.spins[v0]); - flip_cluster (s, v0, step, r); - measurements(s); - } + m.pre_cluster(s, steps, N, v0, step); + + flip_cluster(s, v0, step, r, m); - if (!silent) { - printf("\033[F\033[J"); + m.post_cluster(s, steps, N); } - printf("WOLFF: step %" PRIu64 " / %" PRIu64 ": E = %.2f, S = %" PRIv "\n", N, N, s.E, s.last_cluster_size); } diff --git a/lib/include/wolff/cluster.hpp b/lib/include/wolff/cluster.hpp index e9dff7b..805e2c3 100644 --- a/lib/include/wolff/cluster.hpp +++ b/lib/include/wolff/cluster.hpp @@ -9,11 +9,11 @@ #include "types.h" #include "state.hpp" #include "graph.hpp" +#include "meas.h" template -void flip_cluster(state_t& s, v_t v0, const R_t& r, std::mt19937& rand) { - std::uniform_real_distribution dist(0.0,1.0); - v_t nv = 0; +void flip_cluster(state_t& s, v_t v0, const R_t& r, std::mt19937& rand, wolff_measurement& m) { + std::uniform_real_distribution dist(0.0, 1.0); std::stack stack; stack.push(v0); @@ -75,8 +75,8 @@ void flip_cluster(state_t& s, v_t v0, const R_t& r, std::mt19937& rand prob = H_probs[state_to_ind(rs_old)][state_to_ind(rs_new)]; #endif - s.update_magnetization(rs_old, rs_new); - s.update_fourierZero(non_ghost, rs_old, rs_new); + // run measurement hooks for encountering a ghost bond + m.ghost_bond_added(non_ghost, rs_old, rs_new, dE); } else // this is a perfectly normal bond! #endif { @@ -90,9 +90,10 @@ void flip_cluster(state_t& s, v_t v0, const R_t& r, std::mt19937& rand #ifdef FINITE_STATES prob = J_probs[state_to_ind(s.spins[v])][state_to_ind(si_new)][state_to_ind(s.spins[vn])]; #endif - } - s.update_energy(dE); + // run measurement hooks for encountering a plain bond + m.plain_bond_added(v, s.spins[v], si_new, vn, s.spins[vn], dE); + } #ifndef FINITE_STATES prob = 1.0 - exp(-dE / s.T); @@ -105,16 +106,15 @@ void flip_cluster(state_t& s, v_t v0, const R_t& r, std::mt19937& rand #ifndef NOFIELD if (v_is_ghost) { + m.ghost_site_transformed(s.R, R_new); s.R = R_new; } else #endif { + m.plain_site_transformed(v, s.spins[v], si_new); s.spins[v] = si_new; - nv++; } } } - - s.last_cluster_size = nv; } diff --git a/lib/include/wolff/graph.hpp b/lib/include/wolff/graph.hpp index 165544a..0aeb6af 100644 --- a/lib/include/wolff/graph.hpp +++ b/lib/include/wolff/graph.hpp @@ -1,13 +1,16 @@ #pragma once -#include #include -#include #include #include "types.h" +typedef enum lattice_t { + SQUARE_LATTICE, + DIAGONAL_LATTICE +} lattice_t; + class graph_t { public: v_t ne; @@ -15,7 +18,7 @@ class graph_t { std::vector> v_adj; std::vector> coordinate; - graph_t(D_t D, L_t L); + graph_t(D_t D, L_t L, lattice_t lat = SQUARE_LATTICE); void add_ext(); }; diff --git a/lib/include/wolff/meas.h b/lib/include/wolff/meas.h new file mode 100644 index 0000000..4895eac --- /dev/null +++ b/lib/include/wolff/meas.h @@ -0,0 +1,19 @@ + +#pragma once + +#include "types.h" + +template +class wolff_measurement { + public: + virtual void pre_cluster(const state_t&, count_t, count_t, v_t, const R_t&) = 0; + + virtual void plain_bond_added(v_t, const X_t&, const X_t&, v_t, const X_t&, double) = 0; + virtual void ghost_bond_added(v_t, const X_t&, const X_t&, double) = 0; + + virtual void plain_site_transformed(v_t, const X_t&, const X_t&) = 0; + virtual void ghost_site_transformed(const R_t&, const R_t&) = 0; + + virtual void post_cluster(const state_t&, count_t, count_t) = 0; +}; + diff --git a/lib/include/wolff/state.hpp b/lib/include/wolff/state.hpp index e7c0ac3..4909881 100644 --- a/lib/include/wolff/state.hpp +++ b/lib/include/wolff/state.hpp @@ -9,26 +9,17 @@ template class state_t { - private: - // updating fourier terms F requires many cos and sin calls, faster to do it beforehand. - std::vector> precomputed_cos; - std::vector> precomputed_sin; public: - D_t D; - L_t L; - v_t nv; // the number of vertices in the lattice - v_t ne; // the number of edges in the lattice - graph_t g; // the graph defining the lattice without ghost + D_t D; // the dimension of the system + L_t L; // the linear size of the lattice + v_t nv; // the number of vertices in the original lattice + v_t ne; // the number of edges in the original lattice + graph_t g; // the graph defining the lattice with ghost double T; // the temperature std::vector spins; // the state of the ordinary spins #ifndef NOFIELD R_t R; // the current state of the ghost site #endif - double E; // the system's total energy - typename X_t::M_t M; // the "sum" of the spins, like the total magnetization - v_t last_cluster_size; // the size of the last cluster - std::vector ReF; - std::vector ImF; #ifdef BOND_DEPENDENCE std::function J; // coupling between sites @@ -57,7 +48,7 @@ class state_t { , std::function H #endif #endif - ) : D(D), L(L), g(D, L), T(T), + , lattice_t lat = SQUARE_LATTICE) : D(D), L(L), g(D, L, lat), T(T), #ifndef NOFIELD R(), #endif @@ -69,69 +60,9 @@ class state_t { nv = g.nv; ne = g.ne; spins.resize(nv); -#ifdef BOND_DEPENDENCE - E = 0; - for (v_t v = 0; v < nv; v++) { - for (const v_t &vn : g.v_adj[v]) { - if (v < vn) { - E -= J(v, spins[v], vn, spins[vn]); - } - } - } -#else - E = - (double)ne * J(spins[0], spins[0]); -#endif - #ifndef NOFIELD g.add_ext(); -#ifdef SITE_DEPENDENCE - for (v_t i = 0; i < nv; i++) { - E -= H(i, spins[i]); - } -#else - E -= (double)nv * H(spins[0]); -#endif -#endif - - M = spins[0] * nv; - last_cluster_size = 0; - ReF.resize(D); - ImF.resize(D); - for (D_t i = 0; i < D; i++) { - ReF[i] = spins[0] * 0.0; - ImF[i] = spins[0] * 0.0; - } - precomputed_cos.resize(nv); - precomputed_sin.resize(nv); - for (v_t i = 0; i < nv; i++) { - precomputed_cos[i].resize(D); - precomputed_sin[i].resize(D); - for (D_t j = 0; j < D; j++) { - precomputed_cos[i][j] = cos(2 * M_PI * g.coordinate[i][j] / (double)L); - precomputed_sin[i][j] = sin(2 * M_PI * g.coordinate[i][j] / (double)L); - } - } - } - - void update_magnetization(const X_t& s_old, const X_t& s_new) { - M += s_new - s_old; - } - - void update_energy(const double& dE) { - E += dE; - } - - void update_fourierZero(v_t v, const X_t& s_old, const X_t& s_new) { -#ifdef DIMENSION - for (D_t i = 0; i < DIMENSION; i++) { -#else - for (D_t i = 0; i < D; i++) { #endif - ReF[i] += (s_new - s_old) * precomputed_cos[v][i]; - ImF[i] += (s_new - s_old) * precomputed_sin[v][i]; - } } }; - - -- cgit v1.2.3-70-g09d2