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>
47 struct EvaluatorSelector<MatrixFreeFunctions::tensor_symmetric, false>
53 struct EvaluatorSelector<MatrixFreeFunctions::tensor_symmetric, true>
58 template <
bool is_
long>
59 struct EvaluatorSelector<MatrixFreeFunctions::truncated_tensor, is_long>
65 struct EvaluatorSelector<MatrixFreeFunctions::tensor_symmetric_plus_dg0,
72 struct EvaluatorSelector<MatrixFreeFunctions::tensor_symmetric_plus_dg0, true>
77 template <
bool is_
long>
78 struct EvaluatorSelector<MatrixFreeFunctions::tensor_symmetric_collocation,
104 template <MatrixFreeFunctions::ElementType type,
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);
136 template <MatrixFreeFunctions::ElementType type,
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 =
198 (type == MatrixFreeFunctions::truncated_tensor) ?
199 Utilities::fixed_power<dim>(shape_info.
fe_degree + 1) :
201 const Number *values_dofs = values_dofs_actual;
202 if (type == MatrixFreeFunctions::truncated_tensor)
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)
215 for (
unsigned int c = 0; c < n_components; ++c)
216 values_dofs_tmp[c * dofs_per_comp + count_q] =
219 for (
int k = degree + 1 - j - i; k < degree + 1; ++k, ++count_q)
220 for (
unsigned int c = 0; c < n_components; ++c)
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)
225 for (
unsigned int c = 0; c < n_components; ++c)
226 values_dofs_tmp[c * dofs_per_comp + count_q] = Number();
229 values_dofs = values_dofs_tmp;
235 for (
unsigned int c = 0; c < n_components; c++)
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;
255 for (
unsigned int c = 0; c < n_components; c++)
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;
303 for (
unsigned int c = 0; c < n_components; c++)
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;
398 if (type == MatrixFreeFunctions::tensor_symmetric_plus_dg0 &&
401 values_quad -= n_components * n_q_points;
402 values_dofs -= n_components * dofs_per_comp;
403 for (
unsigned int c = 0; c < n_components; ++c)
404 for (
unsigned int q = 0; q < shape_info.
n_q_points; ++q)
412 template <MatrixFreeFunctions::ElementType type,
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;
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),
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 =
469 (type == MatrixFreeFunctions::truncated_tensor) ?
470 Utilities::fixed_power<dim>(shape_info.
fe_degree + 1) :
473 Number *values_dofs =
474 (type == MatrixFreeFunctions::truncated_tensor) ?
482 for (
unsigned int c = 0; c < n_components; c++)
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;
511 for (
unsigned int c = 0; c < n_components; c++)
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;
544 for (
unsigned int c = 0; c < n_components; c++)
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;
588 if (type == MatrixFreeFunctions::tensor_symmetric_plus_dg0)
590 values_dofs -= n_components * dofs_per_comp -
592 values_quad -= n_components * n_q_points;
593 if (integrate_values)
594 for (
unsigned int c = 0; c < n_components; ++c)
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;
604 for (
unsigned int c = 0; c < n_components; ++c)
610 if (type == MatrixFreeFunctions::truncated_tensor)
612 values_dofs -= dofs_per_comp * n_components;
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)
622 for (
unsigned int c = 0; c < n_components; ++c)
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)
745 Number2>::do_forward(transformation_matrix,
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)
877 do_backward(transformation_matrix,
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)
936 Number2>::do_forward(transformation_matrix,
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)
976 Number2>::do_backward(transformation_matrix,
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>
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));
1128 constexpr
unsigned int n_q_points =
Utilities::pow(fe_degree + 1, dim);
1130 for (
unsigned int c = 0; c < n_components; c++)
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;
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);
1298 for (
unsigned int c = 0; c < n_components; c++)
1301 if (integrate_gradients ==
true)
1309 integrate_gradients,
1316 (fe_degree >= n_q_points_1d ? n_q_points_1d : fe_degree + 1),
1321 add_into_values_array,
1324 gradients_quad += dim * n_q_points;
1325 values_quad += n_q_points;
1332 template <
bool symmetric_evaluate,
1338 struct FEFaceEvaluationImpl
1342 Number * values_dofs,
1343 Number * values_quad,
1344 Number * gradients_quad,
1345 Number * scratch_data,
1346 const bool evaluate_val,
1347 const bool evaluate_grad,
1348 const unsigned int subface_index)
1351 symmetric_evaluate ?
1357 symmetric_evaluate ?
1364 symmetric_evaluate ?
1370 symmetric_evaluate ?
1395 const unsigned int size_deg =
1400 const unsigned int n_q_points = fe_degree > -1 ?
1404 if (evaluate_grad ==
false)
1405 for (
unsigned int c = 0; c < n_components; ++c)
1410 eval1.template values<0, true, false>(values_dofs,
1412 eval2.template values<1, true, false>(values_quad,
1416 eval1.template values<0, true, false>(values_dofs,
1420 values_quad[0] = values_dofs[0];
1425 values_dofs += 2 * size_deg;
1426 values_quad += n_q_points;
1429 for (
unsigned int c = 0; c < n_components; ++c)
1434 if (symmetric_evaluate && n_q_points_1d > fe_degree)
1436 eval1.template values<0, true, false>(values_dofs,
1438 eval1.template values<1, true, false>(values_quad,
1449 eval_grad.template gradients<0, true, false>(
1450 values_quad, gradients_quad);
1451 eval_grad.template gradients<1, true, false>(
1452 values_quad, gradients_quad + n_q_points);
1456 eval1.template gradients<0, true, false>(values_dofs,
1458 eval2.template values<1, true, false>(scratch_data,
1461 eval1.template values<0, true, false>(values_dofs,
1463 eval2.template gradients<1, true, false>(scratch_data,
1467 if (evaluate_val ==
true)
1468 eval2.template values<1, true, false>(scratch_data,
1471 eval1.template values<0, true, false>(values_dofs + size_deg,
1473 eval2.template values<1, true, false>(
1474 scratch_data, gradients_quad + (dim - 1) * n_q_points);
1478 eval1.template values<0, true, false>(values_dofs + size_deg,
1482 eval1.template gradients<0, true, false>(values_dofs,
1484 if (evaluate_val ==
true)
1485 eval1.template values<0, true, false>(values_dofs,
1489 values_quad[0] = values_dofs[0];
1490 gradients_quad[0] = values_dofs[1];
1495 values_dofs += 2 * size_deg;
1496 values_quad += n_q_points;
1497 gradients_quad += dim * n_q_points;
1503 Number * values_dofs,
1504 Number * values_quad,
1505 Number * gradients_quad,
1506 Number * scratch_data,
1507 const bool integrate_val,
1508 const bool integrate_grad,
1509 const unsigned int subface_index)
1512 symmetric_evaluate ?
1518 symmetric_evaluate ?
1525 symmetric_evaluate ?
1531 symmetric_evaluate ?
1548 const unsigned int size_deg =
1553 const unsigned int n_q_points =
1558 if (integrate_grad ==
false)
1559 for (
unsigned int c = 0; c < n_components; ++c)
1564 eval2.template values<1, false, false>(values_quad,
1566 eval1.template values<0, false, false>(values_quad,
1570 eval1.template values<0, false, false>(values_quad,
1574 values_dofs[0] = values_quad[0];
1579 values_dofs += 2 * size_deg;
1580 values_quad += n_q_points;
1583 for (
unsigned int c = 0; c < n_components; ++c)
1588 eval2.template values<1, false, false>(gradients_quad +
1592 eval1.template values<0, false, false>(
1593 gradients_quad + 2 * n_q_points, values_dofs + size_deg);
1594 if (symmetric_evaluate && n_q_points_1d > fe_degree)
1606 eval_grad.template gradients<1, false, true>(
1607 gradients_quad + n_q_points, values_quad);
1609 eval_grad.template gradients<1, false, false>(
1610 gradients_quad + n_q_points, values_quad);
1611 eval_grad.template gradients<0, false, true>(
1612 gradients_quad, values_quad);
1613 eval1.template values<1, false, false>(values_quad,
1615 eval1.template values<0, false, false>(values_quad,
1622 eval2.template values<1, false, false>(values_quad,
1624 eval2.template gradients<1, false, true>(
1625 gradients_quad + n_q_points, scratch_data);
1628 eval2.template gradients<1, false, false>(
1629 gradients_quad + n_q_points, scratch_data);
1631 eval1.template values<0, false, false>(scratch_data,
1633 eval2.template values<1, false, false>(gradients_quad,
1635 eval1.template gradients<0, false, true>(scratch_data,
1640 eval1.template values<0, false, false>(
1641 gradients_quad + n_q_points, values_dofs + size_deg);
1642 eval1.template gradients<0, false, false>(gradients_quad,
1644 if (integrate_val ==
true)
1645 eval1.template values<0, false, true>(values_quad,
1649 values_dofs[0] = values_quad[0];
1650 values_dofs[1] = gradients_quad[0];
1655 values_dofs += 2 * size_deg;
1656 values_quad += n_q_points;
1657 gradients_quad += dim * n_q_points;
1664 template <
int dim,
int fe_degree,
int n_components,
typename Number>
1665 struct FEFaceNormalEvaluationImpl
1667 template <
bool do_evaluate,
bool add_
into_output>
1670 const Number * input,
1672 const bool do_gradients,
1673 const unsigned int face_no)
1686 const unsigned int in_stride = do_evaluate ?
1689 const unsigned int out_stride = do_evaluate ?
1692 const unsigned int face_direction = face_no / 2;
1693 for (
unsigned int c = 0; c < n_components; c++)
1697 if (face_direction == 0)
1698 evalf.template apply_face<0, do_evaluate, add_into_output, 1>(
1700 else if (face_direction == 1)
1701 evalf.template apply_face<1, do_evaluate, add_into_output, 1>(
1704 evalf.template apply_face<2, do_evaluate, add_into_output, 1>(
1709 if (face_direction == 0)
1710 evalf.template apply_face<0, do_evaluate, add_into_output, 0>(
1712 else if (face_direction == 1)
1713 evalf.template apply_face<1, do_evaluate, add_into_output, 0>(
1716 evalf.template apply_face<2, do_evaluate, add_into_output, 0>(
1720 output += out_stride;
1727 DEAL_II_NAMESPACE_CLOSE
static const unsigned int invalid_unsigned_int
unsigned int dofs_per_component_on_cell
#define AssertDimension(dim1, dim2)
constexpr unsigned int pow(const unsigned int base, const unsigned int iexp)
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)
unsigned int dofs_per_component_on_face
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)
unsigned int n_q_points_face
AlignedVector< Number > shape_data_on_face[2]
unsigned int n_q_points_1d
AlignedVector< Number > shape_hessians_eo
AlignedVector< Number > gradients_within_subface[2]
AlignedVector< Number > shape_gradients_eo
AlignedVector< Number > shape_gradients
static::ExceptionBase & ExcNotImplemented()
AlignedVector< Number > values_within_subface[2]
AlignedVector< Number > shape_hessians_collocation_eo