Reference documentation for deal.II version GIT 29f9da0a34 2023-12-07 10:00:01+00:00
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
adolc_number_types.h
Go to the documentation of this file.
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2016 - 2022 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE.md at
12 // the top level directory of deal.II.
13 //
14 // ---------------------------------------------------------------------
15 
16 #ifndef dealii_differentiation_ad_adolc_number_types_h
17 #define dealii_differentiation_ad_adolc_number_types_h
18 
19 #include <deal.II/base/config.h>
20 
21 #include <type_traits>
22 
24 
25 
26 namespace Differentiation
27 {
28  namespace AD
29  {
35  template <typename NumberType, typename = void>
36  struct is_adolc_number : std::false_type
37  {};
38 
39 
45  template <typename NumberType, typename = void>
46  struct is_adolc_taped_number : std::false_type
47  {};
48 
49 
55  template <typename NumberType, typename = void>
56  struct is_adolc_tapeless_number : std::false_type
57  {};
58  } // namespace AD
59 } // namespace Differentiation
60 
61 
63 
64 
65 #ifdef DEAL_II_WITH_ADOLC
66 
67 # include <deal.II/base/exceptions.h>
68 # include <deal.II/base/numbers.h>
69 
72 
73 # include <adolc/adouble.h> // Taped double
74 # include <adolc/adtl.h> // Tapeless double
75 # include <adolc/internal/adolc_settings.h>
76 # include <adolc/internal/adubfunc.h> // Taped double math functions
77 
78 # include <complex>
79 # include <limits>
80 
82 
90  "This function has not yet been implemented for taped ADOL-C "
91  "numbers when the advanced branching feature is activated.");
92 
93 
94 /* ----------- inline and template functions and specializations ----------- */
95 
96 
97 # ifndef DOXYGEN
98 
99 
100 namespace Differentiation
101 {
102  namespace AD
103  {
104  namespace internal
105  {
110  template <typename ScalarType>
111  struct ADNumberInfoFromEnum<
112  ScalarType,
114  std::enable_if_t<std::is_floating_point_v<ScalarType>>>
115  {
116  static const bool is_taped = true;
117  using real_type = adouble;
118  using derivative_type = double;
119  static const unsigned int n_supported_derivative_levels =
121  };
122 
123 
128  template <typename ScalarType>
129  struct ADNumberInfoFromEnum<
130  ScalarType,
132  std::enable_if_t<std::is_floating_point_v<ScalarType>>>
133  {
134  static const bool is_taped = false;
135  using real_type = adtl::adouble;
136  using derivative_type = double;
137  static const unsigned int n_supported_derivative_levels = 1;
138  };
139 
140 
141  template <typename ADNumberType>
142  struct Marking<
143  ADNumberType,
144  std::enable_if_t<ADNumberTraits<ADNumberType>::type_code ==
145  NumberTypes::adolc_taped &&
146  ADNumberTraits<ADNumberType>::is_real_valued>>
147  {
148  using scalar_type = typename ADNumberTraits<ADNumberType>::scalar_type;
149 
150  /*
151  * Initialize the state of an independent variable.
152  */
153  static void
154  independent_variable(const scalar_type &in,
155  const unsigned int,
156  const unsigned int,
157  ADNumberType &out)
158  {
159  out <<= in;
160  }
161 
162  /*
163  * Initialize the state of a dependent variable.
164  *
165  * @note The second argument must be writable, so we
166  * simply pass a copy instead of a non-constant reference.
167  */
168  static void
169  dependent_variable(ADNumberType &out, ADNumberType func)
170  {
171  // Store the value only (strip it of all sensitivities)
172  out = ADNumberTraits<ADNumberType>::get_scalar_value(func);
173  // Mark as a dependent variable
174  scalar_type tmp;
175  func >>= tmp;
176  }
177  };
178 
179  template <typename ADNumberType>
180  struct Marking<
181  ADNumberType,
182  std::enable_if_t<ADNumberTraits<ADNumberType>::type_code ==
183  NumberTypes::adolc_tapeless &&
184  ADNumberTraits<ADNumberType>::is_real_valued>>
185  {
186  using scalar_type = typename ADNumberTraits<ADNumberType>::scalar_type;
187 
188  /*
189  * Initialize the state of an independent variable.
190  */
191  static void
192  independent_variable(const scalar_type &in,
193  const unsigned int index,
194  const unsigned int,
195  ADNumberType &out)
196  {
197  // It is important that the tapeless variables have their values set
198  // before defining their directional derivative index
199  out = in;
200 
201  // Violating this condition when will result in an ADOL-C internal
202  // error. We could rather always throw here in order to provide a
203  // less cryptic message.
204  AssertThrow(index < adtl::getNumDir(),
205  ExcMessage(
206  "The index number of the independent variable being "
207  "marked is greater than the number of independent "
208  "variables that have been declared."));
209  out.setADValue(index, 1 /*seed value for first derivative*/);
210  }
211 
212  /*
213  * Initialize the state of a dependent variable.
214  */
215  static void
216  dependent_variable(ADNumberType &out, const ADNumberType &func)
217  {
218  // Simply transfer value with sensitivities
219  out = 0.0;
220  out = func;
221  }
222  };
223 
224 
229  template <>
230  struct ExtractData<adouble>
231  {
235  static double
236  value(const adouble &x)
237  {
238  return x.getValue();
239  }
240 
241 
248  static unsigned int
249  n_directional_derivatives(const adouble &)
250  {
251  return 0;
252  }
253 
254 
262  static double
263  directional_derivative(const adouble &, const unsigned int)
264  {
265  AssertThrow(false,
266  ExcMessage(
267  "The derivative values for taped ADOL-C numbers must be"
268  " computed through the ::gradient function."));
269  return 0.0;
270  }
271  };
272 
273 
278  template <>
279  struct ExtractData<adtl::adouble>
280  {
284  static double
285  value(const adtl::adouble &x)
286  {
287  return x.getValue();
288  }
289 
290 
294  static unsigned int
295  n_directional_derivatives(const adtl::adouble &)
296  {
297  // This is a global function call...
298  return adtl::getNumDir();
299  }
300 
301 
305  static double
306  directional_derivative(const adtl::adouble &x,
307  const unsigned int direction)
308  {
309  Assert(
310  direction < n_directional_derivatives(x),
311  ExcMessage(
312  "Requested directional derivative is greater than the number "
313  "registered by ADOL-C."));
314  return x.getADValue(direction);
315  }
316  };
317 
318  } // namespace internal
319 
320 
321 
330  template <typename ADNumberType>
331  struct ADNumberTraits<
332  ADNumberType,
333  std::enable_if_t<std::is_same_v<ADNumberType, adouble>>>
334  : NumberTraits<double, NumberTypes::adolc_taped>
335  {
336  static_assert(std::is_same_v<ad_type, adouble>,
337  "Incorrect template type selected for taped ad_type");
338  static_assert(is_taped == true, "Incorrect setting for taping");
339  };
340 
341 
342 
352  template <typename ADNumberType>
353  struct ADNumberTraits<
354  ADNumberType,
355  std::enable_if_t<std::is_same_v<ADNumberType, std::complex<adouble>>>>
356  : NumberTraits<std::complex<double>, NumberTypes::adolc_taped>
357  {
358  static_assert(std::is_same_v<ad_type, std::complex<adouble>>,
359  "Incorrect template type selected for taped ad_type");
360  static_assert(is_taped == true, "Incorrect setting for taping");
361  };
362 
363 
364 
373  template <typename ADNumberType>
374  struct ADNumberTraits<
375  ADNumberType,
376  std::enable_if_t<std::is_same_v<ADNumberType, adtl::adouble>>>
377  : NumberTraits<double, NumberTypes::adolc_tapeless>
378  {
379  static_assert(std::is_same_v<ad_type, adtl::adouble>,
380  "Incorrect template type selected for tapeless ad_type");
381  static_assert(is_tapeless == true, "Incorrect setting for taping");
382  };
383 
384 
385 
395  template <typename ADNumberType>
396  struct ADNumberTraits<
397  ADNumberType,
398  std::enable_if_t<
399  std::is_same_v<ADNumberType, std::complex<adtl::adouble>>>>
400  : NumberTraits<std::complex<double>, NumberTypes::adolc_tapeless>
401  {
402  static_assert(std::is_same_v<ad_type, std::complex<adtl::adouble>>,
403  "Incorrect template type selected for tapeless ad_type");
404  static_assert(is_tapeless == true, "Incorrect setting for taping");
405  };
406 
407 
408 
413  template <>
414  struct NumberTraits<adouble, NumberTypes::adolc_taped>
415  : NumberTraits<typename ADNumberTraits<adouble>::scalar_type,
416  NumberTypes::adolc_taped>
417  {};
418 
419 
424  template <>
425  struct NumberTraits<std::complex<adouble>, NumberTypes::adolc_taped>
426  : NumberTraits<
427  typename ADNumberTraits<std::complex<adouble>>::scalar_type,
428  NumberTypes::adolc_taped>
429  {};
430 
431 
436  template <>
437  struct NumberTraits<adtl::adouble, NumberTypes::adolc_tapeless>
438  : NumberTraits<typename ADNumberTraits<adtl::adouble>::scalar_type,
439  NumberTypes::adolc_tapeless>
440  {};
441 
442 
447  template <>
448  struct NumberTraits<std::complex<adtl::adouble>,
450  : NumberTraits<
451  typename ADNumberTraits<std::complex<adtl::adouble>>::scalar_type,
452  NumberTypes::adolc_tapeless>
453  {};
454 
455 
460  template <typename NumberType>
461  struct is_adolc_taped_number<
462  NumberType,
463  std::enable_if_t<ADNumberTraits<std::decay_t<NumberType>>::type_code ==
464  NumberTypes::adolc_taped>> : std::true_type
465  {};
466 
467 
472  template <typename NumberType>
473  struct is_adolc_tapeless_number<
474  NumberType,
475  std::enable_if_t<ADNumberTraits<std::decay_t<NumberType>>::type_code ==
476  NumberTypes::adolc_tapeless>> : std::true_type
477  {};
478 
479 
484  template <typename NumberType>
485  struct is_adolc_number<
486  NumberType,
487  std::enable_if_t<is_adolc_taped_number<NumberType>::value ||
488  is_adolc_tapeless_number<NumberType>::value>>
489  : std::true_type
490  {};
491 
492  } // namespace AD
493 } // namespace Differentiation
494 
495 
496 # endif // DOXYGEN
497 
498 
500 
501 
502 #endif // DEAL_II_WITH_ADOLC
503 
504 #endif
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:477
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:478
static ::ExceptionBase & ExcADOLCAdvancedBranching()
#define Assert(cond, exc)
Definition: exceptions.h:1631
#define DeclExceptionMsg(Exception, defaulttext)
Definition: exceptions.h:495
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
Definition: exceptions.h:1732
Definition: numbers.h:54