LocalExpression.hpp 2.02 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#pragma once

#include <cassert>

#include <dune/common/std/optional.hh>
#include <dune/functions/gridfunctions/gridviewentityset.hh>

#include <dune/amdis/ContextGeometry.hpp>

namespace AMDiS
{
  template <class Expr, class GridView>
  class LocalExpression
  {
    using EntitySet = Dune::Functions::GridViewEntitySet<GridView, 0>;

    using Element = typename EntitySet::Element;
    using Geometry = typename Element::Geometry;

    using Domain = typename EntitySet::LocalCoordinate;
    using Range = typename Expr::value_type;

    using LocalContext = Element;
    using LocalGeometry = Geometry;
    using GeometryWrapper = ContextGeometry<LocalContext, Geometry, LocalGeometry>; // TODO: allow intersections!

  public:

    /// Constructor. Stores a copy to the expression.
    explicit LocalExpression(Expr const& expr)
      : expr_(expr)
    {}


    /// Evaluate expression `expr_` at local coordinate `lambda`
    /// [expects: LocalExpression is bound to element]
    Range operator()(Domain const& lambda) const
    {
      assert( bound_ );
      return expr_.local(context_.value(), lambda);
    }

    /// Bind expression to a local context. Must be called before you can evaluate it.
    /// [expects: local function is not bound to other element]
    void bind(Element const& element)
    {
      assert( not bound_ ); // NOTE: interpolateTreeSubset(...) does not unbind the element!
      geometry_.emplace(element.geometry());
      context_.emplace(element, *geometry_, *geometry_);

      expr_.bind(element);
      bound_ = true;
    }

    /// Unbind from local context
    void unbind()
    {
      context_.reset();
      geometry_.reset();
      bound_ = false;
    }

    /// Obtain local contex this LocalFunction is bound to
    LocalContext const& localContext() const
    {
      assert( bound_ );
      return context_.value().localContext;
    }

  private:
    Expr expr_;

    Dune::Std::optional<GeometryWrapper> context_;
    Dune::Std::optional<Geometry> geometry_;
    bool bound_ = false;
  };

} // end namespace AMDiS