diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index a08e1a689cf3041dd62b90c81630381581b83f38..61a2b661986a3b0ab2d8484bdd38779e197b28c0 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -73,6 +73,7 @@ add_executable (unit_tests test_IncDecExpressionProcessor.cpp test_INodeProcessor.cpp test_ItemType.cpp + test_LinearSolverOptions.cpp test_ListAffectationProcessor.cpp test_MathModule.cpp test_NameProcessor.cpp diff --git a/tests/test_LinearSolverOptions.cpp b/tests/test_LinearSolverOptions.cpp new file mode 100644 index 0000000000000000000000000000000000000000..494c36760d7b48c6e40c569423a100fed669d0d6 --- /dev/null +++ b/tests/test_LinearSolverOptions.cpp @@ -0,0 +1,177 @@ +#include <catch2/catch.hpp> + +#include <algebra/LinearSolverOptions.hpp> + +#include <sstream> + +// clazy:excludeall=non-pod-global-static + +TEST_CASE("LinearSolverOptions", "[algebra]") +{ + SECTION("print options") + { + SECTION("first set") + { + LinearSolverOptions options; + options.verbose() = true; + options.library() = LSLibrary::builtin; + options.method() = LSMethod::cg; + options.precond() = LSPrecond::incomplete_choleski; + options.epsilon() = 1E-3; + options.maximumIteration() = 100; + + std::stringstream os; + os << '\n' << options; + + std::stringstream expected_output; + expected_output << R"( + library: builtin + method : CG + precond: ICholeski + epsilon: )" << 1E-3 << R"( + maxiter: 100 + verbose: true +)"; + + REQUIRE(os.str() == expected_output.str()); + } + + SECTION("second set") + { + LinearSolverOptions options; + + options.verbose() = false; + options.library() = LSLibrary::petsc; + options.method() = LSMethod::gmres; + options.precond() = LSPrecond::incomplete_LU; + options.epsilon() = 1E-6; + options.maximumIteration() = 200; + + std::stringstream os; + os << '\n' << options; + + std::stringstream expected_output; + expected_output << R"( + library: PETSc + method : GMRES + precond: ILU + epsilon: )" << 1E-6 << R"( + maxiter: 200 + verbose: false +)"; + + REQUIRE(os.str() == expected_output.str()); + } + } + + SECTION("library name") + { + REQUIRE(name(LSLibrary::builtin) == "builtin"); + REQUIRE(name(LSLibrary::petsc) == "PETSc"); + REQUIRE_THROWS_WITH(name(LSLibrary::LS__end), "unexpected error: Linear system library name is not defined!"); + } + + SECTION("method name") + { + REQUIRE(name(LSMethod::cg) == "CG"); + REQUIRE(name(LSMethod::bicgstab) == "BICGStab"); + REQUIRE(name(LSMethod::bicgstab2) == "BICGStab2"); + REQUIRE(name(LSMethod::gmres) == "GMRES"); + REQUIRE(name(LSMethod::lu) == "LU"); + REQUIRE(name(LSMethod::choleski) == "Choleski"); + REQUIRE_THROWS_WITH(name(LSMethod::LS__end), "unexpected error: Linear system method name is not defined!"); + } + + SECTION("precond name") + { + REQUIRE(name(LSPrecond::none) == "none"); + REQUIRE(name(LSPrecond::diagonal) == "diagonal"); + REQUIRE(name(LSPrecond::incomplete_choleski) == "ICholeski"); + REQUIRE(name(LSPrecond::incomplete_LU) == "ILU"); + REQUIRE(name(LSPrecond::amg) == "AMG"); + REQUIRE_THROWS_WITH(name(LSPrecond::LS__end), + "unexpected error: Linear system preconditioner name is not defined!"); + } + + SECTION("library from name") + { + REQUIRE(LSLibrary::builtin == getLSEnumFromName<LSLibrary>("builtin")); + REQUIRE(LSLibrary::petsc == getLSEnumFromName<LSLibrary>("PETSc")); + + REQUIRE_THROWS_WITH(getLSEnumFromName<LSLibrary>("__invalid_lib"), + "error: could not find '__invalid_lib' associate type!"); + } + + SECTION("method from name") + { + REQUIRE(LSMethod::cg == getLSEnumFromName<LSMethod>("CG")); + REQUIRE(LSMethod::bicgstab == getLSEnumFromName<LSMethod>("BICGStab")); + REQUIRE(LSMethod::bicgstab2 == getLSEnumFromName<LSMethod>("BICGStab2")); + REQUIRE(LSMethod::lu == getLSEnumFromName<LSMethod>("LU")); + REQUIRE(LSMethod::choleski == getLSEnumFromName<LSMethod>("Choleski")); + REQUIRE(LSMethod::gmres == getLSEnumFromName<LSMethod>("GMRES")); + + REQUIRE_THROWS_WITH(getLSEnumFromName<LSMethod>("__invalid_method"), + "error: could not find '__invalid_method' associate type!"); + } + + SECTION("precond from name") + { + REQUIRE(LSPrecond::none == getLSEnumFromName<LSPrecond>("none")); + REQUIRE(LSPrecond::diagonal == getLSEnumFromName<LSPrecond>("diagonal")); + REQUIRE(LSPrecond::incomplete_choleski == getLSEnumFromName<LSPrecond>("ICholeski")); + REQUIRE(LSPrecond::incomplete_LU == getLSEnumFromName<LSPrecond>("ILU")); + + REQUIRE_THROWS_WITH(getLSEnumFromName<LSPrecond>("__invalid_precond"), + "error: could not find '__invalid_precond' associate type!"); + } + + SECTION("library list") + { + std::stringstream os; + os << '\n'; + printLSEnumListNames<LSLibrary>(os); + + const std::string library_list = R"( + - builtin + - PETSc +)"; + + REQUIRE(os.str() == library_list); + } + + SECTION("method list") + { + std::stringstream os; + os << '\n'; + printLSEnumListNames<LSMethod>(os); + + const std::string library_list = R"( + - CG + - BICGStab + - BICGStab2 + - GMRES + - LU + - Choleski +)"; + + REQUIRE(os.str() == library_list); + } + + SECTION("precond list") + { + std::stringstream os; + os << '\n'; + printLSEnumListNames<LSPrecond>(os); + + const std::string library_list = R"( + - none + - diagonal + - ICholeski + - ILU + - AMG +)"; + + REQUIRE(os.str() == library_list); + } +}