From f2d3f32b3d0d868b954554102a79fdd39275bb9a Mon Sep 17 00:00:00 2001 From: "Michael C. Heiber" Date: Mon, 7 May 2018 22:13:03 -0400 Subject: [PATCH 01/37] Reorganization Update -moved source files into new src directory --- Event.cpp => src/Event.cpp | 0 Event.h => src/Event.h | 0 Lattice.cpp => src/Lattice.cpp | 0 Lattice.h => src/Lattice.h | 0 Object.cpp => src/Object.cpp | 0 Object.h => src/Object.h | 0 Simulation.cpp => src/Simulation.cpp | 0 Simulation.h => src/Simulation.h | 0 Site.cpp => src/Site.cpp | 0 Site.h => src/Site.h | 0 Utils.cpp => src/Utils.cpp | 0 Utils.h => src/Utils.h | 0 12 files changed, 0 insertions(+), 0 deletions(-) rename Event.cpp => src/Event.cpp (100%) rename Event.h => src/Event.h (100%) rename Lattice.cpp => src/Lattice.cpp (100%) rename Lattice.h => src/Lattice.h (100%) rename Object.cpp => src/Object.cpp (100%) rename Object.h => src/Object.h (100%) rename Simulation.cpp => src/Simulation.cpp (100%) rename Simulation.h => src/Simulation.h (100%) rename Site.cpp => src/Site.cpp (100%) rename Site.h => src/Site.h (100%) rename Utils.cpp => src/Utils.cpp (100%) rename Utils.h => src/Utils.h (100%) diff --git a/Event.cpp b/src/Event.cpp similarity index 100% rename from Event.cpp rename to src/Event.cpp diff --git a/Event.h b/src/Event.h similarity index 100% rename from Event.h rename to src/Event.h diff --git a/Lattice.cpp b/src/Lattice.cpp similarity index 100% rename from Lattice.cpp rename to src/Lattice.cpp diff --git a/Lattice.h b/src/Lattice.h similarity index 100% rename from Lattice.h rename to src/Lattice.h diff --git a/Object.cpp b/src/Object.cpp similarity index 100% rename from Object.cpp rename to src/Object.cpp diff --git a/Object.h b/src/Object.h similarity index 100% rename from Object.h rename to src/Object.h diff --git a/Simulation.cpp b/src/Simulation.cpp similarity index 100% rename from Simulation.cpp rename to src/Simulation.cpp diff --git a/Simulation.h b/src/Simulation.h similarity index 100% rename from Simulation.h rename to src/Simulation.h diff --git a/Site.cpp b/src/Site.cpp similarity index 100% rename from Site.cpp rename to src/Site.cpp diff --git a/Site.h b/src/Site.h similarity index 100% rename from Site.h rename to src/Site.h diff --git a/Utils.cpp b/src/Utils.cpp similarity index 100% rename from Utils.cpp rename to src/Utils.cpp diff --git a/Utils.h b/src/Utils.h similarity index 100% rename from Utils.h rename to src/Utils.h From 539f9b0e3410c2c186fb6e9c7c81f21dab5abacb Mon Sep 17 00:00:00 2001 From: "Michael C. Heiber" Date: Mon, 7 May 2018 22:14:04 -0400 Subject: [PATCH 02/37] Testing Setup -added makefile --- makefile | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 makefile diff --git a/makefile b/makefile new file mode 100644 index 0000000..f4a09ec --- /dev/null +++ b/makefile @@ -0,0 +1,81 @@ +# Copyright (c) 2018 Michael C. Heiber +# This source file is part of the KMC_Lattice project, which is subject to the MIT License. +# For more information, see the LICENSE file that accompanies this software. +# The KMC_Lattice project can be found on Github at https://github.com/MikeHeiber/KMC_Lattice + +ifeq ($(lastword $(subst /, ,$(CXX))),g++) + FLAGS += -Wall -Wextra -O3 -std=c++11 -I. -Isrc +endif +ifeq ($(lastword $(subst /, ,$(CXX))),pgc++) + FLAGS += -O2 -fastsse -Mvect -std=c++11 -Mdalign -Munroll -Mipa=fast -Kieee -m64 -I. -Isrc +endif + +OBJS = src/Event.o src/Lattice.o src/Object.o src/Simulation.o src/Site.o src/Utils.o + +all : libKMC.a +ifndef FLAGS + $(error Valid compiler not detected.) +endif + +libKMC.a : $(OBJS) + ar rcs $@ $^ + +src/Event.o : src/Event.cpp src/Event.h src/Lattice.h src/Object.h src/Simulation.h src/Site.h src/Utils.h + mpicxx $(FLAGS) -c $< -o $@ + +src/Lattice.o : src/Lattice.cpp src/Lattice.h src/Site.h src/Utils.h + mpicxx $(FLAGS) -c $< -o $@ + +src/Object.o : src/Object.cpp src/Object.h src/Utils.h + mpicxx $(FLAGS) -c $< -o $@ + +src/Simulation.o : src/Simulation.cpp src/Simulation.h src/Event.h src/Lattice.h src/Object.h src/Site.h src/Utils.h + mpicxx $(FLAGS) -c $< -o $@ + +src/Site.o : src/Site.cpp KMC_Lattice/Site.h + mpicxx $(FLAGS) -c $< -o $@ + +src/Utils.o : KMC_Lattice/Utils.cpp KMC_Lattice/Utils.h + mpicxx $(FLAGS) -c $< -o $@ + +# +# Testing Section using googletest +# + +ifndef FLAGS + $(error Valid compiler not detected.) +endif +GTEST_DIR = googletest/googletest +GTEST_HEADERS = $(GTEST_DIR)/include/gtest/*.h \ + $(GTEST_DIR)/include/gtest/internal/*.h +GTEST_SRCS_ = $(GTEST_DIR)/src/*.cc $(GTEST_DIR)/src/*.h $(GTEST_HEADERS) +ifeq ($(lastword $(subst /, ,$(CXX))),g++) + GTEST_FLAGS = -isystem $(GTEST_DIR)/include -pthread +endif +ifeq ($(lastword $(subst /, ,$(CXX))),pgc++) + GTEST_FLAGS = -I$(GTEST_DIR)/include +endif + +test : FLAGS = -fprofile-arcs -ftest-coverage -std=c++11 -Wall -Wextra -I. -Isrc +test : test/KMC_Lattice_tests.exe + +test/KMC_Lattice_tests.exe : test/test.o test/gtest-all.o $(OBJS) + mpicxx $(GTEST_FLAGS) $(FLAGS) -lpthread $^ -o $@ + +test/gtest-all.o : $(GTEST_SRCS_) + mpicxx $(GTEST_FLAGS) -I$(GTEST_DIR) $(FLAGS) -c $(GTEST_DIR)/src/gtest-all.cc -o $@ + +test/test.o : test/test.cpp $(GTEST_HEADERS) $(OBJS) + mpicxx $(GTEST_FLAGS) $(FLAGS) -c $< -o $@ + +test_mpi : FLAGS = -fprofile-arcs -ftest-coverage -std=c++11 -Wall -Wextra -I. -Isrc +test_mpi : test/KMC_Lattice_MPI_tests.exe + +test/Excimontec_MPI_tests.exe : test/test_mpi.o test/gtest-all.o $(OBJS) + mpicxx $(GTEST_FLAGS) $(FLAGS) -lpthread $^ -o $@ + +test/test_mpi.o : test/test_mpi.cpp $(GTEST_HEADERS) $(OBJS) + mpicxx $(GTEST_FLAGS) $(FLAGS) -c $< -o $@ + +clean: + -rm src/*.o src/*.gcno* src/*.gcda KMC_Lattice/*.o KMC_Lattice/*.gcno* KMC_Lattice/*.gcda testing/*.o testing/*.gcno* testing/*.gcda *~ Excimontec.exe testing/*.o testing/Excimontec_tests.exe testing/Excimontec_mpi_tests.exe From 3d6e5fb2a0f9a6e8ae00101dc7b165e064cb67f0 Mon Sep 17 00:00:00 2001 From: "Michael C. Heiber" Date: Mon, 7 May 2018 22:14:31 -0400 Subject: [PATCH 03/37] Travis CI Setup -added initial travis yml file --- .travis.yml | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..03f4a5f --- /dev/null +++ b/.travis.yml @@ -0,0 +1,46 @@ +# Copyright (c) 2018 Michael C. Heiber +# This source file is part of the KMC_Lattice project, which is subject to the MIT License. +# For more information, see the LICENSE file that accompanies this software. +# The KMC_Lattice project can be found on Github at https://github.com/MikeHeiber/KMC_Lattice +# Travis CI continuous integration build script + +language: cpp +os: linux +dist: trusty +sudo: required + +compiler: + - gcc + +env: + - COMPILER_OPTIONS="VERSION=4.7 && MPI=mpich2" + - COMPILER_OPTIONS="VERSION=4.7 && MPI=openmpi" + - COMPILER_OPTIONS="VERSION=4.8 && MPI=mpich2" + - COMPILER_OPTIONS="VERSION=4.8 && MPI=openmpi" + - COMPILER_OPTIONS="VERSION=4.9 && MPI=mpich2" + - COMPILER_OPTIONS="VERSION=4.9 && MPI=openmpi" + - COMPILER_OPTIONS="VERSION=5 && MPI=mpich2" + - COMPILER_OPTIONS="VERSION=5 && MPI=openmpi" + - COMPILER_OPTIONS="VERSION=6 && MPI=mpich2" + - COMPILER_OPTIONS="VERSION=6 && MPI=openmpi" + - COMPILER_OPTIONS="VERSION=7 && MPI=mpich2" + - COMPILER_OPTIONS="VERSION=7 && MPI=openmpi" + - COMPILER_OPTIONS="VERSION=8 && MPI=mpich2" + - COMPILER_OPTIONS="VERSION=8 && MPI=openmpi" + +before_install: + - eval "${COMPILER_OPTIONS}" + - sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y + - sudo apt-get update -qq + - sudo apt-get install -qq gcc-$VERSION g++-$VERSION -y + - sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-$VERSION 60 --slave /usr/bin/g++ g++ /usr/bin/g++-$VERSION + - sudo update-alternatives --config gcc + - gcc --version + - if [[ "$MPI" = mpich2 ]]; then sudo apt-get -y install -qq mpich2 libmpich2-dev; fi + - if [[ "$MPI" = openmpi ]]; then sudo apt-get -y install -qq openmpi-bin libopenmpi-dev; fi + - pip install --user cpp-coveralls + +script: + - make -j10 test && travis_wait ./test/KMC_Lattice_tests.exe + - make -j10 test_mpi && travis_wait mpiexec -n 4 ./test/KMC_Lattice_MPI_tests.exe + - coveralls --include src --exclude "googletest/*" --gcov-options '\-lp' From bb3b167c874f9920d2b71f3aaab9e0346a7e4754 Mon Sep 17 00:00:00 2001 From: "Michael C. Heiber" Date: Mon, 7 May 2018 22:16:22 -0400 Subject: [PATCH 04/37] Added googletest Submodule --- .gitmodules | 3 +++ googletest | 1 + 2 files changed, 4 insertions(+) create mode 100644 .gitmodules create mode 160000 googletest diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..7e38e13 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "googletest"] + path = googletest + url = https://github.com/google/googletest diff --git a/googletest b/googletest new file mode 160000 index 0000000..045e7f9 --- /dev/null +++ b/googletest @@ -0,0 +1 @@ +Subproject commit 045e7f9ee4f969ac1a3fe428f79c4b880f0aff43 From 8095a27c2d82ac7d0542b0472544597176d19426 Mon Sep 17 00:00:00 2001 From: "Michael C. Heiber" Date: Mon, 7 May 2018 22:49:58 -0400 Subject: [PATCH 05/37] Makefile Update -corrected a few path bugs in the makefile --- makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/makefile b/makefile index f4a09ec..350874a 100644 --- a/makefile +++ b/makefile @@ -32,10 +32,10 @@ src/Object.o : src/Object.cpp src/Object.h src/Utils.h src/Simulation.o : src/Simulation.cpp src/Simulation.h src/Event.h src/Lattice.h src/Object.h src/Site.h src/Utils.h mpicxx $(FLAGS) -c $< -o $@ -src/Site.o : src/Site.cpp KMC_Lattice/Site.h +src/Site.o : src/Site.cpp src/Site.h mpicxx $(FLAGS) -c $< -o $@ -src/Utils.o : KMC_Lattice/Utils.cpp KMC_Lattice/Utils.h +src/Utils.o : src/Utils.cpp src/Utils.h mpicxx $(FLAGS) -c $< -o $@ # From 39afd25c73efdb5cc7d37fd96065e39655e6598c Mon Sep 17 00:00:00 2001 From: "Michael C. Heiber" Date: Mon, 7 May 2018 22:55:55 -0400 Subject: [PATCH 06/37] Update Makefile -corrected bug in makefile test target name --- makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/makefile b/makefile index 350874a..18c810d 100644 --- a/makefile +++ b/makefile @@ -71,7 +71,7 @@ test/test.o : test/test.cpp $(GTEST_HEADERS) $(OBJS) test_mpi : FLAGS = -fprofile-arcs -ftest-coverage -std=c++11 -Wall -Wextra -I. -Isrc test_mpi : test/KMC_Lattice_MPI_tests.exe -test/Excimontec_MPI_tests.exe : test/test_mpi.o test/gtest-all.o $(OBJS) +test/KMC_Lattice_MPI_tests.exe : test/test_mpi.o test/gtest-all.o $(OBJS) mpicxx $(GTEST_FLAGS) $(FLAGS) -lpthread $^ -o $@ test/test_mpi.o : test/test_mpi.cpp $(GTEST_HEADERS) $(OBJS) From 8fa2dd6dad400074a6bcb1e8b53570536c6cae72 Mon Sep 17 00:00:00 2001 From: "Michael C. Heiber" Date: Mon, 7 May 2018 22:56:17 -0400 Subject: [PATCH 07/37] Testing Update -added test cpp files for unit testing --- test/test.cpp | 500 ++++++++++++++++++++++++++++++++++++++++++++++ test/test_mpi.cpp | 100 ++++++++++ 2 files changed, 600 insertions(+) create mode 100644 test/test.cpp create mode 100644 test/test_mpi.cpp diff --git a/test/test.cpp b/test/test.cpp new file mode 100644 index 0000000..6b5f2a1 --- /dev/null +++ b/test/test.cpp @@ -0,0 +1,500 @@ +// Copyright (c) 2018 Michael C. Heiber +// This source file is part of the KMC_Lattice project, which is subject to the MIT License. +// For more information, see the LICENSE file that accompanies this software. +// The KMC_Lattice project can be found on Github at https://github.com/MikeHeiber/KMC_Lattice + +#include "gtest/gtest.h" +#include "Simulation.h" +#include "Utils.h" + + +using namespace std; +using namespace Utils; + +// Simple derived Simulation class +class TestSim : public Simulation { +public: + bool checkFinished() const { return false; }; + bool executeNextEvent() { return false; }; +}; + +namespace UtilsTests { + + TEST(UtilsTests, CoordsTests) { + Coords coords{ 1, 1, 1 }; + EXPECT_EQ(1, coords.x); + EXPECT_EQ(1, coords.y); + EXPECT_EQ(1, coords.z); + Coords coords2{ 0, 5, 10 }; + EXPECT_TRUE(coords != coords2); + coords2.setXYZ(1, 1, 1); + EXPECT_TRUE(coords == coords2); + } + + TEST(UtilsTests, CalculateProbabilityHistTests) { + mt19937 gen(std::random_device{}()); + uniform_real_distribution<> dist(0, 100); + vector data((int)1e7); + for (int i = 0; i < (int)data.size(); i++) { + data[i] = dist(gen); + } + auto hist = calculateProbabilityHist(data, 10); + uniform_int_distribution<> dist2(0, 9); + EXPECT_EQ(10, (int)hist.size()); + EXPECT_NEAR(1.0 / 100.0, hist[dist2(gen)].second,1e-4); + EXPECT_NEAR(1.0 / 100.0, hist[dist2(gen)].second, 1e-4); + EXPECT_NEAR(1.0 / 100.0, hist[dist2(gen)].second, 1e-4); + hist = calculateProbabilityHist(data, 10.0); + EXPECT_EQ(10, (int)hist.size()); + EXPECT_NEAR(1.0 / 100.0, hist[dist2(gen)].second, 1e-4); + EXPECT_NEAR(1.0 / 100.0, hist[dist2(gen)].second, 1e-4); + EXPECT_NEAR(1.0 / 100.0, hist[dist2(gen)].second, 1e-4); + } + + TEST(UtilsTests, ExponentialDOSTests) { + mt19937 gen(std::random_device{}()); + vector data((int)2e7, 0.0); + createExponentialDOSVector(data, 0.0, 0.1, gen); + auto hist = calculateProbabilityHist(data, 1000); + EXPECT_NEAR(1.0, integrateData(hist), 1e-4); + vector prob; + for_each(hist.begin(), hist.end(), [&prob](pair& x_y) {prob.push_back(x_y.second); }); + double peak = *max_element(prob.begin(), prob.end()); + EXPECT_NEAR(0.5*(1.0 / 0.1), peak, 1e-2*peak); + createExponentialDOSVector(data, 0.0, 0.05, gen); + hist = calculateProbabilityHist(data, 1000); + EXPECT_NEAR(1.0, integrateData(hist), 1e-4); + prob.clear(); + for_each(hist.begin(), hist.end(), [&prob](pair& x_y) {prob.push_back(x_y.second); }); + peak = *max_element(prob.begin(), prob.end()); + EXPECT_NEAR(0.5*(1.0 / 0.05), peak, 1e-2*peak); + } + + TEST(UtilsTests, GaussianDOSTests) { + mt19937 gen(std::random_device{}()); + vector data((int)3e7, 0.0); + createGaussianDOSVector(data, 0.0, 0.15, gen); + EXPECT_NEAR(0.0, vector_avg(data), 1e-4); + EXPECT_NEAR(0.15, vector_stdev(data), 1e-4); + auto hist = calculateProbabilityHist(data, 1000); + EXPECT_NEAR(1.0, integrateData(hist), 1e-4); + double peak = hist[499].second; + EXPECT_NEAR(1.0 / sqrt(2.0*Pi*intpow(0.15, 2)), peak, 1e-1*peak); + createGaussianDOSVector(data, 0.0, 0.05, gen); + EXPECT_NEAR(0.0, vector_avg(data), 1e-4); + EXPECT_NEAR(0.05, vector_stdev(data), 1e-4); + hist = calculateProbabilityHist(data, 0.005); + EXPECT_NEAR(1.0, integrateData(hist), 1e-4); + vector prob; + for_each(hist.begin(), hist.end(), [&prob](pair& x_y) {prob.push_back(x_y.second); }); + peak = *max_element(prob.begin(), prob.end()); + EXPECT_NEAR(1.0 / sqrt(2.0*Pi*intpow(0.05, 2)), peak, 1e-1*peak); + } + + TEST(UtilsTests, ImportBooleanTests) { + bool error_status; + EXPECT_TRUE(importBooleanParam("true", error_status)); + EXPECT_TRUE(importBooleanParam(" true ", error_status)); + EXPECT_FALSE(importBooleanParam("false ", error_status)); + EXPECT_FALSE(importBooleanParam(" false", error_status)); + EXPECT_FALSE(importBooleanParam("blah", error_status)); + EXPECT_FALSE(importBooleanParam(" blah ", error_status)); + EXPECT_TRUE(error_status); + } + + TEST(UtilsTests, IntegrateDataTests) { + vector> data_vec = { {0.0,0.0},{1.0,1.0},{2.0,2.0},{3.0,3.0} }; + auto area = integrateData(data_vec); + EXPECT_DOUBLE_EQ(area, 9.0 / 2.0); + } + + TEST(UtilsTests, InterpolateDataTests) { + vector> data_vec(100); + for (int i = 0; i < (int)data_vec.size();i++) { + data_vec[i].first = 0.1*i; + data_vec[i].second = exp(-data_vec[i].first/2.85); + } + EXPECT_NEAR(1 / exp(1), interpolateData(data_vec, 2.85), 1e-4); + for (int i = 0; i < (int)data_vec.size(); i++) { + data_vec[i].first = 0.2*i; + data_vec[i].second = 2.5*data_vec[i].first - 5.0; + } + EXPECT_NEAR(3.25, interpolateData(data_vec, 3.3), 1e-4); + } + + TEST(UtilsTests, RemoveWhitespaceTests) { + string str = " text "; + EXPECT_EQ(removeWhitespace(str), "text"); + str = " text "; + EXPECT_EQ(removeWhitespace(str), "text"); + str = " text "; + EXPECT_EQ(removeWhitespace(str), "text"); + } + + TEST(UtilsTests, ArrayStatsTests) { + // positive ints + int int_data[10]; + for (int i = 0; i < 10; i++) { + int_data[i] = i + 1; + } + EXPECT_DOUBLE_EQ(5.5, array_avg(int_data, 10)); + EXPECT_NEAR(3.02765035409749, array_stdev(int_data, 10), 1e-14); + // negative ints + for (int i = 0; i < 10; i++) { + int_data[i] = -(i + 1); + } + EXPECT_DOUBLE_EQ(-5.5, array_avg(int_data, 10)); + EXPECT_NEAR(3.02765035409749, array_stdev(int_data, 10), 1e-14); + // positive doubles + double double_data[10]; + for (int i = 0; i < 10; i++) { + double_data[i] = 0.5*(i + 1); + } + EXPECT_DOUBLE_EQ(2.75, array_avg(double_data, 10)); + EXPECT_NEAR(1.51382517704875, array_stdev(double_data, 10), 1e-14); + // negative doubles + for (int i = 0; i < 10; i++) { + double_data[i] = -0.5*(i + 1); + } + EXPECT_DOUBLE_EQ(-2.75, array_avg(double_data, 10)); + EXPECT_NEAR(1.51382517704875, array_stdev(double_data, 10), 1e-14); + } + + TEST(UtilsTests, IntPowTests) { + EXPECT_DOUBLE_EQ(1.0, intpow(2.5, 0)); + EXPECT_DOUBLE_EQ(2.5, intpow(2.5, 1)); + EXPECT_DOUBLE_EQ(6.25, intpow(2.5, 2)); + EXPECT_DOUBLE_EQ(9536.7431640625, intpow(2.5, 10)); + EXPECT_DOUBLE_EQ(0.4, intpow(2.5, -1)); + EXPECT_DOUBLE_EQ(0.16, intpow(2.5, -2)); + EXPECT_DOUBLE_EQ(1.048576e-4, intpow(2.5, -10)); + EXPECT_DOUBLE_EQ(1.0, intpow(15.04564, 0)); + EXPECT_DOUBLE_EQ(1e-21, intpow(1e-7, 3)); + } + + TEST(UtilsTests, RemoveDuplicatesTests) { + vector vec{ 0, 1, 1, 2, 3, 1, 4, 2 }; + removeDuplicates(vec); + EXPECT_EQ(2, vec[2]); + EXPECT_EQ(5, (int)vec.size()); + vec = { 0, 1, 2, 1 }; + removeDuplicates(vec); + EXPECT_EQ(2, vec[2]); + EXPECT_EQ(3, (int)vec.size()); + vector vec2{ 0.0, 1.0, 1.0, 2.0, 3.0, 1.0, 4.0, 2.0 }; + removeDuplicates(vec2); + EXPECT_DOUBLE_EQ(2.0, vec2[2]); + EXPECT_EQ(5, (int)vec2.size()); + Coords coords1{ 1,2,3 }; + Coords coords2{ 1,2,3 }; + Coords coords3{ 4,5,6 }; + vector vec3{ coords1, coords1, coords2, coords3, coords1, coords3, coords2 }; + removeDuplicates(vec3); + EXPECT_EQ(4, vec3[1].x); + EXPECT_EQ(2, (int)vec3.size()); + Object object1(0, 1, { 0,0,0 }); + Object object2(0, 2, { 1,1,1 }); + vector object_ptrs{ &object1, &object1, &object2, &object1, &object2 }; + removeDuplicates(object_ptrs); + EXPECT_EQ(2, (int)object_ptrs.size()); + vector vec4 = {}; + removeDuplicates(vec4); + EXPECT_EQ(0, (int)vec4.size()); + vector vec5 = { 0 }; + removeDuplicates(vec5); + EXPECT_EQ(1, (int)vec5.size()); + vector vec6 = { 0,0 }; + removeDuplicates(vec6); + EXPECT_EQ(1, (int)vec6.size()); + } + + TEST(UtilsTests, VectorStatsTests) { + // positive ints + vector int_data; + int_data.assign(10, 0); + for (int i = 0; i < 10; i++) { + int_data[i] = i + 1; + } + EXPECT_DOUBLE_EQ(5.5, vector_avg(int_data)); + EXPECT_NEAR(3.02765035409749, vector_stdev(int_data), 1e-14); + // negative ints + for (int i = 0; i < 10; i++) { + int_data[i] = -(i + 1); + } + EXPECT_DOUBLE_EQ(-5.5, vector_avg(int_data)); + EXPECT_NEAR(3.02765035409749, vector_stdev(int_data), 1e-14); + // positive doubles + vector double_data; + double_data.assign(10, 0); + for (int i = 0; i < 10; i++) { + double_data[i] = 0.5*(i + 1); + } + EXPECT_DOUBLE_EQ(2.75, vector_avg(double_data)); + EXPECT_NEAR(1.51382517704875, vector_stdev(double_data), 1e-14); + // negative doubles + double_data.assign(10, 0); + for (int i = 0; i < 10; i++) { + double_data[i] = -0.5*(i + 1); + } + EXPECT_DOUBLE_EQ(-2.75, vector_avg(double_data)); + EXPECT_NEAR(1.51382517704875, vector_stdev(double_data), 1e-14); + } +} + +namespace LatticeTests{ + + class LatticeTest : public ::testing::Test { + protected: + mt19937 gen; + Parameters_Lattice params_lattice; + vector sites; + Lattice lattice; + + void SetUp() { + gen.seed(std::random_device{}()); + // Setup params + params_lattice.Enable_periodic_x = true; + params_lattice.Enable_periodic_y = true; + params_lattice.Enable_periodic_z = true; + params_lattice.Length = 50; + params_lattice.Width = 50; + params_lattice.Height = 50; + params_lattice.Unit_size = 1.0; + // Initialize Lattice object + lattice.init(params_lattice, &gen); + Site site; + sites.assign(lattice.getNumSites(), site); + vector site_ptrs((int)sites.size()); + for (int i = 0; i < (int)sites.size(); i++) { + site_ptrs[i] = &sites[i]; + } + lattice.setSitePointers(site_ptrs); + } + }; + + TEST_F(LatticeTest, InitializationTests) { + EXPECT_EQ(50, lattice.getLength()); + EXPECT_EQ(50, lattice.getWidth()); + EXPECT_EQ(50, lattice.getHeight()); + EXPECT_DOUBLE_EQ(1.0, lattice.getUnitSize()); + EXPECT_EQ((long int)50 * 50 * 50, lattice.getNumSites()); + } + + TEST_F(LatticeTest, CalculateDestCoordsTests) { + Coords coords_i{ 49, 49, 49 }; + Coords coords_f; + lattice.calculateDestinationCoords(coords_i, 2, -2, 0, coords_f); + EXPECT_EQ(1, coords_f.x); + EXPECT_EQ(47, coords_f.y); + EXPECT_EQ(49, coords_f.z); + coords_i.setXYZ(0, 0, 49); + lattice.calculateDestinationCoords(coords_i, 1, -2, 2, coords_f); + EXPECT_EQ(1, coords_f.x); + EXPECT_EQ(48, coords_f.y); + EXPECT_EQ(1, coords_f.z); + } + + TEST_F(LatticeTest, PeriodicCrossingTests) { + Coords coords_i{ 49, 49, 49 }; + Coords coords_f{ 0, 49, 48 }; + EXPECT_EQ(lattice.calculateDX(coords_i, coords_f), -50); + EXPECT_EQ(lattice.calculateDY(coords_i, coords_f), 0); + EXPECT_EQ(lattice.calculateDZ(coords_i, coords_f), 0); + coords_i.setXYZ(0, 0, 49); + coords_f.setXYZ(1, 49, 0); + EXPECT_EQ(lattice.calculateDX(coords_i, coords_f), 0); + EXPECT_EQ(lattice.calculateDY(coords_i, coords_f), 50); + EXPECT_EQ(lattice.calculateDZ(coords_i, coords_f), -50); + coords_i.setXYZ(4, 5, 6); + coords_f.setXYZ(3, 6, 5); + EXPECT_EQ(lattice.calculateDX(coords_i, coords_f), 0); + EXPECT_EQ(lattice.calculateDY(coords_i, coords_f), 0); + EXPECT_EQ(lattice.calculateDZ(coords_i, coords_f), 0); + } + + TEST_F(LatticeTest, CheckMoveValidityTests) { + params_lattice.Enable_periodic_x = false; + params_lattice.Enable_periodic_y = false; + params_lattice.Enable_periodic_z = true; + Lattice lattice2; + lattice2.init(params_lattice, &gen); + Coords coords1{ 49, 0, 49 }; + EXPECT_FALSE(lattice2.checkMoveValidity(coords1, 1, 0, 0)); + EXPECT_FALSE(lattice2.checkMoveValidity(coords1, 0, -1, 0)); + EXPECT_TRUE(lattice2.checkMoveValidity(coords1, 0, 0, 1)); + EXPECT_TRUE(lattice2.checkMoveValidity(coords1, -1, 1, -1)); + } + + TEST_F(LatticeTest, RandomSiteGenTests) { + Coords coords; + int N_test = 40000000; + vector xcoords(N_test); + vector ycoords(N_test); + vector zcoords(N_test); + for (int i = 0; i < N_test; i++) { + coords = lattice.generateRandomCoords(); + EXPECT_TRUE(coords.x >= 0 && coords.x < lattice.getLength()); + EXPECT_TRUE(coords.y >= 0 && coords.y < lattice.getWidth()); + EXPECT_TRUE(coords.z >= 0 && coords.z < lattice.getHeight()); + xcoords[i] = coords.x; + ycoords[i] = coords.y; + zcoords[i] = coords.z; + } + EXPECT_NEAR(24.5, vector_avg(xcoords), 2e-2); + EXPECT_NEAR(lattice.getLength() / sqrt(12.0), vector_stdev(xcoords), 1e-2); + EXPECT_NEAR(24.5, vector_avg(ycoords), 2e-2); + EXPECT_NEAR(lattice.getWidth() / sqrt(12.0), vector_stdev(ycoords), 1e-2); + EXPECT_NEAR(24.5, vector_avg(zcoords), 2e-2); + EXPECT_NEAR(lattice.getHeight() / sqrt(12.0), vector_stdev(zcoords), 1e-2); + } + + TEST_F(LatticeTest, LatticeDistanceTests) { + Coords coords_i{ 49, 49, 49 }; + Coords coords_f{ 1, 49, 47 }; + EXPECT_EQ(8, lattice.calculateLatticeDistanceSquared(coords_i, coords_f)); + coords_i.setXYZ(4, 5, 6); + coords_f.setXYZ(3, 6, 5); + EXPECT_EQ(3, lattice.calculateLatticeDistanceSquared(coords_i, coords_f)); + coords_i.setXYZ(0, 49, 1); + coords_f.setXYZ(48, 1, 49); + EXPECT_EQ(12, lattice.calculateLatticeDistanceSquared(coords_i, coords_f)); + } + + TEST_F(LatticeTest, GetSiteCoordsTests) { + Coords coords1, coords2; + int index; + for (int i = 0; i < 100; i++) { + coords1 = lattice.generateRandomCoords(); + index = lattice.getSiteIndex(coords1); + coords2 = lattice.getSiteCoords(index); + EXPECT_EQ(coords1.x, coords2.x); + EXPECT_EQ(coords1.y, coords2.y); + EXPECT_EQ(coords1.z, coords2.z); + } + } + + TEST_F(LatticeTest, OccupancyTests) { + Coords coords; + for (int x = 0; x < lattice.getLength(); x++) { + for (int y = 0; y < lattice.getWidth(); y++) { + for (int z = 0; z < lattice.getHeight(); z++) { + coords.setXYZ(x, y, z); + EXPECT_FALSE(lattice.isOccupied(coords)); + } + } + } + coords.setXYZ(5, 5, 5); + lattice.setOccupied(coords); + EXPECT_TRUE(lattice.isOccupied(coords)); + for (int x = 0; x < lattice.getLength(); x++) { + for (int y = 0; y < lattice.getWidth(); y++) { + for (int z = 0; z < lattice.getHeight(); z++) { + if (lattice.isOccupied(coords)) { + EXPECT_EQ(5, coords.x); + EXPECT_EQ(5, coords.y); + EXPECT_EQ(5, coords.z); + } + } + } + } + lattice.clearOccupancy(coords); + EXPECT_FALSE(lattice.isOccupied(coords)); + } + + TEST_F(LatticeTest, SetSitePointersTests) { + Site site; + vector site_ptrs(10, &site); + EXPECT_FALSE(lattice.setSitePointers(site_ptrs)); + site_ptrs.assign(50 * 50 * 50, &site); + EXPECT_TRUE(lattice.setSitePointers(site_ptrs)); + } +} + +namespace EventTests { + + class EventTest : public ::testing::Test { + protected: + Parameters_Simulation params_base; + TestSim test_sim; + void setUp(){ + { + params_base.Enable_logging = false; + params_base.Enable_periodic_x = true; + params_base.Enable_periodic_y = true; + params_base.Enable_periodic_z = true; + params_base.Length = 50; + params_base.Width = 50; + params_base.Height = 50; + params_base.Unit_size = 1.0; + params_base.Temperature = 300; + params_base.Enable_FRM = false; + params_base.Enable_selective_recalc = true; + params_base.Recalc_cutoff = 3; + params_base.Enable_full_recalc = false; + } + // Initialize TestSim object + test_sim.init(params_base, 0); + } + }; + + TEST_F(EventTest, CalculateExecutionTimeTests) { + Event event(&test_sim); + // Generate collection of wait times + vector times((int)3e7); + for (int i = 0; i < (int)times.size(); i++) { + event.calculateExecutionTime(1e9); + times[i] = event.getExecutionTime(); + } + // Calculate probability distribution of calculated times + auto hist = calculateProbabilityHist(times, 1000); + // Test probability distribution + EXPECT_NEAR(1.0, integrateData(hist), 2e-2); + EXPECT_NEAR(1e9, hist[0].second, 2e7); + auto it = find_if(hist.begin(), hist.end(), [](pair& x_y) {return x_y.first > 1e-9; }); + it--; + EXPECT_NEAR(1e9 / 2.7182818284590, (*it).second, 2e7); + // Test average wait time + EXPECT_NEAR(vector_avg(times), 1e-9, 2e-12); + // Generate collection of wait times + for (int i = 0; i < (int)times.size(); i++) { + event.calculateExecutionTime(1e12); + times[i] = event.getExecutionTime(); + } + // Calculate probability distribution of calculated times + hist = calculateProbabilityHist(times, 1000); + // Test probability distribution + EXPECT_NEAR(1.0, integrateData(hist), 2e-2); + EXPECT_NEAR(1e12, hist[0].second, 2e10); + it = find_if(hist.begin(), hist.end(), [](pair& x_y) {return x_y.first > 1e-12; }); + it--; + EXPECT_NEAR(1e12 / 2.7182818284590, (*it).second, 2e10); + // Test average wait time + EXPECT_NEAR(vector_avg(times), 1e-12, 2e-15); + } +} + +namespace ObjectTests { + + TEST(ObjectTests, CalculateDisplacementTests) { + // Assume object is created in a 50 x 50 x 50 lattice + Object object1(0, 1, { 0,0,0 }); + object1.setCoords({ 0,0,5 }); + EXPECT_DOUBLE_EQ(5.0, object1.calculateDisplacement()); + object1.setCoords({ 0,0,49 }); + object1.incrementDZ(-50); + EXPECT_DOUBLE_EQ(1.0, object1.calculateDisplacement()); + object1.setCoords({ 49,49,49 }); + object1.incrementDX(-50); + object1.incrementDY(-50); + EXPECT_DOUBLE_EQ(sqrt(3), object1.calculateDisplacement()); + object1.setCoords({ 49,0,49 }); + object1.incrementDY(50); + EXPECT_DOUBLE_EQ(sqrt(2), object1.calculateDisplacement()); + } +} + + +int main(int argc, char **argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/test_mpi.cpp b/test/test_mpi.cpp new file mode 100644 index 0000000..971c5d4 --- /dev/null +++ b/test/test_mpi.cpp @@ -0,0 +1,100 @@ +// Copyright (c) 2018 Michael C. Heiber +// This source file is part of the KMC_Lattice project, which is subject to the MIT License. +// For more information, see the LICENSE file that accompanies this software. +// The KMC_Lattice project can be found on Github at https://github.com/MikeHeiber/KMC_Lattice + +#include "gtest/gtest.h" +#include "Utils.h" +#include + +using namespace std; +using namespace Utils; + +namespace MPI_Tests { + + class MPI_Test : public ::testing::Test { + protected: + int procid; + int nproc; + void SetUp() { + MPI_Comm_size(MPI_COMM_WORLD, &nproc); + MPI_Comm_rank(MPI_COMM_WORLD, &procid); + } + }; + + TEST_F(MPI_Test, CalculateVectorAvgTests) { + // Seteup unique data vectors on each proc + vector data(3); + for (int i = 0; i < (int)data.size(); i++) { + data[i] = 3 * procid + i; + } + vector data_avg = MPI_calculateVectorAvg(data); + if (procid == 0) { + EXPECT_EQ(3, (int)data_avg.size()); + EXPECT_DOUBLE_EQ(4.5, data_avg[0]); + EXPECT_DOUBLE_EQ(5.5, data_avg[1]); + EXPECT_DOUBLE_EQ(6.5, data_avg[2]); + } + } + + TEST_F(MPI_Test, CalculateVectorSumTests) { + // Seteup unique data vectors on each proc + vector data(3); + for (int i = 0; i < (int)data.size(); i++) { + data[i] = 3 * procid + i; + } + vector data_sum = MPI_calculateVectorSum(data); + if (procid == 0) { + EXPECT_EQ(3, (int)data_sum.size()); + EXPECT_DOUBLE_EQ(18.0, data_sum[0]); + EXPECT_DOUBLE_EQ(22.0, data_sum[1]); + EXPECT_DOUBLE_EQ(26.0, data_sum[2]); + } + vector data2(3); + for (int i = 0; i < (int)data2.size(); i++) { + data2[i] = 3 * procid + i; + } + vector data_sum2 = MPI_calculateVectorSum(data2); + if (procid == 0) { + EXPECT_EQ(3, (int)data_sum2.size()); + EXPECT_EQ(18, data_sum2[0]); + EXPECT_EQ(22, data_sum2[1]); + EXPECT_EQ(26, data_sum2[2]); + } + } + + TEST_F(MPI_Test, GatherVectorsTests) { + // Seteup unique data vectors on each proc + vector data(3); + for (int i = 0; i < (int)data.size(); i++) { + data[i] = 3 * procid + i; + } + vector data_all = MPI_gatherVectors(data); + if (procid == 0) { + EXPECT_EQ(12, (int)data_all.size()); + for (int i = 0; i < 3 * nproc; i++) { + EXPECT_DOUBLE_EQ((double)i, data_all[i]); + } + } + vector data2(3); + for (int i = 0; i < (int)data2.size(); i++) { + data2[i] = 3 * procid + i; + } + vector data_all2 = MPI_gatherVectors(data2); + if (procid == 0) { + EXPECT_EQ(12, (int)data_all2.size()); + for (int i = 0; i < 3 * nproc; i++) { + EXPECT_EQ(i, data_all2[i]); + } + } + } +} + +int main(int argc, char **argv) { + int result = 0; + ::testing::InitGoogleTest(&argc, argv); + MPI_Init(&argc, &argv); + result = RUN_ALL_TESTS(); + MPI_Finalize(); + return result; +} From 7381ce4667e7183811fe5b4923d127f63ae8137c Mon Sep 17 00:00:00 2001 From: "Michael C. Heiber" Date: Mon, 7 May 2018 22:56:53 -0400 Subject: [PATCH 08/37] Readme Update -added new readme content with CI and testing information and badges --- README.md | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 53 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 4f33573..f17fef4 100644 --- a/README.md +++ b/README.md @@ -3,18 +3,67 @@ ## General Information This object-oriented C++ software package contains a general framework for lattice kinetic Monte Carlo (KMC) simulations. This framework consists of a number of utility functions and base classes that must be extended to create a fully operational KMC simulation. -The goal of this package is to be robust and flexible so that users can easily develop KMC simulations for a wide variety of different scientific problems without the need to start from scratch. +The goal of this package is to be robust, reliable, and flexible so that users can easily develop KMC simulations for a wide variety of different scientific problems without the need to start from scratch. This KMC_Lattice package implements several event recalculation options for creating computationally efficient simulations. The package is designed to be usable on a personal computer and on high performance computing clusters. -A simple example implementation of this general KMC framework can be found in the [KMC_Lattice_example](https://github.com/MikeHeiber/KMC_Lattice_example) package. -To see a more complete implementation for simulating a complex system, check out the [Excimontec](https://github.com/MikeHeiber/Excimontec) software package that is used for simulating organic semiconductor materials and devices. +Check out the [Excimontec](https://github.com/MikeHeiber/Excimontec) software package for an example of a complex tool constructed using KMC_Lattice, which is used for simulating organic semiconductor materials and devices. For further reading about kinetic Monte Carlo simulations, a nice overview of the theory and algorithm can be found here: [Introduction to the Kinetic Monte Carlo Method by Arthur Voter, Los Alamos National Lab](http://www.fml.t.u-tokyo.ac.jp/~izumi/CMS/MC/Introduction_kMC.pdf) -## Work Together +## Current Status + +The current release is KMC_Lattice [![GitHub (pre-)release](https://img.shields.io/github/release/MikeHeiber/KMC_Lattice/all.svg?style=flat-square)](https://github.com/MikeHeiber/KMC_Lattice/releases) +Most major planned features that are to be included in v2.0 are now implemented and have undergone preliminary testing. +However, this software tool is still under development, and as such, there may still be bugs that need to be squashed. +Please report any bugs or submit feature requests in the [Issues](https://github.com/MikeHeiber/KMC_Lattice/issues) section. + +#### Continuous Integration and Testing Status: + +KMC_Lattice is currently being tested on [Ubuntu](https://www.ubuntu.com/) v14.04 with the [GCC compiler](https://gcc.gnu.org/) (versions 4.7, 4.8, 4.9, 5, 6, 7, and 8) and on both [Open MPI](http://www.open-mpi.org/) v1.6.5 and [MPICH](http://www.mpich.org/) v3.04 using [Travis CI](https://travis-ci.com/). + +| Branch | Status | +| :------: | ------ | +| Master | [![Build Status](https://img.shields.io/travis/MikeHeiber/KMC_Lattice/master.svg?style=for-the-badge)](https://travis-ci.org/MikeHeiber/KMC_Lattice) | +| Development | [![Build Status](https://img.shields.io/travis/MikeHeiber/KMC_Lattice/development.svg?style=for-the-badge)](https://travis-ci.org/MikeHeiber/KMC_Lattice) | + +Code is being tested using [googletest](https://github.com/google/googletest) with test coverage assessment by [Coveralls](https://coveralls.io/). + +| Branch | Status | +| :------: | ------ | +| Master | [![Coveralls github branch](https://img.shields.io/coveralls/github/MikeHeiber/KMC_Lattice/master.svg?style=for-the-badge)](https://coveralls.io/github/MikeHeiber/KMC_Lattice?branch=master) | +| Development | [![Coveralls github branch](https://img.shields.io/coveralls/github/MikeHeiber/KMC_Lattice/development.svg?style=for-the-badge)](https://coveralls.io/github/MikeHeiber/KMC_Lattice?branch=development) | + +## Contact + +If you would like to contribute to the development of this project or would like some help in using the tool for your research, please contact me (heiber@mailaps.org) to discuss a collaboration. +You can check out my KMC research and other work on [Researchgate](https://www.researchgate.net/profile/Michael_Heiber). + +## How to try KMC_Lattice? + +#### Building and Testing the KMC_Lattice Library + +This software tool uses [Message Passing Interface (MPI)](https://computing.llnl.gov/tutorials/mpi/) to utilize parallel computing power. +As a result, using KMC_Lattice requires that an MPI library is pre-installed on your system, and the final KMC_Lattice library must be built on your specific system. +We cannot provide pre-built binaries for your system. +Contact your HPC admin to determine the protocols for building MPI applications on your HPC system. +In many cases, the HPC system will already be configured for you, and the package comes with a default makefile that can be used with the [GCC compiler](https://gcc.gnu.org/) or the [PGI compiler](https://www.pgroup.com/). + +If you wish, you can also install MPI on your own personal workstation and then build the KMC_Lattice library there as well. For development and preliminary simulation tests, sometimes it is more efficient to run on your own workstation instead of an HPC system. More information about common MPI packages can be found here: +- Open MPI, http://www.open-mpi.org/ +- MPICH, http://www.mpich.org/ +- MVAPICH, http://mvapich.cse.ohio-state.edu/ + +Once you have an MPI library installed, to build the KMC_Lattice library, copy the KMC_Lattice directory to your machine, set it as your working directory, and run `make`. +Compilation flags have been set for GCC and PGI compilers. If you are using another compiler, you will need to edit the makefile and define your own compiler options. +However, before you use the KMC_Lattice library, you should test it on your own hardware using the unit and system tests provided. +Build the testing executable by running `make test`. +Once the test build is complete, run `./test/KMC_Lattice_tests.exe`. +Please report any build or testing errors in the [Issues](https://github.com/MikeHeiber/KMC_Lattice/issues) section. + +## Contact If you would like to contribute to the development of this project or would like some help in building an efficient KMC simulation tool for your specific scientific problem, please contact me to discuss a collaboration. You can check out my KMC research and other work on [Researchgate](https://www.researchgate.net/profile/Michael_Heiber). From fb67a2e5d7592958b5c29df5ebb1601b50637f46 Mon Sep 17 00:00:00 2001 From: "Michael C. Heiber" Date: Tue, 8 May 2018 10:20:14 -0400 Subject: [PATCH 09/37] Utils Testing Update -simplified data input validation and testing of the calculateProbabilityHist function --- src/Utils.cpp | 63 +++++++++++++++++++-------------------------------- test/test.cpp | 10 ++++++++ 2 files changed, 33 insertions(+), 40 deletions(-) diff --git a/src/Utils.cpp b/src/Utils.cpp index a46baac..4da17f0 100644 --- a/src/Utils.cpp +++ b/src/Utils.cpp @@ -10,23 +10,15 @@ namespace Utils { using namespace std; std::vector> calculateProbabilityHist(const std::vector& data, int num_bins) { - // Determine data range - double min_val = 0.0; - double max_val = 0.0; - auto min_it = min_element(data.begin(), data.end()); - if (min_it != data.end()) { - min_val = *min_it; - } - else { - cout << "Minimum value not found. Data vector has " << data.size() << " elements." << endl; - } - auto max_it = max_element(data.begin(), data.end()); - if (max_it != data.end()) { - max_val = *max_it; - } - else { - cout << "Maximum value not found. Data vector has " << data.size() << " elements." << endl; + // Check for valid input data + if ((int)data.size() == 0) { + cout << "Error! Cannot calculate probability histogram because data vector is empty." << endl; + std::vector> null_output = { {0.0,0.0} }; + return null_output; } + // Determine data range + double min_val = *min_element(data.begin(), data.end()); + double max_val = *max_element(data.begin(), data.end()); // Limit the number of bins to the number of data entries if (num_bins > (int)data.size()) { num_bins = (int)data.size(); @@ -40,23 +32,15 @@ namespace Utils { } std::vector> calculateProbabilityHist(const std::vector& data, double bin_size) { - // Determine data range - double min_val = 0.0; - double max_val = 0.0; - auto min_it = min_element(data.begin(), data.end()); - if (min_it != data.end()) { - min_val = *min_it; - } - else { - cout << "Minimum value not found. Data vector has " << data.size() << " elements." << endl; - } - auto max_it = max_element(data.begin(), data.end()); - if (max_it != data.end()) { - max_val = *max_it; - } - else { - cout << "Maximum value not found. Data vector has " << data.size() << " elements." << endl; + // Check for valid input data + if ((int)data.size() == 0) { + cout << "Error! Cannot calculate probability histogram because data vector is empty." << endl; + std::vector> null_output = { { 0.0,0.0 } }; + return null_output; } + // Determine data range + double min_val = *min_element(data.begin(), data.end()); + double max_val = *max_element(data.begin(), data.end()); // Extend the range a little bit to ensure all data fits in the range min_val -= 1e-12*abs(min_val); max_val += 1e-12*abs(max_val); @@ -71,15 +55,14 @@ namespace Utils { } std::vector> calculateProbabilityHist(const std::vector& data, const double bin_size, const int num_bins) { - // Determine the starting bin position - double min_val = 0.0; - auto min_it = min_element(data.begin(), data.end()); - if (min_it != data.end()) { - min_val = *min_it; - } - else { - cout << "Minimum value not found. Data vector has " << data.size() << " elements." << endl; + // Check for valid input data + if ((int)data.size() == 0) { + cout << "Error! Cannot calculate probability histogram because data vector is empty." << endl; + std::vector> null_output = { { 0.0,0.0 } }; + return null_output; } + // Determine the starting bin position + double min_val = *min_element(data.begin(), data.end()); // Extend the range a little bit to ensure all data fits in the range min_val -= 1e-12*abs(min_val); // Calculate bin-centered x values diff --git a/test/test.cpp b/test/test.cpp index 6b5f2a1..f4792df 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -49,6 +49,16 @@ namespace UtilsTests { EXPECT_NEAR(1.0 / 100.0, hist[dist2(gen)].second, 1e-4); EXPECT_NEAR(1.0 / 100.0, hist[dist2(gen)].second, 1e-4); EXPECT_NEAR(1.0 / 100.0, hist[dist2(gen)].second, 1e-4); + data.clear(); + hist = calculateProbabilityHist(data, 10.0); + EXPECT_DOUBLE_EQ(0.0, hist[0].first); + EXPECT_DOUBLE_EQ(0.0, hist[0].second); + hist = calculateProbabilityHist(data, 5); + EXPECT_DOUBLE_EQ(0.0, hist[0].first); + EXPECT_DOUBLE_EQ(0.0, hist[0].second); + hist = calculateProbabilityHist(data, 1.0, 5); + EXPECT_DOUBLE_EQ(0.0, hist[0].first); + EXPECT_DOUBLE_EQ(0.0, hist[0].second); } TEST(UtilsTests, ExponentialDOSTests) { From af0e0f0581cae79ecfa9d0b9173f2b6f595b440e Mon Sep 17 00:00:00 2001 From: "Michael C. Heiber" Date: Tue, 8 May 2018 14:00:53 -0400 Subject: [PATCH 10/37] Testing Update -added more Utils and Lattice tests for better coverage --- test/test.cpp | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/test/test.cpp b/test/test.cpp index f4792df..40c096b 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -59,6 +59,11 @@ namespace UtilsTests { hist = calculateProbabilityHist(data, 1.0, 5); EXPECT_DOUBLE_EQ(0.0, hist[0].first); EXPECT_DOUBLE_EQ(0.0, hist[0].second); + data = {0.0, 1.0, 2.0, 3.0, 4.0}; + hist = calculateProbabilityHist(data, 10); + EXPECT_EQ(5, (int)hist.size()); + hist = calculateProbabilityHist(data, 0.1); + EXPECT_EQ(5, (int)hist.size()); } TEST(UtilsTests, ExponentialDOSTests) { @@ -130,6 +135,8 @@ namespace UtilsTests { data_vec[i].second = 2.5*data_vec[i].first - 5.0; } EXPECT_NEAR(3.25, interpolateData(data_vec, 3.3), 1e-4); + EXPECT_DOUBLE_EQ(7.5, interpolateData(data_vec, 5)); + EXPECT_TRUE(std::isnan(interpolateData(data_vec, 21.0))); } TEST(UtilsTests, RemoveWhitespaceTests) { @@ -288,6 +295,7 @@ namespace LatticeTests{ EXPECT_EQ(50, lattice.getHeight()); EXPECT_DOUBLE_EQ(1.0, lattice.getUnitSize()); EXPECT_EQ((long int)50 * 50 * 50, lattice.getNumSites()); + EXPECT_DOUBLE_EQ(125000e-21,lattice.getVolume()); } TEST_F(LatticeTest, CalculateDestCoordsTests) { @@ -302,6 +310,11 @@ namespace LatticeTests{ EXPECT_EQ(1, coords_f.x); EXPECT_EQ(48, coords_f.y); EXPECT_EQ(1, coords_f.z); + coords_i.setXYZ(1, 48, 1); + lattice.calculateDestinationCoords(coords_i, -2, 2, -3, coords_f); + EXPECT_EQ(49, coords_f.x); + EXPECT_EQ(0, coords_f.y); + EXPECT_EQ(48, coords_f.z); } TEST_F(LatticeTest, PeriodicCrossingTests) { @@ -328,11 +341,19 @@ namespace LatticeTests{ params_lattice.Enable_periodic_z = true; Lattice lattice2; lattice2.init(params_lattice, &gen); + EXPECT_FALSE(lattice2.isXPeriodic()); + EXPECT_FALSE(lattice2.isYPeriodic()); + EXPECT_TRUE(lattice2.isZPeriodic()); Coords coords1{ 49, 0, 49 }; + EXPECT_FALSE(lattice2.checkMoveValidity(coords1, 0, 0, 0)); EXPECT_FALSE(lattice2.checkMoveValidity(coords1, 1, 0, 0)); EXPECT_FALSE(lattice2.checkMoveValidity(coords1, 0, -1, 0)); EXPECT_TRUE(lattice2.checkMoveValidity(coords1, 0, 0, 1)); EXPECT_TRUE(lattice2.checkMoveValidity(coords1, -1, 1, -1)); + params_lattice.Enable_periodic_z = false; + lattice2.init(params_lattice, &gen); + EXPECT_FALSE(lattice2.isZPeriodic()); + EXPECT_FALSE(lattice2.checkMoveValidity(coords1, 0, 0, 1)); } TEST_F(LatticeTest, RandomSiteGenTests) { @@ -411,12 +432,16 @@ namespace LatticeTests{ EXPECT_FALSE(lattice.isOccupied(coords)); } - TEST_F(LatticeTest, SetSitePointersTests) { + TEST_F(LatticeTest, SiteTests) { Site site; vector site_ptrs(10, &site); EXPECT_FALSE(lattice.setSitePointers(site_ptrs)); site_ptrs.assign(50 * 50 * 50, &site); EXPECT_TRUE(lattice.setSitePointers(site_ptrs)); + Coords coords{5,6,7}; + Site* site1 = *lattice.getSiteIt(coords); + Site* site2 = site_ptrs[lattice.getSiteIndex(coords)]; + EXPECT_EQ(site1,site2); } } From f2b6ff9f5efa6e5d3ee5b679a6955e759550484b Mon Sep 17 00:00:00 2001 From: "Michael C. Heiber" Date: Tue, 8 May 2018 15:06:33 -0400 Subject: [PATCH 11/37] Testing Update -added additional unit tests for better coverage --- test/test.cpp | 50 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/test/test.cpp b/test/test.cpp index 40c096b..d33f59b 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -136,7 +136,10 @@ namespace UtilsTests { } EXPECT_NEAR(3.25, interpolateData(data_vec, 3.3), 1e-4); EXPECT_DOUBLE_EQ(7.5, interpolateData(data_vec, 5)); + // Attempt to interpolate beyond the data range + EXPECT_TRUE(std::isnan(interpolateData(data_vec, -1.0))); EXPECT_TRUE(std::isnan(interpolateData(data_vec, 21.0))); + } TEST(UtilsTests, RemoveWhitespaceTests) { @@ -146,6 +149,10 @@ namespace UtilsTests { EXPECT_EQ(removeWhitespace(str), "text"); str = " text "; EXPECT_EQ(removeWhitespace(str), "text"); + str = "t e xt"; + EXPECT_EQ(removeWhitespace(str), "text"); + str = "text"; + EXPECT_EQ(removeWhitespace(str), "text"); } TEST(UtilsTests, ArrayStatsTests) { @@ -323,11 +330,21 @@ namespace LatticeTests{ EXPECT_EQ(lattice.calculateDX(coords_i, coords_f), -50); EXPECT_EQ(lattice.calculateDY(coords_i, coords_f), 0); EXPECT_EQ(lattice.calculateDZ(coords_i, coords_f), 0); + coords_i = { 0, 49, 48 }; + coords_f = { 49, 49, 49 }; + EXPECT_EQ(lattice.calculateDX(coords_i, coords_f), 50); + EXPECT_EQ(lattice.calculateDY(coords_i, coords_f), 0); + EXPECT_EQ(lattice.calculateDZ(coords_i, coords_f), 0); coords_i.setXYZ(0, 0, 49); coords_f.setXYZ(1, 49, 0); EXPECT_EQ(lattice.calculateDX(coords_i, coords_f), 0); EXPECT_EQ(lattice.calculateDY(coords_i, coords_f), 50); EXPECT_EQ(lattice.calculateDZ(coords_i, coords_f), -50); + coords_i = {1, 49, 0}; + coords_f = {0, 0, 49}; + EXPECT_EQ(lattice.calculateDX(coords_i, coords_f), 0); + EXPECT_EQ(lattice.calculateDY(coords_i, coords_f), -50); + EXPECT_EQ(lattice.calculateDZ(coords_i, coords_f), 50); coords_i.setXYZ(4, 5, 6); coords_f.setXYZ(3, 6, 5); EXPECT_EQ(lattice.calculateDX(coords_i, coords_f), 0); @@ -442,6 +459,17 @@ namespace LatticeTests{ Site* site1 = *lattice.getSiteIt(coords); Site* site2 = site_ptrs[lattice.getSiteIndex(coords)]; EXPECT_EQ(site1,site2); + // Check for sites and indices outside the lattice + coords = {0, 60, 0}; + EXPECT_THROW(lattice.getSiteIndex(coords),out_of_range); + EXPECT_THROW(lattice.getSiteCoords(150000),out_of_range); + // Check site object assignment and clearing + Object object; + site.setObjectPtr(&object); + EXPECT_TRUE(site.isOccupied()); + EXPECT_EQ(&object,site.getObjectPtr()); + site.clearOccupancy(); + EXPECT_FALSE(site.isOccupied()); } } @@ -510,9 +538,25 @@ namespace EventTests { namespace ObjectTests { + TEST(ObjectTests, GeneralObjectTests) { + // Assume object is created in a 50 x 50 x 50 lattice + Coords coords = {0,0,0}; + Object object1(0.0, 1, coords); + EXPECT_EQ("Object",object1.getObjectType()); + EXPECT_EQ(1,object1.getTag()); + EXPECT_EQ(coords,object1.getCoords()); + EXPECT_DOUBLE_EQ(0.0,object1.getCreationTime()); + // Object-Event tests + Event event; + list event_ptrs; + event_ptrs.push_back(&event); + object1.setEventIt(event_ptrs.begin()); + EXPECT_EQ(&event,*(object1.getEventIt())); + } + TEST(ObjectTests, CalculateDisplacementTests) { // Assume object is created in a 50 x 50 x 50 lattice - Object object1(0, 1, { 0,0,0 }); + Object object1(0.0, 1, { 0,0,0 }); object1.setCoords({ 0,0,5 }); EXPECT_DOUBLE_EQ(5.0, object1.calculateDisplacement()); object1.setCoords({ 0,0,49 }); @@ -525,7 +569,11 @@ namespace ObjectTests { object1.setCoords({ 49,0,49 }); object1.incrementDY(50); EXPECT_DOUBLE_EQ(sqrt(2), object1.calculateDisplacement()); + object1.resetInitialCoords({5,5,5}); + object1.setCoords({ 4,4,4 }); + EXPECT_DOUBLE_EQ(sqrt(3), object1.calculateDisplacement()); } + } From fab49c50cbec6fbbe78dd1a9ca988509c965895c Mon Sep 17 00:00:00 2001 From: "Michael C. Heiber" Date: Tue, 8 May 2018 15:32:58 -0400 Subject: [PATCH 12/37] Utils Update -added a basic constructor to the Coords class of the form coords(x,y,z) --- src/Utils.cpp | 2 +- src/Utils.h | 17 +++++++++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/Utils.cpp b/src/Utils.cpp index 4da17f0..775cfba 100644 --- a/src/Utils.cpp +++ b/src/Utils.cpp @@ -142,7 +142,7 @@ namespace Utils { if (data[i-1].first < x_val && data[i].first > x_val) { return data[i - 1].second + ((data[i].second - data[i - 1].second) / (data[i].first - data[i - 1].first))*(x_val - data[i - 1].first); } - if (abs(data[i].first - x_val) < 1e-6) { + if (abs(data[i].first - x_val) < 1e-12) { return data[i].second; } } diff --git a/src/Utils.h b/src/Utils.h index a87d8f5..6001bae 100644 --- a/src/Utils.h +++ b/src/Utils.h @@ -30,6 +30,19 @@ struct Coords{ //! The z Cartesian coordinate. int z; + //! Default constructor that creates an empty Coords object. + Coords(){} + + //! \brief Constructor that creates a Coords object with the x,y,z coordinates set using the input values xval, yval, and zval. + //! \param xval is the input x value. + //! \param yval is the input y value. + //! \param zval is the input z value. + Coords(const int xval, const int yval, const int zval) { + x = xval; + y = yval; + z = zval; + } + //! \brief Sets the x,y,z coordinates using the input values xval, yval, and zval. //! \param xval is the input x value. //! \param yval is the input y value. @@ -154,7 +167,7 @@ namespace Utils { //! \brief Uses MPI to gather vectors from separate processors to build one big vector containing all of the data. //! \details Each processor calls this function and sends an input vector. Upon function return, processor 0 - //! receives the large data vector and all of the othe rprocessors receive an empty vector. + //! receives the large data vector and all of the other processors receive an empty vector. //! \param input_vector is the input data from the processor calling the function. //! \return A vector that is a concatenation of all input vectors from each processor, when called on processor 0. //! \return An empty vector when called on other processors. @@ -162,7 +175,7 @@ namespace Utils { //! \brief Uses MPI to gather vectors from separate processors to build one big vector containing all of the data. //! \details Each processor calls this function and sends an input vector. Upon function return, processor 0 - //! receives the large data vector and all of the othe rprocessors receive an empty vector. + //! receives the large data vector and all of the other processors receive an empty vector. //! \param input_vector is the input data from the processor calling the function. //! \return A vector that is a concatenation of all input vectors from each processor, when called on processor 0. //! \return An empty vector when called on other processors. From ed8ec6dc711790c15d27f10ff7d51f994cec5b2a Mon Sep 17 00:00:00 2001 From: "Michael C. Heiber" Date: Tue, 8 May 2018 15:33:27 -0400 Subject: [PATCH 13/37] Testing Update -added more Event class tests to increase test coverage --- test/test.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/test/test.cpp b/test/test.cpp index d33f59b..500ab14 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -499,6 +499,24 @@ namespace EventTests { test_sim.init(params_base, 0); } }; + + TEST_F(EventTest, GeneralEventTests){ + Event event(&test_sim); + EXPECT_EQ("Event",event.getEventType()); + Coords coords1(0,0,0); + Object object1(0.0, 1, coords1); + event.setObjectPtr(&object1); + EXPECT_EQ(&object1,event.getObjectPtr()); + Coords coords2(1,0,0); + Object object2(0.0, 2, coords2); + event.setObjectTargetPtr(&object2); + EXPECT_EQ(&object2,event.getObjectTargetPtr()); + event.setDestCoords(coords2); + EXPECT_EQ(coords2,event.getDestCoords()); + EXPECT_FALSE(event.setExecutionTime(-1.0)); + EXPECT_TRUE(event.setExecutionTime(1.0)); + EXPECT_DOUBLE_EQ(1.0,event.getExecutionTime()); + } TEST_F(EventTest, CalculateExecutionTimeTests) { Event event(&test_sim); From d523f8e2c91cdbe5156d848f5d430c30d1481554 Mon Sep 17 00:00:00 2001 From: "Michael C. Heiber" Date: Tue, 8 May 2018 18:29:54 -0400 Subject: [PATCH 14/37] Testing Update -updated TestSim dervied Simulation class for creating a testable object -added a number of unit tests for the Simulation class --- test/test.cpp | 118 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 115 insertions(+), 3 deletions(-) diff --git a/test/test.cpp b/test/test.cpp index 500ab14..c210f2d 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -14,10 +14,123 @@ using namespace Utils; // Simple derived Simulation class class TestSim : public Simulation { public: - bool checkFinished() const { return false; }; - bool executeNextEvent() { return false; }; + vector objects; + vector events; + vector sites; + + bool init(const Parameters_Simulation& params, const int id) { + // Initialize Simulation base class + Simulation::init(params, id); + // Initialize Sites + Site site; + sites.assign(lattice.getNumSites(), site); + vector site_ptrs; + for (auto& item : sites) { + site_ptrs.push_back(&item); + } + lattice.setSitePointers(site_ptrs); + // Perform test initialization + // Construct and add initial object + Coords coords1(0, 0, 0); + Object object1(0.0, 1, coords1); + objects.push_back(object1); + addObject(&objects[0]); + // Construct and add event for the object + Event event1(this); + event1.setObjectPtr(&objects[0]); + Coords coords2(1, 0, 0); + event1.setDestCoords(coords2); + event1.calculateExecutionTime(1.0); + events.push_back(event1); + setObjectEvent(&objects[0], &events[0]); + return true; + } + + void calculateNextEvent(Object* object_ptr) { + Event* event_ptr = *(object_ptr->getEventIt()); + Coords coords_i = object_ptr->getCoords(); + Coords coords_f; + lattice.calculateDestinationCoords(coords_i, 0, 10, 0, coords_f); + event_ptr->setDestCoords(coords_f); + event_ptr->calculateExecutionTime(1.0); + } + + bool checkFinished() const { + return (getN_events_executed() == 8); + } + + bool executeNextEvent() { + Event* event_ptr = *chooseNextEvent(); + setTime(event_ptr->getExecutionTime()); + Coords coords_i = (*(event_ptr->getObjectPtr())).getCoords(); + Coords coords_f = event_ptr->getDestCoords(); + moveObject(event_ptr->getObjectPtr(), event_ptr->getDestCoords()); + auto object_vec = findRecalcObjects(coords_i, coords_f); + for (auto item : object_vec) { + calculateNextEvent(item); + } + return true; + } + }; +namespace SimulationTests { + + class SimulationTest : public ::testing::Test { + protected: + Parameters_Simulation params_base; + TestSim sim; + void SetUp() { + { + params_base.Enable_logging = false; + params_base.Enable_periodic_x = true; + params_base.Enable_periodic_y = true; + params_base.Enable_periodic_z = true; + params_base.Length = 50; + params_base.Width = 50; + params_base.Height = 50; + params_base.Unit_size = 1.0; + params_base.Temperature = 300; + params_base.Enable_FRM = false; + params_base.Enable_selective_recalc = true; + params_base.Recalc_cutoff = 3; + params_base.Enable_full_recalc = false; + } + // Initialize TestSim object + sim.init(params_base, 0); + sim.setGeneratorSeed(0); + } + }; + + TEST_F(SimulationTest, SetupTests) { + EXPECT_EQ(0, sim.getId()); + EXPECT_FALSE(sim.isLoggingEnabled()); + EXPECT_DOUBLE_EQ(0.0, sim.getTime()); + EXPECT_EQ(300, sim.getTemp()); + EXPECT_DOUBLE_EQ(125000e-21, sim.getVolume()); + } + + TEST_F(SimulationTest, EventExecutionTests) { + Coords coords(0, 0, 0); + EXPECT_EQ(coords, sim.objects[0].getCoords()); + EXPECT_EQ(1, sim.getN_events()); + EXPECT_TRUE(sim.executeNextEvent()); + coords.setXYZ(1, 0, 0); + EXPECT_EQ(coords, sim.objects[0].getCoords()); + EXPECT_EQ(2, sim.getN_events_executed()); + EXPECT_FALSE(sim.checkFinished()); + while (!sim.checkFinished()) { + EXPECT_TRUE(sim.executeNextEvent()); + } + EXPECT_EQ(8, sim.getN_events_executed()); + Coords coords_f(1, 10, 0); + EXPECT_EQ(coords_f.x, sim.objects[0].getCoords().x); + EXPECT_EQ(coords_f.y, sim.objects[0].getCoords().y); + EXPECT_EQ(coords_f.z, sim.objects[0].getCoords().z); + } + +} + namespace UtilsTests { TEST(UtilsTests, CoordsTests) { @@ -594,7 +707,6 @@ namespace ObjectTests { } - int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); From f1fe19dd8ae404bc6cb99b0df26a5a306f080426 Mon Sep 17 00:00:00 2001 From: "Michael C. Heiber" Date: Wed, 9 May 2018 09:39:40 -0400 Subject: [PATCH 15/37] Coveralls Testing Update -updated travis yml file so that each env variable set has a designated build target and added a separate test item for doing test coverage assessment, which should save testing time on the rest of the builds -updated makefile to have separate test and test_coverage build targets with different compiler flags --- .travis.yml | 43 ++++++++++++++++++++++--------------------- makefile | 11 +++++------ 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/.travis.yml b/.travis.yml index 03f4a5f..70c2278 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,34 +13,35 @@ compiler: - gcc env: - - COMPILER_OPTIONS="VERSION=4.7 && MPI=mpich2" - - COMPILER_OPTIONS="VERSION=4.7 && MPI=openmpi" - - COMPILER_OPTIONS="VERSION=4.8 && MPI=mpich2" - - COMPILER_OPTIONS="VERSION=4.8 && MPI=openmpi" - - COMPILER_OPTIONS="VERSION=4.9 && MPI=mpich2" - - COMPILER_OPTIONS="VERSION=4.9 && MPI=openmpi" - - COMPILER_OPTIONS="VERSION=5 && MPI=mpich2" - - COMPILER_OPTIONS="VERSION=5 && MPI=openmpi" - - COMPILER_OPTIONS="VERSION=6 && MPI=mpich2" - - COMPILER_OPTIONS="VERSION=6 && MPI=openmpi" - - COMPILER_OPTIONS="VERSION=7 && MPI=mpich2" - - COMPILER_OPTIONS="VERSION=7 && MPI=openmpi" - - COMPILER_OPTIONS="VERSION=8 && MPI=mpich2" - - COMPILER_OPTIONS="VERSION=8 && MPI=openmpi" + - OPTIONS="GCC_VERSION=5 && MPI=openmpi && TARGET=test_coverage" + - OPTIONS="GCC_VERSION=4.7 && MPI=mpich2 && TARGET=test" + - OPTIONS="GCC_VERSION=4.7 && MPI=openmpi && TARGET=test" + - OPTIONS="GCC_VERSION=4.8 && MPI=mpich2 && TARGET=test" + - OPTIONS="GCC_VERSION=4.8 && MPI=openmpi && TARGET=test" + - OPTIONS="GCC_VERSION=4.9 && MPI=mpich2 && TARGET=test" + - OPTIONS="GCC_VERSION=4.9 && MPI=openmpi && TARGET=test" + - OPTIONS="GCC_VERSION=5 && MPI=mpich2 && TARGET=test" + - OPTIONS="GCC_VERSION=5 && MPI=openmpi && TARGET=test" + - OPTIONS="GCC_VERSION=6 && MPI=mpich2 && TARGET=test" + - OPTIONS="GCC_VERSION=6 && MPI=openmpi && TARGET=test" + - OPTIONS="GCC_VERSION=7 && MPI=mpich2 && TARGET=test" + - OPTIONS="GCC_VERSION=7 && MPI=openmpi && TARGET=test" + - OPTIONS="GCC_VERSION=8 && MPI=mpich2 && TARGET=test" + - OPTIONS="GCC_VERSION=8 && MPI=openmpi && TARGET=test" before_install: - - eval "${COMPILER_OPTIONS}" + - eval "${OPTIONS}" - sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y - sudo apt-get update -qq - - sudo apt-get install -qq gcc-$VERSION g++-$VERSION -y - - sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-$VERSION 60 --slave /usr/bin/g++ g++ /usr/bin/g++-$VERSION + - sudo apt-get install -qq gcc-$GCC_VERSION g++-$GCC_VERSION -y + - sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-$GCC_VERSION 60 --slave /usr/bin/g++ g++ /usr/bin/g++-$GCC_VERSION - sudo update-alternatives --config gcc - gcc --version - if [[ "$MPI" = mpich2 ]]; then sudo apt-get -y install -qq mpich2 libmpich2-dev; fi - if [[ "$MPI" = openmpi ]]; then sudo apt-get -y install -qq openmpi-bin libopenmpi-dev; fi - - pip install --user cpp-coveralls + - if [[ "$TARGET" = test_coverage ]]; then pip install --user cpp-coveralls; fi script: - - make -j10 test && travis_wait ./test/KMC_Lattice_tests.exe - - make -j10 test_mpi && travis_wait mpiexec -n 4 ./test/KMC_Lattice_MPI_tests.exe - - coveralls --include src --exclude "googletest/*" --gcov-options '\-lp' + - make -j10 $TARGET && travis_wait ./test/KMC_Lattice_tests.exe && travis_wait mpiexec -n 4 ./test/KMC_Lattice_MPI_tests.exe + - if [[ "$TARGET" = test_coverage ]]; then coveralls --include src --exclude "googletest/*" --gcov-options '\-lp'; fi + - diff --git a/makefile b/makefile index 18c810d..6e46b0a 100644 --- a/makefile +++ b/makefile @@ -56,8 +56,10 @@ ifeq ($(lastword $(subst /, ,$(CXX))),pgc++) GTEST_FLAGS = -I$(GTEST_DIR)/include endif -test : FLAGS = -fprofile-arcs -ftest-coverage -std=c++11 -Wall -Wextra -I. -Isrc -test : test/KMC_Lattice_tests.exe +test_coverage : FLAGS = -fprofile-arcs -ftest-coverage -std=c++11 -Wall -Wextra -I. -Isrc +test_coverage : test/KMC_Lattice_tests.exe test/KMC_Lattice_MPI_tests.exe + +test : test/KMC_Lattice_tests.exe test/KMC_Lattice_MPI_tests.exe test/KMC_Lattice_tests.exe : test/test.o test/gtest-all.o $(OBJS) mpicxx $(GTEST_FLAGS) $(FLAGS) -lpthread $^ -o $@ @@ -68,9 +70,6 @@ test/gtest-all.o : $(GTEST_SRCS_) test/test.o : test/test.cpp $(GTEST_HEADERS) $(OBJS) mpicxx $(GTEST_FLAGS) $(FLAGS) -c $< -o $@ -test_mpi : FLAGS = -fprofile-arcs -ftest-coverage -std=c++11 -Wall -Wextra -I. -Isrc -test_mpi : test/KMC_Lattice_MPI_tests.exe - test/KMC_Lattice_MPI_tests.exe : test/test_mpi.o test/gtest-all.o $(OBJS) mpicxx $(GTEST_FLAGS) $(FLAGS) -lpthread $^ -o $@ @@ -78,4 +77,4 @@ test/test_mpi.o : test/test_mpi.cpp $(GTEST_HEADERS) $(OBJS) mpicxx $(GTEST_FLAGS) $(FLAGS) -c $< -o $@ clean: - -rm src/*.o src/*.gcno* src/*.gcda KMC_Lattice/*.o KMC_Lattice/*.gcno* KMC_Lattice/*.gcda testing/*.o testing/*.gcno* testing/*.gcda *~ Excimontec.exe testing/*.o testing/Excimontec_tests.exe testing/Excimontec_mpi_tests.exe + -rm src/*.o src/*.gcno* src/*.gcda test/*.o test/*.gcno* test/*.gcda *~ libKMC.a test/KMC_Lattice_tests.exe test/KMC_Lattice_MPI_tests.exe From 85990e11a80ed7c22512a9bbb6b2029de68aea3e Mon Sep 17 00:00:00 2001 From: "Michael C. Heiber" Date: Wed, 9 May 2018 10:04:46 -0400 Subject: [PATCH 16/37] Travis CI Testing Update -removed unneeded line in travis yml fiel --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 70c2278..528b8a8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -44,4 +44,3 @@ before_install: script: - make -j10 $TARGET && travis_wait ./test/KMC_Lattice_tests.exe && travis_wait mpiexec -n 4 ./test/KMC_Lattice_MPI_tests.exe - if [[ "$TARGET" = test_coverage ]]; then coveralls --include src --exclude "googletest/*" --gcov-options '\-lp'; fi - - From c0a9ed257ffaaebb7d27b3343170dc95d88d5b4b Mon Sep 17 00:00:00 2001 From: "Michael C. Heiber" Date: Wed, 9 May 2018 13:41:45 -0400 Subject: [PATCH 17/37] Simulation Clas Minor Update -added public getN_objects_created function to allow more information to be gathered about the simulation progress -refactored chooseNextEvent fucntion to be more concise --- src/Simulation.cpp | 16 +++++++--------- src/Simulation.h | 5 ++++- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/Simulation.cpp b/src/Simulation.cpp index 7b679f7..b14c329 100644 --- a/src/Simulation.cpp +++ b/src/Simulation.cpp @@ -65,15 +65,9 @@ void Simulation::addObject(Object* object_ptr) { } list::const_iterator Simulation::chooseNextEvent() { - auto event_target_it = event_ptrs.begin(); - if (event_ptrs.size() > 1) { - for (auto it = ++event_ptrs.begin(); it != event_ptrs.end(); ++it) { - if ((*it) != nullptr && ((*event_target_it) == nullptr || ((*it)->getExecutionTime() < (*event_target_it)->getExecutionTime()))) { - event_target_it = it; - } - } - } - return event_target_it; + return min_element(event_ptrs.begin(), event_ptrs.end(), [](Event* a, Event* b) { + return (a != nullptr && b != nullptr ) && (a->getExecutionTime() < b->getExecutionTime()); + }); } vector Simulation::findRecalcObjects(const Coords& coords_start, const Coords& coords_dest) const { @@ -163,6 +157,10 @@ long int Simulation::getN_events_executed() const { return N_events_executed; } +long int Simulation::getN_objects_created() const { + return N_objects_created; +} + int Simulation::getTemp() const { return temperature; } diff --git a/src/Simulation.h b/src/Simulation.h index 6ad0cfc..9942a7b 100644 --- a/src/Simulation.h +++ b/src/Simulation.h @@ -99,6 +99,9 @@ class Simulation{ //! Gets the number of events that have been executed in the simulation. long int getN_events_executed() const; + //! Gets the number of objects that have been created in the simulation. + long int getN_objects_created() const; + //! \brief Gets the processor ID number for the processor that is running the simulation. //! \details This is primarly used with MPI to differentiate between different simualtions running on //! different cores. @@ -214,7 +217,7 @@ class Simulation{ std::list object_ptrs; std::list event_ptrs; // Counters - double time_sim = 0; + double time_sim = 0.0; long int N_objects_created = 0; long int N_events_executed = 0; // Functions From 4ff7ab2bc7bd879ff40d5ecb284feef20c05d5a0 Mon Sep 17 00:00:00 2001 From: "Michael C. Heiber" Date: Wed, 9 May 2018 13:43:34 -0400 Subject: [PATCH 18/37] Simulation Class Testing Update -expanded the TestSim class to contain definitions of serveral derived Event classes and to perform a simple object creation and diffusion simulation with greater code coverage that can be tested --- test/test.cpp | 149 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 113 insertions(+), 36 deletions(-) diff --git a/test/test.cpp b/test/test.cpp index c210f2d..e0e9750 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -14,9 +14,33 @@ using namespace Utils; // Simple derived Simulation class class TestSim : public Simulation { public: - vector objects; - vector events; - vector sites; + class CreationEvent : public Event { + public: + CreationEvent() : Event() {} + CreationEvent(Simulation* simulation_ptr) : Event(simulation_ptr) {} + string getEventType() const { return "Creation"; } + }; + class MoveEvent : public Event { + public: + MoveEvent() : Event() {} + MoveEvent(Simulation* simulation_ptr) : Event(simulation_ptr) {} + string getEventType() const { return "Move"; } + }; + class TerminationEvent : public Event { + public: + TerminationEvent() : Event() {} + TerminationEvent(Simulation* simulation_ptr) : Event(simulation_ptr) {} + string getEventType() const { return "Termination"; } + }; + + // Data members + list objects; + list sites; + CreationEvent event_creation; + list events_move; + list events_termination; + int N_move_events = 0; + int N_termination_events = 0; bool init(const Parameters_Simulation& params, const int id) { // Initialize Simulation base class @@ -30,47 +54,104 @@ class TestSim : public Simulation { } lattice.setSitePointers(site_ptrs); // Perform test initialization - // Construct and add initial object - Coords coords1(0, 0, 0); - Object object1(0.0, 1, coords1); - objects.push_back(object1); - addObject(&objects[0]); - // Construct and add event for the object - Event event1(this); - event1.setObjectPtr(&objects[0]); - Coords coords2(1, 0, 0); - event1.setDestCoords(coords2); - event1.calculateExecutionTime(1.0); - events.push_back(event1); - setObjectEvent(&objects[0], &events[0]); + CreationEvent event_creation_new(this); + event_creation = event_creation_new; + event_creation.setDestCoords(lattice.generateRandomCoords()); + event_creation.calculateExecutionTime(1.0); + addEvent(&event_creation); return true; } void calculateNextEvent(Object* object_ptr) { - Event* event_ptr = *(object_ptr->getEventIt()); + auto move_event_it = find_if(events_move.begin(), events_move.end(), [object_ptr](MoveEvent& a) { return a.getObjectPtr() == object_ptr; }); + auto termination_event_it = find_if(events_termination.begin(), events_termination.end(), [object_ptr](TerminationEvent& a) { return a.getObjectPtr() == object_ptr; }); + // Calculate move events + move_event_it->calculateExecutionTime(100); Coords coords_i = object_ptr->getCoords(); Coords coords_f; - lattice.calculateDestinationCoords(coords_i, 0, 10, 0, coords_f); - event_ptr->setDestCoords(coords_f); - event_ptr->calculateExecutionTime(1.0); + lattice.calculateDestinationCoords(coords_i, 1, 0, 0, coords_f); + move_event_it->setDestCoords(coords_f); + // Calculate termination event + termination_event_it->setDestCoords(coords_i); + termination_event_it->calculateExecutionTime(10); + // Select fastest event + if (move_event_it->getExecutionTime() < termination_event_it->getExecutionTime()) { + setObjectEvent(object_ptr, &(*move_event_it)); + } + else { + setObjectEvent(object_ptr, &(*termination_event_it)); + } } bool checkFinished() const { - return (getN_events_executed() == 8); + return (getN_objects_created() == 5); + } + + void executeCreationEvent(const std::list::const_iterator event_it) { + Event* event_ptr = *event_it; + Coords coords_dest = event_ptr->getDestCoords(); + Object object(event_ptr->getExecutionTime(),getN_objects_created()+1,coords_dest); + objects.push_back(object); + addObject(&objects.back()); + Simulation* sim_ptr = this; + MoveEvent event1(sim_ptr); + event1.setObjectPtr(&objects.back()); + events_move.push_back(event1); + TerminationEvent event2(sim_ptr); + event2.setObjectPtr(&objects.back()); + events_termination.push_back(event2); + // Calculate next creation event + event_creation.setDestCoords(lattice.generateRandomCoords()); + event_creation.calculateExecutionTime(1.0); + } + + void executeMoveEvent(const std::list::const_iterator event_it) { + Event* event_ptr = *event_it; + moveObject(event_ptr->getObjectPtr(), event_ptr->getDestCoords()); + N_move_events++; } bool executeNextEvent() { - Event* event_ptr = *chooseNextEvent(); - setTime(event_ptr->getExecutionTime()); - Coords coords_i = (*(event_ptr->getObjectPtr())).getCoords(); + auto event_it = chooseNextEvent(); + Event* event_ptr = *event_it; + string event_type = event_ptr->getEventType(); + Coords coords_i; Coords coords_f = event_ptr->getDestCoords(); - moveObject(event_ptr->getObjectPtr(), event_ptr->getDestCoords()); + setTime(event_ptr->getExecutionTime()); + if (event_type.compare("Creation")==0) { + executeCreationEvent(event_it); + coords_i = coords_f; + } + else { + coords_i = event_ptr->getObjectPtr()->getCoords(); + if (event_type.compare("Move")==0) { + executeMoveEvent(event_it); + } + else if (event_type.compare("Termination")==0) { + executeTerminationEvent(event_it); + } + else { + return false; + } + } auto object_vec = findRecalcObjects(coords_i, coords_f); for (auto item : object_vec) { calculateNextEvent(item); } return true; } + + void executeTerminationEvent(const std::list::const_iterator event_it) { + Object* object_ptr = (*event_it)->getObjectPtr(); + // Remove object from Simulation class + removeObject(object_ptr); + // Remove local events + auto move_event_it = find_if(events_move.begin(), events_move.end(), [object_ptr](MoveEvent& a) { return a.getObjectPtr() == object_ptr; }); + events_move.erase(move_event_it); + auto termination_event_it = find_if(events_termination.begin(), events_termination.end(), [object_ptr](TerminationEvent& a) { return a.getObjectPtr() == object_ptr; }); + events_termination.erase(termination_event_it); + N_termination_events++; + } }; @@ -111,22 +192,18 @@ namespace SimulationTests { } TEST_F(SimulationTest, EventExecutionTests) { - Coords coords(0, 0, 0); - EXPECT_EQ(coords, sim.objects[0].getCoords()); + EXPECT_EQ(0, (int)sim.objects.size()); EXPECT_EQ(1, sim.getN_events()); EXPECT_TRUE(sim.executeNextEvent()); - coords.setXYZ(1, 0, 0); - EXPECT_EQ(coords, sim.objects[0].getCoords()); - EXPECT_EQ(2, sim.getN_events_executed()); + EXPECT_EQ(1, (int)sim.objects.size()); + EXPECT_EQ(1, sim.objects.front().getTag()); + EXPECT_EQ(2, sim.getN_events()); + EXPECT_EQ(1, sim.getN_events_executed()); EXPECT_FALSE(sim.checkFinished()); while (!sim.checkFinished()) { - EXPECT_TRUE(sim.executeNextEvent()); + sim.executeNextEvent(); } - EXPECT_EQ(8, sim.getN_events_executed()); - Coords coords_f(1, 10, 0); - EXPECT_EQ(coords_f.x, sim.objects[0].getCoords().x); - EXPECT_EQ(coords_f.y, sim.objects[0].getCoords().y); - EXPECT_EQ(coords_f.z, sim.objects[0].getCoords().z); + } } From 565029c7dca20c3b93f963f55ce83b4b5e26e4bb Mon Sep 17 00:00:00 2001 From: "Michael C. Heiber" Date: Wed, 9 May 2018 14:59:46 -0400 Subject: [PATCH 19/37] Simulation Class Testing Update -updated Simulation class test to run a small particle diffusion test and added a test to check the average displacement calculated by each of the KMC algorithms --- test/test.cpp | 75 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 71 insertions(+), 4 deletions(-) diff --git a/test/test.cpp b/test/test.cpp index e0e9750..59c1e34 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -39,8 +39,11 @@ class TestSim : public Simulation { CreationEvent event_creation; list events_move; list events_termination; + Event event_previous; + string event_previous_type; int N_move_events = 0; int N_termination_events = 0; + vector displacement_data; bool init(const Parameters_Simulation& params, const int id) { // Initialize Simulation base class @@ -69,7 +72,33 @@ class TestSim : public Simulation { move_event_it->calculateExecutionTime(100); Coords coords_i = object_ptr->getCoords(); Coords coords_f; - lattice.calculateDestinationCoords(coords_i, 1, 0, 0, coords_f); + int i = 0, j = 0, k = 0; + uniform_int_distribution<> dist(0, 5); + int rand_num = dist(generator); + switch (rand_num) { + case 0: + i = -1; + break; + case 1: + i = 1; + break; + case 2: + j = -1; + break; + case 3: + j = 1; + break; + case 4: + k = -1; + break; + case 5: + k = 1; + break; + default: + i = 1; + break; + } + lattice.calculateDestinationCoords(coords_i, i, j, k, coords_f); move_event_it->setDestCoords(coords_f); // Calculate termination event termination_event_it->setDestCoords(coords_i); @@ -84,7 +113,7 @@ class TestSim : public Simulation { } bool checkFinished() const { - return (getN_objects_created() == 5); + return (N_termination_events == 100000); } void executeCreationEvent(const std::list::const_iterator event_it) { @@ -115,6 +144,8 @@ class TestSim : public Simulation { auto event_it = chooseNextEvent(); Event* event_ptr = *event_it; string event_type = event_ptr->getEventType(); + event_previous = *event_ptr; + event_previous_type = event_type; Coords coords_i; Coords coords_f = event_ptr->getDestCoords(); setTime(event_ptr->getExecutionTime()); @@ -128,6 +159,8 @@ class TestSim : public Simulation { executeMoveEvent(event_it); } else if (event_type.compare("Termination")==0) { + Object* object_ptr = (*event_it)->getObjectPtr(); + displacement_data.push_back(object_ptr->calculateDisplacement()); executeTerminationEvent(event_it); } else { @@ -152,6 +185,14 @@ class TestSim : public Simulation { events_termination.erase(termination_event_it); N_termination_events++; } + + vector getAllObjectPtrs() const { + return getAllObjectPtrs(); + } + + vector getAllEventPtrs() const { + return getAllEventPtrs(); + } }; @@ -200,10 +241,36 @@ namespace SimulationTests { EXPECT_EQ(2, sim.getN_events()); EXPECT_EQ(1, sim.getN_events_executed()); EXPECT_FALSE(sim.checkFinished()); + } + + TEST_F(SimulationTest, KMCAlgorithmTests) { while (!sim.checkFinished()) { - sim.executeNextEvent(); + EXPECT_TRUE(sim.executeNextEvent()); } - + EXPECT_EQ(100000, sim.getN_objects_created()); + double displacement = vector_avg(sim.displacement_data); + TestSim sim2; + params_base.Enable_FRM = true; + params_base.Enable_selective_recalc = false; + params_base.Enable_full_recalc = false; + sim2.init(params_base, 0); + while (!sim2.checkFinished()) { + EXPECT_TRUE(sim2.executeNextEvent()); + } + EXPECT_EQ(100000, sim2.getN_objects_created()); + double displacement2 = vector_avg(sim2.displacement_data); + EXPECT_NEAR(displacement, displacement2, 1e-2); + TestSim sim3; + params_base.Enable_FRM = false; + params_base.Enable_selective_recalc = false; + params_base.Enable_full_recalc = true; + sim3.init(params_base, 0); + while (!sim3.checkFinished()) { + EXPECT_TRUE(sim3.executeNextEvent()); + } + EXPECT_EQ(100000, sim3.getN_objects_created()); + double displacement3 = vector_avg(sim3.displacement_data); + EXPECT_NEAR(displacement, displacement3, 1e-2); } } From a97b8c8dc1326196ffbed3229b1a119358de32b1 Mon Sep 17 00:00:00 2001 From: "Michael C. Heiber" Date: Wed, 9 May 2018 15:30:05 -0400 Subject: [PATCH 20/37] Simulation Class Testing Update -updated simulation termination condition so that it is more consistent for testing --- test/test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test.cpp b/test/test.cpp index 59c1e34..51f5f74 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -113,7 +113,7 @@ class TestSim : public Simulation { } bool checkFinished() const { - return (N_termination_events == 100000); + return (getN_objects_created() == 100000); } void executeCreationEvent(const std::list::const_iterator event_it) { From d4480b95d8685777feda82e6f91f632945cc05e4 Mon Sep 17 00:00:00 2001 From: "Michael C. Heiber" Date: Wed, 9 May 2018 15:42:15 -0400 Subject: [PATCH 21/37] Simulation Class Testing Update -increased diffusion test run to get more accurate statistics --- test/test.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/test.cpp b/test/test.cpp index 51f5f74..3d9c2bb 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -113,7 +113,7 @@ class TestSim : public Simulation { } bool checkFinished() const { - return (getN_objects_created() == 100000); + return (getN_objects_created() == 200000); } void executeCreationEvent(const std::list::const_iterator event_it) { @@ -247,7 +247,7 @@ namespace SimulationTests { while (!sim.checkFinished()) { EXPECT_TRUE(sim.executeNextEvent()); } - EXPECT_EQ(100000, sim.getN_objects_created()); + EXPECT_EQ(200000, sim.getN_objects_created()); double displacement = vector_avg(sim.displacement_data); TestSim sim2; params_base.Enable_FRM = true; @@ -257,7 +257,7 @@ namespace SimulationTests { while (!sim2.checkFinished()) { EXPECT_TRUE(sim2.executeNextEvent()); } - EXPECT_EQ(100000, sim2.getN_objects_created()); + EXPECT_EQ(200000, sim2.getN_objects_created()); double displacement2 = vector_avg(sim2.displacement_data); EXPECT_NEAR(displacement, displacement2, 1e-2); TestSim sim3; @@ -268,7 +268,7 @@ namespace SimulationTests { while (!sim3.checkFinished()) { EXPECT_TRUE(sim3.executeNextEvent()); } - EXPECT_EQ(100000, sim3.getN_objects_created()); + EXPECT_EQ(200000, sim3.getN_objects_created()); double displacement3 = vector_avg(sim3.displacement_data); EXPECT_NEAR(displacement, displacement3, 1e-2); } From ca30f9b91e4793028593e62ccc57ad9f557836ab Mon Sep 17 00:00:00 2001 From: "Michael C. Heiber" Date: Wed, 9 May 2018 16:14:37 -0400 Subject: [PATCH 22/37] Simulation Class Testing Update -increased tolerance on diffusion test results from different algorithms --- test/test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/test.cpp b/test/test.cpp index 3d9c2bb..c998df3 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -259,7 +259,7 @@ namespace SimulationTests { } EXPECT_EQ(200000, sim2.getN_objects_created()); double displacement2 = vector_avg(sim2.displacement_data); - EXPECT_NEAR(displacement, displacement2, 1e-2); + EXPECT_NEAR(displacement, displacement2, 5e-2); TestSim sim3; params_base.Enable_FRM = false; params_base.Enable_selective_recalc = false; @@ -270,7 +270,7 @@ namespace SimulationTests { } EXPECT_EQ(200000, sim3.getN_objects_created()); double displacement3 = vector_avg(sim3.displacement_data); - EXPECT_NEAR(displacement, displacement3, 1e-2); + EXPECT_NEAR(displacement, displacement3, 5e-2); } } From c3cd650d289dc3cde5bb5e9a17e3b04955d33a90 Mon Sep 17 00:00:00 2001 From: "Michael C. Heiber" Date: Thu, 10 May 2018 18:41:28 -0400 Subject: [PATCH 23/37] Lattice Class Update -added a chooseRandomNearestNeighbor function to random pick a nearest neighbor of the current coordinates, which could be a generally valuable function for building KMC simulations --- src/Lattice.cpp | 36 ++++++++++++++++++++++++++++++++++++ src/Lattice.h | 6 ++++++ 2 files changed, 42 insertions(+) diff --git a/src/Lattice.cpp b/src/Lattice.cpp index 7f660bf..e75c67f 100644 --- a/src/Lattice.cpp +++ b/src/Lattice.cpp @@ -144,6 +144,42 @@ bool Lattice::checkMoveValidity(const Coords& coords_initial, const int i, const return true; } +Coords Lattice::chooseRandomNearestNeighbor(const Coords& coords_i) { + int i = 0, j = 0, k = 0; + uniform_int_distribution<> dist(0, 5); + while (1) { + int rand_num = dist(*gen_ptr); + switch (rand_num) { + case 0: + i = -1; + break; + case 1: + i = 1; + break; + case 2: + j = -1; + break; + case 3: + j = 1; + break; + case 4: + k = -1; + break; + case 5: + k = 1; + break; + default: + break; + } + if (checkMoveValidity(coords_i, i, j, k)) { + break; + } + } + Coords coords_f; + calculateDestinationCoords(coords_i, i, j, k, coords_f); + return coords_f; +} + void Lattice::clearOccupancy(const Coords& coords) { site_ptrs[getSiteIndex(coords)]->clearOccupancy(); } diff --git a/src/Lattice.h b/src/Lattice.h index 1636f81..8ac8cac 100644 --- a/src/Lattice.h +++ b/src/Lattice.h @@ -126,6 +126,12 @@ class Lattice{ //! \return false if a move event is not possible. bool checkMoveValidity(const Coords& coords_initial, const int i, const int j, const int k) const; + //! \brief Randomly selects a valid nearest neighbor site + //! \details Will choose a site across a periodic boundary if periodic boundaries are enabled. + //! \param coords_i is the Coords struct that designates the starting coordinates. + //! \return a Coords struct that represents the selected nearest neighbor site. + Coords chooseRandomNearestNeighbor(const Coords& coords_i); + //! \brief Clears the occupancy of the site located at the specified coordinates. //! \param coords is the Coords struct that represents the coordinates of the site to be cleared. void clearOccupancy(const Coords& coords); From fe02ff2d0b7f60cdc4ae50605c3da086fe905cae Mon Sep 17 00:00:00 2001 From: "Michael C. Heiber" Date: Thu, 10 May 2018 18:42:51 -0400 Subject: [PATCH 24/37] Utils Update -replaced malloc dynamic memory allocation with new to conform to prefered C++ style and corrected deallocation statements --- src/Utils.cpp | 66 +++++++++++++++++++++++++-------------------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/src/Utils.cpp b/src/Utils.cpp index 775cfba..b24c87e 100644 --- a/src/Utils.cpp +++ b/src/Utils.cpp @@ -165,11 +165,11 @@ namespace Utils { MPI_Comm_size(MPI_COMM_WORLD, &nproc); vector output_vector; if (procid == 0) { - data_sizes = (int *)malloc(sizeof(int)*nproc); + data_sizes = new int[nproc]; } data_size = (int)input_vector.size(); - data = (double *)malloc(sizeof(double)*data_size); - for (int i = 0; i < (int)input_vector.size(); i++) { + data = new double[data_size]; + for (int i = 0; i < data_size; i++) { data[i] = input_vector[i]; } MPI_Gather(&data_size, 1, MPI_INT, data_sizes, 1, MPI_INT, 0, MPI_COMM_WORLD); @@ -177,8 +177,8 @@ namespace Utils { for (int i = 0; i < nproc; i++) { data_count += data_sizes[i]; } - data_all = (double *)malloc(sizeof(double)*data_count); - data_displacement = (int *)malloc(sizeof(int)*nproc); + data_all = new double[data_count]; + data_displacement = new int[nproc]; data_displacement[0] = 0; for (int i = 1; i < nproc; i++) { data_displacement[i] = data_displacement[i - 1] + data_sizes[i - 1]; @@ -202,10 +202,10 @@ namespace Utils { output_vector.push_back(average); } } - delete data; - delete data_all; - delete data_sizes; - delete data_displacement; + delete[] data; + delete[] data_all; + delete[] data_sizes; + delete[] data_displacement; return output_vector; } @@ -217,8 +217,8 @@ namespace Utils { int procid; MPI_Comm_rank(MPI_COMM_WORLD, &procid); data_size = (int)input_vector.size(); - data = (double *)malloc(sizeof(double)*data_size); - sum = (double *)malloc(sizeof(double)*data_size); + data = new double[data_size]; + sum = new double[data_size]; for (int i = 0; i < (int)input_vector.size(); i++) { data[i] = input_vector[i]; } @@ -228,8 +228,8 @@ namespace Utils { output_vector.push_back(sum[i]); } } - delete data; - delete sum; + delete[] data; + delete[] sum; return output_vector; } @@ -241,8 +241,8 @@ namespace Utils { int procid; MPI_Comm_rank(MPI_COMM_WORLD, &procid); data_size = (int)input_vector.size(); - data = (int *)malloc(sizeof(int)*data_size); - sum = (int *)malloc(sizeof(int)*data_size); + data = new int[data_size]; + sum = new int[data_size]; for (int i = 0; i < (int)input_vector.size(); i++) { data[i] = input_vector[i]; } @@ -252,8 +252,8 @@ namespace Utils { output_vector.push_back(sum[i]); } } - delete data; - delete sum; + delete[] data; + delete[] sum; return output_vector; } @@ -270,10 +270,10 @@ namespace Utils { MPI_Comm_rank(MPI_COMM_WORLD, &procid); MPI_Comm_size(MPI_COMM_WORLD, &nproc); if (procid == 0) { - data_sizes = (int *)malloc(sizeof(int)*nproc); + data_sizes = new int[nproc]; } data_size = (int)input_vector.size(); - data = (double *)malloc(sizeof(double)*data_size); + data = new double[data_size]; for (int i = 0; i < (int)input_vector.size(); i++) { data[i] = input_vector[i]; } @@ -282,8 +282,8 @@ namespace Utils { for (int i = 0; i < nproc; i++) { data_count += data_sizes[i]; } - data_all = (double *)malloc(sizeof(double)*data_count); - data_displacement = (int *)malloc(sizeof(int)*nproc); + data_all = new double[data_count]; + data_displacement = new int[nproc]; data_displacement[0] = 0; for (int i = 1; i < nproc; i++) { data_displacement[i] = data_displacement[i - 1] + data_sizes[i - 1]; @@ -295,10 +295,10 @@ namespace Utils { output_vector.push_back(data_all[i]); } } - delete data; - delete data_all; - delete data_sizes; - delete data_displacement; + delete[] data; + delete[] data_all; + delete[] data_sizes; + delete[] data_displacement; return output_vector; } @@ -315,10 +315,10 @@ namespace Utils { MPI_Comm_rank(MPI_COMM_WORLD, &procid); MPI_Comm_size(MPI_COMM_WORLD, &nproc); if (procid == 0) { - data_sizes = (int *)malloc(sizeof(int)*nproc); + data_sizes = new int[nproc]; } data_size = (int)input_vector.size(); - data = (int *)malloc(sizeof(int)*data_size); + data = new int[data_size]; for (int i = 0; i < (int)input_vector.size(); i++) { data[i] = input_vector[i]; } @@ -327,8 +327,8 @@ namespace Utils { for (int i = 0; i < nproc; i++) { data_count += data_sizes[i]; } - data_all = (int *)malloc(sizeof(int)*data_count); - data_displacement = (int *)malloc(sizeof(int)*nproc); + data_all = new int[data_count]; + data_displacement = new int[nproc]; data_displacement[0] = 0; for (int i = 1; i < nproc; i++) { data_displacement[i] = data_displacement[i - 1] + data_sizes[i - 1]; @@ -340,10 +340,10 @@ namespace Utils { output_vector.push_back(data_all[i]); } } - delete data; - delete data_all; - delete data_sizes; - delete data_displacement; + delete[] data; + delete[] data_all; + delete[] data_sizes; + delete[] data_displacement; return output_vector; } From f18d4c69a4606b5d495ce0c7815161da5ab44fc7 Mon Sep 17 00:00:00 2001 From: "Michael C. Heiber" Date: Thu, 10 May 2018 22:46:10 -0400 Subject: [PATCH 25/37] Simulation Class Update -refactored a number of functions to use C++11 container operation functions with lambdas instead of traditional loops to make code more concise a potentially faster as well --- src/Simulation.cpp | 57 ++++++++++++++++------------------------------ 1 file changed, 19 insertions(+), 38 deletions(-) diff --git a/src/Simulation.cpp b/src/Simulation.cpp index b14c329..3c8f6e5 100644 --- a/src/Simulation.cpp +++ b/src/Simulation.cpp @@ -102,18 +102,12 @@ vector Simulation::findRecalcObjects(const Coords& coords_start, const } vector Simulation::findRecalcNeighbors(const Coords& coords) const { - vector neighbor_ptrs; - neighbor_ptrs.reserve(10); - Coords coords2; const static int recalc_cutoff_sq_lat = (int)((Recalc_cutoff / lattice.getUnitSize())*(Recalc_cutoff / lattice.getUnitSize())); - int distance_sq_lat; - for (auto const &item : object_ptrs) { - coords2 = item->getCoords(); - distance_sq_lat = lattice.calculateLatticeDistanceSquared(coords, coords2); - if (distance_sq_lat <= recalc_cutoff_sq_lat) { - neighbor_ptrs.push_back(item); - } - } + vector neighbor_ptrs(object_ptrs.size()); + auto it = copy_if(object_ptrs.begin(), object_ptrs.end(), neighbor_ptrs.begin(), [this,&coords](Object* element) { + return lattice.calculateLatticeDistanceSquared(coords, element->getCoords()) <= recalc_cutoff_sq_lat; + }); + neighbor_ptrs.resize(std::distance(neighbor_ptrs.begin(), it)); return neighbor_ptrs; } @@ -144,13 +138,9 @@ int Simulation::getId() const { } int Simulation::getN_events() const { - int count = 0; - for (auto const &item : event_ptrs) { - if (item!=nullptr && item->getExecutionTime() > 0) { - count++; - } - } - return count; + return count_if(event_ptrs.begin(), event_ptrs.end(), [](Event* element) { + return (element != nullptr && element->getExecutionTime() > 0); + }); } long int Simulation::getN_events_executed() const { @@ -199,15 +189,11 @@ double Simulation::rand01() { } void Simulation::removeEvent(Event* event_ptr) { - bool success = false; - for (auto it = event_ptrs.begin(); it != event_ptrs.end(); ++it) { - if (*it == event_ptr) { - event_ptrs.erase(it); - success = true; - break; - } + auto it = find_if(event_ptrs.begin(), event_ptrs.end(), [event_ptr](Event* element) {return element == event_ptr;}); + if (it != event_ptrs.end()) { + event_ptrs.erase(it); } - if (!success) { + else{ cout << "Error! The Event pointer could not be found in the event list and could not be removed." << endl; Error_found = true; } @@ -219,21 +205,17 @@ void Simulation::removeObject(Object* object_ptr) { // Delete the event pointer removeEvent(*object_ptr->getEventIt()); // Delete the object pointer - bool success = false; - for (auto it = object_ptrs.begin(); it != object_ptrs.end(); ++it){ - if (*it == object_ptr) { - object_ptrs.erase(it); - success = true; - break; - } + auto it = find_if(object_ptrs.begin(), object_ptrs.end(), [object_ptr](Object* element) {return element == object_ptr; }); + if (it != object_ptrs.end()) { + object_ptrs.erase(it); } - // Update counters - N_events_executed++; - // Error checking - if (!success) { + else { cout << "Error! The Object pointer could not be found in the object list and could not be removed." << endl; Error_found = true; } + // Update counters + N_events_executed++; + } void Simulation::setErrorMessage(const string& input_msg) { @@ -251,4 +233,3 @@ void Simulation::setGeneratorSeed(int seed) { void Simulation::setTime(const double new_time){ time_sim = new_time; } - From 1d74dd9dc8ba008b14986b3550c15c7016bf5b2a Mon Sep 17 00:00:00 2001 From: "Michael C. Heiber" Date: Fri, 11 May 2018 10:31:11 -0400 Subject: [PATCH 26/37] Lattice Class Correction -corrected bug in chooseRandomNearestNeighbor function where i,j,k was not being reset following the selection of an invalid site --- src/Lattice.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Lattice.cpp b/src/Lattice.cpp index e75c67f..8c9e30f 100644 --- a/src/Lattice.cpp +++ b/src/Lattice.cpp @@ -148,6 +148,9 @@ Coords Lattice::chooseRandomNearestNeighbor(const Coords& coords_i) { int i = 0, j = 0, k = 0; uniform_int_distribution<> dist(0, 5); while (1) { + i = 0; + j = 0; + k = 0; int rand_num = dist(*gen_ptr); switch (rand_num) { case 0: From 092984d853bbedc326e4516255493f0a558b3b3b Mon Sep 17 00:00:00 2001 From: "Michael C. Heiber" Date: Fri, 11 May 2018 16:19:16 -0400 Subject: [PATCH 27/37] Utils Template Functions Update -refactored template functions for calculating average and stdev of vector data to use container operations for more concise code and potential speed improvements --- src/Utils.h | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/Utils.h b/src/Utils.h index 6001bae..e9b408a 100644 --- a/src/Utils.h +++ b/src/Utils.h @@ -265,7 +265,7 @@ namespace Utils { } //! \brief This template function efficienctly removes the duplicate entries from an input vector. - //! \details This algorithm allow efficient removal of duplicate vector objects when > or < comparison operators do not exist. + //! \details This algorithm allows efficient removal of duplicate vector objects when > or < comparison operators do not exist. //! \param vec is the input vector to be operated on. template void removeDuplicates(std::vector &vec) { @@ -289,11 +289,7 @@ namespace Utils { //! \return The average of the data set in double format. template double vector_avg(const std::vector& data) { - double sum = 0; - for (auto const &item : data) { - sum += item; - } - return sum / data.size(); + return accumulate(data.begin(), data.end(), 0.0) / (double)data.size(); } //! \brief This template function calculates and returns the standard deviation in double format when given a vector of numerical datatypes. @@ -301,12 +297,11 @@ namespace Utils { //! \return The standard deviation of the data set in double format. template double vector_stdev(const std::vector& data) { - double sum = 0; double avg = vector_avg(data); - for (auto const &item : data) { - sum += (item - avg)*(item - avg); - } - return sqrt(sum / (data.size() - 1)); + double sum = accumulate(data.begin(), data.end(), 0.0, [avg](double& x, const T& element) { + return x + (element - avg)*(element - avg); + }); + return sqrt(sum / (double)((int)data.size() - 1)); } } From d9f1e0108d466d1a5498585009e2ba44941bdc0c Mon Sep 17 00:00:00 2001 From: "Michael C. Heiber" Date: Fri, 11 May 2018 16:21:22 -0400 Subject: [PATCH 28/37] Lattice Class Update -renamed chooseRandomNearestNeighbor to chooseRandomUnoccupiedNeighbor and updated the functionality so that it checks for lattice site occupancy before returning the site coords -refactored calculateDX, calculateDY, and calculateDZ functions to be more concise --- src/Lattice.cpp | 70 ++++++++++++++++++++++++++----------------------- src/Lattice.h | 7 ++--- 2 files changed, 41 insertions(+), 36 deletions(-) diff --git a/src/Lattice.cpp b/src/Lattice.cpp index 8c9e30f..e9a0f82 100644 --- a/src/Lattice.cpp +++ b/src/Lattice.cpp @@ -144,43 +144,50 @@ bool Lattice::checkMoveValidity(const Coords& coords_initial, const int i, const return true; } -Coords Lattice::chooseRandomNearestNeighbor(const Coords& coords_i) { - int i = 0, j = 0, k = 0; - uniform_int_distribution<> dist(0, 5); - while (1) { - i = 0; - j = 0; - k = 0; - int rand_num = dist(*gen_ptr); - switch (rand_num) { - case 0: +Coords Lattice::chooseRandomUnoccupiedNeighbor(const Coords& coords_i) { + vector coords_vec; + coords_vec.reserve(6); + Coords coords_f; + for (int n = 0; n < 6; n++) { + int i = 0; + int j = 0; + int k = 0; + if (n == 0) { i = -1; - break; - case 1: + } + else if (n == 1) { i = 1; - break; - case 2: + } + else if (n == 2) { j = -1; - break; - case 3: + } + else if (n == 3) { j = 1; - break; - case 4: + } + else if (n == 4) { k = -1; - break; - case 5: + } + else if (n == 5) { k = 1; - break; - default: - break; } if (checkMoveValidity(coords_i, i, j, k)) { - break; + calculateDestinationCoords(coords_i, i, j, k, coords_f); + if (!isOccupied(coords_f)) { + coords_vec.push_back(coords_f); + } } + } + if ((int)coords_vec.size() == 1) { + return coords_vec[0]; + } + else if ((int)coords_vec.size()>1) { + uniform_int_distribution<> dist(0, (int)coords_vec.size()-1); + return coords_vec[dist(*gen_ptr)]; + } + else { + coords_f = { -1,-1,-1 }; + return coords_f; } - Coords coords_f; - calculateDestinationCoords(coords_i, i, j, k, coords_f); - return coords_f; } void Lattice::clearOccupancy(const Coords& coords) { @@ -197,20 +204,17 @@ Coords Lattice::generateRandomCoords() { int Lattice::generateRandomX() { uniform_int_distribution distx(0, Length - 1); - auto randx = bind(distx, ref(*gen_ptr)); - return randx(); + return distx(*gen_ptr); } int Lattice::generateRandomY() { uniform_int_distribution disty(0, Width - 1); - auto randy = bind(disty, ref(*gen_ptr)); - return randy(); + return disty(*gen_ptr); } int Lattice::generateRandomZ() { uniform_int_distribution distz(0, Height - 1); - auto randz = bind(distz, ref(*gen_ptr)); - return randz(); + return distz(*gen_ptr); } int Lattice::getHeight() const{ diff --git a/src/Lattice.h b/src/Lattice.h index 8ac8cac..d410b2e 100644 --- a/src/Lattice.h +++ b/src/Lattice.h @@ -126,11 +126,12 @@ class Lattice{ //! \return false if a move event is not possible. bool checkMoveValidity(const Coords& coords_initial, const int i, const int j, const int k) const; - //! \brief Randomly selects a valid nearest neighbor site + //! \brief Randomly selects a valid, unoccupied nearest neighbor site //! \details Will choose a site across a periodic boundary if periodic boundaries are enabled. //! \param coords_i is the Coords struct that designates the starting coordinates. - //! \return a Coords struct that represents the selected nearest neighbor site. - Coords chooseRandomNearestNeighbor(const Coords& coords_i); + //! \return a Coords struct that represents the selected unoccupied nearest neighbor site. + //! \return {-1,-1,-1} if there is no valid unoccupied neighbor + Coords chooseRandomUnoccupiedNeighbor(const Coords& coords_i); //! \brief Clears the occupancy of the site located at the specified coordinates. //! \param coords is the Coords struct that represents the coordinates of the site to be cleared. From 481ccc180821e4416ddcae2f35f479f33cfe18d7 Mon Sep 17 00:00:00 2001 From: "Michael C. Heiber" Date: Fri, 11 May 2018 16:22:03 -0400 Subject: [PATCH 29/37] Object Class Update -updated calculateDisplacement function to remove unneeded double cast --- src/Object.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Object.cpp b/src/Object.cpp index e9df691..0e78856 100644 --- a/src/Object.cpp +++ b/src/Object.cpp @@ -25,7 +25,7 @@ Object::Object(const double time,const int tag_num,const Coords& start_coords){ } double Object::calculateDisplacement() const{ - return sqrt((double)(coords_current.x+dx-coords_initial.x)*(coords_current.x+dx-coords_initial.x)+(coords_current.y+dy-coords_initial.y)*(coords_current.y+dy-coords_initial.y)+(coords_current.z+dz-coords_initial.z)*(coords_current.z+dz-coords_initial.z)); + return sqrt((coords_current.x+dx-coords_initial.x)*(coords_current.x+dx-coords_initial.x)+(coords_current.y+dy-coords_initial.y)*(coords_current.y+dy-coords_initial.y)+(coords_current.z+dz-coords_initial.z)*(coords_current.z+dz-coords_initial.z)); } Coords Object::getCoords() const{ From fd5b93d3b50061e18b01ddf910ab0e89783a16b9 Mon Sep 17 00:00:00 2001 From: "Michael C. Heiber" Date: Mon, 14 May 2018 22:20:19 -0400 Subject: [PATCH 30/37] Random Number Generator Update -updated to 64 bit mersenne twister --- src/Lattice.cpp | 8 ++++---- src/Lattice.h | 4 ++-- src/Simulation.h | 2 +- src/Utils.cpp | 4 ++-- src/Utils.h | 4 ++-- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/Lattice.cpp b/src/Lattice.cpp index e9a0f82..4af43d7 100644 --- a/src/Lattice.cpp +++ b/src/Lattice.cpp @@ -12,7 +12,7 @@ Lattice::Lattice() { } -void Lattice::init(const Parameters_Lattice& params, mt19937* generator_ptr) { +void Lattice::init(const Parameters_Lattice& params, mt19937_64* generator_ptr) { Enable_periodic_x = params.Enable_periodic_x; Enable_periodic_y = params.Enable_periodic_y; Enable_periodic_z = params.Enable_periodic_z; @@ -176,12 +176,12 @@ Coords Lattice::chooseRandomUnoccupiedNeighbor(const Coords& coords_i) { coords_vec.push_back(coords_f); } } - } + } if ((int)coords_vec.size() == 1) { return coords_vec[0]; } - else if ((int)coords_vec.size()>1) { - uniform_int_distribution<> dist(0, (int)coords_vec.size()-1); + else if ((int)coords_vec.size() > 1) { + uniform_int_distribution<> dist(0, (int)coords_vec.size() - 1); return coords_vec[dist(*gen_ptr)]; } else { diff --git a/src/Lattice.h b/src/Lattice.h index d410b2e..bbb4a54 100644 --- a/src/Lattice.h +++ b/src/Lattice.h @@ -48,7 +48,7 @@ class Lattice{ //! \param params is a Parameters_Lattice struct that contains all of the required //! parameters to initialize the Lattice object. //! \param generator_ptr is a pointer to a Mersenne twister number generator. - void init(const Parameters_Lattice& params, std::mt19937* generator_ptr); + void init(const Parameters_Lattice& params, std::mt19937_64* generator_ptr); //! \brief Calculates the destination coordinates when given the starting coordinates and the displacement vector (i,j,k). //! \details When the starting coordinates are near one or more of the lattice boundaries and periodic boundary conditions are enabled, @@ -239,7 +239,7 @@ class Lattice{ int Height; // nm double Unit_size; // nm std::vector site_ptrs; - std::mt19937* gen_ptr; + std::mt19937_64* gen_ptr; }; #endif // LATTICE_H diff --git a/src/Simulation.h b/src/Simulation.h index 9942a7b..b94acaf 100644 --- a/src/Simulation.h +++ b/src/Simulation.h @@ -131,7 +131,7 @@ class Simulation{ protected: //! Mersenne Twister random number generator - std::mt19937 generator; + std::mt19937_64 generator; //! Pointer to an output file stream that is used to print log messages to a logfile when logging is enabled. std::ofstream* Logfile; //! The Lattice object represents a three-dimensional lattice, its boundary conditions, and its occupancy. diff --git a/src/Utils.cpp b/src/Utils.cpp index b24c87e..5966e05 100644 --- a/src/Utils.cpp +++ b/src/Utils.cpp @@ -89,7 +89,7 @@ namespace Utils { return hist; } - void createExponentialDOSVector(std::vector& data, const double mode, const double urbach_energy, std::mt19937& gen) { + void createExponentialDOSVector(std::vector& data, const double mode, const double urbach_energy, std::mt19937_64& gen) { exponential_distribution dist_exp(1.0 / urbach_energy); auto rand_exp = bind(dist_exp, ref(gen)); normal_distribution dist_gaus(0, 2.0*urbach_energy / sqrt(2.0 * Pi)); @@ -106,7 +106,7 @@ namespace Utils { } } - void createGaussianDOSVector(std::vector& data, const double mean, const double stdev, std::mt19937& gen) { + void createGaussianDOSVector(std::vector& data, const double mean, const double stdev, std::mt19937_64& gen) { normal_distribution dist(mean, stdev); auto rand_gaus = bind(dist, ref(gen)); for (auto &item : data) { diff --git a/src/Utils.h b/src/Utils.h index e9b408a..62d4b74 100644 --- a/src/Utils.h +++ b/src/Utils.h @@ -112,14 +112,14 @@ namespace Utils { //! \param mode is the value of the peak of the distribution. //! \param urbach_energy is the parameter that detemines the shape of the exponential tail side of the distribution. //! \param gen is a Mersenne twister random number generator used to randomly draw numbers from the distribution. - void createExponentialDOSVector(std::vector& data, const double mode, const double urbach_energy, std::mt19937& gen); + void createExponentialDOSVector(std::vector& data, const double mode, const double urbach_energy, std::mt19937_64& gen); //! \brief Creates a vector of doubles that has a Gaussian distribution. //! \param data is the data vector where the numbers will be placed, which must be preallocated to the desired size. //! \param mean is the position of the peak and center of the distribution. //! \param stdev is the standard deviation of the distribution, which defines the width of the peak. //! \param gen is a Mersenne twister random number generator used to randomly draw numbers from the distribution. - void createGaussianDOSVector(std::vector& data, const double mean, const double stdev, std::mt19937& gen); + void createGaussianDOSVector(std::vector& data, const double mean, const double stdev, std::mt19937_64& gen); //! \brief Extracts a boolean value from a string containing "true" or "false". //! \param input is the input string. From e82723ed2983e81a4d4033e58beeb92fa0cd2b74 Mon Sep 17 00:00:00 2001 From: "Michael C. Heiber" Date: Mon, 14 May 2018 22:22:03 -0400 Subject: [PATCH 31/37] Simulation Class Testing Update -simplified TestSim class to test random walk simulations -added tests to verify correct random walk simulations --- test/test.cpp | 489 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 344 insertions(+), 145 deletions(-) diff --git a/test/test.cpp b/test/test.cpp index c998df3..ff129ac 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -26,28 +26,26 @@ class TestSim : public Simulation { MoveEvent(Simulation* simulation_ptr) : Event(simulation_ptr) {} string getEventType() const { return "Move"; } }; - class TerminationEvent : public Event { - public: - TerminationEvent() : Event() {} - TerminationEvent(Simulation* simulation_ptr) : Event(simulation_ptr) {} - string getEventType() const { return "Termination"; } - }; // Data members list objects; list sites; CreationEvent event_creation; list events_move; - list events_termination; Event event_previous; string event_previous_type; + Coords coords_creation; + int N_tests = 1; + int N_steps = 1; + double k_move = 1.0; int N_move_events = 0; int N_termination_events = 0; + vector move_counts; vector displacement_data; - bool init(const Parameters_Simulation& params, const int id) { + bool init(const Parameters_Simulation& params) { // Initialize Simulation base class - Simulation::init(params, id); + Simulation::init(params, 0); // Initialize Sites Site site; sites.assign(lattice.getNumSites(), site); @@ -57,132 +55,111 @@ class TestSim : public Simulation { } lattice.setSitePointers(site_ptrs); // Perform test initialization + coords_creation = { lattice.getLength() / 2, lattice.getWidth() / 2, lattice.getHeight() / 2 }; CreationEvent event_creation_new(this); event_creation = event_creation_new; - event_creation.setDestCoords(lattice.generateRandomCoords()); - event_creation.calculateExecutionTime(1.0); + event_creation.calculateExecutionTime(0.01); addEvent(&event_creation); + // Reserve memory + displacement_data.reserve(N_tests); + move_counts.reserve(N_tests); return true; } void calculateNextEvent(Object* object_ptr) { auto move_event_it = find_if(events_move.begin(), events_move.end(), [object_ptr](MoveEvent& a) { return a.getObjectPtr() == object_ptr; }); - auto termination_event_it = find_if(events_termination.begin(), events_termination.end(), [object_ptr](TerminationEvent& a) { return a.getObjectPtr() == object_ptr; }); - // Calculate move events - move_event_it->calculateExecutionTime(100); + move_event_it->calculateExecutionTime(k_move); Coords coords_i = object_ptr->getCoords(); - Coords coords_f; - int i = 0, j = 0, k = 0; - uniform_int_distribution<> dist(0, 5); - int rand_num = dist(generator); - switch (rand_num) { - case 0: - i = -1; - break; - case 1: - i = 1; - break; - case 2: - j = -1; - break; - case 3: - j = 1; - break; - case 4: - k = -1; - break; - case 5: - k = 1; - break; - default: - i = 1; - break; - } - lattice.calculateDestinationCoords(coords_i, i, j, k, coords_f); - move_event_it->setDestCoords(coords_f); - // Calculate termination event - termination_event_it->setDestCoords(coords_i); - termination_event_it->calculateExecutionTime(10); - // Select fastest event - if (move_event_it->getExecutionTime() < termination_event_it->getExecutionTime()) { - setObjectEvent(object_ptr, &(*move_event_it)); + Coords coords_f = lattice.chooseRandomUnoccupiedNeighbor(coords_i); + if (coords_f.x == -1) { + setObjectEvent(object_ptr, nullptr); } else { - setObjectEvent(object_ptr, &(*termination_event_it)); + move_event_it->setDestCoords(coords_f); + setObjectEvent(object_ptr, &(*move_event_it)); } } bool checkFinished() const { - return (getN_objects_created() == 200000); + return (getN_objects_created() == N_tests); } - void executeCreationEvent(const std::list::const_iterator event_it) { - Event* event_ptr = *event_it; - Coords coords_dest = event_ptr->getDestCoords(); - Object object(event_ptr->getExecutionTime(),getN_objects_created()+1,coords_dest); - objects.push_back(object); - addObject(&objects.back()); - Simulation* sim_ptr = this; - MoveEvent event1(sim_ptr); - event1.setObjectPtr(&objects.back()); - events_move.push_back(event1); - TerminationEvent event2(sim_ptr); - event2.setObjectPtr(&objects.back()); - events_termination.push_back(event2); + Coords executeCreationEvent() { + Coords coords_dest = coords_creation; + if(lattice.isOccupied(coords_dest)) { + coords_dest = lattice.chooseRandomUnoccupiedNeighbor(coords_dest); + } + if (coords_dest.x != -1) { + Object object(getTime(), getN_objects_created(), coords_dest); + objects.push_back(object); + addObject(&objects.back()); + Simulation* sim_ptr = this; + MoveEvent event1(sim_ptr); + event1.setObjectPtr(&objects.back()); + events_move.push_back(event1); + move_counts.push_back(0); + } // Calculate next creation event - event_creation.setDestCoords(lattice.generateRandomCoords()); - event_creation.calculateExecutionTime(1.0); + event_creation.calculateExecutionTime(0.01); + return coords_dest; } void executeMoveEvent(const std::list::const_iterator event_it) { Event* event_ptr = *event_it; moveObject(event_ptr->getObjectPtr(), event_ptr->getDestCoords()); + move_counts[event_ptr->getObjectPtr()->getTag()]++; N_move_events++; } bool executeNextEvent() { + // Check if any objects are finished + for (auto& item : objects) { + if (move_counts[item.getTag()]==N_steps) { + displacement_data.push_back(item.calculateDisplacement()); + executeTerminationEvent(&item); + break; + } + } auto event_it = chooseNextEvent(); Event* event_ptr = *event_it; string event_type = event_ptr->getEventType(); event_previous = *event_ptr; - event_previous_type = event_type; + event_previous_type = event_ptr->getEventType(); Coords coords_i; Coords coords_f = event_ptr->getDestCoords(); setTime(event_ptr->getExecutionTime()); - if (event_type.compare("Creation")==0) { - executeCreationEvent(event_it); + if (event_type.compare("Creation") == 0) { + coords_f = executeCreationEvent(); coords_i = coords_f; } else { coords_i = event_ptr->getObjectPtr()->getCoords(); - if (event_type.compare("Move")==0) { + coords_f = event_ptr->getDestCoords(); + if (event_type.compare("Move") == 0) { executeMoveEvent(event_it); } - else if (event_type.compare("Termination")==0) { - Object* object_ptr = (*event_it)->getObjectPtr(); - displacement_data.push_back(object_ptr->calculateDisplacement()); - executeTerminationEvent(event_it); - } else { return false; } } - auto object_vec = findRecalcObjects(coords_i, coords_f); - for (auto item : object_vec) { - calculateNextEvent(item); + if (coords_f.x != -1) { + auto object_vec = findRecalcObjects(coords_i, coords_f); + for (auto item : object_vec) { + calculateNextEvent(item); + } } return true; } - void executeTerminationEvent(const std::list::const_iterator event_it) { - Object* object_ptr = (*event_it)->getObjectPtr(); + void executeTerminationEvent(Object* object_ptr) { // Remove object from Simulation class removeObject(object_ptr); - // Remove local events + // Remove local move event auto move_event_it = find_if(events_move.begin(), events_move.end(), [object_ptr](MoveEvent& a) { return a.getObjectPtr() == object_ptr; }); events_move.erase(move_event_it); - auto termination_event_it = find_if(events_termination.begin(), events_termination.end(), [object_ptr](TerminationEvent& a) { return a.getObjectPtr() == object_ptr; }); - events_termination.erase(termination_event_it); + // Remove local object + auto object_it = find_if(objects.begin(), objects.end(), [object_ptr](Object& a) { return a.getTag() == object_ptr->getTag(); }); + objects.erase(object_it); N_termination_events++; } @@ -193,7 +170,10 @@ class TestSim : public Simulation { vector getAllEventPtrs() const { return getAllEventPtrs(); } - + + Coords getRandomCoords() { + return lattice.generateRandomCoords(); + } }; namespace SimulationTests { @@ -208,9 +188,9 @@ namespace SimulationTests { params_base.Enable_periodic_x = true; params_base.Enable_periodic_y = true; params_base.Enable_periodic_z = true; - params_base.Length = 50; - params_base.Width = 50; - params_base.Height = 50; + params_base.Length = 200; + params_base.Width = 200; + params_base.Height = 200; params_base.Unit_size = 1.0; params_base.Temperature = 300; params_base.Enable_FRM = false; @@ -219,8 +199,10 @@ namespace SimulationTests { params_base.Enable_full_recalc = false; } // Initialize TestSim object - sim.init(params_base, 0); - sim.setGeneratorSeed(0); + sim.init(params_base); + sim.N_tests = 10000; + sim.N_steps = 500; + sim.k_move = 1000; } }; @@ -229,7 +211,7 @@ namespace SimulationTests { EXPECT_FALSE(sim.isLoggingEnabled()); EXPECT_DOUBLE_EQ(0.0, sim.getTime()); EXPECT_EQ(300, sim.getTemp()); - EXPECT_DOUBLE_EQ(125000e-21, sim.getVolume()); + EXPECT_DOUBLE_EQ(params_base.Length*params_base.Width*params_base.Height*1e-21, sim.getVolume()); } TEST_F(SimulationTest, EventExecutionTests) { @@ -237,42 +219,169 @@ namespace SimulationTests { EXPECT_EQ(1, sim.getN_events()); EXPECT_TRUE(sim.executeNextEvent()); EXPECT_EQ(1, (int)sim.objects.size()); - EXPECT_EQ(1, sim.objects.front().getTag()); + EXPECT_EQ(0, sim.objects.front().getTag()); EXPECT_EQ(2, sim.getN_events()); EXPECT_EQ(1, sim.getN_events_executed()); EXPECT_FALSE(sim.checkFinished()); + // Check event destination coords + vector data(20000); + for (int i = 0; i < 10; i++) { + for (auto& item : data) { + sim.calculateNextEvent(&sim.objects.front()); + item = sim.events_move.front().getDestCoords(); + } + auto site_options(data); + removeDuplicates(site_options); + EXPECT_EQ(6, (int)site_options.size()); + for (auto item : site_options) { + int count = count_if(data.begin(), data.end(), [item](Coords element) {return element == item; }); + EXPECT_NEAR(1.0 / 6.0, (double)count / (double)data.size(), 2e-2); + } + EXPECT_TRUE(sim.executeNextEvent()); + } } - TEST_F(SimulationTest, KMCAlgorithmTests) { + TEST_F(SimulationTest, DisplacementTests) { + params_base.Enable_periodic_x = false; + params_base.Enable_periodic_y = false; + params_base.Enable_periodic_z = false; + params_base.Length = 100; + params_base.Width = 100; + params_base.Height = 100; + TestSim sim2; + sim2.init(params_base); + sim2.coords_creation = sim2.getRandomCoords(); + sim2.N_tests = 1000; + sim2.N_steps = 500; + sim2.k_move = 1000; + double displacement; + vector creation_coords; + EXPECT_TRUE(sim2.executeNextEvent()); + while (!sim2.checkFinished()) { + if (sim2.event_previous_type.compare("Creation") == 0) { + creation_coords.push_back(sim2.objects.back().getCoords()); + EXPECT_TRUE(sim2.coords_creation==creation_coords.back()); + sim2.coords_creation = sim2.getRandomCoords(); + } + Coords coords_i = creation_coords[sim2.objects.front().getTag()]; + Coords coords = sim2.objects.front().getCoords(); + displacement = sim2.objects.front().calculateDisplacement(); + EXPECT_DOUBLE_EQ(sqrt((coords.x-coords_i.x)*(coords.x-coords_i.x) + (coords.y-coords_i.y)*(coords.y-coords_i.y) + (coords.z-coords_i.z)*(coords.z-coords_i.z)), displacement); + EXPECT_TRUE(sim2.executeNextEvent()); + } + } + + TEST_F(SimulationTest, 3DRandomWalkTests) { + // 3D while (!sim.checkFinished()) { EXPECT_TRUE(sim.executeNextEvent()); + if (sim.event_previous.getEventType().compare("Move") == 0) { + EXPECT_EQ(sim.event_previous.getDestCoords(), sim.event_previous.getObjectPtr()->getCoords()); + } } - EXPECT_EQ(200000, sim.getN_objects_created()); + EXPECT_EQ(10000, sim.getN_objects_created()); double displacement = vector_avg(sim.displacement_data); - TestSim sim2; + double dim = 3.0; + double expected_val = sqrt(2.0 * sim.N_steps / dim)*(tgamma((dim + 1.0) / 2.0) / tgamma(dim / 2.0)); + EXPECT_NEAR(expected_val, displacement, 2e-2*expected_val); + } + + TEST_F(SimulationTest, 2DRandomWalkTests) { + // 2D + params_base.Enable_periodic_x = true; + params_base.Enable_periodic_y = true; + params_base.Enable_periodic_z = false; + params_base.Length = 200; + params_base.Width = 200; + params_base.Height = 1; + TestSim sim2D; + sim2D.init(params_base); + sim2D.N_tests = 10000; + sim2D.N_steps = 500; + sim2D.k_move = 1000; + while (!sim2D.checkFinished()) { + EXPECT_TRUE(sim2D.executeNextEvent()); + } + double displacement2D = vector_avg(sim2D.displacement_data); + double dim = 2.0; + double expected_val = sqrt(2.0 * sim2D.N_steps / dim)*(tgamma((dim + 1.0) / 2.0) / tgamma(dim / 2.0)); + EXPECT_NEAR(expected_val, displacement2D, 2e-2*expected_val); + } + + TEST_F(SimulationTest, 1DRandomWalkTests) { + // 1D + params_base.Enable_periodic_x = true; + params_base.Enable_periodic_y = false; + params_base.Enable_periodic_z = false; + params_base.Length = 200; + params_base.Width = 1; + params_base.Height = 1; + TestSim sim1D; + sim1D.init(params_base); + sim1D.N_tests = 10000; + sim1D.N_steps = 500; + sim1D.k_move = 1000; + while (!sim1D.checkFinished()) { + EXPECT_TRUE(sim1D.executeNextEvent()); + } + double displacement1D = vector_avg(sim1D.displacement_data); + double dim = 1.0; + double expected_val = sqrt(2.0 * sim1D.N_steps / dim)*(tgamma((dim + 1.0) / 2.0) / tgamma(dim / 2.0)); + EXPECT_NEAR(expected_val, displacement1D, 2e-2*expected_val); + } + + TEST_F(SimulationTest, AlgorithmTests) { + // Selective recalculation method + sim = TestSim(); + params_base.Enable_FRM = false; + params_base.Enable_selective_recalc = true; + params_base.Recalc_cutoff = 3; + params_base.Enable_full_recalc = false; + params_base.Enable_periodic_x = true; + params_base.Enable_periodic_y = true; + params_base.Enable_periodic_z = true; + params_base.Length = 200; + params_base.Width = 200; + params_base.Height = 200; + sim.init(params_base); + sim.N_tests = 1000; + sim.N_steps = 1000; + sim.k_move = 1000; + while (!sim.checkFinished()) { + EXPECT_TRUE(sim.executeNextEvent()); + } + double displacement1 = vector_avg(sim.displacement_data); + // First reaction method + sim = TestSim(); params_base.Enable_FRM = true; params_base.Enable_selective_recalc = false; params_base.Enable_full_recalc = false; - sim2.init(params_base, 0); - while (!sim2.checkFinished()) { - EXPECT_TRUE(sim2.executeNextEvent()); + sim.init(params_base); + sim.N_tests = 1000; + sim.N_steps = 1000; + sim.k_move = 1000; + while (!sim.checkFinished()) { + EXPECT_TRUE(sim.executeNextEvent()); } - EXPECT_EQ(200000, sim2.getN_objects_created()); - double displacement2 = vector_avg(sim2.displacement_data); - EXPECT_NEAR(displacement, displacement2, 5e-2); - TestSim sim3; + double displacement2 = vector_avg(sim.displacement_data); + // Full recalculation method + sim = TestSim(); params_base.Enable_FRM = false; params_base.Enable_selective_recalc = false; params_base.Enable_full_recalc = true; - sim3.init(params_base, 0); - while (!sim3.checkFinished()) { - EXPECT_TRUE(sim3.executeNextEvent()); + sim.init(params_base); + sim.N_tests = 1000; + sim.N_steps = 1000; + sim.k_move = 1000; + while (!sim.checkFinished()) { + EXPECT_TRUE(sim.executeNextEvent()); } - EXPECT_EQ(200000, sim3.getN_objects_created()); - double displacement3 = vector_avg(sim3.displacement_data); - EXPECT_NEAR(displacement, displacement3, 5e-2); + double displacement3 = vector_avg(sim.displacement_data); + // Check different displacement values + EXPECT_NEAR(displacement1, displacement2, 5e-2*displacement1); + EXPECT_NEAR(displacement1, displacement3, 5e-2*displacement1); + EXPECT_NEAR(displacement2, displacement3, 5e-2*displacement2); } - } namespace UtilsTests { @@ -522,35 +631,35 @@ namespace UtilsTests { } } -namespace LatticeTests{ - +namespace LatticeTests { + class LatticeTest : public ::testing::Test { - protected: - mt19937 gen; - Parameters_Lattice params_lattice; - vector sites; - Lattice lattice; - - void SetUp() { - gen.seed(std::random_device{}()); - // Setup params - params_lattice.Enable_periodic_x = true; - params_lattice.Enable_periodic_y = true; - params_lattice.Enable_periodic_z = true; - params_lattice.Length = 50; - params_lattice.Width = 50; - params_lattice.Height = 50; - params_lattice.Unit_size = 1.0; - // Initialize Lattice object - lattice.init(params_lattice, &gen); - Site site; - sites.assign(lattice.getNumSites(), site); - vector site_ptrs((int)sites.size()); - for (int i = 0; i < (int)sites.size(); i++) { - site_ptrs[i] = &sites[i]; - } - lattice.setSitePointers(site_ptrs); + protected: + mt19937_64 gen; + Parameters_Lattice params_lattice; + vector sites; + Lattice lattice; + + void SetUp() { + gen.seed(std::random_device{}()); + // Setup params + params_lattice.Enable_periodic_x = true; + params_lattice.Enable_periodic_y = true; + params_lattice.Enable_periodic_z = true; + params_lattice.Length = 50; + params_lattice.Width = 50; + params_lattice.Height = 50; + params_lattice.Unit_size = 1.0; + // Initialize Lattice object + lattice.init(params_lattice, &gen); + Site site; + sites.assign(lattice.getNumSites(), site); + vector site_ptrs((int)sites.size()); + for (int i = 0; i < (int)sites.size(); i++) { + site_ptrs[i] = &sites[i]; } + lattice.setSitePointers(site_ptrs); + } }; TEST_F(LatticeTest, InitializationTests) { @@ -559,7 +668,7 @@ namespace LatticeTests{ EXPECT_EQ(50, lattice.getHeight()); EXPECT_DOUBLE_EQ(1.0, lattice.getUnitSize()); EXPECT_EQ((long int)50 * 50 * 50, lattice.getNumSites()); - EXPECT_DOUBLE_EQ(125000e-21,lattice.getVolume()); + EXPECT_DOUBLE_EQ(125000e-21, lattice.getVolume()); } TEST_F(LatticeTest, CalculateDestCoordsTests) { @@ -597,8 +706,8 @@ namespace LatticeTests{ EXPECT_EQ(lattice.calculateDX(coords_i, coords_f), 0); EXPECT_EQ(lattice.calculateDY(coords_i, coords_f), 50); EXPECT_EQ(lattice.calculateDZ(coords_i, coords_f), -50); - coords_i = {1, 49, 0}; - coords_f = {0, 0, 49}; + coords_i = { 1, 49, 0 }; + coords_f = { 0, 0, 49 }; EXPECT_EQ(lattice.calculateDX(coords_i, coords_f), 0); EXPECT_EQ(lattice.calculateDY(coords_i, coords_f), -50); EXPECT_EQ(lattice.calculateDZ(coords_i, coords_f), 50); @@ -653,6 +762,95 @@ namespace LatticeTests{ EXPECT_NEAR(lattice.getHeight() / sqrt(12.0), vector_stdev(zcoords), 1e-2); } + TEST_F(LatticeTest, RandomUnoccupiedNeighborTests) { + vector data(30000); + for (int i = 0; i < 8; i++) { + Coords coords = lattice.generateRandomCoords(); + for (auto& item : data) { + Coords coords_new = lattice.chooseRandomUnoccupiedNeighbor(coords); + EXPECT_FALSE(coords_new == coords); + item = lattice.getSiteIndex(coords_new); + } + auto site_options(data); + removeDuplicates(site_options); + EXPECT_EQ(6, (int)site_options.size()); + for (auto item : site_options) { + int count = count_if(data.begin(), data.end(), [item](int element) {return element == item; }); + EXPECT_NEAR(1.0 / 6.0, (double)count/(double)data.size(), 1e-2); + } + } + } + + TEST_F(LatticeTest, 2DTests) { + // Initialize 2D Lattice object + params_lattice.Enable_periodic_x = true; + params_lattice.Enable_periodic_y = true; + params_lattice.Enable_periodic_z = false; + params_lattice.Length = 50; + params_lattice.Width = 50; + params_lattice.Height = 1; + params_lattice.Unit_size = 1.0; + Lattice lattice2D; + lattice2D.init(params_lattice, &gen); + Site site; + sites.assign(lattice2D.getNumSites(), site); + vector site_ptrs((int)sites.size()); + for (int i = 0; i < (int)sites.size(); i++) { + site_ptrs[i] = &sites[i]; + } + lattice2D.setSitePointers(site_ptrs); + // Check random neighbor site generation in 2D + vector data(30000); + for (int i = 0; i < 8; i++) { + Coords coords = lattice2D.generateRandomCoords(); + for (auto& item : data) { + item = lattice2D.getSiteIndex(lattice2D.chooseRandomUnoccupiedNeighbor(coords)); + } + auto site_options(data); + removeDuplicates(site_options); + EXPECT_EQ(4, (int)site_options.size()); + for (auto item : site_options) { + int count = count_if(data.begin(), data.end(), [item](int element) {return element == item; }); + EXPECT_NEAR(1.0 / 4.0, (double)count/(double)data.size(), 1e-2); + } + } + } + + TEST_F(LatticeTest, 1DTests) { + // Initialize 1D Lattice object + params_lattice.Enable_periodic_x = true; + params_lattice.Enable_periodic_y = false; + params_lattice.Enable_periodic_z = false; + params_lattice.Length = 50; + params_lattice.Width = 1; + params_lattice.Height = 1; + params_lattice.Unit_size = 1.0; + Lattice lattice1D; + lattice1D.init(params_lattice, &gen); + Site site; + sites.assign(lattice1D.getNumSites(), site); + vector site_ptrs((int)sites.size()); + for (int i = 0; i < (int)sites.size(); i++) { + site_ptrs[i] = &sites[i]; + } + lattice1D.setSitePointers(site_ptrs); + // Check random neighbor site generation in 1D + vector data(30000); + for (int i = 0; i < 8; i++) { + Coords coords = lattice1D.generateRandomCoords(); + for (auto& item : data) { + item = lattice1D.getSiteIndex(lattice1D.chooseRandomUnoccupiedNeighbor(coords)); + } + auto site_options(data); + removeDuplicates(site_options); + EXPECT_EQ(2, (int)site_options.size()); + for (auto item : site_options) { + int count = count_if(data.begin(), data.end(), [item](int element) {return element == item; }); + EXPECT_NEAR(1.0 / 2.0, (double)count / (double)data.size(), 1e-2); + } + } + } + TEST_F(LatticeTest, LatticeDistanceTests) { Coords coords_i{ 49, 49, 49 }; Coords coords_f{ 1, 49, 47 }; @@ -708,23 +906,24 @@ namespace LatticeTests{ TEST_F(LatticeTest, SiteTests) { Site site; + EXPECT_FALSE(site.isOccupied()); vector site_ptrs(10, &site); EXPECT_FALSE(lattice.setSitePointers(site_ptrs)); site_ptrs.assign(50 * 50 * 50, &site); EXPECT_TRUE(lattice.setSitePointers(site_ptrs)); - Coords coords{5,6,7}; + Coords coords{ 5,6,7 }; Site* site1 = *lattice.getSiteIt(coords); Site* site2 = site_ptrs[lattice.getSiteIndex(coords)]; - EXPECT_EQ(site1,site2); + EXPECT_EQ(site1, site2); // Check for sites and indices outside the lattice - coords = {0, 60, 0}; - EXPECT_THROW(lattice.getSiteIndex(coords),out_of_range); - EXPECT_THROW(lattice.getSiteCoords(150000),out_of_range); + coords = { 0, 60, 0 }; + EXPECT_THROW(lattice.getSiteIndex(coords), out_of_range); + EXPECT_THROW(lattice.getSiteCoords(150000), out_of_range); // Check site object assignment and clearing Object object; site.setObjectPtr(&object); EXPECT_TRUE(site.isOccupied()); - EXPECT_EQ(&object,site.getObjectPtr()); + EXPECT_EQ(&object, site.getObjectPtr()); site.clearOccupancy(); EXPECT_FALSE(site.isOccupied()); } @@ -753,7 +952,7 @@ namespace EventTests { params_base.Enable_full_recalc = false; } // Initialize TestSim object - test_sim.init(params_base, 0); + test_sim.init(params_base); } }; From a382b841fcd3e59d1b4764552a8af57f92a2a0b9 Mon Sep 17 00:00:00 2001 From: "Michael C. Heiber" Date: Mon, 14 May 2018 22:32:17 -0400 Subject: [PATCH 32/37] Testing Update -updated tests to use 64 bit mersenne twister random number generators --- test/test.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/test.cpp b/test/test.cpp index ff129ac..1e87a06 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -398,7 +398,7 @@ namespace UtilsTests { } TEST(UtilsTests, CalculateProbabilityHistTests) { - mt19937 gen(std::random_device{}()); + mt19937_64 gen(std::random_device{}()); uniform_real_distribution<> dist(0, 100); vector data((int)1e7); for (int i = 0; i < (int)data.size(); i++) { @@ -433,7 +433,7 @@ namespace UtilsTests { } TEST(UtilsTests, ExponentialDOSTests) { - mt19937 gen(std::random_device{}()); + mt19937_64 gen(std::random_device{}()); vector data((int)2e7, 0.0); createExponentialDOSVector(data, 0.0, 0.1, gen); auto hist = calculateProbabilityHist(data, 1000); @@ -452,7 +452,7 @@ namespace UtilsTests { } TEST(UtilsTests, GaussianDOSTests) { - mt19937 gen(std::random_device{}()); + mt19937_64 gen(std::random_device{}()); vector data((int)3e7, 0.0); createGaussianDOSVector(data, 0.0, 0.15, gen); EXPECT_NEAR(0.0, vector_avg(data), 1e-4); From acd4b8508be4ea1fd5d3530d3ea837f6dacad02b Mon Sep 17 00:00:00 2001 From: "Michael C. Heiber" Date: Tue, 15 May 2018 15:06:55 -0400 Subject: [PATCH 33/37] Simulation Class Testing -added several new tests to increase test coverage --- test/test.cpp | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/test/test.cpp b/test/test.cpp index 1e87a06..6cbceac 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -79,6 +79,12 @@ class TestSim : public Simulation { setObjectEvent(object_ptr, &(*move_event_it)); } } + + bool checkErrorMessageFunctions(string msg_in){ + setErrorMessage(msg_in); + string msg_out = getErrorMessage(); + return msg_in.compare(msg_out)==0; + } bool checkFinished() const { return (getN_objects_created() == N_tests); @@ -203,6 +209,7 @@ namespace SimulationTests { sim.N_tests = 10000; sim.N_steps = 500; sim.k_move = 1000; + sim.setGeneratorSeed(std::random_device{}()); } }; @@ -223,6 +230,24 @@ namespace SimulationTests { EXPECT_EQ(2, sim.getN_events()); EXPECT_EQ(1, sim.getN_events_executed()); EXPECT_FALSE(sim.checkFinished()); + // Check objects and events + auto object_ptrs = sim.getAllObjectPtrs(); + for(int i=0; i<(int)sim.objects.size(); i++){ + auto it = sim.objects.begin(); + advance(it,i); + EXPECT_TRUE(&(*it)==object_ptrs[i]); + } + auto event_ptrs = sim.getAllEventPtrs(); + for(int i=0; i<(int)event_ptrs.size(); i++){ + if(i==0){ + EXPECT_TRUE(&sim.event_creation==event_ptrs[i]); + } + else{ + auto it = sim.events_move.begin(); + advance(it,i); + EXPECT_TRUE(&(*it)==event_ptrs[i+1]); + } + } // Check event destination coords vector data(20000); for (int i = 0; i < 10; i++) { @@ -382,6 +407,13 @@ namespace SimulationTests { EXPECT_NEAR(displacement1, displacement3, 5e-2*displacement1); EXPECT_NEAR(displacement2, displacement3, 5e-2*displacement2); } + + TEST_F(SimulationTest, ErrorMessageTests) { + EXPECT_TRUE(sim.checkErrorMessageFunctions("Error!")); + EXPECT_TRUE(sim.checkErrorMessageFunctions("Error! There is a problem.")); + EXPECT_TRUE(sim.checkErrorMessageFunctions(" ")); + EXPECT_TRUE(sim.checkErrorMessageFunctions("")); + } } namespace UtilsTests { From cab5a806f7b42282877477c771f550a337e522af Mon Sep 17 00:00:00 2001 From: "Michael C. Heiber" Date: Tue, 15 May 2018 15:30:47 -0400 Subject: [PATCH 34/37] Simulation Class Testing Update -corrected bug with one of the tests --- test/test.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/test.cpp b/test/test.cpp index 6cbceac..be6cae2 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -170,11 +170,11 @@ class TestSim : public Simulation { } vector getAllObjectPtrs() const { - return getAllObjectPtrs(); + return Simulation::getAllObjectPtrs(); } vector getAllEventPtrs() const { - return getAllEventPtrs(); + return Simulation::getAllEventPtrs(); } Coords getRandomCoords() { @@ -244,8 +244,8 @@ namespace SimulationTests { } else{ auto it = sim.events_move.begin(); - advance(it,i); - EXPECT_TRUE(&(*it)==event_ptrs[i+1]); + advance(it,i-1); + EXPECT_TRUE(&(*it)==event_ptrs[i]); } } // Check event destination coords From 0c8271da1940723a1a6080f793d3fa9f85c0f81a Mon Sep 17 00:00:00 2001 From: "Michael C. Heiber" Date: Tue, 15 May 2018 16:18:30 -0400 Subject: [PATCH 35/37] Documentation Update -updated Doxygen documentation based on latest source code changes --- docs/_lattice_8h_source.html | 45 +++++++------- docs/_simulation_8h_source.html | 51 ++++++++-------- docs/_utils_8h_source.html | 40 +++++++------ docs/class_lattice-members.html | 47 ++++++++------- docs/class_lattice.html | 44 ++++++++++++-- docs/class_lattice.js | 3 +- docs/class_simulation-members.html | 37 ++++++------ docs/class_simulation.html | 12 ++-- docs/class_simulation.js | 3 +- docs/functions.html | 13 +++- docs/functions_func.html | 11 +++- docs/functions_vars.html | 2 +- docs/index.html | 38 +++++++++++- docs/md__r_e_a_d_m_e.html | 38 +++++++++++- docs/namespace_utils.html | 30 +++++----- docs/namespacemembers.html | 4 +- docs/namespacemembers_func.html | 4 +- docs/navtreeindex0.js | 96 ++++++++++++++++-------------- docs/search/all_1.js | 7 ++- docs/search/all_4.js | 3 +- docs/search/all_6.js | 2 +- docs/search/functions_1.js | 6 +- docs/search/functions_4.js | 1 + docs/search/functions_5.js | 2 +- docs/search/variables_1.js | 2 +- docs/struct_coords-members.html | 2 + docs/struct_coords.html | 62 ++++++++++++++++++- docs/struct_coords.js | 2 + 28 files changed, 403 insertions(+), 204 deletions(-) diff --git a/docs/_lattice_8h_source.html b/docs/_lattice_8h_source.html index f20d5fd..f744896 100644 --- a/docs/_lattice_8h_source.html +++ b/docs/_lattice_8h_source.html @@ -91,44 +91,45 @@
Lattice.h
-
1 // Copyright (c) 2018 Michael C. Heiber
2 // This source file is part of the KMC_Lattice project, which is subject to the MIT License.
3 // For more information, see the LICENSE file that accompanies this software package.
4 // The KMC_Lattice project can be found on Github at https://github.com/MikeHeiber/KMC_Lattice
5 
6 #ifndef LATTICE_H
7 #define LATTICE_H
8 
9 #include "Utils.h"
10 #include "Site.h"
11 #include <functional>
12 #include <stdexcept>
13 
26  int Length;
28  int Width;
30  int Height;
32  double Unit_size; // nm
33 };
34 
41 class Lattice{
42  public:
45  Lattice();
46 
51  void init(const Parameters_Lattice& params, std::mt19937* generator_ptr);
52 
62  void calculateDestinationCoords(const Coords& coords_initial, const int i, const int j, const int k, Coords& coords_dest) const;
63 
70  int calculateDX(const int x, const int i) const;
71 
78  int calculateDX(const Coords& coords_initial, const Coords& coords_dest) const;
79 
86  int calculateDY(const int y, const int j) const;
87 
94  int calculateDY(const Coords& coords_initial, const Coords& coords_dest) const;
95 
102  int calculateDZ(const int z, const int k) const;
103 
110  int calculateDZ(const Coords& coords_initial, const Coords& coords_dest) const;
111 
116  int calculateLatticeDistanceSquared(const Coords& coords_start, const Coords& coords_dest) const;
117 
127  bool checkMoveValidity(const Coords& coords_initial, const int i, const int j, const int k) const;
128 
131  void clearOccupancy(const Coords& coords);
132 
136 
140  int generateRandomX();
141 
145  int generateRandomY();
146 
150  int generateRandomZ();
151 
154  int getHeight() const;
155 
158  int getLength() const;
159 
162  long int getNumSites() const;
163 
167  Coords getSiteCoords(long int site_index);
168 
173  long int getSiteIndex(const Coords& coords) const;
174 
178  std::vector<Site*>::iterator getSiteIt(const Coords& coords);
179 
182  double getUnitSize() const;
183 
185  double getVolume() const;
186 
189  int getWidth() const;
190 
195  bool isOccupied(const Coords& coords) const;
196 
200  bool isXPeriodic() const;
201 
205  bool isYPeriodic() const;
206 
210  bool isZPeriodic() const;
211 
213  void outputLatticeOccupancy() const;
214 
217  void setOccupied(const Coords& coords);
218 
223  bool setSitePointers(const std::vector<Site*>& input_ptrs);
224  protected:
225 
226  private:
227  bool Enable_periodic_x;
228  bool Enable_periodic_y;
229  bool Enable_periodic_z;
230  int Length; // nm
231  int Width; // nm
232  int Height; // nm
233  double Unit_size; // nm
234  std::vector<Site*> site_ptrs;
235  std::mt19937* gen_ptr;
236 };
237 
238 #endif // LATTICE_H
int generateRandomZ()
Generates a random z coordinate that lies within the z-dimension size of the lattice.
Definition: Lattice.cpp:171
-
bool setSitePointers(const std::vector< Site *> &input_ptrs)
Sets the member site pointer vector to the input site pointer vector.
Definition: Lattice.cpp:258
-
bool isOccupied(const Coords &coords) const
Checks whether the site located at the input coordinates is occupied or not.
Definition: Lattice.cpp:230
+
1 // Copyright (c) 2018 Michael C. Heiber
2 // This source file is part of the KMC_Lattice project, which is subject to the MIT License.
3 // For more information, see the LICENSE file that accompanies this software package.
4 // The KMC_Lattice project can be found on Github at https://github.com/MikeHeiber/KMC_Lattice
5 
6 #ifndef LATTICE_H
7 #define LATTICE_H
8 
9 #include "Utils.h"
10 #include "Site.h"
11 #include <functional>
12 #include <stdexcept>
13 
26  int Length;
28  int Width;
30  int Height;
32  double Unit_size; // nm
33 };
34 
41 class Lattice{
42  public:
45  Lattice();
46 
51  void init(const Parameters_Lattice& params, std::mt19937_64* generator_ptr);
52 
62  void calculateDestinationCoords(const Coords& coords_initial, const int i, const int j, const int k, Coords& coords_dest) const;
63 
70  int calculateDX(const int x, const int i) const;
71 
78  int calculateDX(const Coords& coords_initial, const Coords& coords_dest) const;
79 
86  int calculateDY(const int y, const int j) const;
87 
94  int calculateDY(const Coords& coords_initial, const Coords& coords_dest) const;
95 
102  int calculateDZ(const int z, const int k) const;
103 
110  int calculateDZ(const Coords& coords_initial, const Coords& coords_dest) const;
111 
116  int calculateLatticeDistanceSquared(const Coords& coords_start, const Coords& coords_dest) const;
117 
127  bool checkMoveValidity(const Coords& coords_initial, const int i, const int j, const int k) const;
128 
135 
138  void clearOccupancy(const Coords& coords);
139 
143 
147  int generateRandomX();
148 
152  int generateRandomY();
153 
157  int generateRandomZ();
158 
161  int getHeight() const;
162 
165  int getLength() const;
166 
169  long int getNumSites() const;
170 
174  Coords getSiteCoords(long int site_index);
175 
180  long int getSiteIndex(const Coords& coords) const;
181 
185  std::vector<Site*>::iterator getSiteIt(const Coords& coords);
186 
189  double getUnitSize() const;
190 
192  double getVolume() const;
193 
196  int getWidth() const;
197 
202  bool isOccupied(const Coords& coords) const;
203 
207  bool isXPeriodic() const;
208 
212  bool isYPeriodic() const;
213 
217  bool isZPeriodic() const;
218 
220  void outputLatticeOccupancy() const;
221 
224  void setOccupied(const Coords& coords);
225 
230  bool setSitePointers(const std::vector<Site*>& input_ptrs);
231  protected:
232 
233  private:
234  bool Enable_periodic_x;
235  bool Enable_periodic_y;
236  bool Enable_periodic_z;
237  int Length; // nm
238  int Width; // nm
239  int Height; // nm
240  double Unit_size; // nm
241  std::vector<Site*> site_ptrs;
242  std::mt19937_64* gen_ptr;
243 };
244 
245 #endif // LATTICE_H
int generateRandomZ()
Generates a random z coordinate that lies within the z-dimension size of the lattice.
Definition: Lattice.cpp:215
+
bool setSitePointers(const std::vector< Site *> &input_ptrs)
Sets the member site pointer vector to the input site pointer vector.
Definition: Lattice.cpp:301
+
bool isOccupied(const Coords &coords) const
Checks whether the site located at the input coordinates is occupied or not.
Definition: Lattice.cpp:273
int calculateDZ(const int z, const int k) const
Calculates a coordinate adjustment factor if the z-direction periodic boundary is crossed...
Definition: Lattice.cpp:81
bool Enable_periodic_x
Determines whether the x-direction periodic boundaries will be enabled.
Definition: Lattice.h:20
-
int generateRandomY()
Generates a random y coordinate that lies within the y-dimension size of the lattice.
Definition: Lattice.cpp:165
+
int generateRandomY()
Generates a random y coordinate that lies within the y-dimension size of the lattice.
Definition: Lattice.cpp:210
int calculateDY(const int y, const int j) const
Calculates a coordinate adjustment factor if the y-direction periodic boundary is crossed...
Definition: Lattice.cpp:57
bool Enable_periodic_y
Determines whether the y-direction periodic boundaries will be enabled.
Definition: Lattice.h:22
Lattice()
Default constructor that creates an empty Lattice object.
Definition: Lattice.cpp:11
void calculateDestinationCoords(const Coords &coords_initial, const int i, const int j, const int k, Coords &coords_dest) const
Calculates the destination coordinates when given the starting coordinates and the displacement vecto...
Definition: Lattice.cpp:27
-
double getUnitSize() const
Gets the lattice unit size, which is used to convert lattice units into real space units...
Definition: Lattice.cpp:218
-
void init(const Parameters_Lattice &params, std::mt19937 *generator_ptr)
Initializes the Lattice object using the provided Parameters_Lattice input parameter struct...
Definition: Lattice.cpp:15
-
int generateRandomX()
Generates a random x coordinate that lies within the x-dimension size of the lattice.
Definition: Lattice.cpp:159
-
Coords getSiteCoords(long int site_index)
Gets the coordinates of the specified site.
Definition: Lattice.cpp:189
-
void setOccupied(const Coords &coords)
Sets the site located at the input coordinates to the occupied state.
Definition: Lattice.cpp:254
+
double getUnitSize() const
Gets the lattice unit size, which is used to convert lattice units into real space units...
Definition: Lattice.cpp:261
+
int generateRandomX()
Generates a random x coordinate that lies within the x-dimension size of the lattice.
Definition: Lattice.cpp:205
+
Coords getSiteCoords(long int site_index)
Gets the coordinates of the specified site.
Definition: Lattice.cpp:232
+
void setOccupied(const Coords &coords)
Sets the site located at the input coordinates to the occupied state.
Definition: Lattice.cpp:297
int calculateLatticeDistanceSquared(const Coords &coords_start, const Coords &coords_dest) const
Calculates the shortest distance between a pair of coordinates in squared lattice units...
Definition: Lattice.cpp:105
-
bool isYPeriodic() const
Checks whether the y-direction periodic boundaries are enabled or not.
Definition: Lattice.cpp:238
-
long int getSiteIndex(const Coords &coords) const
Gets the vector index for the site corresponding to the input coordinates.
Definition: Lattice.cpp:202
+
bool isYPeriodic() const
Checks whether the y-direction periodic boundaries are enabled or not.
Definition: Lattice.cpp:281
+
long int getSiteIndex(const Coords &coords) const
Gets the vector index for the site corresponding to the input coordinates.
Definition: Lattice.cpp:245
bool Enable_periodic_z
Determines whether the z-direction periodic boundaries will be enabled.
Definition: Lattice.h:24
-
int getHeight() const
Gets the z-direction size of the lattice, the height.
Definition: Lattice.cpp:177
+
int getHeight() const
Gets the z-direction size of the lattice, the height.
Definition: Lattice.cpp:220
This struct contains all of the main input parameters needed by the Lattice class.
Definition: Lattice.h:18
+
void init(const Parameters_Lattice &params, std::mt19937_64 *generator_ptr)
Initializes the Lattice object using the provided Parameters_Lattice input parameter struct...
Definition: Lattice.cpp:15
int calculateDX(const int x, const int i) const
Calculates a coordinate adjustment factor if the x-direction periodic boundary is crossed...
Definition: Lattice.cpp:33
-
bool isXPeriodic() const
Checks whether the x-direction periodic boundaries are enabled or not.
Definition: Lattice.cpp:234
-
int getLength() const
Gets the x-direction size of the lattice, the length.
Definition: Lattice.cpp:181
-
double getVolume() const
Gets the volume of the lattice in cm^-3.
Definition: Lattice.cpp:226
-
long int getNumSites() const
Gets the number of sites contained in the lattice.
Definition: Lattice.cpp:185
-
bool isZPeriodic() const
Checks whether the z-direction periodic boundaries are enabled or not.
Definition: Lattice.cpp:242
-
void outputLatticeOccupancy() const
Prints to the command line which sites are occupied.
Definition: Lattice.cpp:246
+
bool isXPeriodic() const
Checks whether the x-direction periodic boundaries are enabled or not.
Definition: Lattice.cpp:277
+
int getLength() const
Gets the x-direction size of the lattice, the length.
Definition: Lattice.cpp:224
+
double getVolume() const
Gets the volume of the lattice in cm^-3.
Definition: Lattice.cpp:269
+
long int getNumSites() const
Gets the number of sites contained in the lattice.
Definition: Lattice.cpp:228
+
bool isZPeriodic() const
Checks whether the z-direction periodic boundaries are enabled or not.
Definition: Lattice.cpp:285
+
void outputLatticeOccupancy() const
Prints to the command line which sites are occupied.
Definition: Lattice.cpp:289
double Unit_size
Defines the desired lattice unit size, which is used to convert lattice units into real space units...
Definition: Lattice.h:32
-
int getWidth() const
Gets the y-direction size of the lattice, the width.
Definition: Lattice.cpp:222
+
int getWidth() const
Gets the y-direction size of the lattice, the width.
Definition: Lattice.cpp:265
This simple struct contains Cartesian coordinates specified by integers x,y,z.
Definition: Utils.h:25
-
Coords generateRandomCoords()
Generates the coordinates for a randomly selected site in the lattice.
Definition: Lattice.cpp:151
+
Coords generateRandomCoords()
Generates the coordinates for a randomly selected site in the lattice.
Definition: Lattice.cpp:197
int Height
Defines the desired z-direction size of the lattice.
Definition: Lattice.h:30
int Width
Defines the desired y-direction size of the lattice.
Definition: Lattice.h:28
-
void clearOccupancy(const Coords &coords)
Clears the occupancy of the site located at the specified coordinates.
Definition: Lattice.cpp:147
+
void clearOccupancy(const Coords &coords)
Clears the occupancy of the site located at the specified coordinates.
Definition: Lattice.cpp:193
+
Coords chooseRandomUnoccupiedNeighbor(const Coords &coords_i)
Randomly selects a valid, unoccupied nearest neighbor site.
Definition: Lattice.cpp:147
bool checkMoveValidity(const Coords &coords_initial, const int i, const int j, const int k) const
Checks to see if a generic move operation from the designated initial coordinates to a destination po...
Definition: Lattice.cpp:131
This class contains the properties of a three-dimensional lattice and the functions needed to interac...
Definition: Lattice.h:41
-
std::vector< Site * >::iterator getSiteIt(const Coords &coords)
Gets the vector iterator for the site corresponding to the input coordinates.
Definition: Lattice.cpp:212
+
std::vector< Site * >::iterator getSiteIt(const Coords &coords)
Gets the vector iterator for the site corresponding to the input coordinates.
Definition: Lattice.cpp:255
int Length
Defines the desired x-direction size of the lattice.
Definition: Lattice.h:26
diff --git a/docs/_simulation_8h_source.html b/docs/_simulation_8h_source.html index d5ea36b..f3f916a 100644 --- a/docs/_simulation_8h_source.html +++ b/docs/_simulation_8h_source.html @@ -91,41 +91,42 @@
Simulation.h
-
1 // Copyright (c) 2018 Michael C. Heiber
2 // This source file is part of the KMC_Lattice project, which is subject to the MIT License.
3 // For more information, see the LICENSE file that accompanies this software.
4 // The KMC_Lattice project can be found on Github at https://github.com/MikeHeiber/KMC_Lattice
5 
6 #ifndef SIMULATION_H
7 #define SIMULATION_H
8 
9 #include "Utils.h"
10 #include "Lattice.h"
11 #include "Object.h"
12 #include "Event.h"
13 #include <list>
14 #include <vector>
15 #include <random>
16 #include <iostream>
17 #include <fstream>
18 #include <sstream>
19 #include <ctime>
20 
26 
36  int Length;
38  int Width;
40  int Height;
42  double Unit_size;
46  bool Enable_FRM;
54  std::ofstream* Logfile;
55 };
56 
63 class Simulation{
64  public:
66  virtual ~Simulation();
67 
70  Simulation();
71 
77  void init(const Parameters_Simulation& params, const int id);
78 
83  virtual bool checkFinished() const = 0;
84 
89  virtual bool executeNextEvent() = 0;
90 
93  std::string getErrorMessage() const;
94 
97  int getN_events() const;
98 
100  long int getN_events_executed() const;
101 
105  int getId() const;
106 
108  int getTemp() const;
109 
111  double getTime() const;
112 
114  double getVolume() const;
115 
120  bool isLoggingEnabled() const;
121 
123  double rand01();
124 
127  void setGeneratorSeed(const int seed);
128 
129  protected:
131  std::mt19937 generator;
133  std::ofstream* Logfile;
137  bool Error_found = false;
139  std::string error_msg;
140 
141  //------ Functions
142 
146  std::list<Event*>::const_iterator addEvent(Event* event_ptr);
147 
150  void addObject(Object* object_ptr);
151 
155  std::list<Event*>::const_iterator chooseNextEvent();
156 
161  std::vector<Object*> findRecalcObjects(const Coords& coords_start, const Coords& coords_dest) const;
162 
164  std::vector<Event*> getAllEventPtrs() const;
165 
167  std::vector<Object*> getAllObjectPtrs() const;
168 
172  void moveObject(Object* object_ptr,const Coords& coords_dest);
173 
179  void removeEvent(Event* event_ptr);
180 
187  void removeObject(Object* object_ptr);
188 
191  void setErrorMessage(const std::string& input_msg);
192 
197  void setObjectEvent(const Object* object_ptr,Event* event_ptr);
198 
201  void setTime(const double input_time);
202 
203  private:
204  int Id;
205  // General Parameters
206  bool Enable_logging;
207  int temperature; // Kelvin
208  // KMC Algorithm Event Recalculation Method Parameters
209  bool Enable_FRM;
210  bool Enable_selective_recalc;
211  int Recalc_cutoff;
212  bool Enable_full_recalc;
213  // Data Structures
214  std::list<Object*> object_ptrs;
215  std::list<Event*> event_ptrs;
216  // Counters
217  double time_sim = 0;
218  long int N_objects_created = 0;
219  long int N_events_executed = 0;
220  // Functions
221 
226  std::vector<Object*> findRecalcNeighbors(const Coords& coords) const;
227 };
228 
229 #endif // SIMULATION_H
virtual bool checkFinished() const =0
Checks whether or not the simulation has finished.
-
void removeEvent(Event *event_ptr)
Removes an Event pointer from the event list.
Definition: Simulation.cpp:203
+
1 // Copyright (c) 2018 Michael C. Heiber
2 // This source file is part of the KMC_Lattice project, which is subject to the MIT License.
3 // For more information, see the LICENSE file that accompanies this software.
4 // The KMC_Lattice project can be found on Github at https://github.com/MikeHeiber/KMC_Lattice
5 
6 #ifndef SIMULATION_H
7 #define SIMULATION_H
8 
9 #include "Utils.h"
10 #include "Lattice.h"
11 #include "Object.h"
12 #include "Event.h"
13 #include <list>
14 #include <vector>
15 #include <random>
16 #include <iostream>
17 #include <fstream>
18 #include <sstream>
19 #include <ctime>
20 
26 
36  int Length;
38  int Width;
40  int Height;
42  double Unit_size;
46  bool Enable_FRM;
54  std::ofstream* Logfile;
55 };
56 
63 class Simulation{
64  public:
66  virtual ~Simulation();
67 
70  Simulation();
71 
77  void init(const Parameters_Simulation& params, const int id);
78 
83  virtual bool checkFinished() const = 0;
84 
89  virtual bool executeNextEvent() = 0;
90 
93  std::string getErrorMessage() const;
94 
97  int getN_events() const;
98 
100  long int getN_events_executed() const;
101 
103  long int getN_objects_created() const;
104 
108  int getId() const;
109 
111  int getTemp() const;
112 
114  double getTime() const;
115 
117  double getVolume() const;
118 
123  bool isLoggingEnabled() const;
124 
126  double rand01();
127 
130  void setGeneratorSeed(const int seed);
131 
132  protected:
134  std::mt19937_64 generator;
136  std::ofstream* Logfile;
140  bool Error_found = false;
142  std::string error_msg;
143 
144  //------ Functions
145 
149  std::list<Event*>::const_iterator addEvent(Event* event_ptr);
150 
153  void addObject(Object* object_ptr);
154 
158  std::list<Event*>::const_iterator chooseNextEvent();
159 
164  std::vector<Object*> findRecalcObjects(const Coords& coords_start, const Coords& coords_dest) const;
165 
167  std::vector<Event*> getAllEventPtrs() const;
168 
170  std::vector<Object*> getAllObjectPtrs() const;
171 
175  void moveObject(Object* object_ptr,const Coords& coords_dest);
176 
182  void removeEvent(Event* event_ptr);
183 
190  void removeObject(Object* object_ptr);
191 
194  void setErrorMessage(const std::string& input_msg);
195 
200  void setObjectEvent(const Object* object_ptr,Event* event_ptr);
201 
204  void setTime(const double input_time);
205 
206  private:
207  int Id;
208  // General Parameters
209  bool Enable_logging;
210  int temperature; // Kelvin
211  // KMC Algorithm Event Recalculation Method Parameters
212  bool Enable_FRM;
213  bool Enable_selective_recalc;
214  int Recalc_cutoff;
215  bool Enable_full_recalc;
216  // Data Structures
217  std::list<Object*> object_ptrs;
218  std::list<Event*> event_ptrs;
219  // Counters
220  double time_sim = 0.0;
221  long int N_objects_created = 0;
222  long int N_events_executed = 0;
223  // Functions
224 
229  std::vector<Object*> findRecalcNeighbors(const Coords& coords) const;
230 };
231 
232 #endif // SIMULATION_H
virtual bool checkFinished() const =0
Checks whether or not the simulation has finished.
+
void removeEvent(Event *event_ptr)
Removes an Event pointer from the event list.
Definition: Simulation.cpp:191
int Temperature
Defines the desired temperature of the simulation in Kelvin.
Definition: Simulation.h:44
-
std::vector< Object * > findRecalcObjects(const Coords &coords_start, const Coords &coords_dest) const
Constructs and returns a vector of pointers to all Object objects that are to have their events recal...
Definition: Simulation.cpp:79
-
int getTemp() const
Gets the value of the temperature parameter.
Definition: Simulation.cpp:166
-
bool Error_found
The Error_found flag indicates whether or not there has been an error during one of the simulation op...
Definition: Simulation.h:137
+
std::vector< Object * > findRecalcObjects(const Coords &coords_start, const Coords &coords_dest) const
Constructs and returns a vector of pointers to all Object objects that are to have their events recal...
Definition: Simulation.cpp:73
+
int getTemp() const
Gets the value of the temperature parameter.
Definition: Simulation.cpp:154
+
bool Error_found
The Error_found flag indicates whether or not there has been an error during one of the simulation op...
Definition: Simulation.h:140
This base class contains the basic properties of a KMC simulation event and the functions needed to i...
Definition: Event.h:24
bool Enable_FRM
Determines whether the first reaction method will be used or not.
Definition: Simulation.h:46
-
int getId() const
Gets the processor ID number for the processor that is running the simulation.
Definition: Simulation.cpp:148
-
std::vector< Object * > getAllObjectPtrs() const
Returns a vector of pointers to all Object objects in the simulation.
Definition: Simulation.cpp:135
+
int getId() const
Gets the processor ID number for the processor that is running the simulation.
Definition: Simulation.cpp:136
+
std::vector< Object * > getAllObjectPtrs() const
Returns a vector of pointers to all Object objects in the simulation.
Definition: Simulation.cpp:123
+
std::mt19937_64 generator
Mersenne Twister random number generator.
Definition: Simulation.h:134
bool Enable_periodic_x
Determines whether the x-direction periodic boundary conditions will be enabled or not in the Lattice...
Definition: Simulation.h:30
-
std::mt19937 generator
Mersenne Twister random number generator.
Definition: Simulation.h:131
-
void setErrorMessage(const std::string &input_msg)
Sets the error_msg member variable to the input string.
Definition: Simulation.cpp:241
-
void setObjectEvent(const Object *object_ptr, Event *event_ptr)
Overwrites the Event pointer in the event list associated with the indicated Object to the input Even...
Definition: Simulation.cpp:245
-
void setTime(const double input_time)
Updates the simulation time with the input time.
Definition: Simulation.cpp:253
-
void setGeneratorSeed(const int seed)
Sets the random number generator seed.
Definition: Simulation.cpp:249
+
void setErrorMessage(const std::string &input_msg)
Sets the error_msg member variable to the input string.
Definition: Simulation.cpp:221
+
void setObjectEvent(const Object *object_ptr, Event *event_ptr)
Overwrites the Event pointer in the event list associated with the indicated Object to the input Even...
Definition: Simulation.cpp:225
+
void setTime(const double input_time)
Updates the simulation time with the input time.
Definition: Simulation.cpp:233
+
void setGeneratorSeed(const int seed)
Sets the random number generator seed.
Definition: Simulation.cpp:229
This struct contains all of the main input parameters needed by the Simulation class.
Definition: Simulation.h:25
-
std::string error_msg
The error_msg string holds a message with information about the error that has occurred or is empty o...
Definition: Simulation.h:139
-
bool isLoggingEnabled() const
Checks whether or not logging is enabled.
Definition: Simulation.cpp:178
-
long int getN_events_executed() const
Gets the number of events that have been executed in the simulation.
Definition: Simulation.cpp:162
+
std::string error_msg
The error_msg string holds a message with information about the error that has occurred or is empty o...
Definition: Simulation.h:142
+
bool isLoggingEnabled() const
Checks whether or not logging is enabled.
Definition: Simulation.cpp:166
+
long int getN_events_executed() const
Gets the number of events that have been executed in the simulation.
Definition: Simulation.cpp:146
bool Enable_selective_recalc
Determines whether the selective recalculation method will be used or not.
Definition: Simulation.h:48
+
long int getN_objects_created() const
Gets the number of objects that have been created in the simulation.
Definition: Simulation.cpp:150
virtual ~Simulation()
Default virtual destructor needed by the base class.
Definition: Simulation.cpp:15
-
double getVolume() const
Get the simulation box volume in cm^-3.
Definition: Simulation.cpp:174
-
std::vector< Event * > getAllEventPtrs() const
Returns a vector of pointers to all Event objects in the simulation.
Definition: Simulation.cpp:126
-
double rand01()
Generates a uniform random number from 0 to 1, not including 0.
Definition: Simulation.cpp:199
-
double getTime() const
Get the current simulation time in units of seconds.
Definition: Simulation.cpp:170
+
double getVolume() const
Get the simulation box volume in cm^-3.
Definition: Simulation.cpp:162
+
std::vector< Event * > getAllEventPtrs() const
Returns a vector of pointers to all Event objects in the simulation.
Definition: Simulation.cpp:114
+
double rand01()
Generates a uniform random number from 0 to 1, not including 0.
Definition: Simulation.cpp:187
+
double getTime() const
Get the current simulation time in units of seconds.
Definition: Simulation.cpp:158
virtual bool executeNextEvent()=0
Executes the next event in the simulation.
-
void moveObject(Object *object_ptr, const Coords &coords_dest)
Moves the designated object to the designated destination coordinates.
Definition: Simulation.cpp:182
+
void moveObject(Object *object_ptr, const Coords &coords_dest)
Moves the designated object to the designated destination coordinates.
Definition: Simulation.cpp:170
bool Enable_full_recalc
Determines whether the full recalculation method will be used or not.
Definition: Simulation.h:52
std::list< Event * >::const_iterator addEvent(Event *event_ptr)
Adds a pointer to an Event object to the event list and returns the iterator to its position in the l...
Definition: Simulation.cpp:48
int Recalc_cutoff
Defines the desired event recalculation cutoff radius for the simulation in nm.
Definition: Simulation.h:50
void init(const Parameters_Simulation &params, const int id)
Initializes the Simulation object using the provided Parameters_Simulation struct containing the inpu...
Definition: Simulation.cpp:19
Simulation()
Default constructor that creates an empty Simulation object.
Definition: Simulation.cpp:11
bool Enable_logging
Determines whether logging to a logfile during the simulation will be enabled or not.
Definition: Simulation.h:28
-
std::string getErrorMessage() const
Gets the saved error message.
Definition: Simulation.cpp:144
+
std::string getErrorMessage() const
Gets the saved error message.
Definition: Simulation.cpp:132
bool Enable_periodic_z
Determines whether the z-direction periodic boundary conditions will be enabled or not in the Lattice...
Definition: Simulation.h:34
std::list< Event * >::const_iterator chooseNextEvent()
Searches the event list and determines which event will be executed next.
Definition: Simulation.cpp:67
This abstract base class contains the basic properties of a KMC simulation and the functions needed t...
Definition: Simulation.h:63
@@ -134,14 +135,14 @@
bool Enable_periodic_y
Determines whether the y-direction periodic boundary conditions will be enabled or not in the Lattice...
Definition: Simulation.h:32
This simple struct contains Cartesian coordinates specified by integers x,y,z.
Definition: Utils.h:25
This base class contains the basic properties of a KMC simulation object and the functions needed to ...
Definition: Object.h:22
-
int getN_events() const
Gets the number of events that are currently in the event list.
Definition: Simulation.cpp:152
+
int getN_events() const
Gets the number of events that are currently in the event list.
Definition: Simulation.cpp:140
double Unit_size
Defines the desired resolution of the Lattice in units of nm.
Definition: Simulation.h:42
-
void removeObject(Object *object_ptr)
Removes the Object pointer from the base simulation class.
Definition: Simulation.cpp:218
+
void removeObject(Object *object_ptr)
Removes the Object pointer from the base simulation class.
Definition: Simulation.cpp:202
This class contains the properties of a three-dimensional lattice and the functions needed to interac...
Definition: Lattice.h:41
void addObject(Object *object_ptr)
Adds a pointer to an Object object to the object list.
Definition: Simulation.cpp:53
int Length
Defines the desired x-direction size of the Lattice.
Definition: Simulation.h:36
-
Lattice lattice
The Lattice object represents a three-dimensional lattice, its boundary conditions, and its occupancy.
Definition: Simulation.h:135
-
std::ofstream * Logfile
Pointer to an output file stream that is used to print log messages to a logfile when logging is enab...
Definition: Simulation.h:133
+
Lattice lattice
The Lattice object represents a three-dimensional lattice, its boundary conditions, and its occupancy.
Definition: Simulation.h:138
+
std::ofstream * Logfile
Pointer to an output file stream that is used to print log messages to a logfile when logging is enab...
Definition: Simulation.h:136
std::ofstream * Logfile
Defines the desired output file stream pointer to the logfile.
Definition: Simulation.h:54
diff --git a/docs/_utils_8h_source.html b/docs/_utils_8h_source.html index 1434dbb..6e51097 100644 --- a/docs/_utils_8h_source.html +++ b/docs/_utils_8h_source.html @@ -91,31 +91,33 @@
Utils.h
-
1 // Copyright (c) 2018 Michael C. Heiber
2 // This source file is part of the KMC_Lattice project, which is subject to the MIT License.
3 // For more information, see the LICENSE file that accompanies this software.
4 // The KMC_Lattice project can be found on Github at https://github.com/MikeHeiber/KMC_Lattice
5 
6 #ifndef UTILS_H
7 #define UTILS_H
8 
9 #include <algorithm>
10 #include <cmath>
11 #include <functional>
12 #include <fstream>
13 #include <iostream>
14 #include <memory>
15 #include <mpi.h>
16 #include <random>
17 #include <set>
18 #include <string>
19 #include <vector>
20 
25 struct Coords{
27  int x;
29  int y;
31  int z;
32 
37  void setXYZ(const int xval,const int yval,const int zval){
38  x = xval;
39  y = yval;
40  z = zval;
41  }
44  bool operator==(const Coords& rhs) const{
45  return (x == rhs.x && y == rhs.y && z == rhs.z);
46  }
49  bool operator!=(const Coords& rhs) const {
50  return (x != rhs.x || y != rhs.y || z != rhs.z);
51  }
52 };
53 
58 namespace Utils {
59 
60  // Scientific Constants
61  static constexpr double K_b = 8.61733035e-5;
62  static constexpr double Elementary_charge = 1.602176621e-19; // C
63  static constexpr double Vacuum_permittivity = 8.854187818e-12; // C/Vm
64  static constexpr double Plank = 6.626070040e-34;
65  static constexpr double Light_speed = 2.99792458e8;
66  static constexpr double Pi = 3.14159265359;
67  static constexpr double Coulomb_constant = 8.987551787e9; // N m^2 C^-2
68 
75  std::vector<std::pair<double,double>> calculateProbabilityHist(const std::vector<double>& data, int num_bins);
76 
83  std::vector<std::pair<double, double>> calculateProbabilityHist(const std::vector<double>& data, double bin_size);
84 
92  std::vector<std::pair<double, double>> calculateProbabilityHist(const std::vector<double>& data, const double bin_size, const int num_bins);
93 
102  void createExponentialDOSVector(std::vector<double>& data, const double mode, const double urbach_energy, std::mt19937& gen);
103 
109  void createGaussianDOSVector(std::vector<double>& data, const double mean, const double stdev, std::mt19937& gen);
110 
116  bool importBooleanParam(const std::string& input, bool& error_status);
117 
122  double integrateData(const std::vector<std::pair<double, double>>& data);
123 
129  double interpolateData(const std::vector<std::pair<double, double>>& data, const double x_val);
130 
137  std::vector<double> MPI_calculateVectorAvg(const std::vector<double>& input_vector);
138 
145  std::vector<double> MPI_calculateVectorSum(const std::vector<double>& input_vector);
146 
153  std::vector<int> MPI_calculateVectorSum(const std::vector<int>& input_vector);
154 
161  std::vector<double> MPI_gatherVectors(const std::vector<double>& input_vector);
162 
169  std::vector<int> MPI_gatherVectors(const std::vector<int>& input_vector);
170 
174  std::string removeWhitespace(const std::string& str);
175 
176  // Template functions
177 
182  template<typename T>
183  double array_avg(const T data[], const int array_size) {
184  double sum = 0;
185  for (int i = 0; i < array_size; i++) {
186  sum += data[i];
187  }
188  return sum / array_size;
189  }
190 
195  template<typename T>
196  double array_stdev(const T data[], const int array_size) {
197  double sum = 0;
198  double avg = array_avg(data, array_size);
199  for (int i = 0; i < array_size; i++) {
200  sum += (data[i] - avg)*(data[i] - avg);
201  }
202  return sqrt(sum / (array_size - 1));
203  }
204 
209  template<typename base_type>
210  base_type intpow(const base_type base, const int exponent) {
211  base_type result;
212  if (exponent == 0) {
213  result = 1;
214  return result;
215  }
216  result = base;
217  for (int i = 1; i < abs(exponent); i++) {
218  result *= base;
219  }
220  if (exponent < 0) {
221  result = 1.0 / result;
222  }
223  return result;
224  }
225 
230  template<typename T>
231  void outputVectorToFile(std::vector<T>& vec, std::string filename) {
232  std::ofstream outfile;
233  outfile.open(filename);
234  for (auto const &item : vec) {
235  outfile << item << "\n";
236  }
237  outfile.close();
238  }
239 
244  template<typename T>
245  void outputVectorToFile(std::vector<std::pair<T,T>>& vec, std::string filename) {
246  std::ofstream outfile;
247  outfile.open(filename);
248  for (auto const &item : vec) {
249  outfile << item.first << "," << item.second << "\n";
250  }
251  outfile.close();
252  }
253 
257  template<typename T>
258  void removeDuplicates(std::vector<T> &vec) {
259  if ((int)vec.size() > 2) {
260  for (auto it1 = vec.begin(); it1 != vec.end() - 2; ++it1) {
261  for (auto it2 = it1 + 2; it2 != vec.end(); ++it2) {
262  if (*it2 == *it1) {
263  *it2 = *(it2 - 1);
264  }
265  }
266  }
267  }
268  if ((int)vec.size() > 1) {
269  auto it3 = unique(vec.begin(), vec.end());
270  vec.resize(distance(vec.begin(), it3));
271  }
272  }
273 
277  template<typename T, typename A>
278  double vector_avg(const std::vector<T, A>& data) {
279  double sum = 0;
280  for (auto const &item : data) {
281  sum += item;
282  }
283  return sum / data.size();
284  }
285 
289  template<typename T, typename A>
290  double vector_stdev(const std::vector<T, A>& data) {
291  double sum = 0;
292  double avg = vector_avg(data);
293  for (auto const &item : data) {
294  sum += (item - avg)*(item - avg);
295  }
296  return sqrt(sum / (data.size() - 1));
297  }
298 }
299 
300 #endif // UTILS_H
double vector_stdev(const std::vector< T, A > &data)
This template function calculates and returns the standard deviation in double format when given a ve...
Definition: Utils.h:290
+
1 // Copyright (c) 2018 Michael C. Heiber
2 // This source file is part of the KMC_Lattice project, which is subject to the MIT License.
3 // For more information, see the LICENSE file that accompanies this software.
4 // The KMC_Lattice project can be found on Github at https://github.com/MikeHeiber/KMC_Lattice
5 
6 #ifndef UTILS_H
7 #define UTILS_H
8 
9 #include <algorithm>
10 #include <cmath>
11 #include <functional>
12 #include <fstream>
13 #include <iostream>
14 #include <memory>
15 #include <mpi.h>
16 #include <random>
17 #include <set>
18 #include <string>
19 #include <vector>
20 
25 struct Coords{
27  int x;
29  int y;
31  int z;
32 
34  Coords(){}
35 
40  Coords(const int xval, const int yval, const int zval) {
41  x = xval;
42  y = yval;
43  z = zval;
44  }
45 
50  void setXYZ(const int xval,const int yval,const int zval){
51  x = xval;
52  y = yval;
53  z = zval;
54  }
57  bool operator==(const Coords& rhs) const{
58  return (x == rhs.x && y == rhs.y && z == rhs.z);
59  }
62  bool operator!=(const Coords& rhs) const {
63  return (x != rhs.x || y != rhs.y || z != rhs.z);
64  }
65 };
66 
71 namespace Utils {
72 
73  // Scientific Constants
74  static constexpr double K_b = 8.61733035e-5;
75  static constexpr double Elementary_charge = 1.602176621e-19; // C
76  static constexpr double Vacuum_permittivity = 8.854187818e-12; // C/Vm
77  static constexpr double Plank = 6.626070040e-34;
78  static constexpr double Light_speed = 2.99792458e8;
79  static constexpr double Pi = 3.14159265359;
80  static constexpr double Coulomb_constant = 8.987551787e9; // N m^2 C^-2
81 
88  std::vector<std::pair<double,double>> calculateProbabilityHist(const std::vector<double>& data, int num_bins);
89 
96  std::vector<std::pair<double, double>> calculateProbabilityHist(const std::vector<double>& data, double bin_size);
97 
105  std::vector<std::pair<double, double>> calculateProbabilityHist(const std::vector<double>& data, const double bin_size, const int num_bins);
106 
115  void createExponentialDOSVector(std::vector<double>& data, const double mode, const double urbach_energy, std::mt19937_64& gen);
116 
122  void createGaussianDOSVector(std::vector<double>& data, const double mean, const double stdev, std::mt19937_64& gen);
123 
129  bool importBooleanParam(const std::string& input, bool& error_status);
130 
135  double integrateData(const std::vector<std::pair<double, double>>& data);
136 
142  double interpolateData(const std::vector<std::pair<double, double>>& data, const double x_val);
143 
150  std::vector<double> MPI_calculateVectorAvg(const std::vector<double>& input_vector);
151 
158  std::vector<double> MPI_calculateVectorSum(const std::vector<double>& input_vector);
159 
166  std::vector<int> MPI_calculateVectorSum(const std::vector<int>& input_vector);
167 
174  std::vector<double> MPI_gatherVectors(const std::vector<double>& input_vector);
175 
182  std::vector<int> MPI_gatherVectors(const std::vector<int>& input_vector);
183 
187  std::string removeWhitespace(const std::string& str);
188 
189  // Template functions
190 
195  template<typename T>
196  double array_avg(const T data[], const int array_size) {
197  double sum = 0;
198  for (int i = 0; i < array_size; i++) {
199  sum += data[i];
200  }
201  return sum / array_size;
202  }
203 
208  template<typename T>
209  double array_stdev(const T data[], const int array_size) {
210  double sum = 0;
211  double avg = array_avg(data, array_size);
212  for (int i = 0; i < array_size; i++) {
213  sum += (data[i] - avg)*(data[i] - avg);
214  }
215  return sqrt(sum / (array_size - 1));
216  }
217 
222  template<typename base_type>
223  base_type intpow(const base_type base, const int exponent) {
224  base_type result;
225  if (exponent == 0) {
226  result = 1;
227  return result;
228  }
229  result = base;
230  for (int i = 1; i < abs(exponent); i++) {
231  result *= base;
232  }
233  if (exponent < 0) {
234  result = 1.0 / result;
235  }
236  return result;
237  }
238 
243  template<typename T>
244  void outputVectorToFile(std::vector<T>& vec, std::string filename) {
245  std::ofstream outfile;
246  outfile.open(filename);
247  for (auto const &item : vec) {
248  outfile << item << "\n";
249  }
250  outfile.close();
251  }
252 
257  template<typename T>
258  void outputVectorToFile(std::vector<std::pair<T,T>>& vec, std::string filename) {
259  std::ofstream outfile;
260  outfile.open(filename);
261  for (auto const &item : vec) {
262  outfile << item.first << "," << item.second << "\n";
263  }
264  outfile.close();
265  }
266 
270  template<typename T>
271  void removeDuplicates(std::vector<T> &vec) {
272  if ((int)vec.size() > 2) {
273  for (auto it1 = vec.begin(); it1 != vec.end() - 2; ++it1) {
274  for (auto it2 = it1 + 2; it2 != vec.end(); ++it2) {
275  if (*it2 == *it1) {
276  *it2 = *(it2 - 1);
277  }
278  }
279  }
280  }
281  if ((int)vec.size() > 1) {
282  auto it3 = unique(vec.begin(), vec.end());
283  vec.resize(distance(vec.begin(), it3));
284  }
285  }
286 
290  template<typename T, typename A>
291  double vector_avg(const std::vector<T, A>& data) {
292  return accumulate(data.begin(), data.end(), 0.0) / (double)data.size();
293  }
294 
298  template<typename T, typename A>
299  double vector_stdev(const std::vector<T, A>& data) {
300  double avg = vector_avg(data);
301  double sum = accumulate(data.begin(), data.end(), 0.0, [avg](double& x, const T& element) {
302  return x + (element - avg)*(element - avg);
303  });
304  return sqrt(sum / (double)((int)data.size() - 1));
305  }
306 }
307 
308 #endif // UTILS_H
double vector_stdev(const std::vector< T, A > &data)
This template function calculates and returns the standard deviation in double format when given a ve...
Definition: Utils.h:299
int z
The z Cartesian coordinate.
Definition: Utils.h:31
-
void removeDuplicates(std::vector< T > &vec)
This template function efficienctly removes the duplicate entries from an input vector.
Definition: Utils.h:258
+
void removeDuplicates(std::vector< T > &vec)
This template function efficienctly removes the duplicate entries from an input vector.
Definition: Utils.h:271
int x
The x Cartesian coordinate.
Definition: Utils.h:27
std::vector< std::pair< double, double > > calculateProbabilityHist(const std::vector< double > &data, int num_bins)
Calculates the probability histogram for the input data vector using the input number of bins...
Definition: Utils.cpp:12
-
double array_stdev(const T data[], const int array_size)
This template function calculates and returns the standard deviation in double format when given an a...
Definition: Utils.h:196
-
double array_avg(const T data[], const int array_size)
This template function calculates and returns the average value in double format when given an array ...
Definition: Utils.h:183
-
bool importBooleanParam(const std::string &input, bool &error_status)
Extracts a boolean value from a string containing "true" or "false".
Definition: Utils.cpp:134
+
double array_stdev(const T data[], const int array_size)
This template function calculates and returns the standard deviation in double format when given an a...
Definition: Utils.h:209
+
double array_avg(const T data[], const int array_size)
This template function calculates and returns the average value in double format when given an array ...
Definition: Utils.h:196
+
Coords()
Default constructor that creates an empty Coords object.
Definition: Utils.h:34
+
bool importBooleanParam(const std::string &input, bool &error_status)
Extracts a boolean value from a string containing "true" or "false".
Definition: Utils.cpp:117
int y
The y Cartesian coordinate.
Definition: Utils.h:29
-
double integrateData(const std::vector< std::pair< double, double >> &data)
Numerically integrates a vector of x-y data using the trapezoid rule.
Definition: Utils.cpp:149
+
double integrateData(const std::vector< std::pair< double, double >> &data)
Numerically integrates a vector of x-y data using the trapezoid rule.
Definition: Utils.cpp:132
This namespace provides useful constants and utility functions.
Definition: Utils.cpp:8
-
bool operator==(const Coords &rhs) const
Defines the conditions when two Coords structs are deemed to be equal.
Definition: Utils.h:44
-
std::vector< double > MPI_gatherVectors(const std::vector< double > &input_vector)
Uses MPI to gather vectors from separate processors to build one big vector containing all of the dat...
Definition: Utils.cpp:277
-
void createGaussianDOSVector(std::vector< double > &data, const double mean, const double stdev, std::mt19937 &gen)
Creates a vector of doubles that has a Gaussian distribution.
Definition: Utils.cpp:126
-
void createExponentialDOSVector(std::vector< double > &data, const double mode, const double urbach_energy, std::mt19937 &gen)
Creates a vector of doubles that has a custom asymmetric distribution with an exponential tail...
Definition: Utils.cpp:109
-
std::vector< double > MPI_calculateVectorSum(const std::vector< double > &input_vector)
Uses MPI to calculate the element-wise sum vector from separate vectors coming from different process...
Definition: Utils.cpp:229
-
double vector_avg(const std::vector< T, A > &data)
This template function calculates and returns the average value in double format when given a vector ...
Definition: Utils.h:278
+
void createExponentialDOSVector(std::vector< double > &data, const double mode, const double urbach_energy, std::mt19937_64 &gen)
Creates a vector of doubles that has a custom asymmetric distribution with an exponential tail...
Definition: Utils.cpp:92
+
bool operator==(const Coords &rhs) const
Defines the conditions when two Coords structs are deemed to be equal.
Definition: Utils.h:57
+
std::vector< double > MPI_gatherVectors(const std::vector< double > &input_vector)
Uses MPI to gather vectors from separate processors to build one big vector containing all of the dat...
Definition: Utils.cpp:260
+
Coords(const int xval, const int yval, const int zval)
Constructor that creates a Coords object with the x,y,z coordinates set using the input values xval...
Definition: Utils.h:40
+
void createGaussianDOSVector(std::vector< double > &data, const double mean, const double stdev, std::mt19937_64 &gen)
Creates a vector of doubles that has a Gaussian distribution.
Definition: Utils.cpp:109
+
std::vector< double > MPI_calculateVectorSum(const std::vector< double > &input_vector)
Uses MPI to calculate the element-wise sum vector from separate vectors coming from different process...
Definition: Utils.cpp:212
+
double vector_avg(const std::vector< T, A > &data)
This template function calculates and returns the average value in double format when given a vector ...
Definition: Utils.h:291
This simple struct contains Cartesian coordinates specified by integers x,y,z.
Definition: Utils.h:25
-
double interpolateData(const std::vector< std::pair< double, double >> &data, const double x_val)
Linearly interpolates an x-y data set to determine the interpolated y-value corresponding to an input...
Definition: Utils.cpp:157
-
bool operator!=(const Coords &rhs) const
Defines the conditions when two Coords structs are deemed to be unequal.
Definition: Utils.h:49
-
std::string removeWhitespace(const std::string &str_input)
Removes all spaces and ta characters in a string.
Definition: Utils.cpp:367
-
void setXYZ(const int xval, const int yval, const int zval)
Sets the x,y,z coordinates using the input values xval, yval, and zval.
Definition: Utils.h:37
-
std::vector< double > MPI_calculateVectorAvg(const std::vector< double > &input_vector)
Uses MPI to calculate the element-wise average vector from separate vectors coming from different pro...
Definition: Utils.cpp:170
-
void outputVectorToFile(std::vector< T > &vec, std::string filename)
This template function outputs the input data vector to a file with the specified filename...
Definition: Utils.h:231
-
base_type intpow(const base_type base, const int exponent)
This template function calculates and returns the results of an integer power operation on a base num...
Definition: Utils.h:210
+
double interpolateData(const std::vector< std::pair< double, double >> &data, const double x_val)
Linearly interpolates an x-y data set to determine the interpolated y-value corresponding to an input...
Definition: Utils.cpp:140
+
bool operator!=(const Coords &rhs) const
Defines the conditions when two Coords structs are deemed to be unequal.
Definition: Utils.h:62
+
std::string removeWhitespace(const std::string &str_input)
Removes all spaces and ta characters in a string.
Definition: Utils.cpp:350
+
void setXYZ(const int xval, const int yval, const int zval)
Sets the x,y,z coordinates using the input values xval, yval, and zval.
Definition: Utils.h:50
+
std::vector< double > MPI_calculateVectorAvg(const std::vector< double > &input_vector)
Uses MPI to calculate the element-wise average vector from separate vectors coming from different pro...
Definition: Utils.cpp:153
+
void outputVectorToFile(std::vector< T > &vec, std::string filename)
This template function outputs the input data vector to a file with the specified filename...
Definition: Utils.h:244
+
base_type intpow(const base_type base, const int exponent)
This template function calculates and returns the results of an integer power operation on a base num...
Definition: Utils.h:223
diff --git a/docs/class_lattice-members.html b/docs/class_lattice-members.html index d76109f..4ce5f40 100644 --- a/docs/class_lattice-members.html +++ b/docs/class_lattice-members.html @@ -103,29 +103,30 @@ calculateDZ(const Coords &coords_initial, const Coords &coords_dest) constLattice calculateLatticeDistanceSquared(const Coords &coords_start, const Coords &coords_dest) constLattice checkMoveValidity(const Coords &coords_initial, const int i, const int j, const int k) constLattice - clearOccupancy(const Coords &coords)Lattice - generateRandomCoords()Lattice - generateRandomX()Lattice - generateRandomY()Lattice - generateRandomZ()Lattice - getHeight() constLattice - getLength() constLattice - getNumSites() constLattice - getSiteCoords(long int site_index)Lattice - getSiteIndex(const Coords &coords) constLattice - getSiteIt(const Coords &coords)Lattice - getUnitSize() constLattice - getVolume() constLattice - getWidth() constLattice - init(const Parameters_Lattice &params, std::mt19937 *generator_ptr)Lattice - isOccupied(const Coords &coords) constLattice - isXPeriodic() constLattice - isYPeriodic() constLattice - isZPeriodic() constLattice - Lattice()Lattice - outputLatticeOccupancy() constLattice - setOccupied(const Coords &coords)Lattice - setSitePointers(const std::vector< Site *> &input_ptrs)Lattice + chooseRandomUnoccupiedNeighbor(const Coords &coords_i)Lattice + clearOccupancy(const Coords &coords)Lattice + generateRandomCoords()Lattice + generateRandomX()Lattice + generateRandomY()Lattice + generateRandomZ()Lattice + getHeight() constLattice + getLength() constLattice + getNumSites() constLattice + getSiteCoords(long int site_index)Lattice + getSiteIndex(const Coords &coords) constLattice + getSiteIt(const Coords &coords)Lattice + getUnitSize() constLattice + getVolume() constLattice + getWidth() constLattice + init(const Parameters_Lattice &params, std::mt19937_64 *generator_ptr)Lattice + isOccupied(const Coords &coords) constLattice + isXPeriodic() constLattice + isYPeriodic() constLattice + isZPeriodic() constLattice + Lattice()Lattice + outputLatticeOccupancy() constLattice + setOccupied(const Coords &coords)Lattice + setSitePointers(const std::vector< Site *> &input_ptrs)Lattice diff --git a/docs/class_lattice.html b/docs/class_lattice.html index 1abadae..b8bf9e1 100644 --- a/docs/class_lattice.html +++ b/docs/class_lattice.html @@ -105,9 +105,9 @@  Lattice ()  Default constructor that creates an empty Lattice object. More...
  -void init (const Parameters_Lattice &params, std::mt19937 *generator_ptr) - Initializes the Lattice object using the provided Parameters_Lattice input parameter struct. More...
