Flow123d  release_3.0.0-965-gb0c8897
fe_value_handler.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 fe_value_handler.cc
15  * @brief
16  */
17 
19 #include "la/vector_mpi.hh"
20 #include "fem/mapping_p1.hh"
21 #include "fem/fe_values.hh"
22 #include "quadrature/quadrature.hh"
24 #include "mesh/bounding_box.hh"
25 #include "mesh/accessors.hh"
26 #include "fem/fe_values_views.hh"
27 #include "fem/dh_cell_accessor.hh"
28 
29 
30 /**
31  * Helper class, allow to simplify computing value of FieldFE.
32  *
33  * Use correct method FEValues<...>::shape_xxx given with Value::rank_.
34  * Is done by class partial specialization as, we were not able to do this using function overloading (since
35  * they differ only by return value) and partial specialization of the function templates is not supported in C++.
36  */
37 template<int rank, int elemdim, int spacedim, class Value>
39 public:
40 
41  inline static typename Value::return_type fe_value(FEValues<elemdim,3> &fe_val, unsigned int i_dof, unsigned int i_qp, unsigned int comp_index)
42  {
43  ASSERT(false).error("Unsupported format of FieldFE!\n");
44  typename Value::return_type ret;
45  Value val(ret);
46  val.zeros();
47  return ret;
48  }
49 };
50 
51 
52 /// Partial template specialization of FEShapeHandler for scalar fields
53 template<int elemdim, int spacedim, class Value>
54 class FEShapeHandler<0, elemdim, spacedim, Value> {
55 public:
56  inline static typename Value::return_type fe_value(FEValues<elemdim,3> &fe_val, unsigned int i_dof, unsigned int i_qp, unsigned int comp_index)
57  {
58  return fe_val.shape_value(i_dof, i_qp);
59  }
60 };
61 
62 
63 /// Partial template specialization of FEShapeHandler for vector fields
64 template<int elemdim, int spacedim, class Value>
65 class FEShapeHandler<1, elemdim, spacedim, Value> {
66 public:
67  inline static typename Value::return_type fe_value(FEValues<elemdim,3> &fe_val, unsigned int i_dof, unsigned int i_qp, unsigned int comp_index)
68  {
69  return fe_val.vector_view(comp_index).value(i_dof, i_qp);
70  }
71 };
72 
73 
74 /// Partial template specialization of FEShapeHandler for tensor fields
75 template<int elemdim, int spacedim, class Value>
76 class FEShapeHandler<2, elemdim, spacedim, Value> {
77 public:
78  inline static typename Value::return_type fe_value(FEValues<elemdim,3> &fe_val, unsigned int i_dof, unsigned int i_qp, unsigned int comp_index)
79  {
80  return fe_val.tensor_view(comp_index).value(i_dof, i_qp);
81  }
82 };
83 
84 
85 
86 template <int elemdim, int spacedim, class Value>
88 : value_(r_value_),
89  map_(nullptr)
90 {}
91 
92 
93 template <int elemdim, int spacedim, class Value>
95 {
96  if (dof_indices.size() > 0)
97  WarningOut() << "Multiple initialization of FEValueHandler!";
98 
99  dh_ = init_data.dh;
100  data_vec_ = init_data.data_vec;
101  dof_indices.resize(init_data.ndofs);
102  value_.set_n_comp(init_data.n_comp);
103  comp_index_ = init_data.comp_index;
104 
105  // temporary solution - these objects will be set through FieldCommon
106  map_ = new MappingP1<elemdim,3>();
107 }
108 
109 
110 template <int elemdim, int spacedim, class Value> inline
111 typename Value::return_type const &FEValueHandler<elemdim, spacedim, Value>::value(const Point &p, const ElementAccessor<spacedim> &elm)
112 {
113  std::vector<Point> point_list;
114  point_list.push_back(p);
116  v_list.push_back(r_value_);
117  this->value_list(point_list, elm, v_list);
118  this->r_value_ = v_list[0];
119  return this->r_value_;
120 }
121 
122 
123 template <int elemdim, int spacedim, class Value>
126 {
127  ASSERT_PTR(map_).error();
128  ASSERT_EQ( point_list.size(), value_list.size() ).error();
129 
130  const DHCellAccessor cell = dh_->cell_accessor_from_element( elm.idx() );
131  if (boundary_dofs_) this->get_dof_indices( elm, dof_indices);
132  else cell.get_loc_dof_indices( dof_indices );
133 
134  arma::mat map_mat = map_->element_map(elm);
135  for (unsigned int k=0; k<point_list.size(); k++) {
136  Quadrature<elemdim> quad(1);
137  quad.set_point(0, RefElement<elemdim>::bary_to_local(map_->project_real_to_unit(point_list[k], map_mat)));
138 
139  FEValues<elemdim,3> fe_values(*this->get_mapping(), quad, *dh_->ds()->fe<elemdim>(elm), update_values);
140  fe_values.reinit( const_cast<ElementAccessor<spacedim> &>(elm) );
141 
142  Value envelope(value_list[k]);
143  envelope.zeros();
144  for (unsigned int i=0; i<dh_->ds()->fe<elemdim>(elm)->n_dofs(); i++) {
145  value_list[k] += data_vec_[dof_indices[i]]
147  }
148  }
149 }
150 
151 
152 template <int elemdim, int spacedim, class Value>
153 unsigned int FEValueHandler<elemdim, spacedim, Value>::compute_quadrature(std::vector<arma::vec::fixed<3>> & q_points, std::vector<double> & q_weights,
154  const ElementAccessor<spacedim> &ele, unsigned int order)
155 {
156  static const double weight_coefs[] = { 1., 1., 2., 6. };
157 
158  QGauss<elemdim> qgauss(order);
159  arma::mat map_mat = map_->element_map(ele);
160 
161  for(unsigned i=0; i<qgauss.size(); ++i) {
162  q_weights[i] = qgauss.weight(i)*weight_coefs[elemdim];
163  q_points[i] = map_->project_unit_to_real(RefElement<elemdim>::local_to_bary(qgauss.point(i)), map_mat);
164  }
165 
166  return qgauss.size();
167 }
168 
169 
170 template <int elemdim, int spacedim, class Value>
172 {
173  unsigned int ndofs = this->value_.n_rows() * this->value_.n_cols();
174  for (unsigned int k=0; k<ndofs; k++) {
175  indices[k] = (*boundary_dofs_)[ndofs*cell.idx()+k];
176  }
177  return ndofs;
178 }
179 
180 
181 template <int spacedim, class Value>
183 {
184  if (dof_indices.size() > 0)
185  WarningOut() << "Multiple initialization of FEValueHandler!";
186 
187  dh_ = init_data.dh;
188  data_vec_ = init_data.data_vec;
189  dof_indices.resize(init_data.ndofs);
190  value_.set_n_comp(init_data.n_comp);
191 }
192 
193 
194 template <int spacedim, class Value>
197 {
198  ASSERT_EQ( point_list.size(), value_list.size() ).error();
199 
200  const DHCellAccessor cell = dh_->cell_accessor_from_element( elm.idx() );
201  if (boundary_dofs_) this->get_dof_indices( elm, dof_indices);
202  else cell.get_loc_dof_indices( dof_indices );
203 
204  for (unsigned int k=0; k<point_list.size(); k++) {
205  Value envelope(value_list[k]);
206  envelope.zeros();
207  for (unsigned int i=0; i<dh_->ds()->fe<0>(elm)->n_dofs(); i++) {
208  envelope(i / envelope.n_cols(), i % envelope.n_rows()) += data_vec_[dof_indices[i]];
209  }
210  }
211 }
212 
213 
214 template <int spacedim, class Value>
216 {
217  unsigned int ndofs = this->value_.n_rows() * this->value_.n_cols();
218  for (unsigned int k=0; k<ndofs; k++) {
219  indices[k] = (*boundary_dofs_)[ndofs*cell.idx()+k];
220  }
221  return ndofs;
222 }
223 
224 
225 template <int elemdim, int spacedim, class Value>
227 {}
228 
229 
230 // Instantiations of FEValueHandler and FEShapeHandler
231 #define INSTANCE_VALUE_HANDLER_ALL(dim, spacedim) \
232 template class FEValueHandler<dim, spacedim, FieldValue<0>::Enum >; \
233 template class FEValueHandler<dim, spacedim, FieldValue<0>::Integer >; \
234 template class FEValueHandler<dim, spacedim, FieldValue<0>::Scalar >; \
235 template class FEValueHandler<dim, spacedim, FieldValue<spacedim>::VectorFixed >; \
236 template class FEValueHandler<dim, spacedim, FieldValue<spacedim>::TensorFixed >; \
237 template class FEShapeHandler<0, dim, spacedim, FieldValue<0>::Enum >; \
238 template class FEShapeHandler<0, dim, spacedim, FieldValue<0>::Integer >; \
239 template class FEShapeHandler<0, dim, spacedim, FieldValue<0>::Scalar >; \
240 template class FEShapeHandler<1, dim, spacedim, FieldValue<spacedim>::VectorFixed >; \
241 template class FEShapeHandler<2, dim, spacedim, FieldValue<spacedim>::TensorFixed >;
242 
243 #define INSTANCE_VALUE_HANDLER(dim) \
244 INSTANCE_VALUE_HANDLER_ALL(dim,3)
245 //INSTANCE_VALUE_HANDLER_ALL(dim,2) \
246 
unsigned int comp_index
index of component (of vector_value/tensor_value)
Class MappingP1 implements the affine transformation of the unit cell onto the actual cell...
Shape function values.
Definition: update_flags.hh:87
unsigned int comp_index_
Index of component (of vector_value/tensor_value)
RealPoint project_unit_to_real(const BaryPoint &point, const ElementMap &map) const
Definition: mapping_p1.cc:291
void initialize(FEValueInitData init_data)
Initialize data members.
BaryPoint project_real_to_unit(const RealPoint &point, const ElementMap &map) const
Definition: mapping_p1.cc:275
Space< spacedim >::Point Point
unsigned int get_loc_dof_indices(std::vector< LongIdx > &indices) const
Returns the indices of dofs associated to the cell on the local process.
static Value::return_type fe_value(FEValues< elemdim, 3 > &fe_val, unsigned int i_dof, unsigned int i_qp, unsigned int comp_index)
Cell accessor allow iterate over DOF handler cells.
Class FEValues calculates finite element data on the actual cells such as shape function values...
const FEValuesViews::Tensor< dim, spacedim > & tensor_view(unsigned int i) const
Accessor to tensor values of multicomponent FE.
Definition: fe_values.hh:398
#define ASSERT(expr)
Allow use shorter versions of macro names if these names is not used with external library...
Definition: asserts.hh:346
Value::return_type const & value(const Point &p, const ElementAccessor< spacedim > &elm)
Returns one value in one given point.
Base class for quadrature rules on simplices in arbitrary dimensions.
Definition: fe_values.hh:35
Symmetric Gauss-Legendre quadrature formulae on simplices.
MappingP1< elemdim, 3 > * map_
Mapping object.
static Value::return_type fe_value(FEValues< elemdim, 3 > &fe_val, unsigned int i_dof, unsigned int i_qp, unsigned int comp_index)
double weight(const unsigned int i) const
Returns the ith weight.
Definition: quadrature.hh:161
void value_list(const std::vector< Point > &point_list, const ElementAccessor< spacedim > &elm, std::vector< typename Value::return_type > &value_list)
Returns std::vector of scalar values in several points at once.
Value::return_type r_value_
Basic definitions of numerical quadrature rules.
std::vector< LongIdx > dof_indices
Array of indexes to data_vec_, used for get/set values.
std::shared_ptr< DOFHandlerMultiDim > dh_
DOF handler object.
unsigned int ndofs
number of dofs
unsigned int compute_quadrature(std::vector< arma::vec::fixed< 3 >> &q_points, std::vector< double > &q_weights, const ElementAccessor< spacedim > &elm, unsigned int order=3)
Compute real coordinates and weights (use QGauss) for given element.
const FEValuesViews::Vector< dim, spacedim > & vector_view(unsigned int i) const
Accessor to vector values of multicomponent FE.
Definition: fe_values.hh:388
std::shared_ptr< DOFHandlerMultiDim > dh
DOF handler object.
unsigned int get_dof_indices(const ElementAccessor< 3 > &cell, std::vector< LongIdx > &indices) const
TODO: Temporary solution. Fix problem with merge new DOF handler and boundary Mesh. Will be removed in future.
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.cc:224
MappingP1< elemdim, 3 > * get_mapping()
Return mapping object.
Value value_
Last value, prevents passing large values (vectors) by value.
#define INSTANCE_VALUE_HANDLER(dim)
void set_point(const unsigned int i, const arma::vec::fixed< dim > &p)
Sets individual quadrature point coordinates.
Definition: quadrature.hh:155
#define ASSERT_PTR(ptr)
Definition of assert macro checking non-null pointer (PTR)
Definition: asserts.hh:335
std::shared_ptr< std::vector< LongIdx > > boundary_dofs_
VectorMPI data_vec_
Store data of Field.
const unsigned int size() const
Returns number of quadrature points.
Definition: quadrature.hh:139
~FEValueHandler()
Destructor.
static Value::return_type fe_value(FEValues< elemdim, 3 > &fe_val, unsigned int i_dof, unsigned int i_qp, unsigned int comp_index)
const arma::vec::fixed< dim > & point(const unsigned int i) const
Returns the ith quadrature point.
Definition: quadrature.hh:144
Definitions of particular quadrature rules on simplices.
#define WarningOut()
Macro defining &#39;warning&#39; record of log.
Definition: logger.hh:246
Calculates finite element data on the actual cell.
Definition: fe_values.hh:532
static Value::return_type fe_value(FEValues< elemdim, 3 > &fe_val, unsigned int i_dof, unsigned int i_qp, unsigned int comp_index)
VectorMPI data_vec
Store data of Field.
FEValueHandler()
Constructor.
ElementMap element_map(ElementAccessor< 3 > elm) const
Definition: mapping_p1.cc:265
unsigned int n_comp
number of components
Initialization structure of FEValueHandler class.
unsigned int idx() const
Return local idx of element in boundary / bulk part of element vector.
Definition: accessors.hh:111
#define ASSERT_EQ(a, b)
Definition of comparative assert macro (EQual)
Definition: asserts.hh:327
void reinit(ElementAccessor< 3 > &cell)
Update cell-dependent data (gradients, Jacobians etc.)
Definition: fe_values.cc:528