OperatorTermBase.hpp 6.64 KB
Newer Older
1
2
#pragma once

3
4
#include <vector>
#include <type_traits>
5

6
#include <dune/amdis/QuadratureRules.hpp>
7

8
9
#include <dune/amdis/OperatorEvaluation.hpp>
#include <dune/amdis/common/ValueCategory.hpp>
10
#include <dune/amdis/utility/GetEntity.hpp>
11

12
namespace AMDiS
13
{
14
  /// Abstract base class of all operator terms
15
  template <class LocalContext>
16
17
18
  class OperatorTerm
  {
  protected:
19
    static constexpr int dim = Impl::Get<LocalContext>::Entity::dimension;
20
    static constexpr int dow = LocalContext::Geometry::coorddimension;
21

22
    using QuadratureRule = QuadratureRuleFactory_t<LocalContext,double,dim>;
23
    using Element = typename Impl::Get<LocalContext>::Entity;
24

25
  public:
26
27
28
    virtual void bind(Element const& element) = 0;
    virtual void unbind() = 0;

29
30
    // initialize operator-term on the current element
    virtual void init(LocalContext const& element, QuadratureRule const& points) = 0;
31

32
33
34
35
36
37
38
    virtual double eval(std::size_t iq,
        Dune::FieldVector<double,1> const& test) const = 0;

    virtual double eval(std::size_t iq,
        Dune::FieldVector<double,dow> const& grad_test) const = 0;


39
40
    // evaluate operator-term at quadrature point as zero-order term,
    // with no gradients involved
41
    virtual double eval(std::size_t iq,
42
        Dune::FieldVector<double,1> const& test,
43
        Dune::FieldVector<double,1> const trial) const = 0;
44

45
46
    // evaluate operator-term at quadrature point as first-order term,
    // with gradients on the trial-function
47
    virtual double eval(std::size_t iq,
48
        Dune::FieldVector<double,1> const& test,
49
        Dune::FieldVector<double,dow> const& grad_trial) const = 0;
50

51
52
    // evaluate operator-term at quadrature point as first-order term,
    // with gradients on the test-function
53
    virtual double eval(std::size_t iq,
54
        Dune::FieldVector<double,dow> const& grad_test,
55
        Dune::FieldVector<double,1> const trial) const = 0;
56

57
58
    // evaluate operator-term at quadrature point as second-order term,
    // with gradients on the trial and test-function
59
    virtual double eval(std::size_t iq,
60
61
        Dune::FieldVector<double,dow> const& grad_test,
        Dune::FieldVector<double,dow> const& grad_trial) const = 0;
62

63
64
    // return the polynomial degree, necessary to intergrate the operator-term
    // on an element accurately
65
    virtual int getDegree() const = 0;
66
  };
67
68


69
70
71
72
73
74
75
76
77
78
79
80
  /// \brief Base class for all operator-terms based on expressions
  /**
   * Represents an operator-term with a coefficient the scales the classical operator, e.g.
   * - zero order terms `<expr * u, v>`
   * - first order terms (GRD_PHI) `<(vecexpr * grad(u)), v>`, `<expr * d_i(u), v>` (a)
   * - first order terms (GRD_PSI) `<vecexpr * u, grad(v)>`, `<expr * u, d_i(v)>` (a)
   * - second order terms `<expr * grad(u), grad(v)>`, `<(matexpr *grad(u)), grad(v)>`, `<expr * d_i(u), d_j(v)>` (b)
   **/
  // LocalContext ... The type of the element where to evaluate, either entity (codim=0), or intersection (codim=1)
  // Expression ..... The type of the expression to evaluate
  // Traits ......... Specialization for the operator evaluation [tag:none | VectorComponent (a) | MatrixComponent (b)]
  template <class LocalContext, class Expression, class Traits = tag::none>
81
  class GenericOperatorTerm
82
      : public OperatorTerm<LocalContext>
83
  {
84
    using Super = OperatorTerm<LocalContext>;
85
    using QuadratureRule = typename Super::QuadratureRule;
86
    using Element = typename Super::Element;
87

88
    static constexpr int dow = Super::dow;
89
90

  public:
91
    /// Constructor, stores a copy of the expression `expr` and of the traits `traits`.
92
    explicit GenericOperatorTerm(Expression const& expr, Traits traits = {})
93
      : expr(expr)
94
      , traits(traits)
95
96
    {}

97
98
99
100
101
102
103
    virtual void bind(Element const& element) final
    {
      expr.bind(element);
    }

    virtual void unbind() final {}

104
105
106
107
108
109
110
111
112
    /// \brief Initialize the expression on the current (inside-)element, in the quadrature points.
    /**
     * This initialization does not only bind the operator-term to the inside-element,
     * but also calculates values in all quadrature points. These pre-calculated values
     * can be accessed using the `operator[]` method of the expression.
     *
     * Note: For entities the expression is bound to the `element` directly, but
     * for intersections, the expression is bound to inside-entity of the element.
     **/
113
    virtual void init(LocalContext const& element, QuadratureRule const& points) final
114
    {
115
      expr.init(get_entity(element), points);
116
    }
117

118
    /// Calculates `expr[iq] * test * trial`
119
    virtual double eval(std::size_t iq,
120
        Dune::FieldVector<double,1> const& test) const final
121
122
123
124
125
126
    {
      return Evaluate::zot(_cat{}, traits, expr[iq], test);
    }

    /// Calculates `expr[iq] * test * grad(trial)`, maybe partial derivative only.
    virtual double eval(std::size_t iq,
127
        Dune::FieldVector<double,dow> const& grad_test) const final
128
129
130
131
132
133
134
    {
      return Evaluate::fot(_cat{}, traits, expr[iq], grad_test);
    }


    /// Calculates `expr[iq] * test * trial`
    virtual double eval(std::size_t iq,
135
        Dune::FieldVector<double,1> const& test,
136
        Dune::FieldVector<double,1> const trial) const final
137
    {
138
      return Evaluate::zot(_cat{}, traits, expr[iq], test, trial);
139
    }
140

141
    /// Calculates `expr[iq] * test * grad(trial)`, maybe partial derivative only.
142
    virtual double eval(std::size_t iq,
143
        Dune::FieldVector<double,1> const& test,
144
        Dune::FieldVector<double,dow> const& grad_trial) const final
145
    {
146
      return Evaluate::fot(_cat{}, traits, expr[iq], grad_trial, test);
147
    }
148

149
    /// Calculates `expr[iq] * grad(test) * trial`, maybe partial derivative only.
150
    virtual double eval(std::size_t iq,
151
        Dune::FieldVector<double,dow> const& grad_test,
152
        Dune::FieldVector<double,1> const trial) const final
153
    {
154
      return Evaluate::fot(_cat{}, traits, expr[iq], grad_test, trial);
155
    }
156

157
    /// Calculates `expr[iq] * grad(test) * grad(trial)`, maybe partial derivatives only.
158
    virtual double eval(std::size_t iq,
159
        Dune::FieldVector<double,dow> const& grad_test,
160
        Dune::FieldVector<double,dow> const& grad_trial) const final
161
    {
162
      return Evaluate::sot(_cat{}, traits, expr[iq], grad_test, grad_trial);
163
    }
164

165
    /// Returns the polynomial degree of the expression
166
    virtual int getDegree() const final
167
    {
168
      return expr.getDegree();
169
    }
170

171
  private:
172
173
174
175
    /// A local expression, implementing the Concept \ref Concepts::LocalExpression.
    Expression expr;

    /// One of [tag::none, VectorComponent, MatrixComponent]
176
    Traits traits;
177

178
    using value_type = std::decay_t< decltype( std::declval<Expression>()[std::size_t(0)] ) >;
Praetorius, Simon's avatar
Praetorius, Simon committed
179
    using _cat = ValueCategory_t<value_type>;
180
  };
181

182
} // end namespace AMDiS