14#ifndef dealii_matrix_free_tensor_product_point_kernels_h
15#define dealii_matrix_free_tensor_product_point_kernels_h
38 template <
typename Number,
typename Number2>
44 template <
int dim,
typename Number,
typename Number2>
56 template <
int dim,
typename Number>
62 const unsigned int derivative = 1)
64 const int n_shapes = poly.size();
67 std::array<Number, dim> point;
68 for (
unsigned int d = 0; d < dim; ++d)
70 for (
int i = 0; i < n_shapes; ++i)
71 poly[i].values_of_array(point, derivative, shapes[i].data());
79 template <
typename Number>
98 template <
int dim,
typename Number>
110 const int n_shapes = poly.size();
112 std::array<Number, 2 * dim> point, result;
113 for (
unsigned int d = 0; d < dim; ++d)
115 for (
unsigned int d = 0; d < dim; ++d)
116 point[dim + d] = p1[d];
117 for (
int i = 0; i < n_shapes; ++i)
119 poly[i].values_of_array(point, 0, &result);
120 for (
unsigned int j = 0; j < 2; ++j)
121 for (
unsigned int d = 0; d < dim; ++d)
122 shapes[j * n_shapes + i][0][d] = result[j * dim + d];
136 bool do_renumber =
true,
142 std::array<typename ProductTypeNoPoint<Number, Number2>::type,
145 const std::vector<unsigned int> &renumber,
146 const ::ndarray<Number2, 2, dim> *shapes,
147 const int n_shapes_runtime,
150 static_assert(0 <= dim && dim <= 3,
"Only dim=0,1,2,3 implemented");
151 static_assert(1 <= n_values && n_values <= 2,
152 "Only n_values=1,2 implemented");
154 const int n_shapes = length > 0 ? length : n_shapes_runtime;
159 const Number *values_2 =
161 values + stride * (length > 0 ?
166 std::array<Number3, 2 + n_values> result = {};
167 for (
int i1 = 0; i1 < (dim > 1 ? n_shapes : 1); ++i1)
170 std::array<Number3, 1 + n_values> inner_result = {};
174 if (do_renumber && !renumber.empty())
175 for (
int i0 = 0; i0 < n_shapes; ++i0, ++i)
179 shapes[i0][1][0] * values[renumber[i] * stride];
182 shapes[i0][0][0] * values[renumber[i] * stride];
185 shapes[i0][0][0] * values_2[renumber[i] * stride];
188 for (
int i0 = 0; i0 < n_shapes; ++i0, ++i)
191 inner_result[0] += shapes[i0][1][0] * values[i * stride];
193 inner_result[1] += shapes[i0][0][0] * values[i * stride];
195 inner_result[2] += shapes[i0][0][0] * values_2[i * stride];
202 result[0] += inner_result[0] * shapes[i1][0][1];
203 result[1] += inner_result[1] * shapes[i1][1][1];
205 result[2] += inner_result[1] * shapes[i1][0][1];
207 result[3] += inner_result[2] * shapes[i1][0][1];
212 result[0] = inner_result[0];
214 result[1] = inner_result[1];
216 result[2] = inner_result[2];
232 bool do_renumber =
true,
234 inline std::array<typename ProductTypeNoPoint<Number, Number2>::type,
237 const ::ndarray<Number2, 2, dim> *shapes,
239 const Number *values,
240 const std::vector<unsigned int> &renumber = {})
242 static_assert(0 <= dim && dim <= 3,
"Only dim=0,1,2,3 implemented");
243 static_assert(1 <= n_values && n_values <= 2,
244 "Only n_values=1,2 implemented");
248 std::array<Number3, dim + n_values> result = {};
256 result[1] =
values[1 * stride];
262 for (
int i2 = 0, i = 0; i2 < (dim > 2 ? n_shapes : 1); ++i2)
264 std::array<Number3, 2 + n_values> inner_result;
275 stride>(
values, renumber, shapes, n_shapes, i);
276 else if (n_shapes == 3)
284 stride>(
values, renumber, shapes, n_shapes, i);
285 else if (n_shapes == 4)
293 stride>(
values, renumber, shapes, n_shapes, i);
294 else if (n_shapes == 5)
302 stride>(
values, renumber, shapes, n_shapes, i);
303 else if (n_shapes == 6)
311 stride>(
values, renumber, shapes, n_shapes, i);
320 stride>(
values, renumber, shapes, n_shapes, i);
325 result[0] += inner_result[0] * shapes[i2][0][2];
326 result[1] += inner_result[1] * shapes[i2][0][2];
327 result[2] += inner_result[2] * shapes[i2][1][2];
329 result[3] += inner_result[2] * shapes[i2][0][2];
331 result[4] += inner_result[3] * shapes[i2][0][2];
336 result[0] = inner_result[0];
337 result[1] = inner_result[1];
339 result[2] = inner_result[2];
341 result[3] = inner_result[3];
346 result[0] = inner_result[0];
348 result[1] = inner_result[1];
350 result[2] = inner_result[2];
368 inline std::array<typename ProductTypeNoPoint<Number, Number2>::type,
371 const Number *values,
374 static_assert(0 <= dim && dim <= 3,
"Only dim=0,1,2,3 implemented");
375 static_assert(1 <= n_values && n_values <= 2,
376 "Only n_values=1,2 implemented");
384 std::array<Number3, dim + n_values> result;
388 result[0] = values[0];
390 result[1] = values[1 * stride];
395 result[0] = Number3(values[stride] - values[0]);
397 result[1] = Number3(values[0]) + p[0] * result[0];
399 result[2] = Number3(values[2 * stride]) +
400 p[0] * (values[3 * stride] - values[2 * stride]);
404 const Number3 val10 = Number3(values[stride] - values[0]);
405 const Number3 val32 = Number3(values[3 * stride] - values[2 * stride]);
406 const Number3 tmp0 = Number3(values[0]) + p[0] * val10;
407 const Number3 tmp1 = Number3(values[2 * stride]) + p[0] * val32;
410 result[0] = val10 + p[1] * (val32 - val10);
411 result[1] = tmp1 - tmp0;
414 result[2] = tmp0 + p[1] * result[1];
418 const Number3 tmp0_2 =
419 Number3(values[4 * stride]) +
420 p[0] * (values[5 * stride] - values[4 * stride]);
421 const Number3 tmp1_2 =
422 Number3(values[6 * stride]) +
423 p[0] * (values[7 * stride] - values[6 * stride]);
424 result[3] = tmp0_2 + p[1] * (tmp1_2 - tmp0_2);
429 const Number3 val10 = Number3(values[stride] - values[0]);
430 const Number3 val32 = Number3(values[3 * stride] - values[2 * stride]);
431 const Number3 tmp0 = Number3(values[0]) + p[0] * val10;
432 const Number3 tmp1 = Number3(values[2 * stride]) + p[0] * val32;
433 const Number3 tmp10 = tmp1 - tmp0;
434 const Number3 tmpy0 = tmp0 + p[1] * tmp10;
436 const Number3 val54 = Number3(values[5 * stride] - values[4 * stride]);
437 const Number3 val76 = Number3(values[7 * stride] - values[6 * stride]);
438 const Number3 tmp2 = Number3(values[4 * stride]) + p[0] * val54;
439 const Number3 tmp3 = Number3(values[6 * stride]) + p[0] * val76;
440 const Number3 tmp32 = tmp3 - tmp2;
441 const Number3 tmpy1 = tmp2 + p[1] * tmp32;
444 result[2] = tmpy1 - tmpy0;
445 result[1] = tmp10 + p[2] * (tmp32 - tmp10);
446 const Number3 tmpz0 = val10 + p[1] * (val32 - val10);
447 result[0] = tmpz0 + p[2] * (val54 + p[1] * (val76 - val54) - tmpz0);
450 result[3] = tmpy0 + p[2] * result[2];
493 template <
int dim,
typename Number,
typename Number2>
501 const bool d_linear =
false,
502 const std::vector<unsigned int> &renumber = {})
506 std::array<Number3, dim + 1> result;
515 std::array<::ndarray<Number2, 2, dim>, 200> shapes;
520 shapes.data(), poly.size(),
values.data(), renumber);
522 return std::make_pair(result[dim],
523 Tensor<1, dim, Number3>(
524 ArrayView<Number3>(result.data(), dim)));
533 bool do_renumber =
true,
541 const std::vector<unsigned int> &renumber,
542 const ::ndarray<Number2, 2, dim> *shapes,
543 const int n_shapes_runtime,
546 const int n_shapes = length > 0 ? length : n_shapes_runtime;
549 for (
int i1 = 0; i1 < (dim > 1 ? n_shapes : 1); ++i1)
556 if (do_renumber && !renumber.empty())
557 for (
int i0 = 0; i0 < n_shapes; ++i0, ++i)
558 value += shapes[i0][0][0] * values[renumber[i] * stride];
560 for (
int i0 = 0; i0 < n_shapes; ++i0, ++i)
561 value += shapes[i0][0][0] * values[i * stride];
564 result +=
value * shapes[i1][0][1];
576 bool do_renumber =
true,
580 const ::ndarray<Number2, 2, dim> *shapes,
582 const Number *values,
583 const std::vector<unsigned int> &renumber = {})
585 static_assert(dim >= 0 && dim <= 3,
"Only dim=0,1,2,3 implemented");
598 for (
int i2 = 0, i = 0; i2 < (dim > 2 ? n_shapes : 1); ++i2)
600 Number3 inner_result;
610 values, renumber, shapes, n_shapes, i);
611 else if (n_shapes == 3)
618 values, renumber, shapes, n_shapes, i);
619 else if (n_shapes == 4)
626 values, renumber, shapes, n_shapes, i);
627 else if (n_shapes == 5)
634 values, renumber, shapes, n_shapes, i);
635 else if (n_shapes == 6)
642 values, renumber, shapes, n_shapes, i);
650 values, renumber, shapes, n_shapes, i);
654 result += inner_result * shapes[i2][0][2];
658 result = inner_result;
667 template <
int dim,
typename Number,
typename Number2,
int str
ide = 1>
672 static_assert(dim >= 0 && dim <= 3,
"Only dim=0,1,2,3 implemented");
683 return Number3(values[0]) + p[0] * Number3(values[stride] - values[0]);
687 const Number3 val10 = Number3(values[stride] - values[0]);
688 const Number3 val32 = Number3(values[3 * stride] - values[2 * stride]);
689 const Number3 tmp0 = Number3(values[0]) + p[0] * val10;
690 const Number3 tmp1 = Number3(values[2 * stride]) + p[0] * val32;
691 return tmp0 + p[1] * (tmp1 - tmp0);
695 const Number3 val10 = Number3(values[stride] - values[0]);
696 const Number3 val32 = Number3(values[3 * stride] - values[2 * stride]);
697 const Number3 tmp0 = Number3(values[0]) + p[0] * val10;
698 const Number3 tmp1 = Number3(values[2 * stride]) + p[0] * val32;
699 const Number3 tmpy0 = tmp0 + p[1] * (tmp1 - tmp0);
701 const Number3 val54 = Number3(values[5 * stride] - values[4 * stride]);
702 const Number3 val76 = Number3(values[7 * stride] - values[6 * stride]);
703 const Number3 tmp2 = Number3(values[4 * stride]) + p[0] * val54;
704 const Number3 tmp3 = Number3(values[6 * stride]) + p[0] * val76;
705 const Number3 tmpy1 = tmp2 + p[1] * (tmp3 - tmp2);
707 return tmpy0 + p[2] * (tmpy1 - tmpy0);
716 template <
int dim,
typename Number,
typename Number2>
722 const bool d_linear =
false,
723 const std::vector<unsigned int> &renumber = {})
733 std::array<::ndarray<Number2, 2, dim>, 200> shapes;
734 const int n_shapes = poly.size();
735 std::array<Number2, dim>
point;
736 for (
unsigned int d = 0;
d < dim; ++
d)
738 for (
int i = 0; i < n_shapes; ++i)
739 poly[i].values_of_array(point, 0, shapes[i].data());
741 shapes.data(), n_shapes,
values.data(), renumber);
752 template <
int derivative_order,
typename Number,
typename Number2>
753 inline Tensor<1, 1, typename ProductTypeNoPoint<Number, Number2>::type>
758 const std::vector<unsigned int> &renumber = {})
762 const int n_shapes = poly.size();
764 Assert(renumber.empty() || renumber.size() == values.size(),
767 std::array<Number2, derivative_order + 1> shapes;
769 if (renumber.empty())
770 for (
int i = 0; i < n_shapes; ++i)
772 poly[i].value(p[0], derivative_order, shapes.data());
773 result[0] += shapes[derivative_order] * values[i];
776 for (
int i = 0; i < n_shapes; ++i)
778 poly[i].value(p[0], derivative_order, shapes.data());
779 result[0] += shapes[derivative_order] *
values[renumber[i]];
790 template <
int derivative_order,
typename Number,
typename Number2>
792 derivative_order + 1,
798 const std::vector<unsigned int> &renumber = {})
801 constexpr int dim = 2;
803 const int n_shapes = poly.size();
805 Assert(renumber.empty() || renumber.size() == values.size(),
811 std::array<Number2, dim> point;
812 for (
unsigned int d = 0; d < dim; ++d)
814 for (
int i = 0; i < n_shapes; ++i)
815 poly[i].values_of_array(point, derivative_order, &shapes[i][0]);
818 for (
int i1 = 0, i = 0; i1 < n_shapes; ++i1)
821 if (renumber.empty())
822 for (
int i0 = 0; i0 < n_shapes; ++i0, ++i)
823 for (
unsigned int d = 0; d <= derivative_order; ++d)
824 result_x[d] += shapes[i0][d][0] * values[i];
826 for (
int i0 = 0; i0 < n_shapes; ++i0, ++i)
827 for (
unsigned int d = 0; d <= derivative_order; ++d)
828 result_x[d] += shapes[i0][d][0] * values[renumber[i]];
830 for (
unsigned int d = 0; d <= derivative_order; ++d)
831 result[d] += shapes[i1][d][1] * result_x[derivative_order - d];
842 template <
int derivative_order,
typename Number,
typename Number2>
844 ((derivative_order + 1) * (derivative_order + 2)) / 2,
850 const std::vector<unsigned int> &renumber = {})
853 constexpr int dim = 3;
854 constexpr int n_derivatives =
855 ((derivative_order + 1) * (derivative_order + 2)) / 2;
857 const int n_shapes = poly.size();
859 Assert(renumber.empty() || renumber.size() == values.size(),
865 std::array<Number2, dim> point;
866 for (
unsigned int d = 0; d < dim; ++d)
868 for (
int i = 0; i < n_shapes; ++i)
869 poly[i].values_of_array(point, derivative_order, &shapes[i][0]);
872 for (
int i2 = 0, i = 0; i2 < n_shapes; ++i2)
875 for (
int i1 = 0; i1 < n_shapes; ++i1)
879 if (renumber.empty())
880 for (
int i0 = 0; i0 < n_shapes; ++i0, ++i)
881 for (
unsigned int d = 0; d <= derivative_order; ++d)
882 result_x[d] += shapes[i0][d][0] * values[i];
884 for (
int i0 = 0; i0 < n_shapes; ++i0, ++i)
885 for (
unsigned int d = 0; d <= derivative_order; ++d)
886 result_x[d] += shapes[i0][d][0] * values[renumber[i]];
892 for (
unsigned int d = 0, c = 0; d <= derivative_order; ++d)
893 for (
unsigned int e = d; e <= derivative_order; ++e, ++c)
895 shapes[i1][e - d][1] * result_x[derivative_order - e];
899 for (
unsigned int d = 0, c = 0;
d <= derivative_order; ++
d)
900 for (
unsigned int e = d;
e <= derivative_order; ++
e, ++c)
901 result[c] += shapes[i2][d][2] * result_xy[c];
908 template <
int dim,
typename Number,
typename Number2>
909 SymmetricTensor<2, dim, typename ProductTypeNoPoint<Number, Number2>::type>
914 const std::vector<unsigned int> &renumber = {})
916 static_assert(dim >= 1 && dim <= 3,
"Only dim=1,2,3 implemented");
929 for (
unsigned int d = 0, c = 0; d < 2; ++d)
930 for (
unsigned int e = d; e < 2; ++e, ++c)
934 for (
unsigned int d = 0; d < 2; ++d)
961 const ::ndarray<Number, 2, dim> *shapes,
962 const std::array<Number2, 2 + n_values> &test_grads_value,
963 const int n_shapes_runtime,
966 static_assert(0 <= dim && dim <= 3,
"Only dim=0,1,2,3 implemented");
967 static_assert(1 <= n_values && n_values <= 2,
968 "Only n_values=1,2 implemented");
974 constexpr unsigned int array_size = length > 0 ? length : 1;
975 std::array<Number, array_size> shape_values_x;
976 std::array<Number, array_size> shape_derivs_x;
977 for (
unsigned int j = 0; j < array_size; ++j)
979 shape_values_x[j] = shapes[j][0][0];
980 shape_derivs_x[j] = shapes[j][1][0];
982 for (
int i1 = 0; i1 < (dim > 1 ? length : 1); ++i1)
984 const Number2 test_value_y =
985 dim > 1 ? (test_grads_value[2] * shapes[i1][0][1] +
986 test_grads_value[1] * shapes[i1][1][1]) :
988 const Number2 test_grad_xy =
989 dim > 1 ? test_grads_value[0] * shapes[i1][0][1] :
991 Number2 test_value_y_2;
993 test_value_y_2 = dim > 1 ?
994 test_grads_value[3] * shapes[i1][0][1] :
997 Number2 *values_ptr = values + i + i1 * length;
998 Number2 *values_ptr_2 =
999 n_values > 1 ? values_ptr +
Utilities::pow(length, dim) :
nullptr;
1000 for (
int i0 = 0; i0 < length; ++i0)
1003 values_ptr[i0] += shape_values_x[i0] * test_value_y;
1005 values_ptr[i0] = shape_values_x[i0] * test_value_y;
1006 values_ptr[i0] += shape_derivs_x[i0] * test_grad_xy;
1010 values_ptr_2[i0] += shape_values_x[i0] * test_value_y_2;
1012 values_ptr_2[i0] = shape_values_x[i0] * test_value_y_2;
1016 i += (dim > 1 ? length * length : length);
1020 for (
int i1 = 0; i1 < (dim > 1 ? n_shapes_runtime : 1); ++i1)
1022 const Number2 test_value_y =
1023 dim > 1 ? (test_grads_value[2] * shapes[i1][0][1] +
1024 test_grads_value[1] * shapes[i1][1][1]) :
1025 test_grads_value[2];
1026 const Number2 test_grad_xy =
1027 dim > 1 ? test_grads_value[0] * shapes[i1][0][1] :
1028 test_grads_value[0];
1029 Number2 test_value_y_2;
1031 test_value_y_2 = dim > 1 ?
1032 test_grads_value[3] * shapes[i1][0][1] :
1033 test_grads_value[3];
1035 Number2 *values_ptr = values + i + i1 * n_shapes_runtime;
1036 Number2 *values_ptr_2 =
1040 for (
int i0 = 0; i0 < n_shapes_runtime; ++i0)
1043 values_ptr[i0] += shapes[i0][0][0] * test_value_y;
1045 values_ptr[i0] = shapes[i0][0][0] * test_value_y;
1046 values_ptr[i0] += shapes[i0][1][0] * test_grad_xy;
1050 values_ptr_2[i0] += shapes[i0][0][0] * test_value_y_2;
1052 values_ptr_2[i0] = shapes[i0][0][0] * test_value_y_2;
1056 i += (dim > 1 ? n_shapes_runtime * n_shapes_runtime : n_shapes_runtime);
1073 const ::ndarray<Number, 2, dim> *shapes,
1075 const Number2 *
value,
1079 static_assert(0 <= dim && dim <= 3,
"Only dim=0,1,2,3 implemented");
1080 static_assert(1 <= n_values && n_values <= 2,
1081 "Only n_values=1,2 implemented");
1088 values[0] +=
value[0];
1090 values[0] =
value[0];
1094 values[1] +=
value[1];
1096 values[1] =
value[1];
1103 std::array<Number2, 2 + n_values> test_grads_value;
1104 for (
int i2 = 0, i = 0; i2 < (dim > 2 ? n_shapes : 1); ++i2)
1107 test_grads_value[0] =
1110 test_grads_value[1] = dim > 2 ?
gradient[1] * shapes[i2][0][2] :
1111 (dim > 1 ?
gradient[1] : Number2());
1113 test_grads_value[2] =
1115 (
value[0] * shapes[i2][0][2] +
gradient[2] * shapes[i2][1][2]) :
1119 test_grads_value[3] =
1120 dim > 2 ?
value[1] * shapes[i2][0][2] :
value[1];
1125 values, shapes, test_grads_value, n_shapes, i);
1126 else if (n_shapes == 3)
1128 values, shapes, test_grads_value, n_shapes, i);
1129 else if (n_shapes == 4)
1131 values, shapes, test_grads_value, n_shapes, i);
1132 else if (n_shapes == 5)
1134 values, shapes, test_grads_value, n_shapes, i);
1135 else if (n_shapes == 6)
1137 values, shapes, test_grads_value, n_shapes, i);
1140 values, shapes, test_grads_value, n_shapes, i);
1157 const Number2 *
value,
1162 static_assert(0 <= dim && dim <= 3,
"Only dim=0,1,2,3 implemented");
1163 static_assert(1 <= n_values && n_values <= 2,
1164 "Only n_values=1,2 implemented");
1171 values[0] +=
value[0];
1173 values[0] =
value[0];
1177 values[1] +=
value[1];
1179 values[1] =
value[1];
1187 values[0] +=
value[0] - difference;
1188 values[1] += difference;
1192 values[0] =
value[0] - difference;
1193 values[1] = difference;
1197 const Number2 product =
value[1] * p[0];
1200 values[2] +=
value[1] - product;
1201 values[3] += product;
1205 values[2] =
value[1] - product;
1206 values[3] = product;
1212 const Number2 test_value_y1 =
value[0] * p[1] +
gradient[1];
1213 const Number2 test_value_y0 =
value[0] - test_value_y1;
1214 const Number2 test_grad_xy1 =
gradient[0] * p[1];
1215 const Number2 test_grad_xy0 =
gradient[0] - test_grad_xy1;
1216 const Number2 value0 = p[0] * test_value_y0 + test_grad_xy0;
1217 const Number2 value1 = p[0] * test_value_y1 + test_grad_xy1;
1221 values[0] += test_value_y0 - value0;
1222 values[1] += value0;
1223 values[2] += test_value_y1 - value1;
1224 values[3] += value1;
1228 values[0] = test_value_y0 - value0;
1230 values[2] = test_value_y1 - value1;
1236 const Number2 test_value_y1_2 =
value[1] * p[1];
1237 const Number2 test_value_y0_2 =
value[1] - test_value_y1_2;
1238 const Number2 value0_2 = p[0] * test_value_y0_2;
1239 const Number2 value1_2 = p[0] * test_value_y1_2;
1243 values[4] += test_value_y0_2 - value0_2;
1244 values[5] += value0_2;
1245 values[6] += test_value_y1_2 - value1_2;
1246 values[7] += value1_2;
1250 values[4] = test_value_y0_2 - value0_2;
1251 values[5] = value0_2;
1252 values[6] = test_value_y1_2 - value1_2;
1253 values[7] = value1_2;
1261 const Number2 test_value_z1 =
value[0] * p[2] +
gradient[2];
1262 const Number2 test_value_z0 =
value[0] - test_value_z1;
1263 const Number2 test_grad_x1 =
gradient[0] * p[2];
1264 const Number2 test_grad_x0 =
gradient[0] - test_grad_x1;
1265 const Number2 test_grad_y1 =
gradient[1] * p[2];
1266 const Number2 test_grad_y0 =
gradient[1] - test_grad_y1;
1268 const Number2 test_value_y01 = test_value_z0 * p[1] + test_grad_y0;
1269 const Number2 test_value_y00 = test_value_z0 - test_value_y01;
1270 const Number2 test_grad_xy01 = test_grad_x0 * p[1];
1271 const Number2 test_grad_xy00 = test_grad_x0 - test_grad_xy01;
1272 const Number2 test_value_y11 = test_value_z1 * p[1] + test_grad_y1;
1273 const Number2 test_value_y10 = test_value_z1 - test_value_y11;
1274 const Number2 test_grad_xy11 = test_grad_x1 * p[1];
1275 const Number2 test_grad_xy10 = test_grad_x1 - test_grad_xy11;
1277 const Number2 value00 = p[0] * test_value_y00 + test_grad_xy00;
1278 const Number2 value01 = p[0] * test_value_y01 + test_grad_xy01;
1279 const Number2 value10 = p[0] * test_value_y10 + test_grad_xy10;
1280 const Number2 value11 = p[0] * test_value_y11 + test_grad_xy11;
1284 values[0] += test_value_y00 - value00;
1285 values[1] += value00;
1286 values[2] += test_value_y01 - value01;
1287 values[3] += value01;
1288 values[4] += test_value_y10 - value10;
1289 values[5] += value10;
1290 values[6] += test_value_y11 - value11;
1291 values[7] += value11;
1295 values[0] = test_value_y00 - value00;
1296 values[1] = value00;
1297 values[2] = test_value_y01 - value01;
1298 values[3] = value01;
1299 values[4] = test_value_y10 - value10;
1300 values[5] = value10;
1301 values[6] = test_value_y11 - value11;
1302 values[7] = value11;
1314 template <
bool is_linear,
1321 const ::ndarray<Number, 2, dim> *shapes,
1322 const unsigned int n_shapes,
1323 const Number2 *
value,
1370 template <
int dim,
int length,
typename Number2,
typename Number,
bool add>
1378 const ::ndarray<Number, 2, dim> *shapes,
1379 const Number2 &test_value,
1380 const int n_shapes_runtime,
1385 constexpr unsigned int array_size = length > 0 ? length : 1;
1386 std::array<Number, array_size> shape_values_x;
1387 for (
unsigned int i1 = 0; i1 < array_size; ++i1)
1388 shape_values_x[i1] = shapes[i1][0][0];
1389 for (
int i1 = 0; i1 < (dim > 1 ? length : 1); ++i1)
1391 const Number2 test_value_y =
1392 dim > 1 ? test_value * shapes[i1][0][1] : test_value;
1394 Number2 *values_ptr = values + i + i1 * length;
1395 for (
int i0 = 0; i0 < length; ++i0)
1398 values_ptr[i0] += shape_values_x[i0] * test_value_y;
1400 values_ptr[i0] = shape_values_x[i0] * test_value_y;
1403 i += (dim > 1 ? length * length : length);
1407 for (
int i1 = 0; i1 < (dim > 1 ? n_shapes_runtime : 1); ++i1)
1409 const Number2 test_value_y =
1410 dim > 1 ? test_value * shapes[i1][0][1] : test_value;
1412 Number2 *values_ptr = values + i + i1 * n_shapes_runtime;
1413 for (
int i0 = 0; i0 < n_shapes_runtime; ++i0)
1416 values_ptr[i0] += shapes[i0][0][0] * test_value_y;
1418 values_ptr[i0] = shapes[i0][0][0] * test_value_y;
1421 i += (dim > 1 ? n_shapes_runtime * n_shapes_runtime : n_shapes_runtime);
1430 template <
int dim,
typename Number,
typename Number2,
bool add>
1433 const ::ndarray<Number, 2, dim> *shapes,
1435 const Number2 &
value,
1438 static_assert(dim >= 0 && dim <= 3,
"Only dim=0,1,2,3 implemented");
1453 for (
int i2 = 0, i = 0; i2 < (dim > 2 ? n_shapes : 1); ++i2)
1456 test_value = dim > 2 ?
value * shapes[i2][0][2] :
value;
1462 values, shapes, test_value, n_shapes, i);
1463 else if (n_shapes == 3)
1465 values, shapes, test_value, n_shapes, i);
1466 else if (n_shapes == 4)
1468 values, shapes, test_value, n_shapes, i);
1469 else if (n_shapes == 5)
1471 values, shapes, test_value, n_shapes, i);
1472 else if (n_shapes == 6)
1474 values, shapes, test_value, n_shapes, i);
1477 values, shapes, test_value, n_shapes, i);
1487 template <
int dim,
typename Number,
typename Number2,
bool add>
1493 static_assert(dim >= 0 && dim <= 3,
"Only dim=0,1,2,3 implemented");
1504 const auto x0 = Number(1.) - p[0], x1 = p[0];
1508 values[0] +=
value * x0;
1509 values[1] +=
value * x1;
1513 values[0] =
value * x0;
1514 values[1] =
value * x1;
1519 const auto x0 = Number(1.) - p[0], x1 = p[0], y0 = Number(1.) - p[1],
1522 const auto test_value_y0 =
value * y0;
1523 const auto test_value_y1 =
value * y1;
1527 values[0] += x0 * test_value_y0;
1528 values[1] += x1 * test_value_y0;
1529 values[2] += x0 * test_value_y1;
1530 values[3] += x1 * test_value_y1;
1534 values[0] = x0 * test_value_y0;
1535 values[1] = x1 * test_value_y0;
1536 values[2] = x0 * test_value_y1;
1537 values[3] = x1 * test_value_y1;
1542 const auto x0 = Number(1.) - p[0], x1 = p[0], y0 = Number(1.) - p[1],
1543 y1 = p[1], z0 = Number(1.) - p[2], z1 = p[2];
1545 const auto test_value_z0 =
value * z0;
1546 const auto test_value_z1 =
value * z1;
1548 const auto test_value_y00 = test_value_z0 * y0;
1549 const auto test_value_y01 = test_value_z0 * y1;
1550 const auto test_value_y10 = test_value_z1 * y0;
1551 const auto test_value_y11 = test_value_z1 * y1;
1555 values[0] += x0 * test_value_y00;
1556 values[1] += x1 * test_value_y00;
1557 values[2] += x0 * test_value_y01;
1558 values[3] += x1 * test_value_y01;
1559 values[4] += x0 * test_value_y10;
1560 values[5] += x1 * test_value_y10;
1561 values[6] += x0 * test_value_y11;
1562 values[7] += x1 * test_value_y11;
1566 values[0] = x0 * test_value_y00;
1567 values[1] = x1 * test_value_y00;
1568 values[2] = x0 * test_value_y01;
1569 values[3] = x1 * test_value_y01;
1570 values[4] = x0 * test_value_y10;
1571 values[5] = x1 * test_value_y10;
1572 values[6] = x0 * test_value_y11;
1573 values[7] = x1 * test_value_y11;
1585 template <
bool is_linear,
int dim,
typename Number,
typename Number2>
1588 const unsigned int n_shapes,
1589 const Number2 &
value,
#define DEAL_II_ALWAYS_INLINE
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
#define DEAL_II_ASSERT_UNREACHABLE()
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)
const bool IsBlockVector< VectorType >::value
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)
* * * RotationFunction< dim, Number >::RotationFunction Number(dim)
constexpr T fixed_power(const T t)
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