17 #ifndef dealii_matrix_free_evaluation_kernels_h
18 #define dealii_matrix_free_evaluation_kernels_h
37 template <MatrixFreeFunctions::ElementType element,
bool is_
long>
41 template <
bool is_
long>
59 template <
bool is_
long>
78 template <
bool is_
long>
115 const Number * values_dofs_actual,
116 Number * values_quad,
117 Number * gradients_quad,
118 Number * hessians_quad,
119 Number * scratch_data,
120 const bool evaluate_values,
121 const bool evaluate_gradients,
122 const bool evaluate_hessians);
126 Number * values_dofs_actual,
127 Number * values_quad,
128 Number * gradients_quad,
129 Number * scratch_data,
130 const bool integrate_values,
131 const bool integrate_gradients,
132 const bool add_into_values_array);
146 const Number * values_dofs_actual,
147 Number * values_quad,
148 Number * gradients_quad,
149 Number * hessians_quad,
150 Number * scratch_data,
151 const bool evaluate_values,
152 const bool evaluate_gradients,
153 const bool evaluate_hessians)
155 if (evaluate_values ==
false && evaluate_gradients ==
false &&
156 evaluate_hessians ==
false)
167 shape_info.
data.front().shape_values_eo :
168 shape_info.
data.front().shape_values,
170 shape_info.
data.front().shape_gradients_eo :
171 shape_info.
data.front().shape_gradients,
173 shape_info.
data.front().shape_hessians_eo :
174 shape_info.
data.front().shape_hessians,
175 shape_info.
data.front().fe_degree + 1,
176 shape_info.
data.front().n_q_points_1d);
178 const unsigned int temp_size =
181 (Eval::n_rows_of_product > Eval::n_columns_of_product ?
182 Eval::n_rows_of_product :
183 Eval::n_columns_of_product);
188 temp1 = scratch_data;
189 temp2 = temp1 +
std::max(Utilities::fixed_power<dim>(
190 shape_info.
data.front().fe_degree + 1),
191 Utilities::fixed_power<dim>(
192 shape_info.
data.front().n_q_points_1d));
196 temp1 = scratch_data;
197 temp2 = temp1 + temp_size;
200 const unsigned int n_q_points =
201 temp_size == 0 ? shape_info.
n_q_points : Eval::n_columns_of_product;
202 const unsigned int dofs_per_comp =
204 Utilities::fixed_power<dim>(shape_info.
data.front().fe_degree + 1) :
206 const Number *values_dofs = values_dofs_actual;
209 Number *values_dofs_tmp =
213 fe_degree != -1 ? fe_degree : shape_info.
data.front().fe_degree;
214 unsigned int count_p = 0, count_q = 0;
215 for (
int i = 0; i < (dim > 2 ? degree + 1 : 1); ++i)
217 for (
int j = 0; j < (dim > 1 ? degree + 1 - i : 1); ++j)
219 for (
int k = 0; k < degree + 1 - j - i;
220 ++k, ++count_p, ++count_q)
222 values_dofs_tmp[c * dofs_per_comp + count_q] =
225 for (
int k = degree + 1 - j - i; k < degree + 1; ++k, ++count_q)
227 values_dofs_tmp[c * dofs_per_comp + count_q] = Number();
229 for (
int j = degree + 1 - i; j < degree + 1; ++j)
230 for (
int k = 0; k < degree + 1; ++k, ++count_q)
232 values_dofs_tmp[c * dofs_per_comp + count_q] = Number();
235 values_dofs = values_dofs_tmp;
243 if (evaluate_values ==
true)
244 eval.template values<0, true, false>(values_dofs, values_quad);
245 if (evaluate_gradients ==
true)
246 eval.template gradients<0, true, false>(values_dofs,
248 if (evaluate_hessians ==
true)
249 eval.template hessians<0, true, false>(values_dofs,
253 values_dofs += dofs_per_comp;
254 values_quad += n_q_points;
255 gradients_quad += n_q_points;
256 hessians_quad += n_q_points;
264 if (evaluate_gradients ==
true)
266 eval.template gradients<0, true, false>(values_dofs, temp1);
267 eval.template values<1, true, false>(temp1, gradients_quad);
269 if (evaluate_hessians ==
true)
272 if (evaluate_gradients ==
false)
273 eval.template gradients<0, true, false>(values_dofs, temp1);
274 eval.template gradients<1, true, false>(temp1,
279 eval.template hessians<0, true, false>(values_dofs, temp1);
280 eval.template values<1, true, false>(temp1, hessians_quad);
284 eval.template values<0, true, false>(values_dofs, temp1);
285 if (evaluate_gradients ==
true)
286 eval.template gradients<1, true, false>(temp1,
291 if (evaluate_hessians ==
true)
292 eval.template hessians<1, true, false>(temp1,
297 if (evaluate_values ==
true)
298 eval.template values<1, true, false>(temp1, values_quad);
301 values_dofs += dofs_per_comp;
302 values_quad += n_q_points;
303 gradients_quad += 2 * n_q_points;
304 hessians_quad += 3 * n_q_points;
311 if (evaluate_gradients ==
true)
314 eval.template gradients<0, true, false>(values_dofs, temp1);
315 eval.template values<1, true, false>(temp1, temp2);
316 eval.template values<2, true, false>(temp2, gradients_quad);
319 if (evaluate_hessians ==
true)
322 if (evaluate_gradients ==
false)
324 eval.template gradients<0, true, false>(values_dofs,
326 eval.template values<1, true, false>(temp1, temp2);
328 eval.template gradients<2, true, false>(temp2,
333 eval.template gradients<1, true, false>(temp1, temp2);
334 eval.template values<2, true, false>(temp2,
339 eval.template hessians<0, true, false>(values_dofs, temp1);
340 eval.template values<1, true, false>(temp1, temp2);
341 eval.template values<2, true, false>(temp2, hessians_quad);
345 eval.template values<0, true, false>(values_dofs, temp1);
346 if (evaluate_gradients ==
true)
348 eval.template gradients<1, true, false>(temp1, temp2);
349 eval.template values<2, true, false>(temp2,
354 if (evaluate_hessians ==
true)
357 if (evaluate_gradients ==
false)
358 eval.template gradients<1, true, false>(temp1, temp2);
359 eval.template gradients<2, true, false>(temp2,
364 eval.template hessians<1, true, false>(temp1, temp2);
365 eval.template values<2, true, false>(temp2,
372 eval.template values<1, true, false>(temp1, temp2);
373 if (evaluate_gradients ==
true)
374 eval.template gradients<2, true, false>(temp2,
380 if (evaluate_hessians ==
true)
381 eval.template hessians<2, true, false>(temp2,
387 if (evaluate_values ==
true)
388 eval.template values<2, true, false>(temp2, values_quad);
391 values_dofs += dofs_per_comp;
392 values_quad += n_q_points;
393 gradients_quad += 3 * n_q_points;
394 hessians_quad += 6 * n_q_points;
410 for (
unsigned int q = 0; q < shape_info.
n_q_points; ++q)
427 Number * values_dofs_actual,
428 Number * values_quad,
429 Number * gradients_quad,
430 Number * scratch_data,
431 const bool integrate_values,
432 const bool integrate_gradients,
433 const bool add_into_values_array)
443 shape_info.
data.front().shape_values_eo :
444 shape_info.
data.front().shape_values,
446 shape_info.
data.front().shape_gradients_eo :
447 shape_info.
data.front().shape_gradients,
449 shape_info.
data.front().shape_hessians_eo :
450 shape_info.
data.front().shape_hessians,
451 shape_info.
data.front().fe_degree + 1,
452 shape_info.
data.front().n_q_points_1d);
454 const unsigned int temp_size =
457 (Eval::n_rows_of_product > Eval::n_columns_of_product ?
458 Eval::n_rows_of_product :
459 Eval::n_columns_of_product);
464 temp1 = scratch_data;
465 temp2 = temp1 +
std::max(Utilities::fixed_power<dim>(
466 shape_info.
data.front().fe_degree + 1),
467 Utilities::fixed_power<dim>(
468 shape_info.
data.front().n_q_points_1d));
472 temp1 = scratch_data;
473 temp2 = temp1 + temp_size;
476 const unsigned int n_q_points =
477 temp_size == 0 ? shape_info.
n_q_points : Eval::n_columns_of_product;
478 const unsigned int dofs_per_comp =
480 Utilities::fixed_power<dim>(shape_info.
data.front().fe_degree + 1) :
483 Number *values_dofs =
494 if (integrate_values ==
true)
496 if (add_into_values_array ==
false)
497 eval.template values<0, false, false>(values_quad,
500 eval.template values<0, false, true>(values_quad,
503 if (integrate_gradients ==
true)
505 if (integrate_values ==
true || add_into_values_array ==
true)
506 eval.template gradients<0, false, true>(gradients_quad,
509 eval.template gradients<0, false, false>(gradients_quad,
514 values_dofs += dofs_per_comp;
515 values_quad += n_q_points;
516 gradients_quad += n_q_points;
523 if (integrate_values ==
true && integrate_gradients ==
false)
525 eval.template values<1, false, false>(values_quad, temp1);
526 if (add_into_values_array ==
false)
527 eval.template values<0, false, false>(temp1, values_dofs);
529 eval.template values<0, false, true>(temp1, values_dofs);
531 if (integrate_gradients ==
true)
533 eval.template gradients<1, false, false>(gradients_quad +
536 if (integrate_values)
537 eval.template values<1, false, true>(values_quad, temp1);
538 if (add_into_values_array ==
false)
539 eval.template values<0, false, false>(temp1, values_dofs);
541 eval.template values<0, false, true>(temp1, values_dofs);
542 eval.template values<1, false, false>(gradients_quad, temp1);
543 eval.template gradients<0, false, true>(temp1, values_dofs);
547 values_dofs += dofs_per_comp;
548 values_quad += n_q_points;
549 gradients_quad += 2 * n_q_points;
556 if (integrate_values ==
true && integrate_gradients ==
false)
558 eval.template values<2, false, false>(values_quad, temp1);
559 eval.template values<1, false, false>(temp1, temp2);
560 if (add_into_values_array ==
false)
561 eval.template values<0, false, false>(temp2, values_dofs);
563 eval.template values<0, false, true>(temp2, values_dofs);
565 if (integrate_gradients ==
true)
567 eval.template gradients<2, false, false>(gradients_quad +
570 if (integrate_values)
571 eval.template values<2, false, true>(values_quad, temp1);
572 eval.template values<1, false, false>(temp1, temp2);
573 eval.template values<2, false, false>(gradients_quad +
576 eval.template gradients<1, false, true>(temp1, temp2);
577 if (add_into_values_array ==
false)
578 eval.template values<0, false, false>(temp2, values_dofs);
580 eval.template values<0, false, true>(temp2, values_dofs);
581 eval.template values<2, false, false>(gradients_quad, temp1);
582 eval.template values<1, false, false>(temp1, temp2);
583 eval.template gradients<0, false, true>(temp2, values_dofs);
587 values_dofs += dofs_per_comp;
588 values_quad += n_q_points;
589 gradients_quad += 3 * n_q_points;
603 if (integrate_values)
606 values_dofs[0] = values_quad[0];
607 for (
unsigned int q = 1; q < shape_info.
n_q_points; ++q)
608 values_dofs[0] += values_quad[q];
609 values_dofs += dofs_per_comp;
610 values_quad += n_q_points;
623 unsigned int count_p = 0, count_q = 0;
625 fe_degree != -1 ? fe_degree : shape_info.
data.front().fe_degree;
626 for (
int i = 0; i < (dim > 2 ? degree + 1 : 1); ++i)
628 for (
int j = 0; j < (dim > 1 ? degree + 1 - i : 1); ++j)
630 for (
int k = 0; k < degree + 1 - j - i;
631 ++k, ++count_p, ++count_q)
636 values_dofs[c * dofs_per_comp + count_q];
640 count_q += i * (degree + 1);
643 Utilities::fixed_power<dim>(
644 shape_info.
data.front().fe_degree + 1));
670 static_assert(basis_size_1 == 0 || basis_size_1 <= basis_size_2,
671 "The second dimension must not be smaller than the first");
700 const Number * values_in,
706 basis_size_1 != 0 || basis_size_1_variable <= basis_size_2_variable,
707 ExcMessage(
"The second dimension must not be smaller than the first"));
713 constexpr
int next_dim =
715 ((basis_size_1 == 0 || basis_size_2 > basis_size_1) && dim > 1)) ?
722 (basis_size_1 == 0 ? 0 : basis_size_2),
725 eval_val(transformation_matrix,
728 basis_size_1_variable,
729 basis_size_2_variable);
730 const unsigned int np_1 =
731 basis_size_1 > 0 ? basis_size_1 : basis_size_1_variable;
732 const unsigned int np_2 =
733 basis_size_1 > 0 ? basis_size_2 : basis_size_2_variable;
735 ExcMessage(
"Cannot transform with 0-point basis"));
737 ExcMessage(
"Cannot transform with 0-point basis"));
741 values_in = values_in +
n_components * Utilities::fixed_power<dim>(np_1);
743 values_out +
n_components * Utilities::fixed_power<dim>(np_2);
746 values_in -= Utilities::fixed_power<dim>(np_1);
747 values_out -= Utilities::fixed_power<dim>(np_2);
749 for (
unsigned int q = np_1; q != 0; --q)
760 Utilities::fixed_power<next_dim>(np_1),
763 Utilities::fixed_power<next_dim>(np_2),
764 basis_size_1_variable,
765 basis_size_2_variable);
770 if (basis_size_1 > 0 && basis_size_2 == basis_size_1 && dim == 2)
772 eval_val.template values<0, true, false>(values_in, values_out);
773 eval_val.template values<1, true, false>(values_out, values_out);
776 eval_val.template values<dim - 1,
true,
false>(values_in,
779 eval_val.template values<dim - 1,
true,
false>(values_out,
819 const bool add_into_result,
826 basis_size_1 != 0 || basis_size_1_variable <= basis_size_2_variable,
827 ExcMessage(
"The second dimension must not be smaller than the first"));
828 Assert(add_into_result ==
false || values_in != values_out,
830 "Input and output cannot alias with each other when "
831 "adding the result of the basis change to existing data"));
833 constexpr
int next_dim =
835 ((basis_size_1 == 0 || basis_size_2 > basis_size_1) && dim > 1)) ?
841 (basis_size_1 == 0 ? 0 : basis_size_2),
844 eval_val(transformation_matrix,
847 basis_size_1_variable,
848 basis_size_2_variable);
849 const unsigned int np_1 =
850 basis_size_1 > 0 ? basis_size_1 : basis_size_1_variable;
851 const unsigned int np_2 =
852 basis_size_1 > 0 ? basis_size_2 : basis_size_2_variable;
854 ExcMessage(
"Cannot transform with 0-point basis"));
856 ExcMessage(
"Cannot transform with 0-point basis"));
860 if (basis_size_1 > 0 && basis_size_2 == basis_size_1 && dim == 2)
862 eval_val.template values<1, false, false>(values_in, values_in);
864 eval_val.template values<0, false, true>(values_in, values_out);
866 eval_val.template values<0, false, false>(values_in,
871 if (dim == 1 && add_into_result)
872 eval_val.template values<0, false, true>(values_in, values_out);
874 eval_val.template values<0, false, false>(values_in,
877 eval_val.template values<dim - 1,
false,
false>(values_in,
881 for (
unsigned int q = 0; q < np_1; ++q)
892 q * Utilities::fixed_power<next_dim>(np_2),
894 q * Utilities::fixed_power<next_dim>(np_1),
895 basis_size_1_variable,
896 basis_size_2_variable);
898 values_in += Utilities::fixed_power<dim>(np_2);
899 values_out += Utilities::fixed_power<dim>(np_1);
925 const Number * values_in,
926 Number * scratch_data,
929 constexpr
int next_dim = dim > 1 ? dim - 1 : dim;
930 Number * my_scratch =
931 basis_size_1 != basis_size_2 ? scratch_data : values_out;
933 const unsigned int size_per_component =
Utilities::pow(basis_size_2, dim);
934 Assert(coefficients.
size() == size_per_component ||
937 const unsigned int stride =
938 coefficients.
size() == size_per_component ? 0 : 1;
940 for (
unsigned int q = basis_size_1; q != 0; --q)
961 eval_val(transformation_matrix);
962 const unsigned int n_inner_blocks =
963 (dim > 1 && basis_size_2 < 10) ? basis_size_2 : 1;
965 for (
unsigned int ii = 0; ii <
n_blocks; ii += n_inner_blocks)
968 for (
unsigned int i = ii; i < ii + n_inner_blocks; ++i)
969 eval_val.template values_one_line<dim - 1, true, false>(
970 my_scratch + i, my_scratch + i);
971 for (
unsigned int q = 0; q < basis_size_2; ++q)
972 for (
unsigned int i = ii; i < ii + n_inner_blocks; ++i)
973 my_scratch[i + q *
n_blocks + c * size_per_component] *=
975 c * stride * size_per_component];
976 for (
unsigned int i = ii; i < ii + n_inner_blocks; ++i)
977 eval_val.template values_one_line<dim - 1, false, false>(
978 my_scratch + i, my_scratch + i);
980 for (
unsigned int q = 0; q < basis_size_1; ++q)
1013 template <
int dim,
int fe_degree,
int n_components,
typename Number>
1018 const Number * values_dofs,
1019 Number * values_quad,
1020 Number * gradients_quad,
1021 Number * hessians_quad,
1022 Number * scratch_data,
1023 const bool evaluate_values,
1024 const bool evaluate_gradients,
1025 const bool evaluate_hessians);
1029 Number * values_dofs,
1030 Number * values_quad,
1031 Number * gradients_quad,
1032 Number * scratch_data,
1033 const bool integrate_values,
1034 const bool integrate_gradients,
1035 const bool add_into_values_array);
1040 template <
int dim,
int fe_degree,
int n_components,
typename Number>
1044 const Number * values_dofs,
1045 Number * values_quad,
1046 Number * gradients_quad,
1047 Number * hessians_quad,
1049 const bool evaluate_values,
1050 const bool evaluate_gradients,
1051 const bool evaluate_hessians)
1054 shape_info.
data.front().shape_gradients_collocation_eo.size(),
1055 (fe_degree + 2) / 2 * (fe_degree + 1));
1063 shape_info.
data.front().shape_gradients_collocation_eo,
1064 shape_info.
data.front().shape_hessians_collocation_eo);
1065 constexpr
unsigned int n_q_points =
Utilities::pow(fe_degree + 1, dim);
1069 if (evaluate_values ==
true)
1070 for (
unsigned int i = 0; i < n_q_points; ++i)
1071 values_quad[i] = values_dofs[i];
1072 if (evaluate_gradients ==
true || evaluate_hessians ==
true)
1074 eval.template gradients<0, true, false>(values_dofs,
1077 eval.template gradients<1, true, false>(values_dofs,
1081 eval.template gradients<2, true, false>(values_dofs,
1085 if (evaluate_hessians ==
true)
1087 eval.template hessians<0, true, false>(values_dofs, hessians_quad);
1090 eval.template gradients<1, true, false>(gradients_quad,
1093 eval.template hessians<1, true, false>(values_dofs,
1099 eval.template gradients<2, true, false>(gradients_quad,
1102 eval.template gradients<2, true, false>(
1103 gradients_quad + n_q_points, hessians_quad + 5 * n_q_points);
1104 eval.template hessians<2, true, false>(values_dofs,
1108 hessians_quad += (dim * (dim + 1)) / 2 * n_q_points;
1110 gradients_quad += dim * n_q_points;
1111 values_quad += n_q_points;
1112 values_dofs += n_q_points;
1118 template <
int dim,
int fe_degree,
int n_components,
typename Number>
1122 Number * values_dofs,
1123 Number * values_quad,
1124 Number * gradients_quad,
1126 const bool integrate_values,
1127 const bool integrate_gradients,
1128 const bool add_into_values_array)
1131 shape_info.
data.front().shape_gradients_collocation_eo.size(),
1132 (fe_degree + 2) / 2 * (fe_degree + 1));
1140 shape_info.
data.front().shape_gradients_collocation_eo,
1141 shape_info.
data.front().shape_hessians_collocation_eo);
1142 constexpr
unsigned int n_q_points =
Utilities::pow(fe_degree + 1, dim);
1146 if (integrate_values ==
true && add_into_values_array ==
false)
1147 for (
unsigned int i = 0; i < n_q_points; ++i)
1148 values_dofs[i] = values_quad[i];
1149 else if (integrate_values ==
true)
1150 for (
unsigned int i = 0; i < n_q_points; ++i)
1151 values_dofs[i] += values_quad[i];
1152 if (integrate_gradients ==
true)
1154 if (integrate_values ==
true || add_into_values_array ==
true)
1155 eval.template gradients<0, false, true>(gradients_quad,
1158 eval.template gradients<0, false, false>(gradients_quad,
1161 eval.template gradients<1, false, true>(gradients_quad +
1165 eval.template gradients<2, false, true>(gradients_quad +
1169 gradients_quad += dim * n_q_points;
1170 values_quad += n_q_points;
1171 values_dofs += n_q_points;
1198 const Number * values_dofs,
1199 Number * values_quad,
1200 Number * gradients_quad,
1201 Number * hessians_quad,
1202 Number * scratch_data,
1203 const bool evaluate_values,
1204 const bool evaluate_gradients,
1205 const bool evaluate_hessians);
1209 Number * values_dofs,
1210 Number * values_quad,
1211 Number * gradients_quad,
1212 Number * scratch_data,
1213 const bool integrate_values,
1214 const bool integrate_gradients,
1215 const bool add_into_values_array);
1232 const Number * values_dofs,
1233 Number * values_quad,
1234 Number *gradients_quad,
1235 Number *hessians_quad,
1238 const bool evaluate_gradients,
1239 const bool evaluate_hessians)
1241 Assert(n_q_points_1d > fe_degree,
1242 ExcMessage(
"You lose information when going to a collocation space "
1243 "of lower degree, so the evaluation results would be "
1244 "wrong. Thus, this class does not permit the desired "
1246 constexpr
unsigned int n_q_points =
Utilities::pow(n_q_points_1d, dim);
1253 (fe_degree >= n_q_points_1d ? n_q_points_1d : fe_degree + 1),
1257 Number>::do_forward(shape_info.
data.front().shape_values_eo,
1262 if (evaluate_gradients ==
true || evaluate_hessians ==
true)
1275 values_quad += n_q_points;
1276 gradients_quad += dim * n_q_points;
1277 hessians_quad += (dim * (dim + 1)) / 2 * n_q_points;
1295 Number *values_dofs,
1296 Number *values_quad,
1297 Number *gradients_quad,
1299 const bool integrate_values,
1300 const bool integrate_gradients,
1301 const bool add_into_values_array)
1303 Assert(n_q_points_1d > fe_degree,
1304 ExcMessage(
"You lose information when going to a collocation space "
1305 "of lower degree, so the evaluation results would be "
1306 "wrong. Thus, this class does not permit the desired "
1309 shape_info.
data.front().shape_gradients_collocation_eo.size(),
1310 (n_q_points_1d + 1) / 2 * n_q_points_1d);
1311 constexpr
unsigned int n_q_points =
Utilities::pow(n_q_points_1d, dim);
1316 if (integrate_gradients ==
true)
1324 integrate_gradients,
1331 (fe_degree >= n_q_points_1d ? n_q_points_1d : fe_degree + 1),
1335 Number>::do_backward(shape_info.
data.front().shape_values_eo,
1336 add_into_values_array,
1339 gradients_quad += dim * n_q_points;
1340 values_quad += n_q_points;
1347 template <
bool symmetric_evaluate,
1361 symmetric_evaluate &&
1362 n_q_points_1d > fe_degree &&n_q_points_1d <= 3 * fe_degree / 2 + 1 &&
1363 n_q_points_1d < 200;
1367 Number * values_dofs,
1368 Number * values_quad,
1369 Number * gradients_quad,
1370 Number * scratch_data,
1371 const bool evaluate_val,
1372 const bool evaluate_grad,
1373 const unsigned int subface_index)
1376 symmetric_evaluate ?
1377 data.
data.front().shape_values_eo :
1379 data.
data.front().shape_values :
1380 data.
data.front().values_within_subface[subface_index % 2]);
1382 symmetric_evaluate ?
1383 data.
data.front().shape_values_eo :
1385 data.
data.front().shape_values :
1386 data.
data.front().values_within_subface[subface_index / 2]);
1389 symmetric_evaluate ?
1390 data.
data.front().shape_gradients_eo :
1392 data.
data.front().shape_gradients :
1393 data.
data.front().gradients_within_subface[subface_index % 2]);
1395 symmetric_evaluate ?
1396 data.
data.front().shape_gradients_eo :
1398 data.
data.front().shape_gradients :
1399 data.
data.front().gradients_within_subface[subface_index / 2]);
1412 data.
data.front().fe_degree + 1,
1413 data.
data.front().n_q_points_1d);
1417 data.
data.front().fe_degree + 1,
1418 data.
data.front().n_q_points_1d);
1420 const unsigned int size_deg =
1427 const unsigned int n_q_points = fe_degree > -1 ?
1431 if (evaluate_grad ==
false)
1437 eval1.template values<0, true, false>(values_dofs,
1439 eval2.template values<1, true, false>(values_quad,
1443 eval1.template values<0, true, false>(values_dofs,
1447 values_quad[0] = values_dofs[0];
1452 values_dofs += 2 * size_deg;
1453 values_quad += n_q_points;
1463 eval1.template values<0, true, false>(values_dofs,
1465 eval1.template values<1, true, false>(values_quad,
1475 data.
data.front().shape_gradients_collocation_eo,
1477 eval_grad.template gradients<0, true, false>(
1478 values_quad, gradients_quad);
1479 eval_grad.template gradients<1, true, false>(
1480 values_quad, gradients_quad + n_q_points);
1484 eval1.template gradients<0, true, false>(values_dofs,
1486 eval2.template values<1, true, false>(scratch_data,
1489 eval1.template values<0, true, false>(values_dofs,
1491 eval2.template gradients<1, true, false>(scratch_data,
1495 if (evaluate_val ==
true)
1496 eval2.template values<1, true, false>(scratch_data,
1499 eval1.template values<0, true, false>(values_dofs + size_deg,
1501 eval2.template values<1, true, false>(
1502 scratch_data, gradients_quad + (dim - 1) * n_q_points);
1506 eval1.template values<0, true, false>(values_dofs + size_deg,
1510 eval1.template gradients<0, true, false>(values_dofs,
1512 if (evaluate_val ==
true)
1513 eval1.template values<0, true, false>(values_dofs,
1517 values_quad[0] = values_dofs[0];
1518 gradients_quad[0] = values_dofs[1];
1523 values_dofs += 2 * size_deg;
1524 values_quad += n_q_points;
1525 gradients_quad += dim * n_q_points;
1531 Number * values_dofs,
1532 Number * values_quad,
1533 Number * gradients_quad,
1534 Number * scratch_data,
1535 const bool integrate_val,
1536 const bool integrate_grad,
1537 const unsigned int subface_index)
1540 symmetric_evaluate ?
1541 data.
data.front().shape_values_eo :
1543 data.
data.front().shape_values :
1544 data.
data.front().values_within_subface[subface_index % 2]);
1546 symmetric_evaluate ?
1547 data.
data.front().shape_values_eo :
1549 data.
data.front().shape_values :
1550 data.
data.front().values_within_subface[subface_index / 2]);
1553 symmetric_evaluate ?
1554 data.
data.front().shape_gradients_eo :
1556 data.
data.front().shape_gradients :
1557 data.
data.front().gradients_within_subface[subface_index % 2]);
1559 symmetric_evaluate ?
1560 data.
data.front().shape_gradients_eo :
1562 data.
data.front().shape_gradients :
1563 data.
data.front().gradients_within_subface[subface_index / 2]);
1576 data.
data.front().fe_degree + 1,
1577 data.
data.front().n_q_points_1d);
1581 data.
data.front().fe_degree + 1,
1582 data.
data.front().n_q_points_1d);
1584 const unsigned int size_deg =
1591 const unsigned int n_q_points = fe_degree > -1 ?
1595 if (integrate_grad ==
false)
1601 eval2.template values<1, false, false>(values_quad,
1603 eval1.template values<0, false, false>(values_quad,
1607 eval1.template values<0, false, false>(values_quad,
1611 values_dofs[0] = values_quad[0];
1616 values_dofs += 2 * size_deg;
1617 values_quad += n_q_points;
1625 eval2.template values<1, false, false>(gradients_quad +
1629 eval1.template values<0, false, false>(
1630 gradients_quad + 2 * n_q_points, values_dofs + size_deg);
1641 data.
data.front().shape_gradients_collocation_eo,
1644 eval_grad.template gradients<1, false, true>(
1645 gradients_quad + n_q_points, values_quad);
1647 eval_grad.template gradients<1, false, false>(
1648 gradients_quad + n_q_points, values_quad);
1649 eval_grad.template gradients<0, false, true>(
1650 gradients_quad, values_quad);
1651 eval1.template values<1, false, false>(values_quad,
1653 eval1.template values<0, false, false>(values_quad,
1660 eval2.template values<1, false, false>(values_quad,
1662 eval2.template gradients<1, false, true>(
1663 gradients_quad + n_q_points, scratch_data);
1666 eval2.template gradients<1, false, false>(
1667 gradients_quad + n_q_points, scratch_data);
1669 eval1.template values<0, false, false>(scratch_data,
1671 eval2.template values<1, false, false>(gradients_quad,
1673 eval1.template gradients<0, false, true>(scratch_data,
1678 eval1.template values<0, false, false>(
1679 gradients_quad + n_q_points, values_dofs + size_deg);
1680 eval1.template gradients<0, false, false>(gradients_quad,
1682 if (integrate_val ==
true)
1683 eval1.template values<0, false, true>(values_quad,
1687 values_dofs[0] = values_quad[0];
1688 values_dofs[1] = gradients_quad[0];
1693 values_dofs += 2 * size_deg;
1694 values_quad += n_q_points;
1695 gradients_quad += dim * n_q_points;
1702 template <
int dim,
int fe_degree,
int n_components,
typename Number>
1705 template <
bool do_evaluate,
bool add_
into_output>
1708 const Number * input,
1710 const bool do_gradients,
1711 const unsigned int face_no)
1718 evalf(data.
data.front().shape_data_on_face[face_no % 2],
1721 data.
data.front().fe_degree + 1,
1724 const unsigned int in_stride = do_evaluate ?
1727 const unsigned int out_stride = do_evaluate ?
1730 const unsigned int face_direction = face_no / 2;
1735 if (face_direction == 0)
1736 evalf.template apply_face<0, do_evaluate, add_into_output, 1>(
1738 else if (face_direction == 1)
1739 evalf.template apply_face<1, do_evaluate, add_into_output, 1>(
1742 evalf.template apply_face<2, do_evaluate, add_into_output, 1>(
1747 if (face_direction == 0)
1748 evalf.template apply_face<0, do_evaluate, add_into_output, 0>(
1750 else if (face_direction == 1)
1751 evalf.template apply_face<1, do_evaluate, add_into_output, 0>(
1754 evalf.template apply_face<2, do_evaluate, add_into_output, 0>(
1758 output += out_stride;
1766 template <
typename VectorizedArrayType,
typename Number2>
1770 for (
unsigned int v = 0; v < VectorizedArrayType::size(); ++v)
1771 dst[v] = src_ptr[v];
1778 template <
typename Number,
unsigned int w
idth>
1788 template <
typename VectorizedArrayType,
typename Number2>
1791 const unsigned int * indices,
1792 VectorizedArrayType &dst)
1794 for (
unsigned int v = 0; v < VectorizedArrayType::size(); ++v)
1795 dst[v] = src_ptr[indices[v]];
1802 template <
typename Number,
unsigned int w
idth>
1805 const unsigned int * indices,
1808 dst.
gather(src_ptr, indices);
1814 template <
typename VectorizedArrayType,
typename Number2>
1818 for (
unsigned int v = 0; v < VectorizedArrayType::size(); ++v)
1819 dst_ptr[v] += src[v];
1826 template <
typename Number,
unsigned int w
idth>
1832 (tmp + src).store(dst_ptr);
1838 template <
typename VectorizedArrayType,
typename Number2>
1841 const unsigned int * indices,
1844 for (
unsigned int v = 0; v < VectorizedArrayType::size(); ++v)
1845 dst_ptr[indices[v]] += src[v];
1852 template <
typename Number,
unsigned int w
idth>
1855 const unsigned int * indices,
1858 #if DEAL_II_VECTORIZATION_WIDTH_IN_BITS < 512
1859 for (
unsigned int v = 0; v < width; ++v)
1860 dst_ptr[indices[v]] += src[v];
1863 tmp.
gather(dst_ptr, indices);
1864 (tmp + src).scatter(indices, dst_ptr);
1875 typename VectorizedArrayType,
1876 typename Number2 = Number>
1881 const VectorizedArrayType * values_array,
1882 VectorizedArrayType * values_quad,
1883 VectorizedArrayType * gradients_quad,
1884 VectorizedArrayType * scratch_data,
1885 const bool evaluate_values,
1886 const bool evaluate_gradients,
1887 const unsigned int face_no,
1888 const unsigned int subface_index,
1889 const unsigned int face_orientation,
1892 constexpr
unsigned int static_dofs_per_face =
1895 const unsigned int dofs_per_face =
1897 static_dofs_per_face :
1906 constexpr
unsigned int stack_array_size_threshold = 100;
1909 temp_data[static_dofs_per_face < stack_array_size_threshold ?
1912 VectorizedArrayType *temp1;
1913 if (static_dofs_per_face < stack_array_size_threshold)
1914 temp1 = &temp_data[0];
1916 temp1 = scratch_data;
1921 VectorizedArrayType>::
1922 template interpolate<true, false>(
1923 data, values_array, temp1, evaluate_gradients, face_no);
1925 const unsigned int n_q_points_1d_actual =
1926 fe_degree > -1 ? n_q_points_1d : 0;
1927 if (fe_degree > -1 &&
1934 n_q_points_1d_actual,
1936 VectorizedArrayType>::evaluate_in_face(data,
1951 n_q_points_1d_actual,
1953 VectorizedArrayType>::evaluate_in_face(data,
1964 if (face_orientation)
1978 VectorizedArrayType * values_array,
1979 VectorizedArrayType * values_quad,
1980 VectorizedArrayType * gradients_quad,
1981 VectorizedArrayType * scratch_data,
1982 const bool integrate_values,
1983 const bool integrate_gradients,
1984 const unsigned int face_no,
1985 const unsigned int subface_index,
1986 const unsigned int face_orientation,
1989 if (face_orientation)
1994 integrate_gradients,
2000 constexpr
unsigned int static_dofs_per_face =
2003 const unsigned int dofs_per_face =
2005 static_dofs_per_face :
2008 constexpr
unsigned int stack_array_size_threshold = 100;
2011 temp_data[static_dofs_per_face < stack_array_size_threshold ?
2014 VectorizedArrayType *temp1;
2015 if (static_dofs_per_face < stack_array_size_threshold)
2016 temp1 = &temp_data[0];
2018 temp1 = scratch_data;
2020 const unsigned int n_q_points_1d_actual =
2021 fe_degree > -1 ? n_q_points_1d : 0;
2022 if (fe_degree > -1 &&
2029 n_q_points_1d_actual,
2031 VectorizedArrayType>::integrate_in_face(data,
2039 integrate_gradients,
2046 n_q_points_1d_actual,
2048 VectorizedArrayType>::integrate_in_face(data,
2056 integrate_gradients,
2062 VectorizedArrayType>::
2063 template interpolate<false, false>(
2064 data, temp1, values_array, integrate_gradients, face_no);
2069 const Number2 * src_ptr,
2072 VectorizedArrayType * values_quad,
2073 VectorizedArrayType * gradients_quad,
2074 VectorizedArrayType * scratch_data,
2075 const bool evaluate_values,
2076 const bool evaluate_gradients,
2077 const unsigned int active_fe_index,
2078 const unsigned int first_selected_component,
2079 const unsigned int cell,
2080 const unsigned int face_no,
2081 const unsigned int subface_index,
2083 const unsigned int face_orientation,
2086 const unsigned int side = face_no % 2;
2088 constexpr
unsigned int static_dofs_per_component =
2091 constexpr
unsigned int static_dofs_per_face =
2094 const unsigned int dofs_per_face =
2096 static_dofs_per_face :
2099 constexpr
unsigned int stack_array_size_threshold = 100;
2102 temp_data[static_dofs_per_face < stack_array_size_threshold ?
2105 VectorizedArrayType *__restrict temp1;
2106 if (static_dofs_per_face < stack_array_size_threshold)
2107 temp1 = &temp_data[0];
2109 temp1 = scratch_data;
2112 if (((evaluate_gradients ==
false &&
2113 data.
data.front().nodal_at_cell_boundaries ==
true) ||
2119 interleaved_contiguous)
2123 VectorizedArrayType::size());
2124 const unsigned int dof_index =
2127 [cell * VectorizedArrayType::size()] +
2129 [first_selected_component] *
2130 VectorizedArrayType::size();
2132 if (fe_degree > 1 && evaluate_gradients ==
true)
2137 const VectorizedArrayType grad_weight =
2138 data.
data.front().shape_data_on_face[0][fe_degree + 1 + side];
2141 const unsigned int *index_array =
2143 for (
unsigned int i = 0; i < dofs_per_face; ++i)
2145 const unsigned int ind1 = index_array[2 * i];
2146 const unsigned int ind2 = index_array[2 * i + 1];
2149 for (
unsigned int comp = 0; comp <
n_components; ++comp)
2153 comp * static_dofs_per_component) *
2154 VectorizedArrayType::size(),
2155 temp1[i + 2 * comp * dofs_per_face]);
2157 src_ptr + dof_index +
2158 (ind2 + comp * static_dofs_per_component) *
2159 VectorizedArrayType::size(),
2160 temp1[dofs_per_face + i + 2 * comp * dofs_per_face]);
2161 temp1[i + dofs_per_face + 2 * comp * dofs_per_face] =
2163 (temp1[i + 2 * comp * dofs_per_face] -
2164 temp1[i + dofs_per_face + 2 * comp * dofs_per_face]);
2172 const unsigned int *index_array =
2174 for (
unsigned int i = 0; i < dofs_per_face; ++i)
2176 const unsigned int ind = index_array[i];
2177 for (
unsigned int comp = 0; comp <
n_components; ++comp)
2180 comp * static_dofs_per_component) *
2181 VectorizedArrayType::size(),
2182 temp1[i + 2 * comp * dofs_per_face]);
2188 else if (((evaluate_gradients ==
false &&
2189 data.
data.front().nodal_at_cell_boundaries ==
true) ||
2195 interleaved_contiguous_strided)
2199 VectorizedArrayType::size());
2200 const unsigned int *indices =
2203 [cell * VectorizedArrayType::size()];
2204 if (fe_degree > 1 && evaluate_gradients ==
true)
2209 const VectorizedArrayType grad_weight =
2210 data.
data.front().shape_data_on_face[0][fe_degree + 1 + side];
2214 const unsigned int *index_array =
2216 for (
unsigned int i = 0; i < dofs_per_face; ++i)
2218 const unsigned int ind1 =
2219 index_array[2 * i] * VectorizedArrayType::size();
2220 const unsigned int ind2 =
2221 index_array[2 * i + 1] * VectorizedArrayType::size();
2222 for (
unsigned int comp = 0; comp <
n_components; ++comp)
2226 comp * static_dofs_per_component *
2227 VectorizedArrayType::size() +
2229 [active_fe_index][first_selected_component] *
2230 VectorizedArrayType::size(),
2232 temp1[i + 2 * comp * dofs_per_face]);
2233 VectorizedArrayType grad;
2236 comp * static_dofs_per_component *
2237 VectorizedArrayType::size() +
2239 [active_fe_index][first_selected_component] *
2240 VectorizedArrayType::size(),
2243 temp1[i + dofs_per_face + 2 * comp * dofs_per_face] =
2245 (temp1[i + 2 * comp * dofs_per_face] - grad);
2253 const unsigned int *index_array =
2255 for (
unsigned int i = 0; i < dofs_per_face; ++i)
2257 const unsigned int ind =
2258 index_array[i] * VectorizedArrayType::size();
2259 for (
unsigned int comp = 0; comp <
n_components; ++comp)
2262 comp * static_dofs_per_component *
2263 VectorizedArrayType::size() +
2265 [active_fe_index][first_selected_component] *
2266 VectorizedArrayType::size(),
2268 temp1[i + 2 * comp * dofs_per_face]);
2274 else if (((evaluate_gradients ==
false &&
2275 data.
data.front().nodal_at_cell_boundaries ==
true) ||
2281 interleaved_contiguous_mixed_strides)
2283 const unsigned int *strides =
2285 [dof_access_index][cell * VectorizedArrayType::size()];
2286 unsigned int indices[VectorizedArrayType::size()];
2287 for (
unsigned int v = 0; v < VectorizedArrayType::size(); ++v)
2290 [dof_access_index][cell * VectorizedArrayType::size() + v] +
2292 [first_selected_component] *
2294 const unsigned int nvec =
2297 if (fe_degree > 1 && evaluate_gradients ==
true)
2302 const VectorizedArrayType grad_weight =
2303 data.
data.front().shape_data_on_face[0][fe_degree + 1 + side];
2307 const unsigned int *index_array =
2309 if (nvec == VectorizedArrayType::size())
2310 for (
unsigned int comp = 0; comp <
n_components; ++comp)
2311 for (
unsigned int i = 0; i < dofs_per_face; ++i)
2313 unsigned int ind1[VectorizedArrayType::size()];
2315 for (
unsigned int v = 0; v < VectorizedArrayType::size();
2318 indices[v] + (comp * static_dofs_per_component +
2319 index_array[2 * i]) *
2321 unsigned int ind2[VectorizedArrayType::size()];
2323 for (
unsigned int v = 0; v < VectorizedArrayType::size();
2326 indices[v] + (comp * static_dofs_per_component +
2327 index_array[2 * i + 1]) *
2331 temp1[i + 2 * comp * dofs_per_face]);
2332 VectorizedArrayType grad;
2334 temp1[i + dofs_per_face + 2 * comp * dofs_per_face] =
2336 (temp1[i + 2 * comp * dofs_per_face] - grad);
2340 for (
unsigned int i = 0; i <
n_components * 2 * dofs_per_face;
2342 temp1[i] = VectorizedArrayType();
2343 for (
unsigned int v = 0; v < nvec; ++v)
2344 for (
unsigned int comp = 0; comp <
n_components; ++comp)
2345 for (
unsigned int i = 0; i < dofs_per_face; ++i)
2347 const unsigned int ind1 =
2348 indices[v] + (comp * static_dofs_per_component +
2349 index_array[2 * i]) *
2351 const unsigned int ind2 =
2352 indices[v] + (comp * static_dofs_per_component +
2353 index_array[2 * i + 1]) *
2355 temp1[i + 2 * comp * dofs_per_face][v] =
2357 const Number grad = src_ptr[ind2];
2358 temp1[i + dofs_per_face +
2359 2 * comp * dofs_per_face][v] =
2361 (temp1[i + 2 * comp * dofs_per_face][v] - grad);
2369 const unsigned int *index_array =
2371 if (nvec == VectorizedArrayType::size())
2372 for (
unsigned int comp = 0; comp <
n_components; ++comp)
2373 for (
unsigned int i = 0; i < dofs_per_face; ++i)
2375 unsigned int ind[VectorizedArrayType::size()];
2377 for (
unsigned int v = 0; v < VectorizedArrayType::size();
2381 (comp * static_dofs_per_component + index_array[i]) *
2385 temp1[i + 2 * comp * dofs_per_face]);
2389 for (
unsigned int i = 0; i <
n_components * dofs_per_face;
2391 temp1[i] = VectorizedArrayType();
2392 for (
unsigned int v = 0; v < nvec; ++v)
2393 for (
unsigned int comp = 0; comp <
n_components; ++comp)
2394 for (
unsigned int i = 0; i < dofs_per_face; ++i)
2396 const unsigned int ind1 =
2397 indices[v] + (comp * static_dofs_per_component +
2400 temp1[i + 2 * comp * dofs_per_face][v] =
2408 else if (((evaluate_gradients ==
false &&
2409 data.
data.front().nodal_at_cell_boundaries ==
true) ||
2414 MatrixFreeFunctions::DoFInfo::IndexStorageVariants::
2417 VectorizedArrayType::size())
2419 const unsigned int *indices =
2422 [cell * VectorizedArrayType::size()];
2423 if (evaluate_gradients ==
true &&
2430 const VectorizedArrayType grad_weight =
2431 data.
data.front().shape_data_on_face[0][fe_degree + 1 + side];
2435 const unsigned int *index_array =
2437 for (
unsigned int i = 0; i < dofs_per_face; ++i)
2439 const unsigned int ind1 = index_array[2 * i];
2440 const unsigned int ind2 = index_array[2 * i + 1];
2441 for (
unsigned int comp = 0; comp <
n_components; ++comp)
2444 src_ptr + ind1 + comp * static_dofs_per_component +
2446 [active_fe_index][first_selected_component],
2448 temp1[i + 2 * comp * dofs_per_face]);
2449 VectorizedArrayType grad;
2451 src_ptr + ind2 + comp * static_dofs_per_component +
2453 [active_fe_index][first_selected_component],
2456 temp1[i + dofs_per_face + 2 * comp * dofs_per_face] =
2458 (temp1[i + 2 * comp * dofs_per_face] - grad);
2466 const unsigned int *index_array =
2468 for (
unsigned int i = 0; i < dofs_per_face; ++i)
2469 for (
unsigned int comp = 0; comp <
n_components; ++comp)
2471 const unsigned int ind = index_array[i];
2473 src_ptr + ind + comp * static_dofs_per_component +
2475 [active_fe_index][first_selected_component],
2477 temp1[i + comp * 2 * dofs_per_face]);
2488 if (fe_degree > -1 &&
2497 VectorizedArrayType>::evaluate_in_face(data,
2514 VectorizedArrayType>::evaluate_in_face(data,
2525 if (face_orientation)
2544 VectorizedArrayType * values_array,
2545 VectorizedArrayType * values_quad,
2546 VectorizedArrayType * gradients_quad,
2547 VectorizedArrayType * scratch_data,
2548 const bool integrate_values,
2549 const bool integrate_gradients,
2550 const unsigned int active_fe_index,
2551 const unsigned int first_selected_component,
2552 const unsigned int cell,
2553 const unsigned int face_no,
2554 const unsigned int subface_index,
2556 const unsigned int face_orientation,
2559 if (face_orientation)
2564 integrate_gradients,
2570 const unsigned int side = face_no % 2;
2571 constexpr
unsigned int static_dofs_per_component =
2574 const unsigned int dofs_per_face =
2579 constexpr
unsigned int stack_array_size_threshold = 100;
2581 VectorizedArrayType temp_data[dofs_per_face < stack_array_size_threshold ?
2584 VectorizedArrayType *__restrict temp1;
2585 if (dofs_per_face < stack_array_size_threshold)
2586 temp1 = &temp_data[0];
2588 temp1 = scratch_data;
2590 if (fe_degree > -1 &&
2599 VectorizedArrayType>::integrate_in_face(data,
2607 integrate_gradients,
2616 VectorizedArrayType>::integrate_in_face(data,
2624 integrate_gradients,
2628 if (((integrate_gradients ==
false &&
2629 data.
data.front().nodal_at_cell_boundaries ==
true) ||
2635 interleaved_contiguous)
2639 VectorizedArrayType::size());
2640 const unsigned int dof_index =
2643 [cell * VectorizedArrayType::size()] +
2645 [first_selected_component] *
2646 VectorizedArrayType::size();
2648 if (fe_degree > 1 && integrate_gradients ==
true)
2653 const VectorizedArrayType grad_weight =
2654 data.
data.front().shape_data_on_face[0][fe_degree + 2 - side];
2657 const unsigned int *index_array =
2659 for (
unsigned int i = 0; i < dofs_per_face; ++i)
2661 const unsigned int ind1 = index_array[2 * i];
2662 const unsigned int ind2 = index_array[2 * i + 1];
2665 for (
unsigned int comp = 0; comp <
n_components; ++comp)
2667 VectorizedArrayType val =
2668 temp1[i + 2 * comp * dofs_per_face] -
2670 temp1[i + dofs_per_face + 2 * comp * dofs_per_face];
2671 VectorizedArrayType grad =
2673 temp1[i + dofs_per_face + 2 * comp * dofs_per_face];
2675 dst_ptr + dof_index +
2677 comp * static_dofs_per_component) *
2678 VectorizedArrayType::size());
2680 dst_ptr + dof_index +
2682 comp * static_dofs_per_component) *
2683 VectorizedArrayType::size());
2691 const unsigned int *index_array =
2693 for (
unsigned int i = 0; i < dofs_per_face; ++i)
2695 const unsigned int ind = index_array[i];
2696 for (
unsigned int comp = 0; comp <
n_components; ++comp)
2698 dst_ptr + dof_index +
2700 comp * static_dofs_per_component) *
2701 VectorizedArrayType::size());
2707 else if (((integrate_gradients ==
false &&
2708 data.
data.front().nodal_at_cell_boundaries ==
true) ||
2714 interleaved_contiguous_strided)
2718 VectorizedArrayType::size());
2719 const unsigned int *indices =
2722 [cell * VectorizedArrayType::size()];
2723 if (fe_degree > 1 && integrate_gradients ==
true)
2728 const VectorizedArrayType grad_weight =
2729 data.
data.front().shape_data_on_face[0][fe_degree + 2 - side];
2733 const unsigned int *index_array =
2735 for (
unsigned int i = 0; i < dofs_per_face; ++i)
2737 const unsigned int ind1 =
2738 index_array[2 * i] * VectorizedArrayType::size();
2739 const unsigned int ind2 =
2740 index_array[2 * i + 1] * VectorizedArrayType::size();
2741 for (
unsigned int comp = 0; comp <
n_components; ++comp)
2743 VectorizedArrayType val =
2744 temp1[i + 2 * comp * dofs_per_face] -
2746 temp1[i + dofs_per_face + 2 * comp * dofs_per_face];
2747 VectorizedArrayType grad =
2749 temp1[i + dofs_per_face + 2 * comp * dofs_per_face];
2754 comp * static_dofs_per_component *
2755 VectorizedArrayType::size() +
2757 [active_fe_index][first_selected_component] *
2758 VectorizedArrayType::size());
2763 comp * static_dofs_per_component *
2764 VectorizedArrayType::size() +
2766 [active_fe_index][first_selected_component] *
2767 VectorizedArrayType::size());
2775 const unsigned int *index_array =
2777 for (
unsigned int i = 0; i < dofs_per_face; ++i)
2779 const unsigned int ind =
2780 index_array[i] * VectorizedArrayType::size();
2781 for (
unsigned int comp = 0; comp <
n_components; ++comp)
2783 temp1[i + 2 * comp * dofs_per_face],
2786 comp * static_dofs_per_component *
2787 VectorizedArrayType::size() +
2789 [active_fe_index][first_selected_component] *
2790 VectorizedArrayType::size());
2796 else if (((integrate_gradients ==
false &&
2797 data.
data.front().nodal_at_cell_boundaries ==
true) ||
2803 interleaved_contiguous_mixed_strides)
2805 const unsigned int *strides =
2807 [dof_access_index][cell * VectorizedArrayType::size()];
2808 unsigned int indices[VectorizedArrayType::size()];
2809 for (
unsigned int v = 0; v < VectorizedArrayType::size(); ++v)
2812 [dof_access_index][cell * VectorizedArrayType::size() + v] +
2814 [first_selected_component] *
2816 const unsigned int n_filled_lanes =
2819 if (fe_degree > 1 && integrate_gradients ==
true)
2824 const VectorizedArrayType grad_weight =
2825 data.
data.front().shape_data_on_face[0][fe_degree + 2 - side];
2829 const unsigned int *index_array =
2831 if (n_filled_lanes == VectorizedArrayType::size())
2832 for (
unsigned int comp = 0; comp <
n_components; ++comp)
2833 for (
unsigned int i = 0; i < dofs_per_face; ++i)
2835 unsigned int ind1[VectorizedArrayType::size()];
2837 for (
unsigned int v = 0; v < VectorizedArrayType::size();
2840 indices[v] + (comp * static_dofs_per_component +
2841 index_array[2 * i]) *
2843 unsigned int ind2[VectorizedArrayType::size()];
2845 for (
unsigned int v = 0; v < VectorizedArrayType::size();
2848 indices[v] + (comp * static_dofs_per_component +
2849 index_array[2 * i + 1]) *
2851 VectorizedArrayType val =
2852 temp1[i + 2 * comp * dofs_per_face] -
2854 temp1[i + dofs_per_face + 2 * comp * dofs_per_face];
2855 VectorizedArrayType grad =
2857 temp1[i + dofs_per_face + 2 * comp * dofs_per_face];
2863 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
2864 for (
unsigned int comp = 0; comp <
n_components; ++comp)
2865 for (
unsigned int i = 0; i < dofs_per_face; ++i)
2867 const unsigned int ind1 =
2868 indices[v] + (comp * static_dofs_per_component +
2869 index_array[2 * i]) *
2871 const unsigned int ind2 =
2872 indices[v] + (comp * static_dofs_per_component +
2873 index_array[2 * i + 1]) *
2876 temp1[i + 2 * comp * dofs_per_face][v] -
2877 grad_weight[0] * temp1[i + dofs_per_face +
2878 2 * comp * dofs_per_face][v];
2880 grad_weight[0] * temp1[i + dofs_per_face +
2881 2 * comp * dofs_per_face][v];
2882 dst_ptr[ind1] += val;
2883 dst_ptr[ind2] += grad;
2891 const unsigned int *index_array =
2893 if (n_filled_lanes == VectorizedArrayType::size())
2894 for (
unsigned int comp = 0; comp <
n_components; ++comp)
2895 for (
unsigned int i = 0; i < dofs_per_face; ++i)
2897 unsigned int ind[VectorizedArrayType::size()];
2899 for (
unsigned int v = 0; v < VectorizedArrayType::size();
2903 (comp * static_dofs_per_component + index_array[i]) *
2906 temp1[i + 2 * comp * dofs_per_face], ind, dst_ptr);
2910 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
2911 for (
unsigned int comp = 0; comp <
n_components; ++comp)
2912 for (
unsigned int i = 0; i < dofs_per_face; ++i)
2914 const unsigned int ind1 =
2915 indices[v] + (comp * static_dofs_per_component +
2919 temp1[i + 2 * comp * dofs_per_face][v];
2926 else if (((integrate_gradients ==
false &&
2927 data.
data.front().nodal_at_cell_boundaries ==
true) ||
2932 internal::MatrixFreeFunctions::DoFInfo::IndexStorageVariants::
2935 VectorizedArrayType::size())
2937 const unsigned int *indices =
2940 [cell * VectorizedArrayType::size()];
2942 if (integrate_gradients ==
true &&
2949 const VectorizedArrayType grad_weight =
2950 data.
data.front().shape_data_on_face[0][fe_degree + 2 - side];
2953 const unsigned int *index_array =
2955 for (
unsigned int i = 0; i < dofs_per_face; ++i)
2957 const unsigned int ind1 = index_array[2 * i];
2958 const unsigned int ind2 = index_array[2 * i + 1];
2959 for (
unsigned int comp = 0; comp <
n_components; ++comp)
2961 VectorizedArrayType val =
2962 temp1[i + 2 * comp * dofs_per_face] -
2964 temp1[i + dofs_per_face + 2 * comp * dofs_per_face];
2965 VectorizedArrayType grad =
2967 temp1[i + dofs_per_face + 2 * comp * dofs_per_face];
2971 dst_ptr + comp * static_dofs_per_component + ind1 +
2973 [active_fe_index][first_selected_component]);
2977 dst_ptr + comp * static_dofs_per_component + ind2 +
2979 [active_fe_index][first_selected_component]);
2987 const unsigned int *index_array =
2989 for (
unsigned int i = 0; i < dofs_per_face; ++i)
2991 const unsigned int ind = index_array[i];
2992 for (
unsigned int comp = 0; comp <
n_components; ++comp)
2994 temp1[i + 2 * comp * dofs_per_face],
2996 dst_ptr + comp * static_dofs_per_component + ind +
2998 [active_fe_index][first_selected_component]);
3010 VectorizedArrayType>::
3011 template interpolate<false, false>(
3012 data, temp1, values_array, integrate_gradients, face_no);
3024 const bool gradients,
3025 const unsigned int n_q_points,
3026 VectorizedArrayType * tmp_values,
3027 VectorizedArrayType * values_quad,
3028 VectorizedArrayType * gradients_quad)
3031 const unsigned int *orientation = &orientation_map[face_orientation][0];
3037 for (
unsigned int q = 0; q < n_q_points; ++q)
3038 tmp_values[q] = values_quad[c * n_q_points + orientation[q]];
3040 for (
unsigned int q = 0; q < n_q_points; ++q)
3041 tmp_values[orientation[q]] = values_quad[c * n_q_points + q];
3042 for (
unsigned int q = 0; q < n_q_points; ++q)
3043 values_quad[c * n_q_points + q] = tmp_values[q];
3045 if (gradients ==
true)
3046 for (
unsigned int d = 0;
d < dim; ++
d)
3049 for (
unsigned int q = 0; q < n_q_points; ++q)
3050 tmp_values[q] = gradients_quad[(c * dim +
d) * n_q_points +
3053 for (
unsigned int q = 0; q < n_q_points; ++q)
3054 tmp_values[orientation[q]] =
3055 gradients_quad[(c * dim +
d) * n_q_points + q];
3056 for (
unsigned int q = 0; q < n_q_points; ++q)
3057 gradients_quad[(c * dim +
d) * n_q_points + q] =
3069 template <
int dim,
int fe_degree,
int n_components,
typename Number>
3072 template <
typename FEEvaluationType>
3075 const Number * in_array,
3078 constexpr
unsigned int dofs_per_component =
3082 Assert(fe_eval.get_shape_info().element_type <=
3094 fe_eval.get_shape_info().
data.front().inverse_shape_values_eo);
3098 const Number *in = in_array +
d * dofs_per_component;
3099 Number * out = out_array +
d * dofs_per_component;
3102 evaluator.template hessians<0, true, false>(in, out);
3104 evaluator.template hessians<1, true, false>(out, out);
3106 evaluator.template hessians<2, true, false>(out, out);
3108 for (
unsigned int q = 0; q < dofs_per_component; ++q)
3110 const Number inverse_JxW_q = Number(1.) / fe_eval.JxW(q);
3112 out_array[q +
d * dofs_per_component] *= inverse_JxW_q;
3116 Number *out = out_array +
d * dofs_per_component;
3118 evaluator.template hessians<2, false, false>(out, out);
3120 evaluator.template hessians<1, false, false>(out, out);
3121 evaluator.template hessians<0, false, false>(out, out);
3128 const unsigned int n_desired_components,
3129 const Number * in_array,
3132 constexpr
unsigned int dofs_per_component =
3135 inverse_coefficients.
size() % dofs_per_component == 0,
3137 "Expected diagonal to be a multiple of scalar dof per cells"));
3138 if (inverse_coefficients.
size() != dofs_per_component)
3140 inverse_coefficients.
size());
3153 const unsigned int shift_coefficient =
3154 inverse_coefficients.
size() > dofs_per_component ? dofs_per_component :
3156 const Number *inv_coefficient = inverse_coefficients.
data();
3157 for (
unsigned int d = 0;
d < n_desired_components; ++
d)
3159 const Number *in = in_array +
d * dofs_per_component;
3160 Number * out = out_array +
d * dofs_per_component;
3163 evaluator.template hessians<0, true, false>(in, out);
3165 evaluator.template hessians<1, true, false>(out, out);
3167 evaluator.template hessians<2, true, false>(out, out);
3169 for (
unsigned int q = 0; q < dofs_per_component; ++q)
3170 out[q] *= inv_coefficient[q];
3173 evaluator.template hessians<2, false, false>(out, out);
3175 evaluator.template hessians<1, false, false>(out, out);
3176 evaluator.template hessians<0, false, false>(out, out);
3178 inv_coefficient += shift_coefficient;
3184 const unsigned int n_desired_components,
3185 const Number * in_array,
3188 constexpr
unsigned int dofs_per_cell =
Utilities::pow(fe_degree + 1, dim);
3198 for (
unsigned int d = 0;
d < n_desired_components; ++
d)
3200 const Number *in = in_array +
d * dofs_per_cell;
3201 Number * out = out_array +
d * dofs_per_cell;
3205 evaluator.template hessians<2, false, false>(in, out);
3206 evaluator.template hessians<1, false, false>(out, out);
3207 evaluator.template hessians<0, false, false>(out, out);
3211 evaluator.template hessians<1, false, false>(in, out);
3212 evaluator.template hessians<0, false, false>(out, out);
3215 evaluator.template hessians<0, false, false>(in, out);