-  +void init (const Parameters_Lattice &params, std::mt19937_64 *generator_ptr) + Initializes the Lattice object using the provided Parameters_Lattice input parameter struct. More...
+  void calculateDestinationCoords (const Coords &coords_initial, const int i, const int j, const int k, Coords &coords_dest) const  Calculates the destination coordinates when given the starting coordinates and the displacement vector (i,j,k). More...
  @@ -135,6 +135,9 @@ bool checkMoveValidity (const Coords &coords_initial, const int i, const int j, const int k) const  Checks to see if a generic move operation from the designated initial coordinates to a destination position specified by the displacement vector (i,j,k) is possible. More...
  +Coords chooseRandomUnoccupiedNeighbor (const Coords &coords_i) + Randomly selects a valid, unoccupied nearest neighbor site. More...
+  void clearOccupancy (const Coords &coords)  Clears the occupancy of the site located at the specified coordinates. More...
  @@ -628,6 +631,35 @@

+

◆ chooseRandomUnoccupiedNeighbor()

+ +
+
+ + + + + + + + +
Coords Lattice::chooseRandomUnoccupiedNeighbor (const Coordscoords_i)
+
+ +

Randomly selects a valid, unoccupied nearest neighbor site.

+

Will choose a site across a periodic boundary if periodic boundaries are enabled.

