Flow123d  release_2.1.2-337-g6b7a56b
fe_rt.hh
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.hh
15  * @brief Definitions of Raviart-Thomas finite elements.
16  * @author Jan Stebel
17  */
18 
19 #ifndef FE_RT_HH_
20 #define FE_RT_HH_
21 
22 #include "fem/finite_element.hh"
23 
24 
25 
26 /**
27  * @brief Raviart-Thomas element of order 0.
28  *
29  * The lowest order Raviart-Thomas finite element with linear basis functions
30  * and continuous normal components across element sides.
31  */
32 template <unsigned int dim, unsigned int spacedim>
33 class FE_RT0 : public FiniteElement<dim,spacedim>
34 {
44 
45 public:
46 
47  /// Number of raw basis functions.
48  static const unsigned int n_raw_functions = dim+1;
49 
50  /**
51  * @brief Constructor.
52  */
53  FE_RT0();
54 
55  /**
56  * @brief The scalar variant of basis_vector must be implemented but may not be used.
57  */
58  double basis_value(const unsigned int i, const arma::vec::fixed<dim> &p) const;
59 
60  /**
61  * @brief The scalar variant of basis_grad_vector must be implemented but may not be used.
62  */
63  arma::vec::fixed<dim> basis_grad(const unsigned int i, const arma::vec::fixed<dim> &p) const;
64 
65  /**
66  * @brief Returns the @p ith basis function evaluated at the point @p p.
67  * @param i Number of the basis function.
68  * @param p Point of evaluation.
69  */
70  arma::vec::fixed<dim> basis_vector(const unsigned int i, const arma::vec::fixed<dim> &p) const;
71 
72  /**
73  * @brief Returns the gradient of the @p ith basis function at the point @p p.
74  * @param i Number of the basis function.
75  * @param p Point of evaluation.
76  */
77  arma::mat::fixed<dim,dim> basis_grad_vector(const unsigned int i, const arma::vec::fixed<dim> &p) const;
78 
79  /**
80  * @brief Computes the conversion matrix from internal basis to shape functions.
81  *
82  * Initializes the @p node_matrix for computing the coefficients
83  * of the raw basis functions from values at support points.
84  * Since Raviart-Thomas element is not Lagrangean, the method has
85  * to be reimplemented.
86  */
87  void compute_node_matrix();
88 
89  /**
90  * @brief Calculates the data on the reference cell.
91  *
92  * @param q Quadrature.
93  * @param flags Flags that indicate what quantities should be calculated.
94  */
96 
97  /**
98  * @brief Decides which additional quantities have to be computed
99  * for each cell.
100  */
102 
103  /**
104  * @brief Computes the shape function values and gradients on the actual cell
105  * and fills the FEValues structure.
106  *
107  * @param q Quadrature.
108  * @param data The precomputed finite element data on the reference cell.
109  * @param fv_data The data to be computed.
110  */
111  virtual void fill_fe_values(const Quadrature<dim> &q,
112  FEInternalData &data,
113  FEValuesData<dim,spacedim> &fv_data);
114 
115  /**
116  * @brief Destructor.
117  */
118  virtual ~FE_RT0() {};
119 
120 };
121 
122 
123 
124 
125 
126 
127 
128 
129 
130 
131 template<unsigned int dim, unsigned int spacedim>
133 {
134  arma::vec::fixed<dim> sp;
135 
136  this->init();
137 
138  number_of_dofs = dim+1;
139  number_of_single_dofs[dim] = dim+1;
140 
141  for (unsigned int sid=0; sid<RefElement<dim>::n_sides; ++sid)
142  {
143  sp.fill(0);
144  for (unsigned int i=0; i<RefElement<dim>::n_nodes_per_side; ++i)
147  generalized_support_points.push_back(sp);
148  }
149 
150  order = 1;
151 
152  is_scalar_fe = false;
153 
155 }
156 
157 template<unsigned int dim, unsigned int spacedim>
158 double FE_RT0<dim,spacedim>::basis_value(const unsigned int i, const arma::vec::fixed<dim> &p) const
159 {
160  OLD_ASSERT(false, "basis_value() may not be called for vectorial finite element.");
161 
162  return 0.0;
163 }
164 
165 template<unsigned int dim, unsigned int spacedim>
166 arma::vec::fixed<dim> FE_RT0<dim,spacedim>::basis_grad(const unsigned int i, const arma::vec::fixed<dim> &p) const
167 {
168  OLD_ASSERT(false, "basis_grad() may not be called for vectorial finite element.");
169  return arma::vec::fixed<dim>();
170 }
171 
172 template<unsigned int dim, unsigned int spacedim>
173 arma::vec::fixed<dim> FE_RT0<dim,spacedim>::basis_vector(const unsigned int i, const arma::vec::fixed<dim> &p) const
174 {
175  OLD_ASSERT(i<n_raw_functions, "Index of basis function is out of range.");
176 
177  arma::vec::fixed<dim> v(p);
178 
179  if (i > 0)
180  v[i-1] -= 1;
181 
182  return v;
183 }
184 
185 template<unsigned int dim, unsigned int spacedim>
186 arma::mat::fixed<dim,dim> FE_RT0<dim,spacedim>::basis_grad_vector(const unsigned int i, const arma::vec::fixed<dim> &p) const
187 {
188  OLD_ASSERT(i<n_raw_functions, "Index of basis function is out of range.");
189 
190  return arma::eye(dim,dim);
191 }
192 
193 template<unsigned int dim, unsigned int spacedim>
195 {
196  arma::mat::fixed<n_raw_functions,dim+1> F;
197  arma::vec::fixed<dim> r;
198 
199  /*
200  * Node matrix helps creating the shape functions $\{b_k\}$ from
201  * the raw basis $\{r_i\}$:
202  *
203  * $$ b_k = \sum_{i=0}^{dim*(dim+1)-1} N_{ki} r_i. $$
204  *
205  * The shape functions must obey the flux condition
206  *
207  * $$ b_k\cdot n_j |\Gamma_j| = \delta_{kj}, $$
208  *
209  * where $n_j$, $|\Gamma_j|$ is the unit outward normal vector and
210  * the area of the $j$-th side, respectively. Consequently,
211  * the node matrix $N$ is determined as the Moon-Penrose
212  * pseudoinverse of the flux matrix, i.e.:
213  *
214  * $$ NF = I,\quad F_{ij} = r_i\cdot n_j |\Gamma_j|. $$
215  *
216  */
217 
218  for (unsigned int i=0; i<n_raw_functions; i++)
219  {
220  for (unsigned int j=0; j<dim+1; ++j)
221  {
224  }
225  }
226 
227  if (dim>0) node_matrix = inv(F);
228 
229 }
230 
231 template<unsigned int dim, unsigned int spacedim>
233 {
234  FEInternalData *data = new FEInternalData;
235 
236  if (flags & update_values)
237  {
238  arma::mat::fixed<n_raw_functions,dim> raw_values;
239  arma::mat::fixed<dim+1,dim> shape_values;
240  vector<arma::vec> values;
241 
242  data->basis_vectors.resize(q.size());
243  values.resize(dim+1);
244  for (unsigned int i=0; i<q.size(); i++)
245  {
246  for (unsigned int j=0; j<n_raw_functions; j++)
247  raw_values.row(j) = trans(basis_vector(j, q.point(i)));
248 
249  shape_values = node_matrix * raw_values;
250 
251  for (unsigned int j=0; j<dim+1; j++)
252  values[j] = trans(shape_values.row(j));
253 
254  data->basis_vectors[i] = values;
255  }
256  }
257 
258  if (flags & update_gradients)
259  {
260  arma::mat::fixed<dim,dim> grad;
261  arma::mat::fixed<dim,dim> shape_grads;
262  vector<arma::mat> grads;
263 
264  data->basis_grad_vectors.resize(q.size());
265  grads.resize(dim+1);
266  for (unsigned int i=0; i<q.size(); i++)
267  {
268  for (unsigned int k=0; k<dim+1; k++)
269  {
270  grad.zeros();
271  for (unsigned int l=0; l<n_raw_functions; l++)
272  grad += basis_grad_vector(l, q.point(i)) * node_matrix(k,l);
273  grads[k] = grad;
274  }
275 
276  data->basis_grad_vectors[i] = grads;
277  }
278  }
279 
280  return data;
281 }
282 
283 template<unsigned int dim, unsigned int spacedim> inline
285 {
286  UpdateFlags f = flags;
287 
288  if (flags & update_values)
290 
291  if (flags & update_gradients)
293 
294  return f;
295 }
296 
297 template<unsigned int dim, unsigned int spacedim> inline
299  const Quadrature<dim> &q,
300  FEInternalData &data,
302 {
303  // shape values
304  if (fv_data.update_flags & update_values)
305  {
306  vector<arma::vec::fixed<spacedim> > vectors;
307  vectors.resize(dim+1);
308  for (unsigned int i = 0; i < q.size(); i++)
309  {
310  for (unsigned int k=0; k<dim+1; k++)
311  vectors[k] = fv_data.jacobians[i]*data.basis_vectors[i][k]/fv_data.determinants[i];
312 
313  fv_data.shape_vectors[i] = vectors;
314  }
315  }
316 
317  // shape gradients
318  if (fv_data.update_flags & update_gradients)
319  {
320  vector<arma::mat::fixed<spacedim,spacedim> > grads;
321  grads.resize(dim+1);
322  for (unsigned int i = 0; i < q.size(); i++)
323  {
324  for (unsigned int k=0; k<dim+1; k++)
325  grads[k] = fv_data.jacobians[i]*data.basis_grad_vectors[i][k]*fv_data.inverse_jacobians[i]/fv_data.determinants[i];
326 
327  fv_data.shape_grad_vectors[i] = grads;
328  }
329  }
330 }
331 
332 
333 
334 
335 
336 
337 
338 
339 
340 
341 
342 
343 
344 #endif /* FE_RT_HH_ */
Shape function values.
Definition: update_flags.hh:87
UpdateFlags
Enum type UpdateFlags indicates which quantities are to be recomputed on each finite element cell...
Definition: update_flags.hh:67
void init()
Clears all internal structures.
Determinant of the Jacobian.
std::vector< arma::mat::fixed< dim, spacedim > > inverse_jacobians
Inverse Jacobians at the quadrature points.
Definition: fe_values.hh:82
UpdateFlags update_flags
Flags that indicate which finite element quantities are to be computed.
Definition: fe_values.hh:121
double basis_value(const unsigned int i, const arma::vec::fixed< dim > &p) const
The scalar variant of basis_vector must be implemented but may not be used.
Definition: fe_rt.hh:158
FE_RT0()
Constructor.
Definition: fe_rt.hh:132
arma::mat::fixed< dim, dim > basis_grad_vector(const unsigned int i, const arma::vec::fixed< dim > &p) const
Returns the gradient of the ith basis function at the point p.
Definition: fe_rt.hh:186
std::vector< std::vector< arma::mat::fixed< spacedim, spacedim > > > shape_grad_vectors
Gradients of shape functions (for vectorial finite elements).
Definition: fe_values.hh:110
FEInternalData * initialize(const Quadrature< dim > &q, UpdateFlags flags)
Calculates the data on the reference cell.
Definition: fe_rt.hh:232
std::vector< std::vector< arma::vec > > basis_vectors
Precomputed values of basis functions at the quadrature points.
virtual void fill_fe_values(const Quadrature< dim > &q, FEInternalData &data, FEValuesData< dim, spacedim > &fv_data)
Computes the shape function values and gradients on the actual cell and fills the FEValues structure...
Definition: fe_rt.hh:298
bool is_scalar_fe
Indicator of scalar versus vectorial finite element.
unsigned int number_of_dofs
Total number of degrees of freedom at one finite element.
Base class for quadrature rules on simplices in arbitrary dimensions.
Definition: fe_values.hh:31
Volume element.
std::vector< arma::vec::fixed< dim > > generalized_support_points
Support points for non-Lagrangean finite elements.
#define OLD_ASSERT(...)
Definition: global_defs.h:131
std::vector< arma::mat::fixed< spacedim, dim > > jacobians
Jacobians of the mapping at the quadrature points.
Definition: fe_values.hh:72
unsigned int number_of_single_dofs[dim+1]
Number of single dofs at one geometrical entity of the given dimension (point, line, triangle, tetrahedron).
Raviart-Thomas element of order 0.
Definition: fe_rt.hh:33
arma::vec::fixed< dim > basis_grad(const unsigned int i, const arma::vec::fixed< dim > &p) const
The scalar variant of basis_grad_vector must be implemented but may not be used.
Definition: fe_rt.hh:166
virtual ~FE_RT0()
Destructor.
Definition: fe_rt.hh:118
UpdateFlags update_each(UpdateFlags flags)
Decides which additional quantities have to be computed for each cell.
Definition: fe_rt.hh:284
void compute_node_matrix()
Computes the conversion matrix from internal basis to shape functions.
Definition: fe_rt.hh:194
Shape function gradients.
Definition: update_flags.hh:95
std::vector< std::vector< arma::mat > > basis_grad_vectors
Precomputed gradients of basis functions at the quadrature points.
static double side_measure(unsigned int sid)
arma::vec::fixed< dim > basis_vector(const unsigned int i, const arma::vec::fixed< dim > &p) const
Returns the ith basis function evaluated at the point p.
Definition: fe_rt.hh:173
std::vector< std::vector< arma::vec::fixed< spacedim > > > shape_vectors
Shape functions (for vectorial finite elements) evaluated at quadrature points.
Definition: fe_values.hh:105
unsigned int order
Polynomial order - to be possibly used in hp methods.
Class FEValuesData holds the arrays of data computed by Mapping and FiniteElement.
Definition: fe_values.hh:46
const unsigned int size() const
Returns number of quadrature points.
Definition: quadrature.hh:125
std::vector< double > determinants
Determinants of Jacobians at quadrature points.
Definition: fe_values.hh:77
const arma::vec::fixed< dim > & point(const unsigned int i) const
Returns the ith quadrature point.
Definition: quadrature.hh:130
Structure for storing the precomputed finite element data.
Abstract class for description of finite elements.
Abstract class for the description of a general finite element on a reference simplex in dim dimensio...
Definition: dofhandler.hh:29
arma::mat node_matrix
Matrix that determines the coefficients of the raw basis functions from the values at the support poi...
static const unsigned int n_raw_functions
Number of raw basis functions.
Definition: fe_rt.hh:48