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>
129 evaluate(
const unsigned int n_components,
131 const Number * values_dofs_actual,
135 integrate(
const unsigned int n_components,
137 Number * values_dofs_actual,
139 const bool add_into_values_array);
144 *univariate_shape_data)
167 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
175 evaluate(
const unsigned int n_components,
177 const Number * values_dofs_actual,
181 integrate(
const unsigned int n_components,
183 Number * values_dofs_actual,
185 const bool add_into_values_array);
192 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
199 template <
bool integrate>
201 evaluate_or_integrate(
203 Number * values_dofs_actual,
205 const bool add_into_values_array =
false);
208 template <
typename EvalType>
218 template <
int normal_dir>
220 evaluate_tensor_product_per_component(
222 Number * values_dofs_actual,
224 const bool add_into_values_array,
225 std::integral_constant<bool, false>);
227 template <
int normal_dir>
229 evaluate_tensor_product_per_component(
231 Number * values_dofs_actual,
233 const bool add_into_values_array,
234 std::integral_constant<bool, true>);
246 const unsigned int n_components,
248 const Number * values_dofs_actual,
254 std::array<const MatrixFreeFunctions::UnivariateShapeData<Number> *, 3>
255 univariate_shape_data;
259 univariate_shape_data.fill(&shape_data.front());
261 if (shape_data.size() == dim)
262 for (
int i = 1; i < dim; ++i)
263 univariate_shape_data[i] = &shape_data[i];
265 Eval eval0 = create_evaluator_tensor_product(univariate_shape_data[0]);
266 Eval eval1 = create_evaluator_tensor_product(univariate_shape_data[1]);
267 Eval eval2 = create_evaluator_tensor_product(univariate_shape_data[2]);
269 const unsigned int temp_size =
272 (Eval::n_rows_of_product > Eval::n_columns_of_product ?
273 Eval::n_rows_of_product :
274 Eval::n_columns_of_product);
279 temp2 = temp1 +
std::max(Utilities::fixed_power<dim>(
280 shape_data.front().fe_degree + 1),
281 Utilities::fixed_power<dim>(
282 shape_data.front().n_q_points_1d));
286 temp2 = temp1 + temp_size;
289 const std::size_t n_q_points = temp_size == 0 ?
291 Eval::n_columns_of_product;
292 const std::size_t dofs_per_comp =
296 const Number *values_dofs = values_dofs_actual;
299 const std::size_t n_dofs_per_comp =
301 Number *values_dofs_tmp =
302 temp1 + 2 * (
std::max(n_dofs_per_comp, n_q_points));
304 fe_degree != -1 ? fe_degree : shape_data.front().fe_degree;
305 for (
unsigned int c = 0; c < n_components; ++c)
306 for (
int i = 0, count_p = 0, count_q = 0;
307 i < (dim > 2 ? degree + 1 : 1);
310 for (
int j = 0; j < (dim > 1 ? degree + 1 - i : 1); ++j)
312 for (
int k = 0; k < degree + 1 - j - i;
313 ++k, ++count_p, ++count_q)
314 values_dofs_tmp[c * dofs_per_comp + count_q] =
315 values_dofs_actual[c * n_dofs_per_comp + count_p];
316 for (
int k = degree + 1 - j - i; k < degree + 1;
318 values_dofs_tmp[c * dofs_per_comp + count_q] = Number();
320 for (
int j = degree + 1 - i; j < degree + 1; ++j)
321 for (
int k = 0; k < degree + 1; ++k, ++count_q)
322 values_dofs_tmp[c * dofs_per_comp + count_q] = Number();
324 values_dofs = values_dofs_tmp;
334 for (
unsigned int c = 0; c < n_components; ++c)
337 eval0.template values<0, true, false>(values_dofs, values_quad);
339 eval0.template gradients<0, true, false>(values_dofs,
342 eval0.template hessians<0, true, false>(values_dofs,
346 values_dofs += dofs_per_comp;
347 values_quad += n_q_points;
348 gradients_quad += n_q_points;
349 hessians_quad += n_q_points;
354 for (
unsigned int c = 0; c < n_components; ++c)
359 eval0.template gradients<0, true, false>(values_dofs, temp1);
360 eval1.template values<1, true, false>(temp1, gradients_quad);
366 eval0.template gradients<0, true, false>(values_dofs,
368 eval1.template gradients<1, true, false>(temp1,
373 eval0.template hessians<0, true, false>(values_dofs, temp1);
374 eval1.template values<1, true, false>(temp1, hessians_quad);
378 eval0.template values<0, true, false>(values_dofs, temp1);
380 eval1.template gradients<1, true, false>(temp1,
386 eval1.template hessians<1, true, false>(temp1,
392 eval1.template values<1, true, false>(temp1, values_quad);
395 values_dofs += dofs_per_comp;
396 values_quad += n_q_points;
397 gradients_quad += 2 * n_q_points;
398 hessians_quad += 3 * n_q_points;
403 for (
unsigned int c = 0; c < n_components; ++c)
408 eval0.template gradients<0, true, false>(values_dofs, temp1);
409 eval1.template values<1, true, false>(temp1, temp2);
410 eval2.template values<2, true, false>(temp2, gradients_quad);
418 eval0.template gradients<0, true, false>(values_dofs,
420 eval1.template values<1, true, false>(temp1, temp2);
422 eval2.template gradients<2, true, false>(temp2,
427 eval1.template gradients<1, true, false>(temp1, temp2);
428 eval2.template values<2, true, false>(temp2,
433 eval0.template hessians<0, true, false>(values_dofs, temp1);
434 eval1.template values<1, true, false>(temp1, temp2);
435 eval2.template values<2, true, false>(temp2, hessians_quad);
439 eval0.template values<0, true, false>(values_dofs, temp1);
442 eval1.template gradients<1, true, false>(temp1, temp2);
443 eval2.template values<2, true, false>(temp2,
452 eval1.template gradients<1, true, false>(temp1, temp2);
453 eval2.template gradients<2, true, false>(temp2,
458 eval1.template hessians<1, true, false>(temp1, temp2);
459 eval2.template values<2, true, false>(temp2,
466 eval1.template values<1, true, false>(temp1, temp2);
468 eval2.template gradients<2, true, false>(temp2,
475 eval2.template hessians<2, true, false>(temp2,
482 eval2.template values<2, true, false>(temp2, values_quad);
485 values_dofs += dofs_per_comp;
486 values_quad += n_q_points;
487 gradients_quad += 3 * n_q_points;
488 hessians_quad += 6 * n_q_points;
501 values_quad -= n_components * n_q_points;
502 values_dofs -= n_components * dofs_per_comp;
503 for (std::size_t c = 0; c < n_components; ++c)
504 for (std::size_t q = 0; q < n_q_points; ++q)
505 values_quad[c * n_q_points + q] +=
506 values_dofs[(c + 1) * dofs_per_comp - 1];
519 const unsigned int n_components,
521 Number * values_dofs_actual,
523 const bool add_into_values_array)
525 std::array<const MatrixFreeFunctions::UnivariateShapeData<Number> *, 3>
526 univariate_shape_data;
529 univariate_shape_data.fill(&shape_data.front());
531 if (shape_data.size() == dim)
532 for (
int i = 1; i < dim; ++i)
533 univariate_shape_data[i] = &shape_data[i];
535 Eval eval0 = create_evaluator_tensor_product(univariate_shape_data[0]);
536 Eval eval1 = create_evaluator_tensor_product(univariate_shape_data[1]);
537 Eval eval2 = create_evaluator_tensor_product(univariate_shape_data[2]);
539 const unsigned int temp_size =
542 (Eval::n_rows_of_product > Eval::n_columns_of_product ?
543 Eval::n_rows_of_product :
544 Eval::n_columns_of_product);
549 temp2 = temp1 +
std::max(Utilities::fixed_power<dim>(
550 shape_data.front().fe_degree + 1),
551 Utilities::fixed_power<dim>(
552 shape_data.front().n_q_points_1d));
556 temp2 = temp1 + temp_size;
559 const std::size_t n_q_points = temp_size == 0 ?
561 Eval::n_columns_of_product;
562 const unsigned int dofs_per_comp =
564 Utilities::fixed_power<dim>(shape_data.front().fe_degree + 1) :
567 Number *values_dofs =
569 temp1 + 2 * (std::max<std::size_t>(
581 for (
unsigned int c = 0; c < n_components; ++c)
585 if (add_into_values_array ==
false)
586 eval0.template values<0, false, false>(values_quad,
589 eval0.template values<0, false, true>(values_quad,
595 add_into_values_array ==
true)
596 eval0.template gradients<0, false, true>(gradients_quad,
599 eval0.template gradients<0, false, false>(gradients_quad,
606 add_into_values_array ==
true)
607 eval0.template hessians<0, false, true>(hessians_quad,
610 eval0.template hessians<0, false, false>(hessians_quad,
615 values_dofs += dofs_per_comp;
616 values_quad += n_q_points;
617 gradients_quad += n_q_points;
618 hessians_quad += n_q_points;
623 for (
unsigned int c = 0; c < n_components; ++c)
628 eval1.template values<1, false, false>(values_quad, temp1);
629 if (add_into_values_array ==
false)
630 eval0.template values<0, false, false>(temp1, values_dofs);
632 eval0.template values<0, false, true>(temp1, values_dofs);
636 eval1.template gradients<1, false, false>(gradients_quad +
640 eval1.template values<1, false, true>(values_quad, temp1);
641 if (add_into_values_array ==
false)
642 eval0.template values<0, false, false>(temp1, values_dofs);
644 eval0.template values<0, false, true>(temp1, values_dofs);
645 eval1.template values<1, false, false>(gradients_quad, temp1);
646 eval0.template gradients<0, false, true>(temp1, values_dofs);
651 eval1.template values<1, false, false>(hessians_quad, temp1);
655 add_into_values_array ==
true)
656 eval0.template hessians<0, false, true>(temp1, values_dofs);
658 eval0.template hessians<0, false, false>(temp1,
662 eval1.template hessians<1, false, false>(hessians_quad +
665 eval0.template values<0, false, true>(temp1, values_dofs);
668 eval1.template gradients<1, false, false>(hessians_quad +
671 eval0.template gradients<0, false, true>(temp1, values_dofs);
675 values_dofs += dofs_per_comp;
676 values_quad += n_q_points;
677 gradients_quad += 2 * n_q_points;
678 hessians_quad += 3 * n_q_points;
683 for (
unsigned int c = 0; c < n_components; ++c)
688 eval2.template values<2, false, false>(values_quad, temp1);
689 eval1.template values<1, false, false>(temp1, temp2);
690 if (add_into_values_array ==
false)
691 eval0.template values<0, false, false>(temp2, values_dofs);
693 eval0.template values<0, false, true>(temp2, values_dofs);
697 eval2.template gradients<2, false, false>(gradients_quad +
701 eval2.template values<2, false, true>(values_quad, temp1);
702 eval1.template values<1, false, false>(temp1, temp2);
703 eval2.template values<2, false, false>(gradients_quad +
706 eval1.template gradients<1, false, true>(temp1, temp2);
707 if (add_into_values_array ==
false)
708 eval0.template values<0, false, false>(temp2, values_dofs);
710 eval0.template values<0, false, true>(temp2, values_dofs);
711 eval2.template values<2, false, false>(gradients_quad, temp1);
712 eval1.template values<1, false, false>(temp1, temp2);
713 eval0.template gradients<0, false, true>(temp2, values_dofs);
718 eval2.template values<2, false, false>(hessians_quad, temp1);
719 eval1.template values<1, false, false>(temp1, temp2);
723 add_into_values_array ==
true)
724 eval0.template hessians<0, false, true>(temp2, values_dofs);
726 eval0.template hessians<0, false, false>(temp2,
730 eval2.template values<2, false, false>(hessians_quad +
733 eval1.template hessians<1, false, false>(temp1, temp2);
734 eval0.template values<0, false, true>(temp2, values_dofs);
737 eval2.template hessians<2, false, false>(hessians_quad +
740 eval1.template values<1, false, false>(temp1, temp2);
741 eval0.template values<0, false, true>(temp2, values_dofs);
744 eval2.template values<2, false, false>(hessians_quad +
747 eval1.template gradients<1, false, false>(temp1, temp2);
748 eval0.template gradients<0, false, true>(temp2, values_dofs);
751 eval2.template gradients<2, false, false>(hessians_quad +
754 eval1.template values<1, false, false>(temp1, temp2);
755 eval0.template gradients<0, false, true>(temp2, values_dofs);
758 eval2.template gradients<2, false, false>(hessians_quad +
761 eval1.template gradients<1, false, false>(temp1, temp2);
762 eval0.template values<0, false, true>(temp2, values_dofs);
766 values_dofs += dofs_per_comp;
767 values_quad += n_q_points;
768 gradients_quad += 3 * n_q_points;
769 hessians_quad += 6 * n_q_points;
780 values_dofs -= n_components * dofs_per_comp - dofs_per_comp + 1;
781 values_quad -= n_components * n_q_points;
783 for (
unsigned int c = 0; c < n_components; ++c)
785 values_dofs[0] = values_quad[0];
786 for (
unsigned int q = 1; q < n_q_points; ++q)
787 values_dofs[0] += values_quad[q];
788 values_dofs += dofs_per_comp;
789 values_quad += n_q_points;
793 for (
unsigned int c = 0; c < n_components; ++c)
794 values_dofs[c * dofs_per_comp] = Number();
795 values_dofs += n_components * dofs_per_comp;
801 const std::size_t n_dofs_per_comp =
803 values_dofs -= dofs_per_comp * n_components;
805 fe_degree != -1 ? fe_degree : shape_data.front().fe_degree;
806 for (
unsigned int c = 0; c < n_components; ++c)
807 for (
int i = 0, count_p = 0, count_q = 0;
808 i < (dim > 2 ? degree + 1 : 1);
811 for (
int j = 0; j < (dim > 1 ? degree + 1 - i : 1); ++j)
813 for (
int k = 0; k < degree + 1 - j - i;
814 ++k, ++count_p, ++count_q)
815 values_dofs_actual[c * n_dofs_per_comp + count_p] =
816 values_dofs[c * dofs_per_comp + count_q];
819 count_q += i * (degree + 1);
826 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
833 Number>::evaluate(
const unsigned int n_components,
835 const Number * values_dofs_actual,
838 const std::size_t n_dofs =
849 const auto shape_values = shape_data.front().shape_values.data();
851 auto values_dofs_actual_ptr = values_dofs_actual;
853 Eval eval(shape_values,
nullptr,
nullptr, n_dofs, n_q_points);
854 for (
unsigned int c = 0; c < n_components; ++c)
856 eval.template values<0, true, false>(values_dofs_actual_ptr,
859 values_quad_ptr += n_q_points;
860 values_dofs_actual_ptr += n_dofs;
866 const auto shape_gradients = shape_data.front().shape_gradients.data();
868 auto values_dofs_actual_ptr = values_dofs_actual;
870 for (
unsigned int c = 0; c < n_components; ++c)
872 for (
unsigned int d = 0; d < dim; ++d)
875 shape_gradients + n_q_points * n_dofs * d,
880 eval.template gradients<0, true, false>(values_dofs_actual_ptr,
883 gradients_quad_ptr += n_q_points;
885 values_dofs_actual_ptr += n_dofs;
895 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
902 Number>::integrate(
const unsigned int n_components,
904 Number * values_dofs_actual,
906 const bool add_into_values_array)
912 const std::size_t n_dofs =
923 const auto shape_values = shape_data.front().shape_values.data();
925 auto values_dofs_actual_ptr = values_dofs_actual;
927 Eval eval(shape_values,
nullptr,
nullptr, n_dofs, n_q_points);
928 for (
unsigned int c = 0; c < n_components; ++c)
930 if (add_into_values_array ==
false)
931 eval.template values<0, false, false>(values_quad_ptr,
932 values_dofs_actual_ptr);
934 eval.template values<0, false, true>(values_quad_ptr,
935 values_dofs_actual_ptr);
937 values_quad_ptr += n_q_points;
938 values_dofs_actual_ptr += n_dofs;
944 const auto shape_gradients = shape_data.front().shape_gradients.data();
946 auto values_dofs_actual_ptr = values_dofs_actual;
948 for (
unsigned int c = 0; c < n_components; ++c)
950 for (
unsigned int d = 0; d < dim; ++d)
953 shape_gradients + n_q_points * n_dofs * d,
958 if ((add_into_values_array ==
false &&
961 eval.template gradients<0, false, false>(
962 gradients_quad_ptr, values_dofs_actual_ptr);
964 eval.template gradients<0, false, true>(
965 gradients_quad_ptr, values_dofs_actual_ptr);
967 gradients_quad_ptr += n_q_points;
969 values_dofs_actual_ptr += n_dofs;
975 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
976 template <
bool integrate>
983 evaluate_or_integrate(
985 Number * values_dofs_actual,
987 const bool add_into_values_array)
994 evaluate_tensor_product_per_component<0>(
998 add_into_values_array,
999 std::integral_constant<bool, integrate>());
1001 evaluate_tensor_product_per_component<1>(
1005 add_into_values_array,
1006 std::integral_constant<bool, integrate>());
1010 evaluate_tensor_product_per_component<2>(
1014 add_into_values_array,
1015 std::integral_constant<bool, integrate>());
1022 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
1023 template <
int normal_dir>
1030 evaluate_tensor_product_per_component(
1032 Number * values_dofs_actual,
1034 const bool add_into_values_array,
1035 std::integral_constant<bool, false>)
1037 (void)add_into_values_array;
1042 (fe_degree == -1) ? 1 : fe_degree + 1,
1050 (fe_degree == -1) ? 1 : fe_degree,
1055 typename std::conditional<normal_dir == 0, EvalNormal, EvalTangent>::type;
1057 typename std::conditional<normal_dir == 1, EvalNormal, EvalTangent>::type;
1059 typename std::conditional<normal_dir == 2, EvalNormal, EvalTangent>::type;
1063 Eval0 eval0 = create_evaluator_tensor_product<Eval0>(
1064 ((normal_dir == 0) ? shape_info.
data[0] : shape_info.
data[1]));
1065 Eval1 eval1 = create_evaluator_tensor_product<Eval1>(
1066 ((normal_dir == 1) ? shape_info.
data[0] : shape_info.
data[1]));
1067 Eval2 eval2 = create_evaluator_tensor_product<Eval2>(
1068 ((normal_dir == 2) ? shape_info.
data[0] : shape_info.
data[1]));
1075 std::max(Utilities::fixed_power<dim>(shape_info.
data[0].fe_degree + 1),
1076 Utilities::fixed_power<dim>(shape_info.
data[0].n_q_points_1d));
1078 const std::size_t n_q_points = shape_info.
n_q_points;
1082 Number *values_dofs = values_dofs_actual + dofs_per_comp * normal_dir;
1083 Number *values_quad = fe_eval.
begin_values() + n_q_points * normal_dir;
1084 Number *gradients_quad =
1086 Number *hessians_quad =
1087 (dim == 2) ? fe_eval.
begin_hessians() + 3 * n_q_points * normal_dir :
1095 eval0.template gradients<0, true, false>(values_dofs, temp1);
1096 eval1.template values<1, true, false>(temp1, gradients_quad);
1105 eval0.template gradients<0, true, false>(values_dofs, temp1);
1106 eval1.template gradients<1, true, false>(temp1,
1111 eval0.template hessians<0, true, false>(values_dofs, temp1);
1112 eval1.template values<1, true, false>(temp1, hessians_quad);
1116 eval0.template values<0, true, false>(values_dofs, temp1);
1118 eval1.template gradients<1, true, false>(temp1,
1124 eval1.template hessians<1, true, false>(temp1,
1125 hessians_quad + n_q_points);
1129 eval1.template values<1, true, false>(temp1, values_quad);
1135 eval0.template gradients<0, true, false>(values_dofs, temp1);
1136 eval1.template values<1, true, false>(temp1, temp2);
1137 eval2.template values<2, true, false>(temp2, gradients_quad);
1148 eval0.template gradients<0, true, false>(values_dofs, temp1);
1149 eval1.template values<1, true, false>(temp1, temp2);
1151 eval2.template gradients<2, true, false>(temp2,
1156 eval1.template gradients<1, true, false>(temp1, temp2);
1157 eval2.template values<2, true, false>(temp2,
1162 eval0.template hessians<0, true, false>(values_dofs, temp1);
1163 eval1.template values<1, true, false>(temp1, temp2);
1164 eval2.template values<2, true, false>(temp2, hessians_quad);
1168 eval0.template values<0, true, false>(values_dofs, temp1);
1171 eval1.template gradients<1, true, false>(temp1, temp2);
1172 eval2.template values<2, true, false>(temp2,
1181 eval1.template gradients<1, true, false>(temp1, temp2);
1182 eval2.template gradients<2, true, false>(temp2,
1187 eval1.template hessians<1, true, false>(temp1, temp2);
1188 eval2.template values<2, true, false>(temp2,
1189 hessians_quad + n_q_points);
1194 eval1.template values<1, true, false>(temp1, temp2);
1196 eval2.template gradients<2, true, false>(temp2,
1203 eval2.template hessians<2, true, false>(temp2,
1210 eval2.template values<2, true, false>(temp2, values_quad);
1217 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
1218 template <
int normal_dir>
1225 evaluate_tensor_product_per_component(
1227 Number * values_dofs_actual,
1229 const bool add_into_values_array,
1230 std::integral_constant<bool, true>)
1235 (fe_degree == -1) ? 1 : fe_degree + 1,
1243 (fe_degree == -1) ? 1 : fe_degree,
1248 typename std::conditional<normal_dir == 0, EvalNormal, EvalTangent>::type;
1250 typename std::conditional<normal_dir == 1, EvalNormal, EvalTangent>::type;
1252 typename std::conditional<normal_dir == 2, EvalNormal, EvalTangent>::type;
1256 Eval0 eval0 = create_evaluator_tensor_product<Eval0>(
1257 ((normal_dir == 0) ? shape_info.
data[0] : shape_info.
data[1]));
1258 Eval1 eval1 = create_evaluator_tensor_product<Eval1>(
1259 ((normal_dir == 1) ? shape_info.
data[0] : shape_info.
data[1]));
1260 Eval2 eval2 = create_evaluator_tensor_product<Eval2>(
1261 ((normal_dir == 2) ? shape_info.
data[0] : shape_info.
data[1]));
1268 std::max(Utilities::fixed_power<dim>(shape_info.
data[0].fe_degree + 1),
1269 Utilities::fixed_power<dim>(shape_info.
data[0].n_q_points_1d));
1271 const std::size_t n_q_points = shape_info.
n_q_points;
1275 Number *values_dofs = values_dofs_actual + dofs_per_comp * normal_dir;
1276 Number *values_quad = fe_eval.
begin_values() + n_q_points * normal_dir;
1277 Number *gradients_quad =
1279 Number *hessians_quad =
1280 (dim == 2) ? fe_eval.
begin_hessians() + 3 * n_q_points * normal_dir :
1290 eval1.template values<1, false, false>(values_quad, temp1);
1291 if (add_into_values_array ==
false)
1292 eval0.template values<0, false, false>(temp1, values_dofs);
1294 eval0.template values<0, false, true>(temp1, values_dofs);
1298 eval1.template gradients<1, false, false>(gradients_quad +
1302 eval1.template values<1, false, true>(values_quad, temp1);
1303 if (add_into_values_array ==
false)
1304 eval0.template values<0, false, false>(temp1, values_dofs);
1306 eval0.template values<0, false, true>(temp1, values_dofs);
1307 eval1.template values<1, false, false>(gradients_quad, temp1);
1308 eval0.template gradients<0, false, true>(temp1, values_dofs);
1313 eval1.template values<1, false, false>(hessians_quad, temp1);
1317 add_into_values_array ==
true)
1318 eval0.template hessians<0, false, true>(temp1, values_dofs);
1320 eval0.template hessians<0, false, false>(temp1, values_dofs);
1323 eval1.template hessians<1, false, false>(hessians_quad +
1326 eval0.template values<0, false, true>(temp1, values_dofs);
1329 eval1.template gradients<1, false, false>(hessians_quad +
1332 eval0.template gradients<0, false, true>(temp1, values_dofs);
1340 eval2.template values<2, false, false>(values_quad, temp1);
1341 eval1.template values<1, false, false>(temp1, temp2);
1342 if (add_into_values_array ==
false)
1343 eval0.template values<0, false, false>(temp2, values_dofs);
1345 eval0.template values<0, false, true>(temp2, values_dofs);
1349 eval2.template gradients<2, false, false>(gradients_quad +
1353 eval2.template values<2, false, true>(values_quad, temp1);
1354 eval1.template values<1, false, false>(temp1, temp2);
1355 eval2.template values<2, false, false>(gradients_quad +
1358 eval1.template gradients<1, false, true>(temp1, temp2);
1359 if (add_into_values_array ==
false)
1360 eval0.template values<0, false, false>(temp2, values_dofs);
1362 eval0.template values<0, false, true>(temp2, values_dofs);
1363 eval2.template values<2, false, false>(gradients_quad, temp1);
1364 eval1.template values<1, false, false>(temp1, temp2);
1365 eval0.template gradients<0, false, true>(temp2, values_dofs);
1370 eval2.template values<2, false, false>(hessians_quad, temp1);
1371 eval1.template values<1, false, false>(temp1, temp2);
1375 add_into_values_array ==
true)
1376 eval0.template hessians<0, false, true>(temp2, values_dofs);
1378 eval0.template hessians<0, false, false>(temp2, values_dofs);
1381 eval2.template values<2, false, false>(hessians_quad + n_q_points,
1383 eval1.template hessians<1, false, false>(temp1, temp2);
1384 eval0.template values<0, false, true>(temp2, values_dofs);
1387 eval2.template hessians<2, false, false>(hessians_quad +
1390 eval1.template values<1, false, false>(temp1, temp2);
1391 eval0.template values<0, false, true>(temp2, values_dofs);
1394 eval2.template values<2, false, false>(hessians_quad +
1397 eval1.template gradients<1, false, false>(temp1, temp2);
1398 eval0.template gradients<0, false, true>(temp2, values_dofs);
1401 eval2.template gradients<2, false, false>(hessians_quad +
1404 eval1.template values<1, false, false>(temp1, temp2);
1405 eval0.template gradients<0, false, true>(temp2, values_dofs);
1408 eval2.template gradients<2, false, false>(hessians_quad +
1411 eval1.template gradients<1, false, false>(temp1, temp2);
1412 eval0.template values<0, false, true>(temp2, values_dofs);
1439 static_assert(basis_size_1 == 0 || basis_size_1 <= basis_size_2,
1440 "The second dimension must not be smaller than the first");
1469 const unsigned int n_components,
1471 const Number * values_in,
1472 Number * values_out,
1477 basis_size_1 != 0 || basis_size_1_variable <= basis_size_2_variable,
1478 ExcMessage(
"The second dimension must not be smaller than the first"));
1486 constexpr int next_dim =
1488 ((basis_size_1 == 0 || basis_size_2 > basis_size_1) && dim > 1)) ?
1495 (basis_size_1 == 0 ? 0 : basis_size_2),
1498 eval_val(transformation_matrix,
1501 basis_size_1_variable,
1502 basis_size_2_variable);
1503 const unsigned int np_1 =
1504 basis_size_1 > 0 ? basis_size_1 : basis_size_1_variable;
1505 const unsigned int np_2 =
1506 basis_size_1 > 0 ? basis_size_2 : basis_size_2_variable;
1508 ExcMessage(
"Cannot transform with 0-point basis"));
1510 ExcMessage(
"Cannot transform with 0-point basis"));
1514 values_in = values_in + n_components * Utilities::fixed_power<dim>(np_1);
1516 values_out + n_components * Utilities::fixed_power<dim>(np_2);
1517 for (
unsigned int c = n_components; c != 0; --c)
1519 values_in -= Utilities::fixed_power<dim>(np_1);
1520 values_out -= Utilities::fixed_power<dim>(np_2);
1522 for (
unsigned int q = np_1; q != 0; --q)
1531 transformation_matrix,
1534 Utilities::fixed_power<next_dim>(np_1),
1537 Utilities::fixed_power<next_dim>(np_2),
1538 basis_size_1_variable,
1539 basis_size_2_variable);
1544 if (basis_size_1 > 0 && basis_size_2 == basis_size_1 && dim == 2)
1546 eval_val.template values<0, true, false>(values_in, values_out);
1547 eval_val.template values<1, true, false>(values_out, values_out);
1550 eval_val.template values<dim - 1,
true,
false>(values_in,
1553 eval_val.template values<dim - 1,
true,
false>(values_out,
1593 const unsigned int n_components,
1595 const bool add_into_result,
1597 Number * values_out,
1602 basis_size_1 != 0 || basis_size_1_variable <= basis_size_2_variable,
1603 ExcMessage(
"The second dimension must not be smaller than the first"));
1604 Assert(add_into_result ==
false || values_in != values_out,
1606 "Input and output cannot alias with each other when "
1607 "adding the result of the basis change to existing data"));
1613 constexpr int next_dim =
1615 ((basis_size_1 == 0 || basis_size_2 > basis_size_1) && dim > 1)) ?
1621 (basis_size_1 == 0 ? 0 : basis_size_2),
1624 eval_val(transformation_matrix,
1625 transformation_matrix,
1626 transformation_matrix,
1627 basis_size_1_variable,
1628 basis_size_2_variable);
1629 const unsigned int np_1 =
1630 basis_size_1 > 0 ? basis_size_1 : basis_size_1_variable;
1631 const unsigned int np_2 =
1632 basis_size_1 > 0 ? basis_size_2 : basis_size_2_variable;
1634 ExcMessage(
"Cannot transform with 0-point basis"));
1636 ExcMessage(
"Cannot transform with 0-point basis"));
1638 for (
unsigned int c = 0; c < n_components; ++c)
1640 if (basis_size_1 > 0 && basis_size_2 == basis_size_1 && dim == 2)
1643 eval_val.template values<1, false, false>(values_in, values_in);
1645 eval_val.template hessians<1, false, false>(values_in,
1648 if (add_into_result)
1651 eval_val.template values<0, false, true>(values_in,
1654 eval_val.template hessians<0, false, true>(values_in,
1660 eval_val.template values<0, false, false>(values_in,
1663 eval_val.template hessians<0, false, false>(values_in,
1669 if (dim == 1 && add_into_result)
1672 eval_val.template values<0, false, true>(values_in,
1675 eval_val.template hessians<0, false, true>(values_in,
1681 eval_val.template values<0, false, false>(values_in,
1684 eval_val.template hessians<0, false, false>(values_in,
1690 eval_val.template values<dim - 1,
false,
false>(values_in,
1693 eval_val.template hessians<dim - 1,
false,
false>(
1694 values_in, values_in);
1698 for (
unsigned int q = 0; q < np_1; ++q)
1707 transformation_matrix,
1710 q * Utilities::fixed_power<next_dim>(np_2),
1712 q * Utilities::fixed_power<next_dim>(np_1),
1713 basis_size_1_variable,
1714 basis_size_2_variable);
1716 values_in += Utilities::fixed_power<dim>(np_2);
1717 values_out += Utilities::fixed_power<dim>(np_1);
1745 const Number * values_in,
1746 Number * scratch_data,
1747 Number * values_out)
1749 constexpr int next_dim = dim > 1 ? dim - 1 : dim;
1750 Number * my_scratch =
1751 basis_size_1 != basis_size_2 ? scratch_data : values_out;
1753 const unsigned int size_per_component =
Utilities::pow(basis_size_2, dim);
1754 Assert(coefficients.
size() == size_per_component ||
1755 coefficients.
size() == n_components * size_per_component,
1757 const unsigned int stride =
1758 coefficients.
size() == size_per_component ? 0 : 1;
1760 for (
unsigned int q = basis_size_1; q != 0; --q)
1769 transformation_matrix,
1782 eval_val(transformation_matrix);
1783 const unsigned int n_inner_blocks =
1784 (dim > 1 && basis_size_2 < 10) ? basis_size_2 : 1;
1785 const unsigned int n_blocks =
Utilities::pow(basis_size_2, dim - 1);
1786 for (
unsigned int ii = 0; ii < n_blocks; ii += n_inner_blocks)
1787 for (
unsigned int c = 0; c < n_components; ++c)
1789 for (
unsigned int i = ii; i < ii + n_inner_blocks; ++i)
1790 eval_val.template values_one_line<dim - 1, true, false>(
1791 my_scratch + i, my_scratch + i);
1792 for (
unsigned int q = 0; q < basis_size_2; ++q)
1793 for (
unsigned int i = ii; i < ii + n_inner_blocks; ++i)
1794 my_scratch[i + q * n_blocks + c * size_per_component] *=
1795 coefficients[i + q * n_blocks +
1796 c * stride * size_per_component];
1797 for (
unsigned int i = ii; i < ii + n_inner_blocks; ++i)
1798 eval_val.template values_one_line<dim - 1, false, false>(
1799 my_scratch + i, my_scratch + i);
1801 for (
unsigned int q = 0; q < basis_size_1; ++q)
1810 transformation_matrix,
1833 template <
int dim,
int fe_degree,
typename Number>
1837 evaluate(
const unsigned int n_components,
1839 const Number * values_dofs,
1845 const Number * values_dofs,
1846 Number * gradients_quad,
1847 Number * hessians_quad);
1850 integrate(
const unsigned int n_components,
1852 Number * values_dofs,
1854 const bool add_into_values_array);
1859 Number * values_dofs,
1860 Number * gradients_quad,
1861 const Number * hessians_quad,
1862 const bool add_into_values_array);
1867 template <
int dim,
int fe_degree,
typename Number>
1870 const unsigned int n_components,
1872 const Number * values_dofs,
1875 constexpr std::size_t n_points =
Utilities::pow(fe_degree + 1, dim);
1877 for (
unsigned int c = 0; c < n_components; ++c)
1880 for (
unsigned int i = 0; i < n_points; ++i)
1882 values_dofs[n_points * c + i];
1886 values_dofs + c * n_points,
1889 c * dim * (dim + 1) / 2 * n_points);
1895 template <
int dim,
int fe_degree,
typename Number>
1900 const Number * values_dofs,
1901 Number * gradients_quad,
1902 Number * hessians_quad)
1905 (fe_degree + 2) / 2 * (fe_degree + 1));
1906 constexpr std::size_t n_points =
Utilities::pow(fe_degree + 1, dim);
1916 if ((evaluation_flag &
1919 eval.template gradients<0, true, false>(values_dofs, gradients_quad);
1921 eval.template gradients<1, true, false>(values_dofs,
1922 gradients_quad + n_points);
1924 eval.template gradients<2, true, false>(values_dofs,
1930 eval.template hessians<0, true, false>(values_dofs, hessians_quad);
1933 eval.template gradients<1, true, false>(gradients_quad,
1936 eval.template hessians<1, true, false>(values_dofs,
1937 hessians_quad + n_points);
1941 eval.template gradients<2, true, false>(gradients_quad,
1944 eval.template gradients<2, true, false>(gradients_quad + n_points,
1947 eval.template hessians<2, true, false>(values_dofs,
1956 template <
int dim,
int fe_degree,
typename Number>
1959 const unsigned int n_components,
1961 Number * values_dofs,
1963 const bool add_into_values_array)
1965 constexpr std::size_t n_points =
Utilities::pow(fe_degree + 1, dim);
1967 for (
unsigned int c = 0; c < n_components; ++c)
1971 if (add_into_values_array)
1972 for (
unsigned int i = 0; i < n_points; ++i)
1973 values_dofs[n_points * c + i] +=
1976 for (
unsigned int i = 0; i < n_points; ++i)
1977 values_dofs[n_points * c + i] =
1983 values_dofs + c * n_points,
1986 c * dim * (dim + 1) / 2 * n_points,
1987 add_into_values_array ||
1994 template <
int dim,
int fe_degree,
typename Number>
1999 Number * values_dofs,
2000 Number * gradients_quad,
2001 const Number * hessians_quad,
2002 const bool add_into_values_array)
2005 (fe_degree + 2) / 2 * (fe_degree + 1));
2015 constexpr std::size_t n_points =
Utilities::pow(fe_degree + 1, dim);
2021 if (add_into_values_array ==
true)
2022 eval.template hessians<0, false, true>(hessians_quad, values_dofs);
2024 eval.template hessians<0, false, false>(hessians_quad, values_dofs);
2027 eval.template hessians<1, false, true>(hessians_quad + n_points,
2031 eval.template hessians<2, false, true>(hessians_quad + 2 * n_points,
2038 eval.template gradients<1, false, true>(hessians_quad +
2042 eval.template gradients<1, false, false>(hessians_quad +
2050 eval.template gradients<1, false, true>(hessians_quad +
2054 eval.template gradients<1, false, false>(hessians_quad +
2059 eval.template gradients<2, false, true>(hessians_quad +
2065 eval.template gradients<2, false, true>(
2066 hessians_quad + 5 * n_points, gradients_quad + n_points);
2068 eval.template gradients<2, false, false>(
2069 hessians_quad + 5 * n_points, gradients_quad + n_points);
2076 for (
unsigned int q = 0; q < n_points; ++q)
2077 gradients_quad[(dim - 1) * n_points + q] = Number();
2080 if ((integration_flag &
2083 if (add_into_values_array ||
2085 eval.template gradients<0, false, true>(gradients_quad, values_dofs);
2087 eval.template gradients<0, false, false>(gradients_quad, values_dofs);
2089 eval.template gradients<1, false, true>(gradients_quad + n_points,
2092 eval.template gradients<2, false, true>(gradients_quad + 2 * n_points,
2109 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
2113 evaluate(
const unsigned int n_components,
2115 const Number * values_dofs,
2119 integrate(
const unsigned int n_components,
2121 Number * values_dofs,
2123 const bool add_into_values_array);
2128 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
2134 Number>::evaluate(
const unsigned int n_components,
2136 const Number * values_dofs,
2141 Assert(n_q_points_1d > fe_degree,
2142 ExcMessage(
"You lose information when going to a collocation space "
2143 "of lower degree, so the evaluation results would be "
2144 "wrong. Thus, this class does not permit the desired "
2146 constexpr std::size_t n_dofs =
Utilities::pow(fe_degree + 1, dim);
2147 constexpr std::size_t n_q_points =
Utilities::pow(n_q_points_1d, dim);
2149 for (
unsigned int c = 0; c < n_components; ++c)
2155 (fe_degree >= n_q_points_1d ? n_q_points_1d : fe_degree + 1),
2158 Number>::do_forward(1,
2159 shape_data.shape_values_eo,
2160 values_dofs + c * n_dofs,
2164 if (evaluation_flag &
2167 do_evaluate(shape_data,
2173 c * dim * (dim + 1) / 2 * n_q_points);
2179 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
2185 Number>::integrate(
const unsigned int n_components,
2187 Number * values_dofs,
2189 const bool add_into_values_array)
2193 Assert(n_q_points_1d > fe_degree,
2194 ExcMessage(
"You lose information when going to a collocation space "
2195 "of lower degree, so the evaluation results would be "
2196 "wrong. Thus, this class does not permit the desired "
2198 constexpr std::size_t n_q_points =
Utilities::pow(n_q_points_1d, dim);
2200 for (
unsigned int c = 0; c < n_components; ++c)
2203 if (integration_flag &
2212 c * dim * (dim + 1) / 2 * n_q_points,
2221 (fe_degree >= n_q_points_1d ? n_q_points_1d : fe_degree + 1),
2224 Number>::do_backward(1,
2225 shape_data.shape_values_eo,
2226 add_into_values_array,
2244 const unsigned int n_q_points_1d)
2246 return (n_q_points_1d > fe_degree) && (n_q_points_1d < 200) &&
2247 (n_q_points_1d <= 3 * fe_degree / 2 + 1);
2266 template <
int dim,
typename Number>
2269 template <
int fe_degree,
int n_q_po
ints_1d>
2271 run(
const unsigned int n_components,
2273 const Number * values_dofs,
2281 element_type == ElementType::tensor_general) ||
2282 element_type == ElementType::tensor_raviart_thomas,
2285 if (fe_degree >= 0 && fe_degree + 1 == n_q_points_1d &&
2286 element_type == ElementType::tensor_symmetric_collocation)
2289 n_components, evaluation_flag, values_dofs, fe_eval);
2293 else if (fe_degree >= 0 &&
2295 element_type <= ElementType::tensor_symmetric)
2301 Number>::evaluate(n_components,
2306 else if (fe_degree >= 0 && element_type <= ElementType::tensor_symmetric)
2312 Number>::evaluate(n_components,
2317 else if (element_type == ElementType::tensor_symmetric_plus_dg0)
2323 Number>::evaluate(n_components,
2328 else if (element_type == ElementType::truncated_tensor)
2334 Number>::evaluate(n_components,
2339 else if (element_type == ElementType::tensor_none)
2345 Number>::evaluate(n_components,
2350 else if (element_type == ElementType::tensor_raviart_thomas)
2353 ElementType::tensor_raviart_thomas,
2355 (fe_degree == -1) ? 1 : fe_degree,
2356 (n_q_points_1d < 1) ? 1 : n_q_points_1d,
2357 Number>::template evaluate_or_integrate<false>(evaluation_flag,
2358 const_cast<Number *
>(
2368 Number>::evaluate(n_components,
2395 template <
int dim,
typename Number>
2398 template <
int fe_degree,
int n_q_po
ints_1d>
2400 run(
const unsigned int n_components,
2402 Number * values_dofs,
2404 const bool sum_into_values_array)
2411 element_type == ElementType::tensor_general) ||
2412 element_type == ElementType::tensor_raviart_thomas,
2415 if (fe_degree >= 0 && fe_degree + 1 == n_q_points_1d &&
2416 element_type == ElementType::tensor_symmetric_collocation)
2423 sum_into_values_array);
2427 else if (fe_degree >= 0 &&
2429 element_type <= ElementType::tensor_symmetric)
2435 Number>::integrate(n_components,
2439 sum_into_values_array);
2441 else if (fe_degree >= 0 && element_type <= ElementType::tensor_symmetric)
2447 Number>::integrate(n_components,
2451 sum_into_values_array);
2453 else if (element_type == ElementType::tensor_symmetric_plus_dg0)
2459 Number>::integrate(n_components,
2463 sum_into_values_array);
2465 else if (element_type == ElementType::truncated_tensor)
2471 Number>::integrate(n_components,
2475 sum_into_values_array);
2477 else if (element_type == ElementType::tensor_none)
2483 Number>::integrate(n_components,
2487 sum_into_values_array);
2489 else if (element_type == ElementType::tensor_raviart_thomas)
2493 (fe_degree == -1) ? 1 : fe_degree,
2494 (n_q_points_1d < 1) ? 1 : n_q_points_1d,
2496 template evaluate_or_integrate<true>(integration_flag,
2497 const_cast<Number *
>(
2500 sum_into_values_array);
2508 Number>::integrate(n_components,
2512 sum_into_values_array);
2521 template <
bool symmetric_evaluate,
2543 const unsigned int subface_index,
2544 const unsigned int direction)
2546 if (symmetric_evaluate)
2560 const unsigned int index =
2561 direction == 0 ? subface_index % 2 : subface_index / 2;
2572 const unsigned int n_components,
2575 Number * values_dofs,
2576 Number * values_quad,
2577 Number * gradients_quad,
2578 Number * hessians_quad,
2579 Number * scratch_data,
2580 const unsigned int subface_index)
2585 const std::size_t n_dofs = fe_degree > -1 ?
2588 const std::size_t n_q_points =
2593 Number *values_dofs_ptr = values_dofs;
2597 for (
unsigned int c = 0; c < n_components; ++c)
2602 eval0.template values<0, true, false>(values_dofs,
2604 eval1.template values<1, true, false>(values_quad,
2608 eval0.template values<0, true, false>(values_dofs,
2612 values_quad[0] = values_dofs[0];
2619 values_dofs += 3 * n_dofs;
2620 values_quad += n_q_points;
2623 for (
unsigned int c = 0; c < n_components; ++c)
2628 if (symmetric_evaluate &&
2631 eval0.template values<0, true, false>(values_dofs,
2633 eval0.template values<1, true, false>(values_quad,
2643 eval_grad.template gradients<0, true, false>(
2644 values_quad, gradients_quad);
2645 eval_grad.template gradients<1, true, false>(
2646 values_quad, gradients_quad + n_q_points);
2651 eval0.template gradients<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 gradients<1, true, false>(scratch_data,
2664 eval1.template values<1, true, false>(scratch_data,
2668 eval0.template values<0, true, false>(values_dofs + n_dofs,
2670 eval1.template values<1, true, false>(
2671 scratch_data, gradients_quad + (dim - 1) * n_q_points);
2675 eval0.template values<0, true, false>(values_dofs + n_dofs,
2678 eval0.template gradients<0, true, false>(values_dofs,
2681 eval0.template values<0, true, false>(values_dofs,
2685 values_quad[0] = values_dofs[0];
2686 gradients_quad[0] = values_dofs[1];
2691 values_dofs += 3 * n_dofs;
2692 values_quad += n_q_points;
2693 gradients_quad += dim * n_q_points;
2698 values_dofs = values_dofs_ptr;
2699 for (
unsigned int c = 0; c < n_components; ++c)
2705 eval0.template hessians<0, true, false>(values_dofs,
2707 eval1.template values<1, true, false>(scratch_data,
2711 eval0.template values<0, true, false>(values_dofs,
2713 eval1.template hessians<1, true, false>(scratch_data,
2718 eval0.template values<0, true, false>(values_dofs +
2721 eval1.template values<1, true, false>(scratch_data,
2726 eval0.template gradients<0, true, false>(values_dofs,
2728 eval1.template gradients<1, true, false>(scratch_data,
2733 eval0.template gradients<0, true, false>(values_dofs +
2736 eval1.template values<1, true, false>(scratch_data,
2741 eval0.template values<0, true, false>(values_dofs + n_dofs,
2743 eval1.template gradients<1, true, false>(scratch_data,
2750 eval0.template hessians<0, true, false>(values_dofs,
2753 eval0.template values<0, true, false>(
2754 values_dofs + 2 * n_dofs, hessians_quad + n_q_points);
2756 eval0.template gradients<0, true, false>(
2757 values_dofs + n_dofs, hessians_quad + 2 * n_q_points);
2760 hessians_quad[0] = values_dofs[2];
2765 values_dofs += 3 * n_dofs;
2766 hessians_quad += dim * (dim + 1) / 2 * n_q_points;
2773 const unsigned int n_components,
2776 Number * values_dofs,
2777 Number * values_quad,
2778 Number * gradients_quad,
2779 Number * hessians_quad,
2780 Number * scratch_data,
2781 const unsigned int subface_index)
2786 const std::size_t n_dofs =
2790 const std::size_t n_q_points =
2795 Number *values_dofs_ptr = values_dofs;
2799 for (
unsigned int c = 0; c < n_components; ++c)
2804 eval1.template values<1, false, false>(values_quad,
2806 eval0.template values<0, false, false>(values_quad,
2810 eval0.template values<0, false, false>(values_quad,
2814 values_dofs[0] = values_quad[0];
2819 values_dofs += 3 * n_dofs;
2820 values_quad += n_q_points;
2823 for (
unsigned int c = 0; c < n_components; ++c)
2829 eval1.template values<1, false, false>(gradients_quad +
2833 eval0.template values<0, false, false>(gradients_quad +
2835 values_dofs + n_dofs);
2836 if (symmetric_evaluate &&
2848 eval_grad.template gradients<1, false, true>(
2849 gradients_quad + n_q_points, values_quad);
2851 eval_grad.template gradients<1, false, false>(
2852 gradients_quad + n_q_points, values_quad);
2853 eval_grad.template gradients<0, false, true>(
2854 gradients_quad, values_quad);
2855 eval0.template values<1, false, false>(values_quad,
2857 eval0.template values<0, false, false>(values_quad,
2864 eval1.template values<1, false, false>(values_quad,
2866 eval1.template gradients<1, false, true>(
2867 gradients_quad + n_q_points, scratch_data);
2870 eval1.template gradients<1, false, false>(
2871 gradients_quad + n_q_points, scratch_data);
2874 eval0.template values<0, false, false>(scratch_data,
2878 eval1.template values<1, false, false>(gradients_quad,
2880 eval0.template gradients<0, false, true>(scratch_data,
2885 eval0.template values<0, false, false>(gradients_quad +
2887 values_dofs + n_dofs);
2888 eval0.template gradients<0, false, false>(gradients_quad,
2891 eval0.template values<0, false, true>(values_quad,
2895 values_dofs[0] = values_quad[0];
2896 values_dofs[1] = gradients_quad[0];
2901 values_dofs += 3 * n_dofs;
2902 values_quad += n_q_points;
2903 gradients_quad += dim * n_q_points;
2908 values_dofs = values_dofs_ptr;
2909 for (
unsigned int c = 0; c < n_components; ++c)
2915 eval1.template values<1, false, false>(hessians_quad,
2919 eval0.template hessians<0, false, true>(scratch_data,
2922 eval0.template hessians<0, false, false>(scratch_data,
2926 eval1.template hessians<1, false, false>(hessians_quad +
2929 eval0.template values<0, false, true>(scratch_data,
2933 eval1.template values<1, false, false>(hessians_quad +
2936 eval0.template values<0, false, false>(scratch_data,
2941 eval1.template gradients<1, false, false>(hessians_quad +
2944 eval0.template gradients<0, false, true>(scratch_data,
2948 eval1.template values<1, false, false>(hessians_quad +
2952 eval0.template gradients<0, false, true>(scratch_data,
2956 eval0.template gradients<0, false, false>(scratch_data,
2961 eval1.template gradients<1, false, false>(hessians_quad +
2964 eval0.template values<0, false, true>(scratch_data,
2965 values_dofs + n_dofs);
2972 eval0.template hessians<0, false, true>(hessians_quad,
2975 eval0.template hessians<0, false, false>(hessians_quad,
2979 eval0.template values<0, false, false>(
2980 hessians_quad + n_q_points, values_dofs + 2 * n_dofs);
2983 eval0.template gradients<0, false, true>(
2984 hessians_quad + 2 * n_q_points, values_dofs + n_dofs);
2986 eval0.template gradients<0, false, false>(
2987 hessians_quad + 2 * n_q_points, values_dofs + n_dofs);
2990 values_dofs[2] = hessians_quad[0];
2999 values_dofs += 3 * n_dofs;
3000 hessians_quad += dim * (dim + 1) / 2 * n_q_points;
3006 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
3014 template <
typename EvalType>
3018 const unsigned int subface_index,
3019 const unsigned int direction)
3027 const unsigned int index =
3028 direction == 0 ? subface_index % 2 : subface_index / 2;
3035 template <
bool integrate>
3039 Number * values_dofs,
3041 Number * scratch_data,
3042 const unsigned int subface_index,
3043 const unsigned int face_no)
3045 const unsigned int face_direction = face_no / 2;
3065 evaluate_in_face_apply<0>(values_dofs,
3071 std::integral_constant<bool, integrate>());
3074 evaluate_in_face_apply<1>(values_dofs,
3080 std::integral_constant<bool, integrate>());
3082 evaluate_in_face_apply<2>(values_dofs,
3088 std::integral_constant<bool, integrate>());
3099 template <
int normal_dir>
3102 Number * values_dofs,
3104 Number * scratch_data,
3106 const unsigned int face_direction,
3107 const unsigned int subface_index,
3108 std::integral_constant<bool, false>)
3113 (fe_degree == -1) ? 1 : fe_degree + 1,
3120 (fe_degree == -1) ? 1 : fe_degree,
3125 using TempEval0 =
typename std::
3126 conditional<normal_dir == 0, EvalNormal, EvalTangent>::type;
3127 using TempEval1 =
typename std::
3128 conditional<normal_dir == 0, EvalTangent, EvalNormal>::type;
3129 using Eval0 =
typename std::
3130 conditional<normal_dir == 2, EvalGeneral, TempEval0>::type;
3131 using Eval1 =
typename std::
3132 conditional<normal_dir == 2, EvalGeneral, TempEval1>::type;
3136 Eval0 eval0 = create_evaluator_tensor_product<Eval0>(
3137 ((normal_dir == 0) ? shape_info.
data[0] : shape_info.
data[1]),
3140 Eval1 eval1 = create_evaluator_tensor_product<Eval1>(
3141 ((normal_dir == 1) ? shape_info.
data[0] : shape_info.
data[1]),
3145 constexpr std::size_t n_q_points =
Utilities::pow(n_q_points_1d, dim - 1);
3147 const std::size_t n_dofs_normal =
3149 const std::size_t dofs_stride =
3150 (std::is_same<Eval0, EvalGeneral>::value) ? n_dofs_normal :
3153 static constexpr ::ndarray<unsigned int, 3, 3> component_table = {
3154 {{{1, 2, 0}}, {{2, 0, 1}}, {{0, 1, 2}}}};
3155 const unsigned int component =
3156 (dim == 2 && normal_dir == 0 && face_direction == 1) ?
3158 component_table[face_direction][normal_dir];
3162 3 * ((component == 0) ?
3165 ((face_direction == 0) ? n_dofs_normal : n_dofs_tangent) :
3166 ((face_direction == 2) ? n_dofs_tangent + n_dofs_tangent :
3167 n_dofs_normal + n_dofs_tangent)));
3168 const unsigned int shift = (dim == 2) ? normal_dir / 2 : normal_dir;
3169 Number *values_quad = fe_eval.
begin_values() + n_q_points * shift;
3170 Number *gradients_quad =
3172 Number *hessians_quad =
3173 fe_eval.
begin_hessians() + dim * (dim + 1) / 2 * n_q_points * shift;
3182 eval0.template values<0, true, false>(values_dofs, values_quad);
3183 eval1.template values<1, true, false>(values_quad, values_quad);
3186 eval0.template values<0, true, false>(values_dofs, values_quad);
3198 eval0.template gradients<0, true, false>(values_dofs,
3200 eval1.template values<1, true, false>(scratch_data,
3204 eval0.template values<0, true, false>(values_dofs,
3206 eval1.template gradients<1, true, false>(scratch_data,
3211 eval1.template values<1, true, false>(scratch_data,
3215 eval0.template values<0, true, false>(values_dofs + dofs_stride,
3217 eval1.template values<1, true, false>(scratch_data,
3223 eval0.template values<0, true, false>(values_dofs + dofs_stride,
3226 eval0.template gradients<0, true, false>(values_dofs,
3229 eval0.template values<0, true, false>(values_dofs,
3243 eval0.template hessians<0, true, false>(values_dofs,
3245 eval1.template values<1, true, false>(scratch_data,
3249 eval0.template values<0, true, false>(values_dofs,
3251 eval1.template hessians<1, true, false>(scratch_data,
3256 eval0.template values<0, true, false>(values_dofs +
3259 eval1.template values<1, true, false>(scratch_data,
3264 eval0.template gradients<0, true, false>(values_dofs,
3266 eval1.template gradients<1, true, false>(scratch_data,
3271 eval0.template gradients<0, true, false>(values_dofs +
3274 eval1.template values<1, true, false>(scratch_data,
3279 eval0.template values<0, true, false>(values_dofs + dofs_stride,
3281 eval1.template gradients<1, true, false>(scratch_data,
3288 eval0.template hessians<0, true, false>(values_dofs,
3291 eval0.template values<0, true, false>(
3292 values_dofs + 2 * dofs_stride, hessians_quad + n_q_points);
3294 eval0.template gradients<0, true, false>(
3295 values_dofs + dofs_stride, hessians_quad + 2 * n_q_points);
3303 template <
int normal_dir>
3306 Number * values_dofs,
3308 Number * scratch_data,
3310 const unsigned int face_direction,
3311 const unsigned int subface_index,
3312 std::integral_constant<bool, true>)
3317 (fe_degree == -1) ? 1 : fe_degree + 1,
3324 (fe_degree == -1) ? 1 : fe_degree,
3329 using TempEval0 =
typename std::
3330 conditional<normal_dir == 0, EvalNormal, EvalTangent>::type;
3331 using TempEval1 =
typename std::
3332 conditional<normal_dir == 0, EvalTangent, EvalNormal>::type;
3333 using Eval0 =
typename std::
3334 conditional<normal_dir == 2, EvalGeneral, TempEval0>::type;
3335 using Eval1 =
typename std::
3336 conditional<normal_dir == 2, EvalGeneral, TempEval1>::type;
3340 Eval0 eval0 = create_evaluator_tensor_product<Eval0>(
3341 ((normal_dir == 0) ? shape_info.
data[0] : shape_info.
data[1]),
3344 Eval1 eval1 = create_evaluator_tensor_product<Eval1>(
3345 ((normal_dir == 1) ? shape_info.
data[0] : shape_info.
data[1]),
3349 constexpr std::size_t n_q_points =
Utilities::pow(n_q_points_1d, dim - 1);
3351 const std::size_t n_dofs_normal =
3353 const std::size_t dofs_stride =
3354 (std::is_same<Eval0, EvalGeneral>::value) ? n_dofs_normal :
3357 static constexpr ::ndarray<unsigned int, 3, 3> component_table = {
3358 {{{1, 2, 0}}, {{2, 0, 1}}, {{0, 1, 2}}}};
3359 const unsigned int component =
3360 (dim == 2 && normal_dir == 0 && face_direction == 1) ?
3362 component_table[face_direction][normal_dir];
3366 3 * ((component == 0) ?
3369 ((face_direction == 0) ? n_dofs_normal : n_dofs_tangent) :
3370 ((face_direction == 2) ? n_dofs_tangent + n_dofs_tangent :
3371 n_dofs_normal + n_dofs_tangent)));
3372 const unsigned int shift = (dim == 2) ? normal_dir / 2 : normal_dir;
3373 Number *values_quad = fe_eval.
begin_values() + n_q_points * shift;
3374 Number *gradients_quad =
3376 Number *hessians_quad =
3377 fe_eval.
begin_hessians() + dim * (dim + 1) / 2 * n_q_points * shift;
3386 eval1.template values<1, false, false>(values_quad,
3388 eval0.template values<0, false, false>(values_quad,
3392 eval0.template values<0, false, false>(values_quad,
3405 eval1.template values<1, false, false>(gradients_quad +
3409 eval0.template values<0, false, false>(
3410 gradients_quad + 2 * n_q_points, values_dofs + dofs_stride);
3414 eval1.template values<1, false, false>(values_quad,
3416 eval1.template gradients<1, false, true>(gradients_quad +
3421 eval1.template gradients<1, false, false>(gradients_quad +
3426 eval0.template values<0, false, false>(scratch_data,
3430 eval1.template values<1, false, false>(gradients_quad,
3432 eval0.template gradients<0, false, true>(scratch_data,
3437 eval0.template values<0, false, false>(
3438 gradients_quad + n_q_points, values_dofs + dofs_stride);
3439 eval0.template gradients<0, false, false>(gradients_quad,
3442 eval0.template values<0, false, true>(values_quad,
3456 eval1.template values<1, false, false>(hessians_quad,
3458 if ((evaluation_flag &
3460 eval0.template hessians<0, false, true>(scratch_data,
3463 eval0.template hessians<0, false, false>(scratch_data,
3467 eval1.template hessians<1, false, false>(hessians_quad +
3470 eval0.template values<0, false, true>(scratch_data,
3474 eval1.template values<1, false, false>(hessians_quad +
3477 eval0.template values<0, false, false>(scratch_data,
3482 eval1.template gradients<1, false, false>(hessians_quad +
3485 eval0.template gradients<0, false, true>(scratch_data,
3489 eval1.template values<1, false, false>(hessians_quad +
3493 eval0.template gradients<0, false, true>(scratch_data,
3497 eval0.template gradients<0, false, false>(scratch_data,
3502 eval1.template gradients<1, false, false>(hessians_quad +
3505 eval0.template values<0, false, true>(scratch_data,
3512 if (evaluation_flag &
3514 eval0.template hessians<0, false, true>(hessians_quad,
3517 eval0.template hessians<0, false, false>(hessians_quad,
3521 eval0.template values<0, false, false>(
3522 hessians_quad + n_q_points, values_dofs + 2 * dofs_stride);
3525 eval0.template gradients<0, false, true>(
3526 hessians_quad + 2 * n_q_points, values_dofs + dofs_stride);
3528 eval0.template gradients<0, false, false>(
3529 hessians_quad + 2 * n_q_points, values_dofs + dofs_stride);
3539 template <
int dim,
int fe_degree,
typename Number>
3542 template <
bool do_evaluate,
bool add_
into_output>
3547 const Number * input,
3549 const unsigned int face_no)
3551 Assert(
static_cast<unsigned int>(fe_degree) ==
3552 shape_info.
data.front().fe_degree ||
3556 interpolate_generic_raviart_thomas<do_evaluate, add_into_output>(
3557 n_components, input, output, flags, face_no, shape_info);
3559 interpolate_generic<do_evaluate, add_into_output>(
3565 shape_info.
data.front().fe_degree + 1,
3566 shape_info.
data.front().shape_data_on_face,
3574 template <
bool do_evaluate,
bool add_
into_output>
3577 const unsigned int n_components,
3580 const Number * input,
3582 const unsigned int face_no)
3584 Assert(
static_cast<unsigned int>(fe_degree + 1) ==
3585 shape_info.
data.front().n_q_points_1d ||
3589 interpolate_generic<do_evaluate, add_into_output>(
3595 shape_info.
data.front().quadrature.size(),
3596 shape_info.
data.front().quadrature_data_on_face,
3602 template <
bool do_evaluate,
bool add_
into_output,
int face_direction = 0>
3605 const Number * input,
3608 const unsigned int face_no,
3609 const unsigned int n_points_1d,
3611 const unsigned int dofs_per_component_on_cell,
3612 const unsigned int dofs_per_component_on_face)
3614 if (face_direction == face_no / 2)
3621 evalf(shape_data[face_no % 2],
3627 const unsigned int in_stride = do_evaluate ?
3628 dofs_per_component_on_cell :
3629 dofs_per_component_on_face;
3630 const unsigned int out_stride = do_evaluate ?
3631 dofs_per_component_on_face :
3632 dofs_per_component_on_cell;
3634 for (
unsigned int c = 0; c < n_components; ++c)
3637 evalf.template apply_face<face_direction,
3642 evalf.template apply_face<face_direction,
3647 evalf.template apply_face<face_direction,
3652 output += out_stride;
3655 else if (face_direction < dim)
3659 std::min(face_direction + 1, dim - 1)>(
3667 dofs_per_component_on_cell,
3668 dofs_per_component_on_face);
3672 template <
typename EvalType>
3676 const unsigned int face_no)
3683 template <
bool do_evaluate,
3684 bool add_into_output,
3685 int face_direction = 0,
3686 int max_derivative = 0>
3689 const unsigned int n_components,
3690 const Number * input,
3693 const unsigned int face_no,
3705 bool increase_max_der =
false;
3708 increase_max_der =
true;
3710 if (face_direction == face_no / 2 && !increase_max_der)
3716 shape_info, face_no, input, output);
3718 else if (face_direction == face_no / 2)
3725 n_components, input, output, flag, face_no, shape_info);
3727 else if (face_direction < dim)
3729 if (increase_max_der)
3734 std::min(face_direction + 1, dim - 1),
3736 n_components, input, output, flag, face_no, shape_info);
3745 n_components, input, output, flag, face_no, shape_info);
3751 template <
bool do_evaluate,
3752 bool add_into_output,
3758 const unsigned int face_no,
3759 const Number * input,
3765 using Evalf0 =
typename std::conditional<
3766 face_direction == 0,
3769 (fe_degree == -1) ? 1 : fe_degree + 1,
3775 (fe_degree == -1) ? 1 : fe_degree,
3779 using Evalf1 =
typename std::conditional<
3780 face_direction == 1,
3783 (fe_degree == -1) ? 1 : fe_degree + 1,
3789 (fe_degree == -1) ? 1 : fe_degree,
3793 using Evalf2 =
typename std::conditional<
3794 face_direction == 2,
3797 (fe_degree == -1) ? 1 : fe_degree + 1,
3803 (fe_degree == -1) ? 1 : fe_degree,
3809 create_evaluator_tensor_product<Evalf0>((face_direction == 0) ?
3810 shape_info.
data[0] :
3814 create_evaluator_tensor_product<Evalf1>((face_direction == 1) ?
3815 shape_info.
data[0] :
3819 create_evaluator_tensor_product<Evalf2>((face_direction == 2) ?
3820 shape_info.
data[0] :
3824 const unsigned int dofs_per_component_on_cell =
3826 const unsigned int dofs_per_component_on_face =
3832 const unsigned int in_stride =
3833 do_evaluate ? dofs_per_component_on_cell : dofs_per_component_on_face;
3834 const unsigned int out_stride =
3835 do_evaluate ? dofs_per_component_on_face : dofs_per_component_on_cell;
3837 const unsigned int in_stride_after_normal =
3839 dofs_per_component_on_cell :
3840 dofs_per_component_on_face - 3 *
Utilities::pow(fe_degree, dim - 2);
3841 const unsigned int out_stride_after_normal =
3843 dofs_per_component_on_face - 3 *
Utilities::pow(fe_degree, dim - 2) :
3844 dofs_per_component_on_cell;
3846 evalf0.template apply_face<face_direction,
3849 max_derivative>(input, output);
3851 input += (face_direction == 0) ? in_stride_after_normal : in_stride;
3852 output += (face_direction == 0) ? out_stride_after_normal : out_stride;
3854 evalf1.template apply_face<face_direction,
3857 max_derivative>(input, output);
3862 input += (face_direction == 1) ? in_stride_after_normal : in_stride;
3864 (face_direction == 1) ? out_stride_after_normal : out_stride;
3866 evalf2.template apply_face<face_direction,
3869 max_derivative>(input, output);
3877 template <
typename VectorizedArrayType,
typename Number2>
3881 for (
unsigned int v = 0; v < VectorizedArrayType::size(); ++v)
3882 dst[v] = src_ptr[v];
3889 template <
typename Number, std::
size_t w
idth>
3899 template <
typename VectorizedArrayType,
typename Number2>
3902 const unsigned int * indices,
3903 VectorizedArrayType &dst)
3905 for (
unsigned int v = 0; v < VectorizedArrayType::size(); ++v)
3906 dst[v] = src_ptr[indices[v]];
3913 template <
typename Number, std::
size_t w
idth>
3916 const unsigned int * indices,
3919 dst.
gather(src_ptr, indices);
3925 template <
typename VectorizedArrayType,
typename Number2>
3929 for (
unsigned int v = 0; v < VectorizedArrayType::size(); ++v)
3930 dst_ptr[v] += src[v];
3937 template <
typename Number, std::
size_t w
idth>
3943 (tmp + src).store(dst_ptr);
3949 template <
typename VectorizedArrayType,
typename Number2>
3952 const unsigned int * indices,
3955 for (
unsigned int v = 0; v < VectorizedArrayType::size(); ++v)
3956 dst_ptr[indices[v]] += src[v];
3963 template <
typename Number, std::
size_t w
idth>
3966 const unsigned int * indices,
3969#if DEAL_II_VECTORIZATION_WIDTH_IN_BITS < 512
3970 for (
unsigned int v = 0; v < width; ++v)
3971 dst_ptr[indices[v]] += src[v];
3974 tmp.
gather(dst_ptr, indices);
3975 (tmp + src).scatter(indices, dst_ptr);
3981 template <
typename Number>
3984 const unsigned int n_components,
3986 const unsigned int *orientation,
3987 const bool integrate,
3988 const std::size_t n_q_points,
3989 Number * tmp_values,
3990 Number * values_quad,
3991 Number * gradients_quad,
3992 Number * hessians_quad)
3994 for (
unsigned int c = 0; c < n_components; ++c)
3999 for (
unsigned int q = 0; q < n_q_points; ++q)
4000 tmp_values[q] = values_quad[c * n_q_points + orientation[q]];
4002 for (
unsigned int q = 0; q < n_q_points; ++q)
4003 tmp_values[orientation[q]] = values_quad[c * n_q_points + q];
4004 for (
unsigned int q = 0; q < n_q_points; ++q)
4005 values_quad[c * n_q_points + q] = tmp_values[q];
4008 for (
unsigned int d = 0; d < dim; ++d)
4011 for (
unsigned int q = 0; q < n_q_points; ++q)
4013 gradients_quad[(c * dim + d) * n_q_points + orientation[q]];
4015 for (
unsigned int q = 0; q < n_q_points; ++q)
4016 tmp_values[orientation[q]] =
4017 gradients_quad[(c * dim + d) * n_q_points + q];
4018 for (
unsigned int q = 0; q < n_q_points; ++q)
4019 gradients_quad[(c * dim + d) * n_q_points + q] = tmp_values[q];
4023 const unsigned int hdim = (dim * (dim + 1)) / 2;
4024 for (
unsigned int d = 0; d < hdim; ++d)
4027 for (
unsigned int q = 0; q < n_q_points; ++q)
4028 tmp_values[q] = hessians_quad[(c * hdim + d) * n_q_points +
4031 for (
unsigned int q = 0; q < n_q_points; ++q)
4032 tmp_values[orientation[q]] =
4033 hessians_quad[(c * hdim + d) * n_q_points + q];
4034 for (
unsigned int q = 0; q < n_q_points; ++q)
4035 hessians_quad[(c * hdim + d) * n_q_points + q] =
4044 template <
typename Number,
typename VectorizedArrayType>
4047 const unsigned int dim,
4048 const unsigned int n_components,
4049 const unsigned int v,
4051 const unsigned int * orientation,
4052 const bool integrate,
4053 const std::size_t n_q_points,
4054 Number * tmp_values,
4055 VectorizedArrayType * values_quad,
4056 VectorizedArrayType * gradients_quad =
nullptr,
4057 VectorizedArrayType * hessians_quad =
nullptr)
4059 for (
unsigned int c = 0; c < n_components; ++c)
4064 for (
unsigned int q = 0; q < n_q_points; ++q)
4065 tmp_values[q] = values_quad[c * n_q_points + orientation[q]][v];
4067 for (
unsigned int q = 0; q < n_q_points; ++q)
4068 tmp_values[orientation[q]] = values_quad[c * n_q_points + q][v];
4069 for (
unsigned int q = 0; q < n_q_points; ++q)
4070 values_quad[c * n_q_points + q][v] = tmp_values[q];
4073 for (
unsigned int d = 0; d < dim; ++d)
4077 for (
unsigned int q = 0; q < n_q_points; ++q)
4078 tmp_values[q] = gradients_quad[(c * dim + d) * n_q_points +
4081 for (
unsigned int q = 0; q < n_q_points; ++q)
4082 tmp_values[orientation[q]] =
4083 gradients_quad[(c * dim + d) * n_q_points + q][v];
4084 for (
unsigned int q = 0; q < n_q_points; ++q)
4085 gradients_quad[(c * dim + d) * n_q_points + q][v] =
4091 const unsigned int hdim = (dim * (dim + 1)) / 2;
4092 for (
unsigned int d = 0; d < hdim; ++d)
4095 for (
unsigned int q = 0; q < n_q_points; ++q)
4096 tmp_values[q] = hessians_quad[(c * hdim + d) * n_q_points +
4099 for (
unsigned int q = 0; q < n_q_points; ++q)
4100 tmp_values[orientation[q]] =
4101 hessians_quad[(c * hdim + d) * n_q_points + q][v];
4102 for (
unsigned int q = 0; q < n_q_points; ++q)
4103 hessians_quad[(c * hdim + d) * n_q_points + q][v] =
4112 template <
int dim,
typename Number>
4115 template <
int fe_degree,
int n_q_po
ints_1d>
4117 run(
const unsigned int n_components,
4119 const Number * values_dofs,
4123 const auto &shape_data = shape_info.
data.front();
4132 const unsigned int face_no = fe_eval.
get_face_no();
4134 const std::size_t n_dofs = shape_info.dofs_per_component_on_cell;
4135 const std::size_t n_q_points = shape_info.n_q_points_faces[face_no];
4142 const auto shape_values =
4143 &shape_data.shape_values_face(face_no, face_orientation, 0);
4146 auto values_dofs_actual_ptr = values_dofs;
4148 Eval eval(shape_values,
nullptr,
nullptr, n_dofs, n_q_points);
4149 for (
unsigned int c = 0; c < n_components; ++c)
4151 eval.template values<0, true, false>(values_dofs_actual_ptr,
4154 values_quad_ptr += n_q_points;
4155 values_dofs_actual_ptr += n_dofs;
4162 auto values_dofs_actual_ptr = values_dofs;
4164 std::array<const Number *, dim> shape_gradients;
4165 for (
unsigned int d = 0; d < dim; ++d)
4166 shape_gradients[d] = &shape_data.shape_gradients_face(
4167 face_no, face_orientation, d, 0);
4169 for (
unsigned int c = 0; c < n_components; ++c)
4171 for (
unsigned int d = 0; d < dim; ++d)
4179 eval.template gradients<0, true, false>(
4180 values_dofs_actual_ptr, gradients_quad_ptr);
4182 gradients_quad_ptr += n_q_points;
4184 values_dofs_actual_ptr += n_dofs;
4194 const unsigned int dofs_per_face =
4201 Number *scratch_data = temp + 3 * n_components * dofs_per_face;
4203 bool use_vectorization =
true;
4212 [&](
const auto &v) {
4213 return v == fe_eval.get_cell_ids()[0] ||
4214 v == numbers::invalid_unsigned_int;
4217 if (use_vectorization ==
false)
4219 for (
unsigned int v = 0; v < Number::size(); ++v)
4226 for (
unsigned int i = 0; i < 3 * n_components * dofs_per_face;
4233 template interpolate<true, false>(n_components,
4240 for (
unsigned int i = 0; i < 3 * n_components * dofs_per_face;
4242 temp[i][v] = scratch_data[i][v];
4247 template interpolate<true, false>(n_components,
4255 constexpr unsigned int n_q_points_1d_actual =
4256 fe_degree > -1 ? n_q_points_1d : 0;
4258 if (fe_degree >= 1 &&
4262 (fe_degree == -1) ? 1 : fe_degree,
4263 (n_q_points_1d < 1) ? 1 :
4266 template evaluate_or_integrate_in_face<false>(
4274 else if (fe_degree > -1 &&
4280 n_q_points_1d_actual,
4281 Number>::evaluate_in_face(n_components,
4295 n_q_points_1d_actual,
4296 Number>::evaluate_in_face(n_components,
4307 if (use_vectorization ==
false)
4309 for (
unsigned int v = 0; v < Number::size(); ++v)
4326 shape_info.n_q_points_face,
4341 shape_info.n_q_points_face,
4353 template <
int dim,
typename Number>
4356 template <
int fe_degree,
int n_q_po
ints_1d>
4358 run(
const unsigned int n_components,
4360 Number * values_dofs,
4364 const auto &shape_data = shape_info.
data.front();
4373 const unsigned int face_no = fe_eval.
get_face_no();
4375 const std::size_t n_dofs = shape_info.dofs_per_component_on_cell;
4376 const std::size_t n_q_points = shape_info.n_q_points_faces[face_no];
4383 const auto shape_values =
4384 &shape_data.shape_values_face(face_no, face_orientation, 0);
4387 auto values_dofs_actual_ptr = values_dofs;
4389 Eval eval(shape_values,
nullptr,
nullptr, n_dofs, n_q_points);
4390 for (
unsigned int c = 0; c < n_components; ++c)
4392 eval.template values<0, false, false>(values_quad_ptr,
4393 values_dofs_actual_ptr);
4395 values_quad_ptr += n_q_points;
4396 values_dofs_actual_ptr += n_dofs;
4403 auto values_dofs_actual_ptr = values_dofs;
4405 std::array<const Number *, dim> shape_gradients;
4406 for (
unsigned int d = 0; d < dim; ++d)
4407 shape_gradients[d] = &shape_data.shape_gradients_face(
4408 face_no, face_orientation, d, 0);
4410 for (
unsigned int c = 0; c < n_components; ++c)
4412 for (
unsigned int d = 0; d < dim; ++d)
4422 eval.template gradients<0, false, false>(
4423 gradients_quad_ptr, values_dofs_actual_ptr);
4425 eval.template gradients<0, false, true>(
4426 gradients_quad_ptr, values_dofs_actual_ptr);
4428 gradients_quad_ptr += n_q_points;
4430 values_dofs_actual_ptr += n_dofs;
4440 const unsigned int dofs_per_face =
4445 Number *scratch_data = temp + 3 * n_components * dofs_per_face;
4447 bool use_vectorization =
true;
4456 [&](
const auto &v) {
4457 return v == fe_eval.get_cell_ids()[0] ||
4458 v == numbers::invalid_unsigned_int;
4461 if (use_vectorization ==
false)
4463 for (
unsigned int v = 0; v < Number::size(); ++v)
4480 shape_info.n_q_points_face,
4495 shape_info.n_q_points_face,
4501 const unsigned int n_q_points_1d_actual =
4502 fe_degree > -1 ? n_q_points_1d : 0;
4505 if (fe_degree >= 1 &&
4509 (fe_degree == -1) ? 1 : fe_degree,
4510 (n_q_points_1d < 1) ? 1 :
4513 template evaluate_or_integrate_in_face<true>(integration_flag,
4520 else if (fe_degree > -1 &&
4528 n_q_points_1d_actual,
4529 Number>::integrate_in_face(n_components,
4543 n_q_points_1d_actual,
4544 Number>::integrate_in_face(n_components,
4554 if (use_vectorization ==
false)
4556 for (
unsigned int v = 0; v < Number::size(); ++v)
4565 template interpolate<false, false>(n_components,
4572 for (
unsigned int i = 0; i < 3 * n_components * dofs_per_face;
4574 temp[i][v] = scratch_data[i][v];
4579 template interpolate<false, false>(n_components,
4591 template <
int n_face_orientations,
4593 typename EvaluationData,
4594 const bool check_face_orientations =
false>
4598 const unsigned int n_components,
4600 typename Processor::Number2_ * global_vector_ptr,
4602 const EvaluationData & fe_eval,
4603 typename Processor::VectorizedArrayType_ * temp1)
4605 constexpr int dim = Processor::dim_;
4606 constexpr int fe_degree = Processor::fe_degree_;
4607 using VectorizedArrayType =
typename Processor::VectorizedArrayType_;
4608 constexpr int n_lanes = VectorizedArrayType::size();
4610 using Number =
typename Processor::Number_;
4611 using Number2_ =
typename Processor::Number2_;
4613 const auto & shape_data = fe_eval.get_shape_info().data.front();
4614 constexpr bool integrate = Processor::do_integrate;
4615 const unsigned int face_no = fe_eval.get_face_no();
4616 const auto & dof_info = fe_eval.get_dof_info();
4617 const unsigned int cell = fe_eval.get_cell_or_face_batch_id();
4619 fe_eval.get_dof_access_index();
4621 dof_info.index_storage_variants[dof_access_index].size());
4622 constexpr unsigned int dofs_per_face =
4624 const unsigned int subface_index = fe_eval.get_subface_index();
4626 const unsigned int n_filled_lanes =
4627 dof_info.n_vectorization_lanes_filled[dof_access_index][cell];
4629 bool all_faces_are_same = n_filled_lanes == n_lanes;
4630 if (n_face_orientations == n_lanes)
4631 for (
unsigned int v = 1; v < n_lanes; ++v)
4632 if (fe_eval.get_face_no(v) != fe_eval.get_face_no(0) ||
4633 fe_eval.get_face_orientation(v) != fe_eval.get_face_orientation(0))
4635 all_faces_are_same =
false;
4640 std::array<const unsigned int *, n_face_orientations> orientation = {};
4642 if (dim == 3 && n_face_orientations == n_lanes && !all_faces_are_same &&
4643 fe_eval.is_interior_face() == 0)
4644 for (
unsigned int v = 0; v < n_lanes; ++v)
4652 if (shape_data.nodal_at_cell_boundaries &&
4653 fe_eval.get_face_orientation(v) != 0)
4658 check_face_orientations ==
false)
4672 orientation[v] = &fe_eval.get_shape_info().face_orientations_dofs(
4673 fe_eval.get_face_orientation(v), 0);
4676 else if (dim == 3 && fe_eval.get_face_orientation() != 0)
4680 check_face_orientations ==
false)
4694 for (
unsigned int v = 0; v < n_face_orientations; ++v)
4695 orientation[v] = &fe_eval.get_shape_info().face_orientations_dofs(
4696 fe_eval.get_face_orientation(), 0);
4702 VectorizedArrayType grad_weight =
4704 .shape_data_on_face[0][fe_degree + (integrate ? (2 - face_no % 2) :
4705 (1 + face_no % 2))];
4708 std::array<const unsigned int *, n_face_orientations> index_array_hermite =
4712 if (n_face_orientations == 1)
4713 index_array_hermite[0] =
4714 &fe_eval.get_shape_info().face_to_cell_index_hermite(face_no, 0);
4717 for (
unsigned int v = 0; v < n_lanes; ++v)
4722 const auto face_no = fe_eval.get_face_no(v);
4725 shape_data.shape_data_on_face[0][fe_degree +
4727 (2 - (face_no % 2)) :
4728 (1 + (face_no % 2)))][0];
4730 index_array_hermite[v] =
4731 &fe_eval.get_shape_info().face_to_cell_index_hermite(face_no,
4738 std::array<const unsigned int *, n_face_orientations> index_array_nodal =
4740 if (shape_data.nodal_at_cell_boundaries ==
true)
4742 if (n_face_orientations == 1)
4743 index_array_nodal[0] =
4744 &fe_eval.get_shape_info().face_to_cell_index_nodal(face_no, 0);
4747 for (
unsigned int v = 0; v < n_lanes; ++v)
4752 const auto face_no = fe_eval.get_face_no(v);
4754 index_array_nodal[v] =
4755 &fe_eval.get_shape_info().face_to_cell_index_nodal(face_no,
4762 const auto reorientate = [&](
const unsigned int v,
const unsigned int i) {
4763 return (!check_face_orientations || orientation[v] ==
nullptr) ?
4770 fe_eval.get_cell_ids()[0] :
4772 const unsigned int *dof_indices =
4773 &dof_info.dof_indices_contiguous[dof_access_index][
cell_index];
4775 for (
unsigned int comp = 0; comp < n_components; ++comp)
4777 const std::size_t index_offset =
4778 dof_info.component_dof_indices_offset
4779 [fe_eval.get_active_fe_index()]
4780 [fe_eval.get_first_selected_component()] +
4784 if (n_face_orientations == 1 &&
4785 dof_info.index_storage_variants[dof_access_index][cell] ==
4787 interleaved_contiguous)
4790 dof_info.n_vectorization_lanes_filled[dof_access_index][cell],
4792 Number2_ *vector_ptr =
4793 global_vector_ptr + dof_indices[0] + index_offset * n_lanes;
4797 for (
unsigned int i = 0; i < dofs_per_face; ++i)
4801 const unsigned int ind1 = index_array_hermite[0][2 * i];
4802 const unsigned int ind2 = index_array_hermite[0][2 * i + 1];
4803 const unsigned int i_ = reorientate(0, i);
4804 proc.hermite_grad_vectorized(temp1[i_],
4805 temp1[i_ + dofs_per_face],
4806 vector_ptr + ind1 * n_lanes,
4807 vector_ptr + ind2 * n_lanes,
4813 for (
unsigned int i = 0; i < dofs_per_face; ++i)
4817 const unsigned int i_ = reorientate(0, i);
4818 const unsigned int ind = index_array_nodal[0][i];
4819 proc.value_vectorized(temp1[i_],
4820 vector_ptr + ind * n_lanes);
4826 else if (n_face_orientations == 1 &&
4827 dof_info.index_storage_variants[dof_access_index][cell] ==
4829 interleaved_contiguous_strided)
4832 dof_info.n_vectorization_lanes_filled[dof_access_index][cell],
4834 Number2_ *vector_ptr = global_vector_ptr + index_offset * n_lanes;
4837 for (
unsigned int i = 0; i < dofs_per_face; ++i)
4841 const unsigned int i_ = reorientate(0, i);
4842 const unsigned int ind1 =
4843 index_array_hermite[0][2 * i] * n_lanes;
4844 const unsigned int ind2 =
4845 index_array_hermite[0][2 * i + 1] * n_lanes;
4846 proc.hermite_grad_vectorized_indexed(
4848 temp1[i_ + dofs_per_face],
4858 for (
unsigned int i = 0; i < dofs_per_face; ++i)
4862 const unsigned int i_ = reorientate(0, i);
4863 const unsigned int ind = index_array_nodal[0][i] * n_lanes;
4864 proc.value_vectorized_indexed(temp1[i_],
4872 else if (n_face_orientations == 1 &&
4873 dof_info.index_storage_variants[dof_access_index][cell] ==
4875 interleaved_contiguous_mixed_strides)
4877 const unsigned int *strides =
4878 &dof_info.dof_indices_interleave_strides[dof_access_index]
4880 unsigned int indices[n_lanes];
4881 for (
unsigned int v = 0; v < n_lanes; ++v)
4882 indices[v] = dof_indices[v] + index_offset * strides[v];
4883 const unsigned int n_filled_lanes =
4884 dof_info.n_vectorization_lanes_filled[dof_access_index][cell];
4888 if (n_filled_lanes == n_lanes)
4889 for (
unsigned int i = 0; i < dofs_per_face; ++i)
4893 const unsigned int i_ = reorientate(0, i);
4894 unsigned int ind1[n_lanes];
4896 for (
unsigned int v = 0; v < n_lanes; ++v)
4897 ind1[v] = indices[v] +
4898 index_array_hermite[0][2 * i] * strides[v];
4899 unsigned int ind2[n_lanes];
4901 for (
unsigned int v = 0; v < n_lanes; ++v)
4905 index_array_hermite[0][2 * i + 1] * strides[v];
4906 proc.hermite_grad_vectorized_indexed(
4908 temp1[i_ + dofs_per_face],
4917 if (integrate ==
false)
4918 for (
unsigned int i = 0; i < 2 * dofs_per_face; ++i)
4919 temp1[i] = VectorizedArrayType();
4921 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
4922 for (
unsigned int i = 0; i < dofs_per_face; ++i)
4924 const unsigned int i_ =
4925 reorientate(n_face_orientations == 1 ? 0 : v, i);
4928 temp1[i_ + dofs_per_face][v],
4932 [n_face_orientations == 1 ? 0 : v][2 * i] *
4936 index_array_hermite[n_face_orientations == 1 ?
4940 grad_weight[n_face_orientations == 1 ? 0 : v]);
4946 if (n_filled_lanes == n_lanes)
4947 for (
unsigned int i = 0; i < dofs_per_face; ++i)
4950 unsigned int ind[n_lanes];
4952 for (
unsigned int v = 0; v < n_lanes; ++v)
4954 indices[v] + index_array_nodal[0][i] * strides[v];
4955 const unsigned int i_ = reorientate(0, i);
4956 proc.value_vectorized_indexed(temp1[i_],
4962 if (integrate ==
false)
4963 for (
unsigned int i = 0; i < dofs_per_face; ++i)
4964 temp1[i] = VectorizedArrayType();
4966 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
4967 for (
unsigned int i = 0; i < dofs_per_face; ++i)
4969 temp1[reorientate(n_face_orientations == 1 ? 0 : v,
4973 index_array_nodal[n_face_orientations == 1 ? 0 : v]
4981 else if (n_face_orientations > 1 ||
4982 dof_info.index_storage_variants[dof_access_index][cell] ==
4986 Number2_ *vector_ptr = global_vector_ptr + index_offset;
4988 const bool vectorization_possible =
4989 all_faces_are_same && (sm_ptr ==
nullptr);
4991 std::array<Number2_ *, n_lanes> vector_ptrs;
4992 std::array<unsigned int, n_lanes> reordered_indices;
4994 if (vectorization_possible ==
false)
4997 if (n_face_orientations == 1)
4999 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
5000 if (sm_ptr ==
nullptr)
5002 vector_ptrs[v] = vector_ptr + dof_indices[v];
5008 .dof_indices_contiguous_sm[dof_access_index]
5009 [cell * n_lanes + v];
5010 vector_ptrs[v] =
const_cast<Number2_ *
>(
5011 sm_ptr->operator[](temp.first).data() +
5012 temp.second + index_offset);
5015 else if (n_face_orientations == n_lanes)
5017 const auto &cells = fe_eval.get_cell_ids();
5018 for (
unsigned int v = 0; v < n_lanes; ++v)
5021 if (sm_ptr ==
nullptr)
5026 .dof_indices_contiguous[dof_access_index]
5033 .dof_indices_contiguous_sm[dof_access_index]
5035 vector_ptrs[v] =
const_cast<Number2_ *
>(
5036 sm_ptr->operator[](temp.first).data() +
5037 temp.second + index_offset);
5046 else if (n_face_orientations == n_lanes)
5048 for (
unsigned int v = 0; v < n_lanes; ++v)
5049 reordered_indices[v] =
5050 dof_info.dof_indices_contiguous[dof_access_index]
5051 [fe_eval.get_cell_ids()[v]];
5052 dof_indices = reordered_indices.data();
5057 if (vectorization_possible)
5058 for (
unsigned int i = 0; i < dofs_per_face; ++i)
5060 const unsigned int ind1 = index_array_hermite[0][2 * i];
5061 const unsigned int ind2 =
5062 index_array_hermite[0][2 * i + 1];
5063 const unsigned int i_ = reorientate(0, i);
5065 proc.hermite_grad_vectorized_indexed(
5067 temp1[i_ + dofs_per_face],
5074 else if (n_face_orientations == 1)
5075 for (
unsigned int i = 0; i < dofs_per_face; ++i)
5077 const unsigned int ind1 = index_array_hermite[0][2 * i];
5078 const unsigned int ind2 =
5079 index_array_hermite[0][2 * i + 1];
5080 const unsigned int i_ = reorientate(0, i);
5082 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
5083 proc.hermite_grad(temp1[i_][v],
5084 temp1[i_ + dofs_per_face][v],
5085 vector_ptrs[v][ind1],
5086 vector_ptrs[v][ind2],
5089 if (integrate ==
false)
5090 for (
unsigned int v = n_filled_lanes; v < n_lanes; ++v)
5093 temp1[i + dofs_per_face][v] = 0.0;
5098 if (integrate ==
false && n_filled_lanes < n_lanes)
5099 for (
unsigned int i = 0; i < dofs_per_face; ++i)
5100 temp1[i] = temp1[i + dofs_per_face] = Number();
5102 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
5103 for (
unsigned int i = 0; i < dofs_per_face; ++i)
5105 temp1[reorientate(v, i)][v],
5106 temp1[reorientate(v, i) + dofs_per_face][v],
5107 vector_ptrs[v][index_array_hermite[v][2 * i]],
5108 vector_ptrs[v][index_array_hermite[v][2 * i + 1]],
5114 if (vectorization_possible)
5115 for (
unsigned int i = 0; i < dofs_per_face; ++i)
5117 const unsigned int ind = index_array_nodal[0][i];
5118 const unsigned int i_ = reorientate(0, i);
5120 proc.value_vectorized_indexed(temp1[i_],
5124 else if (n_face_orientations == 1)
5125 for (
unsigned int i = 0; i < dofs_per_face; ++i)
5127 const unsigned int ind = index_array_nodal[0][i];
5128 const unsigned int i_ = reorientate(0, i);
5130 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
5131 proc.value(temp1[i_][v], vector_ptrs[v][ind]);
5133 if (integrate ==
false)
5134 for (
unsigned int v = n_filled_lanes; v < n_lanes; ++v)
5139 if (integrate ==
false && n_filled_lanes < n_lanes)
5140 for (
unsigned int i = 0; i < dofs_per_face; ++i)
5141 temp1[i] = Number();
5143 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
5144 for (
unsigned int i = 0; i < dofs_per_face; ++i)
5145 proc.value(temp1[reorientate(v, i)][v],
5146 vector_ptrs[v][index_array_nodal[v][i]]);
5156 temp1 += 3 * dofs_per_face;
5162 template <
int dim,
typename Number2,
typename VectorizedArrayType>
5165 using Number =
typename VectorizedArrayType::value_type;
5167 template <
int fe_degree,
int n_q_po
ints_1d>
5169 run(
const unsigned int n_components,
5171 const Number2 * src_ptr,
5180 const unsigned int dofs_per_face =
Utilities::pow(fe_degree + 1, dim - 1);
5183 VectorizedArrayType *scratch_data =
5184 temp + 3 * n_components * dofs_per_face;
5191 fe_face_evaluation_process_and_io<VectorizedArrayType::size()>(
5192 p, n_components, evaluation_flag, src_ptr, sm_ptr, fe_eval, temp);
5194 fe_face_evaluation_process_and_io<1>(
5195 p, n_components, evaluation_flag, src_ptr, sm_ptr, fe_eval, temp);
5204 VectorizedArrayType>::
5205 evaluate_in_face(n_components,
5219 VectorizedArrayType>::
5220 evaluate_in_face(n_components,
5237 for (
unsigned int v = 0; v < VectorizedArrayType::size(); ++v)
5284 const Number2 * vector_ptr,
5287 const unsigned int fe_degree = shape_info.
data.front().fe_degree;
5288 if (fe_degree < 1 || !shape_info.
data.front().nodal_at_cell_boundaries ||
5291 shape_info.
data.front().element_type !=
5294 vector_ptr ==
nullptr ||
5295 shape_info.
data.front().element_type >
5305 template <
int fe_degree>
5315 template <
typename T0,
typename T1,
typename T2>
5321 const T2 &grad_weight)
5325 temp_2 = grad_weight * (temp_1 - temp_2);
5328 template <
typename T1,
typename T2>
5335 template <
typename T0,
typename T1,
typename T2,
typename T3>
5341 const T2 &grad_weight,
5342 const T3 &indices_1,
5343 const T3 &indices_2)
5347 temp_2 = grad_weight * (temp_1 - temp_2);
5350 template <
typename T0,
typename T1,
typename T2>
5357 template <
typename T0,
typename T1,
typename T2>
5361 const T1 &src_ptr_1,
5362 const T1 &src_ptr_2,
5363 const T2 &grad_weight)
5367 temp_2 = grad_weight * (temp_1 - src_ptr_2);
5370 template <
typename T1,
typename T2>
5382 template <
int dim,
typename Number2,
typename VectorizedArrayType>
5385 using Number =
typename VectorizedArrayType::value_type;
5387 template <
int fe_degree,
int n_q_po
ints_1d>
5389 run(
const unsigned int n_components,
5400 const unsigned int dofs_per_face =
Utilities::pow(fe_degree + 1, dim - 1);
5403 VectorizedArrayType *scratch_data =
5404 temp + 3 * n_components * dofs_per_face;
5414 for (
unsigned int v = 0; v < VectorizedArrayType::size(); ++v)
5458 VectorizedArrayType>::
5459 integrate_in_face(n_components,
5473 VectorizedArrayType>::
5474 integrate_in_face(n_components,
5489 fe_face_evaluation_process_and_io<VectorizedArrayType::size()>(
5490 p, n_components, integration_flag, dst_ptr, sm_ptr, fe_eval, temp);
5492 fe_face_evaluation_process_and_io<1>(
5493 p, n_components, integration_flag, dst_ptr, sm_ptr, fe_eval, temp);
5499 template <
int fe_degree>
5509 template <
typename T0,
typename T1,
typename T2,
typename T3,
typename T4>
5515 const T4 &grad_weight)
5518 const VectorizedArrayType val = temp_1 - grad_weight * temp_2;
5519 const VectorizedArrayType grad = grad_weight * temp_2;
5524 template <
typename T0,
typename T1>
5532 template <
typename T0,
typename T1,
typename T2,
typename T3>
5538 const T2 &grad_weight,
5539 const T3 &indices_1,
5540 const T3 &indices_2)
5543 const VectorizedArrayType val = temp_1 - grad_weight * temp_2;
5544 const VectorizedArrayType grad = grad_weight * temp_2;
5549 template <
typename T0,
typename T1,
typename T2>
5557 template <
typename T0,
typename T1,
typename T2>
5563 const T2 &grad_weight)
5566 const Number val = temp_1 - grad_weight * temp_2;
5567 const Number grad = grad_weight * temp_2;
5572 template <
typename T0,
typename T1>
5588 template <
int dim,
typename Number>
5591 template <
int fe_degree,
int = 0>
5593 run(
const unsigned int n_components,
5595 const Number * in_array,
5597 typename std::enable_if<fe_degree != -1>::type * =
nullptr)
5599 constexpr unsigned int dofs_per_component =
5617 for (
unsigned int d = 0; d < n_components; ++d)
5619 const Number *in = in_array + d * dofs_per_component;
5620 Number * out = out_array + d * dofs_per_component;
5623 evaluator.template hessians<0, true, false>(in, out);
5625 evaluator.template hessians<1, true, false>(out, out);
5627 evaluator.template hessians<2, true, false>(out, out);
5629 for (
unsigned int q = 0; q < dofs_per_component; ++q)
5631 const Number inverse_JxW_q = Number(1.) / fe_eval.
JxW(q);
5632 for (
unsigned int d = 0; d < n_components; ++d)
5633 out_array[q + d * dofs_per_component] *= inverse_JxW_q;
5635 for (
unsigned int d = 0; d < n_components; ++d)
5637 Number *out = out_array + d * dofs_per_component;
5639 evaluator.template hessians<2, false, false>(out, out);
5641 evaluator.template hessians<1, false, false>(out, out);
5642 evaluator.template hessians<0, false, false>(out, out);
5647 template <
int fe_degree,
int = 0>
5649 run(
const unsigned int n_components,
5651 const Number * in_array,
5653 typename std::enable_if<fe_degree == -1>::type * =
nullptr)
5655 static_assert(fe_degree == -1,
"Only usable for degree -1");
5656 const unsigned int dofs_per_component =
5668 for (
unsigned int d = 0; d < n_components; ++d)
5670 const Number *in = in_array + d * dofs_per_component;
5671 Number * out = out_array + d * dofs_per_component;
5674 evaluator.template values<0, true, false>(in, out);
5676 evaluator.template values<1, true, false>(out, out);
5678 evaluator.template values<2, true, false>(out, out);
5680 for (
unsigned int q = 0; q < dofs_per_component; ++q)
5682 const Number inverse_JxW_q = Number(1.) / fe_eval.
JxW(q);
5683 for (
unsigned int d = 0; d < n_components; ++d)
5684 out_array[q + d * dofs_per_component] *= inverse_JxW_q;
5686 for (
unsigned int d = 0; d < n_components; ++d)
5688 Number *out = out_array + d * dofs_per_component;
5690 evaluator.template values<2, false, false>(out, out);
5692 evaluator.template values<1, false, false>(out, out);
5693 evaluator.template values<0, false, false>(out, out);
5705 template <
int dim,
typename Number>
5708 template <
int fe_degree,
int = 0>
5710 run(
const unsigned int n_desired_components,
5713 const Number * in_array,
5715 typename std::enable_if<fe_degree != -1>::type * =
nullptr)
5717 constexpr unsigned int dofs_per_component =
5720 inverse_coefficients.
size() % dofs_per_component == 0,
5722 "Expected diagonal to be a multiple of scalar dof per cells"));
5723 if (inverse_coefficients.
size() != dofs_per_component)
5725 inverse_coefficients.
size());
5738 const unsigned int shift_coefficient =
5739 inverse_coefficients.
size() > dofs_per_component ? dofs_per_component :
5741 const Number *inv_coefficient = inverse_coefficients.
data();
5742 for (
unsigned int d = 0; d < n_desired_components; ++d)
5744 const Number *in = in_array + d * dofs_per_component;
5745 Number * out = out_array + d * dofs_per_component;
5748 evaluator.template hessians<0, true, false>(in, out);
5750 evaluator.template hessians<1, true, false>(out, out);
5752 evaluator.template hessians<2, true, false>(out, out);
5754 for (
unsigned int q = 0; q < dofs_per_component; ++q)
5755 out[q] *= inv_coefficient[q];
5758 evaluator.template hessians<2, false, false>(out, out);
5760 evaluator.template hessians<1, false, false>(out, out);
5761 evaluator.template hessians<0, false, false>(out, out);
5763 inv_coefficient += shift_coefficient;
5771 template <
int fe_degree,
int = 0>
5778 typename std::enable_if<fe_degree == -1>::type * =
nullptr)
5780 static_assert(fe_degree == -1,
"Only usable for degree -1");
5792 template <
int dim,
typename Number>
5795 template <
int fe_degree,
int n_q_po
ints_1d>
5797 run(
const unsigned int n_desired_components,
5799 const Number * in_array,
5802 static const bool do_inplace =
5803 fe_degree > -1 && (fe_degree + 1 == n_q_points_1d);
5809 const auto &inverse_shape =
5814 const std::size_t dofs_per_component =
5817 const std::size_t n_q_points = do_inplace ?
5832 for (
unsigned int d = 0; d < n_desired_components; ++d)
5834 const Number *in = in_array + d * n_q_points;
5835 Number * out = out_array + d * dofs_per_component;
5838 auto temp_2 = do_inplace ?
5840 (temp_1 +
std::max(n_q_points, dofs_per_component));
5844 evaluator.template hessians<2, false, false>(in, temp_1);
5845 evaluator.template hessians<1, false, false>(temp_1, temp_2);
5846 evaluator.template hessians<0, false, false>(temp_2, out);
5850 evaluator.template hessians<1, false, false>(in, temp_1);
5851 evaluator.template hessians<0, false, false>(temp_1, out);
5854 evaluator.template hessians<0, false, false>(in, out);
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
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 Number *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_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 > &)
static bool run(const unsigned int n_components, const FEEvaluationData< dim, Number, false > &fe_eval, const Number *in_array, Number *out_array, typename std::enable_if< fe_degree !=-1 >::type *=nullptr)
static bool run(const unsigned int n_components, const FEEvaluationData< dim, Number, false > &fe_eval, const Number *in_array, Number *out_array, typename std::enable_if< fe_degree==-1 >::type *=nullptr)
static bool run(const unsigned int n_desired_components, const AlignedVector< Number > &inverse_shape, const AlignedVector< Number > &inverse_coefficients, const Number *in_array, Number *out_array, typename std::enable_if< fe_degree !=-1 >::type *=nullptr)
static bool run(const unsigned int, const AlignedVector< Number > &, const AlignedVector< Number > &, const Number *, Number *, typename std::enable_if< fe_degree==-1 >::type *=nullptr)
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_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 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 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_integrate(const MatrixFreeFunctions::UnivariateShapeData< Number > &shape, const EvaluationFlags::EvaluationFlags integration_flag, Number *values_dofs, Number *gradients_quad, const Number *hessians_quad, const bool add_into_values_array)
static void do_evaluate(const MatrixFreeFunctions::UnivariateShapeData< Number > &shape, const EvaluationFlags::EvaluationFlags evaluation_flag, const Number *values_dofs, Number *gradients_quad, Number *hessians_quad)
static void evaluate(const unsigned int n_components, const EvaluationFlags::EvaluationFlags evaluation_flag, const Number *values_dofs, 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, false > &fe_eval)
static bool run(const unsigned int n_components, const EvaluationFlags::EvaluationFlags integration_flag, Number *values_dofs, FEEvaluationData< dim, Number, false > &fe_eval, const bool sum_into_values_array)
static EvalType create_evaluator_tensor_product(const MatrixFreeFunctions::UnivariateShapeData< Number > &shape_data)
static const EvaluatorVariant variant
static Eval create_evaluator_tensor_product(const MatrixFreeFunctions::UnivariateShapeData< Number > *univariate_shape_data)
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)
EvaluatorTensorProduct< variant, dim, fe_degree+1, n_q_points_1d, Number > Eval
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< VectorizedArrayType > &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 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 >)
static EvalType create_evaluator_tensor_product(const MatrixFreeFunctions::UnivariateShapeData< Number > &data, const unsigned int subface_index, const unsigned int direction)
static void evaluate_in_face(const unsigned int n_components, const EvaluationFlags::EvaluationFlags evaluation_flag, const MatrixFreeFunctions::UnivariateShapeData< Number > &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< Number > &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< Number > &data, Number *values_dofs, Number *values_quad, Number *gradients_quad, Number *hessians_quad, Number *scratch_data, const unsigned int subface_index)
EvaluatorTensorProduct< symmetric_evaluate ? evaluate_evenodd :evaluate_general, dim - 1, fe_degree+1, n_q_points_1d, Number > Eval
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< Number >, 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< Number > &shape_info, const Number *input, Number *output, const unsigned int face_no)
static void interpolate_generic_raviart_thomas_apply_face(const MatrixFreeFunctions::ShapeInfo< Number > &shape_info, const unsigned int face_no, const Number *input, Number *output)
static EvalType create_evaluator_tensor_product(const MatrixFreeFunctions::UnivariateShapeData< Number > &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< Number > &shape_info)
static void interpolate_quadrature(const unsigned int n_components, const EvaluationFlags::EvaluationFlags flags, const MatrixFreeFunctions::ShapeInfo< Number > &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