Parameters
+ + +
coords_iis the Coords struct that designates the starting coordinates.
+
+
+
Returns
a Coords struct that represents the selected unoccupied nearest neighbor site.
+
+{-1,-1,-1} if there is no valid unoccupied neighbor
+
@@ -919,8 +951,8 @@

-

◆ init()

+ +

◆ init()

@@ -934,7 +966,7 @@

- std::mt19937 *  + std::mt19937_64 *  generator_ptr  diff --git a/docs/class_lattice.js b/docs/class_lattice.js index ea4bd74..b7cb893 100644 --- a/docs/class_lattice.js +++ b/docs/class_lattice.js @@ -10,6 +10,7 @@ var class_lattice = [ "calculateDZ", "class_lattice.html#a76b38079e102e17c79b13a3398a404a0", null ], [ "calculateLatticeDistanceSquared", "class_lattice.html#a3f51b0b41cf0e43e0469320310494a1e", null ], [ "checkMoveValidity", "class_lattice.html#ad0592298c4b92e9e84a768b95cd6d0f0", null ], + [ "chooseRandomUnoccupiedNeighbor", "class_lattice.html#abf954e8213010ab8aeac7a0b93a869bc", null ], [ "clearOccupancy", "class_lattice.html#a97a1b4f24cd40b81ed63aa2d7713b63b", null ], [ "generateRandomCoords", "class_lattice.html#a9fbb3c8bc23999ff685b6837beb62606", null ], [ "generateRandomX", "class_lattice.html#ab78435e50e3bf9f376c04fc305785bb4", null ], @@ -24,7 +25,7 @@ var class_lattice = [ "getUnitSize", "class_lattice.html#ac6963a6b2b4b8d96d3417f6e9c2a509d", null ], [ "getVolume", "class_lattice.html#a46f9cec33419459b64ff0efdf47a38b9", null ], [ "getWidth", "class_lattice.html#aeb60d2b8bfb02d9da8bef463f0d41428", null ], - [ "init", "class_lattice.html#a2b0a88048fae662aa71386a3a123a260", null ], + [ "init", "class_lattice.html#ab7322e5340badb9df4d208554fd90a89", null ], [ "isOccupied", "class_lattice.html#a4d37afb6ad4c67f4f6462c2f6d5c337d", null ], [ "isXPeriodic", "class_lattice.html#accf3b995e0d0cb422907728a29b1b523", null ], [ "isYPeriodic", "class_lattice.html#ac3192acefb019c5258143a6c758b3e48", null ], diff --git a/docs/class_simulation-members.html b/docs/class_simulation-members.html index b6814ed..1885b3c 100644 --- a/docs/class_simulation-members.html +++ b/docs/class_simulation-members.html @@ -102,30 +102,31 @@ error_msgSimulationprotected executeNextEvent()=0Simulationpure virtual findRecalcObjects(const Coords &coords_start, const Coords &coords_dest) constSimulationprotected - generatorSimulationprotected + generatorSimulationprotected getAllEventPtrs() constSimulationprotected getAllObjectPtrs() constSimulationprotected getErrorMessage() constSimulation getId() constSimulation getN_events() constSimulation getN_events_executed() constSimulation - getTemp() constSimulation - getTime() constSimulation - getVolume() constSimulation - init(const Parameters_Simulation &params, const int id)Simulation - isLoggingEnabled() constSimulation - latticeSimulationprotected - LogfileSimulationprotected - moveObject(Object *object_ptr, const Coords &coords_dest)Simulationprotected - rand01()Simulation - removeEvent(Event *event_ptr)Simulationprotected - removeObject(Object *object_ptr)Simulationprotected - setErrorMessage(const std::string &input_msg)Simulationprotected - setGeneratorSeed(const int seed)Simulation - setObjectEvent(const Object *object_ptr, Event *event_ptr)Simulationprotected - setTime(const double input_time)Simulationprotected - Simulation()Simulation - ~Simulation()Simulationvirtual + getN_objects_created() constSimulation + getTemp() constSimulation + getTime() constSimulation + getVolume() constSimulation + init(const Parameters_Simulation &params, const int id)Simulation + isLoggingEnabled() constSimulation + latticeSimulationprotected + LogfileSimulationprotected + moveObject(Object *object_ptr, const Coords &coords_dest)Simulationprotected + rand01()Simulation + removeEvent(Event *event_ptr)Simulationprotected + removeObject(Object *object_ptr)Simulationprotected + setErrorMessage(const std::string &input_msg)Simulationprotected + setGeneratorSeed(const int seed)Simulation + setObjectEvent(const Object *object_ptr, Event *event_ptr)Simulationprotected + setTime(const double input_time)Simulationprotected + Simulation()Simulation + ~Simulation()Simulationvirtual

diff --git a/docs/class_simulation.html b/docs/class_simulation.html index 434a747..c0d5f61 100644 --- a/docs/class_simulation.html +++ b/docs/class_simulation.html @@ -130,6 +130,10 @@ long int getN_events_executed () const  Gets the number of events that have been executed in the simulation.
  + +long int getN_objects_created () const + Gets the number of objects that have been created in the simulation.
+  int getId () const  Gets the processor ID number for the processor that is running the simulation. More...
  @@ -199,10 +203,10 @@ - - - + + + diff --git a/docs/class_simulation.js b/docs/class_simulation.js index b58c722..5220e1c 100644 --- a/docs/class_simulation.js +++ b/docs/class_simulation.js @@ -14,6 +14,7 @@ var class_simulation = [ "getId", "class_simulation.html#aff40f268758bd9a0f390a649fc45c05e", null ], [ "getN_events", "class_simulation.html#a7d88f18a1ba988d7e77b8be8de5b10d1", null ], [ "getN_events_executed", "class_simulation.html#a52cb5564151421cbefaca56357738de7", null ], + [ "getN_objects_created", "class_simulation.html#ab07386326b1844df84464abe30927bf5", null ], [ "getTemp", "class_simulation.html#ac00bce7c792fb67a75395c46c03efe0a", null ], [ "getTime", "class_simulation.html#a391ac262089c8bda8e76ce930b1db88b", null ], [ "getVolume", "class_simulation.html#a623c3fbc431ab74c2d2b2374a3b5a3a7", null ], @@ -29,7 +30,7 @@ var class_simulation = [ "setTime", "class_simulation.html#aae315f0881f0b385c566f96beb01d3f6", null ], [ "Error_found", "class_simulation.html#a7f4615a7898fb83d09be5e7fad92bb47", null ], [ "error_msg", "class_simulation.html#a954f41f4332dabda0fecea5d72151988", null ], - [ "generator", "class_simulation.html#a4c1d9071749e0fd93e70380cafb28417", null ], + [ "generator", "class_simulation.html#a269659fa336a5563e2ccfe2db1654ba9", null ], [ "lattice", "class_simulation.html#afb2cf4feeb4d8292eeba8f9ef393c6a4", null ], [ "Logfile", "class_simulation.html#a741321a0bbc89d51b969abda469e6f96", null ] ]; \ No newline at end of file diff --git a/docs/functions.html b/docs/functions.html index d5f9987..b7dd701 100644 --- a/docs/functions.html +++ b/docs/functions.html @@ -130,10 +130,16 @@

- c -

@@ -198,7 +204,7 @@

- g -

    : Lattice
  • generator -: Simulation +: Simulation
  • getAllEventPtrs() : Simulation @@ -242,6 +248,9 @@

    - g -

    • getN_events_executed() : Simulation
    • +
    • getN_objects_created() +: Simulation +
    • getNumSites() : Lattice
    • @@ -305,7 +314,7 @@

      - i -

        : Object
      • init() -: Lattice +: Lattice , Simulation
      • isLoggingEnabled() diff --git a/docs/functions_func.html b/docs/functions_func.html index 2b09ff5..df6b63f 100644 --- a/docs/functions_func.html +++ b/docs/functions_func.html @@ -130,10 +130,16 @@

        - c -

        @@ -209,6 +215,9 @@

        - g -

        • getN_events_executed() : Simulation
        • +
        • getN_objects_created() +: Simulation +
        • getNumSites() : Lattice
        • @@ -264,7 +273,7 @@

          - i -

            : Object
          • init() -: Lattice +: Lattice , Simulation
          • isLoggingEnabled() diff --git a/docs/functions_vars.html b/docs/functions_vars.html index 6d5597a..bf62253 100644 --- a/docs/functions_vars.html +++ b/docs/functions_vars.html @@ -119,7 +119,7 @@ : Simulation
          • generator -: Simulation +: Simulation
          • Height : Parameters_Lattice diff --git a/docs/index.html b/docs/index.html index 6a9222d..a15b8e4 100644 --- a/docs/index.html +++ b/docs/index.html @@ -92,11 +92,43 @@

            General Information

            -

            This object-oriented C++ software package contains a general framework for lattice kinetic Monte Carlo (KMC) simulations. This framework consists of a number of utility functions and base classes that must be extended to create a fully operational KMC simulation. The goal of this package is to be robust and flexible so that users can easily develop KMC simulations for a wide variety of different scientific problems without the need to start from scratch.

            -

            This KMC_Lattice package implements several event recalculation options for creating computationally efficient simulations. The package is designed to be usable on a personal computer and on high performance computing clusters. A simple example implementation of this general KMC framework can be found in the KMC_Lattice_example package. To see a more complete implementation for simulating a complex system, check out the Excimontec software package that is used for simulating organic semiconductor materials and devices.

            +

            This object-oriented C++ software package contains a general framework for lattice kinetic Monte Carlo (KMC) simulations. This framework consists of a number of utility functions and base classes that must be extended to create a fully operational KMC simulation. The goal of this package is to be robust, reliable, and flexible so that users can easily develop KMC simulations for a wide variety of different scientific problems without the need to start from scratch.

            +

            This KMC_Lattice package implements several event recalculation options for creating computationally efficient simulations. The package is designed to be usable on a personal computer and on high performance computing clusters. Check out the Excimontec software package for an example of a complex tool constructed using KMC_Lattice, which is used for simulating organic semiconductor materials and devices.

            For further reading about kinetic Monte Carlo simulations, a nice overview of the theory and algorithm can be found here:

            Introduction to the Kinetic Monte Carlo Method by Arthur Voter, Los Alamos National Lab

            -

            Work Together

            +

            Current Status

            +

            The current release is KMC_Lattice Most major planned features that are to be included in v2.0 are now implemented and have undergone preliminary testing. However, this software tool is still under development, and as such, there may still be bugs that need to be squashed. Please report any bugs or submit feature requests in the Issues section.

            +

            Continuous Integration and Testing Status:

            +

            KMC_Lattice is currently being tested on Ubuntu v14.04 with the GCC compiler (versions 4.7, 4.8, 4.9, 5, 6, 7, and 8) and on both Open MPI v1.6.5 and MPICH v3.04 using Travis CI.

            +

