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