DirichletBC.h 4.78 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/******************************************************************************
 *
 * AMDiS - Adaptive multidimensional simulations
 *
 * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved.
 * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis
 *
 * Authors: 
 * 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.
 * 
 ******************************************************************************/
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 34
namespace AMDiS 
{
35

36 37 38 39 40 41 42 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
  // some tags used for tag-dispatching
  struct _value_by_abstractfunction {};
  struct _value_by_dofvector {};
  struct _value_by_function {};
  
  namespace detail 
  {
    template <class Tag>
    struct ValueContainer {};
    
    template <>
    struct ValueContainer<_value_by_abstractfunction> 
    {
      ValueContainer(AbstractFunction<double, WorldVector<double> > *fct) : value(*fct) {};
      ValueContainer(AbstractFunction<double, WorldVector<double> > &fct) : value(fct) {};
      
      AbstractFunction<double, WorldVector<double> > &value;
    };
    
    template <>
    struct ValueContainer<_value_by_dofvector> 
    {
      ValueContainer(DOFVectorBase<double> *vec) : value(vec) {};
      ValueContainer(DOFVectorBase<double> &vec) : value(&vec) {};
      
      DOFVectorBase<double> *value;
    };
    
#if __cplusplus > 199711L
    template <>
    struct ValueContainer<_value_by_function> 
    {
      ValueContainer(std::function<double(WorldVector<double>)> fct) : value(fct) {};
      
      std::function<double(WorldVector<double>)> value;
    };
#endif
  
  } // end namespace detail
  
76 77 78 79 80 81 82 83 84
  /**
   * \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.
   */
85
  template <class ValueTag>
86 87 88
  class DirichletBC : public BoundaryCondition
  {
  public:
89
    /// Constructor.
90
    DirichletBC(BoundaryType type,
91
		AbstractFunction<double, WorldVector<double> > *fct,
92
		const FiniteElemSpace *rowFeSpace,
93
		const FiniteElemSpace *colFeSpace = NULL,
94
		bool apply = true);
95 96 97 98 99 100 101 102 103
		
#if __cplusplus > 199711L
    /// Constructor.
    DirichletBC(BoundaryType type,
		std::function<double(WorldVector<double>)> fct,
		const FiniteElemSpace *rowFeSpace,
		const FiniteElemSpace *colFeSpace = NULL,
		bool apply = true);
#endif
104

105
    /// Constructor.
106
    DirichletBC(BoundaryType type,
107 108
		DOFVectorBase<double> *vec,
		bool apply = true);
109

110
    /// Implementation of BoundaryCondition::fillBoundaryCondition().
111
    virtual void fillBoundaryCondition(DOFMatrix* matrix,
112
			       ElInfo* elInfo,
113
			       const DegreeOfFreedom* dofIndices,
114
			       const BoundaryType* localBound,
115
			       int nBasFcts) override;
116
  
117
    /// Implementation of BoundaryCondition::fillBoundaryCondition().
118
    virtual void fillBoundaryCondition(DOFVectorBase<double>* vector, 
119
			       ElInfo* elInfo,
120
			       const DegreeOfFreedom* dofIndices,
121
			       const BoundaryType* localBound,
122
			       int nBasFcts) override;
123

124 125 126
    ///
    void initVector(DOFVectorBase<double>*);

127
    /// Implementation of BoundaryCondition::boundResidual().
128 129
    double boundResidual(ElInfo*, 
			 DOFMatrix *,
130 131 132 133
			 const DOFVectorBase<double>*) 
    { 
      return 0.0; 
    }
134

135 136 137
    /// Because this is a Dirichlet boundary condition, always return true.
    bool isDirichlet() 
    { 
138 139
      return true; 
    }
140

141 142 143 144 145
    /// Returns \ref applyBC.
    bool applyBoundaryCondition() 
    {
      return applyBC;
    }
146
    
147
  protected:
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
    void fillBC(_value_by_abstractfunction,
		DOFVectorBase<double>* vector, 
		ElInfo* elInfo,
		const DegreeOfFreedom* dofIndices,
		const BoundaryType* localBound,
		int nBasFcts);
			       
    void fillBC(_value_by_function,
		DOFVectorBase<double>* vector, 
		ElInfo* elInfo,
		const DegreeOfFreedom* dofIndices,
		const BoundaryType* localBound,
		int nBasFcts);
			       
    void fillBC(_value_by_dofvector,
		DOFVectorBase<double>* vector, 
		ElInfo* elInfo,
		const DegreeOfFreedom* dofIndices,
		const BoundaryType* localBound,
		int nBasFcts);
168

169 170
  protected:
    detail::ValueContainer<ValueTag> container;
171

172 173
    /// Defines, if the boundary condition must be applied to the matrix. See
    /// comment of \ref BoundaryCondition::applyBoundaryCondition.
174
    bool applyBC;
175 176 177 178
  };

}

179 180
#include "DirichletBC.hh"

181
#endif