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
No related branches found
No related tags found
1 merge request!116Add tests for EmbeddedIDiscreteFunctionUtils
......@@ -53,7 +53,6 @@ DiscreteFunctionVectorInterpoler::interpolate() const
throw NormalError("invalid discrete function type for vector interpolation");
}
std::shared_ptr<IDiscreteFunction> discrete_function;
switch (m_mesh->dimension()) {
case 1: {
return this->_interpolate<1>();
......@@ -64,8 +63,10 @@ DiscreteFunctionVectorInterpoler::interpolate() const
case 3: {
return this->_interpolate<3>();
}
// LCOV_EXCL_START
default: {
throw UnexpectedError("invalid dimension");
}
// LCOV_EXCL_STOP
}
}
......@@ -111,6 +111,7 @@ add_executable (mpi_unit_tests
test_DiscreteFunctionInterpoler.cpp
test_DiscreteFunctionP0.cpp
test_DiscreteFunctionP0Vector.cpp
test_DiscreteFunctionVectorInterpoler.cpp
test_InterpolateItemArray.cpp
test_InterpolateItemValue.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