Commit d1f4c9ed authored by niklas.baumgarten's avatar niklas.baumgarten
Browse files

refactored main

parent 6e00674f
...@@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.5.1) ...@@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.5.1)
project(MLMC) project(MLMC)
#---------------------------------------------------------------------------------------# #---------------------------------------------------------------------------------------#
#set(CMAKE_CXX_FLAGS_DISTRIBUTION "-O0") set(CMAKE_CXX_FLAGS_DISTRIBUTION "-O0")
#set(CMAKE_CXX_FLAGS_DISTRIBUTION "-O1") #set(CMAKE_CXX_FLAGS_DISTRIBUTION "-O1")
#set(CMAKE_CXX_FLAGS_DISTRIBUTION "-O2") #set(CMAKE_CXX_FLAGS_DISTRIBUTION "-O2")
#set(CMAKE_CXX_FLAGS_DISTRIBUTION "-O3") #set(CMAKE_CXX_FLAGS_DISTRIBUTION "-O3")
...@@ -34,11 +34,11 @@ include_directories(${PROJECT_SOURCE_DIR}/mlmc/src) ...@@ -34,11 +34,11 @@ include_directories(${PROJECT_SOURCE_DIR}/mlmc/src)
# Subdirectories # Subdirectories
add_subdirectory(mlmc/src) add_subdirectory(mlmc/src)
add_subdirectory(mlmc/tests) add_subdirectory(tests)
#---------------------------------------------------------------------------------------# #---------------------------------------------------------------------------------------#
# Executables # Executables
add_executable(MLMC-M++ mlmc/src/Main.C) add_executable(MLMC-M++ mlmc/src/Main.cpp)
# Linking # Linking
target_link_libraries(MLMC-M++ MLMC sprng SRC LIB_PS ${SUPERLU} target_link_libraries(MLMC-M++ MLMC sprng SRC LIB_PS ${SUPERLU}
......
set(MLMC_SRC set(MLMC_SRC
Main.C Main.cpp
Utils.C Utils.C
MLMCMain.C MainProgram.cpp
MultilevelMonteCarlo.C MultilevelMonteCarlo.cpp
utils/IndentedLogger.cpp utils/IndentedLogger.cpp
mc/MonteCarlo.cpp mc/MonteCarlo.cpp
mc/MonteCarloElliptic.C mc/MonteCarloElliptic.cpp
mc/MonteCarloTransport.C mc/MonteCarloTransport.cpp
assemble/EllipticAssemble.C assemble/EllipticAssemble.C
assemble/MixedEllipticAssemble.C assemble/MixedEllipticAssemble.C
assemble/HybridEllipticAssemble.C assemble/HybridEllipticAssemble.C
assemble/DGEllipticAssemble.C assemble/DGEllipticAssemble.C
stochastics/RNManager.C stochastics/RNManager.C
stochastics/CirculantEmbedding.C stochastics/CirculantEmbedding.C
problem/StochasticEllipticProblem.hpp stochastics/SampleGenerator.h stochastics/HybridFluxGenerator.C stochastics/HybridFluxGenerator.h problem/StochasticProblemFactory.hpp mc/MonteCarlo.cpp utils/MultilevelPlotter.cpp utils/MultilevelPlotter.hpp utils/MatrixGraphContainer.cpp utils/MatrixGraphContainer.hpp) problem/StochasticEllipticProblem.hpp
stochastics/SampleGenerator.h
stochastics/HybridFluxGenerator.C
stochastics/HybridFluxGenerator.h
mc/MonteCarlo.cpp
utils/MultilevelPlotter.cpp
utils/MultilevelPlotter.hpp
)
add_library(MLMC STATIC ${MLMC_SRC}) add_library(MLMC STATIC ${MLMC_SRC})
...@@ -10,18 +10,19 @@ void MainProgram::Initialize() { ...@@ -10,18 +10,19 @@ void MainProgram::Initialize() {
problem = createStochasticProblem(); problem = createStochasticProblem();
assemble = createAssemble(); assemble = createAssemble();
plots = new MultilevelPlotter(*meshes); plots = make_unique<MultilevelPlotter>(*meshes);
mlmc = new MultilevelMonteCarlo(initLevels, initSampleAmount, meshes, *plots, mlmc = make_unique<MultilevelMonteCarlo>(initLevels, initSampleAmount, meshes,
stochField, assemble); stochField, assemble, plots);
} }
void MainProgram::Run() { void MainProgram::Run() {
this->PrintInfo(); this->PrintInfo();
mlmc->PrintInfo();
meshes->PrintInfo(); meshes->PrintInfo();
// disc->PrintInfo();
// stochField->PrintInfo();
// assemble->PrintInfo(); // assemble->PrintInfo();
// Stochastic field info mlmc->PrintInfo();
if (experimentName == "ConvergenceTest") { if (experimentName == "ConvergenceTest") {
headConvergenceTest(); headConvergenceTest();
...@@ -36,11 +37,6 @@ void MainProgram::Run() { ...@@ -36,11 +37,6 @@ void MainProgram::Run() {
mlmc->ShowResultsMLMCRun(epsilon); mlmc->ShowResultsMLMCRun(epsilon);
mlmc->ShowKurtosisWarning(); mlmc->ShowKurtosisWarning();
mlmc->ShowExponentResults(); mlmc->ShowExponentResults();
} else if (experimentName == "MLMCOverEpsilon") {
headMLMCOverEpsilon();
mlmc->Method(epsilonList);
mlmc->ShowMCTable();
mlmc->ShowResultsOverEpsilon(epsilonList);
} }
} }
...@@ -53,91 +49,124 @@ void MainProgram::PrintInfo() { ...@@ -53,91 +49,124 @@ void MainProgram::PrintInfo() {
<< " Experiment: " << experimentName << endl; << " Experiment: " << experimentName << endl;
if (experimentName == "MLMCExperiment") if (experimentName == "MLMCExperiment")
Vout(1) << " epsilon: " << epsilon << endl; Vout(1) << " epsilon: " << epsilon << endl;
if (experimentName == "MLMCOverEpsilon")
Vout(1) << " epsilonList: " << vec2str(epsilonList) << endl;
Vout(1) << endl; Vout(1) << endl;
} }
unique_ptr<Meshes> MainProgram::createMeshes() { void MainProgram::checkValues() {
if (verbose == -1) Exit("\nPlease set MainVerbose\n")
if (problemName.empty()) Exit("\nPlease set Problem\n")
if (modelName.empty()) Exit("\nPlease set Model\n")
if (problemName.empty()) Exit("\nPlease set StochasticField\n")
if (experimentName.empty()) Exit("\nPlease set Experiment\n")
if (epsilon == 0.0 &&
experimentName != "ConvergenceTest") Exit("\nPlease set epsilon\n")
if (pLevel == -1) Exit("\nPlease set plevel\n")
if (maxLevel == -1) Exit("\nPlease set maxLevel\n")
if (degree == -1) Exit("\nPlease set degree\n")
if (initLevels.empty()) Exit("\nPlease set initLevels\n")
if (initSampleAmount.empty() && experimentName == "MLMCExperiment") Exit(
"\nPlease set initSampleAmount\n")
if (experimentName == "ConvergenceTest") {
if (uniformSampleAmount != -1) Exit("\nPlease set uniformSampleAmount\n")
initSampleAmount = {};
for (auto &level: initLevels)
initSampleAmount.push_back(uniformSampleAmount);
}
if (initSampleAmount.size() != initLevels.size()) Exit(
"\ninitLevels and initSampleAmount have to be of the same size\n")
if (maxLevel < initLevels.back()) Exit(
"\nLast element of initLevels has to be smaller or equal to maxLevel\n")
}
shared_ptr<Meshes> MainProgram::createMeshes() {
if (problemName.find("1D") != string::npos) if (problemName.find("1D") != string::npos)
return make_unique<Meshes>("Line", pLevel, maxLevel); return make_unique<Meshes>("Line", pLevel, maxLevel);
if (problemName.find("2D") != string::npos) if (problemName.find("2D") != string::npos)
return make_unique<Meshes>("UnitSquare", pLevel, maxLevel); return make_shared<Meshes>("UnitSquare", pLevel, maxLevel);
Exit("\nMesh not found in " + problemName + "\n") Exit("\nMesh not found in " + problemName + "\n")
} }
unique_ptr<Discretization> MainProgram::createDiscretization() { shared_ptr<Discretization> MainProgram::createDiscretization() {
if (modelName == "LagrangeFEM" && degree == 1) if (modelName == "LagrangeFEM" && degree == 1)
return make_unique<Discretization>("linear", 1, meshes->dim()); return make_shared<Discretization>("linear", 1, meshes->dim());
if (modelName == "LagrangeFEM" && degree == 2) if (modelName == "LagrangeFEM" && degree == 2)
return make_unique<Discretization>("serendipity", 1, meshes->dim()); return make_shared<Discretization>("serendipity", 1, meshes->dim());
if (modelName == "MixedFEM" || modelName == "HybridFEM") if (modelName == "MixedFEM" || modelName == "HybridFEM")
return make_unique<Discretization>("RT0_P0", 1, meshes->dim()); return make_shared<Discretization>("RT0_P0", 1, meshes->dim());
if (modelName == "DGFEM") if (modelName == "DGFEM")
return make_unique<DGDiscretization>(new DGDoF(degree)); return make_shared<DGDiscretization>(new DGDoF(degree));
if (modelName == "DGTransport") if (modelName == "DGTransport")
return make_unique<DGDiscretization>(new DGDoF(degree)); return make_shared<DGDiscretization>(new DGDoF(degree));
Exit("\nDiscretization not found in " + modelName + "\n") Exit("\nDiscretization not found in " + modelName + "\n")
} }
unique_ptr<StochasticField> MainProgram::createStochasticField() { shared_ptr<StochasticField> MainProgram::createStochasticField() {
if (meshes == nullptr) Exit(
"\nMeshes have to be initialized to create stochastic field\n")
if (problemName.find("Stochastic") != string::npos) { if (problemName.find("Stochastic") != string::npos) {
if (problemName.find("Laplace") != string::npos) if (problemName.find("Laplace") != string::npos)
return make_unique<StochasticField>(*meshes, "CirculantEmbedding"); return make_shared<StochasticField>(*(meshes.get()), "CirculantEmbedding");
if (problemName.find("Pollution") != string::npos) if (problemName.find("Pollution") != string::npos)
return make_unique<StochasticField>(*meshes, "HybridFluxGenerator"); return make_shared<StochasticField>(*(meshes.get()), "HybridFluxGenerator");
} }
if (problemName.find("Deterministic") != string::npos) { if (problemName.find("Deterministic") != string::npos) {
if (problemName.find("Laplace") != string::npos) if (problemName.find("Laplace") != string::npos)
return make_unique<StochasticField>( return make_shared<StochasticField>(
*meshes, "DeterministicPermeabilityGenerator"); *(meshes.get()), "DeterministicPermeabilityGenerator");
if (problemName.find("Pollution") != string::npos) if (problemName.find("Pollution") != string::npos)
return make_unique<StochasticField>( return make_shared<StochasticField>(
*meshes, "DeterministicHybridFluxGenerator"); *(meshes.get()), "DeterministicHybridFluxGenerator");
} }
Exit("\nStochastic field not found in " + problemName + "\n")
} }
unique_ptr<StochasticProblem> MainProgram::createStochasticProblem() { shared_ptr<StochasticProblem> MainProgram::createStochasticProblem() {
if (problemName.find("StochasticLaplace1D") != -1 || if (problemName.find("StochasticLaplace1D") != string::npos ||
problemName.find("DeterministicLaplace1D") != -1) problemName.find("DeterministicLaplace1D") != string::npos)
return make_unique<StochasticLaplace1D>(); return make_shared<StochasticLaplace1D>();
if (problemName.find("StochasticLaplace2D") != -1 || if (problemName.find("StochasticLaplace2D") != string::npos ||
problemName.find("DeterministicLaplace2D") != -1) problemName.find("DeterministicLaplace2D") != string::npos)
return make_unique<StochasticLaplace2D>(); return make_shared<StochasticLaplace2D>();
if (problemName.find("StochasticPollution1D") != -1 || if (problemName.find("StochasticPollution1D") != string::npos ||
problemName.find("DeterministicPollution1D") != -1) problemName.find("DeterministicPollution1D") != string::npos)
return make_unique<StochasticPollution1D>(); return make_shared<StochasticPollution1D>();
if (problemName.find("StochasticPollutionCosHat1D") != -1 || if (problemName.find("StochasticPollutionCosHat1D") != string::npos ||
problemName.find("DeterministicPollutionCosHat1D") != -1) problemName.find("DeterministicPollutionCosHat1D") != string::npos)
return make_unique<StochasticPollutionCosHat1D>(); return make_shared<StochasticPollutionCosHat1D>();
if (problemName.find("StochasticPollution2D") != -1 || if (problemName.find("StochasticPollution2D") != string::npos ||
problemName.find("DeterministicPollution2D") != -1) problemName.find("DeterministicPollution2D") != string::npos)
return make_unique<StochasticPollution2D>(); return make_shared<StochasticPollution2D>();
if (problemName.find("StochasticPollutionCosHat2D") != -1 || if (problemName.find("StochasticPollutionCosHat2D") != string::npos ||
problemName.find("DeterministicPollutionCosHat2D") != -1) problemName.find("DeterministicPollutionCosHat2D") != string::npos)
return make_unique<StochasticPollutionCosHat2D>(); return make_shared<StochasticPollutionCosHat2D>();
if (problemName.find("StochasticPollutionMollifiedBar2D") != -1 || if (problemName.find("StochasticPollutionMollifiedBar2D") != string::npos ||
problemName.find("DeterministicPollutionMollifiedBar2D") != -1) problemName.find("DeterministicPollutionMollifiedBar2D") != string::npos)
return make_unique<StochasticPollutionMollifiedBar2D>(); return make_shared<StochasticPollutionMollifiedBar2D>();
Exit("\nProblem field not found in " + problemName + "\n")
} }
unique_ptr<Assemble> MainProgram::createAssemble() { shared_ptr<Assemble> MainProgram::createAssemble() {
if (problemName.find("Laplace") != string::npos) { shared_ptr<StochasticEllipticProblem> ellipticProblem =
auto ellipticProblem = dynamic_cast<StochasticEllipticProblem *>(problem.get()); dynamic_pointer_cast<StochasticEllipticProblem>(problem);
shared_ptr<StochasticTransportProblem> transportProblem =
dynamic_pointer_cast<StochasticTransportProblem>(problem);
if (ellipticProblem != nullptr) {
if (modelName == "LagrangeFEM") if (modelName == "LagrangeFEM")
return make_unique<EllipticAssemble>(disc, ellipticProblem); return make_shared<EllipticAssemble>(disc, ellipticProblem);
if (modelName == "MixedFEM") if (modelName == "MixedFEM")
return new MixedEllipticAssemble(disc, ellipticProblem); return make_shared<MixedEllipticAssemble>(disc, ellipticProblem);
if (modelName == "HybridFEM") if (modelName == "HybridFEM")
return new HybridEllipticAssemble(disc, ellipticProblem); return make_shared<HybridEllipticAssemble>(disc, ellipticProblem);
if (modelName == "DGFEM") if (modelName == "DGFEM")
return new DGEllipticAssemble(disc, ellipticProblem); return make_shared<DGEllipticAssemble>(disc, ellipticProblem);
} else if (problemName.find("Pollution") != string::npos) {
auto transportProblem = dynamic_cast<StochasticTransportProblem *>(problem);
Plot plot(meshes->fine(), meshes->dim(), 2);
return new DGTransportAssemble(disc, transportProblem, &plot);
} }
Exit("\nAssembling for this problem not implemented yet\n")
// Todo
if (transportProblem != nullptr) {
return nullptr;
// Plot plot(meshes->fine(), meshes->dim(), 2);
// return make_shared<DGTransportAssemble>(disc, transportProblem, &plot);
}
Exit("\nAssembling for this problem with this discretization not implemented\n")
} }
...@@ -3,37 +3,40 @@ ...@@ -3,37 +3,40 @@
#include "assemble/AssembleHeader.h" #include "assemble/AssembleHeader.h"
#include "problem/StochasticEllipticProblem.hpp" #include "problem/StochasticEllipticProblem.hpp"
#include "MultilevelMonteCarlo.h" #include "MultilevelMonteCarlo.hpp"
#include "discretization/DGDiscretization.h" #include "discretization/DGDiscretization.h"
#include "stochastics/StochasticField.h" #include "stochastics/StochasticField.h"
#include "utils/MultilevelPlotter.hpp" #include "utils/MultilevelPlotter.hpp"
#include "utils/MatrixGraphContainer.hpp" #include <memory>
class MainProgram { class MainProgram {
public: public:
int verbose = 0; int verbose = -1;
string problemName = "", modelName = ""; string problemName = "";
string fieldName = "", experimentName = ""; string modelName = "";
string fieldName = "";
string experimentName = "";
double epsilon = 0.1; double epsilon = 0.0;
int pLevel = 0; int pLevel = -1;
int maxLevel = 8; int maxLevel = -1;
int degree = 0; int degree = -1;
vector<int> initLevels = {3, 4, 5}; vector<int> initLevels;
vector<int> initSampleAmount = {12, 6, 3}; vector<int> initSampleAmount;
vector<double> epsilonList = {0.1, 0.05, 0.01}; int uniformSampleAmount = -1;
unique_ptr<Meshes> meshes = nullptr; shared_ptr<Meshes> meshes;
unique_ptr<Discretization> disc = nullptr; shared_ptr<Discretization> disc;
unique_ptr<StochasticField> stochField = nullptr; shared_ptr<StochasticField> stochField;
unique_ptr<StochasticProblem> problem = nullptr;
unique_ptr<Assemble> assemble = nullptr;
MultilevelPlotter *plots = nullptr; shared_ptr<StochasticProblem> problem;
MultilevelMonteCarlo *mlmc = nullptr; shared_ptr<Assemble> assemble;
shared_ptr<MultilevelPlotter> plots;
shared_ptr<MultilevelMonteCarlo> mlmc;
MainProgram() { MainProgram() {
config.get("MainVerbose", verbose); config.get("MainVerbose", verbose);
...@@ -43,31 +46,13 @@ public: ...@@ -43,31 +46,13 @@ public:
config.get("degree", degree); config.get("degree", degree);
config.get("initLevels", initLevels); config.get("initLevels", initLevels);
config.get("initSampleAmount", initSampleAmount); config.get("initSampleAmount", initSampleAmount);
config.get("epsilonList", epsilonList); config.get("uniformSampleAmount", uniformSampleAmount);
config.get("Problem", problemName); config.get("Problem", problemName);
config.get("Model", modelName); config.get("Model", modelName);
config.get("StochasticField", fieldName); config.get("StochasticField", fieldName);
config.get("Experiment", experimentName); config.get("Experiment", experimentName);
if (initSampleAmount.size() != initLevels.size() checkValues();
&& experimentName != "ConvergenceTest") Exit(
"\ninitLevels and initSampleAmount have to be of the same size.\n")
if (maxLevel < initLevels.back()) Exit(
"\nLast element of initLevels has to be smaller or equal to maxLevel.\n")
int uniformSampleAmount;
config.get("uniformSampleAmount", uniformSampleAmount);
if (experimentName == "ConvergenceTest") {
initSampleAmount = {};
for (auto &level: initLevels)
initSampleAmount.push_back(uniformSampleAmount);
}
}
~MainProgram() {
delete problem;
delete assemble;
delete mlmc;
} }
void Run(); void Run();
...@@ -77,16 +62,17 @@ public: ...@@ -77,16 +62,17 @@ public:
void PrintInfo(); void PrintInfo();
private: private:
void checkValues();
unique_ptr<Meshes> createMeshes(); shared_ptr<Meshes> createMeshes();
unique_ptr<Discretization> createDiscretization(); shared_ptr<Discretization> createDiscretization();
unique_ptr<StochasticField> createStochasticField(); shared_ptr<StochasticField> createStochasticField();
unique_ptr<StochasticProblem> createStochasticProblem(); shared_ptr<StochasticProblem> createStochasticProblem();
unique_ptr<Assemble> createAssemble(); shared_ptr<Assemble> createAssemble();
static void headConvergenceTest() { static void headConvergenceTest() {
mout << endl << "**********************************************************" mout << endl << "**********************************************************"
...@@ -97,14 +83,7 @@ private: ...@@ -97,14 +83,7 @@ private:
static void headMLMCExperiment() { static void headMLMCExperiment() {
mout << endl << "**********************************************************" mout << endl << "**********************************************************"
<< endl << "*** MultilevelMonteCarlo test run ***" << endl << "*** Run Multilevel Monte Carlo Method ***"
<< endl << "**********************************************************"
<< endl;
}
static void headMLMCOverEpsilon() {
mout << endl << "**********************************************************"
<< endl << "*** MultilevelMonteCarlo over epsilon ***"
<< endl << "**********************************************************" << endl << "**********************************************************"
<< endl; << endl;
} }
......
...@@ -14,7 +14,7 @@ file(MAKE_DIRECTORY ${PROJECT_TEST_BINARY_DIR}/data/dual) ...@@ -14,7 +14,7 @@ file(MAKE_DIRECTORY ${PROJECT_TEST_BINARY_DIR}/data/dual)
# Test Executables # Test Executables
add_executable(TestMainProgram ${PROJECT_TEST_DIR}/TestMainProgram.cpp) add_executable(TestMainProgram ${PROJECT_TEST_DIR}/TestMainProgram.cpp TestEllipticMonteCarlo.cpp)
# Linking # Linking
target_link_libraries(TestMainProgram MLMC sprng SRC LIB_PS fftw3 m ${SUPERLU} target_link_libraries(TestMainProgram MLMC sprng SRC LIB_PS fftw3 m ${SUPERLU}
......
...@@ -5,21 +5,34 @@ ...@@ -5,21 +5,34 @@
using namespace ::testing; using namespace ::testing;
class TestMainProgram : public ::Test {
protected:
map<string, string> configMapMLMCExperiment = {
{"MainVerbose", "0"},
{"Problem", "StochasticLaplace1D"},
{"Model", "LagrangeFEM"},
{"Experiment", "MLMCExperiment"},
{"epsilon", "0.1"},
{"plevel", "0"},
{"maxLevel", "8"},
{"degree", "1"},
{"initLevels", "[3, 4, 5]"},
{"initSampleAmount", "[12, 6, 3]"}
};
std::unique_ptr<MainProgram> mainProgram;
void SetUp() override {
config = Config(configMapMLMCExperiment);
mainProgram = std::make_unique<MainProgram>();
mainProgram->Initialize();
}
};
TEST(MainProgram, TestConstructor) { TEST_F(TestMainProgram, TestRunMLMCExperiment) {
std::unique_ptr<MainProgram> mainProgram = std::make_unique<MainProgram>(); mainProgram->Run();
ASSERT_EQ(mainProgram->problemName, "");
ASSERT_EQ(mainProgram->modelName, "");
ASSERT_EQ(mainProgram->fieldName, "");
ASSERT_EQ(mainProgram->verbose, 0);
ASSERT_EQ(mainProgram->epsilon, 0.1);
}
TEST(MainProgram, TestCreateMeshes) {
} }
int main(int argc, char **argv) { int main(int argc, char **argv) {
InitGoogleTest(&argc, argv); InitGoogleTest(&argc, argv);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment