Flow123d  release_3.0.0-1264-g45bfb2a
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, FMT_UNUSED 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 quad(elemdim, 1);
137  quad.point<elemdim>(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 qgauss(elemdim, 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<elemdim>(i).arma()), 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  if (map_ != nullptr) delete map_;
229 }
230 
231 
232 // Instantiations of FEValueHandler and FEShapeHandler
233 #define INSTANCE_VALUE_HANDLER_ALL(dim, spacedim) \
234 template class FEValueHandler<dim, spacedim, FieldValue<0>::Enum >; \
235 template class FEValueHandler<dim, spacedim, FieldValue<0>::Integer >; \
236 template class FEValueHandler<dim, spacedim, FieldValue<0>::Scalar >; \
237 template class FEValueHandler<dim, spacedim, FieldValue<spacedim>::VectorFixed >; \
238 template class FEValueHandler<dim, spacedim, FieldValue<spacedim>::TensorFixed >; \
239 template class FEShapeHandler<0, dim, spacedim, FieldValue<0>::Enum >; \
240 template class FEShapeHandler<0, dim, spacedim, FieldValue<0>::Integer >; \
241 template class FEShapeHandler<0, dim, spacedim, FieldValue<0>::Scalar >; \
242 template class FEShapeHandler<1, dim, spacedim, FieldValue<spacedim>::VectorFixed >; \
243 template class FEShapeHandler<2, dim, spacedim, FieldValue<spacedim>::TensorFixed >;
244 
245 #define INSTANCE_VALUE_HANDLER(dim) \
246 INSTANCE_VALUE_HANDLER_ALL(dim,3)
247 //INSTANCE_VALUE_HANDLER_ALL(dim,2)
248 
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)
Mat< double, N, M > mat
Definition: armor.hh:214
RealPoint project_unit_to_real(const BaryPoint &point, const ElementMap &map) const
Definition: mapping_p1.cc:294
void initialize(FEValueInitData init_data)
Initialize data members.
BaryPoint project_real_to_unit(const RealPoint &point, const ElementMap &map) const
Definition: mapping_p1.cc:278
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.
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:347
Value::return_type const & value(const Point &p, const ElementAccessor< spacedim > &elm)
Returns one value in one given point.
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
Symmetric Gauss-Legendre quadrature formulae on simplices.
MappingP1< elemdim, 3 > * map_
Mapping object.
Armor::vec< point_dim > point(const unsigned int i) const
Returns the ith quadrature point.
Definition: quadrature.hh:90
static Value::return_type fe_value(FEValues< elemdim, 3 > &fe_val, unsigned int i_dof, unsigned int i_qp, unsigned int comp_index)
#define FMT_UNUSED
Definition: posix.h:75
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_
static Value::return_type fe_value(FEValues< elemdim, 3 > &fe_val, unsigned int i_dof, unsigned int i_qp, FMT_UNUSED unsigned int comp_index)
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.
MappingP1< elemdim, 3 > * get_mapping()
Return mapping object.
Value value_
Last value, prevents passing large values (vectors) by value.
#define INSTANCE_VALUE_HANDLER(dim)
#define ASSERT_PTR(ptr)
Definition of assert macro checking non-null pointer (PTR)
Definition: asserts.hh:336
std::shared_ptr< std::vector< LongIdx > > boundary_dofs_
double shape_value(const unsigned int function_no, const unsigned int point_no) override
Return the value of the function_no-th shape function at the point_no-th quadrature point...
Definition: fe_values.cc:229
VectorMPI data_vec_
Store data of Field.
~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)
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:525
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:268
unsigned int n_comp
number of components
unsigned int size() const
Returns number of quadrature points.
Definition: quadrature.hh:85
Initialization structure of FEValueHandler class.
unsigned int idx() const
Return local idx of element in boundary / bulk part of element vector.
Definition: accessors.hh:180
#define ASSERT_EQ(a, b)
Definition of comparative assert macro (EQual)
Definition: asserts.hh:328