Skip to content
Snippets Groups Projects
Commit f38c5713 authored by Stéphane Del Pino's avatar Stéphane Del Pino
Browse files

Add tests for DiscreteFunctionVectorInterpoler

parent a95943c7
Branches
Tags
1 merge request!116Add tests for EmbeddedIDiscreteFunctionUtils
...@@ -53,7 +53,6 @@ DiscreteFunctionVectorInterpoler::interpolate() const ...@@ -53,7 +53,6 @@ DiscreteFunctionVectorInterpoler::interpolate() const
throw NormalError("invalid discrete function type for vector interpolation"); throw NormalError("invalid discrete function type for vector interpolation");
} }
std::shared_ptr<IDiscreteFunction> discrete_function;
switch (m_mesh->dimension()) { switch (m_mesh->dimension()) {
case 1: { case 1: {
return this->_interpolate<1>(); return this->_interpolate<1>();
...@@ -64,8 +63,10 @@ DiscreteFunctionVectorInterpoler::interpolate() const ...@@ -64,8 +63,10 @@ DiscreteFunctionVectorInterpoler::interpolate() const
case 3: { case 3: {
return this->_interpolate<3>(); return this->_interpolate<3>();
} }
// LCOV_EXCL_START
default: { default: {
throw UnexpectedError("invalid dimension"); throw UnexpectedError("invalid dimension");
} }
// LCOV_EXCL_STOP
} }
} }
...@@ -111,6 +111,7 @@ add_executable (mpi_unit_tests ...@@ -111,6 +111,7 @@ add_executable (mpi_unit_tests
test_DiscreteFunctionInterpoler.cpp test_DiscreteFunctionInterpoler.cpp
test_DiscreteFunctionP0.cpp test_DiscreteFunctionP0.cpp
test_DiscreteFunctionP0Vector.cpp test_DiscreteFunctionP0Vector.cpp
test_DiscreteFunctionVectorInterpoler.cpp
test_InterpolateItemArray.cpp test_InterpolateItemArray.cpp
test_InterpolateItemValue.cpp test_InterpolateItemValue.cpp
test_ItemArray.cpp test_ItemArray.cpp
......
#include <catch2/catch_test_macros.hpp>
#include <catch2/matchers/catch_matchers_all.hpp>
#include <language/ast/ASTBuilder.hpp>
#include <language/ast/ASTModulesImporter.hpp>
#include <language/ast/ASTNodeDataTypeBuilder.hpp>
#include <language/ast/ASTNodeExpressionBuilder.hpp>
#include <language/ast/ASTNodeFunctionEvaluationExpressionBuilder.hpp>
#include <language/ast/ASTNodeFunctionExpressionBuilder.hpp>
#include <language/ast/ASTNodeTypeCleaner.hpp>
#include <language/ast/ASTSymbolTableBuilder.hpp>
#include <language/utils/PugsFunctionAdapter.hpp>
#include <language/utils/SymbolTable.hpp>
#include <MeshDataBaseForTests.hpp>
#include <mesh/Connectivity.hpp>
#include <mesh/Mesh.hpp>
#include <mesh/MeshData.hpp>
#include <mesh/MeshDataManager.hpp>
#include <scheme/DiscreteFunctionDescriptorP0Vector.hpp>
#include <scheme/DiscreteFunctionP0Vector.hpp>
#include <scheme/DiscreteFunctionVectorInterpoler.hpp>
#include <pegtl/string_input.hpp>
// clazy:excludeall=non-pod-global-static
TEST_CASE("DiscreteFunctionVectorInterpoler", "[scheme]")
{
auto same_cell_value = [](const CellValue<const double>& fi, const size_t i, const auto& f) -> bool {
for (CellId cell_id = 0; cell_id < fi.numberOfItems(); ++cell_id) {
if (fi[cell_id] != f[cell_id][i]) {
return false;
}
}
return true;
};
auto register_function = [](const TAO_PEGTL_NAMESPACE::position& position,
const std::shared_ptr<SymbolTable>& symbol_table, const std::string& name,
std::vector<FunctionSymbolId>& function_id_list) {
auto [i_symbol, found] = symbol_table->find(name, position);
REQUIRE(found);
REQUIRE(i_symbol->attributes().dataType() == ASTNodeDataType::function_t);
FunctionSymbolId function_symbol_id(std::get<uint64_t>(i_symbol->attributes().value()), symbol_table);
function_id_list.push_back(function_symbol_id);
};
SECTION("1D")
{
constexpr size_t Dimension = 1;
const auto& mesh_1d = MeshDataBaseForTests::get().cartesianMesh1D();
auto xj = MeshDataManager::instance().getMeshData(*mesh_1d).xj();
std::string_view data = R"(
import math;
let B_scalar_non_linear_1d: R^1 -> B, x -> (exp(2 * x[0]) + 3 > 4);
let N_scalar_non_linear_1d: R^1 -> N, x -> floor(3 * x[0] * x[0] + 2);
let Z_scalar_non_linear_1d: R^1 -> Z, x -> floor(exp(2 * x[0]) - 1);
let R_scalar_non_linear_1d: R^1 -> R, x -> 2 * exp(x[0]) + 3;
)";
TAO_PEGTL_NAMESPACE::string_input input{data, "test.pgs"};
auto ast = ASTBuilder::build(input);
ASTModulesImporter{*ast};
ASTNodeTypeCleaner<language::import_instruction>{*ast};
ASTSymbolTableBuilder{*ast};
ASTNodeDataTypeBuilder{*ast};
ASTNodeTypeCleaner<language::var_declaration>{*ast};
ASTNodeTypeCleaner<language::fct_declaration>{*ast};
ASTNodeExpressionBuilder{*ast};
TAO_PEGTL_NAMESPACE::position position{TAO_PEGTL_NAMESPACE::internal::iterator{"fixture"}, "fixture"};
position.byte = data.size(); // ensure that variables are declared at this point
std::shared_ptr<SymbolTable> symbol_table = ast->m_symbol_table;
std::vector<FunctionSymbolId> function_id_list;
register_function(position, symbol_table, "B_scalar_non_linear_1d", function_id_list);
register_function(position, symbol_table, "N_scalar_non_linear_1d", function_id_list);
register_function(position, symbol_table, "Z_scalar_non_linear_1d", function_id_list);
register_function(position, symbol_table, "R_scalar_non_linear_1d", function_id_list);
DiscreteFunctionVectorInterpoler interpoler(mesh_1d, std::make_shared<DiscreteFunctionDescriptorP0Vector>(),
function_id_list);
std::shared_ptr discrete_function = interpoler.interpolate();
size_t i = 0;
{
CellValue<double> cell_value{mesh_1d->connectivity()};
parallel_for(
cell_value.numberOfItems(), PUGS_LAMBDA(const CellId cell_id) {
const TinyVector<Dimension>& x = xj[cell_id];
cell_value[cell_id] = std::exp(2 * x[0]) + 3 > 4;
});
REQUIRE(same_cell_value(cell_value, i++,
dynamic_cast<const DiscreteFunctionP0Vector<Dimension, double>&>(*discrete_function)));
}
{
CellValue<double> cell_value{mesh_1d->connectivity()};
parallel_for(
cell_value.numberOfItems(), PUGS_LAMBDA(const CellId cell_id) {
const TinyVector<Dimension>& x = xj[cell_id];
cell_value[cell_id] = std::floor(3 * x[0] * x[0] + 2);
});
REQUIRE(same_cell_value(cell_value, i++,
dynamic_cast<const DiscreteFunctionP0Vector<Dimension, double>&>(*discrete_function)));
}
{
CellValue<double> cell_value{mesh_1d->connectivity()};
parallel_for(
cell_value.numberOfItems(), PUGS_LAMBDA(const CellId cell_id) {
const TinyVector<Dimension>& x = xj[cell_id];
cell_value[cell_id] = std::floor(std::exp(2 * x[0]) - 1);
});
REQUIRE(same_cell_value(cell_value, i++,
dynamic_cast<const DiscreteFunctionP0Vector<Dimension, double>&>(*discrete_function)));
}
{
CellValue<double> cell_value{mesh_1d->connectivity()};
parallel_for(
cell_value.numberOfItems(), PUGS_LAMBDA(const CellId cell_id) {
const TinyVector<Dimension>& x = xj[cell_id];
cell_value[cell_id] = 2 * std::exp(x[0]) + 3;
});
REQUIRE(same_cell_value(cell_value, i++,
dynamic_cast<const DiscreteFunctionP0Vector<Dimension, double>&>(*discrete_function)));
}
REQUIRE(i == function_id_list.size());
}
SECTION("2D")
{
constexpr size_t Dimension = 2;
const auto& mesh_2d = MeshDataBaseForTests::get().cartesianMesh2D();
auto xj = MeshDataManager::instance().getMeshData(*mesh_2d).xj();
std::string_view data = R"(
import math;
let B_scalar_non_linear_2d: R^2 -> B, x -> (exp(2 * x[0]) + 3 > 4);
let N_scalar_non_linear_2d: R^2 -> N, x -> floor(3 * (x[0] * x[1]) * (x[0] * x[1]) + 2);
let Z_scalar_non_linear_2d: R^2 -> Z, x -> floor(exp(2 * x[1]) - 1);
let R_scalar_non_linear_2d: R^2 -> R, x -> 2 * exp(x[0] + x[1]) + 3;
)";
TAO_PEGTL_NAMESPACE::string_input input{data, "test.pgs"};
auto ast = ASTBuilder::build(input);
ASTModulesImporter{*ast};
ASTNodeTypeCleaner<language::import_instruction>{*ast};
ASTSymbolTableBuilder{*ast};
ASTNodeDataTypeBuilder{*ast};
ASTNodeTypeCleaner<language::var_declaration>{*ast};
ASTNodeTypeCleaner<language::fct_declaration>{*ast};
ASTNodeExpressionBuilder{*ast};
TAO_PEGTL_NAMESPACE::position position{TAO_PEGTL_NAMESPACE::internal::iterator{"fixture"}, "fixture"};
position.byte = data.size(); // ensure that variables are declared at this point
std::shared_ptr<SymbolTable> symbol_table = ast->m_symbol_table;
std::vector<FunctionSymbolId> function_id_list;
register_function(position, symbol_table, "B_scalar_non_linear_2d", function_id_list);
register_function(position, symbol_table, "N_scalar_non_linear_2d", function_id_list);
register_function(position, symbol_table, "Z_scalar_non_linear_2d", function_id_list);
register_function(position, symbol_table, "R_scalar_non_linear_2d", function_id_list);
DiscreteFunctionVectorInterpoler interpoler(mesh_2d, std::make_shared<DiscreteFunctionDescriptorP0Vector>(),
function_id_list);
std::shared_ptr discrete_function = interpoler.interpolate();
size_t i = 0;
{
CellValue<double> cell_value{mesh_2d->connectivity()};
parallel_for(
cell_value.numberOfItems(), PUGS_LAMBDA(const CellId cell_id) {
const TinyVector<Dimension>& x = xj[cell_id];
cell_value[cell_id] = std::exp(2 * x[0]) + 3 > 4;
});
REQUIRE(same_cell_value(cell_value, i++,
dynamic_cast<const DiscreteFunctionP0Vector<Dimension, double>&>(*discrete_function)));
}
{
CellValue<double> cell_value{mesh_2d->connectivity()};
parallel_for(
cell_value.numberOfItems(), PUGS_LAMBDA(const CellId cell_id) {
const TinyVector<Dimension>& x = xj[cell_id];
cell_value[cell_id] = std::floor(3 * (x[0] * x[1]) * (x[0] * x[1]) + 2);
});
REQUIRE(same_cell_value(cell_value, i++,
dynamic_cast<const DiscreteFunctionP0Vector<Dimension, double>&>(*discrete_function)));
}
{
CellValue<double> cell_value{mesh_2d->connectivity()};
parallel_for(
cell_value.numberOfItems(), PUGS_LAMBDA(const CellId cell_id) {
const TinyVector<Dimension>& x = xj[cell_id];
cell_value[cell_id] = std::floor(std::exp(2 * x[1]) - 1);
});
REQUIRE(same_cell_value(cell_value, i++,
dynamic_cast<const DiscreteFunctionP0Vector<Dimension, double>&>(*discrete_function)));
}
{
CellValue<double> cell_value{mesh_2d->connectivity()};
parallel_for(
cell_value.numberOfItems(), PUGS_LAMBDA(const CellId cell_id) {
const TinyVector<Dimension>& x = xj[cell_id];
cell_value[cell_id] = 2 * std::exp(x[0] + x[1]) + 3;
});
REQUIRE(same_cell_value(cell_value, i++,
dynamic_cast<const DiscreteFunctionP0Vector<Dimension, double>&>(*discrete_function)));
}
REQUIRE(i == function_id_list.size());
}
SECTION("3D")
{
constexpr size_t Dimension = 3;
const auto& mesh_3d = MeshDataBaseForTests::get().cartesianMesh3D();
auto xj = MeshDataManager::instance().getMeshData(*mesh_3d).xj();
std::string_view data = R"(
import math;
let B_scalar_non_linear_3d: R^3 -> B, x -> (exp(2 * x[0] + x[2]) + 3 > 4);
let N_scalar_non_linear_3d: R^3 -> N, x -> floor(3 * (x[0] * x[1]) * (x[0] * x[1]) + 2);
let Z_scalar_non_linear_3d: R^3 -> Z, x -> floor(exp(2 * x[1]) - x[2]);
let R_scalar_non_linear_3d: R^3 -> R, x -> 2 * exp(x[0] + x[1]) + 3 * x[2];
)";
TAO_PEGTL_NAMESPACE::string_input input{data, "test.pgs"};
auto ast = ASTBuilder::build(input);
ASTModulesImporter{*ast};
ASTNodeTypeCleaner<language::import_instruction>{*ast};
ASTSymbolTableBuilder{*ast};
ASTNodeDataTypeBuilder{*ast};
ASTNodeTypeCleaner<language::var_declaration>{*ast};
ASTNodeTypeCleaner<language::fct_declaration>{*ast};
ASTNodeExpressionBuilder{*ast};
TAO_PEGTL_NAMESPACE::position position{TAO_PEGTL_NAMESPACE::internal::iterator{"fixture"}, "fixture"};
position.byte = data.size(); // ensure that variables are declared at this point
std::shared_ptr<SymbolTable> symbol_table = ast->m_symbol_table;
std::vector<FunctionSymbolId> function_id_list;
register_function(position, symbol_table, "B_scalar_non_linear_3d", function_id_list);
register_function(position, symbol_table, "N_scalar_non_linear_3d", function_id_list);
register_function(position, symbol_table, "Z_scalar_non_linear_3d", function_id_list);
register_function(position, symbol_table, "R_scalar_non_linear_3d", function_id_list);
DiscreteFunctionVectorInterpoler interpoler(mesh_3d, std::make_shared<DiscreteFunctionDescriptorP0Vector>(),
function_id_list);
std::shared_ptr discrete_function = interpoler.interpolate();
size_t i = 0;
{
CellValue<double> cell_value{mesh_3d->connectivity()};
parallel_for(
cell_value.numberOfItems(), PUGS_LAMBDA(const CellId cell_id) {
const TinyVector<Dimension>& x = xj[cell_id];
cell_value[cell_id] = std::exp(2 * x[0] + x[2]) + 3 > 4;
});
REQUIRE(same_cell_value(cell_value, i++,
dynamic_cast<const DiscreteFunctionP0Vector<Dimension, double>&>(*discrete_function)));
}
{
CellValue<double> cell_value{mesh_3d->connectivity()};
parallel_for(
cell_value.numberOfItems(), PUGS_LAMBDA(const CellId cell_id) {
const TinyVector<Dimension>& x = xj[cell_id];
cell_value[cell_id] = std::floor(3 * (x[0] * x[1]) * (x[0] * x[1]) + 2);
});
REQUIRE(same_cell_value(cell_value, i++,
dynamic_cast<const DiscreteFunctionP0Vector<Dimension, double>&>(*discrete_function)));
}
{
CellValue<double> cell_value{mesh_3d->connectivity()};
parallel_for(
cell_value.numberOfItems(), PUGS_LAMBDA(const CellId cell_id) {
const TinyVector<Dimension>& x = xj[cell_id];
cell_value[cell_id] = std::floor(std::exp(2 * x[1]) - x[2]);
});
REQUIRE(same_cell_value(cell_value, i++,
dynamic_cast<const DiscreteFunctionP0Vector<Dimension, double>&>(*discrete_function)));
}
{
CellValue<double> cell_value{mesh_3d->connectivity()};
parallel_for(
cell_value.numberOfItems(), PUGS_LAMBDA(const CellId cell_id) {
const TinyVector<Dimension>& x = xj[cell_id];
cell_value[cell_id] = 2 * std::exp(x[0] + x[1]) + 3 * x[2];
});
REQUIRE(same_cell_value(cell_value, i++,
dynamic_cast<const DiscreteFunctionP0Vector<Dimension, double>&>(*discrete_function)));
}
REQUIRE(i == function_id_list.size());
}
SECTION("errors")
{
const auto& mesh_3d = MeshDataBaseForTests::get().cartesianMesh3D();
auto xj = MeshDataManager::instance().getMeshData(*mesh_3d).xj();
std::string_view data = R"(
import math;
let B_scalar_non_linear_2d: R^2 -> B, x -> (exp(2 * x[0] + x[1]) + 3 > 4);
let N_scalar_non_linear_1d: R^1 -> N, x -> floor(3 * x[0] * x[0] + 2);
let Z_scalar_non_linear_3d: R^3 -> Z, x -> floor(exp(2 * x[1]) - x[2]);
let R_scalar_non_linear_3d: R^3 -> R, x -> 2 * exp(x[0] + x[1]) + 3 * x[2];
let R2_scalar_non_linear_3d: R^3 -> R^2, x -> (2 * exp(x[0] + x[1]) + 3 * x[2], x[0] - x[1]);
)";
TAO_PEGTL_NAMESPACE::string_input input{data, "test.pgs"};
auto ast = ASTBuilder::build(input);
ASTModulesImporter{*ast};
ASTNodeTypeCleaner<language::import_instruction>{*ast};
ASTSymbolTableBuilder{*ast};
ASTNodeDataTypeBuilder{*ast};
ASTNodeTypeCleaner<language::var_declaration>{*ast};
ASTNodeTypeCleaner<language::fct_declaration>{*ast};
ASTNodeExpressionBuilder{*ast};
TAO_PEGTL_NAMESPACE::position position{TAO_PEGTL_NAMESPACE::internal::iterator{"fixture"}, "fixture"};
position.byte = data.size(); // ensure that variables are declared at this point
std::shared_ptr<SymbolTable> symbol_table = ast->m_symbol_table;
SECTION("invalid function type")
{
std::vector<FunctionSymbolId> function_id_list;
register_function(position, symbol_table, "B_scalar_non_linear_2d", function_id_list);
register_function(position, symbol_table, "N_scalar_non_linear_1d", function_id_list);
register_function(position, symbol_table, "Z_scalar_non_linear_3d", function_id_list);
register_function(position, symbol_table, "R_scalar_non_linear_3d", function_id_list);
DiscreteFunctionVectorInterpoler interpoler(mesh_3d, std::make_shared<DiscreteFunctionDescriptorP0Vector>(),
function_id_list);
const std::string error_msg = R"(error: invalid function type
note: expecting R^3 -> R
note: provided function B_scalar_non_linear_2d: R^2 -> B)";
REQUIRE_THROWS_WITH(interpoler.interpolate(), error_msg);
}
SECTION("invalid value type")
{
std::vector<FunctionSymbolId> function_id_list;
register_function(position, symbol_table, "Z_scalar_non_linear_3d", function_id_list);
register_function(position, symbol_table, "R_scalar_non_linear_3d", function_id_list);
register_function(position, symbol_table, "R2_scalar_non_linear_3d", function_id_list);
DiscreteFunctionVectorInterpoler interpoler(mesh_3d, std::make_shared<DiscreteFunctionDescriptorP0Vector>(),
function_id_list);
const std::string error_msg = R"(error: vector functions require scalar value type.
Invalid interpolation value type: R^2)";
REQUIRE_THROWS_WITH(interpoler.interpolate(), error_msg);
}
SECTION("invalid discrete function type")
{
const std::string error_msg = "error: invalid discrete function type for vector interpolation";
DiscreteFunctionVectorInterpoler interpoler{mesh_3d, std::make_shared<DiscreteFunctionDescriptorP0>(), {}};
REQUIRE_THROWS_WITH(interpoler.interpolate(), error_msg);
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment