feat: Integrate GoogleTest for unit testing and update CI configuration

This commit is contained in:
Max Lübke 2024-12-06 09:28:53 +01:00
parent a986242852
commit 6981373deb
8 changed files with 256 additions and 260 deletions

View File

@ -1,27 +1,26 @@
image: git.gfz-potsdam.de:5000/naaice/tug:ci
image: gcc:14
before_script:
- apt-get update && apt-get install -y cmake ninja-build libeigen3-dev git
stages:
- build
- test
- static_analyze
- doc
build_release:
stage: build
artifacts:
paths:
- build/test/testTug
expire_in: 100s
script:
- mkdir build && cd build
- cmake -DCMAKE_BUILD_TYPE=Release -DTUG_ENABLE_TESTING=ON ..
- make -j$(nproc)
- cp ../test/FTCS_11_11_7000.csv test/
test:
stage: test
script:
- ./build/test/testTug
- mkdir build && cd build
- cmake -DCMAKE_BUILD_TYPE=Release -DTUG_ENABLE_TESTING=ON -G Ninja ..
- ninja
- ctest --output-junit test_results.xml
artifacts:
when: always
paths:
- build/test_results.xml
reports:
junit: build/test_results.xml
pages:
stage: doc

View File

@ -90,6 +90,7 @@ install(FILES "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/tug DESTINATION include)
if(TUG_ENABLE_TESTING)
enable_testing()
add_subdirectory(test)
endif()

View File

@ -1,7 +1,24 @@
find_package(doctest REQUIRED)
include(FetchContent)
add_executable(testTug setup.cpp testSimulation.cpp testGrid.cpp testFTCS.cpp testBoundary.cpp)
target_link_libraries(testTug doctest::doctest tug)
FetchContent_Declare(
googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG v1.15.2
)
FetchContent_MakeAvailable(googletest)
add_executable(testTug
testSimulation.cpp
testGrid.cpp
testFTCS.cpp
testBoundary.cpp
)
target_link_libraries(testTug tug GTest::gtest_main)
include(GoogleTest)
gtest_discover_tests(testTug)
# get relative path of the CSV file
get_filename_component(testSimulationCSV "FTCS_11_11_7000.csv" REALPATH)
@ -9,8 +26,3 @@ get_filename_component(testSimulationCSV "FTCS_11_11_7000.csv" REALPATH)
configure_file(testSimulation.hpp.in testSimulation.hpp)
# include test directory with generated header file from above
target_include_directories(testTug PUBLIC "${CMAKE_CURRENT_BINARY_DIR}" "${PROJECT_SOURCE_DIR}/src")
add_custom_target(
check
COMMAND $<TARGET_FILE:testTug>
DEPENDS testTug)

View File

@ -1,11 +1,13 @@
#include <Eigen/Core>
#include <Eigen/Dense>
#include <fstream>
#include <ios>
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <gtest/gtest.h>
#define TUG_TEST(x) TEST(Tug, x)
inline Eigen::MatrixXd CSV2Eigen(std::string file2Convert) {
std::vector<double> matrixEntries;

View File

@ -1,36 +1,31 @@
#include <doctest/doctest.h>
#include <iostream>
#include <stdio.h>
#include <string>
#include <tug/Boundary.hpp>
#include <typeinfo>
#include <utility>
#include <vector>
using namespace std;
using namespace tug;
TEST_CASE("BoundaryElement") {
#include <gtest/gtest.h>
#define BOUNDARY_TEST(x) TEST(Boundary, x)
BOUNDARY_TEST(Element) {
SUBCASE("Closed case") {
BoundaryElement boundaryElementClosed = BoundaryElement<double>();
CHECK_NOTHROW(BoundaryElement<double>());
CHECK_EQ(boundaryElementClosed.getType(), BC_TYPE_CLOSED);
CHECK_EQ(boundaryElementClosed.getValue(), -1);
CHECK_THROWS(boundaryElementClosed.setValue(0.2));
}
EXPECT_NO_THROW(BoundaryElement<double>());
EXPECT_EQ(boundaryElementClosed.getType(), BC_TYPE_CLOSED);
EXPECT_DOUBLE_EQ(boundaryElementClosed.getValue(), -1);
EXPECT_ANY_THROW(boundaryElementClosed.setValue(0.2));
SUBCASE("Constant case") {
BoundaryElement boundaryElementConstant = BoundaryElement(0.1);
CHECK_NOTHROW(BoundaryElement(0.1));
CHECK_EQ(boundaryElementConstant.getType(), BC_TYPE_CONSTANT);
CHECK_EQ(boundaryElementConstant.getValue(), 0.1);
CHECK_NOTHROW(boundaryElementConstant.setValue(0.2));
CHECK_EQ(boundaryElementConstant.getValue(), 0.2);
}
EXPECT_NO_THROW(BoundaryElement(0.1));
EXPECT_EQ(boundaryElementConstant.getType(), BC_TYPE_CONSTANT);
EXPECT_DOUBLE_EQ(boundaryElementConstant.getValue(), 0.1);
EXPECT_NO_THROW(boundaryElementConstant.setValue(0.2));
EXPECT_DOUBLE_EQ(boundaryElementConstant.getValue(), 0.2);
}
TEST_CASE("Boundary Class") {
BOUNDARY_TEST(Class) {
Grid grid1D = Grid64(10);
Grid grid2D = Grid64(10, 12);
Boundary boundary1D = Boundary(grid1D);
@ -47,56 +42,56 @@ TEST_CASE("Boundary Class") {
std::vector<std::pair<bool, double>> col_ibc(10, std::make_pair(false, -1));
col_ibc[0] = innerBoundary;
SUBCASE("Boundaries 1D case") {
CHECK_NOTHROW(Boundary boundary(grid1D));
CHECK_EQ(boundary1D.getBoundarySide(BC_SIDE_LEFT).size(), 1);
CHECK_EQ(boundary1D.getBoundarySide(BC_SIDE_RIGHT).size(), 1);
CHECK_EQ(boundary1D.getBoundaryElementType(BC_SIDE_LEFT, 0),
{
EXPECT_NO_THROW(Boundary boundary(grid1D));
EXPECT_EQ(boundary1D.getBoundarySide(BC_SIDE_LEFT).size(), 1);
EXPECT_EQ(boundary1D.getBoundarySide(BC_SIDE_RIGHT).size(), 1);
EXPECT_EQ(boundary1D.getBoundaryElementType(BC_SIDE_LEFT, 0),
BC_TYPE_CLOSED);
CHECK_THROWS(boundary1D.getBoundarySide(BC_SIDE_TOP));
CHECK_THROWS(boundary1D.getBoundarySide(BC_SIDE_BOTTOM));
CHECK_NOTHROW(boundary1D.setBoundarySideClosed(BC_SIDE_LEFT));
CHECK_THROWS(boundary1D.setBoundarySideClosed(BC_SIDE_TOP));
CHECK_NOTHROW(boundary1D.setBoundarySideConstant(BC_SIDE_LEFT, 1.0));
CHECK_EQ(boundary1D.getBoundaryElementValue(BC_SIDE_LEFT, 0), 1.0);
CHECK_THROWS(boundary1D.getBoundaryElementValue(BC_SIDE_LEFT, 2));
CHECK_EQ(boundary1D.getBoundaryElementType(BC_SIDE_LEFT, 0),
EXPECT_ANY_THROW(boundary1D.getBoundarySide(BC_SIDE_TOP));
EXPECT_ANY_THROW(boundary1D.getBoundarySide(BC_SIDE_BOTTOM));
EXPECT_NO_THROW(boundary1D.setBoundarySideClosed(BC_SIDE_LEFT));
EXPECT_ANY_THROW(boundary1D.setBoundarySideClosed(BC_SIDE_TOP));
EXPECT_NO_THROW(boundary1D.setBoundarySideConstant(BC_SIDE_LEFT, 1.0));
EXPECT_DOUBLE_EQ(boundary1D.getBoundaryElementValue(BC_SIDE_LEFT, 0), 1.0);
EXPECT_ANY_THROW(boundary1D.getBoundaryElementValue(BC_SIDE_LEFT, 2));
EXPECT_EQ(boundary1D.getBoundaryElementType(BC_SIDE_LEFT, 0),
BC_TYPE_CONSTANT);
CHECK_EQ(boundary1D.getBoundaryElement(BC_SIDE_LEFT, 0).getType(),
EXPECT_EQ(boundary1D.getBoundaryElement(BC_SIDE_LEFT, 0).getType(),
boundary1DVector[0].getType());
CHECK_NOTHROW(boundary1D.setInnerBoundary(0, inner_condition_value));
CHECK_THROWS(boundary1D.setInnerBoundary(0, 0, inner_condition_value));
CHECK_EQ(boundary1D.getInnerBoundary(0), innerBoundary);
CHECK_EQ(boundary1D.getInnerBoundary(1).first, false);
EXPECT_NO_THROW(boundary1D.setInnerBoundary(0, inner_condition_value));
EXPECT_ANY_THROW(boundary1D.setInnerBoundary(0, 0, inner_condition_value));
EXPECT_EQ(boundary1D.getInnerBoundary(0), innerBoundary);
EXPECT_FALSE(boundary1D.getInnerBoundary(1).first);
}
SUBCASE("Boundaries 2D case") {
CHECK_NOTHROW(Boundary boundary(grid1D));
CHECK_EQ(boundary2D.getBoundarySide(BC_SIDE_LEFT).size(), 10);
CHECK_EQ(boundary2D.getBoundarySide(BC_SIDE_RIGHT).size(), 10);
CHECK_EQ(boundary2D.getBoundarySide(BC_SIDE_TOP).size(), 12);
CHECK_EQ(boundary2D.getBoundarySide(BC_SIDE_BOTTOM).size(), 12);
CHECK_EQ(boundary2D.getBoundaryElementType(BC_SIDE_LEFT, 0),
{
EXPECT_NO_THROW(Boundary boundary(grid1D));
EXPECT_EQ(boundary2D.getBoundarySide(BC_SIDE_LEFT).size(), 10);
EXPECT_EQ(boundary2D.getBoundarySide(BC_SIDE_RIGHT).size(), 10);
EXPECT_EQ(boundary2D.getBoundarySide(BC_SIDE_TOP).size(), 12);
EXPECT_EQ(boundary2D.getBoundarySide(BC_SIDE_BOTTOM).size(), 12);
EXPECT_EQ(boundary2D.getBoundaryElementType(BC_SIDE_LEFT, 0),
BC_TYPE_CLOSED);
CHECK_NOTHROW(boundary2D.getBoundarySide(BC_SIDE_TOP));
CHECK_NOTHROW(boundary2D.getBoundarySide(BC_SIDE_BOTTOM));
CHECK_NOTHROW(boundary2D.setBoundarySideClosed(BC_SIDE_LEFT));
CHECK_NOTHROW(boundary2D.setBoundarySideClosed(BC_SIDE_TOP));
CHECK_NOTHROW(boundary2D.setBoundarySideConstant(BC_SIDE_LEFT, 1.0));
CHECK_EQ(boundary2D.getBoundaryElementValue(BC_SIDE_LEFT, 0), 1.0);
CHECK_THROWS(boundary2D.getBoundaryElementValue(BC_SIDE_LEFT, 12));
CHECK_EQ(boundary2D.getBoundaryElementType(BC_SIDE_LEFT, 0),
EXPECT_NO_THROW(boundary2D.getBoundarySide(BC_SIDE_TOP));
EXPECT_NO_THROW(boundary2D.getBoundarySide(BC_SIDE_BOTTOM));
EXPECT_NO_THROW(boundary2D.setBoundarySideClosed(BC_SIDE_LEFT));
EXPECT_NO_THROW(boundary2D.setBoundarySideClosed(BC_SIDE_TOP));
EXPECT_NO_THROW(boundary2D.setBoundarySideConstant(BC_SIDE_LEFT, 1.0));
EXPECT_DOUBLE_EQ(boundary2D.getBoundaryElementValue(BC_SIDE_LEFT, 0), 1.0);
EXPECT_ANY_THROW(boundary2D.getBoundaryElementValue(BC_SIDE_LEFT, 12));
EXPECT_EQ(boundary2D.getBoundaryElementType(BC_SIDE_LEFT, 0),
BC_TYPE_CONSTANT);
CHECK_EQ(boundary2D.getBoundaryElement(BC_SIDE_LEFT, 0).getType(),
EXPECT_EQ(boundary2D.getBoundaryElement(BC_SIDE_LEFT, 0).getType(),
boundary1DVector[0].getType());
CHECK_THROWS(boundary2D.setInnerBoundary(0, inner_condition_value));
CHECK_NOTHROW(boundary2D.setInnerBoundary(0, 1, inner_condition_value));
CHECK_EQ(boundary2D.getInnerBoundary(0, 1), innerBoundary);
CHECK_EQ(boundary2D.getInnerBoundary(0, 2).first, false);
EXPECT_ANY_THROW(boundary2D.setInnerBoundary(0, inner_condition_value));
EXPECT_NO_THROW(boundary2D.setInnerBoundary(0, 1, inner_condition_value));
EXPECT_EQ(boundary2D.getInnerBoundary(0, 1), innerBoundary);
EXPECT_FALSE(boundary2D.getInnerBoundary(0, 2).first);
CHECK_EQ(boundary2D.getInnerBoundaryRow(0), row_ibc);
CHECK_EQ(boundary2D.getInnerBoundaryCol(1), col_ibc);
EXPECT_EQ(boundary2D.getInnerBoundaryRow(0), row_ibc);
EXPECT_EQ(boundary2D.getInnerBoundaryCol(1), col_ibc);
}
}

View File

@ -1,10 +1,9 @@
#include <gtest/gtest.h>
#include <tug/Core/TugUtils.hpp>
#include <doctest/doctest.h>
#include <limits>
#include <gtest/gtest.h>
TEST_CASE("Maths") {
SUBCASE("mean between two alphas") {
TEST(FTCS, calcAlphaIntercell) {
double alpha1 = 10;
double alpha2 = 20;
double average = 15;
@ -14,7 +13,6 @@ TEST_CASE("Maths") {
// double difference = std::fabs(calcAlphaIntercell(alpha1, alpha2) -
// harmonicMean); CHECK(difference <
// std::numeric_limits<double>::epsilon());
CHECK_EQ(calcAlphaIntercell(alpha1, alpha2), harmonicMean);
CHECK_EQ(calcAlphaIntercell(alpha1, alpha2, false), average);
}
EXPECT_DOUBLE_EQ(calcAlphaIntercell(alpha1, alpha2), harmonicMean);
EXPECT_DOUBLE_EQ(calcAlphaIntercell(alpha1, alpha2, false), average);
}

View File

@ -1,258 +1,252 @@
#include <Eigen/Core>
#include <doctest/doctest.h>
#include <tug/Grid.hpp>
#include <vector>
#include <gtest/gtest.h>
using namespace Eigen;
using namespace std;
using namespace tug;
TEST_CASE("1D Grid, too small length") {
int l = 2;
CHECK_THROWS(Grid64(l));
#define GRID_TEST(x) TEST(Grid, x)
GRID_TEST(InvalidConstructorParams) {
EXPECT_ANY_THROW(Grid64(2));
EXPECT_ANY_THROW(Grid64(1, 4));
EXPECT_ANY_THROW(Grid64(4, 1));
}
TEST_CASE("2D Grid64, too small side") {
int r = 1;
int c = 4;
CHECK_THROWS(Grid64(r, c));
r = 4;
c = 1;
CHECK_THROWS(Grid64(r, c));
}
TEST_CASE("1D Grid64") {
GRID_TEST(Grid64OneDimensional) {
int l = 12;
Grid64 grid(l);
SUBCASE("correct construction") {
CHECK_EQ(grid.getDim(), 1);
CHECK_EQ(grid.getLength(), l);
CHECK_EQ(grid.getCol(), l);
CHECK_EQ(grid.getRow(), 1);
{
EXPECT_EQ(grid.getDim(), 1);
EXPECT_EQ(grid.getLength(), l);
EXPECT_EQ(grid.getCol(), l);
EXPECT_EQ(grid.getRow(), 1);
CHECK_EQ(grid.getConcentrations().rows(), 1);
CHECK_EQ(grid.getConcentrations().cols(), l);
CHECK_EQ(grid.getAlpha().rows(), 1);
CHECK_EQ(grid.getAlpha().cols(), l);
CHECK_EQ(grid.getDeltaCol(), 1);
EXPECT_EQ(grid.getConcentrations().rows(), 1);
EXPECT_EQ(grid.getConcentrations().cols(), l);
EXPECT_EQ(grid.getAlpha().rows(), 1);
EXPECT_EQ(grid.getAlpha().cols(), l);
EXPECT_EQ(grid.getDeltaCol(), 1);
CHECK_THROWS(grid.getAlphaX());
CHECK_THROWS(grid.getAlphaY());
CHECK_THROWS(grid.getDeltaRow());
EXPECT_ANY_THROW(grid.getAlphaX());
EXPECT_ANY_THROW(grid.getAlphaY());
EXPECT_ANY_THROW(grid.getDeltaRow());
}
SUBCASE("setting concentrations") {
{
// correct concentrations matrix
MatrixXd concentrations = MatrixXd::Constant(1, l, 3);
CHECK_NOTHROW(grid.setConcentrations(concentrations));
EXPECT_NO_THROW(grid.setConcentrations(concentrations));
// false concentrations matrix
MatrixXd wConcentrations = MatrixXd::Constant(2, l, 4);
CHECK_THROWS(grid.setConcentrations(wConcentrations));
EXPECT_ANY_THROW(grid.setConcentrations(wConcentrations));
}
SUBCASE("setting alpha") {
{
// correct alpha matrix
MatrixXd alpha = MatrixXd::Constant(1, l, 3);
CHECK_NOTHROW(grid.setAlpha(alpha));
EXPECT_NO_THROW(grid.setAlpha(alpha));
CHECK_THROWS(grid.setAlpha(alpha, alpha));
EXPECT_ANY_THROW(grid.setAlpha(alpha, alpha));
grid.setAlpha(alpha);
CHECK_EQ(grid.getAlpha(), alpha);
CHECK_THROWS(grid.getAlphaX());
CHECK_THROWS(grid.getAlphaY());
EXPECT_EQ(grid.getAlpha(), alpha);
EXPECT_ANY_THROW(grid.getAlphaX());
EXPECT_ANY_THROW(grid.getAlphaY());
// false alpha matrix
MatrixXd wAlpha = MatrixXd::Constant(3, l, 2);
CHECK_THROWS(grid.setAlpha(wAlpha));
EXPECT_ANY_THROW(grid.setAlpha(wAlpha));
}
SUBCASE("setting domain") {
{
int d = 8;
// set 1D domain
CHECK_NOTHROW(grid.setDomain(d));
EXPECT_NO_THROW(grid.setDomain(d));
// set 2D domain
CHECK_THROWS(grid.setDomain(d, d));
EXPECT_ANY_THROW(grid.setDomain(d, d));
grid.setDomain(d);
CHECK_EQ(grid.getDeltaCol(), double(d) / double(l));
CHECK_THROWS(grid.getDeltaRow());
EXPECT_DOUBLE_EQ(grid.getDeltaCol(), double(d) / double(l));
EXPECT_ANY_THROW(grid.getDeltaRow());
// set too small domain
d = 0;
CHECK_THROWS(grid.setDomain(d));
EXPECT_ANY_THROW(grid.setDomain(d));
d = -2;
CHECK_THROWS(grid.setDomain(d));
EXPECT_ANY_THROW(grid.setDomain(d));
}
}
TEST_CASE("2D Grid64 quadratic") {
GRID_TEST(Grid64Quadratic) {
int rc = 12;
Grid64 grid(rc, rc);
SUBCASE("correct construction") {
CHECK_EQ(grid.getDim(), 2);
CHECK_THROWS(grid.getLength());
CHECK_EQ(grid.getCol(), rc);
CHECK_EQ(grid.getRow(), rc);
{
EXPECT_EQ(grid.getDim(), 2);
EXPECT_ANY_THROW(grid.getLength());
EXPECT_EQ(grid.getCol(), rc);
EXPECT_EQ(grid.getRow(), rc);
CHECK_EQ(grid.getConcentrations().rows(), rc);
CHECK_EQ(grid.getConcentrations().cols(), rc);
CHECK_THROWS(grid.getAlpha());
EXPECT_EQ(grid.getConcentrations().rows(), rc);
EXPECT_EQ(grid.getConcentrations().cols(), rc);
EXPECT_ANY_THROW(grid.getAlpha());
CHECK_EQ(grid.getAlphaX().rows(), rc);
CHECK_EQ(grid.getAlphaX().cols(), rc);
CHECK_EQ(grid.getAlphaY().rows(), rc);
CHECK_EQ(grid.getAlphaY().cols(), rc);
CHECK_EQ(grid.getDeltaRow(), 1);
CHECK_EQ(grid.getDeltaCol(), 1);
EXPECT_EQ(grid.getAlphaX().rows(), rc);
EXPECT_EQ(grid.getAlphaX().cols(), rc);
EXPECT_EQ(grid.getAlphaY().rows(), rc);
EXPECT_EQ(grid.getAlphaY().cols(), rc);
EXPECT_EQ(grid.getDeltaRow(), 1);
EXPECT_EQ(grid.getDeltaCol(), 1);
}
SUBCASE("setting concentrations") {
{
// correct concentrations matrix
MatrixXd concentrations = MatrixXd::Constant(rc, rc, 2);
CHECK_NOTHROW(grid.setConcentrations(concentrations));
EXPECT_NO_THROW(grid.setConcentrations(concentrations));
// false concentrations matrix
MatrixXd wConcentrations = MatrixXd::Constant(rc, rc + 3, 1);
CHECK_THROWS(grid.setConcentrations(wConcentrations));
EXPECT_ANY_THROW(grid.setConcentrations(wConcentrations));
wConcentrations = MatrixXd::Constant(rc + 3, rc, 4);
CHECK_THROWS(grid.setConcentrations(wConcentrations));
EXPECT_ANY_THROW(grid.setConcentrations(wConcentrations));
wConcentrations = MatrixXd::Constant(rc + 2, rc + 4, 6);
CHECK_THROWS(grid.setConcentrations(wConcentrations));
EXPECT_ANY_THROW(grid.setConcentrations(wConcentrations));
}
SUBCASE("setting alphas") {
{
// correct alpha matrices
MatrixXd alphax = MatrixXd::Constant(rc, rc, 2);
MatrixXd alphay = MatrixXd::Constant(rc, rc, 4);
CHECK_NOTHROW(grid.setAlpha(alphax, alphay));
EXPECT_NO_THROW(grid.setAlpha(alphax, alphay));
CHECK_THROWS(grid.setAlpha(alphax));
EXPECT_ANY_THROW(grid.setAlpha(alphax));
grid.setAlpha(alphax, alphay);
CHECK_EQ(grid.getAlphaX(), alphax);
CHECK_EQ(grid.getAlphaY(), alphay);
CHECK_THROWS(grid.getAlpha());
EXPECT_EQ(grid.getAlphaX(), alphax);
EXPECT_EQ(grid.getAlphaY(), alphay);
EXPECT_ANY_THROW(grid.getAlpha());
// false alpha matrices
alphax = MatrixXd::Constant(rc + 3, rc + 1, 3);
CHECK_THROWS(grid.setAlpha(alphax, alphay));
EXPECT_ANY_THROW(grid.setAlpha(alphax, alphay));
alphay = MatrixXd::Constant(rc + 2, rc + 1, 3);
CHECK_THROWS(grid.setAlpha(alphax, alphay));
EXPECT_ANY_THROW(grid.setAlpha(alphax, alphay));
}
SUBCASE("setting domain") {
{
int dr = 8;
int dc = 9;
// set 1D domain
CHECK_THROWS(grid.setDomain(dr));
EXPECT_ANY_THROW(grid.setDomain(dr));
// set 2D domain
CHECK_NOTHROW(grid.setDomain(dr, dc));
EXPECT_NO_THROW(grid.setDomain(dr, dc));
grid.setDomain(dr, dc);
CHECK_EQ(grid.getDeltaCol(), double(dc) / double(rc));
CHECK_EQ(grid.getDeltaRow(), double(dr) / double(rc));
EXPECT_DOUBLE_EQ(grid.getDeltaCol(), double(dc) / double(rc));
EXPECT_DOUBLE_EQ(grid.getDeltaRow(), double(dr) / double(rc));
// set too small domain
dr = 0;
CHECK_THROWS(grid.setDomain(dr, dc));
EXPECT_ANY_THROW(grid.setDomain(dr, dc));
dr = 8;
dc = 0;
CHECK_THROWS(grid.setDomain(dr, dc));
EXPECT_ANY_THROW(grid.setDomain(dr, dc));
dr = -2;
CHECK_THROWS(grid.setDomain(dr, dc));
EXPECT_ANY_THROW(grid.setDomain(dr, dc));
}
}
TEST_CASE("2D Grid64 non-quadratic") {
GRID_TEST(Grid64NonQuadratic) {
int r = 12;
int c = 15;
Grid64 grid(r, c);
SUBCASE("correct construction") {
CHECK_EQ(grid.getDim(), 2);
CHECK_THROWS(grid.getLength());
CHECK_EQ(grid.getCol(), c);
CHECK_EQ(grid.getRow(), r);
{
EXPECT_EQ(grid.getDim(), 2);
EXPECT_ANY_THROW(grid.getLength());
EXPECT_EQ(grid.getCol(), c);
EXPECT_EQ(grid.getRow(), r);
CHECK_EQ(grid.getConcentrations().rows(), r);
CHECK_EQ(grid.getConcentrations().cols(), c);
CHECK_THROWS(grid.getAlpha());
EXPECT_EQ(grid.getConcentrations().rows(), r);
EXPECT_EQ(grid.getConcentrations().cols(), c);
EXPECT_ANY_THROW(grid.getAlpha());
CHECK_EQ(grid.getAlphaX().rows(), r);
CHECK_EQ(grid.getAlphaX().cols(), c);
CHECK_EQ(grid.getAlphaY().rows(), r);
CHECK_EQ(grid.getAlphaY().cols(), c);
CHECK_EQ(grid.getDeltaRow(), 1);
CHECK_EQ(grid.getDeltaCol(), 1);
EXPECT_EQ(grid.getAlphaX().rows(), r);
EXPECT_EQ(grid.getAlphaX().cols(), c);
EXPECT_EQ(grid.getAlphaY().rows(), r);
EXPECT_EQ(grid.getAlphaY().cols(), c);
EXPECT_EQ(grid.getDeltaRow(), 1);
EXPECT_EQ(grid.getDeltaCol(), 1);
}
SUBCASE("setting concentrations") {
{
// correct concentrations matrix
MatrixXd concentrations = MatrixXd::Constant(r, c, 2);
CHECK_NOTHROW(grid.setConcentrations(concentrations));
EXPECT_NO_THROW(grid.setConcentrations(concentrations));
// false concentrations matrix
MatrixXd wConcentrations = MatrixXd::Constant(r, c + 3, 6);
CHECK_THROWS(grid.setConcentrations(wConcentrations));
EXPECT_ANY_THROW(grid.setConcentrations(wConcentrations));
wConcentrations = MatrixXd::Constant(r + 3, c, 3);
CHECK_THROWS(grid.setConcentrations(wConcentrations));
EXPECT_ANY_THROW(grid.setConcentrations(wConcentrations));
wConcentrations = MatrixXd::Constant(r + 2, c + 4, 2);
CHECK_THROWS(grid.setConcentrations(wConcentrations));
EXPECT_ANY_THROW(grid.setConcentrations(wConcentrations));
}
SUBCASE("setting alphas") {
{
// correct alpha matrices
MatrixXd alphax = MatrixXd::Constant(r, c, 2);
MatrixXd alphay = MatrixXd::Constant(r, c, 4);
CHECK_NOTHROW(grid.setAlpha(alphax, alphay));
EXPECT_NO_THROW(grid.setAlpha(alphax, alphay));
CHECK_THROWS(grid.setAlpha(alphax));
EXPECT_ANY_THROW(grid.setAlpha(alphax));
grid.setAlpha(alphax, alphay);
CHECK_EQ(grid.getAlphaX(), alphax);
CHECK_EQ(grid.getAlphaY(), alphay);
CHECK_THROWS(grid.getAlpha());
EXPECT_EQ(grid.getAlphaX(), alphax);
EXPECT_EQ(grid.getAlphaY(), alphay);
EXPECT_ANY_THROW(grid.getAlpha());
// false alpha matrices
alphax = MatrixXd::Constant(r + 3, c + 1, 3);
CHECK_THROWS(grid.setAlpha(alphax, alphay));
EXPECT_ANY_THROW(grid.setAlpha(alphax, alphay));
alphay = MatrixXd::Constant(r + 2, c + 1, 5);
CHECK_THROWS(grid.setAlpha(alphax, alphay));
EXPECT_ANY_THROW(grid.setAlpha(alphax, alphay));
}
SUBCASE("setting domain") {
{
int dr = 8;
int dc = 9;
// set 1D domain
CHECK_THROWS(grid.setDomain(dr));
EXPECT_ANY_THROW(grid.setDomain(dr));
// set 2D domain
CHECK_NOTHROW(grid.setDomain(dr, dc));
EXPECT_NO_THROW(grid.setDomain(dr, dc));
grid.setDomain(dr, dc);
CHECK_EQ(grid.getDeltaCol(), double(dc) / double(c));
CHECK_EQ(grid.getDeltaRow(), double(dr) / double(r));
EXPECT_DOUBLE_EQ(grid.getDeltaCol(), double(dc) / double(c));
EXPECT_DOUBLE_EQ(grid.getDeltaRow(), double(dr) / double(r));
// set too small domain
dr = 0;
CHECK_THROWS(grid.setDomain(dr, dc));
EXPECT_ANY_THROW(grid.setDomain(dr, dc));
dr = 8;
dc = -1;
CHECK_THROWS(grid.setDomain(dr, dc));
EXPECT_ANY_THROW(grid.setDomain(dr, dc));
dr = -2;
CHECK_THROWS(grid.setDomain(dr, dc));
EXPECT_ANY_THROW(grid.setDomain(dr, dc));
}
SUBCASE("set concentration from pointer") {
{
std::vector<double> concentrations(r * c);
for (int i = 0; i < r * c; i++) {
@ -261,8 +255,8 @@ TEST_CASE("2D Grid64 non-quadratic") {
grid.setConcentrations(concentrations.data());
CHECK_EQ(grid.getConcentrations()(0, 0), 0);
CHECK_EQ(grid.getConcentrations()(0, 1), 1);
CHECK_EQ(grid.getConcentrations()(1, 0), c);
EXPECT_DOUBLE_EQ(grid.getConcentrations()(0, 0), 0);
EXPECT_DOUBLE_EQ(grid.getConcentrations()(0, 1), 1);
EXPECT_DOUBLE_EQ(grid.getConcentrations()(1, 0), c);
}
}

View File

@ -1,14 +1,16 @@
#include "TestUtils.hpp"
#include <gtest/gtest.h>
#include <stdexcept>
#include <tug/Simulation.hpp>
#include <Eigen/src/Core/Matrix.h>
#include <doctest/doctest.h>
#include <stdio.h>
#include <string>
// include the configured header file
#include <testSimulation.hpp>
#define DIFFUSION_TEST(x) TEST(Diffusion, x)
using namespace Eigen;
using namespace std;
using namespace tug;
@ -51,7 +53,7 @@ Grid64 setupSimulation(double timestep, int iterations) {
constexpr double timestep = 0.001;
constexpr double iterations = 7000;
TEST_CASE("equality to reference matrix with FTCS") {
DIFFUSION_TEST(EqualityFTCS) {
// set string from the header file
string test_path = testSimulationCSVDir;
MatrixXd reference = CSV2Eigen(test_path);
@ -69,10 +71,10 @@ TEST_CASE("equality to reference matrix with FTCS") {
sim.run();
cout << endl;
CHECK(checkSimilarity(reference, grid.getConcentrations(), 0.1) == true);
EXPECT_TRUE(checkSimilarity(reference, grid.getConcentrations(), 0.1));
}
TEST_CASE("equality to reference matrix with BTCS") {
DIFFUSION_TEST(EqualityBTCS) {
// set string from the header file
string test_path = testSimulationCSVDir;
MatrixXd reference = CSV2Eigen(test_path);
@ -89,39 +91,35 @@ TEST_CASE("equality to reference matrix with BTCS") {
sim.run();
cout << endl;
CHECK(checkSimilarityV2(reference, grid.getConcentrations(), 0.01) == true);
EXPECT_TRUE(checkSimilarityV2(reference, grid.getConcentrations(), 0.01));
}
TEST_CASE("Initialize environment") {
DIFFUSION_TEST(InitializeEnvironment) {
int rc = 12;
Grid64 grid(rc, rc);
Boundary boundary(grid);
CHECK_NOTHROW(Simulation sim(grid, boundary));
EXPECT_NO_THROW(Simulation sim(grid, boundary));
}
TEST_CASE("Simulation environment") {
DIFFUSION_TEST(SimulationEnvironment) {
int rc = 12;
Grid64 grid(rc, rc);
Boundary boundary(grid);
Simulation<double, tug::FTCS_APPROACH> sim(grid, boundary);
SUBCASE("default paremeters") { CHECK_EQ(sim.getIterations(), -1); }
EXPECT_EQ(sim.getIterations(), -1);
SUBCASE("set iterations") {
CHECK_NOTHROW(sim.setIterations(2000));
CHECK_EQ(sim.getIterations(), 2000);
CHECK_THROWS(sim.setIterations(-300));
}
EXPECT_NO_THROW(sim.setIterations(2000));
EXPECT_EQ(sim.getIterations(), 2000);
EXPECT_THROW(sim.setIterations(-300), std::invalid_argument);
SUBCASE("set timestep") {
CHECK_NOTHROW(sim.setTimestep(0.1));
CHECK_EQ(sim.getTimestep(), 0.1);
CHECK_THROWS(sim.setTimestep(-0.3));
}
EXPECT_NO_THROW(sim.setTimestep(0.1));
EXPECT_DOUBLE_EQ(sim.getTimestep(), 0.1);
EXPECT_THROW(sim.setTimestep(-0.3), std::invalid_argument);
}
TEST_CASE("Closed Boundaries - no change expected") {
DIFFUSION_TEST(ClosedBoundaries) {
constexpr std::uint32_t nrows = 5;
constexpr std::uint32_t ncols = 5;
@ -148,11 +146,10 @@ TEST_CASE("Closed Boundaries - no change expected") {
MatrixXd input_values(concentrations);
sim.run();
CHECK(checkSimilarityV2(input_values, grid.getConcentrations(), 1E-12) ==
true);
EXPECT_TRUE(checkSimilarityV2(input_values, grid.getConcentrations(), 1E-12));
}
TEST_CASE("Constant inner cell - 'absorbing' concentration") {
DIFFUSION_TEST(ConstantInnerCell) {
constexpr std::uint32_t nrows = 5;
constexpr std::uint32_t ncols = 5;
@ -176,12 +173,10 @@ TEST_CASE("Constant inner cell - 'absorbing' concentration") {
MatrixXd input_values(concentrations);
sim.run();
CHECK(grid.getConcentrations()(2, 2) == 0);
CHECK(grid.getConcentrations().sum() < input_values.sum());
EXPECT_DOUBLE_EQ(grid.getConcentrations()(2, 2), 0);
EXPECT_LT(grid.getConcentrations().sum(), input_values.sum());
const bool greater_one = (grid.getConcentrations().array() > 1.0).any();
CHECK(greater_one == false);
EXPECT_FALSE((grid.getConcentrations().array() > 1.0).any());
const bool less_zero = (grid.getConcentrations().array() < 0.0).any();
CHECK(less_zero == false);
EXPECT_FALSE((grid.getConcentrations().array() < 0.0).any());
}