diff --git a/include/IsingModel.hpp b/include/IsingModel.hpp index aac9df3..d484bb1 100644 --- a/include/IsingModel.hpp +++ b/include/IsingModel.hpp @@ -12,9 +12,7 @@ #ifndef __ISING_MODEL__ #define __ISING_MODEL__ -#include "constants.hpp" #include "data_type.hpp" -#include "typedefs.hpp" #include "utils.hpp" #include @@ -22,13 +20,13 @@ #include #include -#define INDEX(I, N) (I + N) % N +#define INDEX(I, N) (I + N) % N ///< I modulo N // Indeces for the neighbor matrix. -#define UP 0 -#define LEFT 0 -#define DOWN 1 -#define RIGHT 1 +#define UP 0 ///< Used for the neighbor matrix in the class +#define LEFT 0 ///< Used for the neighbor matrix in the class +#define DOWN 1 ///< Used for the neighbor matrix in the class +#define RIGHT 1 ///< Used for the neighbor matrix in the class /** @brief The Ising model in 2 dimensions. * @@ -37,7 +35,10 @@ * */ class IsingModel { private: + /** @brief Give access to private members to the test class IsingModelTest. + * */ friend class IsingModelTest; + /** @brief \f$ L \times L \f$ matrix where element \f$ x \in {-1, 1}\f$. * */ arma::Mat lattice; @@ -52,9 +53,8 @@ private: * */ arma::Mat neighbors; - /** @brief A hash map containing all possible energy changes. + /** @brief An array containing all possible energy differences. * */ - //std::unordered_map energy_diff; double energy_diff[17]; /** @brief The temperature of the model. @@ -73,27 +73,36 @@ private: * */ int64_t M; + /** @brief The RNG that is used for the Metropolis algorithm + * */ std::mt19937 engine; + /** @brief Initialize the RNG. + * */ void initialize_engine(); + /** @brief Initialize the lattice with a random distribution of 1s and * -1s. * */ void initialize_lattice(); + /** @brief Initialize the lattice with a specific value. + * */ + void initialize_lattice(int val); + /** @brief initialize the neighbors matrix. * */ void initialize_neighbors(); - /** @brief Initialize the hashmap with the correct values. + /** @brief Initialize the energy_diff array with the correct values. * */ void initialize_energy_diff(); - /** @brief Initialize the magnetization. + /** @brief Initialize the magnetization of the system. * */ void initialize_magnetization(); - /** @brief Initialize the energy. + /** @brief Initialize the energy of the system. * */ void initialize_energy(); @@ -120,18 +129,6 @@ public: /** @brief The Metropolis algorithm. * */ data_t Metropolis(); - - /** @brief Get the current energy. - * - * @return double - * */ - int get_E(); - - /** @brief Get the current magnetization. - * - * @return double - * */ - int get_M(); }; #endif diff --git a/include/constants.hpp b/include/constants.hpp deleted file mode 100644 index 87f1e95..0000000 --- a/include/constants.hpp +++ /dev/null @@ -1,19 +0,0 @@ -/** @file constants.hpp - * - * @author Cory Alexander Balaton (coryab) - * @author Janita Ovidie Sandtrøen Willumsen (janitaws) - * - * @version 1.0 - * - * @brief Library of constants - * - * @bug No known bugs - * */ -#ifndef __CONST__ -#define __CONST__ - -/** @brief Boltzmann constant. unit \f$ \frac{J}{K} \f$. - * */ -#define k_B 1.380649e-23 - -#endif diff --git a/include/data_type.hpp b/include/data_type.hpp index 7192660..30cbf48 100644 --- a/include/data_type.hpp +++ b/include/data_type.hpp @@ -15,10 +15,17 @@ #include #include +/** @brief Type to use with the IsingModel class and montecarlo module.*/ class data_t { public: - double E, M, E2, M2, M_abs; + double E; ///< Energy + double M; ///< Magnetization + double E2; ///< Energy squared + double M2; ///< Magnetization squared + double M_abs; ///< Absolute Magnetization + /** @brief constructor with no parameters. + * */ data_t() { this->E = 0.; @@ -28,6 +35,13 @@ public: this->M_abs = 0.; } + /** @brief Constructor with parameters. + * + * @param E Initial energy + * @param E2 Initial energy squared + * @param M Initial magnetization + * @param M2 Initial magnetization squared + * @param M_abs Initial absolute magnetization*/ data_t(double E, double E2, double M, double M2, double M_abs) { this->E = E; @@ -37,6 +51,12 @@ public: this->M_abs = M_abs; } + /** @brief Overload of the division operator. + * + * @param num The number to divide each field by. + * + * @return data_t + * */ template data_t operator/(T num) { data_t res; @@ -49,6 +69,13 @@ public: return res; } + + /** @brief Overload of the division equals operator. + * + * @param num The number to divide each field by. + * + * @return data_t + * */ template data_t &operator/=(T num) { this->E /= (double)num; @@ -60,6 +87,12 @@ public: return *this; } + /** @brief Overload of the multiply operator. + * + * @param num The number to multiply each field by. + * + * @return data_t + * */ template data_t operator*(T num) { data_t res; @@ -72,6 +105,12 @@ public: return res; } + /** @brief Overload of the multiply equals operator. + * + * @param num The number to multiply each field by. + * + * @return data_t + * */ template data_t &operator*=(T num) { this->E *= (double)num; @@ -83,6 +122,13 @@ public: return *this; } + + /** @brief Overload of the addition operator. + * + * @param b The data_t field to add. + * + * @return data_t + * */ data_t operator+(const data_t &b) { data_t res; @@ -95,6 +141,12 @@ public: return res; } + /** @brief Overload of the addition equals operator. + * + * @param b The data_t field to add. + * + * @return data_t + * */ data_t &operator+=(const data_t &b) { this->E += b.E; @@ -105,17 +157,9 @@ public: return *this; } - - template void operator=(T num) - { - this->E = (double)num; - this->E2 = (double)num; - this->M = (double)num; - this->M2 = (double)num; - this->M_abs = (double)num; - } }; +// Declare a custom reduction for the data_t type. #pragma omp declare reduction(+ : data_t : omp_out += omp_in) #endif diff --git a/include/monte_carlo.hpp b/include/monte_carlo.hpp index f865565..3d943a0 100644 --- a/include/monte_carlo.hpp +++ b/include/monte_carlo.hpp @@ -30,6 +30,7 @@ namespace montecarlo { * @param L The size of the lattice * @param cycles The amount of Monte Carlo cycles to do * @param filename The file to write to + * @param burn_in_time The burn-in time to use * */ void progression(double T, int L, int cycles, const std::string filename, int burn_in_time = BURN_IN_TIME); @@ -41,6 +42,7 @@ void progression(double T, int L, int cycles, const std::string filename, * @param cycles The amount of Monte Carlo cycles to do * @param value The value to set the elements in the lattice * @param filename The file to write to + * @param burn_in_time The burn-in time to use * */ void progression(double T, int L, int cycles, int value, const std::string filename, int burn_in_time = BURN_IN_TIME); @@ -51,6 +53,7 @@ void progression(double T, int L, int cycles, int value, * @param L The size of the lattice * @param cycles The amount of Monte Carlo cycles to do * @param filename The file to write to + * @param burn_in_time The burn-in time to use * */ void pd_estimate(double T, int L, int cycles, const std::string filename, int burn_in_time = BURN_IN_TIME); @@ -61,6 +64,7 @@ void pd_estimate(double T, int L, int cycles, const std::string filename, * @param L The size of the lattice * @param T The Temperature for the Ising model * @param cycles The amount of Monte Carlo cycles to do + * @param burn_in_time The burn-in time to use * * @return data_t * */ @@ -73,6 +77,7 @@ data_t mcmc_serial(int L, double T, int cycles, * @param L The size of the lattice * @param T The Temperature for the Ising model * @param cycles The amount of Monte Carlo cycles to do + * @param burn_in_time The burn-in time to use * * @return data_t * */ @@ -87,6 +92,7 @@ data_t mcmc_parallel(int L, double T, int cycles, * @param point_T The amount of point to measure * @param monte_carlo Which Monte Carlo implementation to use * @param outfile The file to write the data to + * @param burn_in_time The burn-in time to use * */ void phase_transition(int L, double start_T, double end_T, int points_T, int cycles, diff --git a/include/testlib.hpp b/include/testlib.hpp index 853c649..84f6418 100644 --- a/include/testlib.hpp +++ b/include/testlib.hpp @@ -8,7 +8,7 @@ * @brief A small test library. * * @details This a small testing library that is tailored for the needs of the - * project. Anything that is in the details namespace should not be used + * project. Anything that is in the details namespace should not be used * directly, or else it might cause undefined behavior if not used correctly. * * @bug No known bugs @@ -32,6 +32,7 @@ details::m_assert(expr, #expr, __METHOD_NAME__, __FILE__, __LINE__, msg) namespace details { + /** @brief Test an expression, confirm that test is ok, or abort execution. * * @details This function takes in an expression and prints an OK message if @@ -49,6 +50,7 @@ void m_assert(bool expr, std::string expr_str, std::string func, } // namespace details namespace testlib { + /** @brief Test if two armadillo matrices/vectors are close to each other. * * @details This function takes in 2 matrices/vectors and checks if they are diff --git a/include/typedefs.hpp b/include/typedefs.hpp deleted file mode 100644 index 90bc0f5..0000000 --- a/include/typedefs.hpp +++ /dev/null @@ -1,18 +0,0 @@ -/** @file typedefs.hpp - * - * @author Cory Alexander Balaton (coryab) - * @author Janita Ovidie Sandtrøen Willumsen (janitaws) - * - * @version 1.0 - * - * @brief Useful typedefs for cleaner code. - * - * @details These typedefs make the code more readable and easy to follow - * along. - * - * @bug No known bugs - * */ -#ifndef __TYPEDEFS__ -#define __TYPEDEFS__ - -#endif diff --git a/src/IsingModel.cpp b/src/IsingModel.cpp index c94478e..616e251 100644 --- a/src/IsingModel.cpp +++ b/src/IsingModel.cpp @@ -10,7 +10,6 @@ * @bug No known bugs * */ #include "IsingModel.hpp" -#include IsingModel::IsingModel() { @@ -34,8 +33,7 @@ IsingModel::IsingModel(int L, double T, int val) this->L = L; this->T = T; this->initialize_engine(); - this->lattice.set_size(this->L, this->L); - this->lattice.fill(val); + this->initialize_lattice(val); this->initialize_neighbors(); this->initialize_energy_diff(); this->initialize_magnetization(); @@ -58,6 +56,17 @@ void IsingModel::initialize_lattice() this->lattice(i) = 2 * coin_flip(this->engine) - 1; } +void IsingModel::initialize_lattice(int val) +{ + // If val is neither 1 or -1, then initialize random values. + if (val != 1 && val != -1) { + this->initialize_lattice(); + return; + } + this->lattice.set_size(this->L, this->L); + this->lattice.fill(val); +} + void IsingModel::initialize_neighbors() { this->neighbors.set_size(this->L, 2); @@ -133,13 +142,3 @@ data_t IsingModel::Metropolis() return data_t((double)this->E, (double)(this->E * this->E), (double)this->M, (double)(this->M * this->M), std::fabs((double)this->M)); } - -int IsingModel::get_E() -{ - return this->E; -} - -int IsingModel::get_M() -{ - return this->M; -} diff --git a/src/Makefile b/src/Makefile deleted file mode 100644 index 540efaa..0000000 --- a/src/Makefile +++ /dev/null @@ -1,66 +0,0 @@ -#CC=g++ -CC=mpic++ - -LIBSRCS=utils.cpp testlib.cpp data_type.cpp -LIBOBJS=$(LIBSRCS:.cpp=.o) -LIBPROFOBJS=$(addprefix prof/, $(LIBOBJS)) - -CLASSSRCS=IsingModel.cpp monte_carlo.cpp -CLASSOBJS=$(CLASSSRCS:.cpp=.o) -CLASSPROFOBJS=$(addprefix prof/, $(CLASSOBJS)) - -INCLUDE=../include - -CFLAGS=-Wall -larmadillo -std=c++11 -O3 -fomit-frame-pointer -#CFLAGS=-Wall -larmadillo -lblas -llapack -std=c++11 -O3 -fomit-frame-pointer -OPENMP=-fopenmp - -# Add a debug flag when compiling (For the DEBUG macro in utils.hpp) -DEBUG ?= 0 -ifeq ($(DEBUG), 1) - DBGFLAG=-DDBG -g -else - DBGFLAG= -endif - -# Add profiling for serial code -PROFILE ?= 0 -ifeq ($(PROFILE), 1) - PROFFLAG=-pg -fno-inline-functions -else - PROFFLAG= -endif - -.PHONY: clean instrument - -all: main phase_transition_mpi test_suite time -#all: main - -# Instrumentation using scorep for parallel analysis -instrument: prof/phase_transition_mpi.o $(LIBPROFOBJS) $(CLASSPROFOBJS) - scorep $(CC) $(LIBPROFOBJS) $(CLASSPROFOBJS) $< -o phase_transition_mpi_prof $(CFLAGS) $(DBGFLAG) $(PROFFLAG) -I$(INCLUDE) $(OPENMP) - -# Rules for executables -main: main.o $(LIBOBJS) $(CLASSOBJS) - $(CC) $^ -o $@ $(CFLAGS) $(DBGFLAG) $(PROFFLAG) -I$(INCLUDE) $(OPENMP) - -phase_transition_mpi: phase_transition_mpi.o $(LIBOBJS) $(CLASSOBJS) - $(CC) $^ -o $@ $(CFLAGS) $(DBGFLAG) $(PROFFLAG) -I$(INCLUDE) $(OPENMP) - -test_suite: test_suite.o $(LIBOBJS) $(CLASSOBJS) - $(CC) $^ -o $@ $(CFLAGS) $(DBGFLAG) $(PROFFLAG) -I$(INCLUDE) $(OPENMP) - -time: time.o $(LIBOBJS) $(CLASSOBJS) - $(CC) $^ -o $@ $(CFLAGS) $(DBGFLAG) $(PROFFLAG) -I$(INCLUDE) $(OPENMP) - -# Rule for object files -%.o: %.cpp - $(CC) -c $^ -o $@ $(CFLAGS) $(DBGFLAG) $(PROFFLAG) -I$(INCLUDE) $(OPENMP) - -# Rule for instrumented object files -prof/%.o: %.cpp - scorep $(CC) -c $^ -o $@ $(CFLAGS) $(DBGFLAG) $(PROFFLAG) -I$(INCLUDE) $(OPENMP) - -clean: - find . -maxdepth 2 -name "*.o" -type f -delete - rm test_suite main phase_transition_mpi phase_transition_mpi_prof time diff --git a/src/main.cpp b/src/main.cpp index 1d307ba..043c969 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -43,14 +43,17 @@ void create_pd_estimate_data() "../output/pd_estimate/estimate_2_4.txt"); } +/** @brief Create data using the same parameters except one uses burn-in time, + * while the other doesn't. + * */ void test_burn_in_time() { montecarlo::phase_transition( 100, 2.1, 2.4, 40, 1e5, montecarlo::mcmc_serial, - "../output/test_burn_in_time/no_burn_in.txt", 0); + "../output/test_burn_in_time/burn_in.txt", 5000); montecarlo::phase_transition( 100, 2.1, 2.4, 40, 1e5, montecarlo::mcmc_serial, - "../output/test_burn_in_time/burn_in.txt", 5000); + "../output/test_burn_in_time/no_burn_in.txt", 0); } /** @brief Test how much Openmp speeds up.*/ @@ -103,6 +106,7 @@ void create_phase_transition_data() std::cout << "Time: " << t1 - t0 << std::endl; } +/** @brief A function that displays how to use the program and quits.*/ void usage(std::string filename) { std::cout << "Usage: " << filename << " OPTION ...\n" diff --git a/src/mcmc_progression.cpp b/src/mcmc_progression.cpp index e6982d5..b986b8b 100644 --- a/src/mcmc_progression.cpp +++ b/src/mcmc_progression.cpp @@ -18,6 +18,7 @@ #include #include +/** @brief A function that displays how to use the program and quits.*/ void usage(std::string filename) { std::cout << "Usage: " << filename @@ -27,9 +28,7 @@ void usage(std::string filename) exit(-1); } -/** @brief The main function - * - * */ +/** @brief The main function.*/ int main(int argc, char **argv) { // Command options diff --git a/src/pd_estimate.cpp b/src/pd_estimate.cpp index 0ed73c7..3bdcffa 100644 --- a/src/pd_estimate.cpp +++ b/src/pd_estimate.cpp @@ -18,6 +18,7 @@ #include #include +/** @brief A function that displays how to use the program and quits.*/ void usage(std::string filename) { std::cout << "Usage: " << filename diff --git a/src/phase_transition.cpp b/src/phase_transition.cpp index f829405..48c730d 100644 --- a/src/phase_transition.cpp +++ b/src/phase_transition.cpp @@ -21,6 +21,7 @@ #include #include +/** @brief A function that displays how to use the program and quits.*/ void usage(std::string filename) { std::cout << "Usage: " << filename @@ -30,9 +31,7 @@ void usage(std::string filename) exit(-1); } -/** @brief The main function - * - * */ +/** @brief The main function.*/ int main(int argc, char **argv) { // Command options diff --git a/src/phase_transition_mpi.cpp b/src/phase_transition_mpi.cpp index e5fa30e..bfaa121 100644 --- a/src/phase_transition_mpi.cpp +++ b/src/phase_transition_mpi.cpp @@ -21,6 +21,7 @@ #include #include +/** @brief A function that displays how to use the program and quits.*/ void usage(std::string filename) { std::cout @@ -33,9 +34,7 @@ void usage(std::string filename) exit(-1); } -/** @brief The main function - * - * */ +/** @brief The main function.*/ int main(int argc, char **argv) { // Command options diff --git a/src/test_suite.cpp b/src/test_suite.cpp index a9cd8c5..7b85b8c 100644 --- a/src/test_suite.cpp +++ b/src/test_suite.cpp @@ -12,13 +12,21 @@ #include "IsingModel.hpp" #include "testlib.hpp" +/** @brief The analytic expected energy for a \f$ 2 \times 2 \f$ lattice. + * */ #define EPS_2 (-2 * std::sinh(8.)) / (std::cosh(8.) + 3) +/** @brief The analytic expected magnetization for a \f$ 2 \times 2 \f$ + * lattice. + * */ #define MAG_2 (std::exp(8.) + 1) / (2 * (cosh(8.) + 3)) +/** @brief The analytic heat capacity for a \f$ 2 \times 2 \f$ lattice. + * */ #define CV_2 \ 16 * (3 * std::cosh(8.) + 1) / ((std::cosh(8.) + 3) * (std::cosh(8.) + 3)) +/** @brief The analytic susceptibility for a \f$ 2 \times 2 \f$ lattice.*/ #define X_2 \ (3 * std::exp(8.) + std::exp(-8.) + 3) \ / ((std::cosh(8.) + 3) * (std::cosh(8.) + 3)) @@ -87,10 +95,10 @@ public: tmp = data / cycles; if (testlib::close_to(EPS_2, tmp.E / n_spins, tol) && testlib::close_to(MAG_2, tmp.M_abs / n_spins, tol) - && testlib::close_to(CV_2, (tmp.E2 - tmp.E * tmp.E) / (T * T) - / n_spins, tol) - && testlib::close_to(X_2, (tmp.M2 - tmp.M_abs * tmp.M_abs) / T - / n_spins, tol)) { + && testlib::close_to( + CV_2, (tmp.E2 - tmp.E * tmp.E) / (T * T) / n_spins, tol) + && testlib::close_to( + X_2, (tmp.M2 - tmp.M_abs * tmp.M_abs) / T / n_spins, tol)) { return cycles; } } @@ -111,7 +119,7 @@ int main() int accepted_values = 0; // Run through the test multiple times to get a better estimate. - for (size_t i=0; i < iterations; i++) { + for (size_t i = 0; i < iterations; i++) { tmp = test.test_2x2_lattice(1e-2, 1e5); if (tmp == 0) { continue; @@ -119,7 +127,7 @@ int main() accepted_values++; res += tmp; } - + std::cout << "Res: " << res / accepted_values << std::endl; return 0; diff --git a/src/time.cpp b/src/time.cpp index afbb8bd..b93ed43 100644 --- a/src/time.cpp +++ b/src/time.cpp @@ -5,7 +5,7 @@ * * @version 0.1 * - * @brief Timing various things + * @brief Timing various things. * * @bug No known bugs * */ @@ -17,9 +17,11 @@ #include #include +/** @brief Time phase transition using different lattice sizes. + * */ void time_lattice_sizes() { - std::string outfile = "output/timing/lattice_sizes.txt"; + std::string outfile = "data/timing/lattice_sizes.txt"; std::ofstream ofile; int lattice_sizes[] = {20, 40, 60, 80, 100}; @@ -38,9 +40,11 @@ void time_lattice_sizes() ofile.close(); } +/** @brief Time phase transition using different sample sizes. + * */ void time_sample_sizes() { - std::string outfile = "output/timing/sample_sizes.txt"; + std::string outfile = "data/timing/sample_sizes.txt"; std::ofstream ofile; int sample_sizes[] = {1000, 10000, 100000}; @@ -59,6 +63,7 @@ void time_sample_sizes() ofile.close(); } +/** @brief A function that displays how to use the program and quits.*/ void usage(std::string filename) { std::cout << "Usage: " << filename << " OPTION ...\n" @@ -70,6 +75,7 @@ void usage(std::string filename) exit(-1); } +/** @brief The main function.*/ int main(int argc, char **argv) { struct option long_options[] = {{"all", 0, 0, 0},