Reference documentation for deal.II version 9.0.0
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 at
12 // the top level of the deal.II distribution.
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 #include <type_traits>
21 
22 DEAL_II_NAMESPACE_OPEN
23 
24 
25 namespace Differentiation
26 {
27  namespace AD
28  {
36  template <typename NumberType, typename = void>
38  : std::false_type
39  {};
40 
41 
49  template <typename NumberType, typename = void>
51  : std::false_type
52  {};
53 
54 
62  template <typename NumberType, typename = void>
64  : std::false_type
65  {};
66  }
67 }
68 
69 
70 DEAL_II_NAMESPACE_CLOSE
71 
72 
73 #ifdef DEAL_II_WITH_ADOLC
74 
75 #include <adolc/internal/adolc_settings.h>
76 #include <adolc/internal/adubfunc.h> // Taped double math functions
77 
78 #include <adolc/adouble.h> // Taped double
79 #include <adolc/adtl.h> // Tapeless double
80 
81 #include <deal.II/base/numbers.h>
82 #include <deal.II/base/exceptions.h>
83 
84 #include <deal.II/differentiation/ad/ad_number_types.h>
85 #include <deal.II/differentiation/ad/ad_number_traits.h>
86 
87 #include <complex>
88 #include <type_traits>
89 
90 DEAL_II_NAMESPACE_OPEN
91 
99  "This function has not yet been implemented for taped Adol-C "
100  "numbers when the advanced branching feature is activated.");
101 
102 
103 /* --------------------------- inline and template functions and specializations ------------------------- */
104 
105 
106 #ifndef DOXYGEN
107 
108 
109 namespace Differentiation
110 {
111  namespace AD
112  {
113 
114  namespace internal
115  {
116 
121  template<typename ScalarType>
122  struct ADNumberInfoFromEnum<ScalarType, Differentiation::AD::NumberTypes::adolc_taped,
123  typename std::enable_if<std::is_floating_point<ScalarType>::value>::type
124  >
125  {
126  static const bool is_taped = true;
127  typedef adouble real_type;
128  typedef double derivative_type;
129  static const unsigned int n_supported_derivative_levels
130  = std::numeric_limits<unsigned int>::max();
131  };
132 
133 
138  template<typename ScalarType>
139  struct ADNumberInfoFromEnum<ScalarType, Differentiation::AD::NumberTypes::adolc_tapeless,
140  typename std::enable_if<std::is_floating_point<ScalarType>::value>::type
141  >
142  {
143  static const bool is_taped = false;
144  typedef adtl::adouble real_type;
145  typedef double derivative_type;
146  static const unsigned int n_supported_derivative_levels = 1;
147  };
148 
149 
150  template<typename ADNumberType>
151  struct Marking<ADNumberType, typename std::enable_if<
152  ADNumberTraits<ADNumberType>::type_code == NumberTypes::adolc_taped &&
153  ADNumberTraits<ADNumberType>::is_real_valued
154  >::type
155  >
156  {
157  typedef typename ADNumberTraits<ADNumberType>::scalar_type scalar_type;
158 
159  /*
160  * Initialize the state of an independent variable.
161  */
162  static void
163  independent_variable(const scalar_type &in,
164  const unsigned int ,
165  const unsigned int ,
166  ADNumberType &out)
167  {
168  out <<= in;
169  }
170 
171  /*
172  * Initialize the state of a dependent variable.
173  *
174  * @note The second argument must be writable, so we
175  * simply pass a copy instead of a non-constant reference.
176  */
177  static void
178  dependent_variable(ADNumberType &out,
179  ADNumberType func)
180  {
181  // Store the value only (strip it of all sensitivities)
182  out = ADNumberTraits<ADNumberType>::get_scalar_value(func);
183  // Mark as a dependent variable
184  scalar_type tmp;
185  func >>= tmp;
186  }
187  };
188 
189  template<typename ADNumberType>
190  struct Marking<ADNumberType, typename std::enable_if<
191  ADNumberTraits<ADNumberType>::type_code == NumberTypes::adolc_tapeless &&
192  ADNumberTraits<ADNumberType>::is_real_valued
193  >::type>
194  {
195  typedef typename ADNumberTraits<ADNumberType>::scalar_type scalar_type;
196 
197  /*
198  * Initialize the state of an independent variable.
199  */
200  static void
201  independent_variable(const scalar_type &in,
202  const unsigned int index,
203  const unsigned int ,
204  ADNumberType &out)
205  {
206  // It is important that the tapeless variables have their values set
207  // before defining their directional derivative index
208  out = in;
209 
210  // Violating this condition when will result in an Adol-C internal
211  // error. We could rather always throw here in order to provide a
212  // less cryptic message.
213  AssertThrow(index < adtl::getNumDir(),
214  ExcMessage("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,
225  const ADNumberType &func)
226  {
227  // Simply transfer value with sensitivities
228  out = 0.0;
229  out = func;
230  }
231  };
232 
233 
240  template<>
241  struct ExtractData<adouble>
242  {
246  static double
247  value (const adouble &x)
248  {
249  return x.getValue();
250  }
251 
252 
259  static unsigned int
260  n_directional_derivatives (const adouble &)
261  {
262  return 0;
263  }
264 
265 
273  static double
274  directional_derivative (const adouble &,
275  const unsigned int)
276  {
277  AssertThrow(false,
278  ExcMessage("The derivative values for taped Adol-C numbers must be"
279  "computed through the ::gradient function."));
280  return 0.0;
281  }
282  };
283 
284 
291  template<>
292  struct ExtractData<adtl::adouble>
293  {
297  static double
298  value (const adtl::adouble &x)
299  {
300  return x.getValue();
301  }
302 
303 
307  static unsigned int
308  n_directional_derivatives (const adtl::adouble &)
309  {
310  // This is a global function call...
311  return adtl::getNumDir();
312  }
313 
314 
318  static double
319  directional_derivative (const adtl::adouble &x,
320  const unsigned int direction)
321  {
322  Assert(direction < n_directional_derivatives(x),
323  ExcMessage("Requested directional derivative is greater than the number "
324  "registered by Adol-C."));
325  return x.getADValue(direction);
326  }
327  };
328 
329  } // namespace internal
330 
331 
332 
343  template<typename ADNumberType>
344  struct ADNumberTraits<ADNumberType,
345  typename std::enable_if<
346  std::is_same<ADNumberType, adouble>::value
347  >::type>
348  : NumberTraits<double, NumberTypes::adolc_taped>
349  {
350  static_assert(
351  std::is_same<ad_type,adouble>::value,
352  "Incorrect template type selected for taped ad_type");
353  static_assert(
354  is_taped == true,
355  "Incorrect setting for taping");
356  };
357 
358 
359 
371  template<typename ADNumberType>
372  struct ADNumberTraits<ADNumberType,
373  typename std::enable_if<
374  std::is_same<ADNumberType, std::complex<adouble> >::value
375  >::type>
376  : NumberTraits<std::complex<double>, NumberTypes::adolc_taped>
377  {
378  static_assert(
379  std::is_same<ad_type,std::complex<adouble> >::value,
380  "Incorrect template type selected for taped ad_type");
381  static_assert(
382  is_taped == true,
383  "Incorrect setting for taping");
384  };
385 
386 
387 
398  template<typename ADNumberType>
399  struct ADNumberTraits<ADNumberType,
400  typename std::enable_if<
401  std::is_same<ADNumberType, adtl::adouble>::value
402  >::type>
403  : NumberTraits<double, NumberTypes::adolc_tapeless>
404  {
405  static_assert(
406  std::is_same<ad_type,adtl::adouble>::value,
407  "Incorrect template type selected for tapeless ad_type");
408  static_assert(
409  is_tapeless == true,
410  "Incorrect setting for taping");
411  };
412 
413 
414 
426  template<typename ADNumberType>
427  struct ADNumberTraits<ADNumberType,
428  typename std::enable_if<
429  std::is_same<ADNumberType, std::complex<adtl::adouble> >::value
430  >::type>
431  : NumberTraits<std::complex<double>, NumberTypes::adolc_tapeless>
432  {
433  static_assert(
434  std::is_same<ad_type,std::complex<adtl::adouble> >::value,
435  "Incorrect template type selected for tapeless ad_type");
436  static_assert(
437  is_tapeless == true,
438  "Incorrect setting for taping");
439  };
440 
441 
442 
447  template<>
448  struct NumberTraits<adouble,NumberTypes::adolc_taped>
449  : NumberTraits<typename ADNumberTraits<adouble>::scalar_type,NumberTypes::adolc_taped>
450  {};
451 
452 
457  template<>
458  struct NumberTraits<std::complex<adouble>,NumberTypes::adolc_taped>
459  : NumberTraits<typename ADNumberTraits<std::complex<adouble> >::scalar_type,NumberTypes::adolc_taped>
460  {};
461 
462 
467  template<>
468  struct NumberTraits<adtl::adouble,NumberTypes::adolc_tapeless>
469  : NumberTraits<typename ADNumberTraits<adtl::adouble>::scalar_type,NumberTypes::adolc_tapeless>
470  {};
471 
472 
477  template<>
478  struct NumberTraits<std::complex<adtl::adouble>,NumberTypes::adolc_tapeless>
479  : NumberTraits<typename ADNumberTraits<std::complex<adtl::adouble> >::scalar_type,NumberTypes::adolc_tapeless>
480  {};
481 
482 
487  template <typename NumberType>
488  struct is_adolc_taped_number<NumberType, typename std::enable_if<
489  ADNumberTraits<typename std::decay<NumberType>::type>::type_code == NumberTypes::adolc_taped
490  >::type>
491  : std::true_type
492  {};
493 
494 
499  template <typename NumberType>
500  struct is_adolc_tapeless_number<NumberType, typename std::enable_if<
501  ADNumberTraits<typename std::decay<NumberType>::type>::type_code == NumberTypes::adolc_tapeless
502  >::type>
503  : std::true_type
504  {};
505 
506 
511  template <typename NumberType>
512  struct is_adolc_number<NumberType, typename std::enable_if<
513  is_adolc_taped_number<NumberType>::value ||
514  is_adolc_tapeless_number<NumberType>::value
515  >::type>
516  : std::true_type
517  {};
518 
519  } // namespace AD
520 } // namespace Differentiation
521 
522 
523 #endif // DOXYGEN
524 
525 
526 DEAL_II_NAMESPACE_CLOSE
527 
528 
529 #endif // DEAL_II_WITH_ADOLC
530 
531 #endif
STL namespace.
#define AssertThrow(cond, exc)
Definition: exceptions.h:1221
static ::ExceptionBase & ExcADOLCAdvancedBranching()
static ::ExceptionBase & ExcMessage(std::string arg1)
#define Assert(cond, exc)
Definition: exceptions.h:1142
#define DeclExceptionMsg(Exception, defaulttext)
Definition: exceptions.h:335