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

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

7
#include <amdis/ContextGeometry.hpp>
8
9
10
#include <amdis/common/ConceptsBase.hpp>
#include <amdis/common/TypeDefs.hpp>
#include <amdis/utility/TreeData.hpp>
11
12
13
14
15
16
17
18
19

namespace AMDiS
{
  /// Abstract base-class of a \ref LocalAssembler
  template <class LocalContext, class... Nodes>
  class LocalAssemblerBase
  {
  public:

20
    using Element = typename Impl::ContextTypes<LocalContext>::Entity;
21
22
23
24
25
26
27
28
29
30
31
32
33
    using Geometry = typename Element::Geometry;

    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:

34
35
    virtual ~LocalAssemblerBase() {}

36
37
38
39
    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)
40
41
42
    virtual void assemble(LocalContext const& localContext,
                          Nodes const&... nodes,
                          ElementMatrixVector& elementMatrixVector) = 0;
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
  };


  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();
      }

78
      bool doAssemble(bool flag) const
79
80
81
      {
        return flag && (!assembled || changing);
      }
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96

      template <class Geo>
      void bind(Element const& elem, Geo const& geo)
      {
        for (auto& scaled : element) scaled.op->bind(elem,geo);
        for (auto& scaled : boundary) scaled.op->bind(elem,geo);
        for (auto& scaled : intersection) scaled.op->bind(elem,geo);
      }

      void unbind()
      {
        for (auto& scaled : element) scaled.op->unbind();
        for (auto& scaled : boundary) scaled.op->unbind();
        for (auto& scaled : intersection) scaled.op->unbind();
      }
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
    };

  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