Flow123d  release_2.2.0-20-gb8056ca
field_fe.impl.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 field_fe.impl.hh
15  * @brief
16  */
17 
18 #ifndef FIELD_FE_IMPL_HH_
19 #define FIELD_FE_IMPL_HH_
20 
21 #include "fields/field_fe.hh"
22 #include "input/input_type.hh"
23 #include "quadrature/quadrature.hh"
24 #include "fem/fe_values.hh"
25 #include "fem/finite_element.hh"
26 
27 
28 
29 
30 /// Implementation.
31 
32 namespace it = Input::Type;
33 
34 
35 
36 
37 template <int spacedim, class Value>
39  Input::register_class< FieldFE<spacedim, Value>, unsigned int >("FieldFE");
40 
41 
42 
43 template <int spacedim, class Value>
44 FieldFE<spacedim, Value>::FieldFE( unsigned int n_comp)
45 : FieldAlgorithmBase<spacedim, Value>(n_comp),
46  dh_(nullptr),
47  data_(nullptr),
48  data_vec_(nullptr),
49  dof_indices(nullptr),
50  map1_(nullptr),
51  map2_(nullptr),
52  map3_(nullptr)
53 {}
54 
55 
56 template <int spacedim, class Value>
58  Mapping<1,3> *map1,
59  Mapping<2,3> *map2,
60  Mapping<3,3> *map3,
61  const Vec *data)
62 {
63  dh_ = dh;
64  map1_ = map1;
65  map2_ = map2;
66  map3_ = map3;
67  data_vec_ = data;
68  VecGetArray(*data_vec_, &data_);
69 
70  unsigned int ndofs = max(dh_->fe<1>()->n_dofs(), max(dh_->fe<2>()->n_dofs(), dh_->fe<3>()->n_dofs()));
71  dof_indices = new unsigned int[ndofs];
72 }
73 
74 
75 
76 /**
77  * Returns one value in one given point. ResultType can be used to avoid some costly calculation if the result is trivial.
78  */
79 template <int spacedim, class Value>
80 typename Value::return_type const & FieldFE<spacedim, Value>::value(const Point &p, const ElementAccessor<spacedim> &elm)
81 {
82  Point p_rel = p - elm.element()->node[0]->point();
84 
85  if (elm.dim() == 1) {
86  arma::mat::fixed<3,1> m1 = elm.element()->node[1]->point() - elm.element()->node[0]->point();
87  arma::mat::fixed<1,3> im1 = pinv(m1);
88 
89  Quadrature<1> q1(1);
90  q1.set_point(0, im1*p_rel);
91 
92  FEValues<1,3> fe_values1(*map1_, q1, *dh_->fe<1>(), update_values);
93  fe_values1.reinit(cell);
94 
96 
97  if (dh_->fe<1>()->is_scalar()) {
98  double value = 0;
99  for (unsigned int i=0; i<dh_->fe<1>()->n_dofs(); i++)
100  value += data_[dof_indices[i]]*fe_values1.shape_value(i, 0);
101  this->value_(0,0) = value;
102  }
103  else {
105  value.zeros();
106  for (unsigned int i=0; i<dh_->fe<1>()->n_dofs(); i++)
107  value += data_[dof_indices[i]]*fe_values1.shape_vector(i, 0);
108  for (unsigned int i=0; i<3; i++)
109  this->value_(i,0) = value(i);
110  }
111  }
112  else if (elm.dim() == 2) {
113  arma::mat::fixed<3,2> m2;
114  m2.col(0) = elm.element()->node[1]->point() - elm.element()->node[0]->point();
115  m2.col(1) = elm.element()->node[2]->point() - elm.element()->node[0]->point();
116  arma::mat::fixed<2,3> im2 = pinv(m2);
117 
118  Quadrature<2> q2(1);
119  q2.set_point(0, im2*p_rel);
120 
121  FEValues<2,3> fe_values2(*map2_, q2, *dh_->fe<2>(), update_values);
122  fe_values2.reinit(cell);
123 
125 
126  if (dh_->fe<2>()->is_scalar()) {
127  double value = 0;
128  for (unsigned int i=0; i<dh_->fe<2>()->n_dofs(); i++)
129  value += data_[dof_indices[i]]*fe_values2.shape_value(i, 0);
130  this->value_(0,0) = value;
131  }
132  else {
134  value.zeros();
135  for (unsigned int i=0; i<dh_->fe<2>()->n_dofs(); i++)
136  value += data_[dof_indices[i]]*fe_values2.shape_vector(i, 0);
137  for (unsigned int i=0; i<3; i++)
138  this->value_(i,0) = value(i);
139  } }
140  else {
141  arma::mat33 m3;
142  m3.col(0) = elm.element()->node[1]->point() - elm.element()->node[0]->point();
143  m3.col(1) = elm.element()->node[2]->point() - elm.element()->node[0]->point();
144  m3.col(2) = elm.element()->node[3]->point() - elm.element()->node[0]->point();
145  arma::mat33 im3 = inv(m3);
146 
147  Quadrature<3> q3(1);
148  q3.set_point(0, im3*p_rel);
149 
150  FEValues<3,3> fe_values3(*map3_, q3, *dh_->fe<3>(), update_values);
151  fe_values3.reinit(cell);
152 
154 
155  if (dh_->fe<3>()->is_scalar()) {
156  double value = 0;
157  for (unsigned int i=0; i<dh_->fe<3>()->n_dofs(); i++)
158  value += data_[dof_indices[i]]*fe_values3.shape_value(i, 0);
159  this->value_(0,0) = value;
160  }
161  else {
163  value.zeros();
164  for (unsigned int i=0; i<dh_->fe<3>()->n_dofs(); i++)
165  value += data_[dof_indices[i]]*fe_values3.shape_vector(i, 0);
166  for (unsigned int i=0; i<3; i++)
167  this->value_(i,0) = value(i);
168  }
169  }
170 
171  return this->r_value_;
172 }
173 
174 
175 
176 /**
177  * Returns std::vector of scalar values in several points at once.
178  */
179 template <int spacedim, class Value>
182 {
183  OLD_ASSERT_EQUAL( point_list.size(), value_list.size() );
184 
185  DOFHandlerBase::CellIterator cell = dh_->mesh()->element( elm.idx() );
186 
187  if (elm.dim() == 1) {
188  arma::mat::fixed<3,1> m1 = elm.element()->node[1]->point() - elm.element()->node[0]->point();
189  arma::mat::fixed<1,3> im1 = pinv(m1);
190 
192 
193  for (unsigned int k=0; k<point_list.size(); k++) {
194  Quadrature<1> q1(1);
195  Point p_rel = point_list[k] - elm.element()->node[0]->point();
196  q1.set_point(0, im1*p_rel);
197 
198  FEValues<1,3> fe_values1(*map1_, q1, *dh_->fe<1>(), update_values);
199  fe_values1.reinit(cell);
200 
201  Value envelope(value_list[k]);
202 
203  if (dh_->fe<1>()->is_scalar()) {
204  double value = 0;
205  for (unsigned int i=0; i<dh_->fe<1>()->n_dofs(); i++)
206  value += data_[dof_indices[i]]*fe_values1.shape_value(i, 0);
207  envelope(0,0) = value;
208  }
209  else {
211  value.zeros();
212  for (unsigned int i=0; i<dh_->fe<1>()->n_dofs(); i++)
213  value += data_[dof_indices[i]]*fe_values1.shape_vector(i, 0);
214  for (int i=0; i<3; i++)
215  envelope(i,0) = value(i);
216  }
217  }
218  }
219  else if (elm.dim() == 2) {
220  arma::mat::fixed<3,2> m2;
221  m2.col(0) = elm.element()->node[1]->point() - elm.element()->node[0]->point();
222  m2.col(1) = elm.element()->node[2]->point() - elm.element()->node[0]->point();
223  arma::mat::fixed<2,3> im2 = pinv(m2);
224 
226 
227  for (unsigned int k=0; k<point_list.size(); k++) {
228  Quadrature<2> q2(1);
229  Point p_rel = point_list[k] - elm.element()->node[0]->point();
230  q2.set_point(0, im2*p_rel);
231 
232  FEValues<2,3> fe_values2(*map2_, q2, *dh_->fe<2>(), update_values);
233  fe_values2.reinit(cell);
234 
235  Value envelope(value_list[k]);
236 
237  if (dh_->fe<2>()->is_scalar()) {
238  double value = 0;
239  for (unsigned int i=0; i<dh_->fe<2>()->n_dofs(); i++)
240  value += data_[dof_indices[i]]*fe_values2.shape_value(i, 0);
241  envelope(0,0) = value;
242  }
243  else {
245  value.zeros();
246  for (unsigned int i=0; i<dh_->fe<2>()->n_dofs(); i++)
247  value += data_[dof_indices[i]]*fe_values2.shape_vector(i, 0);
248  for (int i=0; i<3; i++)
249  envelope(i,0) = value(i);
250  }
251  }
252  }
253  else {
254  arma::mat33 m3;
255  m3.col(0) = elm.element()->node[1]->point() - elm.element()->node[0]->point();
256  m3.col(1) = elm.element()->node[2]->point() - elm.element()->node[0]->point();
257  m3.col(2) = elm.element()->node[3]->point() - elm.element()->node[0]->point();
258  arma::mat33 im3 = inv(m3);
259 
261 
262  for (unsigned int k=0; k<point_list.size(); k++) {
263  Quadrature<3> q3(1);
264  Point p_rel = point_list[k] - elm.element()->node[0]->point();
265  q3.set_point(0, im3*p_rel);
266 
267  FEValues<3,3> fe_values3(*map3_, q3, *dh_->fe<3>(), update_values);
268  fe_values3.reinit(cell);
269 
270  Value envelope(value_list[k]);
271 
272  if (dh_->fe<3>()->is_scalar()) {
273  double value = 0;
274  for (unsigned int i=0; i<dh_->fe<3>()->n_dofs(); i++)
275  value += data_[dof_indices[i]]*fe_values3.shape_value(i, 0);
276  envelope(0,0) = value;
277  }
278  else {
280  value.zeros();
281  for (unsigned int i=0; i<dh_->fe<3>()->n_dofs(); i++)
282  value += data_[dof_indices[i]]*fe_values3.shape_vector(i, 0);
283  for (int i=0; i<3; i++)
284  envelope(i,0) = value(i);
285  }
286  }
287  }
288 }
289 
290 
291 
292 template <int spacedim, class Value>
294 {
295  if (dof_indices != nullptr) delete[] dof_indices;
296 }
297 
298 
299 
300 #endif /* FIELD_FE_IMPL_HH_ */
Shape function values.
Definition: update_flags.hh:87
virtual ~FieldFE()
Mapping< 2, 3 > * map2_
Definition: field_fe.hh:83
const Element * element() const
Definition: accessors.hh:86
virtual void value_list(const std::vector< Point > &point_list, const ElementAccessor< spacedim > &elm, std::vector< typename Value::return_type > &value_list)
double * data_
Definition: field_fe.hh:78
Class FEValues calculates finite element data on the actual cells such as shape function values...
Node ** node
Definition: elements.h:79
Mesh * mesh() const
Definition: dofhandler.hh:81
Value::return_type r_value_
Mapping< 1, 3 > * map1_
Definition: field_fe.hh:82
FiniteElement< dim, 3 > * fe() const
Returns finite element object for given space dimension.
unsigned int * dof_indices
Definition: field_fe.hh:80
Mapping< 3, 3 > * map3_
Definition: field_fe.hh:84
void set_fe_data(const DOFHandlerMultiDim *dh, Mapping< 1, 3 > *map1, Mapping< 2, 3 > *map2, Mapping< 3, 3 > *map3, const Vec *data)
const Vec * data_vec_
Definition: field_fe.hh:79
Provides the numbering of the finite element degrees of freedom on the computational mesh...
Definition: dofhandler.hh:248
virtual Value::return_type const & value(const Point &p, const ElementAccessor< spacedim > &elm)
void get_loc_dof_indices(const CellIterator &cell, unsigned int indices[]) const override
Returns the indices of dofs associated to the cell on the local process.
Definition: dofhandler.cc:356
Basic definitions of numerical quadrature rules.
Space< spacedim >::Point Point
arma::vec::fixed< spacedim > shape_vector(const unsigned int function_no, const unsigned int point_no)
Return the value of the function_no-th shape function at the point_no-th quadrature point...
Definition: fe_values.hh:254
double shape_value(const unsigned int function_no, const unsigned int point_no)
Return the value of the function_no-th shape function at the point_no-th quadrature point...
Definition: fe_values.hh:226
Value value_
Last value, prevents passing large values (vectors) by value.
void set_point(const unsigned int i, const arma::vec::fixed< dim > &p)
Sets individual quadrature point coordinates.
Definition: quadrature.hh:141
FieldFE(unsigned int n_comp=0)
void reinit(ElementFullIter &cell)
Update cell-dependent data (gradients, Jacobians etc.)
Definition: fe_values.cc:157
Calculates finite element data on the actual cell.
Definition: fe_values.hh:416
const DOFHandlerMultiDim * dh_
Definition: field_fe.hh:77
#define OLD_ASSERT_EQUAL(a, b)
Definition: global_defs.h:133
Abstract class for description of finite elements.
unsigned int dim() const
Definition: accessors.hh:83
arma::vec3 & point()
Definition: nodes.hh:68
unsigned int idx() const
Definition: accessors.hh:113
ElementVector element
Vector of elements of the mesh.
Definition: mesh.h:228