DirichletBC.hpp 1.97 KB
Newer Older
1 2 3 4 5 6
#pragma once

#include <functional>
#include <type_traits>
#include <vector>

7
#include <dune/amdis/common/ConceptsBase.hpp>
8

9 10
#include "Log.hpp"

11 12
namespace AMDiS
{
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
  /// Implements a boundary condition of Dirichlet-type.
  /**
   * By calling the methods \ref init() and \ref finish before and after 
   * assembling the system-matrix, respectively, dirichlet boundary conditions
   * can be applied to the matrix and system vector. Therefore a predicate 
   * functions indicates the DOFs where values should be enforced and a second
   * functor provided in the constructor is responsible for determining the 
   * values to be set at the DOFs.
   * 
   * In the \ref finish method the matrix is called with \ref applyDirichletBC 
   * to erase the corresponding rows and columns for the DOF indices. This 
   * application of boundary conditions can be symmetric if the matrix does 
   * support this symmetric modification. As a result, this method returns a list
   * of columns values, that should be subtracted from the rhs.
   **/
28 29 30 31 32
  template <class WorldVector>
  class DirichletBC
  {
  public:
    template <class Predicate, class Values,
33 34
      class = std::enable_if_t< Concepts::Functor<Predicate, bool(WorldVector)> &&
				Concepts::Functor<Values,  double(WorldVector)> > >
35 36
    DirichletBC(Predicate&& predicate, Values&& values)
      : predicate(std::forward<Predicate>(predicate))
37
      , values(std::forward<Values>(values))
38 39 40
    {}
    
    
41
    template <class Matrix, class VectorX, class VectorB>
42
    void init(bool apply, 
43 44 45
	      Matrix& matrix, 
	      VectorX& rhs, 
	      VectorB& solution);
46 47
    
    
48
    template <class Matrix, class VectorX, class VectorB>
49
    void finish(bool apply, 
50 51 52
		Matrix& matrix, 
		VectorX& rhs, 
		VectorB& solution);
53 54 55 56 57 58 59 60 61 62 63 64
    
  private:
    std::function<bool(WorldVector)> predicate;
    std::function<double(WorldVector)> values;
    
    bool initialized = false;
    std::vector<char> dirichletNodes;
  };

} // end namespace AMDiS

#include "DirichletBC.inc.hpp"