TugJulia/src/Simulation.cpp
2023-08-02 10:35:36 +02:00

194 lines
5.3 KiB
C++

#include <filesystem>
#include <stdexcept>
#include <string>
#include <tug/Simulation.hpp>
#include <fstream>
#include "FTCS.cpp"
#include "TugUtils.hpp"
using namespace std;
Simulation::Simulation(Grid grid, Boundary bc, APPROACH approach) : grid(grid), bc(bc) {
//probably to DEBUG assignment of grid and bc
this->grid = grid;
this->approach = approach;
//TODO calculate max time step
double deltaRowSquare = grid.getDeltaRow() * grid.getDeltaRow();
double deltaColSquare = grid.getDeltaCol() * grid.getDeltaCol();
double minDelta = (deltaRowSquare < deltaColSquare) ? deltaRowSquare : deltaColSquare;
double maxAlphaX = grid.getAlphaX().maxCoeff();
double maxAlphaY = grid.getAlphaY().maxCoeff();
double maxAlpha = (maxAlphaX > maxAlphaY) ? maxAlphaX : maxAlphaY;
//double maxStableTimestep = minDelta / (2*maxAlpha); // Formula from Marco --> seems to be unstable
double maxStableTimestep = 1 / (4 * maxAlpha * ((1/deltaRowSquare) + (1/deltaColSquare))); // Formula from Wikipedia
cout << maxStableTimestep << endl;
this->timestep = maxStableTimestep;
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!");
}
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;
}
double Simulation::getTimestep() {
return this->timestep;
}
void Simulation::setIterations(int iterations) {
this->iterations = iterations;
}
int Simulation::getIterations() {
return this->iterations;
}
void Simulation::printConcentrationsConsole() {
cout << grid.getConcentrations() << endl;
cout << endl;
}
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;
file.open(filename, std::ios_base::app);
if (!file) {
exit(1);
}
IOFormat do_not_align(StreamPrecision, DontAlignCols);
file << grid.getConcentrations().format(do_not_align) << endl;
file << endl << endl;
file.close();
}
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) {
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);
}
grid.setConcentrations(FTCS(grid, bc, timestep));
}
} 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);
}
}