CoordsTerm.hpp 4.01 KB
Newer Older
1
2
3
4
5
6
7
#pragma once

#include <vector>
#include <type_traits>

#include <dune/istl/bvector.hh>

8
#include <dune/amdis/common/Concepts.hpp>
9
#include <dune/amdis/terms/ExpressionBase.hpp>
10

11
namespace AMDiS
12
{
13
  /**
14
15
16
17
    * \addtogroup OperatorTerms
    * @{
    **/

18
  namespace Impl
19
20
21
22
  {
    template <class F, int dow>
    using CoordsFunctorResult
      = std::result_of<F(Dune::FieldVector<double, dow>)>;
23

24
25
26
    template <class F, int dow>
    constexpr bool CallableDow =
      Concepts::Callable<F, Dune::FieldVector<double, dow>>;
27

28
29
30
31
32
33
34
35
36
37
38
39
#ifndef AMDIS_DOW
    template <class F>
    using CoordsFunctorResult_t = typename std::conditional_t<
      CallableDow<F, 1>, CoordsFunctorResult<F, 1>, std::conditional_t<
      CallableDow<F, 2>, CoordsFunctorResult<F, 2>, std::conditional_t<
      CallableDow<F, 3>, CoordsFunctorResult<F, 3>, Id<void>> > >::type;
#else
    template <class F>
    using CoordsFunctorResult_t = typename std::conditional_t<
      CallableDow<F, AMDIS_DOW>, CoordsFunctorResult<F, AMDIS_DOW>, Id<void>>::type;
#endif
  }
40
41
42


  /// \brief An expression that evaluates to the current coordinate of a dof or
43
44
  /// quadrature point with given index. \see eval.
  template <class Functor>
45
  class CoordsFunctorTerm
46
      : public ExpressionBase
47
48
49
  {
  public:
    using value_type = Impl::CoordsFunctorResult_t<Functor>;
50
    static_assert( !std::is_same<value_type, void>::value,
51
                   "Template `Functor` can not be used as a functor.");
52

53
54
    template <class F,
      class = std::enable_if_t<Concepts::Compatible<Functor, F>> >
55
    explicit CoordsFunctorTerm(F&& f, int degree = 1)
56
57
      : ExpressionBase(degree)
      , fct_(std::forward<F>(f))
58
    {}
59
60

    /// \brief Evaluates the functor \ref fct at all quadrature points and
61
    /// stores the result in a vector \ref values.
62
63
    template <class Context, class PointList>
    void init(Context const& context, PointList const& points)
64
    {
65
      values_.resize(points.size());
66
      for (std::size_t iq = 0; iq < points.size(); ++iq)
67
68
69
70
71
72
73
74
75
76
77
78
79
        values_[iq] = local(context, points[iq].position());
    }

    template <class Context, class LocalCoordinate>
    value_type local(Context const& context, LocalCoordinate const& lambda) const
    {
      return fct_(context.global(lambda));
    }

    template <class GlobalCoordinate>
    value_type global(GlobalCoordinate const& x) const
    {
      return fct_(x);
80
    }
81

82
    value_type const& operator[](std::size_t iq) const
83
    {
84
      return values_[iq];
85
    }
86

87
  private:
88
    Functor fct_;
89

90
    std::vector<value_type> values_;
91
  };
92
93


94
  /// Generator function for \ref CoordsFunctorTerm expressions
95
  template <class F>
96
  auto eval(F&& f) { return CoordsFunctorTerm<std::decay_t<F>>{std::forward<F>(f)}; }
97
98
99
100
101
102


  /// \brief An expression that evaluates to the current coordinate of a dof or
  /// quadrature point with given index. \see eval.
  template <int dow>
  class CoordsTerm
103
      : public ExpressionBase
104
105
106
107
  {
  public:
    using value_type = Dune::FieldVector<double, dow>;

108
109
110
    CoordsTerm()
      : ExpressionBase(1)
    {}
111

112
113
    /// \brief Evaluates the functor \ref fct at all quadrature points and
    /// stores the result in a vector \ref values.
114
115
    template <class Context, class PointList>
    void init(Context const& context,
116
117
              PointList const& points)
    {
118
      values_.resize(points.size());
119
      for (std::size_t iq = 0; iq < points.size(); ++iq)
120
        values_[iq] = context.global( points[iq].position() );
121
122
    }

123
124
125
126
127
128
129
130
131
132
133
134
    template <class Context, class LocalCoordinate>
    value_type const& local(Context const& context, LocalCoordinate const& lambda) const
    {
      return context.global(lambda);
    }

    template <class GlobalCoordinate>
    value_type const& global(GlobalCoordinate const& x) const
    {
      return x;
    }

135
    value_type const& operator[](std::size_t iq) const
136
    {
137
      return values_[iq];
138
139
140
    }

  private:
141
    std::vector<value_type> values_;
142
143
144
145
146
147
148
149
  };


  /// Generator function for \ref CoordsTerm expressions
  template <int dow>
  CoordsTerm<dow> X() { return {}; }


150

151
  /** @} **/
152

153
} // end namespace AMDiS