diff --git a/examples/FTCS_2D_proto_example.cpp b/examples/FTCS_2D_proto_example.cpp index 63f36b1..e65d425 100644 --- a/examples/FTCS_2D_proto_example.cpp +++ b/examples/FTCS_2D_proto_example.cpp @@ -78,6 +78,7 @@ int main(int argc, char *argv[]) { // set kind of output [CSV_OUTPUT_OFF (default), CSV_OUTPUT_ON, CSV_OUTPUT_VERBOSE] simulation.setOutputCSV(CSV_OUTPUT_VERBOSE); + // **** RUN SIMULATION **** diff --git a/include/tug/Boundary.hpp b/include/tug/Boundary.hpp index 19ee4c1..9242fe4 100644 --- a/include/tug/Boundary.hpp +++ b/include/tug/Boundary.hpp @@ -1,7 +1,7 @@ /** * @file Boundary.hpp - * @brief - * + * @brief API of Boundary class, that holds all information for each boundary condition + * at the edges of the diffusion grid. * */ #ifndef BOUNDARY_H_ @@ -13,11 +13,19 @@ using namespace std; using namespace Eigen; +/** + * @brief Enum defining the two implemented boundary conditions. + * + */ enum BC_TYPE { BC_TYPE_CLOSED, BC_TYPE_CONSTANT }; +/** + * @brief Enum defining all 4 possible sides to a 1D and 2D grid. + * + */ enum BC_SIDE { BC_SIDE_LEFT, BC_SIDE_RIGHT, @@ -149,12 +157,18 @@ class Boundary { * @brief Returns the boundary condition of a specified side as a vector * of BoundarsElement objects. * - * @param side Boundary side from which the boundaryconditions are to be returned. + * @param side Boundary side from which the boundary conditions are to be returned. * @return vector Contains the boundary conditions as BoundaryElement objects. */ vector getBoundarySide(BC_SIDE side); - // TODO write documentation and tests for this method + /** + * @brief Get thes Boundary Side Values as a vector. Value is -1 in case some specific + boundary is closed. + * + * @param side Boundary side for which the values are to be returned. + * @return VectorXd Vector with values as doubles. + */ VectorXd getBoundarySideValues(BC_SIDE side); /** @@ -192,9 +206,9 @@ class Boundary { double getBoundaryElementValue(BC_SIDE side, int index); private: - Grid grid; + Grid grid; // Boundary is directly dependent on the dimensions of a predefined - vector> boundaries; + vector> boundaries; // Vector with Boundary Element information }; #endif diff --git a/include/tug/Grid.hpp b/include/tug/Grid.hpp index 9369245..23d7f30 100644 --- a/include/tug/Grid.hpp +++ b/include/tug/Grid.hpp @@ -163,8 +163,8 @@ class Grid { int domainRow; // number of domain rows double deltaCol; // delta in x-direction (between columns) double deltaRow; // delta in y-direction (between rows) - MatrixXd concentrations; - MatrixXd alphaX; - MatrixXd alphaY; + MatrixXd concentrations; // Matrix holding grid concentrations + MatrixXd alphaX; // Matrix holding alpha coefficients in x-direction + MatrixXd alphaY; // Matrix holding alpha coefficients in y-direction }; \ No newline at end of file diff --git a/include/tug/Simulation.hpp b/include/tug/Simulation.hpp index 1d678c2..fb9f734 100644 --- a/include/tug/Simulation.hpp +++ b/include/tug/Simulation.hpp @@ -1,34 +1,52 @@ /** * @file Simulation.hpp - * @brief + * @brief API of Simulation class, that holds all information regarding a specific simulation + * run like its timestep, number of iterations and output options. Simulation object + * also holds a predefined Grid and Boundary object. + * */ #include "Boundary.hpp" #include using namespace std; +/** + * @brief Enum defining the two implemented solution approaches. + * + */ enum APPROACH { FTCS_APPROACH, // Forward Time-Centered Space BTCS_APPROACH // Backward Time-Centered Space }; +/** + * @brief Enum holding different options for .csv output. + * + */ enum CSV_OUTPUT { 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 boundary conditions at beginning + CSV_OUTPUT_XTREME // csv output like VERBOSE but additional boundary conditions at beginning }; +/** + * @brief Enum holding different options for console output. + * + */ enum CONSOLE_OUTPUT { CONSOLE_OUTPUT_OFF, // do not print any output to console CONSOLE_OUTPUT_ON, // print before and after concentrations to console CONSOLE_OUTPUT_VERBOSE // print all concentration matrices to console }; +/** + * @brief Enum holding different options for time measurement. + * + */ enum TIME_MEASURE { TIME_MEASURE_OFF, // do not print any time measures - TIME_MEASURE_ON, // print time measure after last iteration - TIME_MEASURE_VERBOSE // print time measures after each iteration + TIME_MEASURE_ON // print time measure after last iteration }; /** diff --git a/src/Grid.cpp b/src/Grid.cpp index 66e95ee..e215e9a 100644 --- a/src/Grid.cpp +++ b/src/Grid.cpp @@ -13,7 +13,6 @@ Grid::Grid(int length) { this->deltaCol = double(this->domainCol)/double(this->col); // -> 1 this->dim = 1; - // TODO move to the case when Simulation is set to constant and use as default this->concentrations = MatrixXd::Constant(1, col, 20); this->alphaX = MatrixXd::Constant(1, col, 1); } @@ -31,7 +30,6 @@ Grid::Grid(int row, int col) { this->deltaCol = double(this->domainCol)/double(this->col); // -> 1 this->dim = 2; - // TODO move to the case when Simulation is set to constant and use as default this->concentrations = MatrixXd::Constant(row, col, 20); this->alphaX = MatrixXd::Constant(row, col, 1); this->alphaY = MatrixXd::Constant(row, col, 1); diff --git a/src/Simulation.cpp b/src/Simulation.cpp index fc35513..17645a5 100644 --- a/src/Simulation.cpp +++ b/src/Simulation.cpp @@ -19,14 +19,6 @@ Simulation::Simulation(Grid &grid, Boundary &bc, APPROACH approach) : grid(grid) this->timestep = -1; // error per default this->iterations = -1; this->innerIterations = 1; - - // MDL no: we need to distinguish between "required dt" and - // "number of (outer) iterations" at which the user needs an - // output and the actual CFL-allowed timestep and consequently the - // number of "inner" iterations which the explicit FTCS needs to - // reach them. The following, at least at the moment, cannot be - // computed here since "timestep" is not yet set when this - // function is called. I brought everything into "FTCS_2D"! this->csv_output = CSV_OUTPUT_OFF; this->console_output = CONSOLE_OUTPUT_OFF; @@ -35,7 +27,6 @@ Simulation::Simulation(Grid &grid, Boundary &bc, APPROACH approach) : grid(grid) 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!"); } @@ -90,7 +81,7 @@ void Simulation::setTimestep(double timestep) { double CFL_Wiki = 1 / (4 * maxAlpha * ((1/deltaRowSquare) + (1/deltaColSquare))); // Formula from Wikipedia cout << "FTCS_2D :: CFL condition MDL: " << CFL_MDL << endl; - cout << "FTCS_2D :: CFL condition Wiki: " << CFL_Wiki << endl; + // cout << "FTCS_2D :: CFL condition Wiki: " << CFL_Wiki << endl; cout << "FTCS_2D :: required dt=" << timestep << endl; if (timestep > CFL_MDL) { @@ -139,7 +130,6 @@ string Simulation::createCSVfile() { 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()); @@ -150,8 +140,7 @@ string Simulation::createCSVfile() { while (filesystem::exists(filename)) { appendIdent += 1; appendIdentString = to_string(appendIdent); - // ?? TODO why double filename? - filename = filename = approachString + "_" + row + "_" + col + "_" + numIterations + "-" + appendIdentString + ".csv"; + filename = approachString + "_" + row + "_" + col + "_" + numIterations + "-" + appendIdentString + ".csv"; } file.open(filename); @@ -159,21 +148,14 @@ string Simulation::createCSVfile() { exit(1); } + // adds lines at the beginning of verbose output csv that represent the boundary conditions and their values + // -1 in case of closed boundary if (csv_output == CSV_OUTPUT_XTREME) { - //rows - //cols - //iterations - //boundary left - //boundary right - //boundary top - //boundary bottom IOFormat one_row(StreamPrecision, DontAlignCols, "", " "); - file << bc.getBoundarySideValues(BC_SIDE_LEFT).format(one_row) << endl; - file << bc.getBoundarySideValues(BC_SIDE_RIGHT).format(one_row) << endl; - file << bc.getBoundarySideValues(BC_SIDE_TOP).format(one_row) << endl; - file << bc.getBoundarySideValues(BC_SIDE_BOTTOM).format(one_row) << endl; - // TODO - // file << to_string(bc.printBoundarySide) << endl; + file << bc.getBoundarySideValues(BC_SIDE_LEFT).format(one_row) << endl; // boundary left + file << bc.getBoundarySideValues(BC_SIDE_RIGHT).format(one_row) << endl; // boundary right + file << bc.getBoundarySideValues(BC_SIDE_TOP).format(one_row) << endl; // boundary top + file << bc.getBoundarySideValues(BC_SIDE_BOTTOM).format(one_row) << endl; // boundary bottom file << endl << endl; } @@ -212,12 +194,10 @@ void Simulation::run() { filename = createCSVfile(); } + auto begin = std::chrono::high_resolution_clock::now(); + if (approach == FTCS_APPROACH) { - auto begin = std::chrono::high_resolution_clock::now(); - progressbar bar(iterations * innerIterations); for (int i = 0; i < iterations * innerIterations; i++) { - // MDL: distinguish between "outer" and "inner" iterations - // std::cout << ":: run(): Outer iteration " << i+1 << "/" << iterations << endl; if (console_output == CONSOLE_OUTPUT_VERBOSE && i > 0) { printConcentrationsConsole(); } @@ -226,13 +206,14 @@ void Simulation::run() { } FTCS(this->grid, this->bc, this->timestep); - bar.update(); + + if (i % (iterations * innerIterations / 100) == 0) { + double percentage = (double)i / ((double)iterations * (double)innerIterations) * 100; + if ((int)percentage % 10 == 0) { + cout << "Progress: " << percentage << "%" << endl; + } + } } - auto end = std::chrono::high_resolution_clock::now(); - auto milliseconds = std::chrono::duration_cast(end - begin); - - // MDL: meaningful stdout messages - std::cout << "\n:: run() finished in " << milliseconds.count() << "ms" << endl; } else if (approach == BTCS_APPROACH) { @@ -250,12 +231,19 @@ void Simulation::run() { } + auto end = std::chrono::high_resolution_clock::now(); + auto milliseconds = std::chrono::duration_cast(end - begin); + if (this->console_output > CONSOLE_OUTPUT_OFF) { printConcentrationsConsole(); } if (this->csv_output > CSV_OUTPUT_OFF) { printConcentrationsCSV(filename); } - + if (this->time_measure > TIME_MEASURE_OFF) { + string approachString = (approach == 0) ? "FTCS" : "BTCS"; + string dimString = (grid.getDim() == 1) ? "-1D" : "-2D"; + cout << approachString << dimString << ":: run() finished in " << milliseconds.count() << "ms" << endl; + } }