Protected Attributes

-std::mt19937 generator
 Mersenne Twister random number generator.
 
+std::mt19937_64 generator
 Mersenne Twister random number generator.
 
std::ofstream * Logfile
 Pointer to an output file stream that is used to print log messages to a logfile when logging is enabled.
+ + + + + + +
Branch Status
Master
Development
+

Code is being tested using googletest with test coverage assessment by Coveralls.

+ + + + + + + +
Branch Status
Master
Development
+

Contact

+

If you would like to contribute to the development of this project or would like some help in using the tool for your research, please contact me (heibe.nosp@m.r@ma.nosp@m.ilaps.nosp@m..org) to discuss a collaboration. You can check out my KMC research and other work on Researchgate.

+

How to try KMC_Lattice?

+

Building and Testing the KMC_Lattice Library

+

This software tool uses Message Passing Interface (MPI) to utilize parallel computing power. As a result, using KMC_Lattice requires that an MPI library is pre-installed on your system, and the final KMC_Lattice library must be built on your specific system. We cannot provide pre-built binaries for your system. Contact your HPC admin to determine the protocols for building MPI applications on your HPC system. In many cases, the HPC system will already be configured for you, and the package comes with a default makefile that can be used with the GCC compiler or the PGI compiler.

+

If you wish, you can also install MPI on your own personal workstation and then build the KMC_Lattice library there as well. For development and preliminary simulation tests, sometimes it is more efficient to run on your own workstation instead of an HPC system. More information about common MPI packages can be found here:

