Reference documentation for deal.II version Git 191d06ed00 2021-05-11 21:15:49 -0400
\(\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 
36 # include <deal.II/lac/full_matrix.h>
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 
47 namespace Differentiation
48 {
49  namespace AD
50  {
168  template <enum AD::NumberTypes ADNumberTypeCode,
169  typename ScalarType = double>
171  {
172  public:
177  using scalar_type =
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
226  n_independent_variables() const;
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 
658  mutable std::vector<bool> registered_marked_independent_variables;
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:
843  using scalar_type =
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
927  register_dof_values(
928  const VectorType & values,
929  const std::vector<::types::global_dof_index> &local_dof_indices);
930 
951  const std::vector<ad_type> &
952  get_sensitive_dof_values() const;
953 
955 
960 
980  void
981  set_dof_values(const std::vector<scalar_type> &dof_values);
982 
1000  template <typename VectorType>
1001  void
1002  set_dof_values(
1003  const VectorType & values,
1004  const std::vector<::types::global_dof_index> &local_dof_indices);
1005 
1007 
1012 
1027  virtual void
1028  compute_residual(Vector<scalar_type> &residual) const = 0;
1029 
1047  virtual void
1048  compute_linearization(FullMatrix<scalar_type> &linearization) const = 0;
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:
1225  using scalar_type =
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 
1298  scalar_type
1299  compute_energy() const;
1300 
1320  void
1321  compute_residual(Vector<scalar_type> &residual) const override;
1322 
1343  virtual void
1344  compute_linearization(
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:
1537  using scalar_type =
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
1634  compute_linearization(
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>
1650  struct Extractor;
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(
1681  rank == tensor_type<double>::rank,
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(
1771  rank == tensor_type<double>::rank,
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>
2325  using VectorFieldValue =
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
2469  set_tensor_entry(NumberType & t,
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 
2648  using scalar_type =
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> &
2774  get_sensitive_variables() const;
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
2900  n_symmetric_independent_variables() const;
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:
3087  using scalar_type =
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
3137  register_dependent_variable(const ad_type &func);
3138 
3146  scalar_type
3147  compute_value() const;
3148 
3161  void
3162  compute_gradient(Vector<scalar_type> &gradient) const;
3163 
3178  void
3179  compute_hessian(FullMatrix<scalar_type> &hessian) const;
3180 
3215  template <typename ExtractorType_Row>
3216  static typename internal::
3218  extract_gradient_component(const Vector<scalar_type> &gradient,
3219  const ExtractorType_Row & extractor_row);
3220 
3259  template <typename ExtractorType_Row, typename ExtractorType_Col>
3260  static typename internal::ScalarFieldHessian<dim,
3261  scalar_type,
3262  ExtractorType_Row,
3263  ExtractorType_Col>::type
3264  extract_hessian_component(const FullMatrix<scalar_type> &hessian,
3265  const ExtractorType_Row & extractor_row,
3266  const ExtractorType_Col & extractor_col);
3267 
3282  extract_hessian_component(
3283  const FullMatrix<scalar_type> & hessian,
3284  const FEValuesExtractors::Scalar &extractor_row,
3285  const FEValuesExtractors::Scalar &extractor_col);
3286 
3299  extract_hessian_component(
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:
3478  using scalar_type =
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
3569  compute_values(Vector<scalar_type> &values) const;
3570 
3585  void
3586  compute_jacobian(FullMatrix<scalar_type> &jacobian) const;
3587 
3588 
3601  template <typename ExtractorType_Row>
3602  static typename internal::
3604  extract_value_component(const Vector<scalar_type> &values,
3605  const ExtractorType_Row & extractor_row);
3606 
3654  template <typename ExtractorType_Row, typename ExtractorType_Col>
3655  static typename internal::VectorFieldJacobian<dim,
3656  scalar_type,
3657  ExtractorType_Row,
3658  ExtractorType_Col>::type
3659  extract_jacobian_component(const FullMatrix<scalar_type> &jacobian,
3660  const ExtractorType_Row & extractor_row,
3661  const ExtractorType_Col & extractor_col);
3662 
3679  extract_jacobian_component(
3680  const FullMatrix<scalar_type> & jacobian,
3681  const FEValuesExtractors::Scalar &extractor_row,
3682  const FEValuesExtractors::Scalar &extractor_col);
3683 
3698  extract_jacobian_component(
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 
3717 namespace 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  {
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  {
3821  index_set[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>
3835  ad_type>
3837  get_sensitive_variables(const ExtractorType &extractor) const
3838  {
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
3849  Assert(this->independent_variables.size() ==
3850  this->n_independent_variables(),
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,
3865  ExcInternalError());
3866  internal::get_tensor_entry(out, i) =
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>
3884  dim,
3886  ExtractorType_Row>::type
3888  extract_gradient_component(const Vector<scalar_type> &gradient,
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>
3915  dim,
3916  typename ScalarFunction<dim, ADNumberTypeCode, ScalarType>::scalar_type,
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>
4005  typename internal::VectorFieldValue<
4006  dim,
4008  ExtractorType_Row>::type
4010  const Vector<scalar_type> &values,
4011  const ExtractorType_Row & extractor_row)
4012  {
4013  // NOTE: The order of components must be consistently defined throughout
4014  // this class.
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,
4038  typename VectorFunction<dim, ADNumberTypeCode, ScalarType>::scalar_type,
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  {
4079  const TableIndices<JacobianType::rank> ti_out =
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
TapedDrivers< ad_type, scalar_type > taped_driver
Definition: ad_helpers.h:592
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
static IndexType local_component(const TableIndices< rank_in > &table_indices, const unsigned int column_offset)
Definition: ad_helpers.h:2155
static const unsigned int invalid_unsigned_int
Definition: types.h:196
HelperBase(const unsigned int n_independent_variables, const unsigned int n_dependent_variables)
Definition: ad_helpers.cc:38
static unsigned int first_component(const FEValuesExtractors::SymmetricTensor< 2 > &extractor)
Definition: ad_helpers.h:2102
static constexpr unsigned int component_to_unrolled_index(const TableIndices< rank_ > &indices)
static unsigned int first_component(const FEValuesExtractors::Tensor< 1 > &extractor)
Definition: ad_helpers.h:1894
void set_sensitivity_value(const unsigned int index, const scalar_type &value)
Definition: ad_helpers.cc:105
static TableIndices< rank > table_index_view(const TableIndices< rank_in > &table_indices, const unsigned int column_offset)
Definition: ad_helpers.h:2129
void mark_independent_variable(const unsigned int index, ad_type &out) const
Definition: ad_helpers.cc:142
static IndexType local_component(const TableIndices< rank_in > &table_indices, const unsigned int column_offset)
Definition: ad_helpers.h:1840
typename HelperBase< ADNumberTypeCode, ScalarType >::scalar_type scalar_type
Definition: ad_helpers.h:3088
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::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)
static TableIndices< rank > table_index_view(const TableIndices< rank_in > &table_indices, const unsigned int column_offset)
Definition: ad_helpers.h:2022
#define AssertIndexRange(index, range)
Definition: exceptions.h:1690
typename Extractor< dim, ExtractorType >::template tensor_type< NumberType > type
Definition: ad_helpers.h:2182
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
void register_independent_variable(const ValueType &value, const ExtractorType &extractor)
static unsigned int first_component(const FEValuesExtractors::Tensor< 2 > &extractor)
Definition: ad_helpers.h:1997
void stop_recording_operations(const bool write_tapes_to_file=false)
Definition: ad_helpers.cc:648
static TableIndices< rank > table_index_view(const TableIndices< rank_in > &table_indices, const unsigned int column_offset)
Definition: ad_helpers.h:1919
static void configure_tapeless_mode(const unsigned int n_independent_variables, const bool ensure_persistent_setting=true)
Definition: ad_helpers.cc:453
std::vector< scalar_type > independent_variable_values
Definition: ad_helpers.h:636
Types< ad_type >::tape_index active_tape_index() const
Definition: ad_helpers.cc:284
std::vector< bool > symmetric_independent_variables
Definition: ad_helpers.h:2914
std::vector< bool > registered_marked_independent_variables
Definition: ad_helpers.h:658
static internal::ScalarFieldGradient< dim, scalar_type, ExtractorType_Row >::type extract_gradient_component(const Vector< scalar_type > &gradient, const ExtractorType_Row &extractor_row)
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
void reset_registered_dependent_variables(const bool flag=false)
Definition: ad_helpers.cc:94
void register_dependent_variable(const unsigned int index, const ad_type &func)
Definition: ad_helpers.cc:684
void print_values(std::ostream &stream) const
Definition: ad_helpers.cc:364
static ::ExceptionBase & ExcMessage(std::string arg1)
typename HessianType< ExtractorType_Row, ExtractorType_Col >::template type< rank, dim, NumberType > type
Definition: ad_helpers.h:2316
std::vector< ad_type > dependent_variables
Definition: ad_helpers.h:750
static constexpr TableIndices< rank_ > unrolled_to_component_indices(const unsigned int i)
typename AD::NumberTraits< ScalarType, ADNumberTypeCode >::ad_type ad_type
Definition: ad_helpers.h:185
static unsigned int first_component(const FEValuesExtractors::Vector &extractor)
Definition: ad_helpers.h:1790
NumberType get_tensor_entry(const TensorType< rank, dim, NumberType > &t, const unsigned int unrolled_index)
Definition: ad_helpers.h:2515
std::size_t n_independent_variables() const
Definition: ad_helpers.cc:241
void set_tensor_entry(TensorType &t, const unsigned int unrolled_index, const NumberType &value)
Definition: ad_helpers.h:2437
typename AD::NumberTraits< ScalarType, ADNumberTypeCode >::scalar_type scalar_type
Definition: ad_helpers.h:178
#define Assert(cond, exc)
Definition: exceptions.h:1465
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
std::vector< bool > registered_marked_dependent_variables
Definition: ad_helpers.h:755
void register_dependent_variable(const ValueType &funcs, const ExtractorType &extractor)
unsigned int n_registered_dependent_variables() const
Definition: ad_helpers.cc:250
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:396
static TableIndices< rank > table_index_view(const TableIndices< rank_in > &table_indices, const unsigned int column_offset)
Definition: ad_helpers.h:1816
static bool symmetric_component(const unsigned int unrolled_index)
Definition: ad_helpers.h:1717
NumberType & get_tensor_entry(NumberType &t, const unsigned int index)
Definition: ad_helpers.h:2599
void print(std::ostream &stream) const
Definition: ad_helpers.cc:309
void finalize_sensitive_independent_variables() const
Definition: ad_helpers.cc:181
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
void register_dof_values(const std::vector< scalar_type > &dof_values)
Definition: ad_helpers.cc:726
bool active_tape_requires_retaping() const
Definition: ad_helpers.cc:502
Definition: tensor.h:449
std::vector< bool > registered_independent_variable_values
Definition: ad_helpers.h:652
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:395
static internal::VectorFieldValue< dim, scalar_type, ExtractorType_Row >::type extract_value_component(const Vector< scalar_type > &values, const ExtractorType_Row &extractor_row)
static bool symmetric_component(const unsigned int unrolled_index)
Definition: ad_helpers.h:1804
void set_tensor_entry(SymmetricTensor< 4, dim, NumberType > &t, const unsigned int unrolled_index_row, const unsigned int unrolled_index_col, const NumberType &value)
Definition: ad_helpers.h:2485
void initialize_non_sensitive_independent_variable(const unsigned int index, ad_type &out) const
Definition: ad_helpers.cc:205
bool recorded_tape_requires_retaping(const typename Types< ad_type >::tape_index tape_index) const
Definition: ad_helpers.cc:489
void set_independent_variable(const ValueType &value, const ExtractorType &extractor)
void print_tape_stats(const typename Types< ad_type >::tape_index tape_index, std::ostream &stream) const
Definition: ad_helpers.cc:378
TapelessDrivers< ad_type, scalar_type > tapeless_driver
Definition: ad_helpers.h:600
bool is_registered_tape(const typename Types< ad_type >::tape_index tape_index) const
Definition: ad_helpers.cc:296
std::vector< IndexType > extract_field_component_indices(const FEValuesExtractors::SymmetricTensor< 2 > &extractor_symm_tensor, const bool ignore_symmetries=true)
Definition: ad_helpers.h:2381
std::vector< ad_type > independent_variables
Definition: ad_helpers.h:646
std::size_t n_dependent_variables() const
Definition: ad_helpers.cc:262
void activate_recorded_tape(const typename Types< ad_type >::tape_index tape_index)
Definition: ad_helpers.cc:479
typename HelperBase< ADNumberTypeCode, ScalarType >::scalar_type scalar_type
Definition: ad_helpers.h:3479
const std::vector< ad_type > & get_sensitive_variables() const
Definition: ad_helpers.cc:1251
void set_dof_values(const std::vector< scalar_type > &dof_values)
Definition: ad_helpers.cc:774
static IndexType local_component(const TableIndices< rank_in > &table_indices, const unsigned int column_offset)
Definition: ad_helpers.h:1943
unsigned int n_registered_independent_variables() const
Definition: ad_helpers.cc:230
static IndexType local_component(const TableIndices< rank_in > &table_indices, const unsigned int column_offset)
Definition: ad_helpers.h:2048
static ::ExceptionBase & ExcInternalError()
void activate_tape(const typename Types< ad_type >::tape_index tape_index, const bool read_mode)
Definition: ad_helpers.cc:527