diff options
author | Jaron Kent-Dobias <jaron@kent-dobias.com> | 2018-07-09 14:19:16 -0400 |
---|---|---|
committer | Jaron Kent-Dobias <jaron@kent-dobias.com> | 2018-07-09 14:19:16 -0400 |
commit | 466812e61e2ccec7750c791835111b402938411c (patch) | |
tree | 09b46ec932ce6b31b8093580d500b91bb0e19bb7 | |
parent | dc72eb1fa4a476eade0ade98a463e7c96000fb0d (diff) | |
download | c++-466812e61e2ccec7750c791835111b402938411c.tar.gz c++-466812e61e2ccec7750c791835111b402938411c.tar.bz2 c++-466812e61e2ccec7750c791835111b402938411c.zip |
wolff run from own function, called with types to run
-rw-r--r-- | CMakeLists.txt | 8 | ||||
-rw-r--r-- | lib/orthogonal.h | 116 | ||||
-rw-r--r-- | lib/wolff.h | 70 | ||||
-rw-r--r-- | src/wolff.cpp | 134 | ||||
-rw-r--r-- | src/wolff_heisenberg.cpp | 77 | ||||
-rw-r--r-- | src/wolff_planar.cpp | 77 |
6 files changed, 308 insertions, 174 deletions
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 <q_t q, class T> -struct orthogonal_t { T *x; }; +struct orthogonal_t { bool is_reflection; T *x; }; template <q_t q, class T> void init(orthogonal_t <q, 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 <q, T> *ptr) { template <q_t q, class T> orthogonal_t <q, T> copy (orthogonal_t <q, T> m) { orthogonal_t <q, 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 <q, T> act (orthogonal_t <q, T> m, vector_t <q, T> v) { vector_t <q, 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 <q, T> act (orthogonal_t <q, T> m, vector_t <q, T> v) { template <q_t q, class T> orthogonal_t <q, T> act (orthogonal_t <q, T> m1, orthogonal_t <q, T> m2) { orthogonal_t <q, 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 <q, T> act (orthogonal_t <q, T> m1, orthogonal_t <q, T> m2) { template <q_t q, class T> vector_t <q, T> act_inverse (orthogonal_t <q, T> m, vector_t <q, T> v) { - vector_t <q, 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 <q, 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 <q_t q, class T> orthogonal_t <q, T> act_inverse (orthogonal_t <q, T> m1, orthogonal_t <q, T> m2) { - orthogonal_t <q, 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 <q, 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 <q_t q> void generate_rotation (gsl_rng *r, orthogonal_t <q, double> *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 <time.h> +#include <getopt.h> + +#include <cluster.h> + +template <q_t q, class T> +double H_vector(vector_t <q, T> v1, T *H) { + vector_t <q, T> H_vec; + H_vec.x = H; + return (double)(dot <q, T> (v1, H_vec)); +} + +template <class R_t, class X_t> +void wolff(count_t N, D_t D, L_t L, double T, std::function <double(X_t, X_t)> J, std::function <double(X_t)> H, unsigned long timestamp, bool silent) { + + state_t <R_t, X_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 <R_t, X_t> (&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 <time.h> -#include <getopt.h> - -#include <cluster.h> - -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 <orthogonal_t <2, double>, 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 <orthogonal_t <2, double>, 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 <getopt.h> + +#include <wolff.h> + +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 <orthogonal_t <3, double>, 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 <getopt.h> + +#include <wolff.h> + +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 <orthogonal_t <2, double>, 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; +} + |