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

Add tests for VariableBCDescriptor checkpointing

parent d3bee0b8
Branches
No related tags found
1 merge request!199Integrate checkpointing
......@@ -183,6 +183,7 @@ if(PUGS_HAS_HDF5)
test_checkpointing_SubItemArrayPerItemVariant.cpp
test_checkpointing_SubItemValuePerItemVariant.cpp
test_checkpointing_Table.cpp
test_checkpointing_VariableBCDescriptor.cpp
)
endif(PUGS_HAS_HDF5)
......
......@@ -217,8 +217,6 @@ TEST_CASE("checkpointing_INamedDiscreteData", "[utils/checkpointing]")
using R2x2 = TinyMatrix<2>;
using R3x3 = TinyMatrix<3>;
NamedDiscreteFunction ndf;
HighFive::Group checkpoint_group = file.createGroup("checkpoint");
HighFive::Group symbol_table_group = checkpoint_group.createGroup("symbol_table");
......
#include <catch2/catch_test_macros.hpp>
#include <catch2/matchers/catch_matchers_all.hpp>
#include <utils/Messenger.hpp>
#include <language/utils/DataHandler.hpp>
#include <language/utils/EmbeddedData.hpp>
#include <mesh/Mesh.hpp>
#include <mesh/NamedBoundaryDescriptor.hpp>
#include <mesh/NumberedBoundaryDescriptor.hpp>
#include <scheme/DiscreteFunctionVariant.hpp>
#include <scheme/OutflowBoundaryConditionDescriptor.hpp>
#include <scheme/SymmetryBoundaryConditionDescriptor.hpp>
#include <scheme/VariableBCDescriptor.hpp>
#include <utils/GlobalVariableManager.hpp>
#include <utils/checkpointing/ReadVariableBCDescriptor.hpp>
#include <utils/checkpointing/ResumingData.hpp>
#include <utils/checkpointing/WriteVariableBCDescriptor.hpp>
#include <MeshDataBaseForTests.hpp>
#include <checkpointing_Connectivity_utilities.hpp>
#include <checkpointing_Mesh_utilities.hpp>
#include <filesystem>
// clazy:excludeall=non-pod-global-static
namespace test_only
{
template <typename DataType>
PUGS_INLINE void
VariableBCDescriptor_check_is_same_data(const DiscreteFunctionP0<DataType>& reference, const EmbeddedData& e_read_data)
{
auto same_value = [](const auto& a, const auto& b) -> bool {
bool same = true;
for (size_t i = 0; i < a.size(); ++i) {
same &= (a[i] == b[i]);
}
return parallel::allReduceAnd(same);
};
REQUIRE_NOTHROW(dynamic_cast<const DataHandler<const VariableBCDescriptor>&>(e_read_data.get()));
const VariableBCDescriptor& var_bc_desc_discrete_data =
*dynamic_cast<const DataHandler<const VariableBCDescriptor>&>(e_read_data.get()).data_ptr();
using DiscreteFunctionT = DiscreteFunctionP0<const DataType>;
DiscreteFunctionT read_data = var_bc_desc_discrete_data.discreteFunctionVariant()->get<DiscreteFunctionT>();
REQUIRE(test_only::isSameMesh(read_data.meshVariant(), reference.meshVariant()));
REQUIRE(same_value(reference.cellValues().arrayView(), read_data.cellValues().arrayView()));
}
PUGS_INLINE void
VariableBCDescriptor_check_is_bc_list(
const std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>>& reference_bc_list,
const EmbeddedData& e_read_data)
{
REQUIRE_NOTHROW(dynamic_cast<const DataHandler<const VariableBCDescriptor>&>(e_read_data.get()));
const VariableBCDescriptor& var_bc_desc_discrete_data =
*dynamic_cast<const DataHandler<const VariableBCDescriptor>&>(e_read_data.get()).data_ptr();
auto read_bc_list = var_bc_desc_discrete_data.bcDescriptorList();
REQUIRE(read_bc_list.size() == reference_bc_list.size());
for (size_t i = 0; i < read_bc_list.size(); ++i) {
const auto reference_bc = reference_bc_list[i];
const auto read_bc = read_bc_list[i];
REQUIRE(read_bc->type() == reference_bc->type());
REQUIRE(read_bc->boundaryDescriptor().type() == reference_bc->boundaryDescriptor().type());
switch (read_bc->boundaryDescriptor().type()) {
case IBoundaryDescriptor::Type::named: {
const NamedBoundaryDescriptor& ref_named_bc =
dynamic_cast<const NamedBoundaryDescriptor&>(reference_bc->boundaryDescriptor());
const NamedBoundaryDescriptor& read_named_bc =
dynamic_cast<const NamedBoundaryDescriptor&>(read_bc->boundaryDescriptor());
REQUIRE(ref_named_bc.name() == read_named_bc.name());
break;
}
case IBoundaryDescriptor::Type::numbered: {
const NumberedBoundaryDescriptor& ref_numbered_bc =
dynamic_cast<const NumberedBoundaryDescriptor&>(reference_bc->boundaryDescriptor());
const NumberedBoundaryDescriptor& read_numbered_bc =
dynamic_cast<const NumberedBoundaryDescriptor&>(read_bc->boundaryDescriptor());
REQUIRE(ref_numbered_bc.number() == read_numbered_bc.number());
break;
}
}
}
}
} // namespace test_only
TEST_CASE("checkpointing_VariableBCDescriptor", "[utils/checkpointing]")
{
std::string tmp_dirname;
{
{
if (parallel::rank() == 0) {
tmp_dirname = [&]() -> std::string {
std::string temp_filename = std::filesystem::temp_directory_path() / "pugs_checkpointing_XXXXXX";
return std::string{mkdtemp(&temp_filename[0])};
}();
}
parallel::broadcast(tmp_dirname, 0);
}
std::filesystem::path path = tmp_dirname;
const std::string filename = path / "checkpoint.h5";
HighFive::FileAccessProps fapl;
fapl.add(HighFive::MPIOFileAccess{MPI_COMM_WORLD, MPI_INFO_NULL});
fapl.add(HighFive::MPIOCollectiveMetadata{});
HighFive::File file = HighFive::File(filename, HighFive::File::Truncate, fapl);
const size_t initial_connectivity_id = GlobalVariableManager::instance().getConnectivityId();
const size_t initial_mesh_id = GlobalVariableManager::instance().getMeshId();
SECTION("Mesh")
{
using R2 = TinyVector<2>;
using R3 = TinyVector<3>;
HighFive::Group checkpoint_group = file.createGroup("checkpoint");
HighFive::Group symbol_table_group = checkpoint_group.createGroup("symbol_table");
auto mesh_1d = MeshDataBaseForTests::get().unordered1DMesh()->get<Mesh<1>>();
DiscreteFunctionP0<R2> df_R2_1d{mesh_1d};
for (CellId cell_id = 0; cell_id < mesh_1d->numberOfCells(); ++cell_id) {
df_R2_1d[cell_id] = R2{std::rand() / (1. * RAND_MAX / mesh_1d->numberOfCells()),
std::rand() / (1. * RAND_MAX / mesh_1d->numberOfCells())};
}
std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>> bc_1d =
{std::make_shared<SymmetryBoundaryConditionDescriptor>(std::make_shared<NamedBoundaryDescriptor>("XMIN")),
std::make_shared<OutflowBoundaryConditionDescriptor>(std::make_shared<NamedBoundaryDescriptor>("XMAX"))};
auto mesh_2d = MeshDataBaseForTests::get().hybrid2DMesh()->get<Mesh<2>>();
DiscreteFunctionP0<R3> df_R3_2d{mesh_2d};
for (CellId cell_id = 0; cell_id < mesh_2d->numberOfCells(); ++cell_id) {
df_R3_2d[cell_id] = R3{std::rand() / (1. * RAND_MAX / mesh_2d->numberOfCells()),
std::rand() / (1. * RAND_MAX / mesh_2d->numberOfCells()),
std::rand() / (1. * RAND_MAX / mesh_2d->numberOfCells())};
}
std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>> bc_2d =
{std::make_shared<SymmetryBoundaryConditionDescriptor>(std::make_shared<NamedBoundaryDescriptor>("XMIN")),
std::make_shared<OutflowBoundaryConditionDescriptor>(std::make_shared<NamedBoundaryDescriptor>("XMAX")),
std::make_shared<SymmetryBoundaryConditionDescriptor>(std::make_shared<NamedBoundaryDescriptor>("YMIN")),
std::make_shared<SymmetryBoundaryConditionDescriptor>(std::make_shared<NamedBoundaryDescriptor>("YMAX"))};
auto mesh_3d = MeshDataBaseForTests::get().hybrid3DMesh()->get<Mesh<3>>();
DiscreteFunctionP0<R3> df_R3_3d{mesh_3d};
for (CellId cell_id = 0; cell_id < mesh_3d->numberOfCells(); ++cell_id) {
df_R3_3d[cell_id] = R3{std::rand() / (1. * RAND_MAX / mesh_3d->numberOfCells()),
std::rand() / (1. * RAND_MAX / mesh_3d->numberOfCells()),
std::rand() / (1. * RAND_MAX / mesh_3d->numberOfCells())};
}
std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>> bc_3d =
{std::make_shared<SymmetryBoundaryConditionDescriptor>(std::make_shared<NamedBoundaryDescriptor>("XMIN")),
std::make_shared<OutflowBoundaryConditionDescriptor>(std::make_shared<NamedBoundaryDescriptor>("XMAX")),
std::make_shared<SymmetryBoundaryConditionDescriptor>(std::make_shared<NamedBoundaryDescriptor>("YMIN")),
std::make_shared<SymmetryBoundaryConditionDescriptor>(std::make_shared<NamedBoundaryDescriptor>("YMAX")),
std::make_shared<SymmetryBoundaryConditionDescriptor>(std::make_shared<NamedBoundaryDescriptor>("ZMIN")),
std::make_shared<SymmetryBoundaryConditionDescriptor>(std::make_shared<NamedBoundaryDescriptor>("ZMAX"))};
{ // Write
using DataHandlerT = DataHandler<const VariableBCDescriptor>;
auto new_mesh_1d_v = test_only::duplicateMesh(std::make_shared<MeshVariant>(mesh_1d));
auto new_mesh_1d = new_mesh_1d_v->get<const Mesh<1>>();
const auto& new_connectivity_1d = new_mesh_1d->connectivity();
DiscreteFunctionP0<const R2> df_R2_1d_new{new_mesh_1d_v,
CellValue<const R2>{new_connectivity_1d,
df_R2_1d.cellValues().arrayView()}};
std::shared_ptr<const VariableBCDescriptor> var_bc_desc_1d =
std::make_shared<VariableBCDescriptor>(std::make_shared<const DiscreteFunctionVariant>(df_R2_1d_new), bc_1d);
checkpointing::writeVariableBCDescriptor("var_bc_desc_1d",
EmbeddedData{std::make_shared<DataHandlerT>(var_bc_desc_1d)}, file,
checkpoint_group, symbol_table_group);
auto new_mesh_2d_v = test_only::duplicateMesh(std::make_shared<MeshVariant>(mesh_2d));
auto new_mesh_2d = new_mesh_2d_v->get<const Mesh<2>>();
const auto& new_connectivity_2d = new_mesh_2d->connectivity();
DiscreteFunctionP0<const R3> df_R3_2d_new{new_mesh_2d_v,
CellValue<const R3>{new_connectivity_2d,
df_R3_2d.cellValues().arrayView()}};
std::shared_ptr<const VariableBCDescriptor> var_bc_desc_2d =
std::make_shared<VariableBCDescriptor>(std::make_shared<const DiscreteFunctionVariant>(df_R3_2d_new), bc_2d);
checkpointing::writeVariableBCDescriptor("var_bc_desc_2d",
EmbeddedData{std::make_shared<DataHandlerT>(var_bc_desc_2d)}, file,
checkpoint_group, symbol_table_group);
auto new_mesh_3d_v = test_only::duplicateMesh(std::make_shared<MeshVariant>(mesh_3d));
auto new_mesh_3d = new_mesh_3d_v->get<const Mesh<3>>();
const auto& new_connectivity_3d = new_mesh_3d->connectivity();
DiscreteFunctionP0<const R3> df_R3_3d_new{new_mesh_3d, CellValue<const R3>{new_connectivity_3d,
df_R3_3d.cellValues().arrayView()}};
std::shared_ptr<const VariableBCDescriptor> var_bc_desc_3d =
std::make_shared<VariableBCDescriptor>(std::make_shared<const DiscreteFunctionVariant>(df_R3_3d_new), bc_3d);
checkpointing::writeVariableBCDescriptor("var_bc_desc_3d",
EmbeddedData{std::make_shared<DataHandlerT>(var_bc_desc_3d)}, file,
checkpoint_group, symbol_table_group);
HighFive::Group global_variables_group = checkpoint_group.createGroup("singleton/global_variables");
global_variables_group.createAttribute("connectivity_id",
GlobalVariableManager::instance().getConnectivityId());
global_variables_group.createAttribute("mesh_id", GlobalVariableManager::instance().getMeshId());
}
// reset to reuse after resuming
GlobalVariableManager::instance().setConnectivityId(initial_connectivity_id);
GlobalVariableManager::instance().setMeshId(initial_mesh_id);
file.flush();
checkpointing::ResumingData::create();
checkpointing::ResumingData::instance().readData(checkpoint_group, nullptr);
GlobalVariableManager::instance().setConnectivityId(initial_connectivity_id);
GlobalVariableManager::instance().setMeshId(initial_mesh_id);
{ // Read
auto e_var_bc_desc_1d = checkpointing::readVariableBCDescriptor("var_bc_desc_1d", symbol_table_group);
test_only::VariableBCDescriptor_check_is_bc_list(bc_1d, e_var_bc_desc_1d);
test_only::VariableBCDescriptor_check_is_same_data(df_R2_1d, e_var_bc_desc_1d);
auto e_var_bc_desc_2d = checkpointing::readVariableBCDescriptor("var_bc_desc_2d", symbol_table_group);
test_only::VariableBCDescriptor_check_is_bc_list(bc_2d, e_var_bc_desc_2d);
test_only::VariableBCDescriptor_check_is_same_data(df_R3_2d, e_var_bc_desc_2d);
auto e_var_bc_desc_3d = checkpointing::readVariableBCDescriptor("var_bc_desc_3d", symbol_table_group);
test_only::VariableBCDescriptor_check_is_bc_list(bc_3d, e_var_bc_desc_3d);
test_only::VariableBCDescriptor_check_is_same_data(df_R3_3d, e_var_bc_desc_3d);
}
checkpointing::ResumingData::destroy();
}
}
parallel::barrier();
if (parallel::rank() == 0) {
std::filesystem::remove_all(std::filesystem::path{tmp_dirname});
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment