17 #ifndef dealii_matrix_free_evaluation_kernels_h 18 #define dealii_matrix_free_evaluation_kernels_h 20 #include <deal.II/base/config.h> 22 #include <deal.II/base/utilities.h> 23 #include <deal.II/base/vectorization.h> 25 #include <deal.II/matrix_free/shape_info.h> 26 #include <deal.II/matrix_free/tensor_product_kernels.h> 29 DEAL_II_NAMESPACE_OPEN
36 template <MatrixFreeFunctions::ElementType element,
bool is_
long>
37 struct EvaluatorSelector
40 template <
bool is_
long>
41 struct EvaluatorSelector<MatrixFreeFunctions::
tensor_general, is_long>
58 template <
bool is_
long>
77 template <
bool is_
long>
114 const Number * values_dofs_actual,
115 Number * values_quad,
116 Number * gradients_quad,
117 Number * hessians_quad,
118 Number * scratch_data,
119 const bool evaluate_values,
120 const bool evaluate_gradients,
121 const bool evaluate_hessians);
125 Number * values_dofs_actual,
126 Number * values_quad,
127 Number * gradients_quad,
128 Number * scratch_data,
129 const bool integrate_values,
130 const bool integrate_gradients,
131 const bool add_into_values_array);
145 const Number * values_dofs_actual,
146 Number * values_quad,
147 Number * gradients_quad,
148 Number * hessians_quad,
149 Number * scratch_data,
150 const bool evaluate_values,
151 const bool evaluate_gradients,
152 const bool evaluate_hessians)
154 if (evaluate_values ==
false && evaluate_gradients ==
false &&
155 evaluate_hessians ==
false)
159 EvaluatorSelector<type, (fe_degree + n_q_points_1d > 4)>::variant;
174 const unsigned int temp_size =
177 (Eval::n_rows_of_product > Eval::n_columns_of_product ?
178 Eval::n_rows_of_product :
179 Eval::n_columns_of_product);
184 temp1 = scratch_data;
186 std::max(Utilities::fixed_power<dim>(shape_info.
fe_degree + 1),
191 temp1 = scratch_data;
192 temp2 = temp1 + temp_size;
195 const unsigned int n_q_points =
196 temp_size == 0 ? shape_info.
n_q_points : Eval::n_columns_of_product;
197 const unsigned int dofs_per_comp =
199 Utilities::fixed_power<dim>(shape_info.
fe_degree + 1) :
201 const Number *values_dofs = values_dofs_actual;
204 Number *values_dofs_tmp =
207 const int degree = fe_degree != -1 ? fe_degree : shape_info.
fe_degree;
208 unsigned int count_p = 0, count_q = 0;
209 for (
int i = 0; i < (dim > 2 ? degree + 1 : 1); ++i)
211 for (
int j = 0; j < (dim > 1 ? degree + 1 - i : 1); ++j)
213 for (
int k = 0; k < degree + 1 - j - i;
214 ++k, ++count_p, ++count_q)
216 values_dofs_tmp[c * dofs_per_comp + count_q] =
219 for (
int k = degree + 1 - j - i; k < degree + 1; ++k, ++count_q)
221 values_dofs_tmp[c * dofs_per_comp + count_q] = Number();
223 for (
int j = degree + 1 - i; j < degree + 1; ++j)
224 for (
int k = 0; k < degree + 1; ++k, ++count_q)
226 values_dofs_tmp[c * dofs_per_comp + count_q] = Number();
229 values_dofs = values_dofs_tmp;
237 if (evaluate_values ==
true)
238 eval.template values<0, true, false>(values_dofs, values_quad);
239 if (evaluate_gradients ==
true)
240 eval.template gradients<0, true, false>(values_dofs,
242 if (evaluate_hessians ==
true)
243 eval.template hessians<0, true, false>(values_dofs,
247 values_dofs += dofs_per_comp;
248 values_quad += n_q_points;
249 gradients_quad += n_q_points;
250 hessians_quad += n_q_points;
258 if (evaluate_gradients ==
true)
260 eval.template gradients<0, true, false>(values_dofs, temp1);
261 eval.template values<1, true, false>(temp1, gradients_quad);
263 if (evaluate_hessians ==
true)
266 if (evaluate_gradients ==
false)
267 eval.template gradients<0, true, false>(values_dofs, temp1);
268 eval.template gradients<1, true, false>(temp1,
273 eval.template hessians<0, true, false>(values_dofs, temp1);
274 eval.template values<1, true, false>(temp1, hessians_quad);
278 eval.template values<0, true, false>(values_dofs, temp1);
279 if (evaluate_gradients ==
true)
280 eval.template gradients<1, true, false>(temp1,
285 if (evaluate_hessians ==
true)
286 eval.template hessians<1, true, false>(temp1,
291 if (evaluate_values ==
true)
292 eval.template values<1, true, false>(temp1, values_quad);
295 values_dofs += dofs_per_comp;
296 values_quad += n_q_points;
297 gradients_quad += 2 * n_q_points;
298 hessians_quad += 3 * n_q_points;
305 if (evaluate_gradients ==
true)
308 eval.template gradients<0, true, false>(values_dofs, temp1);
309 eval.template values<1, true, false>(temp1, temp2);
310 eval.template values<2, true, false>(temp2, gradients_quad);
313 if (evaluate_hessians ==
true)
316 if (evaluate_gradients ==
false)
318 eval.template gradients<0, true, false>(values_dofs,
320 eval.template values<1, true, false>(temp1, temp2);
322 eval.template gradients<2, true, false>(temp2,
327 eval.template gradients<1, true, false>(temp1, temp2);
328 eval.template values<2, true, false>(temp2,
333 eval.template hessians<0, true, false>(values_dofs, temp1);
334 eval.template values<1, true, false>(temp1, temp2);
335 eval.template values<2, true, false>(temp2, hessians_quad);
339 eval.template values<0, true, false>(values_dofs, temp1);
340 if (evaluate_gradients ==
true)
342 eval.template gradients<1, true, false>(temp1, temp2);
343 eval.template values<2, true, false>(temp2,
348 if (evaluate_hessians ==
true)
351 if (evaluate_gradients ==
false)
352 eval.template gradients<1, true, false>(temp1, temp2);
353 eval.template gradients<2, true, false>(temp2,
358 eval.template hessians<1, true, false>(temp1, temp2);
359 eval.template values<2, true, false>(temp2,
366 eval.template values<1, true, false>(temp1, temp2);
367 if (evaluate_gradients ==
true)
368 eval.template gradients<2, true, false>(temp2,
374 if (evaluate_hessians ==
true)
375 eval.template hessians<2, true, false>(temp2,
381 if (evaluate_values ==
true)
382 eval.template values<2, true, false>(temp2, values_quad);
385 values_dofs += dofs_per_comp;
386 values_quad += n_q_points;
387 gradients_quad += 3 * n_q_points;
388 hessians_quad += 6 * n_q_points;
404 for (
unsigned int q = 0; q < shape_info.
n_q_points; ++q)
419 FEEvaluationImpl<type, dim, fe_degree, n_q_points_1d, n_components, Number>::
420 integrate(
const MatrixFreeFunctions::ShapeInfo<Number> &shape_info,
421 Number * values_dofs_actual,
422 Number * values_quad,
423 Number * gradients_quad,
424 Number * scratch_data,
425 const bool integrate_values,
426 const bool integrate_gradients,
427 const bool add_into_values_array)
430 EvaluatorSelector<type, (fe_degree + n_q_points_1d > 4)>::variant;
431 using Eval = EvaluatorTensorProduct<variant,
437 shape_info.shape_values,
439 shape_info.shape_gradients,
441 shape_info.shape_hessians,
442 shape_info.fe_degree + 1,
443 shape_info.n_q_points_1d);
445 const unsigned int temp_size =
448 (Eval::n_rows_of_product > Eval::n_columns_of_product ?
449 Eval::n_rows_of_product :
450 Eval::n_columns_of_product);
455 temp1 = scratch_data;
457 std::max(Utilities::fixed_power<dim>(shape_info.fe_degree + 1),
458 Utilities::fixed_power<dim>(shape_info.n_q_points_1d));
462 temp1 = scratch_data;
463 temp2 = temp1 + temp_size;
466 const unsigned int n_q_points =
467 temp_size == 0 ? shape_info.n_q_points : Eval::n_columns_of_product;
468 const unsigned int dofs_per_comp =
470 Utilities::fixed_power<dim>(shape_info.fe_degree + 1) :
471 shape_info.dofs_per_component_on_cell;
473 Number *values_dofs =
475 scratch_data + 2 * (std::max(shape_info.dofs_per_component_on_cell,
476 shape_info.n_q_points)) :
484 if (integrate_values ==
true)
486 if (add_into_values_array ==
false)
487 eval.template values<0, false, false>(values_quad,
490 eval.template values<0, false, true>(values_quad,
493 if (integrate_gradients ==
true)
495 if (integrate_values ==
true || add_into_values_array ==
true)
496 eval.template gradients<0, false, true>(gradients_quad,
499 eval.template gradients<0, false, false>(gradients_quad,
504 values_dofs += dofs_per_comp;
505 values_quad += n_q_points;
506 gradients_quad += n_q_points;
513 if (integrate_values ==
true && integrate_gradients ==
false)
515 eval.template values<1, false, false>(values_quad, temp1);
516 if (add_into_values_array ==
false)
517 eval.template values<0, false, false>(temp1, values_dofs);
519 eval.template values<0, false, true>(temp1, values_dofs);
521 if (integrate_gradients ==
true)
523 eval.template gradients<1, false, false>(gradients_quad +
526 if (integrate_values)
527 eval.template values<1, false, true>(values_quad, temp1);
528 if (add_into_values_array ==
false)
529 eval.template values<0, false, false>(temp1, values_dofs);
531 eval.template values<0, false, true>(temp1, values_dofs);
532 eval.template values<1, false, false>(gradients_quad, temp1);
533 eval.template gradients<0, false, true>(temp1, values_dofs);
537 values_dofs += dofs_per_comp;
538 values_quad += n_q_points;
539 gradients_quad += 2 * n_q_points;
546 if (integrate_values ==
true && integrate_gradients ==
false)
548 eval.template values<2, false, false>(values_quad, temp1);
549 eval.template values<1, false, false>(temp1, temp2);
550 if (add_into_values_array ==
false)
551 eval.template values<0, false, false>(temp2, values_dofs);
553 eval.template values<0, false, true>(temp2, values_dofs);
555 if (integrate_gradients ==
true)
557 eval.template gradients<2, false, false>(gradients_quad +
560 if (integrate_values)
561 eval.template values<2, false, true>(values_quad, temp1);
562 eval.template values<1, false, false>(temp1, temp2);
563 eval.template values<2, false, false>(gradients_quad +
566 eval.template gradients<1, false, true>(temp1, temp2);
567 if (add_into_values_array ==
false)
568 eval.template values<0, false, false>(temp2, values_dofs);
570 eval.template values<0, false, true>(temp2, values_dofs);
571 eval.template values<2, false, false>(gradients_quad, temp1);
572 eval.template values<1, false, false>(temp1, temp2);
573 eval.template gradients<0, false, true>(temp2, values_dofs);
577 values_dofs += dofs_per_comp;
578 values_quad += n_q_points;
579 gradients_quad += 3 * n_q_points;
591 shape_info.dofs_per_component_on_cell + 1;
593 if (integrate_values)
596 values_dofs[0] = values_quad[0];
597 for (
unsigned int q = 1; q < shape_info.n_q_points; ++q)
598 values_dofs[0] += values_quad[q];
599 values_dofs += dofs_per_comp;
600 values_quad += n_q_points;
605 values_dofs[c * shape_info.dofs_per_component_on_cell] = Number();
606 values_dofs +=
n_components * shape_info.dofs_per_component_on_cell;
613 unsigned int count_p = 0, count_q = 0;
614 const int degree = fe_degree != -1 ? fe_degree : shape_info.fe_degree;
615 for (
int i = 0; i < (dim > 2 ? degree + 1 : 1); ++i)
617 for (
int j = 0; j < (dim > 1 ? degree + 1 - i : 1); ++j)
619 for (
int k = 0; k < degree + 1 - j - i;
620 ++k, ++count_p, ++count_q)
624 [c * shape_info.dofs_per_component_on_cell + count_p] =
625 values_dofs[c * dofs_per_comp + count_q];
629 count_q += i * (degree + 1);
632 Utilities::fixed_power<dim>(shape_info.fe_degree + 1));
658 static_assert(basis_size_1 == 0 || basis_size_1 <= basis_size_2,
659 "The second dimension must not be smaller than the first");
683 DEAL_II_ALWAYS_INLINE
688 const Number * values_in,
694 basis_size_1 != 0 || basis_size_1_variable <= basis_size_2_variable,
695 ExcMessage(
"The second dimension must not be smaller than the first"));
701 constexpr
int next_dim =
703 ((basis_size_1 == 0 || basis_size_2 > basis_size_1) && dim > 1)) ?
710 (basis_size_1 == 0 ? 0 : basis_size_2),
713 eval_val(transformation_matrix,
716 basis_size_1_variable,
717 basis_size_2_variable);
718 const unsigned int np_1 =
719 basis_size_1 > 0 ? basis_size_1 : basis_size_1_variable;
720 const unsigned int np_2 =
721 basis_size_1 > 0 ? basis_size_2 : basis_size_2_variable;
723 ExcMessage(
"Cannot transform with 0-point basis"));
725 ExcMessage(
"Cannot transform with 0-point basis"));
729 values_in = values_in + n_components * Utilities::fixed_power<dim>(np_1);
731 values_out + n_components * Utilities::fixed_power<dim>(np_2);
732 for (
unsigned int c = n_components; c != 0; --c)
734 values_in -= Utilities::fixed_power<dim>(np_1);
735 values_out -= Utilities::fixed_power<dim>(np_2);
737 for (
unsigned int q = np_1; q != 0; --q)
748 Utilities::fixed_power<next_dim>(np_1),
751 Utilities::fixed_power<next_dim>(np_2),
752 basis_size_1_variable,
753 basis_size_2_variable);
758 if (basis_size_1 > 0 && basis_size_2 == basis_size_1 && dim == 2)
760 eval_val.template values<0, true, false>(values_in, values_out);
761 eval_val.template values<1, true, false>(values_out, values_out);
764 eval_val.template values<dim - 1,
true,
false>(values_in,
767 eval_val.template values<dim - 1,
true,
false>(values_out,
802 DEAL_II_ALWAYS_INLINE
807 const bool add_into_result,
814 basis_size_1 != 0 || basis_size_1_variable <= basis_size_2_variable,
815 ExcMessage(
"The second dimension must not be smaller than the first"));
816 Assert(add_into_result ==
false || values_in != values_out,
818 "Input and output cannot alias with each other when " 819 "adding the result of the basis change to existing data"));
821 constexpr
int next_dim =
823 ((basis_size_1 == 0 || basis_size_2 > basis_size_1) && dim > 1)) ?
829 (basis_size_1 == 0 ? 0 : basis_size_2),
832 eval_val(transformation_matrix,
835 basis_size_1_variable,
836 basis_size_2_variable);
837 const unsigned int np_1 =
838 basis_size_1 > 0 ? basis_size_1 : basis_size_1_variable;
839 const unsigned int np_2 =
840 basis_size_1 > 0 ? basis_size_2 : basis_size_2_variable;
842 ExcMessage(
"Cannot transform with 0-point basis"));
844 ExcMessage(
"Cannot transform with 0-point basis"));
846 for (
unsigned int c = 0; c < n_components; ++c)
848 if (basis_size_1 > 0 && basis_size_2 == basis_size_1 && dim == 2)
850 eval_val.template values<1, false, false>(values_in, values_in);
852 eval_val.template values<0, false, true>(values_in, values_out);
854 eval_val.template values<0, false, false>(values_in,
859 if (dim == 1 && add_into_result)
860 eval_val.template values<0, false, true>(values_in, values_out);
862 eval_val.template values<0, false, false>(values_in,
865 eval_val.template values<dim - 1,
false,
false>(values_in,
869 for (
unsigned int q = 0; q < np_1; ++q)
880 q * Utilities::fixed_power<next_dim>(np_2),
882 q * Utilities::fixed_power<next_dim>(np_1),
883 basis_size_1_variable,
884 basis_size_2_variable);
886 values_in += Utilities::fixed_power<dim>(np_2);
887 values_out += Utilities::fixed_power<dim>(np_1);
913 const Number * values_in,
914 Number * scratch_data,
917 constexpr
int next_dim = dim > 1 ? dim - 1 : dim;
918 Number * my_scratch =
919 basis_size_1 != basis_size_2 ? scratch_data : values_out;
921 const unsigned int size_per_component =
Utilities::pow(basis_size_2, dim);
922 Assert(coefficients.
size() == size_per_component ||
923 coefficients.
size() == n_components * size_per_component,
925 const unsigned int stride =
926 coefficients.
size() == size_per_component ? 0 : 1;
928 for (
unsigned int q = basis_size_1; q != 0; --q)
949 eval_val(transformation_matrix);
950 const unsigned int n_inner_blocks =
951 (dim > 1 && basis_size_2 < 10) ? basis_size_2 : 1;
952 const unsigned int n_blocks =
Utilities::pow(basis_size_2, dim - 1);
953 for (
unsigned int ii = 0; ii < n_blocks; ii += n_inner_blocks)
954 for (
unsigned int c = 0; c < n_components; ++c)
956 for (
unsigned int i = ii; i < ii + n_inner_blocks; ++i)
957 eval_val.template values_one_line<dim - 1, true, false>(
958 my_scratch + i, my_scratch + i);
959 for (
unsigned int q = 0; q < basis_size_2; ++q)
960 for (
unsigned int i = ii; i < ii + n_inner_blocks; ++i)
961 my_scratch[i + q * n_blocks + c * size_per_component] *=
962 coefficients[i + q * n_blocks +
963 c * stride * size_per_component];
964 for (
unsigned int i = ii; i < ii + n_inner_blocks; ++i)
965 eval_val.template values_one_line<dim - 1, false, false>(
966 my_scratch + i, my_scratch + i);
968 for (
unsigned int q = 0; q < basis_size_1; ++q)
1001 template <
int dim,
int fe_degree,
int n_components,
typename Number>
1006 const Number * values_dofs,
1007 Number * values_quad,
1008 Number * gradients_quad,
1009 Number * hessians_quad,
1010 Number * scratch_data,
1011 const bool evaluate_values,
1012 const bool evaluate_gradients,
1013 const bool evaluate_hessians);
1017 Number * values_dofs,
1018 Number * values_quad,
1019 Number * gradients_quad,
1020 Number * scratch_data,
1021 const bool integrate_values,
1022 const bool integrate_gradients,
1023 const bool add_into_values_array);
1028 template <
int dim,
int fe_degree,
int n_components,
typename Number>
1032 const Number * values_dofs,
1033 Number * values_quad,
1034 Number * gradients_quad,
1035 Number * hessians_quad,
1037 const bool evaluate_values,
1038 const bool evaluate_gradients,
1039 const bool evaluate_hessians)
1042 (fe_degree + 2) / 2 * (fe_degree + 1));
1052 constexpr
unsigned int n_q_points =
Utilities::pow(fe_degree + 1, dim);
1054 for (
unsigned int c = 0; c < n_components; c++)
1056 if (evaluate_values ==
true)
1057 for (
unsigned int i = 0; i < n_q_points; ++i)
1058 values_quad[i] = values_dofs[i];
1059 if (evaluate_gradients ==
true || evaluate_hessians ==
true)
1061 eval.template gradients<0, true, false>(values_dofs,
1064 eval.template gradients<1, true, false>(values_dofs,
1068 eval.template gradients<2, true, false>(values_dofs,
1072 if (evaluate_hessians ==
true)
1074 eval.template hessians<0, true, false>(values_dofs, hessians_quad);
1077 eval.template gradients<1, true, false>(gradients_quad,
1080 eval.template hessians<1, true, false>(values_dofs,
1086 eval.template gradients<2, true, false>(gradients_quad,
1089 eval.template gradients<2, true, false>(
1090 gradients_quad + n_q_points, hessians_quad + 5 * n_q_points);
1091 eval.template hessians<2, true, false>(values_dofs,
1095 hessians_quad += (dim * (dim + 1)) / 2 * n_q_points;
1097 gradients_quad += dim * n_q_points;
1098 values_quad += n_q_points;
1099 values_dofs += n_q_points;
1105 template <
int dim,
int fe_degree,
int n_components,
typename Number>
1107 FEEvaluationImplCollocation<dim, fe_degree, n_components, Number>::integrate(
1108 const MatrixFreeFunctions::ShapeInfo<Number> &shape_info,
1109 Number * values_dofs,
1110 Number * values_quad,
1111 Number * gradients_quad,
1113 const bool integrate_values,
1114 const bool integrate_gradients,
1115 const bool add_into_values_array)
1118 (fe_degree + 2) / 2 * (fe_degree + 1));
1126 shape_info.shape_gradients_collocation_eo,
1127 shape_info.shape_hessians_collocation_eo);
1128 constexpr
unsigned int n_q_points =
Utilities::pow(fe_degree + 1, dim);
1132 if (integrate_values ==
true && add_into_values_array ==
false)
1133 for (
unsigned int i = 0; i < n_q_points; ++i)
1134 values_dofs[i] = values_quad[i];
1135 else if (integrate_values ==
true)
1136 for (
unsigned int i = 0; i < n_q_points; ++i)
1137 values_dofs[i] += values_quad[i];
1138 if (integrate_gradients ==
true)
1140 if (integrate_values ==
true || add_into_values_array ==
true)
1141 eval.template gradients<0, false, true>(gradients_quad,
1144 eval.template gradients<0, false, false>(gradients_quad,
1147 eval.template gradients<1, false, true>(gradients_quad +
1151 eval.template gradients<2, false, true>(gradients_quad +
1155 gradients_quad += dim * n_q_points;
1156 values_quad += n_q_points;
1157 values_dofs += n_q_points;
1184 const Number * values_dofs,
1185 Number * values_quad,
1186 Number * gradients_quad,
1187 Number * hessians_quad,
1188 Number * scratch_data,
1189 const bool evaluate_values,
1190 const bool evaluate_gradients,
1191 const bool evaluate_hessians);
1195 Number * values_dofs,
1196 Number * values_quad,
1197 Number * gradients_quad,
1198 Number * scratch_data,
1199 const bool integrate_values,
1200 const bool integrate_gradients,
1201 const bool add_into_values_array);
1218 const Number * values_dofs,
1219 Number * values_quad,
1220 Number *gradients_quad,
1221 Number *hessians_quad,
1224 const bool evaluate_gradients,
1225 const bool evaluate_hessians)
1227 Assert(n_q_points_1d > fe_degree,
1228 ExcMessage(
"You lose information when going to a collocation space " 1229 "of lower degree, so the evaluation results would be " 1230 "wrong. Thus, this class does not permit the desired " 1232 constexpr
unsigned int n_q_points =
Utilities::pow(n_q_points_1d, dim);
1234 for (
unsigned int c = 0; c < n_components; c++)
1239 (fe_degree >= n_q_points_1d ? n_q_points_1d : fe_degree + 1),
1248 if (evaluate_gradients ==
true || evaluate_hessians ==
true)
1261 values_quad += n_q_points;
1262 gradients_quad += dim * n_q_points;
1263 hessians_quad += (dim * (dim + 1)) / 2 * n_q_points;
1275 FEEvaluationImplTransformToCollocation<
1280 Number>::integrate(
const MatrixFreeFunctions::ShapeInfo<Number> &shape_info,
1281 Number *values_dofs,
1282 Number *values_quad,
1283 Number *gradients_quad,
1285 const bool integrate_values,
1286 const bool integrate_gradients,
1287 const bool add_into_values_array)
1289 Assert(n_q_points_1d > fe_degree,
1290 ExcMessage(
"You lose information when going to a collocation space " 1291 "of lower degree, so the evaluation results would be " 1292 "wrong. Thus, this class does not permit the desired " 1295 (n_q_points_1d + 1) / 2 * n_q_points_1d);
1296 constexpr
unsigned int n_q_points =
Utilities::pow(n_q_points_1d, dim);
1301 if (integrate_gradients ==
true)
1302 FEEvaluationImplCollocation<dim, n_q_points_1d - 1, 1, Number>::
1303 integrate(shape_info,
1309 integrate_gradients,
1313 FEEvaluationImplBasisChange<
1316 (fe_degree >= n_q_points_1d ? n_q_points_1d : fe_degree + 1),
1320 Number>::do_backward(shape_info.shape_values_eo,
1321 add_into_values_array,
1324 gradients_quad += dim * n_q_points;
1325 values_quad += n_q_points;
1326 values_dofs += shape_info.dofs_per_component_on_cell;
1332 template <
bool symmetric_evaluate,
1338 struct FEFaceEvaluationImpl
1345 static constexpr
bool use_collocation =
1346 symmetric_evaluate &&
1347 n_q_points_1d > fe_degree &&n_q_points_1d <= 3 * fe_degree / 2 + 1 &&
1348 n_q_points_1d < 200;
1351 evaluate_in_face(
const MatrixFreeFunctions::ShapeInfo<Number> &data,
1352 Number * values_dofs,
1353 Number * values_quad,
1354 Number * gradients_quad,
1355 Number * scratch_data,
1356 const bool evaluate_val,
1357 const bool evaluate_grad,
1358 const unsigned int subface_index)
1361 symmetric_evaluate ?
1362 data.shape_values_eo :
1365 data.values_within_subface[subface_index % 2]);
1367 symmetric_evaluate ?
1368 data.shape_values_eo :
1371 data.values_within_subface[subface_index / 2]);
1374 symmetric_evaluate ?
1375 data.shape_gradients_eo :
1377 data.shape_gradients :
1378 data.gradients_within_subface[subface_index % 2]);
1380 symmetric_evaluate ?
1381 data.shape_gradients_eo :
1383 data.shape_gradients :
1384 data.gradients_within_subface[subface_index / 2]);
1398 data.n_q_points_1d);
1403 data.n_q_points_1d);
1405 const unsigned int size_deg =
1410 const unsigned int n_q_points = fe_degree > -1 ?
1412 data.n_q_points_face;
1414 if (evaluate_grad ==
false)
1420 eval1.template values<0, true, false>(values_dofs,
1422 eval2.template values<1, true, false>(values_quad,
1426 eval1.template values<0, true, false>(values_dofs,
1430 values_quad[0] = values_dofs[0];
1435 values_dofs += 2 * size_deg;
1436 values_quad += n_q_points;
1444 if (use_collocation)
1446 eval1.template values<0, true, false>(values_dofs,
1448 eval1.template values<1, true, false>(values_quad,
1457 data.shape_gradients_collocation_eo,
1459 eval_grad.template gradients<0, true, false>(
1460 values_quad, gradients_quad);
1461 eval_grad.template gradients<1, true, false>(
1462 values_quad, gradients_quad + n_q_points);
1466 eval1.template gradients<0, true, false>(values_dofs,
1468 eval2.template values<1, true, false>(scratch_data,
1471 eval1.template values<0, true, false>(values_dofs,
1473 eval2.template gradients<1, true, false>(scratch_data,
1477 if (evaluate_val ==
true)
1478 eval2.template values<1, true, false>(scratch_data,
1481 eval1.template values<0, true, false>(values_dofs + size_deg,
1483 eval2.template values<1, true, false>(
1484 scratch_data, gradients_quad + (dim - 1) * n_q_points);
1488 eval1.template values<0, true, false>(values_dofs + size_deg,
1492 eval1.template gradients<0, true, false>(values_dofs,
1494 if (evaluate_val ==
true)
1495 eval1.template values<0, true, false>(values_dofs,
1499 values_quad[0] = values_dofs[0];
1500 gradients_quad[0] = values_dofs[1];
1505 values_dofs += 2 * size_deg;
1506 values_quad += n_q_points;
1507 gradients_quad += dim * n_q_points;
1512 integrate_in_face(
const MatrixFreeFunctions::ShapeInfo<Number> &data,
1513 Number * values_dofs,
1514 Number * values_quad,
1515 Number * gradients_quad,
1516 Number * scratch_data,
1517 const bool integrate_val,
1518 const bool integrate_grad,
1519 const unsigned int subface_index)
1522 symmetric_evaluate ?
1523 data.shape_values_eo :
1526 data.values_within_subface[subface_index % 2]);
1528 symmetric_evaluate ?
1529 data.shape_values_eo :
1532 data.values_within_subface[subface_index / 2]);
1535 symmetric_evaluate ?
1536 data.shape_gradients_eo :
1538 data.shape_gradients :
1539 data.gradients_within_subface[subface_index % 2]);
1541 symmetric_evaluate ?
1542 data.shape_gradients_eo :
1544 data.shape_gradients :
1545 data.gradients_within_subface[subface_index / 2]);
1555 Eval eval1(val1, grad1, val1, data.fe_degree + 1, data.n_q_points_1d);
1556 Eval eval2(val2, grad2, val1, data.fe_degree + 1, data.n_q_points_1d);
1558 const unsigned int size_deg =
1563 const unsigned int n_q_points = fe_degree > -1 ?
1565 data.n_q_points_face;
1567 if (integrate_grad ==
false)
1573 eval2.template values<1, false, false>(values_quad,
1575 eval1.template values<0, false, false>(values_quad,
1579 eval1.template values<0, false, false>(values_quad,
1583 values_dofs[0] = values_quad[0];
1588 values_dofs += 2 * size_deg;
1589 values_quad += n_q_points;
1597 eval2.template values<1, false, false>(gradients_quad +
1601 eval1.template values<0, false, false>(
1602 gradients_quad + 2 * n_q_points, values_dofs + size_deg);
1603 if (use_collocation)
1612 data.shape_gradients_collocation_eo,
1615 eval_grad.template gradients<1, false, true>(
1616 gradients_quad + n_q_points, values_quad);
1618 eval_grad.template gradients<1, false, false>(
1619 gradients_quad + n_q_points, values_quad);
1620 eval_grad.template gradients<0, false, true>(
1621 gradients_quad, values_quad);
1622 eval1.template values<1, false, false>(values_quad,
1624 eval1.template values<0, false, false>(values_quad,
1631 eval2.template values<1, false, false>(values_quad,
1633 eval2.template gradients<1, false, true>(
1634 gradients_quad + n_q_points, scratch_data);
1637 eval2.template gradients<1, false, false>(
1638 gradients_quad + n_q_points, scratch_data);
1640 eval1.template values<0, false, false>(scratch_data,
1642 eval2.template values<1, false, false>(gradients_quad,
1644 eval1.template gradients<0, false, true>(scratch_data,
1649 eval1.template values<0, false, false>(
1650 gradients_quad + n_q_points, values_dofs + size_deg);
1651 eval1.template gradients<0, false, false>(gradients_quad,
1653 if (integrate_val ==
true)
1654 eval1.template values<0, false, true>(values_quad,
1658 values_dofs[0] = values_quad[0];
1659 values_dofs[1] = gradients_quad[0];
1664 values_dofs += 2 * size_deg;
1665 values_quad += n_q_points;
1666 gradients_quad += dim * n_q_points;
1673 template <
int dim,
int fe_degree,
int n_components,
typename Number>
1674 struct FEFaceNormalEvaluationImpl
1676 template <
bool do_evaluate,
bool add_
into_output>
1678 interpolate(
const MatrixFreeFunctions::ShapeInfo<Number> &data,
1679 const Number * input,
1681 const bool do_gradients,
1682 const unsigned int face_no)
1689 evalf(data.shape_data_on_face[face_no % 2],
1695 const unsigned int in_stride = do_evaluate ?
1696 data.dofs_per_component_on_cell :
1697 2 * data.dofs_per_component_on_face;
1698 const unsigned int out_stride = do_evaluate ?
1699 2 * data.dofs_per_component_on_face :
1700 data.dofs_per_component_on_cell;
1701 const unsigned int face_direction = face_no / 2;
1706 if (face_direction == 0)
1707 evalf.template apply_face<0, do_evaluate, add_into_output, 1>(
1709 else if (face_direction == 1)
1710 evalf.template apply_face<1, do_evaluate, add_into_output, 1>(
1713 evalf.template apply_face<2, do_evaluate, add_into_output, 1>(
1718 if (face_direction == 0)
1719 evalf.template apply_face<0, do_evaluate, add_into_output, 0>(
1721 else if (face_direction == 1)
1722 evalf.template apply_face<1, do_evaluate, add_into_output, 0>(
1725 evalf.template apply_face<2, do_evaluate, add_into_output, 0>(
1729 output += out_stride;
1736 DEAL_II_NAMESPACE_CLOSE
static const unsigned int invalid_unsigned_int
unsigned int dofs_per_component_on_cell
#define AssertDimension(dim1, dim2)
AlignedVector< Number > shape_values_eo
#define AssertThrow(cond, exc)
AlignedVector< Number > shape_hessians
static void do_forward(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)
AlignedVector< Number > shape_values
static void do_mass(const AlignedVector< Number2 > &transformation_matrix, const AlignedVector< Number > &coefficients, const Number *values_in, Number *scratch_data, Number *values_out)
static ::ExceptionBase & ExcMessage(std::string arg1)
static void do_backward(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)
#define Assert(cond, exc)
AlignedVector< Number > shape_gradients_collocation_eo
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
constexpr unsigned int pow(const unsigned int base, const int iexp)
unsigned int n_q_points_1d
AlignedVector< Number > shape_hessians_eo
AlignedVector< Number > shape_gradients_eo
AlignedVector< Number > shape_gradients
static ::ExceptionBase & ExcNotImplemented()
AlignedVector< Number > shape_hessians_collocation_eo