feat: add setting of inner boundary conditions
It is possible to define inner grid cells with a type of either CLOSED, FLUX, CLOSED or UNSET.
This commit is contained in:
parent
fd7e2f5b63
commit
b6eb212bcb
@ -19,7 +19,7 @@ int main(int argc, char *argv[]) {
|
||||
std::vector<double> alpha(n, 1e-1);
|
||||
std::vector<double> field(n, 1e-6);
|
||||
|
||||
BTCSBoundaryCondition bc;
|
||||
BTCSBoundaryCondition bc(n);
|
||||
|
||||
// create instance of diffusion module
|
||||
BTCSDiffusion diffu(dim);
|
||||
|
||||
@ -12,9 +12,10 @@ typedef uint8_t bctype;
|
||||
namespace Diffusion {
|
||||
|
||||
enum {
|
||||
BC_TYPE_CLOSED, /**< Defines a closed/Neumann boundary condition. */
|
||||
BC_TYPE_FLUX, /**< Defines a flux/Cauchy boundary condition. */
|
||||
BC_TYPE_CONSTANT /**< Defines a constant/Dirichlet boundary condition. */
|
||||
BC_TYPE_CLOSED, /**< Defines a closed/Neumann boundary condition. */
|
||||
BC_TYPE_FLUX, /**< Defines a flux/Cauchy boundary condition. */
|
||||
BC_TYPE_CONSTANT, /**< Defines a constant/Dirichlet boundary condition. */
|
||||
BC_UNSET /**< Indicates undefined boundary condition*/
|
||||
};
|
||||
|
||||
enum {
|
||||
@ -23,7 +24,9 @@ enum {
|
||||
BC_SIDE_RIGHT, /**< Defines boundary conditions for the right side of the
|
||||
grid. */
|
||||
BC_SIDE_TOP, /**< Defines boundary conditions for the top of the grid. */
|
||||
BC_SIDE_BOTTOM /**< Defines boundary conditions for the bottom of the grid. */
|
||||
BC_SIDE_BOTTOM, /**< Defines boundary conditions for the bottom of the grid.
|
||||
*/
|
||||
BC_INNER
|
||||
};
|
||||
|
||||
/**
|
||||
@ -40,6 +43,7 @@ typedef struct boundary_condition_s {
|
||||
* Represents both boundary conditions of a row/column.
|
||||
*/
|
||||
typedef std::array<boundary_condition, 2> bc_tuple;
|
||||
typedef std::vector<boundary_condition> bc_vec;
|
||||
|
||||
/**
|
||||
* Class to define the boundary condition of a grid.
|
||||
@ -49,8 +53,10 @@ public:
|
||||
/**
|
||||
* Creates a new instance with two elements. Used when defining boundary
|
||||
* conditions of 1D grids.
|
||||
*
|
||||
* \param x Number of grid cells in x-direction
|
||||
*/
|
||||
BTCSBoundaryCondition();
|
||||
BTCSBoundaryCondition(int x);
|
||||
|
||||
/**
|
||||
* Creates a new instance with 4 * max(x,y) elements. Used to describe the
|
||||
@ -121,6 +127,24 @@ public:
|
||||
*/
|
||||
auto col_boundary(uint32_t i) const -> bc_tuple;
|
||||
|
||||
/**
|
||||
* Get a row of field and its inner boundary conditions.
|
||||
*
|
||||
* \param i Index of the row starting at 0.
|
||||
*
|
||||
* \returns Row of the inner boundary conditions of the field.
|
||||
*/
|
||||
auto getInnerRow(uint32_t i) const -> bc_vec;
|
||||
|
||||
/**
|
||||
* Get a column of field and its inner boundary conditions.
|
||||
*
|
||||
* \param i Index of the column starting at 0.
|
||||
*
|
||||
* \returns Column of the inner boundary conditions of the field.
|
||||
*/
|
||||
auto getInnerCol(uint32_t i) const -> bc_vec;
|
||||
|
||||
/**
|
||||
* Create an instance of boundary_condition data type. Can be seen as a helper
|
||||
* function.
|
||||
@ -137,12 +161,24 @@ public:
|
||||
private:
|
||||
std::vector<boundary_condition> bc_internal;
|
||||
|
||||
bc_vec special_cells;
|
||||
|
||||
uint8_t dim;
|
||||
|
||||
uint32_t sizes[2];
|
||||
uint32_t maxsize;
|
||||
uint32_t maxindex;
|
||||
|
||||
enum { X_DIM, Y_DIM };
|
||||
|
||||
public:
|
||||
/**
|
||||
* Returns the left/right boundary condition for 1D grid.
|
||||
*
|
||||
* \param side Side of the boundary condition to get.
|
||||
*
|
||||
* \returns Boundary condition
|
||||
*/
|
||||
boundary_condition operator()(uint8_t side) const {
|
||||
if (dim != 1) {
|
||||
throw std::invalid_argument(
|
||||
@ -154,7 +190,21 @@ public:
|
||||
return bc_internal[side];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the boundary condition of a given side for 2D grids.
|
||||
*
|
||||
* \param side Side of the boundary condition to get.
|
||||
* \param i Index of the boundary condition.
|
||||
*
|
||||
* \returns Boundary condition
|
||||
*/
|
||||
boundary_condition operator()(uint8_t side, uint32_t i) const {
|
||||
if (side == BC_INNER) {
|
||||
if (i > maxindex) {
|
||||
throw std::out_of_range("Index exceeds grid cell numbers");
|
||||
}
|
||||
return special_cells[i];
|
||||
}
|
||||
if (dim != 2) {
|
||||
throw std::invalid_argument(
|
||||
"Only 2D grids support 2 parameters in operator");
|
||||
@ -165,6 +215,13 @@ public:
|
||||
return bc_internal[side * maxsize + i];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the left/right boundary condition for 1D grid.
|
||||
*
|
||||
* \param side Side of the boundary condition to get.
|
||||
*
|
||||
* \returns Boundary condition
|
||||
*/
|
||||
boundary_condition &operator()(uint8_t side) {
|
||||
if (dim != 1) {
|
||||
throw std::invalid_argument(
|
||||
@ -176,7 +233,21 @@ public:
|
||||
return bc_internal[side];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the boundary condition of a given side for 2D grids.
|
||||
*
|
||||
* \param side Side of the boundary condition to get.
|
||||
* \param i Index of the boundary condition.
|
||||
*
|
||||
* \returns Boundary condition
|
||||
*/
|
||||
boundary_condition &operator()(uint8_t side, uint32_t i) {
|
||||
if (side == BC_INNER) {
|
||||
if (i > maxindex) {
|
||||
throw std::out_of_range("Index exceeds grid cell numbers");
|
||||
}
|
||||
return special_cells[i];
|
||||
}
|
||||
if (dim != 2) {
|
||||
throw std::invalid_argument("Explicit setting of bc value with 2 "
|
||||
"parameters is only supported for 2D grids");
|
||||
|
||||
@ -8,23 +8,29 @@
|
||||
constexpr uint8_t DIM_1D = 2;
|
||||
constexpr uint8_t DIM_2D = 4;
|
||||
|
||||
Diffusion::BTCSBoundaryCondition::BTCSBoundaryCondition() {
|
||||
Diffusion::BTCSBoundaryCondition::BTCSBoundaryCondition(int x) {
|
||||
this->bc_internal.resize(DIM_1D, {0, 0});
|
||||
this->special_cells.resize(x, {BC_UNSET, 0});
|
||||
this->dim = 1;
|
||||
// this value is actually unused
|
||||
this->maxsize = 1;
|
||||
|
||||
this->sizes[0] = 1;
|
||||
this->sizes[1] = 0;
|
||||
this->sizes[X_DIM] = 1;
|
||||
this->sizes[Y_DIM] = x;
|
||||
|
||||
this->maxindex = x - 1;
|
||||
}
|
||||
|
||||
Diffusion::BTCSBoundaryCondition::BTCSBoundaryCondition(int x, int y) {
|
||||
this->maxsize = (x >= y ? x : y);
|
||||
this->bc_internal.resize(DIM_2D * maxsize, {0, 0});
|
||||
this->special_cells.resize(x * y, {BC_UNSET, 0});
|
||||
this->dim = 2;
|
||||
|
||||
this->sizes[0] = x;
|
||||
this->sizes[1] = y;
|
||||
this->sizes[X_DIM] = x;
|
||||
this->sizes[Y_DIM] = y;
|
||||
|
||||
this->maxindex = (x * y) - 1;
|
||||
}
|
||||
|
||||
void Diffusion::BTCSBoundaryCondition::setSide(
|
||||
@ -38,8 +44,8 @@ void Diffusion::BTCSBoundaryCondition::setSide(
|
||||
|
||||
uint32_t size =
|
||||
(side == Diffusion::BC_SIDE_LEFT || side == Diffusion::BC_SIDE_RIGHT
|
||||
? this->sizes[0]
|
||||
: this->sizes[1]);
|
||||
? this->sizes[X_DIM]
|
||||
: this->sizes[Y_DIM]);
|
||||
|
||||
for (uint32_t i = 0; i < size; i++) {
|
||||
this->bc_internal[side * maxsize + i] = input_bc;
|
||||
@ -57,8 +63,8 @@ void Diffusion::BTCSBoundaryCondition::setSide(
|
||||
|
||||
uint32_t size =
|
||||
(side == Diffusion::BC_SIDE_LEFT || side == Diffusion::BC_SIDE_RIGHT
|
||||
? this->sizes[0]
|
||||
: this->sizes[1]);
|
||||
? this->sizes[X_DIM]
|
||||
: this->sizes[Y_DIM]);
|
||||
|
||||
if (input_bc.size() > size) {
|
||||
throw_out_of_range("Input vector is greater than maximum excpected value");
|
||||
@ -80,8 +86,8 @@ auto Diffusion::BTCSBoundaryCondition::getSide(uint8_t side)
|
||||
|
||||
uint32_t size =
|
||||
(side == Diffusion::BC_SIDE_LEFT || side == Diffusion::BC_SIDE_RIGHT
|
||||
? this->sizes[0]
|
||||
: this->sizes[1]);
|
||||
? this->sizes[X_DIM]
|
||||
: this->sizes[Y_DIM]);
|
||||
|
||||
std::vector<Diffusion::boundary_condition> out(size);
|
||||
|
||||
@ -97,7 +103,7 @@ auto Diffusion::BTCSBoundaryCondition::col_boundary(uint32_t i) const
|
||||
if (this->dim == 1) {
|
||||
throw_invalid_argument("Access of column requires at least 2D grid");
|
||||
}
|
||||
if (i >= this->sizes[1]) {
|
||||
if (i >= this->sizes[Y_DIM]) {
|
||||
throw_out_of_range("Index out of range");
|
||||
}
|
||||
|
||||
@ -107,10 +113,42 @@ auto Diffusion::BTCSBoundaryCondition::col_boundary(uint32_t i) const
|
||||
|
||||
auto Diffusion::BTCSBoundaryCondition::row_boundary(uint32_t i) const
|
||||
-> Diffusion::bc_tuple {
|
||||
if (i >= this->sizes[0]) {
|
||||
if (i >= this->sizes[X_DIM]) {
|
||||
throw_out_of_range("Index out of range");
|
||||
}
|
||||
|
||||
return {this->bc_internal[BC_SIDE_LEFT * this->maxsize + i],
|
||||
this->bc_internal[BC_SIDE_RIGHT * this->maxsize + i]};
|
||||
}
|
||||
|
||||
auto Diffusion::BTCSBoundaryCondition::getInnerRow(uint32_t i) const -> bc_vec {
|
||||
if (i >= this->sizes[X_DIM]) {
|
||||
throw_out_of_range("Index is out of range");
|
||||
}
|
||||
|
||||
bc_vec::const_iterator start =
|
||||
this->special_cells.begin() + (i * this->sizes[Y_DIM]);
|
||||
bc_vec::const_iterator end =
|
||||
this->special_cells.begin() + ((i + 1) * this->sizes[Y_DIM]);
|
||||
|
||||
bc_vec row(start, end);
|
||||
|
||||
return row;
|
||||
}
|
||||
|
||||
auto Diffusion::BTCSBoundaryCondition::getInnerCol(uint32_t i) const -> bc_vec {
|
||||
if (this->dim != 2) {
|
||||
throw_invalid_argument("getInnerCol is only applicable for 2D grids");
|
||||
} else if (i >= this->sizes[X_DIM]) {
|
||||
throw_out_of_range("Index is out of range");
|
||||
}
|
||||
|
||||
bc_vec col;
|
||||
col.reserve(this->sizes[X_DIM]);
|
||||
|
||||
for (int j = 0; j < this->sizes[X_DIM]; i += this->sizes[Y_DIM], j++) {
|
||||
col[j] = this->special_cells[i];
|
||||
}
|
||||
|
||||
return col;
|
||||
}
|
||||
|
||||
@ -7,7 +7,7 @@ using namespace Diffusion;
|
||||
|
||||
TEST_CASE("1D Boundary Condition") {
|
||||
|
||||
BTCSBoundaryCondition bc;
|
||||
BTCSBoundaryCondition bc(5);
|
||||
boundary_condition bc_set = {BC_TYPE_CONSTANT, BC_CONST_VALUE};
|
||||
|
||||
SUBCASE("valid get") { CHECK_EQ(bc(BC_SIDE_LEFT).value, 0); }
|
||||
@ -50,7 +50,7 @@ TEST_CASE("2D Boundary Condition") {
|
||||
SUBCASE("valid get") { CHECK_EQ(bc(BC_SIDE_LEFT, 0).value, 0); }
|
||||
|
||||
SUBCASE("invalid get") {
|
||||
CHECK_THROWS(bc(4, 0));
|
||||
CHECK_THROWS(bc(5, 0));
|
||||
CHECK_THROWS(bc(BC_SIDE_LEFT));
|
||||
}
|
||||
|
||||
@ -62,7 +62,7 @@ TEST_CASE("2D Boundary Condition") {
|
||||
|
||||
SUBCASE("invalid set") {
|
||||
CHECK_THROWS(bc(BC_SIDE_LEFT) = bc_set);
|
||||
CHECK_THROWS(bc(4, 0) = bc_set);
|
||||
CHECK_THROWS(bc(5, 0) = bc_set);
|
||||
}
|
||||
|
||||
SUBCASE("call of setSide") {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user