diff --git a/src/mesh/DualConnectivityManager.hpp b/src/mesh/DualConnectivityManager.hpp index 6389c5d459ac677295c09fcfce730cec2bd2f525..d82eabb72c7d42f215ffdf44cec579749f21e88c 100644 --- a/src/mesh/DualConnectivityManager.hpp +++ b/src/mesh/DualConnectivityManager.hpp @@ -44,7 +44,7 @@ class DualConnectivityManager } DualConnectivityInfo& operator=(const DualConnectivityInfo&) = default; - DualConnectivityInfo& operator=(DualConnectivityInfo&&) = delete; + DualConnectivityInfo& operator=(DualConnectivityInfo&&) = delete; DualConnectivityInfo() = default; DualConnectivityInfo(const DualConnectivityInfo&) = default; @@ -86,6 +86,12 @@ class DualConnectivityManager ~DualConnectivityManager() = default; public: + const auto& + primalToDualConnectivityInfoMap() const + { + return m_primal_to_dual_connectivity_info_map; + } + static void create(); static void destroy(); diff --git a/src/utils/checkpointing/Checkpoint.cpp b/src/utils/checkpointing/Checkpoint.cpp index 70166a86175bd5621bc545112db7ac17e28e668a..dbd10ca634f3a14aec59787f74e4b498f44e5ed3 100644 --- a/src/utils/checkpointing/Checkpoint.cpp +++ b/src/utils/checkpointing/Checkpoint.cpp @@ -25,10 +25,13 @@ #include <language/utils/ASTNodeDataTypeTraits.hpp> #include <language/utils/CheckpointResumeRepository.hpp> #include <language/utils/DataHandler.hpp> +#include <mesh/DualConnectivityManager.hpp> +#include <mesh/DualMeshManager.hpp> #include <mesh/MeshVariant.hpp> #include <utils/GlobalVariableManager.hpp> #include <utils/RandomEngine.hpp> +#include <utils/checkpointing/DualMeshTypeHFType.hpp> #include <utils/checkpointing/LinearSolverOptionsHFType.hpp> #include <utils/checkpointing/ParallelCheckerHFType.hpp> @@ -105,7 +108,21 @@ checkpoint() linear_solver_options_default_group.createAttribute("precond", default_options.precond()); } { - std::cout << rang::fgB::magenta << "Checkpoint DualConnectivityManager NIY" << rang::fg::reset << '\n'; + const auto& primal_to_dual_connectivity_info_map = + DualConnectivityManager::instance().primalToDualConnectivityInfoMap(); + for (auto&& primal_to_dual_connectivity_info : primal_to_dual_connectivity_info_map) { + const DualMeshType type_of_dual = primal_to_dual_connectivity_info.first.first; + const size_t primal_connectivity_id = primal_to_dual_connectivity_info.first.second->id(); + const size_t dual_connectivity_id = primal_to_dual_connectivity_info.second.dualConnectivity()->id(); + + HighFive::Group connectivity_group = + checkpoint.createGroup("connectivity/" + std::to_string(dual_connectivity_id)); + connectivity_group.createAttribute("type", std::string{"dual_connectivity"}); + connectivity_group.createAttribute("type_of_dual", type_of_dual); + 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'; } diff --git a/src/utils/checkpointing/CheckpointUtils.cpp b/src/utils/checkpointing/CheckpointUtils.cpp index d457e55f418d860cb9461185a593cedfe9abb252..fb0e9361ffb5f26ffc41ac7a31c699debd4bed85 100644 --- a/src/utils/checkpointing/CheckpointUtils.cpp +++ b/src/utils/checkpointing/CheckpointUtils.cpp @@ -100,11 +100,16 @@ writeConnectivity(const Connectivity<Dimension>& connectivity, HighFive::File& f if (not checkpoint_group.exist(connectivity_group_name)) { bool linked = false; for (auto group_name : file.listObjectNames()) { - if (file.exist(group_name + "/" + connectivity_group_name)) { - checkpoint_group.createHardLink(connectivity_group_name, - file.getGroup(group_name + "/" + connectivity_group_name)); - linked = true; - break; + const std::string stored_connectivity_group_name = group_name + "/" + connectivity_group_name; + if (file.exist(stored_connectivity_group_name)) { + HighFive::Group stored_connectivity_group = file.getGroup(stored_connectivity_group_name); + + const std::string type_name = stored_connectivity_group.getAttribute("type").read<std::string>(); + if (type_name != "dual_connectivity") { + checkpoint_group.createHardLink(connectivity_group_name, file.getGroup(stored_connectivity_group_name)); + linked = true; + break; + } } } diff --git a/src/utils/checkpointing/DualMeshTypeHFType.hpp b/src/utils/checkpointing/DualMeshTypeHFType.hpp new file mode 100644 index 0000000000000000000000000000000000000000..14010b647f13aa978446ccf9723fd7e79b232cd4 --- /dev/null +++ b/src/utils/checkpointing/DualMeshTypeHFType.hpp @@ -0,0 +1,14 @@ +#ifndef DUAL_MESH_TYPE_HF_TYPE_HPP +#define DUAL_MESH_TYPE_HF_TYPE_HPP + +#include <mesh/DualConnectivityManager.hpp> +#include <utils/checkpointing/CheckpointUtils.hpp> + +HighFive::EnumType<DualMeshType> PUGS_INLINE +create_enum_DualMeshType_type() +{ + return {{"dual1d", DualMeshType::Dual1D}, {"diamond", DualMeshType::Diamond}, {"median", DualMeshType::Median}}; +} +HIGHFIVE_REGISTER_TYPE(DualMeshType, create_enum_DualMeshType_type) + +#endif // DUAL_MESH_TYPE_HF_TYPE_HPP diff --git a/src/utils/checkpointing/LinearSolverOptionsHFType.hpp b/src/utils/checkpointing/LinearSolverOptionsHFType.hpp index ce95f2a90519a1b00e1f1f28849908c7176468ac..127fdddc0dfa292d1228d12bf3cd6d7ca39ce4e3 100644 --- a/src/utils/checkpointing/LinearSolverOptionsHFType.hpp +++ b/src/utils/checkpointing/LinearSolverOptionsHFType.hpp @@ -1,5 +1,5 @@ -#ifndef LINEAR_SOLVER_OPTIONS_H_F_TYPE_HPP -#define LINEAR_SOLVER_OPTIONS_H_F_TYPE_HPP +#ifndef LINEAR_SOLVER_OPTIONS_HF_TYPE_HPP +#define LINEAR_SOLVER_OPTIONS_HF_TYPE_HPP #include <algebra/LinearSolverOptions.hpp> #include <utils/checkpointing/CheckpointUtils.hpp> @@ -34,4 +34,4 @@ create_enum_LSOptions_precond_type() } HIGHFIVE_REGISTER_TYPE(LSPrecond, create_enum_LSOptions_precond_type) -#endif // LINEAR_SOLVER_OPTIONS_H_F_TYPE_HPP +#endif // LINEAR_SOLVER_OPTIONS_HF_TYPE_HPP diff --git a/src/utils/checkpointing/Resume.cpp b/src/utils/checkpointing/Resume.cpp index 757458fc45fbed692b015c6407dff89cca752196..b5e65316112c1c41774c2bf00993aea3b301f6b3 100644 --- a/src/utils/checkpointing/Resume.cpp +++ b/src/utils/checkpointing/Resume.cpp @@ -92,7 +92,6 @@ resume() default_options.precond() = linear_solver_options_default_group.getAttribute("precond").read<LSPrecond>(); } { - std::cout << rang::fgB::magenta << "Resume DualConnectivityManager NIY" << rang::fg::reset << '\n'; std::cout << rang::fgB::magenta << "Resume DualMeshManager NIY" << rang::fg::reset << '\n'; } diff --git a/src/utils/checkpointing/ResumingData.cpp b/src/utils/checkpointing/ResumingData.cpp index 8e121cd1c3614c799e57858e0539a764cf3b95bd..a2d6c98b293d4927ccbcab08406926711f803914 100644 --- a/src/utils/checkpointing/ResumingData.cpp +++ b/src/utils/checkpointing/ResumingData.cpp @@ -2,8 +2,10 @@ #include <language/utils/SymbolTable.hpp> #include <mesh/ConnectivityDescriptor.hpp> +#include <mesh/DualConnectivityManager.hpp> #include <mesh/Mesh.hpp> #include <utils/Exceptions.hpp> +#include <utils/checkpointing/DualMeshTypeHFType.hpp> #include <utils/checkpointing/RefItemListHFType.hpp> #include <utils/checkpointing/ResumeUtils.hpp> @@ -23,126 +25,183 @@ ResumingData::_getConnectivityList(const HighFive::Group& checkpoint) for (auto [id, name] : id_name_map) { HighFive::Group connectivity_data = connectivity_group.getGroup(name); - const uint64_t dimension = connectivity_data.getAttribute("dimension").read<uint64_t>(); const std::string type = connectivity_data.getAttribute("type").read<std::string>(); - if (type != "unstructured") { - throw UnexpectedError("invalid connectivity type: " + type); + while (id > GlobalVariableManager::instance().getConnectivityId()) { + GlobalVariableManager::instance().getAndIncrementConnectivityId(); } - ConnectivityDescriptor descriptor; - descriptor.setCellTypeVector(readArray<CellType>(connectivity_data, "cell_type")); - descriptor.setCellNumberVector(readArray<int>(connectivity_data, "cell_numbers")); - descriptor.setNodeNumberVector(readArray<int>(connectivity_data, "node_numbers")); + if (m_id_to_iconnectivity_map.contains(id)) { + throw UnexpectedError("connectivity of id " + std::to_string(id) + " already defined!"); + } - descriptor.setCellOwnerVector(readArray<int>(connectivity_data, "cell_owner")); - descriptor.setNodeOwnerVector(readArray<int>(connectivity_data, "node_owner")); + if (type == "unstructured") { + const uint64_t dimension = connectivity_data.getAttribute("dimension").read<uint64_t>(); - using index_type = typename ConnectivityMatrix::IndexType; + ConnectivityDescriptor descriptor; + descriptor.setCellTypeVector(readArray<CellType>(connectivity_data, "cell_type")); + descriptor.setCellNumberVector(readArray<int>(connectivity_data, "cell_numbers")); + descriptor.setNodeNumberVector(readArray<int>(connectivity_data, "node_numbers")); - descriptor.setCellToNodeMatrix( - ConnectivityMatrix{readArray<index_type>(connectivity_data, "cell_to_node_matrix_rowsMap"), - readArray<index_type>(connectivity_data, "cell_to_node_matrix_values")}); + descriptor.setCellOwnerVector(readArray<int>(connectivity_data, "cell_owner")); + descriptor.setNodeOwnerVector(readArray<int>(connectivity_data, "node_owner")); - if (dimension > 1) { - descriptor.setFaceNumberVector(readArray<int>(connectivity_data, "face_numbers")); - descriptor.setFaceOwnerVector(readArray<int>(connectivity_data, "face_owner")); + using index_type = typename ConnectivityMatrix::IndexType; - descriptor.setCellToFaceMatrix( - ConnectivityMatrix{readArray<index_type>(connectivity_data, "cell_to_face_matrix_rowsMap"), - readArray<index_type>(connectivity_data, "cell_to_face_matrix_values")}); + descriptor.setCellToNodeMatrix( + ConnectivityMatrix{readArray<index_type>(connectivity_data, "cell_to_node_matrix_rowsMap"), + readArray<index_type>(connectivity_data, "cell_to_node_matrix_values")}); - descriptor.setFaceToNodeMatrix( - ConnectivityMatrix{readArray<index_type>(connectivity_data, "face_to_node_matrix_rowsMap"), - readArray<index_type>(connectivity_data, "face_to_node_matrix_values")}); + if (dimension > 1) { + descriptor.setFaceNumberVector(readArray<int>(connectivity_data, "face_numbers")); + descriptor.setFaceOwnerVector(readArray<int>(connectivity_data, "face_owner")); - descriptor.setNodeToFaceMatrix( - ConnectivityMatrix{readArray<index_type>(connectivity_data, "node_to_face_matrix_rowsMap"), - readArray<index_type>(connectivity_data, "node_to_face_matrix_values")}); + descriptor.setCellToFaceMatrix( + ConnectivityMatrix{readArray<index_type>(connectivity_data, "cell_to_face_matrix_rowsMap"), + readArray<index_type>(connectivity_data, "cell_to_face_matrix_values")}); - descriptor.setCellFaceIsReversed(readArray<bool>(connectivity_data, "cell_face_is_reversed")); - } + descriptor.setFaceToNodeMatrix( + ConnectivityMatrix{readArray<index_type>(connectivity_data, "face_to_node_matrix_rowsMap"), + readArray<index_type>(connectivity_data, "face_to_node_matrix_values")}); - if (dimension > 2) { - descriptor.setEdgeNumberVector(readArray<int>(connectivity_data, "edge_numbers")); - descriptor.setEdgeOwnerVector(readArray<int>(connectivity_data, "edge_owner")); + descriptor.setNodeToFaceMatrix( + ConnectivityMatrix{readArray<index_type>(connectivity_data, "node_to_face_matrix_rowsMap"), + readArray<index_type>(connectivity_data, "node_to_face_matrix_values")}); - descriptor.setCellToEdgeMatrix( - ConnectivityMatrix{readArray<index_type>(connectivity_data, "cell_to_edge_matrix_rowsMap"), - readArray<index_type>(connectivity_data, "cell_to_edge_matrix_values")}); + descriptor.setCellFaceIsReversed(readArray<bool>(connectivity_data, "cell_face_is_reversed")); + } - descriptor.setFaceToEdgeMatrix( - ConnectivityMatrix{readArray<index_type>(connectivity_data, "face_to_edge_matrix_rowsMap"), - readArray<index_type>(connectivity_data, "face_to_edge_matrix_values")}); + if (dimension > 2) { + descriptor.setEdgeNumberVector(readArray<int>(connectivity_data, "edge_numbers")); + descriptor.setEdgeOwnerVector(readArray<int>(connectivity_data, "edge_owner")); - descriptor.setEdgeToNodeMatrix( - ConnectivityMatrix{readArray<index_type>(connectivity_data, "edge_to_node_matrix_rowsMap"), - readArray<index_type>(connectivity_data, "edge_to_node_matrix_values")}); + descriptor.setCellToEdgeMatrix( + ConnectivityMatrix{readArray<index_type>(connectivity_data, "cell_to_edge_matrix_rowsMap"), + readArray<index_type>(connectivity_data, "cell_to_edge_matrix_values")}); - descriptor.setNodeToEdgeMatrix( - ConnectivityMatrix{readArray<index_type>(connectivity_data, "node_to_edge_matrix_rowsMap"), - readArray<index_type>(connectivity_data, "node_to_edge_matrix_values")}); + descriptor.setFaceToEdgeMatrix( + ConnectivityMatrix{readArray<index_type>(connectivity_data, "face_to_edge_matrix_rowsMap"), + readArray<index_type>(connectivity_data, "face_to_edge_matrix_values")}); - descriptor.setFaceEdgeIsReversed(readArray<bool>(connectivity_data, "face_edge_is_reversed")); - } + descriptor.setEdgeToNodeMatrix( + ConnectivityMatrix{readArray<index_type>(connectivity_data, "edge_to_node_matrix_rowsMap"), + readArray<index_type>(connectivity_data, "edge_to_node_matrix_values")}); - if (connectivity_data.exist("item_ref_list")) { - HighFive::Group item_group = connectivity_data.getGroup("item_ref_list"); - for (auto item_type_name : item_group.listObjectNames()) { - HighFive::Group item_ref_name_list = item_group.getGroup(item_type_name); - - for (auto item_ref_list_name : item_ref_name_list.listObjectNames()) { - HighFive::Group item_ref_list_data = item_ref_name_list.getGroup(item_ref_list_name); - - RefId ref_id(item_ref_list_data.getAttribute("tag_number").read<uint64_t>(), - item_ref_list_data.getAttribute("tag_name").read<std::string>()); - - RefItemListBase::Type ref_item_list_type = - item_ref_list_data.getAttribute("type").read<RefItemListBase::Type>(); - - if (item_type_name == "cell") { - descriptor.addRefItemList( - RefItemList<ItemType::cell>{ref_id, readArray<CellId>(item_ref_list_data, "list"), ref_item_list_type}); - } else if (item_type_name == "face") { - descriptor.addRefItemList( - RefItemList<ItemType::face>{ref_id, readArray<FaceId>(item_ref_list_data, "list"), ref_item_list_type}); - } else if (item_type_name == "edge") { - descriptor.addRefItemList( - RefItemList<ItemType::edge>{ref_id, readArray<EdgeId>(item_ref_list_data, "list"), ref_item_list_type}); - } else if (item_type_name == "node") { - descriptor.addRefItemList( - RefItemList<ItemType::node>{ref_id, readArray<NodeId>(item_ref_list_data, "list"), ref_item_list_type}); - } else { - throw UnexpectedError("invalid item type: " + item_type_name); + descriptor.setNodeToEdgeMatrix( + ConnectivityMatrix{readArray<index_type>(connectivity_data, "node_to_edge_matrix_rowsMap"), + readArray<index_type>(connectivity_data, "node_to_edge_matrix_values")}); + + descriptor.setFaceEdgeIsReversed(readArray<bool>(connectivity_data, "face_edge_is_reversed")); + } + + if (connectivity_data.exist("item_ref_list")) { + HighFive::Group item_group = connectivity_data.getGroup("item_ref_list"); + for (auto item_type_name : item_group.listObjectNames()) { + HighFive::Group item_ref_name_list = item_group.getGroup(item_type_name); + + for (auto item_ref_list_name : item_ref_name_list.listObjectNames()) { + HighFive::Group item_ref_list_data = item_ref_name_list.getGroup(item_ref_list_name); + + RefId ref_id(item_ref_list_data.getAttribute("tag_number").read<uint64_t>(), + item_ref_list_data.getAttribute("tag_name").read<std::string>()); + + RefItemListBase::Type ref_item_list_type = + item_ref_list_data.getAttribute("type").read<RefItemListBase::Type>(); + + if (item_type_name == "cell") { + descriptor.addRefItemList(RefItemList<ItemType::cell>{ref_id, + readArray<CellId>(item_ref_list_data, "list"), + ref_item_list_type}); + } else if (item_type_name == "face") { + descriptor.addRefItemList(RefItemList<ItemType::face>{ref_id, + readArray<FaceId>(item_ref_list_data, "list"), + ref_item_list_type}); + } else if (item_type_name == "edge") { + descriptor.addRefItemList(RefItemList<ItemType::edge>{ref_id, + readArray<EdgeId>(item_ref_list_data, "list"), + ref_item_list_type}); + } else if (item_type_name == "node") { + descriptor.addRefItemList(RefItemList<ItemType::node>{ref_id, + readArray<NodeId>(item_ref_list_data, "list"), + ref_item_list_type}); + } else { + throw UnexpectedError("invalid item type: " + item_type_name); + } } } } - } - while (id > GlobalVariableManager::instance().getConnectivityId()) { - GlobalVariableManager::instance().getAndIncrementConnectivityId(); - } + switch (dimension) { + case 1: { + m_id_to_iconnectivity_map.insert({id, Connectivity<1>::build(descriptor)}); + break; + } + case 2: { + m_id_to_iconnectivity_map.insert({id, Connectivity<2>::build(descriptor)}); + break; + } + case 3: { + m_id_to_iconnectivity_map.insert({id, Connectivity<3>::build(descriptor)}); + break; + } + default: { + throw UnexpectedError("invalid dimension " + std::to_string(dimension)); + } + } + } else if (type == "dual_connectivity") { + 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>(); - if (m_id_to_iconnectivity_map.contains(id)) { - throw UnexpectedError("connectivity of id " + std::to_string(id) + " already defined!"); - } + std::cout << "reading " << id << " " << ::name(type_of_dual) << " of " << primal_connectivity_id << '\n'; - switch (dimension) { - case 1: { - m_id_to_iconnectivity_map.insert({id, Connectivity<1>::build(descriptor)}); - break; - } - case 2: { - m_id_to_iconnectivity_map.insert({id, Connectivity<2>::build(descriptor)}); - break; - } - case 3: { - m_id_to_iconnectivity_map.insert({id, Connectivity<3>::build(descriptor)}); - break; - } - default: { - throw UnexpectedError("invalid dimension " + std::to_string(dimension)); - } + std::shared_ptr<const IConnectivity> iprimal_connectivity = + m_id_to_iconnectivity_map.at(primal_connectivity_id); + + switch (iprimal_connectivity->dimension()) { + case 1: { + if (type_of_dual != DualMeshType::Dual1D) { + throw UnexpectedError("unexpected dual mesh type"); + } + + const Connectivity<1>& primal_connectivity = dynamic_cast<const Connectivity<1>&>(*iprimal_connectivity); + m_id_to_iconnectivity_map.insert( + {id, DualConnectivityManager::instance().getDual1DConnectivity(primal_connectivity)}); + break; + } + case 2: { + const Connectivity<2>& primal_connectivity = dynamic_cast<const Connectivity<2>&>(*iprimal_connectivity); + + if (type_of_dual == DualMeshType::Diamond) { + m_id_to_iconnectivity_map.insert( + {id, DualConnectivityManager::instance().getDiamondDualConnectivity(primal_connectivity)}); + } else if (type_of_dual == DualMeshType::Median) { + m_id_to_iconnectivity_map.insert( + {id, DualConnectivityManager::instance().getMedianDualConnectivity(primal_connectivity)}); + } else { + throw UnexpectedError("unexpected dual mesh type"); + } + break; + } + case 3: { + const Connectivity<3>& primal_connectivity = dynamic_cast<const Connectivity<3>&>(*iprimal_connectivity); + + if (type_of_dual == DualMeshType::Diamond) { + m_id_to_iconnectivity_map.insert( + {id, DualConnectivityManager::instance().getDiamondDualConnectivity(primal_connectivity)}); + } else if (type_of_dual == DualMeshType::Median) { + m_id_to_iconnectivity_map.insert( + {id, DualConnectivityManager::instance().getMedianDualConnectivity(primal_connectivity)}); + } else { + throw UnexpectedError("unexpected dual mesh type"); + } + break; + } + default: { + throw UnexpectedError("unexpected dimension"); + } + } + } else { + throw UnexpectedError("invalid connectivity type: " + type); } } }