Merge branch 'dynamic-boundary-conditions-functionality' into 'hannes-philipp'

Dynamic boundary conditions functionality

See merge request naaice/tug!6
This commit is contained in:
Hannes Martin Signer 2023-07-28 16:00:51 +02:00
commit 2d293469ff
7 changed files with 226 additions and 162 deletions

View File

@ -7,7 +7,7 @@ set(CMAKE_CXX_STANDARD 17)
find_package(Eigen3 REQUIRED NO_MODULE) find_package(Eigen3 REQUIRED NO_MODULE)
find_package(OpenMP) find_package(OpenMP)
find_package(easy_profiler REQUIRED) find_package(easy_profiler)
## SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2 -mfma") ## SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2 -mfma")
option(TUG_USE_OPENMP "Compile with OpenMP support" ON) option(TUG_USE_OPENMP "Compile with OpenMP support" ON)

View File

@ -9,4 +9,4 @@ target_link_libraries(second_example tug)
target_link_libraries(boundary_example1D tug) target_link_libraries(boundary_example1D tug)
target_link_libraries(FTCS_2D_proto_example tug) target_link_libraries(FTCS_2D_proto_example tug)
target_link_libraries(FTCS_1D_proto_example tug) target_link_libraries(FTCS_1D_proto_example tug)
target_link_libraries(FTCS_2D_proto_example easy_profiler) # target_link_libraries(FTCS_2D_proto_example easy_profiler)

View File

