deal.II version GIT relicensing-2369-g11de1c533e 2025-01-16 20:50:00+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: LGPL-2.1-or-later
4// Copyright (C) 2020 - 2024 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Part of the source code is dual licensed under Apache-2.0 WITH
9// LLVM-exception OR LGPL-2.1-or-later. Detailed license information
10// governing the source code and code contributions can be found in
11// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II.
12//
13// ------------------------------------------------------------------------
14
15#ifndef dealii_fe_point_evaluation_h
16#define dealii_fe_point_evaluation_h
17
18#include <deal.II/base/config.h>
19
24#include <deal.II/base/tensor.h>
26
28#include <deal.II/fe/mapping.h>
29
35
37
39
40namespace internal
41{
43 {
46 std::string,
47 << "You are requesting information from an FEPointEvaluationBase "
48 << "object for which this kind of information has not been computed. "
49 << "What information these objects compute is determined by the update_* "
50 << "flags you pass to MappingInfo() in the Constructor. Here, "
51 << "the operation you are attempting requires the <" << arg1
52 << "> flag to be set, but it was apparently not specified "
53 << "upon initialization.");
54
59 template <int dim,
60 int spacedim,
61 int n_components,
62 typename Number,
63 typename Enable = void>
65 {
69 typename ::internal::VectorizedArrayTrait<
77 using real_gradient_type = std::conditional_t<
78 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;
270
271 static void
272 read_value(const ScalarNumber vector_entry,
273 const unsigned int,
274 scalar_value_type &result)
275 {
276 result = vector_entry;
277 }
278
279 static scalar_value_type
281 {
282 return result;
283 }
284
285 static scalar_value_type
287 {
288 return result.sum();
289 }
290
291 static ScalarNumber
292 sum_value(const unsigned int, const vectorized_value_type &result)
293 {
294 return result.sum();
295 }
296
297 static void
299 const unsigned int vector_lane,
301 {
302 for (unsigned int d = 0; d < dim; ++d)
303 result[d] = value[d][vector_lane];
304 }
305
306 static void
308 const unsigned int,
310 {
311 result = value;
312 }
313
314 static void
316 const unsigned int vector_lane,
317 const scalar_unit_gradient_type &result)
318 {
319 for (unsigned int d = 0; d < dim; ++d)
320 value[d][vector_lane] = result[d];
321 }
322
323 static void
325 const unsigned int,
326 const vectorized_unit_gradient_type &result)
327 {
328 value = result;
329 }
330
331 static void
333 const unsigned int vector_lane)
334 {
335 for (unsigned int d = 0; d < spacedim; ++d)
337 0.;
338 }
339
340 static void
342 const unsigned int vector_lane,
343 scalar_value_type &result)
344 {
345 result = value[vector_lane];
346 }
347
348 static void
350 const unsigned int,
351 vectorized_value_type &result)
352 {
353 result = value;
354 }
355
356 static void
358 const unsigned int vector_lane,
359 const scalar_value_type &result)
360 {
361 value[vector_lane] = result;
362 }
363
364 static void
366 const unsigned int,
367 const vectorized_value_type &result)
368 {
369 value = result;
370 }
371
372 static void
373 set_zero_value(value_type &value, const unsigned int vector_lane)
374 {
376 }
377
378 static void
380 const unsigned int vector_lane,
381 const unsigned int,
382 const ScalarNumber &shape_value)
383 {
385 shape_value;
386 }
387
388 static ScalarNumber
390 const unsigned int vector_lane,
391 const unsigned int)
392 {
394 }
395
396 static void
398 const unsigned int vector_lane,
399 const unsigned int,
400 const Tensor<1, spacedim, ScalarNumber> &shape_gradient)
401 {
402 for (unsigned int d = 0; d < spacedim; ++d)
404 shape_gradient[d];
405 }
406
409 const unsigned int vector_lane,
410 const unsigned int)
411 {
413 for (unsigned int d = 0; d < spacedim; ++d)
414 result[d] =
416 return result;
417 }
418 };
419
420 template <int dim, typename Number>
422 dim,
423 dim,
424 Number,
425 std::enable_if_t<dim != 1>>
426 {
430 typename ::internal::VectorizedArrayTrait<
441
442 static void
443 read_value(const ScalarNumber vector_entry,
444 const unsigned int component,
445 scalar_value_type &result)
446 {
447 AssertIndexRange(component, dim);
448 result[component] = vector_entry;
449 }
450
451 static scalar_value_type
453 {
454 return result;
455 }
456
457 static scalar_value_type
459 {
460 scalar_value_type result_scalar = {};
461
462 for (unsigned int c = 0; c < dim; ++c)
463 result_scalar[c] = result[c].sum();
464
465 return result_scalar;
466 }
467
468 static ScalarNumber
469 sum_value(const unsigned int component,
470 const vectorized_value_type &result)
471 {
472 AssertIndexRange(component, dim);
473 return result[component].sum();
474 }
475
476 static void
478 const unsigned int vector_lane,
479 unit_gradient_type &result)
480 {
481 for (unsigned int i = 0; i < dim; ++i)
482 for (unsigned int d = 0; d < dim; ++d)
483 result[i][d] =
485 value[d][i], vector_lane);
486 }
487
488 static void
490 const unsigned int vector_lane,
491 const unit_gradient_type &result)
492 {
493 for (unsigned int i = 0; i < dim; ++i)
494 for (unsigned int d = 0; d < dim; ++d)
496 value[d][i], vector_lane) = result[i][d];
497 }
498
499 static void
501 const unsigned int vector_lane)
502 {
503 for (unsigned int i = 0; i < dim; ++i)
504 for (unsigned int d = 0; d < dim; ++d)
506 vector_lane) = 0.;
507 }
508
509 static void
511 const unsigned int vector_lane,
512 scalar_value_type &result)
513 {
514 for (unsigned int i = 0; i < dim; ++i)
515 result[i] = value[i][vector_lane];
516 }
517
518 static void
520 const unsigned int,
521 vectorized_value_type &result)
522 {
523 result = value;
524 }
525
526 static void
528 const unsigned int vector_lane,
529 const scalar_value_type &result)
530 {
531 for (unsigned int i = 0; i < dim; ++i)
532 value[i][vector_lane] = result[i];
533 }
534
535 static void
537 const unsigned int,
538 const vectorized_value_type &result)
539 {
540 value = result;
541 }
542
543 static void
544 set_zero_value(value_type &value, const unsigned int vector_lane)
545 {
546 for (unsigned int i = 0; i < dim; ++i)
548 0.;
549 }
550
551 static void
553 const unsigned int vector_lane,
554 const unsigned int component,
555 const ScalarNumber &shape_value)
556 {
558 vector_lane) += shape_value;
559 }
560
561 static ScalarNumber
563 const unsigned int vector_lane,
564 const unsigned int component)
565 {
567 vector_lane);
568 }
569
570 static void
572 const unsigned int vector_lane,
573 const unsigned int component,
574 const Tensor<1, dim, ScalarNumber> &shape_gradient)
575 {
576 for (unsigned int d = 0; d < dim; ++d)
578 vector_lane) +=
579 shape_gradient[d];
580 }
581
584 const unsigned int vector_lane,
585 const unsigned int component)
586 {
588 for (unsigned int d = 0; d < dim; ++d)
589 result[d] =
591 vector_lane);
592 return result;
593 }
594 };
595
596 template <int dim, int spacedim>
597 bool
599 const unsigned int base_element_number);
600
601 template <int dim, int spacedim>
602 bool
604
605 template <int dim, int spacedim>
606 std::vector<Polynomials::Polynomial<double>>
608 } // namespace FEPointEvaluation
609} // namespace internal
610
611
612
619template <int n_components_,
620 int dim,
621 int spacedim = dim,
622 typename Number = double>
624{
625public:
626 static constexpr unsigned int dimension = dim;
627 static constexpr unsigned int n_components = n_components_;
628
629 using number_type = Number;
630
633 using VectorizedArrayType = typename ::internal::VectorizedArrayTrait<
635 using ETT = typename internal::FEPointEvaluation::
636 EvaluatorTypeTraits<dim, spacedim, n_components, Number>;
637 using value_type = typename ETT::value_type;
638 using scalar_value_type = typename ETT::scalar_value_type;
639 using vectorized_value_type = typename ETT::vectorized_value_type;
640 using gradient_type = typename ETT::real_gradient_type;
642 typename ETT::interface_vectorized_unit_gradient_type;
643
644protected:
666 const unsigned int first_selected_component = 0);
667
690 const unsigned int first_selected_component = 0,
691 const bool is_interior = true);
692
697
702
703public:
711 const value_type &
712 get_value(const unsigned int point_index) const;
713
722 void
723 submit_value(const value_type &value, const unsigned int point_index);
724
734 const gradient_type &
735 get_gradient(const unsigned int point_index) const;
736
745 void
746 submit_gradient(const gradient_type &, const unsigned int point_index);
747
755 Number
756 get_divergence(const unsigned int point_index) const;
757
773 void
774 submit_divergence(const Number &value, const unsigned int point_index);
775
782 Tensor<1, (dim == 2 ? 1 : dim), Number>
783 get_curl(const unsigned int point_index) const;
784
791 jacobian(const unsigned int point_index) const;
792
800 inverse_jacobian(const unsigned int point_index) const;
801
807 Number
808 JxW(const unsigned int point_index) const;
809
817 real_point(const unsigned int point_index) const;
818
824 quadrature_point(const unsigned int point_index) const;
825
831 unit_point(const unsigned int point_index) const;
832
842
850
854 unsigned int
856
857protected:
858 static constexpr std::size_t n_lanes_user_interface =
860 static constexpr std::size_t n_lanes_internal =
862 static constexpr std::size_t stride =
864
873 void
874 setup(const unsigned int first_selected_component);
875
881 template <bool is_face, bool is_linear>
882 void
884
888 const unsigned int n_q_batches;
889
893 const unsigned int n_q_points;
894
898 const unsigned int n_q_points_scalar;
899
904
909
914 std::vector<Polynomials::Polynomial<double>> poly;
915
920
925 std::vector<unsigned int> renumber;
926
934 std::vector<scalar_value_type> solution_renumbered;
935
943
948
952 std::vector<value_type> values;
953
957 std::vector<gradient_type> gradients;
958
964
970
976
982
988
994
1000 const Number *JxW_ptr;
1001
1006
1012
1019
1024
1029
1035 std::vector<std::array<bool, n_components>> nonzero_shape_function_component;
1036
1041
1045 std::shared_ptr<FEValues<dim, spacedim>> fe_values;
1046
1050 std::unique_ptr<NonMatching::MappingInfo<dim, spacedim, Number>>
1052
1059
1064
1069
1074
1082
1088
1094
1095 const bool is_interior;
1096};
1097
1098
1099
1130template <int n_components_,
1131 int dim,
1132 int spacedim = dim,
1133 typename Number = double>
1135 : public FEPointEvaluationBase<n_components_, dim, spacedim, Number>
1136{
1137public:
1138 static constexpr unsigned int dimension = dim;
1139 static constexpr unsigned int n_components = n_components_;
1140
1141 using number_type = Number;
1142
1145 using VectorizedArrayType = typename ::internal::VectorizedArrayTrait<
1147 using ETT = typename internal::FEPointEvaluation::
1148 EvaluatorTypeTraits<dim, spacedim, n_components, Number>;
1149 using value_type = typename ETT::value_type;
1150 using scalar_value_type = typename ETT::scalar_value_type;
1151 using vectorized_value_type = typename ETT::vectorized_value_type;
1152 using unit_gradient_type = typename ETT::unit_gradient_type;
1153 using gradient_type = typename ETT::real_gradient_type;
1155 typename ETT::interface_vectorized_unit_gradient_type;
1156
1178 const unsigned int first_selected_component = 0);
1179
1199 const unsigned int first_selected_component = 0);
1200
1212 void
1214 const ArrayView<const Point<dim>> &unit_points);
1215
1220 void
1221 reinit();
1222
1227 void
1228 reinit(const unsigned int cell_index);
1229
1230
1242 template <std::size_t stride_view>
1243 void
1244 evaluate(
1246 const EvaluationFlags::EvaluationFlags &evaluation_flags);
1247
1259 void
1260 evaluate(const ArrayView<const ScalarNumber> &solution_values,
1261 const EvaluationFlags::EvaluationFlags &evaluation_flags);
1262
1285 template <std::size_t stride_view>
1286 void
1288 const EvaluationFlags::EvaluationFlags &integration_flags,
1289 const bool sum_into_values = false);
1290
1313 void
1314 integrate(const ArrayView<ScalarNumber> &solution_values,
1315 const EvaluationFlags::EvaluationFlags &integration_flags,
1316 const bool sum_into_values = false);
1317
1344 template <std::size_t stride_view>
1345 void
1347 const StridedArrayView<ScalarNumber, stride_view> &solution_values,
1348 const EvaluationFlags::EvaluationFlags &integration_flags,
1349 const bool sum_into_values = false);
1350
1377 void
1378 test_and_sum(const ArrayView<ScalarNumber> &solution_values,
1379 const EvaluationFlags::EvaluationFlags &integration_flags,
1380 const bool sum_into_values = false);
1381
1388 normal_vector(const unsigned int point_index) const;
1389
1395 const value_type
1396 get_normal_derivative(const unsigned int point_index) const;
1397
1403 void
1404 submit_normal_derivative(const value_type &, const unsigned int point_index);
1405
1406private:
1407 static constexpr std::size_t n_lanes_user_interface =
1409 static constexpr std::size_t n_lanes_internal =
1411 static constexpr std::size_t stride =
1413
1418 template <bool is_linear, std::size_t stride_view>
1419 void
1422
1427 template <bool is_linear, std::size_t stride_view>
1428 void
1431 const EvaluationFlags::EvaluationFlags &evaluation_flags,
1432 const unsigned int n_shapes,
1433 const unsigned int qb,
1434 vectorized_value_type &value,
1436
1440 template <bool is_linear, std::size_t stride_view>
1441 void
1444 const EvaluationFlags::EvaluationFlags &evaluation_flags);
1445
1449 template <std::size_t stride_view>
1450 void
1453 const EvaluationFlags::EvaluationFlags &evaluation_flags);
1454
1460 template <bool is_linear>
1461 void
1463 const EvaluationFlags::EvaluationFlags &integration_flags,
1464 const unsigned int n_shapes,
1465 const unsigned int qb,
1466 const vectorized_value_type value,
1468 vectorized_value_type *solution_values_vectorized_linear);
1469
1475 template <bool is_linear, std::size_t stride_view>
1476 void
1478 const StridedArrayView<ScalarNumber, stride_view> &solution_values,
1479 vectorized_value_type *solution_values_vectorized_linear,
1480 const bool sum_into_values);
1481
1485 template <bool do_JxW, bool is_linear, std::size_t stride_view>
1486 void
1488 const StridedArrayView<ScalarNumber, stride_view> &solution_values,
1489 const EvaluationFlags::EvaluationFlags &integration_flags,
1490 const bool sum_into_values);
1491
1495 template <bool do_JxW, std::size_t stride_view>
1496 void
1498 const StridedArrayView<ScalarNumber, stride_view> &solution_values,
1499 const EvaluationFlags::EvaluationFlags &integration_flags,
1500 const bool sum_into_values);
1501
1505 template <bool do_JxW, std::size_t stride_view>
1506 void
1508 const StridedArrayView<ScalarNumber, stride_view> &solution_values,
1509 const EvaluationFlags::EvaluationFlags &integration_flags,
1510 const bool sum_into_values);
1511
1517 void
1519};
1520
1521
1522
1540template <int n_components_,
1541 int dim,
1542 int spacedim = dim,
1543 typename Number = double>
1545 : public FEPointEvaluationBase<n_components_, dim, spacedim, Number>
1546{
1547public:
1548 static constexpr unsigned int dimension = dim;
1549 static constexpr unsigned int n_components = n_components_;
1550
1551 using number_type = Number;
1552
1555 using VectorizedArrayType = typename ::internal::VectorizedArrayTrait<
1557 using ETT = typename internal::FEPointEvaluation::
1558 EvaluatorTypeTraits<dim, spacedim, n_components, Number>;
1559 using value_type = typename ETT::value_type;
1560 using scalar_value_type = typename ETT::scalar_value_type;
1561 using vectorized_value_type = typename ETT::vectorized_value_type;
1562 using unit_gradient_type = typename ETT::unit_gradient_type;
1563 using gradient_type = typename ETT::real_gradient_type;
1565 typename ETT::interface_vectorized_unit_gradient_type;
1566
1573 const bool is_interior = true,
1574 const unsigned int first_selected_component = 0);
1575
1580 void
1581 reinit(const unsigned int cell_index, const unsigned int face_number);
1582
1587 void
1588 reinit(const unsigned int face_index);
1589
1601 template <std::size_t stride_view>
1602 void
1603 evaluate(
1605 const EvaluationFlags::EvaluationFlags &evaluation_flags);
1606
1618 void
1619 evaluate(const ArrayView<const ScalarNumber> &solution_values,
1620 const EvaluationFlags::EvaluationFlags &evaluation_flags);
1621
1644 template <std::size_t stride_view>
1645 void
1647 const EvaluationFlags::EvaluationFlags &integration_flags,
1648 const bool sum_into_values = false);
1649
1672 void
1673 integrate(const ArrayView<ScalarNumber> &solution_values,
1674 const EvaluationFlags::EvaluationFlags &integration_flags,
1675 const bool sum_into_values = false);
1676
1699 template <std::size_t stride_view>
1700 void
1702 const StridedArrayView<ScalarNumber, stride_view> &solution_values,
1703 const EvaluationFlags::EvaluationFlags &integration_flags,
1704 const bool sum_into_values = false);
1705
1728 void
1729 test_and_sum(const ArrayView<ScalarNumber> &solution_values,
1730 const EvaluationFlags::EvaluationFlags &integration_flags,
1731 const bool sum_into_values = false);
1732
1739 template <int stride_face_dof = VectorizedArrayType::size()>
1740 void
1741 evaluate_in_face(const ScalarNumber *face_dof_values,
1742 const EvaluationFlags::EvaluationFlags &evaluation_flags);
1743
1750 template <int stride_face_dof = VectorizedArrayType::size()>
1751 void
1752 integrate_in_face(ScalarNumber *face_dof_values,
1753 const EvaluationFlags::EvaluationFlags &integration_flags,
1754 const bool sum_into_values = false);
1755
1762 normal_vector(const unsigned int point_index) const;
1763
1769 const value_type
1770 get_normal_derivative(const unsigned int point_index) const;
1771
1777 void
1778 submit_normal_derivative(const value_type &, const unsigned int point_index);
1779
1780private:
1781 static constexpr std::size_t n_lanes_user_interface =
1783 static constexpr std::size_t n_lanes_internal =
1785 static constexpr std::size_t stride =
1787
1788 template <bool is_linear, std::size_t stride_view>
1789 void
1792 const EvaluationFlags::EvaluationFlags &evaluation_flags);
1793
1794 template <bool do_JxW, bool is_linear, std::size_t stride_view>
1795 void
1797 const StridedArrayView<ScalarNumber, stride_view> &solution_values,
1798 const EvaluationFlags::EvaluationFlags &integration_flags,
1799 const bool sum_into_values);
1800
1805 template <bool is_linear, int stride_face_dof>
1806 void
1807 do_evaluate_in_face(const ScalarNumber *face_dof_values,
1808 const EvaluationFlags::EvaluationFlags &evaluation_flags);
1809
1814 template <bool do_JxW, bool is_linear, int stride_face_dof>
1815 void
1817 ScalarNumber *face_dof_values,
1818 const EvaluationFlags::EvaluationFlags &integration_flags,
1819 const bool sum_into_values);
1820};
1821
1822
1823
1824// ----------------------- template and inline function ----------------------
1825
1826
1827template <int n_components_, int dim, int spacedim, typename Number>
1831 const UpdateFlags update_flags,
1832 const unsigned int first_selected_component)
1833 : n_q_batches(numbers::invalid_unsigned_int)
1834 , n_q_points(numbers::invalid_unsigned_int)
1835 , n_q_points_scalar(numbers::invalid_unsigned_int)
1836 , mapping(&mapping)
1837 , fe(&fe)
1838 , JxW_ptr(nullptr)
1839 , update_flags(update_flags)
1840 , mapping_info_on_the_fly(
1841 std::make_unique<NonMatching::MappingInfo<dim, spacedim, Number>>(
1842 mapping,
1843 update_flags))
1844 , mapping_info(mapping_info_on_the_fly.get())
1845 , current_cell_index(numbers::invalid_unsigned_int)
1846 , current_face_number(numbers::invalid_unsigned_int)
1847 , must_reinitialize_pointers(false)
1848 , is_interior(true)
1849{
1850 setup(first_selected_component);
1851}
1852
1853
1854
1855template <int n_components_, int dim, int spacedim, typename Number>
1860 const unsigned int first_selected_component,
1861 const bool is_interior)
1862 : n_q_batches(numbers::invalid_unsigned_int)
1863 , n_q_points(numbers::invalid_unsigned_int)
1864 , n_q_points_scalar(numbers::invalid_unsigned_int)
1865 , mapping(&mapping_info.get_mapping())
1866 , fe(&fe)
1867 , JxW_ptr(nullptr)
1868 , update_flags(mapping_info.get_update_flags())
1869 , mapping_info(&mapping_info)
1870 , current_cell_index(numbers::invalid_unsigned_int)
1871 , current_face_number(numbers::invalid_unsigned_int)
1872 , must_reinitialize_pointers(true)
1873 , is_interior(is_interior)
1874{
1875 setup(first_selected_component);
1876}
1877
1878
1879
1880template <int n_components_, int dim, int spacedim, typename Number>
1884 : n_q_batches(other.n_q_batches)
1885 , n_q_points(other.n_q_points)
1886 , n_q_points_scalar(other.n_q_points_scalar)
1887 , mapping(other.mapping)
1888 , fe(other.fe)
1889 , poly(other.poly)
1890 , use_linear_path(other.use_linear_path)
1891 , renumber(other.renumber)
1892 , solution_renumbered(other.solution_renumbered)
1893 , solution_renumbered_vectorized(other.solution_renumbered_vectorized)
1894 , values(other.values)
1895 , gradients(other.gradients)
1896 , dofs_per_component(other.dofs_per_component)
1897 , dofs_per_component_face(other.dofs_per_component_face)
1898 , component_in_base_element(other.component_in_base_element)
1899 , nonzero_shape_function_component(other.nonzero_shape_function_component)
1900 , update_flags(other.update_flags)
1901 , fe_values(other.fe_values)
1902 , mapping_info_on_the_fly(
1903 other.mapping_info_on_the_fly ?
1905 *mapping,
1906 update_flags) :
1907 nullptr)
1908 , mapping_info(other.mapping_info)
1909 , current_cell_index(other.current_cell_index)
1910 , current_face_number(other.current_face_number)
1911 , fast_path(other.fast_path)
1912 , must_reinitialize_pointers(true)
1913 , is_interior(other.is_interior)
1914{}
1915
1916
1917
1918template <int n_components_, int dim, int spacedim, typename Number>
1921 : n_q_batches(other.n_q_batches)
1922 , n_q_points(other.n_q_points)
1923 , n_q_points_scalar(other.n_q_points_scalar)
1924 , mapping(other.mapping)
1925 , fe(other.fe)
1926 , poly(other.poly)
1927 , use_linear_path(other.use_linear_path)
1928 , renumber(other.renumber)
1929 , solution_renumbered(other.solution_renumbered)
1930 , solution_renumbered_vectorized(other.solution_renumbered_vectorized)
1931 , values(other.values)
1932 , gradients(other.gradients)
1933 , dofs_per_component(other.dofs_per_component)
1934 , dofs_per_component_face(other.dofs_per_component_face)
1935 , component_in_base_element(other.component_in_base_element)
1936 , nonzero_shape_function_component(other.nonzero_shape_function_component)
1937 , update_flags(other.update_flags)
1938 , fe_values(other.fe_values)
1939 , mapping_info_on_the_fly(std::move(other.mapping_info_on_the_fly))
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(other.must_reinitialize_pointers)
1945 , is_interior(other.is_interior)
1946{}
1947
1948
1949
1950template <int n_components_, int dim, int spacedim, typename Number>
1951void
1953 const unsigned int first_selected_component)
1954{
1955 AssertIndexRange(first_selected_component + n_components,
1956 fe->n_components() + 1);
1957
1958 shapes.reserve(100);
1959
1960 bool same_base_element = true;
1961 unsigned int base_element_number = 0;
1962 component_in_base_element = 0;
1963 unsigned int component = 0;
1964 for (; base_element_number < fe->n_base_elements(); ++base_element_number)
1965 if (component + fe->element_multiplicity(base_element_number) >
1966 first_selected_component)
1967 {
1968 if (first_selected_component + n_components >
1969 component + fe->element_multiplicity(base_element_number))
1970 same_base_element = false;
1971 component_in_base_element = first_selected_component - component;
1972 break;
1973 }
1974 else
1975 component += fe->element_multiplicity(base_element_number);
1976
1979 *fe, base_element_number) &&
1980 same_base_element)
1981 {
1982 shape_info.reinit(QMidpoint<1>(), *fe, base_element_number);
1983 renumber = shape_info.lexicographic_numbering;
1984 dofs_per_component = shape_info.dofs_per_component_on_cell;
1985 dofs_per_component_face = shape_info.dofs_per_component_on_face;
1987 fe->base_element(base_element_number));
1988
1989 bool is_lexicographic = true;
1990 for (unsigned int i = 0; i < renumber.size(); ++i)
1991 if (i != renumber[i])
1992 is_lexicographic = false;
1993
1994 if (is_lexicographic)
1995 renumber.clear();
1996
1997 use_linear_path = (poly.size() == 2 && poly[0].value(0.) == 1. &&
1998 poly[0].value(1.) == 0. && poly[1].value(0.) == 0. &&
1999 poly[1].value(1.) == 1.) &&
2000 (fe->n_components() == n_components);
2001
2002 const unsigned int size_face = 3 * dofs_per_component_face * n_components;
2003 const unsigned int size_cell = dofs_per_component * n_components;
2004 scratch_data_scalar.resize(size_face + size_cell);
2005
2006 solution_renumbered.resize(dofs_per_component);
2007 solution_renumbered_vectorized.resize(dofs_per_component);
2008
2009 fast_path = true;
2010 }
2011 else
2012 {
2013 nonzero_shape_function_component.resize(fe->n_dofs_per_cell());
2014 for (unsigned int d = 0; d < n_components; ++d)
2015 {
2016 const unsigned int component = first_selected_component + d;
2017 for (unsigned int i = 0; i < fe->n_dofs_per_cell(); ++i)
2018 {
2019 const bool is_primitive =
2020 fe->is_primitive() || fe->is_primitive(i);
2021 if (is_primitive)
2022 nonzero_shape_function_component[i][d] =
2023 (component == fe->system_to_component_index(i).first);
2024 else
2025 nonzero_shape_function_component[i][d] =
2026 (fe->get_nonzero_components(i)[component] == true);
2027 }
2028 }
2029
2030 fast_path = false;
2031 }
2032}
2033
2034
2035
2036template <int n_components_, int dim, int spacedim, typename Number>
2037template <bool is_face, bool is_linear>
2038inline void
2040{
2041 const unsigned int geometry_index =
2042 mapping_info->template compute_geometry_index_offset<is_face>(
2043 current_cell_index, current_face_number);
2044
2045 cell_type = mapping_info->get_cell_type(geometry_index);
2046
2047 const_cast<unsigned int &>(n_q_points_scalar) =
2048 mapping_info->get_n_q_points_unvectorized(geometry_index);
2049
2050 // round up n_q_points_scalar / n_lanes_internal
2051 const_cast<unsigned int &>(n_q_batches) =
2052 (n_q_points_scalar + n_lanes_internal - 1) / n_lanes_internal;
2053
2054 const unsigned int n_q_points_before = n_q_points;
2055
2056 const_cast<unsigned int &>(n_q_points) =
2057 (stride == 1) ? n_q_batches : n_q_points_scalar;
2058
2059 if (n_q_points != n_q_points_before)
2060 {
2061 if (update_flags & update_values)
2062 values.resize(n_q_points);
2063 if (update_flags & update_gradients)
2064 gradients.resize(n_q_points);
2065 }
2066
2067 if (n_q_points == 0)
2068 return;
2069
2070 // set unit point pointer
2071 const unsigned int unit_point_offset =
2072 mapping_info->compute_unit_point_index_offset(geometry_index);
2073
2074 if (is_face)
2075 unit_point_faces_ptr =
2076 mapping_info->get_unit_point_faces(unit_point_offset);
2077 else
2078 unit_point_ptr = mapping_info->get_unit_point(unit_point_offset);
2079
2080 // set data pointers
2081 const unsigned int data_offset =
2082 mapping_info->compute_data_index_offset(geometry_index);
2083 const unsigned int compressed_data_offset =
2084 mapping_info->compute_compressed_data_index_offset(geometry_index);
2085#ifdef DEBUG
2086 const UpdateFlags update_flags_mapping =
2087 mapping_info->get_update_flags_mapping();
2088 if (update_flags_mapping & UpdateFlags::update_quadrature_points)
2089 real_point_ptr = mapping_info->get_real_point(data_offset);
2090 if (update_flags_mapping & UpdateFlags::update_jacobians)
2091 jacobian_ptr =
2092 mapping_info->get_jacobian(compressed_data_offset, is_interior);
2093 if (update_flags_mapping & UpdateFlags::update_inverse_jacobians)
2094 inverse_jacobian_ptr =
2095 mapping_info->get_inverse_jacobian(compressed_data_offset, is_interior);
2096 if (update_flags_mapping & UpdateFlags::update_normal_vectors)
2097 normal_ptr = mapping_info->get_normal_vector(data_offset);
2098 if (update_flags_mapping & UpdateFlags::update_JxW_values)
2099 JxW_ptr = mapping_info->get_JxW(data_offset);
2100#else
2101 real_point_ptr = mapping_info->get_real_point(data_offset);
2102 jacobian_ptr =
2103 mapping_info->get_jacobian(compressed_data_offset, is_interior);
2104 inverse_jacobian_ptr =
2105 mapping_info->get_inverse_jacobian(compressed_data_offset, is_interior);
2106 normal_ptr = mapping_info->get_normal_vector(data_offset);
2107 JxW_ptr = mapping_info->get_JxW(data_offset);
2108#endif
2109
2110 if (!is_linear && fast_path)
2111 {
2112 const std::size_t n_shapes = poly.size();
2113 if (is_face)
2114 shapes_faces.resize_fast(n_q_batches * n_shapes);
2115 else
2116 shapes.resize_fast(n_q_batches * n_shapes);
2117
2118 for (unsigned int qb = 0; qb < n_q_batches; ++qb)
2119 if (is_face)
2120 {
2121 if (dim > 1)
2122 {
2124 shapes_faces.data() + qb * n_shapes,
2125 poly,
2126 unit_point_faces_ptr[qb],
2127 update_flags & UpdateFlags::update_gradients ? 1 : 0);
2128 }
2129 }
2130 else
2131 {
2132 if (update_flags & UpdateFlags::update_gradients)
2133 {
2134 internal::compute_values_of_array(shapes.data() + qb * n_shapes,
2135 poly,
2136 unit_point_ptr[qb],
2137 1);
2138 }
2139 else if (qb + 1 < n_q_batches)
2140 {
2141 // Use function with reduced overhead to compute for two
2142 // points at once
2144 shapes.data() + qb * n_shapes,
2145 poly,
2146 unit_point_ptr[qb],
2147 unit_point_ptr[qb + 1]);
2148 ++qb;
2149 }
2150 else
2151 {
2152 internal::compute_values_of_array(shapes.data() + qb * n_shapes,
2153 poly,
2154 unit_point_ptr[qb],
2155 0);
2156 }
2157 }
2158 }
2159}
2160
2161
2162
2163template <int n_components_, int dim, int spacedim, typename Number>
2164inline const typename FEPointEvaluationBase<n_components_,
2165 dim,
2166 spacedim,
2167 Number>::value_type &
2169 const unsigned int point_index) const
2170{
2171 AssertIndexRange(point_index, values.size());
2172 return values[point_index];
2173}
2174
2175
2176
2177template <int n_components_, int dim, int spacedim, typename Number>
2178inline const typename FEPointEvaluationBase<n_components_,
2179 dim,
2180 spacedim,
2181 Number>::gradient_type &
2183 const unsigned int point_index) const
2184{
2185 AssertIndexRange(point_index, gradients.size());
2186 return gradients[point_index];
2187}
2188
2189
2190
2191template <int n_components_, int dim, int spacedim, typename Number>
2192inline Number
2194 const unsigned int point_index) const
2195{
2196 static_assert(n_components == dim,
2197 "Only makes sense for a vector field with dim components");
2198
2199 AssertIndexRange(point_index, values.size());
2200 return trace(gradients[point_index]);
2201}
2202
2203
2204
2205template <int n_components_, int dim, int spacedim, typename Number>
2206inline void
2208 const value_type &value,
2209 const unsigned int point_index)
2210{
2211 AssertIndexRange(point_index, n_q_points);
2212 values[point_index] = value;
2213}
2214
2215
2216
2217template <int n_components_, int dim, int spacedim, typename Number>
2218inline void
2220 const gradient_type &gradient,
2221 const unsigned int point_index)
2222{
2223 AssertIndexRange(point_index, n_q_points);
2224 gradients[point_index] = gradient;
2225}
2226
2227
2228
2229template <int n_components_, int dim, int spacedim, typename Number>
2230inline void
2232 const Number &value,
2233 const unsigned int point_index)
2234{
2235 static_assert(n_components == dim,
2236 "Only makes sense for a vector field with dim components");
2237
2238 AssertIndexRange(point_index, n_q_points);
2239 gradients[point_index] = gradient_type();
2240 for (unsigned int d = 0; d < dim; ++d)
2241 gradients[point_index][d][d] = value;
2242}
2243
2244
2245
2246template <int n_components_, int dim, int spacedim, typename Number>
2247Tensor<1, (dim == 2 ? 1 : dim), Number>
2249 const unsigned int point_index) const
2250{
2251 static_assert(
2252 dim > 1 && n_components == dim,
2253 "Only makes sense for a vector field with dim components and dim > 1");
2254
2255 const Tensor<2, dim, Number> grad = get_gradient(point_index);
2256 Tensor<1, (dim == 2 ? 1 : dim), Number> curl;
2257 switch (dim)
2258 {
2259 case 2:
2260 curl[0] = grad[1][0] - grad[0][1];
2261 break;
2262 case 3:
2263 curl[0] = grad[2][1] - grad[1][2];
2264 curl[1] = grad[0][2] - grad[2][0];
2265 curl[2] = grad[1][0] - grad[0][1];
2266 break;
2267 default:
2269 }
2270 return curl;
2271}
2272
2273
2274
2275template <int n_components_, int dim, int spacedim, typename Number>
2278 const unsigned int point_index) const
2279{
2280 AssertIndexRange(point_index, n_q_points);
2281 Assert(jacobian_ptr != nullptr,
2283 ExcFEPointEvaluationAccessToUninitializedMappingField(
2284 "update_jacobians"));
2285 return jacobian_ptr[cell_type <= ::internal::MatrixFreeFunctions::
2286 GeometryType::affine ?
2287 0 :
2288 point_index];
2289}
2290
2291
2292
2293template <int n_components_, int dim, int spacedim, typename Number>
2296 const unsigned int point_index) const
2297{
2298 AssertIndexRange(point_index, n_q_points);
2299 Assert(inverse_jacobian_ptr != nullptr,
2301 ExcFEPointEvaluationAccessToUninitializedMappingField(
2302 "update_inverse_jacobians"));
2303 return inverse_jacobian_ptr
2304 [cell_type <=
2306 0 :
2307 point_index];
2308}
2309
2310
2311
2312template <int n_components_, int dim, int spacedim, typename Number>
2313inline Number
2315 const unsigned int point_index) const
2316{
2317 AssertIndexRange(point_index, n_q_points);
2318 Assert(JxW_ptr != nullptr,
2320 ExcFEPointEvaluationAccessToUninitializedMappingField(
2321 "update_JxW_values"));
2322 return JxW_ptr[point_index];
2323}
2324
2325
2326
2327template <int n_components_, int dim, int spacedim, typename Number>
2330 const unsigned int point_index) const
2331{
2332 return quadrature_point(point_index);
2333 ;
2334}
2335
2336
2337
2338template <int n_components_, int dim, int spacedim, typename Number>
2341 const unsigned int point_index) const
2342{
2343 AssertIndexRange(point_index, n_q_points);
2344 Assert(real_point_ptr != nullptr,
2346 ExcFEPointEvaluationAccessToUninitializedMappingField(
2347 "update_quadrature_points"));
2348 return real_point_ptr[point_index];
2349}
2350
2351
2352
2353template <int n_components_, int dim, int spacedim, typename Number>
2354inline Point<dim, Number>
2356 const unsigned int point_index) const
2357{
2358 AssertIndexRange(point_index, n_q_points);
2359 Assert(unit_point_ptr != nullptr, ExcMessage("unit_point_ptr is not set!"));
2360 Point<dim, Number> unit_point;
2361 for (unsigned int d = 0; d < dim; ++d)
2363 unit_point_ptr[point_index / stride][d], point_index % stride);
2364 return unit_point;
2365}
2366
2367
2368
2369template <int n_components_, int dim, int spacedim, typename Number>
2376
2377
2378
2379template <int n_components_, int dim, int spacedim, typename Number>
2383 const unsigned int first_selected_component)
2384 : FEPointEvaluationBase<n_components_, dim, spacedim, Number>(
2385 mapping_info,
2386 fe,
2387 first_selected_component)
2388{}
2389
2390
2391
2392template <int n_components_, int dim, int spacedim, typename Number>
2394 const Mapping<dim, spacedim> &mapping,
2396 const UpdateFlags update_flags,
2397 const unsigned int first_selected_component)
2398 : FEPointEvaluationBase<n_components_, dim, spacedim, Number>(
2399 mapping,
2400 fe,
2401 update_flags,
2402 first_selected_component)
2403{}
2404
2405
2406
2407template <int n_components_, int dim, int spacedim, typename Number>
2408inline void
2411{
2412 this->current_cell_index = numbers::invalid_unsigned_int;
2413 this->current_face_number = numbers::invalid_unsigned_int;
2414
2415 if (this->use_linear_path)
2416 this->template do_reinit<false, true>();
2417 else
2418 this->template do_reinit<false, false>();
2419}
2420
2421
2422
2423template <int n_components_, int dim, int spacedim, typename Number>
2424inline void
2426{
2427 internal_reinit_single_cell_state_mapping_info();
2428 this->must_reinitialize_pointers = false;
2429}
2430
2431
2432
2433template <int n_components_, int dim, int spacedim, typename Number>
2434inline void
2437 const ArrayView<const Point<dim>> &unit_points)
2438{
2439 // reinit is only allowed for mapping computation on the fly
2440 AssertThrow(this->mapping_info_on_the_fly.get() != nullptr,
2442
2443 this->mapping_info_on_the_fly->reinit(cell, unit_points);
2444 this->must_reinitialize_pointers = false;
2445
2446 if (!this->fast_path)
2447 {
2448 this->fe_values = std::make_shared<FEValues<dim, spacedim>>(
2449 *this->mapping,
2450 *this->fe,
2452 std::vector<Point<dim>>(unit_points.begin(), unit_points.end())),
2453 this->update_flags);
2454 this->fe_values->reinit(cell);
2455 }
2456
2457 if (this->use_linear_path)
2458 this->template do_reinit<false, true>();
2459 else
2460 this->template do_reinit<false, false>();
2461}
2462
2463
2464
2465template <int n_components_, int dim, int spacedim, typename Number>
2466inline void
2468 const unsigned int cell_index)
2469{
2470 this->current_cell_index = cell_index;
2471 this->current_face_number = numbers::invalid_unsigned_int;
2472 this->must_reinitialize_pointers = false;
2473
2474 if (this->use_linear_path)
2475 this->template do_reinit<false, true>();
2476 else
2477 this->template do_reinit<false, false>();
2478
2479 if (!this->fast_path)
2480 {
2481 std::vector<Point<dim>> unit_points(this->n_q_points_scalar);
2482
2483 for (unsigned int v = 0; v < this->n_q_points_scalar; ++v)
2484 for (unsigned int d = 0; d < dim; ++d)
2485 unit_points[v][d] =
2486 this->unit_point_ptr[v / n_lanes_internal][d][v % n_lanes_internal];
2487
2488 this->fe_values = std::make_shared<FEValues<dim, spacedim>>(
2489 *this->mapping,
2490 *this->fe,
2492 std::vector<Point<dim>>(unit_points.begin(), unit_points.end())),
2493 this->update_flags);
2494
2495 this->fe_values->reinit(
2496 this->mapping_info->get_cell_iterator(this->current_cell_index));
2497 }
2498}
2499
2500
2501
2502template <int n_components_, int dim, int spacedim, typename Number>
2503template <std::size_t stride_view>
2504void
2507 const EvaluationFlags::EvaluationFlags &evaluation_flags)
2508{
2509 Assert(!(evaluation_flags & EvaluationFlags::hessians), ExcNotImplemented());
2510
2511 if (!((evaluation_flags & EvaluationFlags::values) ||
2512 (evaluation_flags & EvaluationFlags::gradients))) // no evaluation flags
2513 return;
2514
2515 if (this->must_reinitialize_pointers)
2516 internal_reinit_single_cell_state_mapping_info();
2517
2518 if (this->n_q_points == 0)
2519 return;
2520
2521 AssertDimension(solution_values.size(), this->fe->dofs_per_cell);
2522 if (this->fast_path)
2523 {
2524 if (this->use_linear_path)
2525 evaluate_fast<true>(solution_values, evaluation_flags);
2526 else
2527 evaluate_fast<false>(solution_values, evaluation_flags);
2528 }
2529 else
2530 evaluate_slow(solution_values, evaluation_flags);
2531}
2532
2533
2534
2535template <int n_components_, int dim, int spacedim, typename Number>
2536void
2538 const ArrayView<const ScalarNumber> &solution_values,
2539 const EvaluationFlags::EvaluationFlags &evaluation_flags)
2540{
2541 evaluate(StridedArrayView<const ScalarNumber, 1>(solution_values.data(),
2542 solution_values.size()),
2543 evaluation_flags);
2544}
2545
2546
2547
2548template <int n_components_, int dim, int spacedim, typename Number>
2549template <std::size_t stride_view>
2550void
2552 const StridedArrayView<ScalarNumber, stride_view> &solution_values,
2553 const EvaluationFlags::EvaluationFlags &integration_flags,
2554 const bool sum_into_values)
2555{
2556 do_integrate<true>(solution_values, integration_flags, sum_into_values);
2557}
2558
2559
2560
2561template <int n_components_, int dim, int spacedim, typename Number>
2562void
2564 const ArrayView<ScalarNumber> &solution_values,
2565 const EvaluationFlags::EvaluationFlags &integration_flags,
2566 const bool sum_into_values)
2567{
2568 integrate(StridedArrayView<ScalarNumber, 1>(solution_values.data(),
2569 solution_values.size()),
2570 integration_flags,
2571 sum_into_values);
2572}
2573
2574
2575
2576template <int n_components_, int dim, int spacedim, typename Number>
2578 scalar_value_type
2580 const
2581{
2582 value_type return_value = {};
2583
2584 for (const auto point_index : this->quadrature_point_indices())
2585 return_value += values[point_index] * this->JxW(point_index);
2586
2587 return ETT::sum_value(return_value);
2588}
2589
2590
2591
2592template <int n_components_, int dim, int spacedim, typename Number>
2593unsigned int
2596{
2597 Assert(stride == 1,
2598 ExcMessage(
2599 "Calling this function only makes sense in fully vectorized mode."));
2600 if (q == n_q_batches - 1)
2601 {
2602 const unsigned int n_filled_lanes =
2603 n_q_points_scalar & (n_lanes_user_interface - 1);
2604 if (n_filled_lanes == 0)
2605 return n_lanes_user_interface;
2606 else
2607 return n_filled_lanes;
2608 }
2609 else
2610 return n_lanes_user_interface;
2611}
2612
2613
2614
2615template <int n_components_, int dim, int spacedim, typename Number>
2616template <std::size_t stride_view>
2617void
2619 const StridedArrayView<ScalarNumber, stride_view> &solution_values,
2620 const EvaluationFlags::EvaluationFlags &integration_flags,
2621 const bool sum_into_values)
2622{
2623 do_integrate<false>(solution_values, integration_flags, sum_into_values);
2624}
2625
2626
2627
2628template <int n_components_, int dim, int spacedim, typename Number>
2629void
2631 const ArrayView<ScalarNumber> &solution_values,
2632 const EvaluationFlags::EvaluationFlags &integration_flags,
2633 const bool sum_into_values)
2634{
2635 test_and_sum(StridedArrayView<ScalarNumber, 1>(solution_values.data(),
2636 solution_values.size()),
2637 integration_flags,
2638 sum_into_values);
2639}
2640
2641
2642
2643template <int n_components_, int dim, int spacedim, typename Number>
2644template <bool is_linear, std::size_t stride_view>
2645inline void
2648{
2649 const unsigned int dofs_per_comp =
2650 is_linear ? Utilities::pow(2, dim) : this->dofs_per_component;
2651
2652 for (unsigned int comp = 0; comp < n_components; ++comp)
2653 {
2654 const std::size_t offset =
2655 (this->component_in_base_element + comp) * dofs_per_comp;
2656
2657 if ((is_linear && n_components == 1) || this->renumber.empty())
2658 {
2659 for (unsigned int i = 0; i < dofs_per_comp; ++i)
2660 ETT::read_value(solution_values[i + offset],
2661 comp,
2662 this->solution_renumbered[i]);
2663 }
2664 else
2665 {
2666 const unsigned int *renumber_ptr = this->renumber.data() + offset;
2667 for (unsigned int i = 0; i < dofs_per_comp; ++i)
2668 ETT::read_value(solution_values[renumber_ptr[i]],
2669 comp,
2670 this->solution_renumbered[i]);
2671 }
2672 }
2673}
2674
2675
2676
2677template <int n_components_, int dim, int spacedim, typename Number>
2678template <bool is_linear, std::size_t stride_view>
2679inline void
2682 const EvaluationFlags::EvaluationFlags &evaluation_flags,
2683 const unsigned int n_shapes,
2684 const unsigned int qb,
2685 vectorized_value_type &value,
2687{
2688 if (evaluation_flags & EvaluationFlags::gradients)
2689 {
2690 std::array<vectorized_value_type, dim + 1> result;
2691 if constexpr (is_linear)
2692 {
2693 if constexpr (n_components == 1)
2694 result =
2696 dim,
2699 1,
2700 stride_view>(solution_values.data(), this->unit_point_ptr[qb]);
2701 else
2702 result =
2704 this->solution_renumbered.data(), this->unit_point_ptr[qb]);
2705 }
2706 else
2708 dim,
2711 1,
2712 false>(this->shapes.data() + qb * n_shapes,
2713 n_shapes,
2714 this->solution_renumbered.data());
2715 gradient[0] = result[0];
2716 if (dim > 1)
2717 gradient[1] = result[1];
2718 if (dim > 2)
2719 gradient[2] = result[2];
2720 value = result[dim];
2721 }
2722 else
2723 {
2724 if constexpr (is_linear)
2725 {
2726 if constexpr (n_components == 1)
2728 dim,
2731 stride_view>(solution_values.data(), this->unit_point_ptr[qb]);
2732 else
2734 this->solution_renumbered.data(), this->unit_point_ptr[qb]);
2735 }
2736 else
2737 value =
2741 false>(
2742 this->shapes.data() + qb * n_shapes,
2743 n_shapes,
2744 this->solution_renumbered.data());
2745 }
2746}
2747
2748
2749
2750template <int n_components_, int dim, int spacedim, typename Number>
2751template <bool is_linear, std::size_t stride_view>
2752inline void
2755 const EvaluationFlags::EvaluationFlags &evaluation_flags)
2756{
2757 if (!(is_linear && n_components == 1))
2758 prepare_evaluate_fast<is_linear>(solution_values);
2759
2760 // loop over quadrature batches qb
2761 const unsigned int n_shapes = is_linear ? 2 : this->poly.size();
2762
2763 for (unsigned int qb = 0; qb < this->n_q_batches; ++qb)
2764 {
2767
2768 compute_evaluate_fast<is_linear>(
2769 solution_values, evaluation_flags, n_shapes, qb, value, gradient);
2770
2771 if (evaluation_flags & EvaluationFlags::values)
2772 {
2773 for (unsigned int v = 0, offset = qb * stride;
2774 v < stride && (stride == 1 || offset < this->n_q_points_scalar);
2775 ++v, ++offset)
2776 ETT::set_value(value, v, this->values[offset]);
2777 }
2778 if (evaluation_flags & EvaluationFlags::gradients)
2779 {
2780 Assert(this->update_flags & update_gradients ||
2781 this->update_flags & update_inverse_jacobians,
2783
2784 for (unsigned int v = 0, offset = qb * stride;
2785 v < stride && (stride == 1 || offset < this->n_q_points_scalar);
2786 ++v, ++offset)
2787 {
2788 unit_gradient_type unit_gradient;
2789 ETT::set_gradient(gradient, v, unit_gradient);
2790 this->gradients[offset] =
2791 this->cell_type <=
2794 this->inverse_jacobian_ptr[0].transpose(), unit_gradient) :
2796 this
2797 ->inverse_jacobian_ptr[this->cell_type <=
2799 GeometryType::affine ?
2800 0 :
2801 offset]
2802 .transpose(),
2803 unit_gradient);
2804 }
2805 }
2806 }
2807}
2808
2809
2810
2811template <int n_components_, int dim, int spacedim, typename Number>
2812template <std::size_t stride_view>
2813inline void
2816 const EvaluationFlags::EvaluationFlags &evaluation_flags)
2817{
2818 // slow path with FEValues
2819 Assert(this->fe_values.get() != nullptr,
2820 ExcMessage(
2821 "Not initialized. Please call FEPointEvaluation::reinit()!"));
2822
2823 const std::size_t n_points = this->fe_values->get_quadrature().size();
2824
2825 if (evaluation_flags & EvaluationFlags::values)
2826 {
2827 this->values.resize(this->n_q_points);
2828 std::fill(this->values.begin(), this->values.end(), value_type());
2829 for (unsigned int i = 0; i < this->fe->n_dofs_per_cell(); ++i)
2830 {
2831 const ScalarNumber value = solution_values[i];
2832 for (unsigned int d = 0; d < n_components; ++d)
2833 if (this->nonzero_shape_function_component[i][d] &&
2834 (this->fe->is_primitive(i) || this->fe->is_primitive()))
2835 for (unsigned int qb = 0, q = 0; q < n_points;
2836 ++qb, q += n_lanes_user_interface)
2837 for (unsigned int v = 0;
2838 v < n_lanes_user_interface && q + v < n_points;
2839 ++v)
2840 ETT::access(this->values[qb],
2841 v,
2842 d,
2843 this->fe_values->shape_value(i, q + v) * value);
2844 else if (this->nonzero_shape_function_component[i][d])
2845 for (unsigned int qb = 0, q = 0; q < n_points;
2846 ++qb, q += n_lanes_user_interface)
2847 for (unsigned int v = 0;
2848 v < n_lanes_user_interface && q + v < n_points;
2849 ++v)
2850 ETT::access(this->values[qb],
2851 v,
2852 d,
2853 this->fe_values->shape_value_component(i,
2854 q + v,
2855 d) *
2856 value);
2857 }
2858 }
2859
2860 if (evaluation_flags & EvaluationFlags::gradients)
2861 {
2862 this->gradients.resize(this->n_q_points);
2863 std::fill(this->gradients.begin(),
2864 this->gradients.end(),
2865 gradient_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->gradients[qb],
2878 v,
2879 d,
2880 this->fe_values->shape_grad(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(
2888 this->gradients[qb],
2889 v,
2890 d,
2891 this->fe_values->shape_grad_component(i, q + v, d) * value);
2892 }
2893 }
2894}
2895
2896
2897
2898template <int n_components_, int dim, int spacedim, typename Number>
2899template <bool is_linear>
2900inline void
2902 const EvaluationFlags::EvaluationFlags &integration_flags,
2903 const unsigned int n_shapes,
2904 const unsigned int qb,
2905 const vectorized_value_type value,
2907 vectorized_value_type *solution_values_vectorized_linear)
2908{
2909 if (integration_flags & EvaluationFlags::gradients)
2911 is_linear,
2912 dim,
2914 vectorized_value_type>(this->shapes.data() + qb * n_shapes,
2915 n_shapes,
2916 &value,
2917 gradient,
2918 is_linear ?
2919 solution_values_vectorized_linear :
2920 this->solution_renumbered_vectorized.data(),
2921 this->unit_point_ptr[qb],
2922 qb != 0);
2923 else
2925 dim,
2928 this->shapes.data() + qb * n_shapes,
2929 n_shapes,
2930 value,
2931 is_linear ? solution_values_vectorized_linear :
2932 this->solution_renumbered_vectorized.data(),
2933 this->unit_point_ptr[qb],
2934 qb != 0);
2935}
2936
2937
2938
2939template <int n_components_, int dim, int spacedim, typename Number>
2940template <bool is_linear, std::size_t stride_view>
2941inline void
2943 const StridedArrayView<ScalarNumber, stride_view> &solution_values,
2944 vectorized_value_type *solution_values_vectorized_linear,
2945 const bool sum_into_values)
2946{
2947 if (!sum_into_values && this->fe->n_components() > n_components)
2948 for (unsigned int i = 0; i < solution_values.size(); ++i)
2949 solution_values[i] = 0;
2950
2951 const unsigned int dofs_per_comp =
2952 is_linear ? Utilities::pow(2, dim) : this->dofs_per_component;
2953
2954 for (unsigned int comp = 0; comp < n_components; ++comp)
2955 {
2956 const std::size_t offset =
2957 (this->component_in_base_element + comp) * dofs_per_comp;
2958
2959 if (is_linear || this->renumber.empty())
2960 {
2961 for (unsigned int i = 0; i < dofs_per_comp; ++i)
2962 if (sum_into_values)
2963 solution_values[i + offset] +=
2964 ETT::sum_value(comp,
2965 is_linear ?
2966 *(solution_values_vectorized_linear + i) :
2967 this->solution_renumbered_vectorized[i]);
2968 else
2969 solution_values[i + offset] =
2970 ETT::sum_value(comp,
2971 is_linear ?
2972 *(solution_values_vectorized_linear + i) :
2973 this->solution_renumbered_vectorized[i]);
2974 }
2975 else
2976 {
2977 const unsigned int *renumber_ptr = this->renumber.data() + offset;
2978 for (unsigned int i = 0; i < dofs_per_comp; ++i)
2979 if (sum_into_values)
2980 solution_values[renumber_ptr[i]] +=
2981 ETT::sum_value(comp, this->solution_renumbered_vectorized[i]);
2982 else
2983 solution_values[renumber_ptr[i]] =
2984 ETT::sum_value(comp, this->solution_renumbered_vectorized[i]);
2985 }
2986 }
2987}
2988
2989
2990
2991template <int n_components_, int dim, int spacedim, typename Number>
2992template <bool do_JxW, bool is_linear, std::size_t stride_view>
2993inline void
2995 const StridedArrayView<ScalarNumber, stride_view> &solution_values,
2996 const EvaluationFlags::EvaluationFlags &integration_flags,
2997 const bool sum_into_values)
2998{
2999 // zero out lanes of incomplete last quadrature point batch
3000 if constexpr (stride == 1)
3001 if (const unsigned int n_filled_lanes =
3002 this->n_q_points_scalar & (n_lanes_internal - 1);
3003 n_filled_lanes > 0)
3004 {
3005 if (integration_flags & EvaluationFlags::values)
3006 for (unsigned int v = n_filled_lanes; v < n_lanes_internal; ++v)
3007 ETT::set_zero_value(this->values.back(), v);
3008 if (integration_flags & EvaluationFlags::gradients)
3009 for (unsigned int v = n_filled_lanes; v < n_lanes_internal; ++v)
3010 ETT::set_zero_gradient(this->gradients.back(), v);
3011 }
3012
3013 std::array<vectorized_value_type, is_linear ? Utilities::pow(2, dim) : 0>
3014 solution_values_vectorized_linear = {};
3015
3016 // loop over quadrature batches qb
3017 const unsigned int n_shapes = is_linear ? 2 : this->poly.size();
3018
3019 const bool cartesian_cell =
3021 const bool affine_cell =
3023 for (unsigned int qb = 0; qb < this->n_q_batches; ++qb)
3024 {
3025 vectorized_value_type value = {};
3027
3028 if (integration_flags & EvaluationFlags::values)
3029 for (unsigned int v = 0, offset = qb * stride;
3030 v < stride && (stride == 1 || offset < this->n_q_points_scalar);
3031 ++v, ++offset)
3032 ETT::get_value(value,
3033 v,
3034 do_JxW ? this->values[offset] * this->JxW_ptr[offset] :
3035 this->values[offset]);
3036
3037 if (integration_flags & EvaluationFlags::gradients)
3038 for (unsigned int v = 0, offset = qb * stride;
3039 v < stride && (stride == 1 || offset < this->n_q_points_scalar);
3040 ++v, ++offset)
3041 {
3042 const gradient_type grad_w =
3043 do_JxW ? this->gradients[offset] * this->JxW_ptr[offset] :
3044 this->gradients[offset];
3045 ETT::get_gradient(
3046 gradient,
3047 v,
3048 cartesian_cell ?
3049 apply_diagonal_transformation(this->inverse_jacobian_ptr[0],
3050 grad_w) :
3052 this->inverse_jacobian_ptr[affine_cell ? 0 : offset],
3053 grad_w));
3054 }
3055
3056 compute_integrate_fast<is_linear>(
3057 integration_flags,
3058 n_shapes,
3059 qb,
3060 value,
3061 gradient,
3062 solution_values_vectorized_linear.data());
3063 }
3064
3065 // add between the lanes and write into the result
3066 finish_integrate_fast<is_linear>(solution_values,
3067 solution_values_vectorized_linear.data(),
3068 sum_into_values);
3069}
3070
3071
3072
3073template <int n_components_, int dim, int spacedim, typename Number>
3074template <bool do_JxW, std::size_t stride_view>
3075inline void
3077 const StridedArrayView<ScalarNumber, stride_view> &solution_values,
3078 const EvaluationFlags::EvaluationFlags &integration_flags,
3079 const bool sum_into_values)
3080{
3081 // slow path with FEValues
3082 Assert(this->fe_values.get() != nullptr,
3083 ExcMessage(
3084 "Not initialized. Please call FEPointEvaluation::reinit()!"));
3085 if (!sum_into_values)
3086 for (unsigned int i = 0; i < solution_values.size(); ++i)
3087 solution_values[i] = 0;
3088
3089 const std::size_t n_points = this->fe_values->get_quadrature().size();
3090
3091 if (integration_flags & EvaluationFlags::values)
3092 {
3093 AssertIndexRange(this->n_q_points, this->values.size() + 1);
3094 for (unsigned int i = 0; i < this->fe->n_dofs_per_cell(); ++i)
3095 {
3096 for (unsigned int d = 0; d < n_components; ++d)
3097 if (this->nonzero_shape_function_component[i][d] &&
3098 (this->fe->is_primitive(i) || this->fe->is_primitive()))
3099 for (unsigned int qb = 0, q = 0; q < n_points;
3100 ++qb, q += n_lanes_user_interface)
3101 for (unsigned int v = 0;
3102 v < n_lanes_user_interface && q + v < n_points;
3103 ++v)
3104 solution_values[i] +=
3105 this->fe_values->shape_value(i, q + v) *
3106 ETT::access(this->values[qb], v, d) *
3107 (do_JxW ? this->fe_values->JxW(q + v) : 1.);
3108 else if (this->nonzero_shape_function_component[i][d])
3109 for (unsigned int qb = 0, q = 0; q < n_points;
3110 ++qb, q += n_lanes_user_interface)
3111 for (unsigned int v = 0;
3112 v < n_lanes_user_interface && q + v < n_points;
3113 ++v)
3114 solution_values[i] +=
3115 this->fe_values->shape_value_component(i, q + v, d) *
3116 ETT::access(this->values[qb], v, d) *
3117 (do_JxW ? this->fe_values->JxW(q + v) : 1.);
3118 }
3119 }
3120
3121 if (integration_flags & EvaluationFlags::gradients)
3122 {
3123 AssertIndexRange(this->n_q_points, this->gradients.size() + 1);
3124 for (unsigned int i = 0; i < this->fe->n_dofs_per_cell(); ++i)
3125 {
3126 for (unsigned int d = 0; d < n_components; ++d)
3127 if (this->nonzero_shape_function_component[i][d] &&
3128 (this->fe->is_primitive(i) || this->fe->is_primitive()))
3129 for (unsigned int qb = 0, q = 0; q < n_points;
3130 ++qb, q += n_lanes_user_interface)
3131 for (unsigned int v = 0;
3132 v < n_lanes_user_interface && q + v < n_points;
3133 ++v)
3134 solution_values[i] +=
3135 this->fe_values->shape_grad(i, q + v) *
3136 ETT::access(this->gradients[qb], v, d) *
3137 (do_JxW ? this->fe_values->JxW(q + v) : 1.);
3138 else if (this->nonzero_shape_function_component[i][d])
3139 for (unsigned int qb = 0, q = 0; q < n_points;
3140 ++qb, q += n_lanes_user_interface)
3141 for (unsigned int v = 0;
3142 v < n_lanes_user_interface && q + v < n_points;
3143 ++v)
3144 solution_values[i] +=
3145 this->fe_values->shape_grad_component(i, q + v, d) *
3146 ETT::access(this->gradients[qb], v, d) *
3147 (do_JxW ? this->fe_values->JxW(q + v) : 1.);
3148 }
3149 }
3150}
3151
3152
3153
3154template <int n_components_, int dim, int spacedim, typename Number>
3155template <bool do_JxW, std::size_t stride_view>
3156void
3158 const StridedArrayView<ScalarNumber, stride_view> &solution_values,
3159 const EvaluationFlags::EvaluationFlags &integration_flags,
3160 const bool sum_into_values)
3161{
3162 if (this->must_reinitialize_pointers)
3163 internal_reinit_single_cell_state_mapping_info();
3164
3165 Assert(!(integration_flags & EvaluationFlags::hessians), ExcNotImplemented());
3166
3167 if (this->n_q_points == 0 || // no evaluation points provided
3168 !((integration_flags & EvaluationFlags::values) ||
3169 (integration_flags &
3170 EvaluationFlags::gradients))) // no integration flags
3171 {
3172 if (!sum_into_values)
3173 for (unsigned int i = 0; i < solution_values.size(); ++i)
3174 solution_values[i] = 0;
3175 return;
3176 }
3177
3178 Assert(
3179 !do_JxW || this->JxW_ptr != nullptr,
3180 ExcMessage(
3181 "JxW pointer is not set! If you do not want to integrate() use test_and_sum()"));
3182
3183 AssertDimension(solution_values.size(), this->fe->dofs_per_cell);
3184 if (this->fast_path)
3185 {
3186 if (this->use_linear_path)
3187 integrate_fast<do_JxW, true>(solution_values,
3188 integration_flags,
3189 sum_into_values);
3190 else
3191 integrate_fast<do_JxW, false>(solution_values,
3192 integration_flags,
3193 sum_into_values);
3194 }
3195 else
3196 integrate_slow<do_JxW>(solution_values, integration_flags, sum_into_values);
3197}
3198
3199
3200
3201template <int n_components_, int dim, int spacedim, typename Number>
3204 const unsigned int point_index) const
3205{
3206 AssertIndexRange(point_index, this->n_q_points);
3207 Assert(this->normal_ptr != nullptr,
3209 ExcFEPointEvaluationAccessToUninitializedMappingField(
3210 "update_normal_vectors"));
3211 return this->normal_ptr[point_index];
3212}
3213
3214
3215
3216template <int n_components_, int dim, int spacedim, typename Number>
3217inline const typename FEPointEvaluation<n_components_,
3218 dim,
3219 spacedim,
3220 Number>::value_type
3222 const unsigned int point_index) const
3223{
3224 AssertIndexRange(point_index, this->gradients.size());
3225 return this->gradients[point_index] * normal_vector(point_index);
3226}
3227
3228
3229
3230template <int n_components_, int dim, int spacedim, typename Number>
3231inline void
3234 const unsigned int point_index)
3235{
3236 AssertIndexRange(point_index, this->gradients.size());
3237 if constexpr (n_components == 1)
3238 this->gradients[point_index] = value * normal_vector(point_index);
3239 else
3240 this->gradients[point_index] =
3241 outer_product(value, normal_vector(point_index));
3242}
3243
3244
3245
3246template <int n_components_, int dim, int spacedim, typename Number>
3251 const bool is_interior,
3252 const unsigned int first_selected_component)
3253 : FEPointEvaluationBase<n_components_, dim, spacedim, Number>(
3254 mapping_info,
3255 fe,
3256 first_selected_component,
3257 is_interior)
3258{}
3259
3260
3261
3262template <int n_components_, int dim, int spacedim, typename Number>
3263inline void
3265 const unsigned int cell_index,
3266 const unsigned int face_number)
3267{
3268 this->current_cell_index = cell_index;
3269 this->current_face_number = face_number;
3270 this->must_reinitialize_pointers = false;
3271
3272 if (this->use_linear_path)
3273 this->template do_reinit<true, true>();
3274 else
3275 this->template do_reinit<true, false>();
3276}
3277
3278
3279
3280template <int n_components_, int dim, int spacedim, typename Number>
3281inline void
3283 const unsigned int face_index)
3284{
3285 this->current_cell_index = face_index;
3286 this->current_face_number =
3287 this->mapping_info->get_face_number(face_index, this->is_interior);
3288 this->must_reinitialize_pointers = false;
3289
3290 if (this->use_linear_path)
3291 this->template do_reinit<true, true>();
3292 else
3293 this->template do_reinit<true, false>();
3294}
3295
3296
3297
3298template <int n_components_, int dim, int spacedim, typename Number>
3299template <std::size_t stride_view>
3300void
3303 const EvaluationFlags::EvaluationFlags &evaluation_flags)
3304{
3305 Assert(!this->must_reinitialize_pointers,
3306 ExcMessage("Object has not been reinitialized!"));
3307
3308 if (this->n_q_points == 0)
3309 return;
3310
3311 Assert(!(evaluation_flags & EvaluationFlags::hessians), ExcNotImplemented());
3312
3313 if (!((evaluation_flags & EvaluationFlags::values) ||
3314 (evaluation_flags & EvaluationFlags::gradients))) // no evaluation flags
3315 return;
3316
3317 AssertDimension(solution_values.size(), this->fe->dofs_per_cell);
3318
3319 if (this->use_linear_path)
3320 do_evaluate<true>(solution_values, evaluation_flags);
3321 else
3322 do_evaluate<false>(solution_values, evaluation_flags);
3323}
3324
3325
3326
3327template <int n_components_, int dim, int spacedim, typename Number>
3328void
3330 const ArrayView<const ScalarNumber> &solution_values,
3331 const EvaluationFlags::EvaluationFlags &evaluation_flags)
3332{
3333 evaluate(StridedArrayView<const ScalarNumber, 1>(solution_values.data(),
3334 solution_values.size()),
3335 evaluation_flags);
3336}
3337
3338
3339
3340template <int n_components_, int dim, int spacedim, typename Number>
3341template <bool is_linear, std::size_t stride_view>
3342void
3345 const EvaluationFlags::EvaluationFlags &evaluation_flags)
3346{
3347 const unsigned int dofs_per_comp =
3348 is_linear ? Utilities::pow(2, dim) : this->dofs_per_component;
3349
3350 const ScalarNumber *input;
3351 if (stride_view == 1 && this->component_in_base_element == 0 &&
3352 (is_linear || this->renumber.empty()))
3353 input = solution_values.data();
3354 else
3355 {
3356 for (unsigned int comp = 0; comp < n_components; ++comp)
3357 {
3358 const std::size_t offset =
3359 (this->component_in_base_element + comp) * dofs_per_comp;
3360
3361 if (is_linear || this->renumber.empty())
3362 {
3363 for (unsigned int i = 0; i < dofs_per_comp; ++i)
3364 this->scratch_data_scalar[i + comp * dofs_per_comp] =
3365 solution_values[i + offset];
3366 }
3367 else
3368 {
3369 const unsigned int *renumber_ptr = this->renumber.data() + offset;
3370 for (unsigned int i = 0; i < dofs_per_comp; ++i)
3371 this->scratch_data_scalar[i + comp * dofs_per_comp] =
3372 solution_values[renumber_ptr[i]];
3373 }
3374 }
3375 input = this->scratch_data_scalar.data();
3376 }
3377
3378 ScalarNumber *output =
3379 this->scratch_data_scalar.begin() + dofs_per_comp * n_components;
3380
3381 internal::FEFaceNormalEvaluationImpl<dim, is_linear ? 1 : -1, ScalarNumber>::
3382 template interpolate<true, false>(n_components,
3383 evaluation_flags,
3384 this->shape_info,
3385 input,
3386 output,
3387 this->current_face_number);
3388
3389 do_evaluate_in_face<is_linear, 1>(output, evaluation_flags);
3390}
3391
3392
3393
3394template <int n_components_, int dim, int spacedim, typename Number>
3395template <std::size_t stride_view>
3396void
3398 const StridedArrayView<ScalarNumber, stride_view> &solution_values,
3399 const EvaluationFlags::EvaluationFlags &integration_flags,
3400 const bool sum_into_values)
3401{
3402 Assert(!this->must_reinitialize_pointers,
3403 ExcMessage("Object has not been reinitialized!"));
3404
3405 Assert(!(integration_flags & EvaluationFlags::hessians), ExcNotImplemented());
3406
3407 if (this->n_q_points == 0 || // no evaluation points provided
3408 !((integration_flags & EvaluationFlags::values) ||
3409 (integration_flags &
3410 EvaluationFlags::gradients))) // no integration flags
3411 {
3412 if (!sum_into_values)
3413 for (unsigned int i = 0; i < solution_values.size(); ++i)
3414 solution_values[i] = 0;
3415 return;
3416 }
3417
3418 AssertDimension(solution_values.size(), this->fe->dofs_per_cell);
3419
3420 if (this->use_linear_path)
3421 do_integrate<true, true>(solution_values,
3422 integration_flags,
3423 sum_into_values);
3424 else
3425 do_integrate<true, false>(solution_values,
3426 integration_flags,
3427 sum_into_values);
3428}
3429
3430
3431
3432template <int n_components_, int dim, int spacedim, typename Number>
3433void
3435 const ArrayView<ScalarNumber> &solution_values,
3436 const EvaluationFlags::EvaluationFlags &integration_flags,
3437 const bool sum_into_values)
3438{
3439 integrate(StridedArrayView<ScalarNumber, 1>(solution_values.data(),
3440 solution_values.size()),
3441 integration_flags,
3442 sum_into_values);
3443}
3444
3445
3446
3447template <int n_components_, int dim, int spacedim, typename Number>
3448template <std::size_t stride_view>
3449void
3451 const StridedArrayView<ScalarNumber, stride_view> &solution_values,
3452 const EvaluationFlags::EvaluationFlags &integration_flags,
3453 const bool sum_into_values)
3454{
3455 Assert(!this->must_reinitialize_pointers,
3456 ExcMessage("Object has not been reinitialized!"));
3457
3458 Assert(!(integration_flags & EvaluationFlags::hessians), ExcNotImplemented());
3459
3460 if (this->n_q_points == 0 || // no evaluation points provided
3461 !((integration_flags & EvaluationFlags::values) ||
3462 (integration_flags &
3463 EvaluationFlags::gradients))) // no integration flags
3464 {
3465 if (!sum_into_values)
3466 for (unsigned int i = 0; i < solution_values.size(); ++i)
3467 solution_values[i] = 0;
3468 return;
3469 }
3470
3471 AssertDimension(solution_values.size(), this->fe->dofs_per_cell);
3472
3473 if (this->use_linear_path)
3474 do_integrate<false, true>(solution_values,
3475 integration_flags,
3476 sum_into_values);
3477 else
3478 do_integrate<false, false>(solution_values,
3479 integration_flags,
3480 sum_into_values);
3481}
3482
3483
3484
3485template <int n_components_, int dim, int spacedim, typename Number>
3486void
3488 const ArrayView<ScalarNumber> &solution_values,
3489 const EvaluationFlags::EvaluationFlags &integration_flags,
3490 const bool sum_into_values)
3491{
3492 test_and_sum(StridedArrayView<ScalarNumber, 1>(solution_values.data(),
3493 solution_values.size()),
3494 integration_flags,
3495 sum_into_values);
3496}
3497
3498
3499
3500template <int n_components_, int dim, int spacedim, typename Number>
3501template <bool do_JxW, bool is_linear, std::size_t stride_view>
3502void
3504 const StridedArrayView<ScalarNumber, stride_view> &solution_values,
3505 const EvaluationFlags::EvaluationFlags &integration_flags,
3506 const bool sum_into_values)
3507{
3508 if (!sum_into_values && this->fe->n_components() > n_components)
3509 for (unsigned int i = 0; i < solution_values.size(); ++i)
3510 solution_values[i] = 0;
3511
3512 do_integrate_in_face<do_JxW, is_linear, 1>(this->scratch_data_scalar.begin(),
3513 integration_flags,
3514 false);
3515
3516 ScalarNumber *input = this->scratch_data_scalar.begin();
3517
3518 if (stride_view == 1 && this->component_in_base_element == 0 &&
3519 (is_linear || this->renumber.empty()))
3520 {
3521 if (sum_into_values)
3522 internal::
3523 FEFaceNormalEvaluationImpl<dim, is_linear ? 1 : -1, ScalarNumber>::
3524 template interpolate<false, true>(n_components,
3525 integration_flags,
3526 this->shape_info,
3527 input,
3528 solution_values.data(),
3529 this->current_face_number);
3530 else
3531 internal::
3532 FEFaceNormalEvaluationImpl<dim, is_linear ? 1 : -1, ScalarNumber>::
3533 template interpolate<false, false>(n_components,
3534 integration_flags,
3535 this->shape_info,
3536 input,
3537 solution_values.data(),
3538 this->current_face_number);
3539 }
3540 else
3541 {
3542 const unsigned int dofs_per_comp_face =
3543 is_linear ? Utilities::pow(2, dim - 1) : this->dofs_per_component_face;
3544
3545 const unsigned int size_input = 3 * dofs_per_comp_face * n_components;
3546 ScalarNumber *output = input + size_input;
3547
3548 internal::
3549 FEFaceNormalEvaluationImpl<dim, is_linear ? 1 : -1, ScalarNumber>::
3550 template interpolate<false, false>(n_components,
3551 integration_flags,
3552 this->shape_info,
3553 input,
3554 output,
3555 this->current_face_number);
3556
3557 const unsigned int dofs_per_comp =
3558 is_linear ? Utilities::pow(2, dim) : this->dofs_per_component;
3559
3560 for (unsigned int comp = 0; comp < n_components; ++comp)
3561 {
3562 const std::size_t offset =
3563 (this->component_in_base_element + comp) * dofs_per_comp;
3564
3565 if (is_linear || this->renumber.empty())
3566 {
3567 for (unsigned int i = 0; i < dofs_per_comp; ++i)
3568 if (sum_into_values)
3569 solution_values[i + offset] +=
3570 output[i + comp * dofs_per_comp];
3571 else
3572 solution_values[i + offset] =
3573 output[i + comp * dofs_per_comp];
3574 }
3575 else
3576 {
3577 const unsigned int *renumber_ptr = this->renumber.data() + offset;
3578 for (unsigned int i = 0; i < dofs_per_comp; ++i)
3579 if (sum_into_values)
3580 solution_values[renumber_ptr[i]] +=
3581 output[i + comp * dofs_per_comp];
3582 else
3583 solution_values[renumber_ptr[i]] =
3584 output[i + comp * dofs_per_comp];
3585 }
3586 }
3587 }
3588}
3589
3590
3591
3592template <int n_components_, int dim, int spacedim, typename Number>
3593template <int stride_face_dof>
3594void
3596 const ScalarNumber *face_dof_values,
3597 const EvaluationFlags::EvaluationFlags &evaluation_flags)
3598{
3599 if (this->use_linear_path)
3600 do_evaluate_in_face<true, stride_face_dof>(face_dof_values,
3601 evaluation_flags);
3602 else
3603 do_evaluate_in_face<false, stride_face_dof>(face_dof_values,
3604 evaluation_flags);
3605}
3606
3607
3608
3609template <int n_components_, int dim, int spacedim, typename Number>
3610template <bool is_linear, int stride_face_dof>
3611inline void
3613 do_evaluate_in_face(const ScalarNumber *face_dof_values,
3614 const EvaluationFlags::EvaluationFlags &evaluation_flags)
3615{
3616 const scalar_value_type *face_dof_values_ptr;
3617 if constexpr (n_components == 1)
3618 face_dof_values_ptr = face_dof_values;
3619 else
3620 {
3621 const unsigned int dofs_per_comp_face =
3622 is_linear ? Utilities::pow(2, dim - 1) : this->dofs_per_component_face;
3623 for (unsigned int comp = 0; comp < n_components; ++comp)
3624 for (unsigned int i = 0; i < 2 * dofs_per_comp_face; ++i)
3625 ETT::read_value(face_dof_values[(i + comp * 3 * dofs_per_comp_face) *
3626 stride_face_dof],
3627 comp,
3628 this->solution_renumbered[i]);
3629
3630 face_dof_values_ptr = this->solution_renumbered.data();
3631 }
3632
3633 constexpr int stride_face_dof_actual =
3634 n_components == 1 ? stride_face_dof : 1;
3635
3636 // loop over quadrature batches qb
3637 const unsigned int n_shapes = is_linear ? 2 : this->poly.size();
3638
3639 for (unsigned int qb = 0; qb < this->n_q_batches; ++qb)
3640 {
3643
3644 if (evaluation_flags & EvaluationFlags::gradients)
3645 {
3646 const std::array<vectorized_value_type, dim + 1> interpolated_value =
3647 is_linear ?
3649 dim - 1,
3652 2,
3653 stride_face_dof_actual>(face_dof_values_ptr,
3654 this->unit_point_faces_ptr[qb]) :
3656 dim - 1,
3659 2,
3660 false,
3661 stride_face_dof_actual>(this->shapes_faces.data() +
3662 qb * n_shapes,
3663 n_shapes,
3664 face_dof_values_ptr);
3665
3666 value = interpolated_value[dim - 1];
3667 // reorder derivative from tangential/normal derivatives into tensor
3668 // in physical coordinates
3669 if (this->current_face_number / 2 == 0)
3670 {
3671 gradient[0] = interpolated_value[dim];
3672 if (dim > 1)
3673 gradient[1] = interpolated_value[0];
3674 if (dim > 2)
3675 gradient[2] = interpolated_value[1];
3676 }
3677 else if (this->current_face_number / 2 == 1)
3678 {
3679 if (dim > 1)
3680 gradient[1] = interpolated_value[dim];
3681 if (dim == 3)
3682 {
3683 gradient[0] = interpolated_value[1];
3684 gradient[2] = interpolated_value[0];
3685 }
3686 else if (dim == 2)
3687 gradient[0] = interpolated_value[0];
3688 else
3690 }
3691 else if (this->current_face_number / 2 == 2)
3692 {
3693 if (dim > 2)
3694 {
3695 gradient[0] = interpolated_value[0];
3696 gradient[1] = interpolated_value[1];
3697 gradient[2] = interpolated_value[dim];
3698 }
3699 else
3701 }
3702 else
3704 }
3705 else
3706 {
3707 value = is_linear ?
3709 dim - 1,
3712 stride_face_dof_actual>(face_dof_values_ptr,
3713 this->unit_point_faces_ptr[qb]) :
3715 dim - 1,
3718 false,
3719 stride_face_dof_actual>(this->shapes_faces.data() +
3720 qb * n_shapes,
3721 n_shapes,
3722 face_dof_values_ptr);
3723 }
3724
3725 if (evaluation_flags & EvaluationFlags::values)
3726 {
3727 for (unsigned int v = 0, offset = qb * stride;
3728 v < stride && (stride == 1 || offset < this->n_q_points_scalar);
3729 ++v, ++offset)
3730 ETT::set_value(value, v, this->values[offset]);
3731 }
3732 if (evaluation_flags & EvaluationFlags::gradients)
3733 {
3734 Assert(this->update_flags & update_gradients ||
3735 this->update_flags & update_inverse_jacobians,
3737
3738 for (unsigned int v = 0, offset = qb * stride;
3739 v < stride && (stride == 1 || offset < this->n_q_points_scalar);
3740 ++v, ++offset)
3741 {
3742 unit_gradient_type unit_gradient;
3743 ETT::set_gradient(gradient, v, unit_gradient);
3744 this->gradients[offset] =
3745 this->cell_type <=
3748 this->inverse_jacobian_ptr[0].transpose(), unit_gradient) :
3750 this
3751 ->inverse_jacobian_ptr[this->cell_type <=
3753 GeometryType::affine ?
3754 0 :
3755 offset]
3756 .transpose(),
3757 unit_gradient);
3758 }
3759 }
3760 }
3761}
3762
3763
3764
3765template <int n_components_, int dim, int spacedim, typename Number>
3766template <int stride_face_dof>
3767void
3769 ScalarNumber *face_dof_values,
3770 const EvaluationFlags::EvaluationFlags &integration_flags,
3771 const bool sum_into_values)
3772{
3773 if (this->use_linear_path)
3774 do_integrate_in_face<true, true, stride_face_dof>(face_dof_values,
3775 integration_flags,
3776 sum_into_values);
3777 else
3778 do_integrate_in_face<true, false, stride_face_dof>(face_dof_values,
3779 integration_flags,
3780 sum_into_values);
3781}
3782
3783
3784
3785template <int n_components_, int dim, int spacedim, typename Number>
3786template <bool do_JxW, bool is_linear, int stride_face_dof>
3787inline void
3790 ScalarNumber *face_dof_values,
3791 const EvaluationFlags::EvaluationFlags &integration_flags,
3792 const bool sum_into_values)
3793{
3794 // zero out lanes of incomplete last quadrature point batch
3795 if constexpr (stride == 1)
3796 if (const unsigned int n_filled_lanes =
3797 this->n_q_points_scalar & (n_lanes_internal - 1);
3798 n_filled_lanes > 0)
3799 {
3800 if (integration_flags & EvaluationFlags::values)
3801 for (unsigned int v = n_filled_lanes; v < n_lanes_internal; ++v)
3802 ETT::set_zero_value(this->values.back(), v);
3803 if (integration_flags & EvaluationFlags::gradients)
3804 for (unsigned int v = n_filled_lanes; v < n_lanes_internal; ++v)
3805 ETT::set_zero_gradient(this->gradients.back(), v);
3806 }
3807
3808 std::array<vectorized_value_type,
3809 is_linear ? 2 * Utilities::pow(2, dim - 1) : 0>
3810 solution_values_vectorized_linear = {};
3811
3812 // loop over quadrature batches qb
3813 const unsigned int n_shapes = is_linear ? 2 : this->poly.size();
3814
3815 const bool cartesian_cell =
3817 const bool affine_cell =
3819 for (unsigned int qb = 0; qb < this->n_q_batches; ++qb)
3820 {
3821 vectorized_value_type value = {};
3823
3824 if (integration_flags & EvaluationFlags::values)
3825 for (unsigned int v = 0, offset = qb * stride;
3826 v < stride && (stride == 1 || offset < this->n_q_points_scalar);
3827 ++v, ++offset)
3828 ETT::get_value(value,
3829 v,
3830 do_JxW ? this->values[offset] * this->JxW_ptr[offset] :
3831 this->values[offset]);
3832
3833 if (integration_flags & EvaluationFlags::gradients)
3834 for (unsigned int v = 0, offset = qb * stride;
3835 v < stride && (stride == 1 || offset < this->n_q_points_scalar);
3836 ++v, ++offset)
3837 {
3838 const auto grad_w =
3839 do_JxW ? this->gradients[offset] * this->JxW_ptr[offset] :
3840 this->gradients[offset];
3841 ETT::get_gradient(
3842 gradient,
3843 v,
3844 cartesian_cell ?
3845 apply_diagonal_transformation(this->inverse_jacobian_ptr[0],
3846 grad_w) :
3848 this->inverse_jacobian_ptr[affine_cell ? 0 : offset],
3849 grad_w));
3850 }
3851
3852 if (integration_flags & EvaluationFlags::gradients)
3853 {
3854 std::array<vectorized_value_type, 2> value_face = {};
3855 Tensor<1, dim - 1, vectorized_value_type> gradient_in_face;
3856
3857 value_face[0] = value;
3858 // fill derivative in physical coordinates into tangential/normal
3859 // derivatives
3860 if (this->current_face_number / 2 == 0)
3861 {
3862 value_face[1] = gradient[0];
3863 if (dim > 1)
3864 gradient_in_face[0] = gradient[1];
3865 if (dim > 2)
3866 gradient_in_face[1] = gradient[2];
3867 }
3868 else if (this->current_face_number / 2 == 1)
3869 {
3870 if (dim > 1)
3871 value_face[1] = gradient[1];
3872 if (dim == 3)
3873 {
3874 gradient_in_face[0] = gradient[2];
3875 gradient_in_face[1] = gradient[0];
3876 }
3877 else if (dim == 2)
3878 gradient_in_face[0] = gradient[0];
3879 else
3881 }
3882 else if (this->current_face_number / 2 == 2)
3883 {
3884 if (dim > 2)
3885 {
3886 value_face[1] = gradient[2];
3887 gradient_in_face[0] = gradient[0];
3888 gradient_in_face[1] = gradient[1];
3889 }
3890 else
3892 }
3893 else
3895
3897 is_linear,
3898 dim - 1,
3901 2>(this->shapes_faces.data() + qb * n_shapes,
3902 n_shapes,
3903 value_face.data(),
3904 gradient_in_face,
3905 is_linear ? solution_values_vectorized_linear.data() :
3906 this->solution_renumbered_vectorized.data(),
3907 this->unit_point_faces_ptr[qb],
3908 qb != 0);
3909 }
3910 else
3912 dim - 1,
3915 this->shapes_faces.data() + qb * n_shapes,
3916 n_shapes,
3917 value,
3918 is_linear ? solution_values_vectorized_linear.data() :
3919 this->solution_renumbered_vectorized.data(),
3920 this->unit_point_faces_ptr[qb],
3921 qb != 0);
3922 }
3923
3924 const unsigned int dofs_per_comp_face =
3925 is_linear ? Utilities::pow(2, dim - 1) : this->dofs_per_component_face;
3926
3927 for (unsigned int comp = 0; comp < n_components; ++comp)
3928 for (unsigned int i = 0; i < 2 * dofs_per_comp_face; ++i)
3929 if (sum_into_values)
3930 face_dof_values[(i + comp * 3 * dofs_per_comp_face) *
3931 stride_face_dof] +=
3932 ETT::sum_value(comp,
3933 is_linear ?
3934 *(solution_values_vectorized_linear.data() + i) :
3935 this->solution_renumbered_vectorized[i]);
3936 else
3937 face_dof_values[(i + comp * 3 * dofs_per_comp_face) * stride_face_dof] =
3938 ETT::sum_value(comp,
3939 is_linear ?
3940 *(solution_values_vectorized_linear.data() + i) :
3941 this->solution_renumbered_vectorized[i]);
3942}
3943
3944
3945
3946template <int n_components_, int dim, int spacedim, typename Number>
3949 const unsigned int point_index) const
3950{
3951 AssertIndexRange(point_index, this->n_q_points);
3952 Assert(this->normal_ptr != nullptr,
3954 ExcFEPointEvaluationAccessToUninitializedMappingField(
3955 "update_normal_vectors"));
3956 if (this->cell_type <= ::internal::MatrixFreeFunctions::affine)
3957 {
3959 for (unsigned int d = 0; d < dim; ++d)
3960 normal[d] =
3961 internal::VectorizedArrayTrait<Number>::get(this->normal_ptr[0][d],
3962 0);
3963
3964 return normal;
3965 }
3966 else
3967 {
3968 return this->normal_ptr[point_index];
3969 }
3970}
3971
3972
3973
3974template <int n_components_, int dim, int spacedim, typename Number>
3975inline const typename FEFacePointEvaluation<n_components_,
3976 dim,
3977 spacedim,
3978 Number>::value_type
3980 get_normal_derivative(const unsigned int point_index) const
3981{
3982 AssertIndexRange(point_index, this->gradients.size());
3983 return this->gradients[point_index] * normal_vector(point_index);
3984}
3985
3986
3987
3988template <int n_components_, int dim, int spacedim, typename Number>
3989inline void
3992 const unsigned int point_index)
3993{
3994 AssertIndexRange(point_index, this->gradients.size());
3995 if constexpr (n_components == 1)
3996 this->gradients[point_index] = value * normal_vector(point_index);
3997 else
3998 this->gradients[point_index] =
3999 outer_product(value, normal_vector(point_index));
4000}
4001
4003
4004#endif
value_type * data() const noexcept
Definition array_view.h:661
std::size_t size() const
Definition array_view.h:684
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
Point< spacedim, Number > real_point(const unsigned int point_index) const
Tensor< 1,(dim==2 ? 1 :dim), Number > get_curl(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
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
FEPointEvaluation(const Mapping< dim, spacedim > &mapping, const FiniteElement< dim, spacedim > &fe, const UpdateFlags update_flags, const unsigned int first_selected_component=0)
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
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:846
std::size_t size() const
Definition array_view.h:867
Tensor< rank, dim, Number > sum(const Tensor< rank, dim, Number > &local, const MPI_Comm mpi_communicator)
#define DEAL_II_DEPRECATED
Definition config.h:205
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:498
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:499
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)
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)
Definition exceptions.h:511
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.
#define DEAL_II_ASSERT_UNREACHABLE()
#define DEAL_II_NOT_IMPLEMENTED()
EvaluationFlags
The EvaluationFlags enum.
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::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)
static const unsigned int invalid_unsigned_int
Definition types.h:232
boost::integer_range< IncrementableType > iota_view
Definition iota_view.h:45
STL namespace.
typename internal::ndarray::HelperArray< T, Ns... >::type ndarray
Definition ndarray.h:107
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)
DEAL_II_HOST constexpr SymmetricTensor< 4, dim, Number > outer_product(const SymmetricTensor< 2, dim, Number > &t1, const SymmetricTensor< 2, dim, Number > &t2)
DEAL_II_HOST constexpr Number trace(const SymmetricTensor< 2, dim2, Number > &)