Flow123d  release_3.0.0-1159-g9e13a92
quadrature.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 quadrature.hh
15  * @brief Basic definitions of numerical quadrature rules.
16  * @author Jan Stebel
17  */
18 
19 #ifndef QUADRATURE_HH_
20 #define QUADRATURE_HH_
21 
22 #include <armadillo>
23 #include <vector>
24 
25 #include "system/armor.hh"
26 #include "mesh/ref_element.hh"
27 
28 
29 
30 /**
31  * @brief Base class for quadrature rules on simplices in arbitrary dimensions.
32  *
33  * This class stores quadrature points and weights on the reference line,
34  * triangle or tetrahedron, respectively.
35  * Quadrature rules are used for evaluation of integrals over elements.
36  * In particular, for a reference element @f$E@f$ we have:
37  * @f[
38  * \int_E f(x)\,dx \approx \sum_{i=1}^{N} w_i f(p_i),
39  * @f]
40  * where @f$\{w_i\}@f$, @f$\{p_i\}@f$ are the quadrature weights and the quadrature points,
41  * respectively.
42  *
43  * TODO:
44  * - remove set_weight, set point; quadrature should be set by its descendants
45  * - introduce Quadrature point which should store point coords together with the weight in raw double[1+dim] array
46  * and just return arma object on the flys
47  */
48 template<unsigned int dim>
49 class Quadrature {
50 public:
51  /**
52  * @brief Constructor.
53  * @param n_quadrature_points Number of quadrature points to be allocated.
54  */
55  Quadrature(const unsigned int n_quadrature_points = 0);
56 
57  /// Copy constructor.
58  Quadrature(const Quadrature<dim> &q);
59 
60  /** @brief Constructor from quadrature of lower dimension (e.g. for side integration).
61  * @param sub_quadrature lower dimnesional (dim-1) quadrature
62  * @param sid local index of side
63  * @param pid index of permutation of nodes on given side
64  */
65  Quadrature(const Quadrature<dim-1> &sub_quadrature, unsigned int sid, unsigned int pid);
66 
67  /// Virtual destructor.
68  virtual ~Quadrature();
69 
70  /**
71  * @brief Modify the number of quadrature points.
72  * @param n_q_points New number of quadrature points.
73  */
74  void resize(const unsigned int n_q_points);
75 
76  /// Returns number of quadrature points.
77  const unsigned int size() const;
78 
79  /// Returns the <tt>i</tt>th quadrature point.
80  arma::vec::fixed<dim> point(const unsigned int i) const;
81 
82  /// Return a reference to the whole array of quadrature points.
83  const Armor::array & get_points() const;
84 
85  /**
86  * @brief Sets individual quadrature point coordinates.
87  * @param i Number of the quadrature point.
88  * @param p New coordinates.
89  */
90  void set_point(const unsigned int i, const arma::vec::fixed<dim> &p);
91 
92  /// Returns the <tt>i</tt>th weight.
93  double weight(const unsigned int i) const;
94 
95  /// Return a reference to the whole array of weights.
96  const std::vector<double> & get_weights() const;
97 
98  /// Sets individual quadrature weight.
99  void set_weight(const unsigned int i, const double w);
100 
101 protected:
102  /**
103  * @brief List of quadrature points.
104  *
105  * To be filled by the constructors of the derived classes.
106  */
108 
109  /**
110  * @brief List of weights to the quadrature points.
111  *
112  * To be filled by the constructors of the derived classes.
113  */
115 
116 };
117 
118 
119 
120 template<unsigned int dim>
121 Quadrature<dim>::Quadrature(const unsigned int n_q)
122 : quadrature_points(n_q, dim),
123  weights(n_q, 0)
124 {}
125 
126 template<unsigned int dim>
129  weights(q.weights)
130 {}
131 
132 template<unsigned int dim>
133 void Quadrature<dim>::resize(const unsigned int n_q)
134 {
136  weights.resize(n_q, 0);
137 }
138 
139 template<unsigned int dim>
140 inline const unsigned int Quadrature<dim>::size() const {
141  return weights.size();
142 }
143 
144 template<unsigned int dim>
145 inline arma::vec::fixed<dim> Quadrature<dim>::point(
146  const unsigned int i) const {
147  return quadrature_points.get<dim>(i).arma();
148 }
149 
150 template<unsigned int dim>
152  return quadrature_points;
153 }
154 
155 template<unsigned int dim>
156 inline void Quadrature<dim>::set_point(const unsigned int i, const arma::vec::fixed<dim> &p)
157 {
158  quadrature_points.get<dim>(i) = p;
159 }
160 
161 template<unsigned int dim>
162 inline double Quadrature<dim>::weight(const unsigned int i) const {
163  return weights[i];
164 }
165 
166 template<unsigned int dim>
168  return weights;
169 }
170 
171 template<unsigned int dim>
172 inline void Quadrature<dim>::set_weight(const unsigned int i, const double w)
173 {
174  weights[i] = w;
175 }
176 
177 template<unsigned int dim>
179 {}
180 
181 template<unsigned int dim> inline
182 Quadrature<dim>::Quadrature(const Quadrature<dim-1> &subq, unsigned int sid, unsigned int pid)
183 : quadrature_points(subq.size(), dim)
184 {
185  // Below we permute point coordinates according to permutation
186  // of nodes on side. We just check that these numbers equal.
188  resize(subq.size());
189 
190 // double lambda;
191 //
192 // // vectors of barycentric coordinates of quadrature points
193 // arma::vec::fixed<dim+1> el_bar_coords;
194 // arma::vec::fixed<dim> side_bar_coords;
195 //
196 // for (unsigned int k=0; k<subq.size(); k++)
197 // {
198 // const arma::vec::fixed<dim-1> &sub_point = subq.point(k);
199 // // Calculate barycentric coordinates on the side of the k-th
200 // // quadrature point.
201 // el_bar_coords.zeros();
202 // lambda = 0;
203 // // Apply somewhere permutation of indices!
204 // for (unsigned int j=0; j<dim-1; j++)
205 // {
206 // side_bar_coords(j) = sub_point(j);
207 // lambda += sub_point(j);
208 // }
209 // side_bar_coords(dim-1) = 1.0 - lambda;
210 //
211 // // transform to element coordinates
212 // auto side_nodes = RefElement<dim>::interact(Interaction<0, (dim - 1)>(sid));
213 // for (unsigned int i=0; i<dim; i++) {
214 // // TODO: use RefElement<>::interpolate to map coordinates from the subelement
215 // unsigned int i_node = (side_nodes[RefElement<dim>::side_permutations[pid][i]]+dim)%(dim+1);
216 // el_bar_coords(i_node) = side_bar_coords((i+dim-1)%dim);
217 // }
218 // quadrature_points[k] = el_bar_coords.subvec(0,dim-1);
219 // weights[k] = subq.weight(k);
220 // }
221 
222  arma::vec::fixed<dim+1> el_bar_coords, final_bar;
223 
224  for (unsigned int k=0; k<subq.size(); k++)
225  {
226  //compute barycentric coordinates on element
227  arma::vec::fixed<dim> p = RefElement<dim-1>::local_to_bary(subq.point(k));
228  arma::vec::fixed<dim> pp;
229 
230  //permute
231  for (unsigned int i=0; i<RefElement<dim>::n_nodes_per_side; i++) {
232  pp(RefElement<dim>::side_permutations[pid][i]) = p(i);
233  }
234 
235  el_bar_coords = RefElement<dim>::template interpolate<dim-1>(pp,sid);
236 
237  //get local coordinates and set
238  quadrature_points.get<dim>(k) = RefElement<dim>::bary_to_local(el_bar_coords);
239  weights[k] = subq.weight(k);
240  }
241 }
242 
243 // Specialized subquadrature consructor for dim=1.
244 template<> inline
245 Quadrature<1>::Quadrature(const Quadrature<0> &subq, unsigned int sid, unsigned int pid)
246 : quadrature_points(1, 1)
247 {
248  quadrature_points.get<1>(0) = { (double)sid };
249  weights.push_back(1);
250 }
251 
252 #endif /* QUADRATURE_HH_ */
arma::vec::fixed< dim > point(const unsigned int i) const
Returns the ith quadrature point.
Definition: quadrature.hh:145
void set_weight(const unsigned int i, const double w)
Sets individual quadrature weight.
Definition: quadrature.hh:172
void resize(uint size)
Definition: armor.hh:141
Mat< Type, nr, nc > get(uint i) const
Definition: armor.hh:162
std::vector< double > weights
List of weights to the quadrature points.
Definition: quadrature.hh:114
Quadrature(const unsigned int n_quadrature_points=0)
Constructor.
Definition: quadrature.hh:121
Base class for quadrature rules on simplices in arbitrary dimensions.
Definition: fe_values.hh:35
const Armor::array & get_points() const
Return a reference to the whole array of quadrature points.
Definition: quadrature.hh:151
virtual ~Quadrature()
Virtual destructor.
Definition: quadrature.hh:178
double weight(const unsigned int i) const
Returns the ith weight.
Definition: quadrature.hh:162
void resize(const unsigned int n_q_points)
Modify the number of quadrature points.
Definition: quadrature.hh:133
void set_point(const unsigned int i, const arma::vec::fixed< dim > &p)
Sets individual quadrature point coordinates.
Definition: quadrature.hh:156
const unsigned int size() const
Returns number of quadrature points.
Definition: quadrature.hh:140
#define ASSERT_DBG(expr)
Definition: asserts.hh:349
const std::vector< double > & get_weights() const
Return a reference to the whole array of weights.
Definition: quadrature.hh:167
static BaryPoint local_to_bary(const LocalPoint &lp)
Converts from local to barycentric coordinates.
Definition: ref_element.cc:296
Class RefElement defines numbering of vertices, sides, calculation of normal vectors etc...
Armor::array quadrature_points
List of quadrature points.
Definition: quadrature.hh:107