16#ifndef dealii_fe_point_evaluation_h
17#define dealii_fe_point_evaluation_h
48 template <
int dim,
int n_components,
typename Number>
56 const unsigned int component,
60 result[component] = vector_entry;
65 const unsigned int component,
69 vector_entry = result[component];
76 const unsigned int vector_lane,
79 for (
unsigned int i = 0; i < n_components; ++i)
80 for (
unsigned int d = 0; d < dim; ++d)
81 result[i][d] =
value[d][i][vector_lane];
87 const unsigned int vector_lane,
90 for (
unsigned int i = 0; i < n_components; ++i)
91 for (
unsigned int d = 0; d < dim; ++d)
92 value[d][i][vector_lane] = result[i][d];
97 const unsigned int vector_lane,
100 for (
unsigned int i = 0; i < n_components; ++i)
101 result[i] =
value[i][vector_lane];
106 const unsigned int vector_lane,
109 for (
unsigned int i = 0; i < n_components; ++i)
110 value[i][vector_lane] = result[i];
113 template <
typename Number2>
116 const unsigned int component)
118 return value[component];
121 template <
typename Number2>
122 static const Number2 &
124 const unsigned int component)
126 return value[component];
130 template <
int dim,
typename Number>
141 result = vector_entry;
149 vector_entry = result;
154 const unsigned int vector_lane,
157 for (
unsigned int d = 0; d < dim; ++d)
158 result[d] =
value[d][vector_lane];
163 const unsigned int vector_lane,
166 for (
unsigned int d = 0; d < dim; ++d)
167 value[d][vector_lane] = result[d];
172 const unsigned int vector_lane,
175 result =
value[vector_lane];
180 const unsigned int vector_lane,
183 value[vector_lane] = result;
186 template <
typename Number2>
193 template <
typename Number2>
194 static const Number2 &
201 template <
int dim,
typename Number>
209 const unsigned int component,
212 result[component] = vector_entry;
217 const unsigned int component,
220 vector_entry = result[component];
226 const unsigned int vector_lane,
229 for (
unsigned int i = 0; i < dim; ++i)
230 for (
unsigned int d = 0; d < dim; ++d)
231 result[i][d] =
value[d][i][vector_lane];
237 const unsigned int vector_lane,
240 for (
unsigned int i = 0; i < dim; ++i)
241 for (
unsigned int d = 0; d < dim; ++d)
242 value[d][i][vector_lane] = result[i][d];
247 const unsigned int vector_lane,
250 for (
unsigned int i = 0; i < dim; ++i)
251 result[i] =
value[i][vector_lane];
256 const unsigned int vector_lane,
259 for (
unsigned int i = 0; i < dim; ++i)
260 value[i][vector_lane] = result[i];
266 return value[component];
269 static const Number &
272 return value[component];
278 return value[component];
284 return value[component];
288 template <
typename Number>
299 result = vector_entry;
307 vector_entry = result;
312 const unsigned int vector_lane,
315 result[0] =
value[0][vector_lane];
320 const unsigned int vector_lane,
323 value[0][vector_lane] = result[0];
328 const unsigned int vector_lane,
331 result =
value[vector_lane];
336 const unsigned int vector_lane,
339 value[vector_lane] = result;
342 template <
typename Number2>
349 template <
typename Number2>
350 static const Number2 &
357 template <
int dim,
int spacedim>
360 const unsigned int base_element_number);
362 template <
int dim,
int spacedim>
366 template <
int dim,
int spacedim>
367 std::vector<Polynomials::Polynomial<double>>
404template <
int n_components,
407 typename Number =
double>
412 EvaluatorTypeTraits<dim, n_components, Number>::value_type;
414 EvaluatorTypeTraits<dim, n_components, Number>::gradient_type;
437 const unsigned int first_selected_component = 0);
457 const unsigned int first_selected_component = 0);
524 get_value(
const unsigned int point_index)
const;
578 jacobian(
const unsigned int point_index)
const;
594 real_point(
const unsigned int point_index)
const;
601 unit_point(
const unsigned int point_index)
const;
613 setup(
const unsigned int first_selected_component);
629 std::vector<Polynomials::Polynomial<double>>
poly;
708 std::unique_ptr<NonMatching::MappingInfo<dim, spacedim>>
731template <
int n_components,
int dim,
int spacedim,
typename Number>
736 const unsigned int first_selected_component)
739 , update_flags(update_flags)
740 , mapping_info_on_the_fly(
741 std::make_unique<
NonMatching::MappingInfo<dim, spacedim>>(mapping,
743 , mapping_info(mapping_info_on_the_fly.get())
745 setup(first_selected_component);
750template <
int n_components,
int dim,
int spacedim,
typename Number>
754 const unsigned int first_selected_component)
755 : mapping(&mapping_info.get_mapping())
757 , update_flags(mapping_info.get_update_flags())
758 , mapping_info(&mapping_info)
760 setup(first_selected_component);
765template <
int n_components,
int dim,
int spacedim,
typename Number>
768 const unsigned int first_selected_component)
771 fe->n_components() + 1);
773 bool same_base_element =
true;
774 unsigned int base_element_number = 0;
775 component_in_base_element = 0;
776 unsigned int component = 0;
777 for (; base_element_number < fe->n_base_elements(); ++base_element_number)
778 if (component + fe->element_multiplicity(base_element_number) >
779 first_selected_component)
781 if (first_selected_component + n_components >
782 component + fe->element_multiplicity(base_element_number))
783 same_base_element =
false;
784 component_in_base_element = first_selected_component - component;
788 component += fe->element_multiplicity(base_element_number);
792 *fe, base_element_number) &&
801 fe->base_element(base_element_number));
803 polynomials_are_hat_functions =
804 (poly.size() == 2 && poly[0].value(0.) == 1. &&
805 poly[0].value(1.) == 0. && poly[1].value(0.) == 0. &&
806 poly[1].value(1.) == 1.);
812 nonzero_shape_function_component.resize(fe->n_dofs_per_cell());
813 for (
unsigned int d = 0; d < n_components; ++d)
815 const unsigned int component = first_selected_component + d;
816 for (
unsigned int i = 0; i < fe->n_dofs_per_cell(); ++i)
818 const bool is_primitive =
819 fe->is_primitive() || fe->is_primitive(i);
821 nonzero_shape_function_component[i][d] =
822 (component == fe->system_to_component_index(i).first);
824 nonzero_shape_function_component[i][d] =
825 (fe->get_nonzero_components(i)[component] ==
true);
835template <
int n_components,
int dim,
int spacedim,
typename Number>
844 mapping_info->reinit(cell, unit_points);
848 fe_values = std::make_shared<FEValues<dim, spacedim>>(
852 std::vector<
Point<dim>>(unit_points.begin(), unit_points.end())),
854 fe_values->reinit(cell);
858 std::vector<Point<dim>>(unit_points.begin(), unit_points.end());
861 values.resize(unit_points.size(), numbers::signaling_nan<value_type>());
863 gradients.resize(unit_points.size(),
864 numbers::signaling_nan<gradient_type>());
869template <
int n_components,
int dim,
int spacedim,
typename Number>
875 const bool precomputed_mapping = mapping_info_on_the_fly.get() ==
nullptr;
876 if (precomputed_mapping)
878 unit_points = mapping_info->get_unit_points();
881 values.resize(unit_points.size(), numbers::signaling_nan<value_type>());
883 gradients.resize(unit_points.size(),
884 numbers::signaling_nan<gradient_type>());
887 if (unit_points.empty())
896 if (solution_renumbered.size() != dofs_per_component)
897 solution_renumbered.resize(dofs_per_component);
898 for (
unsigned int comp = 0; comp < n_components; ++comp)
899 for (
unsigned int i = 0; i < dofs_per_component; ++i)
901 EvaluatorTypeTraits<dim, n_components, Number>::read_value(
902 solution_values[renumber[(component_in_base_element + comp) *
906 solution_renumbered[i]);
910 unit_gradients.resize(unit_points.size(),
911 numbers::signaling_nan<gradient_type>());
913 const std::size_t n_points = unit_points.size();
915 for (
unsigned int i = 0; i < n_points; i += n_lanes)
919 for (
unsigned int j = 0; j < n_lanes && i + j < n_points; ++j)
920 for (
unsigned int d = 0; d < dim; ++d)
921 vectorized_points[d][j] = unit_points[i + j][d];
924 const auto val_and_grad =
929 polynomials_are_hat_functions);
933 for (
unsigned int j = 0; j < n_lanes && i + j < n_points; ++j)
935 EvaluatorTypeTraits<dim, n_components, Number>::set_value(
936 val_and_grad.first, j, values[i + j]);
942 for (
unsigned int j = 0; j < n_lanes && i + j < n_points; ++j)
947 Number>::set_gradient(val_and_grad.second,
949 unit_gradients[i + j]);
952 EvaluatorTypeTraits<dim,
954 double>::gradient_type>(
956 .inverse_jacobians[i + j]
958 unit_gradients[i + j]));
967 Assert(fe_values.get() !=
nullptr,
969 "Not initialized. Please call FEPointEvaluation::reinit()!"));
973 values.resize(unit_points.size());
974 std::fill(values.begin(), values.end(),
value_type());
975 for (
unsigned int i = 0; i < fe->n_dofs_per_cell(); ++i)
977 const Number value = solution_values[i];
978 for (
unsigned int d = 0; d < n_components; ++d)
979 if (nonzero_shape_function_component[i][d] &&
980 (fe->is_primitive(i) || fe->is_primitive()))
981 for (
unsigned int q = 0; q < unit_points.size(); ++q)
983 EvaluatorTypeTraits<dim, n_components, Number>::access(
984 values[q], d) += fe_values->shape_value(i, q) * value;
985 else if (nonzero_shape_function_component[i][d])
986 for (
unsigned int q = 0; q < unit_points.size(); ++q)
988 EvaluatorTypeTraits<dim, n_components, Number>::access(
990 fe_values->shape_value_component(i, q, d) * value;
996 gradients.resize(unit_points.size());
997 std::fill(gradients.begin(), gradients.end(),
gradient_type());
998 for (
unsigned int i = 0; i < fe->n_dofs_per_cell(); ++i)
1000 const Number value = solution_values[i];
1001 for (
unsigned int d = 0; d < n_components; ++d)
1002 if (nonzero_shape_function_component[i][d] &&
1003 (fe->is_primitive(i) || fe->is_primitive()))
1004 for (
unsigned int q = 0; q < unit_points.size(); ++q)
1006 EvaluatorTypeTraits<dim, n_components, Number>::access(
1007 gradients[q], d) += fe_values->shape_grad(i, q) * value;
1008 else if (nonzero_shape_function_component[i][d])
1009 for (
unsigned int q = 0; q < unit_points.size(); ++q)
1011 EvaluatorTypeTraits<dim, n_components, Number>::access(
1013 fe_values->shape_grad_component(i, q, d) * value;
1021template <
int n_components,
int dim,
int spacedim,
typename Number>
1027 const bool precomputed_mapping = mapping_info_on_the_fly.get() ==
nullptr;
1028 if (precomputed_mapping)
1030 unit_points = mapping_info->get_unit_points();
1033 values.resize(unit_points.size(), numbers::signaling_nan<value_type>());
1035 gradients.resize(unit_points.size(),
1036 numbers::signaling_nan<gradient_type>());
1039 if (unit_points.size() == 0)
1041 std::fill(solution_values.
begin(), solution_values.
end(), 0.0);
1057 if (solution_renumbered_vectorized.size() != dofs_per_component)
1058 solution_renumbered_vectorized.resize(dofs_per_component);
1060 solution_renumbered_vectorized.fill(
1066 const std::size_t n_points = unit_points.size();
1068 for (
unsigned int i = 0; i < n_points; i += n_lanes)
1072 for (
unsigned int j = 0; j < n_lanes && i + j < n_points; ++j)
1073 for (
unsigned int d = 0; d < dim; ++d)
1074 vectorized_points[d][j] = unit_points[i + j][d];
1087 for (
unsigned int j = 0; j < n_lanes && i + j < n_points; ++j)
1089 EvaluatorTypeTraits<dim, n_components, Number>::get_value(
1090 value, j, values[i + j]);
1092 for (
unsigned int j = 0; j < n_lanes && i + j < n_points; ++j)
1095 static_cast<typename internal::FEPointEvaluation::
1096 EvaluatorTypeTraits<dim, n_components, double>::
1098 mapping_info->get_mapping_data().inverse_jacobians[i + j],
1102 gradient, j, gradients[i + j]);
1111 solution_renumbered_vectorized);
1115 std::fill(solution_values.
begin(), solution_values.
end(), Number());
1116 for (
unsigned int comp = 0; comp < n_components; ++comp)
1117 for (
unsigned int i = 0; i < dofs_per_component; ++i)
1120 internal::FEPointEvaluation::
1121 EvaluatorTypeTraits<dim, n_components, VectorizedArray<Number>>::
1122 write_value(result, comp, solution_renumbered_vectorized[i]);
1123 for (
unsigned int lane = n_lanes / 2; lane > 0; lane /= 2)
1124 for (
unsigned int j = 0; j < lane; ++j)
1125 result[j] += result[lane + j];
1126 solution_values[renumber[comp * dofs_per_component + i]] =
1135 Assert(fe_values.get() !=
nullptr,
1137 "Not initialized. Please call FEPointEvaluation::reinit()!"));
1138 std::fill(solution_values.
begin(), solution_values.
end(), 0.0);
1143 for (
unsigned int i = 0; i < fe->n_dofs_per_cell(); ++i)
1145 for (
unsigned int d = 0; d < n_components; ++d)
1146 if (nonzero_shape_function_component[i][d] &&
1147 (fe->is_primitive(i) || fe->is_primitive()))
1148 for (
unsigned int q = 0; q < unit_points.size(); ++q)
1149 solution_values[i] +=
1150 fe_values->shape_value(i, q) *
1154 else if (nonzero_shape_function_component[i][d])
1155 for (
unsigned int q = 0; q < unit_points.size(); ++q)
1156 solution_values[i] +=
1157 fe_values->shape_value_component(i, q, d) *
1167 for (
unsigned int i = 0; i < fe->n_dofs_per_cell(); ++i)
1169 for (
unsigned int d = 0; d < n_components; ++d)
1170 if (nonzero_shape_function_component[i][d] &&
1171 (fe->is_primitive(i) || fe->is_primitive()))
1172 for (
unsigned int q = 0; q < unit_points.size(); ++q)
1173 solution_values[i] +=
1174 fe_values->shape_grad(i, q) *
1178 else if (nonzero_shape_function_component[i][d])
1179 for (
unsigned int q = 0; q < unit_points.size(); ++q)
1180 solution_values[i] +=
1181 fe_values->shape_grad_component(i, q, d) *
1192template <
int n_components,
int dim,
int spacedim,
typename Number>
1196 const unsigned int point_index)
const
1199 return values[point_index];
1204template <
int n_components,
int dim,
int spacedim,
typename Number>
1208 const unsigned int point_index)
const
1211 return gradients[point_index];
1216template <
int n_components,
int dim,
int spacedim,
typename Number>
1220 const unsigned int point_index)
const
1223 ExcMessage(
"Unit gradients are currently only implemented for tensor "
1224 "product finite elements combined with MappingQ "
1227 return unit_gradients[point_index];
1232template <
int n_components,
int dim,
int spacedim,
typename Number>
1236 const unsigned int point_index)
1239 values[point_index] = value;
1244template <
int n_components,
int dim,
int spacedim,
typename Number>
1248 const unsigned int point_index)
1251 gradients[point_index] = gradient;
1256template <
int n_components,
int dim,
int spacedim,
typename Number>
1259 const unsigned int point_index)
const
1262 mapping_info->get_mapping_data().jacobians.size());
1263 return mapping_info->get_mapping_data().jacobians[point_index];
1268template <
int n_components,
int dim,
int spacedim,
typename Number>
1271 const unsigned int point_index)
const
1274 mapping_info->get_mapping_data().inverse_jacobians.size());
1275 return mapping_info->get_mapping_data().inverse_jacobians[point_index];
1280template <
int n_components,
int dim,
int spacedim,
typename Number>
1283 const unsigned int point_index)
const
1286 mapping_info->get_mapping_data().quadrature_points.size());
1287 return mapping_info->get_mapping_data().quadrature_points[point_index];
1292template <
int n_components,
int dim,
int spacedim,
typename Number>
1295 const unsigned int point_index)
const
1298 return unit_points[point_index];
std::vector< Polynomials::Polynomial< double > > poly
std::vector< value_type > solution_renumbered
const UpdateFlags update_flags
void submit_gradient(const gradient_type &, const unsigned int point_index)
bool polynomials_are_hat_functions
std::vector< gradient_type > gradients
void setup(const unsigned int first_selected_component)
const value_type & get_value(const unsigned int point_index) const
std::vector< Point< dim > > unit_points
Point< dim > unit_point(const unsigned int point_index) const
void reinit(const typename Triangulation< dim, spacedim >::cell_iterator &cell, const ArrayView< const Point< dim > > &unit_points)
unsigned int component_in_base_element
SmartPointer< NonMatching::MappingInfo< dim, spacedim > > mapping_info
SmartPointer< const Mapping< dim, spacedim > > mapping
void evaluate(const ArrayView< const Number > &solution_values, const EvaluationFlags::EvaluationFlags &evaluation_flags)
std::vector< std::array< bool, n_components > > nonzero_shape_function_component
const gradient_type & get_unit_gradient(const unsigned int point_index) const
DerivativeForm< 1, spacedim, dim > inverse_jacobian(const unsigned int point_index) const
Point< spacedim > real_point(const unsigned int point_index) const
std::vector< gradient_type > unit_gradients
typename internal::FEPointEvaluation::EvaluatorTypeTraits< dim, n_components, Number >::value_type value_type
const gradient_type & get_gradient(const unsigned int point_index) const
FEPointEvaluation(const Mapping< dim > &mapping, const FiniteElement< dim > &fe, const UpdateFlags update_flags, const unsigned int first_selected_component=0)
std::unique_ptr< NonMatching::MappingInfo< dim, spacedim > > mapping_info_on_the_fly
DerivativeForm< 1, dim, spacedim > jacobian(const unsigned int point_index) const
AlignedVector< typename internal::FEPointEvaluation::EvaluatorTypeTraits< dim, n_components, VectorizedArray< Number > >::value_type > solution_renumbered_vectorized
std::vector< value_type > values
void submit_value(const value_type &value, const unsigned int point_index)
void integrate(const ArrayView< Number > &solution_values, const EvaluationFlags::EvaluationFlags &integration_flags)
typename internal::FEPointEvaluation::EvaluatorTypeTraits< dim, n_components, Number >::gradient_type gradient_type
unsigned int dofs_per_component
std::vector< unsigned int > renumber
std::shared_ptr< FEValues< dim, spacedim > > fe_values
SmartPointer< const FiniteElement< dim > > fe
Abstract base class for mapping classes.
static constexpr std::size_t size()
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
@ update_values
Shape function values.
@ update_inverse_jacobians
Volume element.
@ update_gradients
Shape function gradients.
static ::ExceptionBase & ExcNotImplemented()
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcNotInitialized()
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
EvaluationFlags
The EvaluationFlags enum.
std::vector< Polynomials::Polynomial< double > > get_polynomial_space(const FiniteElement< dim, spacedim > &fe)
bool is_fast_path_supported(const FiniteElement< dim, spacedim > &fe, const unsigned int base_element_number)
void integrate_add_tensor_product_value_and_gradient(const std::vector< Polynomials::Polynomial< double > > &poly, const Number2 &value, const Tensor< 1, dim, Number2 > &gradient, const Point< dim, Number > &p, AlignedVector< Number2 > &values, const std::vector< unsigned int > &renumber={})
std::pair< typename ProductTypeNoPoint< Number, Number2 >::type, Tensor< 1, dim, typename ProductTypeNoPoint< Number, Number2 >::type > > evaluate_tensor_product_value_and_gradient(const std::vector< Polynomials::Polynomial< double > > &poly, const std::vector< Number > &values, const Point< dim, Number2 > &p, const bool d_linear=false, const std::vector< unsigned int > &renumber={})
static void get_gradient(Tensor< 1, 1, VectorizedArray< Number > > &value, const unsigned int vector_lane, const gradient_type &result)
static void get_value(VectorizedArray< Number > &value, const unsigned int vector_lane, const value_type &result)
static Number2 & access(Number2 &value, const unsigned int)
static void set_value(const VectorizedArray< Number > &value, const unsigned int vector_lane, value_type &result)
static void set_gradient(const Tensor< 1, 1, VectorizedArray< Number > > &value, const unsigned int vector_lane, gradient_type &result)
static void write_value(Number &vector_entry, const unsigned int, const value_type &result)
static const Number2 & access(const Number2 &value, const unsigned int)
static void read_value(const Number vector_entry, const unsigned int, value_type &result)
static void get_value(VectorizedArray< Number > &value, const unsigned int vector_lane, const value_type &result)
static void read_value(const Number vector_entry, const unsigned int, value_type &result)
static void get_gradient(Tensor< 1, dim, VectorizedArray< Number > > &value, const unsigned int vector_lane, const gradient_type &result)
static const Number2 & access(const Number2 &value, const unsigned int)
static Number2 & access(Number2 &value, const unsigned int)
static void write_value(Number &vector_entry, const unsigned int, const value_type &result)
static void set_gradient(const Tensor< 1, dim, VectorizedArray< Number > > &value, const unsigned int vector_lane, gradient_type &result)
static void set_value(const VectorizedArray< Number > &value, const unsigned int vector_lane, value_type &result)
static const Number & access(const value_type &value, const unsigned int component)
static void write_value(Number &vector_entry, const unsigned int component, const value_type &result)
static void get_gradient(Tensor< 1, dim, Tensor< 1, dim, VectorizedArray< Number > > > &value, const unsigned int vector_lane, const gradient_type &result)
static Number & access(value_type &value, const unsigned int component)
static void set_gradient(const Tensor< 1, dim, Tensor< 1, dim, VectorizedArray< Number > > > &value, const unsigned int vector_lane, gradient_type &result)
static Tensor< 1, dim, Number > & access(gradient_type &value, const unsigned int component)
static void set_value(const Tensor< 1, dim, VectorizedArray< Number > > &value, const unsigned int vector_lane, value_type &result)
static void get_value(Tensor< 1, dim, VectorizedArray< Number > > &value, const unsigned int vector_lane, const value_type &result)
static const Tensor< 1, dim, Number > & access(const gradient_type &value, const unsigned int component)
static void read_value(const Number vector_entry, const unsigned int component, value_type &result)
static void get_gradient(Tensor< 1, dim, Tensor< 1, n_components, VectorizedArray< Number > > > &value, const unsigned int vector_lane, const gradient_type &result)
static void get_value(Tensor< 1, n_components, VectorizedArray< Number > > &value, const unsigned int vector_lane, const value_type &result)
static void write_value(Number &vector_entry, const unsigned int component, const value_type &result)
static void read_value(const Number vector_entry, const unsigned int component, value_type &result)
static const Number2 & access(const Tensor< 1, n_components, Number2 > &value, const unsigned int component)
static void set_value(const Tensor< 1, n_components, VectorizedArray< Number > > &value, const unsigned int vector_lane, value_type &result)
static void set_gradient(const Tensor< 1, dim, Tensor< 1, n_components, VectorizedArray< Number > > > &value, const unsigned int vector_lane, gradient_type &result)
static Number2 & access(Tensor< 1, n_components, Number2 > &value, const unsigned int component)
unsigned int dofs_per_component_on_cell
void reinit(const Quadrature< dim_q > &quad, const FiniteElement< dim, spacedim > &fe_dim, const unsigned int base_element=0)
std::vector< unsigned int > lexicographic_numbering