Skip to content
Snippets Groups Projects
Select Git revision
  • 8ee74d54deb578675d3da8427f28f8964e234fc0
  • develop default protected
  • feature/variational-hydro
  • origin/stage/bouguettaia
  • feature/gmsh-reader
  • feature/reconstruction
  • save_clemence
  • feature/kinetic-schemes
  • feature/local-dt-fsi
  • feature/composite-scheme-sources
  • feature/composite-scheme-other-fluxes
  • 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
  • master protected
  • 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

IConnectivity.hpp

Blame
  • CFunctionEmbedder.hpp 3.32 KiB
    #ifndef CFUNCTION_EMBEDDER_HPP
    #define CFUNCTION_EMBEDDER_HPP
    
    #include <PugsAssert.hpp>
    #include <PugsMacros.hpp>
    
    #include <ASTNodeDataType.hpp>
    #include <ASTNodeDataVariant.hpp>
    
    #include <cmath>
    #include <functional>
    #include <iostream>
    #include <tuple>
    #include <vector>
    
    #include <type_traits>
    
    class ICFunctionEmbedder
    {
     public:
      virtual size_t numberOfArguments() const = 0;
    
      virtual ASTNodeDataType getReturnDataType() const = 0;
    
      virtual std::vector<ASTNodeDataType> getArgumentDataTypes() const = 0;
    
      virtual void apply(const std::vector<ASTNodeDataVariant>& x, ASTNodeDataVariant& f_x) const = 0;
    
      virtual ~ICFunctionEmbedder() = default;
    };
    
    template <typename FX, typename... Args>
    class CFunctionEmbedder : public ICFunctionEmbedder
    {
     private:
      std::function<FX(Args...)> m_f;
      using ArgsTuple = std::tuple<Args...>;
    
      template <size_t I>
      PUGS_INLINE void
      _copy_value(ArgsTuple& t, const std::vector<ASTNodeDataVariant>& v) const
      {
        std::visit(
          [&](auto v_i) {
            if constexpr (std::is_arithmetic_v<decltype(v_i)>) {
              std::get<I>(t) = v_i;
            } else {
              throw std::runtime_error("unexpected argument type!");
            }
          },
          v[I]);
      }
    
      template <size_t... I>
      PUGS_INLINE void
      _copy_from_vector(ArgsTuple& t, const std::vector<ASTNodeDataVariant>& v, std::index_sequence<I...>) const
      {
        Assert(sizeof...(Args) == v.size());
        (_copy_value<I>(t, v), ...);
      }
    
      template <size_t I>
      PUGS_INLINE ASTNodeDataType
      _getOneArgumentDataType(ArgsTuple& t) const
      {
        return ast_node_data_type_from_pod<std::decay_t<decltype(std::get<I>(t))>>;
      }
    
      template <size_t... I>
      PUGS_INLINE std::vector<ASTNodeDataType>
      _getArgumentDataTypes(ArgsTuple t, std::index_sequence<I...>) const
      {
        std::vector<ASTNodeDataType> argument_type_list;
        (argument_type_list.push_back(this->_getOneArgumentDataType<I>(t)), ...);
        return argument_type_list;
      }
    
     public:
      PUGS_INLINE ASTNodeDataType
      getReturnDataType() const final
      {
        return ast_node_data_type_from_pod<FX>;
      }
    
      PUGS_INLINE std::vector<ASTNodeDataType>
      getArgumentDataTypes() const final
      {
        constexpr size_t N = std::tuple_size_v<ArgsTuple>;
        ArgsTuple t;
        using IndexSequence = std::make_index_sequence<N>;
    
        return this->_getArgumentDataTypes(t, IndexSequence{});
      }
    
      PUGS_INLINE size_t
      numberOfArguments() const final
      {
        return sizeof...(Args);
      }
    
      PUGS_INLINE
      void
      apply(const std::vector<ASTNodeDataVariant>& x, ASTNodeDataVariant& f_x) const final
      {
        constexpr size_t N = std::tuple_size_v<ArgsTuple>;
        ArgsTuple t;
        using IndexSequence = std::make_index_sequence<N>;
    
        this->_copy_from_vector(t, x, IndexSequence{});
        f_x = std::apply(m_f, t);
      }
    
      // @note This is written in a template fashion to ensure that function type
      // is correct. If one uses simply CFunctionEmbedder(std::function<FX(Args...)>&&),
      // types seem unchecked
      template <typename FX2, typename... Args2>
      CFunctionEmbedder(std::function<FX2(Args2...)> f) : m_f(f)
      {
        static_assert(std::is_same_v<FX, FX2>, "incorrect return type");
        static_assert(sizeof...(Args) == sizeof...(Args2), "invalid number of arguments");
        using Args2Tuple = std::tuple<Args2...>;
        static_assert(std::is_same_v<ArgsTuple, Args2Tuple>, "invalid arguments type");
      }
    };
    
    #endif   // CFUNCTION_EMBEDDER_HPP