Reference documentation for deal.II version GIT relicensing-464-g14f7274e4d 2024-04-22 15:40:02+00:00
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
Loading...
Searching...
No Matches
ad_helpers.h
Go to the documentation of this file.
1// ------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: LGPL-2.1-or-later
4// Copyright (C) 2018 - 2023 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Part of the source code is dual licensed under Apache-2.0 WITH
9// LLVM-exception OR LGPL-2.1-or-later. Detailed license information
10// governing the source code and code contributions can be found in
11// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II.
12//
13// ------------------------------------------------------------------------
14
15#ifndef dealii_differentiation_ad_ad_helpers_h
16#define dealii_differentiation_ad_ad_helpers_h
17
18#include <deal.II/base/config.h>
19
20#if defined(DEAL_II_WITH_ADOLC) || defined(DEAL_II_TRILINOS_WITH_SACADO)
21
22# include <deal.II/base/numbers.h>
24# include <deal.II/base/tensor.h>
25
32
34
36# include <deal.II/lac/vector.h>
37
38# include <algorithm>
39# include <iostream>
40# include <iterator>
41# include <numeric>
42
44
45namespace Differentiation
46{
47 namespace AD
48 {
166 template <enum AD::NumberTypes ADNumberTypeCode,
167 typename ScalarType = double>
169 {
170 public:
177
182 using ad_type =
184
204 HelperBase(const unsigned int n_independent_variables,
205 const unsigned int n_dependent_variables);
206
210 virtual ~HelperBase() = default;
211
223 std::size_t
225
230 std::size_t
231 n_dependent_variables() const;
232
241 void
242 print(std::ostream &stream) const;
243
250 void
251 print_values(std::ostream &stream) const;
252
263 void
264 print_tape_stats(const typename Types<ad_type>::tape_index tape_index,
265 std::ostream &stream) const;
266
292 static void
294 const bool ensure_persistent_setting = true);
295
338 virtual void
339 reset(const unsigned int n_independent_variables =
341 const unsigned int n_dependent_variables =
343 const bool clear_registered_tapes = true);
344
349 bool
350 is_recording() const;
351
357 active_tape_index() const;
358
363 bool
365 const typename Types<ad_type>::tape_index tape_index) const;
366
392 void
394 const typename Types<ad_type>::tape_buffer_sizes obufsize = 64 * 1024 *
395 1024,
396 const typename Types<ad_type>::tape_buffer_sizes lbufsize = 64 * 1024 *
397 1024,
398 const typename Types<ad_type>::tape_buffer_sizes vbufsize = 64 * 1024 *
399 1024,
400 const typename Types<ad_type>::tape_buffer_sizes tbufsize = 64 * 1024 *
401 1024);
402
448 bool
450 const typename Types<ad_type>::tape_index tape_index,
451 const bool overwrite_tape = false,
452 const bool keep_independent_values = true);
453
465 void
466 stop_recording_operations(const bool write_tapes_to_file = false);
467
477 void
479 const typename Types<ad_type>::tape_index tape_index);
480
520 bool
522 const typename Types<ad_type>::tape_index tape_index) const;
523
563 bool
565
573 void
575
578 protected:
591
599
616 void
617 activate_tape(const typename Types<ad_type>::tape_index tape_index,
618 const bool read_mode);
619
634 mutable std::vector<scalar_type> independent_variable_values;
635
644 mutable std::vector<ad_type> independent_variables;
645
651
657
663 void
665
672 void
673 set_sensitivity_value(const unsigned int index, const scalar_type &value);
674
693 void
694 mark_independent_variable(const unsigned int index, ad_type &out) const;
695
706 void
708
718 void
719 initialize_non_sensitive_independent_variable(const unsigned int index,
720 ad_type &out) const;
721
726 unsigned int
728
748 std::vector<ad_type> dependent_variables;
749
754
761 void
762 reset_registered_dependent_variables(const bool flag = false);
763
767 unsigned int
769
781 void
782 register_dependent_variable(const unsigned int index,
783 const ad_type &func);
784
787 }; // class HelperBase
788
789
790
832 template <enum AD::NumberTypes ADNumberTypeCode,
833 typename ScalarType = double>
834 class CellLevelBase : public HelperBase<ADNumberTypeCode, ScalarType>
835 {
836 public:
843
848 using ad_type =
850
870 CellLevelBase(const unsigned int n_independent_variables,
871 const unsigned int n_dependent_variables);
872
876 virtual ~CellLevelBase() = default;
877
902 void
903 register_dof_values(const std::vector<scalar_type> &dof_values);
904
923 template <typename VectorType>
924 void
926 const VectorType &values,
927 const std::vector<::types::global_dof_index> &local_dof_indices);
928
949 const std::vector<ad_type> &
951
978 void
979 set_dof_values(const std::vector<scalar_type> &dof_values);
980
998 template <typename VectorType>
999 void
1001 const VectorType &values,
1002 const std::vector<::types::global_dof_index> &local_dof_indices);
1003
1025 virtual void
1027
1045 virtual void
1047
1050 }; // class CellLevelBase
1051
1052
1053
1214 template <enum AD::NumberTypes ADNumberTypeCode,
1215 typename ScalarType = double>
1216 class EnergyFunctional : public CellLevelBase<ADNumberTypeCode, ScalarType>
1217 {
1218 public:
1225
1230 using ad_type =
1232
1253 EnergyFunctional(const unsigned int n_independent_variables);
1254
1258 virtual ~EnergyFunctional() = default;
1259
1280 void
1281 register_energy_functional(const ad_type &energy);
1282
1297 compute_energy() const;
1298
1318 void
1319 compute_residual(Vector<scalar_type> &residual) const override;
1320
1341 virtual void
1343 FullMatrix<scalar_type> &linearization) const override;
1344
1347 }; // class EnergyFunctional
1348
1349
1350
1525 template <enum AD::NumberTypes ADNumberTypeCode,
1526 typename ScalarType = double>
1528 : public CellLevelBase<ADNumberTypeCode, ScalarType>
1529 {
1530 public:
1537
1542 using ad_type =
1544
1565 const unsigned int n_dependent_variables);
1566
1570 virtual ~ResidualLinearization() = default;
1571
1592 void
1593 register_residual_vector(const std::vector<ad_type> &residual);
1594
1611 virtual void
1612 compute_residual(Vector<scalar_type> &residual) const override;
1613
1631 virtual void
1633 FullMatrix<scalar_type> &linearization) const override;
1634
1637 }; // class ResidualLinearization
1638
1639
1640
1641 namespace internal
1642 {
1647 template <int dim, typename ExtractorType>
1649
1650
1656 template <int dim>
1657 struct Extractor<dim, FEValuesExtractors::Scalar>
1658 {
1662 static const unsigned int n_components = 1;
1663
1667 static const unsigned int rank = 0;
1668
1672 template <typename NumberType>
1674
1675 static_assert(
1677 "The number of components doesn't match that of the corresponding tensor type.");
1678 static_assert(
1680 "The rank doesn't match that of the corresponding tensor type.");
1681
1685 // Note: FEValuesViews::Scalar::tensor_type is double, so we can't
1686 // use it (FEValuesViews) in this context.
1687 // In fact, sadly, all FEValuesViews objects expect doubles as value
1688 // types.
1689 template <typename NumberType>
1691
1695 template <typename NumberType>
1697
1701 static inline unsigned int
1703 {
1704 return extractor.component;
1705 }
1706
1714 static bool
1715 symmetric_component(const unsigned int unrolled_index)
1716 {
1717 (void)unrolled_index;
1718 return false;
1719 }
1720
1728 template <typename IndexType = unsigned int, int rank_in>
1729 static IndexType
1731 const unsigned int column_offset)
1732 {
1733 Assert(column_offset <= rank_in, ExcInternalError());
1734 (void)table_indices;
1735 (void)column_offset;
1736 return 0;
1737 }
1738 };
1739
1740
1746 template <int dim>
1748 {
1752 static const unsigned int n_components = dim;
1753
1757 static const unsigned int rank = 1;
1758
1762 template <typename NumberType>
1764
1765 static_assert(
1767 "The number of components doesn't match that of the corresponding tensor type.");
1768 static_assert(
1770 "The rank doesn't match that of the corresponding tensor type.");
1771
1775 template <typename NumberType>
1777
1781 template <typename NumberType>
1783
1787 static inline unsigned int
1789 {
1790 return extractor.first_vector_component;
1791 }
1792
1801 static bool
1802 symmetric_component(const unsigned int unrolled_index)
1803 {
1804 (void)unrolled_index;
1805 return false;
1806 }
1807
1812 template <int rank_in>
1813 static TableIndices<rank>
1815 const unsigned int column_offset)
1816 {
1817 Assert(0 + column_offset < rank_in, ExcInternalError());
1818 return TableIndices<rank>(table_indices[column_offset]);
1819 }
1820
1836 template <typename IndexType = unsigned int, int rank_in>
1837 static IndexType
1839 const unsigned int column_offset)
1840 {
1841 static_assert(
1842 rank_in >= rank,
1843 "Cannot extract more table indices than the input table has!");
1844 using TensorType = tensor_type<double>;
1845 return TensorType::component_to_unrolled_index(
1846 table_index_view(table_indices, column_offset));
1847 }
1848 };
1849
1850
1856 template <int dim>
1858 {
1862 static const unsigned int n_components =
1864
1868 static const unsigned int rank = 1;
1869
1873 template <typename NumberType>
1875
1879 template <typename NumberType>
1881
1885 template <typename NumberType>
1887
1891 static inline unsigned int
1893 {
1894 return extractor.first_tensor_component;
1895 }
1896
1904 static bool
1905 symmetric_component(const unsigned int unrolled_index)
1906 {
1907 (void)unrolled_index;
1908 return false;
1909 }
1910
1915 template <int rank_in>
1916 static TableIndices<rank>
1918 const unsigned int column_offset)
1919 {
1920 Assert(column_offset < rank_in, ExcInternalError());
1921 return TableIndices<rank>(table_indices[column_offset]);
1922 }
1923
1939 template <typename IndexType = unsigned int, int rank_in>
1940 static IndexType
1942 const unsigned int column_offset)
1943 {
1944 static_assert(
1945 rank_in >= rank,
1946 "Cannot extract more table indices than the input table has!");
1947 using TensorType = tensor_type<double>;
1948 return TensorType::component_to_unrolled_index(
1949 table_index_view(table_indices, column_offset));
1950 }
1951 };
1952
1953
1959 template <int dim>
1961 {
1965 static const unsigned int n_components =
1967
1971 static const unsigned int rank = Tensor<2, dim>::rank;
1972
1976 template <typename NumberType>
1978
1982 template <typename NumberType>
1984
1988 template <typename NumberType>
1990
1994 static inline unsigned int
1996 {
1997 return extractor.first_tensor_component;
1998 }
1999
2007 static bool
2008 symmetric_component(const unsigned int unrolled_index)
2009 {
2010 (void)unrolled_index;
2011 return false;
2012 }
2013
2018 template <int rank_in>
2019 static TableIndices<rank>
2021 const unsigned int column_offset)
2022 {
2023 Assert(column_offset < rank_in, ExcInternalError());
2024 Assert(column_offset + 1 < rank_in, ExcInternalError());
2025 return TableIndices<rank>(table_indices[column_offset],
2026 table_indices[column_offset + 1]);
2027 }
2028
2044 template <typename IndexType = unsigned int, int rank_in>
2045 static IndexType
2047 const unsigned int column_offset)
2048 {
2049 static_assert(
2050 rank_in >= rank,
2051 "Cannot extract more table indices than the input table has!");
2052 using TensorType = tensor_type<double>;
2053 return TensorType::component_to_unrolled_index(
2054 table_index_view(table_indices, column_offset));
2055 }
2056 };
2057
2058
2064 template <int dim>
2066 {
2070 static const unsigned int n_components =
2072
2076 static const unsigned int rank = SymmetricTensor<2, dim>::rank;
2077
2081 template <typename NumberType>
2083
2087 template <typename NumberType>
2089
2093 template <typename NumberType>
2095
2099 static inline unsigned int
2101 {
2102 return extractor.first_tensor_component;
2103 }
2104
2113 static bool
2114 symmetric_component(const unsigned int unrolled_index)
2115 {
2116 const TableIndices<2> table_indices =
2118 return table_indices[0] != table_indices[1];
2119 }
2120
2125 template <int rank_in>
2126 static TableIndices<rank>
2128 const unsigned int column_offset)
2129 {
2130 Assert(column_offset < rank_in, ExcInternalError());
2131 Assert(column_offset + 1 < rank_in, ExcInternalError());
2132 return TableIndices<rank>(table_indices[column_offset],
2133 table_indices[column_offset + 1]);
2134 }
2135
2151 template <typename IndexType = unsigned int, int rank_in>
2152 static IndexType
2154 const unsigned int column_offset)
2155 {
2156 static_assert(
2157 rank_in >= rank,
2158 "Cannot extract more table indices than the input table has!");
2159 using TensorType = tensor_type<double>;
2160 return TensorType::component_to_unrolled_index(
2161 table_index_view(table_indices, column_offset));
2162 }
2163 };
2164
2165
2171 template <int dim, typename NumberType, typename ExtractorType>
2173 {
2178 using type =
2179 typename Extractor<dim,
2180 ExtractorType>::template tensor_type<NumberType>;
2181 };
2182
2183
2193 template <typename ExtractorType_Row, typename ExtractorType_Col>
2195 {
2207 template <int rank, int dim, typename NumberType>
2209 };
2210
2211
2220 template <>
2223 {
2231 template <int /*rank*/, int dim, typename NumberType>
2232 using type = SymmetricTensor<2 /*rank*/, dim, NumberType>;
2233 };
2234
2235
2244 template <>
2247 {
2256 template <int /*rank*/, int dim, typename NumberType>
2257 using type = SymmetricTensor<2 /*rank*/, dim, NumberType>;
2258 };
2259
2260
2268 template <>
2271 {
2280 template <int /*rank*/, int dim, typename NumberType>
2281 using type = SymmetricTensor<4 /*rank*/, dim, NumberType>;
2282 };
2283
2284
2294 template <int dim,
2295 typename NumberType,
2296 typename ExtractorType_Row,
2297 typename ExtractorType_Col>
2316
2317
2322 template <int dim, typename NumberType, typename ExtractorType_Field>
2325
2326
2336 template <int dim,
2337 typename NumberType,
2338 typename ExtractorType_Field,
2339 typename ExtractorType_Derivative>
2341 NumberType,
2342 ExtractorType_Field,
2343 ExtractorType_Derivative>;
2344
2345
2351 template <int dim,
2352 typename IndexType = unsigned int,
2353 typename ExtractorType>
2354 std::vector<IndexType>
2355 extract_field_component_indices(const ExtractorType &extractor,
2356 const bool ignore_symmetries = true)
2357 {
2358 (void)ignore_symmetries;
2359 const IndexType n_components =
2361 const IndexType comp_first =
2363 std::vector<IndexType> indices(n_components);
2364 std::iota(indices.begin(), indices.end(), comp_first);
2365 return indices;
2366 }
2367
2368
2377 template <int dim, typename IndexType = unsigned int>
2378 std::vector<IndexType>
2380 const FEValuesExtractors::SymmetricTensor<2> &extractor_symm_tensor,
2381 const bool ignore_symmetries = true)
2382 {
2383 using ExtractorType = FEValuesExtractors::SymmetricTensor<2>;
2384 const IndexType n_components =
2386 const IndexType comp_first =
2388 extractor_symm_tensor);
2389
2390 if (ignore_symmetries == true)
2391 {
2392 std::vector<IndexType> indices(n_components);
2393 std::iota(indices.begin(), indices.end(), comp_first);
2394 return indices;
2395 }
2396 else
2397 {
2398 // First get all of the indices of the non-symmetric tensor
2399 const FEValuesExtractors::Tensor<2> extractor_tensor(
2400 extractor_symm_tensor.first_tensor_component);
2401 std::vector<IndexType> indices =
2402 extract_field_component_indices<dim>(extractor_tensor, true);
2403
2404 // Then we overwrite any illegal entries with the equivalent indices
2405 // from the symmetric tensor
2406 for (unsigned int i = 0; i < indices.size(); ++i)
2407 {
2408 // The indices stored in the vector start with the extractor's
2409 // first_component_index. We need to account for this when
2410 // retrieving the tensor (local) index.
2411 const IndexType local_index_i = indices[i] - comp_first;
2412 if (local_index_i >= n_components)
2413 {
2414 const TableIndices<2> ti_tensor =
2416 local_index_i);
2417 const IndexType sti_new_index =
2419 ti_tensor);
2420 indices[i] = comp_first + sti_new_index;
2421 }
2422 }
2423
2424 return indices;
2425 }
2426 }
2427
2428
2433 template <typename TensorType, typename NumberType>
2434 inline void
2435 set_tensor_entry(TensorType &t,
2436 const unsigned int unrolled_index,
2437 const NumberType &value)
2438 {
2439 // Where possible, set values using TableIndices
2440 AssertIndexRange(unrolled_index, t.n_independent_components);
2441 t[TensorType::unrolled_to_component_indices(unrolled_index)] = value;
2442 }
2443
2444
2449 template <int dim, typename NumberType>
2450 inline void
2452 const unsigned int unrolled_index,
2453 const NumberType &value)
2454 {
2455 AssertIndexRange(unrolled_index, 1);
2456 (void)unrolled_index;
2457 t = value;
2458 }
2459
2460
2466 template <typename NumberType>
2467 inline void
2469 const unsigned int unrolled_index,
2470 const NumberType &value)
2471 {
2472 AssertIndexRange(unrolled_index, 1);
2473 (void)unrolled_index;
2474 t = value;
2475 }
2476
2477
2483 template <int dim, typename NumberType>
2484 inline void
2486 const unsigned int unrolled_index_row,
2487 const unsigned int unrolled_index_col,
2488 const NumberType &value)
2489 {
2490 // Fourth order symmetric tensors require a specialized interface
2491 // to extract values.
2492 using SubTensorType = SymmetricTensor<2, dim, NumberType>;
2493 AssertIndexRange(unrolled_index_row,
2494 SubTensorType::n_independent_components);
2495 AssertIndexRange(unrolled_index_col,
2496 SubTensorType::n_independent_components);
2497 const TableIndices<2> indices_row =
2498 SubTensorType::unrolled_to_component_indices(unrolled_index_row);
2499 const TableIndices<2> indices_col =
2500 SubTensorType::unrolled_to_component_indices(unrolled_index_col);
2501 t[indices_row[0]][indices_row[1]][indices_col[0]][indices_col[1]] =
2502 value;
2503 }
2504
2505
2510 template <int rank,
2511 int dim,
2512 typename NumberType,
2513 template <int, int, typename>
2514 class TensorType>
2515 inline NumberType
2516 get_tensor_entry(const TensorType<rank, dim, NumberType> &t,
2517 const unsigned int unrolled_index)
2518 {
2519 // Where possible, get values using TableIndices
2520 AssertIndexRange(unrolled_index, t.n_independent_components);
2521 return t[TensorType<rank, dim, NumberType>::
2522 unrolled_to_component_indices(unrolled_index)];
2523 }
2524
2525
2530 template <int dim,
2531 typename NumberType,
2532 template <int, int, typename>
2533 class TensorType>
2534 inline NumberType
2535 get_tensor_entry(const TensorType<0, dim, NumberType> &t,
2536 const unsigned int unrolled_index)
2537 {
2538 AssertIndexRange(unrolled_index, 1);
2539 (void)unrolled_index;
2540 return t;
2541 }
2542
2543
2549 template <typename NumberType>
2550 inline const NumberType &
2551 get_tensor_entry(const NumberType &t, const unsigned int unrolled_index)
2552 {
2553 AssertIndexRange(unrolled_index, 1);
2554 (void)unrolled_index;
2555 return t;
2556 }
2557
2558
2563 template <int rank,
2564 int dim,
2565 typename NumberType,
2566 template <int, int, typename>
2567 class TensorType>
2568 inline NumberType &
2569 get_tensor_entry(TensorType<rank, dim, NumberType> &t,
2570 const unsigned int unrolled_index)
2571 {
2572 // Where possible, get values using TableIndices
2573 AssertIndexRange(unrolled_index, t.n_independent_components);
2574 return t[TensorType<rank, dim, NumberType>::
2575 unrolled_to_component_indices(unrolled_index)];
2576 }
2577
2578
2583 template <int dim,
2584 typename NumberType,
2585 template <int, int, typename>
2586 class TensorType>
2587 NumberType &
2588 get_tensor_entry(TensorType<0, dim, NumberType> &t,
2589 const unsigned int index)
2590 {
2591 AssertIndexRange(index, 1);
2592 (void)index;
2593 return t;
2594 }
2595
2596
2602 template <typename NumberType>
2603 inline NumberType &
2604 get_tensor_entry(NumberType &t, const unsigned int index)
2605 {
2606 AssertIndexRange(index, 1);
2607 (void)index;
2608 return t;
2609 }
2610
2611 } // namespace internal
2612
2613
2614
2636 template <int dim,
2637 enum AD::NumberTypes ADNumberTypeCode,
2638 typename ScalarType = double>
2640 : public HelperBase<ADNumberTypeCode, ScalarType>
2641 {
2642 public:
2647 static constexpr unsigned int dimension = dim;
2648
2655
2660 using ad_type =
2662
2683 const unsigned int n_dependent_variables);
2684
2688 virtual ~PointLevelFunctionsBase() = default;
2689
2732 virtual void
2733 reset(const unsigned int n_independent_variables =
2735 const unsigned int n_dependent_variables =
2737 const bool clear_registered_tapes = true) override;
2738
2754 void
2755 register_independent_variables(const std::vector<scalar_type> &values);
2756
2785 template <typename ValueType, typename ExtractorType>
2786 void
2787 register_independent_variable(const ValueType &value,
2788 const ExtractorType &extractor);
2789
2810 const std::vector<ad_type> &
2812
2813 /*
2814 * Extract a subset of the independent variables as represented by
2815 * auto-differentiable numbers. These are the independent
2816 * variables @f$\mathbf{A} \subset \mathbf{X}@f$ at which the dependent values
2817 * are evaluated and differentiated.
2818 *
2819 * This function indicates to the AD library that implements the
2820 * auto-differentiable number type that operations performed on these
2821 * numbers are to be tracked so they are considered "sensitive"
2822 * variables. This is, therefore, the set of variables with which one
2823 * would then perform computations, and based on which one can then
2824 * extract both the value of the function and its derivatives with the
2825 * member functions below. The values of the components of the returned
2826 * object are initialized to the values set with
2827 * register_independent_variable().
2828 *
2829 * @param[in] extractor An extractor associated with the input field
2830 * variables. This effectively defines which components of the global set
2831 * of independent variables this field is associated with.
2832 * @return An object of auto-differentiable type numbers. The return type is
2833 * based on the input extractor, and will be either a scalar,
2834 * Tensor<1,dim>, Tensor<2,dim>, or SymmetricTensor<2,dim>.
2835 *
2836 * @note For taped AD numbers, this operation is only valid in recording mode.
2837 */
2838 template <typename ExtractorType>
2841 get_sensitive_variables(const ExtractorType &extractor) const;
2842
2867 void
2868 set_independent_variables(const std::vector<scalar_type> &values);
2869
2896 template <typename ValueType, typename ExtractorType>
2897 void
2898 set_independent_variable(const ValueType &value,
2899 const ExtractorType &extractor);
2900
2903 protected:
2919 void
2920 set_sensitivity_value(const unsigned int index,
2921 const bool symmetric_component,
2922 const scalar_type &value);
2923
2929 bool
2930 is_symmetric_independent_variable(const unsigned int index) const;
2931
2936 unsigned int
2938
2941 private:
2952
2955 }; // class PointLevelFunctionsBase
2956
2957
2958
3113 template <int dim,
3114 enum AD::NumberTypes ADNumberTypeCode,
3115 typename ScalarType = double>
3117 : public PointLevelFunctionsBase<dim, ADNumberTypeCode, ScalarType>
3118 {
3119 public:
3126
3131 using ad_type =
3133
3148 ScalarFunction(const unsigned int n_independent_variables);
3149
3153 virtual ~ScalarFunction() = default;
3154
3173 void
3175
3184 compute_value() const;
3185
3198 void
3199 compute_gradient(Vector<scalar_type> &gradient) const;
3200
3215 void
3217
3252 template <typename ExtractorType_Row>
3253 static typename internal::
3254 ScalarFieldGradient<dim, scalar_type, ExtractorType_Row>::type
3256 const ExtractorType_Row &extractor_row);
3257
3296 template <typename ExtractorType_Row, typename ExtractorType_Col>
3297 static typename internal::ScalarFieldHessian<dim,
3299 ExtractorType_Row,
3300 ExtractorType_Col>::type
3302 const ExtractorType_Row &extractor_row,
3303 const ExtractorType_Col &extractor_col);
3304
3320 const FullMatrix<scalar_type> &hessian,
3321 const FEValuesExtractors::Scalar &extractor_row,
3322 const FEValuesExtractors::Scalar &extractor_col);
3323
3337 const FullMatrix<scalar_type> &hessian,
3338 const FEValuesExtractors::SymmetricTensor<2> &extractor_row,
3339 const FEValuesExtractors::SymmetricTensor<2> &extractor_col);
3340
3343 }; // class ScalarFunction
3344
3345
3346
3504 template <int dim,
3505 enum AD::NumberTypes ADNumberTypeCode,
3506 typename ScalarType = double>
3508 : public PointLevelFunctionsBase<dim, ADNumberTypeCode, ScalarType>
3509 {
3510 public:
3517
3522 using ad_type =
3524
3544 VectorFunction(const unsigned int n_independent_variables,
3545 const unsigned int n_dependent_variables);
3546
3550 virtual ~VectorFunction() = default;
3551
3571 void
3572 register_dependent_variables(const std::vector<ad_type> &funcs);
3573
3592 template <typename ValueType, typename ExtractorType>
3593 void
3594 register_dependent_variable(const ValueType &funcs,
3595 const ExtractorType &extractor);
3596
3605 void
3606 compute_values(Vector<scalar_type> &values) const;
3607
3622 void
3624
3625
3638 template <typename ExtractorType_Row>
3639 static typename internal::
3640 VectorFieldValue<dim, scalar_type, ExtractorType_Row>::type
3642 const ExtractorType_Row &extractor_row);
3643
3691 template <typename ExtractorType_Row, typename ExtractorType_Col>
3692 static typename internal::VectorFieldJacobian<dim,
3694 ExtractorType_Row,
3695 ExtractorType_Col>::type
3697 const ExtractorType_Row &extractor_row,
3698 const ExtractorType_Col &extractor_col);
3699
3717 const FullMatrix<scalar_type> &jacobian,
3718 const FEValuesExtractors::Scalar &extractor_row,
3719 const FEValuesExtractors::Scalar &extractor_col);
3720
3736 const FullMatrix<scalar_type> &jacobian,
3737 const FEValuesExtractors::SymmetricTensor<2> &extractor_row,
3738 const FEValuesExtractors::SymmetricTensor<2> &extractor_col);
3739
3742 }; // class VectorFunction
3743
3744
3745 } // namespace AD
3746} // namespace Differentiation
3747
3748
3749/* ----------------- inline and template functions ----------------- */
3750
3751
3752# ifndef DOXYGEN
3753
3754namespace Differentiation
3755{
3756 namespace AD
3757 {
3758 /* ----------------- CellLevelBase ----------------- */
3759
3760
3761
3762 template <enum AD::NumberTypes ADNumberTypeCode, typename ScalarType>
3763 template <typename VectorType>
3764 void
3766 const VectorType &values,
3767 const std::vector<::types::global_dof_index> &local_dof_indices)
3768 {
3769 // This is actually the same thing the set_dof_values() function,
3770 // in the sense that we simply populate our array of independent values
3771 // with a meaningful number. However, in this case we need to double check
3772 // that we're not registering these variables twice
3773 Assert(
3774 local_dof_indices.size() == this->n_independent_variables(),
3775 ExcMessage(
3776 "Degree of freedom index vector size does not match number of independent variables"));
3777 for (unsigned int i = 0; i < this->n_independent_variables(); ++i)
3778 {
3779 Assert(this->registered_independent_variable_values[i] == false,
3780 ExcMessage("Independent variables already registered."));
3781 }
3782 set_dof_values(values, local_dof_indices);
3783 }
3784
3785
3786
3787 template <enum AD::NumberTypes ADNumberTypeCode, typename ScalarType>
3788 template <typename VectorType>
3789 void
3791 const VectorType &values,
3792 const std::vector<::types::global_dof_index> &local_dof_indices)
3793 {
3794 Assert(local_dof_indices.size() == this->n_independent_variables(),
3795 ExcMessage(
3796 "Vector size does not match number of independent variables"));
3797 for (unsigned int i = 0; i < this->n_independent_variables(); ++i)
3799 i, values[local_dof_indices[i]]);
3800 }
3801
3802
3803
3804 /* ----------------- PointLevelFunctionsBase ----------------- */
3805
3806
3807
3808 template <int dim,
3809 enum AD::NumberTypes ADNumberTypeCode,
3810 typename ScalarType>
3811 template <typename ValueType, typename ExtractorType>
3812 void
3814 register_independent_variable(const ValueType &value,
3815 const ExtractorType &extractor)
3816 {
3817 // This is actually the same thing as the set_independent_variable
3818 // function, in the sense that we simply populate our array of independent
3819 // values with a meaningful number. However, in this case we need to
3820 // double check that we're not registering these variables twice
3821# ifdef DEBUG
3822 const std::vector<unsigned int> index_set(
3823 internal::extract_field_component_indices<dim>(extractor));
3824 for (const unsigned int index : index_set)
3825 {
3826 Assert(
3827 this->registered_independent_variable_values[index] == false,
3828 ExcMessage(
3829 "Overlapping indices for independent variables. "
3830 "One or more indices associated with the field that "
3831 "is being registered as an independent variable have "
3832 "already been associated with another field. This suggests "
3833 "that the component offsets used to construct their counterpart "
3834 "extractors are incompatible with one another. Make sure that "
3835 "the first component for each extractor properly takes into "
3836 "account the dimensionality of the preceding fields."));
3837 }
3838# endif
3839 set_independent_variable(value, extractor);
3840 }
3841
3842
3843
3844 template <int dim,
3845 enum AD::NumberTypes ADNumberTypeCode,
3846 typename ScalarType>
3847 template <typename ValueType, typename ExtractorType>
3848 void
3850 set_independent_variable(const ValueType &value,
3851 const ExtractorType &extractor)
3852 {
3853 const std::vector<unsigned int> index_set(
3854 internal::extract_field_component_indices<dim>(extractor));
3855 for (unsigned int i = 0; i < index_set.size(); ++i)
3856 {
3857 set_sensitivity_value(
3858 index_set[i],
3859 internal::Extractor<dim, ExtractorType>::symmetric_component(i),
3860 internal::get_tensor_entry(value, i));
3861 }
3862 }
3863
3864
3865
3866 template <int dim,
3867 enum AD::NumberTypes ADNumberTypeCode,
3868 typename ScalarType>
3869 template <typename ExtractorType>
3870 typename internal::Extractor<dim, ExtractorType>::template tensor_type<
3873 get_sensitive_variables(const ExtractorType &extractor) const
3874 {
3875 if (ADNumberTraits<ad_type>::is_taped == true)
3876 {
3877 Assert(this->active_tape_index() !=
3879 ExcMessage("Invalid tape index"));
3880 }
3881
3882 // If necessary, finalize the internally stored vector of
3883 // AD numbers that represents the independent variables
3884 this->finalize_sensitive_independent_variables();
3885 Assert(this->independent_variables.size() ==
3886 this->n_independent_variables(),
3887 ExcDimensionMismatch(this->independent_variables.size(),
3888 this->n_independent_variables()));
3889
3890 const std::vector<unsigned int> index_set(
3891 internal::extract_field_component_indices<dim>(extractor));
3892 typename internal::Extractor<dim,
3893 ExtractorType>::template tensor_type<ad_type>
3894 out;
3895
3896 for (unsigned int i = 0; i < index_set.size(); ++i)
3897 {
3898 const unsigned int index = index_set[i];
3899 Assert(index < this->n_independent_variables(), ExcInternalError());
3900 Assert(this->registered_independent_variable_values[index] == true,
3903 this->independent_variables[index];
3904 }
3905
3906 return out;
3907 }
3908
3909
3910
3911 /* ----------------- ScalarFunction ----------------- */
3912
3913
3914
3915 template <int dim,
3916 enum AD::NumberTypes ADNumberTypeCode,
3917 typename ScalarType>
3918 template <typename ExtractorType_Row>
3919 typename internal::ScalarFieldGradient<
3920 dim,
3922 ExtractorType_Row>::type
3925 const ExtractorType_Row &extractor_row)
3926 {
3927 // NOTE: The order of components must be consistently defined throughout
3928 // this class.
3929 typename internal::
3930 ScalarFieldGradient<dim, scalar_type, ExtractorType_Row>::type out;
3931
3932 // Get indexsets for the subblock from which we wish to extract the
3933 // gradient values
3934 const std::vector<unsigned int> row_index_set(
3935 internal::extract_field_component_indices<dim>(extractor_row));
3936 Assert(out.n_independent_components == row_index_set.size(),
3937 ExcMessage("Not all tensor components have been extracted!"));
3938 for (unsigned int r = 0; r < row_index_set.size(); ++r)
3939 internal::set_tensor_entry(out, r, gradient[row_index_set[r]]);
3940
3941 return out;
3942 }
3943
3944
3945
3946 template <int dim,
3947 enum AD::NumberTypes ADNumberTypeCode,
3948 typename ScalarType>
3949 template <typename ExtractorType_Row, typename ExtractorType_Col>
3950 typename internal::ScalarFieldHessian<
3951 dim,
3953 ExtractorType_Row,
3954 ExtractorType_Col>::type
3957 const ExtractorType_Row &extractor_row,
3958 const ExtractorType_Col &extractor_col)
3959 {
3960 using InternalHessian = internal::ScalarFieldHessian<dim,
3961 scalar_type,
3962 ExtractorType_Row,
3963 ExtractorType_Col>;
3964 using InternalExtractorRow = internal::Extractor<dim, ExtractorType_Row>;
3965 using InternalExtractorCol = internal::Extractor<dim, ExtractorType_Col>;
3966 using HessianType = typename InternalHessian::type;
3967
3968 // NOTE: The order of components must be consistently defined throughout
3969 // this class.
3970 HessianType out;
3971
3972 // Get indexsets for the subblocks from which we wish to extract the
3973 // Hessian values
3974 // NOTE: Here we have to do some clever accounting when the
3975 // one extractor is a symmetric Tensor and the other is not, e.g.
3976 // <SymmTensor,Vector>. In this scenario the return type is a
3977 // non-symmetric Tensor<3,dim> but we have to fetch information from a
3978 // SymmTensor row/column that has too few entries to fill the output
3979 // tensor. So we must duplicate the relevant entries in the row/column
3980 // indexset to fetch off-diagonal components that are otherwise
3981 // non-existent in a SymmTensor.
3982 const std::vector<unsigned int> row_index_set(
3983 internal::extract_field_component_indices<dim>(
3984 extractor_row, false /*ignore_symmetries*/));
3985 const std::vector<unsigned int> col_index_set(
3986 internal::extract_field_component_indices<dim>(
3987 extractor_col, false /*ignore_symmetries*/));
3988
3989 for (unsigned int index = 0;
3990 index < HessianType::n_independent_components;
3991 ++index)
3992 {
3993 const TableIndices<HessianType::rank> ti_out =
3994 HessianType::unrolled_to_component_indices(index);
3995 const unsigned int r =
3996 InternalExtractorRow::local_component(ti_out, 0);
3997 const unsigned int c =
3998 InternalExtractorCol::local_component(ti_out,
3999 InternalExtractorRow::rank);
4000
4002 out, index, hessian[row_index_set[r]][col_index_set[c]]);
4003 }
4004
4005 return out;
4006 }
4007
4008
4009
4010 /* ----------------- VectorFunction ----------------- */
4011
4012
4013
4014 template <int dim,
4015 enum AD::NumberTypes ADNumberTypeCode,
4016 typename ScalarType>
4017 template <typename ValueType, typename ExtractorType>
4018 void
4020 register_dependent_variable(const ValueType &funcs,
4021 const ExtractorType &extractor)
4022 {
4023 const std::vector<unsigned int> index_set(
4024 internal::extract_field_component_indices<dim>(extractor));
4025 for (unsigned int i = 0; i < index_set.size(); ++i)
4026 {
4027 Assert(this->registered_marked_dependent_variables[index_set[i]] ==
4028 false,
4029 ExcMessage("Overlapping indices for dependent variables."));
4031 index_set[i], internal::get_tensor_entry(funcs, i));
4032 }
4033 }
4034
4035
4036
4037 template <int dim,
4038 enum AD::NumberTypes ADNumberTypeCode,
4039 typename ScalarType>
4040 template <typename ExtractorType_Row>
4042 dim,
4044 ExtractorType_Row>::type
4046 const Vector<scalar_type> &values,
4047 const ExtractorType_Row &extractor_row)
4048 {
4049 // NOTE: The order of components must be consistently defined throughout
4050 // this class.
4051 typename internal::VectorFieldValue<dim, scalar_type, ExtractorType_Row>::
4052 type out;
4053
4054 // Get indexsets for the subblock from which we wish to extract the
4055 // gradient values
4056 const std::vector<unsigned int> row_index_set(
4057 internal::extract_field_component_indices<dim>(extractor_row));
4058 Assert(out.n_independent_components == row_index_set.size(),
4059 ExcMessage("Not all tensor components have been extracted!"));
4060 for (unsigned int r = 0; r < row_index_set.size(); ++r)
4061 internal::set_tensor_entry(out, r, values[row_index_set[r]]);
4062
4063 return out;
4064 }
4065
4066
4067
4068 template <int dim,
4069 enum AD::NumberTypes ADNumberTypeCode,
4070 typename ScalarType>
4071 template <typename ExtractorType_Row, typename ExtractorType_Col>
4073 dim,
4075 ExtractorType_Row,
4076 ExtractorType_Col>::type
4079 const ExtractorType_Row &extractor_row,
4080 const ExtractorType_Col &extractor_col)
4081 {
4082 using InternalJacobian = internal::VectorFieldJacobian<dim,
4083 scalar_type,
4084 ExtractorType_Row,
4085 ExtractorType_Col>;
4086 using InternalExtractorRow = internal::Extractor<dim, ExtractorType_Row>;
4087 using InternalExtractorCol = internal::Extractor<dim, ExtractorType_Col>;
4088 using JacobianType = typename InternalJacobian::type;
4089
4090 // NOTE: The order of components must be consistently defined throughout
4091 // this class.
4092 JacobianType out;
4093
4094 // Get indexsets for the subblocks from which we wish to extract the
4095 // Hessian values.
4096 // NOTE: Here we have to do some clever accounting when the
4097 // one extractor is a symmetric Tensor and the other is not, e.g.
4098 // <SymmTensor,Vector>. In this scenario the return type is a
4099 // non-symmetric Tensor<3,dim> but we have to fetch information from a
4100 // SymmTensor row/column that has too few entries to fill the output
4101 // tensor. So we must duplicate the relevant entries in the row/column
4102 // indexset to fetch off-diagonal components that are otherwise
4103 // non-existent in a SymmTensor.
4104 const std::vector<unsigned int> row_index_set(
4105 internal::extract_field_component_indices<dim>(
4106 extractor_row, false /*ignore_symmetries*/));
4107 const std::vector<unsigned int> col_index_set(
4108 internal::extract_field_component_indices<dim>(
4109 extractor_col, false /*ignore_symmetries*/));
4110
4111 for (unsigned int index = 0;
4112 index < JacobianType::n_independent_components;
4113 ++index)
4114 {
4116 JacobianType::unrolled_to_component_indices(index);
4117 const unsigned int r =
4118 InternalExtractorRow::local_component(ti_out, 0);
4119 const unsigned int c =
4120 InternalExtractorCol::local_component(ti_out,
4121 InternalExtractorRow::rank);
4122
4124 out, index, jacobian[row_index_set[r]][col_index_set[c]]);
4125 }
4126
4127 return out;
4128 }
4129
4130
4131 } // namespace AD
4132} // namespace Differentiation
4133
4134
4135# endif // DOXYGEN
4136
4137
4139
4140#endif // defined(DEAL_II_WITH_ADOLC) || defined(DEAL_II_TRILINOS_WITH_SACADO)
4141
4142#endif // dealii_differentiation_ad_ad_helpers_h
void register_dof_values(const VectorType &values, const std::vector<::types::global_dof_index > &local_dof_indices)
const std::vector< ad_type > & get_sensitive_dof_values() const
typename HelperBase< ADNumberTypeCode, ScalarType >::ad_type ad_type
Definition ad_helpers.h:849
void set_dof_values(const std::vector< scalar_type > &dof_values)
virtual void compute_residual(Vector< scalar_type > &residual) const =0
void register_dof_values(const std::vector< scalar_type > &dof_values)
virtual void compute_linearization(FullMatrix< scalar_type > &linearization) const =0
void set_dof_values(const VectorType &values, const std::vector<::types::global_dof_index > &local_dof_indices)
typename HelperBase< ADNumberTypeCode, ScalarType >::scalar_type scalar_type
Definition ad_helpers.h:842
void register_energy_functional(const ad_type &energy)
typename HelperBase< ADNumberTypeCode, ScalarType >::ad_type ad_type
void compute_residual(Vector< scalar_type > &residual) const override
virtual void compute_linearization(FullMatrix< scalar_type > &linearization) const override
typename HelperBase< ADNumberTypeCode, ScalarType >::scalar_type scalar_type
unsigned int n_registered_dependent_variables() const
TapedDrivers< ad_type, scalar_type > taped_driver
Definition ad_helpers.h:590
void stop_recording_operations(const bool write_tapes_to_file=false)
std::vector< bool > registered_marked_independent_variables
Definition ad_helpers.h:656
typename AD::NumberTraits< ScalarType, ADNumberTypeCode >::scalar_type scalar_type
Definition ad_helpers.h:176
std::vector< bool > registered_independent_variable_values
Definition ad_helpers.h:650
Types< ad_type >::tape_index active_tape_index() const
void print_tape_stats(const typename Types< ad_type >::tape_index tape_index, std::ostream &stream) const
std::size_t n_independent_variables() const
bool start_recording_operations(const typename Types< ad_type >::tape_index tape_index, const bool overwrite_tape=false, const bool keep_independent_values=true)
std::vector< scalar_type > independent_variable_values
Definition ad_helpers.h:634
void mark_independent_variable(const unsigned int index, ad_type &out) const
bool is_registered_tape(const typename Types< ad_type >::tape_index tape_index) const
std::vector< bool > registered_marked_dependent_variables
Definition ad_helpers.h:753
void reset_registered_dependent_variables(const bool flag=false)
Definition ad_helpers.cc:93
void activate_tape(const typename Types< ad_type >::tape_index tape_index, const bool read_mode)
void set_tape_buffer_sizes(const typename Types< ad_type >::tape_buffer_sizes obufsize=64 *1024 *1024, const typename Types< ad_type >::tape_buffer_sizes lbufsize=64 *1024 *1024, const typename Types< ad_type >::tape_buffer_sizes vbufsize=64 *1024 *1024, const typename Types< ad_type >::tape_buffer_sizes tbufsize=64 *1024 *1024)
unsigned int n_registered_independent_variables() const
void print(std::ostream &stream) const
void set_sensitivity_value(const unsigned int index, const scalar_type &value)
bool active_tape_requires_retaping() const
std::vector< ad_type > independent_variables
Definition ad_helpers.h:644
virtual void reset(const unsigned int n_independent_variables=::numbers::invalid_unsigned_int, const unsigned int n_dependent_variables=::numbers::invalid_unsigned_int, const bool clear_registered_tapes=true)
TapelessDrivers< ad_type, scalar_type > tapeless_driver
Definition ad_helpers.h:598
bool recorded_tape_requires_retaping(const typename Types< ad_type >::tape_index tape_index) const
std::vector< ad_type > dependent_variables
Definition ad_helpers.h:748
std::size_t n_dependent_variables() const
void print_values(std::ostream &stream) const
void register_dependent_variable(const unsigned int index, const ad_type &func)
void finalize_sensitive_independent_variables() const
static void configure_tapeless_mode(const unsigned int n_independent_variables, const bool ensure_persistent_setting=true)
void initialize_non_sensitive_independent_variable(const unsigned int index, ad_type &out) const
typename AD::NumberTraits< ScalarType, ADNumberTypeCode >::ad_type ad_type
Definition ad_helpers.h:183
void activate_recorded_tape(const typename Types< ad_type >::tape_index tape_index)
void set_independent_variable(const ValueType &value, const ExtractorType &extractor)
bool is_symmetric_independent_variable(const unsigned int index) const
typename HelperBase< ADNumberTypeCode, ScalarType >::ad_type ad_type
static constexpr unsigned int dimension
void set_independent_variables(const std::vector< scalar_type > &values)
typename HelperBase< ADNumberTypeCode, ScalarType >::scalar_type scalar_type
unsigned int n_symmetric_independent_variables() const
void register_independent_variables(const std::vector< scalar_type > &values)
void set_sensitivity_value(const unsigned int index, const bool symmetric_component, const scalar_type &value)
void register_independent_variable(const ValueType &value, const ExtractorType &extractor)
const std::vector< ad_type > & get_sensitive_variables() const
virtual void reset(const unsigned int n_independent_variables=::numbers::invalid_unsigned_int, const unsigned int n_dependent_variables=::numbers::invalid_unsigned_int, const bool clear_registered_tapes=true) override
internal::Extractor< dim, ExtractorType >::template tensor_type< typename HelperBase< ADNumberTypeCode, ScalarType >::ad_type > get_sensitive_variables(const ExtractorType &extractor) const
typename HelperBase< ADNumberTypeCode, ScalarType >::scalar_type scalar_type
virtual void compute_residual(Vector< scalar_type > &residual) const override
virtual void compute_linearization(FullMatrix< scalar_type > &linearization) const override
typename HelperBase< ADNumberTypeCode, ScalarType >::ad_type ad_type
void register_residual_vector(const std::vector< ad_type > &residual)
static internal::ScalarFieldHessian< dim, scalar_type, ExtractorType_Row, ExtractorType_Col >::type extract_hessian_component(const FullMatrix< scalar_type > &hessian, const ExtractorType_Row &extractor_row, const ExtractorType_Col &extractor_col)
typename HelperBase< ADNumberTypeCode, ScalarType >::ad_type ad_type
void register_dependent_variable(const ad_type &func)
static internal::ScalarFieldGradient< dim, scalar_type, ExtractorType_Row >::type extract_gradient_component(const Vector< scalar_type > &gradient, const ExtractorType_Row &extractor_row)
void compute_gradient(Vector< scalar_type > &gradient) const
void compute_hessian(FullMatrix< scalar_type > &hessian) const
typename HelperBase< ADNumberTypeCode, ScalarType >::scalar_type scalar_type
typename HelperBase< ADNumberTypeCode, ScalarType >::ad_type ad_type
void compute_values(Vector< scalar_type > &values) const
void register_dependent_variables(const std::vector< ad_type > &funcs)
void compute_jacobian(FullMatrix< scalar_type > &jacobian) const
typename HelperBase< ADNumberTypeCode, ScalarType >::scalar_type scalar_type
static internal::VectorFieldJacobian< dim, scalar_type, ExtractorType_Row, ExtractorType_Col >::type extract_jacobian_component(const FullMatrix< scalar_type > &jacobian, const ExtractorType_Row &extractor_row, const ExtractorType_Col &extractor_col)
static internal::VectorFieldValue< dim, scalar_type, ExtractorType_Row >::type extract_value_component(const Vector< scalar_type > &values, const ExtractorType_Row &extractor_row)
void register_dependent_variable(const ValueType &funcs, const ExtractorType &extractor)
static DEAL_II_HOST constexpr unsigned int component_to_unrolled_index(const TableIndices< rank_ > &indices)
static constexpr TableIndices< rank_ > unrolled_to_component_indices(const unsigned int i)
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:502
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:503
#define Assert(cond, exc)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
static ::ExceptionBase & ExcMessage(std::string arg1)
ScalarFieldHessian< dim, NumberType, ExtractorType_Field, ExtractorType_Derivative > VectorFieldJacobian
NumberType get_tensor_entry(const TensorType< rank, dim, NumberType > &t, const unsigned int unrolled_index)
void set_tensor_entry(TensorType &t, const unsigned int unrolled_index, const NumberType &value)
std::vector< IndexType > extract_field_component_indices(const ExtractorType &extractor, const bool ignore_symmetries=true)
ScalarFieldGradient< dim, NumberType, ExtractorType_Field > VectorFieldValue
void set_dof_values(const DoFCellAccessor< dim, spacedim, lda > &cell, const Vector< number > &local_values, OutputVector &values, const bool perform_check)
static const unsigned int invalid_unsigned_int
Definition types.h:220
const InputIterator OutputIterator out
Definition parallel.h:167
static const Types< ADNumberType >::tape_index invalid_tape_index
Definition ad_drivers.h:119
static unsigned int first_component(const FEValuesExtractors::Scalar &extractor)
static IndexType local_component(const TableIndices< rank_in > &table_indices, const unsigned int column_offset)
static bool symmetric_component(const unsigned int unrolled_index)
static TableIndices< rank > table_index_view(const TableIndices< rank_in > &table_indices, const unsigned int column_offset)
static unsigned int first_component(const FEValuesExtractors::SymmetricTensor< 2 > &extractor)
static IndexType local_component(const TableIndices< rank_in > &table_indices, const unsigned int column_offset)
static TableIndices< rank > table_index_view(const TableIndices< rank_in > &table_indices, const unsigned int column_offset)
static unsigned int first_component(const FEValuesExtractors::Tensor< 1 > &extractor)
static IndexType local_component(const TableIndices< rank_in > &table_indices, const unsigned int column_offset)
static TableIndices< rank > table_index_view(const TableIndices< rank_in > &table_indices, const unsigned int column_offset)
static unsigned int first_component(const FEValuesExtractors::Tensor< 2 > &extractor)
static IndexType local_component(const TableIndices< rank_in > &table_indices, const unsigned int column_offset)
static bool symmetric_component(const unsigned int unrolled_index)
static IndexType local_component(const TableIndices< rank_in > &table_indices, const unsigned int column_offset)
static unsigned int first_component(const FEValuesExtractors::Vector &extractor)
static TableIndices< rank > table_index_view(const TableIndices< rank_in > &table_indices, const unsigned int column_offset)
typename Extractor< dim, ExtractorType >::template tensor_type< NumberType > type
typename HessianType< ExtractorType_Row, ExtractorType_Col >::template type< rank, dim, NumberType > type