+

Once you have an MPI library installed, to build the KMC_Lattice library, copy the KMC_Lattice directory to your machine, set it as your working directory, and run make. Compilation flags have been set for GCC and PGI compilers. If you are using another compiler, you will need to edit the makefile and define your own compiler options. However, before you use the KMC_Lattice library, you should test it on your own hardware using the unit and system tests provided. Build the testing executable by running make test. Once the test build is complete, run ./test/KMC_Lattice_tests.exe. Please report any build or testing errors in the Issues section.

+

Contact

If you would like to contribute to the development of this project or would like some help in building an efficient KMC simulation tool for your specific scientific problem, please contact me to discuss a collaboration. You can check out my KMC research and other work on Researchgate.

Package Contents

Object class - This base class can be extended to represent any entity that one would like to simulate. It could represent an electron, atom, molecule, organism, etc. depending on the application. The Object class contains the fundamental properties and back-end operations that any given entity simulation would require.

diff --git a/docs/md__r_e_a_d_m_e.html b/docs/md__r_e_a_d_m_e.html index 6a9222d..a15b8e4 100644 --- a/docs/md__r_e_a_d_m_e.html +++ b/docs/md__r_e_a_d_m_e.html @@ -92,11 +92,43 @@

General Information

-

This object-oriented C++ software package contains a general framework for lattice kinetic Monte Carlo (KMC) simulations. This framework consists of a number of utility functions and base classes that must be extended to create a fully operational KMC simulation. The goal of this package is to be robust and flexible so that users can easily develop KMC simulations for a wide variety of different scientific problems without the need to start from scratch.

-

This KMC_Lattice package implements several event recalculation options for creating computationally efficient simulations. The package is designed to be usable on a personal computer and on high performance computing clusters. A simple example implementation of this general KMC framework can be found in the KMC_Lattice_example package. To see a more complete implementation for simulating a complex system, check out the Excimontec software package that is used for simulating organic semiconductor materials and devices.

+

This object-oriented C++ software package contains a general framework for lattice kinetic Monte Carlo (KMC) simulations. This framework consists of a number of utility functions and base classes that must be extended to create a fully operational KMC simulation. The goal of this package is to be robust, reliable, and flexible so that users can easily develop KMC simulations for a wide variety of different scientific problems without the need to start from scratch.

+

This KMC_Lattice package implements several event recalculation options for creating computationally efficient simulations. The package is designed to be usable on a personal computer and on high performance computing clusters. Check out the Excimontec software package for an example of a complex tool constructed using KMC_Lattice, which is used for simulating organic semiconductor materials and devices.

For further reading about kinetic Monte Carlo simulations, a nice overview of the theory and algorithm can be found here:

Introduction to the Kinetic Monte Carlo Method by Arthur Voter, Los Alamos National Lab

-

Work Together

+

Current Status

+

The current release is KMC_Lattice Most major planned features that are to be included in v2.0 are now implemented and have undergone preliminary testing. However, this software tool is still under development, and as such, there may still be bugs that need to be squashed. Please report any bugs or submit feature requests in the Issues section.

+

Continuous Integration and Testing Status:

+

KMC_Lattice is currently being tested on Ubuntu v14.04 with the GCC compiler (versions 4.7, 4.8, 4.9, 5, 6, 7, and 8) and on both Open MPI v1.6.5 and MPICH v3.04 using Travis CI.

+ + + + + + + +
Branch Status
Master
Development
+

Code is being tested using googletest with test coverage assessment by Coveralls.

+ + + + + + + +
Branch Status
Master
Development
+

Contact

+

If you would like to contribute to the development of this project or would like some help in using the tool for your research, please contact me (heibe.nosp@m.r@ma.nosp@m.ilaps.nosp@m..org) to discuss a collaboration. You can check out my KMC research and other work on Researchgate.

+

How to try KMC_Lattice?

+

Building and Testing the KMC_Lattice Library

+

This software tool uses Message Passing Interface (MPI) to utilize parallel computing power. As a result, using KMC_Lattice requires that an MPI library is pre-installed on your system, and the final KMC_Lattice library must be built on your specific system. We cannot provide pre-built binaries for your system. Contact your HPC admin to determine the protocols for building MPI applications on your HPC system. In many cases, the HPC system will already be configured for you, and the package comes with a default makefile that can be used with the GCC compiler or the PGI compiler.

+

If you wish, you can also install MPI on your own personal workstation and then build the KMC_Lattice library there as well. For development and preliminary simulation tests, sometimes it is more efficient to run on your own workstation instead of an HPC system. More information about common MPI packages can be found here:

+

Once you have an MPI library installed, to build the KMC_Lattice library, copy the KMC_Lattice directory to your machine, set it as your working directory, and run make. Compilation flags have been set for GCC and PGI compilers. If you are using another compiler, you will need to edit the makefile and define your own compiler options. However, before you use the KMC_Lattice library, you should test it on your own hardware using the unit and system tests provided. Build the testing executable by running make test. Once the test build is complete, run ./test/KMC_Lattice_tests.exe. Please report any build or testing errors in the Issues section.

+

Contact

If you would like to contribute to the development of this project or would like some help in building an efficient KMC simulation tool for your specific scientific problem, please contact me to discuss a collaboration. You can check out my KMC research and other work on Researchgate.

Package Contents

Object class - This base class can be extended to represent any entity that one would like to simulate. It could represent an electron, atom, molecule, organism, etc. depending on the application. The Object class contains the fundamental properties and back-end operations that any given entity simulation would require.

diff --git a/docs/namespace_utils.html b/docs/namespace_utils.html index 43cd7ab..452cc20 100644 --- a/docs/namespace_utils.html +++ b/docs/namespace_utils.html @@ -108,12 +108,12 @@ std::vector< std::pair< double, double > > calculateProbabilityHist (const std::vector< double > &data, const double bin_size, const int num_bins)  Calculates the probability histogram for the input data vector using the input bin size and input number of bins. More...
  -void createExponentialDOSVector (std::vector< double > &data, const double mode, const double urbach_energy, std::mt19937 &gen) - Creates a vector of doubles that has a custom asymmetric distribution with an exponential tail. More...
-  -void createGaussianDOSVector (std::vector< double > &data, const double mean, const double stdev, std::mt19937 &gen) - Creates a vector of doubles that has a Gaussian distribution. More...
-  +void createExponentialDOSVector (std::vector< double > &data, const double mode, const double urbach_energy, std::mt19937_64 &gen) + Creates a vector of doubles that has a custom asymmetric distribution with an exponential tail. More...
+  +void createGaussianDOSVector (std::vector< double > &data, const double mean, const double stdev, std::mt19937_64 &gen) + Creates a vector of doubles that has a Gaussian distribution. More...
+  bool importBooleanParam (const std::string &input, bool &error_status)  Extracts a boolean value from a string containing "true" or "false". More...
  @@ -381,8 +381,8 @@

-

◆ createExponentialDOSVector()

+ +

◆ createExponentialDOSVector()

@@ -408,7 +408,7 @@

- std::mt19937 &  + std::mt19937_64 &  gen  @@ -432,8 +432,8 @@

-

◆ createGaussianDOSVector()

+ +

◆ createGaussianDOSVector()

@@ -459,7 +459,7 @@

- std::mt19937 &  + std::mt19937_64 &  gen  @@ -734,7 +734,7 @@

Uses MPI to gather vectors from separate processors to build one big vector containing all of the data.

-

Each processor calls this function and sends an input vector. Upon function return, processor 0 receives the large data vector and all of the othe rprocessors receive an empty vector.

Parameters
+

Each processor calls this function and sends an input vector. Upon function return, processor 0 receives the large data vector and all of the other processors receive an empty vector.

Parameters
input_vectoris the input data from the processor calling the function.
@@ -763,7 +763,7 @@

Uses MPI to gather vectors from separate processors to build one big vector containing all of the data.

-

Each processor calls this function and sends an input vector. Upon function return, processor 0 receives the large data vector and all of the othe rprocessors receive an empty vector.

Parameters
+

Each processor calls this function and sends an input vector. Upon function return, processor 0 receives the large data vector and all of the other processors receive an empty vector.

Parameters
input_vectoris the input data from the processor calling the function.
@@ -874,7 +874,7 @@

This template function efficienctly removes the duplicate entries from an input vector.

-

This algorithm allow efficient removal of duplicate vector objects when > or < comparison operators do not exist.

Parameters
+

This algorithm allows efficient removal of duplicate vector objects when > or < comparison operators do not exist.

Parameters
vecis the input vector to be operated on.
diff --git a/docs/namespacemembers.html b/docs/namespacemembers.html index c77c7d2..72f3364 100644 --- a/docs/namespacemembers.html +++ b/docs/namespacemembers.html @@ -98,10 +98,10 @@ :
Utils
  • createExponentialDOSVector() -: Utils +: Utils
  • createGaussianDOSVector() -: Utils +: Utils
  • importBooleanParam() : Utils diff --git a/docs/namespacemembers_func.html b/docs/namespacemembers_func.html index cf88be9..c752fa5 100644 --- a/docs/namespacemembers_func.html +++ b/docs/namespacemembers_func.html @@ -98,10 +98,10 @@ : Utils
  • createExponentialDOSVector() -: Utils +: Utils
  • createGaussianDOSVector() -: Utils +: Utils
  • importBooleanParam() : Utils diff --git a/docs/navtreeindex0.js b/docs/navtreeindex0.js index be68629..d64874b 100644 --- a/docs/navtreeindex0.js +++ b/docs/navtreeindex0.js @@ -24,37 +24,38 @@ var NAVTREEINDEX0 = "class_event.html#af4282af20bd5b3940ba75c23e6032f18":[2,0,1,10], "class_lattice.html":[2,0,2], "class_lattice.html#a08adb2f412af409d3ec241e60e687c1a":[2,0,2,2], -"class_lattice.html#a180a9d79a40b1a0a092c8ab489569700":[2,0,2,13], -"class_lattice.html#a2b0a88048fae662aa71386a3a123a260":[2,0,2,24], +"class_lattice.html#a180a9d79a40b1a0a092c8ab489569700":[2,0,2,14], "class_lattice.html#a3f51b0b41cf0e43e0469320310494a1e":[2,0,2,8], -"class_lattice.html#a46f7d12855d24e1bdd02814621b0a178":[2,0,2,20], -"class_lattice.html#a46f9cec33419459b64ff0efdf47a38b9":[2,0,2,22], -"class_lattice.html#a4b43b67a36fcd3dfe62c9eeaffa561d2":[2,0,2,16], -"class_lattice.html#a4be17e9123f7737387991a9d1a8b87b3":[2,0,2,17], -"class_lattice.html#a4d37afb6ad4c67f4f6462c2f6d5c337d":[2,0,2,25], +"class_lattice.html#a46f7d12855d24e1bdd02814621b0a178":[2,0,2,21], +"class_lattice.html#a46f9cec33419459b64ff0efdf47a38b9":[2,0,2,23], +"class_lattice.html#a4b43b67a36fcd3dfe62c9eeaffa561d2":[2,0,2,17], +"class_lattice.html#a4be17e9123f7737387991a9d1a8b87b3":[2,0,2,18], +"class_lattice.html#a4d37afb6ad4c67f4f6462c2f6d5c337d":[2,0,2,26], "class_lattice.html#a4e8b3577701ec0cefce595f6956b22e3":[2,0,2,5], -"class_lattice.html#a515b8bc548ef4a87c3495a7352a60399":[2,0,2,30], +"class_lattice.html#a515b8bc548ef4a87c3495a7352a60399":[2,0,2,31], "class_lattice.html#a584ff9c528ebe46a6aea6ed652d107f4":[2,0,2,6], -"class_lattice.html#a59546ec4301871897ba5adfda1126741":[2,0,2,31], -"class_lattice.html#a60431f6504a253d47acb0b02f524571c":[2,0,2,19], +"class_lattice.html#a59546ec4301871897ba5adfda1126741":[2,0,2,32], +"class_lattice.html#a60431f6504a253d47acb0b02f524571c":[2,0,2,20], "class_lattice.html#a70a5cebc3c0c5a0f609be0592e7cc117":[2,0,2,0], -"class_lattice.html#a74a170b841ad1b74dad43519d37e9eaf":[2,0,2,18], +"class_lattice.html#a74a170b841ad1b74dad43519d37e9eaf":[2,0,2,19], "class_lattice.html#a76b38079e102e17c79b13a3398a404a0":[2,0,2,7], -"class_lattice.html#a96006397a6ab389fb1eee87fde6e2165":[2,0,2,14], -"class_lattice.html#a97a1b4f24cd40b81ed63aa2d7713b63b":[2,0,2,10], -"class_lattice.html#a9fbb3c8bc23999ff685b6837beb62606":[2,0,2,11], -"class_lattice.html#aa1f65735ecbd750ec04b6413b4d47316":[2,0,2,29], +"class_lattice.html#a96006397a6ab389fb1eee87fde6e2165":[2,0,2,15], +"class_lattice.html#a97a1b4f24cd40b81ed63aa2d7713b63b":[2,0,2,11], +"class_lattice.html#a9fbb3c8bc23999ff685b6837beb62606":[2,0,2,12], +"class_lattice.html#aa1f65735ecbd750ec04b6413b4d47316":[2,0,2,30], "class_lattice.html#aa6b80d6264bfc23ae5fea39abd2557d5":[2,0,2,1], -"class_lattice.html#aaa0cba3ab33ac620d9b9f9508c56d1ac":[2,0,2,15], -"class_lattice.html#ab78435e50e3bf9f376c04fc305785bb4":[2,0,2,12], -"class_lattice.html#ac3192acefb019c5258143a6c758b3e48":[2,0,2,27], -"class_lattice.html#ac6963a6b2b4b8d96d3417f6e9c2a509d":[2,0,2,21], -"class_lattice.html#accf3b995e0d0cb422907728a29b1b523":[2,0,2,26], +"class_lattice.html#aaa0cba3ab33ac620d9b9f9508c56d1ac":[2,0,2,16], +"class_lattice.html#ab7322e5340badb9df4d208554fd90a89":[2,0,2,25], +"class_lattice.html#ab78435e50e3bf9f376c04fc305785bb4":[2,0,2,13], +"class_lattice.html#abf954e8213010ab8aeac7a0b93a869bc":[2,0,2,10], +"class_lattice.html#ac3192acefb019c5258143a6c758b3e48":[2,0,2,28], +"class_lattice.html#ac6963a6b2b4b8d96d3417f6e9c2a509d":[2,0,2,22], +"class_lattice.html#accf3b995e0d0cb422907728a29b1b523":[2,0,2,27], "class_lattice.html#acdeca889f7df11fe299f8b7941198c83":[2,0,2,4], "class_lattice.html#ad0592298c4b92e9e84a768b95cd6d0f0":[2,0,2,9], -"class_lattice.html#ad7dd1b12a253e506aba5cedb57bf86ea":[2,0,2,28], +"class_lattice.html#ad7dd1b12a253e506aba5cedb57bf86ea":[2,0,2,29], "class_lattice.html#ad89c5473dd37339ede9fb3d0c3db4300":[2,0,2,3], -"class_lattice.html#aeb60d2b8bfb02d9da8bef463f0d41428":[2,0,2,23], +"class_lattice.html#aeb60d2b8bfb02d9da8bef463f0d41428":[2,0,2,24], "class_object.html":[2,0,3], "class_object.html#a02643ea0804dec3e43f60c788855c03b":[2,0,3,3], "class_object.html#a08df08943dc634609fa69b356a37d73f":[2,0,3,4], @@ -73,36 +74,37 @@ var NAVTREEINDEX0 = "class_object.html#aff050a622272cc7667251c7315f09fd7":[2,0,3,2], "class_simulation.html":[2,0,6], "class_simulation.html#a03d249f04c0921c938d68337dfc65f56":[2,0,6,10], -"class_simulation.html#a0f06c75c9dd6be20a3911781b48fd467":[2,0,6,23], -"class_simulation.html#a1a825b9da67da43104137662694655bd":[2,0,6,24], +"class_simulation.html#a0f06c75c9dd6be20a3911781b48fd467":[2,0,6,24], +"class_simulation.html#a1a825b9da67da43104137662694655bd":[2,0,6,25], "class_simulation.html#a1e0f43c4e11eda5486054c250f4de08f":[2,0,6,3], +"class_simulation.html#a269659fa336a5563e2ccfe2db1654ba9":[2,0,6,30], "class_simulation.html#a33a57b5640b0d33c816dc6e57604162e":[2,0,6,2], -"class_simulation.html#a391ac262089c8bda8e76ce930b1db88b":[2,0,6,15], -"class_simulation.html#a39da17feb9b487c05c9a834def44972f":[2,0,6,22], -"class_simulation.html#a3a4808231d4760f0ab30ea39b6a67e8c":[2,0,6,21], -"class_simulation.html#a43ca861e2514feb7f93bf18ea3b73385":[2,0,6,25], +"class_simulation.html#a391ac262089c8bda8e76ce930b1db88b":[2,0,6,16], +"class_simulation.html#a39da17feb9b487c05c9a834def44972f":[2,0,6,23], +"class_simulation.html#a3a4808231d4760f0ab30ea39b6a67e8c":[2,0,6,22], +"class_simulation.html#a43ca861e2514feb7f93bf18ea3b73385":[2,0,6,26], "class_simulation.html#a48e9e82f9dac1acec5d063a9f6f6115e":[2,0,6,6], -"class_simulation.html#a4c1d9071749e0fd93e70380cafb28417":[2,0,6,29], "class_simulation.html#a52cb5564151421cbefaca56357738de7":[2,0,6,13], -"class_simulation.html#a59666ceba048bec35557cb8b691d24d9":[2,0,6,19], +"class_simulation.html#a59666ceba048bec35557cb8b691d24d9":[2,0,6,20], "class_simulation.html#a5b224cc5b36bcc8eb29689aff223de41":[2,0,6,1], "class_simulation.html#a620684b9ac1fb07344c4c2237ed9f352":[2,0,6,9], -"class_simulation.html#a623c3fbc431ab74c2d2b2374a3b5a3a7":[2,0,6,16], +"class_simulation.html#a623c3fbc431ab74c2d2b2374a3b5a3a7":[2,0,6,17], "class_simulation.html#a662702acf2d446dbdef0e1c87bf21038":[2,0,6,7], -"class_simulation.html#a741321a0bbc89d51b969abda469e6f96":[2,0,6,31], +"class_simulation.html#a741321a0bbc89d51b969abda469e6f96":[2,0,6,32], "class_simulation.html#a7d88f18a1ba988d7e77b8be8de5b10d1":[2,0,6,12], -"class_simulation.html#a7f4615a7898fb83d09be5e7fad92bb47":[2,0,6,27], +"class_simulation.html#a7f4615a7898fb83d09be5e7fad92bb47":[2,0,6,28], "class_simulation.html#a80fad3f57dfaf195a36f7bc49bc88279":[2,0,6,0], -"class_simulation.html#a938de951b2766c6fb2b00cf9714caffa":[2,0,6,20], -"class_simulation.html#a954f41f4332dabda0fecea5d72151988":[2,0,6,28], -"class_simulation.html#aae315f0881f0b385c566f96beb01d3f6":[2,0,6,26], -"class_simulation.html#ac00bce7c792fb67a75395c46c03efe0a":[2,0,6,14], -"class_simulation.html#ac7c8a49a4cc506b850891480e0aae512":[2,0,6,18], +"class_simulation.html#a938de951b2766c6fb2b00cf9714caffa":[2,0,6,21], +"class_simulation.html#a954f41f4332dabda0fecea5d72151988":[2,0,6,29], +"class_simulation.html#aae315f0881f0b385c566f96beb01d3f6":[2,0,6,27], +"class_simulation.html#ab07386326b1844df84464abe30927bf5":[2,0,6,14], +"class_simulation.html#ac00bce7c792fb67a75395c46c03efe0a":[2,0,6,15], +"class_simulation.html#ac7c8a49a4cc506b850891480e0aae512":[2,0,6,19], "class_simulation.html#aec6a6e1a80eb566685e4d257e6f872c5":[2,0,6,8], "class_simulation.html#af69bb46977a3a0084214a194c888e16c":[2,0,6,4], -"class_simulation.html#af88e5e0634b373ba28f1dd87670725a6":[2,0,6,17], +"class_simulation.html#af88e5e0634b373ba28f1dd87670725a6":[2,0,6,18], "class_simulation.html#af8cf2e5c24531582599423df2d70dc5b":[2,0,6,5], -"class_simulation.html#afb2cf4feeb4d8292eeba8f9ef393c6a4":[2,0,6,30], +"class_simulation.html#afb2cf4feeb4d8292eeba8f9ef393c6a4":[2,0,6,31], "class_simulation.html#aff40f268758bd9a0f390a649fc45c05e":[2,0,6,11], "class_site.html":[2,0,7], "class_site.html#a30991b768ded0bb441c5bb54a789160a":[2,0,7,4], @@ -125,12 +127,14 @@ var NAVTREEINDEX0 = "namespaces.html":[1,0], "pages.html":[], "struct_coords.html":[2,0,0], -"struct_coords.html#a59992d986e76375f31828d32c05cd15d":[2,0,0,3], -"struct_coords.html#a7ed64d02fb7550f1506a93fcfab7f16f":[2,0,0,4], -"struct_coords.html#a88de3a6ee710766eb9c9444cee45a9f3":[2,0,0,2], -"struct_coords.html#a96d176173dbd5d97e7af63e1b5c0f7e1":[2,0,0,5], -"struct_coords.html#aaea2c566feec4e4bf56b27a34568be76":[2,0,0,0], -"struct_coords.html#ad3347f6568814df1a2b98b3cd0b78632":[2,0,0,1], +"struct_coords.html#a246211bba85765d5d67953922070d11f":[2,0,0,1], +"struct_coords.html#a5922d1783cefa759950faa50ac347191":[2,0,0,0], +"struct_coords.html#a59992d986e76375f31828d32c05cd15d":[2,0,0,5], +"struct_coords.html#a7ed64d02fb7550f1506a93fcfab7f16f":[2,0,0,6], +"struct_coords.html#a88de3a6ee710766eb9c9444cee45a9f3":[2,0,0,4], +"struct_coords.html#a96d176173dbd5d97e7af63e1b5c0f7e1":[2,0,0,7], +"struct_coords.html#aaea2c566feec4e4bf56b27a34568be76":[2,0,0,2], +"struct_coords.html#ad3347f6568814df1a2b98b3cd0b78632":[2,0,0,3], "struct_parameters___lattice.html":[2,0,4], "struct_parameters___lattice.html#a1b59e1a307ad945fb86f44b68354f605":[2,0,4,3], "struct_parameters___lattice.html#a40f8633b47d204f471d041a0d8216e5b":[2,0,4,6], diff --git a/docs/search/all_1.js b/docs/search/all_1.js index 2827a6d..fc19deb 100644 --- a/docs/search/all_1.js +++ b/docs/search/all_1.js @@ -11,8 +11,9 @@ var searchData= ['checkfinished',['checkFinished',['../class_simulation.html#af69bb46977a3a0084214a194c888e16c',1,'Simulation']]], ['checkmovevalidity',['checkMoveValidity',['../class_lattice.html#ad0592298c4b92e9e84a768b95cd6d0f0',1,'Lattice']]], ['choosenextevent',['chooseNextEvent',['../class_simulation.html#af8cf2e5c24531582599423df2d70dc5b',1,'Simulation']]], + ['chooserandomunoccupiedneighbor',['chooseRandomUnoccupiedNeighbor',['../class_lattice.html#abf954e8213010ab8aeac7a0b93a869bc',1,'Lattice']]], ['clearoccupancy',['clearOccupancy',['../class_lattice.html#a97a1b4f24cd40b81ed63aa2d7713b63b',1,'Lattice::clearOccupancy()'],['../class_site.html#a46ff077954e39046b493ee1ea57a9c93',1,'Site::clearOccupancy()']]], - ['coords',['Coords',['../struct_coords.html',1,'']]], - ['createexponentialdosvector',['createExponentialDOSVector',['../namespace_utils.html#af296d2aa8f889f67fe515fc641c5f5fe',1,'Utils']]], - ['creategaussiandosvector',['createGaussianDOSVector',['../namespace_utils.html#a2ce45ade7d6d4f2995b595da3ebbaaec',1,'Utils']]] + ['coords',['Coords',['../struct_coords.html',1,'Coords'],['../struct_coords.html#a5922d1783cefa759950faa50ac347191',1,'Coords::Coords()'],['../struct_coords.html#a246211bba85765d5d67953922070d11f',1,'Coords::Coords(const int xval, const int yval, const int zval)']]], + ['createexponentialdosvector',['createExponentialDOSVector',['../namespace_utils.html#a62ed21bf039a062d34511cd016cd9b59',1,'Utils']]], + ['creategaussiandosvector',['createGaussianDOSVector',['../namespace_utils.html#aa92dbcc79f8336fcd2d9644db1a2b0ae',1,'Utils']]] ]; diff --git a/docs/search/all_4.js b/docs/search/all_4.js index 148dbf5..612f209 100644 --- a/docs/search/all_4.js +++ b/docs/search/all_4.js @@ -4,7 +4,7 @@ var searchData= ['generaterandomx',['generateRandomX',['../class_lattice.html#ab78435e50e3bf9f376c04fc305785bb4',1,'Lattice']]], ['generaterandomy',['generateRandomY',['../class_lattice.html#a180a9d79a40b1a0a092c8ab489569700',1,'Lattice']]], ['generaterandomz',['generateRandomZ',['../class_lattice.html#a96006397a6ab389fb1eee87fde6e2165',1,'Lattice']]], - ['generator',['generator',['../class_simulation.html#a4c1d9071749e0fd93e70380cafb28417',1,'Simulation']]], + ['generator',['generator',['../class_simulation.html#a269659fa336a5563e2ccfe2db1654ba9',1,'Simulation']]], ['getalleventptrs',['getAllEventPtrs',['../class_simulation.html#aec6a6e1a80eb566685e4d257e6f872c5',1,'Simulation']]], ['getallobjectptrs',['getAllObjectPtrs',['../class_simulation.html#a620684b9ac1fb07344c4c2237ed9f352',1,'Simulation']]], ['getcoords',['getCoords',['../class_object.html#a08df08943dc634609fa69b356a37d73f',1,'Object']]], @@ -19,6 +19,7 @@ var searchData= ['getlength',['getLength',['../class_lattice.html#a4b43b67a36fcd3dfe62c9eeaffa561d2',1,'Lattice']]], ['getn_5fevents',['getN_events',['../class_simulation.html#a7d88f18a1ba988d7e77b8be8de5b10d1',1,'Simulation']]], ['getn_5fevents_5fexecuted',['getN_events_executed',['../class_simulation.html#a52cb5564151421cbefaca56357738de7',1,'Simulation']]], + ['getn_5fobjects_5fcreated',['getN_objects_created',['../class_simulation.html#ab07386326b1844df84464abe30927bf5',1,'Simulation']]], ['getnumsites',['getNumSites',['../class_lattice.html#a4be17e9123f7737387991a9d1a8b87b3',1,'Lattice']]], ['getobjectptr',['getObjectPtr',['../class_event.html#a5317d42bb07d0e75bec0c13bd9bf6de8',1,'Event::getObjectPtr()'],['../class_site.html#aecb14e440914b4d3d4aa7294419791e2',1,'Site::getObjectPtr()']]], ['getobjecttargetptr',['getObjectTargetPtr',['../class_event.html#ab86f724c3c894faa1d6ccca78c357d24',1,'Event']]], diff --git a/docs/search/all_6.js b/docs/search/all_6.js index 0065d14..51422a5 100644 --- a/docs/search/all_6.js +++ b/docs/search/all_6.js @@ -4,7 +4,7 @@ var searchData= ['incrementdx',['incrementDX',['../class_object.html#a3d7c877f4aa179d9a56050c5faddc18d',1,'Object']]], ['incrementdy',['incrementDY',['../class_object.html#a9df010818be72d15bad7985bf8a89ba0',1,'Object']]], ['incrementdz',['incrementDZ',['../class_object.html#a440b267c478f5d63db1954bdbd543408',1,'Object']]], - ['init',['init',['../class_lattice.html#a2b0a88048fae662aa71386a3a123a260',1,'Lattice::init()'],['../class_simulation.html#af88e5e0634b373ba28f1dd87670725a6',1,'Simulation::init()']]], + ['init',['init',['../class_lattice.html#ab7322e5340badb9df4d208554fd90a89',1,'Lattice::init()'],['../class_simulation.html#af88e5e0634b373ba28f1dd87670725a6',1,'Simulation::init()']]], ['integratedata',['integrateData',['../namespace_utils.html#a49411c9d4c7a065dbcf237aa27a84023',1,'Utils']]], ['interpolatedata',['interpolateData',['../namespace_utils.html#af68995497777ee14d812c65991a4046f',1,'Utils']]], ['intpow',['intpow',['../namespace_utils.html#affd19edaa58a3f8425e1f7b4c9233f8a',1,'Utils']]], diff --git a/docs/search/functions_1.js b/docs/search/functions_1.js index 5b87205..fd55459 100644 --- a/docs/search/functions_1.js +++ b/docs/search/functions_1.js @@ -11,7 +11,9 @@ var searchData= ['checkfinished',['checkFinished',['../class_simulation.html#af69bb46977a3a0084214a194c888e16c',1,'Simulation']]], ['checkmovevalidity',['checkMoveValidity',['../class_lattice.html#ad0592298c4b92e9e84a768b95cd6d0f0',1,'Lattice']]], ['choosenextevent',['chooseNextEvent',['../class_simulation.html#af8cf2e5c24531582599423df2d70dc5b',1,'Simulation']]], + ['chooserandomunoccupiedneighbor',['chooseRandomUnoccupiedNeighbor',['../class_lattice.html#abf954e8213010ab8aeac7a0b93a869bc',1,'Lattice']]], ['clearoccupancy',['clearOccupancy',['../class_lattice.html#a97a1b4f24cd40b81ed63aa2d7713b63b',1,'Lattice::clearOccupancy()'],['../class_site.html#a46ff077954e39046b493ee1ea57a9c93',1,'Site::clearOccupancy()']]], - ['createexponentialdosvector',['createExponentialDOSVector',['../namespace_utils.html#af296d2aa8f889f67fe515fc641c5f5fe',1,'Utils']]], - ['creategaussiandosvector',['createGaussianDOSVector',['../namespace_utils.html#a2ce45ade7d6d4f2995b595da3ebbaaec',1,'Utils']]] + ['coords',['Coords',['../struct_coords.html#a5922d1783cefa759950faa50ac347191',1,'Coords::Coords()'],['../struct_coords.html#a246211bba85765d5d67953922070d11f',1,'Coords::Coords(const int xval, const int yval, const int zval)']]], + ['createexponentialdosvector',['createExponentialDOSVector',['../namespace_utils.html#a62ed21bf039a062d34511cd016cd9b59',1,'Utils']]], + ['creategaussiandosvector',['createGaussianDOSVector',['../namespace_utils.html#aa92dbcc79f8336fcd2d9644db1a2b0ae',1,'Utils']]] ]; diff --git a/docs/search/functions_4.js b/docs/search/functions_4.js index f947895..ba897c6 100644 --- a/docs/search/functions_4.js +++ b/docs/search/functions_4.js @@ -18,6 +18,7 @@ var searchData= ['getlength',['getLength',['../class_lattice.html#a4b43b67a36fcd3dfe62c9eeaffa561d2',1,'Lattice']]], ['getn_5fevents',['getN_events',['../class_simulation.html#a7d88f18a1ba988d7e77b8be8de5b10d1',1,'Simulation']]], ['getn_5fevents_5fexecuted',['getN_events_executed',['../class_simulation.html#a52cb5564151421cbefaca56357738de7',1,'Simulation']]], + ['getn_5fobjects_5fcreated',['getN_objects_created',['../class_simulation.html#ab07386326b1844df84464abe30927bf5',1,'Simulation']]], ['getnumsites',['getNumSites',['../class_lattice.html#a4be17e9123f7737387991a9d1a8b87b3',1,'Lattice']]], ['getobjectptr',['getObjectPtr',['../class_event.html#a5317d42bb07d0e75bec0c13bd9bf6de8',1,'Event::getObjectPtr()'],['../class_site.html#aecb14e440914b4d3d4aa7294419791e2',1,'Site::getObjectPtr()']]], ['getobjecttargetptr',['getObjectTargetPtr',['../class_event.html#ab86f724c3c894faa1d6ccca78c357d24',1,'Event']]], diff --git a/docs/search/functions_5.js b/docs/search/functions_5.js index 0065d14..51422a5 100644 --- a/docs/search/functions_5.js +++ b/docs/search/functions_5.js @@ -4,7 +4,7 @@ var searchData= ['incrementdx',['incrementDX',['../class_object.html#a3d7c877f4aa179d9a56050c5faddc18d',1,'Object']]], ['incrementdy',['incrementDY',['../class_object.html#a9df010818be72d15bad7985bf8a89ba0',1,'Object']]], ['incrementdz',['incrementDZ',['../class_object.html#a440b267c478f5d63db1954bdbd543408',1,'Object']]], - ['init',['init',['../class_lattice.html#a2b0a88048fae662aa71386a3a123a260',1,'Lattice::init()'],['../class_simulation.html#af88e5e0634b373ba28f1dd87670725a6',1,'Simulation::init()']]], + ['init',['init',['../class_lattice.html#ab7322e5340badb9df4d208554fd90a89',1,'Lattice::init()'],['../class_simulation.html#af88e5e0634b373ba28f1dd87670725a6',1,'Simulation::init()']]], ['integratedata',['integrateData',['../namespace_utils.html#a49411c9d4c7a065dbcf237aa27a84023',1,'Utils']]], ['interpolatedata',['interpolateData',['../namespace_utils.html#af68995497777ee14d812c65991a4046f',1,'Utils']]], ['intpow',['intpow',['../namespace_utils.html#affd19edaa58a3f8425e1f7b4c9233f8a',1,'Utils']]], diff --git a/docs/search/variables_1.js b/docs/search/variables_1.js index eba0f65..969d096 100644 --- a/docs/search/variables_1.js +++ b/docs/search/variables_1.js @@ -1,4 +1,4 @@ var searchData= [ - ['generator',['generator',['../class_simulation.html#a4c1d9071749e0fd93e70380cafb28417',1,'Simulation']]] + ['generator',['generator',['../class_simulation.html#a269659fa336a5563e2ccfe2db1654ba9',1,'Simulation']]] ]; diff --git a/docs/struct_coords-members.html b/docs/struct_coords-members.html index 17e11e1..adfdcbd 100644 --- a/docs/struct_coords-members.html +++ b/docs/struct_coords-members.html @@ -94,6 +94,8 @@

    This is the complete list of members for Coords, including all inherited members.

    + + diff --git a/docs/struct_coords.html b/docs/struct_coords.html index 150a4c7..2c420f4 100644 --- a/docs/struct_coords.html +++ b/docs/struct_coords.html @@ -103,6 +103,13 @@
    Coords()Coordsinline
    Coords(const int xval, const int yval, const int zval)Coordsinline
    operator!=(const Coords &rhs) constCoordsinline
    operator==(const Coords &rhs) constCoordsinline
    setXYZ(const int xval, const int yval, const int zval)Coordsinline
    + + + + + + @@ -133,7 +140,60 @@
    Author
    Michael C. Heiber
    Date
    2018
    -

    Member Function Documentation

    +

    Constructor & Destructor Documentation

    + +

    ◆ Coords()

    + +
    +
    +

    Public Member Functions

    Coords ()
     Default constructor that creates an empty Coords object.
     
     Coords (const int xval, const int yval, const int zval)
     Constructor that creates a Coords object with the x,y,z coordinates set using the input values xval, yval, and zval. More...
     
    void setXYZ (const int xval, const int yval, const int zval)
     Sets the x,y,z coordinates using the input values xval, yval, and zval. More...
     
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    Coords::Coords (const int xval,
    const int yval,
    const int zval 
    )
    +
    +inline
    +
  • + +

    Constructor that creates a Coords object with the x,y,z coordinates set using the input values xval, yval, and zval.

    +
    Parameters
    + + + + +
    xvalis the input x value.
    yvalis the input y value.
    zvalis the input z value.
    +
    +
    + +
    +
    +

    Member Function Documentation

    ◆ operator!=()

    diff --git a/docs/struct_coords.js b/docs/struct_coords.js index a6974be..b05b4f3 100644 --- a/docs/struct_coords.js +++ b/docs/struct_coords.js @@ -1,5 +1,7 @@ var struct_coords = [ + [ "Coords", "struct_coords.html#a5922d1783cefa759950faa50ac347191", null ], + [ "Coords", "struct_coords.html#a246211bba85765d5d67953922070d11f", null ], [ "operator!=", "struct_coords.html#aaea2c566feec4e4bf56b27a34568be76", null ], [ "operator==", "struct_coords.html#ad3347f6568814df1a2b98b3cd0b78632", null ], [ "setXYZ", "struct_coords.html#a88de3a6ee710766eb9c9444cee45a9f3", null ], From c8515731e39b64152f1966632b9b6ac94b81c53a Mon Sep 17 00:00:00 2001 From: "Michael C. Heiber" Date: Tue, 15 May 2018 16:36:02 -0400 Subject: [PATCH 36/37] Lattice Class Testing Update -reduced test calculation time for several tests -added test for chooseRandomUnoccupiedNeighbor function when all neighbor are occupied --- test/test.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/test/test.cpp b/test/test.cpp index be6cae2..ef80417 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -796,7 +796,7 @@ namespace LatticeTests { TEST_F(LatticeTest, RandomUnoccupiedNeighborTests) { vector data(30000); - for (int i = 0; i < 8; i++) { + for (int i = 0; i < 6; i++) { Coords coords = lattice.generateRandomCoords(); for (auto& item : data) { Coords coords_new = lattice.chooseRandomUnoccupiedNeighbor(coords); @@ -811,6 +811,16 @@ namespace LatticeTests { EXPECT_NEAR(1.0 / 6.0, (double)count/(double)data.size(), 1e-2); } } + // Check for correct output when all neighbor sites are occupied + Coords coords(5,5,5); + lattice.setOccupied(Coords(4,5,5)); + lattice.setOccupied(Coords(6,5,5)); + lattice.setOccupied(Coords(5,4,5)); + lattice.setOccupied(Coords(5,6,5)); + lattice.setOccupied(Coords(5,5,4)); + lattice.setOccupied(Coords(5,5,6)); + Coords coords_new = lattice.chooseRandomUnoccupiedNeighbor(coords); + EXPECT_TRUE(coords_new==Coords(-1,-1,-1)); } TEST_F(LatticeTest, 2DTests) { @@ -833,7 +843,7 @@ namespace LatticeTests { lattice2D.setSitePointers(site_ptrs); // Check random neighbor site generation in 2D vector data(30000); - for (int i = 0; i < 8; i++) { + for (int i = 0; i < 6; i++) { Coords coords = lattice2D.generateRandomCoords(); for (auto& item : data) { item = lattice2D.getSiteIndex(lattice2D.chooseRandomUnoccupiedNeighbor(coords)); @@ -868,7 +878,7 @@ namespace LatticeTests { lattice1D.setSitePointers(site_ptrs); // Check random neighbor site generation in 1D vector data(30000); - for (int i = 0; i < 8; i++) { + for (int i = 0; i < 6; i++) { Coords coords = lattice1D.generateRandomCoords(); for (auto& item : data) { item = lattice1D.getSiteIndex(lattice1D.chooseRandomUnoccupiedNeighbor(coords)); From 8d0768f03d0564235092339ed7bce712513627d1 Mon Sep 17 00:00:00 2001 From: "Michael C. Heiber" Date: Tue, 15 May 2018 17:03:27 -0400 Subject: [PATCH 37/37] Readme Update -edited the readme and corrected a few minor errors. --- README.md | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index f17fef4..54e0c68 100644 --- a/README.md +++ b/README.md @@ -7,15 +7,15 @@ The goal of this package is to be robust, reliable, and flexible so that users c This KMC_Lattice package implements several event recalculation options for creating computationally efficient simulations. The package is designed to be usable on a personal computer and on high performance computing clusters. -Check out the [Excimontec](https://github.com/MikeHeiber/Excimontec) software package for an example of a complex tool constructed using KMC_Lattice, which is used for simulating organic semiconductor materials and devices. +Check out the [Excimontec](https://github.com/MikeHeiber/Excimontec) software package for an example of a complex tool constructed using KMC_Lattice, which is used for simulating organic semiconductor devices. -For further reading about kinetic Monte Carlo simulations, a nice overview of the theory and algorithm can be found here: +For further reading about kinetic Monte Carlo simulations, a nice overview of the theory and algorithms can be found here: [Introduction to the Kinetic Monte Carlo Method by Arthur Voter, Los Alamos National Lab](http://www.fml.t.u-tokyo.ac.jp/~izumi/CMS/MC/Introduction_kMC.pdf) ## Current Status -The current release is KMC_Lattice [![GitHub (pre-)release](https://img.shields.io/github/release/MikeHeiber/KMC_Lattice/all.svg?style=flat-square)](https://github.com/MikeHeiber/KMC_Lattice/releases) +The current release is KMC_Lattice [![GitHub (pre-)release](https://img.shields.io/github/release/MikeHeiber/KMC_Lattice/all.svg?style=flat-square)](https://github.com/MikeHeiber/KMC_Lattice/releases). Most major planned features that are to be included in v2.0 are now implemented and have undergone preliminary testing. However, this software tool is still under development, and as such, there may still be bugs that need to be squashed. Please report any bugs or submit feature requests in the [Issues](https://github.com/MikeHeiber/KMC_Lattice/issues) section. @@ -38,7 +38,7 @@ Code is being tested using [googletest](https://github.com/google/googletest) wi ## Contact -If you would like to contribute to the development of this project or would like some help in using the tool for your research, please contact me (heiber@mailaps.org) to discuss a collaboration. +If you would like to contribute to the development of this project or would like some help in building an efficient KMC simulation tool for your specific scientific problem, please contact me (heiber@mailaps.org) to discuss a collaboration. You can check out my KMC research and other work on [Researchgate](https://www.researchgate.net/profile/Michael_Heiber). ## How to try KMC_Lattice? @@ -47,9 +47,8 @@ You can check out my KMC research and other work on [Researchgate](https://www.r This software tool uses [Message Passing Interface (MPI)](https://computing.llnl.gov/tutorials/mpi/) to utilize parallel computing power. As a result, using KMC_Lattice requires that an MPI library is pre-installed on your system, and the final KMC_Lattice library must be built on your specific system. -We cannot provide pre-built binaries for your system. -Contact your HPC admin to determine the protocols for building MPI applications on your HPC system. -In many cases, the HPC system will already be configured for you, and the package comes with a default makefile that can be used with the [GCC compiler](https://gcc.gnu.org/) or the [PGI compiler](https://www.pgroup.com/). +Contact your HPC admin to determine the protocols for building MPI applications on your specific HPC system. +In many cases, the HPC system and environment will already be configured for you, and the package comes with a default makefile that can be used with the [GCC compiler](https://gcc.gnu.org/) or the [PGI compiler](https://www.pgroup.com/). If you wish, you can also install MPI on your own personal workstation and then build the KMC_Lattice library there as well. For development and preliminary simulation tests, sometimes it is more efficient to run on your own workstation instead of an HPC system. More information about common MPI packages can be found here: - Open MPI, http://www.open-mpi.org/ @@ -57,17 +56,12 @@ If you wish, you can also install MPI on your own personal workstation and then - MVAPICH, http://mvapich.cse.ohio-state.edu/ Once you have an MPI library installed, to build the KMC_Lattice library, copy the KMC_Lattice directory to your machine, set it as your working directory, and run `make`. -Compilation flags have been set for GCC and PGI compilers. If you are using another compiler, you will need to edit the makefile and define your own compiler options. +Compilation flags have been set for the GCC and PGI compilers. If you are using another compiler, you may need to edit the makefile and define your own compiler options. However, before you use the KMC_Lattice library, you should test it on your own hardware using the unit and system tests provided. Build the testing executable by running `make test`. Once the test build is complete, run `./test/KMC_Lattice_tests.exe`. Please report any build or testing errors in the [Issues](https://github.com/MikeHeiber/KMC_Lattice/issues) section. -## Contact - -If you would like to contribute to the development of this project or would like some help in building an efficient KMC simulation tool for your specific scientific problem, please contact me to discuss a collaboration. -You can check out my KMC research and other work on [Researchgate](https://www.researchgate.net/profile/Michael_Heiber). - ## Package Contents Object class - This base class can be extended to represent any entity that one would like to simulate. @@ -88,6 +82,6 @@ For example, site energies can be assigned to derived site classes to account fo Simulation class - This base class can be extended to manage all derived objects and their associated events. The Simulation class contains the fundamental properties and back-end operations that most simulations would require. -Utils - This file contain a number of useful utility functions, scientific constants, etc. that can then be used throughout the software package. +Utils - This contains a number of useful utility functions, scientific constants, etc. that can then be used throughout the software package. Detailed API documentation for these classes and the entire KMC_Lattice package can be viewed [here](https://mikeheiber.github.io/KMC_Lattice/).