From 0f20b3308013be5f8ebb2392eec7c90453d79d73 Mon Sep 17 00:00:00 2001 From: Stephane Del Pino <stephane.delpino44@gmail.com> Date: Mon, 27 May 2024 09:07:44 +0200 Subject: [PATCH] Add checkpoint/resume for dual meshes --- src/mesh/DualMeshManager.hpp | 6 ++ src/utils/checkpointing/Checkpoint.cpp | 16 +++- src/utils/checkpointing/Resume.cpp | 3 - src/utils/checkpointing/ResumingData.cpp | 93 +++++++++++++++++------- 4 files changed, 85 insertions(+), 33 deletions(-) diff --git a/src/mesh/DualMeshManager.hpp b/src/mesh/DualMeshManager.hpp index 46ad9c9f8..201b0e663 100644 --- a/src/mesh/DualMeshManager.hpp +++ b/src/mesh/DualMeshManager.hpp @@ -34,6 +34,12 @@ class DualMeshManager ~DualMeshManager() = default; public: + const auto& + primalToDualMeshMap() const + { + return m_mesh_to_dual_mesh_map; + } + static void create(); static void destroy(); diff --git a/src/utils/checkpointing/Checkpoint.cpp b/src/utils/checkpointing/Checkpoint.cpp index dbd10ca63..5946e10e2 100644 --- a/src/utils/checkpointing/Checkpoint.cpp +++ b/src/utils/checkpointing/Checkpoint.cpp @@ -122,8 +122,20 @@ checkpoint() connectivity_group.createAttribute("id", dual_connectivity_id); connectivity_group.createAttribute("primal_connectivity_id", primal_connectivity_id); } - - std::cout << rang::fgB::magenta << "Checkpoint DualMeshManager NIY" << rang::fg::reset << '\n'; + } + { + const auto& primal_to_dual_mesh_info_map = DualMeshManager::instance().primalToDualMeshMap(); + for (auto&& primal_to_dual_mesh_info : primal_to_dual_mesh_info_map) { + const DualMeshType type_of_dual = primal_to_dual_mesh_info.first.first; + const size_t primal_mesh_id = primal_to_dual_mesh_info.first.second; + const size_t dual_mesh_id = primal_to_dual_mesh_info.second->id(); + + HighFive::Group connectivity_group = checkpoint.createGroup("mesh/" + std::to_string(dual_mesh_id)); + connectivity_group.createAttribute("type", std::string{"dual_mesh"}); + connectivity_group.createAttribute("type_of_dual", type_of_dual); + connectivity_group.createAttribute("id", dual_mesh_id); + connectivity_group.createAttribute("primal_mesh_id", primal_mesh_id); + } } std::shared_ptr<const SymbolTable> p_symbol_table = ASTExecutionStack::getInstance().currentNode().m_symbol_table; diff --git a/src/utils/checkpointing/Resume.cpp b/src/utils/checkpointing/Resume.cpp index b5e653161..b7ee29441 100644 --- a/src/utils/checkpointing/Resume.cpp +++ b/src/utils/checkpointing/Resume.cpp @@ -91,9 +91,6 @@ resume() default_options.method() = linear_solver_options_default_group.getAttribute("method").read<LSMethod>(); default_options.precond() = linear_solver_options_default_group.getAttribute("precond").read<LSPrecond>(); } - { - std::cout << rang::fgB::magenta << "Resume DualMeshManager NIY" << rang::fg::reset << '\n'; - } ResumingData::instance().readData(checkpoint, p_symbol_table); diff --git a/src/utils/checkpointing/ResumingData.cpp b/src/utils/checkpointing/ResumingData.cpp index a2d6c98b2..d0e51c4a5 100644 --- a/src/utils/checkpointing/ResumingData.cpp +++ b/src/utils/checkpointing/ResumingData.cpp @@ -3,6 +3,7 @@ #include <language/utils/SymbolTable.hpp> #include <mesh/ConnectivityDescriptor.hpp> #include <mesh/DualConnectivityManager.hpp> +#include <mesh/DualMeshManager.hpp> #include <mesh/Mesh.hpp> #include <utils/Exceptions.hpp> #include <utils/checkpointing/DualMeshTypeHFType.hpp> @@ -17,6 +18,8 @@ ResumingData::_getConnectivityList(const HighFive::Group& checkpoint) if (checkpoint.exist("connectivity")) { HighFive::Group connectivity_group = checkpoint.getGroup("connectivity"); + // it is important to use a map here. "id"s must be treated in + // increasing order. std::map<size_t, std::string> id_name_map; for (auto connectivity_id_name : connectivity_group.listObjectNames()) { HighFive::Group connectivity_info = connectivity_group.getGroup(connectivity_id_name); @@ -152,8 +155,6 @@ ResumingData::_getConnectivityList(const HighFive::Group& checkpoint) const DualMeshType type_of_dual = connectivity_data.getAttribute("type_of_dual").read<DualMeshType>(); const size_t primal_connectivity_id = connectivity_data.getAttribute("primal_connectivity_id").read<size_t>(); - std::cout << "reading " << id << " " << ::name(type_of_dual) << " of " << primal_connectivity_id << '\n'; - std::shared_ptr<const IConnectivity> iprimal_connectivity = m_id_to_iconnectivity_map.at(primal_connectivity_id); @@ -244,41 +245,77 @@ ResumingData::_getMeshVariantList(const HighFive::Group& checkpoint) if (checkpoint.exist("mesh")) { HighFive::Group mesh_group = checkpoint.getGroup("mesh"); + // it is important to use a map here. "id"s must be treated in + // increasing order. std::map<size_t, std::string> id_name_map; for (auto mesh_id_name : mesh_group.listObjectNames()) { HighFive::Group mesh_info = mesh_group.getGroup(mesh_id_name); id_name_map[mesh_info.getAttribute("id").read<uint64_t>()] = mesh_id_name; } - for (auto [id, name] : id_name_map) { + for (auto&& id_name : id_name_map) { + // workaround due to clang not handling correctly captures + const auto& id = id_name.first; + const auto& name = id_name.second; + HighFive::Group mesh_data = mesh_group.getGroup(name); const std::string type = mesh_data.getAttribute("type").read<std::string>(); - const uint64_t dimension = mesh_data.getAttribute("dimension").read<uint64_t>(); - - if (type != "polygonal") { - throw UnexpectedError("invalid connectivity type"); - } while (id > GlobalVariableManager::instance().getMeshId()) { GlobalVariableManager::instance().getAndIncrementMeshId(); } - switch (dimension) { - case 1: { - m_id_to_mesh_variant_map.insert({id, this->_readPolygonalMesh<1>(mesh_data)}); - break; - } - case 2: { - m_id_to_mesh_variant_map.insert({id, this->_readPolygonalMesh<2>(mesh_data)}); - break; - } - case 3: { - m_id_to_mesh_variant_map.insert({id, this->_readPolygonalMesh<3>(mesh_data)}); - break; - } - default: { - throw UnexpectedError("invalid mesh dimension " + std::to_string(dimension)); - } + if (type == "polygonal") { + const uint64_t dimension = mesh_data.getAttribute("dimension").read<uint64_t>(); + + switch (dimension) { + case 1: { + m_id_to_mesh_variant_map.insert({id, this->_readPolygonalMesh<1>(mesh_data)}); + break; + } + case 2: { + m_id_to_mesh_variant_map.insert({id, this->_readPolygonalMesh<2>(mesh_data)}); + break; + } + case 3: { + m_id_to_mesh_variant_map.insert({id, this->_readPolygonalMesh<3>(mesh_data)}); + break; + } + default: { + throw UnexpectedError("invalid mesh dimension " + std::to_string(dimension)); + } + } + } else if (type == "dual_mesh") { + const DualMeshType type_of_dual = mesh_data.getAttribute("type_of_dual").read<DualMeshType>(); + const size_t primal_mesh_id = mesh_data.getAttribute("primal_mesh_id").read<size_t>(); + + std::shared_ptr<const MeshVariant> primal_mesh_variant = m_id_to_mesh_variant_map.at(primal_mesh_id); + + std::visit( + [&](auto&& mesh) { + using MeshType = std::decay_t<decltype(*mesh)>; + if constexpr (std::is_same_v<MeshType, Mesh<1>>) { + if (type_of_dual == DualMeshType::Dual1D) { + m_id_to_mesh_variant_map.insert({id, DualMeshManager::instance().getDual1DMesh(primal_mesh_variant)}); + } else { + throw UnexpectedError("unexpected dual mesh type"); + } + } else if constexpr (std::is_same_v<MeshType, Mesh<2>> or std::is_same_v<MeshType, Mesh<3>>) { + if (type_of_dual == DualMeshType::Diamond) { + m_id_to_mesh_variant_map.insert( + {id, DualMeshManager::instance().getDiamondDualMesh(primal_mesh_variant)}); + } else if (type_of_dual == DualMeshType::Median) { + m_id_to_mesh_variant_map.insert( + {id, DualMeshManager::instance().getMedianDualMesh(primal_mesh_variant)}); + } else { + throw UnexpectedError("unexpected dual mesh type"); + } + } + }, + primal_mesh_variant->variant()); + + } else { + throw UnexpectedError("invalid mesh type"); } } } @@ -361,11 +398,11 @@ ResumingData::iConnectivity(const size_t connectivity_id) const const std::shared_ptr<const MeshVariant>& ResumingData::meshVariant(const size_t mesh_id) const { - auto i_id_to_connectivity = m_id_to_mesh_variant_map.find(mesh_id); - if (i_id_to_connectivity == m_id_to_mesh_variant_map.end()) { - throw UnexpectedError("cannot find connectivity of id " + std::to_string(mesh_id)); + auto i_id_to_mesh = m_id_to_mesh_variant_map.find(mesh_id); + if (i_id_to_mesh == m_id_to_mesh_variant_map.end()) { + throw UnexpectedError("cannot find mesh of id " + std::to_string(mesh_id)); } else { - return i_id_to_connectivity->second; + return i_id_to_mesh->second; } } -- GitLab