diff --git a/include/tug/Simulation.hpp b/include/tug/Simulation.hpp index f568ec8..f7cbfd3 100644 --- a/include/tug/Simulation.hpp +++ b/include/tug/Simulation.hpp @@ -1,4 +1,5 @@ #include "Boundary.hpp" +#include using namespace std; @@ -8,9 +9,22 @@ enum APPROACH { }; enum CSV_OUTPUT { - CSV_OUTPUT_OFF, - CSV_OUTPUT_ON, - CSV_OUTPUT_VERBOSE + CSV_OUTPUT_OFF, // do not produce csv output + CSV_OUTPUT_ON, // produce csv output with last concentration matrix + CSV_OUTPUT_VERBOSE, // produce csv output with all concentration matrices + CSV_OUTPUT_XTREME // produce csv output with all concentration matrices and simulation environment +}; + +enum CONSOLE_OUTPUT { + CONSOLE_OUTPUT_OFF, // do not print any output to console + CONSOLE_OUTPUT_ON, // print before concentrations to console + CONSOLE_OUTPUT_VERBOSE // print all concentration matrices to console +}; + +enum TIME_MEASURE { + TIME_MEASURE_OFF, // do not print any time measures + TIME_MEASURE_ON, // print one time measure after all iterations + TIME_MEASURE_VERBOSE // print time measures after each iteration }; class Simulation { @@ -32,6 +46,20 @@ class Simulation { */ void setOutputCSV(CSV_OUTPUT csv_output); + /** + * @brief Set the Output Console object + * + * @param console_output + */ + void setOutputConsole(CONSOLE_OUTPUT console_output); + + /** + * @brief Set the Time Measure object + * + * @param time_measure + */ + void setTimeMeasure(TIME_MEASURE time_measure); + /** * @brief Set the Timestep object * @@ -65,8 +93,14 @@ class Simulation { */ void printConcentrationsConsole(); + /** + * @brief + * + * @return string + */ + string createCSVfile(); - void printConcentrationsCSV(string ident, bool appendMode = false); + void printConcentrationsCSV(string filename); /** * @brief Start the simulation with all of the previously set parameters. @@ -80,6 +114,8 @@ class Simulation { double timestep; int iterations; CSV_OUTPUT csv_output; + CONSOLE_OUTPUT console_output; + TIME_MEASURE time_measure; Grid grid; Boundary bc; diff --git a/src/Grid.cpp b/src/Grid.cpp index 28b42f7..003f854 100644 --- a/src/Grid.cpp +++ b/src/Grid.cpp @@ -1,3 +1,4 @@ +#include "TugUtils.hpp" #include #include @@ -12,6 +13,11 @@ Grid::Grid(int col) { } Grid::Grid(int row, int col) { + // TODO check for reasonable dimensions + if (row < 1 || col < 1) { + throw_invalid_argument("Either row or col too small!"); + } + this->row = row; this->col = col; this->domain_row = row; @@ -23,7 +29,6 @@ Grid::Grid(int row, int col) { this->concentrations = MatrixXd::Constant(row, col, 20); this->alpha_x = MatrixXd::Constant(row, col, 1); this->alpha_y = MatrixXd::Constant(row, col, 1); - } void Grid::setConcentrations(MatrixXd concentrations) { diff --git a/src/Simulation.cpp b/src/Simulation.cpp index 6d7bc6f..898eef2 100644 --- a/src/Simulation.cpp +++ b/src/Simulation.cpp @@ -1,9 +1,12 @@ +#include #include +#include #include #include #include "FTCS.cpp" +#include "TugUtils.hpp" using namespace std; @@ -16,16 +19,35 @@ Simulation::Simulation(Grid grid, Boundary bc, APPROACH approach) : grid(grid), this->timestep = 0.01; this->iterations = 1000; this->csv_output = CSV_OUTPUT_OFF; + this->console_output = CONSOLE_OUTPUT_OFF; + this->time_measure = TIME_MEASURE_OFF; } void Simulation::setOutputCSV(CSV_OUTPUT csv_output) { if (csv_output < CSV_OUTPUT_OFF && csv_output > CSV_OUTPUT_VERBOSE) { - throw invalid_argument("Invalid CSV output option given!"); + // throw invalid_argument("Invalid CSV output option given!"); + throw_invalid_argument("Invalid CSV output option given!"); } this->csv_output = csv_output; } +void Simulation::setOutputConsole(CONSOLE_OUTPUT console_output) { + if (console_output < CONSOLE_OUTPUT_OFF && console_output > CONSOLE_OUTPUT_VERBOSE) { + throw_invalid_argument("Invalid console output option given!"); + } + + this->console_output = console_output; +} + +void Simulation::setTimeMeasure(TIME_MEASURE time_measure) { + if (time_measure < TIME_MEASURE_OFF && time_measure > TIME_MEASURE_ON) { + throw_invalid_argument("Invalid time measure option given!"); + } + + this->time_measure = time_measure; +} + void Simulation::setTimestep(double timestep) { //TODO check timestep in FTCS for max value this->timestep = timestep; @@ -44,22 +66,59 @@ int Simulation::getIterations() { } void Simulation::printConcentrationsConsole() { - cout << "Concentrations:" << endl; cout << grid.getConcentrations() << endl; cout << endl; } -void Simulation::printConcentrationsCSV(string ident, bool appendMode) { +string Simulation::createCSVfile() { + ofstream file; + int appendIdent = 0; + string appendIdentString; + + // APPROACH_ROW_COL_ITERATIONS + string approachString = (approach == 0) ? "FTCS" : "BTCS"; + string row = to_string(grid.getRow()); + string col = to_string(grid.getCol()); + string numIterations = to_string(iterations); + + string filename = approachString + "_" + row + "_" + col + "_" + numIterations + ".csv"; + + while (filesystem::exists(filename)) { + appendIdent += 1; + appendIdentString = to_string(appendIdent); + filename = filename = approachString + "_" + row + "_" + col + "_" + numIterations + "-" + appendIdentString + ".csv"; + } + + file.open(filename); + if (!file) { + exit(1); + } + + if (csv_output == CSV_OUTPUT_XTREME) { + //rows + //cols + //iterations + //boundary left + //boundary right + //boundary top + //boundary bottom + file << row << endl; + file << col << endl; + file << numIterations << endl; + // TODO + // file << to_string(bc.printBoundarySide) << endl; + file << endl << endl; + } + + file.close(); + + return filename; +} + +void Simulation::printConcentrationsCSV(string filename) { ofstream file; - string filename = "output-" + ident + ".csv"; - // string directory = "output/"; - - if (appendMode) { - file.open(filename, std::ios_base::app); - } else { - file.open(filename); - } + file.open(filename, std::ios_base::app); if (!file) { exit(1); } @@ -71,29 +130,48 @@ void Simulation::printConcentrationsCSV(string ident, bool appendMode) { } void Simulation::run() { + string filename; + if (this->console_output > CONSOLE_OUTPUT_OFF) { + printConcentrationsConsole(); + } + if (this->csv_output > CSV_OUTPUT_OFF) { + filename = createCSVfile(); + printConcentrationsCSV(filename); + } + if (approach == FTCS_APPROACH) { - printConcentrationsConsole(); + for (int i = 0; i < iterations; i++) { - if (csv_output == CSV_OUTPUT_VERBOSE) { - printConcentrationsCSV("test", true); + if (console_output == CONSOLE_OUTPUT_VERBOSE && i > 0) { + printConcentrationsConsole(); } + if (csv_output == CSV_OUTPUT_VERBOSE && i > 0) { + printConcentrationsCSV(filename); + } + grid.setConcentrations(FTCS(grid, bc, timestep)); - // if (i != 0 && i % 200 == 0) { - // printConcentrationsConsole(); - // } - } - printConcentrationsConsole(); - if (csv_output >= CSV_OUTPUT_ON) { - bool append = false; - if (csv_output == CSV_OUTPUT_VERBOSE) { - append = true; - } - printConcentrationsCSV("test", append); } + } else if (approach == BTCS_APPROACH) { + for (int i = 0; i < iterations; i++) { + if (console_output == CONSOLE_OUTPUT_VERBOSE && i > 0) { + printConcentrationsConsole(); + } + if (csv_output == CSV_OUTPUT_VERBOSE && i > 0) { + printConcentrationsCSV(filename); + } + //TODO break; } + + } + + if (this->console_output > CONSOLE_OUTPUT_OFF) { + printConcentrationsConsole(); + } + if (this->csv_output > CSV_OUTPUT_OFF) { + printConcentrationsCSV(filename); } }