From c28bce2ba6d268bd4b06b16b57d8aaa5247e64fa Mon Sep 17 00:00:00 2001
From: Stephane Del Pino <stephane.delpino44@gmail.com>
Date: Thu, 11 Apr 2024 00:19:08 +0200
Subject: [PATCH] Add checkpoint/resume for IBoundaryDescriptor

---
 src/language/modules/MeshModule.cpp           | 13 +++++++
 src/mesh/NamedBoundaryDescriptor.hpp          |  6 +++
 src/mesh/NumberedBoundaryDescriptor.hpp       |  6 +++
 src/utils/checkpointing/CheckpointUtils.cpp   | 37 +++++++++++++++++++
 src/utils/checkpointing/CheckpointUtils.hpp   |  6 +++
 .../IBoundaryDescriptorHFType.hpp             | 14 +++++++
 src/utils/checkpointing/ResumeUtils.cpp       | 34 ++++++++++++++++-
 src/utils/checkpointing/ResumeUtils.hpp       |  1 +
 8 files changed, 116 insertions(+), 1 deletion(-)
 create mode 100644 src/utils/checkpointing/IBoundaryDescriptorHFType.hpp

diff --git a/src/language/modules/MeshModule.cpp b/src/language/modules/MeshModule.cpp
index 32836f21e..40d5d2304 100644
--- a/src/language/modules/MeshModule.cpp
+++ b/src/language/modules/MeshModule.cpp
@@ -316,4 +316,17 @@ MeshModule::registerCheckpointResume() const
                          }),
                          std::function([](const std::string& symbol_name, const HighFive::Group& symbol_table_group)
                                          -> EmbeddedData { return readMesh(symbol_name, symbol_table_group); }));
+
+  CheckpointResumeRepository::instance()
+    .addCheckpointResume(ast_node_data_type_from<std::shared_ptr<const IBoundaryDescriptor>>,
+                         std::function([](const std::string& symbol_name, const EmbeddedData& embedded_data,
+                                          HighFive::File& file, HighFive::Group& checkpoint_group,
+                                          HighFive::Group& symbol_table_group) {
+                           writeIBoundaryDescriptor(symbol_name, embedded_data, file, checkpoint_group,
+                                                    symbol_table_group);
+                         }),
+                         std::function([](const std::string& symbol_name,
+                                          const HighFive::Group& symbol_table_group) -> EmbeddedData {
+                           return readIBoundaryDescriptor(symbol_name, symbol_table_group);
+                         }));
 }
diff --git a/src/mesh/NamedBoundaryDescriptor.hpp b/src/mesh/NamedBoundaryDescriptor.hpp
index 7ee732c59..34ef2370f 100644
--- a/src/mesh/NamedBoundaryDescriptor.hpp
+++ b/src/mesh/NamedBoundaryDescriptor.hpp
@@ -19,6 +19,12 @@ class NamedBoundaryDescriptor final : public IBoundaryDescriptor
   }
 
  public:
+  [[nodiscard]] const std::string&
+  name() const
+  {
+    return m_name;
+  }
+
   [[nodiscard]] bool
   operator==(const RefId& ref_id) const final
   {
diff --git a/src/mesh/NumberedBoundaryDescriptor.hpp b/src/mesh/NumberedBoundaryDescriptor.hpp
index 2abab9395..9367d6746 100644
--- a/src/mesh/NumberedBoundaryDescriptor.hpp
+++ b/src/mesh/NumberedBoundaryDescriptor.hpp
@@ -24,6 +24,12 @@ class NumberedBoundaryDescriptor final : public IBoundaryDescriptor
   }
 
  public:
+  [[nodiscard]] unsigned int
+  number() const
+  {
+    return m_number;
+  }
+
   [[nodiscard]] Type
   type() const final
   {
diff --git a/src/utils/checkpointing/CheckpointUtils.cpp b/src/utils/checkpointing/CheckpointUtils.cpp
index aace16bdd..338ceee96 100644
--- a/src/utils/checkpointing/CheckpointUtils.cpp
+++ b/src/utils/checkpointing/CheckpointUtils.cpp
@@ -4,9 +4,13 @@
 #include <language/utils/ASTNodeDataTypeTraits.hpp>
 #include <language/utils/DataHandler.hpp>
 #include <mesh/MeshVariant.hpp>
+#include <utils/checkpointing/IBoundaryDescriptorHFType.hpp>
 #include <utils/checkpointing/RefItemListHFType.hpp>
 
+#include <mesh/IBoundaryDescriptor.hpp>
 #include <mesh/Mesh.hpp>
+#include <mesh/NamedBoundaryDescriptor.hpp>
+#include <mesh/NumberedBoundaryDescriptor.hpp>
 
 template <ItemType item_type, size_t Dimension>
 void
@@ -178,3 +182,36 @@ writeMesh(const std::string& symbol_name,
     },
     mesh_v->variant());
 }
+
+void
+writeIBoundaryDescriptor(const std::string& symbol_name,
+                         const EmbeddedData& embedded_data,
+                         HighFive::File&,
+                         HighFive::Group&,
+                         HighFive::Group& symbol_table_group)
+{
+  HighFive::Group variable_group = symbol_table_group.createGroup("embedded/" + symbol_name);
+
+  std::shared_ptr<const IBoundaryDescriptor> iboundary_descriptor_p =
+    dynamic_cast<const DataHandler<const IBoundaryDescriptor>&>(embedded_data.get()).data_ptr();
+
+  const IBoundaryDescriptor& iboundary_descriptor = *iboundary_descriptor_p;
+
+  variable_group.createAttribute("type", dataTypeName(ast_node_data_type_from<decltype(iboundary_descriptor_p)>));
+  variable_group.createAttribute("iboundary_descriptor_type", iboundary_descriptor.type());
+
+  switch (iboundary_descriptor.type()) {
+  case IBoundaryDescriptor::Type::named: {
+    const NamedBoundaryDescriptor& named_boundary_descriptor =
+      dynamic_cast<const NamedBoundaryDescriptor&>(iboundary_descriptor);
+    variable_group.createAttribute("name", named_boundary_descriptor.name());
+    break;
+  }
+  case IBoundaryDescriptor::Type::numbered: {
+    const NumberedBoundaryDescriptor& numbered_boundary_descriptor =
+      dynamic_cast<const NumberedBoundaryDescriptor&>(iboundary_descriptor);
+    variable_group.createAttribute("number", numbered_boundary_descriptor.number());
+    break;
+  }
+  }
+}
diff --git a/src/utils/checkpointing/CheckpointUtils.hpp b/src/utils/checkpointing/CheckpointUtils.hpp
index 9b79c8ec9..e9b716796 100644
--- a/src/utils/checkpointing/CheckpointUtils.hpp
+++ b/src/utils/checkpointing/CheckpointUtils.hpp
@@ -48,4 +48,10 @@ void writeMesh(const std::string& symbol_name,
                HighFive::Group& checkpoint_group,
                HighFive::Group& symbol_table_group);
 
+void writeIBoundaryDescriptor(const std::string& symbol_name,
+                              const EmbeddedData& embedded_data,
+                              HighFive::File& file,
+                              HighFive::Group& checkpoint_group,
+                              HighFive::Group& symbol_table_group);
+
 #endif   // CHECKPOINT_UTILS_HPP
