Reference documentation for deal.II version GIT 5983d193e2 2023-05-27 16:50:02+00:00
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
adolc_number_types.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.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<ScalarType>::value>>
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<ScalarType>::value>>
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<ADNumberType, adouble>::value>>
334  : NumberTraits<double, NumberTypes::adolc_taped>
335  {
336  static_assert(std::is_same<ad_type, adouble>::value,
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<
356  std::is_same<ADNumberType, std::complex<adouble>>::value>>
357  : NumberTraits<std::complex<double>, NumberTypes::adolc_taped>
358  {
359  static_assert(std::is_same<ad_type, std::complex<adouble>>::value,
360  "Incorrect template type selected for taped ad_type");
361  static_assert(is_taped == true, "Incorrect setting for taping");
362  };
363 
364 
365 
374  template <typename ADNumberType>
375  struct ADNumberTraits<
376  ADNumberType,
377  std::enable_if_t<std::is_same<ADNumberType, adtl::adouble>::value>>
378  : NumberTraits<double, NumberTypes::adolc_tapeless>
379  {
380  static_assert(std::is_same<ad_type, adtl::adouble>::value,
381  "Incorrect template type selected for tapeless ad_type");
382  static_assert(is_tapeless == true, "Incorrect setting for taping");
383  };
384 
385 
386 
396  template <typename ADNumberType>
397  struct ADNumberTraits<
398  ADNumberType,
399  std::enable_if_t<
400  std::is_same<ADNumberType, std::complex<adtl::adouble>>::value>>
401  : NumberTraits<std::complex<double>, NumberTypes::adolc_tapeless>
402  {
403  static_assert(std::is_same<ad_type, std::complex<adtl::adouble>>::value,
404  "Incorrect template type selected for tapeless ad_type");
405  static_assert(is_tapeless == true, "Incorrect setting for taping");
406  };
407 
408 
409 
414  template <>
415  struct NumberTraits<adouble, NumberTypes::adolc_taped>
416  : NumberTraits<typename ADNumberTraits<adouble>::scalar_type,
417  NumberTypes::adolc_taped>
418  {};
419 
420 
425  template <>
426  struct NumberTraits<std::complex<adouble>, NumberTypes::adolc_taped>
427  : NumberTraits<
428  typename ADNumberTraits<std::complex<adouble>>::scalar_type,
429  NumberTypes::adolc_taped>
430  {};
431 
432 
437  template <>
438  struct NumberTraits<adtl::adouble, NumberTypes::adolc_tapeless>
439  : NumberTraits<typename ADNumberTraits<adtl::adouble>::scalar_type,
440  NumberTypes::adolc_tapeless>
441  {};
442 
443 
448  template <>
449  struct NumberTraits<std::complex<adtl::adouble>,
451  : NumberTraits<
452  typename ADNumberTraits<std::complex<adtl::adouble>>::scalar_type,
453  NumberTypes::adolc_tapeless>
454  {};
455 
456 
461  template <typename NumberType>
462  struct is_adolc_taped_number<
463  NumberType,
464  std::enable_if_t<ADNumberTraits<typename std::decay<NumberType>::type>::
465  type_code == NumberTypes::adolc_taped>>
466  : std::true_type
467  {};
468 
469 
474  template <typename NumberType>
475  struct is_adolc_tapeless_number<
476  NumberType,
477  std::enable_if_t<ADNumberTraits<typename std::decay<NumberType>::type>::
478  type_code == NumberTypes::adolc_tapeless>>
479  : std::true_type
480  {};
481 
482 
487  template <typename NumberType>
488  struct is_adolc_number<
489  NumberType,
490  std::enable_if_t<is_adolc_taped_number<NumberType>::value ||
491  is_adolc_tapeless_number<NumberType>::value>>
492  : std::true_type
493  {};
494 
495  } // namespace AD
496 } // namespace Differentiation
497 
498 
499 # endif // DOXYGEN
500 
501 
503 
504 
505 #endif // DEAL_II_WITH_ADOLC
506 
507 #endif
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:474
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:475
static ::ExceptionBase & ExcADOLCAdvancedBranching()
#define Assert(cond, exc)
Definition: exceptions.h:1614
#define DeclExceptionMsg(Exception, defaulttext)
Definition: exceptions.h:488
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
Definition: exceptions.h:1703
Definition: numbers.h:55