Reference documentation for deal.II version 9.3.3
\(\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\}}\)
ad_helpers.h
Go to the documentation of this file.
1// ---------------------------------------------------------------------
2//
3// Copyright (C) 2016 - 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 at
12// the top level of the deal.II distribution.
13//
14// ---------------------------------------------------------------------
15
16#ifndef dealii_differentiation_ad_ad_helpers_h
17#define dealii_differentiation_ad_ad_helpers_h
18
19#include <deal.II/base/config.h>
20
21#if defined(DEAL_II_WITH_ADOLC) || defined(DEAL_II_TRILINOS_WITH_SACADO)
22
23# include <deal.II/base/numbers.h>
25# include <deal.II/base/tensor.h>
26
33
35
37# include <deal.II/lac/vector.h>
38
39# include <algorithm>
40# include <iostream>
41# include <iterator>
42# include <numeric>
43# include <set>
44
46
47namespace Differentiation
48{
49 namespace AD
50 {
168 template <enum AD::NumberTypes ADNumberTypeCode,
169 typename ScalarType = double>
171 {
172 public:
179
184 using ad_type =
186
191
206 HelperBase(const unsigned int n_independent_variables,
207 const unsigned int n_dependent_variables);
208
212 virtual ~HelperBase() = default;
213
215
220
225 std::size_t
227
232 std::size_t
233 n_dependent_variables() const;
234
243 void
244 print(std::ostream &stream) const;
245
252 void
253 print_values(std::ostream &stream) const;
254
265 void
266 print_tape_stats(const typename Types<ad_type>::tape_index tape_index,
267 std::ostream & stream) const;
268
270
275
294 static void
296 const bool ensure_persistent_setting = true);
297
299
304
340 virtual void
341 reset(const unsigned int n_independent_variables =
343 const unsigned int n_dependent_variables =
345 const bool clear_registered_tapes = true);
346
351 bool
352 is_recording() const;
353
359 active_tape_index() const;
360
365 bool
367 const typename Types<ad_type>::tape_index tape_index) const;
368
394 void
396 const typename Types<ad_type>::tape_buffer_sizes obufsize = 64 * 1024 *
397 1024,
398 const typename Types<ad_type>::tape_buffer_sizes lbufsize = 64 * 1024 *
399 1024,
400 const typename Types<ad_type>::tape_buffer_sizes vbufsize = 64 * 1024 *
401 1024,
402 const typename Types<ad_type>::tape_buffer_sizes tbufsize = 64 * 1024 *
403 1024);
404
450 bool
452 const typename Types<ad_type>::tape_index tape_index,
453 const bool overwrite_tape = false,
454 const bool keep_independent_values = true);
455
467 void
468 stop_recording_operations(const bool write_tapes_to_file = false);
469
479 void
481 const typename Types<ad_type>::tape_index tape_index);
482
522 bool
524 const typename Types<ad_type>::tape_index tape_index) const;
525
565 bool
567
575 void
577
579
580 protected:
585
593
601
618 void
619 activate_tape(const typename Types<ad_type>::tape_index tape_index,
620 const bool read_mode);
621
623
628
636 mutable std::vector<scalar_type> independent_variable_values;
637
646 mutable std::vector<ad_type> independent_variables;
647
653
659
665 void
667
674 void
675 set_sensitivity_value(const unsigned int index, const scalar_type &value);
676
695 void
696 mark_independent_variable(const unsigned int index, ad_type &out) const;
697
708 void
710
720 void
721 initialize_non_sensitive_independent_variable(const unsigned int index,
722 ad_type &out) const;
723
728 unsigned int
730
732
737
750 std::vector<ad_type> dependent_variables;
751
756
763 void
764 reset_registered_dependent_variables(const bool flag = false);
765
769 unsigned int
771
783 void
784 register_dependent_variable(const unsigned int index,
785 const ad_type & func);
786
788
789 }; // class HelperBase
790
791
792
834 template <enum AD::NumberTypes ADNumberTypeCode,
835 typename ScalarType = double>
836 class CellLevelBase : public HelperBase<ADNumberTypeCode, ScalarType>
837 {
838 public:
845
850 using ad_type =
852
857
872 CellLevelBase(const unsigned int n_independent_variables,
873 const unsigned int n_dependent_variables);
874
878 virtual ~CellLevelBase() = default;
879
881
886
904 void
905 register_dof_values(const std::vector<scalar_type> &dof_values);
906
925 template <typename VectorType>
926 void
928 const VectorType & values,
929 const std::vector<::types::global_dof_index> &local_dof_indices);
930
951 const std::vector<ad_type> &
953
955
960
980 void
981 set_dof_values(const std::vector<scalar_type> &dof_values);
982
1000 template <typename VectorType>
1001 void
1003 const VectorType & values,
1004 const std::vector<::types::global_dof_index> &local_dof_indices);
1005
1007
1012
1027 virtual void
1029
1047 virtual void
1049
1051
1052 }; // class CellLevelBase
1053
1054
1055
1216 template <enum AD::NumberTypes ADNumberTypeCode,
1217 typename ScalarType = double>
1218 class EnergyFunctional : public CellLevelBase<ADNumberTypeCode, ScalarType>
1219 {
1220 public:
1227
1232 using ad_type =
1234
1239
1255 EnergyFunctional(const unsigned int n_independent_variables);
1256
1260 virtual ~EnergyFunctional() = default;
1261
1263
1268
1282 void
1283 register_energy_functional(const ad_type &energy);
1284
1299 compute_energy() const;
1300
1320 void
1321 compute_residual(Vector<scalar_type> &residual) const override;
1322
1343 virtual void
1345 FullMatrix<scalar_type> &linearization) const override;
1346
1348
1349 }; // class EnergyFunctional
1350
1351
1352
1527 template <enum AD::NumberTypes ADNumberTypeCode,
1528 typename ScalarType = double>
1530 : public CellLevelBase<ADNumberTypeCode, ScalarType>
1531 {
1532 public:
1539
1544 using ad_type =
1546
1551
1567 const unsigned int n_dependent_variables);
1568
1572 virtual ~ResidualLinearization() = default;
1573
1575
1580
1594 void
1595 register_residual_vector(const std::vector<ad_type> &residual);
1596
1613 virtual void
1614 compute_residual(Vector<scalar_type> &residual) const override;
1615
1633 virtual void
1635 FullMatrix<scalar_type> &linearization) const override;
1636
1638
1639 }; // class ResidualLinearization
1640
1641
1642
1643 namespace internal
1644 {
1649 template <int dim, typename ExtractorType>
1651
1652
1658 template <int dim>
1659 struct Extractor<dim, FEValuesExtractors::Scalar>
1660 {
1664 static const unsigned int n_components = 1;
1665
1669 static const unsigned int rank = 0;
1670
1674 template <typename NumberType>
1676
1677 static_assert(
1679 "The number of components doesn't match that of the corresponding tensor type.");
1680 static_assert(
1682 "The rank doesn't match that of the corresponding tensor type.");
1683
1687 // Note: FEValuesViews::Scalar::tensor_type is double, so we can't
1688 // use it (FEValuesViews) in this context.
1689 // In fact, sadly, all FEValuesViews objects expect doubles as value
1690 // types.
1691 template <typename NumberType>
1693
1697 template <typename NumberType>
1699
1703 static inline unsigned int
1705 {
1706 return extractor.component;
1707 }
1708
1716 static bool
1717 symmetric_component(const unsigned int unrolled_index)
1718 {
1719 (void)unrolled_index;
1720 return false;
1721 }
1722
1730 template <typename IndexType = unsigned int, int rank_in>
1731 static IndexType
1733 const unsigned int column_offset)
1734 {
1735 Assert(column_offset <= rank_in, ExcInternalError());
1736 (void)table_indices;
1737 (void)column_offset;
1738 return 0;
1739 }
1740 };
1741
1742
1748 template <int dim>
1750 {
1754 static const unsigned int n_components = dim;
1755
1759 static const unsigned int rank = 1;
1760
1764 template <typename NumberType>
1766
1767 static_assert(
1769 "The number of components doesn't match that of the corresponding tensor type.");
1770 static_assert(
1772 "The rank doesn't match that of the corresponding tensor type.");
1773
1777 template <typename NumberType>
1779
1783 template <typename NumberType>
1785
1789 static inline unsigned int
1791 {
1792 return extractor.first_vector_component;
1793 }
1794
1803 static bool
1804 symmetric_component(const unsigned int unrolled_index)
1805 {
1806 (void)unrolled_index;
1807 return false;
1808 }
1809
1814 template <int rank_in>
1815 static TableIndices<rank>
1817 const unsigned int column_offset)
1818 {
1819 Assert(0 + column_offset < rank_in, ExcInternalError());
1820 return TableIndices<rank>(table_indices[column_offset]);
1821 }
1822
1838 template <typename IndexType = unsigned int, int rank_in>
1839 static IndexType
1841 const unsigned int column_offset)
1842 {
1843 static_assert(
1844 rank_in >= rank,
1845 "Cannot extract more table indices than the input table has!");
1846 using TensorType = tensor_type<double>;
1847 return TensorType::component_to_unrolled_index(
1848 table_index_view(table_indices, column_offset));
1849 }
1850 };
1851
1852
1858 template <int dim>
1860 {
1864 static const unsigned int n_components =
1866
1870 static const unsigned int rank = 1;
1871
1875 template <typename NumberType>
1877
1881 template <typename NumberType>
1883
1887 template <typename NumberType>
1889
1893 static inline unsigned int
1895 {
1896 return extractor.first_tensor_component;
1897 }
1898
1906 static bool
1907 symmetric_component(const unsigned int unrolled_index)
1908 {
1909 (void)unrolled_index;
1910 return false;
1911 }
1912
1917 template <int rank_in>
1918 static TableIndices<rank>
1920 const unsigned int column_offset)
1921 {
1922 Assert(column_offset < rank_in, ExcInternalError());
1923 return TableIndices<rank>(table_indices[column_offset]);
1924 }
1925
1941 template <typename IndexType = unsigned int, int rank_in>
1942 static IndexType
1944 const unsigned int column_offset)
1945 {
1946 static_assert(
1947 rank_in >= rank,
1948 "Cannot extract more table indices than the input table has!");
1949 using TensorType = tensor_type<double>;
1950 return TensorType::component_to_unrolled_index(
1951 table_index_view(table_indices, column_offset));
1952 }
1953 };
1954
1955
1961 template <int dim>
1963 {
1967 static const unsigned int n_components =
1969
1973 static const unsigned int rank = Tensor<2, dim>::rank;
1974
1978 template <typename NumberType>
1980
1984 template <typename NumberType>
1986
1990 template <typename NumberType>
1992
1996 static inline unsigned int
1998 {
1999 return extractor.first_tensor_component;
2000 }
2001
2009 static bool
2010 symmetric_component(const unsigned int unrolled_index)
2011 {
2012 (void)unrolled_index;
2013 return false;
2014 }
2015
2020 template <int rank_in>
2021 static TableIndices<rank>
2023 const unsigned int column_offset)
2024 {
2025 Assert(column_offset < rank_in, ExcInternalError());
2026 Assert(column_offset + 1 < rank_in, ExcInternalError());
2027 return TableIndices<rank>(table_indices[column_offset],
2028 table_indices[column_offset + 1]);
2029 }
2030
2046 template <typename IndexType = unsigned int, int rank_in>
2047 static IndexType
2049 const unsigned int column_offset)
2050 {
2051 static_assert(
2052 rank_in >= rank,
2053 "Cannot extract more table indices than the input table has!");
2054 using TensorType = tensor_type<double>;
2055 return TensorType::component_to_unrolled_index(
2056 table_index_view(table_indices, column_offset));
2057 }
2058 };
2059
2060
2066 template <int dim>
2068 {
2072 static const unsigned int n_components =
2074
2078 static const unsigned int rank = SymmetricTensor<2, dim>::rank;
2079
2083 template <typename NumberType>
2085
2089 template <typename NumberType>
2091
2095 template <typename NumberType>
2097
2101 static inline unsigned int
2103 {
2104 return extractor.first_tensor_component;
2105 }
2106
2115 static bool
2116 symmetric_component(const unsigned int unrolled_index)
2117 {
2118 const TableIndices<2> table_indices =
2120 return table_indices[0] != table_indices[1];
2121 }
2122
2127 template <int rank_in>
2128 static TableIndices<rank>
2130 const unsigned int column_offset)
2131 {
2132 Assert(column_offset < rank_in, ExcInternalError());
2133 Assert(column_offset + 1 < rank_in, ExcInternalError());
2134 return TableIndices<rank>(table_indices[column_offset],
2135 table_indices[column_offset + 1]);
2136 }
2137
2153 template <typename IndexType = unsigned int, int rank_in>
2154 static IndexType
2156 const unsigned int column_offset)
2157 {
2158 static_assert(
2159 rank_in >= rank,
2160 "Cannot extract more table indices than the input table has!");
2161 using TensorType = tensor_type<double>;
2162 return TensorType::component_to_unrolled_index(
2163 table_index_view(table_indices, column_offset));
2164 }
2165 };
2166
2167
2173 template <int dim, typename NumberType, typename ExtractorType>
2175 {
2180 using type =
2181 typename Extractor<dim,
2182 ExtractorType>::template tensor_type<NumberType>;
2183 };
2184
2185
2195 template <typename ExtractorType_Row, typename ExtractorType_Col>
2197 {
2209 template <int rank, int dim, typename NumberType>
2211 };
2212
2213
2222 template <>
2225 {
2233 template <int /*rank*/, int dim, typename NumberType>
2234 using type = SymmetricTensor<2 /*rank*/, dim, NumberType>;
2235 };
2236
2237
2246 template <>
2249 {
2258 template <int /*rank*/, int dim, typename NumberType>
2259 using type = SymmetricTensor<2 /*rank*/, dim, NumberType>;
2260 };
2261
2262
2270 template <>
2273 {
2282 template <int /*rank*/, int dim, typename NumberType>
2283 using type = SymmetricTensor<4 /*rank*/, dim, NumberType>;
2284 };
2285
2286
2296 template <int dim,
2297 typename NumberType,
2298 typename ExtractorType_Row,
2299 typename ExtractorType_Col>
2301 {
2307
2314 using type =
2317 };
2318
2319
2324 template <int dim, typename NumberType, typename ExtractorType_Field>
2327
2328
2338 template <int dim,
2339 typename NumberType,
2340 typename ExtractorType_Field,
2341 typename ExtractorType_Derivative>
2343 NumberType,
2344 ExtractorType_Field,
2345 ExtractorType_Derivative>;
2346
2347
2353 template <int dim,
2354 typename IndexType = unsigned int,
2355 typename ExtractorType>
2356 std::vector<IndexType>
2357 extract_field_component_indices(const ExtractorType &extractor,
2358 const bool ignore_symmetries = true)
2359 {
2360 (void)ignore_symmetries;
2361 const IndexType n_components =
2363 const IndexType comp_first =
2365 std::vector<IndexType> indices(n_components);
2366 std::iota(indices.begin(), indices.end(), comp_first);
2367 return indices;
2368 }
2369
2370
2379 template <int dim, typename IndexType = unsigned int>
2380 std::vector<IndexType>
2382 const FEValuesExtractors::SymmetricTensor<2> &extractor_symm_tensor,
2383 const bool ignore_symmetries = true)
2384 {
2385 using ExtractorType = FEValuesExtractors::SymmetricTensor<2>;
2386 const IndexType n_components =
2388 const IndexType comp_first =
2390 extractor_symm_tensor);
2391
2392 if (ignore_symmetries == true)
2393 {
2394 std::vector<IndexType> indices(n_components);
2395 std::iota(indices.begin(), indices.end(), comp_first);
2396 return indices;
2397 }
2398 else
2399 {
2400 // First get all of the indices of the non-symmetric tensor
2401 const FEValuesExtractors::Tensor<2> extractor_tensor(
2402 extractor_symm_tensor.first_tensor_component);
2403 std::vector<IndexType> indices =
2404 extract_field_component_indices<dim>(extractor_tensor, true);
2405
2406 // Then we overwrite any illegal entries with the equivalent indices
2407 // from the symmetric tensor
2408 for (unsigned int i = 0; i < indices.size(); ++i)
2409 {
2410 // The indices stored in the vector start with the extractor's
2411 // first_component_index. We need to account for this when
2412 // retrieving the tensor (local) index.
2413 const IndexType local_index_i = indices[i] - comp_first;
2414 if (local_index_i >= n_components)
2415 {
2416 const TableIndices<2> ti_tensor =
2418 local_index_i);
2419 const IndexType sti_new_index =
2421 ti_tensor);
2422 indices[i] = comp_first + sti_new_index;
2423 }
2424 }
2425
2426 return indices;
2427 }
2428 }
2429
2430
2435 template <typename TensorType, typename NumberType>
2436 inline void
2437 set_tensor_entry(TensorType & t,
2438 const unsigned int unrolled_index,
2439 const NumberType & value)
2440 {
2441 // Where possible, set values using TableIndices
2442 AssertIndexRange(unrolled_index, t.n_independent_components);
2443 t[TensorType::unrolled_to_component_indices(unrolled_index)] = value;
2444 }
2445
2446
2451 template <int dim, typename NumberType>
2453 const unsigned int unrolled_index,
2454 const NumberType & value)
2455 {
2456 AssertIndexRange(unrolled_index, 1);
2457 (void)unrolled_index;
2458 t = value;
2459 }
2460
2461
2467 template <typename NumberType>
2468 inline void
2470 const unsigned int unrolled_index,
2471 const NumberType & value)
2472 {
2473 AssertIndexRange(unrolled_index, 1);
2474 (void)unrolled_index;
2475 t = value;
2476 }
2477
2478
2484 template <int dim, typename NumberType>
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> class TensorType>
2514 inline NumberType
2515 get_tensor_entry(const TensorType<rank, dim, NumberType> &t,
2516 const unsigned int unrolled_index)
2517 {
2518 // Where possible, get values using TableIndices
2519 AssertIndexRange(unrolled_index, t.n_independent_components);
2520 return t[TensorType<rank, dim, NumberType>::
2521 unrolled_to_component_indices(unrolled_index)];
2522 }
2523
2524
2529 template <int dim,
2530 typename NumberType,
2531 template <int, int, typename> class TensorType>
2532 inline NumberType
2533 get_tensor_entry(const TensorType<0, dim, NumberType> &t,
2534 const unsigned int unrolled_index)
2535 {
2536 AssertIndexRange(unrolled_index, 1);
2537 (void)unrolled_index;
2538 return t;
2539 }
2540
2541
2547 template <typename NumberType>
2548 inline const NumberType &
2549 get_tensor_entry(const NumberType &t, const unsigned int unrolled_index)
2550 {
2551 AssertIndexRange(unrolled_index, 1);
2552 (void)unrolled_index;
2553 return t;
2554 }
2555
2556
2561 template <int rank,
2562 int dim,
2563 typename NumberType,
2564 template <int, int, typename> class TensorType>
2565 inline NumberType &
2566 get_tensor_entry(TensorType<rank, dim, NumberType> &t,
2567 const unsigned int unrolled_index)
2568 {
2569 // Where possible, get values using TableIndices
2570 AssertIndexRange(unrolled_index, t.n_independent_components);
2571 return t[TensorType<rank, dim, NumberType>::
2572 unrolled_to_component_indices(unrolled_index)];
2573 }
2574
2575
2580 template <int dim,
2581 typename NumberType,
2582 template <int, int, typename> class TensorType>
2583 NumberType &get_tensor_entry(TensorType<0, dim, NumberType> &t,
2584 const unsigned int index)
2585 {
2586 AssertIndexRange(index, 1);
2587 (void)index;
2588 return t;
2589 }
2590
2591
2597 template <typename NumberType>
2598 inline NumberType &
2599 get_tensor_entry(NumberType &t, const unsigned int index)
2600 {
2601 AssertIndexRange(index, 1);
2602 (void)index;
2603 return t;
2604 }
2605
2606 } // namespace internal
2607
2608
2609
2631 template <int dim,
2632 enum AD::NumberTypes ADNumberTypeCode,
2633 typename ScalarType = double>
2635 : public HelperBase<ADNumberTypeCode, ScalarType>
2636 {
2637 public:
2642 static const unsigned int dimension = dim;
2643
2650
2655 using ad_type =
2657
2662
2678 const unsigned int n_dependent_variables);
2679
2683 virtual ~PointLevelFunctionsBase() = default;
2684
2686
2691
2695 virtual void
2696 reset(const unsigned int n_independent_variables =
2698 const unsigned int n_dependent_variables =
2700 const bool clear_registered_tapes = true) override;
2701
2717 void
2718 register_independent_variables(const std::vector<scalar_type> &values);
2719
2748 template <typename ValueType, typename ExtractorType>
2749 void
2750 register_independent_variable(const ValueType & value,
2751 const ExtractorType &extractor);
2752
2773 const std::vector<ad_type> &
2775
2776 /*
2777 * Extract a subset of the independent variables as represented by
2778 * auto-differentiable numbers. These are the independent
2779 * variables @f$\mathbf{A} \subset \mathbf{X}@f$ at which the dependent values
2780 * are evaluated and differentiated.
2781 *
2782 * This function indicates to the AD library that implements the
2783 * auto-differentiable number type that operations performed on these
2784 * numbers are to be tracked so they are considered "sensitive"
2785 * variables. This is, therefore, the set of variables with which one
2786 * would then perform computations, and based on which one can then
2787 * extract both the value of the function and its derivatives with the
2788 * member functions below. The values of the components of the returned
2789 * object are initialized to the values set with
2790 * register_independent_variable().
2791 *
2792 * @param[in] extractor An extractor associated with the input field
2793 * variables. This effectively defines which components of the global set
2794 * of independent variables this field is associated with.
2795 * @return An object of auto-differentiable type numbers. The return type is
2796 * based on the input extractor, and will be either a scalar,
2797 * Tensor<1,dim>, Tensor<2,dim>, or SymmetricTensor<2,dim>.
2798 *
2799 * @note For taped AD numbers, this operation is only valid in recording mode.
2800 */
2801 template <typename ExtractorType>
2802 typename internal::Extractor<dim,
2803 ExtractorType>::template tensor_type<ad_type>
2804 get_sensitive_variables(const ExtractorType &extractor) const;
2805
2807
2812
2830 void
2831 set_independent_variables(const std::vector<scalar_type> &values);
2832
2859 template <typename ValueType, typename ExtractorType>
2860 void
2861 set_independent_variable(const ValueType & value,
2862 const ExtractorType &extractor);
2863
2865
2866 protected:
2871
2882 void
2883 set_sensitivity_value(const unsigned int index,
2884 const bool symmetric_component,
2885 const scalar_type &value);
2886
2892 bool
2893 is_symmetric_independent_variable(const unsigned int index) const;
2894
2899 unsigned int
2901
2903
2904 private:
2909
2915
2917
2918 }; // class PointLevelFunctionsBase
2919
2920
2921
3076 template <int dim,
3077 enum AD::NumberTypes ADNumberTypeCode,
3078 typename ScalarType = double>
3080 : public PointLevelFunctionsBase<dim, ADNumberTypeCode, ScalarType>
3081 {
3082 public:
3089
3094 using ad_type =
3096
3101
3111 ScalarFunction(const unsigned int n_independent_variables);
3112
3116 virtual ~ScalarFunction() = default;
3117
3119
3124
3136 void
3138
3147 compute_value() const;
3148
3161 void
3162 compute_gradient(Vector<scalar_type> &gradient) const;
3163
3178 void
3180
3215 template <typename ExtractorType_Row>
3216 static typename internal::
3219 const ExtractorType_Row & extractor_row);
3220
3259 template <typename ExtractorType_Row, typename ExtractorType_Col>
3260 static typename internal::ScalarFieldHessian<dim,
3262 ExtractorType_Row,
3263 ExtractorType_Col>::type
3265 const ExtractorType_Row & extractor_row,
3266 const ExtractorType_Col & extractor_col);
3267
3283 const FullMatrix<scalar_type> & hessian,
3284 const FEValuesExtractors::Scalar &extractor_row,
3285 const FEValuesExtractors::Scalar &extractor_col);
3286
3300 const FullMatrix<scalar_type> & hessian,
3301 const FEValuesExtractors::SymmetricTensor<2> &extractor_row,
3302 const FEValuesExtractors::SymmetricTensor<2> &extractor_col);
3303
3305
3306 }; // class ScalarFunction
3307
3308
3309
3467 template <int dim,
3468 enum AD::NumberTypes ADNumberTypeCode,
3469 typename ScalarType = double>
3471 : public PointLevelFunctionsBase<dim, ADNumberTypeCode, ScalarType>
3472 {
3473 public:
3480
3485 using ad_type =
3487
3492
3507 VectorFunction(const unsigned int n_independent_variables,
3508 const unsigned int n_dependent_variables);
3509
3513 virtual ~VectorFunction() = default;
3514
3516
3521
3534 void
3535 register_dependent_variables(const std::vector<ad_type> &funcs);
3536
3555 template <typename ValueType, typename ExtractorType>
3556 void
3557 register_dependent_variable(const ValueType & funcs,
3558 const ExtractorType &extractor);
3559
3568 void
3570
3585 void
3587
3588
3601 template <typename ExtractorType_Row>
3602 static typename internal::
3605 const ExtractorType_Row & extractor_row);
3606
3654 template <typename ExtractorType_Row, typename ExtractorType_Col>
3655 static typename internal::VectorFieldJacobian<dim,
3657 ExtractorType_Row,
3658 ExtractorType_Col>::type
3660 const ExtractorType_Row & extractor_row,
3661 const ExtractorType_Col & extractor_col);
3662
3680 const FullMatrix<scalar_type> & jacobian,
3681 const FEValuesExtractors::Scalar &extractor_row,
3682 const FEValuesExtractors::Scalar &extractor_col);
3683
3699 const FullMatrix<scalar_type> & jacobian,
3700 const FEValuesExtractors::SymmetricTensor<2> &extractor_row,
3701 const FEValuesExtractors::SymmetricTensor<2> &extractor_col);
3702
3704
3705 }; // class VectorFunction
3706
3707
3708 } // namespace AD
3709} // namespace Differentiation
3710
3711
3712/* ----------------- inline and template functions ----------------- */
3713
3714
3715# ifndef DOXYGEN
3716
3717namespace Differentiation
3718{
3719 namespace AD
3720 {
3721 /* ----------------- CellLevelBase ----------------- */
3722
3723
3724
3725 template <enum AD::NumberTypes ADNumberTypeCode, typename ScalarType>
3726 template <typename VectorType>
3727 void
3729 const VectorType & values,
3730 const std::vector<::types::global_dof_index> &local_dof_indices)
3731 {
3732 // This is actually the same thing the set_dof_values() function,
3733 // in the sense that we simply populate our array of independent values
3734 // with a meaningful number. However, in this case we need to double check
3735 // that we're not registering these variables twice
3736 Assert(
3737 local_dof_indices.size() == this->n_independent_variables(),
3738 ExcMessage(
3739 "Degree of freedom index vector size does not match number of independent variables"));
3740 for (unsigned int i = 0; i < this->n_independent_variables(); ++i)
3741 {
3742 Assert(this->registered_independent_variable_values[i] == false,
3743 ExcMessage("Independent variables already registered."));
3744 }
3745 set_dof_values(values, local_dof_indices);
3746 }
3747
3748
3749
3750 template <enum AD::NumberTypes ADNumberTypeCode, typename ScalarType>
3751 template <typename VectorType>
3752 void
3754 const VectorType & values,
3755 const std::vector<::types::global_dof_index> &local_dof_indices)
3756 {
3757 Assert(local_dof_indices.size() == this->n_independent_variables(),
3758 ExcMessage(
3759 "Vector size does not match number of independent variables"));
3760 for (unsigned int i = 0; i < this->n_independent_variables(); ++i)
3762 i, values[local_dof_indices[i]]);
3763 }
3764
3765
3766
3767 /* ----------------- PointLevelFunctionsBase ----------------- */
3768
3769
3770
3771 template <int dim,
3772 enum AD::NumberTypes ADNumberTypeCode,
3773 typename ScalarType>
3774 template <typename ValueType, typename ExtractorType>
3775 void
3777 register_independent_variable(const ValueType & value,
3778 const ExtractorType &extractor)
3779 {
3780 // This is actually the same thing as the set_independent_variable
3781 // function, in the sense that we simply populate our array of independent
3782 // values with a meaningful number. However, in this case we need to
3783 // double check that we're not registering these variables twice
3784# ifdef DEBUG
3785 const std::vector<unsigned int> index_set(
3786 internal::extract_field_component_indices<dim>(extractor));
3787 for (const unsigned int index : index_set)
3788 {
3789 Assert(
3790 this->registered_independent_variable_values[index] == false,
3791 ExcMessage(
3792 "Overlapping indices for independent variables. "
3793 "One or more indices associated with the field that "
3794 "is being registered as an independent variable have "
3795 "already been associated with another field. This suggests "
3796 "that the component offsets used to construct their counterpart "
3797 "extractors are incompatible with one another. Make sure that "
3798 "the first component for each extractor properly takes into "
3799 "account the dimensionality of the preceding fields."));
3800 }
3801# endif
3802 set_independent_variable(value, extractor);
3803 }
3804
3805
3806
3807 template <int dim,
3808 enum AD::NumberTypes ADNumberTypeCode,
3809 typename ScalarType>
3810 template <typename ValueType, typename ExtractorType>
3811 void
3813 set_independent_variable(const ValueType & value,
3814 const ExtractorType &extractor)
3815 {
3816 const std::vector<unsigned int> index_set(
3817 internal::extract_field_component_indices<dim>(extractor));
3818 for (unsigned int i = 0; i < index_set.size(); ++i)
3819 {
3820 set_sensitivity_value(
3821 index_set[i],
3822 internal::Extractor<dim, ExtractorType>::symmetric_component(i),
3823 internal::get_tensor_entry(value, i));
3824 }
3825 }
3826
3827
3828
3829 template <int dim,
3830 enum AD::NumberTypes ADNumberTypeCode,
3831 typename ScalarType>
3832 template <typename ExtractorType>
3833 typename internal::Extractor<dim, ExtractorType>::template tensor_type<
3834 typename PointLevelFunctionsBase<dim, ADNumberTypeCode, ScalarType>::
3835 ad_type>
3837 get_sensitive_variables(const ExtractorType &extractor) const
3838 {
3839 if (ADNumberTraits<ad_type>::is_taped == true)
3840 {
3841 Assert(this->active_tape_index() !=
3843 ExcMessage("Invalid tape index"));
3844 }
3845
3846 // If necessary, finalize the internally stored vector of
3847 // AD numbers that represents the independent variables
3848 this->finalize_sensitive_independent_variables();
3849 Assert(this->independent_variables.size() ==
3850 this->n_independent_variables(),
3851 ExcDimensionMismatch(this->independent_variables.size(),
3852 this->n_independent_variables()));
3853
3854 const std::vector<unsigned int> index_set(
3855 internal::extract_field_component_indices<dim>(extractor));
3856 typename internal::Extractor<dim,
3857 ExtractorType>::template tensor_type<ad_type>
3858 out;
3859
3860 for (unsigned int i = 0; i < index_set.size(); ++i)
3861 {
3862 const unsigned int index = index_set[i];
3863 Assert(index < this->n_independent_variables(), ExcInternalError());
3864 Assert(this->registered_independent_variable_values[index] == true,
3867 this->independent_variables[index];
3868 }
3869
3870 return out;
3871 }
3872
3873
3874
3875 /* ----------------- ScalarFunction ----------------- */
3876
3877
3878
3879 template <int dim,
3880 enum AD::NumberTypes ADNumberTypeCode,
3881 typename ScalarType>
3882 template <typename ExtractorType_Row>
3883 typename internal::ScalarFieldGradient<
3884 dim,
3886 ExtractorType_Row>::type
3889 const ExtractorType_Row & extractor_row)
3890 {
3891 // NOTE: The order of components must be consistently defined throughout
3892 // this class.
3893 typename internal::
3895
3896 // Get indexsets for the subblock from which we wish to extract the
3897 // gradient values
3898 const std::vector<unsigned int> row_index_set(
3899 internal::extract_field_component_indices<dim>(extractor_row));
3900 Assert(out.n_independent_components == row_index_set.size(),
3901 ExcMessage("Not all tensor components have been extracted!"));
3902 for (unsigned int r = 0; r < row_index_set.size(); ++r)
3903 internal::set_tensor_entry(out, r, gradient[row_index_set[r]]);
3904
3905 return out;
3906 }
3907
3908
3909
3910 template <int dim,
3911 enum AD::NumberTypes ADNumberTypeCode,
3912 typename ScalarType>
3913 template <typename ExtractorType_Row, typename ExtractorType_Col>
3914 typename internal::ScalarFieldHessian<
3915 dim,
3917 ExtractorType_Row,
3918 ExtractorType_Col>::type
3921 const ExtractorType_Row & extractor_row,
3922 const ExtractorType_Col & extractor_col)
3923 {
3924 using InternalHessian = internal::ScalarFieldHessian<dim,
3925 scalar_type,
3926 ExtractorType_Row,
3927 ExtractorType_Col>;
3928 using InternalExtractorRow = internal::Extractor<dim, ExtractorType_Row>;
3929 using InternalExtractorCol = internal::Extractor<dim, ExtractorType_Col>;
3930 using HessianType = typename InternalHessian::type;
3931
3932 // NOTE: The order of components must be consistently defined throughout
3933 // this class.
3934 HessianType out;
3935
3936 // Get indexsets for the subblocks from which we wish to extract the
3937 // Hessian values
3938 // NOTE: Here we have to do some clever accounting when the
3939 // one extractor is a symmetric Tensor and the other is not, e.g.
3940 // <SymmTensor,Vector>. In this scenario the return type is a
3941 // non-symmetric Tensor<3,dim> but we have to fetch information from a
3942 // SymmTensor row/column that has too few entries to fill the output
3943 // tensor. So we must duplicate the relevant entries in the row/column
3944 // indexset to fetch off-diagonal components that are otherwise
3945 // non-existent in a SymmTensor.
3946 const std::vector<unsigned int> row_index_set(
3947 internal::extract_field_component_indices<dim>(
3948 extractor_row, false /*ignore_symmetries*/));
3949 const std::vector<unsigned int> col_index_set(
3950 internal::extract_field_component_indices<dim>(
3951 extractor_col, false /*ignore_symmetries*/));
3952
3953 for (unsigned int index = 0;
3954 index < HessianType::n_independent_components;
3955 ++index)
3956 {
3957 const TableIndices<HessianType::rank> ti_out =
3958 HessianType::unrolled_to_component_indices(index);
3959 const unsigned int r =
3960 InternalExtractorRow::local_component(ti_out, 0);
3961 const unsigned int c =
3962 InternalExtractorCol::local_component(ti_out,
3963 InternalExtractorRow::rank);
3964
3966 out, index, hessian[row_index_set[r]][col_index_set[c]]);
3967 }
3968
3969 return out;
3970 }
3971
3972
3973
3974 /* ----------------- VectorFunction ----------------- */
3975
3976
3977
3978 template <int dim,
3979 enum AD::NumberTypes ADNumberTypeCode,
3980 typename ScalarType>
3981 template <typename ValueType, typename ExtractorType>
3982 void
3984 register_dependent_variable(const ValueType & funcs,
3985 const ExtractorType &extractor)
3986 {
3987 const std::vector<unsigned int> index_set(
3988 internal::extract_field_component_indices<dim>(extractor));
3989 for (unsigned int i = 0; i < index_set.size(); ++i)
3990 {
3991 Assert(this->registered_marked_dependent_variables[index_set[i]] ==
3992 false,
3993 ExcMessage("Overlapping indices for dependent variables."));
3995 index_set[i], internal::get_tensor_entry(funcs, i));
3996 }
3997 }
3998
3999
4000
4001 template <int dim,
4002 enum AD::NumberTypes ADNumberTypeCode,
4003 typename ScalarType>
4004 template <typename ExtractorType_Row>
4006 dim,
4008 ExtractorType_Row>::type
4011 const ExtractorType_Row & extractor_row)
4012 {
4013 // NOTE: The order of components must be consistently defined throughout
4014 // this class.
4015 typename internal::VectorFieldValue<dim, scalar_type, ExtractorType_Row>::
4016 type out;
4017
4018 // Get indexsets for the subblock from which we wish to extract the
4019 // gradient values
4020 const std::vector<unsigned int> row_index_set(
4021 internal::extract_field_component_indices<dim>(extractor_row));
4022 Assert(out.n_independent_components == row_index_set.size(),
4023 ExcMessage("Not all tensor components have been extracted!"));
4024 for (unsigned int r = 0; r < row_index_set.size(); ++r)
4025 internal::set_tensor_entry(out, r, values[row_index_set[r]]);
4026
4027 return out;
4028 }
4029
4030
4031
4032 template <int dim,
4033 enum AD::NumberTypes ADNumberTypeCode,
4034 typename ScalarType>
4035 template <typename ExtractorType_Row, typename ExtractorType_Col>
4037 dim,
4039 ExtractorType_Row,
4040 ExtractorType_Col>::type
4043 const ExtractorType_Row & extractor_row,
4044 const ExtractorType_Col & extractor_col)
4045 {
4046 using InternalJacobian = internal::VectorFieldJacobian<dim,
4047 scalar_type,
4048 ExtractorType_Row,
4049 ExtractorType_Col>;
4050 using InternalExtractorRow = internal::Extractor<dim, ExtractorType_Row>;
4051 using InternalExtractorCol = internal::Extractor<dim, ExtractorType_Col>;
4052 using JacobianType = typename InternalJacobian::type;
4053
4054 // NOTE: The order of components must be consistently defined throughout
4055 // this class.
4056 JacobianType out;
4057
4058 // Get indexsets for the subblocks from which we wish to extract the
4059 // Hessian values.
4060 // NOTE: Here we have to do some clever accounting when the
4061 // one extractor is a symmetric Tensor and the other is not, e.g.
4062 // <SymmTensor,Vector>. In this scenario the return type is a
4063 // non-symmetric Tensor<3,dim> but we have to fetch information from a
4064 // SymmTensor row/column that has too few entries to fill the output
4065 // tensor. So we must duplicate the relevant entries in the row/column
4066 // indexset to fetch off-diagonal components that are otherwise
4067 // non-existent in a SymmTensor.
4068 const std::vector<unsigned int> row_index_set(
4069 internal::extract_field_component_indices<dim>(
4070 extractor_row, false /*ignore_symmetries*/));
4071 const std::vector<unsigned int> col_index_set(
4072 internal::extract_field_component_indices<dim>(
4073 extractor_col, false /*ignore_symmetries*/));
4074
4075 for (unsigned int index = 0;
4076 index < JacobianType::n_independent_components;
4077 ++index)
4078 {
4080 JacobianType::unrolled_to_component_indices(index);
4081 const unsigned int r =
4082 InternalExtractorRow::local_component(ti_out, 0);
4083 const unsigned int c =
4084 InternalExtractorCol::local_component(ti_out,
4085 InternalExtractorRow::rank);
4086
4088 out, index, jacobian[row_index_set[r]][col_index_set[c]]);
4089 }
4090
4091 return out;
4092 }
4093
4094
4095 } // namespace AD
4096} // namespace Differentiation
4097
4098
4099# endif // DOXYGEN
4100
4101
4103
4104#endif // defined(DEAL_II_WITH_ADOLC) || defined(DEAL_II_TRILINOS_WITH_SACADO)
4105
4106#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
Definition: ad_helpers.cc:749
typename HelperBase< ADNumberTypeCode, ScalarType >::ad_type ad_type
Definition: ad_helpers.h:851
void set_dof_values(const std::vector< scalar_type > &dof_values)
Definition: ad_helpers.cc:774
virtual void compute_residual(Vector< scalar_type > &residual) const =0
void register_dof_values(const std::vector< scalar_type > &dof_values)
Definition: ad_helpers.cc:726
virtual void compute_linearization(FullMatrix< scalar_type > &linearization) const =0
CellLevelBase(const unsigned int n_independent_variables, const unsigned int n_dependent_variables)
Definition: ad_helpers.cc:715
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:844
void register_energy_functional(const ad_type &energy)
Definition: ad_helpers.cc:807
EnergyFunctional(const unsigned int n_independent_variables)
Definition: ad_helpers.cc:798
typename HelperBase< ADNumberTypeCode, ScalarType >::ad_type ad_type
Definition: ad_helpers.h:1233
void compute_residual(Vector< scalar_type > &residual) const override
Definition: ad_helpers.cc:873
virtual void compute_linearization(FullMatrix< scalar_type > &linearization) const override
Definition: ad_helpers.cc:938
typename HelperBase< ADNumberTypeCode, ScalarType >::scalar_type scalar_type
Definition: ad_helpers.h:1226
unsigned int n_registered_dependent_variables() const
Definition: ad_helpers.cc:250
TapedDrivers< ad_type, scalar_type > taped_driver
Definition: ad_helpers.h:592
void stop_recording_operations(const bool write_tapes_to_file=false)
Definition: ad_helpers.cc:648
std::vector< bool > registered_marked_independent_variables
Definition: ad_helpers.h:658
typename AD::NumberTraits< ScalarType, ADNumberTypeCode >::scalar_type scalar_type
Definition: ad_helpers.h:178
std::vector< bool > registered_independent_variable_values
Definition: ad_helpers.h:652
Types< ad_type >::tape_index active_tape_index() const
Definition: ad_helpers.cc:284
void print_tape_stats(const typename Types< ad_type >::tape_index tape_index, std::ostream &stream) const
Definition: ad_helpers.cc:378
std::size_t n_independent_variables() const
Definition: ad_helpers.cc:241
bool start_recording_operations(const typename Types< ad_type >::tape_index tape_index, const bool overwrite_tape=false, const bool keep_independent_values=true)
Definition: ad_helpers.cc:583
std::vector< scalar_type > independent_variable_values
Definition: ad_helpers.h:636
void mark_independent_variable(const unsigned int index, ad_type &out) const
Definition: ad_helpers.cc:142
bool is_registered_tape(const typename Types< ad_type >::tape_index tape_index) const
Definition: ad_helpers.cc:296
std::vector< bool > registered_marked_dependent_variables
Definition: ad_helpers.h:755
void reset_registered_dependent_variables(const bool flag=false)
Definition: ad_helpers.cc:94
void activate_tape(const typename Types< ad_type >::tape_index tape_index, const bool read_mode)
Definition: ad_helpers.cc:527
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)
Definition: ad_helpers.cc:564
unsigned int n_registered_independent_variables() const
Definition: ad_helpers.cc:230
void print(std::ostream &stream) const
Definition: ad_helpers.cc:309
void set_sensitivity_value(const unsigned int index, const scalar_type &value)
Definition: ad_helpers.cc:105
bool active_tape_requires_retaping() const
Definition: ad_helpers.cc:502
std::vector< ad_type > independent_variables
Definition: ad_helpers.h:646
HelperBase(const unsigned int n_independent_variables, const unsigned int n_dependent_variables)
Definition: ad_helpers.cc:38
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)
Definition: ad_helpers.cc:395
TapelessDrivers< ad_type, scalar_type > tapeless_driver
Definition: ad_helpers.h:600
bool recorded_tape_requires_retaping(const typename Types< ad_type >::tape_index tape_index) const
Definition: ad_helpers.cc:489
std::vector< ad_type > dependent_variables
Definition: ad_helpers.h:750
std::size_t n_dependent_variables() const
Definition: ad_helpers.cc:262
void print_values(std::ostream &stream) const
Definition: ad_helpers.cc:364
void register_dependent_variable(const unsigned int index, const ad_type &func)
Definition: ad_helpers.cc:684
void finalize_sensitive_independent_variables() const
Definition: ad_helpers.cc:181
static void configure_tapeless_mode(const unsigned int n_independent_variables, const bool ensure_persistent_setting=true)
Definition: ad_helpers.cc:453
void initialize_non_sensitive_independent_variable(const unsigned int index, ad_type &out) const
Definition: ad_helpers.cc:205
typename AD::NumberTraits< ScalarType, ADNumberTypeCode >::ad_type ad_type
Definition: ad_helpers.h:185
void activate_recorded_tape(const typename Types< ad_type >::tape_index tape_index)
Definition: ad_helpers.cc:479
void set_independent_variable(const ValueType &value, const ExtractorType &extractor)
bool is_symmetric_independent_variable(const unsigned int index) const
Definition: ad_helpers.cc:1197
typename HelperBase< ADNumberTypeCode, ScalarType >::ad_type ad_type
Definition: ad_helpers.h:2656
PointLevelFunctionsBase(const unsigned int n_independent_variables, const unsigned int n_dependent_variables)
Definition: ad_helpers.cc:1160
void set_independent_variables(const std::vector< scalar_type > &values)
Definition: ad_helpers.cc:1301
typename HelperBase< ADNumberTypeCode, ScalarType >::scalar_type scalar_type
Definition: ad_helpers.h:2649
std::vector< bool > symmetric_independent_variables
Definition: ad_helpers.h:2914
unsigned int n_symmetric_independent_variables() const
Definition: ad_helpers.cc:1211
void register_independent_variables(const std::vector< scalar_type > &values)
Definition: ad_helpers.cc:1225
void set_sensitivity_value(const unsigned int index, const bool symmetric_component, const scalar_type &value)
Definition: ad_helpers.cc:1279
void register_independent_variable(const ValueType &value, const ExtractorType &extractor)
internal::Extractor< dim, ExtractorType >::template tensor_type< ad_type > get_sensitive_variables(const ExtractorType &extractor) const
const std::vector< ad_type > & get_sensitive_variables() const
Definition: ad_helpers.cc:1251
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
Definition: ad_helpers.cc:1173
ResidualLinearization(const unsigned int n_independent_variables, const unsigned int n_dependent_variables)
Definition: ad_helpers.cc:1011
typename HelperBase< ADNumberTypeCode, ScalarType >::scalar_type scalar_type
Definition: ad_helpers.h:1538
virtual void compute_residual(Vector< scalar_type > &residual) const override
Definition: ad_helpers.cc:1037
virtual void compute_linearization(FullMatrix< scalar_type > &linearization) const override
Definition: ad_helpers.cc:1091
typename HelperBase< ADNumberTypeCode, ScalarType >::ad_type ad_type
Definition: ad_helpers.h:1545
void register_residual_vector(const std::vector< ad_type > &residual)
Definition: ad_helpers.cc:1023
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
Definition: ad_helpers.h:3095
void register_dependent_variable(const ad_type &func)
Definition: ad_helpers.cc:1340
static internal::ScalarFieldGradient< dim, scalar_type, ExtractorType_Row >::type extract_gradient_component(const Vector< scalar_type > &gradient, const ExtractorType_Row &extractor_row)
ScalarFunction(const unsigned int n_independent_variables)
Definition: ad_helpers.cc:1326
void compute_gradient(Vector< scalar_type > &gradient) const
Definition: ad_helpers.cc:1403
void compute_hessian(FullMatrix< scalar_type > &hessian) const
Definition: ad_helpers.cc:1477
typename HelperBase< ADNumberTypeCode, ScalarType >::scalar_type scalar_type
Definition: ad_helpers.h:3088
typename HelperBase< ADNumberTypeCode, ScalarType >::ad_type ad_type
Definition: ad_helpers.h:3486
void compute_values(Vector< scalar_type > &values) const
Definition: ad_helpers.cc:1682
void register_dependent_variables(const std::vector< ad_type > &funcs)
Definition: ad_helpers.cc:1666
void compute_jacobian(FullMatrix< scalar_type > &jacobian) const
Definition: ad_helpers.cc:1738
typename HelperBase< ADNumberTypeCode, ScalarType >::scalar_type scalar_type
Definition: ad_helpers.h:3479
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)
VectorFunction(const unsigned int n_independent_variables, const unsigned int n_dependent_variables)
Definition: ad_helpers.cc:1651
static constexpr unsigned int component_to_unrolled_index(const TableIndices< rank_ > &indices)
Definition: tensor.h:472
static constexpr TableIndices< rank_ > unrolled_to_component_indices(const unsigned int i)
Definition: vector.h:110
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:402
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:403
#define Assert(cond, exc)
Definition: exceptions.h:1465
#define AssertIndexRange(index, range)
Definition: exceptions.h:1690
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
Definition: ad_helpers.h:2345
NumberType get_tensor_entry(const TensorType< rank, dim, NumberType > &t, const unsigned int unrolled_index)
Definition: ad_helpers.h:2515
void set_tensor_entry(TensorType &t, const unsigned int unrolled_index, const NumberType &value)
Definition: ad_helpers.h:2437
std::vector< IndexType > extract_field_component_indices(const ExtractorType &extractor, const bool ignore_symmetries=true)
Definition: ad_helpers.h:2357
ScalarFieldGradient< dim, NumberType, ExtractorType_Field > VectorFieldValue
Definition: ad_helpers.h:2326
static const unsigned int invalid_unsigned_int
Definition: types.h:196
static const Types< ADNumberType >::tape_index invalid_tape_index
Definition: ad_drivers.h:121
static unsigned int first_component(const FEValuesExtractors::Scalar &extractor)
Definition: ad_helpers.h:1704
static IndexType local_component(const TableIndices< rank_in > &table_indices, const unsigned int column_offset)
Definition: ad_helpers.h:1732
static bool symmetric_component(const unsigned int unrolled_index)
Definition: ad_helpers.h:1717
static TableIndices< rank > table_index_view(const TableIndices< rank_in > &table_indices, const unsigned int column_offset)
Definition: ad_helpers.h:2129
static unsigned int first_component(const FEValuesExtractors::SymmetricTensor< 2 > &extractor)
Definition: ad_helpers.h:2102
static IndexType local_component(const TableIndices< rank_in > &table_indices, const unsigned int column_offset)
Definition: ad_helpers.h:2155
static TableIndices< rank > table_index_view(const TableIndices< rank_in > &table_indices, const unsigned int column_offset)
Definition: ad_helpers.h:1919
static unsigned int first_component(const FEValuesExtractors::Tensor< 1 > &extractor)
Definition: ad_helpers.h:1894
static IndexType local_component(const TableIndices< rank_in > &table_indices, const unsigned int column_offset)
Definition: ad_helpers.h:1943
static TableIndices< rank > table_index_view(const TableIndices< rank_in > &table_indices, const unsigned int column_offset)
Definition: ad_helpers.h:2022
static unsigned int first_component(const FEValuesExtractors::Tensor< 2 > &extractor)
Definition: ad_helpers.h:1997
static IndexType local_component(const TableIndices< rank_in > &table_indices, const unsigned int column_offset)
Definition: ad_helpers.h:2048
static bool symmetric_component(const unsigned int unrolled_index)
Definition: ad_helpers.h:1804
static IndexType local_component(const TableIndices< rank_in > &table_indices, const unsigned int column_offset)
Definition: ad_helpers.h:1840
static unsigned int first_component(const FEValuesExtractors::Vector &extractor)
Definition: ad_helpers.h:1790
static TableIndices< rank > table_index_view(const TableIndices< rank_in > &table_indices, const unsigned int column_offset)
Definition: ad_helpers.h:1816
typename Extractor< dim, ExtractorType >::template tensor_type< NumberType > type
Definition: ad_helpers.h:2182
typename HessianType< ExtractorType_Row, ExtractorType_Col >::template type< rank, dim, NumberType > type
Definition: ad_helpers.h:2316