14#ifndef dealii_matrix_free_evaluation_kernels_face_h
15#define dealii_matrix_free_evaluation_kernels_face_h
37 template <
bool symmetric_evaluate,
63 const unsigned int subface_index,
64 const unsigned int direction)
66 if (symmetric_evaluate)
68 data.shape_gradients_eo,
69 data.shape_hessians_eo,
80 const unsigned int index =
81 direction == 0 ? subface_index % 2 : subface_index / 2;
92 const unsigned int n_components,
97 Number *gradients_quad,
98 Number *hessians_quad,
100 const unsigned int subface_index)
105 const std::size_t n_dofs = fe_degree > -1 ?
108 const std::size_t n_q_points =
113 Number *values_dofs_ptr = values_dofs;
117 for (
unsigned int c = 0; c < n_components; ++c)
122 eval0.template values<0, true, false>(values_dofs,
124 eval1.template values<1, true, false>(values_quad,
128 eval0.template values<0, true, false>(values_dofs,
132 values_quad[0] = values_dofs[0];
139 values_dofs += 3 * n_dofs;
140 values_quad += n_q_points;
143 for (
unsigned int c = 0; c < n_components; ++c)
148 if (symmetric_evaluate &&
151 eval0.template values<0, true, false>(values_dofs,
153 eval0.template values<1, true, false>(values_quad,
161 eval_grad({},
data.shape_gradients_collocation_eo, {});
162 eval_grad.template gradients<0, true, false, 3>(
163 values_quad, gradients_quad);
164 eval_grad.template gradients<1, true, false, 3>(
165 values_quad, gradients_quad + 1);
170 eval0.template gradients<0, true, false>(values_dofs,
172 eval1.template values<1, true, false, 3>(scratch_data,
176 eval0.template values<0, true, false>(values_dofs,
178 eval1.template gradients<1, true, false, 3>(
179 scratch_data, gradients_quad + 1);
182 eval1.template values<1, true, false>(scratch_data,
186 eval0.template values<0, true, false>(values_dofs + n_dofs,
188 eval1.template values<1, true, false, 3>(scratch_data,
193 eval0.template values<0, true, false, 2>(values_dofs + n_dofs,
195 eval0.template gradients<0, true, false, 2>(values_dofs,
198 eval0.template values<0, true, false>(values_dofs,
202 values_quad[0] = values_dofs[0];
203 gradients_quad[0] = values_dofs[1];
208 values_dofs += 3 * n_dofs;
209 values_quad += n_q_points;
210 gradients_quad += dim * n_q_points;
215 values_dofs = values_dofs_ptr;
216 for (
unsigned int c = 0; c < n_components; ++c)
222 eval0.template hessians<0, true, false>(values_dofs,
224 eval1.template values<1, true, false>(scratch_data,
228 eval0.template values<0, true, false>(values_dofs,
230 eval1.template hessians<1, true, false>(scratch_data,
235 eval0.template values<0, true, false>(values_dofs +
238 eval1.template values<1, true, false>(scratch_data,
243 eval0.template gradients<0, true, false>(values_dofs,
245 eval1.template gradients<1, true, false>(scratch_data,
250 eval0.template gradients<0, true, false>(values_dofs +
253 eval1.template values<1, true, false>(scratch_data,
258 eval0.template values<0, true, false>(values_dofs + n_dofs,
260 eval1.template gradients<1, true, false>(scratch_data,
267 eval0.template hessians<0, true, false>(values_dofs,
270 eval0.template values<0, true, false>(
271 values_dofs + 2 * n_dofs, hessians_quad + n_q_points);
273 eval0.template gradients<0, true, false>(
274 values_dofs + n_dofs, hessians_quad + 2 * n_q_points);
277 hessians_quad[0] = values_dofs[2];
282 values_dofs += 3 * n_dofs;
283 hessians_quad += dim * (dim + 1) / 2 * n_q_points;
290 const unsigned int n_components,
295 Number *gradients_quad,
296 Number *hessians_quad,
297 Number *scratch_data,
298 const unsigned int subface_index)
303 const std::size_t n_dofs =
307 const std::size_t n_q_points =
312 Number *values_dofs_ptr = values_dofs;
316 for (
unsigned int c = 0; c < n_components; ++c)
321 eval1.template values<1, false, false>(values_quad,
323 eval0.template values<0, false, false>(values_quad,
327 eval0.template values<0, false, false>(values_quad,
331 values_dofs[0] = values_quad[0];
336 values_dofs += 3 * n_dofs;
337 values_quad += n_q_points;
340 for (
unsigned int c = 0; c < n_components; ++c)
346 eval1.template values<1, false, false, 3>(gradients_quad + 2,
348 eval0.template values<0, false, false>(scratch_data,
349 values_dofs + n_dofs);
350 if (symmetric_evaluate &&
359 eval_grad({},
data.shape_gradients_collocation_eo, {});
361 eval_grad.template gradients<1, false, true, 3>(
362 gradients_quad + 1, values_quad);
364 eval_grad.template gradients<1, false, false, 3>(
365 gradients_quad + 1, values_quad);
366 eval_grad.template gradients<0, false, true, 3>(
367 gradients_quad, values_quad);
368 eval0.template values<1, false, false>(values_quad,
370 eval0.template values<0, false, false>(values_quad,
377 eval1.template values<1, false, false>(values_quad,
379 eval1.template gradients<1, false, true, 3>(
380 gradients_quad + 1, scratch_data);
383 eval1.template gradients<1, false, false, 3>(
384 gradients_quad + 1, scratch_data);
387 eval0.template values<0, false, false>(scratch_data,
391 eval1.template values<1, false, false, 3>(gradients_quad,
393 eval0.template gradients<0, false, true>(scratch_data,
398 eval0.template values<0, false, false, 2>(gradients_quad + 1,
401 eval0.template gradients<0, false, false, 2>(gradients_quad,
404 eval0.template values<0, false, true>(values_quad,
408 values_dofs[0] = values_quad[0];
409 values_dofs[1] = gradients_quad[0];
414 values_dofs += 3 * n_dofs;
415 values_quad += n_q_points;
416 gradients_quad += dim * n_q_points;
421 values_dofs = values_dofs_ptr;
422 for (
unsigned int c = 0; c < n_components; ++c)
428 eval1.template values<1, false, false>(hessians_quad,
432 eval0.template hessians<0, false, true>(scratch_data,
435 eval0.template hessians<0, false, false>(scratch_data,
439 eval1.template hessians<1, false, false>(hessians_quad +
442 eval0.template values<0, false, true>(scratch_data,
446 eval1.template values<1, false, false>(hessians_quad +
449 eval0.template values<0, false, false>(scratch_data,
454 eval1.template gradients<1, false, false>(hessians_quad +
457 eval0.template gradients<0, false, true>(scratch_data,
461 eval1.template values<1, false, false>(hessians_quad +
465 eval0.template gradients<0, false, true>(scratch_data,
469 eval0.template gradients<0, false, false>(scratch_data,
474 eval1.template gradients<1, false, false>(hessians_quad +
477 eval0.template values<0, false, true>(scratch_data,
478 values_dofs + n_dofs);
485 eval0.template hessians<0, false, true>(hessians_quad,
488 eval0.template hessians<0, false, false>(hessians_quad,
492 eval0.template values<0, false, false>(
493 hessians_quad + n_q_points, values_dofs + 2 * n_dofs);
496 eval0.template gradients<0, false, true>(
497 hessians_quad + 2 * n_q_points, values_dofs + n_dofs);
499 eval0.template gradients<0, false, false>(
500 hessians_quad + 2 * n_q_points, values_dofs + n_dofs);
503 values_dofs[2] = hessians_quad[0];
512 values_dofs += 3 * n_dofs;
513 hessians_quad += dim * (dim + 1) / 2 * n_q_points;
521 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
531 template <
bool do_
integrate>
537 Number *values_dofs_in,
540 Number *scratch_data,
541 const unsigned int subface_index,
542 const unsigned int face_direction)
546 const int degree = fe_degree != -1 ? fe_degree : shape_data[0].fe_degree;
547 const int n_rows_n = degree + 1;
548 const int n_rows_t = degree;
549 const ::ndarray<int, 3, 3> dofs_per_direction{
550 {{{n_rows_n, n_rows_t, n_rows_t}},
551 {{n_rows_t, n_rows_n, n_rows_t}},
552 {{n_rows_t, n_rows_t, n_rows_n}}}};
563 (fe_degree > 0 ? fe_degree : 0),
568 std::array<int, dim> values_dofs_offsets = {};
569 for (
unsigned int comp = 0; comp < dim - 1; ++comp)
572 values_dofs_offsets[comp + 1] =
573 values_dofs_offsets[comp] +
574 3 * dofs_per_direction[comp][(face_direction + 1) % dim];
576 values_dofs_offsets[comp + 1] =
577 values_dofs_offsets[comp] +
578 3 * dofs_per_direction[comp][(face_direction + 1) % dim] *
579 dofs_per_direction[comp][(face_direction + 2) % dim];
585 std::array<unsigned int, dim> components;
586 for (
unsigned int comp = 0; comp < dim; ++comp)
587 components[comp] = (face_direction + comp + 1) % dim;
589 for (
const unsigned int comp : components)
591 Number *values_dofs = values_dofs_in + values_dofs_offsets[comp];
593 std::array<int, 2> n_blocks{
594 {dofs_per_direction[comp][(face_direction + 1) % dim],
595 (dim > 2 ? dofs_per_direction[comp][(face_direction + 2) % dim] :
598 if constexpr (dim == 3)
607 shape_data[0].shape_gradients_collocation_eo.data(),
617 if (n_blocks[0] == n_rows_n)
619 eval.template normal<0>(shape_data[0],
622 eval.template tangential<1, 0>(shape_data[1],
628 eval.template normal<0>(shape_data[0],
630 n_blocks[0] * n_blocks[1],
632 eval.template tangential<1, 0, dim>(shape_data[1],
637 else if (n_blocks[1] == n_rows_n)
639 eval.template normal<1>(shape_data[0],
642 eval.template tangential<0, 1>(shape_data[1],
648 eval.template normal<1>(shape_data[0],
650 n_blocks[0] * n_blocks[1],
652 eval.template tangential<0, 1, dim>(shape_data[1],
659 Eval eval(shape_data[1].shape_values_eo.data(), {}, {});
660 eval.template values<0, true, false>(values_dofs, values);
661 eval.template values<1, true, false>(values, values);
664 eval.template values<0, true, false>(values_dofs +
668 eval.template values<1, true, false, dim>(
669 scratch_data, gradients + 2);
674 eval_g.template gradients<0, true, false, dim>(values,
676 eval_g.template gradients<1, true, false, dim>(values,
692 eval_g.template gradients<0, false, true, dim>(
695 eval_g.template gradients<0, false, false, dim>(
697 eval_g.template gradients<1, false, true, dim>(gradients +
701 if (n_blocks[0] == n_rows_n)
703 eval.template tangential<1, 0>(shape_data[1],
706 eval.template normal<0>(shape_data[0],
712 eval.template tangential<1, 0, dim>(shape_data[1],
715 eval.template normal<0>(shape_data[0],
718 n_blocks[0] * n_blocks[1]);
721 else if (n_blocks[1] == n_rows_n)
723 eval.template tangential<0, 1>(shape_data[1],
726 eval.template normal<1>(shape_data[0],
732 eval.template tangential<0, 1, dim>(shape_data[1],
735 eval.template normal<1>(shape_data[0],
738 n_blocks[0] * n_blocks[1]);
743 Eval eval_iso(shape_data[1].shape_values_eo.data(),
746 eval_iso.template values<1, false, false>(values, values);
747 eval_iso.template values<0, false, false>(values,
751 eval_iso.template values<1, false, false, dim>(
752 gradients + 2, scratch_data);
753 eval_iso.template values<0, false, false>(
755 values_dofs + n_blocks[0] * n_blocks[1]);
771 if (n_blocks[0] == n_rows_n)
773 EvalN eval(shape_data[0].shape_values_eo,
774 shape_data[0].shape_gradients_eo,
776 eval.template values<0, true, false>(values_dofs, values);
779 eval.template gradients<0, true, false, dim>(
780 values_dofs, gradients);
781 eval.template values<0, true, false, dim>(
782 values_dofs + n_rows_n, gradients + 1);
787 Eval eval(shape_data[1].shape_values_eo,
788 shape_data[1].shape_gradients_eo,
790 eval.template values<0, true, false>(values_dofs, values);
793 eval.template gradients<0, true, false, dim>(
794 values_dofs, gradients);
795 eval.template values<0, true, false, dim>(
796 values_dofs + n_rows_t, gradients + 1);
803 if (n_blocks[0] == n_rows_n)
805 EvalN eval(shape_data[0].shape_values_eo,
806 shape_data[0].shape_gradients_eo,
809 eval.template values<0, false, false>(values,
814 eval.template gradients<0, false, true, dim>(
815 gradients, values_dofs);
817 eval.template gradients<0, false, false, dim>(
818 gradients, values_dofs);
819 eval.template values<0, false, false, dim>(
820 gradients + 1, values_dofs + n_rows_n);
825 Eval eval(shape_data[1].shape_values_eo,
826 shape_data[1].shape_gradients_eo,
829 eval.template values<0, false, false>(values,
834 eval.template gradients<0, false, true, dim>(
835 gradients, values_dofs);
837 eval.template gradients<0, false, false, dim>(
838 gradients, values_dofs);
839 eval.template values<0, false, false, dim>(
840 gradients + 1, values_dofs + n_rows_t);
853 template <
int dim,
int fe_degree,
typename Number>
859 template <
bool do_evaluate,
bool add_
into_output>
866 const unsigned int face_no)
868 Assert(
static_cast<unsigned int>(fe_degree) ==
869 shape_info.
data.front().fe_degree ||
873 interpolate_raviart_thomas<do_evaluate, add_into_output>(
874 n_components, input, output, flags, face_no, shape_info);
877 const unsigned int fe_degree_ = shape_info.
data.front().fe_degree;
879 interpolate_generic<do_evaluate, add_into_output>(
886 shape_info.
data.front().shape_data_on_face,
895 template <
bool do_evaluate,
bool add_
into_output>
898 const unsigned int n_components,
903 const unsigned int face_no)
905 Assert(
static_cast<unsigned int>(fe_degree + 1) ==
906 shape_info.
data.front().n_q_points_1d ||
910 interpolate_generic<do_evaluate, add_into_output>(
916 shape_info.
data.front().quadrature.size(),
917 shape_info.
data.front().quadrature_data_on_face,
923 template <
bool do_evaluate,
bool add_
into_output,
int face_direction = 0>
929 const unsigned int face_no,
930 const unsigned int n_points_1d,
932 const unsigned int dofs_per_component_on_cell,
933 const unsigned int dofs_per_component_on_face)
935 if (face_direction == face_no / 2)
937 constexpr int stride_ =
Utilities::pow(fe_degree + 1, face_direction);
939 const int n_rows = fe_degree != -1 ? fe_degree + 1 : n_points_1d;
941 const std::array<int, 2> n_blocks{
942 {(dim > 1 ? n_rows : 1), (dim > 2 ? n_rows : 1)}};
943 std::array<int, 2> steps;
944 if constexpr (face_direction == 0)
945 steps = {{n_rows, 0}};
946 else if constexpr (face_direction == 1 && dim == 2)
948 else if constexpr (face_direction == 1)
950 steps = {{n_rows * n_rows, -n_rows * n_rows * n_rows + 1}};
951 else if constexpr (face_direction == 2)
954 for (
unsigned int c = 0; c < n_components; ++c)
961 2>(shape_data[face_no % 2].begin(),
973 1>(shape_data[face_no % 2].begin(),
985 0>(shape_data[face_no % 2].begin(),
994 input += dofs_per_component_on_cell;
995 output += dofs_per_component_on_face;
999 output += dofs_per_component_on_cell;
1000 input += dofs_per_component_on_face;
1004 else if (face_direction < dim)
1008 std::min(face_direction + 1, dim - 1)>(
1016 dofs_per_component_on_cell,
1017 dofs_per_component_on_face);
1021 template <
bool do_evaluate,
1022 bool add_into_output,
1023 int face_direction = 0,
1024 int max_derivative = 0>
1027 const unsigned int n_components,
1028 const Number *input,
1031 const unsigned int face_no,
1043 bool increase_max_der =
false;
1046 increase_max_der =
true;
1048 if (face_direction == face_no / 2 && !increase_max_der)
1050 constexpr int stride1 =
Utilities::pow(fe_degree + 1, face_direction);
1051 constexpr int stride0 =
Utilities::pow(fe_degree, face_direction);
1052 constexpr int stride2 = fe_degree * (fe_degree + 1);
1055 fe_degree != -1 ? fe_degree : shape_info.
data[0].fe_degree;
1056 const int n_rows_n = degree + 1;
1057 const int n_rows_t = degree;
1059 std::array<int, 3> strides{{1, 1, 1}};
1060 if (face_direction > 0)
1064 strides[1] = n_rows_t * (face_direction == 3 ? n_rows_n : 1);
1067 const ::ndarray<int, 3, 3> dofs_per_direction{
1068 {{{n_rows_n, n_rows_t, n_rows_t}},
1069 {{n_rows_t, n_rows_n, n_rows_t}},
1070 {{n_rows_t, n_rows_t, n_rows_n}}}};
1072 std::array<int, 2> steps, n_blocks;
1074 if constexpr (face_direction == 0)
1075 steps = {{degree + (face_direction == 0), 0}};
1076 else if constexpr (face_direction == 1 && dim == 2)
1078 else if constexpr (face_direction == 1)
1081 {n_rows_n * n_rows_t, -n_rows_n * n_rows_t * n_rows_t + 1}};
1082 else if constexpr (face_direction == 2)
1085 n_blocks[0] = dofs_per_direction[0][(face_direction + 1) % dim];
1087 dim > 2 ? dofs_per_direction[0][(face_direction + 2) % dim] : 1;
1090 (fe_degree != -1 ? (fe_degree + (face_direction == 0)) : 0),
1091 ((face_direction < 2) ? stride1 : stride2),
1094 max_derivative>(shape_info.
data[face_direction != 0]
1095 .shape_data_on_face[face_no % 2]
1101 degree + (face_direction == 0),
1107 output += 3 * n_blocks[0] * n_blocks[1];
1112 input += 3 * n_blocks[0] * n_blocks[1];
1116 if constexpr (face_direction == 0)
1117 steps = {{degree, 0}};
1119 n_blocks[0] = dofs_per_direction[1][(face_direction + 1) % dim];
1121 dim > 2 ? dofs_per_direction[1][(face_direction + 2) % dim] : 1;
1124 (fe_degree != -1 ? (fe_degree + (face_direction == 1)) : 0),
1125 ((face_direction < 2) ? stride0 : stride2),
1128 max_derivative>(shape_info.
data[face_direction != 1]
1129 .shape_data_on_face[face_no % 2]
1135 degree + (face_direction == 1),
1138 if constexpr (dim > 2)
1143 output += 3 * n_blocks[0] * n_blocks[1];
1148 input += 3 * n_blocks[0] * n_blocks[1];
1151 if constexpr (face_direction == 0)
1152 steps = {{degree, 0}};
1153 else if constexpr (face_direction == 1)
1156 {n_rows_t * n_rows_t, -n_rows_n * n_rows_t * n_rows_t + 1}};
1157 else if constexpr (face_direction == 2)
1160 n_blocks[0] = dofs_per_direction[2][(face_direction + 1) % dim];
1161 n_blocks[1] = dofs_per_direction[2][(face_direction + 2) % dim];
1164 (fe_degree != -1 ? (fe_degree + (face_direction == 2)) : 0),
1168 max_derivative>(shape_info.
data[face_direction != 2]
1169 .shape_data_on_face[face_no % 2]
1175 degree + (face_direction == 2),
1179 else if (face_direction == face_no / 2)
1186 n_components, input, output, flag, face_no, shape_info);
1188 else if (face_direction < dim)
1190 if (increase_max_der)
1194 std::min(face_direction + 1, dim - 1),
1196 n_components, input, output, flag, face_no, shape_info);
1202 std::min(face_direction + 1, dim - 1),
1204 n_components, input, output, flag, face_no, shape_info);
1213 template <
typename VectorizedArrayType,
typename Number2>
1217 for (
unsigned int v = 0; v < VectorizedArrayType::size(); ++v)
1218 dst[v] = src_ptr[v];
1225 template <
typename Number, std::
size_t w
idth>
1235 template <
typename VectorizedArrayType,
typename Number2>
1238 const unsigned int *indices,
1239 VectorizedArrayType &dst)
1241 for (
unsigned int v = 0; v < VectorizedArrayType::size(); ++v)
1242 dst[v] = src_ptr[indices[v]];
1249 template <
typename Number, std::
size_t w
idth>
1252 const unsigned int *indices,
1255 dst.
gather(src_ptr, indices);
1261 template <
typename VectorizedArrayType,
typename Number2>
1265 for (
unsigned int v = 0; v < VectorizedArrayType::size(); ++v)
1266 dst_ptr[v] += src[v];
1273 template <
typename Number, std::
size_t w
idth>
1279 (tmp + src).store(dst_ptr);
1285 template <
typename VectorizedArrayType,
typename Number2>
1288 const unsigned int *indices,
1291 for (
unsigned int v = 0; v < VectorizedArrayType::size(); ++v)
1292 dst_ptr[indices[v]] += src[v];
1299 template <
typename Number, std::
size_t w
idth>
1302 const unsigned int *indices,
1305#if DEAL_II_VECTORIZATION_WIDTH_IN_BITS < 512
1306 for (
unsigned int v = 0; v < width; ++v)
1307 dst_ptr[indices[v]] += src[v];
1310 tmp.
gather(dst_ptr, indices);
1311 (tmp + src).scatter(indices, dst_ptr);
1317 template <
typename Number>
1320 const unsigned int n_components,
1322 const unsigned int *orientation,
1323 const bool integrate,
1324 const std::size_t n_q_points,
1326 Number *values_quad,
1327 Number *gradients_quad,
1328 Number *hessians_quad)
1330 for (
unsigned int c = 0; c < n_components; ++c)
1335 for (
unsigned int q = 0; q < n_q_points; ++q)
1336 tmp_values[q] = values_quad[c * n_q_points + orientation[q]];
1338 for (
unsigned int q = 0; q < n_q_points; ++q)
1339 tmp_values[orientation[q]] = values_quad[c * n_q_points + q];
1340 for (
unsigned int q = 0; q < n_q_points; ++q)
1341 values_quad[c * n_q_points + q] = tmp_values[q];
1344 for (
unsigned int d = 0; d < dim; ++d)
1347 for (
unsigned int q = 0; q < n_q_points; ++q)
1349 gradients_quad[(c * n_q_points + orientation[q]) * dim + d];
1351 for (
unsigned int q = 0; q < n_q_points; ++q)
1352 tmp_values[orientation[q]] =
1353 gradients_quad[(c * n_q_points + q) * dim + d];
1354 for (
unsigned int q = 0; q < n_q_points; ++q)
1355 gradients_quad[(c * n_q_points + q) * dim + d] = tmp_values[q];
1359 const unsigned int hdim = (dim * (dim + 1)) / 2;
1360 for (
unsigned int d = 0; d < hdim; ++d)
1363 for (
unsigned int q = 0; q < n_q_points; ++q)
1364 tmp_values[q] = hessians_quad[(c * hdim + d) * n_q_points +
1367 for (
unsigned int q = 0; q < n_q_points; ++q)
1368 tmp_values[orientation[q]] =
1369 hessians_quad[(c * hdim + d) * n_q_points + q];
1370 for (
unsigned int q = 0; q < n_q_points; ++q)
1371 hessians_quad[(c * hdim + d) * n_q_points + q] =
1380 template <
typename Number,
typename VectorizedArrayType>
1383 const unsigned int dim,
1384 const unsigned int n_components,
1385 const unsigned int v,
1387 const unsigned int *orientation,
1388 const bool integrate,
1389 const std::size_t n_q_points,
1391 VectorizedArrayType *values_quad,
1392 VectorizedArrayType *gradients_quad =
nullptr,
1393 VectorizedArrayType *hessians_quad =
nullptr)
1395 for (
unsigned int c = 0; c < n_components; ++c)
1400 for (
unsigned int q = 0; q < n_q_points; ++q)
1401 tmp_values[q] = values_quad[c * n_q_points + orientation[q]][v];
1403 for (
unsigned int q = 0; q < n_q_points; ++q)
1404 tmp_values[orientation[q]] = values_quad[c * n_q_points + q][v];
1405 for (
unsigned int q = 0; q < n_q_points; ++q)
1406 values_quad[c * n_q_points + q][v] = tmp_values[q];
1409 for (
unsigned int d = 0; d < dim; ++d)
1413 for (
unsigned int q = 0; q < n_q_points; ++q)
1415 gradients_quad[(c * n_q_points + orientation[q]) * dim + d]
1418 for (
unsigned int q = 0; q < n_q_points; ++q)
1419 tmp_values[orientation[q]] =
1420 gradients_quad[(c * n_q_points + q) * dim + d][v];
1421 for (
unsigned int q = 0; q < n_q_points; ++q)
1422 gradients_quad[(c * n_q_points + q) * dim + d][v] =
1428 const unsigned int hdim = (dim * (dim + 1)) / 2;
1429 for (
unsigned int d = 0; d < hdim; ++d)
1432 for (
unsigned int q = 0; q < n_q_points; ++q)
1433 tmp_values[q] = hessians_quad[(c * hdim + d) * n_q_points +
1436 for (
unsigned int q = 0; q < n_q_points; ++q)
1437 tmp_values[orientation[q]] =
1438 hessians_quad[(c * hdim + d) * n_q_points + q][v];
1439 for (
unsigned int q = 0; q < n_q_points; ++q)
1440 hessians_quad[(c * hdim + d) * n_q_points + q][v] =
1449 template <
int dim,
typename Number>
1455 const Number *values_dofs,
1459 const auto &shape_data = shape_info.
data.front();
1468 const unsigned int face_no = fe_eval.
get_face_no();
1470 const std::size_t n_dofs = shape_info.dofs_per_component_on_cell;
1471 const std::size_t n_q_points = shape_info.n_q_points_faces[face_no];
1475 const auto *
const shape_values =
1476 &shape_data.shape_values_face(face_no, face_orientation, 0);
1479 auto *in = values_dofs;
1481 for (
unsigned int c = 0; c < n_components; c += 3)
1483 if (c + 1 == n_components)
1492 shape_values, in, out, n_dofs, n_q_points, 1, 1);
1493 else if (c + 2 == n_components)
1502 shape_values, in, out, n_dofs, n_q_points, 1, 1);
1512 shape_values, in, out, n_dofs, n_q_points, 1, 1);
1514 out += 3 * n_q_points;
1522 const auto *in = values_dofs;
1524 const auto *
const shape_gradients =
1525 &shape_data.shape_gradients_face(face_no, face_orientation, 0);
1527 for (
unsigned int c = 0; c < n_components; c += 3)
1529 if (c + 1 == n_components)
1538 shape_gradients, in, out, n_dofs, n_q_points * dim, 1, 1);
1539 else if (c + 2 == n_components)
1548 shape_gradients, in, out, n_dofs, n_q_points * dim, 1, 1);
1558 shape_gradients, in, out, n_dofs, n_q_points * dim, 1, 1);
1559 out += 3 * n_q_points * dim;
1570 template <
int fe_degree>
1577 const Number *values_dofs,
1579 const bool use_vectorization,
1581 Number *scratch_data)
1585 if (use_vectorization ==
false)
1587 const auto &shape_data = shape_info.
data.front();
1589 const unsigned int dofs_per_comp_face =
1593 const unsigned int dofs_per_face = n_components * dofs_per_comp_face;
1595 for (
unsigned int v = 0; v < Number::size(); ++v)
1602 for (
unsigned int i = 0; i < 3 * dofs_per_face; ++i)
1608 template interpolate<true, false>(n_components,
1615 for (
unsigned int i = 0; i < 3 * dofs_per_face; ++i)
1616 temp[i][v] = scratch_data[i][v];
1621 template interpolate<true, false>(n_components,
1630 template <
int fe_degree,
int n_q_po
ints_1d>
1639 Number *scratch_data)
1642 const auto &shape_data = shape_info.
data.front();
1645 constexpr unsigned int n_q_points_1d_actual =
1646 fe_degree > -1 ? n_q_points_1d : 0;
1652 n_q_points_1d_actual,
1654 template evaluate_or_integrate_in_face<false>(
1664 else if (fe_degree > -1 &&
1670 n_q_points_1d_actual,
1685 n_q_points_1d_actual,
1703 const unsigned int n_components,
1706 const bool use_vectorization,
1711 if (use_vectorization ==
false)
1713 for (
unsigned int v = 0; v < Number::size(); ++v)
1727 &shape_info.face_orientations_quad(
1730 shape_info.n_q_points_face,
1744 shape_info.n_q_points_face,
1753 template <
int fe_degree,
int n_q_po
ints_1d>
1757 const Number *values_dofs_actual,
1761 const auto &shape_data = shape_info.
data.front();
1763 const unsigned int dofs_per_comp_face =
1771 Number *temp2 = temp1 + 3 * n_components * dofs_per_comp_face;
1773 const Number *values_dofs =
1777 shape_info.n_q_points)) :
1781 embed_truncated_into_full_tensor_product<dim, fe_degree>(
1783 const_cast<Number *
>(values_dofs),
1787 bool use_vectorization =
true;
1791 for (
unsigned int v = 0; v < Number::size(); ++v)
1794 use_vectorization =
false;
1796 project_to_face<fe_degree>(n_components,
1804 evaluate_in_face<fe_degree, n_q_points_1d>(
1805 n_components, evaluation_flag, fe_eval, temp1, temp2);
1809 n_components, evaluation_flag, fe_eval, use_vectorization, temp1);
1814 template <
int fe_degree,
int n_q_po
ints_1d>
1816 run(
const unsigned int n_components,
1818 const Number *values_dofs,
1829 return evaluate_tensor<fe_degree, n_q_points_1d>(n_components,
1838 template <
int dim,
typename Number>
1841 template <
int fe_degree>
1843 run(
const unsigned int n_components,
1845 const Number *values_dofs,
1849 const auto &shape_data = shape_info.
data.front();
1851 const unsigned int dofs_per_comp_face =
1859 Number *scratch_data = temp + 3 * n_components * dofs_per_comp_face;
1861 bool use_vectorization =
true;
1865 for (
unsigned int v = 0; v < Number::size(); ++v)
1868 use_vectorization =
false;
1871 template project_to_face<fe_degree>(n_components,
1885 template <
int dim,
typename Number>
1888 template <
int fe_degree,
int n_q_po
ints_1d>
1890 run(
const unsigned int n_components,
1895 const auto &shape_data = shape_info.
data.front();
1897 const unsigned int dofs_per_comp_face =
1905 Number *scratch_data = temp + 3 * n_components * dofs_per_comp_face;
1908 template evaluate_in_face<fe_degree, n_q_points_1d>(
1909 n_components, evaluation_flag, fe_eval, temp, scratch_data);
1917 template <
int dim,
typename Number>
1922 const unsigned int n_components,
1924 Number *values_dofs,
1926 const bool sum_into_values)
1929 const auto &shape_data = shape_info.
data.front();
1938 const unsigned int face_no = fe_eval.
get_face_no();
1940 const std::size_t n_dofs = shape_info.dofs_per_component_on_cell;
1941 const std::size_t n_q_points = shape_info.n_q_points_faces[face_no];
1946 const auto *
const shape_values =
1947 &shape_data.shape_values_face(face_no, face_orientation, 0);
1950 auto *out = values_dofs;
1952 for (
unsigned int c = 0; c < n_components; c += 3)
1954 if (sum_into_values)
1956 if (c + 1 == n_components)
1965 shape_values, in, out, n_dofs, n_q_points, 1, 1);
1966 else if (c + 2 == n_components)
1975 shape_values, in, out, n_dofs, n_q_points, 1, 1);
1985 shape_values, in, out, n_dofs, n_q_points, 1, 1);
1989 if (c + 1 == n_components)
1998 shape_values, in, out, n_dofs, n_q_points, 1, 1);
1999 else if (c + 2 == n_components)
2008 shape_values, in, out, n_dofs, n_q_points, 1, 1);
2018 shape_values, in, out, n_dofs, n_q_points, 1, 1);
2020 in += 3 * n_q_points;
2028 auto *out = values_dofs;
2030 const auto *
const shape_gradients =
2031 &shape_data.shape_gradients_face(face_no, face_orientation, 0);
2033 for (
unsigned int c = 0; c < n_components; ++c)
2035 if (!sum_into_values &&
2038 if (c + 1 == n_components)
2047 shape_gradients, in, out, n_dofs, n_q_points * dim, 1, 1);
2048 else if (c + 2 == n_components)
2057 shape_gradients, in, out, n_dofs, n_q_points * dim, 1, 1);
2067 shape_gradients, in, out, n_dofs, n_q_points * dim, 1, 1);
2071 if (c + 1 == n_components)
2080 shape_gradients, in, out, n_dofs, n_q_points * dim, 1, 1);
2081 else if (c + 2 == n_components)
2090 shape_gradients, in, out, n_dofs, n_q_points * dim, 1, 1);
2100 shape_gradients, in, out, n_dofs, n_q_points * dim, 1, 1);
2102 in += 3 * n_q_points * dim;
2118 const unsigned int n_components,
2121 const bool use_vectorization,
2126 if (use_vectorization ==
false)
2128 for (
unsigned int v = 0; v < Number::size(); ++v)
2145 shape_info.n_q_points_face,
2160 shape_info.n_q_points_face,
2167 template <
int fe_degree,
int n_q_po
ints_1d>
2176 Number *scratch_data)
2179 const auto &shape_data = shape_info.
data.front();
2181 const unsigned int n_q_points_1d_actual =
2182 fe_degree > -1 ? n_q_points_1d : 0;
2189 n_q_points_1d_actual,
2191 template evaluate_or_integrate_in_face<true>(
2201 else if (fe_degree > -1 &&
2209 n_q_points_1d_actual,
2224 n_q_points_1d_actual,
2236 template <
int fe_degree>
2243 Number *values_dofs,
2245 const bool use_vectorization,
2247 Number *scratch_data,
2248 const bool sum_into_values)
2251 const auto &shape_data = shape_info.
data.front();
2253 const unsigned int dofs_per_comp_face =
2257 const unsigned int dofs_per_face = n_components * dofs_per_comp_face;
2259 if (use_vectorization ==
false)
2261 for (
unsigned int v = 0; v < Number::size(); ++v)
2270 template interpolate<false, false>(n_components,
2277 if (sum_into_values)
2278 for (
unsigned int i = 0; i < 3 * dofs_per_face; ++i)
2279 values_dofs[i][v] += scratch_data[i][v];
2281 for (
unsigned int i = 0; i < 3 * dofs_per_face; ++i)
2282 values_dofs[i][v] = scratch_data[i][v];
2287 if (sum_into_values)
2289 template interpolate<false, true>(n_components,
2297 template interpolate<false, false>(n_components,
2306 template <
int fe_degree,
int n_q_po
ints_1d>
2310 Number *values_dofs_actual,
2312 const bool sum_into_values)
2315 const auto &shape_data = shape_info.
data.front();
2317 const unsigned int dofs_per_comp_face =
2323 Number *temp2 = temp1 + 3 * n_components * dofs_per_comp_face;
2326 Number *values_dofs =
2328 temp2 + 2 * (std::max<std::size_t>(
2333 bool use_vectorization =
true;
2342 [&](
const auto &v) {
2343 return v == fe_eval.get_cell_ids()[0] ||
2344 v == numbers::invalid_unsigned_int;
2349 n_components, integration_flag, fe_eval, use_vectorization, temp1);
2351 integrate_in_face<fe_degree, n_q_points_1d>(
2352 n_components, integration_flag, fe_eval, temp1, temp2);
2354 collect_from_face<fe_degree>(n_components,
2365 truncate_tensor_product_to_complete_degrees<dim, fe_degree>(
2366 n_components, values_dofs_actual, values_dofs, fe_eval);
2371 template <
int fe_degree,
int n_q_po
ints_1d>
2373 run(
const unsigned int n_components,
2375 Number *values_dofs,
2377 const bool sum_into_values)
2388 return integrate_tensor<fe_degree, n_q_points_1d>(n_components,
2398 template <
int dim,
typename Number>
2401 template <
int fe_degree>
2403 run(
const unsigned int n_components,
2405 Number *values_dofs,
2407 const bool sum_into_values)
2410 const auto &shape_data = shape_info.
data.front();
2412 const unsigned int dofs_per_comp_face =
2418 Number *scratch_data = temp + 3 * n_components * dofs_per_comp_face;
2420 bool use_vectorization =
true;
2429 [&](
const auto &v) {
2430 return v == fe_eval.get_cell_ids()[0] ||
2431 v == numbers::invalid_unsigned_int;
2435 template collect_from_face<fe_degree>(n_components,
2450 template <
int dim,
typename Number>
2453 template <
int fe_degree,
int n_q_po
ints_1d>
2455 run(
const unsigned int n_components,
2461 const auto &shape_data = shape_info.
data.front();
2463 const unsigned int dofs_per_comp_face =
2469 Number *scratch_data = temp + 3 * n_components * dofs_per_comp_face;
2472 template integrate_in_face<fe_degree, n_q_points_1d>(
2473 n_components, integration_flag, fe_eval, temp, scratch_data);
2481 template <
int n_face_orientations,
2483 typename EvaluationData,
2484 const bool check_face_orientations =
false>
2488 const unsigned int n_components,
2490 typename Processor::Number2_ *global_vector_ptr,
2492 const EvaluationData &fe_eval,
2493 typename Processor::VectorizedArrayType_ *temp1)
2495 constexpr int dim = Processor::dim_;
2496 constexpr int fe_degree = Processor::fe_degree_;
2497 using VectorizedArrayType =
typename Processor::VectorizedArrayType_;
2498 constexpr int n_lanes = VectorizedArrayType::size();
2500 using Number =
typename Processor::Number_;
2501 using Number2_ =
typename Processor::Number2_;
2503 const auto &shape_data = fe_eval.get_shape_info().data.front();
2504 constexpr bool integrate = Processor::do_integrate;
2505 const unsigned int face_no = fe_eval.get_face_no();
2506 const auto &dof_info = fe_eval.get_dof_info();
2507 const unsigned int cell = fe_eval.get_cell_or_face_batch_id();
2509 fe_eval.get_dof_access_index();
2511 dof_info.index_storage_variants[dof_access_index].size());
2512 constexpr unsigned int dofs_per_face =
2514 const unsigned int subface_index = fe_eval.get_subface_index();
2516 const unsigned int n_filled_lanes =
2517 dof_info.n_vectorization_lanes_filled[dof_access_index][cell];
2519 bool all_faces_are_same = n_filled_lanes == n_lanes;
2520 if (n_face_orientations == n_lanes)
2521 for (
unsigned int v = 1; v < n_lanes; ++v)
2522 if (fe_eval.get_face_no(v) != fe_eval.get_face_no(0) ||
2523 fe_eval.get_face_orientation(v) != fe_eval.get_face_orientation(0))
2525 all_faces_are_same =
false;
2530 std::array<const unsigned int *, n_face_orientations> orientation = {};
2532 if (dim == 3 && n_face_orientations == n_lanes && !all_faces_are_same &&
2533 fe_eval.is_interior_face() == 0)
2534 for (
unsigned int v = 0; v < n_lanes; ++v)
2542 if (shape_data.nodal_at_cell_boundaries &&
2543 fe_eval.get_face_orientation(v) != 0)
2548 check_face_orientations ==
false)
2562 orientation[v] = &fe_eval.get_shape_info().face_orientations_dofs(
2563 fe_eval.get_face_orientation(v), 0);
2566 else if (dim == 3 && fe_eval.get_face_orientation() != 0)
2570 check_face_orientations ==
false)
2584 for (
unsigned int v = 0; v < n_face_orientations; ++v)
2585 orientation[v] = &fe_eval.get_shape_info().face_orientations_dofs(
2586 fe_eval.get_face_orientation(), 0);
2592 VectorizedArrayType grad_weight =
2594 .shape_data_on_face[0][fe_degree + (integrate ? (2 - face_no % 2) :
2595 (1 + face_no % 2))];
2598 std::array<const unsigned int *, n_face_orientations> index_array_hermite =
2602 if (n_face_orientations == 1)
2603 index_array_hermite[0] =
2604 &fe_eval.get_shape_info().face_to_cell_index_hermite(face_no, 0);
2607 for (
unsigned int v = 0; v < n_lanes; ++v)
2612 const auto face_no = fe_eval.get_face_no(v);
2616 .shape_data_on_face[0][fe_degree + (integrate ?
2617 (2 - (face_no % 2)) :
2618 (1 + (face_no % 2)))];
2620 index_array_hermite[v] =
2621 &fe_eval.get_shape_info().face_to_cell_index_hermite(face_no,
2628 std::array<const unsigned int *, n_face_orientations> index_array_nodal =
2630 if (shape_data.nodal_at_cell_boundaries ==
true)
2632 if (n_face_orientations == 1)
2633 index_array_nodal[0] =
2634 &fe_eval.get_shape_info().face_to_cell_index_nodal(face_no, 0);
2637 for (
unsigned int v = 0; v < n_lanes; ++v)
2642 const auto face_no = fe_eval.get_face_no(v);
2644 index_array_nodal[v] =
2645 &fe_eval.get_shape_info().face_to_cell_index_nodal(face_no,
2652 const auto reorientate = [&](
const unsigned int v,
const unsigned int i) {
2653 return (!check_face_orientations || orientation[v] ==
nullptr) ?
2660 fe_eval.get_cell_ids()[0] :
2662 const unsigned int *dof_indices =
2663 &dof_info.dof_indices_contiguous[dof_access_index][
cell_index];
2665 for (
unsigned int comp = 0; comp < n_components; ++comp)
2667 const std::size_t index_offset =
2668 dof_info.component_dof_indices_offset
2669 [fe_eval.get_active_fe_index()]
2670 [fe_eval.get_first_selected_component()] +
2674 if (n_face_orientations == 1 &&
2675 dof_info.index_storage_variants[dof_access_index][cell] ==
2677 interleaved_contiguous)
2680 dof_info.n_vectorization_lanes_filled[dof_access_index][cell],
2682 Number2_ *vector_ptr =
2683 global_vector_ptr + dof_indices[0] + index_offset * n_lanes;
2687 for (
unsigned int i = 0; i < dofs_per_face; ++i)
2691 const unsigned int ind1 = index_array_hermite[0][2 * i];
2692 const unsigned int ind2 = index_array_hermite[0][2 * i + 1];
2693 const unsigned int i_ = reorientate(0, i);
2694 proc.hermite_grad_vectorized(temp1[
i_],
2695 temp1[
i_ + dofs_per_face],
2696 vector_ptr + ind1 * n_lanes,
2697 vector_ptr + ind2 * n_lanes,
2703 for (
unsigned int i = 0; i < dofs_per_face; ++i)
2707 const unsigned int i_ = reorientate(0, i);
2708 const unsigned int ind = index_array_nodal[0][i];
2709 proc.value_vectorized(temp1[
i_],
2710 vector_ptr + ind * n_lanes);
2716 else if (n_face_orientations == 1 &&
2717 dof_info.index_storage_variants[dof_access_index][cell] ==
2719 interleaved_contiguous_strided)
2722 dof_info.n_vectorization_lanes_filled[dof_access_index][cell],
2724 Number2_ *vector_ptr = global_vector_ptr + index_offset * n_lanes;
2727 for (
unsigned int i = 0; i < dofs_per_face; ++i)
2731 const unsigned int i_ = reorientate(0, i);
2732 const unsigned int ind1 =
2733 index_array_hermite[0][2 * i] * n_lanes;
2734 const unsigned int ind2 =
2735 index_array_hermite[0][2 * i + 1] * n_lanes;
2736 proc.hermite_grad_vectorized_indexed(
2738 temp1[
i_ + dofs_per_face],
2748 for (
unsigned int i = 0; i < dofs_per_face; ++i)
2752 const unsigned int i_ = reorientate(0, i);
2753 const unsigned int ind = index_array_nodal[0][i] * n_lanes;
2754 proc.value_vectorized_indexed(temp1[
i_],
2762 else if (n_face_orientations == 1 &&
2763 dof_info.index_storage_variants[dof_access_index][cell] ==
2765 interleaved_contiguous_mixed_strides)
2767 const unsigned int *strides =
2768 &dof_info.dof_indices_interleave_strides[dof_access_index]
2770 unsigned int indices[n_lanes];
2771 for (
unsigned int v = 0; v < n_lanes; ++v)
2772 indices[v] = dof_indices[v] + index_offset * strides[v];
2773 const unsigned int n_filled_lanes =
2774 dof_info.n_vectorization_lanes_filled[dof_access_index][cell];
2778 if (n_filled_lanes == n_lanes)
2779 for (
unsigned int i = 0; i < dofs_per_face; ++i)
2783 const unsigned int i_ = reorientate(0, i);
2784 unsigned int ind1[n_lanes];
2786 for (
unsigned int v = 0; v < n_lanes; ++v)
2787 ind1[v] = indices[v] +
2788 index_array_hermite[0][2 * i] * strides[v];
2789 unsigned int ind2[n_lanes];
2791 for (
unsigned int v = 0; v < n_lanes; ++v)
2795 index_array_hermite[0][2 * i + 1] * strides[v];
2796 proc.hermite_grad_vectorized_indexed(
2798 temp1[
i_ + dofs_per_face],
2807 if (integrate ==
false)
2808 for (
unsigned int i = 0; i < 2 * dofs_per_face; ++i)
2809 temp1[i] = VectorizedArrayType();
2811 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
2812 for (
unsigned int i = 0; i < dofs_per_face; ++i)
2814 const unsigned int i_ =
2815 reorientate(n_face_orientations == 1 ? 0 : v, i);
2818 temp1[
i_ + dofs_per_face][v],
2822 [n_face_orientations == 1 ? 0 : v][2 * i] *
2826 index_array_hermite[n_face_orientations == 1 ?
2830 grad_weight[n_face_orientations == 1 ? 0 : v]);
2836 if (n_filled_lanes == n_lanes)
2837 for (
unsigned int i = 0; i < dofs_per_face; ++i)
2840 unsigned int ind[n_lanes];
2842 for (
unsigned int v = 0; v < n_lanes; ++v)
2844 indices[v] + index_array_nodal[0][i] * strides[v];
2845 const unsigned int i_ = reorientate(0, i);
2846 proc.value_vectorized_indexed(temp1[
i_],
2852 if (integrate ==
false)
2853 for (
unsigned int i = 0; i < dofs_per_face; ++i)
2854 temp1[i] = VectorizedArrayType();
2856 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
2857 for (
unsigned int i = 0; i < dofs_per_face; ++i)
2859 temp1[reorientate(n_face_orientations == 1 ? 0 : v,
2863 index_array_nodal[n_face_orientations == 1 ? 0 : v]
2871 else if (n_face_orientations > 1 ||
2872 dof_info.index_storage_variants[dof_access_index][cell] ==
2876 Number2_ *vector_ptr = global_vector_ptr + index_offset;
2878 const bool vectorization_possible =
2879 all_faces_are_same && (sm_ptr ==
nullptr);
2881 std::array<Number2_ *, n_lanes> vector_ptrs{{
nullptr}};
2882 std::array<unsigned int, n_lanes> reordered_indices{
2885 if (vectorization_possible ==
false)
2887 if (n_face_orientations == 1)
2889 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
2890 if (sm_ptr ==
nullptr)
2892 vector_ptrs[v] = vector_ptr + dof_indices[v];
2898 .dof_indices_contiguous_sm[dof_access_index]
2899 [cell * n_lanes + v];
2900 vector_ptrs[v] =
const_cast<Number2_ *
>(
2901 sm_ptr->operator[](temp.first).
data() +
2902 temp.second + index_offset);
2905 else if (n_face_orientations == n_lanes)
2907 const auto &cells = fe_eval.get_cell_ids();
2908 for (
unsigned int v = 0; v < n_lanes; ++v)
2911 if (sm_ptr ==
nullptr)
2916 .dof_indices_contiguous[dof_access_index]
2923 .dof_indices_contiguous_sm[dof_access_index]
2925 vector_ptrs[v] =
const_cast<Number2_ *
>(
2926 sm_ptr->operator[](temp.first).
data() +
2927 temp.second + index_offset);
2936 else if (n_face_orientations == n_lanes)
2938 for (
unsigned int v = 0; v < n_lanes; ++v)
2939 reordered_indices[v] =
2940 dof_info.dof_indices_contiguous[dof_access_index]
2941 [fe_eval.get_cell_ids()[v]];
2942 dof_indices = reordered_indices.data();
2947 if (vectorization_possible)
2948 for (
unsigned int i = 0; i < dofs_per_face; ++i)
2950 const unsigned int ind1 = index_array_hermite[0][2 * i];
2951 const unsigned int ind2 =
2952 index_array_hermite[0][2 * i + 1];
2953 const unsigned int i_ = reorientate(0, i);
2955 proc.hermite_grad_vectorized_indexed(
2957 temp1[
i_ + dofs_per_face],
2964 else if (n_face_orientations == 1)
2965 for (
unsigned int i = 0; i < dofs_per_face; ++i)
2967 const unsigned int ind1 = index_array_hermite[0][2 * i];
2968 const unsigned int ind2 =
2969 index_array_hermite[0][2 * i + 1];
2970 const unsigned int i_ = reorientate(0, i);
2972 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
2973 proc.hermite_grad(temp1[
i_][v],
2974 temp1[
i_ + dofs_per_face][v],
2975 vector_ptrs[v][ind1],
2976 vector_ptrs[v][ind2],
2979 if (integrate ==
false)
2980 for (
unsigned int v = n_filled_lanes; v < n_lanes; ++v)
2983 temp1[i + dofs_per_face][v] = 0.0;
2988 if (integrate ==
false && n_filled_lanes < n_lanes)
2989 for (
unsigned int i = 0; i < dofs_per_face; ++i)
2990 temp1[i] = temp1[i + dofs_per_face] = Number();
2992 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
2993 for (
unsigned int i = 0; i < dofs_per_face; ++i)
2995 temp1[reorientate(v, i)][v],
2996 temp1[reorientate(v, i) + dofs_per_face][v],
2997 vector_ptrs[v][index_array_hermite[v][2 * i]],
2998 vector_ptrs[v][index_array_hermite[v][2 * i + 1]],
3004 if (vectorization_possible)
3005 for (
unsigned int i = 0; i < dofs_per_face; ++i)
3007 const unsigned int ind = index_array_nodal[0][i];
3008 const unsigned int i_ = reorientate(0, i);
3010 proc.value_vectorized_indexed(temp1[
i_],
3016 if constexpr (n_face_orientations == 1)
3017 for (
unsigned int i = 0; i < dofs_per_face; ++i)
3019 const unsigned int ind = index_array_nodal[0][i];
3020 const unsigned int i_ = reorientate(0, i);
3022 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
3023 proc.value(temp1[
i_][v], vector_ptrs[v][ind]);
3025 if constexpr (integrate ==
false)
3026 for (
unsigned int v = n_filled_lanes; v < n_lanes;
3032 if (integrate ==
false && n_filled_lanes < n_lanes)
3033 for (
unsigned int i = 0; i < dofs_per_face; ++i)
3034 temp1[i] = Number();
3036 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
3037 for (
unsigned int i = 0; i < dofs_per_face; ++i)
3038 proc.
value(temp1[reorientate(v, i)][v],
3039 vector_ptrs[v][index_array_nodal[v][i]]);
3050 temp1 += 3 * dofs_per_face;
3056 template <
int dim,
typename Number2,
typename VectorizedArrayType>
3059 using Number =
typename VectorizedArrayType::value_type;
3061 template <
int fe_degree,
int n_q_po
ints_1d>
3063 run(
const unsigned int n_components,
3065 const Number2 *src_ptr,
3074 const unsigned int dofs_per_face =
Utilities::pow(fe_degree + 1, dim - 1);
3077 VectorizedArrayType *scratch_data =
3078 temp + 3 * n_components * dofs_per_face;
3085 fe_face_evaluation_process_and_io<VectorizedArrayType::size()>(
3086 p, n_components, evaluation_flag, src_ptr, sm_ptr, fe_eval, temp);
3088 fe_face_evaluation_process_and_io<1>(
3089 p, n_components, evaluation_flag, src_ptr, sm_ptr, fe_eval, temp);
3098 VectorizedArrayType>::
3099 evaluate_in_face(n_components,
3113 VectorizedArrayType>::
3114 evaluate_in_face(n_components,
3131 for (
unsigned int v = 0; v < VectorizedArrayType::size(); ++v)
3174 template <
typename Number3>
3178 const Number2 *vector_ptr,
3181 const unsigned int fe_degree = shape_info.
data.front().fe_degree;
3182 if (fe_degree < 1 || !shape_info.
data.front().nodal_at_cell_boundaries ||
3185 shape_info.
data.front().element_type !=
3188 vector_ptr ==
nullptr ||
3189 shape_info.
data.front().element_type >
3199 template <
int fe_degree>
3209 template <
typename T0,
typename T1,
typename T2>
3215 const T2 &grad_weight)
3219 temp_2 = grad_weight * (temp_1 - temp_2);
3222 template <
typename T1,
typename T2>
3229 template <
typename T0,
typename T1,
typename T2,
typename T3>
3235 const T2 &grad_weight,
3236 const T3 &indices_1,
3237 const T3 &indices_2)
3241 temp_2 = grad_weight * (temp_1 - temp_2);
3244 template <
typename T0,
typename T1,
typename T2>
3251 template <
typename T0,
typename T1,
typename T2>
3255 const T1 &src_ptr_1,
3256 const T1 &src_ptr_2,
3257 const T2 &grad_weight)
3261 temp_2 = grad_weight * (temp_1 - src_ptr_2);
3264 template <
typename T1,
typename T2>
3276 template <
int dim,
typename Number2,
typename VectorizedArrayType>
3279 using Number =
typename VectorizedArrayType::value_type;
3281 template <
int fe_degree,
int n_q_po
ints_1d>
3283 run(
const unsigned int n_components,
3294 const unsigned int dofs_per_face =
Utilities::pow(fe_degree + 1, dim - 1);
3297 VectorizedArrayType *scratch_data =
3298 temp + 3 * n_components * dofs_per_face;
3308 for (
unsigned int v = 0; v < VectorizedArrayType::size(); ++v)
3352 VectorizedArrayType>::
3353 integrate_in_face(n_components,
3367 VectorizedArrayType>::
3368 integrate_in_face(n_components,
3383 fe_face_evaluation_process_and_io<VectorizedArrayType::size()>(
3384 p, n_components, integration_flag, dst_ptr, sm_ptr, fe_eval, temp);
3386 fe_face_evaluation_process_and_io<1>(
3387 p, n_components, integration_flag, dst_ptr, sm_ptr, fe_eval, temp);
3393 template <
int fe_degree>
3403 template <
typename T0,
typename T1,
typename T2,
typename T3,
typename T4>
3409 const T4 &grad_weight)
3412 const VectorizedArrayType val = temp_1 - grad_weight * temp_2;
3413 const VectorizedArrayType grad = grad_weight * temp_2;
3418 template <
typename T0,
typename T1>
3426 template <
typename T0,
typename T1,
typename T2,
typename T3>
3432 const T2 &grad_weight,
3433 const T3 &indices_1,
3434 const T3 &indices_2)
3437 const VectorizedArrayType val = temp_1 - grad_weight * temp_2;
3438 const VectorizedArrayType grad = grad_weight * temp_2;
3443 template <
typename T0,
typename T1,
typename T2>
3451 template <
typename T0,
typename T1,
typename T2>
3457 const T2 &grad_weight)
3460 const Number val = temp_1 - grad_weight * temp_2;
3461 const Number grad = grad_weight * temp_2;
3466 template <
typename T0,
typename T1>
std::uint8_t get_face_no(const unsigned int v=0) const
internal::MatrixFreeFunctions::DoFInfo::DoFAccessIndex get_dof_access_index() const
ScalarNumber shape_info_number_type
const ShapeInfoType & get_shape_info() 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
virtual RangeNumberType value(const Point< dim > &p, const unsigned int component=0) const
void gather(const Number *base_ptr, const unsigned int *offsets)
void load(const OtherNumber *ptr)
#define DEAL_II_ALWAYS_INLINE
#define DEAL_II_OPENMP_SIMD_PRAGMA
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
#define DEAL_II_ASSERT_UNREACHABLE()
#define DEAL_II_NOT_IMPLEMENTED()
static ::ExceptionBase & ExcNotImplemented()
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcInternalError()
#define AssertThrow(cond, exc)
@ tensor_symmetric_no_collocation
@ tensor_symmetric_hermite
std::vector< index_type > data
EvaluationFlags
The EvaluationFlags enum.
* * * RotationFunction< dim, Number >::RotationFunction Number(dim)
constexpr T fixed_power(const T t)
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)
std::enable_if_t<(variant==evaluate_general), void > apply_matrix_vector_product(const Number2 *matrix, const Number *in, Number *out)
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)
std::enable_if_t< contract_onto_face, void > interpolate_to_face(const Number2 *shape_values, const std::array< int, 2 > &n_blocks, const std::array< int, 2 > &steps, const Number *input, Number *DEAL_II_RESTRICT output, const int n_rows_runtime=0, const int stride_runtime=1)
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)
constexpr 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 EvaluationFlags::EvaluationFlags integration_flag, Number *values_dofs, FEEvaluationData< dim, Number, true > &fe_eval, const bool sum_into_values)
static bool run(const unsigned int n_components, const EvaluationFlags::EvaluationFlags evaluation_flag, FEEvaluationData< dim, Number, true > &fe_eval)
static void evaluate_in_face(const unsigned int n_components, const EvaluationFlags::EvaluationFlags evaluation_flag, FEEvaluationData< dim, Number, true > &fe_eval, Number *temp, Number *scratch_data)
static void project_to_face(const unsigned int n_components, const EvaluationFlags::EvaluationFlags evaluation_flag, const Number *values_dofs, FEEvaluationData< dim, Number, true > &fe_eval, const bool use_vectorization, Number *temp, Number *scratch_data)
static bool evaluate_tensor_none(const unsigned int n_components, const EvaluationFlags::EvaluationFlags evaluation_flag, const Number *values_dofs, FEEvaluationData< dim, Number, true > &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)
static void adjust_quadrature_for_face_orientation(const unsigned int n_components, const EvaluationFlags::EvaluationFlags evaluation_flag, FEEvaluationData< dim, Number, true > &fe_eval, const bool use_vectorization, Number *temp)
static bool evaluate_tensor(const unsigned int n_components, const EvaluationFlags::EvaluationFlags evaluation_flag, const Number *values_dofs_actual, FEEvaluationData< dim, Number, true > &fe_eval)
void hermite_grad(T0 &temp_1, T0 &temp_2, const T1 &src_ptr_1, const T1 &src_ptr_2, const T2 &grad_weight)
static const int fe_degree_
static const bool do_integrate
void value_vectorized(T1 &temp, const T2 src_ptr)
void value(T1 &temp, const T2 &src_ptr)
VectorizedArrayType VectorizedArrayType_
void value_vectorized_indexed(T0 &temp, const T1 src_ptr, const T2 &indices)
void hermite_grad_vectorized(T0 &temp_1, T0 &temp_2, const T1 src_ptr_1, const T1 src_ptr_2, const T2 &grad_weight)
void hermite_grad_vectorized_indexed(T0 &temp_1, T0 &temp_2, const T1 src_ptr_1, const T1 src_ptr_2, const T2 &grad_weight, const T3 &indices_1, const T3 &indices_2)
typename VectorizedArrayType::value_type Number
static bool run(const unsigned int n_components, const EvaluationFlags::EvaluationFlags evaluation_flag, const Number2 *src_ptr, const std::vector< ArrayView< const Number2 > > *sm_ptr, FEEvaluationData< dim, VectorizedArrayType, true > &fe_eval)
static bool supports(const EvaluationFlags::EvaluationFlags evaluation_flag, const MatrixFreeFunctions::ShapeInfo< Number3 > &shape_info, const Number2 *vector_ptr, MatrixFreeFunctions::DoFInfo::IndexStorageVariants storage)
static bool run(const unsigned int n_components, const EvaluationFlags::EvaluationFlags integration_flag, FEEvaluationData< dim, Number, true > &fe_eval)
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 integrate_tensor(const unsigned int n_components, const EvaluationFlags::EvaluationFlags integration_flag, Number *values_dofs_actual, FEEvaluationData< dim, Number, true > &fe_eval, const bool sum_into_values)
static bool integrate_tensor_none(const unsigned int n_components, const EvaluationFlags::EvaluationFlags integration_flag, Number *values_dofs, FEEvaluationData< dim, Number, true > &fe_eval, const bool sum_into_values)
static void collect_from_face(const unsigned int n_components, const EvaluationFlags::EvaluationFlags integration_flag, Number *values_dofs, FEEvaluationData< dim, Number, true > &fe_eval, const bool use_vectorization, const Number *temp, Number *scratch_data, const bool sum_into_values)
static bool run(const unsigned int n_components, const EvaluationFlags::EvaluationFlags integration_flag, Number *values_dofs, FEEvaluationData< dim, Number, true > &fe_eval, const bool sum_into_values)
static void integrate_in_face(const unsigned int n_components, const EvaluationFlags::EvaluationFlags integration_flag, FEEvaluationData< dim, Number, true > &fe_eval, Number *temp, Number *scratch_data)
static void adjust_quadrature_for_face_orientation(const unsigned int n_components, const EvaluationFlags::EvaluationFlags integration_flag, FEEvaluationData< dim, Number, true > &fe_eval, const bool use_vectorization, Number *temp)
static bool run(const unsigned int n_components, const EvaluationFlags::EvaluationFlags evaluation_flag, const Number *values_dofs, FEEvaluationData< dim, Number, true > &fe_eval)
static void evaluate_or_integrate_in_face(const EvaluationFlags::EvaluationFlags evaluation_flag, const std::vector< MatrixFreeFunctions::UnivariateShapeData< Number2 > > &shape_data, Number *values_dofs_in, Number *values, Number *gradients, Number *scratch_data, const unsigned int subface_index, const unsigned int face_direction)
typename FEEvaluationData< dim, Number, true >::shape_info_number_type Number2
EvaluatorTensorProduct< symmetric_evaluate ? evaluate_evenodd :evaluate_general, dim - 1, fe_degree+1, n_q_points_1d, Number, Number2 > Eval
static void evaluate_in_face(const unsigned int n_components, const EvaluationFlags::EvaluationFlags evaluation_flag, const MatrixFreeFunctions::UnivariateShapeData< Number2 > &data, Number *values_dofs, Number *values_quad, Number *gradients_quad, Number *hessians_quad, Number *scratch_data, const unsigned int subface_index)
static Eval create_evaluator_tensor_product(const MatrixFreeFunctions::UnivariateShapeData< Number2 > &data, const unsigned int subface_index, const unsigned int direction)
static void integrate_in_face(const unsigned int n_components, const EvaluationFlags::EvaluationFlags integration_flag, const MatrixFreeFunctions::UnivariateShapeData< Number2 > &data, Number *values_dofs, Number *values_quad, Number *gradients_quad, Number *hessians_quad, Number *scratch_data, const unsigned int subface_index)
typename FEEvaluationData< dim, Number, true >::shape_info_number_type Number2
typename FEEvaluationData< dim, Number, true >::shape_info_number_type Number2
static void interpolate_quadrature(const unsigned int n_components, const EvaluationFlags::EvaluationFlags flags, const MatrixFreeFunctions::ShapeInfo< Number2 > &shape_info, const Number *input, Number *output, const unsigned int face_no)
static void interpolate_generic(const unsigned int n_components, const Number *input, Number *output, const EvaluationFlags::EvaluationFlags flag, const unsigned int face_no, const unsigned int n_points_1d, const std::array< AlignedVector< Number2 >, 2 > &shape_data, const unsigned int dofs_per_component_on_cell, const unsigned int dofs_per_component_on_face)
static void interpolate(const unsigned int n_components, const EvaluationFlags::EvaluationFlags flags, const MatrixFreeFunctions::ShapeInfo< Number2 > &shape_info, const Number *input, Number *output, const unsigned int face_no)
static void interpolate_raviart_thomas(const unsigned int n_components, const Number *input, Number *output, const EvaluationFlags::EvaluationFlags flag, const unsigned int face_no, const MatrixFreeFunctions::ShapeInfo< Number2 > &shape_info)
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