deal.II version GIT relicensing-6834-g5b78e6bcdf 2026-10-01 11:20:01+00:00
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
Loading...
Searching...
No Matches
fe_point_evaluation.h
Go to the documentation of this file.
1// -----------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception OR LGPL-2.1-or-later
4// Copyright (C) 2020 - 2026 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Detailed license information governing the source code and contributions
9// can be found in LICENSE.md and CONTRIBUTING.md at the top level directory.
10//
11// -----------------------------------------------------------------------------
12
13#ifndef dealii_fe_point_evaluation_h
14#define dealii_fe_point_evaluation_h
15
16#include <deal.II/base/config.h>
17
23#include <deal.II/base/tensor.h>
25
27#include <deal.II/fe/mapping.h>
28
34
36
38
39namespace internal
40{
42 {
45 std::string,
46 << "You are requesting information from an FEPointEvaluationBase "
47 << "object for which this kind of information has not been computed. "
48 << "What information these objects compute is determined by the update_* "
49 << "flags you pass to MappingInfo() in the Constructor. Here, "
50 << "the operation you are attempting requires the <" << arg1
51 << "> flag to be set, but it was apparently not specified "
52 << "upon initialization.");
53
58 template <int dim,
59 int spacedim,
60 int n_components,
61 typename Number,
62 typename Enable = void>
64 {
68 typename ::internal::VectorizedArrayTrait<
76 using real_gradient_type = std::conditional_t<
77 n_components == spacedim,
87
88 static void
89 read_value(const ScalarNumber vector_entry,
90 const unsigned int component,
91 scalar_value_type &result)
92 {
93 AssertIndexRange(component, n_components);
94 result[component] = vector_entry;
95 }
96
99 {
100 return result;
101 }
102
103 static scalar_value_type
105 {
106 scalar_value_type result_scalar = {};
107
108 for (unsigned int c = 0; c < n_components; ++c)
109 result_scalar[c] = result[c].sum();
110
111 return result_scalar;
112 }
113
114 static ScalarNumber
115 sum_value(const unsigned int component,
116 const vectorized_value_type &result)
117 {
118 AssertIndexRange(component, n_components);
119 return result[component].sum();
120 }
121
122 static void
124 const unsigned int vector_lane,
125 unit_gradient_type &result)
126 {
127 for (unsigned int i = 0; i < n_components; ++i)
128 for (unsigned int d = 0; d < dim; ++d)
129 result[i][d] =
131 value[d][i], vector_lane);
132 }
133
134 static void
136 const unsigned int vector_lane,
137 const unit_gradient_type &result)
138 {
139 for (unsigned int i = 0; i < n_components; ++i)
140 for (unsigned int d = 0; d < dim; ++d)
142 value[d][i], vector_lane) = result[i][d];
143 }
144
145 static void
147 const unsigned int vector_lane,
149 {
150 for (unsigned int i = 0; i < n_components; ++i)
151 for (unsigned int d = 0; d < dim; ++d)
153 value[d][i], vector_lane) = result[i][d];
154 }
155
156 static void
158 const unsigned int vector_lane)
159 {
160 for (unsigned int i = 0; i < n_components; ++i)
161 for (unsigned int d = 0; d < spacedim; ++d)
163 vector_lane) = 0.;
164 }
165
166 static void
168 const unsigned int vector_lane,
169 scalar_value_type &result)
170 {
171 for (unsigned int i = 0; i < n_components; ++i)
172 result[i] = value[i][vector_lane];
173 }
174
175 static void
177 const unsigned int,
178 vectorized_value_type &result)
179 {
180 result = value;
181 }
182
183 static void
185 const unsigned int vector_lane,
186 const scalar_value_type &result)
187 {
188 for (unsigned int i = 0; i < n_components; ++i)
189 value[i][vector_lane] = result[i];
190 }
191
192 static void
194 const unsigned int,
195 const vectorized_value_type &result)
196 {
197 value = result;
198 }
199
200 static void
201 set_zero_value(value_type &value, const unsigned int vector_lane)
202 {
203 for (unsigned int i = 0; i < n_components; ++i)
205 0.;
206 }
207
208 static void
210 const unsigned int vector_lane,
211 const unsigned int component,
212 const ScalarNumber &shape_value)
213 {
215 vector_lane) += shape_value;
216 }
217
218 static ScalarNumber
220 const unsigned int vector_lane,
221 const unsigned int component)
222 {
224 vector_lane);
225 }
226
227 static void
229 const unsigned int vector_lane,
230 const unsigned int component,
231 const Tensor<1, spacedim, ScalarNumber> &shape_gradient)
232 {
233 for (unsigned int d = 0; d < spacedim; ++d)
235 vector_lane) +=
236 shape_gradient[d];
237 }
238
241 const unsigned int vector_lane,
242 const unsigned int component)
243 {
245 for (unsigned int d = 0; d < spacedim; ++d)
246 result[d] =
248 vector_lane);
249 return result;
250 }
251 };
252
253 template <int dim, int spacedim, typename Number>
254 struct EvaluatorTypeTraits<dim, spacedim, 1, Number>
255 {
259 typename ::internal::VectorizedArrayTrait<
261 using value_type = Number;
271
272 static void
273 read_value(const ScalarNumber vector_entry,
274 const unsigned int,
275 scalar_value_type &result)
276 {
277 result = vector_entry;
278 }
279
280 static scalar_value_type
282 {
283 return result;
284 }
285
286 static scalar_value_type
288 {
289 return result.sum();
290 }
291
292 static ScalarNumber
293 sum_value(const unsigned int, const vectorized_value_type &result)
294 {
295 return result.sum();
296 }
297
298 static void
300 const unsigned int vector_lane,
302 {
303 for (unsigned int d = 0; d < dim; ++d)
304 result[d] = value[d][vector_lane];
305 }
306
307 static void
309 const unsigned int,
311 {
312 result = value;
313 }
314
315 static void
317 const unsigned int vector_lane,
318 const scalar_unit_gradient_type &result)
319 {
320 for (unsigned int d = 0; d < dim; ++d)
321 value[d][vector_lane] = result[d];
322 }
323
324 static void
326 const unsigned int,
327 const vectorized_unit_gradient_type &result)
328 {
329 value = result;
330 }
331
332 static void
334 const unsigned int vector_lane)
335 {
336 for (unsigned int d = 0; d < spacedim; ++d)
338 0.;
339 }
340
341 static void
343 const unsigned int vector_lane,
344 scalar_value_type &result)
345 {
346 result = value[vector_lane];
347 }
348
349 static void
351 const unsigned int,
352 vectorized_value_type &result)
353 {
354 result = value;
355 }
356
357 static void
359 const unsigned int vector_lane,
360 const scalar_value_type &result)
361 {
362 value[vector_lane] = result;
363 }
364
365 static void
367 const unsigned int,
368 const vectorized_value_type &result)
369 {
370 value = result;
371 }
372
373 static void
374 set_zero_value(value_type &value, const unsigned int vector_lane)
375 {
377 }
378
379 static void
381 const unsigned int vector_lane,
382 const unsigned int,
383 const ScalarNumber &shape_value)
384 {
386 shape_value;
387 }
388
389 static ScalarNumber
391 const unsigned int vector_lane,
392 const unsigned int)
393 {
395 }
396
397 static void
399 const unsigned int vector_lane,
400 const unsigned int,
401 const Tensor<1, spacedim, ScalarNumber> &shape_gradient)
402 {
403 for (unsigned int d = 0; d < spacedim; ++d)
405 shape_gradient[d];
406 }
407
410 const unsigned int vector_lane,
411 const unsigned int)
412 {
414 for (unsigned int d = 0; d < spacedim; ++d)
415 result[d] =
417 return result;
418 }
419 };
420
421 template <int dim, typename Number>
423 dim,
424 dim,
425 Number,
426 std::enable_if_t<dim != 1>>
427 {
431 typename ::internal::VectorizedArrayTrait<
443
444 static void
445 read_value(const ScalarNumber vector_entry,
446 const unsigned int component,
447 scalar_value_type &result)
448 {
449 AssertIndexRange(component, dim);
450 result[component] = vector_entry;
451 }
452
453 static scalar_value_type
455 {
456 return result;
457 }
458
459 static scalar_value_type
461 {
462 scalar_value_type result_scalar = {};
463
464 for (unsigned int c = 0; c < dim; ++c)
465 result_scalar[c] = result[c].sum();
466
467 return result_scalar;
468 }
469
470 static ScalarNumber
471 sum_value(const unsigned int component,
472 const vectorized_value_type &result)
473 {
474 AssertIndexRange(component, dim);
475 return result[component].sum();
476 }
477
478 static void
480 const unsigned int vector_lane,
481 unit_gradient_type &result)
482 {
483 for (unsigned int i = 0; i < dim; ++i)
484 for (unsigned int d = 0; d < dim; ++d)
485 result[i][d] =
487 value[d][i], vector_lane);
488 }
489
490 static void
492 const unsigned int vector_lane,
493 const unit_gradient_type &result)
494 {
495 for (unsigned int i = 0; i < dim; ++i)
496 for (unsigned int d = 0; d < dim; ++d)
498 value[d][i], vector_lane) = result[i][d];
499 }
500
501 static void
503 const unsigned int vector_lane)
504 {
505 for (unsigned int i = 0; i < dim; ++i)
506 for (unsigned int d = 0; d < dim; ++d)
508 vector_lane) = 0.;
509 }
510
511 static void
513 const unsigned int vector_lane,
514 scalar_value_type &result)
515 {
516 for (unsigned int i = 0; i < dim; ++i)
517 result[i] = value[i][vector_lane];
518 }
519
520 static void
522 const unsigned int,
523 vectorized_value_type &result)
524 {
525 result = value;
526 }
527
528 static void
530 const unsigned int vector_lane,
531 const scalar_value_type &result)
532 {
533 for (unsigned int i = 0; i < dim; ++i)
534 value[i][vector_lane] = result[i];
535 }
536
537 static void
539 const unsigned int,
540 const vectorized_value_type &result)
541 {
542 value = result;
543 }
544
545 static void
546 set_zero_value(value_type &value, const unsigned int vector_lane)
547 {
548 for (unsigned int i = 0; i < dim; ++i)
550 0.;
551 }
552
553 static void
555 const unsigned int vector_lane,
556 const unsigned int component,
557 const ScalarNumber &shape_value)
558 {
560 vector_lane) += shape_value;
561 }
562
563 static ScalarNumber
565 const unsigned int vector_lane,
566 const unsigned int component)
567 {
569 vector_lane);
570 }
571
572 static void
574 const unsigned int vector_lane,
575 const unsigned int component,
576 const Tensor<1, dim, ScalarNumber> &shape_gradient)
577 {
578 for (unsigned int d = 0; d < dim; ++d)
580 vector_lane) +=
581 shape_gradient[d];
582 }
583
586 const unsigned int vector_lane,
587 const unsigned int component)
588 {
590 for (unsigned int d = 0; d < dim; ++d)
591 result[d] =
593 vector_lane);
594 return result;
595 }
596 };
597
598 template <int dim, int spacedim>
599 bool
601 const unsigned int base_element_number);
602
603 template <int dim, int spacedim>
604 bool
606
607 template <int dim, int spacedim>
608 std::vector<Polynomials::Polynomial<double>>
610 } // namespace FEPointEvaluation
611} // namespace internal
612
613
614
621template <int n_components_,
622 int dim,
623 int spacedim = dim,
624 typename Number = double>
626{
627public:
628 static constexpr unsigned int dimension = dim;
629 static constexpr unsigned int n_components = n_components_;
630
631 using number_type = Number;
632
635 using VectorizedArrayType = typename ::internal::VectorizedArrayTrait<
637 using ETT = typename internal::FEPointEvaluation::
638 EvaluatorTypeTraits<dim, spacedim, n_components, Number>;
639 using value_type = typename ETT::value_type;
640 using scalar_value_type = typename ETT::scalar_value_type;
641 using vectorized_value_type = typename ETT::vectorized_value_type;
642 using gradient_type = typename ETT::real_gradient_type;
643 using curl_type = typename ETT::curl_type;
645 typename ETT::interface_vectorized_unit_gradient_type;
646
647protected:
669 const unsigned int first_selected_component = 0);
670
693 const unsigned int first_selected_component = 0,
694 const bool is_interior = true);
695
700
705
706public:
714 const value_type &
715 get_value(const unsigned int point_index) const;
716
725 void
726 submit_value(const value_type &value, const unsigned int point_index);
727
737 const gradient_type &
738 get_gradient(const unsigned int point_index) const;
739
748 void
749 submit_gradient(const gradient_type &, const unsigned int point_index);
750
758 Number
759 get_divergence(const unsigned int point_index) const;
760
776 void
777 submit_divergence(const Number &value, const unsigned int point_index);
778
787 get_curl(const unsigned int point_index) const;
788
795 jacobian(const unsigned int point_index) const;
796
804 inverse_jacobian(const unsigned int point_index) const;
805
811 Number
812 JxW(const unsigned int point_index) const;
813
821 real_point(const unsigned int point_index) const;
822
828 quadrature_point(const unsigned int point_index) const;
829
835 unit_point(const unsigned int point_index) const;
836
846
854
858 unsigned int
860
861protected:
862 static constexpr std::size_t n_lanes_user_interface =
864 static constexpr std::size_t n_lanes_internal =
866 static constexpr std::size_t stride =
868
877 void
878 setup(const unsigned int first_selected_component);
879
885 template <bool is_face, bool is_linear>
886 void
888
892 const unsigned int n_q_batches;
893
897 const unsigned int n_q_points;
898
902 const unsigned int n_q_points_scalar;
903
908
913
918 std::vector<Polynomials::Polynomial<double>> poly;
919
924
929 std::vector<unsigned int> renumber;
930
938 std::vector<scalar_value_type> solution_renumbered;
939
947
952
956 std::vector<value_type> values;
957
961 std::vector<gradient_type> gradients;
962
968
974
980
986
992
998
1004 const Number *JxW_ptr;
1005
1010
1016
1023
1028
1033
1039 std::vector<std::array<bool, n_components>> nonzero_shape_function_component;
1040
1045
1049 std::shared_ptr<FEValues<dim, spacedim>> fe_values;
1050
1054 std::unique_ptr<NonMatching::MappingInfo<dim, spacedim, Number>>
1056
1063
1068
1073
1078
1086
1092
1098
1099 const bool is_interior;
1100};
1101
1102
1103
1134template <int n_components_,
1135 int dim,
1136 int spacedim = dim,
1137 typename Number = double>
1139 : public FEPointEvaluationBase<n_components_, dim, spacedim, Number>
1140{
1141public:
1142 static constexpr unsigned int dimension = dim;
1143 static constexpr unsigned int n_components = n_components_;
1144
1145 using number_type = Number;
1146
1149 using VectorizedArrayType = typename ::internal::VectorizedArrayTrait<
1151 using ETT = typename internal::FEPointEvaluation::
1152 EvaluatorTypeTraits<dim, spacedim, n_components, Number>;
1153 using value_type = typename ETT::value_type;
1154 using scalar_value_type = typename ETT::scalar_value_type;
1155 using vectorized_value_type = typename ETT::vectorized_value_type;
1156 using unit_gradient_type = typename ETT::unit_gradient_type;
1157 using gradient_type = typename ETT::real_gradient_type;
1159 typename ETT::interface_vectorized_unit_gradient_type;
1160
1198 const unsigned int first_selected_component = 0,
1199 const bool force_lexicographic_numbering = false);
1200
1228 const unsigned int first_selected_component = 0,
1229 const bool force_lexicographic_numbering = false);
1230
1242 void
1244 const ArrayView<const Point<dim>> &unit_points);
1245
1250 void
1251 reinit();
1252
1257 void
1258 reinit(const unsigned int cell_index);
1259
1260
1272 template <std::size_t stride_view>
1273 void
1274 evaluate(
1276 const EvaluationFlags::EvaluationFlags &evaluation_flags);
1277
1289 void
1290 evaluate(const ArrayView<const ScalarNumber> &solution_values,
1291 const EvaluationFlags::EvaluationFlags &evaluation_flags);
1292
1315 template <std::size_t stride_view>
1316 void
1318 const EvaluationFlags::EvaluationFlags &integration_flags,
1319 const bool sum_into_values = false);
1320
1343 void
1344 integrate(const ArrayView<ScalarNumber> &solution_values,
1345 const EvaluationFlags::EvaluationFlags &integration_flags,
1346 const bool sum_into_values = false);
1347
1374 template <std::size_t stride_view>
1375 void
1377 const StridedArrayView<ScalarNumber, stride_view> &solution_values,
1378 const EvaluationFlags::EvaluationFlags &integration_flags,
1379 const bool sum_into_values = false);
1380
1407 void
1408 test_and_sum(const ArrayView<ScalarNumber> &solution_values,
1409 const EvaluationFlags::EvaluationFlags &integration_flags,
1410 const bool sum_into_values = false);
1411
1418 normal_vector(const unsigned int point_index) const;
1419
1425 const value_type
1426 get_normal_derivative(const unsigned int point_index) const;
1427
1433 void
1434 submit_normal_derivative(const value_type &, const unsigned int point_index);
1435
1436private:
1437 static constexpr std::size_t n_lanes_user_interface =
1439 static constexpr std::size_t n_lanes_internal =
1441 static constexpr std::size_t stride =
1443
1445
1450 template <bool is_linear, std::size_t stride_view>
1451 void
1454
1459 template <bool is_linear, std::size_t stride_view>
1460 void
1463 const EvaluationFlags::EvaluationFlags &evaluation_flags,
1464 const unsigned int n_shapes,
1465 const unsigned int qb,
1466 vectorized_value_type &value,
1468
1472 template <bool is_linear, std::size_t stride_view>
1473 void
1476 const EvaluationFlags::EvaluationFlags &evaluation_flags);
1477
1481 template <std::size_t stride_view>
1482 void
1485 const EvaluationFlags::EvaluationFlags &evaluation_flags);
1486
1492 template <bool is_linear>
1493 void
1495 const EvaluationFlags::EvaluationFlags &integration_flags,
1496 const unsigned int n_shapes,
1497 const unsigned int qb,
1498 const vectorized_value_type value,
1500 vectorized_value_type *solution_values_vectorized_linear);
1501
1507 template <bool is_linear, std::size_t stride_view>
1508 void
1510 const StridedArrayView<ScalarNumber, stride_view> &solution_values,
1511 vectorized_value_type *solution_values_vectorized_linear,
1512 const bool sum_into_values);
1513
1517 template <bool do_JxW, bool is_linear, std::size_t stride_view>
1518 void
1520 const StridedArrayView<ScalarNumber, stride_view> &solution_values,
1521 const EvaluationFlags::EvaluationFlags &integration_flags,
1522 const bool sum_into_values);
1523
1527 template <bool do_JxW, std::size_t stride_view>
1528 void
1530 const StridedArrayView<ScalarNumber, stride_view> &solution_values,
1531 const EvaluationFlags::EvaluationFlags &integration_flags,
1532 const bool sum_into_values);
1533
1537 template <bool do_JxW, std::size_t stride_view>
1538 void
1540 const StridedArrayView<ScalarNumber, stride_view> &solution_values,
1541 const EvaluationFlags::EvaluationFlags &integration_flags,
1542 const bool sum_into_values);
1543
1549 void
1551};
1552
1553
1554
1572template <int n_components_,
1573 int dim,
1574 int spacedim = dim,
1575 typename Number = double>
1577 : public FEPointEvaluationBase<n_components_, dim, spacedim, Number>
1578{
1579public:
1580 static constexpr unsigned int dimension = dim;
1581 static constexpr unsigned int n_components = n_components_;
1582
1583 using number_type = Number;
1584
1587 using VectorizedArrayType = typename ::internal::VectorizedArrayTrait<
1589 using ETT = typename internal::FEPointEvaluation::
1590 EvaluatorTypeTraits<dim, spacedim, n_components, Number>;
1591 using value_type = typename ETT::value_type;
1592 using scalar_value_type = typename ETT::scalar_value_type;
1593 using vectorized_value_type = typename ETT::vectorized_value_type;
1594 using unit_gradient_type = typename ETT::unit_gradient_type;
1595 using gradient_type = typename ETT::real_gradient_type;
1597 typename ETT::interface_vectorized_unit_gradient_type;
1598
1605 const bool is_interior = true,
1606 const unsigned int first_selected_component = 0);
1607
1612 void
1613 reinit(const unsigned int cell_index, const unsigned int face_number);
1614
1619 void
1620 reinit(const unsigned int face_index);
1621
1633 template <std::size_t stride_view>
1634 void
1635 evaluate(
1637 const EvaluationFlags::EvaluationFlags &evaluation_flags);
1638
1650 void
1651 evaluate(const ArrayView<const ScalarNumber> &solution_values,
1652 const EvaluationFlags::EvaluationFlags &evaluation_flags);
1653
1676 template <std::size_t stride_view>
1677 void
1679 const EvaluationFlags::EvaluationFlags &integration_flags,
1680 const bool sum_into_values = false);
1681
1704 void
1705 integrate(const ArrayView<ScalarNumber> &solution_values,
1706 const EvaluationFlags::EvaluationFlags &integration_flags,
1707 const bool sum_into_values = false);
1708
1731 template <std::size_t stride_view>
1732 void
1734 const StridedArrayView<ScalarNumber, stride_view> &solution_values,
1735 const EvaluationFlags::EvaluationFlags &integration_flags,
1736 const bool sum_into_values = false);
1737
1760 void
1761 test_and_sum(const ArrayView<ScalarNumber> &solution_values,
1762 const EvaluationFlags::EvaluationFlags &integration_flags,
1763 const bool sum_into_values = false);
1764
1771 template <int stride_face_dof = VectorizedArrayType::size()>
1772 void
1773 evaluate_in_face(const ScalarNumber *face_dof_values,
1774 const EvaluationFlags::EvaluationFlags &evaluation_flags);
1775
1782 template <int stride_face_dof = VectorizedArrayType::size()>
1783 void
1784 integrate_in_face(ScalarNumber *face_dof_values,
1785 const EvaluationFlags::EvaluationFlags &integration_flags,
1786 const bool sum_into_values = false);
1787
1794 normal_vector(const unsigned int point_index) const;
1795
1801 const value_type
1802 get_normal_derivative(const unsigned int point_index) const;
1803
1809 void
1810 submit_normal_derivative(const value_type &, const unsigned int point_index);
1811
1812private:
1813 static constexpr std::size_t n_lanes_user_interface =
1815 static constexpr std::size_t n_lanes_internal =
1817 static constexpr std::size_t stride =
1819
1820 template <bool is_linear, std::size_t stride_view>
1821 void
1824 const EvaluationFlags::EvaluationFlags &evaluation_flags);
1825
1826 template <bool do_JxW, bool is_linear, std::size_t stride_view>
1827 void
1829 const StridedArrayView<ScalarNumber, stride_view> &solution_values,
1830 const EvaluationFlags::EvaluationFlags &integration_flags,
1831 const bool sum_into_values);
1832
1837 template <bool is_linear, int stride_face_dof>
1838 void
1839 do_evaluate_in_face(const ScalarNumber *face_dof_values,
1840 const EvaluationFlags::EvaluationFlags &evaluation_flags);
1841
1846 template <bool do_JxW, bool is_linear, int stride_face_dof>
1847 void
1849 ScalarNumber *face_dof_values,
1850 const EvaluationFlags::EvaluationFlags &integration_flags,
1851 const bool sum_into_values);
1852};
1853
1854
1855
1856// ----------------------- template and inline function ----------------------
1857
1858
1859template <int n_components_, int dim, int spacedim, typename Number>
1863 const UpdateFlags update_flags,
1864 const unsigned int first_selected_component)
1865 : n_q_batches(numbers::invalid_unsigned_int)
1866 , n_q_points(numbers::invalid_unsigned_int)
1867 , n_q_points_scalar(numbers::invalid_unsigned_int)
1868 , mapping(&mapping)
1869 , fe(&fe)
1870 , JxW_ptr(nullptr)
1871 , update_flags(update_flags)
1872 , mapping_info_on_the_fly(
1873 std::make_unique<NonMatching::MappingInfo<dim, spacedim, Number>>(
1874 mapping,
1875 update_flags))
1876 , mapping_info(mapping_info_on_the_fly.get())
1877 , current_cell_index(numbers::invalid_unsigned_int)
1878 , current_face_number(numbers::invalid_unsigned_int)
1879 , must_reinitialize_pointers(false)
1880 , is_interior(true)
1881{
1882 setup(first_selected_component);
1883}
1884
1885
1886
1887template <int n_components_, int dim, int spacedim, typename Number>
1892 const unsigned int first_selected_component,
1893 const bool is_interior)
1894 : n_q_batches(numbers::invalid_unsigned_int)
1895 , n_q_points(numbers::invalid_unsigned_int)
1896 , n_q_points_scalar(numbers::invalid_unsigned_int)
1897 , mapping(&mapping_info.get_mapping())
1898 , fe(&fe)
1899 , JxW_ptr(nullptr)
1900 , update_flags(mapping_info.get_update_flags())
1901 , mapping_info(&mapping_info)
1902 , current_cell_index(numbers::invalid_unsigned_int)
1903 , current_face_number(numbers::invalid_unsigned_int)
1904 , must_reinitialize_pointers(true)
1905 , is_interior(is_interior)
1906{
1907 setup(first_selected_component);
1908}
1909
1910
1911
1912template <int n_components_, int dim, int spacedim, typename Number>
1916 : n_q_batches(other.n_q_batches)
1917 , n_q_points(other.n_q_points)
1918 , n_q_points_scalar(other.n_q_points_scalar)
1919 , mapping(other.mapping)
1920 , fe(other.fe)
1921 , poly(other.poly)
1922 , use_linear_path(other.use_linear_path)
1923 , renumber(other.renumber)
1924 , solution_renumbered(other.solution_renumbered)
1925 , solution_renumbered_vectorized(other.solution_renumbered_vectorized)
1926 , values(other.values)
1927 , gradients(other.gradients)
1928 , dofs_per_component(other.dofs_per_component)
1929 , dofs_per_component_face(other.dofs_per_component_face)
1930 , component_in_base_element(other.component_in_base_element)
1931 , nonzero_shape_function_component(other.nonzero_shape_function_component)
1932 , update_flags(other.update_flags)
1933 , fe_values(other.fe_values)
1934 , mapping_info_on_the_fly(
1935 other.mapping_info_on_the_fly ?
1937 *mapping,
1938 update_flags) :
1939 nullptr)
1940 , mapping_info(other.mapping_info)
1941 , current_cell_index(other.current_cell_index)
1942 , current_face_number(other.current_face_number)
1943 , fast_path(other.fast_path)
1944 , must_reinitialize_pointers(true)
1945 , is_interior(other.is_interior)
1946{}
1947
1948
1949
1950template <int n_components_, int dim, int spacedim, typename Number>
1952 FEPointEvaluationBase(FEPointEvaluationBase &&other) noexcept = default;
1953
1954
1955
1956template <int n_components_, int dim, int spacedim, typename Number>
1957void
1959 const unsigned int first_selected_component)
1960{
1961 if (fe->n_components() > 1)
1962 AssertIndexRange(first_selected_component + n_components,
1963 fe->n_components() + 1);
1964
1965 shapes.reserve(100);
1966
1967 bool same_base_element = true;
1968 unsigned int base_element_number = 0;
1969 component_in_base_element = 0;
1970 unsigned int component = 0;
1971
1972 for (; base_element_number < fe->n_base_elements(); ++base_element_number)
1973 if (component + fe->element_multiplicity(base_element_number) >
1974 first_selected_component)
1975 {
1976 // check if we have multiple base elements and span across those base
1977 // elements; if there is a single base element, we can also support
1978 // evaluation of multiple vectors despite a single component in the
1979 // finite element
1980 if (fe->n_components() > 1 &&
1981 first_selected_component + n_components >
1982 component + fe->element_multiplicity(base_element_number))
1983 same_base_element = false;
1984 component_in_base_element = first_selected_component - component;
1985 break;
1986 }
1987 else
1988 component += fe->element_multiplicity(base_element_number);
1989
1992 *fe, base_element_number) &&
1993 same_base_element)
1994 {
1995 shape_info.reinit(QMidpoint<1>(), *fe, base_element_number);
1996 renumber = shape_info.lexicographic_numbering;
1997 dofs_per_component = shape_info.dofs_per_component_on_cell;
1998 dofs_per_component_face = shape_info.dofs_per_component_on_face;
2000 fe->base_element(base_element_number));
2001
2002 bool is_lexicographic = true;
2003 for (unsigned int i = 0; i < renumber.size(); ++i)
2004 if (i != renumber[i])
2005 is_lexicographic = false;
2006
2007 if (is_lexicographic)
2008 renumber.clear();
2009
2010 use_linear_path = (poly.size() == 2 && poly[0].value(0.) == 1. &&
2011 poly[0].value(1.) == 0. && poly[1].value(0.) == 0. &&
2012 poly[1].value(1.) == 1.) &&
2013 (fe->n_components() == n_components);
2014
2015 const unsigned int size_face = 3 * dofs_per_component_face * n_components;
2016 const unsigned int size_cell = dofs_per_component * n_components;
2017 scratch_data_scalar.resize(size_face + size_cell);
2018
2019 solution_renumbered.resize(dofs_per_component);
2020 solution_renumbered_vectorized.resize(dofs_per_component);
2021
2022 fast_path = true;
2023 }
2024 else
2025 {
2026 nonzero_shape_function_component.resize(fe->n_dofs_per_cell());
2027 for (unsigned int d = 0; d < n_components; ++d)
2028 {
2029 const unsigned int component = first_selected_component + d;
2030 for (unsigned int i = 0; i < fe->n_dofs_per_cell(); ++i)
2031 {
2032 const bool is_primitive =
2033 fe->is_primitive() || fe->is_primitive(i);
2034 if (is_primitive)
2035 nonzero_shape_function_component[i][d] =
2036 (component == fe->system_to_component_index(i).first);
2037 else
2038 nonzero_shape_function_component[i][d] =
2039 (fe->get_nonzero_components(i)[component] == true);
2040 }
2041 }
2042
2043 fast_path = false;
2044 }
2045}
2046
2047
2048
2049template <int n_components_, int dim, int spacedim, typename Number>
2050template <bool is_face, bool is_linear>
2051inline void
2053{
2054 const unsigned int geometry_index =
2055 mapping_info->template compute_geometry_index_offset<is_face>(
2056 current_cell_index, current_face_number);
2057
2058 cell_type = mapping_info->get_cell_type(geometry_index);
2059
2060 const_cast<unsigned int &>(n_q_points_scalar) =
2061 mapping_info->get_n_q_points_unvectorized(geometry_index);
2062
2063 // round up n_q_points_scalar / n_lanes_internal
2064 const_cast<unsigned int &>(n_q_batches) =
2065 (n_q_points_scalar + n_lanes_internal - 1) / n_lanes_internal;
2066
2067 const unsigned int n_q_points_before = n_q_points;
2068
2069 const_cast<unsigned int &>(n_q_points) =
2070 (stride == 1) ? n_q_batches : n_q_points_scalar;
2071
2072 if (n_q_points != n_q_points_before)
2073 {
2074 if (update_flags & update_values)
2075 values.resize(n_q_points);
2076 if (update_flags & update_gradients)
2077 gradients.resize(n_q_points);
2078 }
2079
2080 if (n_q_points == 0)
2081 return;
2082
2083 // set unit point pointer
2084 const unsigned int unit_point_offset =
2085 mapping_info->compute_unit_point_index_offset(geometry_index);
2086
2087 if (is_face)
2088 unit_point_faces_ptr =
2089 mapping_info->get_unit_point_faces(unit_point_offset);
2090 else
2091 unit_point_ptr = mapping_info->get_unit_point(unit_point_offset);
2092
2093 // set data pointers
2094 const unsigned int data_offset =
2095 mapping_info->compute_data_index_offset(geometry_index);
2096 const unsigned int compressed_data_offset =
2097 mapping_info->compute_compressed_data_index_offset(geometry_index);
2098 if constexpr (running_in_debug_mode())
2099 {
2100 const UpdateFlags update_flags_mapping =
2101 mapping_info->get_update_flags_mapping();
2102 if (update_flags_mapping & UpdateFlags::update_quadrature_points)
2103 real_point_ptr = mapping_info->get_real_point(data_offset);
2104 if (update_flags_mapping & UpdateFlags::update_jacobians)
2105 jacobian_ptr =
2106 mapping_info->get_jacobian(compressed_data_offset, is_interior);
2107 if (update_flags_mapping & UpdateFlags::update_inverse_jacobians)
2108 inverse_jacobian_ptr =
2109 mapping_info->get_inverse_jacobian(compressed_data_offset,
2110 is_interior);
2111 if (update_flags_mapping & UpdateFlags::update_normal_vectors)
2112 normal_ptr = mapping_info->get_normal_vector(data_offset);
2113 if (update_flags_mapping & UpdateFlags::update_JxW_values)
2114 JxW_ptr = mapping_info->get_JxW(data_offset);
2115 }
2116 else
2117 {
2118 real_point_ptr = mapping_info->get_real_point(data_offset);
2119 jacobian_ptr =
2120 mapping_info->get_jacobian(compressed_data_offset, is_interior);
2121 inverse_jacobian_ptr =
2122 mapping_info->get_inverse_jacobian(compressed_data_offset, is_interior);
2123 normal_ptr = mapping_info->get_normal_vector(data_offset);
2124 JxW_ptr = mapping_info->get_JxW(data_offset);
2125 }
2126
2127 if (!is_linear && fast_path)
2128 {
2129 const std::size_t n_shapes = poly.size();
2130 if (is_face)
2131 shapes_faces.resize_fast(n_q_batches * n_shapes);
2132 else
2133 shapes.resize_fast(n_q_batches * n_shapes);
2134
2135 for (unsigned int qb = 0; qb < n_q_batches; ++qb)
2136 if (is_face)
2137 {
2138 if (dim > 1)
2139 {
2141 shapes_faces.data() + qb * n_shapes,
2142 poly,
2143 unit_point_faces_ptr[qb],
2144 update_flags & UpdateFlags::update_gradients ? 1 : 0);
2145 }
2146 }
2147 else
2148 {
2149 if (update_flags & UpdateFlags::update_gradients)
2150 {
2151 internal::compute_values_of_array(shapes.data() + qb * n_shapes,
2152 poly,
2153 unit_point_ptr[qb],
2154 1);
2155 }
2156 else if (qb + 1 < n_q_batches)
2157 {
2158 // Use function with reduced overhead to compute for two
2159 // points at once
2161 shapes.data() + qb * n_shapes,
2162 poly,
2163 unit_point_ptr[qb],
2164 unit_point_ptr[qb + 1]);
2165 ++qb;
2166 }
2167 else
2168 {
2169 internal::compute_values_of_array(shapes.data() + qb * n_shapes,
2170 poly,
2171 unit_point_ptr[qb],
2172 0);
2173 }
2174 }
2175 }
2176}
2177
2178
2179
2180template <int n_components_, int dim, int spacedim, typename Number>
2181inline const typename FEPointEvaluationBase<n_components_,
2182 dim,
2183 spacedim,
2184 Number>::value_type &
2186 const unsigned int point_index) const
2187{
2188 AssertIndexRange(point_index, values.size());
2189 return values[point_index];
2190}
2191
2192
2193
2194template <int n_components_, int dim, int spacedim, typename Number>
2195inline const typename FEPointEvaluationBase<n_components_,
2196 dim,
2197 spacedim,
2198 Number>::gradient_type &
2200 const unsigned int point_index) const
2201{
2202 AssertIndexRange(point_index, gradients.size());
2203 return gradients[point_index];
2204}
2205
2206
2207
2208template <int n_components_, int dim, int spacedim, typename Number>
2209inline Number
2211 const unsigned int point_index) const
2212{
2213 static_assert(n_components == dim,
2214 "Only makes sense for a vector field with dim components");
2215
2216 AssertIndexRange(point_index, values.size());
2217 return trace(gradients[point_index]);
2218}
2219
2220
2221
2222template <int n_components_, int dim, int spacedim, typename Number>
2223inline void
2225 const value_type &value,
2226 const unsigned int point_index)
2227{
2228 AssertIndexRange(point_index, n_q_points);
2229 values[point_index] = value;
2230}
2231
2232
2233
2234template <int n_components_, int dim, int spacedim, typename Number>
2235inline void
2237 const gradient_type &gradient,
2238 const unsigned int point_index)
2239{
2240 AssertIndexRange(point_index, n_q_points);
2241 gradients[point_index] = gradient;
2242}
2243
2244
2245
2246template <int n_components_, int dim, int spacedim, typename Number>
2247inline void
2249 const Number &value,
2250 const unsigned int point_index)
2251{
2252 static_assert(n_components == dim,
2253 "Only makes sense for a vector field with dim components");
2254
2255 AssertIndexRange(point_index, n_q_points);
2256 gradients[point_index] = gradient_type();
2257 for (unsigned int d = 0; d < dim; ++d)
2258 gradients[point_index][d][d] = value;
2259}
2260
2261
2262
2263template <int n_components_, int dim, int spacedim, typename Number>
2266 const unsigned int point_index) const
2267{
2268 static_assert(
2269 dim > 1 && n_components == dim,
2270 "Only makes sense for a vector field with dim components and dim > 1");
2271
2272 const Tensor<2, dim, Number> grad = get_gradient(point_index);
2273 if constexpr (dim == 2)
2274 return grad[1][0] - grad[0][1];
2275 else if constexpr (dim == 3)
2276 {
2277 curl_type curl;
2278 curl[0] = grad[2][1] - grad[1][2];
2279 curl[1] = grad[0][2] - grad[2][0];
2280 curl[2] = grad[1][0] - grad[0][1];
2281 return curl;
2282 }
2283 else
2285 return {};
2286}
2287
2288
2289
2290template <int n_components_, int dim, int spacedim, typename Number>
2293 const unsigned int point_index) const
2294{
2295 AssertIndexRange(point_index, n_q_points);
2296 Assert(jacobian_ptr != nullptr,
2298 ExcFEPointEvaluationAccessToUninitializedMappingField(
2299 "update_jacobians"));
2300 return jacobian_ptr[cell_type <= ::internal::MatrixFreeFunctions::
2301 GeometryType::affine ?
2302 0 :
2303 point_index];
2304}
2305
2306
2307
2308template <int n_components_, int dim, int spacedim, typename Number>
2311 const unsigned int point_index) const
2312{
2313 AssertIndexRange(point_index, n_q_points);
2314 Assert(inverse_jacobian_ptr != nullptr,
2316 ExcFEPointEvaluationAccessToUninitializedMappingField(
2317 "update_inverse_jacobians"));
2318 return inverse_jacobian_ptr
2319 [cell_type <=
2321 0 :
2322 point_index];
2323}
2324
2325
2326
2327template <int n_components_, int dim, int spacedim, typename Number>
2328inline Number
2330 const unsigned int point_index) const
2331{
2332 AssertIndexRange(point_index, n_q_points);
2333 Assert(JxW_ptr != nullptr,
2335 ExcFEPointEvaluationAccessToUninitializedMappingField(
2336 "update_JxW_values"));
2337 return JxW_ptr[point_index];
2338}
2339
2340
2341
2342template <int n_components_, int dim, int spacedim, typename Number>
2345 const unsigned int point_index) const
2346{
2347 return quadrature_point(point_index);
2348}
2349
2350
2351
2352template <int n_components_, int dim, int spacedim, typename Number>
2355 const unsigned int point_index) const
2356{
2357 AssertIndexRange(point_index, n_q_points);
2358 Assert(real_point_ptr != nullptr,
2360 ExcFEPointEvaluationAccessToUninitializedMappingField(
2361 "update_quadrature_points"));
2362 return real_point_ptr[point_index];
2363}
2364
2365
2366
2367template <int n_components_, int dim, int spacedim, typename Number>
2368inline Point<dim, Number>
2370 const unsigned int point_index) const
2371{
2372 AssertIndexRange(point_index, n_q_points);
2373 Assert(unit_point_ptr != nullptr, ExcMessage("unit_point_ptr is not set!"));
2374 Point<dim, Number> unit_point;
2375 for (unsigned int d = 0; d < dim; ++d)
2377 unit_point_ptr[point_index / stride][d], point_index % stride);
2378 return unit_point;
2379}
2380
2381
2382
2383template <int n_components_, int dim, int spacedim, typename Number>
2391
2392
2393
2394template <int n_components_, int dim, int spacedim, typename Number>
2398 const unsigned int first_selected_component,
2399 const bool force_lexicographic_numbering)
2400 : FEPointEvaluationBase<n_components_, dim, spacedim, Number>(
2401 mapping_info,
2402 fe,
2403 first_selected_component)
2404 , lexicographic_numbering(force_lexicographic_numbering ||
2405 this->renumber.empty())
2406{}
2407
2408
2409
2410template <int n_components_, int dim, int spacedim, typename Number>
2412 const Mapping<dim, spacedim> &mapping,
2414 const UpdateFlags update_flags,
2415 const unsigned int first_selected_component,
2416 const bool force_lexicographic_numbering)
2417 : FEPointEvaluationBase<n_components_, dim, spacedim, Number>(
2418 mapping,
2419 fe,
2420 update_flags,
2421 first_selected_component)
2422 , lexicographic_numbering(force_lexicographic_numbering ||
2423 this->renumber.empty())
2424{}
2425
2426
2427
2428template <int n_components_, int dim, int spacedim, typename Number>
2429inline void
2432{
2433 this->current_cell_index = numbers::invalid_unsigned_int;
2434 this->current_face_number = numbers::invalid_unsigned_int;
2435
2436 if (this->use_linear_path)
2437 this->template do_reinit<false, true>();
2438 else
2439 this->template do_reinit<false, false>();
2440}
2441
2442
2443
2444template <int n_components_, int dim, int spacedim, typename Number>
2445inline void
2447{
2448 internal_reinit_single_cell_state_mapping_info();
2449 this->must_reinitialize_pointers = false;
2450}
2451
2452
2453
2454template <int n_components_, int dim, int spacedim, typename Number>
2455inline void
2458 const ArrayView<const Point<dim>> &unit_points)
2459{
2460 // reinit is only allowed for mapping computation on the fly
2461 AssertThrow(this->mapping_info_on_the_fly.get() != nullptr,
2463
2464 this->mapping_info_on_the_fly->reinit(cell, unit_points);
2465 this->must_reinitialize_pointers = false;
2466
2467 if (!this->fast_path)
2468 {
2469 this->fe_values = std::make_shared<FEValues<dim, spacedim>>(
2470 *this->mapping,
2471 *this->fe,
2473 std::vector<Point<dim>>(unit_points.begin(), unit_points.end())),
2474 this->update_flags);
2475 this->fe_values->reinit(cell);
2476 }
2477
2478 if (this->use_linear_path)
2479 this->template do_reinit<false, true>();
2480 else
2481 this->template do_reinit<false, false>();
2482}
2483
2484
2485
2486template <int n_components_, int dim, int spacedim, typename Number>
2487inline void
2489 const unsigned int cell_index)
2490{
2491 this->current_cell_index = cell_index;
2492 this->current_face_number = numbers::invalid_unsigned_int;
2493 this->must_reinitialize_pointers = false;
2494
2495 if (this->use_linear_path)
2496 this->template do_reinit<false, true>();
2497 else
2498 this->template do_reinit<false, false>();
2499
2500 if (!this->fast_path)
2501 {
2502 std::vector<Point<dim>> unit_points(this->n_q_points_scalar);
2503
2504 for (unsigned int v = 0; v < this->n_q_points_scalar; ++v)
2505 for (unsigned int d = 0; d < dim; ++d)
2506 unit_points[v][d] =
2507 this->unit_point_ptr[v / n_lanes_internal][d][v % n_lanes_internal];
2508
2509 this->fe_values = std::make_shared<FEValues<dim, spacedim>>(
2510 *this->mapping,
2511 *this->fe,
2513 std::vector<Point<dim>>(unit_points.begin(), unit_points.end())),
2514 this->update_flags);
2515
2516 this->fe_values->reinit(
2517 this->mapping_info->get_cell_iterator(this->current_cell_index));
2518 }
2519}
2520
2521
2522
2523template <int n_components_, int dim, int spacedim, typename Number>
2524template <std::size_t stride_view>
2525void
2528 const EvaluationFlags::EvaluationFlags &evaluation_flags)
2529{
2530 Assert(!(evaluation_flags & EvaluationFlags::hessians), ExcNotImplemented());
2531
2532 if (!((evaluation_flags & EvaluationFlags::values) ||
2533 (evaluation_flags & EvaluationFlags::gradients))) // no evaluation flags
2534 return;
2535
2536 if (this->must_reinitialize_pointers)
2537 internal_reinit_single_cell_state_mapping_info();
2538
2539 if (this->n_q_points == 0)
2540 return;
2541
2542 if (this->fe->n_components() > 1)
2543 AssertDimension(solution_values.size(), this->fe->dofs_per_cell);
2544 else
2545 AssertDimension(solution_values.size(),
2546 n_components * this->fe->dofs_per_cell);
2547
2548 if (this->fast_path)
2549 {
2550 if (this->use_linear_path)
2551 evaluate_fast<true>(solution_values, evaluation_flags);
2552 else
2553 evaluate_fast<false>(solution_values, evaluation_flags);
2554 }
2555 else
2556 evaluate_slow(solution_values, evaluation_flags);
2557}
2558
2559
2560
2561template <int n_components_, int dim, int spacedim, typename Number>
2562void
2564 const ArrayView<const ScalarNumber> &solution_values,
2565 const EvaluationFlags::EvaluationFlags &evaluation_flags)
2566{
2567 evaluate(StridedArrayView<const ScalarNumber, 1>(solution_values.data(),
2568 solution_values.size()),
2569 evaluation_flags);
2570}
2571
2572
2573
2574template <int n_components_, int dim, int spacedim, typename Number>
2575template <std::size_t stride_view>
2576void
2578 const StridedArrayView<ScalarNumber, stride_view> &solution_values,
2579 const EvaluationFlags::EvaluationFlags &integration_flags,
2580 const bool sum_into_values)
2581{
2582 do_integrate<true>(solution_values, integration_flags, sum_into_values);
2583}
2584
2585
2586
2587template <int n_components_, int dim, int spacedim, typename Number>
2588void
2590 const ArrayView<ScalarNumber> &solution_values,
2591 const EvaluationFlags::EvaluationFlags &integration_flags,
2592 const bool sum_into_values)
2593{
2594 integrate(StridedArrayView<ScalarNumber, 1>(solution_values.data(),
2595 solution_values.size()),
2596 integration_flags,
2597 sum_into_values);
2598}
2599
2600
2601
2602template <int n_components_, int dim, int spacedim, typename Number>
2604 scalar_value_type
2606 const
2607{
2608 value_type return_value = {};
2609
2610 for (const auto point_index : this->quadrature_point_indices())
2611 return_value += values[point_index] * this->JxW(point_index);
2612
2613 return ETT::sum_value(return_value);
2614}
2615
2616
2617
2618template <int n_components_, int dim, int spacedim, typename Number>
2619unsigned int
2622{
2623 Assert(stride == 1,
2624 ExcMessage(
2625 "Calling this function only makes sense in fully vectorized mode."));
2626 if (q == n_q_batches - 1)
2627 {
2628 const unsigned int n_filled_lanes =
2629 n_q_points_scalar & (n_lanes_user_interface - 1);
2630 if (n_filled_lanes == 0)
2631 return n_lanes_user_interface;
2632 else
2633 return n_filled_lanes;
2634 }
2635 else
2636 return n_lanes_user_interface;
2637}
2638
2639
2640
2641template <int n_components_, int dim, int spacedim, typename Number>
2642template <std::size_t stride_view>
2643void
2645 const StridedArrayView<ScalarNumber, stride_view> &solution_values,
2646 const EvaluationFlags::EvaluationFlags &integration_flags,
2647 const bool sum_into_values)
2648{
2649 do_integrate<false>(solution_values, integration_flags, sum_into_values);
2650}
2651
2652
2653
2654template <int n_components_, int dim, int spacedim, typename Number>
2655void
2657 const ArrayView<ScalarNumber> &solution_values,
2658 const EvaluationFlags::EvaluationFlags &integration_flags,
2659 const bool sum_into_values)
2660{
2661 test_and_sum(StridedArrayView<ScalarNumber, 1>(solution_values.data(),
2662 solution_values.size()),
2663 integration_flags,
2664 sum_into_values);
2665}
2666
2667
2668
2669template <int n_components_, int dim, int spacedim, typename Number>
2670template <bool is_linear, std::size_t stride_view>
2671inline void
2674{
2675 const unsigned int dofs_per_comp =
2676 is_linear ? Utilities::pow(2, dim) : this->dofs_per_component;
2677
2678 for (unsigned int comp = 0; comp < n_components; ++comp)
2679 {
2680 const std::size_t offset =
2681 (this->component_in_base_element + comp) * dofs_per_comp;
2682
2683 if ((is_linear && n_components == 1) || lexicographic_numbering)
2684 {
2685 for (unsigned int i = 0; i < dofs_per_comp; ++i)
2686 ETT::read_value(solution_values[i + offset],
2687 comp,
2688 this->solution_renumbered[i]);
2689 }
2690 else
2691 {
2692 // Consider the case where multiple copies should be evaluated from
2693 // a scalar base element, in that case we should only pick the
2694 // scalar renumbering
2695 if (n_components > this->fe->n_components())
2696 for (unsigned int i = 0; i < dofs_per_comp; ++i)
2697 ETT::read_value(solution_values[this->renumber[i] + offset],
2698 comp,
2699 this->solution_renumbered[i]);
2700 else
2701 {
2702 const unsigned int *renumber_ptr = this->renumber.data() + offset;
2703 for (unsigned int i = 0; i < dofs_per_comp; ++i)
2704 ETT::read_value(solution_values[renumber_ptr[i]],
2705 comp,
2706 this->solution_renumbered[i]);
2707 }
2708 }
2709 }
2710}
2711
2712
2713
2714template <int n_components_, int dim, int spacedim, typename Number>
2715template <bool is_linear, std::size_t stride_view>
2716inline void
2719 const EvaluationFlags::EvaluationFlags &evaluation_flags,
2720 const unsigned int n_shapes,
2721 const unsigned int qb,
2722 vectorized_value_type &value,
2724{
2725 if (evaluation_flags & EvaluationFlags::gradients)
2726 {
2727 std::array<vectorized_value_type, dim + 1> result;
2728 if constexpr (is_linear)
2729 {
2730 if constexpr (n_components == 1)
2731 result =
2733 dim,
2736 1,
2737 stride_view>(solution_values.data(), this->unit_point_ptr[qb]);
2738 else
2739 result =
2741 this->solution_renumbered.data(), this->unit_point_ptr[qb]);
2742 }
2743 else
2745 dim,
2748 1,
2749 false>(this->shapes.data() + qb * n_shapes,
2750 n_shapes,
2751 this->solution_renumbered.data());
2752 gradient[0] = result[0];
2753 if (dim > 1)
2754 gradient[1] = result[1];
2755 if (dim > 2)
2756 gradient[2] = result[2];
2757 value = result[dim];
2758 }
2759 else
2760 {
2761 if constexpr (is_linear)
2762 {
2763 if constexpr (n_components == 1)
2765 dim,
2768 stride_view>(solution_values.data(), this->unit_point_ptr[qb]);
2769 else
2771 this->solution_renumbered.data(), this->unit_point_ptr[qb]);
2772 }
2773 else
2774 value =
2778 false>(
2779 this->shapes.data() + qb * n_shapes,
2780 n_shapes,
2781 this->solution_renumbered.data());
2782 }
2783}
2784
2785
2786
2787template <int n_components_, int dim, int spacedim, typename Number>
2788template <bool is_linear, std::size_t stride_view>
2789inline void
2792 const EvaluationFlags::EvaluationFlags &evaluation_flags)
2793{
2794 if (!(is_linear && n_components == 1))
2795 prepare_evaluate_fast<is_linear>(solution_values);
2796
2797 // loop over quadrature batches qb
2798 const unsigned int n_shapes = is_linear ? 2 : this->poly.size();
2799
2800 for (unsigned int qb = 0; qb < this->n_q_batches; ++qb)
2801 {
2804
2805 compute_evaluate_fast<is_linear>(
2806 solution_values, evaluation_flags, n_shapes, qb, value, gradient);
2807
2808 if (evaluation_flags & EvaluationFlags::values)
2809 {
2810 for (unsigned int v = 0, offset = qb * stride;
2811 v < stride && (stride == 1 || offset < this->n_q_points_scalar);
2812 ++v, ++offset)
2813 ETT::set_value(value, v, this->values[offset]);
2814 }
2815 if (evaluation_flags & EvaluationFlags::gradients)
2816 {
2817 Assert(this->update_flags & update_gradients ||
2818 this->update_flags & update_inverse_jacobians,
2820
2821 for (unsigned int v = 0, offset = qb * stride;
2822 v < stride && (stride == 1 || offset < this->n_q_points_scalar);
2823 ++v, ++offset)
2824 {
2825 unit_gradient_type unit_gradient;
2826 ETT::set_gradient(gradient, v, unit_gradient);
2827 this->gradients[offset] =
2828 this->cell_type <=
2831 this->inverse_jacobian_ptr[0].transpose(), unit_gradient) :
2833 this
2834 ->inverse_jacobian_ptr[this->cell_type <=
2836 GeometryType::affine ?
2837 0 :
2838 offset]
2839 .transpose(),
2840 unit_gradient);
2841 }
2842 }
2843 }
2844}
2845
2846
2847
2848template <int n_components_, int dim, int spacedim, typename Number>
2849template <std::size_t stride_view>
2850inline void
2853 const EvaluationFlags::EvaluationFlags &evaluation_flags)
2854{
2855 // slow path with FEValues
2856 Assert(this->fe_values.get() != nullptr,
2857 ExcMessage(
2858 "Not initialized. Please call FEPointEvaluation::reinit()!"));
2859
2860 const std::size_t n_points = this->fe_values->get_quadrature().size();
2861
2862 if (evaluation_flags & EvaluationFlags::values)
2863 {
2864 this->values.resize(this->n_q_points);
2865 std::fill(this->values.begin(), this->values.end(), value_type());
2866 for (unsigned int i = 0; i < this->fe->n_dofs_per_cell(); ++i)
2867 {
2868 const ScalarNumber value = solution_values[i];
2869 for (unsigned int d = 0; d < n_components; ++d)
2870 if (this->nonzero_shape_function_component[i][d] &&
2871 (this->fe->is_primitive(i) || this->fe->is_primitive()))
2872 for (unsigned int qb = 0, q = 0; q < n_points;
2873 ++qb, q += n_lanes_user_interface)
2874 for (unsigned int v = 0;
2875 v < n_lanes_user_interface && q + v < n_points;
2876 ++v)
2877 ETT::access(this->values[qb],
2878 v,
2879 d,
2880 this->fe_values->shape_value(i, q + v) * value);
2881 else if (this->nonzero_shape_function_component[i][d])
2882 for (unsigned int qb = 0, q = 0; q < n_points;
2883 ++qb, q += n_lanes_user_interface)
2884 for (unsigned int v = 0;
2885 v < n_lanes_user_interface && q + v < n_points;
2886 ++v)
2887 ETT::access(this->values[qb],
2888 v,
2889 d,
2890 this->fe_values->shape_value_component(i,
2891 q + v,
2892 d) *
2893 value);
2894 }
2895 }
2896
2897 if (evaluation_flags & EvaluationFlags::gradients)
2898 {
2899 this->gradients.resize(this->n_q_points);
2900 std::fill(this->gradients.begin(),
2901 this->gradients.end(),
2902 gradient_type());
2903 for (unsigned int i = 0; i < this->fe->n_dofs_per_cell(); ++i)
2904 {
2905 const ScalarNumber value = solution_values[i];
2906 for (unsigned int d = 0; d < n_components; ++d)
2907 if (this->nonzero_shape_function_component[i][d] &&
2908 (this->fe->is_primitive(i) || this->fe->is_primitive()))
2909 for (unsigned int qb = 0, q = 0; q < n_points;
2910 ++qb, q += n_lanes_user_interface)
2911 for (unsigned int v = 0;
2912 v < n_lanes_user_interface && q + v < n_points;
2913 ++v)
2914 ETT::access(this->gradients[qb],
2915 v,
2916 d,
2917 this->fe_values->shape_grad(i, q + v) * value);
2918 else if (this->nonzero_shape_function_component[i][d])
2919 for (unsigned int qb = 0, q = 0; q < n_points;
2920 ++qb, q += n_lanes_user_interface)
2921 for (unsigned int v = 0;
2922 v < n_lanes_user_interface && q + v < n_points;
2923 ++v)
2924 ETT::access(
2925 this->gradients[qb],
2926 v,
2927 d,
2928 this->fe_values->shape_grad_component(i, q + v, d) * value);
2929 }
2930 }
2931}
2932
2933
2934
2935template <int n_components_, int dim, int spacedim, typename Number>
2936template <bool is_linear>
2937inline void
2939 const EvaluationFlags::EvaluationFlags &integration_flags,
2940 const unsigned int n_shapes,
2941 const unsigned int qb,
2942 const vectorized_value_type value,
2944 vectorized_value_type *solution_values_vectorized_linear)
2945{
2946 if (integration_flags & EvaluationFlags::gradients)
2948 is_linear,
2949 dim,
2951 vectorized_value_type>(this->shapes.data() + qb * n_shapes,
2952 n_shapes,
2953 &value,
2954 gradient,
2955 is_linear ?
2956 solution_values_vectorized_linear :
2957 this->solution_renumbered_vectorized.data(),
2958 this->unit_point_ptr[qb],
2959 qb != 0);
2960 else
2962 dim,
2965 this->shapes.data() + qb * n_shapes,
2966 n_shapes,
2967 value,
2968 is_linear ? solution_values_vectorized_linear :
2969 this->solution_renumbered_vectorized.data(),
2970 this->unit_point_ptr[qb],
2971 qb != 0);
2972}
2973
2974
2975
2976template <int n_components_, int dim, int spacedim, typename Number>
2977template <bool is_linear, std::size_t stride_view>
2978inline void
2980 const StridedArrayView<ScalarNumber, stride_view> &solution_values,
2981 vectorized_value_type *solution_values_vectorized_linear,
2982 const bool sum_into_values)
2983{
2984 if (!sum_into_values && this->fe->n_components() > n_components)
2985 for (unsigned int i = 0; i < solution_values.size(); ++i)
2986 solution_values[i] = 0;
2987
2988 const unsigned int dofs_per_comp =
2989 is_linear ? Utilities::pow(2, dim) : this->dofs_per_component;
2990
2991 for (unsigned int comp = 0; comp < n_components; ++comp)
2992 {
2993 const std::size_t offset =
2994 (this->component_in_base_element + comp) * dofs_per_comp;
2995
2996 if (is_linear || lexicographic_numbering)
2997 {
2998 for (unsigned int i = 0; i < dofs_per_comp; ++i)
2999 if (sum_into_values)
3000 solution_values[i + offset] +=
3001 ETT::sum_value(comp,
3002 is_linear ?
3003 *(solution_values_vectorized_linear + i) :
3004 this->solution_renumbered_vectorized[i]);
3005 else
3006 solution_values[i + offset] =
3007 ETT::sum_value(comp,
3008 is_linear ?
3009 *(solution_values_vectorized_linear + i) :
3010 this->solution_renumbered_vectorized[i]);
3011 }
3012 else
3013 {
3014 // Consider the case where multiple copies should be evaluated from
3015 // a scalar base element, in that case we should only pick the
3016 // scalar renumbering
3017 if (n_components > this->fe->n_components())
3018 for (unsigned int i = 0; i < dofs_per_comp; ++i)
3019 if (sum_into_values)
3020 solution_values[this->renumber[i] + offset] +=
3021 ETT::sum_value(comp, this->solution_renumbered_vectorized[i]);
3022 else
3023 solution_values[this->renumber[i] + offset] =
3024 ETT::sum_value(comp, this->solution_renumbered_vectorized[i]);
3025 else
3026 {
3027 const unsigned int *renumber_ptr = this->renumber.data() + offset;
3028 for (unsigned int i = 0; i < dofs_per_comp; ++i)
3029 if (sum_into_values)
3030 solution_values[renumber_ptr[i]] +=
3031 ETT::sum_value(comp,
3032 this->solution_renumbered_vectorized[i]);
3033 else
3034 solution_values[renumber_ptr[i]] =
3035 ETT::sum_value(comp,
3036 this->solution_renumbered_vectorized[i]);
3037 }
3038 }
3039 }
3040}
3041
3042
3043
3044template <int n_components_, int dim, int spacedim, typename Number>
3045template <bool do_JxW, bool is_linear, std::size_t stride_view>
3046inline void
3048 const StridedArrayView<ScalarNumber, stride_view> &solution_values,
3049 const EvaluationFlags::EvaluationFlags &integration_flags,
3050 const bool sum_into_values)
3051{
3052 // zero out lanes of incomplete last quadrature point batch
3053 if constexpr (stride == 1)
3054 if (const unsigned int n_filled_lanes =
3055 this->n_q_points_scalar & (n_lanes_internal - 1);
3056 n_filled_lanes > 0)
3057 {
3058 if (integration_flags & EvaluationFlags::values)
3059 for (unsigned int v = n_filled_lanes; v < n_lanes_internal; ++v)
3060 ETT::set_zero_value(this->values.back(), v);
3061 if (integration_flags & EvaluationFlags::gradients)
3062 for (unsigned int v = n_filled_lanes; v < n_lanes_internal; ++v)
3063 ETT::set_zero_gradient(this->gradients.back(), v);
3064 }
3065
3066 std::array<vectorized_value_type, is_linear ? Utilities::pow(2, dim) : 0>
3067 solution_values_vectorized_linear = {};
3068
3069 // loop over quadrature batches qb
3070 const unsigned int n_shapes = is_linear ? 2 : this->poly.size();
3071
3072 const bool cartesian_cell =
3074 const bool affine_cell =
3076 for (unsigned int qb = 0; qb < this->n_q_batches; ++qb)
3077 {
3078 vectorized_value_type value = {};
3080
3081 if (integration_flags & EvaluationFlags::values)
3082 for (unsigned int v = 0, offset = qb * stride;
3083 v < stride && (stride == 1 || offset < this->n_q_points_scalar);
3084 ++v, ++offset)
3085 ETT::get_value(value,
3086 v,
3087 do_JxW ? this->values[offset] * this->JxW_ptr[offset] :
3088 this->values[offset]);
3089
3090 if (integration_flags & EvaluationFlags::gradients)
3091 for (unsigned int v = 0, offset = qb * stride;
3092 v < stride && (stride == 1 || offset < this->n_q_points_scalar);
3093 ++v, ++offset)
3094 {
3095 const gradient_type grad_w =
3096 do_JxW ? this->gradients[offset] * this->JxW_ptr[offset] :
3097 this->gradients[offset];
3098 ETT::get_gradient(
3099 gradient,
3100 v,
3101 cartesian_cell ?
3102 apply_diagonal_transformation(this->inverse_jacobian_ptr[0],
3103 grad_w) :
3105 this->inverse_jacobian_ptr[affine_cell ? 0 : offset],
3106 grad_w));
3107 }
3108
3109 compute_integrate_fast<is_linear>(
3110 integration_flags,
3111 n_shapes,
3112 qb,
3113 value,
3114 gradient,
3115 solution_values_vectorized_linear.data());
3116 }
3117
3118 // add between the lanes and write into the result
3119 finish_integrate_fast<is_linear>(solution_values,
3120 solution_values_vectorized_linear.data(),
3121 sum_into_values);
3122}
3123
3124
3125
3126template <int n_components_, int dim, int spacedim, typename Number>
3127template <bool do_JxW, std::size_t stride_view>
3128inline void
3130 const StridedArrayView<ScalarNumber, stride_view> &solution_values,
3131 const EvaluationFlags::EvaluationFlags &integration_flags,
3132 const bool sum_into_values)
3133{
3134 // slow path with FEValues
3135 Assert(this->fe_values.get() != nullptr,
3136 ExcMessage(
3137 "Not initialized. Please call FEPointEvaluation::reinit()!"));
3138 if (!sum_into_values)
3139 for (unsigned int i = 0; i < solution_values.size(); ++i)
3140 solution_values[i] = 0;
3141
3142 const std::size_t n_points = this->fe_values->get_quadrature().size();
3143
3144 if (integration_flags & EvaluationFlags::values)
3145 {
3146 AssertIndexRange(this->n_q_points, this->values.size() + 1);
3147 for (unsigned int i = 0; i < this->fe->n_dofs_per_cell(); ++i)
3148 {
3149 for (unsigned int d = 0; d < n_components; ++d)
3150 if (this->nonzero_shape_function_component[i][d] &&
3151 (this->fe->is_primitive(i) || this->fe->is_primitive()))
3152 for (unsigned int qb = 0, q = 0; q < n_points;
3153 ++qb, q += n_lanes_user_interface)
3154 for (unsigned int v = 0;
3155 v < n_lanes_user_interface && q + v < n_points;
3156 ++v)
3157 solution_values[i] +=
3158 this->fe_values->shape_value(i, q + v) *
3159 ETT::access(this->values[qb], v, d) *
3160 (do_JxW ? this->fe_values->JxW(q + v) : 1.);
3161 else if (this->nonzero_shape_function_component[i][d])
3162 for (unsigned int qb = 0, q = 0; q < n_points;
3163 ++qb, q += n_lanes_user_interface)
3164 for (unsigned int v = 0;
3165 v < n_lanes_user_interface && q + v < n_points;
3166 ++v)
3167 solution_values[i] +=
3168 this->fe_values->shape_value_component(i, q + v, d) *
3169 ETT::access(this->values[qb], v, d) *
3170 (do_JxW ? this->fe_values->JxW(q + v) : 1.);
3171 }
3172 }
3173
3174 if (integration_flags & EvaluationFlags::gradients)
3175 {
3176 AssertIndexRange(this->n_q_points, this->gradients.size() + 1);
3177 for (unsigned int i = 0; i < this->fe->n_dofs_per_cell(); ++i)
3178 {
3179 for (unsigned int d = 0; d < n_components; ++d)
3180 if (this->nonzero_shape_function_component[i][d] &&
3181 (this->fe->is_primitive(i) || this->fe->is_primitive()))
3182 for (unsigned int qb = 0, q = 0; q < n_points;
3183 ++qb, q += n_lanes_user_interface)
3184 for (unsigned int v = 0;
3185 v < n_lanes_user_interface && q + v < n_points;
3186 ++v)
3187 solution_values[i] +=
3188 this->fe_values->shape_grad(i, q + v) *
3189 ETT::access(this->gradients[qb], v, d) *
3190 (do_JxW ? this->fe_values->JxW(q + v) : 1.);
3191 else if (this->nonzero_shape_function_component[i][d])
3192 for (unsigned int qb = 0, q = 0; q < n_points;
3193 ++qb, q += n_lanes_user_interface)
3194 for (unsigned int v = 0;
3195 v < n_lanes_user_interface && q + v < n_points;
3196 ++v)
3197 solution_values[i] +=
3198 this->fe_values->shape_grad_component(i, q + v, d) *
3199 ETT::access(this->gradients[qb], v, d) *
3200 (do_JxW ? this->fe_values->JxW(q + v) : 1.);
3201 }
3202 }
3203}
3204
3205
3206
3207template <int n_components_, int dim, int spacedim, typename Number>
3208template <bool do_JxW, std::size_t stride_view>
3209void
3211 const StridedArrayView<ScalarNumber, stride_view> &solution_values,
3212 const EvaluationFlags::EvaluationFlags &integration_flags,
3213 const bool sum_into_values)
3214{
3215 if (this->must_reinitialize_pointers)
3216 internal_reinit_single_cell_state_mapping_info();
3217
3218 Assert(!(integration_flags & EvaluationFlags::hessians), ExcNotImplemented());
3219
3220 if (this->n_q_points == 0 || // no evaluation points provided
3221 !((integration_flags & EvaluationFlags::values) ||
3222 (integration_flags &
3223 EvaluationFlags::gradients))) // no integration flags
3224 {
3225 if (!sum_into_values)
3226 for (unsigned int i = 0; i < solution_values.size(); ++i)
3227 solution_values[i] = 0;
3228 return;
3229 }
3230
3231 Assert(
3232 !do_JxW || this->JxW_ptr != nullptr,
3233 ExcMessage(
3234 "JxW pointer is not set! If you do not want to integrate() use test_and_sum()"));
3235
3236 if (this->fe->n_components() > 1)
3237 AssertDimension(solution_values.size(), this->fe->dofs_per_cell);
3238 else
3239 AssertDimension(solution_values.size(),
3240 n_components * this->fe->dofs_per_cell);
3241
3242 if (this->fast_path)
3243 {
3244 if (this->use_linear_path)
3245 integrate_fast<do_JxW, true>(solution_values,
3246 integration_flags,
3247 sum_into_values);
3248 else
3249 integrate_fast<do_JxW, false>(solution_values,
3250 integration_flags,
3251 sum_into_values);
3252 }
3253 else
3254 integrate_slow<do_JxW>(solution_values, integration_flags, sum_into_values);
3255}
3256
3257
3258
3259template <int n_components_, int dim, int spacedim, typename Number>
3262 const unsigned int point_index) const
3263{
3264 AssertIndexRange(point_index, this->n_q_points);
3265 Assert(this->normal_ptr != nullptr,
3267 ExcFEPointEvaluationAccessToUninitializedMappingField(
3268 "update_normal_vectors"));
3269 return this->normal_ptr[point_index];
3270}
3271
3272
3273
3274template <int n_components_, int dim, int spacedim, typename Number>
3275inline const typename FEPointEvaluation<n_components_,
3276 dim,
3277 spacedim,
3278 Number>::value_type
3280 const unsigned int point_index) const
3281{
3282 AssertIndexRange(point_index, this->gradients.size());
3283
3284 value_type normal_derivative;
3285 if constexpr (n_components == 1)
3286 normal_derivative =
3287 this->gradients[point_index] * normal_vector(point_index);
3288 else
3289 for (unsigned int comp = 0; comp < n_components; ++comp)
3290 normal_derivative[comp] =
3291 this->gradients[point_index][comp] * normal_vector(point_index);
3292
3293 return normal_derivative;
3294}
3295
3296
3297
3298template <int n_components_, int dim, int spacedim, typename Number>
3299inline void
3302 const unsigned int point_index)
3303{
3304 AssertIndexRange(point_index, this->gradients.size());
3305 if constexpr (n_components == 1)
3306 this->gradients[point_index] = value * normal_vector(point_index);
3307 else
3308 for (unsigned int comp = 0; comp < n_components; ++comp)
3309 this->gradients[point_index][comp] =
3310 value[comp] * normal_vector(point_index);
3311}
3312
3313
3314
3315template <int n_components_, int dim, int spacedim, typename Number>
3320 const bool is_interior,
3321 const unsigned int first_selected_component)
3322 : FEPointEvaluationBase<n_components_, dim, spacedim, Number>(
3323 mapping_info,
3324 fe,
3325 first_selected_component,
3326 is_interior)
3327{}
3328
3329
3330
3331template <int n_components_, int dim, int spacedim, typename Number>
3332inline void
3334 const unsigned int cell_index,
3335 const unsigned int face_number)
3336{
3337 this->current_cell_index = cell_index;
3338 this->current_face_number = face_number;
3339 this->must_reinitialize_pointers = false;
3340
3341 if (this->use_linear_path)
3342 this->template do_reinit<true, true>();
3343 else
3344 this->template do_reinit<true, false>();
3345}
3346
3347
3348
3349template <int n_components_, int dim, int spacedim, typename Number>
3350inline void
3352 const unsigned int face_index)
3353{
3354 this->current_cell_index = face_index;
3355 this->current_face_number =
3356 this->mapping_info->get_face_number(face_index, this->is_interior);
3357 this->must_reinitialize_pointers = false;
3358
3359 if (this->use_linear_path)
3360 this->template do_reinit<true, true>();
3361 else
3362 this->template do_reinit<true, false>();
3363}
3364
3365
3366
3367template <int n_components_, int dim, int spacedim, typename Number>
3368template <std::size_t stride_view>
3369void
3372 const EvaluationFlags::EvaluationFlags &evaluation_flags)
3373{
3374 Assert(!this->must_reinitialize_pointers,
3375 ExcMessage("Object has not been reinitialized!"));
3376
3377 if (this->n_q_points == 0)
3378 return;
3379
3380 Assert(!(evaluation_flags & EvaluationFlags::hessians), ExcNotImplemented());
3381
3382 if (!((evaluation_flags & EvaluationFlags::values) ||
3383 (evaluation_flags & EvaluationFlags::gradients))) // no evaluation flags
3384 return;
3385
3386 AssertDimension(solution_values.size(), this->fe->dofs_per_cell);
3387
3388 if (this->use_linear_path)
3389 do_evaluate<true>(solution_values, evaluation_flags);
3390 else
3391 do_evaluate<false>(solution_values, evaluation_flags);
3392}
3393
3394
3395
3396template <int n_components_, int dim, int spacedim, typename Number>
3397void
3399 const ArrayView<const ScalarNumber> &solution_values,
3400 const EvaluationFlags::EvaluationFlags &evaluation_flags)
3401{
3402 evaluate(StridedArrayView<const ScalarNumber, 1>(solution_values.data(),
3403 solution_values.size()),
3404 evaluation_flags);
3405}
3406
3407
3408
3409template <int n_components_, int dim, int spacedim, typename Number>
3410template <bool is_linear, std::size_t stride_view>
3411void
3414 const EvaluationFlags::EvaluationFlags &evaluation_flags)
3415{
3416 const unsigned int dofs_per_comp =
3417 is_linear ? Utilities::pow(2, dim) : this->dofs_per_component;
3418
3419 const ScalarNumber *input;
3420 if (stride_view == 1 && this->component_in_base_element == 0 &&
3421 (is_linear || this->renumber.empty()))
3422 input = solution_values.data();
3423 else
3424 {
3425 for (unsigned int comp = 0; comp < n_components; ++comp)
3426 {
3427 const std::size_t offset =
3428 (this->component_in_base_element + comp) * dofs_per_comp;
3429
3430 if (is_linear || this->renumber.empty())
3431 {
3432 for (unsigned int i = 0; i < dofs_per_comp; ++i)
3433 this->scratch_data_scalar[i + comp * dofs_per_comp] =
3434 solution_values[i + offset];
3435 }
3436 else
3437 {
3438 if (n_components > this->fe->n_components())
3439 for (unsigned int i = 0; i < dofs_per_comp; ++i)
3440 ETT::read_value(solution_values[this->renumber[i] + offset],
3441 comp,
3442 this->solution_renumbered[i]);
3443 else
3444 {
3445 const unsigned int *renumber_ptr =
3446 this->renumber.data() + offset;
3447 for (unsigned int i = 0; i < dofs_per_comp; ++i)
3448 this->scratch_data_scalar[i + comp * dofs_per_comp] =
3449 solution_values[renumber_ptr[i]];
3450 }
3451 }
3452 }
3453 input = this->scratch_data_scalar.data();
3454 }
3455
3456 ScalarNumber *output =
3457 this->scratch_data_scalar.begin() + dofs_per_comp * n_components;
3458
3459 internal::FEFaceNormalEvaluationImpl<dim, is_linear ? 1 : -1, ScalarNumber>::
3460 template interpolate<true, false>(n_components,
3461 evaluation_flags,
3462 this->shape_info,
3463 input,
3464 output,
3465 this->current_face_number);
3466
3467 do_evaluate_in_face<is_linear, 1>(output, evaluation_flags);
3468}
3469
3470
3471
3472template <int n_components_, int dim, int spacedim, typename Number>
3473template <std::size_t stride_view>
3474void
3476 const StridedArrayView<ScalarNumber, stride_view> &solution_values,
3477 const EvaluationFlags::EvaluationFlags &integration_flags,
3478 const bool sum_into_values)
3479{
3480 Assert(!this->must_reinitialize_pointers,
3481 ExcMessage("Object has not been reinitialized!"));
3482
3483 Assert(!(integration_flags & EvaluationFlags::hessians), ExcNotImplemented());
3484
3485 if (this->n_q_points == 0 || // no evaluation points provided
3486 !((integration_flags & EvaluationFlags::values) ||
3487 (integration_flags &
3488 EvaluationFlags::gradients))) // no integration flags
3489 {
3490 if (!sum_into_values)
3491 for (unsigned int i = 0; i < solution_values.size(); ++i)
3492 solution_values[i] = 0;
3493 return;
3494 }
3495
3496 AssertDimension(solution_values.size(), this->fe->dofs_per_cell);
3497
3498 if (this->use_linear_path)
3499 do_integrate<true, true>(solution_values,
3500 integration_flags,
3501 sum_into_values);
3502 else
3503 do_integrate<true, false>(solution_values,
3504 integration_flags,
3505 sum_into_values);
3506}
3507
3508
3509
3510template <int n_components_, int dim, int spacedim, typename Number>
3511void
3513 const ArrayView<ScalarNumber> &solution_values,
3514 const EvaluationFlags::EvaluationFlags &integration_flags,
3515 const bool sum_into_values)
3516{
3517 integrate(StridedArrayView<ScalarNumber, 1>(solution_values.data(),
3518 solution_values.size()),
3519 integration_flags,
3520 sum_into_values);
3521}
3522
3523
3524
3525template <int n_components_, int dim, int spacedim, typename Number>
3526template <std::size_t stride_view>
3527void
3529 const StridedArrayView<ScalarNumber, stride_view> &solution_values,
3530 const EvaluationFlags::EvaluationFlags &integration_flags,
3531 const bool sum_into_values)
3532{
3533 Assert(!this->must_reinitialize_pointers,
3534 ExcMessage("Object has not been reinitialized!"));
3535
3536 Assert(!(integration_flags & EvaluationFlags::hessians), ExcNotImplemented());
3537
3538 if (this->n_q_points == 0 || // no evaluation points provided
3539 !((integration_flags & EvaluationFlags::values) ||
3540 (integration_flags &
3541 EvaluationFlags::gradients))) // no integration flags
3542 {
3543 if (!sum_into_values)
3544 for (unsigned int i = 0; i < solution_values.size(); ++i)
3545 solution_values[i] = 0;
3546 return;
3547 }
3548
3549 AssertDimension(solution_values.size(), this->fe->dofs_per_cell);
3550
3551 if (this->use_linear_path)
3552 do_integrate<false, true>(solution_values,
3553 integration_flags,
3554 sum_into_values);
3555 else
3556 do_integrate<false, false>(solution_values,
3557 integration_flags,
3558 sum_into_values);
3559}
3560
3561
3562
3563template <int n_components_, int dim, int spacedim, typename Number>
3564void
3566 const ArrayView<ScalarNumber> &solution_values,
3567 const EvaluationFlags::EvaluationFlags &integration_flags,
3568 const bool sum_into_values)
3569{
3570 test_and_sum(StridedArrayView<ScalarNumber, 1>(solution_values.data(),
3571 solution_values.size()),
3572 integration_flags,
3573 sum_into_values);
3574}
3575
3576
3577
3578template <int n_components_, int dim, int spacedim, typename Number>
3579template <bool do_JxW, bool is_linear, std::size_t stride_view>
3580void
3582 const StridedArrayView<ScalarNumber, stride_view> &solution_values,
3583 const EvaluationFlags::EvaluationFlags &integration_flags,
3584 const bool sum_into_values)
3585{
3586 if (!sum_into_values && this->fe->n_components() > n_components)
3587 for (unsigned int i = 0; i < solution_values.size(); ++i)
3588 solution_values[i] = 0;
3589
3590 do_integrate_in_face<do_JxW, is_linear, 1>(this->scratch_data_scalar.begin(),
3591 integration_flags,
3592 false);
3593
3594 ScalarNumber *input = this->scratch_data_scalar.begin();
3595
3596 if (stride_view == 1 && this->component_in_base_element == 0 &&
3597 (is_linear || this->renumber.empty()))
3598 {
3599 if (sum_into_values)
3600 internal::
3601 FEFaceNormalEvaluationImpl<dim, is_linear ? 1 : -1, ScalarNumber>::
3602 template interpolate<false, true>(n_components,
3603 integration_flags,
3604 this->shape_info,
3605 input,
3606 solution_values.data(),
3607 this->current_face_number);
3608 else
3609 internal::
3610 FEFaceNormalEvaluationImpl<dim, is_linear ? 1 : -1, ScalarNumber>::
3611 template interpolate<false, false>(n_components,
3612 integration_flags,
3613 this->shape_info,
3614 input,
3615 solution_values.data(),
3616 this->current_face_number);
3617 }
3618 else
3619 {
3620 const unsigned int dofs_per_comp_face =
3621 is_linear ? Utilities::pow(2, dim - 1) : this->dofs_per_component_face;
3622
3623 const unsigned int size_input = 3 * dofs_per_comp_face * n_components;
3624 ScalarNumber *output = input + size_input;
3625
3626 internal::
3627 FEFaceNormalEvaluationImpl<dim, is_linear ? 1 : -1, ScalarNumber>::
3628 template interpolate<false, false>(n_components,
3629 integration_flags,
3630 this->shape_info,
3631 input,
3632 output,
3633 this->current_face_number);
3634
3635 const unsigned int dofs_per_comp =
3636 is_linear ? Utilities::pow(2, dim) : this->dofs_per_component;
3637
3638 for (unsigned int comp = 0; comp < n_components; ++comp)
3639 {
3640 const std::size_t offset =
3641 (this->component_in_base_element + comp) * dofs_per_comp;
3642
3643 if (is_linear || this->renumber.empty())
3644 {
3645 for (unsigned int i = 0; i < dofs_per_comp; ++i)
3646 if (sum_into_values)
3647 solution_values[i + offset] +=
3648 output[i + comp * dofs_per_comp];
3649 else
3650 solution_values[i + offset] =
3651 output[i + comp * dofs_per_comp];
3652 }
3653 else
3654 {
3655 if (n_components > this->fe->n_components())
3656 for (unsigned int i = 0; i < dofs_per_comp; ++i)
3657 if (sum_into_values)
3658 solution_values[this->renumber[i] + offset] +=
3659 ETT::sum_value(comp,
3660 this->solution_renumbered_vectorized[i]);
3661 else
3662 solution_values[this->renumber[i] + offset] =
3663 ETT::sum_value(comp,
3664 this->solution_renumbered_vectorized[i]);
3665 else
3666 {
3667 const unsigned int *renumber_ptr =
3668 this->renumber.data() + offset;
3669 for (unsigned int i = 0; i < dofs_per_comp; ++i)
3670 if (sum_into_values)
3671 solution_values[renumber_ptr[i]] +=
3672 output[i + comp * dofs_per_comp];
3673 else
3674 solution_values[renumber_ptr[i]] =
3675 output[i + comp * dofs_per_comp];
3676 }
3677 }
3678 }
3679 }
3680}
3681
3682
3683
3684template <int n_components_, int dim, int spacedim, typename Number>
3685template <int stride_face_dof>
3686void
3688 const ScalarNumber *face_dof_values,
3689 const EvaluationFlags::EvaluationFlags &evaluation_flags)
3690{
3691 if (this->use_linear_path)
3692 do_evaluate_in_face<true, stride_face_dof>(face_dof_values,
3693 evaluation_flags);
3694 else
3695 do_evaluate_in_face<false, stride_face_dof>(face_dof_values,
3696 evaluation_flags);
3697}
3698
3699
3700
3701template <int n_components_, int dim, int spacedim, typename Number>
3702template <bool is_linear, int stride_face_dof>
3703inline void
3705 do_evaluate_in_face(const ScalarNumber *face_dof_values,
3706 const EvaluationFlags::EvaluationFlags &evaluation_flags)
3707{
3708 const scalar_value_type *face_dof_values_ptr;
3709 if constexpr (n_components == 1)
3710 face_dof_values_ptr = face_dof_values;
3711 else
3712 {
3713 const unsigned int dofs_per_comp_face =
3714 is_linear ? Utilities::pow(2, dim - 1) : this->dofs_per_component_face;
3715 for (unsigned int comp = 0; comp < n_components; ++comp)
3716 for (unsigned int i = 0; i < 2 * dofs_per_comp_face; ++i)
3717 ETT::read_value(face_dof_values[(i + comp * 3 * dofs_per_comp_face) *
3718 stride_face_dof],
3719 comp,
3720 this->solution_renumbered[i]);
3721
3722 face_dof_values_ptr = this->solution_renumbered.data();
3723 }
3724
3725 constexpr int stride_face_dof_actual =
3726 n_components == 1 ? stride_face_dof : 1;
3727
3728 // loop over quadrature batches qb
3729 const unsigned int n_shapes = is_linear ? 2 : this->poly.size();
3730
3731 for (unsigned int qb = 0; qb < this->n_q_batches; ++qb)
3732 {
3735
3736 if (evaluation_flags & EvaluationFlags::gradients)
3737 {
3738 const std::array<vectorized_value_type, dim + 1> interpolated_value =
3739 is_linear ?
3741 dim - 1,
3744 2,
3745 stride_face_dof_actual>(face_dof_values_ptr,
3746 this->unit_point_faces_ptr[qb]) :
3748 dim - 1,
3751 2,
3752 false,
3753 stride_face_dof_actual>(this->shapes_faces.data() +
3754 qb * n_shapes,
3755 n_shapes,
3756 face_dof_values_ptr);
3757
3758 value = interpolated_value[dim - 1];
3759 // reorder derivative from tangential/normal derivatives into tensor
3760 // in physical coordinates
3761 if (this->current_face_number / 2 == 0)
3762 {
3763 gradient[0] = interpolated_value[dim];
3764 if (dim > 1)
3765 gradient[1] = interpolated_value[0];
3766 if (dim > 2)
3767 gradient[2] = interpolated_value[1];
3768 }
3769 else if (this->current_face_number / 2 == 1)
3770 {
3771 if (dim > 1)
3772 gradient[1] = interpolated_value[dim];
3773 if (dim == 3)
3774 {
3775 gradient[0] = interpolated_value[1];
3776 gradient[2] = interpolated_value[0];
3777 }
3778 else if (dim == 2)
3779 gradient[0] = interpolated_value[0];
3780 else
3782 }
3783 else if (this->current_face_number / 2 == 2)
3784 {
3785 if (dim > 2)
3786 {
3787 gradient[0] = interpolated_value[0];
3788 gradient[1] = interpolated_value[1];
3789 gradient[2] = interpolated_value[dim];
3790 }
3791 else
3793 }
3794 else
3796 }
3797 else
3798 {
3799 value = is_linear ?
3801 dim - 1,
3804 stride_face_dof_actual>(face_dof_values_ptr,
3805 this->unit_point_faces_ptr[qb]) :
3807 dim - 1,
3810 false,
3811 stride_face_dof_actual>(this->shapes_faces.data() +
3812 qb * n_shapes,
3813 n_shapes,
3814 face_dof_values_ptr);
3815 }
3816
3817 if (evaluation_flags & EvaluationFlags::values)
3818 {
3819 for (unsigned int v = 0, offset = qb * stride;
3820 v < stride && (stride == 1 || offset < this->n_q_points_scalar);
3821 ++v, ++offset)
3822 ETT::set_value(value, v, this->values[offset]);
3823 }
3824 if (evaluation_flags & EvaluationFlags::gradients)
3825 {
3826 Assert(this->update_flags & update_gradients ||
3827 this->update_flags & update_inverse_jacobians,
3829
3830 for (unsigned int v = 0, offset = qb * stride;
3831 v < stride && (stride == 1 || offset < this->n_q_points_scalar);
3832 ++v, ++offset)
3833 {
3834 unit_gradient_type unit_gradient;
3835 ETT::set_gradient(gradient, v, unit_gradient);
3836 this->gradients[offset] =
3837 this->cell_type <=
3840 this->inverse_jacobian_ptr[0].transpose(), unit_gradient) :
3842 this
3843 ->inverse_jacobian_ptr[this->cell_type <=
3845 GeometryType::affine ?
3846 0 :
3847 offset]
3848 .transpose(),
3849 unit_gradient);
3850 }
3851 }
3852 }
3853}
3854
3855
3856
3857template <int n_components_, int dim, int spacedim, typename Number>
3858template <int stride_face_dof>
3859void
3861 ScalarNumber *face_dof_values,
3862 const EvaluationFlags::EvaluationFlags &integration_flags,
3863 const bool sum_into_values)
3864{
3865 if (this->use_linear_path)
3866 do_integrate_in_face<true, true, stride_face_dof>(face_dof_values,
3867 integration_flags,
3868 sum_into_values);
3869 else
3870 do_integrate_in_face<true, false, stride_face_dof>(face_dof_values,
3871 integration_flags,
3872 sum_into_values);
3873}
3874
3875
3876
3877template <int n_components_, int dim, int spacedim, typename Number>
3878template <bool do_JxW, bool is_linear, int stride_face_dof>
3879inline void
3882 ScalarNumber *face_dof_values,
3883 const EvaluationFlags::EvaluationFlags &integration_flags,
3884 const bool sum_into_values)
3885{
3886 // zero out lanes of incomplete last quadrature point batch
3887 if constexpr (stride == 1)
3888 if (const unsigned int n_filled_lanes =
3889 this->n_q_points_scalar & (n_lanes_internal - 1);
3890 n_filled_lanes > 0)
3891 {
3892 if (integration_flags & EvaluationFlags::values)
3893 for (unsigned int v = n_filled_lanes; v < n_lanes_internal; ++v)
3894 ETT::set_zero_value(this->values.back(), v);
3895 if (integration_flags & EvaluationFlags::gradients)
3896 for (unsigned int v = n_filled_lanes; v < n_lanes_internal; ++v)
3897 ETT::set_zero_gradient(this->gradients.back(), v);
3898 }
3899
3900 std::array<vectorized_value_type,
3901 is_linear ? 2 * Utilities::pow(2, dim - 1) : 0>
3902 solution_values_vectorized_linear = {};
3903
3904 // loop over quadrature batches qb
3905 const unsigned int n_shapes = is_linear ? 2 : this->poly.size();
3906
3907 const bool cartesian_cell =
3909 const bool affine_cell =
3911 for (unsigned int qb = 0; qb < this->n_q_batches; ++qb)
3912 {
3913 vectorized_value_type value = {};
3915
3916 if (integration_flags & EvaluationFlags::values)
3917 for (unsigned int v = 0, offset = qb * stride;
3918 v < stride && (stride == 1 || offset < this->n_q_points_scalar);
3919 ++v, ++offset)
3920 ETT::get_value(value,
3921 v,
3922 do_JxW ? this->values[offset] * this->JxW_ptr[offset] :
3923 this->values[offset]);
3924
3925 if (integration_flags & EvaluationFlags::gradients)
3926 for (unsigned int v = 0, offset = qb * stride;
3927 v < stride && (stride == 1 || offset < this->n_q_points_scalar);
3928 ++v, ++offset)
3929 {
3930 const auto grad_w =
3931 do_JxW ? this->gradients[offset] * this->JxW_ptr[offset] :
3932 this->gradients[offset];
3933 ETT::get_gradient(
3934 gradient,
3935 v,
3936 cartesian_cell ?
3937 apply_diagonal_transformation(this->inverse_jacobian_ptr[0],
3938 grad_w) :
3940 this->inverse_jacobian_ptr[affine_cell ? 0 : offset],
3941 grad_w));
3942 }
3943
3944 if (integration_flags & EvaluationFlags::gradients)
3945 {
3946 std::array<vectorized_value_type, 2> value_face = {};
3947 Tensor<1, dim - 1, vectorized_value_type> gradient_in_face;
3948
3949 value_face[0] = value;
3950 // fill derivative in physical coordinates into tangential/normal
3951 // derivatives
3952 if (this->current_face_number / 2 == 0)
3953 {
3954 value_face[1] = gradient[0];
3955 if (dim > 1)
3956 gradient_in_face[0] = gradient[1];
3957 if (dim > 2)
3958 gradient_in_face[1] = gradient[2];
3959 }
3960 else if (this->current_face_number / 2 == 1)
3961 {
3962 if (dim > 1)
3963 value_face[1] = gradient[1];
3964 if (dim == 3)
3965 {
3966 gradient_in_face[0] = gradient[2];
3967 gradient_in_face[1] = gradient[0];
3968 }
3969 else if (dim == 2)
3970 gradient_in_face[0] = gradient[0];
3971 else
3973 }
3974 else if (this->current_face_number / 2 == 2)
3975 {
3976 if (dim > 2)
3977 {
3978 value_face[1] = gradient[2];
3979 gradient_in_face[0] = gradient[0];
3980 gradient_in_face[1] = gradient[1];
3981 }
3982 else
3984 }
3985 else
3987
3989 is_linear,
3990 dim - 1,
3993 2>(this->shapes_faces.data() + qb * n_shapes,
3994 n_shapes,
3995 value_face.data(),
3996 gradient_in_face,
3997 is_linear ? solution_values_vectorized_linear.data() :
3998 this->solution_renumbered_vectorized.data(),
3999 this->unit_point_faces_ptr[qb],
4000 qb != 0);
4001 }
4002 else
4004 dim - 1,
4007 this->shapes_faces.data() + qb * n_shapes,
4008 n_shapes,
4009 value,
4010 is_linear ? solution_values_vectorized_linear.data() :
4011 this->solution_renumbered_vectorized.data(),
4012 this->unit_point_faces_ptr[qb],
4013 qb != 0);
4014 }
4015
4016 const unsigned int dofs_per_comp_face =
4017 is_linear ? Utilities::pow(2, dim - 1) : this->dofs_per_component_face;
4018
4019 for (unsigned int comp = 0; comp < n_components; ++comp)
4020 for (unsigned int i = 0; i < 2 * dofs_per_comp_face; ++i)
4021 if (sum_into_values)
4022 face_dof_values[(i + comp * 3 * dofs_per_comp_face) *
4023 stride_face_dof] +=
4024 ETT::sum_value(comp,
4025 is_linear ?
4026 *(solution_values_vectorized_linear.data() + i) :
4027 this->solution_renumbered_vectorized[i]);
4028 else
4029 face_dof_values[(i + comp * 3 * dofs_per_comp_face) * stride_face_dof] =
4030 ETT::sum_value(comp,
4031 is_linear ?
4032 *(solution_values_vectorized_linear.data() + i) :
4033 this->solution_renumbered_vectorized[i]);
4034}
4035
4036
4037
4038template <int n_components_, int dim, int spacedim, typename Number>
4041 const unsigned int point_index) const
4042{
4043 AssertIndexRange(point_index, this->n_q_points);
4044 Assert(this->normal_ptr != nullptr,
4046 ExcFEPointEvaluationAccessToUninitializedMappingField(
4047 "update_normal_vectors"));
4048 if (this->cell_type <= ::internal::MatrixFreeFunctions::affine)
4049 {
4051 for (unsigned int d = 0; d < dim; ++d)
4052 normal[d] =
4053 internal::VectorizedArrayTrait<Number>::get(this->normal_ptr[0][d],
4054 0);
4055
4056 return normal;
4057 }
4058 else
4059 {
4060 return this->normal_ptr[point_index];
4061 }
4062}
4063
4064
4065
4066template <int n_components_, int dim, int spacedim, typename Number>
4067inline const typename FEFacePointEvaluation<n_components_,
4068 dim,
4069 spacedim,
4070 Number>::value_type
4072 get_normal_derivative(const unsigned int point_index) const
4073{
4074 AssertIndexRange(point_index, this->gradients.size());
4075
4076 value_type normal_derivative;
4077 if constexpr (n_components == 1)
4078 normal_derivative =
4079 this->gradients[point_index] * normal_vector(point_index);
4080 else
4081 for (unsigned int comp = 0; comp < n_components; ++comp)
4082 normal_derivative[comp] =
4083 this->gradients[point_index][comp] * normal_vector(point_index);
4084
4085 return normal_derivative;
4086}
4087
4088
4089
4090template <int n_components_, int dim, int spacedim, typename Number>
4091inline void
4094 const unsigned int point_index)
4095{
4096 AssertIndexRange(point_index, this->gradients.size());
4097 if constexpr (n_components == 1)
4098 this->gradients[point_index] = value * normal_vector(point_index);
4099 else
4100 for (unsigned int comp = 0; comp < n_components; ++comp)
4101 this->gradients[point_index][comp] =
4102 value[comp] * normal_vector(point_index);
4103}
4104
4106
4107#endif
value_type * data() const noexcept
Definition array_view.h:714
std::size_t size() const
Definition array_view.h:737
typename ETT::vectorized_value_type vectorized_value_type
static constexpr std::size_t n_lanes_internal
void do_integrate_in_face(ScalarNumber *face_dof_values, const EvaluationFlags::EvaluationFlags &integration_flags, const bool sum_into_values)
void integrate_in_face(ScalarNumber *face_dof_values, const EvaluationFlags::EvaluationFlags &integration_flags, const bool sum_into_values=false)
typename ETT::scalar_value_type scalar_value_type
typename internal::VectorizedArrayTrait< Number >::value_type ScalarNumber
void evaluate(const StridedArrayView< const ScalarNumber, stride_view > &solution_values, const EvaluationFlags::EvaluationFlags &evaluation_flags)
void do_evaluate_in_face(const ScalarNumber *face_dof_values, const EvaluationFlags::EvaluationFlags &evaluation_flags)
void submit_normal_derivative(const value_type &, const unsigned int point_index)
typename internal::FEPointEvaluation::EvaluatorTypeTraits< dim, spacedim, n_components, Number > ETT
static constexpr std::size_t stride
typename ETT::interface_vectorized_unit_gradient_type interface_vectorized_unit_gradient_type
void do_evaluate(const StridedArrayView< const ScalarNumber, stride_view > &solution_values, const EvaluationFlags::EvaluationFlags &evaluation_flags)
static constexpr unsigned int n_components
static constexpr std::size_t n_lanes_user_interface
typename ETT::real_gradient_type gradient_type
FEFacePointEvaluation(const NonMatching::MappingInfo< dim, spacedim, Number > &mapping_info, const FiniteElement< dim, spacedim > &fe, const bool is_interior=true, const unsigned int first_selected_component=0)
void evaluate_in_face(const ScalarNumber *face_dof_values, const EvaluationFlags::EvaluationFlags &evaluation_flags)
void reinit(const unsigned int cell_index, const unsigned int face_number)
void test_and_sum(const StridedArrayView< ScalarNumber, stride_view > &solution_values, const EvaluationFlags::EvaluationFlags &integration_flags, const bool sum_into_values=false)
typename ETT::unit_gradient_type unit_gradient_type
const value_type get_normal_derivative(const unsigned int point_index) const
void do_integrate(const StridedArrayView< ScalarNumber, stride_view > &solution_values, const EvaluationFlags::EvaluationFlags &integration_flags, const bool sum_into_values)
void integrate(const StridedArrayView< ScalarNumber, stride_view > &solution_values, const EvaluationFlags::EvaluationFlags &integration_flags, const bool sum_into_values=false)
static constexpr unsigned int dimension
Tensor< 1, spacedim, Number > normal_vector(const unsigned int point_index) const
typename ETT::value_type value_type
typename ::internal::VectorizedArrayTrait< Number >::vectorized_value_type VectorizedArrayType
ObserverPointer< const Mapping< dim, spacedim > > mapping
const DerivativeForm< 1, dim, spacedim, Number > * jacobian_ptr
std::unique_ptr< NonMatching::MappingInfo< dim, spacedim, Number > > mapping_info_on_the_fly
std::vector< gradient_type > gradients
typename ETT::interface_vectorized_unit_gradient_type interface_vectorized_unit_gradient_type
Number get_divergence(const unsigned int point_index) const
Number JxW(const unsigned int point_index) const
const UpdateFlags update_flags
static constexpr std::size_t n_lanes_user_interface
static constexpr std::size_t stride
internal::MatrixFreeFunctions::GeometryType cell_type
std::vector< Polynomials::Polynomial< double > > poly
curl_type get_curl(const unsigned int point_index) const
Point< spacedim, Number > real_point(const unsigned int point_index) const
const unsigned int n_q_points_scalar
const Point< dim, VectorizedArrayType > * unit_point_ptr
FEPointEvaluationBase(FEPointEvaluationBase &&other) noexcept
AlignedVector< ScalarNumber > scratch_data_scalar
std_cxx20::ranges::iota_view< unsigned int, unsigned int > quadrature_point_indices() const
const value_type & get_value(const unsigned int point_index) const
const Point< dim - 1, VectorizedArrayType > * unit_point_faces_ptr
std::vector< scalar_value_type > solution_renumbered
const unsigned int n_q_batches
ObserverPointer< const FiniteElement< dim, spacedim > > fe
std::vector< std::array< bool, n_components > > nonzero_shape_function_component
Point< spacedim, Number > quadrature_point(const unsigned int point_index) const
unsigned int n_active_entries_per_quadrature_batch(unsigned int q)
const gradient_type & get_gradient(const unsigned int point_index) const
std::shared_ptr< FEValues< dim, spacedim > > fe_values
FEPointEvaluationBase(const Mapping< dim, spacedim > &mapping, const FiniteElement< dim, spacedim > &fe, const UpdateFlags update_flags, const unsigned int first_selected_component=0)
std::vector< unsigned int > renumber
std::vector< value_type > values
AlignedVector<::ndarray< VectorizedArrayType, 2, dim - 1 > > shapes_faces
Point< dim, Number > unit_point(const unsigned int point_index) const
const unsigned int n_q_points
void submit_divergence(const Number &value, const unsigned int point_index)
const Tensor< 1, spacedim, Number > * normal_ptr
DerivativeForm< 1, spacedim, dim, Number > inverse_jacobian(const unsigned int point_index) const
AlignedVector< vectorized_value_type > solution_renumbered_vectorized
static constexpr std::size_t n_lanes_internal
ObserverPointer< const NonMatching::MappingInfo< dim, spacedim, Number > > mapping_info
const DerivativeForm< 1, spacedim, dim, Number > * inverse_jacobian_ptr
AlignedVector<::ndarray< VectorizedArrayType, 2, dim > > shapes
typename ETT::value_type value_type
scalar_value_type integrate_value() const
void submit_gradient(const gradient_type &, const unsigned int point_index)
void setup(const unsigned int first_selected_component)
typename ETT::scalar_value_type scalar_value_type
static constexpr unsigned int dimension
typename ::internal::VectorizedArrayTrait< Number >::vectorized_value_type VectorizedArrayType
typename ETT::vectorized_value_type vectorized_value_type
static constexpr unsigned int n_components
typename internal::FEPointEvaluation::EvaluatorTypeTraits< dim, spacedim, n_components, Number > ETT
FEPointEvaluationBase(FEPointEvaluationBase &other) noexcept
DerivativeForm< 1, dim, spacedim, Number > jacobian(const unsigned int point_index) const
typename ETT::real_gradient_type gradient_type
const Point< spacedim, Number > * real_point_ptr
FEPointEvaluationBase(const NonMatching::MappingInfo< dim, spacedim, Number > &mapping_info, const FiniteElement< dim, spacedim > &fe, const unsigned int first_selected_component=0, const bool is_interior=true)
internal::MatrixFreeFunctions::ShapeInfo< ScalarNumber > shape_info
void submit_value(const value_type &value, const unsigned int point_index)
typename internal::VectorizedArrayTrait< Number >::value_type ScalarNumber
typename ETT::curl_type curl_type
static constexpr std::size_t stride
void integrate_slow(const StridedArrayView< ScalarNumber, stride_view > &solution_values, const EvaluationFlags::EvaluationFlags &integration_flags, const bool sum_into_values)
static constexpr unsigned int dimension
typename ETT::value_type value_type
void do_integrate(const StridedArrayView< ScalarNumber, stride_view > &solution_values, const EvaluationFlags::EvaluationFlags &integration_flags, const bool sum_into_values)
void evaluate_fast(const StridedArrayView< const ScalarNumber, stride_view > &solution_values, const EvaluationFlags::EvaluationFlags &evaluation_flags)
typename ETT::scalar_value_type scalar_value_type
typename ETT::unit_gradient_type unit_gradient_type
void evaluate(const StridedArrayView< const ScalarNumber, stride_view > &solution_values, const EvaluationFlags::EvaluationFlags &evaluation_flags)
const value_type get_normal_derivative(const unsigned int point_index) const
void prepare_evaluate_fast(const StridedArrayView< const ScalarNumber, stride_view > &solution_values)
void test_and_sum(const StridedArrayView< ScalarNumber, stride_view > &solution_values, const EvaluationFlags::EvaluationFlags &integration_flags, const bool sum_into_values=false)
void integrate(const StridedArrayView< ScalarNumber, stride_view > &solution_values, const EvaluationFlags::EvaluationFlags &integration_flags, const bool sum_into_values=false)
typename internal::VectorizedArrayTrait< Number >::value_type ScalarNumber
typename ETT::vectorized_value_type vectorized_value_type
void compute_integrate_fast(const EvaluationFlags::EvaluationFlags &integration_flags, const unsigned int n_shapes, const unsigned int qb, const vectorized_value_type value, const interface_vectorized_unit_gradient_type gradient, vectorized_value_type *solution_values_vectorized_linear)
typename ::internal::VectorizedArrayTrait< Number >::vectorized_value_type VectorizedArrayType
typename ETT::real_gradient_type gradient_type
void submit_normal_derivative(const value_type &, const unsigned int point_index)
void evaluate_slow(const StridedArrayView< const ScalarNumber, stride_view > &solution_values, const EvaluationFlags::EvaluationFlags &evaluation_flags)
static constexpr std::size_t n_lanes_internal
static constexpr unsigned int n_components
void finish_integrate_fast(const StridedArrayView< ScalarNumber, stride_view > &solution_values, vectorized_value_type *solution_values_vectorized_linear, const bool sum_into_values)
typename internal::FEPointEvaluation::EvaluatorTypeTraits< dim, spacedim, n_components, Number > ETT
void internal_reinit_single_cell_state_mapping_info()
void compute_evaluate_fast(const StridedArrayView< const ScalarNumber, stride_view > &solution_values, const EvaluationFlags::EvaluationFlags &evaluation_flags, const unsigned int n_shapes, const unsigned int qb, vectorized_value_type &value, interface_vectorized_unit_gradient_type &gradient)
void integrate_fast(const StridedArrayView< ScalarNumber, stride_view > &solution_values, const EvaluationFlags::EvaluationFlags &integration_flags, const bool sum_into_values)
static constexpr std::size_t n_lanes_user_interface
FEPointEvaluation(const Mapping< dim, spacedim > &mapping, const FiniteElement< dim, spacedim > &fe, const UpdateFlags update_flags, const unsigned int first_selected_component=0, const bool force_lexicographic_numbering=false)
typename ETT::interface_vectorized_unit_gradient_type interface_vectorized_unit_gradient_type
Tensor< 1, spacedim, Number > normal_vector(const unsigned int point_index) const
Abstract base class for mapping classes.
Definition mapping.h:318
Definition point.h:111
value_type * data() const noexcept
Definition array_view.h:899
std::size_t size() const
Definition array_view.h:920
Tensor< rank, dim, Number > sum(const Tensor< rank, dim, Number > &local, const MPI_Comm mpi_communicator)
#define DEAL_II_DEPRECATED
Definition config.h:294
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:38
constexpr bool running_in_debug_mode()
Definition config.h:76
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
DerivativeForm< 1, spacedim, dim, Number > transpose(const DerivativeForm< 1, dim, spacedim, Number > &DF)
Tensor< 1, spacedim, typename ProductType< Number1, Number2 >::type > apply_transformation(const DerivativeForm< 1, dim, spacedim, Number1 > &grad_F, const Tensor< 1, dim, Number2 > &d_x)
Tensor< 1, spacedim, typename ProductType< Number1, Number2 >::type > apply_diagonal_transformation(const DerivativeForm< 1, dim, spacedim, Number1 > &grad_F, const Tensor< 1, dim, Number2 > &d_x)
#define DEAL_II_ASSERT_UNREACHABLE()
#define DEAL_II_NOT_IMPLEMENTED()
unsigned int cell_index
static ::ExceptionBase & ExcNotImplemented()
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
static ::ExceptionBase & ExcFEPointEvaluationAccessToUninitializedMappingField(std::string arg1)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcNotInitialized()
#define DeclException1(Exception1, type1, outsequence)
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
UpdateFlags
@ update_values
Shape function values.
@ update_normal_vectors
Normal vectors.
@ update_JxW_values
Transformed quadrature weights.
@ update_jacobians
Volume element.
@ update_inverse_jacobians
Volume element.
@ update_gradients
Shape function gradients.
@ update_quadrature_points
Transformed quadrature points.
EvaluationFlags
The EvaluationFlags enum.
*  *  *  RotationFunction< dim, Number >::RotationFunction Number(dim)
constexpr T pow(const T base, const int iexp)
Definition utilities.h:966
std::vector< Polynomials::Polynomial< double > > get_polynomial_space(const FiniteElement< dim, spacedim > &fe)
bool is_fast_path_supported(const FiniteElement< dim, spacedim > &fe, const unsigned int base_element_number)
std::conditional_t< dim==3, Tensor< 1, 3, NumberType >, std::conditional_t< dim==2, NumberType, std::monostate > > CurlType
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={})
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 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)
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)
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)
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)
constexpr unsigned int invalid_unsigned_int
Definition types.h:228
boost::integer_range< IncrementableType > iota_view
Definition iota_view.h:43
STL namespace.
typename internal::ndarray::HelperArray< T, Ns... >::type ndarray
Definition ndarray.h:105
static void set_zero_gradient(unit_gradient_type &value, const unsigned int vector_lane)
static void access(value_type &value, const unsigned int vector_lane, const unsigned int component, const ScalarNumber &shape_value)
static void set_value(const vectorized_value_type &value, const unsigned int vector_lane, scalar_value_type &result)
static Tensor< 1, dim, ScalarNumber > access(const real_gradient_type &value, const unsigned int vector_lane, const unsigned int component)
static void get_value(vectorized_value_type &value, const unsigned int, const vectorized_value_type &result)
static void set_gradient(const interface_vectorized_unit_gradient_type &value, const unsigned int vector_lane, unit_gradient_type &result)
static void read_value(const ScalarNumber vector_entry, const unsigned int component, scalar_value_type &result)
static void access(real_gradient_type &value, const unsigned int vector_lane, const unsigned int component, const Tensor< 1, dim, ScalarNumber > &shape_gradient)
static ScalarNumber sum_value(const unsigned int component, const vectorized_value_type &result)
static ScalarNumber access(const value_type &value, const unsigned int vector_lane, const unsigned int component)
static void get_value(vectorized_value_type &value, const unsigned int vector_lane, const scalar_value_type &result)
typename ::internal::VectorizedArrayTrait< Number >::vectorized_value_type VectorizedArrayType
static void get_gradient(interface_vectorized_unit_gradient_type &value, const unsigned int vector_lane, const unit_gradient_type &result)
static void set_value(const vectorized_value_type &value, const unsigned int, vectorized_value_type &result)
static ScalarNumber access(const value_type &value, const unsigned int vector_lane, const unsigned int)
static void get_gradient(vectorized_unit_gradient_type &value, const unsigned int, const vectorized_unit_gradient_type &result)
static scalar_value_type sum_value(const scalar_value_type &result)
static void get_value(vectorized_value_type &value, const unsigned int, const vectorized_value_type &result)
static void set_gradient(const vectorized_unit_gradient_type &value, const unsigned int vector_lane, scalar_unit_gradient_type &result)
static void set_zero_value(value_type &value, const unsigned int vector_lane)
static Tensor< 1, spacedim, ScalarNumber > access(const real_gradient_type &value, const unsigned int vector_lane, const unsigned int)
static void set_value(const vectorized_value_type &value, const unsigned int, vectorized_value_type &result)
typename internal::VectorizedArrayTrait< Number >::value_type ScalarNumber
static void get_value(vectorized_value_type &value, const unsigned int vector_lane, const scalar_value_type &result)
static scalar_value_type sum_value(const vectorized_value_type &result)
static void access(real_gradient_type &value, const unsigned int vector_lane, const unsigned int, const Tensor< 1, spacedim, ScalarNumber > &shape_gradient)
static void set_gradient(const vectorized_unit_gradient_type &value, const unsigned int, vectorized_unit_gradient_type &result)
static void set_value(const vectorized_value_type &value, const unsigned int vector_lane, scalar_value_type &result)
static void set_zero_gradient(real_gradient_type &value, const unsigned int vector_lane)
static void access(value_type &value, const unsigned int vector_lane, const unsigned int, const ScalarNumber &shape_value)
static void get_gradient(vectorized_unit_gradient_type &value, const unsigned int vector_lane, const scalar_unit_gradient_type &result)
static ScalarNumber sum_value(const unsigned int, const vectorized_value_type &result)
static void read_value(const ScalarNumber vector_entry, const unsigned int, scalar_value_type &result)
typename ::internal::VectorizedArrayTrait< Number >::vectorized_value_type VectorizedArrayType
static Tensor< 1, spacedim, ScalarNumber > access(const real_gradient_type &value, const unsigned int vector_lane, const unsigned int component)
static void get_gradient(interface_vectorized_unit_gradient_type &value, const unsigned int vector_lane, const DerivativeForm< 1, dim, n_components, Number > &result)
static void get_value(vectorized_value_type &value, const unsigned int, const vectorized_value_type &result)
static void get_value(vectorized_value_type &value, const unsigned int vector_lane, const scalar_value_type &result)
static void set_value(const vectorized_value_type &value, const unsigned int, vectorized_value_type &result)
static scalar_value_type sum_value(const scalar_value_type &result)
typename ::internal::VectorizedArrayTrait< Number >::vectorized_value_type VectorizedArrayType
static scalar_value_type sum_value(const vectorized_value_type &result)
static void read_value(const ScalarNumber vector_entry, const unsigned int component, scalar_value_type &result)
Tensor< 1, n_components, ScalarNumber > scalar_value_type
static void set_value(const vectorized_value_type &value, const unsigned int vector_lane, scalar_value_type &result)
static ScalarNumber access(const value_type &value, const unsigned int vector_lane, const unsigned int component)
static ScalarNumber sum_value(const unsigned int component, const vectorized_value_type &result)
Tensor< 1, n_components, Tensor< 1, dim, VectorizedArrayType > > vectorized_unit_gradient_type
static void set_zero_value(value_type &value, const unsigned int vector_lane)
static void set_gradient(const interface_vectorized_unit_gradient_type &value, const unsigned int vector_lane, unit_gradient_type &result)
static void set_zero_gradient(real_gradient_type &value, const unsigned int vector_lane)
typename internal::VectorizedArrayTrait< Number >::value_type ScalarNumber
static void get_gradient(interface_vectorized_unit_gradient_type &value, const unsigned int vector_lane, const unit_gradient_type &result)
std::conditional_t< n_components==spacedim, Tensor< 2, spacedim, Number >, Tensor< 1, n_components, Tensor< 1, spacedim, Number > > > real_gradient_type
Tensor< 1, n_components, VectorizedArrayType > vectorized_value_type
static void access(real_gradient_type &value, const unsigned int vector_lane, const unsigned int component, const Tensor< 1, spacedim, ScalarNumber > &shape_gradient)
Tensor< 1, n_components, Tensor< 1, dim, Number > > unit_gradient_type
static void access(value_type &value, const unsigned int vector_lane, const unsigned int component, const ScalarNumber &shape_value)
static constexpr std::size_t width()
static constexpr std::size_t stride()
static value_type & get(value_type &value, unsigned int c)
constexpr Number trace(const SymmetricTensor< 2, dim2, Number > &)