Flow123d  JS_before_hm-2-g912b55d
mapping_p1.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 mapping_p1.cc
15  * @brief Class MappingP1 implements the affine transformation of
16  * the unit cell onto the actual cell.
17  * @author Jan Stebel
18  */
19 
20 #include "fem/mapping_p1.hh"
21 #include "quadrature/quadrature.hh"
22 #include "fem/fe_values.hh"
23 
24 
25 
26 using namespace std;
27 
28 
29 
30 template<unsigned int dim, unsigned int spacedim>
32 {
33 }
34 
35 template<unsigned int dim, unsigned int spacedim>
37 {
38  ASSERT_DBG( q.dim() == dim );
40 
41  // Initialize the gradients of the canonical basis in the
42  // barycentric coordinates.
43  // In the case of P1 mapping the shape functions are linear,
44  // hence the gradients are constant and can be precomputed.
45  if ((flags & update_jacobians) |
46  (flags & update_volume_elements) |
47  (flags & update_JxW_values) |
48  (flags & update_side_JxW_values) |
49  (flags & update_inverse_jacobians))
50  {
51  grad.zeros();
52  for (unsigned int i=0; i<dim; i++)
53  {
54  grad(0,i) = -1;
55  grad(i+1,i) = 1;
56  }
57  }
58 
59  // barycentric coordinates of quadrature points
60  if (flags & update_quadrature_points)
61  {
62  data->bar_coords.resize(q.size());
63  for (unsigned int i=0; i<q.size(); i++)
64  data->bar_coords[i] = RefElement<dim>::local_to_bary(q.point<dim>(i).arma());
65  }
66 
67 
68 
69  return data;
70 }
71 
72 template<unsigned int dim, unsigned int spacedim>
74 {
75  UpdateFlags f = flags;
76 
77  if (flags & update_normal_vectors)
79 
80  if ((flags & update_volume_elements) |
81  (flags & update_JxW_values) |
82  (flags & update_inverse_jacobians))
83  f |= update_jacobians;
84 
85  return f;
86 }
87 
88 
89 template<unsigned int dim, unsigned int spacedim>
91  const Quadrature &q,
92  MappingInternalData &data,
94 {
95  ASSERT_DBG( q.dim() == dim );
96  ElementMap coords;
97  arma::mat::fixed<spacedim,dim> jac;
98 
99  if ((fv_data.update_flags & update_jacobians) |
101  (fv_data.update_flags & update_JxW_values) |
104  {
105  coords = element_map(cell);
106  }
107 
108  // calculation of Jacobian dependent data
109  if ((fv_data.update_flags & update_jacobians) |
111  (fv_data.update_flags & update_JxW_values) |
113  {
114  jac = coords*grad;
115 
116  // update Jacobians
117  if (fv_data.update_flags & update_jacobians)
118  for (unsigned int i=0; i<q.size(); i++)
119  fv_data.jacobians[i] = jac;
120 
121  // calculation of determinant dependent data
123  {
124  double det = fabs(determinant(jac));
125 
126  // update determinants
127  if (fv_data.update_flags & update_volume_elements)
128  for (unsigned int i=0; i<q.size(); i++)
129  fv_data.determinants[i] = det;
130 
131  // update JxW values
132  if (fv_data.update_flags & update_JxW_values)
133  for (unsigned int i=0; i<q.size(); i++)
134  fv_data.JxW_values[i] = det*q.weight(i);
135  }
136 
137  // update inverse Jacobians
139  {
140  arma::mat::fixed<dim,spacedim> ijac;
141  if (dim==spacedim)
142  {
143  ijac = inv(jac);
144  }
145  else
146  {
147  ijac = pinv(jac);
148  }
149  for (unsigned int i=0; i<q.size(); i++)
150  fv_data.inverse_jacobians[i] = ijac;
151  }
152  }
153 
154  // quadrature points in the actual cell coordinate system
156  {
157  BaryPoint basis;
158  for (unsigned int i=0; i<q.size(); i++)
159  fv_data.points[i] = coords*data.bar_coords[i];
160  }
161 }
162 
163 template<unsigned int dim, unsigned int spacedim>
165  unsigned int sid,
166  const Quadrature &q,
167  MappingInternalData &data,
169 {
170  ASSERT_DBG( q.dim() == dim );
171  ElementMap coords;
172 
173  if ((fv_data.update_flags & update_jacobians) |
176  (fv_data.update_flags & update_normal_vectors) |
178  {
179  coords = element_map(cell);
180  }
181 
182  // calculation of cell Jacobians and dependent data
183  if ((fv_data.update_flags & update_jacobians) |
187  {
188  arma::mat::fixed<spacedim,dim> jac = coords*grad;
189 
190  // update cell Jacobians
191  if (fv_data.update_flags & update_jacobians)
192  for (unsigned int i=0; i<q.size(); i++)
193  fv_data.jacobians[i] = jac;
194 
195  // update determinants of Jacobians
196  if (fv_data.update_flags & update_volume_elements)
197  {
198  double det = fabs(determinant(jac));
199  for (unsigned int i=0; i<q.size(); i++)
200  fv_data.determinants[i] = det;
201  }
202 
203  // inverse Jacobians
205  {
206  arma::mat::fixed<dim,spacedim> ijac;
207  if (dim==spacedim)
208  {
209  ijac = inv(jac);
210  }
211  else
212  {
213  ijac = pinv(jac);
214  }
215  ASSERT_LE_DBG(q.size(), fv_data.inverse_jacobians.size());
216  for (unsigned int i=0; i<q.size(); i++)
217  fv_data.inverse_jacobians[i] = ijac;
218 
219  // calculation of normal vectors to the side
220  if ((fv_data.update_flags & update_normal_vectors))
221  {
222  arma::vec::fixed<spacedim> n_cell;
223  n_cell = trans(ijac)*RefElement<dim>::normal_vector(sid);
224  n_cell = n_cell/norm(n_cell,2);
225  for (unsigned int i=0; i<q.size(); i++)
226  fv_data.normal_vectors[i] = n_cell;
227  }
228  }
229  }
230 
231  // Quadrature points in the actual cell coordinate system.
232  // The points location can vary from side to side.
234  {
235  for (unsigned int i=0; i<q.size(); i++)
236  fv_data.points[i] = coords*data.bar_coords[i];
237  }
238 
239  if (fv_data.update_flags & update_side_JxW_values)
240  {
241  double side_det;
242  if (dim <= 1)
243  {
244  side_det = 1;
245  }
246  else
247  {
248  arma::mat::fixed<spacedim,dim> side_coords;
249  arma::mat::fixed<spacedim, MatrixSizes<dim>::dim_minus_one > side_jac; // some compilers complain for case dim==0
250 
251  // calculation of side Jacobian
252  side_coords.zeros();
253  for (unsigned int n=0; n<dim; n++)
254  for (unsigned int c=0; c<spacedim; c++)
255  side_coords(c,n) = cell.side(sid)->node(n)->point()[c];
256  side_jac = side_coords * grad.submat(0,0,dim-1,dim-2);
257 
258  // calculation of JxW
259  side_det = fabs(determinant(side_jac));
260  }
261  for (unsigned int i=0; i<q.size(); i++)
262  fv_data.JxW_values[i] = side_det*q.weight(i);
263  }
264 }
265 
266 
267 template<unsigned int dim, unsigned int spacedim>
269 {
270  ElementMap coords;
271  for (unsigned int i=0; i<dim+1; i++)
272  coords.col(i) = elm.node(i)->point();
273  return coords;
274 }
275 
276 
277 template<unsigned int dim, unsigned int spacedim>
279 {
280  arma::mat::fixed<3, dim> A = map.cols(1,dim);
281  for(unsigned int i=0; i < dim; i++ ) {
282  A.col(i) -= map.col(0);
283  }
284 
285  arma::mat::fixed<dim, dim> AtA = A.t()*A;
286  arma::vec::fixed<dim> Atb = A.t()*(point - map.col(0));
287  arma::vec::fixed<dim+1> bary_coord;
288  bary_coord.rows(1, dim) = arma::solve(AtA, Atb);
289  bary_coord( 0 ) = 1.0 - arma::sum( bary_coord.rows(1,dim) );
290  return bary_coord;
291 }
292 
293 template<unsigned int dim, unsigned int spacedim>
295 {
296  return map * point;
297 }
298 
299 template<unsigned int dim, unsigned int spacedim>
301  return RefElement<dim>::clip(barycentric);
302 }
303 
304 template <unsigned int dim, unsigned int spacedim>
306 {
307  arma::vec projection = this->project_real_to_unit(point, this->element_map(elm));
308  return (projection.min() >= -BoundingBox::epsilon);
309 }
310 
311 
312 
313 template class MappingP1<1,3>;
314 template class MappingP1<2,3>;
315 template class MappingP1<3,3>;
316 
317 
318 
319 
arma::mat::fixed< spacedim, dim+1 > ElementMap
Definition: mapping_p1.hh:71
Class MappingP1 implements the affine transformation of the unit cell onto the actual cell...
UpdateFlags
Enum type UpdateFlags indicates which quantities are to be recomputed on each finite element cell...
Definition: update_flags.hh:67
static LocalPoint normal_vector(unsigned int sid)
Transformed quadrature weight for cell sides.
unsigned int dim() const
Definition: quadrature.hh:71
RealPoint project_unit_to_real(const BaryPoint &point, const ElementMap &map) const
Definition: mapping_p1.cc:294
BaryPoint project_real_to_unit(const RealPoint &point, const ElementMap &map) const
Definition: mapping_p1.cc:278
Determinant of the Jacobian.
std::vector< arma::mat::fixed< dim, spacedim > > inverse_jacobians
Inverse Jacobians at the quadrature points.
Definition: fe_values.hh:122
UpdateFlags update_flags
Flags that indicate which finite element quantities are to be computed.
Definition: fe_values.hh:161
UpdateFlags update_each(UpdateFlags flags)
Determines which additional quantities have to be computed.
Definition: mapping_p1.cc:73
Class FEValues calculates finite element data on the actual cells such as shape function values...
static const double epsilon
stabilization parameter
Definition: bounding_box.hh:66
Mat< double, N, 1 > vec
Definition: armor.hh:211
arma::vec::fixed< spacedim > RealPoint
Definition: mapping_p1.hh:70
SideIter side(const unsigned int loc_index)
std::vector< double > JxW_values
Transformed quadrature weights.
Definition: fe_values.hh:107
double weight(const unsigned int i) const
Returns the ith weight.
Definition: quadrature.hh:101
Base class for quadrature rules on simplices in arbitrary dimensions.
Definition: quadrature.hh:48
Volume element.
double determinant(const T &M)
Calculates determinant of a rectangular matrix.
std::vector< arma::vec::fixed< spacedim > > normal_vectors
Shape functions (for vectorial finite elements) evaluated at quadrature points.
Definition: fe_values.hh:156
Armor::vec< point_dim > point(const unsigned int i) const
Returns the ith quadrature point.
Definition: quadrature.hh:90
Transformed quadrature points.
std::vector< arma::mat::fixed< spacedim, dim > > jacobians
Jacobians of the mapping at the quadrature points.
Definition: fe_values.hh:112
std::vector< arma::vec::fixed< spacedim > > points
Coordinates of quadrature points in the actual cell coordinate system.
Definition: fe_values.hh:127
arma::vec::fixed< dim+1 > BaryPoint
Definition: mapping_p1.hh:69
std::vector< arma::vec > bar_coords
Auxiliary array of barycentric coordinates of quadrature points.
Definition: mapping.hh:106
Basic definitions of numerical quadrature rules.
MappingP1()
Constructor.
Definition: mapping_p1.cc:31
void fill_fe_side_values(const ElementAccessor< 3 > &cell, unsigned int sid, const Quadrature &q, MappingInternalData &data, FEValuesData< dim, spacedim > &fv_data)
Calculates the mapping data on a side of a cell.
Definition: mapping_p1.cc:164
NodeAccessor< 3 > node(unsigned int i) const
Returns node for given local index i on the side.
Normal vectors.
#define ASSERT_LE_DBG(a, b)
Definition of comparative assert macro (Less or Equal) only for debug mode.
Definition: asserts.hh:308
MappingInternalData * initialize(const Quadrature &q, UpdateFlags flags)
Initializes the structures and computes static data.
Definition: mapping_p1.cc:36
Class FEValuesData holds the arrays of data computed by Mapping and FiniteElement.
Definition: fe_values.hh:86
void fill_fe_values(const ElementAccessor< 3 > &cell, const Quadrature &q, MappingInternalData &data, FEValuesData< dim, spacedim > &fv_data)
Calculates the mapping data on the actual cell.
Definition: mapping_p1.cc:90
#define ASSERT_DBG(expr)
std::vector< double > determinants
Determinants of Jacobians at quadrature points.
Definition: fe_values.hh:117
static BaryPoint clip(const BaryPoint &barycentric)
Definition: ref_element.cc:450
BaryPoint clip_to_element(BaryPoint &barycentric)
Definition: mapping_p1.cc:300
bool contains_point(arma::vec point, ElementAccessor< 3 > elm)
Test if element contains given point.
Definition: mapping_p1.cc:305
ElementMap element_map(ElementAccessor< 3 > elm) const
Definition: mapping_p1.cc:268
unsigned int size() const
Returns number of quadrature points.
Definition: quadrature.hh:85
Mapping data that can be precomputed on the actual cell.
Definition: mapping.hh:100
Transformed quadrature weights.