PeriodicBC.hpp 2.76 KB
Newer Older
1
2
3
4
5
6
7
8
#pragma once

#include <functional>
#include <list>
#include <map>
#include <type_traits>
#include <vector>

9
#include <amdis/Output.hpp>
10
#include <amdis/common/ConceptsBase.hpp>
11
#include <amdis/common/FieldMatVec.hpp>
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
41
42


namespace AMDiS
{
  template <class ct, int dow>
  struct FaceTransformation
  {
    using WorldMatrix = FieldMatrix<ct, dow, dow>;
    using WorldVector = FieldVector<ct, dow>;

    WorldMatrix matrix_; // Note: We assume the matrix to be orthogonal, here
    WorldVector shift_;

    WorldVector evaluate(WorldVector const& x) const
    {
      WorldVector y = shift_;
      matrix_.umv(x, y);
      return y;
    }

    WorldVector evaluateInverse(WorldVector const& y) const
    {
      WorldVector ys = y - shift_;
      WorldVector x;
      matrix_.mtv(ys, x);
      return x;
    }
  };


  /// Implements a periodic boundary condition
43
44
45
46
  /**
   * \tparam D  Domain
   * \tparam MI Type of the MultiIndex
   **/
47
48
49
50
51
52
53
54
55
56
57
58
59
60
  template <class D, class MI>
  class PeriodicBC
      : public BoundaryCondition
  {
    using Super = BoundaryCondition;

  public:
    using Domain = D;
    using MultiIndex = MI;
    using FaceTrafo = FaceTransformation<typename D::field_type, D::dimension>;

  public:
    template <class BM>
    PeriodicBC(BM&& boundaryManager, BoundaryType id, FaceTrafo faceTrafo)
61
      : Super(FWD(boundaryManager), id)
62
63
64
      , faceTrafo_(std::move(faceTrafo))
    {}

65
66
    template <class RB, class CB>
    void init(RB const& rowBasis, CB const& colBasis);
67

68
69
    template <class Mat, class Sol, class Rhs, class RN, class CN>
    void fillBoundaryCondition(Mat& A, Sol& x, Rhs& b, RN const& rowNode, CN const& colNode);
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

    auto const& associations() const
    {
      return associations_;
    }

    auto const& periodicNodes() const
    {
      return periodicNodes_;
    }

  protected:
    template <class Basis>
    void initAssociations(Basis const& basis);

    template <class Basis>
    void initAssociations2(Basis const& basis);

    // Get the coordinates of the DOFs
    template <class Node>
    std::vector<Domain> coords(Node const& node, std::vector<std::size_t> const& localIndices) const;

  private:
    FaceTrafo faceTrafo_;

    std::vector<bool> periodicNodes_;
    std::map<std::size_t, std::size_t> associations_;
    Dune::Std::optional<bool> hasConnectedIntersections_;
  };


  template <class Basis>
  struct PeriodicData
  {
    using WorldVector = typename Basis::GridView::template Codim<0>::Geometry::GlobalCoordinate;

    template <class RowNode, class ColNode>
    using type = std::list< std::shared_ptr<PeriodicBC<WorldVector, typename Basis::MultiIndex>> >;
  };

  template <class RowBasis, class ColBasis>
  using PeriodicBCs = MatrixData<RowBasis, ColBasis, PeriodicData<RowBasis>::template type>;

} // end namespace AMDiS

#include "PeriodicBC.inc.hpp"