diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..053ecef --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.idea/ +.DS_Store +build +cmake-build-default/ diff --git a/Algorithm/Algorithm.hpp b/Algorithm/Algorithm.hpp new file mode 100644 index 0000000..8c0dd03 --- /dev/null +++ b/Algorithm/Algorithm.hpp @@ -0,0 +1,18 @@ +// +// Created by Patrick O'Brien on 9/19/18. +// + +#ifndef SIMULATION_ALGORITHM_HPP +#define SIMULATION_ALGORITHM_HPP + +#include "../Model/Model.hpp" +#include +using namespace arma; + +#endif //SIMULATION_ALGORITHM_HPP + + +class Algorithm{ +public: + virtual void simulate(int nitr, Model *model_ptr)=0; +}; \ No newline at end of file diff --git a/Algorithm/MonteCarlo.cpp b/Algorithm/MonteCarlo.cpp new file mode 100644 index 0000000..1d9af23 --- /dev/null +++ b/Algorithm/MonteCarlo.cpp @@ -0,0 +1,34 @@ +// +// Created by Patrick O'Brien on 9/19/18. +// + +#include "MonteCarlo.hpp" +#include "../Model/Model.hpp" + +void MonteCarlo::simulate(int nitr, Model *model_ptr) { + std::ofstream output; + output.open("output.json"); + model_ptr->create_initial_spin_configuration(); + + output << R"({"type": "common_origin", "data": [)"; + + int accepted_counter = 0; + output << model_ptr->save_spin_configuration(accepted_counter).str(); + + for (int i = 0; i < nitr; i++) { + uword random_index = randi(1, 1, distr_param(0, (model_ptr->system_size) - 1))(0); + mat old = model_ptr->spin_config.row(random_index); + mat new_s = model_ptr->new_spin(); + double change_eng = model_ptr->energy_change(random_index, new_s); + + if (change_eng < 0.0) { + output << ", "; + model_ptr->update_spin_configuration(random_index, new_s); + accepted_counter++; + output << model_ptr->save_spin_configuration(accepted_counter).str(); + } + } + + output << "]}"; + output.close(); +} \ No newline at end of file diff --git a/Algorithm/MonteCarlo.hpp b/Algorithm/MonteCarlo.hpp new file mode 100644 index 0000000..0d09914 --- /dev/null +++ b/Algorithm/MonteCarlo.hpp @@ -0,0 +1,16 @@ +// +// Created by Patrick O'Brien on 10/2/18. +// + +#ifndef SIMULATION_MONTECARLO_HPP +#define SIMULATION_MONTECARLO_HPP + +#include "Algorithm.hpp" +#include "../Model/Model.hpp" + +#endif //SIMULATION_MONTECARLO_HPP + +class MonteCarlo: public Algorithm{ +public: + void simulate(int nitr, Model *model_ptr) override; +}; \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..a162e79 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,10 @@ +cmake_minimum_required(VERSION 3.10) +project(Simulation) + +set(CMAKE_CXX_STANDARD 11) + +find_library(Simulation libarmadillo) + +add_executable(Simulation main.cpp Model/Model.hpp Model/Heisenberg.cpp Algorithm/MonteCarlo.cpp Lattice/Lattice.hpp Model/Heisenberg.hpp Algorithm/MonteCarlo.hpp Algorithm/Algorithm.hpp) + +target_link_libraries(Simulation armadillo) \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..8d55139 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,4 @@ +FROM ubuntu:18.10 +RUN apt update && DEBIAN_FRONTEND=noninteractive apt install -y g++ git cmake +COPY . /usr/local +WORKDIR /usr/local/cmake-build-debug diff --git a/Lattice/Lattice.hpp b/Lattice/Lattice.hpp new file mode 100644 index 0000000..339332c --- /dev/null +++ b/Lattice/Lattice.hpp @@ -0,0 +1,8 @@ +// +// Created by Patrick O'Brien on 9/27/18. +// + +#ifndef SIMULATION_LATTICE_HPP +#define SIMULATION_LATTICE_HPP + +#endif //SIMULATION_LATTICE_HPP diff --git a/Model/Heisenberg.cpp b/Model/Heisenberg.cpp new file mode 100644 index 0000000..f793a6e --- /dev/null +++ b/Model/Heisenberg.cpp @@ -0,0 +1,109 @@ +// +// Created by Patrick O'Brien on 9/18/18. +// + +#include "Heisenberg.hpp" + +Heisenberg::Heisenberg(int system_size) { + this->system_size = system_size; +} + +mat Heisenberg::new_spin() { + return normalise(randu(3)); +} + +mat Heisenberg::create_initial_spin_configuration() { + mat spin_configuration(this->system_size, 3); + + for (int i = 0; i < this->system_size; i++) { + mat ns = new_spin(); + for (int j = 0; j < 3; j++) { + spin_configuration(i, j) = ns(j); + } + } + + this->spin_config = spin_configuration; + return spin_configuration; +} + +mat Heisenberg::create_ferromagnetic_exchange_matrix() { + this->exchange_matrix = -ones(this->system_size, this->system_size); + return -ones(this->system_size, this->system_size); +} + +double Heisenberg::energy() { + double eng = 0.0; + + for (int i = 0; i < this->system_size; i++) { + for (int j = 0; j < this->system_size; j++) { + for (int k = 0; k < 3; k++) { + eng += this->exchange_matrix(i, j) * (this->spin_config)(i, k) * (this->spin_config)(j, k); + } + } + } + + return eng; +} + +double Heisenberg::energy_change(int ind, mat new_spin_vec) { + double del_eng = 0.0; + + for (int i = 0; i < this->system_size; i++) { + for (int k = 0; k < 3; k++) { + del_eng += 2 * this->exchange_matrix(i, ind) * (new_spin_vec(k) - (this->spin_config)(ind, k)) * + (this->spin_config)(i, k); + } + } + + for (int k = 0; k < 3; k++) { + del_eng -= 2 * this->exchange_matrix(ind, ind) * (new_spin_vec(k) - (this->spin_config)(ind, k)) * + (this->spin_config)(ind, k); + } + + return del_eng; +} + +imat Heisenberg::choose_random_index() { + return randi(1, 1, distr_param(1, this->system_size)); +} + +mat Heisenberg::old_spin() { +// return (this->spin_config)(randi(1,1, distr_param(+1, +10)), 0); + return zeros(this->system_size, 3); +} + +void Heisenberg::update_spin_configuration(uword ind, mat n_spin) { + this->spin_config.row(ind) = n_spin; +} + +std::stringstream Heisenberg::save_spin_configuration(int spin_config_number) { + std::stringstream output; + + output << "{\"step\": " << spin_config_number << ", \"data\": ["; + + for (int i = 0; i < (this->system_size) - 1; i++) { + output << "{\"spin_number\": " << i << "," << "\"x\": " << (this->spin_config)(i, 0) << "," << "\"y\": " + << (this->spin_config)(i, 1) << "," << "\"z\": " << (this->spin_config)(i, 2) << "}, "; + } + + output << "{\"spin_number\": " << (this->system_size) - 1 << "," << "\"x\": " << (this->spin_config)((this->system_size) - 1, 0) << "," << "\"y\": " + << (this->spin_config)((this->system_size) - 1, 1) << "," << "\"z\": " << (this->spin_config)((this->system_size) - 1, 2) << "}]}"; + + return output; +} + + +//mat Heisenberg::create_ferromagnetic_spin_configuration() { +// mat spin_configuration(10, 3); +// +// vec ns = new_spin(); +// +// for (int i = 0; i < 10; i++) { +// for (int j = 0; j < 3; j++) { +// spin_configuration(i, j) = ns(j); +// } +// } +// +// this->spin_config = spin_configuration; +// return spin_configuration; +//} \ No newline at end of file diff --git a/Model/Heisenberg.hpp b/Model/Heisenberg.hpp new file mode 100644 index 0000000..18a1433 --- /dev/null +++ b/Model/Heisenberg.hpp @@ -0,0 +1,27 @@ +// +// Created by Patrick O'Brien on 10/2/18. +// + +#ifndef SIMULATION_HEISENBERG_HPP +#define SIMULATION_HEISENBERG_HPP + +#include "Model.hpp" + +#endif //SIMULATION_HEISENBERG_HPP + +class Heisenberg: public Model { +public: + mat exchange_matrix; + double energy() override; + double energy_change(int ind, mat new_spin_vec) override; + imat choose_random_index() override; + mat old_spin() override; + mat new_spin() override; + mat create_initial_spin_configuration() override; + mat create_ferromagnetic_exchange_matrix(); + mat create_ferromagnetic_spin_configuration(); + void update_spin_configuration(uword ind, mat n_spin) override; + std::stringstream save_spin_configuration(int spin_config_number) override; + + explicit Heisenberg(int system_size); +}; \ No newline at end of file diff --git a/Model/Model.hpp b/Model/Model.hpp new file mode 100644 index 0000000..e855b64 --- /dev/null +++ b/Model/Model.hpp @@ -0,0 +1,22 @@ +// +// Created by Patrick O'Brien on 9/18/18. +// + +#include +#include +using namespace arma; + +#pragma once +class Model{ +public: + mat spin_config; + int system_size; + virtual double energy() = 0; + virtual double energy_change(int ind, mat new_spin_vec) =0; + virtual imat choose_random_index() =0; + virtual mat old_spin()=0; + virtual mat new_spin() =0; + virtual mat create_initial_spin_configuration()=0; + virtual void update_spin_configuration(uword ind, mat n_spin)=0; + virtual std::stringstream save_spin_configuration(int spin_config_number)=0; +}; \ No newline at end of file diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..5f81d96 --- /dev/null +++ b/main.cpp @@ -0,0 +1,31 @@ +#include +#include +#include "Model/Heisenberg.hpp" +#include "Algorithm/MonteCarlo.hpp" + +using namespace arma; + +int main() { + std::cout << "Phys-sym v. 0.0" << std::endl; + std::cout << "Simulation software" << std::endl << std::endl; + + Model *model_ptr; + Heisenberg heisenberg(10); + model_ptr = &heisenberg; + + heisenberg.create_ferromagnetic_exchange_matrix(); + model_ptr -> create_initial_spin_configuration(); + std::cout << "The spin configuration is: " << std::endl << model_ptr -> spin_config << std::endl; + std::cout << "The energy of the system is: " << model_ptr->energy() << std::endl; + + int n_itr = 10000; + Algorithm *alg; + MonteCarlo mc; + alg = &mc; + alg->simulate(n_itr, model_ptr); + + std::cout << "The spin configuration is: " << std::endl << model_ptr -> spin_config << std::endl; + std::cout << "The energy of the system is: " << model_ptr->energy() << std::endl; + + return 0; +} \ No newline at end of file