DirichletBC.inc.hpp 1.91 KB
Newer Older
1
2
3
4
5
6
7
8
9
#pragma once

#include <type_traits>

#include <dune/common/hybridutilities.hh>
#include <dune/functions/functionspacebases/boundarydofs.hh>
#include <dune/functions/functionspacebases/interpolate.hh>
#include <dune/functions/functionspacebases/subspacebasis.hh>

10
#include <amdis/LinearAlgebra.hpp>
11
12
13
14

namespace AMDiS {

template <class D, class R>
15
  template <class RB, class CB>
16
void DirichletBC<D,R>::
17
init(RB const& rowBasis, CB const& colBasis)
18
19
{
  using Dune::Functions::forEachBoundaryDOF;
20
21
  using LV = typename CB::LocalView;
  using IS = typename CB::GridView::Intersection;
22
  dirichletNodes_.resize(colBasis.dimension());
23
  std::fill(dirichletNodes_.begin(), dirichletNodes_.end(), false);
24
  forEachBoundaryDOF(colBasis, [&](int localIndex, LV const& localView, IS const& intersection) {
25
    dirichletNodes_[localView.index(localIndex)] = dirichletNodes_[localView.index(localIndex)] || onBoundary(intersection);
26
27
28
29
30
  });
}


template <class D, class R>
31
  template <class Mat, class Sol, class Rhs, class RN, class RTP, class CN, class CTP>
32
void DirichletBC<D,R>::
33
fillBoundaryCondition(Mat& matrix, Sol& solution, Rhs& rhs, RN const& rowNode, RTP rowTreePath, CN const& colNode, CTP colTreePath)
34
{
35
  auto columns = Constraints<Mat>::dirichletBC(matrix, dirichletNodes_);
36

37
  Dune::Hybrid::ifElse(std::is_same<RangeType_t<RN>, R>{},
38
    [&](auto id) {
39
      auto subBasis = Dune::Functions::subspaceBasis(*rhs.basis(), rowTreePath);
40
41
42
43
44
45
46
      Dune::Functions::interpolate(subBasis, rhs, values_, dirichletNodes_);
    });

  // subtract columns of dirichlet nodes from rhs
  for (auto const& triplet : columns)
    rhs[triplet.row] -= triplet.value * solution[triplet.col];

47
  Dune::Hybrid::ifElse(std::is_same<RangeType_t<CN>, R>{},
48
    [&](auto id) {
49
      auto subBasis = Dune::Functions::subspaceBasis(*solution.basis(), colTreePath);
50
51
52
53
54
      Dune::Functions::interpolate(subBasis, solution, values_, dirichletNodes_);
    });
}

} // end namespace AMDiS