ContextGeometry.hpp 4.08 KB
Newer Older
1
2
#pragma once

3
4
5
6
7
8
#include <type_traits>

#include <dune/common/typetraits.hh>
#include <dune/common/std/optional.hh>
#include <dune/geometry/type.hh>

9
10
namespace AMDiS
{
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
  namespace Impl
  {
    template <class E, class = Dune::void_t<>>
    struct ContextTypes
    {
      using Entity = E;
      using LocalGeometry = typename E::Geometry;
    };

    // specialization for intersections
    template <class I>
    struct ContextTypes<I, Dune::void_t<decltype(std::declval<I>().inside())>>
    {
      using Entity = typename I::Entity;
      using LocalGeometry = typename I::LocalGeometry;
    };

  } // end namespace Impl


  /// \brief Wrapper class for element and geometry
  /**
   * A LocalContext can be either a grid entity of codim 0 (called an element)
   * or an intersection of elements. The element and its geometry may be stored
   * externally and can be passed along with the localContext object.
   * Since an intersection has a geometry (and localGeometry) different from the
   * geometry (and localGeometry) of the entity it belongs to, these objects
   * are provided as well.
   **/
40
  template <class LC>
41
42
  struct ContextGeometry
  {
43
    using ContextType = Impl::ContextTypes<LC>;
44

45
46
47
  public:
    using LocalContext = LC;
    using Element = typename ContextType::Entity;
48
    using Geometry = typename Element::Geometry;
49
    using LocalGeometry = typename ContextType::LocalGeometry;
50
51
52

    using IsEntity = std::is_same<Element, LocalContext>;

53
54
55
56
57
    enum {
      dim = Geometry::mydimension,    //< the dimension of the grid element
      dow = Geometry::coorddimension  //< the dimension of the world
    };

58
59
60
61
62
    /// Constructor. Stores pointer to localContext, element, and geometry.
    ContextGeometry(LocalContext const& localContext, Element const& element, Geometry const& geometry)
      : localContext_(&localContext)
      , element_(&element)
      , geometry_(&geometry)
63
64
    {}

65
66
67
  public:

    Element const& element() const
68
    {
69
      return *element_;
70
71
    }

72
73
74
75
76
77
78
79
80
81
82
83
    LocalContext const& localContext() const
    {
      return *localContext_;
    }

    Geometry const& geometry() const
    {
      return *geometry_;
    }

    LocalGeometry const& localGeometry() const
    {
84
      return localGeometry_impl(IsEntity{});
85
86
87
88
89
90
    }


  public:

    /// Coordinate `p` given in `localGeometry`, transformed to coordinate in `geometry`.
91
    template <class Coordinate>
92
    decltype(auto) local(Coordinate const& p) const
93
    {
94
      return local_impl(p, IsEntity{});
95
96
97
98
99
100
    }

    /// Transformation of coordinate `p` given in `localGeometry` to world space coordinates.
    template <class Coordinate>
    decltype(auto) global(Coordinate const& p) const
    {
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
      return geometry_->global(p);
    }

    /// Return the geometry-type of the localContext
    Dune::GeometryType type() const
    {
      return localContext_->type();
    }

    /// The integration element from the `localGeometry`, the quadrature points are
    /// defined in.
    template <class Coordinate>
    auto integrationElement(Coordinate const& p) const
    {
      return localGeometry().integrationElement(p);
116
117
118
119
120
121
    }

  private: // implementation detail

    // position for elements
    template <class Coordinate>
122
    Coordinate const& local_impl(Coordinate const& p, std::true_type) const
123
124
125
126
127
128
    {
      return p;
    }

    // position for intersection
    template <class Coordinate>
129
    auto local_impl(Coordinate const& p, std::false_type) const
130
131
132
133
134
    {
      return localGeometry().global(p);
    }

    // local-geometry is the same as geometry
135
    Geometry const& localGeometry_impl(std::true_type) const
136
137
138
139
140
    {
      return *geometry_;
    }

    // local-geometry of intersection in inside element
141
    LocalGeometry const& localGeometry_impl(std::false_type) const
142
    {
143
144
145
146
      if (!localGeometry_)
        localGeometry_.emplace(localContext_->geometryInInside());

      return *localGeometry_;
147
148
    }

149
150
151
152
153
154
  private:
    LocalContext const* localContext_;
    Element const* element_;
    Geometry const* geometry_;

    // The localGeometry may be constructed only if needed
155
    mutable Dune::Std::optional<LocalGeometry> localGeometry_;
156
157
158
  };

} // end namespace AMDiS