17#ifndef dealii_matrix_free_evaluation_kernels_h
18#define dealii_matrix_free_evaluation_kernels_h
40 template <MatrixFreeFunctions::ElementType element,
bool is_
long>
44 template <
bool is_
long>
62 template <
bool is_
long>
81 template <
bool is_
long>
88 template <
bool is_
long>
132 evaluate(
const unsigned int n_components,
134 const Number * values_dofs_actual,
138 integrate(
const unsigned int n_components,
140 Number * values_dofs_actual,
142 const bool add_into_values_array);
147 *univariate_shape_data)
170 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
178 evaluate(
const unsigned int n_components,
180 const Number * values_dofs_actual,
184 integrate(
const unsigned int n_components,
186 Number * values_dofs_actual,
188 const bool add_into_values_array);
195 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
202 template <
bool integrate>
204 evaluate_or_integrate(
206 Number * values_dofs_actual,
208 const bool add_into_values_array =
false);
211 template <
typename EvalType,
typename Number2>
221 template <
int normal_dir>
223 evaluate_tensor_product_per_component(
225 Number * values_dofs_actual,
227 const bool add_into_values_array,
228 std::integral_constant<bool, false>);
230 template <
int normal_dir>
232 evaluate_tensor_product_per_component(
234 Number * values_dofs_actual,
236 const bool add_into_values_array,
237 std::integral_constant<bool, true>);
249 const unsigned int n_components,
251 const Number * values_dofs_actual,
257 std::array<const MatrixFreeFunctions::UnivariateShapeData<Number2> *, 3>
258 univariate_shape_data;
262 univariate_shape_data.fill(&shape_data.front());
264 if (shape_data.size() == dim)
265 for (
int i = 1; i < dim; ++i)
266 univariate_shape_data[i] = &shape_data[i];
268 Eval eval0 = create_evaluator_tensor_product(univariate_shape_data[0]);
269 Eval eval1 = create_evaluator_tensor_product(univariate_shape_data[1]);
270 Eval eval2 = create_evaluator_tensor_product(univariate_shape_data[2]);
272 const unsigned int temp_size =
275 (Eval::n_rows_of_product > Eval::n_columns_of_product ?
276 Eval::n_rows_of_product :
277 Eval::n_columns_of_product);
282 temp2 = temp1 +
std::max(Utilities::fixed_power<dim>(
283 shape_data.front().fe_degree + 1),
284 Utilities::fixed_power<dim>(
285 shape_data.front().n_q_points_1d));
289 temp2 = temp1 + temp_size;
292 const std::size_t n_q_points = temp_size == 0 ?
294 Eval::n_columns_of_product;
295 const std::size_t dofs_per_comp =
299 const Number *values_dofs = values_dofs_actual;
302 const std::size_t n_dofs_per_comp =
304 Number *values_dofs_tmp =
305 temp1 + 2 * (
std::max(n_dofs_per_comp, n_q_points));
307 fe_degree != -1 ? fe_degree : shape_data.front().fe_degree;
308 for (
unsigned int c = 0; c < n_components; ++c)
309 for (
int i = 0, count_p = 0, count_q = 0;
310 i < (dim > 2 ? degree + 1 : 1);
313 for (
int j = 0; j < (dim > 1 ? degree + 1 - i : 1); ++j)
315 for (
int k = 0; k < degree + 1 - j - i;
316 ++k, ++count_p, ++count_q)
317 values_dofs_tmp[c * dofs_per_comp + count_q] =
318 values_dofs_actual[c * n_dofs_per_comp + count_p];
319 for (
int k = degree + 1 - j - i; k < degree + 1;
321 values_dofs_tmp[c * dofs_per_comp + count_q] = Number();
323 for (
int j = degree + 1 - i; j < degree + 1; ++j)
324 for (
int k = 0; k < degree + 1; ++k, ++count_q)
325 values_dofs_tmp[c * dofs_per_comp + count_q] = Number();
327 values_dofs = values_dofs_tmp;
337 for (
unsigned int c = 0; c < n_components; ++c)
340 eval0.template values<0, true, false>(values_dofs, values_quad);
342 eval0.template gradients<0, true, false>(values_dofs,
345 eval0.template hessians<0, true, false>(values_dofs,
349 values_dofs += dofs_per_comp;
350 values_quad += n_q_points;
351 gradients_quad += n_q_points;
352 hessians_quad += n_q_points;
357 for (
unsigned int c = 0; c < n_components; ++c)
362 eval0.template gradients<0, true, false>(values_dofs, temp1);
363 eval1.template values<1, true, false>(temp1, gradients_quad);
369 eval0.template gradients<0, true, false>(values_dofs,
371 eval1.template gradients<1, true, false>(temp1,
376 eval0.template hessians<0, true, false>(values_dofs, temp1);
377 eval1.template values<1, true, false>(temp1, hessians_quad);
381 eval0.template values<0, true, false>(values_dofs, temp1);
383 eval1.template gradients<1, true, false>(temp1,
389 eval1.template hessians<1, true, false>(temp1,
395 eval1.template values<1, true, false>(temp1, values_quad);
398 values_dofs += dofs_per_comp;
399 values_quad += n_q_points;
400 gradients_quad += 2 * n_q_points;
401 hessians_quad += 3 * n_q_points;
406 for (
unsigned int c = 0; c < n_components; ++c)
411 eval0.template gradients<0, true, false>(values_dofs, temp1);
412 eval1.template values<1, true, false>(temp1, temp2);
413 eval2.template values<2, true, false>(temp2, gradients_quad);
421 eval0.template gradients<0, true, false>(values_dofs,
423 eval1.template values<1, true, false>(temp1, temp2);
425 eval2.template gradients<2, true, false>(temp2,
430 eval1.template gradients<1, true, false>(temp1, temp2);
431 eval2.template values<2, true, false>(temp2,
436 eval0.template hessians<0, true, false>(values_dofs, temp1);
437 eval1.template values<1, true, false>(temp1, temp2);
438 eval2.template values<2, true, false>(temp2, hessians_quad);
442 eval0.template values<0, true, false>(values_dofs, temp1);
445 eval1.template gradients<1, true, false>(temp1, temp2);
446 eval2.template values<2, true, false>(temp2,
455 eval1.template gradients<1, true, false>(temp1, temp2);
456 eval2.template gradients<2, true, false>(temp2,
461 eval1.template hessians<1, true, false>(temp1, temp2);
462 eval2.template values<2, true, false>(temp2,
469 eval1.template values<1, true, false>(temp1, temp2);
471 eval2.template gradients<2, true, false>(temp2,
478 eval2.template hessians<2, true, false>(temp2,
485 eval2.template values<2, true, false>(temp2, values_quad);
488 values_dofs += dofs_per_comp;
489 values_quad += n_q_points;
490 gradients_quad += 3 * n_q_points;
491 hessians_quad += 6 * n_q_points;
504 values_quad -= n_components * n_q_points;
505 values_dofs -= n_components * dofs_per_comp;
506 for (std::size_t c = 0; c < n_components; ++c)
507 for (std::size_t q = 0; q < n_q_points; ++q)
508 values_quad[c * n_q_points + q] +=
509 values_dofs[(c + 1) * dofs_per_comp - 1];
522 const unsigned int n_components,
524 Number * values_dofs_actual,
526 const bool add_into_values_array)
528 std::array<const MatrixFreeFunctions::UnivariateShapeData<Number2> *, 3>
529 univariate_shape_data;
532 univariate_shape_data.fill(&shape_data.front());
534 if (shape_data.size() == dim)
535 for (
int i = 1; i < dim; ++i)
536 univariate_shape_data[i] = &shape_data[i];
538 Eval eval0 = create_evaluator_tensor_product(univariate_shape_data[0]);
539 Eval eval1 = create_evaluator_tensor_product(univariate_shape_data[1]);
540 Eval eval2 = create_evaluator_tensor_product(univariate_shape_data[2]);
542 const unsigned int temp_size =
545 (Eval::n_rows_of_product > Eval::n_columns_of_product ?
546 Eval::n_rows_of_product :
547 Eval::n_columns_of_product);
552 temp2 = temp1 +
std::max(Utilities::fixed_power<dim>(
553 shape_data.front().fe_degree + 1),
554 Utilities::fixed_power<dim>(
555 shape_data.front().n_q_points_1d));
559 temp2 = temp1 + temp_size;
562 const std::size_t n_q_points = temp_size == 0 ?
564 Eval::n_columns_of_product;
565 const unsigned int dofs_per_comp =
567 Utilities::fixed_power<dim>(shape_data.front().fe_degree + 1) :
570 Number *values_dofs =
572 temp1 + 2 * (std::max<std::size_t>(
584 for (
unsigned int c = 0; c < n_components; ++c)
588 if (add_into_values_array ==
false)
589 eval0.template values<0, false, false>(values_quad,
592 eval0.template values<0, false, true>(values_quad,
598 add_into_values_array ==
true)
599 eval0.template gradients<0, false, true>(gradients_quad,
602 eval0.template gradients<0, false, false>(gradients_quad,
609 add_into_values_array ==
true)
610 eval0.template hessians<0, false, true>(hessians_quad,
613 eval0.template hessians<0, false, false>(hessians_quad,
618 values_dofs += dofs_per_comp;
619 values_quad += n_q_points;
620 gradients_quad += n_q_points;
621 hessians_quad += n_q_points;
626 for (
unsigned int c = 0; c < n_components; ++c)
631 eval1.template values<1, false, false>(values_quad, temp1);
632 if (add_into_values_array ==
false)
633 eval0.template values<0, false, false>(temp1, values_dofs);
635 eval0.template values<0, false, true>(temp1, values_dofs);
639 eval1.template gradients<1, false, false>(gradients_quad +
643 eval1.template values<1, false, true>(values_quad, temp1);
644 if (add_into_values_array ==
false)
645 eval0.template values<0, false, false>(temp1, values_dofs);
647 eval0.template values<0, false, true>(temp1, values_dofs);
648 eval1.template values<1, false, false>(gradients_quad, temp1);
649 eval0.template gradients<0, false, true>(temp1, values_dofs);
654 eval1.template values<1, false, false>(hessians_quad, temp1);
658 add_into_values_array ==
true)
659 eval0.template hessians<0, false, true>(temp1, values_dofs);
661 eval0.template hessians<0, false, false>(temp1,
665 eval1.template hessians<1, false, false>(hessians_quad +
668 eval0.template values<0, false, true>(temp1, values_dofs);
671 eval1.template gradients<1, false, false>(hessians_quad +
674 eval0.template gradients<0, false, true>(temp1, values_dofs);
678 values_dofs += dofs_per_comp;
679 values_quad += n_q_points;
680 gradients_quad += 2 * n_q_points;
681 hessians_quad += 3 * n_q_points;
686 for (
unsigned int c = 0; c < n_components; ++c)
691 eval2.template values<2, false, false>(values_quad, temp1);
692 eval1.template values<1, false, false>(temp1, temp2);
693 if (add_into_values_array ==
false)
694 eval0.template values<0, false, false>(temp2, values_dofs);
696 eval0.template values<0, false, true>(temp2, values_dofs);
700 eval2.template gradients<2, false, false>(gradients_quad +
704 eval2.template values<2, false, true>(values_quad, temp1);
705 eval1.template values<1, false, false>(temp1, temp2);
706 eval2.template values<2, false, false>(gradients_quad +
709 eval1.template gradients<1, false, true>(temp1, temp2);
710 if (add_into_values_array ==
false)
711 eval0.template values<0, false, false>(temp2, values_dofs);
713 eval0.template values<0, false, true>(temp2, values_dofs);
714 eval2.template values<2, false, false>(gradients_quad, temp1);
715 eval1.template values<1, false, false>(temp1, temp2);
716 eval0.template gradients<0, false, true>(temp2, values_dofs);
721 eval2.template values<2, false, false>(hessians_quad, temp1);
722 eval1.template values<1, false, false>(temp1, temp2);
726 add_into_values_array ==
true)
727 eval0.template hessians<0, false, true>(temp2, values_dofs);
729 eval0.template hessians<0, false, false>(temp2,
733 eval2.template values<2, false, false>(hessians_quad +
736 eval1.template hessians<1, false, false>(temp1, temp2);
737 eval0.template values<0, false, true>(temp2, values_dofs);
740 eval2.template hessians<2, false, false>(hessians_quad +
743 eval1.template values<1, false, false>(temp1, temp2);
744 eval0.template values<0, false, true>(temp2, values_dofs);
747 eval2.template values<2, false, false>(hessians_quad +
750 eval1.template gradients<1, false, false>(temp1, temp2);
751 eval0.template gradients<0, false, true>(temp2, values_dofs);
754 eval2.template gradients<2, false, false>(hessians_quad +
757 eval1.template values<1, false, false>(temp1, temp2);
758 eval0.template gradients<0, false, true>(temp2, values_dofs);
761 eval2.template gradients<2, false, false>(hessians_quad +
764 eval1.template gradients<1, false, false>(temp1, temp2);
765 eval0.template values<0, false, true>(temp2, values_dofs);
769 values_dofs += dofs_per_comp;
770 values_quad += n_q_points;
771 gradients_quad += 3 * n_q_points;
772 hessians_quad += 6 * n_q_points;
783 values_dofs -= n_components * dofs_per_comp - dofs_per_comp + 1;
784 values_quad -= n_components * n_q_points;
786 for (
unsigned int c = 0; c < n_components; ++c)
788 values_dofs[0] = values_quad[0];
789 for (
unsigned int q = 1; q < n_q_points; ++q)
790 values_dofs[0] += values_quad[q];
791 values_dofs += dofs_per_comp;
792 values_quad += n_q_points;
796 for (
unsigned int c = 0; c < n_components; ++c)
797 values_dofs[c * dofs_per_comp] = Number();
798 values_dofs += n_components * dofs_per_comp;
804 const std::size_t n_dofs_per_comp =
806 values_dofs -= dofs_per_comp * n_components;
808 fe_degree != -1 ? fe_degree : shape_data.front().fe_degree;
809 for (
unsigned int c = 0; c < n_components; ++c)
810 for (
int i = 0, count_p = 0, count_q = 0;
811 i < (dim > 2 ? degree + 1 : 1);
814 for (
int j = 0; j < (dim > 1 ? degree + 1 - i : 1); ++j)
816 for (
int k = 0; k < degree + 1 - j - i;
817 ++k, ++count_p, ++count_q)
818 values_dofs_actual[c * n_dofs_per_comp + count_p] =
819 values_dofs[c * dofs_per_comp + count_q];
822 count_q += i * (degree + 1);
829 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
836 Number>::evaluate(
const unsigned int n_components,
838 const Number * values_dofs_actual,
843 const std::size_t n_dofs =
856 const auto shape_values = shape_data.front().shape_values.data();
858 auto values_dofs_actual_ptr = values_dofs_actual;
860 Eval eval(shape_values,
nullptr,
nullptr, n_dofs, n_q_points);
861 for (
unsigned int c = 0; c < n_components; ++c)
863 eval.template values<0, true, false>(values_dofs_actual_ptr,
866 values_quad_ptr += n_q_points;
867 values_dofs_actual_ptr += n_dofs;
873 const auto shape_gradients = shape_data.front().shape_gradients.data();
875 auto values_dofs_actual_ptr = values_dofs_actual;
877 for (
unsigned int c = 0; c < n_components; ++c)
879 for (
unsigned int d = 0; d < dim; ++d)
882 shape_gradients + n_q_points * n_dofs * d,
887 eval.template gradients<0, true, false>(values_dofs_actual_ptr,
890 gradients_quad_ptr += n_q_points;
892 values_dofs_actual_ptr += n_dofs;
899 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
906 Number>::integrate(
const unsigned int n_components,
908 Number * values_dofs_actual,
910 const bool add_into_values_array)
915 const std::size_t n_dofs =
928 const auto shape_values = shape_data.front().shape_values.data();
930 auto values_dofs_actual_ptr = values_dofs_actual;
932 Eval eval(shape_values,
nullptr,
nullptr, n_dofs, n_q_points);
933 for (
unsigned int c = 0; c < n_components; ++c)
935 if (add_into_values_array ==
false)
936 eval.template values<0, false, false>(values_quad_ptr,
937 values_dofs_actual_ptr);
939 eval.template values<0, false, true>(values_quad_ptr,
940 values_dofs_actual_ptr);
942 values_quad_ptr += n_q_points;
943 values_dofs_actual_ptr += n_dofs;
949 const auto shape_gradients = shape_data.front().shape_gradients.data();
951 auto values_dofs_actual_ptr = values_dofs_actual;
953 for (
unsigned int c = 0; c < n_components; ++c)
955 for (
unsigned int d = 0; d < dim; ++d)
958 shape_gradients + n_q_points * n_dofs * d,
963 if ((add_into_values_array ==
false &&
966 eval.template gradients<0, false, false>(
967 gradients_quad_ptr, values_dofs_actual_ptr);
969 eval.template gradients<0, false, true>(
970 gradients_quad_ptr, values_dofs_actual_ptr);
972 gradients_quad_ptr += n_q_points;
974 values_dofs_actual_ptr += n_dofs;
980 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
981 template <
bool integrate>
988 evaluate_or_integrate(
990 Number * values_dofs_actual,
992 const bool add_into_values_array)
999 evaluate_tensor_product_per_component<0>(
1003 add_into_values_array,
1004 std::integral_constant<bool, integrate>());
1006 evaluate_tensor_product_per_component<1>(
1010 add_into_values_array,
1011 std::integral_constant<bool, integrate>());
1015 evaluate_tensor_product_per_component<2>(
1019 add_into_values_array,
1020 std::integral_constant<bool, integrate>());
1027 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
1028 template <
int normal_dir>
1035 evaluate_tensor_product_per_component(
1037 Number * values_dofs_actual,
1039 const bool add_into_values_array,
1040 std::integral_constant<bool, false>)
1042 (void)add_into_values_array;
1049 (fe_degree == -1) ? 1 : fe_degree + 1,
1058 (fe_degree == -1) ? 1 : fe_degree,
1064 typename std::conditional<normal_dir == 0, EvalNormal, EvalTangent>::type;
1066 typename std::conditional<normal_dir == 1, EvalNormal, EvalTangent>::type;
1068 typename std::conditional<normal_dir == 2, EvalNormal, EvalTangent>::type;
1071 Eval0 eval0 = create_evaluator_tensor_product<Eval0>(
1072 ((normal_dir == 0) ? shape_info.data[0] : shape_info.data[1]));
1073 Eval1 eval1 = create_evaluator_tensor_product<Eval1>(
1074 ((normal_dir == 1) ? shape_info.data[0] : shape_info.data[1]));
1075 Eval2 eval2 = create_evaluator_tensor_product<Eval2>(
1076 ((normal_dir == 2) ? shape_info.data[0] : shape_info.data[1]));
1083 std::max(Utilities::fixed_power<dim>(shape_info.data[0].fe_degree + 1),
1084 Utilities::fixed_power<dim>(shape_info.data[0].n_q_points_1d));
1086 const std::size_t n_q_points = shape_info.n_q_points;
1087 const std::size_t dofs_per_comp = shape_info.dofs_per_component_on_cell;
1090 Number *values_dofs = values_dofs_actual + dofs_per_comp * normal_dir;
1091 Number *values_quad = fe_eval.
begin_values() + n_q_points * normal_dir;
1092 Number *gradients_quad =
1094 Number *hessians_quad =
1095 (dim == 2) ? fe_eval.
begin_hessians() + 3 * n_q_points * normal_dir :
1103 eval0.template gradients<0, true, false>(values_dofs, temp1);
1104 eval1.template values<1, true, false>(temp1, gradients_quad);
1113 eval0.template gradients<0, true, false>(values_dofs, temp1);
1114 eval1.template gradients<1, true, false>(temp1,
1119 eval0.template hessians<0, true, false>(values_dofs, temp1);
1120 eval1.template values<1, true, false>(temp1, hessians_quad);
1124 eval0.template values<0, true, false>(values_dofs, temp1);
1126 eval1.template gradients<1, true, false>(temp1,
1132 eval1.template hessians<1, true, false>(temp1,
1133 hessians_quad + n_q_points);
1137 eval1.template values<1, true, false>(temp1, values_quad);
1143 eval0.template gradients<0, true, false>(values_dofs, temp1);
1144 eval1.template values<1, true, false>(temp1, temp2);
1145 eval2.template values<2, true, false>(temp2, gradients_quad);
1156 eval0.template gradients<0, true, false>(values_dofs, temp1);
1157 eval1.template values<1, true, false>(temp1, temp2);
1159 eval2.template gradients<2, true, false>(temp2,
1164 eval1.template gradients<1, true, false>(temp1, temp2);
1165 eval2.template values<2, true, false>(temp2,
1170 eval0.template hessians<0, true, false>(values_dofs, temp1);
1171 eval1.template values<1, true, false>(temp1, temp2);
1172 eval2.template values<2, true, false>(temp2, hessians_quad);
1176 eval0.template values<0, true, false>(values_dofs, temp1);
1179 eval1.template gradients<1, true, false>(temp1, temp2);
1180 eval2.template values<2, true, false>(temp2,
1189 eval1.template gradients<1, true, false>(temp1, temp2);
1190 eval2.template gradients<2, true, false>(temp2,
1195 eval1.template hessians<1, true, false>(temp1, temp2);
1196 eval2.template values<2, true, false>(temp2,
1197 hessians_quad + n_q_points);
1202 eval1.template values<1, true, false>(temp1, temp2);
1204 eval2.template gradients<2, true, false>(temp2,
1211 eval2.template hessians<2, true, false>(temp2,
1218 eval2.template values<2, true, false>(temp2, values_quad);
1225 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
1226 template <
int normal_dir>
1233 evaluate_tensor_product_per_component(
1235 Number * values_dofs_actual,
1237 const bool add_into_values_array,
1238 std::integral_constant<bool, true>)
1245 (fe_degree == -1) ? 1 : fe_degree + 1,
1254 (fe_degree == -1) ? 1 : fe_degree,
1260 typename std::conditional<normal_dir == 0, EvalNormal, EvalTangent>::type;
1262 typename std::conditional<normal_dir == 1, EvalNormal, EvalTangent>::type;
1264 typename std::conditional<normal_dir == 2, EvalNormal, EvalTangent>::type;
1267 Eval0 eval0 = create_evaluator_tensor_product<Eval0>(
1268 ((normal_dir == 0) ? shape_info.data[0] : shape_info.data[1]));
1269 Eval1 eval1 = create_evaluator_tensor_product<Eval1>(
1270 ((normal_dir == 1) ? shape_info.data[0] : shape_info.data[1]));
1271 Eval2 eval2 = create_evaluator_tensor_product<Eval2>(
1272 ((normal_dir == 2) ? shape_info.data[0] : shape_info.data[1]));
1279 std::max(Utilities::fixed_power<dim>(shape_info.data[0].fe_degree + 1),
1280 Utilities::fixed_power<dim>(shape_info.data[0].n_q_points_1d));
1282 const std::size_t n_q_points = shape_info.n_q_points;
1283 const std::size_t dofs_per_comp = shape_info.dofs_per_component_on_cell;
1286 Number *values_dofs = values_dofs_actual + dofs_per_comp * normal_dir;
1287 Number *values_quad = fe_eval.
begin_values() + n_q_points * normal_dir;
1288 Number *gradients_quad =
1290 Number *hessians_quad =
1291 (dim == 2) ? fe_eval.
begin_hessians() + 3 * n_q_points * normal_dir :
1301 eval1.template values<1, false, false>(values_quad, temp1);
1302 if (add_into_values_array ==
false)
1303 eval0.template values<0, false, false>(temp1, values_dofs);
1305 eval0.template values<0, false, true>(temp1, values_dofs);
1309 eval1.template gradients<1, false, false>(gradients_quad +
1313 eval1.template values<1, false, true>(values_quad, temp1);
1314 if (add_into_values_array ==
false)
1315 eval0.template values<0, false, false>(temp1, values_dofs);
1317 eval0.template values<0, false, true>(temp1, values_dofs);
1318 eval1.template values<1, false, false>(gradients_quad, temp1);
1319 eval0.template gradients<0, false, true>(temp1, values_dofs);
1324 eval1.template values<1, false, false>(hessians_quad, temp1);
1328 add_into_values_array ==
true)
1329 eval0.template hessians<0, false, true>(temp1, values_dofs);
1331 eval0.template hessians<0, false, false>(temp1, values_dofs);
1334 eval1.template hessians<1, false, false>(hessians_quad +
1337 eval0.template values<0, false, true>(temp1, values_dofs);
1340 eval1.template gradients<1, false, false>(hessians_quad +
1343 eval0.template gradients<0, false, true>(temp1, values_dofs);
1351 eval2.template values<2, false, false>(values_quad, temp1);
1352 eval1.template values<1, false, false>(temp1, temp2);
1353 if (add_into_values_array ==
false)
1354 eval0.template values<0, false, false>(temp2, values_dofs);
1356 eval0.template values<0, false, true>(temp2, values_dofs);
1360 eval2.template gradients<2, false, false>(gradients_quad +
1364 eval2.template values<2, false, true>(values_quad, temp1);
1365 eval1.template values<1, false, false>(temp1, temp2);
1366 eval2.template values<2, false, false>(gradients_quad +
1369 eval1.template gradients<1, false, true>(temp1, temp2);
1370 if (add_into_values_array ==
false)
1371 eval0.template values<0, false, false>(temp2, values_dofs);
1373 eval0.template values<0, false, true>(temp2, values_dofs);
1374 eval2.template values<2, false, false>(gradients_quad, temp1);
1375 eval1.template values<1, false, false>(temp1, temp2);
1376 eval0.template gradients<0, false, true>(temp2, values_dofs);
1381 eval2.template values<2, false, false>(hessians_quad, temp1);
1382 eval1.template values<1, false, false>(temp1, temp2);
1386 add_into_values_array ==
true)
1387 eval0.template hessians<0, false, true>(temp2, values_dofs);
1389 eval0.template hessians<0, false, false>(temp2, values_dofs);
1392 eval2.template values<2, false, false>(hessians_quad + n_q_points,
1394 eval1.template hessians<1, false, false>(temp1, temp2);
1395 eval0.template values<0, false, true>(temp2, values_dofs);
1398 eval2.template hessians<2, false, false>(hessians_quad +
1401 eval1.template values<1, false, false>(temp1, temp2);
1402 eval0.template values<0, false, true>(temp2, values_dofs);
1405 eval2.template values<2, false, false>(hessians_quad +
1408 eval1.template gradients<1, false, false>(temp1, temp2);
1409 eval0.template gradients<0, false, true>(temp2, values_dofs);
1412 eval2.template gradients<2, false, false>(hessians_quad +
1415 eval1.template values<1, false, false>(temp1, temp2);
1416 eval0.template gradients<0, false, true>(temp2, values_dofs);
1419 eval2.template gradients<2, false, false>(hessians_quad +
1422 eval1.template gradients<1, false, false>(temp1, temp2);
1423 eval0.template values<0, false, true>(temp2, values_dofs);
1458 static_assert(basis_size_1 == 0 || basis_size_1 <= basis_size_2,
1459 "The second dimension must not be smaller than the first");
1483 template <
typename Number,
typename Number2>
1490 const Number * values_in,
1491 Number * values_out,
1492 const unsigned int basis_size_1_variable =
1494 const unsigned int basis_size_2_variable =
1498 basis_size_1 != 0 || basis_size_1_variable <= basis_size_2_variable,
1499 ExcMessage(
"The second dimension must not be smaller than the first"));
1507 constexpr int next_dim =
1509 ((basis_size_1 == 0 || basis_size_2 > basis_size_1) && dim > 1)) ?
1516 (basis_size_1 == 0 ? 0 : basis_size_2),
1519 eval_val(transformation_matrix,
1522 basis_size_1_variable,
1523 basis_size_2_variable);
1524 const unsigned int np_1 =
1525 basis_size_1 > 0 ? basis_size_1 : basis_size_1_variable;
1526 const unsigned int np_2 =
1527 basis_size_1 > 0 ? basis_size_2 : basis_size_2_variable;
1529 ExcMessage(
"Cannot transform with 0-point basis"));
1531 ExcMessage(
"Cannot transform with 0-point basis"));
1535 values_in = values_in + n_components * Utilities::fixed_power<dim>(np_1);
1537 values_out + n_components * Utilities::fixed_power<dim>(np_2);
1538 for (
unsigned int c = n_components; c != 0; --c)
1540 values_in -= Utilities::fixed_power<dim>(np_1);
1541 values_out -= Utilities::fixed_power<dim>(np_2);
1543 for (
unsigned int q = np_1; q != 0; --q)
1550 transformation_matrix,
1552 (q - 1) * Utilities::fixed_power<next_dim>(np_1),
1554 (q - 1) * Utilities::fixed_power<next_dim>(np_2),
1555 basis_size_1_variable,
1556 basis_size_2_variable);
1561 if (basis_size_1 > 0 && basis_size_2 == basis_size_1 && dim == 2)
1563 eval_val.template values<0, true, false>(values_in, values_out);
1564 eval_val.template values<1, true, false>(values_out, values_out);
1567 eval_val.template values<dim - 1,
true,
false>(values_in,
1570 eval_val.template values<dim - 1,
true,
false>(values_out,
1605 template <
typename Number,
typename Number2>
1612 const bool add_into_result,
1614 Number * values_out,
1615 const unsigned int basis_size_1_variable =
1617 const unsigned int basis_size_2_variable =
1621 basis_size_1 != 0 || basis_size_1_variable <= basis_size_2_variable,
1622 ExcMessage(
"The second dimension must not be smaller than the first"));
1623 Assert(add_into_result ==
false || values_in != values_out,
1625 "Input and output cannot alias with each other when "
1626 "adding the result of the basis change to existing data"));
1632 constexpr int next_dim =
1634 ((basis_size_1 == 0 || basis_size_2 > basis_size_1) && dim > 1)) ?
1640 (basis_size_1 == 0 ? 0 : basis_size_2),
1643 eval_val(transformation_matrix,
1644 transformation_matrix,
1645 transformation_matrix,
1646 basis_size_1_variable,
1647 basis_size_2_variable);
1648 const unsigned int np_1 =
1649 basis_size_1 > 0 ? basis_size_1 : basis_size_1_variable;
1650 const unsigned int np_2 =
1651 basis_size_1 > 0 ? basis_size_2 : basis_size_2_variable;
1653 ExcMessage(
"Cannot transform with 0-point basis"));
1655 ExcMessage(
"Cannot transform with 0-point basis"));
1657 for (
unsigned int c = 0; c < n_components; ++c)
1659 if (basis_size_1 > 0 && basis_size_2 == basis_size_1 && dim == 2)
1662 eval_val.template values<1, false, false>(values_in, values_in);
1664 eval_val.template hessians<1, false, false>(values_in,
1667 if (add_into_result)
1670 eval_val.template values<0, false, true>(values_in,
1673 eval_val.template hessians<0, false, true>(values_in,
1679 eval_val.template values<0, false, false>(values_in,
1682 eval_val.template hessians<0, false, false>(values_in,
1688 if (dim == 1 && add_into_result)
1691 eval_val.template values<0, false, true>(values_in,
1694 eval_val.template hessians<0, false, true>(values_in,
1700 eval_val.template values<0, false, false>(values_in,
1703 eval_val.template hessians<0, false, false>(values_in,
1709 eval_val.template values<dim - 1,
false,
false>(values_in,
1712 eval_val.template hessians<dim - 1,
false,
false>(
1713 values_in, values_in);
1717 for (
unsigned int q = 0; q < np_1; ++q)
1724 transformation_matrix,
1727 q * Utilities::fixed_power<next_dim>(np_2),
1729 q * Utilities::fixed_power<next_dim>(np_1),
1730 basis_size_1_variable,
1731 basis_size_2_variable);
1733 values_in += Utilities::fixed_power<dim>(np_2);
1734 values_out += Utilities::fixed_power<dim>(np_1);
1758 template <
typename Number,
typename Number2>
1763 const Number * values_in,
1764 Number * scratch_data,
1765 Number * values_out)
1767 constexpr int next_dim = dim > 1 ? dim - 1 : dim;
1768 Number * my_scratch =
1769 basis_size_1 != basis_size_2 ? scratch_data : values_out;
1771 const unsigned int size_per_component =
Utilities::pow(basis_size_2, dim);
1772 Assert(coefficients.
size() == size_per_component ||
1773 coefficients.
size() == n_components * size_per_component,
1775 const unsigned int stride =
1776 coefficients.
size() == size_per_component ? 0 : 1;
1778 for (
unsigned int q = basis_size_1; q != 0; --q)
1785 transformation_matrix,
1798 eval_val(transformation_matrix);
1799 const unsigned int n_inner_blocks =
1800 (dim > 1 && basis_size_2 < 10) ? basis_size_2 : 1;
1801 const unsigned int n_blocks =
Utilities::pow(basis_size_2, dim - 1);
1802 for (
unsigned int ii = 0; ii < n_blocks; ii += n_inner_blocks)
1803 for (
unsigned int c = 0; c < n_components; ++c)
1805 for (
unsigned int i = ii; i < ii + n_inner_blocks; ++i)
1806 eval_val.template values_one_line<dim - 1, true, false>(
1807 my_scratch + i, my_scratch + i);
1808 for (
unsigned int q = 0; q < basis_size_2; ++q)
1809 for (
unsigned int i = ii; i < ii + n_inner_blocks; ++i)
1810 my_scratch[i + q * n_blocks + c * size_per_component] *=
1811 coefficients[i + q * n_blocks +
1812 c * stride * size_per_component];
1813 for (
unsigned int i = ii; i < ii + n_inner_blocks; ++i)
1814 eval_val.template values_one_line<dim - 1, false, false>(
1815 my_scratch + i, my_scratch + i);
1817 for (
unsigned int q = 0; q < basis_size_1; ++q)
1824 transformation_matrix,
1845 template <
int dim,
int fe_degree,
typename Number>
1858 evaluate(
const unsigned int n_components,
1860 const Number * values_dofs,
1866 const Number * values_dofs,
1867 Number * gradients_quad,
1868 Number * hessians_quad);
1871 integrate(
const unsigned int n_components,
1873 Number * values_dofs,
1875 const bool add_into_values_array);
1880 Number * values_dofs,
1881 Number * gradients_quad,
1882 const Number * hessians_quad,
1883 const bool add_into_values_array);
1888 template <
int dim,
int fe_degree,
typename Number>
1891 const unsigned int n_components,
1893 const Number * values_dofs,
1896 constexpr std::size_t n_points =
Utilities::pow(fe_degree + 1, dim);
1898 for (
unsigned int c = 0; c < n_components; ++c)
1901 for (
unsigned int i = 0; i < n_points; ++i)
1903 values_dofs[n_points * c + i];
1907 values_dofs + c * n_points,
1910 c * dim * (dim + 1) / 2 * n_points);
1916 template <
int dim,
int fe_degree,
typename Number>
1921 const Number * values_dofs,
1922 Number * gradients_quad,
1923 Number * hessians_quad)
1926 (fe_degree + 2) / 2 * (fe_degree + 1));
1927 constexpr std::size_t n_points =
Utilities::pow(fe_degree + 1, dim);
1932 if ((evaluation_flag &
1935 eval.template gradients<0, true, false>(values_dofs, gradients_quad);
1937 eval.template gradients<1, true, false>(values_dofs,
1938 gradients_quad + n_points);
1940 eval.template gradients<2, true, false>(values_dofs,
1946 eval.template hessians<0, true, false>(values_dofs, hessians_quad);
1949 eval.template gradients<1, true, false>(gradients_quad,
1952 eval.template hessians<1, true, false>(values_dofs,
1953 hessians_quad + n_points);
1957 eval.template gradients<2, true, false>(gradients_quad,
1960 eval.template gradients<2, true, false>(gradients_quad + n_points,
1963 eval.template hessians<2, true, false>(values_dofs,
1972 template <
int dim,
int fe_degree,
typename Number>
1975 const unsigned int n_components,
1977 Number * values_dofs,
1979 const bool add_into_values_array)
1981 constexpr std::size_t n_points =
Utilities::pow(fe_degree + 1, dim);
1983 for (
unsigned int c = 0; c < n_components; ++c)
1987 if (add_into_values_array)
1988 for (
unsigned int i = 0; i < n_points; ++i)
1989 values_dofs[n_points * c + i] +=
1992 for (
unsigned int i = 0; i < n_points; ++i)
1993 values_dofs[n_points * c + i] =
1999 values_dofs + c * n_points,
2002 c * dim * (dim + 1) / 2 * n_points,
2003 add_into_values_array ||
2010 template <
int dim,
int fe_degree,
typename Number>
2015 Number * values_dofs,
2016 Number * gradients_quad,
2017 const Number * hessians_quad,
2018 const bool add_into_values_array)
2021 (fe_degree + 2) / 2 * (fe_degree + 1));
2026 constexpr std::size_t n_points =
Utilities::pow(fe_degree + 1, dim);
2032 if (add_into_values_array ==
true)
2033 eval.template hessians<0, false, true>(hessians_quad, values_dofs);
2035 eval.template hessians<0, false, false>(hessians_quad, values_dofs);
2038 eval.template hessians<1, false, true>(hessians_quad + n_points,
2042 eval.template hessians<2, false, true>(hessians_quad + 2 * n_points,
2049 eval.template gradients<1, false, true>(hessians_quad +
2053 eval.template gradients<1, false, false>(hessians_quad +
2061 eval.template gradients<1, false, true>(hessians_quad +
2065 eval.template gradients<1, false, false>(hessians_quad +
2070 eval.template gradients<2, false, true>(hessians_quad +
2076 eval.template gradients<2, false, true>(
2077 hessians_quad + 5 * n_points, gradients_quad + n_points);
2079 eval.template gradients<2, false, false>(
2080 hessians_quad + 5 * n_points, gradients_quad + n_points);
2087 for (
unsigned int q = 0; q < n_points; ++q)
2088 gradients_quad[(dim - 1) * n_points + q] = Number();
2091 if ((integration_flag &
2094 if (add_into_values_array ||
2096 eval.template gradients<0, false, true>(gradients_quad, values_dofs);
2098 eval.template gradients<0, false, false>(gradients_quad, values_dofs);
2100 eval.template gradients<1, false, true>(gradients_quad + n_points,
2103 eval.template gradients<2, false, true>(gradients_quad + 2 * n_points,
2120 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
2124 evaluate(
const unsigned int n_components,
2126 const Number * values_dofs,
2130 integrate(
const unsigned int n_components,
2132 Number * values_dofs,
2134 const bool add_into_values_array);
2139 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
2145 Number>::evaluate(
const unsigned int n_components,
2147 const Number * values_dofs,
2152 Assert(n_q_points_1d > fe_degree,
2153 ExcMessage(
"You lose information when going to a collocation space "
2154 "of lower degree, so the evaluation results would be "
2155 "wrong. Thus, this class does not permit the desired "
2157 constexpr std::size_t n_dofs =
Utilities::pow(fe_degree + 1, dim);
2158 constexpr std::size_t n_q_points =
Utilities::pow(n_q_points_1d, dim);
2160 for (
unsigned int c = 0; c < n_components; ++c)
2166 (fe_degree >= n_q_points_1d ? n_q_points_1d : fe_degree + 1),
2167 n_q_points_1d>::do_forward(1,
2168 shape_data.shape_values_eo,
2169 values_dofs + c * n_dofs,
2173 if (evaluation_flag &
2176 do_evaluate(shape_data,
2182 c * dim * (dim + 1) / 2 * n_q_points);
2188 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
2194 Number>::integrate(
const unsigned int n_components,
2196 Number * values_dofs,
2198 const bool add_into_values_array)
2202 Assert(n_q_points_1d > fe_degree,
2203 ExcMessage(
"You lose information when going to a collocation space "
2204 "of lower degree, so the evaluation results would be "
2205 "wrong. Thus, this class does not permit the desired "
2207 constexpr std::size_t n_q_points =
Utilities::pow(n_q_points_1d, dim);
2209 for (
unsigned int c = 0; c < n_components; ++c)
2212 if (integration_flag &
2221 c * dim * (dim + 1) / 2 * n_q_points,
2230 (fe_degree >= n_q_points_1d ? n_q_points_1d : fe_degree + 1),
2231 n_q_points_1d>::do_backward(1,
2232 shape_data.shape_values_eo,
2233 add_into_values_array,
2251 const unsigned int n_q_points_1d)
2253 return (n_q_points_1d > fe_degree) && (n_q_points_1d < 200) &&
2254 (n_q_points_1d <= 3 * fe_degree / 2 + 1);
2273 template <
int dim,
typename Number,
bool do_
integrate>
2276 template <
int fe_degree,
int n_q_po
ints_1d,
typename OtherNumber>
2278 run(
const unsigned int n_components,
2280 OtherNumber * values_dofs,
2282 const bool sum_into_values_array =
false)
2287 std::is_same<Number,
2288 typename std::remove_const<OtherNumber>::type>
::value,
2289 "Type of Number and of OtherNumber do not match.");
2296 element_type == ElementType::tensor_general) ||
2297 element_type == ElementType::tensor_raviart_thomas,
2300 if (fe_degree >= 0 && fe_degree + 1 == n_q_points_1d &&
2301 element_type == ElementType::tensor_symmetric_collocation)
2309 sum_into_values_array);
2313 else if (fe_degree >= 0 &&
2315 element_type <= ElementType::tensor_symmetric)
2326 sum_into_values_array);
2328 else if (fe_degree >= 0 &&
2329 element_type <= ElementType::tensor_symmetric_no_collocation)
2340 sum_into_values_array);
2342 else if (element_type == ElementType::tensor_symmetric_plus_dg0)
2349 Number>>(n_components,
2353 sum_into_values_array);
2355 else if (element_type == ElementType::truncated_tensor)
2366 sum_into_values_array);
2368 else if (element_type == ElementType::tensor_none)
2379 sum_into_values_array);
2381 else if (element_type == ElementType::tensor_raviart_thomas)
2385 (fe_degree == -1) ? 1 : fe_degree,
2386 (n_q_points_1d < 1) ? 1 : n_q_points_1d,
2388 template evaluate_or_integrate<do_integrate>(evaluation_flag,
2389 const_cast<Number *
>(
2392 sum_into_values_array);
2405 sum_into_values_array);
2412 template <
typename T>
2415 const unsigned int n_components,
2417 const Number * values_dofs,
2419 const bool sum_into_values_array,
2420 std::integral_constant<bool, false>)
2422 (void)sum_into_values_array;
2424 T::evaluate(n_components, evaluation_flag, values_dofs, fe_eval);
2427 template <
typename T>
2430 const unsigned int n_components,
2432 Number * values_dofs,
2434 const bool sum_into_values_array,
2435 std::integral_constant<bool, true>)
2437 T::integrate(n_components,
2441 sum_into_values_array);
2444 template <
typename T,
typename OtherNumber>
2447 const unsigned int n_components,
2449 OtherNumber * values_dofs,
2451 const bool sum_into_values_array)
2453 evaluate_or_integrate<T>(n_components,
2457 sum_into_values_array,
2458 std::integral_constant<bool, do_integrate>());
2464 template <
bool symmetric_evaluate,
2490 const unsigned int subface_index,
2491 const unsigned int direction)
2493 if (symmetric_evaluate)
2507 const unsigned int index =
2508 direction == 0 ? subface_index % 2 : subface_index / 2;
2519 const unsigned int n_components,
2522 Number * values_dofs,
2523 Number * values_quad,
2524 Number * gradients_quad,
2525 Number * hessians_quad,
2526 Number * scratch_data,
2527 const unsigned int subface_index)
2532 const std::size_t n_dofs = fe_degree > -1 ?
2535 const std::size_t n_q_points =
2540 Number *values_dofs_ptr = values_dofs;
2544 for (
unsigned int c = 0; c < n_components; ++c)
2549 eval0.template values<0, true, false>(values_dofs,
2551 eval1.template values<1, true, false>(values_quad,
2555 eval0.template values<0, true, false>(values_dofs,
2559 values_quad[0] = values_dofs[0];
2566 values_dofs += 3 * n_dofs;
2567 values_quad += n_q_points;
2570 for (
unsigned int c = 0; c < n_components; ++c)
2575 if (symmetric_evaluate &&
2578 eval0.template values<0, true, false>(values_dofs,
2580 eval0.template values<1, true, false>(values_quad,
2589 eval_grad.template gradients<0, true, false>(
2590 values_quad, gradients_quad);
2591 eval_grad.template gradients<1, true, false>(
2592 values_quad, gradients_quad + n_q_points);
2597 eval0.template gradients<0, true, false>(values_dofs,
2599 eval1.template values<1, true, false>(scratch_data,
2603 eval0.template values<0, true, false>(values_dofs,
2605 eval1.template gradients<1, true, false>(scratch_data,
2610 eval1.template values<1, true, false>(scratch_data,
2614 eval0.template values<0, true, false>(values_dofs + n_dofs,
2616 eval1.template values<1, true, false>(
2617 scratch_data, gradients_quad + (dim - 1) * n_q_points);
2621 eval0.template values<0, true, false>(values_dofs + n_dofs,
2624 eval0.template gradients<0, true, false>(values_dofs,
2627 eval0.template values<0, true, false>(values_dofs,
2631 values_quad[0] = values_dofs[0];
2632 gradients_quad[0] = values_dofs[1];
2637 values_dofs += 3 * n_dofs;
2638 values_quad += n_q_points;
2639 gradients_quad += dim * n_q_points;
2644 values_dofs = values_dofs_ptr;
2645 for (
unsigned int c = 0; c < n_components; ++c)
2651 eval0.template hessians<0, true, false>(values_dofs,
2653 eval1.template values<1, true, false>(scratch_data,
2657 eval0.template values<0, true, false>(values_dofs,
2659 eval1.template hessians<1, true, false>(scratch_data,
2664 eval0.template values<0, true, false>(values_dofs +
2667 eval1.template values<1, true, false>(scratch_data,
2672 eval0.template gradients<0, true, false>(values_dofs,
2674 eval1.template gradients<1, true, false>(scratch_data,
2679 eval0.template gradients<0, true, false>(values_dofs +
2682 eval1.template values<1, true, false>(scratch_data,
2687 eval0.template values<0, true, false>(values_dofs + n_dofs,
2689 eval1.template gradients<1, true, false>(scratch_data,
2696 eval0.template hessians<0, true, false>(values_dofs,
2699 eval0.template values<0, true, false>(
2700 values_dofs + 2 * n_dofs, hessians_quad + n_q_points);
2702 eval0.template gradients<0, true, false>(
2703 values_dofs + n_dofs, hessians_quad + 2 * n_q_points);
2706 hessians_quad[0] = values_dofs[2];
2711 values_dofs += 3 * n_dofs;
2712 hessians_quad += dim * (dim + 1) / 2 * n_q_points;
2719 const unsigned int n_components,
2722 Number * values_dofs,
2723 Number * values_quad,
2724 Number * gradients_quad,
2725 Number * hessians_quad,
2726 Number * scratch_data,
2727 const unsigned int subface_index)
2732 const std::size_t n_dofs =
2736 const std::size_t n_q_points =
2741 Number *values_dofs_ptr = values_dofs;
2745 for (
unsigned int c = 0; c < n_components; ++c)
2750 eval1.template values<1, false, false>(values_quad,
2752 eval0.template values<0, false, false>(values_quad,
2756 eval0.template values<0, false, false>(values_quad,
2760 values_dofs[0] = values_quad[0];
2765 values_dofs += 3 * n_dofs;
2766 values_quad += n_q_points;
2769 for (
unsigned int c = 0; c < n_components; ++c)
2775 eval1.template values<1, false, false>(gradients_quad +
2779 eval0.template values<0, false, false>(gradients_quad +
2781 values_dofs + n_dofs);
2782 if (symmetric_evaluate &&
2793 eval_grad.template gradients<1, false, true>(
2794 gradients_quad + n_q_points, values_quad);
2796 eval_grad.template gradients<1, false, false>(
2797 gradients_quad + n_q_points, values_quad);
2798 eval_grad.template gradients<0, false, true>(
2799 gradients_quad, values_quad);
2800 eval0.template values<1, false, false>(values_quad,
2802 eval0.template values<0, false, false>(values_quad,
2809 eval1.template values<1, false, false>(values_quad,
2811 eval1.template gradients<1, false, true>(
2812 gradients_quad + n_q_points, scratch_data);
2815 eval1.template gradients<1, false, false>(
2816 gradients_quad + n_q_points, scratch_data);
2819 eval0.template values<0, false, false>(scratch_data,
2823 eval1.template values<1, false, false>(gradients_quad,
2825 eval0.template gradients<0, false, true>(scratch_data,
2830 eval0.template values<0, false, false>(gradients_quad +
2832 values_dofs + n_dofs);
2833 eval0.template gradients<0, false, false>(gradients_quad,
2836 eval0.template values<0, false, true>(values_quad,
2840 values_dofs[0] = values_quad[0];
2841 values_dofs[1] = gradients_quad[0];
2846 values_dofs += 3 * n_dofs;
2847 values_quad += n_q_points;
2848 gradients_quad += dim * n_q_points;
2853 values_dofs = values_dofs_ptr;
2854 for (
unsigned int c = 0; c < n_components; ++c)
2860 eval1.template values<1, false, false>(hessians_quad,
2864 eval0.template hessians<0, false, true>(scratch_data,
2867 eval0.template hessians<0, false, false>(scratch_data,
2871 eval1.template hessians<1, false, false>(hessians_quad +
2874 eval0.template values<0, false, true>(scratch_data,
2878 eval1.template values<1, false, false>(hessians_quad +
2881 eval0.template values<0, false, false>(scratch_data,
2886 eval1.template gradients<1, false, false>(hessians_quad +
2889 eval0.template gradients<0, false, true>(scratch_data,
2893 eval1.template values<1, false, false>(hessians_quad +
2897 eval0.template gradients<0, false, true>(scratch_data,
2901 eval0.template gradients<0, false, false>(scratch_data,
2906 eval1.template gradients<1, false, false>(hessians_quad +
2909 eval0.template values<0, false, true>(scratch_data,
2910 values_dofs + n_dofs);
2917 eval0.template hessians<0, false, true>(hessians_quad,
2920 eval0.template hessians<0, false, false>(hessians_quad,
2924 eval0.template values<0, false, false>(
2925 hessians_quad + n_q_points, values_dofs + 2 * n_dofs);
2928 eval0.template gradients<0, false, true>(
2929 hessians_quad + 2 * n_q_points, values_dofs + n_dofs);
2931 eval0.template gradients<0, false, false>(
2932 hessians_quad + 2 * n_q_points, values_dofs + n_dofs);
2935 values_dofs[2] = hessians_quad[0];
2944 values_dofs += 3 * n_dofs;
2945 hessians_quad += dim * (dim + 1) / 2 * n_q_points;
2951 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
2963 template <
typename EvalType>
2967 const unsigned int subface_index,
2968 const unsigned int direction)
2976 const unsigned int index =
2977 direction == 0 ? subface_index % 2 : subface_index / 2;
2984 template <
bool integrate>
2988 Number * values_dofs,
2990 Number * scratch_data,
2991 const unsigned int subface_index,
2992 const unsigned int face_no)
2994 const unsigned int face_direction = face_no / 2;
3014 evaluate_in_face_apply<0>(values_dofs,
3020 std::integral_constant<bool, integrate>());
3023 evaluate_in_face_apply<1>(values_dofs,
3029 std::integral_constant<bool, integrate>());
3031 evaluate_in_face_apply<2>(values_dofs,
3037 std::integral_constant<bool, integrate>());
3048 template <
int normal_dir>
3051 Number * values_dofs,
3053 Number * scratch_data,
3055 const unsigned int face_direction,
3056 const unsigned int subface_index,
3057 std::integral_constant<bool, false>)
3062 (fe_degree == -1) ? 1 : fe_degree + 1,
3070 (fe_degree == -1) ? 1 : fe_degree,
3076 using TempEval0 =
typename std::
3077 conditional<normal_dir == 0, EvalNormal, EvalTangent>::type;
3078 using TempEval1 =
typename std::
3079 conditional<normal_dir == 0, EvalTangent, EvalNormal>::type;
3080 using Eval0 =
typename std::
3081 conditional<normal_dir == 2, EvalGeneral, TempEval0>::type;
3082 using Eval1 =
typename std::
3083 conditional<normal_dir == 2, EvalGeneral, TempEval1>::type;
3086 Eval0 eval0 = create_evaluator_tensor_product<Eval0>(
3087 ((normal_dir == 0) ? shape_info.data[0] : shape_info.data[1]),
3090 Eval1 eval1 = create_evaluator_tensor_product<Eval1>(
3091 ((normal_dir == 1) ? shape_info.data[0] : shape_info.data[1]),
3095 constexpr std::size_t n_q_points =
Utilities::pow(n_q_points_1d, dim - 1);
3096 const std::size_t n_dofs_tangent = shape_info.dofs_per_component_on_face;
3097 const std::size_t n_dofs_normal =
3099 const std::size_t dofs_stride =
3100 (std::is_same<Eval0, EvalGeneral>::value) ? n_dofs_normal :
3103 static constexpr ::ndarray<unsigned int, 3, 3> component_table = {
3104 {{{1, 2, 0}}, {{2, 0, 1}}, {{0, 1, 2}}}};
3105 const unsigned int component =
3106 (dim == 2 && normal_dir == 0 && face_direction == 1) ?
3108 component_table[face_direction][normal_dir];
3112 3 * ((component == 0) ?
3115 ((face_direction == 0) ? n_dofs_normal : n_dofs_tangent) :
3116 ((face_direction == 2) ? n_dofs_tangent + n_dofs_tangent :
3117 n_dofs_normal + n_dofs_tangent)));
3118 const unsigned int shift = (dim == 2) ? normal_dir / 2 : normal_dir;
3119 Number *values_quad = fe_eval.
begin_values() + n_q_points * shift;
3120 Number *gradients_quad =
3122 Number *hessians_quad =
3123 fe_eval.
begin_hessians() + dim * (dim + 1) / 2 * n_q_points * shift;
3132 eval0.template values<0, true, false>(values_dofs, values_quad);
3133 eval1.template values<1, true, false>(values_quad, values_quad);
3136 eval0.template values<0, true, false>(values_dofs, values_quad);
3148 eval0.template gradients<0, true, false>(values_dofs,
3150 eval1.template values<1, true, false>(scratch_data,
3154 eval0.template values<0, true, false>(values_dofs,
3156 eval1.template gradients<1, true, false>(scratch_data,
3161 eval1.template values<1, true, false>(scratch_data,
3165 eval0.template values<0, true, false>(values_dofs + dofs_stride,
3167 eval1.template values<1, true, false>(scratch_data,
3173 eval0.template values<0, true, false>(values_dofs + dofs_stride,
3176 eval0.template gradients<0, true, false>(values_dofs,
3179 eval0.template values<0, true, false>(values_dofs,
3193 eval0.template hessians<0, true, false>(values_dofs,
3195 eval1.template values<1, true, false>(scratch_data,
3199 eval0.template values<0, true, false>(values_dofs,
3201 eval1.template hessians<1, true, false>(scratch_data,
3206 eval0.template values<0, true, false>(values_dofs +
3209 eval1.template values<1, true, false>(scratch_data,
3214 eval0.template gradients<0, true, false>(values_dofs,
3216 eval1.template gradients<1, true, false>(scratch_data,
3221 eval0.template gradients<0, true, false>(values_dofs +
3224 eval1.template values<1, true, false>(scratch_data,
3229 eval0.template values<0, true, false>(values_dofs + dofs_stride,
3231 eval1.template gradients<1, true, false>(scratch_data,
3238 eval0.template hessians<0, true, false>(values_dofs,
3241 eval0.template values<0, true, false>(
3242 values_dofs + 2 * dofs_stride, hessians_quad + n_q_points);
3244 eval0.template gradients<0, true, false>(
3245 values_dofs + dofs_stride, hessians_quad + 2 * n_q_points);
3253 template <
int normal_dir>
3256 Number * values_dofs,
3258 Number * scratch_data,
3260 const unsigned int face_direction,
3261 const unsigned int subface_index,
3262 std::integral_constant<bool, true>)
3267 (fe_degree == -1) ? 1 : fe_degree + 1,
3275 (fe_degree == -1) ? 1 : fe_degree,
3281 using TempEval0 =
typename std::
3282 conditional<normal_dir == 0, EvalNormal, EvalTangent>::type;
3283 using TempEval1 =
typename std::
3284 conditional<normal_dir == 0, EvalTangent, EvalNormal>::type;
3285 using Eval0 =
typename std::
3286 conditional<normal_dir == 2, EvalGeneral, TempEval0>::type;
3287 using Eval1 =
typename std::
3288 conditional<normal_dir == 2, EvalGeneral, TempEval1>::type;
3291 Eval0 eval0 = create_evaluator_tensor_product<Eval0>(
3292 ((normal_dir == 0) ? shape_info.data[0] : shape_info.data[1]),
3295 Eval1 eval1 = create_evaluator_tensor_product<Eval1>(
3296 ((normal_dir == 1) ? shape_info.data[0] : shape_info.data[1]),
3300 constexpr std::size_t n_q_points =
Utilities::pow(n_q_points_1d, dim - 1);
3301 const std::size_t n_dofs_tangent = shape_info.dofs_per_component_on_face;
3302 const std::size_t n_dofs_normal =
3304 const std::size_t dofs_stride =
3305 (std::is_same<Eval0, EvalGeneral>::value) ? n_dofs_normal :
3308 static constexpr ::ndarray<unsigned int, 3, 3> component_table = {
3309 {{{1, 2, 0}}, {{2, 0, 1}}, {{0, 1, 2}}}};
3310 const unsigned int component =
3311 (dim == 2 && normal_dir == 0 && face_direction == 1) ?
3313 component_table[face_direction][normal_dir];
3317 3 * ((component == 0) ?
3320 ((face_direction == 0) ? n_dofs_normal : n_dofs_tangent) :
3321 ((face_direction == 2) ? n_dofs_tangent + n_dofs_tangent :
3322 n_dofs_normal + n_dofs_tangent)));
3323 const unsigned int shift = (dim == 2) ? normal_dir / 2 : normal_dir;
3324 Number *values_quad = fe_eval.
begin_values() + n_q_points * shift;
3325 Number *gradients_quad =
3327 Number *hessians_quad =
3328 fe_eval.
begin_hessians() + dim * (dim + 1) / 2 * n_q_points * shift;
3337 eval1.template values<1, false, false>(values_quad,
3339 eval0.template values<0, false, false>(values_quad,
3343 eval0.template values<0, false, false>(values_quad,
3356 eval1.template values<1, false, false>(gradients_quad +
3360 eval0.template values<0, false, false>(
3361 gradients_quad + 2 * n_q_points, values_dofs + dofs_stride);
3365 eval1.template values<1, false, false>(values_quad,
3367 eval1.template gradients<1, false, true>(gradients_quad +
3372 eval1.template gradients<1, false, false>(gradients_quad +
3377 eval0.template values<0, false, false>(scratch_data,
3381 eval1.template values<1, false, false>(gradients_quad,
3383 eval0.template gradients<0, false, true>(scratch_data,
3388 eval0.template values<0, false, false>(
3389 gradients_quad + n_q_points, values_dofs + dofs_stride);
3390 eval0.template gradients<0, false, false>(gradients_quad,
3393 eval0.template values<0, false, true>(values_quad,
3407 eval1.template values<1, false, false>(hessians_quad,
3409 if ((evaluation_flag &
3411 eval0.template hessians<0, false, true>(scratch_data,
3414 eval0.template hessians<0, false, false>(scratch_data,
3418 eval1.template hessians<1, false, false>(hessians_quad +
3421 eval0.template values<0, false, true>(scratch_data,
3425 eval1.template values<1, false, false>(hessians_quad +
3428 eval0.template values<0, false, false>(scratch_data,
3433 eval1.template gradients<1, false, false>(hessians_quad +
3436 eval0.template gradients<0, false, true>(scratch_data,
3440 eval1.template values<1, false, false>(hessians_quad +
3444 eval0.template gradients<0, false, true>(scratch_data,
3448 eval0.template gradients<0, false, false>(scratch_data,
3453 eval1.template gradients<1, false, false>(hessians_quad +
3456 eval0.template values<0, false, true>(scratch_data,
3463 if (evaluation_flag &
3465 eval0.template hessians<0, false, true>(hessians_quad,
3468 eval0.template hessians<0, false, false>(hessians_quad,
3472 eval0.template values<0, false, false>(
3473 hessians_quad + n_q_points, values_dofs + 2 * dofs_stride);
3476 eval0.template gradients<0, false, true>(
3477 hessians_quad + 2 * n_q_points, values_dofs + dofs_stride);
3479 eval0.template gradients<0, false, false>(
3480 hessians_quad + 2 * n_q_points, values_dofs + dofs_stride);
3490 template <
int dim,
int fe_degree,
typename Number>
3496 template <
bool do_evaluate,
bool add_
into_output>
3501 const Number * input,
3503 const unsigned int face_no)
3505 Assert(
static_cast<unsigned int>(fe_degree) ==
3506 shape_info.
data.front().fe_degree ||
3510 interpolate_generic_raviart_thomas<do_evaluate, add_into_output>(
3511 n_components, input, output, flags, face_no, shape_info);
3513 interpolate_generic<do_evaluate, add_into_output>(
3519 shape_info.
data.front().fe_degree + 1,
3520 shape_info.
data.front().shape_data_on_face,
3528 template <
bool do_evaluate,
bool add_
into_output>
3531 const unsigned int n_components,
3534 const Number * input,
3536 const unsigned int face_no)
3538 Assert(
static_cast<unsigned int>(fe_degree + 1) ==
3539 shape_info.
data.front().n_q_points_1d ||
3543 interpolate_generic<do_evaluate, add_into_output>(
3549 shape_info.
data.front().quadrature.size(),
3550 shape_info.
data.front().quadrature_data_on_face,
3556 template <
bool do_evaluate,
bool add_
into_output,
int face_direction = 0>
3559 const Number * input,
3562 const unsigned int face_no,
3563 const unsigned int n_points_1d,
3565 const unsigned int dofs_per_component_on_cell,
3566 const unsigned int dofs_per_component_on_face)
3568 if (face_direction == face_no / 2)
3576 evalf(shape_data[face_no % 2].begin(),
3582 const unsigned int in_stride = do_evaluate ?
3583 dofs_per_component_on_cell :
3584 dofs_per_component_on_face;
3585 const unsigned int out_stride = do_evaluate ?
3586 dofs_per_component_on_face :
3587 dofs_per_component_on_cell;
3589 for (
unsigned int c = 0; c < n_components; ++c)
3592 evalf.template apply_face<face_direction,
3597 evalf.template apply_face<face_direction,
3602 evalf.template apply_face<face_direction,
3607 output += out_stride;
3610 else if (face_direction < dim)
3614 std::min(face_direction + 1, dim - 1)>(
3622 dofs_per_component_on_cell,
3623 dofs_per_component_on_face);
3627 template <
typename EvalType>
3631 const unsigned int face_no)
3636 template <
bool do_evaluate,
3637 bool add_into_output,
3638 int face_direction = 0,
3639 int max_derivative = 0>
3642 const unsigned int n_components,
3643 const Number * input,
3646 const unsigned int face_no,
3658 bool increase_max_der =
false;
3661 increase_max_der =
true;
3663 if (face_direction == face_no / 2 && !increase_max_der)
3669 shape_info, face_no, input, output);
3671 else if (face_direction == face_no / 2)
3678 n_components, input, output, flag, face_no, shape_info);
3680 else if (face_direction < dim)
3682 if (increase_max_der)
3687 std::min(face_direction + 1, dim - 1),
3689 n_components, input, output, flag, face_no, shape_info);
3698 n_components, input, output, flag, face_no, shape_info);
3704 template <
bool do_evaluate,
3705 bool add_into_output,
3711 const unsigned int face_no,
3712 const Number * input,
3718 using Evalf0 =
typename std::conditional<
3719 face_direction == 0,
3722 (fe_degree == -1) ? 1 : fe_degree + 1,
3729 (fe_degree == -1) ? 1 : fe_degree,
3734 using Evalf1 =
typename std::conditional<
3735 face_direction == 1,
3738 (fe_degree == -1) ? 1 : fe_degree + 1,
3745 (fe_degree == -1) ? 1 : fe_degree,
3750 using Evalf2 =
typename std::conditional<
3751 face_direction == 2,
3754 (fe_degree == -1) ? 1 : fe_degree + 1,
3761 (fe_degree == -1) ? 1 : fe_degree,
3768 create_evaluator_tensor_product<Evalf0>((face_direction == 0) ?
3769 shape_info.
data[0] :
3773 create_evaluator_tensor_product<Evalf1>((face_direction == 1) ?
3774 shape_info.
data[0] :
3778 create_evaluator_tensor_product<Evalf2>((face_direction == 2) ?
3779 shape_info.
data[0] :
3783 const unsigned int dofs_per_component_on_cell =
3785 const unsigned int dofs_per_component_on_face =
3791 const unsigned int in_stride =
3792 do_evaluate ? dofs_per_component_on_cell : dofs_per_component_on_face;
3793 const unsigned int out_stride =
3794 do_evaluate ? dofs_per_component_on_face : dofs_per_component_on_cell;
3796 const unsigned int in_stride_after_normal =
3798 dofs_per_component_on_cell :
3799 dofs_per_component_on_face - 3 *
Utilities::pow(fe_degree, dim - 2);
3800 const unsigned int out_stride_after_normal =
3802 dofs_per_component_on_face - 3 *
Utilities::pow(fe_degree, dim - 2) :
3803 dofs_per_component_on_cell;
3805 evalf0.template apply_face<face_direction,
3808 max_derivative>(input, output);
3810 input += (face_direction == 0) ? in_stride_after_normal : in_stride;
3811 output += (face_direction == 0) ? out_stride_after_normal : out_stride;
3813 evalf1.template apply_face<face_direction,
3816 max_derivative>(input, output);
3821 input += (face_direction == 1) ? in_stride_after_normal : in_stride;
3823 (face_direction == 1) ? out_stride_after_normal : out_stride;
3825 evalf2.template apply_face<face_direction,
3828 max_derivative>(input, output);
3836 template <
typename VectorizedArrayType,
typename Number2>
3840 for (
unsigned int v = 0; v < VectorizedArrayType::size(); ++v)
3841 dst[v] = src_ptr[v];
3848 template <
typename Number, std::
size_t w
idth>
3858 template <
typename VectorizedArrayType,
typename Number2>
3861 const unsigned int * indices,
3862 VectorizedArrayType &dst)
3864 for (
unsigned int v = 0; v < VectorizedArrayType::size(); ++v)
3865 dst[v] = src_ptr[indices[v]];
3872 template <
typename Number, std::
size_t w
idth>
3875 const unsigned int * indices,
3878 dst.
gather(src_ptr, indices);
3884 template <
typename VectorizedArrayType,
typename Number2>
3888 for (
unsigned int v = 0; v < VectorizedArrayType::size(); ++v)
3889 dst_ptr[v] += src[v];
3896 template <
typename Number, std::
size_t w
idth>
3902 (tmp + src).store(dst_ptr);
3908 template <
typename VectorizedArrayType,
typename Number2>
3911 const unsigned int * indices,
3914 for (
unsigned int v = 0; v < VectorizedArrayType::size(); ++v)
3915 dst_ptr[indices[v]] += src[v];
3922 template <
typename Number, std::
size_t w
idth>
3925 const unsigned int * indices,
3928#if DEAL_II_VECTORIZATION_WIDTH_IN_BITS < 512
3929 for (
unsigned int v = 0; v < width; ++v)
3930 dst_ptr[indices[v]] += src[v];
3933 tmp.
gather(dst_ptr, indices);
3934 (tmp + src).scatter(indices, dst_ptr);
3940 template <
typename Number>
3943 const unsigned int n_components,
3945 const unsigned int *orientation,
3946 const bool integrate,
3947 const std::size_t n_q_points,
3948 Number * tmp_values,
3949 Number * values_quad,
3950 Number * gradients_quad,
3951 Number * hessians_quad)
3953 for (
unsigned int c = 0; c < n_components; ++c)
3958 for (
unsigned int q = 0; q < n_q_points; ++q)
3959 tmp_values[q] = values_quad[c * n_q_points + orientation[q]];
3961 for (
unsigned int q = 0; q < n_q_points; ++q)
3962 tmp_values[orientation[q]] = values_quad[c * n_q_points + q];
3963 for (
unsigned int q = 0; q < n_q_points; ++q)
3964 values_quad[c * n_q_points + q] = tmp_values[q];
3967 for (
unsigned int d = 0; d < dim; ++d)
3970 for (
unsigned int q = 0; q < n_q_points; ++q)
3972 gradients_quad[(c * dim + d) * n_q_points + orientation[q]];
3974 for (
unsigned int q = 0; q < n_q_points; ++q)
3975 tmp_values[orientation[q]] =
3976 gradients_quad[(c * dim + d) * n_q_points + q];
3977 for (
unsigned int q = 0; q < n_q_points; ++q)
3978 gradients_quad[(c * dim + d) * n_q_points + q] = tmp_values[q];
3982 const unsigned int hdim = (dim * (dim + 1)) / 2;
3983 for (
unsigned int d = 0; d < hdim; ++d)
3986 for (
unsigned int q = 0; q < n_q_points; ++q)
3987 tmp_values[q] = hessians_quad[(c * hdim + d) * n_q_points +
3990 for (
unsigned int q = 0; q < n_q_points; ++q)
3991 tmp_values[orientation[q]] =
3992 hessians_quad[(c * hdim + d) * n_q_points + q];
3993 for (
unsigned int q = 0; q < n_q_points; ++q)
3994 hessians_quad[(c * hdim + d) * n_q_points + q] =
4003 template <
typename Number,
typename VectorizedArrayType>
4006 const unsigned int dim,
4007 const unsigned int n_components,
4008 const unsigned int v,
4010 const unsigned int * orientation,
4011 const bool integrate,
4012 const std::size_t n_q_points,
4013 Number * tmp_values,
4014 VectorizedArrayType * values_quad,
4015 VectorizedArrayType * gradients_quad =
nullptr,
4016 VectorizedArrayType * hessians_quad =
nullptr)
4018 for (
unsigned int c = 0; c < n_components; ++c)
4023 for (
unsigned int q = 0; q < n_q_points; ++q)
4024 tmp_values[q] = values_quad[c * n_q_points + orientation[q]][v];
4026 for (
unsigned int q = 0; q < n_q_points; ++q)
4027 tmp_values[orientation[q]] = values_quad[c * n_q_points + q][v];
4028 for (
unsigned int q = 0; q < n_q_points; ++q)
4029 values_quad[c * n_q_points + q][v] = tmp_values[q];
4032 for (
unsigned int d = 0; d < dim; ++d)
4036 for (
unsigned int q = 0; q < n_q_points; ++q)
4037 tmp_values[q] = gradients_quad[(c * dim + d) * n_q_points +
4040 for (
unsigned int q = 0; q < n_q_points; ++q)
4041 tmp_values[orientation[q]] =
4042 gradients_quad[(c * dim + d) * n_q_points + q][v];
4043 for (
unsigned int q = 0; q < n_q_points; ++q)
4044 gradients_quad[(c * dim + d) * n_q_points + q][v] =
4050 const unsigned int hdim = (dim * (dim + 1)) / 2;
4051 for (
unsigned int d = 0; d < hdim; ++d)
4054 for (
unsigned int q = 0; q < n_q_points; ++q)
4055 tmp_values[q] = hessians_quad[(c * hdim + d) * n_q_points +
4058 for (
unsigned int q = 0; q < n_q_points; ++q)
4059 tmp_values[orientation[q]] =
4060 hessians_quad[(c * hdim + d) * n_q_points + q][v];
4061 for (
unsigned int q = 0; q < n_q_points; ++q)
4062 hessians_quad[(c * hdim + d) * n_q_points + q][v] =
4071 template <
int dim,
typename Number>
4074 template <
int fe_degree,
int n_q_po
ints_1d>
4076 run(
const unsigned int n_components,
4078 const Number * values_dofs,
4082 const auto &shape_data = shape_info.
data.front();
4093 const unsigned int face_no = fe_eval.
get_face_no();
4095 const std::size_t n_dofs = shape_info.dofs_per_component_on_cell;
4096 const std::size_t n_q_points = shape_info.n_q_points_faces[face_no];
4103 const auto shape_values =
4104 &shape_data.shape_values_face(face_no, face_orientation, 0);
4107 auto values_dofs_actual_ptr = values_dofs;
4109 Eval eval(shape_values,
nullptr,
nullptr, n_dofs, n_q_points);
4110 for (
unsigned int c = 0; c < n_components; ++c)
4112 eval.template values<0, true, false>(values_dofs_actual_ptr,
4115 values_quad_ptr += n_q_points;
4116 values_dofs_actual_ptr += n_dofs;
4123 auto values_dofs_actual_ptr = values_dofs;
4125 std::array<const Number2 *, dim> shape_gradients;
4126 for (
unsigned int d = 0; d < dim; ++d)
4127 shape_gradients[d] = &shape_data.shape_gradients_face(
4128 face_no, face_orientation, d, 0);
4130 for (
unsigned int c = 0; c < n_components; ++c)
4132 for (
unsigned int d = 0; d < dim; ++d)
4140 eval.template gradients<0, true, false>(
4141 values_dofs_actual_ptr, gradients_quad_ptr);
4143 gradients_quad_ptr += n_q_points;
4145 values_dofs_actual_ptr += n_dofs;
4155 const unsigned int dofs_per_face =
4162 Number *scratch_data = temp + 3 * n_components * dofs_per_face;
4164 bool use_vectorization =
true;
4169 for (
unsigned int v = 0; v < Number::size(); ++v)
4172 use_vectorization =
false;
4174 if (use_vectorization ==
false)
4176 for (
unsigned int v = 0; v < Number::size(); ++v)
4183 for (
unsigned int i = 0; i < 3 * n_components * dofs_per_face;
4190 template interpolate<true, false>(n_components,
4197 for (
unsigned int i = 0; i < 3 * n_components * dofs_per_face;
4199 temp[i][v] = scratch_data[i][v];
4204 template interpolate<true, false>(n_components,
4212 constexpr unsigned int n_q_points_1d_actual =
4213 fe_degree > -1 ? n_q_points_1d : 0;
4215 if (fe_degree >= 1 &&
4219 (fe_degree == -1) ? 1 : fe_degree,
4220 (n_q_points_1d < 1) ? 1 :
4223 template evaluate_or_integrate_in_face<false>(
4231 else if (fe_degree > -1 &&
4237 n_q_points_1d_actual,
4238 Number>::evaluate_in_face(n_components,
4252 n_q_points_1d_actual,
4253 Number>::evaluate_in_face(n_components,
4264 if (use_vectorization ==
false)
4266 for (
unsigned int v = 0; v < Number::size(); ++v)
4283 shape_info.n_q_points_face,
4298 shape_info.n_q_points_face,
4310 template <
int dim,
typename Number>
4313 template <
int fe_degree,
int n_q_po
ints_1d>
4315 run(
const unsigned int n_components,
4317 Number * values_dofs,
4321 const auto &shape_data = shape_info.
data.front();
4332 const unsigned int face_no = fe_eval.
get_face_no();
4334 const std::size_t n_dofs = shape_info.dofs_per_component_on_cell;
4335 const std::size_t n_q_points = shape_info.n_q_points_faces[face_no];
4342 const auto shape_values =
4343 &shape_data.shape_values_face(face_no, face_orientation, 0);
4346 auto values_dofs_actual_ptr = values_dofs;
4348 Eval eval(shape_values,
nullptr,
nullptr, n_dofs, n_q_points);
4349 for (
unsigned int c = 0; c < n_components; ++c)
4351 eval.template values<0, false, false>(values_quad_ptr,
4352 values_dofs_actual_ptr);
4354 values_quad_ptr += n_q_points;
4355 values_dofs_actual_ptr += n_dofs;
4362 auto values_dofs_actual_ptr = values_dofs;
4364 std::array<const Number2 *, dim> shape_gradients;
4365 for (
unsigned int d = 0; d < dim; ++d)
4366 shape_gradients[d] = &shape_data.shape_gradients_face(
4367 face_no, face_orientation, d, 0);
4369 for (
unsigned int c = 0; c < n_components; ++c)
4371 for (
unsigned int d = 0; d < dim; ++d)
4381 eval.template gradients<0, false, false>(
4382 gradients_quad_ptr, values_dofs_actual_ptr);
4384 eval.template gradients<0, false, true>(
4385 gradients_quad_ptr, values_dofs_actual_ptr);
4387 gradients_quad_ptr += n_q_points;
4389 values_dofs_actual_ptr += n_dofs;
4399 const unsigned int dofs_per_face =
4404 Number *scratch_data = temp + 3 * n_components * dofs_per_face;
4406 bool use_vectorization =
true;
4415 [&](
const auto &v) {
4416 return v == fe_eval.get_cell_ids()[0] ||
4417 v == numbers::invalid_unsigned_int;
4420 if (use_vectorization ==
false)
4422 for (
unsigned int v = 0; v < Number::size(); ++v)
4439 shape_info.n_q_points_face,
4454 shape_info.n_q_points_face,
4460 const unsigned int n_q_points_1d_actual =
4461 fe_degree > -1 ? n_q_points_1d : 0;
4464 if (fe_degree >= 1 &&
4468 (fe_degree == -1) ? 1 : fe_degree,
4469 (n_q_points_1d < 1) ? 1 :
4472 template evaluate_or_integrate_in_face<true>(integration_flag,
4479 else if (fe_degree > -1 &&
4487 n_q_points_1d_actual,
4488 Number>::integrate_in_face(n_components,
4502 n_q_points_1d_actual,
4503 Number>::integrate_in_face(n_components,
4513 if (use_vectorization ==
false)
4515 for (
unsigned int v = 0; v < Number::size(); ++v)
4524 template interpolate<false, false>(n_components,
4531 for (
unsigned int i = 0; i < 3 * n_components * dofs_per_face;
4533 temp[i][v] = scratch_data[i][v];
4538 template interpolate<false, false>(n_components,
4550 template <
int n_face_orientations,
4552 typename EvaluationData,
4553 const bool check_face_orientations =
false>
4557 const unsigned int n_components,
4559 typename Processor::Number2_ * global_vector_ptr,
4561 const EvaluationData & fe_eval,
4562 typename Processor::VectorizedArrayType_ * temp1)
4564 constexpr int dim = Processor::dim_;
4565 constexpr int fe_degree = Processor::fe_degree_;
4566 using VectorizedArrayType =
typename Processor::VectorizedArrayType_;
4567 constexpr int n_lanes = VectorizedArrayType::size();
4569 using Number =
typename Processor::Number_;
4570 using Number2_ =
typename Processor::Number2_;
4572 const auto & shape_data = fe_eval.get_shape_info().data.front();
4573 constexpr bool integrate = Processor::do_integrate;
4574 const unsigned int face_no = fe_eval.get_face_no();
4575 const auto & dof_info = fe_eval.get_dof_info();
4576 const unsigned int cell = fe_eval.get_cell_or_face_batch_id();
4578 fe_eval.get_dof_access_index();
4580 dof_info.index_storage_variants[dof_access_index].size());
4581 constexpr unsigned int dofs_per_face =
4583 const unsigned int subface_index = fe_eval.get_subface_index();
4585 const unsigned int n_filled_lanes =
4586 dof_info.n_vectorization_lanes_filled[dof_access_index][cell];
4588 bool all_faces_are_same = n_filled_lanes == n_lanes;
4589 if (n_face_orientations == n_lanes)
4590 for (
unsigned int v = 1; v < n_lanes; ++v)
4591 if (fe_eval.get_face_no(v) != fe_eval.get_face_no(0) ||
4592 fe_eval.get_face_orientation(v) != fe_eval.get_face_orientation(0))
4594 all_faces_are_same =
false;
4599 std::array<const unsigned int *, n_face_orientations> orientation = {};
4601 if (dim == 3 && n_face_orientations == n_lanes && !all_faces_are_same &&
4602 fe_eval.is_interior_face() == 0)
4603 for (
unsigned int v = 0; v < n_lanes; ++v)
4611 if (shape_data.nodal_at_cell_boundaries &&
4612 fe_eval.get_face_orientation(v) != 0)
4617 check_face_orientations ==
false)
4631 orientation[v] = &fe_eval.get_shape_info().face_orientations_dofs(
4632 fe_eval.get_face_orientation(v), 0);
4635 else if (dim == 3 && fe_eval.get_face_orientation() != 0)
4639 check_face_orientations ==
false)
4653 for (
unsigned int v = 0; v < n_face_orientations; ++v)
4654 orientation[v] = &fe_eval.get_shape_info().face_orientations_dofs(
4655 fe_eval.get_face_orientation(), 0);
4661 VectorizedArrayType grad_weight =
4663 .shape_data_on_face[0][fe_degree + (integrate ? (2 - face_no % 2) :
4664 (1 + face_no % 2))];
4667 std::array<const unsigned int *, n_face_orientations> index_array_hermite =
4671 if (n_face_orientations == 1)
4672 index_array_hermite[0] =
4673 &fe_eval.get_shape_info().face_to_cell_index_hermite(face_no, 0);
4676 for (
unsigned int v = 0; v < n_lanes; ++v)
4681 const auto face_no = fe_eval.get_face_no(v);
4684 shape_data.shape_data_on_face[0][fe_degree +
4686 (2 - (face_no % 2)) :
4687 (1 + (face_no % 2)))][0];
4689 index_array_hermite[v] =
4690 &fe_eval.get_shape_info().face_to_cell_index_hermite(face_no,
4697 std::array<const unsigned int *, n_face_orientations> index_array_nodal =
4699 if (shape_data.nodal_at_cell_boundaries ==
true)
4701 if (n_face_orientations == 1)
4702 index_array_nodal[0] =
4703 &fe_eval.get_shape_info().face_to_cell_index_nodal(face_no, 0);
4706 for (
unsigned int v = 0; v < n_lanes; ++v)
4711 const auto face_no = fe_eval.get_face_no(v);
4713 index_array_nodal[v] =
4714 &fe_eval.get_shape_info().face_to_cell_index_nodal(face_no,
4721 const auto reorientate = [&](
const unsigned int v,
const unsigned int i) {
4722 return (!check_face_orientations || orientation[v] ==
nullptr) ?
4729 fe_eval.get_cell_ids()[0] :
4731 const unsigned int *dof_indices =
4732 &dof_info.dof_indices_contiguous[dof_access_index][
cell_index];
4734 for (
unsigned int comp = 0; comp < n_components; ++comp)
4736 const std::size_t index_offset =
4737 dof_info.component_dof_indices_offset
4738 [fe_eval.get_active_fe_index()]
4739 [fe_eval.get_first_selected_component()] +
4743 if (n_face_orientations == 1 &&
4744 dof_info.index_storage_variants[dof_access_index][cell] ==
4746 interleaved_contiguous)
4749 dof_info.n_vectorization_lanes_filled[dof_access_index][cell],
4751 Number2_ *vector_ptr =
4752 global_vector_ptr + dof_indices[0] + index_offset * n_lanes;
4756 for (
unsigned int i = 0; i < dofs_per_face; ++i)
4760 const unsigned int ind1 = index_array_hermite[0][2 * i];
4761 const unsigned int ind2 = index_array_hermite[0][2 * i + 1];
4762 const unsigned int i_ = reorientate(0, i);
4763 proc.hermite_grad_vectorized(temp1[i_],
4764 temp1[i_ + dofs_per_face],
4765 vector_ptr + ind1 * n_lanes,
4766 vector_ptr + ind2 * n_lanes,
4772 for (
unsigned int i = 0; i < dofs_per_face; ++i)
4776 const unsigned int i_ = reorientate(0, i);
4777 const unsigned int ind = index_array_nodal[0][i];
4778 proc.value_vectorized(temp1[i_],
4779 vector_ptr + ind * n_lanes);
4785 else if (n_face_orientations == 1 &&
4786 dof_info.index_storage_variants[dof_access_index][cell] ==
4788 interleaved_contiguous_strided)
4791 dof_info.n_vectorization_lanes_filled[dof_access_index][cell],
4793 Number2_ *vector_ptr = global_vector_ptr + index_offset * n_lanes;
4796 for (
unsigned int i = 0; i < dofs_per_face; ++i)
4800 const unsigned int i_ = reorientate(0, i);
4801 const unsigned int ind1 =
4802 index_array_hermite[0][2 * i] * n_lanes;
4803 const unsigned int ind2 =
4804 index_array_hermite[0][2 * i + 1] * n_lanes;
4805 proc.hermite_grad_vectorized_indexed(
4807 temp1[i_ + dofs_per_face],
4817 for (
unsigned int i = 0; i < dofs_per_face; ++i)
4821 const unsigned int i_ = reorientate(0, i);
4822 const unsigned int ind = index_array_nodal[0][i] * n_lanes;
4823 proc.value_vectorized_indexed(temp1[i_],
4831 else if (n_face_orientations == 1 &&
4832 dof_info.index_storage_variants[dof_access_index][cell] ==
4834 interleaved_contiguous_mixed_strides)
4836 const unsigned int *strides =
4837 &dof_info.dof_indices_interleave_strides[dof_access_index]
4839 unsigned int indices[n_lanes];
4840 for (
unsigned int v = 0; v < n_lanes; ++v)
4841 indices[v] = dof_indices[v] + index_offset * strides[v];
4842 const unsigned int n_filled_lanes =
4843 dof_info.n_vectorization_lanes_filled[dof_access_index][cell];
4847 if (n_filled_lanes == n_lanes)
4848 for (
unsigned int i = 0; i < dofs_per_face; ++i)
4852 const unsigned int i_ = reorientate(0, i);
4853 unsigned int ind1[n_lanes];
4855 for (
unsigned int v = 0; v < n_lanes; ++v)
4856 ind1[v] = indices[v] +
4857 index_array_hermite[0][2 * i] * strides[v];
4858 unsigned int ind2[n_lanes];
4860 for (
unsigned int v = 0; v < n_lanes; ++v)
4864 index_array_hermite[0][2 * i + 1] * strides[v];
4865 proc.hermite_grad_vectorized_indexed(
4867 temp1[i_ + dofs_per_face],
4876 if (integrate ==
false)
4877 for (
unsigned int i = 0; i < 2 * dofs_per_face; ++i)
4878 temp1[i] = VectorizedArrayType();
4880 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
4881 for (
unsigned int i = 0; i < dofs_per_face; ++i)
4883 const unsigned int i_ =
4884 reorientate(n_face_orientations == 1 ? 0 : v, i);
4887 temp1[i_ + dofs_per_face][v],
4891 [n_face_orientations == 1 ? 0 : v][2 * i] *
4895 index_array_hermite[n_face_orientations == 1 ?
4899 grad_weight[n_face_orientations == 1 ? 0 : v]);
4905 if (n_filled_lanes == n_lanes)
4906 for (
unsigned int i = 0; i < dofs_per_face; ++i)
4909 unsigned int ind[n_lanes];
4911 for (
unsigned int v = 0; v < n_lanes; ++v)
4913 indices[v] + index_array_nodal[0][i] * strides[v];
4914 const unsigned int i_ = reorientate(0, i);
4915 proc.value_vectorized_indexed(temp1[i_],
4921 if (integrate ==
false)
4922 for (
unsigned int i = 0; i < dofs_per_face; ++i)
4923 temp1[i] = VectorizedArrayType();
4925 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
4926 for (
unsigned int i = 0; i < dofs_per_face; ++i)
4928 temp1[reorientate(n_face_orientations == 1 ? 0 : v,
4932 index_array_nodal[n_face_orientations == 1 ? 0 : v]
4940 else if (n_face_orientations > 1 ||
4941 dof_info.index_storage_variants[dof_access_index][cell] ==
4945 Number2_ *vector_ptr = global_vector_ptr + index_offset;
4947 const bool vectorization_possible =
4948 all_faces_are_same && (sm_ptr ==
nullptr);
4950 std::array<Number2_ *, n_lanes> vector_ptrs;
4951 std::array<unsigned int, n_lanes> reordered_indices;
4953 if (vectorization_possible ==
false)
4956 if (n_face_orientations == 1)
4958 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
4959 if (sm_ptr ==
nullptr)
4961 vector_ptrs[v] = vector_ptr + dof_indices[v];
4967 .dof_indices_contiguous_sm[dof_access_index]
4968 [cell * n_lanes + v];
4969 vector_ptrs[v] =
const_cast<Number2_ *
>(
4970 sm_ptr->operator[](temp.first).data() +
4971 temp.second + index_offset);
4974 else if (n_face_orientations == n_lanes)
4976 const auto &cells = fe_eval.get_cell_ids();
4977 for (
unsigned int v = 0; v < n_lanes; ++v)
4980 if (sm_ptr ==
nullptr)
4985 .dof_indices_contiguous[dof_access_index]
4992 .dof_indices_contiguous_sm[dof_access_index]
4994 vector_ptrs[v] =
const_cast<Number2_ *
>(
4995 sm_ptr->operator[](temp.first).data() +
4996 temp.second + index_offset);
5005 else if (n_face_orientations == n_lanes)
5007 for (
unsigned int v = 0; v < n_lanes; ++v)
5008 reordered_indices[v] =
5009 dof_info.dof_indices_contiguous[dof_access_index]
5010 [fe_eval.get_cell_ids()[v]];
5011 dof_indices = reordered_indices.data();
5016 if (vectorization_possible)
5017 for (
unsigned int i = 0; i < dofs_per_face; ++i)
5019 const unsigned int ind1 = index_array_hermite[0][2 * i];
5020 const unsigned int ind2 =
5021 index_array_hermite[0][2 * i + 1];
5022 const unsigned int i_ = reorientate(0, i);
5024 proc.hermite_grad_vectorized_indexed(
5026 temp1[i_ + dofs_per_face],
5033 else if (n_face_orientations == 1)
5034 for (
unsigned int i = 0; i < dofs_per_face; ++i)
5036 const unsigned int ind1 = index_array_hermite[0][2 * i];
5037 const unsigned int ind2 =
5038 index_array_hermite[0][2 * i + 1];
5039 const unsigned int i_ = reorientate(0, i);
5041 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
5042 proc.hermite_grad(temp1[i_][v],
5043 temp1[i_ + dofs_per_face][v],
5044 vector_ptrs[v][ind1],
5045 vector_ptrs[v][ind2],
5048 if (integrate ==
false)
5049 for (
unsigned int v = n_filled_lanes; v < n_lanes; ++v)
5052 temp1[i + dofs_per_face][v] = 0.0;
5057 if (integrate ==
false && n_filled_lanes < n_lanes)
5058 for (
unsigned int i = 0; i < dofs_per_face; ++i)
5059 temp1[i] = temp1[i + dofs_per_face] = Number();
5061 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
5062 for (
unsigned int i = 0; i < dofs_per_face; ++i)
5064 temp1[reorientate(v, i)][v],
5065 temp1[reorientate(v, i) + dofs_per_face][v],
5066 vector_ptrs[v][index_array_hermite[v][2 * i]],
5067 vector_ptrs[v][index_array_hermite[v][2 * i + 1]],
5073 if (vectorization_possible)
5074 for (
unsigned int i = 0; i < dofs_per_face; ++i)
5076 const unsigned int ind = index_array_nodal[0][i];
5077 const unsigned int i_ = reorientate(0, i);
5079 proc.value_vectorized_indexed(temp1[i_],
5083 else if (n_face_orientations == 1)
5084 for (
unsigned int i = 0; i < dofs_per_face; ++i)
5086 const unsigned int ind = index_array_nodal[0][i];
5087 const unsigned int i_ = reorientate(0, i);
5089 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
5090 proc.value(temp1[i_][v], vector_ptrs[v][ind]);
5092 if (integrate ==
false)
5093 for (
unsigned int v = n_filled_lanes; v < n_lanes; ++v)
5098 if (integrate ==
false && n_filled_lanes < n_lanes)
5099 for (
unsigned int i = 0; i < dofs_per_face; ++i)
5100 temp1[i] = Number();
5102 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
5103 for (
unsigned int i = 0; i < dofs_per_face; ++i)
5104 proc.value(temp1[reorientate(v, i)][v],
5105 vector_ptrs[v][index_array_nodal[v][i]]);
5115 temp1 += 3 * dofs_per_face;
5121 template <
int dim,
typename Number2,
typename VectorizedArrayType>
5124 using Number =
typename VectorizedArrayType::value_type;
5126 template <
int fe_degree,
int n_q_po
ints_1d>
5128 run(
const unsigned int n_components,
5130 const Number2 * src_ptr,
5139 const unsigned int dofs_per_face =
Utilities::pow(fe_degree + 1, dim - 1);
5142 VectorizedArrayType *scratch_data =
5143 temp + 3 * n_components * dofs_per_face;
5150 fe_face_evaluation_process_and_io<VectorizedArrayType::size()>(
5151 p, n_components, evaluation_flag, src_ptr, sm_ptr, fe_eval, temp);
5153 fe_face_evaluation_process_and_io<1>(
5154 p, n_components, evaluation_flag, src_ptr, sm_ptr, fe_eval, temp);
5163 VectorizedArrayType>::
5164 evaluate_in_face(n_components,
5178 VectorizedArrayType>::
5179 evaluate_in_face(n_components,
5196 for (
unsigned int v = 0; v < VectorizedArrayType::size(); ++v)
5239 template <
typename Number3>
5243 const Number2 * vector_ptr,
5246 const unsigned int fe_degree = shape_info.
data.front().fe_degree;
5247 if (fe_degree < 1 || !shape_info.
data.front().nodal_at_cell_boundaries ||
5250 shape_info.
data.front().element_type !=
5253 vector_ptr ==
nullptr ||
5254 shape_info.
data.front().element_type >
5264 template <
int fe_degree>
5274 template <
typename T0,
typename T1,
typename T2>
5280 const T2 &grad_weight)
5284 temp_2 = grad_weight * (temp_1 - temp_2);
5287 template <
typename T1,
typename T2>
5294 template <
typename T0,
typename T1,
typename T2,
typename T3>
5300 const T2 &grad_weight,
5301 const T3 &indices_1,
5302 const T3 &indices_2)
5306 temp_2 = grad_weight * (temp_1 - temp_2);
5309 template <
typename T0,
typename T1,
typename T2>
5316 template <
typename T0,
typename T1,
typename T2>
5320 const T1 &src_ptr_1,
5321 const T1 &src_ptr_2,
5322 const T2 &grad_weight)
5326 temp_2 = grad_weight * (temp_1 - src_ptr_2);
5329 template <
typename T1,
typename T2>
5341 template <
int dim,
typename Number2,
typename VectorizedArrayType>
5344 using Number =
typename VectorizedArrayType::value_type;
5346 template <
int fe_degree,
int n_q_po
ints_1d>
5348 run(
const unsigned int n_components,
5359 const unsigned int dofs_per_face =
Utilities::pow(fe_degree + 1, dim - 1);
5362 VectorizedArrayType *scratch_data =
5363 temp + 3 * n_components * dofs_per_face;
5373 for (
unsigned int v = 0; v < VectorizedArrayType::size(); ++v)
5417 VectorizedArrayType>::
5418 integrate_in_face(n_components,
5432 VectorizedArrayType>::
5433 integrate_in_face(n_components,
5448 fe_face_evaluation_process_and_io<VectorizedArrayType::size()>(
5449 p, n_components, integration_flag, dst_ptr, sm_ptr, fe_eval, temp);
5451 fe_face_evaluation_process_and_io<1>(
5452 p, n_components, integration_flag, dst_ptr, sm_ptr, fe_eval, temp);
5458 template <
int fe_degree>
5468 template <
typename T0,
typename T1,
typename T2,
typename T3,
typename T4>
5474 const T4 &grad_weight)
5477 const VectorizedArrayType val = temp_1 - grad_weight * temp_2;
5478 const VectorizedArrayType grad = grad_weight * temp_2;
5483 template <
typename T0,
typename T1>
5491 template <
typename T0,
typename T1,
typename T2,
typename T3>
5497 const T2 &grad_weight,
5498 const T3 &indices_1,
5499 const T3 &indices_2)
5502 const VectorizedArrayType val = temp_1 - grad_weight * temp_2;
5503 const VectorizedArrayType grad = grad_weight * temp_2;
5508 template <
typename T0,
typename T1,
typename T2>
5516 template <
typename T0,
typename T1,
typename T2>
5522 const T2 &grad_weight)
5525 const Number val = temp_1 - grad_weight * temp_2;
5526 const Number grad = grad_weight * temp_2;
5531 template <
typename T0,
typename T1>
5547 template <
int dim,
typename Number>
5553 template <
int fe_degree,
int = 0>
5555 run(
const unsigned int n_components,
5557 const Number * in_array,
5560 const unsigned int given_degree =
5561 (fe_degree > -1) ? fe_degree :
5564 const unsigned int dofs_per_component =
5584 for (
unsigned int d = 0; d < n_components; ++d)
5586 const Number *in = in_array + d * dofs_per_component;
5587 Number * out = out_array + d * dofs_per_component;
5590 evaluator.template hessians<0, true, false>(in, out);
5592 evaluator.template hessians<1, true, false>(out, out);
5594 evaluator.template hessians<2, true, false>(out, out);
5596 for (
unsigned int q = 0; q < dofs_per_component; ++q)
5598 const Number inverse_JxW_q = Number(1.) / fe_eval.
JxW(q);
5599 for (
unsigned int d = 0; d < n_components; ++d)
5600 out_array[q + d * dofs_per_component] *= inverse_JxW_q;
5602 for (
unsigned int d = 0; d < n_components; ++d)
5604 Number *out = out_array + d * dofs_per_component;
5606 evaluator.template hessians<2, false, false>(out, out);
5608 evaluator.template hessians<1, false, false>(out, out);
5609 evaluator.template hessians<0, false, false>(out, out);
5623 template <
int dim,
typename Number>
5629 template <
int fe_degree,
int = 0>
5631 run(
const unsigned int n_desired_components,
5634 const bool dyadic_coefficients,
5635 const Number * in_array,
5638 const unsigned int given_degree =
5639 (fe_degree > -1) ? fe_degree :
5642 const unsigned int dofs_per_component =
5646 inverse_coefficients.
size() % dofs_per_component == 0,
5648 "Expected diagonal to be a multiple of scalar dof per cells"));
5650 if (!dyadic_coefficients)
5652 if (inverse_coefficients.
size() != dofs_per_component)
5654 inverse_coefficients.
size());
5660 inverse_coefficients.
size());
5680 const Number *in = in_array;
5681 Number * out = out_array;
5683 const Number *inv_coefficient = inverse_coefficients.
data();
5685 const unsigned int shift_coefficient =
5686 inverse_coefficients.
size() > dofs_per_component ? dofs_per_component :
5689 const auto n_comp_outer = dyadic_coefficients ? 1 : n_desired_components;
5690 const auto n_comp_inner = dyadic_coefficients ? n_desired_components : 1;
5692 for (
unsigned int d = 0; d < n_comp_outer; ++d)
5694 for (
unsigned int di = 0; di < n_comp_inner; ++di)
5696 const Number *in_ = in + di * dofs_per_component;
5697 Number * out_ = out + di * dofs_per_component;
5698 evaluator.template hessians<0, true, false>(in_, out_);
5700 evaluator.template hessians<1, true, false>(out_, out_);
5702 evaluator.template hessians<2, true, false>(out_, out_);
5704 if (dyadic_coefficients)
5706 const auto n_coeff_components =
5707 n_desired_components * n_desired_components;
5708 if (n_desired_components == dim)
5710 for (
unsigned int q = 0; q < dofs_per_component; ++q)
5711 vmult<dim>(&inv_coefficient[q * n_coeff_components],
5714 dofs_per_component);
5718 for (
unsigned int q = 0; q < dofs_per_component; ++q)
5719 vmult<-1>(&inv_coefficient[q * n_coeff_components],
5723 n_desired_components);
5727 for (
unsigned int q = 0; q < dofs_per_component; ++q)
5728 out[q] *= inv_coefficient[q];
5730 for (
unsigned int di = 0; di < n_comp_inner; ++di)
5732 Number *out_ = out + di * dofs_per_component;
5734 evaluator.template hessians<2, false, false>(out_, out_);
5736 evaluator.template hessians<1, false, false>(out_, out_);
5737 evaluator.template hessians<0, false, false>(out_, out_);
5740 in += dofs_per_component;
5741 out += dofs_per_component;
5742 inv_coefficient += shift_coefficient;
5749 template <
int n_components>
5751 vmult(
const Number * inverse_coefficients,
5754 const unsigned int dofs_per_component,
5755 const unsigned int n_given_components = 0)
5757 const unsigned int n_desired_components =
5758 (n_components > -1) ? n_components : n_given_components;
5760 std::array<Number, dim + 2> tmp = {};
5761 Assert(n_desired_components <= dim + 2,
5763 "Number of components larger than dim+2 not supported."));
5765 for (
unsigned int d = 0; d < n_desired_components; ++d)
5766 tmp[d] = src[d * dofs_per_component];
5768 for (
unsigned int d1 = 0; d1 < n_desired_components; ++d1)
5770 const Number *inv_coeff_row =
5771 &inverse_coefficients[d1 * n_desired_components];
5772 Number sum = inv_coeff_row[0] * tmp[0];
5773 for (
unsigned int d2 = 1; d2 < n_desired_components; ++d2)
5774 sum += inv_coeff_row[d2] * tmp[d2];
5775 dst[d1 * dofs_per_component] = sum;
5788 template <
int dim,
typename Number>
5791 template <
int fe_degree,
int n_q_po
ints_1d>
5793 run(
const unsigned int n_desired_components,
5795 const Number * in_array,
5798 static const bool do_inplace =
5799 fe_degree > -1 && (fe_degree + 1 == n_q_points_1d);
5805 const auto &inverse_shape =
5810 const std::size_t dofs_per_component =
5813 const std::size_t n_q_points = do_inplace ?
5831 for (
unsigned int d = 0; d < n_desired_components; ++d)
5833 const Number *in = in_array + d * n_q_points;
5834 Number * out = out_array + d * dofs_per_component;
5837 auto temp_2 = do_inplace ?
5839 (temp_1 +
std::max(n_q_points, dofs_per_component));
5843 evaluator.template hessians<2, false, false>(in, temp_1);
5844 evaluator.template hessians<1, false, false>(temp_1, temp_2);
5845 evaluator.template hessians<0, false, false>(temp_2, out);
5849 evaluator.template hessians<1, false, false>(in, temp_1);
5850 evaluator.template hessians<0, false, false>(temp_1, out);
5853 evaluator.template hessians<0, false, false>(in, out);
5866 template <
int fe_degree,
int n_q_po
ints_1d>
5870 return fe_degree != -1;
value_type * data() const noexcept
std::uint8_t get_face_no(const unsigned int v=0) const
internal::MatrixFreeFunctions::DoFInfo::DoFAccessIndex get_dof_access_index() const
const ShapeInfoType & get_shape_info() const
Number JxW(const unsigned int q_point) const
const std::array< unsigned int, n_lanes > & get_cell_ids() const
const Number * begin_gradients() const
unsigned int get_subface_index() const
Number shape_info_number_type
bool is_interior_face() const
ArrayView< Number > get_scratch_data() const
const Number * begin_values() const
std::uint8_t get_face_orientation(const unsigned int v=0) const
const Number * begin_hessians() const
void gather(const Number *base_ptr, const unsigned int *offsets)
void load(const OtherNumber *ptr)
#define DEAL_II_ALWAYS_INLINE
#define DEAL_II_OPENMP_SIMD_PRAGMA
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
static ::ExceptionBase & ExcNotImplemented()
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
@ tensor_symmetric_no_collocation
@ tensor_symmetric_plus_dg0
@ tensor_symmetric_hermite
EvaluationFlags
The EvaluationFlags enum.
constexpr T pow(const T base, const int iexp)
void do_vectorized_add(const VectorizedArrayType src, Number2 *dst_ptr)
constexpr bool use_collocation_evaluation(const unsigned int fe_degree, const unsigned int n_q_points_1d)
void adjust_for_face_orientation_per_lane(const unsigned int dim, const unsigned int n_components, const unsigned int v, const EvaluationFlags::EvaluationFlags flag, const unsigned int *orientation, const bool integrate, const std::size_t n_q_points, Number *tmp_values, VectorizedArrayType *values_quad, VectorizedArrayType *gradients_quad=nullptr, VectorizedArrayType *hessians_quad=nullptr)
void fe_face_evaluation_process_and_io(Processor &proc, const unsigned int n_components, const EvaluationFlags::EvaluationFlags evaluation_flag, typename Processor::Number2_ *global_vector_ptr, const std::vector< ArrayView< const typename Processor::Number2_ > > *sm_ptr, const EvaluationData &fe_eval, typename Processor::VectorizedArrayType_ *temp1)
void do_vectorized_scatter_add(const VectorizedArrayType src, const unsigned int *indices, Number2 *dst_ptr)
void do_vectorized_gather(const Number2 *src_ptr, const unsigned int *indices, VectorizedArrayType &dst)
void do_vectorized_read(const Number2 *src_ptr, VectorizedArrayType &dst)
void adjust_for_face_orientation(const unsigned int dim, const unsigned int n_components, const EvaluationFlags::EvaluationFlags flag, const unsigned int *orientation, const bool integrate, const std::size_t n_q_points, Number *tmp_values, Number *values_quad, Number *gradients_quad, Number *hessians_quad)
@ evaluate_raviart_thomas
static const unsigned int invalid_unsigned_int
::VectorizedArray< Number, width > min(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > max(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
typename FEEvaluationData< dim, Number, false >::shape_info_number_type Number2
static bool run(const unsigned int n_components, const FEEvaluationData< dim, Number, false > &fe_eval, const Number *in_array, Number *out_array)
typename FEEvaluationData< dim, Number, false >::shape_info_number_type Number2
static bool run(const unsigned int n_desired_components, const FEEvaluationData< dim, Number, false > &fe_eval, const ArrayView< const Number > &inverse_coefficients, const bool dyadic_coefficients, const Number *in_array, Number *out_array)
static void vmult(const Number *inverse_coefficients, const Number *src, Number *dst, const unsigned int dofs_per_component, const unsigned int n_given_components=0)
static void do_mass(const unsigned int n_components, const AlignedVector< Number2 > &transformation_matrix, const AlignedVector< Number > &coefficients, const Number *values_in, Number *scratch_data, Number *values_out)
static void do_forward(const unsigned int n_components, const AlignedVector< Number2 > &transformation_matrix, const Number *values_in, Number *values_out, const unsigned int basis_size_1_variable=numbers::invalid_unsigned_int, const unsigned int basis_size_2_variable=numbers::invalid_unsigned_int)
static void do_backward(const unsigned int n_components, const AlignedVector< Number2 > &transformation_matrix, const bool add_into_result, Number *values_in, Number *values_out, const unsigned int basis_size_1_variable=numbers::invalid_unsigned_int, const unsigned int basis_size_2_variable=numbers::invalid_unsigned_int)
static void integrate(const unsigned int n_components, const EvaluationFlags::EvaluationFlags integration_flag, Number *values_dofs, FEEvaluationData< dim, Number, false > &fe_eval, const bool add_into_values_array)
static void do_evaluate(const MatrixFreeFunctions::UnivariateShapeData< Number2 > &shape, const EvaluationFlags::EvaluationFlags evaluation_flag, const Number *values_dofs, Number *gradients_quad, Number *hessians_quad)
static void do_integrate(const MatrixFreeFunctions::UnivariateShapeData< Number2 > &shape, const EvaluationFlags::EvaluationFlags integration_flag, Number *values_dofs, Number *gradients_quad, const Number *hessians_quad, const bool add_into_values_array)
static void evaluate(const unsigned int n_components, const EvaluationFlags::EvaluationFlags evaluation_flag, const Number *values_dofs, FEEvaluationData< dim, Number, false > &fe_eval)
typename FEEvaluationData< dim, Number, false >::shape_info_number_type Number2
static void evaluate_or_integrate(const unsigned int n_components, const EvaluationFlags::EvaluationFlags evaluation_flag, OtherNumber *values_dofs, FEEvaluationData< dim, Number, false > &fe_eval, const bool sum_into_values_array)
static bool run(const unsigned int n_components, const EvaluationFlags::EvaluationFlags evaluation_flag, OtherNumber *values_dofs, FEEvaluationData< dim, Number, false > &fe_eval, const bool sum_into_values_array=false)
static void evaluate_or_integrate(const unsigned int n_components, const EvaluationFlags::EvaluationFlags evaluation_flag, const Number *values_dofs, FEEvaluationData< dim, Number, false > &fe_eval, const bool sum_into_values_array, std::integral_constant< bool, false >)
static void evaluate_or_integrate(const unsigned int n_components, const EvaluationFlags::EvaluationFlags evaluation_flag, Number *values_dofs, FEEvaluationData< dim, Number, false > &fe_eval, const bool sum_into_values_array, std::integral_constant< bool, true >)
static EvalType create_evaluator_tensor_product(const MatrixFreeFunctions::UnivariateShapeData< Number2 > &shape_data)
static const EvaluatorVariant variant
typename FEEvaluationData< dim, Number, false >::shape_info_number_type Number2
EvaluatorTensorProduct< variant, dim, fe_degree+1, n_q_points_1d, Number, Number2 > Eval
static void integrate(const unsigned int n_components, const EvaluationFlags::EvaluationFlags integration_flag, Number *values_dofs_actual, FEEvaluationData< dim, Number, false > &fe_eval, const bool add_into_values_array)
static Eval create_evaluator_tensor_product(const MatrixFreeFunctions::UnivariateShapeData< Number2 > *univariate_shape_data)
static void evaluate(const unsigned int n_components, const EvaluationFlags::EvaluationFlags evaluation_flag, const Number *values_dofs_actual, FEEvaluationData< dim, Number, false > &fe_eval)
static bool run(const unsigned int n_components, const EvaluationFlags::EvaluationFlags evaluation_flag, const Number *values_dofs, FEEvaluationData< dim, Number, true > &fe_eval)
void hermite_grad(T0 &temp_1, T0 &temp_2, const T1 &src_ptr_1, const T1 &src_ptr_2, const T2 &grad_weight)
static const int fe_degree_
static const bool do_integrate
void value_vectorized(T1 &temp, const T2 src_ptr)
void value(T1 &temp, const T2 &src_ptr)
VectorizedArrayType VectorizedArrayType_
void value_vectorized_indexed(T0 &temp, const T1 src_ptr, const T2 &indices)
void hermite_grad_vectorized(T0 &temp_1, T0 &temp_2, const T1 src_ptr_1, const T1 src_ptr_2, const T2 &grad_weight)
void hermite_grad_vectorized_indexed(T0 &temp_1, T0 &temp_2, const T1 src_ptr_1, const T1 src_ptr_2, const T2 &grad_weight, const T3 &indices_1, const T3 &indices_2)
typename VectorizedArrayType::value_type Number
static bool run(const unsigned int n_components, const EvaluationFlags::EvaluationFlags evaluation_flag, const Number2 *src_ptr, const std::vector< ArrayView< const Number2 > > *sm_ptr, FEEvaluationData< dim, VectorizedArrayType, true > &fe_eval)
static bool supports(const EvaluationFlags::EvaluationFlags evaluation_flag, const MatrixFreeFunctions::ShapeInfo< Number3 > &shape_info, const Number2 *vector_ptr, MatrixFreeFunctions::DoFInfo::IndexStorageVariants storage)
static const int fe_degree_
void value(const T0 &temp, T1 &dst_ptr)
void hermite_grad_vectorized(const T0 &temp_1, const T1 &temp_2, T2 dst_ptr_1, T3 dst_ptr_2, const T4 &grad_weight)
void hermite_grad_vectorized_indexed(const T0 &temp_1, const T0 &temp_2, T1 dst_ptr_1, T1 dst_ptr_2, const T2 &grad_weight, const T3 &indices_1, const T3 &indices_2)
static const bool do_integrate
VectorizedArrayType VectorizedArrayType_
void hermite_grad(const T0 &temp_1, const T0 &temp_2, T1 &dst_ptr_1, T1 &dst_ptr_2, const T2 &grad_weight)
void value_vectorized(const T0 &temp, T1 dst_ptr)
void value_vectorized_indexed(const T0 &temp, T1 dst_ptr, const T2 &indices)
typename VectorizedArrayType::value_type Number
static bool run(const unsigned int n_components, const EvaluationFlags::EvaluationFlags integration_flag, Number2 *dst_ptr, const std::vector< ArrayView< const Number2 > > *sm_ptr, FEEvaluationData< dim, VectorizedArrayType, true > &fe_eval)
static bool run(const unsigned int n_components, const EvaluationFlags::EvaluationFlags integration_flag, Number *values_dofs, FEEvaluationData< dim, Number, true > &fe_eval)
static void evaluate_or_integrate_in_face(const EvaluationFlags::EvaluationFlags evaluation_flag, Number *values_dofs, FEEvaluationData< dim, Number, true > &fe_eval, Number *scratch_data, const unsigned int subface_index, const unsigned int face_no)
static void evaluate_in_face_apply(Number *values_dofs, FEEvaluationData< dim, Number, true > &fe_eval, Number *scratch_data, const EvaluationFlags::EvaluationFlags evaluation_flag, const unsigned int face_direction, const unsigned int subface_index, std::integral_constant< bool, false >)
static EvalType create_evaluator_tensor_product(const MatrixFreeFunctions::UnivariateShapeData< Number2 > &data, const unsigned int subface_index, const unsigned int direction)
static void evaluate_in_face_apply(Number *values_dofs, FEEvaluationData< dim, Number, true > &fe_eval, Number *scratch_data, const EvaluationFlags::EvaluationFlags evaluation_flag, const unsigned int face_direction, const unsigned int subface_index, std::integral_constant< bool, true >)
typename FEEvaluationData< dim, Number, true >::shape_info_number_type Number2
EvaluatorTensorProduct< symmetric_evaluate ? evaluate_evenodd :evaluate_general, dim - 1, fe_degree+1, n_q_points_1d, Number, Number2 > Eval
static void evaluate_in_face(const unsigned int n_components, const EvaluationFlags::EvaluationFlags evaluation_flag, const MatrixFreeFunctions::UnivariateShapeData< Number2 > &data, Number *values_dofs, Number *values_quad, Number *gradients_quad, Number *hessians_quad, Number *scratch_data, const unsigned int subface_index)
static Eval create_evaluator_tensor_product(const MatrixFreeFunctions::UnivariateShapeData< Number2 > &data, const unsigned int subface_index, const unsigned int direction)
static void integrate_in_face(const unsigned int n_components, const EvaluationFlags::EvaluationFlags integration_flag, const MatrixFreeFunctions::UnivariateShapeData< Number2 > &data, Number *values_dofs, Number *values_quad, Number *gradients_quad, Number *hessians_quad, Number *scratch_data, const unsigned int subface_index)
typename FEEvaluationData< dim, Number, true >::shape_info_number_type Number2
static EvalType create_evaluator_tensor_product(const MatrixFreeFunctions::UnivariateShapeData< Number2 > &data, const unsigned int face_no)
static void interpolate_generic_raviart_thomas(const unsigned int n_components, const Number *input, Number *output, const EvaluationFlags::EvaluationFlags flag, const unsigned int face_no, const MatrixFreeFunctions::ShapeInfo< Number2 > &shape_info)
typename FEEvaluationData< dim, Number, true >::shape_info_number_type Number2
static void interpolate_generic_raviart_thomas_apply_face(const MatrixFreeFunctions::ShapeInfo< Number2 > &shape_info, const unsigned int face_no, const Number *input, Number *output)
static void interpolate_quadrature(const unsigned int n_components, const EvaluationFlags::EvaluationFlags flags, const MatrixFreeFunctions::ShapeInfo< Number2 > &shape_info, const Number *input, Number *output, const unsigned int face_no)
static void interpolate_generic(const unsigned int n_components, const Number *input, Number *output, const EvaluationFlags::EvaluationFlags flag, const unsigned int face_no, const unsigned int n_points_1d, const std::array< AlignedVector< Number2 >, 2 > &shape_data, const unsigned int dofs_per_component_on_cell, const unsigned int dofs_per_component_on_face)
static void interpolate(const unsigned int n_components, const EvaluationFlags::EvaluationFlags flags, const MatrixFreeFunctions::ShapeInfo< Number2 > &shape_info, const Number *input, Number *output, const unsigned int face_no)
unsigned int n_q_points_face
unsigned int dofs_per_component_on_cell
std::vector< UnivariateShapeData< Number > > data
::Table< 2, unsigned int > face_orientations_quad
unsigned int dofs_per_component_on_face
AlignedVector< Number > shape_values
std::array< AlignedVector< Number >, 2 > shape_data_on_face
AlignedVector< Number > shape_values_eo
AlignedVector< Number > shape_hessians_eo
AlignedVector< Number > shape_gradients_collocation_eo
unsigned int n_q_points_1d
AlignedVector< Number > shape_gradients_eo
AlignedVector< Number > shape_hessians
AlignedVector< Number > shape_gradients
std::array< AlignedVector< Number >, 2 > hessians_within_subface
std::array< AlignedVector< Number >, 2 > values_within_subface
AlignedVector< Number > shape_hessians_collocation_eo
std::array< AlignedVector< Number >, 2 > gradients_within_subface