DirichletBC.h 5.04 KB
Newer Older
1 2 3 4 5 6 7
/******************************************************************************
 *
 * AMDiS - Adaptive multidimensional simulations
 *
 * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved.
 * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis
 *
8
 * Authors:
9 10 11 12 13 14 15 16 17
 * Simon Vey, Thomas Witkowski, Andreas Naumann, Simon Praetorius, et al.
 *
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 *
 *
 * This file is part of AMDiS
 *
 * See also license.opensource.txt in the distribution.
18
 *
19
 ******************************************************************************/
20 21


22 23 24 25 26 27

/** \file DirichletBC.h */

#ifndef AMDIS_DIRICHLETBC_H
#define AMDIS_DIRICHLETBC_H

28
#include "AMDiS_fwd.h"
29 30
#include "BoundaryCondition.h"
#include "AbstractFunction.h"
31
#include "FixVec.h"
32

33
namespace AMDiS
34
{
35

36 37 38 39
  // some tags used for tag-dispatching
  struct _value_by_abstractfunction {};
  struct _value_by_dofvector {};
  struct _value_by_function {};
40 41

  namespace detail
42
  {
43 44 45
    class DirichletBC : public BoundaryCondition
    {
    public:
46

47 48 49 50 51
      /// Constructor.
      DirichletBC(BoundaryType type,
		  const FiniteElemSpace *rowFeSpace,
		  const FiniteElemSpace *colFeSpace,
		  bool apply)
52 53
	: BoundaryCondition(type, rowFeSpace, colFeSpace),
	  applyBC(apply)
54 55 56 57 58 59 60 61 62 63 64 65 66
      { }

      /// Implementation of BoundaryCondition::fillBoundaryCondition().
      virtual void fillBoundaryCondition(DOFMatrix* matrix,
				ElInfo* elInfo,
				const DegreeOfFreedom* dofIndices,
				const BoundaryType* localBound,
				int nBasFcts) override;

      ///
      void initVector(DOFVectorBase<double>* vec);

      /// Implementation of BoundaryCondition::boundResidual().
67
      double boundResidual(ElInfo*,
68
			  DOFMatrix *,
69 70 71
			  const DOFVectorBase<double>*)
      {
	return 0.0;
72 73 74
      }

      /// Because this is a Dirichlet boundary condition, always return true.
75 76 77
      bool isDirichlet()
      {
	return true;
78 79 80
      }

      /// Returns \ref applyBC.
81
      bool applyBoundaryCondition()
82 83 84 85 86 87 88 89 90 91
      {
	return applyBC;
      }

    protected:

      /// Defines, if the boundary condition must be applied to the matrix. See
      /// comment of \ref BoundaryCondition::applyBoundaryCondition.
      bool applyBC;
    };
92

93 94 95 96
  } // end namespace detail



97

98 99 100 101 102 103 104 105 106 107 108
    /**
    * \ingroup Assembler
    *
    * \brief
    * Sub class of BoundaryCondition. Implements Dirichlet boundary conditions.
    * A DOFVectors is set to a given value at a Dirichlet dof and in a DOFMatrix
    * the row corresponding to a Dirichlet dof is replaced by a row containing
    * only a 1.0 in the diagonal.
    */
    template <class ValueTag>
    class DirichletBC {};
109

110
    // specialization for AbstractFunctions as value container
111
    template <>
112
    class DirichletBC<_value_by_abstractfunction> : public detail::DirichletBC
113
    {
114 115 116 117 118 119 120 121 122 123 124
      typedef detail::DirichletBC super;
    public:
      /// Constructor.
      DirichletBC(BoundaryType type,
		  AbstractFunction<double, WorldVector<double> > *fct,
		  const FiniteElemSpace *rowFeSpace,
		  const FiniteElemSpace *colFeSpace = NULL,
		  bool apply = true)
	: super(type, rowFeSpace, colFeSpace, apply),
	  container(*fct)
      { }
125 126


127
      /// Implementation of BoundaryCondition::fillBoundaryCondition().
128
      virtual void fillBoundaryCondition(DOFVectorBase<double>* vector,
129 130 131 132
				ElInfo* elInfo,
				const DegreeOfFreedom* dofIndices,
				const BoundaryType* localBound,
				int nBasFcts) override;
133

134 135
    protected:
      AbstractFunction<double, WorldVector<double> > &container;
136
    };
137 138


139
    // specialization for DOFVectors as value container
140
    template <>
141
    class DirichletBC<_value_by_dofvector> : public detail::DirichletBC
142
    {
143 144 145 146 147 148
      typedef detail::DirichletBC super;
    public:
      /// Constructor.
      DirichletBC(BoundaryType type,
		  DOFVectorBase<double> *vec,
		  bool apply = true);
149 150


151
      /// Implementation of BoundaryCondition::fillBoundaryCondition().
152
      virtual void fillBoundaryCondition(DOFVectorBase<double>* vector,
153 154 155 156
				ElInfo* elInfo,
				const DegreeOfFreedom* dofIndices,
				const BoundaryType* localBound,
				int nBasFcts) override;
157

158 159
    protected:
      DOFVectorBase<double> *container;
160
    };
161 162


163
#if AMDIS_HAS_CXX11
164
    // specialization for std::function or lambdas as value container
165
    template <>
166
    class DirichletBC<_value_by_function> : public detail::DirichletBC
167
    {
168 169 170 171 172 173 174 175 176 177 178
      typedef detail::DirichletBC super;
    public:
      /// Constructor.
      DirichletBC(BoundaryType type,
		  std::function<double(WorldVector<double>)> fct,
		  const FiniteElemSpace *rowFeSpace,
		  const FiniteElemSpace *colFeSpace = NULL,
		  bool apply = true)
	: super(type, rowFeSpace, colFeSpace, apply),
	  container(fct)
      { }
179 180


181
      /// Implementation of BoundaryCondition::fillBoundaryCondition().
182
      virtual void fillBoundaryCondition(DOFVectorBase<double>* vector,
183 184 185 186
				ElInfo* elInfo,
				const DegreeOfFreedom* dofIndices,
				const BoundaryType* localBound,
				int nBasFcts) override;
187

188 189
    protected:
      std::function<double(WorldVector<double>)> container;
190 191
    };
#endif
192 193 194
}

#endif