Reference documentation for deal.II version 9.5.0
\(\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// Copyright (C) 2020 - 2023 by the deal.II authors
4//
5// This file is part of the deal.II library.
6//
7// The deal.II library is free software; you can use it, redistribute
8// it, and/or modify it under the terms of the GNU Lesser General
9// Public License as published by the Free Software Foundation; either
10// version 2.1 of the License, or (at your option) any later version.
11// The full text of the license can be found in the file LICENSE.md at
12// the top level directory of deal.II.
13//
14// ---------------------------------------------------------------------
15
16#ifndef dealii_fe_point_evaluation_h
17#define dealii_fe_point_evaluation_h
18
19#include <deal.II/base/config.h>
20
25#include <deal.II/base/tensor.h>
27
29#include <deal.II/fe/mapping.h>
30
35
37
39
40namespace internal
41{
43 {
46 std::string,
47 << "You are requesting information from an FEPointEvaluation "
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, int n_components, typename Number>
61 {
65 typename ::internal::VectorizedArrayTrait<
78
79 static void
80 read_value(const ScalarNumber vector_entry,
81 const unsigned int component,
82 scalar_value_type &result)
83 {
84 AssertIndexRange(component, n_components);
85 result[component] = vector_entry;
86 }
87
88 static void
90 const unsigned int component,
91 const vectorized_value_type &result)
92 {
93 AssertIndexRange(component, n_components);
94 vector_entry = result[component];
95 }
96
97 static void
99 const unsigned int vector_lane,
100 gradient_type & result)
101 {
102 for (unsigned int i = 0; i < n_components; ++i)
103 for (unsigned int d = 0; d < dim; ++d)
104 result[i][d] =
106 value[d][i], vector_lane);
107 }
108
109 static void
111 const unsigned int vector_lane,
112 const gradient_type & result)
113 {
114 for (unsigned int i = 0; i < n_components; ++i)
115 for (unsigned int d = 0; d < dim; ++d)
117 value[d][i], vector_lane) = result[i][d];
118 }
119
120 static void
121 set_zero_gradient(gradient_type &value, const unsigned int vector_lane)
122 {
123 for (unsigned int i = 0; i < n_components; ++i)
124 for (unsigned int d = 0; d < dim; ++d)
126 vector_lane) = 0.;
127 }
128
129 static void
131 const unsigned int vector_lane,
132 scalar_value_type & result)
133 {
134 for (unsigned int i = 0; i < n_components; ++i)
135 result[i] = value[i][vector_lane];
136 }
137
138 static void
140 const unsigned int,
141 vectorized_value_type &result)
142 {
143 result = value;
144 }
145
146 static void
148 const unsigned int vector_lane,
149 const scalar_value_type &result)
150 {
151 for (unsigned int i = 0; i < n_components; ++i)
152 value[i][vector_lane] = result[i];
153 }
154
155 static void
157 const unsigned int,
158 const vectorized_value_type &result)
159 {
160 value = result;
161 }
162
163 static void
164 set_zero_value(value_type &value, const unsigned int vector_lane)
165 {
166 for (unsigned int i = 0; i < n_components; ++i)
168 0.;
169 }
170
171 static void
173 const unsigned int vector_lane,
174 const unsigned int component,
175 const ScalarNumber &shape_value)
176 {
178 vector_lane) += shape_value;
179 }
180
181 static ScalarNumber
183 const unsigned int vector_lane,
184 const unsigned int component)
185 {
187 vector_lane);
188 }
189
190 static void
192 const unsigned int vector_lane,
193 const unsigned int component,
194 const Tensor<1, dim, ScalarNumber> &shape_gradient)
195 {
196 for (unsigned int d = 0; d < dim; ++d)
198 vector_lane) +=
199 shape_gradient[d];
200 }
201
204 const unsigned int vector_lane,
205 const unsigned int component)
206 {
208 for (unsigned int d = 0; d < dim; ++d)
209 result[d] =
211 vector_lane);
212 return result;
213 }
214 };
215
216 template <int dim, typename Number>
217 struct EvaluatorTypeTraits<dim, 1, Number>
218 {
222 typename ::internal::VectorizedArrayTrait<
224 using value_type = Number;
231
232 static void
233 read_value(const ScalarNumber vector_entry,
234 const unsigned int,
235 scalar_value_type &result)
236 {
237 result = vector_entry;
238 }
239
240 static void
242 const unsigned int,
243 const vectorized_value_type &result)
244 {
245 vector_entry = result;
246 }
247
248 static void
250 const unsigned int vector_lane,
251 scalar_gradient_type & result)
252 {
253 for (unsigned int d = 0; d < dim; ++d)
254 result[d] = value[d][vector_lane];
255 }
256
257 static void
259 const unsigned int,
261 {
262 result = value;
263 }
264
265 static void
267 const unsigned int vector_lane,
268 const scalar_gradient_type &result)
269 {
270 for (unsigned int d = 0; d < dim; ++d)
271 value[d][vector_lane] = result[d];
272 }
273
274 static void
276 const unsigned int,
277 const vectorized_gradient_type &result)
278 {
279 value = result;
280 }
281
282 static void
283 set_zero_gradient(gradient_type &value, const unsigned int vector_lane)
284 {
285 for (unsigned int d = 0; d < dim; ++d)
287 0.;
288 }
289
290 static void
292 const unsigned int vector_lane,
293 scalar_value_type & result)
294 {
295 result = value[vector_lane];
296 }
297
298 static void
300 const unsigned int,
301 vectorized_value_type &result)
302 {
303 result = value;
304 }
305
306 static void
308 const unsigned int vector_lane,
309 const scalar_value_type &result)
310 {
311 value[vector_lane] = result;
312 }
313
314 static void
316 const unsigned int,
317 const vectorized_value_type &result)
318 {
319 value = result;
320 }
321
322 static void
323 set_zero_value(value_type &value, const unsigned int vector_lane)
324 {
326 }
327
328 static void
330 const unsigned int vector_lane,
331 const unsigned int,
332 const ScalarNumber &shape_value)
333 {
335 shape_value;
336 }
337
338 static ScalarNumber
340 const unsigned int vector_lane,
341 const unsigned int)
342 {
344 }
345
346 static void
348 const unsigned int vector_lane,
349 const unsigned int,
350 const scalar_gradient_type &shape_gradient)
351 {
352 for (unsigned int d = 0; d < dim; ++d)
354 shape_gradient[d];
355 }
356
359 const unsigned int vector_lane,
360 const unsigned int)
361 {
363 for (unsigned int d = 0; d < dim; ++d)
364 result[d] =
366 return result;
367 }
368 };
369
370 template <int dim, typename Number>
371 struct EvaluatorTypeTraits<dim, dim, Number>
372 {
376 typename ::internal::VectorizedArrayTrait<
386
387 static void
388 read_value(const ScalarNumber vector_entry,
389 const unsigned int component,
390 scalar_value_type &result)
391 {
392 result[component] = vector_entry;
393 }
394
395 static void
397 const unsigned int component,
398 const vectorized_value_type &result)
399 {
400 vector_entry = result[component];
401 }
402
403 static void
405 const unsigned int vector_lane,
406 gradient_type & result)
407 {
408 for (unsigned int i = 0; i < dim; ++i)
409 for (unsigned int d = 0; d < dim; ++d)
410 result[i][d] =
412 value[d][i], vector_lane);
413 }
414
415 static void
417 const unsigned int vector_lane,
418 const gradient_type & result)
419 {
420 for (unsigned int i = 0; i < dim; ++i)
421 for (unsigned int d = 0; d < dim; ++d)
423 value[d][i], vector_lane) = result[i][d];
424 }
425
426 static void
427 set_zero_gradient(gradient_type &value, const unsigned int vector_lane)
428 {
429 for (unsigned int i = 0; i < dim; ++i)
430 for (unsigned int d = 0; d < dim; ++d)
432 vector_lane) = 0.;
433 }
434
435 static void
437 const unsigned int vector_lane,
438 scalar_value_type & result)
439 {
440 for (unsigned int i = 0; i < dim; ++i)
441 result[i] = value[i][vector_lane];
442 }
443
444 static void
446 const unsigned int,
447 vectorized_value_type &result)
448 {
449 result = value;
450 }
451
452 static void
454 const unsigned int vector_lane,
455 const scalar_value_type &result)
456 {
457 for (unsigned int i = 0; i < dim; ++i)
458 value[i][vector_lane] = result[i];
459 }
460
461 static void
463 const unsigned int,
464 const vectorized_value_type &result)
465 {
466 value = result;
467 }
468
469 static void
470 set_zero_value(value_type &value, const unsigned int vector_lane)
471 {
472 for (unsigned int i = 0; i < dim; ++i)
474 0.;
475 }
476
477 static void
479 const unsigned int vector_lane,
480 const unsigned int component,
481 const ScalarNumber &shape_value)
482 {
484 vector_lane) += shape_value;
485 }
486
487 static ScalarNumber
489 const unsigned int vector_lane,
490 const unsigned int component)
491 {
493 vector_lane);
494 }
495
496 static void
498 const unsigned int vector_lane,
499 const unsigned int component,
500 const Tensor<1, dim, ScalarNumber> &shape_gradient)
501 {
502 for (unsigned int d = 0; d < dim; ++d)
504 vector_lane) +=
505 shape_gradient[d];
506 }
507
510 const unsigned int vector_lane,
511 const unsigned int component)
512 {
514 for (unsigned int d = 0; d < dim; ++d)
515 result[d] =
517 vector_lane);
518 return result;
519 }
520 };
521
522 template <typename Number>
523 struct EvaluatorTypeTraits<1, 1, Number>
524 {
528 typename ::internal::VectorizedArrayTrait<
530 using value_type = Number;
537
538 static void
539 read_value(const ScalarNumber vector_entry,
540 const unsigned int,
541 scalar_value_type &result)
542 {
543 result = vector_entry;
544 }
545
546 static void
548 const unsigned int,
549 const vectorized_value_type &result)
550 {
551 vector_entry = result;
552 }
553
554 static void
556 const unsigned int vector_lane,
557 scalar_gradient_type & result)
558 {
559 result[0] = value[0][vector_lane];
560 }
561
562 static void
564 const unsigned int,
566 {
567 result = value;
568 }
569
570 static void
572 const unsigned int vector_lane,
573 const scalar_gradient_type &result)
574 {
575 value[0][vector_lane] = result[0];
576 }
577
578 static void
580 const unsigned int,
581 const vectorized_gradient_type &result)
582 {
583 value = result;
584 }
585
586 static void
587 set_zero_gradient(gradient_type &value, const unsigned int vector_lane)
588 {
590 }
591
592 static void
594 const unsigned int vector_lane,
595 scalar_value_type & result)
596 {
597 result = value[vector_lane];
598 }
599
600 static void
602 const unsigned int,
603 vectorized_value_type &result)
604 {
605 result = value;
606 }
607
608 static void
610 const unsigned int vector_lane,
611 const scalar_value_type &result)
612 {
613 value[vector_lane] = result;
614 }
615
616 static void
618 const unsigned int,
619 const vectorized_value_type &result)
620 {
621 value = result;
622 }
623
624 static void
625 set_zero_value(value_type &value, const unsigned int vector_lane)
626 {
628 }
629
630 static void
632 const unsigned int vector_lane,
633 const unsigned int,
634 const ScalarNumber &shape_value)
635 {
637 shape_value;
638 }
639
640 static ScalarNumber
642 const unsigned int vector_lane,
643 const unsigned int)
644 {
646 }
647
648 static void
650 const unsigned int vector_lane,
651 const unsigned int,
652 const scalar_gradient_type &shape_gradient)
653 {
655 shape_gradient[0];
656 }
657
660 const unsigned int vector_lane,
661 const unsigned int)
662 {
664 result[0] =
666 return result;
667 }
668 };
669
670 template <int dim, int spacedim>
671 bool
673 const unsigned int base_element_number);
674
675 template <int dim, int spacedim>
676 bool
678
679 template <int dim, int spacedim>
680 std::vector<Polynomials::Polynomial<double>>
682 } // namespace FEPointEvaluation
683} // namespace internal
684
685
686
717template <int n_components_,
718 int dim,
719 int spacedim = dim,
720 typename Number = double>
722{
723public:
724 static constexpr unsigned int dimension = dim;
725 static constexpr unsigned int n_components = n_components_;
726
727 using number_type = Number;
728
731 using VectorizedArrayType = typename ::internal::VectorizedArrayTrait<
733 using ETT = typename internal::FEPointEvaluation::
734 EvaluatorTypeTraits<dim, n_components, Number>;
735 using value_type = typename ETT::value_type;
736 using scalar_value_type = typename ETT::scalar_value_type;
737 using vectorized_value_type = typename ETT::vectorized_value_type;
738 using gradient_type = typename ETT::gradient_type;
740 typename ETT::interface_vectorized_gradient_type;
741
761 const FiniteElement<dim> &fe,
763 const unsigned int first_selected_component = 0);
764
783 const FiniteElement<dim> & fe,
784 const unsigned int first_selected_component = 0);
785
789 FEPointEvaluation(FEPointEvaluation &other) noexcept;
790
794 FEPointEvaluation(FEPointEvaluation &&other) noexcept;
795
800
812 void
814 const ArrayView<const Point<dim>> &unit_points);
815
820 void
821 reinit();
822
827 void
828 reinit(const unsigned int cell_index);
829
834 void
835 reinit(const unsigned int cell_index, const unsigned int face_number);
836
848 void
849 evaluate(const ArrayView<const ScalarNumber> & solution_values,
850 const EvaluationFlags::EvaluationFlags &evaluation_flags);
851
870 void
871 integrate(const ArrayView<ScalarNumber> & solution_values,
872 const EvaluationFlags::EvaluationFlags &integration_flags);
873
896 void
897 test_and_sum(const ArrayView<ScalarNumber> & solution_values,
898 const EvaluationFlags::EvaluationFlags &integration_flags);
899
907 const value_type &
908 get_value(const unsigned int point_index) const;
909
918 void
919 submit_value(const value_type &value, const unsigned int point_index);
920
930 const gradient_type &
931 get_gradient(const unsigned int point_index) const;
932
942 const gradient_type &
943 get_unit_gradient(const unsigned int point_index) const;
944
953 void
954 submit_gradient(const gradient_type &, const unsigned int point_index);
955
962 jacobian(const unsigned int point_index) const;
963
971 inverse_jacobian(const unsigned int point_index) const;
972
978 Number
979 JxW(const unsigned int point_index) const;
980
987 normal_vector(const unsigned int point_index) const;
988
994 real_point(const unsigned int point_index) const;
995
1001 unit_point(const unsigned int point_index) const;
1002
1010
1011private:
1012 static constexpr std::size_t n_lanes_user_interface =
1014 static constexpr std::size_t n_lanes_internal =
1016 static constexpr std::size_t stride =
1018
1027 void
1028 setup(const unsigned int first_selected_component);
1029
1035 void
1036 do_reinit();
1037
1042 void
1044 const ArrayView<const ScalarNumber> & solution_values,
1045 const EvaluationFlags::EvaluationFlags &evaluation_flags);
1046
1051 void
1053 const EvaluationFlags::EvaluationFlags &evaluation_flags,
1054 const unsigned int n_shapes,
1055 const unsigned int qb,
1056 vectorized_value_type & value,
1058
1062 void
1063 evaluate_fast(const ArrayView<const ScalarNumber> & solution_values,
1064 const EvaluationFlags::EvaluationFlags &evaluation_flags);
1065
1069 void
1070 evaluate_slow(const ArrayView<const ScalarNumber> & solution_values,
1071 const EvaluationFlags::EvaluationFlags &evaluation_flags);
1072
1078 void
1080 const EvaluationFlags::EvaluationFlags & integration_flags,
1081 const unsigned int n_shapes,
1082 const unsigned int qb,
1083 const vectorized_value_type & value,
1084 const interface_vectorized_gradient_type &gradient);
1085
1091 void
1093 const ArrayView<ScalarNumber> & solution_values,
1094 const EvaluationFlags::EvaluationFlags &integration_flags);
1095
1099 template <bool do_JxW>
1100 void
1101 integrate_fast(const ArrayView<ScalarNumber> & solution_values,
1102 const EvaluationFlags::EvaluationFlags &integration_flags);
1103
1107 template <bool do_JxW>
1108 void
1109 integrate_slow(const ArrayView<ScalarNumber> & solution_values,
1110 const EvaluationFlags::EvaluationFlags &integration_flags);
1111
1115 template <bool do_JxW>
1116 void
1117 do_integrate(const ArrayView<ScalarNumber> & solution_values,
1118 const EvaluationFlags::EvaluationFlags &integration_flags);
1119
1123 const unsigned int n_q_points;
1124
1128 const unsigned int n_q_points_scalar;
1129
1134
1139
1144 std::vector<Polynomials::Polynomial<double>> poly;
1145
1150
1155 std::vector<unsigned int> renumber;
1156
1164 std::vector<scalar_value_type> solution_renumbered;
1165
1173
1178
1182 std::vector<value_type> values;
1183
1187 std::vector<gradient_type> unit_gradients;
1188
1192 std::vector<gradient_type> gradients;
1193
1199
1205
1211
1217
1223
1229
1235 const Number *JxW_ptr;
1236
1242
1249
1255
1260
1265
1271 std::vector<std::array<bool, n_components>> nonzero_shape_function_component;
1272
1277
1281 std::shared_ptr<FEValues<dim, spacedim>> fe_values;
1282
1286 std::unique_ptr<NonMatching::MappingInfo<dim, spacedim, Number>>
1288
1294
1299
1304
1309
1314 boost::signals2::connection connection_is_reinitialized;
1315
1320
1326
1332};
1333
1334// ----------------------- template and inline function ----------------------
1335
1336
1337template <int n_components_, int dim, int spacedim, typename Number>
1339 const Mapping<dim> & mapping,
1340 const FiniteElement<dim> &fe,
1341 const UpdateFlags update_flags,
1342 const unsigned int first_selected_component)
1343 : n_q_points(numbers::invalid_unsigned_int)
1344 , n_q_points_scalar(numbers::invalid_unsigned_int)
1345 , mapping(&mapping)
1346 , fe(&fe)
1347 , JxW_ptr(nullptr)
1348 , use_face_path(false)
1349 , update_flags(update_flags)
1350 , mapping_info_on_the_fly(
1351 std::make_unique<NonMatching::MappingInfo<dim, spacedim, Number>>(
1352 mapping,
1353 update_flags))
1354 , mapping_info(mapping_info_on_the_fly.get())
1355 , current_cell_index(numbers::invalid_unsigned_int)
1356 , current_face_number(numbers::invalid_unsigned_int)
1357 , is_reinitialized(false)
1358{
1359 setup(first_selected_component);
1360}
1361
1362
1363
1364template <int n_components_, int dim, int spacedim, typename Number>
1367 const FiniteElement<dim> & fe,
1368 const unsigned int first_selected_component)
1369 : n_q_points(numbers::invalid_unsigned_int)
1370 , n_q_points_scalar(numbers::invalid_unsigned_int)
1371 , mapping(&mapping_info.get_mapping())
1372 , fe(&fe)
1373 , JxW_ptr(nullptr)
1374 , use_face_path(false)
1375 , update_flags(mapping_info.get_update_flags())
1376 , mapping_info(&mapping_info)
1377 , current_cell_index(numbers::invalid_unsigned_int)
1378 , current_face_number(numbers::invalid_unsigned_int)
1379 , is_reinitialized(false)
1380{
1381 setup(first_selected_component);
1382 connection_is_reinitialized = mapping_info.connect_is_reinitialized(
1383 [this]() { this->is_reinitialized = false; });
1384}
1385
1386
1387
1388template <int n_components_, int dim, int spacedim, typename Number>
1391 : n_q_points(other.n_q_points)
1392 , n_q_points_scalar(other.n_q_points_scalar)
1393 , mapping(other.mapping)
1394 , fe(other.fe)
1395 , poly(other.poly)
1396 , polynomials_are_hat_functions(other.polynomials_are_hat_functions)
1397 , renumber(other.renumber)
1398 , solution_renumbered(other.solution_renumbered)
1399 , solution_renumbered_vectorized(other.solution_renumbered_vectorized)
1400 , values(other.values)
1401 , unit_gradients(other.unit_gradients)
1402 , gradients(other.gradients)
1403 , dofs_per_component(other.dofs_per_component)
1404 , dofs_per_component_face(other.dofs_per_component_face)
1405 , use_face_path(false)
1406 , component_in_base_element(other.component_in_base_element)
1407 , nonzero_shape_function_component(other.nonzero_shape_function_component)
1408 , update_flags(other.update_flags)
1409 , fe_values(other.fe_values)
1410 , mapping_info_on_the_fly(
1411 other.mapping_info_on_the_fly ?
1413 *mapping,
1414 update_flags) :
1415 nullptr)
1416 , mapping_info(other.mapping_info)
1417 , current_cell_index(other.current_cell_index)
1418 , current_face_number(other.current_face_number)
1419 , fast_path(other.fast_path)
1420 , is_reinitialized(false)
1421 , shapes(other.shapes)
1422 , shapes_faces(other.shapes_faces)
1423{
1424 connection_is_reinitialized = mapping_info->connect_is_reinitialized(
1425 [this]() { this->is_reinitialized = false; });
1426}
1427
1428
1429
1430template <int n_components_, int dim, int spacedim, typename Number>
1433 : n_q_points(other.n_q_points)
1434 , n_q_points_scalar(other.n_q_points_scalar)
1435 , mapping(other.mapping)
1436 , fe(other.fe)
1437 , poly(other.poly)
1438 , polynomials_are_hat_functions(other.polynomials_are_hat_functions)
1439 , renumber(other.renumber)
1440 , solution_renumbered(other.solution_renumbered)
1441 , solution_renumbered_vectorized(other.solution_renumbered_vectorized)
1442 , values(other.values)
1443 , unit_gradients(other.unit_gradients)
1444 , gradients(other.gradients)
1445 , dofs_per_component(other.dofs_per_component)
1446 , dofs_per_component_face(other.dofs_per_component_face)
1447 , use_face_path(false)
1448 , component_in_base_element(other.component_in_base_element)
1449 , nonzero_shape_function_component(other.nonzero_shape_function_component)
1450 , update_flags(other.update_flags)
1451 , fe_values(other.fe_values)
1452 , mapping_info_on_the_fly(std::move(other.mapping_info_on_the_fly))
1453 , mapping_info(other.mapping_info)
1454 , current_cell_index(other.current_cell_index)
1455 , current_face_number(other.current_face_number)
1456 , fast_path(other.fast_path)
1457 , is_reinitialized(false)
1458 , shapes(other.shapes)
1459 , shapes_faces(other.shapes_faces)
1460{
1461 connection_is_reinitialized = mapping_info->connect_is_reinitialized(
1462 [this]() { this->is_reinitialized = false; });
1463}
1464
1465
1466
1467template <int n_components_, int dim, int spacedim, typename Number>
1469{
1470 connection_is_reinitialized.disconnect();
1471}
1472
1473
1474
1475template <int n_components_, int dim, int spacedim, typename Number>
1476void
1478 const unsigned int first_selected_component)
1479{
1480 AssertIndexRange(first_selected_component + n_components,
1481 fe->n_components() + 1);
1482
1483 shapes.reserve(100);
1484
1485 bool same_base_element = true;
1486 unsigned int base_element_number = 0;
1487 component_in_base_element = 0;
1488 unsigned int component = 0;
1489 for (; base_element_number < fe->n_base_elements(); ++base_element_number)
1490 if (component + fe->element_multiplicity(base_element_number) >
1491 first_selected_component)
1492 {
1493 if (first_selected_component + n_components >
1494 component + fe->element_multiplicity(base_element_number))
1495 same_base_element = false;
1496 component_in_base_element = first_selected_component - component;
1497 break;
1498 }
1499 else
1500 component += fe->element_multiplicity(base_element_number);
1501
1504 *fe, base_element_number) &&
1505 same_base_element)
1506 {
1507 shape_info.reinit(QMidpoint<1>(), *fe, base_element_number);
1508 renumber = shape_info.lexicographic_numbering;
1509 dofs_per_component = shape_info.dofs_per_component_on_cell;
1510 dofs_per_component_face = shape_info.dofs_per_component_on_face;
1512 fe->base_element(base_element_number));
1513
1514 bool is_lexicographic = true;
1515 for (unsigned int i = 0; i < renumber.size(); ++i)
1516 if (i != renumber[i])
1517 is_lexicographic = false;
1518
1519 if (is_lexicographic)
1520 renumber.clear();
1521
1522 polynomials_are_hat_functions =
1523 (poly.size() == 2 && poly[0].value(0.) == 1. &&
1524 poly[0].value(1.) == 0. && poly[1].value(0.) == 0. &&
1525 poly[1].value(1.) == 1.);
1526
1527 const unsigned int size_face = 2 * dofs_per_component_face;
1528 const unsigned int size_cell = dofs_per_component;
1529 scratch_data_scalar.resize(size_face + size_cell);
1530
1531 fast_path = true;
1532 }
1533 else
1534 {
1535 nonzero_shape_function_component.resize(fe->n_dofs_per_cell());
1536 for (unsigned int d = 0; d < n_components; ++d)
1537 {
1538 const unsigned int component = first_selected_component + d;
1539 for (unsigned int i = 0; i < fe->n_dofs_per_cell(); ++i)
1540 {
1541 const bool is_primitive =
1542 fe->is_primitive() || fe->is_primitive(i);
1543 if (is_primitive)
1544 nonzero_shape_function_component[i][d] =
1545 (component == fe->system_to_component_index(i).first);
1546 else
1547 nonzero_shape_function_component[i][d] =
1548 (fe->get_nonzero_components(i)[component] == true);
1549 }
1550 }
1551
1552 fast_path = false;
1553 }
1554}
1555
1556
1557
1558template <int n_components_, int dim, int spacedim, typename Number>
1559void
1562 const ArrayView<const Point<dim>> & unit_points)
1563{
1564 // reinit is only allowed for mapping computation on the fly
1565 AssertThrow(mapping_info_on_the_fly.get() != nullptr, ExcNotImplemented());
1566
1567 mapping_info->reinit(cell, unit_points);
1568
1569 if (!fast_path)
1570 {
1571 fe_values = std::make_shared<FEValues<dim, spacedim>>(
1572 *mapping,
1573 *fe,
1575 std::vector<Point<dim>>(unit_points.begin(), unit_points.end())),
1576 update_flags);
1577 fe_values->reinit(cell);
1578 }
1579
1580 do_reinit();
1581}
1582
1583
1584
1585template <int n_components_, int dim, int spacedim, typename Number>
1586void
1588{
1589 current_cell_index = numbers::invalid_unsigned_int;
1590 current_face_number = numbers::invalid_unsigned_int;
1591
1592 do_reinit();
1593}
1594
1595
1596
1597template <int n_components_, int dim, int spacedim, typename Number>
1598void
1600 const unsigned int cell_index)
1601{
1602 current_cell_index = cell_index;
1603 current_face_number = numbers::invalid_unsigned_int;
1604
1605 do_reinit();
1606}
1607
1608
1609
1610template <int n_components_, int dim, int spacedim, typename Number>
1611void
1613 const unsigned int cell_index,
1614 const unsigned int face_number)
1615{
1616 current_cell_index = cell_index;
1617 current_face_number = face_number;
1618
1619 do_reinit();
1620}
1621
1622
1623
1624template <int n_components_, int dim, int spacedim, typename Number>
1625inline void
1627{
1628 const_cast<unsigned int &>(n_q_points_scalar) =
1629 mapping_info->get_n_q_points_unvectorized(current_cell_index,
1630 current_face_number);
1631
1632 // round up n_points_scalar / n_lanes_user_interface
1633 const_cast<unsigned int &>(n_q_points) =
1634 (n_q_points_scalar + n_lanes_user_interface - 1) / n_lanes_user_interface;
1635
1636 if (update_flags & update_values)
1637 values.resize(n_q_points, numbers::signaling_nan<value_type>());
1638 if (update_flags & update_gradients)
1639 gradients.resize(n_q_points, numbers::signaling_nan<gradient_type>());
1640
1641 if (n_q_points == 0)
1642 {
1643 is_reinitialized = true;
1644 return;
1645 }
1646
1647 // use face path if mapping_info in face state and number of quadrature points
1648 // is large enough
1649 use_face_path = mapping_info->is_face_state() && n_q_points_scalar >= 6;
1650
1651 // set unit point pointer
1652 const unsigned int unit_point_offset =
1653 mapping_info->compute_unit_point_index_offset(current_cell_index,
1654 current_face_number);
1655
1656 if (use_face_path)
1657 unit_point_faces_ptr =
1658 mapping_info->get_unit_point_faces(unit_point_offset);
1659 else
1660 unit_point_ptr = mapping_info->get_unit_point(unit_point_offset);
1661
1662 // set data pointers
1663 const UpdateFlags update_flags_mapping =
1664 mapping_info->get_update_flags_mapping();
1665 const unsigned int data_offset =
1666 mapping_info->compute_data_index_offset(current_cell_index,
1667 current_face_number);
1668 if (update_flags_mapping & UpdateFlags::update_quadrature_points)
1669 real_point_ptr = mapping_info->get_real_point(data_offset);
1670 if (update_flags_mapping & UpdateFlags::update_jacobians)
1671 jacobian_ptr = mapping_info->get_jacobian(data_offset);
1672 if (update_flags_mapping & UpdateFlags::update_inverse_jacobians)
1673 inverse_jacobian_ptr = mapping_info->get_inverse_jacobian(data_offset);
1674 if (update_flags_mapping & UpdateFlags::update_normal_vectors)
1675 normal_ptr = mapping_info->get_normal_vector(data_offset);
1676 if (update_flags_mapping & UpdateFlags::update_JxW_values)
1677 JxW_ptr = mapping_info->get_JxW(data_offset);
1678
1679 if (fast_path && !polynomials_are_hat_functions)
1680 {
1681 // round up n_q_points_scalar / n_lanes_internal
1682 const std::size_t n_batches =
1683 (n_q_points_scalar + n_lanes_internal - 1) / n_lanes_internal;
1684 const std::size_t n_shapes = poly.size();
1685
1686 for (unsigned int qb = 0; qb < n_batches; ++qb)
1687 if (use_face_path)
1688 {
1689 if (dim > 1)
1690 {
1691 shapes_faces.resize_fast(n_batches * n_shapes);
1693 shapes_faces.data() + qb * n_shapes,
1694 poly,
1695 unit_point_faces_ptr[qb],
1696 update_flags & UpdateFlags::update_gradients ? 1 : 0);
1697 }
1698 }
1699 else
1700 {
1701 shapes.resize_fast(n_batches * n_shapes);
1703 shapes.data() + qb * n_shapes,
1704 poly,
1705 unit_point_ptr[qb],
1706 update_flags & UpdateFlags::update_gradients ? 1 : 0);
1707 }
1708 }
1709
1710 is_reinitialized = true;
1711}
1712
1713
1714
1715template <int n_components_, int dim, int spacedim, typename Number>
1716inline void
1718 const ArrayView<const ScalarNumber> & solution_values,
1719 const EvaluationFlags::EvaluationFlags &evaluation_flags)
1720{
1721 if (use_face_path)
1722 {
1723 if (solution_renumbered.size() != 2 * dofs_per_component_face)
1724 solution_renumbered.resize(2 * dofs_per_component_face);
1725 }
1726 else
1727 {
1728 if (solution_renumbered.size() != dofs_per_component)
1729 solution_renumbered.resize(dofs_per_component);
1730 }
1731 for (unsigned int comp = 0; comp < n_components; ++comp)
1732 {
1733 const std::size_t offset =
1734 (component_in_base_element + comp) * dofs_per_component;
1735
1736 if (use_face_path)
1737 {
1738 const ScalarNumber *input;
1739 if (renumber.empty())
1740 {
1741 for (unsigned int i = 0; i < dofs_per_component; ++i)
1742 scratch_data_scalar[i] = solution_values[i + offset];
1743 input = scratch_data_scalar.data();
1744 }
1745 else
1746 {
1747 const unsigned int *renumber_ptr = renumber.data() + offset;
1748 for (unsigned int i = 0; i < dofs_per_component; ++i)
1749 scratch_data_scalar[i] = solution_values[renumber_ptr[i]];
1750 input = scratch_data_scalar.data();
1751 }
1752
1753 ScalarNumber *output =
1754 scratch_data_scalar.begin() + dofs_per_component;
1755
1757 template interpolate<true, false>(1,
1758 evaluation_flags,
1759 shape_info,
1760 input,
1761 output,
1762 current_face_number);
1763
1764 for (unsigned int i = 0; i < 2 * dofs_per_component_face; ++i)
1765 ETT::read_value(output[i], comp, solution_renumbered[i]);
1766 }
1767 else
1768 {
1769 if (renumber.empty())
1770 {
1771 for (unsigned int i = 0; i < dofs_per_component; ++i)
1772 ETT::read_value(solution_values[i + offset],
1773 comp,
1774 solution_renumbered[i]);
1775 }
1776 else
1777 {
1778 const unsigned int *renumber_ptr = renumber.data() + offset;
1779 for (unsigned int i = 0; i < dofs_per_component; ++i)
1780 ETT::read_value(solution_values[renumber_ptr[i]],
1781 comp,
1782 solution_renumbered[i]);
1783 }
1784 }
1785 }
1786
1787 // unit gradients are currently only implemented with the fast tensor
1788 // path
1789 unit_gradients.resize(n_q_points, numbers::signaling_nan<gradient_type>());
1790}
1791
1792
1793
1794template <int n_components_, int dim, int spacedim, typename Number>
1795inline void
1797 const EvaluationFlags::EvaluationFlags &evaluation_flags,
1798 const unsigned int n_shapes,
1799 const unsigned int qb,
1800 vectorized_value_type & value,
1802{
1803 if (use_face_path)
1804 {
1805 if (evaluation_flags & EvaluationFlags::gradients)
1806 {
1807 const std::array<vectorized_value_type, dim + 1> interpolated_value =
1808 polynomials_are_hat_functions ?
1810 dim - 1,
1813 2>(n_shapes,
1814 solution_renumbered.data(),
1815 unit_point_faces_ptr[qb]) :
1817 dim - 1,
1820 2,
1821 false>(shapes_faces.data() + qb * n_shapes,
1822 n_shapes,
1823 solution_renumbered.data());
1824
1825 value = interpolated_value[dim - 1];
1826 // reorder derivative from tangential/normal derivatives into tensor
1827 // in physical coordinates
1828 if (current_face_number / 2 == 0)
1829 {
1830 gradient[0] = interpolated_value[dim];
1831 if (dim > 1)
1832 gradient[1] = interpolated_value[0];
1833 if (dim > 2)
1834 gradient[2] = interpolated_value[1];
1835 }
1836 else if (current_face_number / 2 == 1)
1837 {
1838 if (dim > 1)
1839 gradient[1] = interpolated_value[dim];
1840 if (dim == 3)
1841 {
1842 gradient[0] = interpolated_value[1];
1843 gradient[2] = interpolated_value[0];
1844 }
1845 else if (dim == 2)
1846 gradient[0] = interpolated_value[0];
1847 else
1848 Assert(false, ExcInternalError());
1849 }
1850 else if (current_face_number / 2 == 2)
1851 {
1852 if (dim > 2)
1853 {
1854 gradient[0] = interpolated_value[0];
1855 gradient[1] = interpolated_value[1];
1856 gradient[2] = interpolated_value[dim];
1857 }
1858 else
1859 Assert(false, ExcInternalError());
1860 }
1861 else
1862 Assert(false, ExcInternalError());
1863 }
1864 else
1865 {
1866 value = polynomials_are_hat_functions ?
1868 dim - 1,
1870 VectorizedArrayType>(n_shapes,
1871 solution_renumbered.data(),
1872 unit_point_faces_ptr[qb]) :
1874 dim - 1,
1877 false>(shapes_faces.data() + qb * n_shapes,
1878 n_shapes,
1879 solution_renumbered.data());
1880 }
1881 }
1882 else
1883 {
1884 if (evaluation_flags & EvaluationFlags::gradients)
1885 {
1886 const std::array<vectorized_value_type, dim + 1> result =
1887 polynomials_are_hat_functions ?
1889 n_shapes, solution_renumbered.data(), unit_point_ptr[qb]) :
1891 dim,
1894 1,
1895 false>(shapes.data() + qb * n_shapes,
1896 n_shapes,
1897 solution_renumbered.data());
1898 gradient[0] = result[0];
1899 if (dim > 1)
1900 gradient[1] = result[1];
1901 if (dim > 2)
1902 gradient[2] = result[2];
1903 value = result[dim];
1904 }
1905 else
1906 {
1907 value =
1908 polynomials_are_hat_functions ?
1910 n_shapes, solution_renumbered.data(), unit_point_ptr[qb]) :
1912 dim,
1915 false>(shapes.data() + qb * n_shapes,
1916 n_shapes,
1917 solution_renumbered.data());
1918 }
1919 }
1920}
1921
1922
1923
1924template <int n_components_, int dim, int spacedim, typename Number>
1925inline void
1927 const ArrayView<const ScalarNumber> & solution_values,
1928 const EvaluationFlags::EvaluationFlags &evaluation_flags)
1929{
1930 prepare_evaluate_fast(solution_values, evaluation_flags);
1931
1932 // loop over quadrature batches qb / points q
1933 const unsigned int n_shapes = poly.size();
1936 for (unsigned int qb = 0, q = 0; q < n_q_points_scalar;
1937 ++qb, q += n_lanes_internal)
1938 {
1939 compute_evaluate_fast(evaluation_flags, n_shapes, qb, value, gradient);
1940
1941 if (evaluation_flags & EvaluationFlags::values)
1942 {
1943 for (unsigned int v = 0;
1944 v < stride && (stride == 1 || q + v < n_q_points_scalar);
1945 ++v)
1946 ETT::set_value(value, v, values[qb * stride + v]);
1947 }
1948 if (evaluation_flags & EvaluationFlags::gradients)
1949 {
1950 Assert(update_flags & update_gradients ||
1951 update_flags & update_inverse_jacobians,
1953
1954 for (unsigned int v = 0;
1955 v < stride && (stride == 1 || q + v < n_q_points_scalar);
1956 ++v)
1957 {
1958 const unsigned int offset = qb * stride + v;
1959 ETT::set_gradient(gradient, v, unit_gradients[offset]);
1960 gradients[offset] =
1961 apply_transformation(inverse_jacobian_ptr[offset].transpose(),
1962 unit_gradients[offset]);
1963 }
1964 }
1965 }
1966}
1967
1968
1969
1970template <int n_components_, int dim, int spacedim, typename Number>
1971inline void
1973 const ArrayView<const ScalarNumber> & solution_values,
1974 const EvaluationFlags::EvaluationFlags &evaluation_flags)
1975{
1976 // slow path with FEValues
1977 Assert(fe_values.get() != nullptr,
1978 ExcMessage(
1979 "Not initialized. Please call FEPointEvaluation::reinit()!"));
1980
1981 const std::size_t n_points = fe_values->get_quadrature().size();
1982
1983 if (evaluation_flags & EvaluationFlags::values)
1984 {
1985 values.resize(n_q_points);
1986 std::fill(values.begin(), values.end(), value_type());
1987 for (unsigned int i = 0; i < fe->n_dofs_per_cell(); ++i)
1988 {
1989 const ScalarNumber value = solution_values[i];
1990 for (unsigned int d = 0; d < n_components; ++d)
1991 if (nonzero_shape_function_component[i][d] &&
1992 (fe->is_primitive(i) || fe->is_primitive()))
1993 for (unsigned int qb = 0, q = 0; q < n_points;
1994 ++qb, q += n_lanes_user_interface)
1995 for (unsigned int v = 0;
1996 v < n_lanes_user_interface && q + v < n_points;
1997 ++v)
1998 ETT::access(values[qb],
1999 v,
2000 d,
2001 fe_values->shape_value(i, q + v) * value);
2002 else if (nonzero_shape_function_component[i][d])
2003 for (unsigned int qb = 0, q = 0; q < n_points;
2004 ++qb, q += n_lanes_user_interface)
2005 for (unsigned int v = 0;
2006 v < n_lanes_user_interface && q + v < n_points;
2007 ++v)
2008 ETT::access(values[qb],
2009 v,
2010 d,
2011 fe_values->shape_value_component(i, q + v, d) *
2012 value);
2013 }
2014 }
2015
2016 if (evaluation_flags & EvaluationFlags::gradients)
2017 {
2018 gradients.resize(n_q_points);
2019 std::fill(gradients.begin(), gradients.end(), gradient_type());
2020 for (unsigned int i = 0; i < fe->n_dofs_per_cell(); ++i)
2021 {
2022 const ScalarNumber value = solution_values[i];
2023 for (unsigned int d = 0; d < n_components; ++d)
2024 if (nonzero_shape_function_component[i][d] &&
2025 (fe->is_primitive(i) || fe->is_primitive()))
2026 for (unsigned int qb = 0, q = 0; q < n_points;
2027 ++qb, q += n_lanes_user_interface)
2028 for (unsigned int v = 0;
2029 v < n_lanes_user_interface && q + v < n_points;
2030 ++v)
2031 ETT::access(gradients[qb],
2032 v,
2033 d,
2034 fe_values->shape_grad(i, q + v) * value);
2035 else if (nonzero_shape_function_component[i][d])
2036 for (unsigned int qb = 0, q = 0; q < n_points;
2037 ++qb, q += n_lanes_user_interface)
2038 for (unsigned int v = 0;
2039 v < n_lanes_user_interface && q + v < n_points;
2040 ++v)
2041 ETT::access(gradients[qb],
2042 v,
2043 d,
2044 fe_values->shape_grad_component(i, q + v, d) *
2045 value);
2046 }
2047 }
2048}
2049
2050
2051
2052template <int n_components_, int dim, int spacedim, typename Number>
2053void
2055 const ArrayView<const ScalarNumber> & solution_values,
2056 const EvaluationFlags::EvaluationFlags &evaluation_flags)
2057{
2058 if (!is_reinitialized)
2059 reinit();
2060
2061 if (n_q_points == 0)
2062 return;
2063
2064 Assert(!(evaluation_flags & EvaluationFlags::hessians), ExcNotImplemented());
2065
2066 if (!((evaluation_flags & EvaluationFlags::values) ||
2067 (evaluation_flags & EvaluationFlags::gradients))) // no evaluation flags
2068 return;
2069
2070 AssertDimension(solution_values.size(), fe->dofs_per_cell);
2071 if (fast_path)
2072 evaluate_fast(solution_values, evaluation_flags);
2073 else
2074 evaluate_slow(solution_values, evaluation_flags);
2075}
2076
2077
2078
2079template <int n_components_, int dim, int spacedim, typename Number>
2080inline void
2082 const EvaluationFlags::EvaluationFlags & integration_flags,
2083 const unsigned int n_shapes,
2084 const unsigned int qb,
2085 const vectorized_value_type & value,
2086 const interface_vectorized_gradient_type &gradient)
2087{
2088 if (use_face_path)
2089 {
2090 if (integration_flags & EvaluationFlags::gradients)
2091 {
2092 std::array<vectorized_value_type, 2> value_face = {};
2093 Tensor<1, dim - 1, vectorized_value_type> gradient_in_face;
2094
2095 value_face[0] = value;
2096 // fill derivative in physical coordinates into tangential/normal
2097 // derivatives
2098 if (current_face_number / 2 == 0)
2099 {
2100 value_face[1] = gradient[0];
2101 if (dim > 1)
2102 gradient_in_face[0] = gradient[1];
2103 if (dim > 2)
2104 gradient_in_face[1] = gradient[2];
2105 }
2106 else if (current_face_number / 2 == 1)
2107 {
2108 if (dim > 1)
2109 value_face[1] = gradient[1];
2110 if (dim == 3)
2111 {
2112 gradient_in_face[0] = gradient[2];
2113 gradient_in_face[1] = gradient[0];
2114 }
2115 else if (dim == 2)
2116 gradient_in_face[0] = gradient[0];
2117 else
2118 Assert(false, ExcInternalError());
2119 }
2120 else if (current_face_number / 2 == 2)
2121 {
2122 if (dim > 2)
2123 {
2124 value_face[1] = gradient[2];
2125 gradient_in_face[0] = gradient[0];
2126 gradient_in_face[1] = gradient[1];
2127 }
2128 else
2129 Assert(false, ExcInternalError());
2130 }
2131 else
2132 Assert(false, ExcInternalError());
2133
2135 dim - 1,
2138 2>(shapes_faces.data() + qb * n_shapes,
2139 n_shapes,
2140 value_face.data(),
2141 gradient_in_face,
2142 solution_renumbered_vectorized.data(),
2143 unit_point_faces_ptr[qb],
2144 polynomials_are_hat_functions,
2145 qb != 0);
2146 }
2147 else
2151 shapes_faces.data() + qb * n_shapes,
2152 n_shapes,
2153 value,
2154 solution_renumbered_vectorized.data(),
2155 unit_point_faces_ptr[qb],
2156 polynomials_are_hat_functions,
2157 qb != 0);
2158 }
2159 else
2160 {
2161 if (integration_flags & EvaluationFlags::gradients)
2163 dim,
2165 vectorized_value_type>(shapes.data() + qb * n_shapes,
2166 n_shapes,
2167 &value,
2168 gradient,
2169 solution_renumbered_vectorized.data(),
2170 unit_point_ptr[qb],
2171 polynomials_are_hat_functions,
2172 qb != 0);
2173 else
2177 shapes.data() + qb * n_shapes,
2178 n_shapes,
2179 value,
2180 solution_renumbered_vectorized.data(),
2181 unit_point_ptr[qb],
2182 polynomials_are_hat_functions,
2183 qb != 0);
2184 }
2185}
2186
2187
2188
2189template <int n_components_, int dim, int spacedim, typename Number>
2190inline void
2192 const ArrayView<ScalarNumber> & solution_values,
2193 const EvaluationFlags::EvaluationFlags &integration_flags)
2194{
2195 std::fill(solution_values.begin(), solution_values.end(), ScalarNumber());
2196 for (unsigned int comp = 0; comp < n_components; ++comp)
2197 {
2198 const std::size_t offset =
2199 (component_in_base_element + comp) * dofs_per_component;
2200
2201 if (use_face_path)
2202 {
2203 const unsigned int size_input = 2 * dofs_per_component_face;
2204 ScalarNumber * input = scratch_data_scalar.begin();
2205 ScalarNumber * output = input + size_input;
2206
2207 for (unsigned int i = 0; i < 2 * dofs_per_component_face; ++i)
2208 {
2209 VectorizedArrayType vectorized_input;
2210 ETT::write_value(vectorized_input,
2211 comp,
2212 solution_renumbered_vectorized[i]);
2213 input[i] = vectorized_input.sum();
2214 }
2215
2217 template interpolate<false, false>(1,
2218 integration_flags,
2219 shape_info,
2220 input,
2221 output,
2222 current_face_number);
2223
2224 if (renumber.empty())
2225 for (unsigned int i = 0; i < dofs_per_component; ++i)
2226 solution_values[i + offset] = output[i];
2227 else
2228 for (unsigned int i = 0; i < dofs_per_component; ++i)
2229 solution_values[renumber[i + offset]] = output[i];
2230 }
2231 else
2232 {
2233 if (renumber.empty())
2234 for (unsigned int i = 0; i < dofs_per_component; ++i)
2235 {
2236 VectorizedArrayType result;
2237 ETT::write_value(result,
2238 comp,
2239 solution_renumbered_vectorized[i]);
2240 solution_values[i + offset] = result.sum();
2241 }
2242 else
2243 for (unsigned int i = 0; i < dofs_per_component; ++i)
2244 {
2245 VectorizedArrayType result;
2246 ETT::write_value(result,
2247 comp,
2248 solution_renumbered_vectorized[i]);
2249 solution_values[renumber[i + offset]] = result.sum();
2250 }
2251 }
2252 }
2253}
2254
2255
2256
2257template <int n_components_, int dim, int spacedim, typename Number>
2258template <bool do_JxW>
2259inline void
2261 const ArrayView<ScalarNumber> & solution_values,
2262 const EvaluationFlags::EvaluationFlags &integration_flags)
2263{
2264 // fast path with tensor product integration
2265 if (use_face_path)
2266 {
2267 if (solution_renumbered_vectorized.size() != 2 * dofs_per_component_face)
2268 solution_renumbered_vectorized.resize(2 * dofs_per_component_face);
2269 }
2270 else
2271 {
2272 if (solution_renumbered_vectorized.size() != dofs_per_component)
2273 solution_renumbered_vectorized.resize(dofs_per_component);
2274 }
2275
2276 // loop over quadrature batches qb / points q
2277 const unsigned int n_shapes = poly.size();
2278 for (unsigned int qb = 0, q = 0; q < n_q_points_scalar;
2279 ++qb, q += n_lanes_internal)
2280 {
2281 const bool incomplete_last_batch =
2282 q + n_lanes_user_interface > n_q_points_scalar;
2283
2284 vectorized_value_type value = {};
2286
2287 if (integration_flags & EvaluationFlags::values)
2288 {
2289 // zero out lanes of incomplete last quadrature point batch
2290 if (incomplete_last_batch)
2291 {
2292 const unsigned int n_filled_lanes_last_batch =
2293 n_q_points_scalar % n_lanes_internal;
2294 for (unsigned int v = n_filled_lanes_last_batch;
2295 v < n_lanes_internal;
2296 ++v)
2297 ETT::set_zero_value(values[qb], v);
2298 }
2299
2300 for (unsigned int v = 0;
2301 v < stride && (stride == 1 || q + v < n_q_points_scalar);
2302 ++v)
2303 {
2304 const unsigned int offset = qb * stride + v;
2305 if (do_JxW)
2306 values[offset] *= JxW_ptr[offset];
2307 ETT::get_value(value, v, values[offset]);
2308 }
2309 }
2310 if (integration_flags & EvaluationFlags::gradients)
2311 {
2312 // zero out lanes of incomplete last quadrature point batch
2313 if (incomplete_last_batch)
2314 {
2315 const unsigned int n_filled_lanes_last_batch =
2316 n_q_points_scalar % n_lanes_internal;
2317 for (unsigned int v = n_filled_lanes_last_batch;
2318 v < n_lanes_internal;
2319 ++v)
2320 ETT::set_zero_gradient(gradients[qb], v);
2321 }
2322
2323 for (unsigned int v = 0;
2324 v < stride && (stride == 1 || q + v < n_q_points_scalar);
2325 ++v)
2326 {
2327 const unsigned int offset = qb * stride + v;
2328 if (do_JxW)
2329 gradients[offset] *= JxW_ptr[offset];
2330 ETT::get_gradient(
2331 gradient,
2332 v,
2333 apply_transformation(inverse_jacobian_ptr[offset],
2334 gradients[offset]));
2335 }
2336 }
2337
2338 compute_integrate_fast(integration_flags, n_shapes, qb, value, gradient);
2339 }
2340
2341 // add between the lanes and write into the result
2342 finish_integrate_fast(solution_values, integration_flags);
2343}
2344
2345
2346
2347template <int n_components_, int dim, int spacedim, typename Number>
2348template <bool do_JxW>
2349inline void
2351 const ArrayView<ScalarNumber> & solution_values,
2352 const EvaluationFlags::EvaluationFlags &integration_flags)
2353{
2354 // slow path with FEValues
2355 Assert(fe_values.get() != nullptr,
2356 ExcMessage(
2357 "Not initialized. Please call FEPointEvaluation::reinit()!"));
2358 std::fill(solution_values.begin(), solution_values.end(), 0.0);
2359
2360 const std::size_t n_points = fe_values->get_quadrature().size();
2361
2362 if (integration_flags & EvaluationFlags::values)
2363 {
2364 AssertIndexRange(n_q_points, values.size() + 1);
2365 for (unsigned int i = 0; i < fe->n_dofs_per_cell(); ++i)
2366 {
2367 for (unsigned int d = 0; d < n_components; ++d)
2368 if (nonzero_shape_function_component[i][d] &&
2369 (fe->is_primitive(i) || fe->is_primitive()))
2370 for (unsigned int qb = 0, q = 0; q < n_points;
2371 ++qb, q += n_lanes_user_interface)
2372 for (unsigned int v = 0;
2373 v < n_lanes_user_interface && q + v < n_points;
2374 ++v)
2375 solution_values[i] += fe_values->shape_value(i, q + v) *
2376 ETT::access(values[qb], v, d) *
2377 (do_JxW ? fe_values->JxW(q + v) : 1.);
2378 else if (nonzero_shape_function_component[i][d])
2379 for (unsigned int qb = 0, q = 0; q < n_points;
2380 ++qb, q += n_lanes_user_interface)
2381 for (unsigned int v = 0;
2382 v < n_lanes_user_interface && q + v < n_points;
2383 ++v)
2384 solution_values[i] +=
2385 fe_values->shape_value_component(i, q + v, d) *
2386 ETT::access(values[qb], v, d) *
2387 (do_JxW ? fe_values->JxW(q + v) : 1.);
2388 }
2389 }
2390
2391 if (integration_flags & EvaluationFlags::gradients)
2392 {
2393 AssertIndexRange(n_q_points, gradients.size() + 1);
2394 for (unsigned int i = 0; i < fe->n_dofs_per_cell(); ++i)
2395 {
2396 for (unsigned int d = 0; d < n_components; ++d)
2397 if (nonzero_shape_function_component[i][d] &&
2398 (fe->is_primitive(i) || fe->is_primitive()))
2399 for (unsigned int qb = 0, q = 0; q < n_points;
2400 ++qb, q += n_lanes_user_interface)
2401 for (unsigned int v = 0;
2402 v < n_lanes_user_interface && q + v < n_points;
2403 ++v)
2404 solution_values[i] += fe_values->shape_grad(i, q + v) *
2405 ETT::access(gradients[qb], v, d) *
2406 (do_JxW ? fe_values->JxW(q + v) : 1.);
2407 else if (nonzero_shape_function_component[i][d])
2408 for (unsigned int qb = 0, q = 0; q < n_points;
2409 ++qb, q += n_lanes_user_interface)
2410 for (unsigned int v = 0;
2411 v < n_lanes_user_interface && q + v < n_points;
2412 ++v)
2413 solution_values[i] +=
2414 fe_values->shape_grad_component(i, q + v, d) *
2415 ETT::access(gradients[qb], v, d) *
2416 (do_JxW ? fe_values->JxW(q + v) : 1.);
2417 }
2418 }
2419}
2420
2421
2422
2423template <int n_components_, int dim, int spacedim, typename Number>
2424template <bool do_JxW>
2425void
2427 const ArrayView<ScalarNumber> & solution_values,
2428 const EvaluationFlags::EvaluationFlags &integration_flags)
2429{
2430 if (!is_reinitialized)
2431 reinit();
2432
2433 if (n_q_points == 0) // no evaluation points provided
2434 {
2435 std::fill(solution_values.begin(), solution_values.end(), 0.0);
2436 return;
2437 }
2438
2439 Assert(!(integration_flags & EvaluationFlags::hessians), ExcNotImplemented());
2440
2441 if (!((integration_flags & EvaluationFlags::values) ||
2442 (integration_flags &
2443 EvaluationFlags::gradients))) // no integration flags
2444 {
2445 std::fill(solution_values.begin(), solution_values.end(), 0.0);
2446 return;
2447 }
2448
2449 Assert(
2450 !do_JxW || JxW_ptr != nullptr,
2451 ExcMessage(
2452 "JxW pointer is not set! If you do not want to integrate() use test_and_sum()"));
2453
2454 AssertDimension(solution_values.size(), fe->dofs_per_cell);
2455 if (fast_path)
2456 integrate_fast<do_JxW>(solution_values, integration_flags);
2457 else
2458 integrate_slow<do_JxW>(solution_values, integration_flags);
2459}
2460
2461
2462
2463template <int n_components_, int dim, int spacedim, typename Number>
2464void
2466 const ArrayView<ScalarNumber> & solution_values,
2467 const EvaluationFlags::EvaluationFlags &integration_flags)
2468{
2469 do_integrate<true>(solution_values, integration_flags);
2470}
2471
2472
2473
2474template <int n_components_, int dim, int spacedim, typename Number>
2475void
2477 const ArrayView<ScalarNumber> & solution_values,
2478 const EvaluationFlags::EvaluationFlags &integration_flags)
2479{
2480 do_integrate<false>(solution_values, integration_flags);
2481}
2482
2483
2484
2485template <int n_components_, int dim, int spacedim, typename Number>
2487 value_type &
2489 const unsigned int point_index) const
2490{
2491 AssertIndexRange(point_index, values.size());
2492 return values[point_index];
2493}
2494
2495
2496
2497template <int n_components_, int dim, int spacedim, typename Number>
2499 gradient_type &
2501 const unsigned int point_index) const
2502{
2503 AssertIndexRange(point_index, gradients.size());
2504 return gradients[point_index];
2505}
2506
2507
2508
2509template <int n_components_, int dim, int spacedim, typename Number>
2511 gradient_type &
2513 const unsigned int point_index) const
2514{
2515 Assert(fast_path,
2516 ExcMessage("Unit gradients are currently only implemented for tensor "
2517 "product finite elements combined with MappingQ "
2518 "mappings"));
2519 AssertIndexRange(point_index, unit_gradients.size());
2520 return unit_gradients[point_index];
2521}
2522
2523
2524
2525template <int n_components_, int dim, int spacedim, typename Number>
2526inline void
2528 const value_type & value,
2529 const unsigned int point_index)
2530{
2531 AssertIndexRange(point_index, n_q_points);
2532 values[point_index] = value;
2533}
2534
2535
2536
2537template <int n_components_, int dim, int spacedim, typename Number>
2538inline void
2540 const gradient_type &gradient,
2541 const unsigned int point_index)
2542{
2543 AssertIndexRange(point_index, n_q_points);
2544 gradients[point_index] = gradient;
2545}
2546
2547
2548
2549template <int n_components_, int dim, int spacedim, typename Number>
2552 const unsigned int point_index) const
2553{
2554 AssertIndexRange(point_index, n_q_points);
2555 Assert(jacobian_ptr != nullptr,
2557 ExcFEPointEvaluationAccessToUninitializedMappingField(
2558 "update_jacobians"));
2559 return jacobian_ptr[point_index];
2560}
2561
2562
2563
2564template <int n_components_, int dim, int spacedim, typename Number>
2567 const unsigned int point_index) const
2568{
2569 AssertIndexRange(point_index, n_q_points);
2570 Assert(inverse_jacobian_ptr != nullptr,
2572 ExcFEPointEvaluationAccessToUninitializedMappingField(
2573 "update_inverse_jacobians"));
2574 return inverse_jacobian_ptr[point_index];
2575}
2576
2577
2578
2579template <int n_components_, int dim, int spacedim, typename Number>
2580inline Number
2582 const unsigned int point_index) const
2583{
2584 AssertIndexRange(point_index, n_q_points);
2585 Assert(JxW_ptr != nullptr,
2587 ExcFEPointEvaluationAccessToUninitializedMappingField(
2588 "update_JxW_values"));
2589 return JxW_ptr[point_index];
2590}
2591
2592
2593
2594template <int n_components_, int dim, int spacedim, typename Number>
2597 const unsigned int point_index) const
2598{
2599 AssertIndexRange(point_index, n_q_points);
2600 Assert(normal_ptr != nullptr,
2602 ExcFEPointEvaluationAccessToUninitializedMappingField(
2603 "update_normal_vectors"));
2604 return normal_ptr[point_index];
2605}
2606
2607
2608
2609template <int n_components_, int dim, int spacedim, typename Number>
2612 const unsigned int point_index) const
2613{
2614 AssertIndexRange(point_index, n_q_points);
2615 Assert(real_point_ptr != nullptr,
2617 ExcFEPointEvaluationAccessToUninitializedMappingField(
2618 "update_quadrature_points"));
2619 return real_point_ptr[point_index];
2620}
2621
2622
2623
2624template <int n_components_, int dim, int spacedim, typename Number>
2625inline Point<dim, Number>
2627 const unsigned int point_index) const
2628{
2629 AssertIndexRange(point_index, n_q_points);
2630 Assert(unit_point_ptr != nullptr, ExcMessage("unit_point_ptr is not set!"));
2631 Point<dim, Number> unit_point;
2632 for (unsigned int d = 0; d < dim; ++d)
2634 unit_point_ptr[point_index / stride][d], point_index % stride);
2635 return unit_point;
2636}
2637
2638
2639
2640template <int n_components_, int dim, int spacedim, typename Number>
2644{
2645 return {0U, n_q_points};
2646}
2647
2649
2650#endif
iterator begin() const
Definition array_view.h:594
iterator end() const
Definition array_view.h:603
value_type * data() const noexcept
Definition array_view.h:553
std::size_t size() const
Definition array_view.h:576
static constexpr std::size_t stride
SmartPointer< const FiniteElement< dim > > fe
void integrate(const ArrayView< ScalarNumber > &solution_values, const EvaluationFlags::EvaluationFlags &integration_flags)
AlignedVector< vectorized_value_type > solution_renumbered_vectorized
unsigned int current_cell_index
void submit_gradient(const gradient_type &, const unsigned int point_index)
AlignedVector<::ndarray< VectorizedArrayType, 2, dim - 1 > > shapes_faces
std::vector< gradient_type > gradients
typename ETT::gradient_type gradient_type
std::vector< std::array< bool, n_components > > nonzero_shape_function_component
std::vector< gradient_type > unit_gradients
unsigned int current_face_number
static constexpr unsigned int dimension
const Point< dim - 1, VectorizedArrayType > * unit_point_faces_ptr
typename ETT::value_type value_type
std::unique_ptr< NonMatching::MappingInfo< dim, spacedim, Number > > mapping_info_on_the_fly
void test_and_sum(const ArrayView< ScalarNumber > &solution_values, const EvaluationFlags::EvaluationFlags &integration_flags)
typename ETT::scalar_value_type scalar_value_type
const Point< dim, VectorizedArrayType > * unit_point_ptr
std::vector< Polynomials::Polynomial< double > > poly
std::vector< value_type > values
void integrate_slow(const ArrayView< ScalarNumber > &solution_values, const EvaluationFlags::EvaluationFlags &integration_flags)
AlignedVector<::ndarray< VectorizedArrayType, 2, dim > > shapes
const DerivativeForm< 1, spacedim, dim, Number > * inverse_jacobian_ptr
const value_type & get_value(const unsigned int point_index) const
typename internal::VectorizedArrayTrait< Number >::value_type ScalarNumber
typename ETT::vectorized_value_type vectorized_value_type
typename ::internal::VectorizedArrayTrait< Number >::vectorized_value_type VectorizedArrayType
unsigned int dofs_per_component
std_cxx20::ranges::iota_view< unsigned int, unsigned int > quadrature_point_indices() const
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_gradient_type &gradient)
DerivativeForm< 1, dim, spacedim, Number > jacobian(const unsigned int point_index) const
unsigned int dofs_per_component_face
void finish_integrate_fast(const ArrayView< ScalarNumber > &solution_values, const EvaluationFlags::EvaluationFlags &integration_flags)
const DerivativeForm< 1, dim, spacedim, Number > * jacobian_ptr
void evaluate_fast(const ArrayView< const ScalarNumber > &solution_values, const EvaluationFlags::EvaluationFlags &evaluation_flags)
const Point< spacedim, Number > * real_point_ptr
DerivativeForm< 1, spacedim, dim, Number > inverse_jacobian(const unsigned int point_index) const
Point< dim, Number > unit_point(const unsigned int point_index) const
const UpdateFlags update_flags
void prepare_evaluate_fast(const ArrayView< const ScalarNumber > &solution_values, const EvaluationFlags::EvaluationFlags &evaluation_flags)
std::vector< unsigned int > renumber
AlignedVector< ScalarNumber > scratch_data_scalar
void evaluate(const ArrayView< const ScalarNumber > &solution_values, const EvaluationFlags::EvaluationFlags &evaluation_flags)
Number JxW(const unsigned int point_index) const
void setup(const unsigned int first_selected_component)
void submit_value(const value_type &value, const unsigned int point_index)
typename ETT::interface_vectorized_gradient_type interface_vectorized_gradient_type
static constexpr std::size_t n_lanes_internal
void evaluate_slow(const ArrayView< const ScalarNumber > &solution_values, const EvaluationFlags::EvaluationFlags &evaluation_flags)
const unsigned int n_q_points
static constexpr unsigned int n_components
internal::MatrixFreeFunctions::ShapeInfo< ScalarNumber > shape_info
void do_integrate(const ArrayView< ScalarNumber > &solution_values, const EvaluationFlags::EvaluationFlags &integration_flags)
const unsigned int n_q_points_scalar
unsigned int component_in_base_element
std::vector< scalar_value_type > solution_renumbered
typename internal::FEPointEvaluation::EvaluatorTypeTraits< dim, n_components, Number > ETT
std::shared_ptr< FEValues< dim, spacedim > > fe_values
static constexpr std::size_t n_lanes_user_interface
const Tensor< 1, spacedim, Number > * normal_ptr
FEPointEvaluation(const Mapping< dim > &mapping, const FiniteElement< dim > &fe, const UpdateFlags update_flags, const unsigned int first_selected_component=0)
boost::signals2::connection connection_is_reinitialized
void compute_evaluate_fast(const EvaluationFlags::EvaluationFlags &evaluation_flags, const unsigned int n_shapes, const unsigned int qb, vectorized_value_type &value, interface_vectorized_gradient_type &gradient)
void integrate_fast(const ArrayView< ScalarNumber > &solution_values, const EvaluationFlags::EvaluationFlags &integration_flags)
Point< spacedim, Number > real_point(const unsigned int point_index) const
const gradient_type & get_unit_gradient(const unsigned int point_index) const
SmartPointer< const Mapping< dim, spacedim > > mapping
SmartPointer< NonMatching::MappingInfo< dim, spacedim, Number > > mapping_info
Tensor< 1, spacedim, Number > normal_vector(const unsigned int point_index) const
const gradient_type & get_gradient(const unsigned int point_index) const
Abstract base class for mapping classes.
Definition mapping.h:317
Definition point.h:112
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:472
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:473
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)
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 & ExcInternalError()
static ::ExceptionBase & ExcNotInitialized()
#define DeclException1(Exception1, type1, outsequence)
Definition exceptions.h:510
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
UpdateFlags
@ update_values
Shape function values.
@ update_normal_vectors
Normal vectors.
@ update_JxW_values
Transformed quadrature weights.
@ update_jacobians
Volume element.
@ update_inverse_jacobians
Volume element.
@ update_gradients
Shape function gradients.
@ update_quadrature_points
Transformed quadrature points.
EvaluationFlags
The EvaluationFlags enum.
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_linear(const unsigned int n_shapes, const Number *values, const Point< dim, Number2 > &p, const std::vector< unsigned int > &renumber={})
void compute_values_of_array(::ndarray< Number, 2, dim > *shapes, const std::vector< Polynomials::Polynomial< double > > &poly, const Point< dim, Number > &p, const unsigned int derivative=1)
void integrate_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 is_linear, const bool do_add)
ProductTypeNoPoint< Number, Number2 >::type evaluate_tensor_product_value_linear(const unsigned int n_shapes, const Number *values, const Point< dim, Number2 > &p, const std::vector< unsigned int > &renumber={})
ProductTypeNoPoint< Number, Number2 >::type evaluate_tensor_product_value_shapes(const ::ndarray< Number2, 2, dim > *shapes, const int n_shapes, const Number *values, const std::vector< unsigned int > &renumber={})
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 is_linear, const bool do_add)
static const unsigned int invalid_unsigned_int
Definition types.h:213
boost::integer_range< IncrementableType > iota_view
Definition iota_view.h:46
STL namespace.
typename internal::ndarray::HelperArray< T, Ns... >::type ndarray
Definition ndarray.h:108
typename ::internal::VectorizedArrayTrait< Number >::vectorized_value_type VectorizedArrayType
static void access(gradient_type &value, const unsigned int vector_lane, const unsigned int, const scalar_gradient_type &shape_gradient)
static void get_value(vectorized_value_type &value, const unsigned int, const vectorized_value_type &result)
static scalar_gradient_type access(const gradient_type &value, const unsigned int vector_lane, const unsigned int)
static void get_gradient(vectorized_gradient_type &value, const unsigned int, const vectorized_gradient_type &result)
static void set_gradient(const vectorized_gradient_type &value, const unsigned int vector_lane, scalar_gradient_type &result)
static void set_value(const vectorized_value_type &value, const unsigned int vector_lane, scalar_value_type &result)
typename internal::VectorizedArrayTrait< Number >::value_type ScalarNumber
static void set_value(const vectorized_value_type &value, const unsigned int, vectorized_value_type &result)
static void read_value(const ScalarNumber vector_entry, const unsigned int, scalar_value_type &result)
static void write_value(VectorizedArrayType &vector_entry, const unsigned int, const vectorized_value_type &result)
static void set_gradient(const vectorized_gradient_type &value, const unsigned int, vectorized_gradient_type &result)
static void get_value(vectorized_value_type &value, const unsigned int vector_lane, const scalar_value_type &result)
static void set_zero_value(value_type &value, const unsigned int vector_lane)
static ScalarNumber access(const value_type &value, const unsigned int vector_lane, const unsigned int)
static void set_zero_gradient(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_gradient_type &value, const unsigned int vector_lane, const scalar_gradient_type &result)
static void set_value(const vectorized_value_type &value, const unsigned int vector_lane, scalar_value_type &result)
static void read_value(const ScalarNumber vector_entry, const unsigned int, scalar_value_type &result)
static void set_gradient(const vectorized_gradient_type &value, const unsigned int, vectorized_gradient_type &result)
static void get_gradient(vectorized_gradient_type &value, const unsigned int vector_lane, const scalar_gradient_type &result)
static scalar_gradient_type access(const gradient_type &value, const unsigned int vector_lane, const unsigned int)
typename ::internal::VectorizedArrayTrait< Number >::vectorized_value_type VectorizedArrayType
static void set_zero_value(value_type &value, const unsigned int vector_lane)
static void get_value(vectorized_value_type &value, const unsigned int, const vectorized_value_type &result)
static void write_value(VectorizedArrayType &vector_entry, const unsigned int, const vectorized_value_type &result)
static void set_value(const vectorized_value_type &value, const unsigned int, vectorized_value_type &result)
static void set_zero_gradient(gradient_type &value, const unsigned int vector_lane)
static void set_gradient(const vectorized_gradient_type &value, const unsigned int vector_lane, scalar_gradient_type &result)
static void access(gradient_type &value, const unsigned int vector_lane, const unsigned int, const scalar_gradient_type &shape_gradient)
static ScalarNumber access(const value_type &value, const unsigned int vector_lane, const unsigned int)
typename internal::VectorizedArrayTrait< Number >::value_type ScalarNumber
static void get_gradient(vectorized_gradient_type &value, const unsigned int, const vectorized_gradient_type &result)
static void get_value(vectorized_value_type &value, const unsigned int vector_lane, const scalar_value_type &result)
static void access(value_type &value, const unsigned int vector_lane, const unsigned int, const ScalarNumber &shape_value)
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)
static void get_gradient(interface_vectorized_gradient_type &value, const unsigned int vector_lane, const gradient_type &result)
static Tensor< 1, dim, ScalarNumber > access(const gradient_type &value, const unsigned int vector_lane, const unsigned int component)
static void set_zero_gradient(gradient_type &value, const unsigned int vector_lane)
static void write_value(VectorizedArrayType &vector_entry, const unsigned int component, const vectorized_value_type &result)
static void get_value(vectorized_value_type &value, const unsigned int, const vectorized_value_type &result)
static void set_value(const vectorized_value_type &value, const unsigned int, vectorized_value_type &result)
static void set_value(const vectorized_value_type &value, const unsigned int vector_lane, scalar_value_type &result)
static void set_gradient(const interface_vectorized_gradient_type &value, const unsigned int vector_lane, gradient_type &result)
typename internal::VectorizedArrayTrait< Number >::value_type ScalarNumber
static void access(gradient_type &value, const unsigned int vector_lane, const unsigned int component, const Tensor< 1, dim, ScalarNumber > &shape_gradient)
typename ::internal::VectorizedArrayTrait< Number >::vectorized_value_type VectorizedArrayType
static void access(value_type &value, const unsigned int vector_lane, const unsigned int component, const ScalarNumber &shape_value)
static void read_value(const ScalarNumber vector_entry, const unsigned int component, scalar_value_type &result)
static void set_zero_value(value_type &value, const unsigned int vector_lane)
static void write_value(VectorizedArrayType &vector_entry, const unsigned int component, const vectorized_value_type &result)
typename ::internal::VectorizedArrayTrait< Number >::vectorized_value_type VectorizedArrayType
static void set_value(const vectorized_value_type &value, const unsigned int vector_lane, scalar_value_type &result)
typename internal::VectorizedArrayTrait< Number >::value_type ScalarNumber
static void access(value_type &value, const unsigned int vector_lane, const unsigned int component, const ScalarNumber &shape_value)
static void set_zero_value(value_type &value, const unsigned int vector_lane)
Tensor< 1, n_components, VectorizedArrayType > vectorized_value_type
static Tensor< 1, dim, ScalarNumber > access(const gradient_type &value, const unsigned int vector_lane, const unsigned int component)
Tensor< 1, n_components, Tensor< 1, dim, VectorizedArrayType > > vectorized_gradient_type
static void access(gradient_type &value, const unsigned int vector_lane, const unsigned int component, const Tensor< 1, dim, ScalarNumber > &shape_gradient)
static void read_value(const ScalarNumber vector_entry, const unsigned int component, scalar_value_type &result)
Tensor< 1, n_components, Tensor< 1, dim, ScalarNumber > > scalar_gradient_type
static void set_zero_gradient(gradient_type &value, const unsigned int vector_lane)
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, const vectorized_value_type &result)
static void set_value(const vectorized_value_type &value, const unsigned int, vectorized_value_type &result)
static void get_gradient(interface_vectorized_gradient_type &value, const unsigned int vector_lane, const gradient_type &result)
static void set_gradient(const interface_vectorized_gradient_type &value, const unsigned int vector_lane, gradient_type &result)
static void get_value(vectorized_value_type &value, const unsigned int vector_lane, const scalar_value_type &result)
static constexpr std::size_t width()
static constexpr std::size_t stride()
static value_type & get(value_type &value, unsigned int c)