LocalAssemblerBase.hpp 3.22 KB
Newer Older
1
2
3
4
5
6
#pragma once

#include <list>
#include <memory>
#include <type_traits>

7
8
9
#include <amdis/common/ConceptsBase.hpp>
#include <amdis/common/TypeDefs.hpp>
#include <amdis/utility/TreeData.hpp>
10
11
12

namespace AMDiS
{
13
14
15
16
17
18
19
20
21
22
23
  namespace Impl
  {
    template <class E, class = Void_t<>>
    struct ContextImpl
    {
      using Entity = E;
      using Geometry = typename E::Geometry;
    };

    // specialization for intersections
    template <class I>
24
    struct ContextImpl<I, Void_t<decltype(std::declval<I>().inside())>>
25
26
27
28
29
30
31
32
    {
      using Entity = typename I::Entity;
      using Geometry = typename I::LocalGeometry;
    };

  } // end namespace Impl


33
34
35
36
37
38
  /// Abstract base-class of a \ref LocalAssembler
  template <class LocalContext, class... Nodes>
  class LocalAssemblerBase
  {
  public:

39
    using Element = typename Impl::ContextImpl<LocalContext>::Entity;
40
    using Geometry = typename Element::Geometry;
41
    using LocalGeometry = typename Impl::ContextImpl<LocalContext>::Geometry;
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118

    static constexpr int numNodes = sizeof...(Nodes);
    static_assert( numNodes == 1 || numNodes == 2,
      "VectorAssembler gets 1 Node, MatrixAssembler gets 2 Nodes!");

    using ElementMatrixVector = std::conditional_t<
      (sizeof...(Nodes)==1), Impl::ElementVector, std::conditional_t<
      (sizeof...(Nodes)==2), Impl::ElementMatrix, void>>;


  public:

    virtual void bind(Element const& element, Geometry const& geometry) = 0;
    virtual void unbind() = 0;

    /// Assemble an element matrix or element vector on the test- (and trial-) function node(s)
    virtual bool assemble(LocalContext const& localContext,
                          ElementMatrixVector& elementMatrixVector,
                          Nodes const&... nodes) = 0;
  };


  template <class GridView>
  class OperatorLists
  {
    using Element = typename GridView::template Codim<0>::Entity;

    template <class OperatorType>
    struct Scaled
    {
      std::shared_ptr<OperatorType> op;
      double* factor = nullptr;
      double* estFactor = nullptr;
      BoundaryType b = {0};
    };

    template <class... Nodes>
    struct Data
    {
      using ElementOperator = LocalAssemblerBase<Element, Nodes...>;
      using IntersectionOperator = LocalAssemblerBase<typename GridView::Intersection, Nodes...>;

      std::list<Scaled<ElementOperator>> element;
      std::list<Scaled<IntersectionOperator>> boundary;
      std::list<Scaled<IntersectionOperator>> intersection;

      bool assembled = false; // if false, do reassemble
      bool changing = false; // if true, or assembled false, do reassemble

      bool empty() const
      {
        return element.empty() && boundary.empty() && intersection.empty();
      }

      bool assemble(bool flag) const
      {
        return flag && (!assembled || changing);
      }
    };

  public:

    template <class RowNode, class ColNode>
    using MatData = Data<RowNode, ColNode>;

    template <class Node>
    using VecData = Data<Node>;
  };


  template <class GlobalBasis>
  using MatrixOperators = MatrixData<GlobalBasis, OperatorLists<typename GlobalBasis::GridView>::template MatData>;

  template <class GlobalBasis>
  using VectorOperators = VectorData<GlobalBasis, OperatorLists<typename GlobalBasis::GridView>::template VecData>;

} // end namespace AMDiS