Flow123d  JS_before_hm-1008-g3dab983
fe_rt.cc
Go to the documentation of this file.
1 /*!
2  *
3  * Copyright (C) 2015 Technical University of Liberec. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it under
6  * the terms of the GNU General Public License version 3 as published by the
7  * Free Software Foundation. (http://www.gnu.org/licenses/gpl-3.0.en.html)
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12  *
13  *
14  * @file fe_rt.cc
15  * @brief Definitions of Raviart-Thomas finite elements.
16  * @author Jan Stebel
17  */
18 
19 #include "mesh/accessors.hh"
20 #include "fem/fe_rt.hh"
21 #include "fem/fe_values.hh"
22 #include "mesh/ref_element.hh"
24 #include "system/fmt/posix.h" // for FMT_UNUSED
25 
26 
27 RT0_space::RT0_space(unsigned int dim)
28  : FunctionSpace(dim, dim)
29 {}
30 
31 
32 double RT0_space::basis_value(unsigned int basis_index,
33  const arma::vec &point,
34  unsigned int comp_index) const
35 {
36  OLD_ASSERT(basis_index < this->dim(), "Index of basis function is out of range.");
37  OLD_ASSERT(comp_index < this->n_components_, "Index of component is out of range.");
38 
39  if (basis_index>0 && comp_index==basis_index-1)
40  return point[comp_index]-1;
41  else
42  return point[comp_index];
43 }
44 
45 
46 const arma::vec RT0_space::basis_grad(FMT_UNUSED unsigned int basis_index,
47  FMT_UNUSED const arma::vec &point,
48  unsigned int comp_index) const
49 {
50  OLD_ASSERT(basis_index < this->dim(), "Index of basis function is out of range.");
51  OLD_ASSERT(comp_index < this->n_components_, "Index of component is out of range.");
52 
53  arma::vec g(this->space_dim_);
54  g.zeros();
55  g[comp_index] = 1;
56 
57  return g;
58 }
59 
60 
61 template<> FE_RT0<0>::FE_RT0()
62 {
63  arma::vec::fixed<1> sp; sp[0] = 0.;
64  arma::vec::fixed<2> bsp; bsp[0] = 1.; bsp[1] = 0.;
65 
66  this->init(false, FEVectorPiola);
67  this->function_space_ = make_shared<RT0_space>(0);
68 
69  this->dofs_.push_back(Dof(0, 0, bsp, sp, Value));
70  this->component_indices_.clear();
71 }
72 
73 
74 
75 template<unsigned int dim>
77 {
78  arma::vec::fixed<dim> sp;
79 
80  this->init(false, FEVectorPiola);
81  this->function_space_ = make_shared<RT0_space>(dim);
82 
83  for (unsigned int sid=0; sid<RefElement<dim>::n_sides; ++sid)
84  {
85  sp.fill(0);
86  for (unsigned int i=0; i<RefElement<dim>::n_nodes_per_side; ++i)
89  // barycentric coordinates
90  arma::vec::fixed<dim+1> bsp;
91  bsp.subvec(1,dim) = sp;
92  bsp[0] = 1. - arma::sum(sp);
93  // The dof (flux through side) is computed as scalar product of the value with normal vector times side measure.
94  this->dofs_.push_back(Dof(dim-1, sid, bsp, RefElement<dim>::normal_vector(sid)*RefElement<dim>::side_measure(sid), Value));
95  }
96  this->component_indices_.clear();
97  this->nonzero_components_.resize(this->dofs_.size(), std::vector<bool>(this->n_components(), true));
98 
99  this->compute_node_matrix();
100 }
101 
102 
103 
104 
105 template class FE_RT0<0>;
106 template class FE_RT0<1>;
107 template class FE_RT0<2>;
108 template class FE_RT0<3>;
109 
110 
112 {
113  arma::vec::fixed<1> sp; sp[0] = 0.;
114  arma::vec::fixed<1> bsp; bsp[0] = 1.;
115 
116  this->init(false, FEVectorPiola);
117  this->function_space_ = make_shared<RT0_space>(0);
118 
119  this->dofs_.push_back(Dof(0, 0, bsp, sp, Value));
120  this->component_indices_.clear();
121 }
122 
123 
124 template<unsigned int dim>
126 {
127  arma::vec::fixed<dim> sp;
128 
129  this->init(false, FEVectorPiola);
130  this->function_space_ = make_shared<RT0_space>(dim);
131 
132  for (unsigned int sid=0; sid<RefElement<dim>::n_sides; ++sid)
133  {
134  sp.fill(0);
135  for (unsigned int i=0; i<RefElement<dim>::n_nodes_per_side; ++i)
138  // barycentric coordinates
139  arma::vec::fixed<dim+1> bsp;
140  bsp.subvec(1,dim) = sp;
141  bsp[0] = 1. - arma::sum(sp);
142  // The dof (flux through side) is computed as scalar product of the value with normal vector times side measure.
143  this->dofs_.push_back(Dof(dim, 0, bsp, RefElement<dim>::normal_vector(sid)*RefElement<dim>::side_measure(sid), Value));
144  }
145  this->component_indices_.clear();
146  this->nonzero_components_.resize(this->dofs_.size(), std::vector<bool>(this->n_components(), true));
147 
148  this->compute_node_matrix();
149 }
150 
151 
152 
153 
154 template class FE_RT0_disc<0>;
155 template class FE_RT0_disc<1>;
156 template class FE_RT0_disc<2>;
157 template class FE_RT0_disc<3>;
158 
ArmaVec< double, N > vec
Definition: armor.hh:861
FE_RT0_disc()
Constructor.
Definition: fe_rt.cc:125
RT0_space(unsigned int dim)
Definition: fe_rt.cc:27
unsigned int n_components_
Number of components of function values.
Class FEValues calculates finite element data on the actual cells such as shape function values...
double basis_value(unsigned int basis_index, const arma::vec &point, unsigned int comp_index) const override
Value of the i th basis function at point point.
Definition: fe_rt.cc:32
const arma::vec basis_grad(unsigned int basis_index, const arma::vec &point, unsigned int comp_index) const override
Gradient of the i th basis function at point point.
Definition: fe_rt.cc:46
#define OLD_ASSERT(...)
Definition: global_defs.h:131
#define FMT_UNUSED
Definition: posix.h:75
Raviart-Thomas element of order 0.
Definition: fe_rt.hh:60
unsigned int n_components() const
Getter for number of components.
FE_RT0()
Constructor.
Definition: fe_rt.cc:76
Discontinuous Raviart-Thomas element of order 0.
Definition: fe_rt.hh:81
unsigned int dim() const override
Dimension of function space (number of basis functions).
Definition: fe_rt.hh:49
Definitions of particular quadrature rules on simplices.
Class RefElement defines numbering of vertices, sides, calculation of normal vectors etc...
unsigned int space_dim_
Space dimension of function arguments (i.e. 1, 2 or 3).
Definitions of Raviart-Thomas finite elements.