ContextGeometry.hpp 4.09 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
40
  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.
   **/
  template <class LocalContextType>
41
42
  struct ContextGeometry
  {
43
44
45
46
47
48
49
50
51
  public:

    using LocalContext = LocalContextType;
    using Element = typename Impl::ContextTypes<LocalContext>::Entity;
    using Geometry = typename Element::Geometry;
    using LocalGeometry = typename Impl::ContextTypes<LocalContext>::LocalGeometry;

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

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

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

64
65
66
  public:

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

71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
    LocalContext const& localContext() const
    {
      return *localContext_;
    }

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

    LocalGeometry const& localGeometry() const
    {
      return localGeometryImpl(IsEntity{});
    }


  public:

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

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

  private: // implementation detail

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

    // position for intersection
    template <class Coordinate>
128
129
130
131
132
133
134
135
136
137
138
139
140
    auto localImpl(Coordinate const& p, std::false_type) const
    {
      return localGeometry().global(p);
    }

    // local-geometry is the same as geometry
    Geometry const& localGeometryImpl(std::true_type) const
    {
      return *geometry_;
    }

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

      return *localGeometry_;
146
147
    }

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

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

} // end namespace AMDiS