Skip to content
Snippets Groups Projects
Select Git revision
  • f0c17b59be66e8f7b777d1c93ee10ed3a60791a3
  • 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

ScalarDiamondScheme.cpp

Blame
  • ResumeUtils.cpp 28.60 KiB
    #include <utils/checkpointing/ResumeUtils.hpp>
    
    #include <analysis/GaussLegendreQuadratureDescriptor.hpp>
    #include <analysis/GaussLobattoQuadratureDescriptor.hpp>
    #include <analysis/GaussQuadratureDescriptor.hpp>
    #include <language/utils/DataHandler.hpp>
    #include <language/utils/OFStream.hpp>
    #include <language/utils/SymbolTable.hpp>
    #include <mesh/ItemArrayVariant.hpp>
    #include <mesh/ItemValueVariant.hpp>
    #include <mesh/NamedBoundaryDescriptor.hpp>
    #include <mesh/NamedInterfaceDescriptor.hpp>
    #include <mesh/NamedZoneDescriptor.hpp>
    #include <mesh/NumberedBoundaryDescriptor.hpp>
    #include <mesh/NumberedInterfaceDescriptor.hpp>
    #include <mesh/NumberedZoneDescriptor.hpp>
    #include <output/NamedDiscreteFunction.hpp>
    #include <output/NamedItemArrayVariant.hpp>
    #include <output/NamedItemValueVariant.hpp>
    #include <scheme/AxisBoundaryConditionDescriptor.hpp>
    #include <scheme/DirichletBoundaryConditionDescriptor.hpp>
    #include <scheme/DiscreteFunctionDescriptorP0.hpp>
    #include <scheme/DiscreteFunctionDescriptorP0Vector.hpp>
    #include <scheme/DiscreteFunctionP0.hpp>
    #include <scheme/DiscreteFunctionVariant.hpp>
    #include <scheme/ExternalBoundaryConditionDescriptor.hpp>
    #include <scheme/FixedBoundaryConditionDescriptor.hpp>
    #include <scheme/FourierBoundaryConditionDescriptor.hpp>
    #include <scheme/FreeBoundaryConditionDescriptor.hpp>
    #include <scheme/IBoundaryConditionDescriptor.hpp>
    #include <scheme/InflowBoundaryConditionDescriptor.hpp>
    #include <scheme/NeumannBoundaryConditionDescriptor.hpp>
    #include <scheme/OutflowBoundaryConditionDescriptor.hpp>
    #include <scheme/SymmetryBoundaryConditionDescriptor.hpp>
    #include <utils/checkpointing/DiscreteFunctionTypeHFType.hpp>
    #include <utils/checkpointing/IBoundaryConditionDescriptorHFType.hpp>
    #include <utils/checkpointing/IBoundaryDescriptorHFType.hpp>
    #include <utils/checkpointing/IInterfaceDescriptorHFType.hpp>
    #include <utils/checkpointing/INamedDiscreteDataHF.hpp>
    #include <utils/checkpointing/IZoneDescriptorHFType.hpp>
    #include <utils/checkpointing/ItemTypeHFType.hpp>
    #include <utils/checkpointing/OStreamTypeHFType.hpp>
    #include <utils/checkpointing/QuadratureTypeHFType.hpp>
    #include <utils/checkpointing/ResumingData.hpp>
    
    std::shared_ptr<ItemArrayVariant> readItemArrayVariant(const HighFive::Group& item_array_variant_group);
    std::shared_ptr<ItemValueVariant> readItemValueVariant(const HighFive::Group& item_value_variant_group);
    std::shared_ptr<DiscreteFunctionVariant> readDiscreteFunctionVariant(const HighFive::Group& discrete_function_group);
    
    template <typename T, ItemType item_type>
    ItemValue<T, item_type>
    readItemValue(const HighFive::Group& group, const std::string& name, const IConnectivity& connectivity)
    {
      return {connectivity, readArray<T>(group, name)};
    }
    
    template <typename T, ItemType item_type>
    ItemArray<T, item_type>
    readItemArray(const HighFive::Group& group, const std::string& name, const IConnectivity& connectivity)
    {
      return {connectivity, readTable<T>(group, name)};
    }
    
    std::shared_ptr<const IBoundaryDescriptor>
    readIBoundaryDescriptor(const HighFive::Group& iboundarydescriptor_group)
    {
      const IBoundaryDescriptor::Type iboundary_descriptor_type =
        iboundarydescriptor_group.getAttribute("iboundary_descriptor_type").read<IBoundaryDescriptor::Type>();
    
      std::shared_ptr<const IBoundaryDescriptor> i_boundary_descriptor;
    
      switch (iboundary_descriptor_type) {
      case IBoundaryDescriptor::Type::named: {
        const std::string name = iboundarydescriptor_group.getAttribute("name").read<std::string>();
        i_boundary_descriptor  = std::make_shared<const NamedBoundaryDescriptor>(name);
        break;
      }
      case IBoundaryDescriptor::Type::numbered: {
        const unsigned int number = iboundarydescriptor_group.getAttribute("number").read<unsigned int>();
        i_boundary_descriptor     = std::make_shared<const NumberedBoundaryDescriptor>(number);
        break;
      }
      }
    
      return i_boundary_descriptor;
    }
    
    EmbeddedData
    readIBoundaryConditionDescriptor(const std::string& symbol_name, const HighFive::Group& symbol_table_group)
    {
      const HighFive::Group iboundaryconditiondecriptor_group = symbol_table_group.getGroup("embedded/" + symbol_name);
      const IBoundaryConditionDescriptor::Type iboundary_condition_descriptor_type =
        iboundaryconditiondecriptor_group.getAttribute("iboundary_condition_descriptor_type")
          .read<IBoundaryConditionDescriptor::Type>();
    
      HighFive::Group boundary_group = iboundaryconditiondecriptor_group.getGroup("boundary");
      auto i_boundary_descriptor     = readIBoundaryDescriptor(boundary_group);
    
      std::shared_ptr<const IBoundaryConditionDescriptor> bc_descriptor;
    
      switch (iboundary_condition_descriptor_type) {
      case IBoundaryConditionDescriptor::Type::axis: {
        bc_descriptor = std::make_shared<const AxisBoundaryConditionDescriptor>(i_boundary_descriptor);
        break;
      }
      case IBoundaryConditionDescriptor::Type::dirichlet: {
        const std::string name = iboundaryconditiondecriptor_group.getAttribute("name").read<std::string>();
        const size_t rhs_id    = iboundaryconditiondecriptor_group.getAttribute("rhs_function_id").read<size_t>();
    
        bc_descriptor =
          std::make_shared<const DirichletBoundaryConditionDescriptor>(name, i_boundary_descriptor,
                                                                       *ResumingData::instance().functionSymbolId(rhs_id));
        break;
      }
      case IBoundaryConditionDescriptor::Type::external: {
        throw NotImplementedError("checkpoint/resume with sockets");
    
        break;
      }
      case IBoundaryConditionDescriptor::Type::fourier: {
        const std::string name = iboundaryconditiondecriptor_group.getAttribute("name").read<std::string>();
        const size_t rhs_id    = iboundaryconditiondecriptor_group.getAttribute("rhs_function_id").read<size_t>();
        const size_t mass_id   = iboundaryconditiondecriptor_group.getAttribute("mass_function_id").read<size_t>();
    
        bc_descriptor =
          std::make_shared<const FourierBoundaryConditionDescriptor>(name, i_boundary_descriptor,
                                                                     *ResumingData::instance().functionSymbolId(mass_id),
                                                                     *ResumingData::instance().functionSymbolId(rhs_id));
        break;
      }
      case IBoundaryConditionDescriptor::Type::fixed: {
        bc_descriptor = std::make_shared<const FixedBoundaryConditionDescriptor>(i_boundary_descriptor);
        break;
      }
      case IBoundaryConditionDescriptor::Type::free: {
        bc_descriptor = std::make_shared<const FreeBoundaryConditionDescriptor>(i_boundary_descriptor);
        break;
      }
      case IBoundaryConditionDescriptor::Type::inflow: {
        const size_t function_id = iboundaryconditiondecriptor_group.getAttribute("function_id").read<size_t>();
    
        bc_descriptor =
          std::make_shared<const InflowBoundaryConditionDescriptor>(i_boundary_descriptor,
                                                                    *ResumingData::instance().functionSymbolId(
                                                                      function_id));
        break;
      }
      case IBoundaryConditionDescriptor::Type::neumann: {
        const std::string name = iboundaryconditiondecriptor_group.getAttribute("name").read<std::string>();
        const size_t rhs_id    = iboundaryconditiondecriptor_group.getAttribute("rhs_function_id").read<size_t>();
    
        bc_descriptor =
          std::make_shared<const NeumannBoundaryConditionDescriptor>(name, i_boundary_descriptor,
                                                                     *ResumingData::instance().functionSymbolId(rhs_id));
        break;
      }
      case IBoundaryConditionDescriptor::Type::outflow: {
        bc_descriptor = std::make_shared<const OutflowBoundaryConditionDescriptor>(i_boundary_descriptor);
        break;
      }
      case IBoundaryConditionDescriptor::Type::symmetry: {
        bc_descriptor = std::make_shared<const SymmetryBoundaryConditionDescriptor>(i_boundary_descriptor);
        break;
      }
      }
    
      return {std::make_shared<DataHandler<const IBoundaryConditionDescriptor>>(bc_descriptor)};
    }
    
    EmbeddedData
    readIBoundaryDescriptor(const std::string& symbol_name, const HighFive::Group& symbol_table_group)
    {
      const HighFive::Group iboundarydescriptor_group = symbol_table_group.getGroup("embedded/" + symbol_name);
    
      return {std::make_shared<DataHandler<const IBoundaryDescriptor>>(readIBoundaryDescriptor(iboundarydescriptor_group))};
    }
    
    EmbeddedData
    readIDiscreteFunctionDescriptor(const std::string& symbol_name, const HighFive::Group& symbol_table_group)
    {
      const HighFive::Group idiscrete_function_descriptor_group = symbol_table_group.getGroup("embedded/" + symbol_name);
      const DiscreteFunctionType discrete_function_type =
        idiscrete_function_descriptor_group.getAttribute("discrete_function_type").read<DiscreteFunctionType>();
    
      std::shared_ptr<const IDiscreteFunctionDescriptor> idiscrete_function_descriptor;
    
      switch (discrete_function_type) {
      case DiscreteFunctionType::P0: {
        idiscrete_function_descriptor = std::make_shared<const DiscreteFunctionDescriptorP0>();
        break;
      }
      case DiscreteFunctionType::P0Vector: {
        idiscrete_function_descriptor = std::make_shared<const DiscreteFunctionDescriptorP0Vector>();
        break;
      }
      }
    
      return {std::make_shared<DataHandler<const IDiscreteFunctionDescriptor>>(idiscrete_function_descriptor)};
    }
    
    EmbeddedData
    readIInterfaceDescriptor(const std::string& symbol_name, const HighFive::Group& symbol_table_group)
    {
      const HighFive::Group iinterfacedescriptor_group = symbol_table_group.getGroup("embedded/" + symbol_name);
      const IInterfaceDescriptor::Type iinterface_descriptor_type =
        iinterfacedescriptor_group.getAttribute("iinterface_descriptor_type").read<IInterfaceDescriptor::Type>();
    
      std::shared_ptr<const IInterfaceDescriptor> iinterface_descriptor;
    
      switch (iinterface_descriptor_type) {
      case IInterfaceDescriptor::Type::named: {
        const std::string name = iinterfacedescriptor_group.getAttribute("name").read<std::string>();
        iinterface_descriptor  = std::make_shared<const NamedInterfaceDescriptor>(name);
        break;
      }
      case IInterfaceDescriptor::Type::numbered: {
        const unsigned int number = iinterfacedescriptor_group.getAttribute("number").read<unsigned int>();
        iinterface_descriptor     = std::make_shared<const NumberedInterfaceDescriptor>(number);
        break;
      }
      }
      return {std::make_shared<DataHandler<const IInterfaceDescriptor>>(iinterface_descriptor)};
    }
    
    EmbeddedData
    readINamedDiscreteData(const std::string& symbol_name, const HighFive::Group& symbol_table_group)
    {
      const HighFive::Group inamed_discrete_data_group = symbol_table_group.getGroup("embedded/" + symbol_name);
    
      const INamedDiscreteData::Type& type =
        inamed_discrete_data_group.getAttribute("named_discrete_data_type").read<INamedDiscreteData::Type>();
    
      const std::string name = inamed_discrete_data_group.getAttribute("named_discrete_data_name").read<std::string>();
    
      std::shared_ptr<const INamedDiscreteData> inamed_discrete_data;
    
      switch (type) {
      case INamedDiscreteData::Type::discrete_function: {
        HighFive::Group discrete_function_group = inamed_discrete_data_group.getGroup("discrete_function_variant");
        inamed_discrete_data =
          std::make_shared<const NamedDiscreteFunction>(readDiscreteFunctionVariant(discrete_function_group), name);
        break;
      }
      case INamedDiscreteData::Type::item_array: {
        HighFive::Group item_array_group = inamed_discrete_data_group.getGroup("item_array_variant");
        inamed_discrete_data = std::make_shared<const NamedItemArrayVariant>(readItemArrayVariant(item_array_group), name);
        break;
      }
      case INamedDiscreteData::Type::item_value: {
        HighFive::Group item_value_group = inamed_discrete_data_group.getGroup("item_value_variant");
        inamed_discrete_data = std::make_shared<const NamedItemValueVariant>(readItemValueVariant(item_value_group), name);
        break;
      }
      }
    
      return {std::make_shared<DataHandler<const INamedDiscreteData>>(inamed_discrete_data)};
    }
    
    EmbeddedData
    readIQuadratureDescriptor(const std::string& symbol_name, const HighFive::Group& symbol_table_group)
    {
      const HighFive::Group iquadraturedescriptor_group = symbol_table_group.getGroup("embedded/" + symbol_name);
      const QuadratureType quadrature_type =
        iquadraturedescriptor_group.getAttribute("quadrature_type").read<QuadratureType>();
      const size_t degree = iquadraturedescriptor_group.getAttribute("quadrature_degree").read<size_t>();
    
      std::shared_ptr<const IQuadratureDescriptor> iquadrature_descrptor;
    
      switch (quadrature_type) {
      case QuadratureType::Gauss: {
        iquadrature_descrptor = std::make_shared<const GaussQuadratureDescriptor>(degree);
        break;
      }
      case QuadratureType::GaussLegendre: {
        iquadrature_descrptor = std::make_shared<const GaussLegendreQuadratureDescriptor>(degree);
        break;
      }
      case QuadratureType::GaussLobatto: {
        iquadrature_descrptor = std::make_shared<const GaussLobattoQuadratureDescriptor>(degree);
        break;
      }
      }
    
      return {std::make_shared<DataHandler<const IQuadratureDescriptor>>(iquadrature_descrptor)};
    }
    
    template <ItemType item_type>
    std::shared_ptr<ItemArrayVariant>
    readItemArrayVariant(const HighFive::Group& item_array_variant_group)
    {
      const std::string data_type  = item_array_variant_group.getAttribute("data_type").read<std::string>();
      const size_t connectivity_id = item_array_variant_group.getAttribute("connectivity_id").read<size_t>();
    
      const IConnectivity& connectivity = *ResumingData::instance().iConnectivity(connectivity_id);
    
      std::shared_ptr<ItemArrayVariant> p_item_array;
    
      if (data_type == dataTypeName(ast_node_data_type_from<bool>)) {
        p_item_array = std::make_shared<ItemArrayVariant>(
          readItemArray<bool, item_type>(item_array_variant_group, "arrays", connectivity));
      } else if (data_type == dataTypeName(ast_node_data_type_from<long int>)) {
        p_item_array = std::make_shared<ItemArrayVariant>(
          readItemArray<long int, item_type>(item_array_variant_group, "arrays", connectivity));
      } else if (data_type == dataTypeName(ast_node_data_type_from<unsigned long int>)) {
        p_item_array = std::make_shared<ItemArrayVariant>(
          readItemArray<unsigned long int, item_type>(item_array_variant_group, "arrays", connectivity));
      } else if (data_type == dataTypeName(ast_node_data_type_from<double>)) {
        p_item_array = std::make_shared<ItemArrayVariant>(
          readItemArray<double, item_type>(item_array_variant_group, "arrays", connectivity));
      } else if (data_type == dataTypeName(ast_node_data_type_from<TinyVector<1>>)) {
        p_item_array = std::make_shared<ItemArrayVariant>(
          readItemArray<TinyVector<1>, item_type>(item_array_variant_group, "arrays", connectivity));
      } else if (data_type == dataTypeName(ast_node_data_type_from<TinyVector<2>>)) {
        p_item_array = std::make_shared<ItemArrayVariant>(
          readItemArray<TinyVector<2>, item_type>(item_array_variant_group, "arrays", connectivity));
      } else if (data_type == dataTypeName(ast_node_data_type_from<TinyVector<3>>)) {
        p_item_array = std::make_shared<ItemArrayVariant>(
          readItemArray<TinyVector<3>, item_type>(item_array_variant_group, "arrays", connectivity));
      } else if (data_type == dataTypeName(ast_node_data_type_from<TinyMatrix<1>>)) {
        p_item_array = std::make_shared<ItemArrayVariant>(
          readItemArray<TinyMatrix<1>, item_type>(item_array_variant_group, "arrays", connectivity));
      } else if (data_type == dataTypeName(ast_node_data_type_from<TinyMatrix<2>>)) {
        p_item_array = std::make_shared<ItemArrayVariant>(
          readItemArray<TinyMatrix<2>, item_type>(item_array_variant_group, "arrays", connectivity));
      } else if (data_type == dataTypeName(ast_node_data_type_from<TinyMatrix<3>>)) {
        p_item_array = std::make_shared<ItemArrayVariant>(
          readItemArray<TinyMatrix<3>, item_type>(item_array_variant_group, "arrays", connectivity));
      } else {
        throw UnexpectedError("unexpected discrete function data type: " + data_type);
      }
      return p_item_array;
    }
    
    std::shared_ptr<ItemArrayVariant>
    readItemArrayVariant(const HighFive::Group& item_array_variant_group)
    {
      const ItemType item_type = item_array_variant_group.getAttribute("item_type").read<ItemType>();
    
      std::shared_ptr<ItemArrayVariant> p_item_array;
    
      switch (item_type) {
      case ItemType::cell: {
        p_item_array = readItemArrayVariant<ItemType::cell>(item_array_variant_group);
        break;
      }
      case ItemType::face: {
        p_item_array = readItemArrayVariant<ItemType::face>(item_array_variant_group);
        break;
      }
      case ItemType::edge: {
        p_item_array = readItemArrayVariant<ItemType::edge>(item_array_variant_group);
        break;
      }
      case ItemType::node: {
        p_item_array = readItemArrayVariant<ItemType::node>(item_array_variant_group);
        break;
      }
      }
    
      return p_item_array;
    }
    
    EmbeddedData
    readItemArrayVariant(const std::string& symbol_name, const HighFive::Group& symbol_table_group)
    {
      const HighFive::Group item_array_variant_group = symbol_table_group.getGroup("embedded/" + symbol_name);
      return {std::make_shared<DataHandler<const ItemArrayVariant>>(readItemArrayVariant(item_array_variant_group))};
    }
    
    EmbeddedData
    readItemType(const std::string& symbol_name, const HighFive::Group& symbol_table_group)
    {
      const HighFive::Group item_type_group = symbol_table_group.getGroup("embedded/" + symbol_name);
      const ItemType item_type              = item_type_group.getAttribute("item_type").read<ItemType>();
    
      return {std::make_shared<DataHandler<const ItemType>>(std::make_shared<const ItemType>(item_type))};
    }
    
    template <ItemType item_type>
    std::shared_ptr<ItemValueVariant>
    readItemValueVariant(const HighFive::Group& item_value_variant_group)
    {
      const std::string data_type  = item_value_variant_group.getAttribute("data_type").read<std::string>();
      const size_t connectivity_id = item_value_variant_group.getAttribute("connectivity_id").read<size_t>();
    
      const IConnectivity& connectivity = *ResumingData::instance().iConnectivity(connectivity_id);
    
      std::shared_ptr<ItemValueVariant> p_item_value;
    
      if (data_type == dataTypeName(ast_node_data_type_from<bool>)) {
        p_item_value = std::make_shared<ItemValueVariant>(
          readItemValue<bool, item_type>(item_value_variant_group, "values", connectivity));
      } else if (data_type == dataTypeName(ast_node_data_type_from<long int>)) {
        p_item_value = std::make_shared<ItemValueVariant>(
          readItemValue<long int, item_type>(item_value_variant_group, "values", connectivity));
      } else if (data_type == dataTypeName(ast_node_data_type_from<unsigned long int>)) {
        p_item_value = std::make_shared<ItemValueVariant>(
          readItemValue<unsigned long int, item_type>(item_value_variant_group, "values", connectivity));
      } else if (data_type == dataTypeName(ast_node_data_type_from<double>)) {
        p_item_value = std::make_shared<ItemValueVariant>(
          readItemValue<double, item_type>(item_value_variant_group, "values", connectivity));
      } else if (data_type == dataTypeName(ast_node_data_type_from<TinyVector<1>>)) {
        p_item_value = std::make_shared<ItemValueVariant>(
          readItemValue<TinyVector<1>, item_type>(item_value_variant_group, "values", connectivity));
      } else if (data_type == dataTypeName(ast_node_data_type_from<TinyVector<2>>)) {
        p_item_value = std::make_shared<ItemValueVariant>(
          readItemValue<TinyVector<2>, item_type>(item_value_variant_group, "values", connectivity));
      } else if (data_type == dataTypeName(ast_node_data_type_from<TinyVector<3>>)) {
        p_item_value = std::make_shared<ItemValueVariant>(
          readItemValue<TinyVector<3>, item_type>(item_value_variant_group, "values", connectivity));
      } else if (data_type == dataTypeName(ast_node_data_type_from<TinyMatrix<1>>)) {
        p_item_value = std::make_shared<ItemValueVariant>(
          readItemValue<TinyMatrix<1>, item_type>(item_value_variant_group, "values", connectivity));
      } else if (data_type == dataTypeName(ast_node_data_type_from<TinyMatrix<2>>)) {
        p_item_value = std::make_shared<ItemValueVariant>(
          readItemValue<TinyMatrix<2>, item_type>(item_value_variant_group, "values", connectivity));
      } else if (data_type == dataTypeName(ast_node_data_type_from<TinyMatrix<3>>)) {
        p_item_value = std::make_shared<ItemValueVariant>(
          readItemValue<TinyMatrix<3>, item_type>(item_value_variant_group, "values", connectivity));
      } else {
        throw UnexpectedError("unexpected discrete function data type: " + data_type);
      }
      return p_item_value;
    }
    
    std::shared_ptr<ItemValueVariant>
    readItemValueVariant(const HighFive::Group& item_value_variant_group)
    {
      const ItemType item_type = item_value_variant_group.getAttribute("item_type").read<ItemType>();
    
      std::shared_ptr<ItemValueVariant> p_item_value;
    
      switch (item_type) {
      case ItemType::cell: {
        p_item_value = readItemValueVariant<ItemType::cell>(item_value_variant_group);
        break;
      }
      case ItemType::face: {
        p_item_value = readItemValueVariant<ItemType::face>(item_value_variant_group);
        break;
      }
      case ItemType::edge: {
        p_item_value = readItemValueVariant<ItemType::edge>(item_value_variant_group);
        break;
      }
      case ItemType::node: {
        p_item_value = readItemValueVariant<ItemType::node>(item_value_variant_group);
        break;
      }
      }
    
      return p_item_value;
    }
    
    EmbeddedData
    readItemValueVariant(const std::string& symbol_name, const HighFive::Group& symbol_table_group)
    {
      const HighFive::Group item_value_variant_group = symbol_table_group.getGroup("embedded/" + symbol_name);
      return {std::make_shared<DataHandler<const ItemValueVariant>>(readItemValueVariant(item_value_variant_group))};
    }
    
    EmbeddedData
    readIZoneDescriptor(const std::string& symbol_name, const HighFive::Group& symbol_table_group)
    {
      const HighFive::Group izonedescriptor_group = symbol_table_group.getGroup("embedded/" + symbol_name);
      const IZoneDescriptor::Type izone_descriptor_type =
        izonedescriptor_group.getAttribute("izone_descriptor_type").read<IZoneDescriptor::Type>();
    
      std::shared_ptr<const IZoneDescriptor> izone_descriptor;
    
      switch (izone_descriptor_type) {
      case IZoneDescriptor::Type::named: {
        const std::string name = izonedescriptor_group.getAttribute("name").read<std::string>();
        izone_descriptor       = std::make_shared<const NamedZoneDescriptor>(name);
        break;
      }
      case IZoneDescriptor::Type::numbered: {
        const unsigned int number = izonedescriptor_group.getAttribute("number").read<unsigned int>();
        izone_descriptor          = std::make_shared<const NumberedZoneDescriptor>(number);
        break;
      }
      }
    
      return {std::make_shared<DataHandler<const IZoneDescriptor>>(izone_descriptor)};
    }
    
    EmbeddedData
    readMesh(const std::string& symbol_name, const HighFive::Group& symbol_table_group)
    {
      const HighFive::Group mesh_group = symbol_table_group.getGroup("embedded/" + symbol_name);
    
      const size_t mesh_id = mesh_group.getAttribute("id").read<uint64_t>();
    
      return {std::make_shared<DataHandler<const MeshVariant>>(ResumingData::instance().meshVariant(mesh_id))};
    }
    
    std::shared_ptr<DiscreteFunctionVariant>
    readDiscreteFunctionVariant(const HighFive::Group& discrete_function_group)
    {
      DiscreteFunctionType type = discrete_function_group.getAttribute("Vh_type").read<DiscreteFunctionType>();
      size_t mesh_id            = discrete_function_group.getAttribute("mesh_id").read<size_t>();
    
      std::shared_ptr<const MeshVariant> mesh_v = ResumingData::instance().meshVariant(mesh_id);
    
      const std::string data_type = discrete_function_group.getAttribute("data_type").read<std::string>();
    
      std::shared_ptr<DiscreteFunctionVariant> p_discrete_function;
      switch (type) {
      case DiscreteFunctionType::P0: {
        if (data_type == dataTypeName(ast_node_data_type_from<double>)) {
          p_discrete_function = std::make_shared<DiscreteFunctionVariant>(
            DiscreteFunctionP0<const double>(mesh_v,
                                             readItemValue<double, ItemType::cell>(discrete_function_group, "values",
                                                                                   mesh_v->connectivity())));
        } else if (data_type == dataTypeName(ast_node_data_type_from<TinyVector<1>>)) {
          p_discrete_function = std::make_shared<DiscreteFunctionVariant>(
            DiscreteFunctionP0<const TinyVector<1>>(mesh_v,
                                                    readItemValue<TinyVector<1>, ItemType::cell>(discrete_function_group,
                                                                                                 "values",
                                                                                                 mesh_v->connectivity())));
        } else if (data_type == dataTypeName(ast_node_data_type_from<TinyVector<2>>)) {
          p_discrete_function = std::make_shared<DiscreteFunctionVariant>(
            DiscreteFunctionP0<const TinyVector<2>>(mesh_v,
                                                    readItemValue<TinyVector<2>, ItemType::cell>(discrete_function_group,
                                                                                                 "values",
                                                                                                 mesh_v->connectivity())));
        } else if (data_type == dataTypeName(ast_node_data_type_from<TinyVector<3>>)) {
          p_discrete_function = std::make_shared<DiscreteFunctionVariant>(
            DiscreteFunctionP0<const TinyVector<3>>(mesh_v,
                                                    readItemValue<TinyVector<3>, ItemType::cell>(discrete_function_group,
                                                                                                 "values",
                                                                                                 mesh_v->connectivity())));
        } else if (data_type == dataTypeName(ast_node_data_type_from<TinyMatrix<1>>)) {
          p_discrete_function = std::make_shared<DiscreteFunctionVariant>(
            DiscreteFunctionP0<const TinyMatrix<1>>(mesh_v,
                                                    readItemValue<TinyMatrix<1>, ItemType::cell>(discrete_function_group,
                                                                                                 "values",
                                                                                                 mesh_v->connectivity())));
        } else if (data_type == dataTypeName(ast_node_data_type_from<TinyMatrix<2>>)) {
          p_discrete_function = std::make_shared<DiscreteFunctionVariant>(
            DiscreteFunctionP0<const TinyMatrix<2>>(mesh_v,
                                                    readItemValue<TinyMatrix<2>, ItemType::cell>(discrete_function_group,
                                                                                                 "values",
                                                                                                 mesh_v->connectivity())));
        } else if (data_type == dataTypeName(ast_node_data_type_from<TinyMatrix<3>>)) {
          p_discrete_function = std::make_shared<DiscreteFunctionVariant>(
            DiscreteFunctionP0<const TinyMatrix<3>>(mesh_v,
                                                    readItemValue<TinyMatrix<3>, ItemType::cell>(discrete_function_group,
                                                                                                 "values",
                                                                                                 mesh_v->connectivity())));
        } else {
          throw UnexpectedError("unexpected discrete function data type: " + data_type);
        }
        break;
      }
      case DiscreteFunctionType::P0Vector: {
        if (data_type == dataTypeName(ast_node_data_type_from<double>)) {
          p_discrete_function = std::make_shared<DiscreteFunctionVariant>(
            DiscreteFunctionP0Vector<const double>(mesh_v,
                                                   readItemArray<double, ItemType::cell>(discrete_function_group, "values",
                                                                                         mesh_v->connectivity())));
        } else {
          throw UnexpectedError("unexpected discrete function vector data type: " + data_type);
        }
        break;
      }
      }
      return p_discrete_function;
    }
    
    EmbeddedData
    readDiscreteFunctionVariant(const std::string& symbol_name, const HighFive::Group& symbol_table_group)
    {
      const HighFive::Group discrete_function_group = symbol_table_group.getGroup("embedded/" + symbol_name);
    
      std::shared_ptr<DiscreteFunctionVariant> p_discrete_function = readDiscreteFunctionVariant(discrete_function_group);
    
      return {std::make_shared<DataHandler<const DiscreteFunctionVariant>>(p_discrete_function)};
    }
    
    EmbeddedData
    readOStream(const std::string& symbol_name, const HighFive::Group& symbol_table_group)
    {
      const HighFive::Group ostream_group = symbol_table_group.getGroup("embedded/" + symbol_name);
    
      const OStream::Type ostream_type = ostream_group.getAttribute("ostream_type").read<OStream::Type>();
    
      std::shared_ptr<const OStream> p_ostream;
    
      switch (ostream_type) {
      case OStream::Type::std_ofstream: {
        std::string filename = ostream_group.getAttribute("filename").read<std::string>();
    
        p_ostream = std::make_shared<OFStream>(filename, true);
        break;
      }
      case OStream::Type::std_ostream: {
        throw NotImplementedError("std::ostream resume");
      }
      }
    
      return {std::make_shared<DataHandler<const OStream>>(p_ostream)};
    }