17#ifndef dealii_matrix_free_evaluation_kernels_h
18#define dealii_matrix_free_evaluation_kernels_h
36template <
int,
typename,
bool,
typename>
44 template <MatrixFreeFunctions::ElementType element,
bool is_
long>
48 template <
bool is_
long>
66 template <
bool is_
long>
85 template <
bool is_
long>
118 evaluate(
const unsigned int n_components,
121 const Number * values_dofs_actual,
122 Number * values_quad,
123 Number * gradients_quad,
124 Number * hessians_quad,
125 Number * scratch_data);
128 integrate(
const unsigned int n_components,
131 Number * values_dofs_actual,
132 Number * values_quad,
133 Number * gradients_quad,
134 Number * scratch_data,
135 const bool add_into_values_array);
144 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
152 evaluate(
const unsigned int n_components,
155 const Number * values_dofs_actual,
156 Number * values_quad,
157 Number * gradients_quad,
158 Number * hessians_quad,
159 Number * scratch_data);
162 integrate(
const unsigned int n_components,
165 Number * values_dofs_actual,
166 Number * values_quad,
167 Number * gradients_quad,
168 Number * scratch_data,
169 const bool add_into_values_array);
181 const unsigned int n_components,
184 const Number * values_dofs_actual,
185 Number * values_quad,
186 Number * gradients_quad,
187 Number * hessians_quad,
188 Number * scratch_data)
201 shape_info.
data.front().shape_values_eo :
202 shape_info.
data.front().shape_values,
204 shape_info.
data.front().shape_gradients_eo :
205 shape_info.
data.front().shape_gradients,
207 shape_info.
data.front().shape_hessians_eo :
208 shape_info.
data.front().shape_hessians,
209 shape_info.
data.front().fe_degree + 1,
210 shape_info.
data.front().n_q_points_1d);
212 const unsigned int temp_size =
215 (Eval::n_rows_of_product > Eval::n_columns_of_product ?
216 Eval::n_rows_of_product :
217 Eval::n_columns_of_product);
218 Number *temp1 = scratch_data;
222 temp2 = temp1 +
std::max(Utilities::fixed_power<dim>(
223 shape_info.
data.front().fe_degree + 1),
224 Utilities::fixed_power<dim>(
225 shape_info.
data.front().n_q_points_1d));
229 temp2 = temp1 + temp_size;
232 const unsigned int n_q_points =
233 temp_size == 0 ? shape_info.
n_q_points : Eval::n_columns_of_product;
234 const unsigned int dofs_per_comp =
236 Utilities::fixed_power<dim>(shape_info.
data.front().fe_degree + 1) :
238 const Number *values_dofs = values_dofs_actual;
241 Number *values_dofs_tmp =
245 fe_degree != -1 ? fe_degree : shape_info.
data.front().fe_degree;
246 for (
unsigned int c = 0; c < n_components; ++c)
247 for (
int i = 0, count_p = 0, count_q = 0;
248 i < (dim > 2 ? degree + 1 : 1);
251 for (
int j = 0; j < (dim > 1 ? degree + 1 - i : 1); ++j)
253 for (
int k = 0; k < degree + 1 - j - i;
254 ++k, ++count_p, ++count_q)
255 values_dofs_tmp[c * dofs_per_comp + count_q] =
258 for (
int k = degree + 1 - j - i; k < degree + 1;
260 values_dofs_tmp[c * dofs_per_comp + count_q] = Number();
262 for (
int j = degree + 1 - i; j < degree + 1; ++j)
263 for (
int k = 0; k < degree + 1; ++k, ++count_q)
264 values_dofs_tmp[c * dofs_per_comp + count_q] = Number();
266 values_dofs = values_dofs_tmp;
272 for (
unsigned int c = 0; c < n_components; c++)
275 eval.template values<0, true, false>(values_dofs, values_quad);
277 eval.template gradients<0, true, false>(values_dofs,
280 eval.template hessians<0, true, false>(values_dofs,
284 values_dofs += dofs_per_comp;
285 values_quad += n_q_points;
286 gradients_quad += n_q_points;
287 hessians_quad += n_q_points;
292 for (
unsigned int c = 0; c < n_components; c++)
297 eval.template gradients<0, true, false>(values_dofs, temp1);
298 eval.template values<1, true, false>(temp1, gradients_quad);
304 eval.template gradients<0, true, false>(values_dofs, temp1);
305 eval.template gradients<1, true, false>(temp1,
310 eval.template hessians<0, true, false>(values_dofs, temp1);
311 eval.template values<1, true, false>(temp1, hessians_quad);
315 eval.template values<0, true, false>(values_dofs, temp1);
317 eval.template gradients<1, true, false>(temp1,
323 eval.template hessians<1, true, false>(temp1,
329 eval.template values<1, true, false>(temp1, values_quad);
332 values_dofs += dofs_per_comp;
333 values_quad += n_q_points;
334 gradients_quad += 2 * n_q_points;
335 hessians_quad += 3 * n_q_points;
340 for (
unsigned int c = 0; c < n_components; c++)
345 eval.template gradients<0, true, false>(values_dofs, temp1);
346 eval.template values<1, true, false>(temp1, temp2);
347 eval.template values<2, true, false>(temp2, gradients_quad);
355 eval.template gradients<0, true, false>(values_dofs,
357 eval.template values<1, true, false>(temp1, temp2);
359 eval.template gradients<2, true, false>(temp2,
364 eval.template gradients<1, true, false>(temp1, temp2);
365 eval.template values<2, true, false>(temp2,
370 eval.template hessians<0, true, false>(values_dofs, temp1);
371 eval.template values<1, true, false>(temp1, temp2);
372 eval.template values<2, true, false>(temp2, hessians_quad);
376 eval.template values<0, true, false>(values_dofs, temp1);
379 eval.template gradients<1, true, false>(temp1, temp2);
380 eval.template values<2, true, false>(temp2,
389 eval.template gradients<1, true, false>(temp1, temp2);
390 eval.template gradients<2, true, false>(temp2,
395 eval.template hessians<1, true, false>(temp1, temp2);
396 eval.template values<2, true, false>(temp2,
403 eval.template values<1, true, false>(temp1, temp2);
405 eval.template gradients<2, true, false>(temp2,
412 eval.template hessians<2, true, false>(temp2,
419 eval.template values<2, true, false>(temp2, values_quad);
422 values_dofs += dofs_per_comp;
423 values_quad += n_q_points;
424 gradients_quad += 3 * n_q_points;
425 hessians_quad += 6 * n_q_points;
438 values_quad -= n_components * n_q_points;
439 values_dofs -= n_components * dofs_per_comp;
440 for (
unsigned int c = 0; c < n_components; ++c)
441 for (
unsigned int q = 0; q < shape_info.
n_q_points; ++q)
456 const unsigned int n_components,
459 Number * values_dofs_actual,
460 Number * values_quad,
461 Number * gradients_quad,
462 Number * scratch_data,
463 const bool add_into_values_array)
473 shape_info.
data.front().shape_values_eo :
474 shape_info.
data.front().shape_values,
476 shape_info.
data.front().shape_gradients_eo :
477 shape_info.
data.front().shape_gradients,
479 shape_info.
data.front().shape_hessians_eo :
480 shape_info.
data.front().shape_hessians,
481 shape_info.
data.front().fe_degree + 1,
482 shape_info.
data.front().n_q_points_1d);
484 const unsigned int temp_size =
487 (Eval::n_rows_of_product > Eval::n_columns_of_product ?
488 Eval::n_rows_of_product :
489 Eval::n_columns_of_product);
490 Number *temp1 = scratch_data;
494 temp2 = temp1 +
std::max(Utilities::fixed_power<dim>(
495 shape_info.
data.front().fe_degree + 1),
496 Utilities::fixed_power<dim>(
497 shape_info.
data.front().n_q_points_1d));
501 temp2 = temp1 + temp_size;
504 const unsigned int n_q_points =
505 temp_size == 0 ? shape_info.
n_q_points : Eval::n_columns_of_product;
506 const unsigned int dofs_per_comp =
508 Utilities::fixed_power<dim>(shape_info.
data.front().fe_degree + 1) :
511 Number *values_dofs =
520 for (
unsigned int c = 0; c < n_components; c++)
524 if (add_into_values_array ==
false)
525 eval.template values<0, false, false>(values_quad,
528 eval.template values<0, false, true>(values_quad,
534 add_into_values_array ==
true)
535 eval.template gradients<0, false, true>(gradients_quad,
538 eval.template gradients<0, false, false>(gradients_quad,
543 values_dofs += dofs_per_comp;
544 values_quad += n_q_points;
545 gradients_quad += n_q_points;
550 for (
unsigned int c = 0; c < n_components; c++)
555 eval.template values<1, false, false>(values_quad, temp1);
556 if (add_into_values_array ==
false)
557 eval.template values<0, false, false>(temp1, values_dofs);
559 eval.template values<0, false, true>(temp1, values_dofs);
563 eval.template gradients<1, false, false>(gradients_quad +
567 eval.template values<1, false, true>(values_quad, temp1);
568 if (add_into_values_array ==
false)
569 eval.template values<0, false, false>(temp1, values_dofs);
571 eval.template values<0, false, true>(temp1, values_dofs);
572 eval.template values<1, false, false>(gradients_quad, temp1);
573 eval.template gradients<0, false, true>(temp1, values_dofs);
577 values_dofs += dofs_per_comp;
578 values_quad += n_q_points;
579 gradients_quad += 2 * n_q_points;
584 for (
unsigned int c = 0; c < n_components; c++)
589 eval.template values<2, false, false>(values_quad, temp1);
590 eval.template values<1, false, false>(temp1, temp2);
591 if (add_into_values_array ==
false)
592 eval.template values<0, false, false>(temp2, values_dofs);
594 eval.template values<0, false, true>(temp2, values_dofs);
598 eval.template gradients<2, false, false>(gradients_quad +
602 eval.template values<2, false, true>(values_quad, temp1);
603 eval.template values<1, false, false>(temp1, temp2);
604 eval.template values<2, false, false>(gradients_quad +
607 eval.template gradients<1, false, true>(temp1, temp2);
608 if (add_into_values_array ==
false)
609 eval.template values<0, false, false>(temp2, values_dofs);
611 eval.template values<0, false, true>(temp2, values_dofs);
612 eval.template values<2, false, false>(gradients_quad, temp1);
613 eval.template values<1, false, false>(temp1, temp2);
614 eval.template gradients<0, false, true>(temp2, values_dofs);
618 values_dofs += dofs_per_comp;
619 values_quad += n_q_points;
620 gradients_quad += 3 * n_q_points;
631 values_dofs -= n_components * dofs_per_comp -
633 values_quad -= n_components * n_q_points;
635 for (
unsigned int c = 0; c < n_components; ++c)
637 values_dofs[0] = values_quad[0];
638 for (
unsigned int q = 1; q < shape_info.
n_q_points; ++q)
639 values_dofs[0] += values_quad[q];
640 values_dofs += dofs_per_comp;
641 values_quad += n_q_points;
645 for (
unsigned int c = 0; c < n_components; ++c)
653 values_dofs -= dofs_per_comp * n_components;
655 fe_degree != -1 ? fe_degree : shape_info.
data.front().fe_degree;
656 for (
unsigned int c = 0; c < n_components; ++c)
657 for (
int i = 0, count_p = 0, count_q = 0;
658 i < (dim > 2 ? degree + 1 : 1);
661 for (
int j = 0; j < (dim > 1 ? degree + 1 - i : 1); ++j)
663 for (
int k = 0; k < degree + 1 - j - i;
664 ++k, ++count_p, ++count_q)
665 values_dofs_actual[c *
668 values_dofs[c * dofs_per_comp + count_q];
671 count_q += i * (degree + 1);
678 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
685 Number>::evaluate(
const unsigned int n_components,
688 const Number *values_dofs_actual,
689 Number * values_quad,
690 Number * gradients_quad,
691 Number * hessians_quad,
692 Number * scratch_data)
697 const unsigned int n_q_points = shape_info.
n_q_points;
704 const auto shape_values = shape_info.
data.front().shape_values.data();
705 auto values_quad_ptr = values_quad;
706 auto values_dofs_actual_ptr = values_dofs_actual;
708 Eval eval(shape_values,
nullptr,
nullptr, n_dofs, n_q_points);
709 for (
unsigned int c = 0; c < n_components; ++c)
711 eval.template values<0, true, false>(values_dofs_actual_ptr,
714 values_quad_ptr += n_q_points;
715 values_dofs_actual_ptr += n_dofs;
721 const auto shape_gradients =
722 shape_info.
data.front().shape_gradients.data();
723 auto gradients_quad_ptr = gradients_quad;
724 auto values_dofs_actual_ptr = values_dofs_actual;
726 for (
unsigned int c = 0; c < n_components; ++c)
728 for (
unsigned int d = 0;
d < dim; ++
d)
731 shape_gradients + n_q_points * n_dofs *
d,
736 eval.template gradients<0, true, false>(values_dofs_actual_ptr,
739 gradients_quad_ptr += n_q_points;
741 values_dofs_actual_ptr += n_dofs;
754 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
761 Number>::integrate(
const unsigned int n_components,
764 Number * values_dofs_actual,
765 Number * values_quad,
766 Number * gradients_quad,
767 Number * scratch_data,
768 const bool add_into_values_array)
773 const unsigned int n_q_points = shape_info.
n_q_points;
780 const auto shape_values = shape_info.
data.front().shape_values.data();
781 auto values_quad_ptr = values_quad;
782 auto values_dofs_actual_ptr = values_dofs_actual;
784 Eval eval(shape_values,
nullptr,
nullptr, n_dofs, n_q_points);
785 for (
unsigned int c = 0; c < n_components; ++c)
787 if (add_into_values_array ==
false)
788 eval.template values<0, false, false>(values_quad_ptr,
789 values_dofs_actual_ptr);
791 eval.template values<0, false, true>(values_quad_ptr,
792 values_dofs_actual_ptr);
794 values_quad_ptr += n_q_points;
795 values_dofs_actual_ptr += n_dofs;
801 const auto shape_gradients =
802 shape_info.
data.front().shape_gradients.data();
803 auto gradients_quad_ptr = gradients_quad;
804 auto values_dofs_actual_ptr = values_dofs_actual;
806 for (
unsigned int c = 0; c < n_components; ++c)
808 for (
unsigned int d = 0;
d < dim; ++
d)
811 shape_gradients + n_q_points * n_dofs *
d,
816 if ((add_into_values_array ==
false &&
819 eval.template gradients<0, false, false>(
820 gradients_quad_ptr, values_dofs_actual_ptr);
822 eval.template gradients<0, false, true>(
823 gradients_quad_ptr, values_dofs_actual_ptr);
825 gradients_quad_ptr += n_q_points;
827 values_dofs_actual_ptr += n_dofs;
852 static_assert(basis_size_1 == 0 || basis_size_1 <= basis_size_2,
853 "The second dimension must not be smaller than the first");
882 const unsigned int n_components,
884 const Number * values_in,
890 basis_size_1 != 0 || basis_size_1_variable <= basis_size_2_variable,
891 ExcMessage(
"The second dimension must not be smaller than the first"));
899 constexpr int next_dim =
901 ((basis_size_1 == 0 || basis_size_2 > basis_size_1) && dim > 1)) ?
908 (basis_size_1 == 0 ? 0 : basis_size_2),
911 eval_val(transformation_matrix,
914 basis_size_1_variable,
915 basis_size_2_variable);
916 const unsigned int np_1 =
917 basis_size_1 > 0 ? basis_size_1 : basis_size_1_variable;
918 const unsigned int np_2 =
919 basis_size_1 > 0 ? basis_size_2 : basis_size_2_variable;
921 ExcMessage(
"Cannot transform with 0-point basis"));
923 ExcMessage(
"Cannot transform with 0-point basis"));
927 values_in = values_in + n_components * Utilities::fixed_power<dim>(np_1);
929 values_out + n_components * Utilities::fixed_power<dim>(np_2);
930 for (
unsigned int c = n_components; c != 0; --c)
932 values_in -= Utilities::fixed_power<dim>(np_1);
933 values_out -= Utilities::fixed_power<dim>(np_2);
935 for (
unsigned int q = np_1; q != 0; --q)
944 transformation_matrix,
947 Utilities::fixed_power<next_dim>(np_1),
950 Utilities::fixed_power<next_dim>(np_2),
951 basis_size_1_variable,
952 basis_size_2_variable);
957 if (basis_size_1 > 0 && basis_size_2 == basis_size_1 && dim == 2)
959 eval_val.template values<0, true, false>(values_in, values_out);
960 eval_val.template values<1, true, false>(values_out, values_out);
963 eval_val.template
values<dim - 1,
true,
false>(values_in,
966 eval_val.template
values<dim - 1,
true,
false>(values_out,
1006 const unsigned int n_components,
1008 const bool add_into_result,
1010 Number * values_out,
1015 basis_size_1 != 0 || basis_size_1_variable <= basis_size_2_variable,
1016 ExcMessage(
"The second dimension must not be smaller than the first"));
1017 Assert(add_into_result ==
false || values_in != values_out,
1019 "Input and output cannot alias with each other when "
1020 "adding the result of the basis change to existing data"));
1026 constexpr int next_dim =
1028 ((basis_size_1 == 0 || basis_size_2 > basis_size_1) && dim > 1)) ?
1034 (basis_size_1 == 0 ? 0 : basis_size_2),
1037 eval_val(transformation_matrix,
1038 transformation_matrix,
1039 transformation_matrix,
1040 basis_size_1_variable,
1041 basis_size_2_variable);
1042 const unsigned int np_1 =
1043 basis_size_1 > 0 ? basis_size_1 : basis_size_1_variable;
1044 const unsigned int np_2 =
1045 basis_size_1 > 0 ? basis_size_2 : basis_size_2_variable;
1047 ExcMessage(
"Cannot transform with 0-point basis"));
1049 ExcMessage(
"Cannot transform with 0-point basis"));
1051 for (
unsigned int c = 0; c < n_components; ++c)
1053 if (basis_size_1 > 0 && basis_size_2 == basis_size_1 && dim == 2)
1056 eval_val.template values<1, false, false>(values_in, values_in);
1058 eval_val.template hessians<1, false, false>(values_in,
1061 if (add_into_result)
1064 eval_val.template values<0, false, true>(values_in,
1067 eval_val.template hessians<0, false, true>(values_in,
1073 eval_val.template values<0, false, false>(values_in,
1076 eval_val.template hessians<0, false, false>(values_in,
1082 if (dim == 1 && add_into_result)
1085 eval_val.template values<0, false, true>(values_in,
1088 eval_val.template hessians<0, false, true>(values_in,
1094 eval_val.template values<0, false, false>(values_in,
1097 eval_val.template hessians<0, false, false>(values_in,
1103 eval_val.template
values<dim - 1,
false,
false>(values_in,
1106 eval_val.template
hessians<dim - 1,
false,
false>(
1107 values_in, values_in);
1111 for (
unsigned int q = 0; q < np_1; ++q)
1120 transformation_matrix,
1123 q * Utilities::fixed_power<next_dim>(np_2),
1125 q * Utilities::fixed_power<next_dim>(np_1),
1126 basis_size_1_variable,
1127 basis_size_2_variable);
1129 values_in += Utilities::fixed_power<dim>(np_2);
1130 values_out += Utilities::fixed_power<dim>(np_1);
1158 const Number * values_in,
1159 Number * scratch_data,
1160 Number * values_out)
1162 constexpr int next_dim = dim > 1 ? dim - 1 : dim;
1163 Number * my_scratch =
1164 basis_size_1 != basis_size_2 ? scratch_data : values_out;
1166 const unsigned int size_per_component =
Utilities::pow(basis_size_2, dim);
1167 Assert(coefficients.
size() == size_per_component ||
1168 coefficients.
size() == n_components * size_per_component,
1170 const unsigned int stride =
1171 coefficients.
size() == size_per_component ? 0 : 1;
1173 for (
unsigned int q = basis_size_1; q != 0; --q)
1182 transformation_matrix,
1195 eval_val(transformation_matrix);
1196 const unsigned int n_inner_blocks =
1197 (dim > 1 && basis_size_2 < 10) ? basis_size_2 : 1;
1199 for (
unsigned int ii = 0; ii <
n_blocks; ii += n_inner_blocks)
1200 for (
unsigned int c = 0; c < n_components; ++c)
1202 for (
unsigned int i = ii; i < ii + n_inner_blocks; ++i)
1203 eval_val.template values_one_line<dim - 1, true, false>(
1204 my_scratch + i, my_scratch + i);
1205 for (
unsigned int q = 0; q < basis_size_2; ++q)
1206 for (
unsigned int i = ii; i < ii + n_inner_blocks; ++i)
1207 my_scratch[i + q *
n_blocks + c * size_per_component] *=
1209 c * stride * size_per_component];
1210 for (
unsigned int i = ii; i < ii + n_inner_blocks; ++i)
1211 eval_val.template values_one_line<dim - 1, false, false>(
1212 my_scratch + i, my_scratch + i);
1214 for (
unsigned int q = 0; q < basis_size_1; ++q)
1223 transformation_matrix,
1246 template <
int dim,
int fe_degree,
typename Number>
1250 evaluate(
const unsigned int n_components,
1253 const Number * values_dofs,
1254 Number * values_quad,
1255 Number * gradients_quad,
1256 Number * hessians_quad,
1257 Number * scratch_data);
1260 integrate(
const unsigned int n_components,
1263 Number * values_dofs,
1264 Number * values_quad,
1265 Number * gradients_quad,
1266 Number * scratch_data,
1267 const bool add_into_values_array);
1272 template <
int dim,
int fe_degree,
typename Number>
1275 const unsigned int n_components,
1278 const Number * values_dofs,
1279 Number * values_quad,
1280 Number * gradients_quad,
1281 Number * hessians_quad,
1285 shape_info.
data.front().shape_gradients_collocation_eo.size(),
1286 (fe_degree + 2) / 2 * (fe_degree + 1));
1294 shape_info.
data.front().shape_gradients_collocation_eo,
1295 shape_info.
data.front().shape_hessians_collocation_eo);
1296 constexpr unsigned int n_q_points =
Utilities::pow(fe_degree + 1, dim);
1298 for (
unsigned int c = 0; c < n_components; c++)
1301 for (
unsigned int i = 0; i < n_q_points; ++i)
1302 values_quad[i] = values_dofs[i];
1303 if (evaluation_flag &
1306 eval.template gradients<0, true, false>(values_dofs,
1309 eval.template gradients<1, true, false>(values_dofs,
1313 eval.template gradients<2, true, false>(values_dofs,
1319 eval.template hessians<0, true, false>(values_dofs, hessians_quad);
1322 eval.template gradients<1, true, false>(gradients_quad,
1325 eval.template hessians<1, true, false>(values_dofs,
1331 eval.template gradients<2, true, false>(gradients_quad,
1334 eval.template gradients<2, true, false>(
1335 gradients_quad + n_q_points, hessians_quad + 5 * n_q_points);
1336 eval.template hessians<2, true, false>(values_dofs,
1340 hessians_quad += (dim * (dim + 1)) / 2 * n_q_points;
1342 gradients_quad += dim * n_q_points;
1343 values_quad += n_q_points;
1344 values_dofs += n_q_points;
1350 template <
int dim,
int fe_degree,
typename Number>
1353 const unsigned int n_components,
1356 Number * values_dofs,
1357 Number * values_quad,
1358 Number * gradients_quad,
1360 const bool add_into_values_array)
1363 shape_info.
data.front().shape_gradients_collocation_eo.size(),
1364 (fe_degree + 2) / 2 * (fe_degree + 1));
1372 shape_info.
data.front().shape_gradients_collocation_eo,
1373 shape_info.
data.front().shape_hessians_collocation_eo);
1374 constexpr unsigned int n_q_points =
Utilities::pow(fe_degree + 1, dim);
1376 for (
unsigned int c = 0; c < n_components; c++)
1380 if (add_into_values_array ==
false)
1381 for (
unsigned int i = 0; i < n_q_points; ++i)
1382 values_dofs[i] = values_quad[i];
1384 for (
unsigned int i = 0; i < n_q_points; ++i)
1385 values_dofs[i] += values_quad[i];
1390 add_into_values_array ==
true)
1391 eval.template gradients<0, false, true>(gradients_quad,
1394 eval.template gradients<0, false, false>(gradients_quad,
1397 eval.template gradients<1, false, true>(gradients_quad +
1401 eval.template gradients<2, false, true>(gradients_quad +
1405 gradients_quad += dim * n_q_points;
1406 values_quad += n_q_points;
1407 values_dofs += n_q_points;
1423 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
1427 evaluate(
const unsigned int n_components,
1430 const Number * values_dofs,
1431 Number * values_quad,
1432 Number * gradients_quad,
1433 Number * hessians_quad,
1434 Number * scratch_data);
1437 integrate(
const unsigned int n_components,
1440 Number * values_dofs,
1441 Number * values_quad,
1442 Number * gradients_quad,
1443 Number * scratch_data,
1444 const bool add_into_values_array);
1449 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
1455 Number>::evaluate(
const unsigned int n_components,
1458 const Number * values_dofs,
1459 Number * values_quad,
1460 Number *gradients_quad,
1461 Number *hessians_quad,
1464 Assert(n_q_points_1d > fe_degree,
1465 ExcMessage(
"You lose information when going to a collocation space "
1466 "of lower degree, so the evaluation results would be "
1467 "wrong. Thus, this class does not permit the desired "
1469 constexpr unsigned int n_q_points =
Utilities::pow(n_q_points_1d, dim);
1471 for (
unsigned int c = 0; c < n_components; c++)
1477 (fe_degree >= n_q_points_1d ? n_q_points_1d : fe_degree + 1),
1480 Number>::do_forward(1,
1481 shape_info.
data.front().shape_values_eo,
1486 if (evaluation_flag &
1500 values_quad += n_q_points;
1501 gradients_quad += dim * n_q_points;
1502 hessians_quad += (dim * (dim + 1)) / 2 * n_q_points;
1508 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
1514 Number>::integrate(
const unsigned int n_components,
1517 Number *values_dofs,
1518 Number *values_quad,
1519 Number *gradients_quad,
1521 const bool add_into_values_array)
1523 Assert(n_q_points_1d > fe_degree,
1524 ExcMessage(
"You lose information when going to a collocation space "
1525 "of lower degree, so the evaluation results would be "
1526 "wrong. Thus, this class does not permit the desired "
1529 shape_info.
data.front().shape_gradients_collocation_eo.size(),
1530 (n_q_points_1d + 1) / 2 * n_q_points_1d);
1531 constexpr unsigned int n_q_points =
Utilities::pow(n_q_points_1d, dim);
1533 for (
unsigned int c = 0; c < n_components; c++)
1553 (fe_degree >= n_q_points_1d ? n_q_points_1d : fe_degree + 1),
1556 Number>::do_backward(1,
1557 shape_info.
data.front().shape_values_eo,
1558 add_into_values_array,
1561 gradients_quad += dim * n_q_points;
1562 values_quad += n_q_points;
1584 template <
int dim,
typename Number>
1587 template <
int fe_degree,
int n_q_po
ints_1d>
1589 run(
const unsigned int n_components,
1592 Number *values_dofs_actual,
1593 Number *values_quad,
1594 Number *gradients_quad,
1595 Number *hessians_quad,
1596 Number *scratch_data)
1603 static constexpr bool use_collocation =
1604 n_q_points_1d > fe_degree && n_q_points_1d <= 3 * fe_degree / 2 + 1 &&
1605 n_q_points_1d < 200;
1607 if (fe_degree >= 0 && fe_degree + 1 == n_q_points_1d &&
1623 else if (fe_degree >= 0 && use_collocation &&
1631 Number>::evaluate(n_components,
1640 else if (fe_degree >= 0 &&
1649 Number>::evaluate(n_components,
1666 Number>::evaluate(n_components,
1683 Number>::evaluate(n_components,
1699 Number>::evaluate(n_components,
1715 Number>::evaluate(n_components,
1746 template <
int dim,
typename Number>
1749 template <
int fe_degree,
int n_q_po
ints_1d>
1751 run(
const unsigned int n_components,
1754 Number * values_dofs_actual,
1755 Number * values_quad,
1756 Number * gradients_quad,
1757 Number * scratch_data,
1758 const bool sum_into_values_array)
1765 constexpr bool use_collocation = n_q_points_1d > fe_degree &&
1766 n_q_points_1d <= 3 * fe_degree / 2 + 1 &&
1767 n_q_points_1d < 200;
1769 if (fe_degree >= 0 && fe_degree + 1 == n_q_points_1d &&
1781 sum_into_values_array);
1785 else if (fe_degree >= 0 && use_collocation &&
1793 Number>::integrate(n_components,
1800 sum_into_values_array);
1802 else if (fe_degree >= 0 &&
1811 Number>::integrate(n_components,
1818 sum_into_values_array);
1828 Number>::integrate(n_components,
1835 sum_into_values_array);
1845 Number>::integrate(n_components,
1852 sum_into_values_array);
1861 Number>::integrate(n_components,
1868 sum_into_values_array);
1877 Number>::integrate(n_components,
1884 sum_into_values_array);
1893 template <
bool symmetric_evaluate,
1906 symmetric_evaluate &&
1907 n_q_points_1d > fe_degree &&n_q_points_1d <= 3 * fe_degree / 2 + 1 &&
1908 n_q_points_1d < 200;
1913 Number * values_dofs,
1914 Number * values_quad,
1915 Number * gradients_quad,
1916 Number * scratch_data,
1917 const bool evaluate_val,
1918 const bool evaluate_grad,
1919 const unsigned int subface_index)
1922 symmetric_evaluate ?
1923 data.
data.front().shape_values_eo :
1925 data.
data.front().shape_values :
1926 data.
data.front().values_within_subface[subface_index % 2]);
1928 symmetric_evaluate ?
1929 data.
data.front().shape_values_eo :
1931 data.
data.front().shape_values :
1932 data.
data.front().values_within_subface[subface_index / 2]);
1935 symmetric_evaluate ?
1936 data.
data.front().shape_gradients_eo :
1938 data.
data.front().shape_gradients :
1939 data.
data.front().gradients_within_subface[subface_index % 2]);
1941 symmetric_evaluate ?
1942 data.
data.front().shape_gradients_eo :
1944 data.
data.front().shape_gradients :
1945 data.
data.front().gradients_within_subface[subface_index / 2]);
1958 data.
data.front().fe_degree + 1,
1959 data.
data.front().n_q_points_1d);
1963 data.
data.front().fe_degree + 1,
1964 data.
data.front().n_q_points_1d);
1966 const unsigned int size_deg =
1973 const unsigned int n_q_points = fe_degree > -1 ?
1977 if (evaluate_grad ==
false)
1978 for (
unsigned int c = 0; c < n_components; ++c)
1983 eval1.template values<0, true, false>(values_dofs,
1985 eval2.template values<1, true, false>(values_quad,
1989 eval1.template values<0, true, false>(values_dofs,
1993 values_quad[0] = values_dofs[0];
1998 values_dofs += 2 * size_deg;
1999 values_quad += n_q_points;
2002 for (
unsigned int c = 0; c < n_components; ++c)
2009 eval1.template values<0, true, false>(values_dofs,
2011 eval1.template values<1, true, false>(values_quad,
2021 data.
data.front().shape_gradients_collocation_eo,
2023 eval_grad.template gradients<0, true, false>(
2024 values_quad, gradients_quad);
2025 eval_grad.template gradients<1, true, false>(
2026 values_quad, gradients_quad + n_q_points);
2030 eval1.template gradients<0, true, false>(values_dofs,
2032 eval2.template values<1, true, false>(scratch_data,
2035 eval1.template values<0, true, false>(values_dofs,
2037 eval2.template gradients<1, true, false>(scratch_data,
2041 if (evaluate_val ==
true)
2042 eval2.template values<1, true, false>(scratch_data,
2045 eval1.template values<0, true, false>(values_dofs + size_deg,
2047 eval2.template values<1, true, false>(
2048 scratch_data, gradients_quad + (dim - 1) * n_q_points);
2052 eval1.template values<0, true, false>(values_dofs + size_deg,
2056 eval1.template gradients<0, true, false>(values_dofs,
2058 if (evaluate_val ==
true)
2059 eval1.template values<0, true, false>(values_dofs,
2063 values_quad[0] = values_dofs[0];
2064 gradients_quad[0] = values_dofs[1];
2069 values_dofs += 2 * size_deg;
2070 values_quad += n_q_points;
2071 gradients_quad += dim * n_q_points;
2078 Number * values_dofs,
2079 Number * values_quad,
2080 Number * gradients_quad,
2081 Number * scratch_data,
2082 const bool integrate_val,
2083 const bool integrate_grad,
2084 const unsigned int subface_index)
2087 symmetric_evaluate ?
2088 data.
data.front().shape_values_eo :
2090 data.
data.front().shape_values :
2091 data.
data.front().values_within_subface[subface_index % 2]);
2093 symmetric_evaluate ?
2094 data.
data.front().shape_values_eo :
2096 data.
data.front().shape_values :
2097 data.
data.front().values_within_subface[subface_index / 2]);
2100 symmetric_evaluate ?
2101 data.
data.front().shape_gradients_eo :
2103 data.
data.front().shape_gradients :
2104 data.
data.front().gradients_within_subface[subface_index % 2]);
2106 symmetric_evaluate ?
2107 data.
data.front().shape_gradients_eo :
2109 data.
data.front().shape_gradients :
2110 data.
data.front().gradients_within_subface[subface_index / 2]);
2123 data.
data.front().fe_degree + 1,
2124 data.
data.front().n_q_points_1d);
2128 data.
data.front().fe_degree + 1,
2129 data.
data.front().n_q_points_1d);
2131 const unsigned int size_deg =
2138 const unsigned int n_q_points = fe_degree > -1 ?
2142 if (integrate_grad ==
false)
2143 for (
unsigned int c = 0; c < n_components; ++c)
2148 eval2.template values<1, false, false>(values_quad,
2150 eval1.template values<0, false, false>(values_quad,
2154 eval1.template values<0, false, false>(values_quad,
2158 values_dofs[0] = values_quad[0];
2163 values_dofs += 2 * size_deg;
2164 values_quad += n_q_points;
2167 for (
unsigned int c = 0; c < n_components; ++c)
2172 eval2.template values<1, false, false>(gradients_quad +
2176 eval1.template values<0, false, false>(
2177 gradients_quad + 2 * n_q_points, values_dofs + size_deg);
2188 data.
data.front().shape_gradients_collocation_eo,
2191 eval_grad.template gradients<1, false, true>(
2192 gradients_quad + n_q_points, values_quad);
2194 eval_grad.template gradients<1, false, false>(
2195 gradients_quad + n_q_points, values_quad);
2196 eval_grad.template gradients<0, false, true>(
2197 gradients_quad, values_quad);
2198 eval1.template values<1, false, false>(values_quad,
2200 eval1.template values<0, false, false>(values_quad,
2207 eval2.template values<1, false, false>(values_quad,
2209 eval2.template gradients<1, false, true>(
2210 gradients_quad + n_q_points, scratch_data);
2213 eval2.template gradients<1, false, false>(
2214 gradients_quad + n_q_points, scratch_data);
2216 eval1.template values<0, false, false>(scratch_data,
2218 eval2.template values<1, false, false>(gradients_quad,
2220 eval1.template gradients<0, false, true>(scratch_data,
2225 eval1.template values<0, false, false>(
2226 gradients_quad + n_q_points, values_dofs + size_deg);
2227 eval1.template gradients<0, false, false>(gradients_quad,
2229 if (integrate_val ==
true)
2230 eval1.template values<0, false, true>(values_quad,
2234 values_dofs[0] = values_quad[0];
2235 values_dofs[1] = gradients_quad[0];
2240 values_dofs += 2 * size_deg;
2241 values_quad += n_q_points;
2242 gradients_quad += dim * n_q_points;
2249 template <
int dim,
int fe_degree,
typename Number,
bool lex_faces = false>
2252 template <
bool do_evaluate,
bool add_
into_output>
2256 const Number * input,
2258 const bool do_gradients,
2259 const unsigned int face_no)
2261 Assert(
static_cast<unsigned int>(fe_degree) ==
2262 data.
data.front().fe_degree ||
2266 interpolate_generic<do_evaluate, add_into_output>(
2272 data.
data.front().fe_degree + 1,
2273 data.
data.front().shape_data_on_face,
2281 template <
bool do_evaluate,
bool add_
into_output>
2285 const Number * input,
2287 const bool do_gradients,
2288 const unsigned int face_no)
2290 Assert(
static_cast<unsigned int>(fe_degree + 1) ==
2291 data.
data.front().quadrature.size() ||
2295 interpolate_generic<do_evaluate, add_into_output>(
2301 data.
data.front().quadrature.size(),
2302 data.
data.front().quadrature_data_on_face,
2308 template <
bool do_evaluate,
bool add_
into_output,
int face_direction = 0>
2311 const Number * input,
2313 const bool do_gradients,
2314 const unsigned int face_no,
2315 const unsigned int n_points_1d,
2317 const unsigned int dofs_per_component_on_cell,
2318 const unsigned int dofs_per_component_on_face)
2320 if (face_direction == face_no / 2)
2327 evalf(shape_data[face_no % 2],
2333 const unsigned int in_stride = do_evaluate ?
2334 dofs_per_component_on_cell :
2335 dofs_per_component_on_face;
2336 const unsigned int out_stride = do_evaluate ?
2337 dofs_per_component_on_face :
2338 dofs_per_component_on_cell;
2340 for (
unsigned int c = 0; c < n_components; c++)
2343 evalf.template apply_face<face_direction,
2347 lex_faces>(input, output);
2349 evalf.template apply_face<face_direction,
2353 lex_faces>(input, output);
2355 output += out_stride;
2358 else if (face_direction < dim)
2362 std::min(face_direction + 1, dim - 1)>(
2370 dofs_per_component_on_cell,
2371 dofs_per_component_on_face);
2379 template <
typename VectorizedArrayType,
typename Number2>
2383 for (
unsigned int v = 0; v < VectorizedArrayType::size(); ++v)
2384 dst[v] = src_ptr[v];
2391 template <
typename Number,
unsigned int w
idth>
2401 template <
typename VectorizedArrayType,
typename Number2>
2404 const unsigned int * indices,
2405 VectorizedArrayType &dst)
2407 for (
unsigned int v = 0; v < VectorizedArrayType::size(); ++v)
2408 dst[v] = src_ptr[indices[v]];
2415 template <
typename Number,
unsigned int w
idth>
2418 const unsigned int * indices,
2421 dst.
gather(src_ptr, indices);
2427 template <
typename VectorizedArrayType,
typename Number2>
2431 for (
unsigned int v = 0; v < VectorizedArrayType::size(); ++v)
2432 dst_ptr[v] += src[v];
2439 template <
typename Number,
unsigned int w
idth>
2445 (tmp + src).store(dst_ptr);
2451 template <
typename VectorizedArrayType,
typename Number2>
2454 const unsigned int * indices,
2457 for (
unsigned int v = 0; v < VectorizedArrayType::size(); ++v)
2458 dst_ptr[indices[v]] += src[v];
2465 template <
typename Number,
unsigned int w
idth>
2468 const unsigned int * indices,
2471#if DEAL_II_VECTORIZATION_WIDTH_IN_BITS < 512
2472 for (
unsigned int v = 0; v < width; ++v)
2473 dst_ptr[indices[v]] += src[v];
2476 tmp.
gather(dst_ptr, indices);
2477 (tmp + src).scatter(indices, dst_ptr);
2483 template <
typename Number>
2486 const unsigned int n_components,
2487 const unsigned int face_orientation,
2489 const bool integrate,
2492 const unsigned int n_q_points,
2493 Number * tmp_values,
2494 Number * values_quad,
2495 Number * gradients_quad)
2498 const unsigned int *orientation = &orientation_map[face_orientation][0];
2499 for (
unsigned int c = 0; c < n_components; ++c)
2504 for (
unsigned int q = 0; q < n_q_points; ++q)
2505 tmp_values[q] = values_quad[c * n_q_points + orientation[q]];
2507 for (
unsigned int q = 0; q < n_q_points; ++q)
2508 tmp_values[orientation[q]] = values_quad[c * n_q_points + q];
2509 for (
unsigned int q = 0; q < n_q_points; ++q)
2510 values_quad[c * n_q_points + q] = tmp_values[q];
2513 for (
unsigned int d = 0;
d < dim; ++
d)
2516 for (
unsigned int q = 0; q < n_q_points; ++q)
2518 gradients_quad[(c * dim +
d) * n_q_points + orientation[q]];
2520 for (
unsigned int q = 0; q < n_q_points; ++q)
2521 tmp_values[orientation[q]] =
2522 gradients_quad[(c * dim +
d) * n_q_points + q];
2523 for (
unsigned int q = 0; q < n_q_points; ++q)
2524 gradients_quad[(c * dim +
d) * n_q_points + q] = tmp_values[q];
2531 template <
int dim,
typename VectorizedArrayType>
2534 template <
int fe_degree,
int n_q_po
ints_1d>
2536 run(
const unsigned int n_components,
2538 const VectorizedArrayType * values_array,
2539 VectorizedArrayType * values_quad,
2540 VectorizedArrayType * gradients_quad,
2541 VectorizedArrayType * scratch_data,
2542 const bool evaluate_values,
2543 const bool evaluate_gradients,
2544 const unsigned int face_no,
2545 const unsigned int subface_index,
2546 const unsigned int face_orientation,
2553 const auto shape_info = data.
data.front();
2559 VectorizedArrayType,
2560 VectorizedArrayType>;
2562 if (evaluate_values)
2564 const auto shape_values =
2565 &shape_info.shape_values_face(face_no, face_orientation, 0);
2567 auto values_quad_ptr = values_quad;
2568 auto values_dofs_actual_ptr = values_array;
2570 Eval eval(shape_values,
nullptr,
nullptr, n_dofs, n_q_points);
2571 for (
unsigned int c = 0; c < n_components; ++c)
2573 eval.template values<0, true, false>(values_dofs_actual_ptr,
2576 values_quad_ptr += n_q_points;
2577 values_dofs_actual_ptr += n_dofs;
2581 if (evaluate_gradients)
2583 auto gradients_quad_ptr = gradients_quad;
2584 auto values_dofs_actual_ptr = values_array;
2586 std::array<const VectorizedArrayType *, dim> shape_gradients;
2587 for (
unsigned int d = 0;
d < dim; ++
d)
2588 shape_gradients[
d] = &shape_info.shape_gradients_face(
2589 face_no, face_orientation,
d, 0);
2591 for (
unsigned int c = 0; c < n_components; ++c)
2593 for (
unsigned int d = 0;
d < dim; ++
d)
2601 eval.template gradients<0, true, false>(
2602 values_dofs_actual_ptr, gradients_quad_ptr);
2604 gradients_quad_ptr += n_q_points;
2606 values_dofs_actual_ptr += n_dofs;
2614 constexpr unsigned int static_dofs_per_face =
2617 const unsigned int dofs_per_face =
2619 static_dofs_per_face :
2622 VectorizedArrayType *temp1 = scratch_data;
2625 template interpolate<true, false>(
2626 n_components, data, values_array, temp1, evaluate_gradients, face_no);
2628 const unsigned int n_q_points_1d_actual =
2629 fe_degree > -1 ? n_q_points_1d : 0;
2630 if (fe_degree > -1 &&
2637 n_q_points_1d_actual,
2638 VectorizedArrayType>::evaluate_in_face(n_components,
2654 n_q_points_1d_actual,
2655 VectorizedArrayType>::evaluate_in_face(n_components,
2667 if (face_orientation)
2686 template <
int dim,
typename VectorizedArrayType>
2689 template <
int fe_degree,
int n_q_po
ints_1d>
2691 run(
const unsigned int n_components,
2693 VectorizedArrayType * values_array,
2694 VectorizedArrayType * values_quad,
2695 VectorizedArrayType * gradients_quad,
2696 VectorizedArrayType * scratch_data,
2697 const bool integrate_values,
2698 const bool integrate_gradients,
2699 const unsigned int face_no,
2700 const unsigned int subface_index,
2701 const unsigned int face_orientation,
2708 const auto shape_info = data.
data.front();
2714 VectorizedArrayType,
2715 VectorizedArrayType>;
2717 if (integrate_values)
2719 const auto shape_values =
2720 &shape_info.shape_values_face(face_no, face_orientation, 0);
2722 auto values_quad_ptr = values_quad;
2723 auto values_dofs_actual_ptr = values_array;
2725 Eval eval(shape_values,
nullptr,
nullptr, n_dofs, n_q_points);
2726 for (
unsigned int c = 0; c < n_components; ++c)
2728 eval.template values<0, false, false>(values_quad_ptr,
2729 values_dofs_actual_ptr);
2731 values_quad_ptr += n_q_points;
2732 values_dofs_actual_ptr += n_dofs;
2736 if (integrate_gradients)
2738 auto gradients_quad_ptr = gradients_quad;
2739 auto values_dofs_actual_ptr = values_array;
2741 std::array<const VectorizedArrayType *, dim> shape_gradients;
2742 for (
unsigned int d = 0;
d < dim; ++
d)
2743 shape_gradients[
d] = &shape_info.shape_gradients_face(
2744 face_no, face_orientation,
d, 0);
2746 for (
unsigned int c = 0; c < n_components; ++c)
2748 for (
unsigned int d = 0;
d < dim; ++
d)
2756 if ((integrate_values ==
false) &&
d == 0)
2757 eval.template gradients<0, false, false>(
2758 gradients_quad_ptr, values_dofs_actual_ptr);
2760 eval.template gradients<0, false, true>(
2761 gradients_quad_ptr, values_dofs_actual_ptr);
2763 gradients_quad_ptr += n_q_points;
2765 values_dofs_actual_ptr += n_dofs;
2773 if (face_orientation)
2780 integrate_gradients,
2786 constexpr unsigned int static_dofs_per_face =
2789 const unsigned int dofs_per_face =
2791 static_dofs_per_face :
2794 VectorizedArrayType *temp1 = scratch_data;
2796 const unsigned int n_q_points_1d_actual =
2797 fe_degree > -1 ? n_q_points_1d : 0;
2798 if (fe_degree > -1 &&
2805 n_q_points_1d_actual,
2806 VectorizedArrayType>::integrate_in_face(n_components,
2815 integrate_gradients,
2822 n_q_points_1d_actual,
2823 VectorizedArrayType>::integrate_in_face(n_components,
2832 integrate_gradients,
2836 template interpolate<false, false>(n_components,
2840 integrate_gradients,
2848 template <
int n_face_orientations,
typename Processor>
2852 auto n_components = proc.n_components;
2853 auto integrate = proc.integrate;
2854 auto global_vector_ptr = proc.global_vector_ptr;
2855 auto &sm_ptr = proc.sm_ptr;
2856 auto &data = proc.data;
2857 auto &dof_info = proc.dof_info;
2858 auto values_quad = proc.values_quad;
2859 auto gradients_quad = proc.gradients_quad;
2860 auto scratch_data = proc.scratch_data;
2861 auto do_values = proc.do_values;
2862 auto do_gradients = proc.do_gradients;
2863 auto active_fe_index = proc.active_fe_index;
2864 auto first_selected_component = proc.first_selected_component;
2865 auto cells = proc.cells;
2866 auto face_nos = proc.face_nos;
2867 auto subface_index = proc.subface_index;
2868 auto dof_access_index = proc.dof_access_index;
2869 auto face_orientations = proc.face_orientations;
2870 auto &orientation_map = proc.orientation_map;
2872 static const int dim = Processor::dim_;
2873 static const int fe_degree = Processor::fe_degree_;
2874 using VectorizedArrayType =
typename Processor::VectorizedArrayType_;
2876 using Number =
typename Processor::Number_;
2877 using Number2_ =
typename Processor::Number2_;
2879 const unsigned int cell = cells[0];
2889 (face_orientations[0] > 0 &&
2891 !(((do_gradients ==
false &&
2892 data.data.front().nodal_at_cell_boundaries ==
true &&
2894 (data.element_type ==
2897 (dof_info.index_storage_variants[dof_access_index][cell] ==
2899 interleaved_contiguous ||
2900 dof_info.index_storage_variants[dof_access_index][cell] ==
2902 interleaved_contiguous_strided ||
2903 dof_info.index_storage_variants[dof_access_index][cell] ==
2905 interleaved_contiguous_mixed_strides ||
2906 dof_info.index_storage_variants[dof_access_index][cell] ==
2913 face_orientations[0],
2918 data.n_q_points_face,
2927 VectorizedArrayType grad_weight =
2928 (data.data.front().nodal_at_cell_boundaries ==
true && fe_degree > 1 &&
2931 .shape_data_on_face[0][fe_degree + (integrate ?
2932 (2 - (face_nos[0] % 2)) :
2933 (1 + (face_nos[0] % 2)))] :
2934 VectorizedArrayType(0.0 );
2936 constexpr unsigned int static_dofs_per_component =
2939 constexpr unsigned int static_dofs_per_face =
2942 const unsigned int dofs_per_face =
2943 fe_degree > -1 ? static_dofs_per_face :
2946 VectorizedArrayType *temp1 = scratch_data;
2948 const unsigned int dummy = 0;
2951 std::array<const unsigned int *, n_face_orientations> orientation = {};
2953 if (n_face_orientations == 1)
2954 orientation[0] = (data.data.front().nodal_at_cell_boundaries ==
true) ?
2955 &data.face_orientations[face_orientations[0]][0] :
2959 for (
unsigned int v = 0; v < VectorizedArrayType::size(); ++v)
2968 (data.data.front().nodal_at_cell_boundaries ==
true) ?
2969 &data.face_orientations[face_orientations[v]][0] :
2975 std::array<const unsigned int *, n_face_orientations> index_array_hermite =
2978 if (n_face_orientations == 1)
2979 index_array_hermite[0] =
2980 (data.data.front().nodal_at_cell_boundaries ==
true && fe_degree > 1 &&
2982 &data.face_to_cell_index_hermite(face_nos[0], 0) :
2985 if (n_face_orientations > 1 &&
2986 data.data.front().nodal_at_cell_boundaries ==
true && fe_degree > 1 &&
2989 for (
unsigned int v = 0; v < VectorizedArrayType::size(); ++v)
2995 data.data.front().shape_data_on_face
2996 [0][fe_degree + (integrate ? (2 - (face_nos[v] % 2)) :
2997 (1 + (face_nos[v] % 2)))][v];
2999 index_array_hermite[v] =
3000 &data.face_to_cell_index_hermite(face_nos[v], 0);
3005 std::array<const unsigned int *, n_face_orientations> index_array_nodal =
3008 if (n_face_orientations == 1)
3009 index_array_nodal[0] =
3010 (data.data.front().nodal_at_cell_boundaries ==
true) ?
3011 &data.face_to_cell_index_nodal(face_nos[0], 0) :
3014 if (n_face_orientations > 1 &&
3015 (data.data.front().nodal_at_cell_boundaries ==
true))
3017 for (
unsigned int v = 0; v < VectorizedArrayType::size(); ++v)
3022 index_array_nodal[v] =
3023 &data.face_to_cell_index_nodal(face_nos[v], 0);
3027 const auto reorientate = [&](
const unsigned int v,
const unsigned int i) {
3029 face_orientations[n_face_orientations == 1 ? 0 : v] == 0 ||
3038 bool accesses_global_vector =
true;
3040 for (
unsigned int comp = 0; comp < n_components; ++comp)
3043 proc.in_face_operation(temp1, comp);
3050 if ((do_gradients ==
false &&
3051 data.data.front().nodal_at_cell_boundaries ==
true &&
3053 (data.element_type ==
3058 if (n_face_orientations == 1 &&
3059 dof_info.index_storage_variants[dof_access_index][cell] ==
3061 interleaved_contiguous)
3066 dof_info.n_vectorization_lanes_filled[dof_access_index][cell],
3067 VectorizedArrayType::size());
3068 Number2_ *vector_ptr =
3070 dof_info.dof_indices_contiguous[dof_access_index]
3072 VectorizedArrayType::size()] +
3074 .component_dof_indices_offset[active_fe_index]
3075 [first_selected_component] +
3076 comp * static_dofs_per_component) *
3077 VectorizedArrayType::size();
3079 if (fe_degree > 1 && do_gradients ==
true)
3081 for (
unsigned int i = 0; i < dofs_per_face; ++i)
3083 if (n_face_orientations == 1)
3085 const unsigned int ind1 =
3086 index_array_hermite[0][2 * i];
3087 const unsigned int ind2 =
3088 index_array_hermite[0][2 * i + 1];
3090 data.dofs_per_component_on_cell);
3092 data.dofs_per_component_on_cell);
3093 const unsigned int i_ = reorientate(0, i);
3094 proc.hermite_grad_vectorized(
3096 temp1[i_ + dofs_per_face],
3097 vector_ptr + ind1 * VectorizedArrayType::size(),
3098 vector_ptr + ind2 * VectorizedArrayType::size(),
3109 for (
unsigned int i = 0; i < dofs_per_face; ++i)
3111 if (n_face_orientations == 1)
3113 const unsigned int i_ = reorientate(0, i);
3114 const unsigned int ind = index_array_nodal[0][i];
3115 proc.value_vectorized(
3117 vector_ptr + ind * VectorizedArrayType::size());
3128 else if (n_face_orientations == 1 &&
3129 dof_info.index_storage_variants[dof_access_index][cell] ==
3131 interleaved_contiguous_strided)
3136 dof_info.n_vectorization_lanes_filled[dof_access_index][cell],
3137 VectorizedArrayType::size());
3138 const unsigned int *indices =
3139 &dof_info.dof_indices_contiguous[dof_access_index]
3141 VectorizedArrayType::size()];
3142 Number2_ *vector_ptr =
3144 (comp * static_dofs_per_component +
3146 .component_dof_indices_offset[active_fe_index]
3147 [first_selected_component]) *
3148 VectorizedArrayType::size();
3149 if (fe_degree > 1 && do_gradients ==
true)
3151 for (
unsigned int i = 0; i < dofs_per_face; ++i)
3153 if (n_face_orientations == 1)
3155 const unsigned int i_ = reorientate(0, i);
3156 const unsigned int ind1 =
3157 index_array_hermite[0][2 * i] *
3158 VectorizedArrayType::size();
3159 const unsigned int ind2 =
3160 index_array_hermite[0][2 * i + 1] *
3161 VectorizedArrayType::size();
3162 proc.hermite_grad_vectorized_indexed(
3164 temp1[i_ + dofs_per_face],
3179 for (
unsigned int i = 0; i < dofs_per_face; ++i)
3181 if (n_face_orientations == 1)
3183 const unsigned int i_ = reorientate(0, i);
3184 const unsigned int ind =
3185 index_array_nodal[0][i] *
3186 VectorizedArrayType::size();
3187 proc.value_vectorized_indexed(temp1[i_],
3200 else if (n_face_orientations == 1 &&
3201 dof_info.index_storage_variants[dof_access_index][cell] ==
3203 interleaved_contiguous_mixed_strides)
3207 const unsigned int *strides =
3208 &dof_info.dof_indices_interleave_strides
3209 [dof_access_index][cell * VectorizedArrayType::size()];
3210 unsigned int indices[VectorizedArrayType::size()];
3211 for (
unsigned int v = 0; v < VectorizedArrayType::size(); ++v)
3213 dof_info.dof_indices_contiguous
3215 [cell * VectorizedArrayType::size() + v] +
3217 .component_dof_indices_offset[active_fe_index]
3218 [first_selected_component] +
3219 comp * static_dofs_per_component) *
3221 const unsigned int n_filled_lanes =
3222 dof_info.n_vectorization_lanes_filled[dof_access_index][cell];
3224 if (fe_degree > 1 && do_gradients ==
true)
3226 if (n_filled_lanes == VectorizedArrayType::size())
3227 for (
unsigned int i = 0; i < dofs_per_face; ++i)
3229 if (n_face_orientations == 1)
3231 const unsigned int i_ = reorientate(0, i);
3232 unsigned int ind1[VectorizedArrayType::size()];
3234 for (
unsigned int v = 0;
3235 v < VectorizedArrayType::size();
3239 index_array_hermite[0 ][2 * i] *
3241 unsigned int ind2[VectorizedArrayType::size()];
3243 for (
unsigned int v = 0;
3244 v < VectorizedArrayType::size();
3248 index_array_hermite[0 ][2 * i + 1] *
3250 proc.hermite_grad_vectorized_indexed(
3252 temp1[i_ + dofs_per_face],
3266 if (integrate ==
false)
3267 for (
unsigned int i = 0; i < 2 * dofs_per_face; ++i)
3268 temp1[i] = VectorizedArrayType();
3270 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
3271 for (
unsigned int i = 0; i < dofs_per_face; ++i)
3273 const unsigned int i_ =
3274 reorientate(n_face_orientations == 1 ? 0 : v,
3278 temp1[i_ + dofs_per_face][v],
3282 [n_face_orientations == 1 ? 0 : v]
3288 [n_face_orientations == 1 ? 0 : v]
3291 grad_weight[n_face_orientations == 1 ? 0 : v]);
3297 if (n_filled_lanes == VectorizedArrayType::size())
3298 for (
unsigned int i = 0; i < dofs_per_face; ++i)
3300 if (n_face_orientations == 1)
3302 unsigned int ind[VectorizedArrayType::size()];
3304 for (
unsigned int v = 0;
3305 v < VectorizedArrayType::size();
3307 ind[v] = indices[v] +
3308 index_array_nodal[0][i] * strides[v];
3309 const unsigned int i_ = reorientate(0, i);
3310 proc.value_vectorized_indexed(temp1[i_],
3321 if (integrate ==
false)
3322 for (
unsigned int i = 0; i < dofs_per_face; ++i)
3323 temp1[i] = VectorizedArrayType();
3325 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
3326 for (
unsigned int i = 0; i < dofs_per_face; ++i)
3329 n_face_orientations == 1 ? 0 : v, i)][v],
3333 [n_face_orientations == 1 ? 0 : v][i] *
3340 else if (n_face_orientations > 1 ||
3341 dof_info.index_storage_variants[dof_access_index][cell] ==
3345 const unsigned int *indices =
3346 &dof_info.dof_indices_contiguous[dof_access_index]
3348 VectorizedArrayType::size()];
3349 Number2_ *vector_ptr =
3350 global_vector_ptr + comp * static_dofs_per_component +
3352 .component_dof_indices_offset[active_fe_index]
3353 [first_selected_component];
3355 const unsigned int n_filled_lanes =
3356 dof_info.n_vectorization_lanes_filled[dof_access_index][cell];
3358 const bool vectorization_possible =
3359 (n_face_orientations == 1) &&
3360 (n_filled_lanes == VectorizedArrayType::size()) &&
3361 (sm_ptr !=
nullptr);
3363 std::array<Number2_ *, VectorizedArrayType::size()>
3366 if (vectorization_possible ==
false)
3368 if (n_face_orientations == 1)
3370 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
3371 if (sm_ptr ==
nullptr)
3373 vector_ptrs[v] = vector_ptr + indices[v];
3378 dof_info.dof_indices_contiguous_sm
3380 [cell * VectorizedArrayType::size() + v];
3381 vector_ptrs[v] =
const_cast<Number *
>(
3382 sm_ptr->operator[](temp.first).data() +
3383 temp.second + comp * static_dofs_per_component +
3384 dof_info.component_dof_indices_offset
3385 [active_fe_index][first_selected_component]);
3388 else if (n_face_orientations == VectorizedArrayType::size())
3390 for (
unsigned int v = 0;
3391 v < VectorizedArrayType::size();
3395 if (sm_ptr ==
nullptr)
3400 .dof_indices_contiguous[dof_access_index]
3406 dof_info.dof_indices_contiguous_sm
3407 [dof_access_index][cells[v]];
3408 vector_ptrs[v] =
const_cast<Number *
>(
3409 sm_ptr->operator[](temp.first).data() +
3411 comp * static_dofs_per_component +
3412 dof_info.component_dof_indices_offset
3414 [first_selected_component]);
3424 if (do_gradients ==
true &&
3425 data.element_type ==
3428 if (vectorization_possible)
3429 for (
unsigned int i = 0; i < dofs_per_face; ++i)
3431 const unsigned int ind1 =
3432 index_array_hermite[0][2 * i];
3433 const unsigned int ind2 =
3434 index_array_hermite[0][2 * i + 1];
3435 const unsigned int i_ = reorientate(0, i);
3437 proc.hermite_grad_vectorized_indexed(
3439 temp1[i_ + dofs_per_face],
3446 else if (n_face_orientations == 1)
3447 for (
unsigned int i = 0; i < dofs_per_face; ++i)
3449 const unsigned int ind1 =
3450 index_array_hermite[0][2 * i];
3451 const unsigned int ind2 =
3452 index_array_hermite[0][2 * i + 1];
3453 const unsigned int i_ = reorientate(0, i);
3455 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
3456 proc.hermite_grad(temp1[i_][v],
3457 temp1[i_ + dofs_per_face][v],
3458 vector_ptrs[v][ind1],
3459 vector_ptrs[v][ind2],
3462 if (integrate ==
false)
3463 for (
unsigned int v = n_filled_lanes;
3464 v < VectorizedArrayType::size();
3468 temp1[i_ + dofs_per_face][v] = 0.0;
3473 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
3474 for (
unsigned int i = 0; i < dofs_per_face; ++i)
3476 temp1[reorientate(v, i)][v],
3477 temp1[reorientate(v, i) + dofs_per_face][v],
3478 vector_ptrs[v][index_array_hermite[v][2 * i]],
3479 vector_ptrs[v][index_array_hermite[v][2 * i + 1]],
3485 if (vectorization_possible)
3486 for (
unsigned int i = 0; i < dofs_per_face; ++i)
3488 const unsigned int ind = index_array_nodal[0][i];
3489 const unsigned int i_ = reorientate(0, i);
3491 proc.value_vectorized_indexed(temp1[i_],
3495 else if (n_face_orientations == 1)
3496 for (
unsigned int i = 0; i < dofs_per_face; ++i)
3498 const unsigned int ind = index_array_nodal[0][i];
3499 const unsigned int i_ = reorientate(0, i);
3501 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
3502 proc.value(temp1[i_][v], vector_ptrs[v][ind]);
3504 if (integrate ==
false)
3505 for (
unsigned int v = n_filled_lanes;
3506 v < VectorizedArrayType::size();
3511 for (
unsigned int i = 0; i < dofs_per_face; ++i)
3513 for (
unsigned int v = 0;
3514 v < VectorizedArrayType::size();
3518 temp1[reorientate(v, i)][v],
3519 vector_ptrs[v][index_array_nodal[v][i]]);
3532 proc.default_operation(temp1, comp);
3534 accesses_global_vector =
false;
3542 proc.default_operation(temp1, comp);
3544 accesses_global_vector =
false;
3550 proc.in_face_operation(temp1, comp);
3554 (face_orientations[0] > 0 &&
3560 face_orientations[0],
3565 data.n_q_points_face,
3571 return accesses_global_vector;
3578 typename VectorizedArrayType,
3579 typename Number2 = Number>
3582 template <
int fe_degree,
int n_q_po
ints_1d>
3584 run(
const unsigned int n_components,
3585 const unsigned int n_face_orientations,
3586 const Number2 * src_ptr,
3590 VectorizedArrayType * values_quad,
3591 VectorizedArrayType *gradients_quad,
3592 VectorizedArrayType *scratch_data,
3593 const bool evaluate_values,
3594 const bool evaluate_gradients,
3595 const unsigned int active_fe_index,
3596 const unsigned int first_selected_component,
3597 const std::array<
unsigned int, VectorizedArrayType::size()> cells,
3598 const std::array<
unsigned int, VectorizedArrayType::size()> face_nos,
3599 const unsigned int subface_index,
3601 const std::array<
unsigned int, VectorizedArrayType::size()>
3605 if (src_ptr ==
nullptr)
3625 first_selected_component,
3633 if (n_face_orientations == VectorizedArrayType::size())
3634 return fe_face_evaluation_process_and_io<VectorizedArrayType::size()>(
3637 return fe_face_evaluation_process_and_io<1>(p);
3641 template <
int fe_degree,
int n_q_po
ints_1d>
3644 static const int dim_ = dim;
3645 static const int fe_degree_ = fe_degree;
3646 static const int n_q_points_1d_ = n_q_points_1d;
3652 const unsigned int n_components,
3653 const bool integrate,
3654 const Number2 * global_vector_ptr,
3658 VectorizedArrayType * values_quad,
3659 VectorizedArrayType *gradients_quad,
3660 VectorizedArrayType *scratch_data,
3661 const bool do_values,
3662 const bool do_gradients,
3663 const unsigned int active_fe_index,
3664 const unsigned int first_selected_component,
3665 const std::array<
unsigned int, VectorizedArrayType::size()> cells,
3666 const std::array<
unsigned int, VectorizedArrayType::size()> face_nos,
3667 const unsigned int subface_index,
3669 const std::array<
unsigned int, VectorizedArrayType::size()>
3672 : n_components(n_components)
3673 , integrate(integrate)
3674 , global_vector_ptr(global_vector_ptr)
3677 , dof_info(dof_info)
3678 , values_quad(values_quad)
3679 , gradients_quad(gradients_quad)
3680 , scratch_data(scratch_data)
3681 , do_values(do_values)
3682 , do_gradients(do_gradients)
3683 , active_fe_index(active_fe_index)
3684 , first_selected_component(first_selected_component)
3686 , face_nos(face_nos)
3687 , subface_index(subface_index)
3688 , dof_access_index(dof_access_index)
3689 , face_orientations(face_orientations)
3690 , orientation_map(orientation_map)
3693 template <
typename T0,
typename T1,
typename T2>
3699 const T2 &grad_weight)
3703 temp_2 = grad_weight * (temp_1 - temp_2);
3706 template <
typename T1,
typename T2>
3713 template <
typename T0,
typename T1,
typename T2,
typename T3>
3719 const T2 &grad_weight,
3720 const T3 &indices_1,
3721 const T3 &indices_2)
3725 temp_2 = grad_weight * (temp_1 - temp_2);
3728 template <
typename T0,
typename T1,
typename T2>
3735 template <
typename T0,
typename T1,
typename T2>
3739 const T1 &src_ptr_1,
3740 const T2 &src_ptr_2,
3741 const T2 &grad_weight)
3745 temp_2 = grad_weight * (temp_1 - src_ptr_2);
3748 template <
typename T1,
typename T2>
3756 template <
typename T1>
3763 template <
typename T1>
3767 const unsigned int dofs_per_face =
3771 const unsigned int n_q_points =
3774 if (fe_degree > -1 &&
3781 VectorizedArrayType>::
3782 evaluate_in_face( 1,
3785 values_quad + comp * n_q_points,
3786 gradients_quad + comp * dim * n_q_points,
3787 scratch_data + 2 * dofs_per_face,
3796 VectorizedArrayType>::
3797 evaluate_in_face( 1,
3800 values_quad + comp * n_q_points,
3801 gradients_quad + comp * dim * n_q_points,
3802 scratch_data + 2 * dofs_per_face,
3811 const std::vector<ArrayView<const Number>> *
sm_ptr;
3821 const std::array<
unsigned int, VectorizedArrayType::size()>
cells;
3825 const std::array<
unsigned int, VectorizedArrayType::size()>
3833 typename VectorizedArrayType,
3834 typename Number2 = Number>
3837 template <
int fe_degree,
int n_q_po
ints_1d>
3839 run(
const unsigned int n_components,
3840 const unsigned int n_face_orientations,
3845 VectorizedArrayType * values_array,
3846 VectorizedArrayType * values_quad,
3847 VectorizedArrayType *gradients_quad,
3848 VectorizedArrayType *scratch_data,
3849 const bool integrate_values,
3850 const bool integrate_gradients,
3851 const unsigned int active_fe_index,
3852 const unsigned int first_selected_component,
3853 const std::array<
unsigned int, VectorizedArrayType::size()> cells,
3854 const std::array<
unsigned int, VectorizedArrayType::size()> face_nos,
3855 const unsigned int subface_index,
3857 const std::array<
unsigned int, VectorizedArrayType::size()>
3863 if (dst_ptr ==
nullptr ||
3870 template run<fe_degree, n_q_points_1d>(n_components,
3877 integrate_gradients,
3880 face_orientations[0],
3899 integrate_gradients,
3901 first_selected_component,
3909 if (n_face_orientations == VectorizedArrayType::size())
3910 return fe_face_evaluation_process_and_io<VectorizedArrayType::size()>(
3913 return fe_face_evaluation_process_and_io<1>(p);
3917 template <
int fe_degree,
int n_q_po
ints_1d>
3920 static const int dim_ = dim;
3921 static const int fe_degree_ = fe_degree;
3922 static const int n_q_points_1d_ = n_q_points_1d;
3929 VectorizedArrayType * values_array,
3930 const unsigned int n_components,
3931 const bool integrate,
3932 Number2 * global_vector_ptr,
3936 VectorizedArrayType * values_quad,
3937 VectorizedArrayType *gradients_quad,
3938 VectorizedArrayType *scratch_data,
3939 const bool do_values,
3940 const bool do_gradients,
3941 const unsigned int active_fe_index,
3942 const unsigned int first_selected_component,
3943 const std::array<
unsigned int, VectorizedArrayType::size()> cells,
3944 const std::array<
unsigned int, VectorizedArrayType::size()> face_nos,
3945 const unsigned int subface_index,
3947 const std::array<
unsigned int, VectorizedArrayType::size()>
3950 : values_array(values_array)
3951 , n_components(n_components)
3952 , integrate(integrate)
3953 , global_vector_ptr(global_vector_ptr)
3956 , dof_info(dof_info)
3957 , values_quad(values_quad)
3958 , gradients_quad(gradients_quad)
3959 , scratch_data(scratch_data)
3960 , do_values(do_values)
3961 , do_gradients(do_gradients)
3962 , active_fe_index(active_fe_index)
3963 , first_selected_component(first_selected_component)
3965 , face_nos(face_nos)
3966 , subface_index(subface_index)
3967 , dof_access_index(dof_access_index)
3968 , face_orientations(face_orientations)
3969 , orientation_map(orientation_map)
3972 template <
typename T0,
typename T1,
typename T2,
typename T3,
typename T4>
3978 const T4 &grad_weight)
3981 const VectorizedArrayType val = temp_1 - grad_weight * temp_2;
3982 const VectorizedArrayType grad = grad_weight * temp_2;
3987 template <
typename T0,
typename T1>
3995 template <
typename T0,
typename T1,
typename T2,
typename T3>
4001 const T2 &grad_weight,
4002 const T3 &indices_1,
4003 const T3 &indices_2)
4006 const VectorizedArrayType val = temp_1 - grad_weight * temp_2;
4007 const VectorizedArrayType grad = grad_weight * temp_2;
4012 template <
typename T0,
typename T1,
typename T2>
4020 template <
typename T0,
typename T1,
typename T2>
4026 const T2 &grad_weight)
4029 const Number val = temp_1 - grad_weight * temp_2;
4030 const Number grad = grad_weight * temp_2;
4035 template <
typename T0,
typename T1>
4043 template <
typename T0>
4051 template interpolate<false, false>(
4060 template <
typename T0>
4064 const unsigned int dofs_per_face =
4068 const unsigned int n_q_points =
4071 if (fe_degree > -1 &&
4079 VectorizedArrayType>::
4080 integrate_in_face( 1,
4083 values_quad + comp * n_q_points,
4084 gradients_quad + dim * comp * n_q_points,
4085 scratch_data + 2 * dofs_per_face,
4094 VectorizedArrayType>::
4095 integrate_in_face( 1,
4098 values_quad + comp * n_q_points,
4099 gradients_quad + dim * comp * n_q_points,
4100 scratch_data + 2 * dofs_per_face,
4112 const std::vector<ArrayView<const Number>> *
sm_ptr;
4122 const std::array<
unsigned int, VectorizedArrayType::size()>
cells;
4126 const std::array<
unsigned int, VectorizedArrayType::size()>
4138 template <
int dim,
typename Number>
4141 template <
int fe_degree,
int = 0>
4143 run(
const unsigned int n_components,
4145 typename Number::value_type,
4148 const Number * in_array,
4150 typename std::enable_if<fe_degree != -1>::type * =
nullptr)
4152 constexpr unsigned int dofs_per_component =
4156 Assert(fe_eval.get_shape_info().element_type <=
4168 fe_eval.get_shape_info().
data.front().inverse_shape_values_eo);
4170 for (
unsigned int d = 0;
d < n_components; ++
d)
4172 const Number *in = in_array +
d * dofs_per_component;
4173 Number * out = out_array +
d * dofs_per_component;
4176 evaluator.template hessians<0, true, false>(in, out);
4178 evaluator.template hessians<1, true, false>(out, out);
4180 evaluator.template hessians<2, true, false>(out, out);
4182 for (
unsigned int q = 0; q < dofs_per_component; ++q)
4184 const Number inverse_JxW_q = Number(1.) / fe_eval.JxW(q);
4185 for (
unsigned int d = 0;
d < n_components; ++
d)
4186 out_array[q +
d * dofs_per_component] *= inverse_JxW_q;
4188 for (
unsigned int d = 0;
d < n_components; ++
d)
4190 Number *out = out_array +
d * dofs_per_component;
4192 evaluator.template hessians<2, false, false>(out, out);
4194 evaluator.template hessians<1, false, false>(out, out);
4195 evaluator.template hessians<0, false, false>(out, out);
4200 template <
int fe_degree,
int = 0>
4202 run(
const unsigned int n_components,
4204 typename Number::value_type,
4207 const Number * in_array,
4209 typename std::enable_if<fe_degree == -1>::type * =
nullptr)
4211 static_assert(fe_degree == -1,
"Only usable for degree -1");
4212 const unsigned int dofs_per_component =
4213 fe_eval.get_shape_info().dofs_per_component_on_cell;
4218 EvaluatorTensorProduct<internal::evaluate_general, dim, 0, 0, Number>
4219 evaluator(fe_eval.get_shape_info().data.front().inverse_shape_values,
4222 fe_eval.get_shape_info().
data.front().fe_degree + 1,
4223 fe_eval.get_shape_info().data.front().fe_degree + 1);
4225 for (
unsigned int d = 0;
d < n_components; ++
d)
4227 const Number *in = in_array +
d * dofs_per_component;
4228 Number * out = out_array +
d * dofs_per_component;
4231 evaluator.template values<0, true, false>(in, out);
4233 evaluator.template values<1, true, false>(out, out);
4235 evaluator.template values<2, true, false>(out, out);
4237 for (
unsigned int q = 0; q < dofs_per_component; ++q)
4239 const Number inverse_JxW_q = Number(1.) / fe_eval.JxW(q);
4240 for (
unsigned int d = 0;
d < n_components; ++
d)
4241 out_array[q +
d * dofs_per_component] *= inverse_JxW_q;
4243 for (
unsigned int d = 0;
d < n_components; ++
d)
4245 Number *out = out_array +
d * dofs_per_component;
4247 evaluator.template values<2, false, false>(out, out);
4249 evaluator.template values<1, false, false>(out, out);
4250 evaluator.template values<0, false, false>(out, out);
4262 template <
int dim,
typename Number>
4265 template <
int fe_degree,
int = 0>
4267 run(
const unsigned int n_desired_components,
4270 const Number * in_array,
4272 typename std::enable_if<fe_degree != -1>::type * =
nullptr)
4274 constexpr unsigned int dofs_per_component =
4277 inverse_coefficients.
size() % dofs_per_component == 0,
4279 "Expected diagonal to be a multiple of scalar dof per cells"));
4280 if (inverse_coefficients.
size() != dofs_per_component)
4282 inverse_coefficients.
size());
4295 const unsigned int shift_coefficient =
4296 inverse_coefficients.
size() > dofs_per_component ? dofs_per_component :
4298 const Number *inv_coefficient = inverse_coefficients.
data();
4299 for (
unsigned int d = 0;
d < n_desired_components; ++
d)
4301 const Number *in = in_array +
d * dofs_per_component;
4302 Number * out = out_array +
d * dofs_per_component;
4305 evaluator.template hessians<0, true, false>(in, out);
4307 evaluator.template hessians<1, true, false>(out, out);
4309 evaluator.template hessians<2, true, false>(out, out);
4311 for (
unsigned int q = 0; q < dofs_per_component; ++q)
4312 out[q] *= inv_coefficient[q];
4315 evaluator.template hessians<2, false, false>(out, out);
4317 evaluator.template hessians<1, false, false>(out, out);
4318 evaluator.template hessians<0, false, false>(out, out);
4320 inv_coefficient += shift_coefficient;
4328 template <
int fe_degree,
int = 0>
4335 typename std::enable_if<fe_degree == -1>::type * =
nullptr)
4337 static_assert(fe_degree == -1,
"Only usable for degree -1");
4349 template <
int dim,
typename Number>
4352 template <
int fe_degree,
int = 0>
4354 run(
const unsigned int n_desired_components,
4356 const Number * in_array,
4358 typename std::enable_if<fe_degree != -1>::type * =
nullptr)
4360 constexpr unsigned int dofs_per_cell =
Utilities::pow(fe_degree + 1, dim);
4370 for (
unsigned int d = 0;
d < n_desired_components; ++
d)
4372 const Number *in = in_array +
d * dofs_per_cell;
4373 Number * out = out_array +
d * dofs_per_cell;
4377 evaluator.template hessians<2, false, false>(in, out);
4378 evaluator.template hessians<1, false, false>(out, out);
4379 evaluator.template hessians<0, false, false>(out, out);
4383 evaluator.template hessians<1, false, false>(in, out);
4384 evaluator.template hessians<0, false, false>(out, out);
4387 evaluator.template hessians<0, false, false>(in, out);
4392 template <
int fe_degree,
int = 0>
4398 typename std::enable_if<fe_degree == -1>::type * =
nullptr)
4400 static_assert(fe_degree == -1,
"Only usable for degree -1");
void gather(const Number *base_ptr, const unsigned int *offsets)
void load(const Number *ptr)
#define DEAL_II_ALWAYS_INLINE
#define DEAL_II_OPENMP_SIMD_PRAGMA
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
static ::ExceptionBase & ExcNotImplemented()
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
@ tensor_symmetric_collocation
@ tensor_symmetric_plus_dg0
@ tensor_symmetric_hermite
EvaluationFlags
The EvaluationFlags enum.
std::enable_if< IsBlockVector< VectorType >::value, unsignedint >::type n_blocks(const VectorType &vector)
SymmetricTensor< 2, dim, Number > d(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
constexpr T pow(const T base, const int iexp)
void do_vectorized_add(const VectorizedArrayType src, Number2 *dst_ptr)
void do_vectorized_scatter_add(const VectorizedArray< Number, width > src, const unsigned int *indices, Number *dst_ptr)
void do_vectorized_scatter_add(const VectorizedArrayType src, const unsigned int *indices, Number2 *dst_ptr)
static bool fe_face_evaluation_process_and_io(Processor &proc)
void do_vectorized_read(const Number *src_ptr, VectorizedArray< Number, width > &dst)
void do_vectorized_gather(const Number2 *src_ptr, const unsigned int *indices, VectorizedArrayType &dst)
void do_vectorized_add(const VectorizedArray< Number, width > src, Number *dst_ptr)
void adjust_for_face_orientation(const unsigned int dim, const unsigned int n_components, const unsigned int face_orientation, const Table< 2, unsigned int > &orientation_map, const bool integrate, const bool values, const bool gradients, const unsigned int n_q_points, Number *tmp_values, Number *values_quad, Number *gradients_quad)
void do_vectorized_read(const Number2 *src_ptr, VectorizedArrayType &dst)
void do_vectorized_gather(const Number *src_ptr, const unsigned int *indices, VectorizedArray< Number, width > &dst)
static const unsigned int invalid_unsigned_int
::VectorizedArray< Number, width > min(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > max(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
static bool run(const unsigned int n_components, const FEEvaluationBaseData< dim, typename Number::value_type, false, Number > &fe_eval, const Number *in_array, Number *out_array, typename std::enable_if< fe_degree !=-1 >::type *=nullptr)
static bool run(const unsigned int n_components, const FEEvaluationBaseData< dim, typename Number::value_type, false, Number > &fe_eval, const Number *in_array, Number *out_array, typename std::enable_if< fe_degree==-1 >::type *=nullptr)
static bool run(const unsigned int n_desired_components, const AlignedVector< Number > &inverse_shape, const AlignedVector< Number > &inverse_coefficients, const Number *in_array, Number *out_array, typename std::enable_if< fe_degree !=-1 >::type *=nullptr)
static bool run(const unsigned int, const AlignedVector< Number > &, const AlignedVector< Number > &, const Number *, Number *, typename std::enable_if< fe_degree==-1 >::type *=nullptr)
static void do_mass(const unsigned int n_components, const AlignedVector< Number2 > &transformation_matrix, const AlignedVector< Number > &coefficients, const Number *values_in, Number *scratch_data, Number *values_out)
static void do_backward(const unsigned int n_components, const AlignedVector< Number2 > &transformation_matrix, const bool add_into_result, Number *values_in, Number *values_out, const unsigned int basis_size_1_variable=numbers::invalid_unsigned_int, const unsigned int basis_size_2_variable=numbers::invalid_unsigned_int)
static void do_forward(const unsigned int n_components, const AlignedVector< Number2 > &transformation_matrix, const Number *values_in, Number *values_out, const unsigned int basis_size_1_variable=numbers::invalid_unsigned_int, const unsigned int basis_size_2_variable=numbers::invalid_unsigned_int)
static void evaluate(const unsigned int n_components, const EvaluationFlags::EvaluationFlags evaluation_flag, const MatrixFreeFunctions::ShapeInfo< Number > &shape_info, const Number *values_dofs, Number *values_quad, Number *gradients_quad, Number *hessians_quad, Number *scratch_data)
static void integrate(const unsigned int n_components, const EvaluationFlags::EvaluationFlags integration_flag, const MatrixFreeFunctions::ShapeInfo< Number > &shape_info, Number *values_dofs, Number *values_quad, Number *gradients_quad, Number *scratch_data, const bool add_into_values_array)
static bool run(const unsigned int n_components, const EvaluationFlags::EvaluationFlags evaluation_flag, const internal::MatrixFreeFunctions::ShapeInfo< Number > &shape_info, Number *values_dofs_actual, Number *values_quad, Number *gradients_quad, Number *hessians_quad, Number *scratch_data)
static bool run(const unsigned int n_components, const EvaluationFlags::EvaluationFlags integration_flag, const internal::MatrixFreeFunctions::ShapeInfo< Number > &shape_info, Number *values_dofs_actual, Number *values_quad, Number *gradients_quad, Number *scratch_data, const bool sum_into_values_array)
static void evaluate(const unsigned int n_components, const EvaluationFlags::EvaluationFlags evaluation_flag, const MatrixFreeFunctions::ShapeInfo< Number > &shape_info, const Number *values_dofs_actual, Number *values_quad, Number *gradients_quad, Number *hessians_quad, Number *scratch_data)
static void integrate(const unsigned int n_components, const EvaluationFlags::EvaluationFlags integration_flag, const MatrixFreeFunctions::ShapeInfo< Number > &shape_info, Number *values_dofs_actual, Number *values_quad, Number *gradients_quad, Number *scratch_data, const bool add_into_values_array)
static bool run(const unsigned int n_components, const MatrixFreeFunctions::ShapeInfo< VectorizedArrayType > &data, const VectorizedArrayType *values_array, VectorizedArrayType *values_quad, VectorizedArrayType *gradients_quad, VectorizedArrayType *scratch_data, const bool evaluate_values, const bool evaluate_gradients, const unsigned int face_no, const unsigned int subface_index, const unsigned int face_orientation, const Table< 2, unsigned int > &orientation_map)
const Table< 2, unsigned int > & orientation_map
const unsigned int n_components
const Number2 * global_vector_ptr
const unsigned int subface_index
void value_vectorized_indexed(T0 &temp, const T1 src_ptr, const T2 &indices)
const std::vector< ArrayView< const Number > > * sm_ptr
const MatrixFreeFunctions::DoFInfo::DoFAccessIndex dof_access_index
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)
Processor(const unsigned int n_components, const bool integrate, const Number2 *global_vector_ptr, const std::vector< ArrayView< const Number > > *sm_ptr, const MatrixFreeFunctions::ShapeInfo< VectorizedArrayType > &data, const MatrixFreeFunctions::DoFInfo &dof_info, VectorizedArrayType *values_quad, VectorizedArrayType *gradients_quad, VectorizedArrayType *scratch_data, const bool do_values, const bool do_gradients, const unsigned int active_fe_index, const unsigned int first_selected_component, const std::array< unsigned int, VectorizedArrayType::size()> cells, const std::array< unsigned int, VectorizedArrayType::size()> face_nos, const unsigned int subface_index, const MatrixFreeFunctions::DoFInfo::DoFAccessIndex dof_access_index, const std::array< unsigned int, VectorizedArrayType::size()> face_orientations, const Table< 2, unsigned int > &orientation_map)
void value_vectorized(T1 &temp, const T2 src_ptr)
const MatrixFreeFunctions::ShapeInfo< VectorizedArrayType > & data
const std::array< unsigned int, VectorizedArrayType::size()> face_nos
VectorizedArrayType * scratch_data
VectorizedArrayType * values_quad
const std::array< unsigned int, VectorizedArrayType::size()> cells
void hermite_grad(T0 &temp_1, T0 &temp_2, const T1 &src_ptr_1, const T2 &src_ptr_2, const T2 &grad_weight)
void value(T1 &temp, const T2 &src_ptr)
VectorizedArrayType * gradients_quad
VectorizedArrayType VectorizedArrayType_
const std::array< unsigned int, VectorizedArrayType::size()> face_orientations
void hermite_grad_vectorized(T0 &temp_1, T0 &temp_2, const T1 src_ptr_1, const T1 src_ptr_2, const T2 &grad_weight)
const MatrixFreeFunctions::DoFInfo & dof_info
const unsigned int active_fe_index
void in_face_operation(T1 &temp1, const unsigned int comp)
const unsigned int first_selected_component
void default_operation(const T1 &, const unsigned int)
static bool run(const unsigned int n_components, const unsigned int n_face_orientations, const Number2 *src_ptr, const std::vector< ArrayView< const Number > > *sm_ptr, const MatrixFreeFunctions::ShapeInfo< VectorizedArrayType > &data, const MatrixFreeFunctions::DoFInfo &dof_info, VectorizedArrayType *values_quad, VectorizedArrayType *gradients_quad, VectorizedArrayType *scratch_data, const bool evaluate_values, const bool evaluate_gradients, const unsigned int active_fe_index, const unsigned int first_selected_component, const std::array< unsigned int, VectorizedArrayType::size()> cells, const std::array< unsigned int, VectorizedArrayType::size()> face_nos, const unsigned int subface_index, const MatrixFreeFunctions::DoFInfo::DoFAccessIndex dof_access_index, const std::array< unsigned int, VectorizedArrayType::size()> face_orientations, const Table< 2, unsigned int > &orientation_map)
void value_vectorized_indexed(const T0 &temp, T1 dst_ptr, const T2 &indices)
Number2 * global_vector_ptr
const std::array< unsigned int, VectorizedArrayType::size()> face_orientations
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)
const Table< 2, unsigned int > & orientation_map
const std::array< unsigned int, VectorizedArrayType::size()> face_nos
VectorizedArrayType * values_array
const std::vector< ArrayView< const Number > > * sm_ptr
Processor(VectorizedArrayType *values_array, const unsigned int n_components, const bool integrate, Number2 *global_vector_ptr, const std::vector< ArrayView< const Number > > *sm_ptr, const MatrixFreeFunctions::ShapeInfo< VectorizedArrayType > &data, const MatrixFreeFunctions::DoFInfo &dof_info, VectorizedArrayType *values_quad, VectorizedArrayType *gradients_quad, VectorizedArrayType *scratch_data, const bool do_values, const bool do_gradients, const unsigned int active_fe_index, const unsigned int first_selected_component, const std::array< unsigned int, VectorizedArrayType::size()> cells, const std::array< unsigned int, VectorizedArrayType::size()> face_nos, const unsigned int subface_index, const MatrixFreeFunctions::DoFInfo::DoFAccessIndex dof_access_index, const std::array< unsigned int, VectorizedArrayType::size()> face_orientations, const Table< 2, unsigned int > &orientation_map)
void default_operation(const T0 &temp1, const unsigned int comp)
VectorizedArrayType VectorizedArrayType_
const MatrixFreeFunctions::DoFInfo::DoFAccessIndex dof_access_index
VectorizedArrayType * scratch_data
void value(const T0 &temp, T1 &dst_ptr)
const MatrixFreeFunctions::ShapeInfo< VectorizedArrayType > & data
const unsigned int subface_index
const std::array< unsigned int, VectorizedArrayType::size()> cells
void value_vectorized(const T0 &temp, T1 dst_ptr)
void hermite_grad(const T0 &temp_1, const T0 &temp_2, T1 &dst_ptr_1, T1 &dst_ptr_2, const T2 &grad_weight)
VectorizedArrayType * gradients_quad
const MatrixFreeFunctions::DoFInfo & dof_info
void hermite_grad_vectorized(const T0 &temp_1, const T1 &temp_2, T2 dst_ptr_1, T3 dst_ptr_2, const T4 &grad_weight)
const unsigned int first_selected_component
const unsigned int n_components
const unsigned int active_fe_index
VectorizedArrayType * values_quad
void in_face_operation(T0 &temp1, const unsigned int comp)
static bool run(const unsigned int n_components, const unsigned int n_face_orientations, Number2 *dst_ptr, const std::vector< ArrayView< const Number2 > > *sm_ptr, const MatrixFreeFunctions::ShapeInfo< VectorizedArrayType > &data, const MatrixFreeFunctions::DoFInfo &dof_info, VectorizedArrayType *values_array, VectorizedArrayType *values_quad, VectorizedArrayType *gradients_quad, VectorizedArrayType *scratch_data, const bool integrate_values, const bool integrate_gradients, const unsigned int active_fe_index, const unsigned int first_selected_component, const std::array< unsigned int, VectorizedArrayType::size()> cells, const std::array< unsigned int, VectorizedArrayType::size()> face_nos, const unsigned int subface_index, const MatrixFreeFunctions::DoFInfo::DoFAccessIndex dof_access_index, const std::array< unsigned int, VectorizedArrayType::size()> face_orientations, const Table< 2, unsigned int > &orientation_map)
static bool run(const unsigned int n_components, const MatrixFreeFunctions::ShapeInfo< VectorizedArrayType > &data, VectorizedArrayType *values_array, VectorizedArrayType *values_quad, VectorizedArrayType *gradients_quad, VectorizedArrayType *scratch_data, const bool integrate_values, const bool integrate_gradients, const unsigned int face_no, const unsigned int subface_index, const unsigned int face_orientation, const Table< 2, unsigned int > &orientation_map)
static void integrate_in_face(const unsigned int n_components, const MatrixFreeFunctions::ShapeInfo< Number > &data, Number *values_dofs, Number *values_quad, Number *gradients_quad, Number *scratch_data, const bool integrate_val, const bool integrate_grad, const unsigned int subface_index)
static void evaluate_in_face(const unsigned int n_components, const MatrixFreeFunctions::ShapeInfo< Number > &data, Number *values_dofs, Number *values_quad, Number *gradients_quad, Number *scratch_data, const bool evaluate_val, const bool evaluate_grad, const unsigned int subface_index)
static constexpr bool use_collocation
static void interpolate_quadrature(const unsigned int n_components, const MatrixFreeFunctions::ShapeInfo< Number > &data, const Number *input, Number *output, const bool do_gradients, const unsigned int face_no)
static void interpolate_generic(const unsigned int n_components, const Number *input, Number *output, const bool do_gradients, const unsigned int face_no, const unsigned int n_points_1d, const std::array< AlignedVector< Number >, 2 > &shape_data, const unsigned int dofs_per_component_on_cell, const unsigned int dofs_per_component_on_face)
static void interpolate(const unsigned int n_components, const MatrixFreeFunctions::ShapeInfo< Number > &data, const Number *input, Number *output, const bool do_gradients, const unsigned int face_no)
unsigned int n_q_points_face
unsigned int dofs_per_component_on_cell
std::vector< UnivariateShapeData< Number > > data
unsigned int dofs_per_component_on_face
std::vector< unsigned int > n_q_points_faces