Skip to content
Snippets Groups Projects
Select Git revision
  • ef67ba5bc2b500022bb51f5c6a5eb3dbdfd8ef68
  • develop default protected
  • feature/advection
  • feature/composite-scheme-other-fluxes
  • origin/stage/bouguettaia
  • save_clemence
  • feature/local-dt-fsi
  • feature/variational-hydro
  • feature/gmsh-reader
  • feature/reconstruction
  • feature/kinetic-schemes
  • feature/composite-scheme-sources
  • feature/serraille
  • feature/composite-scheme
  • hyperplastic
  • feature/polynomials
  • feature/gks
  • feature/implicit-solver-o2
  • feature/coupling_module
  • feature/implicit-solver
  • feature/merge-local-dt-fsi
  • v0.5.0 protected
  • v0.4.1 protected
  • v0.4.0 protected
  • v0.3.0 protected
  • v0.2.0 protected
  • v0.1.0 protected
  • Kidder
  • v0.0.4 protected
  • v0.0.3 protected
  • v0.0.2 protected
  • v0 protected
  • v0.0.1 protected
33 results

ReproducibleSumUtils.hpp

Blame
  • test_checkpointing_ItemValueVariant.cpp 15.62 KiB
    #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/ItemValueVariant.hpp>
    #include <mesh/Mesh.hpp>
    #include <utils/GlobalVariableManager.hpp>
    #include <utils/checkpointing/ReadItemValueVariant.hpp>
    #include <utils/checkpointing/ResumingData.hpp>
    #include <utils/checkpointing/WriteItemValueVariant.hpp>
    
    #include <MeshDataBaseForTests.hpp>
    #include <checkpointing_Connectivity_utilities.hpp>
    
    #include <filesystem>
    
    // clazy:excludeall=non-pod-global-static
    
    namespace test_only
    {
    
    template <typename DataType, ItemType item_type>
    PUGS_INLINE void
    check_is_same(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 ItemValueVariant>&>(e_read_data.get()));
    
      std::shared_ptr<const ItemValueVariant> p_new_data_v =
        dynamic_cast<const DataHandler<const ItemValueVariant>&>(e_read_data.get()).data_ptr();
    
      using ItemTypeT = ItemValue<const DataType, item_type>;
    
      ItemTypeT read_data = p_new_data_v->get<ItemTypeT>();
    
      switch (reference.connectivity_ptr()->dimension()) {
      case 1: {
        REQUIRE(test_only::isSameConnectivity(dynamic_cast<const Connectivity<1>&>(*reference.connectivity_ptr()),
                                              dynamic_cast<const Connectivity<1>&>(*read_data.connectivity_ptr())));
        break;
      }
      case 2: {
        REQUIRE(test_only::isSameConnectivity(dynamic_cast<const Connectivity<2>&>(*reference.connectivity_ptr()),
                                              dynamic_cast<const Connectivity<2>&>(*read_data.connectivity_ptr())));
        break;
      }
      case 3: {
        REQUIRE(test_only::isSameConnectivity(dynamic_cast<const Connectivity<3>&>(*reference.connectivity_ptr()),
                                              dynamic_cast<const Connectivity<3>&>(*read_data.connectivity_ptr())));
        break;
      }
      default: {
        throw UnexpectedError("invalid connectivity dimension");
      }
      }
    
      REQUIRE(same_value(reference.arrayView(), read_data.arrayView()));
    }
    
    }   // namespace test_only
    
    TEST_CASE("checkpointing_ItemValueVariant", "[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();
    
        SECTION("Connectivity")
        {
          using R1   = TinyVector<1>;
          using R2   = TinyVector<2>;
          using R3   = TinyVector<3>;
          using R1x1 = TinyMatrix<1>;
          using R2x2 = TinyMatrix<2>;
          using R3x3 = TinyMatrix<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>>();
    
          CellValue<bool> cell_B_1d{mesh_1d->connectivity()};
          for (CellId cell_id = 0; cell_id < mesh_1d->numberOfCells(); ++cell_id) {
            cell_B_1d[cell_id] = (std::rand() / (RAND_MAX / mesh_1d->numberOfCells())) % 2;
          }
    
          CellValue<uint64_t> cell_N_1d{mesh_1d->connectivity()};
          for (CellId cell_id = 0; cell_id < mesh_1d->numberOfCells(); ++cell_id) {
            cell_N_1d[cell_id] = (std::rand() / (RAND_MAX / mesh_1d->numberOfCells()));
          }
    
          NodeValue<int64_t> node_Z_1d{mesh_1d->connectivity()};
          for (NodeId node_id = 0; node_id < mesh_1d->numberOfNodes(); ++node_id) {
            node_Z_1d[node_id] = 100 * (std::rand() - RAND_MAX / 2.) / (RAND_MAX / mesh_1d->numberOfNodes());
          }
    
          NodeValue<double> node_R_1d{mesh_1d->connectivity()};
          for (NodeId node_id = 0; node_id < mesh_1d->numberOfNodes(); ++node_id) {
            node_R_1d[node_id] = std::rand() / (1. * RAND_MAX / mesh_1d->numberOfNodes());
          }
    
          CellValue<R1> cell_R1_1d{mesh_1d->connectivity()};
          for (CellId cell_id = 0; cell_id < mesh_1d->numberOfCells(); ++cell_id) {
            cell_R1_1d[cell_id] = R1{std::rand() / (1. * RAND_MAX / mesh_1d->numberOfCells())};
          }
    
          NodeValue<R2> node_R2_1d{mesh_1d->connectivity()};
          for (NodeId node_id = 0; node_id < mesh_1d->numberOfNodes(); ++node_id) {
            node_R2_1d[node_id] = R2{std::rand() / (1. * RAND_MAX / mesh_1d->numberOfNodes()),
                                     std::rand() / (1. * RAND_MAX / mesh_1d->numberOfNodes())};
          }
    
          auto mesh_2d = MeshDataBaseForTests::get().hybrid2DMesh()->get<Mesh<2>>();
    
          FaceValue<R3> face_R3_2d{mesh_2d->connectivity()};
          for (FaceId face_id = 0; face_id < mesh_2d->numberOfFaces(); ++face_id) {
            face_R3_2d[face_id] = R3{std::rand() / (1. * RAND_MAX / mesh_2d->numberOfFaces()),
                                     std::rand() / (1. * RAND_MAX / mesh_2d->numberOfFaces()),
                                     std::rand() / (1. * RAND_MAX / mesh_2d->numberOfFaces())};
          }
    
          NodeValue<R2x2> node_R2x2_2d{mesh_2d->connectivity()};
          for (NodeId node_id = 0; node_id < mesh_2d->numberOfNodes(); ++node_id) {
            node_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())};
          }
    
          auto mesh_3d = MeshDataBaseForTests::get().hybrid3DMesh()->get<Mesh<3>>();
    
          EdgeValue<R3> edge_R3_3d{mesh_3d->connectivity()};
          for (EdgeId edge_id = 0; edge_id < mesh_3d->numberOfEdges(); ++edge_id) {
            edge_R3_3d[edge_id] = R3{std::rand() / (1. * RAND_MAX / mesh_3d->numberOfEdges()),
                                     std::rand() / (1. * RAND_MAX / mesh_3d->numberOfEdges()),
                                     std::rand() / (1. * RAND_MAX / mesh_3d->numberOfEdges())};
          }
    
          FaceValue<R1x1> face_R1x1_3d{mesh_3d->connectivity()};
          for (FaceId face_id = 0; face_id < mesh_3d->numberOfFaces(); ++face_id) {
            face_R1x1_3d[face_id] = R1x1{std::rand() / (1. * RAND_MAX / mesh_3d->numberOfFaces())};
          }
    
          NodeValue<R3x3> node_R3x3_3d{mesh_3d->connectivity()};
          for (NodeId node_id = 0; node_id < mesh_3d->numberOfNodes(); ++node_id) {
            node_R3x3_3d[node_id] = R3x3{std::rand() / (1. * RAND_MAX / mesh_3d->numberOfNodes()),
                                         std::rand() / (1. * RAND_MAX / mesh_3d->numberOfNodes()),
                                         std::rand() / (1. * RAND_MAX / mesh_3d->numberOfNodes()),
                                         std::rand() / (1. * RAND_MAX / mesh_3d->numberOfNodes()),
                                         std::rand() / (1. * RAND_MAX / mesh_3d->numberOfNodes()),
                                         std::rand() / (1. * RAND_MAX / mesh_3d->numberOfNodes()),
                                         std::rand() / (1. * RAND_MAX / mesh_3d->numberOfNodes()),
                                         std::rand() / (1. * RAND_MAX / mesh_3d->numberOfNodes()),
                                         std::rand() / (1. * RAND_MAX / mesh_3d->numberOfNodes())};
          }
    
          {   // Write
            using DataHandlerT = DataHandler<const ItemValueVariant>;
    
            auto new_connectivity_1d = test_only::duplicateConnectivity(mesh_1d->connectivity());
    
            CellValue<const bool> cell_B_1d_new{*new_connectivity_1d, cell_B_1d.arrayView()};
            NodeValue<const int64_t> node_Z_1d_new{*new_connectivity_1d, node_Z_1d.arrayView()};
            CellValue<const uint64_t> cell_N_1d_new{*new_connectivity_1d, cell_N_1d.arrayView()};
            NodeValue<const double> node_R_1d_new{*new_connectivity_1d, node_R_1d.arrayView()};
            CellValue<const R1> cell_R1_1d_new{*new_connectivity_1d, cell_R1_1d.arrayView()};
            NodeValue<const R2> node_R2_1d_new{*new_connectivity_1d, node_R2_1d.arrayView()};
    
            checkpointing::writeItemValueVariant("cell_B_1d",
                                                 EmbeddedData{std::make_shared<DataHandlerT>(
                                                   std::make_shared<const ItemValueVariant>(cell_B_1d_new))},
                                                 file, checkpoint_group, symbol_table_group);
    
            checkpointing::writeItemValueVariant("cell_N_1d",
                                                 EmbeddedData{std::make_shared<DataHandlerT>(
                                                   std::make_shared<const ItemValueVariant>(cell_N_1d_new))},
                                                 file, checkpoint_group, symbol_table_group);
    
            checkpointing::writeItemValueVariant("node_Z_1d",
                                                 EmbeddedData{std::make_shared<DataHandlerT>(
                                                   std::make_shared<const ItemValueVariant>(node_Z_1d_new))},
                                                 file, checkpoint_group, symbol_table_group);
    
            checkpointing::writeItemValueVariant("node_R_1d",
                                                 EmbeddedData{std::make_shared<DataHandlerT>(
                                                   std::make_shared<const ItemValueVariant>(node_R_1d_new))},
                                                 file, checkpoint_group, symbol_table_group);
    
            checkpointing::writeItemValueVariant("cell_R1_1d",
                                                 EmbeddedData{std::make_shared<DataHandlerT>(
                                                   std::make_shared<const ItemValueVariant>(cell_R1_1d_new))},
                                                 file, checkpoint_group, symbol_table_group);
    
            checkpointing::writeItemValueVariant("node_R2_1d",
                                                 EmbeddedData{std::make_shared<DataHandlerT>(
                                                   std::make_shared<const ItemValueVariant>(node_R2_1d_new))},
                                                 file, checkpoint_group, symbol_table_group);
    
            auto new_connectivity_2d = test_only::duplicateConnectivity(mesh_2d->connectivity());
    
            FaceValue<const R3> face_R3_2d_new{*new_connectivity_2d, face_R3_2d.arrayView()};
            NodeValue<const R2x2> node_R2x2_2d_new{*new_connectivity_2d, node_R2x2_2d.arrayView()};
    
            checkpointing::writeItemValueVariant("face_R3_2d",
                                                 EmbeddedData{std::make_shared<DataHandlerT>(
                                                   std::make_shared<const ItemValueVariant>(face_R3_2d_new))},
                                                 file, checkpoint_group, symbol_table_group);
    
            checkpointing::writeItemValueVariant("node_R2x2_2d",
                                                 EmbeddedData{std::make_shared<DataHandlerT>(
                                                   std::make_shared<const ItemValueVariant>(node_R2x2_2d_new))},
                                                 file, checkpoint_group, symbol_table_group);
    
            auto new_connectivity_3d = test_only::duplicateConnectivity(mesh_3d->connectivity());
    
            EdgeValue<const R3> edge_R3_3d_new{*new_connectivity_3d, edge_R3_3d.arrayView()};
            FaceValue<const R1x1> face_R1x1_3d_new{*new_connectivity_3d, face_R1x1_3d.arrayView()};
            NodeValue<const R3x3> node_R3x3_3d_new{*new_connectivity_3d, node_R3x3_3d.arrayView()};
    
            checkpointing::writeItemValueVariant("edge_R3_3d",
                                                 EmbeddedData{std::make_shared<DataHandlerT>(
                                                   std::make_shared<const ItemValueVariant>(edge_R3_3d_new))},
                                                 file, checkpoint_group, symbol_table_group);
    
            checkpointing::writeItemValueVariant("face_R1x1_3d",
                                                 EmbeddedData{std::make_shared<DataHandlerT>(
                                                   std::make_shared<const ItemValueVariant>(face_R1x1_3d_new))},
                                                 file, checkpoint_group, symbol_table_group);
    
            checkpointing::writeItemValueVariant("node_R3x3_3d",
                                                 EmbeddedData{std::make_shared<DataHandlerT>(
                                                   std::make_shared<const ItemValueVariant>(node_R3x3_3d_new))},
                                                 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);
    
          file.flush();
    
          checkpointing::ResumingData::create();
          checkpointing::ResumingData::instance().readData(checkpoint_group, nullptr);
    
          GlobalVariableManager::instance().setConnectivityId(initial_connectivity_id);
          {   // Read
            auto e_cell_B_1d = checkpointing::readItemValueVariant("cell_B_1d", symbol_table_group);
            test_only::check_is_same(cell_B_1d, e_cell_B_1d);
    
            auto e_cell_N_1d = checkpointing::readItemValueVariant("cell_N_1d", symbol_table_group);
            test_only::check_is_same(cell_N_1d, e_cell_N_1d);
    
            auto e_node_Z_1d = checkpointing::readItemValueVariant("node_Z_1d", symbol_table_group);
            test_only::check_is_same(node_Z_1d, e_node_Z_1d);
    
            auto e_node_R_1d = checkpointing::readItemValueVariant("node_R_1d", symbol_table_group);
            test_only::check_is_same(node_R_1d, e_node_R_1d);
    
            auto e_cell_R1_1d = checkpointing::readItemValueVariant("cell_R1_1d", symbol_table_group);
            test_only::check_is_same(cell_R1_1d, e_cell_R1_1d);
    
            auto e_node_R2_1d = checkpointing::readItemValueVariant("node_R2_1d", symbol_table_group);
            test_only::check_is_same(node_R2_1d, e_node_R2_1d);
    
            auto e_face_R3_2d = checkpointing::readItemValueVariant("face_R3_2d", symbol_table_group);
            test_only::check_is_same(face_R3_2d, e_face_R3_2d);
    
            auto e_node_R2x2_2d = checkpointing::readItemValueVariant("node_R2x2_2d", symbol_table_group);
            test_only::check_is_same(node_R2x2_2d, e_node_R2x2_2d);
    
            auto e_edge_R3_3d = checkpointing::readItemValueVariant("edge_R3_3d", symbol_table_group);
            test_only::check_is_same(edge_R3_3d, e_edge_R3_3d);
    
            auto e_face_R1x1_3d = checkpointing::readItemValueVariant("face_R1x1_3d", symbol_table_group);
            test_only::check_is_same(face_R1x1_3d, e_face_R1x1_3d);
    
            auto e_node_R3x3_3d = checkpointing::readItemValueVariant("node_R3x3_3d", symbol_table_group);
            test_only::check_is_same(node_R3x3_3d, e_node_R3x3_3d);
          }
          checkpointing::ResumingData::destroy();
        }
      }
    
      parallel::barrier();
      if (parallel::rank() == 0) {
        std::filesystem::remove_all(std::filesystem::path{tmp_dirname});
      }
    }