@ -1,3 +1,4 @@
#include "tug/Boundary.hpp"
#include <tug/Simulation.hpp> #include <tug/Simulation.hpp>
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
@ -18,7 +19,9 @@ int main(int argc, char *argv[]) {
// ****************** // ******************
// create a boundary with constant values // create a boundary with constant values
Boundary bc = Boundary(grid, BC_TYPE_CONSTANT); Boundary bc = Boundary(grid);
bc.setBoundarySideConstant(BC_SIDE_LEFT, 1);
bc.setBoundarySideConstant(BC_SIDE_RIGHT, 1);
// ************************ // ************************

View File

@ -7,17 +7,17 @@
*/ */
#include <tug/Simulation.hpp> #include <tug/Simulation.hpp>
#include <easy/profiler.h> // #include <easy/profiler.h>
#define EASY_PROFILER_ENABLE ::profiler::setEnabled(true); // #define EASY_PROFILER_ENABLE ::profiler::setEnabled(true);
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
EASY_PROFILER_ENABLE; // EASY_PROFILER_ENABLE;
profiler::startListen(); // profiler::startListen();
// ************** // **************
// **** GRID **** // **** GRID ****
// ************** // **************
profiler::startListen(); // profiler::startListen();
// create a grid with a 20 x 20 field // create a grid with a 20 x 20 field
int row = 20; int row = 20;
int col = 20; int col = 20;
@ -29,8 +29,8 @@ int main(int argc, char *argv[]) {
// (optional) set the concentrations, e.g.: // (optional) set the concentrations, e.g.:
// MatrixXd concentrations = MatrixXd::Constant(20,20,1000); // #row,#col,value // MatrixXd concentrations = MatrixXd::Constant(20,20,1000); // #row,#col,value
// grid.setConcentrations(concentrations); // grid.setConcentrations(concentrations);
MatrixXd concentrations = MatrixXd::Constant(row, col,1); MatrixXd concentrations = MatrixXd::Constant(row,col,0);
concentrations(0,0) = 2000; concentrations(0,0) = 1999;
grid.setConcentrations(concentrations); grid.setConcentrations(concentrations);
@ -45,7 +45,12 @@ int main(int argc, char *argv[]) {
// ****************** // ******************
// create a boundary with constant values // create a boundary with constant values
Boundary bc = Boundary(grid, BC_TYPE_CONSTANT); Boundary bc = Boundary(grid);
bc.setBoundarySideConstant(BC_SIDE_LEFT, 0);
bc.setBoundarySideConstant(BC_SIDE_RIGHT, 0);
bc.setBoundarySideConstant(BC_SIDE_TOP, 0);
bc.setBoundarySideConstant(BC_SIDE_BOTTOM, 0);
// (optional) set boundary condition values for one side, e.g.: // (optional) set boundary condition values for one side, e.g.:
// VectorXd bc_left_values = VectorXd::Constant(20,1); // length,value // VectorXd bc_left_values = VectorXd::Constant(20,1); // length,value
@ -69,7 +74,7 @@ int main(int argc, char *argv[]) {
simulation.setTimestep(0.1); // timestep simulation.setTimestep(0.1); // timestep
// (optional) set the number of iterations // (optional) set the number of iterations
simulation.setIterations(2); simulation.setIterations(10000);
// (optional) set kind of output [CSV_OUTPUT_OFF (default), CSV_OUTPUT_ON, CSV_OUTPUT_VERBOSE] // (optional) set kind of output [CSV_OUTPUT_OFF (default), CSV_OUTPUT_ON, CSV_OUTPUT_VERBOSE]
simulation.setOutputCSV(CSV_OUTPUT_VERBOSE); simulation.setOutputCSV(CSV_OUTPUT_VERBOSE);
@ -78,9 +83,9 @@ int main(int argc, char *argv[]) {
// run the simulation // run the simulation
EASY_BLOCK("SIMULATION") // EASY_BLOCK("SIMULATION")
simulation.run(); simulation.run();
EASY_END_BLOCK; // EASY_END_BLOCK;
profiler::dumpBlocksToFile("test_profile.prof"); // profiler::dumpBlocksToFile("test_profile.prof");
profiler::stopListen(); // profiler::stopListen();
} }

View File

@ -2,6 +2,7 @@
#define BOUNDARY_H_ #define BOUNDARY_H_
#include <Eigen/Core> #include <Eigen/Core>
#include <cstddef>
#include "Grid.hpp" #include "Grid.hpp"
using namespace std; using namespace std;
@ -19,26 +20,21 @@ enum BC_SIDE {
BC_SIDE_BOTTOM BC_SIDE_BOTTOM
}; };
/******************************************* class BoundaryElement {
class WallElement {
public: public:
WallElement() { // bc type closed
this->type = BC_TYPE_CLOSED; BoundaryElement();
this->value = 0;
}
WallElement(double value) { // bc type constant
this->type = BC_TYPE_CONSTANT; BoundaryElement(double value);
this->value = value;
}
BC_TYPE getType() { void setType(BC_TYPE type);
return this->type;
}
double getValue() { void setValue(double value);
return this->value;
} BC_TYPE getType();
double getValue();
private: private:
BC_TYPE type; BC_TYPE type;
@ -47,16 +43,22 @@ class WallElement {
class BoundaryWall { class BoundaryWall {
public: public:
BoundaryWall(int length) { BoundaryWall(int length);
// create array with length many wall elements
} void setWall(BC_TYPE type, double value = NAN);
vector<BoundaryElement> getWall();
void setBoundaryElement(int index, BC_TYPE type, double value = NAN);
BoundaryElement getBoundaryElement();
private: private:
BC_SIDE side; BC_SIDE side;
int length; int length;
vector<WallElement> wall; vector<BoundaryElement> wall;
}; };
***********************/
class Boundary { class Boundary {
public: public:
@ -67,40 +69,29 @@ class Boundary {
* @param grid * @param grid
* @param type * @param type
*/ */
Boundary(Grid grid, BC_TYPE type); Boundary(Grid grid);
/** void setBoundarySideClosed(BC_SIDE side);
* @brief Get the Boundary Condition Type object
*
* @return auto
*/
BC_TYPE getBoundaryConditionType();
/** void setBoundarySideConstant(BC_SIDE side, double value);
* @brief Set the Boundary Condition Value object
*
* @param side
* @param values
*/
void setBoundaryConditionValue(BC_SIDE side, VectorXd values);
/** void setBoundaryElementClosed(BC_SIDE side, int index);
* @brief Get the Boundary Condition Value object
*
* @param side
* @return auto
*/
VectorXd getBoundaryConditionValue(BC_SIDE side);
void setBoundaryElementConstant(BC_SIDE side, int index, double value);
vector<BoundaryElement> getBoundarySide(BC_SIDE side);
BoundaryElement getBoundaryElement(BC_SIDE side, int index);
BC_TYPE getBoundaryElementType(BC_SIDE side, int index);
double getBoundaryElementValue(BC_SIDE side, int index);
private: private:
Grid grid; Grid grid;
// need a way to save the bc type and value for each single 'boundary cell' vector<vector<BoundaryElement>> boundaries;
// perhaps an array for each side with structs containing the bc type as well as a value
// or another object that contains one boundary side
BC_TYPE type;
VectorXd left, right, top, bottom;
}; };
#endif #endif

View File

@ -1,68 +1,85 @@
#include "tug/BoundaryCondition.hpp"
#include <iostream> #include <iostream>
#include <omp.h>
#include <tug/Boundary.hpp> #include <tug/Boundary.hpp>
#include <stdexcept> #include <stdexcept>
using namespace std; using namespace std;
Boundary::Boundary(Grid grid, BC_TYPE type) : grid(grid) { BoundaryElement::BoundaryElement() {
//probably to DEBUG assignment grid this->type = BC_TYPE_CLOSED;
this->value = NAN;
}
BoundaryElement::BoundaryElement(double value) {
this->type = BC_TYPE_CONSTANT;
this->value = value;
}
void BoundaryElement::setType(BC_TYPE type) {
this->type = type; this->type = type;
if (type == BC_TYPE_CONSTANT) {
if (grid.getDim() == 1) {
this->left = VectorXd::Constant(1, 1);
this->right = VectorXd::Constant(1, 1);
} else if (grid.getDim() == 2) {
this->left = VectorXd::Constant(grid.getRow(), 1);
this->right = VectorXd::Constant(grid.getRow(), 1);
this->top = VectorXd::Constant(grid.getCol(), 1);
this->bottom = VectorXd::Constant(grid.getCol(), 1);
} else {
throw invalid_argument("Dimension must be 1 or 2!");
}
}
} }
BC_TYPE Boundary::getBoundaryConditionType() { void BoundaryElement::setValue(double value) {
return this->type; this->value = value;
} }
void Boundary::setBoundaryConditionValue(BC_SIDE side, VectorXd values) { BC_TYPE BoundaryElement::getType() {
if (type != BC_TYPE_CONSTANT) { return this->type;
// TODO check if correct way for handling warning }
cerr << "Values will not be used, wrong BC_TYPE!";
}
switch (side) { double BoundaryElement::getValue() {
case BC_SIDE_LEFT: return this->value;
this->left = values; }
break;
case BC_SIDE_RIGHT: Boundary::Boundary(Grid grid) : grid(grid) {
this->right = values; //probably to DEBUG assignment grid
break;
case BC_SIDE_TOP: if (grid.getDim() == 1) {
this->top = values; this->boundaries = vector<vector<BoundaryElement>>(2);
break;
case BC_SIDE_BOTTOM: this->boundaries[BC_SIDE_LEFT].push_back(BoundaryElement());
this->bottom = values; this->boundaries[BC_SIDE_RIGHT].push_back(BoundaryElement());
break; } else if (grid.getDim() == 2) {
default: this->boundaries = vector<vector<BoundaryElement>>(4);
throw invalid_argument("Invalid side given!");
this->boundaries[BC_SIDE_LEFT] = vector<BoundaryElement>(grid.getRow(), BoundaryElement());
this->boundaries[BC_SIDE_RIGHT] = vector<BoundaryElement>(grid.getRow(), BoundaryElement());
this->boundaries[BC_SIDE_TOP] = vector<BoundaryElement>(grid.getCol(), BoundaryElement());
this->boundaries[BC_SIDE_BOTTOM] = vector<BoundaryElement>(grid.getCol(), BoundaryElement());
} }
} }
VectorXd Boundary::getBoundaryConditionValue(BC_SIDE side) { void Boundary::setBoundarySideClosed(BC_SIDE side) {
switch (side) { this->boundaries[side] = vector<BoundaryElement>(grid.getRow(), BoundaryElement());
case BC_SIDE_LEFT: }
return this->left;
case BC_SIDE_RIGHT: void Boundary::setBoundarySideConstant(BC_SIDE side, double value) {
return this->right; this->boundaries[side] = vector<BoundaryElement>(grid.getRow(), BoundaryElement(value));
case BC_SIDE_TOP: }
return this->top;
case BC_SIDE_BOTTOM: void Boundary::setBoundaryElementClosed(BC_SIDE side, int index) {
return this->bottom; this->boundaries[side][index].setType(BC_TYPE_CLOSED);
default: }
throw invalid_argument("Invalid side given!");
} void Boundary::setBoundaryElementConstant(BC_SIDE side, int index, double value) {
} this->boundaries[side][index].setType(BC_TYPE_CONSTANT);
this->boundaries[side][index].setValue(value);
}
vector<BoundaryElement> Boundary::getBoundarySide(BC_SIDE side) {
return this->boundaries[side];
}
BoundaryElement Boundary::getBoundaryElement(BC_SIDE side, int index) {
return this->boundaries[side][index];
}
BC_TYPE Boundary::getBoundaryElementType(BC_SIDE side, int index) {
return this->boundaries[side][index].getType();
}
double Boundary::getBoundaryElementValue(BC_SIDE side, int index) {
return this->boundaries[side][index].getValue();
}

View File

@ -1,9 +1,11 @@
#include "TugUtils.hpp"
#include <cstddef> #include <cstddef>
#include <tug/Boundary.hpp> #include <tug/Boundary.hpp>
#include <iostream> #include <iostream>
using namespace std; using namespace std;
double calcAlphaIntercell(double alpha1, double alpha2, bool useHarmonic = false) { double calcAlphaIntercell(double alpha1, double alpha2, bool useHarmonic = false) {
if (useHarmonic) { if (useHarmonic) {
return 2 / ((1/alpha1) + (1/alpha2)); return 2 / ((1/alpha1) + (1/alpha2));
@ -57,21 +59,37 @@ double calcHorizontalChangeLeftBoundaryConstant(Grid grid, Boundary bc, int row,
+ 2 * grid.getAlphaX()(row,col) + 2 * grid.getAlphaX()(row,col)
) )
* grid.getConcentrations()(row,col) * grid.getConcentrations()(row,col)
+ 2 * grid.getAlphaX()(row,col) * bc.getBoundaryConditionValue(BC_SIDE_LEFT)(row); + 2 * grid.getAlphaX()(row,col) * bc.getBoundaryElementValue(BC_SIDE_LEFT, row);
return result; return result;
} }
double calcHorizontalChangeLeftBoundaryClosed() { double calcHorizontalChangeLeftBoundaryClosed(Grid grid, int row, int col) {
return 0;
double result =
calcAlphaIntercell(grid.getAlphaX()(row, col+1), grid.getAlphaX()(row, col))
* (grid.getConcentrations()(row, col+1) - grid.getConcentrations()(row, col));
return result;
}
double calcHorizontalChangeLeftBoundary(Grid grid, Boundary bc, int row, int col) {
if (bc.getBoundaryElementType(BC_SIDE_LEFT, col) == BC_TYPE_CONSTANT) {
return calcHorizontalChangeLeftBoundaryConstant(grid, bc, row, col);
} else if (bc.getBoundaryElementType(BC_SIDE_LEFT, col) == BC_TYPE_CLOSED) {
return calcHorizontalChangeLeftBoundaryClosed(grid, row, col);
} else {
throw_invalid_argument("Undefined Boundary Condition Type!");
}
} }
double calcHorizontalChangeRightBoundaryConstant(Grid grid, Boundary bc, int row, int col) { double calcHorizontalChangeRightBoundaryConstant(Grid grid, Boundary bc, int row, int col) {
double result = double result =
2 * grid.getAlphaX()(row,col) * bc.getBoundaryConditionValue(BC_SIDE_RIGHT)(row) 2 * grid.getAlphaX()(row,col) * bc.getBoundaryElementValue(BC_SIDE_RIGHT, row)
- ( - (
calcAlphaIntercell(grid.getAlphaX()(row,col-1), grid.getAlphaX()(row,col)) calcAlphaIntercell(grid.getAlphaX()(row,col-1), grid.getAlphaX()(row,col))
+ 2 * grid.getAlphaX()(row,col) + 2 * grid.getAlphaX()(row,col)
@ -84,8 +102,24 @@ double calcHorizontalChangeRightBoundaryConstant(Grid grid, Boundary bc, int row
} }
double calcHorizontalChangeRightBoundaryClosed() { double calcHorizontalChangeRightBoundaryClosed(Grid grid, int row, int col) {
return 0;
double result =
- (calcAlphaIntercell(grid.getAlphaX()(row, col-1), grid.getAlphaX()(row, col))
* (grid.getConcentrations()(row, col) - grid.getConcentrations()(row, col-1)));
return result;
}
double calcHorizontalChangeRightBoundary(Grid grid, Boundary bc, int row, int col) {
if (bc.getBoundaryElementType(BC_SIDE_RIGHT, col) == BC_TYPE_CONSTANT) {
return calcHorizontalChangeRightBoundaryConstant(grid, bc, row, col);
} else if (bc.getBoundaryElementType(BC_SIDE_RIGHT, col) == BC_TYPE_CLOSED) {
return calcHorizontalChangeRightBoundaryClosed(grid, row, col);
} else {
throw_invalid_argument("Undefined Boundary Condition Type!");
}
} }
@ -99,21 +133,37 @@ double calcVerticalChangeTopBoundaryConstant(Grid grid, Boundary bc, int row, in
+ 2 * grid.getAlphaY()(row, col) + 2 * grid.getAlphaY()(row, col)
) )
* grid.getConcentrations()(row, col) * grid.getConcentrations()(row, col)
+ 2 * grid.getAlphaY()(row, col) * bc.getBoundaryConditionValue(BC_SIDE_TOP)(col); + 2 * grid.getAlphaY()(row, col) * bc.getBoundaryElementValue(BC_SIDE_TOP, col);
return result; return result;
} }
double calcVerticalChangeTopBoundaryClosed() { double calcVerticalChangeTopBoundaryClosed(Grid grid, int row, int col) {
return 0;
double result =
calcAlphaIntercell(grid.getAlphaY()(row+1, col), grid.getConcentrations()(row, col))
* (grid.getConcentrations()(row+1, col) - grid.getConcentrations()(row, col));
return result;
}
double calcVerticalChangeTopBoundary(Grid grid, Boundary bc, int row, int col) {
if (bc.getBoundaryElementType(BC_SIDE_TOP, col) == BC_TYPE_CONSTANT) {
return calcVerticalChangeTopBoundaryConstant(grid, bc, row, col);
} else if (bc.getBoundaryElementType(BC_SIDE_TOP, col) == BC_TYPE_CLOSED) {
return calcVerticalChangeTopBoundaryClosed(grid, row, col);
} else {
throw_invalid_argument("Undefined Boundary Condition Type!");
}
} }
double calcVerticalChangeBottomBoundaryConstant(Grid grid, Boundary bc, int row, int col) { double calcVerticalChangeBottomBoundaryConstant(Grid grid, Boundary bc, int row, int col) {
double result = double result =
2 * grid.getAlphaY()(row, col) * bc.getBoundaryConditionValue(BC_SIDE_BOTTOM)(col) 2 * grid.getAlphaY()(row, col) * bc.getBoundaryElementValue(BC_SIDE_BOTTOM, col)
- ( - (
calcAlphaIntercell(grid.getAlphaY()(row, col), grid.getAlphaY()(row-1, col)) calcAlphaIntercell(grid.getAlphaY()(row, col), grid.getAlphaY()(row-1, col))
+ 2 * grid.getAlphaY()(row, col) + 2 * grid.getAlphaY()(row, col)
@ -126,8 +176,24 @@ double calcVerticalChangeBottomBoundaryConstant(Grid grid, Boundary bc, int row,
} }
double calcVerticalChangeBottomBoundaryClosed() { double calcVerticalChangeBottomBoundaryClosed(Grid grid, int row, int col) {
return 0;
double result =
- (calcAlphaIntercell(grid.getAlphaY()(row, col), grid.getAlphaY()(row-1, col))
* (grid.getConcentrations()(row, col) - grid.getConcentrations()(row-1, col)));
return result;
}
double calcVerticalChangeBottomBoundary(Grid grid, Boundary bc, int row, int col) {
if (bc.getBoundaryElementType(BC_SIDE_BOTTOM, col) == BC_TYPE_CONSTANT) {
return calcVerticalChangeBottomBoundaryConstant(grid, bc, row, col);
} else if (bc.getBoundaryElementType(BC_SIDE_BOTTOM, col) == BC_TYPE_CLOSED) {
return calcVerticalChangeBottomBoundaryClosed(grid, row, col);
} else {
throw_invalid_argument("Undefined Boundary Condition Type!");
}
} }
@ -155,7 +221,7 @@ MatrixXd FTCS_1D(Grid grid, Boundary bc, double timestep) {
concentrations_t1(row, col) = grid.getConcentrations()(row,col) concentrations_t1(row, col) = grid.getConcentrations()(row,col)
+ timestep / (deltaCol*deltaCol) + timestep / (deltaCol*deltaCol)
* ( * (
calcHorizontalChangeLeftBoundaryConstant(grid, bc, row, col) calcHorizontalChangeLeftBoundary(grid, bc, row, col)
) )
; ;
@ -165,7 +231,7 @@ MatrixXd FTCS_1D(Grid grid, Boundary bc, double timestep) {
concentrations_t1(row,col) = grid.getConcentrations()(row,col) concentrations_t1(row,col) = grid.getConcentrations()(row,col)
+ timestep / (deltaCol*deltaCol) + timestep / (deltaCol*deltaCol)
* ( * (
calcHorizontalChangeRightBoundaryConstant(grid, bc, row, col) calcHorizontalChangeRightBoundary(grid, bc, row, col)
) )
; ;
@ -207,7 +273,7 @@ MatrixXd FTCS_2D(Grid grid, Boundary bc, double timestep) {
concentrations_t1(row, col) = grid.getConcentrations()(row,col) concentrations_t1(row, col) = grid.getConcentrations()(row,col)
+ timestep / (deltaCol*deltaCol) + timestep / (deltaCol*deltaCol)
* ( * (
calcHorizontalChangeLeftBoundaryConstant(grid, bc, row, col) calcHorizontalChangeLeftBoundary(grid, bc, row, col)
) )
+ timestep / (deltaRow*deltaRow) + timestep / (deltaRow*deltaRow)
* ( * (
@ -222,7 +288,7 @@ MatrixXd FTCS_2D(Grid grid, Boundary bc, double timestep) {
concentrations_t1(row,col) = grid.getConcentrations()(row,col) concentrations_t1(row,col) = grid.getConcentrations()(row,col)
+ timestep / (deltaCol*deltaCol) + timestep / (deltaCol*deltaCol)
* ( * (
calcHorizontalChangeRightBoundaryConstant(grid, bc, row, col) calcHorizontalChangeRightBoundary(grid, bc, row, col)
) )
+ timestep / (deltaRow*deltaRow) + timestep / (deltaRow*deltaRow)
* ( * (
@ -238,7 +304,7 @@ MatrixXd FTCS_2D(Grid grid, Boundary bc, double timestep) {
concentrations_t1(row, col) = grid.getConcentrations()(row, col) concentrations_t1(row, col) = grid.getConcentrations()(row, col)
+ timestep / (deltaRow*deltaRow) + timestep / (deltaRow*deltaRow)
* ( * (
calcVerticalChangeTopBoundaryConstant(grid, bc, row, col) calcVerticalChangeTopBoundary(grid, bc, row, col)
) )
+ timestep / (deltaCol*deltaCol) + timestep / (deltaCol*deltaCol)
* ( * (
@ -253,7 +319,7 @@ MatrixXd FTCS_2D(Grid grid, Boundary bc, double timestep) {
concentrations_t1(row, col) = grid.getConcentrations()(row, col) concentrations_t1(row, col) = grid.getConcentrations()(row, col)
+ timestep / (deltaRow*deltaRow) + timestep / (deltaRow*deltaRow)
* ( * (
calcVerticalChangeBottomBoundaryConstant(grid, bc, row, col) calcVerticalChangeBottomBoundary(grid, bc, row, col)
) )
+ timestep / (deltaCol*deltaCol) + timestep / (deltaCol*deltaCol)
* ( * (
@ -268,11 +334,11 @@ MatrixXd FTCS_2D(Grid grid, Boundary bc, double timestep) {
concentrations_t1(row,col) = grid.getConcentrations()(row,col) concentrations_t1(row,col) = grid.getConcentrations()(row,col)
+ timestep/(deltaCol*deltaCol) + timestep/(deltaCol*deltaCol)
* ( * (
calcHorizontalChangeLeftBoundaryConstant(grid, bc, row, col) calcHorizontalChangeLeftBoundary(grid, bc, row, col)
) )
+ timestep/(deltaRow*deltaRow) + timestep/(deltaRow*deltaRow)
* ( * (
calcVerticalChangeTopBoundaryConstant(grid, bc, row, col) calcVerticalChangeTopBoundary(grid, bc, row, col)
) )
; ;
@ -282,11 +348,11 @@ MatrixXd FTCS_2D(Grid grid, Boundary bc, double timestep) {
concentrations_t1(row,col) = grid.getConcentrations()(row,col) concentrations_t1(row,col) = grid.getConcentrations()(row,col)
+ timestep/(deltaCol*deltaCol) + timestep/(deltaCol*deltaCol)
* ( * (
calcHorizontalChangeRightBoundaryConstant(grid, bc, row, col) calcHorizontalChangeRightBoundary(grid, bc, row, col)
) )
+ timestep/(deltaRow*deltaRow) + timestep/(deltaRow*deltaRow)
* ( * (
calcVerticalChangeTopBoundaryConstant(grid, bc, row, col) calcVerticalChangeTopBoundary(grid, bc, row, col)
) )
; ;
@ -296,11 +362,11 @@ MatrixXd FTCS_2D(Grid grid, Boundary bc, double timestep) {
concentrations_t1(row,col) = grid.getConcentrations()(row,col) concentrations_t1(row,col) = grid.getConcentrations()(row,col)
+ timestep/(deltaCol*deltaCol) + timestep/(deltaCol*deltaCol)
* ( * (
calcHorizontalChangeLeftBoundaryConstant(grid, bc, row, col) calcHorizontalChangeLeftBoundary(grid, bc, row, col)
) )
+ timestep/(deltaRow*deltaRow) + timestep/(deltaRow*deltaRow)
* ( * (
calcVerticalChangeBottomBoundaryConstant(grid, bc, row, col) calcVerticalChangeBottomBoundary(grid, bc, row, col)
) )
; ;
@ -310,11 +376,11 @@ MatrixXd FTCS_2D(Grid grid, Boundary bc, double timestep) {
concentrations_t1(row,col) = grid.getConcentrations()(row,col) concentrations_t1(row,col) = grid.getConcentrations()(row,col)
+ timestep/(deltaCol*deltaCol) + timestep/(deltaCol*deltaCol)
* ( * (
calcHorizontalChangeRightBoundaryConstant(grid, bc, row, col) calcHorizontalChangeRightBoundary(grid, bc, row, col)
) )
+ timestep/(deltaRow*deltaRow) + timestep/(deltaRow*deltaRow)
* ( * (
calcVerticalChangeBottomBoundaryConstant(grid, bc, row, col) calcVerticalChangeBottomBoundary(grid, bc, row, col)
) )
; ;
@ -324,29 +390,11 @@ MatrixXd FTCS_2D(Grid grid, Boundary bc, double timestep) {
MatrixXd FTCS(Grid grid, Boundary bc, double timestep) { MatrixXd FTCS(Grid grid, Boundary bc, double timestep) {
// inner cells
// TODO only the boundary cells are different in constant and closed case
// if 1D:
// do inner cells
// do left boundary according to bc type
// do right boundary according to bc type
// if 2D:
// do inner cells
// do left boundaries according to bc type
// do right boundaries according to bc type
// ...
if (grid.getDim() == 1) { if (grid.getDim() == 1) {
return FTCS_1D(grid, bc, timestep); return FTCS_1D(grid, bc, timestep);
} else { } else {
return FTCS_2D(grid, bc, timestep); return FTCS_2D(grid, bc, timestep);
} }
// checking the boundary condition type first does not work
// if the boundary condition types change dynamically for a grid
// meaning:
// - boundary condition type needs to be checked for every single boundary cell
// -> this check is last in order
// -
} }