diff options
-rw-r--r-- | CMakeLists.txt | 7 | ||||
-rw-r--r-- | lib/colors.h | 34 | ||||
-rw-r--r-- | lib/potts.h | 22 | ||||
-rw-r--r-- | lib/symmetric.h | 5 | ||||
-rw-r--r-- | src/wolff_On.cpp | 33 | ||||
-rw-r--r-- | src/wolff_potts.cpp | 82 |
6 files changed, 107 insertions, 76 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index eedccaa..5269c48 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,10 +16,12 @@ file(GLOB CPPSOURCES lib/*.cpp) add_executable(wolff_finite src/wolff_finite.c ${CSOURCES}) add_executable(wolff_ising src/wolff_ising.cpp ${CPPSOURCES} ${CSOURCES}) +add_executable(wolff_3potts src/wolff_potts.cpp ${CPPSOURCES} ${CSOURCES}) add_executable(wolff_planar src/wolff_On.cpp ${CPPSOURCES} ${CSOURCES}) add_executable(wolff_heisenberg src/wolff_On.cpp ${CPPSOURCES} ${CSOURCES}) add_executable(analyze_correlations src/analyze_correlations.cpp ${CPPSOURCES} ${CSOURCES}) +SET_TARGET_PROPERTIES(wolff_3potts PROPERTIES COMPILE_FLAGS "-DPOTTSQ=3") SET_TARGET_PROPERTIES(wolff_planar PROPERTIES COMPILE_FLAGS "-DN_COMP=2") SET_TARGET_PROPERTIES(wolff_heisenberg PROPERTIES COMPILE_FLAGS "-DN_COMP=3") @@ -35,16 +37,19 @@ target_link_libraries(wolff_finite cblas gsl m) target_link_libraries(analyze_correlations cblas gsl fftw3 m) if (${GLUT} MATCHES "GLUT-NOTFOUND") target_link_libraries(wolff_ising cblas gsl m) + target_link_libraries(wolff_3potts cblas gsl m) target_link_libraries(wolff_heisenberg cblas gsl m) target_link_libraries(wolff_planar cblas gsl m) else() target_link_libraries(wolff_ising cblas gsl m glut GL GLU) + target_link_libraries(wolff_3potts cblas gsl m glut GL GLU) target_link_libraries(wolff_heisenberg cblas gsl m glut GL GLU) target_link_libraries(wolff_planar cblas gsl m glut GL GLU) target_compile_definitions(wolff_ising PUBLIC HAVE_GLUT) + target_compile_definitions(wolff_3potts PUBLIC HAVE_GLUT) target_compile_definitions(wolff_planar PUBLIC HAVE_GLUT) target_compile_definitions(wolff_heisenberg PUBLIC HAVE_GLUT) endif() -install(TARGETS wolff_finite wolff_ising wolff_heisenberg wolff_planar analyze_correlations DESTINATION bin) +install(TARGETS wolff_finite wolff_ising wolff_3potts wolff_heisenberg wolff_planar analyze_correlations DESTINATION bin) diff --git a/lib/colors.h b/lib/colors.h new file mode 100644 index 0000000..04d39a8 --- /dev/null +++ b/lib/colors.h @@ -0,0 +1,34 @@ +#pragma once + +#include "types.h" + +double hue_to_R(double theta) { + if (((M_PI / 3 <= theta) && (theta < 2 * M_PI / 3)) || ((4 * M_PI / 3 <= theta) && (theta < 5 * M_PI / 3))) { + return 1.0 - fabs(fmod(theta / (2 * M_PI / 6), 2) - 1.0); + } else if (((0 <= theta) && (theta < M_PI / 3)) || ((5 * M_PI / 3 <= theta) && (theta <= 2 * M_PI))) { + return 1.0; + } else { + return 0.0; + } +} + +double hue_to_G(double theta) { + if (((0 <= theta) && (theta < M_PI / 3)) || ((M_PI <= theta) && (theta < 4 * M_PI / 3))) { + return 1.0 - fabs(fmod(theta / (2 * M_PI / 6), 2) - 1.0); + } else if (((M_PI / 3 <= theta) && (theta < 2 * M_PI / 3)) || ((2 * M_PI / 3 <= theta) && (theta < M_PI))) { + return 1.0; + } else { + return 0.0; + } +} + +double hue_to_B(double theta) { + if (((2 * M_PI / 3 <= theta) && (theta < M_PI)) || ((5 * M_PI / 3 <= theta) && (theta <= 2 * M_PI))) { + return 1.0 - fabs(fmod(theta / (2 * M_PI / 6), 2) - 1.0); + } else if (((M_PI <= theta) && (theta < 4 * M_PI / 3)) || ((4 * M_PI / 3 <= theta) && (theta < 5 * M_PI / 3))) { + return 1.0; + } else { + return 0.0; + } +} + diff --git a/lib/potts.h b/lib/potts.h index e7f0899..e411ddb 100644 --- a/lib/potts.h +++ b/lib/potts.h @@ -44,13 +44,11 @@ void free_spin(potts_t <q> s) { // do nothing! } -template <q_t q> -void free_spin(typename potts_t<q>::M_t s) { +void free_spin(int *s) { free(s); } -template <q_t q> -void free_spin(typename potts_t<q>::F_t s) { +void free_spin(double *s) { free(s); } @@ -60,13 +58,13 @@ potts_t <q> copy(potts_t <q> s) { } template <q_t q> -void add(typename potts_t<q>::M_t s1, int a, potts_t <q> s2) { - s1[s2.x] += a; +void add(typename potts_t<q>::M_t *s1, int a, potts_t <q> s2) { + (*s1)[s2.x] += a; } template <q_t q> -void add(typename potts_t<q>::F_t s1, double a, potts_t <q> s2) { - s1[s2.x] += a; +void add(typename potts_t<q>::F_t *s1, double a, potts_t <q> s2) { + (*s1)[s2.x] += a; } template <q_t q> @@ -78,13 +76,13 @@ typename potts_t<q>::M_t scalar_multiple(int factor, potts_t <q> s) { template <q_t q> typename potts_t<q>::F_t scalar_multiple(double factor, potts_t <q> s) { - int *F = (double *)calloc(q, sizeof(double)); - M[s.x] += factor; - return M; + double *F = (double *)calloc(q, sizeof(double)); + F[s.x] += factor; + return F; } template <q_t q> -double norm_squared(typename potts<q>::F_t s) { +double norm_squared(typename potts_t<q>::F_t s) { double total = 0; for (q_t i = 0; i < q; i++) { total += pow(s[i], 2); diff --git a/lib/symmetric.h b/lib/symmetric.h index 0b292a6..a73b403 100644 --- a/lib/symmetric.h +++ b/lib/symmetric.h @@ -6,6 +6,7 @@ #include "types.h" #ifdef __cplusplus +#include "potts.h" extern "C" { #endif @@ -39,11 +40,11 @@ void init(symmetric_t<q> *p) { template <q_t q> void free_spin(symmetric_t<q> p) { - free(p->perm); + free(p.perm); } template <q_t q> -symmetric_t<q_t> copy(symmetric_t<q_t> x) { +symmetric_t<q> copy(symmetric_t<q> x) { symmetric_t<q> x2; x2.perm = (q_t *)malloc(q * sizeof(q_t)); diff --git a/src/wolff_On.cpp b/src/wolff_On.cpp index 32a6fc4..a59876f 100644 --- a/src/wolff_On.cpp +++ b/src/wolff_On.cpp @@ -1,5 +1,6 @@ #include <getopt.h> + #ifdef HAVE_GLUT #include <GL/glut.h> #endif @@ -7,6 +8,7 @@ #include <wolff.h> #include <correlation.h> #include <measure.h> +#include <colors.h> typedef orthogonal_t <N_COMP, double> orthogonal_R_t; typedef vector_t <N_COMP, double> vector_R_t; @@ -32,36 +34,6 @@ double H_modulated(vector_R_t v, int order, double mag) { return mag * cos(order * theta(v)); } -double hue_to_R(double theta) { - if (((M_PI / 3 <= theta) && (theta < 2 * M_PI / 3)) || ((4 * M_PI / 3 <= theta) && (theta < 5 * M_PI / 3))) { - return 1.0 - fabs(fmod(theta / (2 * M_PI / 6), 2) - 1.0); - } else if (((0 <= theta) && (theta < M_PI / 3)) || ((5 * M_PI / 3 <= theta) && (theta <= 2 * M_PI))) { - return 1.0; - } else { - return 0.0; - } -} - -double hue_to_G(double theta) { - if (((0 <= theta) && (theta < M_PI / 3)) || ((M_PI <= theta) && (theta < 4 * M_PI / 3))) { - return 1.0 - fabs(fmod(theta / (2 * M_PI / 6), 2) - 1.0); - } else if (((M_PI / 3 <= theta) && (theta < 2 * M_PI / 3)) || ((2 * M_PI / 3 <= theta) && (theta < M_PI))) { - return 1.0; - } else { - return 0.0; - } -} - -double hue_to_B(double theta) { - if (((2 * M_PI / 3 <= theta) && (theta < M_PI)) || ((5 * M_PI / 3 <= theta) && (theta <= 2 * M_PI))) { - return 1.0 - fabs(fmod(theta / (2 * M_PI / 6), 2) - 1.0); - } else if (((M_PI <= theta) && (theta < 4 * M_PI / 3)) || ((4 * M_PI / 3 <= theta) && (theta < 5 * M_PI / 3))) { - return 1.0; - } else { - return 0.0; - } -} - int main(int argc, char *argv[]) { count_t N = (count_t)1e7; @@ -81,7 +53,6 @@ int main(int argc, char *argv[]) { int order = 2; int opt; - q_t J_ind = 0; q_t H_ind = 0; double epsilon = 1; diff --git a/src/wolff_potts.cpp b/src/wolff_potts.cpp index 9d22ea4..3b55472 100644 --- a/src/wolff_potts.cpp +++ b/src/wolff_potts.cpp @@ -1,29 +1,37 @@ #include <getopt.h> + +#ifdef HAVE_GLUT #include <GL/glut.h> +#endif // include your group and spin space #include <symmetric.h> #include <potts.h> +#include <colors.h> // include wolff.h #include <wolff.h> +typedef state_t <symmetric_t<POTTSQ>, potts_t<POTTSQ>> sim_t; + int main(int argc, char *argv[]) { - count_t N = (count_t)1e7; + count_t N = (count_t)1e4; D_t D = 2; L_t L = 128; double T = 2.26918531421; - double H = 0.0; + double *H_vec = (double *)calloc(MAX_Q, sizeof(double)); bool silent = false; bool draw = false; + unsigned int window_size = 512; int opt; + q_t H_ind = 0; - while ((opt = getopt(argc, argv, "N:D:L:T:H:sd")) != -1) { + while ((opt = getopt(argc, argv, "N:D:L:T:H:sdw:")) != -1) { switch (opt) { case 'N': // number of steps N = (count_t)atof(optarg); @@ -37,15 +45,24 @@ int main(int argc, char *argv[]) { case 'T': // temperature T = atof(optarg); break; - case 'H': // external field - H = atof(optarg); + case 'H': // external field. nth call couples to state n + H_vec[H_ind] = atof(optarg); + H_ind++; break; case 's': // don't print anything during simulation. speeds up slightly silent = true; break; case 'd': +#ifdef HAVE_GLUT draw = true; break; +#else + printf("You didn't compile this with the glut library installed!\n"); + exit(EXIT_FAILURE); +#endif + case 'w': + window_size = atoi(optarg); + break; default: exit(EXIT_FAILURE); } @@ -56,41 +73,49 @@ int main(int argc, char *argv[]) { gsl_rng_set(r, rand_seed()); // define spin-spin coupling - std::function <double(potts_t, ising_t)> Z = [] (ising_t s1, ising_t s2) -> double { + std::function <double(potts_t<POTTSQ>, potts_t<POTTSQ>)> Z = [] (potts_t<POTTSQ> s1, potts_t<POTTSQ> s2) -> double { if (s1.x == s2.x) { return 1.0; } else { - return -1.0; + return 0.0; } }; // define spin-field coupling - std::function <double(ising_t)> B = [=] (ising_t s) -> double { - if (s.x) { - return -H; - } else { - return H; - } + std::function <double(potts_t<POTTSQ>)> B = [=] (potts_t<POTTSQ> s) -> double { + return H_vec[s.x]; }; // initialize state object - state_t <z2_t, ising_t> s(D, L, T, Z, B); + state_t <symmetric_t<POTTSQ>, potts_t<POTTSQ>> s(D, L, T, Z, B); // define function that generates self-inverse rotations - std::function <z2_t(gsl_rng *, const state_t <z2_t, ising_t> *)> gen_R = [] (gsl_rng *, const state_t <z2_t, ising_t> *) -> z2_t { - z2_t rot; - rot.x = true; + std::function <symmetric_t<POTTSQ>(gsl_rng *, const sim_t *)> gen_R = [] (gsl_rng *r, const sim_t *s) -> symmetric_t<POTTSQ> { + symmetric_t<POTTSQ> rot; + init(&rot); + + for (int i = POTTSQ - 1; i >= 0; i--) { + if (rot.perm[i] == i) { + q_t j = gsl_rng_uniform_int(r, i + 1); + if (rot.perm[j] == j) { + q_t tmp = rot.perm[i]; + rot.perm[i] = rot.perm[j]; + rot.perm[j] = tmp; + } + } + } + return rot; }; // define function that updates any number of measurements - std::function <void(const state_t <z2_t, ising_t> *)> measurement; + std::function <void(const sim_t *)> measurement; double average_M = 0; if (!draw) { // a very simple example: measure the average magnetization - measurement = [&] (const state_t <z2_t, ising_t> *s) { - average_M += (double)s->M / (double)N / (double)s->nv; + measurement = [&] (const sim_t *s) { + average_M += (double)s->M[0] / (double)N / (double)s->nv; }; } else { // a more complex example: measure the average magnetization, and draw the spin configuration to the screen @@ -98,22 +123,19 @@ int main(int argc, char *argv[]) { // initialize glut glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); - glutInitWindowSize(L,L); - glutCreateWindow("null"); + glutInitWindowSize(window_size, window_size); + glutCreateWindow("wolff"); glClearColor(0.0,0.0,0.0,0.0); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0.0, L, 0.0, L); - measurement = [&] (const state_t <z2_t, ising_t> *s) { - average_M += (double)s->M / (double)N / (double)s->nv; + measurement = [&] (const sim_t *s) { + average_M += (double)s->M[0] / (double)N / (double)s->nv; glClear(GL_COLOR_BUFFER_BIT); for (v_t i = 0; i < pow(L, 2); i++) { - if (s->spins[i].x == s->R.x) { - glColor3f(0.0, 0.0, 0.0); - } else { - glColor3f(1.0, 1.0, 1.0); - } + potts_t<POTTSQ> tmp_s = act_inverse(s->R, s->spins[i]); + glColor3f(hue_to_R(tmp_s.x * 2 * M_PI / POTTSQ), hue_to_G(tmp_s.x * 2 * M_PI / POTTSQ), hue_to_B(tmp_s.x * 2 * M_PI / POTTSQ)); glRecti(i / L, i % L, (i / L) + 1, (i % L) + 1); } glFlush(); @@ -124,7 +146,7 @@ int main(int argc, char *argv[]) { wolff(N, &s, gen_R, measurement, r, silent); // tell us what we found! - printf("%" PRIcount " Ising runs completed. D = %" PRID ", L = %" PRIL ", T = %g, H = %g, <M> = %g\n", N, D, L, T, H, average_M); + printf("%" PRIcount " %d-Potts runs completed. D = %" PRID ", L = %" PRIL ", T = %g, H = %g, <M> = %g\n", N, POTTSQ, D, L, T, H_vec[0], average_M); // free the random number generator gsl_rng_free(r); |