From 466812e61e2ccec7750c791835111b402938411c Mon Sep 17 00:00:00 2001 From: Jaron Kent-Dobias Date: Mon, 9 Jul 2018 14:19:16 -0400 Subject: wolff run from own function, called with types to run --- CMakeLists.txt | 8 +-- lib/orthogonal.h | 116 +++++++++++++++++++++++++++------------- lib/wolff.h | 70 +++++++++++++++++++++++++ src/wolff.cpp | 134 ----------------------------------------------- src/wolff_heisenberg.cpp | 77 +++++++++++++++++++++++++++ src/wolff_planar.cpp | 77 +++++++++++++++++++++++++++ 6 files changed, 308 insertions(+), 174 deletions(-) create mode 100644 lib/wolff.h delete mode 100644 src/wolff.cpp create mode 100644 src/wolff_heisenberg.cpp create mode 100644 src/wolff_planar.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 7c1bc32..ffbde47 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,7 +12,8 @@ link_directories(~/.local/lib) file(GLOB CSOURCES lib/*.c) file(GLOB CPPSOURCES lib/*.cpp) add_executable(wolff_finite src/wolff_finite.c ${CSOURCES}) -add_executable(wolff src/wolff.cpp ${CPPSOURCES} ${CSOURCES}) +add_executable(wolff_heisenberg src/wolff_heisenberg.cpp ${CPPSOURCES} ${CSOURCES}) +add_executable(wolff_planar src/wolff_planar.cpp ${CPPSOURCES} ${CSOURCES}) find_package(OpenMP) if (OPENMP_FOUND) @@ -21,7 +22,8 @@ if (OPENMP_FOUND) endif() target_link_libraries(wolff_finite gsl m cblas fftw3) -target_link_libraries(wolff gsl m cblas fftw3) +target_link_libraries(wolff_heisenberg gsl m cblas fftw3) +target_link_libraries(wolff_planar gsl m cblas fftw3) -install(TARGETS wolff_finite wolff DESTINATION bin) +install(TARGETS wolff_finite wolff_heisenberg wolff_planar DESTINATION bin) diff --git a/lib/orthogonal.h b/lib/orthogonal.h index 0b2fdd5..0a2b5c7 100644 --- a/lib/orthogonal.h +++ b/lib/orthogonal.h @@ -9,10 +9,11 @@ #include "types.h" template -struct orthogonal_t { T *x; }; +struct orthogonal_t { bool is_reflection; T *x; }; template void init(orthogonal_t *ptr) { + ptr->is_reflection = false; ptr->x = (T *)calloc(q * q, sizeof(T)); for (q_t i = 0; i < q; i++) { @@ -23,9 +24,19 @@ void init(orthogonal_t *ptr) { template orthogonal_t copy (orthogonal_t m) { orthogonal_t m_copy; - m_copy.x = (T *)calloc(q * q, sizeof(T)); + m_copy.is_reflection = m.is_reflection; - for (q_t i = 0; i < q * q; i++) { + q_t size; + + if (m.is_reflection) { + size = q; + } else { + size = q * q; + } + + m_copy.x = (T *)calloc(size, sizeof(T)); + + for (q_t i = 0; i < size; i++) { m_copy.x[i] = m.x[i]; } @@ -42,9 +53,19 @@ vector_t act (orthogonal_t m, vector_t v) { vector_t v_rot; v_rot.x = (T *)calloc(q, sizeof(T)); - for (q_t i = 0; i < q; i++) { - for (q_t j = 0; j < q; j++) { - v_rot.x[i] += m.x[q * i + j] * v.x[j]; + if (m.is_reflection) { + double prod = 0; + for (q_t i = 0; i < q; i++) { + prod += v.x[i] * m.x[i]; + } + for (q_t i = 0; i < q; i++) { + v_rot.x[i] = v.x[i] - 2 * prod * m.x[i]; + } + } else { + for (q_t i = 0; i < q; i++) { + for (q_t j = 0; j < q; j++) { + v_rot.x[i] += m.x[q * i + j] * v.x[j]; + } } } @@ -54,12 +75,28 @@ vector_t act (orthogonal_t m, vector_t v) { template orthogonal_t act (orthogonal_t m1, orthogonal_t m2) { orthogonal_t m2_rot; + + m2_rot.is_reflection = false; m2_rot.x = (T *)calloc(q * q, sizeof(T)); - for (q_t i = 0; i < q; i++) { - for (q_t j = 0; j < q; j++) { + if (m1.is_reflection) { + for (q_t i = 0; i < q; i++) { + double akOki = 0; + for (q_t k = 0; k < q; k++) { - m2_rot.x[i * q + j] += m1.x[i * q + j] * m2.x[j * q + k]; + akOki += m1.x[k] * m2.x[q * k + i]; + } + + for (q_t j = 0; j < q; j++) { + m2_rot.x[q * j + i] = m2.x[q * j + i] - 2 * akOki * m1.x[j]; + } + } + } else { + for (q_t i = 0; i < q; i++) { + for (q_t j = 0; j < q; j++) { + for (q_t k = 0; k < q; k++) { + m2_rot.x[i * q + j] += m1.x[i * q + j] * m2.x[j * q + k]; + } } } } @@ -69,54 +106,59 @@ orthogonal_t act (orthogonal_t m1, orthogonal_t m2) { template vector_t act_inverse (orthogonal_t m, vector_t v) { - vector_t v_rot; - v_rot.x = (T *)calloc(q, sizeof(T)); - - for (q_t i = 0; i < q; i++) { - for (q_t j = 0; j < q; j++) { - v_rot.x[i] += m.x[q * j + i] * v.x[j]; + if (m.is_reflection) { + return act(m, v); // reflections are their own inverse + } else { + vector_t v_rot; + v_rot.x = (T *)calloc(q, sizeof(T)); + + for (q_t i = 0; i < q; i++) { + for (q_t j = 0; j < q; j++) { + v_rot.x[i] += m.x[q * j + i] * v.x[j]; + } } - } - return v_rot; + return v_rot; + } } template orthogonal_t act_inverse (orthogonal_t m1, orthogonal_t m2) { - orthogonal_t m2_rot; - m2_rot.x = (T *)calloc(q * q, sizeof(T)); - - for (q_t i = 0; i < q; i++) { - for (q_t j = 0; j < q; j++) { - for (q_t k = 0; k < q; k++) { - m2_rot.x[i * q + j] += m1.x[j * q + i] * m2.x[j * q + k]; + if (m1.is_reflection) { + return act(m1, m2); // reflections are their own inverse + } else { + orthogonal_t m2_rot; + m2_rot.x = (T *)calloc(q * q, sizeof(T)); + + for (q_t i = 0; i < q; i++) { + for (q_t j = 0; j < q; j++) { + for (q_t k = 0; k < q; k++) { + m2_rot.x[i * q + j] += m1.x[j * q + i] * m2.x[j * q + k]; + } } } - } - return m2_rot; + return m2_rot; + } } template void generate_rotation (gsl_rng *r, orthogonal_t *ptr) { - double *v = (double *)malloc(q * sizeof(double)); + ptr->is_reflection = true; + ptr->x = (double *)calloc(q, sizeof(double)); + double v2 = 0; for (q_t i = 0; i < q; i++) { - v[i] = gsl_ran_ugaussian(r); - v2 += v[i] * v[i]; + ptr->x[i] = gsl_ran_ugaussian(r); + v2 += ptr->x[i] * ptr->x[i]; } - ptr->x = (double *)calloc(q * q, sizeof(double)); - + double mag_v = sqrt(v2); + for (q_t i = 0; i < q; i++) { - ptr->x[q * i + i] = 1.0; - for (q_t j = 0; j < q; j++) { - ptr->x[q * i + j] -= 2 * v[i] * v[j] / v2; - } + ptr->x[i] /= mag_v; } - - free(v); } diff --git a/lib/wolff.h b/lib/wolff.h new file mode 100644 index 0000000..81830ee --- /dev/null +++ b/lib/wolff.h @@ -0,0 +1,70 @@ + +#include +#include + +#include + +template +double H_vector(vector_t v1, T *H) { + vector_t H_vec; + H_vec.x = H; + return (double)(dot (v1, H_vec)); +} + +template +void wolff(count_t N, D_t D, L_t L, double T, std::function J, std::function H, unsigned long timestamp, bool silent) { + + state_t s(D, L, T, J, H); + + // initialize random number generator + gsl_rng *r = gsl_rng_alloc(gsl_rng_mt19937); + gsl_rng_set(r, rand_seed()); + + char *filename_M = (char *)malloc(255 * sizeof(char)); + char *filename_E = (char *)malloc(255 * sizeof(char)); + char *filename_S = (char *)malloc(255 * sizeof(char)); + + sprintf(filename_M, "wolff_%lu_M.dat", timestamp); + sprintf(filename_E, "wolff_%lu_E.dat", timestamp); + sprintf(filename_S, "wolff_%lu_S.dat", timestamp); + + FILE *outfile_M = fopen(filename_M, "wb"); + FILE *outfile_E = fopen(filename_E, "wb"); + FILE *outfile_S = fopen(filename_S, "wb"); + + free(filename_M); + free(filename_E); + free(filename_S); + + v_t cluster_size = 0; + + if (!silent) printf("\n"); + for (count_t steps = 0; steps < N; steps++) { + if (!silent) printf("\033[F\033[JWOLFF: sweep %" PRIu64 " / %" PRIu64 ": E = %.2f, M_0 = %.2f, S = %" PRIv "\n", steps, N, s.E, s.M.x[0], cluster_size); + + v_t v0 = gsl_rng_uniform_int(r, s.nv); + + R_t step; + generate_rotation(r, &step); + + cluster_size = flip_cluster (&s, v0, step, r); + + free_spin(step); + + fwrite(&(s.E), sizeof(double), 1, outfile_E); + fwrite(s.M.x, sizeof(double), 2, outfile_M); + fwrite(&cluster_size, sizeof(uint32_t), 1, outfile_S); + + } + if (!silent) { + printf("\033[F\033[J"); + } + printf("WOLFF: sweep %" PRIu64 " / %" PRIu64 ": E = %.2f, M_0 = %.2f, S = %" PRIv "\n", N, N, s.E, s.M.x[0], cluster_size); + + fclose(outfile_M); + fclose(outfile_E); + fclose(outfile_S); + + gsl_rng_free(r); +} + diff --git a/src/wolff.cpp b/src/wolff.cpp deleted file mode 100644 index f685129..0000000 --- a/src/wolff.cpp +++ /dev/null @@ -1,134 +0,0 @@ - -#include -#include - -#include - -double H_vector(vector_t <2, double> v1, double *H) { - vector_t <2, double> H_vec; - H_vec.x = H; - return dot <2, double> (v1, H_vec); -} - -int main(int argc, char *argv[]) { - - count_t N = (count_t)1e7; - - D_t D = 2; - L_t L = 128; - double T = 2.26918531421; - double *H = (double *)calloc(MAX_Q, sizeof(double)); - - bool silent = false; - - int opt; - q_t J_ind = 0; - q_t H_ind = 0; - - while ((opt = getopt(argc, argv, "N:q:D:L:T:J:H:s")) != -1) { - switch (opt) { - case 'N': // number of steps - N = (count_t)atof(optarg); - break; - case 'D': // dimension - D = atoi(optarg); - break; - case 'L': // linear size - L = atoi(optarg); - break; - case 'T': // temperature - T = atof(optarg); - break; - case 'H': // external field. nth call couples to state n - H[H_ind] = atof(optarg); - H_ind++; - break; - case 's': // don't print anything during simulation. speeds up slightly - silent = true; - break; - default: - exit(EXIT_FAILURE); - } - } - - state_t , vector_t <2, double>> s(D, L, T, dot <2, double>, std::bind(H_vector, std::placeholders::_1, H)); - - // initialize random number generator - gsl_rng *r = gsl_rng_alloc(gsl_rng_mt19937); - gsl_rng_set(r, rand_seed()); - - unsigned long timestamp; - - { - struct timespec spec; - clock_gettime(CLOCK_REALTIME, &spec); - timestamp = spec.tv_sec*1000000000LL + spec.tv_nsec; - } - - FILE *outfile_info = fopen("wolff_metadata.txt", "a"); - - fprintf(outfile_info, "<| \"ID\" -> %lu, \"D\" -> %" PRID ", \"L\" -> %" PRIL ", \"NV\" -> %" PRIv ", \"NE\" -> %" PRIv ", \"T\" -> %.15f, \"H\" -> {", timestamp, D, L, s.nv, s.ne, T); - - for (q_t i = 0; i < 2; i++) { - fprintf(outfile_info, "%.15f", H[i]); - if (i < 2 - 1) { - fprintf(outfile_info, ", "); - } - } - - fprintf(outfile_info, "} |>\n"); - - fclose(outfile_info); - - char *filename_M = (char *)malloc(255 * sizeof(char)); - char *filename_E = (char *)malloc(255 * sizeof(char)); - char *filename_S = (char *)malloc(255 * sizeof(char)); - - sprintf(filename_M, "wolff_%lu_M.dat", timestamp); - sprintf(filename_E, "wolff_%lu_E.dat", timestamp); - sprintf(filename_S, "wolff_%lu_S.dat", timestamp); - - FILE *outfile_M = fopen(filename_M, "wb"); - FILE *outfile_E = fopen(filename_E, "wb"); - FILE *outfile_S = fopen(filename_S, "wb"); - - free(filename_M); - free(filename_E); - free(filename_S); - - v_t cluster_size = 0; - - if (!silent) printf("\n"); - for (count_t steps = 0; steps < N; steps++) { - if (!silent) printf("\033[F\033[JWOLFF: sweep %" PRIu64 " / %" PRIu64 ": E = %.2f, M_0 = %.2f, S = %" PRIv "\n", steps, N, s.E, s.M.x[0], cluster_size); - - v_t v0 = gsl_rng_uniform_int(r, s.nv); - - orthogonal_t <2, double> step; - generate_rotation<2>(r, &step); - - cluster_size = flip_cluster , vector_t <2, double>> (&s, v0, step, r); - - free_spin(step); - - fwrite(&(s.E), sizeof(double), 1, outfile_E); - fwrite(s.M.x, sizeof(double), 2, outfile_M); - fwrite(&cluster_size, sizeof(uint32_t), 1, outfile_S); - - } - if (!silent) { - printf("\033[F\033[J"); - } - printf("WOLFF: sweep %" PRIu64 " / %" PRIu64 ": E = %.2f, M_0 = %.2f, S = %" PRIv "\n", N, N, s.E, s.M.x[0], cluster_size); - - fclose(outfile_M); - fclose(outfile_E); - fclose(outfile_S); - - gsl_rng_free(r); - - free(H); - - return 0; -} - diff --git a/src/wolff_heisenberg.cpp b/src/wolff_heisenberg.cpp new file mode 100644 index 0000000..d1ebd48 --- /dev/null +++ b/src/wolff_heisenberg.cpp @@ -0,0 +1,77 @@ + +#include + +#include + +int main(int argc, char *argv[]) { + + count_t N = (count_t)1e7; + + D_t D = 2; + L_t L = 128; + double T = 2.26918531421; + double *H = (double *)calloc(MAX_Q, sizeof(double)); + + bool silent = false; + + int opt; + q_t J_ind = 0; + q_t H_ind = 0; + + while ((opt = getopt(argc, argv, "N:q:D:L:T:J:H:s")) != -1) { + switch (opt) { + case 'N': // number of steps + N = (count_t)atof(optarg); + break; + case 'D': // dimension + D = atoi(optarg); + break; + case 'L': // linear size + L = atoi(optarg); + break; + case 'T': // temperature + T = atof(optarg); + break; + case 'H': // external field. nth call couples to state n + H[H_ind] = atof(optarg); + H_ind++; + break; + case 's': // don't print anything during simulation. speeds up slightly + silent = true; + break; + default: + exit(EXIT_FAILURE); + } + } + + unsigned long timestamp; + + { + struct timespec spec; + clock_gettime(CLOCK_REALTIME, &spec); + timestamp = spec.tv_sec*1000000000LL + spec.tv_nsec; + } + + FILE *outfile_info = fopen("wolff_metadata.txt", "a"); + + fprintf(outfile_info, "<| \"ID\" -> %lu, \"MODEL\" -> \"HEISENBERG\", q -> \"3\", \"D\" -> %" PRID ", \"L\" -> %" PRIL ", \"NV\" -> %" PRIv ", \"NE\" -> %" PRIv ", \"T\" -> %.15f, \"H\" -> {", timestamp, D, L, L * L, D * L * L, T); + + for (q_t i = 0; i < 2; i++) { + fprintf(outfile_info, "%.15f", H[i]); + if (i < 2 - 1) { + fprintf(outfile_info, ", "); + } + } + + fprintf(outfile_info, "} |>\n"); + + fclose(outfile_info); + + + wolff , vector_t <3, double>> (N, D, L, T, dot <3, double>, std::bind(H_vector <3, double>, std::placeholders::_1, H), timestamp, silent); + + free(H); + + return 0; +} + diff --git a/src/wolff_planar.cpp b/src/wolff_planar.cpp new file mode 100644 index 0000000..02ededc --- /dev/null +++ b/src/wolff_planar.cpp @@ -0,0 +1,77 @@ + +#include + +#include + +int main(int argc, char *argv[]) { + + count_t N = (count_t)1e7; + + D_t D = 2; + L_t L = 128; + double T = 2.26918531421; + double *H = (double *)calloc(MAX_Q, sizeof(double)); + + bool silent = false; + + int opt; + q_t J_ind = 0; + q_t H_ind = 0; + + while ((opt = getopt(argc, argv, "N:q:D:L:T:J:H:s")) != -1) { + switch (opt) { + case 'N': // number of steps + N = (count_t)atof(optarg); + break; + case 'D': // dimension + D = atoi(optarg); + break; + case 'L': // linear size + L = atoi(optarg); + break; + case 'T': // temperature + T = atof(optarg); + break; + case 'H': // external field. nth call couples to state n + H[H_ind] = atof(optarg); + H_ind++; + break; + case 's': // don't print anything during simulation. speeds up slightly + silent = true; + break; + default: + exit(EXIT_FAILURE); + } + } + + unsigned long timestamp; + + { + struct timespec spec; + clock_gettime(CLOCK_REALTIME, &spec); + timestamp = spec.tv_sec*1000000000LL + spec.tv_nsec; + } + + FILE *outfile_info = fopen("wolff_metadata.txt", "a"); + + fprintf(outfile_info, "<| \"ID\" -> %lu, \"MODEL\" -> \"PLANAR\", \"q\" -> 2, \"D\" -> %" PRID ", \"L\" -> %" PRIL ", \"NV\" -> %" PRIv ", \"NE\" -> %" PRIv ", \"T\" -> %.15f, \"H\" -> {", timestamp, D, L, L * L, D * L * L, T); + + for (q_t i = 0; i < 2; i++) { + fprintf(outfile_info, "%.15f", H[i]); + if (i < 2 - 1) { + fprintf(outfile_info, ", "); + } + } + + fprintf(outfile_info, "} |>\n"); + + fclose(outfile_info); + + + wolff , vector_t <2, double>> (N, D, L, T, dot <2, double>, std::bind(H_vector <2, double>, std::placeholders::_1, H), timestamp, silent); + + free(H); + + return 0; +} + -- cgit v1.2.3-54-g00ecf