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

3
#include <optional>
4
5
6
7
8
#include <type_traits>

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

9
10
namespace AMDiS
{
11
12
  namespace Impl
  {
13
    template <class E, class = std::void_t<>>
14
15
16
17
18
19
20
21
    struct ContextTypes
    {
      using Entity = E;
      using LocalGeometry = typename E::Geometry;
    };

    // specialization for intersections
    template <class I>
22
    struct ContextTypes<I, std::void_t<decltype(std::declval<I>().inside())>>
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
    {
      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.
39
40
   *
   * \tparam LC  LocalContext, either element or intersection
41
   **/
42
  template <class LC>
43
44
  struct ContextGeometry
  {
45
    using ContextType = Impl::ContextTypes<LC>;
46

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

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

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

60
    /// Constructor. Stores pointer to localContext, element, and geometry.
Praetorius, Simon's avatar
Praetorius, Simon committed
61
    ContextGeometry(LC const& localContext, Element const& element, Geometry const& geometry)
62
63
64
      : localContext_(&localContext)
      , element_(&element)
      , geometry_(&geometry)
65
66
    {}

67
  public:
68
    /// Return the bound element (entity of codim 0)
69
    Element const& element() const
70
    {
71
      return *element_;
72
73
    }

74
    /// Return the LocalContext, either the element or an intersection.
75
76
77
78
79
    LocalContext const& localContext() const
    {
      return *localContext_;
    }

80
    /// Return the geometry of the \ref Element
81
82
83
84
85
    Geometry const& geometry() const
    {
      return *geometry_;
    }

86
    /// Return the geometry of the element, or geometryInInside of the intersection
87
88
    LocalGeometry const& localGeometry() const
    {
89
      return localGeometry_impl(IsEntity{});
90
91
92
93
94
    }


  public:

95
    /// Coordinate `p` given in `localGeometry`, transformed to coordinate in geometry of the LocalContext.
96
    template <class Coordinate>
97
    decltype(auto) local(Coordinate const& p) const
98
    {
99
      return local_impl(p, IsEntity{});
100
101
102
103
104
105
    }

    /// Transformation of coordinate `p` given in `localGeometry` to world space coordinates.
    template <class Coordinate>
    decltype(auto) global(Coordinate const& p) const
    {
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
      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);
121
122
123
124
125
126
    }

  private: // implementation detail

    // position for elements
    template <class Coordinate>
127
    Coordinate const& local_impl(Coordinate const& p, std::true_type) const
128
129
130
131
132
133
    {
      return p;
    }

    // position for intersection
    template <class Coordinate>
134
    auto local_impl(Coordinate const& p, std::false_type) const
135
136
137
138
139
    {
      return localGeometry().global(p);
    }

    // local-geometry is the same as geometry
140
    Geometry const& localGeometry_impl(std::true_type) const
141
142
143
144
145
    {
      return *geometry_;
    }

    // local-geometry of intersection in inside element
146
    LocalGeometry const& localGeometry_impl(std::false_type) const
147
    {
148
149
150
151
      if (!localGeometry_)
        localGeometry_.emplace(localContext_->geometryInInside());

      return *localGeometry_;
152
153
    }

154
155
156
157
158
159
  private:
    LocalContext const* localContext_;
    Element const* element_;
    Geometry const* geometry_;

    // The localGeometry may be constructed only if needed
160
    mutable std::optional<LocalGeometry> localGeometry_;
161
162
  };

163
164
165
166
167
168
169
170
171
172
173
174
175
176
177

  template <class GV>
  class GlobalContext
  {
  public:
    using GridView = GV;
    using Element = typename GV::template Codim<0>::Entity;
    using Geometry = typename Element::Geometry;

    enum {
      dim = GridView::dimension,      //< the dimension of the grid element
      dow = GridView::dimensionworld  //< the dimension of the world
    };

    /// Constructor. Stores a copy of gridView and a pointer to element and geometry.
Praetorius, Simon's avatar
Praetorius, Simon committed
178
    GlobalContext(GV const& gridView, Element const& element,
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
                  Geometry const& geometry)
      : gridView_(gridView)
      , element_(&element)
      , geometry_(&geometry)
    {}

  public:
    /// Return the GridView this context is bound to
    GridView const& gridView() const
    {
      return gridView_;
    }

    /// Return the bound element (entity of codim 0)
    Element const& element() const
    {
      return *element_;
    }

    /// Return the geometry of the \ref Element
    Geometry const& geometry() const
    {
      return *geometry_;
    }

  private:
    GridView gridView_;
    Element const* element_;
    Geometry const* geometry_;
  };

210
} // end namespace AMDiS