Reference documentation for deal.II version 9.1.1
\(\newcommand{\dealcoloneq}{\mathrel{\vcenter{:}}=}\)
adolc_number_types.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2016 - 2017 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 
23 DEAL_II_NAMESPACE_OPEN
24 
25 
26 namespace Differentiation
27 {
28  namespace AD
29  {
37  template <typename NumberType, typename = void>
38  struct is_adolc_number : std::false_type
39  {};
40 
41 
49  template <typename NumberType, typename = void>
50  struct is_adolc_taped_number : std::false_type
51  {};
52 
53 
61  template <typename NumberType, typename = void>
62  struct is_adolc_tapeless_number : std::false_type
63  {};
64  } // namespace AD
65 } // namespace Differentiation
66 
67 
68 DEAL_II_NAMESPACE_CLOSE
69 
70 
71 #ifdef DEAL_II_WITH_ADOLC
72 
73 # include <deal.II/base/exceptions.h>
74 # include <deal.II/base/numbers.h>
75 
76 # include <deal.II/differentiation/ad/ad_number_traits.h>
77 # include <deal.II/differentiation/ad/ad_number_types.h>
78 
79 # include <adolc/adouble.h> // Taped double
80 # include <adolc/adtl.h> // Tapeless double
81 # include <adolc/internal/adolc_settings.h>
82 # include <adolc/internal/adubfunc.h> // Taped double math functions
83 
84 # include <complex>
85 # include <type_traits>
86 
87 DEAL_II_NAMESPACE_OPEN
88 
96  "This function has not yet been implemented for taped ADOL-C "
97  "numbers when the advanced branching feature is activated.");
98 
99 
100 /* ----------- inline and template functions and specializations ----------- */
101 
102 
103 # ifndef DOXYGEN
104 
105 
106 namespace Differentiation
107 {
108  namespace AD
109  {
110  namespace internal
111  {
116  template <typename ScalarType>
117  struct ADNumberInfoFromEnum<
118  ScalarType,
120  typename std::enable_if<
121  std::is_floating_point<ScalarType>::value>::type>
122  {
123  static const bool is_taped = true;
124  using real_type = adouble;
125  using derivative_type = double;
126  static const unsigned int n_supported_derivative_levels =
127  std::numeric_limits<unsigned int>::max();
128  };
129 
130 
135  template <typename ScalarType>
136  struct ADNumberInfoFromEnum<
137  ScalarType,
139  typename std::enable_if<
140  std::is_floating_point<ScalarType>::value>::type>
141  {
142  static const bool is_taped = false;
143  using real_type = adtl::adouble;
144  using derivative_type = double;
145  static const unsigned int n_supported_derivative_levels = 1;
146  };
147 
148 
149  template <typename ADNumberType>
150  struct Marking<
151  ADNumberType,
152  typename std::enable_if<
153  ADNumberTraits<ADNumberType>::type_code == NumberTypes::adolc_taped &&
154  ADNumberTraits<ADNumberType>::is_real_valued>::type>
155  {
156  using scalar_type = typename ADNumberTraits<ADNumberType>::scalar_type;
157 
158  /*
159  * Initialize the state of an independent variable.
160  */
161  static void
162  independent_variable(const scalar_type &in,
163  const unsigned int,
164  const unsigned int,
165  ADNumberType &out)
166  {
167  out <<= in;
168  }
169 
170  /*
171  * Initialize the state of a dependent variable.
172  *
173  * @note The second argument must be writable, so we
174  * simply pass a copy instead of a non-constant reference.
175  */
176  static void
177  dependent_variable(ADNumberType &out, ADNumberType func)
178  {
179  // Store the value only (strip it of all sensitivities)
180  out = ADNumberTraits<ADNumberType>::get_scalar_value(func);
181  // Mark as a dependent variable
182  scalar_type tmp;
183  func >>= tmp;
184  }
185  };
186 
187  template <typename ADNumberType>
188  struct Marking<ADNumberType,
189  typename std::enable_if<
190  ADNumberTraits<ADNumberType>::type_code ==
191  NumberTypes::adolc_tapeless &&
192  ADNumberTraits<ADNumberType>::is_real_valued>::type>
193  {
194  using scalar_type = typename ADNumberTraits<ADNumberType>::scalar_type;
195 
196  /*
197  * Initialize the state of an independent variable.
198  */
199  static void
200  independent_variable(const scalar_type &in,
201  const unsigned int index,
202  const unsigned int,
203  ADNumberType &out)
204  {
205  // It is important that the tapeless variables have their values set
206  // before defining their directional derivative index
207  out = in;
208 
209  // Violating this condition when will result in an ADOL-C internal
210  // error. We could rather always throw here in order to provide a
211  // less cryptic message.
212  AssertThrow(index < adtl::getNumDir(),
213  ExcMessage(
214  "The index number of the independent variable being "
215  "marked is greater than the number of independent "
216  "variables that have been declared."));
217  out.setADValue(index, 1 /*seed value for first derivative*/);
218  }
219 
220  /*
221  * Initialize the state of a dependent variable.
222  */
223  static void
224  dependent_variable(ADNumberType &out, const ADNumberType &func)
225  {
226  // Simply transfer value with sensitivities
227  out = 0.0;
228  out = func;
229  }
230  };
231 
232 
239  template <>
240  struct ExtractData<adouble>
241  {
245  static double
246  value(const adouble &x)
247  {
248  return x.getValue();
249  }
250 
251 
258  static unsigned int
259  n_directional_derivatives(const adouble &)
260  {
261  return 0;
262  }
263 
264 
272  static double
273  directional_derivative(const adouble &, const unsigned int)
274  {
275  AssertThrow(false,
276  ExcMessage(
277  "The derivative values for taped ADOL-C numbers must be"
278  "computed through the ::gradient function."));
279  return 0.0;
280  }
281  };
282 
283 
290  template <>
291  struct ExtractData<adtl::adouble>
292  {
296  static double
297  value(const adtl::adouble &x)
298  {
299  return x.getValue();
300  }
301 
302 
306  static unsigned int
307  n_directional_derivatives(const adtl::adouble &)
308  {
309  // This is a global function call...
310  return adtl::getNumDir();
311  }
312 
313 
317  static double
318  directional_derivative(const adtl::adouble &x,
319  const unsigned int direction)
320  {
321  Assert(
322  direction < n_directional_derivatives(x),
323  ExcMessage(
324  "Requested directional derivative is greater than the number "
325  "registered by ADOL-C."));
326  return x.getADValue(direction);
327  }
328  };
329 
330  } // namespace internal
331 
332 
333 
344  template <typename ADNumberType>
345  struct ADNumberTraits<
346  ADNumberType,
347  typename std::enable_if<std::is_same<ADNumberType, adouble>::value>::type>
348  : NumberTraits<double, NumberTypes::adolc_taped>
349  {
350  static_assert(std::is_same<ad_type, adouble>::value,
351  "Incorrect template type selected for taped ad_type");
352  static_assert(is_taped == true, "Incorrect setting for taping");
353  };
354 
355 
356 
368  template <typename ADNumberType>
369  struct ADNumberTraits<
370  ADNumberType,
371  typename std::enable_if<
372  std::is_same<ADNumberType, std::complex<adouble>>::value>::type>
373  : NumberTraits<std::complex<double>, NumberTypes::adolc_taped>
374  {
375  static_assert(std::is_same<ad_type, std::complex<adouble>>::value,
376  "Incorrect template type selected for taped ad_type");
377  static_assert(is_taped == true, "Incorrect setting for taping");
378  };
379 
380 
381 
392  template <typename ADNumberType>
393  struct ADNumberTraits<
394  ADNumberType,
395  typename std::enable_if<
396  std::is_same<ADNumberType, adtl::adouble>::value>::type>
397  : NumberTraits<double, NumberTypes::adolc_tapeless>
398  {
399  static_assert(std::is_same<ad_type, adtl::adouble>::value,
400  "Incorrect template type selected for tapeless ad_type");
401  static_assert(is_tapeless == true, "Incorrect setting for taping");
402  };
403 
404 
405 
417  template <typename ADNumberType>
418  struct ADNumberTraits<
419  ADNumberType,
420  typename std::enable_if<
421  std::is_same<ADNumberType, std::complex<adtl::adouble>>::value>::type>
422  : NumberTraits<std::complex<double>, NumberTypes::adolc_tapeless>
423  {
424  static_assert(std::is_same<ad_type, std::complex<adtl::adouble>>::value,
425  "Incorrect template type selected for tapeless ad_type");
426  static_assert(is_tapeless == true, "Incorrect setting for taping");
427  };
428 
429 
430 
435  template <>
436  struct NumberTraits<adouble, NumberTypes::adolc_taped>
437  : NumberTraits<typename ADNumberTraits<adouble>::scalar_type,
438  NumberTypes::adolc_taped>
439  {};
440 
441 
446  template <>
447  struct NumberTraits<std::complex<adouble>, NumberTypes::adolc_taped>
448  : NumberTraits<
449  typename ADNumberTraits<std::complex<adouble>>::scalar_type,
450  NumberTypes::adolc_taped>
451  {};
452 
453 
458  template <>
459  struct NumberTraits<adtl::adouble, NumberTypes::adolc_tapeless>
460  : NumberTraits<typename ADNumberTraits<adtl::adouble>::scalar_type,
461  NumberTypes::adolc_tapeless>
462  {};
463 
464 
469  template <>
470  struct NumberTraits<std::complex<adtl::adouble>,
472  : NumberTraits<
473  typename ADNumberTraits<std::complex<adtl::adouble>>::scalar_type,
474  NumberTypes::adolc_tapeless>
475  {};
476 
477 
482  template <typename NumberType>
483  struct is_adolc_taped_number<
484  NumberType,
485  typename std::enable_if<
486  ADNumberTraits<typename std::decay<NumberType>::type>::type_code ==
487  NumberTypes::adolc_taped>::type> : std::true_type
488  {};
489 
490 
495  template <typename NumberType>
496  struct is_adolc_tapeless_number<
497  NumberType,
498  typename std::enable_if<
499  ADNumberTraits<typename std::decay<NumberType>::type>::type_code ==
500  NumberTypes::adolc_tapeless>::type> : std::true_type
501  {};
502 
503 
508  template <typename NumberType>
509  struct is_adolc_number<NumberType,
510  typename std::enable_if<
511  is_adolc_taped_number<NumberType>::value ||
512  is_adolc_tapeless_number<NumberType>::value>::type>
513  : std::true_type
514  {};
515 
516  } // namespace AD
517 } // namespace Differentiation
518 
519 
520 # endif // DOXYGEN
521 
522 
523 DEAL_II_NAMESPACE_CLOSE
524 
525 
526 #endif // DEAL_II_WITH_ADOLC
527 
528 #endif
STL namespace.
#define AssertThrow(cond, exc)
Definition: exceptions.h:1519
static ::ExceptionBase & ExcADOLCAdvancedBranching()
static ::ExceptionBase & ExcMessage(std::string arg1)
#define Assert(cond, exc)
Definition: exceptions.h:1407
#define DeclExceptionMsg(Exception, defaulttext)
Definition: exceptions.h:496