Reference documentation for deal.II version 9.2.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\}}\)
fe_evaluation.h
Go to the documentation of this file.
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2011 - 2020 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 
17 #ifndef dealii_matrix_free_fe_evaluation_h
18 #define dealii_matrix_free_fe_evaluation_h
19 
20 
21 #include <deal.II/base/config.h>
22 
29 
31 
40 
41 
43 
44 
45 
46 namespace internal
47 {
49 }
50 
51 template <int dim,
52  int fe_degree,
53  int n_q_points_1d = fe_degree + 1,
54  int n_components_ = 1,
55  typename Number = double,
56  typename VectorizedArrayType = VectorizedArray<Number>>
58 
59 
92 template <int dim,
93  int n_components_,
94  typename Number,
95  bool is_face = false,
96  typename VectorizedArrayType = VectorizedArray<Number>>
98 {
99  static_assert(
101  "Type of Number and of VectorizedArrayType do not match.");
102 
103 public:
104  using number_type = Number;
106  using gradient_type =
108  static constexpr unsigned int dimension = dim;
109  static constexpr unsigned int n_components = n_components_;
110 
119 
128  unsigned int
130 
138  get_cell_type() const;
139 
144  get_shape_info() const;
145 
147 
184  template <typename VectorType>
185  void
186  read_dof_values(const VectorType &src, const unsigned int first_index = 0);
187 
216  template <typename VectorType>
217  void
218  read_dof_values_plain(const VectorType & src,
219  const unsigned int first_index = 0);
220 
251  template <typename VectorType>
252  void
254  VectorType & dst,
255  const unsigned int first_index = 0,
256  const std::bitset<VectorizedArrayType::size()> &mask =
257  std::bitset<VectorizedArrayType::size()>().flip()) const;
258 
291  template <typename VectorType>
292  void
294  const unsigned int first_index = 0,
295  const std::bitset<VectorizedArrayType::size()> &mask =
296  std::bitset<VectorizedArrayType::size()>().flip()) const;
297 
299 
320  value_type
321  get_dof_value(const unsigned int dof) const;
322 
333  void
334  submit_dof_value(const value_type val_in, const unsigned int dof);
335 
347  value_type
348  get_value(const unsigned int q_point) const;
349 
361  void
362  submit_value(const value_type val_in, const unsigned int q_point);
363 
374  get_gradient(const unsigned int q_point) const;
375 
389  value_type
390  get_normal_derivative(const unsigned int q_point) const;
391 
404  void
405  submit_gradient(const gradient_type grad_in, const unsigned int q_point);
406 
424  void
425  submit_normal_derivative(const value_type grad_in,
426  const unsigned int q_point);
427 
439  get_hessian(const unsigned int q_point) const;
440 
450  get_hessian_diagonal(const unsigned int q_point) const;
451 
462  value_type
463  get_laplacian(const unsigned int q_point) const;
464 
465 #ifdef DOXYGEN
466  // doxygen does not anyhow mention functions coming from partial template
467  // specialization of the base class, in this case FEEvaluationAccess<dim,dim>.
468  // For now, hack-in those functions manually only to fix documentation:
469 
476  VectorizedArrayType
477  get_divergence(const unsigned int q_point) const;
478 
488  get_symmetric_gradient(const unsigned int q_point) const;
489 
496  Tensor<1, (dim == 2 ? 1 : dim), VectorizedArrayType>
497  get_curl(const unsigned int q_point) const;
498 
514  void
515  submit_divergence(const VectorizedArrayType div_in,
516  const unsigned int q_point);
517 
534  void
537  const unsigned int q_point);
538 
551  void
553  const unsigned int q_point);
554 
555 #endif
556 
573  value_type
574  integrate_value() const;
575 
580  VectorizedArrayType
581  JxW(const unsigned int q_index) const;
582 
588  DEAL_II_DEPRECATED void
590 
598  inverse_jacobian(const unsigned int q_index) const;
599 
613  get_normal_vector(const unsigned int q_point) const;
614 
621  VectorizedArrayType
623 
628  template <typename T>
629  std::array<T, VectorizedArrayType::size()>
630  read_cell_data(const AlignedVector<std::array<T, VectorizedArrayType::size()>>
631  &array) const;
632 
637  std::array<unsigned int, VectorizedArrayType::size()>
638  get_cell_ids() const;
639 
641 
654  const VectorizedArrayType *
655  begin_dof_values() const;
656 
665  VectorizedArrayType *
667 
678  const VectorizedArrayType *
679  begin_values() const;
680 
691  VectorizedArrayType *
692  begin_values();
693 
705  const VectorizedArrayType *
706  begin_gradients() const;
707 
719  VectorizedArrayType *
720  begin_gradients();
721 
734  const VectorizedArrayType *
735  begin_hessians() const;
736 
749  VectorizedArrayType *
750  begin_hessians();
751 
757  const std::vector<unsigned int> &
759 
767  get_scratch_data() const;
768 
770 
771 protected:
782  const unsigned int dof_no,
783  const unsigned int first_selected_component,
784  const unsigned int quad_no,
785  const unsigned int fe_degree,
786  const unsigned int n_q_points,
787  const bool is_interior_face);
788 
823  template <int n_components_other>
824  FEEvaluationBase(const Mapping<dim> & mapping,
825  const FiniteElement<dim> &fe,
826  const Quadrature<1> & quadrature,
827  const UpdateFlags update_flags,
828  const unsigned int first_selected_component,
829  const FEEvaluationBase<dim,
830  n_components_other,
831  Number,
832  is_face,
833  VectorizedArrayType> *other);
834 
841  FEEvaluationBase(const FEEvaluationBase &other);
842 
850  operator=(const FEEvaluationBase &other);
851 
858  template <typename VectorType, typename VectorOperation>
859  void
860  read_write_operation(const VectorOperation &operation,
861  VectorType * vectors[],
862  const std::bitset<VectorizedArrayType::size()> &mask,
863  const bool apply_constraints = true) const;
864 
872  template <typename VectorType, typename VectorOperation>
873  void
875  const VectorOperation & operation,
876  VectorType * vectors[],
877  const std::bitset<VectorizedArrayType::size()> &mask) const;
878 
886  template <typename VectorType, typename VectorOperation>
887  void
889  VectorType * vectors[]) const;
890 
895 
901  VectorizedArrayType *scratch_data;
902 
915  VectorizedArrayType *values_dofs[n_components];
916 
928  VectorizedArrayType *values_quad[n_components];
929 
943  VectorizedArrayType *gradients_quad[n_components][dim];
944 
956  VectorizedArrayType *hessians_quad[n_components][(dim * (dim + 1)) / 2];
957 
961  const unsigned int quad_no;
962 
967  const unsigned int n_fe_components;
968 
973  const unsigned int active_fe_index;
974 
979  const unsigned int active_quad_index;
980 
984  const unsigned int n_quadrature_points;
985 
990 
997 
1005  (is_face ? dim - 1 : dim),
1006  dim,
1007  Number,
1008  VectorizedArrayType> *mapping_data;
1009 
1017 
1023 
1030  const VectorizedArrayType *J_value;
1031 
1036 
1041 
1045  const Number *quadrature_weights;
1046 
1051  unsigned int cell;
1052 
1058 
1064 
1069  unsigned int face_no;
1070 
1075  unsigned int face_orientation;
1076 
1084  unsigned int subface_index;
1085 
1093 
1100 
1107 
1114 
1121 
1128 
1135 
1140  std::shared_ptr<internal::MatrixFreeFunctions::
1141  MappingDataOnTheFly<dim, Number, VectorizedArrayType>>
1143 
1148  const unsigned int first_selected_component;
1149 
1154  mutable std::vector<types::global_dof_index> local_dof_indices;
1155 
1156 private:
1161  void
1163 
1164  // Make other FEEvaluationBase as well as FEEvaluation objects friends.
1165  template <int, int, typename, bool, typename>
1166  friend class FEEvaluationBase;
1167  template <int, int, int, int, typename, typename>
1168  friend class FEEvaluation;
1169 };
1170 
1171 
1172 
1182 template <int dim,
1183  int n_components_,
1184  typename Number,
1185  bool is_face,
1186  typename VectorizedArrayType = VectorizedArray<Number>>
1188  n_components_,
1189  Number,
1190  is_face,
1191  VectorizedArrayType>
1192 {
1193  static_assert(
1195  "Type of Number and of VectorizedArrayType do not match.");
1196 
1197 public:
1198  using number_type = Number;
1200  using gradient_type =
1202  static constexpr unsigned int dimension = dim;
1203  static constexpr unsigned int n_components = n_components_;
1204  using BaseClass =
1206 
1207 protected:
1217  const unsigned int dof_no,
1218  const unsigned int first_selected_component,
1219  const unsigned int quad_no,
1220  const unsigned int fe_degree,
1221  const unsigned int n_q_points,
1222  const bool is_interior_face = true);
1223 
1228  template <int n_components_other>
1229  FEEvaluationAccess(const Mapping<dim> & mapping,
1230  const FiniteElement<dim> &fe,
1231  const Quadrature<1> & quadrature,
1232  const UpdateFlags update_flags,
1233  const unsigned int first_selected_component,
1234  const FEEvaluationBase<dim,
1235  n_components_other,
1236  Number,
1237  is_face,
1238  VectorizedArrayType> *other);
1239 
1243  FEEvaluationAccess(const FEEvaluationAccess &other);
1244 
1249  operator=(const FEEvaluationAccess &other);
1250 };
1251 
1252 
1253 
1264 template <int dim, typename Number, bool is_face, typename VectorizedArrayType>
1265 class FEEvaluationAccess<dim, 1, Number, is_face, VectorizedArrayType>
1266  : public FEEvaluationBase<dim, 1, Number, is_face, VectorizedArrayType>
1267 {
1268  static_assert(
1270  "Type of Number and of VectorizedArrayType do not match.");
1271 
1272 public:
1273  using number_type = Number;
1274  using value_type = VectorizedArrayType;
1276  static constexpr unsigned int dimension = dim;
1277  using BaseClass =
1279 
1282  value_type
1283  get_dof_value(const unsigned int dof) const;
1284 
1287  void
1288  submit_dof_value(const value_type val_in, const unsigned int dof);
1289 
1292  value_type
1293  get_value(const unsigned int q_point) const;
1294 
1297  void
1298  submit_value(const value_type val_in, const unsigned int q_point);
1299 
1302  void
1304  const unsigned int q_point);
1305 
1309  get_gradient(const unsigned int q_point) const;
1310 
1313  value_type
1314  get_normal_derivative(const unsigned int q_point) const;
1315 
1318  void
1319  submit_gradient(const gradient_type grad_in, const unsigned int q_point);
1320 
1323  void
1324  submit_normal_derivative(const value_type grad_in,
1325  const unsigned int q_point);
1326 
1330  get_hessian(unsigned int q_point) const;
1331 
1335  get_hessian_diagonal(const unsigned int q_point) const;
1336 
1339  value_type
1340  get_laplacian(const unsigned int q_point) const;
1341 
1344  value_type
1345  integrate_value() const;
1346 
1347 protected:
1357  const unsigned int dof_no,
1358  const unsigned int first_selected_component,
1359  const unsigned int quad_no,
1360  const unsigned int fe_degree,
1361  const unsigned int n_q_points,
1362  const bool is_interior_face = true);
1363 
1368  template <int n_components_other>
1369  FEEvaluationAccess(const Mapping<dim> & mapping,
1370  const FiniteElement<dim> &fe,
1371  const Quadrature<1> & quadrature,
1372  const UpdateFlags update_flags,
1373  const unsigned int first_selected_component,
1374  const FEEvaluationBase<dim,
1375  n_components_other,
1376  Number,
1377  is_face,
1378  VectorizedArrayType> *other);
1379 
1383  FEEvaluationAccess(const FEEvaluationAccess &other);
1384 
1389  operator=(const FEEvaluationAccess &other);
1390 };
1391 
1392 
1393 
1405 template <int dim, typename Number, bool is_face, typename VectorizedArrayType>
1406 class FEEvaluationAccess<dim, dim, Number, is_face, VectorizedArrayType>
1407  : public FEEvaluationBase<dim, dim, Number, is_face, VectorizedArrayType>
1408 {
1409  static_assert(
1411  "Type of Number and of VectorizedArrayType do not match.");
1412 
1413 public:
1414  using number_type = Number;
1417  static constexpr unsigned int dimension = dim;
1418  static constexpr unsigned int n_components = dim;
1419  using BaseClass =
1421 
1425  get_gradient(const unsigned int q_point) const;
1426 
1431  VectorizedArrayType
1432  get_divergence(const unsigned int q_point) const;
1433 
1441  get_symmetric_gradient(const unsigned int q_point) const;
1442 
1447  Tensor<1, (dim == 2 ? 1 : dim), VectorizedArrayType>
1448  get_curl(const unsigned int q_point) const;
1449 
1453  get_hessian(const unsigned int q_point) const;
1454 
1458  get_hessian_diagonal(const unsigned int q_point) const;
1459 
1462  void
1463  submit_gradient(const gradient_type grad_in, const unsigned int q_point);
1464 
1473  void
1475  const Tensor<1, dim, Tensor<1, dim, VectorizedArrayType>> grad_in,
1476  const unsigned int q_point);
1477 
1486  void
1487  submit_divergence(const VectorizedArrayType div_in,
1488  const unsigned int q_point);
1489 
1498  void
1501  const unsigned int q_point);
1502 
1507  void
1509  const unsigned int q_point);
1510 
1511 protected:
1521  const unsigned int dof_no,
1522  const unsigned int first_selected_component,
1523  const unsigned int quad_no,
1524  const unsigned int dofs_per_cell,
1525  const unsigned int n_q_points,
1526  const bool is_interior_face = true);
1527 
1532  template <int n_components_other>
1533  FEEvaluationAccess(const Mapping<dim> & mapping,
1534  const FiniteElement<dim> &fe,
1535  const Quadrature<1> & quadrature,
1536  const UpdateFlags update_flags,
1537  const unsigned int first_selected_component,
1538  const FEEvaluationBase<dim,
1539  n_components_other,
1540  Number,
1541  is_face,
1542  VectorizedArrayType> *other);
1543 
1547  FEEvaluationAccess(const FEEvaluationAccess &other);
1548 
1553  operator=(const FEEvaluationAccess &other);
1554 };
1555 
1556 
1568 template <typename Number, bool is_face, typename VectorizedArrayType>
1569 class FEEvaluationAccess<1, 1, Number, is_face, VectorizedArrayType>
1570  : public FEEvaluationBase<1, 1, Number, is_face, VectorizedArrayType>
1571 {
1572  static_assert(
1574  "Type of Number and of VectorizedArrayType do not match.");
1575 
1576 public:
1577  using number_type = Number;
1578  using value_type = VectorizedArrayType;
1580  static constexpr unsigned int dimension = 1;
1581  using BaseClass =
1583 
1586  value_type
1587  get_dof_value(const unsigned int dof) const;
1588 
1591  void
1592  submit_dof_value(const value_type val_in, const unsigned int dof);
1593 
1596  value_type
1597  get_value(const unsigned int q_point) const;
1598 
1601  void
1602  submit_value(const value_type val_in, const unsigned int q_point);
1603 
1606  void
1607  submit_value(const gradient_type val_in, const unsigned int q_point);
1608 
1612  get_gradient(const unsigned int q_point) const;
1613 
1616  value_type
1617  get_normal_derivative(const unsigned int q_point) const;
1618 
1621  void
1622  submit_gradient(const gradient_type grad_in, const unsigned int q_point);
1623 
1626  void
1627  submit_gradient(const value_type grad_in, const unsigned int q_point);
1628 
1631  void
1632  submit_normal_derivative(const value_type grad_in,
1633  const unsigned int q_point);
1634 
1637  void
1639  const unsigned int q_point);
1640 
1644  get_hessian(unsigned int q_point) const;
1645 
1649  get_hessian_diagonal(const unsigned int q_point) const;
1650 
1653  value_type
1654  get_laplacian(const unsigned int q_point) const;
1655 
1658  value_type
1659  integrate_value() const;
1660 
1661 protected:
1670  const MatrixFree<1, Number, VectorizedArrayType> &matrix_free,
1671  const unsigned int dof_no,
1672  const unsigned int first_selected_component,
1673  const unsigned int quad_no,
1674  const unsigned int fe_degree,
1675  const unsigned int n_q_points,
1676  const bool is_interior_face = true);
1677 
1682  template <int n_components_other>
1683  FEEvaluationAccess(const Mapping<1> & mapping,
1684  const FiniteElement<1> &fe,
1685  const Quadrature<1> & quadrature,
1686  const UpdateFlags update_flags,
1687  const unsigned int first_selected_component,
1688  const FEEvaluationBase<1,
1689  n_components_other,
1690  Number,
1691  is_face,
1692  VectorizedArrayType> *other);
1693 
1697  FEEvaluationAccess(const FEEvaluationAccess &other);
1698 
1703  operator=(const FEEvaluationAccess &other);
1704 };
1705 
1706 
1707 
2253 template <int dim,
2254  int fe_degree,
2255  int n_q_points_1d,
2256  int n_components_,
2257  typename Number,
2258  typename VectorizedArrayType>
2259 class FEEvaluation : public FEEvaluationAccess<dim,
2260  n_components_,
2261  Number,
2262  false,
2263  VectorizedArrayType>
2264 {
2265  static_assert(
2267  "Type of Number and of VectorizedArrayType do not match.");
2268 
2269 public:
2273  using BaseClass =
2275 
2279  using number_type = Number;
2280 
2287 
2294 
2298  static constexpr unsigned int dimension = dim;
2299 
2304  static constexpr unsigned int n_components = n_components_;
2305 
2312  static constexpr unsigned int static_n_q_points =
2313  Utilities::pow(n_q_points_1d, dim);
2314 
2322  static constexpr unsigned int static_dofs_per_component =
2323  Utilities::pow(fe_degree + 1, dim);
2324 
2332  static constexpr unsigned int tensor_dofs_per_cell =
2334 
2342  static constexpr unsigned int static_dofs_per_cell =
2344 
2371  const unsigned int dof_no = 0,
2372  const unsigned int quad_no = 0,
2373  const unsigned int first_selected_component = 0);
2374 
2401  FEEvaluation(const Mapping<dim> & mapping,
2402  const FiniteElement<dim> &fe,
2403  const Quadrature<1> & quadrature,
2404  const UpdateFlags update_flags,
2405  const unsigned int first_selected_component = 0);
2406 
2412  FEEvaluation(const FiniteElement<dim> &fe,
2413  const Quadrature<1> & quadrature,
2414  const UpdateFlags update_flags,
2415  const unsigned int first_selected_component = 0);
2416 
2427  template <int n_components_other>
2428  FEEvaluation(const FiniteElement<dim> & fe,
2429  const FEEvaluationBase<dim,
2430  n_components_other,
2431  Number,
2432  false,
2433  VectorizedArrayType> &other,
2434  const unsigned int first_selected_component = 0);
2435 
2442  FEEvaluation(const FEEvaluation &other);
2443 
2450  FEEvaluation &
2451  operator=(const FEEvaluation &other);
2452 
2461  void
2462  reinit(const unsigned int cell_batch_index);
2463 
2476  template <typename DoFHandlerType, bool level_dof_access>
2477  void
2479  &cell);
2480 
2491  void
2492  reinit(const typename Triangulation<dim>::cell_iterator &cell);
2493 
2503  void
2504  evaluate(const bool evaluate_values,
2505  const bool evaluate_gradients,
2506  const bool evaluate_hessians = false);
2507 
2520  void
2521  evaluate(const VectorizedArrayType *values_array,
2522  const bool evaluate_values,
2523  const bool evaluate_gradients,
2524  const bool evaluate_hessians = false);
2525 
2539  template <typename VectorType>
2540  void
2541  gather_evaluate(const VectorType &input_vector,
2542  const bool evaluate_values,
2543  const bool evaluate_gradients,
2544  const bool evaluate_hessians = false);
2545 
2556  void
2557  integrate(const bool integrate_values, const bool integrate_gradients);
2558 
2570  void
2571  integrate(const bool integrate_values,
2572  const bool integrate_gradients,
2573  VectorizedArrayType *values_array);
2574 
2588  template <typename VectorType>
2589  void
2590  integrate_scatter(const bool integrate_values,
2591  const bool integrate_gradients,
2592  VectorType &output_vector);
2593 
2599  quadrature_point(const unsigned int q_point) const;
2600 
2607  const unsigned int dofs_per_component;
2608 
2615  const unsigned int dofs_per_cell;
2616 
2624  const unsigned int n_q_points;
2625 
2626 private:
2631  void
2632  check_template_arguments(const unsigned int fe_no,
2633  const unsigned int first_selected_component);
2634 };
2635 
2636 
2637 
2675 template <int dim,
2676  int fe_degree,
2677  int n_q_points_1d = fe_degree + 1,
2678  int n_components_ = 1,
2679  typename Number = double,
2680  typename VectorizedArrayType = VectorizedArray<Number>>
2682  n_components_,
2683  Number,
2684  true,
2685  VectorizedArrayType>
2686 {
2687  static_assert(
2689  "Type of Number and of VectorizedArrayType do not match.");
2690 
2691 public:
2695  using BaseClass =
2697 
2701  using number_type = Number;
2702 
2709 
2716 
2720  static constexpr unsigned int dimension = dim;
2721 
2726  static constexpr unsigned int n_components = n_components_;
2727 
2735  static constexpr unsigned int static_n_q_points =
2736  Utilities::pow(n_q_points_1d, dim - 1);
2737 
2744  static constexpr unsigned int static_n_q_points_cell =
2745  Utilities::pow(n_q_points_1d, dim);
2746 
2753  static constexpr unsigned int static_dofs_per_component =
2754  Utilities::pow(fe_degree + 1, dim);
2755 
2762  static constexpr unsigned int tensor_dofs_per_cell =
2764 
2771  static constexpr unsigned int static_dofs_per_cell =
2773 
2805  const bool is_interior_face = true,
2806  const unsigned int dof_no = 0,
2807  const unsigned int quad_no = 0,
2808  const unsigned int first_selected_component = 0);
2809 
2820  void
2821  reinit(const unsigned int face_batch_number);
2822 
2830  void
2831  reinit(const unsigned int cell_batch_number, const unsigned int face_number);
2832 
2843  void
2844  evaluate(const bool evaluate_values, const bool evaluate_gradients);
2845 
2858  void
2859  evaluate(const VectorizedArrayType *values_array,
2860  const bool evaluate_values,
2861  const bool evaluate_gradients);
2862 
2874  template <typename VectorType>
2875  void
2876  gather_evaluate(const VectorType &input_vector,
2877  const bool evaluate_values,
2878  const bool evaluate_gradients);
2879 
2889  void
2890  integrate(const bool integrate_values, const bool integrate_gradients);
2891 
2900  void
2901  integrate(const bool integrate_values,
2902  const bool integrate_gradients,
2903  VectorizedArrayType *values_array);
2904 
2916  template <typename VectorType>
2917  void
2918  integrate_scatter(const bool integrate_values,
2919  const bool integrate_gradients,
2920  VectorType &output_vector);
2921 
2927  quadrature_point(const unsigned int q_point) const;
2928 
2935  const unsigned int dofs_per_component;
2936 
2943  const unsigned int dofs_per_cell;
2944 
2952  const unsigned int n_q_points;
2953 };
2954 
2955 
2956 
2957 namespace internal
2958 {
2959  namespace MatrixFreeFunctions
2960  {
2961  // a helper function to compute the number of DoFs of a DGP element at
2962  // compile time, depending on the degree
2963  template <int dim, int degree>
2965  {
2966  // this division is always without remainder
2967  static constexpr unsigned int value =
2968  (DGP_dofs_per_component<dim - 1, degree>::value * (degree + dim)) / dim;
2969  };
2970 
2971  // base specialization: 1d elements have 'degree+1' degrees of freedom
2972  template <int degree>
2973  struct DGP_dofs_per_component<1, degree>
2974  {
2975  static constexpr unsigned int value = degree + 1;
2976  };
2977  } // namespace MatrixFreeFunctions
2978 } // namespace internal
2979 
2980 
2981 /*----------------------- Inline functions ----------------------------------*/
2982 
2983 #ifndef DOXYGEN
2984 
2985 
2986 
2987 /*----------------------- FEEvaluationBase ----------------------------------*/
2988 
2989 template <int dim,
2990  int n_components_,
2991  typename Number,
2992  bool is_face,
2993  typename VectorizedArrayType>
2994 inline FEEvaluationBase<dim,
2995  n_components_,
2996  Number,
2997  is_face,
2998  VectorizedArrayType>::
2999  FEEvaluationBase(const MatrixFree<dim, Number, VectorizedArrayType> &data_in,
3000  const unsigned int dof_no,
3001  const unsigned int first_selected_component,
3002  const unsigned int quad_no_in,
3003  const unsigned int fe_degree,
3004  const unsigned int n_q_points,
3005  const bool is_interior_face)
3006  : scratch_data_array(data_in.acquire_scratch_data())
3007  , quad_no(quad_no_in)
3008  , n_fe_components(data_in.get_dof_info(dof_no).start_components.back())
3009  , active_fe_index(fe_degree != numbers::invalid_unsigned_int ?
3010  data_in.get_dof_info(dof_no).fe_index_from_degree(
3011  first_selected_component,
3012  fe_degree) :
3013  0)
3014  , active_quad_index(fe_degree != numbers::invalid_unsigned_int ?
3015  (is_face ? data_in.get_mapping_info()
3016  .face_data[quad_no_in]
3017  .quad_index_from_n_q_points(n_q_points) :
3018  data_in.get_mapping_info()
3019  .cell_data[quad_no_in]
3020  .quad_index_from_n_q_points(n_q_points)) :
3021  0)
3022  , n_quadrature_points(fe_degree != numbers::invalid_unsigned_int ?
3023  n_q_points :
3024  (is_face ? data_in
3025  .get_shape_info(dof_no,
3026  quad_no_in,
3027  active_fe_index,
3028  active_quad_index)
3029  .n_q_points_face :
3030  data_in
3031  .get_shape_info(dof_no,
3032  quad_no_in,
3033  active_fe_index,
3034  active_quad_index)
3035  .n_q_points))
3036  , matrix_info(&data_in)
3037  , dof_info(&data_in.get_dof_info(dof_no))
3038  , mapping_data(
3039  internal::MatrixFreeFunctions::
3040  MappingInfoCellsOrFaces<dim, Number, is_face, VectorizedArrayType>::get(
3041  data_in.get_mapping_info(),
3042  quad_no))
3043  , data(&data_in.get_shape_info(
3044  dof_no,
3045  quad_no_in,
3046  dof_info->component_to_base_index[first_selected_component],
3047  active_fe_index,
3048  active_quad_index))
3049  , jacobian(nullptr)
3050  , J_value(nullptr)
3051  , normal_vectors(nullptr)
3052  , normal_x_jacobian(nullptr)
3053  , quadrature_weights(
3054  mapping_data->descriptor[active_quad_index].quadrature_weights.begin())
3055  , cell(numbers::invalid_unsigned_int)
3056  , is_interior_face(is_interior_face)
3057  , dof_access_index(
3058  is_face ?
3059  (is_interior_face ?
3060  internal::MatrixFreeFunctions::DoFInfo::dof_access_face_interior :
3061  internal::MatrixFreeFunctions::DoFInfo::dof_access_face_exterior) :
3062  internal::MatrixFreeFunctions::DoFInfo::dof_access_cell)
3063  , cell_type(internal::MatrixFreeFunctions::general)
3064  , dof_values_initialized(false)
3065  , values_quad_initialized(false)
3066  , gradients_quad_initialized(false)
3067  , hessians_quad_initialized(false)
3068  , values_quad_submitted(false)
3069  , gradients_quad_submitted(false)
3070  , first_selected_component(first_selected_component)
3071 {
3072  set_data_pointers();
3073  Assert(matrix_info->mapping_initialized() == true, ExcNotInitialized());
3074  AssertDimension(matrix_info->get_task_info().vectorization_length,
3075  VectorizedArrayType::size());
3076  AssertDimension((is_face ? data->n_q_points_face : data->n_q_points),
3077  n_quadrature_points);
3078  AssertDimension(n_quadrature_points,
3079  mapping_data->descriptor[active_quad_index].n_q_points);
3080  Assert(
3081  dof_info->start_components.back() == 1 ||
3082  static_cast<int>(n_components_) <=
3083  static_cast<int>(
3084  dof_info->start_components
3085  [dof_info->component_to_base_index[first_selected_component] + 1]) -
3086  first_selected_component,
3087  ExcMessage(
3088  "You tried to construct a vector-valued evaluator with " +
3090  " components. However, "
3091  "the current base element has only " +
3093  dof_info->start_components
3094  [dof_info->component_to_base_index[first_selected_component] + 1] -
3095  first_selected_component) +
3096  " components left when starting from local element index " +
3098  first_selected_component -
3099  dof_info->start_components
3100  [dof_info->component_to_base_index[first_selected_component]]) +
3101  " (global index " + std::to_string(first_selected_component) + ")"));
3102 
3103  // do not check for correct dimensions of data fields here, should be done
3104  // in derived classes
3105 }
3106 
3107 
3108 
3109 template <int dim,
3110  int n_components_,
3111  typename Number,
3112  bool is_face,
3113  typename VectorizedArrayType>
3114 template <int n_components_other>
3115 inline FEEvaluationBase<dim,
3116  n_components_,
3117  Number,
3118  is_face,
3119  VectorizedArrayType>::
3120  FEEvaluationBase(const Mapping<dim> & mapping,
3121  const FiniteElement<dim> &fe,
3122  const Quadrature<1> & quadrature,
3123  const UpdateFlags update_flags,
3124  const unsigned int first_selected_component,
3125  const FEEvaluationBase<dim,
3126  n_components_other,
3127  Number,
3128  is_face,
3129  VectorizedArrayType> *other)
3130  : scratch_data_array(new AlignedVector<VectorizedArrayType>())
3131  , quad_no(numbers::invalid_unsigned_int)
3132  , n_fe_components(n_components_)
3133  , active_fe_index(numbers::invalid_unsigned_int)
3134  , active_quad_index(numbers::invalid_unsigned_int)
3135  , n_quadrature_points(
3136  Utilities::fixed_power < is_face ? dim - 1 : dim > (quadrature.size()))
3137  , matrix_info(nullptr)
3138  , dof_info(nullptr)
3139  , mapping_data(nullptr)
3140  ,
3141  // select the correct base element from the given FE component
3142  data(new internal::MatrixFreeFunctions::ShapeInfo<VectorizedArrayType>(
3143  quadrature,
3144  fe,
3145  fe.component_to_base_index(first_selected_component).first))
3146  , jacobian(nullptr)
3147  , J_value(nullptr)
3148  , normal_vectors(nullptr)
3149  , normal_x_jacobian(nullptr)
3150  , quadrature_weights(nullptr)
3151  , cell(0)
3152  , cell_type(internal::MatrixFreeFunctions::general)
3153  , is_interior_face(true)
3154  , dof_access_index(internal::MatrixFreeFunctions::DoFInfo::dof_access_cell)
3155  , dof_values_initialized(false)
3156  , values_quad_initialized(false)
3157  , gradients_quad_initialized(false)
3158  , hessians_quad_initialized(false)
3159  , values_quad_submitted(false)
3160  , gradients_quad_submitted(false)
3161  ,
3162  // keep the number of the selected component within the current base element
3163  // for reading dof values
3164  first_selected_component(first_selected_component)
3165 {
3166  set_data_pointers();
3167 
3168  Assert(other == nullptr || other->mapped_geometry.get() != nullptr,
3169  ExcInternalError());
3170  if (other != nullptr &&
3171  other->mapped_geometry->get_quadrature() == quadrature)
3172  mapped_geometry = other->mapped_geometry;
3173  else
3174  mapped_geometry =
3175  std::make_shared<internal::MatrixFreeFunctions::
3176  MappingDataOnTheFly<dim, Number, VectorizedArrayType>>(
3177  mapping, quadrature, update_flags);
3178  cell = 0;
3179 
3180  mapping_data = &mapped_geometry->get_data_storage();
3181  jacobian = mapped_geometry->get_data_storage().jacobians[0].begin();
3182  J_value = mapped_geometry->get_data_storage().JxW_values.begin();
3183 
3184  const unsigned int base_element_number =
3185  fe.component_to_base_index(first_selected_component).first;
3186  Assert(fe.element_multiplicity(base_element_number) == 1 ||
3187  fe.element_multiplicity(base_element_number) -
3188  first_selected_component >=
3189  n_components_,
3190  ExcMessage("The underlying element must at least contain as many "
3191  "components as requested by this class"));
3192  (void)base_element_number;
3193 }
3194 
3195 
3196 
3197 template <int dim,
3198  int n_components_,
3199  typename Number,
3200  bool is_face,
3201  typename VectorizedArrayType>
3202 inline FEEvaluationBase<dim,
3203  n_components_,
3204  Number,
3205  is_face,
3206  VectorizedArrayType>::
3207  FEEvaluationBase(const FEEvaluationBase<dim,
3208  n_components_,
3209  Number,
3210  is_face,
3211  VectorizedArrayType> &other)
3212  : scratch_data_array(other.matrix_info == nullptr ?
3213  new AlignedVector<VectorizedArrayType>() :
3214  other.matrix_info->acquire_scratch_data())
3215  , quad_no(other.quad_no)
3216  , n_fe_components(other.n_fe_components)
3217  , active_fe_index(other.active_fe_index)
3218  , active_quad_index(other.active_quad_index)
3219  , n_quadrature_points(other.n_quadrature_points)
3220  , matrix_info(other.matrix_info)
3221  , dof_info(other.dof_info)
3222  , mapping_data(other.mapping_data)
3223  , data(other.matrix_info == nullptr ?
3224  new internal::MatrixFreeFunctions::ShapeInfo<VectorizedArrayType>(
3225  *other.data) :
3226  other.data)
3227  , jacobian(nullptr)
3228  , J_value(nullptr)
3229  , normal_vectors(nullptr)
3230  , normal_x_jacobian(nullptr)
3231  , quadrature_weights(
3232  other.matrix_info == nullptr ?
3233  nullptr :
3234  mapping_data->descriptor[active_quad_index].quadrature_weights.begin())
3235  , cell(numbers::invalid_unsigned_int)
3236  , cell_type(internal::MatrixFreeFunctions::general)
3237  , is_interior_face(other.is_interior_face)
3238  , dof_access_index(other.dof_access_index)
3239  , dof_values_initialized(false)
3240  , values_quad_initialized(false)
3241  , gradients_quad_initialized(false)
3242  , hessians_quad_initialized(false)
3243  , values_quad_submitted(false)
3244  , gradients_quad_submitted(false)
3245  , first_selected_component(other.first_selected_component)
3246 {
3247  set_data_pointers();
3248 
3249  // Create deep copy of mapped geometry for use in parallel...
3250  if (other.mapped_geometry.get() != nullptr)
3251  {
3252  mapped_geometry = std::make_shared<
3253  internal::MatrixFreeFunctions::
3254  MappingDataOnTheFly<dim, Number, VectorizedArrayType>>(
3255  other.mapped_geometry->get_fe_values().get_mapping(),
3256  other.mapped_geometry->get_quadrature(),
3257  other.mapped_geometry->get_fe_values().get_update_flags());
3258  mapping_data = &mapped_geometry->get_data_storage();
3259  cell = 0;
3260 
3261  jacobian = mapped_geometry->get_data_storage().jacobians[0].begin();
3262  J_value = mapped_geometry->get_data_storage().JxW_values.begin();
3263  }
3264 }
3265 
3266 
3267 
3268 template <int dim,
3269  int n_components_,
3270  typename Number,
3271  bool is_face,
3272  typename VectorizedArrayType>
3273 inline FEEvaluationBase<dim,
3274  n_components_,
3275  Number,
3276  is_face,
3277  VectorizedArrayType> &
3279 operator=(const FEEvaluationBase<dim,
3280  n_components_,
3281  Number,
3282  is_face,
3283  VectorizedArrayType> &other)
3284 {
3285  AssertDimension(quad_no, other.quad_no);
3286  AssertDimension(n_fe_components, other.n_fe_components);
3287  AssertDimension(active_fe_index, other.active_fe_index);
3288  AssertDimension(active_quad_index, other.active_quad_index);
3289  AssertDimension(first_selected_component, other.first_selected_component);
3290 
3291  // release old memory
3292  if (matrix_info == nullptr)
3293  {
3294  delete data;
3295  delete scratch_data_array;
3296  }
3297  else
3298  {
3299  matrix_info->release_scratch_data(scratch_data_array);
3300  }
3301 
3302  matrix_info = other.matrix_info;
3303  dof_info = other.dof_info;
3304  mapping_data = other.mapping_data;
3305  if (other.matrix_info == nullptr)
3306  {
3308  *other.data);
3309  scratch_data_array = new AlignedVector<VectorizedArrayType>();
3310  }
3311  else
3312  {
3313  data = other.data;
3314  scratch_data_array = matrix_info->acquire_scratch_data();
3315  }
3316  set_data_pointers();
3317 
3318  quadrature_weights =
3319  (mapping_data != nullptr ?
3320  mapping_data->descriptor[active_quad_index].quadrature_weights.begin() :
3321  nullptr);
3324  is_interior_face = other.is_interior_face;
3325  dof_access_index = other.dof_access_index;
3326 
3327  // Create deep copy of mapped geometry for use in parallel...
3328  if (other.mapped_geometry.get() != nullptr)
3329  {
3330  mapped_geometry = std::make_shared<
3331  internal::MatrixFreeFunctions::
3332  MappingDataOnTheFly<dim, Number, VectorizedArrayType>>(
3333  other.mapped_geometry->get_fe_values().get_mapping(),
3334  other.mapped_geometry->get_quadrature(),
3335  other.mapped_geometry->get_fe_values().get_update_flags());
3336  cell = 0;
3337  mapping_data = &mapped_geometry->get_data_storage();
3338  jacobian = mapped_geometry->get_data_storage().jacobians[0].begin();
3339  J_value = mapped_geometry->get_data_storage().JxW_values.begin();
3340  }
3341 
3342  return *this;
3343 }
3344 
3345 
3346 
3347 template <int dim,
3348  int n_components_,
3349  typename Number,
3350  bool is_face,
3351  typename VectorizedArrayType>
3352 inline FEEvaluationBase<dim,
3353  n_components_,
3354  Number,
3355  is_face,
3356  VectorizedArrayType>::~FEEvaluationBase()
3357 {
3358  if (matrix_info != nullptr)
3359  {
3360  try
3361  {
3362  matrix_info->release_scratch_data(scratch_data_array);
3363  }
3364  catch (...)
3365  {}
3366  }
3367  else
3368  {
3369  delete scratch_data_array;
3370  delete data;
3371  data = nullptr;
3372  }
3373  scratch_data_array = nullptr;
3374 }
3375 
3376 
3377 
3378 template <int dim,
3379  int n_components_,
3380  typename Number,
3381  bool is_face,
3382  typename VectorizedArrayType>
3383 inline void
3386 {
3387  Assert(scratch_data_array != nullptr, ExcInternalError());
3388 
3389  const unsigned int tensor_dofs_per_component =
3390  Utilities::fixed_power<dim>(this->data->data.front().fe_degree + 1);
3391  const unsigned int dofs_per_component =
3392  this->data->dofs_per_component_on_cell;
3393  const unsigned int n_quadrature_points =
3394  is_face ? this->data->n_q_points_face : this->data->n_q_points;
3395 
3396  const unsigned int shift =
3397  std::max(tensor_dofs_per_component + 1, dofs_per_component) *
3398  n_components_ * 3 +
3399  2 * n_quadrature_points;
3400  const unsigned int allocated_size =
3401  shift + n_components_ * dofs_per_component +
3402  (n_components_ * (dim * dim + 2 * dim + 1) * n_quadrature_points);
3403  scratch_data_array->resize_fast(allocated_size);
3404 
3405  // set the pointers to the correct position in the data array
3406  for (unsigned int c = 0; c < n_components_; ++c)
3407  {
3408  this->values_dofs[c] =
3409  scratch_data_array->begin() + c * dofs_per_component;
3410  this->values_quad[c] = scratch_data_array->begin() +
3411  n_components * dofs_per_component +
3412  c * n_quadrature_points;
3413  for (unsigned int d = 0; d < dim; ++d)
3414  this->gradients_quad[c][d] =
3415  scratch_data_array->begin() +
3416  n_components * (dofs_per_component + n_quadrature_points) +
3417  (c * dim + d) * n_quadrature_points;
3418  for (unsigned int d = 0; d < (dim * dim + dim) / 2; ++d)
3419  this->hessians_quad[c][d] =
3420  scratch_data_array->begin() +
3421  n_components *
3422  ((dim + 1) * n_quadrature_points + dofs_per_component) +
3423  (c * (dim * dim + dim) + d) * n_quadrature_points;
3424  }
3425  scratch_data =
3426  scratch_data_array->begin() + n_components_ * dofs_per_component +
3427  (n_components_ * (dim * dim + 2 * dim + 1) * n_quadrature_points);
3428 }
3429 
3430 
3431 
3432 template <int dim,
3433  int n_components_,
3434  typename Number,
3435  bool is_face,
3436  typename VectorizedArrayType>
3437 inline unsigned int
3440 {
3441  if (matrix_info == nullptr)
3442  return 0;
3443  else
3444  {
3445  AssertIndexRange(cell, this->mapping_data->data_index_offsets.size());
3446  return this->mapping_data->data_index_offsets[cell];
3447  }
3448 }
3449 
3450 
3451 
3452 template <int dim,
3453  int n_components_,
3454  typename Number,
3455  bool is_face,
3456  typename VectorizedArrayType>
3459  get_cell_type() const
3460 {
3462  return cell_type;
3463 }
3464 
3465 
3466 
3467 template <int dim,
3468  int n_components_,
3469  typename Number,
3470  bool is_face,
3471  typename VectorizedArrayType>
3474  get_shape_info() const
3475 {
3476  Assert(data != nullptr, ExcInternalError());
3477  return *data;
3478 }
3479 
3480 
3481 
3482 template <int dim,
3483  int n_components_,
3484  typename Number,
3485  bool is_face,
3486  typename VectorizedArrayType>
3487 inline void
3490 {
3491  AssertDimension(JxW_values.size(), n_quadrature_points);
3492  Assert(J_value != nullptr, ExcNotInitialized());
3493  if (this->cell_type <= internal::MatrixFreeFunctions::affine)
3494  {
3495  VectorizedArrayType J = J_value[0];
3496  for (unsigned int q = 0; q < this->n_quadrature_points; ++q)
3497  JxW_values[q] = J * this->quadrature_weights[q];
3498  }
3499  else
3500  for (unsigned int q = 0; q < n_quadrature_points; ++q)
3501  JxW_values[q] = J_value[q];
3502 }
3503 
3504 
3505 
3506 template <int dim,
3507  int n_components_,
3508  typename Number,
3509  bool is_face,
3510  typename VectorizedArrayType>
3513  get_normal_vector(const unsigned int q_index) const
3514 {
3515  AssertIndexRange(q_index, n_quadrature_points);
3516  Assert(normal_vectors != nullptr, ExcMessage("Did not call reinit()!"));
3517  if (this->cell_type <= internal::MatrixFreeFunctions::flat_faces)
3518  return normal_vectors[0];
3519  else
3520  return normal_vectors[q_index];
3521 }
3522 
3523 
3524 
3525 template <int dim,
3526  int n_components_,
3527  typename Number,
3528  bool is_face,
3529  typename VectorizedArrayType>
3530 inline DEAL_II_ALWAYS_INLINE VectorizedArrayType
3532  const unsigned int q_index) const
3533 {
3534  AssertIndexRange(q_index, n_quadrature_points);
3535  Assert(J_value != nullptr, ExcNotInitialized());
3536  if (this->cell_type <= internal::MatrixFreeFunctions::affine)
3537  {
3538  Assert(this->quadrature_weights != nullptr, ExcInternalError());
3539  return J_value[0] * this->quadrature_weights[q_index];
3540  }
3541  else
3542  return J_value[q_index];
3543 }
3544 
3545 
3546 
3547 template <int dim,
3548  int n_components_,
3549  typename Number,
3550  bool is_face,
3551  typename VectorizedArrayType>
3554  inverse_jacobian(const unsigned int q_index) const
3555 {
3556  AssertIndexRange(q_index, n_quadrature_points);
3557  Assert(this->jacobian != nullptr, ExcNotImplemented());
3558  if (this->cell_type <= internal::MatrixFreeFunctions::affine)
3559  return jacobian[0];
3560  else
3561  return jacobian[q_index];
3562 }
3563 
3564 template <int dim,
3565  int n_components_,
3566  typename Number,
3567  bool is_face,
3568  typename VectorizedArrayType>
3569 std::array<unsigned int, VectorizedArrayType::size()>
3571  get_cell_ids() const
3572 {
3573  const unsigned int n_lanes = VectorizedArrayType::size();
3574  std::array<unsigned int, n_lanes> cells;
3575 
3576  // initialize array
3577  for (unsigned int i = 0; i < n_lanes; ++i)
3578  cells[i] = numbers::invalid_unsigned_int;
3579 
3580  if ((is_face == false) ||
3581  (is_face &&
3582  this->dof_access_index ==
3584  this->is_interior_face))
3585  {
3586  // cell or interior face face (element-centric loop)
3587  for (unsigned int i = 0; i < n_lanes; ++i)
3588  cells[i] = cell * n_lanes + i;
3589  }
3590  else if (is_face &&
3591  this->dof_access_index ==
3593  this->is_interior_face == false)
3594  {
3595  // exterior face (element-centric loop): for this case, we need to
3596  // look into the FaceInfo field that collects information from both
3597  // sides of a face once for the global mesh, and pick the face id that
3598  // is not the local one (cell_this).
3599  for (unsigned int i = 0; i < n_lanes; i++)
3600  {
3601  // compute actual (non vectorized) cell ID
3602  const unsigned int cell_this = this->cell * n_lanes + i;
3603  // compute face ID
3604  unsigned int face_index =
3605  this->matrix_info->get_cell_and_face_to_plain_faces()(this->cell,
3606  this->face_no,
3607  i);
3608 
3609  if (face_index == numbers::invalid_unsigned_int)
3610  continue; // invalid face ID: no neighbor on boundary
3611 
3612  // get cell ID on both sides of face
3613  auto cell_m = this->matrix_info->get_face_info(face_index / n_lanes)
3614  .cells_interior[face_index % n_lanes];
3615  auto cell_p = this->matrix_info->get_face_info(face_index / n_lanes)
3616  .cells_exterior[face_index % n_lanes];
3617 
3618  // compare the IDs with the given cell ID
3619  if (cell_m == cell_this)
3620  cells[i] = cell_p; // neighbor has the other ID
3621  else if (cell_p == cell_this)
3622  cells[i] = cell_m;
3623  }
3624  }
3625  else if (is_face)
3626  {
3627  // face-centric faces
3628  const unsigned int *cells_ =
3629  is_interior_face ?
3630  &this->matrix_info->get_face_info(cell).cells_interior[0] :
3631  &this->matrix_info->get_face_info(cell).cells_exterior[0];
3632  for (unsigned int i = 0; i < VectorizedArrayType::size(); ++i)
3633  if (cells_[i] != numbers::invalid_unsigned_int)
3634  cells[i] = cells_[i];
3635  }
3636 
3637  return cells;
3638 }
3639 
3640 
3641 
3642 template <int dim,
3643  int n_components_,
3644  typename Number,
3645  bool is_face,
3646  typename VectorizedArrayType>
3647 inline VectorizedArrayType
3650 {
3651  Assert(matrix_info != nullptr, ExcNotImplemented());
3652  AssertDimension(array.size(),
3653  matrix_info->get_task_info().cell_partition_data.back());
3654 
3655  // 1) collect ids of cell
3656  const auto cells = this->get_cell_ids();
3657 
3658  // 2) actually gather values
3659  VectorizedArrayType out = make_vectorized_array<Number>(Number(1.));
3660  for (unsigned int i = 0; i < VectorizedArrayType::size(); ++i)
3661  if (cells[i] != numbers::invalid_unsigned_int)
3662  out[i] = array[cells[i] / VectorizedArrayType::size()]
3663  [cells[i] % VectorizedArrayType::size()];
3664  return out;
3665 }
3666 
3667 
3668 
3669 template <int dim,
3670  int n_components_,
3671  typename Number,
3672  bool is_face,
3673  typename VectorizedArrayType>
3674 template <typename T>
3675 inline std::array<T, VectorizedArrayType::size()>
3677  read_cell_data(const AlignedVector<std::array<T, VectorizedArrayType::size()>>
3678  &array) const
3679 {
3680  Assert(matrix_info != nullptr, ExcNotImplemented());
3681  AssertDimension(array.size(),
3682  matrix_info->get_task_info().cell_partition_data.back());
3683 
3684  // 1) collect ids of cell
3685  const auto cells = this->get_cell_ids();
3686 
3687  // 2) actually gather values
3688  std::array<T, VectorizedArrayType::size()> out;
3689  for (unsigned int i = 0; i < VectorizedArrayType::size(); ++i)
3690  if (cells[i] != numbers::invalid_unsigned_int)
3691  out[i] = array[cells[i] / VectorizedArrayType::size()]
3692  [cells[i] % VectorizedArrayType::size()];
3693  return out;
3694 }
3695 
3696 
3697 
3698 namespace internal
3699 {
3700  // allows to select between block vectors and non-block vectors, which
3701  // allows to use a unified interface for extracting blocks on block vectors
3702  // and doing nothing on usual vectors
3703  template <typename VectorType, bool>
3704  struct BlockVectorSelector
3705  {};
3706 
3707  template <typename VectorType>
3708  struct BlockVectorSelector<VectorType, true>
3709  {
3710  using BaseVectorType = typename VectorType::BlockType;
3711 
3712  static BaseVectorType *
3713  get_vector_component(VectorType &vec, const unsigned int component)
3714  {
3715  AssertIndexRange(component, vec.n_blocks());
3716  return &vec.block(component);
3717  }
3718  };
3719 
3720  template <typename VectorType>
3721  struct BlockVectorSelector<VectorType, false>
3722  {
3723  using BaseVectorType = VectorType;
3724 
3725  static BaseVectorType *
3726  get_vector_component(VectorType &vec, const unsigned int component)
3727  {
3728  // FEEvaluation allows to combine several vectors from a scalar
3729  // FiniteElement into a "vector-valued" FEEvaluation object with
3730  // multiple components. These components can be extracted with the other
3731  // get_vector_component functions. If we do not get a vector of vectors
3732  // (std::vector<VectorType>, std::vector<VectorType*>, BlockVector), we
3733  // must make sure that we do not duplicate the components in input
3734  // and/or duplicate the resulting integrals. In such a case, we should
3735  // only get the zeroth component in the vector contained set nullptr for
3736  // the others which allows us to catch unintended use in
3737  // read_write_operation.
3738  if (component == 0)
3739  return &vec;
3740  else
3741  return nullptr;
3742  }
3743  };
3744 
3745  template <typename VectorType>
3746  struct BlockVectorSelector<std::vector<VectorType>, false>
3747  {
3748  using BaseVectorType = VectorType;
3749 
3750  static BaseVectorType *
3751  get_vector_component(std::vector<VectorType> &vec,
3752  const unsigned int component)
3753  {
3754  AssertIndexRange(component, vec.size());
3755  return &vec[component];
3756  }
3757  };
3758 
3759  template <typename VectorType>
3760  struct BlockVectorSelector<std::vector<VectorType *>, false>
3761  {
3762  using BaseVectorType = VectorType;
3763 
3764  static BaseVectorType *
3765  get_vector_component(std::vector<VectorType *> &vec,
3766  const unsigned int component)
3767  {
3768  AssertIndexRange(component, vec.size());
3769  return vec[component];
3770  }
3771  };
3772 } // namespace internal
3773 
3774 
3775 
3776 template <int dim,
3777  int n_components_,
3778  typename Number,
3779  bool is_face,
3780  typename VectorizedArrayType>
3781 template <typename VectorType, typename VectorOperation>
3782 inline void
3784  read_write_operation(const VectorOperation &operation,
3785  VectorType * src[],
3786  const std::bitset<VectorizedArrayType::size()> &mask,
3787  const bool apply_constraints) const
3788 {
3789  // Case 1: No MatrixFree object given, simple case because we do not need to
3790  // process constraints and need not care about vectorization -> go to
3791  // separate function
3792  if (matrix_info == nullptr)
3793  {
3794  read_write_operation_global(operation, src);
3795  return;
3796  }
3797 
3798  Assert(dof_info != nullptr, ExcNotInitialized());
3799  Assert(matrix_info->indices_initialized() == true, ExcNotInitialized());
3800  if (n_fe_components == 1)
3801  for (unsigned int comp = 0; comp < n_components; ++comp)
3802  {
3803  Assert(src[comp] != nullptr,
3804  ExcMessage("The finite element underlying this FEEvaluation "
3805  "object is scalar, but you requested " +
3807  " components via the template argument in "
3808  "FEEvaluation. In that case, you must pass an "
3809  "std::vector<VectorType> or a BlockVector to " +
3810  "read_dof_values and distribute_local_to_global."));
3811  internal::check_vector_compatibility(*src[comp], *dof_info);
3812  }
3813  else
3814  {
3815  internal::check_vector_compatibility(*src[0], *dof_info);
3816  }
3817 
3818  // Case 2: contiguous indices which use reduced storage of indices and can
3819  // use vectorized load/store operations -> go to separate function
3820  AssertIndexRange(cell,
3821  dof_info->index_storage_variants[dof_access_index].size());
3822  if (dof_info->index_storage_variants
3823  [is_face ? dof_access_index :
3825  [cell] >=
3827  {
3828  read_write_operation_contiguous(operation, src, mask);
3829  return;
3830  }
3831 
3832  // Case 3: standard operation with one index per degree of freedom -> go on
3833  // here
3834  constexpr unsigned int n_lanes = VectorizedArrayType::size();
3835  Assert(mask.count() == n_lanes,
3836  ExcNotImplemented("Masking currently not implemented for "
3837  "non-contiguous DoF storage"));
3838 
3839  std::integral_constant<bool,
3841  vector_selector;
3842 
3843  const unsigned int dofs_per_component =
3844  this->data->dofs_per_component_on_cell;
3845  if (dof_info->index_storage_variants
3846  [is_face ? dof_access_index :
3848  [cell] ==
3850  {
3851  const unsigned int *dof_indices =
3852  dof_info->dof_indices_interleaved.data() +
3853  dof_info->row_starts[cell * n_fe_components * n_lanes].first +
3854  dof_info->component_dof_indices_offset[active_fe_index]
3855  [first_selected_component] *
3856  n_lanes;
3857  if (n_components == 1 || n_fe_components == 1)
3858  for (unsigned int i = 0; i < dofs_per_component;
3859  ++i, dof_indices += n_lanes)
3860  for (unsigned int comp = 0; comp < n_components; ++comp)
3861  operation.process_dof_gather(dof_indices,
3862  *src[comp],
3863  0,
3864  values_dofs[comp][i],
3865  vector_selector);
3866  else
3867  for (unsigned int comp = 0; comp < n_components; ++comp)
3868  for (unsigned int i = 0; i < dofs_per_component;
3869  ++i, dof_indices += n_lanes)
3870  operation.process_dof_gather(
3871  dof_indices, *src[0], 0, values_dofs[comp][i], vector_selector);
3872  return;
3873  }
3874 
3875  const unsigned int * dof_indices[n_lanes];
3876  VectorizedArrayType **values_dofs =
3877  const_cast<VectorizedArrayType **>(&this->values_dofs[0]);
3878 
3879  // Assign the appropriate cell ids for face/cell case and get the pointers
3880  // to the dof indices of the cells on all lanes
3881  unsigned int cells_copied[n_lanes];
3882  const unsigned int *cells;
3883  unsigned int n_vectorization_actual =
3884  dof_info->n_vectorization_lanes_filled[dof_access_index][cell];
3885  bool has_constraints = false;
3886  if (is_face)
3887  {
3888  if (dof_access_index ==
3890  for (unsigned int v = 0; v < n_vectorization_actual; ++v)
3891  cells_copied[v] = cell * VectorizedArrayType::size() + v;
3892  cells = dof_access_index ==
3894  &cells_copied[0] :
3895  (is_interior_face ?
3896  &this->matrix_info->get_face_info(cell).cells_interior[0] :
3897  &this->matrix_info->get_face_info(cell).cells_exterior[0]);
3898  for (unsigned int v = 0; v < n_vectorization_actual; ++v)
3899  {
3900  Assert(cells[v] < dof_info->row_starts.size() - 1,
3901  ExcInternalError());
3902  const std::pair<unsigned int, unsigned int> *my_index_start =
3903  &dof_info->row_starts[cells[v] * n_fe_components +
3904  first_selected_component];
3905 
3906  // check whether any of the SIMD lanes has constraints, i.e., the
3907  // constraint indicator which is the second entry of row_starts
3908  // increments on this cell
3909  if (my_index_start[n_components].second != my_index_start[0].second)
3910  has_constraints = true;
3911 
3912  dof_indices[v] =
3913  dof_info->dof_indices.data() + my_index_start[0].first;
3914  }
3915  for (unsigned int v = n_vectorization_actual; v < n_lanes; ++v)
3916  dof_indices[v] = nullptr;
3917  }
3918  else
3919  {
3920  AssertIndexRange((cell + 1) * n_lanes * n_fe_components,
3921  dof_info->row_starts.size());
3922  const unsigned int n_components_read =
3923  n_fe_components > 1 ? n_components : 1;
3924  for (unsigned int v = 0; v < n_vectorization_actual; ++v)
3925  {
3926  const std::pair<unsigned int, unsigned int> *my_index_start =
3927  &dof_info->row_starts[(cell * n_lanes + v) * n_fe_components +
3928  first_selected_component];
3929  if (my_index_start[n_components_read].second !=
3930  my_index_start[0].second)
3931  has_constraints = true;
3932  Assert(my_index_start[n_components_read].first ==
3933  my_index_start[0].first ||
3934  my_index_start[0].first < dof_info->dof_indices.size(),
3935  ExcIndexRange(0,
3936  my_index_start[0].first,
3937  dof_info->dof_indices.size()));
3938  dof_indices[v] =
3939  dof_info->dof_indices.data() + my_index_start[0].first;
3940  }
3941  for (unsigned int v = n_vectorization_actual; v < n_lanes; ++v)
3942  dof_indices[v] = nullptr;
3943  }
3944 
3945  // Case where we have no constraints throughout the whole cell: Can go
3946  // through the list of DoFs directly
3947  if (!has_constraints)
3948  {
3949  if (n_vectorization_actual < n_lanes)
3950  for (unsigned int comp = 0; comp < n_components; ++comp)
3951  for (unsigned int i = 0; i < dofs_per_component; ++i)
3952  operation.process_empty(values_dofs[comp][i]);
3953  if (n_components == 1 || n_fe_components == 1)
3954  {
3955  for (unsigned int v = 0; v < n_vectorization_actual; ++v)
3956  for (unsigned int i = 0; i < dofs_per_component; ++i)
3957  for (unsigned int comp = 0; comp < n_components; ++comp)
3958  operation.process_dof(dof_indices[v][i],
3959  *src[comp],
3960  values_dofs[comp][i][v]);
3961  }
3962  else
3963  {
3964  for (unsigned int comp = 0; comp < n_components; ++comp)
3965  for (unsigned int v = 0; v < n_vectorization_actual; ++v)
3966  for (unsigned int i = 0; i < dofs_per_component; ++i)
3967  operation.process_dof(
3968  dof_indices[v][comp * dofs_per_component + i],
3969  *src[0],
3970  values_dofs[comp][i][v]);
3971  }
3972  return;
3973  }
3974 
3975  // In the case where there are some constraints to be resolved, loop over
3976  // all vector components that are filled and then over local dofs. ind_local
3977  // holds local number on cell, index iterates over the elements of
3978  // index_local_to_global and dof_indices points to the global indices stored
3979  // in index_local_to_global
3980  if (n_vectorization_actual < n_lanes)
3981  for (unsigned int comp = 0; comp < n_components; ++comp)
3982  for (unsigned int i = 0; i < dofs_per_component; ++i)
3983  operation.process_empty(values_dofs[comp][i]);
3984  for (unsigned int v = 0; v < n_vectorization_actual; ++v)
3985  {
3986  const unsigned int cell_index = is_face ? cells[v] : cell * n_lanes + v;
3987  const unsigned int cell_dof_index =
3988  cell_index * n_fe_components + first_selected_component;
3989  const unsigned int n_components_read =
3990  n_fe_components > 1 ? n_components : 1;
3991  unsigned int index_indicators =
3992  dof_info->row_starts[cell_dof_index].second;
3993  unsigned int next_index_indicators =
3994  dof_info->row_starts[cell_dof_index + 1].second;
3995 
3996  // For read_dof_values_plain, redirect the dof_indices field to the
3997  // unconstrained indices
3998  if (apply_constraints == false &&
3999  dof_info->row_starts[cell_dof_index].second !=
4000  dof_info->row_starts[cell_dof_index + n_components_read].second)
4001  {
4002  Assert(dof_info->row_starts_plain_indices[cell_index] !=
4004  ExcNotInitialized());
4005  dof_indices[v] =
4006  dof_info->plain_dof_indices.data() +
4007  dof_info->component_dof_indices_offset[active_fe_index]
4008  [first_selected_component] +
4009  dof_info->row_starts_plain_indices[cell_index];
4010  next_index_indicators = index_indicators;
4011  }
4012 
4013  if (n_components == 1 || n_fe_components == 1)
4014  {
4015  unsigned int ind_local = 0;
4016  for (; index_indicators != next_index_indicators; ++index_indicators)
4017  {
4018  const std::pair<unsigned short, unsigned short> indicator =
4019  dof_info->constraint_indicator[index_indicators];
4020  // run through values up to next constraint
4021  for (unsigned int j = 0; j < indicator.first; ++j)
4022  for (unsigned int comp = 0; comp < n_components; ++comp)
4023  operation.process_dof(dof_indices[v][j],
4024  *src[comp],
4025  values_dofs[comp][ind_local + j][v]);
4026 
4027  ind_local += indicator.first;
4028  dof_indices[v] += indicator.first;
4029 
4030  // constrained case: build the local value as a linear
4031  // combination of the global value according to constraints
4032  Number value[n_components];
4033  for (unsigned int comp = 0; comp < n_components; ++comp)
4034  operation.pre_constraints(values_dofs[comp][ind_local][v],
4035  value[comp]);
4036 
4037  const Number *data_val =
4038  matrix_info->constraint_pool_begin(indicator.second);
4039  const Number *end_pool =
4040  matrix_info->constraint_pool_end(indicator.second);
4041  for (; data_val != end_pool; ++data_val, ++dof_indices[v])
4042  for (unsigned int comp = 0; comp < n_components; ++comp)
4043  operation.process_constraint(*dof_indices[v],
4044  *data_val,
4045  *src[comp],
4046  value[comp]);
4047 
4048  for (unsigned int comp = 0; comp < n_components; ++comp)
4049  operation.post_constraints(value[comp],
4050  values_dofs[comp][ind_local][v]);
4051  ind_local++;
4052  }
4053 
4054  AssertIndexRange(ind_local, dofs_per_component + 1);
4055 
4056  for (; ind_local < dofs_per_component; ++dof_indices[v], ++ind_local)
4057  for (unsigned int comp = 0; comp < n_components; ++comp)
4058  operation.process_dof(*dof_indices[v],
4059  *src[comp],
4060  values_dofs[comp][ind_local][v]);
4061  }
4062  else
4063  {
4064  // case with vector-valued finite elements where all components are
4065  // included in one single vector. Assumption: first come all entries
4066  // to the first component, then all entries to the second one, and
4067  // so on. This is ensured by the way MatrixFree reads out the
4068  // indices.
4069  for (unsigned int comp = 0; comp < n_components; ++comp)
4070  {
4071  unsigned int ind_local = 0;
4072 
4073  // check whether there is any constraint on the current cell
4074  for (; index_indicators != next_index_indicators;
4075  ++index_indicators)
4076  {
4077  const std::pair<unsigned short, unsigned short> indicator =
4078  dof_info->constraint_indicator[index_indicators];
4079 
4080  // run through values up to next constraint
4081  for (unsigned int j = 0; j < indicator.first; ++j)
4082  operation.process_dof(dof_indices[v][j],
4083  *src[0],
4084  values_dofs[comp][ind_local + j][v]);
4085  ind_local += indicator.first;
4086  dof_indices[v] += indicator.first;
4087 
4088  // constrained case: build the local value as a linear
4089  // combination of the global value according to constraints
4090  Number value;
4091  operation.pre_constraints(values_dofs[comp][ind_local][v],
4092  value);
4093 
4094  const Number *data_val =
4095  matrix_info->constraint_pool_begin(indicator.second);
4096  const Number *end_pool =
4097  matrix_info->constraint_pool_end(indicator.second);
4098 
4099  for (; data_val != end_pool; ++data_val, ++dof_indices[v])
4100  operation.process_constraint(*dof_indices[v],
4101  *data_val,
4102  *src[0],
4103  value);
4104 
4105  operation.post_constraints(value,
4106  values_dofs[comp][ind_local][v]);
4107  ind_local++;
4108  }
4109 
4110  AssertIndexRange(ind_local, dofs_per_component + 1);
4111 
4112  // get the dof values past the last constraint
4113  for (; ind_local < dofs_per_component;
4114  ++dof_indices[v], ++ind_local)
4115  {
4116  AssertIndexRange(*dof_indices[v], src[0]->size());
4117  operation.process_dof(*dof_indices[v],
4118  *src[0],
4119  values_dofs[comp][ind_local][v]);
4120  }
4121 
4122  if (apply_constraints == true && comp + 1 < n_components)
4123  next_index_indicators =
4124  dof_info->row_starts[cell_dof_index + comp + 2].second;
4125  }
4126  }
4127  }
4128 }
4129 
4130 
4131 
4132 template <int dim,
4133  int n_components_,
4134  typename Number,
4135  bool is_face,
4136  typename VectorizedArrayType>
4137 template <typename VectorType, typename VectorOperation>
4138 inline void
4141  VectorType * src[]) const
4142 {
4143  Assert(!local_dof_indices.empty(), ExcNotInitialized());
4144 
4145  unsigned int index =
4146  first_selected_component * data->dofs_per_component_on_cell;
4147  for (unsigned int comp = 0; comp < n_components; ++comp)
4148  {
4149  for (unsigned int i = 0; i < data->dofs_per_component_on_cell;
4150  ++i, ++index)
4151  {
4152  operation.process_empty(values_dofs[comp][i]);
4153  operation.process_dof_global(
4154  local_dof_indices[data->lexicographic_numbering[index]],
4155  *src[0],
4156  values_dofs[comp][i][0]);
4157  }
4158  }
4159 }
4160 
4161 
4162 
4163 template <int dim,
4164  int n_components_,
4165  typename Number,
4166  bool is_face,
4167  typename VectorizedArrayType>
4168 template <typename VectorType, typename VectorOperation>
4169 inline void
4172  const VectorOperation & operation,
4173  VectorType * src[],
4174  const std::bitset<VectorizedArrayType::size()> &mask) const
4175 {
4176  // This functions processes the functions read_dof_values,
4177  // distribute_local_to_global, and set_dof_values with the same code for
4178  // contiguous cell indices (DG case). The distinction between these three
4179  // cases is made by the input VectorOperation that either reads values from
4180  // a vector and puts the data into the local data field or write local data
4181  // into the vector. Certain operations are no-ops for the given use case.
4182 
4183  std::integral_constant<bool,
4185  vector_selector;
4187  is_face ? dof_access_index :
4189  const unsigned int n_lanes = mask.count();
4190 
4191  const std::vector<unsigned int> &dof_indices_cont =
4192  dof_info->dof_indices_contiguous[ind];
4193 
4194  // Simple case: We have contiguous storage, so we can simply copy out the
4195  // data
4196  if (dof_info->index_storage_variants[ind][cell] ==
4198  interleaved_contiguous &&
4199  n_lanes == VectorizedArrayType::size())
4200  {
4201  const unsigned int dof_index =
4202  dof_indices_cont[cell * VectorizedArrayType::size()] +
4203  dof_info->component_dof_indices_offset[active_fe_index]
4204  [first_selected_component] *
4205  VectorizedArrayType::size();
4206  if (n_components == 1 || n_fe_components == 1)
4207  for (unsigned int comp = 0; comp < n_components; ++comp)
4208  operation.process_dofs_vectorized(data->dofs_per_component_on_cell,
4209  dof_index,
4210  *src[comp],
4211  values_dofs[comp],
4212  vector_selector);
4213  else
4214  operation.process_dofs_vectorized(data->dofs_per_component_on_cell *
4215  n_components,
4216  dof_index,
4217  *src[0],
4218  values_dofs[0],
4219  vector_selector);
4220  return;
4221  }
4222 
4223  // More general case: Must go through the components one by one and apply
4224  // some transformations
4225  const unsigned int n_filled_lanes =
4226  dof_info->n_vectorization_lanes_filled[ind][this->cell];
4227 
4228  unsigned int dof_indices[VectorizedArrayType::size()];
4229  for (unsigned int v = 0; v < n_filled_lanes; ++v)
4230  dof_indices[v] =
4231  dof_indices_cont[cell * VectorizedArrayType::size() + v] +
4232  dof_info->component_dof_indices_offset[active_fe_index]
4233  [first_selected_component] *
4234  dof_info->dof_indices_interleave_strides
4235  [ind][cell * VectorizedArrayType::size() + v];
4236 
4237  for (unsigned int v = n_filled_lanes; v < VectorizedArrayType::size(); ++v)
4238  dof_indices[v] = numbers::invalid_unsigned_int;
4239 
4240  // In the case with contiguous cell indices, we know that there are no
4241  // constraints and that the indices within each element are contiguous
4242  if (n_filled_lanes == VectorizedArrayType::size() &&
4243  n_lanes == VectorizedArrayType::size())
4244  {
4245  if (dof_info->index_storage_variants[ind][cell] ==
4247  contiguous)
4248  {
4249  if (n_components == 1 || n_fe_components == 1)
4250  for (unsigned int comp = 0; comp < n_components; ++comp)
4251  operation.process_dofs_vectorized_transpose(
4252  data->dofs_per_component_on_cell,
4253  dof_indices,
4254  *src[comp],
4255  values_dofs[comp],
4256  vector_selector);
4257  else
4258  operation.process_dofs_vectorized_transpose(
4259  data->dofs_per_component_on_cell * n_components,
4260  dof_indices,
4261  *src[0],
4262  &values_dofs[0][0],
4263  vector_selector);
4264  }
4265  else if (dof_info->index_storage_variants[ind][cell] ==
4267  interleaved_contiguous_strided)
4268  {
4269  if (n_components == 1 || n_fe_components == 1)
4270  for (unsigned int i = 0; i < data->dofs_per_component_on_cell; ++i)
4271  {
4272  for (unsigned int comp = 0; comp < n_components; ++comp)
4273  operation.process_dof_gather(dof_indices,
4274  *src[comp],
4275  i * VectorizedArrayType::size(),
4276  values_dofs[comp][i],
4277  vector_selector);
4278  }
4279  else
4280  for (unsigned int comp = 0; comp < n_components; ++comp)
4281  for (unsigned int i = 0; i < data->dofs_per_component_on_cell;
4282  ++i)
4283  {
4284  operation.process_dof_gather(
4285  dof_indices,
4286  *src[0],
4287  (comp * data->dofs_per_component_on_cell + i) *
4288  VectorizedArrayType::size(),
4289  values_dofs[comp][i],
4290  vector_selector);
4291  }
4292  }
4293  else
4294  {
4295  Assert(dof_info->index_storage_variants[ind][cell] ==
4297  IndexStorageVariants::interleaved_contiguous_mixed_strides,
4298  ExcNotImplemented());
4299  const unsigned int *offsets =
4300  &dof_info->dof_indices_interleave_strides
4301  [ind][VectorizedArrayType::size() * cell];
4302  if (n_components == 1 || n_fe_components == 1)
4303  for (unsigned int i = 0; i < data->dofs_per_component_on_cell; ++i)
4304  {
4305  for (unsigned int comp = 0; comp < n_components; ++comp)
4306  operation.process_dof_gather(dof_indices,
4307  *src[comp],
4308  0,
4309  values_dofs[comp][i],
4310  vector_selector);
4312  for (unsigned int v = 0; v < VectorizedArrayType::size(); ++v)
4313  dof_indices[v] += offsets[v];
4314  }
4315  else
4316  for (unsigned int comp = 0; comp < n_components; ++comp)
4317  for (unsigned int i = 0; i < data->dofs_per_component_on_cell;
4318  ++i)
4319  {
4320  operation.process_dof_gather(dof_indices,
4321  *src[0],
4322  0,
4323  values_dofs[comp][i],
4324  vector_selector);
4326  for (unsigned int v = 0; v < VectorizedArrayType::size(); ++v)
4327  dof_indices[v] += offsets[v];
4328  }
4329  }
4330  }
4331  else
4332  for (unsigned int comp = 0; comp < n_components; ++comp)
4333  {
4334  for (unsigned int i = 0; i < data->dofs_per_component_on_cell; ++i)
4335  operation.process_empty(values_dofs[comp][i]);
4336  if (dof_info->index_storage_variants[ind][cell] ==
4338  contiguous)
4339  {
4340  if (n_components == 1 || n_fe_components == 1)
4341  {
4342  for (unsigned int v = 0; v < n_filled_lanes; ++v)
4343  if (mask[v] == true)
4344  for (unsigned int i = 0;
4345  i < data->dofs_per_component_on_cell;
4346  ++i)
4347  operation.process_dof(dof_indices[v] + i,
4348  *src[comp],
4349  values_dofs[comp][i][v]);
4350  }
4351  else
4352  {
4353  for (unsigned int v = 0; v < n_filled_lanes; ++v)
4354  if (mask[v] == true)
4355  for (unsigned int i = 0;
4356  i < data->dofs_per_component_on_cell;
4357  ++i)
4358  operation.process_dof(
4359  dof_indices[v] + i +
4360  comp * data->dofs_per_component_on_cell,
4361  *src[0],
4362  values_dofs[comp][i][v]);
4363  }
4364  }
4365  else
4366  {
4367  const unsigned int *offsets =
4368  &dof_info->dof_indices_interleave_strides
4369  [ind][VectorizedArrayType::size() * cell];
4370  for (unsigned int v = 0; v < n_filled_lanes; ++v)
4371  AssertIndexRange(offsets[v], VectorizedArrayType::size() + 1);
4372  if (n_components == 1 || n_fe_components == 1)
4373  for (unsigned int v = 0; v < n_filled_lanes; ++v)
4374  {
4375  if (mask[v] == true)
4376  for (unsigned int i = 0;
4377  i < data->dofs_per_component_on_cell;
4378  ++i)
4379  operation.process_dof(dof_indices[v] + i * offsets[v],
4380  *src[comp],
4381  values_dofs[comp][i][v]);
4382  }
4383  else
4384  {
4385  for (unsigned int v = 0; v < n_filled_lanes; ++v)
4386  if (mask[v] == true)
4387  for (unsigned int i = 0;
4388  i < data->dofs_per_component_on_cell;
4389  ++i)
4390  operation.process_dof(
4391  dof_indices[v] +
4392  (i + comp * data->dofs_per_component_on_cell) *
4393  offsets[v],
4394  *src[0],
4395  values_dofs[comp][i][v]);
4396  }
4397  }
4398  }
4399 }
4400 
4401 
4402 
4403 template <int dim,
4404  int n_components_,
4405  typename Number,
4406  bool is_face,
4407  typename VectorizedArrayType>
4408 template <typename VectorType>
4409 inline void
4411  read_dof_values(const VectorType &src, const unsigned int first_index)
4412 {
4413  // select between block vectors and non-block vectors. Note that the number
4414  // of components is checked in the internal data
4415  typename internal::BlockVectorSelector<
4416  VectorType,
4417  IsBlockVector<VectorType>::value>::BaseVectorType *src_data[n_components];
4418  for (unsigned int d = 0; d < n_components; ++d)
4419  src_data[d] =
4420  internal::BlockVectorSelector<VectorType,
4422  get_vector_component(const_cast<VectorType &>(src), d + first_index);
4423 
4425  read_write_operation(reader,
4426  src_data,
4427  std::bitset<VectorizedArrayType::size()>().flip(),
4428  true);
4429 
4430 # ifdef DEBUG
4431  dof_values_initialized = true;
4432 # endif
4433 }
4434 
4435 
4436 
4437 template <int dim,
4438  int n_components_,
4439  typename Number,
4440  bool is_face,
4441  typename VectorizedArrayType>
4442 template <typename VectorType>
4443 inline void
4445  read_dof_values_plain(const VectorType &src, const unsigned int first_index)
4446 {
4447  // select between block vectors and non-block vectors. Note that the number
4448  // of components is checked in the internal data
4449  typename internal::BlockVectorSelector<
4450  VectorType,
4451  IsBlockVector<VectorType>::value>::BaseVectorType *src_data[n_components];
4452  for (unsigned int d = 0; d < n_components; ++d)
4453  src_data[d] =
4454  internal::BlockVectorSelector<VectorType,
4456  get_vector_component(const_cast<VectorType &>(src), d + first_index);
4457 
4459  read_write_operation(reader,
4460  src_data,
4461  std::bitset<VectorizedArrayType::size()>().flip(),
4462  false);
4463 
4464 # ifdef DEBUG
4465  dof_values_initialized = true;
4466 # endif
4467 }
4468 
4469 
4470 
4471 template <int dim,
4472  int n_components_,
4473  typename Number,
4474  bool is_face,
4475  typename VectorizedArrayType>
4476 template <typename VectorType>
4477 inline void
4480  VectorType & dst,
4481  const unsigned int first_index,
4482  const std::bitset<VectorizedArrayType::size()> &mask) const
4483 {
4484 # ifdef DEBUG
4485  Assert(dof_values_initialized == true,
4487 # endif
4488 
4489  // select between block vectors and non-block vectors. Note that the number
4490  // of components is checked in the internal data
4491  typename internal::BlockVectorSelector<
4492  VectorType,
4493  IsBlockVector<VectorType>::value>::BaseVectorType *dst_data[n_components];
4494  for (unsigned int d = 0; d < n_components; ++d)
4495  dst_data[d] = internal::BlockVectorSelector<
4496  VectorType,
4497  IsBlockVector<VectorType>::value>::get_vector_component(dst,
4498  d + first_index);
4499 
4501  distributor;
4502  read_write_operation(distributor, dst_data, mask);
4503 }
4504 
4505 
4506 
4507 template <int dim,
4508  int n_components_,
4509  typename Number,
4510  bool is_face,
4511  typename VectorizedArrayType>
4512 template <typename VectorType>
4513 inline void
4516  const unsigned int first_index,
4517  const std::bitset<VectorizedArrayType::size()> &mask) const
4518 {
4519 # ifdef DEBUG
4520  Assert(dof_values_initialized == true,
4522 # endif
4523 
4524  // select between block vectors and non-block vectors. Note that the number
4525  // of components is checked in the internal data
4526  typename internal::BlockVectorSelector<
4527  VectorType,
4528  IsBlockVector<VectorType>::value>::BaseVectorType *dst_data[n_components];
4529  for (unsigned int d = 0; d < n_components; ++d)
4530  dst_data[d] = internal::BlockVectorSelector<
4531  VectorType,
4532  IsBlockVector<VectorType>::value>::get_vector_component(dst,
4533  d + first_index);
4534 
4536  read_write_operation(setter, dst_data, mask);
4537 }
4538 
4539 
4540 
4541 /*------------------------------ access to data fields ----------------------*/
4542 
4543 template <int dim,
4544  int n_components,
4545  typename Number,
4546  bool is_face,
4547  typename VectorizedArrayType>
4548 inline const std::vector<unsigned int> &
4551 {
4552  return data->lexicographic_numbering;
4553 }
4554 
4555 
4556 
4557 template <int dim,
4558  int n_components,
4559  typename Number,
4560  bool is_face,
4561  typename VectorizedArrayType>
4564  get_scratch_data() const
4565 {
4567  const_cast<VectorizedArrayType *>(scratch_data),
4568  scratch_data_array->end() - scratch_data);
4569 }
4570 
4571 
4572 
4573 template <int dim,
4574  int n_components,
4575  typename Number,
4576  bool is_face,
4577  typename VectorizedArrayType>
4578 inline const VectorizedArrayType *
4580  begin_dof_values() const
4581 {
4582  return &values_dofs[0][0];
4583 }
4584 
4585 
4586 
4587 template <int dim,
4588  int n_components,
4589  typename Number,
4590  bool is_face,
4591  typename VectorizedArrayType>
4592 inline VectorizedArrayType *
4595 {
4596 # ifdef DEBUG
4597  dof_values_initialized = true;
4598 # endif
4599  return &values_dofs[0][0];
4600 }
4601 
4602 
4603 
4604 template <int dim,
4605  int n_components,
4606  typename Number,
4607  bool is_face,
4608  typename VectorizedArrayType>
4609 inline const VectorizedArrayType *
4611  begin_values() const
4612 {
4613 # ifdef DEBUG
4614  Assert(values_quad_initialized || values_quad_submitted, ExcNotInitialized());
4615 # endif
4616  return &values_quad[0][0];
4617 }
4618 
4619 
4620 
4621 template <int dim,
4622  int n_components,
4623  typename Number,
4624  bool is_face,
4625  typename VectorizedArrayType>
4626 inline VectorizedArrayType *
4628  begin_values()
4629 {
4630 # ifdef DEBUG
4631  values_quad_initialized = true;
4632  values_quad_submitted = true;
4633 # endif
4634  return &values_quad[0][0];
4635 }
4636 
4637 
4638 
4639 template <int dim,
4640  int n_components,
4641  typename Number,
4642  bool is_face,
4643  typename VectorizedArrayType>
4644 inline const VectorizedArrayType *
4646  begin_gradients() const
4647 {
4648 # ifdef DEBUG
4649  Assert(gradients_quad_initialized || gradients_quad_submitted,
4650  ExcNotInitialized());
4651 # endif
4652  return &gradients_quad[0][0][0];
4653 }
4654 
4655 
4656 
4657 template <int dim,
4658  int n_components,
4659  typename Number,
4660  bool is_face,
4661  typename VectorizedArrayType>
4662 inline VectorizedArrayType *
4665 {
4666 # ifdef DEBUG
4667  gradients_quad_submitted = true;
4668  gradients_quad_initialized = true;
4669 # endif
4670  return &gradients_quad[0][0][0];
4671 }
4672 
4673 
4674 
4675 template <int dim,
4676  int n_components,
4677  typename Number,
4678  bool is_face,
4679  typename VectorizedArrayType>
4680 inline const VectorizedArrayType *
4682  begin_hessians() const
4683 {
4684 # ifdef DEBUG
4685  Assert(hessians_quad_initialized, ExcNotInitialized());
4686 # endif
4687  return &hessians_quad[0][0][0];
4688 }
4689 
4690 
4691 
4692 template <int dim,
4693  int n_components,
4694  typename Number,
4695  bool is_face,
4696  typename VectorizedArrayType>
4697 inline VectorizedArrayType *
4700 {
4701 # ifdef DEBUG
4702  hessians_quad_initialized = true;
4703 # endif
4704  return &hessians_quad[0][0][0];
4705 }
4706 
4707 
4708 
4709 template <int dim,
4710  int n_components_,
4711  typename Number,
4712  bool is_face,
4713  typename VectorizedArrayType>
4716  get_dof_value(const unsigned int dof) const
4717 {
4718  AssertIndexRange(dof, this->data->dofs_per_component_on_cell);
4720  for (unsigned int comp = 0; comp < n_components; comp++)
4721  return_value[comp] = this->values_dofs[comp][dof];
4722  return return_value;
4723 }
4724 
4725 
4726 
4727 template <int dim,
4728  int n_components_,
4729  typename Number,
4730  bool is_face,
4731  typename VectorizedArrayType>
4734  get_value(const unsigned int q_point) const
4735 {
4736 # ifdef DEBUG
4737  Assert(this->values_quad_initialized == true,
4739 # endif
4740  AssertIndexRange(q_point, this->n_quadrature_points);
4742  for (unsigned int comp = 0; comp < n_components; comp++)
4743  return_value[comp] = this->values_quad[comp][q_point];
4744  return return_value;
4745 }
4746 
4747 
4748 
4749 template <int dim,
4750  int n_components_,
4751  typename Number,
4752  bool is_face,
4753  typename VectorizedArrayType>
4754 inline DEAL_II_ALWAYS_INLINE
4757  get_gradient(const unsigned int q_point) const
4758 {
4759 # ifdef DEBUG
4760  Assert(this->gradients_quad_initialized == true,
4762 # endif
4763  AssertIndexRange(q_point, this->n_quadrature_points);
4764 
4765  Assert(jacobian != nullptr, ExcNotInitialized());
4766 
4768 
4769  // Cartesian cell
4770  if (!is_face && this->cell_type == internal::MatrixFreeFunctions::cartesian)
4771  {
4772  for (unsigned int comp = 0; comp < n_components; comp++)
4773  for (unsigned int d = 0; d < dim; ++d)
4774  grad_out[comp][d] =
4775  (this->gradients_quad[comp][d][q_point] * jacobian[0][d][d]);
4776  }
4777  // cell with general/affine Jacobian
4778  else
4779  {
4781  jacobian[this->cell_type > internal::MatrixFreeFunctions::affine ?
4782  q_point :
4783  0];
4784  for (unsigned int comp = 0; comp < n_components; comp++)
4785  for (unsigned int d = 0; d < dim; ++d)
4786  {
4787  grad_out[comp][d] =
4788  jac[d][0] * this->gradients_quad[comp][0][q_point];
4789  for (unsigned int e = 1; e < dim; ++e)
4790  grad_out[comp][d] +=
4791  jac[d][e] * this->gradients_quad[comp][e][q_point];
4792  }
4793  }
4794  return grad_out;
4795 }
4796 
4797 
4798 
4799 template <int dim,
4800  int n_components_,
4801  typename Number,
4802  bool is_face,
4803  typename VectorizedArrayType>
4806  get_normal_derivative(const unsigned int q_point) const
4807 {
4808  AssertIndexRange(q_point, this->n_quadrature_points);
4809 # ifdef DEBUG
4810  Assert(this->gradients_quad_initialized == true,
4812 # endif
4813 
4814  Assert(normal_x_jacobian != nullptr, ExcNotInitialized());
4815 
4817  if (this->cell_type == internal::MatrixFreeFunctions::cartesian)
4818  for (unsigned int comp = 0; comp < n_components; comp++)
4819  grad_out[comp] = this->gradients_quad[comp][dim - 1][q_point] *
4820  (this->normal_x_jacobian[0][dim - 1]);
4821  else
4822  {
4823  const unsigned int index =
4824  this->cell_type <= internal::MatrixFreeFunctions::affine ? 0 : q_point;
4825  for (unsigned int comp = 0; comp < n_components; comp++)
4826  {
4827  grad_out[comp] = this->gradients_quad[comp][0][q_point] *
4828  this->normal_x_jacobian[index][0];
4829  for (unsigned int d = 1; d < dim; ++d)
4830  grad_out[comp] += this->gradients_quad[comp][d][q_point] *
4831  this->normal_x_jacobian[index][d];
4832  }
4833  }
4834  return grad_out;
4835 }
4836 
4837 
4838 
4839 namespace internal
4840 {
4841  // compute tmp = hess_unit(u) * J^T. do this manually because we do not
4842  // store the lower diagonal because of symmetry
4843  template <typename VectorizedArrayType>
4844  inline void
4845  hessian_unit_times_jac(const Tensor<2, 1, VectorizedArrayType> &jac,
4846  const VectorizedArrayType *const hessians_quad[1],
4847  const unsigned int q_point,
4848  VectorizedArrayType (&tmp)[1][1])
4849  {
4850  tmp[0][0] = jac[0][0] * hessians_quad[0][q_point];
4851  }
4852 
4853  template <typename VectorizedArrayType>
4854  inline void
4855  hessian_unit_times_jac(const Tensor<2, 2, VectorizedArrayType> &jac,
4856  const VectorizedArrayType *const hessians_quad[3],
4857  const unsigned int q_point,
4858  VectorizedArrayType (&tmp)[2][2])
4859  {
4860  for (unsigned int d = 0; d < 2; ++d)
4861  {
4862  tmp[0][d] = (jac[d][0] * hessians_quad[0][q_point] +
4863  jac[d][1] * hessians_quad[2][q_point]);
4864  tmp[1][d] = (jac[d][0] * hessians_quad[2][q_point] +
4865  jac[d][1] * hessians_quad[1][q_point]);
4866  }
4867  }
4868 
4869  template <typename VectorizedArrayType>
4870  inline void
4871  hessian_unit_times_jac(const Tensor<2, 3, VectorizedArrayType> &jac,
4872  const VectorizedArrayType *const hessians_quad[6],
4873  const unsigned int q_point,
4874  VectorizedArrayType (&tmp)[3][3])
4875  {
4876  for (unsigned int d = 0; d < 3; ++d)
4877  {
4878  tmp[0][d] = (jac[d][0] * hessians_quad[0][q_point] +
4879  jac[d][1] * hessians_quad[3][q_point] +
4880  jac[d][2] * hessians_quad[4][q_point]);
4881  tmp[1][d] = (jac[d][0] * hessians_quad[3][q_point] +
4882  jac[d][1] * hessians_quad[1][q_point] +
4883  jac[d][2] * hessians_quad[5][q_point]);
4884  tmp[2][d] = (jac[d][0] * hessians_quad[4][q_point] +
4885  jac[d][1] * hessians_quad[5][q_point] +
4886  jac[d][2] * hessians_quad[2][q_point]);
4887  }
4888  }
4889 } // namespace internal
4890 
4891 
4892 
4893 template <int dim,
4894  int n_components_,
4895  typename Number,
4896  bool is_face,
4897  typename VectorizedArrayType>
4900  get_hessian(const unsigned int q_point) const
4901 {
4902  Assert(!is_face, ExcNotImplemented());
4903 # ifdef DEBUG
4904  Assert(this->hessians_quad_initialized == true,
4906 # endif
4907  AssertIndexRange(q_point, this->n_quadrature_points);
4908 
4909  Assert(jacobian != nullptr, ExcNotImplemented());
4911  jacobian[this->cell_type <= internal::MatrixFreeFunctions::affine ?
4912  0 :
4913  q_point];
4914 
4916 
4917  // Cartesian cell
4918  if (this->cell_type == internal::MatrixFreeFunctions::cartesian)
4919  {
4920  for (unsigned int comp = 0; comp < n_components; comp++)
4921  for (unsigned int d = 0; d < dim; ++d)
4922  {
4923  hessian_out[comp][d][d] =
4924  (this->hessians_quad[comp][d][q_point] * jac[d][d] * jac[d][d]);
4925  switch (dim)
4926  {
4927  case 1:
4928  break;
4929  case 2:
4930  hessian_out[comp][0][1] =
4931  (this->hessians_quad[comp][2][q_point] * jac[0][0] *
4932  jac[1][1]);
4933  break;
4934  case 3:
4935  hessian_out[comp][0][1] =
4936  (this->hessians_quad[comp][3][q_point] * jac[0][0] *
4937  jac[1][1]);
4938  hessian_out[comp][0][2] =
4939  (this->hessians_quad[comp][4][q_point] * jac[0][0] *
4940  jac[2][2]);
4941  hessian_out[comp][1][2] =
4942  (this->hessians_quad[comp][5][q_point] * jac[1][1] *
4943  jac[2][2]);
4944  break;
4945  default:
4946  Assert(false, ExcNotImplemented());
4947  }
4948  for (unsigned int e = d + 1; e < dim; ++e)
4949  hessian_out[comp][e][d] = hessian_out[comp][d][e];
4950  }
4951  }
4952  // cell with general Jacobian, but constant within the cell
4953  else if (this->cell_type == internal::MatrixFreeFunctions::affine)
4954  {
4955  for (unsigned int comp = 0; comp < n_components; comp++)
4956  {
4957  // compute laplacian before the gradient because it needs to access
4958  // unscaled gradient data
4959  VectorizedArrayType tmp[dim][dim];
4960  internal::hessian_unit_times_jac(jac,
4961  this->hessians_quad[comp],
4962  q_point,
4963  tmp);
4964 
4965  // compute first part of hessian, J * tmp = J * hess_unit(u) * J^T
4966  for (unsigned int d = 0; d < dim; ++d)
4967  for (unsigned int e = d; e < dim; ++e)
4968  {
4969  hessian_out[comp][d][e] = jac[d][0] * tmp[0][e];
4970  for (unsigned int f = 1; f < dim; ++f)
4971  hessian_out[comp][d][e] += jac[d][f] * tmp[f][e];
4972  }
4973 
4974  // no J' * grad(u) part here because the Jacobian is constant
4975  // throughout the cell and hence, its derivative is zero
4976 
4977  // take symmetric part
4978  for (unsigned int d = 0; d < dim; ++d)
4979  for (unsigned int e = d + 1; e < dim; ++e)
4980  hessian_out[comp][e][d] = hessian_out[comp][d][e];
4981  }
4982  }
4983  // cell with general Jacobian
4984  else
4985  {
4986  const Tensor<1, dim *(dim + 1) / 2, Tensor<1, dim, VectorizedArrayType>>
4987  &jac_grad =
4988  mapping_data->jacobian_gradients
4989  [1 - this->is_interior_face]
4990  [this->mapping_data->data_index_offsets[this->cell] + q_point];
4991  for (unsigned int comp = 0; comp < n_components; comp++)
4992  {
4993  // compute laplacian before the gradient because it needs to access
4994  // unscaled gradient data
4995  VectorizedArrayType tmp[dim][dim];
4996  internal::hessian_unit_times_jac(jac,
4997  this->hessians_quad[comp],
4998  q_point,
4999  tmp);
5000 
5001  // compute first part of hessian, J * tmp = J * hess_unit(u) * J^T
5002  for (unsigned int d = 0; d < dim; ++d)
5003  for (unsigned int e = d; e < dim; ++e)
5004  {
5005  hessian_out[comp][d][e] = jac[d][0] * tmp[0][e];
5006  for (unsigned int f = 1; f < dim; ++f)
5007  hessian_out[comp][d][e] += jac[d][f] * tmp[f][e];
5008  }
5009 
5010  // add diagonal part of J' * grad(u)
5011  for (unsigned int d = 0; d < dim; ++d)
5012  for (unsigned int e = 0; e < dim; ++e)
5013  hessian_out[comp][d][d] +=
5014  (jac_grad[d][e] * this->gradients_quad[comp][e][q_point]);
5015 
5016  // add off-diagonal part of J' * grad(u)
5017  for (unsigned int d = 0, count = dim; d < dim; ++d)
5018  for (unsigned int e = d + 1; e < dim; ++e, ++count)
5019  for (unsigned int f = 0; f < dim; ++f)
5020  hessian_out[comp][d][e] +=
5021  (jac_grad[count][f] * this->gradients_quad[comp][f][q_point]);
5022 
5023  // take symmetric part
5024  for (unsigned int d = 0; d < dim; ++d)
5025  for (unsigned int e = d + 1; e < dim; ++e)
5026  hessian_out[comp][e][d] = hessian_out[comp][d][e];
5027  }
5028  }
5030  hessian_out);
5031 }
5032 
5033 
5034 
5035 template <int dim,
5036  int n_components_,
5037  typename Number,
5038  bool is_face,
5039  typename VectorizedArrayType>
5042  get_hessian_diagonal(const unsigned int q_point) const
5043 {
5044  Assert(!is_face, ExcNotImplemented());
5045 # ifdef DEBUG
5046  Assert(this->hessians_quad_initialized == true,
5048 # endif
5049  AssertIndexRange(q_point, this->n_quadrature_points);
5050 
5051  Assert(jacobian != nullptr, ExcNotImplemented());
5053  jacobian[this->cell_type <= internal::MatrixFreeFunctions::affine ?
5054  0 :
5055  q_point];
5056 
5058 
5059  // Cartesian cell
5060  if (this->cell_type == internal::MatrixFreeFunctions::cartesian)
5061  {
5062  for (unsigned int comp = 0; comp < n_components; comp++)
5063  for (unsigned int d = 0; d < dim; ++d)
5064  hessian_out[comp][d] =
5065  (this->hessians_quad[comp][d][q_point] * jac[d][d] * jac[d][d]);
5066  }
5067  // cell with general Jacobian, but constant within the cell
5068  else if (this->cell_type == internal::MatrixFreeFunctions::affine)
5069  {
5070  for (unsigned int comp = 0; comp < n_components; comp++)
5071  {
5072  // compute laplacian before the gradient because it needs to access
5073  // unscaled gradient data
5074  VectorizedArrayType tmp[dim][dim];
5075  internal::hessian_unit_times_jac(jac,
5076  this->hessians_quad[comp],
5077  q_point,
5078  tmp);
5079 
5080  // compute only the trace part of hessian, J * tmp = J *
5081  // hess_unit(u) * J^T
5082  for (unsigned int d = 0; d < dim; ++d)
5083  {
5084  hessian_out[comp][d] = jac[d][0] * tmp[0][d];
5085  for (unsigned int f = 1; f < dim; ++f)
5086  hessian_out[comp][d] += jac[d][f] * tmp[f][d];
5087  }
5088  }
5089  }
5090  // cell with general Jacobian
5091  else
5092  {
5093  const Tensor<1, dim *(dim + 1) / 2, Tensor<1, dim, VectorizedArrayType>>
5094  &jac_grad =
5095  mapping_data->jacobian_gradients
5096  [0][this->mapping_data->data_index_offsets[this->cell] + q_point];
5097  for (unsigned int comp = 0; comp < n_components; comp++)
5098  {
5099  // compute laplacian before the gradient because it needs to access
5100  // unscaled gradient data
5101  VectorizedArrayType tmp[dim][dim];
5102  internal::hessian_unit_times_jac(jac,
5103  this->hessians_quad[comp],
5104  q_point,
5105  tmp);
5106 
5107  // compute only the trace part of hessian, J * tmp = J *
5108  // hess_unit(u) * J^T
5109  for (unsigned int d = 0; d < dim; ++d)
5110  {
5111  hessian_out[comp][d] = jac[d][0] * tmp[0][d];
5112  for (unsigned int f = 1; f < dim; ++f)
5113  hessian_out[comp][d] += jac[d][f] * tmp[f][d];
5114  }
5115 
5116  for (unsigned int d = 0; d < dim; ++d)
5117  for (unsigned int e = 0; e < dim; ++e)
5118  hessian_out[comp][d] +=
5119  (jac_grad[d][e] * this->gradients_quad[comp][e][q_point]);
5120  }
5121  }
5122  return hessian_out;
5123 }
5124 
5125 
5126 
5127 template <int dim,
5128  int n_components_,
5129  typename Number,
5130  bool is_face,
5131  typename VectorizedArrayType>
5134  get_laplacian(const unsigned int q_point) const
5135 {
5136  Assert(is_face == false, ExcNotImplemented());
5137 # ifdef DEBUG
5138  Assert(this->hessians_quad_initialized == true,
5140 # endif
5141  AssertIndexRange(q_point, this->n_quadrature_points);
5142 
5145  hess_diag = get_hessian_diagonal(q_point);
5146  for (unsigned int comp = 0; comp < n_components; ++comp)
5147  {
5148  laplacian_out[comp] = hess_diag[comp][0];
5149  for (unsigned int d = 1; d < dim; ++d)
5150  laplacian_out[comp] += hess_diag[comp][d];
5151  }
5152  return laplacian_out;
5153 }
5154 
5155 
5156 
5157 template <int dim,
5158  int n_components_,
5159  typename Number,
5160  bool is_face,
5161  typename VectorizedArrayType>
5162 inline DEAL_II_ALWAYS_INLINE void
5165  const unsigned int dof)
5166 {
5167 # ifdef DEBUG
5168  this->dof_values_initialized = true;
5169 # endif
5170  AssertIndexRange(dof, this->data->dofs_per_component_on_cell);
5171  for (unsigned int comp = 0; comp < n_components; comp++)
5172  this->values_dofs[comp][dof] = val_in[comp];
5173 }
5174 
5175 
5176 
5177 template <int dim,
5178  int n_components_,
5179  typename Number,
5180  bool is_face,
5181  typename VectorizedArrayType>
5182 inline DEAL_II_ALWAYS_INLINE void
5185  const unsigned int q_point)
5186 {
5188  AssertIndexRange(q_point, this->n_quadrature_points);
5189  Assert(this->J_value != nullptr, ExcNotInitialized());
5190 # ifdef DEBUG
5191  this->values_quad_submitted = true;
5192 # endif
5193 
5194  if (this->cell_type <= internal::MatrixFreeFunctions::affine)
5195  {
5196  const VectorizedArrayType JxW = J_value[0] * quadrature_weights[q_point];
5197  for (unsigned int comp = 0; comp < n_components; ++comp)
5198  this->values_quad[comp][q_point] = val_in[comp] * JxW;
5199  }
5200  else
5201  {
5202  const VectorizedArrayType JxW = J_value[q_point];
5203  for (unsigned int comp = 0; comp < n_components; ++comp)
5204  this->values_quad[comp][q_point] = val_in[comp] * JxW;
5205  }
5206 }
5207 
5208 
5209 
5210 template <int dim,
5211  int n_components_,
5212  typename Number,
5213  bool is_face,
5214  typename VectorizedArrayType>
5215 inline DEAL_II_ALWAYS_INLINE void
5218  const Tensor<1, n_components_, Tensor<1, dim, VectorizedArrayType>> grad_in,
5219  const unsigned int q_point)
5220 {
5222  AssertIndexRange(q_point, this->n_quadrature_points);
5223  Assert(this->J_value != nullptr, ExcNotInitialized());
5224  Assert(this->jacobian != nullptr, ExcNotInitialized());
5225 # ifdef DEBUG
5226  this->gradients_quad_submitted = true;
5227 # endif
5228 
5229  if (!is_face && this->cell_type == internal::MatrixFreeFunctions::cartesian)
5230  {
5231  const VectorizedArrayType JxW = J_value[0] * quadrature_weights[q_point];
5232  for (unsigned int comp = 0; comp < n_components; comp++)
5233  for (unsigned int d = 0; d < dim; ++d)
5234  this->gradients_quad[comp][d][q_point] =
5235  (grad_in[comp][d] * jacobian[0][d][d] * JxW);
5236  }
5237  else
5238  {
5240  this->cell_type > internal::MatrixFreeFunctions::affine ?
5241  jacobian[q_point] :
5242  jacobian[0];
5243  const VectorizedArrayType JxW =
5244  this->cell_type > internal::MatrixFreeFunctions::affine ?
5245  J_value[q_point] :
5246  J_value[0] * quadrature_weights[q_point];
5247  for (unsigned int comp = 0; comp < n_components; ++comp)
5248  for (unsigned int d = 0; d < dim; ++d)
5249  {
5250  VectorizedArrayType new_val = jac[0][d] * grad_in[comp][0];
5251  for (unsigned int e = 1; e < dim; ++e)
5252  new_val += (jac[e][d] * grad_in[comp][e]);
5253  this->gradients_quad[comp][d][q_point] = new_val * JxW;
5254  }
5255  }
5256 }
5257 
5258 
5259 
5260 template <int dim,
5261  int n_components_,
5262  typename Number,
5263  bool is_face,
5264  typename VectorizedArrayType>
5265 inline DEAL_II_ALWAYS_INLINE void
5269  const unsigned int q_point)
5270 {
5271  AssertIndexRange(q_point, this->n_quadrature_points);
5272  Assert(this->normal_x_jacobian != nullptr, ExcNotInitialized());
5273 # ifdef DEBUG
5274  this->gradients_quad_submitted = true;
5275 # endif
5276 
5277  if (this->cell_type == internal::MatrixFreeFunctions::cartesian)
5278  for (unsigned int comp = 0; comp < n_components; comp++)
5279  {
5280  for (unsigned int d = 0; d < dim - 1; ++d)
5281  this->gradients_quad[comp][d][q_point] = VectorizedArrayType();
5282  this->gradients_quad[comp][dim - 1][q_point] =
5283  grad_in[comp] *
5284  (this->normal_x_jacobian[0][dim - 1] * this->J_value[0] *
5285  this->quadrature_weights[q_point]);
5286  }
5287  else
5288  {
5289  const unsigned int index =
5290  this->cell_type <= internal::MatrixFreeFunctions::affine ? 0 : q_point;
5291  for (unsigned int comp = 0; comp < n_components; comp++)
5292  {
5293  VectorizedArrayType factor = grad_in[comp] * this->J_value[index];
5294  if (this->cell_type <= internal::MatrixFreeFunctions::affine)
5295  factor = factor * this->quadrature_weights[q_point];
5296  for (unsigned int d = 0; d < dim; ++d)
5297  this->gradients_quad[comp][d][q_point] =
5298  factor * this->normal_x_jacobian[index][d];
5299  }
5300  }
5301 }
5302 
5303 
5304 
5305 template <int dim,
5306  int n_components_,
5307  typename Number,
5308  bool is_face,
5309  typename VectorizedArrayType>
5312  integrate_value() const
5313 {
5315 # ifdef DEBUG
5316  Assert(this->values_quad_submitted == true,
5318 # endif
5320  for (unsigned int comp = 0; comp < n_components; ++comp)
5321  return_value[comp] = this->values_quad[comp][0];
5322  const unsigned int n_q_points = this->n_quadrature_points;
5323  for (unsigned int q = 1; q < n_q_points; ++q)
5324  for (unsigned int comp = 0; comp < n_components; ++comp)
5325  return_value[comp] += this->values_quad[comp][q];
5326  return (return_value);
5327 }
5328 
5329 
5330 
5331 /*----------------------- FEEvaluationAccess --------------------------------*/
5332 
5333 
5334 template <int dim,
5335  int n_components_,
5336  typename Number,
5337  bool is_face,
5338  typename VectorizedArrayType>
5339 inline FEEvaluationAccess<dim,
5340  n_components_,
5341  Number,
5342  is_face,
5343  VectorizedArrayType>::
5344  FEEvaluationAccess(
5346  const unsigned int dof_no,
5347  const unsigned int first_selected_component,
5348  const unsigned int quad_no_in,
5349  const unsigned int fe_degree,
5350  const unsigned int n_q_points,
5351  const bool is_interior_face)
5352  : FEEvaluationBase<dim, n_components_, Number, is_face, VectorizedArrayType>(
5353  data_in,
5354  dof_no,
5355  first_selected_component,
5356  quad_no_in,
5357  fe_degree,
5358  n_q_points,
5359  is_interior_face)
5360 {}
5361 
5362 
5363 
5364 template <int dim,
5365  int n_components_,
5366  typename Number,
5367  bool is_face,
5368  typename VectorizedArrayType>
5369 template <int n_components_other>
5370 inline FEEvaluationAccess<dim,
5371  n_components_,
5372  Number,
5373  is_face,
5374  VectorizedArrayType>::
5375  FEEvaluationAccess(const Mapping<dim> & mapping,
5376  const FiniteElement<dim> &fe,
5377  const Quadrature<1> & quadrature,
5378  const UpdateFlags update_flags,
5379  const unsigned int first_selected_component,
5380  const FEEvaluationBase<dim,
5381  n_components_other,
5382  Number,
5383  is_face,
5384  VectorizedArrayType> *other)
5385  : FEEvaluationBase<dim, n_components_, Number, is_face, VectorizedArrayType>(
5386  mapping,
5387  fe,
5388  quadrature,
5389  update_flags,
5390  first_selected_component,
5391  other)
5392 {}
5393 
5394 
5395 
5396 template <int dim,
5397  int n_components_,
5398  typename Number,
5399  bool is_face,
5400  typename VectorizedArrayType>
5401 inline FEEvaluationAccess<dim,
5402  n_components_,
5403  Number,
5404  is_face,
5405  VectorizedArrayType>::
5406  FEEvaluationAccess(const FEEvaluationAccess<dim,
5407  n_components_,
5408  Number,
5409  is_face,
5410  VectorizedArrayType> &other)
5411  : FEEvaluationBase<dim, n_components_, Number, is_face, VectorizedArrayType>(
5412  other)
5413 {}
5414 
5415 
5416 
5417 template <int dim,
5418  int n_components_,
5419  typename Number,
5420  bool is_face,
5421  typename VectorizedArrayType>
5422 inline FEEvaluationAccess<dim,
5423  n_components_,
5424  Number,
5425  is_face,
5426  VectorizedArrayType> &
5428 operator=(const FEEvaluationAccess<dim,
5429  n_components_,
5430  Number,
5431  is_face,
5432  VectorizedArrayType> &other)
5433 {
5434  this->FEEvaluationBase<dim,
5435  n_components_,
5436  Number,
5437  is_face,
5438  VectorizedArrayType>::operator=(other);
5439  return *this;
5440 }
5441 
5442 
5443 
5444 /*-------------------- FEEvaluationAccess scalar ----------------------------*/
5445 
5446 
5447 template <int dim, typename Number, bool is_face, typename VectorizedArrayType>
5451  const unsigned int dof_no,
5452  const unsigned int first_selected_component,
5453  const unsigned int quad_no_in,
5454  const unsigned int fe_degree,
5455  const unsigned int n_q_points,
5456  const bool is_interior_face)
5457  : FEEvaluationBase<dim, 1, Number, is_face, VectorizedArrayType>(
5458  data_in,
5459  dof_no,
5460  first_selected_component,
5461  quad_no_in,
5462  fe_degree,
5463  n_q_points,
5464  is_interior_face)
5465 {}
5466 
5467 
5468 
5469 template <int dim, typename Number, bool is_face, typename VectorizedArrayType>
5470 template <int n_components_other>
5472  FEEvaluationAccess(const Mapping<dim> & mapping,
5473  const FiniteElement<dim> &fe,
5474  const Quadrature<1> & quadrature,
5475  const UpdateFlags update_flags,
5476  const unsigned int first_selected_component,
5477  const FEEvaluationBase<dim,
5478  n_components_other,
5479  Number,
5480  is_face,
5481  VectorizedArrayType> *other)
5482  : FEEvaluationBase<dim, 1, Number, is_face, VectorizedArrayType>(
5483  mapping,
5484  fe,
5485  quadrature,
5486  update_flags,
5487  first_selected_component,
5488  other)
5489 {}
5490 
5491 
5492 
5493 template <int dim, typename Number, bool is_face, typename VectorizedArrayType>
5497  &other)
5498  : FEEvaluationBase<dim, 1, Number, is_face, VectorizedArrayType>(other)
5499 {}
5500 
5501 
5502 
5503 template <int dim, typename Number, bool is_face, typename VectorizedArrayType>
5507 {
5509  operator=(other);
5510  return *this;
5511 }
5512 
5513 
5514 
5515 template <int dim, typename Number, bool is_face, typename VectorizedArrayType>
5516 inline DEAL_II_ALWAYS_INLINE VectorizedArrayType
5518  const unsigned int dof) const
5519 {
5520  AssertIndexRange(dof, this->data->dofs_per_component_on_cell);
5521  return this->values_dofs[0][dof];
5522 }
5523 
5524 
5525 
5526 template <int dim, typename Number, bool is_face, typename VectorizedArrayType>
5527 inline DEAL_II_ALWAYS_INLINE VectorizedArrayType
5529  const unsigned int q_point) const
5530 {
5531 # ifdef DEBUG
5532  Assert(this->values_quad_initialized == true,
5534 # endif
5535  AssertIndexRange(q_point, this->n_quadrature_points);
5536  return this->values_quad[0][q_point];
5537 }
5538 
5539 
5540 
5541 template <int dim, typename Number, bool is_face, typename VectorizedArrayType>
5542 inline DEAL_II_ALWAYS_INLINE VectorizedArrayType
5544  get_normal_derivative(const unsigned int q_point) const
5545 {
5546  return BaseClass::get_normal_derivative(q_point)[0];
5547 }
5548 
5549 
5550 
5551 template <int dim, typename Number, bool is_face, typename VectorizedArrayType>
5554  const unsigned int q_point) const
5555 {
5556  // could use the base class gradient, but that involves too many expensive
5557  // initialization operations on tensors
5558 
5559 # ifdef DEBUG
5560  Assert(this->gradients_quad_initialized == true,
5562 # endif
5563  AssertIndexRange(q_point, this->n_quadrature_points);
5564 
5565  Assert(this->jacobian != nullptr, ExcNotInitialized());
5566 
5568 
5569  if (!is_face && this->cell_type == internal::MatrixFreeFunctions::cartesian)
5570  {
5571  for (unsigned int d = 0; d < dim; ++d)
5572  grad_out[d] =
5573  (this->gradients_quad[0][d][q_point] * this->jacobian[0][d][d]);
5574  }
5575  // cell with general/affine Jacobian
5576  else
5577  {
5579  this->jacobian[this->cell_type > internal::MatrixFreeFunctions::affine ?
5580  q_point :
5581  0];
5582  for (unsigned int d = 0; d < dim; ++d)
5583  {
5584  grad_out[d] = jac[d][0] * this->gradients_quad[0][0][q_point];
5585  for (unsigned int e = 1; e < dim; ++e)
5586  grad_out[d] += jac[d][e] * this->gradients_quad[0][e][q_point];
5587  }
5588  }
5589  return grad_out;
5590 }
5591 
5592 
5593 
5594 template <int dim, typename Number, bool is_face, typename VectorizedArrayType>
5597  const unsigned int q_point) const
5598 {
5599  return BaseClass::get_hessian(q_point)[0];
5600 }
5601 
5602 
5603 
5604 template <int dim, typename Number, bool is_face, typename VectorizedArrayType>
5607  get_hessian_diagonal(const unsigned int q_point) const
5608 {
5609  return BaseClass::get_hessian_diagonal(q_point)[0];
5610 }
5611 
5612 
5613 
5614 template <int dim, typename Number, bool is_face, typename VectorizedArrayType>
5615 inline VectorizedArrayType
5617  const unsigned int q_point) const
5618 {
5619  return BaseClass::get_laplacian(q_point)[0];
5620 }
5621 
5622 
5623 
5624 template <int dim, typename Number, bool is_face, typename VectorizedArrayType>
5625 inline void DEAL_II_ALWAYS_INLINE
5627  submit_dof_value(const VectorizedArrayType val_in, const unsigned int dof)
5628 {
5629 # ifdef DEBUG
5630  this->dof_values_initialized = true;
5631  AssertIndexRange(dof, this->data->dofs_per_component_on_cell);
5632 # endif
5633  this->values_dofs[0][dof] = val_in;
5634 }
5635 
5636 
5637 
5638 template <int dim, typename Number, bool is_face, typename VectorizedArrayType>
5639 inline void DEAL_II_ALWAYS_INLINE
5641  const VectorizedArrayType val_in,
5642  const unsigned int q_index)
5643 {
5645  AssertIndexRange(q_index, this->n_quadrature_points);
5646  Assert(this->J_value != nullptr, ExcNotInitialized());
5647 # ifdef DEBUG
5648  this->values_quad_submitted = true;
5649 # endif
5650 
5651  if (this->cell_type <= internal::MatrixFreeFunctions::affine)
5652  {
5653  const VectorizedArrayType JxW =
5654  this->J_value[0] * this->quadrature_weights[q_index];
5655  this->values_quad[0][q_index] = val_in * JxW;
5656  }
5657  else // if (this->cell_type < internal::MatrixFreeFunctions::general)
5658  {
5659  this->values_quad[0][q_index] = val_in * this->J_value[q_index];
5660  }
5661 }
5662 
5663 
5664 
5665 template <int dim, typename Number, bool is_face, typename VectorizedArrayType>
5666 inline DEAL_II_ALWAYS_INLINE void
5668  const Tensor<1, 1, VectorizedArrayType> val_in,
5669  const unsigned int q_point)
5670 {
5671  submit_value(val_in[0], q_point);
5672 }
5673 
5674 
5675 
5676 template <int dim, typename Number, bool is_face, typename VectorizedArrayType>
5677 inline DEAL_II_ALWAYS_INLINE void
5679  submit_normal_derivative(const VectorizedArrayType grad_in,
5680  const unsigned int q_point)
5681 {
5683  grad[0] = grad_in;
5684  BaseClass::submit_normal_derivative(grad, q_point);
5685 }
5686 
5687 
5688 
5689 template <int dim, typename Number, bool is_face, typename VectorizedArrayType>
5690 inline DEAL_II_ALWAYS_INLINE void
5693  const unsigned int q_index)
5694 {
5696  AssertIndexRange(q_index, this->n_quadrature_points);
5697  Assert(this->J_value != nullptr, ExcNotInitialized());
5698  Assert(this->jacobian != nullptr, ExcNotInitialized());
5699 # ifdef DEBUG
5700  this->gradients_quad_submitted = true;
5701 # endif
5702 
5703  if (!is_face && this->cell_type == internal::MatrixFreeFunctions::cartesian)
5704  {
5705  const VectorizedArrayType JxW =
5706  this->J_value[0] * this->quadrature_weights[q_index];
5707  for (unsigned int d = 0; d < dim; ++d)
5708  this->gradients_quad[0][d][q_index] =
5709  (grad_in[d] * this->jacobian[0][d][d] * JxW);
5710  }
5711  // general/affine cell type
5712  else
5713  {
5715  this->cell_type > internal::MatrixFreeFunctions::affine ?
5716  this->jacobian[q_index] :
5717  this->jacobian[0];
5718  const VectorizedArrayType JxW =
5719  this->cell_type > internal::MatrixFreeFunctions::affine ?
5720  this->J_value[q_index] :
5721  this->J_value[0] * this->quadrature_weights[q_index];
5722  for (unsigned int d = 0; d < dim; ++d)
5723  {
5724  VectorizedArrayType new_val = jac[0][d] * grad_in[0];
5725  for (unsigned int e = 1; e < dim; ++e)
5726  new_val += jac[e][d] * grad_in[e];
5727  this->gradients_quad[0][d][q_index] = new_val * JxW;
5728  }
5729  }
5730 }
5731 
5732 
5733 
5734 template <int dim, typename Number, bool is_face, typename VectorizedArrayType>
5735 inline VectorizedArrayType
5737  integrate_value() const
5738 {
5739  return BaseClass::integrate_value()[0];
5740 }
5741 
5742 
5743 
5744 /*----------------- FEEvaluationAccess vector-valued ------------------------*/
5745 
5746 
5747 template <int dim, typename Number, bool is_face, typename VectorizedArrayType>
5751  const unsigned int dof_no,
5752  const unsigned int first_selected_component,
5753  const unsigned int quad_no_in,
5754  const unsigned int fe_degree,
5755  const unsigned int n_q_points,
5756  const bool is_interior_face)
5757  : FEEvaluationBase<dim, dim, Number, is_face, VectorizedArrayType>(
5758  data_in,
5759  dof_no,
5760  first_selected_component,
5761  quad_no_in,
5762  fe_degree,
5763  n_q_points,
5764  is_interior_face)
5765 {}
5766 
5767 
5768 
5769 template <int dim, typename Number, bool is_face, typename VectorizedArrayType>
5770 template <int n_components_other>
5772  FEEvaluationAccess(const Mapping<dim> & mapping,
5773  const FiniteElement<dim> &fe,
5774  const Quadrature<1> & quadrature,
5775  const UpdateFlags update_flags,
5776  const unsigned int first_selected_component,
5777  const FEEvaluationBase<dim,
5778  n_components_other,
5779  Number,
5780  is_face,
5781  VectorizedArrayType> *other)
5782  : FEEvaluationBase<dim, dim, Number, is_face, VectorizedArrayType>(
5783  mapping,
5784  fe,
5785  quadrature,
5786  update_flags,
5787  first_selected_component,
5788  other)
5789 {}
5790 
5791 
5792 
5793 template <int dim, typename Number, bool is_face, typename VectorizedArrayType>
5797  &other)
5798  : FEEvaluationBase<dim, dim, Number, is_face, VectorizedArrayType>(other)
5799 {}
5800 
5801 
5802 
5803 template <int dim, typename Number, bool is_face, typename VectorizedArrayType>
5807  &other)
5808 {
5810  operator=(other);
5811  return *this;
5812 }
5813 
5814 
5815 
5816 template <int dim, typename Number, bool is_face, typename VectorizedArrayType>
5819  get_gradient(const unsigned int q_point) const
5820 {
5821  return BaseClass::get_gradient(q_point);
5822 }
5823 
5824 
5825 
5826 template <int dim, typename Number, bool is_face, typename VectorizedArrayType>
5827 inline DEAL_II_ALWAYS_INLINE VectorizedArrayType
5829  get_divergence(const unsigned int q_point) const
5830 {
5831 # ifdef DEBUG
5832  Assert(this->gradients_quad_initialized == true,
5834 # endif
5835  AssertIndexRange(q_point, this->n_quadrature_points);
5836  Assert(this->jacobian != nullptr, ExcNotInitialized());
5837 
5838  VectorizedArrayType divergence;
5839 
5840  // Cartesian cell
5841  if (!is_face && this->cell_type == internal::MatrixFreeFunctions::cartesian)
5842  {
5843  divergence =
5844  (this->gradients_quad[0][0][q_point] * this->jacobian[0][0][0]);
5845  for (unsigned int d = 1; d < dim; ++d)
5846  divergence +=
5847  (this->gradients_quad[d][d][q_point] * this->jacobian[0][d][d]);
5848  }
5849  // cell with general/constant Jacobian
5850  else
5851  {
5853  this->cell_type == internal::MatrixFreeFunctions::general ?
5854  this->jacobian[q_point] :
5855  this->jacobian[0];
5856  divergence = (jac[0][0] * this->gradients_quad[0][0][q_point]);
5857  for (unsigned int e = 1; e < dim; ++e)
5858  divergence += (jac[0][e] * this->gradients_quad[0][e][q_point]);
5859  for (unsigned int d = 1; d < dim; ++d)
5860  for (unsigned int e = 0; e < dim; ++e)
5861  divergence += (jac[d][e] * this->gradients_quad[d][e][q_point]);
5862  }
5863  return divergence;
5864 }
5865 
5866 
5867 
5868 template <int dim, typename Number, bool is_face, typename VectorizedArrayType>
5871  get_symmetric_gradient(const unsigned int q_point) const
5872 {
5873  // copy from generic function into dim-specialization function
5874  const Tensor<2, dim, VectorizedArrayType> grad = get_gradient(q_point);
5875  VectorizedArrayType symmetrized[(dim * dim + dim) / 2];
5876  VectorizedArrayType half = make_vectorized_array<Number>(0.5);
5877  for (unsigned int d = 0; d < dim; ++d)
5878  symmetrized[d] = grad[d][d];
5879  switch (dim)
5880  {
5881  case 1:
5882  break;
5883  case 2:
5884  symmetrized[2] = grad[0][1] + grad[1][0];
5885  symmetrized[2] *= half;
5886  break;
5887  case 3:
5888  symmetrized[3] = grad[0][1] + grad[1][0];
5889  symmetrized[3] *= half;
5890  symmetrized[4] = grad[0][2] + grad[2][0];
5891  symmetrized[4] *= half;
5892  symmetrized[5] = grad[1][2] + grad[2][1];
5893  symmetrized[5] *= half;
5894  break;
5895  default:
5896  Assert(false, ExcNotImplemented());
5897  }
5899 }
5900 
5901 
5902 
5903 template <int dim, typename Number, bool is_face, typename VectorizedArrayType>
5904 inline DEAL_II_ALWAYS_INLINE
5905  Tensor<1, (dim == 2 ? 1 : dim), VectorizedArrayType>
5907  const unsigned int q_point) const
5908 {
5909  // copy from generic function into dim-specialization function
5910  const Tensor<2, dim, VectorizedArrayType> grad = get_gradient(q_point);
5911  Tensor<1, (dim == 2 ? 1 : dim), VectorizedArrayType> curl;
5912  switch (dim)
5913  {
5914  case 1:
5915  Assert(false,
5916  ExcMessage(
5917  "Computing the curl in 1d is not a useful operation"));
5918  break;
5919  case 2:
5920  curl[0] = grad[1][0] - grad[0][1];
5921  break;
5922  case 3:
5923  curl[0] = grad[2][1] - grad[1][2];
5924  curl[1] = grad[0][2] - grad[2][0];
5925  curl[2] = grad[1][0] - grad[0][1];
5926  break;
5927  default:
5928  Assert(false, ExcNotImplemented());
5929  }
5930  return curl;
5931 }
5932 
5933 
5934 
5935 template <int dim, typename Number, bool is_face, typename VectorizedArrayType>
5938  get_hessian_diagonal(const unsigned int q_point) const
5939 {
5940  return BaseClass::get_hessian_diagonal(q_point);
5941 }
5942 
5943 
5944 
5945 template <int dim, typename Number, bool is_face, typename VectorizedArrayType>
5948  const unsigned int q_point) const
5949 {
5950 # ifdef DEBUG
5951  Assert(this->hessians_quad_initialized == true,
5953 # endif
5954  AssertIndexRange(q_point, this->n_quadrature_points);
5955  return BaseClass::get_hessian(q_point);
5956 }
5957 
5958 
5959 
5960 template <int dim, typename Number, bool is_face, typename VectorizedArrayType>
5961 inline DEAL_II_ALWAYS_INLINE void
5964  const unsigned int q_point)
5965 {
5966  BaseClass::submit_gradient(grad_in, q_point);
5967 }
5968 
5969 
5970 
5971 template <int dim, typename Number, bool is_face, typename VectorizedArrayType>
5972 inline DEAL_II_ALWAYS_INLINE void
5975  const Tensor<1, dim, Tensor<1, dim, VectorizedArrayType>> grad_in,
5976  const unsigned int q_point)
5977 {
5978  BaseClass::submit_gradient(grad_in, q_point);
5979 }
5980 
5981 
5982 
5983 template <int dim, typename Number, bool is_face, typename VectorizedArrayType>
5984 inline DEAL_II_ALWAYS_INLINE void
5986  submit_divergence(const VectorizedArrayType div_in,
5987  const unsigned int q_point)
5988 {
5990  AssertIndexRange(q_point, this->n_quadrature_points);
5991  Assert(this->J_value != nullptr, ExcNotInitialized());
5992  Assert(this->jacobian != nullptr, ExcNotInitialized());
5993 # ifdef DEBUG
5994  this->gradients_quad_submitted = true;
5995 # endif
5996 
5997  if (!is_face && this->cell_type == internal::MatrixFreeFunctions::cartesian)
5998  {
5999  const VectorizedArrayType fac =
6000  this->J_value[0] * this->quadrature_weights[q_point] * div_in;
6001  for (unsigned int d = 0; d < dim; ++d)
6002  {
6003  this->gradients_quad[d][d][q_point] = (fac * this->jacobian[0][d][d]);
6004  for (unsigned int e = d + 1; e < dim; ++e)
6005  {
6006  this->gradients_quad[d][e][q_point] = VectorizedArrayType();
6007  this->gradients_quad[e][d][q_point] = VectorizedArrayType();
6008  }
6009  }
6010  }
6011  else
6012  {
6014  this->cell_type == internal::MatrixFreeFunctions::general ?
6015  this->jacobian[q_point] :
6016  this->jacobian[0];
6017  const VectorizedArrayType fac =
6018  (this->cell_type == internal::MatrixFreeFunctions::general ?
6019  this->J_value[q_point] :
6020  this->J_value[0] * this->quadrature_weights[q_point]) *
6021  div_in;
6022  for (unsigned int d = 0; d < dim; ++d)
6023  {
6024  for (unsigned int e = 0; e < dim; ++e)
6025  this->gradients_quad[d][e][q_point] = jac[d][e] * fac;
6026  }
6027  }
6028 }
6029 
6030 
6031 
6032 template <int dim, typename Number, bool is_face, typename VectorizedArrayType>
6033 inline DEAL_II_ALWAYS_INLINE void
6037  const unsigned int q_point)
6038 {
6039  // could have used base class operator, but that involves some overhead
6040  // which is inefficient. it is nice to have the symmetric tensor because
6041  // that saves some operations
6043  AssertIndexRange(q_point, this->n_quadrature_points);
6044  Assert(this->J_value != nullptr, ExcNotInitialized());
6045  Assert(this->jacobian != nullptr, ExcNotInitialized());
6046 # ifdef DEBUG
6047  this->gradients_quad_submitted = true;
6048 # endif
6049 
6050  if (!is_face && this->cell_type == internal::MatrixFreeFunctions::cartesian)
6051  {
6052  const VectorizedArrayType JxW =
6053  this->J_value[0] * this->quadrature_weights[q_point];
6054  for (unsigned int d = 0; d < dim; ++d)
6055  this->gradients_quad[d][d][q_point] =
6056  (sym_grad.access_raw_entry(d) * JxW * this->jacobian[0][d][d]);
6057  for (unsigned int e = 0, counter = dim; e < dim; ++e)
6058  for (unsigned int d = e + 1; d < dim; ++d, ++counter)
6059  {
6060  const VectorizedArrayType value =
6061  sym_grad.access_raw_entry(counter) * JxW;
6062  this->gradients_quad[e][d][q_point] =
6063  (value * this->jacobian[0][d][d]);
6064  this->gradients_quad[d][e][q_point] =
6065  (value * this->jacobian[0][e][e]);
6066  }
6067  }
6068  // general/affine cell type
6069  else
6070  {
6071  const VectorizedArrayType JxW =
6072  this->cell_type == internal::MatrixFreeFunctions::general ?
6073  this->J_value[q_point] :
6074  this->J_value[0] * this->quadrature_weights[q_point];
6076  this->cell_type == internal::MatrixFreeFunctions::general ?
6077  this->jacobian[q_point] :
6078  this->jacobian[0];
6079  VectorizedArrayType weighted[dim][dim];
6080  for (unsigned int i = 0; i < dim; ++i)
6081  weighted[i][i] = sym_grad.access_raw_entry(i) * JxW;
6082  for (unsigned int i = 0, counter = dim; i < dim; ++i)
6083  for (unsigned int j = i + 1; j < dim; ++j, ++counter)
6084  {
6085  const VectorizedArrayType value =
6086  sym_grad.access_raw_entry(counter) * JxW;
6087  weighted[i][j] = value;
6088  weighted[j][i] = value;
6089  }
6090  for (unsigned int comp = 0; comp < dim; ++comp)
6091  for (unsigned int d = 0; d < dim; ++d)
6092  {
6093  VectorizedArrayType new_val = jac[0][d] * weighted[comp][0];
6094  for (unsigned int e = 1; e < dim; ++e)
6095  new_val += jac[e][d] * weighted[comp][e];
6096  this->gradients_quad[comp][d][q_point] = new_val;
6097  }
6098  }
6099 }
6100 
6101 
6102 
6103 template <int dim, typename Number, bool is_face, typename VectorizedArrayType>
6104 inline DEAL_II_ALWAYS_INLINE void
6107  const unsigned int q_point)
6108 {
6110  switch (dim)
6111  {
6112  case 1:
6113  Assert(false,
6114  ExcMessage(
6115  "Testing by the curl in 1d is not a useful operation"));
6116  break;
6117  case 2:
6118  grad[1][0] = curl[0];
6119  grad[0][1] = -curl[0];
6120  break;
6121  case 3:
6122  grad[2][1] = curl[0];
6123  grad[1][2] = -curl[0];
6124  grad[0][2] = curl[1];
6125  grad[2][0] = -curl[1];
6126  grad[1][0] = curl[2];
6127  grad[0][1] = -curl[2];
6128  break;
6129  default:
6130  Assert(false, ExcNotImplemented());
6131  }
6132  submit_gradient(grad, q_point);
6133 }
6134 
6135 
6136 /*-------------------- FEEvaluationAccess scalar for 1d ---------------------*/
6137 
6138 
6139 template <typename Number, bool is_face, typename VectorizedArrayType>
6142  const unsigned int dof_no,
6143  const unsigned int first_selected_component,
6144  const unsigned int quad_no_in,
6145  const unsigned int fe_degree,
6146  const unsigned int n_q_points,
6147  const bool is_interior_face)
6148  : FEEvaluationBase<1, 1, Number, is_face, VectorizedArrayType>(
6149  data_in,
6150  dof_no,
6151  first_selected_component,
6152  quad_no_in,
6153  fe_degree,
6154  n_q_points,
6155  is_interior_face)
6156 {}
6157 
6158 
6159 
6160 template <typename Number, bool is_face, typename VectorizedArrayType>
6161 template <int n_components_other>
6163  FEEvaluationAccess(const Mapping<1> & mapping,
6164  const FiniteElement<1> &fe,
6165  const Quadrature<1> & quadrature,
6166  const UpdateFlags update_flags,
6167  const unsigned int first_selected_component,
6168  const FEEvaluationBase<1,
6169  n_components_other,
6170  Number,
6171  is_face,
6172  VectorizedArrayType> *other)
6173  : FEEvaluationBase<1, 1, Number, is_face, VectorizedArrayType>(
6174  mapping,
6175  fe,
6176  quadrature,
6177  update_flags,
6178  first_selected_component,
6179  other)
6180 {}
6181 
6182 
6183 
6184 template <typename Number, bool is_face, typename VectorizedArrayType>
6188  : FEEvaluationBase<1, 1, Number, is_face, VectorizedArrayType>(other)
6189 {}
6190 
6191 
6192 
6193 template <typename Number, bool is_face, typename VectorizedArrayType>
6197 {
6199  other);
6200  return *this;
6201 }
6202 
6203 
6204 
6205 template <typename Number, bool is_face, typename VectorizedArrayType>
6206 inline DEAL_II_ALWAYS_INLINE VectorizedArrayType
6208  const unsigned int dof) const
6209 {
6210  AssertIndexRange(dof, this->data->dofs_per_component_on_cell);
6211  return this->values_dofs[0][dof];
6212 }
6213 
6214 
6215 
6216 template <typename Number, bool is_face, typename VectorizedArrayType>
6217 inline DEAL_II_ALWAYS_INLINE VectorizedArrayType
6219  const unsigned int q_point) const
6220 {
6221 # ifdef DEBUG
6222  Assert(this->values_quad_initialized == true,
6224 # endif
6225  AssertIndexRange(q_point, this->n_quadrature_points);
6226  return this->values_quad[0][q_point];
6227 }
6228 
6229 
6230 
6231 template <typename Number, bool is_face, typename VectorizedArrayType>
6234  const unsigned int q_point) const
6235 {
6236  // could use the base class gradient, but that involves too many inefficient
6237  // initialization operations on tensors
6238 
6239 # ifdef DEBUG
6240  Assert(this->gradients_quad_initialized == true,
6242 # endif
6243  AssertIndexRange(q_point, this->n_quadrature_points);
6244 
6246  this->cell_type == internal::MatrixFreeFunctions::general ?
6247  this->jacobian[q_point] :
6248  this->jacobian[0];
6249 
6251  grad_out[0] = jac[0][0] * this->gradients_quad[0][0][q_point];
6252 
6253  return grad_out;
6254 }
6255 
6256 
6257 
6258 template <typename Number, bool is_face, typename VectorizedArrayType>
6259 inline DEAL_II_ALWAYS_INLINE VectorizedArrayType
6261  get_normal_derivative(const unsigned int q_point) const
6262 {
6263  return BaseClass::get_normal_derivative(q_point)[0];
6264 }
6265 
6266 
6267 
6268 template <typename Number, bool is_face, typename VectorizedArrayType>
6271  const unsigned int q_point) const
6272 {
6273  return BaseClass::get_hessian(q_point)[0];
6274 }
6275 
6276 
6277 
6278 template <typename Number, bool is_face, typename VectorizedArrayType>
6281  get_hessian_diagonal(const unsigned int q_point) const
6282 {
6283  return BaseClass::get_hessian_diagonal(q_point)[0];
6284 }
6285 
6286 
6287 
6288 template <typename Number, bool is_face, typename VectorizedArrayType>
6289 inline DEAL_II_ALWAYS_INLINE VectorizedArrayType
6291  const unsigned int q_point) const
6292 {
6293  return BaseClass::get_laplacian(q_point)[0];
6294 }
6295 
6296 
6297 
6298 template <typename Number, bool is_face, typename VectorizedArrayType>
6301  submit_dof_value(const VectorizedArrayType val_in, const unsigned int dof)
6302 {
6303 # ifdef DEBUG
6304  this->dof_values_initialized = true;
6305  AssertIndexRange(dof, this->data->dofs_per_component_on_cell);
6306 # endif
6307  this->values_dofs[0][dof] = val_in;
6308 }
6309 
6310 
6311 
6312 template <typename Number, bool is_face, typename VectorizedArrayType>
6313 inline DEAL_II_ALWAYS_INLINE void
6315  const VectorizedArrayType val_in,
6316  const unsigned int q_point)
6317 {
6319  AssertIndexRange(q_point, this->n_quadrature_points);
6320 # ifdef DEBUG
6321  this->values_quad_submitted = true;
6322 # endif
6323 
6324  if (this->cell_type == internal::MatrixFreeFunctions::general)
6325  {
6326  const VectorizedArrayType JxW = this->J_value[q_point];
6327  this->values_quad[0][q_point] = val_in * JxW;
6328  }
6329  else // if (this->cell_type == internal::MatrixFreeFunctions::general)
6330  {
6331  const VectorizedArrayType JxW =
6332  this->J_value[0] * this->quadrature_weights[q_point];
6333  this->values_quad[0][q_point] = val_in * JxW;
6334  }
6335 }
6336 
6337 
6338 
6339 template <typename Number, bool is_face, typename VectorizedArrayType>
6340 inline DEAL_II_ALWAYS_INLINE void
6342  const Tensor<1, 1, VectorizedArrayType> val_in,
6343  const unsigned int q_point)
6344 {
6345  submit_value(val_in[0], q_point);
6346 }
6347 
6348 
6349 
6350 template <typename Number, bool is_face, typename VectorizedArrayType>
6351 inline DEAL_II_ALWAYS_INLINE void
6353  const Tensor<1, 1, VectorizedArrayType> grad_in,
6354  const unsigned int q_point)
6355 {
6356  submit_gradient(grad_in[0], q_point);
6357 }
6358 
6359 
6360 
6361 template <typename Number, bool is_face, typename VectorizedArrayType>
6362 inline DEAL_II_ALWAYS_INLINE void
6364  const VectorizedArrayType grad_in,
6365  const unsigned int q_point)
6366 {
6368  AssertIndexRange(q_point, this->n_quadrature_points);
6369 # ifdef DEBUG
6370  this->gradients_quad_submitted = true;
6371 # endif
6372 
6374  this->cell_type == internal::MatrixFreeFunctions::general ?
6375  this->jacobian[q_point] :
6376  this->jacobian[0];
6377  const VectorizedArrayType JxW =
6378  this->cell_type == internal::MatrixFreeFunctions::general ?
6379  this->J_value[q_point] :
6380  this->J_value[0] * this->quadrature_weights[q_point];
6381 
6382  this->gradients_quad[0][0][q_point] = jac[0][0] * grad_in * JxW;
6383 }
6384 
6385 
6386 
6387 template <typename Number, bool is_face, typename VectorizedArrayType>
6388 inline DEAL_II_ALWAYS_INLINE void
6390  submit_normal_derivative(const VectorizedArrayType grad_in,
6391  const unsigned int q_point)
6392 {
6394  grad[0] = grad_in;
6395  BaseClass::submit_normal_derivative(grad, q_point);
6396 }
6397 
6398 
6399 
6400 template <typename Number, bool is_face, typename VectorizedArrayType>
6401 inline DEAL_II_ALWAYS_INLINE void
6404  const unsigned int q_point)
6405 {
6406  BaseClass::submit_normal_derivative(grad_in, q_point);
6407 }
6408 
6409 
6410 
6411 template <typename Number, bool is_face, typename VectorizedArrayType>
6412 inline VectorizedArrayType
6414  integrate_value() const
6415 {
6416  return BaseClass::integrate_value()[0];
6417 }
6418 
6419 
6420 
6421 /*-------------------------- FEEvaluation -----------------------------------*/
6422 
6423 
6424 template <int dim,
6425  int fe_degree,
6426  int n_q_points_1d,
6427  int n_components_,
6428  typename Number,
6429  typename VectorizedArrayType>
6430 inline FEEvaluation<dim,
6431  fe_degree,
6432  n_q_points_1d,
6433  n_components_,
6434  Number,
6435  VectorizedArrayType>::
6436  FEEvaluation(const MatrixFree<dim, Number, VectorizedArrayType> &data_in,
6437  const unsigned int fe_no,
6438  const unsigned int quad_no,
6439  const unsigned int first_selected_component)
6440  : BaseClass(data_in,
6441  fe_no,
6442  first_selected_component,
6443  quad_no,
6444  fe_degree,
6445  static_n_q_points)
6446  , dofs_per_component(this->data->dofs_per_component_on_cell)
6447  , dofs_per_cell(this->data->dofs_per_component_on_cell * n_components_)
6448  , n_q_points(this->data->n_q_points)
6449 {
6450  check_template_arguments(fe_no, 0);
6451 }
6452 
6453 
6454 
6455 template <int dim,
6456  int fe_degree,
6457  int n_q_points_1d,
6458  int n_components_,
6459  typename Number,
6460  typename VectorizedArrayType>
6461 inline FEEvaluation<dim,
6462  fe_degree,
6463  n_q_points_1d,
6464  n_components_,
6465  Number,
6466  VectorizedArrayType>::
6467  FEEvaluation(const Mapping<dim> & mapping,
6468  const FiniteElement<dim> &fe,
6469  const Quadrature<1> & quadrature,
6470  const UpdateFlags update_flags,
6471  const unsigned int first_selected_component)
6472  : BaseClass(mapping,
6473  fe,
6474  quadrature,
6475  update_flags,
6476  first_selected_component,
6477  static_cast<
6478  FEEvaluationBase<dim, 1, Number, false, VectorizedArrayType> *>(
6479  nullptr))
6480  , dofs_per_component(this->data->dofs_per_component_on_cell)
6481  , dofs_per_cell(this->data->dofs_per_component_on_cell * n_components_)
6482  , n_q_points(this->data->n_q_points)
6483 {
6484  check_template_arguments(numbers::invalid_unsigned_int, 0);
6485 }
6486 
6487 
6488 
6489 template <int dim,
6490  int fe_degree,
6491  int n_q_points_1d,
6492  int n_components_,
6493  typename Number,
6494  typename VectorizedArrayType>
6495 inline FEEvaluation<dim,
6496  fe_degree,
6497  n_q_points_1d,
6498  n_components_,
6499  Number,
6500  VectorizedArrayType>::
6501  FEEvaluation(const FiniteElement<dim> &fe,
6502  const Quadrature<1> & quadrature,
6503  const UpdateFlags update_flags,
6504  const unsigned int first_selected_component)
6505  : BaseClass(StaticMappingQ1<dim>::mapping,
6506  fe,
6507  quadrature,
6508  update_flags,
6509  first_selected_component,
6510  static_cast<
6511  FEEvaluationBase<dim, 1, Number, false, VectorizedArrayType> *>(
6512  nullptr))
6513  , dofs_per_component(this->data->dofs_per_component_on_cell)
6514  , dofs_per_cell(this->data->dofs_per_component_on_cell * n_components_)
6515  , n_q_points(this->data->n_q_points)
6516 {
6517  check_template_arguments(numbers::invalid_unsigned_int, 0);
6518 }
6519 
6520 
6521 
6522 template <int dim,
6523  int fe_degree,
6524  int n_q_points_1d,
6525  int n_components_,
6526  typename Number,
6527  typename VectorizedArrayType>
6528 template <int n_components_other>
6529 inline FEEvaluation<dim,
6530  fe_degree,
6531  n_q_points_1d,
6532  n_components_,
6533  Number,
6534  VectorizedArrayType>::
6535  FEEvaluation(const FiniteElement<dim> & fe,
6536  const FEEvaluationBase<dim,
6537  n_components_other,
6538  Number,
6539  false,
6540  VectorizedArrayType> &other,
6541  const unsigned int first_selected_component)
6542  : BaseClass(other.mapped_geometry->get_fe_values().get_mapping(),
6543  fe,
6544  other.mapped_geometry->get_quadrature(),
6545  other.mapped_geometry->get_fe_values().get_update_flags(),
6546  first_selected_component,
6547  &other)
6548  , dofs_per_component(this->data->dofs_per_component_on_cell)
6549  , dofs_per_cell(this->data->dofs_per_component_on_cell * n_components_)
6550  , n_q_points(this->data->n_q_points)
6551 {
6552  check_template_arguments(numbers::invalid_unsigned_int, 0);
6553 }
6554 
6555 
6556 
6557 template <int dim,
6558  int fe_degree,
6559  int n_q_points_1d,
6560  int n_components_,
6561  typename Number,
6562  typename VectorizedArrayType>
6563 inline FEEvaluation<dim,
6564  fe_degree,
6565  n_q_points_1d,
6566  n_components_,
6567  Number,
6568  VectorizedArrayType>::FEEvaluation(const FEEvaluation
6569  &other)
6570  : BaseClass(other)
6571  , dofs_per_component(this->data->dofs_per_component_on_cell)
6572  , dofs_per_cell(this->data->dofs_per_component_on_cell * n_components_)
6573  , n_q_points(this->data->n_q_points)
6574 {
6575  check_template_arguments(numbers::invalid_unsigned_int, 0);
6576 }
6577 
6578 
6579 
6580 template <int dim,
6581  int fe_degree,
6582  int n_q_points_1d,
6583  int n_components_,
6584  typename Number,
6585  typename VectorizedArrayType>
6586 inline FEEvaluation<dim,
6587  fe_degree,
6588  n_q_points_1d,
6589  n_components_,
6590  Number,
6591  VectorizedArrayType> &
6592 FEEvaluation<dim,
6593  fe_degree,
6594  n_q_points_1d,
6595  n_components_,
6596  Number,
6597  VectorizedArrayType>::operator=(const FEEvaluation &other)
6598 {
6599  BaseClass::operator=(other);
6600  check_template_arguments(numbers::invalid_unsigned_int, 0);
6601  return *this;
6602 }
6603 
6604 
6605 
6606 template <int dim,
6607  int fe_degree,
6608  int n_q_points_1d,
6609  int n_components_,
6610  typename Number,
6611  typename VectorizedArrayType>
6612 inline void
6613 FEEvaluation<dim,
6614  fe_degree,
6615  n_q_points_1d,
6616  n_components_,
6617  Number,
6618  VectorizedArrayType>::
6619  check_template_arguments(const unsigned int dof_no,
6620  const unsigned int first_selected_component)
6621 {
6622  (void)dof_no;
6623  (void)first_selected_component;
6624 
6625 # ifdef DEBUG
6626  // print error message when the dimensions do not match. Propose a possible
6627  // fix
6628  if ((static_cast<unsigned int>(fe_degree) != numbers::invalid_unsigned_int &&
6629  static_cast<unsigned int>(fe_degree) !=
6630  this->data->data.front().fe_degree) ||
6631  n_q_points != this->n_quadrature_points)
6632  {
6633  std::string message =
6634  "-------------------------------------------------------\n";
6635  message += "Illegal arguments in constructor/wrong template arguments!\n";
6636  message += " Called --> FEEvaluation<dim,";
6637  message += Utilities::int_to_string(fe_degree) + ",";
6638  message += Utilities::int_to_string(n_q_points_1d);
6639  message += "," + Utilities::int_to_string(n_components);
6640  message += ",Number>(data";
6641  if (first_selected_component != numbers::invalid_unsigned_int)
6642  {
6643  message += ", " + Utilities::int_to_string(dof_no) + ", ";
6644  message += Utilities::int_to_string(this->quad_no) + ", ";
6645  message += Utilities::int_to_string(first_selected_component);
6646  }
6647  message += ")\n";
6648 
6649  // check whether some other vector component has the correct number of
6650  // points
6651  unsigned int proposed_dof_comp = numbers::invalid_unsigned_int,
6652  proposed_fe_comp = numbers::invalid_unsigned_int,
6653  proposed_quad_comp = numbers::invalid_unsigned_int;
6654  if (dof_no != numbers::invalid_unsigned_int)
6655  {
6656  if (static_cast<unsigned int>(fe_degree) ==
6657  this->data->data.front().fe_degree)
6658  {
6659  proposed_dof_comp = dof_no;
6660  proposed_fe_comp = first_selected_component;
6661  }
6662  else
6663  for (unsigned int no = 0; no < this->matrix_info->n_components();
6664  ++no)
6665  for (unsigned int nf = 0;
6666  nf < this->matrix_info->n_base_elements(no);
6667  ++nf)
6668  if (this->matrix_info
6669  ->get_shape_info(no, 0, nf, this->active_fe_index, 0)
6670  .data.front()
6671  .fe_degree == static_cast<unsigned int>(fe_degree))
6672  {
6673  proposed_dof_comp = no;
6674  proposed_fe_comp = nf;
6675  break;
6676  }
6677  if (n_q_points ==
6678  this->mapping_data->descriptor[this->active_quad_index]
6679  .n_q_points)
6680  proposed_quad_comp = this->quad_no;
6681  else
6682  for (unsigned int no = 0;
6683  no < this->matrix_info->get_mapping_info().cell_data.size();
6684  ++no)
6685  if (this->matrix_info->get_mapping_info()
6686  .cell_data[no]
6687  .descriptor[this->active_quad_index]
6688  .n_q_points == n_q_points)
6689  {
6690  proposed_quad_comp = no;
6691  break;
6692  }
6693  }
6694  if (proposed_dof_comp != numbers::invalid_unsigned_int &&
6695  proposed_quad_comp != numbers::invalid_unsigned_int)
6696  {
6697  if (proposed_dof_comp != first_selected_component)
6698  message += "Wrong vector component selection:\n";
6699  else
6700  message += "Wrong quadrature formula selection:\n";
6701  message += " Did you mean FEEvaluation<dim,";
6702  message += Utilities::int_to_string(fe_degree) + ",";
6703  message += Utilities::int_to_string(n_q_points_1d);
6704  message += "," + Utilities::int_to_string(n_components);
6705  message += ",Number>(data";
6706  if (dof_no != numbers::invalid_unsigned_int)
6707  {
6708  message +=
6709  ", " + Utilities::int_to_string(proposed_dof_comp) + ", ";
6710  message += Utilities::int_to_string(proposed_quad_comp) + ", ";
6711  message += Utilities::int_to_string(proposed_fe_comp);
6712  }
6713  message += ")?\n";
6714  std::string correct_pos;
6715  if (proposed_dof_comp != dof_no)
6716  correct_pos = " ^ ";
6717  else
6718  correct_pos = " ";
6719  if (proposed_quad_comp != this->quad_no)
6720  correct_pos += " ^ ";
6721  else
6722  correct_pos += " ";
6723  if (proposed_fe_comp != first_selected_component)
6724  correct_pos += " ^\n";
6725  else
6726  correct_pos += " \n";
6727  message += " " +
6728  correct_pos;
6729  }
6730  // ok, did not find the numbers specified by the template arguments in
6731  // the given list. Suggest correct template arguments
6732  const unsigned int proposed_n_q_points_1d = static_cast<unsigned int>(
6733  std::pow(1.001 * this->n_quadrature_points, 1. / dim));
6734  message += "Wrong template arguments:\n";
6735  message += " Did you mean FEEvaluation<dim,";
6736  message +=
6737  Utilities::int_to_string(this->data->data.front().fe_degree) + ",";
6738  message += Utilities::int_to_string(proposed_n_q_points_1d);
6739  message += "," + Utilities::int_to_string(n_components);
6740  message += ",Number>(data";
6741  if (dof_no != numbers::invalid_unsigned_int)
6742  {
6743  message += ", " + Utilities::int_to_string(dof_no) + ", ";
6744  message += Utilities::int_to_string(this->quad_no);
6745  message += ", " + Utilities::int_to_string(first_selected_component);
6746  }
6747  message += ")?\n";
6748  std::string correct_pos;
6749  if (this->data->data.front().fe_degree !=
6750  static_cast<unsigned int>(fe_degree))
6751  correct_pos = " ^";
6752  else
6753  correct_pos = " ";
6754  if (proposed_n_q_points_1d != n_q_points_1d)
6755  correct_pos += " ^\n";
6756  else
6757  correct_pos += " \n";
6758  message += " " + correct_pos;
6759 
6760  Assert(static_cast<unsigned int>(fe_degree) ==
6761  this->data->data.front().fe_degree &&
6762  n_q_points == this->n_quadrature_points,
6763  ExcMessage(message));
6764  }
6765  if (dof_no != numbers::invalid_unsigned_int)
6767  n_q_points,
6768  this->mapping_data->descriptor[this->active_quad_index].n_q_points);
6769 # endif
6770 }
6771 
6772 
6773 
6774 template <int dim,
6775  int fe_degree,
6776  int n_q_points_1d,
6777  int n_components_,
6778  typename Number,
6779  typename VectorizedArrayType>
6780 inline void
6781 FEEvaluation<dim,
6782  fe_degree,
6783  n_q_points_1d,
6784  n_components_,
6785  Number,
6786  VectorizedArrayType>::reinit(const unsigned int cell_index)
6787 {
6788  Assert(this->mapped_geometry == nullptr,
6789  ExcMessage("FEEvaluation was initialized without a matrix-free object."
6790  " Integer indexing is not possible"));
6791  if (this->mapped_geometry != nullptr)
6792  return;
6793 
6794  Assert(this->dof_info != nullptr, ExcNotInitialized());
6795  Assert(this->mapping_data != nullptr, ExcNotInitialized());
6796  this->cell = cell_index;
6797  this->cell_type =
6798  this->matrix_info->get_mapping_info().get_cell_type(cell_index);
6799 
6800  const unsigned int offsets =
6801  this->mapping_data->data_index_offsets[cell_index];
6802  this->jacobian = &this->mapping_data->jacobians[0][offsets];
6803  this->J_value = &this->mapping_data->JxW_values[offsets];
6804 
6805 # ifdef DEBUG
6806  this->dof_values_initialized = false;
6807  this->values_quad_initialized = false;
6808  this->gradients_quad_initialized = false;
6809  this->hessians_quad_initialized = false;
6810 # endif
6811 }
6812 
6813 
6814 
6815 template <int dim,
6816  int fe_degree,
6817  int n_q_points_1d,
6818  int n_components_,
6819  typename Number,
6820  typename VectorizedArrayType>
6821 template <typename DoFHandlerType, bool level_dof_access>
6822 inline void
6823 FEEvaluation<dim,
6824  fe_degree,
6825  n_q_points_1d,
6826  n_components_,
6827  Number,
6828  VectorizedArrayType>::
6829  reinit(
6831 {
6832  Assert(this->matrix_info == nullptr,
6833  ExcMessage("Cannot use initialization from cell iterator if "
6834  "initialized from MatrixFree object. Use variant for "
6835  "on the fly computation with arguments as for FEValues "
6836  "instead"));
6837  Assert(this->mapped_geometry.get() != nullptr, ExcNotInitialized());
6838  this->mapped_geometry->reinit(
6839  static_cast<typename Triangulation<dim>::cell_iterator>(cell));
6840  this->local_dof_indices.resize(cell->get_fe().dofs_per_cell);
6841  if (level_dof_access)
6842  cell->get_mg_dof_indices(this->local_dof_indices);
6843  else
6844  cell->get_dof_indices(this->local_dof_indices);
6845 }
6846 
6847 
6848 
6849 template <int dim,
6850  int fe_degree,
6851  int n_q_points_1d,
6852  int n_components_,
6853  typename Number,
6854  typename VectorizedArrayType>
6855 inline void
6856 FEEvaluation<dim,
6857  fe_degree,
6858  n_q_points_1d,
6859  n_components_,
6860  Number,
6861  VectorizedArrayType>::
6862  reinit(const typename Triangulation<dim>::cell_iterator &cell)
6863 {
6864  Assert(this->matrix_info == 0,
6865  ExcMessage("Cannot use initialization from cell iterator if "
6866  "initialized from MatrixFree object. Use variant for "
6867  "on the fly computation with arguments as for FEValues "
6868  "instead"));
6869  Assert(this->mapped_geometry.get() != 0, ExcNotInitialized());
6870  this->mapped_geometry->reinit(cell);
6871 }
6872 
6873 
6874 
6875 template <int dim,
6876  int fe_degree,
6877  int n_q_points_1d,
6878  int n_components_,
6879  typename Number,
6880  typename VectorizedArrayType>
6882 FEEvaluation<dim,
6883  fe_degree,
6884  n_q_points_1d,
6885  n_components_,
6886  Number,
6887  VectorizedArrayType>::quadrature_point(const unsigned int q) const
6888 {
6889  if (this->matrix_info == nullptr)
6890  {
6891  Assert((this->mapped_geometry->get_fe_values().get_update_flags() |
6893  ExcNotInitialized());
6894  }
6895  else
6896  {
6897  Assert(this->mapping_data->quadrature_point_offsets.empty() == false,
6898  ExcNotInitialized());
6899  }
6900 
6901  AssertIndexRange(q, n_q_points);
6902 
6904  &this->mapping_data->quadrature_points
6905  [this->mapping_data->quadrature_point_offsets[this->cell]];
6906 
6907  // Cartesian/affine mesh: only first vertex of cell is stored, we must
6908  // compute it through the Jacobian (which is stored in non-inverted and
6909  // non-transposed form as index '1' in the jacobian field)
6910  if (this->cell_type <= internal::MatrixFreeFunctions::affine)
6911  {
6912  Assert(this->jacobian != nullptr, ExcNotInitialized());
6914 
6915  const Tensor<2, dim, VectorizedArrayType> &jac = this->jacobian[1];
6916  if (this->cell_type == internal::MatrixFreeFunctions::cartesian)
6917  for (unsigned int d = 0; d < dim; ++d)
6918  point[d] += jac[d][d] *
6919  static_cast<Number>(
6920  this->mapping_data->descriptor[this->active_quad_index]
6921  .quadrature.point(q)[d]);
6922  else
6923  for (unsigned int d = 0; d < dim; ++d)
6924  for (unsigned int e = 0; e < dim; ++e)
6925  point[d] += jac[d][e] * static_cast<Number>(
6926  this->mapping_data
6927  ->descriptor[this->active_quad_index]
6928  .quadrature.point(q)[e]);
6929  return point;
6930  }
6931  else
6932  return quadrature_points[q];
6933 }
6934 
6935 
6936 
6937 template <int dim,
6938  int fe_degree,
6939  int n_q_points_1d,
6940  int n_components_,
6941  typename Number,
6942  typename VectorizedArrayType>
6943 inline void
6944 FEEvaluation<dim,
6945  fe_degree,
6946  n_q_points_1d,
6947  n_components_,
6948  Number,
6949  VectorizedArrayType>::evaluate(const bool evaluate_values,
6950  const bool evaluate_gradients,
6951  const bool evaluate_hessians)
6952 {
6953 # ifdef DEBUG
6954  Assert(this->dof_values_initialized == true,
6956 # endif
6957  evaluate(this->values_dofs[0],
6958  evaluate_values,
6959  evaluate_gradients,
6960  evaluate_hessians);
6961 }
6962 
6963 
6964 
6965 template <int dim,
6966  int fe_degree,
6967  int n_q_points_1d,
6968  int n_components_,
6969  typename Number,
6970  typename VectorizedArrayType>
6971 inline void
6972 FEEvaluation<dim,
6973  fe_degree,
6974  n_q_points_1d,
6975  n_components_,
6976  Number,
6977  VectorizedArrayType>::evaluate(const VectorizedArrayType
6978  * values_array,
6979  const bool evaluate_values,
6980  const bool evaluate_gradients,
6981  const bool evaluate_hessians)
6982 {
6984  dim,
6985  fe_degree,
6986  n_q_points_1d,
6987  n_components,
6988  VectorizedArrayType>::evaluate(*this->data,
6989  const_cast<VectorizedArrayType *>(
6990  values_array),
6991  this->values_quad[0],
6992  this->gradients_quad[0][0],
6993  this->hessians_quad[0][0],
6994  this->scratch_data,
6995  evaluate_values,
6996  evaluate_gradients,
6997  evaluate_hessians);
6998 
6999 # ifdef DEBUG
7000  if (evaluate_values == true)
7001  this->values_quad_initialized = true;
7002  if (evaluate_gradients == true)
7003  this->gradients_quad_initialized = true;
7004  if (evaluate_hessians == true)
7005  this->hessians_quad_initialized = true;
7006 # endif
7007 }
7008 
7009 
7010 
7011 template <int dim,
7012  int fe_degree,
7013  int n_q_points_1d,
7014  int n_components_,
7015  typename Number,
7016  typename VectorizedArrayType>
7017 template <typename VectorType>
7018 inline void
7019 FEEvaluation<
7020  dim,
7021  fe_degree,
7022  n_q_points_1d,
7023  n_components_,
7024  Number,
7025  VectorizedArrayType>::gather_evaluate(const VectorType &input_vector,
7026  const bool evaluate_values,
7027  const bool evaluate_gradients,
7028  const bool evaluate_hessians)
7029 {
7030  // If the index storage is interleaved and contiguous and the vector storage
7031  // has the correct alignment, we can directly pass the pointer into the
7032  // vector to the evaluate() call, without reading the vector entries into a
7033  // separate data field. This saves some operations.
7035  this->dof_info->index_storage_variants
7037  [this->cell] == internal::MatrixFreeFunctions::DoFInfo::
7038  IndexStorageVariants::interleaved_contiguous &&
7039  reinterpret_cast<std::size_t>(
7040  input_vector.begin() +
7041  this->dof_info->dof_indices_contiguous
7043  [this->cell * VectorizedArrayType::size()]) %
7044  sizeof(VectorizedArrayType) ==
7045  0)
7046  {
7047  const VectorizedArrayType *vec_values =
7048  reinterpret_cast<const VectorizedArrayType *>(
7049  input_vector.begin() +
7050  this->dof_info->dof_indices_contiguous
7052  [this->cell * VectorizedArrayType::size()] +
7053  this->dof_info
7054  ->component_dof_indices_offset[this->active_fe_index]
7055  [this->first_selected_component] *
7056  VectorizedArrayType::size());
7057 
7058  evaluate(vec_values,
7059  evaluate_values,
7060  evaluate_gradients,
7061  evaluate_hessians);
7062  }
7063  else
7064  {
7065  this->read_dof_values(input_vector);
7066  evaluate(this->begin_dof_values(),
7067  evaluate_values,
7068  evaluate_gradients,
7069  evaluate_hessians);
7070  }
7071 }
7072 
7073 
7074 
7075 template <int dim,
7076  int fe_degree,
7077  int n_q_points_1d,
7078  int n_components_,
7079  typename Number,
7080  typename VectorizedArrayType>
7081 inline void
7082 FEEvaluation<dim,
7083  fe_degree,
7084  n_q_points_1d,
7085  n_components_,
7086  Number,
7087  VectorizedArrayType>::integrate(const bool integrate_values,
7088  const bool integrate_gradients)
7089 {
7090  integrate(integrate_values, integrate_gradients, this->values_dofs[0]);
7091 
7092 # ifdef DEBUG
7093  this->dof_values_initialized = true;
7094 # endif
7095 }
7096 
7097 
7098 
7099 template <int dim,
7100  int fe_degree,
7101  int n_q_points_1d,
7102  int n_components_,
7103  typename Number,
7104  typename VectorizedArrayType>
7105 inline void
7106 FEEvaluation<dim,
7107  fe_degree,
7108  n_q_points_1d,
7109  n_components_,
7110  Number,
7111  VectorizedArrayType>::integrate(const bool integrate_values,
7112  const bool integrate_gradients,
7113  VectorizedArrayType *values_array)
7114 {
7115 # ifdef DEBUG
7116  if (integrate_values == true)
7117  Assert(this->values_quad_submitted == true,
7119  if (integrate_gradients == true)
7120  Assert(this->gradients_quad_submitted == true,
7122 # endif
7123  Assert(this->matrix_info != nullptr ||
7124  this->mapped_geometry->is_initialized(),
7125  ExcNotInitialized());
7126 
7127  SelectEvaluator<dim,
7128  fe_degree,
7129  n_q_points_1d,
7130  n_components,
7131  VectorizedArrayType>::integrate(*this->data,
7132  values_array,
7133  this->values_quad[0],
7134  this->gradients_quad[0][0],
7135  this->scratch_data,
7136  integrate_values,
7137  integrate_gradients,
7138  false);
7139 
7140 # ifdef DEBUG
7141  this->dof_values_initialized = true;
7142 # endif
7143 }
7144 
7145 
7146 
7147 template <int dim,
7148  int fe_degree,
7149  int n_q_points_1d,
7150  int n_components_,
7151  typename Number,
7152  typename VectorizedArrayType>
7153 template <typename VectorType>
7154 inline void
7155 FEEvaluation<
7156  dim,
7157  fe_degree,
7158  n_q_points_1d,
7159  n_components_,
7160  Number,
7161  VectorizedArrayType>::integrate_scatter(const bool integrate_values,
7162  const bool integrate_gradients,
7163  VectorType &destination)
7164 {
7165  // If the index storage is interleaved and contiguous and the vector storage
7166  // has the correct alignment, we can directly pass the pointer into the
7167  // vector to the integrate() call, without writing temporary results into a
7168  // separate data field that will later be added into the vector. This saves
7169  // some operations.
7171  this->dof_info->index_storage_variants
7173  [this->cell] == internal::MatrixFreeFunctions::DoFInfo::
7174  IndexStorageVariants::interleaved_contiguous &&
7175  reinterpret_cast<std::size_t>(
7176  destination.begin() +
7177  this->dof_info->dof_indices_contiguous
7179  [this->cell * VectorizedArrayType::size()]) %
7180  sizeof(VectorizedArrayType) ==
7181  0)
7182  {
7183  VectorizedArrayType *vec_values = reinterpret_cast<VectorizedArrayType *>(
7184  destination.begin() +
7185  this->dof_info->dof_indices_contiguous
7187  [this->cell * VectorizedArrayType::size()] +
7188  this->dof_info
7189  ->component_dof_indices_offset[this->active_fe_index]
7190  [this->first_selected_component] *
7191  VectorizedArrayType::size());
7192  SelectEvaluator<dim,
7193  fe_degree,
7194  n_q_points_1d,
7195  n_components,
7196  VectorizedArrayType>::integrate(*this->data,
7197  vec_values,
7198  this->values_quad[0],
7199  this
7200  ->gradients_quad[0][0],
7201  this->scratch_data,
7202  integrate_values,
7203  integrate_gradients,
7204  true);
7205  }
7206  else
7207  {
7208  integrate(integrate_values,
7209  integrate_gradients,
7210  this->begin_dof_values());
7211  this->distribute_local_to_global(destination);
7212  }
7213 }
7214 
7215 
7216 
7217 /*-------------------------- FEFaceEvaluation ---------------------------*/
7218 
7219 
7220 
7221 template <int dim,
7222  int fe_degree,
7223  int n_q_points_1d,
7224  int n_components_,
7225  typename Number,
7226  typename VectorizedArrayType>
7227 inline FEFaceEvaluation<dim,
7228  fe_degree,
7229  n_q_points_1d,
7230  n_components_,
7231  Number,
7232  VectorizedArrayType>::
7233  FEFaceEvaluation(
7235  const bool is_interior_face,
7236  const unsigned int dof_no,
7237  const unsigned int quad_no,
7238  const unsigned int first_selected_component)
7239  : BaseClass(matrix_free,
7240  dof_no,
7241  first_selected_component,
7242  quad_no,
7243  fe_degree,
7244  static_n_q_points,
7245  is_interior_face)
7246  , dofs_per_component(this->data->dofs_per_component_on_cell)
7247  , dofs_per_cell(this->data->dofs_per_component_on_cell * n_components_)
7248  , n_q_points(this->data->n_q_points_face)
7249 {}
7250 
7251 
7252 
7253 template <int dim,
7254  int fe_degree,
7255  int n_q_points_1d,
7256  int n_components_,
7257  typename Number,
7258  typename VectorizedArrayType>
7259 inline void
7260 FEFaceEvaluation<dim,
7261  fe_degree,
7262  n_q_points_1d,
7263  n_components_,
7264  Number,
7265  VectorizedArrayType>::reinit(const unsigned int face_index)
7266 {
7267  Assert(this->mapped_geometry == nullptr,
7268  ExcMessage("FEEvaluation was initialized without a matrix-free object."
7269  " Integer indexing is not possible"));
7270  if (this->mapped_geometry != nullptr)
7271  return;
7272 
7273  this->cell = face_index;
7274  this->dof_access_index =
7275  this->is_interior_face ?
7278  Assert(this->mapping_data != nullptr, ExcNotInitialized());
7280  VectorizedArrayType::size()> &faces =
7281  this->matrix_info->get_face_info(face_index);
7282  if (face_index >=
7283  this->matrix_info->get_task_info().face_partition_data.back() &&
7284  face_index <
7285  this->matrix_info->get_task_info().boundary_partition_data.back())
7286  Assert(this->is_interior_face,
7287  ExcMessage("Boundary faces do not have a neighbor"));
7288 
7289  this->face_no =
7290  (this->is_interior_face ? faces.interior_face_no : faces.exterior_face_no);
7291  this->subface_index = faces.subface_index;
7292  if (this->is_interior_face == true)
7293  {
7294  this->subface_index = GeometryInfo<dim>::max_children_per_cell;
7295  if (faces.face_orientation > 8)
7296  this->face_orientation = faces.face_orientation - 8;
7297  else
7298  this->face_orientation = 0;
7299  }
7300  else
7301  {
7302  if (faces.face_orientation < 8)
7303  this->face_orientation = faces.face_orientation;
7304  else
7305  this->face_orientation = 0;
7306  }
7307 
7308  this->cell_type = this->matrix_info->get_mapping_info().face_type[face_index];
7309  const unsigned int offsets =
7310  this->mapping_data->data_index_offsets[face_index];
7311  this->J_value = &this->mapping_data->JxW_values[offsets];
7312  this->normal_vectors = &this->mapping_data->normal_vectors[offsets];
7313  this->jacobian =
7314  &this->mapping_data->jacobians[!this->is_interior_face][offsets];
7315  this->normal_x_jacobian =
7316  &this->mapping_data
7317  ->normals_times_jacobians[!this->is_interior_face][offsets];
7318 
7319 # ifdef DEBUG
7320  this->dof_values_initialized = false;
7321  this->values_quad_initialized = false;
7322  this->gradients_quad_initialized = false;
7323  this->hessians_quad_initialized = false;
7324 # endif
7325 }
7326 
7327 
7328 
7329 template <int dim,
7330  int fe_degree,
7331  int n_q_points_1d,
7332  int n_components_,
7333  typename Number,
7334  typename VectorizedArrayType>
7335 inline void
7336 FEFaceEvaluation<dim,
7337  fe_degree,
7338  n_q_points_1d,
7339  n_components_,
7340  Number,
7341  VectorizedArrayType>::reinit(const unsigned int cell_index,
7342  const unsigned int face_number)
7343 {
7344  Assert(
7345  this->quad_no <
7346  this->matrix_info->get_mapping_info().face_data_by_cells.size(),
7347  ExcMessage(
7348  "You must set MatrixFree::AdditionalData::mapping_update_flags_faces_by_cells to use the present reinit method."));
7350  AssertIndexRange(cell_index,
7351  this->matrix_info->get_mapping_info().cell_type.size());
7352  Assert(this->mapped_geometry == nullptr,
7353  ExcMessage("FEEvaluation was initialized without a matrix-free object."
7354  " Integer indexing is not possible"));
7355  if (this->mapped_geometry != nullptr)
7356  return;
7357  Assert(this->matrix_info != nullptr, ExcNotInitialized());
7358 
7359  this->cell_type = this->matrix_info->get_mapping_info().cell_type[cell_index];
7360  this->cell = cell_index;
7361  this->face_orientation = 0;
7362  this->subface_index = GeometryInfo<dim>::max_children_per_cell;
7363  this->face_no = face_number;
7364  this->dof_access_index =
7366 
7367  const unsigned int offsets =
7368  this->matrix_info->get_mapping_info()
7369  .face_data_by_cells[this->quad_no]
7370  .data_index_offsets[cell_index * GeometryInfo<dim>::faces_per_cell +
7371  face_number];
7372  AssertIndexRange(offsets,
7373  this->matrix_info->get_mapping_info()
7374  .face_data_by_cells[this->quad_no]
7375  .JxW_values.size());
7376  this->J_value = &this->matrix_info->get_mapping_info()
7377  .face_data_by_cells[this->quad_no]
7378  .JxW_values[offsets];
7379  this->normal_vectors = &this->matrix_info->get_mapping_info()
7380  .face_data_by_cells[this->quad_no]
7381  .normal_vectors[offsets];
7382  this->jacobian = &this->matrix_info->get_mapping_info()
7383  .face_data_by_cells[this->quad_no]
7384  .jacobians[!this->is_interior_face][offsets];
7385  this->normal_x_jacobian =
7386  &this->matrix_info->get_mapping_info()
7387  .face_data_by_cells[this->quad_no]
7388  .normals_times_jacobians[!this->is_interior_face][offsets];
7389 
7390 # ifdef DEBUG
7391  this->dof_values_initialized = false;
7392  this->values_quad_initialized = false;
7393  this->gradients_quad_initialized = false;
7394  this->hessians_quad_initialized = false;
7395 # endif
7396 }
7397 
7398 
7399 
7400 template <int dim,
7401  int fe_degree,
7402  int n_q_points_1d,
7403  int n_components,
7404  typename Number,
7405  typename VectorizedArrayType>
7406 inline void
7407 FEFaceEvaluation<dim,
7408  fe_degree,
7409  n_q_points_1d,
7410  n_components,
7411  Number,
7412  VectorizedArrayType>::evaluate(const bool evaluate_values,
7413  const bool evaluate_gradients)
7414 {
7415 # ifdef DEBUG
7416  Assert(this->dof_values_initialized, ExcNotInitialized());
7417 # endif
7418 
7419  evaluate(this->values_dofs[0], evaluate_values, evaluate_gradients);
7420 }
7421 
7422 
7423 
7424 template <int dim,
7425  int fe_degree,
7426  int n_q_points_1d,
7427  int n_components,
7428  typename Number,
7429  typename VectorizedArrayType>
7430 inline void
7431 FEFaceEvaluation<dim,
7432  fe_degree,
7433  n_q_points_1d,
7434  n_components,
7435  Number,
7436  VectorizedArrayType>::evaluate(const VectorizedArrayType
7437  * values_array,
7438  const bool evaluate_values,
7439  const bool evaluate_gradients)
7440 {
7441  if (!(evaluate_values + evaluate_gradients))
7442  return;
7443 
7445  dim,
7446  fe_degree,
7447  n_q_points_1d,
7448  n_components,
7449  Number,
7450  VectorizedArrayType>::evaluate(*this->data,
7451  values_array,
7452  this->begin_values(),
7453  this->begin_gradients(),
7454  this->scratch_data,
7455  evaluate_values,
7456  evaluate_gradients,
7457  this->face_no,
7458  this->subface_index,
7459  this->face_orientation,
7460  this->mapping_data
7461  ->descriptor[this->active_fe_index]
7462  .face_orientations);
7463 
7464 # ifdef DEBUG
7465  if (evaluate_values == true)
7466  this->values_quad_initialized = true;
7467  if (evaluate_gradients == true)
7468  this->gradients_quad_initialized = true;
7469 # endif
7470 }
7471 
7472 
7473 
7474 template <int dim,
7475  int fe_degree,
7476  int n_q_points_1d,
7477  int n_components,
7478  typename Number,
7479  typename VectorizedArrayType>
7480 inline void
7481 FEFaceEvaluation<dim,
7482  fe_degree,
7483  n_q_points_1d,
7484  n_components,
7485  Number,
7486  VectorizedArrayType>::integrate(const bool integrate_values,
7487  const bool integrate_gradients)
7488 {
7489  integrate(integrate_values, integrate_gradients, this->values_dofs[0]);
7490 
7491 # ifdef DEBUG
7492  this->dof_values_initialized = true;
7493 # endif
7494 }
7495 
7496 
7497 
7498 template <int dim,
7499  int fe_degree,
7500  int n_q_points_1d,
7501  int n_components,
7502  typename Number,
7503  typename VectorizedArrayType>
7504 inline void
7505 FEFaceEvaluation<dim,
7506  fe_degree,
7507  n_q_points_1d,
7508  n_components,
7509  Number,
7510  VectorizedArrayType>::integrate(const bool integrate_values,
7511  const bool integrate_gradients,
7512  VectorizedArrayType
7513  *values_array)
7514 {
7515  if (!(integrate_values + integrate_gradients))
7516  return;
7517 
7519  dim,
7520  fe_degree,
7521  n_q_points_1d,
7522  n_components,
7523  Number,
7524  VectorizedArrayType>::integrate(*this->data,
7525  values_array,
7526  this->begin_values(),
7527  this->begin_gradients(),
7528  this->scratch_data,
7529  integrate_values,
7530  integrate_gradients,
7531  this->face_no,
7532  this->subface_index,
7533  this->face_orientation,
7534  this->mapping_data
7535  ->descriptor[this->active_fe_index]
7536  .face_orientations);
7537 }
7538 
7539 
7540 
7541 template <int dim,
7542  int fe_degree,
7543  int n_q_points_1d,
7544  int n_components_,
7545  typename Number,
7546  typename VectorizedArrayType>
7547 template <typename VectorType>
7548 inline void
7550  dim,
7551  fe_degree,
7552  n_q_points_1d,
7553  n_components_,
7554  Number,
7555  VectorizedArrayType>::gather_evaluate(const VectorType &input_vector,
7556  const bool evaluate_values,
7557  const bool evaluate_gradients)
7558 {
7560  (std::is_same<decltype(std::declval<VectorType>().begin()),
7561  double *>::value ||
7562  std::is_same<decltype(std::declval<VectorType>().begin()),
7563  float *>::value),
7564  "This function requires a vector type with begin() function "
7565  "evaluating to a pointer to basic number (float,double). "
7566  "Use read_dof_values() followed by evaluate() instead.");
7567 
7569  fe_degree,
7570  n_q_points_1d,
7571  n_components,
7572  Number,
7573  VectorizedArrayType>::
7574  gather_evaluate(input_vector.begin(),
7575  *this->data,
7576  *this->dof_info,
7577  this->begin_values(),
7578  this->begin_gradients(),
7579  this->scratch_data,
7580  evaluate_values,
7581  evaluate_gradients,
7582  this->active_fe_index,
7583  this->first_selected_component,
7584  this->cell,
7585  this->face_no,
7586  this->subface_index,
7587  this->dof_access_index,
7588  this->face_orientation,
7589  this->mapping_data->descriptor[this->active_fe_index]
7590  .face_orientations))
7591  {
7592  this->read_dof_values(input_vector);
7593  this->evaluate(evaluate_values, evaluate_gradients);
7594  }
7595 
7596 # ifdef DEBUG
7597  if (evaluate_values == true)
7598  this->values_quad_initialized = true;
7599  if (evaluate_gradients == true)
7600  this->gradients_quad_initialized = true;
7601 # endif
7602 }
7603 
7604 
7605 
7606 template <int dim,
7607  int fe_degree,
7608  int n_q_points_1d,
7609  int n_components_,
7610  typename Number,
7611  typename VectorizedArrayType>
7612 template <typename VectorType>
7613 inline void
7615  dim,
7616  fe_degree,
7617  n_q_points_1d,
7618  n_components_,
7619  Number,
7620  VectorizedArrayType>::integrate_scatter(const bool integrate_values,
7621  const bool integrate_gradients,
7622  VectorType &destination)
7623 {
7625  (std::is_same<decltype(std::declval<VectorType>().begin()),
7626  double *>::value ||
7627  std::is_same<decltype(std::declval<VectorType>().begin()),
7628  float *>::value),
7629  "This function requires a vector type with begin() function "
7630  "evaluating to a pointer to basic number (float,double). "
7631  "Use integrate() followed by distribute_local_to_global() "
7632  "instead.");
7633 
7635  fe_degree,
7636  n_q_points_1d,
7637  n_components,
7638  Number,
7639  VectorizedArrayType>::
7640  integrate_scatter(destination.begin(),
7641  *this->data,
7642  *this->dof_info,
7643  this->begin_dof_values(),
7644  this->begin_values(),
7645  this->begin_gradients(),
7646  this->scratch_data,
7647  integrate_values,
7648  integrate_gradients,
7649  this->active_fe_index,
7650  this->first_selected_component,
7651  this->cell,
7652  this->face_no,
7653  this->subface_index,
7654  this->dof_access_index,
7655  this->face_orientation,
7656  this->mapping_data->descriptor[this->active_fe_index]
7657  .face_orientations))
7658  {
7659  // if we arrive here, writing into the destination vector did not succeed
7660  // because some of the assumptions in integrate_scatter were not
7661  // fulfilled (e.g. an element or degree that does not support direct
7662  // writing), so we must do it here
7663  this->distribute_local_to_global(destination);
7664  }
7665 }
7666 
7667 
7668 
7669 template <int dim,
7670  int fe_degree,
7671  int n_q_points_1d,
7672  int n_components_,
7673  typename Number,
7674  typename VectorizedArrayType>
7676 FEFaceEvaluation<dim,
7677  fe_degree,
7678  n_q_points_1d,
7679  n_components_,
7680  Number,
7681  VectorizedArrayType>::quadrature_point(const unsigned int q)
7682  const
7683 {
7684  AssertIndexRange(q, n_q_points);
7685  if (this->dof_access_index < 2)
7686  {
7687  Assert(this->mapping_data->quadrature_point_offsets.empty() == false,
7688  ExcNotImplemented());
7689  AssertIndexRange(this->cell,
7690  this->mapping_data->quadrature_point_offsets.size());
7691  return this->mapping_data->quadrature_points
7692  [this->mapping_data->quadrature_point_offsets[this->cell] + q];
7693  }
7694  else
7695  {
7696  Assert(this->matrix_info->get_mapping_info()
7697  .face_data_by_cells[this->quad_no]
7698  .quadrature_point_offsets.empty() == false,
7699  ExcNotImplemented());
7700  const unsigned int index =
7701  this->cell * GeometryInfo<dim>::faces_per_cell + this->face_no;
7702  AssertIndexRange(index,
7703  this->matrix_info->get_mapping_info()
7704  .face_data_by_cells[this->quad_no]
7705  .quadrature_point_offsets.size());
7706  return this->matrix_info->get_mapping_info()
7707  .face_data_by_cells[this->quad_no]
7708  .quadrature_points[this->matrix_info->get_mapping_info()
7709  .face_data_by_cells[this->quad_no]
7710  .quadrature_point_offsets[index] +
7711  q];
7712  }
7713 }
7714 
7715 
7716 
7717 /*------------------------- end FEFaceEvaluation ------------------------- */
7718 
7719 
7720 #endif // ifndef DOXYGEN
7721 
7722 
7724 
7725 #endif
array_view.h
internal::MatrixFreeFunctions::DGP_dofs_per_component::value
static constexpr unsigned int value
Definition: fe_evaluation.h:2967
internal::MatrixFreeFunctions::FaceToCellTopology::exterior_face_no
unsigned char exterior_face_no
Definition: face_info.h:92
SymmetricTensor::access_raw_entry
constexpr const Number & access_raw_entry(const unsigned int unrolled_index) const
Utilities::pow
constexpr T pow(const T base, const int iexp)
Definition: utilities.h:476
internal::MatrixFreeFunctions::affine
@ affine
Definition: mapping_info.h:62
FEFaceEvaluation::integrate_scatter
void integrate_scatter(const bool integrate_values, const bool integrate_gradients, VectorType &output_vector)
FEEvaluationBase::get_hessian
Tensor< 1, n_components_, Tensor< 2, dim, VectorizedArrayType > > get_hessian(const unsigned int q_point) const
FEEvaluationAccess< 1, 1, Number, is_face, VectorizedArrayType >::number_type
Number number_type
Definition: fe_evaluation.h:1577
FEFaceEvaluation::tensor_dofs_per_cell
static constexpr unsigned int tensor_dofs_per_cell
Definition: fe_evaluation.h:2762
FEEvaluationBase::active_quad_index
const unsigned int active_quad_index
Definition: fe_evaluation.h:979
FEEvaluationAccess::FEEvaluationAccess
FEEvaluationAccess(const MatrixFree< dim, Number, VectorizedArrayType > &matrix_free, const unsigned int dof_no, const unsigned int first_selected_component, const unsigned int quad_no, const unsigned int fe_degree, const unsigned int n_q_points, const bool is_interior_face=true)
FEEvaluationBase::get_gradient
gradient_type get_gradient(const unsigned int q_point) const
FEEvaluationBase::get_normal_derivative
value_type get_normal_derivative(const unsigned int q_point) const
FEEvaluationBase::get_cell_type
internal::MatrixFreeFunctions::GeometryType get_cell_type() const
FEEvaluation::operator=
FEEvaluation & operator=(const FEEvaluation &other)
FEEvaluationBase::fill_JxW_values
void fill_JxW_values(AlignedVector< VectorizedArrayType > &JxW_values) const
update_quadrature_points
@ update_quadrature_points
Transformed quadrature points.
Definition: fe_update_flags.h:122
internal::ExcAccessToUninitializedField
static ::ExceptionBase & ExcAccessToUninitializedField()
FEEvaluationAccess
Definition: fe_evaluation.h:1187
FEEvaluationBase::get_mapping_data_index_offset
unsigned int get_mapping_data_index_offset() const
SelectEvaluator
Definition: evaluation_selector.h:495
FEEvaluationAccess< dim, 1, Number, is_face, VectorizedArrayType >
Definition: fe_evaluation.h:1265
tensor_product_kernels.h
StaticMappingQ1
Definition: mapping_q1.h:88
FEEvaluationBase::values_quad_initialized
bool values_quad_initialized
Definition: fe_evaluation.h:1106
Utilities::int_to_string
std::string int_to_string(const unsigned int value, const unsigned int digits=numbers::invalid_unsigned_int)
Definition: utilities.cc:474
FEEvaluationBase::quad_no
const unsigned int quad_no
Definition: fe_evaluation.h:961
internal::MatrixFreeFunctions::DoFInfo::dof_access_cell
@ dof_access_cell
Definition: dof_info.h:396
FEEvaluationBase::submit_dof_value
void submit_dof_value(const value_type val_in, const unsigned int dof)
FEEvaluationBase::submit_curl
void submit_curl(const Tensor< 1, dim==2 ? 1 :dim, VectorizedArrayType > curl_in, const unsigned int q_point)
SymmetricTensor
Definition: symmetric_tensor.h:611
FEEvaluationBase::get_scratch_data
ArrayView< VectorizedArrayType > get_scratch_data() const
FEFaceEvaluation::static_n_q_points_cell
static constexpr unsigned int static_n_q_points_cell
Definition: fe_evaluation.h:2744
FEEvaluationBase::begin_dof_values
const VectorizedArrayType * begin_dof_values() const
internal::VectorSetter
Definition: vector_access_internal.h:539
FEEvaluationBase::hessians_quad_initialized
bool hessians_quad_initialized
Definition: fe_evaluation.h:1120
FEEvaluationBase::get_shape_info
const internal::MatrixFreeFunctions::ShapeInfo< VectorizedArrayType > & get_shape_info() const
FEEvaluation::reinit
void reinit(const unsigned int cell_batch_index)
internal::MatrixFreeFunctions::DoFInfo::dof_access_face_interior
@ dof_access_face_interior
Definition: dof_info.h:388
FiniteElement::element_multiplicity
unsigned int element_multiplicity(const unsigned int index) const
Definition: fe.h:3105
FEEvaluationBase::get_curl
Tensor< 1,(dim==2 ? 1 :dim), VectorizedArrayType > get_curl(const unsigned int q_point) const
vectorization.h
FEEvaluationAccess::gradient_type
Tensor< 1, n_components_, Tensor< 1, dim, VectorizedArrayType > > gradient_type
Definition: fe_evaluation.h:1201
StandardExceptions::ExcNotImplemented
static ::ExceptionBase & ExcNotImplemented()
evaluation_selector.h
FEEvaluationBase::FEEvaluationBase
friend class FEEvaluationBase
Definition: fe_evaluation.h:1166
Triangulation
Definition: tria.h:1109
FEEvaluationAccess::operator=
FEEvaluationAccess & operator=(const FEEvaluationAccess &other)
internal::MatrixFreeFunctions::ShapeInfo< VectorizedArrayType >
ArrayView
Definition: array_view.h:77
FEEvaluationBase::submit_symmetric_gradient
void submit_symmetric_gradient(const SymmetricTensor< 2, dim, VectorizedArrayType > grad_in, const unsigned int q_point)
FEEvaluationBase::dof_access_index
internal::MatrixFreeFunctions::DoFInfo::DoFAccessIndex dof_access_index
Definition: fe_evaluation.h:1063
FEEvaluation::n_components
static constexpr unsigned int n_components
Definition: fe_evaluation.h:2304
mapping_data_on_the_fly.h
internal::MatrixFreeFunctions::FaceToCellTopology
Definition: face_info.h:56
FEFaceEvaluation::static_n_q_points
static constexpr unsigned int static_n_q_points
Definition: fe_evaluation.h:2735
FEEvaluation::integrate
void integrate(const bool integrate_values, const bool integrate_gradients)
FEFaceEvaluation::n_components
static constexpr unsigned int n_components
Definition: fe_evaluation.h:2726
VectorOperation
Definition: vector_operation.h:38
FEEvaluationBase::inverse_jacobian
Tensor< 2, dim, VectorizedArrayType > inverse_jacobian(const unsigned int q_index) const
AlignedVector::size
size_type size() const
GeometryInfo
Definition: geometry_info.h:1224
internal::MatrixFreeFunctions::general
@ general
Definition: mapping_info.h:74
VectorType
AssertIndexRange
#define AssertIndexRange(index, range)
Definition: exceptions.h:1649
Patterns::Tools::to_string
std::string to_string(const T &t)
Definition: patterns.h:2360
VectorizedArray< Number >
FEEvaluation::number_type
Number number_type
Definition: fe_evaluation.h:2279
FEEvaluationBase::is_interior_face
bool is_interior_face
Definition: fe_evaluation.h:1057
FEEvaluationBase::submit_value
void submit_value(const value_type val_in, const unsigned int q_point)
Physics::Elasticity::Kinematics::e
SymmetricTensor< 2, dim, Number > e(const Tensor< 2, dim, Number > &F)
shape_info.h
MatrixFree
Definition: matrix_free.h:117
internal::MatrixFreeFunctions::DoFInfo::IndexStorageVariants::contiguous
@ contiguous
FEEvaluationBase::get_cell_ids
std::array< unsigned int, VectorizedArrayType::size()> get_cell_ids() const
FEEvaluationBase::mapped_geometry
std::shared_ptr< internal::MatrixFreeFunctions::MappingDataOnTheFly< dim, Number, VectorizedArrayType > > mapped_geometry
Definition: fe_evaluation.h:1142
FEEvaluationBase::dof_values_initialized
bool dof_values_initialized
Definition: fe_evaluation.h:1099
matrix_free.h
second
Point< 2 > second
Definition: grid_out.cc:4353
DEAL_II_ALWAYS_INLINE
#define DEAL_II_ALWAYS_INLINE
Definition: config.h:99
DoFTools::n_components
unsigned int n_components(const DoFHandler< dim, spacedim > &dh)
FEEvaluationBase::cell_type
internal::MatrixFreeFunctions::GeometryType cell_type
Definition: fe_evaluation.h:1092
FEFaceEvaluation::dofs_per_cell
const unsigned int dofs_per_cell
Definition: fe_evaluation.h:2943
internal::MatrixFreeFunctions::DoFInfo
Definition: dof_info.h:99
Physics::Elasticity::Kinematics::d
SymmetricTensor< 2, dim, Number > d(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
FEEvaluationBase::read_write_operation
void read_write_operation(const VectorOperation &operation, VectorType *vectors[], const std::bitset< VectorizedArrayType::size()> &mask, const bool apply_constraints=true) const
DEAL_II_OPENMP_SIMD_PRAGMA
#define DEAL_II_OPENMP_SIMD_PRAGMA
Definition: config.h:140
vector_access_internal.h
FEEvaluationBase::read_dof_values_plain
void read_dof_values_plain(const VectorType &src, const unsigned int first_index=0)
internal::MatrixFreeFunctions::FaceToCellTopology::subface_index
unsigned char subface_index
Definition: face_info.h:99
FEEvaluationBase::get_symmetric_gradient
SymmetricTensor< 2, dim, VectorizedArrayType > get_symmetric_gradient(const unsigned int q_point) const
type_traits.h
FEEvaluationBase::scratch_data_array
AlignedVector< VectorizedArrayType > * scratch_data_array
Definition: fe_evaluation.h:894
FEEvaluation::value_type
typename BaseClass::value_type value_type
Definition: fe_evaluation.h:2286
internal::VectorReader
Definition: vector_access_internal.h:217
FEFaceEvaluation::value_type
typename BaseClass::value_type value_type
Definition: fe_evaluation.h:2708
internal::FEFaceEvaluationSelector
Definition: evaluation_kernels.h:1877
FEEvaluation::quadrature_point
Point< dim, VectorizedArrayType > quadrature_point(const unsigned int q_point) const
FEEvaluationBase::~FEEvaluationBase
~FEEvaluationBase()
OpenCASCADE::point
Point< spacedim > point(const gp_Pnt &p, const double tolerance=1e-10)
Definition: utilities.cc:188
FEEvaluationBase::distribute_local_to_global
void distribute_local_to_global(VectorType &dst, const unsigned int first_index=0, const std::bitset< VectorizedArrayType::size()> &mask=std::bitset< VectorizedArrayType::size()>().flip()) const
FEEvaluation::n_q_points
const unsigned int n_q_points
Definition: fe_evaluation.h:2624
bool
FEEvaluationBase::dof_info
const internal::MatrixFreeFunctions::DoFInfo * dof_info
Definition: fe_evaluation.h:996
FEEvaluationBase::values_quad_submitted
bool values_quad_submitted
Definition: fe_evaluation.h:1127
FEEvaluationBase::begin_gradients
const VectorizedArrayType * begin_gradients() const
FEEvaluationBase::n_fe_components
const unsigned int n_fe_components
Definition: fe_evaluation.h:967
FEEvaluationAccess< 1, 1, Number, is_face, VectorizedArrayType >
Definition: fe_evaluation.h:1569
FEFaceEvaluation::dofs_per_component
const unsigned int dofs_per_component
Definition: fe_evaluation.h:2935
FEEvaluation::integrate_scatter
void integrate_scatter(const bool integrate_values, const bool integrate_gradients, VectorType &output_vector)
FEEvaluationBase::face_no
unsigned int face_no
Definition: fe_evaluation.h:1069
LAPACKSupport::T
static const char T
Definition: lapack_support.h:163
FEEvaluationBase::normal_x_jacobian
const Tensor< 1, dim, VectorizedArrayType > * normal_x_jacobian
Definition: fe_evaluation.h:1040
FEEvaluationBase::gradients_quad_initialized
bool gradients_quad_initialized
Definition: fe_evaluation.h:1113
FEEvaluation::gather_evaluate
void gather_evaluate(const VectorType &input_vector, const bool evaluate_values, const bool evaluate_gradients, const bool evaluate_hessians=false)
FEFaceEvaluation::quadrature_point
Point< dim, VectorizedArrayType > quadrature_point(const unsigned int q_point) const
FEEvaluationBase::set_dof_values
void set_dof_values(VectorType &dst, const unsigned int first_index=0, const std::bitset< VectorizedArrayType::size()> &mask=std::bitset< VectorizedArrayType::size()>().flip()) const
Mapping< dim >
FEEvaluationBase::begin_hessians
const VectorizedArrayType * begin_hessians() const
FEEvaluationBase::submit_gradient
void submit_gradient(const gradient_type grad_in, const unsigned int q_point)
FEEvaluationBase::get_value
value_type get_value(const unsigned int q_point) const
FEEvaluationBase::values_quad
VectorizedArrayType * values_quad[n_components]
Definition: fe_evaluation.h:928
StandardExceptions::ExcIndexRange
static ::ExceptionBase & ExcIndexRange(int arg1, int arg2, int arg3)
FEEvaluation::dimension
static constexpr unsigned int dimension
Definition: fe_evaluation.h:2298
FEEvaluationBase::operator=
FEEvaluationBase & operator=(const FEEvaluationBase &other)
vector_operation.h
StandardExceptions::ExcMessage
static ::ExceptionBase & ExcMessage(std::string arg1)
FEEvaluationBase::mapping_data
const internal::MatrixFreeFunctions::MappingInfoStorage<(is_face ? dim - 1 :dim), dim, Number, VectorizedArrayType > * mapping_data
Definition: fe_evaluation.h:1008
double
TrilinosWrappers::internal::begin
VectorType::value_type * begin(VectorType &V)
Definition: trilinos_sparse_matrix.cc:51
internal::reinit
void reinit(MatrixBlock< MatrixType > &v, const BlockSparsityPattern &p)
Definition: matrix_block.h:621
FEFaceEvaluation::number_type
Number number_type
Definition: fe_evaluation.h:2701
FEFaceEvaluation::static_dofs_per_component
static constexpr unsigned int static_dofs_per_component
Definition: fe_evaluation.h:2753
FEEvaluationAccess::n_components
static constexpr unsigned int n_components
Definition: fe_evaluation.h:1203
Tensor
Definition: tensor.h:450
FEEvaluationBase::gradients_quad_submitted
bool gradients_quad_submitted
Definition: fe_evaluation.h:1134
Utilities::fixed_power
T fixed_power(const T t)
Definition: utilities.h:1072
DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:358
internal::MatrixFreeFunctions::FaceToCellTopology::interior_face_no
unsigned char interior_face_no
Definition: face_info.h:84
FEEvaluationAccess< dim, dim, Number, is_face, VectorizedArrayType >
Definition: fe_evaluation.h:1406
FEEvaluation::dofs_per_cell
const unsigned int dofs_per_cell
Definition: fe_evaluation.h:2615
FEFaceEvaluation::evaluate
void evaluate(const bool evaluate_values, const bool evaluate_gradients)
internal::MatrixFreeFunctions::cartesian
@ cartesian
Definition: mapping_info.h:57
FEEvaluation::tensor_dofs_per_cell
static constexpr unsigned int tensor_dofs_per_cell
Definition: fe_evaluation.h:2332
internal::MatrixFreeFunctions::GeometryType
GeometryType
Definition: mapping_info.h:52
AlignedVector< VectorizedArrayType >
FEEvaluation::FEEvaluation
FEEvaluation(const MatrixFree< dim, Number, VectorizedArrayType > &matrix_free, const unsigned int dof_no=0, const unsigned int quad_no=0, const unsigned int first_selected_component=0)
internal::MatrixFreeFunctions::flat_faces
@ flat_faces
Definition: mapping_info.h:68
LAPACKSupport::general
@ general
No special properties.
Definition: lapack_support.h:113
DEAL_II_DEPRECATED
#define DEAL_II_DEPRECATED
Definition: config.h:98
DoFCellAccessor
Definition: dof_accessor.h:1321
FEEvaluationBase::read_write_operation_global
void read_write_operation_global(const VectorOperation &operation, VectorType *vectors[]) const
AssertDimension
#define AssertDimension(dim1, dim2)
Definition: exceptions.h:1579
smartpointer.h
StandardExceptions::ExcNotInitialized
static ::ExceptionBase & ExcNotInitialized()
FiniteElement::component_to_base_index
std::pair< unsigned int, unsigned int > component_to_base_index(const unsigned int component) const
Definition: fe.h:3203
evaluation_kernels.h
FEEvaluationBase::n_quadrature_points
const unsigned int n_quadrature_points
Definition: fe_evaluation.h:984
FEEvaluationBase::read_write_operation_contiguous
void read_write_operation_contiguous(const VectorOperation &operation, VectorType *vectors[], const std::bitset< VectorizedArrayType::size()> &mask) const
numbers
Definition: numbers.h:207
FEEvaluation::dofs_per_component
const unsigned int dofs_per_component
Definition: fe_evaluation.h:2607
FEEvaluationAccess< dim, 1, Number, is_face, VectorizedArrayType >::number_type
Number number_type
Definition: fe_evaluation.h:1273
FEEvaluationBase::hessians_quad
VectorizedArrayType * hessians_quad[n_components][(dim *(dim+1))/2]
Definition: fe_evaluation.h:956
FEEvaluationBase::values_dofs
VectorizedArrayType * values_dofs[n_components]
Definition: fe_evaluation.h:915
FEEvaluationBase::set_data_pointers
void set_data_pointers()
FiniteElement< dim >
exceptions.h
UpdateFlags
UpdateFlags
Definition: fe_update_flags.h:66
FEEvaluationBase::get_hessian_diagonal
gradient_type get_hessian_diagonal(const unsigned int q_point) const
FEEvaluationBase::n_components
static constexpr unsigned int n_components
Definition: fe_evaluation.h:109
FEEvaluationBase::JxW
VectorizedArrayType JxW(const unsigned int q_index) const
FEEvaluationBase::face_orientation
unsigned int face_orientation
Definition: fe_evaluation.h:1075
FEEvaluationBase::read_dof_values
void read_dof_values(const VectorType &src, const unsigned int first_index=0)
FEEvaluationBase::data
const internal::MatrixFreeFunctions::ShapeInfo< VectorizedArrayType > * data
Definition: fe_evaluation.h:1016
FEEvaluationBase::first_selected_component
const unsigned int first_selected_component
Definition: fe_evaluation.h:1148
FEFaceEvaluation::reinit
void reinit(const unsigned int face_batch_number)
value
static const bool value
Definition: dof_tools_constraints.cc:433
FEEvaluationBase< dim, dim, Number, is_face, VectorizedArrayType >::number_type
Number number_type
Definition: fe_evaluation.h:104
internal::MatrixFreeFunctions::DoFInfo::dof_access_face_exterior
@ dof_access_face_exterior
Definition: dof_info.h:392
StandardExceptions::ExcInternalError
static ::ExceptionBase & ExcInternalError()
FEEvaluationBase::normal_vectors
const Tensor< 1, dim, VectorizedArrayType > * normal_vectors
Definition: fe_evaluation.h:1035
FEEvaluationBase::submit_normal_derivative
void submit_normal_derivative(const value_type grad_in, const unsigned int q_point)
FEFaceEvaluation::gradient_type
typename BaseClass::gradient_type gradient_type
Definition: fe_evaluation.h:2715
FEEvaluationBase::read_cell_data
VectorizedArrayType read_cell_data(const AlignedVector< VectorizedArrayType > &array) const
IsBlockVector
Definition: block_vector_base.h:67
FEEvaluationBase::get_dof_value
value_type get_dof_value(const unsigned int dof) const
FEEvaluationAccess< dim, 1, Number, is_face, VectorizedArrayType >::value_type
VectorizedArrayType value_type
Definition: fe_evaluation.h:1274
Particles::Generators::quadrature_points
void quadrature_points(const Triangulation< dim, spacedim > &triangulation, const Quadrature< dim > &quadrature, const std::vector< std::vector< BoundingBox< spacedim >>> &global_bounding_boxes, ParticleHandler< dim, spacedim > &particle_handler, const Mapping< dim, spacedim > &mapping=StaticMappingQ1< dim, spacedim >::mapping)
Definition: generators.cc:442
FEFaceEvaluation::n_q_points
const unsigned int n_q_points
Definition: fe_evaluation.h:2952
FEEvaluation::BaseClass
FEEvaluationAccess< dim, n_components_, Number, false, VectorizedArrayType > BaseClass
Definition: fe_evaluation.h:2274
Assert
#define Assert(cond, exc)
Definition: exceptions.h:1419
FEFaceEvaluation::integrate
void integrate(const bool integrate_values, const bool integrate_gradients)
FEEvaluationBase::scratch_data
VectorizedArrayType * scratch_data
Definition: fe_evaluation.h:901
symmetric_tensor.h
FEEvaluationAccess::value_type
Tensor< 1, n_components_, VectorizedArrayType > value_type
Definition: fe_evaluation.h:1199
FEEvaluationBase::matrix_info
const MatrixFree< dim, Number, VectorizedArrayType > * matrix_info
Definition: fe_evaluation.h:989
FEEvaluationBase::subface_index
unsigned int subface_index
Definition: fe_evaluation.h:1084
FEEvaluationBase::dimension
static constexpr unsigned int dimension
Definition: fe_evaluation.h:108
FEFaceEvaluation::gather_evaluate
void gather_evaluate(const VectorType &input_vector, const bool evaluate_values, const bool evaluate_gradients)
FEFaceEvaluation::FEFaceEvaluation
FEFaceEvaluation(const MatrixFree< dim, Number, VectorizedArrayType > &matrix_free, const bool is_interior_face=true, const unsigned int dof_no=0, const unsigned int quad_no=0, const unsigned int first_selected_component=0)
DeclException0
#define DeclException0(Exception0)
Definition: exceptions.h:473
FEEvaluationBase::local_dof_indices
std::vector< types::global_dof_index > local_dof_indices
Definition: fe_evaluation.h:1154
std::pow
inline ::VectorizedArray< Number, width > pow(const ::VectorizedArray< Number, width > &x, const Number p)
Definition: vectorization.h:5428
GridTools::shift
void shift(const Tensor< 1, spacedim > &shift_vector, Triangulation< dim, spacedim > &triangulation)
Definition: grid_tools.cc:817
FEEvaluationBase::get_normal_vector
Tensor< 1, dim, VectorizedArrayType > get_normal_vector(const unsigned int q_point) const
FEEvaluationAccess< 1, 1, Number, is_face, VectorizedArrayType >::value_type
VectorizedArrayType value_type
Definition: fe_evaluation.h:1578
FEEvaluation::evaluate
void evaluate(const bool evaluate_values, const bool evaluate_gradients, const bool evaluate_hessians=false)
internal::MatrixFreeFunctions::DoFInfo::IndexStorageVariants
IndexStorageVariants
Definition: dof_info.h:296
FEEvaluationBase::J_value
const VectorizedArrayType * J_value
Definition: fe_evaluation.h:1030
numbers::invalid_unsigned_int
static const unsigned int invalid_unsigned_int
Definition: types.h:191
internal::MatrixFreeFunctions::MappingInfoStorage
Definition: mapping_info.h:117
internal::MatrixFreeFunctions::FaceToCellTopology::face_orientation
unsigned char face_orientation
Definition: face_info.h:108
FEEvaluation::check_template_arguments
void check_template_arguments(const unsigned int fe_no, const unsigned int first_selected_component)
internal::MatrixFreeFunctions::DoFInfo::IndexStorageVariants::interleaved
@ interleaved
Point
Definition: point.h:111
template_constraints.h
config.h
FEEvaluationBase
Definition: fe_evaluation.h:97
FEEvaluation::static_dofs_per_cell
static constexpr unsigned int static_dofs_per_cell
Definition: fe_evaluation.h:2342
FEEvaluation::static_n_q_points
static constexpr unsigned int static_n_q_points
Definition: fe_evaluation.h:2312
FEEvaluationBase::gradients_quad
VectorizedArrayType * gradients_quad[n_components][dim]
Definition: fe_evaluation.h:943
FEFaceEvaluation::dimension
static constexpr unsigned int dimension
Definition: fe_evaluation.h:2720
FEEvaluation
Definition: fe_evaluation.h:57
FEEvaluationBase::jacobian
const Tensor< 2, dim, VectorizedArrayType > * jacobian
Definition: fe_evaluation.h:1022
internal
Definition: aligned_vector.h:369
FEEvaluationAccess< dim, dim, Number, is_face, VectorizedArrayType >::number_type
Number number_type
Definition: fe_evaluation.h:1414
internal::MatrixFreeFunctions::DGP_dofs_per_component
Definition: fe_evaluation.h:2964
FEFaceEvaluation
Definition: fe_evaluation.h:2681
DEAL_II_NAMESPACE_CLOSE
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:359
FEEvaluationBase::get_laplacian
value_type get_laplacian(const unsigned int q_point) const
FEEvaluationBase::begin_values
const VectorizedArrayType * begin_values() const
FEEvaluationBase::cell
unsigned int cell
Definition: fe_evaluation.h:1051
Quadrature< 1 >
first
Point< 2 > first
Definition: grid_out.cc:4352
FEEvaluationBase::get_divergence
VectorizedArrayType get_divergence(const unsigned int q_point) const
internal::MatrixFreeFunctions::DoFInfo::DoFAccessIndex
DoFAccessIndex
Definition: dof_info.h:383
TriaIterator
Definition: tria_iterator.h:578
FEEvaluation::static_dofs_per_component
static constexpr unsigned int static_dofs_per_component
Definition: fe_evaluation.h:2322
FEEvaluation::gradient_type
typename BaseClass::gradient_type gradient_type
Definition: fe_evaluation.h:2293
FEFaceEvaluation::static_dofs_per_cell
static constexpr unsigned int static_dofs_per_cell
Definition: fe_evaluation.h:2771
FEEvaluationBase::integrate_value
value_type integrate_value() const
FEEvaluationAccess::dimension
static constexpr unsigned int dimension
Definition: fe_evaluation.h:1202
FEEvaluationBase::active_fe_index
const unsigned int active_fe_index
Definition: fe_evaluation.h:973
Utilities
Definition: cuda.h:31
Utilities::MPI::max
T max(const T &t, const MPI_Comm &mpi_communicator)
internal::VectorDistributorLocalToGlobal
Definition: vector_access_internal.h:375
internal::check_vector_compatibility
void check_vector_compatibility(const VectorType &vec, const internal::MatrixFreeFunctions::DoFInfo &dof_info)
Definition: vector_access_internal.h:176
FEEvaluationBase::get_internal_dof_numbering
const std::vector< unsigned int > & get_internal_dof_numbering() const
int
FEEvaluationBase::quadrature_weights
const Number * quadrature_weights
Definition: fe_evaluation.h:1045
FEEvaluationBase::submit_divergence
void submit_divergence(const VectorizedArrayType div_in, const unsigned int q_point)