14#ifndef dealii_matrix_free_evaluation_kernels_h
15#define dealii_matrix_free_evaluation_kernels_h
35 template <MatrixFreeFunctions::ElementType element,
bool is_
long>
39 template <
bool is_
long>
57 template <
bool is_
long>
76 template <
bool is_
long>
126 evaluate(
const unsigned int n_components,
128 const Number *values_dofs_actual,
132 integrate(
const unsigned int n_components,
134 Number *values_dofs_actual,
136 const bool add_into_values_array);
141 *univariate_shape_data)
164 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
172 evaluate(
const unsigned int n_components,
174 const Number *values_dofs_actual,
178 integrate(
const unsigned int n_components,
180 Number *values_dofs_actual,
182 const bool add_into_values_array);
194 const unsigned int n_components,
196 const Number *values_dofs_actual,
202 std::array<const MatrixFreeFunctions::UnivariateShapeData<Number2> *, 3>
203 univariate_shape_data;
207 univariate_shape_data.fill(&shape_data.front());
209 if (shape_data.size() == dim)
210 for (
int i = 1; i < dim; ++i)
211 univariate_shape_data[i] = &shape_data[i];
213 Eval eval0 = create_evaluator_tensor_product(univariate_shape_data[0]);
214 Eval eval1 = create_evaluator_tensor_product(univariate_shape_data[1]);
215 Eval eval2 = create_evaluator_tensor_product(univariate_shape_data[2]);
217 const unsigned int temp_size =
220 (Eval::n_rows_of_product > Eval::n_columns_of_product ?
221 Eval::n_rows_of_product :
222 Eval::n_columns_of_product);
227 temp2 = temp1 +
std::max(Utilities::fixed_power<dim>(
228 shape_data.front().fe_degree + 1),
229 Utilities::fixed_power<dim>(
230 shape_data.front().n_q_points_1d));
234 temp2 = temp1 + temp_size;
237 const std::size_t n_q_points = temp_size == 0 ?
239 Eval::n_columns_of_product;
240 const std::size_t dofs_per_comp =
244 const Number *values_dofs =
246 temp1 + 2 * (std::max<std::size_t>(
252 embed_truncated_into_full_tensor_product<dim, fe_degree>(
254 const_cast<Number *
>(values_dofs),
264 for (
unsigned int c = 0; c < n_components; ++c)
267 eval0.template values<0, true, false>(values_dofs, values_quad);
269 eval0.template gradients<0, true, false>(values_dofs,
273 values_dofs += dofs_per_comp;
274 values_quad += n_q_points;
275 gradients_quad += n_q_points;
280 for (
unsigned int c = 0; c < n_components; ++c)
285 eval0.template gradients<0, true, false>(values_dofs, temp1);
286 eval1.template values<1, true, false, 2>(temp1,
291 eval0.template values<0, true, false>(values_dofs, temp1);
293 eval1.template gradients<1, true, false, 2>(temp1,
298 eval1.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;
308 for (
unsigned int c = 0; c < n_components; ++c)
313 eval0.template gradients<0, true, false>(values_dofs, temp1);
314 eval1.template values<1, true, false>(temp1, temp2);
315 eval2.template values<2, true, false, 3>(temp2,
320 eval0.template values<0, true, false>(values_dofs, temp1);
323 eval1.template gradients<1, true, false>(temp1, temp2);
324 eval2.template values<2, true, false, 3>(temp2,
330 eval1.template values<1, true, false>(temp1, temp2);
332 eval2.template gradients<2, true, false, 3>(temp2,
338 eval2.template values<2, true, false>(temp2, values_quad);
341 values_dofs += dofs_per_comp;
342 values_quad += n_q_points;
343 gradients_quad += 3 * n_q_points;
356 values_quad -= n_components * n_q_points;
357 values_dofs -= n_components * dofs_per_comp;
358 for (std::size_t c = 0; c < n_components; ++c)
359 for (std::size_t q = 0; q < n_q_points; ++q)
360 values_quad[c * n_q_points + q] +=
361 values_dofs[(c + 1) * dofs_per_comp - 1];
374 const unsigned int n_components,
376 Number *values_dofs_actual,
378 const bool add_into_values_array)
380 std::array<const MatrixFreeFunctions::UnivariateShapeData<Number2> *, 3>
381 univariate_shape_data;
384 univariate_shape_data.fill(&shape_data.front());
386 if (shape_data.size() == dim)
387 for (
int i = 1; i < dim; ++i)
388 univariate_shape_data[i] = &shape_data[i];
390 Eval eval0 = create_evaluator_tensor_product(univariate_shape_data[0]);
391 Eval eval1 = create_evaluator_tensor_product(univariate_shape_data[1]);
392 Eval eval2 = create_evaluator_tensor_product(univariate_shape_data[2]);
394 const unsigned int temp_size =
397 (Eval::n_rows_of_product > Eval::n_columns_of_product ?
398 Eval::n_rows_of_product :
399 Eval::n_columns_of_product);
404 temp2 = temp1 +
std::max(Utilities::fixed_power<dim>(
405 shape_data.front().fe_degree + 1),
406 Utilities::fixed_power<dim>(
407 shape_data.front().n_q_points_1d));
411 temp2 = temp1 + temp_size;
414 const std::size_t n_q_points = temp_size == 0 ?
416 Eval::n_columns_of_product;
417 const unsigned int dofs_per_comp =
419 Utilities::fixed_power<dim>(shape_data.front().fe_degree + 1) :
423 Number *values_dofs =
425 temp1 + 2 * (std::max<std::size_t>(
436 for (
unsigned int c = 0; c < n_components; ++c)
440 if (add_into_values_array ==
false)
441 eval0.template values<0, false, false>(values_quad,
444 eval0.template values<0, false, true>(values_quad,
450 add_into_values_array ==
true)
451 eval0.template gradients<0, false, true>(gradients_quad,
454 eval0.template gradients<0, false, false>(gradients_quad,
459 values_dofs += dofs_per_comp;
460 values_quad += n_q_points;
461 gradients_quad += n_q_points;
466 for (
unsigned int c = 0; c < n_components; ++c)
471 eval1.template values<1, false, false>(values_quad, temp1);
472 if (add_into_values_array ==
false)
473 eval0.template values<0, false, false>(temp1, values_dofs);
475 eval0.template values<0, false, true>(temp1, values_dofs);
479 eval1.template gradients<1, false, false, 2>(gradients_quad +
483 eval1.template values<1, false, true>(values_quad, temp1);
484 if (add_into_values_array ==
false)
485 eval0.template values<0, false, false>(temp1, values_dofs);
487 eval0.template values<0, false, true>(temp1, values_dofs);
488 eval1.template values<1, false, false, 2>(gradients_quad,
490 eval0.template gradients<0, false, true>(temp1, values_dofs);
494 values_dofs += dofs_per_comp;
495 values_quad += n_q_points;
496 gradients_quad += 2 * n_q_points;
501 for (
unsigned int c = 0; c < n_components; ++c)
506 eval2.template values<2, false, false>(values_quad, temp1);
507 eval1.template values<1, false, false>(temp1, temp2);
508 if (add_into_values_array ==
false)
509 eval0.template values<0, false, false>(temp2, values_dofs);
511 eval0.template values<0, false, true>(temp2, values_dofs);
515 eval2.template gradients<2, false, false, 3>(gradients_quad +
519 eval2.template values<2, false, true>(values_quad, temp1);
520 eval1.template values<1, false, false>(temp1, temp2);
521 eval2.template values<2, false, false, 3>(gradients_quad + 1,
523 eval1.template gradients<1, false, true>(temp1, temp2);
524 if (add_into_values_array ==
false)
525 eval0.template values<0, false, false>(temp2, values_dofs);
527 eval0.template values<0, false, true>(temp2, values_dofs);
528 eval2.template values<2, false, false, 3>(gradients_quad,
530 eval1.template values<1, false, false>(temp1, temp2);
531 eval0.template gradients<0, false, true>(temp2, values_dofs);
535 values_dofs += dofs_per_comp;
536 values_quad += n_q_points;
537 gradients_quad += 3 * n_q_points;
548 values_dofs -= n_components * dofs_per_comp - dofs_per_comp + 1;
549 values_quad -= n_components * n_q_points;
551 for (
unsigned int c = 0; c < n_components; ++c)
553 values_dofs[0] = values_quad[0];
554 for (
unsigned int q = 1; q < n_q_points; ++q)
555 values_dofs[0] += values_quad[q];
556 values_dofs += dofs_per_comp;
557 values_quad += n_q_points;
561 for (
unsigned int c = 0; c < n_components; ++c)
562 values_dofs[c * dofs_per_comp] = Number();
563 values_dofs += n_components * dofs_per_comp;
568 truncate_tensor_product_to_complete_degrees<dim, fe_degree>(
571 values_dofs - dofs_per_comp * n_components,
577 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
584 Number>::evaluate(
const unsigned int n_components,
586 const Number *values_dofs_actual,
591 const std::size_t n_dofs =
602 const auto *
const shape_values = shape_data.front().shape_values.data();
604 const auto *in = values_dofs_actual;
606 for (
unsigned int c = 0; c < n_components; c += 3)
608 if (c + 1 == n_components)
617 shape_values, in, out, n_dofs, n_q_points, 1, 1);
618 else if (c + 2 == n_components)
627 shape_values, in, out, n_dofs, n_q_points, 1, 1);
637 shape_values, in, out, n_dofs, n_q_points, 1, 1);
639 out += 3 * n_q_points;
646 const auto *
const shape_gradients =
647 shape_data.front().shape_gradients.data();
649 const auto *in = values_dofs_actual;
651 for (
unsigned int c = 0; c < n_components; c += 3)
653 if (c + 1 == n_components)
662 shape_gradients, in, out, n_dofs, n_q_points * dim, 1, 1);
663 else if (c + 2 == n_components)
672 shape_gradients, in, out, n_dofs, n_q_points * dim, 1, 1);
682 shape_gradients, in, out, n_dofs, n_q_points * dim, 1, 1);
684 out += 3 * n_q_points * dim;
692 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
699 Number>::integrate(
const unsigned int n_components,
701 Number *values_dofs_actual,
703 const bool add_into_values_array)
708 const std::size_t n_dofs =
719 const auto *
const shape_values = shape_data.front().shape_values.data();
721 auto *out = values_dofs_actual;
723 for (
unsigned int c = 0; c < n_components; c += 3)
725 if (add_into_values_array ==
false)
727 if (c + 1 == n_components)
736 shape_values, in, out, n_dofs, n_q_points, 1, 1);
737 else if (c + 2 == n_components)
746 shape_values, in, out, n_dofs, n_q_points, 1, 1);
756 shape_values, in, out, n_dofs, n_q_points, 1, 1);
760 if (c + 1 == n_components)
769 shape_values, in, out, n_dofs, n_q_points, 1, 1);
770 else if (c + 2 == n_components)
779 shape_values, in, out, n_dofs, n_q_points, 1, 1);
789 shape_values, in, out, n_dofs, n_q_points, 1, 1);
792 in += 3 * n_q_points;
798 const auto *
const shape_gradients =
799 shape_data.front().shape_gradients.data();
801 auto *out = values_dofs_actual;
803 for (
unsigned int c = 0; c < n_components; c += 3)
805 if (add_into_values_array ==
false &&
808 if (c + 1 == n_components)
817 shape_gradients, in, out, n_dofs, n_q_points * dim, 1, 1);
818 else if (c + 2 == n_components)
827 shape_gradients, in, out, n_dofs, n_q_points * dim, 1, 1);
837 shape_gradients, in, out, n_dofs, n_q_points * dim, 1, 1);
841 if (c + 1 == n_components)
850 shape_gradients, in, out, n_dofs, n_q_points * dim, 1, 1);
851 else if (c + 2 == n_components)
860 shape_gradients, in, out, n_dofs, n_q_points * dim, 1, 1);
870 shape_gradients, in, out, n_dofs, n_q_points * dim, 1, 1);
873 in += 3 * n_q_points * dim;
896 static_assert(basis_size_1 == 0 || basis_size_1 <= basis_size_2,
897 "The second dimension must not be smaller than the first");
921 template <
typename Number,
typename Number2>
928 const Number *values_in,
930 const unsigned int basis_size_1_variable =
932 const unsigned int basis_size_2_variable =
936 basis_size_1 != 0 || basis_size_1_variable <= basis_size_2_variable,
937 ExcMessage(
"The second dimension must not be smaller than the first"));
945 constexpr int next_dim = (dim == 1 || (dim == 2 && basis_size_1 > 0 &&
946 basis_size_1 == basis_size_2)) ?
953 (basis_size_1 == 0 ? 0 : basis_size_2),
956 eval_val(transformation_matrix,
959 basis_size_1_variable,
960 basis_size_2_variable);
961 const unsigned int np_1 =
962 basis_size_1 > 0 ? basis_size_1 : basis_size_1_variable;
963 const unsigned int np_2 =
964 basis_size_1 > 0 ? basis_size_2 : basis_size_2_variable;
966 ExcMessage(
"Cannot transform with 0-point basis"));
968 ExcMessage(
"Cannot transform with 0-point basis"));
972 values_in = values_in + n_components * Utilities::fixed_power<dim>(np_1);
974 values_out + n_components * Utilities::fixed_power<dim>(np_2);
975 for (
unsigned int c = n_components; c != 0; --c)
977 values_in -= Utilities::fixed_power<dim>(np_1);
978 values_out -= Utilities::fixed_power<dim>(np_2);
980 for (
unsigned int q = np_1; q != 0; --q)
987 transformation_matrix,
989 (q - 1) * Utilities::fixed_power<next_dim>(np_1),
991 (q - 1) * Utilities::fixed_power<next_dim>(np_2),
992 basis_size_1_variable,
993 basis_size_2_variable);
998 if (basis_size_1 > 0 && basis_size_2 == basis_size_1 && dim == 2)
1000 eval_val.template values<0, true, false>(values_in, values_out);
1001 eval_val.template values<1, true, false>(values_out, values_out);
1004 eval_val.template values<dim - 1,
true,
false>(values_in,
1007 eval_val.template values<dim - 1,
true,
false>(values_out,
1042 template <
typename Number,
typename Number2>
1049 const bool add_into_result,
1052 const unsigned int basis_size_1_variable =
1054 const unsigned int basis_size_2_variable =
1058 basis_size_1 != 0 || basis_size_1_variable <= basis_size_2_variable,
1059 ExcMessage(
"The second dimension must not be smaller than the first"));
1060 Assert(add_into_result ==
false || values_in != values_out,
1062 "Input and output cannot alias with each other when "
1063 "adding the result of the basis change to existing data"));
1069 constexpr int next_dim =
1071 ((basis_size_1 == 0 || basis_size_2 > basis_size_1) && dim > 1)) ?
1077 (basis_size_1 == 0 ? 0 : basis_size_2),
1080 eval_val(transformation_matrix,
1081 transformation_matrix,
1082 transformation_matrix,
1083 basis_size_1_variable,
1084 basis_size_2_variable);
1085 const unsigned int np_1 =
1086 basis_size_1 > 0 ? basis_size_1 : basis_size_1_variable;
1087 const unsigned int np_2 =
1088 basis_size_1 > 0 ? basis_size_2 : basis_size_2_variable;
1090 ExcMessage(
"Cannot transform with 0-point basis"));
1092 ExcMessage(
"Cannot transform with 0-point basis"));
1094 for (
unsigned int c = 0; c < n_components; ++c)
1096 if (basis_size_1 > 0 && basis_size_2 == basis_size_1 && dim == 2)
1099 eval_val.template values<1, false, false>(values_in, values_in);
1101 eval_val.template hessians<1, false, false>(values_in,
1104 if (add_into_result)
1107 eval_val.template values<0, false, true>(values_in,
1110 eval_val.template hessians<0, false, true>(values_in,
1116 eval_val.template values<0, false, false>(values_in,
1119 eval_val.template hessians<0, false, false>(values_in,
1125 if (dim == 1 && add_into_result)
1128 eval_val.template values<0, false, true>(values_in,
1131 eval_val.template hessians<0, false, true>(values_in,
1137 eval_val.template values<0, false, false>(values_in,
1140 eval_val.template hessians<0, false, false>(values_in,
1146 eval_val.template values<dim - 1,
false,
false>(values_in,
1149 eval_val.template hessians<dim - 1,
false,
false>(
1150 values_in, values_in);
1154 for (
unsigned int q = 0; q < np_1; ++q)
1161 transformation_matrix,
1164 q * Utilities::fixed_power<next_dim>(np_2),
1166 q * Utilities::fixed_power<next_dim>(np_1),
1167 basis_size_1_variable,
1168 basis_size_2_variable);
1170 values_in += Utilities::fixed_power<dim>(np_2);
1171 values_out += Utilities::fixed_power<dim>(np_1);
1195 template <
typename Number,
typename Number2>
1200 const Number *values_in,
1201 Number *scratch_data,
1204 constexpr int next_dim = dim > 1 ? dim - 1 : dim;
1205 Number *my_scratch =
1206 basis_size_1 != basis_size_2 ? scratch_data : values_out;
1208 const unsigned int size_per_component =
Utilities::pow(basis_size_2, dim);
1209 Assert(coefficients.
size() == size_per_component ||
1210 coefficients.
size() == n_components * size_per_component,
1212 const unsigned int stride =
1213 coefficients.
size() == size_per_component ? 0 : 1;
1215 for (
unsigned int q = basis_size_1; q != 0; --q)
1222 transformation_matrix,
1235 eval_val(transformation_matrix);
1236 const unsigned int n_inner_blocks =
1237 (dim > 1 && basis_size_2 < 10) ? basis_size_2 : 1;
1238 const unsigned int n_blocks =
Utilities::pow(basis_size_2, dim - 1);
1239 for (
unsigned int ii = 0; ii < n_blocks; ii += n_inner_blocks)
1240 for (
unsigned int c = 0; c < n_components; ++c)
1242 for (
unsigned int i = ii; i < ii + n_inner_blocks; ++i)
1243 eval_val.template values_one_line<dim - 1, true, false>(
1244 my_scratch + i, my_scratch + i);
1245 for (
unsigned int q = 0; q < basis_size_2; ++q)
1246 for (
unsigned int i = ii; i < ii + n_inner_blocks; ++i)
1247 my_scratch[i + q * n_blocks + c * size_per_component] *=
1248 coefficients[i + q * n_blocks +
1249 c * stride * size_per_component];
1250 for (
unsigned int i = ii; i < ii + n_inner_blocks; ++i)
1251 eval_val.template values_one_line<dim - 1, false, false>(
1252 my_scratch + i, my_scratch + i);
1254 for (
unsigned int q = 0; q < basis_size_1; ++q)
1261 transformation_matrix,
1277 template <
int n_po
ints_1d,
int dim,
typename Number,
typename Number2>
1281 const Number *values,
1285 (n_points_1d + 1) / 2 * n_points_1d);
1303 eval.template gradients<0, true, false>(values, gradients);
1307 eval.template gradients<2, true, false, dim>(values, gradients + 2);
1308 constexpr unsigned int loop_bound = (dim > 2 ? n_points_1d : 1);
1309 constexpr unsigned int n_points_2d = n_points_1d * n_points_1d;
1310 const Number *in = values + (loop_bound - 1) * n_points_2d;
1311 Number *out = gradients + (loop_bound - 1) * dim * n_points_2d;
1312 for (
unsigned int l = 0; l < loop_bound; ++l)
1314 eval_2d.template gradients<0, true, false, dim>(in, out);
1315 eval_2d.template gradients<1, true, false, dim>(in, out + 1);
1317 out -= dim * n_points_2d;
1331 template <
int n_po
ints_1d,
int dim,
typename Number,
typename Number2>
1336 const Number *gradients,
1337 const bool add_into_values_array)
1340 (n_points_1d + 1) / 2 * n_points_1d);
1359 if (add_into_values_array)
1360 eval.template gradients<0, false, true>(gradients, values);
1362 eval.template gradients<0, false, false>(gradients, values);
1366 constexpr unsigned int loop_bound = (dim > 2 ? n_points_1d : 1);
1367 constexpr unsigned int n_points_2d = n_points_1d * n_points_1d;
1369 const Number *in = gradients + (loop_bound - 1) * dim * n_points_2d;
1370 Number *out = values + (loop_bound - 1) * n_points_2d;
1371 for (
unsigned int l = 0; l < loop_bound; ++l)
1373 if (add_into_values_array)
1374 eval_2d.template gradients<0, false, true, dim>(in, out);
1376 eval_2d.template gradients<0, false, false, dim>(in, out);
1377 eval_2d.template gradients<1, false, true, dim>(in + 1, out);
1378 in -= dim * n_points_2d;
1383 eval.template gradients<2, false, true, dim>(gradients + 2, values);
1394 template <
int n_po
ints_1d,
int dim,
typename Number>
1408 data.n_q_points_1d *
data.n_q_points_1d);
1416 data.shape_gradients_collocation.data(),
1417 data.shape_hessians_collocation.data(),
1419 data.n_q_points_1d);
1425 for (
unsigned int comp = 0; comp < n_components; ++comp)
1428 eval.template hessians<0, true, false>(values, hessians);
1434 eval.template gradients<0, true, false>(values, scratch);
1435 eval.template gradients<1, true, false>(scratch,
1436 hessians + dim * n_points);
1438 eval.template hessians<1, true, false>(values, hessians + n_points);
1443 eval.template gradients<2, true, false>(scratch,
1444 hessians + 4 * n_points);
1446 eval.template gradients<1, true, false>(values, scratch);
1447 eval.template gradients<2, true, false>(scratch,
1448 hessians + 5 * n_points);
1450 eval.template hessians<2, true, false>(values,
1451 hessians + 2 * n_points);
1455 hessians += (dim * (dim + 1)) / 2 * n_points;
1467 template <
int n_q_po
ints_1d,
int dim,
typename Number>
1471 const bool add_into_values_array)
1479 data.n_q_points_1d *
data.n_q_points_1d);
1487 data.shape_gradients_collocation.data(),
1488 data.shape_hessians_collocation.data(),
1490 data.n_q_points_1d);
1496 for (
unsigned int comp = 0; comp < n_components; ++comp)
1499 if (add_into_values_array ==
true)
1500 eval.template hessians<0, false, true>(hessians, values);
1502 eval.template hessians<0, false, false>(hessians, values);
1506 eval.template hessians<1, false, true>(hessians + n_points, values);
1510 eval.template hessians<2, false, true>(hessians + 2 * n_points,
1513 eval.template gradients<2, false, false>(hessians + 5 * n_points,
1515 eval.template gradients<1, false, true>(scratch, values);
1518 eval.template gradients<2, false, false>(hessians + 4 * n_points,
1525 eval.template gradients<1,
false, (dim > 2)>(hessians +
1528 eval.template gradients<0, false, true>(scratch, values);
1532 hessians += (dim * (dim + 1)) / 2 * n_points;
1544 template <
int dim,
typename Number>
1547 const Number *values_dofs,
1553 using Eval =
typename Impl::Eval;
1555 Impl::create_evaluator_tensor_product(&univariate_shape_data[0]);
1556 Eval eval1 = Impl::create_evaluator_tensor_product(
1557 &univariate_shape_data[std::min<int>(1,
1558 univariate_shape_data.size() - 1)]);
1559 Eval eval2 = Impl::create_evaluator_tensor_product(
1560 &univariate_shape_data[std::min<int>(2,
1561 univariate_shape_data.size() - 1)]);
1566 tmp1 +
std::max(Utilities::fixed_power<dim>(
1567 univariate_shape_data.front().fe_degree + 1),
1568 Utilities::fixed_power<dim>(
1569 univariate_shape_data.front().n_q_points_1d));
1572 for (
unsigned int comp = 0; comp < n_components;
1574 hessians += n_points * dim * (dim + 1) / 2,
1580 eval0.template hessians<0, true, false>(values_dofs, hessians);
1584 eval0.template hessians<0, true, false>(values_dofs, tmp1);
1585 eval1.template values<1, true, false>(tmp1, hessians);
1587 eval0.template gradients<0, true, false>(values_dofs, tmp1);
1588 eval1.template gradients<1, true, false>(tmp1,
1589 hessians + 2 * n_points);
1591 eval0.template values<0, true, false>(values_dofs, tmp1);
1592 eval1.template hessians<1, true, false>(tmp1, hessians + n_points);
1596 eval0.template hessians<0, true, false>(values_dofs, tmp1);
1597 eval1.template values<1, true, false>(tmp1, tmp2);
1598 eval2.template values<2, true, false>(tmp2, hessians);
1600 eval0.template gradients<0, true, false>(values_dofs, tmp1);
1601 eval1.template gradients<1, true, false>(tmp1, tmp2);
1602 eval2.template values<2, true, false>(tmp2,
1603 hessians + 3 * n_points);
1605 eval1.template values<1, true, false>(tmp1, tmp2);
1606 eval2.template gradients<2, true, false>(tmp2,
1607 hessians + 4 * n_points);
1609 eval0.template values<0, true, false>(values_dofs, tmp1);
1610 eval1.template hessians<1, true, false>(tmp1, tmp2);
1611 eval2.template values<2, true, false>(tmp2, hessians + n_points);
1613 eval1.template gradients<1, true, false>(tmp1, tmp2);
1614 eval2.template gradients<2, true, false>(tmp2,
1615 hessians + 5 * n_points);
1617 eval1.template values<1, true, false>(tmp1, tmp2);
1618 eval2.template hessians<2, true, false>(tmp2,
1619 hessians + 2 * n_points);
1625 "Only 1d, 2d and 3d implemented for Hessian"));
1638 template <
int dim,
typename Number>
1642 Number *values_dofs,
1643 const bool add_into_values_array)
1648 using Eval =
typename Impl::Eval;
1650 Impl::create_evaluator_tensor_product(&univariate_shape_data[0]);
1651 Eval eval1 = Impl::create_evaluator_tensor_product(
1652 &univariate_shape_data[std::min<int>(1,
1653 univariate_shape_data.size() - 1)]);
1654 Eval eval2 = Impl::create_evaluator_tensor_product(
1655 &univariate_shape_data[std::min<int>(2,
1656 univariate_shape_data.size() - 1)]);
1661 tmp1 +
std::max(Utilities::fixed_power<dim>(
1662 univariate_shape_data.front().fe_degree + 1),
1663 Utilities::fixed_power<dim>(
1664 univariate_shape_data.front().n_q_points_1d));
1667 for (
unsigned int comp = 0; comp < n_components;
1669 hessians += n_points * dim * (dim + 1) / 2,
1675 if (add_into_values_array)
1676 eval0.template hessians<0, false, true>(hessians, values_dofs);
1678 eval0.template hessians<0, false, false>(hessians, values_dofs);
1682 eval1.template values<1, false, false>(hessians, tmp1);
1683 if (add_into_values_array)
1684 eval0.template hessians<0, false, true>(tmp1, values_dofs);
1686 eval0.template hessians<0, false, false>(tmp1, values_dofs);
1689 eval1.template gradients<1, false, false>(hessians + 2 * n_points,
1691 eval0.template gradients<0, false, true>(tmp1, values_dofs);
1693 eval1.template hessians<1, false, false>(hessians + n_points, tmp1);
1694 eval0.template values<0, false, true>(tmp1, values_dofs);
1698 eval2.template values<2, false, false>(hessians, tmp1);
1699 eval1.template values<1, false, false>(tmp1, tmp2);
1701 if (add_into_values_array)
1702 eval0.template hessians<0, false, true>(tmp2, values_dofs);
1704 eval0.template hessians<0, false, false>(tmp2, values_dofs);
1707 eval2.template values<2, false, false>(hessians + 3 * n_points,
1709 eval1.template gradients<1, false, false>(tmp1, tmp2);
1711 eval2.template gradients<2, false, false>(hessians + 4 * n_points,
1713 eval1.template values<1, false, true>(tmp1, tmp2);
1714 eval1.template values<0, false, true>(tmp2, values_dofs);
1717 eval2.template values<2, false, false>(hessians + n_points, tmp1);
1718 eval1.template hessians<1, false, false>(tmp1, tmp2);
1721 eval2.template gradients<2, false, false>(hessians + 5 * n_points,
1723 eval1.template gradients<1, false, true>(tmp1, tmp2);
1726 eval2.template hessians<2, false, false>(hessians + 2 * n_points,
1728 eval1.template values<1, false, true>(tmp1, tmp2);
1729 eval0.template values<0, false, true>(tmp2, values_dofs);
1735 "Only 1d, 2d and 3d implemented for Hessian"));
1753 template <
int dim,
int fe_degree,
typename Number>
1768 const Number *values_dofs,
1771 constexpr std::size_t n_points =
Utilities::pow(fe_degree + 1, dim);
1773 for (
unsigned int c = 0; c < n_components; ++c)
1776 for (
unsigned int i = 0; i < n_points; ++i)
1778 values_dofs[n_points * c + i];
1781 evaluate_gradients_collocation<fe_degree + 1, dim>(
1783 values_dofs + c * n_points,
1791 Number *values_dofs,
1793 const bool add_into_values_array)
1795 constexpr std::size_t n_points =
Utilities::pow(fe_degree + 1, dim);
1797 for (
unsigned int c = 0; c < n_components; ++c)
1801 if (add_into_values_array)
1802 for (
unsigned int i = 0; i < n_points; ++i)
1803 values_dofs[n_points * c + i] +=
1806 for (
unsigned int i = 0; i < n_points; ++i)
1807 values_dofs[n_points * c + i] =
1812 integrate_gradients_collocation<fe_degree + 1, dim>(
1814 values_dofs + c * n_points,
1816 add_into_values_array ||
1834 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
1840 const Number *values_dofs,
1845 Assert(n_q_points_1d > fe_degree,
1846 ExcMessage(
"You lose information when going to a collocation "
1847 "space of lower degree, so the evaluation results "
1848 "would be wrong. Thus, this class does not permit "
1849 "the chosen operation."));
1850 constexpr std::size_t n_dofs =
Utilities::pow(fe_degree + 1, dim);
1851 constexpr std::size_t n_q_points =
Utilities::pow(n_q_points_1d, dim);
1853 for (
unsigned int c = 0; c < n_components; ++c)
1859 (fe_degree >= n_q_points_1d ? n_q_points_1d : fe_degree + 1),
1860 n_q_points_1d>::do_forward(1,
1861 shape_data.shape_values_eo,
1862 values_dofs + c * n_dofs,
1867 evaluate_gradients_collocation<n_q_points_1d, dim>(
1877 Number *values_dofs,
1879 const bool add_into_values_array)
1883 Assert(n_q_points_1d > fe_degree,
1884 ExcMessage(
"You lose information when going to a collocation "
1885 "space of lower degree, so the evaluation results "
1886 "would be wrong. Thus, this class does not permit "
1887 "the chosen operation."));
1888 constexpr std::size_t n_q_points =
Utilities::pow(n_q_points_1d, dim);
1890 for (
unsigned int c = 0; c < n_components; ++c)
1894 integrate_gradients_collocation<n_q_points_1d, dim>(
1906 (fe_degree >= n_q_points_1d ? n_q_points_1d : fe_degree + 1),
1907 n_q_points_1d>::do_backward(1,
1908 shape_data.shape_values_eo,
1909 add_into_values_array,
1924 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
1934 template <
bool integrate>
1936 evaluate_or_integrate(
1938 Number *values_dofs_actual,
1940 const bool add_into_values_array =
false);
1945 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
1946 template <
bool integrate>
1953 evaluate_or_integrate(
1955 Number *values_dofs,
1959 Assert(dim == 2 || dim == 3,
1960 ExcMessage(
"Only dim = 2,3 implemented for Raviart-Thomas "
1961 "evaluation/integration"));
1975 const unsigned int dofs_per_component =
1977 const unsigned int n_points =
Utilities::pow(n_q_points_1d, dim);
1988 integrate_gradients_collocation<n_q_points_1d, dim>(shape_data[0],
1992 if constexpr (dim > 2)
1993 eval.template tangential<2, 0>(shape_data[1], values, values);
1994 eval.template tangential<1, 0>(shape_data[1], values, values);
1995 eval.template normal<0>(shape_data[0], values, values_dofs, add);
1998 gradients += n_points * dim;
1999 values_dofs += dofs_per_component;
2002 integrate_gradients_collocation<n_q_points_1d, dim>(shape_data[0],
2006 if constexpr (dim > 2)
2007 eval.template tangential<2, 1>(shape_data[1], values, values);
2008 eval.template tangential<0, 1>(shape_data[1], values, values);
2009 eval.template normal<1>(shape_data[0], values, values_dofs, add);
2011 if constexpr (dim > 2)
2014 gradients += n_points * dim;
2015 values_dofs += dofs_per_component;
2018 integrate_gradients_collocation<n_q_points_1d, dim>(shape_data[0],
2022 eval.template tangential<1, 2>(shape_data[1], values, values);
2023 eval.template tangential<0, 2>(shape_data[1], values, values);
2024 eval.template normal<2>(shape_data[0], values, values_dofs, add);
2031 eval.template normal<0>(shape_data[0], values_dofs, values);
2032 eval.template tangential<1, 0>(shape_data[1], values, values);
2033 if constexpr (dim > 2)
2034 eval.template tangential<2, 0>(shape_data[1], values, values);
2036 evaluate_gradients_collocation<n_q_points_1d, dim>(shape_data[0],
2041 gradients += n_points * dim;
2042 values_dofs += dofs_per_component;
2044 eval.template normal<1>(shape_data[0], values_dofs, values);
2045 eval.template tangential<0, 1>(shape_data[1], values, values);
2046 if constexpr (dim > 2)
2047 eval.template tangential<2, 1>(shape_data[1], values, values);
2049 evaluate_gradients_collocation<n_q_points_1d, dim>(shape_data[0],
2053 if constexpr (dim > 2)
2056 gradients += n_points * dim;
2057 values_dofs += dofs_per_component;
2059 eval.template normal<2>(shape_data[0], values_dofs, values);
2060 eval.template tangential<0, 2>(shape_data[1], values, values);
2061 eval.template tangential<1, 2>(shape_data[1], values, values);
2063 evaluate_gradients_collocation<n_q_points_1d, dim>(shape_data[0],
2076 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
2086 template <
bool integrate>
2088 evaluate_or_integrate(
2090 Number *values_dofs_actual,
2092 const bool add_into_values_array =
false);
2097 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
2098 template <
bool integrate>
2105 evaluate_or_integrate(
2107 Number *values_dofs,
2111 Assert(dim == 2 || dim == 3,
2112 ExcMessage(
"Only dim = 2,3 implemented for Nedelec "
2113 "evaluation/integration"));
2128 const unsigned int dofs_per_component =
2130 const unsigned int n_points =
Utilities::pow(n_q_points_1d, dim);
2145 integrate_gradients_collocation<n_q_points_1d, dim>(shape_data[0],
2150 if constexpr (dim > 2)
2151 eval.template tangential<2, 0>(shape_data[1], values, values);
2152 eval.template tangential<1, 0>(shape_data[1], values, values);
2153 eval.template normal<0>(shape_data[0], values, values_dofs, add);
2158 gradients += n_points * dim;
2159 values_dofs += dofs_per_component;
2162 integrate_gradients_collocation<n_q_points_1d, dim>(shape_data[0],
2167 if constexpr (dim > 2)
2168 eval.template tangential<2, 1>(shape_data[1], values, values);
2169 eval.template tangential<0, 1>(shape_data[1], values, values);
2170 eval.template normal<1>(shape_data[0], values, values_dofs, add);
2172 if constexpr (dim > 2)
2175 gradients += n_points * dim;
2176 values_dofs += dofs_per_component;
2179 integrate_gradients_collocation<n_q_points_1d, dim>(shape_data[0],
2184 eval.template tangential<1, 2>(shape_data[1], values, values);
2185 eval.template tangential<0, 2>(shape_data[1], values, values);
2186 eval.template normal<2>(shape_data[0], values, values_dofs, add);
2197 eval.template normal<0>(shape_data[0], values_dofs, values);
2198 eval.template tangential<1, 0>(shape_data[1], values, values);
2199 if constexpr (dim > 2)
2200 eval.template tangential<2, 0>(shape_data[1], values, values);
2202 evaluate_gradients_collocation<n_q_points_1d, dim>(shape_data[0],
2207 gradients += n_points * dim;
2208 values_dofs += dofs_per_component;
2210 eval.template normal<1>(shape_data[0], values_dofs, values);
2211 eval.template tangential<0, 1>(shape_data[1], values, values);
2212 if constexpr (dim > 2)
2213 eval.template tangential<2, 1>(shape_data[1], values, values);
2215 evaluate_gradients_collocation<n_q_points_1d, dim>(shape_data[0],
2219 if constexpr (dim > 2)
2222 gradients += n_points * dim;
2223 values_dofs += dofs_per_component;
2225 eval.template normal<2>(shape_data[0], values_dofs, values);
2226 eval.template tangential<0, 2>(shape_data[1], values, values);
2227 eval.template tangential<1, 2>(shape_data[1], values, values);
2229 evaluate_gradients_collocation<n_q_points_1d, dim>(shape_data[0],
2253 template <
int dim,
typename Number,
bool do_
integrate>
2256 template <
int fe_degree,
int n_q_po
ints_1d,
typename OtherNumber>
2258 run(
const unsigned int n_components,
2260 OtherNumber *values_dofs,
2262 const bool sum_into_values_array_in =
false)
2266 static_assert(std::is_same_v<Number, std::remove_const_t<OtherNumber>>,
2267 "Type of Number and of OtherNumber do not match.");
2274 element_type == ElementType::tensor_general) ||
2275 element_type == ElementType::tensor_raviart_thomas ||
2276 element_type == ElementType::tensor_nedelec,
2280 bool sum_into_values_array = sum_into_values_array_in;
2286 if constexpr (do_integrate)
2290 integrate_hessians_collocation<n_q_points_1d>(
2299 sum_into_values_array);
2300 sum_into_values_array =
true;
2305 if (fe_degree >= 0 && fe_degree + 1 == n_q_points_1d &&
2306 element_type == ElementType::tensor_symmetric_collocation)
2314 sum_into_values_array);
2318 else if (fe_degree >= 0 &&
2320 element_type <= ElementType::tensor_symmetric)
2331 sum_into_values_array);
2333 else if (fe_degree >= 0 &&
2334 element_type <= ElementType::tensor_symmetric_no_collocation)
2345 sum_into_values_array);
2347 else if (element_type == ElementType::tensor_none)
2355 sum_into_values_array);
2357 else if (element_type == ElementType::tensor_symmetric_plus_dg0)
2364 Number>>(n_components,
2368 sum_into_values_array);
2370 else if (element_type == ElementType::truncated_tensor)
2381 sum_into_values_array);
2383 else if (element_type == ElementType::tensor_raviart_thomas)
2385 if constexpr (fe_degree > 0 && n_q_points_1d > 0 && dim > 1)
2392 template evaluate_or_integrate<do_integrate>(
2394 const_cast<Number *
>(values_dofs),
2396 sum_into_values_array);
2402 "Raviart-Thomas currently only possible "
2403 "in 2d/3d and with templated degree for "
2404 "requested fe_degree and n_q_points_1d. "
2405 "Ensure that the highest used degree for "
2406 "Raviart-Thomas, fe_degree+1=" +
2409 ", does not exceed FE_EVAL_FACTORY_DEGREE_MAX."));
2412 else if (element_type == ElementType::tensor_nedelec)
2414 if constexpr (fe_degree >= 0 && n_q_points_1d > 0 && dim > 1)
2421 template evaluate_or_integrate<do_integrate>(
2423 const_cast<Number *
>(values_dofs),
2425 sum_into_values_array);
2431 "in 2d/3d and with templated degree"));
2445 sum_into_values_array);
2454 evaluate_hessians_collocation<n_q_points_1d>(n_components, fe_eval);
2463 template <
typename T>
2466 const unsigned int n_components,
2468 const Number *values_dofs,
2470 const bool sum_into_values_array,
2471 std::bool_constant<false>)
2473 (void)sum_into_values_array;
2475 T::evaluate(n_components, evaluation_flag, values_dofs, fe_eval);
2478 template <
typename T>
2481 const unsigned int n_components,
2483 Number *values_dofs,
2485 const bool sum_into_values_array,
2486 std::bool_constant<true>)
2488 T::integrate(n_components,
2492 sum_into_values_array);
2495 template <
typename T,
typename OtherNumber>
2498 const unsigned int n_components,
2500 OtherNumber *values_dofs,
2502 const bool sum_into_values_array)
2504 evaluate_or_integrate<T>(n_components,
2508 sum_into_values_array,
2509 std::bool_constant<do_integrate>());
2519 template <
int dim,
typename Number>
2525 template <
int fe_degree,
int = 0>
2527 run(
const unsigned int n_components,
2529 const Number *in_array,
2532 const unsigned int given_degree =
2533 (fe_degree > -1) ? fe_degree :
2536 const unsigned int dofs_per_component =
2556 for (
unsigned int d = 0; d < n_components; ++d)
2558 const Number *in = in_array + d * dofs_per_component;
2559 Number *out = out_array + d * dofs_per_component;
2562 evaluator.template hessians<0, true, false>(in, out);
2564 evaluator.template hessians<1, true, false>(out, out);
2566 evaluator.template hessians<2, true, false>(out, out);
2568 for (
unsigned int q = 0; q < dofs_per_component; ++q)
2570 const Number inverse_JxW_q = Number(1.) / fe_eval.
JxW(q);
2571 for (
unsigned int d = 0; d < n_components; ++d)
2572 out_array[q + d * dofs_per_component] *= inverse_JxW_q;
2574 for (
unsigned int d = 0; d < n_components; ++d)
2576 Number *out = out_array + d * dofs_per_component;
2578 evaluator.template hessians<2, false, false>(out, out);
2580 evaluator.template hessians<1, false, false>(out, out);
2581 evaluator.template hessians<0, false, false>(out, out);
2595 template <
int dim,
typename Number>
2601 template <
int fe_degree,
int = 0>
2603 run(
const unsigned int n_desired_components,
2606 const bool dyadic_coefficients,
2607 const Number *in_array,
2610 const unsigned int given_degree =
2611 (fe_degree > -1) ? fe_degree :
2614 const unsigned int dofs_per_component =
2618 inverse_coefficients.
size() % dofs_per_component == 0,
2620 "Expected diagonal to be a multiple of scalar dof per cells"));
2622 if (!dyadic_coefficients)
2624 if (inverse_coefficients.
size() != dofs_per_component)
2626 inverse_coefficients.
size());
2632 inverse_coefficients.
size());
2652 const Number *in = in_array;
2653 Number *out = out_array;
2655 const Number *inv_coefficient = inverse_coefficients.
data();
2657 const unsigned int shift_coefficient =
2658 inverse_coefficients.
size() > dofs_per_component ? dofs_per_component :
2661 const auto n_comp_outer = dyadic_coefficients ? 1 : n_desired_components;
2662 const auto n_comp_inner = dyadic_coefficients ? n_desired_components : 1;
2664 for (
unsigned int d = 0; d < n_comp_outer; ++d)
2666 for (
unsigned int di = 0; di < n_comp_inner; ++di)
2668 const Number *in_ = in + di * dofs_per_component;
2669 Number *out_ = out + di * dofs_per_component;
2670 evaluator.template hessians<0, true, false>(in_, out_);
2672 evaluator.template hessians<1, true, false>(out_, out_);
2674 evaluator.template hessians<2, true, false>(out_, out_);
2676 if (dyadic_coefficients)
2678 const auto n_coeff_components =
2679 n_desired_components * n_desired_components;
2680 if (n_desired_components == dim)
2682 for (
unsigned int q = 0; q < dofs_per_component; ++q)
2683 vmult<dim>(&inv_coefficient[q * n_coeff_components],
2686 dofs_per_component);
2690 for (
unsigned int q = 0; q < dofs_per_component; ++q)
2691 vmult<-1>(&inv_coefficient[q * n_coeff_components],
2695 n_desired_components);
2699 for (
unsigned int q = 0; q < dofs_per_component; ++q)
2700 out[q] *= inv_coefficient[q];
2702 for (
unsigned int di = 0; di < n_comp_inner; ++di)
2704 Number *out_ = out + di * dofs_per_component;
2706 evaluator.template hessians<2, false, false>(out_, out_);
2708 evaluator.template hessians<1, false, false>(out_, out_);
2709 evaluator.template hessians<0, false, false>(out_, out_);
2712 in += dofs_per_component;
2713 out += dofs_per_component;
2714 inv_coefficient += shift_coefficient;
2721 template <
int n_components>
2723 vmult(
const Number *inverse_coefficients,
2726 const unsigned int dofs_per_component,
2727 const unsigned int n_given_components = 0)
2729 const unsigned int n_desired_components =
2730 (n_components > -1) ? n_components : n_given_components;
2732 std::array<Number, dim + 2> tmp = {};
2733 Assert(n_desired_components <= dim + 2,
2735 "Number of components larger than dim+2 not supported."));
2737 for (
unsigned int d = 0; d < n_desired_components; ++d)
2738 tmp[d] = src[d * dofs_per_component];
2740 for (
unsigned int d1 = 0; d1 < n_desired_components; ++d1)
2742 const Number *inv_coeff_row =
2743 &inverse_coefficients[d1 * n_desired_components];
2744 Number sum = inv_coeff_row[0] * tmp[0];
2745 for (
unsigned int d2 = 1; d2 < n_desired_components; ++d2)
2746 sum += inv_coeff_row[d2] * tmp[d2];
2747 dst[d1 * dofs_per_component] = sum;
2760 template <
int dim,
typename Number>
2763 template <
int fe_degree,
int n_q_po
ints_1d>
2765 run(
const unsigned int n_desired_components,
2767 const Number *in_array,
2770 static const bool do_inplace =
2771 fe_degree > -1 && (fe_degree + 1 == n_q_points_1d);
2777 const auto &inverse_shape =
2782 const std::size_t dofs_per_component =
2785 const std::size_t n_q_points = do_inplace ?
2803 for (
unsigned int d = 0; d < n_desired_components; ++d)
2805 const Number *in = in_array + d * n_q_points;
2806 Number *out = out_array + d * dofs_per_component;
2809 auto *temp_2 = do_inplace ?
2811 (temp_1 +
std::max(n_q_points, dofs_per_component));
2815 evaluator.template hessians<2, false, false>(in, temp_1);
2816 evaluator.template hessians<1, false, false>(temp_1, temp_2);
2817 evaluator.template hessians<0, false, false>(temp_2, out);
2821 evaluator.template hessians<1, false, false>(in, temp_1);
2822 evaluator.template hessians<0, false, false>(temp_1, out);
2825 evaluator.template hessians<0, false, false>(in, out);
value_type * data() const noexcept
ScalarNumber shape_info_number_type
const ShapeInfoType & get_shape_info() const
Number JxW(const unsigned int q_point) const
const Number * begin_gradients() const
ArrayView< Number > get_scratch_data() const
const Number * begin_values() const
const Number * begin_hessians() const
#define DEAL_II_ALWAYS_INLINE
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
static ::ExceptionBase & ExcNotImplemented()
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
@ tensor_symmetric_no_collocation
@ tensor_symmetric_plus_dg0
std::vector< index_type > data
EvaluationFlags
The EvaluationFlags enum.
constexpr T pow(const T base, const int iexp)
void evaluate_hessians_collocation(const unsigned int n_components, FEEvaluationData< dim, Number, false > &fe_eval)
constexpr bool use_collocation_evaluation(const unsigned int fe_degree, const unsigned int n_q_points_1d)
void integrate_gradients_collocation(const MatrixFreeFunctions::UnivariateShapeData< Number2 > &shape, Number *values, const Number *gradients, const bool add_into_values_array)
void evaluate_hessians_slow(const unsigned int n_components, const Number *values_dofs, FEEvaluationData< dim, Number, false > &fe_eval)
std::enable_if_t<(variant==evaluate_general), void > apply_matrix_vector_product(const Number2 *matrix, const Number *in, Number *out)
void integrate_hessians_collocation(const unsigned int n_components, FEEvaluationData< dim, Number, false > &fe_eval, const bool add_into_values_array)
void evaluate_gradients_collocation(const MatrixFreeFunctions::UnivariateShapeData< Number2 > &shape, const Number *values, Number *gradients)
void integrate_hessians_slow(const unsigned int n_components, const FEEvaluationData< dim, Number, false > &fe_eval, Number *values_dofs, const bool add_into_values_array)
constexpr unsigned int invalid_unsigned_int
::VectorizedArray< Number, width > max(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
typename FEEvaluationData< dim, Number, false >::shape_info_number_type Number2
static bool run(const unsigned int n_components, const FEEvaluationData< dim, Number, false > &fe_eval, const Number *in_array, Number *out_array)
typename FEEvaluationData< dim, Number, false >::shape_info_number_type Number2
static bool run(const unsigned int n_desired_components, const FEEvaluationData< dim, Number, false > &fe_eval, const ArrayView< const Number > &inverse_coefficients, const bool dyadic_coefficients, const Number *in_array, Number *out_array)
static void vmult(const Number *inverse_coefficients, const Number *src, Number *dst, const unsigned int dofs_per_component, const unsigned int n_given_components=0)
static void do_backward(const unsigned int n_components, const AlignedVector< Number2 > &transformation_matrix, const bool add_into_result, Number *values_in, Number *values_out, const unsigned int basis_size_1_variable=numbers::invalid_unsigned_int, const unsigned int basis_size_2_variable=numbers::invalid_unsigned_int)
static void do_forward(const unsigned int n_components, const AlignedVector< Number2 > &transformation_matrix, const Number *values_in, Number *values_out, const unsigned int basis_size_1_variable=numbers::invalid_unsigned_int, const unsigned int basis_size_2_variable=numbers::invalid_unsigned_int)
static void do_mass(const unsigned int n_components, const AlignedVector< Number2 > &transformation_matrix, const AlignedVector< Number > &coefficients, const Number *values_in, Number *scratch_data, Number *values_out)
static void evaluate(const unsigned int n_components, const EvaluationFlags::EvaluationFlags evaluation_flag, const Number *values_dofs, FEEvaluationData< dim, Number, false > &fe_eval)
static void integrate(const unsigned int n_components, const EvaluationFlags::EvaluationFlags integration_flag, Number *values_dofs, FEEvaluationData< dim, Number, false > &fe_eval, const bool add_into_values_array)
typename FEEvaluationData< dim, Number, false >::shape_info_number_type Number2
static void evaluate_or_integrate(const unsigned int n_components, const EvaluationFlags::EvaluationFlags evaluation_flag, OtherNumber *values_dofs, FEEvaluationData< dim, Number, false > &fe_eval, const bool sum_into_values_array)
static void evaluate_or_integrate(const unsigned int n_components, const EvaluationFlags::EvaluationFlags evaluation_flag, Number *values_dofs, FEEvaluationData< dim, Number, false > &fe_eval, const bool sum_into_values_array, std::bool_constant< true >)
static bool run(const unsigned int n_components, const EvaluationFlags::EvaluationFlags evaluation_flag, OtherNumber *values_dofs, FEEvaluationData< dim, Number, false > &fe_eval, const bool sum_into_values_array_in=false)
static void evaluate_or_integrate(const unsigned int n_components, const EvaluationFlags::EvaluationFlags evaluation_flag, const Number *values_dofs, FEEvaluationData< dim, Number, false > &fe_eval, const bool sum_into_values_array, std::bool_constant< false >)
typename FEEvaluationData< dim, Number, false >::shape_info_number_type Number2
typename FEEvaluationData< dim, Number, false >::shape_info_number_type Number2
static const EvaluatorVariant variant
typename FEEvaluationData< dim, Number, false >::shape_info_number_type Number2
EvaluatorTensorProduct< variant, dim, fe_degree+1, n_q_points_1d, Number, Number2 > Eval
static void integrate(const unsigned int n_components, const EvaluationFlags::EvaluationFlags integration_flag, Number *values_dofs_actual, FEEvaluationData< dim, Number, false > &fe_eval, const bool add_into_values_array)
static Eval create_evaluator_tensor_product(const MatrixFreeFunctions::UnivariateShapeData< Number2 > *univariate_shape_data)
static void evaluate(const unsigned int n_components, const EvaluationFlags::EvaluationFlags evaluation_flag, const Number *values_dofs_actual, FEEvaluationData< dim, Number, false > &fe_eval)
unsigned int dofs_per_component_on_cell
std::vector< UnivariateShapeData< Number > > data
AlignedVector< Number > shape_values
AlignedVector< Number > shape_values_eo
AlignedVector< Number > shape_hessians_eo
AlignedVector< Number > shape_gradients_collocation_eo
unsigned int n_q_points_1d
AlignedVector< Number > shape_gradients_eo
AlignedVector< Number > shape_hessians
AlignedVector< Number > shape_gradients