feat: Implement inner boundaries for FTCS

This commit is contained in:
Max Lübke 2024-12-11 13:22:23 +01:00
parent 3b953e0b96
commit 031c1b2eef
2 changed files with 54 additions and 0 deletions

View File

@ -11,6 +11,7 @@
#include "tug/Core/TugUtils.hpp"
#include <cstddef>
#include <cstring>
#include <iterator>
#include <tug/Boundary.hpp>
#include <tug/Core/Matrix.hpp>
#include <tug/Core/Numeric/SimulationInput.hpp>
@ -55,6 +56,27 @@ constexpr T calcChangeBoundary(T conc_c, T conc_neighbor, T alpha_center,
tug_assert(false, "Undefined Boundary Condition Type!");
}
template <typename T>
static inline void checkAndSetConstantInnerCells(const Boundary<T> &bc,
Grid<T> &grid) {
const auto &inner_boundaries = bc.getInnerBoundaries();
if (inner_boundaries.empty()) {
return;
}
auto &concentrations = grid.getConcentrations();
const auto rows = grid.getRow();
const auto cols = grid.getCol();
for (const auto &[rowcol, value] : inner_boundaries) {
const auto &row = rowcol.first;
const auto &col = rowcol.second;
concentrations(row, col) = value;
}
return;
}
// FTCS solution for 1D grid
template <class T> static void FTCS_1D(SimulationInput<T> &input) {
const std::size_t &colMax = input.colMax;
@ -71,6 +93,8 @@ template <class T> static void FTCS_1D(SimulationInput<T> &input) {
// only one row in 1D case -> row constant at index 0
int row = 0;
const auto inner_bc = bc.getInnerBoundaryRow(0);
// inner cells
// independent of boundary condition type
for (int col = 1; col < colMax - 1; col++) {

View File

@ -215,3 +215,33 @@ DIFFUSION_TEST(ConstantInnerCell) {
EXPECT_FALSE((concentrations_result.array() < 0.0).any());
}
DIFFUSION_TEST(ConstantInnerCellFTCS) {
constexpr std::uint32_t nrows = 5;
constexpr std::uint32_t ncols = 5;
auto concentrations = Eigen::MatrixXd::Constant(nrows, ncols, 1.0);
auto alphax = Eigen::MatrixXd::Constant(nrows, ncols, 1E-5);
auto alphay = Eigen::MatrixXd::Constant(nrows, ncols, 1E-5);
tug::Grid64 grid(concentrations);
grid.setAlpha(alphax, alphay);
tug::Boundary bc(grid);
// inner
bc.setInnerBoundary(2, 2, 0);
tug::Diffusion<double, tug::FTCS_APPROACH> sim(grid, bc);
sim.setTimestep(1);
sim.setIterations(1);
MatrixXd input_values(concentrations);
sim.run();
EXPECT_DOUBLE_EQ(grid.getConcentrations()(2, 2), 0);
EXPECT_LT(grid.getConcentrations().sum(), input_values.sum());
EXPECT_FALSE((grid.getConcentrations().array() > 1.0).any());
EXPECT_FALSE((grid.getConcentrations().array() < 0.0).any());
}