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

3
4
5
6
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

7
8
#include <vector>
#include <type_traits>
9

10
#include <dune/amdis/QuadratureRules.hpp>
11

12
13
#include <dune/amdis/OperatorEvaluation.hpp>
#include <dune/amdis/common/ValueCategory.hpp>
14
#include <dune/amdis/utility/GetEntity.hpp>
15

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

26
    using QuadratureRule = QuadratureRuleFactory_t<LocalContext,double,dim>;
27

28
  public:
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(Dune::GeometryType const& t) 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

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

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

96
97
98
99
100
101
102
103
104
105
    /// \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.
     **/
    virtual void init(LocalContext const& element, QuadratureRule const& points) override
106
    {
107
      expr.init(get_entity(element), points);
108
    }
109

110
    /// Calculates `expr[iq] * test * trial`
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
    virtual double eval(std::size_t iq,
        Dune::FieldVector<double,1> const& test) const override
    {
      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,
        Dune::FieldVector<double,dow> const& grad_test) const override
    {
      return Evaluate::fot(_cat{}, traits, expr[iq], grad_test);
    }


    /// Calculates `expr[iq] * test * trial`
    virtual double eval(std::size_t iq,
127
        Dune::FieldVector<double,1> const& test,
128
        Dune::FieldVector<double,1> const trial) const override
129
    {
130
      return Evaluate::zot(_cat{}, traits, expr[iq], test, trial);
131
    }
132

133
    /// Calculates `expr[iq] * test * grad(trial)`, maybe partial derivative only.
134
    virtual double eval(std::size_t iq,
135
        Dune::FieldVector<double,1> const& test,
136
        Dune::FieldVector<double,dow> const& grad_trial) const override
137
    {
138
      return Evaluate::fot(_cat{}, traits, expr[iq], grad_trial, test);
139
    }
140

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

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

157
    /// Returns the polynomial degree of the expression
158
    virtual int getDegree(Dune::GeometryType const& t) const override
159
    {
160
      return expr.getDegree(t);
161
    }
162

163
  private:
164
165
166
167
    /// A local expression, implementing the Concept \ref Concepts::LocalExpression.
    Expression expr;

    /// One of [tag::none, VectorComponent, MatrixComponent]
168
    Traits traits;
169

170
    using value_type = std::decay_t< decltype( std::declval<Expression>()[std::size_t(0)] ) >;
Praetorius, Simon's avatar
Praetorius, Simon committed
171
    using _cat = ValueCategory_t<value_type>;
172
  };
173

174
} // end namespace AMDiS