perf: represent inner boundary conditions with a std::map
refactor: inner boundary conditions are now accessible via methods test: update test cases
This commit is contained in:
parent
94e83b5eb8
commit
592f59dbc5
@ -3,6 +3,7 @@
|
||||
|
||||
#include <array>
|
||||
#include <bits/stdint-uintn.h>
|
||||
#include <map>
|
||||
#include <stdexcept>
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
@ -128,6 +129,31 @@ public:
|
||||
*/
|
||||
auto col_boundary(uint32_t i) const -> bc_tuple;
|
||||
|
||||
/**
|
||||
* Sets one cell of the inner grid to a given boundary condition.
|
||||
*
|
||||
* \param bc Boundary condition to be set.
|
||||
* \param x Index of grid cell in x direction.
|
||||
* \param y Index of grid cell in y direction.
|
||||
*/
|
||||
void setInnerBC(boundary_condition bc, int x, int y);
|
||||
|
||||
/**
|
||||
* Unsets a previously set inner boundary condition.
|
||||
*
|
||||
* \param x Index of grid cell in x direction.
|
||||
* \param y Index of grid cell in y direction.
|
||||
*/
|
||||
void unsetInnerBC(int x, int y);
|
||||
|
||||
/**
|
||||
* Returns the current boundary condition set for specific inner grid cell.
|
||||
*
|
||||
* \param x Index of grid cell in x direction.
|
||||
* \param y Index of grid cell in y direction.
|
||||
*/
|
||||
auto getInnerBC(int x, int y) -> boundary_condition;
|
||||
|
||||
/**
|
||||
* Get a row of field and its inner boundary conditions.
|
||||
*
|
||||
@ -162,7 +188,7 @@ public:
|
||||
private:
|
||||
std::vector<boundary_condition> bc_internal;
|
||||
|
||||
bc_vec special_cells;
|
||||
std::map<uint32_t, boundary_condition> inner_cells;
|
||||
|
||||
uint8_t dim;
|
||||
|
||||
@ -200,12 +226,6 @@ public:
|
||||
* \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");
|
||||
@ -243,12 +263,6 @@ public:
|
||||
* \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");
|
||||
|
||||
@ -10,7 +10,6 @@ constexpr uint8_t DIM_2D = 4;
|
||||
|
||||
tug::bc::BoundaryCondition::BoundaryCondition(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;
|
||||
@ -24,7 +23,6 @@ tug::bc::BoundaryCondition::BoundaryCondition(int x) {
|
||||
tug::bc::BoundaryCondition::BoundaryCondition(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[X_DIM] = x;
|
||||
@ -126,10 +124,25 @@ auto tug::bc::BoundaryCondition::getInnerRow(uint32_t i) const -> bc_vec {
|
||||
throw_out_of_range("Index is out of range");
|
||||
}
|
||||
|
||||
auto start = this->special_cells.begin() + (i * this->sizes[X_DIM]);
|
||||
auto end = this->special_cells.begin() + ((i + 1) * this->sizes[X_DIM]);
|
||||
bc_vec row(this->sizes[X_DIM], {tug::bc::BC_UNSET, 0});
|
||||
|
||||
bc_vec row(start, end);
|
||||
if (this->inner_cells.empty()) {
|
||||
return row;
|
||||
}
|
||||
|
||||
uint32_t index_min = i * this->sizes[X_DIM];
|
||||
uint32_t index_max = ((i + 1) * this->sizes[X_DIM]) - 1;
|
||||
|
||||
for (auto const &cell : this->inner_cells) {
|
||||
if (cell.first < index_min) {
|
||||
continue;
|
||||
}
|
||||
if (cell.first > index_max) {
|
||||
break;
|
||||
}
|
||||
|
||||
row[cell.first - index_min] = cell.second;
|
||||
}
|
||||
|
||||
return row;
|
||||
}
|
||||
@ -142,12 +155,55 @@ auto tug::bc::BoundaryCondition::getInnerCol(uint32_t i) const -> bc_vec {
|
||||
throw_out_of_range("Index is out of range");
|
||||
}
|
||||
|
||||
bc_vec col;
|
||||
col.reserve(this->sizes[Y_DIM]);
|
||||
bc_vec col(this->sizes[Y_DIM], {tug::bc::BC_UNSET, 0});
|
||||
|
||||
for (int j = 0; j < this->sizes[Y_DIM]; i += this->sizes[X_DIM], j++) {
|
||||
col[j] = this->special_cells[i];
|
||||
if (this->inner_cells.empty()) {
|
||||
return col;
|
||||
}
|
||||
|
||||
for (auto const &cell : this->inner_cells) {
|
||||
if (cell.first % this->sizes[X_DIM] == i) {
|
||||
col[cell.first / this->sizes[X_DIM]] = cell.second;
|
||||
}
|
||||
}
|
||||
|
||||
return col;
|
||||
}
|
||||
|
||||
void tug::bc::BoundaryCondition::setInnerBC(boundary_condition bc, int x,
|
||||
int y = 0) {
|
||||
if (x >= this->sizes[X_DIM] || y >= this->sizes[Y_DIM]) {
|
||||
throw_out_of_range("One input parameter is out of range");
|
||||
}
|
||||
uint32_t index = x * this->sizes[Y_DIM] + y;
|
||||
auto it = this->inner_cells.find(index);
|
||||
|
||||
if (it != this->inner_cells.end()) {
|
||||
it->second = bc;
|
||||
return;
|
||||
}
|
||||
|
||||
this->inner_cells.insert({index, bc});
|
||||
}
|
||||
|
||||
void tug::bc::BoundaryCondition::unsetInnerBC(int x, int y) {
|
||||
uint32_t index = x * this->sizes[Y_DIM] + y;
|
||||
this->inner_cells.erase(index);
|
||||
}
|
||||
|
||||
auto tug::bc::BoundaryCondition::getInnerBC(int x, int y = 0)
|
||||
-> boundary_condition {
|
||||
if (x >= this->sizes[X_DIM] || y >= this->sizes[Y_DIM]) {
|
||||
throw_out_of_range("One input parameter is out of range");
|
||||
}
|
||||
|
||||
uint32_t index = x * this->sizes[Y_DIM] + y;
|
||||
|
||||
auto it = this->inner_cells.find(index);
|
||||
|
||||
if (it != this->inner_cells.end()) {
|
||||
return it->second;
|
||||
}
|
||||
|
||||
return {tug::bc::BC_UNSET, 0};
|
||||
}
|
||||
|
||||
@ -98,22 +98,22 @@ TEST_CASE("1D special inner grid cells") {
|
||||
BoundaryCondition bc(5);
|
||||
boundary_condition bc_set = {BC_TYPE_CONSTANT, BC_CONST_VALUE};
|
||||
|
||||
SUBCASE("valid set") { CHECK_NOTHROW(bc(BC_INNER, 0) = bc_set); }
|
||||
SUBCASE("valid set") { CHECK_NOTHROW(bc.setInnerBC(bc_set, 0, 0)); }
|
||||
|
||||
SUBCASE("valid get") {
|
||||
bc(BC_INNER, 0) = bc_set;
|
||||
CHECK_EQ(bc(BC_INNER, 0).type, bc_set.type);
|
||||
bc.setInnerBC(bc_set, 0, 0);
|
||||
CHECK_EQ(bc.getInnerBC(0, 0).type, bc_set.type);
|
||||
}
|
||||
|
||||
SUBCASE("invalid get") {
|
||||
CHECK_EQ(bc(BC_INNER, 1).type, BC_UNSET);
|
||||
CHECK_THROWS(bc(BC_INNER, 5));
|
||||
CHECK_EQ(bc.getInnerBC(1, 0).type, BC_UNSET);
|
||||
CHECK_THROWS(bc.getInnerBC(0, 1));
|
||||
}
|
||||
|
||||
SUBCASE("invalid set") { CHECK_THROWS(bc(BC_INNER, 5) = bc_set); }
|
||||
SUBCASE("invalid set") { CHECK_THROWS(bc.setInnerBC(bc_set, 0, 1)); }
|
||||
|
||||
SUBCASE("valid row getter") {
|
||||
bc(BC_INNER, 1) = bc_set;
|
||||
bc.setInnerBC(bc_set, 1, 0);
|
||||
|
||||
bc_vec ret = bc.getInnerRow(0);
|
||||
|
||||
@ -130,23 +130,23 @@ TEST_CASE("2D special inner grid cells") {
|
||||
BoundaryCondition bc(5, 5);
|
||||
boundary_condition bc_set = {BC_TYPE_CONSTANT, BC_CONST_VALUE};
|
||||
|
||||
SUBCASE("valid set") { CHECK_NOTHROW(bc(BC_INNER, 0) = bc_set); }
|
||||
SUBCASE("valid set") { CHECK_NOTHROW(bc.setInnerBC(bc_set, 0, 0)); }
|
||||
|
||||
SUBCASE("valid get") {
|
||||
bc(BC_INNER, 0) = bc_set;
|
||||
CHECK_EQ(bc(BC_INNER, 0).type, bc_set.type);
|
||||
bc.setInnerBC(bc_set, 0, 0);
|
||||
CHECK_EQ(bc.getInnerBC(0, 0).type, bc_set.type);
|
||||
}
|
||||
|
||||
SUBCASE("invalid get") {
|
||||
CHECK_EQ(bc(BC_INNER, 1).type, BC_UNSET);
|
||||
CHECK_THROWS(bc(BC_INNER, 25));
|
||||
CHECK_EQ(bc.getInnerBC(1, 0).type, BC_UNSET);
|
||||
CHECK_THROWS(bc.getInnerBC(5, 5));
|
||||
}
|
||||
|
||||
SUBCASE("invalid set") { CHECK_THROWS(bc(BC_INNER, 25) = bc_set); }
|
||||
SUBCASE("invalid set") { CHECK_THROWS(bc.setInnerBC(bc_set, 5, 5)); }
|
||||
|
||||
SUBCASE("valid row getter") {
|
||||
bc(BC_INNER, 0) = bc_set;
|
||||
bc(BC_INNER, 6) = bc_set;
|
||||
bc.setInnerBC(bc_set, 0, 0);
|
||||
bc.setInnerBC(bc_set, 1, 1);
|
||||
|
||||
bc_vec ret = bc.getInnerRow(0);
|
||||
|
||||
@ -160,8 +160,8 @@ TEST_CASE("2D special inner grid cells") {
|
||||
}
|
||||
|
||||
SUBCASE("valid col getter") {
|
||||
bc(BC_INNER, 1) = bc_set;
|
||||
bc(BC_INNER, 5) = bc_set;
|
||||
bc.setInnerBC(bc_set, 0, 1);
|
||||
bc.setInnerBC(bc_set, 1, 0);
|
||||
|
||||
bc_vec ret = bc.getInnerCol(0);
|
||||
|
||||
@ -174,6 +174,22 @@ TEST_CASE("2D special inner grid cells") {
|
||||
CHECK_EQ(ret[1].type, BC_UNSET);
|
||||
}
|
||||
|
||||
SUBCASE("unset boundary condition") {
|
||||
bc.setInnerBC(bc_set, 0, 0);
|
||||
bc.setInnerBC(bc_set, 1, 1);
|
||||
bc.unsetInnerBC(1, 1);
|
||||
|
||||
bc_vec ret = bc.getInnerRow(1);
|
||||
|
||||
CHECK_EQ(ret[0].type, BC_UNSET);
|
||||
CHECK_EQ(ret[1].type, BC_UNSET);
|
||||
|
||||
ret = bc.getInnerCol(1);
|
||||
|
||||
CHECK_EQ(ret[0].type, BC_UNSET);
|
||||
CHECK_EQ(ret[1].type, BC_UNSET);
|
||||
}
|
||||
|
||||
SUBCASE("invalid row getter") { CHECK_THROWS(bc.getInnerRow(5)); }
|
||||
|
||||
SUBCASE("invalid col getter") { CHECK_THROWS(bc.getInnerCol(5)); }
|
||||
|
||||
@ -135,7 +135,7 @@ TEST_CASE("2D closed boundaries, 1 constant cell in the middle") {
|
||||
BoundaryCondition bc(N, M);
|
||||
|
||||
field[MID] = val;
|
||||
bc(BC_INNER, MID) = {BC_TYPE_CONSTANT, val};
|
||||
bc.setInnerBC({BC_TYPE_CONSTANT, val}, N / 2, M / 2);
|
||||
|
||||
TugInput diffu = setupDiffu();
|
||||
diffu.setBoundaryCondition(bc);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user