diff --git a/src/utils/checkpointing/IBoundaryDescriptorHFType.hpp b/src/utils/checkpointing/IBoundaryDescriptorHFType.hpp
new file mode 100644
index 000000000..ea67598c7
--- /dev/null
+++ b/src/utils/checkpointing/IBoundaryDescriptorHFType.hpp
@@ -0,0 +1,14 @@
+#ifndef I_BOUNDARY_DESCRIPTOR_HF_TYPE_HPP
+#define I_BOUNDARY_DESCRIPTOR_HF_TYPE_HPP
+
+#include <mesh/IBoundaryDescriptor.hpp>
+#include <utils/checkpointing/CheckpointUtils.hpp>
+
+HighFive::EnumType<IBoundaryDescriptor::Type> PUGS_INLINE
+create_enum_i_boundary_descriptor_type()
+{
+  return {{"named", IBoundaryDescriptor::Type::named}, {"numbered", IBoundaryDescriptor::Type::numbered}};
+}
+HIGHFIVE_REGISTER_TYPE(IBoundaryDescriptor::Type, create_enum_i_boundary_descriptor_type);
+
+#endif   // I_BOUNDARY_DESCRIPTOR_HF_TYPE_HPP
diff --git a/src/utils/checkpointing/ResumeUtils.cpp b/src/utils/checkpointing/ResumeUtils.cpp
index 1054c2778..32317896c 100644
--- a/src/utils/checkpointing/ResumeUtils.cpp
+++ b/src/utils/checkpointing/ResumeUtils.cpp
@@ -2,6 +2,9 @@
 
 #include <language/utils/DataHandler.hpp>
 #include <language/utils/SymbolTable.hpp>
+#include <mesh/NamedBoundaryDescriptor.hpp>
+#include <mesh/NumberedBoundaryDescriptor.hpp>
+#include <utils/checkpointing/IBoundaryDescriptorHFType.hpp>
 #include <utils/checkpointing/ResumingData.hpp>
 
 EmbeddedData
@@ -11,5 +14,34 @@ readMesh(const std::string& symbol_name, const HighFive::Group& symbol_table_gro
 
   const size_t mesh_id = mesh_group.getAttribute("id").read<uint64_t>();
 
-  return {std::make_shared<DataHandler<const MeshVariant>>(ResumingData::instance().meshVariant(mesh_id))};
+  return EmbeddedData{std::make_shared<DataHandler<const MeshVariant>>(ResumingData::instance().meshVariant(mesh_id))};
+}
+
+EmbeddedData
+readIBoundaryDescriptor(const std::string& symbol_name, const HighFive::Group& symbol_table_group)
+{
+  const HighFive::Group iboundarydecriptor_group = symbol_table_group.getGroup("embedded/" + symbol_name);
+  const IBoundaryDescriptor::Type iboundary_descriptor_type =
+    iboundarydecriptor_group.getAttribute("iboundary_descriptor_type").read<IBoundaryDescriptor::Type>();
+
+  EmbeddedData embedded_data;
+
+  switch (iboundary_descriptor_type) {
+  case IBoundaryDescriptor::Type::named: {
+    const std::string name = iboundarydecriptor_group.getAttribute("name").read<std::string>();
+
+    embedded_data = {
+      std::make_shared<DataHandler<const IBoundaryDescriptor>>(std::make_shared<const NamedBoundaryDescriptor>(name))};
+    break;
+  }
+  case IBoundaryDescriptor::Type::numbered: {
+    const unsigned int number = iboundarydecriptor_group.getAttribute("number").read<unsigned int>();
+
+    embedded_data = {std::make_shared<DataHandler<const IBoundaryDescriptor>>(
+      std::make_shared<const NumberedBoundaryDescriptor>(number))};
+    break;
+  }
+  }
+
+  return embedded_data;
 }
diff --git a/src/utils/checkpointing/ResumeUtils.hpp b/src/utils/checkpointing/ResumeUtils.hpp
index 848fc9100..ce2423256 100644
--- a/src/utils/checkpointing/ResumeUtils.hpp
+++ b/src/utils/checkpointing/ResumeUtils.hpp
@@ -29,5 +29,6 @@ read(const HighFive::Group& group, const std::string& name)
 }
 
 EmbeddedData readMesh(const std::string& symbol_name, const HighFive::Group& symbol_table_group);
+EmbeddedData readIBoundaryDescriptor(const std::string& symbol_name, const HighFive::Group& symbol_table_group);
 
 #endif   // RESUME_UTILS_HPP
-- 
GitLab