16#ifndef dealii_fe_point_evaluation_h
17#define dealii_fe_point_evaluation_h
45 template <
int dim,
int n_components,
typename Number>
53 const unsigned int component,
57 result[component] = vector_entry;
62 const unsigned int component,
66 vector_entry = result[component];
73 const unsigned int vector_lane,
76 for (
unsigned int i = 0; i < n_components; ++i)
77 for (
unsigned int d = 0;
d < dim; ++
d)
78 result[i][
d] =
value[
d][i][vector_lane];
83 const unsigned int vector_lane,
86 for (
unsigned int i = 0; i < n_components; ++i)
87 for (
unsigned int d = 0;
d < dim; ++
d)
88 value[
d][i][vector_lane] = result[i][
d];
93 const unsigned int vector_lane,
96 for (
unsigned int i = 0; i < n_components; ++i)
97 result[i] =
value[i][vector_lane];
102 const unsigned int vector_lane,
105 for (
unsigned int i = 0; i < n_components; ++i)
106 value[i][vector_lane] = result[i];
109 template <
typename Number2>
111 const unsigned int component)
113 return value[component];
116 template <
typename Number2>
117 static const Number2 &
119 const unsigned int component)
121 return value[component];
125 template <
int dim,
typename Number>
136 result = vector_entry;
144 vector_entry = result;
149 const unsigned int vector_lane,
152 for (
unsigned int d = 0;
d < dim; ++
d)
153 result[
d] =
value[
d][vector_lane];
157 const unsigned int vector_lane,
160 for (
unsigned int d = 0;
d < dim; ++
d)
161 value[
d][vector_lane] = result[
d];
166 const unsigned int vector_lane,
169 result =
value[vector_lane];
174 const unsigned int vector_lane,
177 value[vector_lane] = result;
180 template <
typename Number2>
182 access(Number2 &value,
const unsigned int)
187 template <
typename Number2>
188 static const Number2 &
189 access(
const Number2 &value,
const unsigned int)
195 template <
int dim,
typename Number>
203 const unsigned int component,
206 result[component] = vector_entry;
211 const unsigned int component,
214 vector_entry = result[component];
220 const unsigned int vector_lane,
223 for (
unsigned int i = 0; i < dim; ++i)
224 for (
unsigned int d = 0;
d < dim; ++
d)
225 result[i][
d] =
value[
d][i][vector_lane];
230 const unsigned int vector_lane,
233 for (
unsigned int i = 0; i < dim; ++i)
234 for (
unsigned int d = 0;
d < dim; ++
d)
235 value[
d][i][vector_lane] = result[i][
d];
240 const unsigned int vector_lane,
243 for (
unsigned int i = 0; i < dim; ++i)
244 result[i] =
value[i][vector_lane];
248 const unsigned int vector_lane,
251 for (
unsigned int i = 0; i < dim; ++i)
252 value[i][vector_lane] = result[i];
258 return value[component];
261 static const Number &
264 return value[component];
270 return value[component];
276 return value[component];
280 template <
typename Number>
291 result = vector_entry;
299 vector_entry = result;
304 const unsigned int vector_lane,
307 result[0] =
value[0][vector_lane];
311 const unsigned int vector_lane,
314 value[0][vector_lane] = result[0];
319 const unsigned int vector_lane,
322 result =
value[vector_lane];
327 const unsigned int vector_lane,
330 value[vector_lane] = result;
333 template <
typename Number2>
335 access(Number2 &value,
const unsigned int)
340 template <
typename Number2>
341 static const Number2 &
342 access(
const Number2 &value,
const unsigned int)
348 template <
int dim,
int spacedim>
351 const unsigned int base_element_number);
353 template <
int dim,
int spacedim>
354 std::vector<Polynomials::Polynomial<double>>
389template <
int n_components,
392 typename Number =
double>
422 const unsigned int first_selected_component = 0);
489 get_value(
const unsigned int point_index)
const;
543 jacobian(
const unsigned int point_index)
const;
559 real_point(
const unsigned int point_index)
const;
566 unit_point(
const unsigned int point_index)
const;
589 std::vector<Polynomials::Polynomial<double>>
poly;
681template <
int n_components,
int dim,
int spacedim,
typename Number>
686 const unsigned int first_selected_component)
691 , update_flags(update_flags)
694 bool same_base_element =
true;
695 unsigned int base_element_number = 0;
696 unsigned int component = 0;
697 for (; base_element_number <
fe.n_base_elements(); ++base_element_number)
698 if (component +
fe.element_multiplicity(base_element_number) >
699 first_selected_component)
701 if (first_selected_component + n_components >
702 component +
fe.element_multiplicity(base_element_number))
703 same_base_element =
false;
707 component +=
fe.element_multiplicity(base_element_number);
710 fe, base_element_number) &&
719 fe.base_element(base_element_number));
722 (
poly.size() == 2 &&
poly[0].value(0.) == 1. &&
723 poly[0].value(1.) == 0. &&
poly[1].value(0.) == 0. &&
724 poly[1].value(1.) == 1.);
729 for (
unsigned int d = 0;
d < n_components; ++
d)
731 const unsigned int component = first_selected_component +
d;
732 for (
unsigned int i = 0; i <
fe.n_dofs_per_cell(); ++i)
734 const bool is_primitive =
fe.is_primitive() ||
fe.is_primitive(i);
737 (component ==
fe.system_to_component_index(i).first);
740 (
fe.get_nonzero_components(i)[component] ==
true);
757template <
int n_components,
int dim,
int spacedim,
typename Number>
763 this->unit_points.resize(unit_points.size());
764 std::copy(unit_points.begin(), unit_points.end(), this->unit_points.begin());
767 mapping_q_generic->fill_mapping_data_for_generic_points(
768 cell, unit_points, update_flags_mapping, mapping_data);
771 fe_values = std::make_shared<FEValues<dim, spacedim>>(
775 std::vector<
Point<dim>>(unit_points.begin(), unit_points.end())),
776 update_flags | update_flags_mapping);
777 fe_values->reinit(cell);
778 mapping_data.initialize(unit_points.size(), update_flags_mapping);
780 for (
unsigned int q = 0; q < unit_points.size(); ++q)
781 mapping_data.jacobians[q] = fe_values->jacobian(q);
783 for (
unsigned int q = 0; q < unit_points.size(); ++q)
784 mapping_data.inverse_jacobians[q] = fe_values->inverse_jacobian(q);
786 for (
unsigned int q = 0; q < unit_points.size(); ++q)
787 mapping_data.quadrature_points[q] = fe_values->quadrature_point(q);
791 values.resize(unit_points.size(), numbers::signaling_nan<value_type>());
794 numbers::signaling_nan<gradient_type>());
799template <
int n_components,
int dim,
int spacedim,
typename Number>
805 if (unit_points.empty())
814 if (solution_renumbered.size() != dofs_per_component)
815 solution_renumbered.resize(dofs_per_component);
816 for (
unsigned int comp = 0; comp < n_components; ++comp)
817 for (
unsigned int i = 0; i < dofs_per_component; ++i)
819 EvaluatorTypeTraits<dim, n_components, Number>::read_value(
820 solution_values[renumber[comp * dofs_per_component + i]],
822 solution_renumbered[i]);
826 unit_gradients.resize(unit_points.size(),
827 numbers::signaling_nan<gradient_type>());
829 const std::size_t n_points = unit_points.size();
831 for (
unsigned int i = 0; i < n_points; i += n_lanes)
835 for (
unsigned int j = 0; j < n_lanes && i + j < n_points; ++j)
836 for (
unsigned int d = 0;
d < dim; ++
d)
837 vectorized_points[
d][j] = unit_points[i + j][
d];
840 const auto val_and_grad =
845 polynomials_are_hat_functions);
849 for (
unsigned int j = 0; j < n_lanes && i + j < n_points; ++j)
851 EvaluatorTypeTraits<dim, n_components, Number>::set_value(
852 val_and_grad.first, j,
values[i + j]);
858 for (
unsigned int j = 0; j < n_lanes && i + j < n_points; ++j)
865 Number>::set_gradient(val_and_grad.second,
867 unit_gradients[i + j]);
869 mapping_data.inverse_jacobians[i + j].transpose(),
870 unit_gradients[i + j]);
879 Assert(fe_values.get() !=
nullptr,
881 "Not initialized. Please call FEPointEvaluation::reinit()!"));
885 values.resize(unit_points.size());
887 for (
unsigned int i = 0; i < fe->n_dofs_per_cell(); ++i)
889 const Number value = solution_values[i];
890 for (
unsigned int d = 0;
d < n_components; ++
d)
891 if (nonzero_shape_function_component[i][
d] &&
892 (fe->is_primitive(i) || fe->is_primitive()))
893 for (
unsigned int q = 0; q < unit_points.size(); ++q)
895 EvaluatorTypeTraits<dim, n_components, Number>::access(
896 values[q],
d) += fe_values->shape_value(i, q) * value;
897 else if (nonzero_shape_function_component[i][
d])
898 for (
unsigned int q = 0; q < unit_points.size(); ++q)
900 EvaluatorTypeTraits<dim, n_components, Number>::access(
902 fe_values->shape_value_component(i, q,
d) * value;
910 for (
unsigned int i = 0; i < fe->n_dofs_per_cell(); ++i)
912 const Number value = solution_values[i];
913 for (
unsigned int d = 0;
d < n_components; ++
d)
914 if (nonzero_shape_function_component[i][
d] &&
915 (fe->is_primitive(i) || fe->is_primitive()))
916 for (
unsigned int q = 0; q < unit_points.size(); ++q)
918 EvaluatorTypeTraits<dim, n_components, Number>::access(
919 gradients[q],
d) += fe_values->shape_grad(i, q) * value;
920 else if (nonzero_shape_function_component[i][
d])
921 for (
unsigned int q = 0; q < unit_points.size(); ++q)
923 EvaluatorTypeTraits<dim, n_components, Number>::access(
925 fe_values->shape_grad_component(i, q,
d) * value;
933template <
int n_components,
int dim,
int spacedim,
typename Number>
939 if (unit_points.size() == 0)
941 std::fill(solution_values.
begin(), solution_values.
end(), 0.0);
957 if (solution_renumbered_vectorized.size() != dofs_per_component)
958 solution_renumbered_vectorized.resize(dofs_per_component);
960 solution_renumbered_vectorized.fill(
966 const std::size_t n_points = unit_points.size();
968 for (
unsigned int i = 0; i < n_points; i += n_lanes)
972 for (
unsigned int j = 0; j < n_lanes && i + j < n_points; ++j)
973 for (
unsigned int d = 0;
d < dim; ++
d)
974 vectorized_points[
d][j] = unit_points[i + j][
d];
987 for (
unsigned int j = 0; j < n_lanes && i + j < n_points; ++j)
989 EvaluatorTypeTraits<dim, n_components, Number>::get_value(
992 for (
unsigned int j = 0; j < n_lanes && i + j < n_points; ++j)
1010 solution_renumbered_vectorized);
1014 std::fill(solution_values.
begin(), solution_values.
end(), Number());
1015 for (
unsigned int comp = 0; comp < n_components; ++comp)
1016 for (
unsigned int i = 0; i < dofs_per_component; ++i)
1019 internal::FEPointEvaluation::
1020 EvaluatorTypeTraits<dim, n_components, VectorizedArray<Number>>::
1021 write_value(result, comp, solution_renumbered_vectorized[i]);
1022 for (
unsigned int lane = n_lanes / 2; lane > 0; lane /= 2)
1023 for (
unsigned int j = 0; j < lane; ++j)
1024 result[j] += result[lane + j];
1025 solution_values[renumber[comp * dofs_per_component + i]] =
1034 Assert(fe_values.get() !=
nullptr,
1036 "Not initialized. Please call FEPointEvaluation::reinit()!"));
1037 std::fill(solution_values.
begin(), solution_values.
end(), 0.0);
1042 for (
unsigned int i = 0; i < fe->n_dofs_per_cell(); ++i)
1044 for (
unsigned int d = 0;
d < n_components; ++
d)
1045 if (nonzero_shape_function_component[i][
d] &&
1046 (fe->is_primitive(i) || fe->is_primitive()))
1047 for (
unsigned int q = 0; q < unit_points.size(); ++q)
1048 solution_values[i] +=
1049 fe_values->shape_value(i, q) *
1053 else if (nonzero_shape_function_component[i][
d])
1054 for (
unsigned int q = 0; q < unit_points.size(); ++q)
1055 solution_values[i] +=
1056 fe_values->shape_value_component(i, q,
d) *
1066 for (
unsigned int i = 0; i < fe->n_dofs_per_cell(); ++i)
1068 for (
unsigned int d = 0;
d < n_components; ++
d)
1069 if (nonzero_shape_function_component[i][
d] &&
1070 (fe->is_primitive(i) || fe->is_primitive()))
1071 for (
unsigned int q = 0; q < unit_points.size(); ++q)
1072 solution_values[i] +=
1073 fe_values->shape_grad(i, q) *
1077 else if (nonzero_shape_function_component[i][
d])
1078 for (
unsigned int q = 0; q < unit_points.size(); ++q)
1079 solution_values[i] +=
1080 fe_values->shape_grad_component(i, q,
d) *
1091template <
int n_components,
int dim,
int spacedim,
typename Number>
1095 const unsigned int point_index)
const
1098 return values[point_index];
1103template <
int n_components,
int dim,
int spacedim,
typename Number>
1107 const unsigned int point_index)
const
1115template <
int n_components,
int dim,
int spacedim,
typename Number>
1119 const unsigned int point_index)
const
1122 ExcMessage(
"Unit gradients are currently only implemented for tensor "
1123 "product finite elements combined with MappingQGeneric "
1126 return unit_gradients[point_index];
1131template <
int n_components,
int dim,
int spacedim,
typename Number>
1135 const unsigned int point_index)
1138 values[point_index] = value;
1143template <
int n_components,
int dim,
int spacedim,
typename Number>
1147 const unsigned int point_index)
1155template <
int n_components,
int dim,
int spacedim,
typename Number>
1158 const unsigned int point_index)
const
1162 return mapping_data.jacobians[point_index];
1167template <
int n_components,
int dim,
int spacedim,
typename Number>
1170 const unsigned int point_index)
const
1176 return mapping_data.inverse_jacobians[point_index];
1181template <
int n_components,
int dim,
int spacedim,
typename Number>
1184 const unsigned int point_index)
const
1188 return mapping_data.quadrature_points[point_index];
1193template <
int n_components,
int dim,
int spacedim,
typename Number>
1196 const unsigned int point_index)
const
1199 return unit_points[point_index];
std::vector< Polynomials::Polynomial< double > > poly
std::vector< value_type > solution_renumbered
void submit_gradient(const gradient_type &, const unsigned int point_index)
const MappingQGeneric< dim, spacedim > * mapping_q_generic
UpdateFlags update_flags_mapping
bool polynomials_are_hat_functions
std::vector< gradient_type > gradients
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)
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
internal::FEValuesImplementation::MappingRelatedData< dim, spacedim > mapping_data
FEPointEvaluation(const Mapping< dim > &mapping, const FiniteElement< dim > &fe, const UpdateFlags update_flags, const unsigned int first_selected_component=0)
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_jacobians
Volume element.
@ update_inverse_jacobians
Volume element.
@ update_gradients
Shape function gradients.
@ update_quadrature_points
Transformed quadrature points.
@ update_default
No update.
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcNotInitialized()
static ::ExceptionBase & ExcMessage(std::string arg1)
EvaluationFlags
The EvaluationFlags enum.
SymmetricTensor< 2, dim, Number > d(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
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 copy(const T *begin, const T *end, U *dest)
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 > & 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 > & 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)
Tensor< 1, n_components, Number > value_type
static void write_value(Number &vector_entry, const unsigned int component, const value_type &result)
Tensor< 1, n_components, Tensor< 1, dim, Number > > gradient_type
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
std::vector< unsigned int > lexicographic_numbering
void reinit(const Quadrature< dim_q > &quad, const FiniteElement< dim > &fe_dim, const unsigned int base_element=0)