Reference documentation for deal.II version 9.2.0
\(\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  {
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 
69 
70 
71 #ifdef DEAL_II_WITH_ADOLC
72 
73 # include <deal.II/base/exceptions.h>
74 # include <deal.II/base/numbers.h>
75 
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 
87 
95  "This function has not yet been implemented for taped ADOL-C "
96  "numbers when the advanced branching feature is activated.");
97 
98 
99 /* ----------- inline and template functions and specializations ----------- */
100 
101 
102 # ifndef DOXYGEN
103 
104 
105 namespace Differentiation
106 {
107  namespace AD
108  {
109  namespace internal
110  {
115  template <typename ScalarType>
116  struct ADNumberInfoFromEnum<
117  ScalarType,
118  Differentiation::AD::NumberTypes::adolc_taped,
119  typename std::enable_if<
120  std::is_floating_point<ScalarType>::value>::type>
121  {
122  static const bool is_taped = true;
123  using real_type = adouble;
124  using derivative_type = double;
125  static const unsigned int n_supported_derivative_levels =
127  };
128 
129 
134  template <typename ScalarType>
135  struct ADNumberInfoFromEnum<
136  ScalarType,
137  Differentiation::AD::NumberTypes::adolc_tapeless,
138  typename std::enable_if<
139  std::is_floating_point<ScalarType>::value>::type>
140  {
141  static const bool is_taped = false;
142  using real_type = adtl::adouble;
143  using derivative_type = double;
144  static const unsigned int n_supported_derivative_levels = 1;
145  };
146 
147 
148  template <typename ADNumberType>
149  struct Marking<
150  ADNumberType,
151  typename std::enable_if<
152  ADNumberTraits<ADNumberType>::type_code == NumberTypes::adolc_taped &&
153  ADNumberTraits<ADNumberType>::is_real_valued>::type>
154  {
155  using scalar_type = typename ADNumberTraits<ADNumberType>::scalar_type;
156 
157  /*
158  * Initialize the state of an independent variable.
159  */
160  static void
161  independent_variable(const scalar_type &in,
162  const unsigned int,
163  const unsigned int,
164  ADNumberType &out)
165  {
166  out <<= in;
167  }
168 
169  /*
170  * Initialize the state of a dependent variable.
171  *
172  * @note The second argument must be writable, so we
173  * simply pass a copy instead of a non-constant reference.
174  */
175  static void
176  dependent_variable(ADNumberType &out, ADNumberType func)
177  {
178  // Store the value only (strip it of all sensitivities)
180  // Mark as a dependent variable
181  scalar_type tmp;
182  func >>= tmp;
183  }
184  };
185 
186  template <typename ADNumberType>
187  struct Marking<ADNumberType,
188  typename std::enable_if<
189  ADNumberTraits<ADNumberType>::type_code ==
190  NumberTypes::adolc_tapeless &&
191  ADNumberTraits<ADNumberType>::is_real_valued>::type>
192  {
193  using scalar_type = typename ADNumberTraits<ADNumberType>::scalar_type;
194 
195  /*
196  * Initialize the state of an independent variable.
197  */
198  static void
199  independent_variable(const scalar_type &in,
200  const unsigned int index,
201  const unsigned int,
202  ADNumberType &out)
203  {
204  // It is important that the tapeless variables have their values set
205  // before defining their directional derivative index
206  out = in;
207 
208  // Violating this condition when will result in an ADOL-C internal
209  // error. We could rather always throw here in order to provide a
210  // less cryptic message.
211  AssertThrow(index < adtl::getNumDir(),
212  ExcMessage(
213  "The index number of the independent variable being "
214  "marked is greater than the number of independent "
215  "variables that have been declared."));
216  out.setADValue(index, 1 /*seed value for first derivative*/);
217  }
218 
219  /*
220  * Initialize the state of a dependent variable.
221  */
222  static void
223  dependent_variable(ADNumberType &out, const ADNumberType &func)
224  {
225  // Simply transfer value with sensitivities
226  out = 0.0;
227  out = func;
228  }
229  };
230 
231 
238  template <>
239  struct ExtractData<adouble>
240  {
244  static double
245  value(const adouble &x)
246  {
247  return x.getValue();
248  }
249 
250 
257  static unsigned int
258  n_directional_derivatives(const adouble &)
259  {
260  return 0;
261  }
262 
263 
271  static double
272  directional_derivative(const adouble &, const unsigned int)
273  {
274  AssertThrow(false,
275  ExcMessage(
276  "The derivative values for taped ADOL-C numbers must be"
277  " computed through the ::gradient function."));
278  return 0.0;
279  }
280  };
281 
282 
289  template <>
290  struct ExtractData<adtl::adouble>
291  {
295  static double
296  value(const adtl::adouble &x)
297  {
298  return x.getValue();
299  }
300 
301 
305  static unsigned int
306  n_directional_derivatives(const adtl::adouble &)
307  {
308  // This is a global function call...
309  return adtl::getNumDir();
310  }
311 
312 
316  static double
317  directional_derivative(const adtl::adouble &x,
318  const unsigned int direction)
319  {
320  Assert(
321  direction < n_directional_derivatives(x),
322  ExcMessage(
323  "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<
345  ADNumberType,
346  typename std::enable_if<std::is_same<ADNumberType, adouble>::value>::type>
347  : NumberTraits<double, NumberTypes::adolc_taped>
348  {
350  "Incorrect template type selected for taped ad_type");
351  static_assert(is_taped == true, "Incorrect setting for taping");
352  };
353 
354 
355 
367  template <typename ADNumberType>
368  struct ADNumberTraits<
369  ADNumberType,
370  typename std::enable_if<
371  std::is_same<ADNumberType, std::complex<adouble>>::value>::type>
372  : NumberTraits<std::complex<double>, NumberTypes::adolc_taped>
373  {
374  static_assert(std::is_same<ad_type, std::complex<adouble>>::value,
375  "Incorrect template type selected for taped ad_type");
376  static_assert(is_taped == true, "Incorrect setting for taping");
377  };
378 
379 
380 
391  template <typename ADNumberType>
392  struct ADNumberTraits<
393  ADNumberType,
394  typename std::enable_if<
395  std::is_same<ADNumberType, adtl::adouble>::value>::type>
396  : NumberTraits<double, NumberTypes::adolc_tapeless>
397  {
399  "Incorrect template type selected for tapeless ad_type");
400  static_assert(is_tapeless == true, "Incorrect setting for taping");
401  };
402 
403 
404 
416  template <typename ADNumberType>
417  struct ADNumberTraits<
418  ADNumberType,
419  typename std::enable_if<
420  std::is_same<ADNumberType, std::complex<adtl::adouble>>::value>::type>
421  : NumberTraits<std::complex<double>, NumberTypes::adolc_tapeless>
422  {
423  static_assert(std::is_same<ad_type, std::complex<adtl::adouble>>::value,
424  "Incorrect template type selected for tapeless ad_type");
425  static_assert(is_tapeless == true, "Incorrect setting for taping");
426  };
427 
428 
429 
434  template <>
435  struct NumberTraits<adouble, NumberTypes::adolc_taped>
436  : NumberTraits<typename ADNumberTraits<adouble>::scalar_type,
437  NumberTypes::adolc_taped>
438  {};
439 
440 
445  template <>
446  struct NumberTraits<std::complex<adouble>, NumberTypes::adolc_taped>
447  : NumberTraits<
448  typename ADNumberTraits<std::complex<adouble>>::scalar_type,
449  NumberTypes::adolc_taped>
450  {};
451 
452 
457  template <>
458  struct NumberTraits<adtl::adouble, NumberTypes::adolc_tapeless>
459  : NumberTraits<typename ADNumberTraits<adtl::adouble>::scalar_type,
460  NumberTypes::adolc_tapeless>
461  {};
462 
463 
468  template <>
469  struct NumberTraits<std::complex<adtl::adouble>,
471  : NumberTraits<
472  typename ADNumberTraits<std::complex<adtl::adouble>>::scalar_type,
473  NumberTypes::adolc_tapeless>
474  {};
475 
476 
481  template <typename NumberType>
482  struct is_adolc_taped_number<
483  NumberType,
484  typename std::enable_if<
485  ADNumberTraits<typename std::decay<NumberType>::type>::type_code ==
486  NumberTypes::adolc_taped>::type> : std::true_type
487  {};
488 
489 
494  template <typename NumberType>
496  NumberType,
497  typename std::enable_if<
498  ADNumberTraits<typename std::decay<NumberType>::type>::type_code ==
499  NumberTypes::adolc_tapeless>::type> : std::true_type
500  {};
501 
502 
507  template <typename NumberType>
508  struct is_adolc_number<NumberType,
509  typename std::enable_if<
510  is_adolc_taped_number<NumberType>::value ||
511  is_adolc_tapeless_number<NumberType>::value>::type>
512  : std::true_type
513  {};
514 
515  } // namespace AD
516 } // namespace Differentiation
517 
518 
519 # endif // DOXYGEN
520 
521 
523 
524 
525 #endif // DEAL_II_WITH_ADOLC
526 
527 #endif
#define AssertThrow(cond, exc)
Definition: exceptions.h:1531
static ::ExceptionBase & ExcADOLCAdvancedBranching()
static ::ExceptionBase & ExcMessage(std::string arg1)
#define Assert(cond, exc)
Definition: exceptions.h:1419
#define DeclExceptionMsg(Exception, defaulttext)
Definition: exceptions.h:496
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:359
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:358
static const bool value
T max(const T &t, const MPI_Comm &mpi_communicator)