Reference documentation for deal.II version Git a285ab78cc 2020-08-04 19:09:24 +0200
\(\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 
81 
89  "This function has not yet been implemented for taped ADOL-C "
90  "numbers when the advanced branching feature is activated.");
91 
92 
93 /* ----------- inline and template functions and specializations ----------- */
94 
95 
96 # ifndef DOXYGEN
97 
98 
99 namespace Differentiation
100 {
101  namespace AD
102  {
103  namespace internal
104  {
109  template <typename ScalarType>
110  struct ADNumberInfoFromEnum<
111  ScalarType,
112  Differentiation::AD::NumberTypes::adolc_taped,
113  typename std::enable_if<
114  std::is_floating_point<ScalarType>::value>::type>
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,
131  Differentiation::AD::NumberTypes::adolc_tapeless,
132  typename std::enable_if<
133  std::is_floating_point<ScalarType>::value>::type>
134  {
135  static const bool is_taped = false;
136  using real_type = adtl::adouble;
137  using derivative_type = double;
138  static const unsigned int n_supported_derivative_levels = 1;
139  };
140 
141 
142  template <typename ADNumberType>
143  struct Marking<
144  ADNumberType,
145  typename std::enable_if<
146  ADNumberTraits<ADNumberType>::type_code == NumberTypes::adolc_taped &&
147  ADNumberTraits<ADNumberType>::is_real_valued>::type>
148  {
149  using scalar_type = typename ADNumberTraits<ADNumberType>::scalar_type;
150 
151  /*
152  * Initialize the state of an independent variable.
153  */
154  static void
155  independent_variable(const scalar_type &in,
156  const unsigned int,
157  const unsigned int,
158  ADNumberType &out)
159  {
160  out <<= in;
161  }
162 
163  /*
164  * Initialize the state of a dependent variable.
165  *
166  * @note The second argument must be writable, so we
167  * simply pass a copy instead of a non-constant reference.
168  */
169  static void
170  dependent_variable(ADNumberType &out, ADNumberType func)
171  {
172  // Store the value only (strip it of all sensitivities)
174  // Mark as a dependent variable
175  scalar_type tmp;
176  func >>= tmp;
177  }
178  };
179 
180  template <typename ADNumberType>
181  struct Marking<ADNumberType,
182  typename std::enable_if<
183  ADNumberTraits<ADNumberType>::type_code ==
184  NumberTypes::adolc_tapeless &&
185  ADNumberTraits<ADNumberType>::is_real_valued>::type>
186  {
187  using scalar_type = typename ADNumberTraits<ADNumberType>::scalar_type;
188 
189  /*
190  * Initialize the state of an independent variable.
191  */
192  static void
193  independent_variable(const scalar_type &in,
194  const unsigned int index,
195  const unsigned int,
196  ADNumberType &out)
197  {
198  // It is important that the tapeless variables have their values set
199  // before defining their directional derivative index
200  out = in;
201 
202  // Violating this condition when will result in an ADOL-C internal
203  // error. We could rather always throw here in order to provide a
204  // less cryptic message.
205  AssertThrow(index < adtl::getNumDir(),
206  ExcMessage(
207  "The index number of the independent variable being "
208  "marked is greater than the number of independent "
209  "variables that have been declared."));
210  out.setADValue(index, 1 /*seed value for first derivative*/);
211  }
212 
213  /*
214  * Initialize the state of a dependent variable.
215  */
216  static void
217  dependent_variable(ADNumberType &out, const ADNumberType &func)
218  {
219  // Simply transfer value with sensitivities
220  out = 0.0;
221  out = func;
222  }
223  };
224 
225 
230  template <>
231  struct ExtractData<adouble>
232  {
236  static double
237  value(const adouble &x)
238  {
239  return x.getValue();
240  }
241 
242 
249  static unsigned int
250  n_directional_derivatives(const adouble &)
251  {
252  return 0;
253  }
254 
255 
263  static double
264  directional_derivative(const adouble &, const unsigned int)
265  {
266  AssertThrow(false,
267  ExcMessage(
268  "The derivative values for taped ADOL-C numbers must be"
269  " computed through the ::gradient function."));
270  return 0.0;
271  }
272  };
273 
274 
279  template <>
280  struct ExtractData<adtl::adouble>
281  {
285  static double
286  value(const adtl::adouble &x)
287  {
288  return x.getValue();
289  }
290 
291 
295  static unsigned int
296  n_directional_derivatives(const adtl::adouble &)
297  {
298  // This is a global function call...
299  return adtl::getNumDir();
300  }
301 
302 
306  static double
307  directional_derivative(const adtl::adouble &x,
308  const unsigned int direction)
309  {
310  Assert(
311  direction < n_directional_derivatives(x),
312  ExcMessage(
313  "Requested directional derivative is greater than the number "
314  "registered by ADOL-C."));
315  return x.getADValue(direction);
316  }
317  };
318 
319  } // namespace internal
320 
321 
322 
331  template <typename ADNumberType>
332  struct ADNumberTraits<
333  ADNumberType,
334  typename std::enable_if<std::is_same<ADNumberType, adouble>::value>::type>
335  : NumberTraits<double, NumberTypes::adolc_taped>
336  {
337  static_assert(std::is_same<ad_type, adouble>::value,
338  "Incorrect template type selected for taped ad_type");
339  static_assert(is_taped == true, "Incorrect setting for taping");
340  };
341 
342 
343 
353  template <typename ADNumberType>
354  struct ADNumberTraits<
355  ADNumberType,
356  typename std::enable_if<
357  std::is_same<ADNumberType, std::complex<adouble>>::value>::type>
358  : NumberTraits<std::complex<double>, NumberTypes::adolc_taped>
359  {
360  static_assert(std::is_same<ad_type, std::complex<adouble>>::value,
361  "Incorrect template type selected for taped ad_type");
362  static_assert(is_taped == true, "Incorrect setting for taping");
363  };
364 
365 
366 
375  template <typename ADNumberType>
376  struct ADNumberTraits<
377  ADNumberType,
378  typename std::enable_if<
379  std::is_same<ADNumberType, adtl::adouble>::value>::type>
380  : NumberTraits<double, NumberTypes::adolc_tapeless>
381  {
382  static_assert(std::is_same<ad_type, adtl::adouble>::value,
383  "Incorrect template type selected for tapeless ad_type");
384  static_assert(is_tapeless == true, "Incorrect setting for taping");
385  };
386 
387 
388 
398  template <typename ADNumberType>
399  struct ADNumberTraits<
400  ADNumberType,
401  typename std::enable_if<
402  std::is_same<ADNumberType, std::complex<adtl::adouble>>::value>::type>
403  : NumberTraits<std::complex<double>, NumberTypes::adolc_tapeless>
404  {
405  static_assert(std::is_same<ad_type, std::complex<adtl::adouble>>::value,
406  "Incorrect template type selected for tapeless ad_type");
407  static_assert(is_tapeless == true, "Incorrect setting for taping");
408  };
409 
410 
411 
416  template <>
417  struct NumberTraits<adouble, NumberTypes::adolc_taped>
418  : NumberTraits<typename ADNumberTraits<adouble>::scalar_type,
419  NumberTypes::adolc_taped>
420  {};
421 
422 
427  template <>
428  struct NumberTraits<std::complex<adouble>, NumberTypes::adolc_taped>
429  : NumberTraits<
430  typename ADNumberTraits<std::complex<adouble>>::scalar_type,
431  NumberTypes::adolc_taped>
432  {};
433 
434 
439  template <>
440  struct NumberTraits<adtl::adouble, NumberTypes::adolc_tapeless>
441  : NumberTraits<typename ADNumberTraits<adtl::adouble>::scalar_type,
442  NumberTypes::adolc_tapeless>
443  {};
444 
445 
450  template <>
451  struct NumberTraits<std::complex<adtl::adouble>,
453  : NumberTraits<
454  typename ADNumberTraits<std::complex<adtl::adouble>>::scalar_type,
455  NumberTypes::adolc_tapeless>
456  {};
457 
458 
463  template <typename NumberType>
464  struct is_adolc_taped_number<
465  NumberType,
466  typename std::enable_if<
467  ADNumberTraits<typename std::decay<NumberType>::type>::type_code ==
468  NumberTypes::adolc_taped>::type> : std::true_type
469  {};
470 
471 
476  template <typename NumberType>
478  NumberType,
479  typename std::enable_if<
480  ADNumberTraits<typename std::decay<NumberType>::type>::type_code ==
481  NumberTypes::adolc_tapeless>::type> : std::true_type
482  {};
483 
484 
489  template <typename NumberType>
490  struct is_adolc_number<NumberType,
491  typename std::enable_if<
492  is_adolc_taped_number<NumberType>::value ||
493  is_adolc_tapeless_number<NumberType>::value>::type>
494  : std::true_type
495  {};
496 
497  } // namespace AD
498 } // namespace Differentiation
499 
500 
501 # endif // DOXYGEN
502 
503 
505 
506 
507 #endif // DEAL_II_WITH_ADOLC
508 
509 #endif
#define AssertThrow(cond, exc)
Definition: exceptions.h:1521
static ::ExceptionBase & ExcADOLCAdvancedBranching()
static ::ExceptionBase & ExcMessage(std::string arg1)
#define Assert(cond, exc)
Definition: exceptions.h:1411
#define DeclExceptionMsg(Exception, defaulttext)
Definition: exceptions.h:493
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:363
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:362
T max(const T &t, const MPI_Comm &mpi_communicator)