16#ifndef dealii_matrix_free_evaluation_kernels_face_h
17#define dealii_matrix_free_evaluation_kernels_face_h
38 template <
bool symmetric_evaluate,
64 const unsigned int subface_index,
65 const unsigned int direction)
67 if (symmetric_evaluate)
81 const unsigned int index =
82 direction == 0 ? subface_index % 2 : subface_index / 2;
93 const unsigned int n_components,
98 Number *gradients_quad,
99 Number *hessians_quad,
100 Number *scratch_data,
101 const unsigned int subface_index)
106 const std::size_t n_dofs = fe_degree > -1 ?
109 const std::size_t n_q_points =
114 Number *values_dofs_ptr = values_dofs;
118 for (
unsigned int c = 0; c < n_components; ++c)
123 eval0.template values<0, true, false>(values_dofs,
125 eval1.template values<1, true, false>(values_quad,
129 eval0.template values<0, true, false>(values_dofs,
133 values_quad[0] = values_dofs[0];
140 values_dofs += 3 * n_dofs;
141 values_quad += n_q_points;
144 for (
unsigned int c = 0; c < n_components; ++c)
149 if (symmetric_evaluate &&
152 eval0.template values<0, true, false>(values_dofs,
154 eval0.template values<1, true, false>(values_quad,
163 eval_grad.template gradients<0, true, false, 3>(
164 values_quad, gradients_quad);
165 eval_grad.template gradients<1, true, false, 3>(
166 values_quad, gradients_quad + 1);
171 eval0.template gradients<0, true, false>(values_dofs,
173 eval1.template values<1, true, false, 3>(scratch_data,
177 eval0.template values<0, true, false>(values_dofs,
179 eval1.template gradients<1, true, false, 3>(
180 scratch_data, gradients_quad + 1);
183 eval1.template values<1, true, false>(scratch_data,
187 eval0.template values<0, true, false>(values_dofs + n_dofs,
189 eval1.template values<1, true, false, 3>(scratch_data,
194 eval0.template values<0, true, false, 2>(values_dofs + n_dofs,
196 eval0.template gradients<0, true, false, 2>(values_dofs,
199 eval0.template values<0, true, false>(values_dofs,
203 values_quad[0] = values_dofs[0];
204 gradients_quad[0] = values_dofs[1];
209 values_dofs += 3 * n_dofs;
210 values_quad += n_q_points;
211 gradients_quad += dim * n_q_points;
216 values_dofs = values_dofs_ptr;
217 for (
unsigned int c = 0; c < n_components; ++c)
223 eval0.template hessians<0, true, false>(values_dofs,
225 eval1.template values<1, true, false>(scratch_data,
229 eval0.template values<0, true, false>(values_dofs,
231 eval1.template hessians<1, true, false>(scratch_data,
236 eval0.template values<0, true, false>(values_dofs +
239 eval1.template values<1, true, false>(scratch_data,
244 eval0.template gradients<0, true, false>(values_dofs,
246 eval1.template gradients<1, true, false>(scratch_data,
251 eval0.template gradients<0, true, false>(values_dofs +
254 eval1.template values<1, true, false>(scratch_data,
259 eval0.template values<0, true, false>(values_dofs + n_dofs,
261 eval1.template gradients<1, true, false>(scratch_data,
268 eval0.template hessians<0, true, false>(values_dofs,
271 eval0.template values<0, true, false>(
272 values_dofs + 2 * n_dofs, hessians_quad + n_q_points);
274 eval0.template gradients<0, true, false>(
275 values_dofs + n_dofs, hessians_quad + 2 * n_q_points);
278 hessians_quad[0] = values_dofs[2];
283 values_dofs += 3 * n_dofs;
284 hessians_quad += dim * (dim + 1) / 2 * n_q_points;
291 const unsigned int n_components,
296 Number *gradients_quad,
297 Number *hessians_quad,
298 Number *scratch_data,
299 const unsigned int subface_index)
304 const std::size_t n_dofs =
308 const std::size_t n_q_points =
313 Number *values_dofs_ptr = values_dofs;
317 for (
unsigned int c = 0; c < n_components; ++c)
322 eval1.template values<1, false, false>(values_quad,
324 eval0.template values<0, false, false>(values_quad,
328 eval0.template values<0, false, false>(values_quad,
332 values_dofs[0] = values_quad[0];
337 values_dofs += 3 * n_dofs;
338 values_quad += n_q_points;
341 for (
unsigned int c = 0; c < n_components; ++c)
347 eval1.template values<1, false, false, 3>(gradients_quad + 2,
349 eval0.template values<0, false, false>(scratch_data,
350 values_dofs + n_dofs);
351 if (symmetric_evaluate &&
362 eval_grad.template gradients<1, false, true, 3>(
363 gradients_quad + 1, values_quad);
365 eval_grad.template gradients<1, false, false, 3>(
366 gradients_quad + 1, values_quad);
367 eval_grad.template gradients<0, false, true, 3>(
368 gradients_quad, values_quad);
369 eval0.template values<1, false, false>(values_quad,
371 eval0.template values<0, false, false>(values_quad,
378 eval1.template values<1, false, false>(values_quad,
380 eval1.template gradients<1, false, true, 3>(
381 gradients_quad + 1, scratch_data);
384 eval1.template gradients<1, false, false, 3>(
385 gradients_quad + 1, scratch_data);
388 eval0.template values<0, false, false>(scratch_data,
392 eval1.template values<1, false, false, 3>(gradients_quad,
394 eval0.template gradients<0, false, true>(scratch_data,
399 eval0.template values<0, false, false, 2>(gradients_quad + 1,
402 eval0.template gradients<0, false, false, 2>(gradients_quad,
405 eval0.template values<0, false, true>(values_quad,
409 values_dofs[0] = values_quad[0];
410 values_dofs[1] = gradients_quad[0];
415 values_dofs += 3 * n_dofs;
416 values_quad += n_q_points;
417 gradients_quad += dim * n_q_points;
422 values_dofs = values_dofs_ptr;
423 for (
unsigned int c = 0; c < n_components; ++c)
429 eval1.template values<1, false, false>(hessians_quad,
433 eval0.template hessians<0, false, true>(scratch_data,
436 eval0.template hessians<0, false, false>(scratch_data,
440 eval1.template hessians<1, false, false>(hessians_quad +
443 eval0.template values<0, false, true>(scratch_data,
447 eval1.template values<1, false, false>(hessians_quad +
450 eval0.template values<0, false, false>(scratch_data,
455 eval1.template gradients<1, false, false>(hessians_quad +
458 eval0.template gradients<0, false, true>(scratch_data,
462 eval1.template values<1, false, false>(hessians_quad +
466 eval0.template gradients<0, false, true>(scratch_data,
470 eval0.template gradients<0, false, false>(scratch_data,
475 eval1.template gradients<1, false, false>(hessians_quad +
478 eval0.template values<0, false, true>(scratch_data,
479 values_dofs + n_dofs);
486 eval0.template hessians<0, false, true>(hessians_quad,
489 eval0.template hessians<0, false, false>(hessians_quad,
493 eval0.template values<0, false, false>(
494 hessians_quad + n_q_points, values_dofs + 2 * n_dofs);
497 eval0.template gradients<0, false, true>(
498 hessians_quad + 2 * n_q_points, values_dofs + n_dofs);
500 eval0.template gradients<0, false, false>(
501 hessians_quad + 2 * n_q_points, values_dofs + n_dofs);
504 values_dofs[2] = hessians_quad[0];
513 values_dofs += 3 * n_dofs;
514 hessians_quad += dim * (dim + 1) / 2 * n_q_points;
522 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
532 template <
bool do_
integrate>
538 Number *values_dofs_in,
541 Number *scratch_data,
542 const unsigned int subface_index,
543 const unsigned int face_direction)
547 const int degree = fe_degree != -1 ? fe_degree : shape_data[0].fe_degree;
548 const int n_rows_n = degree + 1;
549 const int n_rows_t = degree;
550 const ::ndarray<int, 3, 3> dofs_per_direction{
551 {{{n_rows_n, n_rows_t, n_rows_t}},
552 {{n_rows_t, n_rows_n, n_rows_t}},
553 {{n_rows_t, n_rows_t, n_rows_n}}}};
564 (fe_degree > 0 ? fe_degree : 0),
569 std::array<int, dim> values_dofs_offsets = {};
570 for (
unsigned int comp = 0; comp < dim - 1; ++comp)
573 values_dofs_offsets[comp + 1] =
574 values_dofs_offsets[comp] +
575 3 * dofs_per_direction[comp][(face_direction + 1) % dim];
577 values_dofs_offsets[comp + 1] =
578 values_dofs_offsets[comp] +
579 3 * dofs_per_direction[comp][(face_direction + 1) % dim] *
580 dofs_per_direction[comp][(face_direction + 2) % dim];
586 std::array<unsigned int, dim> components;
587 for (
unsigned int comp = 0; comp < dim; ++comp)
588 components[comp] = (face_direction + comp + 1) % dim;
590 for (
const unsigned int comp : components)
592 Number *values_dofs = values_dofs_in + values_dofs_offsets[comp];
594 std::array<int, 2> n_blocks{
595 {dofs_per_direction[comp][(face_direction + 1) % dim],
596 (dim > 2 ? dofs_per_direction[comp][(face_direction + 2) % dim] :
599 if constexpr (dim == 3)
608 shape_data[0].shape_gradients_collocation_eo.data(),
618 if (n_blocks[0] == n_rows_n)
620 eval.template normal<0>(shape_data[0],
623 eval.template tangential<1, 0>(shape_data[1],
629 eval.template normal<0>(shape_data[0],
631 n_blocks[0] * n_blocks[1],
633 eval.template tangential<1, 0, dim>(shape_data[1],
638 else if (n_blocks[1] == n_rows_n)
640 eval.template normal<1>(shape_data[0],
643 eval.template tangential<0, 1>(shape_data[1],
649 eval.template normal<1>(shape_data[0],
651 n_blocks[0] * n_blocks[1],
653 eval.template tangential<0, 1, dim>(shape_data[1],
660 Eval eval(shape_data[1].shape_values_eo.data(), {}, {});
661 eval.template values<0, true, false>(values_dofs, values);
662 eval.template values<1, true, false>(values, values);
665 eval.template values<0, true, false>(values_dofs +
669 eval.template values<1, true, false, dim>(
670 scratch_data, gradients + 2);
675 eval_g.template gradients<0, true, false, dim>(values,
677 eval_g.template gradients<1, true, false, dim>(values,
693 eval_g.template gradients<0, false, true, dim>(
696 eval_g.template gradients<0, false, false, dim>(
698 eval_g.template gradients<1, false, true, dim>(gradients +
702 if (n_blocks[0] == n_rows_n)
704 eval.template tangential<1, 0>(shape_data[1],
707 eval.template normal<0>(shape_data[0],
713 eval.template tangential<1, 0, dim>(shape_data[1],
716 eval.template normal<0>(shape_data[0],
719 n_blocks[0] * n_blocks[1]);
722 else if (n_blocks[1] == n_rows_n)
724 eval.template tangential<0, 1>(shape_data[1],
727 eval.template normal<1>(shape_data[0],
733 eval.template tangential<0, 1, dim>(shape_data[1],
736 eval.template normal<1>(shape_data[0],
739 n_blocks[0] * n_blocks[1]);
744 Eval eval_iso(shape_data[1].shape_values_eo.data(),
747 eval_iso.template values<1, false, false>(values, values);
748 eval_iso.template values<0, false, false>(values,
752 eval_iso.template values<1, false, false, dim>(
753 gradients + 2, scratch_data);
754 eval_iso.template values<0, false, false>(
756 values_dofs + n_blocks[0] * n_blocks[1]);
772 if (n_blocks[0] == n_rows_n)
774 EvalN eval(shape_data[0].shape_values_eo,
775 shape_data[0].shape_gradients_eo,
777 eval.template values<0, true, false>(values_dofs, values);
780 eval.template gradients<0, true, false, dim>(
781 values_dofs, gradients);
782 eval.template values<0, true, false, dim>(
783 values_dofs + n_rows_n, gradients + 1);
788 Eval eval(shape_data[1].shape_values_eo,
789 shape_data[1].shape_gradients_eo,
791 eval.template values<0, true, false>(values_dofs, values);
794 eval.template gradients<0, true, false, dim>(
795 values_dofs, gradients);
796 eval.template values<0, true, false, dim>(
797 values_dofs + n_rows_t, gradients + 1);
804 if (n_blocks[0] == n_rows_n)
806 EvalN eval(shape_data[0].shape_values_eo,
807 shape_data[0].shape_gradients_eo,
810 eval.template values<0, false, false>(values,
815 eval.template gradients<0, false, true, dim>(
816 gradients, values_dofs);
818 eval.template gradients<0, false, false, dim>(
819 gradients, values_dofs);
820 eval.template values<0, false, false, dim>(
821 gradients + 1, values_dofs + n_rows_n);
826 Eval eval(shape_data[1].shape_values_eo,
827 shape_data[1].shape_gradients_eo,
830 eval.template values<0, false, false>(values,
835 eval.template gradients<0, false, true, dim>(
836 gradients, values_dofs);
838 eval.template gradients<0, false, false, dim>(
839 gradients, values_dofs);
840 eval.template values<0, false, false, dim>(
841 gradients + 1, values_dofs + n_rows_t);
854 template <
int dim,
int fe_degree,
typename Number>
860 template <
bool do_evaluate,
bool add_
into_output>
867 const unsigned int face_no)
869 Assert(
static_cast<unsigned int>(fe_degree) ==
870 shape_info.
data.front().fe_degree ||
874 interpolate_raviart_thomas<do_evaluate, add_into_output>(
875 n_components, input, output, flags, face_no, shape_info);
877 interpolate_generic<do_evaluate, add_into_output>(
883 shape_info.
data.front().fe_degree + 1,
884 shape_info.
data.front().shape_data_on_face,
892 template <
bool do_evaluate,
bool add_
into_output>
895 const unsigned int n_components,
900 const unsigned int face_no)
902 Assert(
static_cast<unsigned int>(fe_degree + 1) ==
903 shape_info.
data.front().n_q_points_1d ||
907 interpolate_generic<do_evaluate, add_into_output>(
913 shape_info.
data.front().quadrature.size(),
914 shape_info.
data.front().quadrature_data_on_face,
920 template <
bool do_evaluate,
bool add_
into_output,
int face_direction = 0>
926 const unsigned int face_no,
927 const unsigned int n_points_1d,
929 const unsigned int dofs_per_component_on_cell,
930 const unsigned int dofs_per_component_on_face)
932 if (face_direction == face_no / 2)
934 constexpr int stride_ =
Utilities::pow(fe_degree + 1, face_direction);
936 const int n_rows = fe_degree != -1 ? fe_degree + 1 : n_points_1d;
938 const std::array<int, 2> n_blocks{
939 {(dim > 1 ? n_rows : 1), (dim > 2 ? n_rows : 1)}};
940 std::array<int, 2> steps;
941 if constexpr (face_direction == 0)
942 steps = {{n_rows, 0}};
943 else if constexpr (face_direction == 1 && dim == 2)
945 else if constexpr (face_direction == 1)
947 steps = {{n_rows * n_rows, -n_rows * n_rows * n_rows + 1}};
948 else if constexpr (face_direction == 2)
951 for (
unsigned int c = 0; c < n_components; ++c)
958 2>(shape_data[face_no % 2].begin(),
970 1>(shape_data[face_no % 2].begin(),
982 0>(shape_data[face_no % 2].begin(),
991 input += dofs_per_component_on_cell;
992 output += dofs_per_component_on_face;
996 output += dofs_per_component_on_cell;
997 input += dofs_per_component_on_face;
1001 else if (face_direction < dim)
1005 std::min(face_direction + 1, dim - 1)>(
1013 dofs_per_component_on_cell,
1014 dofs_per_component_on_face);
1018 template <
bool do_evaluate,
1019 bool add_into_output,
1020 int face_direction = 0,
1021 int max_derivative = 0>
1024 const unsigned int n_components,
1025 const Number *input,
1028 const unsigned int face_no,
1040 bool increase_max_der =
false;
1043 increase_max_der =
true;
1045 if (face_direction == face_no / 2 && !increase_max_der)
1047 constexpr int stride1 =
Utilities::pow(fe_degree + 1, face_direction);
1048 constexpr int stride0 =
Utilities::pow(fe_degree, face_direction);
1049 constexpr int stride2 = fe_degree * (fe_degree + 1);
1052 fe_degree != -1 ? fe_degree : shape_info.
data[0].fe_degree;
1053 const int n_rows_n = degree + 1;
1054 const int n_rows_t = degree;
1056 std::array<int, 3> strides{{1, 1, 1}};
1057 if (face_direction > 0)
1061 strides[1] = n_rows_t * (face_direction == 3 ? n_rows_n : 1);
1064 const ::ndarray<int, 3, 3> dofs_per_direction{
1065 {{{n_rows_n, n_rows_t, n_rows_t}},
1066 {{n_rows_t, n_rows_n, n_rows_t}},
1067 {{n_rows_t, n_rows_t, n_rows_n}}}};
1069 std::array<int, 2> steps, n_blocks;
1071 if constexpr (face_direction == 0)
1072 steps = {{degree + (face_direction == 0), 0}};
1073 else if constexpr (face_direction == 1 && dim == 2)
1075 else if constexpr (face_direction == 1)
1078 {n_rows_n * n_rows_t, -n_rows_n * n_rows_t * n_rows_t + 1}};
1079 else if constexpr (face_direction == 2)
1082 n_blocks[0] = dofs_per_direction[0][(face_direction + 1) % dim];
1084 dim > 2 ? dofs_per_direction[0][(face_direction + 2) % dim] : 1;
1087 (fe_degree != -1 ? (fe_degree + (face_direction == 0)) : 0),
1088 ((face_direction < 2) ? stride1 : stride2),
1091 max_derivative>(shape_info.
data[face_direction != 0]
1092 .shape_data_on_face[face_no % 2]
1098 degree + (face_direction == 0),
1104 output += 3 * n_blocks[0] * n_blocks[1];
1109 input += 3 * n_blocks[0] * n_blocks[1];
1113 if constexpr (face_direction == 0)
1114 steps = {{degree, 0}};
1116 n_blocks[0] = dofs_per_direction[1][(face_direction + 1) % dim];
1118 dim > 2 ? dofs_per_direction[1][(face_direction + 2) % dim] : 1;
1121 (fe_degree != -1 ? (fe_degree + (face_direction == 1)) : 0),
1122 ((face_direction < 2) ? stride0 : stride2),
1125 max_derivative>(shape_info.
data[face_direction != 1]
1126 .shape_data_on_face[face_no % 2]
1132 degree + (face_direction == 1),
1135 if constexpr (dim > 2)
1140 output += 3 * n_blocks[0] * n_blocks[1];
1145 input += 3 * n_blocks[0] * n_blocks[1];
1148 if constexpr (face_direction == 0)
1149 steps = {{degree, 0}};
1150 else if constexpr (face_direction == 1)
1153 {n_rows_t * n_rows_t, -n_rows_n * n_rows_t * n_rows_t + 1}};
1154 else if constexpr (face_direction == 2)
1157 n_blocks[0] = dofs_per_direction[2][(face_direction + 1) % dim];
1158 n_blocks[1] = dofs_per_direction[2][(face_direction + 2) % dim];
1161 (fe_degree != -1 ? (fe_degree + (face_direction == 2)) : 0),
1165 max_derivative>(shape_info.
data[face_direction != 2]
1166 .shape_data_on_face[face_no % 2]
1172 degree + (face_direction == 2),
1176 else if (face_direction == face_no / 2)
1183 n_components, input, output, flag, face_no, shape_info);
1185 else if (face_direction < dim)
1187 if (increase_max_der)
1191 std::min(face_direction + 1, dim - 1),
1193 n_components, input, output, flag, face_no, shape_info);
1199 std::min(face_direction + 1, dim - 1),
1201 n_components, input, output, flag, face_no, shape_info);
1210 template <
typename VectorizedArrayType,
typename Number2>
1214 for (
unsigned int v = 0; v < VectorizedArrayType::size(); ++v)
1215 dst[v] = src_ptr[v];
1222 template <
typename Number, std::
size_t w
idth>
1232 template <
typename VectorizedArrayType,
typename Number2>
1235 const unsigned int *indices,
1236 VectorizedArrayType &dst)
1238 for (
unsigned int v = 0; v < VectorizedArrayType::size(); ++v)
1239 dst[v] = src_ptr[indices[v]];
1246 template <
typename Number, std::
size_t w
idth>
1249 const unsigned int *indices,
1252 dst.
gather(src_ptr, indices);
1258 template <
typename VectorizedArrayType,
typename Number2>
1262 for (
unsigned int v = 0; v < VectorizedArrayType::size(); ++v)
1263 dst_ptr[v] += src[v];
1270 template <
typename Number, std::
size_t w
idth>
1276 (tmp + src).store(dst_ptr);
1282 template <
typename VectorizedArrayType,
typename Number2>
1285 const unsigned int *indices,
1288 for (
unsigned int v = 0; v < VectorizedArrayType::size(); ++v)
1289 dst_ptr[indices[v]] += src[v];
1296 template <
typename Number, std::
size_t w
idth>
1299 const unsigned int *indices,
1302#if DEAL_II_VECTORIZATION_WIDTH_IN_BITS < 512
1303 for (
unsigned int v = 0; v < width; ++v)
1304 dst_ptr[indices[v]] += src[v];
1307 tmp.
gather(dst_ptr, indices);
1308 (tmp + src).scatter(indices, dst_ptr);
1314 template <
typename Number>
1317 const unsigned int n_components,
1319 const unsigned int *orientation,
1320 const bool integrate,
1321 const std::size_t n_q_points,
1323 Number *values_quad,
1324 Number *gradients_quad,
1325 Number *hessians_quad)
1327 for (
unsigned int c = 0; c < n_components; ++c)
1332 for (
unsigned int q = 0; q < n_q_points; ++q)
1333 tmp_values[q] = values_quad[c * n_q_points + orientation[q]];
1335 for (
unsigned int q = 0; q < n_q_points; ++q)
1336 tmp_values[orientation[q]] = values_quad[c * n_q_points + q];
1337 for (
unsigned int q = 0; q < n_q_points; ++q)
1338 values_quad[c * n_q_points + q] = tmp_values[q];
1341 for (
unsigned int d = 0; d < dim; ++d)
1344 for (
unsigned int q = 0; q < n_q_points; ++q)
1346 gradients_quad[(c * n_q_points + orientation[q]) * dim + d];
1348 for (
unsigned int q = 0; q < n_q_points; ++q)
1349 tmp_values[orientation[q]] =
1350 gradients_quad[(c * n_q_points + q) * dim + d];
1351 for (
unsigned int q = 0; q < n_q_points; ++q)
1352 gradients_quad[(c * n_q_points + q) * dim + d] = tmp_values[q];
1356 const unsigned int hdim = (dim * (dim + 1)) / 2;
1357 for (
unsigned int d = 0; d < hdim; ++d)
1360 for (
unsigned int q = 0; q < n_q_points; ++q)
1361 tmp_values[q] = hessians_quad[(c * hdim + d) * n_q_points +
1364 for (
unsigned int q = 0; q < n_q_points; ++q)
1365 tmp_values[orientation[q]] =
1366 hessians_quad[(c * hdim + d) * n_q_points + q];
1367 for (
unsigned int q = 0; q < n_q_points; ++q)
1368 hessians_quad[(c * hdim + d) * n_q_points + q] =
1377 template <
typename Number,
typename VectorizedArrayType>
1380 const unsigned int dim,
1381 const unsigned int n_components,
1382 const unsigned int v,
1384 const unsigned int *orientation,
1385 const bool integrate,
1386 const std::size_t n_q_points,
1388 VectorizedArrayType *values_quad,
1389 VectorizedArrayType *gradients_quad =
nullptr,
1390 VectorizedArrayType *hessians_quad =
nullptr)
1392 for (
unsigned int c = 0; c < n_components; ++c)
1397 for (
unsigned int q = 0; q < n_q_points; ++q)
1398 tmp_values[q] = values_quad[c * n_q_points + orientation[q]][v];
1400 for (
unsigned int q = 0; q < n_q_points; ++q)
1401 tmp_values[orientation[q]] = values_quad[c * n_q_points + q][v];
1402 for (
unsigned int q = 0; q < n_q_points; ++q)
1403 values_quad[c * n_q_points + q][v] = tmp_values[q];
1406 for (
unsigned int d = 0; d < dim; ++d)
1410 for (
unsigned int q = 0; q < n_q_points; ++q)
1412 gradients_quad[(c * n_q_points + orientation[q]) * dim + d]
1415 for (
unsigned int q = 0; q < n_q_points; ++q)
1416 tmp_values[orientation[q]] =
1417 gradients_quad[(c * n_q_points + q) * dim + d][v];
1418 for (
unsigned int q = 0; q < n_q_points; ++q)
1419 gradients_quad[(c * n_q_points + q) * dim + d][v] =
1425 const unsigned int hdim = (dim * (dim + 1)) / 2;
1426 for (
unsigned int d = 0; d < hdim; ++d)
1429 for (
unsigned int q = 0; q < n_q_points; ++q)
1430 tmp_values[q] = hessians_quad[(c * hdim + d) * n_q_points +
1433 for (
unsigned int q = 0; q < n_q_points; ++q)
1434 tmp_values[orientation[q]] =
1435 hessians_quad[(c * hdim + d) * n_q_points + q][v];
1436 for (
unsigned int q = 0; q < n_q_points; ++q)
1437 hessians_quad[(c * hdim + d) * n_q_points + q][v] =
1446 template <
int dim,
typename Number>
1452 const Number *values_dofs,
1456 const auto &shape_data = shape_info.
data.front();
1465 const unsigned int face_no = fe_eval.
get_face_no();
1467 const std::size_t n_dofs = shape_info.dofs_per_component_on_cell;
1468 const std::size_t n_q_points = shape_info.n_q_points_faces[face_no];
1472 const auto *
const shape_values =
1473 &shape_data.shape_values_face(face_no, face_orientation, 0);
1476 auto *in = values_dofs;
1478 for (
unsigned int c = 0; c < n_components; ++c)
1485 shape_values, in, out, n_dofs, n_q_points, 1, 1);
1495 const auto *in = values_dofs;
1497 const auto *
const shape_gradients =
1498 &shape_data.shape_gradients_face(face_no, face_orientation, 0);
1500 for (
unsigned int c = 0; c < n_components; ++c)
1507 shape_gradients, in, out, n_dofs, n_q_points * dim, 1, 1);
1508 out += n_q_points * dim;
1519 template <
int fe_degree>
1526 const Number *values_dofs,
1528 const bool use_vectorization,
1530 Number *scratch_data)
1534 if (use_vectorization ==
false)
1536 const auto &shape_data = shape_info.
data.front();
1538 const unsigned int dofs_per_comp_face =
1542 const unsigned int dofs_per_face = n_components * dofs_per_comp_face;
1544 for (
unsigned int v = 0; v < Number::size(); ++v)
1551 for (
unsigned int i = 0; i < 3 * dofs_per_face; ++i)
1557 template interpolate<true, false>(n_components,
1564 for (
unsigned int i = 0; i < 3 * dofs_per_face; ++i)
1565 temp[i][v] = scratch_data[i][v];
1570 template interpolate<true, false>(n_components,
1579 template <
int fe_degree,
int n_q_po
ints_1d>
1588 Number *scratch_data)
1591 const auto &shape_data = shape_info.
data.front();
1594 constexpr unsigned int n_q_points_1d_actual =
1595 fe_degree > -1 ? n_q_points_1d : 0;
1601 n_q_points_1d_actual,
1603 template evaluate_or_integrate_in_face<false>(
1613 else if (fe_degree > -1 &&
1619 n_q_points_1d_actual,
1634 n_q_points_1d_actual,
1652 const unsigned int n_components,
1655 const bool use_vectorization,
1660 if (use_vectorization ==
false)
1662 for (
unsigned int v = 0; v < Number::size(); ++v)
1676 &shape_info.face_orientations_quad(
1679 shape_info.n_q_points_face,
1693 shape_info.n_q_points_face,
1702 template <
int fe_degree,
int n_q_po
ints_1d>
1706 const Number *values_dofs,
1710 const auto &shape_data = shape_info.
data.front();
1712 const unsigned int dofs_per_comp_face =
1720 Number *scratch_data = temp + 3 * n_components * dofs_per_comp_face;
1722 bool use_vectorization =
true;
1726 for (
unsigned int v = 0; v < Number::size(); ++v)
1729 use_vectorization =
false;
1731 project_to_face<fe_degree>(n_components,
1739 evaluate_in_face<fe_degree, n_q_points_1d>(
1740 n_components, evaluation_flag, fe_eval, temp, scratch_data);
1744 n_components, evaluation_flag, fe_eval, use_vectorization, temp);
1749 template <
int fe_degree,
int n_q_po
ints_1d>
1751 run(
const unsigned int n_components,
1753 const Number *values_dofs,
1764 return evaluate_tensor<fe_degree, n_q_points_1d>(n_components,
1773 template <
int dim,
typename Number>
1776 template <
int fe_degree>
1778 run(
const unsigned int n_components,
1780 const Number *values_dofs,
1784 const auto &shape_data = shape_info.
data.front();
1786 const unsigned int dofs_per_comp_face =
1794 Number *scratch_data = temp + 3 * n_components * dofs_per_comp_face;
1796 bool use_vectorization =
true;
1800 for (
unsigned int v = 0; v < Number::size(); ++v)
1803 use_vectorization =
false;
1806 template project_to_face<fe_degree>(n_components,
1820 template <
int dim,
typename Number>
1823 template <
int fe_degree,
int n_q_po
ints_1d>
1825 run(
const unsigned int n_components,
1830 const auto &shape_data = shape_info.
data.front();
1832 const unsigned int dofs_per_comp_face =
1840 Number *scratch_data = temp + 3 * n_components * dofs_per_comp_face;
1843 template evaluate_in_face<fe_degree, n_q_points_1d>(
1844 n_components, evaluation_flag, fe_eval, temp, scratch_data);
1852 template <
int dim,
typename Number>
1857 const unsigned int n_components,
1859 Number *values_dofs,
1861 const bool sum_into_values)
1864 const auto &shape_data = shape_info.
data.front();
1873 const unsigned int face_no = fe_eval.
get_face_no();
1875 const std::size_t n_dofs = shape_info.dofs_per_component_on_cell;
1876 const std::size_t n_q_points = shape_info.n_q_points_faces[face_no];
1881 const auto *
const shape_values =
1882 &shape_data.shape_values_face(face_no, face_orientation, 0);
1885 auto *out = values_dofs;
1887 for (
unsigned int c = 0; c < n_components; ++c)
1889 if (sum_into_values)
1895 shape_values, in, out, n_dofs, n_q_points, 1, 1);
1902 shape_values, in, out, n_dofs, n_q_points, 1, 1);
1911 auto *out = values_dofs;
1913 const auto *
const shape_gradients =
1914 &shape_data.shape_gradients_face(face_no, face_orientation, 0);
1916 for (
unsigned int c = 0; c < n_components; ++c)
1918 if (!sum_into_values &&
1925 shape_gradients, in, out, n_dofs, n_q_points * dim, 1, 1);
1932 shape_gradients, in, out, n_dofs, n_q_points * dim, 1, 1);
1933 in += n_q_points * dim;
1949 const unsigned int n_components,
1952 const bool use_vectorization,
1957 if (use_vectorization ==
false)
1959 for (
unsigned int v = 0; v < Number::size(); ++v)
1976 shape_info.n_q_points_face,
1991 shape_info.n_q_points_face,
1998 template <
int fe_degree,
int n_q_po
ints_1d>
2007 Number *scratch_data)
2010 const auto &shape_data = shape_info.
data.front();
2012 const unsigned int n_q_points_1d_actual =
2013 fe_degree > -1 ? n_q_points_1d : 0;
2020 n_q_points_1d_actual,
2022 template evaluate_or_integrate_in_face<true>(
2032 else if (fe_degree > -1 &&
2040 n_q_points_1d_actual,
2055 n_q_points_1d_actual,
2067 template <
int fe_degree>
2074 Number *values_dofs,
2076 const bool use_vectorization,
2078 Number *scratch_data,
2079 const bool sum_into_values)
2082 const auto &shape_data = shape_info.
data.front();
2084 const unsigned int dofs_per_comp_face =
2088 const unsigned int dofs_per_face = n_components * dofs_per_comp_face;
2090 if (use_vectorization ==
false)
2092 for (
unsigned int v = 0; v < Number::size(); ++v)
2101 template interpolate<false, false>(n_components,
2108 if (sum_into_values)
2109 for (
unsigned int i = 0; i < 3 * dofs_per_face; ++i)
2110 values_dofs[i][v] += scratch_data[i][v];
2112 for (
unsigned int i = 0; i < 3 * dofs_per_face; ++i)
2113 values_dofs[i][v] = scratch_data[i][v];
2118 if (sum_into_values)
2120 template interpolate<false, true>(n_components,
2128 template interpolate<false, false>(n_components,
2137 template <
int fe_degree,
int n_q_po
ints_1d>
2141 Number *values_dofs,
2143 const bool sum_into_values)
2146 const auto &shape_data = shape_info.
data.front();
2148 const unsigned int dofs_per_comp_face =
2154 Number *scratch_data = temp + 3 * n_components * dofs_per_comp_face;
2156 bool use_vectorization =
true;
2165 [&](
const auto &v) {
2166 return v == fe_eval.get_cell_ids()[0] ||
2167 v == numbers::invalid_unsigned_int;
2172 n_components, integration_flag, fe_eval, use_vectorization, temp);
2174 integrate_in_face<fe_degree, n_q_points_1d>(
2175 n_components, integration_flag, fe_eval, temp, scratch_data);
2177 collect_from_face<fe_degree>(n_components,
2189 template <
int fe_degree,
int n_q_po
ints_1d>
2191 run(
const unsigned int n_components,
2193 Number *values_dofs,
2195 const bool sum_into_values)
2206 return integrate_tensor<fe_degree, n_q_points_1d>(n_components,
2216 template <
int dim,
typename Number>
2219 template <
int fe_degree>
2221 run(
const unsigned int n_components,
2223 Number *values_dofs,
2225 const bool sum_into_values)
2228 const auto &shape_data = shape_info.
data.front();
2230 const unsigned int dofs_per_comp_face =
2236 Number *scratch_data = temp + 3 * n_components * dofs_per_comp_face;
2238 bool use_vectorization =
true;
2247 [&](
const auto &v) {
2248 return v == fe_eval.get_cell_ids()[0] ||
2249 v == numbers::invalid_unsigned_int;
2253 template collect_from_face<fe_degree>(n_components,
2268 template <
int dim,
typename Number>
2271 template <
int fe_degree,
int n_q_po
ints_1d>
2273 run(
const unsigned int n_components,
2279 const auto &shape_data = shape_info.
data.front();
2281 const unsigned int dofs_per_comp_face =
2287 Number *scratch_data = temp + 3 * n_components * dofs_per_comp_face;
2290 template integrate_in_face<fe_degree, n_q_points_1d>(
2291 n_components, integration_flag, fe_eval, temp, scratch_data);
2299 template <
int n_face_orientations,
2301 typename EvaluationData,
2302 const bool check_face_orientations =
false>
2306 const unsigned int n_components,
2308 typename Processor::Number2_ *global_vector_ptr,
2310 const EvaluationData &fe_eval,
2311 typename Processor::VectorizedArrayType_ *temp1)
2313 constexpr int dim = Processor::dim_;
2314 constexpr int fe_degree = Processor::fe_degree_;
2315 using VectorizedArrayType =
typename Processor::VectorizedArrayType_;
2316 constexpr int n_lanes = VectorizedArrayType::size();
2318 using Number =
typename Processor::Number_;
2319 using Number2_ =
typename Processor::Number2_;
2321 const auto &shape_data = fe_eval.get_shape_info().data.front();
2322 constexpr bool integrate = Processor::do_integrate;
2323 const unsigned int face_no = fe_eval.get_face_no();
2324 const auto &dof_info = fe_eval.get_dof_info();
2325 const unsigned int cell = fe_eval.get_cell_or_face_batch_id();
2327 fe_eval.get_dof_access_index();
2329 dof_info.index_storage_variants[dof_access_index].size());
2330 constexpr unsigned int dofs_per_face =
2332 const unsigned int subface_index = fe_eval.get_subface_index();
2334 const unsigned int n_filled_lanes =
2335 dof_info.n_vectorization_lanes_filled[dof_access_index][cell];
2337 bool all_faces_are_same = n_filled_lanes == n_lanes;
2338 if (n_face_orientations == n_lanes)
2339 for (
unsigned int v = 1; v < n_lanes; ++v)
2340 if (fe_eval.get_face_no(v) != fe_eval.get_face_no(0) ||
2341 fe_eval.get_face_orientation(v) != fe_eval.get_face_orientation(0))
2343 all_faces_are_same =
false;
2348 std::array<const unsigned int *, n_face_orientations> orientation = {};
2350 if (dim == 3 && n_face_orientations == n_lanes && !all_faces_are_same &&
2351 fe_eval.is_interior_face() == 0)
2352 for (
unsigned int v = 0; v < n_lanes; ++v)
2360 if (shape_data.nodal_at_cell_boundaries &&
2361 fe_eval.get_face_orientation(v) != 0)
2366 check_face_orientations ==
false)
2380 orientation[v] = &fe_eval.get_shape_info().face_orientations_dofs(
2381 fe_eval.get_face_orientation(v), 0);
2384 else if (dim == 3 && fe_eval.get_face_orientation() != 0)
2388 check_face_orientations ==
false)
2402 for (
unsigned int v = 0; v < n_face_orientations; ++v)
2403 orientation[v] = &fe_eval.get_shape_info().face_orientations_dofs(
2404 fe_eval.get_face_orientation(), 0);
2410 VectorizedArrayType grad_weight =
2412 .shape_data_on_face[0][fe_degree + (integrate ? (2 - face_no % 2) :
2413 (1 + face_no % 2))];
2416 std::array<const unsigned int *, n_face_orientations> index_array_hermite =
2420 if (n_face_orientations == 1)
2421 index_array_hermite[0] =
2422 &fe_eval.get_shape_info().face_to_cell_index_hermite(face_no, 0);
2425 for (
unsigned int v = 0; v < n_lanes; ++v)
2430 const auto face_no = fe_eval.get_face_no(v);
2434 .shape_data_on_face[0][fe_degree + (integrate ?
2435 (2 - (face_no % 2)) :
2436 (1 + (face_no % 2)))];
2438 index_array_hermite[v] =
2439 &fe_eval.get_shape_info().face_to_cell_index_hermite(face_no,
2446 std::array<const unsigned int *, n_face_orientations> index_array_nodal =
2448 if (shape_data.nodal_at_cell_boundaries ==
true)
2450 if (n_face_orientations == 1)
2451 index_array_nodal[0] =
2452 &fe_eval.get_shape_info().face_to_cell_index_nodal(face_no, 0);
2455 for (
unsigned int v = 0; v < n_lanes; ++v)
2460 const auto face_no = fe_eval.get_face_no(v);
2462 index_array_nodal[v] =
2463 &fe_eval.get_shape_info().face_to_cell_index_nodal(face_no,
2470 const auto reorientate = [&](
const unsigned int v,
const unsigned int i) {
2471 return (!check_face_orientations || orientation[v] ==
nullptr) ?
2478 fe_eval.get_cell_ids()[0] :
2480 const unsigned int *dof_indices =
2481 &dof_info.dof_indices_contiguous[dof_access_index][
cell_index];
2483 for (
unsigned int comp = 0; comp < n_components; ++comp)
2485 const std::size_t index_offset =
2486 dof_info.component_dof_indices_offset
2487 [fe_eval.get_active_fe_index()]
2488 [fe_eval.get_first_selected_component()] +
2492 if (n_face_orientations == 1 &&
2493 dof_info.index_storage_variants[dof_access_index][cell] ==
2495 interleaved_contiguous)
2498 dof_info.n_vectorization_lanes_filled[dof_access_index][cell],
2500 Number2_ *vector_ptr =
2501 global_vector_ptr + dof_indices[0] + index_offset * n_lanes;
2505 for (
unsigned int i = 0; i < dofs_per_face; ++i)
2509 const unsigned int ind1 = index_array_hermite[0][2 * i];
2510 const unsigned int ind2 = index_array_hermite[0][2 * i + 1];
2511 const unsigned int i_ = reorientate(0, i);
2512 proc.hermite_grad_vectorized(temp1[i_],
2513 temp1[i_ + dofs_per_face],
2514 vector_ptr + ind1 * n_lanes,
2515 vector_ptr + ind2 * n_lanes,
2521 for (
unsigned int i = 0; i < dofs_per_face; ++i)
2525 const unsigned int i_ = reorientate(0, i);
2526 const unsigned int ind = index_array_nodal[0][i];
2527 proc.value_vectorized(temp1[i_],
2528 vector_ptr + ind * n_lanes);
2534 else if (n_face_orientations == 1 &&
2535 dof_info.index_storage_variants[dof_access_index][cell] ==
2537 interleaved_contiguous_strided)
2540 dof_info.n_vectorization_lanes_filled[dof_access_index][cell],
2542 Number2_ *vector_ptr = global_vector_ptr + index_offset * n_lanes;
2545 for (
unsigned int i = 0; i < dofs_per_face; ++i)
2549 const unsigned int i_ = reorientate(0, i);
2550 const unsigned int ind1 =
2551 index_array_hermite[0][2 * i] * n_lanes;
2552 const unsigned int ind2 =
2553 index_array_hermite[0][2 * i + 1] * n_lanes;
2554 proc.hermite_grad_vectorized_indexed(
2556 temp1[i_ + dofs_per_face],
2566 for (
unsigned int i = 0; i < dofs_per_face; ++i)
2570 const unsigned int i_ = reorientate(0, i);
2571 const unsigned int ind = index_array_nodal[0][i] * n_lanes;
2572 proc.value_vectorized_indexed(temp1[i_],
2580 else if (n_face_orientations == 1 &&
2581 dof_info.index_storage_variants[dof_access_index][cell] ==
2583 interleaved_contiguous_mixed_strides)
2585 const unsigned int *strides =
2586 &dof_info.dof_indices_interleave_strides[dof_access_index]
2588 unsigned int indices[n_lanes];
2589 for (
unsigned int v = 0; v < n_lanes; ++v)
2590 indices[v] = dof_indices[v] + index_offset * strides[v];
2591 const unsigned int n_filled_lanes =
2592 dof_info.n_vectorization_lanes_filled[dof_access_index][cell];
2596 if (n_filled_lanes == n_lanes)
2597 for (
unsigned int i = 0; i < dofs_per_face; ++i)
2601 const unsigned int i_ = reorientate(0, i);
2602 unsigned int ind1[n_lanes];
2604 for (
unsigned int v = 0; v < n_lanes; ++v)
2605 ind1[v] = indices[v] +
2606 index_array_hermite[0][2 * i] * strides[v];
2607 unsigned int ind2[n_lanes];
2609 for (
unsigned int v = 0; v < n_lanes; ++v)
2613 index_array_hermite[0][2 * i + 1] * strides[v];
2614 proc.hermite_grad_vectorized_indexed(
2616 temp1[i_ + dofs_per_face],
2625 if (integrate ==
false)
2626 for (
unsigned int i = 0; i < 2 * dofs_per_face; ++i)
2627 temp1[i] = VectorizedArrayType();
2629 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
2630 for (
unsigned int i = 0; i < dofs_per_face; ++i)
2632 const unsigned int i_ =
2633 reorientate(n_face_orientations == 1 ? 0 : v, i);
2636 temp1[i_ + dofs_per_face][v],
2640 [n_face_orientations == 1 ? 0 : v][2 * i] *
2644 index_array_hermite[n_face_orientations == 1 ?
2648 grad_weight[n_face_orientations == 1 ? 0 : v]);
2654 if (n_filled_lanes == n_lanes)
2655 for (
unsigned int i = 0; i < dofs_per_face; ++i)
2658 unsigned int ind[n_lanes];
2660 for (
unsigned int v = 0; v < n_lanes; ++v)
2662 indices[v] + index_array_nodal[0][i] * strides[v];
2663 const unsigned int i_ = reorientate(0, i);
2664 proc.value_vectorized_indexed(temp1[i_],
2670 if (integrate ==
false)
2671 for (
unsigned int i = 0; i < dofs_per_face; ++i)
2672 temp1[i] = VectorizedArrayType();
2674 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
2675 for (
unsigned int i = 0; i < dofs_per_face; ++i)
2677 temp1[reorientate(n_face_orientations == 1 ? 0 : v,
2681 index_array_nodal[n_face_orientations == 1 ? 0 : v]
2689 else if (n_face_orientations > 1 ||
2690 dof_info.index_storage_variants[dof_access_index][cell] ==
2694 Number2_ *vector_ptr = global_vector_ptr + index_offset;
2696 const bool vectorization_possible =
2697 all_faces_are_same && (sm_ptr ==
nullptr);
2699 std::array<Number2_ *, n_lanes> vector_ptrs{{
nullptr}};
2700 std::array<unsigned int, n_lanes> reordered_indices{
2703 if (vectorization_possible ==
false)
2705 if (n_face_orientations == 1)
2707 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
2708 if (sm_ptr ==
nullptr)
2710 vector_ptrs[v] = vector_ptr + dof_indices[v];
2716 .dof_indices_contiguous_sm[dof_access_index]
2717 [cell * n_lanes + v];
2718 vector_ptrs[v] =
const_cast<Number2_ *
>(
2719 sm_ptr->operator[](temp.first).data() +
2720 temp.second + index_offset);
2723 else if (n_face_orientations == n_lanes)
2725 const auto &cells = fe_eval.get_cell_ids();
2726 for (
unsigned int v = 0; v < n_lanes; ++v)
2729 if (sm_ptr ==
nullptr)
2734 .dof_indices_contiguous[dof_access_index]
2741 .dof_indices_contiguous_sm[dof_access_index]
2743 vector_ptrs[v] =
const_cast<Number2_ *
>(
2744 sm_ptr->operator[](temp.first).data() +
2745 temp.second + index_offset);
2754 else if (n_face_orientations == n_lanes)
2756 for (
unsigned int v = 0; v < n_lanes; ++v)
2757 reordered_indices[v] =
2758 dof_info.dof_indices_contiguous[dof_access_index]
2759 [fe_eval.get_cell_ids()[v]];
2760 dof_indices = reordered_indices.data();
2765 if (vectorization_possible)
2766 for (
unsigned int i = 0; i < dofs_per_face; ++i)
2768 const unsigned int ind1 = index_array_hermite[0][2 * i];
2769 const unsigned int ind2 =
2770 index_array_hermite[0][2 * i + 1];
2771 const unsigned int i_ = reorientate(0, i);
2773 proc.hermite_grad_vectorized_indexed(
2775 temp1[i_ + dofs_per_face],
2782 else if (n_face_orientations == 1)
2783 for (
unsigned int i = 0; i < dofs_per_face; ++i)
2785 const unsigned int ind1 = index_array_hermite[0][2 * i];
2786 const unsigned int ind2 =
2787 index_array_hermite[0][2 * i + 1];
2788 const unsigned int i_ = reorientate(0, i);
2790 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
2791 proc.hermite_grad(temp1[i_][v],
2792 temp1[i_ + dofs_per_face][v],
2793 vector_ptrs[v][ind1],
2794 vector_ptrs[v][ind2],
2797 if (integrate ==
false)
2798 for (
unsigned int v = n_filled_lanes; v < n_lanes; ++v)
2801 temp1[i + dofs_per_face][v] = 0.0;
2806 if (integrate ==
false && n_filled_lanes < n_lanes)
2807 for (
unsigned int i = 0; i < dofs_per_face; ++i)
2808 temp1[i] = temp1[i + dofs_per_face] = Number();
2810 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
2811 for (
unsigned int i = 0; i < dofs_per_face; ++i)
2813 temp1[reorientate(v, i)][v],
2814 temp1[reorientate(v, i) + dofs_per_face][v],
2815 vector_ptrs[v][index_array_hermite[v][2 * i]],
2816 vector_ptrs[v][index_array_hermite[v][2 * i + 1]],
2822 if (vectorization_possible)
2823 for (
unsigned int i = 0; i < dofs_per_face; ++i)
2825 const unsigned int ind = index_array_nodal[0][i];
2826 const unsigned int i_ = reorientate(0, i);
2828 proc.value_vectorized_indexed(temp1[i_],
2834 if constexpr (n_face_orientations == 1)
2835 for (
unsigned int i = 0; i < dofs_per_face; ++i)
2837 const unsigned int ind = index_array_nodal[0][i];
2838 const unsigned int i_ = reorientate(0, i);
2840 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
2841 proc.value(temp1[i_][v], vector_ptrs[v][ind]);
2843 if constexpr (integrate ==
false)
2844 for (
unsigned int v = n_filled_lanes; v < n_lanes;
2850 if (integrate ==
false && n_filled_lanes < n_lanes)
2851 for (
unsigned int i = 0; i < dofs_per_face; ++i)
2852 temp1[i] = Number();
2854 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
2855 for (
unsigned int i = 0; i < dofs_per_face; ++i)
2856 proc.value(temp1[reorientate(v, i)][v],
2857 vector_ptrs[v][index_array_nodal[v][i]]);
2868 temp1 += 3 * dofs_per_face;
2874 template <
int dim,
typename Number2,
typename VectorizedArrayType>
2877 using Number =
typename VectorizedArrayType::value_type;
2879 template <
int fe_degree,
int n_q_po
ints_1d>
2881 run(
const unsigned int n_components,
2883 const Number2 *src_ptr,
2892 const unsigned int dofs_per_face =
Utilities::pow(fe_degree + 1, dim - 1);
2895 VectorizedArrayType *scratch_data =
2896 temp + 3 * n_components * dofs_per_face;
2903 fe_face_evaluation_process_and_io<VectorizedArrayType::size()>(
2904 p, n_components, evaluation_flag, src_ptr, sm_ptr, fe_eval, temp);
2906 fe_face_evaluation_process_and_io<1>(
2907 p, n_components, evaluation_flag, src_ptr, sm_ptr, fe_eval, temp);
2916 VectorizedArrayType>::
2917 evaluate_in_face(n_components,
2931 VectorizedArrayType>::
2932 evaluate_in_face(n_components,
2949 for (
unsigned int v = 0; v < VectorizedArrayType::size(); ++v)
2992 template <
typename Number3>
2996 const Number2 *vector_ptr,
2999 const unsigned int fe_degree = shape_info.
data.front().fe_degree;
3000 if (fe_degree < 1 || !shape_info.
data.front().nodal_at_cell_boundaries ||
3003 shape_info.
data.front().element_type !=
3006 vector_ptr ==
nullptr ||
3007 shape_info.
data.front().element_type >
3017 template <
int fe_degree>
3027 template <
typename T0,
typename T1,
typename T2>
3033 const T2 &grad_weight)
3037 temp_2 = grad_weight * (temp_1 - temp_2);
3040 template <
typename T1,
typename T2>
3047 template <
typename T0,
typename T1,
typename T2,
typename T3>
3053 const T2 &grad_weight,
3054 const T3 &indices_1,
3055 const T3 &indices_2)
3059 temp_2 = grad_weight * (temp_1 - temp_2);
3062 template <
typename T0,
typename T1,
typename T2>
3069 template <
typename T0,
typename T1,
typename T2>
3073 const T1 &src_ptr_1,
3074 const T1 &src_ptr_2,
3075 const T2 &grad_weight)
3079 temp_2 = grad_weight * (temp_1 - src_ptr_2);
3082 template <
typename T1,
typename T2>
3094 template <
int dim,
typename Number2,
typename VectorizedArrayType>
3097 using Number =
typename VectorizedArrayType::value_type;
3099 template <
int fe_degree,
int n_q_po
ints_1d>
3101 run(
const unsigned int n_components,
3112 const unsigned int dofs_per_face =
Utilities::pow(fe_degree + 1, dim - 1);
3115 VectorizedArrayType *scratch_data =
3116 temp + 3 * n_components * dofs_per_face;
3126 for (
unsigned int v = 0; v < VectorizedArrayType::size(); ++v)
3170 VectorizedArrayType>::
3171 integrate_in_face(n_components,
3185 VectorizedArrayType>::
3186 integrate_in_face(n_components,
3201 fe_face_evaluation_process_and_io<VectorizedArrayType::size()>(
3202 p, n_components, integration_flag, dst_ptr, sm_ptr, fe_eval, temp);
3204 fe_face_evaluation_process_and_io<1>(
3205 p, n_components, integration_flag, dst_ptr, sm_ptr, fe_eval, temp);
3211 template <
int fe_degree>
3221 template <
typename T0,
typename T1,
typename T2,
typename T3,
typename T4>
3227 const T4 &grad_weight)
3230 const VectorizedArrayType val = temp_1 - grad_weight * temp_2;
3231 const VectorizedArrayType grad = grad_weight * temp_2;
3236 template <
typename T0,
typename T1>
3244 template <
typename T0,
typename T1,
typename T2,
typename T3>
3250 const T2 &grad_weight,
3251 const T3 &indices_1,
3252 const T3 &indices_2)
3255 const VectorizedArrayType val = temp_1 - grad_weight * temp_2;
3256 const VectorizedArrayType grad = grad_weight * temp_2;
3261 template <
typename T0,
typename T1,
typename T2>
3269 template <
typename T0,
typename T1,
typename T2>
3275 const T2 &grad_weight)
3278 const Number val = temp_1 - grad_weight * temp_2;
3279 const Number grad = grad_weight * temp_2;
3284 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
void gather(const Number *base_ptr, const unsigned int *offsets)
void load(const OtherNumber *ptr)
#define DEAL_II_ALWAYS_INLINE
#define DEAL_II_OPENMP_SIMD_PRAGMA
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
static ::ExceptionBase & ExcNotImplemented()
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcInternalError()
#define AssertThrow(cond, exc)
@ tensor_symmetric_no_collocation
@ tensor_symmetric_hermite
#define DEAL_II_ASSERT_UNREACHABLE()
#define DEAL_II_NOT_IMPLEMENTED()
EvaluationFlags
The EvaluationFlags enum.
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)
static const unsigned int invalid_unsigned_int
::VectorizedArray< Number, width > min(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, 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_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 bool integrate_tensor(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
unsigned int dofs_per_component_on_face
AlignedVector< Number > shape_values
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
std::array< AlignedVector< Number >, 2 > gradients_within_subface