ContextGeometry.hpp 5.7 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
68
69
    // Prevent from storing pointer to rvalue-reference
    ContextGeometry(LC const& localContext, Element const& element, Geometry&& geometry) = delete;

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

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

83
    /// Return the geometry of the \ref Element
84
85
86
87
88
    Geometry const& geometry() const
    {
      return *geometry_;
    }

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


  public:

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

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

  private: // implementation detail

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

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

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

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

      return *localGeometry_;
155
156
    }

157
158
159
160
161
162
  private:
    LocalContext const* localContext_;
    Element const* element_;
    Geometry const* geometry_;

    // The localGeometry may be constructed only if needed
163
    mutable std::optional<LocalGeometry> localGeometry_;
164
165
  };

166
167
168
169
170
171
172
173
174
175
176
177
178
179
180

  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.
181
182
    template <class E, class G>
    GlobalContext(GV const& gridView, E&& element, G&& geometry)
183
      : gridView_(gridView)
184
185
      , element_(Dune::wrap_or_move(FWD(element)))
      , geometry_(Dune::wrap_or_move(FWD(geometry)))
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
    {}

  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_;
209
210
    std::shared_ptr<Element const> element_;
    std::shared_ptr<Geometry const> geometry_;
211
212
  };

213
} // end namespace AMDiS