diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index d83622ee1297dad1b7093a831a93aedb47450284..9d2b66f1e41d8d73dfabceffe4e0b56fea2b5fb9 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -174,6 +174,7 @@ if(PUGS_HAS_HDF5) test_checkpointing_IQuadratureDescriptor.cpp test_checkpointing_IDiscreteFunctionDescriptor.cpp test_checkpointing_IInterfaceDescriptor.cpp + test_checkpointing_INamedDiscreteData.cpp test_checkpointing_ItemType.cpp test_checkpointing_IWriter.cpp test_checkpointing_IZoneDescriptor.cpp diff --git a/tests/checkpointing_Connectivity_utilities.hpp b/tests/checkpointing_Connectivity_utilities.hpp index a107ed78f54a8ee814b9e3085d286892df777aea..c71f4ed629f9e2e21a5d593d777609c05bce4e5a 100644 --- a/tests/checkpointing_Connectivity_utilities.hpp +++ b/tests/checkpointing_Connectivity_utilities.hpp @@ -187,6 +187,47 @@ isSameConnectivity(const Connectivity<Dimension>& connectivity, const Connectivi return same; } +PUGS_INLINE bool +isSameConnectivity(const IConnectivity& i_connectivity, const IConnectivity& read_i_connectivity) +{ + if (i_connectivity.dimension() != read_i_connectivity.dimension()) { + return false; + } else { + switch (i_connectivity.dimension()) { + case 1: { + constexpr size_t Dimension = 1; + + const Connectivity<Dimension>& connectivity = dynamic_cast<const Connectivity<Dimension>&>(i_connectivity); + const Connectivity<Dimension>& read_connectivity = + dynamic_cast<const Connectivity<Dimension>&>(read_i_connectivity); + + return isSameConnectivity(connectivity, read_connectivity); + } + case 2: { + constexpr size_t Dimension = 2; + + const Connectivity<Dimension>& connectivity = dynamic_cast<const Connectivity<Dimension>&>(i_connectivity); + const Connectivity<Dimension>& read_connectivity = + dynamic_cast<const Connectivity<Dimension>&>(read_i_connectivity); + + return isSameConnectivity(connectivity, read_connectivity); + } + case 3: { + constexpr size_t Dimension = 3; + + const Connectivity<Dimension>& connectivity = dynamic_cast<const Connectivity<Dimension>&>(i_connectivity); + const Connectivity<Dimension>& read_connectivity = + dynamic_cast<const Connectivity<Dimension>&>(read_i_connectivity); + + return isSameConnectivity(connectivity, read_connectivity); + } + default: { + return false; + } + } + } +} + } // namespace test_only #endif // CHECKPOINTING_CONNECTIVITY_UTILITIES_HPP diff --git a/tests/test_checkpointing_INamedDiscreteData.cpp b/tests/test_checkpointing_INamedDiscreteData.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d11e29dca2f4d475f8b8a14a8a2e6e3696d961ce --- /dev/null +++ b/tests/test_checkpointing_INamedDiscreteData.cpp @@ -0,0 +1,555 @@ +#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/ItemArrayVariant.hpp> +#include <mesh/ItemValueVariant.hpp> +#include <mesh/Mesh.hpp> +#include <output/INamedDiscreteData.hpp> +#include <output/NamedDiscreteFunction.hpp> +#include <output/NamedItemArrayVariant.hpp> +#include <output/NamedItemValueVariant.hpp> +#include <scheme/DiscreteFunctionVariant.hpp> +#include <utils/GlobalVariableManager.hpp> +#include <utils/checkpointing/ReadINamedDiscreteData.hpp> +#include <utils/checkpointing/ResumingData.hpp> +#include <utils/checkpointing/WriteINamedDiscreteData.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 +{ + +PUGS_INLINE void +INamedDiscreteData_check_is_same_type(const INamedDiscreteData::Type& type, const EmbeddedData& e_read_data) +{ + REQUIRE_NOTHROW(dynamic_cast<const DataHandler<const INamedDiscreteData>&>(e_read_data.get())); + + std::shared_ptr<const INamedDiscreteData> p_new_data_v = + dynamic_cast<const DataHandler<const INamedDiscreteData>&>(e_read_data.get()).data_ptr(); + + REQUIRE(p_new_data_v->type() == type); +} + +PUGS_INLINE void +INamedDiscreteData_check_is_same_name(const std::string& name, const EmbeddedData& e_read_data) +{ + REQUIRE_NOTHROW(dynamic_cast<const DataHandler<const INamedDiscreteData>&>(e_read_data.get())); + + std::shared_ptr<const INamedDiscreteData> p_new_data_v = + dynamic_cast<const DataHandler<const INamedDiscreteData>&>(e_read_data.get()).data_ptr(); + + REQUIRE(p_new_data_v->name() == name); +} + +template <typename DataType> +PUGS_INLINE void +INamedDiscreteData_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 INamedDiscreteData>&>(e_read_data.get())); + + const INamedDiscreteData& i_named_discrete_data = + *dynamic_cast<const DataHandler<const INamedDiscreteData>&>(e_read_data.get()).data_ptr(); + + REQUIRE_NOTHROW(dynamic_cast<const NamedDiscreteFunction&>(i_named_discrete_data)); + + const NamedDiscreteFunction& named_discrete_function = + dynamic_cast<const NamedDiscreteFunction&>(i_named_discrete_data); + + using DiscreteFunctionT = DiscreteFunctionP0<const DataType>; + + DiscreteFunctionT read_data = named_discrete_function.discreteFunctionVariant()->get<DiscreteFunctionT>(); + + REQUIRE(test_only::isSameMesh(read_data.meshVariant(), reference.meshVariant())); + + REQUIRE(same_value(reference.cellValues().arrayView(), read_data.cellValues().arrayView())); +} + +template <typename DataType> +PUGS_INLINE void +INamedDiscreteData_check_is_same_data(const DiscreteFunctionP0Vector<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.numberOfRows(); ++i) { + for (size_t j = 0; j < a.numberOfColumns(); ++j) { + same &= (a(i, j) == b(i, j)); + } + } + return parallel::allReduceAnd(same); + }; + + REQUIRE_NOTHROW(dynamic_cast<const DataHandler<const INamedDiscreteData>&>(e_read_data.get())); + + const INamedDiscreteData& i_named_discrete_data = + *dynamic_cast<const DataHandler<const INamedDiscreteData>&>(e_read_data.get()).data_ptr(); + + REQUIRE_NOTHROW(dynamic_cast<const NamedDiscreteFunction&>(i_named_discrete_data)); + + const NamedDiscreteFunction& named_discrete_function = + dynamic_cast<const NamedDiscreteFunction&>(i_named_discrete_data); + + using DiscreteFunctionT = DiscreteFunctionP0Vector<const DataType>; + + DiscreteFunctionT read_data = named_discrete_function.discreteFunctionVariant()->get<DiscreteFunctionT>(); + + REQUIRE(test_only::isSameMesh(read_data.meshVariant(), reference.meshVariant())); + + REQUIRE(same_value(reference.cellArrays().tableView(), read_data.cellArrays().tableView())); +} + +template <ItemType item_type, typename DataType> +PUGS_INLINE void +INamedDiscreteData_check_is_same_data(const ItemValue<DataType, item_type>& 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 INamedDiscreteData>&>(e_read_data.get())); + + const INamedDiscreteData& i_named_discrete_data = + *dynamic_cast<const DataHandler<const INamedDiscreteData>&>(e_read_data.get()).data_ptr(); + + REQUIRE_NOTHROW(dynamic_cast<const NamedItemValueVariant&>(i_named_discrete_data)); + + const NamedItemValueVariant& named_item_value_variant = + dynamic_cast<const NamedItemValueVariant&>(i_named_discrete_data); + + using ItemValueT = ItemValue<const DataType, item_type>; + + ItemValueT read_data = named_item_value_variant.itemValueVariant()->get<ItemValueT>(); + + REQUIRE(test_only::isSameConnectivity(*read_data.connectivity_ptr(), *reference.connectivity_ptr())); + + REQUIRE(same_value(reference.arrayView(), read_data.arrayView())); +} + +template <ItemType item_type, typename DataType> +PUGS_INLINE void +INamedDiscreteData_check_is_same_data(const ItemArray<DataType, item_type>& 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.numberOfRows(); ++i) { + for (size_t j = 0; j < a.numberOfColumns(); ++j) { + same &= (a(i, j) == b(i, j)); + } + } + return parallel::allReduceAnd(same); + }; + + REQUIRE_NOTHROW(dynamic_cast<const DataHandler<const INamedDiscreteData>&>(e_read_data.get())); + + const INamedDiscreteData& i_named_discrete_data = + *dynamic_cast<const DataHandler<const INamedDiscreteData>&>(e_read_data.get()).data_ptr(); + + REQUIRE_NOTHROW(dynamic_cast<const NamedItemArrayVariant&>(i_named_discrete_data)); + + const NamedItemArrayVariant& named_item_array_variant = + dynamic_cast<const NamedItemArrayVariant&>(i_named_discrete_data); + + using ItemArrayT = ItemArray<const DataType, item_type>; + + ItemArrayT read_data = named_item_array_variant.itemArrayVariant()->get<ItemArrayT>(); + + REQUIRE(test_only::isSameConnectivity(*read_data.connectivity_ptr(), *reference.connectivity_ptr())); + + REQUIRE(reference.sizeOfArrays() == read_data.sizeOfArrays()); + + REQUIRE(same_value(reference.tableView(), read_data.tableView())); +} + +} // namespace test_only + +TEST_CASE("checkpointing_INamedDiscreteData", "[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 R1 = TinyVector<1>; + using R2 = TinyVector<2>; + using R3 = TinyVector<3>; + using R1x1 = TinyMatrix<1>; + 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"); + + auto mesh_1d = MeshDataBaseForTests::get().unordered1DMesh()->get<Mesh<1>>(); + + DiscreteFunctionP0<double> df_R_1d{mesh_1d}; + for (CellId cell_id = 0; cell_id < mesh_1d->numberOfCells(); ++cell_id) { + df_R_1d[cell_id] = std::rand() / (1. * RAND_MAX / mesh_1d->numberOfCells()); + } + + DiscreteFunctionP0<R1> df_R1_1d{mesh_1d}; + for (CellId cell_id = 0; cell_id < mesh_1d->numberOfCells(); ++cell_id) { + df_R1_1d[cell_id] = R1{std::rand() / (1. * RAND_MAX / mesh_1d->numberOfCells())}; + } + + 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())}; + } + + 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())}; + } + + DiscreteFunctionP0<R2x2> df_R2x2_2d{mesh_2d}; + for (CellId cell_id = 0; cell_id < mesh_2d->numberOfCells(); ++cell_id) { + df_R2x2_2d[cell_id] = R2x2{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::rand() / (1. * RAND_MAX / mesh_2d->numberOfCells())}; + } + + NodeValue<R2x2> iv_R2x2_2d{mesh_2d->connectivity()}; + for (NodeId node_id = 0; node_id < mesh_2d->numberOfNodes(); ++node_id) { + iv_R2x2_2d[node_id] = R2x2{std::rand() / (1. * RAND_MAX / mesh_2d->numberOfNodes()), + std::rand() / (1. * RAND_MAX / mesh_2d->numberOfNodes()), + std::rand() / (1. * RAND_MAX / mesh_2d->numberOfNodes()), + std::rand() / (1. * RAND_MAX / mesh_2d->numberOfNodes())}; + } + + FaceArray<R2x2> ia_R2x2_2d{mesh_2d->connectivity(), 3}; + for (FaceId face_id = 0; face_id < mesh_2d->numberOfFaces(); ++face_id) { + for (size_t i = 0; i < ia_R2x2_2d.sizeOfArrays(); ++i) { + ia_R2x2_2d[face_id][i] = R2x2{std::rand() / (1. * RAND_MAX / mesh_2d->numberOfFaces()), + std::rand() / (1. * RAND_MAX / mesh_2d->numberOfFaces()), + std::rand() / (1. * RAND_MAX / mesh_2d->numberOfFaces()), + std::rand() / (1. * RAND_MAX / mesh_2d->numberOfFaces())}; + } + } + + DiscreteFunctionP0Vector<double> dfv_R_2d{mesh_2d, 3}; + for (CellId cell_id = 0; cell_id < mesh_2d->numberOfCells(); ++cell_id) { + for (size_t i = 0; i < dfv_R_2d.size(); ++i) { + dfv_R_2d[cell_id][i] = std::rand() / (1. * RAND_MAX / mesh_2d->numberOfCells()); + } + } + + 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())}; + } + + DiscreteFunctionP0<R1x1> df_R1x1_3d{mesh_3d}; + for (CellId cell_id = 0; cell_id < mesh_3d->numberOfCells(); ++cell_id) { + df_R1x1_3d[cell_id] = R1x1{std::rand() / (1. * RAND_MAX / mesh_3d->numberOfCells())}; + } + + DiscreteFunctionP0<R3x3> df_R3x3_3d{mesh_3d}; + for (CellId cell_id = 0; cell_id < mesh_3d->numberOfCells(); ++cell_id) { + df_R3x3_3d[cell_id] = R3x3{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::rand() / (1. * RAND_MAX / mesh_3d->numberOfCells()), + 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::rand() / (1. * RAND_MAX / mesh_3d->numberOfCells()), + std::rand() / (1. * RAND_MAX / mesh_3d->numberOfCells())}; + } + + EdgeValue<R3x3> iv_R3x3_3d{mesh_3d->connectivity()}; + for (EdgeId edge_id = 0; edge_id < mesh_3d->numberOfEdges(); ++edge_id) { + iv_R3x3_3d[edge_id] = R3x3{std::rand() / (1. * RAND_MAX / mesh_2d->numberOfEdges()), + std::rand() / (1. * RAND_MAX / mesh_2d->numberOfEdges()), + std::rand() / (1. * RAND_MAX / mesh_2d->numberOfEdges()), + std::rand() / (1. * RAND_MAX / mesh_2d->numberOfEdges()), + std::rand() / (1. * RAND_MAX / mesh_2d->numberOfEdges()), + std::rand() / (1. * RAND_MAX / mesh_2d->numberOfEdges()), + std::rand() / (1. * RAND_MAX / mesh_2d->numberOfEdges()), + std::rand() / (1. * RAND_MAX / mesh_2d->numberOfEdges()), + std::rand() / (1. * RAND_MAX / mesh_2d->numberOfEdges())}; + } + + { // Write + using DataHandlerT = DataHandler<const INamedDiscreteData>; + + 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 double> df_R_1d_new{new_mesh_1d_v, + CellValue<const double>{new_connectivity_1d, + df_R_1d.cellValues().arrayView()}}; + DiscreteFunctionP0<const R1> df_R1_1d_new{new_mesh_1d_v, + CellValue<const R1>{new_connectivity_1d, + df_R1_1d.cellValues().arrayView()}}; + 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 INamedDiscreteData> i_named_df_R_1d = + std::make_shared<NamedDiscreteFunction>(std::make_shared<const DiscreteFunctionVariant>(df_R_1d_new), + "df_R_1d"); + + checkpointing::writeINamedDiscreteData("df_R_1d", EmbeddedData{std::make_shared<DataHandlerT>(i_named_df_R_1d)}, + file, checkpoint_group, symbol_table_group); + + std::shared_ptr<const INamedDiscreteData> i_named_df_R1_1d = + std::make_shared<NamedDiscreteFunction>(std::make_shared<const DiscreteFunctionVariant>(df_R1_1d_new), + "df_R1_1d"); + + checkpointing::writeINamedDiscreteData("df_R1_1d", + EmbeddedData{std::make_shared<DataHandlerT>(i_named_df_R1_1d)}, file, + checkpoint_group, symbol_table_group); + + std::shared_ptr<const INamedDiscreteData> i_named_df_R2_1d = + std::make_shared<NamedDiscreteFunction>(std::make_shared<const DiscreteFunctionVariant>(df_R2_1d_new), + "df_R2_1d"); + + checkpointing::writeINamedDiscreteData("df_R2_1d", + EmbeddedData{std::make_shared<DataHandlerT>(i_named_df_R2_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()}}; + DiscreteFunctionP0<const R2x2> df_R2x2_2d_new{new_mesh_2d_v, + CellValue<const R2x2>{new_connectivity_2d, + df_R2x2_2d.cellValues().arrayView()}}; + + NodeValue<const R2x2> iv_R2x2_2d_new{new_connectivity_2d, iv_R2x2_2d.arrayView()}; + + FaceArray<const R2x2> ia_R2x2_2d_new{new_connectivity_2d, ia_R2x2_2d.tableView()}; + + DiscreteFunctionP0Vector<const double> dfv_R_2d_new{new_mesh_2d_v, + CellArray<const double>{new_connectivity_2d, + dfv_R_2d.cellArrays().tableView()}}; + + std::shared_ptr<const INamedDiscreteData> i_named_df_R3_2d = + std::make_shared<NamedDiscreteFunction>(std::make_shared<const DiscreteFunctionVariant>(df_R3_2d_new), + "df_R3_2d"); + + checkpointing::writeINamedDiscreteData("df_R3_2d", + EmbeddedData{std::make_shared<DataHandlerT>(i_named_df_R3_2d)}, file, + checkpoint_group, symbol_table_group); + + std::shared_ptr<const INamedDiscreteData> i_named_df_R2x2_2d = + std::make_shared<NamedDiscreteFunction>(std::make_shared<const DiscreteFunctionVariant>(df_R2x2_2d_new), + "df_R2x2_2d"); + + checkpointing::writeINamedDiscreteData("df_R2x2_2d", + EmbeddedData{std::make_shared<DataHandlerT>(i_named_df_R2x2_2d)}, file, + checkpoint_group, symbol_table_group); + + std::shared_ptr<const INamedDiscreteData> i_named_iv_R2x2_2d = + std::make_shared<NamedItemValueVariant>(std::make_shared<const ItemValueVariant>(iv_R2x2_2d_new), + "iv_R2x2_2d"); + + checkpointing::writeINamedDiscreteData("iv_R2x2_2d", + EmbeddedData{std::make_shared<DataHandlerT>(i_named_iv_R2x2_2d)}, file, + checkpoint_group, symbol_table_group); + + std::shared_ptr<const INamedDiscreteData> i_named_ia_R2x2_2d = + std::make_shared<NamedItemArrayVariant>(std::make_shared<const ItemArrayVariant>(ia_R2x2_2d_new), + "ia_R2x2_2d"); + + checkpointing::writeINamedDiscreteData("ia_R2x2_2d", + EmbeddedData{std::make_shared<DataHandlerT>(i_named_ia_R2x2_2d)}, file, + checkpoint_group, symbol_table_group); + + std::shared_ptr<const INamedDiscreteData> i_named_dfv_R_2d = + std::make_shared<NamedDiscreteFunction>(std::make_shared<const DiscreteFunctionVariant>(dfv_R_2d_new), + "dfv_R_2d"); + + checkpointing::writeINamedDiscreteData("dfv_R_2d", + EmbeddedData{std::make_shared<DataHandlerT>(i_named_dfv_R_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()}}; + DiscreteFunctionP0<const R1x1> df_R1x1_3d_new{new_mesh_3d, + CellValue<const R1x1>{new_connectivity_3d, + df_R1x1_3d.cellValues().arrayView()}}; + DiscreteFunctionP0<const R3x3> df_R3x3_3d_new{new_mesh_3d, + CellValue<const R3x3>{new_connectivity_3d, + df_R3x3_3d.cellValues().arrayView()}}; + + EdgeValue<const R3x3> iv_R3x3_3d_new{new_connectivity_3d, iv_R3x3_3d.arrayView()}; + + std::shared_ptr<const INamedDiscreteData> i_named_df_R3_3d = + std::make_shared<NamedDiscreteFunction>(std::make_shared<const DiscreteFunctionVariant>(df_R3_3d_new), + "df_R3_3d"); + + checkpointing::writeINamedDiscreteData("df_R3_3d", + EmbeddedData{std::make_shared<DataHandlerT>(i_named_df_R3_3d)}, file, + checkpoint_group, symbol_table_group); + + std::shared_ptr<const INamedDiscreteData> i_named_df_R1x1_3d = + std::make_shared<NamedDiscreteFunction>(std::make_shared<const DiscreteFunctionVariant>(df_R1x1_3d_new), + "df_R1x1_3d"); + + checkpointing::writeINamedDiscreteData("df_R1x1_3d", + EmbeddedData{std::make_shared<DataHandlerT>(i_named_df_R1x1_3d)}, file, + checkpoint_group, symbol_table_group); + + std::shared_ptr<const INamedDiscreteData> i_named_df_R3x3_3d = + std::make_shared<NamedDiscreteFunction>(std::make_shared<const DiscreteFunctionVariant>(df_R3x3_3d_new), + "df_R3x3_3d"); + + checkpointing::writeINamedDiscreteData("df_R3x3_3d", + EmbeddedData{std::make_shared<DataHandlerT>(i_named_df_R3x3_3d)}, file, + checkpoint_group, symbol_table_group); + + std::shared_ptr<const INamedDiscreteData> i_named_iv_R3x3_3d = + std::make_shared<NamedItemValueVariant>(std::make_shared<const ItemValueVariant>(iv_R3x3_3d_new), + "iv_R3x3_3d"); + checkpointing::writeINamedDiscreteData("iv_R3x3_3d", + EmbeddedData{std::make_shared<DataHandlerT>(i_named_iv_R3x3_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_df_R_1d = checkpointing::readINamedDiscreteData("df_R_1d", symbol_table_group); + test_only::INamedDiscreteData_check_is_same_type(INamedDiscreteData::Type::discrete_function, e_df_R_1d); + test_only::INamedDiscreteData_check_is_same_name("df_R_1d", e_df_R_1d); + test_only::INamedDiscreteData_check_is_same_data(df_R_1d, e_df_R_1d); + + auto e_df_R1_1d = checkpointing::readINamedDiscreteData("df_R1_1d", symbol_table_group); + test_only::INamedDiscreteData_check_is_same_type(INamedDiscreteData::Type::discrete_function, e_df_R1_1d); + test_only::INamedDiscreteData_check_is_same_name("df_R1_1d", e_df_R1_1d); + test_only::INamedDiscreteData_check_is_same_data(df_R1_1d, e_df_R1_1d); + + auto e_df_R2_1d = checkpointing::readINamedDiscreteData("df_R2_1d", symbol_table_group); + test_only::INamedDiscreteData_check_is_same_type(INamedDiscreteData::Type::discrete_function, e_df_R2_1d); + test_only::INamedDiscreteData_check_is_same_name("df_R2_1d", e_df_R2_1d); + test_only::INamedDiscreteData_check_is_same_data(df_R2_1d, e_df_R2_1d); + + auto e_df_R3_2d = checkpointing::readINamedDiscreteData("df_R3_2d", symbol_table_group); + test_only::INamedDiscreteData_check_is_same_type(INamedDiscreteData::Type::discrete_function, e_df_R3_2d); + test_only::INamedDiscreteData_check_is_same_name("df_R3_2d", e_df_R3_2d); + test_only::INamedDiscreteData_check_is_same_data(df_R3_2d, e_df_R3_2d); + + auto e_df_R2x2_2d = checkpointing::readINamedDiscreteData("df_R2x2_2d", symbol_table_group); + test_only::INamedDiscreteData_check_is_same_type(INamedDiscreteData::Type::discrete_function, e_df_R2x2_2d); + test_only::INamedDiscreteData_check_is_same_name("df_R2x2_2d", e_df_R2x2_2d); + test_only::INamedDiscreteData_check_is_same_data(df_R2x2_2d, e_df_R2x2_2d); + + auto e_iv_R2x2_2d = checkpointing::readINamedDiscreteData("iv_R2x2_2d", symbol_table_group); + test_only::INamedDiscreteData_check_is_same_type(INamedDiscreteData::Type::item_value, e_iv_R2x2_2d); + test_only::INamedDiscreteData_check_is_same_name("iv_R2x2_2d", e_iv_R2x2_2d); + test_only::INamedDiscreteData_check_is_same_data(iv_R2x2_2d, e_iv_R2x2_2d); + + auto e_ia_R2x2_2d = checkpointing::readINamedDiscreteData("ia_R2x2_2d", symbol_table_group); + test_only::INamedDiscreteData_check_is_same_type(INamedDiscreteData::Type::item_array, e_ia_R2x2_2d); + test_only::INamedDiscreteData_check_is_same_name("ia_R2x2_2d", e_ia_R2x2_2d); + test_only::INamedDiscreteData_check_is_same_data(ia_R2x2_2d, e_ia_R2x2_2d); + + auto e_dfv_R_2d = checkpointing::readINamedDiscreteData("dfv_R_2d", symbol_table_group); + test_only::INamedDiscreteData_check_is_same_type(INamedDiscreteData::Type::discrete_function, e_dfv_R_2d); + test_only::INamedDiscreteData_check_is_same_name("dfv_R_2d", e_dfv_R_2d); + test_only::INamedDiscreteData_check_is_same_data(dfv_R_2d, e_dfv_R_2d); + + auto e_df_R3_3d = checkpointing::readINamedDiscreteData("df_R3_3d", symbol_table_group); + test_only::INamedDiscreteData_check_is_same_type(INamedDiscreteData::Type::discrete_function, e_df_R3_3d); + test_only::INamedDiscreteData_check_is_same_name("df_R3_3d", e_df_R3_3d); + test_only::INamedDiscreteData_check_is_same_data(df_R3_3d, e_df_R3_3d); + + auto e_iv_R3x3_3d = checkpointing::readINamedDiscreteData("iv_R3x3_3d", symbol_table_group); + test_only::INamedDiscreteData_check_is_same_type(INamedDiscreteData::Type::item_value, e_iv_R3x3_3d); + test_only::INamedDiscreteData_check_is_same_name("iv_R3x3_3d", e_iv_R3x3_3d); + test_only::INamedDiscreteData_check_is_same_data(iv_R3x3_3d, e_iv_R3x3_3d); + + auto e_df_R1x1_3d = checkpointing::readINamedDiscreteData("df_R1x1_3d", symbol_table_group); + test_only::INamedDiscreteData_check_is_same_type(INamedDiscreteData::Type::discrete_function, e_df_R1x1_3d); + test_only::INamedDiscreteData_check_is_same_name("df_R1x1_3d", e_df_R1x1_3d); + test_only::INamedDiscreteData_check_is_same_data(df_R1x1_3d, e_df_R1x1_3d); + + auto e_df_R3x3_3d = checkpointing::readINamedDiscreteData("df_R3x3_3d", symbol_table_group); + test_only::INamedDiscreteData_check_is_same_type(INamedDiscreteData::Type::discrete_function, e_df_R3x3_3d); + test_only::INamedDiscreteData_check_is_same_name("df_R3x3_3d", e_df_R3x3_3d); + test_only::INamedDiscreteData_check_is_same_data(df_R3x3_3d, e_df_R3x3_3d); + } + checkpointing::ResumingData::destroy(); + } + } + + parallel::barrier(); + if (parallel::rank() == 0) { + std::filesystem::remove_all(std::filesystem::path{tmp_dirname}); + } +}