16#ifndef dealii_matrix_free_tensor_product_point_kernels_h
17#define dealii_matrix_free_tensor_product_point_kernels_h
40 template <
typename Number,
typename Number2>
46 template <
int dim,
typename Number,
typename Number2>
58 template <
int dim,
typename Number>
64 const unsigned int derivative = 1)
66 const int n_shapes = poly.size();
69 std::array<Number, dim> point;
70 for (
unsigned int d = 0; d < dim; ++d)
72 for (
int i = 0; i < n_shapes; ++i)
73 poly[i].values_of_array(point, derivative, shapes[i].
data());
81 template <
typename Number>
100 template <
int dim,
typename Number>
112 const int n_shapes = poly.size();
114 std::array<Number, 2 * dim> point, result;
115 for (
unsigned int d = 0; d < dim; ++d)
117 for (
unsigned int d = 0; d < dim; ++d)
118 point[dim + d] = p1[d];
119 for (
int i = 0; i < n_shapes; ++i)
121 poly[i].values_of_array(point, 0, &result);
122 for (
unsigned int j = 0; j < 2; ++j)
123 for (
unsigned int d = 0; d < dim; ++d)
124 shapes[j * n_shapes + i][0][d] = result[j * dim + d];
138 bool do_renumber =
true,
144 std::array<typename ProductTypeNoPoint<Number, Number2>::type,
147 const std::vector<unsigned int> &renumber,
148 const ::ndarray<Number2, 2, dim> *shapes,
149 const int n_shapes_runtime,
152 static_assert(0 <= dim && dim <= 3,
"Only dim=0,1,2,3 implemented");
153 static_assert(1 <= n_values && n_values <= 2,
154 "Only n_values=1,2 implemented");
156 const int n_shapes = length > 0 ? length : n_shapes_runtime;
161 const Number *values_2 =
163 values + stride * (length > 0 ?
165 Utilities::fixed_power<dim>(n_shapes_runtime)) :
168 std::array<Number3, 2 + n_values> result = {};
169 for (
int i1 = 0; i1 < (dim > 1 ? n_shapes : 1); ++i1)
172 std::array<Number3, 1 + n_values> inner_result = {};
176 if (do_renumber && !renumber.empty())
177 for (
int i0 = 0; i0 < n_shapes; ++i0, ++i)
181 shapes[i0][1][0] * values[renumber[i] * stride];
184 shapes[i0][0][0] * values[renumber[i] * stride];
187 shapes[i0][0][0] * values_2[renumber[i] * stride];
190 for (
int i0 = 0; i0 < n_shapes; ++i0, ++i)
193 inner_result[0] += shapes[i0][1][0] * values[i * stride];
195 inner_result[1] += shapes[i0][0][0] * values[i * stride];
197 inner_result[2] += shapes[i0][0][0] * values_2[i * stride];
204 result[0] += inner_result[0] * shapes[i1][0][1];
205 result[1] += inner_result[1] * shapes[i1][1][1];
207 result[2] += inner_result[1] * shapes[i1][0][1];
209 result[3] += inner_result[2] * shapes[i1][0][1];
214 result[0] = inner_result[0];
216 result[1] = inner_result[1];
218 result[2] = inner_result[2];
234 bool do_renumber =
true,
236 inline std::array<typename ProductTypeNoPoint<Number, Number2>::type,
239 const ::ndarray<Number2, 2, dim> *shapes,
241 const Number *values,
242 const std::vector<unsigned int> &renumber = {})
244 static_assert(0 <= dim && dim <= 3,
"Only dim=0,1,2,3 implemented");
245 static_assert(1 <= n_values && n_values <= 2,
246 "Only n_values=1,2 implemented");
250 std::array<Number3, dim + n_values> result = {};
258 result[1] =
values[1 * stride];
264 for (
int i2 = 0, i = 0; i2 < (dim > 2 ? n_shapes : 1); ++i2)
266 std::array<Number3, 2 + n_values> inner_result;
277 stride>(
values, renumber, shapes, n_shapes, i);
278 else if (n_shapes == 3)
286 stride>(
values, renumber, shapes, n_shapes, i);
287 else if (n_shapes == 4)
295 stride>(
values, renumber, shapes, n_shapes, i);
296 else if (n_shapes == 5)
304 stride>(
values, renumber, shapes, n_shapes, i);
305 else if (n_shapes == 6)
313 stride>(
values, renumber, shapes, n_shapes, i);
322 stride>(
values, renumber, shapes, n_shapes, i);
327 result[0] += inner_result[0] * shapes[i2][0][2];
328 result[1] += inner_result[1] * shapes[i2][0][2];
329 result[2] += inner_result[2] * shapes[i2][1][2];
331 result[3] += inner_result[2] * shapes[i2][0][2];
333 result[4] += inner_result[3] * shapes[i2][0][2];
338 result[0] = inner_result[0];
339 result[1] = inner_result[1];
341 result[2] = inner_result[2];
343 result[3] = inner_result[3];
348 result[0] = inner_result[0];
350 result[1] = inner_result[1];
352 result[2] = inner_result[2];
370 inline std::array<typename ProductTypeNoPoint<Number, Number2>::type,
373 const Number *values,
376 static_assert(0 <= dim && dim <= 3,
"Only dim=0,1,2,3 implemented");
377 static_assert(1 <= n_values && n_values <= 2,
378 "Only n_values=1,2 implemented");
386 std::array<Number3, dim + n_values> result;
390 result[0] = values[0];
392 result[1] = values[1 * stride];
397 result[0] = Number3(values[stride] - values[0]);
399 result[1] = Number3(values[0]) + p[0] * result[0];
401 result[2] = Number3(values[2 * stride]) +
402 p[0] * (values[3 * stride] - values[2 * stride]);
406 const Number3 val10 = Number3(values[stride] - values[0]);
407 const Number3 val32 = Number3(values[3 * stride] - values[2 * stride]);
408 const Number3 tmp0 = Number3(values[0]) + p[0] * val10;
409 const Number3 tmp1 = Number3(values[2 * stride]) + p[0] * val32;
412 result[0] = val10 + p[1] * (val32 - val10);
413 result[1] = tmp1 - tmp0;
416 result[2] = tmp0 + p[1] * result[1];
420 const Number3 tmp0_2 =
421 Number3(values[4 * stride]) +
422 p[0] * (values[5 * stride] - values[4 * stride]);
423 const Number3 tmp1_2 =
424 Number3(values[6 * stride]) +
425 p[0] * (values[7 * stride] - values[6 * stride]);
426 result[3] = tmp0_2 + p[1] * (tmp1_2 - tmp0_2);
431 const Number3 val10 = Number3(values[stride] - values[0]);
432 const Number3 val32 = Number3(values[3 * stride] - values[2 * stride]);
433 const Number3 tmp0 = Number3(values[0]) + p[0] * val10;
434 const Number3 tmp1 = Number3(values[2 * stride]) + p[0] * val32;
435 const Number3 tmp10 = tmp1 - tmp0;
436 const Number3 tmpy0 = tmp0 + p[1] * tmp10;
438 const Number3 val54 = Number3(values[5 * stride] - values[4 * stride]);
439 const Number3 val76 = Number3(values[7 * stride] - values[6 * stride]);
440 const Number3 tmp2 = Number3(values[4 * stride]) + p[0] * val54;
441 const Number3 tmp3 = Number3(values[6 * stride]) + p[0] * val76;
442 const Number3 tmp32 = tmp3 - tmp2;
443 const Number3 tmpy1 = tmp2 + p[1] * tmp32;
446 result[2] = tmpy1 - tmpy0;
447 result[1] = tmp10 + p[2] * (tmp32 - tmp10);
448 const Number3 tmpz0 = val10 + p[1] * (val32 - val10);
449 result[0] = tmpz0 + p[2] * (val54 + p[1] * (val76 - val54) - tmpz0);
452 result[3] = tmpy0 + p[2] * result[2];
495 template <
int dim,
typename Number,
typename Number2>
503 const bool d_linear =
false,
504 const std::vector<unsigned int> &renumber = {})
508 std::array<Number3, dim + 1> result;
517 std::array<::ndarray<Number2, 2, dim>, 200> shapes;
522 shapes.data(), poly.size(),
values.data(), renumber);
524 return std::make_pair(result[dim],
535 bool do_renumber =
true,
543 const std::vector<unsigned int> &renumber,
544 const ::ndarray<Number2, 2, dim> *shapes,
545 const int n_shapes_runtime,
548 const int n_shapes = length > 0 ? length : n_shapes_runtime;
551 for (
int i1 = 0; i1 < (dim > 1 ? n_shapes : 1); ++i1)
558 if (do_renumber && !renumber.empty())
559 for (
int i0 = 0; i0 < n_shapes; ++i0, ++i)
560 value += shapes[i0][0][0] * values[renumber[i] * stride];
562 for (
int i0 = 0; i0 < n_shapes; ++i0, ++i)
563 value += shapes[i0][0][0] * values[i * stride];
566 result +=
value * shapes[i1][0][1];
578 bool do_renumber =
true,
582 const ::ndarray<Number2, 2, dim> *shapes,
584 const Number *values,
585 const std::vector<unsigned int> &renumber = {})
587 static_assert(dim >= 0 && dim <= 3,
"Only dim=0,1,2,3 implemented");
600 for (
int i2 = 0, i = 0; i2 < (dim > 2 ? n_shapes : 1); ++i2)
602 Number3 inner_result;
612 values, renumber, shapes, n_shapes, i);
613 else if (n_shapes == 3)
620 values, renumber, shapes, n_shapes, i);
621 else if (n_shapes == 4)
628 values, renumber, shapes, n_shapes, i);
629 else if (n_shapes == 5)
636 values, renumber, shapes, n_shapes, i);
637 else if (n_shapes == 6)
644 values, renumber, shapes, n_shapes, i);
652 values, renumber, shapes, n_shapes, i);
656 result += inner_result * shapes[i2][0][2];
660 result = inner_result;
669 template <
int dim,
typename Number,
typename Number2,
int str
ide = 1>
674 static_assert(dim >= 0 && dim <= 3,
"Only dim=0,1,2,3 implemented");
685 return Number3(values[0]) + p[0] * Number3(values[stride] - values[0]);
689 const Number3 val10 = Number3(values[stride] - values[0]);
690 const Number3 val32 = Number3(values[3 * stride] - values[2 * stride]);
691 const Number3 tmp0 = Number3(values[0]) + p[0] * val10;
692 const Number3 tmp1 = Number3(values[2 * stride]) + p[0] * val32;
693 return tmp0 + p[1] * (tmp1 - tmp0);
697 const Number3 val10 = Number3(values[stride] - values[0]);
698 const Number3 val32 = Number3(values[3 * stride] - values[2 * stride]);
699 const Number3 tmp0 = Number3(values[0]) + p[0] * val10;
700 const Number3 tmp1 = Number3(values[2 * stride]) + p[0] * val32;
701 const Number3 tmpy0 = tmp0 + p[1] * (tmp1 - tmp0);
703 const Number3 val54 = Number3(values[5 * stride] - values[4 * stride]);
704 const Number3 val76 = Number3(values[7 * stride] - values[6 * stride]);
705 const Number3 tmp2 = Number3(values[4 * stride]) + p[0] * val54;
706 const Number3 tmp3 = Number3(values[6 * stride]) + p[0] * val76;
707 const Number3 tmpy1 = tmp2 + p[1] * (tmp3 - tmp2);
709 return tmpy0 + p[2] * (tmpy1 - tmpy0);
718 template <
int dim,
typename Number,
typename Number2>
724 const bool d_linear =
false,
725 const std::vector<unsigned int> &renumber = {})
735 std::array<::ndarray<Number2, 2, dim>, 200> shapes;
736 const int n_shapes = poly.size();
737 std::array<Number2, dim>
point;
738 for (
unsigned int d = 0;
d < dim; ++
d)
740 for (
int i = 0; i < n_shapes; ++i)
741 poly[i].values_of_array(point, 0, shapes[i].
data());
742 result = evaluate_tensor_product_value_shapes<dim, Number, Number2>(
743 shapes.data(), n_shapes,
values.data(), renumber);
754 template <
int derivative_order,
typename Number,
typename Number2>
760 const std::vector<unsigned int> &renumber = {})
764 const int n_shapes = poly.size();
766 Assert(renumber.empty() || renumber.size() == values.size(),
769 std::array<Number2, derivative_order + 1> shapes;
771 if (renumber.empty())
772 for (
int i = 0; i < n_shapes; ++i)
774 poly[i].value(p[0], derivative_order, shapes.data());
775 result[0] += shapes[derivative_order] * values[i];
778 for (
int i = 0; i < n_shapes; ++i)
780 poly[i].value(p[0], derivative_order, shapes.data());
781 result[0] += shapes[derivative_order] *
values[renumber[i]];
792 template <
int derivative_order,
typename Number,
typename Number2>
794 derivative_order + 1,
800 const std::vector<unsigned int> &renumber = {})
803 constexpr int dim = 2;
805 const int n_shapes = poly.size();
807 Assert(renumber.empty() || renumber.size() == values.size(),
813 std::array<Number2, dim> point;
814 for (
unsigned int d = 0; d < dim; ++d)
816 for (
int i = 0; i < n_shapes; ++i)
817 poly[i].values_of_array(point, derivative_order, &shapes[i][0]);
820 for (
int i1 = 0, i = 0; i1 < n_shapes; ++i1)
823 if (renumber.empty())
824 for (
int i0 = 0; i0 < n_shapes; ++i0, ++i)
825 for (
unsigned int d = 0; d <= derivative_order; ++d)
826 result_x[d] += shapes[i0][d][0] * values[i];
828 for (
int i0 = 0; i0 < n_shapes; ++i0, ++i)
829 for (
unsigned int d = 0; d <= derivative_order; ++d)
830 result_x[d] += shapes[i0][d][0] * values[renumber[i]];
832 for (
unsigned int d = 0; d <= derivative_order; ++d)
833 result[d] += shapes[i1][d][1] * result_x[derivative_order - d];
844 template <
int derivative_order,
typename Number,
typename Number2>
846 ((derivative_order + 1) * (derivative_order + 2)) / 2,
852 const std::vector<unsigned int> &renumber = {})
855 constexpr int dim = 3;
856 constexpr int n_derivatives =
857 ((derivative_order + 1) * (derivative_order + 2)) / 2;
859 const int n_shapes = poly.size();
861 Assert(renumber.empty() || renumber.size() == values.size(),
867 std::array<Number2, dim> point;
868 for (
unsigned int d = 0; d < dim; ++d)
870 for (
int i = 0; i < n_shapes; ++i)
871 poly[i].values_of_array(point, derivative_order, &shapes[i][0]);
874 for (
int i2 = 0, i = 0; i2 < n_shapes; ++i2)
877 for (
int i1 = 0; i1 < n_shapes; ++i1)
881 if (renumber.empty())
882 for (
int i0 = 0; i0 < n_shapes; ++i0, ++i)
883 for (
unsigned int d = 0; d <= derivative_order; ++d)
884 result_x[d] += shapes[i0][d][0] * values[i];
886 for (
int i0 = 0; i0 < n_shapes; ++i0, ++i)
887 for (
unsigned int d = 0; d <= derivative_order; ++d)
888 result_x[d] += shapes[i0][d][0] * values[renumber[i]];
894 for (
unsigned int d = 0, c = 0; d <= derivative_order; ++d)
895 for (
unsigned int e = d; e <= derivative_order; ++e, ++c)
897 shapes[i1][e - d][1] * result_x[derivative_order - e];
901 for (
unsigned int d = 0, c = 0;
d <= derivative_order; ++
d)
902 for (
unsigned int e = d;
e <= derivative_order; ++
e, ++c)
903 result[c] += shapes[i2][d][2] * result_xy[c];
910 template <
int dim,
typename Number,
typename Number2>
916 const std::vector<unsigned int> &renumber = {})
918 static_assert(dim >= 1 && dim <= 3,
"Only dim=1,2,3 implemented");
921 evaluate_tensor_product_higher_derivatives<2>(poly, values, p, renumber);
931 for (
unsigned int d = 0, c = 0; d < 2; ++d)
932 for (
unsigned int e = d; e < 2; ++e, ++c)
936 for (
unsigned int d = 0; d < 2; ++d)
963 const ::ndarray<Number, 2, dim> *shapes,
964 const std::array<Number2, 2 + n_values> &test_grads_value,
965 const int n_shapes_runtime,
968 static_assert(0 <= dim && dim <= 3,
"Only dim=0,1,2,3 implemented");
969 static_assert(1 <= n_values && n_values <= 2,
970 "Only n_values=1,2 implemented");
976 constexpr unsigned int array_size = length > 0 ? length : 1;
977 std::array<Number, array_size> shape_values_x;
978 std::array<Number, array_size> shape_derivs_x;
979 for (
unsigned int j = 0; j < array_size; ++j)
981 shape_values_x[j] = shapes[j][0][0];
982 shape_derivs_x[j] = shapes[j][1][0];
984 for (
int i1 = 0; i1 < (dim > 1 ? length : 1); ++i1)
986 const Number2 test_value_y =
987 dim > 1 ? (test_grads_value[2] * shapes[i1][0][1] +
988 test_grads_value[1] * shapes[i1][1][1]) :
990 const Number2 test_grad_xy =
991 dim > 1 ? test_grads_value[0] * shapes[i1][0][1] :
993 Number2 test_value_y_2;
995 test_value_y_2 = dim > 1 ?
996 test_grads_value[3] * shapes[i1][0][1] :
999 Number2 *values_ptr = values + i + i1 * length;
1000 Number2 *values_ptr_2 =
1001 n_values > 1 ? values_ptr +
Utilities::pow(length, dim) :
nullptr;
1002 for (
int i0 = 0; i0 < length; ++i0)
1005 values_ptr[i0] += shape_values_x[i0] * test_value_y;
1007 values_ptr[i0] = shape_values_x[i0] * test_value_y;
1008 values_ptr[i0] += shape_derivs_x[i0] * test_grad_xy;
1012 values_ptr_2[i0] += shape_values_x[i0] * test_value_y_2;
1014 values_ptr_2[i0] = shape_values_x[i0] * test_value_y_2;
1018 i += (dim > 1 ? length * length : length);
1022 for (
int i1 = 0; i1 < (dim > 1 ? n_shapes_runtime : 1); ++i1)
1024 const Number2 test_value_y =
1025 dim > 1 ? (test_grads_value[2] * shapes[i1][0][1] +
1026 test_grads_value[1] * shapes[i1][1][1]) :
1027 test_grads_value[2];
1028 const Number2 test_grad_xy =
1029 dim > 1 ? test_grads_value[0] * shapes[i1][0][1] :
1030 test_grads_value[0];
1031 Number2 test_value_y_2;
1033 test_value_y_2 = dim > 1 ?
1034 test_grads_value[3] * shapes[i1][0][1] :
1035 test_grads_value[3];
1037 Number2 *values_ptr = values + i + i1 * n_shapes_runtime;
1038 Number2 *values_ptr_2 =
1040 values_ptr + Utilities::fixed_power<dim>(n_shapes_runtime) :
1042 for (
int i0 = 0; i0 < n_shapes_runtime; ++i0)
1045 values_ptr[i0] += shapes[i0][0][0] * test_value_y;
1047 values_ptr[i0] = shapes[i0][0][0] * test_value_y;
1048 values_ptr[i0] += shapes[i0][1][0] * test_grad_xy;
1052 values_ptr_2[i0] += shapes[i0][0][0] * test_value_y_2;
1054 values_ptr_2[i0] = shapes[i0][0][0] * test_value_y_2;
1058 i += (dim > 1 ? n_shapes_runtime * n_shapes_runtime : n_shapes_runtime);
1075 const ::ndarray<Number, 2, dim> *shapes,
1077 const Number2 *
value,
1081 static_assert(0 <= dim && dim <= 3,
"Only dim=0,1,2,3 implemented");
1082 static_assert(1 <= n_values && n_values <= 2,
1083 "Only n_values=1,2 implemented");
1090 values[0] +=
value[0];
1092 values[0] =
value[0];
1096 values[1] +=
value[1];
1098 values[1] =
value[1];
1105 std::array<Number2, 2 + n_values> test_grads_value;
1106 for (
int i2 = 0, i = 0; i2 < (dim > 2 ? n_shapes : 1); ++i2)
1109 test_grads_value[0] =
1112 test_grads_value[1] = dim > 2 ?
gradient[1] * shapes[i2][0][2] :
1113 (dim > 1 ?
gradient[1] : Number2());
1115 test_grads_value[2] =
1117 (
value[0] * shapes[i2][0][2] +
gradient[2] * shapes[i2][1][2]) :
1121 test_grads_value[3] =
1122 dim > 2 ?
value[1] * shapes[i2][0][2] :
value[1];
1126 do_apply_test_functions_xy<dim, 2, Number2, Number, add, n_values>(
1127 values, shapes, test_grads_value, n_shapes, i);
1128 else if (n_shapes == 3)
1129 do_apply_test_functions_xy<dim, 3, Number2, Number, add, n_values>(
1130 values, shapes, test_grads_value, n_shapes, i);
1131 else if (n_shapes == 4)
1132 do_apply_test_functions_xy<dim, 4, Number2, Number, add, n_values>(
1133 values, shapes, test_grads_value, n_shapes, i);
1134 else if (n_shapes == 5)
1135 do_apply_test_functions_xy<dim, 5, Number2, Number, add, n_values>(
1136 values, shapes, test_grads_value, n_shapes, i);
1137 else if (n_shapes == 6)
1138 do_apply_test_functions_xy<dim, 6, Number2, Number, add, n_values>(
1139 values, shapes, test_grads_value, n_shapes, i);
1142 values, shapes, test_grads_value, n_shapes, i);
1159 const Number2 *
value,
1164 static_assert(0 <= dim && dim <= 3,
"Only dim=0,1,2,3 implemented");
1165 static_assert(1 <= n_values && n_values <= 2,
1166 "Only n_values=1,2 implemented");
1173 values[0] +=
value[0];
1175 values[0] =
value[0];
1179 values[1] +=
value[1];
1181 values[1] =
value[1];
1189 values[0] +=
value[0] - difference;
1190 values[1] += difference;
1194 values[0] =
value[0] - difference;
1195 values[1] = difference;
1199 const Number2 product =
value[1] * p[0];
1202 values[2] +=
value[1] - product;
1203 values[3] += product;
1207 values[2] =
value[1] - product;
1208 values[3] = product;
1214 const Number2 test_value_y1 =
value[0] * p[1] +
gradient[1];
1215 const Number2 test_value_y0 =
value[0] - test_value_y1;
1216 const Number2 test_grad_xy1 =
gradient[0] * p[1];
1217 const Number2 test_grad_xy0 =
gradient[0] - test_grad_xy1;
1218 const Number2 value0 = p[0] * test_value_y0 + test_grad_xy0;
1219 const Number2 value1 = p[0] * test_value_y1 + test_grad_xy1;
1223 values[0] += test_value_y0 - value0;
1224 values[1] += value0;
1225 values[2] += test_value_y1 - value1;
1226 values[3] += value1;
1230 values[0] = test_value_y0 - value0;
1232 values[2] = test_value_y1 - value1;
1238 const Number2 test_value_y1_2 =
value[1] * p[1];
1239 const Number2 test_value_y0_2 =
value[1] - test_value_y1_2;
1240 const Number2 value0_2 = p[0] * test_value_y0_2;
1241 const Number2 value1_2 = p[0] * test_value_y1_2;
1245 values[4] += test_value_y0_2 - value0_2;
1246 values[5] += value0_2;
1247 values[6] += test_value_y1_2 - value1_2;
1248 values[7] += value1_2;
1252 values[4] = test_value_y0_2 - value0_2;
1253 values[5] = value0_2;
1254 values[6] = test_value_y1_2 - value1_2;
1255 values[7] = value1_2;
1263 const Number2 test_value_z1 =
value[0] * p[2] +
gradient[2];
1264 const Number2 test_value_z0 =
value[0] - test_value_z1;
1265 const Number2 test_grad_x1 =
gradient[0] * p[2];
1266 const Number2 test_grad_x0 =
gradient[0] - test_grad_x1;
1267 const Number2 test_grad_y1 =
gradient[1] * p[2];
1268 const Number2 test_grad_y0 =
gradient[1] - test_grad_y1;
1270 const Number2 test_value_y01 = test_value_z0 * p[1] + test_grad_y0;
1271 const Number2 test_value_y00 = test_value_z0 - test_value_y01;
1272 const Number2 test_grad_xy01 = test_grad_x0 * p[1];
1273 const Number2 test_grad_xy00 = test_grad_x0 - test_grad_xy01;
1274 const Number2 test_value_y11 = test_value_z1 * p[1] + test_grad_y1;
1275 const Number2 test_value_y10 = test_value_z1 - test_value_y11;
1276 const Number2 test_grad_xy11 = test_grad_x1 * p[1];
1277 const Number2 test_grad_xy10 = test_grad_x1 - test_grad_xy11;
1279 const Number2 value00 = p[0] * test_value_y00 + test_grad_xy00;
1280 const Number2 value01 = p[0] * test_value_y01 + test_grad_xy01;
1281 const Number2 value10 = p[0] * test_value_y10 + test_grad_xy10;
1282 const Number2 value11 = p[0] * test_value_y11 + test_grad_xy11;
1286 values[0] += test_value_y00 - value00;
1287 values[1] += value00;
1288 values[2] += test_value_y01 - value01;
1289 values[3] += value01;
1290 values[4] += test_value_y10 - value10;
1291 values[5] += value10;
1292 values[6] += test_value_y11 - value11;
1293 values[7] += value11;
1297 values[0] = test_value_y00 - value00;
1298 values[1] = value00;
1299 values[2] = test_value_y01 - value01;
1300 values[3] = value01;
1301 values[4] = test_value_y10 - value10;
1302 values[5] = value10;
1303 values[6] = test_value_y11 - value11;
1304 values[7] = value11;
1316 template <
bool is_linear,
1323 const ::ndarray<Number, 2, dim> *shapes,
1324 const unsigned int n_shapes,
1325 const Number2 *
value,
1372 template <
int dim,
int length,
typename Number2,
typename Number,
bool add>
1380 const ::ndarray<Number, 2, dim> *shapes,
1381 const Number2 &test_value,
1382 const int n_shapes_runtime,
1387 constexpr unsigned int array_size = length > 0 ? length : 1;
1388 std::array<Number, array_size> shape_values_x;
1389 for (
unsigned int i1 = 0; i1 < array_size; ++i1)
1390 shape_values_x[i1] = shapes[i1][0][0];
1391 for (
int i1 = 0; i1 < (dim > 1 ? length : 1); ++i1)
1393 const Number2 test_value_y =
1394 dim > 1 ? test_value * shapes[i1][0][1] : test_value;
1396 Number2 *values_ptr = values + i + i1 * length;
1397 for (
int i0 = 0; i0 < length; ++i0)
1400 values_ptr[i0] += shape_values_x[i0] * test_value_y;
1402 values_ptr[i0] = shape_values_x[i0] * test_value_y;
1405 i += (dim > 1 ? length * length : length);
1409 for (
int i1 = 0; i1 < (dim > 1 ? n_shapes_runtime : 1); ++i1)
1411 const Number2 test_value_y =
1412 dim > 1 ? test_value * shapes[i1][0][1] : test_value;
1414 Number2 *values_ptr = values + i + i1 * n_shapes_runtime;
1415 for (
int i0 = 0; i0 < n_shapes_runtime; ++i0)
1418 values_ptr[i0] += shapes[i0][0][0] * test_value_y;
1420 values_ptr[i0] = shapes[i0][0][0] * test_value_y;
1423 i += (dim > 1 ? n_shapes_runtime * n_shapes_runtime : n_shapes_runtime);
1432 template <
int dim,
typename Number,
typename Number2,
bool add>
1435 const ::ndarray<Number, 2, dim> *shapes,
1437 const Number2 &
value,
1440 static_assert(dim >= 0 && dim <= 3,
"Only dim=0,1,2,3 implemented");
1455 for (
int i2 = 0, i = 0; i2 < (dim > 2 ? n_shapes : 1); ++i2)
1458 test_value = dim > 2 ?
value * shapes[i2][0][2] :
value;
1463 do_apply_test_functions_xy_value<dim, 2, Number2, Number, add>(
1464 values, shapes, test_value, n_shapes, i);
1465 else if (n_shapes == 3)
1466 do_apply_test_functions_xy_value<dim, 3, Number2, Number, add>(
1467 values, shapes, test_value, n_shapes, i);
1468 else if (n_shapes == 4)
1469 do_apply_test_functions_xy_value<dim, 4, Number2, Number, add>(
1470 values, shapes, test_value, n_shapes, i);
1471 else if (n_shapes == 5)
1472 do_apply_test_functions_xy_value<dim, 5, Number2, Number, add>(
1473 values, shapes, test_value, n_shapes, i);
1474 else if (n_shapes == 6)
1475 do_apply_test_functions_xy_value<dim, 6, Number2, Number, add>(
1476 values, shapes, test_value, n_shapes, i);
1479 values, shapes, test_value, n_shapes, i);
1489 template <
int dim,
typename Number,
typename Number2,
bool add>
1495 static_assert(dim >= 0 && dim <= 3,
"Only dim=0,1,2,3 implemented");
1506 const auto x0 = 1. - p[0], x1 = p[0];
1510 values[0] +=
value * x0;
1511 values[1] +=
value * x1;
1515 values[0] =
value * x0;
1516 values[1] =
value * x1;
1521 const auto x0 = 1. - p[0], x1 = p[0], y0 = 1. - p[1], y1 = p[1];
1523 const auto test_value_y0 =
value * y0;
1524 const auto test_value_y1 =
value * y1;
1528 values[0] += x0 * test_value_y0;
1529 values[1] += x1 * test_value_y0;
1530 values[2] += x0 * test_value_y1;
1531 values[3] += x1 * test_value_y1;
1535 values[0] = x0 * test_value_y0;
1536 values[1] = x1 * test_value_y0;
1537 values[2] = x0 * test_value_y1;
1538 values[3] = x1 * test_value_y1;
1543 const auto x0 = 1. - p[0], x1 = p[0], y0 = 1. - p[1], y1 = p[1],
1544 z0 = 1. - p[2], z1 = p[2];
1546 const auto test_value_z0 =
value * z0;
1547 const auto test_value_z1 =
value * z1;
1549 const auto test_value_y00 = test_value_z0 * y0;
1550 const auto test_value_y01 = test_value_z0 * y1;
1551 const auto test_value_y10 = test_value_z1 * y0;
1552 const auto test_value_y11 = test_value_z1 * y1;
1556 values[0] += x0 * test_value_y00;
1557 values[1] += x1 * test_value_y00;
1558 values[2] += x0 * test_value_y01;
1559 values[3] += x1 * test_value_y01;
1560 values[4] += x0 * test_value_y10;
1561 values[5] += x1 * test_value_y10;
1562 values[6] += x0 * test_value_y11;
1563 values[7] += x1 * test_value_y11;
1567 values[0] = x0 * test_value_y00;
1568 values[1] = x1 * test_value_y00;
1569 values[2] = x0 * test_value_y01;
1570 values[3] = x1 * test_value_y01;
1571 values[4] = x0 * test_value_y10;
1572 values[5] = x1 * test_value_y10;
1573 values[6] = x0 * test_value_y11;
1574 values[7] = x1 * test_value_y11;
1586 template <
bool is_linear,
int dim,
typename Number,
typename Number2>
1589 const unsigned int n_shapes,
1590 const Number2 &
value,
#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)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
#define DEAL_II_ASSERT_UNREACHABLE()
std::vector< index_type > data
Point< spacedim > point(const gp_Pnt &p, const double tolerance=1e-10)
SymmetricTensor< 2, dim, Number > e(const Tensor< 2, dim, Number > &F)
SymmetricTensor< 2, dim, Number > d(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
constexpr T pow(const T base, const int iexp)
std::array< typename ProductTypeNoPoint< Number, Number2 >::type, dim+n_values > evaluate_tensor_product_value_and_gradient_shapes(const ::ndarray< Number2, 2, dim > *shapes, const int n_shapes, const Number *values, const std::vector< unsigned int > &renumber={})
std::array< typename ProductTypeNoPoint< Number, Number2 >::type, 2+n_values > do_interpolate_xy(const Number *values, const std::vector< unsigned int > &renumber, const ::ndarray< Number2, 2, dim > *shapes, const int n_shapes_runtime, int &i)
void integrate_add_tensor_product_value_linear(const Number2 &value, Number2 *values, const Point< dim, Number > &p)
void integrate_tensor_product_value_and_gradient(const ::ndarray< Number, 2, dim > *shapes, const unsigned int n_shapes, const Number2 *value, const Tensor< 1, dim, Number2 > &gradient, Number2 *values, const Point< dim, Number > &p, const bool do_add)
void do_apply_test_functions_xy_value(Number2 *values, const ::ndarray< Number, 2, dim > *shapes, const Number2 &test_value, const int n_shapes_runtime, int &i)
void compute_values_of_array_in_pairs(::ndarray< Number, 2, dim > *shapes, const std::vector< Polynomials::Polynomial< double > > &poly, const Point< dim, Number > &p0, const Point< dim, Number > &p1)
void integrate_add_tensor_product_value_and_gradient_linear(const Number2 *value, const Tensor< 1, dim, Number2 > &gradient, Number2 *values, const Point< dim, Number > &p)
void integrate_add_tensor_product_value_shapes(const ::ndarray< Number, 2, dim > *shapes, const int n_shapes, const Number2 &value, Number2 *values)
SymmetricTensor< 2, dim, typename ProductTypeNoPoint< Number, Number2 >::type > evaluate_tensor_product_hessian(const std::vector< Polynomials::Polynomial< double > > &poly, const ArrayView< const Number > &values, const Point< dim, Number2 > &p, const std::vector< unsigned int > &renumber={})
ProductTypeNoPoint< Number, Number2 >::type evaluate_tensor_product_value_shapes(const ::ndarray< Number2, 2, dim > *shapes, const int n_shapes, const Number *values, const std::vector< unsigned int > &renumber={})
void compute_values_of_array(::ndarray< Number, 2, dim > *shapes, const std::vector< Polynomials::Polynomial< double > > &poly, const Point< dim, Number > &p, const unsigned int derivative=1)
void integrate_add_tensor_product_value_and_gradient_shapes(const ::ndarray< Number, 2, dim > *shapes, const int n_shapes, const Number2 *value, const Tensor< 1, dim, Number2 > &gradient, Number2 *values)
std::pair< typename ProductTypeNoPoint< Number, Number2 >::type, Tensor< 1, dim, typename ProductTypeNoPoint< Number, Number2 >::type > > evaluate_tensor_product_value_and_gradient(const std::vector< Polynomials::Polynomial< double > > &poly, const ArrayView< const Number > &values, const Point< dim, Number2 > &p, const bool d_linear=false, const std::vector< unsigned int > &renumber={})
void do_apply_test_functions_xy(Number2 *values, const ::ndarray< Number, 2, dim > *shapes, const std::array< Number2, 2+n_values > &test_grads_value, const int n_shapes_runtime, int &i)
ProductTypeNoPoint< Number, Number2 >::type evaluate_tensor_product_value_linear(const Number *values, const Point< dim, Number2 > &p)
std::array< typename ProductTypeNoPoint< Number, Number2 >::type, dim+n_values > evaluate_tensor_product_value_and_gradient_linear(const Number *values, const Point< dim, Number2 > &p)
ProductTypeNoPoint< Number, Number2 >::type evaluate_tensor_product_value(const std::vector< Polynomials::Polynomial< double > > &poly, const ArrayView< const Number > &values, const Point< dim, Number2 > &p, const bool d_linear=false, const std::vector< unsigned int > &renumber={})
Tensor< 1, 1, typename ProductTypeNoPoint< Number, Number2 >::type > evaluate_tensor_product_higher_derivatives(const std::vector< Polynomials::Polynomial< double > > &poly, const ArrayView< const Number > &values, const Point< 1, Number2 > &p, const std::vector< unsigned int > &renumber={})
void integrate_tensor_product_value(const ::ndarray< Number, 2, dim > *shapes, const unsigned int n_shapes, const Number2 &value, Number2 *values, const Point< dim, Number > &p, const bool do_add)
ProductTypeNoPoint< Number, Number2 >::type do_interpolate_xy_value(const Number *values, const std::vector< unsigned int > &renumber, const ::ndarray< Number2, 2, dim > *shapes, const int n_shapes_runtime, int &i)
typename internal::ndarray::HelperArray< T, Ns... >::type ndarray
typename internal::ProductTypeImpl< std::decay_t< T >, std::decay_t< U > >::type type
typename ProductType< Tensor< 1, dim, Number >, Number2 >::type type
typename ProductType< Number, Number2 >::type type